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