mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2024-12-26 17:30:35 +05:00
Adding Multinode method for smesh parallelism (with windows fixed)
Adding walltime for multinode + keeping temporary folder activated with environement variable bos #37471: fix compilation on Windows operating system. Note that SMESH_Gen::send_mesh current implementation is vetoed on windows OS (system call)
This commit is contained in:
parent
cc2c7dfdc0
commit
be238b4bb0
@ -1,16 +1,6 @@
|
|||||||
# contains function to compute a mesh in parallel
|
# contains function to compute a mesh in parallel
|
||||||
from platform import java_ver
|
|
||||||
import sys
|
|
||||||
try:
|
|
||||||
from tkinter import W
|
|
||||||
except:
|
|
||||||
print("warning: could not import tkinter")
|
|
||||||
|
|
||||||
import salome
|
import salome
|
||||||
|
|
||||||
import time
|
|
||||||
|
|
||||||
|
|
||||||
salome.salome_init()
|
salome.salome_init()
|
||||||
import salome_notebook
|
import salome_notebook
|
||||||
notebook = salome_notebook.NoteBook()
|
notebook = salome_notebook.NoteBook()
|
||||||
@ -22,128 +12,77 @@ notebook = salome_notebook.NoteBook()
|
|||||||
import GEOM
|
import GEOM
|
||||||
from salome.geom import geomBuilder
|
from salome.geom import geomBuilder
|
||||||
from salome.smesh import smeshBuilder
|
from salome.smesh import smeshBuilder
|
||||||
import math
|
|
||||||
import SALOMEDS
|
import SALOMEDS
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
geompy = geomBuilder.New()
|
geompy = geomBuilder.New()
|
||||||
|
|
||||||
|
|
||||||
|
nbox = 2
|
||||||
|
boxsize = 100
|
||||||
|
offset = 0
|
||||||
|
# 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')
|
||||||
|
|
||||||
|
rubik_cube = geompy.MakeGlueEdges(all_boxes, 1e-07)
|
||||||
|
geompy.addToStudy(all_boxes, 'rubik_cube')
|
||||||
|
|
||||||
|
|
||||||
smesh = smeshBuilder.New()
|
smesh = smeshBuilder.New()
|
||||||
|
print("Creating Parallel Mesh")
|
||||||
|
par_mesh = smesh.ParallelMesh(rubik_cube, name="par_mesh")
|
||||||
|
|
||||||
|
print("Creating hypoehtesis for netgen")
|
||||||
|
NETGEN_3D_Parameters_1 = smesh.CreateHypothesisByAverageLength( 'NETGEN_Parameters',
|
||||||
|
'NETGENEngine', 34.641, 0 )
|
||||||
|
print("Adding hypothesis")
|
||||||
|
par_mesh.AddGlobalHypothesis(NETGEN_3D_Parameters_1)
|
||||||
|
|
||||||
def build_seq_mesh(nbox, boxsize, offset):
|
print("Setting parallelism method")
|
||||||
# Create 3D faces
|
par_mesh.SetParallelismMethod(smeshBuilder.MULTITHREAD)
|
||||||
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)
|
print("Setting parallelism options")
|
||||||
y_orig = j*(boxsize+offset)
|
param = par_mesh.GetParallelismSettings()
|
||||||
z_orig = k*(boxsize+offset)
|
param.SetNbThreads(6)
|
||||||
|
|
||||||
tmp_box = geompy.MakeBoxDXDYDZ(boxsize, boxsize, boxsize)
|
print("Starting parallel compute")
|
||||||
|
is_done = par_mesh.Compute()
|
||||||
|
if not is_done:
|
||||||
|
raise Exception("Error when computing Mesh")
|
||||||
|
|
||||||
if not i == j == k == 0:
|
print(" Tetrahedron: ", par_mesh.NbTetras())
|
||||||
box = geompy.MakeTranslation(tmp_box, x_orig,
|
print(" Triangle: ", par_mesh.NbTriangles())
|
||||||
y_orig, z_orig)
|
print(" edge: ", par_mesh.NbEdges())
|
||||||
else:
|
|
||||||
box = tmp_box
|
|
||||||
|
|
||||||
geompy.addToStudy(box, 'box_{}:{}:{}'.format(i, j, k))
|
assert par_mesh.NbTetras() > 0
|
||||||
|
assert par_mesh.NbTriangles() > 0
|
||||||
boxes.append(box)
|
assert par_mesh.NbEdges() > 0
|
||||||
|
|
||||||
# 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)
|
|
||||||
|
|
||||||
print("Creating Parallel Mesh")
|
|
||||||
par_mesh = smesh.ParallelMesh(geom, name="par_mesh")
|
|
||||||
par_mesh.AddGlobalHypothesis(netgen_parameters)
|
|
||||||
param = par_mesh.GetParallelismSettings()
|
|
||||||
param.SetNbThreads(6)
|
|
||||||
|
|
||||||
assert param.GetNbThreads() == 6, param.GetNbThreads()
|
|
||||||
|
|
||||||
print("Starting sequential compute")
|
|
||||||
start = time.monotonic()
|
|
||||||
is_done = seq_mesh.Compute()
|
|
||||||
if not is_done:
|
|
||||||
raise Exception("Error when computing Mesh")
|
|
||||||
|
|
||||||
stop = time.monotonic()
|
|
||||||
time_seq = stop-start
|
|
||||||
|
|
||||||
print("Starting parallel compute")
|
|
||||||
start = time.monotonic()
|
|
||||||
is_done = par_mesh.Compute()
|
|
||||||
if not is_done:
|
|
||||||
raise Exception("Error when computing Mesh")
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
@ -43,28 +43,64 @@ How to
|
|||||||
You follow the same principle as the creation of a sequential Mesh.
|
You follow the same principle as the creation of a sequential Mesh.
|
||||||
|
|
||||||
|
|
||||||
#. First you create the mesh:
|
1. First you create the mesh:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
par_mesh = smesh.ParallelMesh(geom, name="par_mesh")
|
par_mesh = smesh.ParallelMesh(my_geom, name="par_mesh")
|
||||||
|
|
||||||
#. Define the Global Hypothesis that will be split into an hypothesis for the
|
2. Define the Global Hypothesis that will be split into an hypothesis for the
|
||||||
1D+2D compound and one for each of the 3D solids:
|
1D+2D compound and one for each of the 3D solids:
|
||||||
.. code-block:: python
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
NETGEN_3D_Parameters_1 = smesh.CreateHypothesisByAverageLength( 'NETGEN_Parameters',
|
NETGEN_3D_Parameters_1 = smesh.CreateHypothesisByAverageLength( 'NETGEN_Parameters',
|
||||||
'NETGENEngine', 34.641, 0 )
|
'NETGENEngine', 34.641, 0 )
|
||||||
par_mesh.AddGlobalHypothesis(netgen_parameters)
|
par_mesh.AddGlobalHypothesis(NETGEN_3D_Parameters_1)
|
||||||
|
|
||||||
|
3. Set the method for the parallelisation:
|
||||||
|
|
||||||
|
You have two methods for parallelisation:
|
||||||
|
|
||||||
|
* Multihtreading: Will run the computation on your computer using the processors on your computer.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
par_mesh.SetParallelismMethod(smeshBuilder.MULTITHREAD)
|
||||||
|
|
||||||
|
|
||||||
|
* MultiNodal: Will run the computation on a remote resource (cluster) that is defined in your salome catalog.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
par_mesh.SetParallelismMethod(smeshBuilder.MULTINODE)
|
||||||
|
|
||||||
|
|
||||||
|
4. Set the parameters for the parallelism:
|
||||||
|
|
||||||
|
* Multithread:
|
||||||
|
|
||||||
#. Set the parameters for the parallelisation:
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
param = par_mesh.GetParallelismSettings()
|
param = par_mesh.GetParallelismSettings()
|
||||||
param.SetNbThreads(6)
|
param.SetNbThreads(6)
|
||||||
|
|
||||||
#. Compute the mesh:
|
* Multinode:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
param = par_mesh.GetParallelismSettings()
|
||||||
|
param.SetResource("cronos")
|
||||||
|
param.SetNbProc(nbox**3)
|
||||||
|
param.SetNbProcPerNode(2)
|
||||||
|
param.SetNbNode(6)
|
||||||
|
param.SetWcKey("P11N0:SALOME_COFEE")
|
||||||
|
|
||||||
|
5. Compute the mesh:
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
mesh.Compute()
|
is_done = par_mesh.Compute()
|
||||||
|
if not is_done:
|
||||||
|
raise Exception("Error when computing Mesh")
|
||||||
|
|
||||||
**See Also** a sample script of :ref:`tui_create_parallel_mesh`.
|
**See Also** a sample script of :ref:`tui_create_parallel_mesh`.
|
||||||
|
@ -250,7 +250,7 @@ module SMESH
|
|||||||
* with TopoDS_Shapes
|
* with TopoDS_Shapes
|
||||||
* The mesh is a parallel one
|
* The mesh is a parallel one
|
||||||
*/
|
*/
|
||||||
SMESH_Mesh CreateParallelMesh( in GEOM::GEOM_Object theObject )
|
SMESH_ParallelMesh CreateParallelMesh( in GEOM::GEOM_Object theObject )
|
||||||
raises ( SALOME::SALOME_Exception );
|
raises ( SALOME::SALOME_Exception );
|
||||||
/*!
|
/*!
|
||||||
* Create an empty mesh object
|
* Create an empty mesh object
|
||||||
|
@ -899,17 +899,6 @@ module SMESH
|
|||||||
*/
|
*/
|
||||||
boolean SetMeshOrder(in submesh_array_array theSubMeshArray);
|
boolean SetMeshOrder(in submesh_array_array theSubMeshArray);
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Set Number of Threads
|
|
||||||
*/
|
|
||||||
void SetNbThreads(in long nbThreads);
|
|
||||||
/*!
|
|
||||||
/*!
|
|
||||||
* \brief Get Number of Threads
|
|
||||||
*/
|
|
||||||
long GetNbThreads();
|
|
||||||
/*!
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Get mesh description
|
* Get mesh description
|
||||||
*/
|
*/
|
||||||
@ -1114,7 +1103,35 @@ module SMESH
|
|||||||
};
|
};
|
||||||
|
|
||||||
interface SMESH_SequentialMesh:SMESH_Mesh{};
|
interface SMESH_SequentialMesh:SMESH_Mesh{};
|
||||||
interface SMESH_ParallelMesh:SMESH_Mesh{};
|
interface SMESH_ParallelMesh:SMESH_Mesh{
|
||||||
|
|
||||||
|
// Parallism method
|
||||||
|
long GetParallelismMethod();
|
||||||
|
void SetParallelismMethod(in long aMethod);
|
||||||
|
|
||||||
|
// Parameters for MutliThreading
|
||||||
|
long GetNbThreads();
|
||||||
|
void SetNbThreads(in long nbThreads);
|
||||||
|
|
||||||
|
// Parameters for MultiNode
|
||||||
|
string GetResource();
|
||||||
|
void SetResource(in string aResource);
|
||||||
|
|
||||||
|
long GetNbProc();
|
||||||
|
void SetNbProc(in long nbProc);
|
||||||
|
|
||||||
|
long GetNbProcPerNode();
|
||||||
|
void SetNbProcPerNode(in long nbProcPerNode);
|
||||||
|
|
||||||
|
long GetNbNode();
|
||||||
|
void SetNbNode(in long nbNode);
|
||||||
|
|
||||||
|
string GetWcKey();
|
||||||
|
void SetWcKey(in string wcKey);
|
||||||
|
|
||||||
|
string GetWalltime();
|
||||||
|
void SetWalltime(in string walltime);
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
# --- options ---
|
# --- options ---
|
||||||
# additional include directories
|
# additional include directories
|
||||||
INCLUDE_DIRECTORIES(
|
INCLUDE_DIRECTORIES(
|
||||||
|
${QT_INCLUDES}
|
||||||
${KERNEL_INCLUDE_DIRS}
|
${KERNEL_INCLUDE_DIRS}
|
||||||
${GEOM_INCLUDE_DIRS}
|
${GEOM_INCLUDE_DIRS}
|
||||||
${OpenCASCADE_INCLUDE_DIR}
|
${OpenCASCADE_INCLUDE_DIR}
|
||||||
@ -69,6 +70,7 @@ SET(_link_LIBRARIES
|
|||||||
MeshDriverGMF
|
MeshDriverGMF
|
||||||
${DriverCGNS_LIB}
|
${DriverCGNS_LIB}
|
||||||
${MEDCoupling_medloader}
|
${MEDCoupling_medloader}
|
||||||
|
Qt5::Core
|
||||||
)
|
)
|
||||||
|
|
||||||
# --- headers ---
|
# --- headers ---
|
||||||
|
@ -51,6 +51,9 @@
|
|||||||
#include "memoire.h"
|
#include "memoire.h"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
@ -174,12 +177,12 @@ SMESH_Mesh* SMESH_Gen::CreateMesh(bool theIsEmbeddedMode)
|
|||||||
*/
|
*/
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
SMESH_Mesh* SMESH_Gen::CreateParallelMesh(bool theIsEmbeddedMode)
|
SMESH_ParallelMesh* SMESH_Gen::CreateParallelMesh(bool theIsEmbeddedMode)
|
||||||
{
|
{
|
||||||
Unexpect aCatch(SalomeException);
|
Unexpect aCatch(SalomeException);
|
||||||
|
|
||||||
// create a new SMESH_mesh object
|
// create a new SMESH_mesh object
|
||||||
SMESH_Mesh *aMesh = new SMESH_ParallelMesh(
|
SMESH_ParallelMesh *aMesh = new SMESH_ParallelMesh(
|
||||||
_localId++,
|
_localId++,
|
||||||
this,
|
this,
|
||||||
theIsEmbeddedMode,
|
theIsEmbeddedMode,
|
||||||
@ -206,7 +209,7 @@ bool SMESH_Gen::sequentialComputeSubMeshes(
|
|||||||
const bool complexShapeFirst,
|
const bool complexShapeFirst,
|
||||||
const bool aShapeOnly)
|
const bool aShapeOnly)
|
||||||
{
|
{
|
||||||
MESSAGE("Compute submeshes sequentialy");
|
MESSAGE("Sequential Compute of submeshes");
|
||||||
|
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
|
|
||||||
@ -290,6 +293,68 @@ const std::function<void(SMESH_subMesh*,
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
/*
|
||||||
|
* Copy a file on remote resource
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
void SMESH_Gen::send_mesh(SMESH_Mesh& aMesh, std::string file_name)
|
||||||
|
{
|
||||||
|
#ifndef WIN32
|
||||||
|
SMESH_ParallelMesh& aParMesh = dynamic_cast<SMESH_ParallelMesh&>(aMesh);
|
||||||
|
// Calling run_mesher
|
||||||
|
// Path to mesher script
|
||||||
|
fs::path send_files = fs::path(std::getenv("SMESH_ROOT_DIR"))/
|
||||||
|
fs::path("bin")/
|
||||||
|
fs::path("salome")/
|
||||||
|
fs::path("send_files.py");
|
||||||
|
|
||||||
|
std::string s_program="python3";
|
||||||
|
std::list<std::string> params;
|
||||||
|
params.push_back(send_files.string());
|
||||||
|
params.push_back(file_name);
|
||||||
|
params.push_back("--resource="+aParMesh.GetResource());
|
||||||
|
|
||||||
|
// log file
|
||||||
|
fs::path log_file=aParMesh.GetTmpFolder() / fs::path("copy.log");
|
||||||
|
QString out_file = log_file.string().c_str();
|
||||||
|
|
||||||
|
// Building arguments for QProcess
|
||||||
|
QString program = QString::fromStdString(s_program);
|
||||||
|
QStringList arguments;
|
||||||
|
for(auto arg : params){
|
||||||
|
arguments << arg.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string cmd = "";
|
||||||
|
cmd += s_program;
|
||||||
|
for(auto arg: params){
|
||||||
|
cmd += " " + arg;
|
||||||
|
}
|
||||||
|
MESSAGE("Send files command: ");
|
||||||
|
MESSAGE(cmd);
|
||||||
|
|
||||||
|
QProcess myProcess;
|
||||||
|
myProcess.setProcessChannelMode(QProcess::MergedChannels);
|
||||||
|
myProcess.setStandardOutputFile(out_file);
|
||||||
|
|
||||||
|
myProcess.start(program, arguments);
|
||||||
|
// Waiting for process to finish (argument -1 make it wait until the end of
|
||||||
|
// the process otherwise it just waits 30 seconds)
|
||||||
|
bool finished = myProcess.waitForFinished(-1);
|
||||||
|
int ret = myProcess.exitCode();
|
||||||
|
|
||||||
|
if(ret != 0 || !finished){
|
||||||
|
// Run crahed
|
||||||
|
std::string msg = "Issue with send_files: \n";
|
||||||
|
msg += "See log for more details: " + log_file.string() + "\n";
|
||||||
|
msg += cmd + "\n";
|
||||||
|
throw SALOME_Exception(msg);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
/*!
|
/*!
|
||||||
* Algo to run the computation of all the submeshes of a mesh in parallel
|
* Algo to run the computation of all the submeshes of a mesh in parallel
|
||||||
@ -315,10 +380,10 @@ bool SMESH_Gen::parallelComputeSubMeshes(
|
|||||||
|
|
||||||
SMESH_subMeshIteratorPtr smIt;
|
SMESH_subMeshIteratorPtr smIt;
|
||||||
SMESH_subMesh *shapeSM = aMesh.GetSubMesh(aShape);
|
SMESH_subMesh *shapeSM = aMesh.GetSubMesh(aShape);
|
||||||
|
SMESH_ParallelMesh &aParMesh = dynamic_cast<SMESH_ParallelMesh&>(aMesh);
|
||||||
|
|
||||||
TopAbs_ShapeEnum previousShapeType = TopAbs_VERTEX;
|
TopAbs_ShapeEnum previousShapeType = TopAbs_VERTEX;
|
||||||
int nbThreads = aMesh.GetNbThreads();
|
MESSAGE("Parallel Compute of submeshes");
|
||||||
MESSAGE("Compute submeshes with threads: " << nbThreads);
|
|
||||||
|
|
||||||
|
|
||||||
smIt = shapeSM->getDependsOnIterator(includeSelf, !complexShapeFirst);
|
smIt = shapeSM->getDependsOnIterator(includeSelf, !complexShapeFirst);
|
||||||
@ -332,11 +397,6 @@ bool SMESH_Gen::parallelComputeSubMeshes(
|
|||||||
// Not doing in parallel 1D and 2D meshes
|
// Not doing in parallel 1D and 2D meshes
|
||||||
if ( !aMesh.HasShapeToMesh() && shapeType == TopAbs_VERTEX )
|
if ( !aMesh.HasShapeToMesh() && shapeType == TopAbs_VERTEX )
|
||||||
continue;
|
continue;
|
||||||
if(shapeType==TopAbs_FACE||shapeType==TopAbs_EDGE)
|
|
||||||
aMesh.SetNbThreads(0);
|
|
||||||
else
|
|
||||||
aMesh.SetNbThreads(nbThreads);
|
|
||||||
|
|
||||||
|
|
||||||
if (shapeType != previousShapeType) {
|
if (shapeType != previousShapeType) {
|
||||||
// Waiting for all threads for the previous type to end
|
// Waiting for all threads for the previous type to end
|
||||||
@ -347,12 +407,12 @@ bool SMESH_Gen::parallelComputeSubMeshes(
|
|||||||
case TopAbs_FACE:
|
case TopAbs_FACE:
|
||||||
file_name = "Mesh2D.med";
|
file_name = "Mesh2D.med";
|
||||||
break;
|
break;
|
||||||
case TopAbs_EDGE:
|
//case TopAbs_EDGE:
|
||||||
file_name = "Mesh1D.med";
|
// file_name = "Mesh1D.med";
|
||||||
break;
|
// break;
|
||||||
case TopAbs_VERTEX:
|
//case TopAbs_VERTEX:
|
||||||
file_name = "Mesh0D.med";
|
// file_name = "Mesh0D.med";
|
||||||
break;
|
// break;
|
||||||
case TopAbs_SOLID:
|
case TopAbs_SOLID:
|
||||||
default:
|
default:
|
||||||
file_name = "";
|
file_name = "";
|
||||||
@ -360,8 +420,11 @@ bool SMESH_Gen::parallelComputeSubMeshes(
|
|||||||
}
|
}
|
||||||
if(file_name != "")
|
if(file_name != "")
|
||||||
{
|
{
|
||||||
fs::path mesh_file = fs::path(aMesh.GetTmpFolder()) / fs::path(file_name);
|
fs::path mesh_file = fs::path(aParMesh.GetTmpFolder()) / fs::path(file_name);
|
||||||
SMESH_DriverMesh::exportMesh(mesh_file.string(), aMesh, "MESH");
|
SMESH_DriverMesh::exportMesh(mesh_file.string(), aMesh, "MESH");
|
||||||
|
if (aParMesh.GetParallelismMethod() == ParallelismMethod::MultiNode) {
|
||||||
|
this->send_mesh(aMesh, mesh_file.string());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//Resetting threaded pool info
|
//Resetting threaded pool info
|
||||||
previousShapeType = shapeType;
|
previousShapeType = shapeType;
|
||||||
@ -375,9 +438,16 @@ bool SMESH_Gen::parallelComputeSubMeshes(
|
|||||||
smToCompute->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
|
smToCompute->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
boost::asio::post(*(aMesh.GetPool()), std::bind(compute_function, smToCompute, computeEvent,
|
// Parallelism is only for 3D parts
|
||||||
|
if(shapeType!=TopAbs_SOLID){
|
||||||
|
compute_function(smToCompute, computeEvent,
|
||||||
shapeSM, aShapeOnly, allowedSubShapes,
|
shapeSM, aShapeOnly, allowedSubShapes,
|
||||||
aShapesId));
|
aShapesId);
|
||||||
|
}else{
|
||||||
|
boost::asio::post(*(aParMesh.GetPool()), std::bind(compute_function, smToCompute, computeEvent,
|
||||||
|
shapeSM, aShapeOnly, allowedSubShapes,
|
||||||
|
aShapesId));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Waiting for the thread for Solids to finish
|
// Waiting for the thread for Solids to finish
|
||||||
@ -385,6 +455,9 @@ bool SMESH_Gen::parallelComputeSubMeshes(
|
|||||||
|
|
||||||
aMesh.GetMeshDS()->Modified();
|
aMesh.GetMeshDS()->Modified();
|
||||||
|
|
||||||
|
// Cleanup done here as in Python the destructor is not called
|
||||||
|
aParMesh.cleanup();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@ -648,6 +721,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
|
|||||||
if ( aShapesId && GetShapeDim( shapeType ) > (int)aDim )
|
if ( aShapesId && GetShapeDim( shapeType ) > (int)aDim )
|
||||||
continue;
|
continue;
|
||||||
sm->SetAllowedSubShapes( fillAllowed( shapeSM, aShapeOnly, allowedSubShapes ));
|
sm->SetAllowedSubShapes( fillAllowed( shapeSM, aShapeOnly, allowedSubShapes ));
|
||||||
|
|
||||||
setCurrentSubMesh( sm );
|
setCurrentSubMesh( sm );
|
||||||
sm->ComputeStateEngine( computeEvent );
|
sm->ComputeStateEngine( computeEvent );
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
class SMESHDS_Document;
|
class SMESHDS_Document;
|
||||||
class SMESH_Algo;
|
class SMESH_Algo;
|
||||||
class SMESH_Mesh;
|
class SMESH_Mesh;
|
||||||
|
class SMESH_ParallelMesh;
|
||||||
class TopoDS_Shape;
|
class TopoDS_Shape;
|
||||||
|
|
||||||
|
|
||||||
@ -70,7 +71,7 @@ public:
|
|||||||
~SMESH_Gen();
|
~SMESH_Gen();
|
||||||
|
|
||||||
SMESH_Mesh* CreateMesh(bool theIsEmbeddedMode);
|
SMESH_Mesh* CreateMesh(bool theIsEmbeddedMode);
|
||||||
SMESH_Mesh* CreateParallelMesh(bool theIsEmbeddedMode);
|
SMESH_ParallelMesh* CreateParallelMesh(bool theIsEmbeddedMode);
|
||||||
|
|
||||||
enum ComputeFlags
|
enum ComputeFlags
|
||||||
{
|
{
|
||||||
@ -169,6 +170,8 @@ public:
|
|||||||
int GetANewId();
|
int GetANewId();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void send_mesh(SMESH_Mesh & aMesh, std::string filename);
|
||||||
|
|
||||||
bool parallelComputeSubMeshes(
|
bool parallelComputeSubMeshes(
|
||||||
SMESH_Mesh & aMesh,
|
SMESH_Mesh & aMesh,
|
||||||
const TopoDS_Shape & aShape,
|
const TopoDS_Shape & aShape,
|
||||||
|
@ -51,7 +51,6 @@
|
|||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/asio/thread_pool.hpp>
|
|
||||||
#endif
|
#endif
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
|
|
||||||
@ -395,19 +394,9 @@ class SMESH_EXPORT SMESH_Mesh
|
|||||||
virtual void Lock(){};
|
virtual void Lock(){};
|
||||||
virtual void Unlock(){};
|
virtual void Unlock(){};
|
||||||
|
|
||||||
virtual int GetNbThreads(){return 0;};
|
virtual void wait(){};
|
||||||
virtual void SetNbThreads(long nbThreads){(void) nbThreads;};
|
|
||||||
|
|
||||||
virtual void InitPoolThreads(){std::cout << "Should not pass here: InitPoolThread" << std::endl;};
|
virtual bool IsParallel(){throw SALOME_Exception("Calling SMESH_Mesh::IsParallel");return false;};
|
||||||
virtual void DeletePoolThreads(){std::cout << "Should not pass here: DeletePoolThread" << std::endl;};
|
|
||||||
virtual void wait(){std::cout << "Should not pass here: wait" << std::endl;};
|
|
||||||
|
|
||||||
virtual bool IsParallel(){std::cout << "Should not pass here: IsParallel" << std::endl;return false;};
|
|
||||||
|
|
||||||
#ifndef WIN32
|
|
||||||
virtual boost::filesystem::path GetTmpFolder() {return "";};
|
|
||||||
virtual boost::asio::thread_pool* GetPool() {return NULL;};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
virtual bool ComputeSubMeshes(
|
virtual bool ComputeSubMeshes(
|
||||||
SMESH_Gen* gen,
|
SMESH_Gen* gen,
|
||||||
@ -419,7 +408,7 @@ class SMESH_EXPORT SMESH_Mesh
|
|||||||
SMESH_subMesh::compute_event &computeEvent,
|
SMESH_subMesh::compute_event &computeEvent,
|
||||||
const bool includeSelf,
|
const bool includeSelf,
|
||||||
const bool complexShapeFirst,
|
const bool complexShapeFirst,
|
||||||
const bool aShapeOnly){(void) gen;(void) aMesh;(void) aShape;(void) aDim;(void) aShapesId;(void) allowedSubShapes;(void) computeEvent;(void) includeSelf;(void) complexShapeFirst;(void) aShapeOnly;std::cout << "Should not pass here: computesubmesh" << std::endl;return false;};
|
const bool aShapeOnly){(void) gen;(void) aMesh;(void) aShape;(void) aDim;(void) aShapesId;(void) allowedSubShapes;(void) computeEvent;(void) includeSelf;(void) complexShapeFirst;(void) aShapeOnly;throw SALOME_Exception("Calling SMESH_Mesh::ComputeSubMeshes");return false;};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -467,12 +456,6 @@ protected:
|
|||||||
// 2) to forget not loaded mesh data at hyp modification
|
// 2) to forget not loaded mesh data at hyp modification
|
||||||
TCallUp* _callUp;
|
TCallUp* _callUp;
|
||||||
|
|
||||||
// Mutex for multhitreading write in SMESH_Mesh
|
|
||||||
#ifndef WIN32
|
|
||||||
boost::mutex _my_lock;
|
|
||||||
#endif
|
|
||||||
int _NbThreads=-1;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SMESH_Mesh();
|
SMESH_Mesh();
|
||||||
SMESH_Mesh(const SMESH_Mesh&) {};
|
SMESH_Mesh(const SMESH_Mesh&) {};
|
||||||
|
@ -32,10 +32,8 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef WIN32
|
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
namespace fs=boost::filesystem;
|
namespace fs=boost::filesystem;
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
@ -43,12 +41,6 @@ namespace fs=boost::filesystem;
|
|||||||
|
|
||||||
#include <utilities.h>
|
#include <utilities.h>
|
||||||
|
|
||||||
#ifdef _DEBUG_
|
|
||||||
static int MYDEBUG = 1;
|
|
||||||
#else
|
|
||||||
static int MYDEBUG = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SMESH_ParallelMesh::SMESH_ParallelMesh(int theLocalId,
|
SMESH_ParallelMesh::SMESH_ParallelMesh(int theLocalId,
|
||||||
SMESH_Gen* theGen,
|
SMESH_Gen* theGen,
|
||||||
bool theIsEmbeddedMode,
|
bool theIsEmbeddedMode,
|
||||||
@ -58,21 +50,51 @@ SMESH_ParallelMesh::SMESH_ParallelMesh(int theLocalId,
|
|||||||
theDocument)
|
theDocument)
|
||||||
{
|
{
|
||||||
MESSAGE("SMESH_ParallelMesh::SMESH_ParallelMesh(int localId)");
|
MESSAGE("SMESH_ParallelMesh::SMESH_ParallelMesh(int localId)");
|
||||||
#ifndef WIN32
|
|
||||||
_NbThreads = std::thread::hardware_concurrency();
|
|
||||||
#else
|
|
||||||
_NbThreads = 0;
|
|
||||||
#endif
|
|
||||||
CreateTmpFolder();
|
CreateTmpFolder();
|
||||||
};
|
};
|
||||||
|
|
||||||
SMESH_ParallelMesh::~SMESH_ParallelMesh()
|
SMESH_ParallelMesh::~SMESH_ParallelMesh()
|
||||||
{
|
{
|
||||||
DeletePoolThreads();
|
cleanup();
|
||||||
if(!MYDEBUG)
|
|
||||||
DeleteTmpFolder();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void SMESH_ParallelMesh::cleanup()
|
||||||
|
{
|
||||||
|
DeletePoolThreads();
|
||||||
|
std::cout << "Keeping tmp folder" << keepingTmpFolfer() << std::endl;
|
||||||
|
if(!keepingTmpFolfer())
|
||||||
|
{
|
||||||
|
MESSAGE("Set SMESH_KEEP_TMP to > 0 to keep temporary folders")
|
||||||
|
DeleteTmpFolder();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Checking if we should keep the temporary folder
|
||||||
|
* They are kept if the variable SMESH_KEEP_TMP is set to higher than 0
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
bool SMESH_ParallelMesh::keepingTmpFolfer()
|
||||||
|
{
|
||||||
|
const char* envVar = std::getenv("SMESH_KEEP_TMP");
|
||||||
|
std::cout << "smesh_keep_tmp: " << envVar << std::endl;
|
||||||
|
|
||||||
|
if (envVar && (envVar[0] != '\0'))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const long long numValue = std::stoll(envVar);
|
||||||
|
return numValue > 0;
|
||||||
|
}
|
||||||
|
catch(const std::exception& e)
|
||||||
|
{
|
||||||
|
std::cerr << e.what() << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
@ -82,11 +104,9 @@ SMESH_ParallelMesh::~SMESH_ParallelMesh()
|
|||||||
//=============================================================================
|
//=============================================================================
|
||||||
void SMESH_ParallelMesh::CreateTmpFolder()
|
void SMESH_ParallelMesh::CreateTmpFolder()
|
||||||
{
|
{
|
||||||
#ifndef WIN32
|
|
||||||
// Temporary folder that will be used by parallel computation
|
// Temporary folder that will be used by parallel computation
|
||||||
tmp_folder = fs::temp_directory_path()/fs::unique_path(fs::path("SMESH_%%%%-%%%%"));
|
tmp_folder = fs::temp_directory_path()/fs::unique_path(fs::path("SMESH_%%%%-%%%%"));
|
||||||
fs::create_directories(tmp_folder);
|
fs::create_directories(tmp_folder);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
@ -96,11 +116,43 @@ void SMESH_ParallelMesh::CreateTmpFolder()
|
|||||||
//=============================================================================
|
//=============================================================================
|
||||||
void SMESH_ParallelMesh::DeleteTmpFolder()
|
void SMESH_ParallelMesh::DeleteTmpFolder()
|
||||||
{
|
{
|
||||||
#ifndef WIN32
|
MESSAGE("Deleting temporary folder" << tmp_folder.string());
|
||||||
fs::remove_all(tmp_folder);
|
fs::remove_all(tmp_folder);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Get the number of Threads to be used for the pool of Threads
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
int SMESH_ParallelMesh::GetPoolNbThreads()
|
||||||
|
{
|
||||||
|
int nbThreads = -1;
|
||||||
|
|
||||||
|
if(_method == ParallelismMethod::MultiThread){
|
||||||
|
nbThreads = _NbThreads;
|
||||||
|
}else if( _method == ParallelismMethod::MultiNode){
|
||||||
|
//TODO: Check of that is the right way
|
||||||
|
nbThreads = std::max(_nbProc, _nbNode*_nbProcPerNode);
|
||||||
|
} else {
|
||||||
|
throw SALOME_Exception("Unknown method "+std::to_string(_method));
|
||||||
|
}
|
||||||
|
|
||||||
|
return nbThreads;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Set Number of thread for multithread run
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
void SMESH_ParallelMesh::SetNbThreads(long nbThreads)
|
||||||
|
{
|
||||||
|
if(nbThreads < 1)
|
||||||
|
throw SALOME_Exception("Number of threads should be higher than 1");
|
||||||
|
_NbThreads=nbThreads;
|
||||||
|
};
|
||||||
|
|
||||||
bool SMESH_ParallelMesh::ComputeSubMeshes(
|
bool SMESH_ParallelMesh::ComputeSubMeshes(
|
||||||
SMESH_Gen* gen,
|
SMESH_Gen* gen,
|
||||||
SMESH_Mesh & aMesh,
|
SMESH_Mesh & aMesh,
|
||||||
|
@ -29,8 +29,17 @@
|
|||||||
|
|
||||||
#include "SMESH_Mesh.hxx"
|
#include "SMESH_Mesh.hxx"
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "SMESH_Gen.hxx"
|
#include "SMESH_Gen.hxx"
|
||||||
#include "SMESH_subMesh.hxx"
|
#include "SMESH_subMesh.hxx"
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <thread>
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
#endif
|
||||||
|
enum ParallelismMethod {MultiThread, MultiNode};
|
||||||
|
|
||||||
class SMESH_EXPORT SMESH_ParallelMesh: public SMESH_Mesh
|
class SMESH_EXPORT SMESH_ParallelMesh: public SMESH_Mesh
|
||||||
{
|
{
|
||||||
@ -40,44 +49,67 @@ class SMESH_EXPORT SMESH_ParallelMesh: public SMESH_Mesh
|
|||||||
bool theIsEmbeddedMode,
|
bool theIsEmbeddedMode,
|
||||||
SMESHDS_Document* theDocument);
|
SMESHDS_Document* theDocument);
|
||||||
|
|
||||||
virtual ~SMESH_ParallelMesh();
|
~SMESH_ParallelMesh();
|
||||||
|
|
||||||
#ifndef WIN32
|
// Locking mechanism
|
||||||
|
#ifndef WIN32
|
||||||
void Lock() override {_my_lock.lock();};
|
void Lock() override {_my_lock.lock();};
|
||||||
void Unlock() override {_my_lock.unlock();};
|
void Unlock() override {_my_lock.unlock();};
|
||||||
|
// We need to recreate the pool afterthe join
|
||||||
int GetNbThreads() override{return _NbThreads;};
|
|
||||||
void SetNbThreads(long nbThreads) override{_NbThreads=nbThreads;};
|
|
||||||
|
|
||||||
void InitPoolThreads() override {_pool = new boost::asio::thread_pool(_NbThreads);};
|
|
||||||
void DeletePoolThreads() override {delete _pool;};
|
|
||||||
|
|
||||||
void wait() override {_pool->join(); DeletePoolThreads(); InitPoolThreads(); };
|
void wait() override {_pool->join(); DeletePoolThreads(); InitPoolThreads(); };
|
||||||
|
#endif
|
||||||
|
|
||||||
bool IsParallel() override {return _NbThreads > 0;};
|
// Thread Pool
|
||||||
|
#ifndef WIN32
|
||||||
void CreateTmpFolder();
|
void InitPoolThreads() {_pool = new boost::asio::thread_pool(GetPoolNbThreads());};
|
||||||
void DeleteTmpFolder();
|
boost::asio::thread_pool* GetPool() {return _pool;};
|
||||||
|
void DeletePoolThreads() {delete _pool;};
|
||||||
boost::filesystem::path GetTmpFolder() override {return tmp_folder;};
|
|
||||||
boost::asio::thread_pool* GetPool() override {return _pool;};
|
|
||||||
#else
|
#else
|
||||||
void Lock() override {};
|
void InitPoolThreads() {};
|
||||||
void Unlock() override {};
|
void* GetPool() {return NULL;};
|
||||||
|
void DeletePoolThreads(){};
|
||||||
int GetNbThreads() override {return 0;};
|
|
||||||
void SetNbThreads(long nbThreads) {(void) nbThreads;};
|
|
||||||
|
|
||||||
void InitPoolThreads() override {};
|
|
||||||
void DeletePoolThreads() override {};
|
|
||||||
void wait() override {};
|
|
||||||
|
|
||||||
bool IsParallel() override {return false;};
|
|
||||||
|
|
||||||
void CreateTmpFolder();
|
|
||||||
void DeleteTmpFolder();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int GetPoolNbThreads();
|
||||||
|
|
||||||
|
// Temporary folder
|
||||||
|
bool keepingTmpFolfer();
|
||||||
|
void CreateTmpFolder();
|
||||||
|
void DeleteTmpFolder();
|
||||||
|
boost::filesystem::path GetTmpFolder() {return tmp_folder;};
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
|
//
|
||||||
|
bool IsParallel() override {return true;};
|
||||||
|
|
||||||
|
// Parallelims paramaters
|
||||||
|
int GetParallelismMethod() {return _method;};
|
||||||
|
void SetParallelismMethod(int aMethod) {_method = aMethod;};
|
||||||
|
|
||||||
|
// Mutlithreading parameters
|
||||||
|
int GetNbThreads() {return _NbThreads;};
|
||||||
|
void SetNbThreads(long nbThreads);
|
||||||
|
|
||||||
|
// Multinode parameters
|
||||||
|
std::string GetResource() {return _resource;};
|
||||||
|
void SetResource(std::string aResource) {_resource = aResource;};
|
||||||
|
|
||||||
|
int GetNbProc() {return _nbProc;};
|
||||||
|
void SetNbProc(long nbProc) {_nbProc = nbProc;};
|
||||||
|
|
||||||
|
int GetNbProcPerNode() {return _nbProcPerNode;};
|
||||||
|
void SetNbProcPerNode(long nbProcPerNodes) {_nbProcPerNode = nbProcPerNodes;};
|
||||||
|
|
||||||
|
int GetNbNode() {return _nbNode;};
|
||||||
|
void SetNbNode(long nbNodes) {_nbNode = nbNodes;};
|
||||||
|
|
||||||
|
std::string GetWcKey() {return _wcKey;};
|
||||||
|
void SetWcKey(std::string wcKey) {_wcKey = wcKey;};
|
||||||
|
|
||||||
|
std::string GetWalltime() {return _walltime;};
|
||||||
|
void SetWalltime(std::string walltime) {_walltime = walltime;};
|
||||||
|
|
||||||
|
// Parallel computation
|
||||||
bool ComputeSubMeshes(
|
bool ComputeSubMeshes(
|
||||||
SMESH_Gen* gen,
|
SMESH_Gen* gen,
|
||||||
SMESH_Mesh & aMesh,
|
SMESH_Mesh & aMesh,
|
||||||
@ -94,9 +126,22 @@ class SMESH_EXPORT SMESH_ParallelMesh: public SMESH_Mesh
|
|||||||
SMESH_ParallelMesh():SMESH_Mesh() {};
|
SMESH_ParallelMesh():SMESH_Mesh() {};
|
||||||
SMESH_ParallelMesh(const SMESH_ParallelMesh& aMesh):SMESH_Mesh(aMesh) {};
|
SMESH_ParallelMesh(const SMESH_ParallelMesh& aMesh):SMESH_Mesh(aMesh) {};
|
||||||
private:
|
private:
|
||||||
|
// Mutex for multhitreading write in SMESH_Mesh
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
boost::filesystem::path tmp_folder;
|
boost::mutex _my_lock;
|
||||||
boost::asio::thread_pool * _pool = nullptr; //thread pool for computation
|
// thread pool for computation
|
||||||
|
boost::asio::thread_pool * _pool = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
boost::filesystem::path tmp_folder;
|
||||||
|
int _method = ParallelismMethod::MultiThread;
|
||||||
|
|
||||||
|
int _NbThreads = std::thread::hardware_concurrency();
|
||||||
|
|
||||||
|
int _nbProc = 1;
|
||||||
|
int _nbProcPerNode = 1;
|
||||||
|
int _nbNode = 1;
|
||||||
|
std::string _resource = "";
|
||||||
|
std::string _wcKey = "P11N0:SALOME";
|
||||||
|
std::string _walltime = "01:00:00";
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@ -45,11 +45,6 @@ class SMESH_EXPORT SMESH_SequentialMesh: public SMESH_Mesh
|
|||||||
void Lock() override {};
|
void Lock() override {};
|
||||||
void Unlock() override {};
|
void Unlock() override {};
|
||||||
|
|
||||||
int GetNbThreads() override {return 0;};
|
|
||||||
void SetNbThreads(long nbThreads) {(void) nbThreads;};
|
|
||||||
|
|
||||||
void InitPoolThreads() override {};
|
|
||||||
void DeletePoolThreads() override {};
|
|
||||||
void wait() override {};
|
void wait() override {};
|
||||||
|
|
||||||
bool IsParallel() override {return false;};
|
bool IsParallel() override {return false;};
|
||||||
|
@ -1517,7 +1517,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event)
|
|||||||
// check submeshes needed
|
// check submeshes needed
|
||||||
// When computing in parallel mode we do not have a additional layer of submesh
|
// When computing in parallel mode we do not have a additional layer of submesh
|
||||||
// The check should not be done in parallel as that check is not thread-safe
|
// The check should not be done in parallel as that check is not thread-safe
|
||||||
if (_father->HasShapeToMesh() && !_father->IsParallel()) {
|
if (_father->HasShapeToMesh() && (!_father->IsParallel() || shape.ShapeType() != TopAbs_SOLID )) {
|
||||||
bool subComputed = false, subFailed = false;
|
bool subComputed = false, subFailed = false;
|
||||||
if (!algo->OnlyUnaryInput()) {
|
if (!algo->OnlyUnaryInput()) {
|
||||||
// --- commented for bos#22320 to compute all sub-shapes at once if possible;
|
// --- commented for bos#22320 to compute all sub-shapes at once if possible;
|
||||||
@ -2188,10 +2188,13 @@ TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * /*theGen*/,
|
|||||||
{
|
{
|
||||||
SMESH_subMesh* subMesh = smIt->next();
|
SMESH_subMesh* subMesh = smIt->next();
|
||||||
const TopoDS_Shape& S = subMesh->_subShape;
|
const TopoDS_Shape& S = subMesh->_subShape;
|
||||||
if ( S.ShapeType() != this->_subShape.ShapeType() )
|
|
||||||
|
if ( S.ShapeType() != this->_subShape.ShapeType() ){
|
||||||
continue;
|
continue;
|
||||||
if ( _allowedSubShapes && !_allowedSubShapes->IsEmpty() && !_allowedSubShapes->Contains( S ))
|
}
|
||||||
|
if ( _allowedSubShapes && !_allowedSubShapes->IsEmpty() && !_allowedSubShapes->Contains( S )){
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if ( subMesh == this )
|
if ( subMesh == this )
|
||||||
{
|
{
|
||||||
aBuilder.Add( aCompound, S );
|
aBuilder.Add( aCompound, S );
|
||||||
@ -2200,6 +2203,7 @@ TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * /*theGen*/,
|
|||||||
else if ( subMesh->GetComputeState() == READY_TO_COMPUTE )
|
else if ( subMesh->GetComputeState() == READY_TO_COMPUTE )
|
||||||
{
|
{
|
||||||
SMESH_Algo* anAlgo = subMesh->GetAlgo();
|
SMESH_Algo* anAlgo = subMesh->GetAlgo();
|
||||||
|
|
||||||
if (( anAlgo->IsSameName( *theAlgo )) && // same algo
|
if (( anAlgo->IsSameName( *theAlgo )) && // same algo
|
||||||
( anAlgo->GetUsedHypothesis( *_father, S, skipAuxHyps ) == usedHyps ) && // same hyps
|
( anAlgo->GetUsedHypothesis( *_father, S, skipAuxHyps ) == usedHyps ) && // same hyps
|
||||||
( anAlgo->GetAssignedShapes() == assiShapes ) && // on same sub-shapes
|
( anAlgo->GetAssignedShapes() == assiShapes ) && // on same sub-shapes
|
||||||
|
@ -146,6 +146,7 @@ SET(SMESHEngine_SOURCES
|
|||||||
SMESH_PreMeshInfo.cxx
|
SMESH_PreMeshInfo.cxx
|
||||||
MG_ADAPT_i.cxx
|
MG_ADAPT_i.cxx
|
||||||
SMESH_Homard_i.cxx
|
SMESH_Homard_i.cxx
|
||||||
|
SMESH_ParallelMesh_i.cxx
|
||||||
)
|
)
|
||||||
|
|
||||||
# --- rules ---
|
# --- rules ---
|
||||||
|
@ -101,8 +101,11 @@
|
|||||||
#include "SMESH_Hypothesis.hxx"
|
#include "SMESH_Hypothesis.hxx"
|
||||||
#include "SMESH_Hypothesis_i.hxx"
|
#include "SMESH_Hypothesis_i.hxx"
|
||||||
#include "SMESH_Mesh.hxx"
|
#include "SMESH_Mesh.hxx"
|
||||||
|
#include "SMESH_ParallelMesh.hxx"
|
||||||
#include "SMESH_MeshEditor.hxx"
|
#include "SMESH_MeshEditor.hxx"
|
||||||
#include "SMESH_Mesh_i.hxx"
|
#include "SMESH_Mesh_i.hxx"
|
||||||
|
#include <SMESH_SequentialMesh_i.hxx>
|
||||||
|
#include "SMESH_ParallelMesh_i.hxx"
|
||||||
#include "SMESH_PreMeshInfo.hxx"
|
#include "SMESH_PreMeshInfo.hxx"
|
||||||
#include "SMESH_PythonDump.hxx"
|
#include "SMESH_PythonDump.hxx"
|
||||||
#include "SMESH_ControlsDef.hxx"
|
#include "SMESH_ControlsDef.hxx"
|
||||||
@ -562,7 +565,7 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName
|
|||||||
*/
|
*/
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh(bool parallel /*=false*/)
|
SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh()
|
||||||
{
|
{
|
||||||
Unexpect aCatch(SALOME_SalomeException);
|
Unexpect aCatch(SALOME_SalomeException);
|
||||||
MESSAGE( "SMESH_Gen_i::createMesh" );
|
MESSAGE( "SMESH_Gen_i::createMesh" );
|
||||||
@ -573,11 +576,10 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh(bool parallel /*=false*/)
|
|||||||
SMESH_Mesh_i* meshServant = new SMESH_Mesh_i( GetPOA(), this );
|
SMESH_Mesh_i* meshServant = new SMESH_Mesh_i( GetPOA(), this );
|
||||||
// create a new mesh object
|
// create a new mesh object
|
||||||
MESSAGE("myIsEmbeddedMode " << myIsEmbeddedMode);
|
MESSAGE("myIsEmbeddedMode " << myIsEmbeddedMode);
|
||||||
if(parallel) {
|
SMESH_Mesh* myImpl = dynamic_cast<SMESH_Mesh*>(myGen.CreateMesh( myIsEmbeddedMode ));
|
||||||
meshServant->SetImpl( dynamic_cast<SMESH_Mesh*>(myGen.CreateParallelMesh( myIsEmbeddedMode )));
|
if(myImpl == NULL )
|
||||||
}else{
|
THROW_SALOME_CORBA_EXCEPTION( "Could not cast SequentialMesh as Mesh", SALOME::INTERNAL_ERROR );
|
||||||
meshServant->SetImpl( dynamic_cast<SMESH_Mesh*>(myGen.CreateMesh( myIsEmbeddedMode )));
|
meshServant->SetImpl(myImpl);
|
||||||
}
|
|
||||||
|
|
||||||
// activate the CORBA servant of Mesh
|
// activate the CORBA servant of Mesh
|
||||||
SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( meshServant->_this() );
|
SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( meshServant->_this() );
|
||||||
@ -592,6 +594,42 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh(bool parallel /*=false*/)
|
|||||||
return SMESH::SMESH_Mesh::_nil();
|
return SMESH::SMESH_Mesh::_nil();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
/*!
|
||||||
|
* SMESH_Gen_i::createParallelMesh
|
||||||
|
*
|
||||||
|
* Create empty parallel mesh on shape
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
SMESH::SMESH_ParallelMesh_ptr SMESH_Gen_i::createParallelMesh()
|
||||||
|
{
|
||||||
|
Unexpect aCatch(SALOME_SalomeException);
|
||||||
|
MESSAGE( "SMESH_Gen_i::createParallelMesh" );
|
||||||
|
|
||||||
|
// Get or create the GEOM_Client instance
|
||||||
|
try {
|
||||||
|
// create a new mesh object servant, store it in a map in study context
|
||||||
|
SMESH_ParallelMesh_i* meshServant = new SMESH_ParallelMesh_i( GetPOA(), this );
|
||||||
|
// create a new mesh object
|
||||||
|
MESSAGE("myIsEmbeddedMode " << myIsEmbeddedMode);
|
||||||
|
SMESH_Mesh* myImpl = dynamic_cast<SMESH_Mesh*>(myGen.CreateParallelMesh( myIsEmbeddedMode ));
|
||||||
|
if(myImpl == NULL )
|
||||||
|
THROW_SALOME_CORBA_EXCEPTION( "Could not cast ParallelMesh as Mesh", SALOME::INTERNAL_ERROR );
|
||||||
|
meshServant->SetImpl(myImpl);
|
||||||
|
|
||||||
|
// activate the CORBA servant of Mesh
|
||||||
|
SMESH::SMESH_ParallelMesh_var mesh = SMESH::SMESH_ParallelMesh::_narrow( meshServant->_this() );
|
||||||
|
int nextId = RegisterObject( mesh );
|
||||||
|
MESSAGE( "Add mesh to map with id = "<< nextId);
|
||||||
|
|
||||||
|
return mesh._retn();
|
||||||
|
}
|
||||||
|
catch (SALOME_Exception& S_ex) {
|
||||||
|
THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
|
||||||
|
}
|
||||||
|
return SMESH::SMESH_ParallelMesh::_nil();
|
||||||
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
/*!
|
/*!
|
||||||
* SMESH_Gen_i::GetShapeReader
|
* SMESH_Gen_i::GetShapeReader
|
||||||
@ -1235,14 +1273,14 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMesh( GEOM::GEOM_Object_ptr theShapeObj
|
|||||||
*/
|
*/
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateParallelMesh( GEOM::GEOM_Object_ptr theShapeObject )
|
SMESH::SMESH_ParallelMesh_ptr SMESH_Gen_i::CreateParallelMesh( GEOM::GEOM_Object_ptr theShapeObject )
|
||||||
{
|
{
|
||||||
Unexpect aCatch(SALOME_SalomeException);
|
Unexpect aCatch(SALOME_SalomeException);
|
||||||
MESSAGE( "SMESH_Gen_i::CreateParallelMesh" );
|
MESSAGE( "SMESH_Gen_i::CreateParallelMesh" );
|
||||||
// create mesh
|
// create mesh
|
||||||
SMESH::SMESH_Mesh_var mesh = this->createMesh(true);
|
SMESH::SMESH_ParallelMesh_var mesh = this->createParallelMesh();
|
||||||
// set shape
|
// set shape
|
||||||
SMESH_Mesh_i* meshServant = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
|
SMESH_ParallelMesh_i* meshServant = SMESH::DownCast<SMESH_ParallelMesh_i*>( mesh );
|
||||||
ASSERT( meshServant );
|
ASSERT( meshServant );
|
||||||
meshServant->SetShape( theShapeObject );
|
meshServant->SetShape( theShapeObject );
|
||||||
|
|
||||||
@ -1254,7 +1292,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateParallelMesh( GEOM::GEOM_Object_ptr the
|
|||||||
aStudyBuilder->CommitCommand();
|
aStudyBuilder->CommitCommand();
|
||||||
if ( !aSO->_is_nil() ) {
|
if ( !aSO->_is_nil() ) {
|
||||||
// Update Python script
|
// Update Python script
|
||||||
TPythonDump(this) << aSO << " = " << this << ".CreateMesh(" << theShapeObject << ")";
|
TPythonDump(this) << aSO << " = " << this << ".CreateParallelMesh(" << theShapeObject << ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ public:
|
|||||||
SMESH::SMESH_Mesh_ptr CreateMesh( GEOM::GEOM_Object_ptr theShapeObject );
|
SMESH::SMESH_Mesh_ptr CreateMesh( GEOM::GEOM_Object_ptr theShapeObject );
|
||||||
|
|
||||||
// Create empty parallel mesh on a shape
|
// Create empty parallel mesh on a shape
|
||||||
SMESH::SMESH_Mesh_ptr CreateParallelMesh( GEOM::GEOM_Object_ptr theShapeObject );
|
SMESH::SMESH_ParallelMesh_ptr CreateParallelMesh( GEOM::GEOM_Object_ptr theShapeObject );
|
||||||
|
|
||||||
// Create empty mesh
|
// Create empty mesh
|
||||||
SMESH::SMESH_Mesh_ptr CreateEmptyMesh();
|
SMESH::SMESH_Mesh_ptr CreateEmptyMesh();
|
||||||
@ -634,7 +634,8 @@ private:
|
|||||||
SMESH::SMESH_Hypothesis_ptr createHypothesis( const char* theHypName,
|
SMESH::SMESH_Hypothesis_ptr createHypothesis( const char* theHypName,
|
||||||
const char* theLibName);
|
const char* theLibName);
|
||||||
// Create empty mesh on shape
|
// Create empty mesh on shape
|
||||||
SMESH::SMESH_Mesh_ptr createMesh(bool parallel=false);
|
SMESH::SMESH_Mesh_ptr createMesh();
|
||||||
|
SMESH::SMESH_ParallelMesh_ptr createParallelMesh();
|
||||||
|
|
||||||
// Check mesh icon
|
// Check mesh icon
|
||||||
bool isGeomModifIcon( SMESH::SMESH_Mesh_ptr mesh );
|
bool isGeomModifIcon( SMESH::SMESH_Mesh_ptr mesh );
|
||||||
|
@ -7028,24 +7028,6 @@ TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
/*!
|
|
||||||
* \brief Set the number of threads for a parallel computation
|
|
||||||
*/
|
|
||||||
//=============================================================================
|
|
||||||
void SMESH_Mesh_i::SetNbThreads(CORBA::Long nbThreads){
|
|
||||||
_impl->SetNbThreads(nbThreads);
|
|
||||||
}
|
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
/*!
|
|
||||||
* \brief Get the number of threads for a parallel computation
|
|
||||||
*/
|
|
||||||
//=============================================================================
|
|
||||||
CORBA::Long SMESH_Mesh_i::GetNbThreads(){
|
|
||||||
return _impl->GetNbThreads();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
/*!
|
/*!
|
||||||
|
@ -673,21 +673,16 @@ private:
|
|||||||
SMESH::submesh_array_array& theSubMeshOrder,
|
SMESH::submesh_array_array& theSubMeshOrder,
|
||||||
const bool theIsDump);
|
const bool theIsDump);
|
||||||
|
|
||||||
/*!
|
|
||||||
* Parallelims informations
|
|
||||||
*/
|
|
||||||
void SetNbThreads(CORBA::Long nbThreads);
|
|
||||||
CORBA::Long GetNbThreads();
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Finds concurrent sub-meshes
|
* \brief Finds concurrent sub-meshes
|
||||||
*/
|
*/
|
||||||
TListOfListOfInt findConcurrentSubMeshes();
|
TListOfListOfInt findConcurrentSubMeshes();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
::SMESH_Mesh* _impl; // :: force no namespace here
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static int _idGenerator;
|
static int _idGenerator;
|
||||||
::SMESH_Mesh* _impl; // :: force no namespace here
|
|
||||||
SMESH_Gen_i* _gen_i;
|
SMESH_Gen_i* _gen_i;
|
||||||
int _id; // id given by creator (unique within the creator instance)
|
int _id; // id given by creator (unique within the creator instance)
|
||||||
int _nbInvalidHypos;
|
int _nbInvalidHypos;
|
||||||
|
@ -24,28 +24,11 @@
|
|||||||
// Module : SMESH
|
// Module : SMESH
|
||||||
|
|
||||||
#include "SMESH_ParallelMesh_i.hxx"
|
#include "SMESH_ParallelMesh_i.hxx"
|
||||||
|
#include "SMESH_Mesh_i.hxx"
|
||||||
|
|
||||||
#include "SMESH_Gen_i.hxx"
|
#include "SMESH_Gen_i.hxx"
|
||||||
|
|
||||||
|
|
||||||
#ifdef _DEBUG_
|
|
||||||
static int MYDEBUG = 0;
|
|
||||||
#else
|
|
||||||
static int MYDEBUG = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
/*!
|
|
||||||
* Constructor
|
|
||||||
*/
|
|
||||||
//=============================================================================
|
|
||||||
|
|
||||||
SMESH_ParallelMesh_i::SMESH_ParallelMesh_i( PortableServer::POA_ptr thePOA,
|
|
||||||
SMESH_Gen_i* gen_i )
|
|
||||||
: SMESH_Mesh_i(thePOA, gen_i)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -70,28 +53,156 @@ namespace
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
//================================================================================
|
::SMESH_ParallelMesh* SMESH_ParallelMesh_i::DownCast()
|
||||||
/*!
|
|
||||||
* \brief Set mesh implementation
|
|
||||||
*/
|
|
||||||
//================================================================================
|
|
||||||
|
|
||||||
void SMESH_ParallelMesh_i::SetImpl(::SMESH_ParallelMesh * impl)
|
|
||||||
{
|
{
|
||||||
if(MYDEBUG) MESSAGE("SMESH_ParallelMesh_i::SetImpl");
|
::SMESH_ParallelMesh* myImpl = dynamic_cast<::SMESH_ParallelMesh*>(_impl);
|
||||||
_impl = impl;
|
if (myImpl == NULL)
|
||||||
if ( _impl )
|
THROW_SALOME_CORBA_EXCEPTION("Could not cast as ParallelMesh", SALOME::INTERNAL_ERROR);
|
||||||
_impl->SetCallUp( new TCallUp_i(this));
|
|
||||||
|
return myImpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
/*!
|
/*!
|
||||||
* Return a mesh implementation
|
* \brief Get the parallellism method
|
||||||
*/
|
*/
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
::SMESH_ParallelMesh & SMESH_ParallelMesh_i::GetImpl()
|
CORBA::Long SMESH_ParallelMesh_i::GetParallelismMethod(){
|
||||||
{
|
return DownCast()->GetParallelismMethod();
|
||||||
if(MYDEBUG) MESSAGE("SMESH_ParallelMesh_i::GetImpl()");
|
}
|
||||||
return *_impl;
|
|
||||||
|
//=============================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Set the parallellism method
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
void SMESH_ParallelMesh_i::SetParallelismMethod(CORBA::Long aMethod){
|
||||||
|
DownCast()->SetParallelismMethod(aMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Get the number of threads for a parallel computation
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
CORBA::Long SMESH_ParallelMesh_i::GetNbThreads(){
|
||||||
|
return DownCast()->GetNbThreads();
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Set the number of threads for a parallel computation
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
void SMESH_ParallelMesh_i::SetNbThreads(CORBA::Long nbThreads){
|
||||||
|
DownCast()->SetNbThreads(nbThreads);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Get the ressource to connect to
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
char* SMESH_ParallelMesh_i::GetResource(){
|
||||||
|
return CORBA::string_dup(DownCast()->GetResource().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Set the ressource to connect to
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
void SMESH_ParallelMesh_i::SetResource(const char* aResource){
|
||||||
|
DownCast()->SetResource(std::string(aResource));
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Get the number of processor to use on ressource
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
CORBA::Long SMESH_ParallelMesh_i::GetNbProc(){
|
||||||
|
return DownCast()->GetNbProc();
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Set the number of processor to use on ressource
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
void SMESH_ParallelMesh_i::SetNbProc(CORBA::Long nbProcs){
|
||||||
|
DownCast()->SetNbProc(nbProcs);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Get the number of processor per node to use on ressource
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
CORBA::Long SMESH_ParallelMesh_i::GetNbProcPerNode(){
|
||||||
|
return DownCast()->GetNbProcPerNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Set the number of processor per node to use on ressource
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
void SMESH_ParallelMesh_i::SetNbProcPerNode(CORBA::Long nbProcPerNodes){
|
||||||
|
DownCast()->SetNbProcPerNode(nbProcPerNodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Get the number of node to use on ressource
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
CORBA::Long SMESH_ParallelMesh_i::GetNbNode(){
|
||||||
|
return DownCast()->GetNbNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Set the number of node to use on ressource
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
void SMESH_ParallelMesh_i::SetNbNode(CORBA::Long nbNodes){
|
||||||
|
DownCast()->SetNbNode(nbNodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Get the wckey to use on ressource
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
char* SMESH_ParallelMesh_i::GetWcKey(){
|
||||||
|
return CORBA::string_dup(DownCast()->GetWcKey().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Set the wckey to use on ressource
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
void SMESH_ParallelMesh_i::SetWcKey(const char* wcKey){
|
||||||
|
DownCast()->SetWcKey(std::string(wcKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Get the walltime to use on ressource
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
char* SMESH_ParallelMesh_i::GetWalltime(){
|
||||||
|
return CORBA::string_dup(DownCast()->GetWalltime().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Set the walltime to use on ressource
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
void SMESH_ParallelMesh_i::SetWalltime(const char* walltime){
|
||||||
|
DownCast()->SetWalltime(std::string(walltime));
|
||||||
}
|
}
|
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include "SMESH_Hypothesis.hxx"
|
#include "SMESH_Hypothesis.hxx"
|
||||||
#include "SMESH_Mesh_i.hxx"
|
#include "SMESH_Mesh_i.hxx"
|
||||||
|
#include "SMESH_ParallelMesh.hxx"
|
||||||
|
|
||||||
#include <SALOME_GenericObj_i.hh>
|
#include <SALOME_GenericObj_i.hh>
|
||||||
#include <SALOMEconfig.h>
|
#include <SALOMEconfig.h>
|
||||||
@ -41,11 +42,40 @@ class SMESH_I_EXPORT SMESH_ParallelMesh_i:
|
|||||||
public virtual POA_SMESH::SMESH_ParallelMesh,
|
public virtual POA_SMESH::SMESH_ParallelMesh,
|
||||||
public virtual SMESH_Mesh_i
|
public virtual SMESH_Mesh_i
|
||||||
{
|
{
|
||||||
|
SMESH_ParallelMesh_i();
|
||||||
|
SMESH_ParallelMesh_i(const SMESH_ParallelMesh_i&);
|
||||||
|
public:
|
||||||
SMESH_ParallelMesh_i( PortableServer::POA_ptr thePOA,
|
SMESH_ParallelMesh_i( PortableServer::POA_ptr thePOA,
|
||||||
SMESH_Gen_i* myGen_i ):SMESH_Mesh_i(thePOA, myGen_i){};
|
SMESH_Gen_i* myGen_i ):SMESH_Mesh_i(thePOA, myGen_i){};
|
||||||
|
|
||||||
virtual ~SMESH_ParallelMesh_i(){};
|
virtual ~SMESH_ParallelMesh_i(){};
|
||||||
|
|
||||||
|
CORBA::Long GetParallelismMethod();
|
||||||
|
void SetParallelismMethod(CORBA::Long aMethod);
|
||||||
|
|
||||||
|
CORBA::Long GetNbThreads();
|
||||||
|
void SetNbThreads(CORBA::Long nbThreads);
|
||||||
|
|
||||||
|
char* GetResource();
|
||||||
|
void SetResource(const char* aResource);
|
||||||
|
|
||||||
|
CORBA::Long GetNbProc();
|
||||||
|
void SetNbProc(CORBA::Long nbProcs);
|
||||||
|
|
||||||
|
CORBA::Long GetNbProcPerNode();
|
||||||
|
void SetNbProcPerNode(CORBA::Long nbProcPerNodes);
|
||||||
|
|
||||||
|
CORBA::Long GetNbNode();
|
||||||
|
void SetNbNode(CORBA::Long nbNodes);
|
||||||
|
|
||||||
|
char* GetWcKey();
|
||||||
|
void SetWcKey(const char* wcKey);
|
||||||
|
|
||||||
|
char* GetWalltime();
|
||||||
|
void SetWalltime(const char* walltime);
|
||||||
|
|
||||||
|
private:
|
||||||
|
::SMESH_ParallelMesh* DownCast();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -40,6 +40,11 @@ SET(smesh_SCRIPTS
|
|||||||
smesh_tools.py
|
smesh_tools.py
|
||||||
)
|
)
|
||||||
|
|
||||||
|
SET(smesh_exe_SCRIPTS
|
||||||
|
mesher_launcher.py
|
||||||
|
send_files.py
|
||||||
|
)
|
||||||
|
|
||||||
SET(StdMeshers_SCRIPTS
|
SET(StdMeshers_SCRIPTS
|
||||||
__init__.py
|
__init__.py
|
||||||
StdMeshersBuilder.py
|
StdMeshersBuilder.py
|
||||||
@ -66,6 +71,7 @@ ENDIF(WIN32)
|
|||||||
install(TARGETS _SMeshHelper DESTINATION ${SALOME_INSTALL_LIBS})
|
install(TARGETS _SMeshHelper DESTINATION ${SALOME_INSTALL_LIBS})
|
||||||
install(FILES ${SMeshHelper_HEADERS} DESTINATION ${SALOME_INSTALL_HEADERS})
|
install(FILES ${SMeshHelper_HEADERS} DESTINATION ${SALOME_INSTALL_HEADERS})
|
||||||
SALOME_INSTALL_SCRIPTS("${_swig_SCRIPTS}" ${SALOME_INSTALL_BINS} EXTRA_DPYS "${SWIG_MODULE_SMeshHelper_REAL_NAME}")
|
SALOME_INSTALL_SCRIPTS("${_swig_SCRIPTS}" ${SALOME_INSTALL_BINS} EXTRA_DPYS "${SWIG_MODULE_SMeshHelper_REAL_NAME}")
|
||||||
|
SALOME_INSTALL_SCRIPTS("${smesh_exe_SCRIPTS}" ${SALOME_INSTALL_BINS})
|
||||||
|
|
||||||
# --- rules ---
|
# --- rules ---
|
||||||
SALOME_INSTALL_SCRIPTS("${smesh_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/smesh DEF_PERMS)
|
SALOME_INSTALL_SCRIPTS("${smesh_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/smesh DEF_PERMS)
|
||||||
|
323
src/SMESH_SWIG/mesher_launcher.py
Normal file
323
src/SMESH_SWIG/mesher_launcher.py
Normal file
@ -0,0 +1,323 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
## Copyright (C) 2021-2023 CEA/DEN, EDF R&D, OPEN CASCADE
|
||||||
|
##
|
||||||
|
## 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
|
||||||
|
##
|
||||||
|
"""
|
||||||
|
File to run mesher from command line
|
||||||
|
"""
|
||||||
|
from os import environ, path
|
||||||
|
import sys
|
||||||
|
import subprocess as sp
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
|
import pydefx
|
||||||
|
import pylauncher
|
||||||
|
|
||||||
|
MESHER_HANDLED = ["NETGEN3D"]
|
||||||
|
|
||||||
|
CMD_TEMPLATE = \
|
||||||
|
"""{runner} {mesher} {mesh_file} {shape_file} {param_file} {elem_orientation_file} {new_element_file} {output_mesh_file} > {log_file} 2>&1"""
|
||||||
|
|
||||||
|
PYTHON_CODE = \
|
||||||
|
"""
|
||||||
|
import subprocess as sp
|
||||||
|
def _exec(cmd):
|
||||||
|
error_code = -1
|
||||||
|
try:
|
||||||
|
output = sp.check_output(cmd, shell=True)
|
||||||
|
error_code = 0
|
||||||
|
except sp.CalledProcessError as e:
|
||||||
|
print('Code crash')
|
||||||
|
print(e.output)
|
||||||
|
error_code = e.returncode
|
||||||
|
raise e
|
||||||
|
return error_code
|
||||||
|
"""
|
||||||
|
|
||||||
|
def create_launcher():
|
||||||
|
""" Initialise pylauncher
|
||||||
|
"""
|
||||||
|
launcher = pylauncher.Launcher_cpp()
|
||||||
|
launcher.SetResourcesManager(create_resources_manager())
|
||||||
|
return launcher
|
||||||
|
|
||||||
|
def create_resources_manager():
|
||||||
|
""" Look for the catalog file and create a ressource manager with it """
|
||||||
|
# localhost is defined anyway, even if the catalog file does not exist.
|
||||||
|
catalog_path = environ.get("USER_CATALOG_RESOURCES_FILE", "")
|
||||||
|
if not path.isfile(catalog_path):
|
||||||
|
salome_path = environ.get("ROOT_SALOME_INSTALL", "")
|
||||||
|
catalog_path = path.join(salome_path, "CatalogResources.xml")
|
||||||
|
if not path.isfile(catalog_path):
|
||||||
|
catalog_path = ""
|
||||||
|
|
||||||
|
return pylauncher.ResourcesManager_cpp(catalog_path)
|
||||||
|
|
||||||
|
def create_job_parameters():
|
||||||
|
""" Initialsie JobParameters """
|
||||||
|
jparam = pylauncher.JobParameters_cpp()
|
||||||
|
jparam.resource_required = create_resource_parameters()
|
||||||
|
return jparam
|
||||||
|
|
||||||
|
def create_resource_parameters():
|
||||||
|
""" Init resourceParams """
|
||||||
|
return pylauncher.resourceParams()
|
||||||
|
|
||||||
|
def get_runner(mesher):
|
||||||
|
"""
|
||||||
|
Get path to exe for mesher
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
mesher: Name of the mesher (NETGEN2D/NETGEN3D...)
|
||||||
|
|
||||||
|
retuns (string) Path to the exe
|
||||||
|
"""
|
||||||
|
if sys.platform.startswith('win'):
|
||||||
|
ext = ".exe"
|
||||||
|
else:
|
||||||
|
ext = ""
|
||||||
|
|
||||||
|
if mesher in ['NETGEN3D']:
|
||||||
|
exe_path = path.join("${NETGENPLUGIN_ROOT_DIR}",
|
||||||
|
"bin",
|
||||||
|
"salome",
|
||||||
|
"NETGENPlugin_Runner"+ext)
|
||||||
|
else:
|
||||||
|
raise Exception("Mesher {mesher} is not handled".format(mesher=mesher))
|
||||||
|
|
||||||
|
return exe_path
|
||||||
|
|
||||||
|
def run_local(args):
|
||||||
|
""" Simple Local run """
|
||||||
|
print("Local run")
|
||||||
|
#TODO: Check on how to handle log for windows (through sp.check_output)
|
||||||
|
cmd = CMD_TEMPLATE.format(\
|
||||||
|
runner=get_runner(args.mesher),
|
||||||
|
mesher=args.mesher,
|
||||||
|
mesh_file=args.input_mesh_file,
|
||||||
|
shape_file=args.shape_file,
|
||||||
|
param_file=args.hypo_file,
|
||||||
|
elem_orientation_file=args.elem_orient_file,
|
||||||
|
new_element_file=args.new_element_file,
|
||||||
|
log_file=path.join(path.dirname(args.shape_file), "run.log"),
|
||||||
|
output_mesh_file=args.output_mesh_file)
|
||||||
|
print("Executing:")
|
||||||
|
print(cmd)
|
||||||
|
sp.check_output(cmd, shell=True, cwd=path.dirname(args.shape_file))
|
||||||
|
|
||||||
|
def run_pylauncher(args):
|
||||||
|
""" Run exe throuhg pylauncher """
|
||||||
|
import time
|
||||||
|
print("Cluster run")
|
||||||
|
|
||||||
|
cmd = CMD_TEMPLATE.format(\
|
||||||
|
runner=get_runner(args.mesher),
|
||||||
|
mesher=args.mesher,
|
||||||
|
mesh_file="../"+path.basename(args.input_mesh_file),
|
||||||
|
shape_file=path.basename(args.shape_file),
|
||||||
|
param_file=path.basename(args.hypo_file),
|
||||||
|
elem_orientation_file=path.basename(args.elem_orient_file),
|
||||||
|
new_element_file=path.basename(args.new_element_file),
|
||||||
|
log_file="run.log",
|
||||||
|
output_mesh_file=path.basename(args.output_mesh_file))
|
||||||
|
|
||||||
|
print("Cmd: ", cmd)
|
||||||
|
|
||||||
|
# salome launcher
|
||||||
|
launcher = create_launcher()
|
||||||
|
|
||||||
|
# See SALOME_Launcher documentation for parameters
|
||||||
|
job_params = create_job_parameters()
|
||||||
|
# different type are:
|
||||||
|
# command Shell out of salome session
|
||||||
|
# command_salome Shell in salome shell
|
||||||
|
# python_salome Python script
|
||||||
|
# yacs_file
|
||||||
|
job_params.job_type = "command_salome" # creates CatalogResources.xml
|
||||||
|
|
||||||
|
job_params.wckey = args.wc_key
|
||||||
|
job_params.resource_required.nb_proc = args.nb_proc
|
||||||
|
job_params.resource_required.nb_proc_per_node = args.nb_proc_per_node
|
||||||
|
job_params.resource_required.nb_node = args.nb_node
|
||||||
|
job_params.maximum_duration = args.walltime
|
||||||
|
|
||||||
|
# job_params.pre_command = pre_command # command to run on frontal
|
||||||
|
# script to run in batch mode
|
||||||
|
run_script = path.join(path.dirname(args.shape_file), "run.sh")
|
||||||
|
with open(run_script, "w") as f:
|
||||||
|
f.write("#!/bin/bash\n")
|
||||||
|
f.write(cmd)
|
||||||
|
job_params.job_file = run_script
|
||||||
|
|
||||||
|
local_dir = path.dirname(args.shape_file)
|
||||||
|
|
||||||
|
# files to copy to remote working dir
|
||||||
|
# Directories are copied recursively.
|
||||||
|
# job_file script is automaticaly copied.
|
||||||
|
job_params.in_files = [args.shape_file,
|
||||||
|
args.hypo_file,
|
||||||
|
args.elem_orient_file]
|
||||||
|
|
||||||
|
print("in_files", job_params.in_files)
|
||||||
|
# local path for in_files
|
||||||
|
job_params.local_directory = local_dir
|
||||||
|
# result files you want to bring back with getJobResults
|
||||||
|
# TODO: replace run.log by argument ? by path
|
||||||
|
out_files = ["run.log"]
|
||||||
|
if args.new_element_file != "NONE":
|
||||||
|
out_files.append(path.relpath(args.new_element_file, local_dir))
|
||||||
|
if args.output_mesh_file != "NONE":
|
||||||
|
out_files.append(path.relpath(args.output_mesh_file, local_dir))
|
||||||
|
job_params.out_files = out_files
|
||||||
|
print("out_files", job_params.out_files)
|
||||||
|
# local path where to copy out_files
|
||||||
|
job_params.result_directory = local_dir
|
||||||
|
|
||||||
|
job_params.job_name = "SMESH_parallel"
|
||||||
|
job_params.resource_required.name = args.resource
|
||||||
|
|
||||||
|
# Extra parameters
|
||||||
|
# String that is directly added to the job submission file
|
||||||
|
# job_params.extra_params = "#SBATCH --nodes=2"
|
||||||
|
|
||||||
|
# remote job directory
|
||||||
|
# Retrieve working dir from catalog
|
||||||
|
res_manager = create_resources_manager()
|
||||||
|
res_params = res_manager.GetResourceDefinition(args.resource)
|
||||||
|
job_params.work_directory = path.join(\
|
||||||
|
res_params.working_directory,
|
||||||
|
path.basename(path.dirname(path.dirname(args.shape_file))),
|
||||||
|
path.basename(path.dirname(args.shape_file)))
|
||||||
|
print("work directory", job_params.work_directory)
|
||||||
|
|
||||||
|
job_id = launcher.createJob(job_params) #SALOME id of the job
|
||||||
|
launcher.launchJob(job_id) # copy files, run pre_command, submit job
|
||||||
|
|
||||||
|
# wait for the end of the job
|
||||||
|
job_state = launcher.getJobState(job_id)
|
||||||
|
print("Job %d state: %s" % (job_id, job_state))
|
||||||
|
while job_state not in ["FINISHED", "FAILED"]:
|
||||||
|
time.sleep(3)
|
||||||
|
job_state = launcher.getJobState(job_id)
|
||||||
|
|
||||||
|
if job_state == "FAILED":
|
||||||
|
raise Exception("Job failed")
|
||||||
|
else:
|
||||||
|
# verify the return code of the execution
|
||||||
|
if(launcher.getJobWorkFile(job_id,
|
||||||
|
"logs/exit_code.log",
|
||||||
|
job_params.result_directory)):
|
||||||
|
exit_code_file = path.join(job_params.result_directory,
|
||||||
|
"exit_code.log")
|
||||||
|
exit_code = ""
|
||||||
|
if path.isfile(exit_code_file):
|
||||||
|
with open(exit_code_file) as myfile:
|
||||||
|
exit_code = myfile.read()
|
||||||
|
exit_code = exit_code.strip()
|
||||||
|
if exit_code != "0":
|
||||||
|
raise Exception(\
|
||||||
|
"An error occured during the execution of the job.")
|
||||||
|
else:
|
||||||
|
raise Exception("Failed to get the exit code of the job.")
|
||||||
|
|
||||||
|
# Retrieve result files
|
||||||
|
launcher.getJobResults(job_id, "")
|
||||||
|
|
||||||
|
# Delete remote working dir
|
||||||
|
del_tmp_folder = True
|
||||||
|
try:
|
||||||
|
val = int(environ.get("SMESH_KEEP_TMP", "0"))
|
||||||
|
del_tmp_folder = val > 0
|
||||||
|
except Exception as e:
|
||||||
|
del_tmp_folder = True
|
||||||
|
|
||||||
|
launcher.clearJobWorkingDir(job_id)
|
||||||
|
|
||||||
|
def def_arg():
|
||||||
|
""" Define and parse arguments for the script """
|
||||||
|
parser = ArgumentParser()
|
||||||
|
parser.add_argument("mesher",
|
||||||
|
choices=MESHER_HANDLED,
|
||||||
|
help="mesher to use from ("+",".join(MESHER_HANDLED)+")")
|
||||||
|
parser.add_argument("input_mesh_file",\
|
||||||
|
help="MED File containing lower-dimension-elements already meshed")
|
||||||
|
parser.add_argument("shape_file",
|
||||||
|
help="STEP file containing the shape to mesh")
|
||||||
|
parser.add_argument("hypo_file",
|
||||||
|
help="Ascii file containint the list of parameters")
|
||||||
|
parser.add_argument("--elem-orient-file",\
|
||||||
|
help="binary file containing the list of elements from "\
|
||||||
|
"INPUT_MESH_FILE associated to the shape and their orientation")
|
||||||
|
# Output file parameters
|
||||||
|
output = parser.add_argument_group("Output files", "Possible output files")
|
||||||
|
output.add_argument("--new-element-file",
|
||||||
|
default="NONE",
|
||||||
|
help="contains elements and nodes added by the meshing")
|
||||||
|
output.add_argument(\
|
||||||
|
"--output-mesh-file",
|
||||||
|
default="NONE",
|
||||||
|
help="MED File containing the mesh after the run of the mesher")
|
||||||
|
|
||||||
|
# Run parameters
|
||||||
|
run_param = parser.add_argument_group(\
|
||||||
|
"Run parameters",
|
||||||
|
"Parameters for the run of the mesher")
|
||||||
|
run_param.add_argument("--method",
|
||||||
|
default="local",
|
||||||
|
choices=["local", "cluster"],
|
||||||
|
help="Running method (default: local)")
|
||||||
|
|
||||||
|
run_param.add_argument("--resource",
|
||||||
|
help="resource from SALOME Catalog")
|
||||||
|
run_param.add_argument("--nb-proc",
|
||||||
|
default=1,
|
||||||
|
type=int,
|
||||||
|
help="Number of processors")
|
||||||
|
run_param.add_argument("--nb-proc-per-node",
|
||||||
|
default=1,
|
||||||
|
type=int,
|
||||||
|
help="Number of processeor per node")
|
||||||
|
run_param.add_argument("--nb-node",
|
||||||
|
default=1,
|
||||||
|
type=int,
|
||||||
|
help="Number of node")
|
||||||
|
run_param.add_argument("--walltime",
|
||||||
|
default="01:00:00",
|
||||||
|
help="walltime for job submission HH:MM:SS (default 01:00:00)")
|
||||||
|
run_param.add_argument("--wc-key",
|
||||||
|
default="P11N0:SALOME",
|
||||||
|
help="wc-key for job submission (default P11N0:SALOME)")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
return args
|
||||||
|
|
||||||
|
def main():
|
||||||
|
""" Main function """
|
||||||
|
args = def_arg()
|
||||||
|
if args.method == "local":
|
||||||
|
run_local(args)
|
||||||
|
elif args.method == "cluster":
|
||||||
|
run_pylauncher(args)
|
||||||
|
else:
|
||||||
|
raise Exception("Unknown method {}".format(args.method))
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
125
src/SMESH_SWIG/send_files.py
Normal file
125
src/SMESH_SWIG/send_files.py
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
## Copyright (C) 2021-2023 CEA/DEN, EDF R&D, OPEN CASCADE
|
||||||
|
##
|
||||||
|
## 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
|
||||||
|
##
|
||||||
|
"""
|
||||||
|
File to send files on remote ressource
|
||||||
|
"""
|
||||||
|
from os import environ, path
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
|
import pydefx
|
||||||
|
import pylauncher
|
||||||
|
|
||||||
|
def create_launcher():
|
||||||
|
""" Initialise pylauncher
|
||||||
|
"""
|
||||||
|
launcher = pylauncher.Launcher_cpp()
|
||||||
|
launcher.SetResourcesManager(create_resources_manager())
|
||||||
|
return launcher
|
||||||
|
|
||||||
|
def create_resources_manager():
|
||||||
|
""" Look for the catalog file and create a ressource manager with it """
|
||||||
|
# localhost is defined anyway, even if the catalog file does not exist.
|
||||||
|
catalog_path = environ.get("USER_CATALOG_RESOURCES_FILE", "")
|
||||||
|
if not path.isfile(catalog_path):
|
||||||
|
salome_path = environ.get("ROOT_SALOME_INSTALL", "")
|
||||||
|
catalog_path = path.join(salome_path, "CatalogResources.xml")
|
||||||
|
if not path.isfile(catalog_path):
|
||||||
|
catalog_path = ""
|
||||||
|
|
||||||
|
return pylauncher.ResourcesManager_cpp(catalog_path)
|
||||||
|
|
||||||
|
def create_job_parameters():
|
||||||
|
""" Initialsie JobParameters """
|
||||||
|
jparam = pylauncher.JobParameters_cpp()
|
||||||
|
jparam.resource_required = create_resource_parameters()
|
||||||
|
return jparam
|
||||||
|
|
||||||
|
def create_resource_parameters():
|
||||||
|
""" Init resourceParams """
|
||||||
|
return pylauncher.resourceParams()
|
||||||
|
|
||||||
|
def send_file(args):
|
||||||
|
""" job to send a file to the cluster """
|
||||||
|
# salome launcher
|
||||||
|
launcher = create_launcher()
|
||||||
|
|
||||||
|
# See SALOME_Launcher documentation for parameters
|
||||||
|
job_params = create_job_parameters()
|
||||||
|
job_params.job_type = "command_salome" # creates CatalogResources.xml
|
||||||
|
|
||||||
|
local_dir = path.dirname(args.input_file)
|
||||||
|
|
||||||
|
# job_params.pre_command = pre_command # command to run on frontal
|
||||||
|
# script to run in batch mode
|
||||||
|
run_script = path.join(path.dirname(args.input_file), "run.sh")
|
||||||
|
with open(run_script, "w") as f:
|
||||||
|
f.write("#!/bin/bash\n")
|
||||||
|
job_params.job_file = run_script
|
||||||
|
job_params.resource_required.nb_proc = 1
|
||||||
|
|
||||||
|
# files to copy to remote working dir
|
||||||
|
# Directories are copied recursively.
|
||||||
|
# job_file script is automaticaly copied.
|
||||||
|
job_params.in_files = [args.input_file]
|
||||||
|
print("in_files", job_params.in_files)
|
||||||
|
# local path where to copy out_files
|
||||||
|
job_params.result_directory = local_dir
|
||||||
|
|
||||||
|
job_params.job_name = "SMESH_transfer"
|
||||||
|
job_params.resource_required.name = args.resource
|
||||||
|
|
||||||
|
# remote job directory
|
||||||
|
# Retrieve working dir from catalog
|
||||||
|
res_manager = create_resources_manager()
|
||||||
|
res_params = res_manager.GetResourceDefinition(args.resource)
|
||||||
|
job_params.work_directory = path.join(\
|
||||||
|
res_params.working_directory,
|
||||||
|
path.basename(path.dirname(args.input_file)))
|
||||||
|
|
||||||
|
print("work_directory", job_params.work_directory)
|
||||||
|
|
||||||
|
job_id = launcher.createJob(job_params) #SALOME id of the job
|
||||||
|
launcher.exportInputFiles(job_id)
|
||||||
|
|
||||||
|
|
||||||
|
def def_arg():
|
||||||
|
""" Define and parse arguments for the script """
|
||||||
|
parser = ArgumentParser()
|
||||||
|
parser.add_argument("input_file",\
|
||||||
|
help="file to copy")
|
||||||
|
|
||||||
|
# Run parameters
|
||||||
|
|
||||||
|
parser.add_argument("--resource",
|
||||||
|
help="resource from SALOME Catalog")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
return args
|
||||||
|
|
||||||
|
def main():
|
||||||
|
""" Main function """
|
||||||
|
args = def_arg()
|
||||||
|
send_file(args)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
@ -1629,7 +1629,9 @@ class Mesh(metaclass = MeshMeta):
|
|||||||
geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
|
geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
|
||||||
geompyD.addToStudy( self.geom, geo_name )
|
geompyD.addToStudy( self.geom, geo_name )
|
||||||
if parallel and isinstance(self, ParallelMesh):
|
if parallel and isinstance(self, ParallelMesh):
|
||||||
self.SetMesh( self.smeshpyD.CreateParallelMesh(self.geom) )
|
mymesh = self.smeshpyD.CreateParallelMesh(self.geom)
|
||||||
|
mymesh2 = mymesh._narrow(SMESH._objref_SMESH_Mesh)
|
||||||
|
self.SetMesh( mymesh )
|
||||||
else:
|
else:
|
||||||
self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
|
self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
|
||||||
|
|
||||||
@ -7550,7 +7552,7 @@ def _copy_netgen_param(dim, local_param, global_param):
|
|||||||
Create 1D/2D/3D netgen parameters from a NETGEN 1D2D3D parameter
|
Create 1D/2D/3D netgen parameters from a NETGEN 1D2D3D parameter
|
||||||
"""
|
"""
|
||||||
if dim==1:
|
if dim==1:
|
||||||
#TODO: Try to identify why we need to substract 1
|
#TODO: Try to identify why we need to substract 1 to have same results
|
||||||
local_param.NumberOfSegments(int(global_param.GetNbSegPerEdge())-1)
|
local_param.NumberOfSegments(int(global_param.GetNbSegPerEdge())-1)
|
||||||
elif dim==2:
|
elif dim==2:
|
||||||
local_param.SetMaxSize(global_param.GetMaxSize())
|
local_param.SetMaxSize(global_param.GetMaxSize())
|
||||||
@ -7559,6 +7561,7 @@ def _copy_netgen_param(dim, local_param, global_param):
|
|||||||
local_param.SetFineness(global_param.GetFineness())
|
local_param.SetFineness(global_param.GetFineness())
|
||||||
local_param.SetNbSegPerEdge(global_param.GetNbSegPerEdge())
|
local_param.SetNbSegPerEdge(global_param.GetNbSegPerEdge())
|
||||||
local_param.SetNbSegPerRadius(global_param.GetNbSegPerRadius())
|
local_param.SetNbSegPerRadius(global_param.GetNbSegPerRadius())
|
||||||
|
#TODO: Why the 0.9 to have same results
|
||||||
local_param.SetGrowthRate(global_param.GetGrowthRate()*0.9)
|
local_param.SetGrowthRate(global_param.GetGrowthRate()*0.9)
|
||||||
local_param.SetChordalError(global_param.GetChordalError())
|
local_param.SetChordalError(global_param.GetChordalError())
|
||||||
local_param.SetChordalErrorEnabled(global_param.GetChordalErrorEnabled())
|
local_param.SetChordalErrorEnabled(global_param.GetChordalErrorEnabled())
|
||||||
@ -7580,6 +7583,31 @@ def _copy_netgen_param(dim, local_param, global_param):
|
|||||||
local_param.SetGrowthRate(global_param.GetGrowthRate())
|
local_param.SetGrowthRate(global_param.GetGrowthRate())
|
||||||
local_param.SetNbThreads(global_param.GetNbThreads())
|
local_param.SetNbThreads(global_param.GetNbThreads())
|
||||||
|
|
||||||
|
|
||||||
|
def _shaperstudy2geom(geompyD, shaper_obj):
|
||||||
|
"""
|
||||||
|
Convertion of shaper object to geom object
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
geompyD: geomBuilder instance
|
||||||
|
shaper_obj: Shaper study object
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
geom object
|
||||||
|
|
||||||
|
"""
|
||||||
|
import tempfile
|
||||||
|
#Writing shaperstudy object into a brep file
|
||||||
|
fid, tmp_file = tempfile.mkstemp(suffix='.brep')
|
||||||
|
with open(fid, 'wb') as f:
|
||||||
|
f.write(shaper_obj.GetShapeStream())
|
||||||
|
# Reimporting brep file into geom
|
||||||
|
real_geom = geompyD.ImportBREP(tmp_file)
|
||||||
|
os.remove(tmp_file)
|
||||||
|
|
||||||
|
return real_geom
|
||||||
|
|
||||||
|
|
||||||
def _split_geom(geompyD, geom):
|
def _split_geom(geompyD, geom):
|
||||||
"""
|
"""
|
||||||
Splitting geometry into n solids and a 2D/1D compound
|
Splitting geometry into n solids and a 2D/1D compound
|
||||||
@ -7588,7 +7616,11 @@ def _split_geom(geompyD, geom):
|
|||||||
geompyD: geomBuilder instance
|
geompyD: geomBuilder instance
|
||||||
geom: geometrical object for meshing
|
geom: geometrical object for meshing
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
compound containing all the 1D,2D elements
|
||||||
|
list of solids
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Splitting geometry into 3D elements and all the 2D/1D into one compound
|
# Splitting geometry into 3D elements and all the 2D/1D into one compound
|
||||||
object_solids = geompyD.ExtractShapes(geom, geompyD.ShapeType["SOLID"],
|
object_solids = geompyD.ExtractShapes(geom, geompyD.ShapeType["SOLID"],
|
||||||
True)
|
True)
|
||||||
@ -7615,7 +7647,6 @@ def _split_geom(geompyD, geom):
|
|||||||
'Face_{}'.format(iface))
|
'Face_{}'.format(iface))
|
||||||
|
|
||||||
# Creating submesh for edges 1D/2D part
|
# Creating submesh for edges 1D/2D part
|
||||||
|
|
||||||
all_faces = geompyD.MakeCompound(faces)
|
all_faces = geompyD.MakeCompound(faces)
|
||||||
geompyD.addToStudy(all_faces, 'Compound_1')
|
geompyD.addToStudy(all_faces, 'Compound_1')
|
||||||
all_faces = geompyD.MakeGlueEdges(all_faces, 1e-07)
|
all_faces = geompyD.MakeGlueEdges(all_faces, 1e-07)
|
||||||
@ -7624,6 +7655,8 @@ def _split_geom(geompyD, geom):
|
|||||||
|
|
||||||
return all_faces, solids
|
return all_faces, solids
|
||||||
|
|
||||||
|
|
||||||
|
MULTITHREAD, MULTINODE = range(2)
|
||||||
class ParallelismSettings:
|
class ParallelismSettings:
|
||||||
"""
|
"""
|
||||||
Defines the parameters for the parallelism of ParallelMesh
|
Defines the parameters for the parallelism of ParallelMesh
|
||||||
@ -7640,21 +7673,109 @@ class ParallelismSettings:
|
|||||||
|
|
||||||
self._mesh = mesh
|
self._mesh = mesh
|
||||||
|
|
||||||
|
|
||||||
|
class MTParallelismSettings(ParallelismSettings):
|
||||||
|
"""
|
||||||
|
Defines the parameters for the parallelism of ParallelMesh using MultiThreading
|
||||||
|
"""
|
||||||
|
def __init__(self, mesh):
|
||||||
|
ParallelismSettings.__init__(self, mesh)
|
||||||
|
|
||||||
|
# Multithreading methods
|
||||||
def SetNbThreads(self, nbThreads):
|
def SetNbThreads(self, nbThreads):
|
||||||
"""
|
""" Set the number of threads for multithread """
|
||||||
Set the number of threads for multithreading
|
|
||||||
"""
|
|
||||||
if nbThreads < 1:
|
if nbThreads < 1:
|
||||||
raise ValueError("Number of threads must be stricly greater than 1")
|
raise ValueError("Number of threads must be stricly greater than 1")
|
||||||
|
|
||||||
self._mesh.mesh.SetNbThreads(nbThreads)
|
self._mesh.mesh.SetNbThreads(nbThreads)
|
||||||
|
|
||||||
def GetNbThreads(self):
|
def GetNbThreads(self):
|
||||||
"""
|
""" Get Number of threads """
|
||||||
Get Number of threads
|
|
||||||
"""
|
|
||||||
return self._mesh.mesh.GetNbThreads()
|
return self._mesh.mesh.GetNbThreads()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
""" str conversion """
|
||||||
|
string = "\nParameter for MultiThreading parallelism:\n"
|
||||||
|
string += "NbThreads: {}\n".format(self.GetNbThreads())
|
||||||
|
|
||||||
|
return string
|
||||||
|
|
||||||
|
|
||||||
|
class MNParallelismSettings(ParallelismSettings):
|
||||||
|
"""
|
||||||
|
Defines the parameters for the parallelism of ParallelMesh using MultiNodal
|
||||||
|
"""
|
||||||
|
def __init__(self, mesh):
|
||||||
|
ParallelismSettings.__init__(self, mesh)
|
||||||
|
|
||||||
|
def GetResource(self):
|
||||||
|
""" Get the resource on which to run """
|
||||||
|
return self._mesh.mesh.GetResource()
|
||||||
|
|
||||||
|
def SetResource(self, resource):
|
||||||
|
""" Set the resource on which to run """
|
||||||
|
self._mesh.mesh.SetResource(resource)
|
||||||
|
|
||||||
|
def SetNbProc(self, nbProc):
|
||||||
|
""" Set the number of Processor for multinode """
|
||||||
|
if nbProc < 1:
|
||||||
|
raise ValueError("Number of Proc must be stricly greater than 1")
|
||||||
|
self._mesh.mesh.SetNbProc(nbProc)
|
||||||
|
|
||||||
|
def GetNbProc(self):
|
||||||
|
""" Get Number of Processor """
|
||||||
|
return self._mesh.mesh.GetNbProc()
|
||||||
|
|
||||||
|
def SetNbProcPerNode(self, nbProcPerNode):
|
||||||
|
""" Set the number of Processor Per Node for multinode """
|
||||||
|
if nbProcPerNode < 1:
|
||||||
|
raise ValueError("Number of Processor Per Node must be stricly greater than 1")
|
||||||
|
|
||||||
|
self._mesh.mesh.SetNbProcPerNode(nbProcPerNode)
|
||||||
|
|
||||||
|
def GetNbProcPerNode(self):
|
||||||
|
""" Get Number of Processor Per Node """
|
||||||
|
return self._mesh.mesh.GetNbProcPerNode()
|
||||||
|
|
||||||
|
def SetNbNode(self, nbNode):
|
||||||
|
""" Set the number of Node for multinode """
|
||||||
|
if nbNode < 1:
|
||||||
|
raise ValueError("Number of Node must be stricly greater than 1")
|
||||||
|
self._mesh.mesh.SetNbNode(nbNode)
|
||||||
|
|
||||||
|
def GetNbNode(self):
|
||||||
|
""" Get Number of Node """
|
||||||
|
return self._mesh.mesh.GetNbNode()
|
||||||
|
|
||||||
|
def SetWcKey(self, wcKey):
|
||||||
|
""" Set the number of Node for multinode """
|
||||||
|
self._mesh.mesh.SetWcKey(wcKey)
|
||||||
|
|
||||||
|
def GetWcKey(self):
|
||||||
|
""" Get Number of Node """
|
||||||
|
return self._mesh.mesh.GetWcKey()
|
||||||
|
|
||||||
|
def SetWalltime(self, walltime):
|
||||||
|
""" Set the number of Node for multinode """
|
||||||
|
self._mesh.mesh.SetWalltime(walltime)
|
||||||
|
|
||||||
|
def GetWalltime(self):
|
||||||
|
""" Get Number of Node """
|
||||||
|
return self._mesh.mesh.GetWalltime()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
""" str conversion """
|
||||||
|
string = "\nParameter for MultiNode parallelism:\n"
|
||||||
|
string += "Reource: {}\n".format(self.GetResource())
|
||||||
|
string += "NbProc: {}\n".format(self.GetNbProc())
|
||||||
|
string += "NbProcPerNode: {}\n".format(self.GetNbProcPerNode())
|
||||||
|
string += "NbNode: {}\n".format(self.GetNbNode())
|
||||||
|
string += "WcKey: {}\n".format(self.GetWcKey())
|
||||||
|
string += "Walltime: {}\n".format(self.GetWalltime())
|
||||||
|
|
||||||
|
return string
|
||||||
|
|
||||||
|
|
||||||
class ParallelMesh(Mesh):
|
class ParallelMesh(Mesh):
|
||||||
"""
|
"""
|
||||||
Surcharge on Mesh for parallel computation of a mesh
|
Surcharge on Mesh for parallel computation of a mesh
|
||||||
@ -7678,33 +7799,61 @@ class ParallelMesh(Mesh):
|
|||||||
if not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
|
if not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
|
||||||
raise ValueError("geom argument must be a geometry")
|
raise ValueError("geom argument must be a geometry")
|
||||||
|
|
||||||
|
import SHAPERSTUDY
|
||||||
|
import shaperBuilder
|
||||||
|
# If we have a shaper object converting it into geom (temporary solution)
|
||||||
|
if isinstance(geom, SHAPERSTUDY.SHAPERSTUDY_ORB._objref_SHAPER_Object):
|
||||||
|
geom_obj = _shaperstudy2geom(geompyD, geom)
|
||||||
|
else:
|
||||||
|
geom_obj = geom
|
||||||
|
|
||||||
# Splitting geometry into one geom containing 1D and 2D elements and a
|
# Splitting geometry into one geom containing 1D and 2D elements and a
|
||||||
# list of 3D elements
|
# list of 3D elements
|
||||||
super(ParallelMesh, self).__init__(smeshpyD, geompyD, geom, name, parallel=True)
|
super(ParallelMesh, self).__init__(smeshpyD, geompyD, geom_obj, name, parallel=True)
|
||||||
|
|
||||||
if split_geom:
|
if split_geom:
|
||||||
self._all_faces, self._solids = _split_geom(geompyD, geom)
|
self._all_faces, self._solids = _split_geom(geompyD, geom_obj)
|
||||||
|
|
||||||
self.UseExistingSegments()
|
order = []
|
||||||
self.UseExistingFaces()
|
self._algo2d = self.Triangle(geom=geom_obj, algo="NETGEN_2D")
|
||||||
|
|
||||||
self._algo2d = self.Triangle(geom=self._all_faces, algo="NETGEN_2D")
|
|
||||||
self._algo3d = []
|
self._algo3d = []
|
||||||
|
|
||||||
for solid_id, solid in enumerate(self._solids):
|
for solid_id, solid in enumerate(self._solids):
|
||||||
name = "Solid_{}".format(solid_id)
|
name = "Solid_{}".format(solid_id)
|
||||||
self.UseExistingSegments(geom=solid)
|
|
||||||
self.UseExistingFaces(geom=solid)
|
|
||||||
algo3d = self.Tetrahedron(geom=solid, algo="NETGEN_3D_Remote")
|
algo3d = self.Tetrahedron(geom=solid, algo="NETGEN_3D_Remote")
|
||||||
self._algo3d.append(algo3d)
|
self._algo3d.append(algo3d)
|
||||||
|
|
||||||
self._param = ParallelismSettings(self)
|
self._param = None
|
||||||
|
|
||||||
|
|
||||||
|
def GetNbSolids(self):
|
||||||
|
"""
|
||||||
|
Return the number of 3D solids
|
||||||
|
"""
|
||||||
|
return len(self._solids)
|
||||||
|
|
||||||
|
def GetParallelismMethod(self):
|
||||||
|
""" Get the parallelims method """
|
||||||
|
return self.mesh.GetParallelismMethod()
|
||||||
|
|
||||||
|
def SetParallelismMethod(self, method):
|
||||||
|
""" Set the parallelims method """
|
||||||
|
if method not in [MULTITHREAD , MULTINODE]:
|
||||||
|
raise ValueError("Parallelism method can only be 0:MultiThread or 1:MultiNode")
|
||||||
|
|
||||||
|
self.mesh.SetParallelismMethod(method)
|
||||||
|
|
||||||
|
if method == MULTITHREAD:
|
||||||
|
self._param = MTParallelismSettings(self)
|
||||||
|
else:
|
||||||
|
self._param = MNParallelismSettings(self)
|
||||||
|
|
||||||
def GetParallelismSettings(self):
|
def GetParallelismSettings(self):
|
||||||
"""
|
"""
|
||||||
Return class to set parameters for the parallelism
|
Return class to set parameters for the parallelism
|
||||||
"""
|
"""
|
||||||
|
if self._param is None:
|
||||||
|
raise Exception("You need to set Parallelism method first (SetParallelismMethod)")
|
||||||
return self._param
|
return self._param
|
||||||
|
|
||||||
def AddGlobalHypothesis(self, hyp):
|
def AddGlobalHypothesis(self, hyp):
|
||||||
@ -7731,7 +7880,6 @@ class ParallelMesh(Mesh):
|
|||||||
|
|
||||||
pass # End of ParallelMesh
|
pass # End of ParallelMesh
|
||||||
|
|
||||||
|
|
||||||
class meshProxy(SMESH._objref_SMESH_Mesh):
|
class meshProxy(SMESH._objref_SMESH_Mesh):
|
||||||
"""
|
"""
|
||||||
Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
|
Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
|
||||||
@ -7774,10 +7922,20 @@ class meshProxy(SMESH._objref_SMESH_Mesh):
|
|||||||
if len( args ) == 1:
|
if len( args ) == 1:
|
||||||
args += True,
|
args += True,
|
||||||
return SMESH._objref_SMESH_Mesh.ExportDAT(self, *args)
|
return SMESH._objref_SMESH_Mesh.ExportDAT(self, *args)
|
||||||
pass
|
|
||||||
omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
|
omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
|
||||||
|
|
||||||
|
|
||||||
|
class parallelMeshProxy(SMESH._objref_SMESH_ParallelMesh):
|
||||||
|
def __init__(self,*args):
|
||||||
|
SMESH._objref_SMESH_ParallelMesh.__init__(self,*args)
|
||||||
|
def __deepcopy__(self, memo=None):
|
||||||
|
new = self.__class__(self)
|
||||||
|
return new
|
||||||
|
omniORB.registerObjref(SMESH._objref_SMESH_ParallelMesh._NP_RepositoryId, parallelMeshProxy)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class submeshProxy(SMESH._objref_SMESH_subMesh):
|
class submeshProxy(SMESH._objref_SMESH_subMesh):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
Loading…
Reference in New Issue
Block a user