00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
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
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
00063
00064 for (int i=0; i<num; i++) {
00065 theModels[i] = theMaterialModels[i]->getCopy();
00066 }
00067 }
00068
00069
00070
00071
00072
00073
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
00085 for (int i=0; i<numMaterials; i++)
00086 delete theModels[i];
00087
00088
00089 if (theModels != 0)
00090 delete [] theModels;
00091 }
00092
00093
00094
00095 int
00096 ParallelMaterial::setTrialStrain(double strain, double strainRate)
00097 {
00098
00099
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
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
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
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
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
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
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
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
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
00251
00252
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
00313
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
00322
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
00366 if (strcmp(argv[0],"stress") == 0) {
00367 theOutput.tag("ResponseType", "sigma11");
00368 theResponse = new MaterialResponse(this, 1, this->getStress());
00369 }
00370
00371 else if (strcmp(argv[0],"tangent") == 0) {
00372 theOutput.tag("ResponseType", "C11");
00373 theResponse = new MaterialResponse(this, 2, this->getTangent());
00374 }
00375
00376
00377 else if (strcmp(argv[0],"strain") == 0) {
00378 theOutput.tag("ResponseType", "eps11");
00379 theResponse = new MaterialResponse(this, 3, this->getStrain());
00380 }
00381
00382
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 }