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 #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
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
00071 Domain *theDom = this->getDomainPtr();
00072 EquiSolnAlgo *theAlgo = this->getAlgorithm();
00073 TransientIntegrator *theIntegratr = this->getIntegrator();
00074 ConvergenceTest *theTest = theAlgo->getConvergenceTest();
00075
00076
00077 int result = 0;
00078 double totalTimeIncr = numSteps * dT;
00079 double currentTimeIncr = 0.0;
00080 double currentDt = dT;
00081
00082
00083 while (currentTimeIncr < totalTimeIncr) {
00084
00085 if (this->checkDomainChange() != 0) {
00086 opserr << "VariableTimeStepDirectIntegrationAnalysis::analyze() - failed checkDomainChange\n";
00087 return -1;
00088 }
00089
00090
00091
00092
00093
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
00113
00114
00115 if (result >= 0)
00116 currentTimeIncr += currentDt;
00117 else {
00118
00119
00120 theDom->revertToLastCommit();
00121 theIntegratr->revertToLastStep();
00122
00123
00124 if (currentDt <= dtMin) {
00125 opserr << "VariableTimeStepDirectIntegrationAnalysis::analyze() - ";
00126 opserr << " failed at time " << theDom->getCurrentTime() << endln;
00127 return result;
00128 }
00129
00130
00131 result = 0;
00132 }
00133
00134
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
00155 double numLastIter = 1.0;
00156 if (theTest != 0)
00157 numLastIter = theTest->getNumTests();
00158
00159
00160
00161 double factor = Jd/numLastIter;
00162 newDt *= factor;
00163
00164
00165 if (newDt < dtMin)
00166 newDt = dtMin - DBL_EPSILON;
00167
00168 else if (newDt > dtMax)
00169 newDt = dtMax;
00170
00171 return newDt;
00172 }
00173
00174