t3.c

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

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