00001
00002
00003
00004 #include "Thyra_NonlinearSolver_NOX.hpp"
00005
00006 #include "NOX.H"
00007 #include "NOX_Thyra.H"
00008
00009
00010
00011 Thyra::NOXNonlinearSolver::NOXNonlinearSolver()
00012 {
00013 param_list_ = Teuchos::rcp(new Teuchos::ParameterList);
00014 valid_param_list_ = Teuchos::rcp(new Teuchos::ParameterList);
00015 }
00016
00017
00018
00019 Thyra::NOXNonlinearSolver::~NOXNonlinearSolver()
00020 {}
00021
00022
00023
00024 void Thyra::NOXNonlinearSolver::
00025 setParameterList(Teuchos::RCP<Teuchos::ParameterList> const& p)
00026 {
00027 TEST_FOR_EXCEPT(Teuchos::is_null(p));
00028 param_list_ = p;
00029 this->resetSolver();
00030 }
00031
00032
00033
00034 Teuchos::RCP<Teuchos::ParameterList>
00035 Thyra::NOXNonlinearSolver::getNonconstParameterList()
00036 {
00037 return param_list_;
00038 }
00039
00040
00041
00042 Teuchos::RCP<Teuchos::ParameterList>
00043 Thyra::NOXNonlinearSolver::unsetParameterList()
00044 {
00045 Teuchos::RCP<Teuchos::ParameterList> _paramList = param_list_;
00046 param_list_ = Teuchos::null;
00047 return _paramList;
00048 }
00049
00050
00051
00052 Teuchos::RCP<const Teuchos::ParameterList>
00053 Thyra::NOXNonlinearSolver::getParameterList() const
00054 {
00055 return param_list_;
00056 }
00057
00058
00059
00060 Teuchos::RCP<const Teuchos::ParameterList>
00061 Thyra::NOXNonlinearSolver::getValidParameters() const
00062 {
00063 return valid_param_list_;
00064 }
00065
00066
00067
00068 void Thyra::NOXNonlinearSolver::
00069 setModel(const Teuchos::RCP<const ModelEvaluator<double> >& model)
00070 {
00071 TEST_FOR_EXCEPT(model.get()==NULL);
00072 model_ = model;
00073 }
00074
00075
00076
00077 Teuchos::RCP< const Thyra::ModelEvaluator<double> >
00078 Thyra::NOXNonlinearSolver::getModel() const
00079 {
00080 return model_;
00081 }
00082
00083
00084
00085 Thyra::SolveStatus<double> Thyra::NOXNonlinearSolver::
00086 solve(VectorBase<double> *x,
00087 const SolveCriteria<double> *solveCriteria,
00088 VectorBase<double> *delta)
00089 {
00090
00091 #ifdef ENABLE_NOX_THYRA_TIMERS
00092 TEUCHOS_FUNC_TIME_MONITOR("Thyra::NOXNonlinearSolver::solve");
00093 #endif
00094
00095 TEST_FOR_EXCEPT(model_.get()==NULL);
00096 TEST_FOR_EXCEPT(param_list_.get()==NULL);
00097
00098 NOX::Thyra::Vector initial_guess(Teuchos::rcp(x, false));
00099
00100 if (Teuchos::is_null(solver_)) {
00101 nox_group_ = Teuchos::rcp(new NOX::Thyra::Group(initial_guess, model_));
00102 status_test_ = this->buildStatusTests(*param_list_);
00103 solver_ = NOX::Solver::buildSolver(nox_group_, status_test_, param_list_);
00104 }
00105 else
00106 solver_->reset(initial_guess);
00107
00108 NOX::StatusTest::StatusType solvStatus = solver_->solve();
00109
00110 Thyra::SolveStatus<double> t_status;
00111
00112 if (solvStatus == NOX::StatusTest::Converged)
00113 t_status.solveStatus = SOLVE_STATUS_CONVERGED;
00114 else if (solvStatus == NOX::StatusTest::Unconverged)
00115 t_status.solveStatus = SOLVE_STATUS_UNCONVERGED;
00116 else if (solvStatus == NOX::StatusTest::Failed)
00117 t_status.solveStatus = SOLVE_STATUS_UNCONVERGED;
00118 else
00119 t_status.solveStatus = SOLVE_STATUS_UNCONVERGED;
00120
00121
00122 const NOX::Abstract::Group& final_group = solver_->getSolutionGroup();
00123 const NOX::Abstract::Vector& final_solution = final_group.getX();
00124
00125 const NOX::Thyra::Vector& vec =
00126 dynamic_cast<const NOX::Thyra::Vector&>(final_solution);
00127
00128 const ::Thyra::VectorBase<double>& new_x =
00129 vec.getThyraVector();
00130
00131 if (delta)
00132 ::Thyra::V_StVpStV<double>(delta,1.0,new_x,-1.0,*x);
00133
00134
00135 ::Thyra::assign(x, new_x);
00136
00137 return t_status;
00138
00139 }
00140
00141
00142
00143 Teuchos::RCP<const Thyra::VectorBase<double> >
00144 Thyra::NOXNonlinearSolver::get_current_x() const
00145 {
00146 return nox_group_->get_current_x();
00147 }
00148
00149
00150
00151 bool Thyra::NOXNonlinearSolver::is_W_current() const
00152 {
00153 return nox_group_->isJacobian();
00154 }
00155
00156
00157
00158 Teuchos::RCP< Thyra::LinearOpWithSolveBase<double> >
00159 Thyra::NOXNonlinearSolver::get_nonconst_W(const bool forceUpToDate)
00160 {
00161 if (forceUpToDate && !nox_group_->isJacobian())
00162 nox_group_->computeJacobian();
00163 return nox_group_->getNonconstJacobian();
00164 }
00165
00166
00167
00168 Teuchos::RCP<const Thyra::LinearOpWithSolveBase<double> >
00169 Thyra::NOXNonlinearSolver::get_W() const
00170 {
00171 return nox_group_->getJacobian();
00172 }
00173
00174
00175
00176 Teuchos::RCP<NOX::StatusTest::Generic> Thyra::NOXNonlinearSolver::
00177 buildStatusTests(Teuchos::ParameterList& p)
00178 {
00179 Teuchos::RCP<NOX::StatusTest::Generic> status_test;
00180
00181 NOX::Utils utils(p.sublist("Printing"));
00182
00183 if (p.isSublist("Status Tests")) {
00184 status_test =
00185 NOX::StatusTest::buildStatusTests(p.sublist("Status Tests"), utils);
00186 }
00187 else {
00188 Teuchos::RCP<NOX::StatusTest::NormF> absresid =
00189 Teuchos::rcp(new NOX::StatusTest::NormF(1.0e-8));
00190 Teuchos::RCP<NOX::StatusTest::NormWRMS> wrms =
00191 Teuchos::rcp(new NOX::StatusTest::NormWRMS(1.0e-2, 1.0e-8));
00192 Teuchos::RCP<NOX::StatusTest::Combo> converged =
00193 Teuchos::rcp(new NOX::StatusTest::Combo(NOX::StatusTest::Combo::AND));
00194 converged->addStatusTest(absresid);
00195 converged->addStatusTest(wrms);
00196 Teuchos::RCP<NOX::StatusTest::MaxIters> maxiters =
00197 Teuchos::rcp(new NOX::StatusTest::MaxIters(20));
00198 Teuchos::RCP<NOX::StatusTest::FiniteValue> fv =
00199 Teuchos::rcp(new NOX::StatusTest::FiniteValue);
00200 Teuchos::RCP<NOX::StatusTest::Combo> combo =
00201 Teuchos::rcp(new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR));
00202 combo->addStatusTest(fv);
00203 combo->addStatusTest(converged);
00204 combo->addStatusTest(maxiters);
00205
00206 status_test = combo;
00207 }
00208
00209 return status_test;
00210 }
00211
00212
00213
00214 void Thyra::NOXNonlinearSolver::resetSolver()
00215 {
00216 nox_group_ = Teuchos::null;
00217 status_test_ = Teuchos::null;
00218 solver_ = Teuchos::null;
00219 }
00220
00221
00222