1#ifndef PRECONDITIONER_START
2#define PRECONDITIONER_START(A,S) Teuchos::RCP<Teuchos::TimeMonitor> A = Teuchos::rcp(new Teuchos::TimeMonitor(*Teuchos::TimeMonitor::getNewTimer(std::string("Preconditioner: ") + std::string(S))));
5#ifndef PRECONDITIONER_STOP
6#define PRECONDITIONER_STOP(A) A.reset();
9#ifndef Preconditioner_DEF_hpp
10#define Preconditioner_DEF_hpp
11#include "Preconditioner_decl.hpp"
12#include <Thyra_DefaultZeroLinearOp_decl.hpp>
13#ifdef FEDD_HAVE_IFPACK2
14#include <Thyra_Ifpack2PreconditionerFactory_def.hpp>
27template <
class SC,
class LO,
class GO,
class NO>
28Preconditioner<SC,LO,GO,NO>::Preconditioner(Problem_Type* problem):
30precondtionerIsBuilt_(false),
46#ifdef PRECONDITIONER_TIMER
47,preconditionerTimer_ (Teuchos::TimeMonitor::getNewCounter(
"Preconditioner: Setup"))
50 problem_.reset( problem,
false );
52 Stratimikos::enableFROSch<LO,GO,NO>( *problem_->getLinearSolverBuilder() );
54#ifdef FEDD_HAVE_IFPACK2
55 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> CRSMat;
56 typedef Tpetra::Operator<SC,LO,GO,NO> TP_op;
57 typedef Thyra::PreconditionerFactoryBase<SC> Base;
58 typedef Thyra::Ifpack2PreconditionerFactory<CRSMat> Impl;
60 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> TpetraCrsMatrix_Type;
61 typedef Teuchos::RCP<TpetraCrsMatrix_Type> TpetraCrsMatrixPtr_Type;
63 problem_->getLinearSolverBuilder()->setPreconditioningStrategyFactory(Teuchos::abstractFactoryStd<Base, Impl>(),
"Ifpack2");
66 Teko::addTekoToStratimikosBuilder( *problem_->getLinearSolverBuilder() );
73template <
class SC,
class LO,
class GO,
class NO>
74Preconditioner<SC,LO,GO,NO>::Preconditioner(TimeProblem_Type* problem):
76precondtionerIsBuilt_(false),
92#ifdef PRECONDITIONER_TIMER
93,preconditionerTimer_ (Teuchos::TimeMonitor::getNewCounter(
"Preconditioner: Setup"))
96 timeProblem_.reset( problem,
false );
98 if(!problem->getUnderlyingProblem()->preconditioner_->getVelocityMassMatrix().is_null()){
99 setVelocityMassMatrix(problem->getUnderlyingProblem()->preconditioner_->getVelocityMassMatrix());
102 if(!problem->getUnderlyingProblem()->preconditioner_->getPressureLaplaceMatrix().is_null()){
103 setPressureLaplaceMatrix(problem->getUnderlyingProblem()->preconditioner_->getPressureLaplaceMatrix());
105 if(!problem->getUnderlyingProblem()->preconditioner_->getPressureMassMatrix().is_null()){
106 setPressureMassMatrix(problem->getUnderlyingProblem()->preconditioner_->getPressureMassMatrix());
109 if(!problem->getUnderlyingProblem()->preconditioner_->getPCDOperatorMatrix().is_null()){
110 setPCDOperator(problem->getUnderlyingProblem()->preconditioner_->getPCDOperatorMatrix());
115template <
class SC,
class LO,
class GO,
class NO>
116Preconditioner<SC,LO,GO,NO>::~Preconditioner()
120template<
class SC,
class LO,
class GO,
class NO>
121void Preconditioner<SC,LO,GO,NO>::setPreconditionerThyraFromLinOp( ThyraLinOpPtr_Type precLinOp ){
122 TEUCHOS_TEST_FOR_EXCEPTION( thyraPrec_.is_null(), std::runtime_error,
"thyraPrec_ is null." );
123 Teuchos::RCP<Thyra::DefaultPreconditioner<SC> > defaultPrec = Teuchos::rcp_dynamic_cast<Thyra::DefaultPreconditioner<SC> > (thyraPrec_);
124 TEUCHOS_TEST_FOR_EXCEPTION( defaultPrec.is_null(), std::runtime_error,
"Cast to DefaultPrecondtioner failed." );
125 TEUCHOS_TEST_FOR_EXCEPTION( precLinOp.is_null(), std::runtime_error,
"precLinOp is null." );
126 defaultPrec->initializeUnspecified( precLinOp );
129template <
class SC,
class LO,
class GO,
class NO>
130typename Preconditioner<SC,LO,GO,NO>::ThyraPrecPtr_Type Preconditioner<SC,LO,GO,NO>::getThyraPrec(){
134template <
class SC,
class LO,
class GO,
class NO>
135typename Preconditioner<SC,LO,GO,NO>::ThyraPrecConstPtr_Type Preconditioner<SC,LO,GO,NO>::getThyraPrecConst()
const{
139template <
class SC,
class LO,
class GO,
class NO>
140void Preconditioner<SC,LO,GO,NO>::initializePreconditioner( std::string type )
142 if ( type ==
"Monolithic" || type ==
"FaCSI" || type ==
"Diagonal" || type ==
"Triangular"){
143 if (type ==
"Monolithic")
144 initPreconditionerMonolithic( );
145 else if (type ==
"FaCSI" || type ==
"Diagonal" || type ==
"Triangular" || type ==
"PCD" || type ==
"LSC")
146 initPreconditionerBlock( );
149 else if (type ==
"Teko" || type ==
"FaCSI-Teko"){
150 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Please construct the Teko precondtioner completely.");
153 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unkown preconditioner type for initialization.");
156template <
class SC,
class LO,
class GO,
class NO>
157void Preconditioner<SC,LO,GO,NO>::initPreconditionerMonolithic( )
160 LinSolverBuilderPtr_Type solverBuilder;
161 Teuchos::RCP<const Thyra::VectorSpaceBase<SC> > thyraRangeSpace;
162 Teuchos::RCP<const Thyra::VectorSpaceBase<SC> > thyraDomainSpace;
164 if (!problem_.is_null()){
165 solverBuilder = problem_->getLinearSolverBuilder();
166 thyraRangeSpace = Thyra::tpetraVectorSpace<SC,LO,GO,NO>( problem_->getSystem()->getMap()->getMergedMap()->getTpetraMap());
167 thyraDomainSpace = Thyra::tpetraVectorSpace<SC,LO,GO,NO>( problem_->getSystem()->getMap()->getMergedMap()->getTpetraMap());
169 else if(!timeProblem_.is_null()){
170 solverBuilder = timeProblem_->getUnderlyingProblem()->getLinearSolverBuilder();
171 thyraRangeSpace = Thyra::tpetraVectorSpace<SC,LO,GO,NO>( timeProblem_->getSystem()->getMap()->getMergedMap()->getTpetraMap() );
172 thyraDomainSpace = Thyra::tpetraVectorSpace<SC,LO,GO,NO>( timeProblem_->getSystem()->getMap()->getMergedMap()->getTpetraMap() );
176 Teuchos::RCP<Thyra::LinearOpBase<SC> > thyraLinOp = Teuchos::rcp(
new Thyra::DefaultZeroLinearOp<SC>( thyraRangeSpace, thyraDomainSpace ) );
178 Teuchos::RCP<Thyra::PreconditionerFactoryBase<SC> > precFactory = solverBuilder->createPreconditioningStrategy(
"");
179 thyraPrec_ = precFactory->createPrec();
181 Teuchos::RCP<Thyra::DefaultPreconditioner<SC> > defaultPrec = Teuchos::rcp_dynamic_cast<Thyra::DefaultPreconditioner<SC> >(thyraPrec_);
183 defaultPrec->initializeUnspecified(thyraLinOp);
186template <
class SC,
class LO,
class GO,
class NO>
187void Preconditioner<SC,LO,GO,NO>::initPreconditionerBlock( )
189 using Teuchos::Array;
192 BlockMultiVectorPtr_Type sol;
193 BlockMultiVectorPtr_Type rhs;
194 LinSolverBuilderPtr_Type solverBuilder;
196 if (!problem_.is_null()){
197 solverBuilder = problem_->getLinearSolverBuilder();
198 size = problem_->getSystem()->size();
199 sol = problem_->getSolution();
200 rhs = problem_->getRhs();
202 else if(!timeProblem_.is_null()){
203 solverBuilder = timeProblem_->getUnderlyingProblem()->getLinearSolverBuilder();
204 size = timeProblem_->getSystem()->size();
205 sol = timeProblem_->getSolution();
206 rhs = timeProblem_->getRhs();
209 Array< RCP< const Thyra::VectorSpaceBase< SC > > > vectorSpacesRange( size );
210 Array< RCP< const Thyra::VectorSpaceBase< SC > > > vectorSpacesDomain( size );
212 for (
int i=0; i<size; i++) {
213 vectorSpacesRange[i] = rhs->getBlock(i)->getMap()->getThyraVectorSpaceBase();
214 vectorSpacesDomain[i] = sol->getBlock(i)->getMap()->getThyraVectorSpaceBase();
217 RCP<const Thyra::DefaultProductVectorSpace<SC> > pR = Thyra::productVectorSpace<SC>( vectorSpacesRange );
218 RCP<const Thyra::DefaultProductVectorSpace<SC> > pD = Thyra::productVectorSpace<SC>( vectorSpacesDomain );
220 RCP<Thyra::LinearOpBase<SC> > thyraLinOp = rcp(
new Thyra::DefaultZeroLinearOp<SC>( pR, pD ) );
222 Teuchos::RCP<Thyra::PreconditionerFactoryBase<SC> > precFactory = solverBuilder->createPreconditioningStrategy(
"");
223 thyraPrec_ = precFactory->createPrec();
225 Teuchos::RCP<Thyra::DefaultPreconditioner<SC> > defaultPrec = Teuchos::rcp_dynamic_cast<Thyra::DefaultPreconditioner<SC> >(thyraPrec_);
227 defaultPrec->initializeUnspecified(thyraLinOp);
230template <
class SC,
class LO,
class GO,
class NO>
231void Preconditioner<SC,LO,GO,NO>::buildPreconditioner( std::string type )
234#ifdef PRECONDITIONER_TIMER
235 CommConstPtr_Type comm;
236 if (!problem_.is_null())
237 comm = problem_->getComm();
238 else if(!timeProblem_.is_null())
239 comm = timeProblem_->getComm();
241 Teuchos::TimeMonitor preconditionerTimeMonitor(*preconditionerTimer_);
244 if (!type.compare(
"Monolithic")){
245 buildPreconditionerMonolithic( );
247 else if (!type.compare(
"Teko")){
249 buildPreconditionerTeko( );
251 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Teko not found! Build Trilinos with Teko.");
254 else if( type ==
"FaCSI" || type ==
"FaCSI-Teko" ){
255 buildPreconditionerFaCSI( type );
257 else if(type ==
"Triangular" || type ==
"Diagonal" || type ==
"PCD" || type ==
"LSC"){
258 buildPreconditionerBlock2x2( );
261 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unkown preconditioner type.");
263#ifdef PRECONDITIONER_TIMER
268template <
class SC,
class LO,
class GO,
class NO>
269void Preconditioner<SC,LO,GO,NO>::buildPreconditionerMonolithic( )
272 CommConstPtr_Type comm;
273 if (!problem_.is_null())
274 comm = problem_->getComm();
275 else if(!timeProblem_.is_null())
276 comm = timeProblem_->getComm();
278 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Preconditioner can not be used without a problem.");
280 bool verbose ( comm->getRank() == 0 );
282 ParameterListPtr_Type parameterList;
284 if (!problem_.is_null())
285 parameterList = problem_->getParameterList();
286 else if(!timeProblem_.is_null())
287 parameterList = timeProblem_->getParameterList();
289 std::string precType = parameterList->sublist(
"ThyraPreconditioner").get(
"Preconditioner Type",
"FROSch");
291 bool useRepeatedMaps = parameterList->get(
"Use repeated maps",
true );
292 bool useNodeLists = parameterList->get(
"Use node lists",
true );
293 ParameterListPtr_Type pListThyraPrec = sublist( parameterList,
"ThyraPreconditioner" );
294 ParameterListPtr_Type plFrosch = sublist( sublist( pListThyraPrec,
"Preconditioner Types" ),
"FROSch");
296 ThyraLinOpConstPtr_Type thyraMatrix;
297 if (!problem_.is_null())
298 thyraMatrix = problem_->getSystem()->getThyraLinOp();
299 else if(!timeProblem_.is_null())
300 thyraMatrix = timeProblem_->getSystemCombined()->getThyraLinOp();
302 UN numberOfBlocks = parameterList->get(
"Number of blocks",1);
304 typedef Tpetra::MultiVector<SC,LO,GO,NO> TMultiVector;
305 typedef Teuchos::RCP<TMultiVector> TMultiVectorPtr;
306 typedef Teuchos::ArrayRCP<TMultiVectorPtr> TMultiVectorPtrVecPtr;
310 typedef Xpetra::MultiVector<SC,LO,GO,NO> XMultiVector;
311 typedef Teuchos::RCP<XMultiVector> XMultiVectorPtr;
312 typedef Teuchos::ArrayRCP<XMultiVectorPtr> XMultiVectorPtrVecPtr;
314 typedef Xpetra::Map<LO,GO,NO> XpetraMap_Type;
315 typedef Teuchos::RCP<XpetraMap_Type> XpetraMapPtr_Type;
316 typedef Teuchos::RCP<const XpetraMap_Type> XpetraMapConstPtr_Type;
317 typedef const XpetraMapConstPtr_Type XpetraMapConstPtrConst_Type;
321 Teuchos::ArrayRCP<Teuchos::RCP<Xpetra::Map<LO,GO,NO> > > repeatedMaps(numberOfBlocks);
324 XMultiVectorPtrVecPtr nodeListVec( numberOfBlocks );
326 nodeListVec = Teuchos::null;
330 if (!precondtionerIsBuilt_) {
331 if ( !precType.compare(
"FROSch") ){
332 Teuchos::ArrayRCP<FROSch::DofOrdering> dofOrderings(numberOfBlocks);
333 Teuchos::ArrayRCP<UN> dofsPerNodeVector(numberOfBlocks);
334 for (UN i = 0; i < numberOfBlocks; i++) {
335 dofsPerNodeVector[i] = (UN) pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").get(
"DofsPerNode" + std::to_string(i+1), 1);
337 if (useRepeatedMaps) {
338 if (dofsPerNodeVector[i] > 1){
340 if (!problem_.is_null()) {
341 if (problem_->getDomain(i)->getFEType() ==
"P0") {
342 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Vector field map not implemented for P0 elements.");
348 MapConstPtr_Type mapConstTmp = problem_->getDomain(i)->getMapVecFieldRepeated();
349 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
350 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
352 repeatedMaps[i] = mapX;
356 else if(!timeProblem_.is_null()){
357 if (timeProblem_->getDomain(i)->getFEType() ==
"P0") {
358 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Vector field map not implemented for P0 elements.");
363 MapConstPtr_Type mapConstTmp = timeProblem_->getDomain(i)->getMapVecFieldRepeated();
364 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
365 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
367 repeatedMaps[i] = mapX;
371 if (!problem_.is_null()){
372 if (problem_->getDomain(i)->getFEType() ==
"P0") {
375 MapConstPtr_Type mapConstTmp = problem_->getDomain(i)->getElementMap();
376 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
377 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
379 repeatedMaps[i] = mapX;
384 MapConstPtr_Type mapConstTmp = problem_->getDomain(i)->getMapRepeated();
385 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
386 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
388 repeatedMaps[i] = mapX;
391 else if (!timeProblem_.is_null()){
392 if (timeProblem_->getDomain(i)->getFEType() ==
"P0") {
395 MapConstPtr_Type mapConstTmp = timeProblem_->getDomain(i)->getElementMap();
396 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
397 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
399 repeatedMaps[i] = mapX;
404 MapConstPtr_Type mapConstTmp = timeProblem_->getDomain(i)->getMapRepeated();
405 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
406 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
408 repeatedMaps[i] = mapX;
415 if (!problem_.is_null()){
416 TEUCHOS_TEST_FOR_EXCEPTION( problem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Node lists cannot be used for P0 elements." );
417 Teuchos::RCP< Tpetra::MultiVector<SC,LO,GO,NO> > nodeListTpetra = problem_->getDomain(i)->getNodeListMV()->getTpetraMultiVectorNonConst();
418 Teuchos::RCP< Xpetra::TpetraMultiVector<SC,LO,GO,NO> > nodeListXpetraTpetra = Teuchos::rcp(
new Xpetra::TpetraMultiVector<SC,LO,GO,NO>(nodeListTpetra));
419 Teuchos::RCP< Xpetra::MultiVector<SC,LO,GO,NO> > nodeListXpetra = Teuchos::rcp_dynamic_cast<Xpetra::MultiVector<SC,LO,GO,NO>>(nodeListXpetraTpetra);
421 nodeListVec[i] = nodeListXpetra;
423 else if (!timeProblem_.is_null()){
424 TEUCHOS_TEST_FOR_EXCEPTION( timeProblem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Node lists cannot be used for P0 elements." );
425 Teuchos::RCP< Tpetra::MultiVector<SC,LO,GO,NO> > nodeListTpetra = timeProblem_->getDomain(i)->getNodeListMV()->getTpetraMultiVectorNonConst();
426 Teuchos::RCP< Xpetra::TpetraMultiVector<SC,LO,GO,NO> > nodeListXpetraTpetra = Teuchos::rcp(
new Xpetra::TpetraMultiVector<SC,LO,GO,NO>(nodeListTpetra));
427 Teuchos::RCP< Xpetra::MultiVector<SC,LO,GO,NO> > nodeListXpetra = Teuchos::rcp_dynamic_cast<Xpetra::MultiVector<SC,LO,GO,NO>>(nodeListXpetraTpetra);
429 nodeListVec[i] = nodeListXpetra;
435 if (!pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").get(
"DofOrdering" + std::to_string(i+1),
"NodeWise" ).compare(
"DimensionWise"))
436 dofOrderings[i] = FROSch::DimensionWise;
437 else if (!pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").get(
"DofOrdering" + std::to_string(i+1),
"NodeWise" ).compare(
"NodeWise"))
438 dofOrderings[i] = FROSch::NodeWise;
440 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Please chose a valid DOF ordering for ThyraPreconditioner(FROSch).");
443 if (!problem_.is_null())
444 dim = problem_->getDomain(0)->getDimension();
445 else if(!timeProblem_.is_null())
446 dim = timeProblem_->getDomain(0)->getDimension();
448 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Dimension", dim);
449 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Repeated Map Vector",repeatedMaps);
450 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Coordinates List Vector",nodeListVec);
451 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"DofOrdering Vector",dofOrderings);
452 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"DofsPerNode Vector",dofsPerNodeVector);
453 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Mpi Ranks Coarse",parameterList->sublist(
"General").get(
"Mpi Ranks Coarse",0) );
459 int lowerBound = 100000000;
461 for (UN i = 0; i < numberOfBlocks; i++) {
462 tuple_intint_Type rankRange;
463 if (!problem_.is_null())
464 rankRange = problem_->getDomain(i)->getMesh()->getRankRange();
465 else if(!timeProblem_.is_null())
466 rankRange = timeProblem_->getDomain(i)->getMesh()->getRankRange();
468 if (std::get<0>(rankRange) < lowerBound)
469 lowerBound = std::get<0>(rankRange);
470 if (std::get<1>(rankRange) > upperBound)
471 upperBound = std::get<1>(rankRange);
474 int lowerBoundCoarse = lowerBound;
475 int upperBoundCoarse = upperBound;
477 if ( parameterList->sublist(
"General").get(
"Mpi Ranks Coarse",0) > 0 ){
478 lowerBoundCoarse = upperBound + 1;
479 upperBoundCoarse = comm->getSize() - 1;
482 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
483 std::cout <<
"\t --- Range for local problems of preconditioner from " << lowerBound <<
" to " << upperBound << std::endl;
484 std::cout <<
"\t --- Range for coarse problem of preconditioner from " << lowerBoundCoarse <<
" to " << upperBoundCoarse << std::endl;
485 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
488 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Local problem ranks lower bound", lowerBound );
489 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Local problem ranks upper bound", upperBound );
491 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Coarse problem ranks lower bound", lowerBoundCoarse );
492 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Coarse problem ranks upper bound", upperBoundCoarse );
499 ParameterListPtr_Type pListThyraSolver = sublist( parameterList,
"ThyraSolver" );
500 pListThyraSolver->setParameters( *pListThyraPrec );
502 LinSolverBuilderPtr_Type solverBuilder;
503 if (!problem_.is_null())
504 solverBuilder = problem_->getLinearSolverBuilder();
505 else if(!timeProblem_.is_null())
506 solverBuilder = timeProblem_->getLinearSolverBuilder();
509 pListPhiExport_ = pListThyraSolver;
511 solverBuilder->setParameterList(pListThyraSolver);
512 precFactory_ = solverBuilder->createPreconditioningStrategy(
"");
514 if ( thyraPrec_.is_null() ){
515 thyraPrec_ = precFactory_->createPrec();
518 Thyra::initializePrec<SC>(*precFactory_, thyraMatrix, thyraPrec_.ptr());
519 precondtionerIsBuilt_ =
true;
523 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unknown preconditioner type; You can only compute a FROSch preconditioner here." );
526 TEUCHOS_TEST_FOR_EXCEPTION( precFactory_.is_null(), std::runtime_error,
"precFactory_ is null.");
527 Thyra::initializePrec<SC>(*precFactory_, thyraMatrix, thyraPrec_.ptr());
530 if (parameterList->sublist(
"Exporter" ).get(
"Export coarse functions",
false))
534template <
class SC,
class LO,
class GO,
class NO>
535void Preconditioner<SC,LO,GO,NO>::buildPreconditionerMonolithicFSI( )
538 CommConstPtr_Type comm;
539 if (!problem_.is_null())
540 comm = problem_->getComm();
541 else if(!timeProblem_.is_null())
542 comm = timeProblem_->getComm();
544 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Preconditioner can not be used without a problem.");
546 bool verbose ( comm->getRank() == 0 );
548 ParameterListPtr_Type parameterList;
550 if (!problem_.is_null())
551 parameterList = problem_->getParameterList();
552 else if(!timeProblem_.is_null())
553 parameterList = timeProblem_->getParameterList();
555 std::string precType = parameterList->sublist(
"ThyraPreconditioner").get(
"Preconditioner Type",
"FROSch");
557 bool useRepeatedMaps = parameterList->get(
"Use repeated maps",
true );
558 bool useNodeLists = parameterList->get(
"Use node lists",
true );
559 ParameterListPtr_Type pListThyraPrec = sublist( parameterList,
"ThyraPreconditioner" );
560 ParameterListPtr_Type plFrosch = sublist( sublist( pListThyraPrec,
"Preconditioner Types" ),
"FROSch");
564 ThyraLinOpConstPtr_Type thyraMatrix;
565 if (!problem_.is_null())
566 thyraMatrix = problem_->getSystem()->getThyraLinOp();
567 else if(!timeProblem_.is_null())
568 thyraMatrix = timeProblem_->getSystemCombined()->getThyraLinOp();
570 UN numberOfBlocks = parameterList->get(
"Number of blocks",1);
571 TEUCHOS_TEST_FOR_EXCEPTION( numberOfBlocks<4 || numberOfBlocks>5, std::logic_error,
"Unknown FSI size." );
574 typedef Tpetra::MultiVector<SC,LO,GO,NO> TMultiVector;
575 typedef Teuchos::RCP<TMultiVector> TMultiVectorPtr;
576 typedef Teuchos::ArrayRCP<TMultiVectorPtr> TMultiVectorPtrVecPtr;
580 typedef Xpetra::MultiVector<SC,LO,GO,NO> XMultiVector;
581 typedef Teuchos::RCP<XMultiVector> XMultiVectorPtr;
582 typedef Teuchos::ArrayRCP<XMultiVectorPtr> XMultiVectorPtrVecPtr;
584 typedef Xpetra::Map<LO,GO,NO> XpetraMap_Type;
585 typedef Teuchos::RCP<XpetraMap_Type> XpetraMapPtr_Type;
586 typedef Teuchos::RCP<const XpetraMap_Type> XpetraMapConstPtr_Type;
587 typedef const XpetraMapConstPtr_Type XpetraMapConstPtrConst_Type;
590 Teuchos::ArrayRCP<Teuchos::RCP<Xpetra::Map<LO,GO,NO> > > repeatedMaps(numberOfBlocks);
593 TMultiVectorPtrVecPtr nodeListVec( numberOfBlocks );
594 nodeListVec = Teuchos::null;
597 if (!precondtionerIsBuilt_) {
598 if ( !precType.compare(
"FROSch") ){
599 Teuchos::ArrayRCP<FROSch::DofOrdering> dofOrderings(numberOfBlocks);
600 Teuchos::ArrayRCP<UN> dofsPerNodeVector(numberOfBlocks);
601 for (UN i = 0; i < numberOfBlocks; i++) {
602 dofsPerNodeVector[i] = (UN) pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").get(
"DofsPerNode" + std::to_string(i+1), 1);
604 TEUCHOS_TEST_FOR_EXCEPTION( timeProblem_.is_null(), std::logic_error,
"FSI time problem is null!" );
605 TEUCHOS_TEST_FOR_EXCEPTION( timeProblem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"We should not be able to use P0 for interface coupling." );
608 MapConstPtr_Type mapConstTmp =timeProblem_->getDomain(i)->getInterfaceMapUnique();
609 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
610 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
612 repeatedMaps[i] = mapX;
615 if (useRepeatedMaps) {
616 if (dofsPerNodeVector[i] > 1){
618 if (!problem_.is_null()) {
619 if (problem_->getDomain(i)->getFEType() ==
"P0") {
620 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Vector field map not implemented for P0 elements.");
626 MapConstPtr_Type mapConstTmp = problem_->getDomain(i)->getMapVecFieldRepeated();
627 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
628 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
630 repeatedMaps[i] = mapX;
633 else if(!timeProblem_.is_null()){
634 if (timeProblem_->getDomain(i)->getFEType() ==
"P0") {
635 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Vector field map not implemented for P0 elements.");
640 MapConstPtr_Type mapConstTmp = timeProblem_->getDomain(i)->getMapVecFieldRepeated();
641 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
642 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
644 repeatedMaps[i] = mapX;
648 if (!problem_.is_null()){
649 if (problem_->getDomain(i)->getFEType() ==
"P0") {
652 MapConstPtr_Type mapConstTmp = problem_->getDomain(i)->getElementMap();
653 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
654 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
658 repeatedMaps[i] = mapX;
663 MapConstPtr_Type mapConstTmp = problem_->getDomain(i)->getMapRepeated();
664 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
665 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
667 Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
668 mapX->describe(*out,Teuchos::VERB_EXTREME);
669 repeatedMaps[i] = mapX;
672 else if (!timeProblem_.is_null()){
673 if (timeProblem_->getDomain(i)->getFEType() ==
"P0") {
676 MapConstPtr_Type mapConstTmp = timeProblem_->getDomain(i)->getElementMap();
677 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
678 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
680 repeatedMaps[i] = mapX;
685 MapConstPtr_Type mapConstTmp = timeProblem_->getDomain(i)->getMapRepeated();
686 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
687 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
689 repeatedMaps[i] = mapX;
695 if (!pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").get(
"DofOrdering" + std::to_string(i+1),
"NodeWise" ).compare(
"DimensionWise"))
696 dofOrderings[i] = FROSch::DimensionWise;
697 else if (!pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").get(
"DofOrdering" + std::to_string(i+1),
"NodeWise" ).compare(
"NodeWise"))
698 dofOrderings[i] = FROSch::NodeWise;
700 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Please chose a valid DOF ordering for ThyraPreconditioner(FROSch).");
705 if (!problem_.is_null())
706 dim = problem_->getDomain(0)->getDimension();
707 else if(!timeProblem_.is_null())
708 dim = timeProblem_->getDomain(0)->getDimension();
710 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Dimension", dim);
711 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Repeated Map Vector",repeatedMaps);
712 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Coordinates List Vector",nodeListVec);
713 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"DofOrdering Vector",dofOrderings);
714 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"DofsPerNode Vector",dofsPerNodeVector);
715 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Mpi Ranks Coarse",parameterList->sublist(
"General").get(
"Mpi Ranks Coarse",0) );
721 int lowerBound = 100000000;
723 for (UN i = 0; i < numberOfBlocks; i++) {
724 tuple_intint_Type rankRange;
725 if (!problem_.is_null())
726 rankRange = problem_->getDomain(i)->getMesh()->getRankRange();
727 else if(!timeProblem_.is_null())
728 rankRange = timeProblem_->getDomain(i)->getMesh()->getRankRange();
730 if (std::get<0>(rankRange) < lowerBound)
731 lowerBound = std::get<0>(rankRange);
732 if (std::get<1>(rankRange) > upperBound)
733 upperBound = std::get<1>(rankRange);
736 int lowerBoundCoarse = lowerBound;
737 int upperBoundCoarse = upperBound;
739 if ( parameterList->sublist(
"General").get(
"Mpi Ranks Coarse",0) > 0 ){
740 lowerBoundCoarse = upperBound + 1;
741 upperBoundCoarse = comm->getSize() - 1;
744 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
745 std::cout <<
"\t --- Range for local problems of preconditioner from " << lowerBound <<
" to " << upperBound << std::endl;
746 std::cout <<
"\t --- Range for coarse problem of preconditioner from " << lowerBoundCoarse <<
" to " << upperBoundCoarse << std::endl;
747 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
750 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Local problem ranks lower bound", lowerBound );
751 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Local problem ranks upper bound", upperBound );
753 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Coarse problem ranks lower bound", lowerBoundCoarse );
754 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Coarse problem ranks upper bound", upperBoundCoarse );
761 ParameterListPtr_Type pListThyraSolver = sublist( parameterList,
"ThyraSolver" );
762 pListThyraSolver->setParameters( *pListThyraPrec );
764 LinSolverBuilderPtr_Type solverBuilder;
765 if (!problem_.is_null())
766 solverBuilder = problem_->getLinearSolverBuilder();
767 else if(!timeProblem_.is_null())
768 solverBuilder = timeProblem_->getUnderlyingProblem()->getLinearSolverBuilder();
771 pListPhiExport_ = pListThyraSolver;
773 solverBuilder->setParameterList(pListThyraSolver);
774 precFactory_ = solverBuilder->createPreconditioningStrategy(
"");
776 if ( thyraPrec_.is_null() )
777 thyraPrec_ = precFactory_->createPrec();
780 Thyra::initializePrec<SC>(*precFactory_, thyraMatrix, thyraPrec_.ptr());
781 precondtionerIsBuilt_ =
true;
785 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unknown preconditioner type; You can only compute a FROSch preconditioner here." );
788 TEUCHOS_TEST_FOR_EXCEPTION( precFactory_.is_null(), std::runtime_error,
"precFactory_ is null.");
789 Thyra::initializePrec<SC>(*precFactory_, thyraMatrix, thyraPrec_.ptr());
792 if (parameterList->sublist(
"Exporter" ).get(
"Export coarse functions",
false))
793 exportCoarseBasisFSI();
799template <
class SC,
class LO,
class GO,
class NO>
800void Preconditioner<SC,LO,GO,NO>::buildPreconditionerTeko( )
803 Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
805 ParameterListPtr_Type parameterList;
806 if (!problem_.is_null())
807 parameterList = problem_->getParameterList();
808 else if(!timeProblem_.is_null())
809 parameterList = timeProblem_->getParameterList();
811 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Preconditioner can not be used without a problem.");
814 LinSolverBuilderPtr_Type solverBuilder;
815 if (!problem_.is_null())
816 solverBuilder = problem_->getLinearSolverBuilder();
817 else if(!timeProblem_.is_null())
818 solverBuilder = timeProblem_->getUnderlyingProblem()->getLinearSolverBuilder();
820 ParameterListPtr_Type tekoPList= sublist( parameterList,
"Teko Parameters" );
822 if (precFactory_.is_null()) {
823 ParameterListPtr_Type tmpSubList = sublist( sublist( sublist( sublist( parameterList,
"Teko Parameters" ) ,
"Preconditioner Types" ) ,
"Teko" ) ,
"Inverse Factory Library" );
826 if ( !tmpSubList->sublist(
"FROSch-Pressure").get(
"Type",
"FROSch").compare(
"FROSch") &&
827 !tmpSubList->sublist(
"FROSch-Velocity").get(
"Type",
"FROSch").compare(
"FROSch") ) {
828 setVelocityParameters( tekoPList, parameterList->sublist(
"General").get(
"Mpi Ranks Coarse",0) );
829 setPressureParameters( tekoPList, parameterList->sublist(
"General").get(
"Mpi Ranks Coarse",0) );
833 BlockMatrixPtr_Type system;
834 if (!problem_.is_null())
835 system = problem_->getSystem();
836 else if(!timeProblem_.is_null())
837 system = timeProblem_->getSystemCombined();
839 TEUCHOS_TEST_FOR_EXCEPTION( system->size()!=2, std::logic_error,
"Wrong size of system for Teko-Block-Preconditioners.");
841 Teko::LinearOp thyraF = system->getBlock(0,0)->getThyraLinOp();
842 Teko::LinearOp thyraBT = system->getBlock(0,1)->getThyraLinOp();
843 Teko::LinearOp thyraB = system->getBlock(1,0)->getThyraLinOp();
845 if (!system->blockExists(1,1)){
846 MatrixPtr_Type dummy;
847 dummy.reset(
new Matrix_Type( system->getBlock(1,0)->getMap(), 1 ) );
848 dummy->fillComplete();
849 system->addBlock( dummy, 1, 1 );
851 Teko::LinearOp thyraC = system->getBlock(1,1)->getThyraLinOp();
853 tekoLinOp_ = Thyra::block2x2(thyraF,thyraBT,thyraB,thyraC);
855 if (!precondtionerIsBuilt_) {
856 if ( precFactory_.is_null() ){
857 ParameterListPtr_Type pListThyraSolver = sublist( parameterList,
"ThyraSolver" );
859 pListThyraSolver->setParameters( *tekoPList );
861 solverBuilder->setParameterList( pListThyraSolver );
862 precFactory_ = solverBuilder->createPreconditioningStrategy(
"");
864 rh_.reset(
new Teko::RequestHandler());
866 if(!tekoPList->sublist(
"Preconditioner Types").sublist(
"Teko").get(
"Inverse Type",
"SIMPLE").compare(
"LSC") ||
867 !tekoPList->sublist(
"Preconditioner Types").sublist(
"Teko").get(
"Inverse Type",
"SIMPLE").compare(
"LSC-Pressure-Laplace") ||
868 !tekoPList->sublist(
"Preconditioner Types").sublist(
"Teko").get(
"Inverse Type",
"SIMPLE").compare(
"SIMPLE")){
869 Teko::LinearOp thyraMass = velocityMassMatrix_;
870 Teuchos::RCP< Teko::StaticRequestCallback<Teko::LinearOp> > callbackMass = Teuchos::rcp(
new Teko::StaticRequestCallback<Teko::LinearOp> (
"Velocity Mass Matrix", thyraMass ) );
871 rh_->addRequestCallback( callbackMass );
873 Teko::LinearOp thyraLaplace = pressureLaplace_;
875 Teuchos::RCP< Teko::StaticRequestCallback<Teko::LinearOp> > callbackLaplace = Teuchos::rcp(
new Teko::StaticRequestCallback<Teko::LinearOp> (
"Pressure Laplace Operator", thyraLaplace ) );
876 rh_->addRequestCallback( callbackLaplace );
878 else if(!tekoPList->sublist(
"Preconditioner Types").sublist(
"Teko").get(
"Inverse Type",
"SIMPLE").compare(
"PCD")){
881 Teko::LinearOp thyraMass = velocityMassMatrix_;
882 Teuchos::RCP< Teko::StaticRequestCallback<Teko::LinearOp> > callbackMass = Teuchos::rcp(
new Teko::StaticRequestCallback<Teko::LinearOp> (
"Velocity Mass Matrix", thyraMass ) );
883 rh_->addRequestCallback( callbackMass );
886 Teko::LinearOp thyraLaplace = pressureLaplace_;
887 Teuchos::RCP< Teko::StaticRequestCallback<Teko::LinearOp> > callbackLaplace = Teuchos::rcp(
new Teko::StaticRequestCallback<Teko::LinearOp> (
"Pressure Laplace Operator", thyraLaplace ) );
888 rh_->addRequestCallback( callbackLaplace );
891 Teko::LinearOp thyraPressureMass = pressureMass_;
892 Teuchos::RCP< Teko::StaticRequestCallback<Teko::LinearOp> > callbackPressureMass = Teuchos::rcp(
new Teko::StaticRequestCallback<Teko::LinearOp> (
"Pressure Mass Matrix", thyraPressureMass ) );
893 rh_->addRequestCallback( callbackPressureMass );
896 if (!timeProblem_.is_null()){
897 timeProblem_->assemble(
"UpdateConvectionDiffusionOperator");
900 problem_->assemble(
"UpdateConvectionDiffusionOperator");
902 Teko::LinearOp thyraPCD = pcdOperator_;
903 callbackPCD_ = Teuchos::rcp(
new Teko::StaticRequestCallback<Teko::LinearOp> (
"PCD Operator", thyraPCD ) );
904 rh_->addRequestCallback( callbackPCD_ );
907 Teuchos::RCP< Teko::StratimikosFactory > tekoFactory = Teuchos::rcp_dynamic_cast<Teko::StratimikosFactory>(precFactory_);
908 tekoFactory->setRequestHandler( rh_ );
912 if ( thyraPrec_.is_null() ){
913 thyraPrec_ = precFactory_->createPrec();
916 Teuchos::RCP< const Thyra::DefaultLinearOpSource< SC > > thyraMatrixSourceOp = defaultLinearOpSource (tekoLinOp_);
919 precFactory_->initializePrec(thyraMatrixSourceOp, thyraPrec_.get());
920 precondtionerIsBuilt_ =
true;
924 if(!tekoPList->sublist(
"Preconditioner Types").sublist(
"Teko").get(
"Inverse Type",
"SIMPLE").compare(
"PCD")){
928 if (!timeProblem_.is_null()){
929 timeProblem_->assemble(
"UpdateConvectionDiffusionOperator");
932 problem_->assemble(
"UpdateConvectionDiffusionOperator");
934 Teuchos::RCP<Teko::RequestHandler> rh = Teuchos::rcp(
new Teko::RequestHandler());
937 Teko::LinearOp thyraPCD;
942 if(!timeProblem_.is_null())
945 pcdOperator_ = timeProblem_->getUnderlyingProblem()->preconditioner_->getPCDOperatorMatrix()->getThyraLinOp();
946 thyraPCD = timeProblem_->getUnderlyingProblem()->preconditioner_->getPCDOperatorMatrix()->getThyraLinOp();
949 thyraPCD= pcdOperator_;
952 Teuchos::RCP< Teko::StaticRequestCallback<Teko::LinearOp> > callbackTmp = Teuchos::rcp(
new Teko::StaticRequestCallback<Teko::LinearOp> (
"PCD Operator", thyraPCD ) );
953 *callbackPCD_ = *callbackTmp;
957 Teuchos::RCP< const Thyra::DefaultLinearOpSource< SC > > thyraMatrixSourceOp = defaultLinearOpSource (tekoLinOp_);
960 precFactory_->initializePrec(thyraMatrixSourceOp, thyraPrec_.get());
965template <
class SC,
class LO,
class GO,
class NO>
966void Preconditioner<SC,LO,GO,NO>::buildPreconditionerFaCSI( std::string type )
968 typedef Domain<SC,LO,GO,NO> Domain_Type;
969 typedef Teuchos::RCP<const Domain_Type> DomainConstPtr_Type;
970 typedef std::vector<DomainConstPtr_Type> DomainConstPtr_vec_Type;
972 Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
974 ParameterListPtr_Type parameterList;
975 if (!timeProblem_.is_null())
976 parameterList = timeProblem_->getParameterList();
978 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Preconditioner can not be used without a time problem.");
981 ProblemPtr_Type steadyProblem = timeProblem_->getUnderlyingProblem();
982 Teuchos::RCP< FSI<SC,LO,GO,NO> > steadyFSI = Teuchos::rcp_dynamic_cast<FSI<SC,LO,GO,NO> >(steadyProblem);
983 BlockMatrixPtr_Type fsiSystem = timeProblem_->getSystemCombined();
985 ParameterListPtr_Type pLFluid = steadyFSI->getFluidProblem()->getParameterList();
987 std::string precTypeFluid;
989 precTypeFluid =
"Monolithic";
990 else if (type ==
"FaCSI-Teko")
991 precTypeFluid =
"Teko";
993 CommConstPtr_Type comm = timeProblem_->getComm();
994 bool useFluidPreconditioner = parameterList->sublist(
"General").get(
"Use Fluid Preconditioner",
true);
995 bool useSolidPreconditioner = parameterList->sublist(
"General").get(
"Use Solid Preconditioner",
true);
996 bool onlyDiagonal = parameterList->sublist(
"General").get(
"Only Diagonal",
false);
997 Teuchos::RCP< PrecOpFaCSI<SC,LO,GO,NO> > facsi
998 = Teuchos::rcp(
new PrecOpFaCSI<SC,LO,GO,NO> ( comm, precTypeFluid ==
"Monolithic", useFluidPreconditioner, useSolidPreconditioner, onlyDiagonal) );
1000 if (comm->getRank() == 0) {
1002 std::cout <<
"\t### No preconditioner will be used! ###" << std::endl;
1004 std::cout <<
"\t### FaCSI standard ###" << std::endl;
1009 if (probFluid_.is_null()){
1010 probFluid_ = Teuchos::rcp(
new MinPrecProblem_Type( pLFluid, timeProblem_->getComm() ) );
1011 DomainConstPtr_vec_Type fluidDomains = steadyFSI->getFluidProblem()->getDomainVector();
1012 probFluid_->initializeDomains( fluidDomains );
1013 probFluid_->initializeLinSolverBuilder( timeProblem_->getLinearSolverBuilder() );
1016 BlockMatrixPtr_Type fluidSystem = Teuchos::rcp(
new BlockMatrix_Type(2) );
1019 MatrixPtr_Type f = Teuchos::rcp(
new Matrix_Type( fsiSystem->getBlock(0,0) ) );
1020 MatrixPtr_Type bt = Teuchos::rcp(
new Matrix_Type( fsiSystem->getBlock(0,1) ) );
1021 MatrixPtr_Type b = Teuchos::rcp(
new Matrix_Type( fsiSystem->getBlock(1,0) ) );
1023 if ( fsiSystem->blockExists(1,1) )
1024 c = Teuchos::rcp(
new Matrix_Type( fsiSystem->getBlock(1,1) ) );
1025 fluidSystem->addBlock( f, 0, 0 );
1026 fluidSystem->addBlock( bt, 0, 1 );
1027 fluidSystem->addBlock( b, 1, 0 );
1028 if ( fsiSystem->blockExists(1,1) )
1029 fluidSystem->addBlock( c, 1, 1 );
1031 faCSIBCFactory_->setSystem( fluidSystem );
1033 probFluid_->initializeSystem( fluidSystem );
1035 probFluid_->setupPreconditioner( precTypeFluid );
1037 precFluid_ = probFluid_->getPreconditioner()->getThyraPrec()->getNonconstUnspecifiedPrecOp();
1040 bool nonlinearStructure =
false;
1041 if (steadyFSI->getStructureProblem().is_null())
1042 nonlinearStructure =
true;
1044 ParameterListPtr_Type pLStructure;
1045 if (nonlinearStructure)
1046 pLStructure = steadyFSI->getNonLinStructureProblem()->getParameterList();
1048 pLStructure = steadyFSI->getStructureProblem()->getParameterList();
1050 if (probSolid_.is_null()){
1051 probSolid_ = Teuchos::rcp(
new MinPrecProblem_Type( pLStructure, timeProblem_->getComm() ) );
1052 DomainConstPtr_vec_Type structDomain;
1053 if (nonlinearStructure)
1054 structDomain = steadyFSI->getNonLinStructureProblem()->getDomainVector();
1056 structDomain = steadyFSI->getStructureProblem()->getDomainVector();
1058 probSolid_->initializeDomains( structDomain );
1059 probSolid_->initializeLinSolverBuilder( timeProblem_->getLinearSolverBuilder() );
1062 BlockMatrixPtr_Type structSystem = Teuchos::rcp(
new BlockMatrix_Type(1) );
1064 structSystem->addBlock( fsiSystem->getBlock(2,2), 0, 0 );
1066 probSolid_->initializeSystem( structSystem );
1068 probSolid_->setupPreconditioner( );
1070 precStruct_ = probSolid_->getPreconditioner()->getThyraPrec()->getNonconstUnspecifiedPrecOp();
1075 if (timeProblem_->getSystem()->size()>4) {
1076 ParameterListPtr_Type pLGeometry = steadyFSI->getGeometryProblem()->getParameterList();
1077 if (probGeo_.is_null()) {
1078 probGeo_ = Teuchos::rcp(
new MinPrecProblem_Type( pLGeometry, timeProblem_->getComm() ) );
1079 DomainConstPtr_vec_Type geoDomain = steadyFSI->getGeometryProblem()->getDomainVector();
1080 probGeo_->initializeDomains( geoDomain );
1081 probGeo_->initializeLinSolverBuilder( timeProblem_->getLinearSolverBuilder() );
1084 BlockMatrixPtr_Type geoSystem = Teuchos::rcp(
new BlockMatrix_Type(1) );
1086 geoSystem->addBlock( fsiSystem->getBlock(4,4), 0, 0 );
1088 probGeo_->initializeSystem( geoSystem );
1090 probGeo_->setupPreconditioner( );
1092 precGeo_ = probGeo_->getPreconditioner()->getThyraPrec()->getNonconstUnspecifiedPrecOp();
1095 if (fsiSystem->size()>4) {
1097 facsi->setGIShape( fsiSystem->getBlock(3,0)->getThyraLinOpNonConst(),
1098 fsiSystem->getBlock(0,3)->getThyraLinOpNonConst(),
1099 fsiSystem->getBlock(3,2)->getThyraLinOpNonConst(),
1100 fsiSystem->getBlock(4,2)->getThyraLinOpNonConst(),
1103 fsiSystem->getBlock(0,0)->getThyraLinOpNonConst(),
1104 fsiSystem->getBlock(0,1)->getThyraLinOpNonConst(),
1106 fsiSystem->getBlock(0,4)->getThyraLinOpNonConst(),
1107 fsiSystem->getBlock(1,4)->getThyraLinOpNonConst() );
1110 facsi->setGI( fsiSystem->getBlock(3,0)->getThyraLinOpNonConst(),
1111 fsiSystem->getBlock(0,3)->getThyraLinOpNonConst(),
1112 fsiSystem->getBlock(3,2)->getThyraLinOpNonConst(),
1113 fsiSystem->getBlock(4,2)->getThyraLinOpNonConst(),
1116 fsiSystem->getBlock(0,0)->getThyraLinOpNonConst(),
1117 fsiSystem->getBlock(0,1)->getThyraLinOpNonConst(),
1122 facsi->setGE( fsiSystem->getBlock(3,0)->getThyraLinOpNonConst(),
1123 fsiSystem->getBlock(0,3)->getThyraLinOpNonConst(),
1124 fsiSystem->getBlock(3,2)->getThyraLinOpNonConst(),
1127 fsiSystem->getBlock(0,0)->getThyraLinOpNonConst(),
1128 fsiSystem->getBlock(0,1)->getThyraLinOpNonConst() );
1131 LinSolverBuilderPtr_Type solverBuilder = timeProblem_->getUnderlyingProblem()->getLinearSolverBuilder();
1133 if ( precFactory_.is_null() )
1134 precFactory_ = solverBuilder->createPreconditioningStrategy(
"");
1136 if ( thyraPrec_.is_null() )
1137 thyraPrec_ = precFactory_->createPrec();
1139 Teuchos::RCP< Thyra::DefaultPreconditioner<SC> > defaultPrec =
1140 Teuchos::rcp_dynamic_cast< Thyra::DefaultPreconditioner<SC> > (thyraPrec_);
1141 ThyraLinOpPtr_Type linOp =
1142 Teuchos::rcp_dynamic_cast< Thyra::LinearOpBase<SC> > (facsi);
1144 defaultPrec->initializeUnspecified( linOp );
1146 precondtionerIsBuilt_ =
true;
1150template <
class SC,
class LO,
class GO,
class NO>
1151void Preconditioner<SC,LO,GO,NO>::setPressureMassMatrix(MatrixPtr_Type massMatrix)
const{
1152 pressureMassMatrixPtr_ = massMatrix;
1153 pressureMass_= massMatrix->getThyraLinOp();
1156template <
class SC,
class LO,
class GO,
class NO>
1157void Preconditioner<SC,LO,GO,NO>::setPressureLaplaceMatrix(MatrixPtr_Type matrix)
const{
1158 pressureLaplace_ =matrix->getThyraLinOp();
1159 pressureLaplaceMatrixPtr_ = matrix;
1168template <
class SC,
class LO,
class GO,
class NO>
1169void Preconditioner<SC,LO,GO,NO>::setPCDOperator(MatrixPtr_Type matrix)
const{
1170 pcdOperator_ = matrix->getThyraLinOp();
1171 pcdOperatorMatrixPtr_ = matrix;
1182template <
class SC,
class LO,
class GO,
class NO>
1183void Preconditioner<SC,LO,GO,NO>::buildPreconditionerBlock2x2( )
1185 PRECONDITIONER_START(buildPreconditionerBlock2x2,
" buildPreconditionerBlock2x2");
1187 typedef Domain<SC,LO,GO,NO> Domain_Type;
1188 typedef Teuchos::RCP<const Domain_Type> DomainConstPtr_Type;
1189 typedef std::vector<DomainConstPtr_Type> DomainConstPtr_vec_Type;
1191 Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
1193 ParameterListPtr_Type parameterList;
1194 BlockMatrixPtr_Type system;
1195 CommConstPtr_Type comm;
1196 ProblemPtr_Type steadyProblem;
1197 if (!timeProblem_.is_null()){
1198 parameterList = timeProblem_->getParameterList();
1199 system = timeProblem_->getSystemCombined();
1200 comm = timeProblem_->getComm();
1201 steadyProblem = timeProblem_->getUnderlyingProblem();
1204 parameterList = problem_->getParameterList();
1205 system = problem_->getSystem();
1206 comm = problem_->getComm();
1207 steadyProblem = problem_;
1210 bool verbose( comm->getRank() == 0 );
1213 std::cout <<
" ######################## " << std::endl;
1214 std::cout <<
" Build 2x2 Preconditioner " << std::endl;
1215 std::cout <<
" ######################## " << std::endl;
1217 ParameterListPtr_Type plVelocity(
new Teuchos::ParameterList( parameterList->sublist(
"Velocity preconditioner") ) );
1218 ParameterListPtr_Type plSchur(
new Teuchos::ParameterList( parameterList->sublist(
"Schur complement preconditioner") ) );
1221 plVelocity->sublist(
"General").setParameters(parameterList->sublist(
"General"));
1222 plSchur->sublist(
"General").setParameters(parameterList->sublist(
"General"));
1224 Teuchos::RCP< PrecBlock2x2<SC,LO,GO,NO> > blockPrec2x2
1225 = Teuchos::rcp(
new PrecBlock2x2<SC,LO,GO,NO> ( comm ) );
1228 if (probVelocity_.is_null()){
1229 probVelocity_ = Teuchos::rcp(
new MinPrecProblem_Type( plVelocity, comm ) );
1230 DomainConstPtr_vec_Type domain1(0);
1231 domain1.push_back( steadyProblem->getDomain(0) );
1232 probVelocity_->initializeDomains( domain1 );
1233 probVelocity_->initializeLinSolverBuilder( steadyProblem->getLinearSolverBuilder() );
1236 BlockMatrixPtr_Type system1 = Teuchos::rcp(
new BlockMatrix_Type(1) );
1238 MatrixPtr_Type F = system->getBlock(0,0);
1240 system1->addBlock( F, 0, 0 );
1242 probVelocity_->initializeSystem( system1 );
1244 PRECONDITIONER_START(setupFInv,
" Setup Preconditioner for F");
1245 probVelocity_->setupPreconditioner(
"Monolithic" );
1246 PRECONDITIONER_STOP(setupFInv);
1248 precVelocity_ = probVelocity_->getPreconditioner()->getThyraPrec()->getNonconstUnspecifiedPrecOp();
1250 if (probSchur_.is_null()) {
1251 if(!timeProblem_.is_null()){
1252 probSchur_ = Teuchos::rcp(
new MinPrecProblem_Type( plSchur, comm ) );
1253 DomainConstPtr_vec_Type domain2(0);
1254 domain2.push_back( timeProblem_->getDomain(1) );
1255 probSchur_->initializeDomains( domain2 );
1256 probSchur_->initializeLinSolverBuilder( timeProblem_->getLinearSolverBuilder() );
1260 probSchur_ = Teuchos::rcp(
new MinPrecProblem_Type( plSchur, comm ) );
1261 DomainConstPtr_vec_Type domain2(0);
1262 domain2.push_back( problem_->getDomain(1) );
1263 probSchur_->initializeDomains( domain2 );
1264 probSchur_->initializeLinSolverBuilder( problem_->getLinearSolverBuilder() );
1269 std::string type = parameterList->sublist(
"General").get(
"Preconditioner Method",
"Diagonal");
1273 PRECONDITIONER_START(setupSInv,
" Setup Preconditioner for S");
1275 if(type ==
"Diagonal" || type ==
"Triangular"){
1276 BlockMatrixPtr_Type Mp = Teuchos::rcp(
new BlockMatrix_Type(1) );
1278 Mp->addBlock( pressureMassMatrixPtr_, 0, 0 );
1280 probSchur_->initializeSystem( Mp );
1282 probSchur_->setupPreconditioner(
"Monolithic" );
1284 precSchur_ = probSchur_->getPreconditioner()->getThyraPrec()->getNonconstUnspecifiedPrecOp();
1286 else if (type ==
"PCD") {
1291 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
1292 std::cout <<
"\t --- Building PCD Operator Components " << std::endl;
1293 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
1296 if (probLaplace_.is_null()) {
1297 if (!timeProblem_.is_null()){
1298 probLaplace_ = Teuchos::rcp(
new MinPrecProblem_Type( plSchur, comm ) );
1299 DomainConstPtr_vec_Type domain2(0);
1300 domain2.push_back( timeProblem_->getDomain(1) );
1301 probLaplace_->initializeDomains( domain2 );
1302 probLaplace_->initializeLinSolverBuilder( timeProblem_->getLinearSolverBuilder() );
1305 probLaplace_ = Teuchos::rcp(
new MinPrecProblem_Type( plSchur, comm ) );
1306 DomainConstPtr_vec_Type domain2(0);
1307 domain2.push_back( problem_->getDomain(1) );
1308 probLaplace_->initializeDomains( domain2 );
1309 probLaplace_->initializeLinSolverBuilder( problem_->getLinearSolverBuilder() );
1313 if(laplaceInverse_.is_null()){
1315 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
1316 std::cout <<
"\t --- PCD: Setup A_p Schwarz Approximation " << std::endl;
1317 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
1319 BlockMatrixPtr_Type Ap = Teuchos::rcp(
new BlockMatrix_Type(1) );
1320 Ap->addBlock(pressureLaplaceMatrixPtr_,0,0);
1322 probLaplace_->initializeSystem( Ap );
1324 probLaplace_->setupPreconditioner(
"Monolithic" );
1325 laplaceInverse_ = probLaplace_->getPreconditioner()->getThyraPrec()->getNonconstUnspecifiedPrecOp();
1328 if (probMass_.is_null()) {
1329 if (!timeProblem_.is_null()){
1330 probMass_ = Teuchos::rcp(
new MinPrecProblem_Type( plSchur, comm ) );
1331 DomainConstPtr_vec_Type domain2(0);
1332 domain2.push_back( timeProblem_->getDomain(1) );
1333 probMass_->initializeDomains( domain2 );
1334 probMass_->initializeLinSolverBuilder( timeProblem_->getLinearSolverBuilder() );
1337 probMass_ = Teuchos::rcp(
new MinPrecProblem_Type( plSchur, comm ) );
1338 DomainConstPtr_vec_Type domain2(0);
1339 domain2.push_back( problem_->getDomain(1) );
1340 probMass_->initializeDomains( domain2 );
1341 probMass_->initializeLinSolverBuilder( problem_->getLinearSolverBuilder() );
1345 if(massMatrixInverse_.is_null()){
1347 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
1348 std::cout <<
"\t --- PCD: Setup M_p Schwarz Approximation " << std::endl;
1349 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
1351 BlockMatrixPtr_Type Qp = Teuchos::rcp(
new BlockMatrix_Type(1) );
1352 Qp->addBlock(pressureMassMatrixPtr_,0,0);
1356 bool explicitInverse = parameterList->sublist(
"General").get(
"Mu Explicit Inverse",
true);
1357 std::string typeDiag = parameterList->sublist(
"General").get(
"Diagonal Approximation",
"Diagonal");
1361 probMass_->initializeSystem( Qp );
1362 probMass_->setupPreconditioner(
"Monolithic" );
1363 massMatrixInverse_ = probMass_->getPreconditioner()->getThyraPrec()->getNonconstUnspecifiedPrecOp();
1367 massMatrixInverse_ = pressureMassMatrixPtr_->buildDiagonalInverse(typeDiag)->getThyraLinOpNonConst() ;
1372 else if (type ==
"LSC") {
1375 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
1376 std::cout <<
"\t --- Building LSC Operator Components " << std::endl;
1377 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
1380 if (probLaplace_.is_null()) {
1381 if (!timeProblem_.is_null()){
1382 probLaplace_ = Teuchos::rcp(
new MinPrecProblem_Type( plSchur, comm ) );
1383 DomainConstPtr_vec_Type domain2(0);
1384 domain2.push_back( timeProblem_->getDomain(1) );
1385 probLaplace_->initializeDomains( domain2 );
1386 probLaplace_->initializeLinSolverBuilder( timeProblem_->getLinearSolverBuilder() );
1389 probLaplace_ = Teuchos::rcp(
new MinPrecProblem_Type( plSchur, comm ) );
1390 DomainConstPtr_vec_Type domain2(0);
1391 domain2.push_back( problem_->getDomain(1) );
1392 probLaplace_->initializeDomains( domain2 );
1393 probLaplace_->initializeLinSolverBuilder( problem_->getLinearSolverBuilder() );
1397 BlockMatrixPtr_Type Ap = Teuchos::rcp(
new BlockMatrix_Type(1) );
1398 Ap->addBlock(pressureLaplaceMatrixPtr_,0,0);
1400 probLaplace_->initializeSystem( Ap );
1402 probLaplace_->setupPreconditioner(
"Monolithic" );
1403 laplaceInverse_ = probLaplace_->getPreconditioner()->getThyraPrec()->getNonconstUnspecifiedPrecOp();
1405 if (probVMass_.is_null()) {
1406 if (!timeProblem_.is_null()){
1407 probVMass_ = Teuchos::rcp(
new MinPrecProblem_Type( plVelocity, comm ) );
1408 DomainConstPtr_vec_Type domain1(0);
1409 domain1.push_back( timeProblem_->getDomain(0) );
1410 probVMass_->initializeDomains( domain1 );
1411 probVMass_->initializeLinSolverBuilder( timeProblem_->getLinearSolverBuilder() );
1414 probVMass_ = Teuchos::rcp(
new MinPrecProblem_Type( plVelocity, comm ) );
1415 DomainConstPtr_vec_Type domain1(0);
1416 domain1.push_back( problem_->getDomain(0) );
1417 probVMass_->initializeDomains( domain1 );
1418 probVMass_->initializeLinSolverBuilder( problem_->getLinearSolverBuilder() );
1421 BlockMatrixPtr_Type Qv = Teuchos::rcp(
new BlockMatrix_Type(1) );
1422 Qv->addBlock(velocityMassMatrixMatrixPtr_,0,0);
1426 bool explicitInverse = parameterList->sublist(
"General").get(
"Mu Explicit Inverse",
true);
1427 std::string typeDiag = parameterList->sublist(
"General").get(
"Diagonal Approximation",
"Diagonal");
1431 probVMass_->initializeSystem( Qv );
1432 probVMass_->setupPreconditioner(
"Monolithic" );
1433 massMatrixVInverse_ = probVMass_->getPreconditioner()->getThyraPrec()->getNonconstUnspecifiedPrecOp();
1437 massMatrixVInverse_ = velocityMassMatrixMatrixPtr_->buildDiagonalInverse(typeDiag)->getThyraLinOpNonConst() ;
1441 PRECONDITIONER_STOP(setupSInv);
1445 if (type ==
"Diagonal") {
1446 blockPrec2x2->setDiagonal(precVelocity_,
1449 else if (type ==
"Triangular") {
1450 ThyraLinOpPtr_Type BT = system->getBlock(0,1)->getThyraLinOpNonConst();
1451 blockPrec2x2->setTriangular(precVelocity_,
1455 else if (type ==
"PCD") {
1456 if (!timeProblem_.is_null()){
1457 timeProblem_->assemble(
"UpdateConvectionDiffusionOperator");
1460 problem_->assemble(
"UpdateConvectionDiffusionOperator");
1462 MatrixPtr_Type pcdOperatorScaled = Teuchos::rcp(
new Matrix_Type( pcdOperatorMatrixPtr_ ) );
1463 pcdOperatorScaled->resumeFill();
1464 pcdOperatorScaled->scale(-1.0);
1465 pcdOperatorScaled->fillComplete();
1466 ThyraLinOpPtr_Type BT = system->getBlock(0,1)->getThyraLinOpNonConst();
1467 blockPrec2x2->setTriangular(precVelocity_,
1469 pcdOperatorScaled->getThyraLinOpNonConst(),
1471 massMatrixVInverse_,
1473 ThyraLinOpPtr_Type B = system->getBlock(1,0)->getThyraLinOpNonConst();
1474 blockPrec2x2->setB(B);
1476 else if (type ==
"LSC") {
1477 ThyraLinOpPtr_Type BT = system->getBlock(0,1)->getThyraLinOpNonConst();
1478 blockPrec2x2->setTriangular(precVelocity_,
1480 massMatrixVInverse_,
1484 ThyraLinOpPtr_Type B = system->getBlock(1,0)->getThyraLinOpNonConst();
1485 blockPrec2x2->setB(B);
1487 ThyraLinOpPtr_Type F = system->getBlock(0,0)->getThyraLinOpNonConst();
1488 blockPrec2x2->setF(F);
1493 LinSolverBuilderPtr_Type solverBuilder;
1494 if (!timeProblem_.is_null())
1495 solverBuilder = timeProblem_->getLinearSolverBuilder();
1497 solverBuilder = problem_->getLinearSolverBuilder();
1499 if ( precFactory_.is_null() )
1500 precFactory_ = solverBuilder->createPreconditioningStrategy(
"");
1502 if ( thyraPrec_.is_null() )
1503 thyraPrec_ = precFactory_->createPrec();
1505 Teuchos::RCP< Thyra::DefaultPreconditioner<SC> > defaultPrec =
1506 Teuchos::rcp_dynamic_cast< Thyra::DefaultPreconditioner<SC> > (thyraPrec_);
1507 ThyraLinOpPtr_Type linOp =
1508 Teuchos::rcp_dynamic_cast< Thyra::LinearOpBase<SC> > (blockPrec2x2);
1510 defaultPrec->initializeUnspecified( linOp );
1512 precondtionerIsBuilt_ =
true;
1514 PRECONDITIONER_STOP(buildPreconditionerBlock2x2);
1521template <
class SC,
class LO,
class GO,
class NO>
1522void Preconditioner<SC,LO,GO,NO>::setVelocityParameters( ParameterListPtr_Type parameterList,
int coarseRanks )
1524 CommConstPtr_Type comm;
1525 if (!problem_.is_null())
1526 comm = problem_->getComm();
1527 else if(!timeProblem_.is_null())
1528 comm = timeProblem_->getComm();
1530 bool verbose( comm->getRank() == 0 );
1533 Teuchos::ArrayRCP<Teuchos::RCP<Xpetra::Map<LO,GO,NO> > > repeatedMaps(1);
1534 typedef Xpetra::Map<LO,GO,NO> XpetraMap_Type;
1535 typedef Teuchos::RCP<XpetraMap_Type> XpetraMapPtr_Type;
1536 typedef Teuchos::RCP<const XpetraMap_Type> XpetraMapConstPtr_Type;
1537 typedef const XpetraMapConstPtr_Type XpetraMapConstPtrConst_Type;
1539 Teuchos::ArrayRCP<FROSch::DofOrdering> dofOrderings(1);
1540 Teuchos::ArrayRCP<UN> dofsPerNodeVector(1);
1541 ParameterListPtr_Type velocitySubList = sublist( sublist( sublist( sublist( parameterList,
"Preconditioner Types" ) ,
"Teko" ) ,
"Inverse Factory Library" ) ,
"FROSch-Velocity" );
1542 dofsPerNodeVector[0] = (UN) velocitySubList->get(
"DofsPerNode", 2);
1543 TEUCHOS_TEST_FOR_EXCEPTION(dofsPerNodeVector[0]<2, std::logic_error,
"DofsPerNode for velocity must be atleast 2.");
1553 MapConstPtr_Type mapConstTmp;
1554 if (!problem_.is_null())
1555 mapConstTmp = problem_->getDomain(0)->getMapVecFieldRepeated();
1556 else if(!timeProblem_.is_null())
1557 mapConstTmp = timeProblem_->getDomain(0)->getMapVecFieldRepeated();
1559 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
1560 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
1562 repeatedMaps[0] = mapX;
1564 if (!velocitySubList->get(
"DofOrdering",
"NodeWise" ).compare(
"DimensionWise"))
1565 dofOrderings[0] = FROSch::DimensionWise;
1566 else if (!velocitySubList->get(
"DofOrdering",
"NodeWise" ).compare(
"NodeWise"))
1567 dofOrderings[0] = FROSch::NodeWise;
1569 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Please chose a valid DOF ordering for ThyraPreconditioner(FROSch).");
1571 velocitySubList->set(
"Repeated Map Vector",repeatedMaps);
1572 velocitySubList->set(
"DofOrdering Vector",dofOrderings);
1573 velocitySubList->set(
"DofsPerNode Vector",dofsPerNodeVector);
1574 velocitySubList->set(
"Mpi Ranks Coarse", coarseRanks );
1576 int lowerBound = 100000000;
1577 int upperBound = -1;
1579 tuple_intint_Type rankRange;
1580 if (!problem_.is_null())
1581 rankRange = problem_->getDomain(0)->getMesh()->getRankRange();
1582 else if(!timeProblem_.is_null())
1583 rankRange = timeProblem_->getDomain(0)->getMesh()->getRankRange();
1585 if (std::get<0>(rankRange) < lowerBound)
1586 lowerBound = std::get<0>(rankRange);
1587 if (std::get<1>(rankRange) > upperBound)
1588 upperBound = std::get<1>(rankRange);
1590 int lowerBoundCoarse = lowerBound;
1591 int upperBoundCoarse = upperBound;
1593 if ( coarseRanks > 0 ){
1594 lowerBoundCoarse = upperBound + 1;
1595 upperBoundCoarse = comm->getSize() - 1;
1598 std::cout <<
"\t --- ------------------------------------------------------------------- ---"<< std::endl;
1599 std::cout <<
"\t --- Range for local problems of preconditioner Teko velocity from " << lowerBound <<
" to " << upperBound << std::endl;
1600 std::cout <<
"\t --- Range for coarse problem of preconditioner Teko velocity from " << lowerBoundCoarse <<
" to " << upperBoundCoarse << std::endl;
1601 std::cout <<
"\t --- ------------------------------------------------------------------- ---"<< std::endl;
1604 velocitySubList->set(
"Local problem ranks lower bound", lowerBound );
1605 velocitySubList->set(
"Local problem ranks upper bound", upperBound );
1607 velocitySubList->set(
"Coarse problem ranks lower bound", lowerBoundCoarse );
1608 velocitySubList->set(
"Coarse problem ranks upper bound", upperBoundCoarse );
1615template <
class SC,
class LO,
class GO,
class NO>
1616void Preconditioner<SC,LO,GO,NO>::setPressureParameters( ParameterListPtr_Type parameterList,
int coarseRanks )
1618 CommConstPtr_Type comm;
1619 if (!problem_.is_null())
1620 comm = problem_->getComm();
1621 else if(!timeProblem_.is_null())
1622 comm = timeProblem_->getComm();
1624 bool verbose( comm->getRank() == 0 );
1626 Teuchos::ArrayRCP<Teuchos::RCP<Xpetra::Map<LO,GO,NO> > > repeatedMaps(1);
1627 typedef Xpetra::Map<LO,GO,NO> XpetraMap_Type;
1628 typedef Teuchos::RCP<XpetraMap_Type> XpetraMapPtr_Type;
1629 typedef Teuchos::RCP<const XpetraMap_Type> XpetraMapConstPtr_Type;
1630 typedef const XpetraMapConstPtr_Type XpetraMapConstPtrConst_Type;
1632 Teuchos::ArrayRCP<FROSch::DofOrdering> dofOrderings(1);
1633 Teuchos::ArrayRCP<UN> dofsPerNodeVector(1);
1634 ParameterListPtr_Type pressureSubList = sublist( sublist( sublist( sublist( parameterList,
"Preconditioner Types" ) ,
"Teko" ) ,
"Inverse Factory Library" ) ,
"FROSch-Pressure" );
1635 dofsPerNodeVector[0] = (UN) pressureSubList->get(
"DofsPerNode", 1);
1636 TEUCHOS_TEST_FOR_EXCEPTION(dofsPerNodeVector[0]!=1, std::logic_error,
"DofsPerNode for pressure must be 1.");
1652 MapConstPtr_Type mapConstTmp;
1653 if (!problem_.is_null()){
1654 if ( problem_->getDomain(1)->getFEType()==
"P0" )
1655 mapConstTmp = problem_->getDomain(1)->getElementMap();
1657 mapConstTmp = problem_->getDomain(1)->getMapRepeated();
1659 else if(!timeProblem_.is_null()){
1660 if ( timeProblem_->getDomain(1)->getFEType()==
"P0" )
1661 mapConstTmp = timeProblem_->getDomain(1)->getElementMap();
1663 mapConstTmp = timeProblem_->getDomain(1)->getMapRepeated();
1668 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
1669 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
1671 repeatedMaps[0] = mapX;
1673 if (!pressureSubList->get(
"DofOrdering",
"NodeWise" ).compare(
"DimensionWise"))
1674 dofOrderings[0] = FROSch::DimensionWise;
1675 else if (!pressureSubList->get(
"DofOrdering",
"NodeWise" ).compare(
"NodeWise"))
1676 dofOrderings[0] = FROSch::NodeWise;
1678 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Please chose a valid DOF ordering for ThyraPreconditioner(FROSch).");
1680 pressureSubList->set(
"Repeated Map Vector",repeatedMaps);
1681 pressureSubList->set(
"DofOrdering Vector",dofOrderings);
1682 pressureSubList->set(
"DofsPerNode Vector",dofsPerNodeVector);
1683 pressureSubList->set(
"Mpi Ranks Coarse", coarseRanks );
1685 int lowerBound = 100000000;
1686 int upperBound = -1;
1689 tuple_intint_Type rankRange;
1690 if (!problem_.is_null())
1691 rankRange = problem_->getDomain(1)->getMesh()->getRankRange();
1692 else if(!timeProblem_.is_null())
1693 rankRange = timeProblem_->getDomain(1)->getMesh()->getRankRange();
1695 if (std::get<0>(rankRange) < lowerBound)
1696 lowerBound = std::get<0>(rankRange);
1697 if (std::get<1>(rankRange) > upperBound)
1698 upperBound = std::get<1>(rankRange);
1700 int lowerBoundCoarse = lowerBound;
1701 int upperBoundCoarse = upperBound;
1703 if ( coarseRanks > 0 ){
1704 lowerBoundCoarse = upperBound + 1;
1705 upperBoundCoarse = comm->getSize() - 1;
1708 std::cout <<
"\t --- ------------------------------------------------------------------- ---"<< std::endl;
1709 std::cout <<
"\t --- Range for local problems of preconditioner Teko pressure from " << lowerBound <<
" to " << upperBound << std::endl;
1710 std::cout <<
"\t --- Range for coarse problem of preconditioner Teko pressure from " << lowerBoundCoarse <<
" to " << upperBoundCoarse << std::endl;
1711 std::cout <<
"\t --- ------------------------------------------------------------------- ---"<< std::endl;
1714 pressureSubList->set(
"Local problem ranks lower bound", lowerBound );
1715 pressureSubList->set(
"Local problem ranks upper bound", upperBound );
1717 pressureSubList->set(
"Coarse problem ranks lower bound", lowerBoundCoarse );
1718 pressureSubList->set(
"Coarse problem ranks upper bound", upperBoundCoarse );
1723template <
class SC,
class LO,
class GO,
class NO>
1724typename Preconditioner<SC,LO,GO,NO>::ThyraLinOpConstPtr_Type Preconditioner<SC,LO,GO,NO>::getTekoOp(){
1728template <
class SC,
class LO,
class GO,
class NO>
1729void Preconditioner<SC,LO,GO,NO>::setVelocityMassMatrix(MatrixPtr_Type massMatrix)
const{
1730 velocityMassMatrix_ = massMatrix->getThyraLinOp();
1731 velocityMassMatrixMatrixPtr_ = massMatrix;
1735template <
class SC,
class LO,
class GO,
class NO>
1736void Preconditioner<SC,LO,GO,NO>::exportCoarseBasis( ){
1738 CommConstPtr_Type comm;
1739 if (!problem_.is_null())
1740 comm = problem_->getComm();
1741 else if(!timeProblem_.is_null())
1742 comm = timeProblem_->getComm();
1744 TEUCHOS_TEST_FOR_EXCEPTION( pListPhiExport_.is_null(), std::runtime_error,
"No parameterlist to extract Phi pointer.");
1745 ParameterListPtr_Type pLPrec = sublist( sublist( pListPhiExport_,
"Preconditioner Types" ) ,
"FROSch" );
1746 std::string coarseType = pLPrec->get(
"CoarseOperator Type",
"RGDSWCoarseOperator" );
1747 ParameterListPtr_Type pLCoarse = sublist( pLPrec, coarseType );
1750 TEUCHOS_TEST_FOR_EXCEPTION( !pLCoarse->isParameter(
"RCP(Phi)"), std::runtime_error,
"No parameter to extract Phi pointer.");
1752 Teuchos::RCP<Tpetra::CrsMatrix<SC,LO,GO,NO> > phiTpetra;
1754 TEUCHOS_TEST_FOR_EXCEPTION( !pLCoarse->isType<
decltype(phiTpetra)>(
"RCP(Phi)"), std::runtime_error,
"Wrong type of pointer to extract Phi.");
1756 phiTpetra = pLCoarse->get<
decltype(phiTpetra)>(
"RCP(Phi)");
1758 MatrixPtr_Type phiMatrix = Teuchos::rcp(
new Matrix_Type( phiTpetra ) );
1761 ParameterListPtr_Type parameterList;
1762 if (!problem_.is_null())
1763 parameterList = problem_->getParameterList();
1764 else if(!timeProblem_.is_null())
1765 parameterList = timeProblem_->getParameterList();
1766 numberOfBlocks = parameterList->get(
"Number of blocks",1);
1769 std::vector<MapConstPtr_Type> blockMaps(numberOfBlocks);
1770 MultiVectorPtr_Type phiMV;
1771 phiMatrix->toMV( phiMV );
1773 for (UN i = 0; i < numberOfBlocks; i++) {
1774 int dofsPerNode = pLPrec->get(
"DofsPerNode" + std::to_string(i+1), 1);
1775 MapConstPtr_Type map;
1776 if (dofsPerNode>1) {
1777 if (!problem_.is_null()) {
1778 TEUCHOS_TEST_FOR_EXCEPTION( problem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Vector field map not implemented for P0 elements.");
1779 map = problem_->getDomain(i)->getMapVecFieldUnique();
1781 else if(!timeProblem_.is_null()){
1782 TEUCHOS_TEST_FOR_EXCEPTION( timeProblem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Vector field map not implemented for P0 elements.");
1783 map = timeProblem_->getDomain(i)->getMapVecFieldUnique();
1787 if (!problem_.is_null()) {
1788 TEUCHOS_TEST_FOR_EXCEPTION( problem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Vector field map not implemented for P0 elements.");
1789 map = problem_->getDomain(i)->getMapUnique();
1791 else if(!timeProblem_.is_null()){
1792 TEUCHOS_TEST_FOR_EXCEPTION( timeProblem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Vector field map not implemented for P0 elements.");
1793 map = timeProblem_->getDomain(i)->getMapUnique();
1800 BlockMultiVectorPtr_Type phiBlockMV = Teuchos::rcp(
new BlockMultiVector_Type ( blockMaps, phiMV->getNumVectors() ) );
1801 phiBlockMV->setMergedVector( phiMV );
1802 phiBlockMV->split();
1804 ParameterListPtr_Type pLProblem;
1805 if (!problem_.is_null())
1806 pLProblem = problem_->getParameterList();
1807 else if(!timeProblem_.is_null())
1808 pLProblem = timeProblem_->getParameterList();
1810 BlockMultiVectorPtr_Type phiSumBlockMV = phiBlockMV->sumColumns();
1812 for (
int i=0; i<phiBlockMV->size(); i++) {
1813 bool exportThisBlock = !pLProblem->sublist(
"Exporter").get(
"Exclude coarse functions block" + std::to_string(i+1),
false);
1815 if (exportThisBlock){
1816 Teuchos::RCP<ExporterParaView<SC,LO,GO,NO> > exporter(
new ExporterParaView<SC,LO,GO,NO>());
1818 DomainConstPtr_Type domain;
1819 if (!problem_.is_null())
1820 domain = problem_->getDomain(i);
1821 else if(!timeProblem_.is_null())
1822 domain = timeProblem_->getDomain(i);
1824 int dofsPerNode = domain->getDimension();
1825 std::string fileName = pLProblem->sublist(
"Exporter").get(
"Name coarse functions block" + std::to_string(i+1),
"phi");
1827 MeshPtr_Type meshNonConst = Teuchos::rcp_const_cast<Mesh_Type>( domain->getMesh() );
1828 exporter->setup(fileName, meshNonConst, domain->getFEType());
1830 for (
int j=0; j<phiBlockMV->getNumVectors(); j++) {
1832 MultiVectorConstPtr_Type exportPhi = phiBlockMV->getBlock( i )->getVector( j );
1834 std::string varName = fileName + std::to_string(j);
1835 if ( pLPrec->get(
"DofsPerNode" + std::to_string(i+1), 1) > 1 )
1836 exporter->addVariable( exportPhi, varName,
"Vector", dofsPerNode, domain->getMapUnique() );
1838 exporter->addVariable( exportPhi, varName,
"Scalar", 1, domain->getMapUnique() );
1841 MultiVectorConstPtr_Type exportSumPhi = phiSumBlockMV->getBlock(i);
1842 std::string varName = fileName +
"Sum";
1843 if ( pLPrec->get(
"DofsPerNode" + std::to_string(i+1), 1) > 1 )
1844 exporter->addVariable( exportSumPhi, varName,
"Vector", dofsPerNode, domain->getMapUnique() );
1846 exporter->addVariable( exportSumPhi, varName,
"Scalar", 1, domain->getMapUnique() );
1848 exporter->save(0.0);
1854template <
class SC,
class LO,
class GO,
class NO>
1855void Preconditioner<SC,LO,GO,NO>::exportCoarseBasisFSI( ){
1857 CommConstPtr_Type comm;
1858 if (!problem_.is_null())
1859 comm = problem_->getComm();
1860 else if(!timeProblem_.is_null())
1861 comm = timeProblem_->getComm();
1863 TEUCHOS_TEST_FOR_EXCEPTION( pListPhiExport_.is_null(), std::runtime_error,
"No parameterlist to extract Phi pointer.");
1864 ParameterListPtr_Type pLPrec = sublist( sublist( pListPhiExport_,
"Preconditioner Types" ) ,
"FROSch" );
1865 std::string coarseType = pLPrec->get(
"CoarseOperator Type",
"RGDSWCoarseOperator" );
1866 ParameterListPtr_Type pLCoarse = sublist( pLPrec, coarseType );
1869 TEUCHOS_TEST_FOR_EXCEPTION( !pLCoarse->isParameter(
"Phi Pointer"), std::runtime_error,
"No parameter to extract Phi pointer.");
1871 Teuchos::RCP<Tpetra::CrsMatrix<SC,LO,GO,NO> > phiTpetra;
1873 TEUCHOS_TEST_FOR_EXCEPTION( !pLCoarse->isType<
decltype(phiTpetra)>(
"Phi Pointer"), std::runtime_error,
"Wrong type of pointer to extract Phi.");
1875 phiTpetra = pLCoarse->get<
decltype(phiTpetra)>(
"Phi Pointer");
1877 MatrixPtr_Type phiMatrix = Teuchos::rcp(
new Matrix_Type( phiTpetra ) );
1880 ParameterListPtr_Type parameterList;
1881 if (!problem_.is_null())
1882 parameterList = problem_->getParameterList();
1883 else if(!timeProblem_.is_null())
1884 parameterList = timeProblem_->getParameterList();
1885 numberOfBlocks = parameterList->get(
"Number of blocks",1);
1888 std::vector<MapConstPtr_Type> blockMaps(numberOfBlocks);
1889 MultiVectorPtr_Type phiMV;
1890 phiMatrix->toMV( phiMV );
1892 for (UN i = 0; i < numberOfBlocks; i++) {
1893 int dofsPerNode = pLPrec->get(
"DofsPerNode" + std::to_string(i+1), 1);
1894 MapConstPtr_Type map;
1896 map = timeProblem_->getDomain(i)->getInterfaceMapVecFieldUnique();
1899 if (dofsPerNode>1) {
1900 if (!problem_.is_null()) {
1901 TEUCHOS_TEST_FOR_EXCEPTION( problem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Vector field map not implemented for P0 elements.");
1902 map = problem_->getDomain(i)->getMapVecFieldUnique();
1904 else if(!timeProblem_.is_null()){
1905 TEUCHOS_TEST_FOR_EXCEPTION( timeProblem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Vector field map not implemented for P0 elements.");
1906 map = timeProblem_->getDomain(i)->getMapVecFieldUnique();
1910 if (!problem_.is_null()) {
1911 TEUCHOS_TEST_FOR_EXCEPTION( problem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Vector field map not implemented for P0 elements.");
1912 map = problem_->getDomain(i)->getMapUnique();
1914 else if(!timeProblem_.is_null()){
1915 TEUCHOS_TEST_FOR_EXCEPTION( timeProblem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Vector field map not implemented for P0 elements.");
1916 map = timeProblem_->getDomain(i)->getMapUnique();
1924 BlockMultiVectorPtr_Type phiBlockMV = Teuchos::rcp(
new BlockMultiVector_Type ( blockMaps, phiMV->getNumVectors() ) );
1925 phiBlockMV->setMergedVector( phiMV );
1926 phiBlockMV->split();
1928 ParameterListPtr_Type pLProblem;
1929 if (!problem_.is_null())
1930 pLProblem = problem_->getParameterList();
1931 else if(!timeProblem_.is_null())
1932 pLProblem = timeProblem_->getParameterList();
1934 BlockMultiVectorPtr_Type phiSumBlockMV = phiBlockMV->sumColumns();
1936 for (
int i=0; i<phiBlockMV->size(); i++) {
1937 bool exportThisBlock = !pLProblem->sublist(
"Exporter").get(
"Exclude coarse functions block" + std::to_string(i+1),
false);
1939 if (exportThisBlock){
1940 Teuchos::RCP<ExporterParaView<SC,LO,GO,NO> > exporter(
new ExporterParaView<SC,LO,GO,NO>());
1942 DomainConstPtr_Type domain;
1943 if (!problem_.is_null())
1944 domain = problem_->getDomain(i);
1945 else if(!timeProblem_.is_null())
1946 domain = timeProblem_->getDomain(i);
1948 int dofsPerNode = domain->getDimension();
1949 std::string fileName = pLProblem->sublist(
"Exporter").get(
"Name coarse functions block" + std::to_string(i+1),
"phi");
1951 MeshPtr_Type meshNonConst = Teuchos::rcp_const_cast<Mesh_Type>( domain->getMesh() );
1952 exporter->setup(fileName, meshNonConst, domain->getFEType());
1954 for (
int j=0; j<phiBlockMV->getNumVectors(); j++) {
1956 MultiVectorConstPtr_Type exportPhi = phiBlockMV->getBlock( i )->getVector( j );
1958 std::string varName = fileName + std::to_string(j);
1959 if ( pLPrec->get(
"DofsPerNode" + std::to_string(i+1), 1) > 1 )
1960 exporter->addVariable( exportPhi, varName,
"Vector", dofsPerNode, domain->getMapUnique() );
1962 exporter->addVariable( exportPhi, varName,
"Scalar", 1, domain->getMapUnique() );
1965 MultiVectorConstPtr_Type exportSumPhi = phiSumBlockMV->getBlock(i);
1966 std::string varName = fileName +
"Sum";
1967 if ( pLPrec->get(
"DofsPerNode" + std::to_string(i+1), 1) > 1 )
1968 exporter->addVariable( exportSumPhi, varName,
"Vector", dofsPerNode, domain->getMapUnique() );
1970 exporter->addVariable( exportSumPhi, varName,
"Scalar", 1, domain->getMapUnique() );
1972 exporter->save(0.0);
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement_decl.hpp:33