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 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <math.h>
00028
00029 #include <ID.h>
00030 #include <Vector.h>
00031 #include <Matrix.h>
00032 #include <Element.h>
00033 #include <Node.h>
00034 #include <NDMaterial.h>
00035 #include <Domain.h>
00036 #include <ErrorHandler.h>
00037 #include <EnhancedQuad.h>
00038 #include <Renderer.h>
00039 #include <ElementResponse.h>
00040 #include <Channel.h>
00041 #include <FEM_ObjectBroker.h>
00042
00043
00044
00045 double EnhancedQuad::xl[2][4] ;
00046 Matrix EnhancedQuad::stiff(8,8) ;
00047 Vector EnhancedQuad::resid(8) ;
00048 Matrix EnhancedQuad::mass(8,8) ;
00049
00050 double EnhancedQuad::stressData[3][4] ;
00051 double EnhancedQuad::tangentData[3][3][4] ;
00052
00053
00054
00055 const double EnhancedQuad::root3 = sqrt(3.0) ;
00056 const double EnhancedQuad::one_over_root3 = 1.0 / root3 ;
00057
00058 const double EnhancedQuad::sg[] = { -one_over_root3,
00059 one_over_root3,
00060 one_over_root3,
00061 -one_over_root3 } ;
00062
00063 const double EnhancedQuad::tg[] = { -one_over_root3,
00064 -one_over_root3,
00065 one_over_root3,
00066 one_over_root3 } ;
00067
00068 const double EnhancedQuad::wg[] = { 1.0, 1.0, 1.0, 1.0 } ;
00069
00070
00071
00072
00073 EnhancedQuad::EnhancedQuad( ) :
00074 Element( 0, ELE_TAG_EnhancedQuad ),
00075 connectedExternalNodes(4),
00076 alpha(4) , load(0), Ki(0)
00077 {
00078 for ( int i = 0 ; i < 4; i++ ) {
00079 materialPointers[i] = 0;
00080 }
00081
00082
00083 alpha.Zero( ) ;
00084 }
00085
00086
00087
00088 EnhancedQuad::EnhancedQuad( int tag,
00089 int node1,
00090 int node2,
00091 int node3,
00092 int node4,
00093 NDMaterial &theMaterial,
00094 const char *type )
00095 :
00096 Element( tag, ELE_TAG_EnhancedQuad ),
00097 connectedExternalNodes(4),
00098 alpha(4), load(0), Ki(0)
00099 {
00100
00101 connectedExternalNodes(0) = node1 ;
00102 connectedExternalNodes(1) = node2 ;
00103 connectedExternalNodes(2) = node3 ;
00104 connectedExternalNodes(3) = node4 ;
00105
00106 if (strcmp(type,"PlaneStrain") != 0 && strcmp(type,"PlaneStress") != 0
00107 && strcmp(type,"PlaneStrain2D") != 0 && strcmp(type,"PlaneStress2D") != 0) {
00108 opserr << "EnhancedQuad::EnhancedQuad -- improper material type " << type << " for EnhancedQuad\n";
00109 exit(-1);
00110 }
00111
00112 int i ;
00113 for ( i = 0 ; i < 4; i++ ) {
00114
00115 materialPointers[i] = theMaterial.getCopy(type) ;
00116
00117 if (materialPointers[i] == 0) {
00118 opserr << "EnhancedQuad::EnhancedQuad -- failed to get a material of type " << type << endln;
00119 exit(-1);
00120 }
00121
00122 }
00123
00124
00125 alpha.Zero( ) ;
00126
00127 }
00128
00129
00130
00131 EnhancedQuad::~EnhancedQuad( )
00132 {
00133 int i ;
00134 for ( i = 0 ; i < 4; i++ )
00135 if (materialPointers[i] != 0)
00136 delete materialPointers[i] ;
00137
00138 if (load != 0)
00139 delete load;
00140
00141 if (Ki != 0)
00142 delete Ki;
00143 }
00144
00145
00146
00147 void EnhancedQuad::setDomain( Domain *theDomain )
00148 {
00149
00150 int i ;
00151
00152
00153 for ( i = 0; i < 4; i++ )
00154 nodePointers[i] = theDomain->getNode( connectedExternalNodes(i) ) ;
00155
00156 this->DomainComponent::setDomain(theDomain) ;
00157 }
00158
00159
00160
00161 int EnhancedQuad::getNumExternalNodes( ) const
00162 {
00163 return 4 ;
00164 }
00165
00166
00167
00168 const ID& EnhancedQuad::getExternalNodes( )
00169 {
00170 return connectedExternalNodes ;
00171 }
00172
00173
00174 Node **
00175 EnhancedQuad::getNodePtrs(void)
00176 {
00177 return nodePointers;
00178 }
00179
00180
00181 int EnhancedQuad::getNumDOF( )
00182 {
00183 return 8 ;
00184 }
00185
00186
00187
00188 int EnhancedQuad::commitState( )
00189 {
00190 int success = 0 ;
00191
00192
00193 if ((success = this->Element::commitState()) != 0) {
00194 opserr << "EnhancedQuad::commitState () - failed in base class";
00195 }
00196
00197 for (int i = 0; i < 4; i++ )
00198 success += materialPointers[i]->commitState( ) ;
00199
00200 return success ;
00201 }
00202
00203
00204
00205
00206 int EnhancedQuad::revertToLastCommit( )
00207 {
00208 int i ;
00209 int success = 0 ;
00210
00211 for ( i = 0; i < 4; i++ )
00212 success += materialPointers[i]->revertToLastCommit( ) ;
00213
00214 return success ;
00215 }
00216
00217
00218
00219 int EnhancedQuad::revertToStart( )
00220 {
00221 int i ;
00222 int success = 0 ;
00223
00224
00225 this->alpha.Zero( ) ;
00226
00227 for ( i = 0; i < 4; i++ )
00228 success += materialPointers[i]->revertToStart( ) ;
00229
00230 return success ;
00231 }
00232
00233
00234 void EnhancedQuad::Print( OPS_Stream &s, int flag )
00235 {
00236 s << endln ;
00237 s << "Enhanced Strain Four Node Quad \n" ;
00238 s << "Element Number: " << this->getTag() << endln ;
00239 s << "Node 1 : " << connectedExternalNodes(0) << endln ;
00240 s << "Node 2 : " << connectedExternalNodes(1) << endln ;
00241 s << "Node 3 : " << connectedExternalNodes(2) << endln ;
00242 s << "Node 4 : " << connectedExternalNodes(3) << endln ;
00243
00244 s << "Material Information : \n " ;
00245 materialPointers[0]->Print( s, flag ) ;
00246
00247 s << endln ;
00248 }
00249
00250
00251 const Matrix& EnhancedQuad::getTangentStiff( )
00252 {
00253 int tang_flag = 1 ;
00254
00255
00256 formResidAndTangent( tang_flag ) ;
00257
00258 return stiff ;
00259 }
00260
00261
00262
00263 const Matrix& EnhancedQuad::getInitialStiff( )
00264 {
00265
00266 if (Ki != 0)
00267 return *Ki;
00268
00269 static const int ndm = 2 ;
00270
00271 static const int ndf = 2 ;
00272
00273 static const int nstress = 3 ;
00274
00275 static const int numberNodes = 4 ;
00276
00277 static const int numberGauss = 4 ;
00278
00279 static const int nShape = 3 ;
00280
00281 static const int nEnhanced = 4 ;
00282
00283 static const int nModes = 2 ;
00284
00285 static const int numberDOF = 8 ;
00286
00287
00288 int i, j, k, p, q ;
00289 int jj, kk ;
00290
00291 static double xsj[numberGauss] ;
00292
00293 static double dvol[numberGauss] ;
00294
00295 static Vector strain(nstress) ;
00296
00297 static double shp[nShape][numberNodes] ;
00298
00299 static double Shape[nShape][numberNodes][numberGauss] ;
00300
00301 static Vector residJ(ndf) ;
00302
00303 static Matrix stiffJK(ndf,ndf) ;
00304
00305 static Matrix stiffKJ(ndf,ndf) ;
00306
00307 static Vector stress(nstress) ;
00308
00309 static Matrix dd(nstress,nstress) ;
00310
00311 static Matrix J0(ndm,ndm) ;
00312
00313 static Matrix J0inv(ndm,ndm) ;
00314
00315
00316 static Matrix Kee(nEnhanced,nEnhanced) ;
00317
00318 static Vector residE(nEnhanced) ;
00319
00320 static Vector Umode(ndf) ;
00321
00322 static Vector dalpha(nEnhanced) ;
00323
00324 static Matrix Kue(numberDOF,nEnhanced) ;
00325
00326 static Matrix Keu(nEnhanced,numberDOF) ;
00327
00328 static Matrix KeeInvKeu(nEnhanced,numberDOF) ;
00329
00330
00331
00332
00333 static Matrix BJ(nstress,ndf) ;
00334
00335 static Matrix BJtran(ndf,nstress) ;
00336
00337 static Matrix BK(nstress,ndf) ;
00338
00339 static Matrix BKtran(ndf,nstress) ;
00340
00341 static Matrix BJtranD(ndf,nstress) ;
00342
00343 static Matrix BKtranD(ndf,nstress) ;
00344
00345
00346
00347
00348 stiff.Zero( ) ;
00349
00350 Kee.Zero( ) ;
00351 residE.Zero( ) ;
00352
00353 Kue.Zero( ) ;
00354 Keu.Zero( ) ;
00355
00356
00357
00358 computeBasis( ) ;
00359
00360
00361 double L1 = 0.0 ;
00362 double L2 = 0.0 ;
00363 computeJacobian( L1, L2, xl, J0, J0inv ) ;
00364
00365
00366 double det ;
00367 for ( i = 0; i < numberGauss; i++ ) {
00368
00369
00370 shape2d( sg[i], tg[i], xl, shp, det ) ;
00371
00372
00373 for ( p = 0; p < nShape; p++ ) {
00374 for ( q = 0; q < numberNodes; q++ )
00375 Shape[p][q][i] = shp[p][q] ;
00376 }
00377
00378
00379 xsj[i] = det ;
00380
00381
00382 dvol[i] = wg[i] * det ;
00383
00384 }
00385
00386 Kee.Zero( ) ;
00387
00388 for ( i = 0; i < numberGauss; i++ ) {
00389
00390
00391 dd = materialPointers[i]->getInitialTangent( ) ;
00392
00393
00394 dd *= dvol[i] ;
00395 saveData( i, stress, dd ) ;
00396 }
00397 Kee.Zero( ) ;
00398 for ( i = 0; i < numberGauss; i++ ) {
00399
00400 for ( p = 0; p < nShape; p++ ) {
00401 for ( q = 0; q < numberNodes; q++ )
00402 shp[p][q] = Shape[p][q][i] ;
00403 }
00404
00405
00406 jj = 0 ;
00407 for ( j = 0; j < nModes; j++ ) {
00408
00409
00410 BJ = computeBenhanced( j, sg[i], tg[i], xsj[i], J0inv ) ;
00411
00412
00413 BJtran = transpose( BJ ) ;
00414
00415
00416 BJtranD.addMatrixProduct(0.0, BJtran, dd, 1.0) ;
00417
00418 kk = 0 ;
00419 for ( k = 0; k < nModes; k++ ) {
00420
00421 BK = computeBenhanced( k, sg[i], tg[i], xsj[i], J0inv ) ;
00422
00423
00424 stiffJK.addMatrixProduct(0.0, BJtranD,BK,1.0) ;
00425
00426 for ( p = 0; p < ndf; p++ ) {
00427 for ( q = 0; q < ndf; q++ )
00428 Kee( jj+p, kk+q ) += stiffJK( p, q ) ;
00429 }
00430
00431 kk += ndf ;
00432 }
00433
00434 jj += ndf ;
00435 }
00436 }
00437
00439 for ( i = 0; i < numberGauss; i++ ) {
00440
00441 for ( p = 0; p < nShape; p++ ) {
00442 for ( q = 0; q < numberNodes; q++ )
00443 shp[p][q] = Shape[p][q][i] ;
00444 }
00445
00446
00447
00448 getData( i, stress, dd ) ;
00449 jj = 0 ;
00450 for ( j = 0; j < numberNodes; j++ ) {
00451
00452 BJ = computeB( j, shp ) ;
00453
00454
00455 BJtran = transpose( BJ ) ;
00456
00457
00458 BJtranD.addMatrixProduct(0.0, BJtran, dd, 1.0) ;
00459
00460
00461 kk = 0 ;
00462 for ( k = 0; k < numberNodes; k++ ) {
00463
00464 BK = computeB( k, shp ) ;
00465
00466
00467 stiffJK.addMatrixProduct(0.0, BJtranD, BK,1.0) ;
00468
00469 for ( p = 0; p < ndf; p++ ) {
00470 for ( q = 0; q < ndf; q++ )
00471 stiff( jj+p, kk+q ) += stiffJK( p, q ) ;
00472 }
00473
00474 kk += ndf ;
00475 }
00476
00477
00478
00479 kk = 0 ;
00480 for ( k = 0; k < nModes; k++ ) {
00481
00482 BK = computeBenhanced( k, sg[i], tg[i], xsj[i], J0inv ) ;
00483
00484
00485 stiffJK.addMatrixProduct(0.0, BJtranD,BK,1.0) ;
00486
00487 for ( p = 0; p < ndf; p++ ) {
00488 for ( q = 0; q < ndf; q++ )
00489 Kue( jj+p, kk+q ) += stiffJK( p, q ) ;
00490 }
00491
00492 kk += ndf ;
00493 }
00494
00495
00496 kk = 0 ;
00497 for ( k = 0; k < nModes; k++ ) {
00498
00499 BK = computeBenhanced( k, sg[i], tg[i], xsj[i], J0inv ) ;
00500
00501
00502 BKtran = transpose( BK ) ;
00503
00504
00505 BKtranD.addMatrixProduct(0.0, BKtran,dd,1.0 ) ;
00506
00507
00508 stiffKJ.addMatrixProduct(0.0, BKtranD,BJ,1.0) ;
00509
00510 for ( p = 0; p < ndf; p++ ) {
00511 for ( q = 0; q < ndf; q++ )
00512 Keu( kk+p, jj+q ) += stiffKJ( p, q ) ;
00513 }
00514
00515 kk += ndf ;
00516 }
00517
00518 jj += ndf ;
00519 }
00520
00521
00522 }
00523
00524
00525 Kee.Solve( Keu, KeeInvKeu ) ;
00526
00527
00528 stiff.addMatrixProduct(1.0, Kue, KeeInvKeu, -1.0);
00529
00530 Ki = new Matrix(stiff);
00531
00532 return stiff;
00533 }
00534
00535
00536
00537
00538 const Matrix& EnhancedQuad::getMass( )
00539 {
00540
00541 int tangFlag = 1 ;
00542
00543 formInertiaTerms( tangFlag ) ;
00544
00545 return mass ;
00546
00547 }
00548
00549
00550
00551 void EnhancedQuad::zeroLoad( )
00552 {
00553 if (load != 0)
00554 load->Zero();
00555
00556 return ;
00557 }
00558
00559
00560 int
00561 EnhancedQuad::addLoad(ElementalLoad *theLoad, double loadFactor)
00562 {
00563 opserr << "EnhancedQuad::addLoad - load type unknown for ele with tag: " << this->getTag() << endln;
00564 return -1;
00565 }
00566
00567 int
00568 EnhancedQuad::addInertiaLoadToUnbalance(const Vector &accel)
00569 {
00570 static const int numberGauss = 4 ;
00571 static const int numberNodes = 4 ;
00572 static const int ndf = 2 ;
00573
00574 int i;
00575
00576
00577 int haveRho = 0;
00578 for (i = 0; i < numberGauss; i++) {
00579 if (materialPointers[i]->getRho() != 0.0)
00580 haveRho = 1;
00581 }
00582
00583 if (haveRho == 0)
00584 return 0;
00585
00586
00587 int tangFlag = 1 ;
00588 formInertiaTerms( tangFlag ) ;
00589
00590
00591 int count = 0;
00592 for (i=0; i<numberNodes; i++) {
00593 const Vector &Raccel = nodePointers[i]->getRV(accel);
00594 for (int j=0; j<ndf; j++)
00595 resid(count++) = Raccel(i);
00596 }
00597
00598
00599 if (load == 0)
00600 load = new Vector(numberNodes*ndf);
00601
00602
00603 load->addMatrixVector(1.0, mass, resid, -1.0);
00604
00605 return 0;
00606 }
00607
00608
00609
00610 const Vector& EnhancedQuad::getResistingForce( )
00611 {
00612 int tang_flag = 0 ;
00613
00614 formResidAndTangent( tang_flag ) ;
00615
00616
00617 if (load != 0)
00618 resid -= *load;
00619
00620 return resid ;
00621 }
00622
00623
00624
00625 const Vector& EnhancedQuad::getResistingForceIncInertia( )
00626 {
00627 int tang_flag = 0 ;
00628
00629 static Vector res(8);
00630
00631
00632 formResidAndTangent( tang_flag ) ;
00633
00634
00635 formInertiaTerms( tang_flag ) ;
00636
00637 res = resid;
00638
00639
00640 if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0)
00641 res += this->getRayleighDampingForces();
00642
00643
00644 if (load != 0)
00645 res -= *load;
00646
00647 return res;
00648 }
00649
00650
00651
00652
00653
00654 void EnhancedQuad::formInertiaTerms( int tangFlag )
00655 {
00656
00657 static const int ndf = 2 ;
00658
00659 static const int numberNodes = 4 ;
00660
00661 static const int numberGauss = 4 ;
00662
00663 static const int nShape = 3 ;
00664
00665 static const int massIndex = nShape - 1 ;
00666
00667 double xsj ;
00668
00669 double dvol ;
00670
00671 static double shp[nShape][numberNodes] ;
00672
00673 static Vector momentum(ndf) ;
00674
00675 int i, j, k, p ;
00676 int jj, kk ;
00677
00678 double temp, rho, massJK ;
00679
00680
00681
00682 mass.Zero( ) ;
00683
00684
00685 computeBasis( ) ;
00686
00687
00688 for ( i = 0; i < numberGauss; i++ ) {
00689
00690
00691 shape2d( sg[i], tg[i], xl, shp, xsj ) ;
00692
00693
00694 dvol = wg[i] * xsj ;
00695
00696
00697 momentum.Zero( ) ;
00698 for ( j = 0; j < numberNodes; j++ )
00699
00700 momentum.addVector( 1.0,
00701 nodePointers[j]->getTrialAccel(),
00702 shp[massIndex][j] ) ;
00703
00704
00705 rho = materialPointers[i]->getRho() ;
00706
00707
00708 momentum *= rho ;
00709
00710
00711
00712 jj = 0 ;
00713 for ( j = 0; j < numberNodes; j++ ) {
00714
00715 temp = shp[massIndex][j] * dvol ;
00716
00717 for ( p = 0; p < ndf; p++ )
00718 resid( jj+p ) += ( temp * momentum(p) ) ;
00719
00720
00721 if ( tangFlag == 1 ) {
00722
00723
00724 temp *= rho ;
00725
00726
00727 kk = 0 ;
00728 for ( k = 0; k < numberNodes; k++ ) {
00729
00730 massJK = temp * shp[massIndex][k] ;
00731
00732 for ( p = 0; p < ndf; p++ )
00733 mass( jj+p, kk+p ) += massJK ;
00734
00735 kk += ndf ;
00736 }
00737
00738 }
00739
00740 jj += ndf ;
00741 }
00742 }
00743 }
00744
00745
00746
00747 void EnhancedQuad::formResidAndTangent( int tang_flag )
00748 {
00749
00750 static const double tolerance = 1.0e-08 ;
00751
00752 static const int nIterations = 10 ;
00753
00754 static const int ndm = 2 ;
00755
00756 static const int ndf = 2 ;
00757
00758 static const int nstress = 3 ;
00759
00760 static const int numberNodes = 4 ;
00761
00762 static const int numberGauss = 4 ;
00763
00764 static const int nShape = 3 ;
00765
00766 static const int nEnhanced = 4 ;
00767
00768 static const int nModes = 2 ;
00769
00770 static const int numberDOF = 8 ;
00771
00772
00773 int i, j, k, p, q ;
00774 int jj, kk ;
00775
00776 int success ;
00777
00778 static double xsj[numberGauss] ;
00779
00780 static double dvol[numberGauss] ;
00781
00782 static Vector strain(nstress) ;
00783
00784 static double shp[nShape][numberNodes] ;
00785
00786 static double Shape[nShape][numberNodes][numberGauss] ;
00787
00788 static Vector residJ(ndf) ;
00789
00790 static Matrix stiffJK(ndf,ndf) ;
00791
00792 static Matrix stiffKJ(ndf,ndf) ;
00793
00794 static Vector stress(nstress) ;
00795
00796 static Matrix dd(nstress,nstress) ;
00797
00798 static Matrix J0(ndm,ndm) ;
00799
00800 static Matrix J0inv(ndm,ndm) ;
00801
00802
00803 static Matrix Kee(nEnhanced,nEnhanced) ;
00804
00805 static Vector residE(nEnhanced) ;
00806
00807 static Vector Umode(ndf) ;
00808
00809 static Vector dalpha(nEnhanced) ;
00810
00811 static Matrix Kue(numberDOF,nEnhanced) ;
00812
00813 static Matrix Keu(nEnhanced,numberDOF) ;
00814
00815 static Matrix KeeInvKeu(nEnhanced,numberDOF) ;
00816
00817
00818
00819
00820 static Matrix BJ(nstress,ndf) ;
00821
00822 static Matrix BJtran(ndf,nstress) ;
00823
00824 static Matrix BK(nstress,ndf) ;
00825
00826 static Matrix BKtran(ndf,nstress) ;
00827
00828 static Matrix BJtranD(ndf,nstress) ;
00829
00830 static Matrix BKtranD(ndf,nstress) ;
00831
00832
00833
00834
00835 stiff.Zero( ) ;
00836 resid.Zero( ) ;
00837
00838 Kee.Zero( ) ;
00839 residE.Zero( ) ;
00840
00841 Kue.Zero( ) ;
00842 Keu.Zero( ) ;
00843
00844
00845
00846 computeBasis( ) ;
00847
00848
00849 double L1 = 0.0 ;
00850 double L2 = 0.0 ;
00851 computeJacobian( L1, L2, xl, J0, J0inv ) ;
00852
00853
00854
00855 double det ;
00856 for ( i = 0; i < numberGauss; i++ ) {
00857
00858
00859 shape2d( sg[i], tg[i], xl, shp, det ) ;
00860
00861
00862 for ( p = 0; p < nShape; p++ ) {
00863 for ( q = 0; q < numberNodes; q++ )
00864 Shape[p][q][i] = shp[p][q] ;
00865 }
00866
00867
00868 xsj[i] = det ;
00869
00870
00871 dvol[i] = wg[i] * det ;
00872
00873 }
00874
00875
00876
00877
00878
00879 int count = 0 ;
00880 do {
00881
00882 residE.Zero( ) ;
00883 Kee.Zero( ) ;
00884
00885
00886 for ( i = 0; i < numberGauss; i++ ) {
00887
00888
00889 for ( p = 0; p < nShape; p++ ) {
00890 for ( q = 0; q < numberNodes; q++ )
00891 shp[p][q] = Shape[p][q][i] ;
00892 }
00893
00894
00895
00896 strain.Zero( ) ;
00897
00898
00899 for ( j = 0; j < numberNodes; j++ ) {
00900
00901
00902 BJ = computeB( j, shp ) ;
00903
00904
00905 const Vector &ul = nodePointers[j]->getTrialDisp( ) ;
00906
00907
00908
00909 strain.addMatrixVector(1.0, BJ, ul, 1.0) ;
00910
00911 }
00912
00913
00914 for ( j = 0; j < nModes; j++ ) {
00915
00916
00917 BJ = computeBenhanced( j, sg[i], tg[i], xsj[i], J0inv ) ;
00918
00919
00920 Umode(0) = this->alpha( 2*j ) ;
00921 Umode(1) = this->alpha( 2*j + 1 ) ;
00922
00923
00924
00925 strain.addMatrixVector(1.0, BJ, Umode, 1.0) ;
00926
00927 }
00928
00929 success = materialPointers[i]->setTrialStrain( strain ) ;
00930
00931
00932 stress = materialPointers[i]->getStress( ) ;
00933
00934
00935 stress *= dvol[i] ;
00936
00937
00938 dd = materialPointers[i]->getTangent( ) ;
00939
00940
00941 dd *= dvol[i] ;
00942
00943
00944 saveData( i, stress, dd ) ;
00945
00946
00947
00948 jj = 0 ;
00949 for ( j = 0; j < nModes; j++ ) {
00950
00951
00952 BJ = computeBenhanced( j, sg[i], tg[i], xsj[i], J0inv ) ;
00953
00954
00955 BJtran = transpose( BJ ) ;
00956
00957
00958
00959
00960
00961 residJ.addMatrixVector(0.0, BJtran,stress,-1.0) ;
00962
00963
00964 for ( p = 0; p < ndf; p++ )
00965 residE( jj+p ) += residJ(p) ;
00966
00967
00968
00969 BJtranD.addMatrixProduct(0.0, BJtran,dd,1.0) ;
00970
00971 kk = 0 ;
00972 for ( k = 0; k < nModes; k++ ) {
00973
00974 BK = computeBenhanced( k, sg[i], tg[i], xsj[i], J0inv ) ;
00975
00976
00977 stiffJK.addMatrixProduct(0.0, BJtranD,BK,1.0) ;
00978
00979 for ( p = 0; p < ndf; p++ ) {
00980 for ( q = 0; q < ndf; q++ )
00981 Kee( jj+p, kk+q ) += stiffJK( p, q ) ;
00982 }
00983
00984 kk += ndf ;
00985 }
00986
00987 jj += ndf ;
00988 }
00989
00990
00991 }
00992
00993
00994
00995
00996 dalpha.Zero( ) ;
00997
00998 Kee.Solve( residE, dalpha ) ;
00999
01000 if (dalpha(0) > 1.0e10) opserr << "dalpha: " << residE << dalpha;
01001
01002 this->alpha += dalpha ;
01003
01004 count++ ;
01005 if ( count > nIterations ) {
01006 opserr << "Exceeded " << nIterations
01007 << " iterations solving for enhanced strain parameters " << endln ;
01008 break ;
01009 }
01010
01011
01012
01013 } while ( residE.Norm() > tolerance || count < 2 ) ;
01014
01015
01016
01017
01018
01019
01020
01021 for ( i = 0; i < numberGauss; i++ ) {
01022
01023
01024 for ( p = 0; p < nShape; p++ ) {
01025 for ( q = 0; q < numberNodes; q++ )
01026 shp[p][q] = Shape[p][q][i] ;
01027 }
01028
01029
01030
01031 getData( i, stress, dd ) ;
01032
01033
01034
01035
01036 jj = 0 ;
01037 for ( j = 0; j < numberNodes; j++ ) {
01038
01039 BJ = computeB( j, shp ) ;
01040
01041
01042 BJtran = transpose( BJ ) ;
01043
01044
01045
01046 residJ.addMatrixVector(0.0, BJtran,stress,1.0) ;
01047
01048 for ( p = 0; p < ndf; p++ )
01049 resid( jj+p ) += residJ(p) ;
01050
01051
01052 if ( tang_flag == 1 ) {
01053
01054
01055 BJtranD.addMatrixProduct(0.0, BJtran,dd,1.0) ;
01056
01057
01058 kk = 0 ;
01059 for ( k = 0; k < numberNodes; k++ ) {
01060
01061 BK = computeB( k, shp ) ;
01062
01063
01064 stiffJK.addMatrixProduct(0.0, BJtranD,BK,1.0) ;
01065
01066 for ( p = 0; p < ndf; p++ ) {
01067 for ( q = 0; q < ndf; q++ )
01068 stiff( jj+p, kk+q ) += stiffJK( p, q ) ;
01069 }
01070
01071 kk += ndf ;
01072 }
01073
01074
01075
01076 kk = 0 ;
01077 for ( k = 0; k < nModes; k++ ) {
01078
01079 BK = computeBenhanced( k, sg[i], tg[i], xsj[i], J0inv ) ;
01080
01081
01082 stiffJK.addMatrixProduct(0.0, BJtranD,BK,1.0) ;
01083
01084 for ( p = 0; p < ndf; p++ ) {
01085 for ( q = 0; q < ndf; q++ )
01086 Kue( jj+p, kk+q ) += stiffJK( p, q ) ;
01087 }
01088
01089 kk += ndf ;
01090 }
01091
01092
01093
01094 kk = 0 ;
01095 for ( k = 0; k < nModes; k++ ) {
01096
01097 BK = computeBenhanced( k, sg[i], tg[i], xsj[i], J0inv ) ;
01098
01099
01100 BKtran = transpose( BK ) ;
01101
01102
01103 BKtranD.addMatrixProduct(0.0, BKtran,dd,1.0 ) ;
01104
01105
01106 stiffKJ.addMatrixProduct(0.0, BKtranD,BJ,1.0) ;
01107
01108 for ( p = 0; p < ndf; p++ ) {
01109 for ( q = 0; q < ndf; q++ )
01110 Keu( kk+p, jj+q ) += stiffKJ( p, q ) ;
01111 }
01112
01113 kk += ndf ;
01114 }
01115
01116
01117
01118 }
01119
01120 jj += ndf ;
01121 }
01122
01123
01124 }
01125
01126
01127
01128
01129 if ( tang_flag == 1 ) {
01130
01131 Kee.Solve( Keu, KeeInvKeu ) ;
01132
01133
01134 stiff.addMatrixProduct(1.0, Kue,KeeInvKeu,-1.0 ) ;
01135
01136 }
01137
01138 return ;
01139 }
01140
01141
01142
01143
01144
01145 int
01146 EnhancedQuad::update(void)
01147 {
01148 return 0;
01149 }
01150
01151
01152
01153 void
01154 EnhancedQuad::saveData(int gp,
01155 const Vector &stress,
01156 const Matrix &tangent )
01157 {
01158
01159 int i, j ;
01160
01161
01162 for ( i=0; i<3; i++ )
01163 stressData[i][gp] = stress(i) ;
01164
01165
01166 for ( i=0; i<3; i++ ) {
01167 for (j=0; j<3; j++ )
01168 tangentData[i][j][gp] = tangent(i,j) ;
01169 }
01170
01171 return ;
01172 }
01173
01174
01175
01176
01177
01178 void EnhancedQuad::getData( int gp,
01179 Vector &stress,
01180 Matrix &tangent )
01181 {
01182
01183 int i, j ;
01184
01185
01186 for ( i=0; i<3; i++ )
01187 stress(i) = stressData[i][gp] ;
01188
01189
01190 for ( i=0; i<3; i++ ) {
01191 for ( j=0; j<3; j++ )
01192 tangent(i,j) = tangentData[i][j][gp] ;
01193 }
01194
01195 return ;
01196
01197 }
01198
01199
01200
01201
01202 void EnhancedQuad::computeBasis( )
01203 {
01204
01205
01206 int i ;
01207 for ( i = 0; i < 4; i++ ) {
01208
01209 const Vector &coorI = nodePointers[i]->getCrds( ) ;
01210
01211 xl[0][i] = coorI(0) ;
01212 xl[1][i] = coorI(1) ;
01213
01214 }
01215
01216 }
01217
01218
01219
01220
01221 const Matrix&
01222 EnhancedQuad::computeB( int node, const double shp[3][4] )
01223 {
01224
01225 static Matrix B(3,2) ;
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237 B.Zero( ) ;
01238
01239 B(0,0) = shp[0][node] ;
01240 B(1,1) = shp[1][node] ;
01241 B(2,0) = shp[1][node] ;
01242 B(2,1) = shp[0][node] ;
01243
01244 return B ;
01245
01246 }
01247
01248
01249
01250
01251 const Matrix&
01252 EnhancedQuad::computeBenhanced( int node,
01253 double L1,
01254 double L2,
01255 double j,
01256 const Matrix &Jinv )
01257 {
01258 static Matrix B(3,2) ;
01259
01260 static double JinvTran[2][2] ;
01261
01262 static double shape[2] ;
01263
01264 static double parameter ;
01265
01266
01267
01268 JinvTran[0][0] = Jinv(0,0) ;
01269 JinvTran[1][1] = Jinv(1,1) ;
01270 JinvTran[0][1] = Jinv(1,0) ;
01271 JinvTran[1][0] = Jinv(0,1) ;
01272
01273
01274
01275 if ( node == 0 ) {
01276
01277
01278 shape[0] = JinvTran[0][0] ;
01279 shape[1] = JinvTran[1][0] ;
01280
01281 parameter = L1 / j ;
01282
01283 }
01284 else if ( node == 1 ) {
01285
01286
01287 shape[0] = JinvTran[0][1] ;
01288 shape[1] = JinvTran[1][1] ;
01289
01290 parameter = L2 / j ;
01291
01292 }
01293
01294 shape[0] *= parameter ;
01295 shape[1] *= parameter ;
01296
01297
01298 B.Zero( ) ;
01299
01300 B(0,0) = shape[0] ;
01301 B(1,1) = shape[1] ;
01302 B(2,0) = shape[1] ;
01303 B(2,1) = shape[0] ;
01304
01305 return B ;
01306
01307 }
01308
01309
01310
01311
01312 void EnhancedQuad::computeJacobian( double L1, double L2,
01313 const double x[2][4],
01314 Matrix &JJ,
01315 Matrix &JJinv )
01316 {
01317 int i, j, k ;
01318
01319 static const double s[] = { -0.5, 0.5, 0.5, -0.5 } ;
01320 static const double t[] = { -0.5, -0.5, 0.5, 0.5 } ;
01321
01322 static double shp[2][4] ;
01323
01324 double ss = L1 ;
01325 double tt = L2 ;
01326
01327 for ( i = 0; i < 4; i++ ) {
01328 shp[0][i] = s[i] * ( 0.5 + t[i]*tt ) ;
01329 shp[1][i] = t[i] * ( 0.5 + s[i]*ss ) ;
01330 }
01331
01332
01333
01334
01335 JJ.Zero( ) ;
01336 for ( i = 0; i < 2; i++ ) {
01337 for ( j = 0; j < 2; j++ ) {
01338
01339 for ( k = 0; k < 4; k++ )
01340 JJ(i,j) += x[i][k] * shp[j][k] ;
01341
01342 }
01343 }
01344
01345 double xsj = JJ(0,0)*JJ(1,1) - JJ(0,1)*JJ(1,0) ;
01346
01347
01348 double jinv = 1.0 / xsj ;
01349 JJinv(0,0) = JJ(1,1) * jinv ;
01350 JJinv(1,1) = JJ(0,0) * jinv ;
01351 JJinv(0,1) = -JJ(0,1) * jinv ;
01352 JJinv(1,0) = -JJ(1,0) * jinv ;
01353
01354 return ;
01355
01356 }
01357
01358
01359
01360
01361 void EnhancedQuad::shape2d( double ss, double tt,
01362 const double x[2][4],
01363 double shp[3][4],
01364 double &xsj )
01365
01366 {
01367
01368 int i, j, k ;
01369
01370 double temp ;
01371
01372 static const double s[] = { -0.5, 0.5, 0.5, -0.5 } ;
01373 static const double t[] = { -0.5, -0.5, 0.5, 0.5 } ;
01374
01375 static Matrix xs(2,2) ;
01376 static Matrix sx(2,2) ;
01377
01378 for ( i = 0; i < 4; i++ ) {
01379 shp[2][i] = ( 0.5 + s[i]*ss )*( 0.5 + t[i]*tt ) ;
01380 shp[0][i] = s[i] * ( 0.5 + t[i]*tt ) ;
01381 shp[1][i] = t[i] * ( 0.5 + s[i]*ss ) ;
01382 }
01383
01384
01385
01386
01387 xs.Zero( ) ;
01388 for ( i = 0; i < 2; i++ ) {
01389 for ( j = 0; j < 2; j++ ) {
01390
01391 for ( k = 0; k < 4; k++ )
01392 xs(i,j) += x[i][k] * shp[j][k] ;
01393
01394 }
01395 }
01396
01397 xsj = xs(0,0)*xs(1,1) - xs(0,1)*xs(1,0) ;
01398
01399
01400
01401 double jinv = 1.0 / xsj ;
01402 sx(0,0) = xs(1,1) * jinv ;
01403 sx(1,1) = xs(0,0) * jinv ;
01404 sx(0,1) = -xs(0,1) * jinv ;
01405 sx(1,0) = -xs(1,0) * jinv ;
01406
01407
01408
01409
01410 for ( i = 0; i < 4; i++ ) {
01411 temp = shp[0][i]*sx(0,0) + shp[1][i]*sx(1,0) ;
01412 shp[1][i] = shp[0][i]*sx(0,1) + shp[1][i]*sx(1,1) ;
01413 shp[0][i] = temp ;
01414 }
01415
01416 return ;
01417 }
01418
01419
01420
01421 const Matrix&
01422 EnhancedQuad::transpose( const Matrix &M )
01423 {
01424 int i ;
01425 int j ;
01426
01427
01428
01429
01430 static int dim1 = 2 ;
01431 static int dim2 = 3 ;
01432 static Matrix Mtran(dim1,dim2) ;
01433
01434 for ( i = 0; i < dim1; i++ ) {
01435 for ( j = 0; j < dim2; j++ )
01436 Mtran(i,j) = M(j,i) ;
01437 }
01438
01439 return Mtran ;
01440 }
01441
01442
01443
01444 Response*
01445 EnhancedQuad::setResponse(const char **argv, int argc,
01446 Information &eleInfo, OPS_Stream &output)
01447 {
01448 Response *theResponse =0;
01449
01450 output.tag("ElementOutput");
01451 output.attr("eleType","EnhancedQuad");
01452 output.attr("eleTag",this->getTag());
01453 output.attr("node1",connectedExternalNodes[0]);
01454 output.attr("node2",connectedExternalNodes[1]);
01455 output.attr("node3",connectedExternalNodes[2]);
01456 output.attr("node4",connectedExternalNodes[3]);
01457
01458 char dataOut[10];
01459 if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0) {
01460
01461 for (int i=1; i<=4; i++) {
01462 sprintf(dataOut,"P1_%d",i);
01463 output.tag("ResponseType",dataOut);
01464 sprintf(dataOut,"P2_%d",i);
01465 output.tag("ResponseType",dataOut);
01466 }
01467
01468 theResponse = new ElementResponse(this, 1, resid);
01469 } else if (strcmp(argv[0],"material") == 0 || strcmp(argv[0],"integrPoint") == 0) {
01470 int pointNum = atoi(argv[1]);
01471 if (pointNum > 0 && pointNum <= 4) {
01472
01473 output.tag("GaussPoint");
01474 output.attr("number",pointNum);
01475 output.attr("eta",sg[pointNum-1]);
01476 output.attr("neta",tg[pointNum-1]);
01477
01478 theResponse = materialPointers[pointNum-1]->setResponse(&argv[2], argc-2, eleInfo, output);
01479
01480 output.endTag();
01481
01482 } else if (strcmp(argv[0],"stresses") ==0) {
01483
01484 for (int i=0; i<4; i++) {
01485 output.tag("GaussPoint");
01486 output.attr("number",i+1);
01487 output.attr("eta",sg[i]);
01488 output.attr("neta",tg[i]);
01489
01490 output.tag("NdMaterialOutput");
01491 output.attr("classType", materialPointers[i]->getClassTag());
01492 output.attr("tag", materialPointers[i]->getTag());
01493
01494 output.tag("ResponseType","sigma11");
01495 output.tag("ResponseType","sigma22");
01496 output.tag("ResponseType","sigma12");
01497
01498 output.endTag();
01499 output.endTag();
01500 }
01501
01502 theResponse = new ElementResponse(this, 3, Vector(12));
01503 }
01504 }
01505
01506 output.endTag();
01507
01508 return theResponse;
01509 }
01510
01511 int
01512 EnhancedQuad::getResponse(int responseID, Information &eleInfo)
01513 {
01514 if (responseID == 1) {
01515
01516 return eleInfo.setVector(this->getResistingForce());
01517
01518 } else if (responseID == 3) {
01519
01520
01521 static Vector stresses(12);
01522 int cnt = 0;
01523 for (int i = 0; i < 4; i++) {
01524
01525
01526 const Vector &sigma = materialPointers[i]->getStress();
01527 stresses(cnt) = sigma(0);
01528 stresses(cnt+1) = sigma(1);
01529 stresses(cnt+2) = sigma(2);
01530 cnt += 3;
01531 }
01532 return eleInfo.setVector(resid);
01533
01534 } else
01535
01536 return -1;
01537 }
01538
01539
01540
01541 int EnhancedQuad::sendSelf (int commitTag, Channel &theChannel)
01542 {
01543 int res = 0;
01544
01545
01546
01547
01548 int dataTag = this->getDbTag();
01549
01550
01551
01552
01553
01554 int matDbTag;
01555
01556 static ID idData(13);
01557
01558 idData(12) = this->getTag();
01559
01560 int i;
01561 for (i = 0; i < 4; i++) {
01562 idData(i) = materialPointers[i]->getClassTag();
01563 matDbTag = materialPointers[i]->getDbTag();
01564
01565
01566 if (matDbTag == 0) {
01567 matDbTag = theChannel.getDbTag();
01568 if (matDbTag != 0)
01569 materialPointers[i]->setDbTag(matDbTag);
01570 }
01571 idData(i+4) = matDbTag;
01572 }
01573
01574 idData(8) = connectedExternalNodes(0);
01575 idData(9) = connectedExternalNodes(1);
01576 idData(10) = connectedExternalNodes(2);
01577 idData(11) = connectedExternalNodes(3);
01578
01579 res += theChannel.sendID(dataTag, commitTag, idData);
01580 if (res < 0) {
01581 opserr << "WARNING EnhancedQuad::sendSelf() - " << this->getTag() << " failed to send ID\n";
01582 return res;
01583 }
01584
01585
01586 res += theChannel.sendVector(dataTag, commitTag, alpha);
01587 if (res < 0) {
01588 opserr << "WARNING EnhancedQuad::sendSelf() - " << this->getTag() << " failed to send ID\n";
01589 return res;
01590 }
01591
01592
01593 for (i = 0; i < 4; i++) {
01594 res += materialPointers[i]->sendSelf(commitTag, theChannel);
01595 if (res < 0) {
01596 opserr << "WARNING EnhancedQuad::sendSelf() - " << this->getTag() << " failed to send its Material\n";
01597 return res;
01598 }
01599 }
01600
01601 return res;
01602 }
01603
01604 int EnhancedQuad::recvSelf (int commitTag,
01605 Channel &theChannel,
01606 FEM_ObjectBroker &theBroker)
01607 {
01608 int res = 0;
01609
01610 int dataTag = this->getDbTag();
01611
01612 static ID idData(13);
01613
01614 res += theChannel.recvID(dataTag, commitTag, idData);
01615 if (res < 0) {
01616 opserr << "WARNING EnhancedQuad::recvSelf() - " << this->getTag() << " failed to receive ID\n";
01617 return res;
01618 }
01619
01620 this->setTag(idData(12));
01621
01622 connectedExternalNodes(0) = idData(8);
01623 connectedExternalNodes(1) = idData(9);
01624 connectedExternalNodes(2) = idData(10);
01625 connectedExternalNodes(3) = idData(11);
01626
01627
01628 res += theChannel.recvVector(dataTag, commitTag, alpha);
01629 if (res < 0) {
01630 opserr << "WARNING EnhancedQuad::sendSelf() - " << this->getTag() << " failed to send ID\n";
01631 return res;
01632 }
01633
01634 int i;
01635
01636 if (materialPointers[0] == 0) {
01637 for (i = 0; i < 4; i++) {
01638 int matClassTag = idData(i);
01639 int matDbTag = idData(i+4);
01640
01641 materialPointers[i] = theBroker.getNewNDMaterial(matClassTag);
01642 if (materialPointers[i] == 0) {
01643 opserr << "EnhancedQuad::recvSelf() - Broker could not create NDMaterial of class type " << matClassTag << endln;
01644 return -1;
01645 }
01646
01647 materialPointers[i]->setDbTag(matDbTag);
01648 res += materialPointers[i]->recvSelf(commitTag, theChannel, theBroker);
01649 if (res < 0) {
01650 opserr << "NLBeamColumn3d::recvSelf() - material " << i << "failed to recv itself\n";
01651 return res;
01652 }
01653 }
01654 }
01655
01656
01657 else {
01658 for (i = 0; i < 4; i++) {
01659 int matClassTag = idData(i);
01660 int matDbTag = idData(i+4);
01661
01662
01663 if (materialPointers[i]->getClassTag() != matClassTag) {
01664 delete materialPointers[i];
01665 materialPointers[i] = theBroker.getNewNDMaterial(matClassTag);
01666 if (materialPointers[i] == 0) {
01667 opserr << "EnhancedQuad::recvSelf() - Broker could not create NDMaterial of class type" << matClassTag << endln;
01668 exit(-1);
01669 }
01670 materialPointers[i]->setDbTag(matDbTag);
01671 }
01672
01673
01674 res += materialPointers[i]->recvSelf(commitTag, theChannel, theBroker);
01675 if (res < 0) {
01676 opserr << "EnhancedQuad::recvSelf() - material " << i << "failed to recv itself\n";
01677 return res;
01678 }
01679 }
01680 }
01681
01682 return res;
01683 }
01684
01685
01686 int
01687 EnhancedQuad::displaySelf(Renderer &theViewer, int displayMode, float fact)
01688 {
01689
01690
01691
01692 static Vector values(4) ;
01693
01694 for (int j=0; j<4; j++)
01695 values(j) = 0.0;
01696
01697
01698
01699 if (displayMode < 4 && displayMode > 0) {
01700 for (int i=0; i<4; i++) {
01701 const Vector &stress = materialPointers[i]->getStress();
01702 values(i) = stress(displayMode-1);
01703 }
01704 }
01705
01706
01707
01708
01709
01710 const Vector &end1Crd = nodePointers[0]->getCrds();
01711 const Vector &end2Crd = nodePointers[1]->getCrds();
01712 const Vector &end3Crd = nodePointers[2]->getCrds();
01713 const Vector &end4Crd = nodePointers[3]->getCrds();
01714
01715 static Matrix coords(4,3) ;
01716
01717 if (displayMode >= 0) {
01718
01719 const Vector &end1Disp = nodePointers[0]->getDisp();
01720 const Vector &end2Disp = nodePointers[1]->getDisp();
01721 const Vector &end3Disp = nodePointers[2]->getDisp();
01722 const Vector &end4Disp = nodePointers[3]->getDisp();
01723
01724 for (int i = 0; i < 2; i++) {
01725 coords(0,i) = end1Crd(i) + end1Disp(i)*fact;
01726 coords(1,i) = end2Crd(i) + end2Disp(i)*fact;
01727 coords(2,i) = end3Crd(i) + end3Disp(i)*fact;
01728 coords(3,i) = end4Crd(i) + end4Disp(i)*fact;
01729 }
01730 } else {
01731 int mode = displayMode * -1;
01732 const Matrix &eigen1 = nodePointers[0]->getEigenvectors();
01733 const Matrix &eigen2 = nodePointers[1]->getEigenvectors();
01734 const Matrix &eigen3 = nodePointers[2]->getEigenvectors();
01735 const Matrix &eigen4 = nodePointers[3]->getEigenvectors();
01736 if (eigen1.noCols() >= mode) {
01737 for (int i = 0; i < 2; i++) {
01738 coords(0,i) = end1Crd(i) + eigen1(i,mode-1)*fact;
01739 coords(1,i) = end2Crd(i) + eigen2(i,mode-1)*fact;
01740 coords(2,i) = end3Crd(i) + eigen3(i,mode-1)*fact;
01741 coords(3,i) = end4Crd(i) + eigen4(i,mode-1)*fact;
01742 }
01743 } else {
01744 for (int i = 0; i < 2; i++) {
01745 coords(0,i) = end1Crd(i);
01746 coords(1,i) = end2Crd(i);
01747 coords(2,i) = end3Crd(i);
01748 coords(3,i) = end4Crd(i);
01749 }
01750 }
01751 }
01752
01753 int error = 0;
01754
01755
01756 error += theViewer.drawPolygon (coords, values);
01757
01758 return error;
01759 }
01760