1 #include "MEDMEM_DriverTools.hxx"
2 #include "MEDMEM_STRING.hxx"
3 #include "MEDMEM_Exception.hxx"
4 #include "MEDMEM_Mesh.hxx"
5 #include "MEDMEM_Group.hxx"
10 using namespace MEDMEM;
11 using namespace MED_EN;
13 // Cet opérateur permet d'ordonner les mailles dans un set suivant l'ordre requis par MED
14 bool _maille::operator < (const _maille& ma) const
16 // si le type géométrique differe, la comparaison est basée dessus
17 // sinon on se base sur une comparaison des numéros de sommets
18 if(geometricType==ma.geometricType)
20 // construction de deux vecteur temporaire contenant les numeros de sommets
21 // pour faire le tri et les comparaisons
22 size_t l=sommets.size();
23 std::vector<int> v1(l);
24 std::vector<int> v2(l);
25 for (unsigned int i=0; i!=l; ++i)
27 v1[i]=sommets[i]->second.number;
28 v2[i]=ma.sommets[i]->second.number;
30 std::sort(v1.begin(), v1.end());
31 std::sort(v2.begin(), v2.end());
32 for(std::vector<int>::const_iterator i1=v1.begin(), i2=v2.begin(); i1!=v1.end(); ++i1, ++i2)
35 return false; // cas d'égalité
38 return geometricType<ma.geometricType;
42 // retourne l'entité d'une maille en fonction de la dimension du maillage.
43 MED_EN::medEntityMesh _maille::getEntity(const int meshDimension) const throw (MEDEXCEPTION)
45 const char * LOC = "_maille::getEntity(const int meshDimension)" ;
48 int mailleDimension = this->dimension();
50 if (mailleDimension == meshDimension)
53 switch (mailleDimension)
65 throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Impossible de determiner l'entite de la maille."));
72 std::ostream& MEDMEM::operator << (std::ostream& os, const _maille& ma)
74 os << "maille " << ma.ordre << " (" << ma.geometricType << ") : < ";
75 std::vector< std::map<int,_noeud>::iterator >::const_iterator i=ma.sommets.begin();
76 os << (*i++)->second.number ;
77 for( ; i!=ma.sommets.end(); ++i)
78 os << ", " << (*i)->second.number;
83 std::ostream& MEDMEM::operator << (std::ostream& os, const _groupe& gr)
85 os << "--- Groupe " << gr.nom << " --- " << std::endl ;
86 os << " -> liste des sous-groupes : ";
87 for( std::vector<int>::const_iterator i=gr.groupes.begin(); i!=gr.groupes.end(); ++i)
89 os << std::endl << " -> liste des mailles : " << std::endl;
90 std::set< std::set< _maille, std::less< _maille >,
91 std::allocator< _maille > >::iterator,
92 _mailleIteratorCompare,
93 std::allocator< std::set< _maille, std::less< _maille >,
94 std::allocator< _maille > >::iterator > >::const_iterator i ;
95 for( i=gr.mailles.begin(); i!=gr.mailles.end(); i++)
96 os << " " << *(*i) << std::endl;
100 std::ostream& MEDMEM::operator << (std::ostream& os, const _noeud& no)
102 os << "noeud " << no.number << " : < ";
103 std::vector<double>::const_iterator i=no.coord.begin();
105 for( ; i!=no.coord.end(); ++i)
111 std::ostream& MEDMEM::operator << (std::ostream& os, const _intermediateMED& mi)
113 os << "Set des mailles : " << std::endl;
114 for( std::set<_maille>::const_iterator i=mi.maillage.begin(); i!=mi.maillage.end(); ++i)
115 os << *i << std::endl;
117 os << std::endl << "Vector des groupes : " << std::endl;
118 // for( std::vector<_groupe>::const_iterator i=mi.groupes.begin(); i!=mi.groupes.end(); ++i)
119 for (unsigned int i=0; i!=mi.groupes.size(); i++)
120 os << std::setw(3) << i << " " << mi.groupes[i] << std::endl;
122 os << std::endl << "map des noeuds : " << std::endl;
123 for( std::map<int,_noeud>::const_iterator i=mi.points.begin(); i!=mi.points.end(); ++i)
124 os << i->second << std::endl;
128 void _intermediateMED::numerotationMaillage()
130 // numerotation des mailles par entité
132 std::set<_maille>::iterator i=maillage.begin();
133 int dimension=i->dimension();
134 for( ; i!=maillage.end(); ++i)
136 if ( dimension!=i->dimension() ) // on change d'entite
138 dimension=i->dimension();
141 (*i).ordre=++i_maille;
145 void _intermediateMED::numerotationPoints()
147 // Fonction de renumerotation des noeuds (necessaire quand il y a des trous dans la numerotation.
149 for( std::map<int,_noeud>::const_iterator i=points.begin(); i!=points.end(); ++i)
150 i->second.number = ++i_noeud ;
156 * create a MED COORDINATE from the intermediate structure.
160 _intermediateMED::getCoordinate(const string & coordinateSystem)
162 const medModeSwitch mode=MED_FULL_INTERLACE;
163 int spaceDimension=points.begin()->second.coord.size();
164 int numberOfNodes=points.size();
167 // creation du tableau des coordonnees en mode MED_FULL_INTERLACE
168 double * coord = new double[spaceDimension*numberOfNodes];
170 for( std::map<int,_noeud>::const_iterator i=points.begin(); i!=points.end(); ++i, ++k)
171 std::copy(i->second.coord.begin(), i->second.coord.end(), coord+k*spaceDimension);
173 // creation de l'objet COORDINATE
174 COORDINATE * coordinate = new COORDINATE(spaceDimension, numberOfNodes, mode);
175 coordinate->setCoordinates(mode,coord);
177 coordinate->setCoordinatesSystem(coordinateSystem);
184 * create a MED CONNECTIVITY from the intermediate structure.
185 * for memory optimisation, clear the intermediate structure (the "maillage" set )
189 _intermediateMED::getConnectivity()
191 const char * LOC = "_intermediateMED::getConnectivity() : ";
193 int numberOfNodes=points.size(); // number of nodes in the mesh
195 medEntityMesh entity;
196 medGeometryElement * types=NULL; // pointeurs pour allouer les structures MED
198 int * connectivity=NULL;
199 CONNECTIVITY *Connectivity, *Constituent;
201 medGeometryElement type=0; // variables de travail
206 std::vector<medGeometryElement> vtype; // tableau de travail : stockage des types geometriques pour UNE entite
207 std::vector<int> vcount; // tableau de travail : nombre d'elements pour chaque type geometrique de vtype
209 std::set<_maille>::const_iterator i=maillage.begin(); // iterateurs sur les mailles
210 std::set<_maille>::const_iterator j=maillage.begin();
212 // renumerote les points de 1 a n (pour le cas ou certains points ne sont pas presents dans le maillage d'origine)
213 numerotationPoints();
217 // boucle sur les entites de la structure maillage :
218 // - on parcourt une premiere fois avec i les mailles d'une entite pour récupérer
219 // des infos sur les types geometriques, leur nombre et le nombre d'elements.
220 // - on alloue la connectivite
221 // - on parcourt une deuxieme fois avec j pour lire les noeuds.
224 type=i->geometricType; // init boucle for
225 dimension=i->dimension();
227 vtype.push_back(type);
228 // Boucle sur i de parcours des mailles d'une entite
229 // Une entite se termine lorsqu'on atteint la fin de maillage ou lorsque la dimension des mailles change
230 for( ; i!=maillage.end() && dimension==i->dimension() ; ++i)
232 if (type != i->geometricType) // si changement de type geometrique
234 vcount.push_back(nbtype); // stocke le nombre d'elements de type nbtype
236 type=i->geometricType;
237 vtype.push_back(type); // stocke le nouveau type geometrique rencontre
242 vcount.push_back(nbtype); // n'a pas été stocké dans la boucle
245 // Pour l'entite qu'on vient de parcourir, allocation des tableau et creation de la connectivite
246 // cout << "Dimension = " << dimension << endl;
247 // cout << "Nombre de type geometriques : " << vtype.size() << endl;
248 // for (unsigned k=0; k!=vtype.size(); ++k )
249 // cout << " -> " << vtype[k] << " : " << vcount[k] << endl;
251 numberOfTypes=vtype.size(); // nombre de types de l'entite
253 if ( i==maillage.end() ) // cas de l'entite de plus haut niveau
255 else if (dimension==2 )
257 else if (dimension==1 )
259 else if (dimension==0 )
262 Connectivity = new CONNECTIVITY(numberOfTypes,entity);
263 Connectivity->setEntityDimension(dimension);
264 Connectivity->setNumberOfNodes(numberOfNodes);
266 types = new medGeometryElement[numberOfTypes];
267 std::copy(vtype.begin(),vtype.end(),types);
268 Connectivity->setGeometricTypes(types,entity);
271 count = new int[numberOfTypes+1];
273 for (unsigned int k=0; k!=vcount.size(); ++k )
274 count[k+1]=count[k]+vcount[k];
275 Connectivity->setCount (count, entity);
278 for (int k=0; k!=numberOfTypes; ++k )
280 // pour chaque type géometrique k, copie des sommets dans connectivity et set dans Connectivity
281 int nbSommetsParMaille = j->sommets.size();
282 int nbSommets = vcount[k] * j->sommets.size();
283 connectivity = new int[ nbSommets ];
284 for (int l=0; l!=vcount[k]; ++l, ++j)
286 for ( unsigned n=0; n != j->sommets.size(); ++n)
287 connectivity[nbSommetsParMaille*l+n] = j->sommets[n]->second.number;
288 //CCRT maillage.erase(j); ; // dangereux, mais optimise la mémoire consommée!
291 Connectivity->setNodal (connectivity, entity, vtype[k]);
292 delete [] connectivity;
296 throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Erreur de lecture des mailles ."));
299 Connectivity->setConstituent (Constituent);
302 Constituent = Connectivity; // stocke Connectivity pour utilisation dans setConstituent lors de la boucle suivante
308 while ( i != maillage.end() );
317 * fill the arguments vector of groups from the intermediate structure.
318 * This function must be called before getConnectivity()
322 _intermediateMED::getGroups(std::vector<GROUP *> & _groupCell, std::vector<GROUP *> & _groupFace, std::vector<GROUP *> & _groupEdge, std::vector<GROUP *> & _groupNode, MESH * _ptrMesh)
324 const char * LOC = "_intermediateMED::getGroups() : ";
326 if (maillage.size() == 0)
327 throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Erreur : il n'y a plus de mailles (appeler getConnectivity apres getGroups!)."));
329 int dimension_maillage=maillage.rbegin()->dimension();
331 numerotationMaillage(); // Renumerotation des mailles par entite
333 for (unsigned int i=0; i!=this->groupes.size(); ++i)
335 // si le groupe est vide, ou si le groupe n'est pas nommé : on passe au suivant
336 if (groupes[i].mailles.empty() || groupes[i].nom.empty())
339 int nb_geometric_types=1;
340 std::set< std::set< _maille, std::less< _maille >,
341 std::allocator< _maille > >::iterator,
342 _mailleIteratorCompare,
343 std::allocator< std::set< _maille, std::less<_maille >,
344 std::allocator< _maille > >::iterator > >::iterator j ;
345 j=groupes[i].mailles.begin();
346 // initialise groupe_entity a l'entite de la premiere maille du groupe
347 medEntityMesh groupe_entity = (**j).getEntity(dimension_maillage);
348 medGeometryElement geometrictype=(**j).geometricType;
350 //Parcours des mailles (a partir de la deuxieme) pour compter les types geometriques
351 for ( ++j ; j!=groupes[i].mailles.end(); ++j )
353 //Compte nombre de types geometriques
354 if ( (**j).geometricType != geometrictype ) // si on change de type geometrique
356 nb_geometric_types++;
357 geometrictype=(**j).geometricType;
360 //Test si groupe valide : le groupe doit pointer vers des entites de meme dimension
361 if ((**j).dimension() != dimension_maillage)
365 // le groupe est valide -> on le traite
366 MED_EN::medGeometryElement * tab_types_geometriques = new MED_EN::medGeometryElement[nb_geometric_types];
367 int * tab_index_types_geometriques = new int[nb_geometric_types+1];
368 int * tab_numeros_elements = new int[groupes[i].mailles.size()];
369 int * tab_nombres_elements = new int[nb_geometric_types];
371 //Remplit tableaux entree des methodes set
372 int indice_mailles=0;
373 j=groupes[i].mailles.begin();
374 geometrictype=(**j).geometricType;
375 tab_index_types_geometriques[0]=1;
376 int indice_types_geometriques=1;
377 tab_types_geometriques[0]=geometrictype;
378 //parcours des mailles du groupe
379 for ( ; j!=groupes[i].mailles.end(); ++j , ++indice_mailles)
381 tab_numeros_elements[indice_mailles]=((**j).ordre);
382 if ((**j).geometricType != geometrictype)
384 tab_index_types_geometriques[indice_types_geometriques]=indice_mailles+1;
385 geometrictype=(**j).geometricType;
386 tab_types_geometriques[indice_types_geometriques]=geometrictype;
387 ++indice_types_geometriques;
390 tab_index_types_geometriques[indice_types_geometriques]=indice_mailles+1;
391 for (int k=0; k != nb_geometric_types; ++k)
393 tab_nombres_elements[k] = tab_index_types_geometriques[k+1]-tab_index_types_geometriques[k];
396 //Determination type entite du groupe
397 vector <GROUP *> * vect_group;
398 switch ( groupe_entity )
401 vect_group= & _groupCell;
404 vect_group= & _groupFace;
407 vect_group= & _groupEdge;
410 vect_group= & _groupNode;
413 //Creation nouveau groupe MED
414 GROUP * new_group = new GROUP();
416 new_group->setTotalNumberOfElements(groupes[i].mailles.size());
417 new_group->setName(groupes[i].nom);
418 new_group->setMesh(_ptrMesh);
419 new_group->setNumberOfGeometricType(nb_geometric_types);
420 new_group->setGeometricType(tab_types_geometriques);
421 new_group->setNumberOfElements(tab_nombres_elements);
422 new_group->setNumber(tab_index_types_geometriques,tab_numeros_elements);
423 new_group->setEntity(groupe_entity);
424 new_group->setAll(groupes[i].mailles.size() == maillage.size());
425 vect_group->push_back(new_group);
426 delete [] tab_types_geometriques;
427 delete [] tab_index_types_geometriques;
428 delete [] tab_numeros_elements;
429 delete [] tab_nombres_elements;