DNDSR 0.1.0.dev1+gcd065ad
Distributed Numeric Data Structure for CFV
Loading...
Searching...
No Matches
FiniteVolume.hpp
Go to the documentation of this file.
1#pragma once
4#include "DNDS/Errors.hpp"
6#include "Geom/Mesh.hpp"
7#include "VRDefines.hpp"
9#include "DOFFactory.hpp"
10
12
13namespace DNDS::CFV
14{
15 class FiniteVolume : public DeviceTransferable<FiniteVolume>
16 {
17 friend class DeviceTransferable<FiniteVolume>;
18 public:
22
23 protected:
25
26 public:
28 {
29 return settings;
30 }
31
36
37 protected:
39 real volGlobal{0}; /// @brief constructed using ConstructMetrics()
40 tScalarPair volumeLocal; /// @brief constructed using ConstructMetrics()
41 tScalarPair faceArea; /// @brief constructed using ConstructMetrics()
42 tRecAtrPair cellAtr; /// @brief constructed using ConstructMetrics()
43 tRecAtrPair faceAtr; /// @brief constructed using ConstructMetrics()
44 tCoeffPair cellIntJacobiDet; /// @brief constructed using ConstructMetrics()
45 tCoeffPair faceIntJacobiDet; /// @brief constructed using ConstructMetrics()
46 t3VecsPair faceUnitNorm; /// @brief constructed using ConstructMetrics()
47 t3VecPair faceMeanNorm; /// @brief constructed using ConstructMetrics()
48 t3VecPair cellBary; /// @brief constructed using ConstructMetrics()
49 t3VecPair faceCent; /// @brief constructed using ConstructMetrics()
50 t3VecPair cellCent; /// @brief constructed using ConstructMetrics()
51 t3VecsPair cellIntPPhysics; /// @brief constructed using ConstructMetrics()
52 t3VecsPair faceIntPPhysics; /// @brief constructed using ConstructMetrics()
53 t3VecPair cellAlignedHBox; /// @brief constructed using ConstructMetrics()
54 t3VecPair cellMajorHBox; /// @brief constructed using ConstructMetrics()
55 t3MatPair cellMajorCoord; /// @brief constructed using ConstructMetrics()
56 t3MatPair cellInertia; /// @brief constructed using ConstructMetrics()
57 tScalarPair cellSmoothScale; /// @brief constructed using ConstructMetrics()
58
81
82 template <typename F>
84 {
85 for_each_member_list(device_array_list(), std::forward<F>(f));
86 }
87
89
90 protected:
92 std::set<index> axisFaces;
93
94 public:
95 int GetAxisSymmetric() const { return axisSymmetric; }
96 int SetAxisSymmetric(int v) { return axisSymmetric = v; }
97
98 public:
100 : mpi(nMpi), mesh(std::move(nMesh)), settings(mesh->getDim())
101 {
102 mRank = mesh->mRank;
103 periodicity = mesh->periodicInfo; //! copy here
104 }
105
106 int getDim() const { return mesh->getDim(); }
107
108 /**
109 * @brief make pair with default MPI type, match **cell** layout
110 *
111 * @tparam TArrayPair ArrayPair's type
112 * @tparam TOthers A list of additional resizing parameter types
113 * @param aPair the pair to be constructed
114 * @param name descriptive name for the pair (appears in error messages)
115 * @param others additional resizing parameters
116 */
117 template <class TArrayPair, class... TOthers>
118 void MakePairDefaultOnCell(TArrayPair &aPair, const std::string &name, TOthers... others)
119 {
120 aPair.InitPair(name, mpi);
121 aPair.father->Resize(mesh->NumCell(), others...);
122 aPair.son->Resize(mesh->NumCellGhost(), others...);
123 }
124
125 /**
126 * @brief make pair with default MPI type, match **face** layout
127 *
128 * @tparam TArrayPair ArrayPair's type
129 * @tparam TOthers A list of additional resizing parameter types
130 * @param aPair the pair to be constructed
131 * @param name descriptive name for the pair (appears in error messages)
132 * @param others additional resizing parameters
133 */
134 template <class TArrayPair, class... TOthers>
135 void MakePairDefaultOnFace(TArrayPair &aPair, const std::string &name, TOthers... others)
136 {
137 aPair.InitPair(name, mpi);
138 aPair.father->Resize(mesh->NumFace(), others...);
139 aPair.son->Resize(mesh->NumFaceGhost(), others...);
140 }
141
142 void SetCellAtrBasic();
143
144 void ConstructCellVolume();
145 void ConstructCellBary();
146 void ConstructCellCent();
149 void ConstructCellAlignedHBox(); // note this is AABB
151
152 void SetFaceAtrBasic();
153
154 void ConstructFaceArea();
155 void ConstructFaceCent();
158 void ConstructFaceUnitNorm(); // on quad int points
160
162
163 template <int nVarsFixed = 1>
165 {
166 BuildUDofOnMesh(u, "FV::BuildUDof::u", mpi, mesh, nVars, buildSon, buildTrans, varloc);
167 }
168
169 template <int nVarsFixed, int dim>
171 {
172 BuildUGradDOnMesh(u, "FV::BuildUGradD::u", mpi, mesh, nVars, buildSon, buildTrans, varloc);
173 }
174
176 {
177 return cellAtr(iCell, 0);
178 }
179
181 {
182 return cellAtr(iCell, 0).Order;
183 }
184
186 {
187 return faceAtr(iFace, 0);
188 }
189
191 {
192 if (getDim() == 2)
193 return Geom::Base::GetNDof<2>(settings.maxOrder);
194 else
195 return Geom::Base::GetNDof<3>(settings.maxOrder);
196 }
197
199 real GetFaceArea(index iFace) const { return faceArea[iFace][0]; }
200
202 {
203 return cellSmoothScale(iCell, 0);
204 }
205
206 real GetGlobalVol() const { return volGlobal; }
207
210
212 {
213 auto e = mesh->GetFaceElement(iFace);
214 return Geom::Elem::Quadrature{e, faceAtr(iFace, 0).intOrder};
215 }
216
218 {
219 auto e = mesh->GetFaceElement(iFace);
220 return Geom::Elem::Quadrature{e, 1};
221 }
222
223 real GetFaceParamArea(index iFace) const { return std::get<1>(this->GetFaceQuadO1(iFace).GetQuadraturePointInfo(0)); }
224
226 {
227 auto e = mesh->GetCellElement(iCell);
228 return Geom::Elem::Quadrature{e, cellAtr(iCell, 0).intOrder};
229 }
230
232 {
233 auto e = mesh->GetCellElement(iCell);
234 return Geom::Elem::Quadrature{e, 1};
235 }
236
237 real GetCellParamVol(index iCell) const { return std::get<1>(this->GetCellQuadO1(iCell).GetQuadraturePointInfo(0)); }
238
240
242 {
243 return mesh->CellIsFaceBack(iCell, iFace);
244 }
245
247 {
248 return mesh->CellFaceOther(iCell, iFace);
249 }
250
252 {
253 if (iG >= 0)
254 return faceUnitNorm(iFace, iG);
255 else
256 return faceMeanNorm[iFace];
257 }
258
260 {
261 if (!mesh->isPeriodic)
262 return GetFaceNorm(iFace, iG);
263 auto faceID = mesh->faceElemInfo[iFace]->zone;
265 return GetFaceNorm(iFace, iG);
266 if (if2c < 0)
267 if2c = CellIsFaceBack(iCell, iFace) ? 0 : 1;
269 return mesh->periodicInfo.TransVector(GetFaceNorm(iFace, iG), faceID);
271 return mesh->periodicInfo.TransVectorBack(GetFaceNorm(iFace, iG), faceID);
272 return GetFaceNorm(iFace, iG);
273 }
274
276 {
277 if (iG >= 0)
278 return faceIntPPhysics(iFace, iG);
279 else
280 return faceCent[iFace];
281 }
282
284 {
285 if (!mesh->isPeriodic)
287 auto faceID = mesh->faceElemInfo[iFace]->zone;
290 if (if2c < 0)
291 if2c = CellIsFaceBack(iCell, iFace) ? 0 : 1;
292 if (if2c == 1 && Geom ::FaceIDIsPeriodicMain(faceID)) // I am donor
293 {
294 return mesh->periodicInfo.TransCoord(GetFaceQuadraturePPhys(iFace, iG), faceID);
295 }
296 if (if2c == 1 && Geom::FaceIDIsPeriodicDonor(faceID)) // I am main
297 return mesh->periodicInfo.TransCoordBack(GetFaceQuadraturePPhys(iFace, iG), faceID);
299 }
300
302 {
303 if (!mesh->isPeriodic)
304 return pnt;
305 auto faceID = mesh->faceElemInfo[iFace]->zone;
307 return pnt;
308 if (if2c < 0)
309 if2c = CellIsFaceBack(iCell, iFace) ? 0 : 1;
310 if (if2c == 1 && Geom ::FaceIDIsPeriodicMain(faceID)) // I am donor
311 {
312 return mesh->periodicInfo.TransCoord(pnt, faceID);
313 }
314 if (if2c == 1 && Geom::FaceIDIsPeriodicDonor(faceID)) // I am main
315 return mesh->periodicInfo.TransCoordBack(pnt, faceID);
316 return pnt;
317 }
318
321 index iFace)
322 {
323 if (!mesh->isPeriodic)
324 return GetCellBary(iCellOther);
325
326 auto faceID = mesh->faceElemInfo[iFace]->zone;
328 return GetCellBary(iCellOther);
330 if ((if2c == 1 && Geom::FaceIDIsPeriodicMain(faceID)) ||
331 (if2c == 0 && Geom::FaceIDIsPeriodicDonor(faceID))) // I am donor
332 return mesh->periodicInfo.TransCoord(GetCellBary(iCellOther), faceID);
333 if ((if2c == 1 && Geom::FaceIDIsPeriodicDonor(faceID)) ||
334 (if2c == 0 && Geom::FaceIDIsPeriodicMain(faceID))) // I am main
335 return mesh->periodicInfo.TransCoordBack(GetCellBary(iCellOther), faceID);
336 return GetCellBary(iCellOther);
337 }
338
341 index iFace, const Geom::tPoint &pnt)
342 {
343 if (!mesh->isPeriodic)
344 return pnt;
345
346 auto faceID = mesh->faceElemInfo[iFace]->zone;
348 return pnt;
350 if ((if2c == 1 && Geom::FaceIDIsPeriodicMain(faceID)) ||
351 (if2c == 0 && Geom::FaceIDIsPeriodicDonor(faceID))) // I am donor
352 return mesh->periodicInfo.TransCoord(pnt, faceID);
353 if ((if2c == 1 && Geom::FaceIDIsPeriodicDonor(faceID)) ||
354 (if2c == 0 && Geom::FaceIDIsPeriodicMain(faceID))) // I am main
355 return mesh->periodicInfo.TransCoordBack(pnt, faceID);
356 return pnt;
357 }
358
361 index iFace)
362 { // structure copy of GetOtherCellBaryFromCell
363 if (!mesh->isPeriodic)
364 return cellInertia[iCellOther];
365
366 auto faceID = mesh->faceElemInfo[iFace]->zone;
368 return cellInertia[iCellOther];
370 if ((if2c == 1 && Geom::FaceIDIsPeriodicMain(faceID)) ||
371 (if2c == 0 && Geom::FaceIDIsPeriodicDonor(faceID))) // I am donor
372 return mesh->periodicInfo.TransMat<3>(cellInertia[iCellOther], faceID);
373 if ((if2c == 1 && Geom::FaceIDIsPeriodicDonor(faceID)) ||
374 (if2c == 0 && Geom::FaceIDIsPeriodicMain(faceID))) // I am main
375 return mesh->periodicInfo.TransMatBack<3>(cellInertia[iCellOther], faceID);
376 return cellInertia[iCellOther];
377 }
378
380 {
381 if (iG >= 0)
382 return cellIntPPhysics(iCell, iG);
383 else
384 return cellCent[iCell];
385 }
386
388 {
389 if (this->getDim() == 2)
390 return cellMajorHBox[iCell]({0, 1}).maxCoeff() * 2;
391 else
392 return cellMajorHBox[iCell].maxCoeff() * 2;
393 }
394
396 {
397 Geom::tSmallCoords coords;
398 mesh->GetCoordsOnCell(iCell, coords);
399 auto e = mesh->GetCellElement(iCell);
400 Geom::tSmallCoords coordsV = coords(EigenAll, Eigen::seq(0, e.GetNumVertices() - 1));
401
403 for (int i = 0; i < e.GetNumVertices(); i++)
404 for (int j = 0; j < i; j++)
405 {
406 real d = (coordsV(EigenAll, i) - coordsV(EigenAll, j)).norm();
407 ret = std::min(ret, d);
408 }
409 return ret;
410 }
411
413 {
414 index bytes = this->getDeviceArrayBytes();
416 return bytes;
417 }
418
419 // to_device(), to_host(), device() are provided by
420 // DeviceTransferable<FiniteVolume> via for_each_device_member().
421
422 template <DeviceBackend B>
424
425 template <DeviceBackend B>
427
428 template <DeviceBackend B>
430 {
431 DeviceBackend B_mesh = mesh->device();
433 return {*this, UnInitIndex};
434 }
435 };
436
437}
Free-function DOF array builders extracted from FiniteVolume.
Device memory abstraction layer with backend-specific storage and factory creation.
CRTP mixin that provides uniform to_device/to_host/device/getDeviceArrayBytes for classes that enumer...
Assertion / error-handling macros and supporting helper functions.
#define DNDS_assert(expr)
Debug-only assertion (compiled out when DNDS_NDEBUG is defined). Prints the expression + file/line + ...
Definition Errors.hpp:108
#define DNDS_MAKE_1_MEMBER_REF(x)
Construct a MemberRef capturing x and its stringified name.
DNDS_DEVICE_CALLABLE bool CellIsFaceBack(index iCell, index iFace) const
DNDS_DEVICE_CALLABLE index CellFaceOther(index iCell, index iFace) const
Geom::tPoint GetFaceNormFromCell(index iFace, index iCell, rowsize if2c, int iG)
void parseSettings(FiniteVolumeSettings::json &j)
t3VecsPair faceUnitNorm
constructed using ConstructMetrics()
real GetFaceParamArea(index iFace) const
t3VecPair faceMeanNorm
constructed using ConstructMetrics()
Geom::Elem::Quadrature GetFaceQuad(index iFace) const
t3MatPair cellMajorCoord
constructed using ConstructMetrics()
real GetCellMaxLenScale(index iCell)
void BuildUGradD(tUGrad< nVarsFixed, dim > &u, int nVars, bool buildSon=true, bool buildTrans=true, Geom::MeshLoc varloc=Geom::MeshLoc::Cell)
int GetCellOrder(index iCell)
tRecAtrPair faceAtr
constructed using ConstructMetrics()
void MakePairDefaultOnFace(TArrayPair &aPair, const std::string &name, TOthers... others)
make pair with default MPI type, match face layout
t3VecPair cellBary
constructed using ConstructMetrics()
Geom::tPoint GetCellBary(index iCell)
void for_each_device_member(F &&f)
t3VecPair cellCent
constructed using ConstructMetrics()
Geom::Elem::Quadrature GetFaceQuadO1(index iFace) const
Geom::tPoint GetCellQuadraturePPhys(index iCell, int iG)
Geom::tPoint GetOtherCellBaryFromCell(index iCell, index iCellOther, index iFace)
real GetCellNodeMinLenScale(index iCell)
ssp< Geom::UnstructuredMesh > mesh
Geom::tPoint GetFaceQuadraturePPhys(index iFace, int iG)
index CellFaceOther(index iCell, index iFace) const
tCoeffPair faceIntJacobiDet
constructed using ConstructMetrics()
real GetCellSmoothScaleRatio(index iCell) const
tCoeffPair cellIntJacobiDet
constructed using ConstructMetrics()
Geom::Elem::Quadrature GetCellQuad(index iCell) const
t3MatPair cellInertia
constructed using ConstructMetrics()
Geom::tPoint GetFaceNorm(index iFace, int iG) const
const FiniteVolumeSettings & getSettings() const
t3VecsPair faceIntPPhysics
constructed using ConstructMetrics()
real GetCellVol(index iCell) const
bool CellIsFaceBack(index iCell, index iFace) const
real GetFaceJacobiDet(index iFace, rowsize iG)
Geom::tPoint GetFaceQuadraturePPhysFromCell(index iFace, index iCell, rowsize if2c, int iG)
void BuildUDof(tUDof< nVarsFixed > &u, int nVars, bool buildSon=true, bool buildTrans=true, Geom::MeshLoc varloc=Geom::MeshLoc::Cell)
tScalarPair faceArea
constructed using ConstructMetrics()
std::set< index > axisFaces
FiniteVolumeSettings settings
FiniteVolumeDeviceView< B > t_deviceView
Geom::Elem::Quadrature GetCellQuadO1(index iCell) const
t3VecPair faceCent
constructed using ConstructMetrics()
void MakePairDefaultOnCell(TArrayPair &aPair, const std::string &name, TOthers... others)
make pair with default MPI type, match cell layout
real GetFaceArea(index iFace) const
t3VecPair cellMajorHBox
constructed using ConstructMetrics()
tRecAtrPair cellAtr
constructed using ConstructMetrics()
Geom::tPoint GetFacePointFromCell(index iFace, index iCell, rowsize if2c, const Geom::tPoint &pnt)
Geom::Base::CFVPeriodicity periodicity
FiniteVolume(MPIInfo nMpi, ssp< Geom::UnstructuredMesh > nMesh)
real GetCellJacobiDet(index iCell, rowsize iG)
real GetCellParamVol(index iCell) const
t3VecsPair cellIntPPhysics
constructed using ConstructMetrics()
t_deviceView< B > deviceView()
tScalarPair cellSmoothScale
constructed using ConstructMetrics()
t3VecPair cellAlignedHBox
constructed using ConstructMetrics()
tScalarPair volumeLocal
constructed using ConstructMetrics()
Geom::tPoint GetOtherCellPointFromCell(index iCell, index iCellOther, index iFace, const Geom::tPoint &pnt)
RecAtr & GetFaceAtr(index iFace)
RecAtr & GetCellAtr(index iCell)
Geom::tGPoint GetOtherCellInertiaFromCell(index iCell, index iCellOther, index iFace)
auto device_array_list()
constructed using ConstructMetrics()
CRTP mixin giving a class uniform to_device / to_host / device / getDeviceArrayBytes methods.
index getDeviceArrayBytes()
Total footprint of every registered father+son pair in bytes.
void BuildUGradDOnMesh(tUGrad< nVarsFixed, dim > &u, const std::string &name, const MPIInfo &mpi, const ssp< Geom::UnstructuredMesh > &mesh, int nVars, bool buildSon=true, bool buildTrans=true, Geom::MeshLoc varloc=Geom::MeshLoc::Cell)
Build a gradient DOF array pair matching a mesh location.
void BuildUDofOnMesh(tUDof< nVarsFixed > &u, const std::string &name, const MPIInfo &mpi, const ssp< Geom::UnstructuredMesh > &mesh, int nVars, bool buildSon=true, bool buildTrans=true, Geom::MeshLoc varloc=Geom::MeshLoc::Cell)
Build a DOF array pair matching a mesh location (cell/face/node).
Eigen::Vector3d tPoint
Definition Geometric.hpp:9
Eigen::Matrix< real, 3, Eigen::Dynamic > tSmallCoords
Definition Geometric.hpp:50
DNDS_DEVICE_CALLABLE bool FaceIDIsPeriodic(t_index id)
DNDS_DEVICE_CALLABLE bool FaceIDIsPeriodicDonor(t_index id)
DNDS_DEVICE_CALLABLE bool FaceIDIsPeriodicMain(t_index id)
Eigen::Matrix3d tGPoint
Definition Geometric.hpp:11
void AllreduceOneIndex(index &v, MPI_Op op, const MPIInfo &mpi)
Single-scalar Allreduce helper for indices (in-place, count = 1).
Definition MPI.hpp:679
DeviceBackend
Enumerates the backends a DeviceStorage / Array can live on.
@ Unknown
Unset / sentinel.
@ Host
Plain CPU memory.
DNDS_CONSTANT const index UnInitIndex
Sentinel "not initialised" index value (= INT64_MIN).
Definition Defines.hpp:176
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
void for_each_member_list(TList &&obj_member_list, F &&f)
Invoke f(member) for every element of a std::tuple of members.
double real
Canonical floating-point scalar used throughout DNDSR (double precision).
Definition Defines.hpp:105
DNDS_CONSTANT const real veryLargeReal
Catch-all upper bound ("practically infinity") for physical scalars.
Definition Defines.hpp:190
int MPI_int
MPI counterpart type for MPI_int (= C int). Used for counts and ranks in MPI calls.
Definition MPI.hpp:43
A means to translate nlohmann json into c++ primitive data types and back; and stores then during com...
DNDS_HOST void ParseFromJson(const json &jsonSetting)
Backward-compatible read (used by Python bindings and VRSettings).
Lightweight bundle of an MPI communicator and the calling rank's coordinates.
Definition MPI.hpp:215
Eigen::Matrix< real, 5, 1 > v