Go to the documentation of this file.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 #include "TSFNOXSolver.H"
00034 #include "NOX_StatusTest_SafeCombo.H"
00035 #include "NOX.H"
00036
00037 #include "TSFLinearSolverBuilder.hpp"
00038 #include "Teuchos_Time.hpp"
00039 #include "Teuchos_TimeMonitor.hpp"
00040 #include "SundanceOut.hpp"
00041 #include "SundanceTabs.hpp"
00042 #include "SundanceExceptions.hpp"
00043 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00044 #include "TSFVectorImpl.hpp"
00045 #include "TSFLinearOperatorImpl.hpp"
00046 #endif
00047
00048
00049 using namespace NOX;
00050 using namespace NOX::TSF;
00051 using namespace Teuchos;
00052 using namespace TSFExtended;
00053
00054
00055 static Time& noxSolverTimer()
00056 {
00057 static RCP<Time> rtn
00058 = TimeMonitor::getNewTimer("NOX solve");
00059 return *rtn;
00060 }
00061
00062 NOXSolver::NOXSolver(const ParameterList& params)
00063 : linSolver_(),
00064 statusTest_(),
00065 params_(),
00066 printParams_()
00067 {
00068 TEST_FOR_EXCEPTION(!params.isSublist("NOX Solver"), runtime_error,
00069 "did not find NOX Solver sublist in " << params);
00070
00071 params_ = params.sublist("NOX Solver");
00072
00073 params_.sublist("Printing").set("MyPID", MPIComm::world().getRank());
00074
00075 if (params_.isSublist("Status Test"))
00076 {
00077 statusTest_ = StatusTestBuilder::makeStatusTest(params_);
00078 }
00079 else
00080 {
00081 RCP<StatusTest::Generic> A = rcp(new StatusTest::NormF(1.0e-12));
00082 RCP<StatusTest::Generic> B = rcp(new StatusTest::MaxIters(20));
00083 statusTest_ =
00084 rcp(new StatusTest::SafeCombo(StatusTest::SafeCombo::OR, A, B));
00085 }
00086
00087 if (params_.isSublist("Linear Solver"))
00088 {
00089 linSolver_ = LinearSolverBuilder::createSolver(params_);
00090 }
00091 else
00092 {
00093 TEST_FOR_EXCEPTION(!params_.isSublist("Linear Solver"),
00094 RuntimeError, "no linear solver specified in NOX parameters");
00095 }
00096
00097 if (params_.isSublist("Printing"))
00098 {
00099 printParams_ = params_.sublist("Printing");
00100 }
00101
00102 TEST_FOR_EXCEPTION(linSolver_.ptr().get()==0, runtime_error,
00103 "null linear solver object in NOXSolver ctor");
00104
00105 TEST_FOR_EXCEPTION(statusTest_.get()==0, runtime_error,
00106 "null status test object in NOXSolver ctor");
00107
00108 }
00109
00110 NOXSolver::NOXSolver(const ParameterList& nonlinParams,
00111 const LinearSolver<double>& linSolver)
00112 : linSolver_(linSolver),
00113 statusTest_(),
00114 params_(),
00115 printParams_()
00116 {
00117 Tabs tab(0);
00118 TEST_FOR_EXCEPTION(!nonlinParams.isSublist("NOX Solver"), runtime_error,
00119 "did not find NOX Solver sublist in " << nonlinParams);
00120
00121 params_ = nonlinParams.sublist("NOX Solver");
00122
00123 params_.sublist("Printing").set("MyPID", MPIComm::world().getRank());
00124
00125 if (params_.isSublist("Status Test"))
00126 {
00127 statusTest_ = StatusTestBuilder::makeStatusTest(params_);
00128 }
00129 else
00130 {
00131 RCP<StatusTest::Generic> A = rcp(new StatusTest::NormF(1.0e-12));
00132 RCP<StatusTest::Generic> B = rcp(new StatusTest::MaxIters(20));
00133 statusTest_ =
00134 rcp(new StatusTest::SafeCombo(StatusTest::SafeCombo::OR, A, B));
00135 }
00136
00137 if (params_.isSublist("Linear Solver"))
00138 {
00139 Out::root() << tab << "WARNING: linear solver in NOX parameter list "
00140 "will be overridden by alternate solver" << std::endl;
00141 }
00142
00143 if (params_.isSublist("Printing"))
00144 {
00145 printParams_ = params_.sublist("Printing");
00146 }
00147
00148 TEST_FOR_EXCEPTION(linSolver_.ptr().get()==0, runtime_error,
00149 "null linear solver object in NOXSolver ctor");
00150
00151 TEST_FOR_EXCEPTION(statusTest_.get()==0, runtime_error,
00152 "null status test object in NOXSolver ctor");
00153
00154 }
00155
00156
00157
00158
00159 NOX::StatusTest::StatusType
00160 NOXSolver::solve(const NonlinearOperator<double>& F,
00161 TSFExtended::Vector<double>& solnVec) const
00162 {
00163 TimeMonitor timer(noxSolverTimer());
00164
00165 Vector<double> x0 = F.getInitialGuess();
00166 RCP<NOX::TSF::Group> grp = rcp(new NOX::TSF::Group(x0, F, linSolver_));
00167 RCP<Teuchos::ParameterList> noxParams
00168 = Teuchos::rcp(¶ms_, false);
00169 RCP<NOX::Solver::Generic> solver
00170 = NOX::Solver::buildSolver(grp, statusTest_, noxParams);
00171
00172 NOX::StatusTest::StatusType rtn = solver->solve();
00173
00174 const NOX::TSF::Group* solnGrp
00175 = dynamic_cast<const NOX::TSF::Group*>(&(solver->getSolutionGroup()));
00176
00177 TEST_FOR_EXCEPTION(solnGrp==0, runtime_error,
00178 "Solution group could not be cast to NOX::TSF::Group");
00179
00180 const NOX::TSF::Vector* x
00181 = dynamic_cast<const NOX::TSF::Vector*>(&(solnGrp->getX()));
00182
00183 TEST_FOR_EXCEPTION(x==0, runtime_error,
00184 "Solution vector could not be cast to NOX::TSF::Vector");
00185
00186 solnVec = x->getTSFVector();
00187
00188 return rtn;
00189 }