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