4#if defined(FEAT_HAVE_TRILINOS)
7#ifdef FROSCH_SEQUENTIAL
8# error FROSCH_SEQUENTIAL does not make sense
11# ifndef FROSCH_HAVE_MPI
12# define FROSCH_HAVE_MPI 1
15# error FROSch without MPI does not make sense.
18#define FROSCH_TIMER_DETAILS 2
20#include <ShyLU_DDFROSch_config.h>
24#include <Teuchos_GlobalMPISession.hpp>
25#include <Teuchos_CommandLineProcessor.hpp>
26#include <Teuchos_XMLParameterListCoreHelpers.hpp>
27#include <Teuchos_StackedTimer.hpp>
30#include <Thyra_LinearOpWithSolveBase.hpp>
31#include <Thyra_LinearOpWithSolveFactoryHelpers.hpp>
32#include <Thyra_SolveSupportTypes.hpp>
33#include <Thyra_TpetraLinearOp.hpp>
34#include <Thyra_TpetraMultiVector.hpp>
35#include <Thyra_TpetraThyraWrappers.hpp>
36#include <Thyra_TpetraVector.hpp>
37#include <Thyra_VectorBase.hpp>
38#include <Thyra_VectorStdOps.hpp>
39#ifdef HAVE_SHYLU_DDFROSCH_EPETRA
40#include <Thyra_EpetraLinearOp.hpp>
42#include <Thyra_VectorSpaceBase_decl.hpp>
43#include <Thyra_VectorSpaceBase_def.hpp>
46#include <Stratimikos_DefaultLinearSolverBuilder.hpp>
47#include <Stratimikos_FROSch_def.hpp>
49#include <Tpetra_Core.hpp>
50#include <Tpetra_MultiVector.hpp>
51#include <Tpetra_CrsMatrix.hpp>
54#include <Thyra_FROSchLinearOp_def.hpp>
55#include <Thyra_FROSchFactory_def.hpp>
56#include <FROSch_Tools_def.hpp>
62#include <kernel/lafem/dense_vector.hpp>
63#include <kernel/util/simple_arg_parser.hpp>
64#include <kernel/util/dist_file_io.hpp>
65#include <kernel/util/hash.hpp>
70using DataType = double;
104 class FROSchParameterList
115 enum Preconditioner {
134 enum PartitionApproach {
139 enum CombineOverlap {
191 explicit FROSchParameterList(
const Dist::Comm& comm_,
const int dim_,
const FROSchParameterList::ProblemType problem_,
const int nlevels_ = 1,
const std::string& name_ =
"FEAT-FROSch Parameterlist");
213 explicit FROSchParameterList(
const Dist::Comm& comm_,
const int dim_,
const std::string& xml_file_,
const std::string& name_ =
"Parameter List");
214 ~FROSchParameterList();
216 void read_from_xml_str(
const std::string &xml_str_);
217 void read_from_xml_file(
const std::string &xml_file_);
223 void* get_core()
const;
229 int get_dpe_velo()
const;
230 int get_dpe_pres()
const;
231 int get_nlevels()
const;
232 bool get_use_timer()
const;
233 bool get_print()
const;
235 void set_dim(
const int dim);
236 void set_nlevels(
const int nlevels);
237 void set_problem_type(
const ProblemType problem_);
238 void set_use_timer(
const bool use_timer_);
239 void set_print(
const bool print_);
241 void set_precond(
const Preconditioner precond_);
242 void set_coarse_solver(
const DirectSolver solver_);
244 void set_gsteps(
const int gsteps_);
245 void set_gsteps(
const std::vector<int>& gsteps_);
247 void set_overlaps(
const int overlap_);
248 void set_overlaps(
const std::vector<int>& overlaps_);
250 void set_combine_overlap(
const CombineOverlap combine_mode_);
251 void set_combine_overlap(
const std::vector<CombineOverlap>& combine_mode_);
253 void set_combine_lvl(
const CombineLevel combine_mode_);
254 void set_combine_lvl(
const std::vector<CombineLevel>& combine_lvl_);
256 void set_solvers(
const DirectSolver solver_ao_,
const DirectSolver solver_ext_);
257 void set_solvers(
const std::vector<DirectSolver>& solvers_ao_,
const std::vector<DirectSolver>& solvers_ext_);
258 void set_solvers_ao(
const DirectSolver solver_);
259 void set_solvers_ao(
const std::vector<DirectSolver>& solvers_);
260 void set_solvers_ext(
const DirectSolver solver_);
261 void set_solvers_ext(
const std::vector<DirectSolver>& solvers_);
263 void set_paritioner(
const std::vector<int>& subregions_,
const PartitionType parti_type_,
const PartitionApproach parti_approach_,
const double parti_imbl_);
264 void set_paritioner(
const std::vector<int>& subregions_,
const std::vector<PartitionType>& parti_types_,
const std::vector<PartitionApproach>& parti_approach_,
const std::vector<double>& parti_imbl_);
266 void set_subregions(
const std::vector<int>& subregions_);
268 void set_parti_types(
const PartitionType parti_type_);
269 void set_parti_types(
const std::vector<PartitionType>& parti_types_);
271 void set_parti_approach(
const PartitionApproach parti_approach_);
272 void set_parti_approach(
const std::vector<PartitionApproach>& parti_approach_);
274 void set_parti_imbl(
const double parti_imbl_);
275 void set_parti_imbl(
const std::vector<double>& parti_imbl_);
277 void set_excludes(
const bool velo_pres_,
const bool pres_velo_);
278 void set_excludes(
const std::vector<bool>& velo_pres_,
const std::vector<bool>& pres_velo_);
279 void set_excludes_velo_pres(
const bool velo_pres_);
280 void set_excludes_velo_pres(
const std::vector<bool>& velo_pres_);
281 void set_excludes_pres_velo(
const bool pres_velo_);
282 void set_excludes_pres_velo(
const std::vector<bool>& pres_velo_);
284 void set_ipous(
const IPOU ipou_velo_,
const IPOU ipou_pres_);
285 void set_ipous(
const std::vector<IPOU>& ipous_velo_,
const std::vector<IPOU>& ipous_pres_);
286 void set_ipous_velo(
const IPOU ipou_);
287 void set_ipous_velo(
const std::vector<IPOU>& ipous_);
288 void set_ipous_pres(
const IPOU ipou_);
289 void set_ipous_pres(
const std::vector<IPOU>& ipous_);
291 void set_cspace(
const bool cspace_velo_,
const bool cspace_pres_);
292 void set_cspace(
const std::vector<bool>& cspace_velo_,
const std::vector<bool>& cspace_pres_);
293 void set_cspace_velo(
const bool cspace_);
294 void set_cspace_velo(
const std::vector<bool>& cspace_);
295 void set_cspace_pres(
const bool cspace_);
296 void set_cspace_pres(
const std::vector<bool>& cspace_);
298 void set_reuse_sf(
const bool rsf_ao_,
const bool rsf_cm_);
299 void set_reuse_sf(
const std::vector<bool> &rsf_ao_,
const std::vector<bool> &rsf_cm_);
300 void set_reuse_sf_ao(
const bool rsf_ao_);
301 void set_reuse_sf_ao(
const std::vector<bool> &rsf_ao_);
302 void set_reuse_sf_cm(
const bool rsf_cm_);
303 void set_reuse_sf_cm(
const std::vector<bool> &rsf_cm_);
305 void set_reuse_coarse(
const bool reuse_cm_,
const bool reuse_cb_);
306 void set_reuse_coarse(
const std::vector<bool> &reuse_cm_,
const std::vector<bool> &reuse_cb_);
307 void set_reuse_coarse_matrix(
const bool reuse_cm_);
308 void set_reuse_coarse_matrix(
const std::vector<bool> &reuse_cm_);
309 void set_reuse_coarse_basis(
const bool reuse_cb_);
310 void set_reuse_coarse_basis(
const std::vector<bool> &reuse_cb_);
312 void set_phi_dropping_threshold(
const double phi_dt_);
313 void set_phi_dropping_threshold(
const std::vector<double> &phi_dt_);
315 void set_verbose(
const bool verbose_);
317 bool parse_args(SimpleArgParser& args);
325 const Dist::Comm& _comm;
342 ProblemType _problem;
343 Preconditioner _preconditioner;
344 DirectSolver _solver_coarse;
346 std::vector<int> _gsteps;
348 std::vector<int> _overlaps;
349 std::vector<DirectSolver> _solvers_ao;
350 std::vector<DirectSolver> _solvers_ext;
353 std::vector<int> _subregions;
354 std::vector<PartitionType> _partition_types;
355 std::vector<PartitionApproach> _partition_approach;
356 std::vector<double> _partition_imbl_tol;
363 std::vector<bool> _exclude_pres_velo;
364 std::vector<bool> _exclude_velo_pres;
368 std::vector<bool> _cspace_velo;
369 std::vector<bool> _cspace_pres;
371 std::vector<IPOU> _ipous_velo;
372 std::vector<IPOU> _ipous_pres;
375 std::vector<CombineOverlap> _combine_ov;
378 std::vector<CombineLevel> _combine_lvl;
381 std::vector<bool> _ao_rsf;
383 std::vector<bool> _cm_rsf;
386 std::vector<bool> _cm_r;
388 std::vector<bool> _cb_r;
392 std::vector<double> _phi_dt;
404 void init_defaults();
408 inline void parameterlist_set_level_id(
const int levelid, Teuchos::ParameterList ¶ms)
410 params.set(
"Level ID", (
unsigned int)levelid);
413 inline void parameterlist_set_default_block_id(
const int defblockid, Teuchos::ParameterList ¶ms)
415 params.set(
"Default BlockId Subdomain Graph", defblockid);
418 inline void parameterlist_set_dim(
const int dimension, Teuchos::ParameterList ¶ms)
420 params.set(
"Dimension", dimension);
423 inline void parameterlist_set_overlap(
const int overlap, Teuchos::ParameterList ¶ms)
425 params.set(
"Overlap", overlap);
428 inline void parameterlist_set_precond(
const FROSchParameterList::Preconditioner precond,
const bool reuse, Teuchos::ParameterList ¶ms)
430 if(precond == FROSchParameterList::TWOLEVEL)
432 params.set(
"FROSch Preconditioner Type",
"TwoLevelPreconditioner");
433 }
else if(precond == FROSchParameterList::TWOLEVELBLOCK)
435 params.set(
"FROSch Preconditioner Type",
"TwoLevelBlockPreconditioner");
436 }
else if(precond == FROSchParameterList::ONELEVEL)
438 params.set(
"FROSch Preconditioner Type",
"OneLevelPreconditioner");
441 XASSERTM(
false,
"Unkown FROSchParameterList::Preconditioner type");
443 params.set(
"Recycling", reuse);
446 inline void parameterlist_set_combine_lvl(
const FROSchParameterList::CombineLevel combine_lvl, Teuchos::ParameterList ¶ms)
448 if(combine_lvl == FROSchParameterList::ADDITIVE)
449 params.set(
"Level Combination",
"Additive");
450 else if(combine_lvl == FROSchParameterList::MULTIPLICATIVE)
451 params.set(
"Level Combination",
"Multiplicative");
453 XASSERTM(
false,
"Unkown FROSchParameterList::CombineLevel type");
456 inline void parameterlist_set_verbose(
const bool verbose, Teuchos::ParameterList ¶ms)
458 params.set(
"Verbose", verbose);
461 inline void parameterlist_header(
const int dim,
const int overlap,
const int levelid,
const int defblockid,
const FROSchParameterList::Preconditioner precond,
const std::string& nullspace,
const FROSchParameterList::CombineLevel combine_lvl,
const bool reuse,
const bool verbose, Teuchos::ParameterList ¶ms)
463 parameterlist_set_dim(dim, params);
464 parameterlist_set_overlap(overlap, params);
465 parameterlist_set_default_block_id(defblockid, params);
466 parameterlist_set_level_id(levelid, params);
467 parameterlist_set_precond(precond, reuse, params);
468 parameterlist_set_combine_lvl(combine_lvl, params);
469 parameterlist_set_verbose(verbose, params);
470 params.set(
"Null Space Type", nullspace);
471 params.set(
"OverlappingOperator Type",
"AlgebraicOverlappingOperator");
472 params.set(
"CoarseOperator Type",
"IPOUHarmonicCoarseOperator");
475 inline void parameterlist_set_solver(
const FROSchParameterList::DirectSolver solver, Teuchos::ParameterList ¶ms)
477 if(solver == FROSchParameterList::ILU)
479 params.set(
"SolverType",
"Ifpack2");
480 params.set(
"Solver",
"RILUK");
481 params.set(
"Ifpack2", Teuchos::ParameterList(
"Ifpack2"));
482 params.sublist(
"Ifpack2").set(
"fact: iluk level-of-fill", 0);
485 params.set(
"SolverType",
"Amesos2");
486 if(solver == FROSchParameterList::KLU)
487 params.set(
"Solver",
"Klu");
488 else if(solver == FROSchParameterList::MUMPS)
489 params.set(
"Solver",
"Mumps");
490 else if(solver == FROSchParameterList::UMFPACK)
491 params.set(
"Solver",
"Umfpack");
493 XASSERTM(
false,
"Unkown FROSchParameterList::DirectSolver type");
497 inline void parameterlist_set_aoo(
const FROSchParameterList::DirectSolver solver, Teuchos::ParameterList ¶ms)
499 params.set(
"AlgebraicOverlappingOperator", Teuchos::ParameterList(
"AlgebraicOverlappingOperator"));
500 if(solver == FROSchParameterList::MUMPS)
501 params.sublist(
"AlgebraicOverlappingOperator").set(
"Reuse: Symbolic Factorization",
false);
502 params.sublist(
"AlgebraicOverlappingOperator").set(
"Solver", Teuchos::ParameterList(
"Solver"));
503 parameterlist_set_solver(solver, params.sublist(
"AlgebraicOverlappingOperator").sublist(
"Solver"));
506 inline void parameterlist_set_extsolv(
const FROSchParameterList::DirectSolver solver, Teuchos::ParameterList ¶ms)
508 params.set(
"ExtensionSolver", Teuchos::ParameterList(
"ExtensionSolver"));
509 parameterlist_set_solver(solver, params.sublist(
"ExtensionSolver"));
512 inline void parameterlist_set_coarsesolv(
const FROSchParameterList::DirectSolver solver, Teuchos::ParameterList ¶ms)
514 params.set(
"CoarseSolver", Teuchos::ParameterList(
"CoarseSolver"));
515 parameterlist_set_solver(solver, params.sublist(
"CoarseSolver"));
518 inline void parameterlist_combine_overlap(
const FROSchParameterList::CombineOverlap mode, Teuchos::ParameterList ¶ms)
520 if(mode == FROSchParameterList::FULL)
521 params.set(
"Combine Values in Overlap",
"Full");
522 else if(mode == FROSchParameterList::RESTRICTED)
523 params.set(
"Combine Values in Overlap",
"Restricted");
524 else if(mode == FROSchParameterList::AVERAGING)
525 params.set(
"Combine Values in Overlap",
"Averaging");
527 XASSERTM(
false,
"Unkown FROSchParameterList::DirectSolver type");
530 inline void parameterlist_set_zoltan2(
const FROSchParameterList::PartitionType parti_type,
const FROSchParameterList::PartitionApproach parti_app,
const double parti_imbl, Teuchos::ParameterList ¶ms)
532 params.set(
"Zoltan2 Parameter", Teuchos::ParameterList(
"Zoltan2 Parameter"));
533 if(parti_type == FROSchParameterList::PARMETIS)
534 params.sublist(
"Zoltan2 Parameter").set(
"algorithm",
"parmetis");
535 else if(parti_type == FROSchParameterList::SCOTCH)
536 params.sublist(
"Zoltan2 Parameter").set(
"algorithm",
"scotch");
537 else if(parti_type == FROSchParameterList::PTSCOTCH)
538 params.sublist(
"Zoltan2 Parameter").set(
"algorithm",
"ptscotch");
539 else if(parti_type == FROSchParameterList::BLOCK)
540 params.sublist(
"Zoltan2 Parameter").set(
"algorithm",
"block");
541 else if(parti_type == FROSchParameterList::PHG)
542 params.sublist(
"Zoltan2 Parameter").set(
"algorithm",
"phg");
544 XASSERTM(
false,
"Unkown FROSchParameterList::PartitionType type");
547 params.sublist(
"Zoltan2 Parameter").set(
"imbalance_tolerance", parti_imbl);
548 if(parti_app == FROSchParameterList::PARTITION)
549 params.sublist(
"Zoltan2 Parameter").set(
"partitioning_approach",
"partition");
550 else if(parti_app == FROSchParameterList::REPARTITION)
551 params.sublist(
"Zoltan2 Parameter").set(
"partitioning_approach",
"repartition");
553 XASSERTM(
false,
"Unkown FROSchParameterList::PartitionApproach type");
556 inline void parameterlist_set_distribution(
const int subreg,
const FROSchParameterList::PartitionType parti_type,
const FROSchParameterList::PartitionApproach parti_app,
const double parti_imbl,
const int gsteps, Teuchos::ParameterList ¶ms)
558 params.set(
"Distribution", Teuchos::ParameterList(
"Distribution"));
559 params.sublist(
"Distribution").set(
"NumProcs", subreg);
562 params.sublist(
"Distribution").set(
"Type",
"linear");
565 params.sublist(
"Distribution").set(
"Type",
"ZoltanDual");
566 parameterlist_set_zoltan2(parti_type, parti_app, parti_imbl, params.sublist(
"Distribution"));
568 params.sublist(
"Distribution").set(
"Factor", (
double)1.0);
569 params.sublist(
"Distribution").set(
"GatheringSteps", gsteps);
570 params.sublist(
"Distribution").set(
"Gathering Communication", Teuchos::ParameterList(
"Gathering Communication"));
571 params.sublist(
"Distribution").sublist(
"Gathering Communication").set(
"Send type",
"Send");
574 inline void parameterlist_set_ipou(
const FROSchParameterList::IPOU ipou,
const bool verbose, Teuchos::ParameterList ¶ms)
576 std::string ipou_str;
577 if(ipou == FROSchParameterList::GDSW)
579 else if(ipou == FROSchParameterList::GDSWSTAR)
580 ipou_str =
"GDSWStar";
581 else if(ipou == FROSchParameterList::RGDSW)
584 XASSERTM(
false,
"Unkown FROSchParameterList::IPOU type");
585 params.set(
"InterfacePartitionOfUnity", Teuchos::ParameterList(
"InterfacePartitionOfUnity"));
586 params.sublist(
"InterfacePartitionOfUnity").set(
"Verbose", verbose);
587 params.sublist(
"InterfacePartitionOfUnity").set(
"Type", ipou_str);
588 params.sublist(
"InterfacePartitionOfUnity").set(ipou_str, Teuchos::ParameterList(ipou_str));
589 params.sublist(
"InterfacePartitionOfUnity").sublist(ipou_str).set(
"Verbose", verbose);
590 params.sublist(
"InterfacePartitionOfUnity").sublist(ipou_str).set(
"Type",
"Full");
591 params.sublist(
"InterfacePartitionOfUnity").sublist(ipou_str).set(
"Distance Function",
"Constant");
592 params.sublist(
"InterfacePartitionOfUnity").sublist(ipou_str).set(
"Custom", Teuchos::ParameterList(
"Custom"));
593 params.sublist(
"InterfacePartitionOfUnity").sublist(ipou_str).sublist(
"Custom").set(
"Roots",
true);
596 params.set(
"PartitionOfUnity", Teuchos::ParameterList(
"PartitionOfUnity"));
597 params.sublist(
"PartitionOfUnity").set(
"Constant", Teuchos::ParameterList(
"Constant"));
598 params.sublist(
"PartitionOfUnity").sublist(
"Constant").set(
"Verbose", verbose);
601 inline void parameterlist_set_block(
const int blockid,
const bool use_cspace,
const int exclude,
const FROSchParameterList::IPOU ipou,
const bool verbose, Teuchos::ParameterList ¶ms)
603 std::string blockid_str = std::to_string(blockid);
604 std::string excl_str = std::to_string(exclude);
606 params.set(blockid_str, Teuchos::ParameterList(blockid_str));
607 params.sublist(blockid_str).set(
"Use For Coarse Space", use_cspace);
609 params.sublist(blockid_str).set(
"Verbosity",
"All");
611 params.sublist(blockid_str).set(
"Verbosity",
"None");
613 params.sublist(blockid_str).set(
"Exclude", excl_str);
614 params.sublist(blockid_str).set(
"Rotations",
false);
615 parameterlist_set_ipou(ipou, verbose, params.sublist(blockid_str));
618 inline void parameterlist_set_reuse_coarse(
const bool rsf_cm,
const bool reuse_cm,
const bool reuse_cb, Teuchos::ParameterList ¶ms)
620 params.set(
"Reuse: Coarse Matrix Symbolic Factorization", rsf_cm);
621 params.set(
"Reuse: Coarse Matrix", reuse_cm);
622 params.set(
"Reuse: Coarse Basis", reuse_cb);
625 FROSchParameterList::FROSchParameterList(
const Dist::Comm& comm_,
const int dim_,
const FROSchParameterList::ProblemType problem_,
const int nlevels_,
const std::string& name_) :
637 XASSERTM(dim_ == 2 || dim_ == 3,
"Only implemented for dim == 2 or dim == 3");
641 FROSchParameterList::FROSchParameterList(
const Dist::Comm& comm_,
const int dim_,
const std::string& xml_file_,
const std::string& name_) :
652 read_from_xml_file(xml_file_);
655 FROSchParameterList::~FROSchParameterList()
660 void FROSchParameterList::read_from_xml_str(
const std::string& xml_str_)
664 Teuchos::ParameterList *param =
new Teuchos::ParameterList(_name);
665 Teuchos::Ptr<Teuchos::ParameterList> ptr_param(param);
666 Teuchos::updateParametersFromXmlString(xml_str_, ptr_param);
668 _core = (
void*)ptr_param.get();
671 void FROSchParameterList::read_from_xml_file(
const std::string& xml_file_)
673 std::stringstream xml_str;
674 DistFileIO::read_common(xml_str, xml_file_, _comm);
675 read_from_xml_str(xml_str.str());
678 void FROSchParameterList::init_defaults()
685 set_subregions(std::vector<int>(1, 1));
687 set_parti_types(FROSchParameterList::PARMETIS);
688 set_parti_approach(FROSchParameterList::REPARTITION);
691 set_ipous(GDSW, GDSW);
693 set_ipous(GDSWSTAR, GDSW);
695 set_solvers(FROSchParameterList::KLU, FROSchParameterList::KLU);
696 _solver_coarse = FROSchParameterList::KLU;
697 _preconditioner = FROSchParameterList::TWOLEVELBLOCK;
698 set_cspace(
true,
true);
699 set_excludes(
false,
false);
701 set_combine_overlap(FROSchParameterList::RESTRICTED);
702 set_combine_lvl(FROSchParameterList::ADDITIVE);
704 set_reuse_sf(
false,
false);
705 set_reuse_coarse(
false,
false);
706 set_phi_dropping_threshold(1.e-8);
711 void FROSchParameterList::print()
const
713 if(_comm.rank() == 0)
715 XASSERTM(_core !=
nullptr,
"_core == nullptr");
716 (
reinterpret_cast<Teuchos::ParameterList*
>(_core))->print(std::cout, 4);
720 void* FROSchParameterList::get_core()
const
725 void FROSchParameterList::create_core()
733 XASSERTM(_nlevels ==
int(_subregions.size()),
"number of subregions is not consistent with number of levels.");
734 XASSERTM(_subregions.back() == 1,
"last entry of subregions is not 1.");
736 std::string precond_str;
737 if(_preconditioner == FROSchParameterList::TWOLEVEL)
738 precond_str =
"TwoLevelPreconditioner";
739 else if(_preconditioner == FROSchParameterList::TWOLEVELBLOCK)
740 precond_str =
"TwoLevelBlockPreconditioner";
741 else if(_preconditioner == FROSchParameterList::ONELEVEL)
742 precond_str =
"OneLevelPreconditioner";
744 XASSERTM(
false,
"Unkown FROSchParameterList::Preconditioner type");
746 Teuchos::ParameterList *params =
new Teuchos::ParameterList(_name);
747 params->set(
"Preconditioner Type",
"FROSch");
748 params->set(
"Preconditioner Types", Teuchos::ParameterList(
"Preconditioner Types"));
749 params->sublist(
"Preconditioner Types").set(
"FROSch", Teuchos::ParameterList(
"FROSch"));
752 DirectSolver solver_ao, solver_ext;
754 IPOU ipou_velo, ipou_pres;
755 bool cspace_velo, cspace_pres, excl_velo_pres, excl_pres_velo;
756 bool rsf_ao, rsf_cm, reuse_cm, reuse_cb;
758 PartitionType partitype;
759 PartitionApproach partiapp;
761 CombineLevel combine_lvl;
765 Teuchos::ParameterList *tmp_params = &(params->sublist(
"Preconditioner Types").sublist(
"FROSch"));
766 for(
int i = 0; i < _nlevels; ++i)
768 overlap = _overlaps.size() == 1 ? _overlaps.at(0) : _overlaps.at(i);
769 solver_ao = _solvers_ao.size() == 1 ? _solvers_ao.at(0) : _solvers_ao.at(i);
770 solver_ext = _solvers_ext.size() == 1 ? _solvers_ext.at(0) : _solvers_ext.at(i);
771 mode = _combine_ov.size() == 1 ? _combine_ov.at(0) : _combine_ov.at(i);
772 combine_lvl = _combine_ov.size() == 1 ? _combine_lvl.at(0) : _combine_lvl.at(i);
773 ipou_velo = _ipous_velo.size() == 1 ? _ipous_velo.at(0) : _ipous_velo.at(i);
774 ipou_pres = _ipous_pres.size() == 1 ? _ipous_pres.at(0) : _ipous_pres.at(i);
775 cspace_velo = _cspace_velo.size() == 1 ? _cspace_velo.at(0) : _cspace_velo.at(i);
776 cspace_pres = _cspace_pres.size() == 1 ? _cspace_pres.at(0) : _cspace_pres.at(i);
777 excl_velo_pres = _exclude_velo_pres.size() == 1 ? _exclude_velo_pres.at(0) : _exclude_velo_pres.at(i);
778 excl_pres_velo = _exclude_pres_velo.size() == 1 ? _exclude_pres_velo.at(0) : _exclude_pres_velo.at(i);
779 partitype = _partition_types.size() == 1 ? _partition_types.at(0) : _partition_types.at(i);
780 partiapp = _partition_approach.size() == 1 ? _partition_approach.at(0) : _partition_approach.at(i);
781 partiimbl = _partition_imbl_tol.size() == 1 ? _partition_imbl_tol.at(0) : _partition_imbl_tol.at(i);
782 gsteps = _gsteps.size() == 1 ? _gsteps.at(0) : _gsteps.at(i);
783 rsf_ao = _ao_rsf.size() == 1 ? _ao_rsf.at(0) : _ao_rsf.at(i);
784 rsf_cm = _cm_rsf.size() == 1 ? _cm_rsf.at(0) : _cm_rsf.at(i);
785 reuse_cm = _cm_r.size() == 1 ? _cm_r.at(0) : _cm_r.at(i);
786 reuse_cb = _cb_r.size() == 1 ? _cb_r.at(0) : _cb_r.at(i);
787 phi_dt = _phi_dt.size() == 1 ? _phi_dt.at(0) : _phi_dt.at(i);
789 reuse = rsf_ao || rsf_cm || reuse_cb || reuse_cm;
792 parameterlist_header(_dimension, overlap, i+1, 1, _preconditioner, (i == 0 ?
"Input" :
"Laplace"), combine_lvl, reuse, verbose, *tmp_params);
793 parameterlist_set_aoo(solver_ao, *tmp_params);
794 parameterlist_combine_overlap(mode, tmp_params->sublist(
"AlgebraicOverlappingOperator"));
795 tmp_params->sublist(
"AlgebraicOverlappingOperator").set(
"Reuse: Symbolic Factorization", rsf_ao);
796 parameterlist_set_verbose(verbose, tmp_params->sublist(
"AlgebraicOverlappingOperator"));
798 tmp_params->set(
"IPOUHarmonicCoarseOperator", Teuchos::ParameterList(
"IPOUHarmonicCoarseOperator"));
799 tmp_params->sublist(
"IPOUHarmonicCoarseOperator").set(
"Blocks", Teuchos::ParameterList(
"Blocks"));
800 parameterlist_set_reuse_coarse(rsf_cm, reuse_cm, reuse_cb, tmp_params->sublist(
"IPOUHarmonicCoarseOperator"));
801 tmp_params->sublist(
"IPOUHarmonicCoarseOperator").set(
"Phi: Dropping Threshold", phi_dt);
802 parameterlist_set_verbose(verbose, tmp_params->sublist(
"IPOUHarmonicCoarseOperator"));
804 if(_problem == FROSchParameterList::PRESSUREPOISSON)
808 parameterlist_set_block(1,
true, -1, ipou_pres, _verbose, tmp_params->sublist(
"IPOUHarmonicCoarseOperator").sublist(
"Blocks"));
809 }
else if(_problem == FROSchParameterList::SADDLEPOINT)
812 parameterlist_set_block(1, cspace_velo, (excl_velo_pres ? 2 : -1), ipou_velo, _verbose, tmp_params->sublist(
"IPOUHarmonicCoarseOperator").sublist(
"Blocks"));
814 parameterlist_set_block(2, cspace_pres, (excl_pres_velo ? 1 : -1), ipou_pres, _verbose, tmp_params->sublist(
"IPOUHarmonicCoarseOperator").sublist(
"Blocks"));
817 XASSERTM(
false,
"Unkown FROSchParameterList::ProblemType type");
819 parameterlist_set_extsolv(solver_ext, tmp_params->sublist(
"IPOUHarmonicCoarseOperator"));
820 parameterlist_set_distribution(_subregions.at(i), partitype, partiapp, partiimbl, gsteps, tmp_params->sublist(
"IPOUHarmonicCoarseOperator"));
823 tmp_params->sublist(
"IPOUHarmonicCoarseOperator").set(
"CoarseSolver", Teuchos::ParameterList(
"CoarseSolver"));
828 tmp_params->sublist(
"IPOUHarmonicCoarseOperator").sublist(
"CoarseSolver").set(
"SolverType",
"FROSchPreconditioner");
829 tmp_params->sublist(
"IPOUHarmonicCoarseOperator").sublist(
"CoarseSolver").set(
"Solver", precond_str);
830 tmp_params->sublist(
"IPOUHarmonicCoarseOperator").sublist(
"CoarseSolver").set(
"FROSchPreconditioner", Teuchos::ParameterList(
"FROSchPreconditioner"));
831 tmp_params->sublist(
"IPOUHarmonicCoarseOperator").sublist(
"CoarseSolver").sublist(
"FROSchPreconditioner").set(precond_str, Teuchos::ParameterList(precond_str));
833 tmp_params = &(tmp_params->sublist(
"IPOUHarmonicCoarseOperator").sublist(
"CoarseSolver").sublist(
"FROSchPreconditioner").sublist(precond_str));
837 parameterlist_set_solver(_solver_coarse, tmp_params->sublist(
"IPOUHarmonicCoarseOperator").sublist(
"CoarseSolver"));
841 _core = (
void*) params;
850 void FROSchParameterList::delete_core()
857 delete reinterpret_cast<Teuchos::ParameterList*
>(_core);
861 int FROSchParameterList::get_dim()
const
866 int FROSchParameterList::get_dpe_velo()
const
871 int FROSchParameterList::get_dpe_pres()
const
876 int FROSchParameterList::get_nlevels()
const
881 bool FROSchParameterList::get_use_timer()
const
886 bool FROSchParameterList::get_print()
const
891 void FROSchParameterList::set_print(
const bool print_)
893 _print_list = print_;
896 void FROSchParameterList::set_use_timer(
const bool use_timer_)
898 _use_timer = use_timer_;
901 void FROSchParameterList::set_nlevels(
const int nlevels_)
906 void FROSchParameterList::set_dim(
const int dim_)
908 XASSERTM(dim_ == 2 || dim_ == 3,
"Only implemented for dim_ == 2 or dim_ == 3");
911 _dpe_pres = dim_ + 1;
914 void FROSchParameterList::set_problem_type(
const ProblemType problem_)
919 void FROSchParameterList::set_precond(
const Preconditioner precond_)
921 _preconditioner = precond_;
924 void FROSchParameterList::set_coarse_solver(
const DirectSolver solver_)
926 _solver_coarse = solver_;
929 void FROSchParameterList::set_gsteps(
const int gsteps_)
931 _gsteps.assign(_nlevels, gsteps_);
934 void FROSchParameterList::set_gsteps(
const std::vector<int>& gsteps_)
936 XASSERT(
int(gsteps_.size()) == _nlevels);
937 _gsteps.assign(gsteps_.begin(), gsteps_.end());
940 void FROSchParameterList::set_overlaps(
const int overlap_)
942 _overlaps.assign(_nlevels, overlap_);
945 void FROSchParameterList::set_overlaps(
const std::vector<int>& overlaps_)
947 XASSERT(
int(overlaps_.size()) == _nlevels);
948 _overlaps.assign(overlaps_.begin(), overlaps_.end());
951 void FROSchParameterList::set_combine_overlap(
const CombineOverlap combine_mode_)
953 _combine_ov.assign(_nlevels, combine_mode_);
956 void FROSchParameterList::set_combine_overlap(
const std::vector<CombineOverlap>& combine_mode_)
958 XASSERT(
int(combine_mode_.size()) == _nlevels);
959 _combine_ov.assign(combine_mode_.begin(), combine_mode_.end());
962 void FROSchParameterList::set_combine_lvl(
const CombineLevel combine_lvl_)
964 _combine_lvl.assign(_nlevels, combine_lvl_);
967 void FROSchParameterList::set_combine_lvl(
const std::vector<CombineLevel>& combine_lvl_)
969 XASSERT(
int(_combine_lvl.size()) == _nlevels);
970 _combine_lvl.assign(combine_lvl_.begin(), combine_lvl_.end());
973 void FROSchParameterList::set_solvers(
const DirectSolver solver_ao_,
const DirectSolver solver_ext_)
975 set_solvers_ao(solver_ao_);
976 set_solvers_ext(solver_ext_);
979 void FROSchParameterList::set_solvers(
const std::vector<DirectSolver>& solver_ao_,
const std::vector<DirectSolver>& solver_ext_)
981 set_solvers_ao(solver_ao_);
982 set_solvers_ext(solver_ext_);
985 void FROSchParameterList::set_solvers_ao(
const DirectSolver solver_)
987 _solvers_ao.assign(_nlevels, solver_);
990 void FROSchParameterList::set_solvers_ao(
const std::vector<DirectSolver>& solvers_)
992 XASSERT(
int(solvers_.size()) == _nlevels);
993 _solvers_ao.assign(solvers_.begin(), solvers_.end());
996 void FROSchParameterList::set_solvers_ext(
const DirectSolver solver_)
998 _solvers_ext.assign(_nlevels, solver_);
1001 void FROSchParameterList::set_solvers_ext(
const std::vector<DirectSolver>& solvers_)
1003 XASSERT(
int(solvers_.size()) == _nlevels);
1004 _solvers_ext.assign(solvers_.begin(), solvers_.end());
1007 void FROSchParameterList::set_paritioner(
const std::vector<int>& subregions_,
const PartitionType parti_type_,
const PartitionApproach parti_approach_,
const double parti_imbl_)
1009 set_subregions(subregions_);
1010 set_parti_types(parti_type_);
1011 set_parti_approach(parti_approach_);
1012 set_parti_imbl(parti_imbl_);
1015 void FROSchParameterList::set_paritioner(
const std::vector<int>& subregions_,
const std::vector<PartitionType>& parti_types_,
const std::vector<PartitionApproach>& parti_approach_,
const std::vector<double>& parti_imbl_)
1017 set_subregions(subregions_);
1018 set_parti_types(parti_types_);
1019 set_parti_approach(parti_approach_);
1020 set_parti_imbl(parti_imbl_);
1023 void FROSchParameterList::set_subregions(
const std::vector<int>& subregions_)
1025 XASSERT(
int(subregions_.size()) == _nlevels);
1026 XASSERTM(
int(subregions_.back()) ==
int(1),
"Last entry has to be one.");
1027 _subregions.assign(subregions_.begin(), subregions_.end());
1030 void FROSchParameterList::set_parti_types(
const PartitionType parti_type_)
1032 _partition_types.assign(_nlevels, parti_type_);
1035 void FROSchParameterList::set_parti_types(
const std::vector<PartitionType>& parti_types_)
1037 XASSERT(
int(parti_types_.size()) == _nlevels);
1038 _partition_types.assign(parti_types_.begin(), parti_types_.end());
1041 void FROSchParameterList::set_parti_approach(
const PartitionApproach parti_approach_)
1043 _partition_approach.assign(_nlevels, parti_approach_);
1046 void FROSchParameterList::set_parti_approach(
const std::vector<PartitionApproach>& parti_approach_)
1048 XASSERT(
int(parti_approach_.size()) == _nlevels);
1049 _partition_approach.assign(parti_approach_.begin(), parti_approach_.end());
1052 void FROSchParameterList::set_parti_imbl(
const double parti_imbl_)
1054 _partition_imbl_tol.assign(_nlevels, parti_imbl_);
1057 void FROSchParameterList::set_parti_imbl(
const std::vector<double>& parti_imbl_)
1059 XASSERT(
int(parti_imbl_.size()) == _nlevels);
1060 _partition_imbl_tol.assign(parti_imbl_.begin(), parti_imbl_.end());
1063 void FROSchParameterList::set_excludes(
const bool velo_pres_,
const bool pres_velo_)
1065 _exclude_velo_pres.assign(_nlevels, velo_pres_);
1066 _exclude_pres_velo.assign(_nlevels, pres_velo_);
1069 void FROSchParameterList::set_excludes(
const std::vector<bool>& velo_pres_,
const std::vector<bool>& pres_velo_)
1071 XASSERT(
int(velo_pres_.size()) == _nlevels);
1072 XASSERT(
int(pres_velo_.size()) == _nlevels);
1073 _exclude_velo_pres.assign(velo_pres_.begin(), velo_pres_.end());
1074 _exclude_pres_velo.assign(pres_velo_.begin(), pres_velo_.end());
1077 void FROSchParameterList::set_excludes_velo_pres(
const bool velo_pres_)
1079 _exclude_velo_pres.assign(_nlevels, velo_pres_);
1082 void FROSchParameterList::set_excludes_velo_pres(
const std::vector<bool>& velo_pres_)
1084 XASSERT(
int(velo_pres_.size()) == _nlevels);
1085 _exclude_velo_pres.assign(velo_pres_.begin(), velo_pres_.end());
1088 void FROSchParameterList::set_excludes_pres_velo(
const bool pres_velo_)
1090 _exclude_pres_velo.assign(_nlevels, pres_velo_);
1093 void FROSchParameterList::set_excludes_pres_velo(
const std::vector<bool>& pres_velo_)
1095 XASSERT(
int(pres_velo_.size()) == _nlevels);
1096 _exclude_pres_velo.assign(pres_velo_.begin(), pres_velo_.end());
1099 void FROSchParameterList::set_ipous(
const IPOU ipou_velo_,
const IPOU ipou_pres_)
1101 set_ipous_velo(ipou_velo_);
1102 set_ipous_pres(ipou_pres_);
1105 void FROSchParameterList::set_ipous(
const std::vector<IPOU>& ipous_velo_,
const std::vector<IPOU>& ipous_pres_)
1107 set_ipous_velo(ipous_velo_);
1108 set_ipous_pres(ipous_pres_);
1111 void FROSchParameterList::set_ipous_velo(
const IPOU ipou_)
1113 _ipous_velo.assign(_nlevels, ipou_);
1116 void FROSchParameterList::set_ipous_velo(
const std::vector<IPOU>& ipous_)
1118 XASSERT(
int(ipous_.size()) == _nlevels);
1119 _ipous_velo.assign(ipous_.begin(), ipous_.end());
1122 void FROSchParameterList::set_ipous_pres(
const IPOU ipou_)
1124 _ipous_pres.assign(_nlevels, ipou_);
1127 void FROSchParameterList::set_ipous_pres(
const std::vector<IPOU>& ipous_)
1129 XASSERT(
int(ipous_.size()) == _nlevels);
1130 _ipous_pres.assign(ipous_.begin(), ipous_.end());
1133 void FROSchParameterList::set_cspace(
const bool cspace_velo_,
const bool cspace_pres_)
1135 set_cspace_velo(cspace_velo_);
1136 set_cspace_pres(cspace_pres_);
1139 void FROSchParameterList::set_cspace(
const std::vector<bool>& cspace_velo_,
const std::vector<bool>& cspace_pres_)
1141 set_cspace_velo(cspace_velo_);
1142 set_cspace_pres(cspace_pres_);
1145 void FROSchParameterList::set_cspace_velo(
const bool cspace_)
1147 _cspace_velo.assign(_nlevels, cspace_);
1150 void FROSchParameterList::set_cspace_velo(
const std::vector<bool>& cspace_)
1152 XASSERT(
int(cspace_.size()) == _nlevels);
1153 _cspace_velo.assign(cspace_.begin(), cspace_.end());
1156 void FROSchParameterList::set_cspace_pres(
const bool cspace_)
1158 _cspace_pres.assign(_nlevels, cspace_);
1161 void FROSchParameterList::set_cspace_pres(
const std::vector<bool>& cspace_)
1163 XASSERT(
int(cspace_.size()) == _nlevels);
1164 _cspace_pres.assign(cspace_.begin(), cspace_.end());
1167 void FROSchParameterList::set_reuse_sf(
const bool rsf_ao_,
const bool rsf_cm_)
1169 set_reuse_sf_ao(rsf_ao_);
1170 set_reuse_sf_cm(rsf_cm_);
1173 void FROSchParameterList::set_reuse_sf(
const std::vector<bool> &rsf_ao_,
const std::vector<bool> &rsf_cm_)
1175 set_reuse_sf_ao(rsf_ao_);
1176 set_reuse_sf_cm(rsf_cm_);
1179 void FROSchParameterList::set_reuse_sf_ao(
const bool rsf_ao_)
1181 _ao_rsf.assign(_nlevels, rsf_ao_);
1184 void FROSchParameterList::set_reuse_sf_ao(
const std::vector<bool> &rsf_ao_)
1186 XASSERT(
int(rsf_ao_.size()) == _nlevels);
1187 _ao_rsf.assign(rsf_ao_.begin(), rsf_ao_.end());
1190 void FROSchParameterList::set_reuse_sf_cm(
const bool rsf_cm_)
1192 _cm_rsf.assign(_nlevels, rsf_cm_);
1195 void FROSchParameterList::set_reuse_sf_cm(
const std::vector<bool> &rsf_cm_)
1197 XASSERT(
int(rsf_cm_.size()) == _nlevels);
1198 _cm_rsf.assign(rsf_cm_.begin(), rsf_cm_.end());
1201 void FROSchParameterList::set_reuse_coarse(
const bool reuse_cm_,
const bool reuse_cb_)
1203 set_reuse_coarse_matrix(reuse_cm_);
1204 set_reuse_coarse_basis(reuse_cb_);
1207 void FROSchParameterList::set_reuse_coarse(
const std::vector<bool> &reuse_cm_,
const std::vector<bool> &reuse_cb_)
1209 set_reuse_coarse_matrix(reuse_cm_);
1210 set_reuse_coarse_basis(reuse_cb_);
1213 void FROSchParameterList::set_reuse_coarse_matrix(
const bool reuse_cm_)
1215 _cm_r.assign(_nlevels, reuse_cm_);
1218 void FROSchParameterList::set_reuse_coarse_matrix(
const std::vector<bool> &reuse_cm_)
1220 XASSERT(
int(reuse_cm_.size()) == _nlevels);
1221 _cm_r.assign(reuse_cm_.begin(), reuse_cm_.end());
1224 void FROSchParameterList::set_reuse_coarse_basis(
const bool rsf_cm_)
1226 _cb_r.assign(_nlevels, rsf_cm_);
1229 void FROSchParameterList::set_reuse_coarse_basis(
const std::vector<bool> &reuse_cb_)
1231 XASSERT(
int(reuse_cb_.size()) == _nlevels);
1232 _cb_r.assign(reuse_cb_.begin(), reuse_cb_.end());
1235 void FROSchParameterList::set_phi_dropping_threshold(
const double phi_dt_)
1237 _phi_dt.assign(_nlevels, phi_dt_);
1240 void FROSchParameterList::set_phi_dropping_threshold(
const std::vector<double> &phi_dt_)
1242 XASSERT(
int(phi_dt_.size()) == _nlevels);
1243 _phi_dt.assign(phi_dt_.begin(), phi_dt_.end());
1246 void FROSchParameterList::set_verbose(
const bool verbose_)
1248 _verbose = verbose_;
1251 inline bool parse_fpl_levels(
const Dist::Comm &comm, SimpleArgParser &args, FROSchParameterList ¶ms)
1253 auto it = args.query(
"frosch-nlevels");
1256 if(it->second.size() == 1)
1258 int nlevels = std::stoi(it->second.front());
1261 comm.print(
"ERROR: given number of levels is smaller then 1");
1263 params.set_nlevels(nlevels);
1266 comm.print(
"ERROR: multiple levels given");
1273 inline bool parse_fpl_dim(
const Dist::Comm& comm, SimpleArgParser& args, FROSchParameterList ¶ms)
1275 auto it = args.query(
"frosch-dim");
1278 if(it->second.size() == 1)
1280 int dim = std::stoi(it->second.front());
1281 if(dim != 2 && dim != 3)
1283 comm.print(
"ERROR: given dimension has to be 2 or 3");
1285 params.set_dim(dim);
1288 comm.print(
"ERROR: multiple dimensions given");
1296 inline bool parse_fpl_overlaps(
const Dist::Comm& comm, SimpleArgParser& args, FROSchParameterList ¶ms)
1298 auto it = args.query(
"frosch-overlap");
1301 if(it->second.size() == 1u)
1303 auto ov = std::stoi(it->second.front());
1306 comm.print(
"ERROR: overlap is smaller than 0");
1309 params.set_overlaps((
int)ov);
1310 }
else if(
int(it->second.size()) == params.get_nlevels())
1312 std::vector<int> overlaps;
1313 overlaps.reserve(params.get_nlevels());
1314 for(
const auto& t : it->second)
1316 auto ov = std::stoi(t);
1319 comm.print(
"ERROR: overlap is smaller than 0");
1322 overlaps.push_back(ov);
1324 params.set_overlaps(overlaps);
1327 comm.print(
"ERROR: not matching number of overlaps: nlevels: " + std::to_string(params.get_nlevels()) +
" number of given overlaps: " + std::to_string(it->second.size()) +
"'");
1334 inline bool parse_fpl_subreg(
const Dist::Comm& comm, SimpleArgParser& args, FROSchParameterList ¶ms)
1336 auto it = args.query(
"frosch-subreg");
1339 if(
int(it->second.size()) == params.get_nlevels())
1341 std::vector<int> subreg;
1342 subreg.reserve(params.get_nlevels());
1343 for(
const auto& t : it->second)
1345 auto sr = std::stoi(t);
1349 comm.print(
"ERROR: subreg is smaller than 0");
1352 subreg.push_back(sr);
1354 if(subreg.back() != 1)
1356 comm.print(
"ERROR: last entry of subreg is not 1: " + std::to_string(subreg.back()));
1358 params.set_subregions(subreg);
1361 comm.print(
"ERROR: not matching number of subregions: nlevels: " + std::to_string(params.get_nlevels()) +
" number of given subregions: " + std::to_string(it->second.size()) +
"'");
1368 inline bool parse_fpl_gsteps(
const Dist::Comm& comm, SimpleArgParser& args, FROSchParameterList ¶ms)
1370 auto it = args.query(
"frosch-gstep");
1373 if(it->second.size() == 1u)
1375 auto gsteps = std::stoi(it->second.front());
1378 comm.print(
"ERROR: gstep is smaller than 1");
1381 params.set_gsteps((
int)gsteps);
1382 }
else if(
int(it->second.size()) == params.get_nlevels())
1384 std::vector<int> gsteps;
1385 gsteps.reserve(params.get_nlevels());
1386 for(
const auto& t : it->second)
1388 auto gs = std::stoi(t);
1391 comm.print(
"ERROR: gstep is smaller than 0");
1394 gsteps.push_back(gs);
1396 params.set_gsteps(gsteps);
1399 comm.print(
"ERROR: not matching number of gsteps: nlevels: " + std::to_string(params.get_nlevels()) +
" number of given gsteps: " + std::to_string(it->second.size()) +
"'");
1406 inline bool parse_fpl_parti_type(
const Dist::Comm& comm, SimpleArgParser& args, FROSchParameterList ¶ms)
1408 auto it = args.query(
"frosch-parti-type");
1411 if(it->second.size() == 1u)
1413 FROSchParameterList::PartitionType parti_type;
1414 std::string type = it->second.front();
1415 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
1417 if(!type.compare(
"parmetis"))
1419 parti_type = Solver::Trilinos::FROSchParameterList::PARMETIS;
1420 }
else if(!type.compare(
"scotch"))
1422 parti_type = Solver::Trilinos::FROSchParameterList::SCOTCH;
1423 }
else if(!type.compare(
"ptscotch"))
1425 parti_type = Solver::Trilinos::FROSchParameterList::PTSCOTCH;
1426 }
else if(!type.compare(
"block"))
1428 parti_type = Solver::Trilinos::FROSchParameterList::BLOCK;
1429 }
else if(!type.compare(
"phg"))
1431 parti_type = Solver::Trilinos::FROSchParameterList::PHG;
1434 comm.print(
"ERROR: unknown partitioner type '" + it->second.front() +
"'");
1437 params.set_parti_types(parti_type);
1438 }
else if(
int(it->second.size()) == params.get_nlevels())
1440 std::vector<FROSchParameterList::PartitionType> parti_types;
1441 parti_types.reserve(params.get_nlevels());
1442 for(
const auto& t : it->second)
1444 std::string type = t;
1445 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
1447 if(!type.compare(
"parmetis"))
1449 parti_types.push_back(Solver::Trilinos::FROSchParameterList::PARMETIS);
1450 }
else if(!type.compare(
"scotch"))
1452 parti_types.push_back(Solver::Trilinos::FROSchParameterList::SCOTCH);
1453 }
else if(!type.compare(
"ptscotch"))
1455 parti_types.push_back(Solver::Trilinos::FROSchParameterList::PTSCOTCH);
1456 }
else if(!type.compare(
"block"))
1458 parti_types.push_back(Solver::Trilinos::FROSchParameterList::BLOCK);
1459 }
else if(!type.compare(
"phg"))
1461 parti_types.push_back(Solver::Trilinos::FROSchParameterList::PHG);
1464 comm.print(
"ERROR: unknown partitioner type '" + t +
"'");
1468 params.set_parti_types(parti_types);
1471 comm.print(
"ERROR: not matching number of parti-type: nlevels: " + std::to_string(params.get_nlevels()) +
" number of given parti-type: " + std::to_string(it->second.size()) +
"'");
1478 inline bool parse_fpl_parti_approach(
const Dist::Comm& comm, SimpleArgParser& args, FROSchParameterList ¶ms)
1480 auto it = args.query(
"frosch-parti-approach");
1483 if(it->second.size() == 1u)
1485 FROSchParameterList::PartitionApproach parti_app;
1486 std::string type = it->second.front();
1487 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
1489 if(!type.compare(
"partition"))
1491 parti_app = FROSchParameterList::PARTITION;
1492 }
else if(!type.compare(
"repartition"))
1494 parti_app = FROSchParameterList::REPARTITION;
1497 comm.print(
"ERROR: unknown partitioner approach '" + it->second.front() +
"'");
1500 params.set_parti_approach(parti_app);
1501 }
else if(
int(it->second.size()) == params.get_nlevels())
1503 std::vector<FROSchParameterList::PartitionApproach> parti_apps;
1504 parti_apps.reserve(params.get_nlevels());
1505 for(
const auto& t : it->second)
1507 std::string type = t;
1508 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
1510 if(!type.compare(
"partition"))
1512 parti_apps.push_back(FROSchParameterList::PARTITION);
1513 }
else if(!type.compare(
"repartitionblock"))
1515 parti_apps.push_back(FROSchParameterList::REPARTITION);
1518 comm.print(
"ERROR: unknown partitioner approach '" + t +
"'");
1522 params.set_parti_approach(parti_apps);
1525 comm.print(
"ERROR: not matching number of parti-approach: nlevels: " + std::to_string(params.get_nlevels()) +
" number of given parti-approach: " + std::to_string(it->second.size()) +
"'");
1532 inline bool parse_fpl_parti_imbl(
const Dist::Comm& comm, SimpleArgParser& args, FROSchParameterList ¶ms)
1534 auto it = args.query(
"frosch-parti-imbl");
1537 if(it->second.size() == 1u)
1539 double parti_imbl = std::stod(it->second.front());
1543 comm.print(
"ERROR: unknown partition imblance smaller than 1.: '" + it->second.front() +
"'");
1546 params.set_parti_imbl(parti_imbl);
1547 }
else if(
int(it->second.size()) == params.get_nlevels())
1549 std::vector<double> parti_imbl;
1550 parti_imbl.reserve(params.get_nlevels());
1551 for(
const auto& t : it->second)
1553 double imbl = std::stod(t);
1557 comm.print(
"ERROR: unknown partition imblance smaller than 1.: '" + t +
"'");
1560 parti_imbl.push_back(imbl);
1562 params.set_parti_imbl(parti_imbl);
1565 comm.print(
"ERROR: not matching number of parti-imbl: nlevels: " + std::to_string(params.get_nlevels()) +
" number of given parti-imbl: " + std::to_string(it->second.size()) +
"'");
1572 inline bool parse_fpl_ipou_pres(
const Dist::Comm& comm, SimpleArgParser& args, FROSchParameterList ¶ms)
1574 auto it = args.query(
"frosch-ipou-pres");
1577 if(it->second.size() == 1u)
1579 FROSchParameterList::IPOU ipou;
1580 std::string type = it->second.front();
1581 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
1583 if(!type.compare(
"gdsw"))
1585 ipou = FROSchParameterList::GDSW;
1586 }
else if(!type.compare(
"gdswstar"))
1588 ipou = FROSchParameterList::GDSWSTAR;
1589 }
else if(!type.compare(
"rgdsw"))
1591 ipou = FROSchParameterList::RGDSW;
1594 comm.print(
"ERROR: unknown ipou pressure type '" + it->second.front() +
"'");
1597 params.set_ipous_pres(ipou);
1598 }
else if(
int(it->second.size()) == params.get_nlevels())
1600 std::vector<FROSchParameterList::IPOU> ipous;
1601 ipous.reserve(params.get_nlevels());
1602 for(
const auto& t : it->second)
1604 std::string type = t;
1605 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
1607 if(!type.compare(
"gdsw"))
1609 ipous.push_back(FROSchParameterList::GDSW);
1610 }
else if(!type.compare(
"gdswstar"))
1612 ipous.push_back(FROSchParameterList::GDSWSTAR);
1613 }
else if(!type.compare(
"rgdsw"))
1615 ipous.push_back(FROSchParameterList::RGDSW);
1618 comm.print(
"ERROR: unknown ipou pressure type '" + t +
"'");
1622 params.set_ipous_pres(ipous);
1625 comm.print(
"ERROR: not matching number of ipou-pres: nlevels: " + std::to_string(params.get_nlevels()) +
" number of given ipou-pres: " + std::to_string(it->second.size()) +
"'");
1632 inline bool parse_fpl_ipou_velo(
const Dist::Comm& comm, SimpleArgParser& args, FROSchParameterList ¶ms)
1634 auto it = args.query(
"frosch-ipou-velo");
1637 if(it->second.size() == 1u)
1639 FROSchParameterList::IPOU ipou;
1640 std::string type = it->second.front();
1641 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
1643 if(!type.compare(
"gdsw"))
1645 ipou = FROSchParameterList::GDSW;
1646 }
else if(!type.compare(
"gdswstar"))
1648 ipou = FROSchParameterList::GDSWSTAR;
1649 }
else if(!type.compare(
"rgdsw"))
1651 ipou = FROSchParameterList::RGDSW;
1654 comm.print(
"ERROR: unknown ipou velocity type '" + it->second.front() +
"'");
1657 params.set_ipous_velo(ipou);
1658 }
else if(
int(it->second.size()) == params.get_nlevels())
1660 std::vector<FROSchParameterList::IPOU> ipous;
1661 ipous.reserve(params.get_nlevels());
1662 for(
const auto& t : it->second)
1664 std::string type = t;
1665 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
1667 if(!type.compare(
"gdsw"))
1669 ipous.push_back(FROSchParameterList::GDSW);
1670 }
else if(!type.compare(
"gdswstar"))
1672 ipous.push_back(FROSchParameterList::GDSWSTAR);
1673 }
else if(!type.compare(
"rgdsw"))
1675 ipous.push_back(FROSchParameterList::RGDSW);
1678 comm.print(
"ERROR: unknown ipou velo type '" + t +
"'");
1682 params.set_ipous_pres(ipous);
1685 comm.print(
"ERROR: not matching number of ipou-velo: nlevels: " + std::to_string(params.get_nlevels()) +
" number of given ipou-velo: " + std::to_string(it->second.size()) +
"'");
1692 inline bool parse_fpl_solver_ao(
const Dist::Comm& comm, SimpleArgParser& args, FROSchParameterList ¶ms)
1694 auto it = args.query(
"frosch-solver-ao");
1697 if(it->second.size() == 1u)
1699 FROSchParameterList::DirectSolver solver;
1700 std::string type = it->second.front();
1701 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
1703 if(!type.compare(
"klu"))
1705 solver = FROSchParameterList::KLU;
1706 }
else if(!type.compare(
"mumps"))
1708 solver = FROSchParameterList::MUMPS;
1709 }
else if(!type.compare(
"umfpack"))
1711 solver = FROSchParameterList::UMFPACK;
1714 comm.print(
"ERROR: unknown solver-ao type '" + it->second.front() +
"'");
1717 params.set_solvers_ao(solver);
1718 }
else if(
int(it->second.size()) == params.get_nlevels())
1720 std::vector<FROSchParameterList::DirectSolver> solvers;
1721 solvers.reserve(params.get_nlevels());
1722 for(
const auto& t : it->second)
1724 std::string type = t;
1725 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
1727 if(!type.compare(
"klu"))
1729 solvers.push_back(FROSchParameterList::KLU);
1730 }
else if(!type.compare(
"mumps"))
1732 solvers.push_back(FROSchParameterList::MUMPS);
1733 }
else if(!type.compare(
"umfpack"))
1735 solvers.push_back(FROSchParameterList::UMFPACK);
1738 comm.print(
"ERROR: unknown solver-ao type '" + t +
"'");
1742 params.set_solvers_ao(solvers);
1745 comm.print(
"ERROR: not matching number of solver-ao: nlevels: " + std::to_string(params.get_nlevels()) +
" number of given solver-ao: " + std::to_string(it->second.size()) +
"'");
1752 inline bool parse_fpl_solver_ext(
const Dist::Comm& comm, SimpleArgParser& args, FROSchParameterList ¶ms)
1754 auto it = args.query(
"frosch-solver-ext");
1757 if(it->second.size() == 1u)
1759 FROSchParameterList::DirectSolver solver;
1760 std::string type = it->second.front();
1761 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
1763 if(!type.compare(
"klu"))
1765 solver = FROSchParameterList::KLU;
1766 }
else if(!type.compare(
"mumps"))
1768 solver = FROSchParameterList::MUMPS;
1769 }
else if(!type.compare(
"umfpack"))
1771 solver = FROSchParameterList::UMFPACK;
1774 comm.print(
"ERROR: unknown solver-ext type '" + it->second.front() +
"'");
1777 params.set_solvers_ext(solver);
1778 }
else if(
int(it->second.size()) == params.get_nlevels())
1780 std::vector<FROSchParameterList::DirectSolver> solvers;
1781 solvers.reserve(params.get_nlevels());
1782 for(
const auto& t : it->second)
1784 std::string type = t;
1785 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
1787 if(!type.compare(
"klu"))
1789 solvers.push_back(FROSchParameterList::KLU);
1790 }
else if(!type.compare(
"mumps"))
1792 solvers.push_back(FROSchParameterList::MUMPS);
1793 }
else if(!type.compare(
"umfpack"))
1795 solvers.push_back(FROSchParameterList::UMFPACK);
1798 comm.print(
"ERROR: unknown solver-ext type '" + t +
"'");
1802 params.set_solvers_ext(solvers);
1805 comm.print(
"ERROR: not matching number of solver-ext: nlevels: " + std::to_string(params.get_nlevels()) +
" number of given solver-ext: " + std::to_string(it->second.size()) +
"'");
1812 inline bool parse_fpl_solver_coarse(
const Dist::Comm& comm, SimpleArgParser& args, FROSchParameterList ¶ms)
1814 auto it = args.query(
"frosch-solver-coarse");
1817 if(it->second.size() == 1u)
1819 FROSchParameterList::DirectSolver solver;
1820 std::string type = it->second.front();
1821 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
1823 if(!type.compare(
"klu"))
1825 solver = FROSchParameterList::KLU;
1826 }
else if(!type.compare(
"mumps"))
1828 solver = FROSchParameterList::MUMPS;
1829 }
else if(!type.compare(
"umfpack"))
1831 solver = FROSchParameterList::UMFPACK;
1834 comm.print(
"ERROR: unknown solver-coarse type '" + it->second.front() +
"'");
1837 params.set_coarse_solver(solver);
1840 comm.print(
"ERROR: multiple coarse solvers are given");
1847 inline bool parse_fpl_precond(
const Dist::Comm& comm, SimpleArgParser& args, FROSchParameterList ¶ms)
1849 auto it = args.query(
"frosch-precond-type");
1852 if(it->second.size() == 1u)
1854 FROSchParameterList::Preconditioner precond;
1855 std::string type = it->second.front();
1856 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
1858 if(!type.compare(
"twolevel"))
1860 precond = FROSchParameterList::TWOLEVEL;
1861 }
else if(!type.compare(
"twolevelblock"))
1863 precond = FROSchParameterList::TWOLEVELBLOCK;
1864 }
else if(!type.compare(
"onelevel"))
1866 precond = FROSchParameterList::ONELEVEL;
1869 comm.print(
"ERROR: unknown precond-type '" + it->second.front() +
"'");
1872 params.set_precond(precond);
1875 comm.print(
"ERROR: multiple preconditioner types are given");
1882 inline bool parse_fpl_cspace_pres(
const Dist::Comm& comm, SimpleArgParser& args, FROSchParameterList ¶ms)
1884 auto it = args.query(
"frosch-cspace-pres");
1887 if(it->second.size() == 1u)
1890 std::string type = it->second.front();
1891 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
1893 if(!type.compare(
"true"))
1896 }
else if(!type.compare(
"false"))
1901 comm.print(
"ERROR: unknown cspace-pres type '" + it->second.front() +
"'");
1904 params.set_cspace_pres(cspace);
1905 }
else if(
int(it->second.size()) == params.get_nlevels())
1907 std::vector<bool> cspaces;
1908 cspaces.reserve(params.get_nlevels());
1909 for(
const auto& t : it->second)
1911 std::string type = t;
1912 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
1914 if(!type.compare(
"true"))
1916 cspaces.push_back(
true);
1917 }
else if(!type.compare(
"false"))
1919 cspaces.push_back(
false);
1922 comm.print(
"ERROR: unknown cspace-pres type '" + t +
"'");
1926 params.set_cspace_pres(cspaces);
1929 comm.print(
"ERROR: not matching number of cspace-pres: nlevels: " + std::to_string(params.get_nlevels()) +
" number of given cspace-pres: " + std::to_string(it->second.size()) +
"'");
1936 inline bool parse_fpl_cspace_velo(
const Dist::Comm& comm, SimpleArgParser& args, FROSchParameterList ¶ms)
1938 auto it = args.query(
"frosch-cspace-velo");
1941 if(it->second.size() == 1u)
1944 std::string type = it->second.front();
1945 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
1947 if(!type.compare(
"true"))
1950 }
else if(!type.compare(
"false"))
1955 comm.print(
"ERROR: unknown cspace-velo type '" + it->second.front() +
"'");
1958 params.set_cspace_velo(cspace);
1959 }
else if(
int(it->second.size()) == params.get_nlevels())
1961 std::vector<bool> cspaces;
1962 cspaces.reserve(params.get_nlevels());
1963 for(
const auto& t : it->second)
1965 std::string type = t;
1966 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
1968 if(!type.compare(
"true"))
1970 cspaces.push_back(
true);
1971 }
else if(!type.compare(
"false"))
1973 cspaces.push_back(
false);
1976 comm.print(
"ERROR: unknown cspace-velo type '" + t +
"'");
1980 params.set_cspace_velo(cspaces);
1983 comm.print(
"ERROR: not matching number of cspace-velo: nlevels: " + std::to_string(params.get_nlevels()) +
" number of given cspace-velo: " + std::to_string(it->second.size()) +
"'");
1990 inline bool parse_fpl_exclude_velo_pres(
const Dist::Comm& comm, SimpleArgParser& args, FROSchParameterList ¶ms)
1992 auto it = args.query(
"frosch-exclude-velo-pres");
1995 if(it->second.size() == 1u)
1998 std::string type = it->second.front();
1999 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
2001 if(!type.compare(
"true"))
2004 }
else if(!type.compare(
"false"))
2009 comm.print(
"ERROR: unknown exclude-velo-pres type '" + it->second.front() +
"'");
2012 params.set_excludes_velo_pres(excl);
2013 }
else if(
int(it->second.size()) == params.get_nlevels())
2015 std::vector<bool> excl;
2016 excl.reserve(params.get_nlevels());
2017 for(
const auto& t : it->second)
2019 std::string type = t;
2020 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
2022 if(!type.compare(
"true"))
2024 excl.push_back(
true);
2025 }
else if(!type.compare(
"false"))
2027 excl.push_back(
false);
2030 comm.print(
"ERROR: unknown exclude-velo-pres type '" + t +
"'");
2034 params.set_excludes_velo_pres(excl);
2037 comm.print(
"ERROR: not matching number of exclude-velo-pres: nlevels: " + std::to_string(params.get_nlevels()) +
" number of given exclude-velo-pres: " + std::to_string(it->second.size()) +
"'");
2044 inline bool parse_fpl_exclude_pres_velo(
const Dist::Comm& comm, SimpleArgParser& args, FROSchParameterList ¶ms)
2046 auto it = args.query(
"frosch-exclude-pres-velo");
2049 if(it->second.size() == 1u)
2052 std::string type = it->second.front();
2053 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
2055 if(!type.compare(
"true"))
2058 }
else if(!type.compare(
"false"))
2063 comm.print(
"ERROR: unknown exclude-velo-pres type '" + it->second.front() +
"'");
2066 params.set_excludes_pres_velo(excl);
2067 }
else if(
int(it->second.size()) == params.get_nlevels())
2069 std::vector<bool> excl;
2070 excl.reserve(params.get_nlevels());
2071 for(
const auto& t : it->second)
2073 std::string type = t;
2074 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
2076 if(!type.compare(
"true"))
2078 excl.push_back(
true);
2079 }
else if(!type.compare(
"false"))
2081 excl.push_back(
false);
2084 comm.print(
"ERROR: unknown exclude-pres-velo type '" + t +
"'");
2088 params.set_excludes_pres_velo(excl);
2091 comm.print(
"ERROR: not matching number of exclude-pres-velo: nlevels: " + std::to_string(params.get_nlevels()) +
" number of given exclude-pres-velo: " + std::to_string(it->second.size()) +
"'");
2098 inline bool parse_fpl_print(
const Dist::Comm& comm, SimpleArgParser& args, FROSchParameterList ¶ms)
2100 auto it = args.query(
"frosch-print-list");
2103 if(it->second.size() == 1u)
2106 std::string type = it->second.front();
2107 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
2108 if(!type.compare(
"true"))
2111 }
else if(!type.compare(
"false"))
2116 comm.print(
"ERROR: unknown print-list '" + it->second.front() +
"'");
2119 params.set_print(print);
2122 comm.print(
"ERROR: more than one print-list arg given: number of args: " + std::to_string(it->second.size()) +
"'");
2129 inline bool parse_fpl_verbose(
const Dist::Comm& comm, SimpleArgParser& args, FROSchParameterList ¶ms)
2131 auto it = args.query(
"frosch-verbose");
2134 if(it->second.size() == 1)
2137 std::string type = it->second.front();
2138 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
2139 if(!type.compare(
"true"))
2142 }
else if(!type.compare(
"false"))
2147 comm.print(
"ERROR: unknown verbose '" + it->second.front() +
"'");
2150 params.set_verbose(verbose);
2153 comm.print(
"ERROR: more than one verbose arg given: number of args: " + std::to_string(it->second.size()) +
"'");
2160 inline bool parse_fpl_timer(
const Dist::Comm& comm, SimpleArgParser& args, FROSchParameterList ¶ms)
2162 auto it = args.query(
"frosch-use-timer");
2165 if(it->second.size() == 1u)
2168 std::string type = it->second.front();
2169 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
2171 if(!type.compare(
"true"))
2174 }
else if(!type.compare(
"false"))
2179 comm.print(
"ERROR: unknown use-timer '" + it->second.front() +
"'");
2182 params.set_use_timer(timer);
2185 comm.print(
"ERROR: more than one use-timer arg given: number of args: " + std::to_string(it->second.size()) +
"'");
2192 inline bool parse_fpl_combine(
const Dist::Comm& comm, SimpleArgParser& args, FROSchParameterList ¶ms)
2194 auto it = args.query(
"frosch-combine-overlap");
2197 if(it->second.size() == 1u)
2199 FROSchParameterList::CombineOverlap mode;
2200 std::string type = it->second.front();
2201 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
2203 if(!type.compare(
"full"))
2205 mode = FROSchParameterList::FULL;
2206 }
else if(!type.compare(
"restricted"))
2208 mode = FROSchParameterList::RESTRICTED;
2209 }
else if(!type.compare(
"averaging"))
2211 mode = FROSchParameterList::AVERAGING;
2214 comm.print(
"ERROR: unknown combine-overlap type '" + it->second.front() +
"'");
2217 params.set_combine_overlap(mode);
2218 }
else if(
int(it->second.size()) == params.get_nlevels())
2220 std::vector<FROSchParameterList::CombineOverlap> modes;
2221 modes.reserve(params.get_nlevels());
2222 for(
const auto& t : it->second)
2224 std::string type = t;
2225 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
2227 if(!type.compare(
"full"))
2229 modes.push_back(FROSchParameterList::FULL);
2230 }
else if(!type.compare(
"restricted"))
2232 modes.push_back(FROSchParameterList::RESTRICTED);
2233 }
else if(!type.compare(
"umfpack"))
2235 modes.push_back(FROSchParameterList::AVERAGING);
2238 comm.print(
"ERROR: unknown combine-overlap type '" + t +
"'");
2242 params.set_combine_overlap(modes);
2245 comm.print(
"ERROR: not matching number of combine-overlap: nlevels: " + std::to_string(params.get_nlevels()) +
" number of given combine-overlap: " + std::to_string(it->second.size()) +
"'");
2252 inline bool parse_fpl_combine_lvl(
const Dist::Comm& comm, SimpleArgParser& args, FROSchParameterList ¶ms)
2254 auto it = args.query(
"frosch-combine-lvl");
2257 if(it->second.size() == 1u)
2259 FROSchParameterList::CombineLevel mode;
2260 std::string type = it->second.front();
2261 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
2263 if(!type.compare(
"additive"))
2265 mode = FROSchParameterList::ADDITIVE;
2266 }
else if(!type.compare(
"multiplicative"))
2268 mode = FROSchParameterList::MULTIPLICATIVE;
2271 comm.print(
"ERROR: unknown combine-lvl type '" + it->second.front() +
"'");
2274 params.set_combine_lvl(mode);
2275 }
else if(
int(it->second.size()) == params.get_nlevels())
2277 std::vector<FROSchParameterList::CombineLevel> modes;
2278 modes.reserve(params.get_nlevels());
2279 for(
const auto& t : it->second)
2281 std::string type = t;
2282 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
2284 if(!type.compare(
"additive"))
2286 modes.push_back(FROSchParameterList::ADDITIVE);
2287 }
else if(!type.compare(
"multiplicative"))
2289 modes.push_back(FROSchParameterList::MULTIPLICATIVE);
2292 comm.print(
"ERROR: unknown combine-lvl type '" + t +
"'");
2296 params.set_combine_lvl(modes);
2299 comm.print(
"ERROR: not matching number of combine-lvl: nlevels: " + std::to_string(params.get_nlevels()) +
" number of given combine-lvl: " + std::to_string(it->second.size()) +
"'");
2306 inline bool parse_fpl_reuse_sf_ao(
const Dist::Comm &comm, SimpleArgParser &args, FROSchParameterList ¶ms)
2308 auto it = args.query(
"frosch-reuse-sf-ao");
2311 if(it->second.size() == 1u)
2314 std::string type = it->second.front();
2315 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
2317 if(!type.compare(
"true"))
2320 }
else if(!type.compare(
"false"))
2325 comm.print(
"ERROR: unknown reuse-sf-ao '" + it->second.front() +
"'");
2328 params.set_reuse_sf_ao(rsf_ao);
2329 }
else if(
int(it->second.size()) == params.get_nlevels())
2331 std::vector<bool> rsf_ao;
2332 rsf_ao.reserve(params.get_nlevels());
2333 for(
const auto& t : it->second)
2335 std::string type = t;
2336 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
2338 if(!type.compare(
"true"))
2340 rsf_ao.push_back(
true);
2341 }
else if(!type.compare(
"false"))
2343 rsf_ao.push_back(
false);
2346 comm.print(
"ERROR: unknown reuse-sf-ao type '" + t +
"'");
2350 params.set_reuse_sf_ao(rsf_ao);
2353 comm.print(
"ERROR: not matching number of reuse-sf-ao: nlevels: " + std::to_string(params.get_nlevels()) +
" number of given reuse-sf-ao: " + std::to_string(it->second.size()) +
"'");
2360 inline bool parse_fpl_reuse_sf_cm(
const Dist::Comm &comm, SimpleArgParser &args, FROSchParameterList ¶ms)
2362 auto it = args.query(
"frosch-reuse-sf-cm");
2365 if(it->second.size() == 1u)
2368 std::string type = it->second.front();
2369 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
2371 if(!type.compare(
"true"))
2374 }
else if(!type.compare(
"false"))
2379 comm.print(
"ERROR: unknown reuse-sf-cm '" + it->second.front() +
"'");
2382 params.set_reuse_sf_cm(rsf_cm);
2383 }
else if(
int(it->second.size()) == params.get_nlevels())
2385 std::vector<bool> rsf_cm;
2386 rsf_cm.reserve(params.get_nlevels());
2387 for(
const auto& t : it->second)
2389 std::string type = t;
2390 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
2392 if(!type.compare(
"true"))
2394 rsf_cm.push_back(
true);
2395 }
else if(!type.compare(
"false"))
2397 rsf_cm.push_back(
false);
2400 comm.print(
"ERROR: unknown reuse-sf-cm type '" + t +
"'");
2404 params.set_reuse_sf_cm(rsf_cm);
2407 comm.print(
"ERROR: not matching number of reuse-sf-cm: nlevels: " + std::to_string(params.get_nlevels()) +
" number of given reuse-sf-cm: " + std::to_string(it->second.size()) +
"'");
2414 inline bool parse_fpl_reuse_coarse_matrix(
const Dist::Comm &comm, SimpleArgParser &args, FROSchParameterList ¶ms)
2416 auto it = args.query(
"frosch-reuse-coarse-matrix");
2419 if(it->second.size() == 1u)
2422 std::string type = it->second.front();
2423 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
2425 if(!type.compare(
"true"))
2428 }
else if(!type.compare(
"false"))
2433 comm.print(
"ERROR: unknown reuse-coarse-matrix '" + it->second.front() +
"'");
2436 params.set_reuse_coarse_matrix(reuse_cm);
2437 }
else if(
int(it->second.size()) == params.get_nlevels())
2439 std::vector<bool> reuse_cm;
2440 reuse_cm.reserve(params.get_nlevels());
2441 for(
const auto& t : it->second)
2443 std::string type = t;
2444 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
2446 if(!type.compare(
"true"))
2448 reuse_cm.push_back(
true);
2449 }
else if(!type.compare(
"false"))
2451 reuse_cm.push_back(
false);
2454 comm.print(
"ERROR: unknown reuse-coarse-matrix type '" + t +
"'");
2458 params.set_reuse_coarse_matrix(reuse_cm);
2461 comm.print(
"ERROR: not matching number of reuse-coarse-matrix: nlevels: " + std::to_string(params.get_nlevels()) +
" number of given reuse-coarse-matrix: " + std::to_string(it->second.size()) +
"'");
2468 inline bool parse_fpl_reuse_coarse_basis(
const Dist::Comm &comm, SimpleArgParser &args, FROSchParameterList ¶ms)
2470 auto it = args.query(
"frosch-reuse-coarse-basis");
2473 if(it->second.size() == 1u)
2476 std::string type = it->second.front();
2477 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
2479 if(!type.compare(
"true"))
2482 }
else if(!type.compare(
"false"))
2487 comm.print(
"ERROR: unknown reuse-coarse-basis '" + it->second.front() +
"'");
2490 params.set_reuse_coarse_basis(reuse_cb);
2491 }
else if(
int(it->second.size()) == params.get_nlevels())
2493 std::vector<bool> reuse_cb;
2494 reuse_cb.reserve(params.get_nlevels());
2495 for(
const auto& t : it->second)
2497 std::string type = t;
2498 std::transform(type.begin(), type.end(), type.begin(), [](
unsigned char c){return std::tolower(c);});
2500 if(!type.compare(
"true"))
2502 reuse_cb.push_back(
true);
2503 }
else if(!type.compare(
"false"))
2505 reuse_cb.push_back(
false);
2508 comm.print(
"ERROR: unknown reuse-coarse-basis type '" + t +
"'");
2512 params.set_reuse_coarse_basis(reuse_cb);
2515 comm.print(
"ERROR: not matching number of reuse-coarse-basis: nlevels: " + std::to_string(params.get_nlevels()) +
" number of given reuse-coarse-basis: " + std::to_string(it->second.size()) +
"'");
2522 inline bool parse_fpl_phi_dt(
const Dist::Comm &comm, SimpleArgParser &args, FROSchParameterList ¶ms)
2524 auto it = args.query(
"frosch-phi-dropping-threshold");
2527 if(it->second.size() == 1u)
2529 double phi_dt = std::stod(it->second.front());
2533 comm.print(
"ERROR: unknown dropping threshold smaller than 0.: '" + it->second.front() +
"'");
2536 params.set_phi_dropping_threshold(phi_dt);
2537 }
else if(
int(it->second.size()) == params.get_nlevels())
2539 std::vector<double> phi_dt;
2540 phi_dt.reserve(params.get_nlevels());
2541 for(
const auto& t : it->second)
2543 double dt = std::stod(t);
2547 comm.print(
"ERROR: unknown partition imblance smaller than 0.: '" + t +
"'");
2550 phi_dt.push_back(dt);
2552 params.set_phi_dropping_threshold(phi_dt);
2555 comm.print(
"ERROR: not matching number of phi-dropping-threshold: nlevels: " + std::to_string(params.get_nlevels()) +
" number of given phi-dropping-threshold: " + std::to_string(it->second.size()) +
"'");
2562 bool FROSchParameterList::parse_args(SimpleArgParser& args)
2565 auto it = args.query(
"frosch-plist");
2568 if(it->second.size() == 1u)
2570 read_from_xml_file(it->second.front());
2575 _comm.print(
"ERROR: multiple XML files are given");
2581 if(!parse_fpl_print(_comm, args, *
this))
2585 if(!parse_fpl_verbose(_comm, args, *
this))
2589 if(!parse_fpl_timer(_comm, args, *
this))
2593 if(!parse_fpl_levels(_comm, args, *
this))
2597 if(!parse_fpl_dim(_comm, args, *
this))
2601 if(!parse_fpl_overlaps(_comm, args, *
this))
2605 if(!parse_fpl_subreg(_comm, args, *
this))
2609 if(!parse_fpl_gsteps(_comm, args, *
this))
2613 if(!parse_fpl_parti_type(_comm, args, *
this))
2617 if(!parse_fpl_parti_approach(_comm, args, *
this))
2621 if(!parse_fpl_parti_imbl(_comm, args, *
this))
2625 if(!parse_fpl_ipou_pres(_comm, args, *
this))
2629 if(!parse_fpl_ipou_velo(_comm, args, *
this))
2633 if(!parse_fpl_solver_ao(_comm, args, *
this))
2637 if(!parse_fpl_solver_ext(_comm, args, *
this))
2641 if(!parse_fpl_solver_coarse(_comm, args, *
this))
2645 if(!parse_fpl_precond(_comm, args, *
this))
2649 if(!parse_fpl_cspace_pres(_comm, args, *
this))
2653 if(!parse_fpl_cspace_velo(_comm, args, *
this))
2657 if(!parse_fpl_exclude_velo_pres(_comm, args, *
this))
2661 if(!parse_fpl_exclude_pres_velo(_comm, args, *
this))
2665 if(!parse_fpl_combine(_comm, args, *
this))
2669 if(!parse_fpl_combine_lvl(_comm, args, *
this))
2673 if (!parse_fpl_reuse_sf_ao(_comm, args, *
this))
2677 if (!parse_fpl_reuse_sf_cm(_comm, args, *
this))
2681 if (!parse_fpl_reuse_coarse_matrix(_comm, args, *
this))
2685 if (!parse_fpl_reuse_coarse_basis(_comm, args, *
this))
2689 if (!parse_fpl_phi_dt(_comm, args, *
this))
2700 class TpetraCoreBase
2704 using UN = unsigned;
2707 using GO = FROSch::DefaultGlobalOrdinal;
2708 using NO = Tpetra::KokkosClassic::DefaultNode::DefaultNodeType;
2710 using AGS = Teuchos::Array<GO>::size_type;
2711 using ARCPS = Teuchos::ArrayRCP<std::size_t>::size_type;
2712 using TGS = Tpetra::global_size_t;
2713 using VGS = std::vector<GO>::size_type;
2716 Teuchos::RCP<const Teuchos::Comm<int>> _comm;
2718 const LO _num_owned_dofs, _num_owned_nonzeros;
2719 const GO _my_dof_offset, _num_global_dofs;
2720 const int _dpe_pres;
2723 Teuchos::ArrayRCP<std::int64_t> _row_ptr;
2725 Teuchos::ArrayRCP<TGS> _num_nze;
2728 Teuchos::ArrayRCP<std::int32_t> _col_idx;
2730 Teuchos::ArrayRCP<SC> _mat_val;
2733 Teuchos::RCP<const Tpetra::Map<LO, GO, NO>> _map;
2736 Teuchos::RCP<Tpetra::MultiVector<SC, LO,GO,NO>> _vec_def, _vec_cor;
2737 Teuchos::RCP<Tpetra::CrsMatrix<SC,LO,GO,NO>> _matrix;
2740 Teuchos::RCP<Teuchos::ParameterList> _params;
2743 Teuchos::RCP<Teuchos::StackedTimer> _stacked_timer;
2745 explicit TpetraCoreBase(
const void* comm, Index num_global_dofs, Index my_dof_offset,
2746 Index num_owned_dofs, Index num_nonzeros,
const Trilinos::FROSchParameterList & params) :
2747 _comm(Teuchos::rcp(new Teuchos::MpiComm<int>(*reinterpret_cast<const MPI_Comm*>(comm)))),
2748 _num_owned_dofs(static_cast<LO>(num_owned_dofs)),
2749 _num_owned_nonzeros(static_cast<LO>(num_nonzeros)),
2750 _my_dof_offset(static_cast<GO>(my_dof_offset)),
2751 _num_global_dofs(static_cast<GO>(num_global_dofs)),
2752 _dpe_pres(params.get_dpe_pres()),
2753 _row_ptr(static_cast<ARCPS>(_num_owned_dofs+1u), static_cast<std::int64_t>(0)),
2754 _num_nze(static_cast<ARCPS>(_num_owned_dofs), static_cast<TGS>(0)),
2755 _col_idx(static_cast<ARCPS>(_num_owned_nonzeros), static_cast<std::int32_t>(0)),
2756 _mat_val(static_cast<ARCPS>(_num_owned_nonzeros), static_cast<SC>(0.)),
2761 _params(Teuchos::null),
2762 _use_timer(params.get_use_timer()),
2763 _stacked_timer(Teuchos::rcp(new Teuchos::StackedTimer(
"TpetraCoreBase")))
2765 void* pcore = params.get_core();
2766 if(pcore !=
nullptr)
2768 _params = Teuchos::rcp(
reinterpret_cast<Teuchos::ParameterList*
>(pcore),
false);
2774 Teuchos::TimeMonitor::setStackedTimer(_stacked_timer);
2778 virtual ~TpetraCoreBase()
2783 _stacked_timer->stop(
"TpetraCoreBase");
2784 Teuchos::StackedTimer::OutputOptions options;
2785 options.output_fraction = options.output_histogram = options.output_minmax =
true;
2786 Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
2787 _stacked_timer->report(*out, _comm, options);
2792 virtual void init_symbolic() = 0;
2794 virtual void init_numeric() = 0;
2796 virtual std::int64_t* get_row_ptr()
2798 return this->_row_ptr.get();
2801 virtual std::int32_t* get_col_idx()
2803 return this->_col_idx.get();
2806 virtual double* get_mat_val()
2808 return this->_mat_val.get();
2811 virtual double* get_vec_def()
2813 return this->_vec_def->getDataNonConst(0).get();
2816 virtual double* get_vec_cor()
2818 return this->_vec_cor->getDataNonConst(0).get();
2821 virtual void format_vec_cor()
2823 return this->_vec_cor->putScalar(0.0);
2827 void set_parameter_list(
void* core,
const FROSchParameterList& params)
2829 void* pcore = params.get_core();
2830 if(pcore ==
nullptr)
2832 reinterpret_cast<TpetraCoreBase*
>(core)->_params = Teuchos::null;
2836 reinterpret_cast<TpetraCoreBase*
>(core)->_params
2837 = Teuchos::rcp(
reinterpret_cast<Teuchos::ParameterList*
>(pcore),
false);
2841 void destroy_core(
void* core)
2843 delete reinterpret_cast<TpetraCoreBase*
>(core);
2846 void init_symbolic(
void* core)
2848 reinterpret_cast<TpetraCoreBase*
>(core)->init_symbolic();
2851 void init_numeric(
void* core)
2853 reinterpret_cast<TpetraCoreBase*
>(core)->init_numeric();
2856 std::int64_t* get_row_ptr(
void* core)
2858 return reinterpret_cast<TpetraCoreBase*
>(core)->get_row_ptr();
2861 std::int32_t* get_col_idx(
void* core)
2863 return reinterpret_cast<TpetraCoreBase*
>(core)->get_col_idx();
2866 double* get_mat_val(
void* core)
2868 return reinterpret_cast<TpetraCoreBase*
>(core)->get_mat_val();
2871 double* get_vec_def(
void* core)
2873 return reinterpret_cast<TpetraCoreBase*
>(core)->get_vec_def();
2876 double* get_vec_cor(
void* core)
2878 return reinterpret_cast<TpetraCoreBase*
>(core)->get_vec_cor();
2881 void format_vec_cor(
void* core)
2883 return reinterpret_cast<TpetraCoreBase*
>(core)->format_vec_cor();
2889 class TpetraCoreScalar :
public TpetraCoreBase
2893 typedef TpetraCoreBase BaseClass;
2894 using UN = unsigned;
2897 using GO = FROSch::DefaultGlobalOrdinal;
2898 using NO = Tpetra::KokkosClassic::DefaultNode::DefaultNodeType;
2900 using AGS = Teuchos::Array<GO>::size_type;
2901 using ARCPS = Teuchos::ArrayRCP<std::size_t>::size_type;
2902 using TGS = Tpetra::global_size_t;
2903 using VGS = std::vector<GO>::size_type;
2905 explicit TpetraCoreScalar(
const void* comm, Index num_global_dofs, Index my_dof_offset,
2906 Index num_owned_dofs, Index num_nonzeros,
const Trilinos::FROSchParameterList & params) :
2907 TpetraCoreBase(comm, num_global_dofs, my_dof_offset, num_owned_dofs, num_nonzeros, params)
2911 virtual void init_symbolic()
override
2915 _stacked_timer->start(
"TpetraCoreScalar::init_core");
2916 _stacked_timer->start(
"TpetraCoreScalar::init_core::build_map");
2920 _num_nze = Teuchos::ArrayRCP<TGS>(
static_cast<ARCPS
>(_num_owned_dofs),
static_cast<TGS
>(0));
2923 for(LO i(0); i < _num_owned_dofs; ++i)
2924 _num_nze[i] =
static_cast<TGS
>(_row_ptr[i+1] - _row_ptr[i]);
2933 std::vector<GO> element_list_vec(
static_cast<VGS
>(_num_owned_dofs));
2934 for(IndexType i = 0; i < static_cast<IndexType>(_num_owned_dofs); ++i)
2935 element_list_vec.at(i) =
static_cast<GO
>(_my_dof_offset + i);
2937 GO num_total_dofs = 0;
2938 GO my_dof_offset_tmp =
static_cast<GO
>(_num_owned_dofs);
2939 Teuchos::reduceAll(*_comm, Teuchos::REDUCE_SUM, 1, &my_dof_offset_tmp, &num_total_dofs);
2941 const GO _index_base = 0;
2942 const Teuchos::ArrayView<const GO> element_list = Teuchos::arrayViewFromVector(element_list_vec);
2943 _map = Teuchos::rcp(
new Tpetra::Map(
static_cast<TGS
>(num_total_dofs), element_list, _index_base, _comm));
2947 _stacked_timer->stop(
"TpetraCoreScalar::init_core::build_map");
2948 _stacked_timer->start(
"TpetraCoreScalar::init_core::build_system_matrix");
2952 auto crsgraph = Teuchos::rcp(
new Tpetra::CrsGraph<LO, GO, NO >(_map, _num_nze()));
2953 const TGS max_nnz_per_row = *std::max_element(_num_nze.begin(), _num_nze.end());
2954 std::vector<GO> col_buffer(max_nnz_per_row);
2961 AGS entries_start = 0;
2962 for(GO i = 0; i < static_cast<GO>(_num_owned_dofs); ++i)
2964 const auto num_entries =
static_cast<AGS
>(_num_nze[i]);
2966 for(Teuchos::Array<GO>::size_type j = 0; j < num_entries; ++j)
2967 col_buffer[j] =
static_cast<GO
>(this->_col_idx[entries_start + j]);
2969 crsgraph->insertGlobalIndices(
static_cast<GO
>(_my_dof_offset + i), int(num_entries), col_buffer.data());
2970 entries_start += num_entries;
2972 crsgraph->fillComplete();
2973 _matrix = Teuchos::rcp(
new Tpetra::CrsMatrix<SC, LO, GO, NO>(crsgraph));
2976 _stacked_timer->stop(
"TpetraCoreScalar::init_core::build_system_matrix");
2980 const LO num_vectors = 1;
2981 _vec_def = Teuchos::rcp(
new Tpetra::MultiVector<SC, LO, GO, NO>(_map, num_vectors));
2982 _vec_cor = Teuchos::rcp(
new Tpetra::MultiVector<SC, LO, GO, NO>(_map, num_vectors));
2985 if (! sublist(sublist(_params,
"Preconditioner Types"),
"FROSch")->get(
"FROSch Preconditioner Type",
"TwoLevelPreconditioner").compare(
"TwoLevelBlockPreconditioner"))
2987 const int NumberOfBlocks = 1;
2988 Teuchos::ArrayRCP<Teuchos::RCP<Xpetra::Map<LO, GO, NO>>> XRepeatedMaps(NumberOfBlocks);
2989 auto xcrsgraph = Teuchos::rcp(
new const Xpetra::TpetraCrsGraph<LO, GO, NO>(Teuchos::rcp_const_cast<Tpetra::CrsGraph<LO, GO, NO >>(_matrix->getCrsGraph ())));
2990 XRepeatedMaps[0] = FROSch::BuildRepeatedMapNonConst<LO, GO, NO>(xcrsgraph);
2991 sublist(sublist(_params,
"Preconditioner Types"),
"FROSch")->set(
"Repeated Map Vector", XRepeatedMaps);
2993 Teuchos::ArrayRCP<FROSch::DofOrdering> dofOrderings(NumberOfBlocks);
2994 dofOrderings[0] = FROSch::NodeWise;
2995 sublist(sublist(_params,
"Preconditioner Types"),
"FROSch")->set(
"DofOrdering Vector", dofOrderings);
2997 Teuchos::ArrayRCP<unsigned> dofsPerNodeVector(NumberOfBlocks);
2998 dofsPerNodeVector[0] = _dpe_pres;
2999 sublist(sublist(_params,
"Preconditioner Types"),
"FROSch")->set(
"DofsPerNode Vector", dofsPerNodeVector);
3002 Teuchos::ArrayRCP<Teuchos::RCP<Xpetra::MultiVector<SC,LO,GO,NO>>> nullSpaceBasis(NumberOfBlocks);
3003 nullSpaceBasis[0] = Xpetra::MultiVectorFactory<SC,LO,GO,NO>::Build(XRepeatedMaps[0].getConst(), 1);
3005 for (
unsigned j = 0; j < XRepeatedMaps[i]->getLocalNumElements(); j += dofsPerNodeVector[i])
3007 nullSpaceBasis[0]->getDataNonConst(i)[XRepeatedMaps[i]->getLocalElement(XRepeatedMaps[i]->getGlobalElement(j))] = Teuchos::ScalarTraits<SC>::one();
3009 sublist(sublist(_params,
"Preconditioner Types"),
"FROSch")->set(
"Null Space Vector", nullSpaceBasis);
3011 else if(! sublist(sublist(_params,
"Preconditioner Types"),
"FROSch")->get(
"FROSch Preconditioner Type",
"TwoLevelPreconditioner").compare(
"TwoLevelPreconditioner"))
3014 auto xcrsgraph = Teuchos::rcp(
new const Xpetra::TpetraCrsGraph<LO, GO, NO>(Teuchos::rcp_const_cast<Tpetra::CrsGraph<LO, GO, NO >>(_matrix->getCrsGraph ())));
3015 Teuchos::RCP<Xpetra::Map<LO, GO, NO>> XRepeatedMap = FROSch::BuildRepeatedMapNonConst<LO, GO, NO>(xcrsgraph);
3016 sublist(sublist(_params,
"Preconditioner Types"),
"FROSch")->set(
"Repeated Map", XRepeatedMap);
3018 Teuchos::RCP<Xpetra::MultiVector<SC,LO,GO,NO>> nullSpaceBasis = Xpetra::MultiVectorFactory<SC,LO,GO,NO>::Build(XRepeatedMap.getConst(), 1);
3019 for (
unsigned j = 0; j < XRepeatedMap->getLocalNumElements(); j += _dpe_pres)
3021 nullSpaceBasis->getDataNonConst(0)[XRepeatedMap->getLocalElement(XRepeatedMap->getGlobalElement(j))] = Teuchos::ScalarTraits<SC>::one();
3023 sublist(sublist(_params,
"Preconditioner Types"),
"FROSch")->set(
"Null Space", nullSpaceBasis);
3028 _stacked_timer->stop(
"TpetraCoreScalar::init_core");
3032 virtual void init_numeric()
override
3034 if(this->_use_timer)
3036 this->_stacked_timer->start(
"TpetraCoreScalar::SetValues");
3039 Teuchos::ArrayView<const LO> Indices;
3041 _matrix->resumeFill();
3042 AGS entries_start = 0;
3044 for(LO i(0); i < _num_owned_dofs; ++i)
3046 const auto num_entries =
static_cast<Teuchos::Array<SC>::size_type
>(_num_nze[i]);
3048 Teuchos::Array<SC> vals_ar(num_entries);
3049 for(Teuchos::Array<SC>::size_type j = 0; j < num_entries; ++j)
3050 vals_ar[j] = _mat_val[
static_cast<VGS
>(entries_start + j)];
3052 Teuchos::Array<GO> cols(num_entries);
3053 for(Teuchos::Array<GO>::size_type j = 0; j < num_entries; ++j)
3054 cols[j] =
static_cast<GO
>(_col_idx[entries_start + j]);
3056 _matrix->replaceGlobalValues(_my_dof_offset +
static_cast<GO
>(i),
3057 cols.view(0,
static_cast<AGS
>(num_entries)),
3058 vals_ar.view(0,
static_cast<Teuchos::Array<SC>::size_type
>(num_entries)));
3060 entries_start += num_entries;
3063 _matrix->fillComplete();
3067 _stacked_timer->stop(
"TpetraCoreScalar::SetValues");
3072 void* create_core_scalar(
const void* comm, Index num_global_dofs, Index my_dof_offset,
3073 Index num_owned_dofs, Index num_nonzeros,
const FROSchParameterList& params)
3075 return new TpetraCoreScalar(comm, num_global_dofs, my_dof_offset, num_owned_dofs, num_nonzeros, params);
3083 class TpetraCoreStokes :
public TpetraCoreBase
3087 typedef TpetraCoreBase BaseClass;
3088 using UN = unsigned;
3091 using GO = FROSch::DefaultGlobalOrdinal;
3092 using NO = Tpetra::KokkosClassic::DefaultNode::DefaultNodeType;
3094 using AGS = Teuchos::Array<GO>::size_type;
3095 using ARCPS = Teuchos::ArrayRCP<std::size_t>::size_type;
3096 using TGS = Tpetra::global_size_t;
3097 using VGS = std::vector<GO>::size_type;
3100 const int _dpe_velo;
3102 const IndexType _num_owned_velo_dofs;
3103 const IndexType _num_owned_pres_dofs;
3105 const IndexType _first_owned_velo_dof;
3106 const IndexType _first_owned_pres_dof;
3108 const IndexType _num_global_velo_dofs;
3109 const IndexType _num_global_pres_dofs;
3111 Teuchos::ArrayRCP<std::int32_t> _col_idx_mapped;
3113 Teuchos::ArrayRCP<GO> _all_global_dof_offset;
3114 Teuchos::ArrayRCP<IndexType> _all_num_owned_velo_dofs, _all_num_owned_pres_dofs;
3115 Teuchos::ArrayRCP<IndexType> _all_first_owned_velo_dof, _all_first_owned_pres_dof;
3117 explicit TpetraCoreStokes(
const void* comm,
3118 Index num_global_dofs, Index my_dof_offset,
3119 Index num_owned_dofs, Index num_nonzeros,
3120 IndexType num_owned_velo_dofs, IndexType num_owned_pres_dofs,
3121 IndexType first_owned_velo_dof, IndexType first_owned_pres_dof,
3122 IndexType num_global_velo_dofs, IndexType num_global_pres_dofs,
3123 const Trilinos::FROSchParameterList & params) :
3124 BaseClass(comm, num_global_dofs, my_dof_offset, num_owned_dofs, num_nonzeros, params),
3125 _dpe_velo(params.get_dpe_velo()),
3126 _num_owned_velo_dofs(num_owned_velo_dofs),
3127 _num_owned_pres_dofs(num_owned_pres_dofs),
3128 _first_owned_velo_dof(first_owned_velo_dof),
3129 _first_owned_pres_dof(first_owned_pres_dof),
3130 _num_global_velo_dofs(num_global_velo_dofs),
3131 _num_global_pres_dofs(num_global_pres_dofs),
3132 _col_idx_mapped(static_cast<ARCPS>(_num_owned_nonzeros), 0),
3133 _all_global_dof_offset(static_cast<ARCPS>(this->_comm->getSize())),
3134 _all_num_owned_velo_dofs(static_cast<ARCPS>(this->_comm->getSize())),
3135 _all_num_owned_pres_dofs(static_cast<ARCPS>(this->_comm->getSize())),
3136 _all_first_owned_velo_dof(static_cast<ARCPS>(this->_comm->getSize())),
3137 _all_first_owned_pres_dof(static_cast<ARCPS>(this->_comm->getSize()))
3141 virtual void init_symbolic()
override
3146 Teuchos::TimeMonitor::setStackedTimer(this->_stacked_timer);
3147 _stacked_timer->start(
"TpetraCoreStokes::init_symbolic");
3151 this->_col_idx_mapped.assign(this->_col_idx.begin(), this->_col_idx.end());
3155 _stacked_timer->start(
"TpetraCoreStokes::init_symbolic::gather");
3158 Teuchos::gatherAll(*(_comm),
static_cast<int>(1), &_my_dof_offset,
static_cast<int>(1*_comm->getSize()), _all_global_dof_offset.getRawPtr());
3159 Teuchos::gatherAll(*(_comm),
static_cast<int>(1), &_num_owned_velo_dofs,
static_cast<int>(1*_comm->getSize()), _all_num_owned_velo_dofs.getRawPtr());
3160 Teuchos::gatherAll(*(_comm),
static_cast<int>(1), &_num_owned_pres_dofs,
static_cast<int>(1*_comm->getSize()), _all_num_owned_pres_dofs.getRawPtr());
3161 Teuchos::gatherAll(*(_comm),
static_cast<int>(1), &_first_owned_velo_dof,
static_cast<int>(1*_comm->getSize()), _all_first_owned_velo_dof.getRawPtr());
3162 Teuchos::gatherAll(*(_comm),
static_cast<int>(1), &_first_owned_pres_dof,
static_cast<int>(1*_comm->getSize()), _all_first_owned_pres_dof.getRawPtr());
3165 _stacked_timer->stop(
"TpetraCoreStokes::init_symbolic::gather");
3166 _stacked_timer->start(
"TpetraCoreStokes::init_symbolic::build_map");
3170 _num_nze = Teuchos::ArrayRCP<TGS>(
static_cast<ARCPS
>(_num_owned_dofs),
static_cast<TGS
>(0));
3173 for(LO i(0); i < _num_owned_dofs; ++i)
3174 _num_nze[i] =
static_cast<TGS
>(this->_row_ptr[i+1] - this->_row_ptr[i]);
3189 const GO _index_base = 0;
3190 std::vector<GO> element_list_vec(
static_cast<VGS
>(_num_owned_dofs));
3191 for(IndexType i = 0; i < static_cast<IndexType>(_num_owned_velo_dofs); ++i)
3192 element_list_vec.at(i) =
static_cast<GO
>(_first_owned_velo_dof + i);
3193 for(IndexType i = 0; i < static_cast<IndexType>(_num_owned_pres_dofs); ++i)
3194 element_list_vec.at(_num_owned_velo_dofs + i) =
static_cast<GO
>(_num_global_velo_dofs + _first_owned_pres_dof + i);
3195 const Teuchos::ArrayView<const GO> element_list = Teuchos::arrayViewFromVector(element_list_vec);
3197 _map = Teuchos::rcp(
new Tpetra::Map(
static_cast<TGS
>(_num_global_velo_dofs + _num_global_pres_dofs), element_list, _index_base, _comm));
3201 _stacked_timer->stop(
"TpetraCoreStokes::init_symbolic::build_map");
3202 _stacked_timer->start(
"TpetraCoreStokes::init_symbolic::build_repeated_maps");
3204 const int NumberOfBlocks = 2;
3207 std::vector<GO> rank_start(_comm->getSize());
3208 std::vector<GO> rank_velo_end(_comm->getSize());
3209 std::vector<GO> rank_total_end(_comm->getSize());
3210 for (
int rank = 0; rank < _comm->getSize(); ++rank)
3212 rank_start[rank] = _all_global_dof_offset[rank];
3213 rank_velo_end[rank] = _all_global_dof_offset[rank] + GO(_all_num_owned_velo_dofs[rank]);
3214 rank_total_end[rank] = _all_global_dof_offset[rank] + GO(_all_num_owned_velo_dofs[rank]) + GO(_all_num_owned_pres_dofs[rank]);
3221 _stacked_timer->start(
"TpetraCoreStokes::init_symbolic::build_repeated_maps::velocity_graph");
3224 std::vector<GO> element_list_vec_velo(
static_cast<VGS
>(_num_owned_velo_dofs));
3225 for(IndexType i = 0; i < static_cast<IndexType>(_num_owned_velo_dofs); ++i)
3226 element_list_vec_velo.at(i) =
static_cast<GO
>(_first_owned_velo_dof + i);
3227 const Teuchos::ArrayView<const GO> element_list_velo = Teuchos::arrayViewFromVector(element_list_vec_velo);
3228 Teuchos::RCP<const Tpetra::Map<LO, GO, NO>> _map_velo = Teuchos::rcp(
new Tpetra::Map(
static_cast<TGS
>(_num_global_velo_dofs), element_list_velo, _index_base, _comm));
3230 auto crsgraph = Teuchos::rcp(
new Tpetra::CrsGraph<LO, GO, NO >(_map_velo, _num_nze.view(0,
static_cast<AGS
>(_num_owned_velo_dofs))));
3231 const TGS max_nnz_per_row = *std::max_element(_num_nze.begin(), _num_nze.end());
3232 std::vector<GO> col_buffer(max_nnz_per_row);
3235 for(IndexType row(0); row < _num_owned_velo_dofs; ++row)
3237 Teuchos::Array<GO> cols(
static_cast<GO
>(_num_nze[
static_cast<ARCPS
>(row)]));
3241 int current_rank = 0;
3243 for(
auto colidx = this->_row_ptr[row]; colidx < this->_row_ptr[row+1]; ++colidx)
3245 GO col =
static_cast<GO
>(this->_col_idx_mapped[colidx]);
3248 while(current_rank <
int(_comm->getSize()) && col >= rank_total_end[current_rank])
3254 if(current_rank <
int(_comm->getSize()) && col >= rank_start[current_rank])
3256 if(col < rank_velo_end[current_rank])
3259 GO mapped_dof = GO(_all_first_owned_velo_dof[current_rank]) + GO(col - rank_start[current_rank]);
3260 cols[counter++] = mapped_dof;
3266 crsgraph->insertGlobalIndices(
static_cast<GO
>(_first_owned_velo_dof + row),
3267 cols.view(0,
static_cast<AGS
>(counter)));
3269 crsgraph->fillComplete();
3273 _stacked_timer->stop(
"TpetraCoreStokes::init_symbolic::build_repeated_maps::velocity_graph");
3276 Teuchos::ArrayRCP<Teuchos::RCP<Tpetra::Map<LO, GO, NO>>> RepeatedMaps(NumberOfBlocks);
3277 Teuchos::ArrayRCP<Teuchos::RCP<Xpetra::Map<LO, GO, NO>>> XRepeatedMaps(NumberOfBlocks);
3279 const GO _index_base_tmp = 0;
3281 std::vector<GO> element_list_vec_tmp(
static_cast<VGS
>(_num_owned_pres_dofs));
3282 for(IndexType i = 0; i < static_cast<IndexType>(_num_owned_pres_dofs); ++i)
3283 element_list_vec_tmp.at(i) =
static_cast<GO
>(_first_owned_pres_dof + i);
3284 const Teuchos::ArrayView<const GO> element_list_tmp = Teuchos::arrayViewFromVector(element_list_vec_tmp);
3285 RepeatedMaps[1] = Teuchos::rcp(
new Tpetra::Map(
static_cast<TGS
>(_num_owned_pres_dofs), element_list_tmp, _index_base_tmp, _comm));
3287 auto xcrsgraph = Teuchos::rcp(
new Xpetra::TpetraCrsGraph<LO, GO, NO>(crsgraph));
3288 XRepeatedMaps[0] = FROSch::BuildRepeatedMapNonConst<LO, GO, NO>(xcrsgraph);
3290 XRepeatedMaps[1] = Teuchos::rcp(
new Xpetra::TpetraMap<LO, GO, NO>(RepeatedMaps[1]));
3292 sublist(sublist(_params,
"Preconditioner Types"),
"FROSch")->set(
"Repeated Map Vector", XRepeatedMaps);
3295 Teuchos::ArrayRCP<FROSch::DofOrdering> dofOrderings(NumberOfBlocks);
3296 dofOrderings[0] = FROSch::NodeWise;
3297 dofOrderings[1] = FROSch::NodeWise;
3298 sublist(sublist(_params,
"Preconditioner Types"),
"FROSch")->set(
"DofOrdering Vector", dofOrderings);
3300 Teuchos::ArrayRCP<unsigned> dofsPerNodeVector(NumberOfBlocks);
3301 dofsPerNodeVector[0] = _dpe_velo;
3302 dofsPerNodeVector[1] = _dpe_pres;
3303 sublist(sublist(_params,
"Preconditioner Types"),
"FROSch")->set(
"DofsPerNode Vector", dofsPerNodeVector);
3306 Teuchos::ArrayRCP<Teuchos::RCP<Xpetra::MultiVector<SC,LO,GO,NO>>> nullSpaceBasis(NumberOfBlocks);
3307 Teuchos::ArrayRCP<Teuchos::RCP<const Xpetra::Map<LO, GO, NO>>> XRepeatedMapsTmp(NumberOfBlocks);
3308 XRepeatedMapsTmp[0] = XRepeatedMaps[0].getConst();
3309 XRepeatedMapsTmp[1] = XRepeatedMaps[1].getConst();
3310 Teuchos::RCP<const Xpetra::Map<LO, GO, NO>> repeatedMap = FROSch::MergeMaps(XRepeatedMapsTmp);
3312 nullSpaceBasis[0] = Xpetra::MultiVectorFactory<SC,LO,GO,NO>::Build(repeatedMap, dofsPerNodeVector[0]);
3313 nullSpaceBasis[1] = Xpetra::MultiVectorFactory<SC,LO,GO,NO>::Build(repeatedMap, 1);
3314 for(
unsigned i = 0; i < dofsPerNodeVector[0]; i++)
3315 for (
unsigned j = i; j < XRepeatedMaps[0]->getLocalNumElements(); j += dofsPerNodeVector[0]) {
3316 nullSpaceBasis[0]->getDataNonConst(i)[XRepeatedMaps[0]->getLocalElement(XRepeatedMaps[0]->getGlobalElement(j))] = Teuchos::ScalarTraits<SC>::one();
3318 LO offset = LO(XRepeatedMaps[0]->getLocalNumElements());
3319 for (
unsigned j = 0; j < XRepeatedMaps[1]->getLocalNumElements(); j += dofsPerNodeVector[1]) {
3320 nullSpaceBasis[1]->getDataNonConst(0)[offset + XRepeatedMaps[1]->getLocalElement(XRepeatedMaps[1]->getGlobalElement(j))] = Teuchos::ScalarTraits<SC>::one();
3323 sublist(sublist(_params,
"Preconditioner Types"),
"FROSch")->set(
"Null Space Vector", nullSpaceBasis);
3327 _stacked_timer->stop(
"TpetraCoreStokes::init_symbolic::build_repeated_maps");
3328 _stacked_timer->start(
"TpetraCoreStokes::init_symbolic::build_crsgraph_system");
3332 GO counter_col_idx = 0;
3335 auto crsgraph = Teuchos::rcp(
new Tpetra::CrsGraph<LO, GO, NO >(_map, _num_nze.view(0,
static_cast<AGS
>(_num_owned_dofs))));
3338 for(IndexType row(0); row < _num_owned_velo_dofs; ++row)
3340 Teuchos::Array<GO> cols(
static_cast<GO
>(_num_nze[
static_cast<ARCPS
>(row)]));
3344 int current_rank = 0;
3346 for(
auto colidx = this->_row_ptr[row]; colidx < this->_row_ptr[row+1]; ++colidx)
3348 GO col =
static_cast<GO
>(this->_col_idx_mapped[colidx]);
3351 while(current_rank <
int(_comm->getSize()) && col >= rank_total_end[current_rank])
3357 if(current_rank <
int(_comm->getSize()) && col >= rank_start[current_rank])
3359 if(col < rank_velo_end[current_rank])
3362 GO mapped_dof = GO(_all_first_owned_velo_dof[current_rank]) + GO(col - rank_start[current_rank]);
3363 cols[counter++] = mapped_dof;
3364 this->_col_idx_mapped[counter_col_idx++] = mapped_dof;
3366 else if (col < rank_total_end[current_rank])
3369 GO pres_offset = col - rank_velo_end[current_rank];
3370 GO mapped_dof = GO(_num_global_velo_dofs) + GO(_all_first_owned_pres_dof[current_rank]) + GO(pres_offset);
3371 cols[counter++] = mapped_dof;
3372 this->_col_idx_mapped[counter_col_idx++] = mapped_dof;
3378 crsgraph->insertGlobalIndices(
static_cast<GO
>(_first_owned_velo_dof + row), cols.view(0,
static_cast<AGS
>(counter)));
3381 for(IndexType row(_num_owned_velo_dofs); row < (_num_owned_velo_dofs + _num_owned_pres_dofs); ++row)
3383 Teuchos::Array<GO> cols(
static_cast<GO
>(_num_nze[
static_cast<ARCPS
>(row)]));
3387 int current_rank = 0;
3389 for(
auto colidx = this->_row_ptr[row]; colidx < this->_row_ptr[row+1]; ++colidx)
3391 GO col = this->_col_idx_mapped[colidx];
3394 while(current_rank <
int(_comm->getSize()) && col >= rank_total_end[current_rank])
3400 if(current_rank <
int(_comm->getSize()) && col >= rank_start[current_rank])
3403 if(col < rank_velo_end[current_rank])
3406 GO mapped_dof = GO(_all_first_owned_velo_dof[current_rank]) + GO(col - rank_start[current_rank]);
3407 cols[counter++] = mapped_dof;
3408 this->_col_idx_mapped[counter_col_idx++] = mapped_dof;
3410 else if(col < rank_total_end[current_rank])
3413 GO pres_offset = col - rank_velo_end[current_rank];
3414 GO mapped_dof = GO(_num_global_velo_dofs) + GO(_all_first_owned_pres_dof[current_rank]) + GO(pres_offset);
3415 cols[counter++] = mapped_dof;
3416 this->_col_idx_mapped[counter_col_idx++] = mapped_dof;
3420 crsgraph->insertGlobalIndices(
static_cast<GO
>(_num_global_velo_dofs + _first_owned_pres_dof + (row - _num_owned_velo_dofs)),
3421 cols.view(0,
static_cast<AGS
>(counter)));
3423 crsgraph->fillComplete();
3427 _stacked_timer->stop(
"TpetraCoreStokes::init_symbolic::build_crsgraph_system");
3428 _stacked_timer->start(
"TpetraCoreStokes::init_symbolic::build_system_matrix");
3432 _matrix = Teuchos::rcp(
new Tpetra::CrsMatrix<SC, LO, GO, NO>(crsgraph, _params));
3435 const LO num_vectors = 1;
3436 _vec_def = Teuchos::rcp(
new Tpetra::MultiVector<SC, LO, GO, NO>(_map, num_vectors));
3437 _vec_cor = Teuchos::rcp(
new Tpetra::MultiVector<SC, LO, GO, NO>(_map, num_vectors));
3441 _stacked_timer->stop(
"TpetraCoreStokes::init_symbolic::build_system_matrix");
3442 _stacked_timer->stop(
"TpetraCoreStokes::init_symbolic");
3446 virtual void init_numeric()
override
3449 _stacked_timer->start(
"TpetraCoreStokes::init_numeric");
3451 Teuchos::ArrayView<const LO> Indices;
3453 _matrix->resumeFill();
3455 AGS entries_start = 0;
3457 for(IndexType row(0); row < _num_owned_velo_dofs; ++row)
3459 const auto num_entries =
static_cast<Teuchos::Array<SC>::size_type
>(_num_nze[
static_cast<AGS
>(row)]);
3462 Teuchos::Array<SC> vals_ar(num_entries);
3463 for(Teuchos::Array<SC>::size_type j = 0; j < num_entries; ++j)
3464 vals_ar[j] =
static_cast<SC
>(this->_mat_val[
static_cast<VGS
>(entries_start + j)]);
3466 Teuchos::Array<GO> cols(num_entries);
3467 for(Teuchos::Array<GO>::size_type j = 0; j < num_entries; ++j)
3468 cols[j] =
static_cast<GO
>(this->_col_idx_mapped[entries_start + j]);
3470 _matrix->replaceGlobalValues(
static_cast<GO
>(_first_owned_velo_dof + row),
3471 cols.view(0,
static_cast<AGS
>(num_entries)),
3472 vals_ar.view(0,
static_cast<Teuchos::Array<SC>::size_type
>(num_entries)));
3474 entries_start += num_entries;
3478 for(IndexType row(0); row < _num_owned_pres_dofs; ++row)
3480 const auto num_entries =
static_cast<Teuchos::Array<SC>::size_type
>(_num_nze[
static_cast<AGS
>(_num_owned_velo_dofs+row)]);
3483 Teuchos::Array<SC> vals_ar(num_entries);
3484 for(Teuchos::Array<SC>::size_type j = 0; j < num_entries; ++j)
3485 vals_ar[j] =
static_cast<SC
>(this->_mat_val[
static_cast<VGS
>(entries_start + j)]);
3487 Teuchos::Array<GO> cols(num_entries);
3488 for(Teuchos::Array<GO>::size_type j = 0; j < num_entries; ++j)
3489 cols[j] =
static_cast<GO
>(this->_col_idx_mapped[entries_start + j]);
3491 _matrix->replaceGlobalValues(
static_cast<GO
>(_num_global_velo_dofs + _first_owned_pres_dof + row),
3492 cols.view(0,
static_cast<AGS
>(num_entries)),
3493 vals_ar.view(0,
static_cast<Teuchos::Array<SC>::size_type
>(num_entries)));
3495 entries_start += num_entries;
3498 _matrix->fillComplete();
3500 if(this->_use_timer)
3502 this->_stacked_timer->stop(
"TpetraCoreStokes::init_numeric");
3507 void* create_core_stokes(
const void* comm, Index num_global_dofs, Index my_dof_offset, Index num_owned_dofs, Index num_nonzeros,
3508 IndexType num_owned_velo_dofs, IndexType num_owned_pres_dofs, IndexType first_owned_velo_dof,
3509 IndexType first_owned_pres_dof, IndexType num_global_velo_dofs, IndexType num_global_pres_dofs,
const Trilinos::FROSchParameterList & params)
3511 return new TpetraCoreStokes(comm, num_global_dofs, my_dof_offset, num_owned_dofs, num_nonzeros, num_owned_velo_dofs, num_owned_pres_dofs, first_owned_velo_dof, first_owned_pres_dof, num_global_velo_dofs, num_global_pres_dofs, params);
3518 typedef struct FROSchPrecond
3520 using SC = TpetraCoreBase::SC;
3521 Teuchos::RCP<Thyra::PreconditionerFactoryBase<SC>> pfbFactory;
3522 Teuchos::RCP<const Thyra::LinearOpBase<SC>> K_thyra;
3523 Teuchos::RCP<Thyra::PreconditionerBase<SC>> ThyraPrec;
3527 void* create_frosch(
void* cr)
3529 using SC = TpetraCoreBase::SC;
3530 using LO = TpetraCoreBase::LO;
3531 using GO = TpetraCoreBase::GO;
3532 using NO = TpetraCoreBase::NO;
3534 TpetraCoreBase *core =
reinterpret_cast<TpetraCoreBase*
>(cr);
3536 Stratimikos::DefaultLinearSolverBuilder linearSolverBuilder;
3537 Stratimikos::enableFROSch<SC, LO, GO, NO>(linearSolverBuilder);
3539 linearSolverBuilder.setParameterList(core->_params);
3541 Teuchos::RCP<Thyra::PreconditionerFactoryBase<SC>> pfbFactory = linearSolverBuilder.createPreconditioningStrategy(
"");
3543 if(core->_use_timer)
3545 Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
3546 pfbFactory->setOStream(out);
3547 pfbFactory->setVerbLevel(Teuchos::VERB_HIGH);
3551 Teuchos::RCP<const Tpetra::RowMatrix<SC, LO, GO, NO>> tpRowMat = Teuchos::rcp_dynamic_cast<const Tpetra::RowMatrix<SC, LO, GO, NO>>(core->_matrix,
true);
3552 Teuchos::RCP<const Tpetra::Operator<SC, LO, GO, NO>> tpOperator = Teuchos::rcp_dynamic_cast<const Tpetra::Operator<SC, LO, GO, NO>> (tpRowMat,
true);
3570 FROSchPrecond *precond =
new FROSchPrecond;
3571 precond->pfbFactory = pfbFactory;
3572 precond->K_thyra = Thyra::createConstLinearOp(tpOperator);
3573 precond->ThyraPrec = Thyra::prec(*pfbFactory, precond->K_thyra);
3578 void reinit_frosch(
void *pre)
3580 using SC = TpetraCoreBase::SC;
3581 FROSchPrecond *precond =
reinterpret_cast<FROSchPrecond *
>(pre);
3582 Thyra::initializePrec<SC>(*(precond->pfbFactory), precond->K_thyra, precond->ThyraPrec.ptr());
3585 void destroy_frosch(
void *pre)
3590 FROSchPrecond *precond =
reinterpret_cast<FROSchPrecond*
>(pre);
3594 void solve_frosch(
void* cr,
void* pre)
3596 using SC = TpetraCoreBase::SC;
3597 using LO = TpetraCoreBase::LO;
3598 using GO = TpetraCoreBase::GO;
3599 using NO = TpetraCoreBase::NO;
3601 TpetraCoreBase *core =
reinterpret_cast<TpetraCoreBase *
>(cr);
3602 FROSchPrecond *fprecond =
reinterpret_cast<FROSchPrecond *
>(pre);
3605 auto thyTpMap = Thyra::tpetraVectorSpace<SC, LO, GO, NO>(core->_vec_cor->getMap());
3606 auto thyDomMap = Thyra::tpetraVectorSpace<SC, LO, GO, NO>(Tpetra::createLocalMapWithNode<LO, GO, NO>(core->_vec_cor->getNumVectors(), core->_vec_cor->getMap()->getComm()) );
3607 auto thyra_X = Teuchos::rcp(
new Thyra::TpetraMultiVector<SC, LO, GO, NO>());
3608 thyra_X->initialize(thyTpMap, thyDomMap, core->_vec_cor);
3610 thyTpMap = Thyra::tpetraVectorSpace<SC, LO, GO, NO>(core->_vec_def->getMap());
3611 thyDomMap = Thyra::tpetraVectorSpace<SC, LO, GO, NO>(Tpetra::createLocalMapWithNode<LO, GO, NO>(core->_vec_def->getNumVectors(), core->_vec_def->getMap()->getComm()) );
3612 auto thyra_B = Teuchos::rcp(
new Thyra::TpetraMultiVector<SC, LO, GO, NO>());
3613 thyra_B->initialize(thyTpMap, thyDomMap, core->_vec_def);
3619 Teuchos::RCP<Thyra::LinearOpBase<SC>> LinearPrecOp = fprecond->ThyraPrec->getNonconstUnspecifiedPrecOp();
3620 Thyra::apply<SC>(*LinearPrecOp, Thyra::NOTRANS, *(thyra_B.getConst()), thyra_X.ptr());
3628void dummy_frosch_function() {}
#define XASSERT(expr)
Assertion macro definition.
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
std::uint64_t Index
Index data type.