DomainDecompositionAnalysis.cpp

Go to the documentation of this file.
00001 /* ****************************************************************** **
00002 **    OpenSees - Open System for Earthquake Engineering Simulation    **
00003 **          Pacific Earthquake Engineering Research Center            **
00004 **                                                                    **
00005 **                                                                    **
00006 ** (C) Copyright 1999, The Regents of the University of California    **
00007 ** All Rights Reserved.                                               **
00008 **                                                                    **
00009 ** Commercial use of this program without express permission of the   **
00010 ** University of California, Berkeley, is strictly prohibited.  See   **
00011 ** file 'COPYRIGHT'  in main directory for information on usage and   **
00012 ** redistribution,  and for a DISCLAIMER OF ALL WARRANTIES.           **
00013 **                                                                    **
00014 ** Developed by:                                                      **
00015 **   Frank McKenna (fmckenna@ce.berkeley.edu)                         **
00016 **   Gregory L. Fenves (fenves@ce.berkeley.edu)                       **
00017 **   Filip C. Filippou (filippou@ce.berkeley.edu)                     **
00018 **                                                                    **
00019 ** ****************************************************************** */
00020                                                                         
00021 // $Revision: 1.6 $
00022 // $Date: 2005/11/29 23:36:47 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/analysis/analysis/DomainDecompositionAnalysis.cpp,v $
00024                                                                         
00025                                                                         
00026 // File: ~/analysis/Analysis/DomainDecompositionAnalysis.C
00027 // 
00028 // Written: fmk 
00029 // Created: Tue Sept 17 16:34:47: 1996
00030 // Revision: A
00031 //
00032 // Description: This file contains the class definition for 
00033 // DomainDecompositionAnalysis. DomainDecompositionAnalysis is a subclass 
00034 // of AnalysisAnalysis, it is used to perform the static condensation process
00035 // on a subdomain.
00036 //
00037 // What: "@(#) DomainDecompositionAnalysis.C, revA"
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     // invoke the destructor on all the objects in the aggregation
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   // now set the pointers to NULL
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     // remove existing FE_elements and DOF_Groups from the Analysis
00186     theModel->clearAll();
00187     theHandler->clearAll();
00188 
00189     // now we invoke handle() on the constraint handler which
00190     // causes the creation of FE_Element and DOF_Group objects
00191     // and their addition to the AnalysisModel.
00192 
00193     numExtEqn = theHandler->handle(&(theSubdomain->getExternalNodes()));
00194 
00195     // we now get a node to number last
00196 
00197     const ID &theExtNodes = theSubdomain->getExternalNodes();
00198     int idSize = theExtNodes.Size();
00199     //    int theLastDOF = -1;
00200 
00201     ID theLastDOFs(1);
00202     int cnt = 0;
00203 
00204     // create an ID containing the tags of the DOF_Groups that are to
00205     // be numbered last
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     // we now invoke number() on the numberer which causes
00223     // equation numbers to be assigned to all the DOFs in the
00224     // AnalysisModel.    
00225 
00226     theNumberer->numberDOF(theLastDOFs);
00227 
00228     /*************************
00229     for (int i=0; i<idSize; i++) {
00230         int nodeTag = theExtNodes(i);
00231         Node *nodePtr = theSubdomain->getNode(nodeTag);
00232         DOF_Group *dofPtr = nodePtr->getDOF_GroupPtr();
00233         if (dofPtr != 0) {
00234             const ID theID = dofPtr->getID();
00235             int size = theID.Size();
00236             for (int j=0; j<size; j++)
00237                 if (theID(j) == -3) {
00238                     theLastDOF = dofPtr->getTag();
00239                     i = idSize;
00240                     j=size;
00241                 }
00242         }
00243     }
00244     theNumberer->numberDOF(theLastDOF);
00245     **********************/
00246 
00247 
00248     // we invoke setSize() on the LinearSOE which
00249     // causes that object to determine its size    
00250     
00251     theSOE->setSize(theModel->getDOFGraph());    
00252     numEqn = theSOE->getNumEqn();
00253 
00254     // we invoke domainChange() on the integrator and algorithm
00255 
00256     theIntegrator->domainChanged();
00257     theAlgorithm->domainChanged();        
00258 
00259     // now set the variables to indicate that tangent has not been formed
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     // we check to see if the domain has changed 
00308     int stamp = the_Domain->hasDomainChanged();
00309     if (stamp != domainStamp) {
00310         domainStamp = stamp;
00311         this->domainChanged();
00312     }
00313     
00314     // if tangFormed == -1 then formTangent has already been
00315     // called for this state by formResidual() or formTangVectProduct()
00316     // so we won't be doing it again.
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     // we check to see if the domain has changed 
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; // set to minus number so tangent 
00353                               // is not formed twice at same state
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     // we check to see if the domain has changed 
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; // set to minus number so tangent 
00384                               // is not formed twice at same state
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     // we check to see if the domain has changed 
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     // we check to see if the domain has changed 
00420     // we check to see if the domain has changed 
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     // we check to see if the domain has changed 
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     // determine the type of each object in the aggregation,
00535     // store it in an ID and send the info off.
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     // invoke sendSelf on each object in the aggregation
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     // receive the data identifyng the objects in the aggregation
00574     ID data(14);
00575     int dataTag = this->getDbTag();
00576     theChannel.recvID(dataTag, commitTag, data);
00577 
00578     //
00579     // now ask the object broker an object of each type
00580     // and invoke recvSelf() on the object to init it.
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     // set the links in all the objects
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 

Generated on Mon Oct 23 15:04:57 2006 for OpenSees by doxygen 1.5.0