TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
NettoieNoeuds.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 <Domaine.h>
18#include <Scatter.h>
19
20Implemente_instanciable_32_64(NettoieNoeuds_32_64, "NettoiePasNoeuds", Interprete_geometrique_base_32_64<_T_>);
21// XD nettoiepasnoeuds interprete nettoiepasnoeuds NO_BRACE Keyword NettoiePasNoeuds does not delete useless nodes
22// XD_CONT (nodes without elements) from a domain.
23// XD attr domain_name ref_domaine domain_name REQ Name of domain.
24
25template <typename _SIZE_>
27
28template <typename _SIZE_>
30
32#if INT_is_64_ == 2
34#endif
35
36/*! @brief Main function of the NettoieNoeuds_32_64 interpreter. Data set structure (in dimension 2):
37 *
38 * NettoieNoeuds_32_64 dom alpha
39 *
40 * @param (Entree& is) an input stream
41 * @return (Entree&) the input stream
42 * @throws the object to mesh is not of type Domaine
43 */
44template <typename _SIZE_>
46{
47 this->associer_domaine(is);
48
49 if (this->domaine().les_sommets().size()!=0)
50 {
51 Cerr << "The keyword NettoiePasNoeuds must be placed before the ";
52 Cerr << "reading of the domain to avoid the cleaning of the double";
53 Cerr << "nodes of the domain." << finl;
55 }
57 Cerr << "NettoiePasNoeuds=" << NettoiePasNoeuds << " for the domain " << this->domaine().le_nom() << finl;
58
59 return is;
60}
61
62template <typename _SIZE_>
64{
65 if (NettoiePasNoeuds==1)
66 return;
67
68 // Allow modification of the structure of the vertex and element arrays:
70
71 DoubleTab_t& coord_sommets=dom.les_sommets();
72 IntTab_t& les_elems=dom.les_elems();
73 int_t nb_som_init=coord_sommets.dimension(0);
74 int_t nb_elem=les_elems.dimension(0);
75 int nb_som_elem=les_elems.dimension_int(1);
76 ArrOfInt_t renum_som_old2new(nb_som_init);
77
78 int_t compteur=0;
79
80 {
81 //int_t i;
82 for (int_t i=0; i<nb_som_init ; i++)
83 renum_som_old2new[i]=-1;
84
85 for (int_t i=0; i<nb_elem ; i++)
86 for (int j=0; j< nb_som_elem; j++)
87 {
88 // GF in the case of polyhedra
89 if (les_elems(i,j)==-1) break;
90 int_t& tmp=renum_som_old2new[les_elems(i,j)];
91 assert (tmp < compteur);
92 if(tmp==-1)
93 tmp=compteur++;
94 }
95 // GF addition: otherwise a duplicate node on a boundary becomes -1
96 int nb_bords=dom.nb_front_Cl();
97 for (int ii=0; ii<nb_bords; ii++)
98 {
99 const Frontiere_t& front= dom.frontiere(ii);
100 const Faces_t& faces=front.faces();
101 const IntTab_t& faces_sommets=faces.les_sommets();
102 int_t nb_faces=faces_sommets.dimension(0);
103 int nb_som_face=faces_sommets.dimension_int(1);
104 for(int_t i=0; i<nb_faces; i++)
105 for(int j=0; j<nb_som_face; j++)
106 {
107 // in the case of polygons
108 if (faces_sommets(i,j)==-1) break;
109 int_t& tmp=renum_som_old2new[faces_sommets(i,j)];
110 assert (tmp < compteur);
111 if(tmp==-1)
112 tmp=compteur++;
113 }
114 }
115 }
116 int_t nb_som_new=compteur;
117 Cerr << "Elimination of " << nb_som_init - nb_som_new << " unnecessary nodes in the domain " << dom.le_nom() << finl;
118 if(nb_som_new!=nb_som_init)
119 {
120 ArrOfInt_t renum_som_new2old(nb_som_new);
121 {
122 int_t j;
123 for (int_t i=0; i<nb_som_init ; i++)
124 if((j=renum_som_old2new[i])!=-1)
125 renum_som_new2old[j]=i;
126 }
127 {
128 int_t i;
129 int j;
130 DoubleTab_t new_coord(nb_som_new, Objet_U::dimension);
131
132 for (i=0; i<nb_som_new ; i++)
133 for (j=0; j<Objet_U::dimension ; j++)
134 {
135 new_coord(i,j)=coord_sommets(renum_som_new2old[i],j);
136 }
137 coord_sommets=new_coord;
138
139 for (i=0; i<nb_elem ; i++)
140 for (j=0; j<nb_som_elem ; j++)
141 {
142 int_t num_som=les_elems(i,j);
143 if (num_som!=-1)
144 les_elems(i,j)=renum_som_old2new[num_som];
145 else
146 les_elems(i,j)=-1;
147 }
148 }
149
150 // Retrieve the boundaries:
151 for (auto &itr : dom.faces_bord())
152 {
153 Frontiere_t& front = itr;
154 Faces_t& faces = front.faces();
155 IntTab_t& faces_sommets = faces.les_sommets();
156 IntTab_t old_faces_sommets(faces.les_sommets());
157 int_t nb_faces = faces_sommets.dimension(0);
158 int nb_som_face = faces_sommets.dimension_int(1);
159 for (int_t i = 0; i < nb_faces; i++)
160 for (int j = 0; j < nb_som_face; j++)
161 {
162 int_t som = old_faces_sommets(i, j);
163 if (som != -1)
164 faces_sommets(i, j) = renum_som_old2new[som];
165 else
166 faces_sommets(i, j) = som;
167 }
168 }
169
170 // Handy renum lambda:
171 auto renum_lamb = [&](auto& itr_arg)
172 {
173 Frontiere_t& front = itr_arg;
174 Faces_t& faces = front.faces();
175 IntTab_t& faces_sommets = faces.les_sommets();
176 IntTab_t old_faces_sommets(faces.les_sommets());
177 int_t nb_faces = faces_sommets.dimension(0);
178 int nb_som_face = faces_sommets.dimension_int(1);
179 for (int_t i = 0; i < nb_faces; i++)
180 for (int j = 0; j < nb_som_face; j++)
181 faces_sommets(i, j) = renum_som_old2new[old_faces_sommets(i, j)];
182 };
183
184 // Internal boundaries:
185 for (auto &itr : dom.bords_int())
186 renum_lamb(itr);
187 // Connectors
188 for (auto &itr : dom.faces_raccord())
189 renum_lamb(itr);
190 // Face groups:
191 for (auto &itr : dom.groupes_faces())
192 renum_lamb(itr);
193 }
195}
196
197/*! @brief checks whether there are duplicate nodes
198 *
199 */
200template <typename _SIZE_>
202{
203 Cerr<<finl<<"Beginning of the search of identical nodes (can be long, algorithm in n^2)..."<<finl;
204 const DoubleTab_t& coord_sommets=dom.les_sommets();
205 int_t ns=coord_sommets.dimension(0);
206 // int nbsomelem=coord_sommets.dimension(1);
207 // const IntTab_t& les_elems= dom.les_elems();
208 int err=0;
209 // the version with element search is faster in principle
210 // n log(n) risks missing duplicate nodes
211 // we fall back to an n*n/2 algorithm
212 /* for (int sommet=0;sommet<ns;sommet++)
213 {
214
215 double x,y,z=0;
216 x=coord_sommets(sommet,0);
217 y=coord_sommets(sommet,1);
218 if (dimension>2)
219 z=coord_sommets(sommet,0);
220
221 int elem2=dom.chercher_elements(x,y,z);
222 if (elem2==-1)
223 {
224 Cerr<<"unable to find node "<<finl;
225 Process::exit();
226 }
227 int som;
228 for ( som=0;som<nbsomelem;som++)
229 {
230 int sommet2=les_elems(elem2,som);
231 int ok=1;
232 for (int dir=0;dir<Objet_U::dimension;dir++)
233 ok=ok&&(est_egal(coord_sommets(sommet,dir),coord_sommets(sommet2,dir)));
234 if (ok)
235 {
236 if (sommet!=sommet2)
237 {
238 Cerr<<" the nodes "<<sommet<<" and "<<sommet2<<" seem the same"<<finl;
239 err=1;
240 }
241 }
242 }
243 }
244 */
245 int_t tmp,pourcent=0;
246 for (int_t sommet=0; sommet<ns; sommet++)
247 {
248 tmp =(sommet*100)/ns;
249 if(tmp>=pourcent)
250 {
251 pourcent = tmp;
252 Cerr << pourcent << "% of nodes have been verified\r " << flush;
253 }
254 for (int_t sommet2=sommet+1; sommet2<ns; sommet2++)
255 {
256 int ok=1;
257 for (int dir=0; dir<Objet_U::dimension; dir++)
258 ok=ok&&(est_egal(coord_sommets(sommet,dir),coord_sommets(sommet2,dir)));
259 if (ok)
260 {
261 if (sommet!=sommet2)
262 {
263 Cerr<< finl << "The nodes "<<sommet<<" and "<<sommet2<<" are the same !"<<finl;
264 err=1;
265 }
266 }
267 }
268 }
269 Cerr<<"End of the search of identical nodes."<<finl;
270 if (err)
272}
273
274
275template class NettoieNoeuds_32_64<int>;
276#if INT_is_64_ == 2
278#endif
279
280
int nb_front_Cl() const
Definition Domaine.h:236
DoubleTab_t & les_sommets()
Definition Domaine.h:113
Bords_t & faces_bord()
Definition Domaine.h:198
const Frontiere_t & frontiere(int i) const
Definition Domaine.h:539
Raccords_t & faces_raccord()
Definition Domaine.h:253
IntTab_t & les_elems()
Definition Domaine.h:129
Bords_Internes_t & bords_int()
Definition Domaine.h:213
Groupes_Faces_t & groupes_faces()
Definition Domaine.h:224
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
const IntTab_t & les_sommets() const
Returns the array of vertices of all faces.
Definition Faces.h:74
const Faces_t & faces() const
Definition Frontiere.h:54
Class Interprete_geometrique_base.
Class NettoieNoeuds x->alpha x.
Domaine_32_64< _SIZE_ > Domaine_t
ArrOfInt_T< _SIZE_ > ArrOfInt_t
static void nettoie(Domaine_t &)
Entree & interpreter_(Entree &) override
Main function of the NettoieNoeuds_32_64 interpreter. Data set structure (in dimension 2):
IntTab_T< _SIZE_ > IntTab_t
Faces_32_64< _SIZE_ > Faces_t
Frontiere_32_64< _SIZE_ > Frontiere_t
DoubleTab_T< _SIZE_ > DoubleTab_t
static void verifie_noeuds(const Domaine_t &)
checks whether there are duplicate nodes
static int NettoiePasNoeuds
friend class Entree
Definition Objet_U.h:71
static int dimension
Definition Objet_U.h:94
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
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
int dimension_int(int d) const
Definition TRUSTTab.tpp:152
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133