Salome HOME
Copyrights update
[modules/med.git] / src / INTERPOLATION / MEDMEM_WrapperMesh.hxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
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.
8 // 
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.
13 //
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
17 //
18 // See http://www.salome-platform.org/
19 //
20 #ifndef MEDMEM_WRAPPER_MESH_HXX
21 #define MEDMEM_WRAPPER_MESH_HXX
22
23 #include "MEDMEM_WrapperCells.hxx"
24
25 #include "stdio.h"
26 #include "stdlib.h"
27
28 #include <vector>
29
30 #ifndef UNDEFINED
31 #define UNDEFINED -1
32 #endif
33
34 #ifndef FAUX
35 #define FAUX 0
36 #endif
37
38 #ifndef VRAI
39 #define VRAI 1
40 #endif
41
42 //////////////////////////////////////////////////////////////////
43 ///                                                            ///
44 ///                        DECLARATIONS                        ///
45 ///                                                            ///
46 //////////////////////////////////////////////////////////////////
47
48 /*********************************************************/
49 /*                                                       */
50 /*                   Wrapper_Maillage                    */
51 /*                                                       */
52 /*********************************************************/
53
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
58
59 // la version utilisée dans MEDMEMOIRE est dé-templatifiée dans MEDMEM_InterpolationHighLevelObject.hxx
60
61 template <class NUAGEMAILLE> class Wrapper_Maillage
62 {
63 protected : 
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;
67         
68         int nbr_noeuds;
69         
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;
77         
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;
84
85         // Méthode privée
86         // construit le tableau mailles_contenant_noeud
87         void Construit_Contenant_Noeud();
88         
89 public :
90
91         Wrapper_Maillage():mailles(NULL) {}
92         // Construit les Connectivités du maillage à la construction
93         Wrapper_Maillage(NUAGEMAILLE * fs, int nn);
94         ~Wrapper_Maillage() {}
95         
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();
103
104 };
105
106 //////////////////////////////////////////////////////////////////
107 ///                                                            ///
108 ///                            CODE                            ///
109 ///                                                            ///
110 //////////////////////////////////////////////////////////////////
111
112 template <class NUAGEMAILLE> int Wrapper_Maillage<NUAGEMAILLE>::DONNE_PREMIERE_MAILLE_CONTENANT(int num_noeud) const
113         {
114         return mailles_contenant_noeud[num_noeud][0];
115         }
116 template <class NUAGEMAILLE> int Wrapper_Maillage<NUAGEMAILLE>::DONNE_VOISIN_DE_MAILLE(int num_maille,int num_face) const
117         {
118         return voisins_de_maille[num_maille][num_face];
119         }
120 template <class NUAGEMAILLE> int Wrapper_Maillage<NUAGEMAILLE>::EST_AU_BORD_FACE_DE_MAILLE(int num_maille,int num_face) const
121         {
122         return face_au_bord[faces_contenues[num_maille][num_face]];
123         }
124 template <class NUAGEMAILLE> int Wrapper_Maillage<NUAGEMAILLE>::DONNE_NBR_FACES_MAILLE(int num_maille)
125         {
126         return (*mailles)[num_maille].DONNE_NBR_FACES();
127         }
128 template <class NUAGEMAILLE> NUAGEMAILLE * Wrapper_Maillage<NUAGEMAILLE>::DONNE_POINTEUR_NUAGEMAILLE()
129         {
130         return mailles;
131         }
132 template <class NUAGEMAILLE> void Wrapper_Maillage<NUAGEMAILLE>::Construit_Contenant_Noeud()
133         {
134         int nbr_noeuds_maille;
135         int num,num_noeud,num_maille;
136         
137         mailles_contenant_noeud.resize(nbr_noeuds);
138         
139         // parcours le tableau des mailles, puis les sommets de chaque maille
140         // et utilise un push_back pour renseigner mailles_contenant_noeud
141                 
142         for (num_maille=0;num_maille<mailles->SIZE();num_maille++)
143                 {
144                 nbr_noeuds_maille=(*mailles)[num_maille].DONNE_NBR_NOEUDS();
145                 for (num_noeud=0;num_noeud<nbr_noeuds_maille;num_noeud++) 
146                         {
147                         num=(*mailles)[num_maille][num_noeud];
148                         mailles_contenant_noeud[num].push_back(num_maille);
149                         }
150                 }       
151
152         }
153 template <class NUAGEMAILLE> Wrapper_Maillage<NUAGEMAILLE>::Wrapper_Maillage(NUAGEMAILLE * fs,int nn)
154         {
155         
156         if (fs) mailles=fs;
157         else
158                 {
159                 cerr<<"Wrapper_Maillage : Nuage mailles vide passé en argument"<<endl;
160                 exit(-1);
161                 }
162                 
163         int i,j;
164         int num_local_face;
165         int num_noeud;
166         int num_maille;
167         int ind_num_maille_sec,num_maille_sec;
168         int flag_existence;
169         int nbr_mailles=mailles->SIZE();
170         int nbr_formants=0;
171         int approx_nbr_formants=0;
172         int tmp;
173         int num_loc;
174         
175         nbr_noeuds=nn;
176         
177         voisins_de_maille.resize(nbr_mailles);
178         faces_contenues.resize(nbr_mailles);
179         maille_au_bord.resize(nbr_mailles,UNDEFINED);
180         
181         type_retour sommets_face;
182         
183         Construit_Contenant_Noeud();
184         
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
188         
189         for (num_maille=0;num_maille<nbr_mailles;num_maille++)
190                 {
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;
195                 }
196                 
197         face_au_bord.reserve(approx_nbr_formants/10);
198         
199         // algorithme principal
200         
201         // REMARQUE : les faces sont numérotées mais ne sont pas construites ni stockées
202         
203         int flag_interm;
204         
205         // on parcourt en premier lieu le nuage de maille (linéaire, en Nombre de Maille)
206         
207         for (num_maille=0;num_maille<nbr_mailles;num_maille++)
208                 {
209                 
210         // pour chaque maille, dite primaire, on parcourt ensuite ses faces (borné, par 8)
211         
212                 for (num_local_face=0;num_local_face<(*mailles)[num_maille].DONNE_NBR_FACES();num_local_face++)
213                         {
214                         num_noeud=(*mailles)[num_maille].DONNE_PREMIER_NOEUD_DE_FACE(num_local_face);
215                         flag_existence=0;
216                         (*mailles)[num_maille].DONNE_FACE(num_local_face,sommets_face);
217                         flag_interm=0;
218                         
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)
221                         
222                         for (ind_num_maille_sec=0;(flag_existence==0)&&(ind_num_maille_sec<mailles_contenant_noeud[num_noeud].size());ind_num_maille_sec++)
223                                 {
224                                 num_maille_sec=mailles_contenant_noeud[num_noeud][ind_num_maille_sec];
225                                 
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
228                                 
229                                 if (num_maille_sec>num_maille)
230                                         {
231                                         flag_interm=1;
232                                         
233         // pour cette maille secondaire on regarde si elle contient la face primaire
234         // (borné, par 8*4=32)                  
235                                         
236                                         num_loc=(*mailles)[num_maille_sec].DONNE_NUM_LOC_FACE_EGALE_A_FORMANT(sommets_face);                                    
237                                         if (num_loc>UNDEFINED)
238                                                 {
239                                                 
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-
242                                                 
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;
249                                                 flag_existence=1;
250                                                 nbr_formants++;
251                                                 }
252                                         }
253                                 }
254                         }
255                 }
256                 
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
259         
260         int ind_num_cont,test_bord,nbr_faces_bord=0;
261         
262         // on parcourt les mailles
263         
264         for (num_maille=0;num_maille<nbr_mailles;num_maille++) 
265                 {
266                 test_bord=0;
267                 
268         // on examine les faces de cette maille dans la numérotation globale faces_contenues
269                 
270                 for (ind_num_cont=0;ind_num_cont<faces_contenues[num_maille].size();ind_num_cont++)
271                         {
272                         
273         // On regarde si tous les numéros globaux des faces sont définis
274                         
275                         if (faces_contenues[num_maille][ind_num_cont]==UNDEFINED)
276                                 {
277                                 
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-
280                                 
281                                   // MESSAGE("La maille "<<num_maille<<" est au bord via sa face "<<ind_num_cont);
282                                 test_bord=1;
283                                 faces_contenues[num_maille][ind_num_cont]=nbr_formants;
284                                 maille_au_bord[num_maille]=VRAI;
285                                 face_au_bord.push_back(VRAI);
286                                 nbr_faces_bord++;
287                                 nbr_formants++;
288                                 }
289                         }
290                         
291         // dans le cas contraire, tous les numéros sont définis, la maille n'est pas au bord
292                         
293                 if (test_bord==0)
294                         {
295                         maille_au_bord[num_maille]=FAUX;
296                         }
297                 }
298         
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
302
303         
304         int verif=0;
305         int nf,nbf=0;
306         for (i=0;i<nbr_mailles;i++) 
307                 {
308                 nf=0;
309                 for (j=0;j<faces_contenues[i].size();j++) 
310                         {
311                         if (faces_contenues[i][j]==UNDEFINED) verif++;
312                         if (voisins_de_maille[i][j]==UNDEFINED) nf++;
313                         }
314                 if (maille_au_bord[i]==UNDEFINED) cerr<<"Maille "<<i<<" non completement construite"<<endl;
315                 if (nf==faces_contenues[i].size()) nbf++;
316                 }
317                 
318         
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);   
325         }
326
327 #endif