Splitting gen compute seq/para + clean up + remove int argument + solve bug (commented notifyevent)

This commit is contained in:
Yoann Audouin 2022-09-29 16:25:05 +02:00
parent d5617f4801
commit c9a5231c32
6 changed files with 205 additions and 97 deletions

View File

@ -52,7 +52,7 @@ The mesh can include the following entities:
* **Node** - a mesh entity defining a position in 3D space with coordinates (x, y, z).
* **Edge** (or segment) - 1D mesh element linking two nodes.
* **Face** - 2D mesh element representing a part of surface bound by links between face nodes. A face can be a triangle, quadrangle or polygon.
* **Volume** - 3D mesh element representing a part of 3D space bound by volume facets. Nodes of a volume describing each facet are defined by the :ref:`connectivity convention <connectivity_page>`. A volume can be a tetrahedron, hexahedron, pentahedron, pyramid, hexagonal prism or polyhedron.
* **Volume** - 3D mesh element representing a part of 3D space bound by volume facets. Nodes of a volume describing each facet are defined by the :ref:`connectivity convention <connectivity_page>`. A volume can be a tetrahedron, hexahedron, pentahedron, pyramid, hexagonal or polyhedron.
* **0D** element - mesh element defined by one node.
* **Ball** element - discrete mesh element defined by a node and a diameter.

View File

@ -160,96 +160,25 @@ SMESH_Mesh* SMESH_Gen::CreateMesh(bool theIsEmbeddedMode)
return aMesh;
}
//=============================================================================
/*
* Parallel compute of a submesh
* This function is used to pass to thread_pool
*/
//=============================================================================
const std::function<void(int,
SMESH_subMesh*,
SMESH_subMesh::compute_event,
SMESH_subMesh*,
bool,
TopTools_IndexedMapOfShape *,
TSetOfInt*)>
compute_function([&] (int id,
SMESH_subMesh* sm,
SMESH_subMesh::compute_event event,
SMESH_subMesh *shapeSM,
bool aShapeOnly,
TopTools_IndexedMapOfShape *allowedSubShapes,
TSetOfInt* aShapesId) -> void
{
if (sm->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
{
sm->SetAllowedSubShapes( fillAllowed( shapeSM, aShapeOnly, allowedSubShapes ));
setCurrentSubMesh( sm );
sm->ComputeStateEngine(event);
setCurrentSubMesh( nullptr );
sm->SetAllowedSubShapes( nullptr );
}
if ( aShapesId )
aShapesId->insert( sm->GetId() );
});
//=============================================================================
/*
* Compute a mesh
*/
//=============================================================================
bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
bool SMESH_Gen::sequentialComputeSubMeshes(
SMESH_Mesh & aMesh,
const TopoDS_Shape & aShape,
const int aFlags /*= COMPACT_MESH*/,
const ::MeshDimension aDim /*=::MeshDim_3D*/,
const ::MeshDimension aDim,
TSetOfInt* aShapesId /*=0*/,
TopTools_IndexedMapOfShape* anAllowedSubShapes/*=0*/)
TopTools_IndexedMapOfShape* allowedSubShapes,
SMESH_subMesh::compute_event &computeEvent,
const bool includeSelf,
const bool complexShapeFirst,
const bool aShapeOnly)
{
MEMOSTAT;
const bool aShapeOnly = aFlags & SHAPE_ONLY;
const bool anUpward = aFlags & UPWARD;
const bool aCompactMesh = aFlags & COMPACT_MESH;
MESSAGE("Compute submeshes sequentialy");
bool ret = true;
SMESH_subMesh *sm, *shapeSM = aMesh.GetSubMesh(aShape);
const bool includeSelf = true;
const bool complexShapeFirst = true;
const int globalAlgoDim = 100;
// Pool of thread for computation
if(aMesh.IsParallel())
aMesh.InitPoolThreads();
SMESH_subMeshIteratorPtr smIt;
// Fix of Issue 22150. Due to !BLSURF->OnlyUnaryInput(), BLSURF computes edges
// that must be computed by Projection 1D-2D while the Projection asks to compute
// one face only.
SMESH_subMesh::compute_event computeEvent =
aShapeOnly ? SMESH_subMesh::COMPUTE_SUBMESH : SMESH_subMesh::COMPUTE;
if ( !aMesh.HasShapeToMesh() )
computeEvent = SMESH_subMesh::COMPUTE_NOGEOM; // if several algos and no geometry
TopTools_IndexedMapOfShape *allowedSubShapes = anAllowedSubShapes, allowedSub;
if ( aShapeOnly && !allowedSubShapes )
allowedSubShapes = &allowedSub;
if ( anUpward ) // is called from the below code in this method
{
// ===============================================
// Mesh all the sub-shapes starting from vertices
// ===============================================
TopAbs_ShapeEnum previousShapeType = TopAbs_VERTEX;
int nbThreads = aMesh.GetNbThreads();
MESSAGE("Running mesh with threads: " << nbThreads << " mesher: " << aMesh.GetMesherNbThreads());
SMESH_subMesh *shapeSM = aMesh.GetSubMesh(aShape);
smIt = shapeSM->getDependsOnIterator(includeSelf, !complexShapeFirst);
while ( smIt->more() )
@ -259,13 +188,118 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
// do not mesh vertices of a pseudo shape
const TopoDS_Shape& shape = smToCompute->GetSubShape();
const TopAbs_ShapeEnum shapeType = shape.ShapeType();
if ( !aMesh.HasShapeToMesh() && shapeType == TopAbs_VERTEX )
continue;
// check for preview dimension limitations
if ( aShapesId && GetShapeDim( shapeType ) > (int)aDim )
{
// clear compute state not to show previous compute errors
// if preview invoked less dimension less than previous
smToCompute->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
continue;
}
if (smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
{
if (_compute_canceled)
return false;
smToCompute->SetAllowedSubShapes( fillAllowed( shapeSM, aShapeOnly, allowedSubShapes ));
setCurrentSubMesh( smToCompute );
smToCompute->ComputeStateEngine( computeEvent );
setCurrentSubMesh( nullptr );
smToCompute->SetAllowedSubShapes( nullptr );
}
// we check all the sub-meshes here and detect if any of them failed to compute
if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE &&
( shapeType != TopAbs_EDGE || !SMESH_Algo::isDegenerated( TopoDS::Edge( shape ))))
ret = false;
else if ( aShapesId )
aShapesId->insert( smToCompute->GetId() );
}
//aMesh.GetMeshDS()->Modified();
return ret;
};
//=============================================================================
/*
* Parallel compute of a submesh
* This function is used to pass to thread_pool
*/
//=============================================================================
const std::function<void(SMESH_subMesh*,
SMESH_subMesh::compute_event,
SMESH_subMesh*,
bool,
TopTools_IndexedMapOfShape *,
TSetOfInt*)>
compute_function([&] (SMESH_subMesh* sm,
SMESH_subMesh::compute_event event,
SMESH_subMesh *shapeSM,
bool aShapeOnly,
TopTools_IndexedMapOfShape *allowedSubShapes,
TSetOfInt* aShapesId) -> void
{
if (sm->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
{
sm->SetAllowedSubShapes( fillAllowed( shapeSM, aShapeOnly, allowedSubShapes ));
//setCurrentSubMesh( sm );
sm->ComputeStateEngine(event);
//setCurrentSubMesh( nullptr );
sm->SetAllowedSubShapes( nullptr );
}
if ( aShapesId )
aShapesId->insert( sm->GetId() );
});
bool SMESH_Gen::parallelComputeSubMeshes(
SMESH_Mesh & aMesh,
const TopoDS_Shape & aShape,
const ::MeshDimension aDim,
TSetOfInt* aShapesId /*=0*/,
TopTools_IndexedMapOfShape* allowedSubShapes,
SMESH_subMesh::compute_event &computeEvent,
const bool includeSelf,
const bool complexShapeFirst,
const bool aShapeOnly)
{
bool ret = true;
SMESH_subMeshIteratorPtr smIt;
SMESH_subMesh *shapeSM = aMesh.GetSubMesh(aShape);
// Pool of thread for computation
// TODO: move when parallelMesh created
aMesh.InitPoolThreads();
TopAbs_ShapeEnum previousShapeType = TopAbs_VERTEX;
int nbThreads = aMesh.GetNbThreads();
MESSAGE("Compute submeshes with threads: " << nbThreads << " mesher: " << aMesh.GetMesherNbThreads());
smIt = shapeSM->getDependsOnIterator(includeSelf, !complexShapeFirst);
while ( smIt->more() )
{
SMESH_subMesh* smToCompute = smIt->next();
// 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
if ( !aMesh.HasShapeToMesh() && shapeType == TopAbs_VERTEX )
continue;
if(shapeType==TopAbs_FACE||shapeType==TopAbs_EDGE)
aMesh.SetNbThreads(0);
else
aMesh.SetNbThreads(nbThreads);
if ((aMesh.IsParallel()||nbThreads!=0) && shapeType != previousShapeType) {
if (shapeType != previousShapeType) {
// Waiting for all threads for the previous type to end
aMesh.wait();
@ -303,32 +337,83 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
smToCompute->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
continue;
}
if(aMesh.IsParallel())
{
boost::asio::post(*(aMesh._pool), std::bind(compute_function, 1, smToCompute, computeEvent,
boost::asio::post(*(aMesh._pool), std::bind(compute_function, smToCompute, computeEvent,
shapeSM, aShapeOnly, allowedSubShapes,
aShapesId));
} else {
compute_function(1 ,smToCompute, computeEvent,
shapeSM, aShapeOnly, allowedSubShapes,
aShapesId);
if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE &&
( shapeType != TopAbs_EDGE || !SMESH_Algo::isDegenerated( TopoDS::Edge( shape ))))
ret = false;
else if ( aShapesId )
aShapesId->insert( smToCompute->GetId() );
}
}
// TODO: Check error handling in parallel mode
if(aMesh.IsParallel()){
// Waiting for the thread for Solids to finish
aMesh.wait();
}
aMesh.GetMeshDS()->Modified();
return ret;
};
//=============================================================================
/*
* Compute a mesh
*/
//=============================================================================
bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
const TopoDS_Shape & aShape,
const int aFlags /*= COMPACT_MESH*/,
const ::MeshDimension aDim /*=::MeshDim_3D*/,
TSetOfInt* aShapesId /*=0*/,
TopTools_IndexedMapOfShape* anAllowedSubShapes/*=0*/)
{
MEMOSTAT;
const bool aShapeOnly = aFlags & SHAPE_ONLY;
const bool anUpward = aFlags & UPWARD;
const bool aCompactMesh = aFlags & COMPACT_MESH;
bool ret = true;
SMESH_subMesh *sm, *shapeSM = aMesh.GetSubMesh(aShape);
const bool includeSelf = true;
const bool complexShapeFirst = true;
const int globalAlgoDim = 100;
SMESH_subMeshIteratorPtr smIt;
// Fix of Issue 22150. Due to !BLSURF->OnlyUnaryInput(), BLSURF computes edges
// that must be computed by Projection 1D-2D while the Projection asks to compute
// one face only.
SMESH_subMesh::compute_event computeEvent =
aShapeOnly ? SMESH_subMesh::COMPUTE_SUBMESH : SMESH_subMesh::COMPUTE;
if ( !aMesh.HasShapeToMesh() )
computeEvent = SMESH_subMesh::COMPUTE_NOGEOM; // if several algos and no geometry
TopTools_IndexedMapOfShape *allowedSubShapes = anAllowedSubShapes, allowedSub;
if ( aShapeOnly && !allowedSubShapes )
allowedSubShapes = &allowedSub;
if ( anUpward ) // is called from the below code in this method
{
// ===============================================
// Mesh all the sub-shapes starting from vertices
// ===============================================
if (aMesh.IsParallel())
ret = parallelComputeSubMeshes(
aMesh, aShape, aDim,
aShapesId, allowedSubShapes,
computeEvent,
includeSelf,
complexShapeFirst,
aShapeOnly);
else
ret = sequentialComputeSubMeshes(
aMesh, aShape, aDim,
aShapesId, allowedSubShapes,
computeEvent,
includeSelf,
complexShapeFirst,
aShapeOnly);
return ret;
}
else

View File

@ -34,6 +34,7 @@
#include "SMESH_Algo.hxx"
#include "SMESH_ComputeError.hxx"
#include "SMESH_subMesh.hxx"
#include <map>
#include <list>
@ -49,7 +50,7 @@ class SMESHDS_Document;
class SMESH_Algo;
class SMESH_Mesh;
class TopoDS_Shape;
class SMESH_subMesh;
typedef SMESH_Hypothesis::Hypothesis_Status TAlgoStateErrorName;
@ -168,6 +169,28 @@ public:
private:
bool parallelComputeSubMeshes(
SMESH_Mesh & aMesh,
const TopoDS_Shape & aShape,
const ::MeshDimension aDim,
TSetOfInt* aShapesId,
TopTools_IndexedMapOfShape* allowedSubShapes,
SMESH_subMesh::compute_event &computeEvent,
const bool includeSelf,
const bool complexShapeFirst,
const bool aShapeOnly);
bool sequentialComputeSubMeshes(
SMESH_Mesh & aMesh,
const TopoDS_Shape & aShape,
const ::MeshDimension aDim,
TSetOfInt* aShapesId /*=0*/,
TopTools_IndexedMapOfShape* allowedSubShapes,
SMESH_subMesh::compute_event &computeEvent,
const bool includeSelf,
const bool complexShapeFirst,
const bool aShapeOnly);
int _localId; // unique Id of created objects, within SMESH_Gen entity
StudyContextStruct* _studyContext;

View File

@ -5588,5 +5588,6 @@ void SMESH_MesherHelper::WriteShape(const TopoDS_Shape& s)
{
const char* name = "/tmp/shape.brep";
BRepTools::Write( s, name );
MESSAGE(name);
}

View File

@ -1907,7 +1907,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event)
break;
}
//notifyListenersOnEvent( event, COMPUTE_EVENT );
notifyListenersOnEvent( event, COMPUTE_EVENT );
return ret;
}

View File

@ -1898,7 +1898,6 @@ class Mesh(metaclass = MeshMeta):
a last total re-compute and that may prevent successful partial re-compute,
then the mesh is cleaned before Compute()
refresh: if *True*, Object Browser is automatically updated (when running in GUI)
nbThreads: Number of threads to use for a parallel computation
Returns:
True or False