inf.c

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

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