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 <cstdint>
9 : #include <iosfwd>
10 :
11 : #include "Utilities/MakeArray.hpp"
12 :
13 : namespace domain {
14 :
15 : /// \brief The topology of a Block or Element in a particular dimension
16 : ///
17 : /// \details The Topology is used to determine the geometry of the Block or
18 : /// Element, which can be used to determine:
19 : /// - Whether there is an interface (with a neighbor or external boundary) in a
20 : /// given direction
21 : /// - The block (element) logical coordinate bounds
22 : /// - The appropriate Basis and Quadrature for a Mesh on an Element
23 : /// - Whether or not h-refinement is allowed in the given dimension
24 : /// - Whether or not the hybrid DG-Subcell scheme can be used
25 : ///
26 : /// \note Choose I1 to represent a closed interval \f$[-1, 1]\f$
27 : ///
28 : /// \note Choose S1 to represent a periodic interval \f$[0, 2 \pi)\f$
29 : ///
30 : /// \note Choose HalfS1 to represent a half-period angular interval
31 : /// \f$[0, \pi]\f$ using a HalfFourier basis
32 : ///
33 : /// \note In consecutive dimensions, choose S2Colatitude and S2Longitude to
34 : /// represent the surface of a sphere
35 : ///
36 : /// \note In consecutive dimensions, choose B2Radial and B2Angular to represent
37 : /// a disk (including the center) or cross-section of a cylinder
38 : ///
39 : /// \note In consecutive dimensions, choose B3Radial, B3Colatitude and
40 : /// B3Longitude to represent a filled ball (including the center)
41 : ///
42 : /// \note Currently h-refinement can only be done in dimensions with
43 : /// Topology::I1
44 : ///
45 : /// \note Currently the hybrid DG-Subcell scheme can be used only in Elements
46 : /// whose topologies are all among I1, B1Radial, CartoonSphere, and
47 : /// CartoonCylinder. Elements with other topologies are automatically treated
48 : /// as DG-only.
49 0 : enum class Topology : uint8_t {
50 : Uninitialized = 0,
51 : I1 = 1,
52 : S1 = 2,
53 : S2Colatitude = 3,
54 : S2Longitude = 4,
55 : B1Radial = 5,
56 : B2Radial = 6,
57 : B2Angular = 7,
58 : B3Radial = 8,
59 : B3Colatitude = 9,
60 : B3Longitude = 10,
61 : CartoonSphere = 11,
62 : CartoonCylinder = 12,
63 : HalfS1 = 13
64 : };
65 :
66 : /// Output operator for a Topology.
67 1 : std::ostream& operator<<(std::ostream& os, Topology topology);
68 :
69 : /// \brief Whether the hybrid DG-subcell scheme can be used in a dimension
70 : /// with this `Topology`.
71 1 : constexpr bool topology_supports_subcell(const Topology topology) {
72 : return topology == Topology::I1 or topology == Topology::B1Radial or
73 : topology == Topology::CartoonSphere or
74 : topology == Topology::CartoonCylinder;
75 : }
76 :
77 0 : namespace topologies {
78 : /// Hypercube \f$[-1, 1]^d\f$
79 : template <size_t VolumeDim>
80 1 : static constexpr auto hypercube = make_array<VolumeDim>(Topology::I1);
81 :
82 : /// Hypertorus: every dimension periodic
83 : template <size_t VolumeDim>
84 1 : static constexpr auto hypertorus = make_array<VolumeDim>(Topology::S1);
85 :
86 : /// Annulus: radial \f$\times\f$ periodic angle
87 1 : static constexpr auto annulus = std::array{Topology::I1, Topology::S1};
88 :
89 : /// Sphere surface: colatitude \f$\times\f$ longitude (spherical harmonics)
90 1 : static constexpr auto spherical_surface =
91 : std::array{Topology::S2Colatitude, Topology::S2Longitude};
92 :
93 : /// Filled disk: radial \f$\times\f$ angle, including the center
94 1 : static constexpr auto disk =
95 : std::array{Topology::B2Radial, Topology::B2Angular};
96 :
97 : /// Spherical shell: radial \f$\times\f$ colatitude \f$\times\f$ longitude
98 : /// (spherical harmonics)
99 1 : static constexpr auto spherical_shell =
100 : std::array{Topology::I1, Topology::S2Colatitude, Topology::S2Longitude};
101 :
102 : /// Cylindrical shell: radial \f$\times\f$ periodic angle \f$\times\f$ axial
103 1 : static constexpr auto cylindrical_shell =
104 : std::array{Topology::I1, Topology::S1, Topology::I1};
105 :
106 : /// Filled cylinder: filled disk \f$\times\f$ axial
107 1 : static constexpr auto full_cylinder =
108 : std::array{Topology::B2Radial, Topology::B2Angular, Topology::I1};
109 :
110 : /// Filled ball: radial \f$\times\f$ colatitude \f$\times\f$ longitude,
111 : /// including the center
112 1 : static constexpr auto full_sphere = std::array{
113 : Topology::B3Radial, Topology::B3Colatitude, Topology::B3Longitude};
114 :
115 : /// Cartoon with spherical symmetry: radial; the two angular dimensions are
116 : /// removed
117 1 : static constexpr auto cartoon_sphere =
118 : std::array{Topology::I1, Topology::CartoonSphere, Topology::CartoonSphere};
119 :
120 : /// Same as `cartoon_sphere`, but the radial dimension includes the origin
121 1 : static constexpr auto cartoon_sphere_inner = std::array{
122 : Topology::B1Radial, Topology::CartoonSphere, Topology::CartoonSphere};
123 :
124 : /// Cartoon with axial symmetry: cylindrical radius \f$\times\f$ axial; the
125 : /// azimuth is removed
126 1 : static constexpr auto cartoon_cylinder =
127 : std::array{Topology::I1, Topology::I1, Topology::CartoonCylinder};
128 :
129 : /// Same as `cartoon_cylinder`, but the cylindrical radius includes the
130 : /// symmetry axis
131 1 : static constexpr auto cartoon_cylinder_inner =
132 : std::array{Topology::B1Radial, Topology::I1, Topology::CartoonCylinder};
133 :
134 : /// Cartoon with axial symmetry: spherical radius \f$\times\f$ polar angle on
135 : /// \f$[0, \pi]\f$; the azimuth is removed. This gives a spherical outer
136 : /// boundary.
137 1 : static constexpr auto cartoon_cylinder_annulus =
138 : std::array{Topology::I1, Topology::HalfS1, Topology::CartoonCylinder};
139 : } // namespace topologies
140 :
141 : } // namespace domain
|