ParallelMaterial.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.11 $
00022 // $Date: 2006/08/04 18:17:04 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/material/uniaxial/ParallelMaterial.cpp,v $
00024                                                                         
00025                                                                         
00026 // File: ~/material/ParallelModel.C
00027 //
00028 // Written: fmk 
00029 // Created: 07/98
00030 // Revision: A
00031 //
00032 // Description: This file contains the class definition for 
00033 // ParallelModel. ParallelModel is an aggregation
00034 // of UniaxialMaterial objects all considered acting in parallel.
00035 //
00036 // What: "@(#) ParallelModel.C, revA"
00037 
00038 #include <ParallelMaterial.h>
00039 #include <ID.h>
00040 #include <Vector.h>
00041 #include <Channel.h>
00042 #include <FEM_ObjectBroker.h>
00043 #include <stdlib.h>
00044 #include <MaterialResponse.h>
00045 
00046 ParallelMaterial::ParallelMaterial(
00047                                  int tag, 
00048                                  int num, 
00049                                  UniaxialMaterial ** theMaterialModels)
00050 :UniaxialMaterial(tag,MAT_TAG_ParallelMaterial),
00051  trialStrain(0.0), trialStrainRate(0.0), numMaterials(num), theModels(0)
00052 {
00053     // create an array (theModels) to store copies of the MaterialModels
00054     theModels = new UniaxialMaterial *[num];
00055 
00056     if (theModels == 0) {
00057         opserr << "FATAL ParallelMaterial::ParallelMaterial() ";
00058         opserr << " ran out of memory for array of size: " << num << "\n";
00059         exit(-1);
00060     }
00061 
00062     // into the newly created array store a ponter to a copy
00063     // of the UniaxialMaterial stored in theMaterialModels
00064     for (int i=0; i<num; i++) {
00065         theModels[i] = theMaterialModels[i]->getCopy();
00066     }
00067 }
00068 
00069 
00070 
00071 // this constructor is used for a ParallelMaterailModel object that
00072 // needs to be constructed in a remote actor process. recvSelf() needs
00073 // to be called on this object
00074 ParallelMaterial::ParallelMaterial()
00075 :UniaxialMaterial(0,MAT_TAG_ParallelMaterial),
00076  trialStrain(0.0), trialStrainRate(0.0), numMaterials(0), theModels(0)
00077 {
00078 
00079 }
00080 
00081 
00082 ParallelMaterial::~ParallelMaterial()
00083 {
00084     // invoke the destructor on each MaterialModel object
00085     for (int i=0; i<numMaterials; i++)
00086         delete theModels[i];
00087 
00088     // now we can delete the array
00089     if (theModels != 0) // just in case blank constructor called and no recvSelf()
00090         delete [] theModels;
00091 }
00092 
00093 
00094 
00095 int 
00096 ParallelMaterial::setTrialStrain(double strain, double strainRate)
00097 {
00098     // set the trialStrain and the trialStrain in each of the
00099     // local MaterialModel objects 
00100     trialStrain = strain;
00101     trialStrainRate = strainRate;
00102 
00103     for (int i=0; i<numMaterials; i++)
00104       theModels[i]->setTrialStrain(strain, strainRate);
00105 
00106     return 0;
00107 }
00108 
00109 
00110 double 
00111 ParallelMaterial::getStrain(void)
00112 {
00113     return trialStrain;
00114 }
00115 
00116 double 
00117 ParallelMaterial::getStrainRate(void)
00118 {
00119     return trialStrainRate;
00120 }
00121 
00122 double 
00123 ParallelMaterial::getStress(void)
00124 {
00125     // get the stress = sum of stress in all local MaterialModel objects
00126     double stress = 0.0;
00127     for (int i=0; i<numMaterials; i++)
00128       stress +=theModels[i]->getStress();
00129 
00130     return stress;
00131 }
00132 
00133 
00134 
00135 double 
00136 ParallelMaterial::getTangent(void)
00137 {
00138     // get the tangent = sum of tangents in all local MaterialModel objects    
00139     double E = 0.0;
00140     for (int i=0; i<numMaterials; i++)
00141       E +=theModels[i]->getTangent();    
00142 
00143     return E;
00144 }
00145 
00146 double 
00147 ParallelMaterial::getInitialTangent(void)
00148 {
00149     // get the tangent = sum of tangents in all local MaterialModel objects    
00150     double E = 0.0;
00151     for (int i=0; i<numMaterials; i++)
00152       E +=theModels[i]->getInitialTangent();    
00153 
00154     return E;
00155 }
00156 
00157 double 
00158 ParallelMaterial::getDampTangent(void)
00159 {
00160     // get the damp tangent = sum of damp tangents in all local MaterialModel objects    
00161     double eta = 0.0;
00162     for (int i=0; i<numMaterials; i++)
00163       eta +=theModels[i]->getDampTangent();    
00164 
00165     return eta;
00166 }
00167 
00168 int 
00169 ParallelMaterial::commitState(void)
00170 {
00171 
00172     // invoke commitState() on each of local MaterialModel objects
00173     for (int i=0; i<numMaterials; i++)
00174         if (theModels[i]->commitState() != 0) {
00175             opserr << "WARNING ParallelMaterial::commitState() ";
00176             opserr << "MaterialModel failed to commitState():" ;
00177             theModels[i]->Print(opserr);
00178         }
00179     
00180     return 0;    
00181 }
00182 
00183 int 
00184 ParallelMaterial::revertToLastCommit(void)
00185 {
00186     // invoke commitState() on each of local MaterialModel objects
00187     for (int i=0; i<numMaterials; i++)
00188         if (theModels[i]->revertToLastCommit() != 0) {
00189             opserr << "WARNING ParallelMaterial::revertToLastCommit() ";
00190             opserr << "MaterialModel failed to revertToLastCommit():" ;
00191             theModels[i]->Print(opserr);
00192         }
00193     
00194     return 0;    
00195 }
00196 
00197 
00198 int 
00199 ParallelMaterial::revertToStart(void)
00200 {
00201     trialStrain = 0.0;
00202     trialStrainRate = 0.0;
00203 
00204     // invoke commitState() on each of local MaterialModel objects
00205     for (int i=0; i<numMaterials; i++)
00206         if (theModels[i]->revertToStart() != 0) {
00207             opserr << "WARNING ParallelMaterial::revertToStart() ";
00208             opserr << "MaterialModel failed to revertToStart():" ;
00209             theModels[i]->Print(opserr);
00210         }
00211     
00212     return 0;    
00213 }
00214 
00215 
00216 
00217 UniaxialMaterial *
00218 ParallelMaterial::getCopy(void)
00219 {
00220     ParallelMaterial *theCopy = new 
00221       ParallelMaterial(this->getTag(),numMaterials,theModels);
00222 
00223     theCopy->trialStrain = trialStrain;
00224     theCopy->trialStrainRate = trialStrainRate;
00225 
00226     return theCopy;
00227 }
00228 
00229 
00230 int 
00231 ParallelMaterial::sendSelf(int cTag, Channel &theChannel)
00232 {
00233 
00234     int res = 0;
00235 
00236     static ID data(3);
00237 
00238     // send ID of size 3 so no possible conflict with classTags ID
00239     int dbTag = this->getDbTag();
00240     data(0) = this->getTag();
00241     data(1) = numMaterials;
00242     data(2) = 0;
00243 
00244     res = theChannel.sendID(dbTag, cTag, data);
00245     if (res < 0) {
00246       opserr << "ParallelMaterial::sendSelf() - failed to send data\n";
00247       return res;
00248     }
00249 
00250     // now create an ID containing the class tags and dbTags of all
00251     // the MaterialModel objects in this ParallelMaterial
00252     // then send each of the MaterialModel objects
00253     ID classTags(numMaterials*2);
00254     for (int i=0; i<numMaterials; i++) {
00255         classTags(i) = theModels[i]->getClassTag();
00256         int matDbTag = theModels[i]->getDbTag();
00257         if (matDbTag == 0) {
00258           matDbTag  = theChannel.getDbTag();
00259           if (matDbTag != 0)
00260             theModels[i]->setDbTag(matDbTag);
00261         }
00262         classTags(i+numMaterials) = matDbTag;
00263     }
00264 
00265     res = theChannel.sendID(dbTag, cTag, classTags);
00266     if (res < 0) {
00267       opserr << "ParallelMaterial::sendSelf() - failed to send data\n";
00268       return res;
00269     }
00270 
00271     for (int j=0; j<numMaterials; j++)
00272         theModels[j]->sendSelf(cTag, theChannel);
00273     
00274     return 0;
00275 }
00276 
00277 int 
00278 ParallelMaterial::recvSelf(int cTag, Channel &theChannel, 
00279                                 FEM_ObjectBroker &theBroker)
00280 {
00281     int res = 0;
00282     static ID data(3);
00283     int dbTag = this->getDbTag();
00284 
00285     res = theChannel.recvID(dbTag, cTag, data);
00286     if (res < 0) {
00287       opserr << "ParallelMaterial::recvSelf() - failed to send data\n";
00288       return res;
00289     }
00290 
00291     this->setTag(int(data(0)));
00292     int numMaterialsSent = int(data(1));
00293     if (numMaterials != numMaterialsSent) { 
00294       numMaterials = numMaterialsSent;
00295       if (theModels != 0) {
00296         for (int i=0; i<numMaterials; i++)
00297           delete theModels[i];
00298 
00299         delete [] theModels;
00300       }
00301 
00302       theModels = new UniaxialMaterial *[numMaterials];      
00303       if (theModels == 0) {
00304         opserr << "FATAL ParallelMaterial::recvSelf() - ran out of memory";
00305         opserr << " for array of size: " << numMaterials << "\n";
00306         return -2;
00307       }
00308       for (int i=0; i<numMaterials; i++)
00309         theModels[i] = 0;
00310     }
00311 
00312     // create and receive an ID for the classTags and dbTags of the local 
00313     // MaterialModel objects
00314     ID classTags(numMaterials*2);
00315     res = theChannel.recvID(dbTag, cTag, classTags);
00316     if (res < 0) {
00317       opserr << "ParallelMaterial::recvSelf() - failed to send data\n";
00318       return res;
00319     }
00320 
00321     // now for each of the MaterialModel objects, create a new object
00322     // and invoke recvSelf() on it
00323     for (int i=0; i<numMaterials; i++) {
00324       int matClassTag = classTags(i);
00325       if (theModels[i] == 0 || theModels[i]->getClassTag() != matClassTag) {
00326         if (theModels[i] == 0)
00327           delete theModels[i];
00328         UniaxialMaterial *theMaterialModel = 
00329             theBroker.getNewUniaxialMaterial(matClassTag);
00330         if (theMaterialModel != 0) {
00331             theModels[i] = theMaterialModel;
00332             theMaterialModel->setDbTag(classTags(i+numMaterials));
00333         }
00334         else {
00335             opserr << "FATAL ParallelMaterial::recvSelf() ";
00336             opserr << " could not get a UniaxialMaterial \n";
00337             exit(-1);
00338         }           
00339       }
00340       theModels[i]->recvSelf(cTag, theChannel, theBroker);
00341     }
00342     return 0;
00343 }
00344 
00345 void 
00346 ParallelMaterial::Print(OPS_Stream &s, int flag)
00347 {
00348     s << "Parallel tag: " << this->getTag() << endln;
00349     for (int i=0; i<numMaterials; i++) {
00350       s << " ";
00351       theModels[i]->Print(s, flag);
00352     }
00353     
00354 }
00355 
00356 Response*
00357 ParallelMaterial::setResponse(const char **argv, int argc, Information &info, OPS_Stream &theOutput)
00358 {
00359   Response *theResponse = 0;
00360 
00361   theOutput.tag("UniaxialMaterialOutput");
00362   theOutput.attr("matType", this->getClassType());
00363   theOutput.attr("matTag", this->getTag());
00364 
00365   // stress
00366   if (strcmp(argv[0],"stress") == 0) {
00367     theOutput.tag("ResponseType", "sigma11");
00368     theResponse =  new MaterialResponse(this, 1, this->getStress());
00369   }  
00370   // tangent
00371   else if (strcmp(argv[0],"tangent") == 0) {
00372     theOutput.tag("ResponseType", "C11");
00373     theResponse =  new MaterialResponse(this, 2, this->getTangent());
00374   }
00375 
00376   // strain
00377   else if (strcmp(argv[0],"strain") == 0) {
00378     theOutput.tag("ResponseType", "eps11");
00379     theResponse =  new MaterialResponse(this, 3, this->getStrain());
00380   }
00381 
00382   // strain
00383   else if ((strcmp(argv[0],"stressStrain") == 0) || 
00384            (strcmp(argv[0],"stressANDstrain") == 0)) {
00385     theOutput.tag("ResponseType", "sig11");
00386     theOutput.tag("ResponseType", "eps11");
00387     theResponse =  new MaterialResponse(this, 4, Vector(2));
00388   }
00389 
00390   else if (strcmp(argv[0],"stresses") == 0) {
00391     for (int i=0; i<numMaterials; i++) {
00392       theOutput.tag("UniaxialMaterialOutput");
00393       theOutput.attr("matType", this->getClassType());
00394       theOutput.attr("matTag", this->getTag());
00395       theOutput.tag("ResponseType", "sigma11");
00396       theOutput.endTag();
00397     }
00398     theResponse =  new MaterialResponse(this, 100, Vector(numMaterials));
00399   }
00400 
00401   else if (strcmp(argv[0],"material") == 0 ||
00402            strcmp(argv[0],"component") == 0) {
00403     if (argc > 1) {
00404       int matNum = atoi(argv[1]) - 1;
00405       if (matNum >= 0 && matNum < numMaterials)
00406         theResponse =  theModels[matNum]->setResponse(&argv[2], argc-2, info, theOutput);
00407     }
00408   }
00409 
00410   theOutput.endTag();
00411   return theResponse;
00412 }
00413 
00414 int
00415 ParallelMaterial::getResponse(int responseID, Information &info)
00416 {
00417   Vector stresses(numMaterials);
00418   int i;
00419 
00420   switch (responseID) {
00421   case 100:
00422     for (i = 0; i < numMaterials; i++)
00423       stresses(i) = theModels[i]->getStress();
00424     return info.setVector(stresses);
00425 
00426   default:
00427     return this->UniaxialMaterial::getResponse(responseID, info);
00428   }
00429 }

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