DNDSR 0.2.1
Distributed Numeric Data Structure for CFV
Loading...
Searching...
No Matches
Mesh_Elevation_SmoothHelpers.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "Mesh.hpp"
4#include "Geom/PointCloud.hpp"
5#include <nanoflann.hpp>
6#include <optional>
7#include <unordered_set>
8
9namespace DNDS::Geom
10{
11 // =================================================================
12 // CoordPairDOF: extends tCoordPair with dot/norm2/addTo/setConstant
13 // for compatibility with Linear::GMRES_LeftPreconditioned.
14 // =================================================================
15 // Value-semantic class: all members are value types (ssp, TTrans);
16 // = default for all special members per rule of five.
17 struct CoordPairDOF : public tCoordPair
18 {
19 CoordPairDOF() = default;
20 ~CoordPairDOF() = default;
21 CoordPairDOF(const CoordPairDOF &) = default;
23 CoordPairDOF &operator=(const CoordPairDOF &) = default;
25
27 {
28 real ret = 0;
29 for (index i = 0; i < this->father->Size(); i++)
30 ret += (*this)[i].dot(R[i]);
32 MPI::Allreduce(&ret, &retSum, 1, DNDS_MPI_REAL, MPI_SUM, this->father->getMPI().comm);
33 return retSum;
34 }
35
36 real norm2() { return std::sqrt(this->dot(*this)); }
37
39 {
40 for (index i = 0; i < this->Size(); i++)
41 (*this)[i] += R[i] * alpha;
42 }
43
45 {
46 for (index i = 0; i < this->Size(); i++)
47 (*this)[i].setConstant(v);
48 }
49
51 {
52 for (index i = 0; i < this->Size(); i++)
53 (*this)[i] = R[i];
54 }
55
57 {
58 for (index i = 0; i < this->Size(); i++)
59 (*this)[i] *= r;
60 }
61 };
62
63 // =================================================================
64 // Shared setup result for all smooth solver variants.
65 // =================================================================
72
73 /**
74 * \brief Common preamble for all smooth solver variants.
75 *
76 * Checks state assertions, identifies boundary-interpolated nodes,
77 * gathers boundary coordinates and displacement values, and sets up
78 * MPI ghost communication so every rank has a complete copy of the
79 * boundary interpolation data.
80 *
81 * \return std::nullopt if nTotalMoved == 0 (nothing to do).
82 */
83 inline std::optional<SmoothSolverSetup> PrepareSmoothSolverSetup(
85 {
86 DNDS_assert(mesh.elevState == Elevation_O1O2);
87 DNDS_assert(mesh.adjPrimaryState == Adj_PointToLocal);
88 DNDS_assert(mesh.cell2node.isLocal() && mesh.bnd2node.isLocal());
89 DNDS_assert(mesh.adjFacialState == Adj_PointToLocal);
90 DNDS_assert(mesh.face2cell.isLocal() && mesh.face2node.isLocal());
91 DNDS_assert(mesh.adjC2FState == Adj_PointToLocal);
92 DNDS_assert(mesh.cell2face.isLocal() && mesh.bnd2face.isLocal());
93 DNDS_assert(mesh.face2node.father);
94 DNDS_assert(mesh.nTotalMoved >= 0);
95 if (!mesh.nTotalMoved)
96 {
97 if (mesh.mpi.rank == mesh.mRank)
98 log() << "UnstructuredMesh === ElevatedNodesSolveInternalSmooth() "
99 "early exit for no nodes were moved";
100 return std::nullopt;
101 }
102
103 SmoothSolverSetup setup;
104
105 for (index iN = 0; iN < mesh.coords.father->Size(); iN++)
106 {
107 if (mesh.coordsElevDisp[iN](0) != largeReal ||
108 mesh.coordsElevDisp[iN](2) == 2 * largeReal)
109 {
110 setup.nodesBoundInterpolated.insert(iN);
111 }
112 }
113
114 setup.boundInterpCoo.InitPair("SmoothSolverSetup::boundInterpCoo", mesh.mpi);
115 setup.boundInterpVal.InitPair("SmoothSolverSetup::boundInterpVal", mesh.mpi);
116
117 setup.boundInterpCoo.father->Resize(setup.nodesBoundInterpolated.size());
118 setup.boundInterpVal.father->Resize(setup.nodesBoundInterpolated.size());
119
120 index top{0};
121 for (auto iN : setup.nodesBoundInterpolated)
122 {
123 setup.boundInterpCoo[top] = mesh.coords[iN];
124 setup.boundInterpVal[top] =
125 (mesh.coordsElevDisp[iN](0) != largeReal)
126 ? tPoint{mesh.coordsElevDisp[iN]}
127 : tPoint::Zero();
128 top++;
129 }
130
131 setup.boundInterpCoo.father->createGlobalMapping();
132 index boundInterpGlobSize = setup.boundInterpCoo.father->globalSize();
133 std::vector<index> boundInterpPullIdx(boundInterpGlobSize);
134 for (index i = 0; i < boundInterpGlobSize; i++)
135 boundInterpPullIdx[i] = i;
137 setup.boundInterpCoo.trans.createGhostMapping(boundInterpPullIdx);
138 setup.boundInterpCoo.trans.createMPITypes();
139 setup.boundInterpCoo.trans.pullOnce();
140
142 setup.boundInterpVal.trans.BorrowGGIndexing(setup.boundInterpCoo.trans);
143 setup.boundInterpVal.trans.createMPITypes();
144 setup.boundInterpVal.trans.pullOnce();
145
146 return setup;
147 }
148
149 // =================================================================
150 // KD-tree point cloud adapter for tCoord (shared).
151 // =================================================================
153 {
156
157 [[nodiscard]] size_t kdtree_get_point_count() const
158 {
160 return ref->Size();
161 }
162 [[nodiscard]] real kdtree_get_pt(const size_t idx, const size_t dim) const
163 {
165 return ref->operator[](idx)(dim);
166 }
167 template <class BBOX>
168 bool kdtree_get_bbox(BBOX &bbox) const { return false; }
169 };
170
171} // namespace DNDS::Geom
#define DNDS_assert(expr)
Debug-only assertion (compiled out when DNDS_NDEBUG is defined). Prints the expression + file/line + ...
Definition Errors.hpp:112
Eigen::Vector3d tPoint
Definition Geometric.hpp:9
std::optional< SmoothSolverSetup > PrepareSmoothSolverSetup(UnstructuredMesh &mesh)
Common preamble for all smooth solver variants.
decltype(tCoordPair::father) tCoord
MPI_int Allreduce(const void *sendbuf, void *recvbuf, MPI_int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
Wrapper over MPI_Allreduce.
Definition MPI.cpp:202
DNDS_CONSTANT const real UnInitReal
Sentinel "not initialised" real value (NaN). Cheap to detect with std::isnan or IsUnInitReal; survive...
Definition Defines.hpp:179
DNDS_CONSTANT const real largeReal
Loose upper bound (e.g., for non-dimensional limits).
Definition Defines.hpp:197
int64_t index
Global row / DOF index type (signed 64-bit; handles multi-billion-cell meshes).
Definition Defines.hpp:112
double real
Canonical floating-point scalar used throughout DNDSR (double precision).
Definition Defines.hpp:110
std::ostream & log()
Return the current DNDSR log stream (either std::cout or the installed file).
Definition Defines.cpp:50
const MPI_Datatype DNDS_MPI_REAL
MPI datatype matching real (= MPI_REAL8).
Definition MPI.hpp:108
DNDS_DEVICE_CALLABLE index Size() const
Combined father + son row count.
Definition ArrayPair.hpp:33
Mutable device view onto an ArrayPair (for CUDA kernels).
void TransAttach()
Bind the transformer to the current father / son pointers.
ArrayPairDeviceView< B, DNDS::ArrayEigenVector< 3 > > t_deviceView
Device-view template alias: t_deviceView<DeviceBackend::CUDA> gives the mutable CUDA view type for th...
ssp< DNDS::ArrayEigenVector< 3 > > father
Owned-side array (must be resized before ghost setup).
index Size() const
Combined row count (father->Size() + son->Size()).
void InitPair(const std::string &name, Args &&...args)
Allocate both father and son arrays, forwarding all args to TArray constructor.
TTrans trans
Ghost-communication engine bound to father and son.
CoordPairDOF(const CoordPairDOF &)=default
CoordPairDOF & operator=(CoordPairDOF &&)=default
void addTo(CoordPairDOF &R, real alpha)
CoordPairDOF(CoordPairDOF &&)=default
CoordPairDOF & operator=(const CoordPairDOF &)=default
real kdtree_get_pt(const size_t idx, const size_t dim) const
Result of the shared smooth solver setup.
std::unordered_set< index > nodesBoundInterpolated
Eigen::Matrix< real, 5, 1 > v
tVec r(NCells)
real alpha
DistributedHex3D mesh
DNDS::index idx