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;
146 int ind_num_noeud,num_noeud;
148 int ind_num_maille_sec,num_maille_sec;
151 int nbr_mailles=mailles->SIZE();
153 int approx_nbr_formants=0;
159 voisins_de_maille.resize(nbr_mailles);
160 faces_contenues.resize(nbr_mailles);
161 maille_au_bord.resize(nbr_mailles,UNDEFINED);
163 type_retour sommets_face;
165 Construit_Contenant_Noeud();
167 // mise a taille des tableaux et calcul d'une approximation du nombre de faces
168 // 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
169 // on calcule cette approximation pour éviter les allocations fréquentes dues aux push_back pour des petits tableaux
171 for (num_maille=0;num_maille<nbr_mailles;num_maille++)
173 tmp=(*mailles)[num_maille].DONNE_NBR_FACES();
174 voisins_de_maille[num_maille]=vector<int>(tmp,UNDEFINED);
175 faces_contenues[num_maille]=vector<int>(tmp,UNDEFINED);
176 approx_nbr_formants+=tmp;
179 face_au_bord.reserve(approx_nbr_formants/10);
181 // algorithme principal
183 // REMARQUE : les faces sont numérotées mais ne sont pas construites ni stockées
187 // on parcourt en premier lieu le nuage de maille (linéaire, en Nombre de Maille)
189 for (num_maille=0;num_maille<nbr_mailles;num_maille++)
192 // pour chaque maille, dite primaire, on parcourt ensuite ses faces (borné, par 8)
194 for (num_local_face=0;num_local_face<(*mailles)[num_maille].DONNE_NBR_FACES();num_local_face++)
196 num_noeud=(*mailles)[num_maille].DONNE_PREMIER_NOEUD_DE_FACE(num_local_face);
198 (*mailles)[num_maille].DONNE_FACE(num_local_face,sommets_face);
201 // 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
202 // (borné, par un coefficient qui dépend de l'anisotropie du maillage, le nombre maximum de maille qui contient un sommet)
204 for (ind_num_maille_sec=0;(flag_existence==0)&&(ind_num_maille_sec<mailles_contenant_noeud[num_noeud].size());ind_num_maille_sec++)
206 num_maille_sec=mailles_contenant_noeud[num_noeud][ind_num_maille_sec];
208 // on teste ensuite si cette maille secondaire a un numéro plus élevé que la maille primaire, dans le cas contraire,
209 // ça veut dire qu'elle a déja été traitée ou sera traitée ultérieurement
211 if (num_maille_sec>num_maille)
215 // pour cette maille secondaire on regarde si elle contient la face primaire
216 // (borné, par 8*4=32)
218 num_loc=(*mailles)[num_maille_sec].DONNE_NUM_LOC_FACE_EGALE_A_FORMANT(sommets_face);
219 if (num_loc>UNDEFINED)
222 // et dans ce cas, la maille secondaire est voisine de la maille primaire, on met à jour les tableaux
223 // si on voulait construire le tableau des faces, c'est ici qu'il faudrait le faire -1-
225 // MESSAGE("La maille "<<num_maille<<" a pour voisin la maille "<<num_maille_sec<<" via la face "<<nbr_formants);
226 face_au_bord.push_back(FAUX);
227 faces_contenues[num_maille][num_local_face]=nbr_formants;
228 voisins_de_maille[num_maille][num_local_face]=num_maille_sec;
229 faces_contenues[num_maille_sec][num_loc]=nbr_formants;
230 voisins_de_maille[num_maille_sec][num_loc]=num_maille;
239 // Construction de la connexité des mailles de bord
240 // 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
242 int ind_num_cont,test_bord,nbr_faces_bord=0;
244 // on parcourt les mailles
246 for (num_maille=0;num_maille<nbr_mailles;num_maille++)
250 // on examine les faces de cette maille dans la numérotation globale faces_contenues
252 for (ind_num_cont=0;ind_num_cont<faces_contenues[num_maille].size();ind_num_cont++)
255 // On regarde si tous les numéros globaux des faces sont définis
257 if (faces_contenues[num_maille][ind_num_cont]==UNDEFINED)
260 // si un seul numéro n'est pas défini, la maille est au bord
261 // si on voulait construire le tableau des faces, c'est ici qu'il faudrait le faire -2-
263 // MESSAGE("La maille "<<num_maille<<" est au bord via sa face "<<ind_num_cont);
265 faces_contenues[num_maille][ind_num_cont]=nbr_formants;
266 maille_au_bord[num_maille]=VRAI;
267 face_au_bord.push_back(VRAI);
273 // dans le cas contraire, tous les numéros sont définis, la maille n'est pas au bord
277 maille_au_bord[num_maille]=FAUX;
281 // Vérification de la connectivité
282 // on regarde si tous les numéros globaux sont définis
283 // si ce n'est pas le cas, c'est que le nuage de maille est mal défini
288 for (i=0;i<nbr_mailles;i++)
291 for (j=0;j<faces_contenues[i].size();j++)
293 if (faces_contenues[i][j]==UNDEFINED) verif++;
294 if (voisins_de_maille[i][j]==UNDEFINED) nf++;
296 if (maille_au_bord[i]==UNDEFINED) cerr<<"Maille "<<i<<" non completement construite"<<endl;
297 if (nf==faces_contenues[i].size()) nbf++;
301 MESSAGE("IL Y A "<<verif<<" PROBLEMES A LA SUITE DE LA CONSTRUCTION DE CONNEXITE");
302 MESSAGE("Nombre de mailles : "<<nbr_mailles);
303 MESSAGE("Approximation du nombre de faces : "<<approx_nbr_formants);
304 MESSAGE("Nombre réel de faces de bord : "<<nbr_faces_bord);
305 MESSAGE("Nombre réel total de faces : "<<nbr_formants);
306 MESSAGE("Nombre de Mailles Isolées : "<<nbf);