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