137 template <
class SC,
class LO,
class GO,
class NO>
138 int NonLinearProblem<SC, LO, GO, NO>::solveUpdate()
142 *previousSolution_ = *this->solution_;
144 int its = this->solve(residualVec_);
149 template <
class SC,
class LO,
class GO,
class NO>
150 int NonLinearProblem<SC, LO, GO, NO>::solveAndUpdate(
const std::string &criterion,
double &criterionValue)
153 int its = solveUpdate();
155 if (criterion ==
"Update")
157 Teuchos::Array<SC> updateNorm(1);
158 this->solution_->norm2(updateNorm());
159 criterionValue = updateNorm[0];
161 this->solution_->update(1., *previousSolution_, 1.);
166 template <
class SC,
class LO,
class GO,
class NO>
167 typename NonLinearProblem<SC, LO, GO, NO>::BlockMultiVectorPtr_Type NonLinearProblem<SC, LO, GO, NO>::getResidualVector()
const
173 template <
class SC,
class LO,
class GO,
class NO>
174 Thyra::ModelEvaluatorBase::InArgs<SC>
175 NonLinearProblem<SC, LO, GO, NO>::getNominalValues()
const
177 return nominalValues_;
180 template <
class SC,
class LO,
class GO,
class NO>
181 Teuchos::RCP<const ::Thyra::VectorSpaceBase<SC>> NonLinearProblem<SC, LO, GO, NO>::get_x_space()
const
186 template <
class SC,
class LO,
class GO,
class NO>
187 Teuchos::RCP<const ::Thyra::VectorSpaceBase<SC>> NonLinearProblem<SC, LO, GO, NO>::get_f_space()
const
192 template <
class SC,
class LO,
class GO,
class NO>
193 Thyra::ModelEvaluatorBase::InArgs<SC>
194 NonLinearProblem<SC, LO, GO, NO>::createInArgs()
const
196 return prototypeInArgs_;
201 template <
class SC,
class LO,
class GO,
class NO>
202 Thyra::ModelEvaluatorBase::OutArgs<SC>
203 NonLinearProblem<SC, LO, GO, NO>::createOutArgsImpl()
const
205 return prototypeOutArgs_;
208 template <
class SC,
class LO,
class GO,
class NO>
209 void NonLinearProblem<SC, LO, GO, NO>::initNOXParameters()
214 using ::Thyra::VectorBase;
215 typedef ::Thyra::ModelEvaluatorBase MEB;
217 MEB::InArgsSetup<SC> inArgs;
218 inArgs.setModelEvalDescription(this->description());
219 inArgs.setSupports(MEB::IN_ARG_x);
220 this->prototypeInArgs_ = inArgs;
222 MEB::OutArgsSetup<SC> outArgs;
223 outArgs.setModelEvalDescription(this->description());
224 outArgs.setSupports(MEB::OUT_ARG_f);
225 outArgs.setSupports(MEB::OUT_ARG_W_op);
226 outArgs.setSupports(MEB::OUT_ARG_W_prec);
227 this->prototypeOutArgs_ = outArgs;
229 this->nominalValues_ = inArgs;
232 template <
class SC,
class LO,
class GO,
class NO>
233 void NonLinearProblem<SC, LO, GO, NO>::initVectorSpaces()
235 this->initNOXParameters();
237 std::string type = this->parameterList_->sublist(
"General").get(
"Preconditioner Method",
"Monolithic");
238 if (!type.compare(
"Monolithic"))
239 initVectorSpacesMonolithic();
240 else if (!type.compare(
"Teko") || type ==
"FaCSI" || type ==
"FaCSI-Teko" || type ==
"Diagonal" || type ==
"Triangular" || type ==
"PCD"|| type ==
"LSC")
241 initVectorSpacesBlock();
243 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unkown preconditioner/solver type.");
246 template <
class SC,
class LO,
class GO,
class NO>
247 void NonLinearProblem<SC, LO, GO, NO>::initVectorSpacesMonolithic()
250 BlockMapPtr_Type map = Teuchos::rcp_const_cast<BlockMap_Type>(this->solution_->getMap());
254 TpetraMapConstPtr_Type tpetraMap = map->getMergedMap()->getTpetraMap();
256 this->xSpace_ = Thyra::createVectorSpace<SC, LO, GO, NO>(tpetraMap);
257 this->fSpace_ = Thyra::createVectorSpace<SC, LO, GO, NO>(tpetraMap);
259 typedef Teuchos::ScalarTraits<SC> ST;
260 x0_ = ::Thyra::createMember(this->xSpace_);
261 V_S(x0_.ptr(), ST::zero());
263 this->nominalValues_.set_x(x0_);
266 template <
class SC,
class LO,
class GO,
class NO>
267 void NonLinearProblem<SC, LO, GO, NO>::initVectorSpacesBlock()
270 BlockMapPtr_Type map = Teuchos::rcp_const_cast<BlockMap_Type>(this->solution_->getMap());
272 TpetraMap_Type tpetra_map;
274 Teuchos::Array<ThyraVecSpaceConstPtr_Type> vecSpaceArray(map->size());
275 for (
int i = 0; i < map->size(); i++)
279 TpetraMapConstPtr_Type tpetraMap =map->getBlock(i)->getTpetraMap();
280 ThyraVecSpaceConstPtr_Type vecSpace = Thyra::createVectorSpace<SC, LO, GO, NO>(tpetraMap);
281 vecSpaceArray[i] = vecSpace;
283 this->xSpace_ = Teuchos::rcp(
new Thyra::DefaultProductVectorSpace<SC>(vecSpaceArray()));
284 this->fSpace_ = Teuchos::rcp(
new Thyra::DefaultProductVectorSpace<SC>(vecSpaceArray()));
286 typedef Teuchos::ScalarTraits<SC> ST;
287 x0_ = ::Thyra::createMember(this->xSpace_);
288 V_S(x0_.ptr(), ST::zero());
290 this->nominalValues_.set_x(x0_);
294 template<
class SC,
class LO,
class GO,
class NO>
295 void NonLinearProblem<SC,LO,GO,NO>::evalModelImpl(
const Thyra::ModelEvaluatorBase::InArgs<SC> &inArgs,
296 const Thyra::ModelEvaluatorBase::OutArgs<SC> &outArgs
299 std::string type = this->parameterList_->sublist(
"General").get(
"Preconditioner Method",
"Monolithic");
300 if ( !type.compare(
"Monolithic"))
301 evalModelImplMonolithic( inArgs, outArgs );
302 else if ( !type.compare(
"Teko")|| !type.compare(
"Diagonal") || type ==
"Triangular"|| !type.compare(
"PCD") || !type.compare(
"LSC")){
303 #ifdef FEDD_HAVE_TEKO
304 evalModelImplBlock( inArgs, outArgs );
306 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Teko not found! Build Trilinos with Teko.");
310 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unkown preconditioner/solver type.");
317 template<
class SC,
class LO,
class GO,
class NO>
318 void NonLinearProblem<SC,LO,GO,NO>::evalModelImplMonolithic(
const Thyra::ModelEvaluatorBase::InArgs<SC> &inArgs,
319 const Thyra::ModelEvaluatorBase::OutArgs<SC> &outArgs )
const
323 using Teuchos::rcp_dynamic_cast;
324 using Teuchos::rcp_const_cast;
325 using Teuchos::ArrayView;
326 using Teuchos::Array;
327 RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
328 TEUCHOS_TEST_FOR_EXCEPTION( inArgs.get_x().is_null(), std::logic_error,
"inArgs.get_x() is null.");
330 RCP< const Thyra::VectorBase< SC > > vecThyra = inArgs.get_x();
331 RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
333 RCP< Thyra::VectorBase< SC > > vecThyraNonConst = rcp_const_cast<Thyra::VectorBase< SC > >(vecThyra);
335 this->solution_->fromThyraMultiVector(vecThyraNonConst);
337 const RCP<Thyra::MultiVectorBase<SC> > f_out = outArgs.get_f();
338 const RCP<Thyra::LinearOpBase<SC> > W_out = outArgs.get_W_op();
339 const RCP<Thyra::PreconditionerBase<SC> > W_prec_out = outArgs.get_W_prec();
341 typedef Thyra::TpetraOperatorVectorExtraction<SC,LO,GO,NO> tpetra_extract;
342 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> TpetraMatrix_Type;
343 typedef RCP<TpetraMatrix_Type> TpetraMatrixPtr_Type;
344 typedef RCP<const TpetraMatrix_Type> TpetraMatrixConstPtr_Type;
346 const bool fill_f = nonnull(f_out);
347 const bool fill_W = nonnull(W_out);
348 const bool fill_W_prec = nonnull(W_prec_out);
351 if ( fill_f || fill_W || fill_W_prec ) {
358 this->calculateNonLinResidualVec(
"standard");
362 Teuchos::RCP<Thyra::MultiVectorBase<SC> > f_thyra = this->getResidualVector()->getThyraMultiVector();
363 f_out->assign(*f_thyra);
366 TpetraMatrixPtr_Type W;
368 this->assemble(
"Newton");
370 this->setBoundariesSystem();
372 Teuchos::RCP<TpetraOp_Type> W_tpetra = tpetra_extract::getTpetraOperator(W_out);
373 Teuchos::RCP<TpetraMatrix_Type> W_tpetraMat = Teuchos::rcp_dynamic_cast<TpetraMatrix_Type>(W_tpetra);
375 TpetraMatrixConstPtr_Type W_systemTpetra = this->getSystem()->getMergedMatrix()->getTpetraMatrix();
376 TpetraMatrixPtr_Type W_systemTpetraNonConst = rcp_const_cast<TpetraMatrix_Type>(W_systemTpetra);
381 Teuchos::RCP<TpetraMatrix_Type> tpetraMatTpetra = W_systemTpetraNonConst;
383 W_tpetraMat->resumeFill();
385 for (
auto i=0; i<tpetraMatTpetra->getMap()->getLocalNumElements(); i++) {
386 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::local_inds_host_view_type indices;
387 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::values_host_view_type values;
388 tpetraMatTpetra->getLocalRowView( i, indices, values);
389 W_tpetraMat->replaceLocalValues( i, indices, values);
391 W_tpetraMat->fillComplete();
398 int newtonLimit = this->parameterList_->sublist(
"Parameter").get(
"newtonLimit",2);
399 if(this->newtonStep_ < newtonLimit || this->parameterList_->sublist(
"Parameter").get(
"Rebuild Preconditioner every Newton Iteration",
true) )
401 this->setupPreconditioner(
"Monolithic" );
405 std::cout <<
" NonLinearProblem<SC,LO,GO,NO>::evalModelImplMonolithic:: Skipping preconditioner reconstruction" << std::endl;
409 precInitOnly_ =
true;
414 std::string levelCombination = this->parameterList_->sublist(
"ThyraPreconditioner").sublist(
"Preconditioner Types").sublist(
"FROSch").get(
"Level Combination",
"Additive");
415 if (!levelCombination.compare(
"Multiplicative")) {
416 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Multiplicative Level Combination is not supported for NOX.");
419 this->newtonStep_ ++;
428 #ifdef FEDD_HAVE_TEKO
429 template<
class SC,
class LO,
class GO,
class NO>
430 void NonLinearProblem<SC,LO,GO,NO>::evalModelImplBlock(
const Thyra::ModelEvaluatorBase::InArgs<SC> &inArgs,
431 const Thyra::ModelEvaluatorBase::OutArgs<SC> &outArgs )
const
435 using Teuchos::rcp_dynamic_cast;
436 using Teuchos::rcp_const_cast;
437 using Teuchos::ArrayView;
438 using Teuchos::Array;
440 RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
441 TEUCHOS_TEST_FOR_EXCEPTION( inArgs.get_x().is_null(), std::logic_error,
"inArgs.get_x() is null.");
443 RCP< const Thyra::VectorBase< SC > > vecThyra = inArgs.get_x();
444 RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
446 RCP< Thyra::VectorBase< SC > > vecThyraNonConst = rcp_const_cast<Thyra::VectorBase< SC > >(vecThyra);
448 RCP< Thyra::ProductVectorBase< SC > > vecThyraBlock = rcp_dynamic_cast<Thyra::ProductVectorBase< SC > > (vecThyraNonConst);
450 this->solution_->getBlockNonConst(0)->fromThyraMultiVector( vecThyraBlock->getNonconstVectorBlock(0) );
451 this->solution_->getBlockNonConst(1)->fromThyraMultiVector( vecThyraBlock->getNonconstVectorBlock(1) );
453 const RCP<Thyra::MultiVectorBase<SC> > f_out = outArgs.get_f();
454 const RCP<Thyra::LinearOpBase<SC> > W_out = outArgs.get_W_op();
455 const RCP<Thyra::PreconditionerBase<SC> > W_prec_out = outArgs.get_W_prec();
457 typedef Thyra::TpetraOperatorVectorExtraction<SC,LO,GO,NO> tpetra_extract;
458 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> TpetraMatrix_Type;
459 typedef RCP<TpetraMatrix_Type> TpetraMatrixPtr_Type;
460 typedef RCP<const TpetraMatrix_Type> TpetraMatrixConstPtr_Type;
462 const bool fill_f = nonnull(f_out);
463 const bool fill_W = nonnull(W_out);
464 const bool fill_W_prec = nonnull(W_prec_out);
466 if ( fill_f || fill_W || fill_W_prec ) {
473 this->calculateNonLinResidualVec(
"standard");
475 Teko::MultiVector f0;
476 Teko::MultiVector f1;
477 f0 = this->getResidualVector()->getBlockNonConst(0)->getThyraMultiVector();
478 f1 = this->getResidualVector()->getBlockNonConst(1)->getThyraMultiVector();
480 std::vector<Teko::MultiVector> f_vec; f_vec.push_back(f0); f_vec.push_back(f1);
482 Teko::MultiVector f = Teko::buildBlockedMultiVector(f_vec);
487 TpetraMatrixPtr_Type W;
490 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> TpetraCrsMatrix;
492 this->assemble(
"Newton");
494 this->setBoundariesSystem();
496 RCP<ThyraBlockOp_Type> W_blocks = rcp_dynamic_cast<ThyraBlockOp_Type>(W_out);
497 RCP<const ThyraOp_Type> W_block00 = W_blocks->getBlock(0,0);
498 RCP<ThyraOp_Type> W_block00NonConst = rcp_const_cast<ThyraOp_Type>( W_block00 );
499 RCP<TpetraOp_Type> W_tpetra = tpetra_extract::getTpetraOperator( W_block00NonConst );
501 RCP<TpetraMatrix_Type> W_tpetraMat = Teuchos::rcp_dynamic_cast<TpetraMatrix_Type>(W_tpetra);
503 TpetraMatrixConstPtr_Type W_matrixTpetra = this->getSystem()->getBlock(0,0)->getTpetraMatrix();
504 TpetraMatrixPtr_Type W_matrixTpetraNonConst = rcp_const_cast<TpetraMatrix_Type>(W_matrixTpetra);
505 RCP<TpetraMatrix_Type> tpetraMatTpetra = W_matrixTpetraNonConst;
507 W_tpetraMat->resumeFill();
509 for (
auto i=0; i<tpetraMatTpetra->getMap()->getLocalNumElements(); i++) {
510 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::local_inds_host_view_type indices;
511 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::values_host_view_type values;
512 tpetraMatTpetra->getLocalRowView( i, indices, values);
513 W_tpetraMat->replaceLocalValues( i, indices, values);
515 W_tpetraMat->fillComplete();
520 std::string type = this->parameterList_->sublist(
"General").get(
"Preconditioner Method",
"Monolithic");
522 int newtonLimit = this->parameterList_->sublist(
"Parameter").get(
"newtonLimit",2);
523 if(this->newtonStep_ < newtonLimit || this->parameterList_->sublist(
"Parameter").get(
"Rebuild Preconditioner every Newton Iteration",
true) )
525 this->setupPreconditioner( type );
529 std::cout <<
" \n NonLinearProblem<SC,LO,GO,NO>::evalModelImplBlock:: Skipping preconditioner reconstruction \n " << std::endl;
533 precInitOnly_ =
true;
537 ParameterListPtr_Type tmpSubList = sublist( sublist( sublist( sublist( this->parameterList_,
"Teko Parameters" ) ,
"Preconditioner Types" ) ,
"Teko" ) ,
"Inverse Factory Library" );
539 std::string levelCombination1 = tmpSubList->sublist(
"FROSch-Velocity" ).get(
"Level Combination",
"Additive");
540 std::string levelCombination2 = tmpSubList->sublist(
"FROSch-Pressure" ).get(
"Level Combination",
"Additive");
542 if ( !levelCombination1.compare(
"Multiplicative") || !levelCombination2.compare(
"Multiplicative") ) {
544 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Multiplicative Level Combination is not supported for NOX.");
545 ParameterListPtr_Type solverPList = this->getLinearSolverBuilder()->getNonconstParameterList();
547 this->newtonStep_ ++;
555 template<
class SC,
class LO,
class GO,
class NO>
558 std::string type = this->parameterList_->sublist(
"General").get(
"Preconditioner Method",
"Monolithic");
559 if ( !type.compare(
"Monolithic"))
560 return create_W_op_Monolithic( );
561 else if ( !type.compare(
"Teko") || !type.compare(
"Diagonal") || !type.compare(
"Triangular") || !type.compare(
"PCD") || !type.compare(
"LSC") ){
562 #ifdef FEDD_HAVE_TEKO
563 return create_W_op_Block( );
565 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Teko not found! Build Trilinos with Teko.");
569 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unkown preconditioner/solver type.");