elm.c

Go to the documentation of this file.
00001 /*
00002 %M This modules contains the element super class methods and definitions
00003 %a Joao Luiz Elias Campos.
00004 %d September 1st, 1998.
00005 %r $Id: elm.c,v 1.2 2004/06/22 17:53:10 joaoluiz Exp $
00006 %w (C) COPYRIGHT 1995-1996, Eduardo Nobre Lages.
00007    (C) COPYRIGHT 1997-1999, Joao Luiz Elias Campos.
00008    All Rights Reserved
00009    Duplication of this program or any part thereof without the express
00010    written consent of the author is prohibited.
00011 */
00012 
00013 /*
00014 ** ------------------------------------------------------------------------
00015 ** Global variables and symbols:
00016 */
00017 #include <stdio.h>
00018 #include <stdlib.h>
00019 #include <math.h>
00020 
00021 #include "load.h"
00022 #include "elm.h"
00023 
00024 /*
00025 %V Element class, element list and number of mesh elements
00026 */
00027 sElmClass   ElmClass[NumElmTypes];
00028 sElement  **ElmList     = 0L;
00029 int         NumElements = 0;
00030 
00031 /*
00032 %V Integration order and thickness
00033 */
00034 sOrder *IntOrder     = 0L;
00035 double *Thickness    = 0L;
00036 int     NumIntOrder  = 0;
00037 int     NumThickness = 0;
00038 
00039 /*
00040 %V Rezone variables
00041 */
00042 int NumRezones = 0;
00043 sRezone *Rezone = 0L;
00044 
00045 
00046 /*
00047 ** ------------------------------------------------------------------------
00048 ** Local variables and symbols:
00049 */
00050 #ifndef PI
00051 #define PI 3.141592654
00052 #endif
00053 /*
00054 ** ------------------------------------------------------------------------
00055 ** Local functions:
00056 */
00057 void T3Init(void);
00058 void Q4Init(void);
00059 void BRICK8Init(void);
00060 void TETR4Init(void);
00061 void INFINITEInit(void);
00062 void INTERFACEInit(void);
00063 void LINE2Init(void);
00064 void DKTInit(void);
00065 
00066 static int fn_tp(double *x, double *y);
00067 
00068 /*
00069 ** ------------------------------------------------------------------------
00070 ** Public functions:
00071 */
00072 
00073 /*
00074 %F This function initializes the globally shared "ElmClass" variable. This
00075    variable holds the pointers to the necessary functions which implement 
00076    the element class methods.
00077 */
00078 void ElementInit(void)
00079 {
00080  int i;
00081 
00082 /* Define the subclasses initialization methods
00083  */
00084  ElmClass[T3].init = T3Init;
00085  ElmClass[Q4].init = Q4Init;
00086  ElmClass[BRICK8].init = BRICK8Init;
00087  ElmClass[TETR4].init = TETR4Init;
00088  ElmClass[INTERFACE].init = INTERFACEInit;
00089  ElmClass[INFINITE].init = INFINITEInit;
00090  ElmClass[LINE2].init = LINE2Init;
00091  ElmClass[DKT].init = DKTInit; 
00092 
00093  for( i = 0; i < NumElmTypes; i++ )
00094   ElmInit(i);
00095 
00096 /* Allocate memory for element list
00097  */
00098  if( ElmList != 0L )
00099   free(ElmList);
00100 
00101  ElmList = (sElement **)calloc( NumElements, sizeof(sElement *) );
00102 
00103 } /* End of ElementInit */
00104 
00105 
00106 /*
00107 %F This function release memory used by element super-class.
00108 */
00109 void ElementFree(void)
00110 {
00111  int i;
00112 
00113 /* Releases sub-classes
00114  */
00115  for( i = 0; i < NumElements; i++ )
00116   ElmFree(ElmList[i]);
00117 
00118 /* Release element list and reset it
00119  */
00120  free(ElmList);
00121 
00122  ElmList = 0L;
00123 
00124 } /* End of ElementFree */
00125 
00126 
00127 /* 
00128 %F This function builds the element adjacence for the line load
00129 */
00130 void ElementBuildAdjacence( void )
00131 {
00132  int       i, j, k;
00133  int       noi, noj, nnode;
00134  int       conn[4];
00135  sElement *elm = 0L;
00136 
00137  for( i = 0; i < NumLineForce; i++ )
00138  {
00139   LineForce[i].adj = 0;
00140   for( j = 0; j < NumElements; j++ )
00141   {
00142    elm   = ElmList[j];
00143    ElmNumNodes(elm,&nnode);
00144    ElmConnect(elm,conn);
00145    if( (LineForce[i].elem - 1) != j )
00146    {
00147     for( k = 0; k < nnode; k++ )
00148     {
00149      noi = conn[k];
00150      noj = conn[(k+1)%nnode];
00151      if( (noj == LineForce[i].noi) && (noi == LineForce[i].noj))
00152       LineForce[i].adj = j + 1;
00153     }
00154    }
00155   }
00156  }
00157 
00158 } /* End of ElementBuildAdjacence */
00159 
00160 
00161 /*
00162 %F This function computes the principal components for a given tensor.
00163 */
00164 void PrincipalTensor( sTensor *tensor, sPTensor *ptensor )
00165 {
00166  double sxx = tensor->xx;
00167  double syy = tensor->yy;
00168  double sxy = tensor->xy;
00169  double szz = tensor->zz;
00170  double sxz = tensor->xz;
00171  double syz = tensor->yz;
00172  double tmed, ratio, ra;
00173  double ang1, ang2;
00174  double len1, len2;
00175  double tp[3], de1, de2;
00176  double I1, I2, I3;
00177  double q, r, phi;
00178  double ZERO = 1.0E-10;
00179 
00180  if( NDof == 2) {
00181    if( sxy >= ZERO ){
00182     ra = sxx * sxx - 2.0 * sxx * syy + syy * syy + 4 * sxy * sxy;
00183     if(ra > 0.0)
00184      ratio = sqrt(ra);
00185     else ratio = 0.0;
00186     tmed  = 0.5 * (sxx + syy);
00187     tp[0] = tmed - 0.5 * ratio;
00188     tp[1] = tmed + 0.5 * ratio;
00189     de1 = syy - sxx - ratio;
00190     de2 = syy - sxx + ratio;
00191   
00192     /* artificio utilizado para
00193      evitar erro numerico
00194      na determinacao dos cossenos
00195      diretores
00196     */
00197      if(de1 == 0.0)
00198       de1 = ZERO;
00199      if(de2 == 0.0)
00200       de2 = ZERO;
00201     /*
00202      determina as tensoes principais
00203      maxima e minima
00204     */
00205      if(tp[0] <= tp[1]){
00206       ptensor->dir1 = tp[0];
00207       ptensor->dir3 = tp[1];
00208       ang1 = -2.0 * sxy / de1;
00209       ang2 = -2.0 * sxy / de2;
00210      }
00211    else{
00212     ptensor->dir1 = tp[1];
00213     ptensor->dir3 = tp[0];
00214     ang1 = -2.0 * sxy / de2;
00215     ang2 = -2.0 * sxy / de1;
00216    }
00217   /*
00218    calcula os cossenos diretores
00219   */
00220    len1 = sqrt(ang1*ang1+1.0);
00221    ptensor->cos1x = ang1 / len1;
00222    ptensor->cos1y = 1.0 / len1;
00223  
00224    len2 = sqrt(ang2*ang2+1.0);
00225    ptensor->cos3x = ang2 / len2;
00226    ptensor->cos3y = 1.0 / len2;
00227   }
00228   else{
00229   /* nesse caso as tensoes principais
00230    sao iguais as tensoes  sxx e syy
00231    bastando apenas verificar os valores
00232    maximo e minimo
00233   */ 
00234    if(syy <= sxx){
00235     ptensor->dir1 = syy;
00236     ptensor->dir3 = sxx;
00237     ptensor->cos1x = 0.0;
00238     ptensor->cos1y = 1.0;
00239     ptensor->cos3x = 1.0;
00240     ptensor->cos3y = 0.0;
00241    }
00242    else{
00243     ptensor->dir1 = sxx;
00244     ptensor->dir3 = syy;
00245     ptensor->cos1x = 1.0;
00246     ptensor->cos1y = 0.0;
00247     ptensor->cos3x = 0.0;
00248     ptensor->cos3y = 1.0;
00249    }
00250   }
00251   ptensor->dir2 = szz;
00252   ptensor->cos1z = ptensor->cos3z = 
00253   ptensor->cos2x = ptensor->cos2y = 
00254   ptensor->cos2z = 0.0;
00255  }
00256  else{
00257   /*
00258    calcula os invariantes de tensoes
00259   */
00260   I1 = sxx + syy + szz; 
00261   I2 = sxx * syy - sxy * sxy + sxx * szz -
00262        sxz * sxz + syy * szz - syz * syz;
00263   I3 = sxx * syy * szz - sxx * syz * syz -
00264        sxy * sxy * szz + 2.0 * sxy * sxz *
00265        syz - sxz * sxz * syy;   
00266   /* 
00267    calcula as raizes do polinomio caracteristico
00268    determinando as tensoes principais
00269   */
00270   q = (3.0 * I2 - (I1 * I1))/9.0;
00271   if(q <= 0.0){
00272    r = (9.0 * I1 * I2 - 27.0 * I3 - 2.0 * I1 * I1 * I1)/54.0;
00273    
00274    if((q*q*q+r*r)>=0.0){
00275     ptensor->dir1 = 0.0;
00276     ptensor->dir2 = 0.0;
00277     ptensor->dir3 = 0.0;
00278    }
00279    else{
00280     ang1 = 120.0 * PI/180.0;
00281     ang2 = 240.0 * PI/180.0;
00282     phi = acos(r/sqrt(-(q * q * q)));
00283    
00284     tp[0] = 2 * sqrt(-q)*cos(1.0/3.0 * phi) + 1.0/3.0 * I1;
00285     tp[1] = 2 * sqrt(-q)*cos(1.0/3.0 * phi + ang1) + 1.0/3.0 * I1;
00286     tp[2] = 2 * sqrt(-q)*cos(1.0/3.0 * phi + ang2) + 1.0/3.0 * I1;
00287    
00288     qsort( tp, 3, sizeof(double), (void *) fn_tp ); 
00289    
00290     ptensor->dir1 = tp[0];
00291     ptensor->dir2 = tp[1];
00292     ptensor->dir3 = tp[2];
00293    }
00294   }
00295   else{
00296    ptensor->dir1 = ptensor->dir2 = ptensor->dir3 = 0.0;
00297   }
00298   /*
00299    fazer o calculo das dir. principais
00300   */
00301   ptensor->cos1z = ptensor->cos2z = 
00302   ptensor->cos3z = ptensor->cos1x = 
00303   ptensor->cos2x = ptensor->cos3x =
00304   ptensor->cos1y = ptensor->cos2y = 
00305   ptensor->cos3y = 0.0;
00306      
00307  }
00308 
00309 } /* End of PrincipalTensor */
00310 
00311 static int fn_tp(double *x, double *y)
00312 {
00313  if (*x > *y)
00314   return 1;
00315  else if (*x == *y)
00316   return 0;
00317  return -1;
00318 }
00319 
00320 /*
00321 %F Compute the off plane stress for the plane strain analysis
00322 */
00323 void ElementOffPlaneStress( double nu, sTensor *str )
00324 {
00325  sPTensor pstr;
00326 
00327 /* Compute the principal stress
00328  */
00329  PrincipalTensor( str, &pstr );
00330 
00331 /* Compute the off plane stress
00332  */
00333  str->zz = nu * (pstr.dir1 + pstr.dir3);
00334 
00335 } /* End of ElementOffPlaneStress */
00336 
00337 
00338 /*
00339 %F This function initializes a given tensor.
00340 */
00341 void ElementInitTensor( sTensor *tensor )
00342 {
00343 /* Initialize tensor
00344  */
00345  tensor->xx = tensor->xy = tensor->xz =
00346               tensor->yy = tensor->yz =
00347                            tensor->zz = 0.0;
00348 
00349 } /* End of ElementInitTensor */
00350 
00351 
00352 /* =======================================================  End of File  */
00353 

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