1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/
20 #ifndef MEDMEM_WRAPPER_MESH_HXX
21 #define MEDMEM_WRAPPER_MESH_HXX
23 #include "MEDMEM_WrapperCells.hxx"
42 //////////////////////////////////////////////////////////////////
46 //////////////////////////////////////////////////////////////////
48 /*********************************************************/
50 /* Wrapper_Maillage */
52 /*********************************************************/
54 // cette classe est à la fois un wrapper sur un nuage de maille et une classe d'algorithme
55 // elle s'occupe de construire les liens de connexités minimums du nuage de maille
56 // pour le transformer en maillage suffisament riche pour etre utilisé par les algorithmes de connexités
57 // et autres méthodes nécessitant des informations de connexité sur un maillage
59 // la version utilisée dans MEDMEMOIRE est dé-templatifiée dans MEDMEM_InterpolationHighLevelObject.hxx
61 template <class NUAGEMAILLE> class Wrapper_Maillage
64 // référence vers le nuage de maille,
65 // voir la classe Wrapper_Nuage_Maille dans MEDMEM_WrapperCells.hxx pour la politique
66 NUAGEMAILLE * mailles;
70 // liste des numéros globaux de faces contenues dans une maille
71 vector< vector<int> > faces_contenues;
72 // liste des numéros globaux de mailles qui contiennent un noeud
73 vector< vector<int> > mailles_contenant_noeud;
74 // liste des numéros globaux de mailles voisines d'une maille donnée via une face
75 // l'ordre du voisin dans la liste implique par quelle face dans le tableau faces_contenues il est voisin
76 vector< vector<int> > voisins_de_maille;
78 // liste des numéros globaux de faces qui sont au bord du maillage
79 // Ce sont les faces qui n'ont qu'une seule maille de rattachement
80 vector<int> face_au_bord;
81 // liste des numéros globaux de mailles qui sont au bord
82 // ce sont les mailles qui ont une face sans voisin
83 vector<int> maille_au_bord;
86 // construit le tableau mailles_contenant_noeud
87 void Construit_Contenant_Noeud();
91 Wrapper_Maillage():mailles(NULL) {}
92 // Construit les Connectivités du maillage à la construction
93 Wrapper_Maillage(NUAGEMAILLE * fs, int nn);
94 ~Wrapper_Maillage() {}
96 // Méthodes de la politique
97 inline int DONNE_NBR_FACES_MAILLE(int num_maille);
98 inline int DONNE_VOISIN_DE_MAILLE(int num_maille,int num_face) const;
99 inline int EST_AU_BORD_FACE_DE_MAILLE(int num_maille,int num_face) const;
100 inline int DONNE_NBR_FACES(int num_maille) const;
101 inline int DONNE_PREMIERE_MAILLE_CONTENANT(int num_noeud) const;
102 inline NUAGEMAILLE * DONNE_POINTEUR_NUAGEMAILLE();
106 //////////////////////////////////////////////////////////////////
110 //////////////////////////////////////////////////////////////////
112 template <class NUAGEMAILLE> int Wrapper_Maillage<NUAGEMAILLE>::DONNE_PREMIERE_MAILLE_CONTENANT(int num_noeud) const
114 return mailles_contenant_noeud[num_noeud][0];
116 template <class NUAGEMAILLE> int Wrapper_Maillage<NUAGEMAILLE>::DONNE_VOISIN_DE_MAILLE(int num_maille,int num_face) const
118 return voisins_de_maille[num_maille][num_face];
120 template <class NUAGEMAILLE> int Wrapper_Maillage<NUAGEMAILLE>::EST_AU_BORD_FACE_DE_MAILLE(int num_maille,int num_face) const
122 return face_au_bord[faces_contenues[num_maille][num_face]];
124 template <class NUAGEMAILLE> int Wrapper_Maillage<NUAGEMAILLE>::DONNE_NBR_FACES_MAILLE(int num_maille)
126 return (*mailles)[num_maille].DONNE_NBR_FACES();
128 template <class NUAGEMAILLE> NUAGEMAILLE * Wrapper_Maillage<NUAGEMAILLE>::DONNE_POINTEUR_NUAGEMAILLE()
132 template <class NUAGEMAILLE> void Wrapper_Maillage<NUAGEMAILLE>::Construit_Contenant_Noeud()
134 int nbr_noeuds_maille;
135 int num,num_noeud,num_maille;
137 mailles_contenant_noeud.resize(nbr_noeuds);
139 // parcours le tableau des mailles, puis les sommets de chaque maille
140 // et utilise un push_back pour renseigner mailles_contenant_noeud
142 for (num_maille=0;num_maille<mailles->SIZE();num_maille++)
144 nbr_noeuds_maille=(*mailles)[num_maille].DONNE_NBR_NOEUDS();
145 for (num_noeud=0;num_noeud<nbr_noeuds_maille;num_noeud++)
147 num=(*mailles)[num_maille][num_noeud];
148 mailles_contenant_noeud[num].push_back(num_maille);
153 template <class NUAGEMAILLE> Wrapper_Maillage<NUAGEMAILLE>::Wrapper_Maillage(NUAGEMAILLE * fs,int nn)
159 cerr<<"Wrapper_Maillage : Nuage mailles vide passé en argument"<<endl;
167 int ind_num_maille_sec,num_maille_sec;
169 int nbr_mailles=mailles->SIZE();
171 int approx_nbr_formants=0;
177 voisins_de_maille.resize(nbr_mailles);
178 faces_contenues.resize(nbr_mailles);
179 maille_au_bord.resize(nbr_mailles,UNDEFINED);
181 type_retour sommets_face;
183 Construit_Contenant_Noeud();
185 // mise a taille des tableaux et calcul d'une approximation du nombre de faces
186 // on postule que le nombre de faces réel est le dixieme de la somme du nombre de faces par maille sur toutes les mailles
187 // on calcule cette approximation pour éviter les allocations fréquentes dues aux push_back pour des petits tableaux
189 for (num_maille=0;num_maille<nbr_mailles;num_maille++)
191 tmp=(*mailles)[num_maille].DONNE_NBR_FACES();
192 voisins_de_maille[num_maille]=vector<int>(tmp,UNDEFINED);
193 faces_contenues[num_maille]=vector<int>(tmp,UNDEFINED);
194 approx_nbr_formants+=tmp;
197 face_au_bord.reserve(approx_nbr_formants/10);
199 // algorithme principal
201 // REMARQUE : les faces sont numérotées mais ne sont pas construites ni stockées
205 // on parcourt en premier lieu le nuage de maille (linéaire, en Nombre de Maille)
207 for (num_maille=0;num_maille<nbr_mailles;num_maille++)
210 // pour chaque maille, dite primaire, on parcourt ensuite ses faces (borné, par 8)
212 for (num_local_face=0;num_local_face<(*mailles)[num_maille].DONNE_NBR_FACES();num_local_face++)
214 num_noeud=(*mailles)[num_maille].DONNE_PREMIER_NOEUD_DE_FACE(num_local_face);
216 (*mailles)[num_maille].DONNE_FACE(num_local_face,sommets_face);
219 // pour chaque face, dite primaire, on prend le premier noeud, et on parcourt les mailles qui contiennent ce noeud tant qu'on n'a pas trouvé de voisin
220 // (borné, par un coefficient qui dépend de l'anisotropie du maillage, le nombre maximum de maille qui contient un sommet)
222 for (ind_num_maille_sec=0;(flag_existence==0)&&(ind_num_maille_sec<mailles_contenant_noeud[num_noeud].size());ind_num_maille_sec++)
224 num_maille_sec=mailles_contenant_noeud[num_noeud][ind_num_maille_sec];
226 // on teste ensuite si cette maille secondaire a un numéro plus élevé que la maille primaire, dans le cas contraire,
227 // ça veut dire qu'elle a déja été traitée ou sera traitée ultérieurement
229 if (num_maille_sec>num_maille)
233 // pour cette maille secondaire on regarde si elle contient la face primaire
234 // (borné, par 8*4=32)
236 num_loc=(*mailles)[num_maille_sec].DONNE_NUM_LOC_FACE_EGALE_A_FORMANT(sommets_face);
237 if (num_loc>UNDEFINED)
240 // et dans ce cas, la maille secondaire est voisine de la maille primaire, on met à jour les tableaux
241 // si on voulait construire le tableau des faces, c'est ici qu'il faudrait le faire -1-
243 // MESSAGE("La maille "<<num_maille<<" a pour voisin la maille "<<num_maille_sec<<" via la face "<<nbr_formants);
244 face_au_bord.push_back(FAUX);
245 faces_contenues[num_maille][num_local_face]=nbr_formants;
246 voisins_de_maille[num_maille][num_local_face]=num_maille_sec;
247 faces_contenues[num_maille_sec][num_loc]=nbr_formants;
248 voisins_de_maille[num_maille_sec][num_loc]=num_maille;
257 // Construction de la connexité des mailles de bord
258 // A ce stade, on n'a que la connexité du voisinage des mailles, et les faces de bord n'ont pas été numérotées
260 int ind_num_cont,test_bord,nbr_faces_bord=0;
262 // on parcourt les mailles
264 for (num_maille=0;num_maille<nbr_mailles;num_maille++)
268 // on examine les faces de cette maille dans la numérotation globale faces_contenues
270 for (ind_num_cont=0;ind_num_cont<faces_contenues[num_maille].size();ind_num_cont++)
273 // On regarde si tous les numéros globaux des faces sont définis
275 if (faces_contenues[num_maille][ind_num_cont]==UNDEFINED)
278 // si un seul numéro n'est pas défini, la maille est au bord
279 // si on voulait construire le tableau des faces, c'est ici qu'il faudrait le faire -2-
281 // MESSAGE("La maille "<<num_maille<<" est au bord via sa face "<<ind_num_cont);
283 faces_contenues[num_maille][ind_num_cont]=nbr_formants;
284 maille_au_bord[num_maille]=VRAI;
285 face_au_bord.push_back(VRAI);
291 // dans le cas contraire, tous les numéros sont définis, la maille n'est pas au bord
295 maille_au_bord[num_maille]=FAUX;
299 // Vérification de la connectivité
300 // on regarde si tous les numéros globaux sont définis
301 // si ce n'est pas le cas, c'est que le nuage de maille est mal défini
306 for (i=0;i<nbr_mailles;i++)
309 for (j=0;j<faces_contenues[i].size();j++)
311 if (faces_contenues[i][j]==UNDEFINED) verif++;
312 if (voisins_de_maille[i][j]==UNDEFINED) nf++;
314 if (maille_au_bord[i]==UNDEFINED) cerr<<"Maille "<<i<<" non completement construite"<<endl;
315 if (nf==faces_contenues[i].size()) nbf++;
319 MESSAGE("IL Y A "<<verif<<" PROBLEMES A LA SUITE DE LA CONSTRUCTION DE CONNEXITE");
320 MESSAGE("Nombre de mailles : "<<nbr_mailles);
321 MESSAGE("Approximation du nombre de faces : "<<approx_nbr_formants);
322 MESSAGE("Nombre réel de faces de bord : "<<nbr_faces_bord);
323 MESSAGE("Nombre réel total de faces : "<<nbr_formants);
324 MESSAGE("Nombre de Mailles Isolées : "<<nbf);