StaticAnalysis.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.10 $
00022 // $Date: 2005/11/29 23:36:47 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/analysis/analysis/StaticAnalysis.cpp,v $
00024                                                                         
00025                                                                         
00026 // Written: fmk 
00027 //
00028 // Description: This file contains the implementation of StaticAnalysis.
00029 //
00030 // What: "@(#) StaticAnalysis.C, revA"
00031 
00032 #include <StaticAnalysis.h>
00033 #include <EquiSolnAlgo.h>
00034 #include <AnalysisModel.h>
00035 #include <LinearSOE.h>
00036 #include <DOF_Numberer.h>
00037 #include <ConstraintHandler.h>
00038 #include <ConvergenceTest.h>
00039 #include <StaticIntegrator.h>
00040 #include <Domain.h>
00041 #include <FE_Element.h>
00042 #include <DOF_Group.h>
00043 #include <FE_EleIter.h>
00044 #include <DOF_GrpIter.h>
00045 #include <Matrix.h>
00046 #include <ID.h>
00047 #include <Graph.h>
00048 #include <Timer.h>
00049 
00050 // AddingSensitivity:BEGIN //////////////////////////////////
00051 #ifdef _RELIABILITY
00052 #include <SensitivityAlgorithm.h>
00053 #endif
00054 // AddingSensitivity:END ////////////////////////////////////
00055 
00056 
00057 // Constructor
00058 //    sets theModel and theSysOFEqn to 0 and the Algorithm to the one supplied
00059 
00060 StaticAnalysis::StaticAnalysis(Domain &the_Domain,
00061                                ConstraintHandler &theHandler,
00062                                DOF_Numberer &theNumberer,
00063                                AnalysisModel &theModel,
00064                                EquiSolnAlgo &theSolnAlgo,                  
00065                                LinearSOE &theLinSOE,
00066                                StaticIntegrator &theStaticIntegrator,
00067                                ConvergenceTest *theConvergenceTest)
00068 :Analysis(the_Domain), theConstraintHandler(&theHandler),
00069  theDOF_Numberer(&theNumberer), theAnalysisModel(&theModel), 
00070  theAlgorithm(&theSolnAlgo), theSOE(&theLinSOE),
00071  theIntegrator(&theStaticIntegrator), theTest(theConvergenceTest),
00072  domainStamp(0)
00073 {
00074     // first we set up the links needed by the elements in the 
00075     // aggregation
00076     theAnalysisModel->setLinks(the_Domain, theHandler);
00077     theConstraintHandler->setLinks(the_Domain,theModel,theStaticIntegrator);
00078     theDOF_Numberer->setLinks(theModel);
00079 
00080     theIntegrator->setLinks(theModel,theLinSOE);
00081     theAlgorithm->setLinks(theModel,theStaticIntegrator,theLinSOE);
00082 
00083     if (theTest != 0)
00084       theAlgorithm->setConvergenceTest(theTest);
00085 
00086     // AddingSensitivity:BEGIN ////////////////////////////////////
00087 #ifdef _RELIABILITY
00088     theSensitivityAlgorithm = 0;
00089 #endif
00090     // AddingSensitivity:END //////////////////////////////////////
00091 }    
00092 
00093 
00094 StaticAnalysis::~StaticAnalysis()
00095 {
00096   // we don't invoke the destructors in case user switching
00097   // from a static to a direct integration analysis 
00098   // clearAll() must be invoked if user wishes to invoke destructor
00099 }    
00100 
00101 void
00102 StaticAnalysis::clearAll(void)
00103 {
00104   // invoke the destructor on all the objects in the aggregation
00105   if (theAnalysisModel != 0)     
00106     delete theAnalysisModel;
00107   if (theConstraintHandler != 0) 
00108     delete theConstraintHandler;
00109   if (theDOF_Numberer != 0)      
00110     delete theDOF_Numberer;
00111   if (theIntegrator != 0) 
00112     delete theIntegrator;
00113   if (theAlgorithm != 0)  
00114     delete theAlgorithm;
00115   if (theSOE != 0)
00116     delete theSOE;
00117   if (theTest != 0)
00118     delete theTest;
00119 
00120   // now set the pointers to NULL
00121   theAnalysisModel =0;
00122   theConstraintHandler =0;
00123   theDOF_Numberer =0;
00124   theIntegrator =0;
00125   theAlgorithm =0;
00126   theSOE =0;
00127   theTest = 0;
00128 
00129   // AddingSensitivity:BEGIN ////////////////////////////////////
00130 #ifdef _RELIABILITY
00131   delete theSensitivityAlgorithm;
00132   theSensitivityAlgorithm =0;
00133 #endif
00134   // AddingSensitivity:END //////////////////////////////////////
00135 }    
00136 
00137 
00138 int 
00139 StaticAnalysis::analyze(int numSteps)
00140 {
00141     int result = 0;
00142     Domain *the_Domain = this->getDomainPtr();
00143 
00144     for (int i=0; i<numSteps; i++) {
00145 
00146         result = theAnalysisModel->newStepDomain();
00147         if (result < 0) {
00148             opserr << "StaticAnalysis::analyze() - the AnalysisModel failed";
00149             opserr << " at iteration: " << i << " with domain at load factor ";
00150             opserr << the_Domain->getCurrentTime() << endln;
00151             the_Domain->revertToLastCommit();
00152 
00153             return -2;
00154         }
00155 
00156         // check for change in Domain since last step. As a change can
00157         // occur in a commit() in a domaindecomp with load balancing
00158         // this must now be inside the loop
00159 
00160         int stamp = the_Domain->hasDomainChanged();
00161 
00162         if (stamp != domainStamp) {
00163             domainStamp = stamp;
00164 
00165             result = this->domainChanged();
00166 
00167             if (result < 0) {
00168                 opserr << "StaticAnalysis::analyze() - domainChanged failed";
00169                 opserr << " at step " << i << " of " << numSteps << endln;
00170                 return -1;
00171             }   
00172         }
00173 
00174 
00175         result = theIntegrator->newStep();
00176         if (result < 0) {
00177             opserr << "StaticAnalysis::analyze() - the Integrator failed";
00178             opserr << " at iteration: " << i << " with domain at load factor ";
00179             opserr << the_Domain->getCurrentTime() << endln;
00180             the_Domain->revertToLastCommit();
00181 
00182             return -2;
00183         }
00184 
00185         result = theAlgorithm->solveCurrentStep();
00186         if (result < 0) {
00187             opserr << "StaticAnalysis::analyze() - the Algorithm failed";
00188             opserr << " at iteration: " << i << " with domain at load factor ";
00189             opserr << the_Domain->getCurrentTime() << endln;
00190             the_Domain->revertToLastCommit();       
00191             theIntegrator->revertToLastStep();
00192 
00193             return -3;
00194         }    
00195 
00196 // AddingSensitivity:BEGIN ////////////////////////////////////
00197 #ifdef _RELIABILITY
00198         if (theSensitivityAlgorithm != 0) {
00199                 result = theSensitivityAlgorithm->computeSensitivities();
00200                 if (result < 0) {
00201                         opserr << "StaticAnalysis::analyze() - the SensitivityAlgorithm failed";
00202                         opserr << " at iteration: " << i << " with domain at load factor ";
00203                         opserr << the_Domain->getCurrentTime() << endln;
00204                         the_Domain->revertToLastCommit();           
00205                         theIntegrator->revertToLastStep();
00206                         return -5;
00207                 }    
00208         }
00209 #endif
00210 // AddingSensitivity:END //////////////////////////////////////
00211 
00212         result = theIntegrator->commit();
00213         if (result < 0) {
00214             opserr << "StaticAnalysis::analyze() - ";
00215             opserr << "the Integrator failed to commit";
00216             opserr << " at iteration: " << i << " with domain at load factor ";
00217             opserr << the_Domain->getCurrentTime() << endln;
00218             the_Domain->revertToLastCommit();       
00219             theIntegrator->revertToLastStep();
00220 
00221             return -4;
00222         }       
00223     }
00224     
00225     return 0;
00226 }
00227 
00228 
00229 int 
00230 StaticAnalysis::initialize(void)
00231 {
00232     Domain *the_Domain = this->getDomainPtr();
00233 
00234     // check if domain has undergone change
00235     int stamp = the_Domain->hasDomainChanged();
00236     if (stamp != domainStamp) {
00237       domainStamp = stamp;      
00238       if (this->domainChanged() < 0) {
00239         opserr << "DirectIntegrationAnalysis::initialize() - domainChanged() failed\n";
00240         return -1;
00241       } 
00242     }
00243     if (theIntegrator->initialize() < 0) {
00244         opserr << "DirectIntegrationAnalysis::initialize() - integrator initialize() failed\n";
00245         return -2;
00246     } else
00247       theIntegrator->commit();
00248     
00249     return 0;
00250 }
00251 
00252 int
00253 StaticAnalysis::domainChanged(void)
00254 {
00255     int result = 0;
00256 
00257     Domain *the_Domain = this->getDomainPtr();
00258     int stamp = the_Domain->hasDomainChanged();
00259     domainStamp = stamp;
00260 
00261     // Timer theTimer; theTimer.start();
00262     // opserr << "StaticAnalysis::domainChanged(void)\n";
00263 
00264     theAnalysisModel->clearAll();    
00265     theConstraintHandler->clearAll();
00266 
00267     // theTimer.pause(); 
00268     // cout <<  "StaticAnalysis::clearAll() " << theTimer.getReal();
00269     // cout << theTimer.getCPU() << endln;
00270     // theTimer.start();    
00271 
00272     // now we invoke handle() on the constraint handler which
00273     // causes the creation of FE_Element and DOF_Group objects
00274     // and their addition to the AnalysisModel.
00275 
00276     result = theConstraintHandler->handle();
00277     if (result < 0) {
00278         opserr << "StaticAnalysis::handle() - ";
00279         opserr << "ConstraintHandler::handle() failed";
00280         return -1;
00281     }
00282 
00283     // we now invoke number() on the numberer which causes
00284     // equation numbers to be assigned to all the DOFs in the
00285     // AnalysisModel.
00286 
00287     result = theDOF_Numberer->numberDOF();
00288     if (result < 0) {
00289         opserr << "StaticAnalysis::handle() - ";
00290         opserr << "DOF_Numberer::numberDOF() failed";
00291         return -2;
00292     }       
00293 
00294     result = theConstraintHandler->doneNumberingDOF();
00295     if (result < 0) {
00296         opserr << "StaticAnalysis::handle() - ";
00297         opserr << "ConstraintHandler::doneNumberingDOF() failed";
00298         return -2;
00299     }       
00300 
00301     // we invoke setSize() on the LinearSOE which
00302     // causes that object to determine its size
00303 
00304     Graph &theGraph = theAnalysisModel->getDOFGraph();
00305 
00306     result = theSOE->setSize(theGraph);
00307     if (result < 0) {
00308         opserr << "StaticAnalysis::handle() - ";
00309         opserr << "LinearSOE::setSize() failed";
00310         return -3;
00311     }       
00312 
00313     // finally we invoke domainChanged on the Integrator and Algorithm
00314     // objects .. informing them that the model has changed
00315 
00316     result = theIntegrator->domainChanged();
00317     if (result < 0) {
00318         opserr << "StaticAnalysis::setAlgorithm() - ";
00319         opserr << "Integrator::domainChanged() failed";
00320         return -4;
00321     }       
00322 
00323     result = theAlgorithm->domainChanged();
00324     if (result < 0) {
00325         opserr << "StaticAnalysis::setAlgorithm() - ";
00326         opserr << "Algorithm::domainChanged() failed";
00327         return -5;
00328     }           
00329 
00330     // if get here successfull
00331     return 0;
00332 }    
00333 
00334 // AddingSensitivity:BEGIN //////////////////////////////
00335 #ifdef _RELIABILITY
00336 int 
00337 StaticAnalysis::setSensitivityAlgorithm(SensitivityAlgorithm *passedSensitivityAlgorithm)
00338 {
00339     int result = 0;
00340 
00341     // invoke the destructor on the old one
00342     if (theSensitivityAlgorithm != 0) {
00343       delete theSensitivityAlgorithm;
00344     }
00345     
00346     theSensitivityAlgorithm = passedSensitivityAlgorithm;
00347     
00348     return 0;
00349 }
00350 #endif
00351 // AddingSensitivity:END ///////////////////////////////
00352 
00353 
00354 int 
00355 StaticAnalysis::setNumberer(DOF_Numberer &theNewNumberer) 
00356 {
00357     // invoke the destructor on the old one
00358     if (theDOF_Numberer != 0)
00359         delete theDOF_Numberer;
00360 
00361     // first set the links needed by the Algorithm
00362     theDOF_Numberer = &theNewNumberer;
00363     theDOF_Numberer->setLinks(*theAnalysisModel);
00364 
00365     // invoke domainChanged() either indirectly or directly
00366     domainStamp = 0;
00367 
00368     return 0;
00369 }
00370 
00371 
00372 int 
00373 StaticAnalysis::setAlgorithm(EquiSolnAlgo &theNewAlgorithm) 
00374 {
00375     // invoke the destructor on the old one
00376     if (theAlgorithm != 0)
00377         delete theAlgorithm;
00378 
00379     // first set the links needed by the Algorithm
00380     theAlgorithm = &theNewAlgorithm;
00381     theAlgorithm->setLinks(*theAnalysisModel,*theIntegrator,*theSOE);
00382     
00383     if (theTest != 0)
00384       theAlgorithm->setConvergenceTest(theTest);
00385     else   // this else is for backward compatability.
00386       theTest = theAlgorithm->getConvergenceTest();
00387     
00388     // invoke domainChanged() either indirectly or directly
00389     domainStamp = 0;
00390 
00391     return 0;
00392 }
00393 
00394 int 
00395 StaticAnalysis::setIntegrator(StaticIntegrator &theNewIntegrator)
00396 {
00397     // invoke the destructor on the old one
00398     if (theIntegrator != 0) {
00399         delete theIntegrator;
00400     }
00401 
00402     // set the links needed by the other objects in the aggregation
00403     Domain *the_Domain = this->getDomainPtr();
00404   
00405     theIntegrator = &theNewIntegrator;
00406     theIntegrator->setLinks(*theAnalysisModel,*theSOE);
00407     theConstraintHandler->setLinks(*the_Domain,*theAnalysisModel,*theIntegrator);
00408     theAlgorithm->setLinks(*theAnalysisModel,*theIntegrator,*theSOE);
00409     
00410     // cause domainChanged to be invoked on next analyze
00411     domainStamp = 0;
00412   
00413   return 0;
00414 
00415 }
00416 
00417 int 
00418 StaticAnalysis::setLinearSOE(LinearSOE &theNewSOE)
00419 {
00420     // invoke the destructor on the old one
00421     if (theSOE != 0)
00422         delete theSOE;
00423 
00424     // set the links needed by the other objects in the aggregation
00425     theSOE = &theNewSOE;
00426     theIntegrator->setLinks(*theAnalysisModel,*theSOE);
00427     theAlgorithm->setLinks(*theAnalysisModel,*theIntegrator,*theSOE);
00428 
00429     // cause domainChanged to be invoked on next analyze
00430     domainStamp = 0;
00431 
00432     return 0;
00433 }
00434 
00435 
00436 int 
00437 StaticAnalysis::setConvergenceTest(ConvergenceTest &theNewTest)
00438 {
00439     // invoke the destructor on the old one
00440     if (theTest != 0)
00441         delete theTest;
00442 
00443     // set the links needed by the other objects in the aggregation
00444     theTest = &theNewTest;
00445     return theAlgorithm->setConvergenceTest(theTest);
00446 }
00447 
00448 
00449 
00450 
00451 
00452 
00453 
00454 
00455 
00456 
00457 
00458 
00459 
00460 

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