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 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <math.h>
00033
00034 #include <ID.h>
00035 #include <Vector.h>
00036 #include <Matrix.h>
00037 #include <Element.h>
00038 #include <Node.h>
00039 #include <SectionForceDeformation.h>
00040 #include <Domain.h>
00041 #include <ErrorHandler.h>
00042 #include <ShellMITC4.h>
00043 #include <R3vectors.h>
00044 #include <Renderer.h>
00045
00046
00047 #include <Channel.h>
00048 #include <FEM_ObjectBroker.h>
00049
00050 #define min(a,b) ( (a)<(b) ? (a):(b) )
00051
00052
00053 Matrix ShellMITC4::stiff(24,24) ;
00054 Vector ShellMITC4::resid(24) ;
00055 Matrix ShellMITC4::mass(24,24) ;
00056
00057
00058 Matrix** ShellMITC4::GammaB1pointer = 0 ;
00059 Matrix** ShellMITC4::GammaD1pointer = 0 ;
00060 Matrix** ShellMITC4::GammaA2pointer = 0 ;
00061 Matrix** ShellMITC4::GammaC2pointer = 0 ;
00062 Matrix** ShellMITC4::Bhat = 0 ;
00063
00064
00065 const double ShellMITC4::root3 = sqrt(3.0) ;
00066 const double ShellMITC4::one_over_root3 = 1.0 / root3 ;
00067
00068 double ShellMITC4::sg[4] ;
00069 double ShellMITC4::tg[4] ;
00070 double ShellMITC4::wg[4] ;
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 ShellMITC4::ShellMITC4( ) :
00089 Element( 0, ELE_TAG_ShellMITC4 ),
00090 connectedExternalNodes(4), load(0), Ki(0)
00091 {
00092 for (int i = 0 ; i < 4; i++ )
00093 materialPointers[i] = 0;
00094
00095
00096 if ( GammaB1pointer == 0 ) {
00097 GammaB1pointer = new Matrix*[4] ;
00098 GammaB1pointer[0] = new Matrix(1,3) ;
00099 GammaB1pointer[1] = new Matrix(1,3) ;
00100 GammaB1pointer[2] = new Matrix(1,3) ;
00101 GammaB1pointer[3] = new Matrix(1,3) ;
00102 }
00103
00104 if ( GammaD1pointer == 0 ) {
00105 GammaD1pointer = new Matrix*[4] ;
00106 GammaD1pointer[0] = new Matrix(1,3) ;
00107 GammaD1pointer[1] = new Matrix(1,3) ;
00108 GammaD1pointer[2] = new Matrix(1,3) ;
00109 GammaD1pointer[3] = new Matrix(1,3) ;
00110 }
00111
00112 if ( GammaA2pointer == 0 ) {
00113 GammaA2pointer = new Matrix*[4] ;
00114 GammaA2pointer[0] = new Matrix(1,3) ;
00115 GammaA2pointer[1] = new Matrix(1,3) ;
00116 GammaA2pointer[2] = new Matrix(1,3) ;
00117 GammaA2pointer[3] = new Matrix(1,3) ;
00118 }
00119
00120 if ( GammaC2pointer == 0 ) {
00121 GammaC2pointer = new Matrix*[4] ;
00122 GammaC2pointer[0] = new Matrix(1,3) ;
00123 GammaC2pointer[1] = new Matrix(1,3) ;
00124 GammaC2pointer[2] = new Matrix(1,3) ;
00125 GammaC2pointer[3] = new Matrix(1,3) ;
00126 }
00127
00128 if ( Bhat == 0 ) {
00129 Bhat = new Matrix*[4] ;
00130 Bhat[0] = new Matrix(2,3) ;
00131 Bhat[1] = new Matrix(2,3) ;
00132 Bhat[2] = new Matrix(2,3) ;
00133 Bhat[3] = new Matrix(2,3) ;
00134 }
00135
00136 sg[0] = -one_over_root3;
00137 sg[1] = one_over_root3;
00138 sg[2] = one_over_root3;
00139 sg[3] = -one_over_root3;
00140
00141 tg[0] = -one_over_root3;
00142 tg[1] = -one_over_root3;
00143 tg[2] = one_over_root3;
00144 tg[3] = one_over_root3;
00145
00146 wg[0] = 1.0;
00147 wg[1] = 1.0;
00148 wg[2] = 1.0;
00149 wg[3] = 1.0;
00150 }
00151
00152
00153
00154
00155 ShellMITC4::ShellMITC4( int tag,
00156 int node1,
00157 int node2,
00158 int node3,
00159 int node4,
00160 SectionForceDeformation &theMaterial ) :
00161 Element( tag, ELE_TAG_ShellMITC4 ),
00162 connectedExternalNodes(4), load(0), Ki(0)
00163 {
00164 int i;
00165
00166 connectedExternalNodes(0) = node1 ;
00167 connectedExternalNodes(1) = node2 ;
00168 connectedExternalNodes(2) = node3 ;
00169 connectedExternalNodes(3) = node4 ;
00170
00171 for ( i = 0 ; i < 4; i++ ) {
00172
00173 materialPointers[i] = theMaterial.getCopy( ) ;
00174
00175 if (materialPointers[i] == 0) {
00176
00177 opserr << "ShellMITC4::constructor - failed to get a material of type: ShellSection\n";
00178 }
00179
00180 }
00181
00182
00183 if ( GammaB1pointer == 0 ) {
00184 GammaB1pointer = new Matrix*[4] ;
00185 GammaB1pointer[0] = new Matrix(1,3) ;
00186 GammaB1pointer[1] = new Matrix(1,3) ;
00187 GammaB1pointer[2] = new Matrix(1,3) ;
00188 GammaB1pointer[3] = new Matrix(1,3) ;
00189 }
00190
00191 if ( GammaD1pointer == 0 ) {
00192 GammaD1pointer = new Matrix*[4] ;
00193 GammaD1pointer[0] = new Matrix(1,3) ;
00194 GammaD1pointer[1] = new Matrix(1,3) ;
00195 GammaD1pointer[2] = new Matrix(1,3) ;
00196 GammaD1pointer[3] = new Matrix(1,3) ;
00197 }
00198
00199 if ( GammaA2pointer == 0 ) {
00200 GammaA2pointer = new Matrix*[4] ;
00201 GammaA2pointer[0] = new Matrix(1,3) ;
00202 GammaA2pointer[1] = new Matrix(1,3) ;
00203 GammaA2pointer[2] = new Matrix(1,3) ;
00204 GammaA2pointer[3] = new Matrix(1,3) ;
00205 }
00206
00207 if ( GammaC2pointer == 0 ) {
00208 GammaC2pointer = new Matrix*[4] ;
00209 GammaC2pointer[0] = new Matrix(1,3) ;
00210 GammaC2pointer[1] = new Matrix(1,3) ;
00211 GammaC2pointer[2] = new Matrix(1,3) ;
00212 GammaC2pointer[3] = new Matrix(1,3) ;
00213 }
00214
00215 if ( Bhat == 0 ) {
00216 Bhat = new Matrix*[4] ;
00217 Bhat[0] = new Matrix(2,3) ;
00218 Bhat[1] = new Matrix(2,3) ;
00219 Bhat[2] = new Matrix(2,3) ;
00220 Bhat[3] = new Matrix(2,3) ;
00221 }
00222
00223 sg[0] = -one_over_root3;
00224 sg[1] = one_over_root3;
00225 sg[2] = one_over_root3;
00226 sg[3] = -one_over_root3;
00227
00228 tg[0] = -one_over_root3;
00229 tg[1] = -one_over_root3;
00230 tg[2] = one_over_root3;
00231 tg[3] = one_over_root3;
00232
00233 wg[0] = 1.0;
00234 wg[1] = 1.0;
00235 wg[2] = 1.0;
00236 wg[3] = 1.0;
00237
00238 }
00239
00240
00241
00242 ShellMITC4::~ShellMITC4( )
00243 {
00244 int i ;
00245 for ( i = 0 ; i < 4; i++ ) {
00246
00247 delete materialPointers[i] ;
00248 materialPointers[i] = 0 ;
00249
00250 nodePointers[i] = 0 ;
00251
00252 }
00253
00254
00255 if ( GammaB1pointer != 0 ) {
00256 delete GammaB1pointer[0] ;
00257 delete GammaB1pointer[1] ;
00258 delete GammaB1pointer[2] ;
00259 delete GammaB1pointer[3] ;
00260 delete [] GammaB1pointer ;
00261 GammaB1pointer = 0 ;
00262 }
00263
00264 if ( GammaD1pointer != 0 ) {
00265 delete GammaD1pointer[0] ;
00266 delete GammaD1pointer[1] ;
00267 delete GammaD1pointer[2] ;
00268 delete GammaD1pointer[3] ;
00269 delete [] GammaD1pointer ;
00270 GammaD1pointer = 0 ;
00271 }
00272
00273 if ( GammaA2pointer != 0 ) {
00274 delete GammaA2pointer[0] ;
00275 delete GammaA2pointer[1] ;
00276 delete GammaA2pointer[2] ;
00277 delete GammaA2pointer[3] ;
00278 delete [] GammaA2pointer ;
00279 GammaA2pointer = 0 ;
00280 }
00281
00282 if ( GammaC2pointer != 0 ) {
00283 delete GammaC2pointer[0] ;
00284 delete GammaC2pointer[1] ;
00285 delete GammaC2pointer[2] ;
00286 delete GammaC2pointer[3] ;
00287 delete [] GammaC2pointer ;
00288 GammaC2pointer = 0 ;
00289 }
00290
00291 if ( Bhat != 0 ) {
00292 delete Bhat[0] ;
00293 delete Bhat[1] ;
00294 delete Bhat[2] ;
00295 delete Bhat[3] ;
00296 delete [] Bhat ;
00297 Bhat = 0 ;
00298 }
00299
00300 if (load != 0)
00301 delete load;
00302
00303 if (Ki != 0)
00304 delete Ki;
00305 }
00306
00307
00308
00309
00310 void ShellMITC4::setDomain( Domain *theDomain )
00311 {
00312 int i, j ;
00313 static Vector eig(3) ;
00314 static Matrix ddMembrane(3,3) ;
00315
00316
00317 for ( i = 0; i < 4; i++ ) {
00318 nodePointers[i] = theDomain->getNode( connectedExternalNodes(i) ) ;
00319
00320 if (nodePointers[i] == 0) {
00321 opserr << "ShellMITC4::setDomain - no node " << connectedExternalNodes(i);
00322 opserr << " exists in the model\n";
00323 }
00324 }
00325
00326
00327 const Matrix &dd = materialPointers[0]->getInitialTangent( ) ;
00328
00329
00330 for ( i = 0; i < 3; i++ ) {
00331 for ( j = 0; j < 3; j++ )
00332 ddMembrane(i,j) = dd(i,j) ;
00333 }
00334
00335
00336 eig = LovelyEig( ddMembrane ) ;
00337
00338
00339
00340 Ktt = min( eig(2), min( eig(0), eig(1) ) ) ;
00341
00342
00343
00344 computeBasis( ) ;
00345
00346 this->DomainComponent::setDomain(theDomain);
00347 }
00348
00349
00350
00351 int ShellMITC4::getNumExternalNodes( ) const
00352 {
00353 return 4 ;
00354 }
00355
00356
00357
00358 const ID& ShellMITC4::getExternalNodes( )
00359 {
00360 return connectedExternalNodes ;
00361 }
00362
00363
00364 Node **
00365 ShellMITC4::getNodePtrs(void)
00366 {
00367 return nodePointers;
00368 }
00369
00370
00371 int ShellMITC4::getNumDOF( )
00372 {
00373 return 24 ;
00374 }
00375
00376
00377
00378 int ShellMITC4::commitState( )
00379 {
00380 int success = 0 ;
00381
00382
00383 if ((success = this->Element::commitState()) != 0) {
00384 opserr << "ShellMITC4::commitState () - failed in base class";
00385 }
00386
00387 for (int i = 0; i < 4; i++ )
00388 success += materialPointers[i]->commitState( ) ;
00389
00390 return success ;
00391 }
00392
00393
00394
00395
00396 int ShellMITC4::revertToLastCommit( )
00397 {
00398 int i ;
00399 int success = 0 ;
00400
00401 for ( i = 0; i < 4; i++ )
00402 success += materialPointers[i]->revertToLastCommit( ) ;
00403
00404 return success ;
00405 }
00406
00407
00408
00409 int ShellMITC4::revertToStart( )
00410 {
00411 int i ;
00412 int success = 0 ;
00413
00414 for ( i = 0; i < 4; i++ )
00415 success += materialPointers[i]->revertToStart( ) ;
00416
00417 return success ;
00418 }
00419
00420
00421 void ShellMITC4::Print( OPS_Stream &s, int flag )
00422 {
00423 if (flag == -1) {
00424 int eleTag = this->getTag();
00425 s << "EL_QUAD4\t" << eleTag << "\t";
00426 s << eleTag << "\t" << 1;
00427 s << "\t" << connectedExternalNodes(0) << "\t" << connectedExternalNodes(1);
00428 s << "\t" << connectedExternalNodes(2) << "\t" << connectedExternalNodes(3) << "\t0.00";
00429 s << endln;
00430 s << "PROP_2D\t" << eleTag << "\t";
00431 s << eleTag << "\t" << 1;
00432 s << "\t" << -1 << "\tSHELL\t1.0\0.0";
00433 s << endln;
00434 } else if (flag < -1) {
00435
00436 int counter = (flag + 1) * -1;
00437 int eleTag = this->getTag();
00438 int i,j;
00439 for ( i = 0; i < 4; i++ ) {
00440 const Vector &stress = materialPointers[i]->getStressResultant();
00441
00442 s << "STRESS\t" << eleTag << "\t" << counter << "\t" << i << "\tTOP";
00443 for (j=0; j<6; j++)
00444 s << "\t" << stress(j);
00445 s << endln;
00446 }
00447
00448 } else {
00449 s << endln ;
00450 s << "MITC4 Bbar Non-Locking Four Node Shell \n" ;
00451 s << "Element Number: " << this->getTag() << endln ;
00452 s << "Node 1 : " << connectedExternalNodes(0) << endln ;
00453 s << "Node 2 : " << connectedExternalNodes(1) << endln ;
00454 s << "Node 3 : " << connectedExternalNodes(2) << endln ;
00455 s << "Node 4 : " << connectedExternalNodes(3) << endln ;
00456
00457 s << "Material Information : \n " ;
00458 materialPointers[0]->Print( s, flag ) ;
00459
00460 s << endln ;
00461 }
00462 }
00463
00464
00465 const Matrix& ShellMITC4::getTangentStiff( )
00466 {
00467 int tang_flag = 1 ;
00468
00469
00470 formResidAndTangent( tang_flag ) ;
00471
00472 return stiff ;
00473 }
00474
00475
00476 const Matrix& ShellMITC4::getInitialStiff( )
00477 {
00478 if (Ki != 0)
00479 return *Ki;
00480
00481 static const int ndf = 6 ;
00482
00483 static const int nstress = 8 ;
00484
00485 static const int ngauss = 4 ;
00486
00487 static const int numnodes = 4 ;
00488
00489 int i, j, k, p, q ;
00490 int jj, kk ;
00491 int node ;
00492
00493 double volume = 0.0 ;
00494
00495 static double xsj ;
00496
00497 static double dvol[ngauss] ;
00498
00499 static double shp[3][numnodes] ;
00500
00501 static double Shape[3][numnodes][ngauss] ;
00502
00503 static Matrix stiffJK(ndf,ndf) ;
00504
00505 static Matrix dd(nstress,nstress) ;
00506
00507 static Matrix J0(2,2) ;
00508
00509 static Matrix J0inv(2,2) ;
00510
00511
00512
00513 static Matrix BJ(nstress,ndf) ;
00514
00515 static Matrix BJtran(ndf,nstress) ;
00516
00517 static Matrix BK(nstress,ndf) ;
00518
00519 static Matrix BJtranD(ndf,nstress) ;
00520
00521
00522 static Matrix Bbend(3,3) ;
00523
00524 static Matrix Bshear(2,3) ;
00525
00526 static Matrix Bmembrane(3,2) ;
00527
00528
00529 static double BdrillJ[ndf] ;
00530
00531 static double BdrillK[ndf] ;
00532
00533 double *drillPointer ;
00534
00535 static double saveB[nstress][ndf][numnodes] ;
00536
00537
00538
00539 stiff.Zero( ) ;
00540
00541
00542
00543
00544
00545
00546 double L1 = 0.0 ;
00547 double L2 = 0.0 ;
00548 computeJacobian( L1, L2, xl, J0, J0inv ) ;
00549
00550
00551 computeGamma( xl, J0 ) ;
00552
00553
00554 for ( node = 0; node < numnodes; node++ ) {
00555 Bhat[node]->Zero( ) ;
00556 }
00557
00558
00559 for ( i = 0; i < ngauss; i++ ) {
00560
00561
00562 shape2d( sg[i], tg[i], xl, shp, xsj ) ;
00563
00564
00565 for ( p = 0; p < 3; p++ ) {
00566 for ( q = 0; q < numnodes; q++ )
00567 Shape[p][q][i] = shp[p][q] ;
00568 }
00569
00570
00571 dvol[i] = wg[i] * xsj ;
00572
00573 volume += dvol[i] ;
00574
00575 for ( node = 0; node < numnodes; node++ ) {
00576
00577
00578
00579 Bhat[node]->addMatrix(1.0,
00580 computeBshear(node,shp),
00581 dvol[i] ) ;
00582
00583
00584
00585
00586
00587 Bhat[node]->addMatrix(1.0,
00588 computeBbarShear(node,sg[i],tg[i],J0inv),
00589 -dvol[i] ) ;
00590
00591 }
00592
00593 }
00594
00595
00596 for ( node = 0; node < numnodes; node++ )
00597
00598 Bhat[node]->operator/=(volume) ;
00599
00600
00601
00602 for ( i = 0; i < ngauss; i++ ) {
00603
00604
00605 for ( p = 0; p < 3; p++ ) {
00606 for ( q = 0; q < numnodes; q++ )
00607 shp[p][q] = Shape[p][q][i] ;
00608 }
00609
00610
00611
00612 for ( j = 0; j < numnodes; j++ ) {
00613
00614
00615
00616 Bmembrane = computeBmembrane( j, shp ) ;
00617
00618 Bbend = computeBbend( j, shp ) ;
00619
00620 Bshear = computeBbarShear( j, sg[i], tg[i], J0inv ) ;
00621
00622
00623 Bshear += (*Bhat[j]) ;
00624
00625 BJ = assembleB( Bmembrane, Bbend, Bshear ) ;
00626
00627
00628 for (p=0; p<nstress; p++) {
00629 for (q=0; q<ndf; q++ )
00630 saveB[p][q][j] = BJ(p,q) ;
00631 }
00632
00633
00634 drillPointer = computeBdrill( j, shp ) ;
00635 for (p=0; p<ndf; p++ ) {
00636
00637 BdrillJ[p] = *drillPointer ;
00638 drillPointer++ ;
00639 }
00640 }
00641
00642
00643 dd = materialPointers[i]->getInitialTangent( ) ;
00644 dd *= dvol[i] ;
00645
00646
00647
00648 jj = 0 ;
00649 for ( j = 0; j < numnodes; j++ ) {
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667 for (p=0; p<nstress; p++) {
00668 for (q=0; q<ndf; q++ )
00669 BJ(p,q) = saveB[p][q][j] ;
00670 }
00671
00672
00673
00674 for ( p = 3; p < 6; p++ ) {
00675 for ( q = 3; q < 6; q++ )
00676 BJ(p,q) *= (-1.0) ;
00677 }
00678
00679
00680
00681
00682 for (p=0; p<ndf; p++) {
00683 for (q=0; q<nstress; q++)
00684 BJtran(p,q) = BJ(q,p) ;
00685 }
00686
00687
00688 drillPointer = computeBdrill( j, shp ) ;
00689 for (p=0; p<ndf; p++ ) {
00690 BdrillJ[p] = *drillPointer ;
00691 drillPointer++ ;
00692 }
00693
00694
00695 BJtranD.addMatrixProduct(0.0, BJtran,dd,1.0 ) ;
00696
00697 for (p=0; p<ndf; p++)
00698 BdrillJ[p] *= ( Ktt*dvol[i] ) ;
00699
00700 kk = 0 ;
00701 for ( k = 0; k < numnodes; k++ ) {
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714 for (p=0; p<nstress; p++) {
00715 for (q=0; q<ndf; q++ )
00716 BK(p,q) = saveB[p][q][k] ;
00717 }
00718
00719
00720
00721 drillPointer = computeBdrill( k, shp ) ;
00722 for (p=0; p<ndf; p++ ) {
00723 BdrillK[p] = *drillPointer ;
00724 drillPointer++ ;
00725 }
00726
00727
00728
00729 stiffJK.addMatrixProduct(0.0, BJtranD,BK,1.0 ) ;
00730
00731 for ( p = 0; p < ndf; p++ ) {
00732 for ( q = 0; q < ndf; q++ ) {
00733 stiff( jj+p, kk+q ) += stiffJK(p,q)
00734 + ( BdrillJ[p]*BdrillK[q] ) ;
00735 }
00736 }
00737
00738 kk += ndf ;
00739 }
00740
00741 jj += ndf ;
00742 }
00743
00744 }
00745
00746 Ki = new Matrix(stiff);
00747
00748 return stiff ;
00749 }
00750
00751
00752
00753 const Matrix& ShellMITC4::getMass( )
00754 {
00755 int tangFlag = 1 ;
00756
00757 formInertiaTerms( tangFlag ) ;
00758
00759 return mass ;
00760 }
00761
00762
00763 void ShellMITC4::zeroLoad( )
00764 {
00765 if (load != 0)
00766 load->Zero();
00767
00768 return ;
00769 }
00770
00771
00772 int
00773 ShellMITC4::addLoad(ElementalLoad *theLoad, double loadFactor)
00774 {
00775 opserr << "ShellMITC4::addLoad - load type unknown for ele with tag: " << this->getTag() << endln;
00776 return -1;
00777 }
00778
00779
00780
00781 int
00782 ShellMITC4::addInertiaLoadToUnbalance(const Vector &accel)
00783 {
00784 int tangFlag = 1 ;
00785
00786 int i;
00787
00788 int allRhoZero = 0;
00789 for (i=0; i<4; i++) {
00790 if (materialPointers[i]->getRho() != 0.0)
00791 allRhoZero = 1;
00792 }
00793
00794 if (allRhoZero == 0)
00795 return 0;
00796
00797 int count = 0;
00798 for (i=0; i<4; i++) {
00799 const Vector &Raccel = nodePointers[i]->getRV(accel);
00800 for (int j=0; j<6; j++)
00801 resid(count++) = Raccel(i);
00802 }
00803
00804 formInertiaTerms( tangFlag ) ;
00805 if (load == 0)
00806 load = new Vector(24);
00807 load->addMatrixVector(1.0, mass, resid, -1.0);
00808
00809 return 0;
00810 }
00811
00812
00813
00814
00815 const Vector& ShellMITC4::getResistingForce( )
00816 {
00817 int tang_flag = 0 ;
00818
00819 formResidAndTangent( tang_flag ) ;
00820
00821
00822 if (load != 0)
00823 resid -= *load;
00824
00825 return resid ;
00826 }
00827
00828
00829
00830 const Vector& ShellMITC4::getResistingForceIncInertia( )
00831 {
00832 static Vector res(24);
00833 int tang_flag = 0 ;
00834
00835
00836 formResidAndTangent( tang_flag ) ;
00837
00838 formInertiaTerms( tang_flag ) ;
00839
00840 res = resid;
00841
00842 if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0)
00843 res += this->getRayleighDampingForces();
00844
00845
00846 if (load != 0)
00847 res -= *load;
00848
00849 return res;
00850 }
00851
00852
00853
00854
00855 void
00856 ShellMITC4::formInertiaTerms( int tangFlag )
00857 {
00858
00859
00860
00861
00862
00863 static const int ndf = 6 ;
00864
00865 static const int numberNodes = 4 ;
00866
00867 static const int numberGauss = 4 ;
00868
00869 static const int nShape = 3 ;
00870
00871 static const int massIndex = nShape - 1 ;
00872
00873 double xsj ;
00874
00875 double dvol ;
00876
00877 static double shp[nShape][numberNodes] ;
00878
00879 static Vector momentum(ndf) ;
00880
00881
00882 int i, j, k, p;
00883 int jj, kk ;
00884
00885 double temp, rhoH, massJK ;
00886
00887
00888
00889 mass.Zero( ) ;
00890
00891
00892
00893
00894
00895
00896 for ( i = 0; i < numberGauss; i++ ) {
00897
00898
00899 shape2d( sg[i], tg[i], xl, shp, xsj ) ;
00900
00901
00902 dvol = wg[i] * xsj ;
00903
00904
00905
00906 momentum.Zero( ) ;
00907 for ( j = 0; j < numberNodes; j++ )
00908
00909 momentum.addVector(1.0,
00910 nodePointers[j]->getTrialAccel(),
00911 shp[massIndex][j] ) ;
00912
00913
00914
00915 rhoH = materialPointers[i]->getRho() ;
00916
00917
00918 momentum *= rhoH ;
00919
00920
00921
00922
00923 for ( j=0, jj=0; j<numberNodes; j++, jj+=ndf ) {
00924
00925 temp = shp[massIndex][j] * dvol ;
00926
00927 for ( p = 0; p < 3; p++ )
00928 resid( jj+p ) += ( temp * momentum(p) ) ;
00929
00930
00931 if ( tangFlag == 1 && rhoH != 0.0) {
00932
00933
00934 temp *= rhoH ;
00935
00936
00937
00938 for ( k=0, kk=0; k<numberNodes; k++, kk+=ndf ) {
00939
00940 massJK = temp * shp[massIndex][k] ;
00941
00942 for ( p = 0; p < 3; p++ )
00943 mass( jj+p, kk+p ) += massJK ;
00944
00945
00946 }
00947
00948 }
00949
00950
00951 }
00952
00953
00954 }
00955
00956 }
00957
00958
00959
00960
00961 void
00962 ShellMITC4::formResidAndTangent( int tang_flag )
00963 {
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003 static const int ndf = 6 ;
01004
01005 static const int nstress = 8 ;
01006
01007 static const int ngauss = 4 ;
01008
01009 static const int numnodes = 4 ;
01010
01011 int i, j, k, p, q ;
01012 int jj, kk ;
01013 int node ;
01014
01015 int success ;
01016
01017 double volume = 0.0 ;
01018
01019 static double xsj ;
01020
01021 static double dvol[ngauss] ;
01022
01023 static Vector strain(nstress) ;
01024
01025 static double shp[3][numnodes] ;
01026
01027 static double Shape[3][numnodes][ngauss] ;
01028
01029 static Vector residJ(ndf) ;
01030
01031 static Matrix stiffJK(ndf,ndf) ;
01032
01033 static Vector stress(nstress) ;
01034
01035 static Matrix dd(nstress,nstress) ;
01036
01037 static Matrix J0(2,2) ;
01038
01039 static Matrix J0inv(2,2) ;
01040
01041 double epsDrill = 0.0 ;
01042
01043 double tauDrill = 0.0 ;
01044
01045
01046
01047 static Matrix BJ(nstress,ndf) ;
01048
01049 static Matrix BJtran(ndf,nstress) ;
01050
01051 static Matrix BK(nstress,ndf) ;
01052
01053 static Matrix BJtranD(ndf,nstress) ;
01054
01055
01056 static Matrix Bbend(3,3) ;
01057
01058 static Matrix Bshear(2,3) ;
01059
01060 static Matrix Bmembrane(3,2) ;
01061
01062
01063 static double BdrillJ[ndf] ;
01064
01065 static double BdrillK[ndf] ;
01066
01067 double *drillPointer ;
01068
01069 static double saveB[nstress][ndf][numnodes] ;
01070
01071
01072
01073
01074
01075
01076 stiff.Zero( ) ;
01077 resid.Zero( ) ;
01078
01079
01080
01081
01082
01083 double L1 = 0.0 ;
01084 double L2 = 0.0 ;
01085 computeJacobian( L1, L2, xl, J0, J0inv ) ;
01086
01087
01088 computeGamma( xl, J0 ) ;
01089
01090
01091 for ( node = 0; node < numnodes; node++ ) {
01092 Bhat[node]->Zero( ) ;
01093 }
01094
01095
01096 for ( i = 0; i < ngauss; i++ ) {
01097
01098
01099 shape2d( sg[i], tg[i], xl, shp, xsj ) ;
01100
01101
01102 for ( p = 0; p < 3; p++ ) {
01103 for ( q = 0; q < numnodes; q++ )
01104 Shape[p][q][i] = shp[p][q] ;
01105 }
01106
01107
01108 dvol[i] = wg[i] * xsj ;
01109
01110 volume += dvol[i] ;
01111
01112 for ( node = 0; node < numnodes; node++ ) {
01113
01114
01115
01116 Bhat[node]->addMatrix(1.0,
01117 computeBshear(node,shp),
01118 dvol[i] ) ;
01119
01120
01121
01122
01123
01124 Bhat[node]->addMatrix(1.0,
01125 computeBbarShear(node,sg[i],tg[i],J0inv),
01126 -dvol[i] ) ;
01127
01128 }
01129
01130 }
01131
01132
01133 for ( node = 0; node < numnodes; node++ )
01134
01135 Bhat[node]->operator/=(volume) ;
01136
01137
01138
01139 for ( i = 0; i < ngauss; i++ ) {
01140
01141
01142 for ( p = 0; p < 3; p++ ) {
01143 for ( q = 0; q < numnodes; q++ )
01144 shp[p][q] = Shape[p][q][i] ;
01145 }
01146
01147
01148
01149 strain.Zero( ) ;
01150 epsDrill = 0.0 ;
01151
01152
01153
01154 for ( j = 0; j < numnodes; j++ ) {
01155
01156
01157
01158 Bmembrane = computeBmembrane( j, shp ) ;
01159
01160 Bbend = computeBbend( j, shp ) ;
01161
01162 Bshear = computeBbarShear( j, sg[i], tg[i], J0inv ) ;
01163
01164
01165 Bshear += (*Bhat[j]) ;
01166
01167 BJ = assembleB( Bmembrane, Bbend, Bshear ) ;
01168
01169
01170 for (p=0; p<nstress; p++) {
01171 for (q=0; q<ndf; q++ )
01172 saveB[p][q][j] = BJ(p,q) ;
01173 }
01174
01175
01176
01177 const Vector &ul = nodePointers[j]->getTrialDisp( ) ;
01178
01179
01180
01181 strain.addMatrixVector(1.0, BJ,ul,1.0 ) ;
01182
01183
01184 drillPointer = computeBdrill( j, shp ) ;
01185 for (p=0; p<ndf; p++ ) {
01186
01187 BdrillJ[p] = *drillPointer ;
01188 drillPointer++ ;
01189 }
01190
01191
01192 for ( p = 0; p < ndf; p++ )
01193 epsDrill += BdrillJ[p]*ul(p) ;
01194
01195 }
01196
01197
01198
01199 success = materialPointers[i]->setTrialSectionDeformation( strain ) ;
01200
01201
01202 stress = materialPointers[i]->getStressResultant( ) ;
01203
01204
01205 tauDrill = Ktt * epsDrill ;
01206
01207
01208 stress *= dvol[i] ;
01209 tauDrill *= dvol[i] ;
01210
01211 if ( tang_flag == 1 ) {
01212 dd = materialPointers[i]->getSectionTangent( ) ;
01213 dd *= dvol[i] ;
01214 }
01215
01216
01217
01218
01219 jj = 0 ;
01220 for ( j = 0; j < numnodes; j++ ) {
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238 for (p=0; p<nstress; p++) {
01239 for (q=0; q<ndf; q++ )
01240 BJ(p,q) = saveB[p][q][j] ;
01241 }
01242
01243
01244
01245 for ( p = 3; p < 6; p++ ) {
01246 for ( q = 3; q < 6; q++ )
01247 BJ(p,q) *= (-1.0) ;
01248 }
01249
01250
01251
01252
01253 for (p=0; p<ndf; p++) {
01254 for (q=0; q<nstress; q++)
01255 BJtran(p,q) = BJ(q,p) ;
01256 }
01257
01258
01259
01260 residJ.addMatrixVector(0.0, BJtran,stress,1.0 ) ;
01261
01262
01263 drillPointer = computeBdrill( j, shp ) ;
01264 for (p=0; p<ndf; p++ ) {
01265 BdrillJ[p] = *drillPointer ;
01266 drillPointer++ ;
01267 }
01268
01269
01270 for ( p = 0; p < ndf; p++ )
01271 resid( jj + p ) += ( residJ(p) + BdrillJ[p]*tauDrill ) ;
01272
01273
01274 if ( tang_flag == 1 ) {
01275
01276
01277 BJtranD.addMatrixProduct(0.0, BJtran,dd,1.0 ) ;
01278
01279 for (p=0; p<ndf; p++)
01280 BdrillJ[p] *= ( Ktt*dvol[i] ) ;
01281
01282 kk = 0 ;
01283 for ( k = 0; k < numnodes; k++ ) {
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296 for (p=0; p<nstress; p++) {
01297 for (q=0; q<ndf; q++ )
01298 BK(p,q) = saveB[p][q][k] ;
01299 }
01300
01301
01302
01303 drillPointer = computeBdrill( k, shp ) ;
01304 for (p=0; p<ndf; p++ ) {
01305 BdrillK[p] = *drillPointer ;
01306 drillPointer++ ;
01307 }
01308
01309
01310
01311
01312 stiffJK.addMatrixProduct(0.0, BJtranD,BK,1.0 ) ;
01313
01314 for ( p = 0; p < ndf; p++ ) {
01315 for ( q = 0; q < ndf; q++ ) {
01316 stiff( jj+p, kk+q ) += stiffJK(p,q)
01317 + ( BdrillJ[p]*BdrillK[q] ) ;
01318 }
01319 }
01320
01321 kk += ndf ;
01322 }
01323
01324 }
01325
01326 jj += ndf ;
01327 }
01328
01329
01330 }
01331
01332
01333 return ;
01334 }
01335
01336
01337
01338
01339
01340 void
01341 ShellMITC4::computeBasis( )
01342 {
01343
01344
01345
01346
01347
01348 static Vector temp(3) ;
01349
01350 static Vector v1(3) ;
01351 static Vector v2(3) ;
01352 static Vector v3(3) ;
01353
01354
01355
01356
01357 const Vector &coor0 = nodePointers[0]->getCrds( ) ;
01358
01359 const Vector &coor1 = nodePointers[1]->getCrds( ) ;
01360
01361 const Vector &coor2 = nodePointers[2]->getCrds( ) ;
01362
01363 const Vector &coor3 = nodePointers[3]->getCrds( ) ;
01364
01365 v1.Zero( ) ;
01366
01367 v1 = coor2 ;
01368 v1 += coor1 ;
01369 v1 -= coor3 ;
01370 v1 -= coor0 ;
01371 v1 *= 0.50 ;
01372
01373 v2.Zero( ) ;
01374
01375 v2 = coor3 ;
01376 v2 += coor2 ;
01377 v2 -= coor1 ;
01378 v2 -= coor0 ;
01379 v2 *= 0.50 ;
01380
01381
01382
01383
01384
01385 double length = v1.Norm( ) ;
01386 v1 /= length ;
01387
01388
01389
01390
01391
01392 double alpha = v2^v1 ;
01393
01394
01395 temp = v1 ;
01396 temp *= alpha ;
01397 v2 -= temp ;
01398
01399
01400
01401
01402 length = v2.Norm( ) ;
01403 v2 /= length ;
01404
01405
01406
01407 v3 = LovelyCrossProduct( v1, v2 ) ;
01408
01409
01410
01411
01412 int i ;
01413 for ( i = 0; i < 4; i++ ) {
01414
01415 const Vector &coorI = nodePointers[i]->getCrds( ) ;
01416
01417 xl[0][i] = coorI^v1 ;
01418 xl[1][i] = coorI^v2 ;
01419
01420 }
01421
01422
01423 for ( i = 0; i < 3; i++ ) {
01424 g1[i] = v1(i) ;
01425 g2[i] = v2(i) ;
01426 g3[i] = v3(i) ;
01427 }
01428
01429 }
01430
01431
01432
01433
01434 double*
01435 ShellMITC4::computeBdrill( int node, const double shp[3][4] )
01436 {
01437
01438
01439 static double Bdrill[6] ;
01440
01441 static double B1 ;
01442 static double B2 ;
01443 static double B6 ;
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463 B1 = -0.5*shp[1][node] ;
01464
01465 B2 = +0.5*shp[0][node] ;
01466
01467 B6 = -shp[2][node] ;
01468
01469 Bdrill[0] = B1*g1[0] + B2*g2[0] ;
01470 Bdrill[1] = B1*g1[1] + B2*g2[1] ;
01471 Bdrill[2] = B1*g1[2] + B2*g2[2] ;
01472
01473 Bdrill[3] = B6*g3[0] ;
01474 Bdrill[4] = B6*g3[1] ;
01475 Bdrill[5] = B6*g3[2] ;
01476
01477 return Bdrill ;
01478
01479 }
01480
01481
01482
01483
01484 void
01485 ShellMITC4::computeGamma( const double xl[2][4], const Matrix &J )
01486 {
01487
01488
01489
01490 static double Jtran[2][2] ;
01491
01492 static Matrix e1Jtran(1,2) ;
01493
01494 static Matrix e2Jtran(1,2) ;
01495
01496 static Matrix Bshear(2,3) ;
01497
01498 static double shape[3][4] ;
01499
01500 double xsj ;
01501
01502 double L1, L2 ;
01503
01504 int node ;
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515 Jtran[0][0] = J(0,0) ;
01516 Jtran[1][1] = J(1,1) ;
01517 Jtran[0][1] = J(1,0) ;
01518 Jtran[1][0] = J(0,1) ;
01519
01520
01521
01522 e1Jtran(0,0) = Jtran[0][0] ;
01523 e1Jtran(0,1) = Jtran[0][1] ;
01524
01525
01526
01527 e2Jtran(0,0) = Jtran[1][0] ;
01528 e2Jtran(0,1) = Jtran[1][1] ;
01529
01530
01531
01532
01533
01534 L1 = 0.0 ;
01535 L2 = -1.0 ;
01536
01537
01538 shape2d( L1, L2, xl, shape, xsj ) ;
01539
01540 for ( node = 0; node < 4; node++ ) {
01541
01542
01543 Bshear = computeBshear( node, shape ) ;
01544
01545 GammaB1pointer[node]->Zero( ) ;
01546
01547
01548 GammaB1pointer[node]->addMatrixProduct(0.0, e1Jtran,Bshear,1.0 );
01549
01550 }
01551
01552
01553
01554
01555
01556
01557
01558 L1 = 0.0 ;
01559 L2 = +1.0 ;
01560
01561
01562 shape2d( L1, L2, xl, shape, xsj ) ;
01563
01564 for ( node = 0; node < 4; node++ ) {
01565
01566
01567 Bshear = computeBshear( node, shape ) ;
01568
01569 GammaD1pointer[node]->Zero( ) ;
01570
01571
01572 GammaD1pointer[node]->addMatrixProduct(0.0, e1Jtran,Bshear,1.0 );
01573
01574 }
01575
01576
01577
01578
01579
01580
01581
01582 L1 = -1.0 ;
01583 L2 = 0.0 ;
01584
01585
01586 shape2d( L1, L2, xl, shape, xsj ) ;
01587
01588 for ( node = 0; node < 4; node++ ) {
01589
01590
01591 Bshear = computeBshear( node, shape ) ;
01592
01593 GammaA2pointer[node]->Zero( ) ;
01594
01595
01596 GammaA2pointer[node]->addMatrixProduct(0.0, e2Jtran,Bshear,1.0 );
01597
01598
01599 }
01600
01601
01602
01603
01604
01605
01606
01607 L1 = +1.0 ;
01608 L2 = 0.0 ;
01609
01610
01611 shape2d( L1, L2, xl, shape, xsj ) ;
01612
01613 for ( node = 0; node < 4; node++ ) {
01614
01615
01616 Bshear = computeBshear( node, shape ) ;
01617
01618 GammaC2pointer[node]->Zero( ) ;
01619
01620
01621 GammaC2pointer[node]->addMatrixProduct(0.0, e2Jtran,Bshear,1.0 );
01622
01623 }
01624
01625
01626
01627 return ;
01628
01629 }
01630
01631
01632
01633
01634 const Matrix&
01635 ShellMITC4::assembleB( const Matrix &Bmembrane,
01636 const Matrix &Bbend,
01637 const Matrix &Bshear )
01638 {
01639
01640
01641
01642
01643
01644
01645
01646
01647 static Matrix B(8,6) ;
01648
01649 static Matrix BmembraneShell(3,3) ;
01650
01651 static Matrix BbendShell(3,3) ;
01652
01653 static Matrix BshearShell(2,6) ;
01654
01655 static Matrix Gmem(2,3) ;
01656
01657 static Matrix Gshear(3,6) ;
01658
01659 int p, q ;
01660 int pp ;
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682 Gmem(0,0) = g1[0] ;
01683 Gmem(0,1) = g1[1] ;
01684 Gmem(0,2) = g1[2] ;
01685
01686 Gmem(1,0) = g2[0] ;
01687 Gmem(1,1) = g2[1] ;
01688 Gmem(1,2) = g2[2] ;
01689
01690
01691 BmembraneShell.addMatrixProduct(0.0, Bmembrane,Gmem,1.0 ) ;
01692
01693
01694
01695
01696 Matrix &Gbend = Gmem ;
01697
01698
01699 BbendShell.addMatrixProduct(0.0, Bbend,Gbend,1.0 ) ;
01700
01701
01702
01703
01704 Gshear.Zero( ) ;
01705
01706 Gshear(0,0) = g3[0] ;
01707 Gshear(0,1) = g3[1] ;
01708 Gshear(0,2) = g3[2] ;
01709
01710 Gshear(1,3) = g1[0] ;
01711 Gshear(1,4) = g1[1] ;
01712 Gshear(1,5) = g1[2] ;
01713
01714 Gshear(2,3) = g2[0] ;
01715 Gshear(2,4) = g2[1] ;
01716 Gshear(2,5) = g2[2] ;
01717
01718
01719 BshearShell.addMatrixProduct(0.0, Bshear,Gshear,1.0 ) ;
01720
01721
01722 B.Zero( ) ;
01723
01724
01725
01726
01727 for ( p = 0; p < 3; p++ ) {
01728
01729 for ( q = 0; q < 3; q++ )
01730 B(p,q) = BmembraneShell(p,q) ;
01731
01732 }
01733
01734
01735
01736 for ( p = 3; p < 6; p++ ) {
01737 pp = p - 3 ;
01738 for ( q = 3; q < 6; q++ )
01739 B(p,q) = BbendShell(pp,q-3) ;
01740 }
01741
01742
01743
01744 for ( p = 0; p < 2; p++ ) {
01745 pp = p + 6 ;
01746
01747 for ( q = 0; q < 6; q++ ) {
01748 B(pp,q) = BshearShell(p,q) ;
01749 }
01750
01751 }
01752
01753 return B ;
01754
01755 }
01756
01757
01758
01759
01760 const Matrix&
01761 ShellMITC4::computeBmembrane( int node, const double shp[3][4] )
01762 {
01763
01764 static Matrix Bmembrane(3,2) ;
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777 Bmembrane.Zero( ) ;
01778
01779 Bmembrane(0,0) = shp[0][node] ;
01780 Bmembrane(1,1) = shp[1][node] ;
01781 Bmembrane(2,0) = shp[1][node] ;
01782 Bmembrane(2,1) = shp[0][node] ;
01783
01784 return Bmembrane ;
01785
01786 }
01787
01788
01789
01790
01791 const Matrix&
01792 ShellMITC4::computeBbend( int node, const double shp[3][4] )
01793 {
01794
01795 static Matrix Bbend(3,2) ;
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808 Bbend.Zero( ) ;
01809
01810 Bbend(0,1) = -shp[0][node] ;
01811 Bbend(1,0) = shp[1][node] ;
01812 Bbend(2,0) = shp[0][node] ;
01813 Bbend(2,1) = -shp[1][node] ;
01814
01815 return Bbend ;
01816 }
01817
01818
01819
01820
01821 const Matrix&
01822 ShellMITC4::computeBbarShear( int node, double L1, double L2,
01823 const Matrix &Jinv )
01824 {
01825 static Matrix Bshear(2,3) ;
01826 static Matrix BshearNat(2,3) ;
01827
01828 static Matrix JinvTran(2,2) ;
01829
01830 static Matrix Gamma1(1,3) ;
01831 static Matrix Gamma2(1,3) ;
01832
01833 static Matrix temp1(1,3) ;
01834 static Matrix temp2(1,3) ;
01835
01836
01837
01838 JinvTran(0,0) = Jinv(0,0) ;
01839 JinvTran(1,1) = Jinv(1,1) ;
01840 JinvTran(0,1) = Jinv(1,0) ;
01841 JinvTran(1,0) = Jinv(0,1) ;
01842
01843
01844
01845
01846
01847
01848 temp1 = *GammaB1pointer[node] ;
01849 temp1 *= ( 1.0 - L2 ) ;
01850
01851 temp2 = *GammaD1pointer[node] ;
01852 temp2 *= ( 1.0 + L2 ) ;
01853
01854 Gamma1 = temp1 ;
01855 Gamma1 += temp2 ;
01856
01857
01858
01859
01860 temp1 = *GammaA2pointer[node] ;
01861 temp1 *= ( 1.0 - L1 ) ;
01862
01863 temp2 = *GammaC2pointer[node] ;
01864 temp2 *= ( 1.0 + L1 ) ;
01865
01866 Gamma2 = temp1 ;
01867 Gamma2 += temp2 ;
01868
01869
01870
01871
01872
01873
01874 BshearNat(0,0) = Gamma1(0,0) ;
01875 BshearNat(0,1) = Gamma1(0,1) ;
01876 BshearNat(0,2) = Gamma1(0,2) ;
01877
01878 BshearNat(1,0) = Gamma2(0,0) ;
01879 BshearNat(1,1) = Gamma2(0,1) ;
01880 BshearNat(1,2) = Gamma2(0,2) ;
01881
01882
01883
01884
01885 Bshear.addMatrixProduct(0.0, JinvTran,BshearNat,0.5 ) ;
01886
01887
01888 return Bshear ;
01889 }
01890
01891
01892
01893
01894 const Matrix&
01895 ShellMITC4::computeBshear( int node, const double shp[3][4] )
01896 {
01897
01898 static Matrix Bshear(2,3) ;
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910 Bshear.Zero( ) ;
01911
01912 Bshear(0,0) = shp[0][node] ;
01913 Bshear(0,2) = shp[2][node] ;
01914 Bshear(1,0) = shp[1][node] ;
01915 Bshear(1,1) = -shp[2][node] ;
01916
01917 return Bshear ;
01918
01919 }
01920
01921
01922
01923
01924 void
01925 ShellMITC4::computeJacobian( double L1, double L2,
01926 const double x[2][4],
01927 Matrix &JJ,
01928 Matrix &JJinv )
01929 {
01930 int i, j, k ;
01931
01932 static const double s[] = { -0.5, 0.5, 0.5, -0.5 } ;
01933 static const double t[] = { -0.5, -0.5, 0.5, 0.5 } ;
01934
01935 static double shp[2][4] ;
01936
01937 double ss = L1 ;
01938 double tt = L2 ;
01939
01940 for ( i = 0; i < 4; i++ ) {
01941 shp[0][i] = s[i] * ( 0.5 + t[i]*tt ) ;
01942 shp[1][i] = t[i] * ( 0.5 + s[i]*ss ) ;
01943 }
01944
01945
01946
01947
01948 JJ.Zero( ) ;
01949 for ( i = 0; i < 2; i++ ) {
01950 for ( j = 0; j < 2; j++ ) {
01951
01952 for ( k = 0; k < 4; k++ )
01953 JJ(i,j) += x[i][k] * shp[j][k] ;
01954
01955 }
01956 }
01957
01958 double xsj = JJ(0,0)*JJ(1,1) - JJ(0,1)*JJ(1,0) ;
01959
01960
01961 double jinv = 1.0 / xsj ;
01962 JJinv(0,0) = JJ(1,1) * jinv ;
01963 JJinv(1,1) = JJ(0,0) * jinv ;
01964 JJinv(0,1) = -JJ(0,1) * jinv ;
01965 JJinv(1,0) = -JJ(1,0) * jinv ;
01966
01967 return ;
01968
01969 }
01970
01971
01972
01973
01974 void
01975 ShellMITC4::shape2d( double ss, double tt,
01976 const double x[2][4],
01977 double shp[3][4],
01978 double &xsj )
01979
01980 {
01981
01982 int i, j, k ;
01983
01984 double temp ;
01985
01986 static const double s[] = { -0.5, 0.5, 0.5, -0.5 } ;
01987 static const double t[] = { -0.5, -0.5, 0.5, 0.5 } ;
01988
01989 static double xs[2][2] ;
01990 static double sx[2][2] ;
01991
01992 for ( i = 0; i < 4; i++ ) {
01993 shp[2][i] = ( 0.5 + s[i]*ss )*( 0.5 + t[i]*tt ) ;
01994 shp[0][i] = s[i] * ( 0.5 + t[i]*tt ) ;
01995 shp[1][i] = t[i] * ( 0.5 + s[i]*ss ) ;
01996 }
01997
01998
01999
02000
02001 for ( i = 0; i < 2; i++ ) {
02002 for ( j = 0; j < 2; j++ ) {
02003
02004 xs[i][j] = 0.0 ;
02005
02006 for ( k = 0; k < 4; k++ )
02007 xs[i][j] += x[i][k] * shp[j][k] ;
02008
02009 }
02010 }
02011
02012 xsj = xs[0][0]*xs[1][1] - xs[0][1]*xs[1][0] ;
02013
02014
02015 double jinv = 1.0 / xsj ;
02016 sx[0][0] = xs[1][1] * jinv ;
02017 sx[1][1] = xs[0][0] * jinv ;
02018 sx[0][1] = -xs[0][1] * jinv ;
02019 sx[1][0] = -xs[1][0] * jinv ;
02020
02021
02022
02023
02024 for ( i = 0; i < 4; i++ ) {
02025 temp = shp[0][i]*sx[0][0] + shp[1][i]*sx[1][0] ;
02026 shp[1][i] = shp[0][i]*sx[0][1] + shp[1][i]*sx[1][1] ;
02027 shp[0][i] = temp ;
02028 }
02029
02030 return ;
02031 }
02032
02033
02034
02035 Matrix
02036 ShellMITC4::transpose( int dim1,
02037 int dim2,
02038 const Matrix &M )
02039 {
02040 int i ;
02041 int j ;
02042
02043 Matrix Mtran( dim2, dim1 ) ;
02044
02045 for ( i = 0; i < dim1; i++ ) {
02046 for ( j = 0; j < dim2; j++ )
02047 Mtran(j,i) = M(i,j) ;
02048 }
02049
02050 return Mtran ;
02051 }
02052
02053
02054
02055 int ShellMITC4::sendSelf (int commitTag, Channel &theChannel)
02056 {
02057
02058 int res = 0;
02059
02060
02061
02062
02063 int dataTag = this->getDbTag();
02064
02065
02066
02067 int matDbTag;
02068
02069 static ID idData(13);
02070
02071 int i;
02072 for (i = 0; i < 4; i++) {
02073 idData(i) = materialPointers[i]->getClassTag();
02074 matDbTag = materialPointers[i]->getDbTag();
02075
02076
02077 if (matDbTag == 0) {
02078 matDbTag = theChannel.getDbTag();
02079 if (matDbTag != 0)
02080 materialPointers[i]->setDbTag(matDbTag);
02081 }
02082 idData(i+4) = matDbTag;
02083 }
02084
02085 idData(8) = this->getTag();
02086 idData(9) = connectedExternalNodes(0);
02087 idData(10) = connectedExternalNodes(1);
02088 idData(11) = connectedExternalNodes(2);
02089 idData(12) = connectedExternalNodes(3);
02090
02091 res += theChannel.sendID(dataTag, commitTag, idData);
02092 if (res < 0) {
02093 opserr << "WARNING ShellMITC4::sendSelf() - " << this->getTag() << " failed to send ID\n";
02094 return res;
02095 }
02096
02097 static Vector vectData(1);
02098 vectData(0) = Ktt;
02099
02100 res += theChannel.sendVector(dataTag, commitTag, vectData);
02101 if (res < 0) {
02102 opserr << "WARNING ShellMITC4::sendSelf() - " << this->getTag() << " failed to send ID\n";
02103 return res;
02104 }
02105
02106
02107 for (i = 0; i < 4; i++) {
02108 res += materialPointers[i]->sendSelf(commitTag, theChannel);
02109 if (res < 0) {
02110 opserr << "WARNING ShellMITC4::sendSelf() - " << this->getTag() << " failed to send its Material\n";
02111 return res;
02112 }
02113 }
02114
02115 return res;
02116 }
02117
02118 int ShellMITC4::recvSelf (int commitTag,
02119 Channel &theChannel,
02120 FEM_ObjectBroker &theBroker)
02121 {
02122 int res = 0;
02123
02124 int dataTag = this->getDbTag();
02125
02126 static ID idData(13);
02127
02128 res += theChannel.recvID(dataTag, commitTag, idData);
02129 if (res < 0) {
02130 opserr << "WARNING ShellMITC4::recvSelf() - " << this->getTag() << " failed to receive ID\n";
02131 return res;
02132 }
02133
02134 this->setTag(idData(8));
02135 connectedExternalNodes(0) = idData(9);
02136 connectedExternalNodes(1) = idData(10);
02137 connectedExternalNodes(2) = idData(11);
02138 connectedExternalNodes(3) = idData(12);
02139
02140 static Vector vectData(1);
02141 res += theChannel.recvVector(dataTag, commitTag, vectData);
02142 if (res < 0) {
02143 opserr << "WARNING ShellMITC4::sendSelf() - " << this->getTag() << " failed to send ID\n";
02144 return res;
02145 }
02146
02147 Ktt = vectData(0);
02148
02149 int i;
02150
02151 if (materialPointers[0] == 0) {
02152 for (i = 0; i < 4; i++) {
02153 int matClassTag = idData(i);
02154 int matDbTag = idData(i+4);
02155
02156 materialPointers[i] = theBroker.getNewSection(matClassTag);
02157 if (materialPointers[i] == 0) {
02158 opserr << "ShellMITC4::recvSelf() - Broker could not create NDMaterial of class type" << matClassTag << endln;;
02159 return -1;
02160 }
02161
02162 materialPointers[i]->setDbTag(matDbTag);
02163 res += materialPointers[i]->recvSelf(commitTag, theChannel, theBroker);
02164 if (res < 0) {
02165 opserr << "NLBeamColumn3d::recvSelf() - material " << i <<
02166 "failed to recv itself\n";
02167 return res;
02168 }
02169 }
02170 }
02171
02172 else {
02173 for (i = 0; i < 4; i++) {
02174 int matClassTag = idData(i);
02175 int matDbTag = idData(i+4);
02176
02177
02178 if (materialPointers[i]->getClassTag() != matClassTag) {
02179 delete materialPointers[i];
02180 materialPointers[i] = theBroker.getNewSection(matClassTag);
02181 if (materialPointers[i] == 0) {
02182 opserr << "ShellMITC4::recvSelf() - Broker could not create NDMaterial of class type" << matClassTag << endln;
02183 exit(-1);
02184 }
02185 }
02186
02187 materialPointers[i]->setDbTag(matDbTag);
02188 res += materialPointers[i]->recvSelf(commitTag, theChannel, theBroker);
02189 if (res < 0) {
02190 opserr << "ShellMITC4::recvSelf() - material " << i << "failed to recv itself\n";
02191 return res;
02192 }
02193 }
02194 }
02195
02196 return res;
02197 }
02198
02199
02200 int
02201 ShellMITC4::displaySelf(Renderer &theViewer, int displayMode, float fact)
02202 {
02203
02204
02205
02206 const Vector &end1Crd = nodePointers[0]->getCrds();
02207 const Vector &end2Crd = nodePointers[1]->getCrds();
02208 const Vector &end3Crd = nodePointers[2]->getCrds();
02209 const Vector &end4Crd = nodePointers[3]->getCrds();
02210
02211 static Matrix coords(4,3);
02212 static Vector values(4);
02213 static Vector P(24) ;
02214
02215 for (int j=0; j<4; j++)
02216 values(j) = 0.0;
02217
02218 if (displayMode >= 0) {
02219 const Vector &end1Disp = nodePointers[0]->getDisp();
02220 const Vector &end2Disp = nodePointers[1]->getDisp();
02221 const Vector &end3Disp = nodePointers[2]->getDisp();
02222 const Vector &end4Disp = nodePointers[3]->getDisp();
02223
02224 if (displayMode < 8 && displayMode > 0) {
02225 for (int i=0; i<4; i++) {
02226 const Vector &stress = materialPointers[i]->getStressResultant();
02227 values(i) = stress(displayMode-1);
02228 }
02229 }
02230
02231 for (int i = 0; i < 3; i++) {
02232 coords(0,i) = end1Crd(i) + end1Disp(i)*fact;
02233 coords(1,i) = end2Crd(i) + end2Disp(i)*fact;
02234 coords(2,i) = end3Crd(i) + end3Disp(i)*fact;
02235 coords(3,i) = end4Crd(i) + end4Disp(i)*fact;
02236
02237 }
02238 } else {
02239 int mode = displayMode * -1;
02240 const Matrix &eigen1 = nodePointers[0]->getEigenvectors();
02241 const Matrix &eigen2 = nodePointers[1]->getEigenvectors();
02242 const Matrix &eigen3 = nodePointers[2]->getEigenvectors();
02243 const Matrix &eigen4 = nodePointers[3]->getEigenvectors();
02244 if (eigen1.noCols() >= mode) {
02245 for (int i = 0; i < 3; i++) {
02246 coords(0,i) = end1Crd(i) + eigen1(i,mode-1)*fact;
02247 coords(1,i) = end2Crd(i) + eigen2(i,mode-1)*fact;
02248 coords(2,i) = end3Crd(i) + eigen3(i,mode-1)*fact;
02249 coords(3,i) = end4Crd(i) + eigen4(i,mode-1)*fact;
02250 }
02251 } else {
02252 for (int i = 0; i < 3; i++) {
02253 coords(0,i) = end1Crd(i);
02254 coords(1,i) = end2Crd(i);
02255 coords(2,i) = end3Crd(i);
02256 coords(3,i) = end4Crd(i);
02257 }
02258 }
02259 }
02260
02261
02262 int error = 0;
02263
02264
02265 error += theViewer.drawPolygon (coords, values);
02266
02267 return error;
02268 }