brk8.c

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

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