mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2024-11-11 16:19:16 +05:00
Modifications to properly handle parallel compute for 2D
This commit is contained in:
parent
b0b5c3242d
commit
aa034dad38
@ -78,12 +78,19 @@ 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')
|
||||
geompy.addToStudy(rubik_cube, 'rubik_cube')
|
||||
|
||||
|
||||
smesh = smeshBuilder.New()
|
||||
print("Creating Parallel Mesh")
|
||||
par_mesh = smesh.ParallelMesh(rubik_cube, name="par_mesh", mesher2D="NETGEN_2D_Remote")
|
||||
par_mesh = smesh.ParallelMesh(rubik_cube, name="par_mesh")
|
||||
|
||||
print("Creating hypoehtesis for netgen")
|
||||
NETGEN_2D_Parameters_1 = smesh.CreateHypothesisByAverageLength( 'NETGEN_Parameters_2D',
|
||||
'NETGENEngine', 34.641, 0 )
|
||||
|
||||
print("Adding hypothesis")
|
||||
par_mesh.Add2DGlobalHypothesis(NETGEN_2D_Parameters_1)
|
||||
|
||||
print("Setting parallelism method")
|
||||
par_mesh.SetParallelismMethod(smeshBuilder.MULTITHREAD)
|
||||
|
@ -54,11 +54,11 @@ 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')
|
||||
geompy.addToStudy(rubik_cube, 'rubik_cube')
|
||||
|
||||
smesh = smeshBuilder.New()
|
||||
print("Creating Parallel Mesh")
|
||||
par_mesh = smesh.ParallelMesh(rubik_cube, name="par_mesh", mesher3D="GMSH")
|
||||
par_mesh = smesh.ParallelMesh(rubik_cube, name="par_mesh")
|
||||
|
||||
print("Creating hypoehtesis for gmsh")
|
||||
GMSH_3D_Parameters_1 = smesh.CreateHypothesis( 'GMSH_Parameters',
|
||||
|
@ -54,7 +54,7 @@ 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')
|
||||
geompy.addToStudy(rubik_cube, 'rubik_cube')
|
||||
|
||||
|
||||
smesh = smeshBuilder.New()
|
||||
|
@ -1109,6 +1109,9 @@ module SMESH
|
||||
long GetParallelismMethod();
|
||||
void SetParallelismMethod(in long aMethod);
|
||||
|
||||
long GetParallelismDimension();
|
||||
void SetParallelismDimension(in long aDim);
|
||||
|
||||
// Parameters for MutliThreading
|
||||
long GetNbThreads();
|
||||
void SetNbThreads(in long nbThreads);
|
||||
|
@ -394,7 +394,7 @@ bool SMESH_Gen::parallelComputeSubMeshes(
|
||||
// do not mesh vertices of a pseudo shape
|
||||
const TopoDS_Shape& shape = smToCompute->GetSubShape();
|
||||
const TopAbs_ShapeEnum shapeType = shape.ShapeType();
|
||||
// Not doing in parallel 1D and 2D meshes
|
||||
// Not doing in parallel 1D meshes
|
||||
if ( !aMesh.HasShapeToMesh() && shapeType == TopAbs_VERTEX )
|
||||
continue;
|
||||
|
||||
@ -402,22 +402,10 @@ bool SMESH_Gen::parallelComputeSubMeshes(
|
||||
// Waiting for all threads for the previous type to end
|
||||
aMesh.wait();
|
||||
|
||||
std::string file_name;
|
||||
switch(previousShapeType){
|
||||
case TopAbs_FACE:
|
||||
file_name = "Mesh2D.med";
|
||||
break;
|
||||
case TopAbs_EDGE:
|
||||
file_name = "Mesh1D.med";
|
||||
break;
|
||||
//case TopAbs_VERTEX:
|
||||
// file_name = "Mesh0D.med";
|
||||
// break;
|
||||
case TopAbs_SOLID:
|
||||
default:
|
||||
file_name = "";
|
||||
break;
|
||||
}
|
||||
std::string file_name="";
|
||||
if (previousShapeType == aParMesh.GetDumpElement())
|
||||
file_name = "Mesh"+std::to_string(aParMesh.GetParallelismDimension()-1)+"D.med";
|
||||
|
||||
if(file_name != "")
|
||||
{
|
||||
fs::path mesh_file = fs::path(aParMesh.GetTmpFolder()) / fs::path(file_name);
|
||||
@ -439,7 +427,7 @@ bool SMESH_Gen::parallelComputeSubMeshes(
|
||||
continue;
|
||||
}
|
||||
// Parallelism is only for 3D parts
|
||||
if(shapeType!=TopAbs_SOLID){
|
||||
if(shapeType!=aMesh.GetParallelElement()){
|
||||
compute_function(smToCompute, computeEvent,
|
||||
shapeSM, aShapeOnly, allowedSubShapes,
|
||||
aShapesId);
|
||||
|
@ -397,6 +397,7 @@ class SMESH_EXPORT SMESH_Mesh
|
||||
virtual void wait(){};
|
||||
|
||||
virtual bool IsParallel(){throw SALOME_Exception("Calling SMESH_Mesh::IsParallel");return false;};
|
||||
virtual int GetParallelElement(){throw SALOME_Exception("Calling SMESH_Mesh::GetParallelElement");return 0;};
|
||||
|
||||
virtual bool ComputeSubMeshes(
|
||||
SMESH_Gen* gen,
|
||||
|
@ -151,6 +151,34 @@ void SMESH_ParallelMesh::SetNbThreads(long nbThreads)
|
||||
_NbThreads=nbThreads;
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* \brief Get the element associated to the dimension of the parallelism
|
||||
*/
|
||||
//=============================================================================
|
||||
int SMESH_ParallelMesh::GetParallelElement()
|
||||
{
|
||||
if (_paraDim==2){
|
||||
return TopAbs_FACE;
|
||||
}else{
|
||||
return TopAbs_SOLID;
|
||||
}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* \brief Get the element associated to the dimension of the parallelism
|
||||
*/
|
||||
//=============================================================================
|
||||
int SMESH_ParallelMesh::GetDumpElement()
|
||||
{
|
||||
if (_paraDim==2){
|
||||
return TopAbs_EDGE;
|
||||
}else{
|
||||
return TopAbs_FACE;
|
||||
}
|
||||
};
|
||||
|
||||
bool SMESH_ParallelMesh::ComputeSubMeshes(
|
||||
SMESH_Gen* gen,
|
||||
SMESH_Mesh & aMesh,
|
||||
|
@ -81,11 +81,16 @@ class SMESH_EXPORT SMESH_ParallelMesh: public SMESH_Mesh
|
||||
|
||||
//
|
||||
bool IsParallel() override {return true;};
|
||||
int GetParallelElement() override;
|
||||
int GetDumpElement();
|
||||
|
||||
// Parallelims paramaters
|
||||
int GetParallelismMethod() {return _method;};
|
||||
void SetParallelismMethod(int aMethod) {_method = aMethod;};
|
||||
|
||||
int GetParallelismDimension() {return _paraDim;};
|
||||
void SetParallelismDimension(int aDim) {_paraDim = aDim;};
|
||||
|
||||
// Mutlithreading parameters
|
||||
int GetNbThreads() {return _NbThreads;};
|
||||
void SetNbThreads(long nbThreads);
|
||||
@ -134,6 +139,7 @@ class SMESH_EXPORT SMESH_ParallelMesh: public SMESH_Mesh
|
||||
#endif
|
||||
boost::filesystem::path tmp_folder;
|
||||
int _method = ParallelismMethod::MultiThread;
|
||||
int _paraDim = 3;
|
||||
|
||||
int _NbThreads = std::thread::hardware_concurrency();
|
||||
|
||||
|
@ -48,6 +48,7 @@ class SMESH_EXPORT SMESH_SequentialMesh: public SMESH_Mesh
|
||||
void wait() override {};
|
||||
|
||||
bool IsParallel() override {return false;};
|
||||
int GetParallelElement() override {return 0;};
|
||||
|
||||
bool ComputeSubMeshes (
|
||||
SMESH_Gen* gen,
|
||||
|
@ -1517,7 +1517,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event)
|
||||
// check submeshes needed
|
||||
// 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
|
||||
if (_father->HasShapeToMesh() && (!_father->IsParallel() || shape.ShapeType() != TopAbs_SOLID )) {
|
||||
if (_father->HasShapeToMesh() && (!_father->IsParallel() || shape.ShapeType() != _father->GetParallelElement() )) {
|
||||
bool subComputed = false, subFailed = false;
|
||||
if (!algo->OnlyUnaryInput()) {
|
||||
// --- commented for bos#22320 to compute all sub-shapes at once if possible;
|
||||
|
@ -81,6 +81,25 @@ void SMESH_ParallelMesh_i::SetParallelismMethod(CORBA::Long aMethod){
|
||||
DownCast()->SetParallelismMethod(aMethod);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* \brief Get the parallell dimension
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
CORBA::Long SMESH_ParallelMesh_i::GetParallelismDimension(){
|
||||
return DownCast()->GetParallelismDimension();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* \brief Set the parallell dimension
|
||||
*/
|
||||
//=============================================================================
|
||||
void SMESH_ParallelMesh_i::SetParallelismDimension(CORBA::Long aDim){
|
||||
DownCast()->SetParallelismDimension(aDim);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* \brief Get the number of threads for a parallel computation
|
||||
|
@ -53,6 +53,9 @@ class SMESH_I_EXPORT SMESH_ParallelMesh_i:
|
||||
CORBA::Long GetParallelismMethod();
|
||||
void SetParallelismMethod(CORBA::Long aMethod);
|
||||
|
||||
CORBA::Long GetParallelismDimension();
|
||||
void SetParallelismDimension(CORBA::Long aDim);
|
||||
|
||||
CORBA::Long GetNbThreads();
|
||||
void SetNbThreads(CORBA::Long nbThreads);
|
||||
|
||||
|
@ -462,7 +462,7 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
|
||||
obj,name = name,obj
|
||||
return Mesh(self, self.geompyD, obj, name)
|
||||
|
||||
def ParallelMesh(self, obj, name=0, split_geom=True, mesher2D=None, mesher3D="NETGEN"):
|
||||
def ParallelMesh(self, obj, name=0, split_geom=True):
|
||||
"""
|
||||
Create a parallel mesh.
|
||||
|
||||
@ -476,7 +476,7 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
|
||||
an instance of class :class:`ParallelMesh`.
|
||||
"""
|
||||
return ParallelMesh(self, self.geompyD, obj,
|
||||
split_geom=split_geom, name=name, mesher2D=mesher2D, mesher3D=mesher3D )
|
||||
split_geom=split_geom, name=name)
|
||||
|
||||
def RemoveMesh( self, mesh ):
|
||||
"""
|
||||
@ -7582,8 +7582,8 @@ def _copy_netgen_param(dim, local_param, global_param):
|
||||
Create 1D/2D/3D netgen parameters from a NETGEN 1D2D3D parameter
|
||||
"""
|
||||
if dim==1:
|
||||
#TODO: Try to identify why we need to substract 1 to have same results
|
||||
local_param.NumberOfSegments(int(global_param.GetNbSegPerEdge())-1)
|
||||
#TODO: More global conversion ? or let user define it
|
||||
local_param.NumberOfSegments(int(global_param.GetMaxSize()))
|
||||
elif dim==2:
|
||||
local_param.SetMaxSize(global_param.GetMaxSize())
|
||||
local_param.SetMinSize(global_param.GetMinSize())
|
||||
@ -7667,23 +7667,15 @@ def _split_geom(geompyD, geom):
|
||||
|
||||
faces = []
|
||||
iface = 0
|
||||
for isolid, solid in enumerate(solids):
|
||||
solid_faces = geompyD.ExtractShapes(solid, geompyD.ShapeType["FACE"],
|
||||
solid_faces = geompyD.ExtractShapes(geom, geompyD.ShapeType["FACE"],
|
||||
True)
|
||||
for face in solid_faces:
|
||||
faces.append(face)
|
||||
iface += 1
|
||||
geompyD.addToStudyInFather(solid, face,
|
||||
geompyD.addToStudyInFather(geom, face,
|
||||
'Face_{}'.format(iface))
|
||||
|
||||
# Creating submesh for edges 1D/2D part
|
||||
all_faces = geompyD.MakeCompound(faces)
|
||||
geompyD.addToStudy(all_faces, 'Compound_1')
|
||||
all_faces = geompyD.MakeGlueEdges(all_faces, 1e-07)
|
||||
all_faces = geompyD.MakeGlueFaces(all_faces, 1e-07)
|
||||
geompyD.addToStudy(all_faces, 'global2D')
|
||||
|
||||
return all_faces, solids
|
||||
return faces, solids
|
||||
|
||||
|
||||
MULTITHREAD, MULTINODE = range(2)
|
||||
@ -7810,7 +7802,7 @@ class ParallelMesh(Mesh):
|
||||
"""
|
||||
Surcharge on Mesh for parallel computation of a mesh
|
||||
"""
|
||||
def __init__(self, smeshpyD, geompyD, geom, split_geom=True, name=0, mesher2D=None, mesher3D="NETGEN"):
|
||||
def __init__(self, smeshpyD, geompyD, geom, split_geom=True, name=0):
|
||||
"""
|
||||
Create a parallel mesh.
|
||||
|
||||
@ -7833,37 +7825,55 @@ class ParallelMesh(Mesh):
|
||||
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)
|
||||
self._geom_obj = _shaperstudy2geom(geompyD, geom)
|
||||
else:
|
||||
geom_obj = geom
|
||||
self._geom_obj = geom
|
||||
|
||||
# Splitting geometry into one geom containing 1D and 2D elements and a
|
||||
# list of 3D elements
|
||||
super(ParallelMesh, self).__init__(smeshpyD, geompyD, geom_obj, name, parallel=True)
|
||||
super(ParallelMesh, self).__init__(smeshpyD, geompyD, self._geom_obj, name, parallel=True)
|
||||
|
||||
if split_geom:
|
||||
self._all_faces, self._solids = _split_geom(geompyD, geom_obj)
|
||||
self._faces, self._solids = _split_geom(geompyD, self._geom_obj)
|
||||
|
||||
self._param = None
|
||||
|
||||
def _build_submeshes(self, mesher2D, mesher3D):
|
||||
"""
|
||||
Contruct the submeshes for a parallel use of smesh
|
||||
|
||||
Parameters:
|
||||
mesher2D: name of 2D mesher for 2D parallel compute (NETGEN)
|
||||
mesher3D: name of 3D mesher for 3D parallel compute (NETGEN or
|
||||
GMSH)
|
||||
"""
|
||||
|
||||
# Building global 2D mesher
|
||||
if mesher3D:
|
||||
if mesher3D == "NETGEN":
|
||||
self._algo2d = self.Triangle(geom=geom_obj, algo="NETGEN_2D")
|
||||
algo2D = "NETGEN_2D"
|
||||
elif mesher3D == "GMSH":
|
||||
self._algo2d = self.Triangle(geom=geom_obj, algo="GMSH_2D")
|
||||
algo2D = "GMSH_2D"
|
||||
else:
|
||||
raise ValueError("mesher3D should be either NETGEN or GMSH")
|
||||
|
||||
self._algo2d = self.Triangle(geom=self._geom_obj, algo=algo2D)
|
||||
|
||||
if mesher2D is not None:
|
||||
# Parallel 2D
|
||||
if mesher2D:
|
||||
#Means that we want to mesh face of solids in parallel and not
|
||||
#the volume
|
||||
self._algo2d = []
|
||||
#For the moment use AutomaticLength based on finesse
|
||||
self._algo1d = self.Segment().AutomaticLength(0.1)
|
||||
# TODO: replace by input hypothesis
|
||||
self._algo1d = self.Segment(geom=self._geom_obj)
|
||||
|
||||
for solid_id, solid in enumerate(self._solids):
|
||||
name = "Solid_{}".format(solid_id)
|
||||
algo2d = self.Triangle(geom=solid, algo="NETGEN_2D_Remote")
|
||||
for face_id, face in enumerate(self._faces):
|
||||
name = "face_{}".format(face_id)
|
||||
algo2d = self.Triangle(geom=face, algo="NETGEN_2D_Remote")
|
||||
self._algo2d.append(algo2d)
|
||||
else:
|
||||
|
||||
if mesher3D:
|
||||
self._algo3d = []
|
||||
for solid_id, solid in enumerate(self._solids):
|
||||
name = "Solid_{}".format(solid_id)
|
||||
@ -7874,14 +7884,18 @@ class ParallelMesh(Mesh):
|
||||
algo3d = self.Tetrahedron(geom=solid, algo="GMSH_3D_Remote")
|
||||
self._algo3d.append(algo3d)
|
||||
|
||||
self._param = None
|
||||
|
||||
def GetNbSolids(self):
|
||||
"""
|
||||
Return the number of 3D solids
|
||||
"""
|
||||
return len(self._solids)
|
||||
|
||||
def GetNbFaces(self):
|
||||
"""
|
||||
Return the number of 2D faces
|
||||
"""
|
||||
return len(self._faces)
|
||||
|
||||
def GetParallelismMethod(self):
|
||||
""" Get the parallelims method """
|
||||
return self.mesh.GetParallelismMethod()
|
||||
@ -7918,11 +7932,16 @@ class ParallelMesh(Mesh):
|
||||
"""
|
||||
if isinstance(hyp, NETGENPlugin._objref_NETGENPlugin_Hypothesis):
|
||||
copy_param = _copy_netgen_param
|
||||
mesher3D = "NETGEN"
|
||||
elif isinstance(hyp, GMSHPlugin._objref_GMSHPlugin_Hypothesis):
|
||||
copy_param = _copy_gmsh_param
|
||||
mesher3D = "GMSH"
|
||||
else:
|
||||
raise ValueError("param must come from NETGENPlugin or GMSHPlugin")
|
||||
|
||||
self.mesh.SetParallelismDimension(3)
|
||||
self._build_submeshes(None, mesher3D)
|
||||
|
||||
param2d = self._algo2d.Parameters()
|
||||
copy_param(2, param2d, hyp)
|
||||
|
||||
@ -7930,6 +7949,31 @@ class ParallelMesh(Mesh):
|
||||
param3d = algo3d.Parameters()
|
||||
copy_param(3, param3d, hyp)
|
||||
|
||||
def Add2DGlobalHypothesis(self, hyp):
|
||||
"""
|
||||
Split hypothesis to apply it to all the submeshes:
|
||||
- the 1D
|
||||
- each of the 2D faces
|
||||
|
||||
Parameters:
|
||||
hyp: a hypothesis to assign
|
||||
|
||||
"""
|
||||
if isinstance(hyp, NETGENPlugin._objref_NETGENPlugin_Hypothesis):
|
||||
copy_param = _copy_netgen_param
|
||||
mesher2D = "NETGEN"
|
||||
else:
|
||||
raise ValueError("param must come from NETGENPlugin")
|
||||
|
||||
self.mesh.SetParallelismDimension(2)
|
||||
self._build_submeshes(mesher2D, None)
|
||||
|
||||
param1d = self._algo1d
|
||||
copy_param(1, param1d, hyp)
|
||||
|
||||
for algo2d in self._algo2d:
|
||||
param2d = algo2d.Parameters()
|
||||
copy_param(2, param2d, hyp)
|
||||
|
||||
pass # End of ParallelMesh
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user