Logo Search packages:      
Sourcecode: salome version File versions  Download package

MEDMEM_EnsightMeshDriver.cxx

//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
//
//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
//
//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
#include "MEDMEM_EnsightMeshDriver.hxx"

#include <sstream>
#include <iomanip>
#include <numeric>

#include "MEDMEM_define.hxx"
#include "MEDMEM_Family.hxx"
#include "MEDMEM_Group.hxx"
#include "MEDMEM_Coordinate.hxx"
#include "MEDMEM_Connectivity.hxx"
#include "MEDMEM_Mesh.hxx"
#include "MEDMEM_CellModel.hxx"
#include "MEDMEM_Grid.hxx"

#include "MEDMEM_MedMeshDriver.hxx"

using namespace std;
using namespace MEDMEM;
using namespace MED_EN;
using namespace MEDMEM_ENSIGHT;

#define TStrTool _ASCIIFileReader
#define TOLERANCE 1e-15

//#define ELEMENT_ID_GIVEN

namespace {

  // ---------------------------------------------------------------------
  /*!
   * \brief The beginning of mesh description used to distinguish files
   * generated by ENSIGHT_MESH_WRONLY_DRIVER from others
   */
  const char* theDescriptionPrefix = "Meshing from MedMemory. ";

  // ---------------------------------------------------------------------
  /*!
   * \brief Default name of a mesh read from EnSight
   */
  const char* theDefaultMeshName = "EnsightMesh";

  // ---------------------------------------------------------------------
  /*!
   * \brief Max number of types in EnSight part
   */
  const int   theMaxNbTypes = 20;

  // ---------------------------------------------------------------------
  /*!
   * \brief Make array with elements == index[i+1]-index[i]
   *  \param size - result array size
   */
  int* getNumbersByIndex( const int* index, int size, const int* elemNumbers=0)
  {
    int* numbers = new int[size];
    int* n = numbers;
    if ( elemNumbers ) {
      const int *elem = elemNumbers-1, *elemEnd = elemNumbers + size;
      while ( ++elem < elemEnd )
        *n++ = index[*elem] - index[*elem-1];
    }
    else {
      const int *ind = index, *indEnd = index + size + 1;
      while ( ++ind < indEnd )
        *n++ = ind[0] - ind[-1];
    }
    return numbers;
  }
  // ---------------------------------------------------------------------
  /*!
   * \brief Type used to delete numbers returned by getNumbersByIndex()
   */
  typedef _ValueOwner<int> TNumbers;

} // namespace


ENSIGHT_MESH_DRIVER::ENSIGHT_MESH_DRIVER(): _CaseFileDriver_User(), _ptrMesh((MESH *)NULL)
{
}

ENSIGHT_MESH_DRIVER::ENSIGHT_MESH_DRIVER(const string & fileName,
                                         MESH *         ptrMesh)
  :_CaseFileDriver_User(fileName,MED_EN::RDWR), _ptrMesh(ptrMesh),
   _meshName(ptrMesh->getName())
{
}

ENSIGHT_MESH_DRIVER::ENSIGHT_MESH_DRIVER(const string & fileName,
                                         MESH *         ptrMesh,
                                         med_mode_acces accessMode)
  :_CaseFileDriver_User(fileName,accessMode), _ptrMesh(ptrMesh), _meshName(ptrMesh->getName())
{
}

ENSIGHT_MESH_DRIVER::ENSIGHT_MESH_DRIVER(const ENSIGHT_MESH_DRIVER & driver)
  :_CaseFileDriver_User(driver), _ptrMesh(driver._ptrMesh), _meshName(driver._meshName)
{
}

ENSIGHT_MESH_DRIVER::~ENSIGHT_MESH_DRIVER()
{
  MESSAGE_MED("ENSIGHT_MESH_DRIVER::~ENSIGHT_MESH_DRIVER() has been destroyed");
}

void    ENSIGHT_MESH_DRIVER::setMeshName(const string & meshName) { _meshName = meshName; };

string  ENSIGHT_MESH_DRIVER::getMeshName() const { return _meshName; };

void ENSIGHT_MESH_DRIVER::openConst(bool checkDataFile) const
{
  const char * LOC ="ENSIGHT_MESH_DRIVER::open() : ";
  BEGIN_OF_MED(LOC);

  if ( checkDataFile )
  {
    if ( getDataFileName().empty() )
      throw MED_EXCEPTION
        ( LOCALIZED( STRING(LOC) << "Internal error, geometry file name is empty"));

    if (!canOpenFile( getDataFileName(), getAccessMode() ))
      throw MED_EXCEPTION
        ( LOCALIZED( STRING(LOC) << "Can not open Ensight Geometry file " << getDataFileName()
                     << " in access mode " << getAccessMode()));
  }
  else
  {
    if ( getCaseFileName().empty() )
      throw MED_EXCEPTION
        ( LOCALIZED( STRING(LOC) << "Case file name is empty, "
                     "please set a correct fileName before calling open()"));

    if ( !canOpenFile( getCaseFileName(), getAccessMode() ))
      throw MED_EXCEPTION
        ( LOCALIZED( STRING(LOC) << "Can not open Ensight Case file " << getCaseFileName()
                     << " in access mode " << getAccessMode()));
  }

  END_OF_MED(LOC);
}

void ENSIGHT_MESH_DRIVER::open() {
  openConst() ;
}

void ENSIGHT_MESH_DRIVER::close() {
}

// ================================================================================
// WRONLY
// ================================================================================

ENSIGHT_MESH_WRONLY_DRIVER::ENSIGHT_MESH_WRONLY_DRIVER() : ENSIGHT_MESH_DRIVER()
{
}

ENSIGHT_MESH_WRONLY_DRIVER::ENSIGHT_MESH_WRONLY_DRIVER(const string & fileName,
                                                       MESH *         ptrMesh,
                                                       bool           append)
  : ENSIGHT_MESH_DRIVER( fileName, ptrMesh, WRONLY ), _append(append)
{
}

ENSIGHT_MESH_WRONLY_DRIVER::ENSIGHT_MESH_WRONLY_DRIVER(const ENSIGHT_MESH_WRONLY_DRIVER & driver)
  : ENSIGHT_MESH_DRIVER(driver),_append(driver._append)
{
}

ENSIGHT_MESH_WRONLY_DRIVER::~ENSIGHT_MESH_WRONLY_DRIVER()
{
}

GENDRIVER * ENSIGHT_MESH_WRONLY_DRIVER::copy() const
{
  return new ENSIGHT_MESH_WRONLY_DRIVER(*this) ;
}

void ENSIGHT_MESH_WRONLY_DRIVER::read() throw (MEDEXCEPTION) {
  throw MEDEXCEPTION("ENSIGHT_MESH_WRONLY_DRIVER::read : Can't read with a WRONLY driver !");
}

//================================================================================
/*!
 * \brief writing
 */
//================================================================================

00210 void ENSIGHT_MESH_WRONLY_DRIVER::write() const throw (MEDEXCEPTION)
{
  const char * LOC = "ENSIGHT_MESH_WRONLY_DRIVER::write() : ";
  BEGIN_OF_MED(LOC);

  openConst(false) ; // check if can write to case file

  // Ensight case organization requires a main file (filename.case) which defines organization

  _CaseFileDriver caseFile( getCaseFileName(), this);
  if ( _append )
    caseFile.read();
  caseFile.addMesh( this ); 
  caseFile.write(); // all fields of _CaseFileDriver_User are set by this method

  openConst(true) ; // check if can write to data file

  cout << "-> creating the Ensight geometry file " << getDataFileName() << endl ;

  // Store mesh description and a special mark in the first two description lines each
  // of 79 chars length maximum, while MED mesh description is up to 200 chars
  const char* line1 = theDescriptionPrefix;
  string      line2 = _ptrMesh->getDescription();
  for ( int i = 0; i < line2.size(); ++i ) { // protect from gabage
    if ( !line2[ i ] || !isascii( line2[ i ])) {
      line2.resize( i );
      break;
    }
  }
  if ( line2.size() >= MAX_LINE_LENGTH )
    line2.resize( MAX_LINE_LENGTH );

  // EnSight will assign node/element visible numbers it-self
  const char* line3 = "node id assign";
#ifdef ELEMENT_ID_GIVEN
  const char* line4 = "element id given";
#else
  const char* line4 = "element id assign";
#endif

  if ( isBinaryEnSightFormatForWriting() )
  {
    // ======================================================
    //                          Binary
    // ======================================================

    _BinaryFileWriter ensightGeomFile( getDataFileName() ); 

    ensightGeomFile.addString("C Binary");
    ensightGeomFile.addString(line1);
    ensightGeomFile.addString(line2);
    ensightGeomFile.addString(line3);
    ensightGeomFile.addString(line4);

    // function to write a support as a part
    typedef void (ENSIGHT_MESH_WRONLY_DRIVER::* TWritePart) (_BinaryFileWriter&, const SUPPORT*) const;
    TWritePart writePart;
    if ( isGoldFormat() )
    {
      // GOLD
      writePart = & ENSIGHT_MESH_WRONLY_DRIVER::writePartGoldBinary;
    }
    else
    {
      // ENSIGHT 6. Write addionally global nodes
      writePart = & ENSIGHT_MESH_WRONLY_DRIVER::writePart6Binary;

      // All point are in 3D, so if we are in 1D or 2D, we complete by zero !
      int SpaceDimension = _ptrMesh->getSpaceDimension() ;
      int NumberOfNodes  = _ptrMesh->getNumberOfNodes() ;
      ensightGeomFile.addString("coordinates");
      ensightGeomFile.addInt( NumberOfNodes );
      const double *coordinate = _ptrMesh->getCoordinates(MED_FULL_INTERLACE) ;
      if ( SpaceDimension == 3 ) {
        ensightGeomFile.addReal(coordinate, NumberOfNodes * SpaceDimension );
      }
      else {
        typedef _ValueIterator< double > TComponentIt;
        vector< TComponentIt > coordCompIt( 3 );
        for (int j=0; j<3; j++, coordinate++)
          if ( j < SpaceDimension )
            coordCompIt[ j ] = TComponentIt( coordinate, SpaceDimension );
          else
            coordCompIt[ j ] = TComponentIt(); // to iterate on zeros
        ensightGeomFile.addReal( coordCompIt, NumberOfNodes, MED_FULL_INTERLACE );
      }
    }

    // We put connectivity

    if ( isToWriteEntity( MED_CELL, _ptrMesh ))
    {
      SUPPORT allCells(_ptrMesh, getMeshName(), MED_CELL );
      (this->*writePart)( ensightGeomFile, &allCells );
    }
    // And meshdim-1 connectivity
    if ( isToWriteEntity( MED_FACE, _ptrMesh ))
    {
      SUPPORT allFaces(_ptrMesh, string("SupportOnAll_")+entNames[MED_FACE], MED_FACE );
      (this->*writePart)( ensightGeomFile, & allFaces);
    }
    else if ( isToWriteEntity(MED_EDGE, _ptrMesh))
    {
      SUPPORT allEdges(_ptrMesh, string("SupportOnAll_")+entNames[MED_EDGE], MED_EDGE );
      (this->*writePart)( ensightGeomFile, & allEdges);
    }

    // Write all groups as parts

    for ( int ent = MED_CELL; ent < MED_ALL_ENTITIES; ++ent )
    {
      medEntityMesh entity = (medEntityMesh) ent;
      int nbGroups = _ptrMesh->getNumberOfGroups(entity);
      for ( int i=1; i<=nbGroups; i++)
      {
        const GROUP* group = _ptrMesh->getGroup( entity, i );
        (this->*writePart)( ensightGeomFile, group );
      }
    }

  }
  else
  {
    // ======================================================
    //                           ASCII
    // ======================================================
    ofstream ensightGeomFile( getDataFileName().c_str(), ios::out); 
    ensightGeomFile.setf(ios::scientific);
    ensightGeomFile.precision(5);

    ensightGeomFile << line1 << endl 
                    << line2 << endl
                    << line3 << endl
                    << line4 << endl;

    // function to write a support as a part
    typedef void (ENSIGHT_MESH_WRONLY_DRIVER::* TWritePart) (ofstream&, const SUPPORT*) const;
    TWritePart writePart;
    if ( isGoldFormat() )
    {
      // GOLD
      writePart = & ENSIGHT_MESH_WRONLY_DRIVER::writePartGoldASCII;
    }
    else
    {
      // ENSIGHT 6. Write addionally global nodes
      writePart = & ENSIGHT_MESH_WRONLY_DRIVER::writePart6ASCII;

      // Put points (all point are in 3D, so if we are in 1D or 2D, we complete by zero !
      int SpaceDimension = _ptrMesh->getSpaceDimension() ;
      int NumberOfNodes  = _ptrMesh->getNumberOfNodes() ;
      string zeros;
      if (SpaceDimension==2) zeros = " 0.00000e+00";
      if (SpaceDimension==1) zeros = " 0.00000e+00 0.00000e+00";
      ensightGeomFile << "coordinates" << endl
                      << setw(8) << NumberOfNodes << endl ;
      const double *coordinate = _ptrMesh->getCoordinates(MED_FULL_INTERLACE) ;
      for (int i=0; i<NumberOfNodes; i++)
      {
        //ensightGeomFile << setw(8) << i+1 ; // node id
        for (int j=0; j<SpaceDimension; j++, coordinate++)
          ensightGeomFile << setw(12) << *coordinate;
        ensightGeomFile << zeros << endl ;
      }
    }

    // We put connectivity

    if ( isToWriteEntity( MED_CELL, _ptrMesh ))
    {
      SUPPORT allCells(_ptrMesh, getMeshName(), MED_CELL );
      (this->*writePart)( ensightGeomFile, &allCells );
    }
    // And meshdim-1 connectivity
    if ( isToWriteEntity( MED_FACE, _ptrMesh ))
    {
      SUPPORT allFaces(_ptrMesh, string("SupportOnAll_")+entNames[MED_FACE], MED_FACE );
      (this->*writePart)( ensightGeomFile, & allFaces);
    }
    else if ( isToWriteEntity(MED_EDGE, _ptrMesh))
    {
      SUPPORT allEdges(_ptrMesh, string("SupportOnAll_")+entNames[MED_EDGE], MED_EDGE );
      (this->*writePart)( ensightGeomFile, & allEdges);
    }

    // Write all groups as parts

    for ( int ent = MED_CELL; ent < MED_ALL_ENTITIES; ++ent )
    {
      medEntityMesh entity = (medEntityMesh) ent;
      int nbGroups = _ptrMesh->getNumberOfGroups(entity);
      for ( int i=1; i<=nbGroups; i++)
      {
        const GROUP* group = _ptrMesh->getGroup( entity, i );
        (this->*writePart)( ensightGeomFile, group );
      }
    }

    ensightGeomFile.close();

  } // end ASCII format

} // ENSIGHT_MESH_WRONLY_DRIVER::write()

//================================================================================
/*!
 * \brief Write support as an EnSight Gold part
 */
//================================================================================

00420 void ENSIGHT_MESH_WRONLY_DRIVER::writePartGoldBinary(_BinaryFileWriter& ensightGeomFile,
                                                     const SUPPORT*     support) const
{
  // part number
  int partNum = getPartNumber( support );
  if ( !partNum )
    throw MED_EXCEPTION ( LOCALIZED( STRING("Internal error: invalid part number")));
  ensightGeomFile.addString( "part" );
  ensightGeomFile.addInt( partNum );

  // group/mesh name
  ensightGeomFile.addString( support->getName() );

  // get geom types
  medEntityMesh entity = support->getEntity();
  int nbTypes = support->getNumberOfTypes();
  const medGeometryElement* geoType = support->getTypes();

  const int * connectivity = 0;
  const int * elemConnectivity = 0;
  const int * index = 0;
  int j;

  // COORDINATES                                                             Gold binary
  // ===================================================================================
  // In Ensight, coordinates of nodes of support elements are in MED_NO_INTERLACE mode.
  // We are to write only nodes belonging to elements of the support and
  // nodal connectivity should refer to these nodes.
  map<int, int> med2ensIds;
  map<int, int>::iterator medEnsIt;
  int SpaceDimension = _ptrMesh->getSpaceDimension() ;
  int NumberOfNodes  = _ptrMesh->getNumberOfNodes() ;
  // -------------------------------------------------
  if ( support->isOnAllElements() )
  {
    // nb of nodes
    ensightGeomFile.addString( "coordinates" );
    ensightGeomFile.addInt( NumberOfNodes );

    // coordinates
    const double *coordinate = _ptrMesh->getCoordinates(MED_FULL_INTERLACE);
    typedef _ValueIterator< double > TComponentIt;
    vector< TComponentIt > coordCompIt( 1 );
    for (int j=0; j<SPACE_DIM; j++, coordinate++) { // loop on dimensions
      if ( j < SpaceDimension )
        coordCompIt[ 0 ] = TComponentIt( coordinate, SpaceDimension );
      else
        coordCompIt[ 0 ] = TComponentIt(); // to iterate on zeros
      ensightGeomFile.addReal( coordCompIt, NumberOfNodes, MED_NO_INTERLACE );
    }
  }
  // -------------------------------------------------
  else // support is not on all elements
  {
    // nb of nodes
    getSupportNodes( support, med2ensIds );
    NumberOfNodes = med2ensIds.size();
    ensightGeomFile.addString( "coordinates" );
    ensightGeomFile.addInt( NumberOfNodes );

    // coordinates
    vector<float> floatCoords( NumberOfNodes );
    for ( j=0; j < SPACE_DIM; j++) { // loop on dimensions
      medEnsIt = med2ensIds.begin();
      if ( j < SpaceDimension ) {
        const double *coordinate = _ptrMesh->getCoordinates(MED_FULL_INTERLACE) + j;
        for (int i=0; i<NumberOfNodes; i++, ++medEnsIt )
          floatCoords[ i ] = (float) coordinate[ (medEnsIt->first-1) * SpaceDimension];
      }
      else if ( j-1 < SpaceDimension ) {
        for (int i=0; i<NumberOfNodes; i++)
          floatCoords[ i ] = 0.;
      }
      ensightGeomFile.addReal( &floatCoords[0], NumberOfNodes );
    }
    // assign local node ids
    for ( medEnsIt = med2ensIds.begin(), j=1; j<=NumberOfNodes; j++, ++medEnsIt )
      medEnsIt->second = j;
  }

  // CONNECTIVITY                                                            Gold binary
  // ===================================================================================
  // loop on types
  for (int i=0; i<nbTypes; i++)
  {
    const medGeometryElement    medType = geoType[i];
    const TEnSightElemType& ensightType = getEnSightType(medType);
    const int numberOfCell              = support->getNumberOfElements(medType);
    int nbCellNodes                     = ensightType._medIndex.size();

    // type name and nb cells
    ensightGeomFile.addString( ensightType._name );
    ensightGeomFile.addInt(  numberOfCell );

    vector<int> nodeIds;

    // -------------------------------------------------
    if ( support->isOnAllElements() )
    {
#ifdef ELEMENT_ID_GIVEN
      // elem numbers
      nodeIds.resize( numberOfCell );
      for ( j = 1; j <= numberOfCell; j++)
        nodeIds[ j-1 ] = j;
      ensightGeomFile.addInt( nodeIds );

      if ( entity != MED_NODE ) nodeIds.clear();
#endif

      if ( nbCellNodes > 1 ) // STANDARD ELEMENTS connectivity
      {
        connectivity = _ptrMesh->getConnectivity(MED_FULL_INTERLACE, MED_NODAL,
                                                 entity, medType);
        nodeIds.reserve( numberOfCell * nbCellNodes);
        for (j = 0 ; j < numberOfCell; j++, connectivity += nbCellNodes)
          for (int k=0; k<nbCellNodes; k++)
            nodeIds.push_back( connectivity[ ensightType._medIndex[k] ]);
        ensightGeomFile.addInt( nodeIds );
      }
      else if ( entity == MED_NODE ) // NODES connectivity
      {
#if !defined(ELEMENT_ID_GIVEN)
        nodeIds.resize( numberOfCell );
        for ( j = 1; j <= numberOfCell; j++)
          nodeIds[ j-1 ] = j;
#endif
        ensightGeomFile.addInt( nodeIds );
      }
      else if ( medType == MED_POLYGON ) // POLYGONs connectivity
      {
        connectivity   = _ptrMesh->getPolygonsConnectivity(MED_NODAL, entity);
        index          = _ptrMesh->getPolygonsConnectivityIndex(MED_NODAL, entity);
        int connLength = _ptrMesh->getPolygonsConnectivityLength(MED_NODAL, entity);
        // number of nodes in each element
        {
          TIntOwner nbNodesInPoly( getNumbersByIndex( index, numberOfCell ));
          ensightGeomFile.addInt( nbNodesInPoly.myValues, numberOfCell );
        } // nbNodesInPoly is deleted here

        // connectivity
        ensightGeomFile.addInt( connectivity, connLength );
      }
      else // POLYHEDRA connectivity
      {
        connectivity       = _ptrMesh->getPolyhedronConnectivity(MED_NODAL);
        index              = _ptrMesh->getPolyhedronIndex(MED_NODAL);
        const int * fIndex = _ptrMesh->getPolyhedronFacesIndex();
        int connLength     = _ptrMesh->getPolyhedronConnectivityLength(MED_NODAL);
        int nbFaces        = _ptrMesh->getNumberOfPolyhedronFaces();
        // nb of faces in each polyhedron
        {
          TIntOwner nbFacesInPoly( getNumbersByIndex( index, numberOfCell ));
          ensightGeomFile.addInt( nbFacesInPoly.myValues, numberOfCell );
        }
        // number of nodes in each face
        {
          TIntOwner nbNodesInFace( getNumbersByIndex( fIndex, nbFaces ));
          ensightGeomFile.addInt( nbNodesInFace.myValues, nbFaces );
        }
        // connectivity
        ensightGeomFile.addInt( connectivity, connLength );
      }
    }
    // -------------------------------------------------
    else // support is not on all elements
    {
      const int *number = support->getNumber(medType);

#ifdef ELEMENT_ID_GIVEN
      ensightGeomFile.addInt( number, numberOfCell );
#endif
      if ( nbCellNodes > 1 ) // STANDARD ELEMENTS connectivity
      {
        connectivity = _ptrMesh->getConnectivity(MED_FULL_INTERLACE, MED_NODAL,
                                                 entity, MED_ALL_ELEMENTS);
        index = _ptrMesh->getConnectivityIndex(MED_FULL_INTERLACE, entity);

        nodeIds.reserve( numberOfCell * nbCellNodes);
        for (j=0; j<numberOfCell; j++) {
          int elem = number[j];
          elemConnectivity = connectivity + index[elem-1]-1;
          for (int k=0; k<nbCellNodes; k++)
          {
            int node = elemConnectivity[ ensightType._medIndex[k] ];
            nodeIds.push_back( med2ensIds[ node ]);
          }
        }
        ensightGeomFile.addInt( nodeIds );
      }
      else if ( entity == MED_NODE )  // NODES connectivity
      {
        nodeIds.resize( numberOfCell );
        for ( j = 1; j <= numberOfCell; j++)
          nodeIds[ j-1 ] = j;
        ensightGeomFile.addInt( nodeIds );
      }
      else if ( medType == MED_POLYGON ) // POLYGONs connectivity
      {
        connectivity   = _ptrMesh->getPolygonsConnectivity(MED_NODAL, entity);
        index          = _ptrMesh->getPolygonsConnectivityIndex(MED_NODAL, entity);
        int connLength = _ptrMesh->getPolygonsConnectivityLength(MED_NODAL, entity);
        int nbStdElems = _ptrMesh->getNumberOfElements(entity,MED_ALL_ELEMENTS);
        // number of nodes in each element
        {
          TIntOwner nbNodesInPoly( getNumbersByIndex( index-nbStdElems, numberOfCell, number ));
          ensightGeomFile.addInt( nbNodesInPoly.myValues, numberOfCell );
        } // nbNodesInPoly is deleted here

        // connectivity
        nodeIds.reserve( connLength );
        for ( j = 0; j < numberOfCell; ++j )
        {
          int elem = number[ j ] - nbStdElems;
          elemConnectivity   = connectivity + index[ elem-1 ]-1;
          const int* connEnd = connectivity + index[ elem   ]-1;
          while ( elemConnectivity < connEnd )
            nodeIds.push_back( med2ensIds[ *elemConnectivity++ ]);
        }
        ensightGeomFile.addInt( nodeIds );
      }
      else // POLYHEDRA connectivity
      {
        connectivity       = _ptrMesh->getPolyhedronConnectivity(MED_NODAL);
        index              = _ptrMesh->getPolyhedronIndex(MED_NODAL);
        const int * fIndex = _ptrMesh->getPolyhedronFacesIndex();
        int connLength     = _ptrMesh->getPolyhedronConnectivityLength(MED_NODAL);
        int nbStdElems     = _ptrMesh->getNumberOfElements(entity,MED_ALL_ELEMENTS);
        // nb of faces in each polyhedron
        {
          TIntOwner nbFacesInPoly( getNumbersByIndex( index-nbStdElems, numberOfCell, number ));
          ensightGeomFile.addInt( nbFacesInPoly.myValues, numberOfCell );
        }
        // number of nodes in each face
        nodeIds.reserve( connLength );
        for ( j = 0; j < numberOfCell; ++j )
        {
          int elem    = number[ j ] - nbStdElems;
          int f1      = index[ elem-1 ] - 1, f2 = index[ elem ] - 1;
          int nbFaces = f2 - f1;
          {
            TIntOwner nbNodesInFace( getNumbersByIndex( &fIndex[ f1 ], nbFaces ));
            ensightGeomFile.addInt( nbNodesInFace.myValues, nbFaces );
          }
          elemConnectivity   = connectivity + fIndex[ f1 ] - 1;
          const int* connEnd = connectivity + fIndex[ f2 ] - 1;
          while ( elemConnectivity < connEnd )
            nodeIds.push_back( med2ensIds[ *elemConnectivity++ ]);
        }
        // connectivity
        ensightGeomFile.addInt( nodeIds );
      }
    }
  }
} // writePartGoldBinary()

//================================================================================
/*!
 * \brief Write support as an EnSight Gold part
 */
//================================================================================

void ENSIGHT_MESH_WRONLY_DRIVER::writePartGoldASCII(ofstream&      ensightGeomFile,
                                                    const SUPPORT* support) const
{
  const int iw = 10;

  // part number
  int partNum = getPartNumber( support );
  ensightGeomFile << "part" << endl
                  << setw(iw) << partNum << endl;
  if ( !partNum )
    throw MED_EXCEPTION ( LOCALIZED( STRING("Internal error: invalid part number")));

  // group/mesh name
  ensightGeomFile << support->getName() << endl;

  // get geom types
  medEntityMesh entity = support->getEntity();
  int nbTypes = support->getNumberOfTypes();
  const medGeometryElement* geoType = support->getTypes();

  const int * connectivity = 0;
  const int * elemConnectivity = 0;
  const int * index = 0;
  int j;

  // COORDINATES                                                              Gold ASCII 
  // ===================================================================================
  // In Ensight, coordinates of nodes of support elements are in MED_NO_INTERLACE mode.
  // We are to write only nodes belonging to elements of the support and
  // nodal connectivity should refer to these nodes.
  map<int, int> med2ensIds;
  map<int, int>::iterator medEnsIt;
  int SpaceDimension = _ptrMesh->getSpaceDimension() ;
  int NumberOfNodes  = _ptrMesh->getNumberOfNodes() ;
  string zeroStr = " 0.00000e+00";
  // -----------------------------------
  if ( support->isOnAllElements() )
  {
    // nb of nodes
    ensightGeomFile << "coordinates" << endl
                    << setw(iw) << NumberOfNodes << endl ;

    // coordinates
    for (j=0; j<SPACE_DIM; j++) { // loop on dimensions
      if ( j < SpaceDimension ) {
        const double *coordinate = _ptrMesh->getCoordinates(MED_FULL_INTERLACE) + j;
        for (int i=0; i<NumberOfNodes; i++, coordinate += SpaceDimension)
          ensightGeomFile << setw(12) << (float) *coordinate << endl;
      }
      else {
        for (int i=0; i<NumberOfNodes; i++)
          ensightGeomFile << zeroStr << endl;
      }
    }
  }
  // -----------------------------------
  else // support is not on all elements
  {
    // nb of nodes
    getSupportNodes( support, med2ensIds );
    NumberOfNodes = med2ensIds.size();
    ensightGeomFile << "coordinates" << endl
                    << setw(iw) << NumberOfNodes << endl ;

    // coordinates
    for ( j=0; j<SPACE_DIM; j++) { // loop on dimensions
      medEnsIt = med2ensIds.begin();
      if ( j < SpaceDimension ) {
        const double *coordinate = _ptrMesh->getCoordinates(MED_FULL_INTERLACE) + j;
        for (int i=0; i<NumberOfNodes; i++, ++medEnsIt )
          ensightGeomFile << setw(12)
                          << (float) coordinate[ (medEnsIt->first-1) * SpaceDimension] << endl;
      }
      else {
        for (int i=0; i<NumberOfNodes; i++)
          ensightGeomFile << zeroStr << endl;
      }
    }
    // assign local node ids
    for ( medEnsIt = med2ensIds.begin(), j=1; j<=NumberOfNodes; j++, ++medEnsIt )
      medEnsIt->second = j;
  }

  // CONNECTIVITY                                                             Gold ASCII
  // ===================================================================================
  // loop on types
  for (int i=0; i<nbTypes; i++)
  {
    const medGeometryElement    medType = geoType[i];
    const TEnSightElemType& ensightType = getEnSightType(medType);
    const int numberOfCell              = support->getNumberOfElements(medType);
    int nbCellNodes                     = ensightType._medIndex.size();

    // type name and nb cells
    ensightGeomFile << ensightType._name        << endl
                    << setw(iw) << numberOfCell << endl;

    // -----------------------------------
    if ( support->isOnAllElements() )
    {
#ifdef ELEMENT_ID_GIVEN
      for ( j = 1; j <= numberOfCell; j++)
        ensightGeomFile << setw(iw) << j << endl;
#endif

      if ( nbCellNodes > 1 ) // STANDARD ELEMENTS connectivity
      {
        connectivity = _ptrMesh->getConnectivity(MED_FULL_INTERLACE, MED_NODAL,
                                                 entity, medType);
        for (j = 0 ; j < numberOfCell; j++, connectivity += nbCellNodes) {
          for (int k=0; k<nbCellNodes; k++)
            ensightGeomFile << setw(iw) << connectivity[ ensightType._medIndex[k] ];
          ensightGeomFile << endl ;
        }
      }
      else if ( entity == MED_NODE ) // NODES connectivity
      {
        for ( j = 1; j <= numberOfCell; j++)
          ensightGeomFile << setw(iw) << j << endl;
      }
      else if ( medType == MED_POLYGON ) // POLYGONs connectivity
      {
        connectivity   = _ptrMesh->getPolygonsConnectivity(MED_NODAL, entity);
        index          = _ptrMesh->getPolygonsConnectivityIndex(MED_NODAL, entity);
        // number of nodes in each element
        const int* ind = index;
        for (j = 0 ; j < numberOfCell; j++, ++ind)
          ensightGeomFile << setw(iw) << ( ind[1] - ind[0] ) << endl;
        
        // connectivity
        for (j = 0; j < numberOfCell; j++, ++index) {
          nbCellNodes = index[1] - index[0];
          for (int k=0; k<nbCellNodes; k++, ++connectivity)
            ensightGeomFile << setw(iw) << *connectivity;
          ensightGeomFile << endl;
        }
      }
      else // POLYHEDRA connectivity
      {
        connectivity       = _ptrMesh->getPolyhedronConnectivity(MED_NODAL);
        index              = _ptrMesh->getPolyhedronIndex(MED_NODAL);
        const int * fIndex = _ptrMesh->getPolyhedronFacesIndex();
        int nbFaces        = _ptrMesh->getNumberOfPolyhedronFaces();
        // nb of faces in each polyhedron
        const int* ind = index;
        for (j = 0 ; j < numberOfCell; j++, ++ind)
          ensightGeomFile << setw(iw) << ( ind[1] - ind[0] ) << endl ;
        // number of nodes in each face
        ind = fIndex;
        for (j = 0 ; j < nbFaces; j++, ++ind)
          ensightGeomFile << setw(iw) << ( ind[1] - ind[0] ) << endl ;
        // connectivity of each face
        for (j = 0 ; j < nbFaces; j++, ++fIndex) {
          int nbFaceNodes = fIndex[1] - fIndex[0];
          for (int k=0; k<nbFaceNodes; k++, ++connectivity)
            ensightGeomFile << setw(iw) << *connectivity;
          ensightGeomFile << endl ;
        }
      }
    }
    // -----------------------------------
    else // support is not on all elements
    {
      const int *number = support->getNumber(medType);

#ifdef ELEMENT_ID_GIVEN
      for ( j = 0; j < numberOfCell; j++)
        ensightGeomFile << setw(iw) << number[j] << endl;
#endif
      if ( nbCellNodes > 1 ) // STANDARD ELEMENTS connectivity
      {
        connectivity = _ptrMesh->getConnectivity(MED_FULL_INTERLACE, MED_NODAL,
                                                 entity, MED_ALL_ELEMENTS);
        index = _ptrMesh->getConnectivityIndex(MED_FULL_INTERLACE, entity);

        for (j=0; j<numberOfCell; j++) {
          int elem = number[j];
          elemConnectivity = connectivity + index[elem-1]-1;
          for (int k=0; k<nbCellNodes; k++) {
            int node = elemConnectivity[ ensightType._medIndex[k] ];
            ensightGeomFile << setw(iw) << med2ensIds[ node ];
          }
          ensightGeomFile << endl;
        }
      }
      else if ( entity == MED_NODE )  // NODES connectivity
      {
        for (j=0; j<numberOfCell; j++) {
          int node = med2ensIds[ number[j] ];
          ensightGeomFile << setw(iw) << node << endl ;
        }
      }
      else if ( medType == MED_POLYGON ) // POLYGONs connectivity
      {
        connectivity   = _ptrMesh->getPolygonsConnectivity(MED_NODAL, entity);
        index          = _ptrMesh->getPolygonsConnectivityIndex(MED_NODAL, entity);
        int nbStdElems = _ptrMesh->getNumberOfElements(entity,MED_ALL_ELEMENTS);
        // number of nodes in each element
        for (j = 0 ; j < numberOfCell; j++) {
          int elem = number[j] - nbStdElems;
          ensightGeomFile << setw(iw) << ( index[elem] - index[elem-1] ) << endl;
        }
        // connectivity
        for ( j = 0; j < numberOfCell; ++j ) {
          int elem = number[ j ] - nbStdElems;
          elemConnectivity   = connectivity + index[ elem-1 ]-1;
          const int* connEnd = connectivity + index[ elem   ]-1;
          while ( elemConnectivity < connEnd )
            ensightGeomFile << setw(iw) << med2ensIds[ *elemConnectivity++ ];
          ensightGeomFile << endl;
        }
      }
      else // POLYHEDRA connectivity
      {
        connectivity       = _ptrMesh->getPolyhedronConnectivity(MED_NODAL);
        index              = _ptrMesh->getPolyhedronIndex(MED_NODAL);
        const int * fIndex = _ptrMesh->getPolyhedronFacesIndex();
        int nbStdElems     = _ptrMesh->getNumberOfElements(entity,MED_ALL_ELEMENTS);
        // nb of faces in each polyhedron
        for (j = 0 ; j < numberOfCell; j++) {
          int elem = number[j] - nbStdElems;
          ensightGeomFile << setw(iw) << ( index[elem] - index[elem-1] ) << endl;
        }
        // number of nodes in each face
        for ( j = 0; j < numberOfCell; ++j ) {
          int elem = number[ j ] - nbStdElems;
          int f1   = index[ elem-1 ], f2 = index[ elem ];
          while ( f1 < f2 ) {
            ensightGeomFile << setw(iw) << ( fIndex[f1] - fIndex[f1-1] ) << endl;
            ++f1;
          }
        }
        // connectivity of each face
        for ( j = 0; j < numberOfCell; ++j ) {
          int elem = number[ j ] - nbStdElems;
          int f1   = index[ elem-1 ] - 1, f2 = index[ elem ] - 1;
          while ( f1 < f2 ) {
            int n1 = fIndex[f1]-1, n2 = fIndex[f1+1]-1;
            ++f1;
            while ( n1 < n2 )
              ensightGeomFile << setw(iw) << connectivity[ n1++ ];
            ensightGeomFile << endl ;
          }
        }
      }
    }
  }
}  // writePartGoldASCII()

//================================================================================
/*!
 * \brief Write support as an Ensight6 part
 */
//================================================================================

00936 void ENSIGHT_MESH_WRONLY_DRIVER::writePart6Binary(_BinaryFileWriter& ensightGeomFile,
                                                  const SUPPORT*     support) const
{
  // part number
  int partNum = getPartNumber( support );
  ensightGeomFile.addString( STRING("part ") << partNum );
  if ( !partNum )
    throw MED_EXCEPTION ( LOCALIZED( STRING("Internal error: invalid part number")));

  // group/mesh name
  ensightGeomFile.addString( support->getName() );

  // get geom types
  medEntityMesh entity = support->getEntity();
  int nbTypes = support->getNumberOfTypes();
  const medGeometryElement* geoType = support->getTypes();

  int j = 1;
  const int * connectivity = 0;
  if ( entity != MED_NODE )
    connectivity = _ptrMesh->getConnectivity(MED_FULL_INTERLACE, MED_NODAL,
                                             entity, MED_ALL_ELEMENTS);
  const int * elemConnectivity = connectivity;

  // CONNECTIVITY                                                       Ensight 6 binary
  // ===================================================================================
  // loop on types
  for (int i=0; i<nbTypes; i++)
  {
    const medGeometryElement    medType = geoType[i];
    const TEnSightElemType& ensightType = getEnSightType(medType);
    int nbCellNodes = ensightType._medIndex.size();
    if ( nbCellNodes == 0 )
      continue; // poly?

    // type name and nb cells
    int numberOfCell = support->getNumberOfElements(medType);
    ensightGeomFile.addString( ensightType._name );
    ensightGeomFile.addInt( numberOfCell );

    vector<int> nodeIds;
    // -------------------------------------------------
    if ( support->isOnAllElements() )
    {
#ifdef ELEMENT_ID_GIVEN
      nodeIds.resize( numberOfCell );
      for ( j = 1; j <= numberOfCell; j++)
        nodeIds[ j-1 ] = j;
      ensightGeomFile.addInt( nodeIds );
#endif
      if ( entity == MED_NODE ) {
#if !defined(ELEMENT_ID_GIVEN)
        nodeIds.resize( numberOfCell * nbCellNodes);
        for ( j = 1; j <= numberOfCell; j++)
          nodeIds[ j-1 ] = j;
#endif
      }
      else {
        nodeIds.clear();
        nodeIds.reserve( numberOfCell * nbCellNodes );
        for (j = 0 ; j < numberOfCell; j++, elemConnectivity += nbCellNodes)
          for (int k=0; k<nbCellNodes; k++)
            nodeIds.push_back( elemConnectivity[ ensightType._medIndex[k] ]);
      }
      ensightGeomFile.addInt( nodeIds );
    }
    // -------------------------------------------------
    else // support is not on all elements
    {
      const int *number = support->getNumber(medType);

#ifdef ELEMENT_ID_GIVEN
      ensightGeomFile.addInt( number, numberOfCell );
#endif
      if ( entity == MED_NODE ) {
        ensightGeomFile.addInt( number, numberOfCell );
      }
      else {
        const int* index = _ptrMesh->getConnectivityIndex(MED_FULL_INTERLACE, entity);

        nodeIds.reserve( numberOfCell * nbCellNodes);
        for (j=0; j<numberOfCell; j++) {
          int elem = number[j];
          elemConnectivity = connectivity + index[elem-1]-1;
          for (int k=0; k<nbCellNodes; k++)
            nodeIds.push_back( elemConnectivity[ ensightType._medIndex[k] ]);
        }
        ensightGeomFile.addInt( nodeIds );
      }
    }
  } // loop on types

} // writePart6Binary()

//================================================================================
/*!
 * \brief Write support as an Ensight6 part
 */
//================================================================================

void ENSIGHT_MESH_WRONLY_DRIVER::writePart6ASCII(ofstream&      ensightGeomFile,
                                                 const SUPPORT* support) const
{
  const int iw = 8;

  // part number
  int partNum = getPartNumber( support );
  ensightGeomFile << "part " << partNum << endl;
  if ( !partNum )
    throw MED_EXCEPTION ( LOCALIZED( STRING("Internal error: invalid part number")));

  // group/mesh name
  ensightGeomFile << support->getName() << endl;

  // get geom types
  medEntityMesh entity = support->getEntity();
  int nbTypes = support->getNumberOfTypes();
  const medGeometryElement* geoType = support->getTypes();

  int j = 1;
  const int * connectivity = 0;
  if ( entity != MED_NODE )
    connectivity = _ptrMesh->getConnectivity(MED_FULL_INTERLACE, MED_NODAL,
                                             entity, MED_ALL_ELEMENTS);
  const int * elemConnectivity = connectivity;

  // CONNECTIVITY                                                        Ensight 6 ASCII
  // ===================================================================================
  // loop on types
  for (int i=0; i<nbTypes; i++)
  {
    const medGeometryElement    medType = geoType[i];
    const TEnSightElemType& ensightType = getEnSightType(medType);
    int nbCellNodes = ensightType._medIndex.size();
    if ( nbCellNodes == 0 )
      continue; // poly?

    // type name and nb cells
    int numberOfCell = support->getNumberOfElements(medType);
    ensightGeomFile << ensightType._name       << endl
                    << setw(iw) << numberOfCell << endl;

    // -------------------------------------------------
    if ( support->isOnAllElements() )
    {
      if ( entity == MED_NODE ) {
        for ( j = 1; j <= numberOfCell; j++) {
#ifdef ELEMENT_ID_GIVEN
          ensightGeomFile << setw(iw) << j;
#endif
          ensightGeomFile << setw(iw) << j << endl;
        }
      }
      else {
        for (j = 1 ; j <= numberOfCell; j++, elemConnectivity += nbCellNodes) {
#ifdef ELEMENT_ID_GIVEN
          ensightGeomFile << setw(iw) << elem++;
#endif
          for (int k=0; k<nbCellNodes; k++)
          {
            ensightGeomFile << setw(iw) << elemConnectivity[ ensightType._medIndex[k] ];
          }
          ensightGeomFile << endl ;
        }
      }
    }
    // -------------------------------------------------
    else  // support is not on all elements
    {
      const int *number = support->getNumber(medType);
      if ( entity == MED_NODE ) {
        for (j=0; j<numberOfCell; j++) {
          int node = number[j];
#ifdef ELEMENT_ID_GIVEN
          ensightGeomFile << setw(iw) << node;
#endif
          ensightGeomFile << setw(iw) << node << endl ;
        }
      }
      else {
        const int* index = _ptrMesh->getConnectivityIndex(MED_FULL_INTERLACE, entity);

        for (j=0; j<numberOfCell; j++) {
          int elem = number[j];
#ifdef ELEMENT_ID_GIVEN
          ensightGeomFile << setw(iw) << elem;
#endif
          elemConnectivity = connectivity + index[elem-1]-1;
          for (int k=0; k<nbCellNodes; k++)
          {
            ensightGeomFile << setw(iw) << elemConnectivity[ ensightType._medIndex[k] ];
          }
          ensightGeomFile << endl ;
        }
      }
    }
  } // loop on types

} // writePart6ASCII()

//================================================================================
/*!
 * \brief Return nb of part to write
 */
//================================================================================

01142 int ENSIGHT_MESH_WRONLY_DRIVER::nbPartsToWrite() const
{
  int nbParts = 0;
  nbParts += (int) isToWriteEntity( MED_CELL, _ptrMesh );
  nbParts += (int) isToWriteEntity( MED_FACE, _ptrMesh );
  nbParts += (int) isToWriteEntity( MED_EDGE, _ptrMesh );

  // all groups
  for ( int ent = MED_CELL; ent < MED_ALL_ENTITIES; ++ent ) {
    int nbGroups = _ptrMesh->getNumberOfGroups(medEntityMesh(ent));
    nbParts += nbGroups;
  }
  return nbParts;
}

// ================================================================================
// RDONLY
// ================================================================================

ENSIGHT_MESH_RDONLY_DRIVER::ENSIGHT_MESH_RDONLY_DRIVER()
  : ENSIGHT_MESH_DRIVER(), _indexInCaseFile(1)
{
}

ENSIGHT_MESH_RDONLY_DRIVER::ENSIGHT_MESH_RDONLY_DRIVER(const string & fileName,
                                                       MESH *         ptrMesh,
                                                       int            index)
  : ENSIGHT_MESH_DRIVER(fileName,ptrMesh,RDONLY), _indexInCaseFile( index )
{
}

ENSIGHT_MESH_RDONLY_DRIVER::ENSIGHT_MESH_RDONLY_DRIVER(const ENSIGHT_MESH_RDONLY_DRIVER & driver) : ENSIGHT_MESH_DRIVER(driver), _indexInCaseFile( driver._indexInCaseFile )
{
}

ENSIGHT_MESH_RDONLY_DRIVER::~ENSIGHT_MESH_RDONLY_DRIVER()
{
}

GENDRIVER * ENSIGHT_MESH_RDONLY_DRIVER::copy() const
{
  return new ENSIGHT_MESH_RDONLY_DRIVER(*this) ;
}

void ENSIGHT_MESH_RDONLY_DRIVER::write() const throw (MEDEXCEPTION)
{
  throw MEDEXCEPTION("ENSIGHT_MESH_RDONLY_DRIVER::write : Can't write with a RDONLY driver !");
}

void ENSIGHT_MESH_RDONLY_DRIVER::merge ( const GENDRIVER& driver )
{
  _CaseFileDriver_User::merge( driver );

  const ENSIGHT_MESH_RDONLY_DRIVER* other =
    dynamic_cast< const ENSIGHT_MESH_RDONLY_DRIVER* >( &driver );
  if ( other ) {
    if ( _indexInCaseFile < other->_indexInCaseFile )
      _indexInCaseFile = other->_indexInCaseFile;
  }
}

//================================================================================
/*!
 * \brief Read mesh in all supported formats
 */
//================================================================================

01209 void ENSIGHT_MESH_RDONLY_DRIVER::read() throw (MEDEXCEPTION)
{
  const char * LOC = "ENSIGHT_MESH_RDONLY_DRIVER::read() : " ;
  BEGIN_OF_MED(LOC);

  openConst(false); // check if can read case file

  _CaseFileDriver caseFile( getCaseFileName(), this);
  caseFile.read();
  caseFile.setDataFileName( _indexInCaseFile, this ); // data from Case File is passed here

  openConst(true); // check if can read data file

  cout << "-> Entering into the geometry file " << getDataFileName() << endl  ;

  _InterMed* imed = new _InterMed();
  imed->_medMesh = getMesh();
  imed->_isOwnMedMesh = false;
  imed->_needSubParts = ( caseFile.getNbVariables() > 0 );
  imed->groupes.reserve(1000);

  // to let field drivers know eventual indices of values
  if ( imed->_needSubParts )
    setInterData( imed );

  if ( isBinaryDataFile( getDataFileName() )) // binary
  {
    if ( isGoldFormat() ) // Gold
    {
      readGoldBinary( *imed );
    }
    else // EnSight6
    {
      read6Binary( *imed );
    }
  }
  else // ASCII
  {
    if ( isGoldFormat() ) // Gold
    {
      readGoldASCII( *imed );
    }
    else // EnSight6
    {
      read6ASCII( *imed );
    }
  }

  if ( _isMadeByMed && !imed->groupes.empty() ) {
    _ptrMesh->_name = imed->groupes[0].nom;
    imed->groupes[0].nom = "SupportOnAll_";
    imed->groupes[0].nom += entNames[MED_CELL];
  }
  else {
    _ptrMesh->_name = theDefaultMeshName;
  }
  _ptrMesh->_spaceDimension = SPACE_DIM;
  _ptrMesh->_meshDimension  = _ptrMesh->_spaceDimension;
  _ptrMesh->_numberOfNodes  = imed->points.size() - imed->nbMerged( MED_POINT1 );
  _ptrMesh->_isAGrid        = 0;
  _ptrMesh->_coordinate     = imed->getCoordinate();

  //Construction des groupes
  imed->getGroups(_ptrMesh->_groupCell,
                  _ptrMesh->_groupFace,
                  _ptrMesh->_groupEdge,
                  _ptrMesh->_groupNode, _ptrMesh);

  _ptrMesh->_connectivity = imed->getConnectivity();

  _ptrMesh->createFamilies();

  // add attributes to families
  set<string> famNames;
  for (medEntityMesh entity=MED_CELL; entity<MED_ALL_ENTITIES; ++entity)
  {
    int i, nb = _ptrMesh->getNumberOfFamilies(entity);
    for ( i = 1; i <= nb; ++i ) {
      FAMILY* f = const_cast<FAMILY*>( _ptrMesh->getFamily( entity, i ));
      f->setNumberOfAttributes( 1 );
      int* attIDs = new int[1];
      attIDs[0] = 1;
      f->setAttributesIdentifiers( attIDs );
      int* attVals = new int[1];
      attVals[0] = 1;
      f->setAttributesValues( attVals );
      string* attDescr = new string[1];
      attDescr[0] = "med_family";
      f->setAttributesDescriptions( attDescr );
      if ( f->getName().length() > 31 ) // limit a name length
        f->setName( STRING("FAM_") << f->getIdentifier());
      // check if family is on the whole mesh entity
      if (_ptrMesh->getNumberOfElements( entity, MED_ALL_ELEMENTS ) ==
          f->getNumberOfElements( MED_ALL_ELEMENTS ))
      {
        f->setAll( true );
        *(f->getnumber()) = MEDSKYLINEARRAY();
      }
      // setAll() for groups
      nb = _ptrMesh->getNumberOfGroups(entity);
      for ( i = 1; i <= nb; ++i ) {
        GROUP * g = const_cast<GROUP*>( _ptrMesh->getGroup( entity, i ));
        if (_ptrMesh->getNumberOfElements( entity, MED_ALL_ELEMENTS ) ==
            g->getNumberOfElements( MED_ALL_ELEMENTS ))
        {
          g->setAll( true );
          *(g->getnumber()) = MEDSKYLINEARRAY();
        }
      }
    }
  }

  END_OF_MED(LOC);
}

//================================================================================
/*!
 * \brief Read mesh in Gold ASCII format
 */
//================================================================================

01330 void ENSIGHT_MESH_RDONLY_DRIVER::readGoldASCII(_InterMed & imed)
{
  const char * LOC ="ENSIGHT_MESH_RDONLY_DRIVER::readGoldASCII() : ";
  BEGIN_OF_MED(LOC);

  _ASCIIFileReader geoFile( getDataFileName() );

  if ( isSingleFileMode() ) {
    int curTimeStep = 1;
    while ( curTimeStep++ < getIndexInDataFile() ) {
      while ( !geoFile.isTimeStepEnd())
        geoFile.getLine();
    }
    while ( !geoFile.isTimeStepBeginning() )
      geoFile.getLine();
  }
  // ----------------------
  // Read mesh description
  // ----------------------
  {
    string descriptionLine1 = geoFile.getLine();
    string descriptionLine2 = geoFile.getLine();

    // find out if the file was created by MED driver
    int prefixSize = strlen( theDescriptionPrefix );
    _isMadeByMed = ( descriptionLine1.substr(0, prefixSize ) == theDescriptionPrefix );

    if ( _isMadeByMed )
      descriptionLine1 = descriptionLine1.substr( prefixSize );
    _ptrMesh->setDescription( descriptionLine1 + descriptionLine2 );
  }

  // ----------------------------------------
  // Find out presence of node/elem numbers 
  // ----------------------------------------

  // EnSight User Manual (for v8) says:
//    You do not have to assign node IDs. If you do, the element connectivities are
//    based on the node numbers. If you let EnSight assign the node IDs, the nodes
//    are considered to be sequential starting at node 1, and element connectivity is
//    done accordingly. If node IDs are set to off, they are numbered internally;
//    however, you will not be able to display or query on them. If you have node
//    IDs in your data, you can have EnSight ignore them by specifying "node id
//    ignore." Using this option may reduce some of the memory taken up by the
//    Client and Server, but display and query on the nodes will not be available.

  // read "node|element id <off|given|assign|ignore>"
  geoFile.getWord(); geoFile.getWord();
  string nodeIds = geoFile.getWord();
  geoFile.getWord(); geoFile.getWord();
  string elemIds = geoFile.getWord();

  bool haveNodeIds = ( nodeIds == "given" || nodeIds == "ignore" );
  bool haveElemIds = ( elemIds == "given" || elemIds == "ignore" );

  // extents: xmin xmax ymin ymax zmin zmax
  vector<double> extents;
  geoFile.toNextLine();
  if ( strncmp( "extents", geoFile.getCurrentPtr(), 7 ) == 0 ) {
    geoFile.skip( /*width =*/ 7, /*nbLines =*/ 1 );
    extents.reserve( 6 );
    while ( extents.size() < extents.capacity() )
      extents.push_back( geoFile.getReal() );
  }

  typedef map<int,_noeud>::iterator INoeud;
  map<int,_noeud> & points = imed.points;
  INoeud firstNode;

  _groupe * partGroupe = 0;
  int partNum = 0, nbParts = 0;

  while ( !geoFile.isTimeStepEnd() )
  {
    string word, restLine, line = geoFile.getLine();
    TStrTool::split( line, word, restLine );

    const TEnSightElemType & partType = getEnSightType( word );
    if ( partType._medType != MED_ALL_ELEMENTS )
    {
      //  Unstructured element type encounters
      // --------------------------------------
      int  nbElemNodes = partType._medType % 100;
      int      nbElems = geoFile.getInt(); // ne
      bool     isGhost = isGhostType( word );
      int    nodeShift = points.empty() ? 0 : points.rbegin()->first;

      // read element ids
      vector<int> elemIds;
      if ( haveElemIds ) {
        elemIds.reserve( nbElems );
        while ( elemIds.size() < nbElems )
          elemIds.push_back( geoFile.getInt() ); // id_e
      }
      if ( isGhost ) { // do not store ghost elements (?)
        int nbNodes = nbElems * nbElemNodes;
        if ( partType._name == "nsided" ) // polygons
        {
          for ( int i = 0; i < nbElems; ++i )
            nbNodes += geoFile.getInt();
          geoFile.skip( nbNodes * INT_WIDTH_GOLD, /*nbLines = */nbElems );
        }
        else if ( partType._name == "nfaced" ) // polyhedrons
        {
          int nbFaces = 0;
          for ( int i = 0; i < nbElems; ++i )
            nbFaces += geoFile.getInt();
          for ( int f = 0; f < nbFaces; ++f )
            nbNodes += geoFile.getInt();
          geoFile.skip( nbNodes * INT_WIDTH_GOLD, /*nbLines = */nbFaces );
        }
        else // standard types
        {
          geoFile.skip( nbNodes, nbElemNodes, INT_WIDTH_GOLD );
        }
        continue;
      }

      // add a group corresponding to subPart (geoType)
      imed.groupes.push_back(_groupe());
      _groupe & groupe = imed.groupes.back();
      groupe.mailles.resize( nbElems );

      // find out if "coordinates" has already been encountered
      _SubPartDesc coordDesc( partNum , "coordinates");
      map< _SubPartDesc, _SubPart >::iterator descPart =
        imed._subPartDescribed.find( coordDesc );
      bool haveCoords = ( descPart != imed._subPartDescribed.end() );
      if ( haveCoords ) {
        firstNode = descPart->second.myFirstNode;
        nodeShift -= descPart->second.myNbNodes;
      }

      // read poly element data
      bool isPoly = ( !nbElemNodes );
      vector<int> nbElemNodesVec( 1, nbElemNodes);
      vector<int> nbElemFaces, nbFaceNodes;
      if ( partType._name == "nsided" ) // polygons
      {
        nbElemNodesVec.resize( nbElems );
        for ( int i = 0; i < nbElems; ++i )
          nbElemNodesVec[ i ] = geoFile.getInt(); // npi
      }
      else if ( partType._name == "nfaced" ) // polyhedrons
      {
        nbElemFaces.resize( nbElems );
        nbElemNodesVec.resize( nbElems );
        int totalNbFaces = 0;
        for ( int i = 0; i < nbElems; ++i )
          totalNbFaces += ( nbElemFaces[ i ] = geoFile.getInt() ); // nf_ei

        nbFaceNodes.resize( totalNbFaces );
        vector<int>::iterator nbFN = nbFaceNodes.begin();
        for ( int i = 0; i < nbElems; ++i ) {
          nbElemNodesVec[ i ] = 0;
          for ( int nbFaces = nbElemFaces[ i ]; nbFaces; --nbFaces, ++nbFN )
            nbElemNodesVec[ i ] += ( *nbFN = geoFile.getInt() ); // np(f_ei)
        }
      }
      // iterator returning nbElemNodes for standard elems and
      // next value from nbElemNodesVec for poly elements
      _ValueIterator<int> nbElemNodesIt( & nbElemNodesVec[0], isPoly ? 1 : 0);

      // iterator returning values form partType._medIndex for standard elems
      // and node index (n) for poly elements
      int n;
      _ValueIterator<int> medIndexIt( isPoly ? &n : &partType._medIndex[0],
                                      isPoly ? 0  : 1);
      // read connectivity
      _maille ma( partType._medType, nbElemNodes );
      ma.sommets.resize( nbElemNodes );
      INoeud node;
      for ( int i = 0; i < nbElems; ++i ) {
        _ValueIterator<int> medIndex = medIndexIt;
        nbElemNodes = nbElemNodesIt.next();
        if ( ma.sommets.size() != nbElemNodes )
          ma.sommets.resize( nbElemNodes );
        for ( n = 0; n < nbElemNodes; ++n ) {
          int nodeID = geoFile.getInt(); // nn_ei
          if ( haveCoords )
            node = points.find( nodeID + nodeShift );
          else 
            node = points.insert( make_pair( nodeID + nodeShift, _noeud())).first;
          ma.sommets[ medIndex.next() ] = node;
        }
        if ( haveElemIds )
          ma.setOrdre( elemIds[ i ] );
        groupe.mailles[i] = imed.insert(ma);
      }
      // store nb nodes in polyhedron faces
      if ( !nbFaceNodes.empty() ) {
        const int* nbFaceNodesPtr = & nbFaceNodes[0];
        for ( int i = 0; i < nbElems; ++i ) {
          vector<int> & nbNodesByFace = imed.polyherdalNbFaceNodes[ &groupe.maille( i ) ];
          nbNodesByFace.assign( nbFaceNodesPtr, nbFaceNodesPtr + nbElemFaces[ i ] );
          nbFaceNodesPtr += nbElemFaces[ i ];
        }
      }
      // create subPart for "coordinates"
      if ( !haveCoords ) {
        _SubPart & coordSubPart = imed._subPartDescribed[ coordDesc ];
        coordSubPart.myFirstNode = points.insert( make_pair( 1 + nodeShift, _noeud())).first;
      }
      // add subPart group to part group
      int groupeIndex = imed.groupes.size();
      partGroupe->groupes.push_back( groupeIndex );

      // create subPart
      _SubPart subPart( partNum, partType._name );
      subPart.myNbCells = nbElems;
      subPart.myCellGroupIndex = groupeIndex;
      imed.addSubPart( subPart );
    }
    else if ( word == "coordinates" )
    {
      // Local node coordinates of a part
      // ------------------------------------
      int nbNodes = geoFile.getInt(); // nn

      // read node ids
      vector<int> nodeIds;
      if ( haveNodeIds ) {
        nodeIds.reserve( nbNodes );
        while ( nodeIds.size() < nbNodes )
          nodeIds.push_back( geoFile.getInt() ); // id_n
      }

      // find out if "coordinates" has already been add at reading connectivity
      _SubPartDesc coordDesc( partNum , "coordinates");
      map< _SubPartDesc, _SubPart >::iterator descPart =
        imed._subPartDescribed.find( coordDesc );
      bool haveCoords = ( descPart != imed._subPartDescribed.end() );

      if ( haveCoords ) {
        // check that all nodes have been added
        firstNode = descPart->second.myFirstNode;
        descPart->second.myNbNodes = nbNodes;
        INoeud inoeud = firstNode, inoEnd = points.end();
        int id = inoeud->first, idEnd = id + nbNodes;
        for ( ; id < idEnd; ++id ) {
          if ( inoeud == inoEnd || inoeud->first > id ) {
            INoeud in = points.insert( inoeud, make_pair( id, _noeud() ));
            in->second.number = id;
            in->second.coord.resize( SPACE_DIM );
          } else {
            ++inoeud;
          }
        }
      }
      else {
        // add nodes
        int nodeShift = points.empty() ? 0 : points.rbegin()->first;
        for ( int iNode = 1; iNode <= nbNodes; ++iNode ) {
          INoeud inoeud = points.insert( points.end(), make_pair( iNode + nodeShift, _noeud()));
          inoeud->second.number = inoeud->first;
          inoeud->second.coord.resize( SPACE_DIM );
        }
        firstNode = points.find( 1 + nodeShift );
        // create "coordinates" subPart
        _SubPart & subPart  = imed._subPartDescribed[ coordDesc ];
        subPart.myNbNodes   = nbNodes;
        subPart.myFirstNode = firstNode;
      }

      // read coordinates in no interlace mode
      INoeud endNode = points.end();
      for ( int j = 0; j < SPACE_DIM; ++j ) {
        for ( INoeud in = firstNode; in != endNode; ++in ) {
          _noeud & node = in->second;
          node.coord[ j ] = geoFile.getReal();
        }
      }
    }
    else if ( word == "part" )
    {
      // Another part encounters
      // -----------------------
      partNum = geoFile.getInt();
      nbParts++;
      geoFile.toNextLine();

      string partName = geoFile.getLine();
      if ( partName.empty() )
        partName = "Part_" + restLine;

      if ( imed.groupes.capacity() - imed.groupes.size() < theMaxNbTypes )
        imed.groupes.reserve( size_t( 1.5 * imed.groupes.size() ));
      imed.groupes.push_back(_groupe());
      partGroupe = & imed.groupes.back();
      partGroupe->nom = partName;
      partGroupe->groupes.reserve( theMaxNbTypes );
    }
    else if ( word == "block" )
    {
      // Structured type
      // ------------------
      bool rectilinear = ( restLine.find( "rectilinear" ) != restLine.npos );
      bool uniform     = ( restLine.find( "uniform" )     != restLine.npos );
      bool curvilinear = ( !rectilinear && !uniform );
      bool iblanked    = ( restLine.find( "iblanked" )    != restLine.npos );
      bool with_ghost  = ( restLine.find( "with_ghost" )  != restLine.npos );
      bool range       = ( restLine.find( "range" )       != restLine.npos );

      // dimension
      int I = geoFile.getInt();
      int J = geoFile.getInt();
      int K = geoFile.getInt();
      int NumberOfNodes = I*J*K;
      if ( !NumberOfNodes ) continue;

      // range
      if ( range ) {
        vector<int> ijkRange; // imin imax jmin jmax kmin kmax
        ijkRange.reserve(6);
        while ( ijkRange.size() < 6 )
          ijkRange.push_back( geoFile.getInt() );
        I = ijkRange[1]-ijkRange[0]+1;
        J = ijkRange[3]-ijkRange[2]+1;
        K = ijkRange[5]-ijkRange[4]+1;
        NumberOfNodes = I*J*K;
      }
      // add nodes
      int nodeShift = points.empty() ? 0 : points.rbegin()->first;
      for ( int iNode = 1; iNode <= NumberOfNodes; ++iNode ) {
        INoeud inoeud = points.insert( points.end(), make_pair( iNode + nodeShift, _noeud()));
        _noeud & node = inoeud->second;
        node.number   = inoeud->first;
        node.coord.resize( SPACE_DIM );
      }
      INoeud firstNode = points.find( nodeShift + 1 );
      INoeud endNode   = points.end();

      GRID grid; // calculator of unstructured data
      grid._iArrayLength   = I;
      grid._jArrayLength   = J;
      grid._kArrayLength   = K;
      grid._numberOfNodes  = NumberOfNodes ;
      grid._spaceDimension = SPACE_DIM;
      if ( J < 2 ) { grid._spaceDimension--; grid._jArrayLength = 0; }
      if ( K < 2 ) { grid._spaceDimension--; grid._kArrayLength = 0; }
      int nbElems = grid.getNumberOfElements(MED_CELL, MED_ALL_ELEMENTS);

      if ( curvilinear ) // read coordinates for all nodes
      {
        for ( int j = 0; j < SPACE_DIM; ++j ) {
          for ( INoeud in = firstNode; in != endNode; ++in )
            in->second.coord[ j ] = geoFile.getReal();
        }
        grid._gridType = MED_BODY_FITTED;
      }
      else if ( rectilinear ) // read delta vectors with non-regular spacing 
      {
        grid._iArray = (double*)geoFile.convertReals<double>( I );
        grid._jArray = (double*)geoFile.convertReals<double>( J );
        grid._kArray = (double*)geoFile.convertReals<double>( K );
        grid._gridType = MED_CARTESIAN;
      }
      else // uniform: read grid origine and delta vectors for regular spacing grid
      {
        TDblOwner xyzOrigin( (double*)geoFile.convertReals<double>( 3 ));
        TDblOwner xyzDelta ( (double*)geoFile.convertReals<double>( 3 ));
        // compute full delta vectors
        grid._iArray = new double[ I ];
        grid._jArray = new double[ J ];
        grid._kArray = new double[ K ];
        double* coors[SPACE_DIM] = { grid._iArray, grid._jArray, grid._kArray };
        int     size [SPACE_DIM] = { I, J, K };
        for ( int j = 0; j < SPACE_DIM; ++j ) {
          double* coo    = coors[ j ];
          double* cooEnd = coo + size[ j ];
          coo[0]         = xyzOrigin[ j ];
          while ( ++coo < cooEnd )
            *coo = coo[-1] + xyzDelta[ j ];
        }
        grid._gridType = MED_CARTESIAN;
      }

      // iblanks
      if ( iblanked )
        geoFile.skip( NumberOfNodes, /*nbPerLine =*/ 1, INT_WIDTH_GOLD);
      // ghosts
      if ( with_ghost ) {
        geoFile.getWord(); // "ghost_flags"
        geoFile.skip( nbElems, /*nbPerLine =*/ 1, INT_WIDTH_GOLD);
      }
      // node ids
      if ( haveNodeIds && geoFile.lookAt( "node_ids" )) {
        geoFile.getWord(); // "node_ids"
        geoFile.skip( NumberOfNodes, /*nbPerLine =*/ 1, INT_WIDTH_GOLD);
      }
      // element ids
      if ( haveElemIds && geoFile.lookAt( "element_ids" ) ) {
        geoFile.getWord(); // "element_ids"
        geoFile.skip( nbElems, /*nbPerLine =*/ 1, INT_WIDTH_GOLD);
      }

      if ( !curvilinear ) // let GRID compute all coordinates
      {
        grid._coordinate = new COORDINATE;
        const double * coo = grid.getCoordinates(MED_FULL_INTERLACE);
        typedef _ValueIterator< double > TCoordIt;
        TCoordIt xCoo( coo+0, grid._spaceDimension);
        TCoordIt yCoo( coo+1, grid._spaceDimension);
        TCoordIt zCoo( coo+2, grid._spaceDimension);
        if ( grid._spaceDimension < 3 ) zCoo = TCoordIt( grid._kArray, 0 );
        if ( grid._spaceDimension < 2 ) yCoo = TCoordIt( grid._jArray, 0 );
        for ( INoeud in = firstNode; in != endNode; ++in ) {
          _noeud& node = in->second;
          node.coord[ 0 ] = xCoo.next();
          node.coord[ 1 ] = yCoo.next();
          node.coord[ 2 ] = zCoo.next();
        }
      }

      // let GRID calculate connectivity 

      const int * conn = grid.getConnectivity( MED_FULL_INTERLACE, MED_NODAL,
                                               MED_CELL, MED_ALL_ELEMENTS );
      medGeometryElement elemType = grid.getElementType( MED_CELL, 1 );
      int  nbElemNodes = elemType % 100;

      partGroupe->mailles.resize( nbElems );
      _maille ma( elemType, nbElemNodes );
      ma.sommets.resize( nbElemNodes );

      for ( int i = 0, nIndex = 0; i < nbElems; ++i ) {
        for ( int n = 0; n < nbElemNodes; ++n ) {
          int nodeID = conn[ nIndex++ ];
          ma.sommets[n] = points.find( nodeID + nodeShift );
        }
        //ma.ordre = ++order;
        partGroupe->mailles[i] = imed.insert(ma);
      }

      _SubPart subPart( partNum, "block" );
      subPart.myNbCells    = nbElems;
      subPart.myNbNodes    = NumberOfNodes;
      subPart.myFirstNode  = firstNode;
      subPart.myCellGroupIndex = imed.groupes.size();
      imed.addSubPart( subPart );
    }
    else
    {
      throw MEDEXCEPTION
        ( LOCALIZED( STRING(LOC) << "Unexpected word: " << word <<
                     " in " << getDataFileName()));
    }
  } // while ( !geoFile.eof() )

  if ( nbParts > 1 )
    imed.mergeNodesAndElements(TOLERANCE);

  END_OF_MED(LOC);
}

//================================================================================
/*!
 * \brief Read mesh in Gold Binary format
 */
//================================================================================

01791 void ENSIGHT_MESH_RDONLY_DRIVER::readGoldBinary(_InterMed & imed)
{
  const char * LOC ="ENSIGHT_MESH_RDONLY_DRIVER::readGoldBinary() : ";
  BEGIN_OF_MED(LOC);

  _BinaryFileReader geoFile( getDataFileName() );

  // check if swapping bytes needed
  try {
    countPartsBinary( geoFile, isSingleFileMode());
  }
  catch (...) {
    geoFile.swapBytes();
    geoFile.rewind();
  }
  if ( getIndexInDataFile() <= 1 )
    geoFile.rewind();
  if ( geoFile.getPosition() == 0 ) {
    TStrOwner format( geoFile.getLine() ); // "C|Fortran Binary"
    if ( !contains( "C Binary", format )) {
      if ( contains( "Fortran Binary", format ))
        throw(MEDEXCEPTION(STRING(LOC) << "Fortran Binary format not supported"));
      else
        throw(MEDEXCEPTION(STRING(LOC) << "unexpected line in " << getDataFileName()
                           << "\n" << format.myValues));
    }
  }
  if ( isSingleFileMode() ) {
    // one time step may be skipped by countPartsBinary
    int curTimeStep = geoFile.getPosition() ? 2 : 1 ;
    while ( curTimeStep < getIndexInDataFile() ) {
      countPartsBinary( geoFile, true ); // skip time step
      curTimeStep++;
    }
    while (1) {
      TStrOwner line( geoFile.getLine() );
      if ( isTimeStepBeginning( line.myValues ))
        break;
    }
  }
  // ----------------------
  // Read mesh description
  // ----------------------
  {
    TStrOwner descriptionLine1 ( geoFile.getLine() );
    TStrOwner descriptionLine2 ( geoFile.getLine() );

    // find out if the file was created by MED driver
    _isMadeByMed = contains( theDescriptionPrefix, descriptionLine1 );

    if ( _isMadeByMed )
      _ptrMesh->setDescription( descriptionLine2.myValues );
    else
      _ptrMesh->setDescription( string(descriptionLine1) + descriptionLine2.myValues );
  }

  // ----------------------------------------
  // Find out presence of node/elem numbers 
  // ----------------------------------------

  // EnSight User Manual (for v8) says:
//    You do not have to assign node IDs. If you do, the element connectivities are
//    based on the node numbers. If you let EnSight assign the node IDs, the nodes
//    are considered to be sequential starting at node 1, and element connectivity is
//    done accordingly. If node IDs are set to off, they are numbered internally;
//    however, you will not be able to display or query on them. If you have node
//    IDs in your data, you can have EnSight ignore them by specifying "node id
//    ignore." Using this option may reduce some of the memory taken up by the
//    Client and Server, but display and query on the nodes will not be available.

  // read "node|element id <off|given|assign|ignore>"
  bool haveNodeIds, haveElemIds;
  {
    TStrOwner nodeIds( geoFile.getLine() );
    TStrOwner elemIds( geoFile.getLine() );

    haveNodeIds = ( contains( "given", nodeIds ) || contains( "ignore", nodeIds ) );
    haveElemIds = ( contains( "given", elemIds ) || contains( "ignore", elemIds ) );
  }

  typedef map<int,_noeud>::iterator INoeud;
  map<int,_noeud> & points = imed.points;
  INoeud firstNode;

  _groupe * partGroupe = 0;
  int partNum = 0, nbParts = 0;

  TFltOwner extents(0); // extents: xmin xmax ymin ymax zmin zmax

  while ( !geoFile.eof() )
  {
    TStrOwner line( geoFile.getLine() );
    if ( isSingleFileMode() && isTimeStepEnd( line.myValues ))
      break;
    string word, restLine;
    TStrTool::split( line.myValues, word, restLine );

    const TEnSightElemType & partType = getEnSightType( word );
    if ( partType._medType != MED_ALL_ELEMENTS )
    {
      //  Unstructured element type encounters
      // --------------------------------------
      int      nbElems = *TIntOwner( geoFile.getInt(1) ); // ne
      int  nbElemNodes = partType._medType % 100;
      bool     isGhost = isGhostType( word );
      int    nodeShift = points.empty() ? 0 : points.rbegin()->first;

      // read element ids
      TIntOwner elemIds( haveElemIds ? geoFile.getInt( nbElems ): 0 ); // id_e

      if ( isGhost ) { // do not store ghost elements (?)
        int nbNodes = nbElems * nbElemNodes;
        if ( partType._name == "nsided" ) // polygons
        {
          TIntOwner nbNodesInFace( geoFile.getInt( nbElems ));
          nbNodes = std::accumulate( nbNodesInFace.myValues, nbNodesInFace.myValues + nbElems, 0 );
        }
        else if ( partType._name == "nfaced" ) // polyhedrons
        {
          TIntOwner nbElemFaces( geoFile.getInt( nbElems ));
          int nbFaces = accumulate( nbElemFaces.myValues, nbElemFaces.myValues + nbElems, 0 );
          TIntOwner nbNodesInFace( geoFile.getInt( nbFaces ));
          nbNodes = std::accumulate( nbNodesInFace.myValues, nbNodesInFace.myValues + nbElems, 0 );
        }
        geoFile.skip( nbNodes * sizeof(int) );
        continue;
      }

      // add a group corresponding to subPart (geoType)
      imed.groupes.push_back(_groupe());
      _groupe & groupe = imed.groupes.back();
      groupe.mailles.resize( nbElems );

      // find out if "coordinates" has already been encountered
      _SubPartDesc coordDesc( partNum , "coordinates");
      map< _SubPartDesc, _SubPart >::iterator descPart =
        imed._subPartDescribed.find( coordDesc );
      bool haveCoords = ( descPart != imed._subPartDescribed.end() );
      if ( haveCoords ) {
        firstNode = descPart->second.myFirstNode;
        nodeShift -= descPart->second.myNbNodes;
      }

      // read poly element data
      bool isPoly = ( !nbElemNodes );
      int nbNodes = 0;
      TIntOwner nbElemNodesVec(0), nbElemFaces(0), nbFaceNodes(0);
      if ( partType._name == "nsided" ) // polygons
      {
        nbElemNodesVec.myValues = geoFile.getInt( nbElems ); // npi
        nbNodes = accumulate( nbElemNodesVec.myValues, nbElemNodesVec.myValues + nbElems, 0 );
      }
      else if ( partType._name == "nfaced" ) // polyhedrons
      {
        nbElemFaces.myValues = geoFile.getInt( nbElems ); // nf_ei
        int totalNbFaces = accumulate( nbElemFaces.myValues, nbElemFaces.myValues + nbElems, 0 );

        nbFaceNodes.myValues = geoFile.getInt( totalNbFaces ); // np(f_ei)
        // calculate nb of nodes in each polyhedron
        int* nbEN = nbElemNodesVec.myValues = new int[ nbElems ];
        const int *nbFN = nbFaceNodes, *nbEF = nbElemFaces, *nbEND = nbEN + nbElems;
        for ( ; nbEN < nbEND; ++nbEN, ++nbEF ) {
          nbNodes += *nbEN = accumulate( nbFN, nbFN + *nbEF, 0 );
          nbFN    += *nbEF;
        }
      }
      else // standard types
      {
        nbElemNodesVec.myValues = new int[ 1 ];
        nbElemNodesVec[ 0 ] = nbElemNodes;
        nbNodes = nbElems * nbElemNodes;
      }
      // iterator returning nbElemNodes for standard elems and
      // next value from nbElemNodesVec for poly elements
      _ValueIterator<int> nbElemNodesIt( nbElemNodesVec, isPoly ? 1 : 0);

      // iterator returning values form partType._medIndex for standard elems
      // and node index (n) for poly elements
      int n;
      _ValueIterator<int> medIndexIt( isPoly ? &n : &partType._medIndex[0],
                                      isPoly ? 0  : 1);
      // read connectivity
      _maille ma( partType._medType, nbElemNodes );
      ma.sommets.resize( nbElemNodes );
      TIntOwner connectivity( geoFile.getInt( nbNodes )); // nn_ei
      int* nodeID = connectivity;
      INoeud node;
      for ( int i = 0; i < nbElems; ++i ) {
        _ValueIterator<int> medIndex = medIndexIt;
        nbElemNodes = nbElemNodesIt.next();
        if ( ma.sommets.size() != nbElemNodes )
          ma.sommets.resize( nbElemNodes );
        for ( n = 0; n < nbElemNodes; ++n, ++nodeID ) {
          if ( haveCoords )
            node = points.find( *nodeID + nodeShift );
          else
            node = points.insert( make_pair( *nodeID + nodeShift, _noeud())).first;
          ma.sommets[ medIndex.next() ] = node;
        }
        if ( haveElemIds )
          ma.setOrdre( elemIds[ i ] );
        groupe.mailles[i] = imed.insert(ma);
      }
      // store nb nodes in polyhedron faces
      if ( nbFaceNodes.myValues ) {
        const int* nbFaceNodesPtr = nbFaceNodes.myValues;
        for ( int i = 0; i < nbElems; ++i ) {
          vector<int> & nbNodesByFace = imed.polyherdalNbFaceNodes[ &groupe.maille( i ) ];
          nbNodesByFace.assign( nbFaceNodesPtr, nbFaceNodesPtr + nbElemFaces[ i ] );
          nbFaceNodesPtr += nbElemFaces[ i ];
        }
      }
      // create subPart for "coordinates"
      if ( !haveCoords ) {
        _SubPart & coordSubPart = imed._subPartDescribed[ coordDesc ];
        coordSubPart.myFirstNode = points.insert( make_pair( 1 + nodeShift, _noeud())).first;
      }
      // add subPart group to part group
      int groupeIndex = imed.groupes.size();
      partGroupe->groupes.push_back( groupeIndex );

      // create subPart
      _SubPart subPart( partNum, partType._name );
      subPart.myNbCells = nbElems;
      subPart.myCellGroupIndex = groupeIndex;
      imed.addSubPart( subPart );
    }
    else if ( word == "coordinates" )
    {
      // Local node coordinates of a part
      // ------------------------------------
      int nbNodes = *TIntOwner( geoFile.getInt(1) ); // nn

      // read node ids
      TIntOwner nodeIds(0);
      if ( haveNodeIds )
        nodeIds.myValues = geoFile.getInt( nbNodes ); // id_n

      // find out if "coordinates" has already been add at reading connectivity
      _SubPartDesc coordDesc( partNum , "coordinates");
      map< _SubPartDesc, _SubPart >::iterator descPart =
        imed._subPartDescribed.find( coordDesc );
      bool haveCoords = ( descPart != imed._subPartDescribed.end() );

      if ( haveCoords ) {
        // check that all nodes have been added
        firstNode = descPart->second.myFirstNode;
        descPart->second.myNbNodes = nbNodes;
        INoeud inoeud = firstNode, inoEnd = points.end();
        int id = inoeud->first, idEnd = id + nbNodes;
        for ( ; id < idEnd; ++id ) {
          if ( inoeud == inoEnd || inoeud->first > id ) {
            INoeud in = points.insert( inoeud, make_pair( id, _noeud() ));
            in->second.number = id;
          } else {
            ++inoeud;
          }
        }
      }
      else {
        // add nodes
        int nodeShift = points.empty() ? 0 : points.rbegin()->first;
        for ( int iNode = 1; iNode <= nbNodes; ++iNode ) {
          INoeud inoeud = points.insert( points.end(), make_pair( iNode + nodeShift, _noeud()));
          inoeud->second.number = inoeud->first;
        }
        firstNode = points.find( 1 + nodeShift );
        // create "coordinates" subPart
        _SubPart & subPart  = imed._subPartDescribed[ coordDesc ];
        subPart.myNbNodes   = nbNodes;
        subPart.myFirstNode = firstNode;
      }

      // read coordinates in no interlace mode
      TFltOwner noInterlaceCoords( geoFile.getFlt( nbNodes * SPACE_DIM ));
      float* x = noInterlaceCoords;
      float* y = x + nbNodes;
      float* z = y + nbNodes;
      INoeud endNode = points.end();
      for ( INoeud in = firstNode; in != endNode; ++in ) {
        _noeud & node = in->second;
        node.coord.resize( SPACE_DIM );
        node.coord[ 0 ] = *x++;
        node.coord[ 1 ] = *y++;
        node.coord[ 2 ] = *z++;
      }
    }
    else if ( word == "part" )
    {
      // Another part encounters
      // -----------------------
      partNum = *TIntOwner( geoFile.getInt(1) );
      nbParts++;

      string partName( TStrOwner( geoFile.getLine() ));
      if ( partName.empty() )
        partName = "Part_" + restLine;

      if ( imed.groupes.capacity() - imed.groupes.size() < theMaxNbTypes )
        imed.groupes.reserve( size_t( 1.5 * imed.groupes.size() ));
      imed.groupes.push_back(_groupe());
      partGroupe = & imed.groupes.back();
      partGroupe->nom = partName;
      partGroupe->groupes.reserve( theMaxNbTypes );
    }
    else if ( word == "block" )
    {
      // Structured type
      // ------------------
      bool rectilinear = ( restLine.find( "rectilinear" ) != restLine.npos );
      bool uniform     = ( restLine.find( "uniform" )     != restLine.npos );
      bool curvilinear = ( !rectilinear && !uniform );
      bool iblanked    = ( restLine.find( "iblanked" )    != restLine.npos );
      bool with_ghost  = ( restLine.find( "with_ghost" )  != restLine.npos );
      bool range       = ( restLine.find( "range" )       != restLine.npos );

      // dimension
      TIntOwner ijk( geoFile.getInt(3) );
      int I = ijk[0];
      int J = ijk[1];
      int K = ijk[2];
      int NumberOfNodes = I*J*K;
      if ( !NumberOfNodes ) continue;

      // range
      if ( range ) {
        TIntOwner ijkRange( geoFile.getInt( 6 ));// imin imax jmin jmax kmin kmax
        I = ijkRange[1]-ijkRange[0]+1;
        J = ijkRange[3]-ijkRange[2]+1;
        K = ijkRange[5]-ijkRange[4]+1;
        NumberOfNodes = I*J*K;
      }
      // add nodes
      int nodeShift = points.empty() ? 0 : points.rbegin()->first;
      for ( int iNode = 1; iNode <= NumberOfNodes; ++iNode ) {
        INoeud inoeud = points.insert( points.end(), make_pair( iNode + nodeShift, _noeud()));
        _noeud & node = inoeud->second;
        node.number   = inoeud->first;
        node.coord.resize( SPACE_DIM );
      }
      INoeud firstNode = points.find( nodeShift + 1 );
      INoeud endNode   = points.end();

      GRID grid; // calculator of unstructured data
      grid._iArrayLength   = I;
      grid._jArrayLength   = J;
      grid._kArrayLength   = K;
      grid._numberOfNodes  = NumberOfNodes ;
      grid._spaceDimension = SPACE_DIM;
      if ( J < 2 ) { grid._spaceDimension--; grid._jArrayLength = 0; }
      if ( K < 2 ) { grid._spaceDimension--; grid._kArrayLength = 0; }
      int nbElems = grid.getNumberOfElements(MED_CELL, MED_ALL_ELEMENTS);

      if ( curvilinear ) // read coordinates for all nodes
      {
        TFltOwner noInterlaceCoords( geoFile.getFlt( NumberOfNodes * SPACE_DIM ));
        float* x = noInterlaceCoords;
        float* y = x + NumberOfNodes;
        float* z = y + NumberOfNodes;
        for ( INoeud in = firstNode; in != endNode; ++in ) {
          _noeud & node = in->second;
          node.coord.resize( SPACE_DIM );
          node.coord[ 0 ] = *x++;
          node.coord[ 1 ] = *y++;
          node.coord[ 2 ] = *z++;
        }
        grid._gridType = MED_BODY_FITTED;
      }
      else if ( rectilinear ) // read delta vectors with non-regular spacing 
      {
        grid._iArray = (double*)geoFile.convertReals<double>( I );
        grid._jArray = (double*)geoFile.convertReals<double>( J );
        grid._kArray = (double*)geoFile.convertReals<double>( K );
        grid._gridType = MED_CARTESIAN;
      }
      else // uniform: read grid origine and delta vectors for regular spacing grid
      {
        TFltOwner xyzOrigin( geoFile.getFlt( 3 ));
        TFltOwner xyzDelta ( geoFile.getFlt( 3 ));
        // compute full delta vectors
        grid._iArray = new double[ I ];
        grid._jArray = new double[ J ];
        grid._kArray = new double[ K ];
        double* coors[SPACE_DIM] = { grid._iArray, grid._jArray, grid._kArray };
        int     size [SPACE_DIM] = { I, J, K };
        for ( int j = 0; j < SPACE_DIM; ++j ) {
          double* coo    = coors[ j ];
          double* cooEnd = coo + size[ j ];
          coo[0]         = xyzOrigin[ j ];
          while ( ++coo < cooEnd )
            *coo = coo[-1] + xyzDelta[ j ];
        }
        grid._gridType = MED_CARTESIAN;
      }

      // iblanks
      if ( iblanked )
        geoFile.skip( NumberOfNodes * sizeof(int) );
      // ghosts
      if ( with_ghost ) {
        TStrOwner( geoFile.getLine() ); // "ghost_flags"
        geoFile.skip( nbElems * sizeof(int) );
      }
      // node ids
      if ( haveNodeIds && !geoFile.eof() ) {
        TStrOwner nextLine( geoFile.getLine() ); // "node_ids"
        if ( contains( "node_ids", nextLine ) )
          geoFile.skip( NumberOfNodes * sizeof(int) );
        else
          geoFile.skip( -MAX_LINE_LENGTH );
      }
      // element ids
      TIntOwner elemIdOwner(0);
      _ValueIterator<int> elemIds;
      if ( haveElemIds && !geoFile.eof() ) {
        TStrOwner nextLine( geoFile.getLine() ); // "element_ids"
        if ( contains( "element_ids", nextLine ) ) {
          elemIdOwner.myValues = geoFile.getInt( nbElems );
          elemIds = _ValueIterator<int>( elemIdOwner, 1);
        } else {
          geoFile.skip( -MAX_LINE_LENGTH );
        }
      }

      if ( !curvilinear ) // let GRID compute all coordinates
      {
        grid._coordinate = new COORDINATE;
        const double * coo = grid.getCoordinates(MED_FULL_INTERLACE);
        typedef _ValueIterator< double > TCoordIt;
        TCoordIt xCoo( coo+0, grid._spaceDimension);
        TCoordIt yCoo( coo+1, grid._spaceDimension);
        TCoordIt zCoo( coo+2, grid._spaceDimension);
        if ( grid._spaceDimension < 3 ) zCoo = TCoordIt( grid._kArray, 0 );
        if ( grid._spaceDimension < 2 ) yCoo = TCoordIt( grid._jArray, 0 );
        for ( INoeud in = firstNode; in != endNode; ++in ) {
          _noeud& node = in->second;
          node.coord[ 0 ] = xCoo.next();
          node.coord[ 1 ] = yCoo.next();
          node.coord[ 2 ] = zCoo.next();
        }
      }

      // let GRID calculate connectivity 

      const int * conn = grid.getConnectivity( MED_FULL_INTERLACE, MED_NODAL,
                                               MED_CELL, MED_ALL_ELEMENTS );
      medGeometryElement elemType = grid.getElementType( MED_CELL, 1 );
      int  nbElemNodes = elemType % 100;

      partGroupe->mailles.resize( nbElems );
      _maille ma( elemType, nbElemNodes );
      ma.sommets.resize( nbElemNodes );

      for ( int i = 0, nIndex = 0; i < nbElems; ++i ) {
        for ( int n = 0; n < nbElemNodes; ++n ) {
          int nodeID = conn[ nIndex++ ];
          ma.sommets[n] = points.find( nodeID + nodeShift );
        }
        ma.setOrdre( elemIds.next() );
        partGroupe->mailles[i] = imed.insert(ma);
      }

      _SubPart subPart( partNum, "block" );
      subPart.myNbCells    = nbElems;
      subPart.myNbNodes    = NumberOfNodes;
      subPart.myFirstNode  = firstNode;
      subPart.myCellGroupIndex = imed.groupes.size();
      imed.addSubPart( subPart );
    }
    else if ( word == "extents" )
    {
      extents.myValues = geoFile.getFlt( 6 );
    }
    else
    {
      throw MED_EXCEPTION
        ( LOCALIZED( STRING(LOC) << "Unexpected word: " << word <<
                     " in " << getDataFileName()));
    }
  } // while ( !geoFile.eof() )

  if ( nbParts > 1 )
    imed.mergeNodesAndElements(TOLERANCE);

  END_OF_MED(LOC);
}

//================================================================================
/*!
 * \brief Read mesh in Ensight6 ASCII format
 */
//================================================================================

02284 void ENSIGHT_MESH_RDONLY_DRIVER::read6ASCII(_InterMed & imed)
{
  const char * LOC ="ENSIGHT_MESH_RDONLY_DRIVER::read6ASCII() : ";
  BEGIN_OF_MED(LOC);

  _ASCIIFileReader geoFile( getDataFileName() );

  if ( isSingleFileMode() ) {
    int curTimeStep = 1;
    while ( curTimeStep < getIndexInDataFile() ) {
      while ( !geoFile.isTimeStepEnd())
        geoFile.getLine();
      curTimeStep++;
    }
    while ( !geoFile.isTimeStepBeginning() )
      geoFile.getLine();
  }
  // ----------------------
  // Read mesh description
  // ----------------------
  {
    string descriptionLine1 = geoFile.getLine();
    string descriptionLine2 = geoFile.getLine();

    // find out if the file was created by MED driver
    int prefixSize = strlen( theDescriptionPrefix );
    _isMadeByMed = ( descriptionLine1.substr(0, prefixSize ) == theDescriptionPrefix );

    if ( _isMadeByMed )
      descriptionLine1 = descriptionLine1.substr( prefixSize );
    _ptrMesh->setDescription( descriptionLine1 + descriptionLine2 );
  }

  // ----------------------------------------
  // Find out presence of node/elem numbers 
  // ----------------------------------------

  // EnSight User Manual (for v8) says:
//    You do not have to assign node IDs. If you do, the element connectivities are
//    based on the node numbers. If you let EnSight assign the node IDs, the nodes
//    are considered to be sequential starting at node 1, and element connectivity is
//    done accordingly. If node IDs are set to off, they are numbered internally;
//    however, you will not be able to display or query on them. If you have node
//    IDs in your data, you can have EnSight ignore them by specifying "node id
//    ignore." Using this option may reduce some of the memory taken up by the
//    Client and Server, but display and query on the nodes will not be available.

  // read "node|element id <off|given|assign|ignore>"
  geoFile.getWord(); geoFile.getWord();
  string nodeIds = geoFile.getWord();
  geoFile.getWord(); geoFile.getWord();
  string elemIds = geoFile.getWord();

  bool haveNodeIds = ( nodeIds == "given" || nodeIds == "ignore" );
  bool haveElemIds = ( elemIds == "given" || elemIds == "ignore" );

  map<int,_noeud> & points = imed.points;
  typedef map<int,_noeud>::iterator INoeud;

  int haveStructuredParts = 0, haveUnstructuredParts = 0;

  _groupe * partGroupe = 0;
  int       partNum = 0;

  while ( !geoFile.isTimeStepEnd() )
  {
    string word, restLine, line = geoFile.getLine();
    TStrTool::split( line, word, restLine );

    const TEnSightElemType & partType = getEnSightType( word );
    if ( !partType._medIndex.empty() )
    {
      //  Unstructured element type encounters
      // --------------------------------------
      int  nbElemNodes = partType._medType % 100;
      int      nbElems = geoFile.getInt();
      if ( nbElems > 0 )
        haveUnstructuredParts++;

      imed.groupes.push_back(_groupe());
      _groupe & groupe = imed.groupes.back();
      groupe.mailles.resize( nbElems );

      // read connectivity
      _maille ma( partType._medType, nbElemNodes );
      ma.sommets.resize( nbElemNodes );
      INoeud node;
      for ( int i = 0; i < nbElems; ++i ) {
        if ( haveElemIds )
          geoFile.getInt();
        for ( int n = 0; n < nbElemNodes; ++n ) {
          int nodeID = geoFile.getInt();
          ma.sommets[ partType._medIndex[n] ] = points.find( nodeID );
        }
        //ma.ordre = ++order;
        groupe.mailles[i] = imed.insert(ma);
      }

      int groupeIndex = imed.groupes.size();
      partGroupe->groupes.push_back( groupeIndex );

      _SubPart subPart( partNum, partType._name );
      subPart.myNbCells = nbElems;
      subPart.myCellGroupIndex = groupeIndex;
      imed.addSubPart( subPart );
    }
    else if ( word == "part" )
    {
      // Another part encounters
      // -----------------------
      partNum = atoi( restLine.c_str() );

      string partName = geoFile.getLine();
      if ( partName.empty() )
        partName = "Part_" + restLine;

      if ( imed.groupes.capacity() - imed.groupes.size() < theMaxNbTypes )
        imed.groupes.reserve( size_t( 1.5 * imed.groupes.size() ));
      imed.groupes.push_back(_groupe());
      partGroupe = & imed.groupes.back();
      partGroupe->nom = partName;
      partGroupe->groupes.reserve( theMaxNbTypes );
    }
    else if ( word == "block" )
    {
      // Structured type
      // ------------------
      bool iblanked  = ( restLine == "iblanked" );

      // dimension
      int I = geoFile.getInt();
      int J = geoFile.getInt();
      int K = geoFile.getInt();
      int NumberOfNodes = I*J*K;
      if ( !NumberOfNodes ) continue;
      haveStructuredParts++;

      // add nodes
      int nodeShift = points.empty() ? 0 : points.rbegin()->first;
      for ( int iNode = 1; iNode <= NumberOfNodes; ++iNode ) {
        INoeud inoeud = points.insert( points.end(), make_pair( iNode + nodeShift, _noeud()));
        _noeud & node = inoeud->second;
        node.number   = inoeud->first;
        node.coord.resize( SPACE_DIM );
      }
      // read coordinates
      INoeud firstNode = points.find( nodeShift + 1 );
      INoeud endNode   = points.end();
      for ( int j = 0; j < SPACE_DIM; ++j ) {
        for ( INoeud in = firstNode; in != endNode; ++in ) {
          _noeud & node = in->second;
          node.coord[ j ] = geoFile.getReal();
        }
      }
      // iblanks
      if ( iblanked )
        geoFile.skip(NumberOfNodes, /*nbPerLine =*/ 10, INT_WIDTH_6);

      // let GRID calculate connectivity 
      GRID grid;
      grid._numberOfNodes = NumberOfNodes ;
      grid._iArrayLength  = I;
      grid._jArrayLength  = J;
      grid._kArrayLength  = K;
      grid._gridType      = MED_BODY_FITTED;
      grid._spaceDimension= SPACE_DIM;
      if ( J < 2 ) { grid._spaceDimension--; grid._jArrayLength = 0; }
      if ( K < 2 ) { grid._spaceDimension--; grid._kArrayLength = 0; }

      const int * conn = grid.getConnectivity( MED_FULL_INTERLACE, MED_NODAL,
                                               MED_CELL, MED_ALL_ELEMENTS );
      medGeometryElement elemType = grid.getElementType( MED_CELL, 1 );
      int  nbElemNodes = elemType % 100;
      int      nbElems = grid.getNumberOfElements(MED_CELL, MED_ALL_ELEMENTS);

      partGroupe->mailles.resize( nbElems );
      _maille ma( elemType, nbElemNodes );
      ma.sommets.resize( nbElemNodes );

      for ( int i = 0, nIndex = 0; i < nbElems; ++i ) {
        for ( int n = 0; n < nbElemNodes; ++n ) {
          int nodeID = conn[ nIndex++ ];
          ma.sommets[n] = points.find( nodeID + nodeShift );
        }
        //ma.ordre = ++order;
        partGroupe->mailles[i] = imed.insert(ma);
      }

      _SubPart subPart( partNum, "block" );
      subPart.myNbCells    = nbElems;
      subPart.myNbNodes    = NumberOfNodes;
      subPart.myFirstNode  = firstNode;
      subPart.myCellGroupIndex = imed.groupes.size();
      imed.addSubPart( subPart );
    }
    else if ( word == "coordinates" )
    {
      // ------------------------------------
      // Unstructured global node coordinates
      // ------------------------------------
      int nbNodes = geoFile.getInt();

      cout << "-> loading coordinates of " << nbNodes << " nodes " << endl ;

      INoeud inoeud;
      for ( int i=0 ; i < nbNodes ; i++ )
      {
        if ( haveNodeIds ) {
          int nodeID = geoFile.getInt();
          inoeud = points.insert( make_pair( nodeID, _noeud() )).first;
          inoeud->second.number = nodeID;
        }
        else {
          int nodeID = i + 1;
          inoeud = points.insert( points.end(), make_pair( nodeID, _noeud()));
          inoeud->second.number = nodeID;
        }
        _noeud & node = inoeud->second;
        node.coord.resize( SPACE_DIM );
        node.coord[ 0 ] = geoFile.getReal();
        node.coord[ 1 ] = geoFile.getReal();
        node.coord[ 2 ] = geoFile.getReal();
      }

      _SubPartDesc cooDesc = _SubPartDesc::globalCoordDesc();
      _SubPart subPart( cooDesc.partNumber(), cooDesc.typeName() );
      subPart.myNbNodes    = nbNodes;
      subPart.myFirstNode  = points.begin();
      imed.addSubPart( subPart );
    }
    else
    {
      throw MED_EXCEPTION
        ( LOCALIZED( STRING(LOC) << "Unexpected word: " << word <<
                     " in " << getDataFileName()));
    }
  } // while ( !geoFile.eof() )

  if ( haveStructuredParts && haveUnstructuredParts || haveStructuredParts > 1 )
    imed.mergeNodesAndElements(TOLERANCE);

  END_OF_MED(LOC);
}

//================================================================================
/*!
 * \brief Read mesh in Ensight6 ASCII format
 */
//================================================================================

02534 void ENSIGHT_MESH_RDONLY_DRIVER::read6Binary(_InterMed & imed)
{
  const char * LOC ="ENSIGHT_MESH_RDONLY_DRIVER::read6Binary() : ";
  BEGIN_OF_MED(LOC);

  _BinaryFileReader geoFile( getDataFileName() );

  // check if swapping bytes needed
  try {
    countPartsBinary( geoFile, isSingleFileMode());
  }
  catch (...) {
    geoFile.swapBytes();
    geoFile.rewind();
  }
  if ( getIndexInDataFile() <= 1 )
    geoFile.rewind();
  if ( geoFile.getPosition() == 0 ) {
    TStrOwner format( geoFile.getLine() ); // "C|Fortran Binary"
    if ( !contains( "C Binary", format )) {
      if ( contains( "Fortran Binary", format ))
        throw(MEDEXCEPTION(STRING(LOC) << "Fortran Binary format not supported"));
      else
        throw(MEDEXCEPTION(STRING(LOC) << "unexpected line in " << getDataFileName()
                           << "\n" << format.myValues));
    }
  }

  if ( isSingleFileMode() ) {
    // one time step may be skipped by countPartsBinary
    int curTimeStep = geoFile.getPosition() ? 2 : 1 ;
    while ( curTimeStep < getIndexInDataFile() ) {
      countPartsBinary( geoFile, true ); // skip time step
      curTimeStep++;
    }
    while (1) {
      TStrOwner line( geoFile.getLine() );
      if ( isTimeStepBeginning( line.myValues ))
        break;
    }
  }
  // ----------------------
  // Read mesh description
  // ----------------------
  {
    TStrOwner descriptionLine1( geoFile.getLine() );
    TStrOwner descriptionLine2( geoFile.getLine() );

    // find out if the file was created by MED driver
    _isMadeByMed = contains( theDescriptionPrefix, descriptionLine1 );

    if ( _isMadeByMed )
      _ptrMesh->setDescription( descriptionLine2.myValues );
    else
      _ptrMesh->setDescription( string(descriptionLine1) + descriptionLine2.myValues );
  }

  // ----------------------------------------
  // Find out presence of node/elem numbers 
  // ----------------------------------------

  // EnSight User Manual (for v8) says:
//    You do not have to assign node IDs. If you do, the element connectivities are
//    based on the node numbers. If you let EnSight assign the node IDs, the nodes
//    are considered to be sequential starting at node 1, and element connectivity is
//    done accordingly. If node IDs are set to off, they are numbered internally;
//    however, you will not be able to display or query on them. If you have node
//    IDs in your data, you can have EnSight ignore them by specifying "node id
//    ignore." Using this option may reduce some of the memory taken up by the
//    Client and Server, but display and query on the nodes will not be available.

  // read "node|element id <off|given|assign|ignore>"
  bool haveNodeIds, haveElemIds;
  {
    TStrOwner nodeIds( geoFile.getLine() );
    TStrOwner elemIds( geoFile.getLine() );

    haveNodeIds = ( contains( "given", nodeIds ) || contains( "ignore", nodeIds ) );
    haveElemIds = ( contains( "given", elemIds ) || contains( "ignore", elemIds ) );
  }
  map<int,_noeud> & points = imed.points;
  typedef map<int,_noeud>::iterator INoeud;

  int haveStructuredParts = 0, haveUnstructuredParts = 0;

  _groupe * partGroupe = 0;
  int       partNum = 0;

  while ( !geoFile.eof() )
  {
    TStrOwner line( geoFile.getLine() );
    if ( isSingleFileMode() && isTimeStepEnd( line.myValues ))
      break;
    string word, restLine;
    TStrTool::split( line.myValues, word, restLine );

    const TEnSightElemType & partType = getEnSightType( word );
    if ( !partType._medIndex.empty() )
    {
      //  Unstructured element type encounters
      // --------------------------------------
      int  nbElemNodes = partType._medType % 100;
      int      nbElems = *TIntOwner( geoFile.getInt(1) ); // ne
      if ( nbElems > 0 )
        haveUnstructuredParts++;

      TIntOwner numbers(0);
      if ( haveElemIds )
        numbers.myValues = geoFile.getInt( nbElems ); // id_e

      imed.groupes.push_back(_groupe());
      _groupe & groupe = imed.groupes.back();
      groupe.mailles.resize( nbElems );

      // read connectivity
      _maille ma( partType._medType, nbElemNodes );
      ma.sommets.resize( nbElemNodes );
      TIntOwner connectivity( geoFile.getInt( nbElems * nbElemNodes ));
      int* nodeID = connectivity;
      INoeud node;
      for ( int i = 0; i < nbElems; ++i ) {
        for ( int n = 0; n < nbElemNodes; ++n, ++nodeID )
          ma.sommets[ partType._medIndex[n] ] = points.find( *nodeID );
        //ma.ordre = ++order;
        groupe.mailles[i] = imed.insert(ma);
      }

      int groupeIndex = imed.groupes.size();
      partGroupe->groupes.push_back( groupeIndex );

      _SubPart subPart( partNum, partType._name );
      subPart.myNbCells = nbElems;
      subPart.myCellGroupIndex = groupeIndex;
      imed.addSubPart( subPart );
    }
    else if ( word == "part" )
    {
      // Another part encounters
      // -----------------------
      partNum = atoi( restLine.c_str() );

      string partName( TStrOwner( geoFile.getLine() ));
      if ( partName.empty() )
        partName = "Part_" + restLine;

      if ( imed.groupes.capacity() - imed.groupes.size() < theMaxNbTypes )
        imed.groupes.reserve( size_t( 1.5 * imed.groupes.size() ));
      imed.groupes.push_back(_groupe());
      partGroupe = & imed.groupes.back();
      partGroupe->nom = partName;
      partGroupe->groupes.reserve( theMaxNbTypes );
    }
    else if ( word == "block" )
    {
      // Structured type
      // ------------------
      bool iblanked  = ( restLine == "iblanked" );

      // dimension
      TIntOwner ijk( geoFile.getInt(3) );
      int I = ijk[0];
      int J = ijk[1];
      int K = ijk[2];
      int NumberOfNodes = I*J*K;
      if ( !NumberOfNodes ) continue;
      haveStructuredParts++;

      // read coordinates
      int nodeShift = points.empty() ? 0 : points.rbegin()->first;
      {
        TFltOwner noInterlaceCoords( geoFile.getFlt( NumberOfNodes * SPACE_DIM ));
        float* x = noInterlaceCoords;
        float* y = x + NumberOfNodes;
        float* z = y + NumberOfNodes;
        for ( int iNode = 1; iNode <= NumberOfNodes; ++iNode ) {
          INoeud inoeud = points.insert( points.end(), make_pair( iNode + nodeShift, _noeud()));
          _noeud & node = inoeud->second;
          node.number   = inoeud->first;
          node.coord.resize( SPACE_DIM );
          node.coord[0] = *x++;
          node.coord[1] = *y++;
          node.coord[2] = *z++;
        }
      }
      // iblanks
      if ( iblanked )
        geoFile.skip(NumberOfNodes * sizeof(int));

      // let GRID calculate connectivity 
      GRID grid;
      grid._numberOfNodes = NumberOfNodes ;
      grid._iArrayLength  = I;
      grid._jArrayLength  = J;
      grid._kArrayLength  = K;
      grid._gridType      = MED_BODY_FITTED;
      grid._spaceDimension= SPACE_DIM;
      if ( J < 2 ) { grid._spaceDimension--; grid._jArrayLength = 0; }
      if ( K < 2 ) { grid._spaceDimension--; grid._kArrayLength = 0; }

      const int * conn = grid.getConnectivity( MED_FULL_INTERLACE, MED_NODAL,
                                               MED_CELL, MED_ALL_ELEMENTS );
      medGeometryElement elemType = grid.getElementType( MED_CELL, 1 );
      int  nbElemNodes = elemType % 100;
      int      nbElems = grid.getNumberOfElements(MED_CELL, MED_ALL_ELEMENTS);

      partGroupe->mailles.resize( nbElems );
      _maille ma( elemType, nbElemNodes );
      ma.sommets.resize( nbElemNodes );

      for ( int i = 0, nIndex = 0; i < nbElems; ++i ) {
        for ( int n = 0; n < nbElemNodes; ++n ) {
          int nodeID = conn[ nIndex++ ];
          ma.sommets[n] = points.find( nodeID + nodeShift );
        }
        //ma.ordre = ++order;
        partGroupe->mailles[i] = imed.insert(ma);
      }

      _SubPart subPart( partNum, "block" );
      subPart.myNbCells    = nbElems;
      subPart.myNbNodes    = NumberOfNodes;
      subPart.myFirstNode  = points.find( nodeShift + 1 );
      subPart.myCellGroupIndex = imed.groupes.size();
      imed.addSubPart( subPart );
    }
    else if ( word == "coordinates" )
    {
      // ------------------------------
      // Unstructured node coordinates
      // ------------------------------
      int nbNodes = *TIntOwner( geoFile.getInt(1) );

      TIntOwner numbers(0);
      if ( haveNodeIds )
        numbers.myValues = geoFile.getInt( nbNodes );

      TFltOwner fullInterlaceCoords( geoFile.getFlt( nbNodes * SPACE_DIM ));
      float* coord = fullInterlaceCoords;

      cout << "-> loading coordinates of " << nbNodes << " nodes " << endl ;

      INoeud inoeud;
      for ( int i=0 ; i < nbNodes ; i++ )
      {
        if ( haveNodeIds ) {
          int nodeID = numbers[ i ];
          inoeud = points.insert( make_pair( nodeID, _noeud() )).first;
          inoeud->second.number = nodeID;
        }
        else {
          int nodeID = i + 1;
          inoeud = points.insert( points.end(), make_pair( nodeID, _noeud()));
          inoeud->second.number = nodeID;
        }
        _noeud & node = inoeud->second;
        node.coord.resize( SPACE_DIM );
        node.coord[ 0 ] = *coord++;
        node.coord[ 1 ] = *coord++;
        node.coord[ 2 ] = *coord++;
      }

      _SubPartDesc cooDesc = _SubPartDesc::globalCoordDesc();
      _SubPart subPart( cooDesc.partNumber(), cooDesc.typeName() );
      subPart.myNbNodes    = nbNodes;
      subPart.myFirstNode  = points.begin();
      imed.addSubPart( subPart );
    }
    else
    {
      throw MED_EXCEPTION
        ( LOCALIZED( STRING(LOC) << "Unexpected word: " << word <<
                     " in " << getDataFileName()));
    }
  } // while ( !geoFile.eof() )

  if ( haveStructuredParts && haveUnstructuredParts || haveStructuredParts > 1 )
    imed.mergeNodesAndElements(TOLERANCE);

  END_OF_MED(LOC);
}

//================================================================================
/*!
 * \brief count number of parts in EnSight geometry file
 */
//================================================================================

int ENSIGHT_MESH_RDONLY_DRIVER::countParts(const string& geomFileName,
                                           const bool    isSingleFileMode)
{
  const char * LOC ="ENSIGHT_MESH_RDONLY_DRIVER::countParts() : ";

  int nbParts = 0;
  if ( isBinaryDataFile( geomFileName ))
  {
    _BinaryFileReader geoFile(geomFileName);
    // check if swapping bytes needed
    try {
      return countPartsBinary( geoFile, isSingleFileMode );
    }
    catch (...) {
    }
    geoFile.swapBytes();
    geoFile.rewind();
    nbParts = countPartsBinary( geoFile, isSingleFileMode );
  }
  else
  {
    _ASCIIFileReader geoFile(geomFileName);

    if ( isSingleFileMode )
      while ( !isTimeStepBeginning( geoFile.getLine() ));

    geoFile.getLine(); // description line 1
    geoFile.getLine(); // description line 2

    // read "node|element id <off|given|assign|ignore>"
    geoFile.getWord(); geoFile.getWord();
    string nodeIds = geoFile.getWord();
    geoFile.getWord(); geoFile.getWord();
    string elemIds = geoFile.getWord();
    bool haveNodeIds = ( nodeIds == "given" || nodeIds == "ignore" );
    bool haveElemIds = ( elemIds == "given" || elemIds == "ignore" );

    bool isGold = true;
    while ( !geoFile.isTimeStepEnd() )
    {
      string word, restLine, line = geoFile.getLine();
      TStrTool::split( line, word, restLine );

      const TEnSightElemType & partType = getEnSightType( word );
      if ( partType._medType != MED_ALL_ELEMENTS )
      {
        //  Unstructured element type encounters
        // --------------------------------------
        int  nbElemNodes = partType._medType % 100;
        int      nbElems = geoFile.getInt(); // ne

        // element ids
        if ( haveElemIds && isGold )
          geoFile.skip( nbElems, /*nbPerLine =*/ 1, INT_WIDTH_GOLD ); // id_e

        // skip connectivity
        int nbNodes = nbElems * nbElemNodes;
        if ( partType._name == "nsided" ) // polygons
        {
          for ( int i = 0; i < nbElems; ++i )
            nbNodes += geoFile.getInt();
          geoFile.skip( nbNodes * INT_WIDTH_GOLD, /*nbLines = */nbElems );
        }
        else if ( partType._name == "nfaced" ) // polyhedrons
        {
          int nbFaces = 0;
          for ( int i = 0; i < nbElems; ++i )
            nbFaces += geoFile.getInt();
          for ( int f = 0; f < nbFaces; ++f )
            nbNodes += geoFile.getInt();
          geoFile.skip( nbNodes * INT_WIDTH_GOLD, /*nbLines = */nbFaces );
        }
        else // standard types
        {
          if ( isGold )
            geoFile.skip( nbNodes, nbElemNodes, INT_WIDTH_GOLD );
          else if ( haveElemIds )
            geoFile.skip( nbNodes + nbElems, nbElemNodes+1, INT_WIDTH_6 );
          else
            geoFile.skip( nbNodes, nbElemNodes, INT_WIDTH_6 );
        }
      }
      else if ( word == "coordinates" )
      {
        isGold = ( nbParts > 0 );
        int nbNodes = geoFile.getInt(); // nn

        if ( isGold )
        {
          if ( haveNodeIds )
            geoFile.skip( nbNodes, /*nbPerLine =*/ 1, INT_WIDTH_GOLD ); // node ids
          geoFile.skip( nbNodes * SPACE_DIM, /*nbPerLine =*/ 1, FLT_WIDTH ); //  coordinates
        }
        else {
          int coordWidth = 3 * FLT_WIDTH;
          if ( haveNodeIds )
            coordWidth += INT_WIDTH_6;
          geoFile.skip(nbNodes, /*nbPerLine =*/ 1, coordWidth);
        }
      }
      else if ( word == "part" )
      {
        nbParts++;
        if ( isGold )
          geoFile.skip( 1, /*nbPerLine =*/ 1, INT_WIDTH_GOLD ); //part number
        else
          geoFile.getWord(); // part number
        geoFile.toNextLine();
        geoFile.getLine(); // description line
      }
      else if ( word == "block" )
      {
        // Structured type
        // ------------------
        bool rectilinear = ( restLine.find( "rectilinear" ) != restLine.npos );
        bool uniform     = ( restLine.find( "uniform" )     != restLine.npos );
        bool curvilinear = ( !rectilinear && !uniform );
        bool iblanked    = ( restLine.find( "iblanked" )    != restLine.npos );
        bool with_ghost  = ( restLine.find( "with_ghost" )  != restLine.npos );
        bool range       = ( restLine.find( "range" )       != restLine.npos );

        // dimension
        int I = geoFile.getInt();
        int J = geoFile.getInt();
        int K = geoFile.getInt();
        int nbNodes = I*J*K;
        if ( !nbNodes ) continue;

        // range
        if ( range ) {
          vector<int> ijkRange; // imin imax jmin jmax kmin kmax
          ijkRange.reserve(6);
          while ( ijkRange.size() < 6 )
            ijkRange.push_back( geoFile.getInt() );
          I = ijkRange[1]-ijkRange[0]+1;
          J = ijkRange[3]-ijkRange[2]+1;
          K = ijkRange[5]-ijkRange[4]+1;
          nbNodes = I*J*K;
        }
        int nbElems = (I-1)*(J-1)*(K-1);

        if ( curvilinear ) // read coordinates for all nodes
        {
          if ( isGold )
            geoFile.skip( nbNodes, /*nbPerLine =*/ 1, FLT_WIDTH );
          else
            geoFile.skip( nbNodes * SPACE_DIM, /*nbPerLine =*/ 6, FLT_WIDTH );
        }
        else if ( rectilinear ) // read delta vectors with non-regular spacing 
        {
          geoFile.skip( I + J + K, /*nbPerLine =*/ 1, FLT_WIDTH );
        }
        else // uniform: read grid origine and delta vectors for regular spacing grid
        {
          geoFile.skip( 6, /*nbPerLine =*/ 1, FLT_WIDTH );
        }

        // iblanks
        if ( iblanked ) {
          if ( isGold )
            geoFile.skip( nbNodes, /*nbPerLine =*/ 1, INT_WIDTH_GOLD);
          else
            geoFile.skip( nbNodes, /*nbPerLine =*/ 10, INT_WIDTH_6 );
        }
        // ghosts
        if ( with_ghost ) {
          geoFile.getWord(); // "ghost_flags"
          geoFile.skip( nbElems, /*nbPerLine =*/ 1, INT_WIDTH_GOLD);
        }
        // node ids
        if ( haveNodeIds && geoFile.lookAt( "node_ids" )) {
          geoFile.getWord(); // "node_ids"
          geoFile.skip( nbNodes, /*nbPerLine =*/ 1, INT_WIDTH_GOLD);
        }
        // element ids
        if ( haveElemIds && geoFile.lookAt( "element_ids" ) ) {
          geoFile.getWord(); // "element_ids"
          geoFile.skip( nbElems, /*nbPerLine =*/ 1, INT_WIDTH_GOLD);
        }
      }
      else if ( word == "extents" ) {
        geoFile.getLine(); geoFile.getLine(); geoFile.getLine();// 3 x 2E12.5
      }
      else
      {
        throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Unexpected word: " << word));
      }
    }
  }
  return nbParts;
}

//================================================================================
/*!
 * \brief count number of parts in EnSight geometry file
 */
//================================================================================

03019 int ENSIGHT_MESH_RDONLY_DRIVER::countPartsBinary(_BinaryFileReader& geoFile,
                                                 const bool         isSingleFileMode)
{
  const char * LOC ="ENSIGHT_MESH_RDONLY_DRIVER::countPartsBinary() : ";

  if ( geoFile.getPosition() == 0 ) {
    TStrOwner format( geoFile.getLine() ); // "C|Fortran Binary"
    if ( !contains( "C Binary", format )) {
      if ( contains( "Fortran Binary", format ))
        throw(MEDEXCEPTION(STRING(LOC) << "Fortran Binary format not supported"));
      else
        throw(MEDEXCEPTION(STRING(LOC) << "unexpected line: \n" << format.myValues));
    }
  }

  if ( isSingleFileMode ) {
    while (1) {
      TStrOwner line( geoFile.getLine() );
      if ( isTimeStepBeginning( line.myValues ))
        break;
    }
  }

  // 2 description lines
  // ----------------------
  geoFile.skip( 2 * MAX_LINE_LENGTH );

  // read "node|element id <off|given|assign|ignore>"
  bool haveNodeIds, haveElemIds;
  {
    TStrOwner nodeIds( geoFile.getLine() );
    TStrOwner elemIds( geoFile.getLine() );

    haveNodeIds = ( contains( "given", nodeIds ) || contains( "ignore", nodeIds ) );
    haveElemIds = ( contains( "given", elemIds ) || contains( "ignore", elemIds ) );
  }

  int nbParts = 0; // the result
  bool isGold = true;

  while ( !geoFile.eof() )
  {
    TStrOwner line( geoFile.getLine() );
    if ( isSingleFileMode && isTimeStepEnd( line.myValues ))
      break;
    string word, restLine;
    TStrTool::split( line.myValues, word, restLine );

    const TEnSightElemType & partType = getEnSightType( word );
    if ( partType._medType != MED_ALL_ELEMENTS )
    {
      //  Unstructured element type encounters
      // --------------------------------------
      int      nbElems = *TIntOwner( geoFile.getInt(1) ); // ne
      int  nbElemNodes = partType._medType % 100;

      // read element ids
      if ( haveElemIds )
        geoFile.skip( nbElems * sizeof(int) ); // id_e

      int nbNodes = nbElems * nbElemNodes;
      if ( partType._name == "nsided" ) // polygons
      {
        TIntOwner nbNodesInFace( geoFile.getInt( nbElems ));
        nbNodes = std::accumulate( nbNodesInFace.myValues, nbNodesInFace.myValues + nbElems, 0 );
      }
      else if ( partType._name == "nfaced" ) // polyhedrons
      {
        TIntOwner nbElemFaces( geoFile.getInt( nbElems ));
        int nbFaces = accumulate( nbElemFaces.myValues, nbElemFaces.myValues + nbElems, 0 );
        TIntOwner nbNodesInFace( geoFile.getInt( nbFaces ));
        nbNodes = std::accumulate( nbNodesInFace.myValues, nbNodesInFace.myValues + nbFaces, 0 );
      }
      geoFile.skip( nbNodes * sizeof(int) );
    }
    else if ( word == "coordinates" )
    {
      if ( nbParts == 0 )
        isGold = false;
      int nbNodes = *TIntOwner( geoFile.getInt(1) ); // nn

      // node ids
      if ( haveNodeIds )
        geoFile.skip( nbNodes * sizeof(int) ); // id_n

      // coordinates
      geoFile.skip( nbNodes * SPACE_DIM * sizeof(int) );
    }
    else if ( word == "part" )
    {
      ++nbParts;
      if ( isGold ) geoFile.skip(sizeof(int)); // part #

      geoFile.skip(MAX_LINE_LENGTH); // description line
    }
    else if ( word == "block" )
    {
      // Structured type
      // ------------------
      bool rectilinear = ( restLine.find( "rectilinear" ) != restLine.npos );
      bool uniform     = ( restLine.find( "uniform" )     != restLine.npos );
      bool curvilinear = ( !rectilinear && !uniform );
      bool iblanked    = ( restLine.find( "iblanked" )    != restLine.npos );
      bool with_ghost  = ( restLine.find( "with_ghost" )  != restLine.npos );
      bool range       = ( restLine.find( "range" )       != restLine.npos );

      // dimension
      TIntOwner ijk( geoFile.getInt(3) );
      int I = ijk[0];
      int J = ijk[1];
      int K = ijk[2];
      int NumberOfNodes = I*J*K;
      if ( !NumberOfNodes ) {
        if ( I != 0 && J != 0 && K != 0 )
          throw MEDEXCEPTION( "Need to swap bytes" );
        continue;
      }

      // range
      if ( range ) {
        TIntOwner ijkRange( geoFile.getInt( 6 ));// imin imax jmin jmax kmin kmax
        I = ijkRange[1]-ijkRange[0]+1;
        J = ijkRange[3]-ijkRange[2]+1;
        K = ijkRange[5]-ijkRange[4]+1;
        NumberOfNodes = I*J*K;
      }
      int nbElems = (I-1)*(J-1)*(K-1);

      if ( curvilinear ) // read coordinates for all nodes
      {
        geoFile.skip( NumberOfNodes * SPACE_DIM * sizeof(float) );
      }
      else if ( rectilinear ) // read delta vectors with non-regular spacing 
      {
        geoFile.skip( (I+J+K) * sizeof(float) );
      }
      else // uniform: read grid origine and delta vectors for regular spacing grid
      {
        geoFile.skip( 6 * sizeof(float) );
      }

      // iblanks
      if ( iblanked )
        geoFile.skip( NumberOfNodes * sizeof(int) );
      // ghosts
      if ( with_ghost ) {
        geoFile.skip( MAX_LINE_LENGTH ); // "ghost_flags"
        geoFile.skip( nbElems * sizeof(int) );
      }
      // node ids
      if ( haveNodeIds && isGold && !geoFile.eof()  ) {
        TStrOwner nextLine( geoFile.getLine() ); // "node_ids"
        if ( contains( "node_ids", nextLine ) )
          geoFile.skip( NumberOfNodes * sizeof(int) );
        else
          geoFile.skip( -MAX_LINE_LENGTH );
      }
      // element ids
      if ( haveElemIds && isGold && !geoFile.eof() ) {
        TStrOwner nextLine( geoFile.getLine() ); // "element_ids"
        if ( contains( "element_ids", nextLine ) )
          geoFile.skip( nbElems * sizeof(int) );
        else
          geoFile.skip( -MAX_LINE_LENGTH );
      }
    }
    else if ( word == "extents" )
    {
      geoFile.skip( 6 * sizeof(float) );
    }
    else
    {
      throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Unexpected word: " << word ));
    }
  } // while ( !geoFile.eof() )

  return nbParts;
}

GROUP* ENSIGHT_MESH_RDONLY_DRIVER::makeGroup( _groupe&     grp,
                                              _InterMed & imed)
{
  //const char* LOC = "ENSIGHT_MESH_RDONLY_DRIVER::makeGroup(): error";

  // prevent creation of other groups but only this one
  for (size_t i=0; i < imed.groupes.size(); ++i)
    imed.groupes[i].nom.clear();

  // let _intermediateMED create a GROUP from grp
  grp.medGroup = 0; // the new GROUP should appear in grp.medGroup
  grp.nom = "TMP";
  vector<GROUP *> tmp;
  imed.getGroups( tmp, tmp, tmp, tmp, imed._medMesh );
  if ( !grp.medGroup )
    throw MEDEXCEPTION(LOCALIZED("Can't create a GROUP from _groupe"));

  grp.medGroup->setName(""); // to let a caller set a proper name
  grp.nom = "";

  // find pre-existing equal _groupe
  _groupe * equalGroupe = 0;
  for (unsigned int i=0; i < imed.groupes.size() && !equalGroupe; ++i) {
    _groupe& g = imed.groupes[i];
    if ( &g != &grp && g.medGroup && g.medGroup->deepCompare( *grp.medGroup ))
      equalGroupe = & g;
  }
  if ( equalGroupe ) {
    delete grp.medGroup;
    grp.medGroup = equalGroupe->medGroup;
  }
  else { // new unique group

    if ( grp.medGroup->isOnAllElements() ) // on all elems
      grp.medGroup->setName( string("SupportOnAll_")+entNames[ grp.medGroup->getEntity() ] );

    // add a new group to mesh
    if ( !imed._isOwnMedMesh ) {
      vector<GROUP*> * groups = 0;
      switch ( grp.medGroup->getEntity() ) {
      case MED_CELL: groups = & imed._medMesh->_groupCell; break;
      case MED_FACE: groups = & imed._medMesh->_groupFace; break;
      case MED_EDGE: groups = & imed._medMesh->_groupEdge; break;
      case MED_NODE: groups = & imed._medMesh->_groupNode; break;
      default:;
      }
      if ( groups ) {
        groups->resize( groups->size() + 1 );
        groups->at( groups->size() - 1) = grp.medGroup;
      }
    }
  }
  return grp.medGroup;
}

Generated by  Doxygen 1.6.0   Back to index