PlaneStressMaterial.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.3 $
00022 // $Date: 2003/02/14 23:01:25 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/material/nD/PlaneStressMaterial.cpp,v $
00024 
00025 //
00026 // Ed "C++" Love
00027 //
00028 // Generic Plane Stress Material
00029 //
00030 
00031 
00032 #include <PlaneStressMaterial.h>
00033 #include <Channel.h>
00034 #include <FEM_ObjectBroker.h>
00035 
00036 //static vector and matrices
00037 Vector  PlaneStressMaterial::stress(3) ;
00038 Matrix  PlaneStressMaterial::tangent(3,3) ;
00039 
00040 
00041 
00042 //null constructor
00043 PlaneStressMaterial::PlaneStressMaterial( ) : 
00044 NDMaterial(0, ND_TAG_PlaneStressMaterial ), 
00045 strain(3) 
00046 { }
00047 
00048 
00049 
00050 //full constructor
00051 PlaneStressMaterial::PlaneStressMaterial(    
00052                                    int tag, 
00053                                    NDMaterial &the3DMaterial ) :
00054 NDMaterial( tag, ND_TAG_PlaneStressMaterial ),
00055 strain(3)
00056 {
00057   theMaterial = the3DMaterial.getCopy("ThreeDimensional") ;
00058 
00059   Tstrain22 = 0.0 ;
00060   Tgamma02 = 0.0 ;
00061   Tgamma12 = 0.0 ;
00062   Cstrain22 = 0.0 ;
00063   Cgamma02 = 0.0 ;
00064   Cgamma12 = 0.0 ;
00065 }
00066 
00067 
00068 
00069 //destructor
00070 PlaneStressMaterial::~PlaneStressMaterial( ) 
00071 { 
00072   delete theMaterial ;
00073 } 
00074 
00075 
00076 
00077 //make a clone of this material
00078 NDMaterial*
00079 PlaneStressMaterial::getCopy( ) 
00080 {
00081   PlaneStressMaterial *clone ;   //new instance of this class
00082 
00083   clone = new PlaneStressMaterial( this->getTag(), 
00084                                    *theMaterial ) ; //make the copy
00085 
00086   clone->Tstrain22 = this->Tstrain22 ;
00087   clone->Tgamma02  = this->Tgamma02 ;
00088   clone->Tgamma12  = this->Tgamma12 ;
00089   clone->Cstrain22 = this->Cstrain22 ;
00090   clone->Cgamma02  = this->Cgamma02 ;
00091   clone->Cgamma12  = this->Cgamma12 ;
00092 
00093   return clone ;
00094 }
00095 
00096 
00097 //make a clone of this material
00098 NDMaterial* 
00099 PlaneStressMaterial::getCopy( const char *type ) 
00100 {
00101   return this->getCopy( ) ;
00102 }
00103 
00104 
00105 //send back order of strain in vector form
00106 int 
00107 PlaneStressMaterial::getOrder( ) const
00108 {
00109   return 3 ;
00110 }
00111 
00112 
00113 const char*
00114 PlaneStressMaterial::getType( ) const 
00115 {
00116   return "PlaneStress" ; 
00117 }
00118 
00119 
00120 
00121 //swap history variables
00122 int 
00123 PlaneStressMaterial::commitState( ) 
00124 {
00125   Cstrain22 = Tstrain22;
00126   Cgamma02 = Tgamma02;
00127   Cgamma12 = Tgamma12;
00128 
00129   return theMaterial->commitState( ) ;
00130 }
00131 
00132 
00133 
00134 //revert to last saved state
00135 int 
00136 PlaneStressMaterial::revertToLastCommit( )
00137 {
00138   Tstrain22 = Cstrain22;
00139   Tgamma02 = Cgamma02;
00140   Tgamma12 = Cgamma12;
00141 
00142   return theMaterial->revertToLastCommit( )  ;
00143 }
00144 
00145 
00146 //revert to start
00147 int
00148 PlaneStressMaterial::revertToStart( )
00149 {
00150   this->Tstrain22 = 0.0 ;
00151   this->Tgamma12  = 0.0 ;
00152   this->Tgamma02  = 0.0 ;
00153   this->Cstrain22 = 0.0 ;
00154   this->Cgamma12  = 0.0 ;
00155   this->Cgamma02  = 0.0 ;
00156   
00157   strain.Zero();
00158 
00159   return theMaterial->revertToStart( ) ;
00160 }
00161 
00162 
00163 //mass per unit volume
00164 double
00165 PlaneStressMaterial::getRho( )
00166 {
00167   return theMaterial->getRho( ) ;
00168 }
00169 
00170 
00171 //receive the strain
00172 int 
00173 PlaneStressMaterial::setTrialStrain( const Vector &strainFromElement )
00174 {
00175   static const double tolerance = 1.0e-08 ;
00176 
00177   this->strain(0) = strainFromElement(0) ;
00178   this->strain(1) = strainFromElement(1) ;
00179   this->strain(2) = strainFromElement(2) ;
00180 
00181   // return theMaterial->setTrialStrain( threeDstrain ) ;
00182   double norm ;
00183 
00184   static Vector outOfPlaneStress(3) ;
00185   static Vector strainIncrement(3) ;
00186   static Vector threeDstress(6) ;
00187   static Vector threeDstrain(6) ;
00188   static Matrix threeDtangent(6,6) ;
00189   static Vector threeDstressCopy(6) ; 
00190   static Matrix threeDtangentCopy(6,6) ;
00191 
00192   static Matrix dd22(3,3) ;
00193 
00194   int i, j ;
00195   int ii, jj ;
00196 
00197   //newton loop to solve for out-of-plane strains
00198   do {
00199 
00200     //set three dimensional strain
00201     threeDstrain(0) = this->strain(0) ;
00202     threeDstrain(1) = this->strain(1) ;
00203     threeDstrain(2) = this->Tstrain22 ;
00204     threeDstrain(3) = this->strain(2) ; 
00205     threeDstrain(4) = this->Tgamma12 ;
00206     threeDstrain(5) = this->Tgamma02 ;
00207 
00208     if (theMaterial->setTrialStrain( threeDstrain ) < 0) {
00209       opserr << "PlaneStressMaterial::setTrialStrain() - setTrialStrain in material failed with strain " << threeDstrain;
00210       return -1;
00211     }
00212 
00213     //three dimensional stress
00214     threeDstress = theMaterial->getStress( ) ;
00215 
00216     //three dimensional tangent 
00217     threeDtangent = theMaterial->getTangent( ) ;
00218 
00219     //NDmaterial strain order          = 11, 22, 33, 12, 23, 31 
00220     //PlaneStressMaterial strain order = 11, 22, 12, 33, 23, 31 
00221 
00222     //swap matrix indices to sort out-of-plane components 
00223     for ( i=0; i<6; i++ ) {
00224 
00225       ii = this->indexMap(i) ;
00226 
00227       threeDstressCopy(ii) = threeDstress(i) ;
00228 
00229       for ( j=0; j<6; j++ ) {
00230 
00231         jj = this->indexMap(j) ;
00232         
00233         threeDtangentCopy(ii,jj) = threeDtangent(i,j) ;
00234 
00235       }//end for j
00236        
00237     }//end for i
00238 
00239 
00240     //partitioned stresses and tangent
00241     for ( i=0; i<3; i++ ) {
00242 
00243       outOfPlaneStress(i) = threeDstressCopy(i+3) ;
00244 
00245       for ( j=0; j<3; j++ ) 
00246         dd22(i,j) = threeDtangentCopy(i+3,j+3) ;
00247 
00248     }//end for i
00249 
00250 
00251     //set norm
00252     norm = outOfPlaneStress.Norm( ) ;
00253 
00254     //int Solve(const Vector &V, Vector &res) const;
00255     //int Solve(const Matrix &M, Matrix &res) const;
00256     //condensation 
00257     dd22.Solve( outOfPlaneStress, strainIncrement ) ;
00258 
00259     //update out of plane strains
00260     this->Tstrain22 -= strainIncrement(0) ;
00261     this->Tgamma12  -= strainIncrement(1) ;
00262     this->Tgamma02  -= strainIncrement(2) ;
00263 
00264   } while ( norm > tolerance ) ;
00265 
00266   return 0;
00267 }
00268 
00269 
00270 //send back the strain
00271 const Vector& 
00272 PlaneStressMaterial::getStrain( )
00273 {
00274   return this->strain ;
00275 }
00276 
00277 
00278 //send back the stress 
00279 const Vector&  
00280 PlaneStressMaterial::getStress( )
00281 {
00282   //three dimensional stress
00283   const Vector &threeDstress = theMaterial->getStress();
00284   static Vector threeDstressCopy(6);
00285 
00286   //partitioned stresses and tangent
00287   //swap matrix indices to sort out-of-plane components 
00288   int i, ii;
00289   for ( i=0; i<6; i++ ) {
00290 
00291     ii = this->indexMap(i) ;
00292 
00293     threeDstressCopy(ii) = threeDstress(i) ;
00294   }
00295 
00296   for ( i=0; i<3; i++ ) 
00297     this->stress(i)     = threeDstressCopy(i) ;
00298   
00299   return this->stress ;
00300 }
00301 
00302 
00303 //send back the tangent 
00304 const Matrix&  
00305 PlaneStressMaterial::getTangent( )
00306 {
00307   static Matrix dd11(3,3) ;
00308   static Matrix dd12(3,3) ;
00309   static Matrix dd21(3,3) ;
00310   static Matrix dd22(3,3) ;
00311 
00312   static Matrix dd22invdd21(3,3) ;
00313   static Matrix threeDtangentCopy(6,6);
00314 
00315   //three dimensional tangent 
00316   const Matrix &threeDtangent = theMaterial->getTangent( ) ;
00317 
00318   //NDmaterial strain order          = 11, 22, 33, 12, 23, 31 
00319   //PlaneStressMaterial strain order = 11, 22, 12, 33, 23, 31 
00320 
00321   //swap matrix indices to sort out-of-plane components 
00322   int i,j, ii, jj;
00323 
00324   for ( i=0; i<6; i++ ) {
00325 
00326     ii = this->indexMap(i) ;
00327 
00328     for ( j=0; j<6; j++ ) {
00329       jj = this->indexMap(j) ;
00330       threeDtangentCopy(ii,jj) = threeDtangent(i,j) ;
00331     }//end for j
00332 
00333   }//end for i
00334 
00335 
00336   //out of plane stress and tangents
00337   for ( i=0; i<3; i++ ) {
00338     for ( j=0; j<3; j++ ) {
00339         
00340       dd11(i,j) = threeDtangentCopy(i,  j  ) ;
00341       dd12(i,j) = threeDtangentCopy(i,  j+3) ;
00342       dd21(i,j) = threeDtangentCopy(i+3,j  ) ;
00343       dd22(i,j) = threeDtangentCopy(i+3,j+3) ;
00344 
00345     }//end for j
00346   }//end for i
00347 
00348   //int Solve(const Vector &V, Vector &res) const;
00349   //int Solve(const Matrix &M, Matrix &res) const;
00350   //condensation 
00351   dd22.Solve( dd21, dd22invdd21 ) ;
00352   this->tangent   = dd11 ; 
00353   this->tangent  -= ( dd12*dd22invdd21 ) ;
00354 
00355   return this->tangent ;
00356 }
00357 
00358 
00359 
00360 int 
00361 PlaneStressMaterial::indexMap( int i )
00362 {
00363   int ii ;
00364 
00365   if ( i == 2 ) 
00366     ii = 3 ;
00367   else if ( i == 3 )
00368     ii = 2 ;
00369   else 
00370     ii = i ;
00371 
00372   return ii ;
00373 }
00374 
00375 
00376 
00377 //print out data
00378 void  
00379 PlaneStressMaterial::Print( OPS_Stream &s, int flag )
00380 {
00381   s << "General Plane Stress Material \n" ;
00382   s << " Tag: " << this->getTag() << "\n" ; 
00383   s << "using the 3D material : \n" ;
00384 
00385   theMaterial->Print( s, flag ) ;
00386 
00387   return ;
00388 }
00389 
00390 
00391 int 
00392 PlaneStressMaterial::sendSelf(int commitTag, Channel &theChannel) 
00393 {
00394   int res = 0;
00395 
00396   // put tag and assocaited materials class and database tags into an id and send it
00397   static ID idData(3);
00398   idData(0) = this->getTag();
00399   idData(1) = theMaterial->getClassTag();
00400   int matDbTag = theMaterial->getDbTag();
00401   if (matDbTag == 0) {
00402     matDbTag = theChannel.getDbTag();
00403     theMaterial->setDbTag(matDbTag);
00404   }
00405   idData(2) = matDbTag;
00406 
00407   res = theChannel.sendID(this->getDbTag(), commitTag, idData);
00408   if (res < 0) {
00409     opserr << "PlaneStressMaterial::sendSelf() - failed to send id data\n";
00410     return res;
00411   }
00412 
00413   // put the strains in a vector and send it
00414   static Vector vecData(3);
00415   vecData(0) = Cstrain22;
00416   vecData(1) = Cgamma02;
00417   vecData(2) = Cgamma12;
00418 
00419   res = theChannel.sendVector(this->getDbTag(), commitTag, vecData);
00420   if (res < 0) {
00421     opserr << "PlaneStressMaterial::sendSelf() - failed to send vector data\n";
00422     return res;
00423   }
00424 
00425   // now send the materials data
00426   res = theMaterial->sendSelf(commitTag, theChannel);
00427   if (res < 0) 
00428     opserr << "PlaneStressMaterial::sendSelf() - failed to send vector material\n";
00429 
00430   return res;
00431 }
00432 
00433 int 
00434 PlaneStressMaterial::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00435 {
00436   int res = 0;
00437 
00438   // recv an id containg the tag and associated materials class and db tags
00439   static ID idData(3);
00440   res = theChannel.sendID(this->getDbTag(), commitTag, idData);
00441   if (res < 0) {
00442     opserr << "PlaneStressMaterial::sendSelf() - failed to send id data\n";
00443     return res;
00444   }
00445 
00446   this->setTag(idData(0));
00447   int matClassTag = idData(1);
00448   
00449   // if the associated material has not yet been created or is of the wrong type
00450   // create a new material for recvSelf later
00451   if (theMaterial == 0 || theMaterial->getClassTag() != matClassTag) {
00452     if (theMaterial != 0)
00453       delete theMaterial;
00454     theMaterial = theBroker.getNewNDMaterial(matClassTag);
00455     if (theMaterial == 0) {
00456       opserr << "PlaneStressMaterial::recvSelf() - failed to get a material of type: " << matClassTag << endln;
00457       return -1;
00458     }
00459   }
00460   theMaterial->setDbTag(idData(2));
00461 
00462   // recv a vector containing strains and set the strains
00463   static Vector vecData(3);
00464   res = theChannel.recvVector(this->getDbTag(), commitTag, vecData);
00465   if (res < 0) {
00466     opserr << "PlaneStressMaterial::sendSelf() - failed to send vector data\n";
00467     return res;
00468   }
00469 
00470   Cstrain22 = vecData(0);
00471   Cgamma02 = vecData(1);
00472   Cgamma12  = vecData(2);
00473 
00474   Tstrain22 = Cstrain22;
00475   Tgamma02 = Cgamma02;
00476   Tgamma12  = Cgamma12;
00477 
00478   // now receive the materials data
00479   res = theMaterial->recvSelf(commitTag, theChannel, theBroker);
00480   if (res < 0) 
00481     opserr << "PlaneStressMaterial::sendSelf() - failed to send vector material\n";
00482   
00483   return res;
00484 }
00485  
00486 
00487 

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