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