TrioCFD 1.9.9_beta
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; // number of vertices per 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(); // sort indices to avoid unexpected index ordering surprises
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) // "remove" the face by resetting the indices to -1
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; // number of vertices per 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(); // sort indices to avoid unexpected index ordering surprises (previously encountered)
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) // "remove" the face by resetting the relevant indices to -1
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 // "add" the face by assigning indices to the first "free" slots (=-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; // number of vertices per element
230 IntTab new_elems(oldsz, nbs);
231
232 int nbfacesom = (dimension == 2) ? 4 : 4 * 3; // number of faces connected to a vertex
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); // to be consistent with what is done in 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 // Rebuild the 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 // Internal boundaries
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:816
void calculer_centres_gravite(DoubleTab_t &xp) const
Calculates the centers of gravity of the domain elements.
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:809
Bords_Internes_t & bords_int()
Definition Domaine.h:213
int_t nb_som() const
Returns the number of vertices of the domain.
Definition Domaine.h:121
void reordonner()
Definition Domaine.h:104
const Nom & le_nom() const override
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
void typer(const Motcle &)
Sets the type of the faces.
Definition Faces.cpp:382
int_t dimensionner(int_t)
(Re-)sizes the faces. The neighbors are resized accordingly.
Definition Faces.cpp:336
const IntTab_t & les_sommets() const
Returns the array of vertices of all faces.
Definition Faces.h:74
void nommer(const Nom &) override
Gives a name to the boundary.
Definition Frontiere.cpp:74
void typer_faces(const Motcle &)
Sets the type of the boundary faces.
Definition Frontiere.cpp:96
const Faces_t & faces() const
Definition Frontiere.h:54
A character string (Nom) in uppercase.
Definition Motcle.h:26
static void nettoie(Domaine_t &)
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(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)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
class Remove_elem Removes from the mesh the elements specified by the user in the data set
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: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
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