tetra4.c

Go to the documentation of this file.
00001 /*
00002 %M This modules contains the TETR4 element sub-class methods and 
00003    definitions
00004 %a Joao Luiz Elias Campos.
00005 %d February 20th, 2001.
00006 %r $Id: tetra4.c,v 1.4 2004/06/24 18:32:35 joaoluiz Exp $
00007 %w (C) COPYRIGHT 1995-1996, Eduardo Nobre Lages.
00008    (C) COPYRIGHT 1997-2001, Joao Luiz Elias Campos.
00009    All Rights Reserved
00010    Duplication of this program or any part thereof without the express
00011    written consent of the author is prohibited.
00012 *
00013 *  Modified:  27-Apr-2005    Alexandre A. Del Savio
00014 *    Foram substituídas todas as alocações dinâmicas feitas com malloc 
00015 *    por calloc.
00016 *
00017 *  Modified:  23-Fev-2006    Juan Pablo Ibañez
00018 *    Modificada a funcão TETR4ReadInitStress que passa a retornar um valor int.
00019 *
00020 *  Modified:  Agosto-06  André Luis Muller
00021 *    Criada a função _TETRA4ElementCenter que retorna as coordenadas do centro de
00022 *    um elemento do tipo TETRA4.
00023 *    Adicionado a função TETRA4StressStrain o cálculo da poro pressão e o 
00024 *    cálculo da tensão efetiva.
00025 *
00026 *  Modified:  Setembro-06 André Luis Muller
00027 *    Modificação na função TETRA4InterForce para possibilitar
00028 *    a condição de tensões iniciais.
00029 *
00030 *    Modificação na função TETRA4New. Inicialização das tensões iniciais
00031 *
00032 *  Modified:  07-06 André Luis Muller
00033 *    Modificação na função TETRA4WriteGaussResults para possibilitar
00034 *    a escolha das respostas a serem escritas no arquivo de resultados.
00035 *
00036 */
00037 
00038 /*
00039 ** ------------------------------------------------------------------------
00040 ** Global variables and symbols:
00041 */
00042 #include <stdio.h>
00043 #include <stdlib.h>
00044 #include <math.h>
00045 #include <string.h>
00046 
00047 #include "rio.h"
00048 #include "load.h"
00049 #include "elm.h"
00050 #include "node.h"
00051 #include "material.h"
00052 #include "load.h"
00053 #include "alg.h"
00054 
00055 /*
00056 ** ------------------------------------------------------------------------
00057 ** Local variables and symbols:
00058 */
00059 
00060 /*
00061 %T TETR4 element data definition
00062 */
00063 typedef struct _tetr4elm
00064 {
00065  int    matid;                /* Material identification          */
00066  int    tckid;                /* Element thickness identification */
00067  int    NumNodes;             /* Number of element nodes          */
00068  int    NumTensComp;          /* Number of tension components     */
00069  int    inc[4];               /* Element incidence                */
00070  double istr[6];              /* Element initial stress           */
00071  double effdef;               /* Effective deformation            */
00072  double prof;                 /* Element profile                  */
00073 } sTetr4Data;
00074 
00075 /*
00076 %V Gauss point coordinates and its weights
00077 */
00078 static double _GPoint  = 0.25000000;
00079 static double _GWeight = 0.16666667;
00080 
00081 static double GForce = 9.85;
00082 
00083 /*
00084 ** ------------------------------------------------------------------------
00085 ** Local functions:
00086 */
00087 static void   _TETR4GetCoord       ( sElement *, sCoord [] );
00088 static void   _TETR4ShapeFunc      ( double, double, double, double [] );
00089 static void   _TETR4Jacobian       ( double, double, double, sCoord [],
00090                                      double *, double [3][3] );
00091 static void   _TETR4BMatrix        ( double, double, double, sCoord [],
00092                                      double [6][12] );
00093 static void   _TETR4DerivShp       ( double, double, double, sDerivRST [] );
00094 static void   _TETR4GetDisplacement( sElement *, double *, double [] );
00095 static double _TETR4MinHeight      ( sCoord * );
00096 static double _TETR4Volume         ( sCoord * );
00097 static void   _TETR4ElementCenter  ( sElement *elm, sCoord coord[1] );
00098 static void   _TETR4FaceCenter( sCoord *coord0, sCoord *coord1, 
00099                                 sCoord *coord2, sCoord *center );
00100                                 
00101 static double RigidCoeff( sElement *elm, int noi, int noj, int nok );
00102 static double _Area( sCoord coord[3] );
00103 static void _Normal( sCoord coord[3], sCoord *normal );  
00104 
00105 /*
00106 %F This functions computes the element rigidity coefficient.
00107 %i Element descriptor.
00108 %o Element rigidity coefficient.
00109 */
00110 static double RigidCoeff( sElement *elm, int noi, int noj, int nok )
00111 {
00112  sCoord coord[3];
00113  double area = 0.0;
00114 
00115 /* Get element coordinates
00116  */
00117  coord[0].x = elm->nodes[noi-1].coord.x;
00118  coord[0].y = elm->nodes[noi-1].coord.y;
00119  coord[0].z = elm->nodes[noi-1].coord.z;
00120  coord[1].x = elm->nodes[noj-1].coord.x;
00121  coord[1].y = elm->nodes[noj-1].coord.y;
00122  coord[1].z = elm->nodes[noj-1].coord.z;
00123  coord[2].x = elm->nodes[nok-1].coord.x;
00124  coord[2].y = elm->nodes[nok-1].coord.y;
00125  coord[2].z = elm->nodes[nok-1].coord.z;
00126 
00127 /* Compute the element area
00128  */
00129  area = _Area( coord );
00130 
00131  return( area );
00132 
00133 } /* End of RigidCoeff */
00134 
00135 static double _Area( sCoord coord[3] )
00136 {
00137  double area = 0.0;
00138  double u[3],v[3],w[3];
00139 
00140 /* Computes element area
00141  */
00142  u[0] = coord[1].x - coord[0].x;
00143  u[1] = coord[1].y - coord[0].y; 
00144  u[2] = coord[1].z - coord[0].z;
00145  v[0] = coord[2].x - coord[0].x; 
00146  v[1] = coord[2].y - coord[0].y; 
00147  v[2] = coord[2].z - coord[0].z;
00148 
00149  w[0] = u[1] * v[2] - u[2] * v[1];
00150  w[1] = u[2] * v[0] - u[0] * v[2];
00151  w[2] = u[0] * v[1] - u[1] * v[0];
00152  area = sqrt(w[0]*w[0] + w[1]*w[1] + w[2]*w[2]) / 2.0;
00153           
00154  return( area );
00155 
00156 } /* End of _Area */
00157 
00158 
00159 
00160 /*
00161 %F This function gets the element center.
00162 %i Element descriptor.
00163 %o Element center.
00164 */
00165 static void _TETR4ElementCenter( sElement *elm, sCoord coord[1] )
00166 {
00167  sTetr4Data *data = 0L;
00168  int      i, node;
00169  
00170  coord[0].x = 0.0;
00171  coord[0].y = 0.0;
00172  coord[0].z = 0.0;
00173 
00174  /* Element element data
00175  */
00176  data = (sTetr4Data *)elm->data;
00177  
00178  for( i = 0; i < data->NumNodes; i++ ) {
00179   node = data->inc[i]-1;
00180   coord[0].x += NodeVector[node].coord.x;
00181   coord[0].y += NodeVector[node].coord.y;
00182   coord[0].z += NodeVector[node].coord.z;
00183  }
00184  /* Compute element center
00185  */
00186  coord[0].x /= data->NumNodes;
00187  coord[0].y /= data->NumNodes;
00188  coord[0].z /= data->NumNodes;
00189 } /* End of _TETR4ElementCenter */
00190 
00191 /*
00192 %F This function computes the element volume.
00193 */
00194 static double _TETR4Volume( sCoord *coord )
00195 {
00196  double jac[3][3];
00197  double detjac, volume = 0.0;
00198 
00199 /* Compute the jacobian matrix
00200  */
00201  _TETR4Jacobian( _GPoint, _GPoint, _GPoint, coord, &detjac, jac );
00202 
00203 /* Rigidity coefficient
00204  */
00205  volume = detjac * _GWeight;
00206 
00207  return volume;
00208 
00209 } /* End of _TETR4Volume */
00210 
00211 /* Calcula o centro de um triangulo */
00212 static void _TETR4FaceCenter( sCoord *coord0, sCoord *coord1, 
00213                               sCoord *coord2, sCoord *center )
00214 {
00215  sCoord med[2]; /* medianas do triângulo */
00216  double dx, dy, dz;
00217 
00218 /* O ponto de interseção das três medianas de um triangulo é o
00219  * seu baricentro. O baricentro divide a mediana em dois segmentos.
00220  * O segmento que une o vértice ao baricentro vale o dobro do 
00221  * segmento que une o baricentro ao lado oposto deste vértice. 
00222  */
00223 
00224  med[0].x = coord0->x;
00225  med[0].y = coord0->y;
00226  med[0].z = coord0->z;
00227  med[1].x = ( coord1->x + coord2->x ) / 2.0;
00228  med[1].y = ( coord1->y + coord2->y ) / 2.0;
00229  med[1].z = ( coord1->z + coord2->z ) / 2.0;
00230  
00231  dx = ( med[1].x - med[0].x ) / 3.0;
00232  dy = ( med[1].y - med[0].y ) / 3.0;
00233  dz = ( med[1].z - med[0].z ) / 3.0;
00234 
00235  center->x = med[0].x + (2*dx);
00236  center->y = med[0].y + (2*dy);
00237  center->z = med[0].z + (2*dz);
00238  }
00239 
00240 /*
00241 %F This function computes the minimun height for the TETR4 element.
00242  */
00243 
00244 #if 0
00245 static double _TETR4MinHeight( sCoord *coord )
00246 {
00247  double volume, bcorr, bmax, hmin;
00248  int    i;
00249 
00250 /* Initialize variables
00251  */
00252  bmax = bcorr = hmin = volume = 0.0;
00253 
00254 /* Loop over the element edges to compute the maximum edge
00255  */
00256  for( i = 0; i < 4; i++ ) {
00257   bcorr = sqrt( ( coord[(i+1)%4].x - coord[i].x ) * ( coord[(i+1)%4].x - coord[i].x ) +
00258                 ( coord[(i+1)%4].y - coord[i].y ) * ( coord[(i+1)%4].y - coord[i].y ) +
00259                 ( coord[(i+1)%4].z - coord[i].z ) * ( coord[(i+1)%4].z - coord[i].z ) );
00260 
00261   if( bcorr > bmax )
00262    bmax = bcorr;
00263  }
00264 
00265 /* Compute element volume
00266  */
00267  volume = _TETR4Volume( coord );
00268 
00269 /* Compute the minimum height
00270  */
00271  hmin = (2.0 * volume) / bmax;
00272 
00273  return hmin;
00274 } /* End of _TETR4MinHeight */
00275 
00276 #else
00277 static double _TETR4MinHeight( sCoord *coord )
00278 {
00279  sCoord center;
00280  double hmin = 0.0;
00281  double h;
00282  int i;
00283  int first = 1;
00284  
00285  for( i = 0; i < 4; i++ ) 
00286  {
00287   _TETR4FaceCenter( &coord[i+1], &coord[(i+2)%4], &coord[(i+3)%4], &center );
00288   h = sqrt( ( (coord[i].x - center.x)*(coord[i].x - center.x) ) +
00289             ( (coord[i].y - center.y)*(coord[i].y - center.y) ) +
00290             ( (coord[i].z - center.z)*(coord[i].z - center.z) ) ); 
00291   if( first || ( h < hmin ) ) 
00292   {
00293    first = 0;
00294    hmin = h;
00295   }
00296  }
00297  return hmin;
00298 }
00299 #endif
00300 
00301 /*
00302 %F This function get the element nodal displacement from the global
00303    vector.
00304 */
00305 static void _TETR4GetDisplacement( sElement *elm, double *U, double ue[12] )
00306 {
00307  sTetr4Data *data = 0L;
00308  int         i;
00309 
00310 /* Get element descriptor
00311  */
00312  data = (sTetr4Data *)elm->data;
00313 
00314 /* Fill element displacement vector
00315  */
00316  for( i = 0; i < data->NumNodes; i++ ) {
00317   ue[3*i]   = U[3*(data->inc[i]-1)];
00318   ue[3*i+1] = U[3*(data->inc[i]-1)+1];
00319   ue[3*i+2] = U[3*(data->inc[i]-1)+2];
00320  }
00321 
00322 } /* End of _TETR4GetDisplacement */
00323 
00324 
00325 /*
00326 %F This function computes the stress x strain matrix for the TETR4 element.
00327 */
00328 static void _TETR4BMatrix( double r, double s, double t, sCoord coord[4], 
00329                                                          double bm[6][12] )
00330 {
00331  double    detjac;
00332  double    jac[3][3], ijac[3][3];
00333  sDerivRST dshp[4];
00334  int       i;
00335 
00336 /* Initialize B matrix
00337  */
00338  for( i = 0; i < 12; i++ )
00339   bm[0][i] = bm[1][i] = bm[2][i] = 
00340   bm[3][i] = bm[4][i] = bm[5][i] = 0.0;
00341 
00342 /* Compute the element jacobian matrix
00343  */
00344  _TETR4Jacobian( r, s, t, coord, &detjac, jac );
00345 
00346 /* Compute the inverse
00347  */
00348  ijac[0][0] =  (jac[1][1] * jac[2][2] - jac[1][2] * jac[2][1]) / detjac;
00349  ijac[0][1] = -(jac[0][1] * jac[2][2] - jac[0][2] * jac[2][1]) / detjac;
00350  ijac[0][2] =  (jac[0][1] * jac[1][2] - jac[0][2] * jac[1][1]) / detjac;
00351  ijac[1][0] = -(jac[1][0] * jac[2][2] - jac[1][2] * jac[2][0]) / detjac;
00352  ijac[1][1] =  (jac[0][0] * jac[2][2] - jac[0][2] * jac[2][0]) / detjac;
00353  ijac[1][2] = -(jac[0][0] * jac[1][2] - jac[0][2] * jac[1][0]) / detjac;
00354  ijac[2][0] =  (jac[1][0] * jac[2][1] - jac[1][1] * jac[2][0]) / detjac;
00355  ijac[2][1] = -(jac[0][0] * jac[2][1] - jac[0][1] * jac[2][0]) / detjac;
00356  ijac[2][2] =  (jac[0][0] * jac[1][1] - jac[0][1] * jac[1][0]) / detjac;
00357 
00358 
00359 /* Compute shape functions derivatives
00360  */
00361  _TETR4DerivShp( r, s, t, dshp );
00362 
00363 /* Compute the B matrix coefficientes
00364  */
00365  for( i = 0; i < 4; i++ ) {
00366   bm[0][3*i]   = bm[3][3*i+1] = bm[4][3*i+2] = (ijac[0][0] * dshp[i].r) +
00367                                                (ijac[0][1] * dshp[i].s) + 
00368                                                (ijac[0][2] * dshp[i].t);
00369   bm[1][3*i+1] = bm[3][3*i]   = bm[5][3*i+2] = (ijac[1][0] * dshp[i].r) +
00370                                                (ijac[1][1] * dshp[i].s) + 
00371                                                (ijac[1][2] * dshp[i].t);
00372   bm[2][3*i+2] = bm[4][3*i]   = bm[5][3*i+1] = (ijac[2][0] * dshp[i].r) +
00373                                                (ijac[2][1] * dshp[i].s) + 
00374                                                (ijac[2][2] * dshp[i].t);
00375  }
00376 
00377 } /* End of _TETR4BMatrix */
00378 
00379 
00380 /*
00381 %F This function computes the jacobian matrix for the quadrilateral 
00382    brick 8 element.
00383 */
00384 static void _TETR4Jacobian( double r, double s, double t, sCoord coord[4], 
00385                             double *detjac, double jac[3][3] )
00386 {
00387  sDerivRST dmap[4];
00388  int       i;
00389 
00390 /* Compute the map derivatives
00391  */
00392  _TETR4DerivShp( r, s, t, dmap );
00393 
00394 /* Compute the jacobian matrix
00395  */
00396  for( i = 0; i < 3; i++ )
00397   jac[i][0] = jac[i][1] = jac[i][2] = 0.0;
00398 
00399  for( i = 0; i < 4; i++ ) {
00400   jac[0][0] += dmap[i].r * coord[i].x;
00401   jac[0][1] += dmap[i].r * coord[i].y;
00402   jac[0][2] += dmap[i].r * coord[i].z;
00403   jac[1][0] += dmap[i].s * coord[i].x;
00404   jac[1][1] += dmap[i].s * coord[i].y;
00405   jac[1][2] += dmap[i].s * coord[i].z;
00406   jac[2][0] += dmap[i].t * coord[i].x;
00407   jac[2][1] += dmap[i].t * coord[i].y;
00408   jac[2][2] += dmap[i].t * coord[i].z;
00409  }
00410 
00411 /* Determiant
00412  */
00413  (*detjac) = jac[0][0] * (jac[1][1] * jac[2][2] - jac[1][2] * jac[2][1]) -
00414              jac[0][1] * (jac[1][0] * jac[2][2] - jac[1][2] * jac[2][0]) +
00415              jac[0][2] * (jac[1][0] * jac[2][1] - jac[1][1] * jac[2][0]);
00416 
00417 } /* End of _TETR4Jacobian */
00418 
00419 
00420 /*
00421 %F This function gets the element coordinates.
00422 %i Element descriptor.
00423 %o Element coordinares.
00424 */
00425 static void _TETR4GetCoord( sElement *elm, sCoord coord[4] )
00426 {
00427  sTetr4Data *data = 0L;
00428  int         i;
00429 
00430 /* Element element data
00431  */
00432  data = (sTetr4Data *)elm->data;
00433 
00434 /* Get element coordinates
00435  */
00436  for( i = 0; i < 4; i++ )
00437  {
00438   coord[i].x = elm->nodes[data->inc[i]-1].coord.x;
00439   coord[i].y = elm->nodes[data->inc[i]-1].coord.y;
00440   coord[i].z = elm->nodes[data->inc[i]-1].coord.z;
00441  }
00442  
00443 } /* End of _TETR4GetCoord */
00444 
00445 
00446 /*
00447 %F This function computes the shape functions for the quadrilateral 
00448    brick 8 element.
00449 */
00450 static void _TETR4ShapeFunc( double r, double s, double t, double shape[4] )
00451 {
00452 /* Compute shape functions
00453  */
00454  shape[0] = r;
00455  shape[1] = s;
00456  shape[2] = t;
00457  shape[3] = 1.0 - r - s - t;
00458 
00459 } /* End of _TETR4ShapeFunc */
00460 
00461 
00462 /*
00463 %F This function computes the shape functions derivatives for the 
00464    quadrilateral brick 8 element.
00465 */
00466 static void _TETR4DerivShp( double r, double s, double t, sDerivRST dshp[8] )
00467 {
00468 /* Compute shape functions derivatives
00469  */
00470  dshp[0].r =  1.0;
00471  dshp[1].r =  0.0;
00472  dshp[2].r =  0.0;
00473  dshp[3].r = -1.0;
00474 
00475  dshp[0].s =  0.0;
00476  dshp[1].s =  1.0;
00477  dshp[2].s =  0.0;
00478  dshp[3].s = -1.0;
00479 
00480  dshp[0].t =  0.0;
00481  dshp[1].t =  0.0;
00482  dshp[2].t =  1.0;
00483  dshp[3].t = -1.0;
00484 
00485 } /* End of _TETR4DerivShp */
00486 
00487 static void _Normal( sCoord coord[3], sCoord *normal )
00488 {
00489  double size;
00490  int first;
00491  int curr;
00492  int prev;
00493  int    i;
00494 
00495  normal->x = 0.0;
00496  normal->y = 0.0;
00497  normal->z = 0.0;
00498  
00499  first = 0;
00500 
00501  for( i = 2; i < 3; i++ )
00502  {
00503   curr = i;
00504   prev = i-1;
00505   
00506   normal->x += (coord[prev].y - coord[first].y) * 
00507                  (coord[curr].z - coord[first].z) -
00508                  (coord[prev].z - coord[first].z) *
00509                  (coord[curr].y - coord[first].y);
00510                  
00511   normal->y += (coord[prev].x - coord[first].x) * 
00512                  (coord[curr].z - coord[first].z) +
00513                  (coord[prev].z - coord[first].z) *
00514                  (coord[curr].x - coord[first].x);
00515                  
00516   normal->z += (coord[prev].x - coord[first].x) * 
00517                  (coord[curr].y - coord[first].y) -
00518                  (coord[prev].y - coord[first].y) *
00519                  (coord[curr].x - coord[first].x);
00520  }
00521 
00522  size = sqrt( (normal->x) * (normal->x) + (normal->y) *
00523               (normal->y) + (normal->z) * (normal->z) );
00524 
00525  if( size > 0.0 ){
00526   normal->x /= size;
00527   normal->y /= size;
00528   normal->z /= size;
00529  }
00530  
00531 } /* end of _Normal */
00532 
00533 
00534 /*
00535 ** ------------------------------------------------------------------------
00536 ** Subclass methods:
00537 */
00538 static void   TETR4New( int, int, int, int, sElement **, sElement **, sNode * );
00539 static void   TETR4Free                  ( sElement * );
00540 static void   TETR4Read                  ( sElement * );
00541 static int    TETR4ReadInitStress        ( sElement * );
00542 static void   TETR4ReadProfile           ( sElement * );
00543 static void   TETR4MassMatrix            ( sElement *, double * );
00544 static void   TETR4Gravity               ( sElement *, double *, double *,
00545                                                                  double * );
00546 static double TETR4RigidCoeff            ( sElement * );
00547 static void   TETR4Connect               ( sElement *, int * );
00548 static void   TETR4NumNodes              ( sElement *, int * );
00549 static void   TETR4AssVector             ( sElement *, double *, double * );
00550 static void   TETR4TimeStep              ( sElement *, double * );
00551 static void   TETR4InterForce            ( sElement *, sTensor *, double * );
00552 static void   TETR4StressStrain          ( sElement *, double, double *,
00553                                                        double *, sTensor *, 
00554                                                        sTensor * );
00555 static void   TETR4WriteStress           ( sElement *, FILE *, double *, 
00556                                                                double * );
00557 static void   TETR4WriteGaussResult      ( sElement *, FILE *, FILE * );
00558 static void   TETR4WriteNodalResult      ( sElement *, FILE *, FILE * );
00559 static void   TETR4WriteGaussVectorResult( sElement *, int, FILE *, FILE * );
00560 static void   TETR4UpdateStress          ( sElement *, double, double *,
00561                                                                sTensor * );
00562 static void   TETR4PercForces            ( sElement *, double * );
00563 static void   TETR4SetPressure           ( sElement *, double );
00564 static void   TETR4SetInitStress         ( sElement *, sTensor * );
00565 static void   TETR4ViscoForce            ( sElement *, double, sTensor *, 
00566                                            double * );                                                                                     
00567 static void TETR4KMatrix( sElement *, double [24][24] );                                                                         
00568 static void TETR4GetDof( sElement *, int [24], int * );
00569 
00570 /*
00571 %F This function computes the equivalent load applied to the element 
00572    face.
00573 */
00574 static void TETR4Load( sElement *elm, eLoadType ltype, int key,
00575                        int noi, int noj, int nok, int *nol,
00576                        double *q1x, double *q1y, double *q1z,
00577                        double *q2x, double *q2y, double *q2z,
00578                        double *q3x, double *q3y, double *q3z,
00579                        double *q4x, double *q4y, double *q4z )
00580 {
00581  double l;
00582  double v1x = (*q1x);
00583  double v1y = (*q1y);
00584  double v1z = (*q1z);
00585  double v2x = (*q2x);
00586  double v2y = (*q2y);
00587  double v2z = (*q2z);
00588  double area;
00589  sCoord normal;
00590  sCoord coord[3]; 
00591  sTetr4Data *data = 0L;
00592  int i, node; 
00593  sCoord vec;
00594  double prod;
00595  
00596  *nol = -1;
00597 
00598 /* Compute the equivalent forces
00599  */
00600  if( ltype == UNIFORM ) {
00601   /* Compute the element edge lenght
00602   */
00603   l = sqrt(((elm->nodes[noi-1].coord.x - elm->nodes[noj-1].coord.x)  *
00604            (elm->nodes[noi-1].coord.x - elm->nodes[noj-1].coord.x)) +
00605           ((elm->nodes[noi-1].coord.y - elm->nodes[noj-1].coord.y)  *
00606            (elm->nodes[noi-1].coord.y - elm->nodes[noj-1].coord.y)) +
00607           ((elm->nodes[noi-1].coord.z - elm->nodes[noj-1].coord.z)  *
00608            (elm->nodes[noi-1].coord.z - elm->nodes[noj-1].coord.z)));
00609            
00610   v1x *= l / 2.0;
00611   v1y *= l / 2.0;
00612   v1z *= l / 2.0;
00613 
00614   (*q1x) = v1x;
00615   (*q1y) = v1y;
00616   (*q1z) = v1z;
00617 
00618   (*q2x) = v1x;
00619   (*q2y) = v1y;
00620   (*q2z) = v1z;
00621  }
00622  if( ltype == AREAUNIFORM ) {
00623         
00624   area = RigidCoeff(elm,noi,noj,nok);
00625   
00626   (*q1x) = 1.0/3.0*v1x*area;
00627   (*q1y) = 1.0/3.0*v1y*area;
00628   (*q1z) = 1.0/3.0*v1z*area;
00629   (*q2x) = 1.0/3.0*v1x*area;
00630   (*q2y) = 1.0/3.0*v1y*area;
00631   (*q2z) = 1.0/3.0*v1z*area;
00632   (*q3x) = 1.0/3.0*v1x*area;
00633   (*q3y) = 1.0/3.0*v1y*area;
00634   (*q3z) = 1.0/3.0*v1z*area;
00635  }
00636  if( ltype == AREAPRESSURE ) {
00637         
00638   area = RigidCoeff(elm,noi,noj,nok);
00639   
00640   coord[0].x = elm->nodes[noi-1].coord.x;
00641   coord[0].y = elm->nodes[noi-1].coord.y;
00642   coord[0].z = elm->nodes[noi-1].coord.z;
00643   coord[1].x = elm->nodes[noj-1].coord.x;
00644   coord[1].y = elm->nodes[noj-1].coord.y;
00645   coord[1].z = elm->nodes[noj-1].coord.z;
00646   coord[2].x = elm->nodes[nok-1].coord.x;
00647   coord[2].y = elm->nodes[nok-1].coord.y;
00648   coord[2].z = elm->nodes[nok-1].coord.z;
00649   
00650   _Normal( coord, &normal );
00651   
00652   /* para garantir a direção da carga*/
00653   
00654   data = (sTetr4Data *)elm->data;
00655   for( i = 0; i < data->NumNodes; i++ ) {
00656    if((data->inc[i]!=noi)&&(data->inc[i]!=noj)&&(data->inc[i]!=nok)){
00657     node = data->inc[i];
00658    }
00659   }
00660           
00661   vec.x = (elm->nodes[noi-1].coord.x - NodeVector[node-1].coord.x);
00662   vec.y = (elm->nodes[noi-1].coord.y - NodeVector[node-1].coord.y);
00663   vec.z = (elm->nodes[noi-1].coord.z - NodeVector[node-1].coord.z); 
00664   
00665   prod = vec.x * normal.x + vec.y * normal.y + vec.z * normal.z; 
00666   if( prod < 0.0){
00667    normal.x *= (-1.0);
00668    normal.y *= (-1.0);
00669    normal.z *= (-1.0);
00670   }
00671   
00672   (*q1x) = 1.0/3.0 * v1x * (-normal.x) * area;
00673   (*q1y) = 1.0/3.0 * v1x * (-normal.y) * area;
00674   (*q1z) = 1.0/3.0 * v1x * (-normal.z) * area;
00675   (*q2x) = 1.0/3.0 * v1x * (-normal.x) * area;
00676   (*q2y) = 1.0/3.0 * v1x * (-normal.y) * area;
00677   (*q2z) = 1.0/3.0 * v1x * (-normal.z) * area;
00678   (*q3x) = 1.0/3.0 * v1x * (-normal.x) * area;
00679   (*q3y) = 1.0/3.0 * v1x * (-normal.y) * area;
00680   (*q3z) = 1.0/3.0 * v1x * (-normal.z) * area;
00681  }                                   
00682                                      
00683 } /* End of TETR4Load */             
00684                                      
00685                                      
00686 /*                                   
00687 %F This method allocates memory for a TETR4 element and fills its data 
00688    with the specific data.
00689 %i Element label (number)
00690 %o Element descriptor.
00691 */
00692 static void TETR4New( int label, int matid, int intord, int tckid, 
00693                       sElement **elm, sElement **elist, sNode *nodes )
00694 {
00695  sTetr4Data *data = 0L;
00696 
00697 /* Get memory for the element descriptor
00698  */
00699  (*elm) = (sElement *)calloc( 1, sizeof(sElement) );
00700 
00701 /* Get memory for the TETR4 element data
00702  */
00703  data = (sTetr4Data *)calloc( 1, sizeof(sTetr4Data) );
00704 
00705 /* Fill TETR4 element data
00706  */
00707  data->matid       = matid;
00708  data->tckid       = tckid;
00709  data->NumNodes    = 4;
00710  data->NumTensComp = 6;
00711  data->effdef      = 0.0;
00712  data->prof        = 0.0;
00713  data->istr[0]     = 0.0;
00714  data->istr[1]     = 0.0;
00715  data->istr[2]     = 0.0;
00716  data->istr[3]     = 0.0;
00717  data->istr[4]     = 0.0;
00718  data->istr[5]     = 0.0;
00719  
00720 /* Fill element descriptor
00721  */
00722  (*elm)->type    = TETR4;
00723  (*elm)->rezone  = NONE;
00724  (*elm)->display = DSP_NO;
00725  (*elm)->curve   = 0;
00726  (*elm)->label   = label;
00727  (*elm)->data    = (void *)data;
00728  (*elm)->nodes   = nodes;
00729 
00730 /* Add to the element list
00731  */
00732  elist[label-1] = (*elm);
00733 
00734 } /* End of TETR4New */
00735 
00736 
00737 /*
00738 %F This method frees the TETR4 element data for a given element.
00739 %i Element descriptor.
00740 */
00741 static void TETR4Free( sElement *elm )
00742 {
00743  sTetr4Data *data = 0L;
00744 
00745 /* Get TETR4 element data
00746  */
00747  data = (sTetr4Data *)elm->data;
00748 
00749 /* Release allocated memory
00750  */
00751  free( data );
00752 
00753 /* Reset element data
00754  */
00755  elm->data = 0L;
00756 
00757 } /* End of TETR4Free */
00758 
00759 
00760 /*
00761 %F This method reads the TETR4 element information.
00762 %i Element descriptor.
00763 */
00764 static void TETR4Read( sElement *elm )
00765 {
00766  sTetr4Data *data = 0L;
00767  int         i1, i2, i3, i4;
00768 
00769 /* Get the element data
00770  */
00771  data = (sTetr4Data *)elm->data;
00772 
00773 /* Read the element incidence
00774  */
00775  fscanf( nf, "%d %d %d %d", &i1, &i2, &i3, &i4 );
00776 
00777 /* Fill element information
00778  */
00779  data->inc[0] = i1;
00780  data->inc[1] = i2;
00781  data->inc[2] = i3;
00782  data->inc[3] = i4;
00783 
00784 } /* End of TETR4Read */
00785 
00786 
00787 /*
00788 %F This method reads the TETR4 initial stress
00789 */
00790 static int TETR4ReadInitStress( sElement *elm )
00791 {
00792  int         numpg = 1;
00793  double      sxx, sxy, sxz;
00794  double      syy, syz, szz;
00795  sTetr4Data *data = 0L;
00796 
00797 /* Get element data
00798  */
00799  data = (sTetr4Data *)elm->data;
00800 
00801 /* Read the number of integration points and check to see if is compatible
00802  * whith the element type.
00803  */
00804  /*fscanf( nf, "%d", &numpg );*/
00805  if( numpg != 1 )
00806  {
00807   printf( "\n\nNumber of gauss points must be equal to one.\n\n" );
00808   return 0;
00809  }
00810  
00811 
00812 /* Read the initial stress information
00813  */
00814  fscanf( nf, "%lf %lf %lf %lf %lf %lf", &sxx, &syy, &szz, &sxy, &sxz, &syz );
00815  data->istr[0] = sxx;
00816  data->istr[1] = syy;
00817  data->istr[2] = szz;
00818  data->istr[3] = sxy;
00819  data->istr[4] = sxz;
00820  data->istr[5] = syz;
00821 
00822  return 1;
00823 
00824 } /* End of TETR4ReadInitStress */
00825 
00826 /*
00827 %F This method reads the TETRA4 profile
00828 */
00829 static void TETRA4ReadProfile( sElement *elm )
00830 {
00831  double prof;
00832  sTetr4Data *data = 0L;
00833 
00834 /* Get element data
00835  */
00836  data = (sTetr4Data *)elm->data;
00837 
00838 /* Read the element profile
00839  */
00840  fscanf( nf, "%lf ", &prof);
00841  data->prof = prof;
00842 
00843 } /* End of TETRA4ReadProfile */
00844 
00845 /*
00846 %F This method computes the mass matrix for the TETR4 element.
00847 %i Element descriptor.
00848 %o Element mass matrix.
00849 */
00850 static void TETR4MassMatrix( sElement *elm, double *mass )
00851 {
00852  sTetr4Data *data = 0L;
00853  sCoord      coord[4];
00854  double      shape[4], jac[3][3];
00855  double      dens, detjac, coeff;
00856  int         i, j;
00857 
00858 /* Initialize mass vector
00859  */
00860  for( i = 0; i < 12; i++ )
00861   mass[i] = 0.0;
00862 
00863 /* Get element coordinates
00864  */
00865  _TETR4GetCoord( elm, coord );
00866 
00867 /* Get material density
00868  */
00869  data = (sTetr4Data *)elm->data;
00870  MatDensity( MatList[data->matid-1], &dens );
00871 
00872 /* Compute shape functions
00873  */
00874  _TETR4ShapeFunc( _GPoint, _GPoint, _GPoint, shape );
00875 
00876 /* Compute the jacobian matrix
00877  */
00878  _TETR4Jacobian( _GPoint, _GPoint, _GPoint, coord, &detjac, jac );
00879 
00880 /* Rigidity coefficient
00881  */ 
00882  coeff = dens * detjac * _GWeight;
00883 
00884 /* Compute mass
00885  */
00886  for( i = 0; i < 4; i++ ) {
00887   for( j = 0; j < 4; j++ ) {
00888    mass[3*i]   += coeff * shape[i] * shape[j];
00889    mass[3*i+1] += coeff * shape[i] * shape[j];
00890    mass[3*i+2] += coeff * shape[i] * shape[j];
00891   }
00892  }
00893 
00894 } /* End of TETR4MassMatrix */
00895 
00896 
00897 /*
00898 %F This functions computes the element rigidity coefficient.
00899 %i Element descriptor.
00900 %o Element rigidity coefficient.
00901 */
00902 static double TETR4RigidCoeff( sElement *elm )
00903 {
00904  sCoord coord[4];
00905  double jac[3][3];
00906  double detjac, volume = 0.0;
00907 
00908 /* Get element coordinates
00909  */
00910  _TETR4GetCoord( elm, coord );
00911 
00912 /* Compute the jacobian matrix
00913  */
00914  _TETR4Jacobian( _GPoint, _GPoint, _GPoint, coord, &detjac, jac );
00915 
00916 /* Rigidity coefficient
00917  */
00918  volume = detjac * _GWeight;
00919 
00920  return volume;
00921 
00922 } /* End of TETR4RigidCoeff */
00923 
00924 
00925 /*
00926 %F
00927 */
00928 static void TETR4Connect( sElement *elm, int *conn )
00929 {
00930  int         i;
00931  sTetr4Data *data = 0L;
00932 
00933  data = (sTetr4Data *)elm->data;
00934 
00935  for( i = 0; i < data->NumNodes; i++ )
00936   conn[i] = data->inc[i];
00937 
00938 } /* End of TETR4Connect */
00939 
00940 
00941 /*
00942 %F
00943 */
00944 static void TETR4NumNodes( sElement *elm, int *nnodes )
00945 {
00946  sTetr4Data *data = (sTetr4Data *)elm->data;
00947 
00948  (*nnodes) = data->NumNodes;
00949 
00950 } /* End of TETR4NumNodes */
00951 
00952 
00953 /*
00954 %F
00955 */
00956 static void TETR4AssVector( sElement *elm, double *GMatrix, double *matrix )
00957 {
00958  int         i;
00959  int         conn[4];
00960  sTetr4Data *data;
00961 
00962 /* Get the element data
00963  */
00964  data = (sTetr4Data *)elm->data;
00965 
00966 /* Get element connectivity
00967  */
00968  ElmConnect( elm, conn );
00969 
00970 /* Assemble matrix
00971  */
00972  for( i = 0; i < data->NumNodes; i++ ) {
00973   GMatrix[3*(conn[i]-1)]   += matrix[3*i];
00974   GMatrix[3*(conn[i]-1)+1] += matrix[3*i+1];
00975   GMatrix[3*(conn[i]-1)+2] += matrix[3*i+2];
00976  }
00977 
00978 } /* End of TETR4AssVector */
00979 
00980 
00981 /*
00982 %F
00983 */
00984 
00985 static void TETR4StressStrain( sElement *elm, double dt, double *U,
00986                                               double *yield, sTensor *stre, 
00987                                               sTensor *stra )
00988 {
00989  sTetr4Data *data = 0L;
00990  sMaterial  *mat  = 0L;
00991  sCoord      coord[4];
00992  double      cm[6][6];
00993  double      bm[6][12];
00994  double      ue[12];
00995  double      def[6], str[6];
00996  double      pf = 1.0;
00997  int         i, j;
00998  double     poropressure;
00999  double     lambda, gamma;
01000  double     distance;
01001  
01002  
01003 /* Get element descriptor
01004  */
01005  data = (sTetr4Data *)elm->data;
01006  
01007 /* Get Material object
01008  */
01009  mat = MatList[data->matid-1];
01010  
01011 /* Get element coordinates
01012  */
01013  _TETR4GetCoord( elm, coord );
01014 
01015 /* Get element displacement
01016  */
01017  _TETR4GetDisplacement( elm, U, ue );
01018 
01019 /* Update the material parameter
01020  */
01021  MatUpdateParameter( mat, data->effdef );
01022 
01023 /* Get material constitutive matrix
01024  */
01025  MatConstitutiveMatrix( mat, cm );
01026 
01027 /* Get element stress x strain matrix
01028  */
01029  _TETR4BMatrix( _GPoint, _GPoint, _GPoint, coord, bm );
01030 
01031 /* Compute the deformations
01032  */
01033  for( i = 0; i < 6; i++ ) {
01034   def[i] = 0.0; 
01035   for( j = 0; j < (3*data->NumNodes); j++ )
01036    def[i] += bm[i][j] * ue[j];
01037  }
01038 
01039 /* Compute the element stress
01040  */
01041  for( i = 0; i < 6; i++ ) {
01042   str[i] = 0.0;
01043   for( j = 0; j < 6; j++ )
01044    str[i] += cm[i][j] * def[j];
01045   str[i] += data->istr[i];
01046  }
01047  
01048 /* Get element lambda
01049  */
01050  lambda = MatList[data->matid-1]->Lambda;
01051  
01052  if(lambda>0.0){
01053  
01054   /* Get element gamma
01055   */
01056   MatDensity( mat, &gamma );
01057  
01058   /* Get element prof
01059   */
01060   distance = data->prof;
01061  
01062   /* Compute the poropressure
01063   */ 
01064   poropressure = lambda*gamma*GForce*distance*Config.loadfactor;
01065   
01066   /* Compute efective stress
01067   */
01068   for( i = 0; i < 3; i++ ) {
01069    str[i] += poropressure;
01070   }
01071  
01072   /* Correct stress based on the material model
01073   */
01074   MatUpdateStress( mat, dt, &pf, &data->effdef, str, def );
01075  
01076   /* Compute total stress
01077   */
01078   for( i = 0; i < 3; i++ ) {
01079    str[i] -= poropressure;
01080   }
01081  }
01082  else{
01083 
01084   /* Correct stress based on the material model
01085   */
01086   MatUpdateStress( mat, dt, &pf, &data->effdef, str, def );
01087  
01088  }
01089 /* Set stress values
01090  */
01091  stre->xx = str[0];
01092  stre->yy = str[1];
01093  stre->zz = str[2];
01094  stre->xy = str[3];
01095  stre->yz = str[4];
01096  stre->xz = str[5];
01097 
01098 /* Set strain values
01099  */
01100  if( stra != 0L ) {
01101   stra->xx = def[0];
01102   stra->yy = def[1];
01103   stra->zz = def[2];
01104   stra->xy = def[3];
01105   stra->yz = def[4];
01106   stra->xz = def[5];
01107  }
01108 
01109 /* Set yield parameter
01110  */
01111  if( yield != 0L )
01112   (*yield) = (pf > 0.0) ? 0.0 : 1.0;
01113 
01114 } /* End of TETR4StressStrain */
01115 
01116 
01117 /*
01118 %F This function computes the internal forces for the T3 element
01119 */
01120 static void TETR4InterForce( sElement *elm, sTensor *stress, 
01121                                             double *intforce )
01122 {
01123  int         i, j;
01124  double      coeff;
01125  double      bm[6][12], str[6], jac[3][3];
01126  sCoord      coord[4];
01127  sTetr4Data *data = 0L;
01128 
01129 /* Get element descriptor
01130  */
01131  data = (sTetr4Data *)elm->data;
01132 
01133 /* Get element coordinates
01134  */
01135  _TETR4GetCoord( elm, coord );
01136 
01137 /* Compute element B matrix
01138  */
01139  _TETR4BMatrix( _GPoint, _GPoint, _GPoint, coord, bm );
01140 
01141 /* Compute rigidity coefficient
01142  */
01143  _TETR4Jacobian( _GPoint, _GPoint, _GPoint, coord, &coeff, jac );
01144 
01145  coeff *= _GWeight;
01146 
01147 /* Check for the initial stress
01148  */
01149  if( stress == 0L ) {
01150   for( i = 0; i < (3*data->NumNodes); i++ ) {
01151    intforce[i] = 0.0;
01152    for( j = 0; j < 6; j++ )
01153     intforce[i] += bm[j][i] * data->istr[j];
01154    intforce[i] *= coeff;
01155   }
01156   return;
01157  }
01158 
01159 /* Get element stress
01160  */
01161  str[0] = stress->xx;
01162  str[1] = stress->yy;
01163  str[2] = stress->zz;
01164  str[3] = stress->xy;
01165  str[4] = stress->yz;
01166  str[5] = stress->xz;
01167 
01168 /* Compute element internal forces for the current gauss point
01169  */
01170  for( i = 0; i < (3*data->NumNodes); i++ ) {
01171   intforce[i] = 0.0;
01172   for( j = 0; j < 6; j++ )
01173    intforce[i] += bm[j][i] * str[j];
01174   intforce[i] *= -coeff;
01175  }  
01176 
01177 } /* End of TETR4InterForce */
01178 
01179 
01180 /*
01181 %F
01182 */
01183 static void TETR4WriteStress( sElement *elm, FILE *out, double *U, double *V )
01184 {
01185  sTensor  stress, strain, strd;
01186  sPTensor pstr;
01187  double   yield;
01188 
01189 /* Check to see if the element was rezoned
01190  */
01191  if( elm->rezone == DONE ) {
01192 
01193  /* Set the stress and strain to 0
01194   */
01195   stress.xx = stress.xy = stress.xz =
01196               stress.yy = stress.yz =
01197                           stress.zz = 0.0;
01198   strd.xx = strd.xy = strd.xz =
01199             strd.yy = strd.yz =
01200                       strd.zz = 0.0;
01201   strain.xx = strain.xy = strain.xz =
01202               strain.yy = strain.yz =
01203                           strain.zz = 0.0;
01204   yield = 0.0;
01205  }
01206  else {
01207  /* Compute the element stress and strain
01208   */
01209   TETR4StressStrain( elm, 0.0, U, &yield, &stress, &strain );
01210  }
01211 
01212 /* Compute desviatory stress
01213  */
01214  PrincipalTensor( &stress, &pstr);
01215 
01216  strd.xx = stress.xx - ((pstr.dir1 + pstr.dir2 + pstr.dir3)/3.0);
01217  strd.yy = stress.yy - ((pstr.dir1 + pstr.dir2 + pstr.dir3)/3.0);
01218  strd.zz = stress.zz - ((pstr.dir1 + pstr.dir2 + pstr.dir3)/3.0);
01219 
01220 /* Write element stress and strain
01221  */
01222  fwrite( &stress, sizeof(sTensor), 1, out );
01223  fwrite( &strain, sizeof(sTensor), 1, out );
01224  fwrite( &strd, sizeof(sTensor), 1, out );
01225  fwrite( &yield, sizeof(double), 1, out );
01226 
01227 } /* End of TETR4WriteStress */
01228 
01229 
01230 /*
01231 %F
01232 */
01233 static void TETR4WriteNodalResult( sElement *elm, FILE *out, FILE *tmp )
01234 {
01235  sTensor  str, strd, def;
01236  sPTensor pstress, pstrain;
01237  double   yield;
01238  int      i;
01239 
01240 /* Read results from temporary file
01241  */
01242  fread( &str, sizeof(sTensor), 1, tmp );
01243  fread( &def, sizeof(sTensor), 1, tmp );
01244  fread( &strd, sizeof(sTensor), 1, tmp );
01245  fread( &yield, sizeof(double), 1, tmp );
01246 
01247 /* Write results on output file
01248  */
01249  fprintf( out, "%d\n", elm->label );
01250  PrincipalTensor( &str, &pstress );
01251  PrincipalTensor( &def, &pstrain );
01252  for( i = 0; i < 4; i++ ) {
01253   fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t", str.xx, str.yy, str.zz );
01254   fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t", str.xy, str.xz, str.yz );
01255   fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t", pstress.dir1,
01256                                                pstress.dir2,
01257                                                pstress.dir3 );
01258   fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t", strd.xx, strd.yy, strd.zz );
01259   fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t", def.xx, def.yy, def.zz );
01260   fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t", def.xy, def.xz, def.yz );
01261   fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t", pstrain.dir1,
01262                                                pstrain.dir2,
01263                                                pstrain.dir3 );
01264   fprintf( out, "%+10.5e\n", yield );
01265  }
01266 
01267 } /* End of TETR4WriteNodalResult */
01268 
01269 
01270 /*
01271 %F
01272 */
01273 static void TETR4WriteGaussResult( sElement *elm, FILE *out, FILE *tmp )
01274 {
01275  sTensor  stress, strain, strd;
01276  sPTensor pstress, pstrain;
01277  double   yield;
01278  int      j;
01279 
01280 /* Read results from temporary file
01281  */
01282  fread( &stress, sizeof(sTensor), 1, tmp );
01283  fread( &strain, sizeof(sTensor), 1, tmp );
01284  fread( &strd, sizeof(sTensor), 1, tmp );
01285  fread( &yield, sizeof(double), 1, tmp );
01286 
01287 /* Write results on output file
01288  */
01289  fprintf( out, "%d\t%d\n", elm->label, 1 );
01290  PrincipalTensor( &stress, &pstress );
01291  PrincipalTensor( &strain, &pstrain );
01292  
01293  for( j = 0; j < Config.numgaussresults; j++){
01294    if((strcmp( Config.gaussresults[j], "Sxx" ) == 0))
01295     fprintf( out, "%+10.5e\t", stress.xx );
01296    else if((strcmp( Config.gaussresults[j], "Syy" ) == 0))
01297     fprintf( out, "%+10.5e\t", stress.yy );
01298    else if((strcmp( Config.gaussresults[j], "Szz" ) == 0))
01299     fprintf( out, "%+10.5e\t", stress.zz );
01300    else if((strcmp( Config.gaussresults[j], "Sxy" ) == 0))
01301     fprintf( out, "%+10.5e\t", stress.xy );
01302    else if((strcmp( Config.gaussresults[j], "Sxz" ) == 0))
01303     fprintf( out, "%+10.5e\t", stress.xz );
01304    else if((strcmp( Config.gaussresults[j], "Syz" ) == 0))
01305     fprintf( out, "%+10.5e\t", stress.yz );
01306    else if((strcmp( Config.gaussresults[j], "S1" ) == 0))
01307     fprintf( out, "%+10.5e\t", pstress.dir1 );
01308    else if((strcmp( Config.gaussresults[j], "S2" ) == 0))
01309     fprintf( out, "%+10.5e\t", pstress.dir2 );
01310    else if((strcmp( Config.gaussresults[j], "S3" ) == 0))
01311     fprintf( out, "%+10.5e\t", pstress.dir3 );
01312    else if((strcmp( Config.gaussresults[j], "Sdx" ) == 0))
01313     fprintf( out, "%+10.5e\t", strd.xx );
01314    else if((strcmp( Config.gaussresults[j], "Sdy" ) == 0))
01315     fprintf( out, "%+10.5e\t", strd.yy );
01316    else if((strcmp( Config.gaussresults[j], "Sdz" ) == 0))
01317     fprintf( out, "%+10.5e\t", strd.zz );
01318    else if((strcmp( Config.gaussresults[j], "Exx" ) == 0))
01319     fprintf( out, "%+10.5e\t", strain.xx );
01320    else if((strcmp( Config.gaussresults[j], "Eyy" ) == 0))
01321     fprintf( out, "%+10.5e\t", strain.yy );
01322    else if((strcmp( Config.gaussresults[j], "Ezz" ) == 0))
01323     fprintf( out, "%+10.5e\t", strain.zz );
01324    else if((strcmp( Config.gaussresults[j], "Exy" ) == 0))
01325     fprintf( out, "%+10.5e\t", strain.xy );
01326    else if((strcmp( Config.gaussresults[j], "Exz" ) == 0))
01327     fprintf( out, "%+10.5e\t", strain.xz );
01328    else if((strcmp( Config.gaussresults[j], "Eyz" ) == 0))
01329     fprintf( out, "%+10.5e\t", strain.yz );
01330    else if((strcmp( Config.gaussresults[j], "E1" ) == 0))
01331     fprintf( out, "%+10.5e\t", pstrain.dir1 );
01332    else if((strcmp( Config.gaussresults[j], "E2" ) == 0))
01333     fprintf( out, "%+10.5e\t", pstrain.dir2 );
01334    else if((strcmp( Config.gaussresults[j], "E3" ) == 0))
01335     fprintf( out, "%+10.5e\t", pstrain.dir3 );
01336    else if((strcmp( Config.gaussresults[j], "Ev" ) == 0))
01337     fprintf( out, "%+10.5e\t", (pstrain.dir1+pstrain.dir2+pstrain.dir3) );
01338   }
01339 
01340 } /* End of TETR4WriteGaussResult */
01341 
01342 
01343 /*
01344 %F
01345 */
01346 static void TETR4WriteGaussVectorResult( sElement *elm, int version,
01347                                          FILE *out, FILE *tmp )
01348 {
01349  sTensor  stress, strain, strd;
01350  sPTensor pstress, pstrain;
01351  double   yield;
01352 
01353 /* Read results from temporary file
01354  */
01355  fread( &stress, sizeof(sTensor), 1, tmp );
01356  fread( &strain, sizeof(sTensor), 1, tmp );
01357  fread( &strd, sizeof(sTensor), 1, tmp );
01358  fread( &yield, sizeof(double), 1, tmp );
01359 
01360 /* Write results on output file
01361  */
01362  fprintf( out, "%d\t%d\n", elm->label, 1 );
01363  PrincipalTensor( &stress, &pstress );
01364  PrincipalTensor( &strain, &pstrain );
01365  if( version > 1 ) {
01366   fprintf( out, "%+10.5e\t%+10.5e\n", pstress.dir1, pstrain.dir1 );
01367   fprintf( out, "%+10.5e\t%+10.5e\n", pstress.dir2, pstrain.dir2 );
01368   fprintf( out, "%+10.5e\t%+10.5e\n", pstress.dir3, pstrain.dir3 );
01369   fprintf( out, "%+10.5e\t%+10.5e\n", pstress.cos1x, pstrain.cos1x );
01370   fprintf( out, "%+10.5e\t%+10.5e\n", pstress.cos2x, pstrain.cos2x );
01371   fprintf( out, "%+10.5e\t%+10.5e\n", pstress.cos3x, pstrain.cos3x );
01372   fprintf( out, "%+10.5e\t%+10.5e\n", pstress.cos1y, pstrain.cos1y );
01373   fprintf( out, "%+10.5e\t%+10.5e\n", pstress.cos2y, pstrain.cos2y );
01374   fprintf( out, "%+10.5e\t%+10.5e\n", pstress.cos3y, pstrain.cos3y );
01375   fprintf( out, "%+10.5e\t%+10.5e\n", pstress.cos1z, pstrain.cos1z );
01376   fprintf( out, "%+10.5e\t%+10.5e\n", pstress.cos2z, pstrain.cos2z );
01377   fprintf( out, "%+10.5e\t%+10.5e\n", pstress.cos3z, pstrain.cos3z );
01378  }
01379  else {
01380   if( pstress.dir1 > 0.0 )
01381    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (pstress.dir1*pstress.cos1x),
01382                                                 (pstress.dir1*pstress.cos1y),
01383                                                  0.0 );
01384   else
01385    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01386 
01387   if( pstress.dir1 < 0.0 )
01388    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (pstress.dir1*pstress.cos1x),
01389                                                 (pstress.dir1*pstress.cos1y),
01390                                                  0.0 );
01391   else
01392    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01393 
01394   if( pstress.dir3 > 0.0 )
01395    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (pstress.dir3*pstress.cos3x),
01396                                                 (pstress.dir3*pstress.cos3y),
01397                                                  0.0 );
01398   else
01399    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01400 
01401   if( pstress.dir3 < 0.0 )
01402    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (pstress.dir3*pstress.cos3x),
01403                                                 (pstress.dir3*pstress.cos3y),
01404                                                  0.0 );
01405   else
01406    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01407 
01408   if( pstrain.dir1 > 0.0 )
01409    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (pstrain.dir1*pstrain.cos1x),
01410                                                 (pstrain.dir1*pstrain.cos1y),
01411                                                  0.0 );
01412   else
01413    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01414 
01415   if( pstrain.dir1 < 0.0 )
01416    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (pstrain.dir1*pstrain.cos1x),
01417                                                 (pstrain.dir1*pstrain.cos1y),
01418                                                  0.0 );
01419   else
01420    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01421 
01422   if( pstrain.dir3 > 0.0 )
01423    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (pstrain.dir3*pstrain.cos3x),
01424                                                 (pstrain.dir3*pstrain.cos3y),
01425                                                  0.0 );
01426   else
01427    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01428 
01429   if( pstrain.dir3 < 0.0 )
01430    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (pstrain.dir3*pstrain.cos3x),
01431                                                 (pstrain.dir3*pstrain.cos3y),
01432                                                  0.0 );
01433   else
01434    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01435  }
01436 
01437 } /* End of TETR4WriteGaussVectorResult */
01438 
01439 /*
01440 %F This function update the element stress to reflect the effects of
01441    the larges displacements.
01442 */
01443 static void TETR4UpdateStress( sElement *elm, double dtime, double *V,
01444                                sTensor *stre )
01445 {
01446  sTetr4Data *data = 0L;
01447  sCoord     coord[4];
01448  double     bm[6][12];
01449  double     ve[12];
01450  double     sxx, syy, szz, rot;
01451  int        i;
01452 
01453 /* Get element descriptor
01454  */
01455  data = (sTetr4Data *)elm->data;
01456 
01457 /* Get element coordinates
01458  */
01459  _TETR4GetCoord( elm, coord );
01460 
01461 /* Get element displacement increment
01462  */
01463  _TETR4GetDisplacement( elm, V, ve );
01464 
01465 /* Compute the displacement increment
01466  */
01467  for( i = 0; i < 12; i++ )
01468   ve[i] *= dtime;
01469 
01470 /* Get element stress x strain matrix
01471  */
01472  _TETR4BMatrix( _GPoint, _GPoint, _GPoint, coord, bm );
01473 
01474 /* Compute rotation factor
01475  */
01476  rot = 0.0;
01477  for( i = 0; i < 12; i++ )
01478   rot += bm[2][i] * ve[i] * pow( -1.0, (double)(i+1) );
01479  rot *= 0.5;
01480 
01481 /* Compute the element stress
01482  */
01483  sxx = stre->xx;
01484  syy = stre->yy;
01485  szz = stre->zz;
01486 
01487  stre->xx -= 2.0 * stre->xy * rot;
01488  stre->yy += 2.0 * stre->xy * rot;
01489  stre->xy += (sxx - syy) * rot;
01490 
01491 } /* End of TETR4UpdateStress */
01492 
01493 
01494 /*
01495 %F
01496 */
01497 static void TETR4TimeStep( sElement *elm, double *dt )
01498 {
01499  sCoord      coord[4];
01500  double      hmin, dtime;
01501  sTetr4Data *data = 0L;
01502  sMaterial  *mat  = 0L;
01503 
01504 /* Get element coordinates
01505  */
01506  _TETR4GetCoord( elm, coord );
01507 
01508 /* Compute the element minimum height
01509  */
01510  hmin = _TETR4MinHeight( coord );
01511 
01512 /* Get element data
01513  */
01514  data = (sTetr4Data *)elm->data;
01515 
01516 /* Get material object
01517  */
01518  mat = MatList[data->matid-1];
01519 
01520 /* Compute the time step according the material type
01521  */
01522  MatTimeStep( mat, &dtime );
01523 
01524 /* Compute the time step
01525  */
01526  if( mat->type == KELVIN ) (*dt) = dtime;
01527  else                      (*dt) = hmin * dtime;
01528 
01529 } /* End of TETR4TimeStep */
01530 
01531 
01532 /*
01533 %F This function computes the load due to a gravitational field. The 
01534    gravitational load is given by the product between the element 
01535    volume and the gravity field components.
01536 %i Element descriptor.
01537 %o Load in X direction.
01538 %o Load in Y direction.
01539 %o Load in Z direction.
01540 */
01541 static void TETR4Gravity( sElement *elm, double *qx, double *qy, double *qz )
01542 {
01543  sTetr4Data *data = 0;
01544  sCoord      coord[4];
01545  double      volume, mass, gamma;
01546  int         matid;
01547 
01548 /* Get element data
01549  */
01550  data = (sTetr4Data *)elm->data;
01551 
01552 /* Get element coordinates
01553  */
01554  _TETR4GetCoord( elm, coord );
01555 
01556 /* Compute element area
01557  */
01558  volume = _TETR4Volume( coord );
01559 
01560 /* Get material id, and the material density property
01561  */
01562  matid = data->matid;
01563  MatDensity( MatList[matid-1], &gamma );
01564 
01565 /* Compute the gravitational load
01566  */
01567  mass = (gamma * volume) / 4.0;
01568 
01569  (*qx) = mass * GravForce.gx;
01570  (*qy) = mass * GravForce.gy;
01571  (*qz) = mass * GravForce.gz;
01572 
01573 } /* End of TETR4Gravity */
01574 
01575 
01576 /*
01577 %F This function computes the percolation forces for the TETR4 element.
01578 */
01579 static void TETR4PercForces( sElement *elm, double *pforce )
01580 {
01581  sCoord      coord[4];
01582  sTetr4Data *data = 0L;
01583  sMaterial  *mat  = 0L;
01584  double      bm[6][12], phi[4], jac[3][3], shape[4];
01585  double      detjac;
01586  sTensor     grad;
01587  int         i, k;
01588 
01589 /* Get element coordinates
01590  */
01591  _TETR4GetCoord( elm, coord );
01592 
01593 /* Get element data
01594  */
01595  data = (sTetr4Data *)elm->data;
01596 
01597 /* Get material object
01598  */
01599  mat = MatList[data->matid-1];
01600 
01601 /* Get element pressure
01602  */
01603  for( i = 0; i < data->NumNodes; i++ )
01604   phi[i] = elm->nodes[data->inc[i]-1].dof.psi + coord[i].y;
01605 
01606  for( i = 0; i < 12; i++ )
01607   pforce[i] = 0.0;
01608 
01609 /* Get element stress x strain matrix
01610  */
01611  _TETR4BMatrix( _GPoint, _GPoint, _GPoint, coord, bm );
01612 
01613 /* Get element jacobiam
01614  */
01615  _TETR4Jacobian( _GPoint, _GPoint, _GPoint, coord, &detjac, jac );
01616 
01617  detjac *= _GWeight * mat->Rhof;
01618 
01619 /* Get element shape functions
01620  */
01621  _TETR4ShapeFunc( _GPoint, _GPoint, _GPoint, shape );
01622 
01623 /* Compute gradient
01624  */
01625  grad.xx = grad.yy = grad.zz = 0.0;
01626  for( k = 0; k < 4; k++ ) {
01627   grad.xx += bm[0][3*k] * phi[k];
01628   grad.yy += bm[1][3*k+1] * phi[k];
01629   grad.zz += bm[2][3*k+2] * phi[k];
01630  }
01631 
01632  for( k = 0; k < 4; k++ ) {
01633   pforce[3*k]   += detjac * shape[k] * grad.xx;
01634   pforce[3*k+1] += detjac * shape[k] * grad.yy;
01635   pforce[3*k+2] += detjac * shape[k] * grad.zz;
01636  }
01637 
01638 } /* End of TETR4PercForce */
01639 
01640 
01641 /*
01642 %F
01643 */
01644 static void TETR4SetPressure( sElement *elm, double pot )
01645 {
01646  sCoord      coord[4];
01647  sTetr4Data *data = 0L;
01648  int         i, id;
01649 
01650 /* Get element coordinates
01651  */
01652  _TETR4GetCoord( elm, coord );
01653 
01654 /* Get element data
01655  */
01656  data = (sTetr4Data *)elm->data;
01657 
01658 /* Compute and set the pressure for the element node
01659  */
01660  for( i = 0; i < 4; i++ ) {
01661   id = data->inc[i] - 1;
01662   elm->nodes[id].dof.psi = pot - coord[i].y;
01663  }
01664 
01665 } /* End of TETR4SetPressure */
01666 
01667 /*
01668 %F
01669 */
01670 static void TETR4SetInitStress( sElement *elm, sTensor *istress )
01671 {
01672  sTetr4Data *data = 0L;
01673  int         i;
01674 
01675 /* Get element data
01676  */
01677  data = (sTetr4Data *)elm->data;
01678 
01679 /* Set initial stress
01680  */
01681  for( i = 0; i < 4; i++ ) {
01682   data->istr[0] = istress->xx;
01683   data->istr[1] = istress->yy;
01684   data->istr[2] = istress->zz;
01685   data->istr[3] = istress->xy;
01686   data->istr[4] = istress->yz;
01687   data->istr[5] = istress->xz;
01688  }
01689 
01690 } /* End of TETR4SetInitStress */
01691 
01692 /*
01693 %F
01694 */
01695 static void TETR4ViscoForce( sElement *elm, double timeStep, sTensor *stress,
01696                              double *vforce )
01697 {
01698  int         i, l, m;
01699  double      coeff;
01700  double      bm[6][12], jac[3][3], cm[6][6];
01701  double      stav[6], strv[6];
01702  sTensor     vsta;
01703  sCoord      coord[4];
01704  sTetr4Data *data = 0L;
01705  sMaterial  *mat  = 0L;
01706 
01707 /* Get element descriptor
01708  */
01709  data = (sTetr4Data *)elm->data;
01710 
01711 /* Get material object
01712  */
01713  mat = MatList[data->matid-1];
01714 
01715 /* Initialize element visco forces vector
01716  */
01717  for( i = 0; i < (3*data->NumNodes); i++ )
01718   vforce[i] = 0.0;
01719 
01720 /* Check to see if the material is a visco one
01721  */
01722  if( !MaterialIsVisco( mat ) )
01723   return;
01724 
01725 /* Get element coordinates
01726  */
01727  _TETR4GetCoord( elm, coord );
01728 
01729 /* Get material constitutive matrix
01730  */
01731  MatConstitutiveMatrix( mat, cm );
01732 
01733 /* Get element stress x strain matrix
01734  */
01735  _TETR4BMatrix( _GPoint, _GPoint, _GPoint, coord, bm );
01736 
01737 /* Get element jacobiam
01738  */
01739  _TETR4Jacobian( _GPoint, _GPoint, _GPoint, coord, &coeff, jac );
01740 
01741  coeff *= _GWeight;
01742 
01743 /* Compute visco stress
01744  */
01745  MatViscoStrain( mat, timeStep, stress, &vsta );
01746 
01747 /* Get viscos strain components
01748  */
01749  stav[0] = vsta.xx;
01750  stav[1] = vsta.yy;
01751  stav[2] = vsta.zz;
01752  stav[3] = vsta.xy;
01753  stav[4] = vsta.yz;
01754  stav[5] = vsta.xz;
01755 
01756 /* Compute viscos stress
01757  */
01758  for( m = 0; m < 6; m++ ) {
01759   strv[m] = 0.0;
01760   for( l = 0; l < 6; l++ )
01761    strv[m] += cm[m][l] * stav[l];
01762  }
01763 
01764 /* Compute element visco forces for the current gauss point
01765  */
01766  for( m = 0; m < (3*data->NumNodes); m++ ) {
01767   vforce[m] = 0.0;
01768   for( l = 0; l < 6; l++ )
01769    vforce[m] += bm[l][m] * strv[l];
01770   vforce[m] *= coeff;
01771  } 
01772 
01773 } /* End of TETR4ViscoForce */
01774 
01775 /*============================ TETR4Kmatrix ===========================*/
01776 
01777 static void TETR4KMatrix( sElement *elm, double k[24][24] )
01778 {           
01779  int    i, j, l;           
01780  sCoord  coord[4];          
01781  double jac[3][3];         
01782  double detjac;            
01783  double C[6][6];          
01784  double B[6][12];          
01785  double BTC[12][6];        
01786  double ke[24][24]; 
01787  sTetr4Data  *data = 0L;
01788  sMaterial  *mat  = 0L;       
01789 
01790  /* Inicia matriz k = 0
01791  */
01792  for( i = 0; i < 24; i++ ) {
01793   for( j = 0; j < 24; j++ ) {
01794    k[i][j] = 0.0;
01795   }
01796  }
01797  
01798  /* Pega descrição do elemento
01799  */
01800  data = (sTetr4Data *)elm->data;
01801  
01802 /* Pega material
01803  */
01804  mat = MatList[data->matid-1];
01805  
01806  /* Pega as coordenadas nodais
01807  */
01808  _TETR4GetCoord(elm, coord);
01809  
01810  /* Pega matriz constitutiva [C]*/
01811  MatConstitutiveMatrix( mat, C );
01812 
01813  /* Calcula matriz B*/
01814  _TETR4BMatrix( _GPoint, _GPoint, _GPoint, coord, B );
01815  /* Calcula o determinante do jacobiano */
01816  _TETR4Jacobian( _GPoint, _GPoint, _GPoint, coord, &detjac, jac );
01817 
01818  /* Calcula [B] transposto * [C] */
01819  for( i = 0; i < 12; i++ ) {
01820   for( j = 0; j < 6; j++)  {
01821    BTC[i][j] =0.0;
01822    for(l=0; l<6; l++){
01823     BTC[i][j] += B[l][i]*C[l][j];
01824    }
01825   }
01826  }
01827  /* Calcula [B] transposto * [C] * [B] * |jac|*/
01828  for( i = 0; i < 12; i++ ) {
01829   for( j = 0; j < 12; j++)  {
01830    ke[i][j] =0.0;
01831    for(l=0; l<6; l++){
01832     ke[i][j] += BTC[i][l]*B[l][j]*detjac*_GWeight;
01833    }
01834   }
01835  }
01836  /* Calcula matriz de rigidez do elemento*/
01837  for( i = 0; i < 24; i++ ) {
01838   for( j = 0; j < 24; j++)  {
01839    k[i][j] += ke[i][j];
01840   }
01841  }
01842    
01843 } /* TETR4KMatrix */
01844 
01845 static void TETR4GetDof( sElement *elm, int u[24], int *index )
01846 {
01847  sTetr4Data *data = 0L;
01848  int        i;
01849 
01850 /* Get element descriptor
01851  */
01852  data = (sTetr4Data *)elm->data;
01853 
01854 /* Fill element dof
01855  */
01856  for( i = 0; i < data->NumNodes; i++ ) {
01857   u[3*i]   = 3*(data->inc[i]-1);
01858   u[3*i+1] = 3*(data->inc[i]-1)+1;
01859   u[3*i+2] = 3*(data->inc[i]-1)+2;
01860  }
01861  
01862  *index = 12;
01863 
01864 } /* End of _TETR4GetDof */
01865 
01866 static void TETR4GetInc( sElement *elm, int inc[8], int *index )
01867 {
01868  sTetr4Data *data = 0L;
01869  int        i;
01870 
01871 /* Get element descriptor
01872  */
01873  data = (sTetr4Data *)elm->data;
01874 
01875 /* Fill element dof
01876  */
01877  for( i = 0; i < data->NumNodes; i++ ) {
01878   inc[i]   = data->inc[i]-1;
01879  }
01880  
01881  *index = 4;
01882 
01883 } /* End of TETR4GetInc */
01884 
01885 
01886 /*
01887 ** ------------------------------------------------------------------------
01888 ** Public functions:
01889 */
01890 
01891 /*
01892 %F This function initializes the sub-class "TETR4".
01893 */
01894 void TETR4Init( void );
01895 void TETR4Init( void )
01896 {
01897 /* Initialize TETR4 element sub-class
01898  */
01899  ElmClass[TETR4].new               = TETR4New;
01900  ElmClass[TETR4].free              = TETR4Free;
01901  ElmClass[TETR4].read              = TETR4Read;
01902  ElmClass[TETR4].readinitstr       = TETR4ReadInitStress;
01903  ElmClass[TETR4].readprofile       = TETRA4ReadProfile;
01904  ElmClass[TETR4].mass              = TETR4MassMatrix;
01905  ElmClass[TETR4].rigidcoeff        = TETR4RigidCoeff;
01906  ElmClass[TETR4].load              = TETR4Load; 
01907  ElmClass[TETR4].connect           = TETR4Connect;
01908  ElmClass[TETR4].numnodes          = TETR4NumNodes;
01909  ElmClass[TETR4].gravity           = TETR4Gravity;
01910  ElmClass[TETR4].assvector         = TETR4AssVector;
01911  ElmClass[TETR4].strstrain         = TETR4StressStrain;
01912  ElmClass[TETR4].timestep          = TETR4TimeStep;
01913  ElmClass[TETR4].intforce          = TETR4InterForce;
01914  ElmClass[TETR4].writestr          = TETR4WriteStress;
01915  ElmClass[TETR4].writendlresult    = TETR4WriteNodalResult;
01916  ElmClass[TETR4].writegauresult    = TETR4WriteGaussResult;
01917  ElmClass[TETR4].writegauvecresult = TETR4WriteGaussVectorResult;
01918  ElmClass[TETR4].updatestress      = TETR4UpdateStress;
01919  ElmClass[TETR4].percforce         = TETR4PercForces;
01920  ElmClass[TETR4].setpressure       = TETR4SetPressure;
01921  ElmClass[TETR4].setinitstress     = TETR4SetInitStress;
01922  ElmClass[TETR4].viscoforce        = TETR4ViscoForce;
01923  ElmClass[TETR4].jacobian          = 0L;
01924  ElmClass[TETR4].volume            = 0L;
01925  ElmClass[TETR4].KMatrix           = TETR4KMatrix;
01926  ElmClass[TETR4].GetDof            = TETR4GetDof;
01927  ElmClass[TETR4].GetInc            = TETR4GetInc;
01928 } /* End of TETR4Init */
01929 
01930 
01931 /* =======================================================  End of File  */
01932 

Generated on Tue Oct 23 11:23:30 2007 for Relax by  doxygen 1.5.3