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