InitializeFirstOrderOperator.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 
10 #include "DataStructures/DataBox/PrefixHelpers.hpp"
14 #include "Domain/Tags.hpp"
15 #include "Elliptic/FirstOrderComputeTags.hpp"
16 #include "Elliptic/Tags.hpp"
17 #include "NumericalAlgorithms/DiscontinuousGalerkin/NormalDotFlux.hpp"
18 #include "NumericalAlgorithms/LinearOperators/Divergence.tpp"
20 #include "ParallelAlgorithms/Initialization/MutateAssign.hpp"
21 #include "Utilities/TMPL.hpp"
22 
23 /// \cond
24 namespace Parallel {
25 template <typename Metavariables>
26 struct GlobalCache;
27 } // namespace Parallel
28 namespace tuples {
29 template <typename... Tags>
30 struct TaggedTuple;
31 } // namespace tuples
32 /// \endcond
33 
34 namespace elliptic {
35 namespace dg {
36 namespace Actions {
37 
38 /*!
39  * \brief Initialize DataBox tags for building the first-order elliptic DG
40  * operator
41  *
42  * \note This action relies on the `SetupDataBox` aggregated initialization
43  * mechanism, so `Actions::SetupDataBox` must be present in the `Initialization`
44  * phase action list prior to this action.
45  */
46 template <size_t Dim, typename FluxesComputer, typename SourcesComputer,
47  typename VariablesTag, typename PrimalVariables,
48  typename AuxiliaryVariables>
50  private:
51  static constexpr size_t volume_dim = Dim;
52  using vars_tag = VariablesTag;
55  using fluxes_tag =
58  using div_fluxes_tag = db::add_tag_prefix<::Tags::div, fluxes_tag>;
59  using inv_jacobian_tag =
61 
62  template <typename Directions>
63  using face_tags =
64  tmpl::list<domain::Tags::Slice<Directions, vars_tag>,
67  // For the strong first-order DG scheme we also need the
68  // interface normal dotted into the fluxes
70  Directions, ::Tags::NormalDotFluxCompute<
71  vars_tag, volume_dim, Frame::Inertial>>>;
72 
73  using fluxes_compute_tag =
74  elliptic::Tags::FirstOrderFluxesCompute<volume_dim, FluxesComputer,
75  vars_tag, PrimalVariables,
76  AuxiliaryVariables>;
78  Dim, SourcesComputer, vars_tag, PrimalVariables, AuxiliaryVariables>;
79 
80  using exterior_tags = tmpl::list<
81  // On exterior (ghost) boundary faces we compute the fluxes from the
82  // data that is being set there to impose boundary conditions. Then, we
83  // compute their normal-dot-fluxes. The flux divergences are sliced from
84  // the volume.
92  div_fluxes_tag>>;
93 
94  public:
95  using simple_tags = tmpl::list<exterior_vars_tag>;
96  using compute_tags = tmpl::flatten<tmpl::list<
99  face_tags<domain::Tags::InternalDirections<volume_dim>>,
100  face_tags<domain::Tags::BoundaryDirectionsInterior<volume_dim>>,
101  exterior_tags>>;
102 
103  template <typename DbTagsList, typename... InboxTags, typename Metavariables,
104  typename ArrayIndex, typename ActionList,
105  typename ParallelComponent>
106  static auto apply(db::DataBox<DbTagsList>& box,
107  const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
108  const Parallel::GlobalCache<Metavariables>& /*cache*/,
109  const ArrayIndex& /*array_index*/,
110  const ActionList /*meta*/,
111  const ParallelComponent* const /*meta*/) noexcept {
112  // Initialize the variables on exterior (ghost) boundary faces. They are
113  // updated throughout the algorithm to impose boundary conditions.
114  typename exterior_vars_tag::type exterior_boundary_vars{};
115  const auto& mesh = db::get<domain::Tags::Mesh<volume_dim>>(box);
116  for (const auto& direction : db::get<domain::Tags::Element<volume_dim>>(box)
117  .external_boundaries()) {
118  exterior_boundary_vars[direction] = typename vars_tag::type{
119  mesh.slice_away(direction.dimension()).number_of_grid_points()};
120  }
121  Initialization::mutate_assign<simple_tags>(
122  make_not_null(&box), std::move(exterior_boundary_vars));
123  return std::make_tuple(std::move(box));
124  }
125 };
126 } // namespace Actions
127 } // namespace dg
128 } // namespace elliptic
Tags::NormalDotFluxCompute
Prefix computing a boundary unit normal vector dotted into the flux from a flux on the boundary.
Definition: NormalDotFlux.hpp:78
elliptic::Tags::FirstOrderFluxesCompute
Definition: FirstOrderComputeTags.hpp:22
Frame::Inertial
Definition: IndexType.hpp:44
Parallel::GlobalCache
Definition: ElementReceiveInterpPoints.hpp:15
Tags.hpp
domain::Tags::Element
Definition: Tags.hpp:97
Tags::DivVariablesCompute
Compute the divergence of a Variables.
Definition: Divergence.hpp:119
db::add_tag_prefix
typename detail::add_tag_prefix_impl< Prefix, Tag, Args... >::type add_tag_prefix
Definition: PrefixHelpers.hpp:51
domain::Tags::BoundaryDirectionsExterior
Definition: Tags.hpp:324
tuple
db::get
const auto & get(const DataBox< TagList > &box) noexcept
Retrieve the item with tag Tag from the DataBox.
Definition: DataBox.hpp:786
elliptic::Tags::FirstOrderSourcesCompute
Definition: FirstOrderComputeTags.hpp:50
dg
Functionality related to discontinuous Galerkin schemes.
Definition: ComputeNonconservativeBoundaryFluxes.hpp:23
domain::Tags::Slice
Compute tag for representing a compute item that slices data from the volume to a set of interfaces.
Definition: InterfaceComputeTags.hpp:115
DataBox.hpp
cstddef
domain::Tags::InverseJacobian< Dim, Frame::Logical, Frame::Inertial >
tuples::TaggedTuple
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:271
Variables.hpp
Element.hpp
domain::Tags::Interface
Tag which is either a SimpleTag for quantities on an interface, base tag to a compute item which acts...
Definition: Tags.hpp:366
domain::Tags::InterfaceCompute
Compute tag for representing items computed on a set of interfaces. Can be retrieved using Tags::Inte...
Definition: InterfaceComputeTags.hpp:67
elliptic
Functionality related to solving elliptic partial differential equations.
Definition: InitializeAnalyticSolution.hpp:29
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
elliptic::dg::Actions::InitializeFirstOrderOperator
Initialize DataBox tags for building the first-order elliptic DG operator.
Definition: InitializeFirstOrderOperator.hpp:49
Prefixes.hpp
std::unordered_map
Parallel
Functionality for parallelization.
Definition: ElementReceiveInterpPoints.hpp:13
TMPL.hpp
Mesh.hpp