RotatedBricks.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <array>
7 #include <cstddef>
8 #include <limits>
9 #include <vector>
10 
11 #include "Domain/Creators/DomainCreator.hpp" // IWYU pragma: keep
12 #include "Domain/Domain.hpp"
13 #include "Options/Options.hpp"
14 #include "Utilities/TMPL.hpp"
15 
16 namespace domain {
17 namespace creators {
18 
19 /// \ingroup DomainCreatorsGroup
20 /// Create a 3D Domain consisting of eight rotated Blocks.
21 ///
22 /// \image html eightcubes_rotated_exploded.png
23 ///
24 /// The orientations of the blocks are described in two different ways:
25 ///
26 /// - 1 - As orientations of blocks relative to the physical cartesian axes.
27 ///
28 /// - 2 - As rotations relative to the physical cartesian axes written using
29 /// Rubik's cube rotation notation, for the sake of shorter variable names.
30 ///
31 /// For reference, this is the notation used:
32 ///
33 /// - U - A clockwise 90 degree rotation about the +z axis (The "up" side)
34 ///
35 /// - R - A clockwise 90 degree rotation about the +x axis (The "right" side)
36 ///
37 /// - F - A clockwise 90 degree rotation about the -y axis (The "front" side)
38 ///
39 /// For reference, D, L, and B ("down", "left", and "back") are the inverse
40 /// rotation to the aforementioned ones, respectively.
41 /// Note: Whereas Rubik's cube rotations rotate a layer of the 3x3 puzzle
42 /// cube, we are adopting the notation to apply to rotations of the
43 /// cube itself.
44 ///
45 /// - The -x, -y, -z block has the aligned orientation, that is,
46 /// xi is aligned with x, eta is aligned with y, and zeta with z.
47 ///
48 /// - The +x, -y, -z block has the orientation (zeta, eta, -xi).
49 /// It corresponds to the orientation obtained by the rotation F.
50 ///
51 /// - The -x, +y, -z block has the orientation (xi, zeta, -eta).
52 /// It corresponds to the orientation obtained by the rotation R.
53 ///
54 /// - The +x, +y, -z block has the orientation (zeta, -xi, -eta).
55 /// It corresponds to the orientation obtained by the rotation F
56 /// followed by the rotation R.
57 ///
58 /// - The -x, -y, +z block has the orientation (eta, -xi, zeta).
59 /// It corresponds to the orientation obtained by the rotation U.
60 ///
61 /// - The +x, -y, +z block has the orientation (eta, -zeta, -xi).
62 /// It corresponds to the orientation obtained by the rotation F
63 /// followed by the rotation U.
64 ///
65 /// - The -x, +y, +z block has the orientation (zeta, -xi, -eta).
66 /// It corresponds to the orientation obtained by the rotation R
67 /// followed by the rotation U (equivalently, F followed by R).
68 ///
69 /// - The +x, +y, +z block also has the aligned orientation
70 /// (xi, eta, zeta), relative to the edifice. It is not aligned
71 /// relative to its neighbors.
72 ///
73 /// This DomainCreator is useful for testing code that deals with
74 /// unaligned blocks.
75 template <typename TargetFrame>
76 class RotatedBricks : public DomainCreator<3, TargetFrame> {
77  public:
78  struct LowerBound {
80  static constexpr OptionString help = {
81  "Sequence [x,y,z] for lower bound in the target frame."};
82  };
83 
84  struct Midpoint {
86  static constexpr OptionString help = {
87  "Sequence [x,y,z] for midpoint in the target frame."};
88  };
89 
90  struct UpperBound {
92  static constexpr OptionString help = {
93  "Sequence [x,y,z] for upper bound in the target frame."};
94  };
95 
96  struct IsPeriodicIn {
97  using type = std::array<bool, 3>;
98  static constexpr OptionString help = {
99  "Sequence in [x,y,z], true if periodic."};
100  static type default_value() noexcept { return {{false, false, false}}; }
101  };
102 
104  using type = std::array<size_t, 3>;
105  static constexpr OptionString help = {
106  "Initial refinement level in [x, y, z]."};
107  };
108 
111  static constexpr OptionString help = {
112  "Initial number of grid points in [[x], [y], [z]]."};
113  };
114 
115  using options = tmpl::list<LowerBound, Midpoint, UpperBound, IsPeriodicIn,
117 
118  static constexpr OptionString help = {
119  "A DomainCreator useful for testing purposes.\n"
120  "RotatedBricks uses eight rotated Blocks to create the rectangular\n"
121  "prism [LowerX,UpperX] x [LowerY,UpperY] x [LowerZ,UpperZ]. The\n"
122  "outermost index to InitialGridPoints is the dimension index, and\n"
123  "the innermost index is the block index along that dimension."};
124 
125  RotatedBricks(typename LowerBound::type lower_xyz,
126  typename Midpoint::type midpoint_xyz,
127  typename UpperBound::type upper_xyz,
128  typename IsPeriodicIn::type is_periodic_in,
129  typename InitialRefinement::type initial_refinement_level_xyz,
130  typename InitialGridPoints::type
131  initial_number_of_grid_points_in_xyz) noexcept;
132 
133  RotatedBricks() = default;
134  RotatedBricks(const RotatedBricks&) = delete;
135  RotatedBricks(RotatedBricks&&) noexcept = default;
136  RotatedBricks& operator=(const RotatedBricks&) = delete;
137  RotatedBricks& operator=(RotatedBricks&&) noexcept = default;
138  ~RotatedBricks() override = default;
139 
140  Domain<3, TargetFrame> create_domain() const noexcept override;
141 
142  std::vector<std::array<size_t, 3>> initial_extents() const noexcept override;
143 
145  noexcept override;
146 
147  private:
148  typename LowerBound::type lower_xyz_{
150  typename Midpoint::type midpoint_xyz_{
152  typename UpperBound::type upper_xyz_{
154  typename IsPeriodicIn::type is_periodic_in_{{false, false, false}};
155  typename InitialRefinement::type initial_refinement_level_xyz_{
157  typename InitialGridPoints::type initial_number_of_grid_points_in_xyz_{
159 };
160 } // namespace creators
161 } // namespace domain
Definition: RotatedBricks.hpp:90
Create a 3D Domain consisting of eight rotated Blocks.
Definition: RotatedBricks.hpp:76
Definition: BlockId.hpp:16
T signaling_NaN(T... args)
Defines classes and functions for making classes creatable from input files.
std::vector< std::array< size_t, 3 > > initial_extents() const noexcept override
Obtain the initial grid extents of the block with the given index.
Definition: RotatedBricks.cpp:76
Base class for creating Domains from an option string.
Definition: DomainCreator.hpp:87
Definition: RotatedBricks.hpp:84
Definition: RotatedBricks.hpp:96
const char *const OptionString
The string used in option structs.
Definition: Options.hpp:26
Defines class template Domain.
Definition: RotatedBricks.hpp:78
T max(T... args)
std::vector< std::array< size_t, 3 > > initial_refinement_levels() const noexcept override
Obtain the initial refinement levels of the blocks.
Definition: RotatedBricks.cpp:91
A wrapper around a vector of Blocks that represent the computational domain.
Definition: Domain.hpp:36
Wraps the template metaprogramming library used (brigand)
Defines class DomainCreator.