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 <Thyra_DefaultZeroLinearOp_decl.hpp>
12#ifdef FEDD_HAVE_IFPACK2
13#include <Thyra_Ifpack2PreconditionerFactory_def.hpp>
16#include "feddlib/core/FE/Domain.hpp"
17#include "feddlib/core/General/BCBuilder.hpp"
19#include "feddlib/problems/abstract/MinPrecProblem.hpp"
20#include "feddlib/problems/abstract/Problem.hpp"
21#include "feddlib/problems/abstract/TimeProblem.hpp"
22#include "feddlib/problems/specific/NavierStokes.hpp"
23#include "feddlib/problems/specific/NonLinElasticity.hpp"
24#include "feddlib/problems/specific/LinElas.hpp"
25#include "feddlib/problems/specific/Geometry.hpp"
26#include "feddlib/problems/specific/FSI.hpp"
27#include "feddlib/problems/Solver/PrecOpFaCSI.hpp"
28#include "feddlib/problems/Solver/PrecBlock2x2.hpp"
40template <
class SC,
class LO,
class GO,
class NO>
41Preconditioner<SC,LO,GO,NO>::Preconditioner(Problem_Type* problem):
43precondtionerIsBuilt_(false),
59#ifdef PRECONDITIONER_TIMER
60,preconditionerTimer_ (Teuchos::TimeMonitor::getNewCounter(
"Preconditioner: Setup"))
63 problem_.reset( problem,
false );
65 Stratimikos::enableFROSch<LO,GO,NO>( *problem_->getLinearSolverBuilder() );
67#ifdef FEDD_HAVE_IFPACK2
68 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> CRSMat;
69 typedef Tpetra::Operator<SC,LO,GO,NO> TP_op;
70 typedef Thyra::PreconditionerFactoryBase<SC> Base;
71 typedef Thyra::Ifpack2PreconditionerFactory<CRSMat> Impl;
73 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> TpetraCrsMatrix_Type;
74 typedef Teuchos::RCP<TpetraCrsMatrix_Type> TpetraCrsMatrixPtr_Type;
76 problem_->getLinearSolverBuilder()->setPreconditioningStrategyFactory(Teuchos::abstractFactoryStd<Base, Impl>(),
"Ifpack2");
79 Teko::addTekoToStratimikosBuilder( *problem_->getLinearSolverBuilder() );
86template <
class SC,
class LO,
class GO,
class NO>
87Preconditioner<SC,LO,GO,NO>::Preconditioner(TimeProblem_Type* problem):
89precondtionerIsBuilt_(false),
105#ifdef PRECONDITIONER_TIMER
106,preconditionerTimer_ (Teuchos::TimeMonitor::getNewCounter(
"Preconditioner: Setup"))
109 timeProblem_.reset( problem,
false );
112 if(!problem->getUnderlyingProblem()->preconditioner_->getPressureProjection().is_null()){
113 setPressureProjection(problem->getUnderlyingProblem()->preconditioner_->getPressureProjection());
116 if(!problem->getUnderlyingProblem()->preconditioner_->getVelocityMassMatrix().is_null()){
117 setVelocityMassMatrix(problem->getUnderlyingProblem()->preconditioner_->getVelocityMassMatrix());
120 if(!problem->getUnderlyingProblem()->preconditioner_->getPressureLaplaceMatrix().is_null()){
121 setPressureLaplaceMatrix(problem->getUnderlyingProblem()->preconditioner_->getPressureLaplaceMatrix());
123 if(!problem->getUnderlyingProblem()->preconditioner_->getPressureMassMatrix().is_null()){
124 setPressureMassMatrix(problem->getUnderlyingProblem()->preconditioner_->getPressureMassMatrix());
127 if(!problem->getUnderlyingProblem()->preconditioner_->getPCDOperatorMatrix().is_null()){
128 setPCDOperator(problem->getUnderlyingProblem()->preconditioner_->getPCDOperatorMatrix());
133template <
class SC,
class LO,
class GO,
class NO>
134Preconditioner<SC,LO,GO,NO>::~Preconditioner()
138template<
class SC,
class LO,
class GO,
class NO>
139void Preconditioner<SC,LO,GO,NO>::setPreconditionerThyraFromLinOp( ThyraLinOpPtr_Type precLinOp ){
140 TEUCHOS_TEST_FOR_EXCEPTION( thyraPrec_.is_null(), std::runtime_error,
"thyraPrec_ is null." );
141 Teuchos::RCP<Thyra::DefaultPreconditioner<SC> > defaultPrec = Teuchos::rcp_dynamic_cast<Thyra::DefaultPreconditioner<SC> > (thyraPrec_);
142 TEUCHOS_TEST_FOR_EXCEPTION( defaultPrec.is_null(), std::runtime_error,
"Cast to DefaultPrecondtioner failed." );
143 TEUCHOS_TEST_FOR_EXCEPTION( precLinOp.is_null(), std::runtime_error,
"precLinOp is null." );
144 defaultPrec->initializeUnspecified( precLinOp );
147template <
class SC,
class LO,
class GO,
class NO>
148typename Preconditioner<SC,LO,GO,NO>::ThyraPrecPtr_Type Preconditioner<SC,LO,GO,NO>::getThyraPrec(){
152template <
class SC,
class LO,
class GO,
class NO>
153typename Preconditioner<SC,LO,GO,NO>::ThyraPrecConstPtr_Type Preconditioner<SC,LO,GO,NO>::getThyraPrecConst()
const{
157template <
class SC,
class LO,
class GO,
class NO>
158void Preconditioner<SC,LO,GO,NO>::initializePreconditioner( std::string type )
160 if ( type ==
"Monolithic" || type ==
"FaCSI" || type ==
"Diagonal" || type ==
"Triangular"){
161 if (type ==
"Monolithic")
162 initPreconditionerMonolithic( );
163 else if (type ==
"FaCSI" || type ==
"Diagonal" || type ==
"Triangular" || type ==
"PCD" || type ==
"LSC")
164 initPreconditionerBlock( );
167 else if (type ==
"Teko" || type ==
"FaCSI-Teko" || type ==
"FaCSI-Block"){
168 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Please construct the Teko precondtioner completely.");
171 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unkown preconditioner type for initialization.");
174template <
class SC,
class LO,
class GO,
class NO>
176 pressureProjection_ = pressureProjection;
179template <
class SC,
class LO,
class GO,
class NO>
180void Preconditioner<SC,LO,GO,NO>::initPreconditionerMonolithic( )
183 LinSolverBuilderPtr_Type solverBuilder;
184 Teuchos::RCP<const Thyra::VectorSpaceBase<SC> > thyraRangeSpace;
185 Teuchos::RCP<const Thyra::VectorSpaceBase<SC> > thyraDomainSpace;
187 if (!problem_.is_null()){
188 solverBuilder = problem_->getLinearSolverBuilder();
189 thyraRangeSpace = Thyra::tpetraVectorSpace<SC,LO,GO,NO>( problem_->getSystem()->getMap()->getMergedMap()->getTpetraMap());
190 thyraDomainSpace = Thyra::tpetraVectorSpace<SC,LO,GO,NO>( problem_->getSystem()->getMap()->getMergedMap()->getTpetraMap());
192 else if(!timeProblem_.is_null()){
193 solverBuilder = timeProblem_->getUnderlyingProblem()->getLinearSolverBuilder();
194 thyraRangeSpace = Thyra::tpetraVectorSpace<SC,LO,GO,NO>( timeProblem_->getSystem()->getMap()->getMergedMap()->getTpetraMap() );
195 thyraDomainSpace = Thyra::tpetraVectorSpace<SC,LO,GO,NO>( timeProblem_->getSystem()->getMap()->getMergedMap()->getTpetraMap() );
199 Teuchos::RCP<Thyra::LinearOpBase<SC> > thyraLinOp = Teuchos::rcp(
new Thyra::DefaultZeroLinearOp<SC>( thyraRangeSpace, thyraDomainSpace ) );
201 Teuchos::RCP<Thyra::PreconditionerFactoryBase<SC> > precFactory = solverBuilder->createPreconditioningStrategy(
"");
202 thyraPrec_ = precFactory->createPrec();
204 Teuchos::RCP<Thyra::DefaultPreconditioner<SC> > defaultPrec = Teuchos::rcp_dynamic_cast<Thyra::DefaultPreconditioner<SC> >(thyraPrec_);
206 defaultPrec->initializeUnspecified(thyraLinOp);
209template <
class SC,
class LO,
class GO,
class NO>
210void Preconditioner<SC,LO,GO,NO>::initPreconditionerBlock( )
212 using Teuchos::Array;
215 BlockMultiVectorPtr_Type sol;
216 BlockMultiVectorPtr_Type rhs;
217 LinSolverBuilderPtr_Type solverBuilder;
219 if (!problem_.is_null()){
220 solverBuilder = problem_->getLinearSolverBuilder();
221 size = problem_->getSystem()->size();
222 sol = problem_->getSolution();
223 rhs = problem_->getRhs();
225 else if(!timeProblem_.is_null()){
226 solverBuilder = timeProblem_->getUnderlyingProblem()->getLinearSolverBuilder();
227 size = timeProblem_->getSystem()->size();
228 sol = timeProblem_->getSolution();
229 rhs = timeProblem_->getRhs();
232 Array< RCP< const Thyra::VectorSpaceBase< SC > > > vectorSpacesRange( size );
233 Array< RCP< const Thyra::VectorSpaceBase< SC > > > vectorSpacesDomain( size );
235 for (
int i=0; i<size; i++) {
236 vectorSpacesRange[i] = rhs->getBlock(i)->getMap()->getThyraVectorSpaceBase();
237 vectorSpacesDomain[i] = sol->getBlock(i)->getMap()->getThyraVectorSpaceBase();
240 RCP<const Thyra::DefaultProductVectorSpace<SC> > pR = Thyra::productVectorSpace<SC>( vectorSpacesRange );
241 RCP<const Thyra::DefaultProductVectorSpace<SC> > pD = Thyra::productVectorSpace<SC>( vectorSpacesDomain );
243 RCP<Thyra::LinearOpBase<SC> > thyraLinOp = rcp(
new Thyra::DefaultZeroLinearOp<SC>( pR, pD ) );
245 Teuchos::RCP<Thyra::PreconditionerFactoryBase<SC> > precFactory = solverBuilder->createPreconditioningStrategy(
"");
246 thyraPrec_ = precFactory->createPrec();
248 Teuchos::RCP<Thyra::DefaultPreconditioner<SC> > defaultPrec = Teuchos::rcp_dynamic_cast<Thyra::DefaultPreconditioner<SC> >(thyraPrec_);
250 defaultPrec->initializeUnspecified(thyraLinOp);
253template <
class SC,
class LO,
class GO,
class NO>
254void Preconditioner<SC,LO,GO,NO>::buildPreconditioner( std::string type )
257#ifdef PRECONDITIONER_TIMER
258 CommConstPtr_Type comm;
259 if (!problem_.is_null())
260 comm = problem_->getComm();
261 else if(!timeProblem_.is_null())
262 comm = timeProblem_->getComm();
264 Teuchos::TimeMonitor preconditionerTimeMonitor(*preconditionerTimer_);
267 if (!type.compare(
"Monolithic")){
268 buildPreconditionerMonolithic( );
270 else if (!type.compare(
"Teko")){
272 buildPreconditionerTeko( );
274 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Teko not found! Build Trilinos with Teko.");
277 else if( type ==
"FaCSI" || type ==
"FaCSI-Teko" || type ==
"FaCSI-Block" ){
278 buildPreconditionerFaCSI( type );
280 else if(type ==
"Triangular" || type ==
"Diagonal" || type ==
"PCD" || type ==
"LSC"){
281 buildPreconditionerBlock2x2( );
284 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unkown preconditioner type.");
286#ifdef PRECONDITIONER_TIMER
291template <
class SC,
class LO,
class GO,
class NO>
292void Preconditioner<SC,LO,GO,NO>::buildPreconditionerMonolithic( )
295 CommConstPtr_Type comm;
296 if (!problem_.is_null())
297 comm = problem_->getComm();
298 else if(!timeProblem_.is_null())
299 comm = timeProblem_->getComm();
301 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Preconditioner can not be used without a problem.");
303 bool verbose ( comm->getRank() == 0 );
305 ParameterListPtr_Type parameterList;
307 if (!problem_.is_null())
308 parameterList = problem_->getParameterList();
309 else if(!timeProblem_.is_null())
310 parameterList = timeProblem_->getParameterList();
312 std::string precType = parameterList->sublist(
"ThyraPreconditioner").get(
"Preconditioner Type",
"FROSch");
314 bool useRepeatedMaps = parameterList->get(
"Use repeated maps",
true );
315 bool useNodeLists = parameterList->get(
"Use node lists",
true );
316 ParameterListPtr_Type pListThyraPrec = sublist( parameterList,
"ThyraPreconditioner" );
317 ParameterListPtr_Type plFrosch = sublist( sublist( pListThyraPrec,
"Preconditioner Types" ),
"FROSch");
319 ThyraLinOpConstPtr_Type thyraMatrix;
320 if (!problem_.is_null())
321 thyraMatrix = problem_->getSystem()->getThyraLinOp();
322 else if(!timeProblem_.is_null())
323 thyraMatrix = timeProblem_->getSystemCombined()->getThyraLinOp();
325 UN numberOfBlocks = parameterList->get(
"Number of blocks",1);
327 typedef Tpetra::MultiVector<SC,LO,GO,NO> TMultiVector;
328 typedef Teuchos::RCP<TMultiVector> TMultiVectorPtr;
329 typedef Teuchos::ArrayRCP<TMultiVectorPtr> TMultiVectorPtrVecPtr;
333 typedef Xpetra::MultiVector<SC,LO,GO,NO> XMultiVector;
334 typedef Teuchos::RCP<XMultiVector> XMultiVectorPtr;
335 typedef Teuchos::ArrayRCP<XMultiVectorPtr> XMultiVectorPtrVecPtr;
337 typedef Xpetra::Map<LO,GO,NO> XpetraMap_Type;
338 typedef Teuchos::RCP<XpetraMap_Type> XpetraMapPtr_Type;
339 typedef Teuchos::RCP<const XpetraMap_Type> XpetraMapConstPtr_Type;
340 typedef const XpetraMapConstPtr_Type XpetraMapConstPtrConst_Type;
344 Teuchos::ArrayRCP<Teuchos::RCP<Xpetra::Map<LO,GO,NO> > > repeatedMaps(numberOfBlocks);
347 XMultiVectorPtrVecPtr nodeListVec( numberOfBlocks );
349 nodeListVec = Teuchos::null;
353 if (!precondtionerIsBuilt_) {
354 if ( !precType.compare(
"FROSch") ){
355 Teuchos::ArrayRCP<FROSch::DofOrdering> dofOrderings(numberOfBlocks);
356 Teuchos::ArrayRCP<UN> dofsPerNodeVector(numberOfBlocks);
357 for (UN i = 0; i < numberOfBlocks; i++) {
358 dofsPerNodeVector[i] = (UN) pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").get(
"DofsPerNode" + std::to_string(i+1), 1);
360 if (useRepeatedMaps) {
361 if (dofsPerNodeVector[i] > 1){
363 if (!problem_.is_null()) {
364 if (problem_->getDomain(i)->getFEType() ==
"P0") {
365 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Vector field map not implemented for P0 elements.");
371 MapConstPtr_Type mapConstTmp = problem_->getDomain(i)->getMapVecFieldRepeated();
372 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
373 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
375 repeatedMaps[i] = mapX;
379 else if(!timeProblem_.is_null()){
380 if (timeProblem_->getDomain(i)->getFEType() ==
"P0") {
381 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Vector field map not implemented for P0 elements.");
386 MapConstPtr_Type mapConstTmp = timeProblem_->getDomain(i)->getMapVecFieldRepeated();
387 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
388 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
390 repeatedMaps[i] = mapX;
394 if (!problem_.is_null()){
395 if (problem_->getDomain(i)->getFEType() ==
"P0") {
398 MapConstPtr_Type mapConstTmp = problem_->getDomain(i)->getElementMap();
399 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
400 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
402 repeatedMaps[i] = mapX;
407 MapConstPtr_Type mapConstTmp = problem_->getDomain(i)->getMapRepeated();
408 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
409 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
411 repeatedMaps[i] = mapX;
414 else if (!timeProblem_.is_null()){
415 if (timeProblem_->getDomain(i)->getFEType() ==
"P0") {
418 MapConstPtr_Type mapConstTmp = timeProblem_->getDomain(i)->getElementMap();
419 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
420 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
422 repeatedMaps[i] = mapX;
427 MapConstPtr_Type mapConstTmp = timeProblem_->getDomain(i)->getMapRepeated();
428 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
429 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
431 repeatedMaps[i] = mapX;
438 if (!problem_.is_null()){
439 TEUCHOS_TEST_FOR_EXCEPTION( problem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Node lists cannot be used for P0 elements." );
440 Teuchos::RCP< Tpetra::MultiVector<SC,LO,GO,NO> > nodeListTpetra = problem_->getDomain(i)->getNodeListMV()->getTpetraMultiVectorNonConst();
441 Teuchos::RCP< Xpetra::TpetraMultiVector<SC,LO,GO,NO> > nodeListXpetraTpetra = Teuchos::rcp(
new Xpetra::TpetraMultiVector<SC,LO,GO,NO>(nodeListTpetra));
442 Teuchos::RCP< Xpetra::MultiVector<SC,LO,GO,NO> > nodeListXpetra = Teuchos::rcp_dynamic_cast<Xpetra::MultiVector<SC,LO,GO,NO>>(nodeListXpetraTpetra);
444 nodeListVec[i] = nodeListXpetra;
446 else if (!timeProblem_.is_null()){
447 TEUCHOS_TEST_FOR_EXCEPTION( timeProblem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Node lists cannot be used for P0 elements." );
448 Teuchos::RCP< Tpetra::MultiVector<SC,LO,GO,NO> > nodeListTpetra = timeProblem_->getDomain(i)->getNodeListMV()->getTpetraMultiVectorNonConst();
449 Teuchos::RCP< Xpetra::TpetraMultiVector<SC,LO,GO,NO> > nodeListXpetraTpetra = Teuchos::rcp(
new Xpetra::TpetraMultiVector<SC,LO,GO,NO>(nodeListTpetra));
450 Teuchos::RCP< Xpetra::MultiVector<SC,LO,GO,NO> > nodeListXpetra = Teuchos::rcp_dynamic_cast<Xpetra::MultiVector<SC,LO,GO,NO>>(nodeListXpetraTpetra);
452 nodeListVec[i] = nodeListXpetra;
458 if (!pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").get(
"DofOrdering" + std::to_string(i+1),
"NodeWise" ).compare(
"DimensionWise"))
459 dofOrderings[i] = FROSch::DimensionWise;
460 else if (!pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").get(
"DofOrdering" + std::to_string(i+1),
"NodeWise" ).compare(
"NodeWise"))
461 dofOrderings[i] = FROSch::NodeWise;
463 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Please chose a valid DOF ordering for ThyraPreconditioner(FROSch).");
466 if (!problem_.is_null())
467 dim = problem_->getDomain(0)->getDimension();
468 else if(!timeProblem_.is_null())
469 dim = timeProblem_->getDomain(0)->getDimension();
471 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Dimension", dim);
472 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Repeated Map Vector",repeatedMaps);
473 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Coordinates List Vector",nodeListVec);
474 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"DofOrdering Vector",dofOrderings);
475 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"DofsPerNode Vector",dofsPerNodeVector);
476 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Mpi Ranks Coarse",parameterList->sublist(
"General").get(
"Mpi Ranks Coarse",0) );
480 if(!pressureProjection_.is_null() && ( dofsPerNodeVector.size() > 1 || dofsPerNodeVector[0] == 1) ){
481 pressureProjection_->merge();
483 Teuchos::RCP< Tpetra::MultiVector<SC,LO,GO,NO> > vectorTpetra = pressureProjection_->getMergedVectorNonConst()->getTpetraMultiVectorNonConst();
484 Teuchos::RCP< Xpetra::TpetraMultiVector<SC,LO,GO,NO> > vectorXpetraTpetra = Teuchos::rcp(
new Xpetra::TpetraMultiVector<SC,LO,GO,NO>(vectorTpetra));
485 Teuchos::RCP< Xpetra::MultiVector<SC,LO,GO,NO> > vectorXpetra = Teuchos::rcp_dynamic_cast<Xpetra::MultiVector<SC,LO,GO,NO>>(vectorXpetraTpetra);
487 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").sublist(
"AlgebraicOverlappingOperator").set(
"Projection",vectorXpetra);
489 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").sublist(
"AlgebraicOverlappingOperator").set(
"Use Pressure Correction",
true);
490 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").sublist(
"AlgebraicOverlappingOperator").set(
"Use Local Pressure Correction",
true);
497 int lowerBound = 100000000;
499 for (UN i = 0; i < numberOfBlocks; i++) {
500 tuple_intint_Type rankRange;
501 if (!problem_.is_null())
502 rankRange = problem_->getDomain(i)->getMesh()->getRankRange();
503 else if(!timeProblem_.is_null())
504 rankRange = timeProblem_->getDomain(i)->getMesh()->getRankRange();
506 if (std::get<0>(rankRange) < lowerBound)
507 lowerBound = std::get<0>(rankRange);
508 if (std::get<1>(rankRange) > upperBound)
509 upperBound = std::get<1>(rankRange);
512 int lowerBoundCoarse = lowerBound;
513 int upperBoundCoarse = upperBound;
515 if ( parameterList->sublist(
"General").get(
"Mpi Ranks Coarse",0) > 0 ){
516 lowerBoundCoarse = upperBound + 1;
517 upperBoundCoarse = comm->getSize() - 1;
520 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
521 std::cout <<
"\t --- Range for local problems of preconditioner from " << lowerBound <<
" to " << upperBound << std::endl;
522 std::cout <<
"\t --- Range for coarse problem of preconditioner from " << lowerBoundCoarse <<
" to " << upperBoundCoarse << std::endl;
523 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
526 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Local problem ranks lower bound", lowerBound );
527 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Local problem ranks upper bound", upperBound );
529 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Coarse problem ranks lower bound", lowerBoundCoarse );
530 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Coarse problem ranks upper bound", upperBoundCoarse );
537 ParameterListPtr_Type pListThyraSolver = sublist( parameterList,
"ThyraSolver" );
538 pListThyraSolver->setParameters( *pListThyraPrec );
540 LinSolverBuilderPtr_Type solverBuilder;
541 if (!problem_.is_null())
542 solverBuilder = problem_->getLinearSolverBuilder();
543 else if(!timeProblem_.is_null())
544 solverBuilder = timeProblem_->getLinearSolverBuilder();
547 pListPhiExport_ = pListThyraSolver;
549 solverBuilder->setParameterList(pListThyraSolver);
550 precFactory_ = solverBuilder->createPreconditioningStrategy(
"");
552 if ( thyraPrec_.is_null() ){
553 thyraPrec_ = precFactory_->createPrec();
556 Thyra::initializePrec<SC>(*precFactory_, thyraMatrix, thyraPrec_.ptr());
557 precondtionerIsBuilt_ =
true;
561 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unknown preconditioner type; You can only compute a FROSch preconditioner here." );
564 TEUCHOS_TEST_FOR_EXCEPTION( precFactory_.is_null(), std::runtime_error,
"precFactory_ is null.");
565 Thyra::initializePrec<SC>(*precFactory_, thyraMatrix, thyraPrec_.ptr());
568 if (parameterList->sublist(
"Exporter" ).get(
"Export coarse functions",
false))
572template <
class SC,
class LO,
class GO,
class NO>
573void Preconditioner<SC,LO,GO,NO>::buildPreconditionerMonolithicFSI( )
576 CommConstPtr_Type comm;
577 if (!problem_.is_null())
578 comm = problem_->getComm();
579 else if(!timeProblem_.is_null())
580 comm = timeProblem_->getComm();
582 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Preconditioner can not be used without a problem.");
584 bool verbose ( comm->getRank() == 0 );
586 ParameterListPtr_Type parameterList;
588 if (!problem_.is_null())
589 parameterList = problem_->getParameterList();
590 else if(!timeProblem_.is_null())
591 parameterList = timeProblem_->getParameterList();
593 std::string precType = parameterList->sublist(
"ThyraPreconditioner").get(
"Preconditioner Type",
"FROSch");
595 bool useRepeatedMaps = parameterList->get(
"Use repeated maps",
true );
596 bool useNodeLists = parameterList->get(
"Use node lists",
true );
597 ParameterListPtr_Type pListThyraPrec = sublist( parameterList,
"ThyraPreconditioner" );
598 ParameterListPtr_Type plFrosch = sublist( sublist( pListThyraPrec,
"Preconditioner Types" ),
"FROSch");
602 ThyraLinOpConstPtr_Type thyraMatrix;
603 if (!problem_.is_null())
604 thyraMatrix = problem_->getSystem()->getThyraLinOp();
605 else if(!timeProblem_.is_null())
606 thyraMatrix = timeProblem_->getSystemCombined()->getThyraLinOp();
608 UN numberOfBlocks = parameterList->get(
"Number of blocks",1);
609 TEUCHOS_TEST_FOR_EXCEPTION( numberOfBlocks<4 || numberOfBlocks>5, std::logic_error,
"Unknown FSI size." );
612 typedef Tpetra::MultiVector<SC,LO,GO,NO> TMultiVector;
613 typedef Teuchos::RCP<TMultiVector> TMultiVectorPtr;
614 typedef Teuchos::ArrayRCP<TMultiVectorPtr> TMultiVectorPtrVecPtr;
618 typedef Xpetra::MultiVector<SC,LO,GO,NO> XMultiVector;
619 typedef Teuchos::RCP<XMultiVector> XMultiVectorPtr;
620 typedef Teuchos::ArrayRCP<XMultiVectorPtr> XMultiVectorPtrVecPtr;
622 typedef Xpetra::Map<LO,GO,NO> XpetraMap_Type;
623 typedef Teuchos::RCP<XpetraMap_Type> XpetraMapPtr_Type;
624 typedef Teuchos::RCP<const XpetraMap_Type> XpetraMapConstPtr_Type;
625 typedef const XpetraMapConstPtr_Type XpetraMapConstPtrConst_Type;
628 Teuchos::ArrayRCP<Teuchos::RCP<Xpetra::Map<LO,GO,NO> > > repeatedMaps(numberOfBlocks);
631 TMultiVectorPtrVecPtr nodeListVec( numberOfBlocks );
632 nodeListVec = Teuchos::null;
635 if (!precondtionerIsBuilt_) {
636 if ( !precType.compare(
"FROSch") ){
637 Teuchos::ArrayRCP<FROSch::DofOrdering> dofOrderings(numberOfBlocks);
638 Teuchos::ArrayRCP<UN> dofsPerNodeVector(numberOfBlocks);
639 for (UN i = 0; i < numberOfBlocks; i++) {
640 dofsPerNodeVector[i] = (UN) pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").get(
"DofsPerNode" + std::to_string(i+1), 1);
642 TEUCHOS_TEST_FOR_EXCEPTION( timeProblem_.is_null(), std::logic_error,
"FSI time problem is null!" );
643 TEUCHOS_TEST_FOR_EXCEPTION( timeProblem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"We should not be able to use P0 for interface coupling." );
646 MapConstPtr_Type mapConstTmp =timeProblem_->getDomain(i)->getInterfaceMapUnique();
647 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
648 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
650 repeatedMaps[i] = mapX;
653 if (useRepeatedMaps) {
654 if (dofsPerNodeVector[i] > 1){
656 if (!problem_.is_null()) {
657 if (problem_->getDomain(i)->getFEType() ==
"P0") {
658 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Vector field map not implemented for P0 elements.");
664 MapConstPtr_Type mapConstTmp = problem_->getDomain(i)->getMapVecFieldRepeated();
665 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
666 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
668 repeatedMaps[i] = mapX;
671 else if(!timeProblem_.is_null()){
672 if (timeProblem_->getDomain(i)->getFEType() ==
"P0") {
673 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Vector field map not implemented for P0 elements.");
678 MapConstPtr_Type mapConstTmp = timeProblem_->getDomain(i)->getMapVecFieldRepeated();
679 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
680 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
682 repeatedMaps[i] = mapX;
686 if (!problem_.is_null()){
687 if (problem_->getDomain(i)->getFEType() ==
"P0") {
690 MapConstPtr_Type mapConstTmp = problem_->getDomain(i)->getElementMap();
691 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
692 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
696 repeatedMaps[i] = mapX;
701 MapConstPtr_Type mapConstTmp = problem_->getDomain(i)->getMapRepeated();
702 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
703 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
705 Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
706 mapX->describe(*out,Teuchos::VERB_EXTREME);
707 repeatedMaps[i] = mapX;
710 else if (!timeProblem_.is_null()){
711 if (timeProblem_->getDomain(i)->getFEType() ==
"P0") {
714 MapConstPtr_Type mapConstTmp = timeProblem_->getDomain(i)->getElementMap();
715 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
716 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
718 repeatedMaps[i] = mapX;
723 MapConstPtr_Type mapConstTmp = timeProblem_->getDomain(i)->getMapRepeated();
724 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
725 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
727 repeatedMaps[i] = mapX;
733 if (!pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").get(
"DofOrdering" + std::to_string(i+1),
"NodeWise" ).compare(
"DimensionWise"))
734 dofOrderings[i] = FROSch::DimensionWise;
735 else if (!pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").get(
"DofOrdering" + std::to_string(i+1),
"NodeWise" ).compare(
"NodeWise"))
736 dofOrderings[i] = FROSch::NodeWise;
738 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Please chose a valid DOF ordering for ThyraPreconditioner(FROSch).");
743 if (!problem_.is_null())
744 dim = problem_->getDomain(0)->getDimension();
745 else if(!timeProblem_.is_null())
746 dim = timeProblem_->getDomain(0)->getDimension();
748 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Dimension", dim);
749 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Repeated Map Vector",repeatedMaps);
750 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Coordinates List Vector",nodeListVec);
751 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"DofOrdering Vector",dofOrderings);
752 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"DofsPerNode Vector",dofsPerNodeVector);
753 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Mpi Ranks Coarse",parameterList->sublist(
"General").get(
"Mpi Ranks Coarse",0) );
759 int lowerBound = 100000000;
761 for (UN i = 0; i < numberOfBlocks; i++) {
762 tuple_intint_Type rankRange;
763 if (!problem_.is_null())
764 rankRange = problem_->getDomain(i)->getMesh()->getRankRange();
765 else if(!timeProblem_.is_null())
766 rankRange = timeProblem_->getDomain(i)->getMesh()->getRankRange();
768 if (std::get<0>(rankRange) < lowerBound)
769 lowerBound = std::get<0>(rankRange);
770 if (std::get<1>(rankRange) > upperBound)
771 upperBound = std::get<1>(rankRange);
774 int lowerBoundCoarse = lowerBound;
775 int upperBoundCoarse = upperBound;
777 if ( parameterList->sublist(
"General").get(
"Mpi Ranks Coarse",0) > 0 ){
778 lowerBoundCoarse = upperBound + 1;
779 upperBoundCoarse = comm->getSize() - 1;
782 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
783 std::cout <<
"\t --- Range for local problems of preconditioner from " << lowerBound <<
" to " << upperBound << std::endl;
784 std::cout <<
"\t --- Range for coarse problem of preconditioner from " << lowerBoundCoarse <<
" to " << upperBoundCoarse << std::endl;
785 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
788 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Local problem ranks lower bound", lowerBound );
789 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Local problem ranks upper bound", upperBound );
791 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Coarse problem ranks lower bound", lowerBoundCoarse );
792 pListThyraPrec->sublist(
"Preconditioner Types").sublist(
"FROSch").set(
"Coarse problem ranks upper bound", upperBoundCoarse );
799 ParameterListPtr_Type pListThyraSolver = sublist( parameterList,
"ThyraSolver" );
800 pListThyraSolver->setParameters( *pListThyraPrec );
802 LinSolverBuilderPtr_Type solverBuilder;
803 if (!problem_.is_null())
804 solverBuilder = problem_->getLinearSolverBuilder();
805 else if(!timeProblem_.is_null())
806 solverBuilder = timeProblem_->getUnderlyingProblem()->getLinearSolverBuilder();
809 pListPhiExport_ = pListThyraSolver;
811 solverBuilder->setParameterList(pListThyraSolver);
812 precFactory_ = solverBuilder->createPreconditioningStrategy(
"");
814 if ( thyraPrec_.is_null() )
815 thyraPrec_ = precFactory_->createPrec();
818 Thyra::initializePrec<SC>(*precFactory_, thyraMatrix, thyraPrec_.ptr());
819 precondtionerIsBuilt_ =
true;
823 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unknown preconditioner type; You can only compute a FROSch preconditioner here." );
826 TEUCHOS_TEST_FOR_EXCEPTION( precFactory_.is_null(), std::runtime_error,
"precFactory_ is null.");
827 Thyra::initializePrec<SC>(*precFactory_, thyraMatrix, thyraPrec_.ptr());
830 if (parameterList->sublist(
"Exporter" ).get(
"Export coarse functions",
false))
831 exportCoarseBasisFSI();
837template <
class SC,
class LO,
class GO,
class NO>
838void Preconditioner<SC,LO,GO,NO>::buildPreconditionerTeko( )
841 Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
843 ParameterListPtr_Type parameterList;
844 if (!problem_.is_null())
845 parameterList = problem_->getParameterList();
846 else if(!timeProblem_.is_null())
847 parameterList = timeProblem_->getParameterList();
849 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Preconditioner can not be used without a problem.");
852 LinSolverBuilderPtr_Type solverBuilder;
853 if (!problem_.is_null())
854 solverBuilder = problem_->getLinearSolverBuilder();
855 else if(!timeProblem_.is_null())
856 solverBuilder = timeProblem_->getUnderlyingProblem()->getLinearSolverBuilder();
858 ParameterListPtr_Type tekoPList= sublist( parameterList,
"Teko Parameters" );
860 if (precFactory_.is_null()) {
861 ParameterListPtr_Type tmpSubList = sublist( sublist( sublist( sublist( parameterList,
"Teko Parameters" ) ,
"Preconditioner Types" ) ,
"Teko" ) ,
"Inverse Factory Library" );
864 if ( !tmpSubList->sublist(
"FROSch-Pressure").get(
"Type",
"FROSch").compare(
"FROSch") &&
865 !tmpSubList->sublist(
"FROSch-Velocity").get(
"Type",
"FROSch").compare(
"FROSch") ) {
866 setVelocityParameters( tekoPList, parameterList->sublist(
"General").get(
"Mpi Ranks Coarse",0) );
867 setPressureParameters( tekoPList, parameterList->sublist(
"General").get(
"Mpi Ranks Coarse",0) );
871 BlockMatrixPtr_Type system;
872 if (!problem_.is_null())
873 system = problem_->getSystem();
874 else if(!timeProblem_.is_null())
875 system = timeProblem_->getSystemCombined();
877 TEUCHOS_TEST_FOR_EXCEPTION( system->size()!=2, std::logic_error,
"Wrong size of system for Teko-Block-Preconditioners.");
879 Teko::LinearOp thyraF = system->getBlock(0,0)->getThyraLinOp();
880 Teko::LinearOp thyraBT = system->getBlock(0,1)->getThyraLinOp();
881 Teko::LinearOp thyraB = system->getBlock(1,0)->getThyraLinOp();
883 if (!system->blockExists(1,1)){
884 MatrixPtr_Type dummy;
885 dummy.reset(
new Matrix_Type( system->getBlock(1,0)->getMap(), 1 ) );
886 dummy->fillComplete();
887 system->addBlock( dummy, 1, 1 );
889 Teko::LinearOp thyraC = system->getBlock(1,1)->getThyraLinOp();
891 tekoLinOp_ = Thyra::block2x2(thyraF,thyraBT,thyraB,thyraC);
893 if (!precondtionerIsBuilt_) {
894 if ( precFactory_.is_null() ){
895 ParameterListPtr_Type pListThyraSolver = sublist( parameterList,
"ThyraSolver" );
897 pListThyraSolver->setParameters( *tekoPList );
899 solverBuilder->setParameterList( pListThyraSolver );
900 precFactory_ = solverBuilder->createPreconditioningStrategy(
"");
902 rh_.reset(
new Teko::RequestHandler());
904 if(!tekoPList->sublist(
"Preconditioner Types").sublist(
"Teko").get(
"Inverse Type",
"SIMPLE").compare(
"LSC") ||
905 !tekoPList->sublist(
"Preconditioner Types").sublist(
"Teko").get(
"Inverse Type",
"SIMPLE").compare(
"LSC-Pressure-Laplace") ||
906 !tekoPList->sublist(
"Preconditioner Types").sublist(
"Teko").get(
"Inverse Type",
"SIMPLE").compare(
"SIMPLE")){
907 Teko::LinearOp thyraMass = velocityMassMatrix_;
908 Teuchos::RCP< Teko::StaticRequestCallback<Teko::LinearOp> > callbackMass = Teuchos::rcp(
new Teko::StaticRequestCallback<Teko::LinearOp> (
"Velocity Mass Matrix", thyraMass ) );
909 rh_->addRequestCallback( callbackMass );
911 Teko::LinearOp thyraLaplace = pressureLaplace_;
913 Teuchos::RCP< Teko::StaticRequestCallback<Teko::LinearOp> > callbackLaplace = Teuchos::rcp(
new Teko::StaticRequestCallback<Teko::LinearOp> (
"Pressure Laplace Operator", thyraLaplace ) );
914 rh_->addRequestCallback( callbackLaplace );
916 else if(!tekoPList->sublist(
"Preconditioner Types").sublist(
"Teko").get(
"Inverse Type",
"SIMPLE").compare(
"PCD")){
919 Teko::LinearOp thyraMass = velocityMassMatrix_;
920 Teuchos::RCP< Teko::StaticRequestCallback<Teko::LinearOp> > callbackMass = Teuchos::rcp(
new Teko::StaticRequestCallback<Teko::LinearOp> (
"Velocity Mass Matrix", thyraMass ) );
921 rh_->addRequestCallback( callbackMass );
924 Teko::LinearOp thyraLaplace = pressureLaplace_;
925 Teuchos::RCP< Teko::StaticRequestCallback<Teko::LinearOp> > callbackLaplace = Teuchos::rcp(
new Teko::StaticRequestCallback<Teko::LinearOp> (
"Pressure Laplace Operator", thyraLaplace ) );
926 rh_->addRequestCallback( callbackLaplace );
929 Teko::LinearOp thyraPressureMass = pressureMass_;
930 Teuchos::RCP< Teko::StaticRequestCallback<Teko::LinearOp> > callbackPressureMass = Teuchos::rcp(
new Teko::StaticRequestCallback<Teko::LinearOp> (
"Pressure Mass Matrix", thyraPressureMass ) );
931 rh_->addRequestCallback( callbackPressureMass );
934 if (!timeProblem_.is_null()){
935 timeProblem_->assemble(
"UpdateConvectionDiffusionOperator");
938 problem_->assemble(
"UpdateConvectionDiffusionOperator");
940 Teko::LinearOp thyraPCD = pcdOperator_;
941 callbackPCD_ = Teuchos::rcp(
new Teko::StaticRequestCallback<Teko::LinearOp> (
"PCD Operator", thyraPCD ) );
942 rh_->addRequestCallback( callbackPCD_ );
945 Teuchos::RCP< Teko::StratimikosFactory > tekoFactory = Teuchos::rcp_dynamic_cast<Teko::StratimikosFactory>(precFactory_);
946 tekoFactory->setRequestHandler( rh_ );
950 if ( thyraPrec_.is_null() ){
951 thyraPrec_ = precFactory_->createPrec();
954 Teuchos::RCP< const Thyra::DefaultLinearOpSource< SC > > thyraMatrixSourceOp = defaultLinearOpSource (tekoLinOp_);
957 precFactory_->initializePrec(thyraMatrixSourceOp, thyraPrec_.get());
958 precondtionerIsBuilt_ =
true;
962 if(!tekoPList->sublist(
"Preconditioner Types").sublist(
"Teko").get(
"Inverse Type",
"SIMPLE").compare(
"PCD")){
966 if (!timeProblem_.is_null()){
967 timeProblem_->assemble(
"UpdateConvectionDiffusionOperator");
970 problem_->assemble(
"UpdateConvectionDiffusionOperator");
972 Teuchos::RCP<Teko::RequestHandler> rh = Teuchos::rcp(
new Teko::RequestHandler());
975 Teko::LinearOp thyraPCD;
980 if(!timeProblem_.is_null())
983 pcdOperator_ = timeProblem_->getUnderlyingProblem()->preconditioner_->getPCDOperatorMatrix()->getThyraLinOp();
984 thyraPCD = timeProblem_->getUnderlyingProblem()->preconditioner_->getPCDOperatorMatrix()->getThyraLinOp();
987 thyraPCD= pcdOperator_;
990 Teuchos::RCP< Teko::StaticRequestCallback<Teko::LinearOp> > callbackTmp = Teuchos::rcp(
new Teko::StaticRequestCallback<Teko::LinearOp> (
"PCD Operator", thyraPCD ) );
991 *callbackPCD_ = *callbackTmp;
995 Teuchos::RCP< const Thyra::DefaultLinearOpSource< SC > > thyraMatrixSourceOp = defaultLinearOpSource (tekoLinOp_);
998 precFactory_->initializePrec(thyraMatrixSourceOp, thyraPrec_.get());
1003template <
class SC,
class LO,
class GO,
class NO>
1004void Preconditioner<SC,LO,GO,NO>::buildPreconditionerFaCSI( std::string type )
1006 typedef Domain<SC,LO,GO,NO> Domain_Type;
1007 typedef Teuchos::RCP<const Domain_Type> DomainConstPtr_Type;
1008 typedef std::vector<DomainConstPtr_Type> DomainConstPtr_vec_Type;
1010 Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
1012 ParameterListPtr_Type parameterList;
1013 if (!timeProblem_.is_null())
1014 parameterList = timeProblem_->getParameterList();
1016 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Preconditioner can not be used without a time problem.");
1019 ProblemPtr_Type steadyProblem = timeProblem_->getUnderlyingProblem();
1020 Teuchos::RCP< FSI<SC,LO,GO,NO> > steadyFSI = Teuchos::rcp_dynamic_cast<FSI<SC,LO,GO,NO> >(steadyProblem);
1021 BlockMatrixPtr_Type fsiSystem = timeProblem_->getSystemCombined();
1023 ParameterListPtr_Type pLFluid = steadyFSI->getFluidProblem()->getParameterList();
1026 std::string precTypeFluid;
1027 if (type ==
"FaCSI")
1028 precTypeFluid =
"Monolithic";
1029 else if (type ==
"FaCSI-Teko"){
1030 precTypeFluid =
"Teko";
1032 else if (type ==
"FaCSI-Block"){
1033 precTypeFluid = parameterList->sublist(
"Parameter Fluid").get(
"Preconditioner Type",
"PCD");
1036 CommConstPtr_Type comm = timeProblem_->getComm();
1037 bool useFluidPreconditioner = parameterList->sublist(
"General").get(
"Use Fluid Preconditioner",
true);
1038 bool useSolidPreconditioner = parameterList->sublist(
"General").get(
"Use Solid Preconditioner",
true);
1039 bool onlyDiagonal = parameterList->sublist(
"General").get(
"Only Diagonal",
false);
1040 Teuchos::RCP< PrecOpFaCSI<SC,LO,GO,NO> > facsi
1041 = Teuchos::rcp(
new PrecOpFaCSI<SC,LO,GO,NO> ( comm, precTypeFluid ==
"Monolithic", useFluidPreconditioner, useSolidPreconditioner, onlyDiagonal) );
1043 if (comm->getRank() == 0) {
1045 std::cout <<
"\t### No preconditioner will be used! ###" << std::endl;
1047 std::cout <<
"\t### FaCSI standard ###" << std::endl;
1050 BlockMatrixPtr_Type fluidSystem = Teuchos::rcp(
new BlockMatrix_Type(2) );
1069 Teuchos::RCP< TimeProblem<SC,LO,GO,NO> > fluidProblem = steadyFSI->problemTimeFluid_;
1070 fluidProblem->combineSystems();
1071 fluidProblem->setBoundariesSystem();
1073 Teuchos::RCP< NavierStokes<SC,LO,GO,NO> > fluidProblemSteady = Teuchos::rcp_dynamic_cast<NavierStokes<SC,LO,GO,NO> >(fluidProblem->getUnderlyingProblem());
1075 faCSIBCFactory_->setSystem( fluidProblem->getSystemCombined() );
1077 fluidProblemSteady->setupPreconditioner( precTypeFluid );
1078 precFluid_ = fluidProblemSteady->getPreconditioner()->getThyraPrec()->getNonconstUnspecifiedPrecOp();
1081 bool nonlinearStructure =
false;
1082 if (steadyFSI->getStructureProblem().is_null())
1083 nonlinearStructure =
true;
1085 ParameterListPtr_Type pLStructure;
1086 if (nonlinearStructure)
1087 pLStructure = steadyFSI->getNonLinStructureProblem()->getParameterList();
1089 pLStructure = steadyFSI->getStructureProblem()->getParameterList();
1091 if (probSolid_.is_null()){
1092 probSolid_ = Teuchos::rcp(
new MinPrecProblem_Type( pLStructure, timeProblem_->getComm() ) );
1093 DomainConstPtr_vec_Type structDomain;
1094 if (nonlinearStructure)
1095 structDomain = steadyFSI->getNonLinStructureProblem()->getDomainVector();
1097 structDomain = steadyFSI->getStructureProblem()->getDomainVector();
1099 probSolid_->initializeDomains( structDomain );
1100 probSolid_->initializeLinSolverBuilder( timeProblem_->getLinearSolverBuilder() );
1103 BlockMatrixPtr_Type structSystem = Teuchos::rcp(
new BlockMatrix_Type(1) );
1105 structSystem->addBlock( fsiSystem->getBlock(2,2), 0, 0 );
1107 probSolid_->initializeSystem( structSystem );
1109 probSolid_->setupPreconditioner( );
1111 precStruct_ = probSolid_->getPreconditioner()->getThyraPrec()->getNonconstUnspecifiedPrecOp();
1116 if (timeProblem_->getSystem()->size()>4) {
1117 ParameterListPtr_Type pLGeometry = steadyFSI->getGeometryProblem()->getParameterList();
1118 if (probGeo_.is_null()) {
1119 probGeo_ = Teuchos::rcp(
new MinPrecProblem_Type( pLGeometry, timeProblem_->getComm() ) );
1120 DomainConstPtr_vec_Type geoDomain = steadyFSI->getGeometryProblem()->getDomainVector();
1121 probGeo_->initializeDomains( geoDomain );
1122 probGeo_->initializeLinSolverBuilder( timeProblem_->getLinearSolverBuilder() );
1125 BlockMatrixPtr_Type geoSystem = Teuchos::rcp(
new BlockMatrix_Type(1) );
1127 geoSystem->addBlock( fsiSystem->getBlock(4,4), 0, 0 );
1129 probGeo_->initializeSystem( geoSystem );
1131 probGeo_->setupPreconditioner( );
1133 precGeo_ = probGeo_->getPreconditioner()->getThyraPrec()->getNonconstUnspecifiedPrecOp();
1136 if (fsiSystem->size()>4) {
1138 facsi->setGIShape( fsiSystem->getBlock(3,0)->getThyraLinOpNonConst(),
1139 fsiSystem->getBlock(0,3)->getThyraLinOpNonConst(),
1140 fsiSystem->getBlock(3,2)->getThyraLinOpNonConst(),
1141 fsiSystem->getBlock(4,2)->getThyraLinOpNonConst(),
1144 fsiSystem->getBlock(0,0)->getThyraLinOpNonConst(),
1145 fsiSystem->getBlock(0,1)->getThyraLinOpNonConst(),
1147 fsiSystem->getBlock(0,4)->getThyraLinOpNonConst(),
1148 fsiSystem->getBlock(1,4)->getThyraLinOpNonConst() );
1151 facsi->setGI( fsiSystem->getBlock(3,0)->getThyraLinOpNonConst(),
1152 fsiSystem->getBlock(0,3)->getThyraLinOpNonConst(),
1153 fsiSystem->getBlock(3,2)->getThyraLinOpNonConst(),
1154 fsiSystem->getBlock(4,2)->getThyraLinOpNonConst(),
1157 fsiSystem->getBlock(0,0)->getThyraLinOpNonConst(),
1158 fsiSystem->getBlock(0,1)->getThyraLinOpNonConst(),
1163 facsi->setGE( fsiSystem->getBlock(3,0)->getThyraLinOpNonConst(),
1164 fsiSystem->getBlock(0,3)->getThyraLinOpNonConst(),
1165 fsiSystem->getBlock(3,2)->getThyraLinOpNonConst(),
1168 fsiSystem->getBlock(0,0)->getThyraLinOpNonConst(),
1169 fsiSystem->getBlock(0,1)->getThyraLinOpNonConst() );
1172 LinSolverBuilderPtr_Type solverBuilder = timeProblem_->getUnderlyingProblem()->getLinearSolverBuilder();
1174 if ( precFactory_.is_null() )
1175 precFactory_ = solverBuilder->createPreconditioningStrategy(
"");
1177 if ( thyraPrec_.is_null() )
1178 thyraPrec_ = precFactory_->createPrec();
1180 Teuchos::RCP< Thyra::DefaultPreconditioner<SC> > defaultPrec =
1181 Teuchos::rcp_dynamic_cast< Thyra::DefaultPreconditioner<SC> > (thyraPrec_);
1182 ThyraLinOpPtr_Type linOp =
1183 Teuchos::rcp_dynamic_cast< Thyra::LinearOpBase<SC> > (facsi);
1185 defaultPrec->initializeUnspecified( linOp );
1187 precondtionerIsBuilt_ =
true;
1191template <
class SC,
class LO,
class GO,
class NO>
1192void Preconditioner<SC,LO,GO,NO>::setPressureMassMatrix(MatrixPtr_Type massMatrix)
const{
1193 pressureMassMatrixPtr_ = massMatrix;
1194 pressureMass_= massMatrix->getThyraLinOp();
1197template <
class SC,
class LO,
class GO,
class NO>
1198void Preconditioner<SC,LO,GO,NO>::setPressureLaplaceMatrix(MatrixPtr_Type matrix)
const{
1199 pressureLaplace_ =matrix->getThyraLinOp();
1200 pressureLaplaceMatrixPtr_ = matrix;
1209template <
class SC,
class LO,
class GO,
class NO>
1210void Preconditioner<SC,LO,GO,NO>::setPCDOperator(MatrixPtr_Type matrix)
const{
1211 pcdOperator_ = matrix->getThyraLinOp();
1212 pcdOperatorMatrixPtr_ = matrix;
1223template <
class SC,
class LO,
class GO,
class NO>
1224void Preconditioner<SC,LO,GO,NO>::buildPreconditionerBlock2x2( )
1226 PRECONDITIONER_START(buildPreconditionerBlock2x2,
" buildPreconditionerBlock2x2");
1228 typedef Domain<SC,LO,GO,NO> Domain_Type;
1229 typedef Teuchos::RCP<const Domain_Type> DomainConstPtr_Type;
1230 typedef std::vector<DomainConstPtr_Type> DomainConstPtr_vec_Type;
1232 Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
1234 ParameterListPtr_Type parameterList;
1235 BlockMatrixPtr_Type system;
1236 CommConstPtr_Type comm;
1237 ProblemPtr_Type steadyProblem;
1238 if (!timeProblem_.is_null()){
1239 std::cout <<
"buildPreconditionerBlock2x2 timeProblem_ " << std::endl;
1240 parameterList = timeProblem_->getParameterList();
1241 system = timeProblem_->getSystemCombined();
1242 comm = timeProblem_->getComm();
1243 steadyProblem = timeProblem_->getUnderlyingProblem();
1246 parameterList = problem_->getParameterList();
1247 system = problem_->getSystem();
1248 comm = problem_->getComm();
1249 steadyProblem = problem_;
1252 bool verbose( comm->getRank() == 0 );
1255 std::cout <<
" ######################## " << std::endl;
1256 std::cout <<
" Build 2x2 Preconditioner " << std::endl;
1257 std::cout <<
" ######################## " << std::endl;
1259 ParameterListPtr_Type plVelocity(
new Teuchos::ParameterList( parameterList->sublist(
"Velocity preconditioner") ) );
1260 ParameterListPtr_Type plSchur(
new Teuchos::ParameterList( parameterList->sublist(
"Schur complement preconditioner") ) );
1263 plVelocity->sublist(
"General").setParameters(parameterList->sublist(
"General"));
1264 plSchur->sublist(
"General").setParameters(parameterList->sublist(
"General"));
1266 Teuchos::RCP< PrecBlock2x2<SC,LO,GO,NO> > blockPrec2x2
1267 = Teuchos::rcp(
new PrecBlock2x2<SC,LO,GO,NO> ( comm ) );
1270 if (probVelocity_.is_null()){
1271 probVelocity_ = Teuchos::rcp(
new MinPrecProblem_Type( plVelocity, comm ) );
1272 DomainConstPtr_vec_Type domain1(0);
1273 domain1.push_back( steadyProblem->getDomain(0) );
1274 probVelocity_->initializeDomains( domain1 );
1275 probVelocity_->initializeLinSolverBuilder( steadyProblem->getLinearSolverBuilder() );
1278 BlockMatrixPtr_Type system1 = Teuchos::rcp(
new BlockMatrix_Type(1) );
1280 MatrixPtr_Type F = system->getBlock(0,0);
1282 system1->addBlock( F, 0, 0 );
1284 probVelocity_->initializeSystem( system1 );
1286 PRECONDITIONER_START(setupFInv,
" Setup Preconditioner for F");
1287 probVelocity_->setupPreconditioner(
"Monolithic" );
1288 PRECONDITIONER_STOP(setupFInv);
1290 precVelocity_ = probVelocity_->getPreconditioner()->getThyraPrec()->getNonconstUnspecifiedPrecOp();
1292 if (probSchur_.is_null()) {
1293 if(!timeProblem_.is_null()){
1294 probSchur_ = Teuchos::rcp(
new MinPrecProblem_Type( plSchur, comm ) );
1295 DomainConstPtr_vec_Type domain2(0);
1296 domain2.push_back( timeProblem_->getDomain(1) );
1297 probSchur_->initializeDomains( domain2 );
1298 probSchur_->initializeLinSolverBuilder( timeProblem_->getLinearSolverBuilder() );
1302 probSchur_ = Teuchos::rcp(
new MinPrecProblem_Type( plSchur, comm ) );
1303 DomainConstPtr_vec_Type domain2(0);
1304 domain2.push_back( problem_->getDomain(1) );
1305 probSchur_->initializeDomains( domain2 );
1306 probSchur_->initializeLinSolverBuilder( problem_->getLinearSolverBuilder() );
1311 std::string type = parameterList->sublist(
"General").get(
"Preconditioner Method",
"Diagonal");
1315 PRECONDITIONER_START(setupSInv,
" Setup Preconditioner for S");
1317 if(type ==
"Diagonal" || type ==
"Triangular"){
1318 BlockMatrixPtr_Type Mp = Teuchos::rcp(
new BlockMatrix_Type(1) );
1320 Mp->addBlock( pressureMassMatrixPtr_, 0, 0 );
1322 probSchur_->initializeSystem( Mp );
1324 probSchur_->setupPreconditioner(
"Monolithic" );
1326 precSchur_ = probSchur_->getPreconditioner()->getThyraPrec()->getNonconstUnspecifiedPrecOp();
1328 else if (type ==
"PCD") {
1333 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
1334 std::cout <<
"\t --- Building PCD Operator Components " << std::endl;
1335 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
1338 if (probLaplace_.is_null()) {
1339 if (!timeProblem_.is_null()){
1340 probLaplace_ = Teuchos::rcp(
new MinPrecProblem_Type( plSchur, comm ) );
1341 DomainConstPtr_vec_Type domain2(0);
1342 domain2.push_back( timeProblem_->getDomain(1) );
1343 probLaplace_->initializeDomains( domain2 );
1344 probLaplace_->initializeLinSolverBuilder( timeProblem_->getLinearSolverBuilder() );
1347 probLaplace_ = Teuchos::rcp(
new MinPrecProblem_Type( plSchur, comm ) );
1348 DomainConstPtr_vec_Type domain2(0);
1349 domain2.push_back( problem_->getDomain(1) );
1350 probLaplace_->initializeDomains( domain2 );
1351 probLaplace_->initializeLinSolverBuilder( problem_->getLinearSolverBuilder() );
1355 if(laplaceInverse_.is_null()){
1357 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
1358 std::cout <<
"\t --- PCD: Setup A_p Schwarz Approximation " << std::endl;
1359 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
1361 BlockMatrixPtr_Type Ap = Teuchos::rcp(
new BlockMatrix_Type(1) );
1362 Ap->addBlock(pressureLaplaceMatrixPtr_,0,0);
1364 probLaplace_->initializeSystem( Ap );
1366 probLaplace_->setupPreconditioner(
"Monolithic" );
1367 laplaceInverse_ = probLaplace_->getPreconditioner()->getThyraPrec()->getNonconstUnspecifiedPrecOp();
1370 if (probMass_.is_null()) {
1371 if (!timeProblem_.is_null()){
1372 probMass_ = Teuchos::rcp(
new MinPrecProblem_Type( plSchur, comm ) );
1373 DomainConstPtr_vec_Type domain2(0);
1374 domain2.push_back( timeProblem_->getDomain(1) );
1375 probMass_->initializeDomains( domain2 );
1376 probMass_->initializeLinSolverBuilder( timeProblem_->getLinearSolverBuilder() );
1379 probMass_ = Teuchos::rcp(
new MinPrecProblem_Type( plSchur, comm ) );
1380 DomainConstPtr_vec_Type domain2(0);
1381 domain2.push_back( problem_->getDomain(1) );
1382 probMass_->initializeDomains( domain2 );
1383 probMass_->initializeLinSolverBuilder( problem_->getLinearSolverBuilder() );
1387 if(massMatrixInverse_.is_null()){
1389 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
1390 std::cout <<
"\t --- PCD: Setup M_p Schwarz Approximation " << std::endl;
1391 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
1393 BlockMatrixPtr_Type Qp = Teuchos::rcp(
new BlockMatrix_Type(1) );
1394 Qp->addBlock(pressureMassMatrixPtr_,0,0);
1398 bool explicitInverse = parameterList->sublist(
"General").get(
"Mu Explicit Inverse",
true);
1399 std::string typeDiag = parameterList->sublist(
"General").get(
"Diagonal Approximation",
"Diagonal");
1403 probMass_->initializeSystem( Qp );
1404 probMass_->setupPreconditioner(
"Monolithic" );
1405 massMatrixInverse_ = probMass_->getPreconditioner()->getThyraPrec()->getNonconstUnspecifiedPrecOp();
1409 massMatrixInverse_ = pressureMassMatrixPtr_->buildDiagonalInverse(typeDiag)->getThyraLinOpNonConst() ;
1414 else if (type ==
"LSC") {
1417 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
1418 std::cout <<
"\t --- Building LSC Operator Components " << std::endl;
1419 std::cout <<
"\t --- -------------------------------------------------------- ---"<< std::endl;
1422 if (probLaplace_.is_null()) {
1423 if (!timeProblem_.is_null()){
1424 probLaplace_ = Teuchos::rcp(
new MinPrecProblem_Type( plSchur, comm ) );
1425 DomainConstPtr_vec_Type domain2(0);
1426 domain2.push_back( timeProblem_->getDomain(1) );
1427 probLaplace_->initializeDomains( domain2 );
1428 probLaplace_->initializeLinSolverBuilder( timeProblem_->getLinearSolverBuilder() );
1431 probLaplace_ = Teuchos::rcp(
new MinPrecProblem_Type( plSchur, comm ) );
1432 DomainConstPtr_vec_Type domain2(0);
1433 domain2.push_back( problem_->getDomain(1) );
1434 probLaplace_->initializeDomains( domain2 );
1435 probLaplace_->initializeLinSolverBuilder( problem_->getLinearSolverBuilder() );
1439 BlockMatrixPtr_Type Ap = Teuchos::rcp(
new BlockMatrix_Type(1) );
1440 Ap->addBlock(pressureLaplaceMatrixPtr_,0,0);
1442 probLaplace_->initializeSystem( Ap );
1444 probLaplace_->setupPreconditioner(
"Monolithic" );
1445 laplaceInverse_ = probLaplace_->getPreconditioner()->getThyraPrec()->getNonconstUnspecifiedPrecOp();
1447 if (probVMass_.is_null()) {
1448 if (!timeProblem_.is_null()){
1449 probVMass_ = Teuchos::rcp(
new MinPrecProblem_Type( plVelocity, comm ) );
1450 DomainConstPtr_vec_Type domain1(0);
1451 domain1.push_back( timeProblem_->getDomain(0) );
1452 probVMass_->initializeDomains( domain1 );
1453 probVMass_->initializeLinSolverBuilder( timeProblem_->getLinearSolverBuilder() );
1456 probVMass_ = Teuchos::rcp(
new MinPrecProblem_Type( plVelocity, comm ) );
1457 DomainConstPtr_vec_Type domain1(0);
1458 domain1.push_back( problem_->getDomain(0) );
1459 probVMass_->initializeDomains( domain1 );
1460 probVMass_->initializeLinSolverBuilder( problem_->getLinearSolverBuilder() );
1463 BlockMatrixPtr_Type Qv = Teuchos::rcp(
new BlockMatrix_Type(1) );
1464 Qv->addBlock(velocityMassMatrixMatrixPtr_,0,0);
1468 bool explicitInverse = parameterList->sublist(
"General").get(
"Mu Explicit Inverse",
true);
1469 std::string typeDiag = parameterList->sublist(
"General").get(
"Diagonal Approximation",
"Diagonal");
1473 probVMass_->initializeSystem( Qv );
1474 probVMass_->setupPreconditioner(
"Monolithic" );
1475 massMatrixVInverse_ = probVMass_->getPreconditioner()->getThyraPrec()->getNonconstUnspecifiedPrecOp();
1479 massMatrixVInverse_ = velocityMassMatrixMatrixPtr_->buildDiagonalInverse(typeDiag)->getThyraLinOpNonConst() ;
1483 PRECONDITIONER_STOP(setupSInv);
1487 if (type ==
"Diagonal") {
1488 blockPrec2x2->setDiagonal(precVelocity_,
1491 else if (type ==
"Triangular") {
1492 ThyraLinOpPtr_Type BT = system->getBlock(0,1)->getThyraLinOpNonConst();
1493 blockPrec2x2->setTriangular(precVelocity_,
1497 else if (type ==
"PCD") {
1498 if (!timeProblem_.is_null()){
1499 timeProblem_->assemble(
"UpdateConvectionDiffusionOperator");
1502 problem_->assemble(
"UpdateConvectionDiffusionOperator");
1504 MatrixPtr_Type pcdOperatorScaled = Teuchos::rcp(
new Matrix_Type( pcdOperatorMatrixPtr_ ) );
1505 pcdOperatorScaled->resumeFill();
1506 pcdOperatorScaled->scale(-1.0);
1507 pcdOperatorScaled->fillComplete();
1508 ThyraLinOpPtr_Type BT = system->getBlock(0,1)->getThyraLinOpNonConst();
1509 blockPrec2x2->setTriangular(precVelocity_,
1511 pcdOperatorScaled->getThyraLinOpNonConst(),
1513 massMatrixVInverse_,
1515 ThyraLinOpPtr_Type B = system->getBlock(1,0)->getThyraLinOpNonConst();
1516 blockPrec2x2->setB(B);
1518 else if (type ==
"LSC") {
1519 ThyraLinOpPtr_Type BT = system->getBlock(0,1)->getThyraLinOpNonConst();
1520 blockPrec2x2->setTriangular(precVelocity_,
1522 massMatrixVInverse_,
1526 ThyraLinOpPtr_Type B = system->getBlock(1,0)->getThyraLinOpNonConst();
1527 blockPrec2x2->setB(B);
1529 ThyraLinOpPtr_Type F = system->getBlock(0,0)->getThyraLinOpNonConst();
1530 blockPrec2x2->setF(F);
1535 LinSolverBuilderPtr_Type solverBuilder;
1536 if (!timeProblem_.is_null())
1537 solverBuilder = timeProblem_->getLinearSolverBuilder();
1539 solverBuilder = problem_->getLinearSolverBuilder();
1541 if ( precFactory_.is_null() )
1542 precFactory_ = solverBuilder->createPreconditioningStrategy(
"");
1544 if ( thyraPrec_.is_null() )
1545 thyraPrec_ = precFactory_->createPrec();
1547 Teuchos::RCP< Thyra::DefaultPreconditioner<SC> > defaultPrec =
1548 Teuchos::rcp_dynamic_cast< Thyra::DefaultPreconditioner<SC> > (thyraPrec_);
1549 ThyraLinOpPtr_Type linOp =
1550 Teuchos::rcp_dynamic_cast< Thyra::LinearOpBase<SC> > (blockPrec2x2);
1552 defaultPrec->initializeUnspecified( linOp );
1554 precondtionerIsBuilt_ =
true;
1556 PRECONDITIONER_STOP(buildPreconditionerBlock2x2);
1563template <
class SC,
class LO,
class GO,
class NO>
1564void Preconditioner<SC,LO,GO,NO>::setVelocityParameters( ParameterListPtr_Type parameterList,
int coarseRanks )
1566 CommConstPtr_Type comm;
1567 if (!problem_.is_null())
1568 comm = problem_->getComm();
1569 else if(!timeProblem_.is_null())
1570 comm = timeProblem_->getComm();
1572 bool verbose( comm->getRank() == 0 );
1575 Teuchos::ArrayRCP<Teuchos::RCP<Xpetra::Map<LO,GO,NO> > > repeatedMaps(1);
1576 typedef Xpetra::Map<LO,GO,NO> XpetraMap_Type;
1577 typedef Teuchos::RCP<XpetraMap_Type> XpetraMapPtr_Type;
1578 typedef Teuchos::RCP<const XpetraMap_Type> XpetraMapConstPtr_Type;
1579 typedef const XpetraMapConstPtr_Type XpetraMapConstPtrConst_Type;
1581 Teuchos::ArrayRCP<FROSch::DofOrdering> dofOrderings(1);
1582 Teuchos::ArrayRCP<UN> dofsPerNodeVector(1);
1583 ParameterListPtr_Type velocitySubList = sublist( sublist( sublist( sublist( parameterList,
"Preconditioner Types" ) ,
"Teko" ) ,
"Inverse Factory Library" ) ,
"FROSch-Velocity" );
1584 dofsPerNodeVector[0] = (UN) velocitySubList->get(
"DofsPerNode", 2);
1585 TEUCHOS_TEST_FOR_EXCEPTION(dofsPerNodeVector[0]<2, std::logic_error,
"DofsPerNode for velocity must be atleast 2.");
1595 MapConstPtr_Type mapConstTmp;
1596 if (!problem_.is_null())
1597 mapConstTmp = problem_->getDomain(0)->getMapVecFieldRepeated();
1598 else if(!timeProblem_.is_null())
1599 mapConstTmp = timeProblem_->getDomain(0)->getMapVecFieldRepeated();
1601 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
1602 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
1604 repeatedMaps[0] = mapX;
1606 if (!velocitySubList->get(
"DofOrdering",
"NodeWise" ).compare(
"DimensionWise"))
1607 dofOrderings[0] = FROSch::DimensionWise;
1608 else if (!velocitySubList->get(
"DofOrdering",
"NodeWise" ).compare(
"NodeWise"))
1609 dofOrderings[0] = FROSch::NodeWise;
1611 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Please chose a valid DOF ordering for ThyraPreconditioner(FROSch).");
1613 velocitySubList->set(
"Repeated Map Vector",repeatedMaps);
1614 velocitySubList->set(
"DofOrdering Vector",dofOrderings);
1615 velocitySubList->set(
"DofsPerNode Vector",dofsPerNodeVector);
1616 velocitySubList->set(
"Mpi Ranks Coarse", coarseRanks );
1618 int lowerBound = 100000000;
1619 int upperBound = -1;
1621 tuple_intint_Type rankRange;
1622 if (!problem_.is_null())
1623 rankRange = problem_->getDomain(0)->getMesh()->getRankRange();
1624 else if(!timeProblem_.is_null())
1625 rankRange = timeProblem_->getDomain(0)->getMesh()->getRankRange();
1627 if (std::get<0>(rankRange) < lowerBound)
1628 lowerBound = std::get<0>(rankRange);
1629 if (std::get<1>(rankRange) > upperBound)
1630 upperBound = std::get<1>(rankRange);
1632 int lowerBoundCoarse = lowerBound;
1633 int upperBoundCoarse = upperBound;
1635 if ( coarseRanks > 0 ){
1636 lowerBoundCoarse = upperBound + 1;
1637 upperBoundCoarse = comm->getSize() - 1;
1640 std::cout <<
"\t --- ------------------------------------------------------------------- ---"<< std::endl;
1641 std::cout <<
"\t --- Range for local problems of preconditioner Teko velocity from " << lowerBound <<
" to " << upperBound << std::endl;
1642 std::cout <<
"\t --- Range for coarse problem of preconditioner Teko velocity from " << lowerBoundCoarse <<
" to " << upperBoundCoarse << std::endl;
1643 std::cout <<
"\t --- ------------------------------------------------------------------- ---"<< std::endl;
1646 velocitySubList->set(
"Local problem ranks lower bound", lowerBound );
1647 velocitySubList->set(
"Local problem ranks upper bound", upperBound );
1649 velocitySubList->set(
"Coarse problem ranks lower bound", lowerBoundCoarse );
1650 velocitySubList->set(
"Coarse problem ranks upper bound", upperBoundCoarse );
1657template <
class SC,
class LO,
class GO,
class NO>
1658void Preconditioner<SC,LO,GO,NO>::setPressureParameters( ParameterListPtr_Type parameterList,
int coarseRanks )
1660 CommConstPtr_Type comm;
1661 if (!problem_.is_null())
1662 comm = problem_->getComm();
1663 else if(!timeProblem_.is_null())
1664 comm = timeProblem_->getComm();
1666 bool verbose( comm->getRank() == 0 );
1668 Teuchos::ArrayRCP<Teuchos::RCP<Xpetra::Map<LO,GO,NO> > > repeatedMaps(1);
1669 typedef Xpetra::Map<LO,GO,NO> XpetraMap_Type;
1670 typedef Teuchos::RCP<XpetraMap_Type> XpetraMapPtr_Type;
1671 typedef Teuchos::RCP<const XpetraMap_Type> XpetraMapConstPtr_Type;
1672 typedef const XpetraMapConstPtr_Type XpetraMapConstPtrConst_Type;
1674 Teuchos::ArrayRCP<FROSch::DofOrdering> dofOrderings(1);
1675 Teuchos::ArrayRCP<UN> dofsPerNodeVector(1);
1676 ParameterListPtr_Type pressureSubList = sublist( sublist( sublist( sublist( parameterList,
"Preconditioner Types" ) ,
"Teko" ) ,
"Inverse Factory Library" ) ,
"FROSch-Pressure" );
1677 dofsPerNodeVector[0] = (UN) pressureSubList->get(
"DofsPerNode", 1);
1678 TEUCHOS_TEST_FOR_EXCEPTION(dofsPerNodeVector[0]!=1, std::logic_error,
"DofsPerNode for pressure must be 1.");
1694 MapConstPtr_Type mapConstTmp;
1695 if (!problem_.is_null()){
1696 if ( problem_->getDomain(1)->getFEType()==
"P0" )
1697 mapConstTmp = problem_->getDomain(1)->getElementMap();
1699 mapConstTmp = problem_->getDomain(1)->getMapRepeated();
1701 else if(!timeProblem_.is_null()){
1702 if ( timeProblem_->getDomain(1)->getFEType()==
"P0" )
1703 mapConstTmp = timeProblem_->getDomain(1)->getElementMap();
1705 mapConstTmp = timeProblem_->getDomain(1)->getMapRepeated();
1710 XpetraMapConstPtr_Type mapConstX = Xpetra::MapFactory<LO,GO,NO>::Build( Xpetra::UseTpetra, mapConstTmp->getGlobalNumElements(), mapConstTmp->getNodeElementList(), mapConstTmp->getIndexBase(), mapConstTmp->getComm() );
1711 Teuchos::RCP<Xpetra::Map<LO,GO,NO> > mapX= Teuchos::rcp_const_cast<Xpetra::Map<LO,GO,NO> > (mapConstX);
1713 repeatedMaps[0] = mapX;
1715 if (!pressureSubList->get(
"DofOrdering",
"NodeWise" ).compare(
"DimensionWise"))
1716 dofOrderings[0] = FROSch::DimensionWise;
1717 else if (!pressureSubList->get(
"DofOrdering",
"NodeWise" ).compare(
"NodeWise"))
1718 dofOrderings[0] = FROSch::NodeWise;
1720 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Please chose a valid DOF ordering for ThyraPreconditioner(FROSch).");
1722 pressureSubList->set(
"Repeated Map Vector",repeatedMaps);
1723 pressureSubList->set(
"DofOrdering Vector",dofOrderings);
1724 pressureSubList->set(
"DofsPerNode Vector",dofsPerNodeVector);
1725 pressureSubList->set(
"Mpi Ranks Coarse", coarseRanks );
1727 int lowerBound = 100000000;
1728 int upperBound = -1;
1731 tuple_intint_Type rankRange;
1732 if (!problem_.is_null())
1733 rankRange = problem_->getDomain(1)->getMesh()->getRankRange();
1734 else if(!timeProblem_.is_null())
1735 rankRange = timeProblem_->getDomain(1)->getMesh()->getRankRange();
1737 if (std::get<0>(rankRange) < lowerBound)
1738 lowerBound = std::get<0>(rankRange);
1739 if (std::get<1>(rankRange) > upperBound)
1740 upperBound = std::get<1>(rankRange);
1742 int lowerBoundCoarse = lowerBound;
1743 int upperBoundCoarse = upperBound;
1745 if ( coarseRanks > 0 ){
1746 lowerBoundCoarse = upperBound + 1;
1747 upperBoundCoarse = comm->getSize() - 1;
1750 std::cout <<
"\t --- ------------------------------------------------------------------- ---"<< std::endl;
1751 std::cout <<
"\t --- Range for local problems of preconditioner Teko pressure from " << lowerBound <<
" to " << upperBound << std::endl;
1752 std::cout <<
"\t --- Range for coarse problem of preconditioner Teko pressure from " << lowerBoundCoarse <<
" to " << upperBoundCoarse << std::endl;
1753 std::cout <<
"\t --- ------------------------------------------------------------------- ---"<< std::endl;
1756 pressureSubList->set(
"Local problem ranks lower bound", lowerBound );
1757 pressureSubList->set(
"Local problem ranks upper bound", upperBound );
1759 pressureSubList->set(
"Coarse problem ranks lower bound", lowerBoundCoarse );
1760 pressureSubList->set(
"Coarse problem ranks upper bound", upperBoundCoarse );
1765template <
class SC,
class LO,
class GO,
class NO>
1766typename Preconditioner<SC,LO,GO,NO>::ThyraLinOpConstPtr_Type Preconditioner<SC,LO,GO,NO>::getTekoOp(){
1770template <
class SC,
class LO,
class GO,
class NO>
1771void Preconditioner<SC,LO,GO,NO>::setVelocityMassMatrix(MatrixPtr_Type massMatrix)
const{
1772 velocityMassMatrix_ = massMatrix->getThyraLinOp();
1773 velocityMassMatrixMatrixPtr_ = massMatrix;
1777template <
class SC,
class LO,
class GO,
class NO>
1778void Preconditioner<SC,LO,GO,NO>::exportCoarseBasis( ){
1780 CommConstPtr_Type comm;
1781 if (!problem_.is_null())
1782 comm = problem_->getComm();
1783 else if(!timeProblem_.is_null())
1784 comm = timeProblem_->getComm();
1786 TEUCHOS_TEST_FOR_EXCEPTION( pListPhiExport_.is_null(), std::runtime_error,
"No parameterlist to extract Phi pointer.");
1787 ParameterListPtr_Type pLPrec = sublist( sublist( pListPhiExport_,
"Preconditioner Types" ) ,
"FROSch" );
1788 std::string coarseType = pLPrec->get(
"CoarseOperator Type",
"RGDSWCoarseOperator" );
1789 ParameterListPtr_Type pLCoarse = sublist( pLPrec, coarseType );
1792 TEUCHOS_TEST_FOR_EXCEPTION( !pLCoarse->isParameter(
"RCP(Phi)"), std::runtime_error,
"No parameter to extract Phi pointer.");
1794 Teuchos::RCP<Tpetra::CrsMatrix<SC,LO,GO,NO> > phiTpetra;
1796 TEUCHOS_TEST_FOR_EXCEPTION( !pLCoarse->isType<
decltype(phiTpetra)>(
"RCP(Phi)"), std::runtime_error,
"Wrong type of pointer to extract Phi.");
1798 phiTpetra = pLCoarse->get<
decltype(phiTpetra)>(
"RCP(Phi)");
1800 MatrixPtr_Type phiMatrix = Teuchos::rcp(
new Matrix_Type( phiTpetra ) );
1803 ParameterListPtr_Type parameterList;
1804 if (!problem_.is_null())
1805 parameterList = problem_->getParameterList();
1806 else if(!timeProblem_.is_null())
1807 parameterList = timeProblem_->getParameterList();
1808 numberOfBlocks = parameterList->get(
"Number of blocks",1);
1811 std::vector<MapConstPtr_Type> blockMaps(numberOfBlocks);
1812 MultiVectorPtr_Type phiMV;
1813 phiMatrix->toMV( phiMV );
1815 for (UN i = 0; i < numberOfBlocks; i++) {
1816 int dofsPerNode = pLPrec->get(
"DofsPerNode" + std::to_string(i+1), 1);
1817 MapConstPtr_Type map;
1818 if (dofsPerNode>1) {
1819 if (!problem_.is_null()) {
1820 TEUCHOS_TEST_FOR_EXCEPTION( problem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Vector field map not implemented for P0 elements.");
1821 map = problem_->getDomain(i)->getMapVecFieldUnique();
1823 else if(!timeProblem_.is_null()){
1824 TEUCHOS_TEST_FOR_EXCEPTION( timeProblem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Vector field map not implemented for P0 elements.");
1825 map = timeProblem_->getDomain(i)->getMapVecFieldUnique();
1829 if (!problem_.is_null()) {
1830 TEUCHOS_TEST_FOR_EXCEPTION( problem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Vector field map not implemented for P0 elements.");
1831 map = problem_->getDomain(i)->getMapUnique();
1833 else if(!timeProblem_.is_null()){
1834 TEUCHOS_TEST_FOR_EXCEPTION( timeProblem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Vector field map not implemented for P0 elements.");
1835 map = timeProblem_->getDomain(i)->getMapUnique();
1842 BlockMultiVectorPtr_Type phiBlockMV = Teuchos::rcp(
new BlockMultiVector_Type ( blockMaps, phiMV->getNumVectors() ) );
1843 phiBlockMV->setMergedVector( phiMV );
1844 phiBlockMV->split();
1846 ParameterListPtr_Type pLProblem;
1847 if (!problem_.is_null())
1848 pLProblem = problem_->getParameterList();
1849 else if(!timeProblem_.is_null())
1850 pLProblem = timeProblem_->getParameterList();
1852 BlockMultiVectorPtr_Type phiSumBlockMV = phiBlockMV->sumColumns();
1854 for (
int i=0; i<phiBlockMV->size(); i++) {
1855 bool exportThisBlock = !pLProblem->sublist(
"Exporter").get(
"Exclude coarse functions block" + std::to_string(i+1),
false);
1857 if (exportThisBlock){
1858 Teuchos::RCP<ExporterParaView<SC,LO,GO,NO> > exporter(
new ExporterParaView<SC,LO,GO,NO>());
1860 DomainConstPtr_Type domain;
1861 if (!problem_.is_null())
1862 domain = problem_->getDomain(i);
1863 else if(!timeProblem_.is_null())
1864 domain = timeProblem_->getDomain(i);
1866 int dofsPerNode = domain->getDimension();
1867 std::string fileName = pLProblem->sublist(
"Exporter").get(
"Name coarse functions block" + std::to_string(i+1),
"phi");
1869 MeshPtr_Type meshNonConst = Teuchos::rcp_const_cast<Mesh_Type>( domain->getMesh() );
1870 exporter->setup(fileName, meshNonConst, domain->getFEType());
1872 for (
int j=0; j<phiBlockMV->getNumVectors(); j++) {
1874 MultiVectorConstPtr_Type exportPhi = phiBlockMV->getBlock( i )->getVector( j );
1876 std::string varName = fileName + std::to_string(j);
1877 if ( pLPrec->get(
"DofsPerNode" + std::to_string(i+1), 1) > 1 )
1878 exporter->addVariable( exportPhi, varName,
"Vector", dofsPerNode, domain->getMapUnique() );
1880 exporter->addVariable( exportPhi, varName,
"Scalar", 1, domain->getMapUnique() );
1883 MultiVectorConstPtr_Type exportSumPhi = phiSumBlockMV->getBlock(i);
1884 std::string varName = fileName +
"Sum";
1885 if ( pLPrec->get(
"DofsPerNode" + std::to_string(i+1), 1) > 1 )
1886 exporter->addVariable( exportSumPhi, varName,
"Vector", dofsPerNode, domain->getMapUnique() );
1888 exporter->addVariable( exportSumPhi, varName,
"Scalar", 1, domain->getMapUnique() );
1890 exporter->save(0.0);
1896template <
class SC,
class LO,
class GO,
class NO>
1897void Preconditioner<SC,LO,GO,NO>::exportCoarseBasisFSI( ){
1899 CommConstPtr_Type comm;
1900 if (!problem_.is_null())
1901 comm = problem_->getComm();
1902 else if(!timeProblem_.is_null())
1903 comm = timeProblem_->getComm();
1905 TEUCHOS_TEST_FOR_EXCEPTION( pListPhiExport_.is_null(), std::runtime_error,
"No parameterlist to extract Phi pointer.");
1906 ParameterListPtr_Type pLPrec = sublist( sublist( pListPhiExport_,
"Preconditioner Types" ) ,
"FROSch" );
1907 std::string coarseType = pLPrec->get(
"CoarseOperator Type",
"RGDSWCoarseOperator" );
1908 ParameterListPtr_Type pLCoarse = sublist( pLPrec, coarseType );
1911 TEUCHOS_TEST_FOR_EXCEPTION( !pLCoarse->isParameter(
"Phi Pointer"), std::runtime_error,
"No parameter to extract Phi pointer.");
1913 Teuchos::RCP<Tpetra::CrsMatrix<SC,LO,GO,NO> > phiTpetra;
1915 TEUCHOS_TEST_FOR_EXCEPTION( !pLCoarse->isType<
decltype(phiTpetra)>(
"Phi Pointer"), std::runtime_error,
"Wrong type of pointer to extract Phi.");
1917 phiTpetra = pLCoarse->get<
decltype(phiTpetra)>(
"Phi Pointer");
1919 MatrixPtr_Type phiMatrix = Teuchos::rcp(
new Matrix_Type( phiTpetra ) );
1922 ParameterListPtr_Type parameterList;
1923 if (!problem_.is_null())
1924 parameterList = problem_->getParameterList();
1925 else if(!timeProblem_.is_null())
1926 parameterList = timeProblem_->getParameterList();
1927 numberOfBlocks = parameterList->get(
"Number of blocks",1);
1930 std::vector<MapConstPtr_Type> blockMaps(numberOfBlocks);
1931 MultiVectorPtr_Type phiMV;
1932 phiMatrix->toMV( phiMV );
1934 for (UN i = 0; i < numberOfBlocks; i++) {
1935 int dofsPerNode = pLPrec->get(
"DofsPerNode" + std::to_string(i+1), 1);
1936 MapConstPtr_Type map;
1938 map = timeProblem_->getDomain(i)->getInterfaceMapVecFieldUnique();
1941 if (dofsPerNode>1) {
1942 if (!problem_.is_null()) {
1943 TEUCHOS_TEST_FOR_EXCEPTION( problem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Vector field map not implemented for P0 elements.");
1944 map = problem_->getDomain(i)->getMapVecFieldUnique();
1946 else if(!timeProblem_.is_null()){
1947 TEUCHOS_TEST_FOR_EXCEPTION( timeProblem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Vector field map not implemented for P0 elements.");
1948 map = timeProblem_->getDomain(i)->getMapVecFieldUnique();
1952 if (!problem_.is_null()) {
1953 TEUCHOS_TEST_FOR_EXCEPTION( problem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Vector field map not implemented for P0 elements.");
1954 map = problem_->getDomain(i)->getMapUnique();
1956 else if(!timeProblem_.is_null()){
1957 TEUCHOS_TEST_FOR_EXCEPTION( timeProblem_->getDomain(i)->getFEType() ==
"P0", std::logic_error,
"Vector field map not implemented for P0 elements.");
1958 map = timeProblem_->getDomain(i)->getMapUnique();
1966 BlockMultiVectorPtr_Type phiBlockMV = Teuchos::rcp(
new BlockMultiVector_Type ( blockMaps, phiMV->getNumVectors() ) );
1967 phiBlockMV->setMergedVector( phiMV );
1968 phiBlockMV->split();
1970 ParameterListPtr_Type pLProblem;
1971 if (!problem_.is_null())
1972 pLProblem = problem_->getParameterList();
1973 else if(!timeProblem_.is_null())
1974 pLProblem = timeProblem_->getParameterList();
1976 BlockMultiVectorPtr_Type phiSumBlockMV = phiBlockMV->sumColumns();
1978 for (
int i=0; i<phiBlockMV->size(); i++) {
1979 bool exportThisBlock = !pLProblem->sublist(
"Exporter").get(
"Exclude coarse functions block" + std::to_string(i+1),
false);
1981 if (exportThisBlock){
1982 Teuchos::RCP<ExporterParaView<SC,LO,GO,NO> > exporter(
new ExporterParaView<SC,LO,GO,NO>());
1984 DomainConstPtr_Type domain;
1985 if (!problem_.is_null())
1986 domain = problem_->getDomain(i);
1987 else if(!timeProblem_.is_null())
1988 domain = timeProblem_->getDomain(i);
1990 int dofsPerNode = domain->getDimension();
1991 std::string fileName = pLProblem->sublist(
"Exporter").get(
"Name coarse functions block" + std::to_string(i+1),
"phi");
1993 MeshPtr_Type meshNonConst = Teuchos::rcp_const_cast<Mesh_Type>( domain->getMesh() );
1994 exporter->setup(fileName, meshNonConst, domain->getFEType());
1996 for (
int j=0; j<phiBlockMV->getNumVectors(); j++) {
1998 MultiVectorConstPtr_Type exportPhi = phiBlockMV->getBlock( i )->getVector( j );
2000 std::string varName = fileName + std::to_string(j);
2001 if ( pLPrec->get(
"DofsPerNode" + std::to_string(i+1), 1) > 1 )
2002 exporter->addVariable( exportPhi, varName,
"Vector", dofsPerNode, domain->getMapUnique() );
2004 exporter->addVariable( exportPhi, varName,
"Scalar", 1, domain->getMapUnique() );
2007 MultiVectorConstPtr_Type exportSumPhi = phiSumBlockMV->getBlock(i);
2008 std::string varName = fileName +
"Sum";
2009 if ( pLPrec->get(
"DofsPerNode" + std::to_string(i+1), 1) > 1 )
2010 exporter->addVariable( exportSumPhi, varName,
"Vector", dofsPerNode, domain->getMapUnique() );
2012 exporter->addVariable( exportSumPhi, varName,
"Scalar", 1, domain->getMapUnique() );
2014 exporter->save(0.0);
void setPressureProjection(BlockMultiVectorPtr_Type pressureProjection) const
Setting pressure projection from specific prolem to be used in preconditioner.
Definition Preconditioner_def.hpp:175
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement_decl.hpp:36