Loading...
Searching...
No Matches
patch_skd_tree.hpp
1/*---------------------------------------------------------------------------*\
2 *
3 * bitpit
4 *
5 * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6 *
7 * -------------------------------------------------------------------------
8 * License
9 * This file is part of bitpit.
10 *
11 * bitpit is free software: you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License v3 (LGPL)
13 * as published by the Free Software Foundation.
14 *
15 * bitpit is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with bitpit. If not, see <http://www.gnu.org/licenses/>.
22 *
23\*---------------------------------------------------------------------------*/
24
25# ifndef __BITPIT_PATCH_SKD_TREE_HPP__
26# define __BITPIT_PATCH_SKD_TREE_HPP__
27
28#include "patch_kernel.hpp"
29
30#include "bitpit_common.hpp"
31
32namespace bitpit {
33
34class PatchSkdTree;
35
37
38friend class PatchSkdTree;
39
40public:
41 void buildCache();
42 void buildCache(const PatchKernel::CellConstRange &cellRange);
43 void destroyCache();
44
45 const PatchKernel & getPatch() const;
46 const std::vector<std::size_t> & getCellRawIds() const;
47 std::size_t getCellRawId(std::size_t n) const;
48
49 const std::array<std::array<double, 3>, 2> & getCachedBox(std::size_t rawId) const;
50
51 std::array<double, 3> evalCachedBoxMean(std::size_t rawId) const;
52 double evalCachedBoxMean(std::size_t rawId, int direction) const;
53
54protected:
56
57 SkdPatchInfo(const PatchKernel *patch, const std::vector<std::size_t> *cellRawIds);
58
59 const PatchKernel *m_patch;
60 const std::vector<std::size_t> *m_cellRawIds;
61
62 std::unique_ptr<BoxCache> m_cellBoxes;
63
64};
65
66class SkdBox {
67
68public:
69 SkdBox();
70 SkdBox(const std::array<double,3> &boxMin, const std::array<double,3> &boxMax);
71
72 bool isEmpty() const;
73
74 const std::array<double, 3> & getBoxMin() const;
75 const std::array<double, 3> & getBoxMax() const;
76
77 double evalPointMinDistance(const std::array<double, 3> &point) const;
78 double evalPointMinDistance(const std::array<double, 3> &point, double emptyDistance) const;
79 double evalPointMinSquareDistance(const std::array<double, 3> &point) const;
80 double evalPointMinSquareDistance(const std::array<double, 3> &point, double emptySquareDistance) const;
81
82 double evalPointMaxDistance(const std::array<double, 3> &point) const;
83 double evalPointMaxDistance(const std::array<double, 3> &point, double emptyDistance) const;
84 double evalPointMaxSquareDistance(const std::array<double, 3> &point) const;
85 double evalPointMaxSquareDistance(const std::array<double, 3> &point, double emptySquareDistance) const;
86
87 bool boxContainsPoint(const std::array<double,3> &point, double offset) const;
88 bool boxIntersectsSphere(const std::array<double,3> &center, double radius) const;
89
90protected:
91 std::array<double, 3> m_boxMin;
92 std::array<double, 3> m_boxMax;
93
94};
95
96class SkdNode : public SkdBox {
97
98friend class PatchSkdTree;
99
100public:
101 BITPIT_PUBLIC_API static const std::size_t NULL_ID;
102
103 BITPIT_PUBLIC_API constexpr static const int MAX_CHILDREN = 2;
104
105 enum ChildLocation {
106 CHILD_LEFT = 0,
107 CHILD_RIGHT = 1,
108 CHILD_BEGIN = 0,
109 CHILD_END = 2
110 };
111
112 SkdNode();
113 SkdNode(const SkdPatchInfo *patchInfo, std::size_t cellRangeBegin, std::size_t cellRangeEnd);
114
115 std::size_t getCellCount() const;
116 std::vector<long> getCells() const;
117 long getCell(std::size_t n) const;
118
119 const SkdBox & getBoundingBox() const;
120
121 std::array<double,3> evalBoxWeightedMean() const;
122 double evalBoxWeightedMean(int direction) const;
123
124 bool isLeaf() const;
125 bool hasChild(ChildLocation child) const;
126 std::size_t getChildId(ChildLocation child) const;
127
128 double evalPointDistance(const std::array<double, 3> &point, bool interiorCellsOnly) const;
129
130 void findPointClosestCell(const std::array<double, 3> &point, bool interiorCellsOnly, long *closestId, double *closestDistance) const;
131 void updatePointClosestCell(const std::array<double, 3> &point, bool interiorCellsOnly, long *closestId, double *closestDistance) const;
132 void updatePointClosestCells(const std::array<double, 3> &point, bool interiorCellsOnly, std::vector<long> *closestIds, double *closestDistance) const;
133
134private:
135 const SkdPatchInfo *m_patchInfo;
136
137 std::size_t m_cellRangeBegin;
138 std::size_t m_cellRangeEnd;
139
140 std::array<std::size_t, MAX_CHILDREN> m_children;
141
142 void initializeBoundingBox();
143
144};
145
146#if BITPIT_ENABLE_MPI
148
149public:
150 static MPI_Datatype getMPIDatatype();
151 static MPI_Op getMPIMinOperation();
152 static void executeMPIMinOperation(SkdGlobalCellDistance *in, SkdGlobalCellDistance *inout, int *len, MPI_Datatype *datatype);
153
154 int & getRank();
155 long & getId();
156 double & getDistance();
157
158 void exportData(int *rank, long *id, double *distance) const;
159
160private:
161 static bool m_MPIDatatypeInitialized;
162 static MPI_Datatype m_MPIDatatype;
163
164 static bool m_MPIMinOperationInitialized;
165 static MPI_Op m_MPIMinOperation;
166
167 double m_distance;
168 long m_id;
169 int m_rank;
170
171};
172#endif
173
175
176public:
177 virtual ~PatchSkdTree() = default;
178
179 void build(std::size_t leaftThreshold = 1, bool squeezeStorage = false);
180 void clear(bool release = false);
181
182 const PatchKernel & getPatch() const;
183
184 std::size_t getLeafMinCellCount() const;
185 std::size_t getLeafMaxCellCount() const;
186
187 std::size_t getNodeCount() const;
188 std::size_t getLeafCount() const;
189
190 const SkdNode & getNode(std::size_t nodeId) const;
191
192 std::size_t evalMaxDepth(std::size_t rootId = 0) const;
193
194 void enableThreadSafeLookups(bool enable);
195 bool areLookupsThreadSafe() const;
196
197#if BITPIT_ENABLE_MPI
198 const SkdBox & getPartitionBox(int rank) const;
199#endif
200
201protected:
202 SkdPatchInfo m_patchInfo;
203 std::vector<std::size_t> m_cellRawIds;
204
205 std::size_t m_nLeafs;
206 std::size_t m_nMinLeafCells;
207 std::size_t m_nMaxLeafCells;
208
209 std::vector<SkdNode> m_nodes;
210
211 bool m_interiorCellsOnly;
212
213 bool m_threadSafeLookups;
215#if BITPIT_ENABLE_MPI
217 int m_nProcessors;
218 MPI_Comm m_communicator;
219 std::vector<SkdBox> m_partitionBoxes;
220#endif
221
222 PatchSkdTree(const PatchKernel *patch, bool interiorCellsOnly = false);
223
224 SkdNode & _getNode(std::size_t nodeId);
225
226#if BITPIT_ENABLE_MPI
227 bool isCommunicatorSet() const;
228 const MPI_Comm & getCommunicator() const;
229 void setCommunicator(MPI_Comm communicator);
230 void freeCommunicator();
231#endif
232
233private:
234 void createChildren(std::size_t parentId, std::size_t leaftThreshold);
235 void createLeaf(std::size_t nodeId);
236
237#if BITPIT_ENABLE_MPI
238 void buildPartitionBoxes();
239#endif
240
241};
242
243}
244
245#endif
The PatchKernel class provides an interface for defining patches.
PatchSkdTree is the class that implements a spatial kd-tree (skd-tree) a bitpit patch.
std::size_t evalMaxDepth(std::size_t rootId=0) const
const SkdBox & getPartitionBox(int rank) const
std::size_t getLeafMinCellCount() const
std::size_t getLeafMaxCellCount() const
bool areLookupsThreadSafe() const
void setCommunicator(MPI_Comm communicator)
std::size_t getLeafCount() const
SkdNode & _getNode(std::size_t nodeId)
void enableThreadSafeLookups(bool enable)
const SkdNode & getNode(std::size_t nodeId) const
void build(std::size_t leaftThreshold=1, bool squeezeStorage=false)
std::size_t getNodeCount() const
void clear(bool release=false)
PatchSkdTree(const PatchKernel *patch, bool interiorCellsOnly=false)
const MPI_Comm & getCommunicator() const
const PatchKernel & getPatch() const
The PiercedStorageRange allow to iterate using range-based loops over a PiercedStorage.
Metafunction for generating a pierced storage.
The SkdBox class defines a box.
bool boxIntersectsSphere(const std::array< double, 3 > &center, double radius) const
double evalPointMaxSquareDistance(const std::array< double, 3 > &point) const
const std::array< double, 3 > & getBoxMin() const
double evalPointMaxDistance(const std::array< double, 3 > &point) const
double evalPointMinDistance(const std::array< double, 3 > &point) const
bool isEmpty() const
double evalPointMinSquareDistance(const std::array< double, 3 > &point) const
const std::array< double, 3 > & getBoxMax() const
bool boxContainsPoint(const std::array< double, 3 > &point, double offset) const
The SkdPatchInfo class defines a node of the skd-tree.
double evalPointDistance(const std::array< double, 3 > &point, bool interiorCellsOnly) const
std::vector< long > getCells() const
bool isLeaf() const
long getCell(std::size_t n) const
void updatePointClosestCell(const std::array< double, 3 > &point, bool interiorCellsOnly, long *closestId, double *closestDistance) const
void findPointClosestCell(const std::array< double, 3 > &point, bool interiorCellsOnly, long *closestId, double *closestDistance) const
std::array< double, 3 > evalBoxWeightedMean() const
const SkdBox & getBoundingBox() const
void updatePointClosestCells(const std::array< double, 3 > &point, bool interiorCellsOnly, std::vector< long > *closestIds, double *closestDistance) const
static BITPIT_PUBLIC_API const std::size_t NULL_ID
std::size_t getChildId(ChildLocation child) const
bool hasChild(ChildLocation child) const
std::size_t getCellCount() const
The SkdGlobalCellDistance class allows to define a distance between a point and a cell.
static MPI_Datatype getMPIDatatype()
static void executeMPIMinOperation(SkdGlobalCellDistance *in, SkdGlobalCellDistance *inout, int *len, MPI_Datatype *datatype)
void exportData(int *rank, long *id, double *distance) const
The SkdPatchInfo class allows to store patch information needed for the construction and the utilizat...
std::array< double, 3 > evalCachedBoxMean(std::size_t rawId) const
SkdPatchInfo(const PatchKernel *patch, const std::vector< std::size_t > *cellRawIds)
const PatchKernel & getPatch() const
const std::vector< std::size_t > & getCellRawIds() const
const std::array< std::array< double, 3 >, 2 > & getCachedBox(std::size_t rawId) const
std::size_t getCellRawId(std::size_t n) const
--- layout: doxygen_footer ---