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 #ifndef THYRA_LINEAR_NONLINEAR_SOLVER_BASE_HPP
00030 #define THYRA_LINEAR_NONLINEAR_SOLVER_BASE_HPP
00031
00032
00033 #include "Thyra_NonlinearSolverBase.hpp"
00034 #include "Thyra_ModelEvaluatorHelpers.hpp"
00035 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
00036 #include "Teuchos_StandardParameterEntryValidators.hpp"
00037 #include "Teuchos_as.hpp"
00038
00039
00040 namespace Thyra {
00041
00042
00049 template <class Scalar>
00050 class LinearNonlinearSolver : public NonlinearSolverBase<Scalar> {
00051 public:
00052
00055
00057 void setParameterList(RCP<Teuchos::ParameterList> const& paramList);
00059 RCP<Teuchos::ParameterList> getParameterList();
00061 RCP<Teuchos::ParameterList> unsetParameterList();
00063 RCP<const Teuchos::ParameterList> getParameterList() const;
00065 RCP<const Teuchos::ParameterList> getValidParameters() const;
00066
00068
00071
00073 void setModel(
00074 const RCP<const ModelEvaluator<Scalar> > &model
00075 );
00077 RCP<const ModelEvaluator<Scalar> > getModel() const;
00079 SolveStatus<Scalar> solve(
00080 VectorBase<Scalar> *x,
00081 const SolveCriteria<Scalar> *solveCriteria,
00082 VectorBase<Scalar> *delta
00083 );
00085 RCP<LinearOpWithSolveBase<Scalar> > get_nonconst_W(const bool forceUpToDate);
00087 RCP<const LinearOpWithSolveBase<Scalar> > get_W() const;
00088
00090
00091 private:
00092
00093 RCP<Teuchos::ParameterList> paramList_;
00094 RCP<const ModelEvaluator<Scalar> > model_;
00095 RCP<LinearOpWithSolveBase<Scalar> > J_;
00096
00097 };
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 template<class Scalar>
00108 void LinearNonlinearSolver<Scalar>::setParameterList(
00109 RCP<Teuchos::ParameterList> const& paramList
00110 )
00111 {
00112 using Teuchos::get;
00113 TEST_FOR_EXCEPT(is_null(paramList));
00114 paramList->validateParametersAndSetDefaults(*getValidParameters(),0);
00115 paramList_ = paramList;
00116
00117 Teuchos::readVerboseObjectSublist(&*paramList_,this);
00118 #ifdef TEUCHOS_DEBUG
00119 paramList_->validateParameters(*getValidParameters(),0);
00120 #endif // TEUCHOS_DEBUG
00121 }
00122
00123
00124 template<class Scalar>
00125 RCP<Teuchos::ParameterList>
00126 LinearNonlinearSolver<Scalar>::getParameterList()
00127 {
00128 return paramList_;
00129 }
00130
00131
00132 template<class Scalar>
00133 RCP<Teuchos::ParameterList>
00134 LinearNonlinearSolver<Scalar>::unsetParameterList()
00135 {
00136 RCP<Teuchos::ParameterList> _paramList = paramList_;
00137 paramList_ = Teuchos::null;
00138 return _paramList;
00139 }
00140
00141
00142 template<class Scalar>
00143 RCP<const Teuchos::ParameterList>
00144 LinearNonlinearSolver<Scalar>::getParameterList() const
00145 {
00146 return paramList_;
00147 }
00148
00149
00150 template<class Scalar>
00151 RCP<const Teuchos::ParameterList>
00152 LinearNonlinearSolver<Scalar>::getValidParameters() const
00153 {
00154 using Teuchos::setDoubleParameter; using Teuchos::setIntParameter;
00155 static RCP<const Teuchos::ParameterList> validPL;
00156 if (is_null(validPL)) {
00157 RCP<Teuchos::ParameterList>
00158 pl = Teuchos::parameterList();
00159
00160 Teuchos::setupVerboseObjectSublist(&*pl);
00161 validPL = pl;
00162 }
00163 return validPL;
00164 }
00165
00166
00167
00168
00169
00170 template <class Scalar>
00171 void LinearNonlinearSolver<Scalar>::setModel(
00172 const RCP<const ModelEvaluator<Scalar> > &model
00173 )
00174 {
00175 TEST_FOR_EXCEPT(model.get()==NULL);
00176 model_ = model;
00177 J_ = Teuchos::null;
00178 }
00179
00180
00181 template <class Scalar>
00182 RCP<const ModelEvaluator<Scalar> >
00183 LinearNonlinearSolver<Scalar>::getModel() const
00184 {
00185 return model_;
00186 }
00187
00188
00189 template <class Scalar>
00190 SolveStatus<Scalar> LinearNonlinearSolver<Scalar>::solve(
00191 VectorBase<Scalar> *x,
00192 const SolveCriteria<Scalar> *solveCriteria,
00193 VectorBase<Scalar> *delta
00194 )
00195 {
00196
00197 using std::endl;
00198 using Teuchos::incrVerbLevel;
00199 using Teuchos::describe;
00200 using Teuchos::as;
00201 using Teuchos::rcp;
00202 using Teuchos::OSTab;
00203 using Teuchos::getFancyOStream;
00204 typedef Teuchos::ScalarTraits<Scalar> ST;
00205 typedef Thyra::ModelEvaluatorBase MEB;
00206 typedef Teuchos::VerboseObjectTempState<MEB> VOTSME;
00207 typedef Thyra::LinearOpWithSolveBase<Scalar> LOWSB;
00208 typedef Teuchos::VerboseObjectTempState<LOWSB> VOTSLOWSB;
00209
00210 #ifdef TEUCHOS_DEBUG
00211 TEST_FOR_EXCEPT(0==x);
00212 THYRA_ASSERT_VEC_SPACES(
00213 "TimeStepNonlinearSolver<Scalar>::solve(...)",
00214 *x->space(),*model_->get_x_space() );
00215 TEST_FOR_EXCEPT(
00216 0!=solveCriteria && "ToDo: Support passed in solve criteria!" );
00217 #endif
00218
00219 const RCP<Teuchos::FancyOStream> out = this->getOStream();
00220 const Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
00221 const bool showTrace = (as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW));
00222 const bool dumpAll = (as<int>(verbLevel) == as<int>(Teuchos::VERB_EXTREME));
00223 TEUCHOS_OSTAB;
00224 VOTSME stateModel_outputTempState(model_,out,incrVerbLevel(verbLevel,-1));
00225 if(out.get() && showTrace)
00226 *out
00227 << "\nEntering LinearNonlinearSolver::solve(...) ...\n"
00228 << "\nmodel = " << describe(*model_,verbLevel);
00229
00230 if(out.get() && dumpAll) {
00231 *out << "\nInitial guess:\n";
00232 *out << "\nx = " << *x;
00233 }
00234
00235
00236 if(!J_.get()) J_ = model_->create_W();
00237 RCP<VectorBase<Scalar> >
00238 f = createMember(model_->get_f_space());
00239 if(out.get() && showTrace)
00240 *out << "\nEvaluating the model f and W ...\n";
00241 eval_f_W( *model_, *x, &*f, &*J_ );
00242
00243
00244 RCP<VectorBase<Scalar> >
00245 dx = createMember(model_->get_x_space());
00246 if(out.get() && showTrace)
00247 *out << "\nSolving the system J*dx = -f ...\n";
00248 VOTSLOWSB J_outputTempState(J_,out,incrVerbLevel(verbLevel,-1));
00249 assign( &*dx, ST::zero() );
00250 Thyra::SolveStatus<Scalar>
00251 linearSolveStatus = Thyra::solve( *J_, NOTRANS, *f, &*dx );
00252 if(out.get() && showTrace)
00253 *out << "\nLinear solve status:\n" << linearSolveStatus;
00254 Vt_S( &*dx, Scalar(-ST::one()) );
00255 if(out.get() && dumpAll)
00256 *out << "\ndx = " << Teuchos::describe(*dx,verbLevel);
00257 if (delta != NULL) {
00258 Thyra::assign( delta, *dx );
00259 if(out.get() && dumpAll)
00260 *out << "\ndelta = " << Teuchos::describe(*delta,verbLevel);
00261 }
00262
00263
00264 Vp_V( x, *dx );
00265 if(out.get() && dumpAll)
00266 *out << "\nUpdated solution x = " << Teuchos::describe(*x,verbLevel);
00267
00268 if(out.get() && showTrace)
00269 *out << "\nLeaving LinearNonlinearSolver::solve(...) ...\n";
00270
00271
00272 return SolveStatus<Scalar>();
00273
00274 }
00275
00276
00277 template <class Scalar>
00278 RCP<LinearOpWithSolveBase<Scalar> >
00279 LinearNonlinearSolver<Scalar>::get_nonconst_W(const bool forceUpToDate)
00280 {
00281 if (forceUpToDate) {
00282 TEST_FOR_EXCEPT(forceUpToDate);
00283 }
00284 return J_;
00285 }
00286
00287
00288 template <class Scalar>
00289 RCP<const LinearOpWithSolveBase<Scalar> >
00290 LinearNonlinearSolver<Scalar>::get_W() const
00291 {
00292 return J_;
00293 }
00294
00295
00296 }
00297
00298
00299 #endif // THYRA_LINEAR_NONLINEAR_SOLVER_BASE_HPP