BoundaryFlux.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <algorithm>
7 #include <array>
8 #include <cstddef>
9 
14 #include "Domain/Mesh.hpp"
15 #include "NumericalAlgorithms/DiscontinuousGalerkin/BoundarySchemes/FirstOrder/BoundaryData.hpp"
17 #include "NumericalAlgorithms/DiscontinuousGalerkin/MortarHelpers.hpp"
18 #include "NumericalAlgorithms/DiscontinuousGalerkin/NumericalFluxes/NumericalFluxHelpers.hpp"
19 #include "NumericalAlgorithms/DiscontinuousGalerkin/Protocols.hpp"
21 #include "Utilities/ProtocolHelpers.hpp"
22 #include "Utilities/Requires.hpp"
23 #include "Utilities/TMPL.hpp"
24 
25 namespace dg {
26 /// Functionality related to the first-order DG scheme.
27 namespace FirstOrderScheme {
28 
29 /*!
30  * \brief Compute the boundary flux contribution and lift it to the volume.
31  *
32  * This computes the numerical flux minus the flux dotted into the interface
33  * normal, projects the result to the face mesh if necessary, and then lifts it
34  * to the volume (still presented only on the face mesh as all other points are
35  * zero).
36  *
37  * Projection must happen after the numerical flux calculation so that the
38  * elements on either side of the mortar calculate the same result. Projection
39  * must happen before flux lifting because we want the factor of the magnitude
40  * of the unit normal added during the lift to cancel the Jacobian factor in
41  * integrals to preserve conservation; this only happens if the two operations
42  * are done on the same grid.
43  */
44 template <size_t FaceDim, typename NumericalFluxType, typename AllFieldsTags,
45  typename AllExtraDataTags,
46  Requires<tt::conforms_to_v<NumericalFluxType,
47  dg::protocols::NumericalFlux>> = nullptr>
48 Variables<typename NumericalFluxType::variables_tags> boundary_flux(
50  local_boundary_data,
52  remote_boundary_data,
53  const NumericalFluxType& numerical_flux_computer,
54  const Scalar<DataVector>& magnitude_of_face_normal,
55  const size_t extent_perpendicular_to_boundary,
56  const Mesh<FaceDim>& face_mesh, const Mesh<FaceDim>& mortar_mesh,
57  const MortarSize<FaceDim>& mortar_size) noexcept {
58  using variables_tags = typename NumericalFluxType::variables_tags;
59 
60  // Compute the Tags::NormalDotNumericalFlux from local and remote data
61  Variables<db::wrap_tags_in<::Tags::NormalDotNumericalFlux, variables_tags>>
62  normal_dot_numerical_fluxes{mortar_mesh.number_of_grid_points()};
63  dg::NumericalFluxes::normal_dot_numerical_fluxes(
64  make_not_null(&normal_dot_numerical_fluxes), numerical_flux_computer,
65  local_boundary_data, remote_boundary_data);
66 
67  // Subtract the local Tags::NormalDotFlux
68  tmpl::for_each<variables_tags>([&normal_dot_numerical_fluxes,
69  &local_boundary_data](
70  const auto tag_v) noexcept {
71  using tag = tmpl::type_from<decltype(tag_v)>;
72  auto& numerical_flux =
73  get<::Tags::NormalDotNumericalFlux<tag>>(normal_dot_numerical_fluxes);
74  const auto& local_flux =
75  get<::Tags::NormalDotFlux<tag>>(local_boundary_data.field_data);
76  for (size_t i = 0; i < numerical_flux.size(); ++i) {
77  numerical_flux[i] -= local_flux[i];
78  }
79  });
80 
81  // Project from the mortar back to the face if needed
82  auto projected_fluxes =
84  ? project_from_mortar(normal_dot_numerical_fluxes, face_mesh,
86  : std::move(normal_dot_numerical_fluxes);
87 
88  // Lift flux to the volume. We still only need to provide it on the face
89  // because it is zero everywhere else.
90  return lift_flux(std::move(projected_fluxes),
91  extent_perpendicular_to_boundary, magnitude_of_face_normal);
92 }
93 
94 } // namespace FirstOrderScheme
95 } // namespace dg
DataBoxTag.hpp
LiftFlux.hpp
dg::protocols::NumericalFlux
Defines the interface for DG numerical fluxes.
Definition: Protocols.hpp:90
Spectral.hpp
algorithm
dg
Functionality related to discontinuous Galerkin schemes.
Definition: ComputeNonconservativeBoundaryFluxes.hpp:23
dg::SimpleBoundaryData
Distinguishes between field data, which can be projected to a mortar, and extra data,...
Definition: SimpleBoundaryData.hpp:35
cstddef
array
dg::lift_flux
auto lift_flux(Variables< tmpl::list< FluxTags... >> flux, const size_t extent_perpendicular_to_boundary, Scalar< DataVector > magnitude_of_face_normal) noexcept -> Variables< tmpl::list< db::remove_tag_prefix< FluxTags >... >>
Lifts the flux contribution from an interface to the volume.
Definition: LiftFlux.hpp:40
dg::project_from_mortar
Variables< Tags > project_from_mortar(const Variables< Tags > &vars, const Mesh< Dim > &face_mesh, const Mesh< Dim > &mortar_mesh, const MortarSize< Dim > &mortar_size) noexcept
Definition: MortarHelpers.hpp:106
Variables.hpp
Mesh
Holds the number of grid points, basis, and quadrature in each direction of the computational grid.
Definition: Mesh.hpp:50
Scalar
Tensor< T, Symmetry<>, index_list<> > Scalar
Definition: TypeAliases.hpp:21
dg::needs_projection
bool needs_projection(const Mesh< Dim > &face_mesh, const Mesh< Dim > &mortar_mesh, const MortarSize< Dim > &mortar_size) noexcept
Definition: MortarHelpers.hpp:70
Tensor.hpp
Requires.hpp
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
Requires
typename Requires_detail::requires_impl< B >::template_error_type_failed_to_meet_requirements_on_template_parameters Requires
Express requirements on the template parameters of a function or class, replaces std::enable_if_t
Definition: Requires.hpp:67
Mesh.hpp
dg::FirstOrderScheme::boundary_flux
Variables< typename NumericalFluxType::variables_tags > boundary_flux(const dg::SimpleBoundaryData< AllFieldsTags, AllExtraDataTags > &local_boundary_data, const dg::SimpleBoundaryData< AllFieldsTags, AllExtraDataTags > &remote_boundary_data, const NumericalFluxType &numerical_flux_computer, const Scalar< DataVector > &magnitude_of_face_normal, const size_t extent_perpendicular_to_boundary, const Mesh< FaceDim > &face_mesh, const Mesh< FaceDim > &mortar_mesh, const MortarSize< FaceDim > &mortar_size) noexcept
Compute the boundary flux contribution and lift it to the volume.
Definition: BoundaryFlux.hpp:48
dg::mortar_mesh
Mesh< Dim > mortar_mesh(const Mesh< Dim > &face_mesh1, const Mesh< Dim > &face_mesh2) noexcept
Definition: MortarHelpers.cpp:19
Prefixes.hpp
dg::mortar_size
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
Definition: MortarHelpers.cpp:36
TMPL.hpp