ImposeBoundaryConditions.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <algorithm>
7 #include <cstddef>
8 #include <tuple>
9 #include <utility>
10 
14 #include "Domain/FaceNormal.hpp"
15 #include "Domain/Tags.hpp"
16 #include "ErrorHandling/Assert.hpp"
17 #include "NumericalAlgorithms/DiscontinuousGalerkin/Actions/InterfaceActionHelpers.hpp"
18 #include "NumericalAlgorithms/DiscontinuousGalerkin/FluxCommunicationTypes.hpp"
19 #include "NumericalAlgorithms/DiscontinuousGalerkin/MortarHelpers.hpp"
20 #include "NumericalAlgorithms/DiscontinuousGalerkin/Tags.hpp"
22 #include "Parallel/Invoke.hpp"
23 #include "PointwiseFunctions/AnalyticSolutions/Tags.hpp"
24 #include "Time/Tags.hpp"
25 #include "Utilities/Gsl.hpp"
26 #include "Utilities/TMPL.hpp"
28 #include "Utilities/TypeTraits.hpp"
29 
30 /// \cond
31 namespace Tags {
32 template <typename Tag>
33 struct Magnitude;
34 } // namespace Tags
35 // IWYU pragma: no_forward_declare db::DataBox
36 /// \endcond
37 
38 namespace dg {
39 namespace Actions {
40 /// \ingroup ActionsGroup
41 /// \ingroup DiscontinuousGalerkinGroup
42 /// \brief Packages data on external boundaries for calculating numerical flux.
43 /// Computes contributions on the interior side from the volume, and imposes
44 /// Dirichlet boundary conditions on the exterior side.
45 ///
46 /// With:
47 /// - Boundary<Tag> =
48 /// Tags::Interface<Tags::BoundaryDirections<volume_dim>, Tag>
49 /// - External<Tag> =
50 /// Tags::Interface<Tags::ExternalBoundaryDirections<volume_dim>, Tag>
51 ///
52 /// Uses:
53 /// - ConstGlobalCache:
54 /// - Metavariables::normal_dot_numerical_flux
55 /// - Metavariables::boundary_condition
56 /// - DataBox:
57 /// - Tags::Element<volume_dim>
58 /// - Boundary<Tags listed in
59 /// Metavariables::normal_dot_numerical_flux::type::argument_tags>
60 /// - External<Tags listed in
61 /// Metavariables::normal_dot_numerical_flux::type::argument_tags>
62 /// - Boundary<Tags::Mesh<volume_dim - 1>>
63 /// - External<Tags::Mesh<volume_dim - 1>>
64 /// - Boundary<Tags::Magnitude<Tags::UnnormalizedFaceNormal<volume_dim>>>,
65 /// - External<Tags::Magnitude<Tags::UnnormalizedFaceNormal<volume_dim>>>,
66 /// - Boundary<Tags::BoundaryCoordinates<volume_dim>>,
67 /// - Metavariables::temporal_id
68 ///
69 /// DataBox changes:
70 /// - Adds: nothing
71 /// - Removes: nothing
72 /// - Modifies:
73 /// - Tags::VariablesBoundaryData
74 /// - External<typename system::variables_tag>
75 ///
76 /// \see ReceiveDataForFluxes
77 template <typename Metavariables>
79  private:
80  // BoundaryConditionMethod and BcSelector are used to select exactly how to
81  // apply the Dirichlet boundary condition depending on properties of the
82  // system. An overloaded `apply_impl` method is used that implements the
83  // boundary condition calculation for the different types.
84  enum class BoundaryConditionMethod {
85  AnalyticBcNoPrimitives,
86  AnalyticBcFluxConservativeWithPrimitives,
87  Unknown
88  };
89  template <BoundaryConditionMethod Method>
91 
92  public:
93  using const_global_cache_tags =
94  tmpl::list<typename Metavariables::normal_dot_numerical_flux,
95  typename Metavariables::boundary_condition_tag>;
96 
97  template <typename DbTags, typename... InboxTags, typename ArrayIndex,
98  typename ActionList, typename ParallelComponent>
102  const ArrayIndex& /*array_index*/, const ActionList /*meta*/,
103  const ParallelComponent* const /*meta*/) noexcept {
104  using system = typename Metavariables::system;
105  return apply_impl<Metavariables::system::volume_dim>(
106  box, cache,
107  BcSelector<(not system::has_primitive_and_conservative_vars
108  ? BoundaryConditionMethod::AnalyticBcNoPrimitives
109  : (system::has_primitive_and_conservative_vars and
110  system::is_in_flux_conservative_form
111  ? BoundaryConditionMethod::
112  AnalyticBcFluxConservativeWithPrimitives
113  : BoundaryConditionMethod::Unknown))>{});
114  }
115 
116  private:
117  template <typename DbTags>
118  static void contribute_data_to_mortar(
120  const Parallel::ConstGlobalCache<Metavariables>& cache) noexcept {
121  using system = typename Metavariables::system;
122  constexpr size_t volume_dim = system::volume_dim;
123 
124  const auto& element = db::get<Tags::Element<volume_dim>>(*box);
125  const auto& temporal_id =
126  db::get<typename Metavariables::temporal_id>(*box);
127  const auto& normal_dot_numerical_flux_computer =
128  get<typename Metavariables::normal_dot_numerical_flux>(cache);
129 
130  for (const auto& direction : element.external_boundaries()) {
131  const auto mortar_id = std::make_pair(
133 
134  auto interior_data = DgActions_detail::compute_local_mortar_data(
135  *box, direction, normal_dot_numerical_flux_computer,
137 
138  auto exterior_data = DgActions_detail::compute_packaged_data(
139  *box, direction, normal_dot_numerical_flux_computer,
141 
142  db::mutate<Tags::VariablesBoundaryData>(
143  box, [&mortar_id, &temporal_id, &interior_data, &exterior_data ](
144  const gsl::not_null<
146  mortar_data) noexcept {
147  mortar_data->at(mortar_id).local_insert(temporal_id,
148  std::move(interior_data));
149  mortar_data->at(mortar_id).remote_insert(temporal_id,
150  std::move(exterior_data));
151  });
152  }
153  }
154 
155  template <size_t VolumeDim, typename DbTags>
156  static std::tuple<db::DataBox<DbTags>&&> apply_impl(
157  db::DataBox<DbTags>& box,
160  BoundaryConditionMethod,
161  BoundaryConditionMethod::AnalyticBcNoPrimitives> /*meta*/) noexcept {
162  using system = typename Metavariables::system;
163 
164  static_assert(
165  system::is_in_flux_conservative_form or
167  typename Metavariables::boundary_condition_tag>,
168  "Only analytic boundary conditions, or dirichlet boundary conditions "
169  "for conservative systems are implemented");
170 
171  // Apply the boundary condition
173  tmpl::list<Tags::Interface<Tags::BoundaryDirectionsExterior<VolumeDim>,
174  typename system::variables_tag>>,
175  tmpl::list<>>(
176  [](const gsl::not_null<db::item_type<
178  typename system::variables_tag>>*>
179  external_bdry_vars,
180  const double time, const auto& boundary_condition,
181  const auto& boundary_coords) noexcept {
182  for (auto& external_direction_and_vars : *external_bdry_vars) {
183  auto& direction = external_direction_and_vars.first;
184  auto& vars = external_direction_and_vars.second;
185  vars.assign_subset(boundary_condition.variables(
186  boundary_coords.at(direction), time,
187  typename system::variables_tag::type::tags_list{}));
188  }
189  },
190  make_not_null(&box), db::get<Tags::Time>(box).value(),
191  get<typename Metavariables::boundary_condition_tag>(cache),
194  box));
195 
196  contribute_data_to_mortar(make_not_null(&box), cache);
197  return std::forward_as_tuple(std::move(box));
198  }
199 
200  template <typename TagsList, typename... ReturnTags, typename... ArgumentTags,
201  typename System>
202  static void apply_impl_helper_conservative_from_primitive(
203  const gsl::not_null<Variables<TagsList>*> conservative_vars,
204  const tuples::TaggedTuple<ArgumentTags...>& argument_vars,
205  tmpl::list<ReturnTags...> /*meta*/, tmpl::list<System> /*meta*/
206  ) noexcept {
208  make_not_null(&get<ReturnTags>(*conservative_vars))...,
209  get<ArgumentTags>(argument_vars)...);
210  }
211 
212  template <size_t VolumeDim, typename DbTags>
213  static std::tuple<db::DataBox<DbTags>&&> apply_impl(
214  db::DataBox<DbTags>& box,
217  BoundaryConditionMethod,
218  BoundaryConditionMethod::
219  AnalyticBcFluxConservativeWithPrimitives> /*meta*/) noexcept {
220  using system = typename Metavariables::system;
221 
222  static_assert(
223  system::is_in_flux_conservative_form and
224  system::has_primitive_and_conservative_vars and
226  typename Metavariables::boundary_condition_tag>,
227  "Only analytic boundary conditions, or dirichlet boundary conditions "
228  "for conservative systems are implemented");
229 
230  // Apply the boundary condition
232  tmpl::list<Tags::Interface<Tags::BoundaryDirectionsExterior<VolumeDim>,
233  typename system::variables_tag>>,
234  tmpl::list<>>(
235  [](const gsl::not_null<db::item_type<
237  typename system::variables_tag>>*>
238  external_bdry_vars,
239  const double time, const auto& boundary_condition,
240  const auto& boundary_coords) noexcept {
241  for (auto& external_direction_and_vars : *external_bdry_vars) {
242  auto& direction = external_direction_and_vars.first;
243  auto& vars = external_direction_and_vars.second;
244 
245  apply_impl_helper_conservative_from_primitive(
246  make_not_null(&vars),
247  boundary_condition.variables(
248  boundary_coords.at(direction), time,
249  typename system::conservative_from_primitive::
250  argument_tags{}),
251  typename system::conservative_from_primitive::return_tags{},
252  tmpl::list<system>{});
253  }
254  },
255  make_not_null(&box), db::get<Tags::Time>(box).value(),
256  get<typename Metavariables::boundary_condition_tag>(cache),
259  box));
260 
261  contribute_data_to_mortar(make_not_null(&box), cache);
262  return std::forward_as_tuple(std::move(box));
263  }
264 };
265 } // namespace Actions
266 } // namespace dg
Defines class tuples::TaggedTuple.
constexpr auto mutate_apply(F f, const gsl::not_null< DataBox< BoxTags > *> box, Args &&... args) noexcept(DataBox_detail::check_mutate_apply_mutate_tags(BoxTags{}, MutateTags{}) and DataBox_detail::check_mutate_apply_argument_tags(BoxTags{}, ArgumentTags{}) and noexcept(DataBox_detail::mutate_apply(f, box, MutateTags{}, ArgumentTags{}, std::forward< Args >(args)...)))
Apply the function f mutating items MutateTags and taking as additional arguments ArgumentTags and ar...
Definition: DataBox.hpp:1773
Definition: InitializeElement.hpp:63
An ElementId uniquely labels an Element. It is constructed from the BlockId of the Block to which the...
Definition: ElementId.hpp:36
The analytic solution, with the type of the analytic solution set as the template parameter...
Definition: Tags.hpp:22
The set of directions which correspond to external boundaries. Used for representing data on the inte...
Definition: Tags.hpp:163
constexpr auto apply(F &&f, const DataBox< BoxTags > &box, Args &&... args)
Apply the function f with argument Tags TagsList from DataBox box
Definition: DataBox.hpp:1595
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:272
Defines classes and functions used for manipulating DataBox&#39;s.
constexpr bool is_same_v
Variable template for is_same.
Definition: TypeTraits.hpp:221
Definition: InterpolationTargetWedgeSectionTorus.hpp:24
Definition: DataBoxTag.hpp:29
A Charm++ chare that caches constant data once per Charm++ node.
Definition: ConstGlobalCache.hpp:76
Declares function unnormalized_face_normal.
The coordinates in a given frame.
Definition: Tags.hpp:95
Defines macro ASSERT.
const auto & get(const DataBox< TagList > &box) noexcept
Retrieve the item with tag Tag from the DataBox.
Definition: DataBox.hpp:1211
The global cache tag that retrieves the parameters for the numerical flux from the input file...
Definition: Tags.hpp:59
The Poisson equation formulated as a set of coupled first-order PDEs.
Definition: FirstOrderSystem.hpp:55
Wraps the template metaprogramming library used (brigand)
Packages data on external boundaries for calculating numerical flux. Computes contributions on the in...
Definition: ImposeBoundaryConditions.hpp:78
typename DataBox_detail::item_type_impl< TagList, Tag >::type item_type
Get the type that is returned by the Tag. If it is a base tag then a TagList must be passed as a seco...
Definition: DataBoxTag.hpp:410
Defines functions and classes from the GSL.
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, but it may be necessary to perform the conversion explicitly when type deduction is desired.
Definition: Gsl.hpp:863
Defines tags related to domain quantities.
Defines helper functions for use with Variables class.
Definition: SolvePoissonProblem.hpp:38
Defines classes SimpleTag, PrefixTag, ComputeTag and several functions for retrieving tag info...
Defines class template ConstGlobalCache.
Defines type traits, some of which are future STL type_traits header.
The set of directions which correspond to external boundaries. To be used to represent data which exi...
Definition: Tags.hpp:177
Tag which is either a SimpleTag for quantities on an interface, base tag to a compute item which acts...
Definition: Tags.hpp:217
Defines tags related to Time quantities.
Definition: ComputeTimeDerivative.hpp:28
Require a pointer to not be a nullptr
Definition: ConservativeFromPrimitive.hpp:12