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 <iostream.h>
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <math.h>
00034
00035 #include <ID.h>
00036 #include <Vector.h>
00037 #include <Matrix.h>
00038 #include <Element.h>
00039 #include <Node.h>
00040 #include <SectionForceDeformation.h>
00041 #include <Domain.h>
00042 #include <ErrorHandler.h>
00043 #include <BbarBrick.h>
00044 #include <Renderer.h>
00045
00046 extern void shp3d( const double ss[3],
00047 double &xsj,
00048 double shp[4][8],
00049 const double xl[3][8] ) ;
00050
00051 double BbarBrick::xl[3][8] ;
00052
00053 Matrix BbarBrick::stiff(24,24) ;
00054 Vector BbarBrick::resid(24) ;
00055 Matrix BbarBrick::mass(24,24) ;
00056 Matrix BbarBrick::damping(24,24) ;
00057
00058
00059
00060 const double BbarBrick::root3 = sqrt(3.0) ;
00061 const double BbarBrick::one_over_root3 = 1.0 / root3 ;
00062
00063 const double BbarBrick::sg[] = { -one_over_root3,
00064 one_over_root3 } ;
00065
00066 const double BbarBrick::wg[] = { 1.0, 1.0, 1.0, 1.0,
00067 1.0, 1.0, 1.0, 1.0 } ;
00068
00069
00070
00071
00072 BbarBrick::BbarBrick( ) :
00073 Element( 0, ELE_TAG_BbarBrick ),
00074 connectedExternalNodes(8)
00075 {
00076
00077 }
00078
00079
00080
00081
00082 BbarBrick::BbarBrick( int tag,
00083 int node1,
00084 int node2,
00085 int node3,
00086 int node4,
00087 int node5,
00088 int node6,
00089 int node7,
00090 int node8,
00091 NDMaterial &theMaterial ) :
00092 Element( tag, ELE_TAG_BbarBrick ),
00093 connectedExternalNodes(8)
00094 {
00095 connectedExternalNodes(0) = node1 ;
00096 connectedExternalNodes(1) = node2 ;
00097 connectedExternalNodes(2) = node3 ;
00098 connectedExternalNodes(3) = node4 ;
00099
00100 connectedExternalNodes(4) = node5 ;
00101 connectedExternalNodes(5) = node6 ;
00102 connectedExternalNodes(6) = node7 ;
00103 connectedExternalNodes(7) = node8 ;
00104
00105 int i ;
00106 for ( i=0; i<8; i++ ) {
00107
00108 materialPointers[i] = theMaterial.getCopy("ThreeDimensional") ;
00109
00110 if (materialPointers[i] == 0) {
00111
00112 g3ErrorHandler->fatal("BbarBrick::constructor %s",
00113 "- failed to get a material of type: ShellSection");
00114 }
00115
00116 }
00117
00118
00119 }
00120
00121
00122
00123
00124 BbarBrick::~BbarBrick( )
00125 {
00126 int i ;
00127 for ( i=0 ; i<8; i++ ) {
00128
00129 delete materialPointers[i] ;
00130 materialPointers[i] = 0 ;
00131
00132 nodePointers[i] = 0 ;
00133
00134 }
00135 }
00136
00137
00138
00139 void BbarBrick::setDomain( Domain *theDomain )
00140 {
00141
00142 int i ;
00143
00144
00145 for ( i=0; i<8; i++ )
00146 nodePointers[i] = theDomain->getNode( connectedExternalNodes(i) ) ;
00147
00148 this->DomainComponent::setDomain(theDomain);
00149
00150 }
00151
00152
00153
00154 int BbarBrick::getNumExternalNodes( ) const
00155 {
00156 return 8 ;
00157 }
00158
00159
00160
00161 const ID& BbarBrick::getExternalNodes( )
00162 {
00163 return connectedExternalNodes ;
00164 }
00165
00166
00167
00168 int BbarBrick::getNumDOF( )
00169 {
00170 return 24 ;
00171 }
00172
00173
00174
00175 int BbarBrick::commitState( )
00176 {
00177 int i ;
00178 int success = 0 ;
00179
00180 for ( i=0; i<8; i++ )
00181 success += materialPointers[i]->commitState( ) ;
00182
00183 return success ;
00184 }
00185
00186
00187
00188
00189 int BbarBrick::revertToLastCommit( )
00190 {
00191 int i ;
00192 int success = 0 ;
00193
00194 for ( i=0; i<8; i++ )
00195 success += materialPointers[i]->revertToLastCommit( ) ;
00196
00197 return success ;
00198 }
00199
00200
00201
00202 int BbarBrick::revertToStart( )
00203 {
00204 int i ;
00205 int success = 0 ;
00206
00207 for ( i=0; i<8; i++ )
00208 success += materialPointers[i]->revertToStart( ) ;
00209
00210 return success ;
00211 }
00212
00213
00214 void BbarBrick::Print( ostream &s, int flag )
00215 {
00216 s << '\n' ;
00217 s << "Volume/Pressure Eight Node BbarBrick \n" ;
00218 s << "Node 1 : " << connectedExternalNodes(0) << '\n' ;
00219 s << "Node 2 : " << connectedExternalNodes(1) << '\n' ;
00220 s << "Node 3 : " << connectedExternalNodes(2) << '\n' ;
00221 s << "Node 4 : " << connectedExternalNodes(3) << '\n' ;
00222 s << "Node 5 : " << connectedExternalNodes(4) << '\n' ;
00223 s << "Node 6 : " << connectedExternalNodes(5) << '\n' ;
00224 s << "Node 7 : " << connectedExternalNodes(6) << '\n' ;
00225 s << "Node 8 : " << connectedExternalNodes(7) << '\n' ;
00226
00227 s << "Material Information : \n " ;
00228 materialPointers[0]->Print( s, flag ) ;
00229
00230 s << endl ;
00231 }
00232
00233
00234 const Matrix& BbarBrick::getTangentStiff( )
00235 {
00236 int tang_flag = 1 ;
00237
00238
00239 formResidAndTangent( tang_flag ) ;
00240
00241 return stiff ;
00242 }
00243
00244
00245
00246 const Matrix& BbarBrick::getSecantStiff( )
00247 {
00248 int tang_flag = 1 ;
00249
00250
00251 formResidAndTangent( tang_flag ) ;
00252
00253 return stiff ;
00254 }
00255
00256
00257
00258 const Matrix& BbarBrick::getDamp( )
00259 {
00260
00261 return damping ;
00262 }
00263
00264
00265
00266 const Matrix& BbarBrick::getMass( )
00267 {
00268 int tangFlag = 1 ;
00269
00270 formInertiaTerms( tangFlag ) ;
00271
00272 return mass ;
00273 }
00274
00275
00276 void BbarBrick::zeroLoad( )
00277 {
00278 return ;
00279 }
00280
00281
00282 int BbarBrick::addLoad( const Vector &addP )
00283 {
00284 return -1 ;
00285 }
00286
00287
00288
00289 const Vector& BbarBrick::getResistingForce( )
00290 {
00291 int tang_flag = 0 ;
00292
00293 formResidAndTangent( tang_flag ) ;
00294
00295 return resid ;
00296 }
00297
00298
00299
00300 const Vector& BbarBrick::getResistingForceIncInertia( )
00301 {
00302 int tang_flag = 0 ;
00303
00304
00305 formResidAndTangent( tang_flag ) ;
00306
00307 formInertiaTerms( tang_flag ) ;
00308
00309 return resid ;
00310 }
00311
00312
00313
00314
00315
00316 void BbarBrick::formInertiaTerms( int tangFlag )
00317 {
00318
00319 static const int ndm = 3 ;
00320
00321 static const int ndf = 3 ;
00322
00323 static const int numberNodes = 8 ;
00324
00325 static const int numberGauss = 8 ;
00326
00327 static const int nShape = 4 ;
00328
00329 static const int massIndex = nShape - 1 ;
00330
00331 double xsj ;
00332
00333 double dvol[numberGauss] ;
00334
00335 static double shp[nShape][numberNodes] ;
00336
00337 static double Shape[nShape][numberNodes][numberGauss] ;
00338
00339 static double gaussPoint[ndm] ;
00340
00341 static Vector momentum(ndf) ;
00342
00343 int i, j, k, p, q ;
00344 int jj, kk ;
00345
00346 double temp, rho, massJK ;
00347
00348
00349
00350 mass.Zero( ) ;
00351
00352
00353 computeBasis( ) ;
00354
00355
00356
00357 int count = 0 ;
00358
00359 for ( i = 0; i < 2; i++ ) {
00360 for ( j = 0; j < 2; j++ ) {
00361 for ( k = 0; k < 2; k++ ) {
00362
00363 gaussPoint[0] = sg[i] ;
00364 gaussPoint[1] = sg[j] ;
00365 gaussPoint[2] = sg[k] ;
00366
00367
00368 shp3d( gaussPoint, xsj, shp, xl ) ;
00369
00370
00371 for ( p = 0; p < nShape; p++ ) {
00372 for ( q = 0; q < numberNodes; q++ )
00373 Shape[p][q][count] = shp[p][q] ;
00374 }
00375
00376
00377 dvol[count] = wg[count] * xsj ;
00378
00379 count++ ;
00380
00381 }
00382 }
00383 }
00384
00385
00386
00387
00388 for ( i = 0; i < numberGauss; i++ ) {
00389
00390
00391 for ( p = 0; p < nShape; p++ ) {
00392 for ( q = 0; q < numberNodes; q++ )
00393 shp[p][q] = Shape[p][q][i] ;
00394 }
00395
00396
00397
00398 momentum.Zero( ) ;
00399 for ( j = 0; j < numberNodes; j++ )
00400 momentum += shp[massIndex][j] * ( nodePointers[j]->getTrialAccel() ) ;
00401
00402
00403 rho = materialPointers[i]->getRho() ;
00404
00405
00406 momentum *= rho ;
00407
00408
00409
00410 jj = 0 ;
00411 for ( j = 0; j < numberNodes; j++ ) {
00412
00413 temp = shp[massIndex][j] * dvol[i] ;
00414
00415 for ( p = 0; p < ndf; p++ )
00416 resid( jj+p ) += ( temp * momentum(p) ) ;
00417
00418
00419 if ( tangFlag == 1 ) {
00420
00421
00422 temp *= rho ;
00423
00424
00425 kk = 0 ;
00426 for ( k = 0; k < numberNodes; k++ ) {
00427
00428 massJK = temp * shp[massIndex][k] ;
00429
00430 for ( p = 0; p < ndf; p++ )
00431 mass( jj+p, kk+p ) += massJK ;
00432
00433 kk += ndf ;
00434 }
00435
00436 }
00437
00438 jj += ndf ;
00439 }
00440
00441
00442 }
00443
00444 }
00445
00446
00447
00448 void BbarBrick::formResidAndTangent( int tang_flag )
00449 {
00450
00451
00452
00453 static const int ndm = 3 ;
00454
00455 static const int ndf = 3 ;
00456
00457 static const int nstress = 6 ;
00458
00459 static const int numberNodes = 8 ;
00460
00461 static const int numberGauss = 8 ;
00462
00463 static const int nShape = 4 ;
00464
00465 int i, j, k, p, q ;
00466 int jj, kk ;
00467
00468 int success ;
00469
00470 static double volume ;
00471
00472 static double xsj ;
00473
00474 static double dvol[numberGauss] ;
00475
00476 static double gaussPoint[ndm] ;
00477
00478 static Vector strain(nstress) ;
00479
00480 static double shp[nShape][numberNodes] ;
00481
00482 static double Shape[nShape][numberNodes][numberGauss] ;
00483
00484 static double shpBar[nShape][numberNodes] ;
00485
00486 static Vector residJ(ndf) ;
00487
00488 static Matrix stiffJK(ndf,ndf) ;
00489
00490 static Vector stress(nstress) ;
00491
00492 static Matrix dd(nstress,nstress) ;
00493
00494
00495
00496
00497 static Matrix BJ(nstress,ndf) ;
00498
00499 static Matrix BJtran(ndf,nstress) ;
00500
00501 static Matrix BK(nstress,ndf) ;
00502
00503 static Matrix BJtranD(ndf,nstress) ;
00504
00505
00506
00507
00508
00509 stiff.Zero( ) ;
00510 resid.Zero( ) ;
00511
00512
00513 computeBasis( ) ;
00514
00515
00516
00517 for ( p = 0; p < nShape; p++ ) {
00518 for ( q = 0; q < numberNodes; q++ )
00519 shpBar[p][q] = 0.0 ;
00520 }
00521
00522
00523 volume = 0.0 ;
00524
00525
00526
00527 int count = 0 ;
00528
00529 for ( i = 0; i < 2; i++ ) {
00530 for ( j = 0; j < 2; j++ ) {
00531 for ( k = 0; k < 2; k++ ) {
00532
00533 gaussPoint[0] = sg[i] ;
00534 gaussPoint[1] = sg[j] ;
00535 gaussPoint[2] = sg[k] ;
00536
00537
00538 shp3d( gaussPoint, xsj, shp, xl ) ;
00539
00540
00541 for ( p = 0; p < nShape; p++ ) {
00542 for ( q = 0; q < numberNodes; q++ )
00543 Shape[p][q][count] = shp[p][q] ;
00544 }
00545
00546
00547 dvol[count] = wg[count] * xsj ;
00548
00549
00550 volume += dvol[count] ;
00551
00552
00553 for ( p = 0; p < nShape; p++ ) {
00554 for ( q = 0; q < numberNodes; q++ )
00555 shpBar[p][q] += ( dvol[count] * shp[p][q] ) ;
00556 }
00557
00558 count++ ;
00559
00560 }
00561 }
00562 }
00563
00564
00565
00566 for ( p = 0; p < nShape; p++ ) {
00567 for ( q = 0; q < numberNodes; q++ )
00568 shpBar[p][q] /= volume ;
00569 }
00570
00571
00572
00573 for ( i = 0; i < numberGauss; i++ ) {
00574
00575
00576 for ( p = 0; p < nShape; p++ ) {
00577 for ( q = 0; q < numberNodes; q++ )
00578 shp[p][q] = Shape[p][q][i] ;
00579 }
00580
00581
00582
00583 strain.Zero( ) ;
00584
00585
00586
00587 for ( j = 0; j < numberNodes; j++ ) {
00588
00589
00590
00591 BJ = computeBbar( j, shp, shpBar ) ;
00592
00593
00594 const Vector &ul = nodePointers[j]->getTrialDisp( ) ;
00595
00596
00597 strain += (BJ*ul) ;
00598
00599 }
00600
00601
00602
00603
00604 success = materialPointers[i]->setTrialStrain( strain ) ;
00605
00606
00607 stress = materialPointers[i]->getStress( ) ;
00608
00609
00610
00611 stress *= dvol[i] ;
00612
00613 if ( tang_flag == 1 ) {
00614 dd = materialPointers[i]->getTangent( ) ;
00615 dd *= dvol[i] ;
00616 }
00617
00618
00619
00620
00621 jj = 0 ;
00622 for ( j = 0; j < numberNodes; j++ ) {
00623
00624 BJ = computeBbar( j, shp, shpBar ) ;
00625
00626
00627 BJtran = transpose( nstress, ndf, BJ ) ;
00628
00629
00630
00631 residJ = BJtran * stress ;
00632
00633
00634 for ( p = 0; p < ndf; p++ )
00635 resid( jj + p ) += residJ(p) ;
00636
00637
00638 if ( tang_flag == 1 ) {
00639
00640 BJtranD = BJtran * dd ;
00641
00642 kk = 0 ;
00643 for ( k = 0; k < numberNodes; k++ ) {
00644
00645 BK = computeBbar( k, shp, shpBar ) ;
00646
00647
00648 stiffJK = BJtranD * BK ;
00649
00650 for ( p = 0; p < ndf; p++ ) {
00651 for ( q = 0; q < ndf; q++ )
00652 stiff( jj+p, kk+q ) += stiffJK( p, q ) ;
00653 }
00654
00655 kk += ndf ;
00656 }
00657
00658 }
00659
00660 jj += ndf ;
00661 }
00662
00663
00664 }
00665
00666
00667 return ;
00668 }
00669
00670
00671
00672
00673
00674 void BbarBrick::computeBasis( )
00675 {
00676
00677
00678
00679 int i ;
00680 for ( i = 0; i < 8; i++ ) {
00681
00682 const Vector &coorI = nodePointers[i]->getCrds( ) ;
00683
00684 xl[0][i] = coorI(0) ;
00685 xl[1][i] = coorI(1) ;
00686 xl[2][i] = coorI(2) ;
00687
00688 }
00689
00690 }
00691
00692
00693
00694
00695 Matrix BbarBrick::computeBbar( int node,
00696 const double shp[4][8],
00697 const double shpBar[4][8] )
00698 {
00699
00700 static Matrix Bbar(6,3) ;
00701
00702 static Matrix Bdev(3,3) ;
00703
00704 static Matrix BbarVol(3,3) ;
00705
00706 static const double one3 = 1.0/3.0 ;
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736 Bdev.Zero( ) ;
00737 BbarVol.Zero( ) ;
00738 Bbar.Zero( ) ;
00739
00740
00741 Bdev(0,0) = 2.0*shp[0][node] ;
00742 Bdev(0,1) = -shp[1][node] ;
00743 Bdev(0,2) = -shp[2][node] ;
00744
00745 Bdev(1,0) = -shp[0][node] ;
00746 Bdev(1,1) = 2.0*shp[1][node] ;
00747 Bdev(1,2) = -shp[2][node] ;
00748
00749 Bdev(2,0) = -shp[0][node] ;
00750 Bdev(2,1) = -shp[1][node] ;
00751 Bdev(2,2) = 2.0*shp[2][node] ;
00752
00753 Bdev *= one3 ;
00754
00755
00756
00757 BbarVol(0,0) = shpBar[0][node] ;
00758 BbarVol(0,1) = shpBar[1][node] ;
00759 BbarVol(0,2) = shpBar[2][node] ;
00760
00761 BbarVol(1,0) = shpBar[0][node] ;
00762 BbarVol(1,1) = shpBar[1][node] ;
00763 BbarVol(1,2) = shpBar[2][node] ;
00764
00765 BbarVol(2,0) = shpBar[0][node] ;
00766 BbarVol(2,1) = shpBar[1][node] ;
00767 BbarVol(2,2) = shpBar[2][node] ;
00768
00769 BbarVol *= one3 ;
00770
00771
00772
00773 for ( int i=0; i<3; i++ ){
00774 for ( int j=0; j<3; j++ )
00775 Bbar(i,j) = Bdev(i,j) + BbarVol(i,j) ;
00776 }
00777
00778
00779
00780 Bbar(3,0) = shp[1][node] ;
00781 Bbar(3,1) = shp[0][node] ;
00782
00783 Bbar(4,1) = shp[2][node] ;
00784 Bbar(4,2) = shp[1][node] ;
00785
00786 Bbar(5,0) = shp[2][node] ;
00787 Bbar(5,2) = shp[0][node] ;
00788
00789 return Bbar ;
00790
00791 }
00792
00793
00794
00795 Matrix BbarBrick::transpose( int dim1,
00796 int dim2,
00797 const Matrix &M )
00798 {
00799 int i ;
00800 int j ;
00801
00802 Matrix Mtran( dim2, dim1 ) ;
00803
00804 for ( i = 0; i < dim1; i++ ) {
00805 for ( j = 0; j < dim2; j++ )
00806 Mtran(j,i) = M(i,j) ;
00807 }
00808
00809 return Mtran ;
00810 }
00811
00812
00813
00814 int BbarBrick::sendSelf (int commitTag, Channel &theChannel)
00815 {
00816 return -1;
00817 }
00818
00819 int BbarBrick::recvSelf (int commitTag,
00820 Channel &theChannel,
00821 FEM_ObjectBroker &theBroker)
00822 {
00823 return -1;
00824 }
00825
00826
00827 int
00828 BbarBrick::displaySelf(Renderer &theViewer, int displayMode, float fact)
00829 {
00830
00831 const Vector &end1Crd = nodePointers[0]->getCrds();
00832 const Vector &end2Crd = nodePointers[1]->getCrds();
00833 const Vector &end3Crd = nodePointers[2]->getCrds();
00834 const Vector &end4Crd = nodePointers[3]->getCrds();
00835
00836 const Vector &end5Crd = nodePointers[4]->getCrds();
00837 const Vector &end6Crd = nodePointers[5]->getCrds();
00838 const Vector &end7Crd = nodePointers[6]->getCrds();
00839 const Vector &end8Crd = nodePointers[7]->getCrds();
00840
00841 const Vector &end1Disp = nodePointers[0]->getDisp();
00842 const Vector &end2Disp = nodePointers[1]->getDisp();
00843 const Vector &end3Disp = nodePointers[2]->getDisp();
00844 const Vector &end4Disp = nodePointers[3]->getDisp();
00845
00846 const Vector &end5Disp = nodePointers[4]->getDisp();
00847 const Vector &end6Disp = nodePointers[5]->getDisp();
00848 const Vector &end7Disp = nodePointers[6]->getDisp();
00849 const Vector &end8Disp = nodePointers[7]->getDisp();
00850
00851 static Matrix coords(4,3);
00852 static Vector values(4);
00853 static Vector P(24) ;
00854
00855 values(0) = 1 ;
00856 values(1) = 1 ;
00857 values(2) = 1 ;
00858 values(3) = 1 ;
00859
00860 if (displayMode < 3 && displayMode > 0)
00861 P = this->getResistingForce();
00862
00863 int error = 0;
00864
00865 int i;
00866 for (i = 0; i < 3; i++) {
00867 coords(0,i) = end1Crd(i) + end1Disp(i)*fact;
00868 coords(1,i) = end2Crd(i) + end2Disp(i)*fact;
00869 coords(2,i) = end3Crd(i) + end3Disp(i)*fact;
00870 coords(3,i) = end4Crd(i) + end4Disp(i)*fact;
00871 }
00872 error += theViewer.drawPolygon (coords, values);
00873
00874 for (i = 0; i < 3; i++) {
00875 coords(0,i) = end5Crd(i) + end5Disp(i)*fact;
00876 coords(1,i) = end6Crd(i) + end6Disp(i)*fact;
00877 coords(2,i) = end7Crd(i) + end7Disp(i)*fact;
00878 coords(3,i) = end8Crd(i) + end8Disp(i)*fact;
00879 }
00880 error += theViewer.drawPolygon (coords, values);
00881
00882 for (i = 0; i < 3; i++) {
00883 coords(0,i) = end1Crd(i) + end1Disp(i)*fact;
00884 coords(1,i) = end4Crd(i) + end4Disp(i)*fact;
00885 coords(2,i) = end8Crd(i) + end8Disp(i)*fact;
00886 coords(3,i) = end5Crd(i) + end5Disp(i)*fact;
00887 }
00888 error += theViewer.drawPolygon (coords, values);
00889
00890 for (i = 0; i < 3; i++) {
00891 coords(0,i) = end2Crd(i) + end2Disp(i)*fact;
00892 coords(1,i) = end3Crd(i) + end3Disp(i)*fact;
00893 coords(2,i) = end7Crd(i) + end7Disp(i)*fact;
00894 coords(3,i) = end6Crd(i) + end6Disp(i)*fact;
00895 }
00896 error += theViewer.drawPolygon (coords, values);
00897
00898
00899 for (i = 0; i < 3; i++) {
00900 coords(0,i) = end1Crd(i) + end1Disp(i)*fact;
00901 coords(1,i) = end2Crd(i) + end2Disp(i)*fact;
00902 coords(2,i) = end6Crd(i) + end6Disp(i)*fact;
00903 coords(3,i) = end5Crd(i) + end5Disp(i)*fact;
00904 }
00905 error += theViewer.drawPolygon (coords, values);
00906
00907 for (i = 0; i < 3; i++) {
00908 coords(0,i) = end4Crd(i) + end4Disp(i)*fact;
00909 coords(1,i) = end3Crd(i) + end3Disp(i)*fact;
00910 coords(2,i) = end7Crd(i) + end7Disp(i)*fact;
00911 coords(3,i) = end8Crd(i) + end8Disp(i)*fact;
00912 }
00913 error += theViewer.drawPolygon (coords, values);
00914
00915
00916 return error;
00917 }