Twenty_Node_Brick.cpp

Go to the documentation of this file.
00001 /* *********************************************************************
00002 **    OpenSees - Open System for Earthquake Engineering Simulation    **
00003 **          Pacific Earthquake Engineering Research Center            **
00004 **                                                                    **
00005 **                                                                    **
00006 ** (C) Copyright 1999, The Regents of the University of California    **
00007 ** All Rights Reserved.                                               **
00008 **                                                                    **
00009 ** Commercial use of this program without express permission of the   **
00010 ** University of California, Berkeley, is strictly prohibited.  See   **
00011 ** file 'COPYRIGHT'  in main directory for information on usage and   **
00012 ** redistribution,  and for a DISCLAIMER OF ALL WARRANTIES.           **
00013 **                                                                    **
00014 ** Developed by:                                                      **
00015 **   Frank McKenna (fmckenna@ce.berkeley.edu)                         **
00016 **   Gregory L. Fenves (fenves@ce.berkeley.edu)                       **
00017 **   Filip C. Filippou (filippou@ce.berkeley.edu)                     **
00018 **                                                                    **
00019 ** ****************************************************************** */
00020 //
00021 // by Jinchi Lu and Zhaohui Yang (May 2004)
00022 //
00023 // 20NodeBrick element
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 //static data
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 //null constructor
00064 Twenty_Node_Brick::Twenty_Node_Brick( ) :
00065 Element( 0, ELE_TAG_Twenty_Node_Brick ),
00066 connectedExternalNodes(20), load(0), Ki(0)//, kc(0), rho(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         // calculate local shape functions and derivatives
00074         compuLocalShapeFunction();
00075 }
00076 
00077 
00078 //*********************************************************************
00079 //full constructor
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)//, kc(bulk), rho(rhof)
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     // Allocate arrays of pointers to NDMaterials
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                 } //end if
00142 
00143         } //end for i
00144 
00145         // Body forces
00146         b[0] = b1;
00147         b[1] = b2;
00148         b[2] = b3;
00149 //      printf("b %15.6e %15.6e %15.6e \n", b1, b2,b3);
00150         // calculate local shape functions and derivatives
00151         compuLocalShapeFunction();
00152 
00153 }
00154 //******************************************************************
00155 
00156 
00157 //destructor
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     // Delete the array of pointers to NDMaterial pointer arrays
00167     if (materialPointers)
00168                 delete [] materialPointers;
00169 
00170         for ( i=0 ; i<nenu; i++ ) {
00171                 nodePointers[i] = 0 ;
00172         } //end for i
00173 
00174         if (load != 0)
00175                 delete load;
00176 
00177         if (Ki != 0)
00178                 delete Ki;
00179 }
00180 
00181 
00182 //set domain
00183 void  Twenty_Node_Brick::setDomain( Domain *theDomain )
00184 {
00185         int i,dof ;
00186         // Check Domain is not null - invoked when object removed from a domain
00187         if (theDomain == 0) {
00188                 for ( i=0; i<nenu; i++ )
00189                         nodePointers[i] = 0;
00190                 return;
00191         }
00192         //node pointers
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 //get the number of external nodes
00211 int  Twenty_Node_Brick::getNumExternalNodes( ) const
00212 {
00213         return nenu ;
00214 }
00215 
00216 
00217 //return connected external nodes
00218 const ID&  Twenty_Node_Brick::getExternalNodes( )
00219 {
00220         return connectedExternalNodes ;
00221 }
00222 
00223 //return connected external node
00224 Node **
00225 Twenty_Node_Brick::getNodePtrs(void)
00226 {
00227         return nodePointers ;
00228 }
00229 
00230 
00231 //return number of dofs
00232 int  Twenty_Node_Brick::getNumDOF( )
00233 {
00234         return 60 ;
00235 }
00236 
00237 
00238 //commit state
00239 int  Twenty_Node_Brick::commitState( )
00240 {
00241         int success = 0 ;
00242 
00243         // call element commitState to do any base class stuff
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 //revert to last commit
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 //revert to start
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 //print out element data
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                 // spit out the section location & invoke print on the scetion
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                 for (i=0; i<numMaterials; i++) {
00326                 s << "#MATERIAL\n";
00327                 //      materialPointers[i]->Print(s, flag);
00328                 s << materialPointers[i]->getStress();
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         //compute basis vectors and local nodal coordinates
00386         computeBasis( ) ;
00387 
00388         for( i = 0; i < nintu; i++ ) {
00389                 // compute Jacobian and global shape functions
00390                 Jacobian3d(i, xsj, 0);
00391                 //volume element to also be saved
00392                 dvolu[i] = wu[i] * xsj ;
00393                 volume += dvolu[i];
00394         } // end for i
00395     //printf("volume = %f\n", volume);
00396 
00397         // Loop over the integration points
00398         for (i = 0; i < nintu; i++) {
00399 
00400                 // Interpolate strains
00401                 //eps = B*u;
00402                 //eps.addMatrixVector(0.0, B, u, 1.0);
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                         //BJ = computeB( j, shp ) ;
00427 
00428                         //nodal displacements
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                         //compute the strain
00435                         //strain += (BJ*ul) ;
00436                         eps.addMatrixVector(1.0,B,ul3,1.0 ) ;
00437 
00438                         /* for( k = 0; k < 6; k++) {
00439                         for( k1 = 0; k1 < 3; k1++) {
00440                         eps[k] += BJ(k, k1)*u[k1][j];
00441                         }
00442                 }       */
00443 
00444 
00445                 }
00446 
00447                 // Set the material strain
00448                 ret += materialPointers[i]->setTrialStrain(eps);
00449         }
00450 
00451         return ret;
00452 }
00453 
00454 
00455 //return tangent stiffness matrix
00456 
00457 const Matrix&  Twenty_Node_Brick::getTangentStiff( )
00458 
00459 {
00460 
00461         return getStiff( 1 );
00462 
00463 }
00464 
00465 
00466 
00467 // return initial stiffness matrix
00468 
00469 const Matrix&  Twenty_Node_Brick::getInitialStiff( )
00470 
00471 {
00472 
00473         return getStiff( 0 );
00474 
00475 }
00476 
00477 
00478 
00479 // compute stiffness matrix
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 ;  // determinant jacaobian matrix
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 //              FILE *fp;
00526 
00527 //              fp = fopen("stiff.dat","w");
00528 
00529 
00530 
00531         //compute basis vectors and local nodal coordinates
00532 
00533         computeBasis( ) ;
00534 
00535 
00536 
00537         for( i = 0; i < nintu; i++ ) {
00538 
00539                 // compute Jacobian and global shape functions
00540 
00541                 Jacobian3d(i, xsj, 0);
00542 
00543                 //volume element to also be saved
00544 
00545                 dvolu[i] = wu[i] * xsj ;
00546 
00547                 volume += dvolu[i];
00548 
00549         } // end for i
00550 
00551     //printf("volume = %f\n", volume);
00552 
00553 
00554 
00555 //      for( i = 0; i < nintu; i++ ) {
00556 
00557 //              for(int j = 0; j < nenu; j++ ) {
00558 
00559 //                      printf("%5d %5d %15.6e %15.6e %15.6e %15.6e\n", i,j,
00560 
00561 //                              shgu[0][j][i], shgu[1][j][i], shgu[2][j][i], shgu[3][j][i]);
00562 
00563 //              }
00564 
00565 //      }
00566 
00567 //      exit(-1);
00568 
00569 
00570 
00571         // Loop over the integration points
00572 
00573         for (i = 0; i < nintu; i++) {
00574 
00575 
00576 
00577                 // Get the material tangent
00578 
00579                 if( flag == 0 )
00580 
00581                         D = materialPointers[i]->getInitialTangent();
00582 
00583                 else
00584 
00585                         D = materialPointers[i]->getTangent();
00586 
00587                 //const Matrix &D = materialPointers[i]->getTangent();
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                 // Perform numerical integration
00658 
00659                 //K = K + (B^ D * B) * intWt(i) * detJ;
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 //return mass matrix
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 //return mass matrix
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 ;  // determinant jacaobian matrix
00748 
00749         int i, j, k, m, ik, jk;
00750 
00751         double volume = 0.;
00752 
00753         //zero damp
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 //      printf("calling addInertiaLoadToUnbalance()\n");
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         // Compute mass matrix
00868 
00869         int tangFlag = 1 ;
00870 
00871         formInertiaTerms( tangFlag ) ;
00872 
00873 
00874 
00875         // create the load vector if one does not exist
00876 
00877         if (load == 0)
00878 
00879           load = new Vector(60);
00880 
00881 
00882 
00883         // add -M * RV(accel) to the load vector
00884 
00885         load->addMatrixVector(1.0, mass, ra, -1.0);
00886 
00887         //for( i = 0; i < 60; i++) {
00888 
00889         //      for( j = 0; j < 60; j++)
00890 
00891         //                              load(i) += -mass(i,j)*ra[j];
00892 
00893         //}
00894 
00895 
00896 
00897         return 0;
00898 
00899 }
00900 
00901 
00902 
00903 
00904 
00905 //get residual
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 //      printf("calling getResistingForce()\n");
00922 
00923         resid.Zero();
00924 
00925 
00926 
00927         //compute basis vectors and local nodal coordinates
00928 
00929         computeBasis( ) ;
00930 
00931         //gauss loop to compute and save shape functions
00932 
00933         for( i = 0; i < nintu; i++ ) {
00934 
00935                 // compute Jacobian and global shape functions
00936 
00937                 Jacobian3d(i, xsj, 0);
00938 
00939                 //volume element to also be saved
00940 
00941                 dvolu[i] = wu[i] * xsj ;
00942 
00943                 volume += dvolu[i];
00944 
00945         } // end for i
00946 
00947         //printf("volume = %f\n", volume);
00948 
00949 
00950 
00951         // Loop over the integration points
00952 
00953         for (i = 0; i < nintu; i++) {
00954 
00955 
00956 
00957                 // Get material stress response
00958 
00959                 const Vector &sigma = materialPointers[i]->getStress();
00960 
00961 
00962 
00963                 // Perform numerical integration on internal force
00964 
00965                 //P = P + (B^ sigma) * intWt(i)*intWt(j) * detJ;
00966 
00967                 //P.addMatrixTransposeVector(1.0, B, sigma, intWt(i)*intWt(j)*detJ);
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                         // Subtract equiv. body forces from the nodes
01022 
01023                         //P = P - (N^ b) * intWt(i)*intWt(j) * detJ;
01024 
01025                         //P.addMatrixTransposeVector(1.0, N, b, -intWt(i)*intWt(j)*detJ);
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         // Subtract other external nodal loads ... P_res = P_int - P_ext
01042 
01043 //      opserr<<"resid before:"<<resid<<endln;
01044 
01045 
01046 
01047         if (load != 0)
01048 
01049                 resid -= *load;
01050 
01051 
01052 
01053 //      opserr<<"resid "<<resid<<endln;
01054 
01055 
01056 
01057         return resid ;
01058 
01059 }
01060 
01061 
01062 
01063 
01064 
01065 //get residual with inertia terms
01066 
01067 const Vector&  Twenty_Node_Brick::getResistingForceIncInertia( )
01068 
01069 {
01070 
01071         static Vector res(60);
01072 
01073 
01074 
01075 //      printf("getResistingForceIncInertia()\n");
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         // Compute the current resisting force
01108 
01109         this->getResistingForce();
01110 
01111 //      opserr<<"K "<<resid<<endln;
01112 
01113 
01114 
01115         // Compute the mass matrix
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 //      printf("\n");
01132 
01133         //opserr<<"K+M "<<P<<endln;
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 //      opserr<<"Pd"<<Pd<<endln;
01176 
01177 
01178 
01179         res = resid;
01180 
01181 //      opserr<<"res "<<res<<endln;
01182 
01183 
01184 
01185 //      exit(-1);
01186 
01187         return res;
01188 
01189 }
01190 
01191 
01192 
01193 
01194 
01195 //*********************************************************************
01196 
01197 //form inertia terms
01198 
01199 
01200 
01201 void   Twenty_Node_Brick::formInertiaTerms( int tangFlag )
01202 
01203 {
01204 
01205         static double xsj ;  // determinant jacaobian matrix
01206 
01207         int i, j, k, ik, m, jk;
01208 
01209         double Nrho;
01210 
01211 
01212 
01213         //zero mass
01214 
01215         mass.Zero( ) ;
01216 
01217 
01218 
01219         //compute basis vectors and local nodal coordinates
01220 
01221         computeBasis( ) ;
01222 
01223         //gauss loop to compute and save shape functions
01224 
01225         for( i = 0; i < nintu; i++ ) {
01226 
01227                 // compute Jacobian and global shape functions
01228 
01229                 Jacobian3d(i, xsj, 0);
01230 
01231                 //volume element to also be saved
01232 
01233                 dvolu[i] = wu[i] * xsj ;
01234 
01235         } // end for i
01236 
01237 
01238 
01239         // Compute consistent mass matrix
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         //e = 0.7;  //theMaterial[i]->getVoidRatio();
01280 
01281         //n = e / (1.0 + e);
01282 
01283         //return n * rho + (1.0-n) * rhoi;
01284 
01285         return rhoi;
01286 
01287 }
01288 
01289 
01290 
01291 //************************************************************************
01292 
01293 //compute local coordinates and basis
01294 
01295 
01296 
01297 void   Twenty_Node_Brick::computeBasis( )
01298 
01299 {
01300 
01301 
01302 
01303         //nodal coordinates
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         }  //end for i
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         // note: we don't check for dataTag == 0 for Element
01348 
01349         // objects as that is taken care of in a commit by the Domain
01350 
01351         // object - don't want to have to do the check if sending data
01352 
01353         int dataTag = this->getDbTag();
01354 
01355 
01356 
01357         // Quad packs its data into a Vector and sends this to theChannel
01358 
01359         // along with its dbTag and the commitTag passed in the arguments
01360 
01361 
01362 
01363         // Now quad sends the ids of its materials
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                 // NOTE: we do have to ensure that the material has a database
01386 
01387                 // tag if we are sending to a database channel.
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         // Finally, this element asks its material objects to send themselves
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         //  now receives the tags of its 20 external nodes
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                         // Allocate new material with the sent class tag
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                         // Now receive materials into the newly allocated space
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         // materials exist , ensure materials of correct type and recvSelf on them
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                         // Check that material is of the right type; if not,
01544 
01545                         // delete it and create a new one of the right type
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                         // Receive the material
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(); // GaussPoint
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(); // NdMaterialOutput
01661       output.endTag(); // GaussPoint
01662     }
01663     theResponse = new ElementResponse(this, 5, Vector(162));
01664   }
01665   
01666   output.endTag(); // ElementOutput
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                 // Loop over the integration points
01712 
01713                 int cnt = 0;
01714 
01715                 for (int i = 0; i < nintu; i++) {
01716 
01717 
01718 
01719                         // Get material stress response
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 // calculate local shape functions
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         // solid phase
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 ) { // solid
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         } //end if
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                         } //end if
01838 
01839                 }
01840 
01841         }
01842 
01843 
01844 
01845 
01846 
01847 
01848 
01849 
01850 
01851         //Compute jacobian transformation
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         //Compute adjoint to jacobian
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         //Compute determinant of jacobian
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         //Compute jacobian inverse
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         } //end for j
01948 
01949 
01950 
01951 
01952 
01953         //Compute derivatives with repect to global coords.
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         } //end for k
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                         } //end if
01996 
01997                 }
01998 
01999         }
02000 
02001 
02002 
02003 
02004 
02005 }
02006 
02007 
02008 
02009 
02010 

Generated on Mon Oct 23 15:05:03 2006 for OpenSees by doxygen 1.5.0