Gyselalib++
 
Loading...
Searching...
No Matches
onion_patch_locator.hpp
1// SPDX-License-Identifier: MIT
2
3#pragma once
4#include <stdexcept>
5
6#include <ddc/ddc.hpp>
7
8#include <sll/mapping/mapping_tools.hpp>
9
10#include "ddc_aliases.hpp"
11#include "multipatch_type.hpp"
12#include "types.hpp"
13
14
15
44template <
45 class MultipatchIdxRanges,
48 class ExecSpace = Kokkos::DefaultExecutionSpace>
50
51
61template <
62 class... Patches,
65 class ExecSpace>
67 MultipatchType<IdxRangeOnPatch, Patches...>,
70 ExecSpace>
71{
72 static_assert(is_curvilinear_2d_mapping_v<LogicalToPhysicalMapping>);
73
78
79 static_assert(Theta::PERIODIC, "Theta dimension must be periodic.");
80
81public:
83 using MultipatchIdxRanges = MultipatchType<IdxRangeOnPatch, Patches...>;
84
86 using PatchOrdering = ddc::detail::TypeSeq<Patches...>;
87
89 using exec_space = ExecSpace;
90
93 static constexpr int outside_rmax_domain = -1;
94
97 static constexpr int outside_rmin_domain = -2;
98
99private:
100 static constexpr std::size_t n_patches = ddc::type_seq_size_v<PatchOrdering>;
101
102 static_assert(
103 std::is_invocable_r_v<Coord<R, Theta>, PhysicalToLogicalMapping, Coord<X, Y>>,
104 "The mapping has to contain an operator from the physical domain to the logical "
105 "domain.");
106 static_assert(
107 (((std::is_same_v<typename Patches::Dim1, R>)&&(
108 std::is_same_v<typename Patches::Dim2, Theta>))
109 && ...),
110 "The mappings and the patches have to be defined on the same dimensions.");
111
112
113 LogicalToPhysicalMapping const m_to_cartesian_mapping;
114 PhysicalToLogicalMapping const m_to_curvilinear_mapping;
115 MultipatchIdxRanges const m_all_idx_ranges;
116
117 Kokkos::View<Coord<R>*, typename ExecSpace::memory_space> m_radii;
118
119public:
131 MultipatchIdxRanges const& all_idx_ranges,
132 LogicalToPhysicalMapping const& to_physical_mapping,
133 PhysicalToLogicalMapping const& to_logical_mapping)
134 : m_to_cartesian_mapping(to_physical_mapping)
135 , m_to_curvilinear_mapping(to_logical_mapping)
136 , m_all_idx_ranges(all_idx_ranges)
137 , m_radii("m_radii", n_patches + 1)
138 {
139 set_and_check_radii();
140 }
141
142
143 ~OnionPatchLocator() = default;
144
158 KOKKOS_INLINE_FUNCTION int operator()(Coord<X, Y> const coord) const
159 {
160 int patch_index_min = 0;
161 int patch_index_max = n_patches - 1;
162
163 Coord<R> r_min = m_radii(patch_index_min);
164 Coord<R> r_max = m_radii(patch_index_max + 1);
165 Coord<R> r(m_to_curvilinear_mapping(coord));
166 KOKKOS_ASSERT(!Kokkos::isnan(double(r)));
167
168 if (r > r_max) {
169 return outside_rmax_domain;
170 }
171 if (r < r_min) {
172 return outside_rmin_domain;
173 }
174
175 while (patch_index_max >= patch_index_min) {
176 int patch_index_mid = (patch_index_min + patch_index_max) / 2;
177 r_min = m_radii(patch_index_mid);
178 r_max = m_radii(patch_index_mid + 1);
179
180 if (r_min <= r && r < r_max) {
181 return patch_index_mid;
182 } else if (r < r_min) {
183 patch_index_max = patch_index_mid - 1;
184 } else if (r_max <= r) {
185 patch_index_min = patch_index_mid + 1;
186 }
187 };
188
189 if (r != m_radii(n_patches)) {
190 Kokkos::abort("Dichotomy method failed to find the right patch.");
191 }
192 return n_patches - 1;
193 }
194
195
202 template <class Patch>
204 {
205 return m_to_cartesian_mapping;
206 }
207
214 template <class Dim1, class Dim2>
216 {
217 static_assert(
218 (std::is_same_v<Dim1, R>)&&(std::is_same_v<Dim2, Theta>),
219 "Wrong continuous dimensions.");
220 return m_to_cartesian_mapping;
221 }
222
224 template <class Patch>
226
228 template <class Dim1, class Dim2>
230
231private:
235 void set_and_check_radii()
236 {
237 Kokkos::View<Coord<R>*, Kokkos::HostSpace> radii_host("radii_host", n_patches + 1);
238
239 std::array<Coord<R>, n_patches> r_min {
240 (Coord<R>(ddc::coordinate(m_all_idx_ranges.template get<Patches>().front())))...};
241 std::array<Coord<R>, n_patches> r_max {
242 (Coord<R>(ddc::coordinate(m_all_idx_ranges.template get<Patches>().back())))...};
243
244 radii_host(0) = r_min[0];
245 for (std::size_t i(0); i < n_patches - 1; i++) {
246 if (abs(double(r_min[i + 1] - r_max[i])) > 1e-14) {
247 throw std::invalid_argument("The patches listed in PatchOrdering must be ordered.");
248 }
249 radii_host(i + 1) = r_max[i];
250 }
251 radii_host(n_patches) = r_max[n_patches - 1];
252
253 Kokkos::deep_copy(m_radii, radii_host);
254 }
255};
256
257
258// To help the template deduction.
259template <
260 class MultipatchIdxRanges,
263 class ExecSpace = Kokkos::DefaultExecutionSpace>
265 MultipatchIdxRanges const& all_idx_ranges,
266 LogicalToPhysicalMapping const& to_physical_mapping,
267 PhysicalToLogicalMapping const& to_logical_mapping)
269 MultipatchIdxRanges,
272 ExecSpace>;
A class for describing the circular 2D mapping.
Definition cartesian_to_circular.hpp:40
A class for describing the circular 2D mapping.
Definition circular_to_cartesian.hpp:43
X cartesian_tag_x
Indicate the first physical coordinate.
Definition circular_to_cartesian.hpp:46
R curvilinear_tag_r
Indicate the first logical coordinate.
Definition circular_to_cartesian.hpp:50
Y cartesian_tag_y
Indicate the second physical coordinate.
Definition circular_to_cartesian.hpp:48
Theta curvilinear_tag_theta
Indicate the second logical coordinate.
Definition circular_to_cartesian.hpp:52
A class to store several objects that are of a type which is templated by the patch.
Definition multipatch_type.hpp:32
KOKKOS_INLINE_FUNCTION int operator()(Coord< X, Y > const coord) const
Get the patch where the given physical coordinate is.
Definition onion_patch_locator.hpp:158
ddc::detail::TypeSeq< Patches... > PatchOrdering
Sequence ddc::detail::TypeSeq of patch tags.
Definition onion_patch_locator.hpp:86
KOKKOS_FUNCTION LogicalToPhysicalMapping get_mapping_on_logical_dim() const
Get the mapping from given logical continuous dimensions.
Definition onion_patch_locator.hpp:215
OnionPatchLocator(MultipatchIdxRanges const &all_idx_ranges, LogicalToPhysicalMapping const &to_physical_mapping, PhysicalToLogicalMapping const &to_logical_mapping)
Instantiante the operator with MultipatchType of index ranges and a mapping on all the patches.
Definition onion_patch_locator.hpp:130
KOKKOS_FUNCTION LogicalToPhysicalMapping get_mapping_on_patch() const
Get the mapping on the given Patch.
Definition onion_patch_locator.hpp:203
ExecSpace exec_space
The space (CPU/GPU) where the calculations are carried out.
Definition onion_patch_locator.hpp:89
Patch locator specialised for "onion" geometry.
Definition onion_patch_locator.hpp:49
Define non periodic real R dimension.
Definition geometry.hpp:31
Define periodic real Theta dimension.
Definition geometry.hpp:42
static bool constexpr PERIODIC
Define periodicity of the dimension.
Definition geometry.hpp:47
Define non periodic real X dimension.
Definition geometry.hpp:278
Define non periodic real Y dimension.
Definition geometry.hpp:289