]> SALOME platform Git repositories - modules/med.git/blob - src/MEDMEM/MEDMEM_GibiMeshDriver.cxx
Salome HOME
correct a small bug appearing when using the gcc 3.2.1.
[modules/med.git] / src / MEDMEM / MEDMEM_GibiMeshDriver.cxx
1 using namespace std;
2
3 #include <algorithm>
4
5 #include "MEDMEM_GibiMeshDriver.hxx"
6
7 #include "MEDMEM_DriversDef.hxx"
8
9 #include "MEDMEM_Family.hxx"
10 #include "MEDMEM_Group.hxx"
11 #include "MEDMEM_Coordinate.hxx"
12 #include "MEDMEM_Connectivity.hxx"
13 #include "MEDMEM_Mesh.hxx"
14 #include "MEDMEM_CellModel.hxx"
15 #include "MEDMEM_define.hxx"
16 #include "MEDMEM_DriverTools.hxx"
17
18 /////
19 using namespace MED_EN;
20 using namespace MEDMEM;
21 /////
22
23
24 /////
25 const size_t GIBI_MESH_DRIVER::nb_geometrie_gibi;
26
27 const medGeometryElement GIBI_MESH_DRIVER::geomGIBItoMED[nb_geometrie_gibi] =
28      {   /*1 */ MED_POINT1 ,/*2 */ MED_SEG2   ,/*3 */ MED_SEG3   ,/*4 */ MED_TRIA3  ,/*5 */ MED_NONE   ,
29        /*6 */ MED_TRIA6  ,/*7 */ MED_NONE   ,/*8 */ MED_QUAD4  ,/*9 */ MED_NONE   ,/*10*/ MED_QUAD8  ,
30        /*11*/ MED_NONE   ,/*12*/ MED_NONE   ,/*13*/ MED_NONE   ,/*14*/ MED_HEXA8  ,/*15*/ MED_HEXA20 ,
31        /*16*/ MED_PENTA6 ,/*17*/ MED_PENTA15,/*18*/ MED_NONE   ,/*19*/ MED_NONE   ,/*20*/ MED_NONE   ,
32        /*21*/ MED_NONE   ,/*22*/ MED_NONE   ,/*23*/ MED_TETRA4 ,/*24*/ MED_TETRA10,/*25*/ MED_PYRA5  ,
33        /*26*/ MED_PYRA13 ,/*27*/ MED_NONE   ,/*28*/ MED_NONE   ,/*29*/ MED_NONE   ,/*30*/ MED_NONE   ,
34        /*31*/ MED_NONE   ,/*32*/ MED_NONE   ,/*33*/ MED_NONE   ,/*34*/ MED_NONE   ,/*35*/ MED_NONE   ,
35        /*36*/ MED_NONE   ,/*37*/ MED_NONE   ,/*38*/ MED_NONE   ,/*39*/ MED_NONE   ,/*40*/ MED_NONE   ,
36        /*41*/ MED_NONE   ,/*42*/ MED_NONE   ,/*43*/ MED_NONE   ,/*44*/ MED_NONE   ,/*45*/ MED_NONE   ,
37        /*46*/ MED_NONE   ,/*47*/ MED_NONE   };
38
39 //const medGeometryElement GIBI_MESH_DRIVER::geomGIBItoMED[nb_geometrie_gibi];
40 /////
41
42 // Every memory allocation made in the MedDriver members function are desallocated in the Mesh destructor 
43
44 GIBI_MESH_DRIVER::GIBI_MESH_DRIVER():
45   GENDRIVER(),
46   _ptrMesh(( MESH *)MED_NULL),
47   // A VOIR _medIdt(MED_INVALID),
48   _meshName("")
49 {
50 }
51
52 GIBI_MESH_DRIVER::GIBI_MESH_DRIVER(const string & fileName,
53                                    MESH * ptrMesh,
54                                    MED_EN::med_mode_acces accessMode): 
55   GENDRIVER(fileName,accessMode),
56   _ptrMesh(ptrMesh)
57   // A VOIR _medIdt(MED_INVALID), 
58 {
59   _meshName=fileName.substr(0,fileName.rfind("."));
60 }
61   
62 GIBI_MESH_DRIVER::GIBI_MESH_DRIVER(const GIBI_MESH_DRIVER & driver): 
63   GENDRIVER(driver),
64   _ptrMesh(driver._ptrMesh),
65   // A VOIR _medIdt(MED_INVALID), 
66   _meshName(driver._meshName)
67 {
68 }
69
70 GIBI_MESH_DRIVER::~GIBI_MESH_DRIVER()
71 {
72 }
73
74 void GIBI_MESH_DRIVER::open()
75   throw (MEDEXCEPTION)
76 {
77     const char * LOC = "GIBI_MESH_DRIVER::open()" ;
78     BEGIN_OF(LOC);
79
80     _gibi.open(_fileName.c_str(), ios::in);
81     if(_gibi)
82         _status = MED_OPENED;
83     else
84     {
85         _status = MED_CLOSED;
86         throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Could not open file "<<_fileName<<" in mode ios::in"));
87     }
88   END_OF(LOC);
89 }
90   
91 void GIBI_MESH_DRIVER::close()
92   throw (MEDEXCEPTION)
93 {
94     const char * LOC = "GIBI_MESH_DRIVER::close() " ;
95     BEGIN_OF(LOC);
96     if ( _status == MED_OPENED) 
97     {
98         _gibi.close();
99         _status = MED_CLOSED;
100     }
101     END_OF(LOC);
102 }
103
104 void    GIBI_MESH_DRIVER::setMeshName(const string & meshName) { _meshName = meshName; };
105 string  GIBI_MESH_DRIVER::getMeshName() const { return _meshName; };
106
107
108 //---------------------------------- RDONLY PART -------------------------------------------------------------
109
110 GIBI_MESH_RDONLY_DRIVER::GIBI_MESH_RDONLY_DRIVER(): GIBI_MESH_DRIVER()
111 {
112 }
113
114 GIBI_MESH_RDONLY_DRIVER::GIBI_MESH_RDONLY_DRIVER(const string & fileName,
115         MESH * ptrMesh):
116 GIBI_MESH_DRIVER(fileName,ptrMesh,MED_RDONLY)
117
118     MESSAGE("GIBI_MESH_RDONLY_DRIVER::GIBI_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created");
119 }
120
121     GIBI_MESH_RDONLY_DRIVER::GIBI_MESH_RDONLY_DRIVER(const GIBI_MESH_RDONLY_DRIVER & driver): 
122 GIBI_MESH_DRIVER(driver)
123 {
124 }
125
126 GIBI_MESH_RDONLY_DRIVER::~GIBI_MESH_RDONLY_DRIVER()
127 {
128     //MESSAGE("GIBI_MESH_RDONLY_DRIVER::~GIBI_MESH_RDONLY_DRIVER() has been destroyed");
129 }
130   
131 GENDRIVER * GIBI_MESH_RDONLY_DRIVER::copy(void) const
132 {
133     return new GIBI_MESH_RDONLY_DRIVER(*this);
134 }
135
136 void GIBI_MESH_RDONLY_DRIVER::read(void) throw (MEDEXCEPTION)
137 {
138     const char * LOC = "GIBI_MESH_RDONLY_DRIVER::read() : " ;
139     BEGIN_OF(LOC);
140
141     if (_status!=MED_OPENED)
142         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "The _idt of file " << _fileName << " is : "  
143                                                  <<  " (the file is not opened)." )) ;
144
145     // LECTURE DES DONNEES DS FICHIER GIBI
146
147     _intermediateMED medi; // structure de données intermédiaire pour conversion gibi->med
148     string buf_ligne; // pour lire une ligne
149     const char* enregistrement_type="ENREGISTREMENT DE TYPE";
150     std::vector<int> numero_noeuds; // tableau de travail (indices)
151
152
153     while ( getline(_gibi, buf_ligne) ) // boucle externe de recherche de "ENREGISTREMENT DE TYPE"
154     {
155         string::size_type pos = buf_ligne.find(enregistrement_type);
156         if ( pos==string::npos )
157             continue; // "ENREGISTREMENT DE TYPE" non trouvé -> on lit la ligne suivante
158
159         // lecture du numéro d'enregistrement
160         int numero_enregistrement;
161         istringstream buf(buf_ligne.c_str()+strlen(enregistrement_type)+1);
162         buf >> numero_enregistrement;
163
164         enum { ENREG_TYPE_2=2, ENREG_TYPE_4=4}; // énumération des types d'enregistrement traités
165         int niveau, niveau_erreur;
166         unsigned space_dimension,nb_reels;
167         int numero_pile, nb_objets_nommes, nb_objets, nb_indices;
168         string s1,s2,s3,s4,s5,s6,s7; // temporary strings
169         int i1; //temporary int
170         double d1; //temporary double
171         vector<int> indices_objets_nommes;
172         vector<string> objets_nommes;
173
174         switch (numero_enregistrement)
175           {
176           case ENREG_TYPE_4:
177             MESSAGE(LOC << "---- Traitement enregistrement de type 4");
178             _gibi >> s1 >> niveau >> s2 >> s3 >> niveau_erreur >> s4 >> space_dimension;
179             if ( !_gibi || s1!="NIVEAU" || s3!="ERREUR" || s4!="DIMENSION" ) // verification mots -cles
180               throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << " Could not read file " << _fileName 
181                                            << " : syntax error in type 4 record"));
182             break;
183
184           case ENREG_TYPE_2:
185             {
186               MESSAGE(LOC << "---- Traitement enregistrement de type 2");
187               _gibi >> s1 >> s2 >> numero_pile >> s3 >> s4 >> s5 >> nb_objets_nommes >> s6 >> s7 >> nb_objets;
188               if ( !_gibi || s1!="PILE"   || s2!="NUMERO"       || s3!="NBRE"  // verification mots -cles
189                    || s4!="OBJETS" || s5!="NOMMES"       || s6!="NBRE"   
190                    || s7!="OBJETS" || nb_objets_nommes<0 || nb_objets<0  )
191                 {
192                   throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << " Could not read file " << _fileName 
193                                                << " : error in type 2 record"));
194                 }
195
196               // lecture des objets nommés et de leurs indices
197               objets_nommes.resize(nb_objets_nommes);
198               indices_objets_nommes.resize(nb_objets_nommes);
199               for (int i=0; i!=nb_objets_nommes; ++i)
200                 _gibi >> objets_nommes[i];
201
202               for (int i=0; i!=nb_objets_nommes; ++i)
203                 _gibi >> indices_objets_nommes[i];
204                 
205               // boucle interne : lecture de la pile
206               enum {PILE_SOUS_MAILLAGE=1, PILE_NOEUDS=32, PILE_COORDONNEES=33};
207               switch(numero_pile)
208                 {
209                 case PILE_SOUS_MAILLAGE:
210                   {
211                     medi.groupes.reserve(nb_objets);
212                     for (int objet=0; objet!=nb_objets; ++objet) // pour chaque groupe
213                       {
214                         unsigned type_geom_castem, nb_reference,nb_noeud,nb_elements, nb_sous_maillage;
215                         _gibi >> type_geom_castem >> nb_sous_maillage >> nb_reference >> nb_noeud >> nb_elements;
216                         
217                         // le cas type_geom_castem=0 correspond aux maillages composites
218                         if (type_geom_castem<0 || (type_geom_castem>0 && geomGIBItoMED[type_geom_castem-1]==MED_NONE) )
219                           throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << " Error while reading file " << _fileName 
220                                                        << "\nCastem geometric type " << type_geom_castem 
221                                                        << " does not have a correspondant MED geometric type!" ));
222
223                         // lecture des references (non utilisé pour MED)
224                         for( unsigned i=0; i!=nb_reference; ++i)
225                           _gibi >> i1;
226                         
227                         // lecture des couleurs (non utilisé pour MED)
228                         for( unsigned i=0; i!=nb_elements; ++i)
229                           _gibi >> i1;
230                         
231                         _groupe groupe;
232                         // si le groupe se compose de sous-maillages (ie groupe composite) 
233                         if (type_geom_castem==0 && nb_sous_maillage>0) 
234                           {
235                             // lecture des indices des sous-maillages, stockage.
236                             // les mailles correspondant a ces sous_maillages seront inserees a la fin du case
237                             for (unsigned i=0; i!=nb_sous_maillage; ++i)
238                               {
239                                 _gibi >> i1;
240                                 groupe.groupes.push_back(i1);
241                               }
242                           }
243                         else
244                           {
245                             pair<set<_maille>::iterator,bool> p;
246                             pair<map<int,_noeud>::iterator,bool> p_no;
247                             _noeud no;
248                             no.coord.reserve(space_dimension);
249                             no.coord.resize(space_dimension);
250                             _maille ma(geomGIBItoMED[type_geom_castem-1], nb_noeud);
251                             ma.sommets.resize(nb_noeud);
252
253                             // lecture pour chaque maille des sommets et insertions
254                             for( unsigned i=0; i!=nb_elements; ++i)
255                               {
256                                 for (unsigned n=0; n!=nb_noeud; ++n)
257                                   {
258                                     _gibi >> i1;
259                                     no.number=i1;
260                                     p_no=medi.points.insert(make_pair(i1, no));
261                                     ma.sommets[n]=p_no.first;
262                                   }
263
264                                 p=medi.maillage.insert(ma);
265                                 groupe.mailles.insert(p.first); // on stocke dans le groupe un iterateur sur la maille
266
267 //                                  cout << "   " << p.second << ": ";
268 //                                  for (unsigned n=0; n!=nb_noeud; ++n)
269 //                                      cout <<  ma.sommets[n]->second.number << " ";
270 //                                  cout << endl;
271                                 
272                               }
273                           }
274                         medi.groupes.push_back(groupe);
275                       }
276
277                     for (int i=0; i!=nb_objets_nommes; ++i)
278                       medi.groupes[indices_objets_nommes[i]-1].nom=objets_nommes[i];
279                     
280                     // scanne les groupes à la recherche de groupes composites
281                     for( std::vector<_groupe>::iterator i=medi.groupes.begin(); i!=medi.groupes.end(); ++i)
282                       {
283                         if( i->groupes.size() ) // le groupe i contient des sous-maillages
284                           {
285                             for( std::list<int>::iterator j=i->groupes.begin(); j!=i->groupes.end(); ++j)
286                               {
287                                 // pour chacun des sous-maillages j, on recupere les iterateurs *k sur les  maille 
288                                 // contenues et on les insere dans le groupe i
289                                 std::set< std::set<_maille>::iterator >::const_iterator k=medi.groupes[*j-1].mailles.begin();
290                                 for( ; k!=medi.groupes[*j-1].mailles.end(); ++k)
291                                   i->mailles.insert(*k);
292                               }
293                             i->groupes.clear(); // après avoir insere leur mailles, on efface les groupes composites
294                           }
295                       }
296                     
297                     break;
298                   }// Fin case PILE_SOUS_MAILLAGE
299                         
300                 case PILE_NOEUDS:
301                   {
302                     std::vector<int> place_noeuds;
303                     _gibi >> nb_indices;
304                     if (nb_indices != nb_objets)
305                       {
306                         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << " Could not read file " << _fileName 
307                                                      << "Erreur de lecture dans enregistrement de type " << ENREG_TYPE_2 
308                                                      << " (pile " << PILE_NOEUDS << ")" ));
309                       }
310                     
311                     place_noeuds.resize(nb_objets);
312                     for (unsigned i=0; i!=place_noeuds.size(); ++i)
313                       _gibi >> place_noeuds[i];
314                     int max=(* std::max_element(place_noeuds.begin(),place_noeuds.end()));
315
316                     // numero_noeuds contient pour chacun des max noeuds qu'on va lire dans le case PILE_COORDONNEES
317                     // son indice dans la connectivite du maillage. Cet indice correspond egalement a la cle du map
318                     // medi.points ou l'on stocke les noeuds.
319                     numero_noeuds.resize(max,-1);
320                     for (unsigned i=0; i!=place_noeuds.size(); ++i)
321                       numero_noeuds[place_noeuds[i]-1]=i+1;
322                     break;
323                   }
324                   
325                 case PILE_COORDONNEES:
326                   _gibi >> nb_reels;
327                   // PROVISOIRE : certains fichier gibi n'ont 
328                   if (nb_reels < numero_noeuds.size()*(space_dimension))
329                     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << " Could not read file " << _fileName 
330                                                  << "Erreur de lecture dans enregistrement de type " << ENREG_TYPE_2 
331                                                  << " (pile " << PILE_COORDONNEES << ")" ));
332
333                   for (unsigned i=0; i!=numero_noeuds.size(); ++i)
334                     {
335                       // si le noeud est utilisé dans le maillage, on lit ses coordonnées et on les stocke dans la structure
336                       if ( (numero_noeuds[i] != -1) && (medi.points.find(numero_noeuds[i])!=medi.points.end()) ) 
337                         {
338                           for (unsigned j=0; j!=space_dimension; ++j)
339                             _gibi >> medi.points[numero_noeuds[i]].coord[j];
340                           _gibi >> d1; // on ne conserve pas la densite
341                         }
342                       else // sinon, on passe au noeud suivant
343                         {
344                           for (unsigned j=0; j!=space_dimension+1; ++j)
345                             _gibi >> d1;
346                         }
347                     }
348                   break;
349
350                 } // Fin switch numero_pile
351               break;
352             } // Fin case ENREG_TYPE_2
353           }
354
355     } //  fin de la boucle while de lecture externe
356
357     // impression résultats
358     MESSAGE(LOC << "GIBI_MESH_RDONLY_DRIVER::read : RESULTATS STRUCTURE INTERMEDIAIRES : ");
359     MESSAGE(LOC <<  medi );
360
361             // TRANSFORMATION EN STRUCTURES MED
362     if ( ! _ptrMesh->isEmpty() )
363     {
364         throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Mesh object not empty : can't fill it!"));
365     }
366     else if ( medi.maillage.size()==0 || medi.groupes.size()==0 || medi.points.size()==0)
367     {
368         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << " Error while reading file " << _fileName 
369                     << " The data read are not completed " ) ) ;
370     }
371     else
372     {
373         _ptrMesh->_name = _meshName;
374         _ptrMesh->_spaceDimension = medi.points.begin()->second.coord.size();
375         _ptrMesh->_meshDimension = medi.maillage.rbegin()->dimension();
376         _ptrMesh->_numberOfNodes = medi.points.size();
377         _ptrMesh->_isAGrid = 0;
378         _ptrMesh->_coordinate = medi.getCoordinate();
379
380         //Construction des groupes
381         vector<GROUP *> groupCell, groupFace, groupEdge, groupNode;
382         medi.getGroups(groupCell, groupFace, groupEdge, groupNode, _ptrMesh);
383         _ptrMesh->_groupCell = groupCell;
384         _ptrMesh->_groupFace = groupFace;
385         _ptrMesh->_groupEdge = groupEdge;
386         _ptrMesh->_groupNode = groupNode;
387
388         //Affectation derniers attributs objet Mesh
389         _ptrMesh->_numberOfCellsGroups = _ptrMesh->_groupCell.size();
390         _ptrMesh->_numberOfFacesGroups = _ptrMesh->_groupFace.size();
391         _ptrMesh->_numberOfEdgesGroups = _ptrMesh->_groupEdge.size();
392         _ptrMesh->_numberOfNodesGroups = _ptrMesh->_groupNode.size();
393
394         // appele en dernier car cette fonction detruit le maillage intermediaire!
395         _ptrMesh->_connectivity = medi.getConnectivity(); 
396
397         // calcul de la connectivite d-1 complete, avec renumerotation des groupes
398         if (_ptrMesh->_spaceDimension==3)
399             _ptrMesh->_connectivity->updateGroup(_ptrMesh->_groupFace) ;
400         else if (_ptrMesh->_spaceDimension==2)
401             _ptrMesh->_connectivity->updateGroup(_ptrMesh->_groupEdge) ;
402         
403     }
404
405
406
407     END_OF(LOC);
408 }
409
410 void GIBI_MESH_RDONLY_DRIVER::write( void ) const
411   throw (MEDEXCEPTION)
412 {
413   throw MEDEXCEPTION("GIBI_MESH_RDONLY_DRIVER::write : Can't write with a RDONLY driver !");
414 }
415
416
417 /*--------------------- WRONLY PART -------------------------------*/
418
419 GIBI_MESH_WRONLY_DRIVER::GIBI_MESH_WRONLY_DRIVER():GIBI_MESH_DRIVER()
420 {
421 }
422   
423 GIBI_MESH_WRONLY_DRIVER::GIBI_MESH_WRONLY_DRIVER(const string & fileName,
424                                                  MESH * ptrMesh):
425   GIBI_MESH_DRIVER(fileName,ptrMesh,MED_WRONLY)
426 {
427   MESSAGE("GIBI_MESH_WRONLY_DRIVER::GIBI_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created");
428 }
429
430 GIBI_MESH_WRONLY_DRIVER::GIBI_MESH_WRONLY_DRIVER(const GIBI_MESH_WRONLY_DRIVER & driver): 
431   GIBI_MESH_DRIVER(driver)
432 {
433 }
434
435 GIBI_MESH_WRONLY_DRIVER::~GIBI_MESH_WRONLY_DRIVER()
436 {
437   //MESSAGE("GIBI_MESH_WRONLY_DRIVER::GIBI_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed");
438 }
439
440 GENDRIVER * GIBI_MESH_WRONLY_DRIVER::copy(void) const
441 {
442   return new GIBI_MESH_WRONLY_DRIVER(*this);
443 }
444
445 void GIBI_MESH_WRONLY_DRIVER::read (void)
446   throw (MEDEXCEPTION)
447 {
448   throw MEDEXCEPTION("GIBI_MESH_WRONLY_DRIVER::read : Can't read with a WRONLY driver !");
449 }
450
451 void GIBI_MESH_WRONLY_DRIVER::write(void) const
452   throw (MEDEXCEPTION)
453
454   const char * LOC = "void GIBI_MESH_WRONLY_DRIVER::write(void) const : ";
455   BEGIN_OF(LOC);
456
457   throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<< "Write Driver isn\'t implemented"));
458
459   END_OF(LOC);
460
461
462
463
464 /*--------------------- RDWR PART -------------------------------*/
465
466 GIBI_MESH_RDWR_DRIVER::GIBI_MESH_RDWR_DRIVER():GIBI_MESH_DRIVER()
467 {
468 }
469
470 GIBI_MESH_RDWR_DRIVER::GIBI_MESH_RDWR_DRIVER(const string & fileName,
471                                            MESH * ptrMesh):
472   GIBI_MESH_DRIVER(fileName,ptrMesh,MED_RDWR)
473 {
474   MESSAGE("GIBI_MESH_RDWR_DRIVER::GIBI_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been created");
475 }
476
477 GIBI_MESH_RDWR_DRIVER::GIBI_MESH_RDWR_DRIVER(const GIBI_MESH_RDWR_DRIVER & driver): 
478   GIBI_MESH_RDONLY_DRIVER::GIBI_MESH_DRIVER(driver)
479 {
480 }
481
482 GIBI_MESH_RDWR_DRIVER::~GIBI_MESH_RDWR_DRIVER() {
483   //MESSAGE("GIBI_MESH_RDWR_DRIVER::GIBI_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed");
484
485   
486 GENDRIVER * GIBI_MESH_RDWR_DRIVER::copy(void) const
487 {
488   return new GIBI_MESH_RDWR_DRIVER(*this);
489 }
490
491 void GIBI_MESH_RDWR_DRIVER::write(void) const
492   throw (MEDEXCEPTION)
493 {
494   GIBI_MESH_WRONLY_DRIVER::write();
495 }
496 void GIBI_MESH_RDWR_DRIVER::read (void)
497   throw (MEDEXCEPTION)
498 {
499   GIBI_MESH_RDONLY_DRIVER::read();
500 }