mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2024-11-11 16:19:16 +05:00
[bos #38500 #41499 #41496][EDF] Make body fitting thread safe. Implement new parallel for function with std::threads to compute the elements and include needed lock_guard mutex wrapper in problematic function ::Add of B_Intersection and Hexahedron class.
This commit is contained in:
parent
27c8af8c6e
commit
a4d1fae96a
@ -98,7 +98,9 @@
|
|||||||
#include <gp_Sphere.hxx>
|
#include <gp_Sphere.hxx>
|
||||||
#include <gp_Torus.hxx>
|
#include <gp_Torus.hxx>
|
||||||
|
|
||||||
|
//STD
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
#include <boost/container/flat_map.hpp>
|
#include <boost/container/flat_map.hpp>
|
||||||
|
|
||||||
@ -116,12 +118,15 @@
|
|||||||
#define _WIN32_WINNT 0x0A00
|
#define _WIN32_WINNT 0x0A00
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
#include <algorithm>
|
||||||
#include <tbb/parallel_for.h>
|
#include <tbb/parallel_for.h>
|
||||||
//#include <tbb/enumerable_thread_specific.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace SMESH;
|
using namespace SMESH;
|
||||||
|
std::mutex _eMutex;
|
||||||
|
std::mutex _bMutex;
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
/*!
|
/*!
|
||||||
@ -351,7 +356,7 @@ namespace
|
|||||||
mutable vector< TGeomID > _faceIDs;
|
mutable vector< TGeomID > _faceIDs;
|
||||||
|
|
||||||
B_IntersectPoint(): _node(NULL) {}
|
B_IntersectPoint(): _node(NULL) {}
|
||||||
bool Add( const vector< TGeomID >& fIDs, const SMDS_MeshNode* n=0 ) const;
|
bool Add( const vector< TGeomID >& fIDs, const SMDS_MeshNode* n=NULL ) const;
|
||||||
TGeomID HasCommonFace( const B_IntersectPoint * other, TGeomID avoidFace=-1 ) const;
|
TGeomID HasCommonFace( const B_IntersectPoint * other, TGeomID avoidFace=-1 ) const;
|
||||||
size_t GetCommonFaces( const B_IntersectPoint * other, TGeomID * commonFaces ) const;
|
size_t GetCommonFaces( const B_IntersectPoint * other, TGeomID * commonFaces ) const;
|
||||||
bool IsOnFace( TGeomID faceID ) const;
|
bool IsOnFace( TGeomID faceID ) const;
|
||||||
@ -749,6 +754,7 @@ namespace
|
|||||||
}
|
}
|
||||||
void Add( const E_IntersectPoint* ip )
|
void Add( const E_IntersectPoint* ip )
|
||||||
{
|
{
|
||||||
|
const std::lock_guard<std::mutex> lock(_eMutex);
|
||||||
// Possible cases before Add(ip):
|
// Possible cases before Add(ip):
|
||||||
/// 1) _node != 0 --> _Node at hex corner ( _intPoint == 0 || _intPoint._node == 0 )
|
/// 1) _node != 0 --> _Node at hex corner ( _intPoint == 0 || _intPoint._node == 0 )
|
||||||
/// 2) _node == 0 && _intPoint._node != 0 --> link intersected by FACE
|
/// 2) _node == 0 && _intPoint._node != 0 --> link intersected by FACE
|
||||||
@ -1306,6 +1312,7 @@ namespace
|
|||||||
bool B_IntersectPoint::Add( const vector< TGeomID >& fIDs,
|
bool B_IntersectPoint::Add( const vector< TGeomID >& fIDs,
|
||||||
const SMDS_MeshNode* n) const
|
const SMDS_MeshNode* n) const
|
||||||
{
|
{
|
||||||
|
const std::lock_guard<std::mutex> lock(_bMutex);
|
||||||
size_t prevNbF = _faceIDs.size();
|
size_t prevNbF = _faceIDs.size();
|
||||||
|
|
||||||
if ( _faceIDs.empty() )
|
if ( _faceIDs.empty() )
|
||||||
@ -1318,7 +1325,7 @@ namespace
|
|||||||
if ( it == _faceIDs.end() )
|
if ( it == _faceIDs.end() )
|
||||||
_faceIDs.push_back( fIDs[i] );
|
_faceIDs.push_back( fIDs[i] );
|
||||||
}
|
}
|
||||||
if ( !_node )
|
if ( !_node && n != NULL )
|
||||||
_node = n;
|
_node = n;
|
||||||
|
|
||||||
return prevNbF < _faceIDs.size();
|
return prevNbF < _faceIDs.size();
|
||||||
@ -3618,6 +3625,35 @@ namespace
|
|||||||
|
|
||||||
return !_volumeDefs._nodes.empty();
|
return !_volumeDefs._nodes.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
void computeHexa(Type& hex)
|
||||||
|
{
|
||||||
|
if ( hex )
|
||||||
|
hex->computeElements();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implement parallel computation of Hexa with c++ thread implementation
|
||||||
|
template<typename Iterator, class Function>
|
||||||
|
void parallel_for(const Iterator& first, const Iterator& last, Function&& f, const int nthreads = 1)
|
||||||
|
{
|
||||||
|
const unsigned int group = ((last-first))/std::abs(nthreads);
|
||||||
|
|
||||||
|
std::vector<std::thread> threads;
|
||||||
|
threads.reserve(nthreads);
|
||||||
|
Iterator it = first;
|
||||||
|
for (; it < last-group; it += group) {
|
||||||
|
// to create a thread
|
||||||
|
// Pass iterators by value and the function by reference!
|
||||||
|
auto lambda = [=,&f](){ std::for_each(it, std::min(it+group, last), f);};
|
||||||
|
|
||||||
|
// stack the threads
|
||||||
|
threads.push_back( std::thread( lambda ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::for_each(it, last, f); // last steps while we wait for other threads
|
||||||
|
std::for_each(threads.begin(), threads.end(), [](std::thread& x){x.join();});
|
||||||
|
}
|
||||||
//================================================================================
|
//================================================================================
|
||||||
/*!
|
/*!
|
||||||
* \brief Create elements in the mesh
|
* \brief Create elements in the mesh
|
||||||
@ -3731,9 +3767,9 @@ namespace
|
|||||||
|
|
||||||
// compute definitions of volumes resulted from hexadron intersection
|
// compute definitions of volumes resulted from hexadron intersection
|
||||||
#ifdef WITH_TBB
|
#ifdef WITH_TBB
|
||||||
tbb::parallel_for ( tbb::blocked_range<size_t>( 0, intHexa.size() ),
|
auto numOfThreads = std::thread::hardware_concurrency();
|
||||||
ParallelHexahedron( intHexa ),
|
numOfThreads = (numOfThreads != 0) ? numOfThreads : 1;
|
||||||
tbb::simple_partitioner()); // computeElements() is called here
|
parallel_for(intHexa.begin(), intHexa.end(), computeHexa<Hexahedron*>, numOfThreads );
|
||||||
#else
|
#else
|
||||||
for ( size_t i = 0; i < intHexa.size(); ++i )
|
for ( size_t i = 0; i < intHexa.size(); ++i )
|
||||||
if ( Hexahedron * hex = intHexa[ i ] )
|
if ( Hexahedron * hex = intHexa[ i ] )
|
||||||
|
Loading…
Reference in New Issue
Block a user