ShellMITC4.cpp

Go to the documentation of this file.
00001 /* ****************************************************************** **
00002 **    OpenSees - Open System for Earthquake Engineering Simulation    **
00003 **          Pacific Earthquake Engineering Research Center            **
00004 **                                                                    **
00005 **                                                                    **
00006 ** (C) Copyright 1999, The Regents of the University of California    **
00007 ** All Rights Reserved.                                               **
00008 **                                                                    **
00009 ** Commercial use of this program without express permission of the   **
00010 ** University of California, Berkeley, is strictly prohibited.  See   **
00011 ** file 'COPYRIGHT'  in main directory for information on usage and   **
00012 ** redistribution,  and for a DISCLAIMER OF ALL WARRANTIES.           **
00013 **                                                                    **
00014 ** Developed by:                                                      **
00015 **   Frank McKenna (fmckenna@ce.berkeley.edu)                         **
00016 **   Gregory L. Fenves (fenves@ce.berkeley.edu)                       **
00017 **   Filip C. Filippou (filippou@ce.berkeley.edu)                     **
00018 **                                                                    **
00019 ** ****************************************************************** */
00020                                                                         
00021 // $Revision: 1.14 $
00022 // $Date: 2006/03/21 22:19:12 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/element/shell/ShellMITC4.cpp,v $
00024 
00025 // Ed "C++" Love
00026 //
00027 // B-bar four node shell element with membrane and drill
00028 //
00029 
00030 #include <stdio.h> 
00031 #include <stdlib.h> 
00032 #include <math.h> 
00033 
00034 #include <ID.h> 
00035 #include <Vector.h>
00036 #include <Matrix.h>
00037 #include <Element.h>
00038 #include <Node.h>
00039 #include <SectionForceDeformation.h>
00040 #include <Domain.h>
00041 #include <ErrorHandler.h>
00042 #include <ShellMITC4.h>
00043 #include <R3vectors.h>
00044 #include <Renderer.h>
00045 
00046 
00047 #include <Channel.h>
00048 #include <FEM_ObjectBroker.h>
00049 
00050 #define min(a,b) ( (a)<(b) ? (a):(b) )
00051 
00052 //static data
00053 Matrix  ShellMITC4::stiff(24,24) ;
00054 Vector  ShellMITC4::resid(24) ;
00055 Matrix  ShellMITC4::mass(24,24) ;
00056 
00057 //intialize pointers to zero using intialization list 
00058 Matrix**  ShellMITC4::GammaB1pointer = 0 ;
00059 Matrix**  ShellMITC4::GammaD1pointer = 0 ;
00060 Matrix**  ShellMITC4::GammaA2pointer = 0 ;
00061 Matrix**  ShellMITC4::GammaC2pointer = 0 ; 
00062 Matrix**  ShellMITC4::Bhat           = 0 ;
00063     
00064 //quadrature data
00065 const double  ShellMITC4::root3 = sqrt(3.0) ;
00066 const double  ShellMITC4::one_over_root3 = 1.0 / root3 ;
00067 
00068 double ShellMITC4::sg[4] ;
00069 double ShellMITC4::tg[4] ;
00070 double ShellMITC4::wg[4] ;
00071 
00072 /*
00073 const double  ShellMITC4::sg[] = { -one_over_root3,  
00074                                 one_over_root3, 
00075                                 one_over_root3, 
00076                                -one_over_root3 } ;
00077 
00078 const double  ShellMITC4::tg[] = { -one_over_root3, 
00079                                -one_over_root3, 
00080                                 one_over_root3,  
00081                                 one_over_root3 } ;
00082 
00083 const double  ShellMITC4::wg[] = { 1.0, 1.0, 1.0, 1.0 } ;
00084 */
00085   
00086 
00087 //null constructor
00088 ShellMITC4::ShellMITC4( ) :
00089 Element( 0, ELE_TAG_ShellMITC4 ),
00090 connectedExternalNodes(4), load(0), Ki(0)
00091 { 
00092   for (int i = 0 ;  i < 4; i++ ) 
00093     materialPointers[i] = 0;
00094 
00095   //shear matrix pointers
00096   if ( GammaB1pointer == 0 ) {
00097         GammaB1pointer = new Matrix*[4] ;      //four matrix pointers
00098         GammaB1pointer[0] = new Matrix(1,3) ;  //
00099         GammaB1pointer[1] = new Matrix(1,3) ;  //    four
00100         GammaB1pointer[2] = new Matrix(1,3) ;  //  1x3 matrices
00101         GammaB1pointer[3] = new Matrix(1,3) ;  //
00102   } //end if B1
00103 
00104   if ( GammaD1pointer == 0 ) {
00105         GammaD1pointer = new Matrix*[4] ;
00106         GammaD1pointer[0] = new Matrix(1,3) ;
00107         GammaD1pointer[1] = new Matrix(1,3) ;
00108         GammaD1pointer[2] = new Matrix(1,3) ;
00109         GammaD1pointer[3] = new Matrix(1,3) ;
00110   } //end if D1
00111 
00112   if ( GammaA2pointer == 0 ) {
00113         GammaA2pointer = new Matrix*[4] ;
00114         GammaA2pointer[0] = new Matrix(1,3) ;
00115         GammaA2pointer[1] = new Matrix(1,3) ;
00116         GammaA2pointer[2] = new Matrix(1,3) ;
00117         GammaA2pointer[3] = new Matrix(1,3) ;
00118   } //end if A2
00119 
00120   if ( GammaC2pointer == 0 ) {
00121         GammaC2pointer = new Matrix*[4] ;
00122         GammaC2pointer[0] = new Matrix(1,3) ;
00123         GammaC2pointer[1] = new Matrix(1,3) ;
00124         GammaC2pointer[2] = new Matrix(1,3) ;
00125         GammaC2pointer[3] = new Matrix(1,3) ;
00126   } //end if C2
00127 
00128   if ( Bhat == 0 ) {
00129         Bhat = new Matrix*[4] ;
00130         Bhat[0] = new Matrix(2,3) ;
00131         Bhat[1] = new Matrix(2,3) ;
00132         Bhat[2] = new Matrix(2,3) ;
00133         Bhat[3] = new Matrix(2,3) ;
00134   } //end if Bhat
00135 
00136   sg[0] = -one_over_root3;
00137   sg[1] = one_over_root3;
00138   sg[2] = one_over_root3;
00139   sg[3] = -one_over_root3;  
00140 
00141   tg[0] = -one_over_root3;
00142   tg[1] = -one_over_root3;
00143   tg[2] = one_over_root3;
00144   tg[3] = one_over_root3;  
00145 
00146   wg[0] = 1.0;
00147   wg[1] = 1.0;
00148   wg[2] = 1.0;
00149   wg[3] = 1.0;
00150 }
00151 
00152 
00153 //*********************************************************************
00154 //full constructor
00155 ShellMITC4::ShellMITC4(  int tag, 
00156                          int node1,
00157                          int node2,
00158                          int node3,
00159                          int node4,
00160                          SectionForceDeformation &theMaterial ) :
00161 Element( tag, ELE_TAG_ShellMITC4 ),
00162 connectedExternalNodes(4), load(0), Ki(0)
00163 {
00164   int i;
00165 
00166   connectedExternalNodes(0) = node1 ;
00167   connectedExternalNodes(1) = node2 ;
00168   connectedExternalNodes(2) = node3 ;
00169   connectedExternalNodes(3) = node4 ;
00170 
00171   for ( i = 0 ;  i < 4; i++ ) {
00172 
00173       materialPointers[i] = theMaterial.getCopy( ) ;
00174 
00175       if (materialPointers[i] == 0) {
00176 
00177         opserr << "ShellMITC4::constructor - failed to get a material of type: ShellSection\n";
00178       } //end if
00179       
00180   } //end for i 
00181 
00182   //shear matrix pointers
00183   if ( GammaB1pointer == 0 ) {
00184         GammaB1pointer = new Matrix*[4] ;      //four matrix pointers
00185         GammaB1pointer[0] = new Matrix(1,3) ;  //
00186         GammaB1pointer[1] = new Matrix(1,3) ;  //    four
00187         GammaB1pointer[2] = new Matrix(1,3) ;  //  1x3 matrices
00188         GammaB1pointer[3] = new Matrix(1,3) ;  //
00189   } //end if B1
00190 
00191   if ( GammaD1pointer == 0 ) {
00192         GammaD1pointer = new Matrix*[4] ;
00193         GammaD1pointer[0] = new Matrix(1,3) ;
00194         GammaD1pointer[1] = new Matrix(1,3) ;
00195         GammaD1pointer[2] = new Matrix(1,3) ;
00196         GammaD1pointer[3] = new Matrix(1,3) ;
00197   } //end if D1
00198 
00199   if ( GammaA2pointer == 0 ) {
00200         GammaA2pointer = new Matrix*[4] ;
00201         GammaA2pointer[0] = new Matrix(1,3) ;
00202         GammaA2pointer[1] = new Matrix(1,3) ;
00203         GammaA2pointer[2] = new Matrix(1,3) ;
00204         GammaA2pointer[3] = new Matrix(1,3) ;
00205   } //end if A2
00206 
00207   if ( GammaC2pointer == 0 ) {
00208         GammaC2pointer = new Matrix*[4] ;
00209         GammaC2pointer[0] = new Matrix(1,3) ;
00210         GammaC2pointer[1] = new Matrix(1,3) ;
00211         GammaC2pointer[2] = new Matrix(1,3) ;
00212         GammaC2pointer[3] = new Matrix(1,3) ;
00213   } //end if C2
00214 
00215   if ( Bhat == 0 ) {
00216         Bhat = new Matrix*[4] ;
00217         Bhat[0] = new Matrix(2,3) ;
00218         Bhat[1] = new Matrix(2,3) ;
00219         Bhat[2] = new Matrix(2,3) ;
00220         Bhat[3] = new Matrix(2,3) ;
00221   } //end if Bhat
00222 
00223   sg[0] = -one_over_root3;
00224   sg[1] = one_over_root3;
00225   sg[2] = one_over_root3;
00226   sg[3] = -one_over_root3;  
00227 
00228   tg[0] = -one_over_root3;
00229   tg[1] = -one_over_root3;
00230   tg[2] = one_over_root3;
00231   tg[3] = one_over_root3;  
00232 
00233   wg[0] = 1.0;
00234   wg[1] = 1.0;
00235   wg[2] = 1.0;
00236   wg[3] = 1.0;
00237 
00238 }
00239 //******************************************************************
00240 
00241 //destructor 
00242 ShellMITC4::~ShellMITC4( )
00243 {
00244   int i ;
00245   for ( i = 0 ;  i < 4; i++ ) {
00246 
00247     delete materialPointers[i] ;
00248     materialPointers[i] = 0 ; 
00249 
00250     nodePointers[i] = 0 ;
00251 
00252   } //end for i
00253 
00254   //shear matrix pointers
00255   if ( GammaB1pointer != 0 ) {
00256         delete GammaB1pointer[0] ;
00257         delete GammaB1pointer[1] ;
00258         delete GammaB1pointer[2] ;
00259         delete GammaB1pointer[3] ;
00260         delete [] GammaB1pointer ;
00261         GammaB1pointer = 0 ;
00262   } //end if B1
00263 
00264   if ( GammaD1pointer != 0 ) {
00265         delete GammaD1pointer[0] ;
00266         delete GammaD1pointer[1] ;
00267         delete GammaD1pointer[2] ;
00268         delete GammaD1pointer[3] ;
00269         delete [] GammaD1pointer ;
00270         GammaD1pointer = 0 ;
00271   } //end if D1
00272 
00273   if ( GammaA2pointer != 0 ) {
00274         delete GammaA2pointer[0] ;
00275         delete GammaA2pointer[1] ;
00276         delete GammaA2pointer[2] ;
00277         delete GammaA2pointer[3] ;
00278         delete [] GammaA2pointer ;
00279         GammaA2pointer = 0 ;
00280   } //end if A2
00281 
00282   if ( GammaC2pointer != 0 ) {
00283         delete GammaC2pointer[0] ;
00284         delete GammaC2pointer[1] ;
00285         delete GammaC2pointer[2] ;
00286         delete GammaC2pointer[3] ;
00287         delete [] GammaC2pointer ;
00288         GammaC2pointer = 0 ;
00289   } //end if C2
00290 
00291   if ( Bhat != 0 ) {
00292         delete Bhat[0] ;
00293         delete Bhat[1] ;
00294         delete Bhat[2] ;
00295         delete Bhat[3] ;
00296         delete [] Bhat ;
00297         Bhat = 0 ;
00298   } //end if Bhat
00299 
00300   if (load != 0)
00301     delete load;
00302 
00303   if (Ki != 0)
00304     delete Ki;
00305 }
00306 //**************************************************************************
00307 
00308 
00309 //set domain
00310 void  ShellMITC4::setDomain( Domain *theDomain ) 
00311 {  
00312   int i, j ;
00313   static Vector eig(3) ;
00314   static Matrix ddMembrane(3,3) ;
00315 
00316   //node pointers
00317   for ( i = 0; i < 4; i++ ) {
00318      nodePointers[i] = theDomain->getNode( connectedExternalNodes(i) ) ;
00319      
00320      if (nodePointers[i] == 0) {
00321        opserr << "ShellMITC4::setDomain - no node " << connectedExternalNodes(i);
00322        opserr << " exists in the model\n";
00323      }
00324   }
00325 
00326   //compute drilling stiffness penalty parameter
00327   const Matrix &dd = materialPointers[0]->getInitialTangent( ) ;
00328 
00329   //assemble ddMembrane ;
00330   for ( i = 0; i < 3; i++ ) {
00331       for ( j = 0; j < 3; j++ )
00332          ddMembrane(i,j) = dd(i,j) ;
00333   } //end for i 
00334 
00335   //eigenvalues of ddMembrane
00336   eig = LovelyEig( ddMembrane ) ;
00337   
00338   //set ktt 
00339   //Ktt = dd(2,2) ;  //shear modulus 
00340   Ktt = min( eig(2), min( eig(0), eig(1) ) ) ;
00341   //Ktt = dd(2,2);
00342 
00343   //basis vectors and local coordinates
00344   computeBasis( ) ;
00345 
00346   this->DomainComponent::setDomain(theDomain);
00347 }
00348 
00349 
00350 //get the number of external nodes
00351 int  ShellMITC4::getNumExternalNodes( ) const
00352 {
00353   return 4 ;
00354 } 
00355  
00356 
00357 //return connected external nodes
00358 const ID&  ShellMITC4::getExternalNodes( ) 
00359 {
00360   return connectedExternalNodes ;
00361 } 
00362 
00363 
00364 Node **
00365 ShellMITC4::getNodePtrs(void) 
00366 {
00367   return nodePointers;
00368 } 
00369 
00370 //return number of dofs
00371 int  ShellMITC4::getNumDOF( ) 
00372 {
00373   return 24 ;
00374 }
00375 
00376 
00377 //commit state
00378 int  ShellMITC4::commitState( )
00379 {
00380   int success = 0 ;
00381 
00382   // call element commitState to do any base class stuff
00383   if ((success = this->Element::commitState()) != 0) {
00384     opserr << "ShellMITC4::commitState () - failed in base class";
00385   }    
00386 
00387   for (int i = 0; i < 4; i++ ) 
00388     success += materialPointers[i]->commitState( ) ;
00389   
00390   return success ;
00391 }
00392  
00393 
00394 
00395 //revert to last commit 
00396 int  ShellMITC4::revertToLastCommit( ) 
00397 {
00398   int i ;
00399   int success = 0 ;
00400 
00401   for ( i = 0; i < 4; i++ ) 
00402     success += materialPointers[i]->revertToLastCommit( ) ;
00403   
00404   return success ;
00405 }
00406     
00407 
00408 //revert to start 
00409 int  ShellMITC4::revertToStart( ) 
00410 {
00411   int i ;
00412   int success = 0 ;
00413 
00414   for ( i = 0; i < 4; i++ ) 
00415     success += materialPointers[i]->revertToStart( ) ;
00416   
00417   return success ;
00418 }
00419 
00420 //print out element data
00421 void  ShellMITC4::Print( OPS_Stream &s, int flag )
00422 {
00423   if (flag == -1) {
00424     int eleTag = this->getTag();
00425     s << "EL_QUAD4\t" << eleTag << "\t";
00426     s << eleTag << "\t" << 1; 
00427     s  << "\t" << connectedExternalNodes(0) << "\t" << connectedExternalNodes(1);
00428     s  << "\t" << connectedExternalNodes(2) << "\t" << connectedExternalNodes(3) << "\t0.00";
00429     s << endln;
00430     s << "PROP_2D\t" << eleTag << "\t";
00431     s << eleTag << "\t" << 1; 
00432     s  << "\t" << -1 << "\tSHELL\t1.0\0.0";
00433     s << endln;
00434   }  else if (flag < -1) {
00435 
00436      int counter = (flag + 1) * -1;
00437      int eleTag = this->getTag();
00438      int i,j;
00439      for ( i = 0; i < 4; i++ ) {
00440        const Vector &stress = materialPointers[i]->getStressResultant();
00441        
00442        s << "STRESS\t" << eleTag << "\t" << counter << "\t" << i << "\tTOP";
00443        for (j=0; j<6; j++)
00444          s << "\t" << stress(j);
00445        s << endln;
00446      }
00447 
00448    } else {
00449     s << endln ;
00450     s << "MITC4 Bbar Non-Locking Four Node Shell \n" ;
00451     s << "Element Number: " << this->getTag() << endln ;
00452     s << "Node 1 : " << connectedExternalNodes(0) << endln ;
00453     s << "Node 2 : " << connectedExternalNodes(1) << endln ;
00454     s << "Node 3 : " << connectedExternalNodes(2) << endln ;
00455     s << "Node 4 : " << connectedExternalNodes(3) << endln ;
00456     
00457     s << "Material Information : \n " ;
00458     materialPointers[0]->Print( s, flag ) ;
00459     
00460     s << endln ;
00461   }
00462 }
00463 
00464 //return stiffness matrix 
00465 const Matrix&  ShellMITC4::getTangentStiff( ) 
00466 {
00467   int tang_flag = 1 ; //get the tangent 
00468 
00469   //do tangent and residual here
00470   formResidAndTangent( tang_flag ) ;  
00471 
00472   return stiff ;
00473 }    
00474 
00475 //return secant matrix 
00476 const Matrix&  ShellMITC4::getInitialStiff( ) 
00477 {
00478   if (Ki != 0)
00479     return *Ki;
00480 
00481   static const int ndf = 6 ; //two membrane plus three bending plus one drill
00482 
00483   static const int nstress = 8 ; //three membrane, three moment, two shear
00484 
00485   static const int ngauss = 4 ;
00486 
00487   static const int numnodes = 4 ;
00488 
00489   int i,  j,  k, p, q ;
00490   int jj, kk ;
00491   int node ;
00492 
00493   double volume = 0.0 ;
00494 
00495   static double xsj ;  // determinant jacaobian matrix 
00496 
00497   static double dvol[ngauss] ; //volume element
00498 
00499   static double shp[3][numnodes] ;  //shape functions at a gauss point
00500 
00501   static double Shape[3][numnodes][ngauss] ; //all the shape functions
00502 
00503   static Matrix stiffJK(ndf,ndf) ; //nodeJK stiffness 
00504 
00505   static Matrix dd(nstress,nstress) ;  //material tangent
00506 
00507   static Matrix J0(2,2) ;  //Jacobian at center
00508  
00509   static Matrix J0inv(2,2) ; //inverse of Jacobian at center
00510 
00511   //---------B-matrices------------------------------------
00512 
00513     static Matrix BJ(nstress,ndf) ;      // B matrix node J
00514 
00515     static Matrix BJtran(ndf,nstress) ;
00516 
00517     static Matrix BK(nstress,ndf) ;      // B matrix node k
00518 
00519     static Matrix BJtranD(ndf,nstress) ;
00520 
00521 
00522     static Matrix Bbend(3,3) ;  // bending B matrix
00523 
00524     static Matrix Bshear(2,3) ; // shear B matrix
00525 
00526     static Matrix Bmembrane(3,2) ; // membrane B matrix
00527 
00528 
00529     static double BdrillJ[ndf] ; //drill B matrix
00530 
00531     static double BdrillK[ndf] ;  
00532 
00533     double *drillPointer ;
00534 
00535     static double saveB[nstress][ndf][numnodes] ;
00536 
00537   //-------------------------------------------------------
00538 
00539   stiff.Zero( ) ;
00540 
00541 
00542   //compute basis vectors and local nodal coordinates
00543   //computeBasis( ) ;
00544 
00545   //compute Jacobian and inverse at center
00546   double L1 = 0.0 ;
00547   double L2 = 0.0 ;
00548   computeJacobian( L1, L2, xl, J0, J0inv ) ; 
00549 
00550   //compute the gamma's
00551   computeGamma( xl, J0 ) ;
00552 
00553   //zero Bhat = \frac{1}{volume} \int{  B - \bar{B} } \diff A
00554   for ( node = 0;  node < numnodes;  node++ ) {
00555     Bhat[node]->Zero( ) ;
00556   }
00557 
00558   //gauss loop to compute Bhat's 
00559   for ( i = 0; i < ngauss; i++ ) {
00560 
00561     //get shape functions    
00562     shape2d( sg[i], tg[i], xl, shp, xsj ) ;
00563 
00564     //save shape functions
00565     for ( p = 0; p < 3; p++ ) {
00566       for ( q = 0; q < numnodes; q++ )
00567           Shape[p][q][i] = shp[p][q] ;
00568     } // end for p
00569 
00570     //volume element to also be saved
00571     dvol[i] = wg[i] * xsj ;  
00572 
00573     volume += dvol[i] ;
00574 
00575     for ( node = 0; node < numnodes; node++ ) {
00576 
00577       //compute B shear matrix for this node
00578       //Bhat[node] += (  dvol[i] * computeBshear(node,shp)  ) ;
00579       Bhat[node]->addMatrix(1.0, 
00580                            computeBshear(node,shp),
00581                            dvol[i] ) ;
00582 
00583       //compute B-bar shear matrix for this node
00584       //Bhat[node] -= ( dvol[i] *
00585       //            computeBbarShear( node, sg[i], tg[i], J0inv ) 
00586       //                ) ;
00587       Bhat[node]->addMatrix(1.0, 
00588                            computeBbarShear(node,sg[i],tg[i],J0inv),
00589                            -dvol[i] ) ;
00590 
00591     } //end for node   
00592 
00593   } // end for i gauss loop
00594 
00595   //compute Bhat 
00596     for ( node = 0;  node < numnodes;  node++ )
00597       //(*Bhat[node]) /= volume ;
00598       Bhat[node]->operator/=(volume) ;
00599     
00600 
00601   //gauss loop 
00602   for ( i = 0; i < ngauss; i++ ) {
00603 
00604     //extract shape functions from saved array
00605     for ( p = 0; p < 3; p++ ) {
00606        for ( q = 0; q < numnodes; q++ )
00607           shp[p][q]  = Shape[p][q][i] ;
00608     } // end for p
00609 
00610 
00611     // j-node loop to compute strain 
00612     for ( j = 0; j < numnodes; j++ )  {
00613 
00614       //compute B matrix 
00615 
00616       Bmembrane = computeBmembrane( j, shp ) ;
00617 
00618       Bbend = computeBbend( j, shp ) ;
00619 
00620       Bshear = computeBbarShear( j, sg[i], tg[i], J0inv ) ;
00621 
00622       //add Bhat to shear terms 
00623       Bshear += (*Bhat[j]) ;
00624 
00625       BJ = assembleB( Bmembrane, Bbend, Bshear ) ;
00626 
00627       //save the B-matrix
00628       for (p=0; p<nstress; p++) {
00629         for (q=0; q<ndf; q++ )
00630           saveB[p][q][j] = BJ(p,q) ;
00631       }//end for p
00632 
00633       //drilling B matrix
00634       drillPointer = computeBdrill( j, shp ) ;
00635       for (p=0; p<ndf; p++ ) {
00636         //BdrillJ[p] = *drillPointer++ ;
00637         BdrillJ[p] = *drillPointer ; //set p-th component
00638         drillPointer++ ;             //pointer arithmetic
00639       }//end for p
00640     } // end for j
00641   
00642 
00643     dd = materialPointers[i]->getInitialTangent( ) ;
00644     dd *= dvol[i] ;
00645 
00646     //residual and tangent calculations node loops
00647 
00648     jj = 0 ;
00649     for ( j = 0; j < numnodes; j++ ) {
00650 
00651       //Bmembrane = computeBmembrane( j, shp ) ;
00652 
00653       //Bbend = computeBbend( j, shp ) ;
00654 
00655       //multiply bending terms by (-1.0) for correct statement
00656       // of equilibrium  
00657       //Bbend *= (-1.0) ;
00658 
00659       //Bshear = computeBbarShear( j, sg[i], tg[i], J0inv ) ;
00660 
00661       //add Bhat to shear terms
00662       //Bshear += (*Bhat[j]) ;
00663 
00664       //BJ = assembleB( Bmembrane, Bbend, Bshear ) ;
00665 
00666       //extract BJ
00667       for (p=0; p<nstress; p++) {
00668         for (q=0; q<ndf; q++ )
00669           BJ(p,q) = saveB[p][q][j]   ;
00670       }//end for p
00671 
00672       //multiply bending terms by (-1.0) for correct statement
00673       // of equilibrium  
00674       for ( p = 3; p < 6; p++ ) {
00675         for ( q = 3; q < 6; q++ ) 
00676           BJ(p,q) *= (-1.0) ;
00677       } //end for p
00678 
00679 
00680       //transpose 
00681       //BJtran = transpose( 8, ndf, BJ ) ;
00682       for (p=0; p<ndf; p++) {
00683         for (q=0; q<nstress; q++) 
00684           BJtran(p,q) = BJ(q,p) ;
00685       }//end for p
00686 
00687       //drilling B matrix
00688       drillPointer = computeBdrill( j, shp ) ;
00689       for (p=0; p<ndf; p++ ) {
00690         BdrillJ[p] = *drillPointer ;
00691         drillPointer++ ;
00692       }//end for p
00693 
00694       //BJtranD = BJtran * dd ;
00695       BJtranD.addMatrixProduct(0.0, BJtran,dd,1.0 ) ;
00696       
00697       for (p=0; p<ndf; p++) 
00698         BdrillJ[p] *= ( Ktt*dvol[i] ) ;
00699       
00700       kk = 0 ;
00701       for ( k = 0; k < numnodes; k++ ) {
00702 
00703         //Bmembrane = computeBmembrane( k, shp ) ;
00704         
00705         //Bbend = computeBbend( k, shp ) ;
00706         
00707         //Bshear = computeBbarShear( k, sg[i], tg[i], J0inv ) ;
00708 
00709         //Bshear += (*Bhat[k]) ;
00710         
00711         //BK = assembleB( Bmembrane, Bbend, Bshear ) ;
00712         
00713         //extract BK
00714         for (p=0; p<nstress; p++) {
00715           for (q=0; q<ndf; q++ )
00716             BK(p,q) = saveB[p][q][k]   ;
00717         }//end for p
00718         
00719         
00720         //drilling B matrix
00721         drillPointer = computeBdrill( k, shp ) ;
00722         for (p=0; p<ndf; p++ ) {
00723           BdrillK[p] = *drillPointer ;
00724           drillPointer++ ;
00725         }//end for p
00726         
00727         //stiffJK = BJtranD * BK  ;
00728         // +  transpose( 1,ndf,BdrillJ ) * BdrillK ; 
00729         stiffJK.addMatrixProduct(0.0, BJtranD,BK,1.0 ) ;
00730         
00731         for ( p = 0; p < ndf; p++ )  {
00732           for ( q = 0; q < ndf; q++ ) {
00733             stiff( jj+p, kk+q ) += stiffJK(p,q) 
00734               + ( BdrillJ[p]*BdrillK[q] ) ;
00735           }//end for q
00736         }//end for p
00737         
00738         kk += ndf ;
00739       } // end for k loop
00740       
00741       jj += ndf ;
00742     } // end for j loop
00743     
00744   } //end for i gauss loop 
00745 
00746   Ki = new Matrix(stiff);
00747   
00748   return stiff ;
00749 }
00750     
00751 
00752 //return mass matrix
00753 const Matrix&  ShellMITC4::getMass( ) 
00754 {
00755   int tangFlag = 1 ;
00756 
00757   formInertiaTerms( tangFlag ) ;
00758 
00759   return mass ;
00760 } 
00761 
00762 
00763 void  ShellMITC4::zeroLoad( )
00764 {
00765   if (load != 0)
00766     load->Zero();
00767 
00768   return ;
00769 }
00770 
00771 
00772 int 
00773 ShellMITC4::addLoad(ElementalLoad *theLoad, double loadFactor)
00774 {
00775   opserr << "ShellMITC4::addLoad - load type unknown for ele with tag: " << this->getTag() << endln;
00776   return -1;
00777 }
00778 
00779 
00780 
00781 int 
00782 ShellMITC4::addInertiaLoadToUnbalance(const Vector &accel)
00783 {
00784   int tangFlag = 1 ;
00785 
00786   int i;
00787 
00788   int allRhoZero = 0;
00789   for (i=0; i<4; i++) {
00790     if (materialPointers[i]->getRho() != 0.0)
00791       allRhoZero = 1;
00792   }
00793 
00794   if (allRhoZero == 0) 
00795     return 0;
00796 
00797   int count = 0;
00798   for (i=0; i<4; i++) {
00799     const Vector &Raccel = nodePointers[i]->getRV(accel);
00800     for (int j=0; j<6; j++)
00801       resid(count++) = Raccel(i);
00802   }
00803 
00804   formInertiaTerms( tangFlag ) ;
00805   if (load == 0) 
00806     load = new Vector(24);
00807   load->addMatrixVector(1.0, mass, resid, -1.0);
00808 
00809   return 0;
00810 }
00811 
00812 
00813 
00814 //get residual
00815 const Vector&  ShellMITC4::getResistingForce( ) 
00816 {
00817   int tang_flag = 0 ; //don't get the tangent
00818 
00819   formResidAndTangent( tang_flag ) ;
00820 
00821   // subtract external loads 
00822   if (load != 0)
00823     resid -= *load;
00824 
00825   return resid ;   
00826 }
00827 
00828 
00829 //get residual with inertia terms
00830 const Vector&  ShellMITC4::getResistingForceIncInertia( )
00831 {
00832   static Vector res(24);
00833   int tang_flag = 0 ; //don't get the tangent
00834 
00835   //do tangent and residual here 
00836   formResidAndTangent( tang_flag ) ;
00837 
00838   formInertiaTerms( tang_flag ) ;
00839 
00840   res = resid;
00841   // add the damping forces if rayleigh damping
00842   if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0)
00843     res += this->getRayleighDampingForces();
00844 
00845   // subtract external loads 
00846   if (load != 0)
00847     res -= *load;
00848 
00849   return res;
00850 }
00851 
00852 //*********************************************************************
00853 //form inertia terms
00854 
00855 void   
00856 ShellMITC4::formInertiaTerms( int tangFlag ) 
00857 {
00858 
00859   //translational mass only
00860   //rotational inertia terms are neglected
00861 
00862 
00863   static const int ndf = 6 ; 
00864 
00865   static const int numberNodes = 4 ;
00866 
00867   static const int numberGauss = 4 ;
00868 
00869   static const int nShape = 3 ;
00870 
00871   static const int massIndex = nShape - 1 ;
00872 
00873   double xsj ;  // determinant jacaobian matrix 
00874 
00875   double dvol ; //volume element
00876 
00877   static double shp[nShape][numberNodes] ;  //shape functions at a gauss point
00878 
00879   static Vector momentum(ndf) ;
00880 
00881 
00882   int i, j, k, p;
00883   int jj, kk ;
00884 
00885   double temp, rhoH, massJK ;
00886 
00887 
00888   //zero mass 
00889   mass.Zero( ) ;
00890 
00891   //compute basis vectors and local nodal coordinates
00892   //computeBasis( ) ;
00893 
00894 
00895   //gauss loop 
00896   for ( i = 0; i < numberGauss; i++ ) {
00897 
00898     //get shape functions    
00899     shape2d( sg[i], tg[i], xl, shp, xsj ) ;
00900 
00901     //volume element to also be saved
00902     dvol = wg[i] * xsj ;  
00903 
00904 
00905     //node loop to compute accelerations
00906     momentum.Zero( ) ;
00907     for ( j = 0; j < numberNodes; j++ ) 
00908       //momentum += ( shp[massIndex][j] * nodePointers[j]->getTrialAccel() ) ;
00909       momentum.addVector(1.0,  
00910                          nodePointers[j]->getTrialAccel(),
00911                          shp[massIndex][j] ) ;
00912 
00913       
00914     //density
00915     rhoH = materialPointers[i]->getRho() ;
00916 
00917     //multiply acceleration by density to form momentum
00918     momentum *= rhoH ;
00919 
00920 
00921     //residual and tangent calculations node loops
00922     //jj = 0 ;
00923     for ( j=0, jj=0; j<numberNodes; j++, jj+=ndf ) {
00924 
00925       temp = shp[massIndex][j] * dvol ;
00926 
00927       for ( p = 0; p < 3; p++ )
00928         resid( jj+p ) += ( temp * momentum(p) ) ;
00929 
00930       
00931       if ( tangFlag == 1 && rhoH != 0.0) {
00932 
00933          //multiply by density
00934          temp *= rhoH ;
00935 
00936          //node-node translational mass
00937          //kk = 0 ;
00938          for ( k=0, kk=0; k<numberNodes; k++, kk+=ndf ) {
00939 
00940            massJK = temp * shp[massIndex][k] ;
00941 
00942            for ( p = 0; p < 3; p++ ) 
00943               mass( jj+p, kk+p ) +=  massJK ;
00944             
00945            //kk += ndf ;
00946           } // end for k loop
00947 
00948       } // end if tang_flag 
00949 
00950       //jj += ndf ;
00951     } // end for j loop
00952 
00953 
00954   } //end for i gauss loop 
00955 
00956 }
00957 
00958 //*********************************************************************
00959 
00960 //form residual and tangent
00961 void  
00962 ShellMITC4::formResidAndTangent( int tang_flag ) 
00963 {
00964   //
00965   //  six(6) nodal dof's ordered :
00966   //
00967   //    -        - 
00968   //   |    u1    |   <---plate membrane
00969   //   |    u2    |
00970   //   |----------|
00971   //   |  w = u3  |   <---plate bending
00972   //   |  theta1  | 
00973   //   |  theta2  | 
00974   //   |----------|
00975   //   |  theta3  |   <---drill 
00976   //    -        -  
00977   //
00978   // membrane strains ordered :
00979   //
00980   //            strain(0) =   eps00     i.e.   (11)-strain
00981   //            strain(1) =   eps11     i.e.   (22)-strain
00982   //            strain(2) =   gamma01   i.e.   (12)-shear
00983   //
00984   // curvatures and shear strains ordered  :
00985   //
00986   //            strain(3) =     kappa00  i.e.   (11)-curvature
00987   //            strain(4) =     kappa11  i.e.   (22)-curvature
00988   //            strain(5) =   2*kappa01  i.e. 2*(12)-curvature 
00989   //
00990   //            strain(6) =     gamma02  i.e.   (13)-shear
00991   //            strain(7) =     gamma12  i.e.   (23)-shear
00992   //
00993   //  same ordering for moments/shears but no 2 
00994   //  
00995   //  Then, 
00996   //              epsilon00 = -z * kappa00      +    eps00_membrane
00997   //              epsilon11 = -z * kappa11      +    eps11_membrane
00998   //  gamma01 = 2*epsilon01 = -z * (2*kappa01)  +  gamma01_membrane 
00999   //
01000   //  Shear strains gamma02, gamma12 constant through cross section
01001   //
01002 
01003   static const int ndf = 6 ; //two membrane plus three bending plus one drill
01004 
01005   static const int nstress = 8 ; //three membrane, three moment, two shear
01006 
01007   static const int ngauss = 4 ;
01008 
01009   static const int numnodes = 4 ;
01010 
01011   int i,  j,  k, p, q ;
01012   int jj, kk ;
01013   int node ;
01014 
01015   int success ;
01016   
01017   double volume = 0.0 ;
01018 
01019   static double xsj ;  // determinant jacaobian matrix 
01020 
01021   static double dvol[ngauss] ; //volume element
01022 
01023   static Vector strain(nstress) ;  //strain
01024 
01025   static double shp[3][numnodes] ;  //shape functions at a gauss point
01026 
01027   static double Shape[3][numnodes][ngauss] ; //all the shape functions
01028 
01029   static Vector residJ(ndf) ; //nodeJ residual 
01030 
01031   static Matrix stiffJK(ndf,ndf) ; //nodeJK stiffness 
01032 
01033   static Vector stress(nstress) ;  //stress resultants
01034 
01035   static Matrix dd(nstress,nstress) ;  //material tangent
01036 
01037   static Matrix J0(2,2) ;  //Jacobian at center
01038  
01039   static Matrix J0inv(2,2) ; //inverse of Jacobian at center
01040 
01041   double epsDrill = 0.0 ;  //drilling "strain"
01042 
01043   double tauDrill = 0.0 ; //drilling "stress"
01044 
01045   //---------B-matrices------------------------------------
01046 
01047     static Matrix BJ(nstress,ndf) ;      // B matrix node J
01048 
01049     static Matrix BJtran(ndf,nstress) ;
01050 
01051     static Matrix BK(nstress,ndf) ;      // B matrix node k
01052 
01053     static Matrix BJtranD(ndf,nstress) ;
01054 
01055 
01056     static Matrix Bbend(3,3) ;  // bending B matrix
01057 
01058     static Matrix Bshear(2,3) ; // shear B matrix
01059 
01060     static Matrix Bmembrane(3,2) ; // membrane B matrix
01061 
01062 
01063     static double BdrillJ[ndf] ; //drill B matrix
01064 
01065     static double BdrillK[ndf] ;  
01066 
01067     double *drillPointer ;
01068 
01069     static double saveB[nstress][ndf][numnodes] ;
01070 
01071   //-------------------------------------------------------
01072 
01073     
01074 
01075   //zero stiffness and residual 
01076   stiff.Zero( ) ;
01077   resid.Zero( ) ;
01078 
01079   //compute basis vectors and local nodal coordinates
01080   //computeBasis( ) ;
01081 
01082   //compute Jacobian and inverse at center
01083   double L1 = 0.0 ;
01084   double L2 = 0.0 ;
01085   computeJacobian( L1, L2, xl, J0, J0inv ) ; 
01086 
01087   //compute the gamma's
01088   computeGamma( xl, J0 ) ;
01089 
01090   //zero Bhat = \frac{1}{volume} \int{  B - \bar{B} } \diff A
01091   for ( node = 0;  node < numnodes;  node++ ) {
01092     Bhat[node]->Zero( ) ;
01093   }
01094 
01095   //gauss loop to compute Bhat's 
01096   for ( i = 0; i < ngauss; i++ ) {
01097 
01098     //get shape functions    
01099     shape2d( sg[i], tg[i], xl, shp, xsj ) ;
01100 
01101     //save shape functions
01102     for ( p = 0; p < 3; p++ ) {
01103       for ( q = 0; q < numnodes; q++ )
01104           Shape[p][q][i] = shp[p][q] ;
01105     } // end for p
01106 
01107     //volume element to also be saved
01108     dvol[i] = wg[i] * xsj ;  
01109 
01110     volume += dvol[i] ;
01111 
01112     for ( node = 0; node < numnodes; node++ ) {
01113 
01114       //compute B shear matrix for this node
01115       //Bhat[node] += (  dvol[i] * computeBshear(node,shp)  ) ;
01116       Bhat[node]->addMatrix(1.0, 
01117                            computeBshear(node,shp),
01118                            dvol[i] ) ;
01119 
01120       //compute B-bar shear matrix for this node
01121       //Bhat[node] -= ( dvol[i] *
01122       //            computeBbarShear( node, sg[i], tg[i], J0inv ) 
01123       //                ) ;
01124       Bhat[node]->addMatrix(1.0, 
01125                            computeBbarShear(node,sg[i],tg[i],J0inv),
01126                            -dvol[i] ) ;
01127 
01128     } //end for node   
01129 
01130   } // end for i gauss loop
01131 
01132   //compute Bhat 
01133     for ( node = 0;  node < numnodes;  node++ )
01134       //(*Bhat[node]) /= volume ;
01135       Bhat[node]->operator/=(volume) ;
01136     
01137 
01138   //gauss loop 
01139   for ( i = 0; i < ngauss; i++ ) {
01140 
01141     //extract shape functions from saved array
01142     for ( p = 0; p < 3; p++ ) {
01143        for ( q = 0; q < numnodes; q++ )
01144           shp[p][q]  = Shape[p][q][i] ;
01145     } // end for p
01146 
01147 
01148     //zero the strains
01149     strain.Zero( ) ;
01150     epsDrill = 0.0 ;
01151 
01152 
01153     // j-node loop to compute strain 
01154     for ( j = 0; j < numnodes; j++ )  {
01155 
01156       //compute B matrix 
01157 
01158       Bmembrane = computeBmembrane( j, shp ) ;
01159 
01160       Bbend = computeBbend( j, shp ) ;
01161 
01162       Bshear = computeBbarShear( j, sg[i], tg[i], J0inv ) ;
01163 
01164       //add Bhat to shear terms 
01165       Bshear += (*Bhat[j]) ;
01166 
01167       BJ = assembleB( Bmembrane, Bbend, Bshear ) ;
01168 
01169       //save the B-matrix
01170       for (p=0; p<nstress; p++) {
01171         for (q=0; q<ndf; q++ )
01172           saveB[p][q][j] = BJ(p,q) ;
01173       }//end for p
01174 
01175 
01176       //nodal "displacements" 
01177       const Vector &ul = nodePointers[j]->getTrialDisp( ) ;
01178 
01179       //compute the strain
01180       //strain += (BJ*ul) ; 
01181       strain.addMatrixVector(1.0, BJ,ul,1.0 ) ;
01182 
01183       //drilling B matrix
01184       drillPointer = computeBdrill( j, shp ) ;
01185       for (p=0; p<ndf; p++ ) {
01186         //BdrillJ[p] = *drillPointer++ ;
01187         BdrillJ[p] = *drillPointer ; //set p-th component
01188         drillPointer++ ;             //pointer arithmetic
01189       }//end for p
01190 
01191       //drilling "strain" 
01192       for ( p = 0; p < ndf; p++ )
01193         epsDrill +=  BdrillJ[p]*ul(p) ;
01194 
01195     } // end for j
01196   
01197 
01198     //send the strain to the material 
01199     success = materialPointers[i]->setTrialSectionDeformation( strain ) ;
01200 
01201     //compute the stress
01202     stress = materialPointers[i]->getStressResultant( ) ;
01203 
01204     //drilling "stress" 
01205     tauDrill = Ktt * epsDrill ;
01206 
01207     //multiply by volume element
01208     stress   *= dvol[i] ;
01209     tauDrill *= dvol[i] ;
01210 
01211     if ( tang_flag == 1 ) {
01212       dd = materialPointers[i]->getSectionTangent( ) ;
01213       dd *= dvol[i] ;
01214     } //end if tang_flag
01215 
01216 
01217     //residual and tangent calculations node loops
01218 
01219     jj = 0 ;
01220     for ( j = 0; j < numnodes; j++ ) {
01221 
01222       //Bmembrane = computeBmembrane( j, shp ) ;
01223 
01224       //Bbend = computeBbend( j, shp ) ;
01225 
01226       //multiply bending terms by (-1.0) for correct statement
01227       // of equilibrium  
01228       //Bbend *= (-1.0) ;
01229 
01230       //Bshear = computeBbarShear( j, sg[i], tg[i], J0inv ) ;
01231 
01232       //add Bhat to shear terms
01233       //Bshear += (*Bhat[j]) ;
01234 
01235       //BJ = assembleB( Bmembrane, Bbend, Bshear ) ;
01236 
01237       //extract BJ
01238       for (p=0; p<nstress; p++) {
01239         for (q=0; q<ndf; q++ )
01240           BJ(p,q) = saveB[p][q][j]   ;
01241       }//end for p
01242 
01243       //multiply bending terms by (-1.0) for correct statement
01244       // of equilibrium  
01245       for ( p = 3; p < 6; p++ ) {
01246         for ( q = 3; q < 6; q++ ) 
01247           BJ(p,q) *= (-1.0) ;
01248       } //end for p
01249 
01250 
01251       //transpose 
01252       //BJtran = transpose( 8, ndf, BJ ) ;
01253       for (p=0; p<ndf; p++) {
01254         for (q=0; q<nstress; q++) 
01255           BJtran(p,q) = BJ(q,p) ;
01256       }//end for p
01257 
01258 
01259       //residJ = BJtran * stress ;
01260       residJ.addMatrixVector(0.0, BJtran,stress,1.0 ) ;
01261 
01262       //drilling B matrix
01263       drillPointer = computeBdrill( j, shp ) ;
01264       for (p=0; p<ndf; p++ ) {
01265         BdrillJ[p] = *drillPointer ;
01266         drillPointer++ ;
01267       }//end for p
01268 
01269       //residual including drill
01270       for ( p = 0; p < ndf; p++ )
01271         resid( jj + p ) += ( residJ(p) + BdrillJ[p]*tauDrill ) ;
01272 
01273 
01274       if ( tang_flag == 1 ) {
01275 
01276         //BJtranD = BJtran * dd ;
01277         BJtranD.addMatrixProduct(0.0, BJtran,dd,1.0 ) ;
01278 
01279         for (p=0; p<ndf; p++) 
01280           BdrillJ[p] *= ( Ktt*dvol[i] ) ;
01281 
01282         kk = 0 ;
01283         for ( k = 0; k < numnodes; k++ ) {
01284 
01285           //Bmembrane = computeBmembrane( k, shp ) ;
01286 
01287           //Bbend = computeBbend( k, shp ) ;
01288 
01289           //Bshear = computeBbarShear( k, sg[i], tg[i], J0inv ) ;
01290 
01291           //Bshear += (*Bhat[k]) ;
01292 
01293           //BK = assembleB( Bmembrane, Bbend, Bshear ) ;
01294 
01295           //extract BK
01296           for (p=0; p<nstress; p++) {
01297             for (q=0; q<ndf; q++ )
01298               BK(p,q) = saveB[p][q][k]   ;
01299           }//end for p
01300 
01301           
01302           //drilling B matrix
01303           drillPointer = computeBdrill( k, shp ) ;
01304           for (p=0; p<ndf; p++ ) {
01305             BdrillK[p] = *drillPointer ;
01306             drillPointer++ ;
01307           }//end for p
01308   
01309  
01310           //stiffJK = BJtranD * BK  ;
01311           // +  transpose( 1,ndf,BdrillJ ) * BdrillK ; 
01312           stiffJK.addMatrixProduct(0.0, BJtranD,BK,1.0 ) ;
01313 
01314           for ( p = 0; p < ndf; p++ )  {
01315             for ( q = 0; q < ndf; q++ ) {
01316                stiff( jj+p, kk+q ) += stiffJK(p,q) 
01317                                    + ( BdrillJ[p]*BdrillK[q] ) ;
01318             }//end for q
01319           }//end for p
01320 
01321           kk += ndf ;
01322         } // end for k loop
01323 
01324       } // end if tang_flag 
01325 
01326       jj += ndf ;
01327     } // end for j loop
01328 
01329 
01330   } //end for i gauss loop 
01331 
01332   
01333   return ;
01334 }
01335 
01336 
01337 //************************************************************************
01338 //compute local coordinates and basis
01339 
01340 void   
01341 ShellMITC4::computeBasis( ) 
01342 {
01343   //could compute derivatives \frac{ \partial {\bf x} }{ \partial L_1 } 
01344   //                     and  \frac{ \partial {\bf x} }{ \partial L_2 }
01345   //and use those as basis vectors but this is easier 
01346   //and the shell is flat anyway.
01347 
01348   static Vector temp(3) ;
01349 
01350   static Vector v1(3) ;
01351   static Vector v2(3) ;
01352   static Vector v3(3) ;
01353 
01354   //get two vectors (v1, v2) in plane of shell by 
01355   // nodal coordinate differences
01356 
01357   const Vector &coor0 = nodePointers[0]->getCrds( ) ;
01358 
01359   const Vector &coor1 = nodePointers[1]->getCrds( ) ;
01360 
01361   const Vector &coor2 = nodePointers[2]->getCrds( ) ;
01362   
01363   const Vector &coor3 = nodePointers[3]->getCrds( ) ;
01364 
01365   v1.Zero( ) ;
01366   //v1 = 0.5 * ( coor2 + coor1 - coor3 - coor0 ) ;
01367   v1  = coor2 ;
01368   v1 += coor1 ;
01369   v1 -= coor3 ;
01370   v1 -= coor0 ;
01371   v1 *= 0.50 ;
01372   
01373   v2.Zero( ) ;
01374   //v2 = 0.5 * ( coor3 + coor2 - coor1 - coor0 ) ;
01375   v2  = coor3 ;
01376   v2 += coor2 ;
01377   v2 -= coor1 ;
01378   v2 -= coor0 ;
01379   v2 *= 0.50 ;
01380     
01381 
01382  
01383   //normalize v1 
01384   //double length = LovelyNorm( v1 ) ;
01385   double length = v1.Norm( ) ;
01386   v1 /= length ;
01387 
01388 
01389   //Gram-Schmidt process for v2 
01390 
01391   //double alpha = LovelyInnerProduct( v2, v1 ) ;
01392   double alpha = v2^v1 ;
01393 
01394   //v2 -= alpha*v1 ;
01395   temp = v1 ;
01396   temp *= alpha ;
01397   v2 -= temp ;
01398 
01399 
01400   //normalize v2 
01401   //length = LovelyNorm( v2 ) ;
01402   length = v2.Norm( ) ;
01403   v2 /= length ;
01404 
01405 
01406   //cross product for v3  
01407   v3 = LovelyCrossProduct( v1, v2 ) ;
01408 
01409   
01410   //local nodal coordinates in plane of shell
01411 
01412   int i ;
01413   for ( i = 0; i < 4; i++ ) {
01414 
01415        const Vector &coorI = nodePointers[i]->getCrds( ) ;
01416 
01417        xl[0][i] = coorI^v1 ;  
01418        xl[1][i] = coorI^v2 ;
01419 
01420   }  //end for i 
01421 
01422   //basis vectors stored as array of doubles
01423   for ( i = 0; i < 3; i++ ) {
01424       g1[i] = v1(i) ;
01425       g2[i] = v2(i) ;
01426       g3[i] = v3(i) ;
01427   }  //end for i 
01428 
01429 }
01430 
01431 //*************************************************************************
01432 //compute Bdrill
01433 
01434 double*
01435 ShellMITC4::computeBdrill( int node, const double shp[3][4] )
01436 {
01437 
01438   //static Matrix Bdrill(1,6) ;
01439   static double Bdrill[6] ;
01440 
01441   static double B1 ;
01442   static double B2 ;
01443   static double B6 ;
01444 
01445 
01446 //---Bdrill Matrix in standard {1,2,3} mechanics notation---------
01447 //
01448 //             -                                       -
01449 //   Bdrill = | -0.5*N,2   +0.5*N,1    0    0    0   -N |   (1x6) 
01450 //             -                                       -  
01451 //
01452 //----------------------------------------------------------------
01453 
01454   //  Bdrill.Zero( ) ;
01455 
01456   //Bdrill(0,0) = -0.5*shp[1][node] ;
01457 
01458   //Bdrill(0,1) = +0.5*shp[0][node] ;
01459 
01460   //Bdrill(0,5) =     -shp[2][node] ;
01461 
01462 
01463   B1 =  -0.5*shp[1][node] ; 
01464 
01465   B2 =  +0.5*shp[0][node] ;
01466 
01467   B6 =  -shp[2][node] ;
01468 
01469   Bdrill[0] = B1*g1[0] + B2*g2[0] ;
01470   Bdrill[1] = B1*g1[1] + B2*g2[1] ; 
01471   Bdrill[2] = B1*g1[2] + B2*g2[2] ;
01472 
01473   Bdrill[3] = B6*g3[0] ;
01474   Bdrill[4] = B6*g3[1] ; 
01475   Bdrill[5] = B6*g3[2] ;
01476  
01477   return Bdrill ;
01478 
01479 }
01480 
01481 //*************************************************************************
01482 //compute the gamma's
01483 
01484 void   
01485 ShellMITC4::computeGamma( const double xl[2][4], const Matrix &J )
01486 {
01487   //static Matrix e1(1,2) ;
01488   //static Matrix e2(1,2) ;
01489 
01490   static double Jtran[2][2] ;  // J transpose
01491 
01492   static Matrix e1Jtran(1,2) ; // e1*Jtran 
01493 
01494   static Matrix e2Jtran(1,2) ; // e2*Jtran
01495 
01496   static Matrix Bshear(2,3) ; // shear strain-displacement matrix
01497 
01498   static double shape[3][4] ; // shape functions 
01499 
01500   double xsj ; 
01501 
01502   double L1, L2 ;
01503 
01504   int node ;
01505 
01506  /*  
01507   e1(0,0) = 1.0 ;
01508   e1(0,1) = 0.0 ;
01509 
01510   e2(0,0) = 0.0 ;
01511   e2(0,1) = 1.0 ;
01512  */
01513 
01514   //Jtran = transpose( 2, 2, J ) ;
01515   Jtran[0][0] = J(0,0) ;
01516   Jtran[1][1] = J(1,1) ;
01517   Jtran[0][1] = J(1,0) ;
01518   Jtran[1][0] = J(0,1) ;
01519 
01520   //first row of Jtran
01521   //e1Jtran = e1*Jtran ; 
01522   e1Jtran(0,0) = Jtran[0][0] ;
01523   e1Jtran(0,1) = Jtran[0][1] ;
01524 
01525   //second row of Jtran 
01526   //e2Jtran = e2*Jtran ;
01527   e2Jtran(0,0) = Jtran[1][0] ;
01528   e2Jtran(0,1) = Jtran[1][1] ;
01529 
01530 
01531   //-------------GammaB1--------------------------------
01532 
01533     //set natural coordinate point location
01534     L1 =  0.0 ;
01535     L2 = -1.0 ;
01536 
01537     //get shape functions    
01538     shape2d( L1, L2, xl, shape, xsj ) ;
01539 
01540     for ( node = 0; node < 4; node++ ) {
01541 
01542         //compute shear B        
01543         Bshear = computeBshear( node, shape ) ;
01544 
01545         GammaB1pointer[node]->Zero( ) ;
01546 
01547         //( *GammaB1pointer[node] ) = e1Jtran*Bshear ;
01548         GammaB1pointer[node]->addMatrixProduct(0.0, e1Jtran,Bshear,1.0 );
01549 
01550     } //end for node
01551  
01552   //----------------------------------------------------
01553 
01554 
01555   //-------------GammaD1--------------------------------
01556 
01557     //set natural coordinate point location
01558     L1 =  0.0 ;
01559     L2 = +1.0 ;
01560 
01561     //get shape functions    
01562     shape2d( L1, L2, xl, shape, xsj ) ;
01563 
01564     for ( node = 0; node < 4; node++ ) {
01565 
01566         //compute shear B        
01567         Bshear = computeBshear( node, shape ) ;
01568 
01569         GammaD1pointer[node]->Zero( ) ;
01570 
01571         //( *GammaD1pointer[node] ) = e1Jtran*Bshear ;
01572         GammaD1pointer[node]->addMatrixProduct(0.0, e1Jtran,Bshear,1.0 );
01573 
01574     } //end for node
01575  
01576   //----------------------------------------------------    
01577 
01578 
01579   //-------------GammaA2--------------------------------
01580 
01581     //set natural coordinate point location
01582     L1 = -1.0 ;
01583     L2 =  0.0 ;
01584 
01585     //get shape functions    
01586     shape2d( L1, L2, xl, shape, xsj ) ;
01587 
01588     for ( node = 0; node < 4; node++ ) {
01589 
01590         //compute shear B        
01591         Bshear = computeBshear( node, shape ) ;
01592 
01593         GammaA2pointer[node]->Zero( ) ;
01594 
01595         //( *GammaA2pointer[node] ) = e2Jtran*Bshear ;
01596         GammaA2pointer[node]->addMatrixProduct(0.0, e2Jtran,Bshear,1.0 );
01597                    
01598 
01599     } //end for node
01600  
01601   //----------------------------------------------------     
01602 
01603 
01604   //-------------GammaC2--------------------------------
01605 
01606     //set natural coordinate point location
01607     L1 = +1.0 ;
01608     L2 =  0.0 ;
01609 
01610     //get shape functions    
01611     shape2d( L1, L2, xl, shape, xsj ) ;
01612 
01613     for ( node = 0; node < 4; node++ ) {
01614 
01615         //compute shear B        
01616         Bshear = computeBshear( node, shape ) ;
01617 
01618         GammaC2pointer[node]->Zero( ) ;
01619 
01620         //( *GammaC2pointer[node] ) = e2Jtran*Bshear ;
01621         GammaC2pointer[node]->addMatrixProduct(0.0, e2Jtran,Bshear,1.0 );
01622 
01623     } //end for node
01624  
01625   //----------------------------------------------------     
01626 
01627  return ;
01628 
01629 }
01630 
01631 //********************************************************************
01632 //assemble a B matrix
01633 
01634 const Matrix&  
01635 ShellMITC4::assembleB( const Matrix &Bmembrane,
01636                                const Matrix &Bbend, 
01637                                const Matrix &Bshear ) 
01638 {
01639 
01640   //Matrix Bbend(3,3) ;  // plate bending B matrix
01641 
01642   //Matrix Bshear(2,3) ; // plate shear B matrix
01643 
01644   //Matrix Bmembrane(3,2) ; // plate membrane B matrix
01645 
01646 
01647     static Matrix B(8,6) ;
01648 
01649     static Matrix BmembraneShell(3,3) ; 
01650     
01651     static Matrix BbendShell(3,3) ; 
01652 
01653     static Matrix BshearShell(2,6) ;
01654  
01655     static Matrix Gmem(2,3) ;
01656 
01657     static Matrix Gshear(3,6) ;
01658 
01659     int p, q ;
01660     int pp ;
01661 
01662 //    
01663 // For Shell : 
01664 //
01665 //---B Matrices in standard {1,2,3} mechanics notation---------
01666 //
01667 //            -                     _          
01668 //           | Bmembrane  |     0    |
01669 //           | --------------------- |     
01670 //    B =    |     0      |  Bbend   |   (8x6) 
01671 //           | --------------------- |
01672 //           |         Bshear        |
01673 //            -           -         -
01674 //
01675 //-------------------------------------------------------------
01676 //
01677 //
01678 
01679 
01680     //shell modified membrane terms
01681     
01682     Gmem(0,0) = g1[0] ;
01683     Gmem(0,1) = g1[1] ;
01684     Gmem(0,2) = g1[2] ;
01685 
01686     Gmem(1,0) = g2[0] ;
01687     Gmem(1,1) = g2[1] ;
01688     Gmem(1,2) = g2[2] ;
01689 
01690     //BmembraneShell = Bmembrane * Gmem ;
01691     BmembraneShell.addMatrixProduct(0.0, Bmembrane,Gmem,1.0 ) ;
01692 
01693 
01694     //shell modified bending terms 
01695 
01696     Matrix &Gbend = Gmem ;
01697 
01698     //BbendShell = Bbend * Gbend ;
01699     BbendShell.addMatrixProduct(0.0, Bbend,Gbend,1.0 ) ; 
01700 
01701 
01702     //shell modified shear terms 
01703 
01704     Gshear.Zero( ) ;
01705 
01706     Gshear(0,0) = g3[0] ;
01707     Gshear(0,1) = g3[1] ;
01708     Gshear(0,2) = g3[2] ;
01709 
01710     Gshear(1,3) = g1[0] ;
01711     Gshear(1,4) = g1[1] ;
01712     Gshear(1,5) = g1[2] ;
01713 
01714     Gshear(2,3) = g2[0] ;
01715     Gshear(2,4) = g2[1] ;
01716     Gshear(2,5) = g2[2] ;
01717 
01718     //BshearShell = Bshear * Gshear ;
01719     BshearShell.addMatrixProduct(0.0, Bshear,Gshear,1.0 ) ;
01720    
01721 
01722   B.Zero( ) ;
01723 
01724   //assemble B from sub-matrices 
01725 
01726   //membrane terms 
01727   for ( p = 0; p < 3; p++ ) {
01728 
01729       for ( q = 0; q < 3; q++ ) 
01730           B(p,q) = BmembraneShell(p,q) ;
01731 
01732   } //end for p
01733 
01734 
01735   //bending terms
01736   for ( p = 3; p < 6; p++ ) {
01737     pp = p - 3 ;
01738     for ( q = 3; q < 6; q++ ) 
01739         B(p,q) = BbendShell(pp,q-3) ; 
01740   } // end for p
01741     
01742 
01743   //shear terms 
01744   for ( p = 0; p < 2; p++ ) {
01745       pp = p + 6 ;
01746       
01747       for ( q = 0; q < 6; q++ ) {
01748           B(pp,q) = BshearShell(p,q) ; 
01749       } // end for q
01750  
01751   } //end for p
01752   
01753   return B ;
01754 
01755 }
01756 
01757 //***********************************************************************
01758 //compute Bmembrane matrix
01759 
01760 const Matrix&   
01761 ShellMITC4::computeBmembrane( int node, const double shp[3][4] ) 
01762 {
01763 
01764   static Matrix Bmembrane(3,2) ;
01765 
01766 //---Bmembrane Matrix in standard {1,2,3} mechanics notation---------
01767 //
01768 //                -             -
01769 //               | +N,1      0   | 
01770 // Bmembrane =   |   0     +N,2  |    (3x2)
01771 //               | +N,2    +N,1  |
01772 //                -             -  
01773 //
01774 //  three(3) strains and two(2) displacements (for plate)
01775 //-------------------------------------------------------------------
01776 
01777   Bmembrane.Zero( ) ;
01778 
01779   Bmembrane(0,0) = shp[0][node] ;
01780   Bmembrane(1,1) = shp[1][node] ;
01781   Bmembrane(2,0) = shp[1][node] ;
01782   Bmembrane(2,1) = shp[0][node] ;
01783 
01784   return Bmembrane ;
01785 
01786 }
01787 
01788 //***********************************************************************
01789 //compute Bbend matrix
01790 
01791 const Matrix&   
01792 ShellMITC4::computeBbend( int node, const double shp[3][4] )
01793 {
01794 
01795     static Matrix Bbend(3,2) ;
01796 
01797 //---Bbend Matrix in standard {1,2,3} mechanics notation---------
01798 //
01799 //            -             -
01800 //   Bbend = |    0    -N,1  | 
01801 //           |  +N,2     0   |    (3x2)
01802 //           |  +N,1   -N,2  |
01803 //            -             -  
01804 //
01805 //  three(3) curvatures and two(2) rotations (for plate)
01806 //----------------------------------------------------------------
01807 
01808     Bbend.Zero( ) ;
01809 
01810     Bbend(0,1) = -shp[0][node] ;
01811     Bbend(1,0) =  shp[1][node] ;
01812     Bbend(2,0) =  shp[0][node] ;
01813     Bbend(2,1) = -shp[1][node] ; 
01814 
01815     return Bbend ;
01816 }
01817 
01818 //***********************************************************************
01819 //compute Bbar shear matrix
01820 
01821 const Matrix&  
01822 ShellMITC4::computeBbarShear( int node, double L1, double L2,
01823                               const Matrix &Jinv ) 
01824 {
01825     static Matrix Bshear(2,3) ;
01826     static Matrix BshearNat(2,3) ;
01827 
01828     static Matrix JinvTran(2,2) ;  // J-inverse-transpose
01829 
01830     static Matrix Gamma1(1,3) ;
01831     static Matrix Gamma2(1,3) ; 
01832 
01833     static Matrix temp1(1,3) ;
01834     static Matrix temp2(1,3) ;
01835 
01836 
01837     //JinvTran = transpose( 2, 2, Jinv ) ;
01838     JinvTran(0,0) = Jinv(0,0) ;
01839     JinvTran(1,1) = Jinv(1,1) ;
01840     JinvTran(0,1) = Jinv(1,0) ;
01841     JinvTran(1,0) = Jinv(0,1) ;
01842 
01843 
01844     // compute BShear from Bbar interpolation
01845     
01846     //Gamma1 = ( 1.0 - L2 )*( *GammaB1pointer[node] )  +
01847     //         ( 1.0 + L2 )*( *GammaD1pointer[node] )   ;
01848     temp1  = *GammaB1pointer[node] ;
01849     temp1 *= ( 1.0 - L2 ) ;
01850     
01851     temp2  = *GammaD1pointer[node] ;
01852     temp2 *= ( 1.0 + L2 ) ;
01853 
01854     Gamma1  = temp1 ;
01855     Gamma1 += temp2 ;
01856 
01857 
01858     //Gamma2 = ( 1.0 - L1 )*( *GammaA2pointer[node] )  +
01859     //         ( 1.0 + L1 )*( *GammaC2pointer[node] )   ;
01860     temp1  = *GammaA2pointer[node] ;
01861     temp1 *= ( 1.0 - L1 ) ;
01862     
01863     temp2  = *GammaC2pointer[node] ;
01864     temp2 *= ( 1.0 + L1 ) ;
01865 
01866     Gamma2  = temp1 ;
01867     Gamma2 += temp2 ;
01868 
01869     //don't forget the 1/2
01870     //Gamma1 *= 0.50 ;
01871     //Gamma2 *= 0.50 ;
01872 
01873 
01874     BshearNat(0,0) = Gamma1(0,0) ;
01875     BshearNat(0,1) = Gamma1(0,1) ;
01876     BshearNat(0,2) = Gamma1(0,2) ;
01877 
01878     BshearNat(1,0) = Gamma2(0,0) ;
01879     BshearNat(1,1) = Gamma2(0,1) ;
01880     BshearNat(1,2) = Gamma2(0,2) ;
01881 
01882 
01883     //strain tensor push on BshearNat
01884     //Bshear = ( JinvTran * BshearNat ) ;
01885     Bshear.addMatrixProduct(0.0,  JinvTran,BshearNat,0.5 ) ;
01886     //note the 1/2 -----------------------------------^
01887 
01888     return Bshear ;
01889 }
01890 
01891 //***********************************************************************
01892 //compute standard Bshear matrix
01893 
01894 const Matrix&  
01895 ShellMITC4::computeBshear( int node, const double shp[3][4] )
01896 {
01897 
01898   static Matrix Bshear(2,3) ;
01899 
01900 //---Bshear Matrix in standard {1,2,3} mechanics notation------
01901 //
01902 //             -                -
01903 //   Bshear = | +N,1      0    +N |  (2x3)
01904 //            | +N,2     -N     0 |
01905 //             -                -  
01906 //
01907 //  two(2) shear strains, one(1) displacement and two(2) rotations for plate 
01908 //-----------------------------------------------------------------------
01909 
01910   Bshear.Zero( ) ;
01911 
01912   Bshear(0,0) =  shp[0][node] ;
01913   Bshear(0,2) =  shp[2][node] ;
01914   Bshear(1,0) =  shp[1][node] ;
01915   Bshear(1,1) = -shp[2][node] ;
01916 
01917   return Bshear ;
01918 
01919 }  
01920 
01921 //***********************************************************************
01922 //compute Jacobian matrix and inverse at point {L1,L2} 
01923 
01924 void   
01925 ShellMITC4::computeJacobian( double L1, double L2,
01926                                     const double x[2][4], 
01927                                     Matrix &JJ, 
01928                                     Matrix &JJinv )
01929 {
01930   int i, j, k ;
01931      
01932   static const double s[] = { -0.5,  0.5, 0.5, -0.5 } ;
01933   static const double t[] = { -0.5, -0.5, 0.5,  0.5 } ;
01934 
01935   static double shp[2][4] ;
01936 
01937   double ss = L1 ;
01938   double tt = L2 ;
01939 
01940   for ( i = 0; i < 4; i++ ) {
01941       shp[0][i] = s[i] * ( 0.5 + t[i]*tt ) ;
01942       shp[1][i] = t[i] * ( 0.5 + s[i]*ss ) ;
01943   } // end for i
01944 
01945   
01946   // Construct jacobian and its inverse
01947   
01948   JJ.Zero( ) ;
01949   for ( i = 0; i < 2; i++ ) {
01950     for ( j = 0; j < 2; j++ ) {
01951 
01952       for ( k = 0; k < 4; k++ )
01953           JJ(i,j) +=  x[i][k] * shp[j][k] ;
01954 
01955     } //end for j
01956   }  // end for i 
01957 
01958   double xsj = JJ(0,0)*JJ(1,1) - JJ(0,1)*JJ(1,0) ;
01959 
01960   //inverse jacobian
01961   double jinv = 1.0 / xsj ;
01962   JJinv(0,0) =  JJ(1,1) * jinv ;
01963   JJinv(1,1) =  JJ(0,0) * jinv ;
01964   JJinv(0,1) = -JJ(0,1) * jinv ; 
01965   JJinv(1,0) = -JJ(1,0) * jinv ; 
01966 
01967   return ;
01968 
01969 }
01970 
01971 //************************************************************************
01972 //shape function routine for four node quads
01973 
01974 void  
01975 ShellMITC4::shape2d( double ss, double tt, 
01976                            const double x[2][4], 
01977                            double shp[3][4], 
01978                            double &xsj            )
01979 
01980 { 
01981 
01982   int i, j, k ;
01983 
01984   double temp ;
01985      
01986   static const double s[] = { -0.5,  0.5, 0.5, -0.5 } ;
01987   static const double t[] = { -0.5, -0.5, 0.5,  0.5 } ;
01988 
01989   static double xs[2][2] ;
01990   static double sx[2][2] ;
01991 
01992   for ( i = 0; i < 4; i++ ) {
01993       shp[2][i] = ( 0.5 + s[i]*ss )*( 0.5 + t[i]*tt ) ;
01994       shp[0][i] = s[i] * ( 0.5 + t[i]*tt ) ;
01995       shp[1][i] = t[i] * ( 0.5 + s[i]*ss ) ;
01996   } // end for i
01997 
01998   
01999   // Construct jacobian and its inverse
02000   
02001   for ( i = 0; i < 2; i++ ) {
02002     for ( j = 0; j < 2; j++ ) {
02003 
02004       xs[i][j] = 0.0 ;
02005 
02006       for ( k = 0; k < 4; k++ )
02007           xs[i][j] +=  x[i][k] * shp[j][k] ;
02008 
02009     } //end for j
02010   }  // end for i 
02011 
02012   xsj = xs[0][0]*xs[1][1] - xs[0][1]*xs[1][0] ;
02013 
02014   //inverse jacobian
02015   double jinv = 1.0 / xsj ;
02016   sx[0][0] =  xs[1][1] * jinv ;
02017   sx[1][1] =  xs[0][0] * jinv ;
02018   sx[0][1] = -xs[0][1] * jinv ; 
02019   sx[1][0] = -xs[1][0] * jinv ; 
02020 
02021 
02022   //form global derivatives 
02023   
02024   for ( i = 0; i < 4; i++ ) {
02025     temp      = shp[0][i]*sx[0][0] + shp[1][i]*sx[1][0] ;
02026     shp[1][i] = shp[0][i]*sx[0][1] + shp[1][i]*sx[1][1] ;
02027     shp[0][i] = temp ;
02028   } // end for i
02029 
02030   return ;
02031 }
02032            
02033 //**********************************************************************
02034 
02035 Matrix  
02036 ShellMITC4::transpose( int dim1, 
02037                                        int dim2, 
02038                                        const Matrix &M ) 
02039 {
02040   int i ;
02041   int j ;
02042 
02043   Matrix Mtran( dim2, dim1 ) ;
02044 
02045   for ( i = 0; i < dim1; i++ ) {
02046      for ( j = 0; j < dim2; j++ ) 
02047          Mtran(j,i) = M(i,j) ;
02048   } // end for i
02049 
02050   return Mtran ;
02051 }
02052 
02053 //**********************************************************************
02054 
02055 int  ShellMITC4::sendSelf (int commitTag, Channel &theChannel)
02056 {
02057 
02058   int res = 0;
02059 
02060   // note: we don't check for dataTag == 0 for Element
02061   // objects as that is taken care of in a commit by the Domain
02062   // object - don't want to have to do the check if sending data
02063   int dataTag = this->getDbTag();
02064   
02065 
02066   // Now quad sends the ids of its materials
02067   int matDbTag;
02068   
02069   static ID idData(13);
02070   
02071   int i;
02072   for (i = 0; i < 4; i++) {
02073     idData(i) = materialPointers[i]->getClassTag();
02074     matDbTag = materialPointers[i]->getDbTag();
02075     // NOTE: we do have to ensure that the material has a database
02076     // tag if we are sending to a database channel.
02077     if (matDbTag == 0) {
02078       matDbTag = theChannel.getDbTag();
02079                         if (matDbTag != 0)
02080                           materialPointers[i]->setDbTag(matDbTag);
02081     }
02082     idData(i+4) = matDbTag;
02083   }
02084   
02085   idData(8) = this->getTag();
02086   idData(9) = connectedExternalNodes(0);
02087   idData(10) = connectedExternalNodes(1);
02088   idData(11) = connectedExternalNodes(2);
02089   idData(12) = connectedExternalNodes(3);
02090 
02091   res += theChannel.sendID(dataTag, commitTag, idData);
02092   if (res < 0) {
02093     opserr << "WARNING ShellMITC4::sendSelf() - " << this->getTag() << " failed to send ID\n";
02094     return res;
02095   }
02096 
02097   static Vector vectData(1);
02098   vectData(0) = Ktt;
02099 
02100   res += theChannel.sendVector(dataTag, commitTag, vectData);
02101   if (res < 0) {
02102     opserr << "WARNING ShellMITC4::sendSelf() - " << this->getTag() << " failed to send ID\n";
02103     return res;
02104   }
02105 
02106   // Finally, quad asks its material objects to send themselves
02107   for (i = 0; i < 4; i++) {
02108     res += materialPointers[i]->sendSelf(commitTag, theChannel);
02109     if (res < 0) {
02110       opserr << "WARNING ShellMITC4::sendSelf() - " << this->getTag() << " failed to send its Material\n";
02111       return res;
02112     }
02113   }
02114   
02115   return res;
02116 }
02117     
02118 int  ShellMITC4::recvSelf (int commitTag, 
02119                        Channel &theChannel, 
02120                        FEM_ObjectBroker &theBroker)
02121 {
02122   int res = 0;
02123   
02124   int dataTag = this->getDbTag();
02125 
02126   static ID idData(13);
02127   // Quad now receives the tags of its four external nodes
02128   res += theChannel.recvID(dataTag, commitTag, idData);
02129   if (res < 0) {
02130     opserr << "WARNING ShellMITC4::recvSelf() - " << this->getTag() << " failed to receive ID\n";
02131     return res;
02132   }
02133 
02134   this->setTag(idData(8));
02135   connectedExternalNodes(0) = idData(9);
02136   connectedExternalNodes(1) = idData(10);
02137   connectedExternalNodes(2) = idData(11);
02138   connectedExternalNodes(3) = idData(12);
02139 
02140   static Vector vectData(1);
02141   res += theChannel.recvVector(dataTag, commitTag, vectData);
02142   if (res < 0) {
02143     opserr << "WARNING ShellMITC4::sendSelf() - " << this->getTag() << " failed to send ID\n";
02144     return res;
02145   }
02146 
02147   Ktt = vectData(0);
02148 
02149   int i;
02150 
02151   if (materialPointers[0] == 0) {
02152     for (i = 0; i < 4; i++) {
02153       int matClassTag = idData(i);
02154       int matDbTag = idData(i+4);
02155       // Allocate new material with the sent class tag
02156       materialPointers[i] = theBroker.getNewSection(matClassTag);
02157       if (materialPointers[i] == 0) {
02158         opserr << "ShellMITC4::recvSelf() - Broker could not create NDMaterial of class type" << matClassTag << endln;;
02159         return -1;
02160       }
02161       // Now receive materials into the newly allocated space
02162       materialPointers[i]->setDbTag(matDbTag);
02163       res += materialPointers[i]->recvSelf(commitTag, theChannel, theBroker);
02164       if (res < 0) {
02165         opserr << "NLBeamColumn3d::recvSelf() - material " << i <<
02166           "failed to recv itself\n";
02167         return res;
02168       }
02169     }
02170   }
02171   // Number of materials is the same, receive materials into current space
02172   else {
02173     for (i = 0; i < 4; i++) {
02174       int matClassTag = idData(i);
02175       int matDbTag = idData(i+4);
02176       // Check that material is of the right type; if not,
02177       // delete it and create a new one of the right type
02178       if (materialPointers[i]->getClassTag() != matClassTag) {
02179         delete materialPointers[i];
02180         materialPointers[i] = theBroker.getNewSection(matClassTag);
02181         if (materialPointers[i] == 0) {
02182           opserr << "ShellMITC4::recvSelf() - Broker could not create NDMaterial of class type" << matClassTag << endln;
02183           exit(-1);
02184         }
02185       }
02186       // Receive the material
02187       materialPointers[i]->setDbTag(matDbTag);
02188       res += materialPointers[i]->recvSelf(commitTag, theChannel, theBroker);
02189       if (res < 0) {
02190         opserr << "ShellMITC4::recvSelf() - material " << i << "failed to recv itself\n";
02191         return res;
02192       }
02193     }
02194   }
02195   
02196   return res;
02197 }
02198 //**************************************************************************
02199 
02200 int
02201 ShellMITC4::displaySelf(Renderer &theViewer, int displayMode, float fact)
02202 {
02203     // first determine the end points of the quad based on
02204     // the display factor (a measure of the distorted image)
02205     // store this information in 4 3d vectors v1 through v4
02206     const Vector &end1Crd = nodePointers[0]->getCrds();
02207     const Vector &end2Crd = nodePointers[1]->getCrds(); 
02208     const Vector &end3Crd = nodePointers[2]->getCrds(); 
02209     const Vector &end4Crd = nodePointers[3]->getCrds(); 
02210 
02211     static Matrix coords(4,3);
02212     static Vector values(4);
02213     static Vector P(24) ;
02214 
02215     for (int j=0; j<4; j++)
02216       values(j) = 0.0;
02217 
02218     if (displayMode >= 0) {
02219       const Vector &end1Disp = nodePointers[0]->getDisp();
02220       const Vector &end2Disp = nodePointers[1]->getDisp();
02221       const Vector &end3Disp = nodePointers[2]->getDisp();
02222       const Vector &end4Disp = nodePointers[3]->getDisp();
02223       
02224       if (displayMode < 8 && displayMode > 0) {
02225         for (int i=0; i<4; i++) {
02226           const Vector &stress = materialPointers[i]->getStressResultant();
02227           values(i) = stress(displayMode-1);
02228         }
02229       }
02230 
02231       for (int i = 0; i < 3; i++) {
02232         coords(0,i) = end1Crd(i) + end1Disp(i)*fact;
02233         coords(1,i) = end2Crd(i) + end2Disp(i)*fact;    
02234         coords(2,i) = end3Crd(i) + end3Disp(i)*fact;    
02235         coords(3,i) = end4Crd(i) + end4Disp(i)*fact;    
02236 
02237       }
02238     } else {
02239       int mode = displayMode * -1;
02240       const Matrix &eigen1 = nodePointers[0]->getEigenvectors();
02241       const Matrix &eigen2 = nodePointers[1]->getEigenvectors();
02242       const Matrix &eigen3 = nodePointers[2]->getEigenvectors();
02243       const Matrix &eigen4 = nodePointers[3]->getEigenvectors();
02244       if (eigen1.noCols() >= mode) {
02245         for (int i = 0; i < 3; i++) {
02246           coords(0,i) = end1Crd(i) + eigen1(i,mode-1)*fact;
02247           coords(1,i) = end2Crd(i) + eigen2(i,mode-1)*fact;
02248           coords(2,i) = end3Crd(i) + eigen3(i,mode-1)*fact;
02249           coords(3,i) = end4Crd(i) + eigen4(i,mode-1)*fact;
02250         }    
02251       } else {
02252         for (int i = 0; i < 3; i++) {
02253           coords(0,i) = end1Crd(i);
02254           coords(1,i) = end2Crd(i);
02255           coords(2,i) = end3Crd(i);
02256           coords(3,i) = end4Crd(i);
02257         }    
02258       }
02259     }
02260 
02261     //opserr << coords;
02262     int error = 0;
02263 
02264     //error += theViewer.drawPolygon (coords, values);
02265     error += theViewer.drawPolygon (coords, values);
02266 
02267     return error;
02268 }

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