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 #include <stdlib.h>
00035
00036 #include <Channel.h>
00037 #include <FEM_ObjectBroker.h>
00038 #include <Vector.h>
00039 #include <Matrix.h>
00040 #include <MatrixUtil.h>
00041 #include <classTags.h>
00042 #include <SectionAggregator.h>
00043 #include <MaterialResponse.h>
00044 #include <ID.h>
00045
00046 #include <classTags.h>
00047
00048
00049 SectionAggregator::SectionAggregator (int tag, SectionForceDeformation &theSec,
00050 int numAdds, UniaxialMaterial **theAdds,
00051 const ID &addCodes):
00052 SectionForceDeformation(tag, SEC_TAG_Aggregator),
00053 theSection(0), theAdditions(0), code(0), numMats(numAdds), otherDbTag(0)
00054 {
00055 theSection = theSec.getCopy();
00056
00057 if (!theSection)
00058 g3ErrorHandler->fatal("SectionAggregator - failed to get copy of section");
00059
00060 theSectionOrder = theSection->getOrder();
00061
00062 order = numMats + theSectionOrder;
00063
00064 ks = Matrix(order,order);
00065 fs = Matrix(order,order);
00066 s = Vector(order);
00067 e = Vector(order);
00068
00069 if (!theAdds)
00070 g3ErrorHandler->fatal("SectionAggregator - null uniaxial material array passed");
00071
00072 theAdditions = new UniaxialMaterial *[numMats];
00073
00074 if (!theAdditions)
00075 g3ErrorHandler->fatal("SectionAggregator - failed to allocate pointers");
00076
00077 int i;
00078
00079 for (i = 0; i < numMats; i++) {
00080 if (!theAdds[i])
00081 g3ErrorHandler->fatal("SectionAggregator - null uniaxial material pointer passed");
00082
00083 theAdditions[i] = theAdds[i]->getCopy(this);
00084
00085 if (!theAdditions[i])
00086 g3ErrorHandler->fatal("SectionAggregator - failed to copy uniaxial material");
00087 }
00088
00089 code = new ID(order);
00090
00091 if (!code)
00092 g3ErrorHandler->fatal("SectionAggregator - failed to allocate ID");
00093
00094 const ID &secCode = theSection->getType();
00095
00096 for (i = 0; i < theSectionOrder; i++)
00097 (*code)(i) = secCode(i);
00098
00099 for ( ; i < order; i++)
00100 (*code)(i) = addCodes(i-theSectionOrder);
00101 }
00102
00103 SectionAggregator::SectionAggregator (int tag, int numAdds, UniaxialMaterial **theAdds,
00104 const ID &addCodes):
00105 SectionForceDeformation(tag, SEC_TAG_Aggregator),
00106 theSection(0), theAdditions(0), code(0), order(numAdds),
00107 theSectionOrder(0), numMats(numAdds), otherDbTag(0)
00108 {
00109 ks = Matrix(order,order);
00110 fs = Matrix(order,order);
00111 s = Vector(order);
00112 e = Vector(order);
00113
00114 if (!theAdds)
00115 g3ErrorHandler->fatal("SectionAggregator - null uniaxial material array passed");
00116
00117 theAdditions = new UniaxialMaterial *[numMats];
00118
00119 if (!theAdditions)
00120 g3ErrorHandler->fatal("SectionAggregator - failed to allocate pointers");
00121
00122 int i;
00123
00124 for (i = 0; i < numMats; i++) {
00125 if (!theAdds[i])
00126 g3ErrorHandler->fatal("SectionAggregator - null uniaxial material pointer passed");
00127
00128 theAdditions[i] = theAdds[i]->getCopy(this);
00129
00130 if (!theAdditions[i])
00131 g3ErrorHandler->fatal("SectionAggregator - failed to copy uniaxial material");
00132 }
00133
00134 code = new ID(addCodes);
00135
00136 if (!code)
00137 g3ErrorHandler->fatal("SectionAggregator - failed to allocate ID");
00138 }
00139
00140 SectionAggregator::SectionAggregator (int tag, SectionForceDeformation &theSec,
00141 UniaxialMaterial &theAddition, int c) :
00142 SectionForceDeformation(tag, SEC_TAG_Aggregator),
00143 theSection(0), theAdditions(0), code(0), numMats(1), otherDbTag(0)
00144 {
00145 theSection = theSec.getCopy();
00146
00147 if (!theSection)
00148 g3ErrorHandler->fatal("SectionAggregator - failed to get copy of section");
00149
00150 theSectionOrder = theSection->getOrder();
00151
00152 order = 1 + theSectionOrder;
00153
00154 ks = Matrix(order,order);
00155 fs = Matrix(order,order);
00156 s = Vector(order);
00157 e = Vector(order);
00158
00159 theAdditions = new UniaxialMaterial *[1];
00160
00161 theAdditions[0] = theAddition.getCopy(this);
00162
00163 if (!theAdditions[0])
00164 g3ErrorHandler->fatal("SectionAggregator - failed to copy uniaxial material");
00165
00166 code = new ID(order);
00167
00168 if (!code)
00169 g3ErrorHandler->fatal("SectionAggregator - failed to allocate ID");
00170
00171 const ID &secCode = theSection->getType();
00172 int i;
00173
00174 for (i = 0; i < theSectionOrder; i++)
00175 (*code)(i) = secCode(i);
00176
00177 (*code)(i) = c;
00178 }
00179
00180
00181
00182
00183 SectionAggregator::SectionAggregator():
00184 SectionForceDeformation(0, SEC_TAG_Aggregator),
00185 theSection(0), theAdditions(0), code(0), order(0),
00186 theSectionOrder(0), numMats(0), otherDbTag(0)
00187 {
00188
00189 }
00190
00191
00192 SectionAggregator::~SectionAggregator()
00193 {
00194 int i;
00195
00196 if (theSection)
00197 delete theSection;
00198
00199 for (i = 0; i < numMats; i++)
00200 if (theAdditions[i])
00201 delete theAdditions[i];
00202
00203 if (theAdditions)
00204 delete [] theAdditions;
00205
00206 if (code)
00207 delete code;
00208 }
00209
00210 int SectionAggregator::setTrialSectionDeformation (const Vector &deforms)
00211 {
00212 e = deforms;
00213
00214 int ret = 0;
00215 int i = 0;
00216
00217 if (theSection) {
00218 Vector v(theSectionOrder);
00219
00220 for (i = 0; i < theSectionOrder; i++)
00221 v(i) = e(i);
00222
00223 ret = theSection->setTrialSectionDeformation(v);
00224 }
00225
00226 for ( ; i < order; i++)
00227 ret += theAdditions[i-theSectionOrder]->setTrialStrain(e(i));
00228
00229 return ret;
00230 }
00231
00232 const Vector &
00233 SectionAggregator::getSectionDeformation(void)
00234 {
00235 return e;
00236 }
00237
00238 const Matrix &
00239 SectionAggregator::getSectionTangent(void)
00240 {
00241 int i = 0;
00242
00243 if (theSection) {
00244
00245 const Matrix &k = theSection->getSectionTangent();
00246
00247 int j;
00248
00249 for (i = 0; i < theSectionOrder; i++)
00250 for (j = 0; j < theSectionOrder; j++)
00251 ks(i,j) = k(i,j);
00252 }
00253
00254 for ( ; i < order; i++) {
00255 ks(i,i) = theAdditions[i-theSectionOrder]->getTangent();
00256 if (ks(i,i) == 0.0) {
00257 g3ErrorHandler->warning("WARNING SectionAggregator::getSectionTangent - singular section stiffness");
00258 ks(i,i) = 1.e-12;
00259 }
00260 }
00261
00262 return ks;
00263 }
00264
00265 const Matrix &
00266 SectionAggregator::getSectionFlexibility(void)
00267 {
00268 int i = 0;
00269
00270 if (theSection) {
00271
00272 const Matrix &f = theSection->getSectionFlexibility();
00273
00274 int j;
00275
00276 for (i = 0; i < theSectionOrder; i++)
00277 for (j = 0; j < theSectionOrder; j++)
00278 fs(i,j) = f(i,j);
00279 }
00280
00281 double k;
00282
00283 for ( ; i < order; i++) {
00284 k = theAdditions[i-theSectionOrder]->getTangent();
00285 if (k == 0.0) {
00286 g3ErrorHandler->warning("WARNING SectionAggregator::getSectionFlexibility - singular section stiffness");
00287 fs(i,i) = 1.e14;
00288 }
00289 else
00290 fs(i,i) = 1/k;
00291 }
00292
00293 return fs;
00294 }
00295
00296 const Vector &
00297 SectionAggregator::getStressResultant(void)
00298 {
00299 int i = 0;
00300
00301 if (theSection) {
00302
00303 const Vector &p = theSection->getStressResultant();
00304
00305 for (i = 0; i < theSectionOrder; i++)
00306 s(i) = p(i);
00307 }
00308
00309 for ( ; i < order; i++)
00310 s(i) = theAdditions[i-theSectionOrder]->getStress();
00311
00312 return s;
00313 }
00314
00315 SectionForceDeformation *
00316 SectionAggregator::getCopy(void)
00317 {
00318 SectionAggregator *theCopy;
00319
00320 if (theSection) {
00321 ID *c = new ID(numMats);
00322
00323 for (int i = 0; i < numMats; i++)
00324 (*c)(i) = (*code)(i+theSectionOrder);
00325
00326 theCopy = new SectionAggregator (this->getTag(), *theSection, numMats, theAdditions, *c);
00327
00328 delete c;
00329 }
00330 else
00331 theCopy = new SectionAggregator (this->getTag(), order, theAdditions, *code);
00332
00333 if (!theCopy)
00334 g3ErrorHandler->fatal("SectionAggregator::getCopy - failed to allocate copy");
00335
00336 theCopy->e = e;
00337 theCopy->s = s;
00338 theCopy->ks = ks;
00339 theCopy->fs = fs;
00340
00341 return theCopy;
00342 }
00343
00344 const ID&
00345 SectionAggregator::getType () const
00346 {
00347 return *code;
00348 }
00349
00350 int
00351 SectionAggregator::getOrder () const
00352 {
00353 return order;
00354 }
00355
00356 int
00357 SectionAggregator::commitState(void)
00358 {
00359 int err = 0;
00360
00361 if (theSection)
00362 err += theSection->commitState();
00363
00364 for (int i = 0; i < numMats; i++)
00365 err += theAdditions[i]->commitState();
00366
00367 return err;
00368 }
00369
00370 int
00371 SectionAggregator::revertToLastCommit(void)
00372 {
00373 int err = 0;
00374
00375 int i = 0;
00376
00377
00378
00379 if (theSection) {
00380 err += theSection->revertToLastCommit();
00381 const Vector &esec = theSection->getSectionDeformation();
00382
00383 for (i = 0; i < theSectionOrder; i++)
00384 e(i) = esec(i);
00385 }
00386
00387
00388 for ( ; i < order; i++) {
00389 int j = i-theSectionOrder;
00390 err += theAdditions[j]->revertToLastCommit();
00391 e(i) = theAdditions[j]->getStrain();
00392 }
00393
00394 return err;
00395 }
00396
00397 int
00398 SectionAggregator::revertToStart(void)
00399 {
00400 int err = 0;
00401
00402 if (theSection)
00403 err += theSection->revertToStart();
00404
00405 for (int i = 0; i < numMats; i++)
00406 err += theAdditions[i]->revertToStart();
00407
00408
00409 e.Zero();
00410 s.Zero();
00411 ks.Zero();
00412 fs.Zero();
00413
00414 return err;
00415 }
00416
00417 int
00418 SectionAggregator::sendSelf(int cTag, Channel &theChannel)
00419 {
00420 int res = 0;
00421
00422
00423 if (otherDbTag == 0)
00424 otherDbTag = theChannel.getDbTag();
00425
00426
00427 static ID data(5);
00428
00429 data(0) = this->getTag();
00430 data(1) = otherDbTag;
00431 data(2) = order;
00432 data(3) = theSectionOrder;
00433 data(4) = numMats;
00434
00435
00436 res += theChannel.sendID(this->getDbTag(), cTag, data);
00437 if (res < 0) {
00438 g3ErrorHandler->warning("%s -- could not send data ID",
00439 "SectionAggregator::sendSelf");
00440 return res;
00441 }
00442
00443 if (order > 0) {
00444
00445 res += theChannel.sendVector(this->getDbTag(), cTag, e);
00446 if (res < 0) {
00447 g3ErrorHandler->warning("%s -- failed to send section deformations",
00448 "SectionAggregator::sendSelf");
00449 return res;
00450 }
00451 }
00452
00453
00454
00455 int numTags = (theSection == 0) ? numMats : numMats + 1;
00456 ID classTags(2*numTags + order);
00457
00458
00459 int i, dbTag;
00460 for (i = 0; i < numMats; i++) {
00461 classTags(i) = theAdditions[i]->getClassTag();
00462
00463 dbTag = theAdditions[i]->getDbTag();
00464
00465 if (dbTag == 0) {
00466 dbTag = theChannel.getDbTag();
00467 if (dbTag != 0)
00468 theAdditions[i]->setDbTag(dbTag);
00469 }
00470
00471 classTags(i+numTags) = dbTag;
00472 }
00473
00474
00475 if (theSection != 0) {
00476 classTags(numTags-1) = theSection->getClassTag();
00477
00478 dbTag = theSection->getDbTag();
00479
00480 if (dbTag == 0) {
00481 dbTag = theChannel.getDbTag();
00482 if (dbTag != 0)
00483 theSection->setDbTag(dbTag);
00484 }
00485
00486 classTags(2*numTags-1) = dbTag;
00487 }
00488
00489
00490 int j = 2*numTags;
00491 for (i = 0; i < order; i++, j++)
00492 classTags(j) = (*code)(i);
00493
00494
00495 res += theChannel.sendID(otherDbTag, cTag, classTags);
00496 if (res < 0) {
00497 g3ErrorHandler->warning("%s -- could not send classTags ID",
00498 "SectionAggregator::sendSelf");
00499 return res;
00500 }
00501
00502
00503 for (i = 0; i < numMats; i++) {
00504 res += theAdditions[i]->sendSelf(cTag, theChannel);
00505 if (res < 0) {
00506 g3ErrorHandler->warning("%s -- could not send UniaxialMaterial, i = %d",
00507 "SectionAggregator::sendSelf", i);
00508 return res;
00509 }
00510 }
00511
00512
00513 if (theSection != 0) {
00514 res += theSection->sendSelf(cTag, theChannel);
00515 if (res < 0) {
00516 g3ErrorHandler->warning("%s -- could not send SectionForceDeformation",
00517 "SectionAggregator::sendSelf");
00518 return res;
00519 }
00520 }
00521
00522 return res;
00523 }
00524
00525 int
00526 SectionAggregator::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00527 {
00528 int res = 0;
00529
00530
00531 static ID data(5);
00532 res += theChannel.recvID(this->getDbTag(), cTag, data);
00533 if (res < 0) {
00534 g3ErrorHandler->warning("%s -- could not receive data ID",
00535 "SectionAggregator::recvSelf");
00536 return res;
00537 }
00538
00539 this->setTag(data(0));
00540 otherDbTag = data(1);
00541 order = data(2);
00542 theSectionOrder = data(3);
00543 numMats = data(4);
00544
00545 if (order > 0) {
00546
00547 ks = Matrix(order,order);
00548 fs = Matrix(order,order);
00549 s = Vector(order);
00550 e = Vector(order);
00551
00552
00553 res += theChannel.recvVector(this->getDbTag(), cTag, e);
00554 if (res < 0) {
00555 g3ErrorHandler->warning("%s -- failed to receive section deformations",
00556 "SectionAggregator::recvSelf");
00557 return res;
00558 }
00559 }
00560
00561
00562 int numTags = (theSectionOrder == 0) ? numMats : numMats + 1;
00563 ID classTags(numTags*2 + order);
00564
00565
00566 res += theChannel.recvID(otherDbTag, cTag, classTags);
00567 if (res < 0) {
00568 g3ErrorHandler->warning("%s -- could not receive classTags ID",
00569 "SectionAggregator::recvSelf");
00570 return res;
00571 }
00572
00573
00574 if (theAdditions == 0) {
00575 theAdditions = new UniaxialMaterial *[numMats];
00576 if (theAdditions == 0) {
00577 g3ErrorHandler->warning("%s -- could not allocate UniaxialMaterial array",
00578 "SectionAggregator::recvSelf");
00579 return -1;
00580 }
00581
00582 for (int j = 0; j < numMats; j++)
00583 theAdditions[j] = 0;
00584 }
00585
00586
00587 int i, classTag;
00588 for (i = 0; i < numMats; i++) {
00589 classTag = classTags(i);
00590
00591
00592 if (theAdditions[i] == 0)
00593 theAdditions[i] = theBroker.getNewUniaxialMaterial(classTag);
00594
00595
00596
00597 else if (theAdditions[i]->getClassTag() != classTag) {
00598 delete theAdditions[i];
00599 theAdditions[i] = theBroker.getNewUniaxialMaterial(classTag);
00600 }
00601
00602
00603 if (theAdditions[i] == 0) {
00604 g3ErrorHandler->warning("%s -- could not get UniaxialMaterial, i = %d",
00605 "SectionAggregator::recvSelf", i);
00606 return -1;
00607 }
00608
00609
00610 theAdditions[i]->setDbTag(classTags(i+numTags));
00611 res += theAdditions[i]->recvSelf(cTag, theChannel, theBroker);
00612 if (res < 0) {
00613 g3ErrorHandler->warning("%s -- could not receive UniaxialMaterial, i = %d",
00614 "SectionAggregator::recvSelf", i);
00615 return res;
00616 }
00617 }
00618
00619
00620 if (theSectionOrder == 0)
00621 return res;
00622
00623 classTag = classTags(numTags-1);
00624
00625
00626 if (theSection == 0)
00627 theSection = theBroker.getNewSection(classTag);
00628
00629
00630
00631 else if (theSection->getClassTag() != classTag) {
00632 delete theSection;
00633 theSection = theBroker.getNewSection(classTag);
00634 }
00635
00636
00637 if (theSection == 0) {
00638 g3ErrorHandler->warning("%s -- could not get a SectionForceDeformation",
00639 "SectionAggregator::recvSelf");
00640 return -1;
00641 }
00642
00643
00644 theSection->setDbTag(classTags(2*numTags-1));
00645 res += theSection->recvSelf(cTag, theChannel, theBroker);
00646 if (res < 0) {
00647 g3ErrorHandler->warning("%s -- could not receive SectionForceDeformation",
00648 "SectionAggregator::recvSelf");
00649 return res;
00650 }
00651
00652
00653 if (code == 0)
00654 code = new ID(order);
00655 else if (code->Size() != order) {
00656 delete code;
00657 code = new ID(order);
00658 }
00659 if (code == 0) {
00660 g3ErrorHandler->warning("%s -- could not allocate new code ID",
00661 "SectionAggregator::recvSelf");
00662 return -1;
00663 }
00664
00665
00666 int j = 2*numTags;
00667 for (i = 0; i < order; i++, j++)
00668 (*code)(i) = classTags(j);
00669
00670 return res;
00671 }
00672
00673 void
00674 SectionAggregator::Print(ostream &s, int flag)
00675 {
00676 s << "\nSection Aggregator, tag: " << this->getTag() << endl;
00677 s << "\tSection code: " << *code;
00678 if (theSection) {
00679 s << "\tSection, tag: " << theSection->getTag() << endl;
00680 theSection->Print(s, flag);
00681 }
00682 s << "\tUniaxial Additions" << endl;
00683 for (int i = 0; i < numMats; i++)
00684 s << "\t\tUniaxial Material, tag: " << theAdditions[i]->getTag() << endl;
00685 }
00686
00687 Response*
00688 SectionAggregator::setResponse(char **argv, int argc, Information &info)
00689 {
00690
00691 Response *res = SectionForceDeformation::setResponse(argv, argc, info);
00692 if (res != 0)
00693 return res;
00694
00695
00696
00697
00698
00699 else if (theSection != 0)
00700 return theSection->setResponse(argv, argc, info);
00701
00702 else
00703 return 0;
00704 }
00705
00706 int
00707 SectionAggregator::getResponse(int responseID, Information &info)
00708 {
00709
00710
00711 return SectionForceDeformation::getResponse(responseID, info);
00712 }
00713
00714 int
00715 SectionAggregator::setVariable(const char *argv)
00716 {
00717
00718 if (strcmp(argv,"axialStrain") == 0)
00719 return 1;
00720
00721 else if (strcmp(argv,"curvatureZ") == 0)
00722 return 2;
00723
00724 else if (strcmp(argv,"curvatureY") == 0)
00725 return 3;
00726 else
00727 return -1;
00728 }
00729
00730 int
00731 SectionAggregator::getVariable(int variableID, double &info)
00732 {
00733 int i;
00734
00735 info = 0.0;
00736
00737 switch (variableID) {
00738 case 1:
00739
00740 for (i = 0; i < order; i++)
00741 if ((*code)(i) == SECTION_RESPONSE_P)
00742 info += e(i);
00743 return 0;
00744 case 2:
00745 for (i = 0; i < order; i++)
00746 if ((*code)(i) == SECTION_RESPONSE_MZ)
00747 info += e(i);
00748 return 0;
00749 case 3:
00750 for (i = 0; i < order; i++)
00751 if ((*code)(i) == SECTION_RESPONSE_MY)
00752 info += e(i);
00753 return 0;
00754 default:
00755 return -1;
00756 }
00757 }