Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <cstddef>
7 : #include <optional>
8 : #include <utility>
9 :
10 : #include "DataStructures/DataBox/DataBox.hpp"
11 : #include "DataStructures/DataBox/MetavariablesTag.hpp"
12 : #include "DataStructures/DataBox/PrefixHelpers.hpp"
13 : #include "DataStructures/DataBox/Prefixes.hpp"
14 : #include "DataStructures/TaggedTuple.hpp"
15 : #include "DataStructures/Variables.hpp"
16 : #include "Domain/Structure/ElementId.hpp"
17 : #include "Domain/Tags.hpp"
18 : #include "Elliptic/DiscontinuousGalerkin/Tags.hpp"
19 : #include "NumericalAlgorithms/DiscontinuousGalerkin/ApplyMassMatrix.hpp"
20 : #include "Parallel/AlgorithmExecution.hpp"
21 : #include "ParallelAlgorithms/Amr/Protocols/Projector.hpp"
22 : #include "ParallelAlgorithms/Initialization/MutateAssign.hpp"
23 : #include "Utilities/CallWithDynamicType.hpp"
24 : #include "Utilities/MakeWithValue.hpp"
25 : #include "Utilities/TMPL.hpp"
26 :
27 : /// \cond
28 : namespace Parallel {
29 : template <typename Metavariables>
30 : struct GlobalCache;
31 : } // namespace Parallel
32 : /// \endcond
33 :
34 : namespace elliptic::Actions {
35 :
36 : /*!
37 : * \brief Initialize the "fixed sources" of the elliptic equations, i.e. their
38 : * variable-independent source term \f$f(x)\f$
39 : *
40 : * This action initializes \f$f(x)\f$ in an elliptic system of PDEs \f$-div(F) +
41 : * S = f(x)\f$.
42 : *
43 : * Uses:
44 : * - System:
45 : * - `primal_fields`
46 : * - DataBox:
47 : * - `BackgroundTag`
48 : * - `Tags::Coordinates<Dim, Frame::Inertial>`
49 : *
50 : * DataBox:
51 : * - Adds:
52 : * - `db::wrap_tags_in<::Tags::FixedSource, primal_fields>`
53 : */
54 : template <typename System, typename BackgroundTag,
55 : size_t Dim = System::volume_dim>
56 1 : struct InitializeFixedSources : tt::ConformsTo<::amr::protocols::Projector> {
57 : private:
58 0 : using fixed_sources_tag = ::Tags::Variables<
59 : db::wrap_tags_in<::Tags::FixedSource, typename System::primal_fields>>;
60 :
61 : public: // Iterable action
62 0 : using const_global_cache_tags =
63 : tmpl::list<elliptic::dg::Tags::Massive, BackgroundTag>;
64 0 : using simple_tags = tmpl::list<fixed_sources_tag>;
65 0 : using compute_tags = tmpl::list<>;
66 :
67 : template <typename DbTagsList, typename... InboxTags, typename Metavariables,
68 : typename ActionList, typename ParallelComponent>
69 0 : static Parallel::iterable_action_return_t apply(
70 : db::DataBox<DbTagsList>& box,
71 : const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
72 : const Parallel::GlobalCache<Metavariables>& /*cache*/,
73 : const ElementId<Dim>& /*array_index*/, const ActionList /*meta*/,
74 : const ParallelComponent* const /*meta*/) {
75 : db::mutate_apply<InitializeFixedSources>(make_not_null(&box));
76 : return {Parallel::AlgorithmExecution::Continue, std::nullopt};
77 : }
78 :
79 : public: // DataBox mutator, amr::protocols::Projector
80 0 : using return_tags = tmpl::list<fixed_sources_tag>;
81 0 : using argument_tags = tmpl::list<
82 : domain::Tags::Coordinates<Dim, Frame::Inertial>, BackgroundTag,
83 : elliptic::dg::Tags::Massive, domain::Tags::Mesh<Dim>,
84 : domain::Tags::DetInvJacobian<Frame::ElementLogical, Frame::Inertial>,
85 : Parallel::Tags::Metavariables>;
86 :
87 : template <typename Background, typename Metavariables, typename... AmrData>
88 0 : static void apply(
89 : const gsl::not_null<typename fixed_sources_tag::type*> fixed_sources,
90 : const tnsr::I<DataVector, Dim>& inertial_coords,
91 : const Background& background, const bool massive, const Mesh<Dim>& mesh,
92 : const Scalar<DataVector>& det_inv_jacobian, const Metavariables& /*meta*/,
93 : const AmrData&... /*amr_data*/) {
94 : // Retrieve the fixed-sources of the elliptic system from the background,
95 : // which (along with the boundary conditions) define the problem we want to
96 : // solve.
97 : using factory_classes =
98 : typename std::decay_t<Metavariables>::factory_creation::factory_classes;
99 : *fixed_sources =
100 : call_with_dynamic_type<Variables<typename fixed_sources_tag::tags_list>,
101 : tmpl::at<factory_classes, Background>>(
102 : &background, [&inertial_coords](const auto* const derived) {
103 : return variables_from_tagged_tuple(derived->variables(
104 : inertial_coords, typename fixed_sources_tag::tags_list{}));
105 : });
106 :
107 : // Apply DG mass matrix to the fixed sources if the DG operator is massive
108 : if (massive) {
109 : *fixed_sources /= get(det_inv_jacobian);
110 : ::dg::apply_mass_matrix(fixed_sources, mesh);
111 : }
112 : }
113 : };
114 :
115 : } // namespace elliptic::Actions
|