TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Octree_Double.cpp
1/****************************************************************************
2* Copyright (c) 2024, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#include <Octree_Double.h>
17
18template <typename _SIZE_>
20{
21 dim_ = 0;
22 octree_int_.reset();
23 origin_.reset();
24 factor_.reset();
25}
26
27/*! @brief searches for the elements or points contained in the octree_floor that contains the point (x,y,z).
28 *
29 * Returns the number n of these elements.
30 * The indices of the elements are in floor_elements()[index+i] for 0 <= i < n
31 *
32 */
33template <typename _SIZE_>
35{
36 if (dim_ == 0)
37 return 0; // empty octree
38 int ix = 0, iy = 0, iz = 0;
39 int ok = integer_position(x, 0, ix)
40 && integer_position(y, 1, iy)
41 && integer_position(z, 2, iz);
42 return ok ? octree_int_.search_elements(ix, iy, iz, index) : 0;
43}
44
45/*! @brief builds an octree containing the points with coordinates coords.
46 *
47 * If include_virtual=1, stores coords.dimension_tot(0) elements, otherwise stores
48 * coords.dimension(0) elements.
49 * If epsilon = 0, builds an octree of zero-size points (each point
50 * is in a single octree_floor).
51 * Otherwise, builds an octree of cubic elements centered on the coords, with half-width epsilon.
52 * A point can then be found in several octree_floors.
53 *
54 */
55template <typename _SIZE_>
56void Octree_Double_32_64<_SIZE_>::build_nodes(const DoubleTab_t& coords, const bool include_virtual, const double epsilon)
57{
58 octree_int_.reset();
59 compute_origin_factors(coords, epsilon, include_virtual);
60 const int_t nb_som = include_virtual ? coords.dimension_tot(0) : coords.dimension(0);
61 if (nb_som == 0)
62 return; // empty octree
63 const int dim = coords.dimension_int(1);
64 if (epsilon < 0.)
65 {
66 Cerr << "Internal error in Octree_Double_32_64<_SIZE_>::build_nodes: negative epsilon" << finl;
68 }
69 bool have_epsilon = (epsilon != 0.);
70 IntTab_t elements_boxes;
71 elements_boxes.resize(nb_som, have_epsilon ? (dim*2) : dim, RESIZE_OPTIONS::NOCOPY_NOINIT);
72
73 for (int_t i = 0; i < nb_som; i++)
74 for (int j = 0; j < dim; j++)
75 {
76 int pos1 = 0;
77 const double x0 = coords(i, j);
78 double x = x0 - epsilon;
79 if (!integer_position(x, j, pos1))
80 {
81 Cerr << "Fatal error in octree : integer position outside octree" << finl;
83 }
84 elements_boxes(i, j) = pos1;
85 if (have_epsilon)
86 {
87 pos1 = 0;
88 double xbis = x0 + epsilon;
89 if (!integer_position(xbis, j, pos1))
90 {
91 Cerr << "Fatal error in octree : integer position outside octree" << finl;
93 }
94 elements_boxes(i, dim+j) = pos1;
95 }
96 }
97 octree_int_.build(dim, elements_boxes);
98}
99
100/*! @brief searches for all elements or points potentially having a non-empty intersection with the given box.
101 *
102 */
103template <typename _SIZE_>
105 double xmax, double ymax, double zmax,
106 ArrOfInt_t& elements) const
107{
108 const int dim = dim_;
109 if (dim == 0)
110 {
111 elements.resize_array(0);
112 return 0;
113 }
114 int x0 = 0, x1 = 0, y0 = 0, y1 = 0, z0 = 0, z1 = 0;
115 int ok = integer_position_clip(xmin, xmax, x0, x1, 0);
116 if ((ok) && (dim >= 1))
117 {
118 ok = integer_position_clip(ymin, ymax, y0, y1, 1);
119 if ((ok) && (dim >= 2))
120 ok = integer_position_clip(zmin, zmax, z0, z1, 2);
121 }
122 if (ok)
123 octree_int_.search_elements_box(x0, y0, z0, x1, y1, z1, elements);
124 else
125 elements.resize_array(0);
126 return elements.size_array();
127}
128
129/*! @brief Searches for all elements or points potentially having a non-empty intersection with the given box (center +/- radius in each direction).
130 *
131 * @param center Center of the box.
132 * @param radius Half-width of the box in each direction.
133 * @param elements Array filled with the indices of the matching elements.
134 * @return Number of elements found.
135 */
136template <typename _SIZE_>
138Octree_Double_32_64<_SIZE_>::search_elements_box(const ArrOfDouble& center, const double radius,
139 ArrOfInt_t& elements) const
140{
141 int dim = center.size_array();
142 double x = center[0];
143 double y = (dim>=2) ? center[1] : 0.;
144 double z = (dim>2) ? center[2] : 0.;
145 int_t i = search_elements_box(x-radius, y-radius, z-radius,
146 x+radius, y+radius, z+radius,
147 elements);
148 return i;
149}
150
151/*! @brief Non-member method. Searches among the vertices in node_list for those within a distance
152 *
153 * less than epsilon from the point (x,y,z). node_list contains indices of
154 * vertices in the coords array. The list of nodes satisfying the criterion is placed
155 * in node_list. Returns the index in the coords array of the nearest vertex.
156 *
157 */
158template <typename _SIZE_>
160 const DoubleTab_t& coords, ArrOfInt_t& node_list,
161 double epsilon)
162{
163 const int_t n = node_list.size_array();
164 double eps2 = epsilon * epsilon;
165 int_t count = 0;
166 const int dim = coords.dimension_int(1);
167 double dmin = eps2;
168 int_t nearest = -1;
169 for (int_t i = 0; i < n; i++)
170 {
171 const int_t som = node_list[i];
172 double dx = x - coords(som, 0);
173 double dy = (dim >= 2) ? y - coords(som, 1) : 0.;
174 double dz = (dim >= 3) ? z - coords(som, 2) : 0.;
175 double d2 = dx * dx + dy * dy + dz * dz;
176 if (d2 < eps2)
177 {
178 node_list[count] = som;
179 if (d2 < dmin)
180 {
181 dmin = d2;
182 nearest = som;
183 }
184 count++;
185 }
186 }
187 node_list.resize_array(count);
188 return nearest;
189}
190
191/*! @brief Same as search_nodes_close_to(double x, double y, double z, ...)
192 *
193 */
194template <typename _SIZE_>
196 const DoubleTab_t& coords, ArrOfInt_t& node_list,
197 double epsilon)
198{
199 int dim = point.size_array();
200 double x = point[0];
201 double y = (dim>=2) ? point[1] : 0.;
202 double z = (dim>2) ? point[2] : 0.;
203 int_t i = search_nodes_close_to(x, y, z, coords, node_list, epsilon);
204 return i;
205}
206
207template class Octree_Double_32_64<int>;
208#if INT_is_64_ == 2
210#endif
211
: An octree allowing to search in space for elements or points described by real-valued coordinates.
bool integer_position(double x, int direction, int &ix) const
Converts a real coordinate to an integer coordinate for the octree_int.
DoubleTab_T< _SIZE_ > DoubleTab_t
void compute_origin_factors(const _TAB_TYPE_ &coords, const double epsilon, const int include_virtual)
Helper method for build_nodes and build_elements: computes the conversion factors from real to intege...
static int_t search_nodes_close_to(double x, double y, double z, const DoubleTab_t &coords, ArrOfInt_t &node_list, double epsilon)
Non-member method. Searches among the vertices in node_list for those within a distance.
ArrOfInt_T< _SIZE_ > ArrOfInt_t
bool integer_position_clip(double xmin, double xmax, int &x0, int &x1, int direction) const
void build_nodes(const DoubleTab_t &coords, const bool include_virtual, const double epsilon=0.)
builds an octree containing the points with coordinates coords.
Octree_Int_32_64< _SIZE_ > octree_int_
int_t search_elements(double x, double y, double z, int_t &index) const
searches for the elements or points contained in the octree_floor that contains the point (x,...
int_t search_elements_box(double xmin, double ymin, double zmin, double xmax, double ymax, double zmax, ArrOfInt_t &elements) const
searches for all elements or points potentially having a non-empty intersection with the given box.
IntTab_T< _SIZE_ > IntTab_t
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
_SIZE_ size_array() const
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
int dimension_int(int d) const
Definition TRUSTTab.tpp:152
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
_SIZE_ dimension_tot(int) const override
Definition TRUSTTab.tpp:160
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133