Twenty_Eight_Node_BrickUP.cpp

Go to the documentation of this file.
00001 /* *********************************************************************
00002 
00003 **    OpenSees - Open System for Earthquake Engineering Simulation    **
00004 
00005 **          Pacific Earthquake Engineering Research Center            **
00006 
00007 **                                                                    **
00008 
00009 **                                                                    **
00010 
00011 ** (C) Copyright 1999, The Regents of the University of California    **
00012 
00013 ** All Rights Reserved.                                               **
00014 
00015 **                                                                    **
00016 
00017 ** Commercial use of this program without express permission of the   **
00018 
00019 ** University of California, Berkeley, is strictly prohibited.  See   **
00020 
00021 ** file 'COPYRIGHT'  in main directory for information on usage and   **
00022 
00023 ** redistribution,  and for a DISCLAIMER OF ALL WARRANTIES.           **
00024 
00025 **                                                                    **
00026 
00027 ** Developed by:                                                      **
00028 
00029 **   Frank McKenna (fmckenna@ce.berkeley.edu)                         **
00030 
00031 **   Gregory L. Fenves (fenves@ce.berkeley.edu)                       **
00032 
00033 **   Filip C. Filippou (filippou@ce.berkeley.edu)                     **
00034 
00035 **                                                                    **
00036 
00037 ** ****************************************************************** */
00038 
00039 //
00040 
00041 // by Jinchi Lu and Zhaohui Yang (May 2004)
00042 
00043 //
00044 
00045 // 20-8 Noded TwentyEightNodeBrickUP element
00046 
00047 //
00048 
00049 
00050 
00051 #include <stdio.h>
00052 
00053 #include <stdlib.h>
00054 
00055 #include <math.h>
00056 
00057 
00058 
00059 #include <ID.h>
00060 
00061 #include <Vector.h>
00062 
00063 #include <Matrix.h>
00064 
00065 #include <Element.h>
00066 
00067 #include <Node.h>
00068 
00069 #include <Domain.h>
00070 
00071 #include <ErrorHandler.h>
00072 
00073 #include <Twenty_Eight_Node_BrickUP.h>
00074 
00075 #include <shp3d.h>
00076 
00077 #include <shp3dv.h>
00078 
00079 #include <Renderer.h>
00080 
00081 #include <ElementResponse.h>
00082 
00083 
00084 
00085 
00086 
00087 #include <Channel.h>
00088 
00089 #include <FEM_ObjectBroker.h>
00090 
00091 
00092 
00093 //static data
00094 
00095 double  TwentyEightNodeBrickUP::xl[3][20] ;
00096 
00097 
00098 
00099 Matrix  TwentyEightNodeBrickUP::stiff(68,68) ;
00100 
00101 Vector  TwentyEightNodeBrickUP::resid(68) ;
00102 
00103 Matrix  TwentyEightNodeBrickUP::mass(68,68) ;
00104 
00105 Matrix  TwentyEightNodeBrickUP::damp(68,68) ;
00106 
00107 
00108 
00109 const int TwentyEightNodeBrickUP::nintu=27;
00110 
00111 const int TwentyEightNodeBrickUP::nintp=8;
00112 
00113 const int TwentyEightNodeBrickUP::nenu=20;
00114 
00115 const int TwentyEightNodeBrickUP::nenp=8;
00116 
00117 double TwentyEightNodeBrickUP::shgu[4][20][27]; 
00118 
00119 double TwentyEightNodeBrickUP::shgp[4][8][8];
00120 
00121 double TwentyEightNodeBrickUP::shgq[4][20][8];  
00122 
00123 double TwentyEightNodeBrickUP::shlu[4][20][27]; 
00124 
00125 double TwentyEightNodeBrickUP::shlp[4][8][8];
00126 
00127 double TwentyEightNodeBrickUP::shlq[4][20][8];  
00128 
00129 double TwentyEightNodeBrickUP::wu[27];  
00130 
00131 double TwentyEightNodeBrickUP::wp[8];   
00132 
00133 double TwentyEightNodeBrickUP::dvolu[27]; 
00134 
00135 double TwentyEightNodeBrickUP::dvolp[8];  
00136 
00137 double TwentyEightNodeBrickUP::dvolq[8];  
00138 
00139 
00140 
00141 //null constructor
00142 
00143 TwentyEightNodeBrickUP::TwentyEightNodeBrickUP( ) :
00144 
00145 Element( 0, ELE_TAG_Twenty_Eight_Node_BrickUP ),
00146 
00147 connectedExternalNodes(20), load(0), Ki(0), kc(0), rho(0)
00148 
00149 {
00150 
00151   for (int i=0; i<20; i++ ) {
00152 
00153     nodePointers[i] = 0;
00154 
00155   }
00156 
00157   b[0] = b[1] = b[2] = 0.;
00158 
00159   perm[0] = perm[1] = perm[2] = 0.;
00160 
00161   
00162 
00163   // calculate local shape functions and derivatives
00164 
00165   compuLocalShapeFunction();
00166 
00167 }
00168 
00169 
00170 
00171 
00172 
00173 //*********************************************************************
00174 
00175 //full constructor
00176 
00177 TwentyEightNodeBrickUP::TwentyEightNodeBrickUP(int tag,
00178 
00179                                                int node1,
00180 
00181                                                int node2,
00182 
00183                                                int node3,
00184 
00185                                                int node4,
00186 
00187                                                int node5,
00188 
00189                                                int node6,
00190 
00191                                                int node7,
00192 
00193                                                int node8,
00194 
00195                                                int node9,
00196 
00197                                                int node10,
00198 
00199                                                int node11,
00200 
00201                                                int node12,
00202 
00203                                                int node13,
00204 
00205                                                int node14,
00206 
00207                                                int node15,
00208 
00209                                                int node16,
00210 
00211                                                int node17,
00212 
00213                                                int node18,
00214 
00215                                                int node19,
00216 
00217                                                int node20,
00218 
00219                                                NDMaterial &theMaterial, double bulk, double rhof,
00220 
00221                                                double p1, double p2, double p3,
00222 
00223                                                double b1, double b2, double b3) :Element( tag, ELE_TAG_Twenty_Eight_Node_BrickUP ),
00224 
00225 connectedExternalNodes(20), load(0), Ki(0), kc(bulk), rho(rhof)
00226 
00227 {
00228 
00229         connectedExternalNodes(0) = node1 ;
00230 
00231         connectedExternalNodes(1) = node2 ;
00232 
00233         connectedExternalNodes(2) = node3 ;
00234 
00235         connectedExternalNodes(3) = node4 ;
00236 
00237         connectedExternalNodes(4) = node5 ;
00238 
00239         connectedExternalNodes(5) = node6 ;
00240 
00241         connectedExternalNodes(6) = node7 ;
00242 
00243         connectedExternalNodes(7) = node8 ;
00244 
00245         connectedExternalNodes(8) = node9 ;
00246 
00247         connectedExternalNodes(9) = node10 ;
00248 
00249         connectedExternalNodes(10) = node11 ;
00250 
00251         connectedExternalNodes(11) = node12 ;
00252 
00253         connectedExternalNodes(12) = node13 ;
00254 
00255         connectedExternalNodes(13) = node14 ;
00256 
00257         connectedExternalNodes(14) = node15 ;
00258 
00259         connectedExternalNodes(15) = node16 ;
00260 
00261         connectedExternalNodes(16) = node17 ;
00262 
00263         connectedExternalNodes(17) = node18 ;
00264 
00265         connectedExternalNodes(18) = node19 ;
00266 
00267         connectedExternalNodes(19) = node20 ;
00268 
00269         
00270 
00271         int i ;
00272 
00273     // Allocate arrays of pointers to NDMaterials
00274 
00275     materialPointers = new NDMaterial *[nintu];
00276 
00277     
00278 
00279     if (materialPointers == 0) {
00280 
00281       opserr << "TwentyEightNodeBrickUP::TwentyEightNodeBrickUP - failed allocate material model pointer\n";
00282 
00283       exit(-1);
00284 
00285     }
00286 
00287     for ( i=0; i<nintu; i++ ) {
00288 
00289       
00290 
00291       materialPointers[i] = theMaterial.getCopy("ThreeDimensional") ;
00292 
00293       
00294 
00295       if (materialPointers[i] == 0) {
00296 
00297         opserr <<"TwentyEightNodeBrickUP::constructor - failed to get a material of type: ThreeDimensional\n";
00298 
00299         exit(-1);
00300 
00301       } //end if
00302 
00303       
00304 
00305     } //end for i
00306 
00307     
00308 
00309     // Body forces
00310 
00311     b[0] = b1;
00312 
00313     b[1] = b2;
00314 
00315     b[2] = b3;
00316 
00317     // Permeabilities
00318 
00319     perm[0] = p1;
00320 
00321     perm[1] = p2;
00322 
00323     perm[2] = p3;
00324 
00325     //printf("b %15.6e %15.6e %15.6e perm %15.6e %15.6e %15.6e\n", b1, b2,b3,p1,p2,p3);
00326 
00327     // calculate local shape functions and derivatives
00328 
00329     compuLocalShapeFunction();
00330 
00331     
00332 
00333 }
00334 
00335 //******************************************************************
00336 
00337 
00338 
00339 
00340 
00341 //destructor
00342 
00343 TwentyEightNodeBrickUP::~TwentyEightNodeBrickUP( )
00344 
00345 {
00346 
00347   int i ;
00348 
00349   for ( i = 0; i < nintu; i++) {
00350 
00351     if (materialPointers[i])
00352 
00353       delete materialPointers[i];
00354 
00355   }
00356 
00357   
00358 
00359   // Delete the array of pointers to NDMaterial pointer arrays
00360 
00361   if (materialPointers)
00362 
00363     delete [] materialPointers;
00364 
00365   
00366 
00367   for ( i=0 ; i<nenu; i++ ) {           
00368 
00369     nodePointers[i] = 0 ;               
00370 
00371   } //end for i
00372 
00373   
00374 
00375   if (load != 0)
00376 
00377     delete load;
00378 
00379   
00380 
00381   if (Ki != 0)
00382 
00383     delete Ki;
00384 
00385 }
00386 
00387 
00388 
00389 
00390 
00391 //set domain
00392 
00393 void  TwentyEightNodeBrickUP::setDomain( Domain *theDomain )
00394 
00395 {
00396 
00397   int i,dof ;
00398 
00399   
00400 
00401   // Check Domain is not null - invoked when object removed from a domain
00402 
00403   if (theDomain == 0) {
00404 
00405     for ( i=0; i<nenu; i++ )
00406 
00407       nodePointers[i] = 0;
00408 
00409     return;
00410 
00411   }
00412 
00413   
00414 
00415   //node pointers
00416 
00417   for ( i=0; i<nenu; i++ ) {
00418 
00419     nodePointers[i] = theDomain->getNode( connectedExternalNodes(i) ) ;
00420 
00421     if (nodePointers[i] == 0) {
00422 
00423       opserr << "FATAL ERROR TwentyEightNodeBrickUP ("<<this->getTag()<<"): node not found in domain"<<endln;
00424 
00425       return;
00426 
00427     }
00428 
00429     
00430 
00431     dof = nodePointers[i]->getNumberDOF();
00432 
00433     if( (i<nenp && dof != 4) || (i>=nenp && dof != 3) ) {
00434 
00435       opserr << "FATAL ERROR TwentyEightNodeBrickUP ("<<this->getTag()<<"): has wrong number of DOFs at its nodes"<<endln;
00436 
00437       return;
00438 
00439     }
00440 
00441   }
00442 
00443   this->DomainComponent::setDomain(theDomain);
00444 
00445 }
00446 
00447 
00448 
00449 
00450 
00451 //get the number of external nodes
00452 
00453 int  TwentyEightNodeBrickUP::getNumExternalNodes( ) const
00454 
00455 {
00456 
00457   return nenu ;
00458 
00459 }
00460 
00461 
00462 
00463 
00464 
00465 //return connected external nodes
00466 
00467 const ID&  TwentyEightNodeBrickUP::getExternalNodes( )
00468 
00469 {
00470 
00471         return connectedExternalNodes ;
00472 
00473 }
00474 
00475 
00476 
00477 //return connected external node
00478 
00479 Node **
00480 
00481 TwentyEightNodeBrickUP::getNodePtrs(void)
00482 
00483 {
00484 
00485         return nodePointers ;
00486 
00487 }
00488 
00489 
00490 
00491 
00492 
00493 //return number of dofs
00494 
00495 int  TwentyEightNodeBrickUP::getNumDOF( )
00496 
00497 {
00498 
00499         return 68 ;
00500 
00501 }
00502 
00503 
00504 
00505 
00506 
00507 //commit state
00508 
00509 int  TwentyEightNodeBrickUP::commitState( )
00510 
00511 {
00512 
00513         int success = 0 ;
00514 
00515         
00516 
00517         // call element commitState to do any base class stuff
00518 
00519         if ((success = this->Element::commitState()) != 0) {
00520 
00521                 opserr << "TwentyEightNodeBrickUP::commitState () - failed in base class";
00522 
00523         }
00524 
00525         
00526 
00527         for (int i=0; i<nintu; i++ )
00528 
00529                 success += materialPointers[i]->commitState( ) ;
00530 
00531         
00532 
00533         return success ;
00534 
00535 }
00536 
00537 
00538 
00539 
00540 
00541 
00542 
00543 //revert to last commit
00544 
00545 int  TwentyEightNodeBrickUP::revertToLastCommit( )
00546 
00547 {
00548 
00549         int i ;
00550 
00551         int success = 0 ;
00552 
00553         
00554 
00555         for ( i=0; i<nintu; i++ )
00556 
00557                 success += materialPointers[i]->revertToLastCommit( ) ;
00558 
00559         
00560 
00561         return success ;
00562 
00563 }
00564 
00565 
00566 
00567 
00568 
00569 //revert to start
00570 
00571 int  TwentyEightNodeBrickUP::revertToStart( )
00572 
00573 {
00574 
00575         int i ;
00576 
00577         int success = 0 ;
00578 
00579         
00580 
00581         for ( i=0; i<nintu; i++ )
00582 
00583                 success += materialPointers[i]->revertToStart( ) ;
00584 
00585         
00586 
00587         return success ;
00588 
00589 }
00590 
00591 
00592 
00593 //print out element data
00594 
00595 void  TwentyEightNodeBrickUP::Print( OPS_Stream &s, int flag )
00596 
00597 {
00598 
00599         
00600 
00601         if (flag == 2) {
00602 
00603                 
00604 
00605                 s << "#20_8_BrickUP\n";
00606 
00607                 
00608 
00609                 int i;
00610 
00611                 const int numNodes = 20;
00612 
00613                 const int nstress = 6 ;
00614 
00615                 
00616 
00617                 for (i=0; i<numNodes; i++) {
00618 
00619                         const Vector &nodeCrd = nodePointers[i]->getCrds();
00620 
00621                         const Vector &nodeDisp = nodePointers[i]->getDisp();
00622 
00623                         s << "#NODE " << nodeCrd(0) << " " << nodeCrd(1) << " " << nodeCrd(2)
00624 
00625                                 << " " << nodeDisp(0) << " " << nodeDisp(1) << " " << nodeDisp(2) << endln;
00626 
00627                 }
00628 
00629                 
00630 
00631                 // spit out the section location & invoke print on the scetion
00632 
00633                 const int numMaterials = nintu;
00634 
00635                 
00636 
00637                 static Vector avgStress(7);
00638 
00639                 static Vector avgStrain(nstress);
00640 
00641                 avgStress.Zero();
00642 
00643                 avgStrain.Zero();
00644 
00645                 for (i=0; i<numMaterials; i++) {
00646 
00647                         avgStress += materialPointers[i]->getCommittedStress();
00648 
00649                         avgStrain += materialPointers[i]->getCommittedStrain();
00650 
00651                 }
00652 
00653                 avgStress /= numMaterials;
00654 
00655                 avgStrain /= numMaterials;
00656 
00657                 
00658 
00659                 s << "#AVERAGE_STRESS ";
00660 
00661                 for (i=0; i<7; i++)
00662 
00663                         s << avgStress(i) << " " ;
00664 
00665                 s << endln;
00666 
00667                 
00668 
00669                 s << "#AVERAGE_STRAIN ";
00670 
00671                 for (i=0; i<nstress; i++)
00672 
00673                         s << avgStrain(i) << " " ;
00674 
00675                 s << endln;
00676 
00677                 
00678 
00679                 /*
00680 
00681                 for (i=0; i<numMaterials; i++) {
00682 
00683                 s << "#MATERIAL\n";
00684 
00685                 //      materialPointers[i]->Print(s, flag);
00686 
00687                 s << materialPointers[i]->getStress();
00688 
00689                 }
00690 
00691                 */
00692 
00693                 
00694 
00695         } else {
00696 
00697                 
00698 
00699                 s << endln ;
00700 
00701                 s << "20-8 Noded TwentyEightNodeBrickUP \n" ;
00702 
00703                 s << "Element Number: " << this->getTag() << endln ;
00704 
00705                 s << "Node 1 : " << connectedExternalNodes(0) << endln ;
00706 
00707                 s << "Node 2 : " << connectedExternalNodes(1) << endln ;
00708 
00709                 s << "Node 3 : " << connectedExternalNodes(2) << endln ;
00710 
00711                 s << "Node 4 : " << connectedExternalNodes(3) << endln ;
00712 
00713                 s << "Node 5 : " << connectedExternalNodes(4) << endln ;
00714 
00715                 s << "Node 6 : " << connectedExternalNodes(5) << endln ;
00716 
00717                 s << "Node 7 : " << connectedExternalNodes(6) << endln ;
00718 
00719                 s << "Node 8 : " << connectedExternalNodes(7) << endln ;
00720 
00721                 s << "Node 9 : " << connectedExternalNodes(8) << endln ;
00722 
00723                 s << "Node 10 : " << connectedExternalNodes(9) << endln ;
00724 
00725                 s << "Node 11 : " << connectedExternalNodes(10) << endln ;
00726 
00727                 s << "Node 12 : " << connectedExternalNodes(11) << endln ;
00728 
00729                 s << "Node 13 : " << connectedExternalNodes(12) << endln ;
00730 
00731                 s << "Node 14 : " << connectedExternalNodes(13) << endln ;
00732 
00733                 s << "Node 15 : " << connectedExternalNodes(14) << endln ;
00734 
00735                 s << "Node 16 : " << connectedExternalNodes(15) << endln ;
00736 
00737                 s << "Node 17 : " << connectedExternalNodes(16) << endln ;
00738 
00739                 s << "Node 18 : " << connectedExternalNodes(17) << endln ;
00740 
00741                 s << "Node 19 : " << connectedExternalNodes(18) << endln ;
00742 
00743                 s << "Node 20 : " << connectedExternalNodes(19) << endln ;
00744 
00745                 
00746 
00747                 s << "Material Information : \n " ;
00748 
00749                 materialPointers[0]->Print( s, flag ) ;
00750 
00751                 
00752 
00753                 s << endln ;
00754 
00755         }
00756 
00757 }
00758 
00759 
00760 
00761 int
00762 
00763 TwentyEightNodeBrickUP::update()
00764 
00765 {
00766 
00767         int i, j, k, k1;
00768 
00769         static double u[3][20];
00770 
00771         static double xsj;
00772 
00773         static Matrix B(6, 3);
00774 
00775         double volume = 0.;
00776 
00777 
00778 
00779         for (i = 0; i < nenu; i++) {
00780 
00781              const Vector &disp = nodePointers[i]->getTrialDisp();
00782 
00783              u[0][i] = disp(0);
00784 
00785              u[1][i] = disp(1);
00786 
00787              u[2][i] = disp(2);
00788 
00789     }
00790 
00791 
00792 
00793         static Vector eps(6);
00794 
00795 
00796 
00797         int ret = 0;
00798 
00799 
00800 
00801         //compute basis vectors and local nodal coordinates
00802 
00803         computeBasis( ) ;
00804 
00805         
00806 
00807         for( i = 0; i < nintu; i++ ) {
00808 
00809                 // compute Jacobian and global shape functions
00810 
00811                 Jacobian3d(i, xsj, 0);          
00812 
00813                 //volume element to also be saved
00814 
00815                 dvolu[i] = wu[i] * xsj ;
00816 
00817                 volume += dvolu[i];
00818 
00819         } // end for i
00820 
00821     //printf("volume = %f\n", volume);
00822 
00823 
00824 
00825         // Loop over the integration points
00826 
00827         for (i = 0; i < nintu; i++) {
00828 
00829 
00830 
00831                 // Interpolate strains
00832 
00833                 //eps = B*u;
00834 
00835                 //eps.addMatrixVector(0.0, B, u, 1.0);
00836 
00837                 eps.Zero();
00838 
00839                 for ( j = 0; j < nenu; j++) {
00840 
00841 
00842 
00843 
00844 
00845                         B(0,0) = shgu[0][j][i];
00846 
00847                         B(0,1) = 0.;
00848 
00849                         B(0,2) = 0.;
00850 
00851                         B(1,0) = 0.;
00852 
00853                         B(1,1) = shgu[1][j][i];
00854 
00855                         B(1,2) = 0.;
00856 
00857                         B(2,0) = 0.;
00858 
00859                         B(2,1) = 0.;
00860 
00861                         B(2,2) = shgu[2][j][i];
00862 
00863                         B(3,0) = shgu[1][j][i];
00864 
00865                         B(3,1) = shgu[0][j][i];
00866 
00867                         B(3,2) = 0.;
00868 
00869                         B(4,0) = 0.;
00870 
00871                         B(4,1) = shgu[2][j][i];
00872 
00873                         B(4,2) = shgu[1][j][i];
00874 
00875                         B(5,0) = shgu[2][j][i];
00876 
00877                         B(5,1) = 0.;
00878 
00879                         B(5,2) = shgu[0][j][i];
00880 
00881 
00882 
00883                         //BJ = computeB( j, shp ) ;
00884 
00885                         
00886 
00887                         //nodal displacements 
00888 
00889                         const Vector &ul = nodePointers[j]->getTrialDisp( ) ;
00890 
00891                         Vector ul3(3);
00892 
00893                         ul3(0) = ul(0);
00894 
00895                         ul3(1) = ul(1);
00896 
00897                         ul3(2) = ul(2);
00898 
00899                         //compute the strain
00900 
00901                         //strain += (BJ*ul) ; 
00902 
00903                         eps.addMatrixVector(1.0,B,ul3,1.0 ) ;
00904 
00905                         
00906 
00907                         /* for( k = 0; k < 6; k++) {
00908 
00909                         for( k1 = 0; k1 < 3; k1++) {
00910 
00911                         eps[k] += BJ(k, k1)*u[k1][j];
00912 
00913                         }
00914 
00915                 }       */
00916 
00917 
00918 
00919 
00920 
00921                 }
00922 
00923 
00924 
00925                 // Set the material strain
00926 
00927                 ret += materialPointers[i]->setTrialStrain(eps);
00928 
00929         }
00930 
00931 
00932 
00933         return ret;
00934 
00935 }
00936 
00937 
00938 
00939 //return tangent stiffness matrix
00940 
00941 const Matrix&  TwentyEightNodeBrickUP::getTangentStiff( )
00942 
00943 {
00944 
00945         return getStiff( 1 );
00946 
00947 }
00948 
00949 
00950 
00951 // return initial stiffness matrix
00952 
00953 const Matrix&  TwentyEightNodeBrickUP::getInitialStiff( )
00954 
00955 {
00956 
00957         return getStiff( 0 );
00958 
00959 }
00960 
00961 
00962 
00963 // compute stiffness matrix
00964 
00965 const Matrix&  TwentyEightNodeBrickUP::getStiff( int flag )
00966 
00967 {
00968 
00969         if (flag != 0 && flag != 1) {
00970 
00971                 opserr << "FATAL TwentyEightNodeBrickUP::getStiff() - illegal use\n";
00972 
00973                 exit(-1);
00974 
00975         }  
00976 
00977         
00978 
00979         if (flag == 0 && Ki != 0)
00980 
00981                 return *Ki;
00982 
00983         
00984 
00985         int i, j ;
00986 
00987         
00988 
00989         static double xsj ;  // determinant jacaobian matrix
00990 
00991         double volume = 0.;
00992 
00993         //-------------------------------------------------------
00994 
00995         int j3, j3m1, j3m2, ik, ib, jk, jb;
00996 
00997         static Matrix B(6,nenu*3);
00998 
00999         static Matrix BTDB(nenu*3,nenu*3);
01000 
01001         static Matrix D(6, 6);
01002 
01003         B.Zero(); 
01004 
01005         BTDB.Zero();
01006 
01007         stiff.Zero();
01008 
01009         
01010 
01011         //compute basis vectors and local nodal coordinates
01012 
01013         computeBasis( ) ;
01014 
01015         
01016 
01017         for( i = 0; i < nintu; i++ ) {
01018 
01019                 // compute Jacobian and global shape functions
01020 
01021                 Jacobian3d(i, xsj, 0);          
01022 
01023                 //volume element to also be saved
01024 
01025                 dvolu[i] = wu[i] * xsj ;
01026 
01027                 volume += dvolu[i];
01028 
01029         } // end for i
01030 
01031     //printf("volume = %f\n", volume);
01032 
01033 
01034 
01035 //      for( i = 0; i < nintu; i++ ) {
01036 
01037 //              for(int j = 0; j < nenu; j++ ) {
01038 
01039 //                      printf("%5d %5d %15.6e %15.6e %15.6e %15.6e\n", i,j, 
01040 
01041 //                              shgu[0][j][i], shgu[1][j][i], shgu[2][j][i], shgu[3][j][i]);
01042 
01043 //              }
01044 
01045 //      }
01046 
01047 //      exit(-1);
01048 
01049 
01050 
01051         // Loop over the integration points
01052 
01053         for (i = 0; i < nintu; i++) {
01054 
01055                 
01056 
01057                 // Get the material tangent
01058 
01059                 if( flag == 0 )
01060 
01061                         D = materialPointers[i]->getInitialTangent();
01062 
01063                 else
01064 
01065                         D = materialPointers[i]->getTangent();
01066 
01067                 //const Matrix &D = materialPointers[i]->getTangent();
01068 
01069                 
01070 
01071                 
01072 
01073                 for (j=0; j<nenu; j++) {
01074 
01075                         
01076 
01077                         j3   = 3*j+2;
01078 
01079                         j3m1 = j3 - 1;
01080 
01081                         j3m2 = j3 - 2;
01082 
01083                         
01084 
01085                         B(0,j3m2) = shgu[0][j][i];
01086 
01087                         B(0,j3m1) = 0.;
01088 
01089                         B(0,j3  ) = 0.;
01090 
01091 
01092 
01093                         B(1,j3m2) = 0.;
01094 
01095                         B(1,j3m1) = shgu[1][j][i];
01096 
01097                         B(1,j3  ) = 0.;
01098 
01099                         
01100 
01101                         B(2,j3m2) = 0.;
01102 
01103                         B(2,j3m1) = 0.;
01104 
01105                         B(2,j3  ) = shgu[2][j][i];
01106 
01107                         
01108 
01109                         B(3,j3m2) = shgu[1][j][i];
01110 
01111                         B(3,j3m1) = shgu[0][j][i];
01112 
01113                         B(3,j3  ) = 0.;
01114 
01115                         
01116 
01117                         B(4,j3m2) = 0.;
01118 
01119                         B(4,j3m1) = shgu[2][j][i];
01120 
01121                         B(4,j3  ) = shgu[1][j][i];
01122 
01123                         
01124 
01125                         B(5,j3m2) = shgu[2][j][i];
01126 
01127                         B(5,j3m1) = 0.;
01128 
01129                         B(5,j3  ) = shgu[0][j][i];
01130 
01131                         
01132 
01133                 }
01134 
01135                 
01136 
01137                 // Perform numerical integration
01138 
01139                 //K = K + (B^ D * B) * intWt(i) * detJ;
01140 
01141                 BTDB.addMatrixTripleProduct(1.0, B, D, dvolu[i]);
01142 
01143         }
01144 
01145         
01146 
01147         for (i = 0; i < nenu; i++) {
01148 
01149                 if (i<nenp) 
01150 
01151                         ik = i*4;
01152 
01153                 else
01154 
01155                         ik = nenp*4 + (i-nenp)*3;
01156 
01157                 ib = i*3;
01158 
01159                 
01160 
01161                 for (j = 0; j < nenu; j++) {
01162 
01163                         if (j<nenp)
01164 
01165                                 jk = j*4;
01166 
01167                         else
01168 
01169                                 jk = nenp*4 + (j-nenp)*3;
01170 
01171                         jb = j*3;
01172 
01173                         for( int i1 = 0; i1 < 3; i1++)
01174 
01175                                 for(int j1 = 0; j1 < 3; j1++) {
01176 
01177                                         stiff(ik+i1, jk+j1) = BTDB(ib+i1,jb+j1);
01178 
01179                                 }
01180 
01181                 }
01182 
01183         }
01184 
01185         if( flag == 1) {
01186 
01187                 return stiff;
01188 
01189         }
01190 
01191         Ki = new Matrix(stiff);
01192 
01193         if (Ki == 0) {
01194 
01195                 opserr << "FATAL TwentyEightNodeBrickUP::getStiff() -";
01196 
01197                 opserr << "ran out of memory\n";
01198 
01199                 exit(-1);
01200 
01201         }  
01202 
01203     
01204 
01205         return *Ki;
01206 
01207 }
01208 
01209 
01210 
01211 
01212 
01213 //return mass matrix
01214 
01215 const Matrix&  TwentyEightNodeBrickUP::getMass( )
01216 
01217 {
01218 
01219         int tangFlag = 1 ;
01220 
01221         
01222 
01223         formInertiaTerms( tangFlag ) ;
01224 
01225         
01226 
01227         return mass ;
01228 
01229 }
01230 
01231 
01232 
01233 
01234 
01235 //return mass matrix
01236 
01237 const Matrix&  TwentyEightNodeBrickUP::getDamp( )
01238 
01239 {
01240 
01241         int tangFlag = 1 ;
01242 
01243         
01244 
01245         formDampingTerms( tangFlag ) ;
01246 
01247         
01248 
01249         return damp ;
01250 
01251 }
01252 
01253 
01254 
01255 void TwentyEightNodeBrickUP::formDampingTerms( int tangFlag )
01256 
01257 {
01258 
01259         static double xsj ;  // determinant jacaobian matrix
01260 
01261         int i, j, k, m, ik, jk;
01262 
01263         double volume = 0.;
01264 
01265         //zero damp
01266 
01267         damp.Zero( ) ;
01268 
01269         
01270 
01271         if (betaK != 0.0)
01272 
01273                 damp.addMatrix(1.0, this->getTangentStiff(), betaK);
01274 
01275         if (betaK0 != 0.0)
01276 
01277                 damp.addMatrix(1.0, this->getInitialStiff(), betaK0);
01278 
01279         if (betaKc != 0.0)
01280 
01281                 damp.addMatrix(1.0, *Kc, betaKc);       
01282 
01283         
01284 
01285         if (alphaM != 0.0) {
01286 
01287                 this->getMass();
01288 
01289                 for( i = 0; i < nenu; i++ ) {
01290 
01291                         if( i < nenp) 
01292 
01293                                 ik = i*4;
01294 
01295                         else
01296 
01297                                 ik = nenp*4 + (i - nenp) * 3;
01298 
01299                         for( j = 0; j < nenu; j++) {
01300 
01301                                 if( j < nenp) 
01302 
01303                                         jk = j * 4;
01304 
01305                                 else
01306 
01307                                         jk = nenp * 4 + (j-nenp) * 3;
01308 
01309                                 for( k = 0; k < 3; k++)
01310 
01311                                         damp(ik + k, jk + k) += mass(ik + k, jk + k) * alphaM;
01312 
01313                         }
01314 
01315                 }                               
01316 
01317         }
01318 
01319         
01320 
01321         //compute basis vectors and local nodal coordinates
01322 
01323         computeBasis( ) ;       
01324 
01325         //gauss loop to compute and save shape functions
01326 
01327         for( i = 0; i < nintp; i++ ) {
01328 
01329                 // compute Jacobian and global shape functions
01330 
01331                 Jacobian3d(i, xsj, 1);          
01332 
01333                 //volume element to also be saved
01334 
01335                 dvolp[i] = wp[i] * xsj ;
01336 
01337                 volume += dvolp[i];
01338 
01339         } // end for i
01340 
01341         //printf("volume = %f\n", volume);
01342 
01343         
01344 
01345         volume = 0.;
01346 
01347         for( i = 0; i < nintp; i++ ) {
01348 
01349                 // compute Jacobian and global shape functions
01350 
01351                 Jacobian3d(i, xsj, 2);          
01352 
01353                 //volume element to also be saved
01354 
01355                 dvolq[i] = wp[i] * xsj ;        
01356 
01357                 volume += dvolq[i];
01358 
01359         } // end for i
01360 
01361         //printf("volume = %f\n", volume);
01362 
01363 
01364 
01365         // Compute coupling matrix
01366 
01367         for( i = 0; i < nenu; i++ ) {
01368 
01369                 if( i < nenp) 
01370 
01371                         ik = i * 4;
01372 
01373                 else
01374 
01375                         ik = nenp * 4 + (i-nenp)*3;
01376 
01377                 for( j = 0; j < nenp; j++) {
01378 
01379                         jk = j * 4 + 3;
01380 
01381                         for( m = 0; m < nintp; m++) {
01382 
01383                                 for( k = 0; k < 3; k++) {
01384 
01385                                         damp(ik+k,jk) += -dvolq[m]*shgq[k][i][m]*shgp[3][j][m];
01386 
01387                                 }
01388 
01389                         }
01390 
01391                         for( k = 0; k < 3; k++ ) {
01392 
01393                                 damp(jk, ik+k) = damp(ik+k, jk);
01394 
01395                         }
01396 
01397                 }
01398 
01399         }
01400 
01401         // Compute permeability matrix
01402 
01403         for( i = 0; i < nenp; i++ ) {
01404 
01405                 ik = i*4 + 3;
01406 
01407                 for( j = 0; j < nenp; j++ ) {
01408 
01409                         jk = j * 4 + 3;
01410 
01411                         for( m = 0; m < nintp; m++ ) {
01412 
01413                                 damp(ik,jk) += - dvolp[m]*(perm[0]*shgp[0][i][m]*shgp[0][j][m] +
01414 
01415                                         perm[1]*shgp[1][i][m]*shgp[1][j][m]+
01416 
01417                                         perm[2]*shgp[2][i][m]*shgp[2][j][m]);
01418 
01419                         }
01420 
01421                 }
01422 
01423         }
01424 
01425 }
01426 
01427 
01428 
01429 
01430 
01431 void  TwentyEightNodeBrickUP::zeroLoad( )
01432 
01433 {
01434 
01435         if (load != 0)
01436 
01437                 load->Zero();
01438 
01439         
01440 
01441         return ;
01442 
01443 }
01444 
01445 
01446 
01447 
01448 
01449 int
01450 
01451 TwentyEightNodeBrickUP::addLoad(ElementalLoad *theLoad, double loadFactor)
01452 
01453 {
01454 
01455         opserr << "TwentyEightNodeBrickUP::addLoad - load type unknown for truss with tag: " << this->getTag() << endln;
01456 
01457         return -1;
01458 
01459 }
01460 
01461 
01462 
01463 int
01464 
01465 TwentyEightNodeBrickUP::addInertiaLoadToUnbalance(const Vector &accel)
01466 
01467 {
01468 
01469         static Vector ra(68);
01470 
01471         int i, j, ik;
01472 
01473         ra.Zero();
01474 
01475         
01476 
01477         for( i = 0; i < nenu; i++) {
01478 
01479                 const Vector &Raccel = nodePointers[i]->getRV(accel);
01480 
01481                 if ((i<nenp && 4 != Raccel.Size()) || (i>=nenp && 3 != Raccel.Size())) {
01482 
01483                         opserr << "TwentyEightNodeBrickUP::addInertiaLoadToUnbalance matrix and vector sizes are incompatable\n";
01484 
01485                         return -1;
01486 
01487                 }
01488 
01489                 
01490 
01491                 if (i<nenp) 
01492 
01493                         ik = i*4;
01494 
01495                 else
01496 
01497                         ik = nenp*4 + (i-nenp)*3;
01498 
01499                 
01500 
01501                 ra[ik] = Raccel(0);
01502 
01503                 ra[ik+1] = Raccel(1);
01504 
01505                 ra[ik+2] = Raccel(2);
01506 
01507         }
01508 
01509         
01510 
01511         // Compute mass matrix
01512 
01513         int tangFlag = 1 ;
01514 
01515         formInertiaTerms( tangFlag ) ;
01516 
01517         
01518 
01519         // create the load vector if one does not exist
01520 
01521         if (load == 0)
01522 
01523           load = new Vector(68);
01524 
01525         
01526 
01527         // add -M * RV(accel) to the load vector
01528 
01529         load->addMatrixVector(1.0, mass, ra, -1.0);
01530 
01531         //for( i = 0; i < 68; i++) {
01532 
01533         //      for( j = 0; j < 68; j++)                        
01534 
01535         //                              load(i) += -mass(i,j)*ra[j];
01536 
01537         //}
01538 
01539         
01540 
01541         return 0;
01542 
01543 }
01544 
01545 
01546 
01547 
01548 
01549 //get residual
01550 
01551 const Vector&  TwentyEightNodeBrickUP::getResistingForce( )
01552 
01553 {
01554 
01555         int i, j, jk, k, k1;
01556 
01557         double xsj;
01558 
01559         static Matrix B(6, 3);
01560 
01561         double volume = 0.;
01562 
01563         
01564 
01565 //      printf("calling getResistingForce()\n");
01566 
01567         resid.Zero();
01568 
01569         
01570 
01571         //compute basis vectors and local nodal coordinates
01572 
01573         computeBasis( ) ;       
01574 
01575         //gauss loop to compute and save shape functions
01576 
01577         for( i = 0; i < nintu; i++ ) {
01578 
01579                 // compute Jacobian and global shape functions
01580 
01581                 Jacobian3d(i, xsj, 0);          
01582 
01583                 //volume element to also be saved
01584 
01585                 dvolu[i] = wu[i] * xsj ;
01586 
01587                 volume += dvolu[i];
01588 
01589         } // end for i
01590 
01591         //printf("volume = %f\n", volume);
01592 
01593         volume = 0.;
01594 
01595         for( i = 0; i < nintp; i++ ) {
01596 
01597                 // compute Jacobian and global shape functions
01598 
01599                 Jacobian3d(i, xsj, 1);          
01600 
01601                 //volume element to also be saved
01602 
01603                 dvolp[i] = wp[i] * xsj ;        
01604 
01605                 volume += dvolp[i];
01606 
01607         } // end for i
01608 
01609         //printf("volume = %f\n", volume);
01610 
01611         
01612 
01613         // Loop over the integration points
01614 
01615         for (i = 0; i < nintu; i++) {
01616 
01617                 
01618 
01619                 // Get material stress response
01620 
01621                 const Vector &sigma = materialPointers[i]->getStress();
01622 
01623                 
01624 
01625                 // Perform numerical integration on internal force
01626 
01627                 //P = P + (B^ sigma) * intWt(i)*intWt(j) * detJ;
01628 
01629                 //P.addMatrixTransposeVector(1.0, B, sigma, intWt(i)*intWt(j)*detJ);
01630 
01631                 for (j = 0; j < nenu; j++) {
01632 
01633                         if (j<nenp) 
01634 
01635                                 jk = j*4;
01636 
01637                         else
01638 
01639                                 jk = nenp*4 + (j-nenp)*3;
01640 
01641                         
01642 
01643                         B(0,0) = shgu[0][j][i];
01644 
01645                         B(0,1) = 0.;
01646 
01647                         B(0,2) = 0.;
01648 
01649                         B(1,0) = 0.;
01650 
01651                         B(1,1) = shgu[1][j][i];
01652 
01653                         B(1,2) = 0.;
01654 
01655                         B(2,0) = 0.;
01656 
01657                         B(2,1) = 0.;
01658 
01659                         B(2,2) = shgu[2][j][i];
01660 
01661                         B(3,0) = shgu[1][j][i];
01662 
01663                         B(3,1) = shgu[0][j][i];
01664 
01665                         B(3,2) = 0.;
01666 
01667                         B(4,0) = 0.;
01668 
01669                         B(4,1) = shgu[2][j][i];
01670 
01671                         B(4,2) = shgu[1][j][i];
01672 
01673                         B(5,0) = shgu[2][j][i];
01674 
01675                         B(5,1) = 0.;
01676 
01677                         B(5,2) = shgu[0][j][i];
01678 
01679                         
01680 
01681                         
01682 
01683                         for(k = 0; k < 3; k++) {
01684 
01685                                 for(k1 = 0; k1 < 6; k1++)
01686 
01687                                         resid(jk+k) += dvolu[i]*(B(k1,k)*sigma(k1));
01688 
01689                         }
01690 
01691                         // Subtract equiv. body forces from the nodes
01692 
01693                         //P = P - (N^ b) * intWt(i)*intWt(j) * detJ;
01694 
01695                         //P.addMatrixTransposeVector(1.0, N, b, -intWt(i)*intWt(j)*detJ);
01696 
01697                         double r = mixtureRho(i);
01698 
01699                         resid(jk) -= dvolu[i]*(shgu[3][j][i]*r*b[0]);
01700 
01701                         resid(jk+1) -= dvolu[i]*(shgu[3][j][i]*r*b[1]);
01702 
01703                         resid(jk+2) -= dvolu[i]*(shgu[3][j][i]*r*b[2]);
01704 
01705                 }
01706 
01707         }
01708 
01709         
01710 
01711         // Subtract fluid body force
01712 
01713         for (j = 0; j < nenp; j++) {
01714 
01715                 jk = j*4+3;
01716 
01717                 for (i = 0; i < nintp; i++) {
01718 
01719                         resid(jk) += dvolp[i]*rho*(perm[0]*b[0]*shgp[0][j][i] +
01720 
01721                                 perm[1]*b[1]*shgp[1][j][i] + perm[2]*b[2]*shgp[2][j][i]);
01722 
01723                 }
01724 
01725         }
01726 
01727         
01728 
01729         // Subtract other external nodal loads ... P_res = P_int - P_ext
01730 
01731 //      opserr<<"resid before:"<<resid<<endln; 
01732 
01733 
01734 
01735         if (load != 0)
01736 
01737                 resid -= *load;
01738 
01739 
01740 
01741 //      opserr<<"resid "<<resid<<endln; 
01742 
01743         
01744 
01745         return resid ;
01746 
01747 }
01748 
01749 
01750 
01751 
01752 
01753 //get residual with inertia terms
01754 
01755 const Vector&  TwentyEightNodeBrickUP::getResistingForceIncInertia( )
01756 
01757 {
01758 
01759         static Vector res(68);
01760 
01761         
01762 
01763         int i, j, ik;
01764 
01765         static double a[68];
01766 
01767         
01768 
01769         for (i=0; i<nenu; i++) {
01770 
01771                 const Vector &accel = nodePointers[i]->getTrialAccel();
01772 
01773                 if ((i<nenp && 4 != accel.Size()) || (i>=nenp && 3 != accel.Size())) {
01774 
01775                         opserr << "TwentyEightNodeBrickUP::getResistingForceIncInertia matrix and vector sizes are incompatable\n";
01776 
01777                         exit(-1);
01778 
01779                 }
01780 
01781                 
01782 
01783                 if (i<nenp) 
01784 
01785                         ik = i*4;
01786 
01787                 else
01788 
01789                         ik = nenp*4 + (i-nenp)*3;
01790 
01791                 a[ik] = accel(0);
01792 
01793                 a[ik+1] = accel(1);
01794 
01795                 a[ik+2] = accel(2);
01796 
01797                 if (i<nenp) a[ik+3] = accel(3);
01798 
01799         }
01800 
01801         // Compute the current resisting force
01802 
01803         this->getResistingForce();
01804 
01805 //      opserr<<"K "<<resid<<endln;
01806 
01807         
01808 
01809         // Compute the mass matrix
01810 
01811         this->getMass();
01812 
01813 
01814 
01815         for (i = 0; i < 68; i++) {
01816 
01817                 for (j = 0; j < 68; j++){
01818 
01819                         resid(i) += mass(i,j)*a[j];
01820 
01821                 }
01822 
01823         }
01824 
01825 //      printf("\n");
01826 
01827         //opserr<<"K+M "<<P<<endln; 
01828 
01829         
01830 
01831         
01832 
01833         for (i=0; i<nenu; i++) {
01834 
01835                 const Vector &vel = nodePointers[i]->getTrialVel();
01836 
01837                 if ((i<nenp && 4 != vel.Size()) || (i>=nenp && 3 != vel.Size())) {
01838 
01839                         opserr << "TwentyEightNodeBrickUP::getResistingForceIncInertia matrix and vector sizes are incompatable\n";
01840 
01841                         exit(-1);
01842 
01843                 }
01844 
01845                 
01846 
01847                 if (i<nenp)
01848 
01849                         ik = i*4;
01850 
01851                 else
01852 
01853                         ik = nenp*4 + (i-nenp)*3;
01854 
01855                 a[ik] = vel(0);
01856 
01857                 a[ik+1] = vel(1);
01858 
01859                 a[ik+2] = vel(2);
01860 
01861                 if (i<nenp) a[ik+3] = vel(3);
01862 
01863         }
01864 
01865         
01866 
01867         this->getDamp();
01868 
01869         
01870 
01871         for (i = 0; i < 68; i++) {
01872 
01873                 for (j = 0; j < 68; j++) {
01874 
01875                         resid(i) += damp(i,j)*a[j];
01876 
01877                 }
01878 
01879         }
01880 
01881         
01882 
01883         res = resid;
01884 
01885 //      opserr<<"res "<<res<<endln; 
01886 
01887         
01888 
01889         return res;
01890 
01891 }
01892 
01893 
01894 
01895 
01896 
01897 //*********************************************************************
01898 
01899 //form inertia terms
01900 
01901 
01902 
01903 void   TwentyEightNodeBrickUP::formInertiaTerms( int tangFlag )
01904 
01905 {
01906 
01907         static double xsj ;  // determinant jacaobian matrix
01908 
01909         int i, j, k, ik, m, jk;
01910 
01911         double Nrho;
01912 
01913         
01914 
01915         //zero mass
01916 
01917         mass.Zero( ) ;
01918 
01919         
01920 
01921         //compute basis vectors and local nodal coordinates
01922 
01923         computeBasis( ) ;
01924 
01925         //gauss loop to compute and save shape functions
01926 
01927         for( i = 0; i < nintu; i++ ) {
01928 
01929                 // compute Jacobian and global shape functions
01930 
01931                 Jacobian3d(i, xsj, 0);          
01932 
01933                 //volume element to also be saved
01934 
01935                 dvolu[i] = wu[i] * xsj ;        
01936 
01937         } // end for i
01938 
01939         for( i = 0; i < nintp; i++ ) {
01940 
01941                 // compute Jacobian and global shape functions
01942 
01943                 Jacobian3d(i, xsj, 1);          
01944 
01945                 //volume element to also be saved
01946 
01947                 dvolp[i] = wp[i] * xsj ;        
01948 
01949         } // end for i
01950 
01951         
01952 
01953         // Compute consistent mass matrix
01954 
01955         for (i = 0; i < nenu; i++) {
01956 
01957                 if (i<nenp) 
01958 
01959                         ik = i*4;
01960 
01961                 else
01962 
01963                         ik = nenp*4 + (i-nenp)*3;
01964 
01965                 
01966 
01967                 for (j = 0; j < nenu; j++) {
01968 
01969                         if (j<nenp) 
01970 
01971                                 jk = j*4;
01972 
01973                         else
01974 
01975                                 jk = nenp*4 + (j-nenp)*3;
01976 
01977                         
01978 
01979                         for (m = 0; m < nintu; m++) {
01980 
01981                                 Nrho = dvolu[m]*mixtureRho(m)*shgu[3][i][m]*shgu[3][j][m];
01982 
01983                                 for( k = 0; k < 3; k++) {
01984 
01985                                         mass(ik+k,jk+k) += Nrho;
01986 
01987                                 }
01988 
01989                         }
01990 
01991                 }
01992 
01993         }
01994 
01995         
01996 
01997         // Compute compressibility matrix
01998 
01999         double oneOverKc = 1./kc;
02000 
02001         for (i = 0; i < nenp; i++) {
02002 
02003                 ik = i*4+3;
02004 
02005                 
02006 
02007                 for (j = 0; j < nenp; j++) {
02008 
02009                         jk = j*4+3;
02010 
02011                         
02012 
02013                         for (m = 0; m < nintp; m++) {
02014 
02015                                 mass(ik,jk) += -dvolp[m]*oneOverKc*shgp[3][i][m]*shgp[3][j][m];
02016 
02017                         }
02018 
02019                 }
02020 
02021         }
02022 
02023 }
02024 
02025 
02026 
02027 
02028 
02029 double TwentyEightNodeBrickUP::mixtureRho(int i)
02030 
02031 {
02032 
02033         double rhoi;
02034 
02035         
02036 
02037         rhoi= materialPointers[i]->getRho();
02038 
02039         //e = 0.7;  //theMaterial[i]->getVoidRatio();
02040 
02041         //n = e / (1.0 + e);
02042 
02043         //return n * rho + (1.0-n) * rhoi;
02044 
02045         return rhoi;
02046 
02047 }
02048 
02049 
02050 
02051 //************************************************************************
02052 
02053 //compute local coordinates and basis
02054 
02055 
02056 
02057 void   TwentyEightNodeBrickUP::computeBasis( )
02058 
02059 {
02060 
02061         
02062 
02063         //nodal coordinates
02064 
02065         
02066 
02067         int i ;
02068 
02069         for ( i = 0; i < nenu; i++ ) {
02070 
02071                 
02072 
02073                 const Vector &coorI = nodePointers[i]->getCrds( ) ;
02074 
02075                 
02076 
02077                 xl[0][i] = coorI(0) ;
02078 
02079                 xl[1][i] = coorI(1) ;
02080 
02081                 xl[2][i] = coorI(2) ;
02082 
02083                 
02084 
02085         }  //end for i
02086 
02087         
02088 
02089 }
02090 
02091 
02092 
02093 
02094 
02095 //**********************************************************************
02096 
02097 
02098 
02099 int  TwentyEightNodeBrickUP::sendSelf (int commitTag, Channel &theChannel)
02100 
02101 {
02102 
02103         int res = 0;
02104 
02105 
02106 
02107         // note: we don't check for dataTag == 0 for Element
02108 
02109         // objects as that is taken care of in a commit by the Domain
02110 
02111         // object - don't want to have to do the check if sending data
02112 
02113         int dataTag = this->getDbTag();
02114 
02115 
02116 
02117         // Quad packs its data into a Vector and sends this to theChannel
02118 
02119         // along with its dbTag and the commitTag passed in the arguments
02120 
02121 
02122 
02123         // Now quad sends the ids of its materials
02124 
02125         int matDbTag;
02126 
02127 
02128 
02129         static ID idData(75);
02130 
02131 
02132 
02133         idData(74) = this->getTag();
02134 
02135 
02136 
02137         int i;
02138 
02139         for (i = 0; i < nintu; i++) {
02140 
02141                 idData(i) = materialPointers[i]->getClassTag();
02142 
02143                 matDbTag = materialPointers[i]->getDbTag();
02144 
02145                 // NOTE: we do have to ensure that the material has a database
02146 
02147                 // tag if we are sending to a database channel.
02148 
02149                 if (matDbTag == 0) {
02150 
02151                         matDbTag = theChannel.getDbTag();
02152 
02153                         if (matDbTag != 0)
02154 
02155                                 materialPointers[i]->setDbTag(matDbTag);
02156 
02157                 }
02158 
02159                 idData(i+nintu) = matDbTag;
02160 
02161         }
02162 
02163         for( i = 0; i < 20; i++)
02164 
02165                 idData(54+i) = connectedExternalNodes(i);
02166 
02167 
02168 
02169 
02170 
02171         res += theChannel.sendID(dataTag, commitTag, idData);
02172 
02173         if (res < 0) {
02174 
02175                 opserr << "WARNING TwentyEightNodeBrickUP::sendSelf() - " << this->getTag() << " failed to send ID\n";
02176 
02177                 return res;
02178 
02179         }
02180 
02181 
02182 
02183 
02184 
02185         // Finally, this element asks its material objects to send themselves
02186 
02187         for (i = 0; i < nintu ; i++) {
02188 
02189                 res += materialPointers[i]->sendSelf(commitTag, theChannel);
02190 
02191                 if (res < 0) {
02192 
02193                         opserr << "WARNING TwentyEightNodeBrickUP::sendSelf() - " << this->getTag() << " failed to send its Material\n";
02194 
02195                         return res;
02196 
02197                 }
02198 
02199         }
02200 
02201 
02202 
02203         return res;
02204 
02205 
02206 
02207 }
02208 
02209 
02210 
02211 int  TwentyEightNodeBrickUP::recvSelf (int commitTag,
02212 
02213                                                                            Channel &theChannel,
02214 
02215                                                                            FEM_ObjectBroker &theBroker)
02216 
02217 {
02218 
02219         int res = 0;
02220 
02221 
02222 
02223         int dataTag = this->getDbTag();
02224 
02225 
02226 
02227         static ID idData(75);
02228 
02229         //  now receives the tags of its 20 external nodes
02230 
02231         res += theChannel.recvID(dataTag, commitTag, idData);
02232 
02233         if (res < 0) {
02234 
02235                 opserr << "WARNING TwentyEightNodeBrickUP::recvSelf() - " << this->getTag() << " failed to receive ID\n";
02236 
02237                 return res;
02238 
02239         }
02240 
02241 
02242 
02243         this->setTag(idData(74));
02244 
02245 
02246 
02247         int i;
02248 
02249         for( i = 0; i < 20; i++)
02250 
02251                 connectedExternalNodes(i) = idData(54+i);
02252 
02253 
02254 
02255         if (materialPointers[0] == 0) {
02256 
02257                 for (i = 0; i < nintu; i++) {
02258 
02259                         int matClassTag = idData(i);
02260 
02261                         int matDbTag = idData(i+nintu);
02262 
02263                         // Allocate new material with the sent class tag
02264 
02265                         materialPointers[i] = theBroker.getNewNDMaterial(matClassTag);
02266 
02267                         if (materialPointers[i] == 0) {
02268 
02269                                 opserr << "TwentyEightNodeBrickUP::recvSelf() - Broker could not create NDMaterial of class type " << matClassTag << endln;
02270 
02271                                 return -1;
02272 
02273                         }
02274 
02275                         // Now receive materials into the newly allocated space
02276 
02277                         materialPointers[i]->setDbTag(matDbTag);
02278 
02279                         res += materialPointers[i]->recvSelf(commitTag, theChannel, theBroker);
02280 
02281                         if (res < 0) {
02282 
02283                                 opserr << "TwentyEightNodeBrickUP::recvSelf() - material " << i << "failed to recv itself\n";
02284 
02285                                 return res;
02286 
02287                         }
02288 
02289                 }
02290 
02291         }
02292 
02293         // materials exist , ensure materials of correct type and recvSelf on them
02294 
02295         else {
02296 
02297                 for (i = 0; i < nintu; i++) {
02298 
02299                         int matClassTag = idData(i);
02300 
02301                         int matDbTag = idData(i+nintu);
02302 
02303                         // Check that material is of the right type; if not,
02304 
02305                         // delete it and create a new one of the right type
02306 
02307                         if (materialPointers[i]->getClassTag() != matClassTag) {
02308 
02309                                 delete materialPointers[i];
02310 
02311                                 materialPointers[i] = theBroker.getNewNDMaterial(matClassTag);
02312 
02313                                 if (materialPointers[i] == 0) {
02314 
02315                                         opserr << "TwentyEightNodeBrickUP::recvSelf() - Broker could not create NDMaterial of class type " <<
02316 
02317                                                 matClassTag << endln;
02318 
02319                                         exit(-1);
02320 
02321                                 }
02322 
02323                                 materialPointers[i]->setDbTag(matDbTag);
02324 
02325                         }
02326 
02327                         // Receive the material
02328 
02329 
02330 
02331                         res += materialPointers[i]->recvSelf(commitTag, theChannel, theBroker);
02332 
02333                         if (res < 0) {
02334 
02335                                 opserr << "TwentyEightNodeBrickUP::recvSelf() - material " << i << "failed to recv itself\n";
02336 
02337                                 return res;
02338 
02339                         }
02340 
02341                 }
02342 
02343         }
02344 
02345 
02346 
02347         return res;
02348 
02349 }
02350 
02351 //**************************************************************************
02352 
02353 
02354 
02355 int
02356 
02357 TwentyEightNodeBrickUP::displaySelf(Renderer &theViewer, int displayMode, float fact)
02358 
02359 {
02360 
02361    return 0;
02362 
02363 }
02364 
02365 
02366 
02367 Response*
02368 TwentyEightNodeBrickUP::setResponse(const char **argv, int argc, Information &eleInfo, OPS_Stream &output)
02369 {
02370 
02371   Response *theResponse = 0;
02372 
02373   char outputData[32];
02374 
02375   output.tag("ElementOutput");
02376   output.attr("eleType","Twenty_Eight_Node_BrickUP");
02377   output.attr("eleTag",this->getTag());
02378   for (int i=1; i<=20; i++) {
02379     sprintf(outputData,"node%d",i);
02380     output.attr(outputData, nodePointers[i-1]->getTag());
02381   }
02382 
02383   if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0) {
02384 
02385 
02386     for (int i=1; i<=20; i++) {
02387       sprintf(outputData,"P1_",i);
02388       output.tag("ResponseType",outputData);
02389       sprintf(outputData,"P2_",i);
02390       output.tag("ResponseType",outputData);
02391       sprintf(outputData,"P3_",i);
02392       output.tag("ResponseType",outputData);
02393       if (i <= nenp) {
02394         sprintf(outputData,"Pp_",i);
02395         output.tag("ResponseType",outputData);
02396       }
02397     }
02398 
02399     theResponse = new ElementResponse(this, 1, resid);
02400     
02401   } else if (strcmp(argv[0],"stiff") == 0 || strcmp(argv[0],"stiffness") == 0)
02402     
02403     theResponse = new ElementResponse(this, 2, stiff);
02404     
02405   
02406   
02407   else if (strcmp(argv[0],"mass") == 0)
02408     
02409     theResponse = new ElementResponse(this, 3, mass);
02410   
02411   
02412   
02413   else if (strcmp(argv[0],"damp") == 0)
02414     
02415     theResponse = new ElementResponse(this, 4, damp);
02416   
02417 
02418   
02419   else if (strcmp(argv[0],"material") == 0 || strcmp(argv[0],"integrPoint") == 0) {
02420     
02421     int pointNum = atoi(argv[1]);
02422     
02423     if (pointNum > 0 && pointNum <= nintu) {
02424 
02425       output.tag("GaussPoint");
02426       output.attr("number",pointNum);
02427 
02428       theResponse =  materialPointers[pointNum-1]->setResponse(&argv[2], argc-2, eleInfo, output);
02429       
02430       output.endTag(); // GaussPoint
02431     }
02432   } else if (strcmp(argv[0],"stresses") ==0) {
02433 
02434     for (int i=0; i<nintu; i++) {
02435       output.tag("GaussPoint");
02436       output.attr("number",i+1);
02437       output.tag("NdMaterialOutput");
02438       output.attr("classType", materialPointers[i]->getClassTag());
02439       output.attr("tag", materialPointers[i]->getTag());
02440 
02441       output.tag("ResponseType","sigma11");
02442       output.tag("ResponseType","sigma22");
02443       output.tag("ResponseType","sigma33");
02444       output.tag("ResponseType","sigma12");
02445       output.tag("ResponseType","sigma13");
02446       output.tag("ResponseType","sigma23");      
02447 
02448       output.endTag(); // NdMaterialOutput
02449       output.endTag(); // GaussPoint
02450     }          
02451     
02452     theResponse = new ElementResponse(this, 5, Vector(nintu*6));
02453     
02454   }
02455   
02456   
02457   output.endTag(); // ElementOutput
02458   return theResponse;
02459 }
02460 
02461 
02462 
02463 int
02464 
02465 TwentyEightNodeBrickUP::getResponse(int responseID, Information &eleInfo)
02466 
02467 {
02468 
02469         static Vector stresses(nintu*6);
02470 
02471         
02472 
02473         if (responseID == 1)
02474 
02475                 return eleInfo.setVector(this->getResistingForce());
02476 
02477         
02478 
02479         else if (responseID == 2)
02480 
02481                 return eleInfo.setMatrix(this->getTangentStiff());
02482 
02483 
02484 
02485     else if (responseID == 3)
02486 
02487         return eleInfo.setMatrix(this->getMass());
02488 
02489 
02490 
02491     else if (responseID == 4)
02492 
02493         return eleInfo.setMatrix(this->getDamp());
02494 
02495     
02496 
02497         else if (responseID == 5) {
02498 
02499                 
02500 
02501                 // Loop over the integration points
02502 
02503                 int cnt = 0;
02504 
02505                 for (int i = 0; i < nintu; i++) {
02506 
02507                         // Get material stress response
02508 
02509                         const Vector &sigma = materialPointers[i]->getStress();
02510 
02511                         stresses(cnt++) = sigma(0);
02512 
02513                         stresses(cnt++) = sigma(1);
02514 
02515                         stresses(cnt++) = sigma(2);
02516 
02517                         stresses(cnt++) = sigma(3);
02518 
02519                         stresses(cnt++) = sigma(4);
02520 
02521                         stresses(cnt++) = sigma(5);
02522 
02523                 }
02524 
02525                 return eleInfo.setVector(stresses);
02526 
02527                 
02528 
02529         }
02530 
02531         else
02532 
02533                 
02534 
02535                 return -1;
02536 
02537 }
02538 
02539 
02540 
02541 // calculate local shape functions
02542 
02543 void
02544 
02545 TwentyEightNodeBrickUP::compuLocalShapeFunction() {
02546 
02547         
02548 
02549         int i, k, j;
02550 
02551         static double shl[4][20][27], w[27];
02552 
02553         // solid phase
02554 
02555         brcshl(shl, w, nintu, nenu);
02556 
02557         for(k = 0; k < nintu; k++) {
02558 
02559                 wu[k] = w[k];
02560 
02561                 for( j = 0; j < nenu; j++)
02562 
02563                         for( i = 0; i < 4; i++)
02564 
02565                                 shlu[i][j][k] = shl[i][j][k];
02566 
02567         }
02568 
02569         // fluid phase
02570 
02571         brcshl(shl, w, nintp, nenu);
02572 
02573         for(k = 0; k < nintp; k++) {
02574 
02575                 wp[k] = w[k];
02576 
02577                 for( j = 0; j < nenu; j++)
02578 
02579                         for( i = 0; i < 4; i++)
02580 
02581                                 shlq[i][j][k] = shl[i][j][k];
02582 
02583         }
02584 
02585         // coupling term
02586 
02587         brcshl(shl, w, nintp, nenp);
02588 
02589         for(k = 0; k < nintp; k++) {
02590 
02591                 wp[k] = w[k];
02592 
02593                 for( j = 0; j < nenp; j++)
02594 
02595                         for( i = 0; i < 4; i++)
02596 
02597                                 shlp[i][j][k] = shl[i][j][k];
02598 
02599         }
02600 
02601         
02602 
02603 }
02604 
02605 
02606 
02607 void
02608 
02609 TwentyEightNodeBrickUP::Jacobian3d(int gaussPoint, double& xsj, int mode)
02610 
02611 {
02612 
02613         int i, j, k, nint, nen;
02614 
02615         double rxsj, c1, c2, c3;
02616 
02617         static double xs[3][3];
02618 
02619         static double ad[3][3];
02620 
02621         static double shp[4][20];
02622 
02623         
02624 
02625         if( mode == 0 ) { // solid
02626 
02627                 nint = nintu;
02628 
02629                 nen = nenu;
02630 
02631         }
02632 
02633         else if( mode == 1) { // fluid
02634 
02635                 nint = nintp;
02636 
02637                 nen = nenp;
02638 
02639         }
02640 
02641         else if( mode == 2 ) { // coupling
02642 
02643                 nint = nintp;
02644 
02645                 nen = nenu;
02646 
02647         }
02648 
02649         else {
02650 
02651                 opserr <<"TwentyEightNodeBrickUP::Jacobian3d - illegal mode: " << mode << "\n";
02652 
02653                 exit(-1);
02654 
02655         } //end if
02656 
02657         
02658 
02659         for( j = 0; j < nen; j++) {
02660 
02661                 for( i = 0; i < 4; i++) {
02662 
02663                         if( mode == 0 ) 
02664 
02665                                 shp[i][j] = shlu[i][j][gaussPoint];
02666 
02667                         else if( mode == 1 )
02668 
02669                                 shp[i][j] = shlp[i][j][gaussPoint];
02670 
02671                         else if( mode == 2 )
02672 
02673                                 shp[i][j] = shlq[i][j][gaussPoint];
02674 
02675                         else {
02676 
02677                                 opserr <<"TwentyEightNodeBrickUP::Jacobian3d - illegal mode: " << mode << "\n";
02678 
02679                                 exit(-1);
02680 
02681                         } //end if
02682 
02683                 }
02684 
02685         }
02686 
02687         
02688 
02689         
02690 
02691         
02692 
02693         
02694 
02695         //Compute jacobian transformation
02696 
02697         
02698 
02699         for ( j=0; j<3; j++ ) {
02700 
02701                 for( k = 0; k < 3; k++ ) {
02702 
02703                         xs[j][k] = 0;
02704 
02705                         for( i = 0; i < nen; i++ ) {
02706 
02707                                 xs[j][k] += xl[j][i] * shp[k][i];
02708 
02709                         }
02710 
02711                 }
02712 
02713         }
02714 
02715         
02716 
02717         
02718 
02719         //Compute adjoint to jacobian
02720 
02721         
02722 
02723         ad[0][0] = xs[1][1]*xs[2][2] - xs[1][2]*xs[2][1] ;
02724 
02725         ad[0][1] = xs[2][1]*xs[0][2] - xs[2][2]*xs[0][1] ;
02726 
02727         ad[0][2] = xs[0][1]*xs[1][2] - xs[0][2]*xs[1][1] ;
02728 
02729         
02730 
02731         ad[1][0] = xs[1][2]*xs[2][0] - xs[1][0]*xs[2][2] ;
02732 
02733         ad[1][1] = xs[2][2]*xs[0][0] - xs[2][0]*xs[0][2] ;
02734 
02735         ad[1][2] = xs[0][2]*xs[1][0] - xs[0][0]*xs[1][2] ;
02736 
02737         
02738 
02739         ad[2][0] = xs[1][0]*xs[2][1] - xs[1][1]*xs[2][0] ;
02740 
02741         ad[2][1] = xs[2][0]*xs[0][1] - xs[2][1]*xs[0][0] ; 
02742 
02743         ad[2][2] = xs[0][0]*xs[1][1] - xs[0][1]*xs[1][0] ;
02744 
02745         
02746 
02747         //Compute determinant of jacobian
02748 
02749         
02750 
02751         xsj  = xs[0][0]*ad[0][0] + xs[0][1]*ad[1][0] + xs[0][2]*ad[2][0] ;
02752 
02753         if (xsj<=0) {
02754 
02755                 opserr <<"TwentyEightNodeBrickUP::Jacobian3d - Non-positive Jacobian: " << xsj << "\n";
02756 
02757                 for( i = 0; i < nen; i++ ) {
02758 
02759                         printf("%5d %15.6e %15.6e %15.6e %15.6e\n", i, 
02760 
02761                                 shp[0][i], shp[1][i], shp[2][i], shp[3][i]);
02762 
02763                 }
02764 
02765 
02766 
02767                 exit(-1);
02768 
02769         }
02770 
02771         
02772 
02773         rxsj = 1.0/xsj ;
02774 
02775         
02776 
02777         //Compute jacobian inverse
02778 
02779         
02780 
02781         for ( j=0; j<3; j++ ) {
02782 
02783                 
02784 
02785         for ( i=0; i<3; i++ ) 
02786 
02787                         xs[i][j] = ad[i][j]*rxsj ;
02788 
02789                 
02790 
02791         } //end for j
02792 
02793         
02794 
02795         
02796 
02797         //Compute derivatives with repect to global coords.
02798 
02799         
02800 
02801         for ( k=0; k<nen; k++) {
02802 
02803                 
02804 
02805                 c1 = shp[0][k]*xs[0][0] + shp[1][k]*xs[1][0] + shp[2][k]*xs[2][0] ;
02806 
02807         c2 = shp[0][k]*xs[0][1] + shp[1][k]*xs[1][1] + shp[2][k]*xs[2][1] ;
02808 
02809         c3 = shp[0][k]*xs[0][2] + shp[1][k]*xs[1][2] + shp[2][k]*xs[2][2] ;
02810 
02811                 
02812 
02813         shp[0][k] = c1 ;
02814 
02815         shp[1][k] = c2 ;
02816 
02817         shp[2][k] = c3 ;
02818 
02819                 
02820 
02821         } //end for k
02822 
02823         
02824 
02825         for( j = 0; j < nen; j++) {
02826 
02827                 for( i = 0; i < 4; i++) {
02828 
02829                         if( mode == 0 ) 
02830 
02831                                 shgu[i][j][gaussPoint] = shp[i][j];
02832 
02833                         else if( mode == 1 )
02834 
02835                                 shgp[i][j][gaussPoint] = shp[i][j]; 
02836 
02837                         else if( mode == 2 )
02838 
02839                                 shgq[i][j][gaussPoint] = shp[i][j];
02840 
02841                         else {
02842 
02843                                 opserr <<"TwentyEightNodeBrickUP::Jacobian3d - illegal mode: " << mode << "\n";
02844 
02845                                 exit(-1);
02846 
02847                         } //end if
02848 
02849                 }
02850 
02851         }
02852 
02853         
02854 
02855         
02856 
02857 }
02858 
02859 
02860 
02861 
02862 

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