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

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