TrioCFD 1.9.8
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 cherche les elements ou les points contenus dans l'octree_floor qui contient le point (x,y,z).
28 *
29 * Renvoie le nombre n de ces elements.
30 * Les indices des elements sont dans floor_elements()[index+i] pour 0 <= i < n
31 *
32 */
33template <typename _SIZE_>
35{
36 if (dim_ == 0)
37 return 0; // octree vide
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 construit un octree contenant les points de coordonnees coords.
46 *
47 * Si include_virtual=1, on stocke coords.dimension_tot(0) elements, sinon on en
48 * stocke coords.dimension(0)
49 * Si epsilon = 0, on construit un octree de points de taille nulle (chaque point
50 * se trouve dans un seul octree_floor)
51 * Sinon, on construit un octree d'elements cubiques centres sur les coords, de demie-largeur epsilon.
52 * Un point peut alors se trouver dans plusieurs octree_floor.
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; // octree vide
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 cherche tous les elements ou points ayant potentiellement une intersection non vide avec la boite donnee.
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 cherche tous les elements ou points ayant potentiellement une intersection non vide avec la boite donnee (centre + ou - radius dans chaque direction)
130 *
131 */
132template <typename _SIZE_>
134Octree_Double_32_64<_SIZE_>::search_elements_box(const ArrOfDouble& center, const double radius,
135 ArrOfInt_t& elements) const
136{
137 int dim = center.size_array();
138 double x = center[0];
139 double y = (dim>=2) ? center[1] : 0.;
140 double z = (dim>2) ? center[2] : 0.;
141 int_t i = search_elements_box(x-radius, y-radius, z-radius,
142 x+radius, y+radius, z+radius,
143 elements);
144 return i;
145}
146
147/*! @brief Methode hors classe Cherche parmi les sommets de la liste node_list ceux qui sont a une
148 *
149 * distance inferieure a epsilon du point (x,y,z). node_list contient des indices de
150 * sommets dans le tableau coords. La liste des noeuds verifiant le critere est mise
151 * dans node_list. On renvoie l'indice dans le tableau coords du sommet le plus proche.
152 *
153 */
154template <typename _SIZE_>
156 const DoubleTab_t& coords, ArrOfInt_t& node_list,
157 double epsilon)
158{
159 const int_t n = node_list.size_array();
160 double eps2 = epsilon * epsilon;
161 int_t count = 0;
162 const int dim = coords.dimension_int(1);
163 double dmin = eps2;
164 int_t nearest = -1;
165 for (int_t i = 0; i < n; i++)
166 {
167 const int_t som = node_list[i];
168 double dx = x - coords(som, 0);
169 double dy = (dim >= 2) ? y - coords(som, 1) : 0.;
170 double dz = (dim >= 3) ? z - coords(som, 2) : 0.;
171 double d2 = dx * dx + dy * dy + dz * dz;
172 if (d2 < eps2)
173 {
174 node_list[count] = som;
175 if (d2 < dmin)
176 {
177 dmin = d2;
178 nearest = som;
179 }
180 count++;
181 }
182 }
183 node_list.resize_array(count);
184 return nearest;
185}
186
187/*! @brief Idem que search_nodes_close_to(double x, double y, double z, .
188 *
189 * ..)
190 *
191 */
192template <typename _SIZE_>
194 const DoubleTab_t& coords, ArrOfInt_t& node_list,
195 double epsilon)
196{
197 int dim = point.size_array();
198 double x = point[0];
199 double y = (dim>=2) ? point[1] : 0.;
200 double z = (dim>2) ? point[2] : 0.;
201 int_t i = search_nodes_close_to(x, y, z, coords, node_list, epsilon);
202 return i;
203}
204
205template class Octree_Double_32_64<int>;
206#if INT_is_64_ == 2
208#endif
209
: Un octree permettant de chercher dans l'espace des elements ou des points decrits par des coordonne...
bool integer_position(double x, int direction, int &ix) const
Convertit une coordonnee reelle en coordonnee entiere pour l'octree_int.
DoubleTab_T< _SIZE_ > DoubleTab_t
void compute_origin_factors(const _TAB_TYPE_ &coords, const double epsilon, const int include_virtual)
methode outil pour build_nodes et build_elements (calcul des facteurs de conversion entre reels et en...
static int_t search_nodes_close_to(double x, double y, double z, const DoubleTab_t &coords, ArrOfInt_t &node_list, double epsilon)
Methode hors classe Cherche parmi les sommets de la liste node_list ceux qui sont a une.
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.)
construit un octree contenant les points de coordonnees coords.
Octree_Int_32_64< _SIZE_ > octree_int_
int_t search_elements(double x, double y, double z, int_t &index) const
cherche les elements ou les points contenus dans l'octree_floor qui contient le point (x,...
int_t search_elements_box(double xmin, double ymin, double zmin, double xmax, double ymax, double zmax, ArrOfInt_t &elements) const
cherche tous les elements ou points ayant potentiellement une intersection non vide avec la boite don...
IntTab_T< _SIZE_ > IntTab_t
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
_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