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 #include <Subdomain.h>
00037 #include <stdlib.h>
00038
00039 #include <DomainComponent.h>
00040 #include <Element.h>
00041 #include <Node.h>
00042 #include <SP_Constraint.h>
00043 #include <MP_Constraint.h>
00044 #include <MapOfTaggedObjects.h>
00045 #include <DomainDecompositionAnalysis.h>
00046 #include <FE_Element.h>
00047 #include <SingleDomNodIter.h>
00048 #include <classTags.h>
00049 #include <PartitionedModelBuilder.h>
00050 #include <DOF_Group.h>
00051
00052 #include <EquiSolnAlgo.h>
00053 #include <IncrementalIntegrator.h>
00054 #include <LinearSOE.h>
00055
00056 #include <FE_Element.h>
00057
00058 #include <Channel.h>
00059 #include <FEM_ObjectBroker.h>
00060
00061 #include <Timer.h>
00062
00063
00064 Matrix Subdomain::badResult(1,1);
00065
00066
00067 Subdomain::Subdomain(int tag)
00068 :Element(tag,ELE_TAG_Subdomain),
00069 Domain(),
00070 mapBuilt(false),map(0),mappedVect(0),mappedMatrix(0),
00071 realCost(0.0),cpuCost(0),pageCost(0),
00072 theAnalysis(0), extNodes(0), theFEele(0),
00073 thePartitionedModelBuilder(0)
00074 {
00075
00076 internalNodes = new MapOfTaggedObjects();
00077 externalNodes = new MapOfTaggedObjects();
00078
00079
00080 internalNodeIter = new SingleDomNodIter(internalNodes);
00081 externalNodeIter = new SingleDomNodIter(externalNodes);
00082 theNodIter = new SubdomainNodIter(*this);
00083
00084
00085 if (internalNodes == 0 || externalNodes == 0 ||
00086 internalNodeIter == 0 || externalNodeIter == 0 ||
00087 theNodIter == 0) {
00088
00089 opserr << "Subdomain::Subdomain() - ran out of memory\n";
00090 exit(-1);
00091 }
00092 }
00093
00094
00095 Subdomain::Subdomain(int tag,
00096 TaggedObjectStorage &theInternalNodeStorage,
00097 TaggedObjectStorage &theExternalNodeStorage,
00098 TaggedObjectStorage &theElementsStorage,
00099 TaggedObjectStorage &theLoadPatternsStorage,
00100 TaggedObjectStorage &theMPsStorage,
00101 TaggedObjectStorage &theSPsStorage)
00102 :Element(tag,ELE_TAG_Subdomain),
00103 Domain(theExternalNodeStorage, theElementsStorage,
00104 theLoadPatternsStorage,
00105 theMPsStorage,theSPsStorage),
00106 mapBuilt(false),map(0),mappedVect(0),mappedMatrix(0),
00107 internalNodes(&theInternalNodeStorage),
00108 externalNodes(&theExternalNodeStorage),
00109 realCost(0.0),cpuCost(0),pageCost(0),
00110 theAnalysis(0), extNodes(0), theFEele(0),
00111 thePartitionedModelBuilder(0)
00112 {
00113
00114
00115 internalNodeIter = new SingleDomNodIter(internalNodes);
00116 externalNodeIter = new SingleDomNodIter(externalNodes);
00117
00118
00119 if (internalNodes == 0 || externalNodes == 0 ||
00120 internalNodeIter == 0 || externalNodeIter == 0 ||
00121 theNodIter == 0) {
00122
00123 opserr << "Subdomain::Subdomain() - ran out of memory\n";
00124 exit(-1);
00125 }
00126
00127 }
00128
00129
00130 Subdomain::~Subdomain()
00131 {
00132 if (internalNodes != 0)
00133 delete internalNodes;
00134
00135 if (externalNodes != 0)
00136 delete externalNodes;
00137
00138 if (internalNodeIter != 0)
00139 delete internalNodeIter;
00140
00141 if (externalNodeIter != 0)
00142 delete externalNodeIter;
00143
00144 if (map != 0)
00145 delete map;
00146 if (mappedVect != 0)
00147 delete mappedVect;
00148 if (mappedMatrix != 0)
00149 delete mappedMatrix;
00150 }
00151
00152
00153 void
00154 Subdomain::clearAll(void)
00155 {
00156 this->Domain::clearAll();
00157
00158 if (internalNodes != 0)
00159 internalNodes->clearAll();
00160
00161 if (externalNodes != 0)
00162 externalNodes->clearAll();
00163 }
00164
00165 int
00166 Subdomain::buildSubdomain(int numSubdomains, PartitionedModelBuilder &theBuilder)
00167 {
00168 int result = theBuilder.buildSubdomain(this->getTag(), numSubdomains, *this);
00169 if (result == 0) {
00170 this->hasDomainChanged();
00171 this->invokeChangeOnAnalysis();
00172 }
00173 return result;
00174 }
00175
00176
00177
00178
00179
00180
00181 bool
00182 Subdomain::addNode(Node * node)
00183 {
00184 #ifdef _G3DEBUG
00185
00186
00187
00188
00189
00190
00191
00192 #endif
00193
00194 bool result = internalNodes->addComponent(node);
00195 if (result == true) {
00196 node->setDomain(this);
00197 this->domainChange();
00198 }
00199
00200 return result;
00201 }
00202
00203 bool
00204 Subdomain::addExternalNode(Node *thePtr)
00205 {
00206 #ifdef _G3DEBUG
00207
00208
00209 int nodTag = thePtr->getTag();
00210 TaggedObject *other = externalNodes->getComponentPtr(nodTag);
00211 if (other != 0)
00212 return false;
00213
00214 other = internalNodes->getComponentPtr(nodTag);
00215 if (other != 0)
00216 return false;
00217
00218 #endif
00219
00220 Node *newDummy = new Node(*thePtr, false);
00221 if (newDummy == 0)
00222 return false;
00223
00224 bool result = externalNodes->addComponent(newDummy);
00225 if (result == true) {
00226
00227 newDummy->setDomain(this);
00228 this->domainChange();
00229 }
00230
00231 return result;
00232 }
00233
00234
00235
00236 Node *
00237 Subdomain::removeNode(int tag)
00238 {
00239 TaggedObject *object = internalNodes->removeComponent(tag);
00240 if (object == 0) {
00241 object = externalNodes->removeComponent(tag);
00242 if (object != 0) {
00243
00244
00245 Node *result = (Node *)object;
00246 this->domainChange();
00247
00248 return result;
00249 }
00250 }
00251 else {
00252 this->domainChange();
00253 Node *result = (Node *)object;
00254 return result;
00255 }
00256
00257 return 0;
00258 }
00259
00260 NodeIter &
00261 Subdomain::getNodes()
00262 {
00263 theNodIter->reset();
00264 return *theNodIter;
00265 }
00266
00267 Node **
00268 Subdomain::getNodePtrs(void)
00269 {
00270 opserr << "Subdomain::getNodePtrs() - should not be called\n";
00271 return 0;
00272 }
00273
00274 Node *
00275 Subdomain::getNode(int tag)
00276 {
00277
00278 TaggedObject *object = internalNodes->getComponentPtr(tag);
00279 if (object == 0) {
00280 object = externalNodes->getComponentPtr(tag);
00281 if (object != 0) {
00282 Node *result = (Node *)object;
00283 return result;
00284 }
00285 }
00286 else {
00287 Node *result = (Node *)object;
00288 return result;
00289 }
00290
00291 return 0;
00292 }
00293
00294 bool
00295 Subdomain::hasNode(int tag)
00296 {
00297 if (this->getNode(tag) != 0)
00298 return true;
00299 else
00300 return false;
00301 }
00302
00303 bool
00304 Subdomain::hasElement(int tag)
00305 {
00306 if (this->getElement(tag) != 0)
00307 return true;
00308 else
00309 return false;
00310 }
00311
00312
00313 int
00314 Subdomain::getNumNodes(void) const
00315 {
00316 return internalNodes->getNumComponents() +
00317 externalNodes->getNumComponents();
00318 }
00319
00320 int
00321 Subdomain::commit(void)
00322 {
00323 this->Domain::commit();
00324
00325 NodeIter &theNodes = this->getNodes();
00326 Node *nodePtr;
00327 while ((nodePtr = theNodes()) != 0)
00328 nodePtr->commitState();
00329
00330 return 0;
00331 }
00332
00333 int
00334 Subdomain::revertToLastCommit(void)
00335 {
00336 this->Domain::revertToLastCommit();
00337
00338 NodeIter &theNodes = this->getNodes();
00339 Node *nodePtr;
00340 while ((nodePtr = theNodes()) != 0)
00341 nodePtr->revertToLastCommit();
00342
00343 return 0;
00344 }
00345
00346 int
00347 Subdomain::revertToStart(void)
00348 {
00349 this->Domain::revertToLastCommit();
00350
00351 NodeIter &theNodes = this->getNodes();
00352 Node *nodePtr;
00353 while ((nodePtr = theNodes()) != 0)
00354 nodePtr->revertToStart();
00355
00356 return 0;
00357 }
00358
00359 int
00360 Subdomain::update(void)
00361 {
00362 return this->Domain::update();
00363 }
00364
00365 int
00366 Subdomain::update(double newTime, double dT)
00367 {
00368 return this->Domain::update(newTime, dT);
00369 }
00370
00371 void
00372 Subdomain::Print(OPS_Stream &s, int flag)
00373 {
00374 s << "Current Subdomain Information for Subdomain: ";
00375 s << this->getTag() << "\n";
00376
00377 s << "\nINTERNAL NODE DATA: NumNodes: ";
00378 s << internalNodes->getNumComponents() << "\n";
00379 internalNodes->Print(s);
00380
00381 s << "\nEXTERNAL NODE DATA: NumNodes: ";
00382 s << externalNodes->getNumComponents() << "\n";
00383 externalNodes->Print(s);
00384
00385 this->Domain::Print(s);
00386 s << "\nEnd Subdomain Information\n";
00387 }
00388
00389
00390
00391 NodeIter &
00392 Subdomain::getInternalNodeIter(void)
00393 {
00394 internalNodeIter->reset();
00395 return *internalNodeIter;
00396 }
00397
00398
00399 NodeIter &
00400 Subdomain::getExternalNodeIter(void)
00401 {
00402 externalNodeIter->reset();
00403 return *externalNodeIter;
00404 }
00405
00406
00407
00408 void
00409 Subdomain::wipeAnalysis(void)
00410 {
00411 if (theAnalysis != 0) {
00412 theAnalysis->clearAll();
00413 delete theAnalysis;
00414 }
00415 }
00416
00417 void
00418 Subdomain::setDomainDecompAnalysis(DomainDecompositionAnalysis &theNewAnalysis)
00419 {
00420 theAnalysis = &theNewAnalysis;
00421
00422 }
00423
00424
00425 int
00426 Subdomain::setAnalysisAlgorithm(EquiSolnAlgo &theAlgorithm)
00427 {
00428 if (theAnalysis != 0)
00429 return theAnalysis->setAlgorithm(theAlgorithm);
00430 return 0;
00431 }
00432
00433 int
00434 Subdomain::setAnalysisIntegrator(IncrementalIntegrator &theIntegrator)
00435 {
00436 if (theAnalysis != 0)
00437 return theAnalysis->setIntegrator(theIntegrator);
00438 return 0;
00439 }
00440
00441 int
00442 Subdomain::setAnalysisLinearSOE(LinearSOE &theSOE)
00443 {
00444 if (theAnalysis != 0)
00445 return theAnalysis->setLinearSOE(theSOE);
00446 return 0;
00447 }
00448
00449 int
00450 Subdomain::setAnalysisConvergenceTest(ConvergenceTest &theTest)
00451 {
00452 if (theAnalysis != 0)
00453 return theAnalysis->setConvergenceTest(theTest);
00454 return 0;
00455 }
00456
00457 int
00458 Subdomain::invokeChangeOnAnalysis(void)
00459 {
00460 int result = 0;
00461 if (theAnalysis != 0)
00462 result = theAnalysis->domainChanged();
00463
00464 mapBuilt = false;
00465 return result;
00466 }
00467
00468
00469 int
00470 Subdomain::getNumExternalNodes(void) const
00471 {
00472 return externalNodes->getNumComponents();
00473 }
00474
00475 const ID &
00476 Subdomain::getExternalNodes()
00477 {
00478
00479 int numExt = externalNodes->getNumComponents();
00480 if (extNodes == 0) {
00481 extNodes = new ID(numExt);
00482 if (extNodes == 0 || extNodes->Size() != numExt) {
00483 opserr << "Subdomain::getExternalNodes(): ";
00484 opserr << " - ran out of memory for size " << numExt <<endln;
00485 exit(-1);
00486 }
00487 }
00488
00489 if (extNodes->Size() != numExt) {
00490 delete extNodes;
00491 extNodes = new ID(numExt);
00492 if (extNodes == 0 || extNodes->Size() != numExt) {
00493 opserr << "Subdomain::getExternalNodes(): ";
00494 opserr << " - ran out of memory for size " << numExt <<endln;
00495 exit(-1);
00496 }
00497 }
00498
00499
00500
00501
00502 NodeIter &theExtNodes = this->getExternalNodeIter();
00503 Node *nodPtr;
00504 int cnt = 0;
00505
00506 while ((nodPtr = theExtNodes()) != 0)
00507 (*extNodes)(cnt++) = nodPtr->getTag();
00508
00509
00510 ID &res = *extNodes;
00511 return res;
00512 }
00513
00514
00515
00516 int
00517 Subdomain::getNumDOF(void)
00518 {
00519 if (theAnalysis != 0)
00520 return theAnalysis->getNumExternalEqn();
00521 else {
00522
00523 return 0;
00524 }
00525 }
00526
00527 int
00528 Subdomain::commitState(void)
00529 {
00530 return this->commit();
00531 }
00532
00533 const Matrix &
00534 Subdomain::getTangentStiff(void)
00535 {
00536 opserr << "Subdomain::getTangentStiff(void)";
00537 opserr << "DOES NOT DO ANYTHING";
00538 return badResult;
00539 }
00540
00541 const Matrix &
00542 Subdomain::getInitialStiff(void)
00543 {
00544 opserr << "Subdomain::getSecantStiff(void)";
00545 opserr << "DOES NOT DO ANYTHING";
00546 return badResult;
00547 }
00548
00549 const Matrix &
00550 Subdomain::getDamp(void)
00551 {
00552 opserr << "Subdomain::getDamp(void)";
00553 opserr << "DOES NOT DO ANYTHING";
00554 return badResult;
00555 }
00556
00557 const Matrix &
00558 Subdomain::getMass(void)
00559 {
00560 opserr << "Subdomain::getMass(void)";
00561 opserr << "DOES NOT DO ANYTHING";
00562 return badResult;
00563 }
00564
00565
00566
00567
00568 void
00569 Subdomain::zeroLoad(void)
00570 {
00571 opserr << "Subdomain::zeroLoad() - should not be called\n";
00572 }
00573
00574
00575 int
00576 Subdomain::addLoad(ElementalLoad *theLoad, double loadFactor)
00577 {
00578 opserr << "Subdomain::addLoad() - should not be called\n";
00579 return 0;
00580 }
00581
00582 int
00583 Subdomain::addInertiaLoadToUnbalance(const Vector &accel)
00584 {
00585 return 0;
00586 }
00587
00588
00589 const Vector &
00590 Subdomain::getResistingForce(void)
00591 {
00592 if (theAnalysis == 0) {
00593 opserr << "Subdomain::getResistingForce() ";
00594 opserr << " - no StaticCondensationAnalysis has been set\n";
00595 exit(-1);
00596 }
00597
00598 if (mapBuilt == false)
00599 this->buildMap();
00600
00601 ID &theMap = *map;
00602 const Vector &anaResidual = theAnalysis->getResidual();
00603 int numDOF = this->getNumDOF();
00604 for (int i=0; i<numDOF; i++)
00605 (*mappedVect)(i) = anaResidual(theMap(i));
00606
00607 return *mappedVect;
00608 }
00609
00610
00611 const Vector &
00612 Subdomain::getResistingForceIncInertia(void)
00613 {
00614 opserr << "Subdomain::getResistingForceWithInertia() ";
00615 opserr << " - should not be called\n";
00616
00617 return this->getResistingForce();
00618 }
00619
00620
00621
00622 bool
00623 Subdomain::isSubdomain(void)
00624 {
00625 return true;
00626 }
00627
00628
00629 int
00630 Subdomain::setRayleighDampingFactors(double alphaM, double betaK, double betaK0, double betaKc)
00631 {
00632 return this->Domain::setRayleighDampingFactors(alphaM, betaK, betaK0, betaKc);
00633 }
00634
00635 int
00636 Subdomain::computeTang(void)
00637 {
00638 if (theAnalysis != 0) {
00639 theTimer.start();
00640
00641 int res =0;
00642 res = theAnalysis->formTangent();
00643
00644 return res;
00645
00646 } else {
00647 opserr << "Subdomain::getcomputeTang() ";
00648 opserr << " - no StaticCondensationAnalysis has been set\n";
00649 return 0;
00650 }
00651 }
00652
00653
00654
00655 int
00656 Subdomain::computeResidual(void)
00657 {
00658 if (theAnalysis != 0) {
00659 theTimer.start();
00660
00661 int res =0;
00662 res = theAnalysis->formResidual();
00663
00664 theTimer.pause();
00665 realCost += theTimer.getReal();
00666 cpuCost += theTimer.getCPU();
00667 pageCost += theTimer.getNumPageFaults();
00668
00669 return res;
00670
00671 } else {
00672 opserr << "Subdomain::computeResidual() ";
00673 opserr << " - no StaticCondensationAnalysis has been set\n";
00674 return 0;
00675 }
00676 }
00677
00678
00679 const Matrix &
00680 Subdomain::getTang(void)
00681 {
00682 if (theAnalysis == 0) {
00683 opserr << "Subdomain::getTang() ";
00684 opserr << " - no StaticCondensationAnalysis has been set\n";
00685 exit(-1);
00686 }
00687
00688 if (mapBuilt == false)
00689 this->buildMap();
00690
00691 ID &theMap = *map;
00692 const Matrix &anaTang = theAnalysis->getTangent();
00693 int numDOF = this->getNumDOF();
00694 for (int i=0; i<numDOF; i++)
00695 for (int j=0; j<numDOF; j++)
00696 (*mappedMatrix)(i,j) = anaTang(theMap(i),theMap(j));
00697
00698 return *mappedMatrix;
00699 }
00700
00701
00702 void
00703 Subdomain::setFE_ElementPtr(FE_Element *theFE_Ele)
00704 {
00705 theFEele = theFE_Ele;
00706 }
00707
00708
00709 FE_Element *
00710 Subdomain::getFE_ElementPtr(void)
00711 {
00712 return theFEele;
00713 }
00714
00715
00716
00717 const Vector &
00718 Subdomain::getLastExternalSysResponse(void)
00719 {
00720 if (theFEele == 0) {
00721 opserr << "FATAL ERROR: Subdomain::getLastExternalSysResponse() :";
00722 opserr << " - no FE_Element *exists for a subdomain\n";
00723 opserr << " This is the responsibilty of the FE_ELement constructor\n";
00724 exit(0);
00725 }
00726
00727
00728
00729
00730 if (mapBuilt == false)
00731 this->buildMap();
00732
00733 ID &theMap = *map;
00734 const Vector &localResponse = theFEele->getLastResponse();
00735 int numDOF = this->getNumDOF();
00736 for (int i=0; i<numDOF; i++)
00737 (*mappedVect)(theMap(i)) = localResponse(i);
00738
00739 return *mappedVect;
00740 }
00741
00742
00743 int
00744 Subdomain::computeNodalResponse(void)
00745 {
00746 int res =0;
00747 if (theAnalysis != 0) {
00748 res = theAnalysis->computeInternalResponse();
00749 return res;
00750 }
00751 else {
00752 opserr << "Subdomain::computeNodalResponse() ";
00753 opserr << "- no StaticAnalysis has been set\n";
00754 return 0;
00755 }
00756 }
00757
00758
00759 int
00760 Subdomain::newStep(double dT)
00761 {
00762 if (theAnalysis != 0)
00763 return theAnalysis->newStep(dT);
00764
00765 return 0;
00766 }
00767
00768
00769 bool
00770 Subdomain::doesIndependentAnalysis(void)
00771 {
00772 if (theAnalysis != 0)
00773 return theAnalysis->doesIndependentAnalysis();
00774 else
00775 return true;
00776 }
00777
00778
00779 int
00780 Subdomain::sendSelf(int cTag, Channel &theChannel)
00781 {
00782 int dataTag = this->getDbTag();
00783 if (theAnalysis != 0) {
00784 ID data(2);
00785 data(0) = theAnalysis->getClassTag();
00786 data(1) = 0;
00787 theChannel.sendID(dataTag, cTag, data);
00788
00789 return theAnalysis->sendSelf(cTag, theChannel);
00790 }
00791 else {
00792 opserr << "Subdomain::sendSelf - no analysis set\n";
00793
00794 }
00795 return -1;
00796 }
00797
00798 int
00799 Subdomain::recvSelf(int cTag, Channel &theChannel,
00800 FEM_ObjectBroker &theBroker)
00801 {
00802 int dataTag = this->getDbTag();
00803 ID data(2);
00804 theChannel.recvID(dataTag, cTag, data);
00805 if (data(1) == 0) {
00806 theAnalysis = theBroker.getNewDomainDecompAnalysis(data(0),*this);
00807 if (theAnalysis != 0)
00808 return theAnalysis->recvSelf(cTag, theChannel,theBroker);
00809 }
00810 return -1;
00811 }
00812
00813 double
00814 Subdomain::getCost(void)
00815 {
00816 double lastRealCost = realCost;
00817
00818 realCost = 0.0;
00819 cpuCost = 0.0;
00820 pageCost = 0;
00821
00822 return lastRealCost;
00823 }
00824
00825
00826 int
00827 Subdomain::buildMap(void)
00828 {
00829 if (mapBuilt == false) {
00830
00831 int numDOF = this->getNumDOF();
00832 if (map == 0)
00833 map = new ID(numDOF);
00834 if (map->Size() != numDOF) {
00835 delete map;
00836 map = new ID(numDOF);
00837 }
00838
00839
00840 int numInt = theAnalysis->getNumInternalEqn();
00841
00842 const ID &theExtNodes = this->getExternalNodes();
00843 int numExtNodes = theExtNodes.Size();
00844 int locInMap =0;
00845 for (int i=0; i<numExtNodes; i++) {
00846 Node *nodePtr = this->getNode(theExtNodes(i));
00847 int numNodeDOF = nodePtr->getNumberDOF();
00848 DOF_Group *theDOF = nodePtr->getDOF_GroupPtr();
00849 const ID &theLocalID = theDOF->getID();
00850 for (int j=0; j<numNodeDOF; j++){
00851 int locInSubdomainExt = theLocalID(j)-numInt;
00852 (*map)(locInMap)=locInSubdomainExt;
00853 locInMap++;
00854 }
00855 }
00856 mapBuilt = true;
00857
00858 if (mappedVect == 0)
00859 mappedVect = new Vector(numDOF);
00860 if (mappedVect->Size() != numDOF) {
00861 delete mappedVect;
00862 mappedVect = new Vector(numDOF);
00863 }
00864
00865 if (mappedMatrix == 0)
00866 mappedMatrix = new Matrix(numDOF,numDOF);
00867 if (mappedMatrix->noRows() != numDOF) {
00868 delete mappedMatrix;
00869 mappedMatrix = new Matrix(numDOF,numDOF);
00870 }
00871 }
00872
00873 return 0;
00874 }
00875
00876
00877 DomainDecompositionAnalysis *
00878 Subdomain::getDDAnalysis(void)
00879 {
00880 return theAnalysis;
00881 }