Initialize.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <cstddef>
7 #include <tuple>
8 #include <type_traits>
9 #include <utility>
10 
13 #include "Domain/Tags.hpp"
14 #include "Evolution/DgSubcell/ActiveGrid.hpp"
15 #include "Evolution/DgSubcell/Mesh.hpp"
16 #include "Evolution/DgSubcell/NeighborData.hpp"
17 #include "Evolution/DgSubcell/Projection.hpp"
18 #include "Evolution/DgSubcell/Tags/ActiveGrid.hpp"
19 #include "Evolution/DgSubcell/Tags/Coordinates.hpp"
20 #include "Evolution/DgSubcell/Tags/DidRollback.hpp"
21 #include "Evolution/DgSubcell/Tags/Inactive.hpp"
22 #include "Evolution/DgSubcell/Tags/Jacobians.hpp"
23 #include "Evolution/DgSubcell/Tags/Mesh.hpp"
24 #include "Evolution/DgSubcell/Tags/NeighborData.hpp"
25 #include "Evolution/DgSubcell/Tags/SubcellOptions.hpp"
26 #include "Evolution/DgSubcell/Tags/TciGridHistory.hpp"
27 #include "Evolution/DgSubcell/Tags/TciStatus.hpp"
28 #include "Evolution/DgSubcell/TciStatus.hpp"
29 #include "Evolution/Initialization/SetVariables.hpp"
31 #include "Parallel/GlobalCache.hpp"
32 #include "Utilities/TMPL.hpp"
33 #include "Utilities/TaggedTuple.hpp"
34 
36 /*!
37  * \brief Initialize the subcell grid, and switch from DG to subcell if the DG
38  * solution is inadmissible.
39  *
40  * Interior cells are marked as troubled if
41  * `subcell_options.always_use_subcells()` is `true` or if
42  * `Metavariables::SubcellOptions::DgInitialDataTci::apply` reports that the
43  * initial data is not well represented on the DG grid for that cell. Exterior
44  * cells are never marked as troubled, because subcell doesn't yet support
45  * boundary conditions.
46  *
47  * If the cell is troubled then `Tags::ActiveGrid` is set to
48  * `subcell::ActiveGrid::Subcell`, the `System::variables_tag` become the
49  * variables on the subcell grid set by calling
50  * `evolution::Initialization::Actions::SetVariables`,
51  * ` Tags::Inactive<System::variables_tag>` become the (inadmissible) DG
52  * solution, and the `db::add_tag_prefix<Tags::dt, System::variables_tag>` are
53  * resized to the subcell grid with an `ASSERT` requiring that they were
54  * previously set to the size of the DG grid (this is to reduce the likelihood
55  * of them being resized back to the DG grid later).
56  *
57  * \details `Metavariables::SubcellOptions::DgInitialDataTci::apply` is called
58  * with the evolved variables on the DG grid, the projected evolved variables,
59  * the DG mesh, the initial RDMP parameters \f$\delta_0\f$ and \f$\epsilon\f$,
60  * and the Persson TCI parameter \f$\alpha\f$. The apply function must return a
61  * `bool` that is `true` if the cell is troubled.
62  *
63  * GlobalCache:
64  * - Uses:
65  * - `subcell::Tags::SubcellOptions`
66  *
67  * DataBox:
68  * - Uses:
69  * - `domain::Tags::Mesh<Dim>`
70  * - `domain::Tags::Element<Dim>`
71  * - `System::variables_tag`
72  * - Adds:
73  * - `subcell::Tags::Mesh<Dim>`
74  * - `subcell::Tags::ActiveGrid`
75  * - `subcell::Tags::DidRollback`
76  * - `subcell::Tags::Inactive<System::variables_tag>`
77  * - `subcell::Tags::TciGridHistory`
78  * - `subcell::Tags::NeighborDataForReconstructionAndRdmpTci<Dim>`
79  * - `subcell::fd::Tags::InverseJacobianLogicalToGrid<Dim>`
80  * - `subcell::fd::Tags::DetInverseJacobianLogicalToGrid`
81  * - `subcell::Tags::LogicalCoordinates<Dim>`
82  * - `subcell::Tags::Corodinates<Dim, Frame::Grid>` (as compute tag)
83  * - `subcell::Tags::TciStatusCompute<Dim>`
84  * - Removes: nothing
85  * - Modifies:
86  * - `System::variables_tag` if the cell is troubled
87  * - `Tags::dt<System::variables_tag>` if the cell is troubled
88  */
89 template <size_t Dim, typename System, typename TciMutator>
90 struct Initialize {
91  using const_global_cache_tags = tmpl::list<Tags::SubcellOptions>;
92 
93  using simple_tags =
94  tmpl::list<Tags::Mesh<Dim>, Tags::ActiveGrid, Tags::DidRollback,
100  using compute_tags =
101  tmpl::list<Tags::LogicalCoordinatesCompute<Dim>,
107 
108  template <typename DbTagsList, typename... InboxTags, typename ArrayIndex,
109  typename ActionList, typename ParallelComponent,
110  typename Metavariables>
111  static std::tuple<db::DataBox<DbTagsList>&&> apply(
112  db::DataBox<DbTagsList>& box,
113  const tuples::TaggedTuple<InboxTags...>& inboxes,
115  const ArrayIndex& array_index, ActionList /*meta*/,
116  const ParallelComponent* const /*meta*/) noexcept {
117  const SubcellOptions& subcell_options = db::get<Tags::SubcellOptions>(box);
118  const Mesh<Dim>& dg_mesh = db::get<::domain::Tags::Mesh<Dim>>(box);
119  const Mesh<Dim> subcell_mesh = fd::mesh(dg_mesh);
120  // Note: we currently cannot do subcell at boundaries, so only set on
121  // interior elements.
122  bool cell_is_troubled = subcell_options.always_use_subcells() and
123  db::get<::domain::Tags::Element<Dim>>(box)
124  .external_boundaries()
125  .empty();
126  db::mutate_apply<tmpl::list<subcell::Tags::Mesh<Dim>, Tags::ActiveGrid,
129  typename System::variables_tag>,
130  typename TciMutator::argument_tags>(
131  [&cell_is_troubled, &dg_mesh, &subcell_mesh, &subcell_options](
132  const gsl::not_null<Mesh<Dim>*> subcell_mesh_ptr,
133  const gsl::not_null<ActiveGrid*> active_grid_ptr,
134  const gsl::not_null<bool*> did_rollback_ptr,
135  const auto inactive_vars_ptr, const auto active_vars_ptr,
136  const auto&... args_for_tci) noexcept {
137  // We don't consider setting the initial grid to subcell as rolling
138  // back. Since no time step is undone, we just continue on the
139  // subcells as a normal solve.
140  *did_rollback_ptr = false;
141 
142  *subcell_mesh_ptr = subcell_mesh;
143  *active_grid_ptr = ActiveGrid::Dg;
144  fd::project(inactive_vars_ptr, *active_vars_ptr, dg_mesh,
145  subcell_mesh.extents());
146  // Now check if the DG solution is admissible
147  cell_is_troubled |= TciMutator::apply(
148  *active_vars_ptr, *inactive_vars_ptr,
149  subcell_options.initial_data_rdmp_delta0(),
150  subcell_options.initial_data_rdmp_epsilon(),
151  subcell_options.initial_data_persson_exponent(), args_for_tci...);
152  if (cell_is_troubled) {
153  // Swap grid
154  *active_grid_ptr = ActiveGrid::Subcell;
155  using std::swap;
156  swap(*active_vars_ptr, *inactive_vars_ptr);
157  }
158  },
159  make_not_null(&box));
160  if (cell_is_troubled) {
161  // Set variables on subcells.
162  if constexpr (System::has_primitive_and_conservative_vars) {
163  db::mutate<typename System::primitive_variables_tag>(
164  make_not_null(&box),
165  [&subcell_mesh](const auto prim_vars_ptr) noexcept {
166  prim_vars_ptr->initialize(subcell_mesh.number_of_grid_points());
167  });
168  }
169  evolution::Initialization::Actions::
170  SetVariables<Tags::Coordinates<Dim, Frame::Logical>>::apply(
171  box, inboxes, cache, array_index, ActionList{},
173  db::mutate<
175  make_not_null(&box),
176  [&dg_mesh, &subcell_mesh](const auto dt_vars_ptr) noexcept {
177  ASSERT(dt_vars_ptr->number_of_grid_points() ==
178  dg_mesh.number_of_grid_points(),
179  "Subcell is resizing the time derivative variables and "
180  "expected them to be the size of the DG grid ("
181  << dg_mesh.number_of_grid_points() << ") but got "
182  << dt_vars_ptr->number_of_grid_points());
183  dt_vars_ptr->initialize(subcell_mesh.number_of_grid_points(), 0.0);
184  });
185  }
186  return std::forward_as_tuple(std::move(box));
187  }
188 };
189 } // namespace evolution::dg::subcell::Actions
evolution::dg::subcell::Actions::Initialize
Initialize the subcell grid, and switch from DG to subcell if the DG solution is inadmissible.
Definition: Initialize.hpp:90
evolution::dg::subcell::Actions
Actions for the DG-subcell hybrid solver.
Definition: Actions.hpp:9
utility
evolution::dg::subcell::fd::project
DataVector project(const DataVector &dg_u, const Mesh< Dim > &dg_mesh, const Index< Dim > &subcell_extents) noexcept
Project the variable dg_u onto the subcell grid with extents subcell_extents.
evolution::dg::subcell::fd::Tags::InverseJacobianLogicalToGrid
The inverse Jacobian from the logical frame to the grid frame at the cell centers.
Definition: Jacobians.hpp:22
Parallel::GlobalCache
Definition: ElementReceiveInterpPoints.hpp:15
GlobalCache.hpp
Tags.hpp
db::add_tag_prefix
typename detail::add_tag_prefix_impl< Prefix, Tag, Args... >::type add_tag_prefix
Definition: PrefixHelpers.hpp:51
tuple
evolution::dg::subcell::fd::mesh
Mesh< Dim > mesh(const Mesh< Dim > &dg_mesh) noexcept
Computes the cell-centered finite-difference mesh from the DG mesh, using grid points per dimension,...
evolution::dg::subcell::ActiveGrid
ActiveGrid
Definition: ActiveGrid.hpp:11
db::mutate
decltype(auto) mutate(const gsl::not_null< DataBox< TagList > * > box, Invokable &&invokable, Args &&... args) noexcept
Allows changing the state of one or more non-computed elements in the DataBox.
Definition: DataBox.hpp:641
std::add_pointer_t
evolution::dg::subcell::Tags::NeighborDataForReconstructionAndRdmpTci
The neighbor data for reconstruction and the RDMP troubled-cell indicator.
Definition: NeighborData.hpp:25
DataBox.hpp
cstddef
evolution::dg::subcell::Tags::TciGridHistory
A record of which grid the TCI requested we use.
Definition: TciGridHistory.hpp:20
tuples::TaggedTuple
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:271
evolution::dg::subcell::SubcellOptions
Holds the system-agnostic subcell parameters, such as numbers controlling when to switch between DG a...
Definition: SubcellOptions.hpp:23
domain::Tags::MappedCoordinates
Definition: Tags.hpp:143
ASSERT
#define ASSERT(a, m)
Assert that an expression should be true.
Definition: Assert.hpp:49
Element.hpp
Mesh
Holds the number of grid points, basis, and quadrature in each direction of the computational grid.
Definition: Mesh.hpp:49
ActionTesting::cache
Parallel::GlobalCache< Metavariables > & cache(MockRuntimeSystem< Metavariables > &runner, const ArrayIndex &array_index) noexcept
Returns the GlobalCache of Component with index array_index.
Definition: MockRuntimeSystemFreeFunctions.hpp:382
make_not_null
gsl::not_null< T * > make_not_null(T *ptr) noexcept
Construct a not_null from a pointer. Often this will be done as an implicit conversion,...
Definition: Gsl.hpp:880
evolution::dg::subcell::Tags::DidRollback
Tag indicating whether we are retrying a step after a rollback of a failed DG step.
Definition: DidRollback.hpp:16
evolution::dg::subcell::fd::Tags::DetInverseJacobianLogicalToGrid
The determinant of the inverse Jacobian from the logical frame to the grid frame at the cell centers.
Definition: Jacobians.hpp:33
evolution::dg::subcell::Tags::Inactive
Mark a tag as holding data for the inactive grid.
Definition: Inactive.hpp:23
evolution::dg::subcell::Tags::Coordinates
The coordinates in a given frame.
Definition: Coordinates.hpp:27
evolution::dg::subcell::Tags::TciStatusCompute
Computes the TCI status from the currently active grid and the TCI history.
Definition: TciStatus.hpp:33
type_traits
TMPL.hpp
Mesh.hpp
gsl::not_null
Require a pointer to not be a nullptr
Definition: ReadSpecPiecewisePolynomial.hpp:13
domain::Tags::ElementMap
Definition: Tags.hpp:115