]> SALOME platform Git repositories - plugins/ghs3dprlplugin.git/commitdiff
Salome HOME
bos #24596 [CEA] New MeshGems license duc/V9_7_BR_new_MGLIC
authoreap <eap@opencascade.com>
Thu, 5 Aug 2021 12:33:26 +0000 (15:33 +0300)
committerDUC ANH HOANG <duc-anh-externe.hoang@edf.fr>
Thu, 13 Oct 2022 09:53:42 +0000 (11:53 +0200)
Fix bos #26435 MG-Tetra_HPC failed with new licence mechanism:
- set input file
- redirect messages to log file
- read log file only if it exists
- write meshes to default names in tmp as in GHS3D plugin
- works with both mpi and multithread

Meshes are still not loaded (since there are expected to be big)

src/GHS3DPRLPlugin/CMakeLists.txt
src/GHS3DPRLPlugin/GHS3DPRLPlugin_GHS3DPRL.cxx
src/GHS3DPRLPlugin/GHS3DPRLPlugin_GHS3DPRL.hxx
src/GHS3DPRLPlugin/GHS3DPRLPlugin_Hypothesis.cxx
src/GHS3DPRLPlugin/GHS3DPRLPlugin_Hypothesis.hxx
src/GHS3DPRLPlugin/MG_TetraHPC_API.cxx
src/GHS3DPRLPlugin/MG_TetraHPC_API.hxx
src/tepal2med/tetrahpc2med.cxx

index b0b0ce879b41ce0c239795de2a5c92e2c5e73fa2..ef597b2045d0194df0e103900d8ad1fafdeb0e43 100644 (file)
@@ -53,6 +53,7 @@ SET(_link_LIBRARIES
   ${SMESH_SMDS}
   ${SMESH_StdMeshers}
   ${SMESH_MeshDriverGMF}
+  ${SMESH_SMESHUtils}
   ${KERNEL_SalomeGenericObj}
   ${KERNEL_SALOMELocalTrace}
   ${KERNEL_SALOMEBasics}
index 71ff80573c7d3ec08d5b542c04de75a3b004aefa..db4f829611840bf71bd44c96e55d872dae77b9ac 100644 (file)
@@ -279,11 +279,13 @@ bool GHS3DPRLPlugin_GHS3DPRL::Compute(SMESH_Mesh&         theMesh,
 
   map <int,int> aSmdsToGHS3DPRLIdMap;
   map <int,const SMDS_MeshNode*> aGHS3DPRLIdToNodeMap;
-  GHS3DPRL_In = path + "GHS3DPRL";
+  _genericName = GHS3DPRLPlugin_Hypothesis::GetFileName(_hypothesis);
+  TCollection_AsciiString aGenericName((char*) _genericName.c_str() );
+  GHS3DPRL_In = aGenericName + ".mesh";
   GHS3DPRL_Out = path + casenamemed;
-  GHS3DPRL_Out_Mesh = path + casenamemed + "_out.mesh";
+  GHS3DPRL_Out_Mesh = aGenericName + "_out.mesh";
   GHS3DPRL_Outxml = path + casenamemed + ".xml"; //master file
-  logFileName = path + casenamemed + ".log"; // MG library output
+  logFileName = aGenericName + ".log"; // MG library output
   NbPart=_NbPart;
   Gradation=_Gradation;
   MinSize=_MinSize;
@@ -295,7 +297,7 @@ bool GHS3DPRLPlugin_GHS3DPRL::Compute(SMESH_Mesh&         theMesh,
   //             --verbose=0 --menu=no --launchtetra=yes;
 
   run_GHS3DPRL = run_GHS3DPRL +
-    " --casename=" + GHS3DPRL_In +
+    " --casename=" + aGenericName +
     " --number=" + NbPart +
     " --medname=" + GHS3DPRL_Out +
     " --launchtetra=yes" +
@@ -310,8 +312,6 @@ bool GHS3DPRLPlugin_GHS3DPRL::Compute(SMESH_Mesh&         theMesh,
   system( run_nokeep_files.ToCString() ); //clean files
   run_nokeep_files = rm + GHS3DPRL_In + "* ";
 
-  fileskinmesh=path + "GHS3DPRL.mesh";
-  GHS3DPRL_Out = path + casenamemed;
   removeFile( GHS3DPRL_Outxml ); //only the master xml file
 
   MG_TetraHPC_API mgTetraHPC( _computeCanceled, _progress );
@@ -319,30 +319,54 @@ bool GHS3DPRLPlugin_GHS3DPRL::Compute(SMESH_Mesh&         theMesh,
   if ( !useLib )
     mgTetraHPC.SetUseExecutable();
 
-  exportGMF( &mgTetraHPC, fileskinmesh.ToCString(), meshDS );
+  exportGMF( &mgTetraHPC, GHS3DPRL_In.ToCString(), meshDS );
 
-  if ( useLib )
+  if ( true /*useLib*/ )
   {
-    TCollection_AsciiString cmd = TCollection_AsciiString("mg-tetra_hpc.exe") + 
-      " --number_of_subdomains=" + NbPart +
-      " --gradation=" + Gradation +
-      " --min_size=" + MinSize +
-      " --max_size=" + MaxSize +
-      " --verbose=3" +
-      " --out=" + GHS3DPRL_Out_Mesh +
-      " " + _AdvOptions.c_str();
+    TCollection_AsciiString cmd = TCollection_AsciiString();
+    if (_Multithread)
+      cmd += "mg-tetra_hpc.exe";
+    else
+      cmd = cmd + "mpirun --n " + NbPart + " mg-tetra_hpc_mpi.exe";
+    cmd = cmd + " --in=" + GHS3DPRL_In;
+    if (_Multithread)
+      cmd = cmd +" --max_number_of_threads=" + NbPart;
+    cmd = cmd + " --gradation=" + Gradation;
+    cmd = cmd + " --min_size=" + MinSize;
+    cmd = cmd + " --max_size=" + MaxSize;
+    cmd = cmd + " --verbose=3";
+    cmd = cmd + " --out=" + GHS3DPRL_Out_Mesh;
+    cmd = cmd + " " + _AdvOptions.c_str();
+    cmd = cmd + " 1>" + logFileName;
 
     cout << endl
          << "  Run mg-tetra_hpc as library. Creating a mesh file " << GHS3DPRL_Out_Mesh << endl
          << "  Creating a log file : " << logFileName << endl << endl;
     mgTetraHPC.SetLogFile( logFileName.ToCString() );
 
-    mgTetraHPC.Compute( cmd.ToCString() );
+    std::string log;
+    Ok = mgTetraHPC.Compute( cmd.ToCString(), log );
 
-    std::string log = mgTetraHPC.GetLog();
-    if ( log.find(" Dlim "   ) != std::string::npos ||
-         log.find(" license ") != std::string::npos )
-      return error("License problem");
+    if (!Ok)
+    {
+      std::cout << "Error: " << std::endl;
+      std::cout << log << std::endl;
+      // try to guess an error from the output log
+      std::string log2 = mgTetraHPC.GetLog();
+      if ( log2.find(" Dlim "   ) != std::string::npos ||
+          log2.find(" license ") != std::string::npos )
+        return error("License problem");
+      std::cout << log2 << std::endl;
+      if ( log2.find("You are using an empty MPI stubs library") != std::string::npos )
+      {
+        std:string msg = "You are using an empty MPI stubs library. Please build it first to be able to use mg-tetra_hpc_mpi.exe.\n";
+        msg += "./salome context\n";
+        msg += "cd $MESHGEMSHOME/stubs\n";
+        msg += "mpicc meshgems_mpi.c -DMESHGEMS_LINUX_BUILD -I../include -shared -fPIC -o $MESHGEMSHOME/lib/Linux_64/libmeshgems_mpi.so";
+        return error(msg);
+      }
+      return error(log);
+    }
 
     // set --launchtetra=no
     int yesPos = run_GHS3DPRL.Search("launchtetra") + sizeof("launchtetra");
@@ -355,55 +379,62 @@ bool GHS3DPRLPlugin_GHS3DPRL::Compute(SMESH_Mesh&         theMesh,
     cout<<"  Write input file for mg-tetra_hpc "<<fileskinmesh<<"...";
     cout<<" ...done\n";
   }
-  fileskinmed=path + "GHS3DPRL_skin.med";
-  cout<<"  Write file "<<fileskinmed<<"...";
-  theMesh.ExportMED(fileskinmed.ToCString(),"SKIN_INITIAL",true);
-  cout<<" ...done\n\n";
-
-  cout<<"GHS3DPRL command :\n  "<<run_GHS3DPRL.ToCString()<<endl;
-  //sometimes it is better to wait flushing files on slow filesystem...
-  system( "sleep 3" );
-  //launch tetrahpc2med which launch mg-tetra_hpc.py which launch mg-tetra_hpc(_mpi?).exe
-  res = system( run_GHS3DPRL.ToCString() );
-  if (res > 0) 
+  // if mpi, convert meshes to med with xml master file
+  if (!_Multithread)
   {
-    pluginerror = pluginerror + "PROBLEM tetrahpc2med command";
-    cout<<pluginerror<<endl;
-    error(COMPERR_ALGO_FAILED, pluginerror.ToCString());
-    return false; //but it is not a problem but if true my message is overwritten
-  }
-  system( "sleep 3" );
-
-  if (_Background) {
-    pluginerror = pluginerror + "backgrounding... plugin is not waiting for output files "+ casenamemed + "_*.med";
-    cout<<pluginerror<<endl;
-    error(COMPERR_NO_MESH_ON_SHAPE, pluginerror.ToCString());
-    return false; //but it is not a problem but if true my message is overwritten
-    //return true; //but it is not a problem,
-  }
+    fileskinmed=path + casenamemed + "_skin.med";
+    cout<<"  Write file "<<fileskinmed<<"...";
+    theMesh.ExportMED(fileskinmed.ToCString(),"SKIN_INITIAL",true);
+    cout<<" ...done\n\n";
+
+    cout<<"GHS3DPRL command :\n  "<<run_GHS3DPRL.ToCString()<<endl;
+    //sometimes it is better to wait flushing files on slow filesystem...
+    system( "sleep 3" );
+    //launch tetrahpc2med which launch mg-tetra_hpc.py which launch mg-tetra_hpc(_mpi?).exe
+    std::cout << "run_GHS3DPRL cmd: " << run_GHS3DPRL << std::endl;
+    res = system( run_GHS3DPRL.ToCString() );
+    if (res > 0)
+    {
+      pluginerror = pluginerror + "PROBLEM tetrahpc2med command";
+      cout<<pluginerror<<endl;
+      error(COMPERR_ALGO_FAILED, pluginerror.ToCString());
+      return false; //but it is not a problem but if true my message is overwritten
+    }
+    system( "sleep 3" );
+
+    if (_Background) {
+      pluginerror = pluginerror + "backgrounding... plugin is not waiting for output files "+ path +casenamemed + "_*.med";
+      cout<<pluginerror<<endl;
+      error(COMPERR_NO_MESH_ON_SHAPE, pluginerror.ToCString());
+      return false; //but it is not a problem but if true my message is overwritten
+      //return true; //but it is not a problem,
+    }
 
-  // read a result, GHS3DPRL_Out is the name of master file (previous xml format)
-  FILE * aResultFile = fopen( GHS3DPRL_Outxml.ToCString(), "r" );
-  if (aResultFile){
-    Ok = true;
-    fclose(aResultFile);
-    cout<<"GHS3DPRL OK output master file "<<casenamemed<<".xml exist !\n\n";
-    pluginerror = pluginerror + "MG-tetra_hpc mesh(es) not loaded in memory, are stored in files "+ casenamemed + "_*.med";
-    cout<<pluginerror<<endl;
-    error(COMPERR_WARNING, pluginerror.ToCString() );
-    if (!_KeepFiles) system( run_nokeep_files.ToCString() );
-  }
-  else{
-    Ok = false; //it is a problem AND my message is NOT overwritten
-    pluginerror = pluginerror + "output master file " + casenamemed + ".xml do not exist";
-    cout<<pluginerror<<endl;
-    error(COMPERR_ALGO_FAILED, pluginerror.ToCString() );
-    cout<<"GHS3DPRL KO output files "<<GHS3DPRL_Out<<" do not exist ! see intermediates files keeped:\n";
-    TCollection_AsciiString run_list_files("ls -alt ");
-    run_list_files +=  GHS3DPRL_Out + "* " + GHS3DPRL_In + "* " + path + "tetrahpc.log";
-    system( run_list_files.ToCString() );
-    cout<<endl;
+    // read a result, GHS3DPRL_Out is the name of master file (previous xml format)
+    FILE * aResultFile = fopen( GHS3DPRL_Outxml.ToCString(), "r" );
+    if (aResultFile){
+      Ok = true;
+      fclose(aResultFile);
+      cout<<"GHS3DPRL OK output master file "<<casenamemed<<".xml exist !\n\n";
+      pluginerror = pluginerror + "MG-tetra_hpc mesh(es) not loaded in memory, are stored in files "+ path + casenamemed + "_*.med";
+      cout<<pluginerror<<endl;
+      error(COMPERR_WARNING, pluginerror.ToCString() );
+      if (!_KeepFiles) system( run_nokeep_files.ToCString() );
+    }
+    else{
+      Ok = false; //it is a problem AND my message is NOT overwritten
+      pluginerror = pluginerror + "output master file " + casenamemed + ".xml do not exist";
+      cout<<pluginerror<<endl;
+      error(COMPERR_ALGO_FAILED, pluginerror.ToCString() );
+      cout<<"GHS3DPRL KO output files "<<GHS3DPRL_Out<<" do not exist ! see intermediates files keeped:\n";
+      TCollection_AsciiString run_list_files("ls -alt ");
+      run_list_files +=  GHS3DPRL_Out + "* " + GHS3DPRL_In + "* " + logFileName;
+      system( run_list_files.ToCString() );
+      cout<<endl;
+    }
   }
+  else
+    Ok = true;
 
   return Ok;
 }
index 6a450bd6af4a66347c4637de03266eaeb6a3ec55..fd9b85a38f8fd6d13beb7f33f392c7f16e53a028 100644 (file)
@@ -57,6 +57,7 @@ public:
 
 protected:
   const GHS3DPRLPlugin_Hypothesis* _hypothesis;
+  std::string _genericName;
 private:
   int   _countSubMesh;
   int   _countTotal;
index 16505ffd67834e194d7d448b8e0bff7e3175306b..635fe2e7b2ae126338d453e9cf84320c9c47baa7 100644 (file)
 // ---
 //
 #include "GHS3DPRLPlugin_Hypothesis.hxx"
+#include <Basics_DirUtils.hxx>
+#include <SMESH_File.hxx>
 #include <utilities.h>
+#include <unistd.h>
+
+#ifdef WIN32
+#include <process.h>
+#define getpid _getpid
+#endif
 
 //=============================================================================
 /*!
@@ -47,6 +55,56 @@ GHS3DPRLPlugin_Hypothesis::GHS3DPRLPlugin_Hypothesis (int hypId, SMESH_Gen * gen
   _param_algo_dim = 3;
 }
 
+//=======================================================================
+//function : DefaultWorkingDirectory
+//=======================================================================
+
+std::string GHS3DPRLPlugin_Hypothesis::DefaultWorkingDirectory()
+{
+  TCollection_AsciiString aTmpDir;
+
+  char *Tmp_dir = getenv("SALOME_TMP_DIR");
+  if(Tmp_dir != NULL) {
+    aTmpDir = Tmp_dir;
+  }
+  else {
+#ifdef WIN32
+    aTmpDir = TCollection_AsciiString("C:\\");
+#else
+    aTmpDir = TCollection_AsciiString("/tmp/");
+#endif
+  }
+  return aTmpDir.ToCString();
+}
+
+//================================================================================
+/*!
+ * \brief Return a unique file name
+ */
+//================================================================================
+
+std::string GHS3DPRLPlugin_Hypothesis::GetFileName(const GHS3DPRLPlugin_Hypothesis* hyp)
+{
+  std::string aTmpDir = DefaultWorkingDirectory();
+  if ( !SMESH_File( aTmpDir ).exists() )
+    aTmpDir = Kernel_Utils::GetTmpDirByPath( aTmpDir );
+
+  const char lastChar = *aTmpDir.rbegin();
+#ifdef WIN32
+    if(lastChar != '\\') aTmpDir+='\\';
+#else
+    if(lastChar != '/') aTmpDir+='/';
+#endif
+
+  TCollection_AsciiString aGenericName = (char*)aTmpDir.c_str();
+  aGenericName += "MGTETRAHPC_";
+  aGenericName += getpid();
+  aGenericName += "_";
+  aGenericName += Abs((Standard_Integer)(long) aGenericName.ToCString());
+
+  return aGenericName.ToCString();
+}
+
 //=============================================================================
 /*!
  *
@@ -290,7 +348,7 @@ std::string GHS3DPRLPlugin_Hypothesis::GetDefaultMEDName()
 //=============================================================================
 int GHS3DPRLPlugin_Hypothesis::GetDefaultNbPart()
 {
-  return 16;
+  return 8;
 }
 
 //=============================================================================
index 01460656bfb7b020f486aa041b2391bdeae13841..5051e56f127269b498d66bb1f816876ffd32388b 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "SMESH_Hypothesis.hxx"
 #include "Utils_SALOME_Exception.hxx"
+#include <TCollection_AsciiString.hxx>
 
 //  Parameters for work of GHS3DPRL
 //
@@ -41,6 +42,13 @@ public:
 
   static const char* GetHypType() { return "MG-Tetra Parallel Parameters"; }
 
+  static std::string DefaultWorkingDirectory();
+
+  /*!
+   * \brief Return a unique file name
+   */
+  static std::string GetFileName(const GHS3DPRLPlugin_Hypothesis* hyp);
+
   void                  SetMEDName(std::string theVal);
   std::string           GetMEDName() const { return _MEDName; }
 
index b8b59d55e86848b685977c67a30e96d45f188f3a..f91ffaf0c94ef84cc24dd9d792601cd36a756e16 100644 (file)
 
 #include <SMESH_Comment.hxx>
 #include <SMESH_File.hxx>
+#include <SMESH_MGLicenseKeyGen.hxx>
 #include <Utils_SALOME_Exception.hxx>
 
-#include <vector>
-#include <iterator>
 #include <cstring>
+#include <iostream>
+#include <iterator>
+#include <vector>
 
 #ifdef USE_MG_LIBS
 
@@ -584,6 +586,14 @@ void MG_TetraHPC_API::LibData::Init()
 
 bool MG_TetraHPC_API::LibData::Compute( const std::string& outFile )
 {
+  // MG license
+  std::string errorTxt;
+  if ( !SMESHUtils_MGLicenseKeyGen::SignMesh( _tria_mesh, errorTxt ))
+  {
+    AddError( SMESH_Comment( "Problem with library SalomeMeshGemsKeyGenerator: ") << errorTxt );
+    return false;
+  }
+
   // Set surface mesh
   status_t ret = tetra_hpc_set_input_mesh( _session, _tria_mesh );
   if ( ret != STATUS_OK ) MG_Error( "unable to set surface mesh");
@@ -635,7 +645,8 @@ struct MG_TetraHPC_API::LibData // to avoid compiler warnings
  */
 //================================================================================
 
-MG_TetraHPC_API::MG_TetraHPC_API(volatile bool& cancelled_flag, double& progress)
+MG_TetraHPC_API::MG_TetraHPC_API(volatile bool& cancelled_flag, double& progress):
+  _nbNodes(0), _nbEdges(0), _nbFaces(0), _nbVolumes(0)
 {
   _useLib = false;
   _libData = new LibData( cancelled_flag, progress );
@@ -695,7 +706,7 @@ void MG_TetraHPC_API::SetUseExecutable()
  */
 //================================================================================
 
-bool MG_TetraHPC_API::Compute( const std::string& cmdLine )
+bool MG_TetraHPC_API::Compute( const std::string& cmdLine, std::string& errStr )
 {
   if ( _useLib ) {
 #ifdef USE_MG_LIBS
@@ -744,7 +755,7 @@ bool MG_TetraHPC_API::Compute( const std::string& cmdLine )
     }
 
     // compute
-    bool ok =  _libData->Compute( outFile );
+    bool ok = _libData->Compute( outFile );
 
     GetLog(); // write a log file
     _logFile = ""; // not to write it again
@@ -753,16 +764,33 @@ bool MG_TetraHPC_API::Compute( const std::string& cmdLine )
 #endif
   }
 
-  (void)cmdLine; // unused
-  // Run library ONLY
+  // add MG license key
+  {
+    std::string errorTxt, meshIn;
+    std::string key = SMESHUtils_MGLicenseKeyGen::GetKey( meshIn,
+                                                          _nbNodes, _nbEdges, _nbFaces, _nbVolumes,
+                                                          errorTxt );
+    if ( key.empty() )
+    {
+      errStr = "Problem with library SalomeMeshGemsKeyGenerator: " + errorTxt;
+      return false;
+    }
+
+    const_cast< std::string& >( cmdLine ) += " --key " + key;
+  }
 
-  // int err = system( cmdLine.c_str() ); // run
+  std::cout << "Launching: " << cmdLine << std::endl;
 
-  // if ( err )
-  //   errStr = SMESH_Comment("system(mg-tetra.exe ...) command failed with error: ")
-  //     << strerror( errno );
+  int err = system( cmdLine.c_str() ); // run
+
+  if ( err )
+  {
+    errStr = SMESH_Comment("system command failed with error: ")
+      << strerror( errno );
+    return false;
+  }
+  return true;
 
-  return false;
 }
 
 //================================================================================
@@ -1012,6 +1040,16 @@ int  MG_TetraHPC_API::GmfOpenMesh(const char* theFile, int rdOrWr, int ver, int
 
 void MG_TetraHPC_API::GmfSetKwd(int iMesh, GmfKwdCod what, int nb )
 {
+  if ( iMesh == 1 )
+  {
+    switch ( what ) {
+    case GmfVertices:  _nbNodes = nb; break;
+    case GmfEdges:     _nbEdges = nb; break;
+    case GmfTriangles: _nbFaces = nb; break;
+    default:;
+    }
+  }
+
   if ( _useLib ) {
 #ifdef USE_MG_LIBS
     switch ( what ) {
@@ -1190,6 +1228,11 @@ std::string MG_TetraHPC_API::GetLog()
     return err;
 #endif
   }
+  std::cout << "_logFile: " << _logFile << std::endl;
+
   SMESH_File file( _logFile );
-  return file.getPos();
+  if (file.exists() && file.size() > 0)
+    return file.getPos();
+  else
+    return "";
 }
index b4f9153c498b2a38ce5f30fe42f9de49414d2074..d1aed510c4d6f18b208863c8f6b6db547cf6c257 100644 (file)
@@ -52,7 +52,7 @@ public:
   void GmfSetLin(int iMesh, GmfKwdCod what, int id ); // required
   void GmfSetLin(int iMesh, GmfKwdCod what, int node1, int node2, int node3, int domain ); // tria
 
-  bool Compute( const std::string& cmdLine );
+  bool Compute( const std::string& cmdLine, std::string& errStr );
 
   // OUT from MESHGEMS
   int  GmfOpenMesh(const char* theFile, int rdOrWr, int * ver, int * dim);
@@ -81,6 +81,13 @@ private:
   LibData*      _libData;
   std::set<int> _openFiles;
   std::string   _logFile;
+
+
+  // count mesh entities for MG license key generation
+  int           _nbNodes;
+  int           _nbEdges;
+  int           _nbFaces;
+  int           _nbVolumes;
 };
 
 #endif
index fc18102beebfd734681f2206674bb0e05302c519..901c28338899122efe6433606927de4c88c14707 100644 (file)
@@ -840,10 +840,6 @@ int main(int argc, char *argv[])
    else
       path="./";
    casenamemed=casenamemed.section('/',-1);
-   if (casenamemed.length()>20){
-      std::cerr<<"--medname truncated (no more 20 characters)"<<std::endl;
-      casenamemed.truncate(20);
-   }
 
    n=casename.count('/');
    if (n>0)
@@ -851,10 +847,6 @@ int main(int argc, char *argv[])
    else
       pathini="./";
    casename=casename.section('/',-1);
-   if (casename.length()>20){
-      std::cerr<<"--casename truncated (no more 20 characters)"<<std::endl;
-      casename.truncate(20);
-   }
 
    //std::cout<<"CaseNameMed="<<casenamemed.toLatin1().constData()<<std::endl;
    //std::cout<<"PathMed="<<path.toLatin1().constData()<<std::endl;