From: Yoann Audouin Date: Mon, 16 Jan 2023 13:43:55 +0000 (+0100) Subject: Add documentation X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=5fa7f9af0ac181bf4444f97157fab1553a777463;p=modules%2Fsmesh.git Add documentation --- diff --git a/doc/examples/creating_parallel_mesh.py b/doc/examples/creating_parallel_mesh.py new file mode 100644 index 000000000..9cfc0ee80 --- /dev/null +++ b/doc/examples/creating_parallel_mesh.py @@ -0,0 +1,135 @@ +# contains function to compute a mesh in parallel +from platform import java_ver +import sys +from tkinter import W +import salome + +import time + + +salome.salome_init() +import salome_notebook +notebook = salome_notebook.NoteBook() + +### +### GEOM component +### + +import GEOM +from salome.geom import geomBuilder +from salome.smesh import smeshBuilder +import math +import SALOMEDS + +import numpy as np + +geompy = geomBuilder.New() + +smesh = smeshBuilder.New() + + +def build_seq_mesh(nbox, boxsize, offset): + # Create 3D faces + boxes = [] + # First creating all the boxes + for i in range(nbox): + for j in range(nbox): + for k in range(nbox): + + x_orig = i*(boxsize+offset) + y_orig = j*(boxsize+offset) + z_orig = k*(boxsize+offset) + + tmp_box = geompy.MakeBoxDXDYDZ(boxsize, boxsize, boxsize) + + if not i == j == k == 0: + box = geompy.MakeTranslation(tmp_box, x_orig, + y_orig, z_orig) + else: + box = tmp_box + + geompy.addToStudy(box, 'box_{}:{}:{}'.format(i, j, k)) + + boxes.append(box) + + # Create fuse of all boxes + all_boxes = geompy.MakeCompound(boxes) + geompy.addToStudy(all_boxes, 'Compound_1') + + # Removing duplicates faces and edges + all_boxes = geompy.MakeGlueFaces(all_boxes, 1e-07) + geompy.addToStudy(all_boxes, 'Glued_Faces_1') + + all_boxes = geompy.MakeGlueEdges(all_boxes, 1e-07) + geompy.addToStudy(all_boxes, 'rubik_cube') + + + # Building sequetial mesh + print("Creating mesh") + all_box_mesh = smesh.Mesh(all_boxes, "seq_mesh") + + print("Adding algo") + algo3d = all_box_mesh.Tetrahedron(algo=smeshBuilder.NETGEN_1D2D3D) + + netgen_parameters = algo3d.Parameters() + netgen_parameters.SetMaxSize(34.641) + netgen_parameters.SetMinSize(0.141421) + netgen_parameters.SetOptimize(1) + netgen_parameters.SetCheckOverlapping(0) + netgen_parameters.SetCheckChartBoundary(0) + netgen_parameters.SetFineness(5) + netgen_parameters.SetNbSegPerEdge(16*(boxsize//100)) + netgen_parameters.SetNbSegPerRadius(1.5) + netgen_parameters.SetGrowthRate(0.15) + netgen_parameters.SetChordalError(-1) + netgen_parameters.SetChordalErrorEnabled(0) + netgen_parameters.SetUseSurfaceCurvature(1) + netgen_parameters.SetQuadAllowed(0) + netgen_parameters.SetCheckOverlapping(False) + netgen_parameters.SetNbThreads(2) + + return all_boxes, all_box_mesh, netgen_parameters + +def run_test(nbox=2, boxsize=100): + """ Run sequential mesh and parallel version of it + + nbox: NUmber of boxes + boxsize: Size of each box + """ + geom, seq_mesh, netgen_parameters = build_seq_mesh(nbox, boxsize, 0) + + par_mesh = smesh.ParallelMesh(geom, name="par_mesh") + par_mesh.AddGlobalHypothesis(netgen_parameters) + par_mesh.SetNbThreads(6) + + start = time.monotonic() + is_done = seq_mesh.Compute() + assert is_done + stop = time.monotonic() + time_seq = stop-start + + start = time.monotonic() + is_done = par_mesh.Compute() + assert is_done + stop = time.monotonic() + time_par = stop-start + + print(" Tetrahedron: ", seq_mesh.NbTetras(), par_mesh.NbTetras()) + print(" Triangle: ", seq_mesh.NbTriangles(), par_mesh.NbTriangles()) + print(" edge: ", seq_mesh.NbEdges(), par_mesh.NbEdges()) + + assert par_mesh.NbTetras() > 0 + assert par_mesh.NbTriangles() > 0 + assert par_mesh.NbEdges() > 0 + + print("Time elapsed (seq, par): ", time_seq, time_par) + +def main(): + if sys.platform == "win32": + print("Test disabled on Windows") + return + nbox = 2 + boxsize = 100 + run_test(nbox, boxsize) + +main() diff --git a/doc/examples/tests.set b/doc/examples/tests.set index df39d9dd9..e051ca01c 100644 --- a/doc/examples/tests.set +++ b/doc/examples/tests.set @@ -129,6 +129,7 @@ SET(BAD_TESTS viewing_meshes_ex01.py radial_prism_3d_algo.py create_dual_mesh.py + creating_parallel_mesh.py ) IF(NOT WIN32) LIST(APPEND BAD_TESTS diff --git a/doc/gui/images/diagram_parallel_mesh.png b/doc/gui/images/diagram_parallel_mesh.png new file mode 100644 index 000000000..466b29b97 Binary files /dev/null and b/doc/gui/images/diagram_parallel_mesh.png differ diff --git a/doc/gui/input/about_meshes.rst b/doc/gui/input/about_meshes.rst index 619bd799f..6350eea4b 100644 --- a/doc/gui/input/about_meshes.rst +++ b/doc/gui/input/about_meshes.rst @@ -71,6 +71,8 @@ Quadratic mesh can be obtained in three ways: * Using :ref:`convert_to_from_quadratic_mesh_page` operation. * Using an appropriate option of some meshing algorithms, which generate elements of several dimensions starting from mesh segments. +A work in progress allow you to compute your mesh in parralle :ref:`Parallel Computing` + **Table of Contents** @@ -86,3 +88,4 @@ Quadratic mesh can be obtained in three ways: copy_mesh.rst create_dual_mesh.rst connectivity.rst + parallel_compute.rst diff --git a/doc/gui/input/parallel_compute.rst b/doc/gui/input/parallel_compute.rst new file mode 100644 index 000000000..82d1abfb9 --- /dev/null +++ b/doc/gui/input/parallel_compute.rst @@ -0,0 +1,69 @@ +.. _parallel_compute_page: + +****************** +Parallel Computing +****************** + + +.. warning:: + This functionality is a work in progress. + + It is only available for NETGEN. + + It is only available in TUI. + + +The goal here is to speed up computation by running sub-meshes in parallel +(multi-threading). + +******* +Concept +******* + +.. image:: ../images/diagram_parallel_mesh.png + +In order to parallelise the computation of the mesh we split the geometry into: + + * A 1D+2D compound + * A list of 3D solids + +Then create a sub-mesh for each of those geometry. +And associate Hypothesis to the mesh using a hypothesis on the whole geometry + +We will first compute sequentially the 1D+2D compound with NETGEN_1D2D. + +Then we will compute all the solids in parallel. Having done the 1D+2D first +ensure that all the solids can be computed without any concurrency. + + +****** +How to +****** + +You follow the same principle as the creation of a sequential Mesh. + + +#. First you create the mesh: + .. code-block:: python + + par_mesh = smesh.ParallelMesh(geom, name="par_mesh") + +#. Define the Global Hypothesis that will be split into an hypothesis for the + 1D+2D compound and one for each of the 3D solids: + .. code-block:: python + + NETGEN_3D_Parameters_1 = smesh.CreateHypothesisByAverageLength( 'NETGEN_Parameters', + 'NETGENEngine', 34.641, 0 ) + par_mesh.AddGlobalHypothesis(netgen_parameters) + +#. Set the parameters for the parallelisation: + .. code-block:: python + + par_mesh.SetNbThreads()Compute() + +#. Compute the mesh: + .. code-block:: python + + mesh.Compute() + +**See Also** a sample script of :ref:`tui_create_parallel_mesh`. diff --git a/doc/gui/input/tui_creating_meshes.rst b/doc/gui/input/tui_creating_meshes.rst index 253fbf260..67e14d358 100644 --- a/doc/gui/input/tui_creating_meshes.rst +++ b/doc/gui/input/tui_creating_meshes.rst @@ -117,3 +117,12 @@ Creating Dual Mesh :download:`Download this script <../../examples/create_dual_mesh.py>` +.. _tui_create_parallel_mesh: + +Creating Parallel Mesh +====================== + +.. literalinclude:: ../../examples/creating_parallel_mesh.py + :language: python + +:download:`Download this script <../../examples/creating_parallel_mesh.py>` diff --git a/test/SMESH_ParallelCompute.py b/test/SMESH_ParallelCompute.py deleted file mode 100644 index 9cfc0ee80..000000000 --- a/test/SMESH_ParallelCompute.py +++ /dev/null @@ -1,135 +0,0 @@ -# contains function to compute a mesh in parallel -from platform import java_ver -import sys -from tkinter import W -import salome - -import time - - -salome.salome_init() -import salome_notebook -notebook = salome_notebook.NoteBook() - -### -### GEOM component -### - -import GEOM -from salome.geom import geomBuilder -from salome.smesh import smeshBuilder -import math -import SALOMEDS - -import numpy as np - -geompy = geomBuilder.New() - -smesh = smeshBuilder.New() - - -def build_seq_mesh(nbox, boxsize, offset): - # Create 3D faces - boxes = [] - # First creating all the boxes - for i in range(nbox): - for j in range(nbox): - for k in range(nbox): - - x_orig = i*(boxsize+offset) - y_orig = j*(boxsize+offset) - z_orig = k*(boxsize+offset) - - tmp_box = geompy.MakeBoxDXDYDZ(boxsize, boxsize, boxsize) - - if not i == j == k == 0: - box = geompy.MakeTranslation(tmp_box, x_orig, - y_orig, z_orig) - else: - box = tmp_box - - geompy.addToStudy(box, 'box_{}:{}:{}'.format(i, j, k)) - - boxes.append(box) - - # Create fuse of all boxes - all_boxes = geompy.MakeCompound(boxes) - geompy.addToStudy(all_boxes, 'Compound_1') - - # Removing duplicates faces and edges - all_boxes = geompy.MakeGlueFaces(all_boxes, 1e-07) - geompy.addToStudy(all_boxes, 'Glued_Faces_1') - - all_boxes = geompy.MakeGlueEdges(all_boxes, 1e-07) - geompy.addToStudy(all_boxes, 'rubik_cube') - - - # Building sequetial mesh - print("Creating mesh") - all_box_mesh = smesh.Mesh(all_boxes, "seq_mesh") - - print("Adding algo") - algo3d = all_box_mesh.Tetrahedron(algo=smeshBuilder.NETGEN_1D2D3D) - - netgen_parameters = algo3d.Parameters() - netgen_parameters.SetMaxSize(34.641) - netgen_parameters.SetMinSize(0.141421) - netgen_parameters.SetOptimize(1) - netgen_parameters.SetCheckOverlapping(0) - netgen_parameters.SetCheckChartBoundary(0) - netgen_parameters.SetFineness(5) - netgen_parameters.SetNbSegPerEdge(16*(boxsize//100)) - netgen_parameters.SetNbSegPerRadius(1.5) - netgen_parameters.SetGrowthRate(0.15) - netgen_parameters.SetChordalError(-1) - netgen_parameters.SetChordalErrorEnabled(0) - netgen_parameters.SetUseSurfaceCurvature(1) - netgen_parameters.SetQuadAllowed(0) - netgen_parameters.SetCheckOverlapping(False) - netgen_parameters.SetNbThreads(2) - - return all_boxes, all_box_mesh, netgen_parameters - -def run_test(nbox=2, boxsize=100): - """ Run sequential mesh and parallel version of it - - nbox: NUmber of boxes - boxsize: Size of each box - """ - geom, seq_mesh, netgen_parameters = build_seq_mesh(nbox, boxsize, 0) - - par_mesh = smesh.ParallelMesh(geom, name="par_mesh") - par_mesh.AddGlobalHypothesis(netgen_parameters) - par_mesh.SetNbThreads(6) - - start = time.monotonic() - is_done = seq_mesh.Compute() - assert is_done - stop = time.monotonic() - time_seq = stop-start - - start = time.monotonic() - is_done = par_mesh.Compute() - assert is_done - stop = time.monotonic() - time_par = stop-start - - print(" Tetrahedron: ", seq_mesh.NbTetras(), par_mesh.NbTetras()) - print(" Triangle: ", seq_mesh.NbTriangles(), par_mesh.NbTriangles()) - print(" edge: ", seq_mesh.NbEdges(), par_mesh.NbEdges()) - - assert par_mesh.NbTetras() > 0 - assert par_mesh.NbTriangles() > 0 - assert par_mesh.NbEdges() > 0 - - print("Time elapsed (seq, par): ", time_seq, time_par) - -def main(): - if sys.platform == "win32": - print("Test disabled on Windows") - return - nbox = 2 - boxsize = 100 - run_test(nbox, boxsize) - -main() diff --git a/test/tests.set b/test/tests.set index 0035933fe..b14e7c200 100644 --- a/test/tests.set +++ b/test/tests.set @@ -65,7 +65,6 @@ SET(BAD_TESTS SMESH_create_dual_mesh_adapt.py SMESH_create_dual_mesh_tpipe.py netgen_runner.py - SMESH_ParallelCompute.py ) IF(NOT WIN32) LIST(APPEND BAD_TESTS