Salome HOME
Copyright update 2022
[modules/smesh.git] / src / SMESH / MG_ADAPT.cxx
index 64030554123fd51a5d62048d71994a6d79ac317b..739394b78da3bbc568a59b59d5f180f5c9f8b25d 100644 (file)
@@ -1,7 +1,4 @@
-// Copyright (C) 2007-2020  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
+// Copyright (C) 2020-2022  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-// file : MG_ADAPT.cxx
+//
 
 #include "MG_ADAPT.hxx"
 
-#include "MeshFormatReader.hxx"
-#include "MeshFormatWriter.hxx"
-#include "MEDFileMesh.hxx"
-#include "MCAuto.hxx"
-#include "MEDFileData.hxx"
-#include "MEDFileField.hxx"
-#include "MEDCouplingFieldDouble.hxx"
-
-#include <utilities.h>
-#include <iostream>
-#include <unistd.h>
-#include <TCollection_AsciiString.hxx>
-#include <cstring>
-#include <cstdlib>
-#include <boost/filesystem.hpp>
+#include <DriverGMF_Read.hxx>
+#include <SMESH_Comment.hxx>
+#include <SMESH_File.hxx>
+#include <SMESH_MGLicenseKeyGen.hxx>
+#include <SMESH_TypeDefs.hxx>
+
+#include <MEDFileData.hxx>
+#include <MEDFileField.hxx>
+#include <MEDFileMesh.hxx>
+#include <MeshFormatReader.hxx>
+#include <MeshFormatWriter.hxx>
+
+#include <Utils_SALOME_Exception.hxx>
+#include <Basics_Utils.hxx>
+#include "SMESH_TypeDefs.hxx"
+
+#ifndef WIN32
+#include <unistd.h> // getpid()
+#else
+#include <process.h>
+#endif
+#include <fcntl.h>
+#include <array>
+#include <memory>   // unique_ptr
+
+typedef SMESH_Comment ToComment;
 
 using namespace MG_ADAPT;
 static std::string removeFile(std::string fileName, int& notOk)
@@ -44,25 +52,121 @@ static std::string removeFile(std::string fileName, int& notOk)
   std::string errStr;
   notOk = std::remove(fileName.c_str());
   if (notOk) errStr = ToComment("\n error while removing file : ") << fileName;
-        else errStr = ToComment("\n file : ") << fileName << " succesfully deleted! \n ";
+  else       errStr = ToComment("\n file : ") << fileName << " succesfully deleted! \n ";
 
   return errStr;
 }
-std::string remove_extension(const std::string& filename) {
+std::string MG_ADAPT::remove_extension(const std::string& filename)
+{
   size_t lastdot = filename.find_last_of(".");
   if (lastdot == std::string::npos) return filename;
   return filename.substr(0, lastdot);
 }
 namespace
 {
-struct GET_DEFAULT // struct used to get default value from GetOptionValue()
-{
-  bool isDefault;
-  operator bool* () {
-      return &isDefault;
+
+  bool isFileExist( const std::string& fName )
+  {
+    return SMESH_File( fName ).exists();
+  }
+
+  // =======================================================================
+  med_idt openMedFile(const std::string aFile)
+  // =======================================================================
+  // renvoie le medId associe au fichier Med apres ouverture
+  {
+    med_idt medIdt = MEDfileOpen(aFile.c_str(),MED_ACC_RDONLY);
+    if (medIdt <0)
+    {
+      THROW_SALOME_EXCEPTION("\nThe med file " << aFile << " cannot be opened.\n");
+    }
+    return medIdt;
   }
-};
-}
+
+  // =======================================================================
+  void getTimeStepInfos(std::string aFile, med_int& numdt, med_int& numit, std::string fieldName)
+  // =======================================================================
+  {
+    // Il faut voir si plusieurs maillages
+
+    herr_t erreur = 0 ;
+    med_idt medIdt ;
+
+    // Ouverture du fichier
+    //~SCRUTE(aFile.toStdString());
+    medIdt = openMedFile(aFile);
+    if ( medIdt < 0 ) return ;
+    // Lecture du nombre de champs
+    med_int ncha = MEDnField(medIdt) ;
+    if (ncha < 1 )
+    {
+      //~addMessage( ToComment(" error: there is no field in  ") << aFile, /*fatal=*/true );
+      return;
+    }
+    // Lecture des caracteristiques du champs
+
+    //       Lecture du type du champ, des noms des composantes et du nom de l'unite
+    char nomcha  [MED_NAME_SIZE+1];
+    strcpy(nomcha, fieldName.c_str());
+    //       Lecture du nombre de composantes
+    med_int ncomp = MEDfieldnComponentByName(medIdt, nomcha);
+    char meshname[MED_NAME_SIZE+1];
+    char * comp = (char*) malloc(ncomp*MED_SNAME_SIZE+1);
+    char * unit = (char*) malloc(ncomp*MED_SNAME_SIZE+1);
+    char dtunit[MED_SNAME_SIZE+1];
+    med_bool local;
+    med_field_type typcha;
+    med_int nbofcstp;
+    erreur =  MEDfieldInfoByName (medIdt, nomcha, meshname,&local,&typcha,comp,unit,dtunit, &nbofcstp);
+    free(comp);
+    free(unit);
+    if ( erreur < 0 )
+    {
+      //~addMessage( ToComment(" error: error while reading field  ") << nomcha << " in file " << aFile , /*fatal=*/true );
+      return;
+    }
+
+    med_float dt;
+    med_int tmp_numdt, tmp_numit;
+
+    //~med_int step = data->myUseLastTimeStep ? nbofcstp : data->myTimeStep+1;
+    //~myPrint("step ", step);
+    erreur = MEDfieldComputingStepInfo ( medIdt, nomcha, 1, &numdt, &numit, &dt );
+    for( int step = 1; step <= nbofcstp; step++ )
+    {
+      erreur = MEDfieldComputingStepInfo ( medIdt, nomcha, step, &tmp_numdt, &tmp_numit, &dt );
+      if(tmp_numdt > numdt)
+      {
+        numdt = tmp_numdt;
+        numit = tmp_numit;
+      }
+    }
+    if ( erreur < 0 )
+    {
+      //~addMessage( ToComment(" error: error while reading field ") << nomcha << "step (numdt, numit) = " <<"("<< numdt<< ", "
+      //numit<< ")" <<" in file " << aFile , /*fatal=*/true );
+      return;
+    }
+
+    // Fermeture du fichier
+    if ( medIdt > 0 ) MEDfileClose(medIdt);
+
+  }
+
+  struct GET_DEFAULT // struct used to get default value from GetOptionValue()
+  {
+    bool isDefault;
+    operator bool* () {
+      return &isDefault;
+    }
+  };
+
+  class outFileStream : public std::ofstream{
+  public:
+    ~outFileStream(){close();} //to close file at dtor
+  };
+
+} // anonymous namespace
 
 //----------------------------------------------------------------------------------------
 MgAdapt::MgAdapt()
@@ -129,7 +233,7 @@ MgAdapt::~MgAdapt()
 void MgAdapt::buildModel()
 {
 
-  const char* boolOptionNames[] = { "compute_ridges",                          // yes
+  const char* boolOptionNames[] = { "compute_ridges", // yes
                                     "" // mark of end
                                   };
   // const char* intOptionNames[] = { "max_number_of_errors_printed", // 1
@@ -139,8 +243,8 @@ void MgAdapt::buildModel()
   const char* doubleOptionNames[] = { "max_memory",  // 0
                                       "" // mark of end
                                     };
-  const char* charOptionNames[] = { "components",                    // "yes"
-                                    "adaptation",            // both
+  const char* charOptionNames[] = { "components",  // "yes"
+                                    "adaptation",  // both
                                     "" // mark of end
                                   };
 
@@ -167,10 +271,10 @@ void MgAdapt::buildModel()
 
   // default values to be used while MG-Adapt
 
-  _defaultOptionValues["adaptation"                         ] = "both";
-  _defaultOptionValues["components"                         ] = "outside components";
-  _defaultOptionValues["compute_ridges"                     ] = "yes";
-  _defaultOptionValues["max_memory"                         ] = ToComment(defaultMaximumMemory());
+  _defaultOptionValues["adaptation"    ] = "both";
+  _defaultOptionValues["components"    ] = "outside components";
+  _defaultOptionValues["compute_ridges"] = "yes";
+  _defaultOptionValues["max_memory"    ] = ToComment(defaultMaximumMemory());
 }
 
 //=============================================================================
@@ -219,9 +323,17 @@ MgAdaptHypothesisData* MgAdapt::getData() const
 }
 void MgAdapt::setMedFileIn(std::string fileName)
 {
-  medFileIn  = fileName;
-  if (medFileOut == "") // default MED file Out
-    medFileOut = remove_extension( fileName )+ ".adapt.med";
+  if ( isFileExist( fileName ))
+  {
+    medFileIn = fileName;
+
+    if (medFileOut == "") // default MED file Out
+      medFileOut = remove_extension( fileName )+ ".adapt.med";
+  }
+  else
+  {
+    THROW_SALOME_EXCEPTION("\nThe file "<< fileName <<" does not exist.\n");
+  }
 }
 
 std::string MgAdapt::getMedFileIn()
@@ -233,7 +345,6 @@ void MgAdapt::setMedFileOut(std::string fileOut)
 {
   medFileOut = fileOut;
 }
-
 std::string MgAdapt::getMedFileOut()
 {
   return medFileOut;
@@ -363,7 +474,14 @@ bool MgAdapt::getRemoveOnSuccess()
 }
 void MgAdapt::setSizeMapFile(std::string mapFile)
 {
-  sizeMapFile = mapFile;
+  if ( mapFile == "" || isFileExist(mapFile) )
+  {
+    sizeMapFile = mapFile;
+  }
+  else
+  {
+    THROW_SALOME_EXCEPTION("\nThe file "<< mapFile <<" does not exist.\n");
+  }
 }
 std::string MgAdapt::getSizeMapFile()
 {
@@ -428,7 +546,6 @@ bool MgAdapt::getPrintLogInFile()
   return printLogInFile;
 }
 
-
 bool MgAdapt::setAll()
 {
 
@@ -500,8 +617,9 @@ void MgAdapt::checkDirPath(std::string& dirPath)
 //=============================================================================
 void MgAdapt::setOptionValue(const std::string& optionName,
                              const std::string& optionValue)
-throw (std::invalid_argument)
 {
+//   INFOS("setOptionValue");
+//   std::cout << "optionName: " << optionName << ", optionValue: " << optionValue << std::endl;
   TOptionValues::iterator op_val = _option2value.find(optionName);
   if (op_val == _option2value.end())
   {
@@ -512,13 +630,12 @@ throw (std::invalid_argument)
 
   if (op_val->second != optionValue)
   {
-
     std::string lowerOptionValue = toLowerStr(optionValue);
     const char* ptr = lowerOptionValue.c_str();
     // strip white spaces
     while (ptr[0] == ' ')
       ptr++;
-    int i = strlen(ptr);
+    size_t i = strlen(ptr);
     while (i != 0 && ptr[i - 1] == ' ')
       i--;
     // check value type
@@ -559,19 +676,21 @@ throw (std::invalid_argument)
       throw std::invalid_argument(msg);
     }
     std::string value( ptr, i );
+//     std::cout << "==> value: " << value << std::endl;
     if ( _defaultOptionValues[ optionName ] == value ) value.clear();
 
+//     std::cout << "==> value: " << value << std::endl;
     op_val->second = value;
-
   }
 }
 //=============================================================================
 //! Return option value. If isDefault provided, it can be a default value,
 //  then *isDefault == true. If isDefault is not provided, the value will be
 //  empty if it equals a default one.
-std::string MgAdapt::getOptionValue(const std::string& optionName, bool*              isDefault) const
-throw (std::invalid_argument)
+std::string MgAdapt::getOptionValue(const std::string& optionName, bool* isDefault) const
 {
+//   INFOS("getOptionValue");
+//   std::cout << "optionName: " << optionName << ", isDefault: " << isDefault << std::endl;
   TOptionValues::const_iterator op_val = _option2value.find(optionName);
   if (op_val == _option2value.end())
   {
@@ -590,6 +709,8 @@ throw (std::invalid_argument)
     op_val = _defaultOptionValues.find( optionName );
     if (op_val != _defaultOptionValues.end()) val = op_val->second;
   }
+//   std::cout << "==> val: " << val << std::endl;
+
   return val;
 }
 //================================================================================
@@ -599,7 +720,6 @@ throw (std::invalid_argument)
 //================================================================================
 
 double MgAdapt::toDbl(const std::string& str, bool* isOk )
-throw (std::invalid_argument)
 {
   if ( str.empty() ) throw std::invalid_argument("Empty value provided");
 
@@ -625,7 +745,7 @@ std::string MgAdapt::toLowerStr(const std::string& str)
 {
   std::string s = str;
   for ( size_t i = 0; i <= s.size(); ++i )
-    s[i] = tolower( s[i] );
+    s[i] = (char) tolower( s[i] );
   return s;
 }
 //================================================================================
@@ -635,13 +755,12 @@ std::string MgAdapt::toLowerStr(const std::string& str)
 //================================================================================
 
 bool MgAdapt::toBool(const std::string& str, bool* isOk )
-throw (std::invalid_argument)
 {
   std::string s = str;
   if ( isOk ) *isOk = true;
 
   for ( size_t i = 0; i <= s.size(); ++i )
-    s[i] = tolower( s[i] );
+    s[i] = (char) tolower( s[i] );
 
   if ( s == "1" || s == "true" || s == "active" || s == "yes" )
     return true;
@@ -665,7 +784,6 @@ throw (std::invalid_argument)
 //================================================================================
 
 int MgAdapt::toInt(const std::string& str, bool* isOk )
-throw (std::invalid_argument)
 {
   if ( str.empty() ) throw std::invalid_argument("Empty value provided");
 
@@ -698,7 +816,7 @@ bool MgAdapt::hasOptionDefined( const std::string& optionName ) const
 }
 //================================================================================
 /*!
- * \brief Return command to run MG-Tetra mesher excluding file prefix (-f)
+ * \brief Return command to run MG-Adapt mesher excluding file prefix (-f)
  */
 //================================================================================
 
@@ -707,11 +825,11 @@ std::string MgAdapt::getCommandToRun(MgAdapt* hyp)
   return hyp ? hyp->getCommandToRun() : ToComment("error with hypothesis!");
 }
 
-
-
 int MgAdapt::compute(std::string& errStr)
 {
   std::string cmd = getCommandToRun();
+//   std::cout << cmd << std::endl;
+
   int err = 0;
   execCmd( cmd.c_str(), err ); // run
 
@@ -719,6 +837,11 @@ int MgAdapt::compute(std::string& errStr)
   {
     errStr = ToComment("system(mg-adapt.exe ...) command failed with error: ") << strerror( errno );
   }
+  else if ( !isFileExist( meshFormatOutputMesh ))
+  {
+    errStr = ToComment(" failed to find file ") << meshFormatOutputMesh
+                                                << " output from MG-Adapt run";
+  }
   else
   {
     convertMeshFile(meshFormatOutputMesh, solFormatOutput);
@@ -732,11 +855,11 @@ void MgAdapt::execCmd( const char* cmd, int& err)
   err = 1;
   std::array <char, 128> buffer;
   std::streambuf* buf;
-outFileStream fileStream;
+  outFileStream fileStream;
   if (printLogInFile)
   {
-  fileStream.open(logFile);
-  buf = fileStream.rdbuf();
+    fileStream.open(logFile);
+    buf = fileStream.rdbuf();
   }
   else
   {
@@ -744,7 +867,19 @@ outFileStream fileStream;
   }
   std::ostream logStream(buf);
 
+
+#if defined(WIN32)
+#  if defined(UNICODE)
+  const wchar_t * aCmd = Kernel_Utils::utf8_decode(cmd);
+  SMESHUtils::ArrayDeleter<const wchar_t> deleter( aCmd );
+  std::unique_ptr <FILE, decltype(&_pclose)> pipe(_wpopen(aCmd, O_RDONLY), _pclose );
+#  else
+  std::unique_ptr <FILE, decltype(&_pclose)> pipe(_popen(cmd, "r"), _pclose );
+#  endif
+#else
   std::unique_ptr <FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose );
+#endif
+
   if(!pipe)
   {
     throw std::runtime_error("popen() failed!");
@@ -831,23 +966,19 @@ std::string MgAdapt::getCommandToRun()
   }
   //~else
   //~{
-      //~// constant value TODO
+  //~// constant value TODO
   //~}
-  /* sizemap file is not adapted in case of only surface adaptation see MeshGems docs */
-  std::string adapOp   = "adaptation";
-  std::string adpOpVal = getOptionValue(adapOp);
-  std::string surfaceAdapt = "surface";
-  if(surfaceAdapt != adpOpVal )
+  // Check coherence between mesh dimension and option fo adaptation
+  checkDimensionOptionAdaptation();
+
+  //   sizemap file is written only if level is higher than 3
+  if ( verbosityLevel > 3)
   {
     std::string solFileOut = getFileName()+".sol";
     cmd+= " --write_sizemap "+ solFileOut;
     solFormatOutput.push_back(solFileOut);
     tmpFilesToBeDeleted.push_back(solFileOut);
   }
-  if (verbosityLevel != defaultVerboseLevel())
-  {
-    cmd+= " --verbose "+ ToComment(verbosityLevel);
-  }
 
   std::string option, value;
   bool isDefault;
@@ -861,45 +992,62 @@ std::string MgAdapt::getCommandToRun()
       value = getOptionValue( option, &isDefault );
 
       if ( isDefault )
-          continue;
+        continue;
       if ( value.empty() )//value == NoValue() )
       {
         if ( _defaultOptionValues.count( option ))
-            continue; // non-custom option with no value
+          continue; // non-custom option with no value
         //value.clear();
       }
       if ( strncmp( "no", option.c_str(), 2 ) == 0 ) // options w/o values: --no_*
       {
         if ( !value.empty() && toBool( value ) == false )
-            continue;
+          continue;
         value.clear();
       }
       if ( option[0] != '-' )
         cmd += " --";
       else
         cmd += " ";
+      //       std::cout << "--- option: '" << option << ", value: '" << value <<"'"<< std::endl;
       cmd += option + " " + value;
     }
   }
-    //~}
-//~cmd+= " >"
+
+  // Verbosity Level
+  if (verbosityLevel != defaultVerboseLevel())
+  {
+    cmd+= " --verbose "+ ToComment(verbosityLevel);
+  }
+  // get license key
+  {
+    smIdType nbVertex, nbEdge, nbFace, nbVol;
+    DriverGMF_Read gmfReader;
+    gmfReader.SetFile( meshIn );
+    gmfReader.GetMeshInfo( nbVertex, nbEdge, nbFace, nbVol );
+
+    std::string errorTxt;
+    std::string key = SMESHUtils_MGLicenseKeyGen::GetKey( meshIn,
+                                                          FromSmIdType<int>( nbVertex ),
+                                                          FromSmIdType<int>( nbEdge ),
+                                                          FromSmIdType<int>( nbFace ),
+                                                          FromSmIdType<int>( nbVol ),
+                                                          errorTxt );
+    if ( key.empty() )
+      return ToComment( "Problem with library SalomeMeshGemsKeyGenerator: " + errorTxt );
+
+    cmd += " --key " + key;
+  }
+
 #ifdef WIN32
-    cmd += " < NUL";
+  cmd += " < NUL";
 #endif
+  //   std::cout << "--- cmd :"<< std::endl;
+  //   std::cout << cmd << std::endl;
 
   return cmd;
 }
 
-bool MgAdapt::isFileExist(const std::string& fName)
-{
-
-  if ( fName.empty() ) return false;
-
-  boost::system::error_code err;
-  bool res = boost::filesystem::exists( fName, err );
-
-  return err ? false : res;
-}
 //=======================================================================
 //function : defaultMaximumMemory
 //=======================================================================
@@ -928,7 +1076,7 @@ double MgAdapt::defaultMaximumMemory()
   if ( err == 0 )
   {
     long ramMB = si.totalram * si.mem_unit / 1024 / 1024;
-    return ( 0.7 * ramMB );
+    return ( 0.7 * double( ramMB ));
   }
 #endif
   return 1024;
@@ -940,21 +1088,23 @@ double MgAdapt::defaultMaximumMemory()
 
 std::string MgAdapt::defaultWorkingDirectory()
 {
-  TCollection_AsciiString aTmpDir;
+  std::string aTmpDir;
 
   char *Tmp_dir = getenv("SALOME_TMP_DIR");
   if(Tmp_dir != NULL)
   {
     aTmpDir = Tmp_dir;
   }
-  else {
+
+  if ( ! isFileExist( aTmpDir ))
+  {
 #ifdef WIN32
-    aTmpDir = TCollection_AsciiString("C:\\");
+    aTmpDir = "C:\\";
 #else
-    aTmpDir = TCollection_AsciiString("/tmp/");
+    aTmpDir = "/tmp/";
 #endif
   }
-  return aTmpDir.ToCString();
+  return aTmpDir;
 }
 //================================================================================
 /*!
@@ -972,13 +1122,17 @@ std::string MgAdapt::getFileName() const
   if(lastChar != '/') aTmpDir+='/';
 #endif
 
-  TCollection_AsciiString aGenericName = (char*)aTmpDir.c_str();
-  aGenericName += "MgAdapt_";
-  aGenericName += getpid();
-  aGenericName += "_";
-  aGenericName += Abs((Standard_Integer)(long) aGenericName.ToCString());
+  SMESH_Comment aGenericName( aTmpDir );
+  aGenericName << "MgAdapt_";
+#ifndef WIN32
+  aGenericName << getpid();
+#else
+aGenericName << _getpid();
+#endif
+  aGenericName << "_";
+  aGenericName << std::abs((int)(long) aGenericName.data());
 
-  return aGenericName.ToCString();
+  return aGenericName;
 }
 //=======================================================================
 //function : defaultLogFile
@@ -1127,6 +1281,98 @@ void MgAdapt::copyMgAdaptHypothesisData( const MgAdaptHypothesisData* from)
   data->myVerboseLevel = from->myVerboseLevel;
 }
 
+std::vector<std::string> MgAdapt::getListFieldsNames(std::string fileIn)
+{
+  MEDCoupling::MCAuto<MEDCoupling::MEDFileData> mfd = MEDCoupling::MEDFileData::New(fileIn);
+  std::vector<std::string> listFieldsNames(mfd->getFields()->getFieldsNames());
+  return listFieldsNames ;
+}
+
+void MgAdapt::checkDimensionOptionAdaptation()
+{
+  // Quand le maillage est 3D, tout est possible
+  // Quand le maillage est 2D, il faut 'surface' sauf si carte de fonds 3D
+  MEDCoupling::MCAuto<MEDCoupling::MEDFileData> mfd = MEDCoupling::MEDFileData::New(medFileIn);
+  int meshdim = mfd->getMeshes()->getMeshAtPos(0)->getMeshDimension() ;
+//   std::cout << "meshdim = " << meshdim << std::endl;
+
+  if ( meshdim == 2 )
+  {
+    std::string optionName   = "adaptation";
+    std::string optionValue = getOptionValue(optionName);
+//     std::cout << "optionValue = '" << optionValue <<"'"<< std::endl;
+    bool a_tester = false ;
+    // carte locale ou constante : impĂ©ratif d'avoir "surface"
+    if ( useLocalMap || useConstantValue) a_tester = true ;
+    // carte de fond : impĂ©ratif d'avoir "surface" si le fonds est aussi 2D
+    else
+    {
+      MEDCoupling::MCAuto<MEDCoupling::MEDFileData> mfdbg = MEDCoupling::MEDFileData::New(sizeMapFile);
+      int meshdimbg = mfdbg->getMeshes()->getMeshAtPos(0)->getMeshDimension() ;
+//       std::cout << "meshdimbg = " << meshdimbg << std::endl;
+      if ( meshdimbg == 2 ) a_tester = true ;
+    }
+    if ( a_tester )
+    {
+      if ( optionValue == "" ) setOptionValue (optionName, "surface");
+      else
+      {
+        if ( optionValue != "surface" )
+        {
+          THROW_SALOME_EXCEPTION("Mesh dimension is 2; the option should be 'surface'"
+                                 " instead of '" << optionValue << "'.");
+        }
+      }
+    }
+  }
+}
+
+void MgAdapt::checkFieldName(std::string fileIn)
+{
+  bool ret = false ;
+  std::vector<std::string> listFieldsNames = getListFieldsNames(fileIn);
+  std::size_t jaux(listFieldsNames.size());
+  for(std::size_t j=0;j<jaux;j++)
+  {
+    if ( fieldName == listFieldsNames[j] )
+    {
+      ret = true ;
+      break ;
+    }
+  }
+  if ( ! ret )
+  {
+    std::cout << "Available field names:" << std::endl;
+    for(std::size_t j=0;j<jaux;j++)
+    { std::cout << listFieldsNames[j] << std::endl;}
+    THROW_SALOME_EXCEPTION( "Field " << fieldName << " is not found.");
+  }
+}
+
+void MgAdapt::checkTimeStepRank(std::string fileIn)
+{
+  bool ret = false ;
+  MEDCoupling::MCAuto<MEDCoupling::MEDFileData> mfd = MEDCoupling::MEDFileData::New(fileIn);
+  MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeFieldMultiTS> fts( mfd->getFields()->getFieldWithName(fieldName) );
+  std::vector<double> timevalue;
+  std::vector< std::pair<int,int> > timesteprank = fts->getTimeSteps(timevalue);
+  std::size_t jaux(timesteprank.size());
+  for(std::size_t j=0;j<jaux;j++)
+  {
+    if ( ( timeStep == timesteprank[j].first ) & ( rank == timesteprank[j].second ) )
+    {
+      ret = true ;
+      break ;
+    }
+  }
+  if ( ! ret )
+  {
+    std::cout << "Available (Time step, Rank):" << std::endl;
+    for(std::size_t j=0;j<jaux;j++)
+    { std::cout << "(Time step = " << timesteprank[j].first << ", Rank = " << timesteprank[j].second << ")" << std::endl;}
+    THROW_SALOME_EXCEPTION("(Time step = " << timeStep << ", Rank = " << rank << ") is not found.");
+  }
+}
 
 void MgAdapt::convertMedFile(std::string& meshFormatMeshFileName, std::string& solFormatFieldFileName, std::string& meshFormatsizeMapFile)
 {
@@ -1136,7 +1382,7 @@ void MgAdapt::convertMedFile(std::string& meshFormatMeshFileName, std::string& s
   MEDCoupling::MEDFileMeshes* meshes = mfd->getMeshes();
   MEDCoupling::MEDFileMesh* fileMesh = meshes->getMeshAtPos(0); // ok only one mesh in file!
   if (meshNameOut =="")
-      meshNameOut = fileMesh->getName();
+    meshNameOut = fileMesh->getName();
   storeGroupsAndFams(fileMesh);
 
   MEDCoupling::MCAuto<MEDCoupling::MEDFileFields> fields = MEDCoupling::MEDFileFields::New();
@@ -1146,16 +1392,29 @@ void MgAdapt::convertMedFile(std::string& meshFormatMeshFileName, std::string& s
 
   if (useBackgroundMap)
   {
+    checkFieldName(sizeMapFile) ;
+    checkTimeStepRank(sizeMapFile) ;
     meshFormatsizeMapFile = getFileName();
     meshFormatsizeMapFile += ".mesh";
     buildBackGroundMeshAndSolFiles(fieldFileNames, meshFormatsizeMapFile);
   }
   else if(useLocalMap)
   {
-    MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeFieldMultiTS> fts = dynamic_cast<MEDCoupling::MEDFileFieldMultiTS *>( mfd->getFields()->getFieldWithName(fieldName) );
+    checkFieldName(medFileIn) ;
+    checkTimeStepRank(medFileIn) ;
+    MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeFieldMultiTS> fts( mfd->getFields()->getFieldWithName(fieldName) );
     MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeField1TS> f = fts->getTimeStep(timeStep, rank);
-    MEDCoupling::MCAuto<MEDCoupling::MEDFileFieldMultiTS> tmFts = MEDCoupling::MEDFileFieldMultiTS::New();
-    tmFts->pushBackTimeStep(f);
+    MEDCoupling::MCAuto<MEDCoupling::MEDFileFieldMultiTS> tmFts = MEDCoupling::DynamicCast<MEDCoupling::MEDFileAnyTypeFieldMultiTS,MEDCoupling::MEDFileFieldMultiTS>(fts);
+
+    // if not able to cast to double field, try float field
+    if (!tmFts)
+    {
+      MEDCoupling::MCAuto<MEDCoupling::MEDFileFloatFieldMultiTS>  tmFtsFloat = MEDCoupling::DynamicCast<MEDCoupling::MEDFileAnyTypeFieldMultiTS,MEDCoupling::MEDFileFloatFieldMultiTS>(fts);
+      if (!tmFtsFloat)
+        THROW_SALOME_EXCEPTION("\nUnexpected field type.\n");
+      // convert float field to double
+      tmFts = tmFtsFloat->convertToDouble();
+    }
 
     fields->pushField(tmFts);
 
@@ -1211,15 +1470,14 @@ void MgAdapt::storeGroups(MEDCoupling::MEDFileMesh* fileMesh)
 
   for ( ; g2ff != grpFams.end(); ++g2ff )
   {
-    std::string        groupName = g2ff->first;
+    std::string             groupName = g2ff->first;
     std::vector<std::string> famNames = g2ff->second;
 
     if ( famNames.empty() ) continue;
-    std::size_t k = 0;
-    std::vector< mcIdType> famListId;
+    std::vector< int> famListId;
     for ( size_t i = 0; i < famNames.size(); ++i )
     {
-      famListId.push_back( fileMesh->getFamilyId( famNames[i].c_str() ) );
+      famListId.push_back( FromIdType<int>( fileMesh->getFamilyId( famNames[i].c_str() )));
     }
     group grp(groupName, famListId, famNames);
     groupVec.push_back(grp);
@@ -1234,7 +1492,7 @@ void MgAdapt::storefams(MEDCoupling::MEDFileMesh* fileMesh)
   for ( ; f != grpFams.end(); ++f )
   {
     if(!f->second) continue;  // FAMILLE_ZERO
-    family fs(f->first, f->second);
+    family fs(f->first, FromIdType<int>( f->second ));
     famVec.push_back(fs);
   }
 
@@ -1272,14 +1530,14 @@ void MgAdapt::restoreGroups(MEDCoupling::MEDFileMesh* fileMesh) const
   fileMesh->setGroupInfo(info);
 }
 
-void MgAdapt::buildConstantSizeMapSolFile(const std::string& solFormatFieldFileName, const int dim, const int version, const mcIdType nbNodes) const
+void MgAdapt::buildConstantSizeMapSolFile(const std::string& solFormatFieldFileName, const int dim, const int version, const size_t nbNodes) const
 {
   MeshFormat::Localizer loc;
   MeshFormat::MeshFormatParser writer;
   int fileId = writer.GmfOpenMesh( solFormatFieldFileName.c_str(), GmfWrite, version, dim);
   int typTab[] = {GmfSca};
   writer.GmfSetKwd(fileId, MeshFormat::GmfSolAtVertices, (int)nbNodes, 1, typTab);
-  for (mcIdType i = 0; i<nbNodes; i++)
+  for (size_t i = 0; i<nbNodes; i++)
   {
     double valTab[1] = {constantValue};
     writer.GmfSetLin( fileId, MeshFormat::GmfSolAtVertices, valTab);
@@ -1291,8 +1549,8 @@ void MgAdapt::buildBackGroundMeshAndSolFiles(const std::vector<std::string>& fie
 {
   MEDCoupling::MCAuto<MEDCoupling::MEDFileData> tmpMfd = MEDCoupling::MEDFileData::New(sizeMapFile);
   MEDCoupling::MEDFileFields* tmpFields = tmpMfd->getFields();
-  MEDCoupling::MEDFileAnyTypeFieldMultiTS* fts = tmpFields->getFieldWithName(fieldName);
-  MEDCoupling::MCAuto<MEDCoupling::MEDFileFieldMultiTS>  fts1 = dynamic_cast<MEDCoupling::MEDFileFieldMultiTS *>(fts);
+  MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeFieldMultiTS> fts( tmpFields->getFieldWithName(fieldName) );
+  MEDCoupling::MCAuto<MEDCoupling::MEDFileFieldMultiTS>  fts1 = MEDCoupling::DynamicCastSafe<MEDCoupling::MEDFileAnyTypeFieldMultiTS,MEDCoupling::MEDFileFieldMultiTS>(fts);
   MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeField1TS> f = fts1->getTimeStep(timeStep, rank);
   MEDCoupling::MCAuto<MEDCoupling::MEDFileFieldMultiTS> tmFts = MEDCoupling::MEDFileFieldMultiTS::New();
   tmFts->pushBackTimeStep(f);
@@ -1307,104 +1565,20 @@ void MgAdapt::buildBackGroundMeshAndSolFiles(const std::vector<std::string>& fie
   tmpWriter.setMEDFileDS(tmpMfd);
   tmpWriter.write();
 }
-// =======================================================================
-med_idt MgAdapt::openMedFile(const std::string aFile)
-// =======================================================================
-// renvoie le medId associe au fichier Med apres ouverture
-{
-  med_idt medIdt = MEDfileOpen(aFile.c_str(),MED_ACC_RDONLY);
-  if (medIdt <0)
-  {
-    //~addMessage( ToComment(" error: Can't open  ") << aFile, /*fatal=*/true );
-    ;
-  }
-  return medIdt;
-}
 
 MgAdapt::Status MgAdapt::addMessage(const std::string& msg,
-                                  const bool         isFatal/*=false*/)
+                                    const bool         isFatal/*=false*/)
 {
   if ( isFatal )
-    _myErrorMessages.clear(); // warnings are useless if a fatal error encounters
+    _errorMessages.clear(); // warnings are useless if a fatal error encounters
 
-  _myErrorMessages.push_back( msg );
+  _errorMessages.push_back( msg );
 
-//~MESSAGE(msg);
+  //~MESSAGE(msg);
 #ifdef _DEBUG_
   std::cout << msg << std::endl;
 #endif
-  return ( _myStatus = isFatal ? MgAdapt::DRS_FAIL : MgAdapt::DRS_WARN_SKIP_ELEM );
-}
-
-// =======================================================================
-void MgAdapt::getTimeStepInfos(std::string aFile, med_int& numdt, med_int& numit)
-// =======================================================================
-{
-// Il faut voir si plusieurs maillages
-
-  herr_t erreur = 0 ;
-  med_idt medIdt ;
-
-
-  // Ouverture du fichier
-  //~SCRUTE(aFile.toStdString());
-  medIdt = openMedFile(aFile);
-  if ( medIdt < 0 ) return ;
-  // Lecture du nombre de champs
-  med_int ncha = MEDnField(medIdt) ;
-  if (ncha < 1 )
-  {
-    //~addMessage( ToComment(" error: there is no field in  ") << aFile, /*fatal=*/true );
-    return;
-  }
-  // Lecture des caracteristiques du champs
-
-  //       Lecture du type du champ, des noms des composantes et du nom de l'unite
-  char nomcha  [MED_NAME_SIZE+1];
-  strcpy(nomcha, fieldName.c_str());
-//       Lecture du nombre de composantes
-  med_int ncomp = MEDfieldnComponentByName(medIdt, nomcha);
-  char meshname[MED_NAME_SIZE+1];
-  char * comp = (char*) malloc(ncomp*MED_SNAME_SIZE+1);
-  char * unit = (char*) malloc(ncomp*MED_SNAME_SIZE+1);
-  char dtunit[MED_SNAME_SIZE+1];
-  med_bool local;
-  med_field_type typcha;
-  med_int nbofcstp;
-  erreur =  MEDfieldInfoByName (medIdt, nomcha, meshname,&local,&typcha,comp,unit,dtunit, &nbofcstp);
-  free(comp);
-  free(unit);
-  if ( erreur < 0 )
-  {
-      //~addMessage( ToComment(" error: error while reading field  ") << nomcha << " in file " << aFile , /*fatal=*/true );
-    return;
-  }
-
-  med_float dt;
-  med_int tmp_numdt, tmp_numit;
-
-  //~med_int step = data->myUseLastTimeStep ? nbofcstp : data->myTimeStep+1;
-  //~myPrint("step ", step);
-  erreur = MEDfieldComputingStepInfo ( medIdt, nomcha, 1, &numdt, &numit, &dt );
-  for(med_int step = 1; step <= nbofcstp; step++ )
-  {
-    erreur = MEDfieldComputingStepInfo ( medIdt, nomcha, step, &tmp_numdt, &tmp_numit, &dt );
-    if(tmp_numdt > numdt)
-    {
-      numdt = tmp_numdt;
-      numit = tmp_numit;
-    }
-  }
-  if ( erreur < 0 )
-  {
-    //~addMessage( ToComment(" error: error while reading field ") << nomcha << "step (numdt, numit) = " <<"("<< numdt<< ", " \
-    numit<< ")" <<" in file " << aFile , /*fatal=*/true );
-    return;
-  }
-
-  // Fermeture du fichier
-  if ( medIdt > 0 ) MEDfileClose(medIdt);
-
+  return ( _status = isFatal ? MgAdapt::DRS_FAIL : MgAdapt::DRS_WARN_SKIP_ELEM );
 }
 
 void MgAdapt::updateTimeStepRank()
@@ -1421,7 +1595,7 @@ void MgAdapt::updateTimeStepRank()
   else if (myUseLastTimeStep)
   {
     std::string fieldFile = useBackgroundMap ? sizeMapFile : medFileIn;
-    getTimeStepInfos(fieldFile, tmst, arank);
+    getTimeStepInfos(fieldFile, tmst, arank, fieldName);
     setRankTimeStep((int)tmst, (int)arank);
   }
 }