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