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 #include <PeriodicNewton.h>
00035 #include <AnalysisModel.h>
00036 #include <StaticAnalysis.h>
00037 #include <IncrementalIntegrator.h>
00038 #include <LinearSOE.h>
00039 #include <ID.h>
00040 #include <Channel.h>
00041 #include <FEM_ObjectBroker.h>
00042 #include <ConvergenceTest.h>
00043
00044
00045 PeriodicNewton::PeriodicNewton(int theTangentToUse, int mc)
00046 :EquiSolnAlgo(EquiALGORITHM_TAGS_PeriodicNewton),
00047 theTest(0), tangent(theTangentToUse), maxCount(mc)
00048 {
00049
00050 }
00051
00052
00053 PeriodicNewton::PeriodicNewton(ConvergenceTest &theT, int theTangentToUse, int mc)
00054 :EquiSolnAlgo(EquiALGORITHM_TAGS_PeriodicNewton),
00055 theTest(&theT), tangent(theTangentToUse), maxCount(mc)
00056 {
00057
00058 }
00059
00060
00061 PeriodicNewton::~PeriodicNewton()
00062 {
00063
00064 }
00065
00066 int
00067 PeriodicNewton::setConvergenceTest(ConvergenceTest *newTest)
00068 {
00069 theTest = newTest;
00070 return 0;
00071 }
00072
00073 int
00074 PeriodicNewton::solveCurrentStep(void)
00075 {
00076
00077
00078 AnalysisModel *theAnalysisModel = this->getAnalysisModelPtr();
00079 IncrementalIntegrator *theIncIntegratorr = this->getIncrementalIntegratorPtr();
00080 LinearSOE *theSOE = this->getLinearSOEptr();
00081
00082 if ((theAnalysisModel == 0) || (theIncIntegratorr == 0) || (theSOE == 0)
00083 || (theTest == 0)){
00084 opserr << "WARNING PeriodicNewton::solveCurrentStep() - setLinks() has";
00085 opserr << " not been called - or no ConvergenceTest has been set\n";
00086 return -5;
00087 }
00088
00089
00090
00091 if (theIncIntegratorr->formUnbalance() < 0) {
00092 opserr << "WARNING PeriodicNewton::solveCurrentStep() -";
00093 opserr << "the Integrator failed in formUnbalance()\n";
00094 return -2;
00095 }
00096
00097 if (theIncIntegratorr->formTangent(tangent) < 0){
00098 opserr << "WARNING PeriodicNewton::solveCurrentStep() -";
00099 opserr << "the Integrator failed in formTangent()\n";
00100 return -1;
00101 }
00102
00103
00104 theTest->setEquiSolnAlgo(*this);
00105 if (theTest->start() < 0) {
00106 opserr << "PeriodicNewton::solveCurrentStep() -";
00107 opserr << "the ConvergenceTest object failed in start()\n";
00108 return -3;
00109 }
00110
00111
00112 int result = -1;
00113 int count = 0;
00114 int iter = 0;
00115 do {
00116 if (theSOE->solve() < 0) {
00117 opserr << "WARNING PeriodicNewton::solveCurrentStep() -";
00118 opserr << "the LinearSysOfEqn failed in solve()\n";
00119 return -3;
00120 }
00121
00122 if (theIncIntegratorr->update(theSOE->getX()) < 0) {
00123 opserr << "WARNING PeriodicNewton::solveCurrentStep() -";
00124 opserr << "the Integrator failed in update()\n";
00125 return -4;
00126 }
00127
00128 if (theIncIntegratorr->formUnbalance() < 0) {
00129 opserr << "WARNING PeriodicNewton::solveCurrentStep() -";
00130 opserr << "the Integrator failed in formUnbalance()\n";
00131 return -2;
00132 }
00133
00134 this->record(count++);
00135 result = theTest->test();
00136
00137 iter++;
00138 if (iter > maxCount) {
00139 if (theIncIntegratorr->formTangent(tangent) < 0){
00140 opserr << "WARNING PeriodicNewton::solveCurrentStep() -";
00141 opserr << "the Integrator failed in formTangent()\n";
00142 return -1;
00143 }
00144 iter = 0;
00145 }
00146
00147 } while (result == -1);
00148
00149 if (result == -2) {
00150 opserr << "PeriodicNewton::solveCurrentStep() -";
00151 opserr << "the ConvergenceTest object failed in test()\n";
00152 return -3;
00153 }
00154
00155 return result;
00156 }
00157
00158 ConvergenceTest *
00159 PeriodicNewton::getConvergenceTest(void)
00160 {
00161 return theTest;
00162 }
00163
00164 int
00165 PeriodicNewton::sendSelf(int cTag, Channel &theChannel)
00166 {
00167 int result = 0;
00168 int dataTag = this->getDbTag();
00169 static ID data(3);
00170 data(0) = theTest->getClassTag();
00171 data(1) = theTest->getDbTag();
00172 data(2) = maxCount;
00173
00174 result = theChannel.sendID(dataTag, cTag, data);
00175 if (result != 0) {
00176 opserr << "PeriodicNewton::sendSelf() - failed to send ID\n";
00177 return result;
00178 }
00179
00180 result = theTest->sendSelf(cTag, theChannel);
00181 if (result != 0) {
00182 opserr << "PeriodicNewton::sendSelf() - failed to send CTest object\n";
00183 return result;
00184 }
00185
00186 return 0;
00187 }
00188
00189 int
00190 PeriodicNewton::recvSelf(int cTag,
00191 Channel &theChannel,
00192 FEM_ObjectBroker &theBroker)
00193 {
00194 static ID data(3);
00195 int result;
00196 int dataTag = this->getDbTag();
00197
00198 result = theChannel.recvID(dataTag, cTag, data);
00199 if (result != 0) {
00200 opserr << "PeriodicNewton::recvSelf() - failed to receive ID\n";
00201 return result;
00202 }
00203 int ctType = data(0);
00204 int ctDb = data(1);
00205 maxCount = data(2);
00206
00207 theTest = theBroker.getNewConvergenceTest(ctType);
00208 theTest->setDbTag(ctDb);
00209 result = theTest->recvSelf(cTag, theChannel, theBroker);
00210 if (result != 0) {
00211 opserr << "PeriodicNewton::recvSelf() - failed to recv CTest object\n";
00212 return result;
00213 }
00214
00215 return 0;
00216 }
00217
00218 void
00219 PeriodicNewton::Print(OPS_Stream &s, int flag)
00220 {
00221 if (flag == 0) {
00222 s << "PeriodicNewton" << endln;
00223 s << "Max count: " << maxCount << endln;
00224 }
00225 }