Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

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.1.1.1 $
00022 // $Date: 2000/09/15 08:23:16 $
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 
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     theSubdomain->setDomainDecompAnalysis(*this);
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);
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 
00128     theSubdomain->setDomainDecompAnalysis(*this);
00129 }    
00130 
00131 
00132 DomainDecompositionAnalysis::~DomainDecompositionAnalysis()
00133 {
00134 
00135 }    
00136 
00137 int 
00138 DomainDecompositionAnalysis::analyze(void)
00139 {
00140     cerr << "DomainDecompositionAnalysis::analyze(void)";
00141     cerr << "does nothing and should not have been called\n";
00142     return -1;
00143 }
00144 
00145 int
00146 DomainDecompositionAnalysis::domainChanged(void)
00147 {
00148     // remove existing FE_elements and DOF_Groups from the Analysis
00149     theModel->clearAll();
00150     theHandler->clearAll();
00151 
00152     // now we invoke handle() on the constraint handler which
00153     // causes the creation of FE_Element and DOF_Group objects
00154     // and their addition to the AnalysisModel.
00155 
00156     numExtEqn = theHandler->handle(&(theSubdomain->getExternalNodes()));
00157 
00158     // we now get a node to number last
00159 
00160     const ID &theExtNodes = theSubdomain->getExternalNodes();
00161     int idSize = theExtNodes.Size();
00162     //    int theLastDOF = -1;
00163 
00164     ID theLastDOFs(1);
00165     int cnt = 0;
00166 
00167     // create an ID containing the tags of the DOF_Groups that are to
00168     // be numbered last
00169     for (int i=0; i<idSize; i++) {
00170  int nodeTag = theExtNodes(i);
00171  Node *nodePtr = theSubdomain->getNode(nodeTag);
00172  DOF_Group *dofGrpPtr = nodePtr->getDOF_GroupPtr();
00173  if (dofGrpPtr != 0) {
00174      const ID theID = dofGrpPtr->getID();
00175      int size = theID.Size();
00176      for (int j=0; j<size; j++)
00177   if (theID(j) == -3) {
00178       theLastDOFs[cnt]  = dofGrpPtr->getTag();
00179       cnt++;
00180       j = size;
00181   }
00182  }
00183     }
00184 
00185     // we now invoke number() on the numberer which causes
00186     // equation numbers to be assigned to all the DOFs in the
00187     // AnalysisModel.    
00188 
00189     theNumberer->numberDOF(theLastDOFs);
00190 
00191     /*************************
00192     for (int i=0; i<idSize; i++) {
00193  int nodeTag = theExtNodes(i);
00194  Node *nodePtr = theSubdomain->getNode(nodeTag);
00195  DOF_Group *dofPtr = nodePtr->getDOF_GroupPtr();
00196  if (dofPtr != 0) {
00197      const ID theID = dofPtr->getID();
00198      int size = theID.Size();
00199      for (int j=0; j<size; j++)
00200   if (theID(j) == -3) {
00201       theLastDOF = dofPtr->getTag();
00202              i = idSize;
00203                     j=size;
00204   }
00205  }
00206     }
00207     theNumberer->numberDOF(theLastDOF);
00208     **********************/
00209 
00210 
00211     // we invoke setSize() on the LinearSOE which
00212     // causes that object to determine its size    
00213     
00214     theSOE->setSize(theModel->getDOFGraph());    
00215     numEqn = theSOE->getNumEqn();
00216 
00217     // we invoke domainChange() on the integrator and algorithm
00218 
00219     theIntegrator->domainChanged();
00220     theAlgorithm->domainChanged();        
00221 
00222     // now set the variables to indicate that tangent has not been formed
00223 
00224     tangFormed = false;
00225     tangFormedCount = 0;
00226     
00227     return 0;
00228 }
00229 
00230 
00231 int
00232 DomainDecompositionAnalysis::getNumExternalEqn(void)
00233 {
00234     return numExtEqn;
00235 }
00236 
00237 int
00238 DomainDecompositionAnalysis::getNumInternalEqn(void)
00239 {
00240     return numEqn-numExtEqn;
00241 }
00242 
00243 
00244 
00245 
00246 int  
00247 DomainDecompositionAnalysis::computeInternalResponse(void)
00248 {
00249     return theAlgorithm->solveCurrentStep();
00250 }
00251 
00252 
00253 
00254 
00255 int  
00256 DomainDecompositionAnalysis::formTangent(void)
00257 {
00258     int result =0;
00259 
00260     Domain *the_Domain = this->getDomainPtr();
00261 
00262     // we check to see if the domain has changed 
00263     int stamp = the_Domain->hasDomainChanged();
00264     if (stamp != domainStamp) {
00265  domainStamp = stamp;
00266  this->domainChanged();
00267     }
00268     
00269     // if tangFormed == -1 then formTangent has already been
00270     // called for this state by formResidual() or formTangVectProduct()
00271     // so we won't be doing it again.
00272 
00273     if (tangFormedCount != -1) {
00274  result = theIntegrator->formTangent();
00275  if (result < 0)
00276      return result;
00277  result = theSolver->condenseA(numEqn-numExtEqn);
00278  if (result < 0)
00279      return result;
00280     }
00281  
00282     tangFormed = true;
00283     tangFormedCount++;
00284     
00285     return result;
00286 }
00287 
00288 
00289 
00290 int  
00291 DomainDecompositionAnalysis::formResidual(void)
00292 {
00293     int result =0;
00294     Domain *the_Domain = this->getDomainPtr();    
00295     
00296     // we check to see if the domain has changed 
00297     int stamp = the_Domain->hasDomainChanged();
00298     if (stamp != domainStamp) {
00299  domainStamp = stamp;
00300  this->domainChanged();
00301     }
00302     
00303     if (tangFormed == false) {
00304  result = this->formTangent();
00305  if (result < 0)
00306      return result;
00307  tangFormedCount = -1; // set to minus number so tangent 
00308                        // is not formed twice at same state
00309     }
00310 
00311     result = theIntegrator->formUnbalance();
00312 
00313     if (result < 0)
00314  return result;
00315     return theSolver->condenseRHS(numEqn-numExtEqn);
00316 }
00317 
00318 
00319 
00320 int  
00321 DomainDecompositionAnalysis::formTangVectProduct(Vector &u)
00322 {
00323     int result = 0;
00324 
00325     Domain *the_Domain = this->getDomainPtr();
00326     
00327     // we check to see if the domain has changed 
00328     int stamp = the_Domain->hasDomainChanged();
00329     if (stamp != domainStamp) {
00330  domainStamp = stamp;
00331  this->domainChanged();
00332     }
00333     
00334     if (tangFormed == false) {
00335  result = this->formTangent();
00336  if (result < 0)
00337      return result;
00338  tangFormedCount = -1; // set to minus number so tangent 
00339                        // is not formed twice at same state
00340     }    
00341 
00342     return theSolver->computeCondensedMatVect(numEqn-numExtEqn,u);
00343 }
00344 
00345 
00346 
00347 const Matrix &
00348 DomainDecompositionAnalysis::getTangent()
00349 {
00350     Domain *the_Domain = this->getDomainPtr();
00351     
00352     // we check to see if the domain has changed 
00353     int stamp = the_Domain->hasDomainChanged();
00354     if (stamp != domainStamp) {
00355  domainStamp = stamp;
00356  this->domainChanged();
00357     }
00358 
00359     if (tangFormed == false) {
00360  this->formTangent();
00361     }
00362     
00363     return (theSolver->getCondensedA());
00364 }
00365 
00366 
00367 
00368 const Vector &
00369 DomainDecompositionAnalysis::getResidual()
00370 {
00371 
00372     Domain *the_Domain = this->getDomainPtr();
00373     
00374     // we check to see if the domain has changed 
00375     // we check to see if the domain has changed 
00376     int stamp = the_Domain->hasDomainChanged();
00377     if (stamp != domainStamp) {
00378  domainStamp = stamp;
00379  this->domainChanged();
00380  this->formResidual(); 
00381     }
00382     
00383     if (theResidual == 0) {
00384  theResidual = new Vector(theSolver->getCondensedRHS());
00385  return *theResidual; 
00386     }
00387     else if (theResidual->Size() != numExtEqn) {
00388  delete theResidual;
00389  theResidual = new Vector(theSolver->getCondensedRHS());
00390  return *theResidual;      
00391     }
00392     else {
00393  (*theResidual) = theSolver->getCondensedRHS();
00394     }
00395 
00396     return *theResidual;
00397 }
00398 
00399 
00400 
00401 
00402 const Vector &
00403 DomainDecompositionAnalysis::getTangVectProduct()
00404 {
00405     Domain *the_Domain = this->getDomainPtr();
00406     
00407     // we check to see if the domain has changed 
00408     int stamp = the_Domain->hasDomainChanged();
00409     if (stamp != domainStamp) {
00410  domainStamp = stamp;
00411  this->domainChanged();
00412     }
00413     
00414     return theSolver->getCondensedMatVect();
00415 }
00416 
00417 
00418 
00419 
00420 
00421 Subdomain  *
00422 DomainDecompositionAnalysis::getSubdomainPtr(void) const
00423 {
00424     return theSubdomain;
00425 }
00426 
00427 
00428 
00429 
00430 ConstraintHandler *
00431 DomainDecompositionAnalysis::getConstraintHandlerPtr(void) const
00432 {
00433     return theHandler;
00434 }
00435 
00436 
00437 
00438 DOF_Numberer *
00439 DomainDecompositionAnalysis::getDOF_NumbererPtr(void) const
00440 {
00441     return theNumberer;
00442 }
00443 
00444 
00445 
00446 AnalysisModel  *
00447 DomainDecompositionAnalysis::getAnalysisModelPtr(void) const
00448 {
00449     return theModel;
00450 }
00451 
00452 
00453 
00454 DomainDecompAlgo  *
00455 DomainDecompositionAnalysis::getDomainDecompAlgoPtr(void) const
00456 {
00457     return theAlgorithm;
00458 }
00459 
00460 
00461 
00462 IncrementalIntegrator *
00463 DomainDecompositionAnalysis::getIncrementalIntegratorPtr(void) const
00464 {
00465     return theIntegrator;
00466 }
00467 
00468 
00469 
00470 LinearSOE *
00471 DomainDecompositionAnalysis::getLinSOEPtr(void) const
00472 {
00473     return theSOE;    
00474 }
00475 
00476 
00477 
00478 DomainSolver *
00479 DomainDecompositionAnalysis::getDomainSolverPtr(void) const
00480 {
00481     return theSolver;
00482 }
00483 
00484 
00485 int 
00486 DomainDecompositionAnalysis::sendSelf(int commitTag,
00487           Channel &theChannel)
00488 {
00489     // determine the type of each object in the aggregation,
00490     // store it in an ID and send the info off.
00491     int dataTag = this->getDbTag();
00492     ID data(14);
00493     data(0) = theHandler->getClassTag();
00494     data(1) = theNumberer->getClassTag();
00495     data(2) = theModel->getClassTag();
00496     data(3) = theAlgorithm->getClassTag();
00497     data(4) = theIntegrator->getClassTag();    
00498     data(5) = theSOE->getClassTag();    
00499     data(6) = theSolver->getClassTag();        
00500 
00501     data(7) = theHandler->getDbTag();
00502     data(8) = theNumberer->getDbTag();
00503     data(9) = theModel->getDbTag();
00504     data(10) = theAlgorithm->getDbTag();
00505     data(11) = theIntegrator->getDbTag();    
00506     data(12) = theSOE->getDbTag();    
00507     data(13) = theSolver->getDbTag();        
00508 
00509     theChannel.sendID(dataTag, commitTag, data);
00510 
00511     // invoke sendSelf on each object in the aggregation
00512     
00513     theHandler->sendSelf(commitTag, theChannel);
00514     theNumberer->sendSelf(commitTag, theChannel);
00515     theModel->sendSelf(commitTag, theChannel);
00516     theAlgorithm->sendSelf(commitTag, theChannel);
00517     theIntegrator->sendSelf(commitTag, theChannel);    
00518     theSOE->sendSelf(commitTag, theChannel);    
00519     theSolver->sendSelf(commitTag, theChannel);            
00520     return 0;
00521 }
00522 
00523 int 
00524 DomainDecompositionAnalysis::recvSelf(int commitTag, 
00525           Channel &theChannel, 
00526           FEM_ObjectBroker &theBroker)
00527 {
00528     // receive the data identifyng the objects in the aggregation
00529     ID data(14);
00530     int dataTag = this->getDbTag();
00531     theChannel.recvID(dataTag, commitTag, data);
00532 
00533     //
00534     // now ask the object broker an object of each type
00535     // and invoke recvSelf() on the object to init it.
00536     //
00537 
00538     theHandler = theBroker.getNewConstraintHandler(data(0));
00539     if (theHandler != 0) {
00540  theHandler->setDbTag(data(7));
00541  theHandler->recvSelf(commitTag, theChannel,theBroker);
00542     }
00543     else {
00544  cerr << "DomainDecompositionAnalysis::recvSelf";
00545  cerr << " - failed to get the ConstraintHandler\n";
00546  return -1;
00547     }
00548 
00549 
00550 
00551     theNumberer = theBroker.getNewNumberer(data(1));
00552     if (theNumberer != 0) {
00553  theNumberer->setDbTag(data(8)); 
00554  theNumberer->recvSelf(commitTag, theChannel,theBroker);
00555     }
00556     else {
00557  cerr << "DomainDecompositionAnalysis::recvSelf";
00558  cerr << " - failed to get the DOF Numberer\n";
00559  return -1;
00560     }    
00561 
00562 
00563     theModel = theBroker.getNewAnalysisModel(data(2));
00564     if (theModel != 0) {
00565  theModel->setDbTag(data(9));
00566  theModel->recvSelf(commitTag, theChannel,theBroker);
00567     }
00568     else {
00569  cerr << "DomainDecompositionAnalysis::recvSelf";
00570  cerr << " - failed to get the AnalysisModel\n";
00571  return -1;
00572     }        
00573 
00574 
00575 
00576 
00577     theAlgorithm = theBroker.getNewDomainDecompAlgo(data(3));
00578     if (theAlgorithm != 0) {
00579  theAlgorithm->setDbTag(data(10));
00580  theAlgorithm->recvSelf(commitTag, theChannel,theBroker);
00581     }
00582     else {
00583  cerr << "DomainDecompositionAnalysis::recvSelf";
00584  cerr << " - failed to get the Domain Decomp Algo\n";
00585  return -1;
00586     }            
00587 
00588     theIntegrator = theBroker.getNewIncrementalIntegrator(data(4));
00589     if (theIntegrator != 0) {
00590  theIntegrator->setDbTag(data(11));
00591  theIntegrator->recvSelf(commitTag, theChannel,theBroker);
00592     }
00593     else {
00594  cerr << "DomainDecompositionAnalysis::recvSelf";
00595  cerr << " - failed to get the IncrementalIntegrator\n";
00596  return -1;
00597     }         
00598 
00599     theSOE = theBroker.getPtrNewDDLinearSOE(data(5),data(6));
00600     theSolver = theBroker.getNewDomainSolver();
00601 
00602     if (theSOE == 0 || theSolver == 0) {
00603  cerr << "DomainDecompositionAnalysis::recvSelf";
00604  cerr << " - failed to get the LinearSOE and the DomainSolver \n";
00605  return -1;
00606     }  else {
00607  theSOE->setDbTag(data(12));
00608  theSolver->setDbTag(data(13));
00609  theSOE->recvSelf(commitTag, theChannel,theBroker);
00610  theSolver->recvSelf(commitTag, theChannel,theBroker);
00611     }
00612 
00613     // set the links in all the objects
00614 
00615     theModel->setLinks(*theSubdomain);
00616     theHandler->setLinks(*theSubdomain,*theModel,*theIntegrator);
00617     theNumberer->setLinks(*theModel);
00618     theIntegrator->setLinks(*theModel,*theSOE);
00619     theAlgorithm->setLinks(*theModel,*theIntegrator,*theSOE,
00620       *theSolver,*theSubdomain);
00621 
00622     theSubdomain->setDomainDecompAnalysis(*this);
00623 
00624     return 0;
00625 }
00626 
00627 
00628 
00629 
Copyright Contact Us