TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Remove_elem.cpp
1/****************************************************************************
2* Copyright (c) 2026, 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 <NettoieNoeuds.h>
17#include <Remove_elem.h>
18#include <TRUSTLists.h>
19#include <TRUSTArray.h>
20#include <Scatter.h>
21#include <Param.h>
22
23Implemente_instanciable(Remove_elem, "Remove_elem", Interprete_geometrique_base);
24// XD remove_elem interprete remove_elem INHERITS_BRACE Keyword to remove element from a VDF mesh (named domaine_name),
25// XD_CONT either from an explicit list of elements or from a geometric condition defined by a condition f(x,y)>0 in 2D
26// XD_CONT and f(x,y,z)>0 in 3D. All the new borders generated are gathered in one boundary called : newBord (to rename
27// XD_CONT it, use RegroupeBord keyword. To split it to different boundaries, use decoupebord keyword). Example of a
28// XD_CONT removed zone of radius 0.2 centered at (x,y)=(0.5,0.5): NL2 Remove_elem dom { fonction
29// XD_CONT $0.2*0.2-(x-0.5)^2-(y-0.5)^2>0$ } NL2 Warning : the thickness of removed zone has to be large enough to avoid
30// XD_CONT singular nodes as decribed below : \includeimage{{removeelem.jpeg}}
31// XD attr domaine ref_domaine domain REQ Name of domain
32// XD attr bloc remove_elem_bloc bloc REQ not_set
33
34Sortie& Remove_elem::printOn(Sortie& os) const { return Interprete::printOn(os); }
35
37
38int Remove_elem::lire_motcle_non_standard(const Motcle& mot, Entree& is)
39{
40 int retval = 1;
41 if (mot == "liste")
42 {
43 int nb_elem, elem;
44 is >> nb_elem;
45 for (int i = 0; i < nb_elem; i++)
46 {
47 is >> elem;
48 listelem.add(elem);
49 }
50 }
51 else
52 retval = -1;
53
54 return retval;
55}
56
57// XD remove_elem_bloc objet_lecture nul BRACE not_set
59{
61 Param param(que_suis_je());
62 Nom fonction;
63 param.ajouter_non_std("liste", this); // XD_ADD_P listentier
64 // XD_CONT not_set
65 param.ajouter("fonction", &fonction); // XD_ADD_P chaine
66 // XD_CONT not_set
68 if (fonction == "??")
69 f_ok = 0;
70 else
71 {
72 Cerr << "Reading and interpretation of the function " << fonction << " ... ";
73 f.setNbVar(3);
74 f.setString(fonction);
75 f.addVar("x");
76 f.addVar("y");
77 f.addVar("z");
78 f.parseString();
79 f_ok = 1;
80 Cerr << " Ok" << finl;
81 }
82
87 Cerr << "Refinement... OK" << finl;
88 return is;
89}
90
91void Remove_elem::recreer_faces(Domaine& domaine, Faces& faces, IntTab& som_face) const
92{
93 IntTab& sommets = faces.les_sommets();
94 int nb_faces = sommets.dimension(0);
95 int nbs = (dimension == 2) ? 2 : 4; // nombre de sommets par face
96 IntTab faces_recreees(nb_faces, nbs);
97
98 int ii = 0;
99
100 for (int i = 0; i < nb_faces; i++)
101 {
102 ArrOfInt ind(4);
103 ind[0] = sommets(i, 0);
104 ind[1] = sommets(i, 1);
105 ind[2] = (dimension == 3) ? sommets(i, 2) : -1;
106 ind[3] = (dimension == 3) ? sommets(i, 3) : -1;
107 ind.ordonne_array(); // ordonnancement des indices pour eviter les mauvaises surprises de numerotations d'indices
108
109 int trouve = 0;
110
111 int j = 0;
112 for (; j < som_face.dimension(2); j++)
113 {
114 if (som_face(ind[3], 0, j) == ind[2] && som_face(ind[3], 1, j) == ind[1] && som_face(ind[3], 2, j) == ind[0])
115 {
116 trouve = 1;
117 break;
118 }
119 }
120
121 if (trouve == 1) // on "supprime" la face en reinitialisant a -1 les indices
122 {
123 som_face(ind[3], 0, j) = -1;
124 som_face(ind[3], 1, j) = -1;
125 som_face(ind[3], 2, j) = -1;
126 }
127 else
128 {
129 faces_recreees(ii, 0) = sommets(i, 0);
130 faces_recreees(ii, 1) = sommets(i, 1);
131 if (dimension == 3)
132 {
133 faces_recreees(ii, 2) = sommets(i, 2);
134 faces_recreees(ii, 3) = sommets(i, 3);
135 }
136 ii++;
137 }
138 }
139
140 faces_recreees.resize(ii, nbs);
141
142 sommets.reset();
143 sommets.ref(faces_recreees);
144}
145
146void Remove_elem::creer_faces(Domaine& dom, Faces& faces, IntTab& som_face) const
147{
148 faces.dimensionner(1);
149 IntTab& sommets = faces.les_sommets();
150 int nbsom = domaine().les_sommets().dimension(0);
151 int nbs = (dimension == 2) ? 2 : 4; // nombre de sommets par face
152 IntTab faces_recreees(1, nbs);
153
154 int ii = 0;
155
156 for (int i = 0; i < nbsom; i++)
157 {
158 for (int j = 0; j < som_face.dimension(2); j++)
159 {
160 if (som_face(i, 0, j) != -1)
161 {
162 faces_recreees.resize(ii + 1, nbs);
163 faces_recreees(ii, 0) = i;
164 faces_recreees(ii, 1) = som_face(i, 0, j);
165 if (dimension == 3)
166 {
167 faces_recreees(ii, 2) = som_face(i, 1, j);
168 faces_recreees(ii, 3) = som_face(i, 2, j);
169 }
170 ii++;
171 }
172 }
173 }
174
175 faces.dimensionner(ii);
176 sommets.ref(faces_recreees);
177}
178
179void Remove_elem::remplir_liste(IntTab& som_face, int ind1, int ind2, int ind3, int ind4) const
180{
181 ArrOfInt ind(4);
182 ind[0] = ind1;
183 ind[1] = ind2;
184 ind[2] = ind3;
185 ind[3] = ind4;
186 ind.ordonne_array(); // ordonnancement des indices pour eviter les mauvaises surprises de numerotations d'indices (rencontrees prealablement)
187
188 int trouve = 0;
189
190 int j = 0;
191 for (; j < som_face.dimension(2); j++)
192 {
193 if (som_face(ind[3], 0, j) == ind[2] && som_face(ind[3], 1, j) == ind[1] && som_face(ind[3], 2, j) == ind[0])
194 {
195 trouve = 1;
196 break;
197 }
198 }
199
200 if (trouve == 1) // on "supprime" la face en reinitialisant a -1 les indices concernes
201 {
202 som_face(ind[3], 0, j) = -1;
203 som_face(ind[3], 1, j) = -1;
204 som_face(ind[3], 2, j) = -1;
205 }
206 else // on "ajoute" la face en affectant les indices aux premieres cases "libres" (=-1)
207 {
208 for (j = 0; j < som_face.dimension(2); j++)
209 {
210 if (som_face(ind[3], 0, j) == -1)
211 break;
212 }
213 som_face(ind[3], 0, j) = ind[2];
214 som_face(ind[3], 1, j) = ind[1];
215 som_face(ind[3], 2, j) = ind[0];
216 }
217}
218
220{
221 if (dom.type_elem()->que_suis_je() == "Rectangle" || dom.type_elem()->que_suis_je() == "Hexaedre")
222 {
223
224 IntTab& les_elems = dom.les_elems();
225 int oldsz = les_elems.dimension(0);
226 ArrOfInt marq_remove(oldsz);
227 int nbsom = domaine().les_sommets().dimension(0);
228
229 int nbs = (dimension == 2) ? 4 : 8; // nombre de sommets par element
230 IntTab new_elems(oldsz, nbs);
231
232 int nbfacesom = (dimension == 2) ? 4 : 4 * 3; // nbre de faces connectees a un sommet
233 IntTab som_face(nbsom, 3, nbfacesom);
234 som_face = -1;
235
236 if (f_ok)
237 {
238 DoubleTab xg(oldsz, dimension);
239 dom.type_elem()->calculer_centres_gravite(xg);
240 for (int i = 0; i < oldsz; i++)
241 {
242 f.setVar(0, xg(i, 0));
243 f.setVar(1, xg(i, 1));
244 if (dimension == 3)
245 f.setVar(2, xg(i, 2));
246 //if(f.eval()) listelem.add(i);
247 if ((int) (f.eval() + 0.5))
248 marq_remove[i] = 1; //listelem.add(i); // pour etre conforme a ce qui est fait dans DecoupeBord
249 }
250 }
251 else
252 {
253 for (int i = 0; i < listelem.size(); i++)
254 {
255 marq_remove[listelem[i]] = 1;
256 }
257
258 }
259
260 int j = 0;
261 Cerr << "-> " << listelem.size() << " elements will be removed from the domain " << domaine().le_nom() << finl;
262 /* if (listelem.size()==0)
263 {
264 Cerr << "May be an error when applying Remove_elem : no elements found." << finl;
265 Process::exit();
266 } */
267 for (int i = 0; i < oldsz; i++)
268 {
269 if (marq_remove[i] == 0)
270 {
271 for (int k = 0; k < nbs; k++)
272 new_elems(j, k) = les_elems(i, k);
273 j++;
274 }
275 else
276 {
277 if (dimension == 2)
278 {
279 int i0 = les_elems(i, 0);
280 int i1 = les_elems(i, 1);
281 int i2 = les_elems(i, 2);
282 int i3 = les_elems(i, 3);
283
284 remplir_liste(som_face, i0, i1, -1, -1);
285 remplir_liste(som_face, i0, i2, -1, -1);
286 remplir_liste(som_face, i1, i3, -1, -1);
287 remplir_liste(som_face, i2, i3, -1, -1);
288 }
289 else
290 {
291 int i0 = les_elems(i, 0);
292 int i1 = les_elems(i, 1);
293 int i2 = les_elems(i, 2);
294 int i3 = les_elems(i, 3);
295 int i4 = les_elems(i, 4);
296 int i5 = les_elems(i, 5);
297 int i6 = les_elems(i, 6);
298 int i7 = les_elems(i, 7);
299
300 remplir_liste(som_face, i0, i1, i2, i3);
301 remplir_liste(som_face, i0, i1, i4, i5);
302 remplir_liste(som_face, i0, i4, i2, i6);
303 remplir_liste(som_face, i1, i5, i3, i7);
304 remplir_liste(som_face, i2, i3, i6, i7);
305 remplir_liste(som_face, i4, i5, i6, i7);
306 }
307 }
308 }
309
310 new_elems.resize(j, nbs);
311 les_elems.ref(new_elems);
312
313 // Reconstruction de l'octree
314 dom.invalide_octree();
315 dom.construit_octree();
316 dom.reordonner();
317
318 {
319 Cerr << " Regeneration of boundaries" << finl;
320 for (auto &itr : dom.faces_bord())
321 {
322 Faces& les_faces = itr.faces();
323 if (dimension == 2)
324 les_faces.typer(Type_Face::segment_2D);
325 else
326 les_faces.typer(Type_Face::quadrangle_3D);
327 recreer_faces(dom, les_faces, som_face);
328 }
329 Cerr << " addition of a new boundary issued from removed elements" << finl;
330 Bord& new_bord = dom.faces_bord().add(Bord());
331 new_bord.nommer("newBord");
332 if (dimension == 2)
333 new_bord.typer_faces(Type_Face::segment_2D);
334 else
335 new_bord.typer_faces(Type_Face::quadrangle_3D);
336 Faces& les_faces = new_bord.faces();
337 creer_faces(dom, les_faces, som_face);
338 }
339
340 {
341 // Les Bords internes
342 Cerr << "Regeneration of internal faces" << finl;
343 for (auto &itr : dom.bords_int())
344 {
345 Faces& les_faces = itr.faces();
346 if (dimension == 2)
347 les_faces.typer(Type_Face::segment_2D);
348 else
349 les_faces.typer(Type_Face::quadrangle_3D);
350 recreer_faces(dom, les_faces, som_face);
351 }
352 }
353
354 Cerr << "END of Remove_elem..." << finl;
355 Cerr << " 1 NbElem=" << dom.les_elems().dimension(0) << " NbNod=" << dom.nb_som() << finl;
356 }
357
358 else
359
360 {
361 Cerr << "We do not yet know how to Remove_elem the " << dom.type_elem()->que_suis_je() << "s" << finl;
362 exit();
363 }
364}
365
366
const OctreeRoot_t & construit_octree() const
Definition Domaine.cpp:817
void calculer_centres_gravite(DoubleTab_t &xp) const
Calcule les centres de gravites des elements du domaine.
Definition Domaine.h:503
DoubleTab_t & les_sommets()
Definition Domaine.h:113
Bords_t & faces_bord()
Definition Domaine.h:198
IntTab_t & les_elems()
Definition Domaine.h:129
void invalide_octree()
Definition Domaine.cpp:810
Bords_Internes_t & bords_int()
Definition Domaine.h:213
int_t nb_som() const
Renvoie le nombre de sommets du domaine.
Definition Domaine.h:121
void reordonner()
Definition Domaine.h:104
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
void typer(const Motcle &)
Type les faces.
Definition Faces.cpp:390
int_t dimensionner(int_t)
(Re-)dimensionne les faces On redimensionne les voisins en consequence.
Definition Faces.cpp:344
const IntTab_t & les_sommets() const
Renvoie le tableau des sommets de toutes les faces.
Definition Faces.h:74
void nommer(const Nom &) override
Donne un nom a la frontiere.
Definition Frontiere.cpp:74
void typer_faces(const Motcle &)
Type les faces de la frontiere.
Definition Frontiere.cpp:96
const Faces_t & faces() const
Definition Frontiere.h:54
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
static void nettoie(Domaine_t &)
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
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(const char *keyword, const int *value, Param::Nature nat=Param::OPTIONAL)
Register an integer parameter.
Definition Param.cpp:364
void ajouter_non_std(const char *keyword, const Objet_U *value, Param::Nature nat=Param::OPTIONAL)
Register a keyword handled by Objet_U::lire_motcle_non_standard.
Definition Param.cpp:489
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
class Remove_elem Enleve du maillage les elements specifies par l'utilisateur dans le jeu de donnees
Definition Remove_elem.h:34
void recreer_faces(Domaine &, Faces &, IntTab &) const
Entree & interpreter_(Entree &) override
Parser_U f
Definition Remove_elem.h:48
void remove_elem_(Domaine &)
void creer_faces(Domaine &, Faces &, IntTab &) const
IntList listelem
Definition Remove_elem.h:47
void remplir_liste(IntTab &, int, int, int, int) const
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
void ordonne_array()
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