FluidSolidPorousMaterial.cpp

Go to the documentation of this file.
00001 // $Revision: 1.21 $
00002 // $Date: 2006/08/04 18:29:48 $
00003 // $Source: /usr/local/cvs/OpenSees/SRC/material/nD/soil/FluidSolidPorousMaterial.cpp,v $
00004                                                                         
00005 // Written: ZHY
00006 
00007 //
00008 // FluidSolidPorousMaterial.cpp
00009 // -------------------
00010 //
00011 #include <math.h>
00012 #include <stdlib.h>
00013 #include <FluidSolidPorousMaterial.h>
00014 #include <Information.h>
00015 #include <MaterialResponse.h>
00016 #include <ID.h>
00017 #include <FEM_ObjectBroker.h>
00018 
00019 int* FluidSolidPorousMaterial::loadStagex = 0;
00020 int* FluidSolidPorousMaterial::ndmx = 0;
00021 double* FluidSolidPorousMaterial::combinedBulkModulusx = 0;
00022 int FluidSolidPorousMaterial::matCount = 0;
00023 double FluidSolidPorousMaterial::pAtm = 101;
00024 
00025 Vector FluidSolidPorousMaterial::workV3(3);
00026 Vector FluidSolidPorousMaterial::workV6(6);
00027 Matrix FluidSolidPorousMaterial::workM3(3,3);
00028 Matrix FluidSolidPorousMaterial::workM6(6,6);
00029 
00030 FluidSolidPorousMaterial::FluidSolidPorousMaterial (int tag, int nd, NDMaterial &soilMat,
00031                                                     double combinedBulkModul, double atm)
00032  : NDMaterial(tag, ND_TAG_FluidSolidPorousMaterial)
00033 {
00034   if (combinedBulkModul < 0) {
00035     opserr << "WARNING:FluidSolidPorousMaterial::FluidSolidPorousMaterial: combinedBulkModulus < 0" << endln;
00036     opserr << "Will reset to 0." <<endln;
00037     combinedBulkModul = 0.;
00038   }
00039 
00040   if (matCount%20 == 0) {
00041      int * temp1 = loadStagex;
00042          int * temp2 = ndmx;
00043          double * temp3 = combinedBulkModulusx;
00044      loadStagex = new int[matCount+20];
00045      ndmx = new int[matCount+20];
00046          combinedBulkModulusx = new double[matCount+20];
00047          for (int i=0; i<matCount; i++) {
00048          loadStagex[i] = temp1[i];
00049                  ndmx[i] = temp2[i];
00050                  combinedBulkModulusx[i] = temp3[i];
00051          }
00052          if (matCount > 0) {
00053              delete [] temp1; delete [] temp2; delete [] temp3;
00054          }
00055   }
00056 
00057   ndmx[matCount] = nd;
00058   loadStagex[matCount] = 0;  //default
00059   combinedBulkModulusx[matCount] = combinedBulkModul;
00060   matN = matCount;
00061   matCount ++;
00062   pAtm = atm;
00063 
00064   theSoilMaterial = soilMat.getCopy();
00065   trialExcessPressure = currentExcessPressure = 0.;
00066   trialVolumeStrain = currentVolumeStrain = 0.;
00067   initMaxPress = 0.;
00068   e2p = 0;
00069 }
00070    
00071 
00072 FluidSolidPorousMaterial::FluidSolidPorousMaterial () 
00073  : NDMaterial(0,ND_TAG_FluidSolidPorousMaterial), theSoilMaterial(0)
00074 {
00075   trialExcessPressure = currentExcessPressure = 0.;
00076   trialVolumeStrain = currentVolumeStrain = 0.;
00077   initMaxPress = 0.;
00078   e2p = 0;
00079 }
00080 
00081 
00082 FluidSolidPorousMaterial::FluidSolidPorousMaterial (const FluidSolidPorousMaterial & a)
00083  : NDMaterial(a.getTag(),ND_TAG_FluidSolidPorousMaterial)
00084 {
00085         matN = a.matN;
00086     theSoilMaterial = a.theSoilMaterial->getCopy();
00087     trialExcessPressure = a.trialExcessPressure;
00088         currentExcessPressure = a.currentExcessPressure;
00089         trialVolumeStrain = a.trialVolumeStrain;
00090         currentVolumeStrain = a.currentVolumeStrain;
00091         initMaxPress = a.initMaxPress;
00092         e2p = a.e2p;
00093 }
00094 
00095 
00096 FluidSolidPorousMaterial::~FluidSolidPorousMaterial ()
00097 {
00098         if (theSoilMaterial != 0)
00099                 delete theSoilMaterial;
00100 }
00101 
00102 
00103 int FluidSolidPorousMaterial::setTrialStrain (const Vector &strain)
00104 {
00105         int ndm = ndmx[matN];
00106 
00107         if (ndm==2 && strain.Size()==3)
00108                 trialVolumeStrain = strain[0]+strain[1];
00109         else if (ndm==3 && strain.Size()==6)
00110                 trialVolumeStrain = strain[0]+strain[1]+strain[2];
00111         else {
00112                 opserr << "Fatal:FluidSolidPorousMaterial:: Material dimension is: " << ndm << endln;
00113                 opserr << "But strain vector size is: " << strain.Size() << endln;
00114                 exit(-1);;
00115         }
00116 
00117   return theSoilMaterial->setTrialStrain(strain);
00118 }
00119 
00120 
00121 int FluidSolidPorousMaterial::setTrialStrain (const Vector &strain, const Vector &rate)
00122 {
00123         int ndm = ndmx[matN];
00124 
00125         if (ndm==2 && strain.Size()==3)
00126                 trialVolumeStrain = strain[0]+strain[1];
00127         else if (ndm==3 && strain.Size()==6)
00128                 trialVolumeStrain = strain[0]+strain[1]+strain[2];
00129         else {
00130                 opserr << "Fatal:FluidSolidPorousMaterial:: Material dimension is: " << ndm << endln;
00131                 opserr << "But strain vector size is: " << strain.Size() << endln;
00132                 exit(-1);;
00133         }
00134 
00135   return theSoilMaterial->setTrialStrain(strain, rate);
00136 }
00137 
00138 
00139 int FluidSolidPorousMaterial::setTrialStrainIncr (const Vector &strain)
00140 {
00141         int ndm = ndmx[matN];
00142 
00143         if (ndm==2 && strain.Size()==3)
00144                 trialVolumeStrain = currentVolumeStrain + strain[0]+strain[1];
00145         else if (ndm==3 && strain.Size()==6)
00146                 trialVolumeStrain = currentVolumeStrain + strain[0]+strain[1]+strain[2];
00147         else {
00148                 opserr << "Fatal:FluidSolidPorousMaterial:: Material dimension is: " << ndm << endln;
00149                 opserr << "But strain vector size is: " << strain.Size() << endln;
00150                 exit(-1);;
00151         }
00152 
00153   return theSoilMaterial->setTrialStrainIncr(strain);
00154 }
00155 
00156 
00157 int FluidSolidPorousMaterial::setTrialStrainIncr (const Vector &strain, const Vector &rate)
00158 {
00159         int ndm = ndmx[matN];
00160 
00161         if (ndm==2 && strain.Size()==3)
00162                 trialVolumeStrain = currentVolumeStrain + strain[0]+strain[1];
00163         else if (ndm==3 && strain.Size()==6)
00164                 trialVolumeStrain = currentVolumeStrain + strain[0]+strain[1]+strain[2];
00165         else {
00166                 opserr << "Fatal:FluidSolidPorousMaterial:: Material dimension is: " << ndm << endln;
00167                 opserr << "But strain vector size is: " << strain.Size() << endln;
00168                 exit(-1);;
00169         }
00170 
00171   return theSoilMaterial->setTrialStrainIncr(strain, rate);
00172 }
00173 
00174 
00175 const Matrix & FluidSolidPorousMaterial::getTangent (void)
00176 {
00177         int ndm = ndmx[matN];
00178         int loadStage = loadStagex[matN];
00179         double combinedBulkModulus = combinedBulkModulusx[matN];
00180 
00181         Matrix *workM = (ndm == 2) ? &workM3 : &workM6;
00182   
00183         *workM = theSoilMaterial->getTangent();
00184 
00185         if (loadStage != 0) { 
00186           for (int i=0; i<ndm; i++) 
00187                   for (int j=0; j<ndm; j++) 
00188                           (*workM)(i,j) = (*workM)(i,j) + combinedBulkModulus;
00189   }
00190 
00191         return *workM;
00192 }
00193 
00194 const Matrix & FluidSolidPorousMaterial::getInitialTangent (void)
00195 {
00196         int ndm = ndmx[matN];
00197 
00198         Matrix *workM = (ndm == 2) ? &workM3 : &workM6;
00199   
00200         *workM = theSoilMaterial->getInitialTangent();
00201 
00202         return *workM;
00203 }
00204 
00205 double FluidSolidPorousMaterial::getRho(void)
00206 {
00207   return theSoilMaterial->getRho();
00208 }
00209 
00210 const Vector & FluidSolidPorousMaterial::getStress (void)
00211 {
00212         int ndm = ndmx[matN];
00213         int loadStage = loadStagex[matN];
00214         double combinedBulkModulus = combinedBulkModulusx[matN];
00215 
00216         Vector *workV = (ndm == 2) ? &workV3 : &workV6;
00217 
00218         *workV = theSoilMaterial->getStress();
00219 
00220         if (loadStage != 0) { 
00221                 if (e2p==0) {
00222                         e2p = 1;
00223                         initMaxPress = ((*workV)[0] < (*workV)[1]) ? (*workV)[0] : (*workV)[1]; 
00224                         if (ndm == 3)
00225                                 initMaxPress = (initMaxPress < (*workV)[2]) ? initMaxPress : (*workV)[2];
00226                 }
00227                 trialExcessPressure = currentExcessPressure;
00228         trialExcessPressure += 
00229                                (trialVolumeStrain - currentVolumeStrain) * combinedBulkModulus;
00230                 if (trialExcessPressure > pAtm-initMaxPress) 
00231                         trialExcessPressure = pAtm-initMaxPress;
00232                 //if (trialExcessPressure < initMaxPress)
00233                 //      trialExcessPressure = initMaxPress;
00234           for (int i=0; i<ndm; i++) 
00235       (*workV)[i] += trialExcessPressure;
00236         }
00237 
00238   return *workV;
00239 }
00240 
00241 
00242 int FluidSolidPorousMaterial::updateParameter(int responseID, Information &info)
00243 {
00244         if (responseID<10)
00245                 loadStagex[matN] = responseID;
00246         else {
00247                 if (responseID==11) combinedBulkModulusx[matN]=info.theDouble;
00248         }
00249 
00250   return 0;
00251 }
00252 
00253 
00254 const Vector & FluidSolidPorousMaterial::getCommittedStress (void)
00255 {
00256         return theSoilMaterial->getCommittedStress();
00257 }
00258 
00259 
00260 const Vector & FluidSolidPorousMaterial::getCommittedStrain (void)
00261 {
00262         return theSoilMaterial->getCommittedStrain();
00263 }
00264 
00265 
00266 const Vector & FluidSolidPorousMaterial::getCommittedPressure (void)
00267 {
00268         int ndm = ndmx[matN];
00269 
00270         static Vector temp(2);
00271         
00272         temp[0] = currentExcessPressure;
00273         temp[1] = temp[0]/initMaxPress;
00274     
00275         return temp;
00276 }
00277 
00278 
00279 const Vector & FluidSolidPorousMaterial::getStrain (void)
00280 {
00281   return theSoilMaterial->getStrain();
00282 }
00283 
00284 
00285 int FluidSolidPorousMaterial::commitState (void)
00286 {
00287         int loadStage = loadStagex[matN];
00288 
00289         currentVolumeStrain = trialVolumeStrain;
00290         if (loadStage != 0) 
00291                 currentExcessPressure = trialExcessPressure;
00292         else
00293         currentExcessPressure = 0.;
00294 
00295         return theSoilMaterial->commitState();
00296 }
00297 
00298 
00299 int FluidSolidPorousMaterial::revertToLastCommit (void)
00300 {
00301         return theSoilMaterial->revertToLastCommit();
00302 }
00303 
00304 int FluidSolidPorousMaterial::revertToStart (void)
00305 {
00306         return theSoilMaterial->revertToStart();
00307 }
00308 
00309 NDMaterial * FluidSolidPorousMaterial::getCopy (void)
00310 {
00311   FluidSolidPorousMaterial * copy = new FluidSolidPorousMaterial(*this);
00312         return copy;
00313 }
00314 
00315 
00316 NDMaterial * FluidSolidPorousMaterial::getCopy (const char *code)
00317 {
00318         if (strcmp(code,"FluidSolidPorous") == 0 || strcmp(code,"PlaneStrain") == 0 ||
00319                 strcmp(code,"ThreeDimensional") == 0) {
00320      FluidSolidPorousMaterial * copy = new FluidSolidPorousMaterial(*this);
00321            return copy;
00322         }
00323 
00324         return 0;
00325 }
00326 
00327 
00328 const char * FluidSolidPorousMaterial::getType (void) const
00329 {
00330         int ndm = ndmx[matN];
00331 
00332         return (ndm == 2) ? "PlaneStrain" : "ThreeDimensional";
00333 }
00334 
00335 
00336 int FluidSolidPorousMaterial::getOrder (void) const
00337 {
00338         int ndm = ndmx[matN];
00339 
00340         return (ndm == 2) ? 3 : 6;
00341 }
00342 
00343 
00344 int FluidSolidPorousMaterial::sendSelf(int commitTag, Channel &theChannel)
00345 {
00346         int ndm = ndmx[matN];
00347         int loadStage = loadStagex[matN];
00348         double combinedBulkModulus = combinedBulkModulusx[matN];
00349 
00350         int res = 0;
00351 
00352         static Vector data(7);
00353         data(0) = this->getTag();
00354         data(1) = ndm;
00355         data(2) = loadStage;
00356     data(3) = combinedBulkModulus;
00357         data(4) = currentExcessPressure;
00358     data(5) = currentVolumeStrain;
00359         data(6) = matN;
00360 
00361     res += theChannel.sendVector(this->getDbTag(), commitTag, data);
00362         if (res < 0) {
00363           opserr << "FluidSolidPorousMaterial::sendSelf -- could not send Vector\n";
00364              
00365                 return res;
00366         }
00367 
00368         ID classTags(2);
00369 
00370         classTags(0) = theSoilMaterial->getClassTag();
00371         int matDbTag = theSoilMaterial->getDbTag();
00372         // NOTE: we do have to ensure that the material has a database
00373         // tag if we are sending to a database channel.
00374         if (matDbTag == 0) {
00375                 matDbTag = theChannel.getDbTag();
00376                 if (matDbTag != 0)
00377                         theSoilMaterial->setDbTag(matDbTag);
00378         }
00379         classTags(1) = matDbTag;
00380 
00381         res += theChannel.sendID(this->getDbTag(), commitTag, classTags);
00382         if (res < 0) {
00383           opserr << "WARNING FluidSolidPorousMaterial::sendSelf() - " << this->getTag() << " failed to send ID\n";
00384           
00385           return res;
00386         }
00387 
00388         // Finally, asks the material object to send itself
00389         res += theSoilMaterial->sendSelf(commitTag, theChannel);
00390         if (res < 0) {
00391           opserr << "WARNING FluidSolidPorousMaterial::sendSelf() - " << this->getTag() << " failed to send its Material\n";
00392           return res;
00393         }
00394 
00395         return res;
00396 }
00397 
00398 
00399 
00400 
00401 int FluidSolidPorousMaterial::recvSelf(int commitTag, Channel &theChannel, 
00402                  FEM_ObjectBroker &theBroker)    
00403 {
00404         int res = 0;
00405 
00406         static Vector data(7);
00407 
00408         res += theChannel.recvVector(this->getDbTag(), commitTag, data);
00409         if (res < 0) {
00410           opserr << "FluidSolidPorousMaterial::recvSelf -- could not receive Vector\n";
00411           return res;
00412         }
00413     
00414         this->setTag((int)data(0));
00415         int ndm = data(1);
00416         int loadStage = data(2);
00417         double combinedBulkModulus = data(3);
00418         currentExcessPressure = data(4);
00419         currentVolumeStrain = data(5);
00420     matN = data(6);
00421 
00422         ndmx[matN] = ndm;
00423         loadStagex[matN] = loadStage;
00424         combinedBulkModulusx[matN] = combinedBulkModulus;
00425 
00426         // now receives the ids of its material
00427         ID classTags(2);
00428 
00429         res += theChannel.recvID(this->getDbTag(), commitTag, classTags);
00430         if (res < 0)  {
00431           opserr << "FluidSolidPorousMaterial::recvSelf() - failed to recv ID data\n";
00432           return res;
00433         }    
00434         
00435         int matClassTag = classTags(0);
00436         int matDbTag = classTags(1);
00437         // Check that material is of the right type; if not,
00438         // delete it and create a new one of the right type
00439         if (theSoilMaterial == 0 || theSoilMaterial->getClassTag() != matClassTag) {
00440           if (theSoilMaterial != 0)
00441             delete theSoilMaterial;
00442           theSoilMaterial = theBroker.getNewNDMaterial(matClassTag);
00443           if (theSoilMaterial == 0) {
00444             opserr << "FluidSolidPorousMaterial::recvSelf() - " <<
00445               "Broker could not create NDMaterial of class type" << matClassTag << endln;
00446             exit(-1);
00447           }
00448         }
00449 
00450         // Receive the material
00451         theSoilMaterial->setDbTag(matDbTag);
00452         res += theSoilMaterial->recvSelf(commitTag, theChannel, theBroker);
00453         if (res < 0) {
00454           opserr << "FluidSolidPorousMaterial::recvSelf() - material failed to recv itself\n";
00455           return res;
00456         }
00457 
00458         return res;
00459 }
00460 
00461 
00462 Response*
00463 FluidSolidPorousMaterial::setResponse (const char **argv, int argc, Information &matInfo, OPS_Stream &output)
00464 {
00465   if (strcmp(argv[0],"stress") == 0 || strcmp(argv[0],"stresses") == 0)
00466     return new MaterialResponse(this, 1, this->getCommittedStress());
00467   
00468   else if (strcmp(argv[0],"strain") == 0 || strcmp(argv[0],"strains") == 0)
00469     return new MaterialResponse(this, 2, this->getCommittedStrain());
00470   
00471   else if (strcmp(argv[0],"tangent") == 0)
00472     return new MaterialResponse(this, 3, this->getTangent());
00473   
00474   else if (strcmp(argv[0],"backbone") == 0)
00475     return theSoilMaterial->setResponse(argv, argc, matInfo, output);
00476   
00477   else if (strcmp(argv[0],"pressure") == 0)
00478     return new MaterialResponse(this, 5, this->getCommittedPressure());
00479   
00480   else
00481     return 0;
00482 }
00483 
00484 
00485 int FluidSolidPorousMaterial::getResponse (int responseID, Information &matInfo)
00486 {
00487   switch (responseID) {
00488   case 1:
00489     return matInfo.setVector(this->getCommittedStress());
00490     
00491   case 2:
00492     return matInfo.setVector(this->getCommittedStrain());
00493     
00494   case 3:
00495     return matInfo.setMatrix(this->getTangent());
00496     
00497   case 4:
00498     return theSoilMaterial->getResponse(responseID, matInfo);
00499     
00500   case 5:
00501     return matInfo.setVector(this->getCommittedPressure());
00502     
00503   default:
00504     return -1;
00505   }
00506 }
00507 
00508 
00509 void FluidSolidPorousMaterial::Print(OPS_Stream &s, int flag )
00510 {
00511         s << "FluidSolidPorousMaterial" << endln;
00512 }
00513 
00514 
00515 
00516 
00517 
00518 
00519 
00520 
00521 
00522 
00523 
00524 
00525 
00526 
00527 

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