TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Extruder_en3.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 <Connectivite_som_elem.h>
17#include <Static_Int_Lists.h>
18#include <Faces_builder.h>
19#include <Extruder_en3.h>
20#include <Domaine.h>
21#include <Scatter.h>
22#include <Param.h>
23
24Implemente_instanciable_sans_constructeur(Extruder_en3,"Extruder_en3",Interprete_geometrique_base);
25// XD extruder_en3 extruder extruder_en3 BRACE Class to create a 3D tetrahedral/hexahedral mesh (a prism is cut in 3)
26// XD_CONT from a 2D triangular/quadrangular mesh. The names of the boundaries (by default, devant (front) and derriere
27// XD_CONT (back)) may be edited by the keyword nom_cl_devant and nom_cl_derriere. If 'null' is written for nom_cl, then
28// XD_CONT no boundary condition is generated at this place. NL2 Recommendation : to ensure conformity between meshes
29// XD_CONT (in case of fluid/solid coupling) it is recommended to extrude all the domains at the same time.
30
32 NZ_(-1),
33 nom_dvt_("devant"),
34 nom_derriere_("derriere")
35{
36 direction_.resize(3,RESIZE_OPTIONS::NOCOPY_NOINIT);
37}
38
40
42
43/*! @brief Fonction principale de l'interprete Extruder_en3
44 *
45 * Triangule 1 a 1 toutes les domaines du domaine specifie par la directive.
46 * On triangule le domaine grace a la methode:
47 * void Extruder_en3::extruder(Domaine& domaine) const
48 * Extruder_en3 signifie ici transformer en triangle des
49 * elements geometrique d'un domaine.
50 *
51 * @param (Entree& is) un flot d'entree
52 * @return (Entree&) le flot d'entree
53 * @throws l'objet a mailler n'est pas de type Domaine
54 */
56{
57 if (Objet_U::dimension!=2)
58 {
59 Cerr << " We only can extruder_en3 the 2D meshes ! " << finl;
60 exit();
61 }
62
63 int nb_dom=0;
64 Noms noms_dom;
65 Param param(que_suis_je());
66 param.ajouter("domaine",&noms_dom,Param::REQUIRED); // XD attr domaine listchaine domain_name REQ List of the domains
67 param.ajouter("nb_tranches",&NZ_,Param::REQUIRED);
69 param.ajouter("nom_cl_devant",&nom_dvt_); // XD attr nom_cl_devant chaine nom_cl_devant OPT New name of the
70 // XD_CONT first boundary.
71 param.ajouter("nom_cl_derriere",&nom_derriere_); // XD attr nom_cl_derriere chaine nom_cl_derriere OPT New name of
72 // XD_CONT the second boundary.
74 nb_dom=noms_dom.size();
75
76 // creation du tableau de correspondance des indices
77 // pour assurer le decoupage conforme entre domaines
78 //////////////////////////////////////////////////////
79
80 // PQ : 07/09/08 : le decoupage des prismes apres extrusion est base sur une numerotation
81 // globale des indices qui permet d'assurer la conformite des maillages. Ces indices references
82 // dans le tableau nums sont issus du regroupement des domaines en un seul
83 // On procede par concatenation des domaines dans "dom_tot" de maniere a ne pas interferer
84 // avec les domaines d'origines.
85 Domaine dom_tot; // just to get correct renumbering
86 for(int i=0; i<nb_dom; i++)
87 {
88 associer_domaine(noms_dom[nb_dom-1-i]);
89 Domaine& domi=domaine(i);
90 IntVect num;
91 dom_tot.ajouter(domi.coord_sommets(), num);
92
93 /////////////////////////
94 // extrusion des domaines
95 /////////////////////////
97 extruder(domi,num);
99 }
100
101 return is;
102}
103
104/*! @brief Extrusion d'un domaine surfacique
105 *
106 */
107void Extruder_en3::extruder(Domaine& dom, const IntVect& num)
108{
109 if(dom.type_elem()->que_suis_je() == "Triangle")
110 {
111 int oldnbsom = dom.nb_som();
112 IntTab& les_elems=dom.les_elems();
113 int oldsz=les_elems.dimension(0);
114 double dx = direction_[0]/NZ_;
115 double dy = direction_[1]/NZ_;
116 double dz = direction_[2]/NZ_;
117
118 Faces les_faces;
119 {
120 // bloc a factoriser avec Domaine_VF.cpp :
121 Type_Face type_face = dom.type_elem()->type_face(0);
122 les_faces.typer(type_face);
123 les_faces.associer_domaine(dom);
124
125 Static_Int_Lists connectivite_som_elem;
126 const IntTab& elements = dom.les_elems();
127 const int nb_sommets_tot = dom.nb_som_tot();
128
129 construire_connectivite_som_elem(nb_sommets_tot,
130 elements,
131 connectivite_som_elem,
132 1 /* include virtual elements */);
133
134 Faces_builder faces_builder;
135 IntTab dnu; // Tableau dont on aura pas besoin
136 faces_builder.creer_faces_reeles(dom,
137 connectivite_som_elem,
138 les_faces,
139 dnu);
140 }
141
142 int newnbsom = oldnbsom*(NZ_+1);
143 DoubleTab new_soms(newnbsom, 3);
144 DoubleTab& coord_sommets=dom.les_sommets();
146
147 // les sommets du maillage 2D sont translates en premier
148 for (int i=0; i<oldnbsom; i++)
149 {
150 double x = coord_sommets(i,0);
151 double y = coord_sommets(i,1);
152 double z=0.;
153 if (coord_sommets.dimension(1)>2)
154 z=coord_sommets(i,2);
155 for (int k=0; k<=NZ_; k++)
156 {
157 new_soms(k*oldnbsom+i,0)=x;
158 new_soms(k*oldnbsom+i,1)=y;
159 new_soms(k*oldnbsom+i,2)=z;
160
161 x += dx;
162 y += dy;
163 z += dz;
164 }
165 }
166
167 coord_sommets.resize(0);
168 dom.ajouter(new_soms);
169
170 int newnbelem = 3*NZ_*oldsz;
171 IntTab new_elems(newnbelem, 4); // les nouveaux elements
172 for (int i=0; i<oldsz; i++)
173 {
174 int i1=les_elems(i,0);
175 int i2=les_elems(i,1);
176 int i3=les_elems(i,2);
177
178 int ii1 = num[i1];
179 int ii2 = num[i2];
180 int ii3 = num[i3];
181 int i4=i1+oldnbsom;
182 int i5=i2+oldnbsom;
183 int i6=i3+oldnbsom;
184
185 for (int k=0; k<NZ_; k++)
186 {
187 int j=3*k*oldsz+3*i;
188 if (ii1>ii2 && ii1>ii3)
189 {
190 new_elems(j,0) = i1;
191 new_elems(j,1) = i2;
192 new_elems(j,2) = i3;
193 new_elems(j,3) = i4;
194 if (ii3>ii2)
195 {
196 new_elems(j+1,0) = i2;
197 new_elems(j+1,1) = i3;
198 new_elems(j+1,2) = i4;
199 new_elems(j+1,3) = i6;
200
201 new_elems(j+2,0) = i2;
202 new_elems(j+2,1) = i4;
203 new_elems(j+2,2) = i5;
204 new_elems(j+2,3) = i6;
205 }
206 else
207 {
208 new_elems(j+1,0) = i2;
209 new_elems(j+1,1) = i3;
210 new_elems(j+1,2) = i4;
211 new_elems(j+1,3) = i5;
212
213 new_elems(j+2,0) = i3;
214 new_elems(j+2,1) = i4;
215 new_elems(j+2,2) = i5;
216 new_elems(j+2,3) = i6;
217 }
218 }
219
220 if (ii2>ii1 && ii2>ii3)
221 {
222 new_elems(j,0) = i1;
223 new_elems(j,1) = i2;
224 new_elems(j,2) = i3;
225 new_elems(j,3) = i5;
226 if (ii1>ii3)
227 {
228 new_elems(j+1,0) = i1;
229 new_elems(j+1,1) = i3;
230 new_elems(j+1,2) = i4;
231 new_elems(j+1,3) = i5;
232
233 new_elems(j+2,0) = i3;
234 new_elems(j+2,1) = i4;
235 new_elems(j+2,2) = i5;
236 new_elems(j+2,3) = i6;
237 }
238 else
239 {
240 new_elems(j+1,0) = i1;
241 new_elems(j+1,1) = i3;
242 new_elems(j+1,2) = i5;
243 new_elems(j+1,3) = i6;
244
245 new_elems(j+2,0) = i1;
246 new_elems(j+2,1) = i4;
247 new_elems(j+2,2) = i5;
248 new_elems(j+2,3) = i6;
249 }
250 }
251
252 if (ii3>ii1 && ii3>ii2)
253 {
254 new_elems(j,0) = i1;
255 new_elems(j,1) = i2;
256 new_elems(j,2) = i3;
257 new_elems(j,3) = i6;
258 if (ii2>ii1)
259 {
260 new_elems(j+1,0) = i1;
261 new_elems(j+1,1) = i2;
262 new_elems(j+1,2) = i5;
263 new_elems(j+1,3) = i6;
264
265 new_elems(j+2,0) = i1;
266 new_elems(j+2,1) = i4;
267 new_elems(j+2,2) = i5;
268 new_elems(j+2,3) = i6;
269 }
270 else
271 {
272 new_elems(j+1,0) = i1;
273 new_elems(j+1,1) = i2;
274 new_elems(j+1,2) = i4;
275 new_elems(j+1,3) = i6;
276
277 new_elems(j+2,0) = i2;
278 new_elems(j+2,1) = i4;
279 new_elems(j+2,2) = i5;
280 new_elems(j+2,3) = i6;
281 }
282 }
283
285 i1+=oldnbsom;
286 i2+=oldnbsom;
287 i3+=oldnbsom;
288 i4+=oldnbsom;
289 i5+=oldnbsom;
290 i6+=oldnbsom;
291 }
292 }
293 // Reconstruction de l'octree
294 dom.invalide_octree();
295 dom.typer("Tetraedre");
296
297 les_elems.ref(new_elems);
298 construire_bords(dom, les_faces,oldnbsom, oldsz, num);
299 }
300 else
301 Cerr << "TRUST doesn't know how to extrude " << dom.type_elem()->que_suis_je() <<"s"<<finl;
302}
303
304/*! @brief Creation des bords du domaine extrude
305 *
306 */
307void Extruder_en3::construire_bords(Domaine& dom, Faces& les_faces, int oldnbsom, int oldsz, const IntVect& num)
308{
309 IntTab& les_elems = dom.les_elems();
310 // Les bords:
311 for (auto &itr : dom.faces_bord())
312 {
313 Faces& les_faces_du_bord = itr.faces();
314 construire_bord_lateral(les_faces_du_bord, les_faces, oldnbsom, num);
315 }
316
317 // Les raccords:
318 for (auto &itr : dom.faces_raccord())
319 {
320 Faces& les_faces_du_bord = itr->faces();
321 construire_bord_lateral(les_faces_du_bord, les_faces, oldnbsom, num);
322 }
323
324 // Devant
325 if(nom_dvt_=="NULL")
326 {
327 Cerr << "We don't associate any boundary to the front of the domain " << dom.le_nom() << finl;
328 }
329 else
330 {
331 Bord& devant = dom.faces_bord().add(Bord());
332 devant.nommer(nom_dvt_);
333 Faces& les_faces_dvt=devant.faces();
334 les_faces_dvt.typer(Type_Face::triangle_3D);
335
336 IntTab som_dvt(oldsz, 3);
337 les_faces_dvt.voisins().resize(oldsz, 2);
338 les_faces_dvt.voisins()=-1;
339
340 for (int i=0; i<oldsz; i++)
341 {
342 int i0=les_elems(3*i,0);
343 int i1=les_elems(3*i,1);
344 int i2=les_elems(3*i,2);
345
346 som_dvt(i,0) = i0;
347 som_dvt(i,1) = i1;
348 som_dvt(i,2) = i2;
349 }
350 les_faces_dvt.les_sommets().ref(som_dvt);
351 }
352
353 // Derriere
354 if(nom_derriere_=="NULL")
355 {
356 Cerr << "We don't associate any boundary to the back of the domain " << dom.le_nom() << finl;
357 }
358 else
359 {
360 Bord& derriere = dom.faces_bord().add(Bord());
361 derriere.nommer(nom_derriere_);
362 Faces& les_faces_der=derriere.faces();
363 les_faces_der.typer(Type_Face::triangle_3D);
364
365 IntTab som_der(oldsz, 3);
366 les_faces_der.voisins().resize(oldsz, 2);
367 les_faces_der.voisins()=-1;
368
369 for (int i=0; i<oldsz; i++)
370 {
371 int i0=les_elems(3*i,0);
372 int i1=les_elems(3*i,1);
373 int i2=les_elems(3*i,2);
374
375 som_der(i,0) = i0+oldnbsom*NZ_;
376 som_der(i,1) = i1+oldnbsom*NZ_;
377 som_der(i,2) = i2+oldnbsom*NZ_;
378 }
379 les_faces_der.les_sommets().ref(som_der);
380 }
381}
382
383/*! @brief Creation d'un bord lateral
384 *
385 */
386void Extruder_en3::construire_bord_lateral(Faces& les_faces_du_bord, Faces& les_faces, int oldnbsom, const IntVect& num)
387{
388 // oldnbsom = number of nodes of the 2D mesh
389 int nb_faces = les_faces_du_bord.nb_faces();
390 IntTab les_sommets(2*nb_faces*NZ_,3);
391 for (int i=0; i<nb_faces; i++)
392 {
393 int i0=les_faces_du_bord.sommet(i,0);
394 int i1=les_faces_du_bord.sommet(i,1);
395 int ii0= num[i0];
396 int ii1= num[i1];
397 for (int k=0; k<NZ_; k++)
398 {
399 int j=2*nb_faces*k+2*i;
400
401 if (ii0>ii1)
402 {
403 les_sommets(j,0) = i0;
404 les_sommets(j,1) = i1;
405 les_sommets(j,2) = i0+oldnbsom;
406
407 les_sommets(j+1,0) = i1;
408 les_sommets(j+1,1) = i0+oldnbsom;
409 les_sommets(j+1,2) = i1+oldnbsom;
410 }
411 else
412 {
413 les_sommets(j,0) = i0;
414 les_sommets(j,1) = i1;
415 les_sommets(j,2) = i1+oldnbsom;
416
417 les_sommets(j+1,0) = i0;
418 les_sommets(j+1,1) = i0+oldnbsom;
419 les_sommets(j+1,2) = i1+oldnbsom;
420 }
421 i0+=oldnbsom;
422 i1+=oldnbsom;
423 }
424 }
425
426 les_faces_du_bord.typer(Type_Face::triangle_3D);
427 les_faces_du_bord.les_sommets().ref(les_sommets);
428 les_faces_du_bord.voisins().resize(2*nb_faces*NZ_, 2);
429 les_faces_du_bord.voisins()=-1;
430}
431
DoubleTab_t & les_sommets()
Definition Domaine.h:113
Bords_t & faces_bord()
Definition Domaine.h:198
Raccords_t & faces_raccord()
Definition Domaine.h:253
IntTab_t & les_elems()
Definition Domaine.h:129
void invalide_octree()
Definition Domaine.cpp:810
void typer(const Nom &)
Type les elements du domaine avec le nom passe en parametre.
Definition Domaine.h:457
const DoubleTab_t & coord_sommets() const
Definition Domaine.h:112
int_t nb_som_tot() const
Renvoie le nombre total de sommets du domaine i.e. le nombre de sommets reels et virtuels sur le proc...
Definition Domaine.h:123
int_t nb_som() const
Renvoie le nombre de sommets du domaine.
Definition Domaine.h:121
void ajouter(const DoubleTab_t &soms)
Ajoute des noeuds (ou sommets) au domaine (sans verifier les doublons).
Definition Domaine.cpp:909
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
Classe Extruder_en3 Cette classe est un interprete qui sert a lire et executer.
void construire_bord_lateral(Faces &, Faces &, int, const IntVect &)
Creation d'un bord lateral.
void extruder(Domaine &, const IntVect &)
Extrusion d'un domaine surfacique.
void construire_bords(Domaine &, Faces &, int, int, const IntVect &)
Creation des bords du domaine extrude.
Entree & interpreter_(Entree &) override
Fonction principale de l'interprete Extruder_en3.
ArrOfDouble direction_
void typer(const Motcle &)
Type les faces.
Definition Faces.cpp:390
void associer_domaine(const Domaine_t &z)
Definition Faces.h:94
IntTab_t & voisins()
Renvoie le tableau des voisins (des faces).
Definition Faces.h:89
int_t nb_faces() const
Definition Faces.h:66
const IntTab_t & les_sommets() const
Renvoie le tableau des sommets de toutes les faces.
Definition Faces.h:74
int_t sommet(int_t, int) const
Renvoie le numero du j-ieme sommet de la i-ieme face.
Definition Faces.h:130
void creer_faces_reeles(Domaine_t &domaine, const Static_Int_Lists_t &connect_som_elem, Faces_t &les_faces, IntTab_t &elem_faces)
A partir de la description des elements du domaine et des frontieres (bords, raccords,...
void nommer(const Nom &) override
Donne un nom a la frontiere.
Definition Frontiere.cpp:74
const Faces_t & faces() const
Definition Frontiere.h:54
void mettre_a_jour_sous_domaine(Domaine_t &domaine, int_t &elem, int_t num_premier_elem, int_t nb_elem) const
Un tableau de chaine de caracteres (VECT(Nom)).
Definition Noms.h:26
friend class Entree
Definition Objet_U.h:76
static int dimension
Definition Objet_U.h:99
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
Helper class to factorize the readOn method of Objet_U classes.
Definition Param.h:112
void ajouter_arr_size_predefinie(const char *keyword, const ArrOfInt *value, Param::Nature nat=Param::OPTIONAL)
Register an ArrOfInt whose size has already been fixed.
Definition Param.cpp:411
void ajouter(const char *keyword, const int *value, Param::Nature nat=Param::OPTIONAL)
Register an integer parameter.
Definition Param.cpp:364
@ REQUIRED
Definition Param.h:115
int lire_avec_accolades_depuis(Entree &is)
Parse the parameter block { ... } from is.
Definition Param.cpp:32
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
static void init_sequential_domain(Domaine_32_64< _SIZE_ > &dom)
Create parallel descriptors for the vertex and element arrays of the domain (necessary because Scatte...
Definition Scatter.cpp:2742
static void uninit_sequential_domain(Domaine_32_64< _SIZE_ > &dom)
methode utilisee par les interpretes qui modifient le domaine (sequentiel), detruit les descripteurs ...
Definition Scatter.cpp:2757
Classe de base des flux de sortie.
Definition Sortie.h:52
virtual void ref(const TRUSTTab &)
Definition TRUSTTab.tpp:308
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133