TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Trianguler_fin.cpp
1/****************************************************************************
2* Copyright (c) 2023, 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 <Trianguler_fin.h>
17#include <Domaine.h>
18
19Implemente_instanciable(Trianguler_fin, "Trianguler_fin", Triangulation_base);
20// XD trianguler_fin triangulate trianguler_fin INHERITS_BRACE Trianguler_fin is the recommended option to triangulate
21// XD_CONT rectangles. NL2 As an extension (subdivision) of Triangulate_h option, this one cut each initial rectangle in
22// XD_CONT 8 triangles (against 4, previously). This cutting ensures : NL2 - a correct cutting in the corners (in
23// XD_CONT respect to pressure discretization PreP1B). NL2 - a better isotropy of elements than with Trianguler_h
24// XD_CONT option. NL2 - a better alignment of summits (this could have a benefit effect on calculation near walls since
25// XD_CONT first elements in contact with it are all contained in the same constant thickness, and, by this way, a 2D
26// XD_CONT cartesian grid based on summits can be engendered and used to realize statistical analysis in plane channel
27// XD_CONT configuration for instance). Principle: NL2 \includeimage{{triangulerfin.jpeg}}
28
29
31
33
34/*! @brief Triangule tous les element d'un domaine: transforme les elements goemetriques du domaine en triangles.
35 *
36 * Pour l'instant on ne sait trianguler que des Rectangles
37 * (on les coupe en 8).
38 *
39 * @param (Domaine& domaine) le domaine dont on veut trianguler les elements
40 */
41void Trianguler_fin::trianguler(Domaine& dom) const
42{
43 const DoubleTab& xs = dom.coord_sommets();
44 IntTab& les_elems = dom.les_elems();
45 int oldsz = les_elems.dimension(0);
46 DoubleTab& sommets = dom.les_sommets();
47 int nbs = sommets.dimension(0);
48
49 {
50 DoubleTab sommets_ajoutes(oldsz, dimension);
51 dom.type_elem()->calculer_centres_gravite(sommets_ajoutes);
52 sommets.resize(4 * nbs, dimension);
53 for (int i = 0; i < oldsz; i++)
54 for (int j = 0; j < dimension; j++)
55 sommets(nbs + i, j) = sommets_ajoutes(i, j);
56 }
57
58 if ((dom.type_elem()->que_suis_je() == "Rectangle") || (dom.type_elem()->que_suis_je() == "Quadrangle"))
59 {
60 dom.typer("Triangle");
61 IntTab new_elems(8 * oldsz, 3);
62 IntTab fait_sommet_arete(4 * nbs, 3);
63 fait_sommet_arete = -1;
64 int j = 0;
65
66 for (int i = 0; i < oldsz; i++)
67 {
68 int i0 = les_elems(i, 0);
69 int i1 = les_elems(i, 1);
70 int i2 = les_elems(i, 2);
71 int i3 = les_elems(i, 3);
72 int i01 = -1;
73 int i02 = -1;
74 int i13 = -1;
75 int i23 = -1;
76
77 for (int ii = 0; ii < j; ii++)
78 {
79 if (fait_sommet_arete(ii, 0) == i0 && fait_sommet_arete(ii, 1) == i1)
80 i01 = nbs + oldsz + ii;
81 if (fait_sommet_arete(ii, 0) == i0 && fait_sommet_arete(ii, 1) == i2)
82 i02 = nbs + oldsz + ii;
83 if (fait_sommet_arete(ii, 0) == i1 && fait_sommet_arete(ii, 1) == i3)
84 i13 = nbs + oldsz + ii;
85 if (fait_sommet_arete(ii, 0) == i2 && fait_sommet_arete(ii, 1) == i3)
86 i23 = nbs + oldsz + ii;
87 }
88
89 if (i01 == -1)
90 {
91 fait_sommet_arete(j, 0) = i0;
92 fait_sommet_arete(j, 1) = i1;
93 i01 = nbs + oldsz + j;
94 sommets(i01, 0) = 0.5 * (xs(i0, 0) + xs(i1, 0));
95 sommets(i01, 1) = 0.5 * (xs(i0, 1) + xs(i1, 1));
96 j++;
97 }
98
99 if (i02 == -1)
100 {
101 fait_sommet_arete(j, 0) = i0;
102 fait_sommet_arete(j, 1) = i2;
103 i02 = nbs + oldsz + j;
104 sommets(i02, 0) = 0.5 * (xs(i0, 0) + xs(i2, 0));
105 sommets(i02, 1) = 0.5 * (xs(i0, 1) + xs(i2, 1));
106 j++;
107 }
108
109 if (i13 == -1)
110 {
111 fait_sommet_arete(j, 0) = i1;
112 fait_sommet_arete(j, 1) = i3;
113 i13 = nbs + oldsz + j;
114 sommets(i13, 0) = 0.5 * (xs(i1, 0) + xs(i3, 0));
115 sommets(i13, 1) = 0.5 * (xs(i1, 1) + xs(i3, 1));
116 j++;
117 }
118
119 if (i23 == -1)
120 {
121 fait_sommet_arete(j, 0) = i2;
122 fait_sommet_arete(j, 1) = i3;
123 i23 = nbs + oldsz + j;
124 sommets(i23, 0) = 0.5 * (xs(i2, 0) + xs(i3, 0));
125 sommets(i23, 1) = 0.5 * (xs(i2, 1) + xs(i3, 1));
126 j++;
127 }
128
129 new_elems(i, 0) = i + nbs;
130 new_elems(i, 1) = i0;
131 new_elems(i, 2) = i01;
132
133 new_elems(i + oldsz, 0) = i + nbs;
134 new_elems(i + oldsz, 1) = i01;
135 new_elems(i + oldsz, 2) = i1;
136 mettre_a_jour_sous_domaine(dom, i, i + oldsz, 1);
137
138 new_elems(i + 2 * oldsz, 0) = i + nbs;
139 new_elems(i + 2 * oldsz, 1) = i1;
140 new_elems(i + 2 * oldsz, 2) = i13;
141 mettre_a_jour_sous_domaine(dom, i, i + 2 * oldsz, 1);
142
143 new_elems(i + 3 * oldsz, 0) = i + nbs;
144 new_elems(i + 3 * oldsz, 1) = i13;
145 new_elems(i + 3 * oldsz, 2) = i3;
146 mettre_a_jour_sous_domaine(dom, i, i + 3 * oldsz, 1);
147
148 new_elems(i + 4 * oldsz, 0) = i + nbs;
149 new_elems(i + 4 * oldsz, 1) = i3;
150 new_elems(i + 4 * oldsz, 2) = i23;
151 mettre_a_jour_sous_domaine(dom, i, i + 4 * oldsz, 1);
152
153 new_elems(i + 5 * oldsz, 0) = i + nbs;
154 new_elems(i + 5 * oldsz, 1) = i23;
155 new_elems(i + 5 * oldsz, 2) = i2;
156 mettre_a_jour_sous_domaine(dom, i, i + 5 * oldsz, 1);
157
158 new_elems(i + 6 * oldsz, 0) = i + nbs;
159 new_elems(i + 6 * oldsz, 1) = i2;
160 new_elems(i + 6 * oldsz, 2) = i02;
161 mettre_a_jour_sous_domaine(dom, i, i + 6 * oldsz, 1);
162
163 new_elems(i + 7 * oldsz, 0) = i + nbs;
164 new_elems(i + 7 * oldsz, 1) = i02;
165 new_elems(i + 7 * oldsz, 2) = i0;
166 mettre_a_jour_sous_domaine(dom, i, i + 7 * oldsz, 1);
167
168 }
169
170 if (nbs + oldsz + j > 4 * nbs)
171 {
172 Cerr << " Review the sizing of sommets() in Trianguler_fin " << finl;
173 exit();
174 }
175 sommets.resize(nbs + oldsz + j, dimension);
176 les_elems.ref(new_elems);
177
178 // Reconstruction de l'octree
179 Cerr << "We have split the rectangles..." << finl;
180 dom.invalide_octree();
181 dom.typer("Triangle");
182 Cerr << " Reconstruction of the Octree" << finl;
183 dom.construit_octree();
184 Cerr << " Octree rebuilt" << finl;
185
186 Cerr << "Splitting of the boundaries" << finl;
187 for (auto &itr : dom.faces_bord())
188 {
189 Faces& les_faces = itr.faces();
190 les_faces.typer(Type_Face::segment_2D);
191 IntTab& sommetsfaces = les_faces.les_sommets();
192 int nb_faces = sommetsfaces.dimension(0);
193 IntTab nouveaux(2 * nb_faces, 2);
194 les_faces.voisins().resize(2 * nb_faces, 2);
195 les_faces.voisins() = -1;
196
197 for (int i = 0; i < nb_faces; i++)
198 {
199 int i0 = sommetsfaces(i, 0);
200 int i1 = sommetsfaces(i, 1);
201 int i01 = -1;
202 for (int ii = 0; ii < nbs + oldsz + j; ii++)
203 if (fait_sommet_arete(ii, 0) == i0 && fait_sommet_arete(ii, 1) == i1)
204 i01 = nbs + oldsz + ii;
205 assert(i01 >= 0);
206 nouveaux(2 * i, 0) = i0;
207 nouveaux(2 * i, 1) = i01;
208 nouveaux(2 * i + 1, 0) = i01;
209 nouveaux(2 * i + 1, 1) = i1;
210 }
211 sommetsfaces.ref(nouveaux);
212 }
213
214 Cerr << "Splitting of the connectors" << finl;
215 for (auto &itr : dom.faces_raccord())
216 {
217 Faces& les_faces = itr->faces();
218 les_faces.typer(Type_Face::segment_2D);
219 IntTab& sommetsfaces = les_faces.les_sommets();
220 int nb_faces = sommetsfaces.dimension(0);
221 IntTab nouveaux(2 * nb_faces, 2);
222 les_faces.voisins().resize(2 * nb_faces, 2);
223 les_faces.voisins() = -1;
224
225 for (int i = 0; i < nb_faces; i++)
226 {
227 int i0 = sommetsfaces(i, 0);
228 int i1 = sommetsfaces(i, 1);
229 int i01 = -1;
230 for (int ii = 0; ii < nbs + oldsz + j; ii++)
231 if (fait_sommet_arete(ii, 0) == i0 && fait_sommet_arete(ii, 1) == i1)
232 i01 = nbs + oldsz + ii;
233 assert(i01 >= 0);
234 nouveaux(2 * i, 0) = i0;
235 nouveaux(2 * i, 1) = i01;
236 nouveaux(2 * i + 1, 0) = i01;
237 nouveaux(2 * i + 1, 1) = i1;
238 }
239 sommetsfaces.ref(nouveaux);
240 }
241
242 Cerr << "Splitting of the internal boundary faces" << finl;
243 for (auto &itr : dom.bords_int())
244 {
245 Faces& les_faces = itr.faces();
246 les_faces.typer(Type_Face::segment_2D);
247 IntTab& sommetsfaces = les_faces.les_sommets();
248 int nb_faces = sommetsfaces.dimension(0);
249 IntTab nouveaux(2 * nb_faces, 2);
250 les_faces.voisins().resize(2 * nb_faces, 2);
251 les_faces.voisins() = -1;
252
253 for (int i = 0; i < nb_faces; i++)
254 {
255 int i0 = sommetsfaces(i, 0);
256 int i1 = sommetsfaces(i, 1);
257 int i01 = -1;
258 for (int ii = 0; ii < nbs + oldsz + j; ii++)
259 if (fait_sommet_arete(ii, 0) == i0 && fait_sommet_arete(ii, 1) == i1)
260 i01 = nbs + oldsz + ii;
261 assert(i01 >= 0);
262 nouveaux(2 * i, 0) = i0;
263 nouveaux(2 * i, 1) = i01;
264 nouveaux(2 * i + 1, 0) = i01;
265 nouveaux(2 * i + 1, 1) = i1;
266 }
267 sommetsfaces.ref(nouveaux);
268 }
269
270 Cerr << "Splitting of the group of faces" << finl;
271 for (auto &itr : dom.groupes_faces())
272 {
273 Faces& les_faces = itr.faces();
274 les_faces.typer(Type_Face::segment_2D);
275 IntTab& sommetsfaces = les_faces.les_sommets();
276 int nb_faces = sommetsfaces.dimension(0);
277 IntTab nouveaux(2 * nb_faces, 2);
278 les_faces.voisins().resize(2 * nb_faces, 2);
279 les_faces.voisins() = -1;
280
281 for (int i = 0; i < nb_faces; i++)
282 {
283 int i0 = sommetsfaces(i, 0);
284 int i1 = sommetsfaces(i, 1);
285 int i01 = -1;
286 for (int ii = 0; ii < nbs + oldsz + j; ii++)
287 if (fait_sommet_arete(ii, 0) == i0 && fait_sommet_arete(ii, 1) == i1)
288 i01 = nbs + oldsz + ii;
289 assert(i01 >= 0);
290 nouveaux(2 * i, 0) = i0;
291 nouveaux(2 * i, 1) = i01;
292 nouveaux(2 * i + 1, 0) = i01;
293 nouveaux(2 * i + 1, 1) = i1;
294 }
295 sommetsfaces.ref(nouveaux);
296 }
297 }
298 else
299 {
300 Cerr << "We do not yet know how to Trianguler_fin the " << dom.type_elem()->que_suis_je() << "s" << finl;
302 }
303}
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
Raccords_t & faces_raccord()
Definition Domaine.h:253
IntTab_t & les_elems()
Definition Domaine.h:129
void invalide_octree()
Definition Domaine.cpp:810
Bords_Internes_t & bords_int()
Definition Domaine.h:213
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
Groupes_Faces_t & groupes_faces()
Definition Domaine.h:224
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
IntTab_t & voisins()
Renvoie le tableau des voisins (des faces).
Definition Faces.h:89
const IntTab_t & les_sommets() const
Renvoie le tableau des sommets de toutes les faces.
Definition Faces.h:74
void mettre_a_jour_sous_domaine(Domaine_t &domaine, int_t &elem, int_t num_premier_elem, int_t nb_elem) const
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
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
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
Triangulation_base Classe destinee a factoriser l'action de triangulation des interpretes.
Classe Trianguler_fin Cette classe est un interprete qui sert a lire et executer.
void trianguler(Domaine &) const override
Triangule tous les element d'un domaine: transforme les elements goemetriques du domaine en triangles...