171 template <
class SC,
class LO,
class GO,
class NO>
178 template <
class SC,
class LO,
class GO,
class NO>
179 Thyra::ModelEvaluatorBase::InArgs<SC>
180 NonLinearProblem<SC, LO, GO, NO>::getNominalValues()
const
182 return nominalValues_;
185 template <
class SC,
class LO,
class GO,
class NO>
186 Teuchos::RCP<const ::Thyra::VectorSpaceBase<SC>> NonLinearProblem<SC, LO, GO, NO>::get_x_space()
const
191 template <
class SC,
class LO,
class GO,
class NO>
192 Teuchos::RCP<const ::Thyra::VectorSpaceBase<SC>> NonLinearProblem<SC, LO, GO, NO>::get_f_space()
const
197 template <
class SC,
class LO,
class GO,
class NO>
198 Thyra::ModelEvaluatorBase::InArgs<SC>
199 NonLinearProblem<SC, LO, GO, NO>::createInArgs()
const
201 return prototypeInArgs_;
206 template <
class SC,
class LO,
class GO,
class NO>
207 Thyra::ModelEvaluatorBase::OutArgs<SC>
208 NonLinearProblem<SC, LO, GO, NO>::createOutArgsImpl()
const
210 return prototypeOutArgs_;
213 template <
class SC,
class LO,
class GO,
class NO>
214 void NonLinearProblem<SC, LO, GO, NO>::initNOXParameters()
219 using ::Thyra::VectorBase;
220 typedef ::Thyra::ModelEvaluatorBase MEB;
222 MEB::InArgsSetup<SC> inArgs;
223 inArgs.setModelEvalDescription(this->description());
224 inArgs.setSupports(MEB::IN_ARG_x);
225 this->prototypeInArgs_ = inArgs;
227 MEB::OutArgsSetup<SC> outArgs;
228 outArgs.setModelEvalDescription(this->description());
229 outArgs.setSupports(MEB::OUT_ARG_f);
230 outArgs.setSupports(MEB::OUT_ARG_W_op);
231 outArgs.setSupports(MEB::OUT_ARG_W_prec);
232 this->prototypeOutArgs_ = outArgs;
234 this->nominalValues_ = inArgs;
237 template <
class SC,
class LO,
class GO,
class NO>
238 void NonLinearProblem<SC, LO, GO, NO>::initVectorSpaces()
240 this->initNOXParameters();
242 std::string type = this->parameterList_->sublist(
"General").get(
"Preconditioner Method",
"Monolithic");
243 if (!type.compare(
"Monolithic"))
244 initVectorSpacesMonolithic();
245 else if (!type.compare(
"Teko") || type ==
"FaCSI" || type ==
"FaCSI-Teko" || type ==
"FaCSI-Block" || type ==
"Diagonal" || type ==
"Triangular" || type ==
"PCD"|| type ==
"LSC")
246 initVectorSpacesBlock();
248 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unkown preconditioner/solver type.");
251 template <
class SC,
class LO,
class GO,
class NO>
252 void NonLinearProblem<SC, LO, GO, NO>::initVectorSpacesMonolithic()
255 BlockMapPtr_Type map = Teuchos::rcp_const_cast<BlockMap_Type>(this->solution_->getMap());
259 TpetraMapConstPtr_Type tpetraMap = map->getMergedMap()->getTpetraMap();
261 this->xSpace_ = Thyra::createVectorSpace<SC, LO, GO, NO>(tpetraMap);
262 this->fSpace_ = Thyra::createVectorSpace<SC, LO, GO, NO>(tpetraMap);
264 typedef Teuchos::ScalarTraits<SC> ST;
265 x0_ = ::Thyra::createMember(this->xSpace_);
266 V_S(x0_.ptr(), ST::zero());
268 this->nominalValues_.set_x(x0_);
271 template <
class SC,
class LO,
class GO,
class NO>
272 void NonLinearProblem<SC, LO, GO, NO>::initVectorSpacesBlock()
275 BlockMapPtr_Type map = Teuchos::rcp_const_cast<BlockMap_Type>(this->solution_->getMap());
277 TpetraMap_Type tpetra_map;
279 Teuchos::Array<ThyraVecSpaceConstPtr_Type> vecSpaceArray(map->size());
280 for (
int i = 0; i < map->size(); i++)
284 TpetraMapConstPtr_Type tpetraMap =map->getBlock(i)->getTpetraMap();
285 ThyraVecSpaceConstPtr_Type vecSpace = Thyra::createVectorSpace<SC, LO, GO, NO>(tpetraMap);
286 vecSpaceArray[i] = vecSpace;
288 this->xSpace_ = Teuchos::rcp(
new Thyra::DefaultProductVectorSpace<SC>(vecSpaceArray()));
289 this->fSpace_ = Teuchos::rcp(
new Thyra::DefaultProductVectorSpace<SC>(vecSpaceArray()));
291 typedef Teuchos::ScalarTraits<SC> ST;
292 x0_ = ::Thyra::createMember(this->xSpace_);
293 V_S(x0_.ptr(), ST::zero());
295 this->nominalValues_.set_x(x0_);
299 template<
class SC,
class LO,
class GO,
class NO>
300 void NonLinearProblem<SC,LO,GO,NO>::evalModelImpl(
const Thyra::ModelEvaluatorBase::InArgs<SC> &inArgs,
301 const Thyra::ModelEvaluatorBase::OutArgs<SC> &outArgs
304 std::string type = this->parameterList_->sublist(
"General").get(
"Preconditioner Method",
"Monolithic");
305 if ( !type.compare(
"Monolithic"))
306 evalModelImplMonolithic( inArgs, outArgs );
307 else if ( !type.compare(
"Teko")|| !type.compare(
"Diagonal") || type ==
"Triangular"|| !type.compare(
"PCD") || !type.compare(
"LSC")){
308 #ifdef FEDD_HAVE_TEKO
309 evalModelImplBlock( inArgs, outArgs );
311 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Teko not found! Build Trilinos with Teko.");
315 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unkown preconditioner/solver type.");
322 template<
class SC,
class LO,
class GO,
class NO>
323 void NonLinearProblem<SC,LO,GO,NO>::evalModelImplMonolithic(
const Thyra::ModelEvaluatorBase::InArgs<SC> &inArgs,
324 const Thyra::ModelEvaluatorBase::OutArgs<SC> &outArgs )
const
328 using Teuchos::rcp_dynamic_cast;
329 using Teuchos::rcp_const_cast;
330 using Teuchos::ArrayView;
331 using Teuchos::Array;
337 TEUCHOS_TEST_FOR_EXCEPTION( inArgs.get_x().is_null(), std::logic_error,
"inArgs.get_x() is null.");
339 RCP< const Thyra::VectorBase< SC > > vecThyra = inArgs.get_x();
340 RCP< Thyra::VectorBase< SC > > vecThyraNonConst = rcp_const_cast<Thyra::VectorBase< SC > >(vecThyra);
342 this->solution_->fromThyraMultiVector(vecThyraNonConst);
345 const RCP<Thyra::MultiVectorBase<SC> > f_out = outArgs.get_f();
346 const RCP<Thyra::LinearOpBase<SC> > W_out = outArgs.get_W_op();
347 const RCP<Thyra::PreconditionerBase<SC> > W_prec_out = outArgs.get_W_prec();
350 typedef Thyra::TpetraOperatorVectorExtraction<SC,LO,GO,NO> tpetra_extract;
351 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> TpetraMatrix_Type;
352 typedef RCP<TpetraMatrix_Type> TpetraMatrixPtr_Type;
353 typedef RCP<const TpetraMatrix_Type> TpetraMatrixConstPtr_Type;
356 const bool fill_f = nonnull(f_out);
357 const bool fill_W = nonnull(W_out);
358 const bool fill_W_prec = nonnull(W_prec_out);
361 if ( fill_f || fill_W || fill_W_prec ) {
369 this->calculateNonLinResidualVec(
"standard");
373 Teuchos::RCP<Thyra::MultiVectorBase<SC> > f_thyra = this->getResidualVector()->getThyraMultiVector();
374 f_out->assign(*f_thyra);
378 TpetraMatrixPtr_Type W;
380 this->assemble(
"Newton");
381 this->setBoundariesSystem();
384 Teuchos::RCP<TpetraOp_Type> W_tpetra = tpetra_extract::getTpetraOperator(W_out);
385 Teuchos::RCP<TpetraMatrix_Type> W_tpetraMat = Teuchos::rcp_dynamic_cast<TpetraMatrix_Type>(W_tpetra);
387 TpetraMatrixConstPtr_Type W_systemTpetra = this->getSystem()->getMergedMatrix()->getTpetraMatrix();
388 TpetraMatrixPtr_Type W_systemTpetraNonConst = rcp_const_cast<TpetraMatrix_Type>(W_systemTpetra);
393 Teuchos::RCP<TpetraMatrix_Type> tpetraMatTpetra = W_systemTpetraNonConst;
395 W_tpetraMat->resumeFill();
397 for (
auto i=0; i<tpetraMatTpetra->getMap()->getLocalNumElements(); i++) {
398 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::local_inds_host_view_type indices;
399 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::values_host_view_type values;
400 tpetraMatTpetra->getLocalRowView( i, indices, values);
401 W_tpetraMat->replaceLocalValues( i, indices, values);
403 W_tpetraMat->fillComplete();
411 int newtonLimit = this->parameterList_->sublist(
"Parameter").get(
"newtonLimit",2);
412 if(this->newtonStep_ < newtonLimit || this->parameterList_->sublist(
"Parameter").get(
"Rebuild Preconditioner every Newton Iteration",
true) )
414 this->setupPreconditioner(
"Monolithic" );
418 std::cout <<
" NonLinearProblem<SC,LO,GO,NO>::evalModelImplMonolithic:: Skipping preconditioner reconstruction" << std::endl;
422 precInitOnly_ =
true;
427 std::string levelCombination = this->parameterList_->sublist(
"ThyraPreconditioner").sublist(
"Preconditioner Types").sublist(
"FROSch").get(
"Level Combination",
"Additive");
428 if (!levelCombination.compare(
"Multiplicative")) {
429 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Multiplicative Level Combination is not supported for NOX.");
432 this->newtonStep_ ++;
441 #ifdef FEDD_HAVE_TEKO
442 template<
class SC,
class LO,
class GO,
class NO>
444 const Thyra::ModelEvaluatorBase::OutArgs<SC> &outArgs )
const
448 using Teuchos::rcp_dynamic_cast;
449 using Teuchos::rcp_const_cast;
450 using Teuchos::ArrayView;
451 using Teuchos::Array;
458 TEUCHOS_TEST_FOR_EXCEPTION( inArgs.get_x().is_null(), std::logic_error,
"inArgs.get_x() is null.");
460 RCP< const Thyra::VectorBase< SC > > vecThyra = inArgs.get_x();
462 RCP< Thyra::VectorBase< SC > > vecThyraNonConst = rcp_const_cast<Thyra::VectorBase< SC > >(vecThyra);
464 RCP< Thyra::ProductVectorBase< SC > > vecThyraBlock = rcp_dynamic_cast<Thyra::ProductVectorBase< SC > > (vecThyraNonConst);
466 this->solution_->getBlockNonConst(0)->fromThyraMultiVector( vecThyraBlock->getNonconstVectorBlock(0) );
467 this->solution_->getBlockNonConst(1)->fromThyraMultiVector( vecThyraBlock->getNonconstVectorBlock(1) );
470 const RCP<Thyra::MultiVectorBase<SC> > f_out = outArgs.get_f();
471 const RCP<Thyra::LinearOpBase<SC> > W_out = outArgs.get_W_op();
472 const RCP<Thyra::PreconditionerBase<SC> > W_prec_out = outArgs.get_W_prec();
475 typedef Thyra::TpetraOperatorVectorExtraction<SC,LO,GO,NO> tpetra_extract;
476 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> TpetraMatrix_Type;
477 typedef RCP<TpetraMatrix_Type> TpetraMatrixPtr_Type;
478 typedef RCP<const TpetraMatrix_Type> TpetraMatrixConstPtr_Type;
481 const bool fill_f = nonnull(f_out);
482 const bool fill_W = nonnull(W_out);
483 const bool fill_W_prec = nonnull(W_prec_out);
485 if ( fill_f || fill_W || fill_W_prec ) {
493 this->calculateNonLinResidualVec(
"standard");
495 Teko::MultiVector f0;
496 Teko::MultiVector f1;
497 f0 = this->getResidualVector()->getBlockNonConst(0)->getThyraMultiVector();
498 f1 = this->getResidualVector()->getBlockNonConst(1)->getThyraMultiVector();
500 std::vector<Teko::MultiVector> f_vec; f_vec.push_back(f0); f_vec.push_back(f1);
502 Teko::MultiVector f = Teko::buildBlockedMultiVector(f_vec);
508 TpetraMatrixPtr_Type W;
511 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> TpetraCrsMatrix;
513 this->assemble(
"Newton");
514 this->setBoundariesSystem();
517 RCP<ThyraBlockOp_Type> W_blocks = rcp_dynamic_cast<ThyraBlockOp_Type>(W_out);
518 RCP<const ThyraOp_Type> W_block00 = W_blocks->getBlock(0,0);
519 RCP<ThyraOp_Type> W_block00NonConst = rcp_const_cast<ThyraOp_Type>( W_block00 );
520 RCP<TpetraOp_Type> W_tpetra = tpetra_extract::getTpetraOperator( W_block00NonConst );
522 RCP<TpetraMatrix_Type> W_tpetraMat = Teuchos::rcp_dynamic_cast<TpetraMatrix_Type>(W_tpetra);
524 TpetraMatrixConstPtr_Type W_matrixTpetra = this->getSystem()->getBlock(0,0)->getTpetraMatrix();
525 TpetraMatrixPtr_Type W_matrixTpetraNonConst = rcp_const_cast<TpetraMatrix_Type>(W_matrixTpetra);
526 RCP<TpetraMatrix_Type> tpetraMatTpetra = W_matrixTpetraNonConst;
528 W_tpetraMat->resumeFill();
530 for (
auto i=0; i<tpetraMatTpetra->getMap()->getLocalNumElements(); i++) {
531 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::local_inds_host_view_type indices;
532 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::values_host_view_type values;
533 tpetraMatTpetra->getLocalRowView( i, indices, values);
534 W_tpetraMat->replaceLocalValues( i, indices, values);
536 W_tpetraMat->fillComplete();
541 std::string type = this->parameterList_->sublist(
"General").get(
"Preconditioner Method",
"Monolithic");
544 int newtonLimit = this->parameterList_->sublist(
"Parameter").get(
"newtonLimit",2);
545 if(this->newtonStep_ < newtonLimit || this->parameterList_->sublist(
"Parameter").get(
"Rebuild Preconditioner every Newton Iteration",
true) )
547 this->setupPreconditioner( type );
551 std::cout <<
" \n NonLinearProblem<SC,LO,GO,NO>::evalModelImplBlock:: Skipping preconditioner reconstruction \n " << std::endl;
555 precInitOnly_ =
true;
559 ParameterListPtr_Type tmpSubList = sublist( sublist( sublist( sublist( this->parameterList_,
"Teko Parameters" ) ,
"Preconditioner Types" ) ,
"Teko" ) ,
"Inverse Factory Library" );
561 std::string levelCombination1 = tmpSubList->sublist(
"FROSch-Velocity" ).get(
"Level Combination",
"Additive");
562 std::string levelCombination2 = tmpSubList->sublist(
"FROSch-Pressure" ).get(
"Level Combination",
"Additive");
564 if ( !levelCombination1.compare(
"Multiplicative") || !levelCombination2.compare(
"Multiplicative") ) {
566 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Multiplicative Level Combination is not supported for NOX.");
567 ParameterListPtr_Type solverPList = this->getLinearSolverBuilder()->getNonconstParameterList();
569 this->newtonStep_ ++;
577 template<
class SC,
class LO,
class GO,
class NO>
580 std::string type = this->parameterList_->sublist(
"General").get(
"Preconditioner Method",
"Monolithic");
581 if ( !type.compare(
"Monolithic"))
582 return create_W_op_Monolithic( );
583 else if ( !type.compare(
"Teko") || !type.compare(
"Diagonal") || !type.compare(
"Triangular") || !type.compare(
"PCD") || !type.compare(
"LSC") ){
584 #ifdef FEDD_HAVE_TEKO
585 return create_W_op_Block( );
587 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Teko not found! Build Trilinos with Teko.");
591 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unkown preconditioner/solver type.");