00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include <stdio.h>
00043 #include <stdlib.h>
00044 #include <math.h>
00045 #include <string.h>
00046
00047 #include "rio.h"
00048 #include "load.h"
00049 #include "elm.h"
00050 #include "node.h"
00051 #include "material.h"
00052 #include "load.h"
00053 #include "alg.h"
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 typedef struct _tetr4elm
00064 {
00065 int matid;
00066 int tckid;
00067 int NumNodes;
00068 int NumTensComp;
00069 int inc[4];
00070 double istr[6];
00071 double effdef;
00072 double prof;
00073 } sTetr4Data;
00074
00075
00076
00077
00078 static double _GPoint = 0.25000000;
00079 static double _GWeight = 0.16666667;
00080
00081 static double GForce = 9.85;
00082
00083
00084
00085
00086
00087 static void _TETR4GetCoord ( sElement *, sCoord [] );
00088 static void _TETR4ShapeFunc ( double, double, double, double [] );
00089 static void _TETR4Jacobian ( double, double, double, sCoord [],
00090 double *, double [3][3] );
00091 static void _TETR4BMatrix ( double, double, double, sCoord [],
00092 double [6][12] );
00093 static void _TETR4DerivShp ( double, double, double, sDerivRST [] );
00094 static void _TETR4GetDisplacement( sElement *, double *, double [] );
00095 static double _TETR4MinHeight ( sCoord * );
00096 static double _TETR4Volume ( sCoord * );
00097 static void _TETR4ElementCenter ( sElement *elm, sCoord coord[1] );
00098 static void _TETR4FaceCenter( sCoord *coord0, sCoord *coord1,
00099 sCoord *coord2, sCoord *center );
00100
00101 static double RigidCoeff( sElement *elm, int noi, int noj, int nok );
00102 static double _Area( sCoord coord[3] );
00103 static void _Normal( sCoord coord[3], sCoord *normal );
00104
00105
00106
00107
00108
00109
00110 static double RigidCoeff( sElement *elm, int noi, int noj, int nok )
00111 {
00112 sCoord coord[3];
00113 double area = 0.0;
00114
00115
00116
00117 coord[0].x = elm->nodes[noi-1].coord.x;
00118 coord[0].y = elm->nodes[noi-1].coord.y;
00119 coord[0].z = elm->nodes[noi-1].coord.z;
00120 coord[1].x = elm->nodes[noj-1].coord.x;
00121 coord[1].y = elm->nodes[noj-1].coord.y;
00122 coord[1].z = elm->nodes[noj-1].coord.z;
00123 coord[2].x = elm->nodes[nok-1].coord.x;
00124 coord[2].y = elm->nodes[nok-1].coord.y;
00125 coord[2].z = elm->nodes[nok-1].coord.z;
00126
00127
00128
00129 area = _Area( coord );
00130
00131 return( area );
00132
00133 }
00134
00135 static double _Area( sCoord coord[3] )
00136 {
00137 double area = 0.0;
00138 double u[3],v[3],w[3];
00139
00140
00141
00142 u[0] = coord[1].x - coord[0].x;
00143 u[1] = coord[1].y - coord[0].y;
00144 u[2] = coord[1].z - coord[0].z;
00145 v[0] = coord[2].x - coord[0].x;
00146 v[1] = coord[2].y - coord[0].y;
00147 v[2] = coord[2].z - coord[0].z;
00148
00149 w[0] = u[1] * v[2] - u[2] * v[1];
00150 w[1] = u[2] * v[0] - u[0] * v[2];
00151 w[2] = u[0] * v[1] - u[1] * v[0];
00152 area = sqrt(w[0]*w[0] + w[1]*w[1] + w[2]*w[2]) / 2.0;
00153
00154 return( area );
00155
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165 static void _TETR4ElementCenter( sElement *elm, sCoord coord[1] )
00166 {
00167 sTetr4Data *data = 0L;
00168 int i, node;
00169
00170 coord[0].x = 0.0;
00171 coord[0].y = 0.0;
00172 coord[0].z = 0.0;
00173
00174
00175
00176 data = (sTetr4Data *)elm->data;
00177
00178 for( i = 0; i < data->NumNodes; i++ ) {
00179 node = data->inc[i]-1;
00180 coord[0].x += NodeVector[node].coord.x;
00181 coord[0].y += NodeVector[node].coord.y;
00182 coord[0].z += NodeVector[node].coord.z;
00183 }
00184
00185
00186 coord[0].x /= data->NumNodes;
00187 coord[0].y /= data->NumNodes;
00188 coord[0].z /= data->NumNodes;
00189 }
00190
00191
00192
00193
00194 static double _TETR4Volume( sCoord *coord )
00195 {
00196 double jac[3][3];
00197 double detjac, volume = 0.0;
00198
00199
00200
00201 _TETR4Jacobian( _GPoint, _GPoint, _GPoint, coord, &detjac, jac );
00202
00203
00204
00205 volume = detjac * _GWeight;
00206
00207 return volume;
00208
00209 }
00210
00211
00212 static void _TETR4FaceCenter( sCoord *coord0, sCoord *coord1,
00213 sCoord *coord2, sCoord *center )
00214 {
00215 sCoord med[2];
00216 double dx, dy, dz;
00217
00218
00219
00220
00221
00222
00223
00224 med[0].x = coord0->x;
00225 med[0].y = coord0->y;
00226 med[0].z = coord0->z;
00227 med[1].x = ( coord1->x + coord2->x ) / 2.0;
00228 med[1].y = ( coord1->y + coord2->y ) / 2.0;
00229 med[1].z = ( coord1->z + coord2->z ) / 2.0;
00230
00231 dx = ( med[1].x - med[0].x ) / 3.0;
00232 dy = ( med[1].y - med[0].y ) / 3.0;
00233 dz = ( med[1].z - med[0].z ) / 3.0;
00234
00235 center->x = med[0].x + (2*dx);
00236 center->y = med[0].y + (2*dy);
00237 center->z = med[0].z + (2*dz);
00238 }
00239
00240
00241
00242
00243
00244 #if 0
00245 static double _TETR4MinHeight( sCoord *coord )
00246 {
00247 double volume, bcorr, bmax, hmin;
00248 int i;
00249
00250
00251
00252 bmax = bcorr = hmin = volume = 0.0;
00253
00254
00255
00256 for( i = 0; i < 4; i++ ) {
00257 bcorr = sqrt( ( coord[(i+1)%4].x - coord[i].x ) * ( coord[(i+1)%4].x - coord[i].x ) +
00258 ( coord[(i+1)%4].y - coord[i].y ) * ( coord[(i+1)%4].y - coord[i].y ) +
00259 ( coord[(i+1)%4].z - coord[i].z ) * ( coord[(i+1)%4].z - coord[i].z ) );
00260
00261 if( bcorr > bmax )
00262 bmax = bcorr;
00263 }
00264
00265
00266
00267 volume = _TETR4Volume( coord );
00268
00269
00270
00271 hmin = (2.0 * volume) / bmax;
00272
00273 return hmin;
00274 }
00275
00276 #else
00277 static double _TETR4MinHeight( sCoord *coord )
00278 {
00279 sCoord center;
00280 double hmin = 0.0;
00281 double h;
00282 int i;
00283 int first = 1;
00284
00285 for( i = 0; i < 4; i++ )
00286 {
00287 _TETR4FaceCenter( &coord[i+1], &coord[(i+2)%4], &coord[(i+3)%4], ¢er );
00288 h = sqrt( ( (coord[i].x - center.x)*(coord[i].x - center.x) ) +
00289 ( (coord[i].y - center.y)*(coord[i].y - center.y) ) +
00290 ( (coord[i].z - center.z)*(coord[i].z - center.z) ) );
00291 if( first || ( h < hmin ) )
00292 {
00293 first = 0;
00294 hmin = h;
00295 }
00296 }
00297 return hmin;
00298 }
00299 #endif
00300
00301
00302
00303
00304
00305 static void _TETR4GetDisplacement( sElement *elm, double *U, double ue[12] )
00306 {
00307 sTetr4Data *data = 0L;
00308 int i;
00309
00310
00311
00312 data = (sTetr4Data *)elm->data;
00313
00314
00315
00316 for( i = 0; i < data->NumNodes; i++ ) {
00317 ue[3*i] = U[3*(data->inc[i]-1)];
00318 ue[3*i+1] = U[3*(data->inc[i]-1)+1];
00319 ue[3*i+2] = U[3*(data->inc[i]-1)+2];
00320 }
00321
00322 }
00323
00324
00325
00326
00327
00328 static void _TETR4BMatrix( double r, double s, double t, sCoord coord[4],
00329 double bm[6][12] )
00330 {
00331 double detjac;
00332 double jac[3][3], ijac[3][3];
00333 sDerivRST dshp[4];
00334 int i;
00335
00336
00337
00338 for( i = 0; i < 12; i++ )
00339 bm[0][i] = bm[1][i] = bm[2][i] =
00340 bm[3][i] = bm[4][i] = bm[5][i] = 0.0;
00341
00342
00343
00344 _TETR4Jacobian( r, s, t, coord, &detjac, jac );
00345
00346
00347
00348 ijac[0][0] = (jac[1][1] * jac[2][2] - jac[1][2] * jac[2][1]) / detjac;
00349 ijac[0][1] = -(jac[0][1] * jac[2][2] - jac[0][2] * jac[2][1]) / detjac;
00350 ijac[0][2] = (jac[0][1] * jac[1][2] - jac[0][2] * jac[1][1]) / detjac;
00351 ijac[1][0] = -(jac[1][0] * jac[2][2] - jac[1][2] * jac[2][0]) / detjac;
00352 ijac[1][1] = (jac[0][0] * jac[2][2] - jac[0][2] * jac[2][0]) / detjac;
00353 ijac[1][2] = -(jac[0][0] * jac[1][2] - jac[0][2] * jac[1][0]) / detjac;
00354 ijac[2][0] = (jac[1][0] * jac[2][1] - jac[1][1] * jac[2][0]) / detjac;
00355 ijac[2][1] = -(jac[0][0] * jac[2][1] - jac[0][1] * jac[2][0]) / detjac;
00356 ijac[2][2] = (jac[0][0] * jac[1][1] - jac[0][1] * jac[1][0]) / detjac;
00357
00358
00359
00360
00361 _TETR4DerivShp( r, s, t, dshp );
00362
00363
00364
00365 for( i = 0; i < 4; i++ ) {
00366 bm[0][3*i] = bm[3][3*i+1] = bm[4][3*i+2] = (ijac[0][0] * dshp[i].r) +
00367 (ijac[0][1] * dshp[i].s) +
00368 (ijac[0][2] * dshp[i].t);
00369 bm[1][3*i+1] = bm[3][3*i] = bm[5][3*i+2] = (ijac[1][0] * dshp[i].r) +
00370 (ijac[1][1] * dshp[i].s) +
00371 (ijac[1][2] * dshp[i].t);
00372 bm[2][3*i+2] = bm[4][3*i] = bm[5][3*i+1] = (ijac[2][0] * dshp[i].r) +
00373 (ijac[2][1] * dshp[i].s) +
00374 (ijac[2][2] * dshp[i].t);
00375 }
00376
00377 }
00378
00379
00380
00381
00382
00383
00384 static void _TETR4Jacobian( double r, double s, double t, sCoord coord[4],
00385 double *detjac, double jac[3][3] )
00386 {
00387 sDerivRST dmap[4];
00388 int i;
00389
00390
00391
00392 _TETR4DerivShp( r, s, t, dmap );
00393
00394
00395
00396 for( i = 0; i < 3; i++ )
00397 jac[i][0] = jac[i][1] = jac[i][2] = 0.0;
00398
00399 for( i = 0; i < 4; i++ ) {
00400 jac[0][0] += dmap[i].r * coord[i].x;
00401 jac[0][1] += dmap[i].r * coord[i].y;
00402 jac[0][2] += dmap[i].r * coord[i].z;
00403 jac[1][0] += dmap[i].s * coord[i].x;
00404 jac[1][1] += dmap[i].s * coord[i].y;
00405 jac[1][2] += dmap[i].s * coord[i].z;
00406 jac[2][0] += dmap[i].t * coord[i].x;
00407 jac[2][1] += dmap[i].t * coord[i].y;
00408 jac[2][2] += dmap[i].t * coord[i].z;
00409 }
00410
00411
00412
00413 (*detjac) = jac[0][0] * (jac[1][1] * jac[2][2] - jac[1][2] * jac[2][1]) -
00414 jac[0][1] * (jac[1][0] * jac[2][2] - jac[1][2] * jac[2][0]) +
00415 jac[0][2] * (jac[1][0] * jac[2][1] - jac[1][1] * jac[2][0]);
00416
00417 }
00418
00419
00420
00421
00422
00423
00424
00425 static void _TETR4GetCoord( sElement *elm, sCoord coord[4] )
00426 {
00427 sTetr4Data *data = 0L;
00428 int i;
00429
00430
00431
00432 data = (sTetr4Data *)elm->data;
00433
00434
00435
00436 for( i = 0; i < 4; i++ )
00437 {
00438 coord[i].x = elm->nodes[data->inc[i]-1].coord.x;
00439 coord[i].y = elm->nodes[data->inc[i]-1].coord.y;
00440 coord[i].z = elm->nodes[data->inc[i]-1].coord.z;
00441 }
00442
00443 }
00444
00445
00446
00447
00448
00449
00450 static void _TETR4ShapeFunc( double r, double s, double t, double shape[4] )
00451 {
00452
00453
00454 shape[0] = r;
00455 shape[1] = s;
00456 shape[2] = t;
00457 shape[3] = 1.0 - r - s - t;
00458
00459 }
00460
00461
00462
00463
00464
00465
00466 static void _TETR4DerivShp( double r, double s, double t, sDerivRST dshp[8] )
00467 {
00468
00469
00470 dshp[0].r = 1.0;
00471 dshp[1].r = 0.0;
00472 dshp[2].r = 0.0;
00473 dshp[3].r = -1.0;
00474
00475 dshp[0].s = 0.0;
00476 dshp[1].s = 1.0;
00477 dshp[2].s = 0.0;
00478 dshp[3].s = -1.0;
00479
00480 dshp[0].t = 0.0;
00481 dshp[1].t = 0.0;
00482 dshp[2].t = 1.0;
00483 dshp[3].t = -1.0;
00484
00485 }
00486
00487 static void _Normal( sCoord coord[3], sCoord *normal )
00488 {
00489 double size;
00490 int first;
00491 int curr;
00492 int prev;
00493 int i;
00494
00495 normal->x = 0.0;
00496 normal->y = 0.0;
00497 normal->z = 0.0;
00498
00499 first = 0;
00500
00501 for( i = 2; i < 3; i++ )
00502 {
00503 curr = i;
00504 prev = i-1;
00505
00506 normal->x += (coord[prev].y - coord[first].y) *
00507 (coord[curr].z - coord[first].z) -
00508 (coord[prev].z - coord[first].z) *
00509 (coord[curr].y - coord[first].y);
00510
00511 normal->y += (coord[prev].x - coord[first].x) *
00512 (coord[curr].z - coord[first].z) +
00513 (coord[prev].z - coord[first].z) *
00514 (coord[curr].x - coord[first].x);
00515
00516 normal->z += (coord[prev].x - coord[first].x) *
00517 (coord[curr].y - coord[first].y) -
00518 (coord[prev].y - coord[first].y) *
00519 (coord[curr].x - coord[first].x);
00520 }
00521
00522 size = sqrt( (normal->x) * (normal->x) + (normal->y) *
00523 (normal->y) + (normal->z) * (normal->z) );
00524
00525 if( size > 0.0 ){
00526 normal->x /= size;
00527 normal->y /= size;
00528 normal->z /= size;
00529 }
00530
00531 }
00532
00533
00534
00535
00536
00537
00538 static void TETR4New( int, int, int, int, sElement **, sElement **, sNode * );
00539 static void TETR4Free ( sElement * );
00540 static void TETR4Read ( sElement * );
00541 static int TETR4ReadInitStress ( sElement * );
00542 static void TETR4ReadProfile ( sElement * );
00543 static void TETR4MassMatrix ( sElement *, double * );
00544 static void TETR4Gravity ( sElement *, double *, double *,
00545 double * );
00546 static double TETR4RigidCoeff ( sElement * );
00547 static void TETR4Connect ( sElement *, int * );
00548 static void TETR4NumNodes ( sElement *, int * );
00549 static void TETR4AssVector ( sElement *, double *, double * );
00550 static void TETR4TimeStep ( sElement *, double * );
00551 static void TETR4InterForce ( sElement *, sTensor *, double * );
00552 static void TETR4StressStrain ( sElement *, double, double *,
00553 double *, sTensor *,
00554 sTensor * );
00555 static void TETR4WriteStress ( sElement *, FILE *, double *,
00556 double * );
00557 static void TETR4WriteGaussResult ( sElement *, FILE *, FILE * );
00558 static void TETR4WriteNodalResult ( sElement *, FILE *, FILE * );
00559 static void TETR4WriteGaussVectorResult( sElement *, int, FILE *, FILE * );
00560 static void TETR4UpdateStress ( sElement *, double, double *,
00561 sTensor * );
00562 static void TETR4PercForces ( sElement *, double * );
00563 static void TETR4SetPressure ( sElement *, double );
00564 static void TETR4SetInitStress ( sElement *, sTensor * );
00565 static void TETR4ViscoForce ( sElement *, double, sTensor *,
00566 double * );
00567 static void TETR4KMatrix( sElement *, double [24][24] );
00568 static void TETR4GetDof( sElement *, int [24], int * );
00569
00570
00571
00572
00573
00574 static void TETR4Load( sElement *elm, eLoadType ltype, int key,
00575 int noi, int noj, int nok, int *nol,
00576 double *q1x, double *q1y, double *q1z,
00577 double *q2x, double *q2y, double *q2z,
00578 double *q3x, double *q3y, double *q3z,
00579 double *q4x, double *q4y, double *q4z )
00580 {
00581 double l;
00582 double v1x = (*q1x);
00583 double v1y = (*q1y);
00584 double v1z = (*q1z);
00585 double v2x = (*q2x);
00586 double v2y = (*q2y);
00587 double v2z = (*q2z);
00588 double area;
00589 sCoord normal;
00590 sCoord coord[3];
00591 sTetr4Data *data = 0L;
00592 int i, node;
00593 sCoord vec;
00594 double prod;
00595
00596 *nol = -1;
00597
00598
00599
00600 if( ltype == UNIFORM ) {
00601
00602
00603 l = sqrt(((elm->nodes[noi-1].coord.x - elm->nodes[noj-1].coord.x) *
00604 (elm->nodes[noi-1].coord.x - elm->nodes[noj-1].coord.x)) +
00605 ((elm->nodes[noi-1].coord.y - elm->nodes[noj-1].coord.y) *
00606 (elm->nodes[noi-1].coord.y - elm->nodes[noj-1].coord.y)) +
00607 ((elm->nodes[noi-1].coord.z - elm->nodes[noj-1].coord.z) *
00608 (elm->nodes[noi-1].coord.z - elm->nodes[noj-1].coord.z)));
00609
00610 v1x *= l / 2.0;
00611 v1y *= l / 2.0;
00612 v1z *= l / 2.0;
00613
00614 (*q1x) = v1x;
00615 (*q1y) = v1y;
00616 (*q1z) = v1z;
00617
00618 (*q2x) = v1x;
00619 (*q2y) = v1y;
00620 (*q2z) = v1z;
00621 }
00622 if( ltype == AREAUNIFORM ) {
00623
00624 area = RigidCoeff(elm,noi,noj,nok);
00625
00626 (*q1x) = 1.0/3.0*v1x*area;
00627 (*q1y) = 1.0/3.0*v1y*area;
00628 (*q1z) = 1.0/3.0*v1z*area;
00629 (*q2x) = 1.0/3.0*v1x*area;
00630 (*q2y) = 1.0/3.0*v1y*area;
00631 (*q2z) = 1.0/3.0*v1z*area;
00632 (*q3x) = 1.0/3.0*v1x*area;
00633 (*q3y) = 1.0/3.0*v1y*area;
00634 (*q3z) = 1.0/3.0*v1z*area;
00635 }
00636 if( ltype == AREAPRESSURE ) {
00637
00638 area = RigidCoeff(elm,noi,noj,nok);
00639
00640 coord[0].x = elm->nodes[noi-1].coord.x;
00641 coord[0].y = elm->nodes[noi-1].coord.y;
00642 coord[0].z = elm->nodes[noi-1].coord.z;
00643 coord[1].x = elm->nodes[noj-1].coord.x;
00644 coord[1].y = elm->nodes[noj-1].coord.y;
00645 coord[1].z = elm->nodes[noj-1].coord.z;
00646 coord[2].x = elm->nodes[nok-1].coord.x;
00647 coord[2].y = elm->nodes[nok-1].coord.y;
00648 coord[2].z = elm->nodes[nok-1].coord.z;
00649
00650 _Normal( coord, &normal );
00651
00652
00653
00654 data = (sTetr4Data *)elm->data;
00655 for( i = 0; i < data->NumNodes; i++ ) {
00656 if((data->inc[i]!=noi)&&(data->inc[i]!=noj)&&(data->inc[i]!=nok)){
00657 node = data->inc[i];
00658 }
00659 }
00660
00661 vec.x = (elm->nodes[noi-1].coord.x - NodeVector[node-1].coord.x);
00662 vec.y = (elm->nodes[noi-1].coord.y - NodeVector[node-1].coord.y);
00663 vec.z = (elm->nodes[noi-1].coord.z - NodeVector[node-1].coord.z);
00664
00665 prod = vec.x * normal.x + vec.y * normal.y + vec.z * normal.z;
00666 if( prod < 0.0){
00667 normal.x *= (-1.0);
00668 normal.y *= (-1.0);
00669 normal.z *= (-1.0);
00670 }
00671
00672 (*q1x) = 1.0/3.0 * v1x * (-normal.x) * area;
00673 (*q1y) = 1.0/3.0 * v1x * (-normal.y) * area;
00674 (*q1z) = 1.0/3.0 * v1x * (-normal.z) * area;
00675 (*q2x) = 1.0/3.0 * v1x * (-normal.x) * area;
00676 (*q2y) = 1.0/3.0 * v1x * (-normal.y) * area;
00677 (*q2z) = 1.0/3.0 * v1x * (-normal.z) * area;
00678 (*q3x) = 1.0/3.0 * v1x * (-normal.x) * area;
00679 (*q3y) = 1.0/3.0 * v1x * (-normal.y) * area;
00680 (*q3z) = 1.0/3.0 * v1x * (-normal.z) * area;
00681 }
00682
00683 }
00684
00685
00686
00687
00688
00689
00690
00691
00692 static void TETR4New( int label, int matid, int intord, int tckid,
00693 sElement **elm, sElement **elist, sNode *nodes )
00694 {
00695 sTetr4Data *data = 0L;
00696
00697
00698
00699 (*elm) = (sElement *)calloc( 1, sizeof(sElement) );
00700
00701
00702
00703 data = (sTetr4Data *)calloc( 1, sizeof(sTetr4Data) );
00704
00705
00706
00707 data->matid = matid;
00708 data->tckid = tckid;
00709 data->NumNodes = 4;
00710 data->NumTensComp = 6;
00711 data->effdef = 0.0;
00712 data->prof = 0.0;
00713 data->istr[0] = 0.0;
00714 data->istr[1] = 0.0;
00715 data->istr[2] = 0.0;
00716 data->istr[3] = 0.0;
00717 data->istr[4] = 0.0;
00718 data->istr[5] = 0.0;
00719
00720
00721
00722 (*elm)->type = TETR4;
00723 (*elm)->rezone = NONE;
00724 (*elm)->display = DSP_NO;
00725 (*elm)->curve = 0;
00726 (*elm)->label = label;
00727 (*elm)->data = (void *)data;
00728 (*elm)->nodes = nodes;
00729
00730
00731
00732 elist[label-1] = (*elm);
00733
00734 }
00735
00736
00737
00738
00739
00740
00741 static void TETR4Free( sElement *elm )
00742 {
00743 sTetr4Data *data = 0L;
00744
00745
00746
00747 data = (sTetr4Data *)elm->data;
00748
00749
00750
00751 free( data );
00752
00753
00754
00755 elm->data = 0L;
00756
00757 }
00758
00759
00760
00761
00762
00763
00764 static void TETR4Read( sElement *elm )
00765 {
00766 sTetr4Data *data = 0L;
00767 int i1, i2, i3, i4;
00768
00769
00770
00771 data = (sTetr4Data *)elm->data;
00772
00773
00774
00775 fscanf( nf, "%d %d %d %d", &i1, &i2, &i3, &i4 );
00776
00777
00778
00779 data->inc[0] = i1;
00780 data->inc[1] = i2;
00781 data->inc[2] = i3;
00782 data->inc[3] = i4;
00783
00784 }
00785
00786
00787
00788
00789
00790 static int TETR4ReadInitStress( sElement *elm )
00791 {
00792 int numpg = 1;
00793 double sxx, sxy, sxz;
00794 double syy, syz, szz;
00795 sTetr4Data *data = 0L;
00796
00797
00798
00799 data = (sTetr4Data *)elm->data;
00800
00801
00802
00803
00804
00805 if( numpg != 1 )
00806 {
00807 printf( "\n\nNumber of gauss points must be equal to one.\n\n" );
00808 return 0;
00809 }
00810
00811
00812
00813
00814 fscanf( nf, "%lf %lf %lf %lf %lf %lf", &sxx, &syy, &szz, &sxy, &sxz, &syz );
00815 data->istr[0] = sxx;
00816 data->istr[1] = syy;
00817 data->istr[2] = szz;
00818 data->istr[3] = sxy;
00819 data->istr[4] = sxz;
00820 data->istr[5] = syz;
00821
00822 return 1;
00823
00824 }
00825
00826
00827
00828
00829 static void TETRA4ReadProfile( sElement *elm )
00830 {
00831 double prof;
00832 sTetr4Data *data = 0L;
00833
00834
00835
00836 data = (sTetr4Data *)elm->data;
00837
00838
00839
00840 fscanf( nf, "%lf ", &prof);
00841 data->prof = prof;
00842
00843 }
00844
00845
00846
00847
00848
00849
00850 static void TETR4MassMatrix( sElement *elm, double *mass )
00851 {
00852 sTetr4Data *data = 0L;
00853 sCoord coord[4];
00854 double shape[4], jac[3][3];
00855 double dens, detjac, coeff;
00856 int i, j;
00857
00858
00859
00860 for( i = 0; i < 12; i++ )
00861 mass[i] = 0.0;
00862
00863
00864
00865 _TETR4GetCoord( elm, coord );
00866
00867
00868
00869 data = (sTetr4Data *)elm->data;
00870 MatDensity( MatList[data->matid-1], &dens );
00871
00872
00873
00874 _TETR4ShapeFunc( _GPoint, _GPoint, _GPoint, shape );
00875
00876
00877
00878 _TETR4Jacobian( _GPoint, _GPoint, _GPoint, coord, &detjac, jac );
00879
00880
00881
00882 coeff = dens * detjac * _GWeight;
00883
00884
00885
00886 for( i = 0; i < 4; i++ ) {
00887 for( j = 0; j < 4; j++ ) {
00888 mass[3*i] += coeff * shape[i] * shape[j];
00889 mass[3*i+1] += coeff * shape[i] * shape[j];
00890 mass[3*i+2] += coeff * shape[i] * shape[j];
00891 }
00892 }
00893
00894 }
00895
00896
00897
00898
00899
00900
00901
00902 static double TETR4RigidCoeff( sElement *elm )
00903 {
00904 sCoord coord[4];
00905 double jac[3][3];
00906 double detjac, volume = 0.0;
00907
00908
00909
00910 _TETR4GetCoord( elm, coord );
00911
00912
00913
00914 _TETR4Jacobian( _GPoint, _GPoint, _GPoint, coord, &detjac, jac );
00915
00916
00917
00918 volume = detjac * _GWeight;
00919
00920 return volume;
00921
00922 }
00923
00924
00925
00926
00927
00928 static void TETR4Connect( sElement *elm, int *conn )
00929 {
00930 int i;
00931 sTetr4Data *data = 0L;
00932
00933 data = (sTetr4Data *)elm->data;
00934
00935 for( i = 0; i < data->NumNodes; i++ )
00936 conn[i] = data->inc[i];
00937
00938 }
00939
00940
00941
00942
00943
00944 static void TETR4NumNodes( sElement *elm, int *nnodes )
00945 {
00946 sTetr4Data *data = (sTetr4Data *)elm->data;
00947
00948 (*nnodes) = data->NumNodes;
00949
00950 }
00951
00952
00953
00954
00955
00956 static void TETR4AssVector( sElement *elm, double *GMatrix, double *matrix )
00957 {
00958 int i;
00959 int conn[4];
00960 sTetr4Data *data;
00961
00962
00963
00964 data = (sTetr4Data *)elm->data;
00965
00966
00967
00968 ElmConnect( elm, conn );
00969
00970
00971
00972 for( i = 0; i < data->NumNodes; i++ ) {
00973 GMatrix[3*(conn[i]-1)] += matrix[3*i];
00974 GMatrix[3*(conn[i]-1)+1] += matrix[3*i+1];
00975 GMatrix[3*(conn[i]-1)+2] += matrix[3*i+2];
00976 }
00977
00978 }
00979
00980
00981
00982
00983
00984
00985 static void TETR4StressStrain( sElement *elm, double dt, double *U,
00986 double *yield, sTensor *stre,
00987 sTensor *stra )
00988 {
00989 sTetr4Data *data = 0L;
00990 sMaterial *mat = 0L;
00991 sCoord coord[4];
00992 double cm[6][6];
00993 double bm[6][12];
00994 double ue[12];
00995 double def[6], str[6];
00996 double pf = 1.0;
00997 int i, j;
00998 double poropressure;
00999 double lambda, gamma;
01000 double distance;
01001
01002
01003
01004
01005 data = (sTetr4Data *)elm->data;
01006
01007
01008
01009 mat = MatList[data->matid-1];
01010
01011
01012
01013 _TETR4GetCoord( elm, coord );
01014
01015
01016
01017 _TETR4GetDisplacement( elm, U, ue );
01018
01019
01020
01021 MatUpdateParameter( mat, data->effdef );
01022
01023
01024
01025 MatConstitutiveMatrix( mat, cm );
01026
01027
01028
01029 _TETR4BMatrix( _GPoint, _GPoint, _GPoint, coord, bm );
01030
01031
01032
01033 for( i = 0; i < 6; i++ ) {
01034 def[i] = 0.0;
01035 for( j = 0; j < (3*data->NumNodes); j++ )
01036 def[i] += bm[i][j] * ue[j];
01037 }
01038
01039
01040
01041 for( i = 0; i < 6; i++ ) {
01042 str[i] = 0.0;
01043 for( j = 0; j < 6; j++ )
01044 str[i] += cm[i][j] * def[j];
01045 str[i] += data->istr[i];
01046 }
01047
01048
01049
01050 lambda = MatList[data->matid-1]->Lambda;
01051
01052 if(lambda>0.0){
01053
01054
01055
01056 MatDensity( mat, &gamma );
01057
01058
01059
01060 distance = data->prof;
01061
01062
01063
01064 poropressure = lambda*gamma*GForce*distance*Config.loadfactor;
01065
01066
01067
01068 for( i = 0; i < 3; i++ ) {
01069 str[i] += poropressure;
01070 }
01071
01072
01073
01074 MatUpdateStress( mat, dt, &pf, &data->effdef, str, def );
01075
01076
01077
01078 for( i = 0; i < 3; i++ ) {
01079 str[i] -= poropressure;
01080 }
01081 }
01082 else{
01083
01084
01085
01086 MatUpdateStress( mat, dt, &pf, &data->effdef, str, def );
01087
01088 }
01089
01090
01091 stre->xx = str[0];
01092 stre->yy = str[1];
01093 stre->zz = str[2];
01094 stre->xy = str[3];
01095 stre->yz = str[4];
01096 stre->xz = str[5];
01097
01098
01099
01100 if( stra != 0L ) {
01101 stra->xx = def[0];
01102 stra->yy = def[1];
01103 stra->zz = def[2];
01104 stra->xy = def[3];
01105 stra->yz = def[4];
01106 stra->xz = def[5];
01107 }
01108
01109
01110
01111 if( yield != 0L )
01112 (*yield) = (pf > 0.0) ? 0.0 : 1.0;
01113
01114 }
01115
01116
01117
01118
01119
01120 static void TETR4InterForce( sElement *elm, sTensor *stress,
01121 double *intforce )
01122 {
01123 int i, j;
01124 double coeff;
01125 double bm[6][12], str[6], jac[3][3];
01126 sCoord coord[4];
01127 sTetr4Data *data = 0L;
01128
01129
01130
01131 data = (sTetr4Data *)elm->data;
01132
01133
01134
01135 _TETR4GetCoord( elm, coord );
01136
01137
01138
01139 _TETR4BMatrix( _GPoint, _GPoint, _GPoint, coord, bm );
01140
01141
01142
01143 _TETR4Jacobian( _GPoint, _GPoint, _GPoint, coord, &coeff, jac );
01144
01145 coeff *= _GWeight;
01146
01147
01148
01149 if( stress == 0L ) {
01150 for( i = 0; i < (3*data->NumNodes); i++ ) {
01151 intforce[i] = 0.0;
01152 for( j = 0; j < 6; j++ )
01153 intforce[i] += bm[j][i] * data->istr[j];
01154 intforce[i] *= coeff;
01155 }
01156 return;
01157 }
01158
01159
01160
01161 str[0] = stress->xx;
01162 str[1] = stress->yy;
01163 str[2] = stress->zz;
01164 str[3] = stress->xy;
01165 str[4] = stress->yz;
01166 str[5] = stress->xz;
01167
01168
01169
01170 for( i = 0; i < (3*data->NumNodes); i++ ) {
01171 intforce[i] = 0.0;
01172 for( j = 0; j < 6; j++ )
01173 intforce[i] += bm[j][i] * str[j];
01174 intforce[i] *= -coeff;
01175 }
01176
01177 }
01178
01179
01180
01181
01182
01183 static void TETR4WriteStress( sElement *elm, FILE *out, double *U, double *V )
01184 {
01185 sTensor stress, strain, strd;
01186 sPTensor pstr;
01187 double yield;
01188
01189
01190
01191 if( elm->rezone == DONE ) {
01192
01193
01194
01195 stress.xx = stress.xy = stress.xz =
01196 stress.yy = stress.yz =
01197 stress.zz = 0.0;
01198 strd.xx = strd.xy = strd.xz =
01199 strd.yy = strd.yz =
01200 strd.zz = 0.0;
01201 strain.xx = strain.xy = strain.xz =
01202 strain.yy = strain.yz =
01203 strain.zz = 0.0;
01204 yield = 0.0;
01205 }
01206 else {
01207
01208
01209 TETR4StressStrain( elm, 0.0, U, &yield, &stress, &strain );
01210 }
01211
01212
01213
01214 PrincipalTensor( &stress, &pstr);
01215
01216 strd.xx = stress.xx - ((pstr.dir1 + pstr.dir2 + pstr.dir3)/3.0);
01217 strd.yy = stress.yy - ((pstr.dir1 + pstr.dir2 + pstr.dir3)/3.0);
01218 strd.zz = stress.zz - ((pstr.dir1 + pstr.dir2 + pstr.dir3)/3.0);
01219
01220
01221
01222 fwrite( &stress, sizeof(sTensor), 1, out );
01223 fwrite( &strain, sizeof(sTensor), 1, out );
01224 fwrite( &strd, sizeof(sTensor), 1, out );
01225 fwrite( &yield, sizeof(double), 1, out );
01226
01227 }
01228
01229
01230
01231
01232
01233 static void TETR4WriteNodalResult( sElement *elm, FILE *out, FILE *tmp )
01234 {
01235 sTensor str, strd, def;
01236 sPTensor pstress, pstrain;
01237 double yield;
01238 int i;
01239
01240
01241
01242 fread( &str, sizeof(sTensor), 1, tmp );
01243 fread( &def, sizeof(sTensor), 1, tmp );
01244 fread( &strd, sizeof(sTensor), 1, tmp );
01245 fread( &yield, sizeof(double), 1, tmp );
01246
01247
01248
01249 fprintf( out, "%d\n", elm->label );
01250 PrincipalTensor( &str, &pstress );
01251 PrincipalTensor( &def, &pstrain );
01252 for( i = 0; i < 4; i++ ) {
01253 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t", str.xx, str.yy, str.zz );
01254 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t", str.xy, str.xz, str.yz );
01255 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t", pstress.dir1,
01256 pstress.dir2,
01257 pstress.dir3 );
01258 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t", strd.xx, strd.yy, strd.zz );
01259 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t", def.xx, def.yy, def.zz );
01260 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t", def.xy, def.xz, def.yz );
01261 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t", pstrain.dir1,
01262 pstrain.dir2,
01263 pstrain.dir3 );
01264 fprintf( out, "%+10.5e\n", yield );
01265 }
01266
01267 }
01268
01269
01270
01271
01272
01273 static void TETR4WriteGaussResult( sElement *elm, FILE *out, FILE *tmp )
01274 {
01275 sTensor stress, strain, strd;
01276 sPTensor pstress, pstrain;
01277 double yield;
01278 int j;
01279
01280
01281
01282 fread( &stress, sizeof(sTensor), 1, tmp );
01283 fread( &strain, sizeof(sTensor), 1, tmp );
01284 fread( &strd, sizeof(sTensor), 1, tmp );
01285 fread( &yield, sizeof(double), 1, tmp );
01286
01287
01288
01289 fprintf( out, "%d\t%d\n", elm->label, 1 );
01290 PrincipalTensor( &stress, &pstress );
01291 PrincipalTensor( &strain, &pstrain );
01292
01293 for( j = 0; j < Config.numgaussresults; j++){
01294 if((strcmp( Config.gaussresults[j], "Sxx" ) == 0))
01295 fprintf( out, "%+10.5e\t", stress.xx );
01296 else if((strcmp( Config.gaussresults[j], "Syy" ) == 0))
01297 fprintf( out, "%+10.5e\t", stress.yy );
01298 else if((strcmp( Config.gaussresults[j], "Szz" ) == 0))
01299 fprintf( out, "%+10.5e\t", stress.zz );
01300 else if((strcmp( Config.gaussresults[j], "Sxy" ) == 0))
01301 fprintf( out, "%+10.5e\t", stress.xy );
01302 else if((strcmp( Config.gaussresults[j], "Sxz" ) == 0))
01303 fprintf( out, "%+10.5e\t", stress.xz );
01304 else if((strcmp( Config.gaussresults[j], "Syz" ) == 0))
01305 fprintf( out, "%+10.5e\t", stress.yz );
01306 else if((strcmp( Config.gaussresults[j], "S1" ) == 0))
01307 fprintf( out, "%+10.5e\t", pstress.dir1 );
01308 else if((strcmp( Config.gaussresults[j], "S2" ) == 0))
01309 fprintf( out, "%+10.5e\t", pstress.dir2 );
01310 else if((strcmp( Config.gaussresults[j], "S3" ) == 0))
01311 fprintf( out, "%+10.5e\t", pstress.dir3 );
01312 else if((strcmp( Config.gaussresults[j], "Sdx" ) == 0))
01313 fprintf( out, "%+10.5e\t", strd.xx );
01314 else if((strcmp( Config.gaussresults[j], "Sdy" ) == 0))
01315 fprintf( out, "%+10.5e\t", strd.yy );
01316 else if((strcmp( Config.gaussresults[j], "Sdz" ) == 0))
01317 fprintf( out, "%+10.5e\t", strd.zz );
01318 else if((strcmp( Config.gaussresults[j], "Exx" ) == 0))
01319 fprintf( out, "%+10.5e\t", strain.xx );
01320 else if((strcmp( Config.gaussresults[j], "Eyy" ) == 0))
01321 fprintf( out, "%+10.5e\t", strain.yy );
01322 else if((strcmp( Config.gaussresults[j], "Ezz" ) == 0))
01323 fprintf( out, "%+10.5e\t", strain.zz );
01324 else if((strcmp( Config.gaussresults[j], "Exy" ) == 0))
01325 fprintf( out, "%+10.5e\t", strain.xy );
01326 else if((strcmp( Config.gaussresults[j], "Exz" ) == 0))
01327 fprintf( out, "%+10.5e\t", strain.xz );
01328 else if((strcmp( Config.gaussresults[j], "Eyz" ) == 0))
01329 fprintf( out, "%+10.5e\t", strain.yz );
01330 else if((strcmp( Config.gaussresults[j], "E1" ) == 0))
01331 fprintf( out, "%+10.5e\t", pstrain.dir1 );
01332 else if((strcmp( Config.gaussresults[j], "E2" ) == 0))
01333 fprintf( out, "%+10.5e\t", pstrain.dir2 );
01334 else if((strcmp( Config.gaussresults[j], "E3" ) == 0))
01335 fprintf( out, "%+10.5e\t", pstrain.dir3 );
01336 else if((strcmp( Config.gaussresults[j], "Ev" ) == 0))
01337 fprintf( out, "%+10.5e\t", (pstrain.dir1+pstrain.dir2+pstrain.dir3) );
01338 }
01339
01340 }
01341
01342
01343
01344
01345
01346 static void TETR4WriteGaussVectorResult( sElement *elm, int version,
01347 FILE *out, FILE *tmp )
01348 {
01349 sTensor stress, strain, strd;
01350 sPTensor pstress, pstrain;
01351 double yield;
01352
01353
01354
01355 fread( &stress, sizeof(sTensor), 1, tmp );
01356 fread( &strain, sizeof(sTensor), 1, tmp );
01357 fread( &strd, sizeof(sTensor), 1, tmp );
01358 fread( &yield, sizeof(double), 1, tmp );
01359
01360
01361
01362 fprintf( out, "%d\t%d\n", elm->label, 1 );
01363 PrincipalTensor( &stress, &pstress );
01364 PrincipalTensor( &strain, &pstrain );
01365 if( version > 1 ) {
01366 fprintf( out, "%+10.5e\t%+10.5e\n", pstress.dir1, pstrain.dir1 );
01367 fprintf( out, "%+10.5e\t%+10.5e\n", pstress.dir2, pstrain.dir2 );
01368 fprintf( out, "%+10.5e\t%+10.5e\n", pstress.dir3, pstrain.dir3 );
01369 fprintf( out, "%+10.5e\t%+10.5e\n", pstress.cos1x, pstrain.cos1x );
01370 fprintf( out, "%+10.5e\t%+10.5e\n", pstress.cos2x, pstrain.cos2x );
01371 fprintf( out, "%+10.5e\t%+10.5e\n", pstress.cos3x, pstrain.cos3x );
01372 fprintf( out, "%+10.5e\t%+10.5e\n", pstress.cos1y, pstrain.cos1y );
01373 fprintf( out, "%+10.5e\t%+10.5e\n", pstress.cos2y, pstrain.cos2y );
01374 fprintf( out, "%+10.5e\t%+10.5e\n", pstress.cos3y, pstrain.cos3y );
01375 fprintf( out, "%+10.5e\t%+10.5e\n", pstress.cos1z, pstrain.cos1z );
01376 fprintf( out, "%+10.5e\t%+10.5e\n", pstress.cos2z, pstrain.cos2z );
01377 fprintf( out, "%+10.5e\t%+10.5e\n", pstress.cos3z, pstrain.cos3z );
01378 }
01379 else {
01380 if( pstress.dir1 > 0.0 )
01381 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (pstress.dir1*pstress.cos1x),
01382 (pstress.dir1*pstress.cos1y),
01383 0.0 );
01384 else
01385 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01386
01387 if( pstress.dir1 < 0.0 )
01388 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (pstress.dir1*pstress.cos1x),
01389 (pstress.dir1*pstress.cos1y),
01390 0.0 );
01391 else
01392 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01393
01394 if( pstress.dir3 > 0.0 )
01395 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (pstress.dir3*pstress.cos3x),
01396 (pstress.dir3*pstress.cos3y),
01397 0.0 );
01398 else
01399 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01400
01401 if( pstress.dir3 < 0.0 )
01402 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (pstress.dir3*pstress.cos3x),
01403 (pstress.dir3*pstress.cos3y),
01404 0.0 );
01405 else
01406 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01407
01408 if( pstrain.dir1 > 0.0 )
01409 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (pstrain.dir1*pstrain.cos1x),
01410 (pstrain.dir1*pstrain.cos1y),
01411 0.0 );
01412 else
01413 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01414
01415 if( pstrain.dir1 < 0.0 )
01416 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (pstrain.dir1*pstrain.cos1x),
01417 (pstrain.dir1*pstrain.cos1y),
01418 0.0 );
01419 else
01420 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01421
01422 if( pstrain.dir3 > 0.0 )
01423 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (pstrain.dir3*pstrain.cos3x),
01424 (pstrain.dir3*pstrain.cos3y),
01425 0.0 );
01426 else
01427 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01428
01429 if( pstrain.dir3 < 0.0 )
01430 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (pstrain.dir3*pstrain.cos3x),
01431 (pstrain.dir3*pstrain.cos3y),
01432 0.0 );
01433 else
01434 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01435 }
01436
01437 }
01438
01439
01440
01441
01442
01443 static void TETR4UpdateStress( sElement *elm, double dtime, double *V,
01444 sTensor *stre )
01445 {
01446 sTetr4Data *data = 0L;
01447 sCoord coord[4];
01448 double bm[6][12];
01449 double ve[12];
01450 double sxx, syy, szz, rot;
01451 int i;
01452
01453
01454
01455 data = (sTetr4Data *)elm->data;
01456
01457
01458
01459 _TETR4GetCoord( elm, coord );
01460
01461
01462
01463 _TETR4GetDisplacement( elm, V, ve );
01464
01465
01466
01467 for( i = 0; i < 12; i++ )
01468 ve[i] *= dtime;
01469
01470
01471
01472 _TETR4BMatrix( _GPoint, _GPoint, _GPoint, coord, bm );
01473
01474
01475
01476 rot = 0.0;
01477 for( i = 0; i < 12; i++ )
01478 rot += bm[2][i] * ve[i] * pow( -1.0, (double)(i+1) );
01479 rot *= 0.5;
01480
01481
01482
01483 sxx = stre->xx;
01484 syy = stre->yy;
01485 szz = stre->zz;
01486
01487 stre->xx -= 2.0 * stre->xy * rot;
01488 stre->yy += 2.0 * stre->xy * rot;
01489 stre->xy += (sxx - syy) * rot;
01490
01491 }
01492
01493
01494
01495
01496
01497 static void TETR4TimeStep( sElement *elm, double *dt )
01498 {
01499 sCoord coord[4];
01500 double hmin, dtime;
01501 sTetr4Data *data = 0L;
01502 sMaterial *mat = 0L;
01503
01504
01505
01506 _TETR4GetCoord( elm, coord );
01507
01508
01509
01510 hmin = _TETR4MinHeight( coord );
01511
01512
01513
01514 data = (sTetr4Data *)elm->data;
01515
01516
01517
01518 mat = MatList[data->matid-1];
01519
01520
01521
01522 MatTimeStep( mat, &dtime );
01523
01524
01525
01526 if( mat->type == KELVIN ) (*dt) = dtime;
01527 else (*dt) = hmin * dtime;
01528
01529 }
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541 static void TETR4Gravity( sElement *elm, double *qx, double *qy, double *qz )
01542 {
01543 sTetr4Data *data = 0;
01544 sCoord coord[4];
01545 double volume, mass, gamma;
01546 int matid;
01547
01548
01549
01550 data = (sTetr4Data *)elm->data;
01551
01552
01553
01554 _TETR4GetCoord( elm, coord );
01555
01556
01557
01558 volume = _TETR4Volume( coord );
01559
01560
01561
01562 matid = data->matid;
01563 MatDensity( MatList[matid-1], &gamma );
01564
01565
01566
01567 mass = (gamma * volume) / 4.0;
01568
01569 (*qx) = mass * GravForce.gx;
01570 (*qy) = mass * GravForce.gy;
01571 (*qz) = mass * GravForce.gz;
01572
01573 }
01574
01575
01576
01577
01578
01579 static void TETR4PercForces( sElement *elm, double *pforce )
01580 {
01581 sCoord coord[4];
01582 sTetr4Data *data = 0L;
01583 sMaterial *mat = 0L;
01584 double bm[6][12], phi[4], jac[3][3], shape[4];
01585 double detjac;
01586 sTensor grad;
01587 int i, k;
01588
01589
01590
01591 _TETR4GetCoord( elm, coord );
01592
01593
01594
01595 data = (sTetr4Data *)elm->data;
01596
01597
01598
01599 mat = MatList[data->matid-1];
01600
01601
01602
01603 for( i = 0; i < data->NumNodes; i++ )
01604 phi[i] = elm->nodes[data->inc[i]-1].dof.psi + coord[i].y;
01605
01606 for( i = 0; i < 12; i++ )
01607 pforce[i] = 0.0;
01608
01609
01610
01611 _TETR4BMatrix( _GPoint, _GPoint, _GPoint, coord, bm );
01612
01613
01614
01615 _TETR4Jacobian( _GPoint, _GPoint, _GPoint, coord, &detjac, jac );
01616
01617 detjac *= _GWeight * mat->Rhof;
01618
01619
01620
01621 _TETR4ShapeFunc( _GPoint, _GPoint, _GPoint, shape );
01622
01623
01624
01625 grad.xx = grad.yy = grad.zz = 0.0;
01626 for( k = 0; k < 4; k++ ) {
01627 grad.xx += bm[0][3*k] * phi[k];
01628 grad.yy += bm[1][3*k+1] * phi[k];
01629 grad.zz += bm[2][3*k+2] * phi[k];
01630 }
01631
01632 for( k = 0; k < 4; k++ ) {
01633 pforce[3*k] += detjac * shape[k] * grad.xx;
01634 pforce[3*k+1] += detjac * shape[k] * grad.yy;
01635 pforce[3*k+2] += detjac * shape[k] * grad.zz;
01636 }
01637
01638 }
01639
01640
01641
01642
01643
01644 static void TETR4SetPressure( sElement *elm, double pot )
01645 {
01646 sCoord coord[4];
01647 sTetr4Data *data = 0L;
01648 int i, id;
01649
01650
01651
01652 _TETR4GetCoord( elm, coord );
01653
01654
01655
01656 data = (sTetr4Data *)elm->data;
01657
01658
01659
01660 for( i = 0; i < 4; i++ ) {
01661 id = data->inc[i] - 1;
01662 elm->nodes[id].dof.psi = pot - coord[i].y;
01663 }
01664
01665 }
01666
01667
01668
01669
01670 static void TETR4SetInitStress( sElement *elm, sTensor *istress )
01671 {
01672 sTetr4Data *data = 0L;
01673 int i;
01674
01675
01676
01677 data = (sTetr4Data *)elm->data;
01678
01679
01680
01681 for( i = 0; i < 4; i++ ) {
01682 data->istr[0] = istress->xx;
01683 data->istr[1] = istress->yy;
01684 data->istr[2] = istress->zz;
01685 data->istr[3] = istress->xy;
01686 data->istr[4] = istress->yz;
01687 data->istr[5] = istress->xz;
01688 }
01689
01690 }
01691
01692
01693
01694
01695 static void TETR4ViscoForce( sElement *elm, double timeStep, sTensor *stress,
01696 double *vforce )
01697 {
01698 int i, l, m;
01699 double coeff;
01700 double bm[6][12], jac[3][3], cm[6][6];
01701 double stav[6], strv[6];
01702 sTensor vsta;
01703 sCoord coord[4];
01704 sTetr4Data *data = 0L;
01705 sMaterial *mat = 0L;
01706
01707
01708
01709 data = (sTetr4Data *)elm->data;
01710
01711
01712
01713 mat = MatList[data->matid-1];
01714
01715
01716
01717 for( i = 0; i < (3*data->NumNodes); i++ )
01718 vforce[i] = 0.0;
01719
01720
01721
01722 if( !MaterialIsVisco( mat ) )
01723 return;
01724
01725
01726
01727 _TETR4GetCoord( elm, coord );
01728
01729
01730
01731 MatConstitutiveMatrix( mat, cm );
01732
01733
01734
01735 _TETR4BMatrix( _GPoint, _GPoint, _GPoint, coord, bm );
01736
01737
01738
01739 _TETR4Jacobian( _GPoint, _GPoint, _GPoint, coord, &coeff, jac );
01740
01741 coeff *= _GWeight;
01742
01743
01744
01745 MatViscoStrain( mat, timeStep, stress, &vsta );
01746
01747
01748
01749 stav[0] = vsta.xx;
01750 stav[1] = vsta.yy;
01751 stav[2] = vsta.zz;
01752 stav[3] = vsta.xy;
01753 stav[4] = vsta.yz;
01754 stav[5] = vsta.xz;
01755
01756
01757
01758 for( m = 0; m < 6; m++ ) {
01759 strv[m] = 0.0;
01760 for( l = 0; l < 6; l++ )
01761 strv[m] += cm[m][l] * stav[l];
01762 }
01763
01764
01765
01766 for( m = 0; m < (3*data->NumNodes); m++ ) {
01767 vforce[m] = 0.0;
01768 for( l = 0; l < 6; l++ )
01769 vforce[m] += bm[l][m] * strv[l];
01770 vforce[m] *= coeff;
01771 }
01772
01773 }
01774
01775
01776
01777 static void TETR4KMatrix( sElement *elm, double k[24][24] )
01778 {
01779 int i, j, l;
01780 sCoord coord[4];
01781 double jac[3][3];
01782 double detjac;
01783 double C[6][6];
01784 double B[6][12];
01785 double BTC[12][6];
01786 double ke[24][24];
01787 sTetr4Data *data = 0L;
01788 sMaterial *mat = 0L;
01789
01790
01791
01792 for( i = 0; i < 24; i++ ) {
01793 for( j = 0; j < 24; j++ ) {
01794 k[i][j] = 0.0;
01795 }
01796 }
01797
01798
01799
01800 data = (sTetr4Data *)elm->data;
01801
01802
01803
01804 mat = MatList[data->matid-1];
01805
01806
01807
01808 _TETR4GetCoord(elm, coord);
01809
01810
01811 MatConstitutiveMatrix( mat, C );
01812
01813
01814 _TETR4BMatrix( _GPoint, _GPoint, _GPoint, coord, B );
01815
01816 _TETR4Jacobian( _GPoint, _GPoint, _GPoint, coord, &detjac, jac );
01817
01818
01819 for( i = 0; i < 12; i++ ) {
01820 for( j = 0; j < 6; j++) {
01821 BTC[i][j] =0.0;
01822 for(l=0; l<6; l++){
01823 BTC[i][j] += B[l][i]*C[l][j];
01824 }
01825 }
01826 }
01827
01828 for( i = 0; i < 12; i++ ) {
01829 for( j = 0; j < 12; j++) {
01830 ke[i][j] =0.0;
01831 for(l=0; l<6; l++){
01832 ke[i][j] += BTC[i][l]*B[l][j]*detjac*_GWeight;
01833 }
01834 }
01835 }
01836
01837 for( i = 0; i < 24; i++ ) {
01838 for( j = 0; j < 24; j++) {
01839 k[i][j] += ke[i][j];
01840 }
01841 }
01842
01843 }
01844
01845 static void TETR4GetDof( sElement *elm, int u[24], int *index )
01846 {
01847 sTetr4Data *data = 0L;
01848 int i;
01849
01850
01851
01852 data = (sTetr4Data *)elm->data;
01853
01854
01855
01856 for( i = 0; i < data->NumNodes; i++ ) {
01857 u[3*i] = 3*(data->inc[i]-1);
01858 u[3*i+1] = 3*(data->inc[i]-1)+1;
01859 u[3*i+2] = 3*(data->inc[i]-1)+2;
01860 }
01861
01862 *index = 12;
01863
01864 }
01865
01866 static void TETR4GetInc( sElement *elm, int inc[8], int *index )
01867 {
01868 sTetr4Data *data = 0L;
01869 int i;
01870
01871
01872
01873 data = (sTetr4Data *)elm->data;
01874
01875
01876
01877 for( i = 0; i < data->NumNodes; i++ ) {
01878 inc[i] = data->inc[i]-1;
01879 }
01880
01881 *index = 4;
01882
01883 }
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894 void TETR4Init( void );
01895 void TETR4Init( void )
01896 {
01897
01898
01899 ElmClass[TETR4].new = TETR4New;
01900 ElmClass[TETR4].free = TETR4Free;
01901 ElmClass[TETR4].read = TETR4Read;
01902 ElmClass[TETR4].readinitstr = TETR4ReadInitStress;
01903 ElmClass[TETR4].readprofile = TETRA4ReadProfile;
01904 ElmClass[TETR4].mass = TETR4MassMatrix;
01905 ElmClass[TETR4].rigidcoeff = TETR4RigidCoeff;
01906 ElmClass[TETR4].load = TETR4Load;
01907 ElmClass[TETR4].connect = TETR4Connect;
01908 ElmClass[TETR4].numnodes = TETR4NumNodes;
01909 ElmClass[TETR4].gravity = TETR4Gravity;
01910 ElmClass[TETR4].assvector = TETR4AssVector;
01911 ElmClass[TETR4].strstrain = TETR4StressStrain;
01912 ElmClass[TETR4].timestep = TETR4TimeStep;
01913 ElmClass[TETR4].intforce = TETR4InterForce;
01914 ElmClass[TETR4].writestr = TETR4WriteStress;
01915 ElmClass[TETR4].writendlresult = TETR4WriteNodalResult;
01916 ElmClass[TETR4].writegauresult = TETR4WriteGaussResult;
01917 ElmClass[TETR4].writegauvecresult = TETR4WriteGaussVectorResult;
01918 ElmClass[TETR4].updatestress = TETR4UpdateStress;
01919 ElmClass[TETR4].percforce = TETR4PercForces;
01920 ElmClass[TETR4].setpressure = TETR4SetPressure;
01921 ElmClass[TETR4].setinitstress = TETR4SetInitStress;
01922 ElmClass[TETR4].viscoforce = TETR4ViscoForce;
01923 ElmClass[TETR4].jacobian = 0L;
01924 ElmClass[TETR4].volume = 0L;
01925 ElmClass[TETR4].KMatrix = TETR4KMatrix;
01926 ElmClass[TETR4].GetDof = TETR4GetDof;
01927 ElmClass[TETR4].GetInc = TETR4GetInc;
01928 }
01929
01930
01931
01932