22 #if defined(LIBMESH_TRILINOS_HAVE_NOX) && defined(LIBMESH_TRILINOS_HAVE_EPETRA) 36 #include "NOX_Epetra_MatrixFree.H" 37 #include "NOX_Epetra_LinearSystem_AztecOO.H" 38 #include "NOX_Epetra_Group.H" 39 #include "NOX_Epetra_Vector.H" 46 public NOX::Epetra::Interface::Jacobian,
47 public NOX::Epetra::Interface::Preconditioner
56 bool computeF(
const Epetra_Vector & x,
58 NOX::Epetra::Interface::Required::FillType fillType);
62 Epetra_Operator & Jac);
71 Epetra_RowMatrix & M);
76 Epetra_Operator & Prec,
77 Teuchos::ParameterList * p);
97 NOX::Epetra::Interface::Required::FillType )
99 LOG_SCOPE(
"residual()",
"TrilinosNoxNonlinearSolver");
108 X_global.
swap(X_sys);
115 X_global.swap(X_sys);
125 libmesh_error_msg(
"ERROR: cannot specify both a function and object to compute the Residual!");
128 libmesh_error_msg(
"ERROR: cannot specify both a function and object to compute the combined Residual & Jacobian!");
154 Epetra_Operator & jac)
156 LOG_SCOPE(
"jacobian()",
"TrilinosNoxNonlinearSolver");
168 X_global.
swap(X_sys);
173 X_global.swap(X_sys);
179 libmesh_error_msg(
"ERROR: cannot specify both a function and object to compute the Jacobian!");
182 libmesh_error_msg(
"ERROR: cannot specify both a function and object to compute the combined Residual & Jacobian!");
197 libmesh_error_msg(
"Error! Unable to compute residual and/or Jacobian!");
216 Epetra_Operator & prec,
217 Teuchos::ParameterList * )
219 LOG_SCOPE(
"preconditioner()",
"TrilinosNoxNonlinearSolver");
232 X_global.
swap(X_sys);
237 X_global.swap(X_sys);
243 libmesh_error_msg(
"ERROR: cannot specify both a function and object to compute the Jacobian!");
246 libmesh_error_msg(
"ERROR: cannot specify both a function and object to compute the combined Residual & Jacobian!");
261 libmesh_error_msg(
"Error! Unable to compute residual and/or Jacobian!");
275 template <
typename T>
282 template <
typename T>
291 template <
typename T>
292 std::pair<unsigned int, Real>
301 if (this->user_presolve)
302 this->user_presolve(this->system());
307 NOX::Epetra::Vector x(*x_epetra->
vec());
309 Teuchos::RCP<Teuchos::ParameterList> nlParamsPtr = Teuchos::rcp(
new Teuchos::ParameterList);
310 Teuchos::ParameterList & nlParams = *(nlParamsPtr.get());
311 nlParams.set(
"Nonlinear Solver",
"Line Search Based");
314 Teuchos::ParameterList & printParams = nlParams.sublist(
"Printing");
315 printParams.set(
"Output Precision", 3);
316 printParams.set(
"Output Processor", 0);
317 printParams.set(
"Output Information",
318 NOX::Utils::OuterIteration +
319 NOX::Utils::OuterIterationStatusTest +
320 NOX::Utils::InnerIteration +
321 NOX::Utils::LinearSolverDetails +
322 NOX::Utils::Parameters +
323 NOX::Utils::Details +
324 NOX::Utils::Warning);
326 Teuchos::ParameterList & dirParams = nlParams.sublist(
"Direction");
327 dirParams.set(
"Method",
"Newton");
328 Teuchos::ParameterList & newtonParams = dirParams.sublist(
"Newton");
329 newtonParams.set(
"Forcing Term Method",
"Constant");
331 Teuchos::ParameterList & lsParams = newtonParams.sublist(
"Linear Solver");
332 lsParams.set(
"Aztec Solver",
"GMRES");
333 lsParams.set(
"Max Iterations", static_cast<int>(this->max_linear_iterations));
334 lsParams.set(
"Tolerance", this->initial_linear_tolerance);
335 lsParams.set(
"Output Frequency", 1);
336 lsParams.set(
"Size of Krylov Subspace", 1000);
339 Teuchos::RCP<NOX::Epetra::Interface::Required> iReq(_interface);
340 Teuchos::RCP<NOX::Epetra::LinearSystemAztecOO> linSys;
341 Teuchos::RCP<Epetra_Operator> pc;
343 if (this->jacobian || this->jacobian_object || this->residual_and_jacobian_object)
345 if (this->_preconditioner)
348 lsParams.set(
"Preconditioner",
"User Defined");
351 cast_ptr<TrilinosPreconditioner<Number> *>(this->_preconditioner);
352 pc = Teuchos::rcp(trilinos_pc);
354 Teuchos::RCP<NOX::Epetra::Interface::Preconditioner> iPrec(_interface);
355 linSys = Teuchos::rcp(
new NOX::Epetra::LinearSystemAztecOO(printParams, lsParams, iReq, iPrec, pc, x));
359 lsParams.set(
"Preconditioner",
"None");
366 Teuchos::RCP<Epetra_RowMatrix> jacMat = Teuchos::rcp(jacSys.
mat());
368 Teuchos::RCP<NOX::Epetra::Interface::Jacobian> iJac(_interface);
369 linSys = Teuchos::rcp(
new NOX::Epetra::LinearSystemAztecOO(printParams, lsParams, iReq, iJac, jacMat, x));
375 Teuchos::RCP<NOX::Epetra::MatrixFree> MF = Teuchos::rcp(
new NOX::Epetra::MatrixFree(printParams, iReq, x));
377 Teuchos::RCP<NOX::Epetra::Interface::Jacobian> iJac(MF);
378 linSys = Teuchos::rcp(
new NOX::Epetra::LinearSystemAztecOO(printParams, lsParams, iReq, iJac, MF, x));
382 Teuchos::RCP<NOX::Epetra::Group> grpPtr = Teuchos::rcp(
new NOX::Epetra::Group(printParams, iReq, x, linSys));
383 NOX::Epetra::Group & grp = *(grpPtr.get());
385 Teuchos::RCP<NOX::StatusTest::NormF> absresid =
386 Teuchos::rcp(
new NOX::StatusTest::NormF(this->absolute_residual_tolerance, NOX::StatusTest::NormF::Unscaled));
387 Teuchos::RCP<NOX::StatusTest::NormF> relresid =
388 Teuchos::rcp(
new NOX::StatusTest::NormF(grp, this->relative_residual_tolerance));
389 Teuchos::RCP<NOX::StatusTest::MaxIters> maxiters =
390 Teuchos::rcp(
new NOX::StatusTest::MaxIters(this->max_nonlinear_iterations));
391 Teuchos::RCP<NOX::StatusTest::FiniteValue> finiteval =
392 Teuchos::rcp(
new NOX::StatusTest::FiniteValue());
393 Teuchos::RCP<NOX::StatusTest::NormUpdate> normupdate =
394 Teuchos::rcp(
new NOX::StatusTest::NormUpdate(this->absolute_step_tolerance));
395 Teuchos::RCP<NOX::StatusTest::Combo> combo =
396 Teuchos::rcp(
new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR));
397 combo->addStatusTest(absresid);
398 combo->addStatusTest(relresid);
399 combo->addStatusTest(maxiters);
400 combo->addStatusTest(finiteval);
401 combo->addStatusTest(normupdate);
403 Teuchos::RCP<Teuchos::ParameterList> finalPars = nlParamsPtr;
405 Teuchos::RCP<NOX::Solver::Generic> solver = NOX::Solver::buildSolver(grpPtr, combo, nlParamsPtr);
406 NOX::StatusTest::StatusType
status = solver->solve();
407 this->converged = (
status == NOX::StatusTest::Converged);
409 const NOX::Epetra::Group & finalGroup =
dynamic_cast<const NOX::Epetra::Group &
>(solver->getSolutionGroup());
410 const NOX::Epetra::Vector & noxFinalSln =
dynamic_cast<const NOX::Epetra::Vector &
>(finalGroup.getX());
412 *x_epetra->
vec() = noxFinalSln.getEpetraVector();
415 Real residual_norm = finalGroup.getNormF();
416 unsigned int total_iters = solver->getNumIterations();
417 _n_linear_iterations = finalPars->sublist(
"Direction").sublist(
"Newton").sublist(
"Linear Solver").sublist(
"Output").get(
"Total Number of Linear Iterations", -1);
423 return std::make_pair(total_iters, residual_norm);
428 template <
typename T>
432 return _n_linear_iterations;
445 #endif // LIBMESH_TRILINOS_HAVE_NOX && LIBMESH_TRILINOS_HAVE_EPETRA
void(* residual)(const NumericVector< Number > &X, NumericVector< Number > &R, sys_type &S)
virtual int get_total_linear_iterations() override
NonlinearImplicitSystem::ComputeResidualandJacobian * residual_and_jacobian_object
virtual void residual(const NumericVector< Number > &X, NumericVector< Number > &R, sys_type &S)=0
bool computePrecMatrix(const Epetra_Vector &x, Epetra_RowMatrix &M)
Epetra_FECrsMatrix * mat()
virtual void init(const char *name=nullptr) override
NumericVector< Number > * rhs
Provides a uniform interface to vector storage schemes for different linear algebra libraries...
const Parallel::Communicator & comm() const
NoxNonlinearSolver< Number > * _solver
virtual std::pair< unsigned int, Real > solve(SparseMatrix< T > &, NumericVector< T > &, NumericVector< T > &, const double, const unsigned int) override
NonlinearImplicitSystem::ComputeResidual * residual_object
void(* jacobian)(const NumericVector< Number > &X, SparseMatrix< Number > &J, sys_type &S)
virtual void clear() override
const sys_type & system() const
NonlinearImplicitSystem::ComputeJacobian * jacobian_object
Problem_Interface(NoxNonlinearSolver< Number > *solver)
virtual void jacobian(const NumericVector< Number > &X, SparseMatrix< Number > &J, sys_type &S)=0
bool computePreconditioner(const Epetra_Vector &x, Epetra_Operator &Prec, Teuchos::ParameterList *p)
std::unique_ptr< NumericVector< Number > > solution
void init(triangulateio &t)
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and non-linear solv...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
SparseMatrix< Number > * matrix
virtual void swap(NumericVector< T > &v) override
std::unique_ptr< NumericVector< Number > > current_local_solution
bool computeJacobian(const Epetra_Vector &x, Epetra_Operator &Jac)
Compute an explicit Jacobian.
Epetra_FECrsMatrix * mat()
const DofMap & get_dof_map() const
virtual void residual_and_jacobian(const NumericVector< Number > &X, NumericVector< Number > *R, SparseMatrix< Number > *J, sys_type &S)=0
void(* matvec)(const NumericVector< Number > &X, NumericVector< Number > *R, SparseMatrix< Number > *J, sys_type &S)
void enforce_constraints_exactly(const System &system, NumericVector< Number > *v=nullptr, bool homogeneous=false) const
bool computeF(const Epetra_Vector &x, Epetra_Vector &FVec, NOX::Epetra::Interface::Required::FillType fillType)
Compute and return F.