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 template <bool Linearized, size_t Dim, typename Registrars, typename DbTagsList,
35  typename... FieldsAndFluxes>
38  boundary_condition,
39  const db::DataBox<DbTagsList>& box, const Direction<Dim>& direction,
40  const gsl::not_null<FieldsAndFluxes*>... fields_and_fluxes) noexcept {
43  Dim, Registrars>::creatable_classes>(
44  &boundary_condition, [&direction, &box, &fields_and_fluxes...](
45  const auto* const derived) noexcept {
46  using Derived = std::decay_t<std::remove_pointer_t<decltype(derived)>>;
47  using argument_tags =
48  tmpl::conditional_t<Linearized,
49  typename Derived::argument_tags_linearized,
50  typename Derived::argument_tags>;
51  using volume_tags =
52  tmpl::conditional_t<Linearized,
53  typename Derived::volume_tags_linearized,
54  typename Derived::volume_tags>;
55  elliptic::util::apply_at<
56  tmpl::transform<
57  argument_tags,
59  tmpl::_1,
60  tmpl::pin<domain::Tags::BoundaryDirectionsInterior<Dim>>,
61  tmpl::pin<volume_tags>>>,
62  volume_tags>(
63  [&derived, &fields_and_fluxes...](const auto&... args) noexcept {
64  if constexpr (Linearized) {
65  derived->apply_linearized(fields_and_fluxes..., args...);
66  } else {
67  derived->apply(fields_and_fluxes..., args...);
68  }
69  },
70  box, direction);
71  });
72 }
73 } // namespace elliptic
elliptic::apply_boundary_condition
void apply_boundary_condition(const elliptic::BoundaryConditions::BoundaryCondition< Dim, Registrars > &boundary_condition, const db::DataBox< DbTagsList > &box, const Direction< Dim > &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:36
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
Direction< Dim >
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
type_traits
TMPL.hpp
gsl::not_null
Require a pointer to not be a nullptr
Definition: ReadSpecThirdOrderPiecewisePolynomial.hpp:13