ApplyBoundaryCondition.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <cstddef>
7 #include <type_traits>
8 
10 #include "Domain/InterfaceHelpers.hpp"
12 #include "Domain/Tags.hpp"
13 #include "Elliptic/BoundaryConditions/BoundaryCondition.hpp"
15 #include "Utilities/FakeVirtual.hpp"
16 #include "Utilities/Gsl.hpp"
17 #include "Utilities/TMPL.hpp"
18 
19 namespace elliptic {
20 /*!
21  * \brief Apply the `boundary_condition` to the `fields_and_fluxes` with
22  * arguments from interface tags in the DataBox.
23  *
24  * This functions assumes the arguments for the `boundary_condition` are stored
25  * in the DataBox in tags
26  * `domain::Tags::Interface<domain::Tags::BoundaryDirectionsInterior<Dim>,
27  * Tag>`. This may turn out not to be the most efficient setup, so code that
28  * uses the boundary conditions doesn't have to use this function but can
29  * procure the arguments differently. For example, future optimizations may
30  * involve storing a subset of arguments that don't change during an elliptic
31  * solve in direction-maps in the DataBox, and slicing other arguments to the
32  * interface every time the boundary conditions are applied.
33  *
34  * The `ArgsTransform` template parameter can be used to transform the set of
35  * argument tags for the boundary conditions further. It must be compatible with
36  * `tmpl::transform`. For example, it may wrap the tags in another prefix. Set
37  * it to `void` (default) to apply no transformation.
38  */
39 template <bool Linearized, typename ArgsTransform = void, size_t Dim,
40  typename Registrars, typename DbTagsList, typename MapKeys,
41  typename... FieldsAndFluxes>
44  boundary_condition,
45  const db::DataBox<DbTagsList>& box, const MapKeys& map_keys_to_direction,
46  const gsl::not_null<FieldsAndFluxes*>... fields_and_fluxes) noexcept {
49  Dim, Registrars>::creatable_classes>(
50  &boundary_condition,
51  [&map_keys_to_direction, &box,
52  &fields_and_fluxes...](const auto* const derived) noexcept {
53  using Derived = std::decay_t<std::remove_pointer_t<decltype(derived)>>;
54  using volume_tags =
55  tmpl::conditional_t<Linearized,
56  typename Derived::volume_tags_linearized,
57  typename Derived::volume_tags>;
58  using argument_tags = tmpl::transform<
59  tmpl::conditional_t<Linearized,
60  typename Derived::argument_tags_linearized,
61  typename Derived::argument_tags>,
63  tmpl::_1,
64  tmpl::pin<domain::Tags::BoundaryDirectionsInterior<Dim>>,
65  tmpl::pin<volume_tags>>>;
66  using argument_tags_transformed =
67  tmpl::conditional_t<std::is_same_v<ArgsTransform, void>,
68  argument_tags,
69  tmpl::transform<argument_tags, ArgsTransform>>;
70  using volume_tags_transformed =
71  tmpl::conditional_t<std::is_same_v<ArgsTransform, void>,
72  volume_tags,
73  tmpl::transform<volume_tags, ArgsTransform>>;
74  elliptic::util::apply_at<argument_tags_transformed,
75  volume_tags_transformed>(
76  [&derived, &fields_and_fluxes...](const auto&... args) noexcept {
77  if constexpr (Linearized) {
78  derived->apply_linearized(fields_and_fluxes..., args...);
79  } else {
80  derived->apply(fields_and_fluxes..., args...);
81  }
82  },
83  box, map_keys_to_direction);
84  });
85 }
86 } // namespace elliptic
Tags.hpp
call_with_dynamic_type
Result call_with_dynamic_type(Base *const obj, Callable &&f) noexcept
Call a functor with the derived type of a base class pointer.
Definition: FakeVirtual.hpp:103
make_interface_tag
Definition: InterfaceHelpers.hpp:35
DataBox.hpp
cstddef
elliptic::BoundaryConditions::BoundaryCondition
Base class for boundary conditions for elliptic systems.
Definition: BoundaryCondition.hpp:91
std::decay_t
ApplyAt.hpp
std::remove_pointer_t
Gsl.hpp
elliptic
Functionality related to solving elliptic partial differential equations.
Definition: InitializeAnalyticSolution.hpp:29
Direction.hpp
elliptic::apply_boundary_condition
void apply_boundary_condition(const elliptic::BoundaryConditions::BoundaryCondition< Dim, Registrars > &boundary_condition, const db::DataBox< DbTagsList > &box, const MapKeys &map_keys_to_direction, const gsl::not_null< FieldsAndFluxes * >... fields_and_fluxes) noexcept
Apply the boundary_condition to the fields_and_fluxes with arguments from interface tags in the DataB...
Definition: ApplyBoundaryCondition.hpp:42
type_traits
TMPL.hpp
gsl::not_null
Require a pointer to not be a nullptr
Definition: ReadSpecPiecewisePolynomial.hpp:13