From 6dd23a10c3441c0ccdc104380cb5192399eb806e Mon Sep 17 00:00:00 2001 From: cconopoima Date: Tue, 28 Mar 2023 14:33:12 -0300 Subject: [PATCH] Fixing issues pointed. Eliminate reference to MG_TetraHPC_API class since it is not be used. Fix typo when MGTetra HPC (parallel_mode is parallel_strategy). Reuse the same command line for MGTetra and MGTetraHPC changing the called executable depending on the user selection. Define ghs3dSetParametersDemo.py as test folling suggested instructions. --- CMakeLists.txt | 4 +- doc/salome/examples/CMakeLists.txt | 27 + doc/salome/examples/examples.set | 22 + src/GHS3DPlugin/CMakeLists.txt | 2 - src/GHS3DPlugin/GHS3DPlugin_GHS3D.cxx | 306 +--- src/GHS3DPlugin/GHS3DPlugin_GHS3D.hxx | 14 +- src/GHS3DPlugin/GHS3DPlugin_Hypothesis.cxx | 45 +- src/GHS3DPlugin/GHS3DPlugin_Hypothesis.hxx | 2 +- .../GHS3DPlugin_OptimizerHypothesis.cxx | 2 +- src/GHS3DPlugin/MG_TetraHPC_API.cxx | 1239 ----------------- src/GHS3DPlugin/MG_TetraHPC_API.hxx | 91 -- src/GUI/GHS3DPluginGUI_HypothesisCreator.cxx | 27 +- 12 files changed, 105 insertions(+), 1676 deletions(-) create mode 100644 doc/salome/examples/examples.set delete mode 100644 src/GHS3DPlugin/MG_TetraHPC_API.cxx delete mode 100644 src/GHS3DPlugin/MG_TetraHPC_API.hxx diff --git a/CMakeLists.txt b/CMakeLists.txt index 4683a30..376548c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -195,12 +195,14 @@ SET(SALOME_INSTALL_DOC "${SALOME_INSTALL_DOC}" CACHE PATH "Install path: SALOME SET(SALOME_GHS3DPLUGIN_INSTALL_RES_DATA "${SALOME_INSTALL_RES}/ghs3dplugin" CACHE PATH "Install path: SALOME GHS3DPLUGIN specific data") +SET(SALOME_GHS3DPLUGIN_INSTALL_TESTS "${SALOME_INSTALL_BINS}/test") + MARK_AS_ADVANCED(SALOME_INSTALL_BINS SALOME_INSTALL_LIBS SALOME_INSTALL_IDLS SALOME_INSTALL_HEADERS) MARK_AS_ADVANCED(SALOME_INSTALL_SCRIPT_SCRIPTS SALOME_INSTALL_SCRIPT_DATA SALOME_INSTALL_SCRIPT_PYTHON) MARK_AS_ADVANCED(SALOME_INSTALL_APPLISKEL_SCRIPTS SALOME_INSTALL_APPLISKEL_PYTHON SALOME_INSTALL_CMAKE_LOCAL SALOME_INSTALL_RES) MARK_AS_ADVANCED(SALOME_INSTALL_PYTHON SALOME_INSTALL_PYTHON_SHARED) MARK_AS_ADVANCED(SALOME_INSTALL_AMCONFIG_LOCAL SALOME_INSTALL_DOC) -MARK_AS_ADVANCED(SALOME_GHS3DPLUGIN_INSTALL_RES_DATA) +MARK_AS_ADVANCED(SALOME_GHS3DPLUGIN_INSTALL_RES_DATA SALOME_GHS3DPLUGIN_INSTALL_TESTS) # Accumulate environment variables for GHS3DPLUGIN module SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH NOCHECK ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_BINS} diff --git a/doc/salome/examples/CMakeLists.txt b/doc/salome/examples/CMakeLists.txt index edf8555..0fc6575 100644 --- a/doc/salome/examples/CMakeLists.txt +++ b/doc/salome/examples/CMakeLists.txt @@ -18,4 +18,31 @@ # FILE(GLOB files "${CMAKE_CURRENT_SOURCE_DIR}/*.py") +INCLUDE(examples.set) + +SET(COMPONENT_NAME GHS3DPLUGIN) + +SET(TEST_INSTALL_DIRECTORY ${SALOME_GHS3DPLUGIN_INSTALL_TESTS}) + +# make test +SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env) + +FOREACH(tfile ${EXAMPLE_NAMES}) + SET(TEST_NAME ${COMPONENT_NAME}_${tfile}) + #ADD_TEST(NAME ${TEST_NAME} + # COMMAND ${PYTHON_EXECUTABLE} -B ${CMAKE_SOURCE_DIR}/doc/salome/examples/testme.py ${CMAKE_CURRENT_SOURCE_DIR}/${tfile}.py) + ADD_TEST(NAME ${TEST_NAME} + COMMAND ${PYTHON_EXECUTABLE} -B ${CMAKE_CURRENT_SOURCE_DIR}/${tfile}.py) + SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES ENVIRONMENT "${tests_env}") + SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES LABELS "${COMPONENT_NAME}") + #INSTALL(FILES ${tfile}.py DESTINATION ${SALOME_INSTALL_DOC}/examples/GHS3DPLUGIN) +ENDFOREACH() + +# salome test +FOREACH(tfile ${EXAMPLE_NAMES}) + INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${tfile}.py + DESTINATION ${TEST_INSTALL_DIRECTORY}) +ENDFOREACH() + +INSTALL(FILES examples.set DESTINATION ${TEST_INSTALL_DIRECTORY}) INSTALL(FILES ${files} DESTINATION ${SALOME_INSTALL_DOC}/examples/GHS3DPLUGIN) diff --git a/doc/salome/examples/examples.set b/doc/salome/examples/examples.set new file mode 100644 index 0000000..11f137d --- /dev/null +++ b/doc/salome/examples/examples.set @@ -0,0 +1,22 @@ +# Copyright (C) 2016-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 +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# 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 +# + +SET(EXAMPLE_NAMES + ghs3dSetParametersDemo +) \ No newline at end of file diff --git a/src/GHS3DPlugin/CMakeLists.txt b/src/GHS3DPlugin/CMakeLists.txt index 286387f..ff46649 100644 --- a/src/GHS3DPlugin/CMakeLists.txt +++ b/src/GHS3DPlugin/CMakeLists.txt @@ -75,7 +75,6 @@ SET(GHS3DEngine_HEADERS GHS3DPlugin_OptimizerHypothesis.hxx GHS3DPlugin_OptimizerHypothesis_i.hxx MG_Tetra_API.hxx - MG_TetraHPC_API.hxx ) # --- sources --- @@ -91,7 +90,6 @@ SET(GHS3DEngine_SOURCES GHS3DPlugin_OptimizerHypothesis.cxx GHS3DPlugin_OptimizerHypothesis_i.cxx MG_Tetra_API.cxx - MG_TetraHPC_API.cxx ) # --- scripts --- diff --git a/src/GHS3DPlugin/GHS3DPlugin_GHS3D.cxx b/src/GHS3DPlugin/GHS3DPlugin_GHS3D.cxx index 14c9f61..0b48cdf 100644 --- a/src/GHS3DPlugin/GHS3DPlugin_GHS3D.cxx +++ b/src/GHS3DPlugin/GHS3DPlugin_GHS3D.cxx @@ -27,7 +27,6 @@ #include "GHS3DPlugin_GHS3D.hxx" #include "GHS3DPlugin_Hypothesis.hxx" #include "MG_Tetra_API.hxx" -#include "MG_TetraHPC_API.hxx" #include #include @@ -1588,18 +1587,7 @@ static bool writeGMFFile(MG_Tetra_API* MGInput */ //============================================================================= bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, - const TopoDS_Shape& theShape ) -{ - bool isMGTetra = _hyp->GetAlgorithm() == GHS3DPlugin_Hypothesis::MGTetra; - - if ( isMGTetra ) - return ComputeMGTetra( theMesh, theShape ); - else - return ComputeMGTetraHPC( theMesh, theShape ); -} - -bool GHS3DPlugin_GHS3D::ComputeMGTetra(SMESH_Mesh& theMesh, - const TopoDS_Shape& theShape) + const TopoDS_Shape& theShape) { bool Ok(false); TopExp_Explorer expBox ( theShape, TopAbs_SOLID ); @@ -1879,33 +1867,14 @@ bool GHS3DPlugin_GHS3D::ComputeMGTetra(SMESH_Mesh& theMesh, return Ok; } -bool GHS3DPlugin_GHS3D::ComputeMGTetraHPC(SMESH_Mesh& theMesh, - const TopoDS_Shape& /*theShape*/) -{ - SMESH_MesherHelper helper( theMesh ); - bool ok = ComputeMGTetraHPC( theMesh, &helper ); - return ok; -} - //============================================================================= /*! *Here we are going to use the MG-Tetra mesher w/o geometry */ //================================0============================================= -bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, - SMESH_MesherHelper* theHelper ) -{ - bool isMGTetra = _hyp->GetAlgorithm() == GHS3DPlugin_Hypothesis::MGTetra; - if ( isMGTetra ) - return ComputeMGTetra( theMesh, theHelper ); - else - return ComputeMGTetraHPC( theMesh, theHelper ); - -} - -bool GHS3DPlugin_GHS3D::ComputeMGTetra(SMESH_Mesh& theMesh, - SMESH_MesherHelper* theHelper) +bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, + SMESH_MesherHelper* theHelper) { theHelper->IsQuadraticSubMesh( theHelper->GetSubShape() ); @@ -2115,275 +2084,6 @@ bool GHS3DPlugin_GHS3D::ComputeMGTetra(SMESH_Mesh& theMesh, return Ok; } -//============================================================================= -// Write a skin mesh into a GMF file or pass it to MG-TetraHPC API -static void exportGMFHPC( MG_TetraHPC_API* theTetraInput, - const char* theFile, - const SMESHDS_Mesh* theMeshDS) -{ - int meshID = theTetraInput->GmfOpenMesh( theFile, GmfWrite, GMFVERSION, GMFDIMENSION); - - // nodes - int iN = 0, nbNodes = theMeshDS->NbNodes(); - theTetraInput->GmfSetKwd( meshID, GmfVertices, nbNodes ); - std::map< const SMDS_MeshNode*, int, TIDCompare > node2IdMap; - SMDS_NodeIteratorPtr nodeIt = theMeshDS->nodesIterator(); - SMESH_TNodeXYZ n; - while ( nodeIt->more() ) - { - n.Set( nodeIt->next() ); - theTetraInput->GmfSetLin( meshID, GmfVertices, n.X(), n.Y(), n.Z(), n._node->getshapeId() ); - node2IdMap.insert( node2IdMap.end(), std::make_pair( n._node, ++iN )); - } - - // triangles - SMDS_ElemIteratorPtr elemIt = theMeshDS->elementGeomIterator( SMDSGeom_TRIANGLE ); - if ( elemIt->more() ) - { - int nbTria = theMeshDS->GetMeshInfo().NbElements( SMDSGeom_TRIANGLE ); - theTetraInput->GmfSetKwd(meshID, GmfTriangles, nbTria ); - for ( int gmfID = 1; elemIt->more(); ++gmfID ) - { - const SMDS_MeshElement* tria = elemIt->next(); - theTetraInput->GmfSetLin(meshID, GmfTriangles, - node2IdMap[ tria->GetNode( 0 )], - node2IdMap[ tria->GetNode( 1 )], - node2IdMap[ tria->GetNode( 2 )], - tria->getshapeId() ); - } - } - theTetraInput->GmfCloseMesh( meshID ); -} - - -//======================================================================= -//before launching salome -//SALOME_TMP_DIR (for keep tepal intermediates files) could be set in user's directories -static TCollection_AsciiString getTmpDir() -{ - TCollection_AsciiString aTmpDir; - char *Tmp_dir = getenv("SALOME_TMP_DIR"); - if (Tmp_dir == NULL) Tmp_dir = getenv("TMP"); - if(Tmp_dir != NULL) - { - aTmpDir = Tmp_dir; -#ifdef WIN32 - if(aTmpDir.Value(aTmpDir.Length()) != '\\') aTmpDir+='\\'; -#else - if(aTmpDir.Value(aTmpDir.Length()) != '/') aTmpDir+='/'; -#endif - } - else - { -#ifdef WIN32 - aTmpDir = TCollection_AsciiString("C:\\"); -#else - aTmpDir = TCollection_AsciiString("/tmp/"); -#endif - } - return aTmpDir; -} - -bool GHS3DPlugin_GHS3D::ComputeMGTetraHPC(SMESH_Mesh& theMesh, - SMESH_MesherHelper* /*theHelper*/) -{ - bool Ok=false; - TCollection_AsciiString pluginerror("MG-TETRA_HPC: "); - SMESHDS_Mesh* meshDS = theMesh.GetMeshDS(); - if ( theMesh.NbTriangles() == 0 ) - return error( COMPERR_BAD_INPUT_MESH, "From MGTetra-HPC. No triangles in the mesh" ); - - if (_hyp == NULL){ - pluginerror += "No existing parameters/hypothesis for MG-TETRA_HPC"; - cout <<"\n"<HasOptionDefined("verbose") : true; - bool proximity = _hyp->GetUseVolumeProximity(); - bool isMultithread = _hyp->GetUseNumOfThreads(); - double minSize = _hyp->GetMinSize(); - double maxSize = _hyp->GetMaxSize(); - - TCollection_AsciiString - tmpDir = getTmpDir(), - GHS3DPRL_In, - GHS3DPRL_Out, - GHS3DPRL_Out_Mesh, - GHS3DPRL_Outxml, - logFileName, - rm("rm -f "), - run_nokeep_files, - NbPart, - fileskinmed(""), - path, - casenamemed; //_MEDName.c_str()); - - casenamemed += (char *)_MEDName.c_str(); - int n = casenamemed.SearchFromEnd('/'); - - if (n>0) { - path=casenamemed.SubString(1,n); - casenamemed=casenamemed.SubString(n+1,casenamemed.Length()); - } - else - path=tmpDir; - - if (casenamemed.Length()>20){ - casenamemed=casenamemed.SubString(1,20); - cerr<<"MEDName truncated (no more 20 characters) = "<GetNumOfThreads() ); - - const char* parallelMode[] = { "none", "reproducible_given_max_number_of_threads", "reproducible", "aggressive" }; - const short myMode = _hyp->GetParallelMode(); - if ( myMode >= 1 && myMode < 4 ) { - cmd += " --parallel_mode "; - cmd += parallelMode[ myMode ]; - } - } - - cmd = cmd + " --gradation " + SMESH_Comment( _hyp->GetGradation() ); - - const char* optimizationLevel[] = { "none" , "light" , "standard" , "standard+" , "strong" }; - const short myOpt = _hyp->GetOptimizationLevel(); - if ( myOpt >= 0 && myOpt < 5 && myOpt != 3 /*not standard+ for HPC*/) { - cmd += " --optimisation_level "; - cmd += optimizationLevel[ myOpt ]; - } - - if ( minSize > 0 ) cmd = cmd + " --min_size " + SMESH_Comment( minSize ); - if ( maxSize > 0 ) cmd = cmd + " --max_size " + SMESH_Comment( maxSize ); - if ( verbose ) cmd = cmd + " --verbose " + SMESH_Comment( _hyp->GetVerboseLevel() ); - if ( proximity ) cmd = cmd + " --volume_proximity_layers " + SMESH_Comment( _hyp->GetNbVolumeProximityLayers() ); - - _hyp->SetAdvancedOptionsInCommandLine( _AdvOptions ); - cmd = cmd + " " + _AdvOptions.c_str(); - cmd = cmd + " --out=" + GHS3DPRL_Out_Mesh; - 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() ); - - std::string log; - Ok = mgTetraHPC.Compute( cmd.ToCString(), log ); - - 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); - } - - if (!isMultithread) - { - fileskinmed=path + casenamemed + "_skin.med"; - cout<<" Write file "< 0) - { - Ok = true; - pluginerror = pluginerror + "MG-tetra_hpc mesh not loaded in memory, is stored in file "+ resuMedFile; - cout<myAlgorithm; + std::string cmd = GetExeName( algoId ); // check if any option is overridden by hyp->myTextOption bool max_memory = hyp ? !hyp->HasOptionDefined("max_memory") : true; bool auto_memory = hyp ? !hyp->HasOptionDefined("automatic_memory") : true; @@ -1843,15 +1844,14 @@ std::string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* h useBndRecovery = hyp->myToUseBoundaryRecoveryVersion; // MG-Tetra needs to know amount of memory it may use (MB). - // Default memory is defined at MG-Tetra installation but it may be not enough, - // so allow to use about all available memory - if ( max_memory ) { + // Default memory is defined at MG-Tetra installation but it may be not enough, // so allow to use about all available memory + if ( algoId == MGTetra && max_memory ) { float aMaximumMemory = hyp ? hyp->myMaximumMemory : -1; cmd += " --max_memory "; if ( aMaximumMemory < 0 ) cmd += SMESH_Comment( int( DefaultMaximumMemory() )); else cmd += SMESH_Comment( int( aMaximumMemory )); } - if ( auto_memory && !useBndRecovery ) { + if ( algoId == MGTetra && ( auto_memory && !useBndRecovery ) ) { float aInitialMemory = hyp ? hyp->myInitialMemory : -1; cmd += " --automatic_memory "; if ( aInitialMemory > 0 ) cmd += SMESH_Comment( int( aInitialMemory )); @@ -1876,11 +1876,13 @@ std::string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* h cmd += " --optimisation_level none"; // issue 22608 } else if ( optim_level && hyp && !useBndRecovery ) { - if ( hyp->myOptimizationLevel >= 0 && hyp->myOptimizationLevel < 5 ) { - const char* level[] = { "none" , "light" , "standard" , "standard+" , "strong" }; - cmd += " --optimisation_level "; - cmd += level[ hyp->myOptimizationLevel ]; - } + const char* level[] = { "none" , "light" , "standard" , "standard+" , "strong" }; + const short myOpt = hyp->myOptimizationLevel; + + if ( myOpt >= 0 && myOpt < 5 && ( algoId == MGTetra || ( algoId == MGTetraHPC && myOpt != 3 ) ) ) { + cmd += " --optimisation_level "; + cmd += level[ myOpt ]; + } } // to create internal nodes @@ -1917,13 +1919,20 @@ std::string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* h cmd += " --gradation " + SMESH_Comment( hyp->myGradation ); if ( hyp->GetUseNumOfThreads() ) - { + { cmd += " --max_number_of_threads " + SMESH_Comment( hyp->GetNumOfThreads() ); const char* pthreadMode[] = { "none" , "aggressive" , "safe" }; - if ( hyp->myPthreadModeMG >= 1 && hyp->myPthreadModeMG < 3 ) { + const char* parallelMode[] = { "none", "reproducible_given_max_number_of_threads", "reproducible", "aggressive" }; + + if ( algoId == MGTetra && hyp->myPthreadModeMG >= 1 && hyp->myPthreadModeMG < 3 ) { cmd += " --pthreads_mode "; cmd += pthreadMode[ hyp->myPthreadModeMG ]; } + else if ( algoId == MGTetraHPC && hyp->myPthreadModeMGHPC >= 1 && hyp->myPthreadModeMGHPC < 4 ) + { + cmd += " --parallel_strategy "; + cmd += parallelMode[ hyp->myPthreadModeMGHPC ]; + } } // proximity @@ -2003,9 +2012,17 @@ std::string GHS3DPlugin_Hypothesis::GetFileNameHPC(const GHS3DPlugin_Hypothesis* */ //================================================================================ -std::string GHS3DPlugin_Hypothesis::GetExeName() +std::string GHS3DPlugin_Hypothesis::GetExeName( ImplementedAlgorithms algoId ) { - return "mg-tetra.exe"; + switch ( algoId ) + { + case MGTetra: + return "mg-tetra.exe"; + case MGTetraHPC: + return "mg-tetra_hpc.exe"; + default: + throw( "Undefined algorithm id: "); + } } //================================================================================ diff --git a/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.hxx b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.hxx index b354445..1b52bb6 100644 --- a/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.hxx +++ b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.hxx @@ -301,7 +301,7 @@ public: /*! * \brief Return the name of executable */ - static std::string GetExeName(); + static std::string GetExeName( ImplementedAlgorithms algoId ); /*! * To set an enforced vertex diff --git a/src/GHS3DPlugin/GHS3DPlugin_OptimizerHypothesis.cxx b/src/GHS3DPlugin/GHS3DPlugin_OptimizerHypothesis.cxx index 7e5cf77..a27c823 100644 --- a/src/GHS3DPlugin/GHS3DPlugin_OptimizerHypothesis.cxx +++ b/src/GHS3DPlugin/GHS3DPlugin_OptimizerHypothesis.cxx @@ -153,7 +153,7 @@ bool GHS3DPlugin_OptimizerHypothesis::SetParametersByDefaults(const TDefaults& std::string GHS3DPlugin_OptimizerHypothesis::CommandToRun(const GHS3DPlugin_OptimizerHypothesis* hyp) { - SMESH_Comment cmd( GetExeName() ); + SMESH_Comment cmd( GetExeName( (ImplementedAlgorithms) 1 ) ); cmd << " --max_memory " << (( hyp && hyp->myMaximumMemory > 0 ) ? hyp->myMaximumMemory : DefaultMaximumMemory()); diff --git a/src/GHS3DPlugin/MG_TetraHPC_API.cxx b/src/GHS3DPlugin/MG_TetraHPC_API.cxx deleted file mode 100644 index cdecdf2..0000000 --- a/src/GHS3DPlugin/MG_TetraHPC_API.cxx +++ /dev/null @@ -1,1239 +0,0 @@ -// Copyright (C) 2004-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 -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// 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 "MG_TetraHPC_API.hxx" - -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifdef USE_MG_LIBS - -extern "C"{ -#include -#include -} - -struct MG_TetraHPC_API::LibData -{ - // MG objects - context_t * _context; - tetra_hpc_session_t * _session; - mesh_t * _tria_mesh; - sizemap_t * _sizemap; - mesh_t * _tetra_mesh; - - // data to pass to MG - std::vector _xyz; - std::vector _nodeSize; // required nodes - std::vector _edgeNodes; - int _nbRequiredEdges; - std::vector _triaNodes; - int _nbRequiredTria; - - int _count; - volatile bool& _cancelled_flag; - std::string _errorStr; - double& _progress; - - LibData( volatile bool & cancelled_flag, double& progress ) - : _context(0), _session(0), _tria_mesh(0), _sizemap(0), _tetra_mesh(0), - _nbRequiredEdges(0), _nbRequiredTria(0), - _cancelled_flag( cancelled_flag ), _progress( progress ) - { - } - // methods setting callbacks implemented after callback definitions - void Init(); - bool Compute( const std::string& outFile ); - - ~LibData() - { - if ( _tetra_mesh ) - tetra_hpc_regain_mesh( _session, _tetra_mesh ); - if ( _session ) - tetra_hpc_session_delete( _session ); - if ( _tria_mesh ) - mesh_delete( _tria_mesh ); - if ( _sizemap ) - sizemap_delete( _sizemap ); - if ( _context ) - context_delete( _context ); - - _tetra_mesh = 0; - _session = 0; - _tria_mesh = 0; - _sizemap = 0; - _context = 0; - } - - void AddError( const char *txt ) - { - if ( txt ) - _errorStr += txt; - } - - const std::string& GetErrors() - { - return _errorStr; - } - - void MG_Error(const char* txt="") - { - SMESH_Comment msg("\nMeshGems error. "); - msg << txt << "\n"; - AddError( msg.c_str() ); - } - - bool SetParam( const std::string& param, const std::string& value ) - { - status_t ret = tetra_hpc_set_param( _session, param.c_str(), value.c_str() ); -#ifdef _DEBUG_ - //std::cout << param << " = " << value << std::endl; -#endif - return ( ret == STATUS_OK ); - } - - bool Cancelled() - { - return _cancelled_flag; - } - - int ReadNbSubDomains() - { - integer nb = 0; - status_t ret = mesh_get_subdomain_count( _tetra_mesh, & nb ); - - if ( ret != STATUS_OK ) MG_Error("mesh_get_subdomain_count problem"); - return nb; - } - - int ReadNbNodes() - { - integer nb = 0; - status_t ret = mesh_get_vertex_count( _tetra_mesh, & nb ); - - if ( ret != STATUS_OK ) MG_Error("mesh_get_vertex_count problem"); - return nb; - } - - int ReadNbEdges() - { - integer nb = 0; - status_t ret = mesh_get_edge_count( _tetra_mesh, & nb ); - - if ( ret != STATUS_OK ) MG_Error("mesh_get_edge_count problem"); - return nb; - } - - int ReadNbTria() - { - integer nb = 0; - status_t ret = mesh_get_triangle_count( _tetra_mesh, & nb ); - - if ( ret != STATUS_OK ) MG_Error("mesh_get_triangle_count problem"); - return nb; - } - - int ReadNbQuads() - { - integer nb = 0; - status_t ret = mesh_get_quadrangle_count( _tetra_mesh, & nb ); - - if ( ret != STATUS_OK ) MG_Error("mesh_get_quadrangle_count problem"); - return nb; - } - - int ReadNbTetra() - { - integer nb = 0; - status_t ret = mesh_get_tetrahedron_count( _tetra_mesh, & nb ); - - if ( ret != STATUS_OK ) MG_Error("mesh_get_tetrahedron_count problem"); - return nb; - } - - int ReadNbHexa() - { - integer nb = 0; - status_t ret = mesh_get_hexahedron_count( _tetra_mesh, & nb ); - - if ( ret != STATUS_OK ) MG_Error("mesh_get_hexahedron_count problem"); - return nb; - } - - void ResetCounter() - { - _count = 1; - } - - void ReadSubDomain( int* nbNodes, int* faceInd, int* ori, int* domain ) - { - integer tag, seed_type, seed_idx, seed_orientation; - status_t ret = mesh_get_subdomain_description( _tetra_mesh, _count, - &tag, &seed_type, &seed_idx, &seed_orientation); - - if ( ret != STATUS_OK ) MG_Error( "unable to get a sub-domain description"); - - *nbNodes = 3; - *faceInd = seed_idx; - *domain = tag; - *ori = seed_orientation; - - ++_count; - } - void ReadNodeXYZ( double* x, double* y, double *z, int* /*domain*/ ) - { - real coo[3]; - status_t ret = mesh_get_vertex_coordinates( _tetra_mesh, _count, coo ); - if ( ret != STATUS_OK ) MG_Error( "unable to get resulting vertices" ); - - *x = coo[0]; - *y = coo[1]; - *z = coo[2]; - - ++_count; - } - - void ReadEdgeNodes( int* node1, int* node2, int* domain ) - { - integer vtx[2], tag; - status_t ret = mesh_get_edge_vertices( _tetra_mesh, _count, vtx); - if (ret != STATUS_OK) MG_Error( "unable to get resulting edge" ); - - *node1 = vtx[0]; - *node2 = vtx[1]; - - ret = mesh_get_edge_tag( _tetra_mesh, _count, &tag ); - if (ret != STATUS_OK) MG_Error( "unable to get resulting edge tag" ); - - *domain = tag; - - ++_count; - } - - void ReadTriaNodes( int* node1, int* node2, int* node3, int* domain ) - { - integer vtx[3], tag; - status_t ret = mesh_get_triangle_vertices( _tetra_mesh, _count, vtx); - if (ret != STATUS_OK) MG_Error( "unable to get resulting triangle" ); - - *node1 = vtx[0]; - *node2 = vtx[1]; - *node3 = vtx[2]; - - ret = mesh_get_triangle_tag( _tetra_mesh, _count, &tag ); - if (ret != STATUS_OK) MG_Error( "unable to get resulting triangle tag" ); - - *domain = tag; - - ++_count; - } - - void ReadQuadNodes( int* node1, int* node2, int* node3, int* node4, int* domain ) - { - integer vtx[4], tag; - status_t ret = mesh_get_quadrangle_vertices( _tetra_mesh, _count, vtx); - if (ret != STATUS_OK) MG_Error( "unable to get resulting quadrangle" ); - - *node1 = vtx[0]; - *node2 = vtx[1]; - *node3 = vtx[2]; - *node4 = vtx[3]; - - ret = mesh_get_quadrangle_tag( _tetra_mesh, _count, &tag ); - if (ret != STATUS_OK) MG_Error( "unable to get resulting quadrangle tag" ); - - *domain = tag; - - ++_count; - } - - void ReadTetraNodes( int* node1, int* node2, int* node3, int* node4, int* domain ) - { - integer vtx[4], tag; - status_t ret = mesh_get_tetrahedron_vertices( _tetra_mesh, _count, vtx); - if (ret != STATUS_OK) MG_Error( "unable to get resulting tetrahedron" ); - - *node1 = vtx[0]; - *node2 = vtx[1]; - *node3 = vtx[2]; - *node4 = vtx[3]; - - ret = mesh_get_tetrahedron_tag( _tetra_mesh, _count, &tag ); - if (ret != STATUS_OK) MG_Error( "unable to get resulting tetrahedron tag" ); - - *domain = tag; - - ++_count; - } - - void ReadHexaNodes( int* node1, int* node2, int* node3, int* node4, - int* node5, int* node6, int* node7, int* node8, int* domain ) - { - integer vtx[8], tag; - status_t ret = mesh_get_hexahedron_vertices( _tetra_mesh, _count, vtx); - if (ret != STATUS_OK) MG_Error( "unable to get resulting hexahedron" ); - - *node1 = vtx[0]; - *node2 = vtx[1]; - *node3 = vtx[2]; - *node4 = vtx[3]; - *node5 = vtx[4]; - *node6 = vtx[5]; - *node7 = vtx[6]; - *node8 = vtx[7]; - - ret = mesh_get_hexahedron_tag( _tetra_mesh, _count, &tag ); - if (ret != STATUS_OK) MG_Error( "unable to get resulting hexahedron tag" ); - - *domain = tag; - - ++_count; - } - - void SetNbVertices( int nb ) - { - _xyz.reserve( _xyz.capacity() + nb ); - } - - void SetNbEdges( int nb ) - { - _edgeNodes.reserve( nb * 2 ); - } - - void SetNbTria( int nb ) - { - _triaNodes.reserve( nb * 3 ); - } - - void SetNbReqVertices( int nb ) - { - _nodeSize.reserve( nb ); - } - - void SetNbReqEdges( int nb ) - { - _nbRequiredEdges = nb; - } - - void SetNbReqTria( int nb ) - { - _nbRequiredTria = nb; - } - - void AddNode( double x, double y, double z, int /*domain*/ ) - { - _xyz.push_back( x ); - _xyz.push_back( y ); - _xyz.push_back( z ); - } - - void AddSizeAtNode( double size ) - { - _nodeSize.push_back( size ); - } - - void AddEdgeNodes( int node1, int node2, int /*domain*/ ) - { - _edgeNodes.push_back( node1 ); - _edgeNodes.push_back( node2 ); - } - - void AddTriaNodes( int node1, int node2, int node3, int /*domain*/ ) - { - _triaNodes.push_back( node1 ); - _triaNodes.push_back( node2 ); - _triaNodes.push_back( node3 ); - } - - int NbNodes() - { - return _xyz.size() / 3; - } - - double* NodeCoord( int iNode ) - { - return & _xyz[ iNode * 3 ]; - } - - int NbEdges() - { - return _edgeNodes.size() / 2; - } - - int* GetEdgeNodes( int iEdge ) - { - return & _edgeNodes[ iEdge * 2 ]; - } - - int NbTriangles() - { - return _triaNodes.size() / 3; - } - - int * GetTriaNodes( int iTria ) - { - return & _triaNodes[ iTria * 3 ]; - } - - int IsVertexRequired( int iNode ) - { - return ! ( iNode < int( NbNodes() - _nodeSize.size() )); - } - - double GetSizeAtVertex( int iNode ) - { - return IsVertexRequired( iNode ) ? _nodeSize[ iNode - NbNodes() + _nodeSize.size() ] : 0.; - } -}; - -namespace // functions called by MG library to exchange with the application -{ - status_t get_vertex_count(integer * nbvtx, void *user_data) - { - MG_TetraHPC_API::LibData* data = (MG_TetraHPC_API::LibData *) user_data; - *nbvtx = data->NbNodes(); - - return STATUS_OK; - } - - status_t get_vertex_coordinates(integer ivtx, real * xyz, void *user_data) - { - MG_TetraHPC_API::LibData* data = (MG_TetraHPC_API::LibData *) user_data; - double* coord = data->NodeCoord( ivtx-1 ); - for (int j = 0; j < 3; j++) - xyz[j] = coord[j]; - - return STATUS_OK; - } - status_t get_edge_count(integer * nbedge, void *user_data) - { - MG_TetraHPC_API::LibData* data = (MG_TetraHPC_API::LibData *) user_data; - *nbedge = data->NbEdges(); - - return STATUS_OK; - } - - status_t get_edge_vertices(integer iedge, integer * vedge, void *user_data) - { - MG_TetraHPC_API::LibData* data = (MG_TetraHPC_API::LibData *) user_data; - int* nodes = data->GetEdgeNodes( iedge-1 ); - vedge[0] = nodes[0]; - vedge[1] = nodes[1]; - - return STATUS_OK; - } - - status_t get_triangle_count(integer * nbtri, void *user_data) - { - MG_TetraHPC_API::LibData* data = (MG_TetraHPC_API::LibData *) user_data; - *nbtri = data->NbTriangles(); - - return STATUS_OK; - } - - status_t get_triangle_vertices(integer itri, integer * vtri, void *user_data) - { - MG_TetraHPC_API::LibData* data = (MG_TetraHPC_API::LibData *) user_data; - int* nodes = data->GetTriaNodes( itri-1 ); - vtri[0] = nodes[0]; - vtri[1] = nodes[1]; - vtri[2] = nodes[2]; - - return STATUS_OK; - } - - // status_t get_triangle_extra_vertices(integer itri, integer * typetri, - // integer * evtri, void *user_data) - // { - // int j; - // MG_TetraHPC_API::LibData* data = (MG_TetraHPC_API::LibData *) user_data; - - // if (1) { - // /* We want to describe a linear "3 nodes" triangle */ - // *typetri = MESHGEMS_MESH_ELEMENT_TYPE_TRIA3; - // } else { - // /* We want to describe a quadratic "6 nodes" triangle */ - // *typetri = MESHGEMS_MESH_ELEMENT_TYPE_TRIA6; - // for (j = 0; j < 3; j++) - // evtri[j] = 0; /* the j'th quadratic vertex index of the itri'th triangle */ - // } - - // return STATUS_OK; - // } - - // status_t get_tetrahedron_count(integer * nbtetra, void *user_data) - // { - // MG_TetraHPC_API::LibData* data = (MG_TetraHPC_API::LibData *) user_data; - - // *nbtetra = 0; /* the number of tetra in your input mesh (0 if you describe a surface mesh) */ - - // return STATUS_OK; - // } - - // status_t get_tetrahedron_vertices(integer itetra, integer * vtetra, - // void *user_data) - // { - // int j; - // MG_TetraHPC_API::LibData* data = (MG_TetraHPC_API::LibData *) user_data; - - // for (j = 0; j < 4; j++) - // vtetra[j] = 0; /* the j'th vertex index of the itetra'th tetrahedron */ - - // return STATUS_OK; - // } - - status_t get_vertex_required_property(integer ivtx, integer * rvtx, void *user_data) - { - MG_TetraHPC_API::LibData* data = (MG_TetraHPC_API::LibData *) user_data; - *rvtx = data->IsVertexRequired( ivtx - 1 ); - - return STATUS_OK; - } - - // status_t get_vertex_weight(integer ivtx, real * wvtx, void *user_data) - // { - // MG_TetraHPC_API::LibData* data = (MG_TetraHPC_API::LibData *) user_data; - // *wvtx = data->GetSizeAtVertex( ivtx - 1 ); - - // return STATUS_OK; - // } - - status_t my_message_cb(message_t * msg, void *user_data) - { - char *desc; - message_get_description(msg, &desc); - - MG_TetraHPC_API::LibData* data = (MG_TetraHPC_API::LibData *) user_data; - data->AddError( desc ); - -#ifdef _DEBUG_ - //std::cout << desc << std::endl; -#endif - - return STATUS_OK; - } - - status_t my_interrupt_callback(integer *interrupt_status, void *user_data) - { - MG_TetraHPC_API::LibData* data = (MG_TetraHPC_API::LibData *) user_data; - *interrupt_status = ( data->Cancelled() ? INTERRUPT_STOP : INTERRUPT_CONTINUE ); - - //std::cout << "INTERRUPT_STOP" << std::endl; - - - return STATUS_OK; - } - -} // end namespace - - -void MG_TetraHPC_API::LibData::Init() -{ - status_t ret; - - // Create the meshgems working context - _context = context_new(); - if ( !_context ) MG_Error( "unable to create a new context" ); - - // Set the message callback for the _context. - ret = context_set_message_callback( _context, my_message_cb, this ); - if ( ret != STATUS_OK ) MG_Error("in context_set_message_callback"); - - // Create the structure holding the callbacks giving access to triangle mesh - _tria_mesh = mesh_new( _context ); - if ( !_tria_mesh ) MG_Error("unable to create a new mesh"); - - // Set callbacks to provide triangle mesh data - mesh_set_get_vertex_count( _tria_mesh, get_vertex_count, this ); - mesh_set_get_vertex_coordinates( _tria_mesh, get_vertex_coordinates, this ); - mesh_set_get_vertex_required_property( _tria_mesh, get_vertex_required_property, this ); - mesh_set_get_edge_count( _tria_mesh, get_edge_count, this); - mesh_set_get_edge_vertices( _tria_mesh, get_edge_vertices, this ); - mesh_set_get_triangle_count( _tria_mesh, get_triangle_count, this ); - mesh_set_get_triangle_vertices( _tria_mesh, get_triangle_vertices, this ); - - // Create a tetra session - _session = tetra_hpc_session_new( _context ); - if ( !_session ) MG_Error( "unable to create a new tetra_hpc session"); - - ret = tetra_hpc_set_interrupt_callback( _session, my_interrupt_callback, this ); - if ( ret != STATUS_OK ) MG_Error("in tetra_set_interrupt_callback"); - -} - -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"); - - // // Set a sizemap - // if ( !_nodeSize.empty() ) - // { - // _sizemap = meshgems_sizemap_new( _tria_mesh, meshgems_sizemap_type_iso_mesh_vertex, - // (void*) &get_vertex_weight, this ); - // if ( !_sizemap ) MG_Error("unable to create a new sizemap"); - - // ret = tetra_hpc_set_sizemap( _session, _sizemap ); - // if ( ret != STATUS_OK ) MG_Error( "unable to set sizemap"); - // } - - ////////////////////////////////////////////////////////////////////////////////////////// - // const char* file = "/tmp/ghs3d_IN.mesh"; - // mesh_write_mesh( _tria_mesh,file); - // std::cout << std::endl << std::endl << "Write " << file << std::endl << std::endl << std::endl; - - ret = tetra_hpc_mesh( _session ); - if ( ret != STATUS_OK ) return false; - - ret = tetra_hpc_get_mesh( _session, &_tetra_mesh); - if (ret != STATUS_OK) MG_Error( "unable to get resulting mesh"); - - mesh_write_mesh( _tetra_mesh, outFile.c_str() ); - - return true; -} - -#else // ifdef USE_MG_LIBS - -struct MG_TetraHPC_API::LibData // to avoid compiler warnings -{ - volatile bool& _cancelled_flag; - double& _progress; - LibData(volatile bool& cancelled_flag, double& progress) - : _cancelled_flag{cancelled_flag}, _progress{progress} - {} -}; - -#endif // ifdef USE_MG_LIBS - - -//================================================================================ -/*! - * \brief Constructor - */ -//================================================================================ - -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 ); -#ifdef USE_MG_LIBS - _useLib = true; - _libData->Init(); - if ( getenv("MG_TetraHPC_USE_EXE")) - _useLib = false; -#endif -} - -//================================================================================ -/*! - * \brief Destructor - */ -//================================================================================ - -MG_TetraHPC_API::~MG_TetraHPC_API() -{ -#ifdef USE_MG_LIBS - delete _libData; - _libData = 0; -#endif - std::set::iterator id = _openFiles.begin(); - for ( ; id != _openFiles.end(); ++id ) - ::GmfCloseMesh( *id ); - _openFiles.clear(); -} - -//================================================================================ -/*! - * \brief Return the way of MG usage - */ -//================================================================================ - -bool MG_TetraHPC_API::IsLibrary() -{ - return _useLib; -} - -//================================================================================ -/*! - * \brief Switch to usage of MG-Tetra executable - */ -//================================================================================ - -void MG_TetraHPC_API::SetUseExecutable() -{ - _useLib = false; -} - -//================================================================================ -/*! - * \brief Compute the tetra mesh - * \param [in] cmdLine - a command to run mg_tetra.exe - * \return bool - Ok or not - */ -//================================================================================ - -bool MG_TetraHPC_API::Compute( const std::string& cmdLine, std::string& errStr ) -{ - std::cout << "Command line from MG_Tetra-HPC: " << cmdLine << "\n"; - if ( _useLib ) { -#ifdef USE_MG_LIBS - - // split cmdLine - std::istringstream strm( cmdLine ); - std::istream_iterator sIt( strm ), sEnd; - std::vector< std::string > args( sIt, sEnd ); - - std::string outFile; - - // set parameters - std::string arg, param, value; - for ( size_t i = 1; i < args.size(); ++i ) - { - // look for a param name; it starts from "-" - arg = args[i]; - if ( arg.size() < 2 || arg[0] != '-') - continue; - while ( arg[0] == '-') - arg = arg.substr( 1 ); - - size_t eqPos = arg.find('='); - if ( eqPos != std::string::npos ) - { - param = arg.substr( 0, eqPos ); - value = arg.substr( eqPos+1 ); - } - else - { - param = arg; - value = ""; - } - if ( param == "out" ) - { - outFile = value; - continue; - } - while ( i+1 < args.size() && args[i+1][0] != '-' ) - { - if ( !value.empty() ) value += " "; - value += args[++i]; - } - if ( !_libData->SetParam( param, value )) - std::cout << "Warning: wrong param: '" << param <<"' = '" << value << "'" << std::endl; - } - - // compute - bool ok = _libData->Compute( outFile ); - - GetLog(); // write a log file - _logFile = ""; // not to write it again - - return ok; -#endif - } - - // 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; - } - - std::cout << "Launching: " << cmdLine << std::endl; - - int err = system( cmdLine.c_str() ); // run - - if ( err ) - { - errStr = SMESH_Comment("system command failed with error: ") - << strerror( errno ); - return false; - } - return true; - -} - -//================================================================================ -/*! - * \brief Prepare for reading a mesh data - */ -//================================================================================ - -int MG_TetraHPC_API::GmfOpenMesh(const char* theFile, int rdOrWr, int * ver, int * dim) -{ - if ( _useLib ) { -#ifdef USE_MG_LIBS - return 1; -#endif - } - int id = ::GmfOpenMesh(theFile, rdOrWr, ver, dim ); - _openFiles.insert( id ); - return id; -} - -//================================================================================ -/*! - * \brief Return nb of entities - */ -//================================================================================ - -int MG_TetraHPC_API::GmfStatKwd( int iMesh, GmfKwdCod what ) -{ - if ( _useLib ) { -#ifdef USE_MG_LIBS - switch ( what ) - { - case GmfSubDomainFromGeom: return _libData->ReadNbSubDomains(); - case GmfVertices: return _libData->ReadNbNodes(); - case GmfEdges: return _libData->ReadNbEdges(); - case GmfTriangles: return _libData->ReadNbTria(); - case GmfQuadrilaterals: return _libData->ReadNbQuads(); - case GmfTetrahedra: return _libData->ReadNbTetra(); - case GmfHexahedra: return _libData->ReadNbHexa(); - default: return 0; - } - return 0; -#endif - } - return ::GmfStatKwd( iMesh, what ); -} - -//================================================================================ -/*! - * \brief Prepare for reading some data - */ -//================================================================================ - -void MG_TetraHPC_API::GmfGotoKwd( int iMesh, GmfKwdCod what ) -{ - if ( _useLib ) { -#ifdef USE_MG_LIBS - _libData->ResetCounter(); - return; -#endif - } - ::GmfGotoKwd( iMesh, what ); -} - -//================================================================================ -/*! - * \brief Return index of a domain identified by a triangle normal - * \param [in] iMesh - mesh file index - * \param [in] what - must be GmfSubDomainFromGeom - * \param [out] nbNodes - nb nodes in a face - * \param [out] faceInd - face index - * \param [out] ori - face orientation - * \param [out] domain - domain index - * \param [in] dummy - an artificial param used to discriminate from GmfGetLin() reading - * a triangle - */ -//================================================================================ - -void MG_TetraHPC_API::GmfGetLin( int iMesh, GmfKwdCod what, int* nbNodes, int* faceInd, int* ori, int* domain, int /*dummy*/ ) -{ - if ( _useLib ) { -#ifdef USE_MG_LIBS - _libData->ReadSubDomain( nbNodes, faceInd, ori, domain ); - return; -#endif - } - ::GmfGetLin( iMesh, what, nbNodes, faceInd, ori, domain ); -} - -//================================================================================ -/*! - * \brief Return coordinates of a next node - */ -//================================================================================ - -void MG_TetraHPC_API::GmfGetLin(int iMesh, GmfKwdCod what, - double* x, double* y, double *z, int* domain ) -{ - if ( _useLib ) { -#ifdef USE_MG_LIBS - _libData->ReadNodeXYZ( x, y, z, domain ); - return; -#endif - } - ::GmfGetLin(iMesh, what, x, y, z, domain ); -} - -//================================================================================ -/*! - * \brief Return coordinates of a next node - */ -//================================================================================ - -void MG_TetraHPC_API::GmfGetLin(int iMesh, GmfKwdCod what, - float* x, float* y, float *z, int* domain ) -{ - if ( _useLib ) { -#ifdef USE_MG_LIBS - double X,Y,Z; - _libData->ReadNodeXYZ( &X, &Y, &Z, domain ); - *x = X; - *y = Y; - *z = Z; - return; -#endif - } - ::GmfGetLin(iMesh, what, x, y, z, domain ); -} - -//================================================================================ -/*! - * \brief Return node index of a next corner - */ -//================================================================================ - -void MG_TetraHPC_API::GmfGetLin(int iMesh, GmfKwdCod what, int* node ) -{ - if ( _useLib ) { -#ifdef USE_MG_LIBS - node = 0; - return; -#endif - } - ::GmfGetLin(iMesh, what, node ); -} - -//================================================================================ -/*! - * \brief Return node indices of a next edge - */ -//================================================================================ - -void MG_TetraHPC_API::GmfGetLin(int iMesh, GmfKwdCod what, int* node1, int* node2, int* domain ) -{ - if ( _useLib ) { -#ifdef USE_MG_LIBS - _libData->ReadEdgeNodes( node1, node2, domain ); - return; -#endif - } - ::GmfGetLin( iMesh, what, node1, node2, domain ); -} - -//================================================================================ -/*! - * \brief Return node indices of a next triangle - */ -//================================================================================ - -void MG_TetraHPC_API::GmfGetLin(int iMesh, GmfKwdCod what, - int* node1, int* node2, int* node3, int* domain ) -{ - if ( _useLib ) { -#ifdef USE_MG_LIBS - _libData->ReadTriaNodes( node1, node2, node3, domain ); - return; -#endif - } - ::GmfGetLin(iMesh, what, node1, node2, node3, domain ); -} - -//================================================================================ -/*! - * \brief Return node indices of a next tetrahedron or quadrangle - */ -//================================================================================ - -void MG_TetraHPC_API::GmfGetLin(int iMesh, GmfKwdCod what, - int* node1, int* node2, int* node3, int* node4, int* domain ) -{ - if ( _useLib ) { -#ifdef USE_MG_LIBS - if ( what == GmfQuadrilaterals ) - _libData->ReadQuadNodes( node1, node2, node3, node4, domain ); - else - _libData->ReadTetraNodes( node1, node2, node3, node4, domain ); - return; -#endif - } - ::GmfGetLin(iMesh, what, node1, node2, node3, node4, domain ); -} - -//================================================================================ -/*! - * \brief Return node indices of a next hexahedron - */ -//================================================================================ - -void MG_TetraHPC_API::GmfGetLin(int iMesh, GmfKwdCod what, - int* node1, int* node2, int* node3, int* node4, - int* node5, int* node6, int* node7, int* node8, - int* domain ) -{ - if ( _useLib ) { -#ifdef USE_MG_LIBS - _libData->ReadHexaNodes( node1, node2, node3, node4, - node5, node6, node7, node8, domain ); - return; -#endif - } - ::GmfGetLin(iMesh, what, node1, node2, node3, node4, node5, node6, node7, node8, domain ); -} - -//================================================================================ -/*! - * \brief Prepare for passing data to MeshGems - */ -//================================================================================ - -int MG_TetraHPC_API::GmfOpenMesh(const char* theFile, int rdOrWr, int ver, int dim) -{ - if ( _useLib ) { -#ifdef USE_MG_LIBS - return 1; -#endif - } - int id = ::GmfOpenMesh(theFile, rdOrWr, ver, dim); - _openFiles.insert( id ); - return id; -} - -//================================================================================ -/*! - * \brief Set number of entities - */ -//================================================================================ - -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 ) { - case GmfVertices: _libData->SetNbVertices( nb ); break; - case GmfEdges: _libData->SetNbEdges ( nb ); break; - case GmfRequiredEdges: _libData->SetNbReqEdges( nb ); break; - case GmfTriangles: _libData->SetNbTria ( nb ); break; - case GmfRequiredTriangles: _libData->SetNbReqTria ( nb ); break; - default:; - } - return; -#endif - } - ::GmfSetKwd(iMesh, what, nb ); -} - -//================================================================================ -/*! - * \brief Add coordinates of a node - */ -//================================================================================ - -void MG_TetraHPC_API::GmfSetLin(int iMesh, GmfKwdCod what, double x, double y, double z, int domain) -{ - if ( _useLib ) { -#ifdef USE_MG_LIBS - _libData->AddNode( x, y, z, domain ); - return; -#endif - } - ::GmfSetLin(iMesh, what, x, y, z, domain); -} - -//================================================================================ -/*! - * \brief Set number of field entities - * \param [in] iMesh - solution file index - * \param [in] what - solution type - * \param [in] nbNodes - nb of entities - * \param [in] nbTypes - nb of data entries in each entity - * \param [in] type - types of the data entries - * - * Used to prepare to storing size at nodes - */ -//================================================================================ - -void MG_TetraHPC_API::GmfSetKwd(int iMesh, GmfKwdCod what, int nbNodes, int dummy, int type[] ) -{ - if ( _useLib ) { -#ifdef USE_MG_LIBS - if ( what == GmfSolAtVertices ) _libData->SetNbReqVertices( nbNodes ); - return; -#endif - } - ::GmfSetKwd(iMesh, what, nbNodes, dummy, type ); -} - -//================================================================================ -/*! - * \brief Add solution data - */ -//================================================================================ - -void MG_TetraHPC_API::GmfSetLin(int iMesh, GmfKwdCod what, double vals[]) -{ - if ( _useLib ) { -#ifdef USE_MG_LIBS - _libData->AddSizeAtNode( vals[0] ); - return; -#endif - } - ::GmfSetLin(iMesh, what, vals); -} - -//================================================================================ -/*! - * \brief Add edge nodes - */ -//================================================================================ - -void MG_TetraHPC_API::GmfSetLin(int iMesh, GmfKwdCod what, int node1, int node2, int domain ) -{ - if ( _useLib ) { -#ifdef USE_MG_LIBS - _libData->AddEdgeNodes( node1, node2, domain ); - return; -#endif - } - ::GmfSetLin(iMesh, what, node1, node2, domain ); -} - -//================================================================================ -/*! - * \brief Add a 'required' flag - */ -//================================================================================ - -void MG_TetraHPC_API::GmfSetLin(int iMesh, GmfKwdCod what, int id ) -{ - if ( _useLib ) { -#ifdef USE_MG_LIBS - return; -#endif - } - ::GmfSetLin(iMesh, what, id ); -} - -//================================================================================ -/*! - * \brief Add triangle nodes - */ -//================================================================================ - -void MG_TetraHPC_API::GmfSetLin(int iMesh, GmfKwdCod what, int node1, int node2, int node3, int domain ) -{ - if ( _useLib ) { -#ifdef USE_MG_LIBS - _libData->AddTriaNodes( node1, node2, node3, domain ); - return; -#endif - } - ::GmfSetLin(iMesh, what, node1, node2, node3, domain ); -} - -//================================================================================ -/*! - * \brief Close a file - */ -//================================================================================ - -void MG_TetraHPC_API::GmfCloseMesh( int iMesh ) -{ - if ( _useLib ) { -#ifdef USE_MG_LIBS - return; -#endif - } - ::GmfCloseMesh( iMesh ); - _openFiles.erase( iMesh ); -} - -//================================================================================ -/*! - * \brief Return true if the log is not empty - */ -//================================================================================ - -bool MG_TetraHPC_API::HasLog() -{ - if ( _useLib ) { -#ifdef USE_MG_LIBS - return !_libData->GetErrors().empty(); -#endif - } - SMESH_File file( _logFile ); - return file.size() > 0; -} - -//================================================================================ -/*! - * \brief Return log contents - */ -//================================================================================ - -std::string MG_TetraHPC_API::GetLog() -{ - if ( _useLib ) { -#ifdef USE_MG_LIBS - const std::string& err = _libData->GetErrors(); - if ( !_logFile.empty() && !err.empty() ) - { - SMESH_File file( _logFile, /*openForReading=*/false ); - file.openForWriting(); - file.write( err.c_str(), err.size() ); - } - return err; -#endif - } - std::cout << "_logFile: " << _logFile << std::endl; - - SMESH_File file( _logFile ); - if (file.exists() && file.size() > 0) - return file.getPos(); - else - return ""; -} diff --git a/src/GHS3DPlugin/MG_TetraHPC_API.hxx b/src/GHS3DPlugin/MG_TetraHPC_API.hxx deleted file mode 100644 index 34fe868..0000000 --- a/src/GHS3DPlugin/MG_TetraHPC_API.hxx +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (C) 2004-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 -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// 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 -// - -#ifndef __MG_TetraHPC_IO_HXX__ -#define __MG_TetraHPC_IO_HXX__ - -#include "MG_Tetra_API.hxx" - -#include -#include - -/*! - * \brief Class providing a transparent switch between MG_TetraHPC usage as - * a library and as an executable. API of libmesh5 inherited. - */ -class MG_TetraHPC_API -{ -public: - - MG_TetraHPC_API( volatile bool& cancelled_flag, double& progress ); - ~MG_TetraHPC_API(); - - bool IsLibrary(); - bool IsExecutable() { return !IsLibrary(); } - void SetUseExecutable(); - - // IN to MESHGEMS - int GmfOpenMesh(const char* theFile, int rdOrWr, int ver, int dim); - void GmfSetKwd(int iMesh, GmfKwdCod what, int nb ); - void GmfSetLin(int iMesh, GmfKwdCod what, double x, double y, double z, int domain); - void GmfSetKwd(int iMesh, GmfKwdCod what, int nbNodes, int dummy, int type[] ); // sol type - void GmfSetLin(int iMesh, GmfKwdCod what, double vals[]); // sol - void GmfSetLin(int iMesh, GmfKwdCod what, int node1, int node2, int domain ); // edge - 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, std::string& errStr ); - - // OUT from MESHGEMS - int GmfOpenMesh(const char* theFile, int rdOrWr, int * ver, int * dim); - int GmfStatKwd( int iMesh, GmfKwdCod what ); - void GmfGotoKwd( int iMesh, GmfKwdCod what ); - void GmfGetLin( int iMesh, GmfKwdCod what, int* nbNodes, int* faceInd, int* ori, int* domain, int dummy ); - void GmfGetLin(int iMesh, GmfKwdCod what, float* x, float* y, float *z, int* domain ); - void GmfGetLin(int iMesh, GmfKwdCod what, double* x, double* y, double *z, int* domain ); - void GmfGetLin(int iMesh, GmfKwdCod what, int* node ); - void GmfGetLin(int iMesh, GmfKwdCod what, int* node1, int* node2, int* domain ); - void GmfGetLin(int iMesh, GmfKwdCod what, int* node1, int* node2, int* node3, int* domain ); - void GmfGetLin(int iMesh, GmfKwdCod what, int* node1, int* node2, int* node3, int* node4, int* domain ); - void GmfGetLin(int iMesh, GmfKwdCod what, int* node1, int* node2, int* node3, int* node4, int* node5, int* node6, int* node7, int* node8, int* domain ); - void GmfCloseMesh( int iMesh ); - - void SetLogFile( const std::string& logFileName ) { _logFile = logFileName; } - bool HasLog(); - std::string GetLog(); - - - struct LibData; - -private: - - bool _useLib; - LibData* _libData; - std::set _openFiles; - std::string _logFile; - - - // count mesh entities for MG license key generation - int _nbNodes; - int _nbEdges; - int _nbFaces; - int _nbVolumes; -}; - -#endif diff --git a/src/GUI/GHS3DPluginGUI_HypothesisCreator.cxx b/src/GUI/GHS3DPluginGUI_HypothesisCreator.cxx index 6b477bf..2589be3 100644 --- a/src/GUI/GHS3DPluginGUI_HypothesisCreator.cxx +++ b/src/GUI/GHS3DPluginGUI_HypothesisCreator.cxx @@ -1921,20 +1921,28 @@ bool GHS3DPluginGUI_HypothesisCreator::storeParamsToHypo( const GHS3DHypothesisD if( isCreation() ) SMESH::SetName( SMESH::FindSObject( h ), h_data.myName.toLatin1().constData() ); - h->SetAlgorithm ((CORBA::Short) h_data.myAlgorithm ); + if ( opt->_is_nil() ) + { + h->SetAlgorithm ((CORBA::Short) h_data.myAlgorithm ); + h->SetUseNumOfThreads ( h_data.myUseNumOfThreads ); + h->SetNumOfThreads ( (CORBA::Short) h_data.myNumOfThreads ); + h->SetPthreadMode ( (CORBA::Short) h_data.myPthreadMode ); + h->SetParallelMode ( (CORBA::Short) h_data.myParallelMode ); + h->SetGradation ( h_data.myGradation ); + h->SetToMeshHoles ( h_data.myToMeshHoles ); + h->SetToMakeGroupsOfDomains ( h_data.myToMakeGroupsOfDomains ); + h->SetVolumeProximity ( h_data.myUseProximity ); + h->SetNbVolumeProximityLayers ((CORBA::Short) h_data.myNbProximityLayers ); + } + + // Common existing options optimization a MGTetra && MGTetraHPC h->SetOptimizationLevel ((CORBA::Short) h_data.myOptimizationLevel ); h->SetMinSize ( h_data.myUseMinSize ? h_data.myMinSize : 0 ); h->SetMaxSize ( h_data.myUseMaxSize ? h_data.myMaxSize : 0 ); h->SetMinMaxSizeDefault ( this->myMinSizeDefault, this->myMaxSizeDefault ); - h->SetGradation ( h_data.myGradation ); - h->SetVolumeProximity ( h_data.myUseProximity ); - h->SetNbVolumeProximityLayers ((CORBA::Short) h_data.myNbProximityLayers ); - h->SetToMeshHoles ( h_data.myToMeshHoles ); - h->SetToMakeGroupsOfDomains ( h_data.myToMakeGroupsOfDomains ); h->SetMaximumMemory ( h_data.myMaximumMemory ); h->SetInitialMemory ( h_data.myInitialMemory ); - h->SetInitialMemory ( h_data.myInitialMemory ); h->SetKeepFiles ( h_data.myKeepFiles ); h->SetWorkingDirectory ( h_data.myWorkingDir.toLatin1().constData() ); h->SetVerboseLevel ( h_data.myVerboseLevel ); @@ -1943,10 +1951,7 @@ bool GHS3DPluginGUI_HypothesisCreator::storeParamsToHypo( const GHS3DHypothesisD //h->SetFEMCorrection ( h_data.myFEMCorrection ); h->SetStandardOutputLog ( h_data.myLogInStandardOutput ); h->SetRemoveLogOnSuccess ( h_data.myRemoveLogOnSuccess ); - h->SetUseNumOfThreads ( h_data.myUseNumOfThreads ); - h->SetNumOfThreads ( (CORBA::Short) h_data.myNumOfThreads ); - h->SetPthreadMode ( (CORBA::Short) h_data.myPthreadMode ); - h->SetParallelMode ( (CORBA::Short) h_data.myParallelMode ); + if ( !opt->_is_nil() ) { -- 2.39.2