ApplyBoundaryFluxesLocalTimeStepping.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 
12 #include "Domain/IndexToSliceAt.hpp"
13 #include "Domain/Tags.hpp" // IWYU pragma: keep // for db::item_type<Tags::Mesh<...>>
14 #include "NumericalAlgorithms/DiscontinuousGalerkin/FluxCommunicationTypes.hpp"
15 #include "NumericalAlgorithms/DiscontinuousGalerkin/MortarHelpers.hpp"
16 #include "NumericalAlgorithms/DiscontinuousGalerkin/Tags.hpp" // IWYU pragma: keep // for db::item_type<Tags::Mortars<...>>
17 #include "Time/Tags.hpp" // IWYU pragma: keep // for db::item_type<Tags::TimeStep>
18 #include "Time/TimeSteppers/TimeStepper.hpp" // IWYU pragma: keep
19 // IWYU pragma: no_include "Time/Time.hpp" // for TimeDelta
20 #include "Utilities/Gsl.hpp"
22 
23 /// \cond
24 // IWYU pragma: no_forward_declare TimeDelta
25 namespace Parallel {
26 template <typename Metavariables>
27 class ConstGlobalCache;
28 } // namespace Parallel
29 // IWYU pragma: no_forward_declare db::DataBox
30 /// \endcond
31 
32 namespace dg {
33 namespace Actions {
34 /// \ingroup ActionsGroup
35 /// \ingroup DiscontinuousGalerkinGroup
36 /// \brief Perform the boundary part of the update of the variables
37 /// for local time stepping.
38 ///
39 /// Uses:
40 /// - ConstGlobalCache:
41 /// - OptionTags::TimeStepper
42 /// - Metavariables::normal_dot_numerical_flux
43 /// - DataBox:
44 /// - Tags::Mesh<volume_dim>
45 /// - Tags::Mortars<Tags::Mesh<volume_dim - 1>, volume_dim>
46 /// - Tags::Mortars<Tags::MortarSize<volume_dim - 1>, volume_dim>
47 /// - Tags::TimeStep
48 ///
49 /// DataBox changes:
50 /// - Adds: nothing
51 /// - Removes: nothing
52 /// - Modifies:
53 /// - variables_tag
54 /// - FluxCommunicationTypes<Metavariables>::mortar_data_tag
56  template <typename DbTags, typename... InboxTags, typename Metavariables,
57  typename ArrayIndex, typename ActionList,
58  typename ParallelComponent>
61  const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
63  const ArrayIndex& /*array_index*/, const ActionList /*meta*/,
64  const ParallelComponent* const /*meta*/) noexcept {
65  static_assert(Metavariables::local_time_stepping,
66  "ApplyBoundaryFluxesLocalTimeStepping can only be used with "
67  "local time-stepping.");
68 
69  using system = typename Metavariables::system;
70  constexpr size_t volume_dim = system::volume_dim;
71  using variables_tag = typename system::variables_tag;
72 
73  using flux_comm_types = FluxCommunicationTypes<Metavariables>;
74 
75  using mortar_data_tag =
76  typename flux_comm_types::local_time_stepping_mortar_data_tag;
77  db::mutate<variables_tag, mortar_data_tag>(
78  make_not_null(&box),
79  [&cache](
83  const db::item_type<Tags::Mortars<Tags::Mesh<volume_dim - 1>,
84  volume_dim>>& mortar_meshes,
85  const db::item_type<Tags::Mortars<Tags::MortarSize<volume_dim - 1>,
86  volume_dim>>& mortar_sizes,
87  const db::item_type<Tags::TimeStep>& time_step) noexcept {
88  // Having the lambda just wrap another lambda works around a
89  // gcc 6.4.0 segfault.
90  [
91  &cache, &vars, &mortar_data, &mesh, &mortar_meshes, &mortar_sizes,
92  &time_step
93  ]() noexcept {
94  const auto& normal_dot_numerical_flux_computer =
95  get<typename Metavariables::normal_dot_numerical_flux>(cache);
96  const LtsTimeStepper& time_stepper =
97  get<OptionTags::TimeStepper>(cache);
98 
99  for (auto& mortar_id_and_data : *mortar_data) {
100  const auto& mortar_id = mortar_id_and_data.first;
101  auto& data = mortar_id_and_data.second;
102  const auto& direction = mortar_id.first;
103  const size_t dimension = direction.dimension();
104 
105  const auto face_mesh = mesh.slice_away(dimension);
106  const auto perpendicular_extent = mesh.extents(dimension);
107  const auto& mortar_mesh = mortar_meshes.at(mortar_id);
108  const auto& mortar_size = mortar_sizes.at(mortar_id);
109 
110  // This lambda must only capture quantities that are
111  // independent of the simulation state.
112  const auto coupling =
113  [
114  &face_mesh, &mortar_mesh, &mortar_size,
115  &normal_dot_numerical_flux_computer, &perpendicular_extent
116  ](const typename flux_comm_types::LocalData& local_data,
117  const typename flux_comm_types::PackagedData&
118  remote_data) noexcept {
119  return compute_boundary_flux_contribution<flux_comm_types>(
120  normal_dot_numerical_flux_computer, local_data, remote_data,
121  face_mesh, mortar_mesh, perpendicular_extent, mortar_size);
122  };
123 
124  const auto lifted_data = time_stepper.compute_boundary_delta(
125  coupling, make_not_null(&data), time_step);
126 
127  add_slice_to_data(vars, lifted_data, mesh.extents(), dimension,
128  index_to_slice_at(mesh.extents(), direction));
129  }
130  }();
131  },
132  db::get<Tags::Mesh<volume_dim>>(box),
134  db::get<Tags::Mortars<Tags::MortarSize<volume_dim - 1>, volume_dim>>(
135  box),
136  db::get<Tags::TimeStep>(box));
137 
138  return std::forward_as_tuple(std::move(box));
139  }
140 };
141 } // namespace Actions
142 } // namespace dg
size_t index_to_slice_at(const Index< Dim > &extents, const Direction< Dim > &direction) noexcept
Finds the index in the perpendicular dimension of an element boundary.
Definition: IndexToSliceAt.hpp:15
Defines class tuples::TaggedTuple.
Definition: InitializeElement.hpp:63
Mesh< Dim > mortar_mesh(const Mesh< Dim > &face_mesh1, const Mesh< Dim > &face_mesh2) noexcept
Find a mesh for a mortar capable of representing data from either of two faces.
Definition: MortarHelpers.cpp:19
Contains functions that forward to Charm++ parallel functions.
Definition: Abort.hpp:13
Base class for TimeSteppers with local time-stepping support, derived from TimeStepper.
Definition: TimeStepper.hpp:105
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
Data on mortars, indexed by (Direction, ElementId) pairs.
Definition: Tags.hpp:34
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:272
Defines classes and functions used for manipulating DataBox&#39;s.
Definition: InterpolationTargetWedgeSectionTorus.hpp:24
Types related to flux communication.
Definition: FluxCommunicationTypes.hpp:37
A Charm++ chare that caches constant data once per Charm++ node.
Definition: ConstGlobalCache.hpp:76
Size of a mortar, relative to the element face. That is, the part of the face that it covers...
Definition: Tags.hpp:46
Perform the boundary part of the update of the variables for local time stepping. ...
Definition: ApplyBoundaryFluxesLocalTimeStepping.hpp:55
std::array< Spectral::MortarSize, Dim - 1 > mortar_size(const ElementId< Dim > &self, const ElementId< Dim > &neighbor, const size_t dimension, const OrientationMap< Dim > &orientation) noexcept
Determine the size of the mortar (i.e., the part of the face it covers) for communicating with a neig...
Definition: MortarHelpers.cpp:36
const auto & get(const DataBox< TagList > &box) noexcept
Retrieve the item with tag Tag from the DataBox.
Definition: DataBox.hpp:1211
The Poisson equation formulated as a set of coupled first-order PDEs.
Definition: FirstOrderSystem.hpp:55
The computational grid of the Element in the DataBox.
Definition: Tags.hpp:75
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...
void add_slice_to_data(const gsl::not_null< Variables< TagsList > *> volume_vars, const Variables< TagsList > &vars_on_slice, const Index< VolumeDim > &extents, const size_t sliced_dim, const size_t fixed_index) noexcept
Adds data on a codimension 1 slice to a volume quantity. The slice has a constant logical coordinate ...
Definition: VariablesHelpers.hpp:157
Defines tags related to Time quantities.
Definition: ComputeTimeDerivative.hpp:28
Require a pointer to not be a nullptr
Definition: ConservativeFromPrimitive.hpp:12