Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <cstddef>
7 :
8 : #include "DataStructures/DataBox/PrefixHelpers.hpp"
9 : #include "DataStructures/DataBox/Prefixes.hpp"
10 : #include "DataStructures/DataBox/Tag.hpp"
11 : #include "DataStructures/DataVector.hpp"
12 : #include "DataStructures/SliceVariables.hpp"
13 : #include "Domain/Structure/Element.hpp"
14 : #include "Domain/Structure/IndexToSliceAt.hpp"
15 : #include "Domain/Tags.hpp"
16 : #include "Domain/Tags/FaceNormal.hpp"
17 : #include "Domain/Tags/Faces.hpp"
18 : #include "NumericalAlgorithms/DiscontinuousGalerkin/NormalDotFlux.hpp"
19 : #include "NumericalAlgorithms/Spectral/Mesh.hpp"
20 : #include "NumericalAlgorithms/Spectral/Quadrature.hpp"
21 : #include "Utilities/ErrorHandling/Assert.hpp"
22 : #include "Utilities/Gsl.hpp"
23 : #include "Utilities/TMPL.hpp"
24 :
25 : namespace elliptic::Tags {
26 :
27 : /// The `FieldsTag` on external boundaries
28 : template <size_t Dim, typename FieldsTag>
29 1 : struct BoundaryFieldsCompute : db::ComputeTag,
30 : domain::Tags::Faces<Dim, FieldsTag> {
31 0 : using base = domain::Tags::Faces<Dim, FieldsTag>;
32 0 : using return_type = typename base::type;
33 0 : using argument_tags = tmpl::list<FieldsTag, domain::Tags::Mesh<Dim>,
34 : domain::Tags::Element<Dim>>;
35 0 : static void function(const gsl::not_null<return_type*> vars_on_face,
36 : const typename FieldsTag::type& vars,
37 : const Mesh<Dim>& mesh, const Element<Dim>& element) {
38 : ASSERT(mesh.quadrature(0) == Spectral::Quadrature::GaussLobatto,
39 : "Slicing fields to the boundary currently supports only "
40 : "Gauss-Lobatto grids. Add support to "
41 : "'elliptic::Tags::BoundaryFieldsCompute'.");
42 : for (const auto& direction : element.external_boundaries()) {
43 : data_on_slice(make_not_null(&((*vars_on_face)[direction])), vars,
44 : mesh.extents(), direction.dimension(),
45 : index_to_slice_at(mesh.extents(), direction));
46 : }
47 : }
48 : };
49 :
50 : /// The `::Tags::NormalDotFlux<FieldsTag>` on external boundaries
51 : template <size_t Dim, typename FieldsTag, typename FluxesTag>
52 1 : struct BoundaryFluxesCompute
53 : : db::ComputeTag,
54 : domain::Tags::Faces<
55 : Dim, db::add_tag_prefix<::Tags::NormalDotFlux, FieldsTag>> {
56 0 : using base =
57 : domain::Tags::Faces<Dim,
58 : db::add_tag_prefix<::Tags::NormalDotFlux, FieldsTag>>;
59 0 : using return_type = typename base::type;
60 0 : using argument_tags =
61 : tmpl::list<FluxesTag,
62 : domain::Tags::Faces<Dim, domain::Tags::FaceNormal<Dim>>,
63 : domain::Tags::Mesh<Dim>, domain::Tags::Element<Dim>>;
64 0 : static void function(
65 : const gsl::not_null<return_type*> normal_dot_fluxes,
66 : const typename FluxesTag::type& fluxes,
67 : const DirectionMap<Dim, tnsr::i<DataVector, Dim>>& face_normals,
68 : const Mesh<Dim>& mesh, const Element<Dim>& element) {
69 : ASSERT(mesh.quadrature(0) == Spectral::Quadrature::GaussLobatto,
70 : "Slicing fluxes to the boundary currently supports only "
71 : "Gauss-Lobatto grids. Add support to "
72 : "'elliptic::Tags::BoundaryFluxesCompute'.");
73 : for (const auto& direction : element.external_boundaries()) {
74 : const auto fluxes_on_face =
75 : data_on_slice(fluxes, mesh.extents(), direction.dimension(),
76 : index_to_slice_at(mesh.extents(), direction));
77 : normal_dot_flux(make_not_null(&((*normal_dot_fluxes)[direction])),
78 : face_normals.at(direction), fluxes_on_face);
79 : }
80 : }
81 : };
82 :
83 : } // namespace elliptic::Tags
|