TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Polygone.cpp
1/****************************************************************************
2* Copyright (c) 2025, 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 <TRUSTList.h>
17#include <Polygone.h>
18#include <Triangle.h>
19#include <Domaine.h>
20#include <Polygon_geom_tools.h>
21#include <algorithm>
22
23Implemente_instanciable_sans_constructeur_32_64(Polygone_32_64,"Polygone",Poly_geom_base_32_64<_T_>);
24
25template <typename _SIZE_>
34
35template <typename _SIZE_>
37{
38 s<< FacesIndex_ <<finl;
39 s<< PolygonIndex_ <<finl;
40 s<< nb_som_elem_max_ <<finl;
41 s<< nb_face_elem_max_ <<finl;
42 WARN;
43 return s;
44}
45
46template <typename _SIZE_>
48{
49 s>>FacesIndex_;
50 s>>PolygonIndex_;
51 s>>nb_som_elem_max_;
52 s>>nb_face_elem_max_;
53 return s;
54}
55
56
57template <typename _SIZE_>
59{
60 const IntTab_t& les_elems = mon_dom->les_elems();
61 int_t nb_elem = les_elems.dimension_tot(0);
62 ArrOfInt_t PolygonIndex_OK(nb_elem+1);
63 PolygonIndex_OK[0]=0;
64 for (int_t ele=0; ele<nb_elem; ele++)
65 {
66 int nbf=get_nb_som_elem_max();
67 while (les_elems(ele,nbf-1)<0)
68 nbf--;
69 PolygonIndex_OK[ele+1]= PolygonIndex_OK[ele]+nbf;
70 }
71 ArrOfInt_t FacesIndex_OK(PolygonIndex_OK[nb_elem]);
72 int_t f=0;
73 for (int_t ele=0; ele<nb_elem; ele++)
74 for (int ss=0; ss<(int)(PolygonIndex_OK[ele+1]-PolygonIndex_OK[ele]); ss++) // yes, difference of long giving an int, hence the cast -> face size
75 FacesIndex_OK[f++]= les_elems(ele,ss);
76
77 assert(f==PolygonIndex_OK[nb_elem]);
78
79 FacesIndex_=FacesIndex_OK;
80 PolygonIndex_=PolygonIndex_OK;
81}
82
83/* Build a reduced version of the polytope connectivity when splitting domains in DomainCutter - this always produce
84 * a 32b object:
85 */
86template <typename _SIZE_>
87void Polygone_32_64<_SIZE_>::build_reduced(OWN_PTR(Elem_geom_base_32_64<int>)& type_elem, const ArrOfInt_t& elems_sous_part) const
88{
89 type_elem.typer("Polygone");
90 Polygone_32_64<int>& reduced = ref_cast(Polygone_32_64<int>, type_elem.valeur());
93
94 const IntTab_t& les_elems = mon_dom->les_elems();
95 ArrOfInt& Pi = reduced.PolygonIndex_, &Fi = reduced.FacesIndex_;
96 Fi.resize(0);
97
98 for (int_t i = 0; i < elems_sous_part.size_array(); i++)
99 {
100 int_t e = elems_sous_part[i];
101 for (int_t f = PolygonIndex_[e]; f < PolygonIndex_[e + 1]; f++)
102 {
103 int nf = static_cast<int>(f - PolygonIndex_[e]); // num of faces always an int
104 // The below is not necessary (contrarly to what's done for polyedrons) since get_tab_faces_sommets_locaux() below only uses Pi
105// Fi.append_array(les_elems(e, nf));
106 Fi.append_array(les_elems(e, nf) > 0 ? 1 : -1);
107 }
108 Pi.append_array(Fi.size_array()); // this is what will be used by get_tab_faces_sommets_locaux()
109 }
110}
111
112
113template <typename _SIZE_>
118
119
120template <typename _SIZE_>
122{
123 return PolygonIndex_[mon_dom->nb_elem()];
124}
125
126template <typename _SIZE_>
128{
129 if (nb_som_elem_max_>-1)
130 return nb_som_elem_max_ ;
131 else
132 return mon_dom->les_elems().dimension_int(1);
133}
134
135/*! @brief Returns the LML name of a polygon = "POLYEDRE_" + 2*nb_som_max (or "POLYGONE_" + nb_som_max in 3D).
136 *
137 * @return LML name string for this polygon type.
138 */
139template <typename _SIZE_>
141{
142 static Nom nom;
143 nom="POLYEDRE_";
145 if (dimension==3) nom="POLYGONE_";
146 if (dimension==3) n=Nom(get_nb_som_elem_max());
147 nom+=n;
148 return nom;
149}
150
151
152// ToDo move to Triangle
153template <typename _SIZE_>
154int contient_triangle(const ArrOfDouble& pos, _SIZE_ som0, _SIZE_ som1, _SIZE_ som2, const TRUSTTab<double, _SIZE_>& coord)
155{
156 double prod,p0,p1,p2;
157
158 // Determine the orientation (counter-clockwise or clockwise) for the vertex numbering:
159 // Compute prod = 01 cross 02 along z
160 // prod > 0 : counter-clockwise
161 // prod < 0 : clockwise
162 prod = (coord(som1,0)-coord(som0,0))*(coord(som2,1)-coord(som0,1))
163 - (coord(som1,1)-coord(som0,1))*(coord(som2,0)-coord(som0,0));
164 double signe;
165 if (prod >= 0)
166 signe = 1;
167 else
168 signe = -1;
169 // Compute p0 = 0M cross 1M along z
170 p0 = (pos[0]-coord(som0,0))*(pos[1]-coord(som1,1))
171 - (pos[1]-coord(som0,1))*(pos[0]-coord(som1,0));
172 p0 *= signe;
173 // Compute p1 = 1M cross 2M along z
174 p1 = (pos[0]-coord(som1,0))*(pos[1]-coord(som2,1))
175 - (pos[1]-coord(som1,1))*(pos[0]-coord(som2,0));
176 p1 *= signe;
177 // Compute p2 = 2M cross 0M along z
178 p2 = (pos[0]-coord(som2,0))*(pos[1]-coord(som0,1))
179 - (pos[1]-coord(som2,1))*(pos[0]-coord(som0,0));
180 p2 *= signe;
181 double epsilon=std::fabs(prod)*Objet_U::precision_geom;
182 if ((p0>-epsilon) && (p1>-epsilon) && (p2>-epsilon))
183 return 1;
184 else
185 return 0;
186}
187
188/*! @brief Returns 1 if element "num_poly" of the domain associated with this geometric element contains the point with coordinates "pos_r".
189 *
190 * Returns 0 otherwise. Implemented by decomposing the polygon into triangles.
191 *
192 * @param pos_r Coordinates of the point to locate.
193 * @param num_poly Index of the domain element in which to search for the point.
194 * @return 1 if the point belongs to element "num_poly", 0 otherwise.
195 */
196template <typename _SIZE_>
197int Polygone_32_64<_SIZE_>::contient(const ArrOfDouble& pos_r, int_t num_poly ) const
198{
199 const Domaine_t& domaine=mon_dom.valeur();
200 const IntTab_t& elem=domaine.les_elems();
201 const DoubleTab_t& coord=domaine.coord_sommets();
202 //DoubleTab pos(3,dimension);
203 // decompose the polygon into triangles all sharing vertex 0.
204
205 int_t s0=elem(num_poly,0);
206 for (int s=1; s<nb_som_elem_max_-1 ; s++)
207 {
208 int_t s1=elem(num_poly,s);
209 int_t s2=elem(num_poly,s+1);
210 if (s2<0)
211 break;
212
213 if (contient_triangle(pos_r,s0,s1,s2,coord))
214 return 1;
215 }
216
217 return 0;
218}
219
220
221/*! @brief Not yet implemented — always returns 0. Returns 1 if the vertices specified by "pos" are those of element "element" in the associated domain.
222 *
223 * @param pos Vertex indices to compare.
224 * @param element Index of the domain element whose vertices are to be compared.
225 * @return 1 if the vertices match, 0 otherwise.
226 */
227template <typename _SIZE_>
229{
230 BLOQUE;
231 return 0;
232}
233
234
235/*! @brief Computes the volumes (areas) of the elements of the associated domain.
236 *
237 * @param volumes Vector to fill with the volumes of domain elements.
238 */
239template <typename _SIZE_>
241{
242 const Domaine_t& domaine = mon_dom.valeur();
243 const IntTab_t& elem = domaine.les_elems();
244 const DoubleTab_t& coord = domaine.coord_sommets();
245 int_t size = domaine.nb_elem();
246
247 assert(volumes.size_totale()==domaine.nb_elem_tot());
248
249 for (int_t num_poly = 0; num_poly < size; num_poly++)
250 {
251 // Determine the actual number of vertices for this polygon (terminated by -1)
252 int nbsom = 0;
253 const int nbsom_max = get_nb_som_elem_max();
254 while (nbsom < nbsom_max && elem(num_poly, nbsom) >= 0) nbsom++;
255 if (nbsom < 3)
256 {
257 volumes(num_poly) = 0.;
258 continue;
259 }
260
261 const auto index_of = [&](int i) -> int_t { return elem(num_poly, i); };
262 const Polygon_geom_data geom = compute_polygon_geom(coord, dimension, nbsom, index_of, Objet_U::bidim_axi);
263
265 volumes(num_poly) = geom.area_;
266 else
267 volumes(num_poly) = 2.0 * M_PI * std::fabs(geom.moment_r_);
268 }
269
270 volumes.echange_espace_virtuel();
271 return;
272}
273
274/*! @brief Fills faces_som_local(i,j) giving for 0 <= i < nb_faces() and 0 <= j < nb_som_face(i) the local vertex index on the element.
275 *
276 * We have 0 <= faces_sommets_locaux(i,j) < nb_som().
277 * If faces do not all have the same number of vertices, the number of columns
278 * equals the maximum, and unused entries are set to -1.
279 * Returns 1 if all faces have the same vertex count, 0 otherwise.
280 *
281 * @param faces_som_local Table to fill with local face-vertex indices.
282 * @return 1 if all faces have the same vertex count, 0 otherwise.
283 */
284template <typename _SIZE_>
286{
287 return 0;
288}
289
290template <typename _SIZE_>
292{
293 faces_som_local.resize(nb_face_elem_max_,nb_som_face());
294 faces_som_local=-1;
295
296 // look for the faces of the element
297 int nb_face = static_cast<int>(PolygonIndex_[ele+1]-PolygonIndex_[ele]); // always within int
298
299 // [ABN] Duh?! always assume consecutive connectivity??
300 for (int fl=0; fl<nb_face-1; fl++)
301 {
302 faces_som_local(fl,0)=fl;
303 faces_som_local(fl,1)=fl+1;
304 }
305
306 // Last face:
307 int fl=nb_face-1;
308 faces_som_local(fl,0)=fl;
309 faces_som_local(fl,1)=0;
310
311 return 1;
312}
313
314// From the indirection arrays FacesIndex and PolygonIndex,
315// compute les_elems, nb_som_face_max_, nb_face_elem_max_, nb_som_elem_max_.
316template <typename _SIZE_>
318{
320 // determine the maximum number of vertices per element
323 int_t nelem=PolygonIndex.size_array()-1;
324 for (int_t ele=0; ele<nelem; ele++)
325 {
326 prov.vide();
327 int_t nbf=PolygonIndex[ele+1]-PolygonIndex[ele];
328 if (nbf>nb_face_elem_max_) nb_face_elem_max_=(int)nbf;
329 for (int_t f=PolygonIndex[ele]; f<PolygonIndex[ele+1]; f++)
330 prov.add_if_not(FacesIndex[f]);
331 int nbsom=prov.size();
332 if (nbsom>nb_som_elem_max_) nb_som_elem_max_=nbsom;
333 }
336 Cerr<<" Polygon information nb_som_elem_max "<< nb_som_elem_max_<<" nb_face_elem_max "<<nb_face_elem_max_<<finl;
337 les_elems.resize(nelem,nb_som_elem_max_);
338 les_elems=-1;
339 // second pass to determine les_elems
340 for (int_t ele=0; ele<nelem; ele++)
341 {
342 prov.vide();
343 for (int_t f=PolygonIndex[ele]; f<PolygonIndex[ele+1]; f++)
344 prov.add_if_not(FacesIndex[f]);
345 int nbsom=prov.size();
346 for (int s=0; s<nbsom; s++)
347 les_elems(ele,s)=prov[s];
348 }
349 FacesIndex_=FacesIndex;
350 PolygonIndex_=PolygonIndex;
352}
353
354
355template <typename _SIZE_>
357{
358 const Domaine_t& domaine=mon_dom.valeur();
359 const IntTab_t& elem=domaine.les_elems();
360 const DoubleTab_t& coord=domaine.coord_sommets();
361 int_t nb_elem;
362 if(xp.dimension(0)==0)
363 {
364 nb_elem = mon_dom->nb_elem_tot();
365 xp.resize(nb_elem,dimension);
366 }
367 else
368 nb_elem=xp.dimension(0);
369
370 xp=0;
371 DoubleTab pos(3,dimension);
372 ArrOfDouble xpl(dimension);
373 for (int_t num_poly=0; num_poly<nb_elem; num_poly++)
374 {
375 double aire=0;
376 xpl=0;
377 int_t s0=elem(num_poly,0);
378 for (int d=0; d<dimension; d++)
379 pos(0,d)=coord(s0,d);
380 for (int s=1; s<get_nb_som_elem_max()-1 ; s++)
381 {
382 int_t s1=elem(num_poly,s);
383 int_t s2=elem(num_poly,s+1);
384 if (s2<0)
385 break;
386 for (int d=0; d<dimension; d++)
387 {
388 pos(1,d)=coord(s1,d);
389 pos(2,d)=coord(s2,d);
390 }
391 double airel = aire_triangle(pos);
392 for (int d=0; d<dimension; d++)
393 xpl[d]+=airel*(pos(0,d)+pos(1,d)+pos(2,d));
394 aire+=airel;
395 }
396 aire*=3.;
397 for (int d=0; d<dimension; d++)
398 xp(num_poly,d)=xpl[d]/(aire);
399 }
400}
401
402template <typename _SIZE_>
403void Polygone_32_64<_SIZE_>::calculer_un_centre_gravite(const int_t num_poly,DoubleVect& xp) const
404{
405 const Domaine_t& domaine=mon_dom.valeur();
406 const IntTab_t& elem=domaine.les_elems();
407 const DoubleTab_t& coord=domaine.coord_sommets();
408 xp.resize(dimension);
409
410 xp=0;
411 DoubleTab pos(3,dimension);
412 ArrOfDouble xpl(dimension);
413 {
414 double aire=0;
415 xpl=0;
416 int_t s0=elem(num_poly,0);
417 for (int d=0; d<dimension; d++)
418 pos(0,d)=coord(s0,d);
419 for (int s=1; s<nb_som_elem_max_-1 ; s++)
420 {
421 int_t s1=elem(num_poly,s);
422 int_t s2=elem(num_poly,s+1);
423 if (s2<0)
424 break;
425 for (int d=0; d<dimension; d++)
426 {
427 pos(1,d)=coord(s1,d);
428 pos(2,d)=coord(s2,d);
429 }
430 double airel = aire_triangle(pos);
431 for (int d=0; d<dimension; d++)
432 xpl[d]+=airel*(pos(0,d)+pos(1,d)+pos(2,d));
433 aire+=airel;
434 }
435 aire*=3.;
436 for (int d=0; d<dimension; d++)
437 xp(d)=xpl[d]/(aire);
438 }
439}
440
441
442
443template class Polygone_32_64<int>;
444#if INT_is_64_ == 2
445template class Polygone_32_64<trustIdType>;
446#endif
Class Elem_geom_base This class is the base class for the definition of elements.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
Definition Objet_U.cpp:289
static double precision_geom
Definition Objet_U.h:81
static int bidim_axi
Definition Objet_U.h:97
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
Base class for polyedrons and polygons. Connectivity is stored in descending mode:
Class Polygone represents the geometric element Polygone.
Definition Polygone.h:29
int get_tab_faces_sommets_locaux(IntTab &faces_som_local) const override
Fills faces_som_local(i,j) giving for 0 <= i < nb_faces() and 0 <= j < nb_som_face(i) the local verte...
Definition Polygone.cpp:285
_SIZE_ get_somme_nb_faces_elem() const override
Definition Polygone.cpp:121
void build_reduced(OWN_PTR(Elem_geom_base_32_64< int >)&type_elem, const ArrOfInt_t &elems_sous_part) const override
Definition Polygone.cpp:87
friend class Polygone_32_64
Definition Polygone.h:35
Domaine_32_64< _SIZE_ > Domaine_t
Definition Polygone.h:43
void calculer_un_centre_gravite(const int_t elem, DoubleVect &xp) const override
Definition Polygone.cpp:403
static int dimension
Definition Objet_U.h:94
ArrOfInt_T< _SIZE_ > ArrOfInt_t
Definition Polygone.h:38
void calculer_centres_gravite(DoubleTab_t &xp) const override
Compute all centers of mass of all elements in the domain.
Definition Polygone.cpp:356
void calculer_volumes(DoubleVect_t &vols) const override
Computes the volumes (areas) of the elements of the associated domain.
Definition Polygone.cpp:240
int get_nb_som_elem_max() const
Definition Polygone.cpp:127
int nb_som_face(int=0) const override
Returns the maximum number of vertices of the faces of the specified type.
Definition Polygone.h:144
SmallArrOfTID_T< _SIZE_ > SmallArrOfTID_t
Definition Polygone.h:40
ArrOfInt_t PolygonIndex_
Definition Polygone.h:87
DoubleTab_T< _SIZE_ > DoubleTab_t
Definition Polygone.h:42
void affecte_connectivite_numero_global(const ArrOfInt_t &FacesIndex, const ArrOfInt_t &PolygonIndex, IntTab_t &les_elems)
Definition Polygone.cpp:317
_SIZE_ int_t
Definition Polygone.h:37
void compute_virtual_index() override
Definition Polygone.cpp:114
IntTab_T< _SIZE_ > IntTab_t
Definition Polygone.h:39
int contient(const ArrOfDouble &pos, int_t elem) const override
Returns 1 if element "num_poly" of the domain associated with this geometric element contains the poi...
Definition Polygone.cpp:197
DoubleVect_T< _SIZE_ > DoubleVect_t
Definition Polygone.h:41
const Nom & nom_lml() const override
Returns the LML name of a polygon = "POLYEDRE_" + 2*nb_som_max (or "POLYGONE_" + nb_som_max in 3D).
Definition Polygone.cpp:140
void rebuild_index()
Definition Polygone.cpp:58
static double mp_max(double)
Definition Process.cpp:379
Base class for output streams.
Definition Sortie.h:52
void append_array(_TYPE_ valeur)
_SIZE_ size_array() const
void resize(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTArray.h:156
: Class used to represent a list of int/double precision reals.
Definition TRUSTList.h:33
TRUSTList & add_if_not(_TYPE_)
Ajout d'un element a la liste ssi il n'existe pas deja.
void vide()
Vide la liste.
int size() const
Definition TRUSTList.h:68
N-dimensional array for N <= 4.
Definition TRUSTTab.h:31
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
_SIZE_ size_totale() const
Definition TRUSTVect.tpp:61
void resize(_SIZE_, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTVect.tpp:91
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")