dkt.c

Go to the documentation of this file.
00001 /*
00002 %M This modules contains the DKT element sub-class methods and 
00003    definitions
00004 %a André Luis Muller.
00005 %d 08-2007.
00006 OBS: a implementação desse elemento difere do elemento (discrete Kirchhoff triangle)
00007      original, afim de atender algumas especificações do programa Recon.
00008 
00009 /*
00010 ** ------------------------------------------------------------------------
00011 ** Global variables and symbols:
00012 */
00013 #include <stdio.h>
00014 #include <stdlib.h>
00015 #include <string.h>
00016 #include <math.h>
00017 
00018 #include "rio.h"
00019 #include "load.h"
00020 #include "elm.h"
00021 #include "node.h"
00022 #include "material.h"
00023 #include "load.h"
00024 #include "alg.h"
00025 
00026 
00027 /*
00028 ** ------------------------------------------------------------------------
00029 ** Local variables and symbols:
00030 */
00031 
00032 /*
00033 %T DKT element data definition
00034 */
00035 typedef struct _dktelm {
00036  int      matid;             /* Material identification          */
00037  int      tckid;             /* Element thickness identification */
00038  int      NumNodes;          /* Number of element nodes          */
00039  int      NumTensComp;       /* Number of tension components     */
00040  int      inc[3];            /* Element incidence                */
00041  double   istr[4];           /* Element initial stress           */
00042  double   effdef;            /* Effective deformation            */
00043  sTensor *iPress;            /* Element internal pressure        */
00044  double prof;                /* Element profile                  */
00045 } sDKTData;
00046 
00047 /*
00048 %V Gauss point coordinates 
00049 */
00050 static double _GPoint  = 0.3333333;
00051 
00052 /*
00053 ** ------------------------------------------------------------------------
00054 ** Local functions:
00055 */
00056 static void   _DKTGetCoord       ( sElement *, sCoord [] );
00057 static double _DKTArea           ( sCoord [] );
00058 static double _DKTMinHeight      ( sCoord [] );
00059 static void   _DKTGetDisplacement( sElement *, double *, double [] );
00060 static void   _DKTBMatrix        ( sElement *, double [6][9] );
00061 static void   _DKTDerivShp       ( double, double, double, sDerivRST [] );
00062 
00063 /*
00064 %F This function gets the element coordinates.
00065 %i Element descriptor.
00066 %o Element coordinares.
00067 */
00068 static void _DKTGetCoord( sElement *elm, sCoord coord[3] )
00069 {
00070  sDKTData *data = 0L;
00071  int      i;
00072 
00073 /* Element element data
00074  */
00075  data = (sDKTData *)elm->data;
00076 
00077 /* Get element coordinates
00078  */
00079  for( i = 0; i < 3; i++ ) {
00080   coord[i].x = elm->nodes[data->inc[i]-1].coord.x;
00081   coord[i].y = elm->nodes[data->inc[i]-1].coord.y;
00082   coord[i].z = elm->nodes[data->inc[i]-1].coord.z;
00083  }
00084 
00085 } /* End of _DKTGetCoord */
00086 
00087 
00088 /*
00089 %F This function computes the element area
00090 %i Element coordinates.
00091 %o Element area.
00092 */
00093 static double _DKTArea( sCoord coord[3] )
00094 {
00095  double area = 0.0;
00096  double u[3],v[3],w[3];
00097 /* Computes element area
00098  */
00099  u[0] = coord[1].x - coord[0].x;
00100  u[1] = coord[1].y - coord[0].y; 
00101  u[2] = coord[1].z - coord[0].z;
00102  v[0] = coord[2].x - coord[0].x; 
00103  v[1] = coord[2].y - coord[0].y; 
00104  v[2] = coord[2].z - coord[0].z;
00105 
00106  w[0] = u[1] * v[2] - u[2] * v[1];
00107  w[1] = u[2] * v[0] - u[0] * v[2];
00108  w[2] = u[0] * v[1] - u[1] * v[0];
00109  area = sqrt(w[0]*w[0] + w[1]*w[1] + w[2]*w[2]) / 2.0;
00110 
00111  return( area );
00112 
00113 } /* End of _DKTArea */
00114 
00115 
00116 /*
00117 %F This function computes the minimum height for the element.
00118 %i Element coordinate.
00119 %o Minimum height
00120 */
00121 static double _DKTMinHeight( sCoord coord[3] )
00122 {
00123  int    i;
00124  double area;
00125  double bcorr;
00126  double bmax;
00127  double hmin;
00128 
00129 /* Initializa variables
00130  */
00131  bmax = bcorr = hmin = area = 0.0;
00132 
00133 /* Loop over the element edges to compute the maximum edge
00134  */
00135  for( i = 0; i < 3; i++ ) {
00136   bcorr = sqrt( ( coord[(i+1)%3].x - coord[i].x ) * ( coord[(i+1)%3].x - coord[i].x ) +
00137                 ( coord[(i+1)%3].y - coord[i].y ) * ( coord[(i+1)%3].y - coord[i].y ) +
00138                 ( coord[(i+1)%3].z - coord[i].z ) * ( coord[(i+1)%3].z - coord[i].z ));
00139 
00140   if( bcorr > bmax )
00141    bmax = bcorr;
00142  }
00143 
00144 /* Computes the element area
00145  */
00146  area = _DKTArea( coord );
00147 
00148 /* Computes the minimum height
00149  */
00150  hmin = (2.0 * area) / bmax;
00151 
00152  return( hmin );
00153 
00154 } /* End of _DKTMinHight */
00155 
00156 
00157 /*
00158 %F This function get the element nodal displacement from the global 
00159    vector.
00160 */
00161 static void _DKTGetDisplacement( sElement *elm, double *U, double ue[9] )
00162 {
00163  sDKTData *data = 0L;
00164  int      i;
00165 
00166 /* Get element descriptor
00167  */
00168  data = (sDKTData *)elm->data;
00169 
00170 /* Fill element displacement vector
00171  */
00172  for( i = 0; i < data->NumNodes; i++ ) {
00173   ue[3*i]   = U[3*(data->inc[i]-1)];
00174   ue[3*i+1] = U[3*(data->inc[i]-1)+1];
00175   ue[3*i+2] = U[3*(data->inc[i]-1)+2];
00176  }
00177 
00178 } /* End of _DKTGetDisplacement */
00179 
00180 /*
00181 %F This function computes the shape functions derivatives for the 
00182    _DKT element.
00183 */
00184 static void _DKTDerivShp( double r, double s, double t, sDerivRST dshp[3] )
00185 {
00186 /* Compute shape functions derivatives
00187  */
00188  dshp[0].r =  1.0;
00189  dshp[1].r =  0.0;
00190  dshp[2].r = -1.0;
00191  
00192 
00193  dshp[0].s =  0.0;
00194  dshp[1].s =  1.0;
00195  dshp[2].s = -1.0;
00196  
00197 
00198  dshp[0].t =  0.0;
00199  dshp[1].t =  0.0;
00200  dshp[2].t =  0.0;
00201  
00202 
00203 } /* End of _DKTDerivShp */
00204 
00205 
00206 /*
00207 %F This function computes the stress x strain matrix for the DKT element.
00208 */
00209 static void _DKTBMatrix( sElement *elm, double bm[6][9] )
00210 {
00211  int i;
00212  double detjac;
00213  double jac[3][3], ijac[3][3];
00214  sCoord coord[3];
00215  sDerivRST dshp[3];
00216  
00217  for( i = 0; i < 9; i++ )
00218   bm[0][i] = bm[1][i] = bm[2][i] = 
00219   bm[3][i] = bm[4][i] = bm[5][i] = 0.0;
00220 
00221 /* Get element coordinate
00222  */
00223  _DKTGetCoord( elm, coord );
00224 
00225 /* Compute the element jacobian matrix
00226  */
00227  jac[0][0] = coord[0].x - coord[2].x;
00228  jac[0][1] = coord[0].y - coord[2].y;
00229  jac[0][2] = coord[0].z - coord[2].z;
00230  jac[1][0] = coord[1].x - coord[2].x;
00231  jac[1][1] = coord[1].y - coord[2].y;
00232  jac[1][2] = coord[1].z - coord[2].z;
00233  jac[2][0] = jac[2][1] = 0.0;
00234  jac[2][2] = 1.0;
00235 
00236 /* Compute the matrix determinant
00237  */ 
00238  detjac = _DKTArea( coord );
00239 
00240 /* Compute the inverse
00241  */
00242  ijac[0][0] =  (jac[1][1] * jac[2][2] - jac[1][2] * jac[2][1]) / detjac;
00243  ijac[0][1] = -(jac[0][1] * jac[2][2] - jac[0][2] * jac[2][1]) / detjac;
00244  ijac[0][2] =  (jac[0][1] * jac[1][2] - jac[0][2] * jac[1][1]) / detjac;
00245  ijac[1][0] = -(jac[1][0] * jac[2][2] - jac[1][2] * jac[2][0]) / detjac;
00246  ijac[1][1] =  (jac[0][0] * jac[2][2] - jac[0][2] * jac[2][0]) / detjac;
00247  ijac[1][2] = -(jac[0][0] * jac[1][2] - jac[0][2] * jac[1][0]) / detjac;
00248  ijac[2][0] =  (jac[1][0] * jac[2][1] - jac[1][1] * jac[2][0]) / detjac;
00249  ijac[2][1] = -(jac[0][0] * jac[2][1] - jac[0][1] * jac[2][0]) / detjac;
00250  ijac[2][2] =  (jac[0][0] * jac[1][1] - jac[0][1] * jac[1][0]) / detjac;
00251 
00252 /* Compute the B matrix coefficientes
00253  */
00254  _DKTDerivShp( _GPoint, _GPoint, _GPoint, dshp );
00255  
00256  for( i = 0; i < 3; i++ ) {
00257   bm[0][3*i]   = bm[3][3*i+1] = bm[4][3*i+2] = (ijac[0][0] * dshp[i].r) +
00258                                                (ijac[0][1] * dshp[i].s) + 
00259                                                (ijac[0][2] * dshp[i].t);
00260   bm[1][3*i+1] = bm[3][3*i]   = bm[5][3*i+2] = (ijac[1][0] * dshp[i].r) +
00261                                                (ijac[1][1] * dshp[i].s) + 
00262                                                (ijac[1][2] * dshp[i].t);
00263   bm[2][3*i+2] = bm[4][3*i]   = bm[5][3*i+1] = (ijac[2][0] * dshp[i].r) +
00264                                                (ijac[2][1] * dshp[i].s) + 
00265                                                (ijac[2][2] * dshp[i].t);
00266  }
00267  
00268 } /* End of _DKTBMatrix */
00269 
00270 
00271 /*
00272 ** ------------------------------------------------------------------------
00273 ** Subclass methods:
00274 */
00275 static void   DKTNew( int, int, int, int, sElement **, sElement **, sNode * );
00276 static void   DKTFree                  ( sElement * );
00277 static void   DKTRead                  ( sElement * );
00278 static void   DKTMassMatrix            ( sElement *, double * );
00279 
00280 static double DKTRigidCoeff            ( sElement * );
00281 static void   DKTConnect               ( sElement *, int * );
00282 static void   DKTNumNodes              ( sElement *, int * );
00283 static void   DKTGravity               ( sElement *, double *, double *, 
00284                                                     double * );
00285 static void   DKTAssVector             ( sElement *, double *, double * );
00286 static void   DKTStressStrain          ( sElement *, double, double *, double *,
00287                                                     sTensor *, sTensor * );
00288 static void   DKTTimeStep              ( sElement *, double * );
00289 static void   DKTInterForce            ( sElement *, sTensor *, double * );
00290 static void   DKTWriteStress           ( sElement *, FILE *, double *,
00291                                                             double * );
00292 static void   DKTWriteNodalResult      ( sElement *, FILE *, FILE * );
00293 static void   DKTWriteGaussResult      ( sElement *, FILE *, FILE * );
00294 static void   DKTWriteGaussVectorResult( sElement *, int, FILE *, FILE * );
00295 
00296 
00297 static void   DKTSetInitStress         ( sElement *, sTensor * );
00298 
00299 static void   DKTVolume                ( sElement *, double * );
00300 
00301 static void DKTKMatrix( sElement *, double [24][24] );                                                                         
00302 static void DKTGetDof( sElement *, int [24], int * );
00303 /*
00304 %F This method allocates memory for a DKT element and fills its data with 
00305    the specific data.
00306 %i Element label (number)
00307 %o Element descriptor.
00308 */
00309 static void DKTNew( int label, int matid, int intord, int tckid, 
00310                    sElement **elm, sElement **elist, sNode *nodes )
00311 {
00312  sDKTData *data = 0L;
00313 
00314 /* Get memory for the element descriptor
00315  */
00316  (*elm) = (sElement *)calloc(1, sizeof(sElement));
00317 
00318 /* Get memory for the DKT element data
00319  */
00320  data = (sDKTData *)calloc(1, sizeof(sDKTData));
00321 
00322 /* Fill DKT element data
00323  */
00324  data->matid       = matid;
00325  data->tckid       = tckid;
00326  data->NumNodes    = 3;
00327  data->NumTensComp = 4;
00328  data->effdef      = 0.0;
00329  data->istr[0]     = 0.0;
00330  data->istr[1]     = 0.0;
00331  data->istr[2]     = 0.0;
00332  data->iPress      = 0L;
00333  
00334 
00335 /* Fill element descriptor
00336  */
00337  (*elm)->type    = DKT;
00338  (*elm)->rezone  = NONE;
00339  (*elm)->display = DSP_NO;
00340  (*elm)->curve   = 0;
00341  (*elm)->label   = label;
00342  (*elm)->data    = (void *)data;
00343  (*elm)->nodes   = nodes;
00344 
00345 /* Add to the element list
00346  */
00347  elist[label-1] = (*elm);
00348 
00349 } /* End of DKTNew */
00350 
00351 
00352 /*
00353 %F This method frees the DKT element data for a given element.
00354 %i Element descriptor.
00355 */
00356 static void DKTFree( sElement *elm )
00357 {
00358  sDKTData *data = 0L;
00359 
00360 /* Get DKT element data
00361  */
00362  data = (sDKTData *)elm->data;
00363 
00364 /* Release internal pressure
00365  */
00366  if( data->iPress != 0L )
00367   free( data->iPress );
00368 
00369 /* Release allocated memory
00370  */
00371  free( data );
00372 
00373 /* Reset element data
00374  */
00375  elm->data = 0L;
00376 
00377 } /* End of DKTFree */
00378 
00379 
00380 /*
00381 %F This method reads the DKT element information.
00382 %i Element descriptor.
00383 */
00384 static void DKTRead( sElement *elm )
00385 {
00386  sDKTData *data = 0L;
00387  int      i1, i2, i3;
00388 
00389 /* Get the element data
00390  */
00391  data = (sDKTData *)elm->data;
00392 
00393 /* Read the element incidence
00394  */
00395  fscanf( nf, "%d %d %d", &i1, &i2, &i3 );
00396 
00397 /* Fill element information
00398  */
00399  data->inc[0] = i1;
00400  data->inc[1] = i2;
00401  data->inc[2] = i3;
00402 
00403 } /* End of DKTRead */
00404 
00405 
00406 /*
00407 %F This method reads the DKT initial stress
00408 */
00409 static int DKTReadInitStress( sElement *elm )
00410 {
00411  int      numpg = 1;
00412  double   sxx, syy, sxy ,szz, sxz, syz;
00413  sDKTData *data = 0L;
00414 
00415 /* Get element data
00416  */
00417  data = (sDKTData *)elm->data;
00418 
00419 /* Read the number of integration points and check to see if is compatible 
00420  * whith the element type.
00421  
00422  /*fscanf( nf, "%d", &numpg );*/
00423  if( numpg != 1 ) {
00424   printf( "\n\nNumber of gauss points must be equal to one.\n\n" );
00425   return 0;
00426  }
00427  
00428 
00429 /* Read the initial stress information
00430  */
00431  fscanf( nf, "%lf %lf %lf %lf %lf %lf", &sxx, &syy, &szz, &sxy, &sxz, &syz);
00432  data->istr[0] = sxx;
00433  data->istr[1] = syy;
00434  data->istr[2] = sxy;
00435 
00436  return 1;
00437 } /* End of DKTReadInitStress */
00438 
00439 
00440 /*
00441 %F This method computes the mass matrix for the DKT element.
00442 %i Element descriptor.
00443 %o Element mass matrix.
00444 */
00445 static void DKTMassMatrix( sElement *elm, double *mass )
00446 {
00447  sDKTData *data = 0L;
00448  sCoord   coord[3];
00449  double   area, ncont, dens;
00450  int      i, matid;
00451 
00452 /* Get element coordinates
00453  */
00454  _DKTGetCoord( elm, coord );
00455 
00456 /* Compute element area
00457  */
00458  area = _DKTArea( coord );
00459 
00460 /* Get material density
00461  */
00462  data  = (sDKTData *)elm->data;
00463  matid = data->matid;
00464  MatDensity( MatList[matid-1], &dens );
00465 
00466 /* Calculate the element node contribution for the element mass
00467  */
00468  ncont = (area * dens) / 3.0;
00469 
00470 /* Compute the mass matrix
00471  */
00472  for( i = 0; i < 9; i++ )
00473   mass[i] = ncont;
00474  
00475 } /* End of DKTMassMatrix */
00476 
00477 
00478 /*
00479 %F This functions computes the element rigidity coefficient.
00480 %i Element descriptor.
00481 %o Element rigidity coefficient.
00482 */
00483 static double DKTRigidCoeff( sElement *elm )
00484 {
00485  sCoord coord[3];
00486  double area = 0.0;
00487 
00488 /* Get element coordinates
00489  */
00490  _DKTGetCoord( elm, coord );
00491 
00492 /* Compute the element area
00493  */
00494  area = _DKTArea( coord );
00495 
00496  return( area );
00497 
00498 } /* End of DKTRigidCoeff */
00499 
00500 
00501 /*
00502 %F
00503 */
00504 static void DKTConnect( sElement *elm, int *conn )
00505 {
00506  int      i;
00507  sDKTData *data = 0L; 
00508 
00509  data = (sDKTData *)elm->data;
00510 
00511  for( i = 0; i < data->NumNodes; i++ )
00512   conn[i] = data->inc[i];
00513 
00514 } /* End of DKTConnect */
00515 
00516 
00517 /*
00518 %F
00519 */
00520 static void DKTNumNodes( sElement *elm, int *nnodes )
00521 {
00522  sDKTData *data = (sDKTData *)elm->data;
00523 
00524  (*nnodes) = data->NumNodes;
00525 
00526 } /* End of DKTNumNodes */
00527 
00528 
00529 /*
00530 %F
00531 */
00532 static void DKTGravity( sElement *elm, double *qx, double *qy, double *qz )
00533 {
00534  sDKTData *data = 0;
00535  sCoord   coord[3];
00536  double   area, mass, gamma;
00537  int      matid;
00538 
00539 /* Get element data
00540  */
00541  data = (sDKTData *)elm->data;
00542 
00543 /* Get element coordinates
00544  */
00545  _DKTGetCoord( elm, coord );
00546 
00547 /* Compute element area
00548  */
00549  area = _DKTArea( coord );
00550 
00551 /* Get material id, and the material density property
00552  */
00553  matid = data->matid;
00554  MatDensity( MatList[matid-1], &gamma );
00555  
00556 /* Compute the gravitational load
00557  */
00558  mass = (gamma * area) / 3.0;
00559 
00560  (*qx) = mass * GravForce.gx;
00561  (*qy) = mass * GravForce.gy;
00562  (*qz) = mass * GravForce.gz;
00563 
00564 } /* End of DKTGravity */
00565 
00566 
00567 /*
00568 %F
00569 */
00570 static void DKTAssVector( sElement *elm, double *GMatrix, double *matrix )
00571 {
00572  int      i;
00573  int      conn[3];
00574  sDKTData *data;
00575 
00576 /* Get the element data
00577  */
00578  data = (sDKTData *)elm->data;
00579 
00580 /* Get element connectivity
00581  */
00582  ElmConnect( elm, conn );
00583 
00584 /* Assemble matrix
00585  */
00586  for( i = 0; i < data->NumNodes; i++ ) {
00587   GMatrix[3*(conn[i]-1)]   += matrix[3*i];
00588   GMatrix[3*(conn[i]-1)+1] += matrix[3*i+1];
00589   GMatrix[3*(conn[i]-1)+2] += matrix[3*i+2];
00590  }
00591  
00592 } /* End of DKTAssVector */
00593 
00594 
00595 /*
00596 %F
00597 */
00598 static void DKTStressStrain( sElement *elm, double dt, double *U, double *yield, 
00599                                            sTensor *stre, sTensor *stra )
00600 {
00601  sDKTData   *data = 0L;
00602  sMaterial *mat  = 0L;
00603  double     cm[6][6];
00604  double     bm[6][9];
00605  double     ue[9];
00606  double     def[6], str[6];
00607  double     nu;
00608  double     pf = 1.0;
00609  int        i, j;
00610  
00611  
00612 /* Initialize stress and strain variables.
00613  */
00614  stre = (sTensor *)memset( (void *)stre, 0, sizeof(sTensor) );
00615  if( stra != 0L )
00616   stra = (sTensor *)memset( (void *)stra, 0, sizeof(sTensor) );
00617 
00618 /* Get element descriptor
00619  */
00620  data = (sDKTData *)elm->data;
00621 
00622 /* Get Material object
00623  */
00624  mat = MatList[data->matid-1];
00625 
00626 /* Update the material parameter
00627  */
00628  MatUpdateParameter( mat, data->effdef );
00629 
00630 /* Get material constitutive matrix
00631  */
00632  //MatPSMatrix( mat, cm );
00633  MatConstitutiveMatrix( mat, cm ); 
00634 
00635 /* Get poisson coeff.
00636  */
00637  MatNuParameter( mat, &nu );
00638 
00639 /* Get element stress x strain matrix
00640  */
00641  _DKTBMatrix( elm, bm );
00642 
00643 /* Get element displacement
00644  */
00645  _DKTGetDisplacement( elm, U, ue );
00646 
00647 /* Compute the deformations
00648  */
00649  for( i = 0; i < 6; i++ ) {
00650   def[i] = 0.0;
00651   for( j = 0; j < (3*data->NumNodes); j++ )
00652    def[i] += bm[i][j] * ue[j];
00653  }
00654 
00655 /* Compute the element stress
00656  */
00657  for( i = 0; i < 6; i++ ) {
00658   str[i] = 0.0;
00659   for( j = 0; j < 6; j++ )
00660    str[i] += cm[i][j] * def[j];
00661   str[i] += data->istr[i];
00662  }
00663  /* Correct stress based on the material model
00664  */
00665  MatUpdateStress( mat, dt, &pf, &data->effdef, str, def );
00666 
00667 
00668 /* Set stress values
00669  */
00670  stre->xx = str[0];
00671  stre->yy = str[1];
00672  stre->zz = str[2];
00673  stre->xy = str[3];
00674  stre->yz = str[4];
00675  stre->xz = str[5];
00676 
00677 /* Set strain values
00678  */
00679  if( stra != 0L ) {
00680   stra->xx = def[0];
00681   stra->yy = def[1];
00682   stra->zz = def[2];
00683   stra->xy = def[3];
00684   stra->yz = def[4];
00685   stra->xz = def[5];
00686  }
00687 
00688 /* Set yield parameter
00689  */
00690  if( yield != 0L )
00691   (*yield) = (pf > 0.0) ? 0.0 : 1.0;
00692 
00693 } /* End of DKTtressStrain */
00694 
00695 
00696 
00697 /*
00698 %F
00699 */
00700 static void DKTTimeStep( sElement *elm, double *dt )
00701 {
00702  sCoord     coord[3];
00703  double     hmin, dtime;
00704  sDKTData   *data = 0L;
00705  sMaterial *mat  = 0L;
00706 
00707 /* Get element coordinates
00708  */
00709  _DKTGetCoord( elm, coord );
00710 
00711 /* Compute the element minimum height
00712  */
00713  hmin = _DKTMinHeight( coord );
00714 
00715 /* Get element data
00716  */
00717  data = (sDKTData *)elm->data;
00718 
00719 /* Get material object
00720  */
00721  mat = MatList[data->matid-1];
00722 
00723 /* Compute the time step according the material type
00724  */
00725  MatTimeStep( mat, &dtime );
00726 
00727 /* Compute the time step
00728  */
00729  if( mat->type == KELVIN ) (*dt) = dtime;
00730  else                      (*dt) = hmin * dtime;
00731 
00732 } /* End of DKTTimeStep */
00733 
00734 
00735 /*
00736 %F This function computes the internal forces for the DKT element
00737 */
00738 static void DKTInterForce( sElement *elm, sTensor *stress, double *intforce )
00739 {
00740  int      i, j;
00741  double   coeff = 0.0;
00742  double   bm[6][9], str[6];
00743  sDKTData *data = 0L;
00744 
00745 /* Get element descriptor
00746  */ 
00747  data = (sDKTData *)elm->data;
00748 
00749 /* Compute element rigidity coefficient
00750  */ 
00751  coeff = ElmRigidCoeff( elm );
00752 
00753 /* Compute element B matrix
00754  */
00755  _DKTBMatrix( elm, bm );
00756 
00757 /* Check for the initial stress
00758  */
00759  if( stress == 0L ) {
00760   for( i = 0; i < (3*data->NumNodes); i++ ) {
00761    intforce[i] = 0.0;
00762    for( j = 0; j < 3; j++ ) 
00763     intforce[i] += bm[j][i] * data->istr[j];
00764    intforce[i] *= coeff;
00765   }
00766   return;
00767  }
00768 
00769 /* Get element stress
00770  */
00771  str[0] = stress->xx;
00772  str[1] = stress->yy;
00773  str[2] = stress->zz;
00774  str[3] = stress->xy;
00775  str[4] = stress->yz;
00776  str[5] = stress->xz;
00777 
00778 /* Compute element internal forces
00779  */
00780  for( i = 0; i < (3*data->NumNodes); i++ ) {
00781   intforce[i] = 0.0;
00782   for( j = 0; j < 6; j++ ) 
00783    intforce[i] += bm[j][i] * str[j];
00784   intforce[i] *= coeff;
00785  }
00786  for( i = 0; i < (3*data->NumNodes); i++ ) 
00787   intforce[i] *= -1.0;
00788 
00789 
00790 } /* End of DKTInterForce */
00791 
00792 
00793 /*
00794 %F
00795 */
00796 static void DKTWriteStress( sElement *elm, FILE *out, double *U, double *V )
00797 {
00798  sTensor  stress;
00799  sTensor  strain;
00800  sTensor  strd = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
00801  double   yield = 0.0;
00802  double   iso;
00803  
00804 /* Check to see if the element was rezoned
00805  */
00806  if( elm->rezone == DONE ) {
00807   stress.xx = stress.xy = stress.xz = 
00808               stress.yy = stress.yz = 
00809                           stress.zz = 0.0;
00810   strd.xx = strd.xy = strd.xz = 
00811             strd.yy = strd.yz = 
00812                       strd.zz = 0.0;
00813   strain.xx = strain.xy = strain.xz = 
00814               strain.yy = strain.yz = 
00815                           strain.zz = 0.0;
00816   yield = 0.0;
00817  }
00818  else {
00819  /* Compute the element stress and strain
00820   */
00821   DKTStressStrain( elm, 0.0, U, &yield, &stress, &strain );
00822  }
00823 
00824 /* Compute desviatory stress
00825  */
00826  iso = (stress.xx + stress.yy + stress.zz)/3.0;
00827  strd.xx = stress.xx - iso;
00828  strd.yy = stress.yy - iso;
00829 
00830 /* Write element stress, strain and yield parameter
00831  */
00832  fwrite( &stress, sizeof(sTensor), 1, out );
00833  fwrite( &strain, sizeof(sTensor), 1, out );
00834  fwrite( &strd, sizeof(sTensor), 1, out );
00835  fwrite( &yield, sizeof(double), 1, out );
00836 
00837 } /* End of DKTWriteStress */
00838 
00839 
00840 /*
00841 %F
00842 */
00843 static void DKTWriteNodalResult( sElement *elm, FILE *out, FILE *tmp )
00844 {
00845  sTensor  sts, sta;
00846  sPTensor psts, psta;
00847  sTensor  strd;
00848  double   yield;
00849  int      i;
00850  double   iso;
00851 
00852 /* Read results from temporary file
00853  */
00854  fread( &sts, sizeof(sTensor), 1, tmp );
00855  fread( &sta, sizeof(sTensor), 1, tmp );
00856  fread( &strd, sizeof(sTensor), 1, tmp );
00857  fread( &yield, sizeof(double), 1, tmp );
00858 
00859 /* Computes the principal tensors
00860  */
00861  PrincipalTensor( &sts, &psts );
00862  PrincipalTensor( &sta, &psta );
00863  
00864  /* Computes the isotropic stress
00865  */
00866  iso = (sts.xx + sts.yy + sts.zz)/3.0;
00867 
00868 /* Write results on output file
00869  */
00870  fprintf( out, "%d\n", elm->label );
00871  for( i = 0; i < 3; i++ ) {
00872   fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t%+10.5e\t", sts.xx,
00873                                                         sts.yy,
00874                                                         sts.zz,
00875                                                         sts.xy );
00876   fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t", psts.dir1,
00877                                                psts.dir2,
00878                                                psts.dir3 );
00879   fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t", strd.xx,
00880                                                strd.yy,
00881                                                iso );
00882   fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t", sta.xx,
00883                                                sta.yy,
00884                                                sta.xy );
00885   fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t", psta.dir1,
00886                                                psta.dir2,
00887                                                psta.dir3 );
00888   fprintf( out, "%+10.5e\n", yield );
00889  }
00890 
00891 } /* End of DKTWriteNodalResult */
00892 
00893 
00894 /*
00895 %F
00896 */
00897 static void DKTWriteGaussResult( sElement *elm, FILE *out, FILE *tmp )
00898 {
00899  sTensor  sts, sta;
00900  sPTensor psts, psta, epsts, dpsts;
00901  sTensor  strd, estr;
00902  double   yield;
00903  double   iso, piso;
00904  double   poropressure = 0.0;
00905  sMaterial *mat  = 0L;
00906  sDKTData   *data = 0L;
00907  int      j;
00908 
00909 /* Read results from temporary file
00910  */
00911  fread( &sts, sizeof(sTensor), 1, tmp );
00912  fread( &sta, sizeof(sTensor), 1, tmp );
00913  fread( &strd, sizeof(sTensor), 1, tmp );
00914  fread( &yield, sizeof(double), 1, tmp );
00915 
00916 /* Computes the principal stress
00917  */
00918  PrincipalTensor( &sts, &psts );
00919  PrincipalTensor( &sta, &psta );
00920  
00921 /* Computes the isotropic stress
00922  */
00923  iso = (sts.xx + sts.yy + sts.zz)/3.0;
00924  
00925 /* Compute desviatory principal stress
00926  */
00927  piso = (psts.dir1 + psts.dir2 + psts.dir3)/3.0;
00928  
00929  dpsts.dir1 = psts.dir1 - piso;
00930  dpsts.dir3 = psts.dir3 - piso;
00931  
00932  /* Get element descriptor
00933  */
00934  data = (sDKTData *)elm->data;
00935 
00936 /* Get Material object
00937  */
00938  mat = MatList[data->matid-1];
00939  
00940  estr.xx = sts.xx;
00941  estr.yy = sts.yy;
00942  estr.xy = sts.xy;
00943  
00944 /* Computes the principal efetive stress
00945  */
00946  PrincipalTensor( &estr, &epsts );  
00947  
00948 /* Write results on output file
00949  */
00950  
00951  fprintf( out, "%d\t%d\n", elm->label, 1 );
00952  
00953  for( j = 0; j < Config.numgaussresults; j++){
00954    if((strcmp( Config.gaussresults[j], "Sxx" ) == 0))
00955     fprintf( out, "%+10.5e\t", sts.xx );
00956    else if((strcmp( Config.gaussresults[j], "Syy" ) == 0))
00957     fprintf( out, "%+10.5e\t", sts.yy );
00958    else if((strcmp( Config.gaussresults[j], "Szz" ) == 0))
00959     fprintf( out, "%+10.5e\t", sts.zz );
00960    else if((strcmp( Config.gaussresults[j], "Sxy" ) == 0))
00961     fprintf( out, "%+10.5e\t", sts.xy );
00962    else if((strcmp( Config.gaussresults[j], "Sxz" ) == 0))
00963     fprintf( out, "%+10.5e\t", sts.xz );
00964    else if((strcmp( Config.gaussresults[j], "Syz" ) == 0))
00965     fprintf( out, "%+10.5e\t", sts.yz );
00966    else if((strcmp( Config.gaussresults[j], "S1" ) == 0))
00967     fprintf( out, "%+10.5e\t", psts.dir1 );
00968    else if((strcmp( Config.gaussresults[j], "S2" ) == 0))
00969     fprintf( out, "%+10.5e\t", psts.dir2 );
00970    else if((strcmp( Config.gaussresults[j], "S3" ) == 0))
00971     fprintf( out, "%+10.5e\t", psts.dir3 );
00972    else if((strcmp( Config.gaussresults[j], "Sdx" ) == 0))
00973     fprintf( out, "%+10.5e\t", strd.xx );
00974    else if((strcmp( Config.gaussresults[j], "Sdy" ) == 0))
00975     fprintf( out, "%+10.5e\t", strd.yy );
00976    else if((strcmp( Config.gaussresults[j], "Sdz" ) == 0))
00977     fprintf( out, "%+10.5e\t", strd.zz );
00978    else if((strcmp( Config.gaussresults[j], "Exx" ) == 0))
00979     fprintf( out, "%+10.5e\t", sta.xx );
00980    else if((strcmp( Config.gaussresults[j], "Eyy" ) == 0))
00981     fprintf( out, "%+10.5e\t", sta.yy );
00982    else if((strcmp( Config.gaussresults[j], "Ezz" ) == 0))
00983     fprintf( out, "%+10.5e\t", sta.zz );
00984    else if((strcmp( Config.gaussresults[j], "Exy" ) == 0))
00985     fprintf( out, "%+10.5e\t", sta.xy );
00986    else if((strcmp( Config.gaussresults[j], "Exz" ) == 0))
00987     fprintf( out, "%+10.5e\t", sta.xz );
00988    else if((strcmp( Config.gaussresults[j], "Eyz" ) == 0))
00989     fprintf( out, "%+10.5e\t", sta.yz );
00990    else if((strcmp( Config.gaussresults[j], "E1" ) == 0))
00991     fprintf( out, "%+10.5e\t", psta.dir1 );
00992    else if((strcmp( Config.gaussresults[j], "E2" ) == 0))
00993     fprintf( out, "%+10.5e\t", psta.dir2 );
00994    else if((strcmp( Config.gaussresults[j], "E3" ) == 0))
00995     fprintf( out, "%+10.5e\t", psta.dir3 );
00996    else if((strcmp( Config.gaussresults[j], "Ev" ) == 0))
00997     fprintf( out, "%+10.5e\t", (psta.dir1+psta.dir2+psta.dir3) );
00998  }                               
00999  
01000 } /* End of DKTWriteGaussResult */
01001 
01002 
01003 /*
01004 %F
01005 */
01006 static void DKTWriteGaussVectorResult( sElement *elm, int version, FILE *out,
01007                                       FILE *tmp )
01008 {
01009  sPTensor psts, psta;
01010  sTensor  sts, sta;
01011  sTensor  strd;
01012  double   yield;
01013 
01014 /* Read results from temporary file
01015  */
01016  fread( &sts, sizeof(sTensor), 1, tmp );
01017  fread( &sta, sizeof(sTensor), 1, tmp );
01018  fread( &strd, sizeof(sTensor), 1, tmp );
01019  fread( &yield, sizeof(double), 1, tmp );
01020 
01021 /* Computes the principal stress
01022  */
01023  PrincipalTensor( &sts, &psts );
01024  PrincipalTensor( &sta, &psta );
01025 
01026 /* Write results on output file
01027  */
01028  fprintf( out, "%d\t%d\n", elm->label, 1 );
01029 
01030  if( version > 1 ) {
01031   fprintf( out, "%+10.5e\t%+10.5e\n", psts.dir1, psta.dir1 );
01032   fprintf( out, "%+10.5e\t%+10.5e\n", psts.dir2, psta.dir2 );
01033   fprintf( out, "%+10.5e\t%+10.5e\n", psts.dir3, psta.dir3 );
01034   fprintf( out, "%+10.5e\t%+10.5e\n", psts.cos1x, psta.cos1x );
01035   fprintf( out, "%+10.5e\t%+10.5e\n", psts.cos2x, psta.cos2x );
01036   fprintf( out, "%+10.5e\t%+10.5e\n", psts.cos3x, psta.cos3x );
01037   fprintf( out, "%+10.5e\t%+10.5e\n", psts.cos1y, psta.cos1y );
01038   fprintf( out, "%+10.5e\t%+10.5e\n", psts.cos2y, psta.cos2y );
01039   fprintf( out, "%+10.5e\t%+10.5e\n", psts.cos3y, psta.cos3y );
01040   fprintf( out, "%+10.5e\t%+10.5e\n", psts.cos1z, psta.cos1z );
01041   fprintf( out, "%+10.5e\t%+10.5e\n", psts.cos2z, psta.cos2z );
01042   fprintf( out, "%+10.5e\t%+10.5e\n", psts.cos3z, psta.cos3z );
01043  }
01044  else {
01045   if( psts.dir1 > 0.0 )
01046    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (psts.dir1*psts.cos1x),
01047                                                 (psts.dir1*psts.cos1y), 0.0 );
01048   else
01049    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01050 
01051   if( psts.dir1 < 0.0 )
01052    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (psts.dir1*psts.cos1x),
01053                                                 (psts.dir1*psts.cos1y), 0.0 );
01054   else
01055    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01056 
01057   if( psts.dir3 > 0.0 )
01058    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (psts.dir3*psts.cos1y),
01059                                                 (psts.dir3*psts.cos3y), 0.0 );
01060   else
01061    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01062 
01063   if( psts.dir3 < 0.0 )
01064    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (psts.dir3*psts.cos3x),
01065                                                 (psts.dir3*psts.cos3y), 0.0 );
01066   else
01067    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01068 
01069   if( psta.dir1 > 0.0 )
01070    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (psta.dir1*psta.cos1x),
01071                                                 (psta.dir1*psta.cos1y), 0.0 );
01072   else
01073    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01074  
01075   if( psta.dir1 < 0.0 )
01076    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (psta.dir1*psta.cos1x),
01077                                                 (psta.dir1*psta.cos1y), 0.0 );
01078   else
01079    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01080 
01081   if( psta.dir3 > 0.0 )
01082    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (psta.dir3*psta.cos3x),
01083                                                 (psta.dir3*psta.cos3y), 0.0 );
01084   else
01085    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01086 
01087   if( psta.dir3 < 0.0 )
01088    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (psta.dir3*psta.cos3x),
01089                                                 (psta.dir3*psta.cos3y), 0.0 );
01090   else
01091    fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01092  }
01093 
01094 } /* End of DKTWriteGaussVectorResult */
01095 
01096 /*
01097 %F
01098 */
01099 static void DKTSetInitStress( sElement *elm, sTensor *istress )
01100 {
01101  sDKTData *data = 0L;
01102 
01103 /* Get element data
01104  */
01105  data = (sDKTData *)elm->data;
01106 
01107 /* Set element initial stress
01108  */
01109  data->istr[0] = istress->xx;
01110  data->istr[1] = istress->yy;
01111  data->istr[2] = istress->xy;
01112  
01113 } /* End of DKTetInitStress */
01114 
01118 static void DKTVolume( sElement *elm, double *v )
01119 {
01120   sCoord coord[2];
01121 
01122   /* Get element coordinates
01123    */
01124   _DKTGetCoord(elm, coord);
01125 
01126   /* Compute element area
01127    */
01128   (*v) = _DKTArea(coord);
01129 
01130 } /* End of DKTVolume */
01131 
01132 static void DKTKMatrix( sElement *elm, double k[24][24] )
01133 {         
01134  int    i, j, l;           
01135  sCoord  coord[3];                  
01136  double detjac;            
01137  double C[6][6];          
01138  double B[6][9];          
01139  double BTC[9][6];        
01140  double ke[9][9]; 
01141  sDKTData  *data = 0L;
01142  sMaterial  *mat  = 0L;  
01143 
01144  /* Inicia matriz k = 0
01145  */
01146  for( i = 0; i < 24; i++ ) {
01147   for( j = 0; j < 24; j++ ) {
01148    k[i][j] = 0.0;
01149   }
01150  }
01151  
01152  /* Pega descrição do elemento
01153  */
01154  data = (sDKTData *)elm->data;
01155  
01156 /* Pega material
01157  */
01158  mat = MatList[data->matid-1];
01159  
01160  /* Pega as coordenadas nodais
01161  */
01162  _DKTGetCoord(elm, coord);
01163  
01164  /* Pega matriz constitutiva [C]*/
01165  //MatPSMatrix( mat, C );
01166  MatConstitutiveMatrix( mat, C ); 
01167 
01168  /* Calcula matriz B*/
01169  _DKTBMatrix(elm, B );
01170  
01171  /* Calcula a área do elemento */
01172  detjac = _DKTArea( coord);
01173  
01174  /*Calcula [B] transposto * [C] */
01175  for( i = 0; i < 9; i++ ) {
01176   for( j = 0; j < 6; j++)  {
01177    BTC[i][j] =0.0;
01178    for(l=0; l<6; l++){
01179     BTC[i][j] += B[l][i]*C[l][j];
01180    }
01181   }
01182  }
01183  /* Calcula [B] transposto * [C] * [B] * |jac|*/
01184  for( i = 0; i < 9; i++ ) {
01185   for( j = 0; j < 9; j++)  {
01186    ke[i][j] =0.0;
01187    for(l=0; l<6; l++){
01188     ke[i][j] += BTC[i][l]*B[l][j]*detjac;
01189    }
01190   }
01191  }
01192  /* Calcula matriz de rigidez do elemento*/
01193  for( i = 0; i < 9; i++ ) {
01194   for( j = 0; j < 9; j++)  {
01195    k[i][j] += ke[i][j];
01196   }
01197  }
01198  
01199 } /* DKTKMatrix */
01200 
01201 static void DKTGetDof( sElement *elm, int u[24], int *index )
01202 {
01203  sDKTData *data = 0L;
01204  int        i;
01205 
01206 /* Get element descriptor
01207  */
01208  data = (sDKTData *)elm->data;
01209 
01210 /* Fill element dof
01211  */
01212  for( i = 0; i < data->NumNodes; i++ ) {
01213   u[3*i]   = 3*(data->inc[i]-1);
01214   u[3*i+1] = 3*(data->inc[i]-1)+1;
01215   u[3*i+2] = 3*(data->inc[i]-1)+2;
01216  }
01217  
01218  *index = 9;
01219 
01220 } /* End of DKTGetDof */
01221 
01222 static void DKTGetInc( sElement *elm, int inc[8], int *index )
01223 {
01224  sDKTData *data = 0L;
01225  int        i;
01226 
01227 /* Get element descriptor
01228  */
01229  data = (sDKTData *)elm->data;
01230  
01231  for( i = 0; i < data->NumNodes; i++ ) {
01232   inc[i] = data->inc[i]-1;
01233  }
01234  
01235  *index = 3;
01236 } /* End of DKTGetInc */
01237 
01238 /*
01239 ** ------------------------------------------------------------------------
01240 ** Public functions:
01241 */
01242 
01243 /*
01244 %F This function initializes the sub-class "DKT".
01245 */
01246 void DKTInit( void );
01247 void DKTInit( void )
01248 {
01249 /* Initialize DKT element sub-class
01250  */
01251  ElmClass[DKT].new               = DKTNew;
01252  ElmClass[DKT].free              = DKTFree;
01253  ElmClass[DKT].read              = DKTRead;
01254  ElmClass[DKT].readinitstr       = DKTReadInitStress;
01255  ElmClass[DKT].readprofile       = 0L;
01256  ElmClass[DKT].mass              = DKTMassMatrix;
01257  ElmClass[DKT].rigidcoeff        = DKTRigidCoeff;
01258  ElmClass[DKT].load              = 0L;
01259  ElmClass[DKT].connect           = DKTConnect;
01260  ElmClass[DKT].numnodes          = DKTNumNodes;
01261  ElmClass[DKT].gravity           = DKTGravity;
01262  ElmClass[DKT].assvector         = DKTAssVector;
01263  ElmClass[DKT].strstrain         = DKTStressStrain;
01264  ElmClass[DKT].timestep          = DKTTimeStep;
01265  ElmClass[DKT].intforce          = DKTInterForce;
01266  ElmClass[DKT].writestr          = DKTWriteStress;
01267  ElmClass[DKT].writendlresult    = DKTWriteNodalResult;
01268  ElmClass[DKT].writegauresult    = DKTWriteGaussResult;
01269  ElmClass[DKT].writegauvecresult = DKTWriteGaussVectorResult;
01270  ElmClass[DKT].updatestress      = 0L;
01271  ElmClass[DKT].percforce         = 0L;
01272  ElmClass[DKT].setpressure       = 0L;
01273  ElmClass[DKT].setinitstress     = DKTSetInitStress;
01274  ElmClass[DKT].viscoforce        = 0L;
01275  ElmClass[DKT].jacobian          = 0L;
01276  ElmClass[DKT].volume            = DKTVolume;
01277  ElmClass[DKT].KMatrix           = DKTKMatrix;
01278  ElmClass[DKT].GetDof            = DKTGetDof;
01279  ElmClass[DKT].GetInc            = DKTGetInc;
01280  
01281 } /* End of DKTInit */
01282 
01283 
01284 /* =======================================================  End of File  */
01285 

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