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

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