Back to index

salome-med  6.5.0
MEDMEM_PorflowMeshDriver.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 #include "MEDMEM_PorflowMeshDriver.hxx"
00024 #include "MEDMEM_DriversDef.hxx"
00025 #include "MEDMEM_DriverTools.hxx"
00026 
00027 #include "MEDMEM_Family.hxx"
00028 #include "MEDMEM_Group.hxx"
00029 #include "MEDMEM_Coordinate.hxx"
00030 #include "MEDMEM_Connectivity.hxx"
00031 #include "MEDMEM_Mesh.hxx"
00032 #include "MEDMEM_CellModel.hxx"
00033 #include "MEDMEM_define.hxx"
00034 #include <string.h>
00035 #include <ctype.h>
00036 #include <iostream>
00037 #include <sstream>
00038 #include <iomanip>
00039 
00040 using namespace std;
00041 using namespace MED_EN;
00042 using namespace MEDMEM;
00043 
00044 // geometric types conversion from PORFLOW -> MED
00045 //const size_t PORFLOW_MESH_DRIVER::nb_geometrie_porflow;
00046 const medGeometryElement PORFLOW_MESH_DRIVER::geomPORFLOWtoMED[nb_geometrie_porflow] =
00047   {   /*  1  */ MED_TRIA3   ,/*  2  */ MED_QUAD4  ,/*  3  */ MED_TETRA4  ,/*  4  */ MED_PYRA5  ,
00048       /*  5  */ MED_PENTA6  ,/*  6  */ MED_HEXA8   };
00049 // indirection table from PORFLOW order to MED one for nodes numerotation in all PORFLOW geometries
00050 //const size_t PORFLOW_MESH_DRIVER::nb_nodes_max;
00051 
00052 // conversion from porflow connectivity to MED connectivity
00053 const int PORFLOW_MESH_DRIVER::numPORFLOWtoMED[nb_geometrie_porflow] [nb_nodes_max] = {
00054       /*  TRI3   */ { /*1*/ 1, /*2*/ 3, /*3*/ 2 },
00055       /*  QUA4   */ { /*1*/ 1, /*2*/ 4, /*3*/ 3, /*4*/ 2 },
00056       /*  TETRA4 */ { /*1*/ 1, /*2*/ 4, /*3*/ 3, /*4*/ 2 },
00057       /*  PYRA5  */ { /*1*/ 1, /*2*/ 4, /*3*/ 3, /*4*/ 2, /*5*/ 5 },
00058       /*  PENTA6 */ { /*1*/ 1, /*2*/ 3, /*3*/ 2, /*4*/ 4, /*5*/ 6, /*6*/ 5 },
00059       /*  HEXA8  */ { /*1*/ 1, /*2*/ 4, /*3*/ 3, /*4*/ 2, /*5*/ 5, /*6*/ 8, /*7*/ 7, /*8*/ 6 } };
00060 
00061 // Porflox nodal connectivity of faces - documented in Porflow user's manual
00062 //const size_t PORFLOW_MESH_DRIVER::nb_faces_max;
00063 //const size_t PORFLOW_MESH_DRIVER::nb_nodes2_max;
00064 const int PORFLOW_MESH_DRIVER::connectivityPORFLOW[nb_geometrie_porflow][nb_faces_max][nb_nodes2_max]={
00065   //{/* TRI3   */ {3,1,0,0}, {1,2,0,0}, {2,3,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0} },
00066   //{/* QUA4   */ {1,4,0,0}, {2,3,0,0}, {1,2,0,0}, {3,4,0,0}, {0,0,0,0}, {0,0,0,0} },
00067     {/* TRI3   */ {1,3,0,0}, {2,1,0,0}, {3,2,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0} },
00068     {/* QUA4   */ {1,4,0,0}, {3,2,0,0}, {2,1,0,0}, {4,3,0,0}, {0,0,0,0}, {0,0,0,0} },
00069     {/* TETRA4 */ {1,3,4,0}, {1,4,2,0}, {4,3,2,0}, {1,2,3,0}, {0,0,0,0}, {0,0,0,0} },
00070     {/* PYRA5  */ {1,4,5,0}, {1,5,2,0}, {3,2,5,0}, {4,3,5,0}, {1,2,3,4}, {0,0,0,0} },
00071     {/* PENTA6 */ {1,3,6,4}, {2,1,4,5}, {3,2,5,6}, {1,2,3,0}, {4,6,5,0}, {0,0,0,0} },
00072     {/* HEXA8  */ {1,4,8,5}, {3,2,6,7}, {2,1,5,6}, {4,3,7,8}, {1,2,3,4}, {5,8,7,6} },
00073 };
00074 
00075 // helper function
00076 inline static bool isKeyWord(const string & line, const char * key);
00077 inline static void locateFileName(const string& line, string::size_type& pos1, string::size_type& pos2);
00078 inline static string getPorflowFileName(const string& line, const char * context);
00079 inline static medGeometryElement get2DMedGeomType(int nbSommets);
00080 
00081 
00082 // Every memory allocation made in the MedDriver members function are desallocated in the Mesh destructor 
00083 
00084 PORFLOW_MESH_DRIVER::PORFLOW_MESH_DRIVER():
00085   GENDRIVER(PORFLOW_DRIVER),
00086   _ptrMesh(( MESH *) NULL),
00087   // A VOIR _medIdt(MED_INVALID),
00088   _meshName("")
00089 {
00090 }
00091 
00092 PORFLOW_MESH_DRIVER::PORFLOW_MESH_DRIVER(const string & fileName,
00093                                          GMESH *        ptrMesh,
00094                                          MED_EN::med_mode_acces accessMode): 
00095   GENDRIVER(fileName, accessMode, PORFLOW_DRIVER),
00096   _ptrMesh(0)
00097 {
00098   if (ptrMesh)
00099     _ptrMesh = const_cast<MESH*>( ptrMesh->convertInMESH() );
00100   // mesh name construction from fileName
00101   const string ext=".inp"; // expected extension
00102   string::size_type pos=fileName.find(ext,0);
00103   string::size_type pos1=fileName.rfind('/');
00104 #ifdef WNT
00105   if (pos1 == string::npos ) pos1=fileName.rfind('\\');
00106 #endif
00107   if (pos1 != string::npos )
00108     _meshName = string(fileName,pos1+1,pos-pos1-1); //get rid of directory & extension
00109   else
00110     _meshName = string(fileName,0,pos); //get rid of directory & extension
00111   SCRUTE_MED(_meshName);
00112 }
00113 
00114 PORFLOW_MESH_DRIVER::PORFLOW_MESH_DRIVER(const PORFLOW_MESH_DRIVER & driver): 
00115   GENDRIVER(driver),
00116   _ptrMesh(driver._ptrMesh),
00117   // A VOIR _medIdt(MED_INVALID), 
00118   _meshName(driver._meshName)
00119 {
00120   if (_ptrMesh)
00121     _ptrMesh->addReference();
00122 }
00123 
00124 PORFLOW_MESH_DRIVER::~PORFLOW_MESH_DRIVER()
00125 {
00126   if (_ptrMesh)
00127     _ptrMesh->removeReference();
00128 }
00129 
00130 void PORFLOW_MESH_DRIVER::open()
00131   throw (MEDEXCEPTION)
00132 {
00133     const char * LOC = "PORFLOW_MESH_DRIVER::open()" ;
00134     BEGIN_OF_MED(LOC);
00135 
00136     if (_status == MED_OPENED)
00137       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"File "<<_fileName<<" is already open"));
00138 
00139     _porflow.open(_fileName.c_str(), ios::in);
00140     if(_porflow)
00141         _status = MED_OPENED;
00142     else
00143     {
00144         _status = MED_CLOSED;
00145         throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Could not open file "<<_fileName<<" in mode ios::in"));
00146     }
00147   END_OF_MED(LOC);
00148 }
00149   
00150 void PORFLOW_MESH_DRIVER::close()
00151   throw (MEDEXCEPTION)
00152 {
00153   const char* LOC = "PORFLOW_MESH_DRIVER::close() ";
00154   BEGIN_OF_MED(LOC);
00155   if ( _status == MED_OPENED) {
00156     _porflow.close();
00157     _status = MED_CLOSED;
00158   }
00159   END_OF_MED(LOC);
00160 }
00161 
00162 void    PORFLOW_MESH_DRIVER::setMeshName(const string & meshName) { _meshName = meshName; }
00163 string  PORFLOW_MESH_DRIVER::getMeshName() const { return _meshName; }
00164 
00165 
00166 //---------------------------------- RDONLY PART -------------------------------------------------------------
00167 
00168 PORFLOW_MESH_RDONLY_DRIVER::PORFLOW_MESH_RDONLY_DRIVER(): PORFLOW_MESH_DRIVER()
00169 {
00170 }
00171   
00172 PORFLOW_MESH_RDONLY_DRIVER::PORFLOW_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh):
00173   PORFLOW_MESH_DRIVER(fileName,ptrMesh,RDONLY)
00174 {
00175   MESSAGE_MED("PORFLOW_MESH_RDONLY_DRIVER::PORFLOW_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created");
00176 }
00177   
00178 PORFLOW_MESH_RDONLY_DRIVER::PORFLOW_MESH_RDONLY_DRIVER(const PORFLOW_MESH_RDONLY_DRIVER & driver): 
00179   PORFLOW_MESH_DRIVER(driver)
00180 {
00181 }
00182 
00183 PORFLOW_MESH_RDONLY_DRIVER::~PORFLOW_MESH_RDONLY_DRIVER()
00184 {
00185   //MESSAGE_MED("PORFLOW_MESH_RDONLY_DRIVER::~PORFLOW_MESH_RDONLY_DRIVER() has been destroyed");
00186 }
00187   
00188 GENDRIVER * PORFLOW_MESH_RDONLY_DRIVER::copy(void) const
00189 {
00190   return new PORFLOW_MESH_RDONLY_DRIVER(*this);
00191 }
00192 
00193 // helper function to check if line starts with key
00194 inline static bool isKeyWord(const string & line, const char * key)
00195 {
00196     const int SIZE_KEY=4;
00197     const char * pt=line.c_str();
00198     while( isspace(*pt) ) // get rid of leading blanks
00199         ++pt;
00200     return !strncmp(pt,key,SIZE_KEY);
00201 }
00202 
00203 inline static void locateFileName(const string& line, string::size_type& pos1, string::size_type& pos2)
00204 {
00205     pos1 = line.find('"',0);
00206     if ( pos1 != string::npos ) // if we found "
00207         pos2=line.find('"',pos1+1); // search a second "
00208     else // we didn't succeed with double quotes, so we try single quotes
00209     {
00210         pos1 = line.find('\'',0);
00211         if ( pos1 != string::npos ) // if we found '
00212             pos2=line.find('\'',pos1+1); // search a second '
00213     }
00214 }
00215 
00216 
00217 // helper fonction : inversion of PORFLOW_MESH_DRIVER::geomPORFLOWtoMED
00218 // return the Porflow geometric type, -1 if not found
00219 inline int PORFLOW_MESH_DRIVER::geomMEDtoPorflow(medGeometryElement medGeo)
00220 {
00221     for (int g=0; g!=nb_geometrie_porflow; ++g)
00222         if( medGeo == geomPORFLOWtoMED[g] )
00223             return g;
00224     return -1;
00225 }
00226 
00227 
00228 // Correspondance between the number of nodes and the Med face geometric type
00229 inline static medGeometryElement get2DMedGeomType(int nbSommets)
00230 {
00231     switch (nbSommets)
00232     {
00233         case 2:
00234             return MED_SEG2;
00235             break;
00236         case 3:
00237             return MED_TRIA3;
00238             break;
00239         case 4:
00240             return MED_QUAD4;
00241             break;
00242     }
00243     return MED_NONE;
00244 }
00245 
00246 // helper function to read a porflow file name (enclosed in single or double quotes) in line
00247 inline static string getPorflowFileName(const string& line, const char * context)
00248 {
00249     string::size_type pos1=string::npos;
00250     string::size_type pos2=string::npos;
00251 
00252     locateFileName(line, pos1, pos2);
00253 
00254     // if we found a not empty filename
00255     if (pos1 != string::npos && pos2 != string::npos && pos2>pos1+1)
00256         return string(line,pos1+1,pos2-pos1-1);
00257 
00258     // else, we throw an exception
00259     string diagnosis("PORFLOW_MESH_RDONLY_DRIVER::read() : Error after reading keyword ");
00260     diagnosis+=context;
00261     diagnosis+="\nNo filename was found enclosed in single or double quotes\n";
00262     throw MEDEXCEPTION(diagnosis.c_str());
00263 }
00264 
00265 
00266 // helper function to read a porflow coordinate file ( .xyz )
00267 void PORFLOW_MESH_RDONLY_DRIVER::readPorflowCoordinateFile(const string & coorFileName,_intermediateMED & medi,const int space_dimension)
00268 {
00269 
00270     ifstream coorFile(coorFileName.c_str(), ios::in);
00271     if(!coorFile)
00272     {
00273         string diagnosis("PORFLOW_MESH_RDONLY_DRIVER::read()\nError, can't open coordinates file :");
00274         diagnosis+=coorFileName;
00275         throw MEDEXCEPTION(diagnosis.c_str());
00276     }
00277     
00278     // scan of the coord file
00279     _noeud node;
00280     node.coord.resize(space_dimension);
00281     string buf_ligne; // to read a line
00282     while ( getline(coorFile, buf_ligne) ) // we can't use input stream directly because some 2D files have "0.0" in third coordinate
00283       {
00284         istringstream buf(buf_ligne.c_str());
00285         buf >> node.number;
00286         if (!buf) // for spaces at the end of the file
00287           break;
00288         for (int i=0; i!=space_dimension; ++i)
00289           buf >> node.coord[i];
00290         medi.points.insert(make_pair(node.number,node));
00291       }
00292     coorFile.close();
00293 }
00294 
00295 // helper function to read a porflow connectivity file ( .cnc )
00296 void PORFLOW_MESH_RDONLY_DRIVER::readPorflowConnectivityFile(bool hybride,const string & connecFileName,_intermediateMED & medi,std::vector<std::set<_maille>::iterator>& p_ma_table,int mesh_dimension)
00297 {
00298 
00299     ifstream connFile(connecFileName.c_str(), ios::in);
00300     if(!connFile)
00301     {
00302         string diagnosis("PORFLOW_MESH_RDONLY_DRIVER::read()\nError, can't open connectivity file :");
00303         diagnosis+=connecFileName;
00304         throw MEDEXCEPTION(diagnosis.c_str());
00305     }
00306 
00307     _maille maille;
00308     unsigned int code, nodes_number, node, ordre;
00309     set<_maille>::iterator p_ma;
00310 
00311     if (hybride) // "HYBR" key-word
00312       while (connFile)
00313         {
00314           connFile >> ordre;
00315           maille.setOrdre( ordre );
00316           if (!connFile) // for spaces at the end of the file
00317             break;
00318           connFile >> code;
00319           connFile >> nodes_number;
00320           maille.geometricType = geomPORFLOWtoMED[code-1];
00321           if(maille.geometricType%100!=(int)nodes_number) // following incohenrences founded in some porflow files!
00322           {
00323               MESSAGE_MED("WARNING : the read node number don't seem to be compatible with geometric type!");
00324               SCRUTE_MED(maille.geometricType);
00325               SCRUTE_MED(nodes_number);
00326           }
00327           maille.sommets.resize(nodes_number);
00328           for (unsigned i=0; i!=nodes_number; ++i)
00329             {
00330               connFile >> node;
00331               maille.sommets[numPORFLOWtoMED[code-1][i]-1] = medi.points.find(node);
00332             }
00333           p_ma = medi.insert(maille);
00334           if (maille.ordre() > p_ma_table.size()-1) // construction of a vector of iterators on _maille structures
00335             p_ma_table.resize(2*maille.ordre());
00336           p_ma_table[maille.ordre()] = p_ma;
00337         }
00338     else // default case (or "VERT" key-word)
00339       {
00340         if (mesh_dimension == 2) // we have QUA4
00341           {
00342             code = 2;
00343             maille.geometricType = geomPORFLOWtoMED[code-1];
00344             nodes_number = 4;
00345             maille.sommets.resize(nodes_number);
00346           }
00347         else if (mesh_dimension == 3) // we have HEXA8
00348           {
00349             code = 6;
00350             maille.geometricType = geomPORFLOWtoMED[code-1];
00351             nodes_number = 8;
00352             maille.sommets.resize(nodes_number);
00353           }
00354         else
00355           throw MEDEXCEPTION("PORFLOW_MESH_RDONLY_DRIVER::read()\nError, can't determine geometric type for this VERT mesh");
00356         while (connFile)
00357           {
00358             connFile >> ordre; maille.setOrdre(ordre);
00359             if (!connFile) // for spaces at the end of the file
00360               break;
00361             for (unsigned i=0; i!=nodes_number; ++i)
00362               {
00363                 connFile >> node;
00364                 maille.sommets[numPORFLOWtoMED[code-1][i]-1] = medi.points.find(node);
00365               }
00366             p_ma = medi.insert(maille);
00367             if (maille.ordre() > p_ma_table.size()-1) // construction of a vector of iterators on _maille structures
00368               p_ma_table.resize(2*maille.ordre());
00369             p_ma_table[maille.ordre()] = p_ma;
00370           }
00371       }
00372     connFile.close();
00373 }
00374 
00375 void PORFLOW_MESH_RDONLY_DRIVER::read(void)
00376   throw (MEDEXCEPTION)
00377 {
00378     const char * LOC = "PORFLOW_MESH_RDONLY_DRIVER::read() : " ;
00379     BEGIN_OF_MED(LOC);
00380 
00381     if (_status!=MED_OPENED)
00382         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "The _idt of file " << _fileName 
00383                     << " is : "  <<  " (the file is not opened)." )) ;
00384 
00385     // if _fileName contains a directory, extract the directory name
00386     // the directory name will be used to locate the files included in _fileName.
00387     string dirName;
00388     string::size_type pos=_fileName.rfind('/');
00389 #ifdef WNT
00390     if (pos == string::npos ) pos=_fileName.rfind('\\');
00391 #endif
00392     if (pos != string::npos )
00393         dirName=string(_fileName, 0, pos+1);
00394 
00395     _intermediateMED medi; // structure de données intermédiaire pour conversion porflow->med
00396     string buf_ligne; // pour lire une ligne
00397     unsigned numberOfGridElement=0; // number of grid elements
00398     unsigned space_dimension=2;  // by default, the problem is assumed to be 2D
00399     string coordinateSystem="CARTESIAN";
00400     bool hybride=false;
00401     _groupe currentGroup;
00402     vector<bool> isGroupAList; // vector to store the type of a group (ie PAIR or LIST)
00403     bool processLoca=false;
00404     string connFileName;
00405     string coorFileName;
00406     std::vector<std::set<_maille>::iterator> p_ma_table(10000); // store iterators for direct access by index
00407     string small("abcdefghijklmnopqrstuvwxyz");
00408 
00409     while ( getline(_porflow, buf_ligne) ) // scan .inp file and look for main keywords (LOCA, GRID, COOR & CONN)
00410     {
00411 
00412         // Skip comments
00413         if(buf_ligne[0]=='/')
00414             continue; 
00415         
00416         // look if there is a filename
00417         string::size_type pos1=string::npos;
00418         string::size_type pos2=string::npos;
00419         locateFileName(buf_ligne, pos1, pos2);
00420         
00421         pos=0;
00422         if (pos1!=string::npos && pos2!=string::npos) // if there is a file name in buf_line
00423             // convert every char to upper, except those between pos1-pos2 (which correspond to a file name)
00424             while ( (pos=buf_ligne.find_first_of(small,pos)) != string::npos )
00425                 if (pos<pos1 || pos>pos2 )
00426                     buf_ligne[pos]=toupper(buf_ligne[pos]);
00427                 else
00428                     ++pos;
00429         else
00430             // convert every char to upper
00431             while ( (pos=buf_ligne.find_first_of(small,pos)) != string::npos )
00432                 buf_ligne[pos]=toupper(buf_ligne[pos]);
00433 
00434         
00435         // LOCA KEYWORD :
00436         //   expected syntax : 
00437         //      - LOCA {PAIR} [ID=id] {N1,N2, ... ,Nn} : group specification by paired element & surface numbers
00438         //      - LOCA {LIST} [ID=id] {N1, ... ,Nn}    : group specification by a list of elements
00439         //   the syntax corresponding to the use of input file is not implemented
00440         if ( isKeyWord(buf_ligne,"LOCA") )
00441         {
00442             MESSAGE_MED("Mot clé LOCA détecté");
00443             processLoca=true;
00444             // if currentGroup is not empty, a group has been precessed 
00445             //  -> we store it, clear currentGroup, and start the precessing of a new group
00446             if ( !currentGroup.groupes.empty() )
00447                 medi.groupes.push_back(currentGroup);
00448             currentGroup.groupes.clear();
00449             currentGroup.nom.erase();
00450             if ( buf_ligne.find("PAIR",0) != string::npos )
00451             {
00452                 isGroupAList.push_back(false);
00453             }
00454             else if ( buf_ligne.find("LIST",0) != string::npos )
00455             {
00456                 isGroupAList.push_back(true);
00457             }
00458             else
00459                 throw MEDEXCEPTION("PORFLOW_MESH_RDONLY_DRIVER::read() : Error, after keyword LOCA, LIST or PAIR is expected\n");
00460                 
00461             pos=buf_ligne.find("ID=",0);
00462             if ( pos != string::npos )
00463             {
00464                 istringstream buf(buf_ligne.c_str()+pos+3);
00465                 buf >> currentGroup.nom;
00466 
00467                 // avoid problem in the following processing of elements if the group's name contains a digit
00468                 // -> we replace group's name with blanks
00469                 while( pos<buf_ligne.size() && !isspace( buf_ligne[pos] ) )
00470                     buf_ligne[pos++]=' ';
00471             }
00472         }
00473 
00474 
00475         // GRID KEYWORD :
00476         //   expected syntax : GRID {UNST} [THREE] {N1} [NODE] [N2]
00477         //   the syntax corresponding to structured grids is not implemented
00478         else if ( isKeyWord(buf_ligne,"GRID") )
00479         {
00480             MESSAGE_MED("Mot clé GRID détecté");
00481             processLoca=false;
00482             pos=buf_ligne.find("UNST",0);
00483             if ( pos != string::npos ) // unstructured grid
00484             {
00485                 // we find the number of grid elements
00486                 string::size_type len=buf_ligne.size();
00487                 while ( pos<len && !isdigit(buf_ligne[pos]) )
00488                         ++pos;
00489                 if ( pos==len )
00490                     throw MEDEXCEPTION("PORFLOW_MESH_RDONLY_DRIVER::read() : Error, number of grid elements unspecified!\n");
00491                 istringstream buf(buf_ligne.c_str()+pos);
00492                 buf >> numberOfGridElement;
00493 
00494                 pos=buf_ligne.find("THREE",0);
00495                 if ( pos != string::npos ) // if we find THREE, the problem is 3D
00496                     space_dimension=3;
00497             }
00498             else
00499             {
00500                 throw MEDEXCEPTION("PORFLOW_MESH_RDONLY_DRIVER::read() : Error, structured grids are not yet supported!\n");
00501             }
00502         }
00503         
00504 
00505         // CONN KEYWORD :
00506         //   expected syntax : 
00507         //      - CONN {HYBR} {filename} : vertex connectivity for mixed hybrid elements
00508         //      - CONN {VERT} {filename} : vertex connectivity for quad or hex elements
00509         //   the default option is HYBR
00510         else if ( isKeyWord(buf_ligne,"CONN") )
00511         {
00512             MESSAGE_MED("Mot clé CONN détecté");
00513             processLoca=false;
00514             string fileCONN=getPorflowFileName(buf_ligne,"CONN");
00515             
00516             if ( buf_ligne.find("HYBR",0) != string::npos )
00517                 hybride=true;
00518 
00519 
00520             if(fileCONN.rfind('/') == string::npos)
00521                 // no directory was specified -> we add dirName, which may be empty
00522 
00523                 connFileName=dirName+fileCONN;
00524             else
00525                 connFileName=fileCONN;
00526         }
00527 
00528         
00529         // COOR KEYWORD :
00530         //   expected syntax : COOR {VERT} {filename}
00531         else if ( isKeyWord(buf_ligne,"COOR") )
00532         {
00533             MESSAGE_MED("Mot clé COOR");
00534             processLoca=false;
00535             string fileCOOR=getPorflowFileName(buf_ligne,"COOR");
00536 
00537             pos=buf_ligne.find("VERT",0);
00538             if ( pos == string::npos ) 
00539                 throw MEDEXCEPTION("PORFLOW_MESH_RDONLY_DRIVER::read() : Error, after keyword COOR, we require VERT\n");
00540 
00541             pos=buf_ligne.find("CYLI",0);
00542             if ( pos != string::npos )
00543                 coordinateSystem="CYLINDRICAL";
00544 
00545             if(fileCOOR.rfind('/') == string::npos)
00546                 // no directory was specified -> we add dirName, which may be empty
00547                 coorFileName=dirName+fileCOOR;
00548             else
00549                 coorFileName=fileCOOR;
00550         }
00551 
00552 
00553         if (processLoca) 
00554         {
00555             // read group specification
00556 
00557 
00558             // replace non digit caracters with blanks
00559             string::iterator last_non_blank=buf_ligne.end();
00560             for (string::iterator it=buf_ligne.begin(); it!=buf_ligne.end(); ++it)
00561                 if ( !isdigit(*it) )
00562                     *it=' ';
00563                 else
00564                     last_non_blank=it;
00565 
00566             if (last_non_blank != buf_ligne.end() ) // if the line is not blank
00567             {
00568                 buf_ligne=string(buf_ligne.begin(),++last_non_blank); // suppress trailing blanks
00569 
00570                 istringstream buf(buf_ligne.c_str());
00571                 int i1;
00572                 buf >> i1; // we know the line is not blank
00573                 do
00574                 {
00575                     currentGroup.groupes.push_back(i1);
00576                     buf >> i1;
00577                 }
00578                 while ( buf );
00579 
00580             }
00581         }
00582         
00583     }
00584     if ( !currentGroup.groupes.empty() ) // if necessary, add the last group to medi.groupes
00585         medi.groupes.push_back(currentGroup);
00586 
00587     readPorflowCoordinateFile(coorFileName,medi,space_dimension);
00588     readPorflowConnectivityFile(hybride,connFileName,medi,p_ma_table,space_dimension);
00589 
00590 
00591     // Group processing :
00592     //   In the scan loop, we have store in medi.groupes.groupes either :
00593     //     - paired list of element and surface number (keyword PAIR)
00594     //     - an explicit list of element numbers (keyword LIST)
00595     //   What we stored (pairs or list) is remembered through vector isGroupAList.
00596     //   For both cases, we must convert these numbers to iterators to cells inside the set medi.maillage
00597     //     - in the LIST case, these cells already exist.
00598     //     - in the PAIR case, we have to create the corresponding 2D/1D faces
00599     // scan groups
00600     //for( std::vector<_groupe>::iterator i=medi.groupes.begin(); i!=medi.groupes.end(); ++i)
00601     for( unsigned i=0; i!=medi.groupes.size(); ++i)
00602     {
00603         if ( isGroupAList[i] ) 
00604         {
00605             // medi.groupes[i].groupes is a vector of element numbers; it points to it
00606             medi.groupes[i].mailles.resize( medi.groupes[i].groupes.size() );
00607             std::vector<int>::const_iterator it=medi.groupes[i].groupes.begin();
00608             for(int j = 0 ; it!=medi.groupes[i].groupes.end(); ++it, ++j)
00609             {
00610                 // insert the iterator to the corresponding cell we stored in p_ma_table
00611                 medi.groupes[i].mailles[j] = p_ma_table[*it];
00612             }
00613             
00614         }
00615         else
00616         {
00617             int nelem=0;
00618             int nface=0;
00619             int ngeom=0;
00620             int ielem=0;
00621             std::set<_maille>::iterator p_ma;
00622             _maille maille2D;
00623             
00624             // medi.groupes[i].groupes is a vector of paired element and surface numbers
00625             // *it points to the element number,  *(it+1) points to the surface number
00626             std::vector<int>::const_iterator it=medi.groupes[i].groupes.begin();
00627             medi.groupes[i].mailles.resize( medi.groupes[i].groupes.size() / 2 );
00628             for(  ; it!=medi.groupes[i].groupes.end(); ++it)
00629             {
00630                 nelem=*it;
00631                 nface=*(++it);
00632                 p_ma=p_ma_table[nelem]; // points to the cell
00633                 ngeom=geomMEDtoPorflow(p_ma->geometricType);
00634 
00635                 // create the face corresponding to nface
00636                 int l=0;
00637                 while( l<nb_nodes2_max && connectivityPORFLOW[ngeom][nface-1][l] )
00638                 {
00639                     maille2D.sommets.push_back(p_ma->sommets[ numPORFLOWtoMED[ngeom][ connectivityPORFLOW[ngeom][nface-1][l++]-1 ]-1 ]);
00640                 }
00641 
00642                 // the corresponding 2D MED geometric type depends upon the number of nodes
00643                 maille2D.sommets.resize(l);
00644                 maille2D.geometricType = get2DMedGeomType(l);
00645                 p_ma = medi.insert(maille2D); // we insert the face in our mesh
00646                 medi.groupes[i].mailles[ielem++]=p_ma; // and insert an iterator on it in our group
00647                 maille2D.sommets.clear();
00648             }
00649 
00650         }
00651         medi.groupes[i].groupes.clear(); // we don't need element numbers anymore
00652         
00653     }
00654 
00655     p_ma_table.clear(); // we don't need it anymore
00656     MESSAGE_MED(LOC << "PORFLOW_MESH_RDONLY_DRIVER::read : RESULTATS STRUCTURE INTERMEDIAIRES : ");
00657     MESSAGE_MED(LOC <<  medi );
00658             // TRANSFORMATION EN STRUCTURES MED
00659     if ( ! _ptrMesh->isEmpty() )
00660     {
00661         throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Mesh object not empty : can't fill it!"));
00662     }
00663     else if ( /*medi.maillage.size()==0 || */medi.groupes.size()==0 || medi.points.size()==0)
00664     {
00665         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << " Error while reading file " << _fileName 
00666                     << " The data read are not completed " ) ) ;
00667     }
00668     else
00669     {
00670         _ptrMesh->_name = _meshName;
00671         _ptrMesh->_spaceDimension = medi.points.begin()->second.coord.size();
00672         _ptrMesh->_numberOfNodes = medi.points.size();
00673         _ptrMesh->_coordinate = medi.getCoordinate();
00674 
00675         //Construction des groupes
00676         vector<GROUP *> groupCell, groupFace, groupEdge, groupNode;
00677         medi.getGroups(groupCell, groupFace, groupEdge, groupNode, _ptrMesh);
00678         _ptrMesh->_groupCell = groupCell;
00679         _ptrMesh->_groupFace = groupFace;
00680         _ptrMesh->_groupEdge = groupEdge;
00681         _ptrMesh->_groupNode = groupNode;
00682 
00683         // appele en dernier car cette fonction detruit le maillage intermediaire!
00684         _ptrMesh->_connectivity = medi.getConnectivity(); 
00685         MESSAGE_MED(LOC << "PORFLOW_MESH_RDONLY_DRIVER::read : FIN ");
00686 
00687         // calcul de la connectivite d-1 complete, avec renumerotation des groupes
00688         // if (_ptrMesh->_spaceDimension==3)
00689         //     _ptrMesh->_connectivity->updateGroup(_ptrMesh->_groupFace) ;
00690         // else if (_ptrMesh->_spaceDimension==2)
00691         //     _ptrMesh->_connectivity->updateGroup(_ptrMesh->_groupEdge) ;
00692         
00693         // Creation des familles ?artir des groupes
00694         // NC : Cet appel pourra ?e diff鲩 quand la gestion de la coh鲥nce famille/groupes sera assur饊   _ptrMesh->createFamilies();
00695     }
00696 
00697 
00698   END_OF_MED(LOC);
00699 }
00700 
00701 void PORFLOW_MESH_RDONLY_DRIVER::write( void ) const
00702   throw (MEDEXCEPTION)
00703 {
00704   throw MEDEXCEPTION("PORFLOW_MESH_RDONLY_DRIVER::write : Can't write with a RDONLY driver !");
00705 }
00706 
00707 
00708 /*--------------------- WRONLY PART -------------------------------*/
00709 
00710 PORFLOW_MESH_WRONLY_DRIVER::PORFLOW_MESH_WRONLY_DRIVER():PORFLOW_MESH_DRIVER()
00711 {
00712 }
00713   
00714 PORFLOW_MESH_WRONLY_DRIVER::PORFLOW_MESH_WRONLY_DRIVER(const string & fileName,
00715                                                        GMESH *        ptrMesh):
00716   PORFLOW_MESH_DRIVER(fileName,ptrMesh,WRONLY)
00717 {
00718   MESSAGE_MED("PORFLOW_MESH_WRONLY_DRIVER::PORFLOW_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created");
00719 }
00720 
00721 PORFLOW_MESH_WRONLY_DRIVER::PORFLOW_MESH_WRONLY_DRIVER(const PORFLOW_MESH_WRONLY_DRIVER & driver): 
00722   PORFLOW_MESH_DRIVER(driver)
00723 {
00724 }
00725 
00726 PORFLOW_MESH_WRONLY_DRIVER::~PORFLOW_MESH_WRONLY_DRIVER()
00727 {
00728   //MESSAGE_MED("PORFLOW_MESH_WRONLY_DRIVER::PORFLOW_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed");
00729 }
00730 
00731 GENDRIVER * PORFLOW_MESH_WRONLY_DRIVER::copy(void) const
00732 {
00733   return new PORFLOW_MESH_WRONLY_DRIVER(*this);
00734 }
00735 
00736 void PORFLOW_MESH_WRONLY_DRIVER::read (void)
00737   throw (MEDEXCEPTION)
00738 {
00739   throw MEDEXCEPTION("PORFLOW_MESH_WRONLY_DRIVER::read : Can't read with a WRONLY driver !");
00740 }
00741 
00742 void PORFLOW_MESH_WRONLY_DRIVER::write(void) const
00743   throw (MEDEXCEPTION)
00744 { 
00745   const char * LOC = "void PORFLOW_MESH_WRONLY_DRIVER::write(void) const : ";
00746   BEGIN_OF_MED(LOC);
00747 
00748   throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<< "Write Driver isn\'t implemented"));
00749 
00750   END_OF_MED(LOC);
00751 } 
00752 
00753 
00754 
00755 /*--------------------- RDWR PART -------------------------------*/
00756 
00757 PORFLOW_MESH_RDWR_DRIVER::PORFLOW_MESH_RDWR_DRIVER():
00758   PORFLOW_MESH_DRIVER(),
00759   PORFLOW_MESH_RDONLY_DRIVER(),
00760   PORFLOW_MESH_WRONLY_DRIVER()
00761 {
00762 }
00763 
00764 PORFLOW_MESH_RDWR_DRIVER::PORFLOW_MESH_RDWR_DRIVER(const string & fileName,MESH * ptrMesh):
00765   PORFLOW_MESH_DRIVER(fileName,ptrMesh,RDWR),
00766   PORFLOW_MESH_RDONLY_DRIVER(fileName,ptrMesh),
00767   PORFLOW_MESH_WRONLY_DRIVER(fileName,ptrMesh)
00768 {
00769   MESSAGE_MED("PORFLOW_MESH_RDWR_DRIVER::PORFLOW_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been created");
00770 }
00771 
00772 PORFLOW_MESH_RDWR_DRIVER::PORFLOW_MESH_RDWR_DRIVER(const PORFLOW_MESH_RDWR_DRIVER & driver): 
00773   PORFLOW_MESH_DRIVER(driver),
00774   PORFLOW_MESH_RDONLY_DRIVER(driver),
00775   PORFLOW_MESH_WRONLY_DRIVER(driver)
00776 {
00777 }
00778 
00779 PORFLOW_MESH_RDWR_DRIVER::~PORFLOW_MESH_RDWR_DRIVER() {
00780   //MESSAGE_MED("PORFLOW_MESH_RDWR_DRIVER::PORFLOW_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed");
00781 } 
00782   
00783 GENDRIVER * PORFLOW_MESH_RDWR_DRIVER::copy(void) const
00784 {
00785   return new PORFLOW_MESH_RDWR_DRIVER(*this);
00786 }
00787 
00788 void PORFLOW_MESH_RDWR_DRIVER::write(void) const
00789   throw (MEDEXCEPTION)
00790 {
00791   PORFLOW_MESH_WRONLY_DRIVER::write();
00792 }
00793 void PORFLOW_MESH_RDWR_DRIVER::read (void)
00794   throw (MEDEXCEPTION)
00795 {
00796   PORFLOW_MESH_RDONLY_DRIVER::read();
00797 }