TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Extruder_en20.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 <Extruder_en20.h>
19#include <Faces_builder.h>
20#include <Domaine.h>
21#include <Scatter.h>
22#include <Param.h>
23
24Implemente_instanciable_sans_constructeur(Extruder_en20, "Extruder_en20", Interprete_geometrique_base);
25// XD extruder_en20 interprete extruder_en20 BRACE It does the same task as Extruder except that a prism is cut into 20
26// XD_CONT tetraedra instead of 3. The name of the boundaries will be devant (front) and derriere (back). But you can
27// XD_CONT change these names with the keyword RegroupeBord.
28
29Extruder_en20::Extruder_en20() { direction.resize(3, RESIZE_OPTIONS::NOCOPY_NOINIT); }
30
32
34
35/*! @brief Main function of the Extruder_en20 interpreter. Extrudes the domain specified by the directive.
36 *
37 * Extrusion is performed by calling:
38 * void Extruder_en20::extruder(Domaine& domaine) const
39 * Here, extrusion means transforming the geometric elements of a domain into triangles.
40 *
41 * @param is An input stream.
42 * @return The input stream.
43 * @throws Error if the object to mesh is not of type Domaine.
44 */
46{
47 Nom nom_dom;
48 Param param(que_suis_je());
49 param.ajouter("domaine",&nom_dom,Param::REQUIRED); // XD attr domaine ref_domaine domain_name REQ Name of the domain.
50 param.ajouter("nb_tranches",&NZ,Param::REQUIRED); // XD attr nb_tranches entier nb_tranches REQ Number of elements
51 // XD_CONT in the extrusion direction.
52 param.ajouter_arr_size_predefinie("direction",&direction,Param::REQUIRED); // XD attr direction troisf direction OPT
53 // XD_CONT 0 Direction of the extrude operation.
55 associer_domaine(nom_dom);
59 return is;
60}
61
62/*! @brief Extrudes all elements of a domain: transforms the geometric elements of the domain.
63 *
64 * Currently only Rectangles can be extruded (they are cut into 4 sub-elements).
65 *
66 * @param dom The domain whose elements are to be extruded.
67 */
68void Extruder_en20::extruder(Domaine& dom)
69{
70 if (dom.type_elem()->que_suis_je() == "Rectangle" || dom.type_elem()->que_suis_je() == "Quadrangle" )
71 {
72 Cerr << " The extrusion of quadrangle is made by Extruder and not by Extruder_en20 " << finl;
73 exit();
74 }
75 else if( dom.type_elem()->que_suis_je() == "Triangle")
76 {
77 int oldnbsom = dom.nb_som();
78 IntTab& les_elems=dom.les_elems();
79 int oldsz=les_elems.dimension(0);
80 double dx = direction[0]/NZ;
81 double dy = direction[1]/NZ;
82 double dz = direction[2]/NZ;
83
84 Faces les_faces;
85 //domaine.creer_faces(les_faces);
86 {
87 // block to be factored out with Domaine_VF.cpp:
88 Type_Face type_face = dom.type_elem()->type_face(0);
89 les_faces.typer(type_face);
90 les_faces.associer_domaine(dom);
91
92 Static_Int_Lists connectivite_som_elem;
93 const int nb_sommets_tot = dom.nb_som_tot();
94 const IntTab& elements = dom.les_elems();
95
96 construire_connectivite_som_elem(nb_sommets_tot,
97 elements,
98 connectivite_som_elem,
99 1 /* include virtual elements */);
100
101 Faces_builder faces_builder;
102 IntTab elem_faces; // Array that will not be needed
103 faces_builder.creer_faces_reeles(dom,
104 connectivite_som_elem,
105 les_faces,
106 elem_faces);
107 }
108 const int nbfaces2D = les_faces.nb_faces();
109
110
111 int newnbsom = oldnbsom*(NZ+1)+NZ*oldsz+nbfaces2D*NZ+oldnbsom*NZ;
112 DoubleTab new_soms(newnbsom, 3);
113 DoubleTab& coord_sommets=dom.les_sommets();
115
116
117 // vertices of the 2D mesh are translated first
118 for (int i=0; i<oldnbsom; i++)
119 {
120 double x = coord_sommets(i,0);
121 double y = coord_sommets(i,1);
122 double z=0;
123 if (coord_sommets.dimension(1)>2)
124 z=coord_sommets(i,2);
125 for (int k=0; k<=NZ; k++)
126 {
127 new_soms(k*oldnbsom+i,0)=x;
128 new_soms(k*oldnbsom+i,1)=y;
129 new_soms(k*oldnbsom+i,2)=z;
130
131 x += dx;
132 y += dy;
133 z += dz;
134 }
135 }
136
137
138 // compute centroids of 2D elements then translate these points
139 for (int i=0; i<oldsz; i++)
140 {
141 int i0=les_elems(i,0);
142 int i1=les_elems(i,1);
143 int i2=les_elems(i,2);
144
145 double xg = 1./3.*(coord_sommets(i0,0)+coord_sommets(i1,0)+coord_sommets(i2,0))+0.5*dx;
146 double yg = 1./3.*(coord_sommets(i0,1)+coord_sommets(i1,1)+coord_sommets(i2,1))+0.5*dy;
147 double z = 0.5*dz;
148 if (coord_sommets.dimension(1)>2)
149 z = 1./3.*(coord_sommets(i0,2)+coord_sommets(i1,2)+coord_sommets(i2,2))+0.5*dz;
150 for (int k=0; k<NZ; k++)
151 {
152
153 new_soms(oldnbsom*(NZ+1)+k*oldsz+i,0)=xg;
154 new_soms(oldnbsom*(NZ+1)+k*oldsz+i,1)=yg;
155 new_soms(oldnbsom*(NZ+1)+k*oldsz+i,2)=z;
156
157 xg += dx;
158 yg += dy;
159 z += dz;
160 }
161 }
162
163
164 // compute face centers of the 2D mesh then translate these points
165 for (int i=0; i<nbfaces2D; i++)
166 {
167 int i0=les_faces.sommet(i,0);
168 int i1=les_faces.sommet(i,1);
169
170 double x01 = 0.5*(coord_sommets(i0,0)+coord_sommets(i1,0))+0.5*dx;
171 double y01 = 0.5*(coord_sommets(i0,1)+coord_sommets(i1,1))+0.5*dy;
172 double z = 0.5*dz;
173 if (coord_sommets.dimension(1)>2)
174 z = 0.5*(coord_sommets(i0,2)+coord_sommets(i1,2))+0.5*dz;
175 for (int k=0; k<NZ; k++)
176 {
177 new_soms(oldnbsom*(NZ+1)+NZ*oldsz+k*nbfaces2D+i,0)=x01;
178 new_soms(oldnbsom*(NZ+1)+NZ*oldsz+k*nbfaces2D+i,1)=y01;
179 new_soms(oldnbsom*(NZ+1)+NZ*oldsz+k*nbfaces2D+i,2)=z;
180 x01 += dx;
181 y01 += dy;
182 z += dz;
183 }
184 }
185
186 // compute edge midpoints of the 2D mesh then translate these points
187 for (int i=0; i<oldnbsom; i++)
188 {
189 double x = coord_sommets(i,0)+0.5*dx;
190 double y = coord_sommets(i,1)+ 0.5*dy;
191 double z = 0.5*dz;
192 if (coord_sommets.dimension(1)>2)
193 z=coord_sommets(i,2)+0.5*dz;
194 for (int k=0; k<NZ; k++)
195 {
196 new_soms(oldnbsom*(NZ+1)+NZ*oldsz+NZ*nbfaces2D+k*oldnbsom+i,0)=x;
197 new_soms(oldnbsom*(NZ+1)+NZ*oldsz+NZ*nbfaces2D+k*oldnbsom+i,1)=y;
198 new_soms(oldnbsom*(NZ+1)+NZ*oldsz+NZ*nbfaces2D+k*oldnbsom+i,2)=z;
199 x += dx;
200 y += dy;
201 z += dz;
202 }
203 }
204
205
206 coord_sommets.reset();
207 dom.ajouter(new_soms);
208
209 int newnbelem = 20*NZ*oldsz;
210 IntTab new_elems(newnbelem, 4); // the new elements
211 int cpt=0;
212
213
214 // first, store the top and bottom tetrahedra: NZ*nb_triangle*2 tetrahedra
215 for (int i=0; i<oldsz; i++)
216 {
217 int i0=les_elems(i,0);
218 int i1=les_elems(i,1);
219 int i2=les_elems(i,2);
220
221 int ig=oldnbsom*(NZ+1)+i;
222
223 for (int k=0; k<NZ; k++)
224 {
225 new_elems(2*k*oldsz+2*i,0) = i0;
226 new_elems(2*k*oldsz+2*i,1) = i1;
227 new_elems(2*k*oldsz+2*i,2) = i2;
228 new_elems(2*k*oldsz+2*i,3) = ig;
229 cpt++;
230
231 new_elems(2*k*oldsz+2*i+1,0) = i0+oldnbsom;
232 new_elems(2*k*oldsz+2*i+1,1) = i1+oldnbsom;
233 new_elems(2*k*oldsz+2*i+1,2) = i2+oldnbsom;
234 new_elems(2*k*oldsz+2*i+1,3) = ig;
235 cpt++;
236
237 mettre_a_jour_sous_domaine(dom,i,2*k*oldsz+2*i,2);
238
239 i0+=oldnbsom;
240 i1+=oldnbsom;
241 i2+=oldnbsom;
242 ig+=oldsz;
243 }
244 }
245
246
247
248 // then the remaining tetrahedra
249 for (int i=0; i<nbfaces2D; i++)
250 {
251 for (int ivois=0; ivois<2; ivois++)
252 {
253 int elem = les_faces.voisin(i,ivois);
254
255 if (elem>=0)
256 {
257 int i0=les_faces.sommet(i,0);
258 int i1=les_faces.sommet(i,1);
259 int i01=oldnbsom*(NZ+1)+NZ*oldsz+i;
260
261 for (int k=0; k<NZ; k++)
262 {
263 int ig=oldnbsom*(NZ+1)+k*oldsz+elem;
264
265 int i00=oldnbsom*(NZ+1)+NZ*oldsz+NZ*nbfaces2D+i0;
266 int i11=oldnbsom*(NZ+1)+NZ*oldsz+NZ*nbfaces2D+i1;
267 // int i00=oldnbsom*(NZ+1)+NZ*oldsz+NZ*nbfaces2D+k*oldnbsom+i0;
268 // int i11=oldnbsom*(NZ+1)+NZ*oldsz+NZ*nbfaces2D+k*oldnbsom+i1;
269
270 new_elems(cpt,0) = i0;
271 new_elems(cpt,1) = i1;
272 new_elems(cpt,2) = i01;
273 new_elems(cpt++,3) = ig;
274
275 new_elems(cpt,0) = i0+oldnbsom;
276 new_elems(cpt,1) = i1+oldnbsom;
277 new_elems(cpt,2) = i01;
278 new_elems(cpt++,3) = ig;
279
280 new_elems(cpt,0) = i1;
281 new_elems(cpt,1) = i11;
282 new_elems(cpt,2) = i01;
283 new_elems(cpt++,3) = ig;
284
285 new_elems(cpt,0) = i11;
286 new_elems(cpt,1) = i1+oldnbsom;
287 new_elems(cpt,2) = i01;
288 new_elems(cpt++,3) = ig;
289
290 new_elems(cpt,0) = i0;
291 new_elems(cpt,1) = i00;
292 new_elems(cpt,2) = i01;
293 new_elems(cpt++,3) = ig;
294
295 new_elems(cpt,0) = i00;
296 new_elems(cpt,1) = i0+oldnbsom;
297 new_elems(cpt,2) = i01;
298 new_elems(cpt++,3) = ig;
299
300
301 i0+=oldnbsom;
302 i1+=oldnbsom;
303 i01+=nbfaces2D;
304 ig+=oldsz;
305 }
306 }
307 }
308 }
309
310 les_elems.ref(new_elems);
311
312 // Rebuild the octree
313 dom.invalide_octree();
314 dom.typer("Tetraedre");
315
316 extruder_dvt(dom, les_faces,oldnbsom, oldsz);
317
318 }
319 else
320 {
321 Cerr << "It is not known yet how to extrude "
322 << dom.type_elem()->que_suis_je() <<"s"<<finl;
323 exit();
324 }
325}
326
327
328
329void Extruder_en20::traiter_faces_dvt(Faces& les_faces_bord, Faces& les_faces, int oldnbsom, int oldsz, int nbfaces2D )
330{
331 int size_2D = les_faces_bord.nb_faces();
332
333 IntTab les_sommets(6*size_2D*NZ, 3);
334
335 for (int i=0; i<size_2D; i++)
336 {
337 int i0=les_faces_bord.sommet(i,0);
338 int i1=les_faces_bord.sommet(i,1);
339
340 //double x01 = 0.5*(coord_sommets(i0,0)+coord_sommets(i1,0));
341 //double y01 = 0.5*(coord_sommets(i0,1)+coord_sommets(i1,1));
342
343 // find the index of this boundary face: not optimal!
344 int jface=-1;
345 for (int iface=0; iface<nbfaces2D; iface++)
346 {
347 int j0=les_faces.sommet(iface,0);
348 int j1=les_faces.sommet(iface,1);
349
350 if (((i0==j0) &&(i1==j1)) || ((i0==j1) &&(i1==j0)))
351 {
352 jface=iface;
353 break;
354 }
355 }
356 assert(jface>=0);
357
358 for (int k=0; k<NZ; k++)
359 {
360 //double z = (k+0.5)*dz;
361 //int i01 = domaine.chercher_sommets(x01, y01, z);
362 int j01 = oldnbsom*(NZ+1)+NZ*oldsz+k*nbfaces2D+jface;
363
364 int i00=oldnbsom*(NZ+1)+NZ*oldsz+NZ*nbfaces2D+i0;
365 int i11=oldnbsom*(NZ+1)+NZ*oldsz+NZ*nbfaces2D+i1;
366 // int i00=oldnbsom*(NZ+1)+NZ*oldsz+NZ*nbfaces2D+k*oldnbsom+i0;
367 // int i11=oldnbsom*(NZ+1)+NZ*oldsz+NZ*nbfaces2D+k*oldnbsom+i1;
368
369 les_sommets(k*6*size_2D+6*i,0) = i0;
370 les_sommets(k*6*size_2D+6*i,1) = i1;
371 les_sommets(k*6*size_2D+6*i,2) = j01;
372
373 les_sommets(k*6*size_2D+6*i+1,0) = j01;
374 les_sommets(k*6*size_2D+6*i+1,1) = i1;
375 les_sommets(k*6*size_2D+6*i+1,2) = i11;
376
377 les_sommets(k*6*size_2D+6*i+2,0) = j01;
378 les_sommets(k*6*size_2D+6*i+2,1) = i11;
379 les_sommets(k*6*size_2D+6*i+2,2) = i1+oldnbsom;
380
381 les_sommets(k*6*size_2D+6*i+3,0) = j01;
382 les_sommets(k*6*size_2D+6*i+3,1) = i0+oldnbsom;
383 les_sommets(k*6*size_2D+6*i+3,2) = i1+oldnbsom;
384
385 les_sommets(k*6*size_2D+6*i+4,0) = j01;
386 les_sommets(k*6*size_2D+6*i+4,1) = i0+oldnbsom;
387 les_sommets(k*6*size_2D+6*i+4,2) = i00;
388
389 les_sommets(k*6*size_2D+6*i+5,0) = j01;
390 les_sommets(k*6*size_2D+6*i+5,1) = i00;
391 les_sommets(k*6*size_2D+6*i+5,2) = i0;
392
393 i0+=oldnbsom;
394 i1+=oldnbsom;
395 }
396 }
397
398 les_faces_bord.typer(Type_Face::triangle_3D);
399 les_faces_bord.les_sommets().ref(les_sommets);
400 les_faces_bord.voisins().resize(6*size_2D*NZ, 2);
401 les_faces_bord.voisins()=-1;
402}
403
404
405
406void Extruder_en20::extruder_dvt(Domaine& dom, Faces& les_faces, int oldnbsom, int oldsz)
407{
408 const int nbfaces2D = les_faces.nb_faces();
409 IntTab& les_elems = dom.les_elems();
410
411 for (auto &itr : dom.faces_bord())
412 {
413 Faces& les_faces_bord = itr.faces();
414 traiter_faces_dvt(les_faces_bord, les_faces, oldnbsom, oldsz, nbfaces2D);
415 }
416
417 for (auto &itr : dom.faces_raccord())
418 {
419 Faces& les_faces_bord = itr->faces();
420 traiter_faces_dvt(les_faces_bord, les_faces, oldnbsom, oldsz, nbfaces2D);
421 }
422
423 Bord& devant = dom.faces_bord().add(Bord());
424 devant.nommer("devant");
425 Faces& les_faces_dvt=devant.faces();
426 les_faces_dvt.typer(Type_Face::triangle_3D);
427
428 IntTab som_dvt(oldsz, 3);
429 les_faces_dvt.voisins().resize(oldsz, 2);
430 les_faces_dvt.voisins()=-1;
431
432 Bord& derriere = dom.faces_bord().add(Bord());
433 derriere.nommer("derriere");
434 Faces& les_faces_der=derriere.faces();
435 les_faces_der.typer(Type_Face::triangle_3D);
436
437 IntTab som_der(oldsz, 3);
438 les_faces_der.voisins().resize(oldsz, 2);
439 les_faces_der.voisins()=-1;
440
441 for (int i=0; i<oldsz; i++)
442 {
443 int i0=les_elems(2*i,0);
444 int i1=les_elems(2*i,1);
445 int i2=les_elems(2*i,2);
446
447 som_dvt(i,0) = i0;
448 som_dvt(i,1) = i1;
449 som_dvt(i,2) = i2;
450
451 som_der(i,0) = i0+oldnbsom*NZ;
452 som_der(i,1) = i1+oldnbsom*NZ;
453 som_der(i,2) = i2+oldnbsom*NZ;
454
455 }
456
457
458 les_faces_dvt.les_sommets().ref(som_dvt);
459 les_faces_der.les_sommets().ref(som_der);
460
461}
462
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:809
void typer(const Nom &)
Sets the element type of the domain using the name passed as parameter.
Definition Domaine.h:457
int_t nb_som_tot() const
Returns the total number of vertices of the domain i.e. the number of real and virtual vertices on th...
Definition Domaine.h:123
int_t nb_som() const
Returns the number of vertices of the domain.
Definition Domaine.h:121
void ajouter(const DoubleTab_t &soms)
Adds nodes (or vertices) to the domain (without checking for duplicates).
Definition Domaine.cpp:908
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
Extruder_en20 class — interpreter that reads and executes the Extruder_en20 directive:
virtual void extruder_dvt(Domaine &, Faces &, int, int)
ArrOfDouble direction
Entree & interpreter_(Entree &) override
Main function of the Extruder_en20 interpreter. Extrudes the domain specified by the directive.
void extruder(Domaine &)
Extrudes all elements of a domain: transforms the geometric elements of the domain.
void typer(const Motcle &)
Sets the type of the faces.
Definition Faces.cpp:382
void associer_domaine(const Domaine_t &z)
Definition Faces.h:94
IntTab_t & voisins()
Returns the array of neighbors (of the faces).
Definition Faces.h:89
int_t nb_faces() const
Definition Faces.h:66
int_t voisin(int_t, int) const
Returns the number of the i-th neighbor of face.
Definition Faces.h:165
const IntTab_t & les_sommets() const
Returns the array of vertices of all faces.
Definition Faces.h:74
int_t sommet(int_t, int) const
Returns the number of the j-th vertex of the i-th 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)
From the description of the domain elements and boundaries (borders, connections, face groups,...
void nommer(const Nom &) override
Gives a name to the boundary.
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
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
friend class Entree
Definition Objet_U.h:71
static int dimension
Definition Objet_U.h:94
const Nom & que_suis_je() const
Returns the string identifying the class.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
Definition Objet_U.cpp:289
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
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)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
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:2739
static void uninit_sequential_domain(Domaine_32_64< _SIZE_ > &dom)
Method used by interpreters that modify the domain (sequential), destroys the descriptors of vertices...
Definition Scatter.cpp:2754
Base class for output streams.
Definition Sortie.h:52
virtual void ref(const TRUSTTab &)
Definition TRUSTTab.tpp:308
void reset() override
Definition TRUSTTab.tpp:362
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133