Rythmos_TimeStepNonlinearSolver.hpp

00001 //@HEADER
00002 // ***********************************************************************
00003 //
00004 //                           Rythmos Package
00005 //                 Copyright (2006) 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 Todd S. Coffey (tscoffe@sandia.gov)
00025 //
00026 // ***********************************************************************
00027 //@HEADER
00028 
00029 
00030 #ifndef RYTHMOS_TIME_STEP_NONLINEAR_SOLVER_HPP
00031 #define RYTHMOS_TIME_STEP_NONLINEAR_SOLVER_HPP
00032 
00033 
00034 #include "Thyra_NonlinearSolverBase.hpp"
00035 #include "Thyra_TestingTools.hpp"
00036 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
00037 #include "Teuchos_StandardParameterEntryValidators.hpp"
00038 #include "Teuchos_as.hpp"
00039 
00040 
00041 namespace Rythmos {
00042 
00043 
00054 template <class Scalar>
00055 class TimeStepNonlinearSolver : public Thyra::NonlinearSolverBase<Scalar> {
00056 public:
00057 
00059   typedef Teuchos::ScalarTraits<Scalar> ST;
00061   typedef typename ST::magnitudeType ScalarMag;
00063   typedef Teuchos::ScalarTraits<ScalarMag> SMT;
00064 
00067 
00069   TimeStepNonlinearSolver();
00070 
00072 
00075 
00077   void setParameterList(RCP<ParameterList> const& paramList);
00079   RCP<ParameterList> getParameterList();
00081   RCP<ParameterList> unsetParameterList();
00083   RCP<const ParameterList> getParameterList() const;
00085   RCP<const ParameterList> getValidParameters() const;
00086 
00088 
00091 
00093   void setModel(
00094     const RCP<const Thyra::ModelEvaluator<Scalar> > &model
00095     );
00097   RCP<const Thyra::ModelEvaluator<Scalar> > getModel() const;
00099   Thyra::SolveStatus<Scalar> solve(
00100     Thyra::VectorBase<Scalar> *x,
00101     const Thyra::SolveCriteria<Scalar> *solveCriteria,
00102     Thyra::VectorBase<Scalar> *delta = NULL
00103     );
00105   bool supportsCloning() const;
00107   RCP<Thyra::NonlinearSolverBase<Scalar> >
00108   cloneNonlinearSolver() const;  
00110   RCP<const Thyra::VectorBase<Scalar> > get_current_x() const;
00112   bool is_W_current() const;
00114   RCP<Thyra::LinearOpWithSolveBase<Scalar> >
00115   get_nonconst_W(const bool forceUpToDate);
00117   RCP<const Thyra::LinearOpWithSolveBase<Scalar> > get_W() const;
00119   void set_W_is_current(bool W_is_current);
00120 
00122 
00123 private:
00124 
00125   // private object data members
00126 
00127   RCP<ParameterList> paramList_;
00128   RCP<const Thyra::ModelEvaluator<Scalar> > model_;
00129   RCP<Thyra::LinearOpWithSolveBase<Scalar> > J_;
00130   RCP<Thyra::VectorBase<Scalar> > current_x_;
00131   bool J_is_current_;
00132 
00133   double defaultTol_;
00134   int defaultMaxIters_;
00135   double nonlinearSafetyFactor_;
00136   double linearSafetyFactor_;
00137   double RMinFraction_;
00138   bool throwOnLinearSolveFailure_;
00139 
00140   // static class data members
00141 
00142   static const std::string DefaultTol_name_;
00143   static const double DefaultTol_default_;
00144 
00145   static const std::string DefaultMaxIters_name_;
00146   static const int DefaultMaxIters_default_;
00147 
00148   static const std::string NonlinearSafetyFactor_name_;
00149   static const double NonlinearSafetyFactor_default_;
00150 
00151   static const std::string LinearSafetyFactor_name_;
00152   static const double LinearSafetyFactor_default_;
00153 
00154   static const std::string RMinFraction_name_;
00155   static const double RMinFraction_default_;
00156 
00157   static const std::string ThrownOnLinearSolveFailure_name_;
00158   static const bool ThrownOnLinearSolveFailure_default_;
00159 
00160 };
00161 
00162 
00163 // ////////////////////////
00164 // Defintions
00165 
00166 
00167 // Static members
00168 
00169 
00170 template<class Scalar>
00171 const std::string
00172 TimeStepNonlinearSolver<Scalar>::DefaultTol_name_ = "Default Tol";
00173 
00174 template<class Scalar>
00175 const double
00176 TimeStepNonlinearSolver<Scalar>::DefaultTol_default_ = 1e-2;
00177 
00178 
00179 template<class Scalar>
00180 const std::string
00181 TimeStepNonlinearSolver<Scalar>::DefaultMaxIters_name_ = "Default Max Iters";
00182 
00183 template<class Scalar>
00184 const int
00185 TimeStepNonlinearSolver<Scalar>::DefaultMaxIters_default_ = 3;
00186 
00187 
00188 template<class Scalar>
00189 const std::string
00190 TimeStepNonlinearSolver<Scalar>::NonlinearSafetyFactor_name_
00191 = "Nonlinear Safety Factor";
00192 
00193 template<class Scalar>
00194 const double
00195 TimeStepNonlinearSolver<Scalar>::NonlinearSafetyFactor_default_ = 0.1;
00196 
00197 
00198 template<class Scalar>
00199 const std::string
00200 TimeStepNonlinearSolver<Scalar>::LinearSafetyFactor_name_ = "Linear Safety Factor";
00201 
00202 template<class Scalar>
00203 const double
00204 TimeStepNonlinearSolver<Scalar>::LinearSafetyFactor_default_ = 0.05;
00205 
00206 
00207 template<class Scalar>
00208 const std::string
00209 TimeStepNonlinearSolver<Scalar>::RMinFraction_name_ = "R Min Fraction";
00210 
00211 template<class Scalar>
00212 const double
00213 TimeStepNonlinearSolver<Scalar>::RMinFraction_default_ = 0.3;
00214 
00215 
00216 template<class Scalar>
00217 const std::string
00218 TimeStepNonlinearSolver<Scalar>::ThrownOnLinearSolveFailure_name_
00219 = "Thrown on Linear Solve Failure";
00220 
00221 template<class Scalar>
00222 const bool
00223 TimeStepNonlinearSolver<Scalar>::ThrownOnLinearSolveFailure_default_ = false;
00224 
00225 
00226 // Constructors/Intializers/Misc
00227 
00228 
00229 template <class Scalar>
00230 TimeStepNonlinearSolver<Scalar>::TimeStepNonlinearSolver()
00231   :J_is_current_(false),
00232    defaultTol_(DefaultTol_default_),
00233    defaultMaxIters_(DefaultMaxIters_default_),
00234    nonlinearSafetyFactor_(NonlinearSafetyFactor_default_),
00235    linearSafetyFactor_(LinearSafetyFactor_default_),
00236    RMinFraction_(RMinFraction_default_),
00237    throwOnLinearSolveFailure_(ThrownOnLinearSolveFailure_default_)
00238 {}
00239 
00240 
00241 // Overridden from ParameterListAcceptor
00242 
00243 
00244 template<class Scalar>
00245 void TimeStepNonlinearSolver<Scalar>::setParameterList(
00246   RCP<ParameterList> const& paramList
00247   )
00248 {
00249   using Teuchos::get;
00250   TEST_FOR_EXCEPT(is_null(paramList));
00251   paramList->validateParametersAndSetDefaults(*getValidParameters(),0);
00252   paramList_ = paramList;
00253   defaultTol_ = get<double>(*paramList_,DefaultTol_name_);
00254   defaultMaxIters_ = get<int>(*paramList_,DefaultMaxIters_name_);
00255   nonlinearSafetyFactor_ = get<double>(*paramList_,NonlinearSafetyFactor_name_);
00256   linearSafetyFactor_ = get<double>(*paramList_,LinearSafetyFactor_name_);
00257   RMinFraction_ = get<double>(*paramList_,RMinFraction_name_);
00258   throwOnLinearSolveFailure_ = get<bool>(
00259     *paramList_,ThrownOnLinearSolveFailure_name_);
00260   Teuchos::readVerboseObjectSublist(&*paramList_,this);
00261 #ifdef TEUCHOS_DEBUG
00262   paramList_->validateParameters(*getValidParameters(),0);
00263 #endif // TEUCHOS_DEBUG
00264 }
00265 
00266 
00267 template<class Scalar>
00268 RCP<ParameterList>
00269 TimeStepNonlinearSolver<Scalar>::getParameterList()
00270 {
00271   return paramList_;
00272 }
00273 
00274 
00275 template<class Scalar>
00276 RCP<ParameterList>
00277 TimeStepNonlinearSolver<Scalar>::unsetParameterList()
00278 {
00279   RCP<ParameterList> _paramList = paramList_;
00280   paramList_ = Teuchos::null;
00281   return _paramList;
00282 }
00283 
00284 
00285 template<class Scalar>
00286 RCP<const ParameterList>
00287 TimeStepNonlinearSolver<Scalar>::getParameterList() const
00288 {
00289   return paramList_;
00290 }
00291 
00292 
00293 template<class Scalar>
00294 RCP<const ParameterList>
00295 TimeStepNonlinearSolver<Scalar>::getValidParameters() const
00296 {
00297   using Teuchos::setDoubleParameter; using Teuchos::setIntParameter;
00298   static RCP<const ParameterList> validPL;
00299   if (is_null(validPL)) {
00300     RCP<ParameterList> pl = Teuchos::parameterList();
00301     setDoubleParameter(
00302       DefaultTol_name_, DefaultTol_default_,
00303       "The default base tolerance for the nonlinear timestep solve.\n"
00304       "This tolerance can be overridden ???",
00305       &*pl );
00306     setIntParameter(
00307       DefaultMaxIters_name_, DefaultMaxIters_default_,
00308       "The default maximum number of Newton iterations to perform.\n"
00309       "This default can be overridden ???",
00310       &*pl );
00311     setDoubleParameter(
00312       NonlinearSafetyFactor_name_, NonlinearSafetyFactor_default_,
00313       "The factor (< 1.0) to multiply tol to bound R*||dx|||.\n"
00314       "The exact nonlinear convergence test is:\n"
00315       "  R*||dx|| <= \"" + NonlinearSafetyFactor_name_ + "\" * tol.",
00316       &*pl );
00317     setDoubleParameter(
00318       LinearSafetyFactor_name_, LinearSafetyFactor_default_,
00319       "This factor multiplies the nonlinear safety factor which multiplies\n"
00320       "tol when determining the linear solve tolerence.\n"
00321       "The exact linear convergence tolerance is:\n"
00322       "  ||J*dx+f||/||f|| <= \"" + LinearSafetyFactor_name_ + "\" * "
00323       "\"" + NonlinearSafetyFactor_name_ + "\" * tol.",
00324       &*pl );
00325     setDoubleParameter(
00326       RMinFraction_name_, RMinFraction_default_,
00327       "The faction below which the R factor is not allowed to drop\n"
00328       "below each Newton iteration.  The R factor is related to the\n"
00329       "ratio of ||dx||/||dx_last|| between nonlinear iterations.",
00330       &*pl );
00331     pl->set(
00332       ThrownOnLinearSolveFailure_name_, ThrownOnLinearSolveFailure_default_,
00333       "If set to true (\"1\"), then an Thyra::CatastrophicSolveFailure\n"
00334       "exception will be thrown when a linear solve fails to meet it's tolerance."
00335       );
00336     Teuchos::setupVerboseObjectSublist(&*pl);
00337     validPL = pl;
00338   }
00339   return validPL;
00340 }
00341 
00342 
00343 // Overridden from NonlinearSolverBase
00344 
00345 
00346 template <class Scalar>
00347 void TimeStepNonlinearSolver<Scalar>::setModel(
00348   const RCP<const Thyra::ModelEvaluator<Scalar> > &model
00349   )
00350 {
00351   TEST_FOR_EXCEPT(model.get()==NULL);
00352   model_ = model;
00353   J_ = Teuchos::null;
00354   current_x_ = Teuchos::null;
00355   J_is_current_ = false;
00356 }
00357 
00358 
00359 template <class Scalar>
00360 RCP<const Thyra::ModelEvaluator<Scalar> >
00361 TimeStepNonlinearSolver<Scalar>::getModel() const
00362 {
00363   return model_;
00364 }
00365 
00366 template <class Scalar>
00367 Thyra::SolveStatus<Scalar>
00368 TimeStepNonlinearSolver<Scalar>::solve(
00369   Thyra::VectorBase<Scalar> *x,
00370   const Thyra::SolveCriteria<Scalar> *solveCriteria,
00371   Thyra::VectorBase<Scalar> *delta
00372   )
00373 {
00374   
00375 #ifdef ENABLE_RYTHMOS_TIMERS
00376   TEUCHOS_FUNC_TIME_MONITOR("Rythmos:TimeStepNonlinearSolver::solve");
00377 #endif
00378 
00379   using std::endl;
00380   using Teuchos::incrVerbLevel;
00381   using Teuchos::describe;
00382   using Teuchos::as;
00383   using Teuchos::rcp;
00384   using Teuchos::OSTab;
00385   using Teuchos::getFancyOStream;
00386   typedef Thyra::ModelEvaluatorBase MEB;
00387   typedef Teuchos::VerboseObjectTempState<MEB> VOTSME;
00388   typedef Thyra::LinearOpWithSolveBase<Scalar> LOWSB;
00389   typedef Teuchos::VerboseObjectTempState<LOWSB> VOTSLOWSB;
00390 
00391 #ifdef TEUCHOS_DEBUG
00392   TEST_FOR_EXCEPT(0==x);
00393   THYRA_ASSERT_VEC_SPACES(
00394     "TimeStepNonlinearSolver<Scalar>::solve(...)",
00395     *x->space(),*model_->get_x_space() );
00396   TEST_FOR_EXCEPT(
00397     0!=solveCriteria && "ToDo: Support passed in solve criteria!" );
00398 #endif
00399 
00400   const RCP<Teuchos::FancyOStream> out = this->getOStream();
00401   const Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
00402   const bool showNewtonDetails =
00403     (!is_null(out) && (as<int>(verbLevel) >= as<int>(Teuchos::VERB_MEDIUM)));
00404   const bool dumpAll =
00405     (!is_null(out) && (as<int>(verbLevel) == as<int>(Teuchos::VERB_EXTREME))); 
00406   TEUCHOS_OSTAB;
00407   VOTSME stateModel_outputTempState(model_,out,incrVerbLevel(verbLevel,-1));
00408 
00409   if (showNewtonDetails)
00410     *out
00411       << "\nEntering TimeStepNonlinearSolver::solve(...) ...\n"
00412       << "\nmodel = " << Teuchos::describe(*model_,verbLevel);
00413 
00414   if(dumpAll) {
00415     *out << "\nInitial guess:\n";
00416     *out << "\nx = " << *x;
00417   }
00418 
00419   // Initialize storage for algorithm
00420   if(!J_.get()) J_ = model_->create_W();
00421   RCP<Thyra::VectorBase<Scalar> > f = createMember(model_->get_f_space());
00422   RCP<Thyra::VectorBase<Scalar> > dx = createMember(model_->get_x_space());
00423   RCP<Thyra::VectorBase<Scalar> > dx_last = createMember(model_->get_x_space());
00424   RCP<Thyra::VectorBase<Scalar> > x_curr = createMember(model_->get_x_space());
00425   if (delta != NULL)
00426     Thyra::V_S(delta,ST::zero()); // delta stores the cumulative update to x over the whole Newton solve.
00427   Thyra::assign(&*x_curr,*x);
00428   J_is_current_ = false;
00429   current_x_ = Teuchos::null;
00430 
00431   // Initialize convergence criteria
00432   ScalarMag R = SMT::one();
00433   ScalarMag linearTolSafety = linearSafetyFactor_ * nonlinearSafetyFactor_;
00434   int maxIters = defaultMaxIters_;
00435   ScalarMag tol = defaultTol_;
00436   // ToDo: Get above from solveCriteria!
00437 
00438   // Do the undampened Newton iterations
00439   bool converged = false;
00440   bool sawFailedLinearSolve = false;
00441   Thyra::SolveStatus<Scalar> failedLinearSolveStatus;
00442   ScalarMag nrm_dx;
00443   ScalarMag nrm_dx_last;
00444   int iter = 1;
00445   for( ; iter <= maxIters; ++iter ) {
00446     if (showNewtonDetails)
00447       *out << "\n*** newtonIter = " << iter << endl;
00448     if (showNewtonDetails)
00449       *out << "\nEvaluating the model f and W ...\n";
00450     eval_f_W( *model_, *x_curr, &*f, &*J_ );
00451     if (showNewtonDetails)
00452       *out << "\nSolving the system J*dx = -f ...\n";
00453     Thyra::V_S(&*dx,ST::zero()); // Initial guess is needed!
00454     Thyra::SolveCriteria<Scalar>
00455       linearSolveCriteria(
00456         Thyra::SolveMeasureType(
00457           Thyra::SOLVE_MEASURE_NORM_RESIDUAL, Thyra::SOLVE_MEASURE_NORM_RHS
00458           ),
00459         linearTolSafety*tol
00460         );
00461     VOTSLOWSB J_outputTempState(J_,out,incrVerbLevel(verbLevel,-1));
00462     Thyra::SolveStatus<Scalar> linearSolveStatus
00463       = Thyra::solve( *J_, Thyra::NOTRANS, *f, &*dx, &linearSolveCriteria );
00464     if (showNewtonDetails)
00465       *out << "\nLinear solve status:\n" << linearSolveStatus;
00466     Thyra::Vt_S(&*dx,Scalar(-ST::one()));
00467     if (dumpAll)
00468       *out << "\ndx = " << Teuchos::describe(*dx,verbLevel);
00469     if (delta != NULL) {
00470       Thyra::Vp_V(delta,*dx);
00471       if (dumpAll)
00472         *out << "\ndelta = " << Teuchos::describe(*delta,verbLevel);
00473     }
00474     // Check the linear solve
00475     if(linearSolveStatus.solveStatus != Thyra::SOLVE_STATUS_CONVERGED) {
00476       sawFailedLinearSolve = true;
00477       failedLinearSolveStatus = linearSolveStatus;
00478       if (throwOnLinearSolveFailure_) {
00479         TEST_FOR_EXCEPTION(
00480           throwOnLinearSolveFailure_, Thyra::CatastrophicSolveFailure,
00481           "Error, the linear solver did not converge!"
00482           );
00483       }
00484       if (showNewtonDetails)
00485         *out << "\nWarning, linear solve did not converge!  Continuing anyway :-)\n";
00486     }
00487     // Update the solution: x_curr = x_curr + dx
00488     Vp_V( &*x_curr, *dx );
00489     if (dumpAll)
00490       *out << "\nUpdated solution x = " << Teuchos::describe(*x_curr,verbLevel);
00491     // Convergence test
00492     nrm_dx = Thyra::norm(*dx);
00493     if ( R*nrm_dx <= nonlinearSafetyFactor_*tol )
00494       converged = true;
00495     if (showNewtonDetails)
00496       *out
00497         << "\nConvergence test:\n"
00498         << "  R*||dx|| = " << R << "*" << nrm_dx
00499         << " = " << (R*nrm_dx) << "\n"
00500         << "    <= nonlinearSafetyFactor*tol = " << nonlinearSafetyFactor_ << "*" << tol
00501         << " = " << (nonlinearSafetyFactor_*tol)
00502         << " : " << ( converged ? "converged!" : " unconverged" )
00503         << endl;
00504     if(converged)
00505       break; // We have converged!!!
00506     // Update convergence criteria for the next iteration ...
00507     if(iter > 1) {
00508       const Scalar
00509         MinR = RMinFraction_*R,
00510         nrm_dx_ratio = nrm_dx/nrm_dx_last;
00511       R = std::max(MinR,nrm_dx_ratio);
00512       if (showNewtonDetails)
00513       *out
00514         << "\nUpdated R\n"
00515         << "  = max(RMinFraction*R,||dx||/||dx_last||)\n"
00516         << "  = max("<<RMinFraction_<<"*"<<R<<","<<nrm_dx<<"/"<<nrm_dx_last<<")\n"
00517         << "  = max("<<MinR<<","<<nrm_dx_ratio<<")\n"
00518         << "  = " << R << endl;
00519     }
00520     // Save to old
00521     std::swap(dx_last,dx);
00522     nrm_dx_last = nrm_dx;
00523   }
00524 
00525   // Set the solution
00526   Thyra::assign(x,*x_curr);
00527   
00528   if (dumpAll)
00529     *out << "\nFinal solution x = " << Teuchos::describe(*x,verbLevel);
00530 
00531   // Check the status
00532 
00533   Thyra::SolveStatus<Scalar> solveStatus;
00534 
00535   std::ostringstream oss;
00536   Teuchos::FancyOStream omsg(rcp(&oss,false));
00537 
00538   omsg << "Solver: " << this->description() << endl;
00539 
00540   if(converged) {
00541     solveStatus.solveStatus = Thyra::SOLVE_STATUS_CONVERGED;
00542     omsg << "CVODE status test converged!\n";
00543   }
00544   else {
00545     solveStatus.solveStatus = Thyra::SOLVE_STATUS_UNCONVERGED;
00546     omsg << "CVODE status test failed!\n";
00547   }
00548 
00549   if (sawFailedLinearSolve) {
00550     omsg << "Warning!  A failed linear solve was encountered with status:\n";
00551     OSTab tab(omsg);
00552     omsg << failedLinearSolveStatus;
00553   }
00554 
00555   omsg
00556     << "R*||dx|| = " << R << "*" << nrm_dx
00557     << " <= nonlinearSafetyFactor*tol = " << nonlinearSafetyFactor_ << "*" << tol << " : "
00558     << ( converged ? "converged!" : " unconverged" ) << endl;
00559 
00560   omsg
00561     << "Iterations = " << iter;
00562   // Above, we leave off the last newline since this is the convention for the
00563   // SolveStatus::message string!
00564 
00565   solveStatus.message = oss.str();
00566 
00567   // Update the solution state for external clients
00568   current_x_ = x->clone_v();
00569   J_is_current_ = false;
00570   // 2007/09/04: rabartl: Note, above the Jacobian J is always going to be out
00571   // of date since this algorithm computes x_curr = x_curr + dx for at least
00572   // one solve for dx = -inv(J)*f.  Therefore, J is never at the updated
00573   // x_curr, only the old x_curr!
00574 
00575   if (showNewtonDetails)
00576     *out << "\nLeaving TimeStepNonlinearSolver::solve(...) ...\n";
00577 
00578   return solveStatus;
00579 
00580 }
00581 
00582 
00583 template <class Scalar>
00584 bool TimeStepNonlinearSolver<Scalar>::supportsCloning() const
00585 {
00586   return true;
00587 }
00588 
00589 
00590 template <class Scalar>
00591 RCP<Thyra::NonlinearSolverBase<Scalar> >
00592 TimeStepNonlinearSolver<Scalar>::cloneNonlinearSolver() const
00593 {
00594   RCP<TimeStepNonlinearSolver<Scalar> >
00595     nonlinearSolver = Teuchos::rcp(new TimeStepNonlinearSolver<Scalar>);
00596   nonlinearSolver->model_ = model_; // Shallow copy is okay, model is stateless
00597   nonlinearSolver->defaultTol_ = defaultTol_;
00598   nonlinearSolver->defaultMaxIters_ = defaultMaxIters_;
00599   nonlinearSolver->nonlinearSafetyFactor_ = nonlinearSafetyFactor_;
00600   nonlinearSolver->linearSafetyFactor_ = linearSafetyFactor_;
00601   nonlinearSolver->RMinFraction_ = RMinFraction_;
00602   nonlinearSolver->throwOnLinearSolveFailure_ = throwOnLinearSolveFailure_;
00603   // Note: The specification of this virtual function in the interface class
00604   // allows us to just copy the algorithm, not the entire state so we are
00605   // done!
00606   return nonlinearSolver;
00607 }
00608 
00609 
00610 template <class Scalar>
00611 RCP<const Thyra::VectorBase<Scalar> >
00612 TimeStepNonlinearSolver<Scalar>::get_current_x() const
00613 {
00614   return current_x_;
00615 }
00616 
00617 
00618 template <class Scalar>
00619 bool TimeStepNonlinearSolver<Scalar>::is_W_current() const
00620 {
00621   return J_is_current_;
00622 }
00623 
00624 
00625 template <class Scalar>
00626 RCP<Thyra::LinearOpWithSolveBase<Scalar> >
00627 TimeStepNonlinearSolver<Scalar>::get_nonconst_W(const bool forceUpToDate)
00628 {
00629   if (is_null(J_))
00630     return Teuchos::null;
00631   if (forceUpToDate) {
00632 #ifdef TEUCHOS_DEBUG
00633     TEST_FOR_EXCEPT(is_null(current_x_));
00634 #endif
00635     Thyra::eval_f_W<Scalar>( *model_, *current_x_, 0, &*J_ );
00636     J_is_current_ = true;
00637   }
00638   return J_;
00639 }
00640 
00641 
00642 template <class Scalar>
00643 RCP<const Thyra::LinearOpWithSolveBase<Scalar> >
00644 TimeStepNonlinearSolver<Scalar>::get_W() const
00645 {
00646   return J_;
00647 }
00648 
00649 
00650 template <class Scalar>
00651 void TimeStepNonlinearSolver<Scalar>::set_W_is_current(bool W_is_current)
00652 {
00653   J_is_current_ = W_is_current;
00654 }
00655 
00656 
00657 } // namespace Rythmos
00658 
00659 
00660 #endif // RYTHMOS_TIME_STEP_NONLINEAR_SOLVER_HPP

Generated on Tue Oct 20 12:46:08 2009 for Rythmos - Transient Integration for Differential Equations by doxygen 1.4.7