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
00040 #include <DomainDecompositionAnalysis.h>
00041 #include <ConstraintHandler.h>
00042 #include <DOF_Numberer.h>
00043 #include <AnalysisModel.h>
00044 #include <LinearSOE.h>
00045 #include <DomainDecompAlgo.h>
00046 #include <DomainSolver.h>
00047 #include <ConvergenceTest.h>
00048 #include <IncrementalIntegrator.h>
00049 #include <Subdomain.h>
00050
00051 #include <FE_Element.h>
00052 #include <DOF_Group.h>
00053 #include <FE_EleIter.h>
00054 #include <DOF_GrpIter.h>
00055 #include <Matrix.h>
00056 #include <ID.h>
00057 #include <Node.h>
00058
00059 #include <Channel.h>
00060 #include <FEM_ObjectBroker.h>
00061
00062 DomainDecompositionAnalysis::DomainDecompositionAnalysis(Subdomain &the_Domain)
00063 :Analysis(the_Domain),
00064 MovableObject(DomDecompANALYSIS_TAGS_DomainDecompositionAnalysis),
00065 theSubdomain(&the_Domain),
00066 theHandler(0),
00067 theNumberer(0),
00068 theModel(0),
00069 theAlgorithm(0),
00070 theIntegrator(0),
00071 theSOE(0),
00072 theSolver(0),
00073 theResidual(0),numEqn(0),numExtEqn(0),tangFormed(false),tangFormedCount(0),
00074 domainStamp(0)
00075 {
00076 theSubdomain->setDomainDecompAnalysis(*this);
00077 }
00078
00079
00080 DomainDecompositionAnalysis::DomainDecompositionAnalysis(int clsTag,
00081 Subdomain &the_Domain)
00082 :Analysis(the_Domain),
00083 MovableObject(clsTag),
00084 theSubdomain(&the_Domain),
00085 theHandler(0),
00086 theNumberer(0),
00087 theModel(0),
00088 theAlgorithm(0),
00089 theIntegrator(0),
00090 theSOE(0),
00091 theSolver(0),
00092 theResidual(0),numEqn(0),numExtEqn(0),tangFormed(false),tangFormedCount(0),
00093 domainStamp(0)
00094 {
00095
00096 }
00097
00098 DomainDecompositionAnalysis::DomainDecompositionAnalysis(Subdomain &the_Domain,
00099 ConstraintHandler &handler,
00100 DOF_Numberer &numberer,
00101 AnalysisModel &model,
00102 DomainDecompAlgo &theSolnAlgo,
00103 IncrementalIntegrator &integrator,
00104 LinearSOE &theLinSOE,
00105 DomainSolver &theDDSolver)
00106
00107
00108 :Analysis(the_Domain),
00109 MovableObject(DomDecompANALYSIS_TAGS_DomainDecompositionAnalysis),
00110 theSubdomain( &the_Domain),
00111 theHandler( &handler),
00112 theNumberer( &numberer),
00113 theModel( &model),
00114 theAlgorithm( &theSolnAlgo),
00115 theIntegrator( &integrator),
00116 theSOE( &theLinSOE),
00117 theSolver( &theDDSolver),
00118 theResidual(0),numEqn(0),numExtEqn(0),tangFormed(false),tangFormedCount(0)
00119 {
00120 theModel->setLinks(the_Domain, handler);
00121 theHandler->setLinks(*theSubdomain,*theModel,*theIntegrator);
00122 theNumberer->setLinks(*theModel);
00123 theIntegrator->setLinks(*theModel,*theSOE);
00124 theAlgorithm->setLinks(*theModel,*theIntegrator,*theSOE,
00125 *theSolver,*theSubdomain);
00126
00127 theSubdomain->setDomainDecompAnalysis(*this);
00128 }
00129
00130
00131 DomainDecompositionAnalysis::~DomainDecompositionAnalysis()
00132 {
00133 if (theResidual != 0)
00134 delete theResidual;
00135 }
00136
00137 void
00138 DomainDecompositionAnalysis::clearAll(void)
00139 {
00140
00141 if (theModel != 0)
00142 delete theModel;
00143 if (theHandler != 0)
00144 delete theHandler;
00145 if (theNumberer != 0)
00146 delete theNumberer;
00147 if (theIntegrator != 0)
00148 delete theIntegrator;
00149 if (theAlgorithm != 0)
00150 delete theAlgorithm;
00151 if (theSOE != 0)
00152 delete theSOE;
00153
00154
00155 theModel =0;
00156 theHandler =0;
00157 theNumberer =0;
00158 theIntegrator =0;
00159 theAlgorithm =0;
00160 theSOE =0;
00161 }
00162
00163 int
00164 DomainDecompositionAnalysis::analyze(double dT)
00165 {
00166 return 0;
00167 }
00168
00169 int
00170 DomainDecompositionAnalysis::initialize(void)
00171 {
00172 return 0;
00173 }
00174
00175
00176 bool
00177 DomainDecompositionAnalysis::doesIndependentAnalysis(void)
00178 {
00179 return false;
00180 }
00181
00182 int
00183 DomainDecompositionAnalysis::domainChanged(void)
00184 {
00185
00186 theModel->clearAll();
00187 theHandler->clearAll();
00188
00189
00190
00191
00192
00193 numExtEqn = theHandler->handle(&(theSubdomain->getExternalNodes()));
00194
00195
00196
00197 const ID &theExtNodes = theSubdomain->getExternalNodes();
00198 int idSize = theExtNodes.Size();
00199
00200
00201 ID theLastDOFs(1);
00202 int cnt = 0;
00203
00204
00205
00206 for (int i=0; i<idSize; i++) {
00207 int nodeTag = theExtNodes(i);
00208 Node *nodePtr = theSubdomain->getNode(nodeTag);
00209 DOF_Group *dofGrpPtr = nodePtr->getDOF_GroupPtr();
00210 if (dofGrpPtr != 0) {
00211 const ID theID = dofGrpPtr->getID();
00212 int size = theID.Size();
00213 for (int j=0; j<size; j++)
00214 if (theID(j) == -3) {
00215 theLastDOFs[cnt] = dofGrpPtr->getTag();
00216 cnt++;
00217 j = size;
00218 }
00219 }
00220 }
00221
00222
00223
00224
00225
00226 theNumberer->numberDOF(theLastDOFs);
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 theSOE->setSize(theModel->getDOFGraph());
00252 numEqn = theSOE->getNumEqn();
00253
00254
00255
00256 theIntegrator->domainChanged();
00257 theAlgorithm->domainChanged();
00258
00259
00260
00261 tangFormed = false;
00262 tangFormedCount = 0;
00263
00264 return 0;
00265 }
00266
00267
00268 int
00269 DomainDecompositionAnalysis::getNumExternalEqn(void)
00270 {
00271 return numExtEqn;
00272 }
00273
00274 int
00275 DomainDecompositionAnalysis::getNumInternalEqn(void)
00276 {
00277 return numEqn-numExtEqn;
00278 }
00279
00280
00281
00282
00283 int
00284 DomainDecompositionAnalysis::newStep(double dT)
00285 {
00286 return theIntegrator->newStep(dT);
00287 }
00288
00289
00290
00291 int
00292 DomainDecompositionAnalysis::computeInternalResponse(void)
00293 {
00294 return theAlgorithm->solveCurrentStep();
00295 }
00296
00297
00298
00299
00300 int
00301 DomainDecompositionAnalysis::formTangent(void)
00302 {
00303 int result =0;
00304
00305 Domain *the_Domain = this->getDomainPtr();
00306
00307
00308 int stamp = the_Domain->hasDomainChanged();
00309 if (stamp != domainStamp) {
00310 domainStamp = stamp;
00311 this->domainChanged();
00312 }
00313
00314
00315
00316
00317
00318 if (tangFormedCount != -1) {
00319 result = theIntegrator->formTangent();
00320 if (result < 0)
00321 return result;
00322 result = theSolver->condenseA(numEqn-numExtEqn);
00323 if (result < 0)
00324 return result;
00325 }
00326
00327 tangFormed = true;
00328 tangFormedCount++;
00329
00330 return result;
00331 }
00332
00333
00334
00335 int
00336 DomainDecompositionAnalysis::formResidual(void)
00337 {
00338 int result =0;
00339 Domain *the_Domain = this->getDomainPtr();
00340
00341
00342 int stamp = the_Domain->hasDomainChanged();
00343 if (stamp != domainStamp) {
00344 domainStamp = stamp;
00345 this->domainChanged();
00346 }
00347
00348 if (tangFormed == false) {
00349 result = this->formTangent();
00350 if (result < 0)
00351 return result;
00352 tangFormedCount = -1;
00353
00354 }
00355
00356 result = theIntegrator->formUnbalance();
00357
00358 if (result < 0)
00359 return result;
00360 return theSolver->condenseRHS(numEqn-numExtEqn);
00361 }
00362
00363
00364
00365 int
00366 DomainDecompositionAnalysis::formTangVectProduct(Vector &u)
00367 {
00368 int result = 0;
00369
00370 Domain *the_Domain = this->getDomainPtr();
00371
00372
00373 int stamp = the_Domain->hasDomainChanged();
00374 if (stamp != domainStamp) {
00375 domainStamp = stamp;
00376 this->domainChanged();
00377 }
00378
00379 if (tangFormed == false) {
00380 result = this->formTangent();
00381 if (result < 0)
00382 return result;
00383 tangFormedCount = -1;
00384
00385 }
00386
00387 return theSolver->computeCondensedMatVect(numEqn-numExtEqn,u);
00388 }
00389
00390
00391
00392 const Matrix &
00393 DomainDecompositionAnalysis::getTangent()
00394 {
00395 Domain *the_Domain = this->getDomainPtr();
00396
00397
00398 int stamp = the_Domain->hasDomainChanged();
00399 if (stamp != domainStamp) {
00400 domainStamp = stamp;
00401 this->domainChanged();
00402 }
00403
00404 if (tangFormed == false) {
00405 this->formTangent();
00406 }
00407
00408 return (theSolver->getCondensedA());
00409 }
00410
00411
00412
00413 const Vector &
00414 DomainDecompositionAnalysis::getResidual()
00415 {
00416
00417 Domain *the_Domain = this->getDomainPtr();
00418
00419
00420
00421 int stamp = the_Domain->hasDomainChanged();
00422 if (stamp != domainStamp) {
00423 domainStamp = stamp;
00424 this->domainChanged();
00425 this->formResidual();
00426 }
00427
00428 if (theResidual == 0) {
00429 theResidual = new Vector(theSolver->getCondensedRHS());
00430 return *theResidual;
00431 }
00432 else if (theResidual->Size() != numExtEqn) {
00433 delete theResidual;
00434 theResidual = new Vector(theSolver->getCondensedRHS());
00435 return *theResidual;
00436 }
00437 else {
00438 (*theResidual) = theSolver->getCondensedRHS();
00439 }
00440
00441 return *theResidual;
00442 }
00443
00444
00445
00446
00447 const Vector &
00448 DomainDecompositionAnalysis::getTangVectProduct()
00449 {
00450 Domain *the_Domain = this->getDomainPtr();
00451
00452
00453 int stamp = the_Domain->hasDomainChanged();
00454 if (stamp != domainStamp) {
00455 domainStamp = stamp;
00456 this->domainChanged();
00457 }
00458
00459 return theSolver->getCondensedMatVect();
00460 }
00461
00462
00463
00464
00465
00466 Subdomain *
00467 DomainDecompositionAnalysis::getSubdomainPtr(void) const
00468 {
00469 return theSubdomain;
00470 }
00471
00472
00473
00474
00475 ConstraintHandler *
00476 DomainDecompositionAnalysis::getConstraintHandlerPtr(void) const
00477 {
00478 return theHandler;
00479 }
00480
00481
00482
00483 DOF_Numberer *
00484 DomainDecompositionAnalysis::getDOF_NumbererPtr(void) const
00485 {
00486 return theNumberer;
00487 }
00488
00489
00490
00491 AnalysisModel *
00492 DomainDecompositionAnalysis::getAnalysisModelPtr(void) const
00493 {
00494 return theModel;
00495 }
00496
00497
00498
00499 DomainDecompAlgo *
00500 DomainDecompositionAnalysis::getDomainDecompAlgoPtr(void) const
00501 {
00502 return theAlgorithm;
00503 }
00504
00505
00506
00507 IncrementalIntegrator *
00508 DomainDecompositionAnalysis::getIncrementalIntegratorPtr(void) const
00509 {
00510 return theIntegrator;
00511 }
00512
00513
00514
00515 LinearSOE *
00516 DomainDecompositionAnalysis::getLinSOEPtr(void) const
00517 {
00518 return theSOE;
00519 }
00520
00521
00522
00523 DomainSolver *
00524 DomainDecompositionAnalysis::getDomainSolverPtr(void) const
00525 {
00526 return theSolver;
00527 }
00528
00529
00530 int
00531 DomainDecompositionAnalysis::sendSelf(int commitTag,
00532 Channel &theChannel)
00533 {
00534
00535
00536 int dataTag = this->getDbTag();
00537 ID data(14);
00538 data(0) = theHandler->getClassTag();
00539 data(1) = theNumberer->getClassTag();
00540 data(2) = theModel->getClassTag();
00541 data(3) = theAlgorithm->getClassTag();
00542 data(4) = theIntegrator->getClassTag();
00543 data(5) = theSOE->getClassTag();
00544 data(6) = theSolver->getClassTag();
00545
00546 data(7) = theHandler->getDbTag();
00547 data(8) = theNumberer->getDbTag();
00548 data(9) = theModel->getDbTag();
00549 data(10) = theAlgorithm->getDbTag();
00550 data(11) = theIntegrator->getDbTag();
00551 data(12) = theSOE->getDbTag();
00552 data(13) = theSolver->getDbTag();
00553
00554 theChannel.sendID(dataTag, commitTag, data);
00555
00556
00557
00558 theHandler->sendSelf(commitTag, theChannel);
00559 theNumberer->sendSelf(commitTag, theChannel);
00560 theModel->sendSelf(commitTag, theChannel);
00561 theAlgorithm->sendSelf(commitTag, theChannel);
00562 theIntegrator->sendSelf(commitTag, theChannel);
00563 theSOE->sendSelf(commitTag, theChannel);
00564 theSolver->sendSelf(commitTag, theChannel);
00565 return 0;
00566 }
00567
00568 int
00569 DomainDecompositionAnalysis::recvSelf(int commitTag,
00570 Channel &theChannel,
00571 FEM_ObjectBroker &theBroker)
00572 {
00573
00574 ID data(14);
00575 int dataTag = this->getDbTag();
00576 theChannel.recvID(dataTag, commitTag, data);
00577
00578
00579
00580
00581
00582
00583 theHandler = theBroker.getNewConstraintHandler(data(0));
00584 if (theHandler != 0) {
00585 theHandler->setDbTag(data(7));
00586 theHandler->recvSelf(commitTag, theChannel,theBroker);
00587 }
00588 else {
00589 opserr << "DomainDecompositionAnalysis::recvSelf";
00590 opserr << " - failed to get the ConstraintHandler\n";
00591 return -1;
00592 }
00593
00594
00595
00596 theNumberer = theBroker.getNewNumberer(data(1));
00597 if (theNumberer != 0) {
00598 theNumberer->setDbTag(data(8));
00599 theNumberer->recvSelf(commitTag, theChannel,theBroker);
00600 }
00601 else {
00602 opserr << "DomainDecompositionAnalysis::recvSelf";
00603 opserr << " - failed to get the DOF Numberer\n";
00604 return -1;
00605 }
00606
00607
00608 theModel = theBroker.getNewAnalysisModel(data(2));
00609 if (theModel != 0) {
00610 theModel->setDbTag(data(9));
00611 theModel->recvSelf(commitTag, theChannel,theBroker);
00612 }
00613 else {
00614 opserr << "DomainDecompositionAnalysis::recvSelf";
00615 opserr << " - failed to get the AnalysisModel\n";
00616 return -1;
00617 }
00618
00619
00620 theAlgorithm = theBroker.getNewDomainDecompAlgo(data(3));
00621 if (theAlgorithm != 0) {
00622 theAlgorithm->setDbTag(data(10));
00623 theAlgorithm->recvSelf(commitTag, theChannel,theBroker);
00624 }
00625 else {
00626 opserr << "DomainDecompositionAnalysis::recvSelf";
00627 opserr << " - failed to get the Domain Decomp Algo\n";
00628 return -1;
00629 }
00630
00631 theIntegrator = theBroker.getNewIncrementalIntegrator(data(4));
00632 if (theIntegrator != 0) {
00633 theIntegrator->setDbTag(data(11));
00634 theIntegrator->recvSelf(commitTag, theChannel,theBroker);
00635 }
00636 else {
00637 opserr << "DomainDecompositionAnalysis::recvSelf";
00638 opserr << " - failed to get the IncrementalIntegrator\n";
00639 return -1;
00640 }
00641
00642 theSOE = theBroker.getPtrNewDDLinearSOE(data(5),data(6));
00643 theSolver = theBroker.getNewDomainSolver();
00644
00645 if (theSOE == 0 || theSolver == 0) {
00646 opserr << "DomainDecompositionAnalysis::recvSelf";
00647 opserr << " - failed to get the LinearSOE and the DomainSolver \n";
00648 return -1;
00649 } else {
00650 theSOE->setDbTag(data(12));
00651 theSolver->setDbTag(data(13));
00652 theSOE->recvSelf(commitTag, theChannel,theBroker);
00653 theSolver->recvSelf(commitTag, theChannel,theBroker);
00654 }
00655
00656
00657
00658 theModel->setLinks(*theSubdomain, *theHandler);
00659 theHandler->setLinks(*theSubdomain,*theModel,*theIntegrator);
00660 theNumberer->setLinks(*theModel);
00661 theIntegrator->setLinks(*theModel,*theSOE);
00662 theAlgorithm->setLinks(*theModel,*theIntegrator,*theSOE,
00663 *theSolver,*theSubdomain);
00664
00665 theSubdomain->setDomainDecompAnalysis(*this);
00666
00667 return 0;
00668 }
00669
00670
00671 int
00672 DomainDecompositionAnalysis::setAlgorithm(EquiSolnAlgo &theAlgorithm)
00673 {
00674 opserr << "DomainDecompositionAnalysis::setAlgorithm() - not implemented\n";
00675 return -1;
00676 }
00677
00678 int
00679 DomainDecompositionAnalysis::setIntegrator(IncrementalIntegrator &theIntegrator)
00680 {
00681 opserr << "DomainDecompositionAnalysis::setIntegrator() - not implemented\n";
00682 return -1;
00683 }
00684
00685
00686 int
00687 DomainDecompositionAnalysis::setLinearSOE(LinearSOE &theSOE)
00688 {
00689 opserr << "DomainDecompositionAnalysis::setLinearSOE() - not implemented\n";
00690 return -1;
00691 }
00692
00693 int
00694 DomainDecompositionAnalysis::setConvergenceTest(ConvergenceTest &theTest)
00695 {
00696 opserr << "DomainDecompositionAnalysis::setConvergenceTest() - not implemented\n";
00697 return -1;
00698 }
00699
00700