# ============
OPTION(SALOME_BUILD_TESTS "Build SALOME tests" ON)
OPTION(SALOME_BUILD_DOC "Generate SALOME HYBRIDPLUGIN documentation" ON)
-OPTION(SALOME_USE_MG_LIBS "Use MeshGems libraries" OFF)
+OPTION(SALOME_USE_MG_LIBS "Use MeshGems libraries" ON)
MARK_AS_ADVANCED(SALOME_USE_MG_LIBS)
IF(SALOME_BUILD_TESTS)
HYBRID Parameters hypothesis works only with <b>MeshGems-Hybrid</b>
algorithm. This algorithm is a commercial software.
-To get a licence, visit http://www.distene.com and http://www.meshgems.com/
+To get a license, visit https://www.spatial.com/products/3d-precise-mesh
\tableofcontents
\section hybrid_general_parameters General parameters
-\image html hybrid_hypothesis_arguments.png
+MG-Hybrid allows to generate meshes with:
+- tetrahedral or hexahedral elements for the main core of the shape,
+- prismatic layers (prisms or hexahedra) depending on the surface mesh (triangles or quadrangles)
+- pyramids doing the junction if needed between tetrahedra (or prisms) and hexahedra.
-- <b>Hybrid parameters</b> - See distene documentation or MeshGems-Hybrid help command:
+\image html hybrid_tetra_dominant.png "Tetra dominant"
+
+\image html hybrid_hexa_dominant.png "Hexa dominant"
+
+\image html hybrid_cartesian_core.png "Cartesian core"
+
+\image html hybrid_hypothesis_arguments.png "Hybrid arguments"
+
+- <b>Number of boundary layers</b> - Sets the number of boundary layers to add.
+
+- <b>Size mode</b> - Define where to sets the boundary layers:
+
+ - <b>Global</b> - Define the layers on all the faces
+
+ - <b>Local</b> - Define the layers on selected faces. To be selected on the tab <b>Faces with layers</b>
+
+- <b>Height of first layer</b> - Define the height of the first layer
+
+- <b>Height relative to local surface</b> - If set to yes, the given size is relative to the surface size
+
+- <b>Growth of boundary layers</b> - Define if the boundary layers will be added inside the domain (<b>Downward growth</b>) or outside the domain (<b>Upward growth</b>).
+
+- <b>Maximal element angle (degrees)</b> - Sets the maximum internal angles of elements (in degree).
+This setting applies to the boundary layer elements only.
+
+- <b>Geometric progression</b> - Sets the geometric progression for all the boundary layer growths.
+
+- <b>Imprinting</b> - If set to yes, allows to define where the boundary layers will be imprinted (the inlets and oulets in a CFD study). These faces are to be selected in the <b>Faces with imprinting</b> tab.
+
+- <b>Snapping</b> - If set to yes, allows to define where the boundary layers are already imprinted on the 2D mesh (the inlets and oulets in a CFD study). These faces are to be selected in the <b>Faces with snapping</b> tab.
+
+\ref hybrid_top "Back to top"
+
+\section hybrid_advanced_parameters Advanced parameters
+
+\image html hybrid_hypothesis_advanced.png
+
+\subsection advanced_meshing_options Advanced meshing options
+
+- A table allows to input in the command line any text
+ for hybrid argument from "mg-hybrid.exe help", and future advanced options... <br>
+<b>Add option</b> - adds a line to the table where you can type an option and its value as text.
+A check box in the first column activates/deactivates the option of the current row. A deactivated option will be erased upon pressing \a Ok.
+
+- <b>Add multi normals</b> - Add extra normals at opening ridges and
+corners.
+
+- <b>Collision mode</b> - Sets the behavior in case of collision between layers.
+
+ - <b>decrease</b> - keeps the number of desired layer but decreases the height of the layers to
+ avoid any collision
+
+ - <b>stop</b> - stops locally the generation of layers to avoid collisions; the number of
+ generated layers may differ from the specified desired number
+
+- <b>Gradation</b> - Sets the desired maximum ratio between 2 adjacent edges.
+ It applies only to the edges which belong to the tetrahedra.
+
+- <b>Maximum number of threads</b> - Sets the maximum number of threads to be used in parallel.
+
+- <b>Multi normal angle threshold</b> - Set the maximum angle (in
+ degrees) between the multiple normals at opening ridges.
+
+- <b>Smooth normals</b> - Smooth normals at closed ridges and corners.
+
+\subsection log Logs and debug
+
+- <b>Working directory</b> - allows defining the folder for input and output
+files of hybrid software, which are the files starting with "HYBRID_" prefix.
+
+- <b>Verbose level</b> - to choose verbosity level in the range from
+0 to 10.
+
+ - 0, no standard output,
+
+ - 2, prints the data, quality statistics of the skin and final
+ meshes and indicates when the final mesh is being saved. In addition
+ the software gives indication regarding the CPU time.
+
+ - 10, same as 2 plus the main steps in the computation, quality
+ statistics histogram of the skin mesh, quality statistics histogram
+ together with the characteristics of the final mesh.
+
+- <b>Print log in a file</b> - if this option is checked on the log is printed in a
+file placed in the working directory, otherwise it is printed on the standard output.
+
+- <b>Remove log on success</b> - if this option is checked on the log file is kept only
+if an error occurs during the computation. This option is only available if <b>Print log in a file</b>
+is enabled (there must be a log file to delete it) and <b>Keep all working files</b> is disabled
+(in this case the log file is always kept).
+
+- <b>Keep all working files</b> - allows checking input and output files
+of hybrid software, while usually these files are removed after the
+launch of the mesher. The log file (if any) is also kept if this option is checked.
+
+- <b>Use library</b> - allows to call MG-Hybrid by library instead of executable.
+You can also set the environment variable <b>MG_HYBRID_USE_LIB</b> to change this default behaviour.
+
+\ref hybrid_top "Back to top"
+
+\section hybrid_layers_faces Faces with layers
+
+\image html hybrid_hypothesis_layers.png
+
+In case of a mesh based on geometry, if <b>Size mode</b> is set to
+<b>Local</b>, this tab becomes activated. You can specify geometrical
+faces on which boundary layers should be constructed (i.e. corresponding to the walls in a CFD study).
+After clicking
+\a Selection button (arrow) you can select faces either in the
+Viewer or in the Object Browser. \b Add button adds IDs of the
+selected faces to the <b>Face IDs</b> list. \b Remove button removes
+selected IDs from the list.
+
+\section hybrid_layers_faces Faces with imprinting
+
+\image html hybrid_hypothesis_imprinting.png
+
+If *Imprinting* is set to yes, this tab becomes activated. You can select the faces
+where the layers will be imprinted (i.e. corresponding to the inlets and outlets in a CFD study).
+
+\section hybrid_layers_faces Faces with snapping
+
+\image html hybrid_hypothesis_snapping.png
+
+Instead of letting MG-Hybrid do the imprinting on faces, you can tell to use existing faces where
+cells corresponding to the imprinting are already present (created by the surface mesh generation
+with dedicated algorithms).
+
+<br><b>See Also</b> a sample TUI Script of the \ref tui_hybrid "creation of a MG-Hybrid hypothesis".
+
+\ref hybrid_top "Back to top"
+
+\section hybrid_all_parameters All MG-hybrid parameters
+
+- <b>Hybrid parameters</b> - See documentation in $MESHGEMS_ROOT_DIR/Docs/mg-hybrid_user_manual.pdf
+or MG-Hybrid help command:
\verbatim
$> mg-hybrid.exe --help
- ==========================================
- MG-Hybrid -- MeshGems 2.9-6 (August, 2019)
- ==========================================
-
- Distene SAS
- Campus Teratec
- 2, rue de la Piquetterie
- 91680 Bruyeres le Chatel
- FRANCE
- Phone: +33(0)970-650-219 Fax: +33(0)169-269-033
- EMail: <support@distene.com>
-
- Running MG-Hybrid (Copyright 2014-2019 by Distene SAS)
- date of run: 07-Oct-2019 AT 17:40:47
- running on : Linux 3.16.0-4-amd64 x86_64
+ ============================================
+ MG-Hybrid -- MeshGems 2.15-1 (January, 2023)
+ ============================================
+
+
+ Running MG-Hybrid (Copyright 2014-2023 by Dassault Systemes SE)
+ date of run: 06-Jun-2024 AT 13:13:22
+ running on : Linux 5.11.12-300.fc34.x86_64 x86_64
using modules:
- MeshGems-Core 2.9-6
+ MeshGems-Core 2.15-1
- MeshGems is a Registered Trademark of Distene SAS
+ MeshGems is a commercial trademark of Dassault Systemes SE
MG-HYBRID USAGE
mg-hybrid.exe [-h] [-v <verbose>] [-i <filein>] [-o <fileout>] \
- [--global_physical_size <size>] [--max_number_of_threads <maxthreads>] \
+ [--global_physical_size <size>] \
+ [--max_number_of_threads <maxthreads>] \
[--boundary_layer_size_mode <mode>] \
[--boundary_layer_height_relative_to_local_surface_size <yes|no>] \
- [--number_of_boundary_layers <number>] [--boundary_layer_global_initial_height <height>] \
+ [--number_of_boundary_layers <number>] \
+ [--boundary_layer_global_initial_height <height>] \
[--boundary_layer_surface_tags <list>] \
[--boundary_layer_initial_height_on_surface_tags <list>] \
[--boundary_layer_geometric_progression <real>] \
- [--boundary_layer_max_element_angle <size>] [--boundary_layer_imprinting <boolean>] \
- [--boundary_layer_imprinting_tags <list>] [--boundary_layer_snapping <boolean>] \
- [--boundary_layer_snapping_tags <list>] [--normal_direction <dir>] [--gradation <real>] \
- [--element_generation <type>] [--collision_mode <mode>] [--add_multinormals <yes|no>] \
+ [--boundary_layer_max_element_angle <size>] \
+ [--boundary_layer_imprinting <boolean>] \
+ [--boundary_layer_imprinting_tags <list>] \
+ [--boundary_layer_snapping <boolean>] \
+ [--boundary_layer_snapping_tags <list>] [--normal_direction <dir>] \
+ [--gradation <real>] [--element_generation <type>] \
+ [--collision_mode <mode>] [--add_multinormals <yes|no>] \
[--multinormal_angle_threshold <angle>] [--smooth_normals <yes|no>] \
[--optimisation <type>]
--boundary_layer_size_mode <mode>
Sets the behavior for the boundary layer sizes.
If <mode> is:
- global: the boundary_layer_global_initial_height is used to compute the layer heights
+ global: the boundary_layer_global_initial_height is used to compute
+ the layer heights
local: the boundary_layer_surface_tags and
- boundary_layer_initial_height_on_surface_tags are used to compute the layer heights
+ boundary_layer_initial_height_on_surface_tags are used to compute
+ the layer heights
Default: global
--boundary_layer_height_relative_to_local_surface_size <yes|no>
Sets the height of the first layer.
--boundary_layer_surface_tags <list>
- Comma separated list of surface references to be used to grow boundary layers.
+ Comma separated list of surface references to be used to grow
+ boundary layers.
--boundary_layer_initial_height_on_surface_tags <list>
- Comma separated list of initial heights to be used to grow boundary layers.
+ Comma separated list of initial heights to be used to grow boundary
+ layers.
--boundary_layer_geometric_progression <real>
- Sets the geometric progression for all the boundary layer growths (position of layer
- number i is h * g^(i-1)).
+ Sets the geometric progression for all the boundary layer growths
+ (position of layer number i is h * g^(i-1)).
Default: 1.0
--boundary_layer_max_element_angle <size>
- Sets the maximum internal angles of elements (in degree). This setting applies to the
- boundary layer elements only.
+ Sets the maximum internal angles of elements (in degree). This
+ setting applies to the boundary layer elements only.
Default: 165.
--boundary_layer_imprinting <boolean>
- Activates the imprinting of the boundary layers. The parts of the surface where the
- layers have to be imprinted are defined through the option
- --boundary_layer_imprinting_tags
+ Activates the imprinting of the boundary layers. The parts of the
+ surface where the layers have to be imprinted are defined through the
+ option --boundary_layer_imprinting_tags
Default: no imprinting
--boundary_layer_imprinting_tags <list>
- Comma separated list of surface references that have to be imprinted by boundary layers.
+ Comma separated list of surface references that have to be imprinted
+ by boundary layers.
--boundary_layer_snapping <boolean>
- Activates the snapping of the generated boundary layers on the surface. The parts of the
- surface where the layers have to be snapped into are defined through the option
- --boundary_layer_snapping_tags
+ Activates the snapping of the generated boundary layers on the
+ surface. The parts of the surface where the layers have to be snapped
+ into are defined through the option --boundary_layer_snapping_tags
Default: no snapping
--boundary_layer_snapping_tags <list>
- Comma separated list of surface references that are imprinted by boundary layers.
+ Comma separated list of surface references that are imprinted by
+ boundary layers.
--normal_direction <dir>
- Specifies whether mg-hybrid should use the surface normals or the inverse of the surface
- normals.
+ Specifies whether mg-hybrid should use the surface normals or the
+ inverse of the surface normals.
if <dir> is:
- 1 : means the layers grow in the same direction as the normals to the surface
- -1 : means the layers grow in the opposite direction to the normals of the surface
+ 1 : means the layers grow in the same direction as the normals to
+ the surface
+ -1 : means the layers grow in the opposite direction to the normals
+ of the surface
Default: 1
--gradation <real>
- Sets the desired maximum ratio between 2 adjacent edges. It applies only to the edges
- which belong to the tetrahedra.
+ Sets the desired maximum ratio between 2 adjacent edges. It applies
+ only to the edges which belong to the tetrahedra.
Default: 2.0
--element_generation <type>
Sets the element type for the mesh generation.
If <type> is:
- tetra_dominant : prismatic or hexahedral elements in the boundary layers, tetrahedra in
- the remaining volume
- hexa_dominant : prismatic or hexahedral elements in the boundary layers, mixture of
- hexahedra and tetrahedra in the remaining volume
- cartesian_core : cartesian hexa core with tetrahedra and pyramids in the remaining
+ tetra_dominant : prismatic or hexahedral elements in the boundary
+ layers, tetrahedra in the remaining volume
+ hexa_dominant : prismatic or hexahedral elements in the boundary
+ layers, mixture of hexahedra and tetrahedra in the remaining
volume
- extrusion_only : only prismatic or hexahedral elements near the boundary are generated.
- The remaining volume is not filled.
+ cartesian_core : cartesian hexa core with tetrahedra and pyramids
+ in the remaining volume
+ extrusion_only : only prismatic or hexahedral elements near the
+ boundary are generated. The remaining volume is not filled.
Default: tetra_dominant
--collision_mode <mode>
Sets the behavior in case of collision between layers.
If <mode> is:
- decrease : keeps the number of desired layer but decreases the height of the layers to
- avoid any collision
- stop : stops locally the generation of layers to avoid collisions; the number of
- generated layers may differ from the specified desired number
+ decrease : keeps the number of desired layer but decreases the
+ height of the layers to avoid any collision
+ stop : stops locally the generation of layers to avoid collisions;
+ the number of generated layers may differ from the specified
+ desired number
Default: stop
--add_multinormals <yes|no>
Default: yes.
-================================================================================
- MG-Hybrid -- MeshGems 2.9-6 (August, 2019)
- END OF SESSION - MG-Hybrid (Copyright 2014-2019 by Distene SAS)
- compiled Sep 2 2019 23:42:41 on Linux_64
- MeshGems is a Registered Trademark of Distene SAS
-================================================================================
- ( Distene SAS
- Phone: +33(0)970-650-219 Fax: +33(0)169-269-033
- EMail: <support@distene.com> )
+====================================================================================
+ MG-Hybrid -- MeshGems 2.15-1 (January, 2023)
+ END OF SESSION - MG-Hybrid (Copyright 2014-2023 by Dassault Systemes SE)
+ compiled Jan 18 2023 13:33:47 on Linux_64
+ MeshGems is a commercial trademark of Dassault Systemes SE
+====================================================================================
-\endverbatim
-\ref hybrid_top "Back to top"
-
-\section hybrid_advanced_parameters Advanced parameters
-
-\image html hybrid_hypothesis_advanced.png
-
-\subsection advanced_meshing_options Advanced meshing options
-
-- A table allows to input in the command line any text
- for hybrid argument from "mg-hybrid.exe help", and future advanced options... <br>
-<b>Add option</b> - adds a line to the table where you can type an option and its value as text.
-A check box in the first column activates/deactivates the option of the current row. A deactivated option will be erased upon pressing \a Ok.
-
-- <b>Add multi normals</b> - Add extra normals at opening ridges and
-corners.
-
-- <b>Collision mode</b> - Sets the behavior in case of collision between layers.
-
- - <b>decrease</b> - keeps the number of desired layer but decreases the height of the layers to
- avoid any collision
-
- - <b>stop</b> - stops locally the generation of layers to avoid collisions; the number of
- generated layers may differ from the specified desired number
-
-- <b>Gradation</b> - Sets the desired maximum ratio between 2 adjacent edges.
- It applies only to the edges which belong to the tetrahedra.
-
-- <b>Maximum number of threads</b> - Sets the maximum number of threads to be used in parallel.
-
-- <b>Multi normal angle threshold</b> - Set the maximum angle (in
- degrees) between the multiple normals at opening ridges.
-
-- <b>Smooth normals</b> - Smooth normals at closed ridges and corners.
-
-\subsection log Logs and debug
-
-- <b>Working directory</b> - allows defining the folder for input and output
-files of hybrid software, which are the files starting with "HYBRID_" prefix.
-
-- <b>Verbose level</b> - to choose verbosity level in the range from
-0 to 10.
-
- - 0, no standard output,
-
- - 2, prints the data, quality statistics of the skin and final
- meshes and indicates when the final mesh is being saved. In addition
- the software gives indication regarding the CPU time.
-
- - 10, same as 2 plus the main steps in the computation, quality
- statistics histogram of the skin mesh, quality statistics histogram
- together with the characteristics of the final mesh.
-
-- <b>Print log in a file</b> - if this option is checked on the log is printed in a
-file placed in the working directory, otherwise it is printed on the standard output.
-
-- <b>Remove log on success</b> - if this option is checked on the log file is kept only
-if an error occurs during the computation. This option is only available if <b>Print log in a file</b>
-is enabled (there must be a log file to delete it) and <b>Keep all working files</b> is disabled
-(in this case the log file is always kept).
-
-- <b>Keep all working files</b> - allows checking input and output files
-of hybrid software, while usually these files are removed after the
-launch of the mesher. The log file (if any) is also kept if this option is checked.
-
-\ref hybrid_top "Back to top"
-
-\section hybrid_layers_meshes Layers meshes
-
-\image html hybrid_hypothesis_layers.png
-
-HYBRID algorithm mesh layers on groups of faces. If <b>Mesh layers on all wrap</b>
-is checked, all wrap is meshed as layers (as boundary_layers_surface_ids 5), else
-only submeshes selected an added are meshed as layers (as boundary_layers_surface_ids 6).
-Pay attention: theses groups should be defined
-into the shell mesh from a previous group defined in the geometry.
-
-
-\ref hybrid_top "Back to top"
-
-\section hybrid_layers_faces Faces with layers
-
-\image html hybrid_hypothesis_faces.png
-
-In case of a mesh based on geometry, if <b>Mesh layers on all wrap</b>
-on <b>Layers meshes</b> tab is unchecked, you can specify geometrical
-faces on which boundary layers should be constructed. After clicking
-\a Selection button (arrow) you can select faces either in the
-Viewer or in the Object Browser. \b Add button adds IDs of the
-selected faces to the <b>Face IDs</b> list. \b Remove button removes
-selected IDs from the list.
-
-<br><b>See Also</b> a sample TUI Script of the \ref tui_hybrid "creation of a MG-Hybrid hypothesis".
+\endverbatim
\ref hybrid_top "Back to top"
*/
void SetToMeshHoles(in boolean toMesh);
boolean GetToMeshHoles();
+ /*!
+ * To call MG-Hybrid by library. Default is no (i.e. by executable)
+ */
+ void SetToUseLibrary(in boolean toUseLib);
+ boolean GetToUseLibrary();
/*!
* To mesh layers on all wrap Default is yes.
*/
</property>
</widget>
</item>
+ <item row="3" column="0">
+ <widget class="QCheckBox" name="useLibraryCheck">
+ <property name="text">
+ <string>HYBRID_USE_LIBRARY</string>
+ </property>
+ <property name="autoExclusive">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
myAdvWidget->verboseLevelSpin ->setValue ( data.myVerboseLevel );
myAdvWidget->logInFileCheck ->setChecked( !data.myLogInStandardOutput );
myAdvWidget->removeLogOnSuccessCheck ->setChecked( data.myRemoveLogOnSuccess );
+ myAdvWidget->useLibraryCheck ->setChecked( data.myUseLib );
if ( myOptions.operator->() ) {
for ( int i = 0, nb = myOptions->length(); i < nb; ++i )
h_data.myVerboseLevel = h->GetVerboseLevel();
h_data.myLogInStandardOutput = h->GetStandardOutputLog();
h_data.myRemoveLogOnSuccess = h->GetRemoveLogOnSuccess();
+ h_data.myUseLib = h->GetToUseLibrary();
HYBRIDPluginGUI_HypothesisCreator* that = (HYBRIDPluginGUI_HypothesisCreator*)this;
that->myOptions = h->GetOptionValues();
h->SetStandardOutputLog ( h_data.myLogInStandardOutput );
if ( h->GetRemoveLogOnSuccess() != h_data.myRemoveLogOnSuccess )
h->SetRemoveLogOnSuccess ( h_data.myRemoveLogOnSuccess );
+ if ( h->GetToUseLibrary() != h_data.myUseLib )
+ h->SetToUseLibrary ( h_data.myUseLib );
// Enforced vertices
//int nbVertex = (int) h_data.myEnforcedVertices.size();
h_data.myVerboseLevel = myAdvWidget->verboseLevelSpin->value();
h_data.myLogInStandardOutput = !myAdvWidget->logInFileCheck->isChecked();
h_data.myRemoveLogOnSuccess = myAdvWidget->removeLogOnSuccessCheck->isChecked();
+ h_data.myUseLib = myAdvWidget->useLibraryCheck->isChecked();
// Enforced vertices
h_data.myEnforcedVertices.clear();
typedef struct
{
bool myHeightIsRelative, myImprinting, mySnapping, myLayersOnAllWrap,
- myKeepFiles, myLogInStandardOutput, myRemoveLogOnSuccess;
+ myKeepFiles, myLogInStandardOutput, myRemoveLogOnSuccess, myUseLib;
int myOptimizationLevel, myCollisionMode, myBoundaryLayersGrowth, myElementGeneration;
QString myName,myWorkingDir;
double myGradation;
<source>KEEP_WORKING_FILES</source>
<translation>Keep all working files</translation>
</message>
+ <message>
+ <source>HYBRID_USE_LIBRARY</source>
+ <translation>Use library</translation>
+ </message>
<message>
<source>COLLISION_MODE</source>
<translation>Behavior in case of collision between layers</translation>
<source>KEEP_WORKING_FILES</source>
<translation>Conserver tous les fichiers temporaires</translation>
</message>
+ <message>
+ <source>HYBRID_USE_LIBRARY</source>
+ <translation>Utiliser la librairie</translation>
+ </message>
<message>
<source>COLLISION_MODE</source>
<translation>Comportement en cas de collision entre les couches</translation>
<source>KEEP_WORKING_FILES</source>
<translation>すべての作業ファイルを維持</translation>
</message>
+ <message>
+ <source>HYBRID_USE_LIBRARY</source>
+ <translation>図書館を利用する</translation>
+ </message>
<message>
<source>COLLISION_MODE</source>
<translation>レイヤー間の干渉時の振る舞い</translation>
pass
return self.params
+ ## To call MG-Hybrid by library. Default is no (i.e. by executable)
+ # @param toUseLib "mesh layers on all wrap" flag value
+ def SetToUseLibrary(self, toUseLib):
+ self.Parameters().SetToUseLibrary(toUseLib)
+ pass
+
## To mesh layers on all wrap. Default is to mesh.
# @param toMesh "mesh layers on all wrap" flag value
def SetLayersOnAllWrap(self, toMesh):
MG_HYBRID_API mgHybrid( _computeCanceled, _progress );
+ bool useLibrary = HYBRIDPlugin_Hypothesis::GetToUseLibrary(_hyp);
+ if (useLibrary)
+ mgHybrid.SetUseLibrary();
+ else
+ mgHybrid.SetUseExecutable();
+
Ok = writeGMFFile(&mgHybrid,
aGMFFileName.c_str(),
aRequiredVerticesFileName.c_str(),
myToCreateNewNodes(DefaultToCreateNewNodes()),
myToUseBoundaryRecoveryVersion(DefaultToUseBoundaryRecoveryVersion()),
myToUseFemCorrection(DefaultToUseFEMCorrection()),
- myToRemoveCentralPoint(DefaultToRemoveCentralPoint())
+ myToRemoveCentralPoint(DefaultToRemoveCentralPoint()),
+ myUseLib(DefaultToUseLib())
{
_name = "HYBRID_Parameters";
_param_algo_dim = 3;
}
}
+//=======================================================================
+//function : SetToUseLibrary
+//=======================================================================
+
+void HYBRIDPlugin_Hypothesis::SetToUseLibrary(bool toUseLib)
+{
+ if ( myUseLib != toUseLib ) {
+ myUseLib = toUseLib;
+ NotifySubMeshesHypothesisModification();
+ }
+}
+
+//=======================================================================
+//function : GetToUseLibrary
+//=======================================================================
+
+bool HYBRIDPlugin_Hypothesis::GetToUseLibrary() const
+{
+ return myUseLib;
+}
+
+//=======================================================================
+//function : GetToUseLibrary
+//=======================================================================
+
+bool HYBRIDPlugin_Hypothesis::GetToUseLibrary(const HYBRIDPlugin_Hypothesis* hyp)
+{
+ bool res;
+ if ( hyp )
+ res = hyp->GetToUseLibrary();
+ else
+ res = DefaultToUseLib();
+ return res;
+}
+
//=======================================================================
//function : SetLayersOnAllWrap
_groupsToRemove.clear();
}
+//=======================================================================
+//function : DefaultToUseLib
+//=======================================================================
+
+bool HYBRIDPlugin_Hypothesis::DefaultToUseLib()
+{
+ // default is false but it can be change by environment variable
+ if (getenv("MG_HYBRID_USE_LIB"))
+ return true;
+ return false;
+}
//=======================================================================
//function : DefaultLayersOnAllWrap
for ( o2v = _customOption2value.begin(); o2v != _customOption2value.end(); ++o2v )
save << " -" << o2v->first << " -" << o2v->second;
+ // New in SALOME 9.13
+ save << " " << myUseLib;
+
return save;
}
}
}
+ // New in SALOME 9.13
+ if ( static_cast<bool>(load >> i))
+ myUseLib = (bool) i;
+
return load;
}
if ( !faceLayersIDs.empty() )
cmd << " --boundary_layer_surface_tags ";
for ( size_t i = 0; i < faceLayersIDs.size(); ++i )
- cmd << faceLayersIDs[i] << ",";
+ {
+ cmd << faceLayersIDs[i];
+ if (i<faceLayersIDs.size()-1)
+ cmd << ",";
+ }
// Don't need to set the height of the layer face by face since:
// - the same height is already set on all the faces with boundary_layer_global_initial_height
// - we don't allow the user to set different heights for specific faces for now
if ( !faceImprintingIDs.empty() )
cmd << " --boundary_layer_imprinting yes --boundary_layer_imprinting_tags ";
for ( size_t i = 0; i < faceImprintingIDs.size(); ++i )
- cmd << faceImprintingIDs[i] << ",";
+ {
+ cmd << faceImprintingIDs[i];
+ if (i<faceImprintingIDs.size()-1)
+ cmd << ",";
+ }
// faces with snapping
const std::vector<int>& faceSnappingIDs = hyp->GetFacesWithSnapping();
if ( !faceSnappingIDs.empty() )
cmd << " --boundary_layer_snapping yes --boundary_layer_snapping_tags ";
for ( size_t i = 0; i < faceSnappingIDs.size(); ++i )
- cmd << faceSnappingIDs[i] << ",";
+ {
+ cmd << faceSnappingIDs[i];
+ if (i<faceSnappingIDs.size()-1)
+ cmd << ",";
+ }
}
}
op_val = _customOption2value.find(optionName);
if (op_val == _customOption2value.end())
{
- std::string msg = "Unknown MG-Tetra option: <" + optionName + ">";
+ std::string msg = "Unknown MG-Hybrid option: <" + optionName + ">";
+ MESSAGE(msg);
throw std::invalid_argument(msg);
}
}
if (op_val != _defaultOptionValues.end())
val = op_val->second;
}
+ MESSAGE("GetOptionValue " << optionName << " = " << val);
return val;
}
*/
void SetBoundaryLayersMaxElemAngle( double angle );
double GetBoundaryLayersMaxElemAngle() const { return myBoundaryLayersMaxElemAngle; }
+ /*!
+ * To call MG-Hybrid by library. Default is no (i.e. by executable)
+ */
+ void SetToUseLibrary(bool toUseLib);
+ bool GetToUseLibrary() const;
/*!
* To mesh layers on all wrap. Default is yes.
*/
static TID2SizeMap GetNodeIDToSizeMap(const HYBRIDPlugin_Hypothesis* hyp);
static TSetStrings GetGroupsToRemove(const HYBRIDPlugin_Hypothesis* hyp);
static bool GetToMakeGroupsOfDomains(const HYBRIDPlugin_Hypothesis* hyp);
+ static bool GetToUseLibrary(const HYBRIDPlugin_Hypothesis* hyp);
void ClearGroupsToRemove();
static bool DefaultHeightIsRelative() { return false; }
static double DefaultBoundaryLayersMaxElemAngle() { return 165.0; }
static bool DefaultMeshHoles();
+ static bool DefaultToUseLib();
static bool DefaultLayersOnAllWrap();
static bool DefaultToMakeGroupsOfDomains();
static double DefaultMaximumMemory();
bool myToUseBoundaryRecoveryVersion; // missing from hybrid
bool myToUseFemCorrection; // missing from hybrid
bool myToRemoveCentralPoint; // missing from hybrid
+ bool myUseLib;
THYBRIDEnforcedVertexList _enfVertexList;
return this->GetImpl()->GetBoundaryLayersMaxElemAngle();
}
+//=======================================================================
+//function : SetToUseLibrary
+//=======================================================================
+
+void HYBRIDPlugin_Hypothesis_i::SetToUseLibrary(CORBA::Boolean toUseLib)
+{
+ ASSERT(myBaseImpl);
+ this->GetImpl()->SetToUseLibrary(toUseLib);
+ SMESH::TPythonDump() << _this() << ".SetToUseLibrary( " << toUseLib << " )";
+}
+
+//=======================================================================
+//function : GetToUseLibrary
+//=======================================================================
+
+CORBA::Boolean HYBRIDPlugin_Hypothesis_i::GetToUseLibrary()
+{
+ ASSERT(myBaseImpl);
+ return this->GetImpl()->GetToUseLibrary();
+}
+
//=======================================================================
//function : SetLayersOnAllWrap
//=======================================================================
*/
void SetFacesWithSnapping(const SMESH::long_array& faceIDs);
SMESH::long_array* GetFacesWithSnapping();
+ /*!
+ * To call MG-Hybrid by library. Default is no (i.e. by executable)
+ */
+ void SetToUseLibrary(CORBA::Boolean toUseLib);
+ CORBA::Boolean GetToUseLibrary();
/*!
* To mesh "layers on all wrap". Default is to mesh.
*/
#include <SMESH_File.hxx>
#include <SMESH_MGLicenseKeyGen.hxx>
#include <Utils_SALOME_Exception.hxx>
+#include "utilities.h"
#include <cstring>
#include <iostream>
#include <iterator>
#include <vector>
+#include <sstream>
#ifdef USE_MG_LIBS
{
SMESH_Comment msg("\nMeshGems error. ");
msg << txt << "\n";
+ std::cout << msg;
AddError( msg.c_str() );
}
+ //================================================================================
+ /*!
+ * \brief SetParam to define a parameter by its value
+ * \param [in] param - the parameter to set
+ * \param [in] valus - its value
+ * \return bool - Ok or not
+ */
+ //================================================================================
bool SetParam( const std::string& param, const std::string& value )
{
status_t ret = hybrid_set_param( _session, param.c_str(), value.c_str() );
-#ifdef _DEBUG_
- //std::cout << param << " = " << value << std::endl;
-#endif
+ MESSAGE(param << " = " << value);
return ( ret == STATUS_OK );
}
+
+ //================================================================================
+ /*!
+ * \brief SetTags to define boundary layers
+ * \param [in] param - the parameter to set
+ * \param [in] values - a list of ids separated by a comma
+ * \param [in] size - the size of the boundary layer
+ * \return bool - Ok or not
+ */
+ //================================================================================
+ bool SetTags( const std::string& param, const std::string& values, const std::string& size )
+ {
+ // constructing stream from the string
+ std::stringstream ss(values);
+ std::string s;
+ // for each string value separated by ',' call hybrid API to set the tag
+ while (getline(ss, s, ','))
+ {
+ status_t ret;
+ int tag = stoi(s);
+ if ( param=="boundary_layer_imprinting_tags" )
+ {
+ ret = hybrid_set_boundary_layer_imprinting_tag(_session, tag);
+ MESSAGE("imprinting " << tag);
+ }
+ else if ( param=="boundary_layer_snapping_tags" )
+ {
+ ret = hybrid_set_boundary_layer_snapping_tag(_session, tag);
+ MESSAGE("snapping " << tag);
+ }
+ else if ( param=="boundary_layer_surface_tags" )
+ {
+ ret = hybrid_set_initial_height_on_surface_tag(_session, tag, stod(size));
+ MESSAGE("height " << tag << " = " << stod(size));
+ }
+ if ( ret != STATUS_OK )
+ {
+ MESSAGE("PBBBBBBBBBBBBBBBBBBBBBB STATUS not OK ");
+ return false;
+ }
+ }
+ return true;
+ }
+
bool Cancelled()
{
return _cancelled_flag;
return nb;
}
+ int ReadNbPyramids()
+ {
+ integer nb = 0;
+ status_t ret = mesh_get_pyramid_count( _hybrid_mesh, & nb );
+
+ if ( ret != STATUS_OK ) MG_Error("mesh_get_pyramid_count problem");
+ return nb;
+ }
+
int ReadNbCorners()
{
return _corners.size();
status_t my_message_cb(message_t * msg, void *user_data)
{
char *desc;
+ integer e, n, m;
+ integer i, i_data[10];
+ real r_data[10];
+ n = m = 0;
+ message_get_description(msg, &desc);
+ message_get_number(msg, &e);
+
+ if (e < 0) {
+ printf("mg-hybrid ERROR %i : %s", MESHGEMS_ABS_CODE(e), desc);
+ message_get_integer_data_count(msg, &n);
+ message_get_real_data_count(msg, &m);
+ printf("MGMESSAGE %i ", e);
+ printf(" %i", n);
+ if (n > 0) {
+ message_get_integer_data(msg, 1, n, i_data);
+ for (i = 0; i < n; i++)
+ printf(" %i", i_data[i]);
+ }
+ printf(" %i", m);
+ if (m > 0) {
+ message_get_real_data(msg, 1, m, r_data);
+ for (i = 0; i < m; i++)
+ printf(" %f", r_data[i]);
+ }
+ printf(" \n");
+
+ }
+ if (e >= 0) {
+ if (e == 0)
+ printf("\rmg-hybrid info : %s", desc);
+ else
+ printf("mg-hybrid info %i : %s", MESHGEMS_CODE(e), desc);
+ }
message_get_description(msg, &desc);
MG_HYBRID_API::LibData* data = (MG_HYBRID_API::LibData *) user_data;
{
_useLib = false;
_libData = new LibData( cancelled_flag, progress );
-#ifdef USE_MG_LIBS
- _useLib = true;
- _libData->Init();
- if ( getenv("MG_HYBRID_USE_EXE"))
- _useLib = false;
-#endif
}
//================================================================================
MG_HYBRID_API::~MG_HYBRID_API()
{
-#ifdef USE_MG_LIBS
delete _libData;
_libData = 0;
-#endif
std::set<int>::iterator id = _openFiles.begin();
for ( ; id != _openFiles.end(); ++id )
::GmfCloseMesh( *id );
return _useLib;
}
+//================================================================================
+/*!
+ * \brief Switch to usage of MG-HYBRID library
+ */
+//================================================================================
+
+void MG_HYBRID_API::SetUseLibrary()
+{
+ _useLib = true;
+#ifdef USE_MG_LIBS
+ _libData->Init();
+#endif
+}
+
//================================================================================
/*!
* \brief Switch to usage of MG-HYBRID executable
{
if ( _useLib ) {
#ifdef USE_MG_LIBS
-
// split cmdLine
std::istringstream strm( cmdLine );
std::istream_iterator<std::string> sIt( strm ), sEnd;
// set parameters
std::string param, value;
- for ( size_t i = 1; i < args.size(); ++i )
+ std::string boundary_layer_size;
+
+ for ( size_t i = 1; i < args.size(); i=i+2 )
{
- // look for a param name; it starts from "-"
param = args[i];
- if ( param.size() < 2 || param[0] != '-')
+ value = args[i+1];
+ MESSAGE("param: " << param);
+ MESSAGE("value: " << value);
+
+ // skipping output redirection, it is not a param to set
+ if (param=="1>")
continue;
+
+ // removing -- from param
while ( param[0] == '-')
param = param.substr( 1 );
- value = "";
- while ( i+1 < args.size() && args[i+1][0] != '-' )
+ // store this value for boundary layer definition (needed by setTags after)
+ if (param == "boundary_layer_global_initial_height")
+ boundary_layer_size = value;
+
+ // set parameters with list of tags (string of ids separated by a comma)
+ if (param=="boundary_layer_imprinting_tags" || param=="boundary_layer_snapping_tags" || param=="boundary_layer_surface_tags")
{
- if ( strncmp( "1>", args[i+1].c_str(), 2 ) == 0 )
- break;
- if ( !value.empty() ) value += " ";
- value += args[++i];
+ if (!_libData->SetTags(param, value, boundary_layer_size))
+ std::cout << "Warning: error in SetTags(" << param << ", " << value << ", " << boundary_layer_size << ")" << std::endl;
}
- if ( !_libData->SetParam( param, value ))
+ // set other parameters
+ else if ( !_libData->SetParam( param, value ))
std::cout << "Warning: wrong param: '" << param <<"' = '" << value << "'" << std::endl;
}
#endif
}
+ // not library => call executable
+
// add MG license key
{
std::string errorTxt, meshIn;
case GmfQuadrilaterals: return _libData->ReadNbQuads();
case GmfTetrahedra: return _libData->ReadNbTetra();
case GmfPrisms: return _libData->ReadNbPrisms();
+ case GmfPyramids: return _libData->ReadNbPyramids();
case GmfHexahedra: return _libData->ReadNbHexa();
case GmfCorners: return _libData->ReadNbCorners();
default: return 0;
bool IsLibrary();
bool IsExecutable() { return !IsLibrary(); }
+ void SetUseLibrary();
void SetUseExecutable();
// IN to MESHGEMS
geom_groups = [Inlet_x, Inlet_z, Outlet, Wall]
d_geom_groups = {}
+for geom_group in geom_groups:
+ name = geom_group.GetName()
+ d_geom_groups[name] = geom_group
+
+shape_volume = geompy.BasicProperties(piquage)[2]
###
### SMESH component
MG_Hybrid_Parameters_1.SetNbOfBoundaryLayers( 3 )
MG_Hybrid_Parameters_1.SetFacesWithLayers( wall_ids )
+Mesh_1.Compute()
-isDone = Mesh_1.Compute()
+def checkMesh_1(Mesh_1):
+ Mesh_1.CheckCompute()
-if not isDone:
- raise Exception("Error when computing Mesh_without_imprinting")
+ d_groups_1 = {}
-d_groups_1 = {}
+ for geom_group in geom_groups:
+ name = geom_group.GetName()
+ gr = Mesh_1.Group(geom_group)
+ d_groups_1[name] = gr
+ d_geom_groups[name] = geom_group
-for geom_group in geom_groups:
- name = geom_group.GetName()
- gr = Mesh_1.Group(geom_group)
- d_groups_1[name] = gr
- d_geom_groups[name] = geom_group
+ assert Mesh_1.NbQuadrangles() == 0
-assert Mesh_1.NbQuadrangles() == 0
+ # Compare whole mesh volume
+ volume_error_1 = abs(shape_volume-Mesh_1.GetVolume())/shape_volume
-shape_volume = geompy.BasicProperties(piquage)[2]
+ assert volume_error_1 < 0.02
-# Compare whole mesh volume
-volume_error_1 = abs(shape_volume-Mesh_1.GetVolume())/shape_volume
+ return d_groups_1
-assert volume_error_1 < 0.02
+d_groups_1 = checkMesh_1(Mesh_1)
+
+# Compute same mesh with library
+MG_Hybrid_Parameters_1.SetToUseLibrary(True)
+Mesh_1.Clear()
+Mesh_1.Compute()
+d_groups_1 = checkMesh_1(Mesh_1)
# Viscous layers with imprinting
# ==============================
isDone = Mesh_2.Compute()
-if not isDone:
- raise Exception("Error when computing Mesh_with_imprinting")
+mesh_2_volume = Mesh_2.GetVolume()
+faces_imprinted = ["Inlet_x", "Inlet_z", "Outlet"]
+
+def checkMesh_2(Mesh_2, d_groups_1):
+ Mesh_2.CheckCompute()
+ assert Mesh_2.NbQuadrangles() > 0
-assert Mesh_2.NbQuadrangles() > 0
+ d_groups_2 = {}
-d_groups_2 = {}
+ for geom_group in geom_groups:
+ name = geom_group.GetName()
+ gr = Mesh_2.Group(geom_group)
+ d_groups_2[name] = gr
-for geom_group in geom_groups:
- name = geom_group.GetName()
- gr = Mesh_2.Group(geom_group)
- d_groups_2[name] = gr
+ # Check viscous layers with imprinting
+ for name in faces_imprinted:
+ geom_area = geompy.BasicProperties(d_geom_groups[name])[1]
+ gr_1 = d_groups_1[name]
+ gr_2 = d_groups_2[name]
+ #assert gr_1.Size() > 0
+ assert gr_2.Size() > 0
+ # Nb of quadrangles is in 7th index of mesh info
+ assert gr_2.GetMeshInfo()[7] > 0
-faces_imprinted = ["Inlet_x", "Inlet_z", "Outlet"]
+ # Compare mesh group and geom group
+ area_error_1 = abs(geom_area-smesh.GetArea(gr_2))/geom_area
+ assert area_error_1 < 0.025
+ # Compare mesh group with imprinting and mesh group without imprinting
+ area_error_2 = abs(smesh.GetArea(gr_1)-smesh.GetArea(gr_2))/smesh.GetArea(gr_1)
+ assert area_error_2 < 1e-08
-# Check viscous layers with imprinting
-for name in faces_imprinted:
- geom_area = geompy.BasicProperties(d_geom_groups[name])[1]
- gr_1 = d_groups_1[name]
- gr_2 = d_groups_2[name]
- #assert gr_1.Size() > 0
- assert gr_2.Size() > 0
- # Nb of quadrangles is in 7th index of mesh info
- assert gr_2.GetMeshInfo()[7] > 0
-
- # Compare mesh group and geom group
- area_error_1 = abs(geom_area-smesh.GetArea(gr_2))/geom_area
- assert area_error_1 < 0.025
- # Compare mesh group with imprinting and mesh group without imprinting
- area_error_2 = abs(smesh.GetArea(gr_1)-smesh.GetArea(gr_2))/smesh.GetArea(gr_1)
- assert area_error_2 < 1e-08
-
-# Compare whole mesh volume
-mesh_2_volume = Mesh_2.GetVolume()
-volume_error_2 = abs(shape_volume-mesh_2_volume)/shape_volume
+ # Compare whole mesh volume
+ volume_error_2 = abs(shape_volume-mesh_2_volume)/shape_volume
+
+ assert volume_error_2 < 0.02
-assert volume_error_2 < 0.02
+ return d_groups_2
+
+d_groups_2 = checkMesh_2(Mesh_2, d_groups_1)
+
+# Compute same mesh with library
+MG_Hybrid_Parameters_2.SetToUseLibrary(True)
+Mesh_2.Clear()
+Mesh_2.Compute()
+d_groups_2 = checkMesh_2(Mesh_2, d_groups_1)
# Viscous layers with imprinting set by groups
# ============================================
isDone = Mesh_3.Compute()
-if not isDone:
- raise Exception("Error when computing Mesh_with_imprinting_set_by_groups")
+def checkMesh_3(Mesh_3, d_groups_2):
+ Mesh_3.CheckCompute()
-d_groups_3 = {}
+ d_groups_3 = {}
-for geom_group in geom_groups:
- name = geom_group.GetName()
- gr = Mesh_3.Group(geom_group)
- d_groups_3[name] = gr
+ for geom_group in geom_groups:
+ name = geom_group.GetName()
+ gr = Mesh_3.Group(geom_group)
+ d_groups_3[name] = gr
+
+ # Compare whole mesh volume
+ mesh_3_volume = Mesh_3.GetVolume()
+ volume_error_3 = abs(mesh_2_volume-mesh_3_volume)/mesh_2_volume
+
+ assert math.isclose(mesh_3_volume,mesh_2_volume,rel_tol=1e-7)
-# Compare whole mesh volume
-mesh_3_volume = Mesh_3.GetVolume()
-volume_error_3 = abs(mesh_2_volume-mesh_3_volume)/mesh_2_volume
+ # Check viscous layers with imprinting
+ for name in faces_imprinted:
+ gr_2 = d_groups_2[name]
+ gr_3 = d_groups_3[name]
+ assert gr_3.Size() > 0
+ # Nb of quadrangles is in 7th index of mesh info
+ assert gr_2.GetMeshInfo()[7] == gr_3.GetMeshInfo()[7]
-assert math.isclose(mesh_3_volume,mesh_2_volume,rel_tol=1e-7)
+ # Compare mesh group with imprinting set by ids and mesh group with imprinting set by geom group
+ assert math.isclose( smesh.GetArea(gr_2), smesh.GetArea(gr_3))
-# Check viscous layers with imprinting
-for name in faces_imprinted:
- gr_2 = d_groups_2[name]
- gr_3 = d_groups_3[name]
- assert gr_3.Size() > 0
- # Nb of quadrangles is in 7th index of mesh info
- assert gr_2.GetMeshInfo()[7] == gr_3.GetMeshInfo()[7]
+checkMesh_3(Mesh_3, d_groups_2)
- # Compare mesh group with imprinting set by ids and mesh group with imprinting set by geom group
- assert math.isclose( smesh.GetArea(gr_2), smesh.GetArea(gr_3))
+# Compute same mesh with library
+MG_Hybrid_Parameters_3.SetToUseLibrary(True)
+Mesh_3.Clear()
+Mesh_3.Compute()
+checkMesh_3(Mesh_3, d_groups_2)