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 <CTestEnergyIncr.h>
00038 #include <Vector.h>
00039 #include <Channel.h>
00040 #include <EquiSolnAlgo.h>
00041 #include <LinearSOE.h>
00042
00043
00044 CTestEnergyIncr::CTestEnergyIncr()
00045 : ConvergenceTest(CONVERGENCE_TEST_CTestEnergyIncr),
00046 theSOE(0), tol(0), maxNumIter(0), currentIter(0), printFlag(0),
00047 norms(1), nType(2)
00048 {
00049
00050 }
00051
00052
00053 CTestEnergyIncr::CTestEnergyIncr(double theTol, int maxIter, int printIt, int normType)
00054 : ConvergenceTest(CONVERGENCE_TEST_CTestEnergyIncr),
00055 theSOE(0), tol(theTol), maxNumIter(maxIter), currentIter(0),printFlag(printIt),
00056 norms(maxNumIter), nType(normType)
00057 {
00058
00059 }
00060
00061
00062 CTestEnergyIncr::~CTestEnergyIncr()
00063 {
00064
00065 }
00066
00067
00068 ConvergenceTest* CTestEnergyIncr::getCopy(int iterations)
00069 {
00070 CTestEnergyIncr *theCopy ;
00071 theCopy = new CTestEnergyIncr(this->tol, iterations, this->printFlag, this->nType);
00072
00073 theCopy->theSOE = this->theSOE ;
00074
00075 return theCopy ;
00076 }
00077
00078
00079 void CTestEnergyIncr::setTolerance(double newTol)
00080 {
00081 tol = newTol;
00082 }
00083
00084
00085 int CTestEnergyIncr::setEquiSolnAlgo(EquiSolnAlgo &theAlgo)
00086 {
00087 theSOE = theAlgo.getLinearSOEptr();
00088 if (theSOE == 0) {
00089 opserr << "WARNING: CTestEnergyIncr::setEquiSolnAlgo - no SOE\n";
00090 return -1;
00091 }
00092 else
00093 return 0;
00094 }
00095
00096
00097 int CTestEnergyIncr::test(void)
00098 {
00099
00100
00101 if (theSOE == 0)
00102 return -2;
00103
00104
00105
00106 if (currentIter == 0) {
00107 opserr << "WARNING: CTestEnergyIncr::test() - start() was never invoked.\n";
00108 return -2;
00109 }
00110
00111
00112 const Vector &b = theSOE->getB();
00113 const Vector &x = theSOE->getX();
00114 double product = x ^ b;
00115 if (product < 0.0)
00116 product *= -0.5;
00117 else
00118 product *= 0.5;
00119
00120 if (currentIter <= maxNumIter)
00121 norms(currentIter-1) = product;
00122
00123
00124 if (printFlag == 1) {
00125 opserr << "CTestEnergyIncr::test() - iteration: " << currentIter;
00126 opserr << " current EnergyIncr: " << product << " (max: " << tol << ")\n";
00127 }
00128 if (printFlag == 4) {
00129 opserr << "CTestEnergyIncr::test() - iteration: " << currentIter;
00130 opserr << " current EnergyIncr: " << product << " (max: " << tol << ")\n";
00131 opserr << "\tNorm deltaX: " << x.pNorm(nType) << ", Norm deltaR: " << b.pNorm(nType) << endln;
00132 opserr << "\tdeltaX: " << x << "\tdeltaR: " << b;
00133 }
00134
00135
00136
00137
00138
00139
00140 if (product <= tol) {
00141
00142
00143 if (printFlag != 0) {
00144 if (printFlag == 1 || printFlag == 4)
00145 opserr << endln;
00146 else if (printFlag == 2 || printFlag == 6) {
00147 opserr << "CTestEnergyIncr::test() - iteration: " << currentIter;
00148 opserr << " last EnergyIncr: " << product << " (max: " << tol << ")\n";
00149 }
00150 }
00151
00152
00153 return currentIter;
00154 }
00155
00156
00157 else if ((printFlag == 5 || printFlag == 6) && currentIter >= maxNumIter) {
00158 opserr << "WARNING: CTestEnergyIncr::test() - failed to converge but goin on -";
00159 opserr << " current EnergyIncr: " << product << " (max: " << tol << ")\n";
00160 opserr << "\tNorm deltaX: " << x.pNorm(nType) << ", Norm deltaR: " << b.pNorm(nType) << endln;
00161 return currentIter;
00162 }
00163
00164
00165 else if (currentIter >= maxNumIter) {
00166 opserr << "WARNING: CTestEnergyIncr::test() - failed to converge \n";
00167 opserr << "after: " << currentIter << " iterations\n";
00168 currentIter++;
00169 return -2;
00170 }
00171
00172
00173 else {
00174 currentIter++;
00175 return -1;
00176 }
00177 }
00178
00179
00180 int CTestEnergyIncr::start(void)
00181 {
00182 if (theSOE == 0) {
00183 opserr << "WARNING: CTestEnergyIncr::test() - no SOE returning true\n";
00184 return -1;
00185 }
00186
00187
00188 currentIter = 1;
00189 norms.Zero();
00190 return 0;
00191 }
00192
00193
00194 int CTestEnergyIncr::getNumTests(void)
00195 {
00196 return currentIter;
00197 }
00198
00199
00200 int CTestEnergyIncr::getMaxNumTests(void)
00201 {
00202 return maxNumIter;
00203 }
00204
00205
00206 double CTestEnergyIncr::getRatioNumToMax(void)
00207 {
00208 double div = maxNumIter;
00209 return currentIter/div;
00210 }
00211
00212
00213 const Vector& CTestEnergyIncr::getNorms(void)
00214 {
00215 return norms;
00216 }
00217
00218
00219 int CTestEnergyIncr::sendSelf(int cTag, Channel &theChannel)
00220 {
00221 int res = 0;
00222 static Vector x(4);
00223 x(0) = tol;
00224 x(1) = maxNumIter;
00225 x(2) = printFlag;
00226 x(3) = nType;
00227 res = theChannel.sendVector(this->getDbTag(), cTag, x);
00228 if (res < 0)
00229 opserr << "CTestEnergyIncr::sendSelf() - failed to send data\n";
00230
00231 return res;
00232 }
00233
00234
00235 int CTestEnergyIncr::recvSelf(int cTag, Channel &theChannel,
00236 FEM_ObjectBroker &theBroker)
00237 {
00238 int res = 0;
00239 static Vector x(4);
00240 res = theChannel.recvVector(this->getDbTag(), cTag, x);
00241
00242 if (res < 0) {
00243 opserr << "CTestEnergyIncr::sendSelf() - failed to send data\n";
00244 tol = 1.0e-8;
00245 maxNumIter = 25;
00246 printFlag = 0;
00247 nType = 2;
00248 }
00249 else {
00250 tol = x(0);
00251 maxNumIter = (int) x(1);
00252 printFlag = (int) x(2);
00253 nType = (int) x(3);
00254 norms.resize(maxNumIter);
00255 }
00256
00257 return res;
00258 }