FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
frosch.hpp
1#pragma once
2
3// includes, FEAT
5#include <kernel/util/simple_arg_parser.hpp>
6#include <kernel/solver/adp_solver_base.hpp>
7
8#if defined(FEAT_HAVE_TRILINOS) || defined(DOXYGEN)
9
10#ifndef FEAT_HAVE_MPI
11# error FROSch without MPI does not make sense.
12#endif
13
14// includes, system
15#include <vector>
16#include <regex>
17
18namespace FEAT
19{
20 namespace Solver
21 {
23 namespace Trilinos
24 {
50 class FROSchParameterList
51 {
52 public:
53 /* Use MUMPS or UMFPACK or ILU */
54 enum DirectSolver {
55 KLU, /* Trilinos internal solver: works always */
56 MUMPS, /* Trilinos needs to be compiled with Amesos2 and Mumps */
57 UMFPACK, /* Trilinos needs to be compiled with Amesos2 and Umfpack */
58 ILU /* Trilinos needs to be compiled with Ifpack2 */
59 };
60 /* Normally, use TWOLEVELBLOCK */
61 enum Preconditioner {
62 ONELEVEL, /* one-level overlapping schwarz; just for testing */
63 TWOLEVEL, /* works only for pressure Poisson and two-level neither for multi-level pressure Poisson nor for the saddle point problem */
64 TWOLEVELBLOCK /* works for pressure Poisson (two-level and multi-level) and the saddle point problem (two-level and multi-level) */
65 };
66
67 enum ProblemType {
68 PRESSUREPOISSON,
69 SADDLEPOINT
70 };
71
72 enum PartitionType {
73 PHG, /* Parallel hyper-graph, Zoltan */
74 PARMETIS, /* Trilinos needs to be compiled with Parmetis */
75 BLOCK, /* Should work always (not good) */
76 SCOTCH, /* Scotch */
77 PTSCOTCH /* Scotch */
78 };
79
80 enum PartitionApproach {
81 PARTITION,
82 REPARTITION /* probably the best, but I'm not sure */
83 };
84
85 enum CombineOverlap {
86 FULL, /* produces a symmetric preconditioner */
87 RESTRICTED, /* __ATTENTION:__ produces a non-symmetric preconditioner. As default: Restricted with (F)GMRES should work better than FULL with PCG. */
88 AVERAGING /* __ATTENTION:__ produces a non-symmetric preconditioner. Should work better than FULL with PCG. */
89 };
90
91 enum CombineLevel {
92 ADDITIVE, /* Combine first and second level in an additive way */
93 MULTIPLICATIVE /* Combine first and second level in a multiplicative way: __ATTENTION:__ this leads to an unsymmetric preconditioner */
94 };
95
96 /* interface partition of unity
97 *
98 * Normally:
99 * velocity:
100 * In 2D use GDSW.
101 * In 3D use GDSWSTAR.
102 * pressure:
103 * Use GDSW, but for discont. pressure it does not matter which is choosen
104 *
105 */
106 enum IPOU {
107 GDSW,
108 GDSWSTAR, /* Only for three dimensional problems */
109 RGDSW
110 };
111
137 explicit FROSchParameterList(const Dist::Comm& comm_, const int dim_, const FROSchParameterList::ProblemType problem_, const int nlevels_ = 1, const std::string& name_ = "FEAT-FROSch Parameterlist");
138
159 explicit FROSchParameterList(const Dist::Comm& comm_, const int dim_, const std::string& xml_file_, const std::string& name_ = "Parameter List");
160 ~FROSchParameterList();
161
162 void read_from_xml_str(const std::string &xml_str_);
163 void read_from_xml_file(const std::string &xml_file_);
164
165 /* Print parameter list to rank zero */
166 void print() const;
167
168 /* return a pointer to the core */
169 void* get_core() const;
170
171 void create_core();
172 void delete_core();
173
174 int get_dim() const;
175 int get_dpe_velo() const;
176 int get_dpe_pres() const;
177 int get_nlevels() const;
178 bool get_use_timer() const;
179 bool get_print() const;
180
181 void set_dim(const int dim);
182 void set_nlevels(const int nlevels);
183 void set_problem_type(const ProblemType problem_);
184 void set_use_timer(const bool use_timer_);
185 void set_print(const bool print_);
186
187 void set_precond(const Preconditioner precond_);
188 void set_coarse_solver(const DirectSolver solver_);
189
190 void set_gsteps(const int gsteps_);
191 void set_gsteps(const std::vector<int>& gsteps_);
192
193 void set_overlaps(const int overlap_);
194 void set_overlaps(const std::vector<int>& overlaps_);
195
196 void set_combine_overlap(const CombineOverlap combine_mode_);
197 void set_combine_overlap(const std::vector<CombineOverlap>& combine_mode_);
198
199 void set_combine_lvl(const CombineLevel combine_mode_);
200 void set_combine_lvl(const std::vector<CombineLevel>& combine_lvl_);
201
202 void set_solvers(const DirectSolver solver_ao_, const DirectSolver solver_ext_);
203 void set_solvers(const std::vector<DirectSolver>& solvers_ao_, const std::vector<DirectSolver>& solvers_ext_);
204 void set_solvers_ao(const DirectSolver solver_);
205 void set_solvers_ao(const std::vector<DirectSolver>& solvers_);
206 void set_solvers_ext(const DirectSolver solver_);
207 void set_solvers_ext(const std::vector<DirectSolver>& solvers_);
208
209 void set_paritioner(const std::vector<int>& subregions_, const PartitionType parti_type_, const PartitionApproach parti_approach_, const double parti_imbl_);
210 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_);
211
212 void set_subregions(const std::vector<int>& subregions_);
213
214 void set_parti_types(const PartitionType parti_type_);
215 void set_parti_types(const std::vector<PartitionType>& parti_types_);
216
217 void set_parti_approach(const PartitionApproach parti_approach_);
218 void set_parti_approach(const std::vector<PartitionApproach>& parti_approach_);
219
220 void set_parti_imbl(const double parti_imbl_);
221 void set_parti_imbl(const std::vector<double>& parti_imbl_);
222
223 void set_excludes(const bool velo_pres_, const bool pres_velo_);
224 void set_excludes(const std::vector<bool>& velo_pres_, const std::vector<bool>& pres_velo_);
225 void set_excludes_velo_pres(const bool velo_pres_);
226 void set_excludes_velo_pres(const std::vector<bool>& velo_pres_);
227 void set_excludes_pres_velo(const bool pres_velo_);
228 void set_excludes_pres_velo(const std::vector<bool>& pres_velo_);
229
230 void set_ipous(const IPOU ipou_velo_, const IPOU ipou_pres_);
231 void set_ipous(const std::vector<IPOU>& ipous_velo_, const std::vector<IPOU>& ipous_pres_);
232 void set_ipous_velo(const IPOU ipou_);
233 void set_ipous_velo(const std::vector<IPOU>& ipous_);
234 void set_ipous_pres(const IPOU ipou_);
235 void set_ipous_pres(const std::vector<IPOU>& ipous_);
236
237 void set_cspace(const bool cspace_velo_, const bool cspace_pres_);
238 void set_cspace(const std::vector<bool>& cspace_velo_, const std::vector<bool>& cspace_pres_);
239 void set_cspace_velo(const bool cspace_);
240 void set_cspace_velo(const std::vector<bool>& cspace_);
241 void set_cspace_pres(const bool cspace_);
242 void set_cspace_pres(const std::vector<bool>& cspace_);
243
244 void set_reuse_sf(const bool rsf_ao_, const bool rsf_cm_);
245 void set_reuse_sf(const std::vector<bool> &rsf_ao_, const std::vector<bool> &rsf_cm_);
246 void set_reuse_sf_ao(const bool rsf_ao_);
247 void set_reuse_sf_ao(const std::vector<bool> &rsf_ao_);
248 void set_reuse_sf_cm(const bool rsf_cm_);
249 void set_reuse_sf_cm(const std::vector<bool> &rsf_cm_);
250
251 void set_reuse_coarse(const bool reuse_cm_, const bool reuse_cb_);
252 void set_reuse_coarse(const std::vector<bool> &reuse_cm_, const std::vector<bool> &reuse_cb_);
253 void set_reuse_coarse_matrix(const bool reuse_cm_);
254 void set_reuse_coarse_matrix(const std::vector<bool> &reuse_cm_);
255 void set_reuse_coarse_basis(const bool reuse_cb_);
256 void set_reuse_coarse_basis(const std::vector<bool> &reuse_cb_);
257
258 void set_phi_dropping_threshold(const double phi_dt_);
259 void set_phi_dropping_threshold(const std::vector<double> &phi_dt_);
260
261 void set_verbose(const bool verbose_);
262
263 bool parse_args(SimpleArgParser& args);
264
265 protected:
268 void* _core;
269
270 /* for parsing of arguments */
271 const Dist::Comm& _comm;
272
273 /* spatial dimensios */
274 int _dimension;
275 /* dofs per entity (velocity) */
276 int _dpe_velo;
277 /* dofs per pressure (velocity) */
278 int _dpe_pres;
279
280 /* Number of levels (Domain Decomposition levels) before the coarse problem is solved
281 *
282 * For example:
283 * The two-level preconditioner has _nlevels = 1
284 * The three-level preconditioner has _nlevels = 2
285 * */
286 int _nlevels;
287
288 ProblemType _problem;
289 Preconditioner _preconditioner;
290 DirectSolver _solver_coarse;
291
292 std::vector<int> _gsteps;
293
294 std::vector<int> _overlaps;
295 std::vector<DirectSolver> _solvers_ao;
296 std::vector<DirectSolver> _solvers_ext;
297
298 /* __ATTENTION:__ the last entry has to be one */
299 std::vector<int> _subregions;
300 std::vector<PartitionType> _partition_types;
301 std::vector<PartitionApproach> _partition_approach;
302 std::vector<double> _partition_imbl_tol;
303
304 /* exclude blocks for the coarse space:
305 *
306 * _exclude_velo_pres: exclude the velocity-pressure coupling
307 * _exclude_pres_velo: exclude the pressure-velocity coupling
308 */
309 std::vector<bool> _exclude_pres_velo;
310 std::vector<bool> _exclude_velo_pres;
311 /*
312 * use block for coarse space. Normally, set this both to true.
313 */
314 std::vector<bool> _cspace_velo;
315 std::vector<bool> _cspace_pres;
316 /* interface partition of unity for blocks */
317 std::vector<IPOU> _ipous_velo;
318 std::vector<IPOU> _ipous_pres;
319
320 /* combine mode of overlap */
321 std::vector<CombineOverlap> _combine_ov;
322
323 /* combine mode of lvl */
324 std::vector<CombineLevel> _combine_lvl;
325
326 /* reuse symbolic factorization: algebraic overlapping Operator */
327 std::vector<bool> _ao_rsf;
328 /* reuse symbolic factorization: coarse matrix */
329 std::vector<bool> _cm_rsf;
330
331 /* reuse the complete coarse matrix */
332 std::vector<bool> _cm_r;
333 /* reuse the complete coarse basis */
334 std::vector<bool> _cb_r;
335 /* Phi: Dropping Threshold ==> default 1.e-8.
336 * The higher the dropping threshold the more Krylov iterations
337 * but the faster the construction of the coarse basis */
338 std::vector<double> _phi_dt;
339
340 std::string _name;
341
342 /* print the parameter list after construction */
343 bool _print_list;
344 /* use Trilinos timers for FROSch solver */
345 bool _use_timer;
346
347 /* verbose flag for the FROSch/Trilinos class */
348 bool _verbose;
349
350 void init_defaults();
351
352 }; // FROSchParameterList
353
354 inline void add_supported_fpl_args(SimpleArgParser& args)
355 {
356 args.support("frosch-plist", "<XML file>\n"
357 "The frosch parameter list as a Trilinos parameter list.\n"
358 "__ATTENTION:__ If this option is given, then all the other options are ignored.\n"
359 "May contain the following types: XML file path."
360 );
361 args.support("frosch-print-list", "<bool>\n"
362 "The Trilinos parameter list is print after the construction.\n"
363 "May contain the following types: true, false."
364 );
365 args.support("frosch-verbose", "<bool>\n"
366 "The Trilinos/FROSch verbose. Print output of FROSch.\n"
367 "May contain the following types: true, false."
368 );
369 args.support("frosch-use-timer", "<bool>\n"
370 "Use the Trilinos timers for FROSch solver\n"
371 "May contain the following types: true, false."
372 );
373 args.support("frosch-nlevels", "<int>\n"
374 "Specifies the (additional) number of levels.\n"
375 "__ATTENTION:__ The used number of levels are one more, since the coarsest level is not counted.\n"
376 " Therefore, two-level overlapping Schwarz has nlevels == 1.\n"
377 "May contain the following types: int > 0"
378 );
379 args.support("frosch-dim", "<int>\n"
380 "Specifies the (spatial) dimension.\n"
381 "May contain the following types: int > 0"
382 );
383 args.support("frosch-overlap", "<int | int...>\n"
384 "Specifies which number of overlaps are used.\n"
385 "Number of arguments has be one or same as the value of the argument: frosch-nlevels (int).\n"
386 "May contain the following types: int > 0\n"
387 "Default is 1."
388 );
389 args.support("frosch-subreg", "<int | int...>\n"
390 "Specifies number of subregions for multi-level approach.\n"
391 "Number of arguments has same as the value of the argument: frosch-nlevels (int).\n"
392 "The last entry has to be one.\n"
393 "May contain the following types: int > 0"
394 );
395 args.support("frosch-gstep", "<int | int...>\n"
396 "Specifies number of gathering steps for the coarse problem.\n"
397 "Number of arguments has same as the value of the argument: frosch-nlevels (int).\n"
398 "May contain the following types: int > 0"
399 );
400 args.support("frosch-parti-type", "<types | types...>\n"
401 "Specifies the paritioner for multi-level approach.\n"
402 "Number of arguments has be one or same as the value of the argument: frosch-nlevels (int).\n"
403 "May contain the following types: block, parmetis, phg, zoltan, scotch, ptscotch"
404 );
405 args.support("frosch-parti-approach", "<types | types...>\n"
406 "Specifies the paritioner approach for multi-level approach.\n"
407 "Only used when parmetis partitioning is used\n."
408 "Number of arguments has be one or same as the value of the argument: frosch-nlevels (int).\n"
409 "May contain the following types: partition, repartition."
410 );
411 args.support("frosch-parti-imbl", "<double | double...>\n"
412 "Specifies the paritioner imblance for multi-level approach.\n"
413 "Number of arguments has be one or same as the value of the argument: frosch-nlevels (int).\n"
414 "May contain the following types: double > 1."
415 );
416 args.support("frosch-ipou-pres", "<types | types...>\n"
417 "Specifies the interface partition of unity for the pressure space.\n"
418 "Number of arguments has be one or same as the value of the argument: frosch-nlevels (int).\n"
419 "May contain the following types: gdsw, gdswstar, rgdsw."
420 );
421 args.support("frosch-ipou-velo", "<types | types...>\n"
422 "Specifies the interface partition of unity for the velocity space.\n"
423 "Number of arguments has be one or same as the value of the argument: frosch-nlevels (int).\n"
424 "May contain the following types: gdsw, gdswstar, rgdsw."
425 );
426 args.support("frosch-solver-ao", "<types | types...>\n"
427 "Specifies the overlapping direct solver.\n"
428 "Number of arguments has be one or same as the value of the argument: frosch-nlevels (int).\n"
429 "May contain the following types: klu, mumps, umfpack."
430 );
431 args.support("frosch-solver-ext", "<types | types...>\n"
432 "Specifies the extension direct solver.\n"
433 "Number of arguments has be one or same as the value of the argument: frosch-nlevels (int).\n"
434 "May contain the following types: klu, mumps, umfpack."
435 );
436 args.support("frosch-solver-coarse", "<types>\n"
437 "Specifies the coarse direct solver.\n"
438 "May contain the following types: klu, mumps, umfpack."
439 );
440 args.support("frosch-precond-type", "<types>\n"
441 "Specifies FROSch preconditioner type.\n"
442 "May contain the following types: onelevel, twolevel, twolevelblock."
443 );
444 args.support("frosch-cspace-pres", "<bool | bool...>\n"
445 "Specifies the use of the pressure for the coarse space (monolithic only).\n"
446 "Number of arguments has be one or same as the value of the argument: frosch-nlevels (int).\n"
447 "May contain the following types: true, false."
448 );
449 args.support("frosch-cspace-velo", "<bool | bool...>\n"
450 "Specifies the use of the velocity for the coarse space (monolithic only).\n"
451 "Number of arguments has be one or same as the value of the argument: frosch-nlevels (int).\n"
452 "May contain the following types: true, false."
453 );
454 args.support("frosch-exclude-velo-pres", "<bool | bool...>\n"
455 "Exclude the velocity-pressure coupling in coarse space (monolithic only).\n"
456 "Number of arguments has be one or same as the value of the argument: frosch-nlevels (int).\n"
457 "May contain the following types: true, false."
458 );
459 args.support("frosch-exclude-pres-velo", "<bool | bool...>\n"
460 "Exclude the pressure-velocity coupling in coarse space (monolithic only).\n"
461 "Number of arguments has be one or same as the value of the argument: frosch-nlevels (int).\n"
462 "May contain the following types: true, false."
463 );
464 args.support("frosch-combine-overlap", "<types | types...>\n"
465 "Combine mode of the overlap.\n"
466 "Number of arguments has be one or same as the value of the argument: frosch-nlevels (int).\n"
467 "May contain the following types: full, restricted, averaging."
468 );
469 args.support("frosch-combine-lvl", "<types | types...>\n"
470 "Combine mode of the different levels.\n"
471 "Number of arguments has be one or same as the value of the argument: frosch-nlevels (int).\n"
472 "May contain the following types: additive, multiplicative"
473 );
474 args.support("frosch-reuse-sf-ao", "<bool | bool...>\n"
475 "Reuse the symbolic factorization of the algebraic overlapping operator.\n"
476 "Number of arguments has be one or same as the value of the argument: frosch-nlevels (int).\n"
477 "May contain the following types: true, false"
478 );
479 args.support("frosch-reuse-sf-cm", "<bool | bool...>\n"
480 "Reuse the symbolic factorization of the coarse matrix.\n"
481 "Number of arguments has be one or same as the value of the argument: frosch-nlevels (int).\n"
482 "May contain the following types: true, false"
483 );
484 args.support("frosch-reuse-coarse-matrix", "<bool | bool...>\n"
485 "Reuse the complete coarse matrix.\n"
486 "Number of arguments has be one or same as the value of the argument: frosch-nlevels (int).\n"
487 "May contain the following types: true, false"
488 );
489 args.support("frosch-reuse-coarse-basis", "<bool | bool...>\n"
490 "Reuse the coarse basis functions.\n"
491 "Number of arguments has be one or same as the value of the argument: frosch-nlevels (int).\n"
492 "May contain the following types: true, false"
493 );
494 args.support("frosch-phi-dropping-threshold", "<double | double...>\n"
495 "Dropping threshold for the coarse matrix.\n"
496 "Number of arguments has be one or same as the value of the argument: frosch-nlevels (int).\n"
497 "May contain the following types: double > 0."
498 );
499 }
500
501 inline std::shared_ptr<FROSchParameterList> init_params_two_level_pressure_poisson(const Dist::Comm& comm_,
502 const int dim_,
503 const int overlap_,
504 const FROSchParameterList::IPOU ipou_pres_ = FROSchParameterList::GDSW,
505 const FROSchParameterList::DirectSolver solver_ao_ = FROSchParameterList::KLU,
506 const FROSchParameterList::DirectSolver solver_ext_ = FROSchParameterList::KLU,
507 const FROSchParameterList::DirectSolver solver_coarse_ = FROSchParameterList::KLU,
508 const FROSchParameterList::Preconditioner precond_ = FROSchParameterList::TWOLEVELBLOCK,
509 const FROSchParameterList::CombineOverlap mode_ = FROSchParameterList::RESTRICTED,
510 const bool use_timer_ = false,
511 const bool print_list_ = false)
512 {
513 std::shared_ptr<FROSchParameterList> params = std::make_shared<FROSchParameterList>(comm_, dim_, FROSchParameterList::PRESSUREPOISSON);
514 params->set_overlaps(overlap_);
515 /* IPOU for velocity will not be used, set it anyway */
516 params->set_ipous(FROSchParameterList::GDSW, ipou_pres_);
517 params->set_solvers(solver_ao_, solver_ext_);
518 params->set_coarse_solver(solver_coarse_);
519 params->set_precond(precond_);
520 params->set_combine_overlap(mode_);
521 params->set_use_timer(use_timer_);
522 params->set_print(print_list_);
523
524 params->set_cspace(true, true);
525 /* Will not be used, set it anyway */
526 params->set_excludes(false, false);
527 params->set_paritioner(std::vector<int>(1, 1),
528 Solver::Trilinos::FROSchParameterList::PARMETIS, /* DUMMY NOT USED, since std::vector<int>(1, 1) */
529 Solver::Trilinos::FROSchParameterList::REPARTITION, /* DUMMY NOT USED, since std::vector<int>(1, 1) */
530 1.1 /* DUMMY NOT USED, since std::vector<int>(1, 1) */);
531 return params;
532 }
533
534 inline std::shared_ptr<FROSchParameterList> init_params_three_level_pressure_poisson(const Dist::Comm& comm_,
535 const int dim_,
536 const int overlap_,
537 const int nsubreg_,
538 const FROSchParameterList::PartitionType parti_type_ = FROSchParameterList::PARMETIS,
539 const FROSchParameterList::PartitionApproach parti_approach_ = FROSchParameterList::REPARTITION,
540 const double parti_imbl_ = 1.1,
541 const FROSchParameterList::IPOU ipou_pres_ = FROSchParameterList::GDSW,
542 const FROSchParameterList::DirectSolver solver_ao_ = FROSchParameterList::KLU,
543 const FROSchParameterList::DirectSolver solver_ext_ = FROSchParameterList::KLU,
544 const FROSchParameterList::DirectSolver solver_coarse_ = FROSchParameterList::KLU,
545 const FROSchParameterList::Preconditioner precond_ = FROSchParameterList::TWOLEVELBLOCK,
546 const FROSchParameterList::CombineOverlap mode_ = FROSchParameterList::RESTRICTED,
547 const bool use_timer_ = false,
548 const bool print_list_ = false)
549 {
550 std::shared_ptr<FROSchParameterList> params = std::make_shared<FROSchParameterList>(comm_, dim_, FROSchParameterList::PRESSUREPOISSON, 2);
551 params->set_overlaps(overlap_);
552 params->set_paritioner(std::vector<int>({nsubreg_, 1}), parti_type_, parti_approach_, parti_imbl_);
553 /* IPOU for velocity will not be used, set it anyway */
554 params->set_ipous(FROSchParameterList::GDSW, ipou_pres_);
555 params->set_solvers(solver_ao_, solver_ext_);
556 params->set_coarse_solver(solver_coarse_);
557 params->set_precond(precond_);
558 params->set_combine_overlap(mode_);
559 params->set_use_timer(use_timer_);
560 params->set_print(print_list_);
561
562 params->set_cspace(true, true);
563 /* Will not be used, set it anyway */
564 params->set_excludes(false, false);
565 return params;
566 }
567
568 inline std::shared_ptr<FROSchParameterList> init_params_two_level_monolithic(const Dist::Comm& comm_,
569 const int dim_,
570 const int overlap_,
571 const FROSchParameterList::IPOU ipou_velo_ = FROSchParameterList::GDSW,
572 const FROSchParameterList::IPOU ipou_pres_ = FROSchParameterList::GDSW,
573 const FROSchParameterList::DirectSolver solver_ao_ = FROSchParameterList::KLU,
574 const FROSchParameterList::DirectSolver solver_ext_ = FROSchParameterList::KLU,
575 const FROSchParameterList::DirectSolver solver_coarse_ = FROSchParameterList::KLU,
576 const bool excl_velo_pres_ = false,
577 const bool excl_pres_velo_ = false,
578 const FROSchParameterList::CombineOverlap mode_ = FROSchParameterList::RESTRICTED,
579 const bool use_timer_ = false,
580 const bool print_list_ = false)
581 {
582 std::shared_ptr<FROSchParameterList> params = std::make_shared<FROSchParameterList>(comm_, dim_, FROSchParameterList::PRESSUREPOISSON);
583 params->set_overlaps(overlap_);
584 params->set_ipous(ipou_velo_, ipou_pres_);
585 params->set_solvers(solver_ao_, solver_ext_);
586 params->set_coarse_solver(solver_coarse_);
587 params->set_excludes(excl_velo_pres_, excl_pres_velo_);
588 params->set_combine_overlap(mode_);
589 params->set_use_timer(use_timer_);
590 params->set_print(print_list_);
591
592 params->set_precond(FROSchParameterList::TWOLEVELBLOCK);
593 params->set_cspace(true, true);
594 params->set_paritioner(std::vector<int>(1, 1),
595 Solver::Trilinos::FROSchParameterList::PARMETIS, /* DUMMY NOT USED, since std::vector<int>(1, 1) */
596 Solver::Trilinos::FROSchParameterList::REPARTITION, /* DUMMY NOT USED, since std::vector<int>(1, 1) */
597 1.1 /* DUMMY NOT USED, since std::vector<int>(1, 1) */);
598 return params;
599 }
600
601 inline std::shared_ptr<FROSchParameterList> init_params_three_level_monolithic(const Dist::Comm& comm_,
602 const int dim_,
603 const int overlap_,
604 const int nsubreg_,
605 const FROSchParameterList::PartitionType parti_type_ = FROSchParameterList::PARMETIS,
606 const FROSchParameterList::PartitionApproach parti_approach_ = FROSchParameterList::REPARTITION,
607 const double parti_imbl_ = 1.1,
608 const FROSchParameterList::IPOU ipou_velo_ = FROSchParameterList::GDSW,
609 const FROSchParameterList::IPOU ipou_pres_ = FROSchParameterList::GDSW,
610 const FROSchParameterList::DirectSolver solver_ao_ = FROSchParameterList::KLU,
611 const FROSchParameterList::DirectSolver solver_ext_ = FROSchParameterList::KLU,
612 const FROSchParameterList::DirectSolver solver_coarse_ = FROSchParameterList::KLU,
613 const bool excl_velo_pres_ = false,
614 const bool excl_pres_velo_ = false,
615 const FROSchParameterList::CombineOverlap mode_ = FROSchParameterList::RESTRICTED,
616 const bool use_timer_ = false,
617 const bool print_list_ = false)
618 {
619 std::shared_ptr<FROSchParameterList> params = std::make_shared<FROSchParameterList>(comm_, dim_, FROSchParameterList::PRESSUREPOISSON, 2);
620 params->set_overlaps(overlap_);
621 params->set_paritioner(std::vector<int>({nsubreg_, 1}), parti_type_, parti_approach_, parti_imbl_);
622 params->set_ipous(ipou_velo_, ipou_pres_);
623 params->set_solvers(solver_ao_, solver_ext_);
624 params->set_coarse_solver(solver_coarse_);
625 params->set_excludes(excl_velo_pres_, excl_pres_velo_);
626 params->set_combine_overlap(mode_);
627 params->set_use_timer(use_timer_);
628 params->set_print(print_list_);
629
630 params->set_precond(FROSchParameterList::TWOLEVELBLOCK);
631 params->set_cspace(true, true);
632 return params;
633 }
634
666 void* create_core_scalar(const void* comm, Index num_global_dofs, Index my_dof_offset,
667 Index num_owned_dofs, Index num_nonzeros, const FROSchParameterList & params);
668
669 // Trilinos FROSch Stokes
670 void* create_core_stokes(const void* comm, Index num_global_dofs, Index my_dof_offset,
671 Index num_owned_dofs, Index num_nonzeros, Index num_owned_velo_dofs, Index num_owned_pres_dofs,
672 Index first_owned_velo_dof, Index first_owned_pres_dof,
673 Index num_global_velo_dofs, Index num_global_pres_dofs,
674 const Trilinos::FROSchParameterList & params);
675
676 void destroy_core(void* core);
677
678 void set_parameter_list(void* core, const FROSchParameterList & params);
679
680 void init_symbolic(void* core);
681 void init_numeric(void* core);
682
683 std::int64_t* get_row_ptr(void* core);
684 std::int32_t* get_col_idx(void* core);
685 double* get_mat_val(void* core);
686 double* get_vec_def(void* core);
687 double* get_vec_cor(void* core);
688 void format_vec_cor(void* core);
689
690 // FROSch Wrappers
691 void* create_frosch(void* core);
692 void reinit_frosch(void *core);
693 void compute_frosch(void *solver);
694 void destroy_frosch(void* solver);
695 void solve_frosch(void* core, void* solver);
696
697 } // namespace Trilinos
699
713 template<typename Matrix_, typename Filter_, typename SolverBase_ = Solver::SolverBase<typename Matrix_::VectorTypeL>>
715 public ADPSolverBase<Matrix_, Filter_, SolverBase_>
716 {
717 public:
720 // the vector type
721 typedef typename BaseClass::VectorType VectorType;
722
723 protected:
725 void* _core;
726 const Trilinos::FROSchParameterList& _params;
727
728 explicit TpetraSolverBase(const Matrix_& matrix, const Filter_& filter, const Trilinos::FROSchParameterList & params) :
729 BaseClass(matrix, filter),
730 _core(nullptr),
731 _params(params)
732 {
733 }
734
744 void _upload_def(const VectorType& vec_def)
745 {
746 this->_upload_vector(Trilinos::get_vec_def(this->_core), vec_def.local());
747 }
748
753 {
754 // format Tpetra correction vector
755 Trilinos::format_vec_cor(this->_core);
756 }
757
767 void _download_cor(VectorType& vec_cor)
768 {
769 this->_download_vector(vec_cor.local(), Trilinos::get_vec_cor(this->_core));
770
771 // apply correction filter
772 this->_system_filter.filter_cor(vec_cor);
773 }
774
775 public:
782 virtual void init_numeric() override
783 {
785
786 XASSERT(this->_core != nullptr);
787
788 // update matrix values of Trilinos matrix
789 this->_upload_numeric(Trilinos::get_mat_val(this->_core),
790 Trilinos::get_row_ptr(this->_core), Trilinos::get_col_idx(this->_core));
791
792 Trilinos::init_numeric(this->_core);
793 }
794
801 virtual void done_symbolic() override
802 {
803 XASSERT(this->_core != nullptr);
804
805 Trilinos::destroy_core(this->_core);
806 this->_core = nullptr;
807
809 }
810 }; // class TpetraSolverBase<...>
811
821 template<typename Matrix_, typename Filter_>
823 public TpetraSolverBase<Matrix_, Filter_>
824 {
825 public:
829 typedef typename BaseClass::VectorType VectorType;
830
831 protected:
833 void* _solver;
834
835 public:
836 explicit FROSchPreconditioner(const Matrix_& matrix, const Filter_& filter, const Trilinos::FROSchParameterList & params) :
837 BaseClass(matrix, filter, params),
838 _solver(nullptr)
839 {
840 }
841
842 explicit FROSchPreconditioner(const String& DOXY(section_name), PropertyMap* DOXY(section),
843 const Matrix_& matrix, const Filter_& filter)
844 :
845 FROSchPreconditioner(matrix, filter)
846 {
848 }
849
850 virtual String name() const override
851 {
852 return "FROSchPreconditioner";
853 }
854
864 virtual void init_symbolic() override
865 {
867
868 XASSERT(this->_core == nullptr);
869
870 // create our Tpetra core wrapper object
871 this->_core = Trilinos::create_core_scalar(
872 &this->_get_comm()->mpi_comm(),
873 this->_get_num_global_dofs(),
875 this->_get_num_owned_dofs(),
877 this->_params);
878
879 BaseClass::_upload_symbolic(Trilinos::get_row_ptr(this->_core), Trilinos::get_col_idx(this->_core));
880
881 Trilinos::init_symbolic(this->_core);
882 }
883
884 virtual void init_numeric() override
885 {
887
888 // create FROSchPreconditioner
889 if(_solver == nullptr)
890 {
891 this->_solver = Trilinos::create_frosch(this->_core);
892 }
893 else
894 {
895 Trilinos::reinit_frosch(this->_solver);
896 }
897 }
898
899 virtual void done_numeric() override
900 {
901 // if(_solver != nullptr)
902 // {
903 // Trilinos::destroy_frosch(_solver);
904 // _solver = nullptr;
905 // }
906 }
907
908 virtual ~FROSchPreconditioner() override
909 {
910 if (_solver != nullptr)
911 {
912 Trilinos::destroy_frosch(_solver);
913 _solver = nullptr;
914 }
915 }
916
917 virtual Status apply(VectorType& vec_cor, const VectorType& vec_def) override
918 {
919 // upload defect vector and format correction
920 this->_upload_def(vec_def);
921 this->_format_cor();
922
923 // apply FROSchPreconditioner
924 Trilinos::solve_frosch(this->_core, this->_solver);
925
926 // download correction
927 this->_download_cor(vec_cor);
928
929 // okay
930 return Status::success;
931 }
932 }; // class FROSchPreconditioner
933
946 template<typename Matrix_, typename Filter_>
947 inline std::shared_ptr<FROSchPreconditioner<Matrix_, Filter_>> new_frosch(
948 const Matrix_& matrix, const Filter_& filter)
949 {
950 return std::make_shared<FROSchPreconditioner<Matrix_, Filter_>>(matrix, filter);
951 }
952
971 template<typename Matrix_, typename Filter_>
972 inline std::shared_ptr<FROSchPreconditioner<Matrix_, Filter_>> new_frosch(
973 const String& section_name, PropertyMap* section,
974 const Matrix_& matrix, const Filter_& filter)
975 {
976 return std::make_shared<FROSchPreconditioner<Matrix_, Filter_>>(section_name, section, matrix, filter);
977 }
978
994 template<typename Matrix_, typename Filter_>
995 inline std::shared_ptr<FROSchPreconditioner<Matrix_, Filter_>> new_frosch(
996 const Matrix_& matrix, const Filter_& filter, const Trilinos::FROSchParameterList & params)
997 {
998 return std::make_shared<FROSchPreconditioner<Matrix_, Filter_>>(matrix, filter, params);
999 }
1000
1010 template<typename Matrix_, typename Filter_>
1012 public TpetraSolverBase<Matrix_, Filter_>
1013 {
1014 public:
1018 typedef typename BaseClass::VectorType VectorType;
1019
1020 protected:
1022 void* _solver;
1023 // number of velocity/pressure dofs owned by this process
1024 Index _num_owned_velo_dofs;
1025 Index _num_owned_pres_dofs;
1026 // index of first velocity/pressure dof owned by this process
1027 Index _first_owned_velo_dof;
1028 Index _first_owned_pres_dof;
1029 // total number of velocity/pressure dofs
1030 Index _num_global_velo_dofs;
1031 Index _num_global_pres_dofs;
1032
1033 public:
1034 explicit StokesFROSchPreconditioner(const Matrix_& matrix, const Filter_& filter, const Trilinos::FROSchParameterList & params) :
1035 BaseClass(matrix, filter, params),
1036 _solver(nullptr),
1037 _num_owned_velo_dofs(0),
1038 _num_owned_pres_dofs(0),
1039 _first_owned_velo_dof(0),
1040 _first_owned_pres_dof(0),
1041 _num_global_velo_dofs(0),
1042 _num_global_pres_dofs(0)
1043 {
1044 }
1045
1046 explicit StokesFROSchPreconditioner(const String& DOXY(section_name), PropertyMap* DOXY(section),
1047 const Matrix_& matrix, const Filter_& filter) :
1048 StokesFROSchPreconditioner(matrix, filter)
1049 {
1051 }
1052
1053 virtual ~StokesFROSchPreconditioner() override
1054 {
1055 if (_solver != nullptr)
1056 {
1057 Trilinos::destroy_frosch(_solver);
1058 _solver = nullptr;
1059 }
1060 }
1061
1062 virtual String name() const override
1063 {
1064 return "StokesFROSchPreconditioner";
1065 }
1066
1079 virtual void init_symbolic() override
1080 {
1081 // This is the init_symbolic of FROSchPreconditioner,
1082 // but the FROSchPreconditioner class does not override
1083 // the method of the TpetraSolverClass
1084
1086
1087 this->_deduct_sizes();
1088
1089 XASSERT(this->_num_global_velo_dofs + this->_num_global_pres_dofs == this->_get_num_global_dofs());
1090 XASSERT(this->_first_owned_velo_dof + this->_first_owned_pres_dof == this->_get_global_dof_offset());
1091 XASSERT(this->_core == nullptr);
1092
1093 /*this->_get_comm()->allprint(
1094 "this->_get_num_global_dofs() = " + stringify(this->_get_num_global_dofs()) + "\n" +
1095 "this->_get_global_dof_offset() = " + stringify(this->_get_global_dof_offset()) + "\n" +
1096 "this->_get_num_owned_dofs() = " + stringify(this->_get_num_owned_dofs()) + "\n" +
1097 "this->_get_adp_matrix_num_nzes() = " + stringify(this->_get_adp_matrix_num_nzes()) + "\n" +
1098 "this->_num_owned_velo_dofs = " + stringify(this->_num_owned_velo_dofs) + "\n" +
1099 "this->_num_owned_pres_dofs = " + stringify(this->_num_owned_pres_dofs) + "\n" +
1100 "this->_first_owned_velo_dof = " + stringify(this->_first_owned_velo_dof) + "\n" +
1101 "this->_first_owned_pres_dof = " + stringify(this->_first_owned_pres_dof) + "\n" +
1102 "this->_num_global_velo_dofs = " + stringify(this->_num_global_velo_dofs) + "\n" +
1103 "this->_num_global_pres_dofs = " + stringify(this->_num_global_pres_dofs));*/
1104
1105 // create our Tpetra Stokes core wrapper object
1106 this->_core = Trilinos::create_core_stokes(
1107 &this->_get_comm()->mpi_comm(),
1108 this->_get_num_global_dofs(),
1109 this->_get_global_dof_offset(),
1110 this->_get_num_owned_dofs(),
1112 this->_num_owned_velo_dofs,
1113 this->_num_owned_pres_dofs,
1114 this->_first_owned_velo_dof,
1115 this->_first_owned_pres_dof,
1116 this->_num_global_velo_dofs,
1117 this->_num_global_pres_dofs,
1118 this->_params);
1119
1120 BaseClass::_upload_symbolic(Trilinos::get_row_ptr(this->_core), Trilinos::get_col_idx(this->_core));
1121
1122 Trilinos::init_symbolic(this->_core);
1123 }
1124
1125 virtual void init_numeric() override
1126 {
1128
1129 // create FROSchPreconditioner
1130 if(_solver == nullptr)
1131 {
1132 this->_solver = Trilinos::create_frosch(this->_core);
1133 }
1134 else
1135 {
1136 Trilinos::reinit_frosch(this->_solver);
1137 }
1138 }
1139
1140 virtual Status apply(VectorType& vec_cor, const VectorType& vec_def) override
1141 {
1142 // upload defect vector and format correction
1143 this->_upload_def(vec_def);
1144 this->_format_cor();
1145
1146 // apply FROSchPreconditioner
1147 Trilinos::solve_frosch(this->_core, this->_solver);
1148
1149 // download correction
1150 this->_download_cor(vec_cor);
1151
1152 // okay
1153 return Status::success;
1154 }
1155
1156 private:
1157 void _deduct_sizes()
1158 {
1159 // get and split the block information
1160 auto vbi = this->_get_adp_block_information().split_by_charset("\n");
1161
1162 // block information must consist of 4 entries
1163 XASSERTM(vbi.size() == std::size_t(4), "invalid block information for StokesFROSchPreconditioner");
1164
1165 // last block must terminate the tuple block
1166 XASSERTM(vbi[3] == "</Tuple>", "invalid block information for StokesFROSchPreconditioner");
1167
1168 // try to parse the block information for the entire tuple
1169 std::regex rext("<Tuple gc=\"(\\d+)\" gf=\"(\\d+)\" go=\"(\\d+)\" lc=\"(\\d+)\" lo=\"0\">");
1170 std::smatch rmt;
1171 if(!std::regex_match(vbi.at(0), rmt, rext))
1172 throw InternalError("invalid Tuple block information for StokesFROSchPreconditioner:\n" + vbi.at(0));
1173
1174 // try to parse the block information for the velocity component
1175 std::regex rexv("<Blocked bs=\"(\\d+)\" gc=\"(\\d+)\" gf=\"(\\d+)\" go=\"(\\d+)\" lc=\"(\\d+)\" lo=\"0\"/>");
1176 std::smatch rmv;
1177 if(!std::regex_match(vbi.at(1), rmv, rexv))
1178 throw InternalError("invalid velocity block information for StokesFROSchPreconditioner:\n" + vbi.at(1));
1179
1180 if(!String(rmv[2]).parse(this->_num_global_velo_dofs))
1181 throw InternalError("invalid velocity block information for StokesFROSchPreconditioner: failed to parse global velocity dof count");
1182 if(!String(rmv[3]).parse(this->_first_owned_velo_dof))
1183 throw InternalError("invalid velocity block information for StokesFROSchPreconditioner: failed to parse first owned global velocity dof");
1184 if(!String(rmv[5]).parse(this->_num_owned_velo_dofs))
1185 throw InternalError("invalid velocity block information for StokesFROSchPreconditioner: failed to parse local velocity dof count");
1186
1187 // try to parse the block information for the pressure component
1188 std::regex rexp("<Scalar gc=\"(\\d+)\" gf=\"(\\d+)\" go=\"(\\d+)\" lc=\"(\\d+)\" lo=\"(\\d+)\"/>");
1189 std::smatch rmp;
1190 if(!std::regex_match(vbi.at(2), rmp, rexp))
1191 throw InternalError("invalid velocity block information for StokesFROSchPreconditioner:\n" + vbi.at(2));
1192
1193 if(!String(rmp[1]).parse(this->_num_global_pres_dofs))
1194 throw InternalError("invalid velocity block information for StokesFROSchPreconditioner: failed to parse global velocity dof count");
1195 if(!String(rmp[2]).parse(this->_first_owned_pres_dof))
1196 throw InternalError("invalid velocity block information for StokesFROSchPreconditioner: failed to parse first owned global velocity dof");
1197 if(!String(rmp[4]).parse(this->_num_owned_pres_dofs))
1198 throw InternalError("invalid velocity block information for StokesFROSchPreconditioner: failed to parse local velocity dof count");
1199 }
1200
1201 /*void _deduct_sizes_old()
1202 {
1203 this->_num_owned_velo_dofs = this->_get_num_owned_dofs() - this->_num_owned_pres_dofs;
1204
1205 this->_num_global_velo_dofs = this->_num_owned_velo_dofs;
1206 this->_num_global_pres_dofs = this->_num_owned_pres_dofs;
1207 this->_get_comm()->allreduce(&this->_num_global_velo_dofs, &this->_num_global_velo_dofs, 1u, Dist::op_sum);
1208 this->_get_comm()->allreduce(&this->_num_global_pres_dofs, &this->_num_global_pres_dofs, 1u, Dist::op_sum);
1209
1210 this->_first_owned_velo_dof = 0;
1211 this->_first_owned_pres_dof = 0;
1212 this->_get_comm()->exscan(&this->_num_owned_velo_dofs, &this->_first_owned_velo_dof, 1u, Dist::op_sum);
1213 this->_get_comm()->exscan(&this->_num_owned_pres_dofs, &this->_first_owned_pres_dof, 1u, Dist::op_sum);
1214 }*/
1215 }; // class StokesFROSchPreconditioner
1216
1232 template<typename Matrix_, typename Filter_>
1233 inline std::shared_ptr<FROSchPreconditioner<Matrix_, Filter_>> new_stokes_frosch(
1234 const Matrix_& matrix, const Filter_& filter, const Index num_owned_pres_dofs)
1235 {
1236 return std::make_shared<StokesFROSchPreconditioner<Matrix_, Filter_>>(matrix, filter, num_owned_pres_dofs);
1237 }
1238
1257 template<typename Matrix_, typename Filter_>
1258 inline std::shared_ptr<StokesFROSchPreconditioner<Matrix_, Filter_>> new_stokes_frosch(
1259 const String& section_name, PropertyMap* section,
1260 const Matrix_& matrix, const Filter_& filter)
1261 {
1262 return std::make_shared<StokesFROSchPreconditioner<Matrix_, Filter_>>(section_name, section, matrix, filter);
1263 }
1264
1280 template<typename Matrix_, typename Filter_>
1281 inline std::shared_ptr<StokesFROSchPreconditioner<Matrix_, Filter_>> new_stokes_frosch(
1282 const Matrix_& matrix, const Filter_& filter, const Trilinos::FROSchParameterList & params)
1283 {
1284 return std::make_shared<StokesFROSchPreconditioner<Matrix_, Filter_>>(matrix, filter, params);
1285 }
1286 } // namespace Solver
1287} // namespace FEAT
1288
1289#endif // defined(FEAT_HAVE_TRILINOS) || defined(DOXYGEN)
#define XASSERT(expr)
Assertion macro definition.
Definition: assertion.hpp:262
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
FEAT Kernel base header.
exception that is thrown if something that is never supposed to happen happens
Definition: exception.hpp:96
A class organizing a tree of key-value pairs.
Base-Class for solvers based on Algebraic-DOF-Partitioning.
const Dist::Comm * _get_comm() const
const FilterType & _system_filter
the system filter
void _upload_symbolic(RPT_ *row_ptr, CIT_ *col_idx)
Uploads the ADP matrix structure to the given arrays.
Index _get_num_owned_dofs() const
Index _get_global_dof_offset() const
String _get_adp_block_information() const
void _download_vector(LocalVectorType &vector, const DTV_ *val)
Downloads the ADP vector values from the given array.
void _upload_vector(DTV_ *val, const LocalVectorType &vector)
Uploads the ADP vector values to the given array.
MatrixType::VectorTypeL VectorType
the (local) vector type
Index _get_num_global_dofs() const
Index _get_adp_matrix_num_nzes() const
void _upload_numeric(DTV_ *val, const RPT_ *row_ptr, const CIT_ *col_idx)
Uploads the (filtered) ADP matrix values to the given array.
Trilinos FROSchPreconditioner class template.
Definition: frosch.hpp:824
virtual void done_numeric() override
Numeric finalization method.
Definition: frosch.hpp:899
BaseClass::VectorType VectorType
the vector type
Definition: frosch.hpp:829
FROSchPreconditioner(const String &section_name, PropertyMap *section, const Matrix_ &matrix, const Filter_ &filter)
Definition: frosch.hpp:842
void * _solver
the FROSchPreconditioner solver object
Definition: frosch.hpp:833
virtual String name() const override
Returns a descriptive string.
Definition: frosch.hpp:850
TpetraSolverBase< Matrix_, Filter_ > BaseClass
our base-class
Definition: frosch.hpp:827
virtual void init_numeric() override
Numeric Initialization.
Definition: frosch.hpp:884
virtual void init_symbolic() override
Symbolic Initialization.
Definition: frosch.hpp:864
virtual void init_symbolic()
Symbolic initialization method.
Definition: base.hpp:227
virtual void init_numeric()
Numeric initialization method.
Definition: base.hpp:237
virtual void done_symbolic()
Symbolic finalization method.
Definition: base.hpp:255
Trilinos StokesFROSchPreconditioner class template.
Definition: frosch.hpp:1013
virtual void init_numeric() override
Numeric Initialization.
Definition: frosch.hpp:1125
void * _solver
the FROSchPreconditioner solver object
Definition: frosch.hpp:1022
virtual void init_symbolic() override
Symbolic Initialization.
Definition: frosch.hpp:1079
virtual String name() const override
Returns a descriptive string.
Definition: frosch.hpp:1062
TpetraSolverBase< Matrix_, Filter_ > BaseClass
our base-class
Definition: frosch.hpp:1016
StokesFROSchPreconditioner(const String &section_name, PropertyMap *section, const Matrix_ &matrix, const Filter_ &filter)
Definition: frosch.hpp:1046
BaseClass::VectorType VectorType
the vector type
Definition: frosch.hpp:1018
Base-Class for solvers/preconditioners borrowed from Trilinos/FROSch library.
Definition: frosch.hpp:716
virtual void done_symbolic() override
Symbolic Finalization.
Definition: frosch.hpp:801
void _download_cor(VectorType &vec_cor)
Downloads the Tpetra correction vector.
Definition: frosch.hpp:767
ADPSolverBase< Matrix_, Filter_, SolverBase_ > BaseClass
our base-class
Definition: frosch.hpp:719
void * _core
a pointer to our opaque core wrapper object
Definition: frosch.hpp:725
void _format_cor()
Format the Tpetra correction vector.
Definition: frosch.hpp:752
void _upload_def(const VectorType &vec_def)
Uploads the Tpetra defect vector.
Definition: frosch.hpp:744
virtual void init_numeric() override
Numeric Initialization.
Definition: frosch.hpp:782
String class implementation.
Definition: string.hpp:47
std::deque< String > split_by_charset(const String &charset) const
Splits the string by a delimiter charset.
Definition: string.hpp:468
Status
Solver status return codes enumeration.
Definition: base.hpp:47
@ success
solving successful (convergence criterion fulfilled)
std::shared_ptr< FROSchPreconditioner< Matrix_, Filter_ > > new_frosch(const Matrix_ &matrix, const Filter_ &filter)
Creates a new FROSchPreconditioner solver object.
Definition: frosch.hpp:947
std::shared_ptr< FROSchPreconditioner< Matrix_, Filter_ > > new_stokes_frosch(const Matrix_ &matrix, const Filter_ &filter, const Index num_owned_pres_dofs)
Creates a new StokesFROSchPreconditioner solver object.
Definition: frosch.hpp:1233
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.