/*
    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"

#define EPS_STRAIN_CORRECTION 1.e-10

long int membrane_apply( long int element, long int gr, 
  double memmat[MDIM][MDIM], double inc_ept[],
  double inc_epe[], double new_sig[] )

  /* Assumption: no shear stresses due to normal strains */

{
  long int swit=0, membrane_found=1, membrane=-NO, axisymmetric=-NO, ldum=0;
  double rdum=0., ddum[1], tmp_epe[MDIM*MDIM], rh[2], mat[2*2], inv_mat[2*2], 
    work[MDIM];

      // elastic correction for zero perpendicular stress(es)
  db( GROUP_MATERI_MEMBRANE, gr, &membrane, ddum, ldum, VERSION_NORMAL, GET_IF_EXISTS );
  if ( membrane==-YES ) {
    swit = set_swit(element,-1, "membrane");
    if ( swit ) pri( "In routine MEMBRANE" );
    if ( db_active_index( GROUP_MATERI_ELASTI_COMPRESSIBILITY, gr, VERSION_NORMAL ) ) {
      pri( "Error: GROUP_MATERI_ELASTI_COMPRESSIBILITY cannot be used with MEMBRANE." );
      exit(TN_EXIT_STATUS);
    }
    if ( db_active_index( GROUP_MATERI_HYPER_MOONEY_RIVLIN, gr, VERSION_NORMAL ) ) {
      pri( "Error: GROUP_MATERI_HYPER_MOONEY_RIVLIN cannot be used with MEMBRANE." );
      exit(TN_EXIT_STATUS);
    }
    if ( db_active_index( GROUP_MATERI_HYPER_BESSELING, gr, VERSION_NORMAL ) ) {
      pri( "Error: GROUP_MATERI_HYPER_BESSELING cannot be used with MEMBRANE." );
      exit(TN_EXIT_STATUS);
    }
    db( OPTIONS_AXISYMMETRIC, 0, &axisymmetric, ddum, ldum, VERSION_NORMAL, GET_IF_EXISTS );
    mat[0] = memmat[1][1];
    mat[1] = memmat[1][2];
    mat[2] = memmat[2][1];
    mat[3] = memmat[2][2];
    array_set( work, 0., MDIM );
    array_set( tmp_epe, 0., MDIM*MDIM );
    if ( ndim==2 ) {
      if ( axisymmetric==-YES ) {
        pri( "Error: either use GROUP_MATERI_MEMBRANE or OPTIONS_AXISYMMETRIC in 2D." );
        exit(TN_EXIT_STATUS);
      }
      else if ( mat[2]!=0. )
        work[2] = -new_sig[8]/mat[3];
    }
    else if ( ndim==1 ) {
      if ( axisymmetric==-YES ) {
        if ( mat[1]!=0. ) work[1] = -new_sig[4]/mat[0];
      }
      else {
        rh[0] = -new_sig[4];
        rh[1] = -new_sig[8];
        if ( matrix_inverse( mat, inv_mat, rdum, 2 ) )
          matrix_ab( inv_mat, rh, &work[1], 2, 2, 1 );
      }
    }
    tmp_epe[4] = work[1];
    tmp_epe[8] = work[2];
    array_add( inc_ept, tmp_epe, inc_ept, MDIM*MDIM );
    array_add( inc_epe, tmp_epe, inc_epe, MDIM*MDIM );
    if ( array_size( tmp_epe, MDIM*MDIM ) > EPS_STRAIN_CORRECTION ) 
      membrane_found = 0;
    if ( swit ) {
      pri( "strain correction", tmp_epe, MDIM, MDIM );
      pri( "Out routine MEMBRANE" );
    }
  }

  return membrane_found;
}
