1#ifndef NonLinLaplace_def_hpp
2#define NonLinLaplace_def_hpp
3#include "NonLinLaplace_decl.hpp"
14template <
class SC,
class LO,
class GO,
class NO>
15NonLinLaplace<SC, LO, GO, NO>::NonLinLaplace(
16 const DomainConstPtr_Type &domain, std::string FEType,
17 ParameterListPtr_Type parameterList)
20 this->nonLinearTolerance_ =
21 this->parameterList_->sublist(
"Parameter").get(
"relNonLinTol", 1.0e-6);
22 this->initNOXParameters();
23 this->addVariable(domain, FEType,
"u", 1);
24 this->dim_ = this->getDomain(0)->getDimension();
25 u_rep_ = Teuchos::rcp(
26 new MultiVector_Type(this->getDomain(0)->getMapRepeated()));
29template <
class SC,
class LO,
class GO,
class NO>
30NonLinLaplace<SC, LO, GO, NO>::~NonLinLaplace() {}
32template <
class SC,
class LO,
class GO,
class NO>
33void NonLinLaplace<SC, LO, GO, NO>::info() {
35 this->infoNonlinProblem();
42template <
class SC,
class LO,
class GO,
class NO>
43void NonLinLaplace<SC, LO, GO, NO>::assemble(std::string type)
const {
46 std::cout <<
"-- Assembly nonlinear laplace ... " << std::flush;
50 this->reAssemble(type);
53 std::cout <<
"done -- " << std::endl;
60template <
class SC,
class LO,
class GO,
class NO>
61void NonLinLaplace<SC, LO, GO, NO>::initAssemble()
const {
64 std::cout <<
"-- Initial assembly " << std::flush;
67 if (this->system_.is_null())
68 this->system_.reset(
new BlockMatrix_Type(1));
70 if (this->residualVec_.is_null())
71 this->residualVec_.reset(
new BlockMultiVector_Type(1));
73 this->feFactory_->assemblyNonlinearLaplace(
74 this->dim_, this->getDomain(0)->getFEType(), 2, this->u_rep_,
75 this->system_, this->residualVec_, this->parameterList_,
"Jacobian");
78 this->solution_->putScalar(1.);
81 std::cout <<
"done -- " << std::endl;
89template <
class SC,
class LO,
class GO,
class NO>
90void NonLinLaplace<SC, LO, GO, NO>::reAssemble(std::string type)
const {
93 std::cout <<
"-- Reassembly nonlinear laplace"
94 <<
" (" << type <<
") ... " << std::flush;
96 MultiVectorConstPtr_Type u = this->solution_->getBlock(0);
97 this->u_rep_->importFromVector(u,
true);
101 this->feFactory_->assemblyNonlinearLaplace(
102 this->dim_, this->getDomain(0)->getFEType(), 2, this->u_rep_,
103 this->system_, this->residualVec_, this->parameterList_,
"Rhs");
105 }
else if (type ==
"Newton") {
107 this->feFactory_->assemblyNonlinearLaplace(
108 this->dim_, this->getDomain(0)->getFEType(), 2, this->u_rep_,
109 this->system_, this->residualVec_, this->parameterList_,
113 std::cout <<
"done -- " << std::endl;
116template <
class SC,
class LO,
class GO,
class NO>
117void NonLinLaplace<SC, LO, GO, NO>::reAssembleExtrapolation(
118 BlockMultiVectorPtrArray_Type previousSolutions) {
120 TEUCHOS_TEST_FOR_EXCEPTION(
121 true, std::logic_error,
122 "Only Newton/NOX implemented for nonlinear Laplace!");
129template <
class SC,
class LO,
class GO,
class NO>
130void NonLinLaplace<SC, LO, GO, NO>::evalModelImpl(
131 const Thyra::ModelEvaluatorBase::InArgs<SC> &inArgs,
132 const Thyra::ModelEvaluatorBase::OutArgs<SC> &outArgs)
const {
133 using Teuchos::Array;
134 using Teuchos::ArrayView;
137 using Teuchos::rcp_const_cast;
138 using Teuchos::rcp_dynamic_cast;
140 TEUCHOS_TEST_FOR_EXCEPTION(
141 this->solution_->getBlock(0)->getMap()->getUnderlyingLib() !=
"Tpetra",
143 "Use of NOX only supports Tpetra. Epetra support must be implemented.");
144 RCP<Teuchos::FancyOStream> fancy =
145 Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
146 TEUCHOS_TEST_FOR_EXCEPTION(inArgs.get_x().is_null(), std::logic_error,
147 "inArgs.get_x() is null.");
149 RCP<const Thyra::VectorBase<SC>> vecThyra = inArgs.get_x();
150 RCP<Teuchos::FancyOStream> out =
151 Teuchos::VerboseObjectBase::getDefaultOStream();
153 RCP<Thyra::VectorBase<SC>> vecThyraNonConst =
154 rcp_const_cast<Thyra::VectorBase<SC>>(vecThyra);
156 this->solution_->fromThyraMultiVector(vecThyraNonConst);
158 const RCP<Thyra::MultiVectorBase<SC>> f_out = outArgs.get_f();
159 const RCP<Thyra::LinearOpBase<SC>> W_out = outArgs.get_W_op();
160 const RCP<Thyra::PreconditionerBase<SC>> W_prec_out = outArgs.get_W_prec();
162 typedef Thyra::TpetraOperatorVectorExtraction<SC,LO,GO,NO> tpetra_extract;
163 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> TpetraMatrix_Type;
164 typedef RCP<TpetraMatrix_Type> TpetraMatrixPtr_Type;
165 typedef RCP<const TpetraMatrix_Type> TpetraMatrixConstPtr_Type;
167 const bool fill_f = nonnull(f_out);
168 const bool fill_W = nonnull(W_out);
169 const bool fill_W_prec = nonnull(W_prec_out);
171 if (fill_f || fill_W || fill_W_prec) {
178 this->calculateNonLinResidualVec(
"standard");
180 RCP<Thyra::MultiVectorBase<SC>> f_thyra =
181 this->getResidualVector()->getThyraMultiVector();
182 f_out->assign(*f_thyra);
185 TpetraMatrixPtr_Type W;
188 this->reAssemble(
"Newton");
190 this->setBoundariesSystem();
192 Teuchos::RCP<TpetraOp_Type> W_tpetra = tpetra_extract::getTpetraOperator(W_out);
193 Teuchos::RCP<TpetraMatrix_Type> W_tpetraMat = Teuchos::rcp_dynamic_cast<TpetraMatrix_Type>(W_tpetra);
195 TpetraMatrixConstPtr_Type W_systemTpetra = this->getSystem()->getMergedMatrix()->getTpetraMatrix();
196 TpetraMatrixPtr_Type W_systemTpetraNonConst = rcp_const_cast<TpetraMatrix_Type>(W_systemTpetra);
201 Teuchos::RCP<TpetraMatrix_Type> tpetraMatTpetra = W_systemTpetraNonConst;
203 W_tpetraMat->resumeFill();
205 for (
auto i=0; i<tpetraMatTpetra->getMap()->getLocalNumElements(); i++) {
206 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::local_inds_host_view_type indices;
207 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::values_host_view_type values;
208 tpetraMatTpetra->getLocalRowView( i, indices, values);
209 W_tpetraMat->replaceLocalValues( i, indices, values);
211 W_tpetraMat->fillComplete();
215 this->setupPreconditioner(
"Monolithic");
222 std::string levelCombination =
223 this->parameterList_->sublist(
"ThyraPreconditioner")
224 .sublist(
"Preconditioner Types")
226 .get(
"Level Combination",
"Additive");
227 if (!levelCombination.compare(
"Multiplicative")) {
228 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
229 "Multiplicative Level Combination "
230 "is not supported for NOX. In "
231 "general we need to pre-apply the "
232 "coarse problem. This must be "
233 "implemented here.");
243template <
class SC,
class LO,
class GO,
class NO>
244Teuchos::RCP<Thyra::LinearOpBase<SC>>
245NonLinLaplace<SC, LO, GO, NO>::create_W_op()
const {
247 Teuchos::RCP<const Thyra::LinearOpBase<SC>> W_opConst =
248 this->system_->getThyraLinOp();
249 Teuchos::RCP<Thyra::LinearOpBase<SC>> W_op =
250 Teuchos::rcp_const_cast<Thyra::LinearOpBase<SC>>(W_opConst);
258template <
class SC,
class LO,
class GO,
class NO>
259Teuchos::RCP<Thyra::PreconditionerBase<SC>>
260NonLinLaplace<SC, LO, GO, NO>::create_W_prec()
const {
261 this->initializeSolverBuilder();
262 this->initializePreconditioner();
264 Teuchos::RCP<const Thyra::PreconditionerBase<SC>> thyraPrec =
265 this->getPreconditionerConst()->getThyraPrecConst();
266 Teuchos::RCP<Thyra::PreconditionerBase<SC>> thyraPrecNonConst =
267 Teuchos::rcp_const_cast<Thyra::PreconditionerBase<SC>>(thyraPrec);
269 return thyraPrecNonConst;
275template <
class SC,
class LO,
class GO,
class NO>
276void NonLinLaplace<SC, LO, GO, NO>::calculateNonLinResidualVec(
277 std::string type,
double time)
const {
279 this->reAssemble(
"Rhs");
282 if (!type.compare(
"standard")) {
284 this->residualVec_->update(-1., *this->rhs_, 1.);
285 this->bcFactory_->setVectorMinusBC(this->residualVec_, this->solution_,
287 }
else if (!type.compare(
"reverse")) {
290 this->residualVec_->update(1., *this->rhs_, -1.);
295 this->bcFactory_->setBCMinusVector(this->residualVec_, this->solution_,
298 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
299 "Unknown type for residual computation.");
Definition NonLinearProblem_decl.hpp:24
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement.cpp:5