Salome HOME
Merge branch 'master' into gni/adaptation
[modules/smesh.git] / src / SMESH / MG_ADAPT.cxx
index 76934c6a748f170ccaae608175e628c979598438..c3e95da76d5e71a0bb34b567a885b36bca4329fa 100644 (file)
@@ -133,7 +133,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
@@ -143,8 +143,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
                                   };
 
@@ -171,10 +171,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());
 }
 
 //=============================================================================
@@ -527,6 +527,8 @@ 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())
   {
@@ -537,7 +539,6 @@ throw (std::invalid_argument)
 
   if (op_val->second != optionValue)
   {
-
     std::string lowerOptionValue = toLowerStr(optionValue);
     const char* ptr = lowerOptionValue.c_str();
     // strip white spaces
@@ -584,19 +585,22 @@ 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
+std::string MgAdapt::getOptionValue(const std::string& optionName, bool* isDefault) const
 throw (std::invalid_argument)
 {
+//   INFOS("getOptionValue");
+//   std::cout << "optionName: " << optionName << ", isDefault: " << isDefault << std::endl;
   TOptionValues::const_iterator op_val = _option2value.find(optionName);
   if (op_val == _option2value.end())
   {
@@ -615,6 +619,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;
 }
 //================================================================================
@@ -737,6 +743,8 @@ std::string MgAdapt::getCommandToRun(MgAdapt* hyp)
 int MgAdapt::compute(std::string& errStr)
 {
   std::string cmd = getCommandToRun();
+//   std::cout << cmd << std::endl;
+
   int err = 0;
   execCmd( cmd.c_str(), err ); // run
 
@@ -858,21 +866,17 @@ std::string MgAdapt::getCommandToRun()
   //~{
       //~// 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;
@@ -886,31 +890,40 @@ 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;
     }
   }
+
+  // Verbosity Level
+  if (verbosityLevel != defaultVerboseLevel())
+  {
+    cmd+= " --verbose "+ ToComment(verbosityLevel);
+  }
     //~}
 //~cmd+= " >"
 #ifdef WIN32
     cmd += " < NUL";
 #endif
+//   std::cout << "--- cmd :"<< std::endl;
+//   std::cout << cmd << std::endl;
 
   return cmd;
 }
@@ -1152,9 +1165,83 @@ void MgAdapt::copyMgAdaptHypothesisData( const MgAdaptHypothesisData* from)
   data->myVerboseLevel = from->myVerboseLevel;
 }
 
-bool MgAdapt::checkTimeStepRank(std::string fileIn)
+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" )
+        {
+          SALOME::ExceptionStruct es;
+          es.type = SALOME::BAD_PARAM;
+          std::string text = "Mesh dimension is 2; the option should be 'surface' instead of '" + optionValue + "'." ;
+          es.text = CORBA::string_dup(text.c_str());
+          throw SALOME::SALOME_Exception(es);
+        }
+      }
+    }
+  }
+}
+
+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;}
+    SALOME::ExceptionStruct es;
+    es.type = SALOME::BAD_PARAM;
+    std::string text = "Field " + fieldName + " is not found." ;
+    es.text = CORBA::string_dup(text.c_str());
+    throw SALOME::SALOME_Exception(es);
+  }
+}
+
+void MgAdapt::checkTimeStepRank(std::string fileIn)
 {
-  INFOS("checkTimeStepRank");
   bool ret = false ;
   MEDCoupling::MCAuto<MEDCoupling::MEDFileData> mfd = MEDCoupling::MEDFileData::New(fileIn);
   MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeFieldMultiTS> fts = dynamic_cast<MEDCoupling::MEDFileFieldMultiTS *>( mfd->getFields()->getFieldWithName(fieldName) );
@@ -1165,25 +1252,23 @@ bool MgAdapt::checkTimeStepRank(std::string fileIn)
   std::size_t jaux(timesteprank.size());
   for(std::size_t j=0;j<jaux;j++)
   {
-//     std::cout << "--- l[j]first  " << timesteprank[j].first << std::endl;
-//     std::cout << "--- l[j]second " << timesteprank[j].second << std::endl;
     if ( ( timeStep == timesteprank[j].first ) & ( rank == timesteprank[j].second ) )
     {
       ret = true ;
+      break ;
     }
   }
   if ( ! ret )
   {
-    std::cout << "Available (Time step, Rank) :" << std::endl;
+    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;}
-   SALOME::ExceptionStruct es;
+    SALOME::ExceptionStruct es;
     es.type = SALOME::BAD_PARAM;
     std::string text = "(Time step = " + std::to_string(timeStep) + ", Rank = " + std::to_string(rank) + ") is not found." ;
     es.text = CORBA::string_dup(text.c_str());
     throw SALOME::SALOME_Exception(es);
   }
-  return ret ;
 }
 
 void MgAdapt::convertMedFile(std::string& meshFormatMeshFileName, std::string& solFormatFieldFileName, std::string& meshFormatsizeMapFile)
@@ -1204,14 +1289,16 @@ void MgAdapt::convertMedFile(std::string& meshFormatMeshFileName, std::string& s
 
   if (useBackgroundMap)
   {
-    bool ret = checkTimeStepRank(sizeMapFile) ;
+    checkFieldName(sizeMapFile) ;
+    checkTimeStepRank(sizeMapFile) ;
     meshFormatsizeMapFile = getFileName();
     meshFormatsizeMapFile += ".mesh";
     buildBackGroundMeshAndSolFiles(fieldFileNames, meshFormatsizeMapFile);
   }
   else if(useLocalMap)
   {
-    bool ret = checkTimeStepRank(medFileIn) ;
+    checkFieldName(medFileIn) ;
+    checkTimeStepRank(medFileIn) ;
     MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeFieldMultiTS> fts = dynamic_cast<MEDCoupling::MEDFileFieldMultiTS *>( mfd->getFields()->getFieldWithName(fieldName) );
     MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeField1TS> f = fts->getTimeStep(timeStep, rank);
     MEDCoupling::MCAuto<MEDCoupling::MEDFileFieldMultiTS> tmFts = MEDCoupling::MEDFileFieldMultiTS::New();