1 #ifndef MEDMEM_WRAPPER_MESH_HXX
2 #define MEDMEM_WRAPPER_MESH_HXX
4 #include "MEDMEM_WrapperCells.hxx"
23 //////////////////////////////////////////////////////////////////
27 //////////////////////////////////////////////////////////////////
29 /*********************************************************/
31 /* Wrapper_Maillage */
33 /*********************************************************/
35 // cette classe est à la fois un wrapper sur un nuage de maille et une classe d'algorithme
36 // elle s'occupe de construire les liens de connexités minimums du nuage de maille
37 // pour le transformer en maillage suffisament riche pour etre utilisé par les algorithmes de connexités
38 // et autres méthodes nécessitant des informations de connexité sur un maillage
40 // la version utilisée dans MEDMEMOIRE est dé-templatifiée dans MEDMEM_InterpolationHighLevelObject.hxx
42 template <class NUAGEMAILLE> class Wrapper_Maillage
45 // référence vers le nuage de maille,
46 // voir la classe Wrapper_Nuage_Maille dans MEDMEM_WrapperCells.hxx pour la politique
47 NUAGEMAILLE * mailles;
51 // liste des numéros globaux de faces contenues dans une maille
52 vector< vector<int> > faces_contenues;
53 // liste des numéros globaux de mailles qui contiennent un noeud
54 vector< vector<int> > mailles_contenant_noeud;
55 // liste des numéros globaux de mailles voisines d'une maille donnée via une face
56 // l'ordre du voisin dans la liste implique par quelle face dans le tableau faces_contenues il est voisin
57 vector< vector<int> > voisins_de_maille;
59 // liste des numéros globaux de faces qui sont au bord du maillage
60 // Ce sont les faces qui n'ont qu'une seule maille de rattachement
61 vector<int> face_au_bord;
62 // liste des numéros globaux de mailles qui sont au bord
63 // ce sont les mailles qui ont une face sans voisin
64 vector<int> maille_au_bord;
67 // construit le tableau mailles_contenant_noeud
68 void Construit_Contenant_Noeud();
72 Wrapper_Maillage():mailles(NULL) {}
73 // Construit les Connectivités du maillage à la construction
74 Wrapper_Maillage(NUAGEMAILLE * fs, int nn);
75 ~Wrapper_Maillage() {}
77 // Méthodes de la politique
78 inline int DONNE_NBR_FACES_MAILLE(int num_maille);
79 inline int DONNE_VOISIN_DE_MAILLE(int num_maille,int num_face) const;
80 inline int EST_AU_BORD_FACE_DE_MAILLE(int num_maille,int num_face) const;
81 inline int DONNE_NBR_FACES(int num_maille) const;
82 inline int DONNE_PREMIERE_MAILLE_CONTENANT(int num_noeud) const;
83 inline NUAGEMAILLE * DONNE_POINTEUR_NUAGEMAILLE();
87 //////////////////////////////////////////////////////////////////
91 //////////////////////////////////////////////////////////////////
93 template <class NUAGEMAILLE> int Wrapper_Maillage<NUAGEMAILLE>::DONNE_PREMIERE_MAILLE_CONTENANT(int num_noeud) const
95 return mailles_contenant_noeud[num_noeud][0];
97 template <class NUAGEMAILLE> int Wrapper_Maillage<NUAGEMAILLE>::DONNE_VOISIN_DE_MAILLE(int num_maille,int num_face) const
99 return voisins_de_maille[num_maille][num_face];
101 template <class NUAGEMAILLE> int Wrapper_Maillage<NUAGEMAILLE>::EST_AU_BORD_FACE_DE_MAILLE(int num_maille,int num_face) const
103 return face_au_bord[faces_contenues[num_maille][num_face]];
105 template <class NUAGEMAILLE> int Wrapper_Maillage<NUAGEMAILLE>::DONNE_NBR_FACES_MAILLE(int num_maille)
107 return (*mailles)[num_maille].DONNE_NBR_FACES();
109 template <class NUAGEMAILLE> NUAGEMAILLE * Wrapper_Maillage<NUAGEMAILLE>::DONNE_POINTEUR_NUAGEMAILLE()
113 template <class NUAGEMAILLE> void Wrapper_Maillage<NUAGEMAILLE>::Construit_Contenant_Noeud()
115 int nbr_noeuds_maille;
116 int num,num_noeud,num_maille;
118 mailles_contenant_noeud.resize(nbr_noeuds);
120 // parcours le tableau des mailles, puis les sommets de chaque maille
121 // et utilise un push_back pour renseigner mailles_contenant_noeud
123 for (num_maille=0;num_maille<mailles->SIZE();num_maille++)
125 nbr_noeuds_maille=(*mailles)[num_maille].DONNE_NBR_NOEUDS();
126 for (num_noeud=0;num_noeud<nbr_noeuds_maille;num_noeud++)
128 num=(*mailles)[num_maille][num_noeud];
129 mailles_contenant_noeud[num].push_back(num_maille);
134 template <class NUAGEMAILLE> Wrapper_Maillage<NUAGEMAILLE>::Wrapper_Maillage(NUAGEMAILLE * fs,int nn)
140 cerr<<"Wrapper_Maillage : Nuage mailles vide passé en argument"<<endl;
148 int ind_num_maille_sec,num_maille_sec;
150 int nbr_mailles=mailles->SIZE();
152 int approx_nbr_formants=0;
158 voisins_de_maille.resize(nbr_mailles);
159 faces_contenues.resize(nbr_mailles);
160 maille_au_bord.resize(nbr_mailles,UNDEFINED);
162 type_retour sommets_face;
164 Construit_Contenant_Noeud();
166 // mise a taille des tableaux et calcul d'une approximation du nombre de faces
167 // 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
168 // on calcule cette approximation pour éviter les allocations fréquentes dues aux push_back pour des petits tableaux
170 for (num_maille=0;num_maille<nbr_mailles;num_maille++)
172 tmp=(*mailles)[num_maille].DONNE_NBR_FACES();
173 voisins_de_maille[num_maille]=vector<int>(tmp,UNDEFINED);
174 faces_contenues[num_maille]=vector<int>(tmp,UNDEFINED);
175 approx_nbr_formants+=tmp;
178 face_au_bord.reserve(approx_nbr_formants/10);
180 // algorithme principal
182 // REMARQUE : les faces sont numérotées mais ne sont pas construites ni stockées
186 // on parcourt en premier lieu le nuage de maille (linéaire, en Nombre de Maille)
188 for (num_maille=0;num_maille<nbr_mailles;num_maille++)
191 // pour chaque maille, dite primaire, on parcourt ensuite ses faces (borné, par 8)
193 for (num_local_face=0;num_local_face<(*mailles)[num_maille].DONNE_NBR_FACES();num_local_face++)
195 num_noeud=(*mailles)[num_maille].DONNE_PREMIER_NOEUD_DE_FACE(num_local_face);
197 (*mailles)[num_maille].DONNE_FACE(num_local_face,sommets_face);
200 // 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
201 // (borné, par un coefficient qui dépend de l'anisotropie du maillage, le nombre maximum de maille qui contient un sommet)
203 for (ind_num_maille_sec=0;(flag_existence==0)&&(ind_num_maille_sec<mailles_contenant_noeud[num_noeud].size());ind_num_maille_sec++)
205 num_maille_sec=mailles_contenant_noeud[num_noeud][ind_num_maille_sec];
207 // on teste ensuite si cette maille secondaire a un numéro plus élevé que la maille primaire, dans le cas contraire,
208 // ça veut dire qu'elle a déja été traitée ou sera traitée ultérieurement
210 if (num_maille_sec>num_maille)
214 // pour cette maille secondaire on regarde si elle contient la face primaire
215 // (borné, par 8*4=32)
217 num_loc=(*mailles)[num_maille_sec].DONNE_NUM_LOC_FACE_EGALE_A_FORMANT(sommets_face);
218 if (num_loc>UNDEFINED)
221 // et dans ce cas, la maille secondaire est voisine de la maille primaire, on met à jour les tableaux
222 // si on voulait construire le tableau des faces, c'est ici qu'il faudrait le faire -1-
224 // MESSAGE("La maille "<<num_maille<<" a pour voisin la maille "<<num_maille_sec<<" via la face "<<nbr_formants);
225 face_au_bord.push_back(FAUX);
226 faces_contenues[num_maille][num_local_face]=nbr_formants;
227 voisins_de_maille[num_maille][num_local_face]=num_maille_sec;
228 faces_contenues[num_maille_sec][num_loc]=nbr_formants;
229 voisins_de_maille[num_maille_sec][num_loc]=num_maille;
238 // Construction de la connexité des mailles de bord
239 // 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
241 int ind_num_cont,test_bord,nbr_faces_bord=0;
243 // on parcourt les mailles
245 for (num_maille=0;num_maille<nbr_mailles;num_maille++)
249 // on examine les faces de cette maille dans la numérotation globale faces_contenues
251 for (ind_num_cont=0;ind_num_cont<faces_contenues[num_maille].size();ind_num_cont++)
254 // On regarde si tous les numéros globaux des faces sont définis
256 if (faces_contenues[num_maille][ind_num_cont]==UNDEFINED)
259 // si un seul numéro n'est pas défini, la maille est au bord
260 // si on voulait construire le tableau des faces, c'est ici qu'il faudrait le faire -2-
262 // MESSAGE("La maille "<<num_maille<<" est au bord via sa face "<<ind_num_cont);
264 faces_contenues[num_maille][ind_num_cont]=nbr_formants;
265 maille_au_bord[num_maille]=VRAI;
266 face_au_bord.push_back(VRAI);
272 // dans le cas contraire, tous les numéros sont définis, la maille n'est pas au bord
276 maille_au_bord[num_maille]=FAUX;
280 // Vérification de la connectivité
281 // on regarde si tous les numéros globaux sont définis
282 // si ce n'est pas le cas, c'est que le nuage de maille est mal défini
287 for (i=0;i<nbr_mailles;i++)
290 for (j=0;j<faces_contenues[i].size();j++)
292 if (faces_contenues[i][j]==UNDEFINED) verif++;
293 if (voisins_de_maille[i][j]==UNDEFINED) nf++;
295 if (maille_au_bord[i]==UNDEFINED) cerr<<"Maille "<<i<<" non completement construite"<<endl;
296 if (nf==faces_contenues[i].size()) nbf++;
300 MESSAGE("IL Y A "<<verif<<" PROBLEMES A LA SUITE DE LA CONSTRUCTION DE CONNEXITE");
301 MESSAGE("Nombre de mailles : "<<nbr_mailles);
302 MESSAGE("Approximation du nombre de faces : "<<approx_nbr_formants);
303 MESSAGE("Nombre réel de faces de bord : "<<nbr_faces_bord);
304 MESSAGE("Nombre réel total de faces : "<<nbr_formants);
305 MESSAGE("Nombre de Mailles Isolées : "<<nbf);