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