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
00038
00039
00040
00041
00042 #include "NOX_StatusTest_NormWRMS.H"
00043 #include "NOX_Common.H"
00044 #include "NOX_Abstract_Vector.H"
00045 #include "NOX_Abstract_Group.H"
00046 #include "NOX_Solver_Generic.H"
00047 #include "NOX_Solver_LineSearchBased.H"
00048 #include "NOX_Utils.H"
00049
00050
00051
00052
00053 using namespace NOX::StatusTest;
00054
00055 NormWRMS::NormWRMS(double rtol_, double atol_, double BDFmult_, double tol_,
00056 double alpha_, double beta_) :
00057 value(0.0),
00058 rtol(rtol_),
00059 atolIsScalar(true),
00060 atol(atol_),
00061 factor(BDFmult_),
00062 tolerance(tol_),
00063 alpha(alpha_),
00064 computedStepSize(1.0),
00065 beta(beta_),
00066 achievedTol(0.0),
00067 status(Unconverged),
00068 printCriteria2Info(false),
00069 printCriteria3Info(false)
00070 {
00071
00072 }
00073
00074 NormWRMS::NormWRMS(double rtol_,
00075 const Teuchos::RCP<const NOX::Abstract::Vector>& atolVec_,
00076 double BDFmult_, double tol_, double alpha_, double beta_) :
00077 value(0.0),
00078 rtol(rtol_),
00079 atolIsScalar(false),
00080 atol(0.0),
00081 atolVec(atolVec_),
00082 factor(BDFmult_),
00083 tolerance(tol_),
00084 alpha(alpha_),
00085 computedStepSize(1.0),
00086 beta(beta_),
00087 achievedTol(0.0),
00088 status(Unconverged),
00089 printCriteria2Info(false),
00090 printCriteria3Info(false)
00091 {
00092
00093 }
00094
00095 NormWRMS::~NormWRMS()
00096 {
00097
00098 }
00099
00100 StatusType NormWRMS::
00101 checkStatus(const Solver::Generic& problem,
00102 NOX::StatusTest::CheckType checkType)
00103 {
00104 if (checkType == NOX::StatusTest::None) {
00105 status = Unevaluated;
00106 value = 1.0e+12;
00107 return status;
00108 }
00109
00110 status = Unconverged;
00111
00112 const Abstract::Group& soln = problem.getSolutionGroup();
00113 const Abstract::Group& oldsoln = problem.getPreviousSolutionGroup();
00114 const Abstract::Vector& x = soln.getX();
00115
00116
00117
00118
00119 int niters = problem.getNumIterations();
00120 if (niters == 0)
00121 {
00122 status = Unconverged;
00123 value = 1.0e+12;
00124 return status;
00125 }
00126
00127
00128
00129
00130
00131 if (Teuchos::is_null(u))
00132 u = x.clone(NOX::ShapeCopy);
00133 if (Teuchos::is_null(v))
00134 v = x.clone(NOX::ShapeCopy);
00135
00136
00137
00138 v->abs(oldsoln.getX());
00139 if (atolIsScalar)
00140 {
00141 u->init(1.0);
00142 u->update(rtol, *v, atol);
00143 }
00144 else
00145 {
00146 u->update(rtol, *v, 1.0, *atolVec, 0.0);
00147 }
00148
00149
00150 v->reciprocal(*u);
00151
00152
00153 u->update(1.0, x, -1.0, oldsoln.getX(), 0.0);
00154
00155
00156 u->scale(*v);
00157
00158
00159 value = u->norm() * factor / sqrt(static_cast<double>(u->length()));
00160
00161 StatusType status1 = Unconverged;
00162 if (value < tolerance)
00163 status1 = Converged;
00164
00165
00166
00167 StatusType status2 = Unconverged;
00168
00169
00170
00171 const Solver::Generic* test = 0;
00172 test = dynamic_cast<const Solver::LineSearchBased*>(&problem);
00173 if (test == 0)
00174 {
00175 status2 = Converged;
00176 }
00177 else
00178 {
00179 printCriteria2Info = true;
00180 computedStepSize =
00181 (dynamic_cast<const Solver::LineSearchBased*>(&problem))->getStepSize();
00182
00183 if (computedStepSize >= alpha)
00184 status2 = Converged;
00185 }
00186
00187
00188
00189
00190
00191
00192
00193 const Teuchos::ParameterList& p = problem.getList();
00194 if (niters == 1) {
00195 if (p.isSublist("Direction")) {
00196 if (p.sublist("Direction").isSublist("Newton")) {
00197 if (p.sublist("Direction").sublist("Newton").isSublist("Linear Solver")) {
00198 if (p.sublist("Direction").sublist("Newton").sublist("Linear Solver").isSublist("Output")) {
00199
00200 const Teuchos::ParameterList& list = p.sublist("Direction").sublist("Newton").sublist("Linear Solver").sublist("Output");
00201
00202 if (Teuchos::isParameterType<double>(list, "Achieved Tolerance")) {
00203
00204 printCriteria3Info = true;
00205
00206
00207 }
00208 }
00209 }
00210 }
00211 }
00212 }
00213
00214 StatusType status3 = Converged;
00215 if (printCriteria3Info) {
00216 achievedTol = const_cast<Teuchos::ParameterList&>(problem.getList()).
00217 sublist("Direction").sublist("Newton").sublist("Linear Solver").
00218 sublist("Output").get("Achieved Tolerance", -1.0);
00219 status3 = (achievedTol <= beta) ? Converged : Unconverged;
00220 }
00221
00222
00223
00224 if ((status1 == Converged) &&
00225 (status2 == Converged) &&
00226 (status3 == Converged))
00227 status = Converged;
00228
00229 return status;
00230 }
00231
00232 StatusType NormWRMS::getStatus() const
00233 {
00234 return status;
00235 }
00236
00237
00238 ostream& NormWRMS::print(ostream& stream, int indent) const
00239 {
00240 for (int j = 0; j < indent; j ++)
00241 stream << ' ';
00242 stream << status;
00243 stream << "WRMS-Norm = " << Utils::sciformat(value, 3) << " < " << tolerance;
00244 if (printCriteria2Info) {
00245 stream << "\n";
00246 for (int j = 0; j < indent + 13; j ++)
00247 stream << ' ';
00248 stream << "(Min Step Size: " << Utils::sciformat(computedStepSize, 3) << " >= " << alpha << ")";
00249 }
00250 if (printCriteria3Info) {
00251 stream << "\n";
00252 for (int j = 0; j < indent+ 13; j ++)
00253 stream << ' ';
00254 stream << "(Max Lin Solv Tol: " << Utils::sciformat(achievedTol, 3) << " < " << beta << ")";
00255 }
00256 stream << endl;
00257 return stream;
00258 }
00259
00260
00261 double NormWRMS::getNormWRMS() const
00262 {
00263 return value;
00264 }
00265
00266 double NormWRMS::getTolerance() const
00267 {
00268 return tolerance;
00269 }
00270
00271 double NormWRMS::getRTOL() const
00272 {
00273 return rtol;
00274 }
00275
00276 double NormWRMS::getATOL() const
00277 {
00278 if (atolIsScalar)
00279 return atol;
00280
00281 return (-1.0);
00282 }
00283
00284 double NormWRMS::getBDFMultiplier() const
00285 {
00286 return factor;
00287 }
00288
00289 double NormWRMS::getAlpha() const
00290 {
00291 return alpha;
00292 }
00293
00294 double NormWRMS::getBeta() const
00295 {
00296 return beta;
00297 }