Thyra_LinearNonlinearSolver.hpp

00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //    Thyra: Interfaces and Support for Abstract Numerical Algorithms
00005 //                 Copyright (2004) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // ***********************************************************************
00027 // @HEADER
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 // Defintions
00102 
00103 
00104 // Overridden from Teuchos::ParameterListAcceptor
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   // ToDo: Accept some parameters if this makes sense!
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     // ToDo: Set up some parameters when needed!
00160     Teuchos::setupVerboseObjectSublist(&*pl);
00161     validPL = pl;
00162   }
00163   return validPL;
00164 }
00165 
00166 
00167 // Overridden from NonlinearSolverBase
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   // Compute the Jacobian and the residual at the input point!
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   // Solve the system: J*dx = -f
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   // Update the solution: x += dx
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   // Return default status
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 } // namespace Thyra
00297 
00298 
00299 #endif // THYRA_LINEAR_NONLINEAR_SOLVER_BASE_HPP

Generated on Tue Oct 20 12:47:16 2009 for Thyra Nonlinear Solver Support by doxygen 1.4.7