VariableTimeStepDirectIntegrationAnalysis.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.5 $
00022 // $Date: 2005/12/06 18:20:22 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/analysis/analysis/VariableTimeStepDirectIntegrationAnalysis.cpp,v $
00024                                                                         
00025                                                                         
00026 // File: ~/analysis/analysis/VariableTimeStepDirectIntegrationAnalysis.C
00027 // 
00028 // Written: fmk 
00029 // Created: 10/00
00030 // Revision: A
00031 //
00032 // Description: This file contains the implementation of the
00033 // VariableTimeStepDirectIntegrationAnalysis class.
00034 //
00035 // What: "@(#) VariableTimeStepDirectIntegrationAnalysis.C, revA"
00036 
00037 #include <VariableTimeStepDirectIntegrationAnalysis.h>
00038 #include <EquiSolnAlgo.h>
00039 #include <TransientIntegrator.h>
00040 #include <Domain.h>
00041 #include <ConvergenceTest.h>
00042 #include <float.h>
00043 
00044 // Constructor
00045 VariableTimeStepDirectIntegrationAnalysis::VariableTimeStepDirectIntegrationAnalysis(
00046                               Domain &the_Domain,
00047                               ConstraintHandler &theHandler,
00048                               DOF_Numberer &theNumberer,
00049                               AnalysisModel &theModel,
00050                               EquiSolnAlgo &theSolnAlgo,                   
00051                               LinearSOE &theLinSOE,
00052                               TransientIntegrator &theTransientIntegrator,
00053                               ConvergenceTest *theTest)
00054 
00055 :DirectIntegrationAnalysis(the_Domain, theHandler, theNumberer, theModel, 
00056                            theSolnAlgo, theLinSOE, theTransientIntegrator, theTest)
00057 {
00058 
00059 }    
00060 
00061 VariableTimeStepDirectIntegrationAnalysis::~VariableTimeStepDirectIntegrationAnalysis()
00062 {
00063 
00064 }    
00065 
00066 
00067 int 
00068 VariableTimeStepDirectIntegrationAnalysis::analyze(int numSteps, double dT, double dtMin, double dtMax, int Jd)
00069 {
00070   // get some pointers
00071   Domain *theDom = this->getDomainPtr();
00072   EquiSolnAlgo *theAlgo = this->getAlgorithm();
00073   TransientIntegrator *theIntegratr = this->getIntegrator();
00074   ConvergenceTest *theTest = theAlgo->getConvergenceTest();
00075 
00076   // set some variables
00077   int result = 0;  
00078   double totalTimeIncr = numSteps * dT;
00079   double currentTimeIncr = 0.0;
00080   double currentDt = dT;
00081   
00082   // loop until analysis has performed the total time incr requested
00083   while (currentTimeIncr < totalTimeIncr) {
00084 
00085     if (this->checkDomainChange() != 0) {
00086       opserr << "VariableTimeStepDirectIntegrationAnalysis::analyze() - failed checkDomainChange\n";
00087       return -1;
00088     }
00089 
00090     //
00091     // do newStep(), solveCurrentStep() and commit() as in regular
00092     // DirectINtegrationAnalysis - difference is we do not return
00093     // if a failure - we stop the analysis & resize time step if failure
00094     //
00095 
00096     if (theIntegratr->newStep(currentDt) < 0) {
00097       result = -2;
00098     }
00099     
00100     if (result >= 0) {
00101       result = theAlgo->solveCurrentStep();
00102       if (result < 0) 
00103         result = -3;
00104     }    
00105 
00106     if (result >= 0) {
00107       result = theIntegratr->commit();
00108       if (result < 0) 
00109         result = -4;
00110     }
00111 
00112     // if the time step was successfull increment delta T for the analysis
00113     // othewise revert the Domain to last committed state & see if can go on
00114 
00115     if (result >= 0) 
00116       currentTimeIncr += currentDt;
00117     else {
00118 
00119       // invoke the revertToLastCommit
00120       theDom->revertToLastCommit();         
00121       theIntegratr->revertToLastStep();
00122 
00123       // if last dT was <= min specified the analysis FAILS - return FAILURE
00124       if (currentDt <= dtMin) {
00125         opserr << "VariableTimeStepDirectIntegrationAnalysis::analyze() - ";
00126         opserr << " failed at time " << theDom->getCurrentTime() << endln;
00127         return result;
00128       }
00129       
00130       // if still here reset result for next loop
00131       result = 0;
00132     }
00133 
00134     // now we determine a new delta T for next loop
00135     currentDt = this->determineDt(currentDt, dtMin, dtMax, Jd, theTest);
00136   }
00137 
00138   return 0;
00139 }
00140 
00141 
00142 
00143 
00144 
00145 double 
00146 VariableTimeStepDirectIntegrationAnalysis::determineDt(double dT, 
00147                                                        double dtMin, 
00148                                                        double dtMax, 
00149                                                        int Jd,
00150                                                        ConvergenceTest *theTest)
00151 {
00152   double newDt = dT;
00153     
00154   // get the number of trial steps in the last solveCurrentStep()
00155   double numLastIter = 1.0;
00156   if (theTest != 0)
00157     numLastIter = theTest->getNumTests();
00158   
00159   
00160   // determine new dT based on last dT and Jd and #iter of last step
00161   double factor = Jd/numLastIter;
00162   newDt *= factor;
00163   
00164   // ensure: dtMin <~~ dT <= dtMax
00165   if (newDt < dtMin)
00166     newDt = dtMin - DBL_EPSILON;  // to ensure we get out of the analysis 
00167                                // loop if can't converge on next step
00168   else if (newDt > dtMax)
00169     newDt = dtMax;
00170     
00171   return newDt;
00172 }
00173 
00174 

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