src/INTERPOLATION/MEDMEM_WrapperMesh.hxx

Go to the documentation of this file.
00001 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00002 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00003 // 
00004 // This library is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public
00006 // License as published by the Free Software Foundation; either 
00007 // version 2.1 of the License.
00008 // 
00009 // This library is distributed in the hope that it will be useful 
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
00012 // Lesser General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU Lesser General Public  
00015 // License along with this library; if not, write to the Free Software 
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00017 //
00018 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00019 //
00020 #ifndef MEDMEM_WRAPPER_MESH_HXX
00021 #define MEDMEM_WRAPPER_MESH_HXX
00022 
00023 #include "MEDMEM_WrapperCells.hxx"
00024 
00025 #include "stdio.h"
00026 #include "stdlib.h"
00027 
00028 #include <vector>
00029 
00030 #ifndef UNDEFINED
00031 #define UNDEFINED -1
00032 #endif
00033 
00034 #ifndef FAUX
00035 #define FAUX 0
00036 #endif
00037 
00038 #ifndef VRAI
00039 #define VRAI 1
00040 #endif
00041 
00047 
00048 /*********************************************************/
00049 /*                                                       */
00050 /*                   Wrapper_Maillage                    */
00051 /*                                                       */
00052 /*********************************************************/
00053 
00054 // cette classe est à la fois un wrapper sur un nuage de maille et une classe d'algorithme
00055 // elle s'occupe de construire les liens de connexités minimums du nuage de maille
00056 // pour le transformer en maillage suffisament riche pour etre utilisé par les algorithmes de connexités
00057 // et autres méthodes nécessitant des informations de connexité sur un maillage
00058 
00059 // la version utilisée dans MEDMEMOIRE est dé-templatifiée dans MEDMEM_InterpolationHighLevelObject.hxx
00060 
00061 template <class NUAGEMAILLE> class Wrapper_Maillage
00062 {
00063 protected : 
00064      // référence vers le nuage de maille, 
00065      // voir la classe Wrapper_Nuage_Maille dans MEDMEM_WrapperCells.hxx pour la politique
00066      NUAGEMAILLE * mailles;
00067      
00068      int nbr_noeuds;
00069      
00070      // liste des numéros globaux de faces contenues dans une maille
00071      vector< vector<int> > faces_contenues;
00072      // liste des numéros globaux de mailles qui contiennent un noeud
00073      vector< vector<int> > mailles_contenant_noeud;
00074      // liste des numéros globaux de mailles voisines d'une maille donnée via une face
00075      // l'ordre du voisin dans la liste implique par quelle face dans le tableau faces_contenues il est voisin
00076      vector< vector<int> > voisins_de_maille;
00077      
00078      // liste des numéros globaux de faces qui sont au bord du maillage
00079      // Ce sont les faces qui n'ont qu'une seule maille de rattachement
00080      vector<int> face_au_bord;
00081      // liste des numéros globaux de mailles qui sont au bord
00082      // ce sont les mailles qui ont une face sans voisin
00083      vector<int> maille_au_bord;
00084 
00085      // Méthode privée
00086      // construit le tableau mailles_contenant_noeud
00087      void Construit_Contenant_Noeud();
00088      
00089 public :
00090 
00091      Wrapper_Maillage():mailles(NULL) {}
00092      // Construit les Connectivités du maillage à la construction
00093      Wrapper_Maillage(NUAGEMAILLE * fs, int nn);
00094      ~Wrapper_Maillage() {}
00095      
00096      // Méthodes de la politique
00097      inline int DONNE_NBR_FACES_MAILLE(int num_maille); 
00098      inline int DONNE_VOISIN_DE_MAILLE(int num_maille,int num_face) const;
00099      inline int EST_AU_BORD_FACE_DE_MAILLE(int num_maille,int num_face) const; 
00100      inline int DONNE_NBR_FACES(int num_maille) const;
00101      inline int DONNE_PREMIERE_MAILLE_CONTENANT(int num_noeud) const;
00102      inline NUAGEMAILLE * DONNE_POINTEUR_NUAGEMAILLE();
00103 
00104 };
00105 
00111 
00112 template <class NUAGEMAILLE> int Wrapper_Maillage<NUAGEMAILLE>::DONNE_PREMIERE_MAILLE_CONTENANT(int num_noeud) const
00113      {
00114      return mailles_contenant_noeud[num_noeud][0];
00115      }
00116 template <class NUAGEMAILLE> int Wrapper_Maillage<NUAGEMAILLE>::DONNE_VOISIN_DE_MAILLE(int num_maille,int num_face) const
00117      {
00118      return voisins_de_maille[num_maille][num_face];
00119      }
00120 template <class NUAGEMAILLE> int Wrapper_Maillage<NUAGEMAILLE>::EST_AU_BORD_FACE_DE_MAILLE(int num_maille,int num_face) const
00121      {
00122      return face_au_bord[faces_contenues[num_maille][num_face]];
00123      }
00124 template <class NUAGEMAILLE> int Wrapper_Maillage<NUAGEMAILLE>::DONNE_NBR_FACES_MAILLE(int num_maille)
00125      {
00126      return (*mailles)[num_maille].DONNE_NBR_FACES();
00127      }
00128 template <class NUAGEMAILLE> NUAGEMAILLE * Wrapper_Maillage<NUAGEMAILLE>::DONNE_POINTEUR_NUAGEMAILLE()
00129      {
00130      return mailles;
00131      }
00132 template <class NUAGEMAILLE> void Wrapper_Maillage<NUAGEMAILLE>::Construit_Contenant_Noeud()
00133      {
00134      int nbr_noeuds_maille;
00135      int num,num_noeud,num_maille;
00136      
00137      mailles_contenant_noeud.resize(nbr_noeuds);
00138      
00139      // parcours le tableau des mailles, puis les sommets de chaque maille
00140      // et utilise un push_back pour renseigner mailles_contenant_noeud
00141           
00142      for (num_maille=0;num_maille<mailles->SIZE();num_maille++)
00143           {
00144           nbr_noeuds_maille=(*mailles)[num_maille].DONNE_NBR_NOEUDS();
00145           for (num_noeud=0;num_noeud<nbr_noeuds_maille;num_noeud++) 
00146                {
00147                num=(*mailles)[num_maille][num_noeud];
00148                mailles_contenant_noeud[num].push_back(num_maille);
00149                }
00150           }    
00151 
00152      }
00153 template <class NUAGEMAILLE> Wrapper_Maillage<NUAGEMAILLE>::Wrapper_Maillage(NUAGEMAILLE * fs,int nn)
00154      {
00155      
00156      if (fs) mailles=fs;
00157      else
00158           {
00159           cerr<<"Wrapper_Maillage : Nuage mailles vide passé en argument"<<endl;
00160           exit(-1);
00161           }
00162           
00163      int i,j;
00164      int num_local_face;
00165      int num_noeud;
00166      int num_maille;
00167      int ind_num_maille_sec,num_maille_sec;
00168      int flag_existence;
00169      int nbr_mailles=mailles->SIZE();
00170      int nbr_formants=0;
00171      int approx_nbr_formants=0;
00172      int tmp;
00173      int num_loc;
00174      
00175      nbr_noeuds=nn;
00176      
00177      voisins_de_maille.resize(nbr_mailles);
00178      faces_contenues.resize(nbr_mailles);
00179      maille_au_bord.resize(nbr_mailles,UNDEFINED);
00180      
00181      type_retour sommets_face;
00182      
00183      Construit_Contenant_Noeud();
00184      
00185      // mise a taille des tableaux et calcul d'une approximation du nombre de faces
00186      // 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
00187      // on calcule cette approximation pour éviter les allocations fréquentes dues aux push_back pour des petits tableaux
00188      
00189      for (num_maille=0;num_maille<nbr_mailles;num_maille++)
00190           {
00191           tmp=(*mailles)[num_maille].DONNE_NBR_FACES();
00192           voisins_de_maille[num_maille]=vector<int>(tmp,UNDEFINED);
00193           faces_contenues[num_maille]=vector<int>(tmp,UNDEFINED);
00194           approx_nbr_formants+=tmp;
00195           }
00196           
00197      face_au_bord.reserve(approx_nbr_formants/10);
00198      
00199      // algorithme principal
00200      
00201      // REMARQUE : les faces sont numérotées mais ne sont pas construites ni stockées
00202      
00203      int flag_interm;
00204      
00205      // on parcourt en premier lieu le nuage de maille (linéaire, en Nombre de Maille)
00206      
00207      for (num_maille=0;num_maille<nbr_mailles;num_maille++)
00208           {
00209           
00210      // pour chaque maille, dite primaire, on parcourt ensuite ses faces (borné, par 8)
00211      
00212           for (num_local_face=0;num_local_face<(*mailles)[num_maille].DONNE_NBR_FACES();num_local_face++)
00213                {
00214                num_noeud=(*mailles)[num_maille].DONNE_PREMIER_NOEUD_DE_FACE(num_local_face);
00215                flag_existence=0;
00216                (*mailles)[num_maille].DONNE_FACE(num_local_face,sommets_face);
00217                flag_interm=0;
00218                
00219      // 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
00220      // (borné, par un coefficient qui dépend de l'anisotropie du maillage, le nombre maximum de maille qui contient un sommet)
00221                
00222                for (ind_num_maille_sec=0;(flag_existence==0)&&(ind_num_maille_sec<mailles_contenant_noeud[num_noeud].size());ind_num_maille_sec++)
00223                     {
00224                     num_maille_sec=mailles_contenant_noeud[num_noeud][ind_num_maille_sec];
00225                     
00226      // on teste ensuite si cette maille secondaire a un numéro plus élevé que la maille primaire, dans le cas contraire, 
00227      // ça veut dire qu'elle a déja été traitée ou sera traitée ultérieurement
00228                     
00229                     if (num_maille_sec>num_maille)
00230                          {
00231                          flag_interm=1;
00232                          
00233      // pour cette maille secondaire on regarde si elle contient la face primaire
00234      // (borné, par 8*4=32)             
00235                          
00236                          num_loc=(*mailles)[num_maille_sec].DONNE_NUM_LOC_FACE_EGALE_A_FORMANT(sommets_face);                     
00237                          if (num_loc>UNDEFINED)
00238                               {
00239                               
00240      // et dans ce cas, la maille secondaire est voisine de la maille primaire, on met à jour les tableaux
00241      // si on voulait construire le tableau des faces, c'est ici qu'il faudrait le faire -1-
00242                               
00243                                                   // MESSAGE("La maille "<<num_maille<<" a pour voisin la maille "<<num_maille_sec<<" via la face "<<nbr_formants);
00244                               face_au_bord.push_back(FAUX);
00245                               faces_contenues[num_maille][num_local_face]=nbr_formants;
00246                               voisins_de_maille[num_maille][num_local_face]=num_maille_sec;
00247                               faces_contenues[num_maille_sec][num_loc]=nbr_formants;
00248                               voisins_de_maille[num_maille_sec][num_loc]=num_maille;
00249                               flag_existence=1;
00250                               nbr_formants++;
00251                               }
00252                          }
00253                     }
00254                }
00255           }
00256           
00257      // Construction de la connexité des mailles de bord
00258      // 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
00259      
00260      int ind_num_cont,test_bord,nbr_faces_bord=0;
00261      
00262      // on parcourt les mailles
00263      
00264      for (num_maille=0;num_maille<nbr_mailles;num_maille++) 
00265           {
00266           test_bord=0;
00267           
00268      // on examine les faces de cette maille dans la numérotation globale faces_contenues
00269           
00270           for (ind_num_cont=0;ind_num_cont<faces_contenues[num_maille].size();ind_num_cont++)
00271                {
00272                
00273      // On regarde si tous les numéros globaux des faces sont définis
00274                
00275                if (faces_contenues[num_maille][ind_num_cont]==UNDEFINED)
00276                     {
00277                     
00278      // si un seul numéro n'est pas défini, la maille est au bord
00279      // si on voulait construire le tableau des faces, c'est ici qu'il faudrait le faire -2-
00280                     
00281                                   // MESSAGE("La maille "<<num_maille<<" est au bord via sa face "<<ind_num_cont);
00282                     test_bord=1;
00283                     faces_contenues[num_maille][ind_num_cont]=nbr_formants;
00284                     maille_au_bord[num_maille]=VRAI;
00285                     face_au_bord.push_back(VRAI);
00286                     nbr_faces_bord++;
00287                     nbr_formants++;
00288                     }
00289                }
00290                
00291      // dans le cas contraire, tous les numéros sont définis, la maille n'est pas au bord
00292                
00293           if (test_bord==0)
00294                {
00295                maille_au_bord[num_maille]=FAUX;
00296                }
00297           }
00298      
00299      // Vérification de la connectivité
00300      // on regarde si tous les numéros globaux sont définis
00301      // si ce n'est pas le cas, c'est que le nuage de maille est mal défini
00302 
00303      
00304      int verif=0;
00305      int nf,nbf=0;
00306      for (i=0;i<nbr_mailles;i++) 
00307           {
00308           nf=0;
00309           for (j=0;j<faces_contenues[i].size();j++) 
00310                {
00311                if (faces_contenues[i][j]==UNDEFINED) verif++;
00312                if (voisins_de_maille[i][j]==UNDEFINED) nf++;
00313                }
00314           if (maille_au_bord[i]==UNDEFINED) cerr<<"Maille "<<i<<" non completement construite"<<endl;
00315           if (nf==faces_contenues[i].size()) nbf++;
00316           }
00317           
00318      
00319      MESSAGE("IL Y A "<<verif<<" PROBLEMES A LA SUITE DE LA CONSTRUCTION DE CONNEXITE");
00320      MESSAGE("Nombre de mailles : "<<nbr_mailles);
00321      MESSAGE("Approximation du nombre de faces : "<<approx_nbr_formants);
00322      MESSAGE("Nombre réel de faces de bord : "<<nbr_faces_bord);
00323      MESSAGE("Nombre réel total de faces : "<<nbr_formants);
00324      MESSAGE("Nombre de Mailles Isolées : "<<nbf);     
00325      }
00326 
00327 #endif