]> SALOME platform Git repositories - modules/med.git/blob - src/MEDMEM/MEDMEM_DriverTools.cxx
Salome HOME
correct a small bug appearing when using the gcc 3.2.1.
[modules/med.git] / src / MEDMEM / MEDMEM_DriverTools.cxx
1 using namespace std;
2 #include "MEDMEM_DriverTools.hxx"
3 #include "MEDMEM_STRING.hxx"
4 #include "MEDMEM_Exception.hxx"
5 #include "MEDMEM_Mesh.hxx"
6 #include "MEDMEM_Group.hxx"
7 #include <algorithm>
8 using namespace MEDMEM;
9
10
11 // Cet opérateur permet d'ordonner les mailles dans un set suivant l'ordre requis par MED
12 bool _maille::operator < (const _maille& ma) const
13 {
14     // si le type géométrique differe, la comparaison est basée dessus
15     // sinon on se base sur une comparaison des numéros de sommets 
16     if(geometricType==ma.geometricType)
17     {
18         // construction de deux vecteur temporaire contenant les numeros de sommets
19         // pour faire le tri et les comparaisons
20         size_t l=sommets.size();
21         std::vector<int> v1(l);
22         std::vector<int> v2(l);
23         for (unsigned int i=0; i!=l; ++i)
24           {
25             v1[i]=sommets[i]->second.number;
26             v2[i]=ma.sommets[i]->second.number;
27           }
28         std::sort(v1.begin(), v1.end());
29         std::sort(v2.begin(), v2.end());
30         for(std::vector<int>::const_iterator i1=v1.begin(), i2=v2.begin(); i1!=v1.end(); ++i1, ++i2)
31             if(*i1 != *i2)
32                 return *i1 < *i2;
33         return false; // cas d'égalité
34     }
35     else
36         return geometricType<ma.geometricType;
37 };
38
39
40 // retourne l'entité d'une maille en fonction de la dimension du maillage.
41 MED_EN::medEntityMesh _maille::getEntity(const int meshDimension) const throw (MEDEXCEPTION)
42 {
43   const char * LOC = "_maille::getEntity(const int meshDimension)" ;
44   BEGIN_OF(LOC);
45
46   int mailleDimension = this->dimension();
47   medEntityMesh entity;
48   if (mailleDimension == meshDimension)
49     entity = MED_CELL;
50   else
51     switch (mailleDimension)
52       {
53       case 0 :
54         entity = MED_NODE;
55         break;
56       case 1 :
57         entity = MED_EDGE;
58         break;
59       case 2 :
60         entity = MED_FACE;
61         break;
62       default :
63         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Impossible de determiner l'entite de la maille."));
64       }
65 return entity;
66
67 END_OF(LOC);
68 };
69
70 std::ostream& MEDMEM::operator << (std::ostream& os, const _maille& ma)
71 {
72     os << "maille " << ma.ordre << " (" << ma.geometricType << ") : < ";
73     std::vector< std::map<int,_noeud>::iterator >::const_iterator i=ma.sommets.begin();
74     os << (*i++)->second.number ;
75     for( ; i!=ma.sommets.end(); ++i)
76         os << ", " << (*i)->second.number;
77     os << " >";
78     return os;
79 }
80
81 std::ostream& MEDMEM::operator << (std::ostream& os, const _groupe& gr)
82 {
83     os << "--- Groupe " << gr.nom << " --- " << std::endl ;
84     os << " -> liste des sous-groupes : ";
85     for( std::list<int>::const_iterator i=gr.groupes.begin(); i!=gr.groupes.end(); ++i)
86         os << *i << " ";
87     os << std::endl << " -> liste des mailles : " << std::endl;
88     for( _groupe::mailleIter i=gr.mailles.begin(); i!=gr.mailles.end(); i++)
89         os << "    " << *(*i) << std::endl;
90     return os;
91 }
92
93 std::ostream& MEDMEM::operator << (std::ostream& os, const _noeud& no)
94 {
95     os << "noeud " << no.number << " : < ";
96     std::vector<double>::const_iterator i=no.coord.begin();
97     os << *i++ ;
98     for( ; i!=no.coord.end(); ++i)
99         os << ", " << *i;
100     os << " >";
101     return os;
102 }
103
104 std::ostream& MEDMEM::operator << (std::ostream& os, const _intermediateMED& mi)
105 {
106     os << "Set des mailles : " << std::endl;
107     for( std::set<_maille>::const_iterator i=mi.maillage.begin(); i!=mi.maillage.end(); ++i)
108         os << *i << std::endl;
109     
110     os << std::endl << "Vector des groupes : " << std::endl;
111    // for( std::vector<_groupe>::const_iterator i=mi.groupes.begin(); i!=mi.groupes.end(); ++i)
112     for (unsigned int i=0; i!=mi.groupes.size(); i++)
113       os << std::setw(3) << i << " " << mi.groupes[i] << std::endl;
114     
115     os << std::endl << "map des noeuds : " << std::endl;
116     for( std::map<int,_noeud>::const_iterator i=mi.points.begin(); i!=mi.points.end(); ++i)
117         os << i->second << std::endl;
118     return os;
119 }
120
121 void _intermediateMED::numerotationMaillage()
122 {
123     // numerotation des mailles par entité
124     int i_maille=0;
125     std::set<_maille>::iterator i=maillage.begin();
126     int dimension=i->dimension();
127     for( ; i!=maillage.end(); ++i)
128     {
129         if ( dimension!=i->dimension() ) // on change d'entite
130         {
131             dimension=i->dimension();
132             i_maille=0;
133         }
134         (*i).ordre=++i_maille;
135     }
136 }
137
138 void _intermediateMED::numerotationPoints()
139 {
140     // Fonction de renumerotation des noeuds (necessaire quand il y a des trous dans la numerotation.
141     int i_noeud=0;
142     for( std::map<int,_noeud>::const_iterator i=points.begin(); i!=points.end(); ++i)
143         i->second.number = ++i_noeud ;
144 }
145     
146
147 /*!
148  * \if developper
149  * create a MED COORDINATE from the intermediate structure.
150  * \endif
151  */
152 COORDINATE *
153 _intermediateMED::getCoordinate()
154 {
155     const medModeSwitch mode=MED_FULL_INTERLACE;
156     const string coordinateSystem="CARTESIAN";
157
158     int spaceDimension=points.begin()->second.coord.size();
159     int numberOfNodes=points.size();
160
161
162     // creation du tableau des coordonnees en mode MED_FULL_INTERLACE
163     double * coord = new double[spaceDimension*numberOfNodes];
164     int k=0;
165     for( std::map<int,_noeud>::const_iterator i=points.begin(); i!=points.end(); ++i, ++k)
166         std::copy(i->second.coord.begin(), i->second.coord.end(), coord+k*spaceDimension);
167
168     // creation de l'objet COORDINATE
169     COORDINATE * coordinate = new COORDINATE(spaceDimension, numberOfNodes, mode);
170     coordinate->setCoordinates(mode,coord);
171     delete [] coord;
172     coordinate->setCoordinatesSystem(coordinateSystem);
173     return coordinate;
174 }
175
176
177   /*!
178    * \if developper
179    * create a MED CONNECTIVITY from the intermediate structure.
180    * for memory optimisation, clear the intermediate structure (the "maillage" set )
181    * \endif
182    */
183 CONNECTIVITY * 
184 _intermediateMED::getConnectivity()
185 {
186     const char * LOC = "_intermediateMED::getConnectivity() : ";
187     BEGIN_OF(LOC);
188     int numberOfNodes=points.size(); // number of nodes in the mesh
189     int numberOfTypes=0;
190     medEntityMesh entity;
191     medGeometryElement * types=NULL; // pointeurs pour allouer les structures MED
192     int * count=NULL;
193     int * connectivity=NULL;
194     CONNECTIVITY *Connectivity, *Constituent;
195
196     medGeometryElement type=0; // variables de travail
197     int nbtype=0;
198     int dimension=0;
199     bool first = true;
200
201     std::vector<medGeometryElement> vtype; // tableau de travail : stockage des types geometriques pour UNE entite
202     std::vector<int> vcount; // tableau de travail : nombre d'elements pour chaque type geometrique de vtype
203
204     std::set<_maille>::const_iterator i=maillage.begin(); // iterateurs sur les mailles
205     std::set<_maille>::const_iterator j=maillage.begin();
206
207     // renumerote les points de 1 a n (pour le cas ou certains points ne sont pas presents dans le maillage d'origine) 
208     numerotationPoints(); 
209
210     do 
211     {
212         // boucle sur les entites de la structure maillage :
213         //   - on parcourt une premiere fois avec i les mailles d'une entite pour récupérer 
214         //     des infos sur les types geometriques, leur nombre et le nombre d'elements.
215         //   - on alloue la connectivite
216         //   - on parcourt une deuxieme fois avec j pour lire les noeuds.
217
218
219         type=i->geometricType; // init boucle for
220         dimension=i->dimension();
221         nbtype=0;
222         vtype.push_back(type);
223         // Boucle sur i de parcours des mailles d'une entite
224         // Une entite se termine lorsqu'on atteint la fin de maillage ou lorsque la dimension des mailles change
225         for( ; i!=maillage.end() && dimension==i->dimension() ; ++i)
226         {
227             if (type != i->geometricType) // si changement de type geometrique
228             {
229                 vcount.push_back(nbtype); // stocke le nombre d'elements de type nbtype
230                 nbtype=0;
231                 type=i->geometricType;
232                 vtype.push_back(type); // stocke le nouveau type geometrique rencontre
233             }
234
235             ++nbtype;
236         }
237         vcount.push_back(nbtype); // n'a pas été stocké dans la boucle
238
239         
240         // Pour l'entite qu'on vient de parcourir, allocation des tableau et creation de la connectivite
241 //      cout << "Dimension = " << dimension << endl;
242 //      cout << "Nombre de type geometriques : " << vtype.size() << endl;
243 //      for (unsigned k=0; k!=vtype.size(); ++k )
244 //          cout << "  -> " << vtype[k] << " : " << vcount[k] << endl;
245
246         numberOfTypes=vtype.size(); // nombre de types de l'entite
247         
248         if ( i==maillage.end() ) // cas de l'entite de plus haut niveau
249             entity=MED_CELL;
250         else if (dimension==2 )
251             entity=MED_FACE;
252         else if (dimension==1 )
253             entity=MED_EDGE;
254         else if (dimension==0 )
255             entity=MED_NODE;
256
257         Connectivity = new CONNECTIVITY(numberOfTypes,entity);
258         Connectivity->setEntityDimension(dimension);
259         Connectivity->setNumberOfNodes(numberOfNodes);
260         
261         types = new medGeometryElement[numberOfTypes];
262         std::copy(vtype.begin(),vtype.end(),types);
263         Connectivity->setGeometricTypes(types,entity);
264         delete [] types;
265
266         count = new int[numberOfTypes+1];
267         count[0]=1;
268         for (unsigned int k=0; k!=vcount.size(); ++k )
269           count[k+1]=count[k]+vcount[k];
270         Connectivity->setCount (count, entity);
271         delete [] count;
272
273         for (int k=0; k!=numberOfTypes; ++k )
274           {
275             // pour chaque type geometrique k, copie des sommets dans connectivity et set dans Connectivity
276             int nbSommetsParMaille = j->sommets.size();
277             int nbSommets = vcount[k] * j->sommets.size();
278             connectivity = new int[ nbSommets ];
279             for (int l=0; l!=vcount[k]; ++l, ++j)
280             {
281                 for ( unsigned n=0; n != j->sommets.size(); ++n)
282                     connectivity[nbSommetsParMaille*l+n] = j->sommets[n]->second.number;
283                 maillage.erase(j);    ; // dangereux, mais optimise la mémoire consommée!
284             }
285
286             Connectivity->setNodal  (connectivity, entity, vtype[k]);
287             delete [] connectivity;
288           }
289                 
290         if (i!=j)
291             throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Erreur de lecture des mailles ."));
292
293         if ( ! first)
294             Connectivity->setConstituent (Constituent);
295         else
296             first = false;
297         Constituent = Connectivity; // stocke Connectivity pour utilisation dans setConstituent lors de la boucle suivante
298
299         vtype.clear();
300         vcount.clear();
301
302     }
303     while ( i != maillage.end() );
304
305     END_OF(LOC);
306     return Connectivity;
307 }
308
309
310   /*!
311    * \if developper
312    * fill the arguments vector of groups from the intermediate structure.
313    * This function must be called before getConnectivity()
314    * \endif
315    */
316 void
317 _intermediateMED::getGroups(std::vector<GROUP *> & _groupCell, std::vector<GROUP *> & _groupFace, std::vector<GROUP *> & _groupEdge, std::vector<GROUP *> & _groupNode, MESH * _ptrMesh)
318 {
319     const char * LOC = "_intermediateMED::getGroups() : ";
320     BEGIN_OF(LOC);
321     if (maillage.size() == 0)
322         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Erreur : il n'y a plus de mailles (appeler getConnectivity apres getGroups!)."));
323
324     int dimension_maillage=maillage.rbegin()->dimension();
325
326     numerotationMaillage(); // Renumerotation des mailles par entite
327
328     for (unsigned int i=0; i!=this->groupes.size(); ++i)
329     {
330         if (groupes[i].mailles.size()==0)
331             continue; // si le groupe est vide, on passe au suivant
332
333         int nb_geometric_types=1;
334         _groupe::mailleIter j=groupes[i].mailles.begin(); 
335         // initialise groupe_entity a l'entite de la premiere maille du groupe
336         medEntityMesh groupe_entity = (**j).getEntity(dimension_maillage);
337         medGeometryElement geometrictype=(**j).geometricType;
338
339         //Parcours des mailles (a partir de la deuxieme) pour compter les types geometriques
340         for ( ++j ; j!=groupes[i].mailles.end(); ++j )
341         {
342             //Compte nombre de types geometriques
343             if ( (**j).geometricType != geometrictype ) // si on change de type geometrique
344             {
345                 nb_geometric_types++;
346                 geometrictype=(**j).geometricType;
347             }
348
349             //Test si groupe valide : le groupe doit pointer vers des entites de meme dimension
350             if ((**j).dimension() != dimension_maillage)
351                 continue;
352         }
353
354         // le groupe est valide -> on le traite
355         MED_EN::medGeometryElement * tab_types_geometriques = new MED_EN::medGeometryElement[nb_geometric_types];
356         int * tab_index_types_geometriques = new int[nb_geometric_types+1];
357         int * tab_numeros_elements = new int[groupes[i].mailles.size()];
358         int * tab_nombres_elements = new int[nb_geometric_types];
359
360         //Remplit tableaux entree des methodes set
361         int indice_mailles=0;
362         j=groupes[i].mailles.begin();
363         geometrictype=(**j).geometricType;
364         tab_index_types_geometriques[0]=1;
365         int indice_types_geometriques=1;
366         tab_types_geometriques[0]=geometrictype;
367         //parcours des mailles du groupe
368         for (  ; j!=groupes[i].mailles.end(); ++j , ++indice_mailles)
369         {
370             tab_numeros_elements[indice_mailles]=((**j).ordre);
371             if ((**j).geometricType != geometrictype)
372             {
373                 tab_index_types_geometriques[indice_types_geometriques]=indice_mailles+1;
374                 geometrictype=(**j).geometricType;
375                 tab_types_geometriques[indice_types_geometriques]=geometrictype;
376                 ++indice_types_geometriques;
377             }
378         }
379         tab_index_types_geometriques[indice_types_geometriques]=indice_mailles+1;
380         for (int k=0; k != nb_geometric_types; ++k)
381         {
382             tab_nombres_elements[k] = tab_index_types_geometriques[k+1]-tab_index_types_geometriques[k];
383         }
384
385         //Determination type entite du groupe
386         vector <GROUP *> * vect_group;
387         switch ( groupe_entity )
388         {
389             case MED_CELL :
390                 vect_group= & _groupCell;
391                 break;
392             case MED_FACE :
393                 vect_group= & _groupFace;
394                 break;
395             case MED_EDGE :
396                 vect_group= & _groupEdge;
397                 break;
398             case MED_NODE :
399                 vect_group= & _groupNode;
400                 break;
401         }
402         //Creation nouveau groupe MED
403         GROUP * new_group = new GROUP();
404         //Appel methodes set
405         new_group->setTotalNumberOfElements(groupes[i].mailles.size());
406         new_group->setName(groupes[i].nom);
407         new_group->setMesh(_ptrMesh);
408         new_group->setNumberOfGeometricType(nb_geometric_types);
409         new_group->setGeometricType(tab_types_geometriques);
410         new_group->setNumberOfElements(tab_nombres_elements);
411         new_group->setNumber(tab_index_types_geometriques,tab_numeros_elements);
412         new_group->setEntity(groupe_entity);
413         new_group->setAll(groupes[i].mailles.size() == maillage.size());
414         vect_group->push_back(new_group);
415         delete [] tab_types_geometriques;
416         delete [] tab_index_types_geometriques;
417         delete [] tab_numeros_elements;
418         delete [] tab_nombres_elements;
419     }
420
421     END_OF(LOC);
422 }
423
424 /////