00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00029
00030
00031
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include <math.h>
00036
00037 #include "rio.h"
00038 #include "load.h"
00039 #include "elm.h"
00040 #include "node.h"
00041 #include "material.h"
00042
00043
00044
00045
00046
00050 typedef struct _line2elm {
00051 int matid;
00052 int tckid;
00053 int NumNodes;
00054 int NumTensComp;
00055 int inc[2];
00056 double istr[4];
00057 double effdef;
00058 sTensor *iPress;
00059 } sLINE2Data;
00060
00061
00062
00063
00064 static void _LINE2GetCoord(sElement *, sCoord []);
00065 static double _LINE2Area(sCoord []);
00066 static double _LINE2MinHeight(sCoord []);
00067 static void _LINE2GetDisplacement(sElement *, double *, double []);
00068 static void _LINE2BMatrix(sElement *, double [3][6]);
00069 static double _LINE2Lenght(sCoord *);
00070 static sCoord _LINE2Cross(sCoord *, sCoord *);
00071 static void _LINE2Inverse(double [3][3], double [3][3]);
00072 static void _LINE2Normalize( sCoord *vec, sCoord *n );
00073
00078 static void _LINE2Normalize( sCoord *vec, sCoord *n )
00079 {
00080 double len;
00081
00082 len = _LINE2Lenght(vec);
00083
00084 n->x = vec->x / len;
00085 n->y = vec->y / len;
00086 n->z = vec->z / len;
00087 }
00088
00092 static void _LINE2Inverse(double m[3][3], double d[3][3])
00093 {
00094 double det = m[0][0] * ((m[1][1] * m[2][2]) - (m[1][2] * m[2][1])) -
00095 m[0][1] * ((m[1][0] * m[2][2]) - (m[1][2] * m[2][0])) +
00096 m[0][2] * ((m[1][0] * m[2][1]) - (m[1][1] * m[2][0]));
00097
00098 d[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) / det;
00099 d[0][1] = -(m[0][1] * m[2][2] - m[0][2] * m[2][1]) / det;
00100 d[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) / det;
00101 d[1][0] = -(m[1][0] * m[2][2] - m[1][2] * m[2][0]) / det;
00102 d[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) / det;
00103 d[1][2] = -(m[0][0] * m[1][2] - m[0][2] * m[1][0]) / det;
00104 d[2][0] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) / det;
00105 d[2][1] = -(m[0][0] * m[2][1] - m[0][1] * m[2][0]) / det;
00106 d[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) / det;
00107
00108 }
00109
00113 static double _LINE2Lenght(sCoord *v)
00114 {
00115 return sqrt((v->x * v->x) + (v->y * v->y) + (v->z * v->z));
00116
00117 }
00118
00122 static sCoord _LINE2Cross(sCoord *u, sCoord *v)
00123 {
00124 sCoord w;
00125 w.x = (u->y * v->z) - (u->z * v->y);
00126 w.y = (u->z * v->x) - (u->x * v->z);
00127 w.z = (u->x * v->y) - (u->y * v->x);
00128 return w;
00129
00130 }
00131
00137 static void _LINE2GetCoord(sElement *elm, sCoord coord[2])
00138 {
00139 sLINE2Data *data = 0L;
00140
00141
00142
00143 data = (sLINE2Data *)elm->data;
00144
00145
00146
00147 coord[0].x = elm->nodes[data->inc[0]-1].coord.x;
00148 coord[0].y = elm->nodes[data->inc[0]-1].coord.y;
00149 coord[0].z = elm->nodes[data->inc[0]-1].coord.z;
00150 coord[1].x = elm->nodes[data->inc[1]-1].coord.x;
00151 coord[1].y = elm->nodes[data->inc[1]-1].coord.y;
00152 coord[1].z = elm->nodes[data->inc[1]-1].coord.z;
00153
00154 }
00155
00161 static double _LINE2Area(sCoord coord[2])
00162 {
00163 double dx = coord[1].x - coord[0].x;
00164 double dy = coord[1].y - coord[0].y;
00165 double dz = coord[1].z - coord[0].z;
00166 return sqrt((dx * dx) + (dy * dy) + (dz * dz));
00167
00168 }
00169
00175 static double _LINE2MinHeight(sCoord coord[2])
00176 {
00177 return _LINE2Area(coord);
00178
00179 }
00180
00185 static void _LINE2GetDisplacement(sElement *elm, double *U, double ue[6])
00186 {
00187 sLINE2Data *data = 0L;
00188
00189
00190
00191 data = (sLINE2Data *)elm->data;
00192
00193
00194
00195 ue[0] = U[2*(data->inc[0]-1)];
00196 ue[1] = U[2*(data->inc[0]-1)+1];
00197 ue[2] = U[2*(data->inc[1]-1)];
00198 ue[3] = U[2*(data->inc[1]-1)+1];
00199
00200 }
00201
00205 static void _LINE2BMatrix(sElement *elm, double bm[3][6])
00206 {
00207 double jac[3][3], ijac[3][3];
00208 double len;
00209 int i;
00210 sCoord n1, n2, n3;
00211 sCoord ex = {1.0, 0.0, 0.0};
00212 sCoord ey = {0.0, 1.0, 0.0};
00213 sCoord ez = {0.0, 0.0, 1.0};
00214 sCoord coord[2], dxyz[2];
00215
00216 _LINE2GetCoord(elm, coord);
00217
00218 n1.x = 0.5 * (coord[1].x - coord[0].x);
00219 n1.y = 0.5 * (coord[1].y - coord[0].y);
00220 n1.z = 0.5 * (coord[1].z - coord[0].z);
00221
00222 len = _LINE2Lenght(&n1);
00223 n2 = _LINE2Cross(&ex, &n1);
00224 if( (_LINE2Lenght(&n2)/len) < 1.0e-5 ) {
00225 n2 = _LINE2Cross(&ey, &n1);
00226 if( (_LINE2Lenght(&n2)/len) < 1.0e-5 ) {
00227 n2 = _LINE2Cross(&ez, &n1);
00228 }
00229 }
00230 n3 = _LINE2Cross(&n1, &n2);
00231
00232 jac[0][0] = n1.x;
00233 jac[0][1] = n1.y;
00234 jac[0][2] = n1.z;
00235 jac[1][0] = n2.x;
00236 jac[1][1] = n2.y;
00237 jac[1][2] = n2.z;
00238 jac[2][0] = n3.x;
00239 jac[2][1] = n3.y;
00240 jac[2][2] = n3.z;
00241
00242 _LINE2Inverse(jac, ijac);
00243
00244 dxyz[0].x = -0.5 * ijac[0][0];
00245 dxyz[0].y = -0.5 * ijac[1][0];
00246 dxyz[0].z = -0.5 * ijac[2][0];
00247 dxyz[1].x = 0.5 * ijac[0][0];
00248 dxyz[1].y = 0.5 * ijac[1][0];
00249 dxyz[1].z = 0.5 * ijac[2][0];
00250
00251 for( i = 0; i < 2; i++ ) {
00252 bm[0][2*i] = bm[3][2*i+1] = dxyz[i].x;
00253 bm[1][2*i+1] = bm[3][2*i] = dxyz[i].y;
00254 bm[2][2*i+1] = bm[2][2*i] = 0.0;
00255 bm[0][2*i+1] = bm[1][2*i] = 0.0;
00256 }
00257
00258 }
00259
00260
00261
00262
00263 static void LINE2New(int, int, int, int, sElement **, sElement **, sNode * );
00264 static void LINE2Free(sElement * );
00265 static void LINE2Read(sElement * );
00266 static int LINE2ReadInitStress(sElement * );
00267 static void LINE2MassMatrix(sElement *, double * );
00268 static double LINE2RigidCoeff(sElement *);
00269 static void LINE2Connect(sElement *, int *);
00270 static void LINE2SetConnect(sElement *, int *);
00271 static void LINE2UpdateConnect(sElement *);
00272 static void LINE2NumNodes(sElement *, int *);
00273 static void LINE2Gravity(sElement *, double *, double *, double *);
00274 static void LINE2AssVector(sElement *, double *, double *);
00275 static void LINE2StressStrain(sElement *, double, double *, double *,
00276 sTensor *, sTensor *);
00277 static void LINE2TimeStep(sElement *, double *);
00278 static void LINE2InterForce(sElement *, sTensor *, double *);
00279 static void LINE2WriteStress(sElement *, FILE *, double *, double *);
00280 static void LINE2WriteNodalResult(sElement *, FILE *, FILE *);
00281 static void LINE2WriteGaussResult(sElement *, FILE *, FILE *);
00282 static void LINE2WriteGaussVectorResult(sElement *, int, FILE *, FILE *);
00283 static void LINE2UpdateStress(sElement *, double, double *, sTensor *);
00284 static void LINE2PercForces(sElement *, double *);
00285 static void LINE2SetPressure(sElement *, double);
00286 static void LINE2SetInitStress(sElement *, sTensor *);
00287 static void LINE2ViscoForce(sElement *, double, sTensor *, double *);
00288 static void LINE2Jacobian(sElement *, double [3][3], double [3][3]);
00289 static void LINE2Volume(sElement *, double *);
00290
00291
00292
00293
00294
00295
00296
00297 static void LINE2New(int label, int matid, int intord, int tckid,
00298 sElement **elm, sElement **elist, sNode *nodes )
00299 {
00300 sLINE2Data *data = 0L;
00301
00302
00303
00304 (*elm) = (sElement *)malloc( sizeof(sElement) );
00305
00306
00307
00308 data = (sLINE2Data *)malloc( sizeof(sLINE2Data) );
00309
00310
00311
00312 data->matid = matid;
00313 data->tckid = tckid;
00314 data->NumNodes = 2;
00315 data->NumTensComp = 4;
00316 data->effdef = 0.0;
00317 data->istr[0] = 0.0;
00318 data->istr[1] = 0.0;
00319 data->istr[2] = 0.0;
00320 data->iPress = 0L;
00321
00322
00323
00324 (*elm)->type = LINE2;
00325 (*elm)->rezone = NONE;
00326 (*elm)->display = DSP_NO;
00327 (*elm)->curve = 0;
00328 (*elm)->label = label;
00329 (*elm)->data = (void *)data;
00330 (*elm)->nodes = nodes;
00331
00332
00333
00334 elist[label-1] = (*elm);
00335
00336 }
00337
00338
00339
00340
00341
00342
00343 static void LINE2Free(sElement *elm)
00344 {
00345 sLINE2Data *data = 0L;
00346
00347
00348
00349 data = (sLINE2Data *)elm->data;
00350
00351
00352
00353 if( data->iPress != 0L )
00354 free( data->iPress );
00355
00356
00357
00358 free( data );
00359
00360
00361
00362 elm->data = 0L;
00363
00364 }
00365
00366
00367
00368
00369
00370
00371 static void LINE2Read( sElement *elm )
00372 {
00373 sLINE2Data *data = 0L;
00374 int i1, i2;
00375
00376
00377
00378 data = (sLINE2Data *)elm->data;
00379
00380
00381
00382 fscanf( nf, "%d %d", &i1, &i2 );
00383
00384
00385
00386 data->inc[0] = i1;
00387 data->inc[1] = i2;
00388
00389 }
00390
00391
00392
00393
00394
00395 static int LINE2ReadInitStress( sElement *elm )
00396 {
00397 int numpg;
00398 double sxx, syy, sxy;
00399 sLINE2Data *data = 0L;
00400
00401
00402
00403 data = (sLINE2Data *)elm->data;
00404
00405
00406
00407
00408 fscanf( nf, "%d", &numpg );
00409 if( numpg != 1 ) {
00410 printf( "\n\nNumber of gauss points must be equal to one.\n\n" );
00411 return 0;
00412 }
00413
00414
00415
00416 fscanf( nf, "%lf %lf %lf", &sxx, &syy, &sxy );
00417 data->istr[0] = sxx;
00418 data->istr[1] = syy;
00419 data->istr[2] = sxy;
00420
00421 return 1;
00422
00423 }
00424
00425
00426
00427
00428
00429
00430
00431 static void LINE2MassMatrix( sElement *elm, double *mass )
00432 {
00433 sLINE2Data *data = 0L;
00434 sCoord coord[2];
00435 double area, ncont, dens;
00436 int i, matid;
00437
00438
00439
00440 _LINE2GetCoord( elm, coord );
00441
00442
00443
00444 area = _LINE2Area( coord );
00445
00446
00447
00448 data = (sLINE2Data *)elm->data;
00449 matid = data->matid;
00450 MatDensity( MatList[matid-1], &dens );
00451
00452
00453
00454 ncont = (area * dens) / 2.0;
00455
00456
00457
00458 for( i = 0; i < 6; i++ )
00459 mass[i] = ncont;
00460
00461 }
00462
00463
00464
00465
00466
00467
00468
00469 static double LINE2RigidCoeff( sElement *elm )
00470 {
00471 sCoord coord[2];
00472 double area = 0.0;
00473
00474
00475
00476 _LINE2GetCoord( elm, coord );
00477
00478
00479
00480 area = _LINE2Area( coord );
00481
00482 return( area );
00483
00484 }
00485
00486
00487
00488
00489 static void LINE2Connect( sElement *elm, int *conn )
00490 {
00491 int i;
00492 sLINE2Data *data = 0L;
00493
00494 data = (sLINE2Data *)elm->data;
00495
00496 for( i = 0; i < data->NumNodes; i++ )
00497 conn[i] = data->inc[i];
00498
00499 }
00500
00501
00502
00503
00504 static void LINE2SetConnect( sElement *elm, int *conn )
00505 {
00506 int i;
00507 sLINE2Data *data = 0L;
00508
00509 data = (sLINE2Data *)elm->data;
00510
00511 for( i = 0; i < data->NumNodes; i++ )
00512 data->inc[i] = conn[i];
00513
00514 }
00515
00516
00517
00518
00519 static void LINE2UpdateConnect( sElement *elm )
00520 {
00521 int i;
00522 sLINE2Data *data = 0L;
00523
00524 data = (sLINE2Data *)elm->data;
00525
00526 for( i = 0; i < data->NumNodes; i++ )
00527 (data->inc[i])++;
00528
00529 }
00530
00531
00532
00533
00534 static void LINE2NumNodes( sElement *elm, int *nnodes )
00535 {
00536 sLINE2Data *data = (sLINE2Data *)elm->data;
00537
00538 (*nnodes) = data->NumNodes;
00539
00540 }
00541
00542
00543
00544
00545
00546 static void LINE2Gravity( sElement *elm, double *qx, double *qy, double *qz )
00547 {
00548 sLINE2Data *data = 0;
00549 sCoord coord[3];
00550 double area, mass, gamma;
00551 int matid;
00552
00553
00554
00555 data = (sLINE2Data *)elm->data;
00556
00557
00558
00559 _LINE2GetCoord( elm, coord );
00560
00561
00562
00563 area = _LINE2Area( coord );
00564
00565
00566
00567 matid = data->matid;
00568 MatDensity( MatList[matid-1], &gamma );
00569
00570
00571
00572 mass = (gamma * area) / 2.0;
00573
00574 (*qx) = mass * GravForce.gx;
00575 (*qy) = mass * GravForce.gy;
00576 (*qz) = mass * GravForce.gz;
00577
00578 }
00579
00580
00581
00582
00583
00584 static void LINE2AssVector( sElement *elm, double *GMatrix, double *matrix )
00585 {
00586 int i;
00587 int conn[2];
00588 sLINE2Data *data;
00589
00590
00591
00592 data = (sLINE2Data *)elm->data;
00593
00594
00595
00596 ElmConnect( elm, conn );
00597
00598
00599
00600 for( i = 0; i < data->NumNodes; i++ ) {
00601 GMatrix[2*(conn[i]-1)] += matrix[2*i];
00602 GMatrix[2*(conn[i]-1)+1] += matrix[2*i+1];
00603 }
00604
00605 }
00606
00607
00608
00609
00610
00611 static void LINE2StressStrain( sElement *elm, double dt, double *U,
00612 double *yield, sTensor *stre, sTensor *stra )
00613 {
00614 sLINE2Data *data = 0L;
00615 sMaterial *mat = 0L;
00616 double cm[6][6];
00617 double bm[3][6];
00618 double ue[6];
00619 double def[3], str[4];
00620 double nu;
00621 double pf = 1.0;
00622 int i, j;
00623
00624
00625
00626 stre = (sTensor *)memset( (void *)stre, 0, sizeof(sTensor) );
00627 if( stra != 0L )
00628 stra = (sTensor *)memset( (void *)stra, 0, sizeof(sTensor) );
00629
00630
00631
00632 data = (sLINE2Data *)elm->data;
00633
00634
00635
00636 mat = MatList[data->matid-1];
00637
00638
00639
00640 MatUpdateParameter( mat, data->effdef );
00641
00642
00643
00644 MatConstitutiveMatrix( mat, cm );
00645
00646
00647
00648 MatNuParameter( mat, &nu );
00649
00650
00651
00652 _LINE2BMatrix( elm, bm );
00653
00654
00655
00656 _LINE2GetDisplacement( elm, U, ue );
00657
00658
00659
00660 for( i = 0; i < 3; i++ ) {
00661 def[i] = 0.0;
00662 for( j = 0; j < (2*data->NumNodes); j++ )
00663 def[i] += bm[i][j] * ue[j];
00664 }
00665
00666
00667
00668 for( i = 0; i < 3; i++ ) {
00669 str[i] = 0.0;
00670 for( j = 0; j < 3; j++ )
00671 str[i] += cm[i][j] * def[j];
00672 }
00673 str[3] = 0.0;
00674
00675
00676
00677 MatUpdateStress( mat, dt, &pf, &data->effdef, str, def );
00678
00679
00680
00681 stre->xx = str[0];
00682 stre->yy = str[1];
00683 stre->xy = str[2];
00684 stre->zz = str[3];
00685
00686
00687
00688 ElementOffPlaneStress( nu, stre );
00689
00690
00691
00692 if( stra != 0L ) {
00693 stra->xx = def[0];
00694 stra->yy = def[1];
00695 stra->xy = def[2];
00696 }
00697
00698
00699
00700 if( yield != 0L )
00701 (*yield) = (pf > 0.0) ? 0.0 : 1.0;
00702
00703 }
00704
00705
00706
00707
00708
00709 static void LINE2TimeStep( sElement *elm, double *dt )
00710 {
00711 sCoord coord[2];
00712 double hmin, dtime;
00713 sLINE2Data *data = 0L;
00714 sMaterial *mat = 0L;
00715
00716
00717
00718 _LINE2GetCoord( elm, coord );
00719
00720
00721
00722 hmin = _LINE2MinHeight( coord );
00723
00724
00725
00726 data = (sLINE2Data *)elm->data;
00727
00728
00729
00730 mat = MatList[data->matid-1];
00731
00732
00733
00734 MatTimeStep( mat, &dtime );
00735
00736
00737
00738 if( mat->type == KELVIN ) (*dt) = dtime;
00739 else (*dt) = hmin * dtime;
00740
00741 }
00742
00743
00744
00745
00746
00747 static void LINE2InterForce( sElement *elm, sTensor *stress, double *intforce )
00748 {
00749 int i, j;
00750 double coeff = 0.0;
00751 double bm[3][6], str[3];
00752 sLINE2Data *data = 0L;
00753
00754
00755
00756 data = (sLINE2Data *)elm->data;
00757
00758
00759
00760 coeff = ElmRigidCoeff( elm );
00761
00762
00763
00764 _LINE2BMatrix( elm, bm );
00765
00766
00767
00768 if( stress == 0L ) {
00769 for( i = 0; i < (2*data->NumNodes); i++ ) {
00770 intforce[i] = 0.0;
00771 for( j = 0; j < 3; j++ )
00772 intforce[i] += bm[j][i] * data->istr[j];
00773 intforce[i] *= coeff;
00774 }
00775 return;
00776 }
00777
00778
00779
00780 str[0] = stress->xx;
00781 str[1] = stress->yy;
00782 str[2] = stress->xy;
00783
00784
00785
00786 for( i = 0; i < (2*data->NumNodes); i++ ) {
00787 intforce[i] = 0.0;
00788 for( j = 0; j < 3; j++ )
00789 intforce[i] += bm[j][i] * str[j];
00790 intforce[i] *= coeff;
00791 }
00792 for( i = 0; i < (2*data->NumNodes); i++ )
00793 intforce[i] *= -1.0;
00794
00795
00796
00797 if( data->iPress != 0L ) {
00798 for( i = 0; i < (2*data->NumNodes); i++ ) {
00799 intforce[i] += coeff * bm[0][i] * data->iPress->xx;
00800 intforce[i] += coeff * bm[1][i] * data->iPress->yy;
00801 }
00802 }
00803
00804 }
00805
00806
00807
00808
00809
00810 static void LINE2WriteStress( sElement *elm, FILE *out, double *U, double *V )
00811 {
00812 sTensor stress;
00813 sTensor strain;
00814 sTensor strd = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
00815 sPTensor pstr = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
00816 double yield = 0.0;
00817
00818
00819
00820 if( elm->rezone == DONE ) {
00821 stress.xx = stress.xy = stress.xz =
00822 stress.yy = stress.yz =
00823 stress.zz = 0.0;
00824 strd.xx = strd.xy = strd.xz =
00825 strd.yy = strd.yz =
00826 strd.zz = 0.0;
00827 strain.xx = strain.xy = strain.xz =
00828 strain.yy = strain.yz =
00829 strain.zz = 0.0;
00830 yield = 0.0;
00831 }
00832 else {
00833
00834
00835 LINE2StressStrain( elm, 0.0, U, &yield, &stress, &strain );
00836 }
00837
00838
00839
00840 PrincipalTensor( &stress, &pstr );
00841
00842 strd.xx = stress.xx - ((pstr.dir1 + pstr.dir3 + pstr.dir2)/3.0);
00843 strd.yy = stress.yy - ((pstr.dir1 + pstr.dir3 + pstr.dir2)/3.0);
00844
00845
00846
00847 fwrite( &stress, sizeof(sTensor), 1, out );
00848 fwrite( &strain, sizeof(sTensor), 1, out );
00849 fwrite( &strd, sizeof(sTensor), 1, out );
00850 fwrite( &yield, sizeof(double), 1, out );
00851
00852 }
00853
00854
00855
00856
00857
00858 static void LINE2WriteNodalResult( sElement *elm, FILE *out, FILE *tmp )
00859 {
00860 sTensor sts, sta;
00861 sPTensor psts, psta;
00862 sTensor strd;
00863 double yield;
00864 int i;
00865
00866
00867
00868 fread( &sts, sizeof(sTensor), 1, tmp );
00869 fread( &sta, sizeof(sTensor), 1, tmp );
00870 fread( &strd, sizeof(sTensor), 1, tmp );
00871 fread( &yield, sizeof(double), 1, tmp );
00872
00873
00874
00875 PrincipalTensor( &sts, &psts );
00876 PrincipalTensor( &sta, &psta );
00877
00878
00879
00880 fprintf( out, "%d\n", elm->label );
00881 for( i = 0; i < 2; i++ ) {
00882 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t%+10.5e\t", sts.xx,
00883 sts.yy,
00884 sts.zz,
00885 sts.xy );
00886 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t", psts.dir1,
00887 psts.dir2,
00888 psts.dir3 );
00889 fprintf( out, "%+10.5e\t%+10.5e\t", strd.xx,
00890 strd.yy );
00891 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t", sta.xx,
00892 sta.yy,
00893 sta.xy );
00894 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t", psta.dir1,
00895 psta.dir2,
00896 psta.dir3 );
00897 fprintf( out, "%+10.5e\n", yield );
00898 }
00899
00900 }
00901
00902
00903
00904
00905
00906 static void LINE2WriteGaussResult( sElement *elm, FILE *out, FILE *tmp )
00907 {
00908 sTensor sts, sta;
00909 sPTensor psts, psta;
00910 sTensor strd;
00911 double yield;
00912 double d1, d2, d3, smises;
00913
00914
00915
00916 fread( &sts, sizeof(sTensor), 1, tmp );
00917 fread( &sta, sizeof(sTensor), 1, tmp );
00918 fread( &strd, sizeof(sTensor), 1, tmp );
00919 fread( &yield, sizeof(double), 1, tmp );
00920
00921
00922
00923 PrincipalTensor( &sts, &psts );
00924 PrincipalTensor( &sta, &psta );
00925
00926
00927
00928 d1 = (psts.dir1 - psts.dir2)*(psts.dir1 - psts.dir2);
00929 d2 = (psts.dir1 - psts.dir3)*(psts.dir1 - psts.dir3);
00930 d3 = (psts.dir2 - psts.dir3)*(psts.dir2 - psts.dir3);
00931 smises = sqrt( 0.5*(d1 + d2 + d3) );
00932
00933
00934
00935 fprintf( out, "%d\t%d\n", elm->label, 1 );
00936 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t%+10.5e\t", sts.xx,
00937 sts.yy,
00938 sts.zz,
00939 sts.xy );
00940 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t", psts.dir1,
00941 psts.dir2,
00942 psts.dir3 );
00943 fprintf( out, "%+10.5e\t%+10.5e\t", strd.xx,
00944 strd.yy );
00945 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t", sta.xx,
00946 sta.yy,
00947 sta.xy );
00948 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\t", psta.dir1,
00949 psta.dir2,
00950 psta.dir3 );
00951 fprintf( out, "%+10.5e\t", (psta.dir1+psta.dir2+psta.dir3) );
00952 fprintf( out, "%+10.5e\t", yield );
00953 fprintf( out, "%+10.5e\n", smises );
00954
00955 }
00956
00957
00958
00959
00960
00961 static void LINE2WriteGaussVectorResult( sElement *elm, int version, FILE *out,
00962 FILE *tmp )
00963 {
00964 sPTensor psts, psta;
00965 sTensor sts, sta;
00966 sTensor strd;
00967 double yield;
00968
00969
00970
00971 fread( &sts, sizeof(sTensor), 1, tmp );
00972 fread( &sta, sizeof(sTensor), 1, tmp );
00973 fread( &strd, sizeof(sTensor), 1, tmp );
00974 fread( &yield, sizeof(double), 1, tmp );
00975
00976
00977
00978 PrincipalTensor( &sts, &psts );
00979 PrincipalTensor( &sta, &psta );
00980
00981
00982
00983 fprintf( out, "%d\t%d\n", elm->label, 1 );
00984
00985 if( version > 1 ) {
00986 fprintf( out, "%+10.5e\t%+10.5e\n", psts.dir1, psta.dir1 );
00987 fprintf( out, "%+10.5e\t%+10.5e\n", psts.dir2, psta.dir2 );
00988 fprintf( out, "%+10.5e\t%+10.5e\n", psts.dir3, psta.dir3 );
00989 fprintf( out, "%+10.5e\t%+10.5e\n", psts.cos1x, psta.cos1x );
00990 fprintf( out, "%+10.5e\t%+10.5e\n", psts.cos2x, psta.cos2x );
00991 fprintf( out, "%+10.5e\t%+10.5e\n", psts.cos3x, psta.cos3x );
00992 fprintf( out, "%+10.5e\t%+10.5e\n", psts.cos1y, psta.cos1y );
00993 fprintf( out, "%+10.5e\t%+10.5e\n", psts.cos2y, psta.cos2y );
00994 fprintf( out, "%+10.5e\t%+10.5e\n", psts.cos3y, psta.cos3y );
00995 fprintf( out, "%+10.5e\t%+10.5e\n", psts.cos1z, psta.cos1z );
00996 fprintf( out, "%+10.5e\t%+10.5e\n", psts.cos2z, psta.cos2z );
00997 fprintf( out, "%+10.5e\t%+10.5e\n", psts.cos3z, psta.cos3z );
00998 }
00999 else {
01000 if( psts.dir1 > 0.0 )
01001 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (psts.dir1*psts.cos1x),
01002 (psts.dir1*psts.cos1y), 0.0 );
01003 else
01004 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01005
01006 if( psts.dir1 < 0.0 )
01007 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (psts.dir1*psts.cos1x),
01008 (psts.dir1*psts.cos1y), 0.0 );
01009 else
01010 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01011
01012 if( psts.dir3 > 0.0 )
01013 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (psts.dir3*psts.cos1y),
01014 (psts.dir3*psts.cos3y), 0.0 );
01015 else
01016 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01017
01018 if( psts.dir3 < 0.0 )
01019 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (psts.dir3*psts.cos3x),
01020 (psts.dir3*psts.cos3y), 0.0 );
01021 else
01022 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01023
01024 if( psta.dir1 > 0.0 )
01025 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (psta.dir1*psta.cos1x),
01026 (psta.dir1*psta.cos1y), 0.0 );
01027 else
01028 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01029
01030 if( psta.dir1 < 0.0 )
01031 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (psta.dir1*psta.cos1x),
01032 (psta.dir1*psta.cos1y), 0.0 );
01033 else
01034 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01035
01036 if( psta.dir3 > 0.0 )
01037 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (psta.dir3*psta.cos3x),
01038 (psta.dir3*psta.cos3y), 0.0 );
01039 else
01040 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01041
01042 if( psta.dir3 < 0.0 )
01043 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", (psta.dir3*psta.cos3x),
01044 (psta.dir3*psta.cos3y), 0.0 );
01045 else
01046 fprintf( out, "%+10.5e\t%+10.5e\t%+10.5e\n", 0.0, 0.0, 0.0 );
01047 }
01048
01049 }
01050
01051
01052
01053
01054
01055
01056 static void LINE2UpdateStress( sElement *elm, double dtime, double *V,
01057 sTensor *stre )
01058 {
01059 sLINE2Data *data = 0L;
01060 double bm[3][6];
01061 double ve[6];
01062 double sxx, syy, rot;
01063 int i;
01064
01065
01066
01067 data = (sLINE2Data *)elm->data;
01068
01069
01070
01071 _LINE2BMatrix( elm, bm );
01072
01073
01074
01075 _LINE2GetDisplacement( elm, V, ve );
01076
01077
01078
01079 for( i = 0; i < 2*data->NumNodes; i++ )
01080 ve[i] *= dtime;
01081
01082
01083
01084 rot = 0.0;
01085 for( i = 0; i < 2*data->NumNodes; i++ )
01086 rot += bm[2][i] * ve[i] * pow( -1.0, (double)(i+1) );
01087 rot *= 0.5;
01088
01089
01090
01091 sxx = stre->xx;
01092 syy = stre->yy;
01093
01094 stre->xx -= 2.0 * stre->xy * rot;
01095 stre->yy += 2.0 * stre->xy * rot;
01096 stre->xy += (sxx - syy) * rot;
01097
01098 }
01099
01100
01101
01102
01103
01104 static void LINE2PercForces( sElement *elm, double *pforce )
01105 {
01106 sCoord coord[2];
01107 sLINE2Data *data = 0L;
01108 sMaterial *mat = 0L;
01109 double bm[3][6], phi[2];
01110 sTensor grad;
01111 int i, k;
01112
01113
01114
01115 for( i = 0; i < 2*data->NumNodes; i++ )
01116 pforce[i] = 0.0;
01117
01118
01119
01120 data = (sLINE2Data *)elm->data;
01121
01122
01123
01124 _LINE2GetCoord( elm, coord );
01125
01126
01127
01128 mat = MatList[data->matid-1];
01129
01130
01131
01132 for( i = 0; i < data->NumNodes; i++ )
01133 phi[i] = elm->nodes[data->inc[i]-1].dof.psi + coord[i].y;
01134
01135
01136
01137 _LINE2BMatrix( elm, bm );
01138
01139
01140
01141 grad.xx = grad.yy = 0.0;
01142 for( k = 0; k < data->NumNodes; k++ ) {
01143 grad.xx -= bm[0][2*k] * phi[k];
01144 grad.yy -= bm[1][2*k+1] * phi[k];
01145 }
01146
01147
01148
01149 for( i = 0; i < data->NumNodes; i++ ) {
01150 pforce[2*i] = grad.xx;
01151 pforce[2*i+1] = grad.yy;
01152 }
01153
01154 }
01155
01156
01157
01158
01159
01160 static void LINE2SetPressure( sElement *elm, double pot )
01161 {
01162 sCoord coord[2];
01163 sLINE2Data *data = 0L;
01164 double elev;
01165
01166
01167
01168 _LINE2GetCoord( elm, coord );
01169
01170
01171
01172 elev = 0.5 * (coord[0].y + coord[1].y);
01173
01174
01175
01176 data = (sLINE2Data *)elm->data;
01177
01178
01179
01180 data->iPress = (sTensor *)malloc( sizeof(sTensor) );
01181 ElementInitTensor( data->iPress );
01182 data->iPress->xx =
01183 data->iPress->yy = pot - elev;
01184
01185 }
01186
01187
01188
01189
01190 static void LINE2SetInitStress( sElement *elm, sTensor *istress )
01191 {
01192 sLINE2Data *data = 0L;
01193
01194
01195
01196 data = (sLINE2Data *)elm->data;
01197
01198
01199
01200 data->istr[0] = istress->xx;
01201 data->istr[1] = istress->yy;
01202 data->istr[2] = istress->xy;
01203
01204 }
01205
01206
01207
01208
01209 static void LINE2ViscoForce( sElement *elm, double timeStep, sTensor *stress,
01210 double *vforce )
01211 {
01212 int i, j;
01213 double coeff;
01214 double bm[3][6], cm[6][6];
01215 double stav[3], strv[4];
01216 sTensor vsta;
01217 sLINE2Data *data = 0L;
01218 sMaterial *mat = 0L;
01219
01220
01221
01222 data = (sLINE2Data *)elm->data;
01223
01224
01225
01226 mat = MatList[data->matid-1];
01227
01228
01229
01230 for( i = 0; i < (2*data->NumNodes); i++ )
01231 vforce[i] = 0.0;
01232
01233
01234
01235 if( !MaterialIsVisco( mat ) )
01236 return;
01237
01238
01239
01240 coeff = ElmRigidCoeff( elm );
01241
01242
01243
01244 _LINE2BMatrix( elm, bm );
01245
01246
01247
01248 MatConstitutiveMatrix( mat, cm );
01249
01250
01251
01252 MatViscoStrain( mat, timeStep, stress, &vsta );
01253
01254
01255
01256 stav[0] = vsta.xx;
01257 stav[1] = vsta.yy;
01258 stav[2] = vsta.xy;
01259
01260
01261
01262 for( i = 0; i < 3; i++ ) {
01263 strv[i] = 0.0;
01264 for( j = 0; j < 3; j++ )
01265 strv[i] += cm[i][j] * stav[j];
01266 }
01267 strv[3] = 0.0;
01268
01269
01270
01271 for( i = 0; i < (2*data->NumNodes); i++ ) {
01272 vforce[i] = 0.0;
01273 for( j = 0; j < 3; j++ )
01274 vforce[i] += bm[j][i] * strv[j];
01275 vforce[i] *= coeff;
01276 }
01277
01278 }
01279
01280
01284 static void LINE2Jacobian(sElement *elm, double jac[3][3], double ijac[3][3])
01285 {
01286 double len;
01287 sCoord n1, n2, n3;
01288 sCoord ex = {1.0, 0.0, 0.0};
01289 sCoord ey = {0.0, 1.0, 0.0};
01290 sCoord ez = {0.0, 0.0, 1.0};
01291 sCoord coord[2];
01292
01293 _LINE2GetCoord(elm, coord);
01294
01295 n1.x = (coord[1].x - coord[0].x);
01296 n1.y = (coord[1].y - coord[0].y);
01297 n1.z = (coord[1].z - coord[0].z);
01298
01299 len = _LINE2Lenght(&n1);
01300
01301
01302 _LINE2Normalize( &n1, &n1 );
01303
01304 n2 = _LINE2Cross(&ex, &n1);
01305 if( (_LINE2Lenght(&n2)/len) < 1.0e-5 ) {
01306 n2 = _LINE2Cross(&ey, &n1);
01307 if( (_LINE2Lenght(&n2)/len) < 1.0e-5 ) {
01308 n2 = _LINE2Cross(&ez, &n1);
01309 }
01310 }
01311
01312
01313 _LINE2Normalize( &n2, &n2 );
01314
01315 n3 = _LINE2Cross(&n1, &n2);
01316
01317 jac[0][0] = n1.x;
01318 jac[0][1] = n1.y;
01319 jac[0][2] = n1.z;
01320 jac[1][0] = n2.x;
01321 jac[1][1] = n2.y;
01322 jac[1][2] = n2.z;
01323 jac[2][0] = n3.x;
01324 jac[2][1] = n3.y;
01325 jac[2][2] = n3.z;
01326
01327 _LINE2Inverse(jac, ijac);
01328
01329 }
01330
01334 static void LINE2Volume(sElement *elm, double *v)
01335 {
01336 sCoord coord[2];
01337
01338
01339
01340 _LINE2GetCoord(elm, coord);
01341
01342
01343
01344 (*v) = _LINE2Area(coord);
01345
01346 }
01347
01348
01349
01350
01351
01352
01353
01354
01355 void LINE2Init(void);
01356 void LINE2Init(void)
01357 {
01358
01359
01360 ElmClass[LINE2].new = LINE2New;
01361 ElmClass[LINE2].free = LINE2Free;
01362 ElmClass[LINE2].read = LINE2Read;
01363 ElmClass[LINE2].readinitstr = LINE2ReadInitStress;
01364 ElmClass[LINE2].mass = LINE2MassMatrix;
01365 ElmClass[LINE2].rigidcoeff = LINE2RigidCoeff;
01366 ElmClass[LINE2].load = NULL;
01367 ElmClass[LINE2].connect = LINE2Connect;
01368 ElmClass[LINE2].setconnect = LINE2SetConnect;
01369 ElmClass[LINE2].updateconnect = LINE2UpdateConnect;
01370 ElmClass[LINE2].numnodes = LINE2NumNodes;
01371 ElmClass[LINE2].gravity = LINE2Gravity;
01372 ElmClass[LINE2].assvector = LINE2AssVector;
01373 ElmClass[LINE2].strstrain = LINE2StressStrain;
01374 ElmClass[LINE2].timestep = LINE2TimeStep;
01375 ElmClass[LINE2].intforce = LINE2InterForce;
01376 ElmClass[LINE2].writestr = LINE2WriteStress;
01377 ElmClass[LINE2].writendlresult = LINE2WriteNodalResult;
01378 ElmClass[LINE2].writegauresult = LINE2WriteGaussResult;
01379 ElmClass[LINE2].writegauvecresult = LINE2WriteGaussVectorResult;
01380 ElmClass[LINE2].updatestress = LINE2UpdateStress;
01381 ElmClass[LINE2].percforce = LINE2PercForces;
01382 ElmClass[LINE2].setpressure = LINE2SetPressure;
01383 ElmClass[LINE2].setinitstress = LINE2SetInitStress;
01384 ElmClass[LINE2].viscoforce = LINE2ViscoForce;
01385 ElmClass[LINE2].jacobian = LINE2Jacobian;
01386 ElmClass[LINE2].volume = LINE2Volume;
01387 ElmClass[LINE2].KMatrix = 0L;
01388 ElmClass[LINE2].GetDof = 0L;
01389
01390 }
01391
01392
01393
01394
01395
01396