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
00043
00044
00045
00046
00047
00048
00049
00050 #include "PlayaNOXSolver.hpp"
00051 #include "NOX_StatusTest_SafeCombo.hpp"
00052 #include "NOX.H"
00053
00054 #include "PlayaLinearSolverBuilder.hpp"
00055 #include "Teuchos_Time.hpp"
00056 #include "Teuchos_TimeMonitor.hpp"
00057 #include "PlayaOut.hpp"
00058 #include "PlayaTabs.hpp"
00059 #include "PlayaExceptions.hpp"
00060 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00061 #include "PlayaVectorImpl.hpp"
00062 #include "PlayaLinearOperatorImpl.hpp"
00063 #endif
00064
00065
00066 using namespace NOX;
00067 using namespace NOX::NOXPlaya;
00068 using namespace Teuchos;
00069 using namespace Playa;
00070 using std::runtime_error;
00071 using std::cout;
00072 using std::ostream;
00073
00074
00075 static Time& noxSolverTimer()
00076 {
00077 static RCP<Time> rtn
00078 = TimeMonitor::getNewTimer("NOX solve");
00079 return *rtn;
00080 }
00081
00082 NOXSolver::NOXSolver(const ParameterList& params)
00083 : linSolver_(),
00084 statusTest_(),
00085 params_(),
00086 printParams_()
00087 {
00088 TEUCHOS_TEST_FOR_EXCEPTION(!params.isSublist("NOX Solver"), runtime_error,
00089 "did not find NOX Solver sublist in " << params);
00090
00091 params_ = params.sublist("NOX Solver");
00092
00093 params_.sublist("Printing").set("MyPID", MPIComm::world().getRank());
00094
00095 if (params_.isSublist("Status Test"))
00096 {
00097 statusTest_ = StatusTestBuilder::makeStatusTest(params_);
00098 }
00099 else
00100 {
00101 RCP<StatusTest::Generic> A = rcp(new StatusTest::NormF(1.0e-12));
00102 RCP<StatusTest::Generic> B = rcp(new StatusTest::MaxIters(20));
00103 statusTest_ =
00104 rcp(new StatusTest::SafeCombo(StatusTest::SafeCombo::OR, A, B));
00105 }
00106
00107 if (params_.isSublist("Linear Solver"))
00108 {
00109 linSolver_ = LinearSolverBuilder::createSolver(params_);
00110 }
00111 else
00112 {
00113 TEUCHOS_TEST_FOR_EXCEPTION(!params_.isSublist("Linear Solver"),
00114 RuntimeError, "no linear solver specified in NOX parameters");
00115 }
00116
00117 if (params_.isSublist("Printing"))
00118 {
00119 printParams_ = params_.sublist("Printing");
00120 }
00121
00122 TEUCHOS_TEST_FOR_EXCEPTION(linSolver_.ptr().get()==0, runtime_error,
00123 "null linear solver object in NOXSolver ctor");
00124
00125 TEUCHOS_TEST_FOR_EXCEPTION(statusTest_.get()==0, runtime_error,
00126 "null status test object in NOXSolver ctor");
00127
00128 }
00129
00130 NOXSolver::NOXSolver(const ParameterList& nonlinParams,
00131 const LinearSolver<double>& linSolver)
00132 : linSolver_(linSolver),
00133 statusTest_(),
00134 params_(),
00135 printParams_()
00136 {
00137 Tabs tab(0);
00138 TEUCHOS_TEST_FOR_EXCEPTION(!nonlinParams.isSublist("NOX Solver"), runtime_error,
00139 "did not find NOX Solver sublist in " << nonlinParams);
00140
00141 params_ = nonlinParams.sublist("NOX Solver");
00142
00143 params_.sublist("Printing").set("MyPID", MPIComm::world().getRank());
00144
00145 if (params_.isSublist("Status Test"))
00146 {
00147 statusTest_ = StatusTestBuilder::makeStatusTest(params_);
00148 }
00149 else
00150 {
00151 RCP<StatusTest::Generic> A = rcp(new StatusTest::NormF(1.0e-12));
00152 RCP<StatusTest::Generic> B = rcp(new StatusTest::MaxIters(20));
00153 statusTest_ =
00154 rcp(new StatusTest::SafeCombo(StatusTest::SafeCombo::OR, A, B));
00155 }
00156
00157 if (params_.isSublist("Linear Solver"))
00158 {
00159 Out::root() << tab << "WARNING: linear solver in NOX parameter list "
00160 "will be overridden by alternate solver" << std::endl;
00161 }
00162
00163 if (params_.isSublist("Printing"))
00164 {
00165 printParams_ = params_.sublist("Printing");
00166 }
00167
00168 TEUCHOS_TEST_FOR_EXCEPTION(linSolver_.ptr().get()==0, runtime_error,
00169 "null linear solver object in NOXSolver ctor");
00170
00171 TEUCHOS_TEST_FOR_EXCEPTION(statusTest_.get()==0, runtime_error,
00172 "null status test object in NOXSolver ctor");
00173
00174 }
00175
00176
00177
00178
00179 SolverState<double>
00180 NOXSolver::solve(const NonlinearOperator<double>& F,
00181 Playa::Vector<double>& solnVec) const
00182 {
00183 TimeMonitor timer(noxSolverTimer());
00184
00185 Vector<double> x0 = F.getInitialGuess();
00186 RCP<NOX::NOXPlaya::Group> grp = rcp(new NOX::NOXPlaya::Group(x0, F, linSolver_));
00187 RCP<Teuchos::ParameterList> noxParams
00188 = Teuchos::rcp(¶ms_, false);
00189 RCP<NOX::Solver::Generic> solver
00190 = NOX::Solver::buildSolver(grp, statusTest_, noxParams);
00191
00192 NOX::StatusTest::StatusType rtn = solver->solve();
00193
00194
00195 const NOX::NOXPlaya::Group* solnGrp
00196 = dynamic_cast<const NOX::NOXPlaya::Group*>(&(solver->getSolutionGroup()));
00197
00198 TEUCHOS_TEST_FOR_EXCEPTION(solnGrp==0, runtime_error,
00199 "Solution group could not be cast to NOX::NOXPlaya::Group");
00200
00201 double resid = solnGrp->getNormF();
00202 int itersUsed = solver->getNumIterations();
00203
00204
00205
00206 const NOX::NOXPlaya::Vector* x
00207 = dynamic_cast<const NOX::NOXPlaya::Vector*>(&(solnGrp->getX()));
00208
00209 TEUCHOS_TEST_FOR_EXCEPTION(x==0, runtime_error,
00210 "Solution vector could not be cast to NOX::NOXPlaya::Vector");
00211
00212 solnVec = x->getPlayaVector();
00213
00214 if (rtn==NOX::StatusTest::Converged)
00215 {
00216 return SolverState<double>(SolveConverged, "Solve converged", itersUsed, resid);
00217 }
00218 else if (rtn==NOX::StatusTest::Unconverged)
00219 {
00220 return SolverState<double>(SolveFailedToConverge, "Solve failed to converge", itersUsed, resid);
00221 }
00222 else
00223 {
00224 return SolverState<double>(SolveCrashed, "Solve crashed", itersUsed, resid);
00225 }
00226
00227 }