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 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <math.h>
00030
00031 #include <ID.h>
00032 #include <Vector.h>
00033 #include <Matrix.h>
00034 #include <Element.h>
00035 #include <Node.h>
00036 #include <Domain.h>
00037 #include <ErrorHandler.h>
00038 #include <Twenty_Node_Brick.h>
00039 #include <shp3d.h>
00040 #include <shp3dv.h>
00041 #include <Renderer.h>
00042 #include <ElementResponse.h>
00043
00044
00045 #include <Channel.h>
00046 #include <FEM_ObjectBroker.h>
00047
00048
00049 double Twenty_Node_Brick::xl[3][20] ;
00050
00051 Matrix Twenty_Node_Brick::stiff(60,60) ;
00052 Vector Twenty_Node_Brick::resid(60) ;
00053 Matrix Twenty_Node_Brick::mass(60,60) ;
00054 Matrix Twenty_Node_Brick::damp(60,60) ;
00055
00056 const int Twenty_Node_Brick::nintu=27;
00057 const int Twenty_Node_Brick::nenu=20;
00058 double Twenty_Node_Brick::shgu[4][20][27];
00059 double Twenty_Node_Brick::shlu[4][20][27];
00060 double Twenty_Node_Brick::wu[27];
00061 double Twenty_Node_Brick::dvolu[27];
00062
00063
00064 Twenty_Node_Brick::Twenty_Node_Brick( ) :
00065 Element( 0, ELE_TAG_Twenty_Node_Brick ),
00066 connectedExternalNodes(20), load(0), Ki(0)
00067 {
00068 for (int i=0; i<20; i++ ) {
00069 nodePointers[i] = 0;
00070 }
00071 b[0] = b[1] = b[2] = 0.;
00072
00073
00074 compuLocalShapeFunction();
00075 }
00076
00077
00078
00079
00080 Twenty_Node_Brick::Twenty_Node_Brick(int tag,
00081 int node1,
00082 int node2,
00083 int node3,
00084 int node4,
00085 int node5,
00086 int node6,
00087 int node7,
00088 int node8,
00089 int node9,
00090 int node10,
00091 int node11,
00092 int node12,
00093 int node13,
00094 int node14,
00095 int node15,
00096 int node16,
00097 int node17,
00098 int node18,
00099 int node19,
00100 int node20,
00101 NDMaterial &theMaterial,
00102 double b1, double b2, double b3) :
00103 Element( tag, ELE_TAG_Twenty_Node_Brick ),
00104 connectedExternalNodes(20), load(0), Ki(0)
00105 {
00106 connectedExternalNodes(0) = node1 ;
00107 connectedExternalNodes(1) = node2 ;
00108 connectedExternalNodes(2) = node3 ;
00109 connectedExternalNodes(3) = node4 ;
00110 connectedExternalNodes(4) = node5 ;
00111 connectedExternalNodes(5) = node6 ;
00112 connectedExternalNodes(6) = node7 ;
00113 connectedExternalNodes(7) = node8 ;
00114 connectedExternalNodes(8) = node9 ;
00115 connectedExternalNodes(9) = node10 ;
00116 connectedExternalNodes(10) = node11 ;
00117 connectedExternalNodes(11) = node12 ;
00118 connectedExternalNodes(12) = node13 ;
00119 connectedExternalNodes(13) = node14 ;
00120 connectedExternalNodes(14) = node15 ;
00121 connectedExternalNodes(15) = node16 ;
00122 connectedExternalNodes(16) = node17 ;
00123 connectedExternalNodes(17) = node18 ;
00124 connectedExternalNodes(18) = node19 ;
00125 connectedExternalNodes(19) = node20 ;
00126 int i ;
00127
00128 materialPointers = new NDMaterial *[nintu];
00129
00130 if (materialPointers == 0) {
00131 opserr << "Twenty_Node_Brick::Twenty_Node_Brick - failed allocate material model pointer\n";
00132 exit(-1);
00133 }
00134 for ( i=0; i<nintu; i++ ) {
00135
00136 materialPointers[i] = theMaterial.getCopy("ThreeDimensional") ;
00137
00138 if (materialPointers[i] == 0) {
00139 opserr <<"Twenty_Node_Brick::constructor - failed to get a material of type: ThreeDimensional\n";
00140 exit(-1);
00141 }
00142
00143 }
00144
00145
00146 b[0] = b1;
00147 b[1] = b2;
00148 b[2] = b3;
00149
00150
00151 compuLocalShapeFunction();
00152
00153 }
00154
00155
00156
00157
00158 Twenty_Node_Brick::~Twenty_Node_Brick( )
00159 {
00160 int i ;
00161 for ( i = 0; i < nintu; i++) {
00162 if (materialPointers[i])
00163 delete materialPointers[i];
00164 }
00165
00166
00167 if (materialPointers)
00168 delete [] materialPointers;
00169
00170 for ( i=0 ; i<nenu; i++ ) {
00171 nodePointers[i] = 0 ;
00172 }
00173
00174 if (load != 0)
00175 delete load;
00176
00177 if (Ki != 0)
00178 delete Ki;
00179 }
00180
00181
00182
00183 void Twenty_Node_Brick::setDomain( Domain *theDomain )
00184 {
00185 int i,dof ;
00186
00187 if (theDomain == 0) {
00188 for ( i=0; i<nenu; i++ )
00189 nodePointers[i] = 0;
00190 return;
00191 }
00192
00193 for ( i=0; i<nenu; i++ ) {
00194 nodePointers[i] = theDomain->getNode( connectedExternalNodes(i) ) ;
00195 if (nodePointers[i] == 0) {
00196 opserr << "FATAL ERROR Twenty_Node_Brick ("<<this->getTag()<<"): node not found in domain"<<endln;
00197 return;
00198 }
00199
00200 dof = nodePointers[i]->getNumberDOF();
00201 if( dof != 3 ) {
00202 opserr << "FATAL ERROR Twenty_Node_Brick ("<<this->getTag()<<"): has wrong number of DOFs at its nodes"<<endln;
00203 return;
00204 }
00205 }
00206 this->DomainComponent::setDomain(theDomain);
00207 }
00208
00209
00210
00211 int Twenty_Node_Brick::getNumExternalNodes( ) const
00212 {
00213 return nenu ;
00214 }
00215
00216
00217
00218 const ID& Twenty_Node_Brick::getExternalNodes( )
00219 {
00220 return connectedExternalNodes ;
00221 }
00222
00223
00224 Node **
00225 Twenty_Node_Brick::getNodePtrs(void)
00226 {
00227 return nodePointers ;
00228 }
00229
00230
00231
00232 int Twenty_Node_Brick::getNumDOF( )
00233 {
00234 return 60 ;
00235 }
00236
00237
00238
00239 int Twenty_Node_Brick::commitState( )
00240 {
00241 int success = 0 ;
00242
00243
00244 if ((success = this->Element::commitState()) != 0) {
00245 opserr << "Twenty_Node_Brick::commitState () - failed in base class";
00246 }
00247
00248 for (int i=0; i<nintu; i++ )
00249 success += materialPointers[i]->commitState( ) ;
00250
00251 return success ;
00252 }
00253
00254
00255
00256
00257 int Twenty_Node_Brick::revertToLastCommit( )
00258 {
00259 int i ;
00260 int success = 0 ;
00261
00262 for ( i=0; i<nintu; i++ )
00263 success += materialPointers[i]->revertToLastCommit( ) ;
00264
00265 return success ;
00266 }
00267
00268
00269
00270 int Twenty_Node_Brick::revertToStart( )
00271 {
00272 int success = 0 ;
00273
00274 for (int i=0; i<nintu; i++)
00275 success += materialPointers[i]->revertToStart( ) ;
00276
00277
00278 return success ;
00279 }
00280
00281
00282 void Twenty_Node_Brick::Print( OPS_Stream &s, int flag )
00283 {
00284
00285 if (flag == 2) {
00286
00287 s << "#20NodeBrick\n";
00288
00289 int i;
00290 const int numNodes = 20;
00291 const int nstress = 6 ;
00292
00293 for (i=0; i<numNodes; i++) {
00294 const Vector &nodeCrd = nodePointers[i]->getCrds();
00295 const Vector &nodeDisp = nodePointers[i]->getDisp();
00296 s << "#NODE " << nodeCrd(0) << " " << nodeCrd(1) << " " << nodeCrd(2)
00297 << " " << nodeDisp(0) << " " << nodeDisp(1) << " " << nodeDisp(2) << endln;
00298 }
00299
00300
00301 const int numMaterials = nintu;
00302
00303 static Vector avgStress(7);
00304 static Vector avgStrain(nstress);
00305 avgStress.Zero();
00306 avgStrain.Zero();
00307 for (i=0; i<numMaterials; i++) {
00308 avgStress += materialPointers[i]->getCommittedStress();
00309 avgStrain += materialPointers[i]->getCommittedStrain();
00310 }
00311 avgStress /= numMaterials;
00312 avgStrain /= numMaterials;
00313
00314 s << "#AVERAGE_STRESS ";
00315 for (i=0; i<7; i++)
00316 s << avgStress(i) << " " ;
00317 s << endln;
00318
00319 s << "#AVERAGE_STRAIN ";
00320 for (i=0; i<nstress; i++)
00321 s << avgStrain(i) << " " ;
00322 s << endln;
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332 } else {
00333
00334 s << endln ;
00335 s << "20NodeBrick Twenty_Node_Brick \n" ;
00336 s << "Element Number: " << this->getTag() << endln ;
00337 s << "Node 1 : " << connectedExternalNodes(0) << endln ;
00338 s << "Node 2 : " << connectedExternalNodes(1) << endln ;
00339 s << "Node 3 : " << connectedExternalNodes(2) << endln ;
00340 s << "Node 4 : " << connectedExternalNodes(3) << endln ;
00341 s << "Node 5 : " << connectedExternalNodes(4) << endln ;
00342 s << "Node 6 : " << connectedExternalNodes(5) << endln ;
00343 s << "Node 7 : " << connectedExternalNodes(6) << endln ;
00344 s << "Node 8 : " << connectedExternalNodes(7) << endln ;
00345 s << "Node 9 : " << connectedExternalNodes(8) << endln ;
00346 s << "Node 10 : " << connectedExternalNodes(9) << endln ;
00347 s << "Node 11 : " << connectedExternalNodes(10) << endln ;
00348 s << "Node 12 : " << connectedExternalNodes(11) << endln ;
00349 s << "Node 13 : " << connectedExternalNodes(12) << endln ;
00350 s << "Node 14 : " << connectedExternalNodes(13) << endln ;
00351 s << "Node 15 : " << connectedExternalNodes(14) << endln ;
00352 s << "Node 16 : " << connectedExternalNodes(15) << endln ;
00353 s << "Node 17 : " << connectedExternalNodes(16) << endln ;
00354 s << "Node 18 : " << connectedExternalNodes(17) << endln ;
00355 s << "Node 19 : " << connectedExternalNodes(18) << endln ;
00356 s << "Node 20 : " << connectedExternalNodes(19) << endln ;
00357
00358 s << "Material Information : \n " ;
00359 materialPointers[0]->Print( s, flag ) ;
00360
00361 s << endln ;
00362 }
00363 }
00364
00365 int
00366 Twenty_Node_Brick::update()
00367 {
00368 int i, j, k, k1;
00369 static double u[3][20];
00370 static double xsj;
00371 static Matrix B(6, 3);
00372 double volume = 0.;
00373
00374 for (i = 0; i < nenu; i++) {
00375 const Vector &disp = nodePointers[i]->getTrialDisp();
00376 u[0][i] = disp(0);
00377 u[1][i] = disp(1);
00378 u[2][i] = disp(2);
00379 }
00380
00381 static Vector eps(6);
00382
00383 int ret = 0;
00384
00385
00386 computeBasis( ) ;
00387
00388 for( i = 0; i < nintu; i++ ) {
00389
00390 Jacobian3d(i, xsj, 0);
00391
00392 dvolu[i] = wu[i] * xsj ;
00393 volume += dvolu[i];
00394 }
00395
00396
00397
00398 for (i = 0; i < nintu; i++) {
00399
00400
00401
00402
00403 eps.Zero();
00404 for ( j = 0; j < nenu; j++) {
00405
00406
00407 B(0,0) = shgu[0][j][i];
00408 B(0,1) = 0.;
00409 B(0,2) = 0.;
00410 B(1,0) = 0.;
00411 B(1,1) = shgu[1][j][i];
00412 B(1,2) = 0.;
00413 B(2,0) = 0.;
00414 B(2,1) = 0.;
00415 B(2,2) = shgu[2][j][i];
00416 B(3,0) = shgu[1][j][i];
00417 B(3,1) = shgu[0][j][i];
00418 B(3,2) = 0.;
00419 B(4,0) = 0.;
00420 B(4,1) = shgu[2][j][i];
00421 B(4,2) = shgu[1][j][i];
00422 B(5,0) = shgu[2][j][i];
00423 B(5,1) = 0.;
00424 B(5,2) = shgu[0][j][i];
00425
00426
00427
00428
00429 const Vector &ul = nodePointers[j]->getTrialDisp( ) ;
00430 Vector ul3(3);
00431 ul3(0) = ul(0);
00432 ul3(1) = ul(1);
00433 ul3(2) = ul(2);
00434
00435
00436 eps.addMatrixVector(1.0,B,ul3,1.0 ) ;
00437
00438
00439
00440
00441
00442
00443
00444
00445 }
00446
00447
00448 ret += materialPointers[i]->setTrialStrain(eps);
00449 }
00450
00451 return ret;
00452 }
00453
00454
00455
00456
00457 const Matrix& Twenty_Node_Brick::getTangentStiff( )
00458
00459 {
00460
00461 return getStiff( 1 );
00462
00463 }
00464
00465
00466
00467
00468
00469 const Matrix& Twenty_Node_Brick::getInitialStiff( )
00470
00471 {
00472
00473 return getStiff( 0 );
00474
00475 }
00476
00477
00478
00479
00480
00481 const Matrix& Twenty_Node_Brick::getStiff( int flag )
00482
00483 {
00484
00485 if (flag != 0 && flag != 1) {
00486
00487 opserr << "FATAL Twenty_Node_Brick::getStiff() - illegal use\n";
00488
00489 exit(-1);
00490
00491 }
00492
00493
00494
00495 if (flag == 0 && Ki != 0)
00496
00497 return *Ki;
00498
00499
00500
00501 int i, j ;
00502
00503
00504
00505 static double xsj ;
00506
00507 double volume = 0.;
00508
00509
00510
00511 int j3, j3m1, j3m2, ik, ib, jk, jb;
00512
00513 static Matrix B(6,nenu*3);
00514
00515 static Matrix BTDB(nenu*3,nenu*3);
00516
00517 static Matrix D(6, 6);
00518
00519 B.Zero();
00520
00521 BTDB.Zero();
00522
00523 stiff.Zero();
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533 computeBasis( ) ;
00534
00535
00536
00537 for( i = 0; i < nintu; i++ ) {
00538
00539
00540
00541 Jacobian3d(i, xsj, 0);
00542
00543
00544
00545 dvolu[i] = wu[i] * xsj ;
00546
00547 volume += dvolu[i];
00548
00549 }
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573 for (i = 0; i < nintu; i++) {
00574
00575
00576
00577
00578
00579 if( flag == 0 )
00580
00581 D = materialPointers[i]->getInitialTangent();
00582
00583 else
00584
00585 D = materialPointers[i]->getTangent();
00586
00587
00588
00589
00590
00591
00592
00593 for (j=0; j<nenu; j++) {
00594
00595
00596
00597 j3 = 3*j+2;
00598
00599 j3m1 = j3 - 1;
00600
00601 j3m2 = j3 - 2;
00602
00603
00604
00605 B(0,j3m2) = shgu[0][j][i];
00606
00607 B(0,j3m1) = 0.;
00608
00609 B(0,j3 ) = 0.;
00610
00611
00612
00613 B(1,j3m2) = 0.;
00614
00615 B(1,j3m1) = shgu[1][j][i];
00616
00617 B(1,j3 ) = 0.;
00618
00619
00620
00621 B(2,j3m2) = 0.;
00622
00623 B(2,j3m1) = 0.;
00624
00625 B(2,j3 ) = shgu[2][j][i];
00626
00627
00628
00629 B(3,j3m2) = shgu[1][j][i];
00630
00631 B(3,j3m1) = shgu[0][j][i];
00632
00633 B(3,j3 ) = 0.;
00634
00635
00636
00637 B(4,j3m2) = 0.;
00638
00639 B(4,j3m1) = shgu[2][j][i];
00640
00641 B(4,j3 ) = shgu[1][j][i];
00642
00643
00644
00645 B(5,j3m2) = shgu[2][j][i];
00646
00647 B(5,j3m1) = 0.;
00648
00649 B(5,j3 ) = shgu[0][j][i];
00650
00651
00652
00653 }
00654
00655
00656
00657
00658
00659
00660
00661 BTDB.addMatrixTripleProduct(1.0, B, D, dvolu[i]);
00662
00663 }
00664
00665 for( i = 0; i < 60; i++)
00666
00667 for( j = 0; j < 60; j++)
00668
00669 stiff(i,j) = BTDB(i,j);
00670
00671
00672
00673 if( flag == 1) {
00674
00675 return stiff;
00676
00677 }
00678
00679 Ki = new Matrix(stiff);
00680
00681 if (Ki == 0) {
00682
00683 opserr << "FATAL Twenty_Node_Brick::getStiff() -";
00684
00685 opserr << "ran out of memory\n";
00686
00687 exit(-1);
00688
00689 }
00690
00691
00692
00693 return *Ki;
00694
00695 }
00696
00697
00698
00699
00700
00701
00702
00703 const Matrix& Twenty_Node_Brick::getMass( )
00704
00705 {
00706
00707 int tangFlag = 1 ;
00708
00709
00710
00711 formInertiaTerms( tangFlag ) ;
00712
00713
00714
00715 return mass ;
00716
00717 }
00718
00719
00720
00721
00722
00723
00724
00725 const Matrix& Twenty_Node_Brick::getDamp( )
00726
00727 {
00728
00729 int tangFlag = 1 ;
00730
00731
00732
00733 formDampingTerms( tangFlag ) ;
00734
00735
00736
00737 return damp ;
00738
00739 }
00740
00741
00742
00743 void Twenty_Node_Brick::formDampingTerms( int tangFlag )
00744
00745 {
00746
00747 static double xsj ;
00748
00749 int i, j, k, m, ik, jk;
00750
00751 double volume = 0.;
00752
00753
00754
00755 damp.Zero( ) ;
00756
00757
00758
00759 if (betaK != 0.0)
00760
00761 damp.addMatrix(1.0, this->getTangentStiff(), betaK);
00762
00763 if (betaK0 != 0.0)
00764
00765 damp.addMatrix(1.0, this->getInitialStiff(), betaK0);
00766
00767 if (betaKc != 0.0)
00768
00769 damp.addMatrix(1.0, *Kc, betaKc);
00770
00771
00772
00773 if (alphaM != 0.0) {
00774
00775 this->getMass();
00776
00777 for( i = 0; i < 60; i++)
00778
00779 for( j = 0; j < 60; j++)
00780
00781 damp(i,j) += mass(i,j) * alphaM;
00782
00783 }
00784
00785
00786
00787 return;
00788
00789
00790
00791 }
00792
00793
00794
00795
00796
00797 void Twenty_Node_Brick::zeroLoad( )
00798
00799 {
00800
00801 if (load != 0)
00802
00803 load->Zero();
00804
00805
00806
00807 return ;
00808
00809 }
00810
00811
00812
00813
00814
00815 int
00816
00817 Twenty_Node_Brick::addLoad(ElementalLoad *theLoad, double loadFactor)
00818
00819 {
00820
00821 opserr << "Twenty_Node_Brick::addLoad - load type unknown for truss with tag: " << this->getTag() << endln;
00822
00823 return -1;
00824
00825 }
00826
00827
00828
00829 int
00830
00831 Twenty_Node_Brick::addInertiaLoadToUnbalance(const Vector &accel)
00832
00833 {
00834
00835 static Vector ra(60);
00836
00837
00838
00839 int i, j, ik;
00840
00841 ra.Zero();
00842
00843
00844
00845 for( i = 0; i < nenu; i++) {
00846
00847 const Vector &Raccel = nodePointers[i]->getRV(accel);
00848
00849 if ( 3 != Raccel.Size() ) {
00850
00851 opserr << "Twenty_Node_Brick::addInertiaLoadToUnbalance matrix and vector sizes are incompatable\n";
00852
00853 return -1;
00854
00855 }
00856
00857 ra[i*3] = Raccel(0);
00858
00859 ra[i*3+1] = Raccel(1);
00860
00861 ra[i*3+2] = Raccel(2);
00862
00863 }
00864
00865
00866
00867
00868
00869 int tangFlag = 1 ;
00870
00871 formInertiaTerms( tangFlag ) ;
00872
00873
00874
00875
00876
00877 if (load == 0)
00878
00879 load = new Vector(60);
00880
00881
00882
00883
00884
00885 load->addMatrixVector(1.0, mass, ra, -1.0);
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897 return 0;
00898
00899 }
00900
00901
00902
00903
00904
00905
00906
00907 const Vector& Twenty_Node_Brick::getResistingForce( )
00908
00909 {
00910
00911 int i, j, jk, k, k1;
00912
00913 double xsj;
00914
00915 static Matrix B(6, 3);
00916
00917 double volume = 0.;
00918
00919
00920
00921
00922
00923 resid.Zero();
00924
00925
00926
00927
00928
00929 computeBasis( ) ;
00930
00931
00932
00933 for( i = 0; i < nintu; i++ ) {
00934
00935
00936
00937 Jacobian3d(i, xsj, 0);
00938
00939
00940
00941 dvolu[i] = wu[i] * xsj ;
00942
00943 volume += dvolu[i];
00944
00945 }
00946
00947
00948
00949
00950
00951
00952
00953 for (i = 0; i < nintu; i++) {
00954
00955
00956
00957
00958
00959 const Vector &sigma = materialPointers[i]->getStress();
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969 for (j = 0; j < nenu; j++) {
00970
00971
00972
00973 B(0,0) = shgu[0][j][i];
00974
00975 B(0,1) = 0.;
00976
00977 B(0,2) = 0.;
00978
00979 B(1,0) = 0.;
00980
00981 B(1,1) = shgu[1][j][i];
00982
00983 B(1,2) = 0.;
00984
00985 B(2,0) = 0.;
00986
00987 B(2,1) = 0.;
00988
00989 B(2,2) = shgu[2][j][i];
00990
00991 B(3,0) = shgu[1][j][i];
00992
00993 B(3,1) = shgu[0][j][i];
00994
00995 B(3,2) = 0.;
00996
00997 B(4,0) = 0.;
00998
00999 B(4,1) = shgu[2][j][i];
01000
01001 B(4,2) = shgu[1][j][i];
01002
01003 B(5,0) = shgu[2][j][i];
01004
01005 B(5,1) = 0.;
01006
01007 B(5,2) = shgu[0][j][i];
01008
01009
01010
01011
01012
01013 for(k = 0; k < 3; k++) {
01014
01015 for(k1 = 0; k1 < 6; k1++)
01016
01017 resid(j*3+k) += dvolu[i]*(B(k1,k)*sigma(k1));
01018
01019 }
01020
01021
01022
01023
01024
01025
01026
01027 double r = mixtureRho(i);
01028
01029 resid(j*3) -= dvolu[i]*(shgu[3][j][i]*r*b[0]);
01030
01031 resid(j*3+1) -= dvolu[i]*(shgu[3][j][i]*r*b[1]);
01032
01033 resid(j*3+2) -= dvolu[i]*(shgu[3][j][i]*r*b[2]);
01034
01035 }
01036
01037 }
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047 if (load != 0)
01048
01049 resid -= *load;
01050
01051
01052
01053
01054
01055
01056
01057 return resid ;
01058
01059 }
01060
01061
01062
01063
01064
01065
01066
01067 const Vector& Twenty_Node_Brick::getResistingForceIncInertia( )
01068
01069 {
01070
01071 static Vector res(60);
01072
01073
01074
01075
01076
01077
01078
01079 int i, j, ik;
01080
01081 static double a[60];
01082
01083
01084
01085 for (i=0; i<nenu; i++) {
01086
01087 const Vector &accel = nodePointers[i]->getTrialAccel();
01088
01089 if ( 3 != accel.Size() ) {
01090
01091 opserr << "Twenty_Node_Brick::getResistingForceIncInertia matrix and vector sizes are incompatable\n";
01092
01093 exit(-1);
01094
01095 }
01096
01097
01098
01099 a[i*3] = accel(0);
01100
01101 a[i*3+1] = accel(1);
01102
01103 a[i*3+2] = accel(2);
01104
01105 }
01106
01107
01108
01109 this->getResistingForce();
01110
01111
01112
01113
01114
01115
01116
01117 this->getMass();
01118
01119
01120
01121 for (i = 0; i < 60; i++) {
01122
01123 for (j = 0; j < 60; j++){
01124
01125 resid(i) += mass(i,j)*a[j];
01126
01127 }
01128
01129 }
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139 for (i=0; i<nenu; i++) {
01140
01141 const Vector &vel = nodePointers[i]->getTrialVel();
01142
01143 if ( 3!= vel.Size() ) {
01144
01145 opserr << "Twenty_Node_Brick::getResistingForceIncInertia matrix and vector sizes are incompatable\n";
01146
01147 exit(-1);
01148
01149 }
01150
01151 a[i*3] = vel(0);
01152
01153 a[i*3+1] = vel(1);
01154
01155 a[i*3+2] = vel(2);
01156
01157 }
01158
01159
01160
01161 this->getDamp();
01162
01163
01164
01165 for (i = 0; i < 60; i++) {
01166
01167 for (j = 0; j < 60; j++) {
01168
01169 resid(i) += damp(i,j)*a[j];
01170
01171 }
01172
01173 }
01174
01175
01176
01177
01178
01179 res = resid;
01180
01181
01182
01183
01184
01185
01186
01187 return res;
01188
01189 }
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201 void Twenty_Node_Brick::formInertiaTerms( int tangFlag )
01202
01203 {
01204
01205 static double xsj ;
01206
01207 int i, j, k, ik, m, jk;
01208
01209 double Nrho;
01210
01211
01212
01213
01214
01215 mass.Zero( ) ;
01216
01217
01218
01219
01220
01221 computeBasis( ) ;
01222
01223
01224
01225 for( i = 0; i < nintu; i++ ) {
01226
01227
01228
01229 Jacobian3d(i, xsj, 0);
01230
01231
01232
01233 dvolu[i] = wu[i] * xsj ;
01234
01235 }
01236
01237
01238
01239
01240
01241 for (i = 0; i < nenu; i++) {
01242
01243 for (j = 0; j < nenu; j++) {
01244
01245 for (m = 0; m < nintu; m++) {
01246
01247 Nrho = dvolu[m]*mixtureRho(m)*shgu[3][i][m]*shgu[3][j][m];
01248
01249 for( k = 0; k < 3; k++) {
01250
01251 mass(i*3+k,j*3+k) += Nrho;
01252
01253 }
01254
01255 }
01256
01257 }
01258
01259 }
01260
01261
01262
01263 }
01264
01265
01266
01267
01268
01269 double Twenty_Node_Brick::mixtureRho(int i)
01270
01271 {
01272
01273 double rhoi;
01274
01275
01276
01277 rhoi= materialPointers[i]->getRho();
01278
01279
01280
01281
01282
01283
01284
01285 return rhoi;
01286
01287 }
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297 void Twenty_Node_Brick::computeBasis( )
01298
01299 {
01300
01301
01302
01303
01304
01305
01306
01307 int i ;
01308
01309 for ( i = 0; i < nenu; i++ ) {
01310
01311
01312
01313 const Vector &coorI = nodePointers[i]->getCrds( ) ;
01314
01315
01316
01317 xl[0][i] = coorI(0) ;
01318
01319 xl[1][i] = coorI(1) ;
01320
01321 xl[2][i] = coorI(2) ;
01322
01323
01324
01325 }
01326
01327
01328
01329 }
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339 int Twenty_Node_Brick::sendSelf (int commitTag, Channel &theChannel)
01340
01341 {
01342
01343 int res = 0;
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353 int dataTag = this->getDbTag();
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365 int matDbTag;
01366
01367
01368
01369 static ID idData(75);
01370
01371
01372
01373 idData(74) = this->getTag();
01374
01375
01376
01377 int i;
01378
01379 for (i = 0; i < nintu; i++) {
01380
01381 idData(i) = materialPointers[i]->getClassTag();
01382
01383 matDbTag = materialPointers[i]->getDbTag();
01384
01385
01386
01387
01388
01389 if (matDbTag == 0) {
01390
01391 matDbTag = theChannel.getDbTag();
01392
01393 if (matDbTag != 0)
01394
01395 materialPointers[i]->setDbTag(matDbTag);
01396
01397 }
01398
01399 idData(i+nintu) = matDbTag;
01400
01401 }
01402
01403 for( i = 0; i < 20; i++)
01404
01405 idData(54+i) = connectedExternalNodes(i);
01406
01407
01408
01409
01410
01411 res += theChannel.sendID(dataTag, commitTag, idData);
01412
01413 if (res < 0) {
01414
01415 opserr << "WARNING Twenty_Node_Brick::sendSelf() - " << this->getTag() << " failed to send ID\n";
01416
01417 return res;
01418
01419 }
01420
01421
01422
01423
01424
01425
01426
01427 for (i = 0; i < nintu ; i++) {
01428
01429 res += materialPointers[i]->sendSelf(commitTag, theChannel);
01430
01431 if (res < 0) {
01432
01433 opserr << "WARNING Twenty_Node_Brick::sendSelf() - " << this->getTag() << " failed to send its Material\n";
01434
01435 return res;
01436
01437 }
01438
01439 }
01440
01441
01442
01443 return res;
01444
01445
01446
01447 }
01448
01449
01450
01451 int Twenty_Node_Brick::recvSelf (int commitTag,
01452
01453 Channel &theChannel,
01454
01455 FEM_ObjectBroker &theBroker)
01456
01457 {
01458
01459 int res = 0;
01460
01461
01462
01463 int dataTag = this->getDbTag();
01464
01465
01466
01467 static ID idData(75);
01468
01469
01470
01471 res += theChannel.recvID(dataTag, commitTag, idData);
01472
01473 if (res < 0) {
01474
01475 opserr << "WARNING Twenty_Node_Brick::recvSelf() - " << this->getTag() << " failed to receive ID\n";
01476
01477 return res;
01478
01479 }
01480
01481
01482
01483 this->setTag(idData(74));
01484
01485
01486
01487 int i;
01488
01489 for( i = 0; i < 20; i++)
01490
01491 connectedExternalNodes(i) = idData(54+i);
01492
01493
01494
01495 if (materialPointers[0] == 0) {
01496
01497 for (i = 0; i < nintu; i++) {
01498
01499 int matClassTag = idData(i);
01500
01501 int matDbTag = idData(i+nintu);
01502
01503
01504
01505 materialPointers[i] = theBroker.getNewNDMaterial(matClassTag);
01506
01507 if (materialPointers[i] == 0) {
01508
01509 opserr << "Twenty_Node_Brick::recvSelf() - Broker could not create NDMaterial of class type " << matClassTag << endln;
01510
01511 return -1;
01512
01513 }
01514
01515
01516
01517 materialPointers[i]->setDbTag(matDbTag);
01518
01519 res += materialPointers[i]->recvSelf(commitTag, theChannel, theBroker);
01520
01521 if (res < 0) {
01522
01523 opserr << "Twenty_Node_Brick::recvSelf() - material " << i << "failed to recv itself\n";
01524
01525 return res;
01526
01527 }
01528
01529 }
01530
01531 }
01532
01533
01534
01535 else {
01536
01537 for (i = 0; i < nintu; i++) {
01538
01539 int matClassTag = idData(i);
01540
01541 int matDbTag = idData(i+nintu);
01542
01543
01544
01545
01546
01547 if (materialPointers[i]->getClassTag() != matClassTag) {
01548
01549 delete materialPointers[i];
01550
01551 materialPointers[i] = theBroker.getNewNDMaterial(matClassTag);
01552
01553 if (materialPointers[i] == 0) {
01554
01555 opserr << "Twenty_Node_Brick::recvSelf() - Broker could not create NDMaterial of class type " <<
01556
01557 matClassTag << endln;
01558
01559 exit(-1);
01560
01561 }
01562
01563 materialPointers[i]->setDbTag(matDbTag);
01564
01565 }
01566
01567
01568
01569
01570
01571 res += materialPointers[i]->recvSelf(commitTag, theChannel, theBroker);
01572
01573 if (res < 0) {
01574
01575 opserr << "Twenty_Node_Brick::recvSelf() - material " << i << "failed to recv itself\n";
01576
01577 return res;
01578
01579 }
01580
01581 }
01582
01583 }
01584
01585
01586
01587 return res;
01588
01589 }
01590
01591
01592
01593
01594
01595 int
01596
01597 Twenty_Node_Brick::displaySelf(Renderer &theViewer, int displayMode, float fact)
01598
01599 {
01600
01601 return 0;
01602
01603 }
01604
01605
01606
01607 Response*
01608 Twenty_Node_Brick::setResponse(const char **argv, int argc, Information &eleInfo, OPS_Stream &output)
01609 {
01610
01611 Response *theResponse = 0;
01612
01613 char outputData[32];
01614
01615 output.tag("ElementOutput");
01616 output.attr("eleType","Twenty_Node_Brick");
01617 output.attr("eleTag",this->getTag());
01618 for (int i=1; i<=20; i++) {
01619 sprintf(outputData,"node%d",i);
01620 output.attr(outputData, connectedExternalNodes[i-1]);
01621 }
01622
01623 if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0) {
01624
01625 for (int i=1; i<=20; i++)
01626 for (int j=1; j<=3; j++) {
01627 sprintf(outputData,"P%d_%d",j,i);
01628 output.tag("ResponseType",outputData);
01629 }
01630
01631 theResponse = new ElementResponse(this, 1, resid);
01632
01633 } else if (strcmp(argv[0],"material") == 0 || strcmp(argv[0],"integrPoint") == 0) {
01634 int pointNum = atoi(argv[1]);
01635 if (pointNum > 0 && pointNum <= nintu) {
01636
01637 output.tag("GaussPoint");
01638 output.attr("number",pointNum);
01639
01640 theResponse = materialPointers[pointNum-1]->setResponse(&argv[2], argc-2, eleInfo, output);
01641
01642 output.endTag();
01643 }
01644 } else if (strcmp(argv[0],"stresses") ==0) {
01645
01646 for (int i=0; i<27; i++) {
01647 output.tag("GaussPoint");
01648 output.attr("number",i+1);
01649 output.tag("NdMaterialOutput");
01650 output.attr("classType", materialPointers[i]->getClassTag());
01651 output.attr("tag", materialPointers[i]->getTag());
01652
01653 output.tag("ResponseType","sigma11");
01654 output.tag("ResponseType","sigma22");
01655 output.tag("ResponseType","sigma33");
01656 output.tag("ResponseType","sigma12");
01657 output.tag("ResponseType","sigma13");
01658 output.tag("ResponseType","sigma23");
01659
01660 output.endTag();
01661 output.endTag();
01662 }
01663 theResponse = new ElementResponse(this, 5, Vector(162));
01664 }
01665
01666 output.endTag();
01667 return theResponse;
01668
01669 }
01670
01671
01672
01673 int
01674
01675 Twenty_Node_Brick::getResponse(int responseID, Information &eleInfo)
01676
01677 {
01678
01679 static Vector stresses(162);
01680
01681
01682
01683 if (responseID == 1)
01684
01685 return eleInfo.setVector(this->getResistingForce());
01686
01687
01688
01689 else if (responseID == 2)
01690
01691 return eleInfo.setMatrix(this->getTangentStiff());
01692
01693
01694
01695 else if (responseID == 3)
01696
01697 return eleInfo.setMatrix(this->getMass());
01698
01699
01700
01701 else if (responseID == 4)
01702
01703 return eleInfo.setMatrix(this->getDamp());
01704
01705
01706
01707 else if (responseID == 5) {
01708
01709
01710
01711
01712
01713 int cnt = 0;
01714
01715 for (int i = 0; i < nintu; i++) {
01716
01717
01718
01719
01720
01721 const Vector &sigma = materialPointers[i]->getStress();
01722
01723 stresses(cnt++) = sigma(0);
01724
01725 stresses(cnt++) = sigma(1);
01726
01727 stresses(cnt++) = sigma(2);
01728
01729 stresses(cnt++) = sigma(3);
01730
01731 stresses(cnt++) = sigma(4);
01732
01733 stresses(cnt++) = sigma(5);
01734
01735 }
01736
01737 return eleInfo.setVector(stresses);
01738
01739
01740
01741 }
01742
01743 else
01744
01745
01746
01747 return -1;
01748
01749 }
01750
01751
01752
01753
01754
01755 void
01756
01757 Twenty_Node_Brick::compuLocalShapeFunction() {
01758
01759
01760
01761 int i, k, j;
01762
01763 static double shl[4][20][27], w[27];
01764
01765
01766
01767 brcshl(shl, w, nintu, nenu);
01768
01769 for(k = 0; k < nintu; k++) {
01770
01771 wu[k] = w[k];
01772
01773 for( j = 0; j < nenu; j++)
01774
01775 for( i = 0; i < 4; i++)
01776
01777 shlu[i][j][k] = shl[i][j][k];
01778
01779 }
01780
01781
01782
01783 }
01784
01785
01786
01787 void
01788
01789 Twenty_Node_Brick::Jacobian3d(int gaussPoint, double& xsj, int mode)
01790
01791 {
01792
01793 int i, j, k, nint, nen;
01794
01795 double rxsj, c1, c2, c3;
01796
01797 static double xs[3][3];
01798
01799 static double ad[3][3];
01800
01801 static double shp[4][20];
01802
01803
01804
01805 if( mode == 0 ) {
01806
01807 nint = nintu;
01808
01809 nen = nenu;
01810
01811 }
01812
01813 else {
01814
01815 opserr <<"Twenty_Node_Brick::Jacobian3d - illegal mode: " << mode << "\n";
01816
01817 exit(-1);
01818
01819 }
01820
01821
01822
01823 for( j = 0; j < nen; j++) {
01824
01825 for( i = 0; i < 4; i++) {
01826
01827 if( mode == 0 )
01828
01829 shp[i][j] = shlu[i][j][gaussPoint];
01830
01831 else {
01832
01833 opserr <<"Twenty_Node_Brick::Jacobian3d - illegal mode: " << mode << "\n";
01834
01835 exit(-1);
01836
01837 }
01838
01839 }
01840
01841 }
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855 for ( j=0; j<3; j++ ) {
01856
01857 for( k = 0; k < 3; k++ ) {
01858
01859 xs[j][k] = 0;
01860
01861 for( i = 0; i < nen; i++ ) {
01862
01863 xs[j][k] += xl[j][i] * shp[k][i];
01864
01865 }
01866
01867 }
01868
01869 }
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879 ad[0][0] = xs[1][1]*xs[2][2] - xs[1][2]*xs[2][1] ;
01880
01881 ad[0][1] = xs[2][1]*xs[0][2] - xs[2][2]*xs[0][1] ;
01882
01883 ad[0][2] = xs[0][1]*xs[1][2] - xs[0][2]*xs[1][1] ;
01884
01885
01886
01887 ad[1][0] = xs[1][2]*xs[2][0] - xs[1][0]*xs[2][2] ;
01888
01889 ad[1][1] = xs[2][2]*xs[0][0] - xs[2][0]*xs[0][2] ;
01890
01891 ad[1][2] = xs[0][2]*xs[1][0] - xs[0][0]*xs[1][2] ;
01892
01893
01894
01895 ad[2][0] = xs[1][0]*xs[2][1] - xs[1][1]*xs[2][0] ;
01896
01897 ad[2][1] = xs[2][0]*xs[0][1] - xs[2][1]*xs[0][0] ;
01898
01899 ad[2][2] = xs[0][0]*xs[1][1] - xs[0][1]*xs[1][0] ;
01900
01901
01902
01903
01904
01905
01906
01907 xsj = xs[0][0]*ad[0][0] + xs[0][1]*ad[1][0] + xs[0][2]*ad[2][0] ;
01908
01909 if (xsj<=0) {
01910
01911 opserr <<"Twenty_Node_Brick::Jacobian3d - Non-positive Jacobian: " << xsj << "\n";
01912
01913 for( i = 0; i < nen; i++ ) {
01914
01915 printf("%5d %15.6e %15.6e %15.6e %15.6e\n", i,
01916
01917 shp[0][i], shp[1][i], shp[2][i], shp[3][i]);
01918
01919 }
01920
01921
01922
01923 exit(-1);
01924
01925 }
01926
01927
01928
01929 rxsj = 1.0/xsj ;
01930
01931
01932
01933
01934
01935
01936
01937 for ( j=0; j<3; j++ ) {
01938
01939
01940
01941 for ( i=0; i<3; i++ )
01942
01943 xs[i][j] = ad[i][j]*rxsj ;
01944
01945
01946
01947 }
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957 for ( k=0; k<nen; k++) {
01958
01959
01960
01961 c1 = shp[0][k]*xs[0][0] + shp[1][k]*xs[1][0] + shp[2][k]*xs[2][0] ;
01962
01963 c2 = shp[0][k]*xs[0][1] + shp[1][k]*xs[1][1] + shp[2][k]*xs[2][1] ;
01964
01965 c3 = shp[0][k]*xs[0][2] + shp[1][k]*xs[1][2] + shp[2][k]*xs[2][2] ;
01966
01967
01968
01969 shp[0][k] = c1 ;
01970
01971 shp[1][k] = c2 ;
01972
01973 shp[2][k] = c3 ;
01974
01975
01976
01977 }
01978
01979
01980
01981 for( j = 0; j < nen; j++) {
01982
01983 for( i = 0; i < 4; i++) {
01984
01985 if( mode == 0 )
01986
01987 shgu[i][j][gaussPoint] = shp[i][j];
01988
01989 else {
01990
01991 opserr <<"Twenty_Node_Brick::Jacobian3d - illegal mode: " << mode << "\n";
01992
01993 exit(-1);
01994
01995 }
01996
01997 }
01998
01999 }
02000
02001
02002
02003
02004
02005 }
02006
02007
02008
02009
02010