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`, and
51  * ` Tags::Inactive<System::variables_tag>` become the (inadmissible) DG
52  * solution.
53  *
54  * \details `Metavariables::SubcellOptions::DgInitialDataTci::apply` is called
55  * with the evolved variables on the DG grid, the projected evolved variables,
56  * the DG mesh, the initial RDMP parameters \f$\delta_0\f$ and \f$\epsilon\f$,
57  * and the Persson TCI parameter \f$\alpha\f$. The apply function must return a
58  * `bool` that is `true` if the cell is troubled.
59  *
60  * GlobalCache:
61  * - Uses:
62  * - `subcell::Tags::SubcellOptions`
63  *
64  * DataBox:
65  * - Uses:
66  * - `domain::Tags::Mesh<Dim>`
67  * - `domain::Tags::Element<Dim>`
68  * - `System::variables_tag`
69  * - Adds:
70  * - `subcell::Tags::Mesh<Dim>`
71  * - `subcell::Tags::ActiveGrid`
72  * - `subcell::Tags::DidRollback`
73  * - `subcell::Tags::Inactive<System::variables_tag>`
74  * - `subcell::Tags::TciGridHistory`
75  * - `subcell::Tags::NeighborDataForReconstructionAndRdmpTci<Dim>`
76  * - `subcell::fd::Tags::InverseJacobianLogicalToGrid<Dim>`
77  * - `subcell::fd::Tags::DetInverseJacobianLogicalToGrid`
78  * - `subcell::Tags::LogicalCoordinates<Dim>`
79  * - `subcell::Tags::Corodinates<Dim, Frame::Grid>` (as compute tag)
80  * - `subcell::Tags::TciStatusCompute<Dim>`
81  * - Removes: nothing
82  * - Modifies:
83  * - `System::variables_tag` if the cell is troubled
84  */
85 template <size_t Dim, typename System, typename TciMutator>
86 struct Initialize {
87  using const_global_cache_tags = tmpl::list<Tags::SubcellOptions>;
88 
89  using simple_tags =
90  tmpl::list<Tags::Mesh<Dim>, Tags::ActiveGrid, Tags::DidRollback,
96  using compute_tags =
97  tmpl::list<Tags::LogicalCoordinatesCompute<Dim>,
103 
104  template <typename DbTagsList, typename... InboxTags, typename ArrayIndex,
105  typename ActionList, typename ParallelComponent,
106  typename Metavariables>
107  static std::tuple<db::DataBox<DbTagsList>&&> apply(
108  db::DataBox<DbTagsList>& box,
109  const tuples::TaggedTuple<InboxTags...>& inboxes,
111  const ArrayIndex& array_index, ActionList /*meta*/,
112  const ParallelComponent* const /*meta*/) noexcept {
113  const SubcellOptions& subcell_options = db::get<Tags::SubcellOptions>(box);
114  const Mesh<Dim>& dg_mesh = db::get<::domain::Tags::Mesh<Dim>>(box);
115  const Mesh<Dim> subcell_mesh = fd::mesh(dg_mesh);
116  // Note: we currently cannot do subcell at boundaries, so only set on
117  // interior elements.
118  bool cell_is_troubled = subcell_options.always_use_subcells() and
119  db::get<::domain::Tags::Element<Dim>>(box)
120  .external_boundaries()
121  .empty();
122  db::mutate_apply<tmpl::list<subcell::Tags::Mesh<Dim>, Tags::ActiveGrid,
125  typename System::variables_tag>,
126  typename TciMutator::argument_tags>(
127  [&cell_is_troubled, &dg_mesh, &subcell_mesh, &subcell_options](
128  const gsl::not_null<Mesh<Dim>*> subcell_mesh_ptr,
129  const gsl::not_null<ActiveGrid*> active_grid_ptr,
130  const gsl::not_null<bool*> did_rollback_ptr,
131  const auto inactive_vars_ptr, const auto active_vars_ptr,
132  const auto&... args_for_tci) noexcept {
133  // We don't consider setting the initial grid to subcell as rolling
134  // back. Since no time step is undone, we just continue on the
135  // subcells as a normal solve.
136  *did_rollback_ptr = false;
137 
138  *subcell_mesh_ptr = subcell_mesh;
139  *active_grid_ptr = ActiveGrid::Dg;
140  fd::project(inactive_vars_ptr, *active_vars_ptr, dg_mesh,
141  subcell_mesh.extents());
142  // Now check if the DG solution is admissible
143  cell_is_troubled |= TciMutator::apply(
144  *active_vars_ptr, *inactive_vars_ptr,
145  subcell_options.initial_data_rdmp_delta0(),
146  subcell_options.initial_data_rdmp_epsilon(),
147  subcell_options.initial_data_persson_exponent(), args_for_tci...);
148  if (cell_is_troubled) {
149  // Swap grid
150  *active_grid_ptr = ActiveGrid::Subcell;
151  using std::swap;
152  swap(*active_vars_ptr, *inactive_vars_ptr);
153  }
154  },
155  make_not_null(&box));
156  if (cell_is_troubled) {
157  // Set variables on subcells.
158  if constexpr (System::has_primitive_and_conservative_vars) {
159  db::mutate<typename System::primitive_variables_tag>(
160  make_not_null(&box),
161  [&subcell_mesh](const auto prim_vars_ptr) noexcept {
162  prim_vars_ptr->initialize(subcell_mesh.number_of_grid_points());
163  });
164  }
165  evolution::Initialization::Actions::
166  SetVariables<Tags::Coordinates<Dim, Frame::Logical>>::apply(
167  box, inboxes, cache, array_index, ActionList{},
169  }
170  return std::forward_as_tuple(std::move(box));
171  }
172 };
173 } // 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:86
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
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
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
Element.hpp
Mesh
Holds the number of grid points, basis, and quadrature in each direction of the computational grid.
Definition: Mesh.hpp:48
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: ReadSpecThirdOrderPiecewisePolynomial.hpp:13
domain::Tags::ElementMap
Definition: Tags.hpp:115