1#ifndef Preconditioner_DEF_hpp
2#define Preconditioner_DEF_hpp
3#include "Preconditioner_decl.hpp"
4#include <Thyra_DefaultZeroLinearOp_decl.hpp>
5#ifdef FEDD_HAVE_IFPACK2
6#include <Thyra_Ifpack2PreconditionerFactory_def.hpp>
19template <
class SC,
class LO,
class GO,
class NO>
20Preconditioner<SC,LO,GO,NO>::Preconditioner(Problem_Type* problem):
22precondtionerIsBuilt_(false),
37#ifdef PRECONDITIONER_TIMER
38,preconditionerTimer_ (Teuchos::TimeMonitor::getNewCounter(
"Preconditioner: Setup"))
41 problem_.reset( problem,
false );
43 Stratimikos::enableFROSch<LO,GO,NO>( *problem_->getLinearSolverBuilder() );
45#ifdef FEDD_HAVE_IFPACK2
46 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> CRSMat;
47 typedef Tpetra::Operator<SC,LO,GO,NO> TP_op;
48 typedef Thyra::PreconditionerFactoryBase<SC> Base;
49 typedef Thyra::Ifpack2PreconditionerFactory<CRSMat> Impl;
51 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> TpetraCrsMatrix_Type;
52 typedef Teuchos::RCP<TpetraCrsMatrix_Type> TpetraCrsMatrixPtr_Type;
54 problem_->getLinearSolverBuilder()->setPreconditioningStrategyFactory(Teuchos::abstractFactoryStd<Base, Impl>(),
"Ifpack2");
57 Teko::addTekoToStratimikosBuilder( *problem_->getLinearSolverBuilder() );
64template <
class SC,
class LO,
class GO,
class NO>
65Preconditioner<SC,LO,GO,NO>::Preconditioner(TimeProblem_Type* problem):
67precondtionerIsBuilt_(false),
82#ifdef PRECONDITIONER_TIMER
83,preconditionerTimer_ (Teuchos::TimeMonitor::getNewCounter(
"Preconditioner: Setup"))
86 timeProblem_.reset( problem,
false );
90template <
class SC,
class LO,
class GO,
class NO>
91Preconditioner<SC,LO,GO,NO>::~Preconditioner()
95template<
class SC,
class LO,
class GO,
class NO>
96void Preconditioner<SC,LO,GO,NO>::setPreconditionerThyraFromLinOp( ThyraLinOpPtr_Type precLinOp ){
97 TEUCHOS_TEST_FOR_EXCEPTION( thyraPrec_.is_null(), std::runtime_error,
"thyraPrec_ is null." );
98 Teuchos::RCP<Thyra::DefaultPreconditioner<SC> > defaultPrec = Teuchos::rcp_dynamic_cast<Thyra::DefaultPreconditioner<SC> > (thyraPrec_);
99 TEUCHOS_TEST_FOR_EXCEPTION( defaultPrec.is_null(), std::runtime_error,
"Cast to DefaultPrecondtioner failed." );
100 TEUCHOS_TEST_FOR_EXCEPTION( precLinOp.is_null(), std::runtime_error,
"precLinOp is null." );
101 defaultPrec->initializeUnspecified( precLinOp );
104template <
class SC,
class LO,
class GO,
class NO>
105typename Preconditioner<SC,LO,GO,NO>::ThyraPrecPtr_Type Preconditioner<SC,LO,GO,NO>::getThyraPrec(){
109template <
class SC,
class LO,
class GO,
class NO>
110typename Preconditioner<SC,LO,GO,NO>::ThyraPrecConstPtr_Type Preconditioner<SC,LO,GO,NO>::getThyraPrecConst()
const{
114template <
class SC,
class LO,
class GO,
class NO>
115void Preconditioner<SC,LO,GO,NO>::initializePreconditioner( std::string type )
117 if ( type ==
"Monolithic" || type ==
"FaCSI" || type ==
"Diagonal" || type ==
"Triangular"){
118 if (type ==
"Monolithic")
119 initPreconditionerMonolithic( );
120 else if (type ==
"FaCSI" || type ==
"Diagonal" || type ==
"Triangular")
121 initPreconditionerBlock( );
124 else if (type ==
"Teko" || type ==
"FaCSI-Teko"){
125 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Please construct the Teko precondtioner completely.");
128 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unkown preconditioner type for initialization.");
131template <
class SC,
class LO,
class GO,
class NO>
132void Preconditioner<SC,LO,GO,NO>::initPreconditionerMonolithic( )
135 LinSolverBuilderPtr_Type solverBuilder;
136 Teuchos::RCP<const Thyra::VectorSpaceBase<SC> > thyraRangeSpace;
137 Teuchos::RCP<const Thyra::VectorSpaceBase<SC> > thyraDomainSpace;
139 if (!problem_.is_null()){
140 solverBuilder = problem_->getLinearSolverBuilder();
141 thyraRangeSpace = Thyra::tpetraVectorSpace<SC,LO,GO,NO>( problem_->getSystem()->getMap()->getMergedMap()->getTpetraMap());
142 thyraDomainSpace = Thyra::tpetraVectorSpace<SC,LO,GO,NO>( problem_->getSystem()->getMap()->getMergedMap()->getTpetraMap());
144 else if(!timeProblem_.is_null()){
145 solverBuilder = timeProblem_->getUnderlyingProblem()->getLinearSolverBuilder();
146 thyraRangeSpace = Thyra::tpetraVectorSpace<SC,LO,GO,NO>( timeProblem_->getSystem()->getMap()->getMergedMap()->getTpetraMap() );
147 thyraDomainSpace = Thyra::tpetraVectorSpace<SC,LO,GO,NO>( timeProblem_->getSystem()->getMap()->getMergedMap()->getTpetraMap() );
151 Teuchos::RCP<Thyra::LinearOpBase<SC> > thyraLinOp = Teuchos::rcp(
new Thyra::DefaultZeroLinearOp<SC>( thyraRangeSpace, thyraDomainSpace ) );
153 Teuchos::RCP<Thyra::PreconditionerFactoryBase<SC> > precFactory = solverBuilder->createPreconditioningStrategy(
"");
154 thyraPrec_ = precFactory->createPrec();
156 Teuchos::RCP<Thyra::DefaultPreconditioner<SC> > defaultPrec = Teuchos::rcp_dynamic_cast<Thyra::DefaultPreconditioner<SC> >(thyraPrec_);
158 defaultPrec->initializeUnspecified(thyraLinOp);
161template <
class SC,
class LO,
class GO,
class NO>
162void Preconditioner<SC,LO,GO,NO>::initPreconditionerBlock( )
164 using Teuchos::Array;
167 BlockMultiVectorPtr_Type sol;
168 BlockMultiVectorPtr_Type rhs;
169 LinSolverBuilderPtr_Type solverBuilder;
171 if (!problem_.is_null()){
172 solverBuilder = problem_->getLinearSolverBuilder();
173 size = problem_->getSystem()->size();
174 sol = problem_->getSolution();
175 rhs = problem_->getRhs();
177 else if(!timeProblem_.is_null()){
178 solverBuilder = timeProblem_->getUnderlyingProblem()->getLinearSolverBuilder();
179 size = timeProblem_->getSystem()->size();
180 sol = timeProblem_->getSolution();
181 rhs = timeProblem_->getRhs();
184 Array< RCP< const Thyra::VectorSpaceBase< SC > > > vectorSpacesRange( size );
185 Array< RCP< const Thyra::VectorSpaceBase< SC > > > vectorSpacesDomain( size );
187 for (
int i=0; i<size; i++) {
188 vectorSpacesRange[i] = rhs->getBlock(i)->getMap()->getThyraVectorSpaceBase();
189 vectorSpacesDomain[i] = sol->getBlock(i)->getMap()->getThyraVectorSpaceBase();
192 RCP<const Thyra::DefaultProductVectorSpace<SC> > pR = Thyra::productVectorSpace<SC>( vectorSpacesRange );
193 RCP<const Thyra::DefaultProductVectorSpace<SC> > pD = Thyra::productVectorSpace<SC>( vectorSpacesDomain );
195 RCP<Thyra::LinearOpBase<SC> > thyraLinOp = rcp(
new Thyra::DefaultZeroLinearOp<SC>( pR, pD ) );
197 Teuchos::RCP<Thyra::PreconditionerFactoryBase<SC> > precFactory = solverBuilder->createPreconditioningStrategy(
"");
198 thyraPrec_ = precFactory->createPrec();
200 Teuchos::RCP<Thyra::DefaultPreconditioner<SC> > defaultPrec = Teuchos::rcp_dynamic_cast<Thyra::DefaultPreconditioner<SC> >(thyraPrec_);
202 defaultPrec->initializeUnspecified(thyraLinOp);
205template <
class SC,
class LO,
class GO,
class NO>
206void Preconditioner<SC,LO,GO,NO>::buildPreconditioner( std::string type )
209#ifdef PRECONDITIONER_TIMER
210 CommConstPtr_Type comm;
211 if (!problem_.is_null())
212 comm = problem_->getComm();
213 else if(!timeProblem_.is_null())
214 comm = timeProblem_->getComm();
216 Teuchos::TimeMonitor preconditionerTimeMonitor(*preconditionerTimer_);
219 if (!type.compare(
"Monolithic")){
220 buildPreconditionerMonolithic( );
222 else if (!type.compare(
"Teko")){
224 buildPreconditionerTeko( );
226 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Teko not found! Build Trilinos with Teko.");
229 else if( type ==
"FaCSI" || type ==
"FaCSI-Teko" ){
230 buildPreconditionerFaCSI( type );
232 else if(type ==
"Triangular" || type ==
"Diagonal"){
233 buildPreconditionerBlock2x2( );
236 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unkown preconditioner type.");
238#ifdef PRECONDITIONER_TIMER
243template <
class SC,
class LO,
class GO,
class NO>
244void Preconditioner<SC,LO,GO,NO>::buildPreconditionerMonolithic( )
247 CommConstPtr_Type comm;
248 if (!problem_.is_null())
249 comm = problem_->getComm();
250 else if(!timeProblem_.is_null())
251 comm = timeProblem_->getComm();
253 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Preconditioner can not be used without a problem.");
255 bool verbose ( comm->getRank() == 0 );
257 ParameterListPtr_Type parameterList;
259 if (!problem_.is_null())
260 parameterList = problem_->getParameterList();
261 else if(!timeProblem_.is_null())
262 parameterList = timeProblem_->getParameterList();
264 std::string precType = parameterList->sublist(
"ThyraPreconditioner").get(
"Preconditioner Type",
"FROSch");
266 bool useRepeatedMaps = parameterList->get(
"Use repeated maps",
true );
267 bool useNodeLists = parameterList->get(
"Use node lists",
true );
268 ParameterListPtr_Type pListThyraPrec = sublist( parameterList,
"ThyraPreconditioner" );
269 ParameterListPtr_Type plFrosch = sublist( sublist( pListThyraPrec,
"Preconditioner Types" ),
"FROSch");
271 ThyraLinOpConstPtr_Type thyraMatrix;
272 if (!problem_.is_null())
273 thyraMatrix = problem_->getSystem()->getThyraLinOp();
274 else if(!timeProblem_.is_null())
275 thyraMatrix = timeProblem_->getSystemCombined()->getThyraLinOp();
277 UN numberOfBlocks = parameterList->get(
"Number of blocks",1);
279 typedef Tpetra::MultiVector<SC,LO,GO,NO> TMultiVector;
280 typedef Teuchos::RCP<TMultiVector> TMultiVectorPtr;
281 typedef Teuchos::ArrayRCP<TMultiVectorPtr> TMultiVectorPtrVecPtr;
285 typedef Xpetra::MultiVector<SC,LO,GO,NO> XMultiVector;
286 typedef Teuchos::RCP<XMultiVector> XMultiVectorPtr;
287 typedef Teuchos::ArrayRCP<XMultiVectorPtr> XMultiVectorPtrVecPtr;
289 typedef Xpetra::Map<LO,GO,NO> XpetraMap_Type;
290 typedef Teuchos::RCP<XpetraMap_Type> XpetraMapPtr_Type;
291 typedef Teuchos::RCP<const XpetraMap_Type> XpetraMapConstPtr_Type;
292 typedef const XpetraMapConstPtr_Type XpetraMapConstPtrConst_Type;
296 Teuchos::ArrayRCP<Teuchos::RCP<Xpetra::Map<LO,GO,NO> > > repeatedMaps(numberOfBlocks);
299 XMultiVectorPtrVecPtr nodeListVec( numberOfBlocks );
301 nodeListVec = Teuchos::null;
305 if (!precondtionerIsBuilt_) {
306 if ( !precType.compare(
"FROSch") ){
307 Teuchos::ArrayRCP<FROSch::DofOrdering> dofOrderings(numberOfBlocks);
308 Teuchos::ArrayRCP<UN> dofsPerNodeVector(numberOfBlocks);
309 for (UN i = 0; i < numberOfBlocks; i++) {
310 dofsPerNodeVector[i] = (UN) pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").get(
"DofsPerNode" + std::to_string(i+1), 1);
312 if (useRepeatedMaps) {
313 if (dofsPerNodeVector[i] > 1){
315 if (!problem_.is_null()) {
316 if (problem_->getDomain(i)->getFEType() ==
"P0") {
317 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Vector field map not implemented for P0 elements.");
323 MapConstPtr_Type mapConstTmp = problem_->getDomain(i)->getMapVecFieldRepeated();
324 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
325 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
327 repeatedMaps[i] = mapX;
331 else if(!timeProblem_.is_null()){
332 if (timeProblem_->getDomain(i)->getFEType() ==
"P0") {
333 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Vector field map not implemented for P0 elements.");
338 MapConstPtr_Type mapConstTmp = timeProblem_->getDomain(i)->getMapVecFieldRepeated();
339 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
340 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
342 repeatedMaps[i] = mapX;
346 if (!problem_.is_null()){
347 if (problem_->getDomain(i)->getFEType() ==
"P0") {
350 MapConstPtr_Type mapConstTmp = problem_->getDomain(i)->getElementMap();
351 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
352 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
354 repeatedMaps[i] = mapX;
359 MapConstPtr_Type mapConstTmp = problem_->getDomain(i)->getMapRepeated();
360 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
361 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
363 repeatedMaps[i] = mapX;
366 else if (!timeProblem_.is_null()){
367 if (timeProblem_->getDomain(i)->getFEType() ==
"P0") {
370 MapConstPtr_Type mapConstTmp = timeProblem_->getDomain(i)->getElementMap();
371 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
372 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
374 repeatedMaps[i] = mapX;
379 MapConstPtr_Type mapConstTmp = timeProblem_->getDomain(i)->getMapRepeated();
380 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
381 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
383 repeatedMaps[i] = mapX;
390 if (!problem_.is_null()){
391 TEUCHOS_TEST_FOR_EXCEPTION( problem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Node lists cannot be used for P0 elements." );
392 Teuchos::RCP< Tpetra::MultiVector<SC,LO,GO,NO> > nodeListTpetra = problem_->getDomain(i)->getNodeListMV()->getTpetraMultiVectorNonConst();
393 Teuchos::RCP< Xpetra::TpetraMultiVector<SC,LO,GO,NO> > nodeListXpetraTpetra = Teuchos::rcp(
new Xpetra::TpetraMultiVector<SC,LO,GO,NO>(nodeListTpetra));
394 Teuchos::RCP< Xpetra::MultiVector<SC,LO,GO,NO> > nodeListXpetra = Teuchos::rcp_dynamic_cast<Xpetra::MultiVector<SC,LO,GO,NO>>(nodeListXpetraTpetra);
396 nodeListVec[i] = nodeListXpetra;
398 else if (!timeProblem_.is_null()){
399 TEUCHOS_TEST_FOR_EXCEPTION( timeProblem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Node lists cannot be used for P0 elements." );
400 Teuchos::RCP< Tpetra::MultiVector<SC,LO,GO,NO> > nodeListTpetra = timeProblem_->getDomain(i)->getNodeListMV()->getTpetraMultiVectorNonConst();
401 Teuchos::RCP< Xpetra::TpetraMultiVector<SC,LO,GO,NO> > nodeListXpetraTpetra = Teuchos::rcp(
new Xpetra::TpetraMultiVector<SC,LO,GO,NO>(nodeListTpetra));
402 Teuchos::RCP< Xpetra::MultiVector<SC,LO,GO,NO> > nodeListXpetra = Teuchos::rcp_dynamic_cast<Xpetra::MultiVector<SC,LO,GO,NO>>(nodeListXpetraTpetra);
404 nodeListVec[i] = nodeListXpetra;
410 if (!pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").get(
"DofOrdering" + std::to_string(i+1),
"NodeWise" ).compare(
"DimensionWise"))
411 dofOrderings[i] = FROSch::DimensionWise;
412 else if (!pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").get(
"DofOrdering" + std::to_string(i+1),
"NodeWise" ).compare(
"NodeWise"))
413 dofOrderings[i] = FROSch::NodeWise;
415 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Please chose a valid DOF ordering for ThyraPreconditioner(FROSch).");
418 if (!problem_.is_null())
419 dim = problem_->getDomain(0)->getDimension();
420 else if(!timeProblem_.is_null())
421 dim = timeProblem_->getDomain(0)->getDimension();
423 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Dimension", dim);
424 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Repeated Map Vector",repeatedMaps);
425 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Coordinates List Vector",nodeListVec);
426 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"DofOrdering Vector",dofOrderings);
427 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"DofsPerNode Vector",dofsPerNodeVector);
428 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Mpi Ranks Coarse",parameterList->sublist(
"General").get(
"Mpi Ranks Coarse",0) );
434 int lowerBound = 100000000;
436 for (UN i = 0; i < numberOfBlocks; i++) {
437 tuple_intint_Type rankRange;
438 if (!problem_.is_null())
439 rankRange = problem_->getDomain(i)->getMesh()->getRankRange();
440 else if(!timeProblem_.is_null())
441 rankRange = timeProblem_->getDomain(i)->getMesh()->getRankRange();
443 if (std::get<0>(rankRange) < lowerBound)
444 lowerBound = std::get<0>(rankRange);
445 if (std::get<1>(rankRange) > upperBound)
446 upperBound = std::get<1>(rankRange);
449 int lowerBoundCoarse = lowerBound;
450 int upperBoundCoarse = upperBound;
452 if ( parameterList->sublist(
"General").get(
"Mpi Ranks Coarse",0) > 0 ){
453 lowerBoundCoarse = upperBound + 1;
454 upperBoundCoarse = comm->getSize() - 1;
457 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
458 std::cout <<
"\t --- Range for local problems of preconditioner from " << lowerBound <<
" to " << upperBound << std::endl;
459 std::cout <<
"\t --- Range for coarse problem of preconditioner from " << lowerBoundCoarse <<
" to " << upperBoundCoarse << std::endl;
460 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
463 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Local problem ranks lower bound", lowerBound );
464 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Local problem ranks upper bound", upperBound );
466 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Coarse problem ranks lower bound", lowerBoundCoarse );
467 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Coarse problem ranks upper bound", upperBoundCoarse );
474 ParameterListPtr_Type pListThyraSolver = sublist( parameterList,
"ThyraSolver" );
475 pListThyraSolver->setParameters( *pListThyraPrec );
477 LinSolverBuilderPtr_Type solverBuilder;
478 if (!problem_.is_null())
479 solverBuilder = problem_->getLinearSolverBuilder();
480 else if(!timeProblem_.is_null())
481 solverBuilder = timeProblem_->getLinearSolverBuilder();
484 pListPhiExport_ = pListThyraSolver;
486 solverBuilder->setParameterList(pListThyraSolver);
487 precFactory_ = solverBuilder->createPreconditioningStrategy(
"");
489 if ( thyraPrec_.is_null() ){
490 thyraPrec_ = precFactory_->createPrec();
493 Thyra::initializePrec<SC>(*precFactory_, thyraMatrix, thyraPrec_.ptr());
494 precondtionerIsBuilt_ =
true;
498 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unknown preconditioner type; You can only compute a FROSch preconditioner here." );
501 TEUCHOS_TEST_FOR_EXCEPTION( precFactory_.is_null(), std::runtime_error,
"precFactory_ is null.");
502 Thyra::initializePrec<SC>(*precFactory_, thyraMatrix, thyraPrec_.ptr());
505 if (parameterList->sublist(
"Exporter" ).get(
"Export coarse functions",
false))
509template <
class SC,
class LO,
class GO,
class NO>
510void Preconditioner<SC,LO,GO,NO>::buildPreconditionerMonolithicFSI( )
513 CommConstPtr_Type comm;
514 if (!problem_.is_null())
515 comm = problem_->getComm();
516 else if(!timeProblem_.is_null())
517 comm = timeProblem_->getComm();
519 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Preconditioner can not be used without a problem.");
521 bool verbose ( comm->getRank() == 0 );
523 ParameterListPtr_Type parameterList;
525 if (!problem_.is_null())
526 parameterList = problem_->getParameterList();
527 else if(!timeProblem_.is_null())
528 parameterList = timeProblem_->getParameterList();
530 std::string precType = parameterList->sublist(
"ThyraPreconditioner").get(
"Preconditioner Type",
"FROSch");
532 bool useRepeatedMaps = parameterList->get(
"Use repeated maps",
true );
533 bool useNodeLists = parameterList->get(
"Use node lists",
true );
534 ParameterListPtr_Type pListThyraPrec = sublist( parameterList,
"ThyraPreconditioner" );
535 ParameterListPtr_Type plFrosch = sublist( sublist( pListThyraPrec,
"Preconditioner Types" ),
"FROSch");
539 ThyraLinOpConstPtr_Type thyraMatrix;
540 if (!problem_.is_null())
541 thyraMatrix = problem_->getSystem()->getThyraLinOp();
542 else if(!timeProblem_.is_null())
543 thyraMatrix = timeProblem_->getSystemCombined()->getThyraLinOp();
545 UN numberOfBlocks = parameterList->get(
"Number of blocks",1);
546 TEUCHOS_TEST_FOR_EXCEPTION( numberOfBlocks<4 || numberOfBlocks>5, std::logic_error,
"Unknown FSI size." );
549 typedef Tpetra::MultiVector<SC,LO,GO,NO> TMultiVector;
550 typedef Teuchos::RCP<TMultiVector> TMultiVectorPtr;
551 typedef Teuchos::ArrayRCP<TMultiVectorPtr> TMultiVectorPtrVecPtr;
555 typedef Xpetra::MultiVector<SC,LO,GO,NO> XMultiVector;
556 typedef Teuchos::RCP<XMultiVector> XMultiVectorPtr;
557 typedef Teuchos::ArrayRCP<XMultiVectorPtr> XMultiVectorPtrVecPtr;
559 typedef Xpetra::Map<LO,GO,NO> XpetraMap_Type;
560 typedef Teuchos::RCP<XpetraMap_Type> XpetraMapPtr_Type;
561 typedef Teuchos::RCP<const XpetraMap_Type> XpetraMapConstPtr_Type;
562 typedef const XpetraMapConstPtr_Type XpetraMapConstPtrConst_Type;
565 Teuchos::ArrayRCP<Teuchos::RCP<Xpetra::Map<LO,GO,NO> > > repeatedMaps(numberOfBlocks);
568 TMultiVectorPtrVecPtr nodeListVec( numberOfBlocks );
569 nodeListVec = Teuchos::null;
572 if (!precondtionerIsBuilt_) {
573 if ( !precType.compare(
"FROSch") ){
574 Teuchos::ArrayRCP<FROSch::DofOrdering> dofOrderings(numberOfBlocks);
575 Teuchos::ArrayRCP<UN> dofsPerNodeVector(numberOfBlocks);
576 for (UN i = 0; i < numberOfBlocks; i++) {
577 dofsPerNodeVector[i] = (UN) pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").get(
"DofsPerNode" + std::to_string(i+1), 1);
579 TEUCHOS_TEST_FOR_EXCEPTION( timeProblem_.is_null(), std::logic_error,
"FSI time problem is null!" );
580 TEUCHOS_TEST_FOR_EXCEPTION( timeProblem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"We should not be able to use P0 for interface coupling." );
583 MapConstPtr_Type mapConstTmp =timeProblem_->getDomain(i)->getInterfaceMapUnique();
584 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
585 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
587 repeatedMaps[i] = mapX;
590 if (useRepeatedMaps) {
591 if (dofsPerNodeVector[i] > 1){
593 if (!problem_.is_null()) {
594 if (problem_->getDomain(i)->getFEType() ==
"P0") {
595 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Vector field map not implemented for P0 elements.");
601 MapConstPtr_Type mapConstTmp = problem_->getDomain(i)->getMapVecFieldRepeated();
602 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
603 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
605 repeatedMaps[i] = mapX;
608 else if(!timeProblem_.is_null()){
609 if (timeProblem_->getDomain(i)->getFEType() ==
"P0") {
610 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Vector field map not implemented for P0 elements.");
615 MapConstPtr_Type mapConstTmp = timeProblem_->getDomain(i)->getMapVecFieldRepeated();
616 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
617 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
619 repeatedMaps[i] = mapX;
623 if (!problem_.is_null()){
624 if (problem_->getDomain(i)->getFEType() ==
"P0") {
627 MapConstPtr_Type mapConstTmp = problem_->getDomain(i)->getElementMap();
628 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
629 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
633 repeatedMaps[i] = mapX;
638 MapConstPtr_Type mapConstTmp = problem_->getDomain(i)->getMapRepeated();
639 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
640 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
642 std::cout <<
" +++++++++ Output 3" << std::endl;
643 Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
644 mapX->describe(*out,Teuchos::VERB_EXTREME);
645 repeatedMaps[i] = mapX;
648 else if (!timeProblem_.is_null()){
649 if (timeProblem_->getDomain(i)->getFEType() ==
"P0") {
652 MapConstPtr_Type mapConstTmp = timeProblem_->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);
656 repeatedMaps[i] = mapX;
661 MapConstPtr_Type mapConstTmp = timeProblem_->getDomain(i)->getMapRepeated();
662 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
663 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
665 repeatedMaps[i] = mapX;
671 if (!pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").get(
"DofOrdering" + std::to_string(i+1),
"NodeWise" ).compare(
"DimensionWise"))
672 dofOrderings[i] = FROSch::DimensionWise;
673 else if (!pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").get(
"DofOrdering" + std::to_string(i+1),
"NodeWise" ).compare(
"NodeWise"))
674 dofOrderings[i] = FROSch::NodeWise;
676 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Please chose a valid DOF ordering for ThyraPreconditioner(FROSch).");
681 if (!problem_.is_null())
682 dim = problem_->getDomain(0)->getDimension();
683 else if(!timeProblem_.is_null())
684 dim = timeProblem_->getDomain(0)->getDimension();
686 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Dimension", dim);
687 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Repeated Map Vector",repeatedMaps);
688 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Coordinates List Vector",nodeListVec);
689 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"DofOrdering Vector",dofOrderings);
690 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"DofsPerNode Vector",dofsPerNodeVector);
691 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Mpi Ranks Coarse",parameterList->sublist(
"General").get(
"Mpi Ranks Coarse",0) );
697 int lowerBound = 100000000;
699 for (UN i = 0; i < numberOfBlocks; i++) {
700 tuple_intint_Type rankRange;
701 if (!problem_.is_null())
702 rankRange = problem_->getDomain(i)->getMesh()->getRankRange();
703 else if(!timeProblem_.is_null())
704 rankRange = timeProblem_->getDomain(i)->getMesh()->getRankRange();
706 if (std::get<0>(rankRange) < lowerBound)
707 lowerBound = std::get<0>(rankRange);
708 if (std::get<1>(rankRange) > upperBound)
709 upperBound = std::get<1>(rankRange);
712 int lowerBoundCoarse = lowerBound;
713 int upperBoundCoarse = upperBound;
715 if ( parameterList->sublist(
"General").get(
"Mpi Ranks Coarse",0) > 0 ){
716 lowerBoundCoarse = upperBound + 1;
717 upperBoundCoarse = comm->getSize() - 1;
720 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
721 std::cout <<
"\t --- Range for local problems of preconditioner from " << lowerBound <<
" to " << upperBound << std::endl;
722 std::cout <<
"\t --- Range for coarse problem of preconditioner from " << lowerBoundCoarse <<
" to " << upperBoundCoarse << std::endl;
723 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
726 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Local problem ranks lower bound", lowerBound );
727 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Local problem ranks upper bound", upperBound );
729 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Coarse problem ranks lower bound", lowerBoundCoarse );
730 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Coarse problem ranks upper bound", upperBoundCoarse );
737 ParameterListPtr_Type pListThyraSolver = sublist( parameterList,
"ThyraSolver" );
738 pListThyraSolver->setParameters( *pListThyraPrec );
740 LinSolverBuilderPtr_Type solverBuilder;
741 if (!problem_.is_null())
742 solverBuilder = problem_->getLinearSolverBuilder();
743 else if(!timeProblem_.is_null())
744 solverBuilder = timeProblem_->getUnderlyingProblem()->getLinearSolverBuilder();
747 pListPhiExport_ = pListThyraSolver;
749 solverBuilder->setParameterList(pListThyraSolver);
750 precFactory_ = solverBuilder->createPreconditioningStrategy(
"");
752 if ( thyraPrec_.is_null() )
753 thyraPrec_ = precFactory_->createPrec();
756 Thyra::initializePrec<SC>(*precFactory_, thyraMatrix, thyraPrec_.ptr());
757 precondtionerIsBuilt_ =
true;
761 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unknown preconditioner type; You can only compute a FROSch preconditioner here." );
764 TEUCHOS_TEST_FOR_EXCEPTION( precFactory_.is_null(), std::runtime_error,
"precFactory_ is null.");
765 Thyra::initializePrec<SC>(*precFactory_, thyraMatrix, thyraPrec_.ptr());
768 if (parameterList->sublist(
"Exporter" ).get(
"Export coarse functions",
false))
769 exportCoarseBasisFSI();
775template <
class SC,
class LO,
class GO,
class NO>
776void Preconditioner<SC,LO,GO,NO>::buildPreconditionerTeko( )
779 Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
781 ParameterListPtr_Type parameterList;
782 if (!problem_.is_null())
783 parameterList = problem_->getParameterList();
784 else if(!timeProblem_.is_null())
785 parameterList = timeProblem_->getParameterList();
787 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Preconditioner can not be used without a problem.");
790 LinSolverBuilderPtr_Type solverBuilder;
791 if (!problem_.is_null())
792 solverBuilder = problem_->getLinearSolverBuilder();
793 else if(!timeProblem_.is_null())
794 solverBuilder = timeProblem_->getUnderlyingProblem()->getLinearSolverBuilder();
796 ParameterListPtr_Type tekoPList;
797 if (precFactory_.is_null()) {
798 ParameterListPtr_Type tmpSubList = sublist( sublist( sublist( sublist( parameterList,
"Teko Parameters" ) ,
"Preconditioner Types" ) ,
"Teko" ) ,
"Inverse Factory Library" );
800 tekoPList = sublist( parameterList,
"Teko Parameters" );
803 if ( !tmpSubList->sublist(
"FROSch-Pressure").get(
"Type",
"FROSch").compare(
"FROSch") &&
804 !tmpSubList->sublist(
"FROSch-Velocity").get(
"Type",
"FROSch").compare(
"FROSch") ) {
805 setVelocityParameters( tekoPList, parameterList->sublist(
"General").get(
"Mpi Ranks Coarse",0) );
806 setPressureParameters( tekoPList, parameterList->sublist(
"General").get(
"Mpi Ranks Coarse",0) );
810 BlockMatrixPtr_Type system;
811 if (!problem_.is_null())
812 system = problem_->getSystem();
813 else if(!timeProblem_.is_null())
814 system = timeProblem_->getSystemCombined();
816 TEUCHOS_TEST_FOR_EXCEPTION( system->size()!=2, std::logic_error,
"Wrong size of system for Teko-Block-Preconditioners.");
818 Teko::LinearOp thyraF = system->getBlock(0,0)->getThyraLinOp();
819 Teko::LinearOp thyraBT = system->getBlock(0,1)->getThyraLinOp();
820 Teko::LinearOp thyraB = system->getBlock(1,0)->getThyraLinOp();
822 if (!system->blockExists(1,1)){
823 MatrixPtr_Type dummy;
824 dummy.reset(
new Matrix_Type( system->getBlock(1,0)->getMap(), 1 ) );
825 dummy->fillComplete();
826 system->addBlock( dummy, 1, 1 );
828 Teko::LinearOp thyraC = system->getBlock(1,1)->getThyraLinOp();
830 tekoLinOp_ = Thyra::block2x2(thyraF,thyraBT,thyraB,thyraC);
832 if (!precondtionerIsBuilt_) {
834 if ( precFactory_.is_null() ){
835 ParameterListPtr_Type pListThyraSolver = sublist( parameterList,
"ThyraSolver" );
837 pListThyraSolver->setParameters( *tekoPList );
839 solverBuilder->setParameterList( pListThyraSolver );
840 precFactory_ = solverBuilder->createPreconditioningStrategy(
"");
841 Teuchos::RCP<Teko::RequestHandler> rh = Teuchos::rcp(
new Teko::RequestHandler());
843 Teko::LinearOp thyraMass = velocityMassMatrix_;
845 Teuchos::RCP< Teko::StaticRequestCallback<Teko::LinearOp> > callbackMass = Teuchos::rcp(
new Teko::StaticRequestCallback<Teko::LinearOp> (
"Velocity Mass Matrix", thyraMass ) );
846 rh->addRequestCallback( callbackMass );
848 Teuchos::RCP< Teko::StratimikosFactory > tekoFactory = Teuchos::rcp_dynamic_cast<Teko::StratimikosFactory>(precFactory_);
849 tekoFactory->setRequestHandler( rh );
853 if ( thyraPrec_.is_null() ){
854 thyraPrec_ = precFactory_->createPrec();
857 Teuchos::RCP< const Thyra::DefaultLinearOpSource< SC > > thyraMatrixSourceOp = defaultLinearOpSource (tekoLinOp_);
860 precFactory_->initializePrec(thyraMatrixSourceOp, thyraPrec_.get());
861 precondtionerIsBuilt_ =
true;
867 Teuchos::RCP< const Thyra::DefaultLinearOpSource< SC > > thyraMatrixSourceOp = defaultLinearOpSource (tekoLinOp_);
870 precFactory_->initializePrec(thyraMatrixSourceOp, thyraPrec_.get());
875template <
class SC,
class LO,
class GO,
class NO>
876void Preconditioner<SC,LO,GO,NO>::buildPreconditionerFaCSI( std::string type )
878 typedef Domain<SC,LO,GO,NO> Domain_Type;
879 typedef Teuchos::RCP<const Domain_Type> DomainConstPtr_Type;
880 typedef std::vector<DomainConstPtr_Type> DomainConstPtr_vec_Type;
882 Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
884 ParameterListPtr_Type parameterList;
885 if (!timeProblem_.is_null())
886 parameterList = timeProblem_->getParameterList();
888 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Preconditioner can not be used without a time problem.");
891 ProblemPtr_Type steadyProblem = timeProblem_->getUnderlyingProblem();
892 Teuchos::RCP< FSI<SC,LO,GO,NO> > steadyFSI = Teuchos::rcp_dynamic_cast<FSI<SC,LO,GO,NO> >(steadyProblem);
893 BlockMatrixPtr_Type fsiSystem = timeProblem_->getSystemCombined();
895 ParameterListPtr_Type pLFluid = steadyFSI->getFluidProblem()->getParameterList();
897 std::string precTypeFluid;
899 precTypeFluid =
"Monolithic";
900 else if (type ==
"FaCSI-Teko")
901 precTypeFluid =
"Teko";
903 CommConstPtr_Type comm = timeProblem_->getComm();
904 bool useFluidPreconditioner = parameterList->sublist(
"General").get(
"Use Fluid Preconditioner",
true);
905 bool useSolidPreconditioner = parameterList->sublist(
"General").get(
"Use Solid Preconditioner",
true);
906 bool onlyDiagonal = parameterList->sublist(
"General").get(
"Only Diagonal",
false);
907 Teuchos::RCP< PrecOpFaCSI<SC,LO,GO,NO> > facsi
908 = Teuchos::rcp(
new PrecOpFaCSI<SC,LO,GO,NO> ( comm, precTypeFluid ==
"Monolithic", useFluidPreconditioner, useSolidPreconditioner, onlyDiagonal) );
910 if (comm->getRank() == 0) {
912 std::cout <<
"\t### No preconditioner will be used! ###" << std::endl;
914 std::cout <<
"\t### FaCSI standard ###" << std::endl;
919 if (probFluid_.is_null()){
920 probFluid_ = Teuchos::rcp(
new MinPrecProblem_Type( pLFluid, timeProblem_->getComm() ) );
921 DomainConstPtr_vec_Type fluidDomains = steadyFSI->getFluidProblem()->getDomainVector();
922 probFluid_->initializeDomains( fluidDomains );
923 probFluid_->initializeLinSolverBuilder( timeProblem_->getLinearSolverBuilder() );
926 BlockMatrixPtr_Type fluidSystem = Teuchos::rcp(
new BlockMatrix_Type(2) );
929 MatrixPtr_Type f = Teuchos::rcp(
new Matrix_Type( fsiSystem->getBlock(0,0) ) );
930 MatrixPtr_Type bt = Teuchos::rcp(
new Matrix_Type( fsiSystem->getBlock(0,1) ) );
931 MatrixPtr_Type b = Teuchos::rcp(
new Matrix_Type( fsiSystem->getBlock(1,0) ) );
933 if ( fsiSystem->blockExists(1,1) )
934 c = Teuchos::rcp(
new Matrix_Type( fsiSystem->getBlock(1,1) ) );
935 fluidSystem->addBlock( f, 0, 0 );
936 fluidSystem->addBlock( bt, 0, 1 );
937 fluidSystem->addBlock( b, 1, 0 );
938 if ( fsiSystem->blockExists(1,1) )
939 fluidSystem->addBlock( c, 1, 1 );
941 faCSIBCFactory_->setSystem( fluidSystem );
943 probFluid_->initializeSystem( fluidSystem );
945 probFluid_->setupPreconditioner( precTypeFluid );
947 precFluid_ = probFluid_->getPreconditioner()->getThyraPrec()->getNonconstUnspecifiedPrecOp();
950 bool nonlinearStructure =
false;
951 if (steadyFSI->getStructureProblem().is_null())
952 nonlinearStructure =
true;
954 ParameterListPtr_Type pLStructure;
955 if (nonlinearStructure)
956 pLStructure = steadyFSI->getNonLinStructureProblem()->getParameterList();
958 pLStructure = steadyFSI->getStructureProblem()->getParameterList();
960 if (probSolid_.is_null()){
961 probSolid_ = Teuchos::rcp(
new MinPrecProblem_Type( pLStructure, timeProblem_->getComm() ) );
962 DomainConstPtr_vec_Type structDomain;
963 if (nonlinearStructure)
964 structDomain = steadyFSI->getNonLinStructureProblem()->getDomainVector();
966 structDomain = steadyFSI->getStructureProblem()->getDomainVector();
968 probSolid_->initializeDomains( structDomain );
969 probSolid_->initializeLinSolverBuilder( timeProblem_->getLinearSolverBuilder() );
972 BlockMatrixPtr_Type structSystem = Teuchos::rcp(
new BlockMatrix_Type(1) );
974 structSystem->addBlock( fsiSystem->getBlock(2,2), 0, 0 );
976 probSolid_->initializeSystem( structSystem );
978 probSolid_->setupPreconditioner( );
980 precStruct_ = probSolid_->getPreconditioner()->getThyraPrec()->getNonconstUnspecifiedPrecOp();
985 if (timeProblem_->getSystem()->size()>4) {
986 ParameterListPtr_Type pLGeometry = steadyFSI->getGeometryProblem()->getParameterList();
987 if (probGeo_.is_null()) {
988 probGeo_ = Teuchos::rcp(
new MinPrecProblem_Type( pLGeometry, timeProblem_->getComm() ) );
989 DomainConstPtr_vec_Type geoDomain = steadyFSI->getGeometryProblem()->getDomainVector();
990 probGeo_->initializeDomains( geoDomain );
991 probGeo_->initializeLinSolverBuilder( timeProblem_->getLinearSolverBuilder() );
994 BlockMatrixPtr_Type geoSystem = Teuchos::rcp(
new BlockMatrix_Type(1) );
996 geoSystem->addBlock( fsiSystem->getBlock(4,4), 0, 0 );
998 probGeo_->initializeSystem( geoSystem );
1000 probGeo_->setupPreconditioner( );
1002 precGeo_ = probGeo_->getPreconditioner()->getThyraPrec()->getNonconstUnspecifiedPrecOp();
1005 if (fsiSystem->size()>4) {
1007 facsi->setGIShape( fsiSystem->getBlock(3,0)->getThyraLinOpNonConst(),
1008 fsiSystem->getBlock(0,3)->getThyraLinOpNonConst(),
1009 fsiSystem->getBlock(3,2)->getThyraLinOpNonConst(),
1010 fsiSystem->getBlock(4,2)->getThyraLinOpNonConst(),
1013 fsiSystem->getBlock(0,0)->getThyraLinOpNonConst(),
1014 fsiSystem->getBlock(0,1)->getThyraLinOpNonConst(),
1016 fsiSystem->getBlock(0,4)->getThyraLinOpNonConst(),
1017 fsiSystem->getBlock(1,4)->getThyraLinOpNonConst() );
1020 facsi->setGI( fsiSystem->getBlock(3,0)->getThyraLinOpNonConst(),
1021 fsiSystem->getBlock(0,3)->getThyraLinOpNonConst(),
1022 fsiSystem->getBlock(3,2)->getThyraLinOpNonConst(),
1023 fsiSystem->getBlock(4,2)->getThyraLinOpNonConst(),
1026 fsiSystem->getBlock(0,0)->getThyraLinOpNonConst(),
1027 fsiSystem->getBlock(0,1)->getThyraLinOpNonConst(),
1032 facsi->setGE( fsiSystem->getBlock(3,0)->getThyraLinOpNonConst(),
1033 fsiSystem->getBlock(0,3)->getThyraLinOpNonConst(),
1034 fsiSystem->getBlock(3,2)->getThyraLinOpNonConst(),
1037 fsiSystem->getBlock(0,0)->getThyraLinOpNonConst(),
1038 fsiSystem->getBlock(0,1)->getThyraLinOpNonConst() );
1041 LinSolverBuilderPtr_Type solverBuilder = timeProblem_->getUnderlyingProblem()->getLinearSolverBuilder();
1043 if ( precFactory_.is_null() )
1044 precFactory_ = solverBuilder->createPreconditioningStrategy(
"");
1046 if ( thyraPrec_.is_null() )
1047 thyraPrec_ = precFactory_->createPrec();
1049 Teuchos::RCP< Thyra::DefaultPreconditioner<SC> > defaultPrec =
1050 Teuchos::rcp_dynamic_cast< Thyra::DefaultPreconditioner<SC> > (thyraPrec_);
1051 ThyraLinOpPtr_Type linOp =
1052 Teuchos::rcp_dynamic_cast< Thyra::LinearOpBase<SC> > (facsi);
1054 defaultPrec->initializeUnspecified( linOp );
1056 precondtionerIsBuilt_ =
true;
1060template <
class SC,
class LO,
class GO,
class NO>
1061void Preconditioner<SC,LO,GO,NO>::setPressureMassMatrix(MatrixPtr_Type massMatrix)
const{
1062 pressureMassMatrix_ = massMatrix;
1065template <
class SC,
class LO,
class GO,
class NO>
1066void Preconditioner<SC,LO,GO,NO>::buildPreconditionerBlock2x2( )
1069 typedef Domain<SC,LO,GO,NO> Domain_Type;
1070 typedef Teuchos::RCP<const Domain_Type> DomainConstPtr_Type;
1071 typedef std::vector<DomainConstPtr_Type> DomainConstPtr_vec_Type;
1073 Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
1075 ParameterListPtr_Type parameterList;
1076 BlockMatrixPtr_Type system;
1077 CommConstPtr_Type comm;
1078 ProblemPtr_Type steadyProblem;
1079 if (!timeProblem_.is_null()){
1080 parameterList = timeProblem_->getParameterList();
1081 system = timeProblem_->getSystem();
1082 comm = timeProblem_->getComm();
1083 steadyProblem = timeProblem_->getUnderlyingProblem();
1086 parameterList = problem_->getParameterList();
1087 system = problem_->getSystem();
1088 comm = problem_->getComm();
1089 steadyProblem = problem_;
1091 bool verbose( comm->getRank() == 0 );
1094 std::cout <<
" ############## " << std::endl;
1095 std::cout <<
" Build Preconditioner " << std::endl;
1096 std::cout <<
" ############## " << std::endl;
1098 ParameterListPtr_Type plVelocity(
new Teuchos::ParameterList( parameterList->sublist(
"Velocity preconditioner") ) );
1099 ParameterListPtr_Type plSchur(
new Teuchos::ParameterList( parameterList->sublist(
"Schur complement preconditioner") ) );
1102 plVelocity->sublist(
"General").setParameters(parameterList->sublist(
"General"));
1103 plSchur->sublist(
"General").setParameters(parameterList->sublist(
"General"));
1105 Teuchos::RCP< PrecBlock2x2<SC,LO,GO,NO> > blockPrec2x2
1106 = Teuchos::rcp(
new PrecBlock2x2<SC,LO,GO,NO> ( comm ) );
1108 if (probVelocity_.is_null()){
1109 probVelocity_ = Teuchos::rcp(
new MinPrecProblem_Type( plVelocity, comm ) );
1110 DomainConstPtr_vec_Type domain1(0);
1111 domain1.push_back( steadyProblem->getDomain(0) );
1112 probVelocity_->initializeDomains( domain1 );
1113 probVelocity_->initializeLinSolverBuilder( steadyProblem->getLinearSolverBuilder() );
1116 BlockMatrixPtr_Type system1 = Teuchos::rcp(
new BlockMatrix_Type(1) );
1118 MatrixPtr_Type F = system->getBlock(0,0);
1120 system1->addBlock( F, 0, 0 );
1122 probVelocity_->initializeSystem( system1 );
1124 probVelocity_->setupPreconditioner(
"Monolithic" );
1126 precVelocity_ = probVelocity_->getPreconditioner()->getThyraPrec()->getNonconstUnspecifiedPrecOp();
1128 if (probSchur_.is_null()) {
1129 if(!timeProblem_.is_null()){
1130 probSchur_ = Teuchos::rcp(
new MinPrecProblem_Type( plSchur, comm ) );
1131 DomainConstPtr_vec_Type domain2(0);
1132 domain2.push_back( timeProblem_->getDomain(1) );
1133 probSchur_->initializeDomains( domain2 );
1134 probSchur_->initializeLinSolverBuilder( timeProblem_->getLinearSolverBuilder() );
1138 probSchur_ = Teuchos::rcp(
new MinPrecProblem_Type( plSchur, comm ) );
1139 DomainConstPtr_vec_Type domain2(0);
1140 domain2.push_back( problem_->getDomain(1) );
1141 probSchur_->initializeDomains( domain2 );
1142 probSchur_->initializeLinSolverBuilder( problem_->getLinearSolverBuilder() );
1149 BlockMatrixPtr_Type system2 = Teuchos::rcp(
new BlockMatrix_Type(1) );
1151 system2->addBlock( pressureMassMatrix_, 0, 0 );
1153 probSchur_->initializeSystem( system2 );
1155 probSchur_->setupPreconditioner(
"Monolithic" );
1157 precSchur_ = probSchur_->getPreconditioner()->getThyraPrec()->getNonconstUnspecifiedPrecOp();
1160 std::string type = parameterList->sublist(
"General").get(
"Preconditioner Method",
"Diagonal");
1161 if (type ==
"Diagonal") {
1162 blockPrec2x2->setDiagonal(precVelocity_,
1165 else if (type ==
"Triangular") {
1166 ThyraLinOpPtr_Type BT = system->getBlock(0,1)->getThyraLinOpNonConst();
1167 blockPrec2x2->setTriangular(precVelocity_,
1172 LinSolverBuilderPtr_Type solverBuilder;
1173 if (!timeProblem_.is_null())
1174 solverBuilder = timeProblem_->getLinearSolverBuilder();
1176 solverBuilder = problem_->getLinearSolverBuilder();
1178 if ( precFactory_.is_null() )
1179 precFactory_ = solverBuilder->createPreconditioningStrategy(
"");
1181 if ( thyraPrec_.is_null() )
1182 thyraPrec_ = precFactory_->createPrec();
1184 Teuchos::RCP< Thyra::DefaultPreconditioner<SC> > defaultPrec =
1185 Teuchos::rcp_dynamic_cast< Thyra::DefaultPreconditioner<SC> > (thyraPrec_);
1186 ThyraLinOpPtr_Type linOp =
1187 Teuchos::rcp_dynamic_cast< Thyra::LinearOpBase<SC> > (blockPrec2x2);
1189 defaultPrec->initializeUnspecified( linOp );
1191 precondtionerIsBuilt_ =
true;
1197template <
class SC,
class LO,
class GO,
class NO>
1198void Preconditioner<SC,LO,GO,NO>::setVelocityParameters( ParameterListPtr_Type parameterList,
int coarseRanks )
1200 CommConstPtr_Type comm;
1201 if (!problem_.is_null())
1202 comm = problem_->getComm();
1203 else if(!timeProblem_.is_null())
1204 comm = timeProblem_->getComm();
1206 bool verbose( comm->getRank() == 0 );
1209 Teuchos::ArrayRCP<Teuchos::RCP<Xpetra::Map<LO,GO,NO> > > repeatedMaps(1);
1210 typedef Xpetra::Map<LO,GO,NO> XpetraMap_Type;
1211 typedef Teuchos::RCP<XpetraMap_Type> XpetraMapPtr_Type;
1212 typedef Teuchos::RCP<const XpetraMap_Type> XpetraMapConstPtr_Type;
1213 typedef const XpetraMapConstPtr_Type XpetraMapConstPtrConst_Type;
1215 Teuchos::ArrayRCP<FROSch::DofOrdering> dofOrderings(1);
1216 Teuchos::ArrayRCP<UN> dofsPerNodeVector(1);
1217 ParameterListPtr_Type velocitySubList = sublist( sublist( sublist( sublist( parameterList,
"Preconditioner Types" ) ,
"Teko" ) ,
"Inverse Factory Library" ) ,
"FROSch-Velocity" );
1218 dofsPerNodeVector[0] = (UN) velocitySubList->get(
"DofsPerNode", 2);
1219 TEUCHOS_TEST_FOR_EXCEPTION(dofsPerNodeVector[0]<2, std::logic_error,
"DofsPerNode for velocity must be atleast 2.");
1229 MapConstPtr_Type mapConstTmp;
1230 if (!problem_.is_null())
1231 mapConstTmp = problem_->getDomain(0)->getMapVecFieldRepeated();
1232 else if(!timeProblem_.is_null())
1233 mapConstTmp = timeProblem_->getDomain(0)->getMapVecFieldRepeated();
1235 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
1236 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
1238 repeatedMaps[0] = mapX;
1240 if (!velocitySubList->get(
"DofOrdering",
"NodeWise" ).compare(
"DimensionWise"))
1241 dofOrderings[0] = FROSch::DimensionWise;
1242 else if (!velocitySubList->get(
"DofOrdering",
"NodeWise" ).compare(
"NodeWise"))
1243 dofOrderings[0] = FROSch::NodeWise;
1245 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Please chose a valid DOF ordering for ThyraPreconditioner(FROSch).");
1247 velocitySubList->set(
"Repeated Map Vector",repeatedMaps);
1248 velocitySubList->set(
"DofOrdering Vector",dofOrderings);
1249 velocitySubList->set(
"DofsPerNode Vector",dofsPerNodeVector);
1250 velocitySubList->set(
"Mpi Ranks Coarse", coarseRanks );
1252 int lowerBound = 100000000;
1253 int upperBound = -1;
1255 tuple_intint_Type rankRange;
1256 if (!problem_.is_null())
1257 rankRange = problem_->getDomain(0)->getMesh()->getRankRange();
1258 else if(!timeProblem_.is_null())
1259 rankRange = timeProblem_->getDomain(0)->getMesh()->getRankRange();
1261 if (std::get<0>(rankRange) < lowerBound)
1262 lowerBound = std::get<0>(rankRange);
1263 if (std::get<1>(rankRange) > upperBound)
1264 upperBound = std::get<1>(rankRange);
1266 int lowerBoundCoarse = lowerBound;
1267 int upperBoundCoarse = upperBound;
1269 if ( coarseRanks > 0 ){
1270 lowerBoundCoarse = upperBound + 1;
1271 upperBoundCoarse = comm->getSize() - 1;
1274 std::cout <<
"\t --- ------------------------------------------------------------------- ---"<< std::endl;
1275 std::cout <<
"\t --- Range for local problems of preconditioner Teko velocity from " << lowerBound <<
" to " << upperBound << std::endl;
1276 std::cout <<
"\t --- Range for coarse problem of preconditioner Teko velocity from " << lowerBoundCoarse <<
" to " << upperBoundCoarse << std::endl;
1277 std::cout <<
"\t --- ------------------------------------------------------------------- ---"<< std::endl;
1280 velocitySubList->set(
"Local problem ranks lower bound", lowerBound );
1281 velocitySubList->set(
"Local problem ranks upper bound", upperBound );
1283 velocitySubList->set(
"Coarse problem ranks lower bound", lowerBoundCoarse );
1284 velocitySubList->set(
"Coarse problem ranks upper bound", upperBoundCoarse );
1291template <
class SC,
class LO,
class GO,
class NO>
1292void Preconditioner<SC,LO,GO,NO>::setPressureParameters( ParameterListPtr_Type parameterList,
int coarseRanks )
1294 CommConstPtr_Type comm;
1295 if (!problem_.is_null())
1296 comm = problem_->getComm();
1297 else if(!timeProblem_.is_null())
1298 comm = timeProblem_->getComm();
1300 bool verbose( comm->getRank() == 0 );
1302 Teuchos::ArrayRCP<Teuchos::RCP<Xpetra::Map<LO,GO,NO> > > repeatedMaps(1);
1303 typedef Xpetra::Map<LO,GO,NO> XpetraMap_Type;
1304 typedef Teuchos::RCP<XpetraMap_Type> XpetraMapPtr_Type;
1305 typedef Teuchos::RCP<const XpetraMap_Type> XpetraMapConstPtr_Type;
1306 typedef const XpetraMapConstPtr_Type XpetraMapConstPtrConst_Type;
1308 Teuchos::ArrayRCP<FROSch::DofOrdering> dofOrderings(1);
1309 Teuchos::ArrayRCP<UN> dofsPerNodeVector(1);
1310 ParameterListPtr_Type pressureSubList = sublist( sublist( sublist( sublist( parameterList,
"Preconditioner Types" ) ,
"Teko" ) ,
"Inverse Factory Library" ) ,
"FROSch-Pressure" );
1311 dofsPerNodeVector[0] = (UN) pressureSubList->get(
"DofsPerNode", 1);
1312 TEUCHOS_TEST_FOR_EXCEPTION(dofsPerNodeVector[0]!=1, std::logic_error,
"DofsPerNode for pressure must be 1.");
1328 MapConstPtr_Type mapConstTmp;
1329 if (!problem_.is_null()){
1330 if ( problem_->getDomain(1)->getFEType()==
"P0" )
1331 mapConstTmp = problem_->getDomain(1)->getElementMap();
1333 mapConstTmp = problem_->getDomain(1)->getMapRepeated();
1335 else if(!timeProblem_.is_null()){
1336 if ( timeProblem_->getDomain(1)->getFEType()==
"P0" )
1337 mapConstTmp = timeProblem_->getDomain(1)->getElementMap();
1339 mapConstTmp = timeProblem_->getDomain(1)->getMapRepeated();
1344 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
1345 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
1347 repeatedMaps[0] = mapX;
1349 if (!pressureSubList->get(
"DofOrdering",
"NodeWise" ).compare(
"DimensionWise"))
1350 dofOrderings[0] = FROSch::DimensionWise;
1351 else if (!pressureSubList->get(
"DofOrdering",
"NodeWise" ).compare(
"NodeWise"))
1352 dofOrderings[0] = FROSch::NodeWise;
1354 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Please chose a valid DOF ordering for ThyraPreconditioner(FROSch).");
1356 pressureSubList->set(
"Repeated Map Vector",repeatedMaps);
1357 pressureSubList->set(
"DofOrdering Vector",dofOrderings);
1358 pressureSubList->set(
"DofsPerNode Vector",dofsPerNodeVector);
1359 pressureSubList->set(
"Mpi Ranks Coarse", coarseRanks );
1361 int lowerBound = 100000000;
1362 int upperBound = -1;
1365 tuple_intint_Type rankRange;
1366 if (!problem_.is_null())
1367 rankRange = problem_->getDomain(1)->getMesh()->getRankRange();
1368 else if(!timeProblem_.is_null())
1369 rankRange = timeProblem_->getDomain(1)->getMesh()->getRankRange();
1371 if (std::get<0>(rankRange) < lowerBound)
1372 lowerBound = std::get<0>(rankRange);
1373 if (std::get<1>(rankRange) > upperBound)
1374 upperBound = std::get<1>(rankRange);
1376 int lowerBoundCoarse = lowerBound;
1377 int upperBoundCoarse = upperBound;
1379 if ( coarseRanks > 0 ){
1380 lowerBoundCoarse = upperBound + 1;
1381 upperBoundCoarse = comm->getSize() - 1;
1384 std::cout <<
"\t --- ------------------------------------------------------------------- ---"<< std::endl;
1385 std::cout <<
"\t --- Range for local problems of preconditioner Teko pressure from " << lowerBound <<
" to " << upperBound << std::endl;
1386 std::cout <<
"\t --- Range for coarse problem of preconditioner Teko pressure from " << lowerBoundCoarse <<
" to " << upperBoundCoarse << std::endl;
1387 std::cout <<
"\t --- ------------------------------------------------------------------- ---"<< std::endl;
1390 pressureSubList->set(
"Local problem ranks lower bound", lowerBound );
1391 pressureSubList->set(
"Local problem ranks upper bound", upperBound );
1393 pressureSubList->set(
"Coarse problem ranks lower bound", lowerBoundCoarse );
1394 pressureSubList->set(
"Coarse problem ranks upper bound", upperBoundCoarse );
1399template <
class SC,
class LO,
class GO,
class NO>
1400typename Preconditioner<SC,LO,GO,NO>::ThyraLinOpConstPtr_Type Preconditioner<SC,LO,GO,NO>::getTekoOp(){
1404template <
class SC,
class LO,
class GO,
class NO>
1405void Preconditioner<SC,LO,GO,NO>::setVelocityMassMatrix(MatrixPtr_Type massMatrix)
const{
1406 velocityMassMatrix_ = massMatrix->getThyraLinOp();
1410template <
class SC,
class LO,
class GO,
class NO>
1411void Preconditioner<SC,LO,GO,NO>::exportCoarseBasis( ){
1413 CommConstPtr_Type comm;
1414 if (!problem_.is_null())
1415 comm = problem_->getComm();
1416 else if(!timeProblem_.is_null())
1417 comm = timeProblem_->getComm();
1419 TEUCHOS_TEST_FOR_EXCEPTION( pListPhiExport_.is_null(), std::runtime_error,
"No parameterlist to extract Phi pointer.");
1420 ParameterListPtr_Type pLPrec = sublist( sublist( pListPhiExport_,
"Preconditioner Types" ) ,
"FROSch" );
1421 std::string coarseType = pLPrec->get(
"CoarseOperator Type",
"RGDSWCoarseOperator" );
1422 ParameterListPtr_Type pLCoarse = sublist( pLPrec, coarseType );
1425 TEUCHOS_TEST_FOR_EXCEPTION( !pLCoarse->isParameter(
"RCP(Phi)"), std::runtime_error,
"No parameter to extract Phi pointer.");
1427 Teuchos::RCP<Tpetra::CrsMatrix<SC,LO,GO,NO> > phiTpetra;
1429 TEUCHOS_TEST_FOR_EXCEPTION( !pLCoarse->isType<
decltype(phiTpetra)>(
"RCP(Phi)"), std::runtime_error,
"Wrong type of pointer to extract Phi.");
1431 phiTpetra = pLCoarse->get<
decltype(phiTpetra)>(
"RCP(Phi)");
1433 MatrixPtr_Type phiMatrix = Teuchos::rcp(
new Matrix_Type( phiTpetra ) );
1436 ParameterListPtr_Type parameterList;
1437 if (!problem_.is_null())
1438 parameterList = problem_->getParameterList();
1439 else if(!timeProblem_.is_null())
1440 parameterList = timeProblem_->getParameterList();
1441 numberOfBlocks = parameterList->get(
"Number of blocks",1);
1444 std::vector<MapConstPtr_Type> blockMaps(numberOfBlocks);
1445 MultiVectorPtr_Type phiMV;
1446 phiMatrix->toMV( phiMV );
1448 for (UN i = 0; i < numberOfBlocks; i++) {
1449 int dofsPerNode = pLPrec->get(
"DofsPerNode" + std::to_string(i+1), 1);
1450 MapConstPtr_Type map;
1451 if (dofsPerNode>1) {
1452 if (!problem_.is_null()) {
1453 TEUCHOS_TEST_FOR_EXCEPTION( problem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Vector field map not implemented for P0 elements.");
1454 map = problem_->getDomain(i)->getMapVecFieldUnique();
1456 else if(!timeProblem_.is_null()){
1457 TEUCHOS_TEST_FOR_EXCEPTION( timeProblem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Vector field map not implemented for P0 elements.");
1458 map = timeProblem_->getDomain(i)->getMapVecFieldUnique();
1462 if (!problem_.is_null()) {
1463 TEUCHOS_TEST_FOR_EXCEPTION( problem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Vector field map not implemented for P0 elements.");
1464 map = problem_->getDomain(i)->getMapUnique();
1466 else if(!timeProblem_.is_null()){
1467 TEUCHOS_TEST_FOR_EXCEPTION( timeProblem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Vector field map not implemented for P0 elements.");
1468 map = timeProblem_->getDomain(i)->getMapUnique();
1475 BlockMultiVectorPtr_Type phiBlockMV = Teuchos::rcp(
new BlockMultiVector_Type ( blockMaps, phiMV->getNumVectors() ) );
1476 phiBlockMV->setMergedVector( phiMV );
1477 phiBlockMV->split();
1479 ParameterListPtr_Type pLProblem;
1480 if (!problem_.is_null())
1481 pLProblem = problem_->getParameterList();
1482 else if(!timeProblem_.is_null())
1483 pLProblem = timeProblem_->getParameterList();
1485 BlockMultiVectorPtr_Type phiSumBlockMV = phiBlockMV->sumColumns();
1487 for (
int i=0; i<phiBlockMV->size(); i++) {
1488 bool exportThisBlock = !pLProblem->sublist(
"Exporter").get(
"Exclude coarse functions block" + std::to_string(i+1),
false);
1490 if (exportThisBlock){
1491 Teuchos::RCP<ExporterParaView<SC,LO,GO,NO> > exporter(
new ExporterParaView<SC,LO,GO,NO>());
1493 DomainConstPtr_Type domain;
1494 if (!problem_.is_null())
1495 domain = problem_->getDomain(i);
1496 else if(!timeProblem_.is_null())
1497 domain = timeProblem_->getDomain(i);
1499 int dofsPerNode = domain->getDimension();
1500 std::string fileName = pLProblem->sublist(
"Exporter").get(
"Name coarse functions block" + std::to_string(i+1),
"phi");
1502 MeshPtr_Type meshNonConst = Teuchos::rcp_const_cast<Mesh_Type>( domain->getMesh() );
1503 exporter->setup(fileName, meshNonConst, domain->getFEType());
1505 for (
int j=0; j<phiBlockMV->getNumVectors(); j++) {
1507 MultiVectorConstPtr_Type exportPhi = phiBlockMV->getBlock( i )->getVector( j );
1509 std::string varName = fileName + std::to_string(j);
1510 if ( pLPrec->get(
"DofsPerNode" + std::to_string(i+1), 1) > 1 )
1511 exporter->addVariable( exportPhi, varName,
"Vector", dofsPerNode, domain->getMapUnique() );
1513 exporter->addVariable( exportPhi, varName,
"Scalar", 1, domain->getMapUnique() );
1516 MultiVectorConstPtr_Type exportSumPhi = phiSumBlockMV->getBlock(i);
1517 std::string varName = fileName +
"Sum";
1518 if ( pLPrec->get(
"DofsPerNode" + std::to_string(i+1), 1) > 1 )
1519 exporter->addVariable( exportSumPhi, varName,
"Vector", dofsPerNode, domain->getMapUnique() );
1521 exporter->addVariable( exportSumPhi, varName,
"Scalar", 1, domain->getMapUnique() );
1523 exporter->save(0.0);
1529template <
class SC,
class LO,
class GO,
class NO>
1530void Preconditioner<SC,LO,GO,NO>::exportCoarseBasisFSI( ){
1532 CommConstPtr_Type comm;
1533 if (!problem_.is_null())
1534 comm = problem_->getComm();
1535 else if(!timeProblem_.is_null())
1536 comm = timeProblem_->getComm();
1538 TEUCHOS_TEST_FOR_EXCEPTION( pListPhiExport_.is_null(), std::runtime_error,
"No parameterlist to extract Phi pointer.");
1539 ParameterListPtr_Type pLPrec = sublist( sublist( pListPhiExport_,
"Preconditioner Types" ) ,
"FROSch" );
1540 std::string coarseType = pLPrec->get(
"CoarseOperator Type",
"RGDSWCoarseOperator" );
1541 ParameterListPtr_Type pLCoarse = sublist( pLPrec, coarseType );
1544 TEUCHOS_TEST_FOR_EXCEPTION( !pLCoarse->isParameter(
"Phi Pointer"), std::runtime_error,
"No parameter to extract Phi pointer.");
1546 Teuchos::RCP<Tpetra::CrsMatrix<SC,LO,GO,NO> > phiTpetra;
1548 TEUCHOS_TEST_FOR_EXCEPTION( !pLCoarse->isType<
decltype(phiTpetra)>(
"Phi Pointer"), std::runtime_error,
"Wrong type of pointer to extract Phi.");
1550 phiTpetra = pLCoarse->get<
decltype(phiTpetra)>(
"Phi Pointer");
1552 MatrixPtr_Type phiMatrix = Teuchos::rcp(
new Matrix_Type( phiTpetra ) );
1555 ParameterListPtr_Type parameterList;
1556 if (!problem_.is_null())
1557 parameterList = problem_->getParameterList();
1558 else if(!timeProblem_.is_null())
1559 parameterList = timeProblem_->getParameterList();
1560 numberOfBlocks = parameterList->get(
"Number of blocks",1);
1563 std::vector<MapConstPtr_Type> blockMaps(numberOfBlocks);
1564 MultiVectorPtr_Type phiMV;
1565 phiMatrix->toMV( phiMV );
1567 for (UN i = 0; i < numberOfBlocks; i++) {
1568 int dofsPerNode = pLPrec->get(
"DofsPerNode" + std::to_string(i+1), 1);
1569 MapConstPtr_Type map;
1571 map = timeProblem_->getDomain(i)->getInterfaceMapVecFieldUnique();
1574 if (dofsPerNode>1) {
1575 if (!problem_.is_null()) {
1576 TEUCHOS_TEST_FOR_EXCEPTION( problem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Vector field map not implemented for P0 elements.");
1577 map = problem_->getDomain(i)->getMapVecFieldUnique();
1579 else if(!timeProblem_.is_null()){
1580 TEUCHOS_TEST_FOR_EXCEPTION( timeProblem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Vector field map not implemented for P0 elements.");
1581 map = timeProblem_->getDomain(i)->getMapVecFieldUnique();
1585 if (!problem_.is_null()) {
1586 TEUCHOS_TEST_FOR_EXCEPTION( problem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Vector field map not implemented for P0 elements.");
1587 map = problem_->getDomain(i)->getMapUnique();
1589 else if(!timeProblem_.is_null()){
1590 TEUCHOS_TEST_FOR_EXCEPTION( timeProblem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Vector field map not implemented for P0 elements.");
1591 map = timeProblem_->getDomain(i)->getMapUnique();
1599 BlockMultiVectorPtr_Type phiBlockMV = Teuchos::rcp(
new BlockMultiVector_Type ( blockMaps, phiMV->getNumVectors() ) );
1600 phiBlockMV->setMergedVector( phiMV );
1601 phiBlockMV->split();
1603 ParameterListPtr_Type pLProblem;
1604 if (!problem_.is_null())
1605 pLProblem = problem_->getParameterList();
1606 else if(!timeProblem_.is_null())
1607 pLProblem = timeProblem_->getParameterList();
1609 BlockMultiVectorPtr_Type phiSumBlockMV = phiBlockMV->sumColumns();
1611 for (
int i=0; i<phiBlockMV->size(); i++) {
1612 bool exportThisBlock = !pLProblem->sublist(
"Exporter").get(
"Exclude coarse functions block" + std::to_string(i+1),
false);
1614 if (exportThisBlock){
1615 Teuchos::RCP<ExporterParaView<SC,LO,GO,NO> > exporter(
new ExporterParaView<SC,LO,GO,NO>());
1617 DomainConstPtr_Type domain;
1618 if (!problem_.is_null())
1619 domain = problem_->getDomain(i);
1620 else if(!timeProblem_.is_null())
1621 domain = timeProblem_->getDomain(i);
1623 int dofsPerNode = domain->getDimension();
1624 std::string fileName = pLProblem->sublist(
"Exporter").get(
"Name coarse functions block" + std::to_string(i+1),
"phi");
1626 MeshPtr_Type meshNonConst = Teuchos::rcp_const_cast<Mesh_Type>( domain->getMesh() );
1627 exporter->setup(fileName, meshNonConst, domain->getFEType());
1629 for (
int j=0; j<phiBlockMV->getNumVectors(); j++) {
1631 MultiVectorConstPtr_Type exportPhi = phiBlockMV->getBlock( i )->getVector( j );
1633 std::string varName = fileName + std::to_string(j);
1634 if ( pLPrec->get(
"DofsPerNode" + std::to_string(i+1), 1) > 1 )
1635 exporter->addVariable( exportPhi, varName,
"Vector", dofsPerNode, domain->getMapUnique() );
1637 exporter->addVariable( exportPhi, varName,
"Scalar", 1, domain->getMapUnique() );
1640 MultiVectorConstPtr_Type exportSumPhi = phiSumBlockMV->getBlock(i);
1641 std::string varName = fileName +
"Sum";
1642 if ( pLPrec->get(
"DofsPerNode" + std::to_string(i+1), 1) > 1 )
1643 exporter->addVariable( exportSumPhi, varName,
"Vector", dofsPerNode, domain->getMapUnique() );
1645 exporter->addVariable( exportSumPhi, varName,
"Scalar", 1, domain->getMapUnique() );
1647 exporter->save(0.0);
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement.cpp:5