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