Salome HOME
correct small problem from the version in the MedFileV2_2 branch.
[modules/med.git] / src / MEDMEM / MEDMEM_GibiMeshDriver.cxx
index 0da08ffa57efa8f024217e98d3592d30a17ecc7e..d401ffff140fbd2619c9f2b59f53cad7022987ca 100644 (file)
@@ -1,13 +1,7 @@
-//  MED MEDMEM : MED files in memory
-//
-//  Copyright (C) 2003  CEA/DEN, EDF R&D
-//
-//
-//
-//  File   : MEDMEM_GibiMeshDriver.cxx
-//  Module : MED
-
 using namespace std;
+
+#include <algorithm>
+
 #include "MEDMEM_GibiMeshDriver.hxx"
 
 #include "MEDMEM_DriversDef.hxx"
@@ -18,6 +12,30 @@ using namespace std;
 #include "MEDMEM_Connectivity.hxx"
 #include "MEDMEM_Mesh.hxx"
 #include "MEDMEM_CellModel.hxx"
+#include "MEDMEM_define.hxx"
+#include "MEDMEM_DriverTools.hxx"
+
+/////
+using namespace MED_EN;
+using namespace MEDMEM;
+/////
+
+
+/////
+const size_t GIBI_MESH_DRIVER::nb_geometrie_gibi;
+
+const medGeometryElement GIBI_MESH_DRIVER::geomGIBItoMED[nb_geometrie_gibi] =
+     {   /*1 */ MED_POINT1 ,/*2 */ MED_SEG2   ,/*3 */ MED_SEG3   ,/*4 */ MED_TRIA3  ,/*5 */ MED_NONE   ,
+       /*6 */ MED_TRIA6  ,/*7 */ MED_NONE   ,/*8 */ MED_QUAD4  ,/*9 */ MED_NONE   ,/*10*/ MED_QUAD8  ,
+       /*11*/ MED_NONE   ,/*12*/ MED_NONE   ,/*13*/ MED_NONE   ,/*14*/ MED_HEXA8  ,/*15*/ MED_HEXA20 ,
+       /*16*/ MED_PENTA6 ,/*17*/ MED_PENTA15,/*18*/ MED_NONE   ,/*19*/ MED_NONE   ,/*20*/ MED_NONE   ,
+       /*21*/ MED_NONE   ,/*22*/ MED_NONE   ,/*23*/ MED_TETRA4 ,/*24*/ MED_TETRA10,/*25*/ MED_PYRA5  ,
+       /*26*/ MED_PYRA13 ,/*27*/ MED_NONE   ,/*28*/ MED_NONE   ,/*29*/ MED_NONE   ,/*30*/ MED_NONE   ,
+       /*31*/ MED_NONE   ,/*32*/ MED_NONE   ,/*33*/ MED_NONE   ,/*34*/ MED_NONE   ,/*35*/ MED_NONE   ,
+       /*36*/ MED_NONE   ,/*37*/ MED_NONE   ,/*38*/ MED_NONE   ,/*39*/ MED_NONE   ,/*40*/ MED_NONE   ,
+       /*41*/ MED_NONE   ,/*42*/ MED_NONE   ,/*43*/ MED_NONE   ,/*44*/ MED_NONE   ,/*45*/ MED_NONE   ,
+       /*46*/ MED_NONE   ,/*47*/ MED_NONE   };
+/////
 
 // Every memory allocation made in the MedDriver members function are desallocated in the Mesh destructor 
 
@@ -33,10 +51,16 @@ GIBI_MESH_DRIVER::GIBI_MESH_DRIVER(const string & fileName,
                                    MESH * ptrMesh,
                                    MED_EN::med_mode_acces accessMode): 
   GENDRIVER(fileName,accessMode),
-  _ptrMesh(ptrMesh),
+  _ptrMesh(ptrMesh)
   // A VOIR _medIdt(MED_INVALID), 
-  _meshName("")
 {
+//   _meshName=fileName.substr(0,fileName.rfind("."));
+    // mesh name construction from fileName
+    const string ext=".sauve"; // expected extension
+    string::size_type pos=fileName.find(ext,0);
+    string::size_type pos1=fileName.rfind('/');
+    _meshName = string(fileName,pos1+1,pos-pos1-1); //get rid of directory & extension
+    SCRUTE(_meshName);
 }
   
 GIBI_MESH_DRIVER::GIBI_MESH_DRIVER(const GIBI_MESH_DRIVER & driver): 
@@ -54,40 +78,31 @@ GIBI_MESH_DRIVER::~GIBI_MESH_DRIVER()
 void GIBI_MESH_DRIVER::open()
   throw (MEDEXCEPTION)
 {
-  const char * LOC = "GIBI_MESH_DRIVER::open()" ;
-  BEGIN_OF(LOC);
-
-//   if (_medIdt > 0) 
-//     _status = MED_OPENED; 
-//   else {
-//     _medIdt = MED_INVALID;
-//     _status = MED_CLOSED;
-//     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Could not open file "<<_fileName<<" in mode "<<_accessMode));
-//   }
-  
+    const char * LOC = "GIBI_MESH_DRIVER::open()" ;
+    BEGIN_OF(LOC);
+
+    _gibi.open(_fileName.c_str(), ios::in);
+    if(_gibi)
+       _status = MED_OPENED;
+    else
+    {
+       _status = MED_CLOSED;
+       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Could not open file "<<_fileName<<" in mode ios::in"));
+    }
   END_OF(LOC);
 }
   
 void GIBI_MESH_DRIVER::close()
   throw (MEDEXCEPTION)
 {
-  const char * LOC = "GIBI_MESH_DRIVER::close() " ;
-  BEGIN_OF(LOC);
-
-//   int err = 0;
-//   if ( _status == MED_OPENED) {
-//     err=MED_FR::MEDfermer(_medIdt);
-//     H5close(); // If we call H5close() all the files are closed.
-//     if (err != 0)
-//       throw MEDEXCEPTION( LOCALIZED(STRING(LOC)
-//                                 <<" Error when closing file !"
-//                                 )
-//                       );
-//     _status = MED_CLOSED;
-//     _medIdt = MED_INVALID;
-//   }
-
-  END_OF(LOC);
+    const char * LOC = "GIBI_MESH_DRIVER::close() " ;
+    BEGIN_OF(LOC);
+    if ( _status == MED_OPENED) 
+    {
+       _gibi.close();
+       _status = MED_CLOSED;
+    }
+    END_OF(LOC);
 }
 
 void    GIBI_MESH_DRIVER::setMeshName(const string & meshName) { _meshName = meshName; };
@@ -99,42 +114,298 @@ string  GIBI_MESH_DRIVER::getMeshName() const { return _meshName; };
 GIBI_MESH_RDONLY_DRIVER::GIBI_MESH_RDONLY_DRIVER(): GIBI_MESH_DRIVER()
 {
 }
-  
+
 GIBI_MESH_RDONLY_DRIVER::GIBI_MESH_RDONLY_DRIVER(const string & fileName,
-                                                 MESH * ptrMesh):
-  GIBI_MESH_DRIVER(fileName,ptrMesh,MED_RDONLY)
+       MESH * ptrMesh):
+GIBI_MESH_DRIVER(fileName,ptrMesh,MED_RDONLY)
 { 
-  MESSAGE("GIBI_MESH_RDONLY_DRIVER::GIBI_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created");
+    MESSAGE("GIBI_MESH_RDONLY_DRIVER::GIBI_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created");
 }
-  
-GIBI_MESH_RDONLY_DRIVER::GIBI_MESH_RDONLY_DRIVER(const GIBI_MESH_RDONLY_DRIVER & driver): 
-  GIBI_MESH_DRIVER(driver)
+
+    GIBI_MESH_RDONLY_DRIVER::GIBI_MESH_RDONLY_DRIVER(const GIBI_MESH_RDONLY_DRIVER & driver): 
+GIBI_MESH_DRIVER(driver)
 {
 }
 
 GIBI_MESH_RDONLY_DRIVER::~GIBI_MESH_RDONLY_DRIVER()
 {
-  //MESSAGE("GIBI_MESH_RDONLY_DRIVER::~GIBI_MESH_RDONLY_DRIVER() has been destroyed");
+    //MESSAGE("GIBI_MESH_RDONLY_DRIVER::~GIBI_MESH_RDONLY_DRIVER() has been destroyed");
 }
   
 GENDRIVER * GIBI_MESH_RDONLY_DRIVER::copy(void) const
 {
-  return new GIBI_MESH_RDONLY_DRIVER(*this);
+    return new GIBI_MESH_RDONLY_DRIVER(*this);
 }
 
-void GIBI_MESH_RDONLY_DRIVER::read(void)
-  throw (MEDEXCEPTION)
+void GIBI_MESH_RDONLY_DRIVER::read(void) throw (MEDEXCEPTION)
 {
-  const char * LOC = "GIBI_MESH_RDONLY_DRIVER::read() : " ;
-  BEGIN_OF(LOC);
-  if (_status!=MED_OPENED)
-    throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "The _idt of file " << _fileName << " is : "  <<  " (the file is not opened)." )) ;
-
-  _ptrMesh->_name =  _meshName;
-  
-  END_OF(LOC);
+    const char * LOC = "GIBI_MESH_RDONLY_DRIVER::read() : " ;
+    BEGIN_OF(LOC);
+
+    if (_status!=MED_OPENED)
+       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "The _idt of file " << _fileName << " is : "  
+                                                <<  " (the file is not opened)." )) ;
+
+    // LECTURE DES DONNEES DS FICHIER GIBI
+
+    _intermediateMED medi; // structure de données intermédiaire pour conversion gibi->med
+    string buf_ligne; // pour lire une ligne
+    const char* enregistrement_type="ENREGISTREMENT DE TYPE";
+    std::vector<int> numero_noeuds; // tableau de travail (indices)
+
+
+    while ( getline(_gibi, buf_ligne) ) // boucle externe de recherche de "ENREGISTREMENT DE TYPE"
+    {
+       string::size_type pos = buf_ligne.find(enregistrement_type);
+       if ( pos==string::npos )
+           continue; // "ENREGISTREMENT DE TYPE" non trouvé -> on lit la ligne suivante
+
+       // lecture du numéro d'enregistrement
+       int numero_enregistrement;
+       istringstream buf(buf_ligne.c_str()+strlen(enregistrement_type)+1);
+       buf >> numero_enregistrement;
+
+       enum { ENREG_TYPE_2=2, ENREG_TYPE_4=4}; // énumération des types d'enregistrement traités
+       int niveau, niveau_erreur;
+       unsigned space_dimension,nb_reels;
+       int numero_pile, nb_objets_nommes, nb_objets, nb_indices;
+       string s1,s2,s3,s4,s5,s6,s7; // temporary strings
+       int i1; //temporary int
+       double d1; //temporary double
+       vector<int> indices_objets_nommes;
+       vector<string> objets_nommes;
+
+       switch (numero_enregistrement)
+         {
+         case ENREG_TYPE_4:
+           MESSAGE(LOC << "---- Traitement enregistrement de type 4");
+           _gibi >> s1 >> niveau >> s2 >> s3 >> niveau_erreur >> s4 >> space_dimension;
+           if ( !_gibi || s1!="NIVEAU" || s3!="ERREUR" || s4!="DIMENSION" ) // verification mots -cles
+             throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << " Could not read file " << _fileName 
+                                          << " : syntax error in type 4 record"));
+           break;
+
+         case ENREG_TYPE_2:
+           {
+             MESSAGE(LOC << "---- Traitement enregistrement de type 2");
+             _gibi >> s1 >> s2 >> numero_pile >> s3 >> s4 >> s5 >> nb_objets_nommes >> s6 >> s7 >> nb_objets;
+             if ( !_gibi || s1!="PILE"   || s2!="NUMERO"       || s3!="NBRE"  // verification mots -cles
+                  || s4!="OBJETS" || s5!="NOMMES"       || s6!="NBRE"   
+                  || s7!="OBJETS" || nb_objets_nommes<0 || nb_objets<0  )
+               {
+                 throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << " Could not read file " << _fileName 
+                                              << " : error in type 2 record"));
+               }
+
+             // lecture des objets nommés et de leurs indices
+             objets_nommes.resize(nb_objets_nommes);
+             indices_objets_nommes.resize(nb_objets_nommes);
+             for (int i=0; i!=nb_objets_nommes; ++i)
+               _gibi >> objets_nommes[i];
+
+             for (int i=0; i!=nb_objets_nommes; ++i)
+               _gibi >> indices_objets_nommes[i];
+               
+             // boucle interne : lecture de la pile
+             enum {PILE_SOUS_MAILLAGE=1, PILE_NOEUDS=32, PILE_COORDONNEES=33};
+             switch(numero_pile)
+               {
+               case PILE_SOUS_MAILLAGE:
+                 {
+                   medi.groupes.reserve(nb_objets);
+                   for (int objet=0; objet!=nb_objets; ++objet) // pour chaque groupe
+                     {
+                       unsigned type_geom_castem, nb_reference,nb_noeud,nb_elements, nb_sous_maillage;
+                       _gibi >> type_geom_castem >> nb_sous_maillage >> nb_reference >> nb_noeud >> nb_elements;
+                       
+                       // le cas type_geom_castem=0 correspond aux maillages composites
+                       if (type_geom_castem<0 || (type_geom_castem>0 && geomGIBItoMED[type_geom_castem-1]==MED_NONE) )
+                         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << " Error while reading file " << _fileName 
+                                                      << "\nCastem geometric type " << type_geom_castem 
+                                                      << " does not have a correspondant MED geometric type!" ));
+
+                       // lecture des references (non utilisé pour MED)
+                       for( unsigned i=0; i!=nb_reference; ++i)
+                         _gibi >> i1;
+                       
+                       // lecture des couleurs (non utilisé pour MED)
+                       for( unsigned i=0; i!=nb_elements; ++i)
+                         _gibi >> i1;
+                       
+                       _groupe groupe;
+                       // si le groupe se compose de sous-maillages (ie groupe composite) 
+                       if (type_geom_castem==0 && nb_sous_maillage>0) 
+                         {
+                           // lecture des indices des sous-maillages, stockage.
+                           // les mailles correspondant a ces sous_maillages seront inserees a la fin du case
+                           for (unsigned i=0; i!=nb_sous_maillage; ++i)
+                             {
+                               _gibi >> i1;
+                               groupe.groupes.push_back(i1);
+                             }
+                         }
+                       else
+                         {
+                           pair<set<_maille>::iterator,bool> p;
+                           pair<map<int,_noeud>::iterator,bool> p_no;
+                           _noeud no;
+                           no.coord.reserve(space_dimension);
+                           no.coord.resize(space_dimension);
+                           _maille ma(geomGIBItoMED[type_geom_castem-1], nb_noeud);
+                           ma.sommets.resize(nb_noeud);
+
+                           // lecture pour chaque maille des sommets et insertions
+                           for( unsigned i=0; i!=nb_elements; ++i)
+                             {
+                               for (unsigned n=0; n!=nb_noeud; ++n)
+                                 {
+                                   _gibi >> i1;
+                                   no.number=i1;
+                                   p_no=medi.points.insert(make_pair(i1, no));
+                                   ma.sommets[n]=p_no.first;
+                                 }
+
+                               p=medi.maillage.insert(ma);
+                               groupe.mailles.insert(p.first); // on stocke dans le groupe un iterateur sur la maille
+
+//                                 cout << "   " << p.second << ": ";
+//                                 for (unsigned n=0; n!=nb_noeud; ++n)
+//                                     cout <<  ma.sommets[n]->second.number << " ";
+//                                 cout << endl;
+                               
+                             }
+                         }
+                       medi.groupes.push_back(groupe);
+                     }
+
+                   for (int i=0; i!=nb_objets_nommes; ++i)
+                     medi.groupes[indices_objets_nommes[i]-1].nom=objets_nommes[i];
+                   
+                   // scanne les groupes à la recherche de groupes composites
+                   for( std::vector<_groupe>::iterator i=medi.groupes.begin(); i!=medi.groupes.end(); ++i)
+                     {
+                       if( i->groupes.size() ) // le groupe i contient des sous-maillages
+                         {
+                           for( std::vector<int>::iterator j=i->groupes.begin(); j!=i->groupes.end(); ++j)
+                             {
+                               // pour chacun des sous-maillages j, on recupere les iterateurs *k sur les  maille 
+                               // contenues et on les insere dans le groupe i
+                               std::set< std::set<_maille>::iterator >::const_iterator k=medi.groupes[*j-1].mailles.begin();
+                               for( ; k!=medi.groupes[*j-1].mailles.end(); ++k)
+                                 i->mailles.insert(*k);
+                             }
+                           i->groupes.clear(); // après avoir inséré leur mailles, on efface les groupes composites
+                         }
+                     }
+                   
+                   break;
+                 }// Fin case PILE_SOUS_MAILLAGE
+                       
+               case PILE_NOEUDS:
+                 {
+                   std::vector<int> place_noeuds;
+                   _gibi >> nb_indices;
+                   if (nb_indices != nb_objets)
+                     {
+                       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << " Could not read file " << _fileName 
+                                                    << "Erreur de lecture dans enregistrement de type " << ENREG_TYPE_2 
+                                                    << " (pile " << PILE_NOEUDS << ")" ));
+                     }
+                   
+                   place_noeuds.resize(nb_objets);
+                   for (unsigned i=0; i!=place_noeuds.size(); ++i)
+                     _gibi >> place_noeuds[i];
+                   int max=(* std::max_element(place_noeuds.begin(),place_noeuds.end()));
+
+                   // numero_noeuds contient pour chacun des max noeuds qu'on va lire dans le case PILE_COORDONNEES
+                   // son indice dans la connectivite du maillage. Cet indice correspond egalement a la cle du map
+                   // medi.points ou l'on stocke les noeuds.
+                   numero_noeuds.resize(max,-1);
+                   for (unsigned i=0; i!=place_noeuds.size(); ++i)
+                     numero_noeuds[place_noeuds[i]-1]=i+1;
+                   break;
+                 }
+                 
+               case PILE_COORDONNEES:
+                 _gibi >> nb_reels;
+                 // PROVISOIRE : certains fichier gibi n'ont 
+                 if (nb_reels < numero_noeuds.size()*(space_dimension))
+                   throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << " Could not read file " << _fileName 
+                                                << "Erreur de lecture dans enregistrement de type " << ENREG_TYPE_2 
+                                                << " (pile " << PILE_COORDONNEES << ")" ));
+
+                 for (unsigned i=0; i!=numero_noeuds.size(); ++i)
+                   {
+                     // si le noeud est utilisé dans le maillage, on lit ses coordonnées et on les stocke dans la structure
+                     if ( (numero_noeuds[i] != -1) && (medi.points.find(numero_noeuds[i])!=medi.points.end()) ) 
+                       {
+                         for (unsigned j=0; j!=space_dimension; ++j)
+                           _gibi >> medi.points[numero_noeuds[i]].coord[j];
+                         _gibi >> d1; // on ne conserve pas la densite
+                       }
+                     else // sinon, on passe au noeud suivant
+                       {
+                         for (unsigned j=0; j!=space_dimension+1; ++j)
+                           _gibi >> d1;
+                       }
+                   }
+                 break;
+
+               } // Fin switch numero_pile
+             break;
+           } // Fin case ENREG_TYPE_2
+         }
+
+    } //  fin de la boucle while de lecture externe
+
+    // impression résultats
+    MESSAGE(LOC << "GIBI_MESH_RDONLY_DRIVER::read : RESULTATS STRUCTURE INTERMEDIAIRES : ");
+    MESSAGE(LOC <<  medi );
+
+           // TRANSFORMATION EN STRUCTURES MED
+    if ( ! _ptrMesh->isEmpty() )
+    {
+       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Mesh object not empty : can't fill it!"));
+    }
+    else if ( medi.maillage.size()==0 || medi.groupes.size()==0 || medi.points.size()==0)
+    {
+       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << " Error while reading file " << _fileName 
+                   << " The data read are not completed " ) ) ;
+    }
+    else
+    {
+       _ptrMesh->_name = _meshName;
+       _ptrMesh->_spaceDimension = medi.points.begin()->second.coord.size();
+       _ptrMesh->_meshDimension = medi.maillage.rbegin()->dimension();
+       _ptrMesh->_numberOfNodes = medi.points.size();
+       _ptrMesh->_isAGrid = 0;
+       _ptrMesh->_coordinate = medi.getCoordinate();
+
+       //Construction des groupes
+       vector<GROUP *> groupCell, groupFace, groupEdge, groupNode;
+       medi.getGroups(groupCell, groupFace, groupEdge, groupNode, _ptrMesh);
+       _ptrMesh->_groupCell = groupCell;
+       _ptrMesh->_groupFace = groupFace;
+       _ptrMesh->_groupEdge = groupEdge;
+       _ptrMesh->_groupNode = groupNode;
+
+       // appele en dernier car cette fonction detruit le maillage intermediaire!
+       _ptrMesh->_connectivity = medi.getConnectivity(); 
+
+       // calcul de la connectivite d-1 complete, avec renumerotation des groupes
+       //if (_ptrMesh->_spaceDimension==3)
+       //    _ptrMesh->_connectivity->updateGroup(_ptrMesh->_groupFace) ;
+       //else if (_ptrMesh->_spaceDimension==2)
+       //    _ptrMesh->_connectivity->updateGroup(_ptrMesh->_groupEdge) ;
+       
+       // Creation des familles à partir des groupes
+       // NC : Cet appel pourra être différé quand la gestion de la cohérence famille/groupes sera assurée
+       _ptrMesh->createFamilies();
+    }
+
+
+
+    END_OF(LOC);
 }
 
 void GIBI_MESH_RDONLY_DRIVER::write( void ) const