9#include <unordered_set>
14#include <nanoflann.hpp>
17#ifdef DNDS_USE_SUPERLU
18# include <superlu_ddefs.h>
38 ret += (*
this)[
i].dot(
R[
i]);
46 return std::sqrt(this->
dot(*
this));
58 (*
this)[
i].setConstant(v);
74 struct PointCloudKDTreeCoordPair
93 return ref->operator[](
idx)(dim);
113 struct SmoothSolverSetup
135 UnstructuredMesh &
mesh)
146 if (!
mesh.nTotalMoved)
149 log() <<
"UnstructuredMesh === ElevatedNodesSolveInternalSmooth() early exit for no nodes were moved";
153 SmoothSolverSetup setup;
157 for (
index iN = 0; iN <
mesh.coords.father->Size(); iN++)
162 setup.nodesBoundInterpolated.insert(iN);
167 setup.boundInterpCoo.InitPair(
"SmoothSolverSetup::boundInterpCoo",
mesh.mpi);
168 setup.boundInterpVal.InitPair(
"SmoothSolverSetup::boundInterpVal",
mesh.mpi);
170 setup.boundInterpCoo.father->Resize(setup.nodesBoundInterpolated.size());
171 setup.boundInterpVal.father->Resize(setup.nodesBoundInterpolated.size());
174 for (
auto iN : setup.nodesBoundInterpolated)
176 setup.boundInterpCoo[top] =
mesh.coords[iN];
177 setup.boundInterpVal[top] =
185 setup.boundInterpCoo.father->createGlobalMapping();
186 index boundInterpGlobSize = setup.boundInterpCoo.father->globalSize();
187 std::vector<index> boundInterpPullIdx(boundInterpGlobSize);
188 for (
index i = 0;
i < boundInterpGlobSize;
i++)
189 boundInterpPullIdx[
i] =
i;
190 setup.boundInterpCoo.TransAttach();
191 setup.boundInterpCoo.trans.createGhostMapping(boundInterpPullIdx);
192 setup.boundInterpCoo.trans.createMPITypes();
193 setup.boundInterpCoo.trans.pullOnce();
195 setup.boundInterpVal.TransAttach();
196 setup.boundInterpVal.trans.BorrowGGIndexing(setup.boundInterpCoo.trans);
197 setup.boundInterpVal.trans.createMPITypes();
198 setup.boundInterpVal.trans.pullOnce();
209 auto &nodesBoundInterpolated =
setup.nodesBoundInterpolated;
210 auto &boundInterpCoo =
setup.boundInterpCoo;
211 auto &boundInterpVal =
setup.boundInterpVal;
218 log() <<
"RBF set: " << boundInterpCoo.son->Size() << std::endl;
220 using kdtree_t = nanoflann::KDTreeSingleIndexAdaptor<
221 nanoflann::L2_Simple_Adaptor<real, PointCloudKDTreeCoordPair>,
230 if (nodesBoundInterpolated.count(
iN))
269 coefs(EigenLast - 3, EigenAll) +
270 qs.transpose() *
coefs.bottomRows(3))
299 auto &nodesBoundInterpolated =
setup.nodesBoundInterpolated;
300 auto &boundInterpCoo =
setup.boundInterpCoo;
301 auto &boundInterpVal =
setup.boundInterpVal;
314 log() <<
"RBF set: " << boundInterpCoo.son->Size() << std::endl;
316 using kdtree_t = nanoflann::KDTreeSingleIndexAdaptor<
317 nanoflann::L2_Simple_Adaptor<real, PointCloudKDTreeCoordPair>,
321 using kdtree_tcoo = nanoflann::KDTreeSingleIndexAdaptor<
322 nanoflann::L2_Simple_Adaptor<real, PointCloudKDTree>,
333 boundInterpCoef.InitPair(
"ElevatedNodesSolveInternalSmoothV1Old::boundInterpCoef",
mpi);
334 boundInterpR.InitPair(
"ElevatedNodesSolveInternalSmoothV1Old::boundInterpR",
mpi);
372 log() <<
"RBF assembled: " << boundInterpCoo.son->Size() << std::endl;
375 Eigen::SparseLU<Eigen::SparseMatrix<real>, Eigen::COLAMDOrdering<int>>
LUSolver;
406 if (!nodesBoundInterpolated.count(
iN))
413#if NANOFLANN_VERSION < 0x150
414 std::vector<std::pair<DNDS::index, DNDS::real>>
IndicesDists;
416 std::vector<nanoflann::ResultItem<DNDS::index, DNDS::real>>
IndicesDists;
420#if NANOFLANN_VERSION < 0x150
421 nanoflann::SearchParams params{};
423 nanoflann::SearchParameters params{};
426 Eigen::Vector<real, Eigen::Dynamic>
outDists;
493 auto &nodesBoundInterpolated =
setup.nodesBoundInterpolated;
494 auto &boundInterpCoo =
setup.boundInterpCoo;
495 auto &boundInterpVal =
setup.boundInterpVal;
510 log() <<
"RBF set: " << boundInterpCoo.son->Size() << std::endl;
512 using kdtree_t = nanoflann::KDTreeSingleIndexAdaptor<
513 nanoflann::L2_Simple_Adaptor<real, PointCloudKDTreeCoordPair>,
517 using kdtree_tcoo = nanoflann::KDTreeSingleIndexAdaptor<
518 nanoflann::L2_Simple_Adaptor<real, PointCloudKDTree>,
530 boundInterpR.InitPair(
"ElevatedNodesSolveInternalSmoothV1::boundInterpR",
mpi);
533 boundInterpR.father->Resize(boundInterpCoo.father->Size());
534 std::vector<std::vector<std::pair<index, real>>>
MatC;
712 Eigen::SparseLU<Eigen::SparseMatrix<real>, Eigen::COLAMDOrdering<int>>
LUSolver;
723 v.InitPair(
"ElevatedNodesSolveInternalSmoothV1::v",
mpi);
727 v.trans.createMPITypes();
728 v.trans.initPersistentPull();
737 x.trans.startPersistentPull();
738 x.trans.waitPersistentPull();
747 Ax.trans.startPersistentPull();
748 Ax.trans.waitPersistentPull();
752 x.trans.startPersistentPull();
753 x.trans.waitPersistentPull();
754 Eigen::Matrix<real, Eigen::Dynamic, 3>
xVal;
758 Eigen::Matrix<real, Eigen::Dynamic, 3>
xValPrec;
764 MLX.trans.startPersistentPull();
765 MLX.trans.waitPersistentPull();
777 log() << fmt::format(
"iRestart {}, res {}, resB {}",
iRestart,
res,
resB) << std::endl;
793 boundInterpR.trans.BorrowGGIndexing(boundInterpCoo.trans);
812 if (!nodesBoundInterpolated.count(
iN))
819#if NANOFLANN_VERSION < 0x150
820 std::vector<std::pair<DNDS::index, DNDS::real>>
IndicesDists;
822 std::vector<nanoflann::ResultItem<DNDS::index, DNDS::real>>
IndicesDists;
826#if NANOFLANN_VERSION < 0x150
827 nanoflann::SearchParams params{};
829 nanoflann::SearchParameters params{};
832 Eigen::Vector<real, Eigen::Dynamic>
outDists;
Batch of uniform-sized Eigen matrices per row, with variable batch count.
Pre-compiled-header style shim that includes the heavy Eigen headers under DNDSR's warning suppressio...
#define DNDS_assert(expr)
Debug-only assertion (compiled out when DNDS_NDEBUG is defined). Prints the expression + file/line + ...
#define DNDS_MPI_InsertCheck(mpi, info)
Debug helper: barrier + print "CHECK <info> RANK r @ fn @ file:line".
MatrixXR RBFCPC2(Tcent cent, Tx xs, real R, RBFKernelType kernel=Gaussian)
MatrixXR FRBFBasis(TIn RiXj, RBFKernelType kernel)
MatrixXR RBFInterpolateSolveCoefsNoPoly(const tSmallCoords &xs, const TF fs, real R, RBFKernelType kernel=Gaussian)
DNDS::ArrayPair< DNDS::ArrayEigenVector< 3 > > tCoordPair
Eigen::Matrix< real, 3, Eigen::Dynamic > tSmallCoords
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.
DNDS_CONSTANT const real UnInitReal
Sentinel "not initialised" real value (NaN). Cheap to detect with std::isnan or IsUnInitReal; survive...
Eigen::Matrix< real, Eigen::Dynamic, Eigen::Dynamic > MatrixXR
Column-major dynamic Eigen matrix of reals (default layout).
DNDS_CONSTANT const real largeReal
Loose upper bound (e.g., for non-dimensional limits).
int64_t index
Global row / DOF index type (signed 64-bit; handles multi-billion-cell meshes).
constexpr T sqr(const T &a)
a * a, constexpr. Works for all arithmetic types.
double real
Canonical floating-point scalar used throughout DNDSR (double precision).
std::ostream & log()
Return the current DNDSR log stream (either std::cout or the installed file).
const MPI_Datatype DNDS_MPI_REAL
MPI datatype matching real (= MPI_REAL8).
DNDS_DEVICE_CALLABLE index Size() const
Combined father + son row count.
Mutable device view onto an ArrayPair (for CUDA kernels).
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()).
TTrans trans
Ghost-communication engine bound to father and son.
CoordPairDOF(const CoordPairDOF &)=default
void operator=(CoordPairDOF &R)
real dot(CoordPairDOF &R)
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
PointCloudKDTreeCoordPair(tCoord &v)
bool kdtree_get_bbox(BBOX &) const
real coord_t
The type of each coordinate.
size_t kdtree_get_point_count() const
std::unordered_set< index > nodesBoundInterpolated
tCoordPair boundInterpVal
tCoordPair boundInterpCoo
UnstructuredMeshDeviceView< B > t_deviceView
tCoordPair coordsElevDisp
only elevation
void ElevatedNodesSolveInternalSmooth()
void ElevatedNodesSolveInternalSmoothV1Old()
void ElevatedNodesSolveInternalSmoothV1()
struct DNDS::Geom::UnstructuredMesh::ElevationInfo elevationInfo
int rank
This rank's 0-based index within comm (-1 until initialised).
Eigen::Matrix< real, 5, 1 > v