Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <array>
7 : #include <cstddef>
8 : #include <memory>
9 : #include <optional>
10 : #include <tuple>
11 : #include <utility>
12 : #include <vector>
13 :
14 : #include "ControlSystem/Tags/FunctionsOfTimeInitialize.hpp"
15 : #include "DataStructures/DataBox/DataBox.hpp"
16 : #include "DataStructures/Tensor/IndexType.hpp"
17 : #include "Domain/CoordinateMaps/CoordinateMap.hpp"
18 : #include "Domain/CoordinateMaps/Identity.hpp"
19 : #include "Domain/CoordinateMaps/Tags.hpp"
20 : #include "Domain/CreateInitialElement.hpp"
21 : #include "Domain/Creators/Tags/Domain.hpp"
22 : #include "Domain/Creators/Tags/FunctionsOfTime.hpp"
23 : #include "Domain/Creators/Tags/InitialExtents.hpp"
24 : #include "Domain/Creators/Tags/InitialRefinementLevels.hpp"
25 : #include "Domain/Domain.hpp"
26 : #include "Domain/ElementMap.hpp"
27 : #include "Domain/MinimumGridSpacing.hpp"
28 : #include "Domain/Structure/CreateInitialMesh.hpp"
29 : #include "Domain/Structure/Direction.hpp"
30 : #include "Domain/Structure/Element.hpp"
31 : #include "Domain/Structure/ElementId.hpp"
32 : #include "Domain/Tags.hpp"
33 : #include "Domain/Tags/NeighborMesh.hpp"
34 : #include "Domain/TagsTimeDependent.hpp"
35 : #include "Evolution/DiscontinuousGalerkin/Initialization/QuadratureTag.hpp"
36 : #include "Evolution/TagsDomain.hpp"
37 : #include "NumericalAlgorithms/Spectral/Basis.hpp"
38 : #include "NumericalAlgorithms/Spectral/LogicalCoordinates.hpp"
39 : #include "NumericalAlgorithms/Spectral/Mesh.hpp"
40 : #include "NumericalAlgorithms/Spectral/Quadrature.hpp"
41 : #include "Parallel/AlgorithmExecution.hpp"
42 : #include "Parallel/GlobalCache.hpp"
43 : #include "Parallel/Tags/ArrayIndex.hpp"
44 : #include "ParallelAlgorithms/Amr/Protocols/Projector.hpp"
45 : #include "ParallelAlgorithms/Initialization/MutateAssign.hpp"
46 : #include "Utilities/Gsl.hpp"
47 : #include "Utilities/TMPL.hpp"
48 : #include "Utilities/TaggedTuple.hpp"
49 :
50 : /// \cond
51 : namespace Frame {
52 : struct Inertial;
53 : } // namespace Frame
54 : /// \endcond
55 :
56 : namespace evolution::dg::Initialization {
57 :
58 : /// \ingroup InitializationGroup
59 : /// \brief Initialize items related to the basic structure of the element
60 : ///
61 : /// \details See the type aliases defined below for what items are added to the
62 : /// GlobalCache and DataBox and how they are initialized
63 :
64 : template <typename Metavariables, bool UseControlSystems = false>
65 1 : struct Domain {
66 0 : static constexpr size_t dim = Metavariables::volume_dim;
67 :
68 : /// Tags for constant items added to the GlobalCache. These items are
69 : /// initialized from input file options.
70 1 : using const_global_cache_tags = tmpl::list<::domain::Tags::Domain<dim>>;
71 :
72 : /// Tags for mutable items added to the GlobalCache. These items are
73 : /// initialized from input file options.
74 1 : using mutable_global_cache_tags = tmpl::list<tmpl::conditional_t<
75 : UseControlSystems, ::control_system::Tags::FunctionsOfTimeInitialize,
76 : ::domain::Tags::FunctionsOfTimeInitialize>>;
77 :
78 : /// Tags for simple DataBox items that are initialized from input file options
79 1 : using simple_tags_from_options =
80 : tmpl::list<::domain::Tags::InitialExtents<dim>,
81 : ::domain::Tags::InitialRefinementLevels<dim>,
82 : evolution::dg::Tags::Quadrature>;
83 :
84 : /// Tags for simple DataBox items that are default initialized.
85 1 : using default_initialized_simple_tags = tmpl::list<>;
86 :
87 : /// Tags for items fetched by the DataBox and passed to the apply function
88 1 : using argument_tags =
89 : tmpl::append<const_global_cache_tags, simple_tags_from_options,
90 : tmpl::list<::Parallel::Tags::ArrayIndex<ElementId<dim>>>>;
91 :
92 : /// Tags for items in the DataBox that are mutated by the apply function
93 1 : using return_tags =
94 : tmpl::list<::domain::Tags::Mesh<dim>, ::domain::Tags::Element<dim>,
95 : ::domain::Tags::ElementMap<dim, Frame::Grid>,
96 : ::domain::CoordinateMaps::Tags::CoordinateMap<dim, Frame::Grid,
97 : Frame::Inertial>,
98 : ::domain::Tags::NeighborMesh<dim>>;
99 :
100 : /// Tags for mutable DataBox items that are either default initialized or
101 : /// initialized by the apply function
102 1 : using simple_tags =
103 : tmpl::append<default_initialized_simple_tags, return_tags>;
104 :
105 : /// Tags for immutable DataBox items (compute items or reference items) added
106 : /// to the DataBox.
107 1 : using compute_tags = tmpl::list<
108 : ::domain::Tags::LogicalCoordinates<dim>,
109 : // Compute tags for Frame::Grid quantities
110 : ::domain::Tags::MappedCoordinates<
111 : ::domain::Tags::ElementMap<dim, Frame::Grid>,
112 : ::domain::Tags::Coordinates<dim, Frame::ElementLogical>>,
113 : ::domain::Tags::InverseJacobianCompute<
114 : ::domain::Tags::ElementMap<dim, Frame::Grid>,
115 : ::domain::Tags::Coordinates<dim, Frame::ElementLogical>>,
116 : // Compute tag to retrieve functions of time from global cache.
117 : Parallel::Tags::FromGlobalCache<
118 : tmpl::conditional_t<UseControlSystems,
119 : ::control_system::Tags::FunctionsOfTimeInitialize,
120 : ::domain::Tags::FunctionsOfTimeInitialize>,
121 : Metavariables>,
122 : // Compute tags for Frame::Inertial quantities
123 : ::domain::Tags::CoordinatesMeshVelocityAndJacobiansCompute<
124 : ::domain::CoordinateMaps::Tags::CoordinateMap<dim, Frame::Grid,
125 : Frame::Inertial>>,
126 :
127 : ::domain::Tags::InertialFromGridCoordinatesCompute<dim>,
128 : ::domain::Tags::ElementToInertialInverseJacobian<dim>,
129 : ::domain::Tags::DetInvJacobianCompute<dim, Frame::ElementLogical,
130 : Frame::Inertial>,
131 : ::domain::Tags::InertialMeshVelocityCompute<dim>,
132 : evolution::domain::Tags::DivMeshVelocityCompute<dim>,
133 : // Compute tags for other mesh quantities
134 : ::domain::Tags::MinimumGridSpacingCompute<dim, Frame::Inertial>>;
135 :
136 : /// Given the items fetched from a DataBox by the argument_tags, mutate
137 : /// the items in the DataBox corresponding to return_tags
138 1 : static void apply(
139 : const gsl::not_null<Mesh<dim>*> mesh,
140 : const gsl::not_null<Element<dim>*> element,
141 : const gsl::not_null<ElementMap<dim, Frame::Grid>*> element_map,
142 : const gsl::not_null<std::unique_ptr<
143 : ::domain::CoordinateMapBase<Frame::Grid, Frame::Inertial, dim>>*>
144 : grid_to_inertial_map,
145 : const gsl::not_null<DirectionalIdMap<dim, Mesh<dim>>*> neighbor_mesh,
146 : const ::Domain<dim>& domain,
147 : const std::vector<std::array<size_t, dim>>& initial_extents,
148 : const std::vector<std::array<size_t, dim>>& initial_refinement,
149 : const Spectral::Quadrature& i1_quadrature,
150 : const ElementId<dim>& element_id) {
151 : *element = ::domain::create_initial_element(element_id, domain.blocks(),
152 : initial_refinement);
153 : const Spectral::Basis i1_basis{Spectral::Basis::Legendre};
154 : *mesh = ::domain::create_initial_mesh(initial_extents, *element, i1_basis,
155 : i1_quadrature);
156 : const auto& my_block = domain.blocks()[element_id.block_id()];
157 : *element_map = ElementMap<dim, Frame::Grid>{element_id, my_block};
158 :
159 : if (my_block.is_time_dependent()) {
160 : *grid_to_inertial_map =
161 : my_block.moving_mesh_grid_to_inertial_map().get_clone();
162 : } else {
163 : *grid_to_inertial_map =
164 : ::domain::make_coordinate_map_base<Frame::Grid, Frame::Inertial>(
165 : ::domain::CoordinateMaps::Identity<dim>{});
166 : }
167 :
168 : for (const auto& [direction, neighbors] : element->neighbors()) {
169 : for (const auto& neighbor : neighbors) {
170 : const auto& neighbor_block = domain.blocks()[neighbor.block_id()];
171 : if (neighbors.are_conforming()) {
172 : const auto& neighbor_orientation = neighbors.orientation(neighbor);
173 : neighbor_mesh->emplace(
174 : DirectionalId{direction, neighbor},
175 : neighbor_orientation.inverse_map()(::domain::create_initial_mesh(
176 : initial_extents, neighbor_block, neighbor, i1_basis,
177 : i1_quadrature)));
178 : } else {
179 : neighbor_mesh->emplace(
180 : DirectionalId{direction, neighbor},
181 : ::domain::create_initial_mesh(initial_extents, neighbor_block,
182 : neighbor, i1_basis, i1_quadrature));
183 : }
184 : }
185 : }
186 : }
187 : };
188 :
189 : /// \brief Initialize/update items related to coordinate maps after an AMR
190 : /// change
191 : template <size_t Dim>
192 1 : struct ProjectDomain : tt::ConformsTo<amr::protocols::Projector> {
193 0 : using return_tags = tmpl::list<::domain::Tags::ElementMap<Dim, Frame::Grid>,
194 : ::domain::CoordinateMaps::Tags::CoordinateMap<
195 : Dim, Frame::Grid, Frame::Inertial>>;
196 0 : using argument_tags =
197 : tmpl::list<::domain::Tags::Domain<Dim>, ::domain::Tags::Element<Dim>>;
198 :
199 0 : static void apply(
200 : const gsl::not_null<ElementMap<Dim, Frame::Grid>*> /*element_map*/,
201 : const gsl::not_null<std::unique_ptr<
202 : ::domain::CoordinateMapBase<Frame::Grid, Frame::Inertial, Dim>>*>
203 : /*grid_to_inertial_map*/,
204 : const ::Domain<Dim>& /*domain*/, const Element<Dim>& /*element*/,
205 : const std::pair<Mesh<Dim>, Element<Dim>>& /*old_mesh_and_element*/) {
206 : // Do not change anything for p-refinement
207 : }
208 :
209 : template <typename ParentOrChildrenItemsType>
210 0 : static void apply(
211 : const gsl::not_null<ElementMap<Dim, Frame::Grid>*> element_map,
212 : const gsl::not_null<std::unique_ptr<
213 : ::domain::CoordinateMapBase<Frame::Grid, Frame::Inertial, Dim>>*>
214 : grid_to_inertial_map,
215 : const ::Domain<Dim>& domain, const Element<Dim>& element,
216 : const ParentOrChildrenItemsType& /*parent_or_children_items*/) {
217 : const ElementId<Dim>& element_id = element.id();
218 : const auto& my_block = domain.blocks()[element_id.block_id()];
219 : *element_map = ElementMap<Dim, Frame::Grid>{element_id, my_block};
220 : if (my_block.is_time_dependent()) {
221 : *grid_to_inertial_map =
222 : my_block.moving_mesh_grid_to_inertial_map().get_clone();
223 : } else {
224 : *grid_to_inertial_map =
225 : ::domain::make_coordinate_map_base<Frame::Grid, Frame::Inertial>(
226 : ::domain::CoordinateMaps::Identity<Dim>{});
227 : }
228 : }
229 : };
230 : } // namespace evolution::dg::Initialization
|