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