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