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

Generated on Tue Oct 20 10:24:09 2009 for Rythmos - Transient Integration for Differential Equations by  doxygen 1.6.1