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