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
00039 #include <PartitionedDomain.h>
00040 #include <stdlib.h>
00041
00042 #include <DomainPartitioner.h>
00043 #include <Element.h>
00044 #include <Node.h>
00045 #include <SP_Constraint.h>
00046 #include <MP_Constraint.h>
00047 #include <ArrayOfTaggedObjects.h>
00048 #include <ArrayOfTaggedObjectsIter.h>
00049 #include <Subdomain.h>
00050 #include <DomainPartitioner.h>
00051 #include <PartitionedDomain.h>
00052 #include <PartitionedDomainEleIter.h>
00053 #include <PartitionedDomainSubIter.h>
00054 #include <SingleDomEleIter.h>
00055 #include <Vertex.h>
00056 #include <Graph.h>
00057 #include <LoadPattern.h>
00058 #include <NodalLoad.h>
00059 #include <ElementalLoad.h>
00060 #include <SP_Constraint.h>
00061 #include <Recorder.h>
00062
00063 PartitionedDomain::PartitionedDomain()
00064 :Domain(),
00065 theSubdomains(0),theDomainPartitioner(0),
00066 theSubdomainIter(0), mySubdomainGraph(0)
00067 {
00068 elements = new ArrayOfTaggedObjects(1024);
00069 theSubdomains = new ArrayOfTaggedObjects(32);
00070 theSubdomainIter = new PartitionedDomainSubIter(theSubdomains);
00071
00072 mainEleIter = new SingleDomEleIter(elements);
00073 theEleIter = new PartitionedDomainEleIter(this);
00074
00075 if (theSubdomains == 0 || elements == 0 ||
00076 theSubdomainIter == 0 ||
00077 theEleIter == 0 || mainEleIter == 0) {
00078
00079 opserr << "FATAL: PartitionedDomain::PartitionedDomain ";
00080 opserr << " - ran out of memory\n";
00081 exit(-1);
00082 }
00083 }
00084
00085
00086 PartitionedDomain::PartitionedDomain(DomainPartitioner &thePartitioner)
00087 :Domain(),
00088 theSubdomains(0),theDomainPartitioner(&thePartitioner),
00089 theSubdomainIter(0), mySubdomainGraph(0)
00090 {
00091 elements = new ArrayOfTaggedObjects(1024);
00092 theSubdomains = new ArrayOfTaggedObjects(32);
00093 theSubdomainIter = new PartitionedDomainSubIter(theSubdomains);
00094
00095 mainEleIter = new SingleDomEleIter(elements);
00096 theEleIter = new PartitionedDomainEleIter(this);
00097
00098 if (theSubdomains == 0 || elements == 0 ||
00099 theSubdomainIter == 0 || theDomainPartitioner == 0 ||
00100 theEleIter == 0 || mainEleIter == 0) {
00101
00102 opserr << "FATAL: PartitionedDomain::PartitionedDomain ";
00103 opserr << " - ran out of memory\n";
00104 exit(-1);
00105 }
00106 }
00107
00108
00109 PartitionedDomain::PartitionedDomain(int numNodes, int numElements,
00110 int numSPs, int numMPs, int numLoadPatterns,
00111 int numSubdomains,
00112 DomainPartitioner &thePartitioner)
00113
00114 :Domain(numNodes,0,numSPs,numMPs,numLoadPatterns),
00115 theSubdomains(0),theDomainPartitioner(&thePartitioner),
00116 theSubdomainIter(0), mySubdomainGraph(0)
00117 {
00118 elements = new ArrayOfTaggedObjects(numElements);
00119 theSubdomains = new ArrayOfTaggedObjects(numSubdomains);
00120 theSubdomainIter = new PartitionedDomainSubIter(theSubdomains);
00121
00122 mainEleIter = new SingleDomEleIter(elements);
00123 theEleIter = new PartitionedDomainEleIter(this);
00124
00125 if (theSubdomains == 0 || elements == 0 ||
00126 theSubdomainIter == 0 ||
00127 theEleIter == 0 || mainEleIter == 0) {
00128
00129 opserr << "FATAL: PartitionedDomain::PartitionedDomain(int ..) ";
00130 opserr << " - ran out of memory\n";
00131 exit(-1);
00132 }
00133 }
00134
00135
00136
00137
00138 PartitionedDomain::~PartitionedDomain()
00139 {
00140 this->clearAll();
00141
00142 if (elements != 0)
00143 delete elements;
00144
00145 if (theSubdomains != 0)
00146 delete theSubdomains;
00147
00148 if (theSubdomainIter != 0)
00149 delete theSubdomainIter;
00150
00151 if (theEleIter != 0)
00152 delete theEleIter;
00153 }
00154
00155 void
00156 PartitionedDomain::clearAll(void)
00157 {
00158 this->Domain::clearAll();
00159 elements->clearAll();
00160
00161 SubdomainIter &mySubdomains = this->getSubdomains();
00162 Subdomain *theSub;
00163 while ((theSub = mySubdomains()) != 0)
00164 theSub->clearAll();
00165
00166 theSubdomains->clearAll();
00167 }
00168
00169
00170
00171 bool
00172 PartitionedDomain::addElement(Element *elePtr)
00173 {
00174 if (elePtr->isSubdomain() == true)
00175 return this->addSubdomain((Subdomain *)elePtr);
00176
00177 int eleTag = elePtr->getTag();
00178 #ifdef _DEBUG
00179 if (check == true) {
00180
00181
00182 if (eleTag < 0) {
00183 opserr << "PartitionedDomain::addElement - Element " << eleTag;
00184 opserr << " tag must be >= 0\n";
00185 return false;
00186 }
00187
00188
00189
00190
00191
00192 const ID &nodes = elePtr->getExternalNodes();
00193 for (int i=0; i<nodes.Size(); i++) {
00194 int nodeTag = nodes(i);
00195 Node *nodePtr = this->getNode(nodeTag);
00196 if (nodePtr == 0) {
00197 opserr << "PartitionedDomain::addElement - In element " << eleTag;
00198 opserr << " no node " << nodeTag << " exists in the domain\n";
00199 return false;
00200 }
00201 }
00202
00203 }
00204 #endif
00205
00206 TaggedObject *other = elements->getComponentPtr(eleTag);
00207 if (other != 0)
00208 return false;
00209
00210 bool result = elements->addComponent(elePtr);
00211 if (result == true) {
00212 elePtr->setDomain(this);
00213 this->domainChange();
00214 }
00215
00216 return result;
00217 }
00218
00219
00220
00221 bool
00222 PartitionedDomain::addNode(Node *nodePtr)
00223 {
00224 #ifdef _DEBUG
00225 if (check == true) {
00226
00227
00228
00229 }
00230 #endif
00231 return (this->Domain::addNode(nodePtr));
00232 }
00233
00234
00235
00236 bool
00237 PartitionedDomain::addSP_Constraint(SP_Constraint *load)
00238 {
00239 int nodeTag = load->getNodeTag();
00240
00241
00242
00243
00244 Node *nodePtr = this->getNode(nodeTag);
00245 if (nodePtr != 0) {
00246 return (this->Domain::addSP_Constraint(load));
00247 }
00248
00249
00250 SubdomainIter &theSubdomains = this->getSubdomains();
00251 Subdomain *theSub;
00252 while ((theSub = theSubdomains()) != 0) {
00253 bool res = theSub->hasNode(nodeTag);
00254 if (res == true)
00255 return theSub->addSP_Constraint(load);
00256 }
00257
00258
00259
00260 opserr << "PartitionedDomain::addSP_Constraint - cannot add as node with tag" <<
00261 nodeTag << "does not exist in model\n";
00262
00263 return false;
00264
00265 }
00266
00267 bool
00268 PartitionedDomain::addSP_Constraint(SP_Constraint *load, int pattern)
00269 {
00270 int nodeTag = load->getNodeTag();
00271
00272
00273
00274
00275 Node *nodePtr = this->getNode(nodeTag);
00276 if (nodePtr != 0) {
00277 return (this->Domain::addSP_Constraint(load, pattern));
00278 }
00279
00280
00281 SubdomainIter &theSubdomains = this->getSubdomains();
00282 Subdomain *theSub;
00283 while ((theSub = theSubdomains()) != 0) {
00284 bool res = theSub->hasNode(nodeTag);
00285 if (res == true)
00286 return theSub->addSP_Constraint(load, pattern);
00287 }
00288
00289
00290
00291 opserr << "PartitionedDomain::addSP_Constraint - cannot add as node with tag" <<
00292 nodeTag << "does not exist in model\n";
00293
00294 return false;
00295
00296 }
00297
00298 bool
00299 PartitionedDomain::addLoadPattern(LoadPattern *loadPattern)
00300 {
00301 bool result = true;
00302
00303 int tag = loadPattern->getTag();
00304 if (this->getLoadPattern(tag) != 0) {
00305 opserr << "PartitionedDomain::addLoadPattern - cannot add as LoadPattern with tag" <<
00306 tag << "already exists in model\n";
00307 return false;
00308 }
00309
00310 SubdomainIter &theSubdomains = this->getSubdomains();
00311 Subdomain *theSub;
00312 while ((theSub = theSubdomains()) != 0) {
00313 bool res = theSub->addLoadPattern(loadPattern);
00314 if (res != true) {
00315 opserr << "PartitionedDomain::addLoadPattern - cannot add as LoadPattern with tag: " <<
00316 tag << " to subdomain\n";
00317 result = res;
00318 }
00319 }
00320
00321 this->Domain::addLoadPattern(loadPattern);
00322
00323 return result;
00324 }
00325
00326
00327 bool
00328 PartitionedDomain::addNodalLoad(NodalLoad *load, int pattern)
00329 {
00330 int nodeTag = load->getNodeTag();
00331
00332
00333
00334
00335 Node *nodePtr = this->getNode(nodeTag);
00336 if (nodePtr != 0) {
00337 return (this->Domain::addNodalLoad(load, pattern));
00338 }
00339
00340
00341
00342 SubdomainIter &theSubdomains = this->getSubdomains();
00343 Subdomain *theSub;
00344 while ((theSub = theSubdomains()) != 0) {
00345 bool res = theSub->hasNode(nodeTag);
00346 if (res == true) {
00347
00348 return theSub->addNodalLoad(load, pattern);
00349 }
00350 }
00351
00352
00353 opserr << "PartitionedDomain::addNodalLoad - cannot add as node with tag" <<
00354 nodeTag << "does not exist in model\n";
00355 return false;
00356 }
00357
00358
00359 bool
00360 PartitionedDomain::addElementalLoad(ElementalLoad *load, int pattern)
00361 {
00362 opserr << "PartitionedDomain::addElementalLoad - not yet implemented\n";
00363 return false;
00364 }
00365
00366
00367 Element *
00368 PartitionedDomain::removeElement(int tag)
00369 {
00370
00371 TaggedObject *res = elements->removeComponent(tag);
00372 Element *result = 0;
00373 if (res != 0) {
00374 result = (Element *)res;
00375 this->domainChange();
00376 return result;
00377 }
00378
00379
00380 if (theSubdomains != 0) {
00381 ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains);
00382 TaggedObject *theObject;
00383 while ((theObject = theSubsIter()) != 0) {
00384 Subdomain *theSub = (Subdomain *)theObject;
00385 result = theSub->removeElement(tag);
00386 if (result != 0) {
00387 return result;
00388 }
00389 }
00390 }
00391
00392
00393 return 0;
00394 }
00395
00396
00397 Node *
00398 PartitionedDomain::removeNode(int tag)
00399 {
00400
00401 Node *result = this->Domain::removeNode(tag);
00402
00403
00404 if (theSubdomains != 0) {
00405 ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains);
00406 TaggedObject *theObject;
00407 while ((theObject = theSubsIter()) != 0) {
00408 Subdomain *theSub = (Subdomain *)theObject;
00409 Node *res = theSub->removeNode(tag);
00410 if (res != 0)
00411 result = res;
00412 }
00413 }
00414
00415 if (result != 0)
00416 this->domainChange();
00417
00418 return result;
00419 }
00420
00421 SP_Constraint *
00422 PartitionedDomain::removeSP_Constraint(int tag)
00423 {
00424
00425 SP_Constraint *result = this->Domain::removeSP_Constraint(tag);
00426 if (result != 0) {
00427 this->domainChange();
00428 return result;
00429 }
00430
00431
00432
00433 if (theSubdomains != 0) {
00434 ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains);
00435 TaggedObject *theObject;
00436 while ((theObject = theSubsIter()) != 0) {
00437 Subdomain *theSub = (Subdomain *)theObject;
00438 result = theSub->removeSP_Constraint(tag);
00439 if (result != 0) {
00440 return result;
00441 }
00442 }
00443 }
00444
00445
00446 return 0;
00447 }
00448
00449
00450 MP_Constraint *
00451 PartitionedDomain::removeMP_Constraint(int tag)
00452 {
00453
00454 MP_Constraint *result = this->Domain::removeMP_Constraint(tag);
00455 if (result != 0) {
00456 this->domainChange();
00457 return result;
00458 }
00459
00460
00461 if (theSubdomains != 0) {
00462 ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains);
00463 TaggedObject *theObject;
00464 while ((theObject = theSubsIter()) != 0) {
00465 Subdomain *theSub = (Subdomain *)theObject;
00466 result = theSub->removeMP_Constraint(tag);
00467 if (result != 0) {
00468 return result;
00469 }
00470 }
00471 }
00472
00473
00474 return 0;
00475 }
00476
00477
00478 LoadPattern *
00479 PartitionedDomain::removeLoadPattern(int tag)
00480 {
00481
00482 LoadPattern *result = this->Domain::removeLoadPattern(tag);
00483
00484
00485 if (theSubdomains != 0) {
00486 ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains);
00487 TaggedObject *theObject;
00488 while ((theObject = theSubsIter()) != 0) {
00489 Subdomain *theSub = (Subdomain *)theObject;
00490 LoadPattern *res = theSub->removeLoadPattern(tag);
00491 if (res != 0)
00492 result = res;
00493 }
00494 }
00495
00496 if (result != 0)
00497 this->domainChange();
00498
00499 return result;
00500 }
00501
00502
00503 ElementIter &
00504 PartitionedDomain::getElements()
00505 {
00506 theEleIter->reset();
00507 return *theEleIter;
00508 }
00509
00510
00511 Element *
00512 PartitionedDomain::getElement(int tag)
00513 {
00514
00515 TaggedObject *res = elements->getComponentPtr(tag);
00516 Element *result =0;
00517 if (res != 0) {
00518 result = (Element *)res;
00519 return result;
00520 }
00521
00522
00523 if (theSubdomains != 0) {
00524 ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains);
00525 TaggedObject *theObject;
00526 while ((theObject = theSubsIter()) != 0) {
00527 Subdomain *theSub = (Subdomain *)theObject;
00528 result = theSub->getElement(tag);
00529 if (result != 0)
00530 return result;
00531 }
00532 }
00533
00534
00535 return 0;
00536 }
00537
00538
00539 int
00540 PartitionedDomain::getNumElements(void) const
00541 {
00542 int result = elements->getNumComponents();
00543
00544
00545 result += theSubdomains->getNumComponents();
00546 return result;
00547 }
00548
00549 void
00550 PartitionedDomain::applyLoad(double timeStep)
00551 {
00552 this->Domain::applyLoad(timeStep);
00553
00554
00555 if (theSubdomains != 0) {
00556 ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains);
00557 TaggedObject *theObject;
00558 while ((theObject = theSubsIter()) != 0) {
00559 Subdomain *theSub = (Subdomain *)theObject;
00560 theSub->applyLoad(timeStep);
00561 }
00562 }
00563 }
00564
00565
00566 void
00567 PartitionedDomain::setCommitTag(int newTag)
00568 {
00569 this->Domain::setCommitTag(newTag);
00570
00571
00572 if (theSubdomains != 0) {
00573 ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains);
00574 TaggedObject *theObject;
00575 while ((theObject = theSubsIter()) != 0) {
00576 Subdomain *theSub = (Subdomain *)theObject;
00577 theSub->setCommitTag(newTag);
00578 }
00579 }
00580 }
00581
00582
00583
00584 void
00585 PartitionedDomain::setCurrentTime(double newTime)
00586 {
00587 this->Domain::setCurrentTime(newTime);
00588
00589
00590 if (theSubdomains != 0) {
00591 ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains);
00592 TaggedObject *theObject;
00593 while ((theObject = theSubsIter()) != 0) {
00594 Subdomain *theSub = (Subdomain *)theObject;
00595 theSub->setCurrentTime(newTime);
00596 }
00597 }
00598 }
00599
00600
00601 void
00602 PartitionedDomain::setCommittedTime(double newTime)
00603 {
00604 this->Domain::setCommittedTime(newTime);
00605
00606
00607 if (theSubdomains != 0) {
00608 ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains);
00609 TaggedObject *theObject;
00610 while ((theObject = theSubsIter()) != 0) {
00611 Subdomain *theSub = (Subdomain *)theObject;
00612 theSub->setCommittedTime(newTime);
00613 }
00614 }
00615 }
00616
00617
00618 void
00619 PartitionedDomain::setLoadConstant(void)
00620 {
00621 this->Domain::setLoadConstant();
00622
00623
00624 if (theSubdomains != 0) {
00625 ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains);
00626 TaggedObject *theObject;
00627 while ((theObject = theSubsIter()) != 0) {
00628 Subdomain *theSub = (Subdomain *)theObject;
00629 theSub->setLoadConstant();
00630 }
00631 }
00632 }
00633
00634
00635 int
00636 PartitionedDomain::update(void)
00637 {
00638 int res = this->Domain::update();
00639
00640
00641 if (theSubdomains != 0) {
00642 ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains);
00643 TaggedObject *theObject;
00644 while ((theObject = theSubsIter()) != 0) {
00645 Subdomain *theSub = (Subdomain *)theObject;
00646 theSub->computeNodalResponse();
00647 theSub->update();
00648 }
00649 }
00650
00651 #ifdef _PARALLEL_PROCESSING
00652 return this->barrierCheck(res);
00653 #endif
00654 return 0;
00655 }
00656
00657
00658
00659
00660 #ifdef _PARALLEL_PROCESSING
00661 int
00662 PartitionedDomain::barrierCheck(int res)
00663 {
00664 int result = res;
00665
00666
00667 if (theSubdomains != 0) {
00668 ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains);
00669 TaggedObject *theObject;
00670 while ((theObject = theSubsIter()) != 0) {
00671 Subdomain *theSub = (Subdomain *)theObject;
00672 int subResult = theSub->barrierCheckIN();
00673 if (subResult != 0)
00674 result = subResult;
00675 }
00676
00677 ArrayOfTaggedObjectsIter theSubsIter1(*theSubdomains);
00678 while ((theObject = theSubsIter1()) != 0) {
00679 Subdomain *theSub = (Subdomain *)theObject;
00680 theSub->barrierCheckOUT(result);
00681 }
00682 }
00683
00684 return result;
00685 }
00686 #endif
00687
00688 int
00689 PartitionedDomain::update(double newTime, double dT)
00690 {
00691 this->applyLoad(newTime);
00692 int res = this->Domain::update();
00693
00694
00695 if (theSubdomains != 0) {
00696 ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains);
00697 TaggedObject *theObject;
00698 while ((theObject = theSubsIter()) != 0) {
00699 Subdomain *theSub = (Subdomain *)theObject;
00700 theSub->computeNodalResponse();
00701 theSub->update(newTime, dT);
00702 }
00703 }
00704
00705 #ifdef _PARALLEL_PROCESSING
00706 return this->barrierCheck(res);
00707 #endif
00708 return 0;
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735 }
00736
00737
00738
00739 int
00740 PartitionedDomain::newStep(double dT)
00741 {
00742 this->Domain::newStep(dT);
00743
00744 int res = 0;
00745
00746 if (theSubdomains != 0) {
00747 ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains);
00748 TaggedObject *theObject;
00749 while ((theObject = theSubsIter()) != 0) {
00750 Subdomain *theSub = (Subdomain *)theObject;
00751 res += theSub->newStep(dT);
00752 if (res != 0)
00753 opserr << "PartitionedDomain::step - subdomain " << theSub->getTag() << " failed in step\n";
00754 }
00755 }
00756 return res;
00757 }
00758
00759
00760
00761
00762 int
00763 PartitionedDomain::commit(void)
00764 {
00765 int result = this->Domain::commit();
00766 if (result < 0) {
00767 opserr << "PartitionedDomain::commit(void) - failed in Domain::commit()\n";
00768 return result;
00769 }
00770
00771
00772 if (theSubdomains != 0) {
00773 ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains);
00774 TaggedObject *theObject;
00775 while ((theObject = theSubsIter()) != 0) {
00776 Subdomain *theSub = (Subdomain *)theObject;
00777 int res = theSub->commit();
00778 if (res < 0) {
00779 opserr << "PartitionedDomain::commit(void)";
00780 opserr << " - failed in Subdomain::commit()\n";
00781 return res;
00782 }
00783 }
00784 }
00785
00786
00787 int numSubdomains = this->getNumSubdomains();
00788 if (numSubdomains != 0 && theDomainPartitioner != 0) {
00789 Graph &theSubGraphs = this->getSubdomainGraph();
00790 theDomainPartitioner->balance(theSubGraphs);
00791 }
00792
00793 return 0;
00794 }
00795
00796
00797 int
00798 PartitionedDomain::revertToLastCommit(void)
00799 {
00800 int result = this->Domain::revertToLastCommit();
00801 if (result < 0) {
00802 opserr << "PartitionedDomain::revertToLastCommit(void) - failed in Domain::revertToLastCommit()\n";
00803 return result;
00804 }
00805
00806
00807 if (theSubdomains != 0) {
00808 ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains);
00809 TaggedObject *theObject;
00810 while ((theObject = theSubsIter()) != 0) {
00811 Subdomain *theSub = (Subdomain *)theObject;
00812 int res = theSub->revertToLastCommit();
00813 if (res < 0) {
00814 opserr << "PartitionedDomain::revertToLastCommit(void)";
00815 opserr << " - failed in Subdomain::revertToLastCommit()\n";
00816 return res;
00817 }
00818 }
00819 }
00820
00821 return 0;
00822 }
00823
00824 int
00825 PartitionedDomain::revertToStart(void)
00826 {
00827 int result = this->Domain::revertToStart();
00828 if (result < 0) {
00829 opserr << "PartitionedDomain::revertToLastCommit(void) - failed in Domain::revertToLastCommit()\n";
00830 return result;
00831 }
00832
00833
00834 if (theSubdomains != 0) {
00835 ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains);
00836 TaggedObject *theObject;
00837 while ((theObject = theSubsIter()) != 0) {
00838 Subdomain *theSub = (Subdomain *)theObject;
00839 int res = theSub->revertToStart();
00840 if (res < 0) {
00841 opserr << "PartitionedDomain::revertToLastCommit(void)";
00842 opserr << " - failed in Subdomain::revertToLastCommit()\n";
00843 return res;
00844 }
00845 }
00846 }
00847
00848 return 0;
00849 }
00850
00851
00852 int
00853 PartitionedDomain::addRecorder(Recorder &theRecorder)
00854 {
00855 if (this->Domain::addRecorder(theRecorder) < 0)
00856 return -1;
00857
00858
00859 if (theSubdomains != 0) {
00860 ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains);
00861 TaggedObject *theObject;
00862 while ((theObject = theSubsIter()) != 0) {
00863 Subdomain *theSub = (Subdomain *)theObject;
00864 int res = theSub->addRecorder(theRecorder);
00865 if (res < 0) {
00866 opserr << "PartitionedDomain::revertToLastCommit(void)";
00867 opserr << " - failed in Subdomain::revertToLastCommit()\n";
00868 return res;
00869 }
00870 }
00871 }
00872 return 0;
00873 }
00874
00875 int
00876 PartitionedDomain::removeRecorders(void)
00877 {
00878 if (this->Domain::removeRecorders() < 0)
00879 return -1;
00880
00881
00882 if (theSubdomains != 0) {
00883 ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains);
00884 TaggedObject *theObject;
00885 while ((theObject = theSubsIter()) != 0) {
00886 Subdomain *theSub = (Subdomain *)theObject;
00887 int res = theSub->removeRecorders();
00888 if (res < 0) {
00889 opserr << "PartitionedDomain::revertToLastCommit(void)";
00890 opserr << " - failed in Subdomain::revertToLastCommit()\n";
00891 return res;
00892 }
00893 }
00894 }
00895 return 0;
00896 }
00897
00898 void
00899 PartitionedDomain::Print(OPS_Stream &s, int flag)
00900 {
00901 this->Domain::Print(s, flag);
00902
00903 s << "\nELEMENT DATA: NumEle: " << elements->getNumComponents() << "\n";
00904 elements->Print(s);
00905
00906
00907 if (theSubdomains != 0) {
00908 ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains);
00909 TaggedObject *theObject;
00910 while ((theObject = theSubsIter()) != 0) {
00911 theObject->Print(s, flag);
00912 }
00913 }
00914 }
00915
00916
00917 int
00918 PartitionedDomain::setPartitioner(DomainPartitioner *thePartitioner)
00919 {
00920 theDomainPartitioner = thePartitioner;
00921 return 0;
00922 }
00923
00924
00925 int
00926 PartitionedDomain::partition(int numPartitions, bool usingMain, int mainPartitionID)
00927 {
00928 int result = 0;
00929
00930
00931 Graph &theEleGraph = this->getElementGraph();
00932
00933
00934 DomainPartitioner *thePartitioner = this->getPartitioner();
00935 if (thePartitioner != 0) {
00936 thePartitioner->setPartitionedDomain(*this);
00937 result = thePartitioner->partition(numPartitions, usingMain, mainPartitionID);
00938 } else {
00939 opserr << "PartitionedDomain::partition(int numPartitions) - no associated partitioner\n";
00940 return -1;
00941 }
00942
00943
00944
00945
00946
00947
00948 if (theSubdomains != 0) {
00949 ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains);
00950 TaggedObject *theObject;
00951 while ((theObject = theSubsIter()) != 0) {
00952 Subdomain *theSub = (Subdomain *)theObject;
00953 for (int i=0; i<numRecorders; i++) {
00954 int res = theSub->addRecorder(*theRecorders[i]);
00955 if (res != 0) {
00956 opserr << "PartitionedDomain::revertToLastCommit(void)";
00957 opserr << " - failed in Subdomain::revertToLastCommit()\n";
00958 return res;
00959 }
00960 }
00961 }
00962 }
00963
00964
00965 return result;
00966 }
00967
00968
00969 bool
00970 PartitionedDomain::addSubdomain(Subdomain *theSubdomain)
00971 {
00972 int eleTag = theSubdomain->getTag();
00973 TaggedObject *other = theSubdomains->getComponentPtr(eleTag);
00974 if (other != 0)
00975 return false;
00976
00977 bool result = theSubdomains->addComponent(theSubdomain);
00978 if (result == true) {
00979 theSubdomain->setDomain(this);
00980 this->domainChange();
00981 }
00982
00983 return result;
00984
00985 }
00986
00987 int
00988 PartitionedDomain::getNumSubdomains(void)
00989 {
00990 return theSubdomains->getNumComponents();
00991 }
00992
00993 Subdomain *
00994 PartitionedDomain::getSubdomainPtr(int tag)
00995 {
00996 TaggedObject *mc = theSubdomains->getComponentPtr(tag);
00997 if (mc == 0) return 0;
00998 Subdomain *result = (Subdomain *)mc;
00999 return result;
01000 }
01001
01002 SubdomainIter &
01003 PartitionedDomain::getSubdomains(void)
01004 {
01005 theSubdomainIter->reset();
01006 return *theSubdomainIter;
01007 }
01008
01009
01010
01011 DomainPartitioner *
01012 PartitionedDomain::getPartitioner(void) const
01013 {
01014 return theDomainPartitioner;
01015 }
01016
01017
01018
01019
01020 int
01021 PartitionedDomain::buildEleGraph(Graph *theEleGraph)
01022 {
01023 int numVertex = elements->getNumComponents();
01024
01025
01026
01027 if (numVertex == 0)
01028 return 0;
01029
01030
01031
01032 int *theElementTagVertices = 0;
01033 int maxEleNum = 0;
01034
01035 TaggedObject *tagdObjPtr;
01036 TaggedObjectIter &theEles = elements->getComponents();
01037 while ((tagdObjPtr = theEles()) != 0)
01038 if (tagdObjPtr->getTag() > maxEleNum)
01039 maxEleNum = tagdObjPtr->getTag();
01040
01041 theElementTagVertices = new int[maxEleNum+1];
01042
01043 if (theElementTagVertices == 0) {
01044 opserr << "WARNING Domain::buildEleGraph ";
01045 opserr << " - Not Enough Memory for ElementTagVertices\n";
01046 return -1;
01047 }
01048
01049 for (int j=0; j<=maxEleNum; j++) theElementTagVertices[j] = -1;
01050
01051
01052
01053
01054 TaggedObjectIter &theEles2 = elements->getComponents();
01055
01056 int count = START_VERTEX_NUM;
01057 while ((tagdObjPtr = theEles2()) != 0) {
01058 int ElementTag = tagdObjPtr->getTag();
01059 Vertex *vertexPtr = new Vertex(count,ElementTag);
01060
01061 if (vertexPtr == 0) {
01062 opserr << "WARNING Domain::buildEleGraph";
01063 opserr << " - Not Enough Memory to create ";
01064 opserr << count << "th Vertex\n";
01065 delete [] theElementTagVertices;
01066 return -1;
01067 }
01068
01069 theEleGraph->addVertex(vertexPtr);
01070 theElementTagVertices[ElementTag] = count++;
01071
01072 }
01073
01074
01075
01076
01077
01078
01079 Vertex **theNodeTagVertices = 0;
01080 int maxNodNum = 0;
01081 Node *nodPtr;
01082 NodeIter &nodeIter = this->getNodes();
01083 while ((nodPtr = nodeIter()) != 0)
01084 if (nodPtr->getTag() > maxNodNum)
01085 maxNodNum = nodPtr->getTag();
01086
01087 theNodeTagVertices = new Vertex *[maxNodNum+1];
01088
01089 if (theNodeTagVertices == 0) {
01090 opserr << "WARNING Domain::buildEleGraph ";
01091 opserr << " - Not Enough Memory for NodeTagVertices\n";
01092 return -1;
01093 }
01094
01095 for (int l=0; l<=maxNodNum; l++) theNodeTagVertices[l] = 0;
01096
01097
01098
01099
01100
01101 NodeIter &nodeIter2 = this->getNodes();
01102 count = START_VERTEX_NUM;
01103 while ((nodPtr = nodeIter2()) != 0) {
01104 int nodeTag = nodPtr->getTag();
01105 Vertex *vertexPtr = new Vertex(count++,nodeTag);
01106 theNodeTagVertices[nodeTag] = vertexPtr;
01107
01108 if (vertexPtr == 0) {
01109 opserr << "WARNING Domain::buildEleGraph";
01110 opserr << " - Not Enough Memory to create ";
01111 opserr << count << "th Node Vertex\n";
01112 delete [] theNodeTagVertices;
01113 return -1;
01114 }
01115 }
01116
01117
01118 Element *elePtr;
01119 TaggedObjectIter &theEles3 = elements->getComponents();
01120
01121 while((tagdObjPtr = theEles3()) != 0) {
01122 elePtr = (Element *)tagdObjPtr;
01123 int eleTag = elePtr->getTag();
01124 const ID &id = elePtr->getExternalNodes();
01125
01126 int size = id.Size();
01127 for (int i=0; i<size; i++)
01128 theNodeTagVertices[id(i)]->addEdge(eleTag);
01129 }
01130
01131
01132
01133
01134
01135
01136 Vertex *vertexPtr;
01137 for (int k=0; k<=maxNodNum; k++)
01138 if ((vertexPtr = theNodeTagVertices[k]) != 0) {
01139
01140 const ID &id = vertexPtr->getAdjacency();
01141
01142 int size = id.Size();
01143 for (int i=0; i<size; i++) {
01144 int Element1 = id(i);
01145
01146 int vertexTag1 = theElementTagVertices[Element1];
01147
01148 for (int j=0; j<size; j++)
01149 if (i != j) {
01150
01151 int Element2 = id(j);
01152 int vertexTag2 = theElementTagVertices[Element2];
01153
01154
01155 if (vertexTag1 > vertexTag2)
01156 theEleGraph->addEdge(vertexTag1,vertexTag2);
01157 theEleGraph->addEdge(vertexTag2,vertexTag1);
01158 }
01159 }
01160 }
01161
01162
01163
01164
01165 delete [] theElementTagVertices;
01166
01167 for (int i=0; i<=maxNodNum; i++)
01168 if ((vertexPtr = theNodeTagVertices[i]) != 0)
01169 delete vertexPtr;
01170
01171 delete [] theNodeTagVertices;
01172
01173 return 0;
01174
01175 }
01176
01177
01178
01179
01180
01181 Node *
01182 PartitionedDomain::removeExternalNode(int tag)
01183 {
01184 return (this->Domain::removeNode(tag));
01185 }
01186
01187 Graph &
01188 PartitionedDomain::getSubdomainGraph(void)
01189 {
01190
01191
01192 if (mySubdomainGraph != 0) {
01193 delete mySubdomainGraph;
01194 mySubdomainGraph = 0;
01195 }
01196
01197
01198 if (mySubdomainGraph == 0)
01199 mySubdomainGraph = new Graph(this->getNumSubdomains()+START_VERTEX_NUM);
01200
01201 if (mySubdomainGraph == 0)
01202 mySubdomainGraph = new Graph();
01203
01204 int numVertex = theSubdomains->getNumComponents();
01205
01206
01207
01208 if (numVertex == 0)
01209 return *mySubdomainGraph;
01210
01211
01212
01213 int *theElementTagVertices = 0;
01214 int maxEleNum = 0;
01215
01216 TaggedObject *tagdObjPtr;
01217 TaggedObjectIter &theEles = theSubdomains->getComponents();
01218 while ((tagdObjPtr = theEles()) != 0)
01219 if (tagdObjPtr->getTag() > maxEleNum)
01220 maxEleNum = tagdObjPtr->getTag();
01221
01222 theElementTagVertices = new int[maxEleNum+1];
01223
01224 if (theElementTagVertices == 0) {
01225 opserr << "WARNING PartitionedDomain::buildEleGraph ";
01226 opserr << " - Not Enough Memory for ElementTagVertices\n";
01227 exit(-1);
01228 }
01229
01230 for (int j=0; j<=maxEleNum; j++) theElementTagVertices[j] = -1;
01231
01232
01233
01234
01235
01236 TaggedObjectIter &theEles2 = theSubdomains->getComponents();
01237
01238 while ((tagdObjPtr = theEles2()) != 0) {
01239 Subdomain *theSub = (Subdomain *)tagdObjPtr;
01240
01241 int ElementTag = tagdObjPtr->getTag();
01242
01243 Vertex *vertexPtr = new Vertex(ElementTag, ElementTag, theSub->getCost());
01244 if (vertexPtr == 0) {
01245 opserr << "WARNING Domain::buildEleGraph";
01246 opserr << " - Not Enough Memory to create ";
01247 opserr << ElementTag << "th Vertex\n";
01248 delete [] theElementTagVertices;
01249 exit(-1);
01250 }
01251
01252 mySubdomainGraph->addVertex(vertexPtr);
01253
01254 theElementTagVertices[ElementTag] = ElementTag;
01255 }
01256
01257
01258
01259
01260
01261
01262 Vertex **theNodeTagVertices = 0;
01263 int maxNodNum = 0;
01264 Node *nodPtr;
01265 NodeIter &nodeIter = this->getNodes();
01266 while ((nodPtr = nodeIter()) != 0)
01267 if (nodPtr->getTag() > maxNodNum)
01268 maxNodNum = nodPtr->getTag();
01269
01270 theNodeTagVertices = new Vertex *[maxNodNum+1];
01271
01272 if (theNodeTagVertices == 0) {
01273 opserr << "WARNING Domain::buildEleGraph ";
01274 opserr << " - Not Enough Memory for NodeTagVertices\n";
01275 exit(-1);
01276 }
01277
01278 for (int l=0; l<=maxNodNum; l++) theNodeTagVertices[l] = 0;
01279
01280
01281
01282
01283
01284 NodeIter &nodeIter2 = this->getNodes();
01285 int count = START_VERTEX_NUM;
01286 while ((nodPtr = nodeIter2()) != 0) {
01287 int nodeTag = nodPtr->getTag();
01288 Vertex *vertexPtr = new Vertex(count++,nodeTag);
01289 theNodeTagVertices[nodeTag] = vertexPtr;
01290
01291 if (vertexPtr == 0) {
01292 opserr << "WARNING Domain::buildEleGraph";
01293 opserr << " - Not Enough Memory to create "; opserr << count << "th Node Vertex\n";
01294 delete [] theNodeTagVertices;
01295 exit(-1);
01296 }
01297 }
01298
01299
01300 Element *elePtr;
01301 TaggedObjectIter &theEles3 = theSubdomains->getComponents();
01302
01303 while((tagdObjPtr = theEles3()) != 0) {
01304 elePtr = (Element *)tagdObjPtr;
01305 int eleTag = elePtr->getTag();
01306 const ID &id = elePtr->getExternalNodes();
01307
01308 int size = id.Size();
01309 for (int i=0; i<size; i++)
01310 theNodeTagVertices[id(i)]->addEdge(eleTag);
01311 }
01312
01313
01314
01315
01316
01317 Vertex *vertexPtr;
01318 for (int k=0; k<=maxNodNum; k++)
01319 if ((vertexPtr = theNodeTagVertices[k]) != 0) {
01320
01321 const ID &id = vertexPtr->getAdjacency();
01322
01323 int size = id.Size();
01324 for (int i=0; i<size; i++) {
01325 int Element1 = id(i);
01326
01327 int vertexTag1 = theElementTagVertices[Element1];
01328
01329 for (int j=0; j<size; j++)
01330 if (i != j) {
01331
01332 int Element2 = id(j);
01333 int vertexTag2 = theElementTagVertices[Element2];
01334
01335
01336 if (vertexTag1 > vertexTag2)
01337 mySubdomainGraph->addEdge(vertexTag1,vertexTag2);
01338 mySubdomainGraph->addEdge(vertexTag2,vertexTag1);
01339 }
01340 }
01341 }
01342
01343
01344
01345
01346 delete [] theElementTagVertices;
01347
01348 for (int i=0; i<=maxNodNum; i++)
01349 if ((vertexPtr = theNodeTagVertices[i]) != 0)
01350 delete vertexPtr;
01351
01352 delete [] theNodeTagVertices;
01353
01354 return *mySubdomainGraph;
01355 }
01356
01357
01358 double
01359 PartitionedDomain::getNodeDisp(int nodeTag, int dof, int &errorFlag)
01360 {
01361 double result = this->Domain::getNodeDisp(nodeTag, dof, errorFlag);
01362
01363 if (errorFlag != 0) {
01364
01365
01366 if (theSubdomains != 0) {
01367 ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains);
01368 TaggedObject *theObject;
01369 while ((theObject = theSubsIter()) != 0 && errorFlag != 0) {
01370 Subdomain *theSub = (Subdomain *)theObject;
01371 result = theSub->getNodeDisp(nodeTag, dof, errorFlag);
01372 if (errorFlag == 0)
01373 return result;
01374 }
01375 }
01376 }
01377
01378 return result;
01379 }
01380
01381
01382 int
01383 PartitionedDomain::setMass(const Matrix &mass, int nodeTag)
01384 {
01385 int result = this->Domain::setMass(mass, nodeTag);
01386
01387 if (result != 0) {
01388
01389
01390 if (theSubdomains != 0) {
01391 ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains);
01392 TaggedObject *theObject;
01393 while ((theObject = theSubsIter()) != 0 && result != 0) {
01394 Subdomain *theSub = (Subdomain *)theObject;
01395 result = theSub->setMass(mass, nodeTag);
01396 }
01397 }
01398 }
01399
01400 return result;
01401 }