]> SALOME platform Git repositories - modules/med.git/blob - src/MEDMEM/INTERPOLATION/MEDMEM_WrapperMesh.hxx
Salome HOME
DCQ : Merge with Ecole Ete a6.
[modules/med.git] / src / MEDMEM / INTERPOLATION / MEDMEM_WrapperMesh.hxx
1 #ifndef MEDMEM_WRAPPER_MESH_HXX
2 #define MEDMEM_WRAPPER_MESH_HXX
3
4 #include "MEDMEM_WrapperCells.hxx"
5
6 #include "stdio.h"
7 #include "stdlib.h"
8
9 #include <vector>
10
11 #ifndef UNDEFINED
12 #define UNDEFINED -1
13 #endif
14
15 #ifndef FAUX
16 #define FAUX 0
17 #endif
18
19 #ifndef VRAI
20 #define VRAI 1
21 #endif
22
23 //////////////////////////////////////////////////////////////////
24 ///                                                            ///
25 ///                        DECLARATIONS                        ///
26 ///                                                            ///
27 //////////////////////////////////////////////////////////////////
28
29 /*********************************************************/
30 /*                                                       */
31 /*                   Wrapper_Maillage                    */
32 /*                                                       */
33 /*********************************************************/
34
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
39
40 // la version utilisée dans MEDMEMOIRE est dé-templatifiée dans MEDMEM_InterpolationHighLevelObject.hxx
41
42 template <class NUAGEMAILLE> class Wrapper_Maillage
43 {
44 protected : 
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;
48         
49         int nbr_noeuds;
50         
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;
58         
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;
65
66         // Méthode privée
67         // construit le tableau mailles_contenant_noeud
68         void Construit_Contenant_Noeud();
69         
70 public :
71
72         Wrapper_Maillage():mailles(NULL) {}
73         // Construit les Connectivités du maillage à la construction
74         Wrapper_Maillage(NUAGEMAILLE * fs, int nn);
75         ~Wrapper_Maillage() {}
76         
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();
84
85 };
86
87 //////////////////////////////////////////////////////////////////
88 ///                                                            ///
89 ///                            CODE                            ///
90 ///                                                            ///
91 //////////////////////////////////////////////////////////////////
92
93 template <class NUAGEMAILLE> int Wrapper_Maillage<NUAGEMAILLE>::DONNE_PREMIERE_MAILLE_CONTENANT(int num_noeud) const
94         {
95         return mailles_contenant_noeud[num_noeud][0];
96         }
97 template <class NUAGEMAILLE> int Wrapper_Maillage<NUAGEMAILLE>::DONNE_VOISIN_DE_MAILLE(int num_maille,int num_face) const
98         {
99         return voisins_de_maille[num_maille][num_face];
100         }
101 template <class NUAGEMAILLE> int Wrapper_Maillage<NUAGEMAILLE>::EST_AU_BORD_FACE_DE_MAILLE(int num_maille,int num_face) const
102         {
103         return face_au_bord[faces_contenues[num_maille][num_face]];
104         }
105 template <class NUAGEMAILLE> int Wrapper_Maillage<NUAGEMAILLE>::DONNE_NBR_FACES_MAILLE(int num_maille)
106         {
107         return (*mailles)[num_maille].DONNE_NBR_FACES();
108         }
109 template <class NUAGEMAILLE> NUAGEMAILLE * Wrapper_Maillage<NUAGEMAILLE>::DONNE_POINTEUR_NUAGEMAILLE()
110         {
111         return mailles;
112         }
113 template <class NUAGEMAILLE> void Wrapper_Maillage<NUAGEMAILLE>::Construit_Contenant_Noeud()
114         {
115         int nbr_noeuds_maille;
116         int num,num_noeud,num_maille;
117         
118         mailles_contenant_noeud.resize(nbr_noeuds);
119         
120         // parcours le tableau des mailles, puis les sommets de chaque maille
121         // et utilise un push_back pour renseigner mailles_contenant_noeud
122                 
123         for (num_maille=0;num_maille<mailles->SIZE();num_maille++)
124                 {
125                 nbr_noeuds_maille=(*mailles)[num_maille].DONNE_NBR_NOEUDS();
126                 for (num_noeud=0;num_noeud<nbr_noeuds_maille;num_noeud++) 
127                         {
128                         num=(*mailles)[num_maille][num_noeud];
129                         mailles_contenant_noeud[num].push_back(num_maille);
130                         }
131                 }       
132
133         }
134 template <class NUAGEMAILLE> Wrapper_Maillage<NUAGEMAILLE>::Wrapper_Maillage(NUAGEMAILLE * fs,int nn)
135         {
136         
137         if (fs) mailles=fs;
138         else
139                 {
140                 cerr<<"Wrapper_Maillage : Nuage mailles vide passé en argument"<<endl;
141                 exit(-1);
142                 }
143                 
144         int i,j,k;
145         int num_local_face;
146         int ind_num_noeud,num_noeud;
147         int num_maille;
148         int ind_num_maille_sec,num_maille_sec;
149         int num_local_sec;
150         int flag_existence;
151         int nbr_mailles=mailles->SIZE();
152         int nbr_formants=0;
153         int approx_nbr_formants=0;
154         int tmp;
155         int num_loc;
156         
157         nbr_noeuds=nn;
158         
159         voisins_de_maille.resize(nbr_mailles);
160         faces_contenues.resize(nbr_mailles);
161         maille_au_bord.resize(nbr_mailles,UNDEFINED);
162         
163         type_retour sommets_face;
164         
165         Construit_Contenant_Noeud();
166         
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
170         
171         for (num_maille=0;num_maille<nbr_mailles;num_maille++)
172                 {
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;
177                 }
178                 
179         face_au_bord.reserve(approx_nbr_formants/10);
180         
181         // algorithme principal
182         
183         // REMARQUE : les faces sont numérotées mais ne sont pas construites ni stockées
184         
185         int flag_interm;
186         
187         // on parcourt en premier lieu le nuage de maille (linéaire, en Nombre de Maille)
188         
189         for (num_maille=0;num_maille<nbr_mailles;num_maille++)
190                 {
191                 
192         // pour chaque maille, dite primaire, on parcourt ensuite ses faces (borné, par 8)
193         
194                 for (num_local_face=0;num_local_face<(*mailles)[num_maille].DONNE_NBR_FACES();num_local_face++)
195                         {
196                         num_noeud=(*mailles)[num_maille].DONNE_PREMIER_NOEUD_DE_FACE(num_local_face);
197                         flag_existence=0;
198                         (*mailles)[num_maille].DONNE_FACE(num_local_face,sommets_face);
199                         flag_interm=0;
200                         
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)
203                         
204                         for (ind_num_maille_sec=0;(flag_existence==0)&&(ind_num_maille_sec<mailles_contenant_noeud[num_noeud].size());ind_num_maille_sec++)
205                                 {
206                                 num_maille_sec=mailles_contenant_noeud[num_noeud][ind_num_maille_sec];
207                                 
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
210                                 
211                                 if (num_maille_sec>num_maille)
212                                         {
213                                         flag_interm=1;
214                                         
215         // pour cette maille secondaire on regarde si elle contient la face primaire
216         // (borné, par 8*4=32)                  
217                                         
218                                         num_loc=(*mailles)[num_maille_sec].DONNE_NUM_LOC_FACE_EGALE_A_FORMANT(sommets_face);                                    
219                                         if (num_loc>UNDEFINED)
220                                                 {
221                                                 
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-
224                                                 
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;
231                                                 flag_existence=1;
232                                                 nbr_formants++;
233                                                 }
234                                         }
235                                 }
236                         }
237                 }
238                 
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
241         
242         int ind_num_cont,test_bord,nbr_faces_bord=0;
243         
244         // on parcourt les mailles
245         
246         for (num_maille=0;num_maille<nbr_mailles;num_maille++) 
247                 {
248                 test_bord=0;
249                 
250         // on examine les faces de cette maille dans la numérotation globale faces_contenues
251                 
252                 for (ind_num_cont=0;ind_num_cont<faces_contenues[num_maille].size();ind_num_cont++)
253                         {
254                         
255         // On regarde si tous les numéros globaux des faces sont définis
256                         
257                         if (faces_contenues[num_maille][ind_num_cont]==UNDEFINED)
258                                 {
259                                 
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-
262                                 
263                                   // MESSAGE("La maille "<<num_maille<<" est au bord via sa face "<<ind_num_cont);
264                                 test_bord=1;
265                                 faces_contenues[num_maille][ind_num_cont]=nbr_formants;
266                                 maille_au_bord[num_maille]=VRAI;
267                                 face_au_bord.push_back(VRAI);
268                                 nbr_faces_bord++;
269                                 nbr_formants++;
270                                 }
271                         }
272                         
273         // dans le cas contraire, tous les numéros sont définis, la maille n'est pas au bord
274                         
275                 if (test_bord==0)
276                         {
277                         maille_au_bord[num_maille]=FAUX;
278                         }
279                 }
280         
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
284
285         
286         int verif=0;
287         int nf,nbf=0;
288         for (i=0;i<nbr_mailles;i++) 
289                 {
290                 nf=0;
291                 for (j=0;j<faces_contenues[i].size();j++) 
292                         {
293                         if (faces_contenues[i][j]==UNDEFINED) verif++;
294                         if (voisins_de_maille[i][j]==UNDEFINED) nf++;
295                         }
296                 if (maille_au_bord[i]==UNDEFINED) cerr<<"Maille "<<i<<" non completement construite"<<endl;
297                 if (nf==faces_contenues[i].size()) nbf++;
298                 }
299                 
300         
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);   
307         }
308
309 #endif