Dune::Copasi
Loading...
Searching...
No Matches
make_step_operator.hh
Go to the documentation of this file.
1#ifndef DUNE_COPASI_MODEL_MAKE_DIFFUSION_REACTION_STEP_OPERATOR_HH
2#define DUNE_COPASI_MODEL_MAKE_DIFFUSION_REACTION_STEP_OPERATOR_HH
3
6
7#if HAVE_METIS && DUNE_COPASI_CONCURRENT_ASSEMBLY
8#include <dune/pdelab/common/partition/metis.hh>
9#endif
10
11#include <dune/pdelab/common/partition/simple.hh>
12#include <dune/pdelab/common/execution.hh>
13#include <dune/pdelab/operator/operator.hh>
14
15#include <spdlog/spdlog.h>
16
17#include <memory>
18
20
21template<class LocalBasisTraits,
22 class Coefficients,
23 class Residual,
24 class ResidualQuantity,
25 class TimeQuantity,
26 PDELab::Concept::Basis Basis,
27 Dune::Concept::GridView CellDataGridView = typename Basis::EntitySet,
28 class CellDataType = double>
29[[nodiscard]] inline static std::unique_ptr<PDELab::Operator<Coefficients, Coefficients>>
30make_step_operator(const ParameterTree& config,
31 const Basis& basis,
32 std::size_t halo,
34 std::shared_ptr<const CellData<CellDataGridView, CellDataType>> grid_cell_data = nullptr)
35{
36
37 std::unique_ptr<PDELab::Operator<Coefficients, Coefficients>> one_step;
38 const auto& assembly_cfg = config.sub("assembly");
39
40 auto make_one_step_op = [&, functor_factory, grid_cell_data]<class ExecutionPolicy, PDELab::Concept::Basis OperatorBasis>(
41 ExecutionPolicy execution_policy, const OperatorBasis& operator_basis) {
42 spdlog::info("Creating mass/stiffness local operator");
43 const auto& time_step_cfg = config.sub("time_step_operator");
44 const auto& scalar_field_cfg = config.sub("scalar_field");
45 bool is_linear = config.get("is_linear", false);
46 using LocalOperator =
47 LocalOperator<OperatorBasis, LocalBasisTraits, CellDataGridView, CellDataType, ExecutionPolicy>;
48 LocalOperator const stiff_lop(operator_basis,
49 LocalOperator::Form::Stiffness,
50 is_linear,
51 scalar_field_cfg,
52 functor_factory,
53 grid_cell_data,
54 execution_policy);
55 LocalOperator const mass_lop(operator_basis,
56 LocalOperator::Form::Mass,
57 is_linear,
58 scalar_field_cfg,
59 functor_factory,
60 grid_cell_data,
61 execution_policy);
63 time_step_cfg, operator_basis, mass_lop, stiff_lop);
64 };
65
66 auto entity_set = basis.entitySet();
67 std::size_t part_patches =
68 assembly_cfg.get("partition.patches", static_cast<std::size_t>(entity_set.size(0) / 40));
69
70#if DUNE_COPASI_CONCURRENT_ASSEMBLY
73 auto entity_set = basis.entitySet();
74 auto default_part_type =
75#if HAVE_METIS
76 "METIS";
77#else
78 "Simple";
79#endif // HAVE_METIS
80 auto part_type = assembly_cfg.get("partition.type", default_part_type);
81 auto part_coloring = assembly_cfg.get("partition.coloring", "None");
82 spdlog::info(" Concurrent Partitioning:");
83 spdlog::info(" Type: {}", part_type);
84 spdlog::info(" Patches: {}", part_patches);
85 spdlog::info(" Halo: {}", halo);
86 spdlog::info(" Coloring: {}", part_coloring);
87 if (part_type == "METIS") {
88#if HAVE_METIS
89 if (part_coloring == "None") {
90 return make_one_step_op(
91 execution_policy,
92 basis.subSpace(
93 PDELab::EntitySetPartitioner::Metis{ entity_set, part_patches, halo },
94 TypeTree::treePath()));
95 } else if (part_coloring == "DSatur") {
96 return make_one_step_op(
97 execution_policy,
98 basis.subSpace(PDELab::EntitySetPartitioner::MetisColored{ entity_set, part_patches, halo },
99 TypeTree::treePath()));
100 } else {
101 throw format_exception(IOError{}, "Not known coloring algorithm '{}' known", part_coloring);
102 }
103#else
104 throw format_exception(IOError{}, "'METIS' partitioner is not available on this executable");
105#endif // HAVE_METIS
106 } else if (part_type == "Simple") {
107 if (part_coloring == "None") {
108 return make_one_step_op(
109 execution_policy,
110 basis.subSpace(
111 PDELab::EntitySetPartitioner::Simple{ entity_set, part_patches, halo },
112 TypeTree::treePath()));
113 } else if (part_coloring == "DSatur") {
114 return make_one_step_op(
115 execution_policy,
116 basis.subSpace(PDELab::EntitySetPartitioner::SimpleColored{ entity_set, part_patches, halo },
117 TypeTree::treePath()));
118 } else {
119 throw format_exception(IOError{}, "Not known coloring algorithm '{}' known", part_coloring);
120 }
121 } else {
122 throw format_exception(IOError{}, "Not known partition algorithm '{}' known", part_type);
123 }
124 };
125
126 auto exec_policy = assembly_cfg.get("type", "concurrent");
127#else
128 auto exec_policy = assembly_cfg.get("type", "sequential");
129#endif // DUNE_COPASI_CONCURRENT_ASSEMBLY
130
131 spdlog::info("Creating time-step operator with '{}' execution policy", exec_policy);
132 if (exec_policy != "sequential" and part_patches < std::thread::hardware_concurrency()) {
133 exec_policy = "sequential";
134 spdlog::warn("Too few patches '{}', execution policy of assembler is switched to 'sequential'", part_patches);
135 }
136
137 if (exec_policy == "sequential") {
138 one_step = make_one_step_op(PDELab::Execution::seq, basis);
139#if DUNE_COPASI_CONCURRENT_ASSEMBLY
140 } else if (exec_policy == "concurrent") {
141 one_step = make_concurrent_one_step_op(PDELab::Execution::par);
142#endif // DUNE_COPASI_CONCURRENT_ASSEMBLY
143 } else {
144 throw format_exception(IOError{}, "Not known execution '{}' policy known", exec_policy);
145 }
146
147 return one_step;
148}
149
150} // namespace Dune::Copasi::DiffusionReaction
151
152#endif // DUNE_COPASI_MODEL_MAKE_DIFFUSION_REACTION_STEP_OPERATOR_HH
Definition factory.hh:28
auto format_exception(Exception &&e, fmt::format_string< Args... > format, Args &&... args)
Definition exceptions.hh:23
constexpr bool is_bitflags_v
Alias for Bitflag indicator.
Definition bit_flags.hh:24