DNDSR 0.1.0.dev1+gcd065ad
Distributed Numeric Data Structure for CFV
Loading...
Searching...
No Matches
PeriodicInfo.hpp
Go to the documentation of this file.
1#pragma once
2
4#include "DNDS/ArrayPair.hpp"
5#include "Geometric.hpp"
8
9namespace DNDS::Geom
10{
12 {
13 uint8_t __v{0U};
14 [[nodiscard]] bool getP1() const { return __v & 0x01U; }
15 [[nodiscard]] bool getP2() const { return __v & 0x02U; }
16 [[nodiscard]] bool getP3() const { return __v & 0x04U; }
17 void setP1True() { __v |= 0x01U; }
18 void setP2True() { __v |= 0x02U; }
19 void setP3True() { __v |= 0x04U; }
21 DNDS_DEVICE_CALLABLE uint8_t operator^(const NodePeriodicBits &r) const
22 {
23 return uint8_t(__v ^ r.__v);
24 }
26 {
27 return NodePeriodicBits{uint8_t(__v & r.__v)};
28 }
29 DNDS_DEVICE_CALLABLE operator uint8_t() const
30 {
31 return uint8_t{__v};
32 }
33 DNDS_DEVICE_CALLABLE operator bool() const
34 {
35 return bool(__v);
36 }
38 {
39 return uint8_t(r) == uint8_t(*this);
40 }
41 static MPI_Datatype CommType() { return MPI_UINT8_T; }
42 static int CommMult() { return 1; }
43
44 inline friend std::ostream &operator<<(std::ostream &o, const NodePeriodicBits &b)
45 {
46 o << int(b.__v);
47 return o;
48 }
49 };
50
51 static const NodePeriodicBits nodePB1{0x01U};
52 static const NodePeriodicBits nodePB2{0x02U};
53 static const NodePeriodicBits nodePB3{0x04U};
54
55}
56namespace DNDS
57{
58// DNDS_DEVICE_STORAGE_BASE_DELETER_INST(Geom::NodePeriodicBits, extern)
59// DNDS_DEVICE_STORAGE_INST(Geom::NodePeriodicBits, DeviceBackend::Host, extern)
60// #ifdef DNDS_USE_CUDA
61// DNDS_DEVICE_STORAGE_INST(Geom::NodePeriodicBits, DeviceBackend::CUDA, extern)
62// #endif
63}
64namespace DNDS::Geom
65{
66
68 {
71
72 bool operator<(const NodeIndexPBI &r) const
73 {
74 if (i < r.i)
75 return true;
76 else if (i == r.i)
77 return uint8_t(pbi) < uint8_t(r.pbi);
78 else
79 return false;
80 }
81
82 bool operator==(const NodeIndexPBI &r) const
83 {
84 return r.i == i && r.pbi == pbi;
85 }
86
87 bool operator!=(const NodeIndexPBI &r) const { return !(*this == r); }
88 };
89
90 inline bool isCollaborativeNodePeriodicBits(const std::vector<NodePeriodicBits> &a, const std::vector<NodePeriodicBits> &b)
91 {
92 size_t n = a.size();
93 DNDS_assert(n == b.size());
94 if (n == 0)
95 return true;
96 auto v0 = a[0] ^ b[0];
97 for (size_t i = 1; i < n; i++)
98 if ((a.at(i) ^ b.at(i)) != v0)
99 return false;
100 return true;
101 }
102
103 class NodePeriodicBitsRow // instead of std::vector<NodePeriodicBits> for building on raw buffer as a "mapping" object
104 {
105 NodePeriodicBits *__p_indices;
106 rowsize __Row_size;
107
108 public:
109 NodePeriodicBitsRow(NodePeriodicBits *ptr, rowsize siz) : __p_indices(ptr), __Row_size(siz) {} // default actually
110
112 {
113 DNDS_assert(j >= 0 && j < __Row_size);
114 return __p_indices[j];
115 }
116
118 {
119 DNDS_assert(j >= 0 && j < __Row_size);
120 return __p_indices[j];
121 }
122
123 operator std::vector<NodePeriodicBits>() const // copies to a new std::vector<index>
124 {
125 return std::vector<NodePeriodicBits>(__p_indices, __p_indices + __Row_size);
126 }
127
128 void operator=(const std::vector<NodePeriodicBits> &r)
129 {
130 DNDS_assert(__Row_size == r.size());
131 std::copy(r.begin(), r.end(), __p_indices);
132 }
133
135 {
136 DNDS_assert(__Row_size == r.size());
137 std::copy(r.cbegin(), r.cend(), __p_indices);
138 }
139
141 {
143 ret.setP1True();
144 ret.setP2True();
145 ret.setP3True();
146 for (auto &v : *this)
147 ret = ret & v;
148 return ret;
149 }
150
151 NodePeriodicBits *begin() { return __p_indices; }
152 NodePeriodicBits *end() { return __p_indices + __Row_size; } // past-end
153 const NodePeriodicBits *cbegin() const { return __p_indices; }
154 const NodePeriodicBits *cend() const { return __p_indices + __Row_size; } // past-end
155 [[nodiscard]] rowsize size() const { return __Row_size; }
156 };
157
158 template <rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
159 class ArrayNodePeriodicBits : public ParArray<NodePeriodicBits, _row_size, _row_max, _align>
160 {
161 public:
163 using t_base::t_base;
164
166 {
167 DNDS_assert(i < this->Size()); //! disable past-end input
169 }
170
172 };
173 template <rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
175
177 {
178 std::array<tGPointPortable, 4> rotation;
179 std::array<tPointPortable, 4> translation;
180 std::array<tPointPortable, 4> rotationCenter;
183 {
184 for (auto &r : rotation)
185 r.map().setIdentity();
186 for (auto &r : rotationCenter)
187 r.map().setZero();
188 translation[0].map().setZero();
189 translation[1].map() = tPoint{1, 0, 0};
190 translation[2].map() = tPoint{0, 1, 0};
191 translation[3].map() = tPoint{0, 0, 1};
192
193 // translation[1] = tPoint{0, 0, 0};
194 // rotation[1] << 0, 1, 0,
195 // -1, 0, 0,
196 // 0, 0, 1;
197 }
198
199 DNDS_HOST void WriteSerializer(Serializer::SerializerBaseSSP serializerP, const std::string &name)
200 {
201 auto cwd = serializerP->GetCurrentPath();
202 serializerP->CreatePath(name);
203 serializerP->GoToPath(name);
204
205 for (int i = 1; i <= 3; i++)
206 {
207 serializerP->WriteRealVector("rotation" + std::to_string(i), Geom::JacobiToSTDVector(rotation.at(i).map()), Serializer::ArrayGlobalOffset_One);
208 serializerP->WriteRealVector("rotationCenter" + std::to_string(i), Geom::VectorToSTDVector(rotationCenter.at(i).map()), Serializer::ArrayGlobalOffset_One);
209 serializerP->WriteRealVector("translation" + std::to_string(i), Geom::VectorToSTDVector(translation.at(i).map()), Serializer::ArrayGlobalOffset_One);
210 }
211
212 serializerP->GoToPath(cwd);
213 }
214
215 DNDS_HOST void ReadSerializer(Serializer::SerializerBaseSSP serializerP, const std::string &name)
216 {
217 auto cwd = serializerP->GetCurrentPath();
218 // serializerP->CreatePath(name); // * no create
219 serializerP->GoToPath(name);
220
221 for (int i = 1; i <= 3; i++)
222 {
223 std::vector<real> rotRead, rotCRead, transRead;
224 Serializer::ArrayGlobalOffset offsetV = Serializer::ArrayGlobalOffset_One; // must explicitly set as One
225 serializerP->ReadRealVector("rotation" + std::to_string(i), rotRead, offsetV);
226 serializerP->ReadRealVector("rotationCenter" + std::to_string(i), rotCRead, offsetV);
227 serializerP->ReadRealVector("translation" + std::to_string(i), transRead, offsetV);
228 rotation.at(i).map() = Geom::STDVectorToJacobi(rotRead);
229 rotationCenter.at(i).map() = Geom::STDVectorToVector(rotCRead);
230 translation.at(i).map() = Geom::STDVectorToVector(transRead);
231 }
232
233 serializerP->GoToPath(cwd);
234 }
235
236 DNDS_DEVICE_CALLABLE [[nodiscard]] tPoint TransCoord(const tPoint &c, t_index id) const
237 {
239 t_index i{0};
240 if (FaceIDIsPeriodicDonor(id))
241 i = -id - 3;
242 else
243 i = -id;
244 return rotation.at(i).map() * (c - rotationCenter.at(i).map()) + rotationCenter.at(i).map() + translation.at(i).map();
245 }
246
247 DNDS_DEVICE_CALLABLE [[nodiscard]] tPoint TransCoordBack(const tPoint &c, t_index id) const
248 {
250 t_index i{0};
251 if (FaceIDIsPeriodicDonor(id))
252 i = -id - 3;
253 else
254 i = -id;
255 return rotation.at(i).map().transpose() * ((c - translation.at(i).map()) - rotationCenter.at(i).map()) + rotationCenter.at(i).map();
256 }
257
258 ///@todo //TODO: add support for cartesian tensor transformation
259
260 template <int dim, int nVec>
261 DNDS_DEVICE_CALLABLE Eigen::Matrix<real, dim, nVec> TransVector(const Eigen::Matrix<real, dim, nVec> &v, t_index id)
262 {
264 t_index i{0};
265 if (FaceIDIsPeriodicDonor(id))
266 i = -id - 3;
267 else
268 i = -id;
269 if constexpr (dim == 3)
270 return rotation.at(i).map() * v;
271 else
272 return rotation.at(i).map()({0, 1}, {0, 1}) * v;
273 }
274
275 template <int dim, int nVec>
276 DNDS_DEVICE_CALLABLE Eigen::Matrix<real, dim, nVec> TransVectorBack(const Eigen::Matrix<real, dim, nVec> &v, t_index id)
277 {
279 t_index i{0};
280 if (FaceIDIsPeriodicDonor(id))
281 i = -id - 3;
282 else
283 i = -id;
284 if constexpr (dim == 3)
285 return rotation.at(i).map().transpose() * v;
286 else
287 return rotation.at(i).map()({0, 1}, {0, 1}).transpose() * v;
288 }
289
290 template <int dim>
291 DNDS_DEVICE_CALLABLE Eigen::Matrix<real, dim, dim> TransMat(const Eigen::Matrix<real, dim, dim> &m, t_index id)
292 {
294 t_index i{0};
295 if (FaceIDIsPeriodicDonor(id))
296 i = -id - 3;
297 else
298 i = -id;
299 if constexpr (dim == 3)
300 return rotation.at(i).map() * m * rotation.at(i).map().transpose();
301 else
302 return rotation.at(i).map()({0, 1}, {0, 1}) * m * rotation.at(i).map()({0, 1}, {0, 1}).transpose();
303 }
304
305 template <int dim>
306 DNDS_DEVICE_CALLABLE Eigen::Matrix<real, dim, dim> TransMatBack(const Eigen::Matrix<real, dim, dim> &m, t_index id)
307 {
309 t_index i{0};
310 if (FaceIDIsPeriodicDonor(id))
311 i = -id - 3;
312 else
313 i = -id;
314 if constexpr (dim == 3)
315 return rotation.at(i).map().transpose() * m * rotation.at(i).map();
316 else
317 return rotation.at(i).map()({0, 1}, {0, 1}).transpose() * m * rotation.at(i).map()({0, 1}, {0, 1});
318 }
319
320 DNDS_DEVICE_CALLABLE [[nodiscard]] tPoint GetCoordByBits(const tPoint &c, const NodePeriodicBits &bits) const
321 {
322 if (!bool(bits))
323 return c;
324 tPoint ret = c;
325 if (bits.getP3())
326 ret = this->TransCoord(ret, BC_ID_PERIODIC_3);
327 if (bits.getP2())
328 ret = this->TransCoord(ret, BC_ID_PERIODIC_2);
329 if (bits.getP1())
330 ret = this->TransCoord(ret, BC_ID_PERIODIC_1);
331 return ret;
332 }
333
334 template <int dim, int nVec>
335 DNDS_DEVICE_CALLABLE auto GetVectorByBits(const Eigen::Matrix<real, dim, nVec> &v, const NodePeriodicBits &bits)
336 {
337 if (!bool(bits))
338 return v;
339 Eigen::Matrix<real, dim, nVec> ret = v;
340 if (bits.getP3())
341 ret = this->TransVector<dim, nVec>(ret, BC_ID_PERIODIC_3);
342 if (bits.getP2())
343 ret = this->TransVector<dim, nVec>(ret, BC_ID_PERIODIC_2);
344 if (bits.getP1())
345 ret = this->TransVector<dim, nVec>(ret, BC_ID_PERIODIC_1);
346 return ret;
347 }
348
349 DNDS_DEVICE_CALLABLE [[nodiscard]] tPoint GetCoordBackByBits(const tPoint &c, const NodePeriodicBits &bits) const
350 {
351 if (!bool(bits))
352 return c;
353 tPoint ret = c;
354 if (bits.getP1())
355 ret = this->TransCoordBack(ret, BC_ID_PERIODIC_1);
356 if (bits.getP2())
357 ret = this->TransCoordBack(ret, BC_ID_PERIODIC_2);
358 if (bits.getP3())
359 ret = this->TransCoordBack(ret, BC_ID_PERIODIC_3);
360 return ret;
361 }
362
363 template <int dim, int nVec>
364 DNDS_DEVICE_CALLABLE auto GetVectorBackByBits(const Eigen::Matrix<real, dim, nVec> &v, const NodePeriodicBits &bits)
365 {
366 if (!bool(bits))
367 return v;
368 Eigen::Matrix<real, dim, nVec> ret = v;
369 if (bits.getP1())
370 ret = this->TransVectorBack<dim, nVec>(ret, BC_ID_PERIODIC_1);
371 if (bits.getP2())
372 ret = this->TransVectorBack<dim, nVec>(ret, BC_ID_PERIODIC_2);
373 if (bits.getP3())
374 ret = this->TransVectorBack<dim, nVec>(ret, BC_ID_PERIODIC_3);
375 return ret;
376 }
377 };
378} // namespace DNDS::Geom
Father-son array pairs with device views and ghost communication.
ParArray (MPI-aware array) and ArrayTransformer (ghost/halo communication).
#define DNDS_DEVICE_TRIVIAL_COPY_DEFINE(T, T_Self)
Definition Defines.hpp:83
#define DNDS_DEVICE_CALLABLE
Definition Defines.hpp:76
#define DNDS_HOST
Definition Defines.hpp:78
#define DNDS_DEVICE_TRIVIAL_COPY_DEFINE_NO_EMPTY_CTOR(T, T_Self)
Definition Defines.hpp:91
#define DNDS_assert(expr)
Debug-only assertion (compiled out when DNDS_NDEBUG is defined). Prints the expression + file/line + ...
Definition Errors.hpp:108
Base types and abstract interface for array serialization.
Non-owning device-callable view of an Array, specialised per DeviceBackend.
T * operator[](index iRow)
Return a raw pointer to the start of row iRow.
Definition Array.hpp:630
rowsize RowSize() const
Uniform row width for fixed layouts (no row index needed).
Definition Array.hpp:176
index Size() const
Number of rows currently stored. O(1).
Definition Array.hpp:171
NodePeriodicBits * rowPtr(index i)
NodePeriodicBitsRow operator[](index i)
void operator=(const NodePeriodicBitsRow &r)
const NodePeriodicBits * cbegin() const
NodePeriodicBits & operator[](rowsize j)
void operator=(const std::vector< NodePeriodicBits > &r)
NodePeriodicBits operator[](rowsize j) const
const NodePeriodicBits * cend() const
NodePeriodicBitsRow(NodePeriodicBits *ptr, rowsize siz)
MPI-aware Array: adds a communicator, rank, and global index mapping.
Describes one rank's window into a globally-distributed dataset.
Eigen::VectorXd STDVectorToVector(const std::vector< real > &v)
Definition Geometric.hpp:94
tJacobi STDVectorToJacobi(const std::vector< real > &v)
Definition Geometric.hpp:80
int32_t t_index
Definition Geometric.hpp:6
Eigen::Vector3d tPoint
Definition Geometric.hpp:9
DNDS_DEVICE_CALLABLE bool FaceIDIsPeriodic(t_index id)
DNDS_DEVICE_CALLABLE bool FaceIDIsPeriodicDonor(t_index id)
bool isCollaborativeNodePeriodicBits(const std::vector< NodePeriodicBits > &a, const std::vector< NodePeriodicBits > &b)
std::vector< real > JacobiToSTDVector(const tJacobi &j)
Definition Geometric.hpp:72
std::vector< real > VectorToSTDVector(const Eigen::VectorXd &v)
Definition Geometric.hpp:89
ssp< SerializerBase > SerializerBaseSSP
the host side operators are provided as implemented
int32_t rowsize
Row-width / per-row element-count type (signed 32-bit).
Definition Defines.hpp:109
int64_t index
Global row / DOF index type (signed 64-bit; handles multi-billion-cell meshes).
Definition Defines.hpp:107
Convenience bundle of a father, son, and attached ArrayTransformer.
bool operator!=(const NodeIndexPBI &r) const
bool operator<(const NodeIndexPBI &r) const
bool operator==(const NodeIndexPBI &r) const
DNDS_DEVICE_CALLABLE bool operator==(const NodePeriodicBits &r) const
friend std::ostream & operator<<(std::ostream &o, const NodePeriodicBits &b)
DNDS_DEVICE_CALLABLE NodePeriodicBits operator&(const NodePeriodicBits &r) const
static MPI_Datatype CommType()
DNDS_HOST void WriteSerializer(Serializer::SerializerBaseSSP serializerP, const std::string &name)
DNDS_DEVICE_CALLABLE tPoint GetCoordBackByBits(const tPoint &c, const NodePeriodicBits &bits) const
std::array< tPointPortable, 4 > rotationCenter
DNDS_DEVICE_CALLABLE auto GetVectorByBits(const Eigen::Matrix< real, dim, nVec > &v, const NodePeriodicBits &bits)
DNDS_DEVICE_CALLABLE tPoint TransCoordBack(const tPoint &c, t_index id) const
DNDS_DEVICE_CALLABLE auto GetVectorBackByBits(const Eigen::Matrix< real, dim, nVec > &v, const NodePeriodicBits &bits)
std::array< tPointPortable, 4 > translation
std::array< tGPointPortable, 4 > rotation
DNDS_DEVICE_CALLABLE tPoint GetCoordByBits(const tPoint &c, const NodePeriodicBits &bits) const
DNDS_DEVICE_CALLABLE Eigen::Matrix< real, dim, nVec > TransVectorBack(const Eigen::Matrix< real, dim, nVec > &v, t_index id)
DNDS_DEVICE_CALLABLE Eigen::Matrix< real, dim, dim > TransMat(const Eigen::Matrix< real, dim, dim > &m, t_index id)
DNDS_DEVICE_CALLABLE Eigen::Matrix< real, dim, dim > TransMatBack(const Eigen::Matrix< real, dim, dim > &m, t_index id)
DNDS_HOST void ReadSerializer(Serializer::SerializerBaseSSP serializerP, const std::string &name)
DNDS_DEVICE_CALLABLE Eigen::Matrix< real, dim, nVec > TransVector(const Eigen::Matrix< real, dim, nVec > &v, t_index id)
DNDS_DEVICE_CALLABLE tPoint TransCoord(const tPoint &c, t_index id) const
Eigen::Matrix< real, 5, 1 > v
tVec r(NCells)
tVec b(NCells)
Eigen::Vector3d n(1.0, 0.0, 0.0)