Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <array> 7 : #include <cstddef> 8 : #include <memory> 9 : #include <string> 10 : #include <unordered_map> 11 : 12 : #include "DataStructures/DataBox/Tag.hpp" 13 : #include "DataStructures/Tensor/TypeAliases.hpp" // IWYU pragma: keep 14 : #include "Domain/CoordinateMaps/Tags.hpp" 15 : #include "Domain/Tags.hpp" 16 : #include "Domain/TagsTimeDependent.hpp" 17 : #include "Time/Tags.hpp" 18 : #include "Utilities/TMPL.hpp" 19 : 20 : /// \cond 21 : namespace domain { 22 : template <typename SourceFrame, typename TargetFrame, size_t Dim> 23 : class CoordinateMapBase; 24 : namespace FunctionsOfTime { 25 : class FunctionOfTime; 26 : } // namespace FunctionsOfTime 27 : } // namespace domain 28 : template <size_t VolumeDim, typename Frame> 29 : class ElementMap; 30 : namespace domain { 31 : namespace Tags { 32 : template <size_t Dim, typename Frame> 33 : struct ElementMap; 34 : } // namespace Tags 35 : } // namespace domain 36 : /// \endcond 37 : 38 : /// @{ 39 : /*! 40 : * \ingroup ComputationalDomainGroup 41 : * \brief Compute the inertial-coordinate size of an element along each of its 42 : * logical directions. 43 : * 44 : * For each logical direction, compute the distance (in inertial coordinates) 45 : * between the element's lower and upper faces in that logical direction. 46 : * The distance is measured between centers of the faces, with the centers 47 : * defined in the logical coordinates. 48 : * Note that for curved elements, this is an approximate measurement of size. 49 : * 50 : * \details 51 : * Because this quantity is defined in terms of specific coordinates, it is 52 : * not well represented by a `Tensor`, so we use a `std::array`. 53 : */ 54 : template <size_t VolumeDim> 55 1 : std::array<double, VolumeDim> size_of_element( 56 : const ElementMap<VolumeDim, Frame::Inertial>& logical_to_inertial_map); 57 : 58 : template <size_t VolumeDim> 59 1 : std::array<double, VolumeDim> size_of_element( 60 : const ElementMap<VolumeDim, Frame::Grid>& logical_to_grid_map, 61 : const domain::CoordinateMapBase<Frame::Grid, Frame::Inertial, VolumeDim>& 62 : grid_to_inertial_map, 63 : double time, 64 : const std::unordered_map< 65 : std::string, std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>& 66 : functions_of_time); 67 : /// @} 68 : 69 : namespace domain { 70 : namespace Tags { 71 : /// \ingroup DataBoxTagsGroup 72 : /// \ingroup ComputationalDomainGroup 73 : /// The inertial-coordinate size of an element along each of its logical 74 : /// directions. 75 : template <size_t VolumeDim> 76 1 : struct SizeOfElement : db::SimpleTag { 77 0 : using type = std::array<double, VolumeDim>; 78 : }; 79 : 80 : template <size_t VolumeDim> 81 0 : struct SizeOfElementCompute : db::ComputeTag, SizeOfElement<VolumeDim> { 82 0 : using base = SizeOfElement<VolumeDim>; 83 0 : using argument_tags = 84 : tmpl::list<Tags::ElementMap<VolumeDim, Frame::Grid>, 85 : CoordinateMaps::Tags::CoordinateMap<VolumeDim, Frame::Grid, 86 : Frame::Inertial>, 87 : ::Tags::Time, domain::Tags::FunctionsOfTime>; 88 0 : using return_type = typename base::type; 89 : 90 0 : static constexpr void function( 91 : gsl::not_null<std::array<double, VolumeDim>*> result, 92 : const ::ElementMap<VolumeDim, Frame::Grid>& logical_to_grid_map, 93 : const domain::CoordinateMapBase<Frame::Grid, Frame::Inertial, VolumeDim>& 94 : grid_to_inertial_map, 95 : const double time, 96 : const std::unordered_map< 97 : std::string, 98 : std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>& 99 : functions_of_time) { 100 : *result = size_of_element(logical_to_grid_map, grid_to_inertial_map, time, 101 : functions_of_time); 102 : } 103 : }; 104 : } // namespace Tags 105 : } // namespace domain