TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Connectivite_frontieres.cpp
1/****************************************************************************
2* Copyright (c) 2015 - 2016, 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#include <Connectivite_frontieres.h>
16#include <TRUST_Deriv.h>
17#include <Domaine_VF.h>
18#include <TRUST_Ref.h>
19#include <Array_tools.h>
20
21Implemente_instanciable(Connectivite_frontieres,"Connectivite_frontieres",Objet_U);
22
24{
25 Cerr << "Connectivite_frontieres::readOn" << finl;
26 assert(0);
28 return is;
29}
30
32{
33 Cerr << "Connectivite_frontieres::printOn" << finl;
34 assert(0);
36 return is;
37}
38
40{
41 const Nom& nom_elem = domaine_vf.domaine().type_elem()->que_suis_je();
42
43 // Definition des aretes si la face est un segment
44 static const int segment[2][2] = { { 0, -1 },
45 { 1, -1 }
46 };
47 // ... face est un triangle
48 static const int triangle[3][2] = { { 0, 1 },
49 { 1, 2 },
50 { 2, 0 }
51 };
52 // .. face est un quadrangle
53 static const int quad[4][2] = { { 0, 1 },
54 { 1, 3 },
55 { 3, 2 },
56 { 2, 0 }
57 };
58 int nb_aretes_par_face = -1;
59 const int (*tableau)[2] = 0; // Pointeur sur un tableau de 2 entiers
60
61 if (nom_elem == "Rectangle")
62 {
63 tableau = segment;
64 nb_aretes_par_face = 2;
65 }
66 else if (nom_elem == "Rectangle_2D_axi")
67 {
68 tableau = segment;
69 nb_aretes_par_face = 2;
70 }
71 else if (nom_elem == "Triangle")
72 {
73 tableau = segment;
74 nb_aretes_par_face = 2;
75 }
76 else if (nom_elem == "Tetraedre")
77 {
78 tableau = triangle;
79 nb_aretes_par_face = 3;
80 }
81 else if (nom_elem == "Hexaedre")
82 {
83 tableau = quad;
84 nb_aretes_par_face = 4;
85 }
86 else
87 {
88 Cerr << "Connectivite_frontieres::remplir_def_face_aretes\n";
89 Cerr << " Le type d'element " << nom_elem;
90 Cerr << " n'est pas reconnu !\n";
92 }
93 def_face_aretes_.resize(nb_aretes_par_face,2);
94 for (int i = 0; i < nb_aretes_par_face; i++)
95 {
96 def_face_aretes_(i,0) = tableau[i][0];
97 def_face_aretes_(i,1) = tableau[i][1];
98 }
99}
100
102{
103 refdomaine_vf_ = domaine_vf;
104
105 remplir_def_face_aretes(domaine_vf);
106 remplir_faces_voisins(domaine_vf);
107}
108
109/*! @brief Remplissage de faces_voisins_
110 *
111 */
113{
114 int i_frontiere; // Un numero de frontiere (bord, raccord ou faces internes)
115 int i;
116 const Domaine& domaine = domaine_vf.domaine();
117 const int nb_frontieres = domaine.nb_front_Cl();
118 assert(def_face_aretes_.dimension(0) > 0);
119 const int nb_aretes_par_face = def_face_aretes_.dimension(0);
120 // Nombre de faces de bord reelles
121 const int nb_faces_front = domaine.nb_faces_frontiere();
122
123 // Comptage des faces de bord virtuelles
124 int nb_faces_frontiere_virt = 0;
125 for (i_frontiere = 0; i_frontiere < nb_frontieres; i_frontiere++)
126 {
127 const ArrOfInt& liste_faces_virt =
128 domaine.frontiere(i_frontiere).get_faces_virt();
129 nb_faces_frontiere_virt += liste_faces_virt.size_array();
130 }
131
132 // Nombre total de faces
133 const int nb_faces_front_tot = nb_faces_front + nb_faces_frontiere_virt;
134
135 // Remplissage du tableau liste_faces contenant la liste de toutes les
136 // faces frontiere (reelles et virtuelles)
137 ArrOfInt liste_faces(nb_faces_front_tot);
138
139 // Faces reelles = les nb_faces_frontiere premieres faces du domaine
140 // n = nombre de faces remplies dans liste_faces
141 int n;
142 for (n = 0; n < nb_faces_front; n++)
143 liste_faces[n] = n;
144 // Maintenant, n==nb_faces_frontiere ...
145
146 // Faces virtuelles :
147 {
148 const int nb_frontieres_cl = domaine.nb_front_Cl();
149 //int i_frontiere;
150 for (i_frontiere = 0; i_frontiere < nb_frontieres_cl; i_frontiere++)
151 {
152 const Frontiere& frontiere = domaine.frontiere(i_frontiere);
153 const ArrOfInt& faces_virtuelles = frontiere.get_faces_virt();
154 const int nb_faces_frontiere = faces_virtuelles.size_array();
155 for (int ii = 0; ii < nb_faces_frontiere; ii++)
156 {
157 liste_faces[n] = faces_virtuelles[ii];
158 n++;
159 }
160 }
161 }
162
163 // Construction d'une liste d'aretes : pour chaque face frontiere,
164 // 2, 3 ou 4 aretes. Pour chaque arete, on construit une ligne du tableau les_aretes
165 // colonne 1 et 2 : numeros des deux sommets extremites, le + petit numero en premier
166 // et en 2D, colonne2 = -1
167 // colonne 3 : indice de la face adjacente a l'arete dans domaine_vf.face_voisins_
168 // colonne 4 : numero de l'arete sur la face
169
170 IntTab les_aretes(nb_faces_front_tot * nb_aretes_par_face, 4);
171 int nb_aretes = 0; // Nombre d'aretes rangees dans le tableau
172
173 {
174 const IntTab& face_sommets = domaine_vf.face_sommets();
175 int i_face; // indice de la face dans liste_faces
176
177 for (i_face = 0; i_face < nb_faces_front_tot; i_face++)
178 {
179
180 // Indice de la face a traiter dans domaine_vf.face_voisins_ :
181 const int face = liste_faces[i_face];
182
183 // Boucle sur les aretes de la face (les aretes de la face sont definie
184 // par le contenu du tableau def_face_aretes)
185 for (int i_arete = 0; i_arete < nb_aretes_par_face; i_arete++)
186 {
187 // Numeros des deux sommets de l'arete sur la face
188 int i_sommet0 = def_face_aretes_(i_arete, 0);
189 int i_sommet1 = def_face_aretes_(i_arete, 1);
190 // Numeros des deux sommets dans le domaine
191 int sommet0 = face_sommets(face, i_sommet0);
192 int sommet1 = (i_sommet1 >= 0) ? face_sommets(face, i_sommet1) : -1;
193 // On classe les deux sommets dans l'ordre croissant:
194 if (sommet1 >= 0 && sommet1 < sommet0)
195 {
196 int tmp = sommet0;
197 sommet0 = sommet1;
198 sommet1 = tmp;
199 }
200 // Les deux sommets definissent un arete, on la range dans les_aretes :
201 les_aretes(nb_aretes, 0) = sommet0;
202 les_aretes(nb_aretes, 1) = sommet1;
203 les_aretes(nb_aretes, 2) = face;
204 les_aretes(nb_aretes, 3) = i_arete;
205 nb_aretes++;
206 }
207 }
208 }
209
210 // On trie la liste d'aretes dans l'ordre lexicographique:
211 // par ordre croissant de sommet0, puis de sommet1, puis de i_face
212 assert(les_aretes.dimension(1) == 4);
213 if (nb_aretes > 0)
214 {
215 using quadruplet = std::array<int, 4>;
216 quadruplet* ptr = reinterpret_cast<quadruplet*>(les_aretes.addr());
217 std::sort(ptr, ptr+nb_aretes, [&](const quadruplet& q1, const quadruplet& q2)
218 {
219 if (q1[0] != q2[0])
220 return ( q1[0]<q2[0] );
221 if (q1[1] != q2[1])
222 return ( q1[1]<q2[1] );
223 return ( q1[2]<q2[2] );
224 });
225 }
226 // Maintenant, les aretes identiques se suivent dans le tableau.
227 // On trouve donc des couples de numeros de faces adjacentes.
228 // On remplit le tableau des faces voisines...
229
230 faces_voisins_.resize(nb_faces_front, nb_aretes_par_face);
231 faces_voisins_ = -1;
232 for (i = 0; i < nb_aretes - 1; i++)
233 {
234 // Recherche d'un couple d'aretes identiques
235 if (les_aretes(i, 0) == les_aretes(i+1, 0)
236 && les_aretes(i, 1) == les_aretes(i+1, 1))
237 {
238 const int face0 = les_aretes(i, 2);
239 const int arete0= les_aretes(i, 3);
240 const int face1 = les_aretes(i+1, 2);
241 const int arete1= les_aretes(i+1, 3);
242
243 assert(face0 != face1);
244 assert(face0 >= nb_faces_front || faces_voisins_(face0, arete0) < 0);
245 assert(face1 >= nb_faces_front || faces_voisins_(face1, arete1) < 0);
246
247 if (face0 < nb_faces_front)
248 faces_voisins_(face0, arete0) = face1;
249 if (face1 < nb_faces_front)
250 faces_voisins_(face1, arete1) = face0;
251 }
252 }
253
254 // Il ne doit pas rester de face de bord reelle sans voisin :
255 for (i = 0; i < nb_faces_front; i++)
256 {
257 for (int j = 0; j < nb_aretes_par_face; j++)
258 {
259 if (faces_voisins_(i,j) < 0)
260 {
261 Cerr << "(PE" << me();
262 Cerr << ") Erreur dans Connectivite_frontieres::associer_domaine_vf\n";
263 Cerr << " faces_voisins_(" << i << "," << j << ") < 0" << finl;
264 assert(0);
266 }
267 }
268 }
269}
void remplir_faces_voisins(const Domaine_VF &domaine_vf)
Remplissage de faces_voisins_.
void remplir_def_face_aretes(const Domaine_VF &domaine_vf)
virtual void associer_domaine_vf(const Domaine_VF &domaine_vf)
int nb_front_Cl() const
Definition Domaine.h:236
class Domaine_VF
Definition Domaine_VF.h:44
int face_sommets(int i, int j) const
renvoie le numero du ieme sommet de la face num_face.
Definition Domaine_VF.h:583
const Domaine & domaine() const
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
const ArrOfInt_t & get_faces_virt() const
Definition Frontiere.h:69
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
classe Objet_U Cette classe est la classe de base des Objets de TRUST
Definition Objet_U.h:73
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 int me()
renvoie mon rang dans le groupe de communication courant.
Definition Process.cpp:125
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
_SIZE_ size_array() const
_TYPE_ * addr()
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133