8 #include "DataStructures/DataBox/PrefixHelpers.hpp"
9 #include "Domain/Creators/RegisterDerivedWithCharm.hpp"
11 #include "Elliptic/Actions/InitializeAnalyticSolution.hpp"
12 #include "Elliptic/Actions/InitializeFields.hpp"
13 #include "Elliptic/Actions/InitializeFixedSources.hpp"
14 #include "Elliptic/DiscontinuousGalerkin/DgElementArray.hpp"
15 #include "Elliptic/DiscontinuousGalerkin/ImposeBoundaryConditions.hpp"
16 #include "Elliptic/DiscontinuousGalerkin/ImposeInhomogeneousBoundaryConditionsOnSource.hpp"
17 #include "Elliptic/DiscontinuousGalerkin/InitializeFirstOrderOperator.hpp"
18 #include "Elliptic/DiscontinuousGalerkin/NumericalFluxes/FirstOrderInternalPenalty.hpp"
19 #include "Elliptic/FirstOrderOperator.hpp"
21 #include "Elliptic/Tags.hpp"
22 #include "Elliptic/Triggers/EveryNIterations.hpp"
23 #include "IO/Observer/Actions/RegisterEvents.hpp"
24 #include "IO/Observer/Helpers.hpp"
25 #include "IO/Observer/ObserverComponent.hpp"
26 #include "NumericalAlgorithms/Convergence/Tags.hpp"
27 #include "NumericalAlgorithms/DiscontinuousGalerkin/BoundarySchemes/FirstOrder/FirstOrderScheme.hpp"
28 #include "NumericalAlgorithms/DiscontinuousGalerkin/Tags.hpp"
30 #include "Parallel/Actions/SetupDataBox.hpp"
31 #include "Parallel/Actions/TerminatePhase.hpp"
33 #include "Parallel/InitializationFunctions.hpp"
34 #include "Parallel/PhaseDependentActionList.hpp"
35 #include "Parallel/Reduction.hpp"
37 #include "ParallelAlgorithms/Actions/MutateApply.hpp"
38 #include "ParallelAlgorithms/DiscontinuousGalerkin/CollectDataForFluxes.hpp"
39 #include "ParallelAlgorithms/DiscontinuousGalerkin/FluxCommunication.hpp"
40 #include "ParallelAlgorithms/DiscontinuousGalerkin/InitializeDomain.hpp"
41 #include "ParallelAlgorithms/DiscontinuousGalerkin/InitializeInterfaces.hpp"
42 #include "ParallelAlgorithms/DiscontinuousGalerkin/InitializeMortars.hpp"
43 #include "ParallelAlgorithms/Events/ObserveErrorNorms.hpp"
44 #include "ParallelAlgorithms/Events/ObserveFields.hpp"
45 #include "ParallelAlgorithms/EventsAndTriggers/Actions/RunEventsAndTriggers.hpp"
46 #include "ParallelAlgorithms/Initialization/Actions/RemoveOptionsAndTerminatePhase.hpp"
47 #include "ParallelAlgorithms/LinearSolver/Gmres/Gmres.hpp"
49 #include "PointwiseFunctions/AnalyticData/AnalyticData.hpp"
50 #include "PointwiseFunctions/AnalyticSolutions/Poisson/AnalyticSolution.hpp"
51 #include "PointwiseFunctions/AnalyticSolutions/Poisson/Lorentzian.hpp"
52 #include "PointwiseFunctions/AnalyticSolutions/Poisson/Moustache.hpp"
53 #include "PointwiseFunctions/AnalyticSolutions/Poisson/ProductOfSinusoids.hpp"
54 #include "PointwiseFunctions/AnalyticSolutions/Poisson/Zero.hpp"
55 #include "PointwiseFunctions/AnalyticSolutions/Tags.hpp"
58 #include "Utilities/Functional.hpp"
61 namespace SolvePoisson::OptionTags {
63 static std::string name() noexcept {
return "LinearSolver"; }
65 "The iterative Krylov-subspace linear solver";
68 static std::string name() noexcept {
return "GMRES"; }
69 static constexpr
Options::String help =
"Options for the GMRES linear solver";
76 struct Metavariables {
77 static constexpr
size_t volume_dim = Dim;
85 using analytic_solution_registrars = tmpl::flatten<tmpl::list<
86 Poisson::Solutions::Registrars::ProductOfSinusoids<Dim>,
87 tmpl::conditional_t<Dim == 1 or Dim == 2,
88 Poisson::Solutions::Registrars::Moustache<Dim>,
90 tmpl::conditional_t<Dim == 3,
91 Poisson::Solutions::Registrars::Lorentzian<Dim>,
98 using initial_guess_registrars =
99 tmpl::list<Poisson::Solutions::Registrars::Zero<Dim>>;
104 "Find the solution to a Poisson problem."};
106 using fluxes_computer_tag =
111 using linear_solver =
115 using linear_solver_iteration_id =
120 typename system::fields_tag>;
122 typename system::primal_fields>;
123 using auxiliary_variables =
125 typename system::auxiliary_fields>;
130 volume_dim, fluxes_computer_tag, primal_variables,
131 auxiliary_variables>>;
136 volume_dim, linear_operand_tag,
139 normal_dot_numerical_flux, linear_solver_iteration_id>;
143 using observe_fields =
typename system::fields_tag::tags_list;
144 using analytic_solution_fields = observe_fields;
147 volume_dim, linear_solver_iteration_id, observe_fields,
148 analytic_solution_fields>,
150 linear_solver_iteration_id, analytic_solution_fields>>;
152 linear_solver_iteration_id>>;
155 using const_global_cache_tags =
156 tmpl::list<analytic_solution_tag, initial_guess_tag, fluxes_computer_tag,
157 normal_dot_numerical_flux,
161 using observed_reduction_data_tags =
162 observers::collect_reduction_data_tags<tmpl::flatten<tmpl::list<
163 typename Event<events>::creatable_classes, linear_solver>>>;
166 enum class Phase { Initialization, RegisterWithObserver, Solve, Exit };
168 using initialization_actions = tmpl::list<
175 typename linear_solver::initialize_element,
179 analytic_solution_fields>,
184 volume_dim,
typename system::fluxes_computer,
185 typename system::sources_computer, linear_operand_tag,
186 primal_variables, auxiliary_variables>,
189 using build_linear_operator_actions = tmpl::list<
195 linear_operand_tag>>,
197 linear_operand_tag, primal_variables>,
204 using register_actions =
208 using solve_actions = tmpl::list<
209 typename linear_solver::template solve<tmpl::list<
216 initialization_actions>,
222 using component_list = tmpl::flatten<
223 tmpl::list<dg_element_array,
typename linear_solver::component_list,
228 template <
typename... Tags>
229 static Phase determine_next_phase(
232 const Phase& current_phase,
233 const Parallel::CProxy_GlobalCache<
234 Metavariables>& ) noexcept {
235 switch (current_phase) {
236 case Phase::Initialization:
237 return Phase::RegisterWithObserver;
238 case Phase::RegisterWithObserver:
244 "Should never call determine_next_phase with the current phase "
248 "Unknown type of phase. Did you static_cast<Phase> an integral "
254 static const std::vector<void (*)()> charm_init_node_funcs{
255 &setup_error_handling,
257 &domain::creators::register_derived_with_charm,
259 metavariables::analytic_solution_tag::type::element_type>,
261 metavariables::initial_guess_tag::type::element_type>,
263 metavariables::system::boundary_conditions_base>,
268 static const std::vector<void (*)()> charm_init_proc_funcs{
Add into the DataBox default constructed items for the collection of tags requested by any of the act...
Definition: SetupDataBox.hpp:102
A GMRES solver for nonsymmetric linear systems of equations .
Definition: Gmres.hpp:87
Registers this element of a parallel component with the local Observer parallel component for each tr...
Definition: RegisterEvents.hpp:97
Adds boundary contributions to the sources.
Definition: ImposeInhomogeneousBoundaryConditionsOnSource.hpp:71
Place the analytic solution of the system fields in the DataBox.
Definition: InitializeAnalyticSolution.hpp:58
Send local boundary data needed for fluxes to neighbors.
Definition: FluxCommunication.hpp:78
Definition: RemoveOptionsAndTerminatePhase.hpp:27
tmpl::list< Tags... > face_compute_tags
Definition: InitializeInterfaces.hpp:41
Terminate the algorithm to proceed to the next phase.
Definition: TerminatePhase.hpp:26
tmpl::list< Tags... > slice_tags_to_face
Definition: InitializeInterfaces.hpp:31
void disable_openblas_multithreading() noexcept
Disable OpenBLAS multithreading since it conflicts with Charm++ parallelism.
Definition: Blas.cpp:15
A template for defining a registrar.
Definition: Registration.hpp:42
Mutating DataBox invokable to compute the bulk contribution to the operator represented by the Operat...
Definition: FirstOrderOperator.hpp:224
void enable_floating_point_exceptions()
Definition: FloatingPointExceptions.cpp:27
The Poisson equation formulated as a set of coupled first-order PDEs.
Definition: FirstOrderSystem.hpp:78
#define ERROR(m)
prints an error message to the standard error stream and aborts the program.
Definition: Error.hpp:36
List of all the actions to be executed in the specified phase.
Definition: PhaseDependentActionList.hpp:16
The nodegroup parallel component that is responsible for writing data to disk.
Definition: ObserverComponent.hpp:51
Initialize items related to the interfaces between Elements and on external boundaries.
Definition: InitializeInterfaces.hpp:120
The parallel component responsible for managing the DG elements that compose the computational domain...
Definition: DgElementArray.hpp:37
Initialize items related to the basic structure of the element.
Definition: InitializeDomain.hpp:67
Run the events and triggers.
Definition: RunEventsAndTriggers.hpp:27
Apply the function Mutator::apply to the DataBox.
Definition: MutateApply.hpp:40
The group parallel component that is responsible for reducing data to be observed.
Definition: ObserverComponent.hpp:29
Definition: Trigger.hpp:34
Base class for analytic solutions of the Poisson equation.
Definition: AnalyticSolution.hpp:32
Initialize mortars between elements for exchanging fluxes.
Definition: InitializeMortars.hpp:78
Collect data that is needed to compute numerical fluxes and store it on mortars, projecting it if nec...
Definition: CollectDataForFluxes.hpp:68
Definition: ObserveFields.hpp:68
The internal penalty flux for first-order elliptic equations.
Definition: FirstOrderInternalPenalty.hpp:147
Provides analytic tensor data as a function of the spatial coordinates.
Definition: AnalyticData.hpp:30
Initialize the dynamic fields of the elliptic system, i.e. those we solve for.
Definition: InitializeFields.hpp:43
tmpl::list< Tags... > exterior_compute_tags
Definition: InitializeInterfaces.hpp:46
const char *const String
The string used in option structs.
Definition: Options.hpp:32
Boundary contributions for a first-order DG scheme.
Definition: FirstOrderScheme.hpp:66
void register_derived_classes_with_charm() noexcept
Register derived classes of the Base class.
Definition: RegisterDerivedClassesWithCharm.hpp:31
Set field data on external boundaries so that they represent homogeneous (zero) Dirichlet boundary co...
Definition: ImposeBoundaryConditions.hpp:91
Initialize DataBox tags for building the first-order elliptic DG operator.
Definition: InitializeFirstOrderOperator.hpp:49
Receive boundary data needed for fluxes from neighbors.
Definition: FluxCommunication.hpp:175
Initialize the "fixed sources" of the elliptic equations, i.e. their variable-independent source term...
Definition: InitializeFixedSources.hpp:53
Require a pointer to not be a nullptr
Definition: ReadSpecThirdOrderPiecewisePolynomial.hpp:13
tmpl::list< Tags... > slice_tags_to_exterior
Definition: InitializeInterfaces.hpp:36