/*
    Copyright (C) 1998  Dennis Roddeman
    email: dennis.roddeman@uibk.ac.at

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.


    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software Foundation 
    59 Temple Place, Suite 330, Boston, MA, 02111-1307, USA
*/

#include "tochnog.h"

void groundflow( long int element, long int gr, long int nnol,
  double h[], double d[], double volume, double old_unknowns[], 
  double new_unknowns[], double grad_new_unknowns[], 
  double element_matrix[], double element_rhside[],
  double element_rhside_internal[], double element_rhside_static[], 
  double element_residue[] )

{
  long int swit=0, inol=0, jnol=0, idim=0, jdim=0, ipuknwn=0, iuknwn=0, indx=0, 
    indxi=0, indxj=0, ldum=0, idum[1];
  double tmp=0., pe=0., dtime=0., divergence=0.;

  swit = set_swit(element,-1,"groundflow");
  if ( swit ) pri( "In routine GROUNDFLOW." );

  db( DTIME, 0, idum, &dtime, ldum, VERSION_NEW, GET );
  get_group_data( GROUP_GROUNDFLOW_PERMEABILITY, gr, new_unknowns,
    &pe, ldum, GET_IF_EXISTS );
  if ( materi_velocity ) {
    for ( idim=0; idim<ndim; idim++ ) {
      iuknwn = vel_indx + idim * nder;
      divergence += grad_new_unknowns[idim*nuknwn+iuknwn];
    }
  }

  for ( inol=0; inol<nnol; inol++ ) {
    for ( jdim=0; jdim<ndim; jdim++ ) {
      ipuknwn = pres_indx/nder;
      indx = inol*npuknwn + ipuknwn;
        // solid deformation
      if ( materi_velocity ) {
        ipuknwn = pres_indx/nder;
        indx = inol*npuknwn + ipuknwn;
        tmp = h[inol] * divergence;
        element_rhside[indx] -= volume * tmp;
        element_rhside_internal[indx] += volume * tmp;
        element_rhside_static[indx] += volume * tmp;
        if ( residue ) element_residue[indx] -= tmp;
        indxi = inol*npuknwn + ipuknwn;
        for ( jnol=0; jnol<nnol; jnol++ ) {
          for ( idim=0; idim<ndim; idim++ ) {
            indxj = jnol*npuknwn + ipuknwn;
            element_matrix[indxi*nnol*npuknwn+indxj] +=
              volume * h[inol] * d[idim*nnol+jnol] * dtime;
          }
        }
      }
      if ( groundflow_gvelocity ) {
        iuknwn = gvel_indx + jdim*nder;
        ipuknwn = iuknwn/nder;
        indx = inol*npuknwn + ipuknwn;
        tmp = h[inol] * ( -pe*grad_new_unknowns[jdim*nuknwn+pres_indx] -
          old_unknowns[iuknwn] ) / dtime;
        element_rhside[indx] += volume * tmp;
        element_rhside_internal[indx] -= volume * tmp;
        element_rhside_static[indx] -= volume * tmp;
      }
    }
  }

  if ( swit ) pri( "Out function GROUNDFLOW" );

}
