From 6a94434123e7cfde51d87b5bec743a89576915eb Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Wed, 11 May 2022 09:10:21 +0200 Subject: [PATCH 01/29] WIP --- src/SMESH/CMakeLists.txt | 3 +- src/SMESH/SMESH_Algo.cxx | 20 +- src/SMESH/SMESH_Gen.cxx | 81 ++++++-- src/SMESH/SMESH_Gen.hxx | 9 +- src/SMESH/SMESH_Mesh.hxx | 60 +++--- src/SMESH/SMESH_subMesh.cxx | 25 ++- src/SMESH/ctpl.h | 240 +++++++++++++++++++++++ src/StdMeshers/StdMeshers_Regular_1D.cxx | 14 +- 8 files changed, 382 insertions(+), 70 deletions(-) create mode 100644 src/SMESH/ctpl.h diff --git a/src/SMESH/CMakeLists.txt b/src/SMESH/CMakeLists.txt index 7929c74f8..8f1ad0d8a 100644 --- a/src/SMESH/CMakeLists.txt +++ b/src/SMESH/CMakeLists.txt @@ -90,6 +90,7 @@ SET(SMESHimpl_HEADERS SMESH_SMESH.hxx MG_ADAPT.hxx SMESH_Homard.hxx + ctpl.h ) # --- sources --- @@ -117,7 +118,7 @@ SET(SMESHimpl_SOURCES ADD_LIBRARY(SMESHimpl ${SMESHimpl_SOURCES}) IF(WIN32) TARGET_COMPILE_OPTIONS(SMESHimpl PRIVATE /bigobj) - ADD_DEFINITIONS(-DNOMINMAX) + ADD_DEFINITIONS(-DNOMINMAX) ENDIF(WIN32) TARGET_LINK_LIBRARIES(SMESHimpl ${_link_LIBRARIES} ) diff --git a/src/SMESH/SMESH_Algo.cxx b/src/SMESH/SMESH_Algo.cxx index 788a048c1..582e554ee 100644 --- a/src/SMESH/SMESH_Algo.cxx +++ b/src/SMESH/SMESH_Algo.cxx @@ -169,7 +169,7 @@ const SMESH_Algo::Features& SMESH_Algo::GetFeatures( const std::string& algoType //============================================================================= /*! - * + * */ //============================================================================= @@ -186,7 +186,7 @@ SMESH_Algo::SMESH_Algo (int hypId, SMESH_Gen * gen) //============================================================================= /*! - * + * */ //============================================================================= @@ -198,7 +198,7 @@ SMESH_Algo::~SMESH_Algo() //============================================================================= /*! - * + * */ //============================================================================= @@ -238,7 +238,7 @@ istream & SMESH_Algo::LoadFrom(istream & load) { return load; } //============================================================================= /*! - * + * */ //============================================================================= @@ -252,7 +252,7 @@ const vector < string > &SMESH_Algo::GetCompatibleHypothesis() * List the hypothesis used by the algorithm associated to the shape. * Hypothesis associated to father shape -are- taken into account (see * GetAppliedHypothesis). Relevant hypothesis have a name (type) listed in - * the algorithm. This method could be surcharged by specific algorithms, in + * the algorithm. This method could be surcharged by specific algorithms, in * case of several hypothesis simultaneously applicable. */ //============================================================================= @@ -264,7 +264,7 @@ SMESH_Algo::GetUsedHypothesis(SMESH_Mesh & aMesh, { SMESH_Algo* me = const_cast< SMESH_Algo* >( this ); - std::list savedHyps; // don't delete the list if + std::list savedHyps; // don't delete the list if savedHyps.swap( me->_usedHypList ); // it does not change (#16578) me->_usedHypList.clear(); @@ -565,7 +565,7 @@ bool SMESH_Algo::IsStraight( const TopoDS_Edge & E, return false; // E seems closed double edgeTol = 10 * curve.Tolerance(); - double lenTol2 = lineLen2 * 1e-4; + double lenTol2 = lineLen2 * 1e-4; double tol2 = Min( edgeTol * edgeTol, lenTol2 ); const double nbSamples = 7; @@ -816,7 +816,7 @@ SMESH_Algo::EMeshError SMESH_Algo::GetMeshError(SMESH_subMesh* subMesh) /*! * \brief Sets event listener to submeshes if necessary * \param subMesh - submesh where algo is set - * + * * After being set, event listener is notified on each event of a submesh. * By default non listener is set */ @@ -1020,7 +1020,7 @@ void SMESH_Algo::addBadInputElements(const SMESHDS_SubMesh* sm, //============================================================================= /*! - * + * */ //============================================================================= @@ -1034,7 +1034,7 @@ void SMESH_Algo::addBadInputElements(const SMESHDS_SubMesh* sm, //============================================================================= /*! - * + * */ //============================================================================= diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index ef42e33e0..9f81f7494 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -155,6 +155,41 @@ 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 + parallel_compute([&] (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 @@ -182,6 +217,11 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, const bool complexShapeFirst = true; const int globalAlgoDim = 100; + // Pool of thread for computation + if (!_pool){ + _pool = new ctpl::thread_pool(2); + } + SMESH_subMeshIteratorPtr smIt; // Fix of Issue 22150. Due to !BLSURF->OnlyUnaryInput(), BLSURF computes edges @@ -202,7 +242,9 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, // Mesh all the sub-shapes starting from vertices // =============================================== + TopAbs_ShapeEnum previousShapeType = TopAbs_VERTEX; smIt = shapeSM->getDependsOnIterator(includeSelf, !complexShapeFirst); + std::vector> pending; while ( smIt->more() ) { SMESH_subMesh* smToCompute = smIt->next(); @@ -213,6 +255,18 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, if ( !aMesh.HasShapeToMesh() && shapeType == TopAbs_VERTEX ) continue; + std::cout << "Shape Type" << shapeType << " previous" << previousShapeType << std::endl; + if (shapeType != previousShapeType) { + // Waiting for all thread for the previous type to end + for(auto it =std::begin(pending); it != std::end(pending); ++it){ + std::cout << "Waiting" << std::endl; + it->wait(); + } + //Resetting threaded pool info + previousShapeType = shapeType; + pending.clear(); + } + // check for preview dimension limitations if ( aShapesId && GetShapeDim( shapeType ) > (int)aDim ) { @@ -221,25 +275,18 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, smToCompute->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); continue; } + pending.push_back(_pool->push(parallel_compute, smToCompute, computeEvent, + shapeSM, aShapeOnly, allowedSubShapes, + aShapesId)); + std::cout << "Launched " << smToCompute << " shape type " << shapeType << std::endl; - 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() ); } + + for(auto it =std::begin(pending); it != std::end(pending); ++it){ + it->wait(); + } + pending.clear(); //aMesh.GetMeshDS()->Modified(); return ret; } @@ -603,7 +650,7 @@ bool SMESH_Gen::Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape& aSubShape = smToCompute->GetSubShape(); const int aShapeDim = GetShapeDim( aSubShape ); if ( aShapeDim < 1 ) break; - + SMESH_Algo* algo = GetAlgo( smToCompute ); if ( algo && !algo->NeedDiscreteBoundary() ) { if ( algo->SupportSubmeshes() ) { diff --git a/src/SMESH/SMESH_Gen.hxx b/src/SMESH/SMESH_Gen.hxx index b8b98a8a8..7d3508c0f 100644 --- a/src/SMESH/SMESH_Gen.hxx +++ b/src/SMESH/SMESH_Gen.hxx @@ -34,6 +34,8 @@ #include "SMESH_Algo.hxx" #include "SMESH_ComputeError.hxx" +#include "ctpl.h" + #include #include @@ -41,6 +43,7 @@ #include #include + #include #include @@ -77,7 +80,7 @@ public: SHAPE_ONLY_UPWARD = 3 // SHAPE_ONLY | UPWARD }; /*! - * \brief Computes aMesh on aShape + * \brief Computes aMesh on aShape * \param aMesh - the mesh. * \param aShape - the shape. * \param aFlags - ComputeFlags. By default compute the whole mesh and compact at the end. @@ -101,7 +104,7 @@ public: const SMESH_subMesh* GetCurrentSubMesh() const; /*! - * \brief evaluates size of prospective mesh on a shape + * \brief evaluates size of prospective mesh on a shape * \param aMesh - the mesh * \param aShape - the shape * \param aResMap - map for prospective numbers of elements @@ -184,6 +187,8 @@ private: volatile bool _compute_canceled; std::list< SMESH_subMesh* > _sm_current; + // TODO: Replace by number of thread + ctpl::thread_pool * _pool = nullptr; //thread pool for computation }; #endif diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx index 461e949da..4a0ce0e49 100644 --- a/src/SMESH/SMESH_Mesh.hxx +++ b/src/SMESH/SMESH_Mesh.hxx @@ -43,6 +43,8 @@ #include "MEDCouplingMemArray.hxx" +#include "ctpl.h" + #include #include #include @@ -127,20 +129,20 @@ class SMESH_EXPORT SMESH_Mesh int UNVToMesh(const char* theFileName); int MEDToMesh(const char* theFileName, const char* theMeshName); - + std::string STLToMesh(const char* theFileName); int CGNSToMesh(const char* theFileName, const int theMeshIndex, std::string& theMeshName); - + SMESH_ComputeErrorPtr GMFToMesh(const char* theFileName, bool theMakeRequiredGroups = true ); SMESH_Hypothesis::Hypothesis_Status AddHypothesis(const TopoDS_Shape & aSubShape, int anHypId, std::string* error=0); - + SMESH_Hypothesis::Hypothesis_Status RemoveHypothesis(const TopoDS_Shape & aSubShape, int anHypId); - + const std::list & GetHypothesisList(const TopoDS_Shape & aSubShape) const; @@ -148,7 +150,7 @@ class SMESH_EXPORT SMESH_Mesh const SMESH_HypoFilter& aFilter, const bool andAncestors, TopoDS_Shape* assignedTo=0) const; - + int GetHypotheses(const TopoDS_Shape & aSubShape, const SMESH_HypoFilter& aFilter, std::list< const SMESHDS_Hypothesis * >& aHypList, @@ -159,7 +161,7 @@ class SMESH_EXPORT SMESH_Mesh const SMESH_HypoFilter& aFilter, const bool andAncestors, TopoDS_Shape* assignedTo=0) const; - + int GetHypotheses(const SMESH_subMesh * aSubMesh, const SMESH_HypoFilter& aFilter, std::list< const SMESHDS_Hypothesis * >& aHypList, @@ -169,25 +171,25 @@ class SMESH_EXPORT SMESH_Mesh SMESH_Hypothesis * GetHypothesis(const int aHypID) const; const std::list & GetLog(); - + void ClearLog(); - + int GetId() const { return _id; } - + bool MeshExists( int meshId ) const; - + SMESH_Mesh* FindMesh( int meshId ) const; SMESHDS_Mesh * GetMeshDS() { return _meshDS; } const SMESHDS_Mesh * GetMeshDS() const { return _meshDS; } - + SMESH_Gen *GetGen() { return _gen; } SMESH_subMesh *GetSubMesh(const TopoDS_Shape & aSubShape); - + SMESH_subMesh *GetSubMeshContaining(const TopoDS_Shape & aSubShape) const; - + SMESH_subMesh *GetSubMeshContaining(const int aShapeID) const; /*! * \brief Return submeshes of groups containing the given subshape @@ -209,7 +211,7 @@ class SMESH_EXPORT SMESH_Mesh * \brief check if a hypothesis allowing notconform mesh is present */ bool IsNotConformAllowed() const; - + bool IsMainShape(const TopoDS_Shape& theShape) const; TopoDS_Shape GetShapeByEntry(const std::string& entry) const; @@ -303,20 +305,20 @@ class SMESH_EXPORT SMESH_Mesh bool withRequiredGroups = true ); double GetComputeProgress() const; - + smIdType NbNodes() const; smIdType Nb0DElements() const; smIdType NbBalls() const; - + smIdType NbEdges(SMDSAbs_ElementOrder order = ORDER_ANY) const; - + smIdType NbFaces(SMDSAbs_ElementOrder order = ORDER_ANY) const; smIdType NbTriangles(SMDSAbs_ElementOrder order = ORDER_ANY) const; smIdType NbQuadrangles(SMDSAbs_ElementOrder order = ORDER_ANY) const; smIdType NbBiQuadQuadrangles() const; smIdType NbBiQuadTriangles() const; smIdType NbPolygons(SMDSAbs_ElementOrder order = ORDER_ANY) const; - + smIdType NbVolumes(SMDSAbs_ElementOrder order = ORDER_ANY) const; smIdType NbTetras(SMDSAbs_ElementOrder order = ORDER_ANY) const; smIdType NbHexas(SMDSAbs_ElementOrder order = ORDER_ANY) const; @@ -327,9 +329,9 @@ class SMESH_EXPORT SMESH_Mesh smIdType NbBiQuadPrisms() const; smIdType NbHexagonalPrisms() const; smIdType NbPolyhedrons() const; - + smIdType NbSubMesh() const; - + size_t NbGroup() const { return _mapGroup.size(); } int NbMeshes() const; // nb meshes in the Study @@ -344,9 +346,9 @@ class SMESH_EXPORT SMESH_Mesh typedef boost::shared_ptr< SMDS_Iterator > GroupIteratorPtr; GroupIteratorPtr GetGroups() const; - + std::list GetGroupIds() const; - + SMESH_Group* GetGroup (const int theGroupID) const; bool RemoveGroup (const int theGroupID); @@ -381,7 +383,10 @@ class SMESH_EXPORT SMESH_Mesh const SMESH_subMesh* smAfter ) const; std::ostream& Dump(std::ostream & save); - + + void Lock() {_my_lock.lock();}; + void Unlock() {_my_lock.unlock();}; + private: void exportMEDCommmon(DriverMED_W_SMESHDS_Mesh& myWriter, @@ -397,7 +402,7 @@ private: void fillAncestorsMap(const TopoDS_Shape& theShape); void getAncestorsSubMeshes(const TopoDS_Shape& theSubShape, std::vector< SMESH_subMesh* >& theSubMeshes) const; - + protected: int _id; // id given by creator (unique within the creator instance) int _groupId; // id generator for group objects @@ -410,12 +415,12 @@ protected: class SubMeshHolder; SubMeshHolder* _subMeshHolder; - + bool _isAutoColor; bool _isModified; //!< modified since last total re-compute, issue 0020693 double _shapeDiagonal; //!< diagonal size of bounding box of shape to mesh - + TopTools_IndexedDataMapOfShapeListOfShape _mapAncestors; mutable std::vector _ancestorSubMeshes; // to speed up GetHypothes[ei]s() @@ -428,6 +433,9 @@ protected: // 2) to forget not loaded mesh data at hyp modification TCallUp* _callUp; + // Mutex for multhitreading write in SMESH_Mesh + std::mutex _my_lock; + protected: SMESH_Mesh(); SMESH_Mesh(const SMESH_Mesh&) {}; diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index 0b697d7a0..d37172d90 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -609,7 +609,7 @@ bool SMESH_subMesh::IsApplicableHypothesis(const SMESH_Hypothesis* theHypothesis * \param [in] event - what happens * \param [in] anHyp - a hypothesis * \return SMESH_Hypothesis::Hypothesis_Status - a treatment result. - * + * * Optional description of a problematic situation (if any) can be retrieved * via GetComputeError(). */ @@ -1033,8 +1033,8 @@ SMESH_Hypothesis::Hypothesis_Status // detect algorithm hiding // - if ( ret == SMESH_Hypothesis::HYP_OK && - ( event == ADD_ALGO || event == ADD_FATHER_ALGO ) && algo && + if ( ret == SMESH_Hypothesis::HYP_OK && + ( event == ADD_ALGO || event == ADD_FATHER_ALGO ) && algo && algo->GetName() == anHyp->GetName() ) { // is algo hidden? @@ -1392,12 +1392,14 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) else if (( event == COMPUTE || event == COMPUTE_SUBMESH ) && !_alwaysComputed ) { + _father->Lock(); const TopoDS_Vertex & V = TopoDS::Vertex( _subShape ); gp_Pnt P = BRep_Tool::Pnt(V); if ( SMDS_MeshNode * n = _father->GetMeshDS()->AddNode(P.X(), P.Y(), P.Z()) ) { _father->GetMeshDS()->SetNodeOnVertex(n,_Id); _computeState = COMPUTE_OK; } + _father->Unlock(); } if ( event == MODIF_ALGO_STATE ) cleanDependants(); @@ -1500,6 +1502,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) case COMPUTE: case COMPUTE_SUBMESH: { + _father->Lock(); algo = GetAlgo(); ASSERT(algo); ret = algo->CheckHypothesis((*_father), _subShape, hyp_status); @@ -1541,6 +1544,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) break; // goto exit } } + _father->Unlock(); // Compute // to restore cout that may be redirected by algo @@ -1569,6 +1573,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) } else { + std::cout<<"Running compute for " << _father << " of shape type " << shape.ShapeType() << std::endl; ret = algo->Compute((*_father), shape); } // algo can set _computeError of submesh @@ -1729,7 +1734,9 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) updateDependantsState( SUBMESH_COMPUTED ); } // let algo clear its data gathered while algo->Compute() + _father->Lock(); algo->CheckHypothesis((*_father), _subShape, hyp_status); + _father->Unlock(); } break; case COMPUTE_CANCELED: // nothing to do @@ -1897,7 +1904,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) break; } - notifyListenersOnEvent( event, COMPUTE_EVENT ); + //notifyListenersOnEvent( event, COMPUTE_EVENT ); return ret; } @@ -2097,7 +2104,7 @@ void SMESH_subMesh::updateDependantsState(const compute_event theEvent) //======================================================================= //function : cleanDependants -//purpose : +//purpose : //======================================================================= void SMESH_subMesh::cleanDependants() @@ -2121,7 +2128,7 @@ void SMESH_subMesh::cleanDependants() //======================================================================= //function : removeSubMeshElementsAndNodes -//purpose : +//purpose : //======================================================================= void SMESH_subMesh::removeSubMeshElementsAndNodes() @@ -2297,7 +2304,7 @@ SMESH_subMesh::OwnListenerData::OwnListenerData( SMESH_subMesh* sm, EventListene * \param listener - the listener to store * \param data - the listener data to store * \param where - the submesh to store the listener and it's data - * + * * It remembers the submesh where it puts the listener in order to delete * them when HYP_OK algo_state is lost * After being set, event listener is notified on each event of where submesh. @@ -2319,7 +2326,7 @@ void SMESH_subMesh::SetEventListener(EventListener* listener, * \brief Sets an event listener and its data to a submesh * \param listener - the listener to store * \param data - the listener data to store - * + * * After being set, event listener is notified on each event of a submesh. */ //================================================================================ @@ -2529,7 +2536,7 @@ void SMESH_subMesh::loadDependentMeshes() * \param subMesh - the submesh where the event occurs * \param data - listener data stored in the subMesh * \param hyp - hypothesis, if eventType is algo_event - * + * * The base implementation translates CLEAN event to the subMesh * stored in listener data. Also it sends SUBMESH_COMPUTED event in case of * successful COMPUTE event. diff --git a/src/SMESH/ctpl.h b/src/SMESH/ctpl.h new file mode 100644 index 000000000..64f650d3e --- /dev/null +++ b/src/SMESH/ctpl.h @@ -0,0 +1,240 @@ + +/********************************************************* + * + * Copyright (C) 2014 by Vitaliy Vitsentiy + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************/ + + +#ifndef __ctpl_thread_pool_H__ +#define __ctpl_thread_pool_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifndef _ctplThreadPoolLength_ +#define _ctplThreadPoolLength_ 100 +#endif + + +// thread pool to run user's functors with signature +// ret func(int id, other_params) +// where id is the index of the thread that runs the functor +// ret is some return type + + +namespace ctpl { + + class thread_pool { + + public: + + thread_pool() : q(_ctplThreadPoolLength_) { this->init(); } + thread_pool(int nThreads, int queueSize = _ctplThreadPoolLength_) : q(queueSize) { this->init(); this->resize(nThreads); } + + // the destructor waits for all the functions in the queue to be finished + ~thread_pool() { + this->stop(true); + } + + // get the number of running threads in the pool + int size() { return static_cast(this->threads.size()); } + + // number of idle threads + int n_idle() { return this->nWaiting; } + std::thread & get_thread(int i) { return *this->threads[i]; } + + // change the number of threads in the pool + // should be called from one thread, otherwise be careful to not interleave, also with this->stop() + // nThreads must be >= 0 + void resize(int nThreads) { + if (!this->isStop && !this->isDone) { + int oldNThreads = static_cast(this->threads.size()); + if (oldNThreads <= nThreads) { // if the number of threads is increased + this->threads.resize(nThreads); + this->flags.resize(nThreads); + + for (int i = oldNThreads; i < nThreads; ++i) { + this->flags[i] = std::make_shared>(false); + this->set_thread(i); + } + } + else { // the number of threads is decreased + for (int i = oldNThreads - 1; i >= nThreads; --i) { + *this->flags[i] = true; // this thread will finish + this->threads[i]->detach(); + } + { + // stop the detached threads that were waiting + std::unique_lock lock(this->mutex); + this->cv.notify_all(); + } + this->threads.resize(nThreads); // safe to delete because the threads are detached + this->flags.resize(nThreads); // safe to delete because the threads have copies of shared_ptr of the flags, not originals + } + } + } + + // empty the queue + void clear_queue() { + std::function * _f; + while (this->q.pop(_f)) + delete _f; // empty the queue + } + + // pops a functional wraper to the original function + std::function pop() { + std::function * _f = nullptr; + this->q.pop(_f); + std::unique_ptr> func(_f); // at return, delete the function even if an exception occurred + + std::function f; + if (_f) + f = *_f; + return f; + } + + + // wait for all computing threads to finish and stop all threads + // may be called asyncronously to not pause the calling thread while waiting + // if isWait == true, all the functions in the queue are run, otherwise the queue is cleared without running the functions + void stop(bool isWait = false) { + if (!isWait) { + if (this->isStop) + return; + this->isStop = true; + for (int i = 0, n = this->size(); i < n; ++i) { + *this->flags[i] = true; // command the threads to stop + } + this->clear_queue(); // empty the queue + } + else { + if (this->isDone || this->isStop) + return; + this->isDone = true; // give the waiting threads a command to finish + } + { + std::unique_lock lock(this->mutex); + this->cv.notify_all(); // stop all waiting threads + } + for (int i = 0; i < static_cast(this->threads.size()); ++i) { // wait for the computing threads to finish + if (this->threads[i]->joinable()) + this->threads[i]->join(); + } + // if there were no threads in the pool but some functors in the queue, the functors are not deleted by the threads + // therefore delete them here + this->clear_queue(); + this->threads.clear(); + this->flags.clear(); + } + + template + auto push(F && f, Rest&&... rest) ->std::future { + auto pck = std::make_shared>( + std::bind(std::forward(f), std::placeholders::_1, std::forward(rest)...) + ); + + auto _f = new std::function([pck](int id) { + (*pck)(id); + }); + this->q.push(_f); + + std::unique_lock lock(this->mutex); + this->cv.notify_one(); + + return pck->get_future(); + } + + // run the user's function that excepts argument int - id of the running thread. returned value is templatized + // operator returns std::future, where the user can get the result and rethrow the catched exceptins + template + auto push(F && f) ->std::future { + auto pck = std::make_shared>(std::forward(f)); + + auto _f = new std::function([pck](int id) { + (*pck)(id); + }); + this->q.push(_f); + + std::unique_lock lock(this->mutex); + this->cv.notify_one(); + + return pck->get_future(); + } + + + private: + + // deleted + thread_pool(const thread_pool &);// = delete; + thread_pool(thread_pool &&);// = delete; + thread_pool & operator=(const thread_pool &);// = delete; + thread_pool & operator=(thread_pool &&);// = delete; + + void set_thread(int i) { + std::shared_ptr> flag(this->flags[i]); // a copy of the shared ptr to the flag + auto f = [this, i, flag/* a copy of the shared ptr to the flag */]() { + std::atomic & _flag = *flag; + std::function * _f; + bool isPop = this->q.pop(_f); + while (true) { + while (isPop) { // if there is anything in the queue + std::unique_ptr> func(_f); // at return, delete the function even if an exception occurred + (*_f)(i); + + if (_flag) + return; // the thread is wanted to stop, return even if the queue is not empty yet + else + isPop = this->q.pop(_f); + } + + // the queue is empty here, wait for the next command + std::unique_lock lock(this->mutex); + ++this->nWaiting; + this->cv.wait(lock, [this, &_f, &isPop, &_flag](){ isPop = this->q.pop(_f); return isPop || this->isDone || _flag; }); + --this->nWaiting; + + if (!isPop) + return; // if the queue is empty and this->isDone == true or *flag then return + } + }; + this->threads[i].reset(new std::thread(f)); // compiler may not support std::make_unique() + } + + void init() { this->nWaiting = 0; this->isStop = false; this->isDone = false; } + + std::vector> threads; + std::vector>> flags; + mutable boost::lockfree::queue *> q; + std::atomic isDone; + std::atomic isStop; + std::atomic nWaiting; // how many threads are waiting + + std::mutex mutex; + std::condition_variable cv; + }; + +} + +#endif // __ctpl_thread_pool_H__ + diff --git a/src/StdMeshers/StdMeshers_Regular_1D.cxx b/src/StdMeshers/StdMeshers_Regular_1D.cxx index 40e8fbd82..bd20e30fa 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.cxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.cxx @@ -716,7 +716,7 @@ void StdMeshers_Regular_1D::redistributeNearVertices (SMESH_Mesh & theM //============================================================================= /*! - * + * */ //============================================================================= bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh, @@ -1164,7 +1164,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh, //============================================================================= /*! - * + * */ //============================================================================= @@ -1182,6 +1182,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t SMESHDS_Mesh * meshDS = theMesh.GetMeshDS(); + theMesh.Lock(); const TopoDS_Edge & EE = TopoDS::Edge(theShape); TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD)); int shapeID = meshDS->ShapeToIndex( E ); @@ -1196,9 +1197,10 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t ASSERT(!VLast.IsNull()); const SMDS_MeshNode * nFirst = SMESH_Algo::VertexNode( VFirst, meshDS ); const SMDS_MeshNode * nLast = SMESH_Algo::VertexNode( VLast, meshDS ); - if ( !nFirst || !nLast ) + if ( !nFirst || !nLast ){ + theMesh.Unlock(); return error( COMPERR_BAD_INPUT_MESH, "No node on vertex"); - + } // remove elements created by e.g. pattern mapping (PAL21999) // CLEAN event is incorrectly ptopagated seemingly due to Propagation hyp // so TEMPORARY solution is to clean the submesh manually @@ -1242,6 +1244,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t BRepAdaptor_Curve C3d( E ); if ( ! computeInternalParameters( theMesh, C3d, length, f, l, params, reversed, true )) { + theMesh.Unlock(); return false; } redistributeNearVertices( theMesh, C3d, length, params, VFirst, VLast ); @@ -1332,13 +1335,14 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t meshDS->SetMeshElementOnShape(edge, shapeID); } } + theMesh.Unlock(); return true; } //============================================================================= /*! - * + * */ //============================================================================= From 2323e27949d465b1cbdda4600c715efd7ac3592c Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Mon, 25 Jul 2022 10:35:21 +0200 Subject: [PATCH 02/29] Parallel version for 1d mesher number of segment --- src/SMESH/SMESH_Algo.cxx | 3 ++ src/SMESH/SMESH_Gen.cxx | 1 + src/SMESH/SMESH_subMesh.cxx | 43 +++++++++++++++++++----- src/SMESH/SMESH_subMesh.hxx | 17 +++++----- src/StdMeshers/StdMeshers_Regular_1D.cxx | 40 +++++++++++++++++----- 5 files changed, 80 insertions(+), 24 deletions(-) diff --git a/src/SMESH/SMESH_Algo.cxx b/src/SMESH/SMESH_Algo.cxx index 582e554ee..215879d3c 100644 --- a/src/SMESH/SMESH_Algo.cxx +++ b/src/SMESH/SMESH_Algo.cxx @@ -281,6 +281,9 @@ SMESH_Algo::GetUsedHypothesis(SMESH_Mesh & aMesh, if ( _usedHypList == savedHyps ) savedHyps.swap( me->_usedHypList ); + for(auto hyp:_usedHypList){ + std::cout << hyp << std::endl; + } return _usedHypList; } diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index 9f81f7494..a67b6f09b 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -262,6 +262,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, std::cout << "Waiting" << std::endl; it->wait(); } + cout << "Number of segments: " << aMesh.NbEdges() << endl; //Resetting threaded pool info previousShapeType = shapeType; pending.clear(); diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index d37172d90..cf6ba0b98 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -65,6 +65,7 @@ using namespace std; //#define PRINT_WHO_COMPUTE_WHAT #endif +#define PRINT_WHO_COMPUTE_WHAT //============================================================================= /*! * \brief Allocate some memory at construction and release it at destruction. @@ -206,6 +207,20 @@ SMESH_Algo* SMESH_subMesh::GetAlgo() const return _algo; } +//================================================================================ +/*! + * \brief Returns a current algorithm + */ +//================================================================================ + +SMESH_Algo* SMESH_subMesh::CopyAlgo() const +{ + //SMESH_Algo* algo = (SMESH_Algo*) new StdMeshers_Regular_1D(666, _father->GetGent()); + SMESH_Algo* algo; + + return algo; +} + //================================================================================ /*! * \brief Allow algo->Compute() if a sub-shape of lower dim is meshed but @@ -1392,6 +1407,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) else if (( event == COMPUTE || event == COMPUTE_SUBMESH ) && !_alwaysComputed ) { + // LOCK: Adding node to mesh _father->Lock(); const TopoDS_Vertex & V = TopoDS::Vertex( _subShape ); gp_Pnt P = BRep_Tool::Pnt(V); @@ -1400,6 +1416,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) _computeState = COMPUTE_OK; } _father->Unlock(); + // UNLOCK } if ( event == MODIF_ALGO_STATE ) cleanDependants(); @@ -1502,10 +1519,13 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) case COMPUTE: case COMPUTE_SUBMESH: { - _father->Lock(); algo = GetAlgo(); + SMESH_Algo* algo2 = CopyAlgo(); + cout << "Algo2" << algo2; ASSERT(algo); - ret = algo->CheckHypothesis((*_father), _subShape, hyp_status); + //_father->Lock(); + //ret = algo->CheckHypothesis((*_father), _subShape, hyp_status); + //_father->Unlock(); if (!ret) { MESSAGE("***** verify compute state *****"); @@ -1516,7 +1536,9 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) TopoDS_Shape shape = _subShape; algo->SubMeshesToCompute().assign( 1, this ); // check submeshes needed - if (_father->HasShapeToMesh() ) { + // Forcing to false for parallel run + // TODO: Remove forced false + if (_father->HasShapeToMesh() && false) { bool subComputed = false, subFailed = false; if (!algo->OnlyUnaryInput()) { // --- commented for bos#22320 to compute all sub-shapes at once if possible; @@ -1544,7 +1566,6 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) break; // goto exit } } - _father->Unlock(); // Compute // to restore cout that may be redirected by algo @@ -1647,8 +1668,10 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) #ifdef PRINT_WHO_COMPUTE_WHAT for (subS.ReInit(); subS.More(); subS.Next()) { - const std::list & hyps = + _father->Lock(); + const std::list hyps = _algo->GetUsedHypothesis( *_father, _subShape ); + _father->Unlock(); SMESH_Comment hypStr; if ( !hyps.empty() ) { @@ -1734,9 +1757,9 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) updateDependantsState( SUBMESH_COMPUTED ); } // let algo clear its data gathered while algo->Compute() - _father->Lock(); - algo->CheckHypothesis((*_father), _subShape, hyp_status); - _father->Unlock(); + //_father->Lock(); + //algo->CheckHypothesis((*_father), _subShape, hyp_status); + //_father->Unlock(); } break; case COMPUTE_CANCELED: // nothing to do @@ -2172,8 +2195,10 @@ TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * /*theGen*/, return _subShape; const bool skipAuxHyps = false; + _father->Lock(); list usedHyps = theAlgo->GetUsedHypothesis( *_father, _subShape, skipAuxHyps ); // copy + _father->Lock(); std::list < TopoDS_Shape > assiShapes = theAlgo->GetAssignedShapes(); // put in a compound all shapes with the same hypothesis assigned @@ -2201,6 +2226,7 @@ TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * /*theGen*/, } else if ( subMesh->GetComputeState() == READY_TO_COMPUTE ) { + _father->Lock(); SMESH_Algo* anAlgo = subMesh->GetAlgo(); if (( anAlgo->IsSameName( *theAlgo )) && // same algo ( anAlgo->GetUsedHypothesis( *_father, S, skipAuxHyps ) == usedHyps ) && // same hyps @@ -2212,6 +2238,7 @@ TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * /*theGen*/, theSubComputed = false; theSubs.push_back( subMesh ); } + _father->Unlock(); } } diff --git a/src/SMESH/SMESH_subMesh.hxx b/src/SMESH/SMESH_subMesh.hxx index fbfd222c2..0f925570a 100644 --- a/src/SMESH/SMESH_subMesh.hxx +++ b/src/SMESH/SMESH_subMesh.hxx @@ -69,7 +69,7 @@ class SMESH_EXPORT SMESH_subMesh int GetId() const; // == meshDS->ShapeToIndex( aSubShape ) SMESH_Mesh* GetFather() { return _father; } - + SMESHDS_SubMesh * GetSubMeshDS(); const SMESHDS_SubMesh * GetSubMeshDS() const; @@ -79,6 +79,7 @@ class SMESH_EXPORT SMESH_subMesh SMESH_subMesh *GetFirstToCompute(); SMESH_Algo* GetAlgo() const; + SMESH_Algo* CopyAlgo() const; const std::map < int, SMESH_subMesh * >& DependsOn(); bool DependsOn( const SMESH_subMesh* other ) const; @@ -123,7 +124,7 @@ class SMESH_EXPORT SMESH_subMesh }; // ================================================================== - // Members to track non hierarchical dependencies between sub-meshes + // Members to track non hierarchical dependencies between sub-meshes // ================================================================== /*! @@ -131,7 +132,7 @@ class SMESH_EXPORT SMESH_subMesh * \param listener - the listener to store * \param data - the listener data to store * \param where - the submesh to store the listener and it's data - * + * * The method remembers the submesh \awhere it puts the listener in order to delete * it when HYP_OK algo_state is lost * After being set, event listener is notified on each event of \awhere submesh. @@ -185,7 +186,7 @@ protected: * \brief Sets an event listener and its data to a submesh * \param listener - the listener to store * \param data - the listener data to store - * + * * After being set, event listener is notified on each event of a submesh. */ void setEventListener(EventListener* listener, EventListenerData* data); @@ -245,7 +246,7 @@ public: bool IsApplicableHypothesis(const SMESH_Hypothesis* theHypothesis) const; // return true if theHypothesis can be used to mesh me: // its shape type is checked - + SMESH_Hypothesis::Hypothesis_Status CheckConcurrentHypothesis (SMESH_Hypothesis* theHypothesis); // check if there are several applicable hypothesis on fathers @@ -277,7 +278,7 @@ public: int GetComputeCost() const; // how costly is to compute this sub-mesh - + /*! * \brief Find common submeshes (based on shared subshapes with other * \param theOther submesh to check @@ -319,7 +320,7 @@ protected: /*! * \brief Return a hypothesis attached to theShape. - * + * * If theHyp is provided, similar but not same hypotheses * is returned; else an applicable ones having theHypType * is returned @@ -327,7 +328,7 @@ protected: const SMESH_Hypothesis* getSimilarAttached(const TopoDS_Shape& theShape, const SMESH_Hypothesis * theHyp, const int theHypType = 0); - // + // int computeCost() const; protected: diff --git a/src/StdMeshers/StdMeshers_Regular_1D.cxx b/src/StdMeshers/StdMeshers_Regular_1D.cxx index bd20e30fa..c26113ab3 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.cxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.cxx @@ -126,14 +126,22 @@ bool StdMeshers_Regular_1D::CheckHypothesis( SMESH_Mesh& aMesh, _onlyUnaryInput = true; // check propagation in a redefined GetUsedHypothesis() - const list & hyps = + const list hyps = GetUsedHypothesis(aMesh, aShape, /*ignoreAuxiliaryHyps=*/false); - const SMESH_HypoFilter & propagFilter = StdMeshers_Propagation::GetFilter(); // find non-auxiliary hypothesis const SMESHDS_Hypothesis *theHyp = 0; set< string > propagTypes; + std::cout << "For shape " << aShape.HashCode(1) << " of type "<< aShape.ShapeType() << + "CheckHypothesis" << std::endl; + for(auto hyp:hyps){ + SMESH_Comment hypStr; + hypStr << hyp << " " << hyp->GetName() << " "; + ((SMESHDS_Hypothesis*)hyp)->SaveTo( hypStr.Stream() ); + hypStr << " "; + std::cout << hypStr << std::endl; + } list ::const_iterator h = hyps.begin(); for ( ; h != hyps.end(); ++h ) { if ( static_cast(*h)->IsAuxiliary() ) { @@ -848,8 +856,12 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh, { // Number Of Segments hypothesis nbSegments = _ivalue[ NB_SEGMENTS_IND ]; - if ( nbSegments < 1 ) return false; - if ( nbSegments == 1 ) return true; + if ( nbSegments < 1 ) { + return false; + } + if ( nbSegments == 1 ) { + return true; + } switch (_ivalue[ DISTR_TYPE_IND ]) { @@ -1170,10 +1182,16 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh, bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & theShape) { - if ( _hypType == NONE ) - return false; + SMESH_Hypothesis::Hypothesis_Status hyp_status; + theMesh.Lock(); + bool ret = this->CheckHypothesis(theMesh, theShape, hyp_status); + int hypType = _hypType; + theMesh.Unlock(); - if ( _hypType == ADAPTIVE ) + if ( hypType == NONE ) + return false; + + if ( hypType == ADAPTIVE ) { _adaptiveHyp->GetAlgo()->InitComputeError(); _adaptiveHyp->GetAlgo()->Compute( theMesh, theShape ); @@ -1183,6 +1201,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t SMESHDS_Mesh * meshDS = theMesh.GetMeshDS(); theMesh.Lock(); + const TopoDS_Edge & EE = TopoDS::Edge(theShape); TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD)); int shapeID = meshDS->ShapeToIndex( E ); @@ -1199,6 +1218,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t const SMDS_MeshNode * nLast = SMESH_Algo::VertexNode( VLast, meshDS ); if ( !nFirst || !nLast ){ theMesh.Unlock(); + std::cout << "exit no node" << std::endl; return error( COMPERR_BAD_INPUT_MESH, "No node on vertex"); } // remove elements created by e.g. pattern mapping (PAL21999) @@ -1232,7 +1252,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t // take into account reversing the edge the hypothesis is propagated from // (_mainEdge.Orientation() marks mutual orientation of EDGEs in propagation chain) reversed = ( _mainEdge.Orientation() == TopAbs_REVERSED ); - if ( _hypType != DISTRIB_PROPAGATION ) { + if ( hypType != DISTRIB_PROPAGATION ) { int mainID = meshDS->ShapeToIndex(_mainEdge); if ( std::find( _revEdgesIDs.begin(), _revEdgesIDs.end(), mainID) != _revEdgesIDs.end()) reversed = !reversed; @@ -1245,6 +1265,8 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t BRepAdaptor_Curve C3d( E ); if ( ! computeInternalParameters( theMesh, C3d, length, f, l, params, reversed, true )) { theMesh.Unlock(); + std::cout << "exit Compute internal failed" << std::endl; + return false; } redistributeNearVertices( theMesh, C3d, length, params, VFirst, VLast ); @@ -1336,6 +1358,8 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t } } theMesh.Unlock(); + std::cout << "exit normal" << std::endl; + return true; } From 0be5e44fdfaaecff8412b625954d53399def1801 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Fri, 26 Aug 2022 11:37:02 +0200 Subject: [PATCH 03/29] Working version for 3d with run_mesher --- src/SMESH/CMakeLists.txt | 2 + src/SMESH/SMESH_Gen.cxx | 29 ++- src/SMESH/SMESH_Mesh.cxx | 6 + src/SMESH/SMESH_Mesh.hxx | 4 + src/SMESH/SMESH_subMesh.cxx | 10 +- src/SMESHDS/SMESHDS_Mesh.cxx | 359 ++++++++++++++++++----------------- 6 files changed, 225 insertions(+), 185 deletions(-) diff --git a/src/SMESH/CMakeLists.txt b/src/SMESH/CMakeLists.txt index 8f1ad0d8a..fee16b4cd 100644 --- a/src/SMESH/CMakeLists.txt +++ b/src/SMESH/CMakeLists.txt @@ -91,6 +91,7 @@ SET(SMESHimpl_HEADERS MG_ADAPT.hxx SMESH_Homard.hxx ctpl.h + DriverMesh.hxx ) # --- sources --- @@ -111,6 +112,7 @@ SET(SMESHimpl_SOURCES SMESH_MesherHelper.cxx MG_ADAPT.cxx SMESH_Homard.cxx + DriverMesh.cxx ) # --- rules --- diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index a67b6f09b..0b5dc1385 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -30,6 +30,7 @@ #include "SMESH_Gen.hxx" +#include "DriverMesh.hxx" #include "SMDS_Mesh.hxx" #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" @@ -55,6 +56,8 @@ #include using namespace std; +#include +namespace fs = boost::filesystem; // Environment variable separator #ifdef WIN32 @@ -255,14 +258,34 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, if ( !aMesh.HasShapeToMesh() && shapeType == TopAbs_VERTEX ) continue; - std::cout << "Shape Type" << shapeType << " previous" << previousShapeType << std::endl; + //DEBUG std::cout << "Shape Type" << shapeType << " previous" << previousShapeType << std::endl; if (shapeType != previousShapeType) { // Waiting for all thread for the previous type to end for(auto it =std::begin(pending); it != std::end(pending); ++it){ std::cout << "Waiting" << std::endl; it->wait(); } - cout << "Number of segments: " << aMesh.NbEdges() << endl; + 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; + default: + file_name = ""; + break; + } + if(file_name != ""){ + fs::path mesh_file = fs::path(aMesh.tmp_folder) / fs::path(file_name); + // TODO: change mesh name + export_mesh(mesh_file.string(), aMesh, "Maillage_1"); + + } //Resetting threaded pool info previousShapeType = shapeType; pending.clear(); @@ -279,7 +302,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, pending.push_back(_pool->push(parallel_compute, smToCompute, computeEvent, shapeSM, aShapeOnly, allowedSubShapes, aShapesId)); - std::cout << "Launched " << smToCompute << " shape type " << shapeType << std::endl; + //DEBUG std::cout << "Launched " << smToCompute << " shape type " << shapeType << std::endl; } diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index 5ff4c1830..5ca9919ac 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -80,6 +80,9 @@ #include #endif +#include +namespace fs=boost::filesystem; + // maximum stored group name length in MED file #define MAX_MED_GROUP_NAME_LENGTH 80 @@ -121,6 +124,9 @@ SMESH_Mesh::SMESH_Mesh(int theLocalId, _callUp = NULL; _meshDS->ShapeToMesh( PseudoShape() ); _subMeshHolder = new SubMeshHolder; + // Temporary folder that will be used by parallel computation + tmp_folder = fs::temp_directory_path()/fs::unique_path(fs::path("SMESH_%%%%-%%%%")); + fs::create_directories(tmp_folder); // assure unique persistent ID if ( _document->NbMeshes() > 1 ) diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx index 4a0ce0e49..46a6ddc27 100644 --- a/src/SMESH/SMESH_Mesh.hxx +++ b/src/SMESH/SMESH_Mesh.hxx @@ -49,6 +49,7 @@ #include #include #include +#include #ifdef WIN32 #pragma warning(disable:4251) // Warning DLL Interface ... @@ -387,6 +388,9 @@ class SMESH_EXPORT SMESH_Mesh void Lock() {_my_lock.lock();}; void Unlock() {_my_lock.unlock();}; + // Temporary folder used during parallel Computation + boost::filesystem::path tmp_folder; + private: void exportMEDCommmon(DriverMED_W_SMESHDS_Mesh& myWriter, diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index cf6ba0b98..651b74af3 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -271,7 +271,8 @@ bool SMESH_subMesh::IsMeshComputed() const TopExp_Explorer exp( _subShape, (TopAbs_ShapeEnum) type ); for ( ; exp.More(); exp.Next() ) { - if ( SMESHDS_SubMesh * smDS = meshDS->MeshElements( exp.Current() )) + SMESHDS_SubMesh * smDS = meshDS->MeshElements( exp.Current() ); + if ( smDS ) { bool computed = (dim > 0) ? smDS->NbElements() : smDS->NbNodes(); if ( computed ) @@ -1594,7 +1595,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) } else { - std::cout<<"Running compute for " << _father << " of shape type " << shape.ShapeType() << std::endl; + // TODO: Replace by call to ParallelCompute ret = algo->Compute((*_father), shape); } // algo can set _computeError of submesh @@ -1655,6 +1656,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) bool isComputeErrorSet = !checkComputeError( algo, ret, shape ); if ( isComputeErrorSet ) ret = false; + // TODO: See why IsMeshCompited() returns false // check if anything was built TopExp_Explorer subS(shape, _subShape.ShapeType()); if ( ret ) @@ -2051,7 +2053,9 @@ bool SMESH_subMesh::checkComputeError(SMESH_Algo* theAlgo, if ( !_computeError || _computeError->IsOK() ) { // no error description is set to this sub-mesh, check if any mesh is computed - _computeState = IsMeshComputed() ? COMPUTE_OK : FAILED_TO_COMPUTE; + //TODO: See why this does not work + //_computeState = IsMeshComputed() ? COMPUTE_OK : FAILED_TO_COMPUTE; + _computeState = COMPUTE_OK; if ( _computeState != COMPUTE_OK ) { if ( _subShape.ShapeType() == TopAbs_EDGE && diff --git a/src/SMESHDS/SMESHDS_Mesh.cxx b/src/SMESHDS/SMESHDS_Mesh.cxx index 563e2de98..36fc2d131 100644 --- a/src/SMESHDS/SMESHDS_Mesh.cxx +++ b/src/SMESHDS/SMESHDS_Mesh.cxx @@ -99,7 +99,7 @@ int SMESHDS_Mesh::GetPersistentId() const //======================================================================= //function : ShapeToMesh -//purpose : +//purpose : //======================================================================= void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S) { @@ -141,7 +141,7 @@ void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S) //======================================================================= //function : AddHypothesis -//purpose : +//purpose : //======================================================================= bool SMESHDS_Mesh::AddHypothesis(const TopoDS_Shape & SS, @@ -165,7 +165,7 @@ bool SMESHDS_Mesh::AddHypothesis(const TopoDS_Shape & SS, //======================================================================= //function : RemoveHypothesis -//purpose : +//purpose : //======================================================================= bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape & S, @@ -186,7 +186,7 @@ bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape & S, //======================================================================= //function : AddNode -//purpose : +//purpose : //======================================================================= SMDS_MeshNode* SMESHDS_Mesh::AddNode(double x, double y, double z) { @@ -204,7 +204,7 @@ SMDS_MeshNode* SMESHDS_Mesh::AddNodeWithID(double x, double y, double z, smIdTyp //======================================================================= //function : MoveNode -//purpose : +//purpose : //======================================================================= void SMESHDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z) @@ -235,7 +235,7 @@ bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem, //======================================================================= //function : ChangePolygonNodes -//purpose : +//purpose : //======================================================================= bool SMESHDS_Mesh::ChangePolygonNodes (const SMDS_MeshElement * elem, std::vector& nodes) @@ -309,7 +309,7 @@ SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElement(const SMDS_MeshNode * node) //======================================================================= //function :AddBallWithID -//purpose : +//purpose : //======================================================================= SMDS_BallElement* SMESHDS_Mesh::AddBallWithID(smIdType node, double diameter, smIdType ID) @@ -338,7 +338,7 @@ SMDS_BallElement* SMESHDS_Mesh::AddBall (const SMDS_MeshNode * node, //======================================================================= //function :AddEdgeWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(smIdType n1, smIdType n2, smIdType ID) @@ -349,7 +349,7 @@ SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(smIdType n1, smIdType n2, smIdType ID } SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, + const SMDS_MeshNode * n2, smIdType ID) { return AddEdgeWithID(n1->GetID(), @@ -361,15 +361,15 @@ SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2) { SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2); - if(anElem) myScript->AddEdge(anElem->GetID(), - n1->GetID(), + if(anElem) myScript->AddEdge(anElem->GetID(), + n1->GetID(), n2->GetID()); return anElem; } //======================================================================= //function :AddFace -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3, smIdType ID) { @@ -380,7 +380,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, + const SMDS_MeshNode * n3, smIdType ID) { return AddFaceWithID(n1->GetID(), @@ -394,8 +394,8 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace( const SMDS_MeshNode * n1, const SMDS_MeshNode * n3) { SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3); - if(anElem) myScript->AddFace(anElem->GetID(), - n1->GetID(), + if(anElem) myScript->AddFace(anElem->GetID(), + n1->GetID(), n2->GetID(), n3->GetID()); return anElem; @@ -403,7 +403,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace( const SMDS_MeshNode * n1, //======================================================================= //function :AddFace -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4, smIdType ID) { @@ -415,7 +415,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, + const SMDS_MeshNode * n4, smIdType ID) { return AddFaceWithID(n1->GetID(), @@ -431,9 +431,9 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, const SMDS_MeshNode * n4) { SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3, n4); - if(anElem) myScript->AddFace(anElem->GetID(), - n1->GetID(), - n2->GetID(), + if(anElem) myScript->AddFace(anElem->GetID(), + n1->GetID(), + n2->GetID(), n3->GetID(), n4->GetID()); return anElem; @@ -441,7 +441,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, //======================================================================= //function :AddVolume -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4, smIdType ID) { @@ -453,11 +453,11 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdTyp SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, + const SMDS_MeshNode * n4, smIdType ID) { - return AddVolumeWithID(n1->GetID(), - n2->GetID(), + return AddVolumeWithID(n1->GetID(), + n2->GetID(), n3->GetID(), n4->GetID(), ID); @@ -469,9 +469,9 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n4) { SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4); - if(anElem) myScript->AddVolume(anElem->GetID(), - n1->GetID(), - n2->GetID(), + if(anElem) myScript->AddVolume(anElem->GetID(), + n1->GetID(), + n2->GetID(), n3->GetID(), n4->GetID()); return anElem; @@ -479,7 +479,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, //======================================================================= //function :AddVolume -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4, smIdType n5, smIdType ID) { @@ -492,13 +492,13 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, + const SMDS_MeshNode * n5, smIdType ID) { - return AddVolumeWithID(n1->GetID(), - n2->GetID(), + return AddVolumeWithID(n1->GetID(), + n2->GetID(), n3->GetID(), - n4->GetID(), + n4->GetID(), n5->GetID(), ID); } @@ -510,18 +510,18 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n5) { SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5); - if(anElem) myScript->AddVolume(anElem->GetID(), - n1->GetID(), - n2->GetID(), + if(anElem) myScript->AddVolume(anElem->GetID(), + n1->GetID(), + n2->GetID(), n3->GetID(), - n4->GetID(), + n4->GetID(), n5->GetID()); return anElem; } //======================================================================= //function :AddVolume -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4, smIdType n5, smIdType n6, smIdType ID) { @@ -535,14 +535,14 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, + const SMDS_MeshNode * n6, smIdType ID) { - return AddVolumeWithID(n1->GetID(), - n2->GetID(), + return AddVolumeWithID(n1->GetID(), + n2->GetID(), n3->GetID(), - n4->GetID(), - n5->GetID(), + n4->GetID(), + n5->GetID(), n6->GetID(), ID); } @@ -555,19 +555,19 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n6) { SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6); - if(anElem) myScript->AddVolume(anElem->GetID(), - n1->GetID(), - n2->GetID(), + if(anElem) myScript->AddVolume(anElem->GetID(), + n1->GetID(), + n2->GetID(), n3->GetID(), - n4->GetID(), - n5->GetID(), + n4->GetID(), + n5->GetID(), n6->GetID()); return anElem; } //======================================================================= //function :AddVolume -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4, smIdType n5, smIdType n6, smIdType n7, smIdType n8, smIdType ID) { @@ -583,16 +583,16 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n5, const SMDS_MeshNode * n6, const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, + const SMDS_MeshNode * n8, smIdType ID) { - return AddVolumeWithID(n1->GetID(), - n2->GetID(), + return AddVolumeWithID(n1->GetID(), + n2->GetID(), n3->GetID(), - n4->GetID(), - n5->GetID(), - n6->GetID(), - n7->GetID(), + n4->GetID(), + n5->GetID(), + n6->GetID(), + n7->GetID(), n8->GetID(), ID); } @@ -607,14 +607,14 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n8) { SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8); - if(anElem) myScript->AddVolume(anElem->GetID(), - n1->GetID(), - n2->GetID(), + if(anElem) myScript->AddVolume(anElem->GetID(), + n1->GetID(), + n2->GetID(), n3->GetID(), - n4->GetID(), - n5->GetID(), - n6->GetID(), - n7->GetID(), + n4->GetID(), + n5->GetID(), + n6->GetID(), + n7->GetID(), n8->GetID()); return anElem; } @@ -641,14 +641,14 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n5, const SMDS_MeshNode * n6, const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, - const SMDS_MeshNode * n9, - const SMDS_MeshNode * n10, - const SMDS_MeshNode * n11, - const SMDS_MeshNode * n12, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n9, + const SMDS_MeshNode * n10, + const SMDS_MeshNode * n11, + const SMDS_MeshNode * n12, smIdType ID) { - return AddVolumeWithID(n1->GetID(), + return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), @@ -670,14 +670,14 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n5, const SMDS_MeshNode * n6, const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, - const SMDS_MeshNode * n9, - const SMDS_MeshNode * n10, - const SMDS_MeshNode * n11, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n9, + const SMDS_MeshNode * n10, + const SMDS_MeshNode * n11, const SMDS_MeshNode * n12) { SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12); - if(anElem) myScript->AddVolume(anElem->GetID(), + if(anElem) myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(), n3->GetID(), @@ -696,7 +696,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, //======================================================================= //function : AddPolygonalFace -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (const std::vector& nodes_ids, const smIdType ID) @@ -742,7 +742,7 @@ SMESHDS_Mesh::AddPolygonalFace (const std::vector& nodes) //======================================================================= //function : AddQuadPolygonalFace -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector& nodes_ids, const smIdType ID) @@ -788,7 +788,7 @@ SMESHDS_Mesh::AddQuadPolygonalFace (const std::vector& nod //======================================================================= //function : AddPolyhedralVolume -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (const std::vector& nodes_ids, const std::vector& quantities, @@ -836,7 +836,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolume //======================================================================= //function : removeFromContainers -//purpose : +//purpose : //======================================================================= static void removeFromContainers (SMESHDS_Mesh* /*theMesh*/, @@ -905,8 +905,8 @@ void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n) } if ( SMESHDS_SubMesh * sm = MeshElements( n->getshapeId() )) sm->RemoveNode( n ); - - + + std::vector removedElems; std::vector removedNodes; @@ -918,7 +918,7 @@ void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n) //======================================================================= //function : RemoveFreeNode -//purpose : +//purpose : //======================================================================= bool SMESHDS_Mesh::RemoveFreeNode(const SMDS_MeshNode * n, SMESHDS_SubMesh * subMesh, @@ -971,20 +971,20 @@ void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt) RemoveFreeElement( elt, subMesh, true ); return; } - + myScript->RemoveElement(elt->GetID()); std::vector removedElems; std::vector removedNodes; SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes ); - + removeFromContainers( this, myGroups, removedElems ); } //======================================================================= //function : RemoveFreeElement -//purpose : +//purpose : //======================================================================== void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt, SMESHDS_SubMesh * subMesh, @@ -1151,7 +1151,7 @@ void SMESHDS_Mesh::SetNodeOnVertex(const SMDS_MeshNode * aNode, //======================================================================= //function : UnSetNodeOnShape -//purpose : +//purpose : //======================================================================= void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode) { @@ -1173,7 +1173,7 @@ void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement * anElement, //======================================================================= //function : UnSetMeshElementOnShape -//purpose : +//purpose : //======================================================================= void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem, const TopoDS_Shape & S) @@ -1184,7 +1184,7 @@ void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem, //======================================================================= //function : ShapeToMesh -//purpose : +//purpose : //======================================================================= TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const { @@ -1229,7 +1229,7 @@ SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index) const //======================================================================= //function : SubMeshIndices -//purpose : +//purpose : //======================================================================= std::list SMESHDS_Mesh::SubMeshIndices() const { @@ -1243,7 +1243,7 @@ std::list SMESHDS_Mesh::SubMeshIndices() const //======================================================================= //function : SubMeshes -//purpose : +//purpose : //======================================================================= SMESHDS_SubMeshIteratorPtr SMESHDS_Mesh::SubMeshes() const @@ -1253,7 +1253,7 @@ SMESHDS_SubMeshIteratorPtr SMESHDS_Mesh::SubMeshes() const //======================================================================= //function : GetHypothesis -//purpose : +//purpose : //======================================================================= const std::list& @@ -1283,7 +1283,7 @@ bool SMESHDS_Mesh::IsUsedHypothesis(const SMESHDS_Hypothesis * H) const //======================================================================= //function : GetScript -//purpose : +//purpose : //======================================================================= SMESHDS_Script* SMESHDS_Mesh::GetScript() { @@ -1292,7 +1292,7 @@ SMESHDS_Script* SMESHDS_Mesh::GetScript() //======================================================================= //function : ClearScript -//purpose : +//purpose : //======================================================================= void SMESHDS_Mesh::ClearScript() { @@ -1301,7 +1301,7 @@ void SMESHDS_Mesh::ClearScript() //======================================================================= //function : HasMeshElements -//purpose : +//purpose : //======================================================================= bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S) const { @@ -1311,7 +1311,7 @@ bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S) const //======================================================================= //function : HasHypothesis -//purpose : +//purpose : //======================================================================= bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S) { @@ -1319,8 +1319,8 @@ bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S) } //======================================================================= -//function : NewSubMesh -//purpose : +//function : NewSubMesh +//purpose : //======================================================================= SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index) { @@ -1328,6 +1328,7 @@ SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index) if ( !SM ) { SM = new SMESHDS_SubMesh(this, Index); + std::cout << "Adding " << Index << ':' <Add( Index, SM ); } return SM; @@ -1335,7 +1336,7 @@ SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index) //======================================================================= //function : AddCompoundSubmesh -//purpose : +//purpose : //======================================================================= int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S, @@ -1370,7 +1371,7 @@ int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S, //======================================================================= //function : IndexToShape -//purpose : +//purpose : //======================================================================= const TopoDS_Shape& SMESHDS_Mesh::IndexToShape(int ShapeIndex) const { @@ -1399,7 +1400,7 @@ int SMESHDS_Mesh::MaxSubMeshIndex() const //======================================================================= //function : ShapeToIndex -//purpose : +//purpose : //======================================================================= int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const { @@ -1409,7 +1410,7 @@ int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const //======================================================================= //function : SetNodeOnVolume -//purpose : +//purpose : //======================================================================= void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index) { @@ -1457,7 +1458,7 @@ void SMESHDS_Mesh::SetNodeOnVertex(const SMDS_MeshNode* aNode, int Index) //======================================================================= //function : SetMeshElementOnShape -//purpose : +//purpose : //======================================================================= void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement, int Index) @@ -1467,7 +1468,7 @@ void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement, //======================================================================= //function : ~SMESHDS_Mesh -//purpose : +//purpose : //======================================================================= SMESHDS_Mesh::~SMESHDS_Mesh() { @@ -1488,9 +1489,9 @@ SMESHDS_Mesh::~SMESHDS_Mesh() //======================================================================= //function : AddEdgeWithID -//purpose : +//purpose : //======================================================================= -SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(smIdType n1, smIdType n2, smIdType n12, smIdType ID) +SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(smIdType n1, smIdType n2, smIdType n12, smIdType ID) { SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,n12,ID); if(anElem) myScript->AddEdge(ID,n1,n2,n12); @@ -1499,15 +1500,15 @@ SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(smIdType n1, smIdType n2, smIdType n1 //======================================================================= //function : AddEdge -//purpose : +//purpose : //======================================================================= SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2, const SMDS_MeshNode* n12) { SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2,n12); - if(anElem) myScript->AddEdge(anElem->GetID(), - n1->GetID(), + if(anElem) myScript->AddEdge(anElem->GetID(), + n1->GetID(), n2->GetID(), n12->GetID()); return anElem; @@ -1515,11 +1516,11 @@ SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1, //======================================================================= //function : AddEdgeWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n12, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n12, smIdType ID) { return AddEdgeWithID(n1->GetID(), @@ -1531,7 +1532,7 @@ SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, //======================================================================= //function : AddFace -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -1541,7 +1542,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, const SMDS_MeshNode * n31) { SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31); - if(anElem) myScript->AddFace(anElem->GetID(), + if(anElem) myScript->AddFace(anElem->GetID(), n1->GetID(), n2->GetID(), n3->GetID(), n12->GetID(), n23->GetID(), n31->GetID()); return anElem; @@ -1549,7 +1550,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, //======================================================================= //function : AddFaceWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n12,smIdType n23,smIdType n31, smIdType ID) @@ -1561,14 +1562,14 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3 //======================================================================= //function : AddFaceWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, - const SMDS_MeshNode * n31, + const SMDS_MeshNode * n31, smIdType ID) { return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), @@ -1578,7 +1579,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, //======================================================================= //function : AddFace -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -1589,7 +1590,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, const SMDS_MeshNode * nCenter) { SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31,nCenter); - if(anElem) myScript->AddFace(anElem->GetID(), + if(anElem) myScript->AddFace(anElem->GetID(), n1->GetID(), n2->GetID(), n3->GetID(), n12->GetID(), n23->GetID(), n31->GetID(), nCenter->GetID()); @@ -1598,7 +1599,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, //======================================================================= //function : AddFaceWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n12,smIdType n23,smIdType n31, smIdType nCenter, smIdType ID) @@ -1610,15 +1611,15 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3 //======================================================================= //function : AddFaceWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, - const SMDS_MeshNode * n31, - const SMDS_MeshNode * nCenter, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * nCenter, smIdType ID) { return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), @@ -1629,7 +1630,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, //======================================================================= //function : AddFace -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -1641,7 +1642,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, const SMDS_MeshNode * n41) { SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41); - if(anElem) myScript->AddFace(anElem->GetID(), + if(anElem) myScript->AddFace(anElem->GetID(), n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID()); return anElem; @@ -1649,7 +1650,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, //======================================================================= //function : AddFaceWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4, smIdType n12,smIdType n23,smIdType n34,smIdType n41, smIdType ID) @@ -1661,7 +1662,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3 //======================================================================= //function : AddFaceWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -1669,8 +1670,8 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n4, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, - const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, smIdType ID) { return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), @@ -1681,7 +1682,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, //======================================================================= //function : AddFace -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -1690,11 +1691,11 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, + const SMDS_MeshNode * n41, const SMDS_MeshNode * nCenter) { SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41,nCenter); - if(anElem) myScript->AddFace(anElem->GetID(), + if(anElem) myScript->AddFace(anElem->GetID(), n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(), nCenter->GetID()); @@ -1703,7 +1704,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, //======================================================================= //function : AddFaceWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4, smIdType n12,smIdType n23,smIdType n34,smIdType n41, @@ -1716,7 +1717,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3 //======================================================================= //function : AddFaceWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -1724,9 +1725,9 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n4, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, - const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, - const SMDS_MeshNode * nCenter, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * nCenter, smIdType ID) { return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), @@ -1737,21 +1738,21 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, //======================================================================= //function : AddVolume -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, + const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n31, - const SMDS_MeshNode * n14, + const SMDS_MeshNode * n14, const SMDS_MeshNode * n24, const SMDS_MeshNode * n34) { SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34); - if(anElem) myScript->AddVolume(anElem->GetID(), + if(anElem) myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), n12->GetID(), n23->GetID(), n31->GetID(), n14->GetID(), n24->GetID(), n34->GetID()); @@ -1760,7 +1761,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, //======================================================================= //function : AddVolumeWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4, smIdType n12,smIdType n23,smIdType n31, @@ -1771,7 +1772,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdTyp if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n12,n23,n31,n14,n24,n34); return anElem; } - + //======================================================================= //function : AddVolumeWithID //purpose : 2d order tetrahedron of 10 nodes @@ -1783,7 +1784,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n31, - const SMDS_MeshNode * n14, + const SMDS_MeshNode * n14, const SMDS_MeshNode * n24, const SMDS_MeshNode * n34, smIdType ID) @@ -1796,18 +1797,18 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, //======================================================================= //function : AddVolume -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, + const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, + const SMDS_MeshNode * n5, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, const SMDS_MeshNode * n41, - const SMDS_MeshNode * n15, + const SMDS_MeshNode * n15, const SMDS_MeshNode * n25, const SMDS_MeshNode * n35, const SMDS_MeshNode * n45) @@ -1824,7 +1825,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, //======================================================================= //function : AddVolumeWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4, smIdType n5, smIdType n12,smIdType n23,smIdType n34,smIdType n41, @@ -1837,7 +1838,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdTyp n15,n25,n35,n45); return anElem; } - + //======================================================================= //function : AddVolumeWithID //purpose : 2d order pyramid of 13 nodes @@ -1846,12 +1847,12 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, + const SMDS_MeshNode * n5, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, const SMDS_MeshNode * n41, - const SMDS_MeshNode * n15, + const SMDS_MeshNode * n15, const SMDS_MeshNode * n25, const SMDS_MeshNode * n35, const SMDS_MeshNode * n45, @@ -1870,17 +1871,17 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, //purpose : 2nd order pentahedron (prism) with 15 nodes //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, + const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, - const SMDS_MeshNode * n31, + const SMDS_MeshNode * n31, const SMDS_MeshNode * n45, const SMDS_MeshNode * n56, - const SMDS_MeshNode * n64, + const SMDS_MeshNode * n64, const SMDS_MeshNode * n14, const SMDS_MeshNode * n25, const SMDS_MeshNode * n36) @@ -2000,7 +2001,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdTyp n45,n56,n64,n14,n25,n36, n1245, n2356, n1346); return anElem; } - + //======================================================================= //function : AddVolumeWithID //purpose : 2d order Pentahedron with 18 nodes @@ -2009,14 +2010,14 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, - const SMDS_MeshNode * n31, + const SMDS_MeshNode * n31, const SMDS_MeshNode * n45, const SMDS_MeshNode * n56, - const SMDS_MeshNode * n64, + const SMDS_MeshNode * n64, const SMDS_MeshNode * n14, const SMDS_MeshNode * n25, const SMDS_MeshNode * n36, @@ -2039,21 +2040,21 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, //purpose : add quadratic hexahedron //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, + const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, + const SMDS_MeshNode * n8, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, + const SMDS_MeshNode * n41, const SMDS_MeshNode * n56, const SMDS_MeshNode * n67, const SMDS_MeshNode * n78, - const SMDS_MeshNode * n85, + const SMDS_MeshNode * n85, const SMDS_MeshNode * n15, const SMDS_MeshNode * n26, const SMDS_MeshNode * n37, @@ -2075,7 +2076,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, //======================================================================= //function : AddVolumeWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4, smIdType n5, smIdType n6, smIdType n7, smIdType n8, @@ -2091,7 +2092,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdTyp n56,n67,n78,n85,n15,n26,n37,n48); return anElem; } - + //======================================================================= //function : AddVolumeWithID //purpose : 2d order Hexahedrons with 20 nodes @@ -2100,18 +2101,18 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, + const SMDS_MeshNode * n8, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, + const SMDS_MeshNode * n41, const SMDS_MeshNode * n56, const SMDS_MeshNode * n67, const SMDS_MeshNode * n78, - const SMDS_MeshNode * n85, + const SMDS_MeshNode * n85, const SMDS_MeshNode * n15, const SMDS_MeshNode * n26, const SMDS_MeshNode * n37, @@ -2132,25 +2133,25 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, + const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, + const SMDS_MeshNode * n8, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, + const SMDS_MeshNode * n41, const SMDS_MeshNode * n56, const SMDS_MeshNode * n67, const SMDS_MeshNode * n78, - const SMDS_MeshNode * n85, + const SMDS_MeshNode * n85, const SMDS_MeshNode * n15, const SMDS_MeshNode * n26, const SMDS_MeshNode * n37, - const SMDS_MeshNode * n48, + const SMDS_MeshNode * n48, const SMDS_MeshNode * n1234, const SMDS_MeshNode * n1256, const SMDS_MeshNode * n2367, From 5d3c1425f83862a5a3616e3128f70341637216ba Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Tue, 30 Aug 2022 09:42:21 +0200 Subject: [PATCH 04/29] Adding SetNbThreads in Python to set if compute will be done in parallel --- idl/SMESH_Mesh.idl | 48 ++++++++++++++++++---------------- src/SMESH/SMESH_Mesh.hxx | 6 +++++ src/SMESH/SMESH_subMesh.cxx | 9 ++----- src/SMESH_I/SMESH_2smeshpy.cxx | 2 +- src/SMESH_I/SMESH_Mesh_i.cxx | 18 ++++++++++--- src/SMESH_I/SMESH_Mesh_i.hxx | 6 +++-- src/SMESH_SWIG/smeshBuilder.py | 5 +++- 7 files changed, 57 insertions(+), 37 deletions(-) diff --git a/idl/SMESH_Mesh.idl b/idl/SMESH_Mesh.idl index bfbb0cdd5..e70b3d842 100644 --- a/idl/SMESH_Mesh.idl +++ b/idl/SMESH_Mesh.idl @@ -156,7 +156,7 @@ module SMESH Geom_BALL, Geom_LAST }; - + /*! * ElementOrder points out entities of what order are requested */ @@ -238,7 +238,7 @@ module SMESH DRS_FAIL // general failure (exception etc.) }; - /*! + /*! * \brief A structure containing information about MED file */ struct MedFileInfo @@ -263,7 +263,7 @@ module SMESH */ const long EXTRUSION_FLAG_BOUNDARY = 1; const long EXTRUSION_FLAG_SEW = 2; - + /*! * Structure used in mesh edit preview data (MeshPreviewStruct) */ @@ -344,7 +344,7 @@ module SMESH /*! * Get geom shape to mesh. A result should not be nil. Use HasShapeToMesh() - * to know if a returned shape + * to know if a returned shape */ GEOM::GEOM_Object GetShapeToMesh() raises (SALOME::SALOME_Exception); @@ -457,7 +457,7 @@ module SMESH in SMESH_GroupBase aGroup2, in string name ) raises (SALOME::SALOME_Exception); - + /*! * Union of list of groups * New group is created. All mesh elements that are @@ -476,7 +476,7 @@ module SMESH in SMESH_GroupBase aGroup2, in string name ) raises (SALOME::SALOME_Exception); - + /*! * Intersection of list of groups * New group is created. All mesh elements that are @@ -495,7 +495,7 @@ module SMESH in SMESH_GroupBase aToolGroup, in string name ) raises (SALOME::SALOME_Exception); - + /*! * Cut of lists of groups * New group is created. All mesh elements that are present in @@ -505,14 +505,14 @@ module SMESH in ListOfGroups aToolGroups, in string name) raises (SALOME::SALOME_Exception); - + /*! * Create a group of entities basing on nodes of other groups. * \param [in] aListOfGroups - list of either groups, sub-meshes or filters. * \param [in] anElemType - a type of elements to include to the new group. * \param [in] name - a name of the new group. * \param [in] nbCommonNodes - criterion of inclusion of an element to the new group. - * \param [in] underlyingOnly - if \c True, an element is included to the + * \param [in] underlyingOnly - if \c True, an element is included to the * new group provided that it is based on nodes of an element of * \a aListOfGroups * \return SMESH_Group - the created group @@ -679,12 +679,12 @@ module SMESH * med files in 4.0.0 (default format) or 3.2.1 or 3.3.1 formats. * The minor must be between 0 and the current minor version of MED file library. * If version is equal to -1, the version is not changed (default). - * - autoDimension : if @c True, a space dimension for export is defined by mesh + * - autoDimension : if @c True, a space dimension for export is defined by mesh * configuration; for example a planar mesh lying on XOY plane - * will be exported as a mesh in 2D space. + * will be exported as a mesh in 2D space. * If @a autoDimension == @c False, the space dimension is 3. * - fields : list of GEOM fields defined on the shape to mesh. - * - geomAssocFields : each character of this string means a need to export a + * - geomAssocFields : each character of this string means a need to export a * corresponding field; correspondence between fields and characters is following: * - 'v' stands for _vertices_ field; * - 'e' stands for _edges_ field; @@ -724,7 +724,7 @@ module SMESH * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32) */ long_array GetMEDVersionsCompatibleForAppend(); - + /*! * Export Mesh to different Formats * (UNV supported version is I-DEAS 10) @@ -735,17 +735,17 @@ module SMESH in boolean renumer ) raises (SALOME::SALOME_Exception); void ExportSTL( in string file, in boolean isascii ) raises (SALOME::SALOME_Exception); - void ExportCGNS( in SMESH_IDSource meshPart, + void ExportCGNS( in SMESH_IDSource meshPart, in string file, in boolean overwrite, in boolean groupElemsByType) raises (SALOME::SALOME_Exception); - void ExportGMF( in SMESH_IDSource meshPart, + void ExportGMF( in SMESH_IDSource meshPart, in string file, in boolean withRequiredGroups) raises (SALOME::SALOME_Exception); - void ExportPartToDAT( in SMESH_IDSource meshPart, + void ExportPartToDAT( in SMESH_IDSource meshPart, in string file, in boolean renumer ) raises (SALOME::SALOME_Exception); - void ExportPartToUNV( in SMESH_IDSource meshPart, + void ExportPartToUNV( in SMESH_IDSource meshPart, in string file, in boolean renumer ) raises (SALOME::SALOME_Exception); void ExportPartToSTL( in SMESH_IDSource meshPart, @@ -857,10 +857,10 @@ module SMESH smIdType_array GetNodesId() raises (SALOME::SALOME_Exception); - + /*! * Returns type of mesh element - */ + */ ElementType GetElementType( in smIdType id, in boolean iselem ) raises (SALOME::SALOME_Exception); @@ -875,7 +875,7 @@ module SMESH smIdType_array GetSubMeshNodesId(in long ShapeID, in boolean all ) raises (SALOME::SALOME_Exception); - + ElementType GetSubMeshElementType(in long ShapeID) raises (SALOME::SALOME_Exception); @@ -899,6 +899,10 @@ module SMESH */ boolean SetMeshOrder(in submesh_array_array theSubMeshArray); + /*! + * \brief Set Number of Threads + */ + void SetNbThreads(in long nbThreads); /*! * Get mesh description @@ -939,7 +943,7 @@ module SMESH long GetShapeID(in smIdType id); /*! - * For given element returns ID of result shape after + * For given element returns ID of result shape after * ::FindShape() from SMESH_MeshEditor * If there is not element for given ID - returns -1 */ @@ -1072,7 +1076,7 @@ module SMESH */ smIdType_array GetElementsByType( in ElementType theType ) raises (SALOME::SALOME_Exception); - + /*! * Returns type of mesh element (same as SMESH_Mesh::GetElementType() ) */ diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx index 46a6ddc27..2b8632abb 100644 --- a/src/SMESH/SMESH_Mesh.hxx +++ b/src/SMESH/SMESH_Mesh.hxx @@ -385,9 +385,14 @@ class SMESH_EXPORT SMESH_Mesh std::ostream& Dump(std::ostream & save); + // Data for parallel computation + void Lock() {_my_lock.lock();}; void Unlock() {_my_lock.unlock();}; + int GetNbThreads(){return _NbThreads;}; + void SetNbThreads(int nbThreads){_NbThreads=nbThreads;}; + // Temporary folder used during parallel Computation boost::filesystem::path tmp_folder; @@ -439,6 +444,7 @@ protected: // Mutex for multhitreading write in SMESH_Mesh std::mutex _my_lock; + int _NbThreads=0; protected: SMESH_Mesh(); diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index 651b74af3..751cf8b79 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -271,8 +271,7 @@ bool SMESH_subMesh::IsMeshComputed() const TopExp_Explorer exp( _subShape, (TopAbs_ShapeEnum) type ); for ( ; exp.More(); exp.Next() ) { - SMESHDS_SubMesh * smDS = meshDS->MeshElements( exp.Current() ); - if ( smDS ) + if ( SMESHDS_SubMesh * smDS = meshDS->MeshElements( exp.Current() ) ) { bool computed = (dim > 0) ? smDS->NbElements() : smDS->NbNodes(); if ( computed ) @@ -1595,7 +1594,6 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) } else { - // TODO: Replace by call to ParallelCompute ret = algo->Compute((*_father), shape); } // algo can set _computeError of submesh @@ -1656,7 +1654,6 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) bool isComputeErrorSet = !checkComputeError( algo, ret, shape ); if ( isComputeErrorSet ) ret = false; - // TODO: See why IsMeshCompited() returns false // check if anything was built TopExp_Explorer subS(shape, _subShape.ShapeType()); if ( ret ) @@ -2053,9 +2050,7 @@ bool SMESH_subMesh::checkComputeError(SMESH_Algo* theAlgo, if ( !_computeError || _computeError->IsOK() ) { // no error description is set to this sub-mesh, check if any mesh is computed - //TODO: See why this does not work - //_computeState = IsMeshComputed() ? COMPUTE_OK : FAILED_TO_COMPUTE; - _computeState = COMPUTE_OK; + _computeState = IsMeshComputed() ? COMPUTE_OK : FAILED_TO_COMPUTE; if ( _computeState != COMPUTE_OK ) { if ( _subShape.ShapeType() == TopAbs_EDGE && diff --git a/src/SMESH_I/SMESH_2smeshpy.cxx b/src/SMESH_I/SMESH_2smeshpy.cxx index 03a600094..a062e3d2f 100644 --- a/src/SMESH_I/SMESH_2smeshpy.cxx +++ b/src/SMESH_I/SMESH_2smeshpy.cxx @@ -2212,7 +2212,7 @@ bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand ) "GetElemNode","IsMediumNode","IsMediumNodeOfAnyElem","ElemNbEdges","ElemNbFaces", "GetElemFaceNodes", "GetFaceNormal", "FindElementByNodes", "IsPoly","IsQuadratic","BaryCenter","GetHypothesisList", "SetAutoColor", "GetAutoColor", - "Clear", "ConvertToStandalone", "GetMeshOrder", "SetMeshOrder" + "Clear", "ConvertToStandalone", "GetMeshOrder", "SetMeshOrder", "SetNbThreads" ,"" }; // <- mark of end sameMethods.Insert( names ); } diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index b307c7bbb..a7abda6db 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -2506,7 +2506,7 @@ void SMESH_Mesh_i::CheckGeomModif( bool theIsBreakLink ) } old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape ); } - + } } // store assigned hypotheses @@ -6170,8 +6170,8 @@ SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh() /*! * \brief Return false if GetMeshInfo() return incorrect information that may * happen if mesh data is not yet fully loaded from the file of study. - * - * + * + * */ //================================================================================ @@ -7037,6 +7037,16 @@ TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes() return res; } +//============================================================================= +/*! + * \brief Set the number of threads for a parallel computation + */ +//============================================================================= +void SMESH_Mesh_i::SetNbThreads(int nbThreads){ + _impl->SetNbThreads(nbThreads); +} + + //============================================================================= /*! * \brief Convert submesh ids into submesh interfaces @@ -7229,7 +7239,7 @@ smIdType SMESH_MeshPartDS::MinNodeID() const { if ( _meshDS ) return _meshDS->MinNodeID(); return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID(); -} +} // ------------------------------------------------------------------------------------- smIdType SMESH_MeshPartDS::MaxElementID() const { diff --git a/src/SMESH_I/SMESH_Mesh_i.hxx b/src/SMESH_I/SMESH_Mesh_i.hxx index 8a50d1226..25892ca9d 100644 --- a/src/SMESH_I/SMESH_Mesh_i.hxx +++ b/src/SMESH_I/SMESH_Mesh_i.hxx @@ -226,7 +226,7 @@ public: const char* file, CORBA::Boolean withRequiredGroups); - + template void ExportPartToMEDCommon(SPECLS& speCls, SMESH::SMESH_IDSource_ptr meshPart, @@ -571,7 +571,7 @@ public: * Persistence of geometry tick */ int& MainShapeTick() { return _mainShapeTick; } - + /*! * Sets list of notebook variables used for Mesh operations separated by ":" symbol @@ -673,6 +673,8 @@ private: SMESH::submesh_array_array& theSubMeshOrder, const bool theIsDump); + void SetNbThreads(int nbThreads); + /*! * \brief Finds concurrent sub-meshes */ diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index 62db88951..19ae2a934 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -1864,7 +1864,7 @@ class Mesh(metaclass = MeshMeta): return self.smeshpyD.Evaluate(self.mesh, geom) - def Compute(self, geom=0, discardModifs=False, refresh=False): + def Compute(self, geom=0, discardModifs=False, refresh=False, nbThreads=0): """ Compute the mesh and return the status of the computation @@ -1874,6 +1874,7 @@ 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 @@ -1885,6 +1886,8 @@ class Mesh(metaclass = MeshMeta): try: if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693 self.mesh.Clear() + # Setting parallel parameters + self.mesh.SetNbThreads(nbThreads) ok = self.smeshpyD.Compute(self.mesh, geom) except SALOME.SALOME_Exception as ex: print("Mesh computation failed, exception caught:") From 67ee393af6c08994ef666e35dc533a140d32459b Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Tue, 30 Aug 2022 13:24:07 +0200 Subject: [PATCH 05/29] Restoring orignal compute + cleanup --- src/SMESH/SMESH_Algo.cxx | 3 -- src/SMESH/SMESH_Gen.cxx | 60 +++++++++++++++++++++++------------- src/SMESH/SMESH_Gen.hxx | 2 -- src/SMESH/SMESH_Mesh.hxx | 7 +++++ src/SMESH/SMESH_subMesh.cxx | 38 ++++++----------------- src/SMESHDS/SMESHDS_Mesh.cxx | 1 - 6 files changed, 54 insertions(+), 57 deletions(-) diff --git a/src/SMESH/SMESH_Algo.cxx b/src/SMESH/SMESH_Algo.cxx index 215879d3c..582e554ee 100644 --- a/src/SMESH/SMESH_Algo.cxx +++ b/src/SMESH/SMESH_Algo.cxx @@ -281,9 +281,6 @@ SMESH_Algo::GetUsedHypothesis(SMESH_Mesh & aMesh, if ( _usedHypList == savedHyps ) savedHyps.swap( me->_usedHypList ); - for(auto hyp:_usedHypList){ - std::cout << hyp << std::endl; - } return _usedHypList; } diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index 0b5dc1385..c27f5ec02 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -171,7 +171,7 @@ const std::function - parallel_compute([&] (int id, + compute_function([&] (int id, SMESH_subMesh* sm, SMESH_subMesh::compute_event event, SMESH_subMesh *shapeSM, @@ -179,7 +179,7 @@ const std::function void { - if (sm->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE) + if (sm->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE) { sm->SetAllowedSubShapes( fillAllowed( shapeSM, aShapeOnly, allowedSubShapes )); //setCurrentSubMesh( sm ); @@ -188,6 +188,7 @@ const std::functionSetAllowedSubShapes( nullptr ); } + // TODO: Check if this is necessary if ( aShapesId ) aShapesId->insert( sm->GetId() ); @@ -221,9 +222,8 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, const int globalAlgoDim = 100; // Pool of thread for computation - if (!_pool){ - _pool = new ctpl::thread_pool(2); - } + if(aMesh.IsParallel()) + aMesh.InitPoolThreads(); SMESH_subMeshIteratorPtr smIt; @@ -246,8 +246,9 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, // =============================================== TopAbs_ShapeEnum previousShapeType = TopAbs_VERTEX; - smIt = shapeSM->getDependsOnIterator(includeSelf, !complexShapeFirst); std::vector> pending; + + smIt = shapeSM->getDependsOnIterator(includeSelf, !complexShapeFirst); while ( smIt->more() ) { SMESH_subMesh* smToCompute = smIt->next(); @@ -259,11 +260,10 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, continue; //DEBUG std::cout << "Shape Type" << shapeType << " previous" << previousShapeType << std::endl; - if (shapeType != previousShapeType) { - // Waiting for all thread for the previous type to end - for(auto it =std::begin(pending); it != std::end(pending); ++it){ - std::cout << "Waiting" << std::endl; - it->wait(); + if (aMesh.IsParallel() && shapeType != previousShapeType) { + // Waiting for all threads for the previous type to end + for(auto &it: pending){ + it.wait(); } std::string file_name; switch(previousShapeType){ @@ -280,7 +280,8 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, file_name = ""; break; } - if(file_name != ""){ + if(file_name != "") + { fs::path mesh_file = fs::path(aMesh.tmp_folder) / fs::path(file_name); // TODO: change mesh name export_mesh(mesh_file.string(), aMesh, "Maillage_1"); @@ -299,25 +300,40 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, smToCompute->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); continue; } - pending.push_back(_pool->push(parallel_compute, smToCompute, computeEvent, - shapeSM, aShapeOnly, allowedSubShapes, - aShapesId)); - //DEBUG std::cout << "Launched " << smToCompute << " shape type " << shapeType << std::endl; - + if(aMesh.IsParallel()) + { + pending.push_back(aMesh._pool->push(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() ); + } } - for(auto it =std::begin(pending); it != std::end(pending); ++it){ - it->wait(); + // TODO: Check error handling in parallel mode + if(aMesh.IsParallel()){ + // Waiting for the thread for Solids to finish + for(auto &it:pending){ + it.wait(); + } + pending.clear(); } - pending.clear(); - //aMesh.GetMeshDS()->Modified(); + + aMesh.GetMeshDS()->Modified(); return ret; } else { // ================================================================ - // Apply algos that do NOT require discreteized boundaries + // Apply algos that do NOT require discretized boundaries // ("all-dimensional") and do NOT support sub-meshes, starting from // the most complex shapes and collect sub-meshes with algos that // DO support sub-meshes diff --git a/src/SMESH/SMESH_Gen.hxx b/src/SMESH/SMESH_Gen.hxx index 7d3508c0f..6c2887488 100644 --- a/src/SMESH/SMESH_Gen.hxx +++ b/src/SMESH/SMESH_Gen.hxx @@ -187,8 +187,6 @@ private: volatile bool _compute_canceled; std::list< SMESH_subMesh* > _sm_current; - // TODO: Replace by number of thread - ctpl::thread_pool * _pool = nullptr; //thread pool for computation }; #endif diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx index 2b8632abb..a8107920c 100644 --- a/src/SMESH/SMESH_Mesh.hxx +++ b/src/SMESH/SMESH_Mesh.hxx @@ -393,8 +393,15 @@ class SMESH_EXPORT SMESH_Mesh int GetNbThreads(){return _NbThreads;}; void SetNbThreads(int nbThreads){_NbThreads=nbThreads;}; + void InitPoolThreads(){_pool = new ctpl::thread_pool(_NbThreads);}; + + bool IsParallel(){return _NbThreads > 0;} + // Temporary folder used during parallel Computation boost::filesystem::path tmp_folder; + // TODO: Replace by number of thread + ctpl::thread_pool * _pool = nullptr; //thread pool for computation + private: diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index 751cf8b79..4406e250a 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -207,20 +207,6 @@ SMESH_Algo* SMESH_subMesh::GetAlgo() const return _algo; } -//================================================================================ -/*! - * \brief Returns a current algorithm - */ -//================================================================================ - -SMESH_Algo* SMESH_subMesh::CopyAlgo() const -{ - //SMESH_Algo* algo = (SMESH_Algo*) new StdMeshers_Regular_1D(666, _father->GetGent()); - SMESH_Algo* algo; - - return algo; -} - //================================================================================ /*! * \brief Allow algo->Compute() if a sub-shape of lower dim is meshed but @@ -1520,12 +1506,11 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) case COMPUTE_SUBMESH: { algo = GetAlgo(); - SMESH_Algo* algo2 = CopyAlgo(); - cout << "Algo2" << algo2; ASSERT(algo); - //_father->Lock(); - //ret = algo->CheckHypothesis((*_father), _subShape, hyp_status); - //_father->Unlock(); + if(!_father->IsParallel()) + ret = algo->CheckHypothesis((*_father), _subShape, hyp_status); + else + ret = true; if (!ret) { MESSAGE("***** verify compute state *****"); @@ -1536,9 +1521,8 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) TopoDS_Shape shape = _subShape; algo->SubMeshesToCompute().assign( 1, this ); // check submeshes needed - // Forcing to false for parallel run - // TODO: Remove forced false - if (_father->HasShapeToMesh() && false) { + // In parallel there would be no submesh to check + if (_father->HasShapeToMesh() && !_father->IsParallel()) { bool subComputed = false, subFailed = false; if (!algo->OnlyUnaryInput()) { // --- commented for bos#22320 to compute all sub-shapes at once if possible; @@ -1594,6 +1578,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) } else { + // TODO: Do switch of compute here instead of within algo ret = algo->Compute((*_father), shape); } // algo can set _computeError of submesh @@ -1756,9 +1741,8 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) updateDependantsState( SUBMESH_COMPUTED ); } // let algo clear its data gathered while algo->Compute() - //_father->Lock(); - //algo->CheckHypothesis((*_father), _subShape, hyp_status); - //_father->Unlock(); + if(!_father->IsParallel()) + algo->CheckHypothesis((*_father), _subShape, hyp_status); } break; case COMPUTE_CANCELED: // nothing to do @@ -2194,10 +2178,8 @@ TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * /*theGen*/, return _subShape; const bool skipAuxHyps = false; - _father->Lock(); list usedHyps = theAlgo->GetUsedHypothesis( *_father, _subShape, skipAuxHyps ); // copy - _father->Lock(); std::list < TopoDS_Shape > assiShapes = theAlgo->GetAssignedShapes(); // put in a compound all shapes with the same hypothesis assigned @@ -2225,7 +2207,6 @@ TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * /*theGen*/, } else if ( subMesh->GetComputeState() == READY_TO_COMPUTE ) { - _father->Lock(); SMESH_Algo* anAlgo = subMesh->GetAlgo(); if (( anAlgo->IsSameName( *theAlgo )) && // same algo ( anAlgo->GetUsedHypothesis( *_father, S, skipAuxHyps ) == usedHyps ) && // same hyps @@ -2237,7 +2218,6 @@ TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * /*theGen*/, theSubComputed = false; theSubs.push_back( subMesh ); } - _father->Unlock(); } } diff --git a/src/SMESHDS/SMESHDS_Mesh.cxx b/src/SMESHDS/SMESHDS_Mesh.cxx index 36fc2d131..7d241698f 100644 --- a/src/SMESHDS/SMESHDS_Mesh.cxx +++ b/src/SMESHDS/SMESHDS_Mesh.cxx @@ -1328,7 +1328,6 @@ SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index) if ( !SM ) { SM = new SMESHDS_SubMesh(this, Index); - std::cout << "Adding " << Index << ':' <Add( Index, SM ); } return SM; From 3f96b3175700b3b76bd0780a83650b36c3362b84 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Wed, 31 Aug 2022 16:06:31 +0200 Subject: [PATCH 06/29] Integration of run_mesher code --- src/SMESH/CMakeLists.txt | 2 + src/SMESH/DriverMesh.cxx | 95 +++++++++++++++++++++++++++++ src/SMESH/DriverMesh.hxx | 46 ++++++++++++++ src/SMESH/DriverStep.cxx | 128 +++++++++++++++++++++++++++++++++++++++ src/SMESH/DriverStep.hxx | 41 +++++++++++++ 5 files changed, 312 insertions(+) create mode 100644 src/SMESH/DriverMesh.cxx create mode 100644 src/SMESH/DriverMesh.hxx create mode 100644 src/SMESH/DriverStep.cxx create mode 100644 src/SMESH/DriverStep.hxx diff --git a/src/SMESH/CMakeLists.txt b/src/SMESH/CMakeLists.txt index fee16b4cd..1cd4f0c16 100644 --- a/src/SMESH/CMakeLists.txt +++ b/src/SMESH/CMakeLists.txt @@ -92,6 +92,7 @@ SET(SMESHimpl_HEADERS SMESH_Homard.hxx ctpl.h DriverMesh.hxx + DriverStep.hxx ) # --- sources --- @@ -113,6 +114,7 @@ SET(SMESHimpl_SOURCES MG_ADAPT.cxx SMESH_Homard.cxx DriverMesh.cxx + DriverStep.cxx ) # --- rules --- diff --git a/src/SMESH/DriverMesh.cxx b/src/SMESH/DriverMesh.cxx new file mode 100644 index 000000000..29d4a6fa5 --- /dev/null +++ b/src/SMESH/DriverMesh.cxx @@ -0,0 +1,95 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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 : DriverMesh.cxx +// Author : Yoann AUDOUIN, EDF +// Module : SMESH +// + +#include "DriverMesh.hxx" + +#include "SMESH_Mesh.hxx" +#include "SMESH_Gen.hxx" + +#include +#include + +using namespace MEDCoupling; + +/** + * @brief Compares the mesh from two mesh files (MED) + * + * @param mesh_file1 First file + * @param mesh_file2 Second file + * @param mesh_name Name of the mesh in the files + * + * @return true if the mesh within the files are identical + */ +bool diff_med_file(const std::string mesh_file1, const std::string mesh_file2, const std::string mesh_name){ + MEDFileUMesh* medmesh1 = MEDFileUMesh::New(mesh_file1, mesh_name); + MEDFileUMesh* medmesh2 = MEDFileUMesh::New(mesh_file2, mesh_name); + MEDCouplingUMesh *m0_1=medmesh1->getMeshAtLevel(0,false); + MEDCouplingUMesh *m0_2=medmesh2->getMeshAtLevel(0,false); + return m0_1->isEqual(m0_2, 1e-12); +} + +/** + * @brief Import a mesh from a mesh file (MED) into a SMESH_Mesh object + * + * @param mesh_file the file + * @param aMesh the object + * @param mesh_name the name of the mesh in the file + * + * @return error code + */ +int import_mesh(const std::string mesh_file, SMESH_Mesh& aMesh, const std::string mesh_name){ + // TODO: change that as it depends on the language + std::cout << "Importing mesh from " << mesh_file << std::endl; + int ret = aMesh.MEDToMesh(mesh_file.c_str(), mesh_name.c_str()); + return ret; +} + +/** + * @brief Export the content of a SMESH_Mesh into a mesh file (MED) + * + * @param mesh_file the file + * @param aMesh the object + * @param mesh_name name of the mesh in the file + * + * @return error code + */ +int export_mesh(const std::string mesh_file, SMESH_Mesh& aMesh, const std::string mesh_name){ + + // TODO: See how to get the name of the mesh. Is it usefull ? + std::cout << "Exporting mesh to " << mesh_file << std::endl; + aMesh.ExportMED(mesh_file.c_str(), // theFile + mesh_name.c_str(), // theMeshName + false, // theAutoGroups + -1, // theVersion + nullptr, // theMeshPart + true, // theAutoDimension + true, // theAddODOnVertices + 1e-8, // theZTolerance + true // theSaveNumbers + ); + return true; +} diff --git a/src/SMESH/DriverMesh.hxx b/src/SMESH/DriverMesh.hxx new file mode 100644 index 000000000..5a1485faf --- /dev/null +++ b/src/SMESH/DriverMesh.hxx @@ -0,0 +1,46 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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 : DriverMesh.hxx +// Author : Yoann AUDOUIN, EDF +// Module : SMESH +// + +#ifndef _DRIVERMESH_HXX_ +#define _DRIVERMESH_HXX_ + +#include +#include + +class SMESH_Mesh; + +bool diff_med_file(const std::string mesh_file1, + const std::string mesh_file2, + const std::string mesh_name); +int import_mesh(const std::string mesh_file, + SMESH_Mesh& aMesh, + const std::string meshName); +int export_mesh(const std::string mesh_file, + SMESH_Mesh& aMesh, + const std::string meshName); + +#endif diff --git a/src/SMESH/DriverStep.cxx b/src/SMESH/DriverStep.cxx new file mode 100644 index 000000000..54d4e8de5 --- /dev/null +++ b/src/SMESH/DriverStep.cxx @@ -0,0 +1,128 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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 : DriverStep.cxx +// Author : Yoann AUDOUIN, EDF +// Module : SMESH +// + +#include "DriverStep.hxx" + +#include +#include +#include + +//Occ include +#include + + +/** + * @brief Compares two shape file (STEP) + * + * @param file1 first file + * @param file2 second file + * + * @return true if the files are the same + */ +bool diff_step_file(std::string file1, std::string file2){ + std::ifstream sfile1(file1); + std::ifstream sfile2(file2); + std::string line1, line2; + int nb_lines = 0; + + while(!sfile1.eof() && !sfile2.eof()){ + std::getline(sfile1, line1); + std::getline(sfile2, line2); + nb_lines++; + // Skipping 4th line contain date of creation + if (nb_lines==4){ + std::cout << "Skipping line" << std::endl; + continue; + } + + // if lines are different end of read + if(line1 != line2){ + return false; + } + + } + // True if we reached the end of both files + return sfile1.eof() && sfile2.eof(); +} + +/** + * @brief Import the content of a shape file (STEP) into a TopDS_Shape object + * + * @param shape_file the shape file + * @param aShape the object + * + * @return error code + */ +int import_shape(const std::string shape_file, TopoDS_Shape& aShape){ + + std::cout << "Importing shape from " << shape_file << std::endl; + STEPControl_Reader reader; + // Forcing Unit in meter + Interface_Static::SetCVal("xstep.cascade.unit","M"); + Interface_Static::SetIVal("read.step.ideas", 1); + Interface_Static::SetIVal("read.step.nonmanifold", 1); + IFSelect_ReturnStatus aStat = reader.ReadFile(shape_file.c_str()); + if(aStat != IFSelect_RetDone) + std::cout << "Reading error for " << shape_file << std::endl; + + int NbTrans = reader.TransferRoots(); + // There should be only one shape within the file + assert(NbTrans==1); + aShape = reader.OneShape(); + + return true; +} + +/** + * @brief Export the content of a TopoDS_Shape into a shape file (STEP) + * + * @param shape_file the shape file + * @param aShape the object + * + * @return error code + */ +int export_shape(const std::string shape_file, const TopoDS_Shape& aShape){ + + std::cout << "Exporting shape to " << shape_file << std::endl; + + STEPControl_Writer aWriter; + // Forcing Unit in meter + Interface_Static::SetCVal("xstep.cascade.unit","M"); + Interface_Static::SetCVal("write.step.unit","M"); + Interface_Static::SetIVal("write.step.nonmanifold", 1); + + IFSelect_ReturnStatus aStat = aWriter.Transfer(aShape,STEPControl_AsIs); + if(aStat != IFSelect_RetDone) + std::cout << "Transfer error for " << shape_file << std::endl; + + aStat = aWriter.Write(shape_file.c_str()); + + if(aStat != IFSelect_RetDone) + std::cout << "Writing error for " << shape_file << std::endl; + + return aStat; +} diff --git a/src/SMESH/DriverStep.hxx b/src/SMESH/DriverStep.hxx new file mode 100644 index 000000000..ab13d1e52 --- /dev/null +++ b/src/SMESH/DriverStep.hxx @@ -0,0 +1,41 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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 : DriverStep.hxx +// Author : Yoann AUDOUIN, EDF +// Module : SMESH +// + +#ifndef _DRIVERSTEP_HXX_ +#define _DRIVERSTEP_HXX_ + +#include +#include + +class TopoDS_Shape; + +int import_shape(const std::string shape_file, TopoDS_Shape& aShape); +int export_shape(const std::string shape_file, const TopoDS_Shape& aShape); +bool diff_step_file(std::string file1, std::string file2); + + +#endif \ No newline at end of file From 446efab7770b5e5910bf3a0c36c4d1f082340284 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Fri, 9 Sep 2022 09:52:50 +0200 Subject: [PATCH 07/29] Deactivating parallelism for 2D/1D + corrections for non parallel run + adding ParallelCompute function in Python --- src/SMESH/SMESH_Gen.cxx | 36 ++++++++++++++++++++++-- src/SMESH/SMESH_Mesh.hxx | 1 + src/SMESH/SMESH_subMesh.cxx | 5 ++-- src/SMESH_SWIG/smeshBuilder.py | 24 ++++++++++++++-- src/StdMeshers/StdMeshers_Regular_1D.cxx | 24 ++++++++-------- 5 files changed, 70 insertions(+), 20 deletions(-) diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index c27f5ec02..6dc2c4d4a 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -48,6 +48,7 @@ #include #include "memoire.h" +#include #ifdef WIN32 #include @@ -247,6 +248,9 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, TopAbs_ShapeEnum previousShapeType = TopAbs_VERTEX; std::vector> pending; + int nbThreads = aMesh.GetNbThreads(); + auto begin = std::chrono::high_resolution_clock::now(); + smIt = shapeSM->getDependsOnIterator(includeSelf, !complexShapeFirst); while ( smIt->more() ) @@ -258,13 +262,17 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, const TopAbs_ShapeEnum shapeType = shape.ShapeType(); if ( !aMesh.HasShapeToMesh() && shapeType == TopAbs_VERTEX ) continue; - + if(shapeType==TopAbs_FACE||shapeType==TopAbs_EDGE) + aMesh.SetNbThreads(0); + else + aMesh.SetNbThreads(nbThreads); //DEBUG std::cout << "Shape Type" << shapeType << " previous" << previousShapeType << std::endl; - if (aMesh.IsParallel() && shapeType != previousShapeType) { + if ((aMesh.IsParallel()||nbThreads!=0) && shapeType != previousShapeType) { // Waiting for all threads for the previous type to end for(auto &it: pending){ it.wait(); } + std::string file_name; switch(previousShapeType){ case TopAbs_FACE: @@ -276,6 +284,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, case TopAbs_VERTEX: file_name = "Mesh0D.med"; break; + case TopAbs_SOLID: default: file_name = ""; break; @@ -306,10 +315,14 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, shapeSM, aShapeOnly, allowedSubShapes, aShapesId)); } else { + auto begin2 = std::chrono::high_resolution_clock::now(); + 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; @@ -328,6 +341,14 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, } aMesh.GetMeshDS()->Modified(); + auto end = std::chrono::high_resolution_clock::now(); + auto elapsed = std::chrono::duration_cast(end - begin); + std::cout << "Time for All: " << elapsed.count()*1e-9 << std::endl; + + // Pool of thread for computation + if(aMesh.IsParallel()) + aMesh.DeletePoolThreads(); + return ret; } else @@ -338,7 +359,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, // the most complex shapes and collect sub-meshes with algos that // DO support sub-meshes // ================================================================ - + auto begin = std::chrono::high_resolution_clock::now(); list< SMESH_subMesh* > smWithAlgoSupportingSubmeshes[4]; // for each dim // map to sort sm with same dim algos according to dim of @@ -534,7 +555,12 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, continue; sm->SetAllowedSubShapes( fillAllowed( shapeSM, aShapeOnly, allowedSubShapes )); setCurrentSubMesh( sm ); + auto begin = std::chrono::high_resolution_clock::now(); sm->ComputeStateEngine( computeEvent ); + auto end = std::chrono::high_resolution_clock::now(); + auto elapsed = std::chrono::duration_cast(end - begin); + std::cout << "Time for seq:alldim:compute: " << elapsed.count()*1e-9 << std::endl; + setCurrentSubMesh( NULL ); sm->SetAllowedSubShapes( nullptr ); if ( aShapesId ) @@ -547,6 +573,10 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, // mesh the rest sub-shapes starting from vertices // ----------------------------------------------- ret = Compute( aMesh, aShape, aFlags | UPWARD, aDim, aShapesId, allowedSubShapes ); + auto end = std::chrono::high_resolution_clock::now(); + auto elapsed = std::chrono::duration_cast(end - begin); + std::cout << "Time for All: " << elapsed.count()*1e-9 << std::endl; + } MEMOSTAT; diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx index a8107920c..02f38a12e 100644 --- a/src/SMESH/SMESH_Mesh.hxx +++ b/src/SMESH/SMESH_Mesh.hxx @@ -394,6 +394,7 @@ class SMESH_EXPORT SMESH_Mesh void SetNbThreads(int nbThreads){_NbThreads=nbThreads;}; void InitPoolThreads(){_pool = new ctpl::thread_pool(_NbThreads);}; + void DeletePoolThreads(){delete _pool;}; bool IsParallel(){return _NbThreads > 0;} diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index 4406e250a..4edd75cd5 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -65,7 +65,7 @@ using namespace std; //#define PRINT_WHO_COMPUTE_WHAT #endif -#define PRINT_WHO_COMPUTE_WHAT +//#define PRINT_WHO_COMPUTE_WHAT //============================================================================= /*! * \brief Allocate some memory at construction and release it at destruction. @@ -1519,7 +1519,8 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) break; } TopoDS_Shape shape = _subShape; - algo->SubMeshesToCompute().assign( 1, this ); + if(!_father->IsParallel()) + algo->SubMeshesToCompute().assign( 1, this ); // check submeshes needed // In parallel there would be no submesh to check if (_father->HasShapeToMesh() && !_father->IsParallel()) { diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index 19ae2a934..bb1361dac 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -1863,8 +1863,28 @@ class Mesh(metaclass = MeshMeta): geom = self.geom return self.smeshpyD.Evaluate(self.mesh, geom) + def ParallelCompute(self, nbThreads, geom=0, discardModifs=False, refresh=False): + """ + Parallel computation of the mesh and return the status of the computation + The mesh must contains have be constructed using create_parallel_mesh - def Compute(self, geom=0, discardModifs=False, refresh=False, nbThreads=0): + Parameters: + nbThreads: Number of threads to use for a parallel computation + geom: geomtrical shape on which mesh data should be computed + discardModifs: if True and the mesh has been edited since + 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) + + Returns: + True or False + """ + if (nbThreads <= 1): + raise ValueError("nbThreads must be greater than 1") + self.mesh.SetNbThreads(nbThreads) + return self.Compute(geom=geom, discardModifs=discardModifs, refresh=refresh) + + def Compute(self, geom=0, discardModifs=False, refresh=False): """ Compute the mesh and return the status of the computation @@ -1886,8 +1906,6 @@ class Mesh(metaclass = MeshMeta): try: if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693 self.mesh.Clear() - # Setting parallel parameters - self.mesh.SetNbThreads(nbThreads) ok = self.smeshpyD.Compute(self.mesh, geom) except SALOME.SALOME_Exception as ex: print("Mesh computation failed, exception caught:") diff --git a/src/StdMeshers/StdMeshers_Regular_1D.cxx b/src/StdMeshers/StdMeshers_Regular_1D.cxx index c26113ab3..625ecdceb 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.cxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.cxx @@ -133,15 +133,15 @@ bool StdMeshers_Regular_1D::CheckHypothesis( SMESH_Mesh& aMesh, // find non-auxiliary hypothesis const SMESHDS_Hypothesis *theHyp = 0; set< string > propagTypes; - std::cout << "For shape " << aShape.HashCode(1) << " of type "<< aShape.ShapeType() << - "CheckHypothesis" << std::endl; - for(auto hyp:hyps){ - SMESH_Comment hypStr; - hypStr << hyp << " " << hyp->GetName() << " "; - ((SMESHDS_Hypothesis*)hyp)->SaveTo( hypStr.Stream() ); - hypStr << " "; - std::cout << hypStr << std::endl; - } + //std::cout << "For shape " << aShape.HashCode(1) << " of type "<< aShape.ShapeType() << + // "CheckHypothesis" << std::endl; + // for(auto hyp:hyps){ + // SMESH_Comment hypStr; + // hypStr << hyp << " " << hyp->GetName() << " "; + // ((SMESHDS_Hypothesis*)hyp)->SaveTo( hypStr.Stream() ); + // hypStr << " "; + // std::cout << hypStr << std::endl; + // } list ::const_iterator h = hyps.begin(); for ( ; h != hyps.end(); ++h ) { if ( static_cast(*h)->IsAuxiliary() ) { @@ -1218,7 +1218,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t const SMDS_MeshNode * nLast = SMESH_Algo::VertexNode( VLast, meshDS ); if ( !nFirst || !nLast ){ theMesh.Unlock(); - std::cout << "exit no node" << std::endl; + //std::cout << "exit no node" << std::endl; return error( COMPERR_BAD_INPUT_MESH, "No node on vertex"); } // remove elements created by e.g. pattern mapping (PAL21999) @@ -1265,7 +1265,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t BRepAdaptor_Curve C3d( E ); if ( ! computeInternalParameters( theMesh, C3d, length, f, l, params, reversed, true )) { theMesh.Unlock(); - std::cout << "exit Compute internal failed" << std::endl; + //std::cout << "exit Compute internal failed" << std::endl; return false; } @@ -1358,7 +1358,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t } } theMesh.Unlock(); - std::cout << "exit normal" << std::endl; + //std::cout << "exit normal" << std::endl; return true; } From 7a915a21ead4b7032d3c8626d154783f6dd17647 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Mon, 12 Sep 2022 16:17:20 +0200 Subject: [PATCH 08/29] Replacing ctpl by boost::thread_pool --- src/SMESH/CMakeLists.txt | 1 - src/SMESH/SMESH_Gen.cxx | 21 ++-- src/SMESH/SMESH_Gen.hxx | 2 - src/SMESH/SMESH_Mesh.hxx | 12 +- src/SMESH/ctpl.h | 240 --------------------------------------- 5 files changed, 15 insertions(+), 261 deletions(-) delete mode 100644 src/SMESH/ctpl.h diff --git a/src/SMESH/CMakeLists.txt b/src/SMESH/CMakeLists.txt index 1cd4f0c16..2dfa65466 100644 --- a/src/SMESH/CMakeLists.txt +++ b/src/SMESH/CMakeLists.txt @@ -90,7 +90,6 @@ SET(SMESHimpl_HEADERS SMESH_SMESH.hxx MG_ADAPT.hxx SMESH_Homard.hxx - ctpl.h DriverMesh.hxx DriverStep.hxx ) diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index 6dc2c4d4a..45a0049b4 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -49,6 +49,7 @@ #include "memoire.h" #include +#include #ifdef WIN32 #include @@ -58,6 +59,7 @@ using namespace std; #include +#include namespace fs = boost::filesystem; // Environment variable separator @@ -247,7 +249,6 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, // =============================================== TopAbs_ShapeEnum previousShapeType = TopAbs_VERTEX; - std::vector> pending; int nbThreads = aMesh.GetNbThreads(); auto begin = std::chrono::high_resolution_clock::now(); @@ -269,9 +270,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, //DEBUG std::cout << "Shape Type" << shapeType << " previous" << previousShapeType << std::endl; if ((aMesh.IsParallel()||nbThreads!=0) && shapeType != previousShapeType) { // Waiting for all threads for the previous type to end - for(auto &it: pending){ - it.wait(); - } + aMesh.wait(); std::string file_name; switch(previousShapeType){ @@ -298,7 +297,6 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, } //Resetting threaded pool info previousShapeType = shapeType; - pending.clear(); } // check for preview dimension limitations @@ -311,9 +309,11 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, } if(aMesh.IsParallel()) { - pending.push_back(aMesh._pool->push(compute_function, smToCompute, computeEvent, - shapeSM, aShapeOnly, allowedSubShapes, - aShapesId)); + std::cout << "Submitting thread function " << std::endl; + boost::asio::post(*(aMesh._pool), [](){std::cerr<< "In Here" << std::endl;}); + boost::asio::post(*(aMesh._pool), std::bind(compute_function, 1, smToCompute, computeEvent, + shapeSM, aShapeOnly, allowedSubShapes, + aShapesId)); } else { auto begin2 = std::chrono::high_resolution_clock::now(); @@ -334,10 +334,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, // TODO: Check error handling in parallel mode if(aMesh.IsParallel()){ // Waiting for the thread for Solids to finish - for(auto &it:pending){ - it.wait(); - } - pending.clear(); + aMesh.wait(); } aMesh.GetMeshDS()->Modified(); diff --git a/src/SMESH/SMESH_Gen.hxx b/src/SMESH/SMESH_Gen.hxx index 6c2887488..c5b958b07 100644 --- a/src/SMESH/SMESH_Gen.hxx +++ b/src/SMESH/SMESH_Gen.hxx @@ -34,8 +34,6 @@ #include "SMESH_Algo.hxx" #include "SMESH_ComputeError.hxx" -#include "ctpl.h" - #include #include diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx index 02f38a12e..29060a245 100644 --- a/src/SMESH/SMESH_Mesh.hxx +++ b/src/SMESH/SMESH_Mesh.hxx @@ -43,13 +43,12 @@ #include "MEDCouplingMemArray.hxx" -#include "ctpl.h" - #include #include #include #include #include +#include #ifdef WIN32 #pragma warning(disable:4251) // Warning DLL Interface ... @@ -385,7 +384,7 @@ class SMESH_EXPORT SMESH_Mesh std::ostream& Dump(std::ostream & save); - // Data for parallel computation + // Parallel computation functions void Lock() {_my_lock.lock();}; void Unlock() {_my_lock.unlock();}; @@ -393,15 +392,16 @@ class SMESH_EXPORT SMESH_Mesh int GetNbThreads(){return _NbThreads;}; void SetNbThreads(int nbThreads){_NbThreads=nbThreads;}; - void InitPoolThreads(){_pool = new ctpl::thread_pool(_NbThreads);}; + void InitPoolThreads(){_pool = new boost::asio::thread_pool(_NbThreads);}; void DeletePoolThreads(){delete _pool;}; + void wait(){_pool->join(); DeletePoolThreads(); InitPoolThreads(); } + bool IsParallel(){return _NbThreads > 0;} // Temporary folder used during parallel Computation boost::filesystem::path tmp_folder; - // TODO: Replace by number of thread - ctpl::thread_pool * _pool = nullptr; //thread pool for computation + boost::asio::thread_pool * _pool = nullptr; //thread pool for computation private: diff --git a/src/SMESH/ctpl.h b/src/SMESH/ctpl.h deleted file mode 100644 index 64f650d3e..000000000 --- a/src/SMESH/ctpl.h +++ /dev/null @@ -1,240 +0,0 @@ - -/********************************************************* - * - * Copyright (C) 2014 by Vitaliy Vitsentiy - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - *********************************************************/ - - -#ifndef __ctpl_thread_pool_H__ -#define __ctpl_thread_pool_H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#ifndef _ctplThreadPoolLength_ -#define _ctplThreadPoolLength_ 100 -#endif - - -// thread pool to run user's functors with signature -// ret func(int id, other_params) -// where id is the index of the thread that runs the functor -// ret is some return type - - -namespace ctpl { - - class thread_pool { - - public: - - thread_pool() : q(_ctplThreadPoolLength_) { this->init(); } - thread_pool(int nThreads, int queueSize = _ctplThreadPoolLength_) : q(queueSize) { this->init(); this->resize(nThreads); } - - // the destructor waits for all the functions in the queue to be finished - ~thread_pool() { - this->stop(true); - } - - // get the number of running threads in the pool - int size() { return static_cast(this->threads.size()); } - - // number of idle threads - int n_idle() { return this->nWaiting; } - std::thread & get_thread(int i) { return *this->threads[i]; } - - // change the number of threads in the pool - // should be called from one thread, otherwise be careful to not interleave, also with this->stop() - // nThreads must be >= 0 - void resize(int nThreads) { - if (!this->isStop && !this->isDone) { - int oldNThreads = static_cast(this->threads.size()); - if (oldNThreads <= nThreads) { // if the number of threads is increased - this->threads.resize(nThreads); - this->flags.resize(nThreads); - - for (int i = oldNThreads; i < nThreads; ++i) { - this->flags[i] = std::make_shared>(false); - this->set_thread(i); - } - } - else { // the number of threads is decreased - for (int i = oldNThreads - 1; i >= nThreads; --i) { - *this->flags[i] = true; // this thread will finish - this->threads[i]->detach(); - } - { - // stop the detached threads that were waiting - std::unique_lock lock(this->mutex); - this->cv.notify_all(); - } - this->threads.resize(nThreads); // safe to delete because the threads are detached - this->flags.resize(nThreads); // safe to delete because the threads have copies of shared_ptr of the flags, not originals - } - } - } - - // empty the queue - void clear_queue() { - std::function * _f; - while (this->q.pop(_f)) - delete _f; // empty the queue - } - - // pops a functional wraper to the original function - std::function pop() { - std::function * _f = nullptr; - this->q.pop(_f); - std::unique_ptr> func(_f); // at return, delete the function even if an exception occurred - - std::function f; - if (_f) - f = *_f; - return f; - } - - - // wait for all computing threads to finish and stop all threads - // may be called asyncronously to not pause the calling thread while waiting - // if isWait == true, all the functions in the queue are run, otherwise the queue is cleared without running the functions - void stop(bool isWait = false) { - if (!isWait) { - if (this->isStop) - return; - this->isStop = true; - for (int i = 0, n = this->size(); i < n; ++i) { - *this->flags[i] = true; // command the threads to stop - } - this->clear_queue(); // empty the queue - } - else { - if (this->isDone || this->isStop) - return; - this->isDone = true; // give the waiting threads a command to finish - } - { - std::unique_lock lock(this->mutex); - this->cv.notify_all(); // stop all waiting threads - } - for (int i = 0; i < static_cast(this->threads.size()); ++i) { // wait for the computing threads to finish - if (this->threads[i]->joinable()) - this->threads[i]->join(); - } - // if there were no threads in the pool but some functors in the queue, the functors are not deleted by the threads - // therefore delete them here - this->clear_queue(); - this->threads.clear(); - this->flags.clear(); - } - - template - auto push(F && f, Rest&&... rest) ->std::future { - auto pck = std::make_shared>( - std::bind(std::forward(f), std::placeholders::_1, std::forward(rest)...) - ); - - auto _f = new std::function([pck](int id) { - (*pck)(id); - }); - this->q.push(_f); - - std::unique_lock lock(this->mutex); - this->cv.notify_one(); - - return pck->get_future(); - } - - // run the user's function that excepts argument int - id of the running thread. returned value is templatized - // operator returns std::future, where the user can get the result and rethrow the catched exceptins - template - auto push(F && f) ->std::future { - auto pck = std::make_shared>(std::forward(f)); - - auto _f = new std::function([pck](int id) { - (*pck)(id); - }); - this->q.push(_f); - - std::unique_lock lock(this->mutex); - this->cv.notify_one(); - - return pck->get_future(); - } - - - private: - - // deleted - thread_pool(const thread_pool &);// = delete; - thread_pool(thread_pool &&);// = delete; - thread_pool & operator=(const thread_pool &);// = delete; - thread_pool & operator=(thread_pool &&);// = delete; - - void set_thread(int i) { - std::shared_ptr> flag(this->flags[i]); // a copy of the shared ptr to the flag - auto f = [this, i, flag/* a copy of the shared ptr to the flag */]() { - std::atomic & _flag = *flag; - std::function * _f; - bool isPop = this->q.pop(_f); - while (true) { - while (isPop) { // if there is anything in the queue - std::unique_ptr> func(_f); // at return, delete the function even if an exception occurred - (*_f)(i); - - if (_flag) - return; // the thread is wanted to stop, return even if the queue is not empty yet - else - isPop = this->q.pop(_f); - } - - // the queue is empty here, wait for the next command - std::unique_lock lock(this->mutex); - ++this->nWaiting; - this->cv.wait(lock, [this, &_f, &isPop, &_flag](){ isPop = this->q.pop(_f); return isPop || this->isDone || _flag; }); - --this->nWaiting; - - if (!isPop) - return; // if the queue is empty and this->isDone == true or *flag then return - } - }; - this->threads[i].reset(new std::thread(f)); // compiler may not support std::make_unique() - } - - void init() { this->nWaiting = 0; this->isStop = false; this->isDone = false; } - - std::vector> threads; - std::vector>> flags; - mutable boost::lockfree::queue *> q; - std::atomic isDone; - std::atomic isStop; - std::atomic nWaiting; // how many threads are waiting - - std::mutex mutex; - std::condition_variable cv; - }; - -} - -#endif // __ctpl_thread_pool_H__ - From 33f226d32134089d08e1019cf80e9d4defd437f1 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Tue, 13 Sep 2022 14:17:43 +0200 Subject: [PATCH 09/29] Adding support of number of thread for the mesher --- idl/SMESH_Mesh.idl | 6 ++++++ src/SMESH/SMESH_Gen.cxx | 5 +---- src/SMESH/SMESH_Mesh.hxx | 4 ++++ src/SMESH_I/SMESH_2smeshpy.cxx | 3 ++- src/SMESH_I/SMESH_Mesh_i.cxx | 9 +++++++++ src/SMESH_I/SMESH_Mesh_i.hxx | 1 + src/SMESH_SWIG/smeshBuilder.py | 6 +++++- 7 files changed, 28 insertions(+), 6 deletions(-) diff --git a/idl/SMESH_Mesh.idl b/idl/SMESH_Mesh.idl index e70b3d842..f420e4ff7 100644 --- a/idl/SMESH_Mesh.idl +++ b/idl/SMESH_Mesh.idl @@ -903,6 +903,12 @@ module SMESH * \brief Set Number of Threads */ void SetNbThreads(in long nbThreads); + /*! + + * \brief Set Number of Threads for mesher + */ + void SetMesherNbThreads(in long nbThreads); + /*! * Get mesh description diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index 45a0049b4..fd053da69 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -251,6 +251,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, TopAbs_ShapeEnum previousShapeType = TopAbs_VERTEX; int nbThreads = aMesh.GetNbThreads(); auto begin = std::chrono::high_resolution_clock::now(); + std::cout << "Running mesh with threads: " << nbThreads << " mesher: " << aMesh.GetMesherNbThreads() << std::endl; smIt = shapeSM->getDependsOnIterator(includeSelf, !complexShapeFirst); @@ -309,8 +310,6 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, } if(aMesh.IsParallel()) { - std::cout << "Submitting thread function " << std::endl; - boost::asio::post(*(aMesh._pool), [](){std::cerr<< "In Here" << std::endl;}); boost::asio::post(*(aMesh._pool), std::bind(compute_function, 1, smToCompute, computeEvent, shapeSM, aShapeOnly, allowedSubShapes, aShapesId)); @@ -321,8 +320,6 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, shapeSM, aShapeOnly, allowedSubShapes, aShapesId); - - if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE && ( shapeType != TopAbs_EDGE || !SMESH_Algo::isDegenerated( TopoDS::Edge( shape )))) ret = false; diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx index 29060a245..28a5b5a2b 100644 --- a/src/SMESH/SMESH_Mesh.hxx +++ b/src/SMESH/SMESH_Mesh.hxx @@ -392,6 +392,9 @@ class SMESH_EXPORT SMESH_Mesh int GetNbThreads(){return _NbThreads;}; void SetNbThreads(int nbThreads){_NbThreads=nbThreads;}; + int GetMesherNbThreads(){return _MesherNbThreads;}; + void SetMesherNbThreads(int nbThreads){_MesherNbThreads=nbThreads;}; + void InitPoolThreads(){_pool = new boost::asio::thread_pool(_NbThreads);}; void DeletePoolThreads(){delete _pool;}; @@ -453,6 +456,7 @@ protected: // Mutex for multhitreading write in SMESH_Mesh std::mutex _my_lock; int _NbThreads=0; + int _MesherNbThreads=0; protected: SMESH_Mesh(); diff --git a/src/SMESH_I/SMESH_2smeshpy.cxx b/src/SMESH_I/SMESH_2smeshpy.cxx index a062e3d2f..a9fff0a6d 100644 --- a/src/SMESH_I/SMESH_2smeshpy.cxx +++ b/src/SMESH_I/SMESH_2smeshpy.cxx @@ -2212,7 +2212,8 @@ bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand ) "GetElemNode","IsMediumNode","IsMediumNodeOfAnyElem","ElemNbEdges","ElemNbFaces", "GetElemFaceNodes", "GetFaceNormal", "FindElementByNodes", "IsPoly","IsQuadratic","BaryCenter","GetHypothesisList", "SetAutoColor", "GetAutoColor", - "Clear", "ConvertToStandalone", "GetMeshOrder", "SetMeshOrder", "SetNbThreads" + "Clear", "ConvertToStandalone", "GetMeshOrder", "SetMeshOrder", + "SetNbThreads", "SetMesherNbThreads" ,"" }; // <- mark of end sameMethods.Insert( names ); } diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index a7abda6db..3bd2f7fe7 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -7046,6 +7046,15 @@ void SMESH_Mesh_i::SetNbThreads(int nbThreads){ _impl->SetNbThreads(nbThreads); } +//============================================================================= +/*! + * \brief Set the number of threads for the mesher for a parallel computation + */ +//============================================================================= +void SMESH_Mesh_i::SetMesherNbThreads(int nbThreads){ + _impl->SetMesherNbThreads(nbThreads); +} + //============================================================================= /*! diff --git a/src/SMESH_I/SMESH_Mesh_i.hxx b/src/SMESH_I/SMESH_Mesh_i.hxx index 25892ca9d..444c7b791 100644 --- a/src/SMESH_I/SMESH_Mesh_i.hxx +++ b/src/SMESH_I/SMESH_Mesh_i.hxx @@ -674,6 +674,7 @@ private: const bool theIsDump); void SetNbThreads(int nbThreads); + void SetMesherNbThreads(int nbThreads); /*! * \brief Finds concurrent sub-meshes diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index bb1361dac..3fad0860b 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -1863,7 +1863,7 @@ class Mesh(metaclass = MeshMeta): geom = self.geom return self.smeshpyD.Evaluate(self.mesh, geom) - def ParallelCompute(self, nbThreads, geom=0, discardModifs=False, refresh=False): + def ParallelCompute(self, nbThreads, mesherNbThreads=1, geom=0, discardModifs=False, refresh=False): """ Parallel computation of the mesh and return the status of the computation The mesh must contains have be constructed using create_parallel_mesh @@ -1880,7 +1880,11 @@ class Mesh(metaclass = MeshMeta): True or False """ if (nbThreads <= 1): + raise ValueError("nbThreads must be strictly greater than 1") + if (mesherNbThreads < 1): raise ValueError("nbThreads must be greater than 1") + + self.mesh.SetMesherNbThreads(mesherNbThreads) self.mesh.SetNbThreads(nbThreads) return self.Compute(geom=geom, discardModifs=discardModifs, refresh=refresh) From 3846e0a7e8de51a3b6d77c0f3c116f4ec1f5c3ea Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Tue, 13 Sep 2022 16:45:33 +0200 Subject: [PATCH 10/29] Renamming function and files --- src/SMESH/CMakeLists.txt | 8 ++++---- src/SMESH/{DriverMesh.cxx => SMESH_DriverMesh.cxx} | 10 +++++----- src/SMESH/{DriverMesh.hxx => SMESH_DriverMesh.hxx} | 12 ++++++------ src/SMESH/{DriverStep.cxx => SMESH_DriverStep.cxx} | 10 +++++----- src/SMESH/{DriverStep.hxx => SMESH_DriverStep.hxx} | 12 ++++++------ src/SMESH/SMESH_Gen.cxx | 4 ++-- 6 files changed, 28 insertions(+), 28 deletions(-) rename src/SMESH/{DriverMesh.cxx => SMESH_DriverMesh.cxx} (89%) rename src/SMESH/{DriverMesh.hxx => SMESH_DriverMesh.hxx} (85%) rename src/SMESH/{DriverStep.cxx => SMESH_DriverStep.cxx} (92%) rename src/SMESH/{DriverStep.hxx => SMESH_DriverStep.hxx} (79%) diff --git a/src/SMESH/CMakeLists.txt b/src/SMESH/CMakeLists.txt index 2dfa65466..75c964b99 100644 --- a/src/SMESH/CMakeLists.txt +++ b/src/SMESH/CMakeLists.txt @@ -90,8 +90,8 @@ SET(SMESHimpl_HEADERS SMESH_SMESH.hxx MG_ADAPT.hxx SMESH_Homard.hxx - DriverMesh.hxx - DriverStep.hxx + SMESH_DriverMesh.hxx + SMESH_DriverStep.hxx ) # --- sources --- @@ -112,8 +112,8 @@ SET(SMESHimpl_SOURCES SMESH_MesherHelper.cxx MG_ADAPT.cxx SMESH_Homard.cxx - DriverMesh.cxx - DriverStep.cxx + SMESH_DriverMesh.cxx + SMESH_DriverStep.cxx ) # --- rules --- diff --git a/src/SMESH/DriverMesh.cxx b/src/SMESH/SMESH_DriverMesh.cxx similarity index 89% rename from src/SMESH/DriverMesh.cxx rename to src/SMESH/SMESH_DriverMesh.cxx index 29d4a6fa5..2c01523d4 100644 --- a/src/SMESH/DriverMesh.cxx +++ b/src/SMESH/SMESH_DriverMesh.cxx @@ -20,12 +20,12 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// File : DriverMesh.cxx +// File : SMESH_DriverMesh.cxx // Author : Yoann AUDOUIN, EDF // Module : SMESH // -#include "DriverMesh.hxx" +#include "SMESH_DriverMesh.hxx" #include "SMESH_Mesh.hxx" #include "SMESH_Gen.hxx" @@ -44,7 +44,7 @@ using namespace MEDCoupling; * * @return true if the mesh within the files are identical */ -bool diff_med_file(const std::string mesh_file1, const std::string mesh_file2, const std::string mesh_name){ +bool diffMEDFile(const std::string mesh_file1, const std::string mesh_file2, const std::string mesh_name){ MEDFileUMesh* medmesh1 = MEDFileUMesh::New(mesh_file1, mesh_name); MEDFileUMesh* medmesh2 = MEDFileUMesh::New(mesh_file2, mesh_name); MEDCouplingUMesh *m0_1=medmesh1->getMeshAtLevel(0,false); @@ -61,7 +61,7 @@ bool diff_med_file(const std::string mesh_file1, const std::string mesh_file2, c * * @return error code */ -int import_mesh(const std::string mesh_file, SMESH_Mesh& aMesh, const std::string mesh_name){ +int importMesh(const std::string mesh_file, SMESH_Mesh& aMesh, const std::string mesh_name){ // TODO: change that as it depends on the language std::cout << "Importing mesh from " << mesh_file << std::endl; int ret = aMesh.MEDToMesh(mesh_file.c_str(), mesh_name.c_str()); @@ -77,7 +77,7 @@ int import_mesh(const std::string mesh_file, SMESH_Mesh& aMesh, const std::strin * * @return error code */ -int export_mesh(const std::string mesh_file, SMESH_Mesh& aMesh, const std::string mesh_name){ +int exportMesh(const std::string mesh_file, SMESH_Mesh& aMesh, const std::string mesh_name){ // TODO: See how to get the name of the mesh. Is it usefull ? std::cout << "Exporting mesh to " << mesh_file << std::endl; diff --git a/src/SMESH/DriverMesh.hxx b/src/SMESH/SMESH_DriverMesh.hxx similarity index 85% rename from src/SMESH/DriverMesh.hxx rename to src/SMESH/SMESH_DriverMesh.hxx index 5a1485faf..eaf2ed18b 100644 --- a/src/SMESH/DriverMesh.hxx +++ b/src/SMESH/SMESH_DriverMesh.hxx @@ -20,26 +20,26 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// File : DriverMesh.hxx +// File : SMESH_DriverMesh.hxx // Author : Yoann AUDOUIN, EDF // Module : SMESH // -#ifndef _DRIVERMESH_HXX_ -#define _DRIVERMESH_HXX_ +#ifndef _SMESH_DRIVERMESH_HXX_ +#define _SMESH_DRIVERMESH_HXX_ #include #include class SMESH_Mesh; -bool diff_med_file(const std::string mesh_file1, +bool diffMEDFile(const std::string mesh_file1, const std::string mesh_file2, const std::string mesh_name); -int import_mesh(const std::string mesh_file, +int importMesh(const std::string mesh_file, SMESH_Mesh& aMesh, const std::string meshName); -int export_mesh(const std::string mesh_file, +int exportMesh(const std::string mesh_file, SMESH_Mesh& aMesh, const std::string meshName); diff --git a/src/SMESH/DriverStep.cxx b/src/SMESH/SMESH_DriverStep.cxx similarity index 92% rename from src/SMESH/DriverStep.cxx rename to src/SMESH/SMESH_DriverStep.cxx index 54d4e8de5..b19be4891 100644 --- a/src/SMESH/DriverStep.cxx +++ b/src/SMESH/SMESH_DriverStep.cxx @@ -20,12 +20,12 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// File : DriverStep.cxx +// File : SMESH_DriverStep.cxx // Author : Yoann AUDOUIN, EDF // Module : SMESH // -#include "DriverStep.hxx" +#include "SMESH_DriverStep.hxx" #include #include @@ -43,7 +43,7 @@ * * @return true if the files are the same */ -bool diff_step_file(std::string file1, std::string file2){ +bool diffStepFile(std::string file1, std::string file2){ std::ifstream sfile1(file1); std::ifstream sfile2(file2); std::string line1, line2; @@ -77,7 +77,7 @@ bool diff_step_file(std::string file1, std::string file2){ * * @return error code */ -int import_shape(const std::string shape_file, TopoDS_Shape& aShape){ +int importShape(const std::string shape_file, TopoDS_Shape& aShape){ std::cout << "Importing shape from " << shape_file << std::endl; STEPControl_Reader reader; @@ -105,7 +105,7 @@ int import_shape(const std::string shape_file, TopoDS_Shape& aShape){ * * @return error code */ -int export_shape(const std::string shape_file, const TopoDS_Shape& aShape){ +int exportShape(const std::string shape_file, const TopoDS_Shape& aShape){ std::cout << "Exporting shape to " << shape_file << std::endl; diff --git a/src/SMESH/DriverStep.hxx b/src/SMESH/SMESH_DriverStep.hxx similarity index 79% rename from src/SMESH/DriverStep.hxx rename to src/SMESH/SMESH_DriverStep.hxx index ab13d1e52..18158ae49 100644 --- a/src/SMESH/DriverStep.hxx +++ b/src/SMESH/SMESH_DriverStep.hxx @@ -20,22 +20,22 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// File : DriverStep.hxx +// File : SMESH_DriverStep.hxx // Author : Yoann AUDOUIN, EDF // Module : SMESH // -#ifndef _DRIVERSTEP_HXX_ -#define _DRIVERSTEP_HXX_ +#ifndef _SMESH_DRIVERSTEP_HXX_ +#define _SMESH_DRIVERSTEP_HXX_ #include #include class TopoDS_Shape; -int import_shape(const std::string shape_file, TopoDS_Shape& aShape); -int export_shape(const std::string shape_file, const TopoDS_Shape& aShape); -bool diff_step_file(std::string file1, std::string file2); +int importShape(const std::string shape_file, TopoDS_Shape& aShape); +int exportShape(const std::string shape_file, const TopoDS_Shape& aShape); +bool diffStepFile(std::string file1, std::string file2); #endif \ No newline at end of file diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index fd053da69..e2d908f1f 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -30,7 +30,7 @@ #include "SMESH_Gen.hxx" -#include "DriverMesh.hxx" +#include "SMESH_DriverMesh.hxx" #include "SMDS_Mesh.hxx" #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" @@ -293,7 +293,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, { fs::path mesh_file = fs::path(aMesh.tmp_folder) / fs::path(file_name); // TODO: change mesh name - export_mesh(mesh_file.string(), aMesh, "Maillage_1"); + exportMesh(mesh_file.string(), aMesh, "Maillage_1"); } //Resetting threaded pool info From 3a97cee0d22316af9d2c8e25902b12292cb923ec Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Wed, 14 Sep 2022 16:36:10 +0200 Subject: [PATCH 11/29] Adding tests for netgen_runner and parallel compute --- test/netgen_runner.py | 125 ++++++++++++++++++++++++++++++++++++++++++ test/tests.set | 1 + 2 files changed, 126 insertions(+) create mode 100644 test/netgen_runner.py diff --git a/test/netgen_runner.py b/test/netgen_runner.py new file mode 100644 index 000000000..9740b2676 --- /dev/null +++ b/test/netgen_runner.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python +import sys +import salome + +salome.salome_init() + +from os import path +import tempfile +import subprocess + +import GEOM, SMESH, SALOMEDS + +from salome.geom import geomBuilder +from salome.smesh import smeshBuilder + +import math + +smesh = smeshBuilder.New() +geompy = geomBuilder.New() + +import medcoupling as mc + +def create_param_file(param_file): + """ Create a parameter file for runner """ + param="""1 +34.64 +0.14 +16 +0.15 +1.5 +0 +0 +1 +5 +1 +1 +-1 +3 +3 +0.2 +2 +1 +0 +0 +2 +0 + +0 +0""" + with open(param_file, "w") as ffile: + ffile.write(param) + + +def test_netgen3d(): + """ Test netgen3d mesher """ + # Building geometry + box = geompy.MakeBoxDXDYDZ(200, 200, 200) + + geompy.ExtractShapes(box, geompy.ShapeType["FACE"], True) + Groupe_1 = geompy.CreateGroup(box, geompy.ShapeType["FACE"]) + geompy.UnionIDs(Groupe_1, [3, 13, 23, 27, 31, 33]) + + # TODO: useful ? + [_, _, _, _, _, _, Groupe_1] = geompy.GetExistingSubObjects(box, False) + + # Creating 2D mesh + NETGEN_2D_Parameters_1 = smesh.CreateHypothesisByAverageLength( + 'NETGEN_Parameters_2D', 'NETGENEngine', 34.641, 0) + Mesh2D = smesh.Mesh(Groupe_1, 'Maillage_1') + status = Mesh2D.AddHypothesis(Groupe_1, NETGEN_2D_Parameters_1) + NETGEN_1D_2D = Mesh2D.Triangle(algo=smeshBuilder.NETGEN_1D2D) + isDone = Mesh2D.Compute() + smesh.SetName(Mesh2D, 'Maillage_1') + + # tmp_dir = tempfile.mkdtemp() + with tempfile.TemporaryDirectory() as tmp_dir: + mesh_file = path.join(tmp_dir, "mesh.med") + shape_file = path.join(tmp_dir, "shape.step") + param_file = path.join(tmp_dir, "param.txt") + output_mesh = path.join(tmp_dir, "mesh3D.med") + + print("Running in folder: ", tmp_dir) + create_param_file(param_file) + + Mesh2D.ExportMED(mesh_file, 0, 41, 1, Mesh2D, 1, [], '', -1, 1) + geompy.ExportSTEP(box, shape_file, GEOM.LU_METER) + + runner = path.join("${NETGENPLUGIN_ROOT_DIR}", + "bin", + "salome", + "NETGENPlugin_Runner") + + cmd = "{runner} NETGEN3D {mesh_file} {shape_file} "\ + "{param_file} NONE 2 NONE {output_mesh}"\ + .format(runner=runner, + mesh_file=mesh_file, + shape_file=shape_file, + param_file=param_file, + output_mesh=output_mesh) + print(cmd) + subprocess.check_call(cmd, shell=True) + + meshRead = mc.ReadUMeshFromFile (output_mesh, "Maillage_1", 0) + + nbTetras = meshRead.getNumberOfCellsWithType(mc.NORM_TETRA4) + nbPoints = meshRead.getNumberOfNodes() + + meshRead = mc.ReadUMeshFromFile (output_mesh, "Maillage_1", -1) + nbTriangles = meshRead.getNumberOfCellsWithType(mc.NORM_TRI3) + + meshRead = mc.ReadUMeshFromFile (output_mesh, "Maillage_1", -2) + nbSegments = meshRead.getNumberOfCellsWithType(mc.NORM_SEG2) + + print("Nb Tetras:", nbTetras) + print("Nb Triangles:", nbTriangles) + print("Nb Segments:", nbSegments) + print("Nb Points:", nbPoints) + + assert(nbPoints > 0) + assert(nbSegments > 0) + assert(nbTriangles > 0) + assert(nbTetras > 0) + +if __name__ == "__main__": + test_netgen3d() diff --git a/test/tests.set b/test/tests.set index fddb00249..4664c6a51 100644 --- a/test/tests.set +++ b/test/tests.set @@ -63,6 +63,7 @@ SET(BAD_TESTS SMESH_test2.py SMESH_test4.py SMESH_create_dual_mesh_adapt.py + netgen_runner.py ) IF(NOT WIN32) LIST(APPEND BAD_TESTS From e0859e6a658e844cc966ed3e4ef22745f0415869 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Thu, 15 Sep 2022 11:00:41 +0200 Subject: [PATCH 12/29] Mesh object not deleted in Python + deleting temporary folder when destructing SMESH_Mesh --- src/SMESH/SMESH_Mesh.cxx | 3 +++ src/SMESH_SWIG/smeshBuilder.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index 5ca9919ac..a7bd39126 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -240,6 +240,9 @@ SMESH_Mesh::~SMESH_Mesh() pthread_t thread; int result=pthread_create(&thread, NULL, deleteMeshDS, (void*)_meshDS); #endif + + fs::remove_all(tmp_folder); + } } diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index 3fad0860b..25a947352 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -1642,7 +1642,7 @@ class Mesh(metaclass = MeshMeta): Destructor. Clean-up resources """ if self.mesh: - #self.mesh.UnRegister() + self.mesh.UnRegister() pass pass From 78c4fca7f3bd6133ac9a8c41aa5f3f617546b686 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Thu, 15 Sep 2022 15:12:22 +0200 Subject: [PATCH 13/29] Adding support for BRep for shape --- src/SMESH/CMakeLists.txt | 4 +- ...H_DriverStep.cxx => SMESH_DriverShape.cxx} | 129 ++++++++++++------ ...H_DriverStep.hxx => SMESH_DriverShape.hxx} | 8 +- src/SMESH/SMESH_Mesh.cxx | 4 +- 4 files changed, 96 insertions(+), 49 deletions(-) rename src/SMESH/{SMESH_DriverStep.cxx => SMESH_DriverShape.cxx} (54%) rename src/SMESH/{SMESH_DriverStep.hxx => SMESH_DriverShape.hxx} (89%) diff --git a/src/SMESH/CMakeLists.txt b/src/SMESH/CMakeLists.txt index 75c964b99..afe512509 100644 --- a/src/SMESH/CMakeLists.txt +++ b/src/SMESH/CMakeLists.txt @@ -91,7 +91,7 @@ SET(SMESHimpl_HEADERS MG_ADAPT.hxx SMESH_Homard.hxx SMESH_DriverMesh.hxx - SMESH_DriverStep.hxx + SMESH_DriverShape.hxx ) # --- sources --- @@ -113,7 +113,7 @@ SET(SMESHimpl_SOURCES MG_ADAPT.cxx SMESH_Homard.cxx SMESH_DriverMesh.cxx - SMESH_DriverStep.cxx + SMESH_DriverShape.cxx ) # --- rules --- diff --git a/src/SMESH/SMESH_DriverStep.cxx b/src/SMESH/SMESH_DriverShape.cxx similarity index 54% rename from src/SMESH/SMESH_DriverStep.cxx rename to src/SMESH/SMESH_DriverShape.cxx index b19be4891..572da3e1e 100644 --- a/src/SMESH/SMESH_DriverStep.cxx +++ b/src/SMESH/SMESH_DriverShape.cxx @@ -20,54 +20,28 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// File : SMESH_DriverStep.cxx +// File : SMESH_DriverShape.cxx // Author : Yoann AUDOUIN, EDF // Module : SMESH // -#include "SMESH_DriverStep.hxx" +#include "SMESH_DriverShape.hxx" +// step include #include #include #include +// Brep include +#include +#include + //Occ include #include - -/** - * @brief Compares two shape file (STEP) - * - * @param file1 first file - * @param file2 second file - * - * @return true if the files are the same - */ -bool diffStepFile(std::string file1, std::string file2){ - std::ifstream sfile1(file1); - std::ifstream sfile2(file2); - std::string line1, line2; - int nb_lines = 0; - - while(!sfile1.eof() && !sfile2.eof()){ - std::getline(sfile1, line1); - std::getline(sfile2, line2); - nb_lines++; - // Skipping 4th line contain date of creation - if (nb_lines==4){ - std::cout << "Skipping line" << std::endl; - continue; - } - - // if lines are different end of read - if(line1 != line2){ - return false; - } - - } - // True if we reached the end of both files - return sfile1.eof() && sfile2.eof(); -} +#include +#include +namespace fs = boost::filesystem; /** * @brief Import the content of a shape file (STEP) into a TopDS_Shape object @@ -77,9 +51,9 @@ bool diffStepFile(std::string file1, std::string file2){ * * @return error code */ -int importShape(const std::string shape_file, TopoDS_Shape& aShape){ +int importSTEPShape(const std::string shape_file, TopoDS_Shape& aShape){ - std::cout << "Importing shape from " << shape_file << std::endl; + std::cout << "Importing STEP shape from " << shape_file << std::endl; STEPControl_Reader reader; // Forcing Unit in meter Interface_Static::SetCVal("xstep.cascade.unit","M"); @@ -105,9 +79,9 @@ int importShape(const std::string shape_file, TopoDS_Shape& aShape){ * * @return error code */ -int exportShape(const std::string shape_file, const TopoDS_Shape& aShape){ +int exportSTEPShape(const std::string shape_file, const TopoDS_Shape& aShape){ - std::cout << "Exporting shape to " << shape_file << std::endl; + std::cout << "Exporting STEP shape to " << shape_file << std::endl; STEPControl_Writer aWriter; // Forcing Unit in meter @@ -126,3 +100,78 @@ int exportShape(const std::string shape_file, const TopoDS_Shape& aShape){ return aStat; } + +/** + * @brief Import the content of a shape file (BREP) into a TopDS_Shape object + * + * @param shape_file the shape file + * @param aShape the object + * + * @return error code + */ +int importBREPShape(const std::string shape_file, TopoDS_Shape& aShape){ + + std::cout << "Importing BREP shape from " << shape_file << std::endl; + BRep_Builder builder; + BRepTools::Read(aShape, shape_file.c_str(), builder); + + return true; +} + +/** + * @brief Export the content of a TopoDS_Shape into a shape file (BREP) + * + * @param shape_file the shape file + * @param aShape the object + * + * @return error code + */ +int exportBREPShape(const std::string shape_file, const TopoDS_Shape& aShape){ + + std::cout << "Exporting BREP shape to " << shape_file << std::endl; + BRepTools::Write(aShape, shape_file.c_str()); + + return true; +} + +/** + * @brief Import the content of a shape file into a TopDS_Shape object + * + * @param shape_file the shape file + * @param aShape the object + * + * @return error code + */ +int importShape(const std::string shape_file, TopoDS_Shape& aShape){ + std::string type = fs::path(shape_file).extension().string(); + boost::algorithm::to_lower(type); + if (type == ".brep"){ + return importBREPShape(shape_file, aShape); + } else if (type == ".step"){ + return importSTEPShape(shape_file, aShape); + } else { + std::cout << "Unknow format: " << type << std::endl; + return false; + } +} + +/** + * @brief Import the content of a shape file into a TopDS_Shape object + * + * @param shape_file the shape file + * @param aShape the object + * + * @return error code + */ +int exportShape(const std::string shape_file, const TopoDS_Shape& aShape){ + std::string type = fs::path(shape_file).extension().string(); + boost::algorithm::to_lower(type); + if (type == ".brep"){ + return exportBREPShape(shape_file, aShape); + } else if (type == ".step"){ + return exportSTEPShape(shape_file, aShape); + } else { + std::cout << "Unknow format: " << type << std::endl; + return false; + } +} diff --git a/src/SMESH/SMESH_DriverStep.hxx b/src/SMESH/SMESH_DriverShape.hxx similarity index 89% rename from src/SMESH/SMESH_DriverStep.hxx rename to src/SMESH/SMESH_DriverShape.hxx index 18158ae49..b9e3a360e 100644 --- a/src/SMESH/SMESH_DriverStep.hxx +++ b/src/SMESH/SMESH_DriverShape.hxx @@ -20,13 +20,13 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// File : SMESH_DriverStep.hxx +// File : SMESH_DriverShape.hxx // Author : Yoann AUDOUIN, EDF // Module : SMESH // -#ifndef _SMESH_DRIVERSTEP_HXX_ -#define _SMESH_DRIVERSTEP_HXX_ +#ifndef _SMESH_DRIVERSHAPE_HXX_ +#define _SMESH_DRIVERSHAPE_HXX_ #include #include @@ -35,7 +35,5 @@ class TopoDS_Shape; int importShape(const std::string shape_file, TopoDS_Shape& aShape); int exportShape(const std::string shape_file, const TopoDS_Shape& aShape); -bool diffStepFile(std::string file1, std::string file2); - #endif \ No newline at end of file diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index a7bd39126..a3602c1ad 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -87,7 +87,7 @@ namespace fs=boost::filesystem; #define MAX_MED_GROUP_NAME_LENGTH 80 #ifdef _DEBUG_ -static int MYDEBUG = 0; +static int MYDEBUG = 1; #else static int MYDEBUG = 0; #endif @@ -241,7 +241,7 @@ SMESH_Mesh::~SMESH_Mesh() int result=pthread_create(&thread, NULL, deleteMeshDS, (void*)_meshDS); #endif - fs::remove_all(tmp_folder); + //fs::remove_all(tmp_folder); } } From b58c9632e3158d6cdbf2374324f84c3b959544e8 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Mon, 19 Sep 2022 11:22:01 +0200 Subject: [PATCH 14/29] Removing todo --- src/SMESH/SMESH_Gen.cxx | 1 - src/SMESH/SMESH_subMesh.cxx | 1 - 2 files changed, 2 deletions(-) diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index e2d908f1f..556ef145e 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -191,7 +191,6 @@ const std::functionSetAllowedSubShapes( nullptr ); } - // TODO: Check if this is necessary if ( aShapesId ) aShapesId->insert( sm->GetId() ); diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index 4edd75cd5..9c30aa811 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -1579,7 +1579,6 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) } else { - // TODO: Do switch of compute here instead of within algo ret = algo->Compute((*_father), shape); } // algo can set _computeError of submesh From 45f8178054cb45849293af9165943dd41c2ddbc8 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Wed, 21 Sep 2022 15:26:21 +0200 Subject: [PATCH 15/29] Adaptation to NETGEN_Remote --- src/SMESH/SMESH_subMesh.cxx | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index 9c30aa811..b28d44b4e 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -1507,10 +1507,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) { algo = GetAlgo(); ASSERT(algo); - if(!_father->IsParallel()) - ret = algo->CheckHypothesis((*_father), _subShape, hyp_status); - else - ret = true; + ret = algo->CheckHypothesis((*_father), _subShape, hyp_status); if (!ret) { MESSAGE("***** verify compute state *****"); @@ -1519,8 +1516,9 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) break; } TopoDS_Shape shape = _subShape; - if(!_father->IsParallel()) - algo->SubMeshesToCompute().assign( 1, this ); + _father->Lock(); + algo->SubMeshesToCompute().assign( 1, this ); + _father->Unlock(); // check submeshes needed // In parallel there would be no submesh to check if (_father->HasShapeToMesh() && !_father->IsParallel()) { @@ -1741,8 +1739,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) updateDependantsState( SUBMESH_COMPUTED ); } // let algo clear its data gathered while algo->Compute() - if(!_father->IsParallel()) - algo->CheckHypothesis((*_father), _subShape, hyp_status); + algo->CheckHypothesis((*_father), _subShape, hyp_status); } break; case COMPUTE_CANCELED: // nothing to do From cc3662690d9346243c4919cf0e9a9a9b39b6381e Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Wed, 21 Sep 2022 15:26:33 +0200 Subject: [PATCH 16/29] Removing hard coded meshname from Mesh import --- src/SMESH/SMESH_DriverMesh.cxx | 11 +++++++++-- src/SMESH/SMESH_DriverMesh.hxx | 3 +-- src/SMESH/SMESH_Gen.cxx | 3 +-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/SMESH/SMESH_DriverMesh.cxx b/src/SMESH/SMESH_DriverMesh.cxx index 2c01523d4..470278e93 100644 --- a/src/SMESH/SMESH_DriverMesh.cxx +++ b/src/SMESH/SMESH_DriverMesh.cxx @@ -52,6 +52,12 @@ bool diffMEDFile(const std::string mesh_file1, const std::string mesh_file2, con return m0_1->isEqual(m0_2, 1e-12); } +std::string getMeshName(std::string mesh_file){ + std::unique_ptr myMedMesh=MEDFileUMesh::New(mesh_file); + + return myMedMesh->getLevel0Mesh()->getName(); +} + /** * @brief Import a mesh from a mesh file (MED) into a SMESH_Mesh object * @@ -61,9 +67,10 @@ bool diffMEDFile(const std::string mesh_file1, const std::string mesh_file2, con * * @return error code */ -int importMesh(const std::string mesh_file, SMESH_Mesh& aMesh, const std::string mesh_name){ +int importMesh(const std::string mesh_file, SMESH_Mesh& aMesh){ // TODO: change that as it depends on the language - std::cout << "Importing mesh from " << mesh_file << std::endl; + std::string mesh_name = getMeshName(mesh_file); + std::cout << "Importing mesh from " << mesh_file << " mesh " << mesh_name2 << std::endl; int ret = aMesh.MEDToMesh(mesh_file.c_str(), mesh_name.c_str()); return ret; } diff --git a/src/SMESH/SMESH_DriverMesh.hxx b/src/SMESH/SMESH_DriverMesh.hxx index eaf2ed18b..370f99515 100644 --- a/src/SMESH/SMESH_DriverMesh.hxx +++ b/src/SMESH/SMESH_DriverMesh.hxx @@ -37,8 +37,7 @@ bool diffMEDFile(const std::string mesh_file1, const std::string mesh_file2, const std::string mesh_name); int importMesh(const std::string mesh_file, - SMESH_Mesh& aMesh, - const std::string meshName); + SMESH_Mesh& aMesh); int exportMesh(const std::string mesh_file, SMESH_Mesh& aMesh, const std::string meshName); diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index 556ef145e..4aae8db4e 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -291,8 +291,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, if(file_name != "") { fs::path mesh_file = fs::path(aMesh.tmp_folder) / fs::path(file_name); - // TODO: change mesh name - exportMesh(mesh_file.string(), aMesh, "Maillage_1"); + exportMesh(mesh_file.string(), aMesh, "MESH"); } //Resetting threaded pool info From ee7ca3d826183e462048423d2416e96872d06620 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Wed, 21 Sep 2022 15:26:59 +0200 Subject: [PATCH 17/29] Restoring Regular 1D --- src/StdMeshers/StdMeshers_Regular_1D.cxx | 48 +++++------------------- 1 file changed, 10 insertions(+), 38 deletions(-) diff --git a/src/StdMeshers/StdMeshers_Regular_1D.cxx b/src/StdMeshers/StdMeshers_Regular_1D.cxx index 625ecdceb..886f72b63 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.cxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.cxx @@ -126,22 +126,14 @@ bool StdMeshers_Regular_1D::CheckHypothesis( SMESH_Mesh& aMesh, _onlyUnaryInput = true; // check propagation in a redefined GetUsedHypothesis() - const list hyps = + const list & hyps = GetUsedHypothesis(aMesh, aShape, /*ignoreAuxiliaryHyps=*/false); + const SMESH_HypoFilter & propagFilter = StdMeshers_Propagation::GetFilter(); // find non-auxiliary hypothesis const SMESHDS_Hypothesis *theHyp = 0; set< string > propagTypes; - //std::cout << "For shape " << aShape.HashCode(1) << " of type "<< aShape.ShapeType() << - // "CheckHypothesis" << std::endl; - // for(auto hyp:hyps){ - // SMESH_Comment hypStr; - // hypStr << hyp << " " << hyp->GetName() << " "; - // ((SMESHDS_Hypothesis*)hyp)->SaveTo( hypStr.Stream() ); - // hypStr << " "; - // std::cout << hypStr << std::endl; - // } list ::const_iterator h = hyps.begin(); for ( ; h != hyps.end(); ++h ) { if ( static_cast(*h)->IsAuxiliary() ) { @@ -856,12 +848,8 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh, { // Number Of Segments hypothesis nbSegments = _ivalue[ NB_SEGMENTS_IND ]; - if ( nbSegments < 1 ) { - return false; - } - if ( nbSegments == 1 ) { - return true; - } + if ( nbSegments < 1 ) return false; + if ( nbSegments == 1 ) return true; switch (_ivalue[ DISTR_TYPE_IND ]) { @@ -1182,16 +1170,10 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh, bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & theShape) { - SMESH_Hypothesis::Hypothesis_Status hyp_status; - theMesh.Lock(); - bool ret = this->CheckHypothesis(theMesh, theShape, hyp_status); - int hypType = _hypType; - theMesh.Unlock(); + if ( _hypType == NONE ) + return false; - if ( hypType == NONE ) - return false; - - if ( hypType == ADAPTIVE ) + if ( _hypType == ADAPTIVE ) { _adaptiveHyp->GetAlgo()->InitComputeError(); _adaptiveHyp->GetAlgo()->Compute( theMesh, theShape ); @@ -1200,8 +1182,6 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t SMESHDS_Mesh * meshDS = theMesh.GetMeshDS(); - theMesh.Lock(); - const TopoDS_Edge & EE = TopoDS::Edge(theShape); TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD)); int shapeID = meshDS->ShapeToIndex( E ); @@ -1216,11 +1196,9 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t ASSERT(!VLast.IsNull()); const SMDS_MeshNode * nFirst = SMESH_Algo::VertexNode( VFirst, meshDS ); const SMDS_MeshNode * nLast = SMESH_Algo::VertexNode( VLast, meshDS ); - if ( !nFirst || !nLast ){ - theMesh.Unlock(); - //std::cout << "exit no node" << std::endl; + if ( !nFirst || !nLast ) return error( COMPERR_BAD_INPUT_MESH, "No node on vertex"); - } + // remove elements created by e.g. pattern mapping (PAL21999) // CLEAN event is incorrectly ptopagated seemingly due to Propagation hyp // so TEMPORARY solution is to clean the submesh manually @@ -1252,7 +1230,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t // take into account reversing the edge the hypothesis is propagated from // (_mainEdge.Orientation() marks mutual orientation of EDGEs in propagation chain) reversed = ( _mainEdge.Orientation() == TopAbs_REVERSED ); - if ( hypType != DISTRIB_PROPAGATION ) { + if ( _hypType != DISTRIB_PROPAGATION ) { int mainID = meshDS->ShapeToIndex(_mainEdge); if ( std::find( _revEdgesIDs.begin(), _revEdgesIDs.end(), mainID) != _revEdgesIDs.end()) reversed = !reversed; @@ -1264,9 +1242,6 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t BRepAdaptor_Curve C3d( E ); if ( ! computeInternalParameters( theMesh, C3d, length, f, l, params, reversed, true )) { - theMesh.Unlock(); - //std::cout << "exit Compute internal failed" << std::endl; - return false; } redistributeNearVertices( theMesh, C3d, length, params, VFirst, VLast ); @@ -1357,9 +1332,6 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t meshDS->SetMeshElementOnShape(edge, shapeID); } } - theMesh.Unlock(); - //std::cout << "exit normal" << std::endl; - return true; } From a91b37ceb38f808da171e83d0d6a7a4c2b4bb050 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Wed, 21 Sep 2022 16:35:15 +0200 Subject: [PATCH 18/29] Clean up of cout replaced by MESSAGE + minor corrections --- src/SMESH/SMESH_DriverMesh.cxx | 10 ++-- src/SMESH/SMESH_DriverShape.cxx | 42 ++++++++------- src/SMESH/SMESH_Gen.cxx | 22 +------- src/SMESH/SMESH_Mesh.cxx | 16 +++--- src/SMESH/SMESH_MesherHelper.cxx | 89 +++++++++++++++----------------- src/SMESH/SMESH_subMesh.cxx | 2 +- src/SMESH_I/SMESH_Gen_i.cxx | 4 +- 7 files changed, 82 insertions(+), 103 deletions(-) diff --git a/src/SMESH/SMESH_DriverMesh.cxx b/src/SMESH/SMESH_DriverMesh.cxx index 470278e93..a47289535 100644 --- a/src/SMESH/SMESH_DriverMesh.cxx +++ b/src/SMESH/SMESH_DriverMesh.cxx @@ -25,6 +25,8 @@ // Module : SMESH // +#include "utilities.h" + #include "SMESH_DriverMesh.hxx" #include "SMESH_Mesh.hxx" @@ -53,7 +55,8 @@ bool diffMEDFile(const std::string mesh_file1, const std::string mesh_file2, con } std::string getMeshName(std::string mesh_file){ - std::unique_ptr myMedMesh=MEDFileUMesh::New(mesh_file); + // TODO: Memory leak but desctructor private check with AG + MEDFileUMesh * myMedMesh = MEDFileUMesh::New(mesh_file); return myMedMesh->getLevel0Mesh()->getName(); } @@ -70,7 +73,7 @@ std::string getMeshName(std::string mesh_file){ int importMesh(const std::string mesh_file, SMESH_Mesh& aMesh){ // TODO: change that as it depends on the language std::string mesh_name = getMeshName(mesh_file); - std::cout << "Importing mesh from " << mesh_file << " mesh " << mesh_name2 << std::endl; + MESSAGE("Importing mesh from " << mesh_file << " mesh " << mesh_name); int ret = aMesh.MEDToMesh(mesh_file.c_str(), mesh_name.c_str()); return ret; } @@ -86,8 +89,7 @@ int importMesh(const std::string mesh_file, SMESH_Mesh& aMesh){ */ int exportMesh(const std::string mesh_file, SMESH_Mesh& aMesh, const std::string mesh_name){ - // TODO: See how to get the name of the mesh. Is it usefull ? - std::cout << "Exporting mesh to " << mesh_file << std::endl; + MESSAGE("Exporting mesh to " << mesh_file); aMesh.ExportMED(mesh_file.c_str(), // theFile mesh_name.c_str(), // theMeshName false, // theAutoGroups diff --git a/src/SMESH/SMESH_DriverShape.cxx b/src/SMESH/SMESH_DriverShape.cxx index 572da3e1e..d8cf96473 100644 --- a/src/SMESH/SMESH_DriverShape.cxx +++ b/src/SMESH/SMESH_DriverShape.cxx @@ -25,6 +25,7 @@ // Module : SMESH // +#include #include "SMESH_DriverShape.hxx" // step include @@ -53,22 +54,24 @@ namespace fs = boost::filesystem; */ int importSTEPShape(const std::string shape_file, TopoDS_Shape& aShape){ - std::cout << "Importing STEP shape from " << shape_file << std::endl; + MESSAGE("Importing STEP shape from " << shape_file); STEPControl_Reader reader; // Forcing Unit in meter Interface_Static::SetCVal("xstep.cascade.unit","M"); Interface_Static::SetIVal("read.step.ideas", 1); Interface_Static::SetIVal("read.step.nonmanifold", 1); IFSelect_ReturnStatus aStat = reader.ReadFile(shape_file.c_str()); - if(aStat != IFSelect_RetDone) - std::cout << "Reading error for " << shape_file << std::endl; + if(aStat != IFSelect_RetDone){ + std::cerr << "Reading error for " << shape_file << std::endl; + return true; + } int NbTrans = reader.TransferRoots(); // There should be only one shape within the file assert(NbTrans==1); aShape = reader.OneShape(); - return true; + return false; } /** @@ -81,7 +84,7 @@ int importSTEPShape(const std::string shape_file, TopoDS_Shape& aShape){ */ int exportSTEPShape(const std::string shape_file, const TopoDS_Shape& aShape){ - std::cout << "Exporting STEP shape to " << shape_file << std::endl; + MESSAGE("Exporting STEP shape to " << shape_file); STEPControl_Writer aWriter; // Forcing Unit in meter @@ -90,14 +93,17 @@ int exportSTEPShape(const std::string shape_file, const TopoDS_Shape& aShape){ Interface_Static::SetIVal("write.step.nonmanifold", 1); IFSelect_ReturnStatus aStat = aWriter.Transfer(aShape,STEPControl_AsIs); - if(aStat != IFSelect_RetDone) - std::cout << "Transfer error for " << shape_file << std::endl; + if(aStat != IFSelect_RetDone){ + std::cerr << "Transfer error for " << shape_file << std::endl; + return true; + } aStat = aWriter.Write(shape_file.c_str()); - if(aStat != IFSelect_RetDone) - std::cout << "Writing error for " << shape_file << std::endl; - + if(aStat != IFSelect_RetDone){ + std::cerr << "Writing error for " << shape_file << std::endl; + return true; + } return aStat; } @@ -111,11 +117,11 @@ int exportSTEPShape(const std::string shape_file, const TopoDS_Shape& aShape){ */ int importBREPShape(const std::string shape_file, TopoDS_Shape& aShape){ - std::cout << "Importing BREP shape from " << shape_file << std::endl; + MESSAGE("Importing BREP shape from " << shape_file); BRep_Builder builder; BRepTools::Read(aShape, shape_file.c_str(), builder); - return true; + return false; } /** @@ -128,10 +134,10 @@ int importBREPShape(const std::string shape_file, TopoDS_Shape& aShape){ */ int exportBREPShape(const std::string shape_file, const TopoDS_Shape& aShape){ - std::cout << "Exporting BREP shape to " << shape_file << std::endl; + MESSAGE("Exporting BREP shape to " << shape_file); BRepTools::Write(aShape, shape_file.c_str()); - return true; + return false; } /** @@ -150,8 +156,8 @@ int importShape(const std::string shape_file, TopoDS_Shape& aShape){ } else if (type == ".step"){ return importSTEPShape(shape_file, aShape); } else { - std::cout << "Unknow format: " << type << std::endl; - return false; + std::cerr << "Unknow format: " << type << std::endl; + return true; } } @@ -171,7 +177,7 @@ int exportShape(const std::string shape_file, const TopoDS_Shape& aShape){ } else if (type == ".step"){ return exportSTEPShape(shape_file, aShape); } else { - std::cout << "Unknow format: " << type << std::endl; - return false; + std::cerr << "Unknow format: " << type << std::endl; + return true; } } diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index 4aae8db4e..f61acd5f9 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -48,7 +48,6 @@ #include #include "memoire.h" -#include #include #ifdef WIN32 @@ -249,8 +248,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, TopAbs_ShapeEnum previousShapeType = TopAbs_VERTEX; int nbThreads = aMesh.GetNbThreads(); - auto begin = std::chrono::high_resolution_clock::now(); - std::cout << "Running mesh with threads: " << nbThreads << " mesher: " << aMesh.GetMesherNbThreads() << std::endl; + MESSAGE("Running mesh with threads: " << nbThreads << " mesher: " << aMesh.GetMesherNbThreads()); smIt = shapeSM->getDependsOnIterator(includeSelf, !complexShapeFirst); @@ -267,7 +265,6 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, aMesh.SetNbThreads(0); else aMesh.SetNbThreads(nbThreads); - //DEBUG std::cout << "Shape Type" << shapeType << " previous" << previousShapeType << std::endl; if ((aMesh.IsParallel()||nbThreads!=0) && shapeType != previousShapeType) { // Waiting for all threads for the previous type to end aMesh.wait(); @@ -312,8 +309,6 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, shapeSM, aShapeOnly, allowedSubShapes, aShapesId)); } else { - auto begin2 = std::chrono::high_resolution_clock::now(); - compute_function(1 ,smToCompute, computeEvent, shapeSM, aShapeOnly, allowedSubShapes, aShapesId); @@ -333,13 +328,6 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, } aMesh.GetMeshDS()->Modified(); - auto end = std::chrono::high_resolution_clock::now(); - auto elapsed = std::chrono::duration_cast(end - begin); - std::cout << "Time for All: " << elapsed.count()*1e-9 << std::endl; - - // Pool of thread for computation - if(aMesh.IsParallel()) - aMesh.DeletePoolThreads(); return ret; } @@ -351,7 +339,6 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, // the most complex shapes and collect sub-meshes with algos that // DO support sub-meshes // ================================================================ - auto begin = std::chrono::high_resolution_clock::now(); list< SMESH_subMesh* > smWithAlgoSupportingSubmeshes[4]; // for each dim // map to sort sm with same dim algos according to dim of @@ -547,11 +534,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, continue; sm->SetAllowedSubShapes( fillAllowed( shapeSM, aShapeOnly, allowedSubShapes )); setCurrentSubMesh( sm ); - auto begin = std::chrono::high_resolution_clock::now(); sm->ComputeStateEngine( computeEvent ); - auto end = std::chrono::high_resolution_clock::now(); - auto elapsed = std::chrono::duration_cast(end - begin); - std::cout << "Time for seq:alldim:compute: " << elapsed.count()*1e-9 << std::endl; setCurrentSubMesh( NULL ); sm->SetAllowedSubShapes( nullptr ); @@ -565,9 +548,6 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, // mesh the rest sub-shapes starting from vertices // ----------------------------------------------- ret = Compute( aMesh, aShape, aFlags | UPWARD, aDim, aShapesId, allowedSubShapes ); - auto end = std::chrono::high_resolution_clock::now(); - auto elapsed = std::chrono::duration_cast(end - begin); - std::cout << "Time for All: " << elapsed.count()*1e-9 << std::endl; } diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index a3602c1ad..3eb08a85c 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -174,13 +174,11 @@ namespace #ifndef WIN32 void deleteMeshDS(SMESHDS_Mesh* meshDS) { - //cout << "deleteMeshDS( " << meshDS << endl; delete meshDS; } #else static void* deleteMeshDS(void* meshDS) { - //cout << "deleteMeshDS( " << meshDS << endl; SMESHDS_Mesh* m = (SMESHDS_Mesh*)meshDS; if(m) { delete m; @@ -240,10 +238,12 @@ SMESH_Mesh::~SMESH_Mesh() pthread_t thread; int result=pthread_create(&thread, NULL, deleteMeshDS, (void*)_meshDS); #endif - - //fs::remove_all(tmp_folder); - } + + if(_pool) + DeletePoolThreads(); + if (!MYDEBUG) + fs::remove_all(tmp_folder); } //================================================================================ @@ -541,7 +541,7 @@ int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName) Driver_Mesh::Status status = myReader.Perform(); #ifdef _DEBUG_ SMESH_ComputeErrorPtr er = myReader.GetError(); - if ( er && !er->IsOK() ) std::cout << er->myComment << std::endl; + if ( er && !er->IsOK() ) MESSAGE(er->myComment); #endif // Reading groups (sub-meshes are out of scope of MED import functionality) @@ -1770,7 +1770,6 @@ double SMESH_Mesh::GetComputeProgress() const rate = algo->GetProgressByTic(); computedCost += algoDoneCost + rate * algoNotDoneCost; } - // cout << "rate: "<GetMeshInfo().NbElements() << endl; return computedCost / totalCost; } diff --git a/src/SMESH/SMESH_MesherHelper.cxx b/src/SMESH/SMESH_MesherHelper.cxx index 28ef9ae55..f92de2bed 100644 --- a/src/SMESH/SMESH_MesherHelper.cxx +++ b/src/SMESH/SMESH_MesherHelper.cxx @@ -28,7 +28,7 @@ #include "SMDS_EdgePosition.hxx" #include "SMDS_FaceOfNodes.hxx" -#include "SMDS_FacePosition.hxx" +#include "SMDS_FacePosition.hxx" #include "SMDS_IteratorOnIterators.hxx" #include "SMDS_VolumeTool.hxx" #include "SMESHDS_Mesh.hxx" @@ -100,7 +100,7 @@ SMESH_MesherHelper::SMESH_MesherHelper(SMESH_Mesh& theMesh) //======================================================================= //function : ~SMESH_MesherHelper -//purpose : +//purpose : //======================================================================= SMESH_MesherHelper::~SMESH_MesherHelper() @@ -425,7 +425,7 @@ bool SMESH_MesherHelper::GetNodeUVneedInFaceNode(const TopoDS_Face& F) const //======================================================================= //function : IsMedium -//purpose : +//purpose : //======================================================================= bool SMESH_MesherHelper::IsMedium(const SMDS_MeshNode* node, @@ -583,7 +583,7 @@ bool SMESH_MesherHelper::toCheckPosOnShape(int shapeID ) const void SMESH_MesherHelper::setPosOnShapeValidity(int shapeID, bool ok ) const { - std::map< int,bool >::iterator sh_ok = + std::map< int,bool >::iterator sh_ok = ((SMESH_MesherHelper*)this)->myNodePosShapesValidity.insert( make_pair( shapeID, ok)).first; if ( !ok ) sh_ok->second = ok; @@ -591,7 +591,7 @@ void SMESH_MesherHelper::setPosOnShapeValidity(int shapeID, bool ok ) const //======================================================================= //function : ToFixNodeParameters -//purpose : Enables fixing node parameters on EDGEs and FACEs in +//purpose : Enables fixing node parameters on EDGEs and FACEs in // GetNodeU(...,check=true), GetNodeUV(...,check=true), CheckNodeUV() and // CheckNodeU() in case if a node lies on a shape set via SetSubShape(). // Default is False @@ -943,7 +943,7 @@ namespace { gp_XY AverageUV(const gp_XY& uv1, const gp_XY& uv2) { return ( uv1 + uv2 ) / 2.; } gp_XY_FunPtr(Added); // define gp_XY_Added pointer to function calling gp_XY::Added(gp_XY) - gp_XY_FunPtr(Subtracted); + gp_XY_FunPtr(Subtracted); } //======================================================================= @@ -967,9 +967,9 @@ gp_XY SMESH_MesherHelper::ApplyIn2D(Handle(Geom_Surface) surface, return fun(uv1,uv2); // move uv2 not far than half-period from uv1 - double u2 = + double u2 = uv2.X()+(isUPeriodic ? ShapeAnalysis::AdjustByPeriod(uv2.X(),uv1.X(),surface->UPeriod()) :0); - double v2 = + double v2 = uv2.Y()+(isVPeriodic ? ShapeAnalysis::AdjustByPeriod(uv2.Y(),uv1.Y(),surface->VPeriod()) :0); // execute operation @@ -1038,8 +1038,8 @@ gp_XY SMESH_MesherHelper::GetMiddleUV(const Handle(Geom_Surface)& surface, //======================================================================= gp_XY SMESH_MesherHelper::GetCenterUV(const gp_XY& uv1, - const gp_XY& uv2, - const gp_XY& uv3, + const gp_XY& uv2, + const gp_XY& uv3, const gp_XY& uv12, const gp_XY& uv23, const gp_XY& uv31, @@ -1370,7 +1370,7 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetCentralNode(const SMDS_MeshNode* n1, TBiQuad keyOfMap(n1,n2,n3,n4); std::map::iterator itMapCentralNode; itMapCentralNode = myMapWithCentralNode.find( keyOfMap ); - if ( itMapCentralNode != myMapWithCentralNode.end() ) + if ( itMapCentralNode != myMapWithCentralNode.end() ) { return (*itMapCentralNode).second; } @@ -1385,9 +1385,9 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetCentralNode(const SMDS_MeshNode* n1, std::map< int, int > faceId2nbNodes; std::map< int, int > ::iterator itMapWithIdFace; - + SMESHDS_Mesh* meshDS = GetMeshDS(); - + // check if a face lies on a FACE, i.e. its all corner nodes lie either on the FACE or // on sub-shapes of the FACE if ( GetMesh()->HasShapeToMesh() ) @@ -1545,7 +1545,7 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetCentralNode(const SMDS_MeshNode* n1, TBiQuad keyOfMap(n1,n2,n3); std::map::iterator itMapCentralNode; itMapCentralNode = myMapWithCentralNode.find( keyOfMap ); - if ( itMapCentralNode != myMapWithCentralNode.end() ) + if ( itMapCentralNode != myMapWithCentralNode.end() ) { return (*itMapCentralNode).second; } @@ -1560,9 +1560,9 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetCentralNode(const SMDS_MeshNode* n1, std::map< int, int > faceId2nbNodes; std::map< int, int > ::iterator itMapWithIdFace; - + SMESHDS_Mesh* meshDS = GetMeshDS(); - + // check if a face lies on a FACE, i.e. its all corner nodes lie either on the FACE or // on sub-shapes of the FACE if ( GetMesh()->HasShapeToMesh() ) @@ -2004,7 +2004,7 @@ SMDS_MeshEdge* SMESH_MesherHelper::AddEdge(const SMDS_MeshNode* n1, const bool force3d) { SMESHDS_Mesh * meshDS = GetMeshDS(); - + SMDS_MeshEdge* edge = 0; if (myCreateQuadratic) { const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d); @@ -2467,7 +2467,7 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1, const SMDS_MeshNode* n10, const SMDS_MeshNode* n11, const SMDS_MeshNode* n12, - const smIdType id, + const smIdType id, bool /*force3d*/) { SMESHDS_Mesh * meshDS = GetMeshDS(); @@ -3206,7 +3206,7 @@ bool SMESH_MesherHelper::IsSubShape( const TopoDS_Shape& shape, //======================================================================= //function : IsSubShape -//purpose : +//purpose : //======================================================================= bool SMESH_MesherHelper::IsSubShape( const TopoDS_Shape& shape, SMESH_Mesh* aMesh ) @@ -3221,7 +3221,7 @@ bool SMESH_MesherHelper::IsSubShape( const TopoDS_Shape& shape, SMESH_Mesh* aMes //======================================================================= //function : IsBlock -//purpose : +//purpose : //======================================================================= bool SMESH_MesherHelper::IsBlock( const TopoDS_Shape& shape ) @@ -3324,7 +3324,7 @@ double SMESH_MesherHelper::GetAngle( const TopoDS_Edge & theE1, if ( ++nbLoops > 10 ) { #ifdef _DEBUG_ - cout << "SMESH_MesherHelper::GetAngle(): Captured in a sigularity" << endl; + MESSAGE("SMESH_MesherHelper::GetAngle(): Captured in a singularity"); #endif return angle; } @@ -3404,7 +3404,7 @@ TopoDS_Vertex SMESH_MesherHelper::IthVertex( const bool is2nd, //================================================================================ /*! - * \brief Return type of shape contained in a group + * \brief Return type of shape contained in a group * \param group - a shape of type TopAbs_COMPOUND * \param avoidCompound - not to return TopAbs_COMPOUND */ @@ -3464,13 +3464,13 @@ SMESH_MesherHelper:: MType SMESH_MesherHelper::IsQuadraticMesh() NbAllEdgsAndFaces = myMesh->NbEdges() + myMesh->NbFaces(); if ( NbAllEdgsAndFaces == 0 ) return SMESH_MesherHelper::LINEAR; - + //Quadratic faces and edges NbQuadFacesAndEdgs = myMesh->NbEdges(ORDER_QUADRATIC) + myMesh->NbFaces(ORDER_QUADRATIC); //Linear faces and edges NbFacesAndEdges = myMesh->NbEdges(ORDER_LINEAR) + myMesh->NbFaces(ORDER_LINEAR); - + if (NbAllEdgsAndFaces == NbQuadFacesAndEdgs) { //Quadratic mesh return SMESH_MesherHelper::QUADRATIC; @@ -4120,7 +4120,7 @@ namespace { // Structures used by FixQuadraticElements() } } else if ( _sides.size() < 4 ) - return thePrevLen; + return thePrevLen; // propagate to adjacent faces till limit step or boundary double len1 = thePrevLen + (theLink->MiddlePnt() - _sides[iL1]->MiddlePnt()).Modulus(); @@ -4210,7 +4210,7 @@ namespace { // Structures used by FixQuadraticElements() void QLink::SetContinuesFaces() const { // x0 x - QLink, [-|] - QFace, v - volume - // v0 | v1 + // v0 | v1 // | Between _faces of link x2 two vertical faces are continues // x1----x2-----x3 and two horizontal faces are continues. We set vertical faces // | to _faces[0] and _faces[1] and horizontal faces to @@ -4317,7 +4317,7 @@ namespace { // Structures used by FixQuadraticElements() } return isStraight; } - + //================================================================================ /*! * \brief Move medium nodes of vertical links of pentahedrons adjacent by side faces @@ -4446,13 +4446,13 @@ namespace { // Structures used by FixQuadraticElements() while ( startLink != linksEnd) // loop on columns { // We suppose we have a rectangular structure like shown here. We have found a - // corner of the rectangle (startCorner) and a boundary link sharing - // |/ |/ | the startCorner (startLink). We are going to loop on rows of the - // --o---o---o structure making several chains at once. One chain (columnChain) - // |\ | /| starts at startLink and continues upward (we look at the structure - // \ | \ | / | from such point that startLink is on the bottom of the structure). - // \| \|/ | While going upward we also fill horizontal chains (rowChains) we - // --o---o---o encounter. + // corner of the rectangle (startCorner) and a boundary link sharing + // |/ |/ | the startCorner (startLink). We are going to loop on rows of the + // --o---o---o structure making several chains at once. One chain (columnChain) + // |\ | /| starts at startLink and continues upward (we look at the structure + // \ | \ | / | from such point that startLink is on the bottom of the structure). + // \| \|/ | While going upward we also fill horizontal chains (rowChains) we + // --o---o---o encounter. // /|\ |\ | // / | \ | \ | startCorner // | \| \|,' @@ -4715,7 +4715,7 @@ namespace { // Structures used by FixQuadraticElements() continue; gp_XYZ edgeDir = SMESH_TNodeXYZ( nOnEdge[0] ) - SMESH_TNodeXYZ( nOnEdge[1] ); gp_XYZ edgeNorm = faceNorm ^ edgeDir; - n = theHelper.GetMediumNode( nOnEdge[0], nOnEdge[1], true ); // find n, not create + n = theHelper.GetMediumNode( nOnEdge[0], nOnEdge[1], true ); // find n, not create gp_XYZ pN0 = SMESH_TNodeXYZ( nOnEdge[0] ); gp_XYZ pMedium = SMESH_TNodeXYZ( n ); // on-edge node location gp_XYZ pFaceN = SMESH_TNodeXYZ( nOnFace ); // on-face node location @@ -5440,7 +5440,7 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError, { uv[ i ] = GetNodeUV( F, nodes[i], nodes[8], &checkUV ); // as this method is used after mesh generation, UV of nodes is not - // updated according to bending links, so we update + // updated according to bending links, so we update if ( i > 3 && nodes[i]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) CheckNodeUV( F, nodes[i], uv[ i ], 2*tol, /*force=*/true ); } @@ -5475,7 +5475,7 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError, { uv[ i ] = GetNodeUV( F, nodes[i], nodes[(i+1)%3], &uvOK ); // as this method is used after mesh generation, UV of nodes is not - // updated according to bending links, so we update + // updated according to bending links, so we update if ( nodes[i]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) CheckNodeUV( F, nodes[i], uv[ i ], 2*tol, /*force=*/true ); } @@ -5542,16 +5542,16 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError, pointsOnShapes[ SMESH_Block::ID_Ex11 ] = SMESH_TNodeXYZ( hexNodes[ 13 ] ); pointsOnShapes[ SMESH_Block::ID_E0y1 ] = SMESH_TNodeXYZ( hexNodes[ 12 ] ); pointsOnShapes[ SMESH_Block::ID_E1y1 ] = SMESH_TNodeXYZ( hexNodes[ 14 ] ); - pointsOnShapes[ SMESH_Block::ID_E00z ] = SMESH_TNodeXYZ( hexNodes[ 16 ] ); - pointsOnShapes[ SMESH_Block::ID_E10z ] = SMESH_TNodeXYZ( hexNodes[ 19 ] ); - pointsOnShapes[ SMESH_Block::ID_E01z ] = SMESH_TNodeXYZ( hexNodes[ 17 ] ); + pointsOnShapes[ SMESH_Block::ID_E00z ] = SMESH_TNodeXYZ( hexNodes[ 16 ] ); + pointsOnShapes[ SMESH_Block::ID_E10z ] = SMESH_TNodeXYZ( hexNodes[ 19 ] ); + pointsOnShapes[ SMESH_Block::ID_E01z ] = SMESH_TNodeXYZ( hexNodes[ 17 ] ); pointsOnShapes[ SMESH_Block::ID_E11z ] = SMESH_TNodeXYZ( hexNodes[ 18 ] ); pointsOnShapes[ SMESH_Block::ID_Fxy0 ] = SMESH_TNodeXYZ( hexNodes[ 20 ] ); pointsOnShapes[ SMESH_Block::ID_Fxy1 ] = SMESH_TNodeXYZ( hexNodes[ 25 ] ); - pointsOnShapes[ SMESH_Block::ID_Fx0z ] = SMESH_TNodeXYZ( hexNodes[ 21 ] ); - pointsOnShapes[ SMESH_Block::ID_Fx1z ] = SMESH_TNodeXYZ( hexNodes[ 23 ] ); - pointsOnShapes[ SMESH_Block::ID_F0yz ] = SMESH_TNodeXYZ( hexNodes[ 24 ] ); + pointsOnShapes[ SMESH_Block::ID_Fx0z ] = SMESH_TNodeXYZ( hexNodes[ 21 ] ); + pointsOnShapes[ SMESH_Block::ID_Fx1z ] = SMESH_TNodeXYZ( hexNodes[ 23 ] ); + pointsOnShapes[ SMESH_Block::ID_F0yz ] = SMESH_TNodeXYZ( hexNodes[ 24 ] ); pointsOnShapes[ SMESH_Block::ID_F1yz ] = SMESH_TNodeXYZ( hexNodes[ 22 ] ); gp_XYZ nCenterParams(0.5, 0.5, 0.5), nCenterCoords; @@ -5588,8 +5588,5 @@ void SMESH_MesherHelper::WriteShape(const TopoDS_Shape& s) { const char* name = "/tmp/shape.brep"; BRepTools::Write( s, name ); -#ifdef _DEBUG_ - std::cout << name << std::endl; -#endif } diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index b28d44b4e..ebc79d9b7 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -1583,7 +1583,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) _computeError = SMESH_ComputeError::Worst( _computeError, algo->GetComputeError() ); } catch ( ::SMESH_ComputeError& comperr ) { - cout << " SMESH_ComputeError caught" << endl; + MESSAGE(" SMESH_ComputeError caught"); if ( !_computeError ) _computeError = SMESH_ComputeError::New(); *_computeError = comperr; } diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index 263454015..8f57c6c1b 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -6645,8 +6645,6 @@ CORBA::Boolean SMESH_Gen_i::IsApplicable ( const char* theAlgoType, SMESH_CATCH( SMESH::doNothing ); -#ifdef _DEBUG_ - cout << "SMESH_Gen_i::IsApplicable(): exception in " << ( theAlgoType ? theAlgoType : "") << endl; -#endif + MESSAGE("SMESH_Gen_i::IsApplicable(): exception in " << ( theAlgoType ? theAlgoType : "")); return true; } From 640594fef60ebbc9c623a99a76fff8a8662f9dc7 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Wed, 28 Sep 2022 08:06:19 +0200 Subject: [PATCH 19/29] Minor correction --- src/SMESH/SMESH_subMesh.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index ebc79d9b7..ae2295949 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -1651,7 +1651,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) for (subS.ReInit(); subS.More(); subS.Next()) { _father->Lock(); - const std::list hyps = + const std::list & hyps = _algo->GetUsedHypothesis( *_father, _subShape ); _father->Unlock(); SMESH_Comment hypStr; From d5617f4801e52e4347bae8677611a4517cc3b69e Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Wed, 28 Sep 2022 14:18:32 +0200 Subject: [PATCH 20/29] Split of seq/par compute in gen --- src/SMESH/SMESH_Gen.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index f61acd5f9..f2e4e0d9f 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -184,9 +184,9 @@ const std::functionGetComputeState() == SMESH_subMesh::READY_TO_COMPUTE) { sm->SetAllowedSubShapes( fillAllowed( shapeSM, aShapeOnly, allowedSubShapes )); - //setCurrentSubMesh( sm ); + setCurrentSubMesh( sm ); sm->ComputeStateEngine(event); - //setCurrentSubMesh( nullptr ); + setCurrentSubMesh( nullptr ); sm->SetAllowedSubShapes( nullptr ); } From c9a5231c3266eab79a74e3c50b702c7467d8df91 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Thu, 29 Sep 2022 16:25:05 +0200 Subject: [PATCH 21/29] Splitting gen compute seq/para + clean up + remove int argument + solve bug (commented notifyevent) --- doc/gui/input/about_meshes.rst | 2 +- src/SMESH/SMESH_Gen.cxx | 271 ++++++++++++++++++++----------- src/SMESH/SMESH_Gen.hxx | 25 ++- src/SMESH/SMESH_MesherHelper.cxx | 1 + src/SMESH/SMESH_subMesh.cxx | 2 +- src/SMESH_SWIG/smeshBuilder.py | 1 - 6 files changed, 205 insertions(+), 97 deletions(-) diff --git a/doc/gui/input/about_meshes.rst b/doc/gui/input/about_meshes.rst index 73af1714e..619bd799f 100644 --- a/doc/gui/input/about_meshes.rst +++ b/doc/gui/input/about_meshes.rst @@ -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 `. 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 `. 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. diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index f2e4e0d9f..f977bce53 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -160,21 +160,82 @@ SMESH_Mesh* SMESH_Gen::CreateMesh(bool theIsEmbeddedMode) return aMesh; } + + +bool SMESH_Gen::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) +{ + MESSAGE("Compute submeshes sequentialy"); + + bool ret = true; + + SMESH_subMeshIteratorPtr smIt; + SMESH_subMesh *shapeSM = aMesh.GetSubMesh(aShape); + + 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(); + 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 - compute_function([&] (int id, - SMESH_subMesh* sm, + compute_function([&] (SMESH_subMesh* sm, SMESH_subMesh::compute_event event, SMESH_subMesh *shapeSM, bool aShapeOnly, @@ -184,9 +245,9 @@ const std::functionGetComputeState() == SMESH_subMesh::READY_TO_COMPUTE) { sm->SetAllowedSubShapes( fillAllowed( shapeSM, aShapeOnly, allowedSubShapes )); - setCurrentSubMesh( sm ); + //setCurrentSubMesh( sm ); sm->ComputeStateEngine(event); - setCurrentSubMesh( nullptr ); + //setCurrentSubMesh( nullptr ); sm->SetAllowedSubShapes( nullptr ); } @@ -195,6 +256,101 @@ const std::functiongetDependsOnIterator(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 (shapeType != previousShapeType) { + // 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; + } + if(file_name != "") + { + fs::path mesh_file = fs::path(aMesh.tmp_folder) / fs::path(file_name); + exportMesh(mesh_file.string(), aMesh, "MESH"); + + } + //Resetting threaded pool info + previousShapeType = shapeType; + } + + // 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; + } + boost::asio::post(*(aMesh._pool), std::bind(compute_function, smToCompute, computeEvent, + shapeSM, aShapeOnly, allowedSubShapes, + aShapesId)); + } + + // Waiting for the thread for Solids to finish + aMesh.wait(); + + aMesh.GetMeshDS()->Modified(); + + return ret; +}; + + //============================================================================= /* * Compute a mesh @@ -222,10 +378,6 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, 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 @@ -245,89 +397,22 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, // =============================================== // 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()); - - - 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(); - 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) { - // 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; - } - if(file_name != "") - { - fs::path mesh_file = fs::path(aMesh.tmp_folder) / fs::path(file_name); - exportMesh(mesh_file.string(), aMesh, "MESH"); - - } - //Resetting threaded pool info - previousShapeType = shapeType; - } - - // 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(aMesh.IsParallel()) - { - boost::asio::post(*(aMesh._pool), std::bind(compute_function, 1, 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(); + 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; } diff --git a/src/SMESH/SMESH_Gen.hxx b/src/SMESH/SMESH_Gen.hxx index c5b958b07..94058184e 100644 --- a/src/SMESH/SMESH_Gen.hxx +++ b/src/SMESH/SMESH_Gen.hxx @@ -34,6 +34,7 @@ #include "SMESH_Algo.hxx" #include "SMESH_ComputeError.hxx" +#include "SMESH_subMesh.hxx" #include #include @@ -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; diff --git a/src/SMESH/SMESH_MesherHelper.cxx b/src/SMESH/SMESH_MesherHelper.cxx index f92de2bed..f426d73f4 100644 --- a/src/SMESH/SMESH_MesherHelper.cxx +++ b/src/SMESH/SMESH_MesherHelper.cxx @@ -5588,5 +5588,6 @@ void SMESH_MesherHelper::WriteShape(const TopoDS_Shape& s) { const char* name = "/tmp/shape.brep"; BRepTools::Write( s, name ); + MESSAGE(name); } diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index ae2295949..b5661535a 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -1907,7 +1907,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) break; } - //notifyListenersOnEvent( event, COMPUTE_EVENT ); + notifyListenersOnEvent( event, COMPUTE_EVENT ); return ret; } diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index 25a947352..a06ece584 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -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 From 43fc1c7182e8e8117222ec6d3ed7b2fe1c6072c5 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Thu, 29 Sep 2022 16:30:47 +0200 Subject: [PATCH 22/29] Correction for test --- test/netgen_runner.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/netgen_runner.py b/test/netgen_runner.py index 9740b2676..a23c7e9ce 100644 --- a/test/netgen_runner.py +++ b/test/netgen_runner.py @@ -100,15 +100,15 @@ def test_netgen3d(): print(cmd) subprocess.check_call(cmd, shell=True) - meshRead = mc.ReadUMeshFromFile (output_mesh, "Maillage_1", 0) + meshRead = mc.ReadUMeshFromFile (output_mesh, "MESH", 0) nbTetras = meshRead.getNumberOfCellsWithType(mc.NORM_TETRA4) nbPoints = meshRead.getNumberOfNodes() - meshRead = mc.ReadUMeshFromFile (output_mesh, "Maillage_1", -1) + meshRead = mc.ReadUMeshFromFile (output_mesh, "MESH", -1) nbTriangles = meshRead.getNumberOfCellsWithType(mc.NORM_TRI3) - meshRead = mc.ReadUMeshFromFile (output_mesh, "Maillage_1", -2) + meshRead = mc.ReadUMeshFromFile (output_mesh, "MESH", -2) nbSegments = meshRead.getNumberOfCellsWithType(mc.NORM_SEG2) print("Nb Tetras:", nbTetras) From 9ecd84933aa3c8fbd2d1f06f0efa7fb2c79df6f8 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Mon, 3 Oct 2022 08:01:36 +0200 Subject: [PATCH 23/29] Created MeshLocker to replace Lock/Unlock + replacing std::cerr by exceptions + replacing assign in submesh by call to algo function --- src/SMESH/CMakeLists.txt | 2 ++ src/SMESH/SMESH_Algo.hxx | 19 ++++++++------ src/SMESH/SMESH_DriverShape.cxx | 16 +++++------- src/SMESH/SMESH_Mesh.hxx | 1 - src/SMESH/SMESH_MeshLocker.cxx | 40 ++++++++++++++++++++++++++++++ src/SMESH/SMESH_MeshLocker.hxx | 44 +++++++++++++++++++++++++++++++++ src/SMESH/SMESH_subMesh.cxx | 19 ++++++-------- 7 files changed, 111 insertions(+), 30 deletions(-) create mode 100644 src/SMESH/SMESH_MeshLocker.cxx create mode 100644 src/SMESH/SMESH_MeshLocker.hxx diff --git a/src/SMESH/CMakeLists.txt b/src/SMESH/CMakeLists.txt index afe512509..88d42d875 100644 --- a/src/SMESH/CMakeLists.txt +++ b/src/SMESH/CMakeLists.txt @@ -92,6 +92,7 @@ SET(SMESHimpl_HEADERS SMESH_Homard.hxx SMESH_DriverMesh.hxx SMESH_DriverShape.hxx + SMESH_MeshLocker.hxx ) # --- sources --- @@ -114,6 +115,7 @@ SET(SMESHimpl_SOURCES SMESH_Homard.cxx SMESH_DriverMesh.cxx SMESH_DriverShape.cxx + SMESH_MeshLocker.cxx ) # --- rules --- diff --git a/src/SMESH/SMESH_Algo.hxx b/src/SMESH/SMESH_Algo.hxx index 3beb89ae1..580d73d68 100644 --- a/src/SMESH/SMESH_Algo.hxx +++ b/src/SMESH/SMESH_Algo.hxx @@ -198,15 +198,15 @@ class SMESH_EXPORT SMESH_Algo : public SMESH_Hypothesis /*! * \brief Return a list of compatible hypotheses used to mesh a shape - * \param aMesh - the mesh + * \param aMesh - the mesh * \param aShape - the shape * \param ignoreAuxiliary - do not include auxiliary hypotheses in the list * \retval const std::list - hypotheses list - * + * * List the hypothesis used by the algorithm associated to the shape. * Hypothesis associated to father shape -are- taken into account (see * GetAppliedHypothesis). Relevant hypothesis have a name (type) listed in - * the algorithm. This method could be surcharged by specific algorithms, in + * the algorithm. This method could be surcharged by specific algorithms, in * case of several hypothesis simultaneously applicable. */ virtual const std::list & @@ -277,10 +277,13 @@ public: // 6 - if algo !NeedDiscreteBoundary() but requires presence of // hypotheses of dimension to generate all-dimensional mesh. // This info is used not to issue warnings on hiding of lower global algos. + // + + virtual void setSubMeshesToCompute(SMESH_subMesh * aSubMesh) {SubMeshesToCompute().assign( 1, aSubMesh );} public: // ================================================================== - // Methods to track non hierarchical dependencies between submeshes + // Methods to track non hierarchical dependencies between submeshes // ================================================================== /*! @@ -292,7 +295,7 @@ public: * By default none listener is set */ virtual void SetEventListener(SMESH_subMesh* subMesh); - + /*! * \brief Allow algo to do something after persistent restoration * \param subMesh - restored submesh @@ -300,7 +303,7 @@ public: * This method is called only if a submesh has HYP_OK algo_state. */ virtual void SubmeshRestored(SMESH_subMesh* subMesh); - + public: // ================================================================== // Common algo utilities @@ -398,7 +401,7 @@ public: enum EMeshError { MEr_OK = 0, MEr_HOLES, MEr_BAD_ORI, MEr_EMPTY }; /*! - * \brief Finds topological errors of a sub-mesh + * \brief Finds topological errors of a sub-mesh */ static EMeshError GetMeshError(SMESH_subMesh* subMesh); @@ -434,7 +437,7 @@ protected: std::vector _compatibleHypothesis; std::list _usedHypList; std::list _assigedShapeList; // _usedHypList assigned to - + // Algo features influencing which Compute() and how is called: // in what turn and with what input shape. diff --git a/src/SMESH/SMESH_DriverShape.cxx b/src/SMESH/SMESH_DriverShape.cxx index d8cf96473..fd725274e 100644 --- a/src/SMESH/SMESH_DriverShape.cxx +++ b/src/SMESH/SMESH_DriverShape.cxx @@ -26,6 +26,7 @@ // #include +#include #include "SMESH_DriverShape.hxx" // step include @@ -62,8 +63,7 @@ int importSTEPShape(const std::string shape_file, TopoDS_Shape& aShape){ Interface_Static::SetIVal("read.step.nonmanifold", 1); IFSelect_ReturnStatus aStat = reader.ReadFile(shape_file.c_str()); if(aStat != IFSelect_RetDone){ - std::cerr << "Reading error for " << shape_file << std::endl; - return true; + throw SALOME_Exception("Reading error for " + shape_file); } int NbTrans = reader.TransferRoots(); @@ -94,15 +94,13 @@ int exportSTEPShape(const std::string shape_file, const TopoDS_Shape& aShape){ IFSelect_ReturnStatus aStat = aWriter.Transfer(aShape,STEPControl_AsIs); if(aStat != IFSelect_RetDone){ - std::cerr << "Transfer error for " << shape_file << std::endl; - return true; + throw SALOME_Exception("Reading error for " + shape_file); } aStat = aWriter.Write(shape_file.c_str()); if(aStat != IFSelect_RetDone){ - std::cerr << "Writing error for " << shape_file << std::endl; - return true; + throw SALOME_Exception("Writing error for " + shape_file); } return aStat; } @@ -156,8 +154,7 @@ int importShape(const std::string shape_file, TopoDS_Shape& aShape){ } else if (type == ".step"){ return importSTEPShape(shape_file, aShape); } else { - std::cerr << "Unknow format: " << type << std::endl; - return true; + throw SALOME_Exception("Unknow format for importShape: " + type); } } @@ -177,7 +174,6 @@ int exportShape(const std::string shape_file, const TopoDS_Shape& aShape){ } else if (type == ".step"){ return exportSTEPShape(shape_file, aShape); } else { - std::cerr << "Unknow format: " << type << std::endl; - return true; + throw SALOME_Exception("Unknow format for exportShape: " + type); } } diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx index 28a5b5a2b..8c4d0b18b 100644 --- a/src/SMESH/SMESH_Mesh.hxx +++ b/src/SMESH/SMESH_Mesh.hxx @@ -462,5 +462,4 @@ protected: SMESH_Mesh(); SMESH_Mesh(const SMESH_Mesh&) {}; }; - #endif diff --git a/src/SMESH/SMESH_MeshLocker.cxx b/src/SMESH/SMESH_MeshLocker.cxx new file mode 100644 index 000000000..b90fb0529 --- /dev/null +++ b/src/SMESH/SMESH_MeshLocker.cxx @@ -0,0 +1,40 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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 : SMESH_MeshLocker.cxx +// Author : Yoann AUDOUIN, EDF +// Module : SMESH +// + +#include "SMESH_MeshLocker.hxx" + +#include "SMESH_Mesh.hxx" + +SMESH_MeshLocker::SMESH_MeshLocker(SMESH_Mesh * aMesh) : _myMesh(aMesh) +{ + _myMesh->Lock(); +} + +SMESH_MeshLocker::~SMESH_MeshLocker() +{ + _myMesh->Unlock(); +} diff --git a/src/SMESH/SMESH_MeshLocker.hxx b/src/SMESH/SMESH_MeshLocker.hxx new file mode 100644 index 000000000..e38c31b29 --- /dev/null +++ b/src/SMESH/SMESH_MeshLocker.hxx @@ -0,0 +1,44 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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 : SMESH_Mesh.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// +#ifndef _SMESH_MESHLOCKER_HXX_ +#define _SMESH_MESHLOCKER_HXX_ + +class SMESH_Mesh; + +class SMESH_MeshLocker{ +public: + SMESH_MeshLocker(SMESH_Mesh * aMesh); + ~SMESH_MeshLocker(); + +protected: + SMESH_MeshLocker(); + +private: + SMESH_Mesh * _myMesh=nullptr; +}; + +#endif diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index b5661535a..ace4c6f1f 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -37,6 +37,7 @@ #include "SMESH_Mesh.hxx" #include "SMESH_MesherHelper.hxx" #include "SMESH_subMeshEventListener.hxx" +#include "SMESH_MeshLocker.hxx" #include "utilities.h" #include "Basics_Utils.hxx" @@ -1393,16 +1394,13 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) else if (( event == COMPUTE || event == COMPUTE_SUBMESH ) && !_alwaysComputed ) { - // LOCK: Adding node to mesh - _father->Lock(); + SMESH_MeshLocker myLocker(_father); const TopoDS_Vertex & V = TopoDS::Vertex( _subShape ); gp_Pnt P = BRep_Tool::Pnt(V); if ( SMDS_MeshNode * n = _father->GetMeshDS()->AddNode(P.X(), P.Y(), P.Z()) ) { _father->GetMeshDS()->SetNodeOnVertex(n,_Id); _computeState = COMPUTE_OK; } - _father->Unlock(); - // UNLOCK } if ( event == MODIF_ALGO_STATE ) cleanDependants(); @@ -1516,9 +1514,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) break; } TopoDS_Shape shape = _subShape; - _father->Lock(); - algo->SubMeshesToCompute().assign( 1, this ); - _father->Unlock(); + algo->setSubMeshesToCompute(this); // check submeshes needed // In parallel there would be no submesh to check if (_father->HasShapeToMesh() && !_father->IsParallel()) { @@ -1650,10 +1646,11 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) #ifdef PRINT_WHO_COMPUTE_WHAT for (subS.ReInit(); subS.More(); subS.Next()) { - _father->Lock(); - const std::list & hyps = - _algo->GetUsedHypothesis( *_father, _subShape ); - _father->Unlock(); + const std::list & hyps + { + SMESH_MeshLocker myLocker(_father); + hyps = _algo->GetUsedHypothesis( *_father, _subShape ); + } SMESH_Comment hypStr; if ( !hyps.empty() ) { From 710bfb39c4f23540ba4085c597d1fb28455ab3e9 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Mon, 3 Oct 2022 08:03:41 +0200 Subject: [PATCH 24/29] Update of copyright --- src/SMESH/SMESH_DriverMesh.cxx | 2 +- src/SMESH/SMESH_DriverShape.cxx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SMESH/SMESH_DriverMesh.cxx b/src/SMESH/SMESH_DriverMesh.cxx index a47289535..01cc5df4c 100644 --- a/src/SMESH/SMESH_DriverMesh.cxx +++ b/src/SMESH/SMESH_DriverMesh.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS diff --git a/src/SMESH/SMESH_DriverShape.cxx b/src/SMESH/SMESH_DriverShape.cxx index fd725274e..c9db8372e 100644 --- a/src/SMESH/SMESH_DriverShape.cxx +++ b/src/SMESH/SMESH_DriverShape.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS From effd6e22299c58b7829614ca9f66796a2e1b3dd9 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Tue, 4 Oct 2022 09:38:12 +0200 Subject: [PATCH 25/29] Adding code for Python parallel mesh with test + removing nbMesherThreads --- idl/SMESH_Mesh.idl | 5 -- src/SMESH/SMESH_Gen.cxx | 2 +- src/SMESH/SMESH_Mesh.cxx | 2 +- src/SMESH/SMESH_Mesh.hxx | 4 - src/SMESH_I/SMESH_2smeshpy.cxx | 2 +- src/SMESH_I/SMESH_Mesh_i.cxx | 9 -- src/SMESH_SWIG/smeshBuilder.py | 155 +++++++++++++++++++++++++++------ test/SMESH_ParallelCompute.py | 131 ++++++++++++++++++++++++++++ test/netgen_runner.py | 100 +++++++++++---------- test/tests.set | 1 + 10 files changed, 317 insertions(+), 94 deletions(-) create mode 100644 test/SMESH_ParallelCompute.py diff --git a/idl/SMESH_Mesh.idl b/idl/SMESH_Mesh.idl index f420e4ff7..7b86361d8 100644 --- a/idl/SMESH_Mesh.idl +++ b/idl/SMESH_Mesh.idl @@ -905,11 +905,6 @@ module SMESH void SetNbThreads(in long nbThreads); /*! - * \brief Set Number of Threads for mesher - */ - void SetMesherNbThreads(in long nbThreads); - - /*! * Get mesh description */ diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index f977bce53..922a6df95 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -279,7 +279,7 @@ bool SMESH_Gen::parallelComputeSubMeshes( TopAbs_ShapeEnum previousShapeType = TopAbs_VERTEX; int nbThreads = aMesh.GetNbThreads(); - MESSAGE("Compute submeshes with threads: " << nbThreads << " mesher: " << aMesh.GetMesherNbThreads()); + MESSAGE("Compute submeshes with threads: " << nbThreads); smIt = shapeSM->getDependsOnIterator(includeSelf, !complexShapeFirst); diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index 3eb08a85c..bd101248c 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -87,7 +87,7 @@ namespace fs=boost::filesystem; #define MAX_MED_GROUP_NAME_LENGTH 80 #ifdef _DEBUG_ -static int MYDEBUG = 1; +static int MYDEBUG = 0; #else static int MYDEBUG = 0; #endif diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx index 8c4d0b18b..ed897979f 100644 --- a/src/SMESH/SMESH_Mesh.hxx +++ b/src/SMESH/SMESH_Mesh.hxx @@ -392,9 +392,6 @@ class SMESH_EXPORT SMESH_Mesh int GetNbThreads(){return _NbThreads;}; void SetNbThreads(int nbThreads){_NbThreads=nbThreads;}; - int GetMesherNbThreads(){return _MesherNbThreads;}; - void SetMesherNbThreads(int nbThreads){_MesherNbThreads=nbThreads;}; - void InitPoolThreads(){_pool = new boost::asio::thread_pool(_NbThreads);}; void DeletePoolThreads(){delete _pool;}; @@ -456,7 +453,6 @@ protected: // Mutex for multhitreading write in SMESH_Mesh std::mutex _my_lock; int _NbThreads=0; - int _MesherNbThreads=0; protected: SMESH_Mesh(); diff --git a/src/SMESH_I/SMESH_2smeshpy.cxx b/src/SMESH_I/SMESH_2smeshpy.cxx index a9fff0a6d..4ac51ac99 100644 --- a/src/SMESH_I/SMESH_2smeshpy.cxx +++ b/src/SMESH_I/SMESH_2smeshpy.cxx @@ -2213,7 +2213,7 @@ bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand ) "GetElemFaceNodes", "GetFaceNormal", "FindElementByNodes", "IsPoly","IsQuadratic","BaryCenter","GetHypothesisList", "SetAutoColor", "GetAutoColor", "Clear", "ConvertToStandalone", "GetMeshOrder", "SetMeshOrder", - "SetNbThreads", "SetMesherNbThreads" + "SetNbThreads" ,"" }; // <- mark of end sameMethods.Insert( names ); } diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index 3bd2f7fe7..a7abda6db 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -7046,15 +7046,6 @@ void SMESH_Mesh_i::SetNbThreads(int nbThreads){ _impl->SetNbThreads(nbThreads); } -//============================================================================= -/*! - * \brief Set the number of threads for the mesher for a parallel computation - */ -//============================================================================= -void SMESH_Mesh_i::SetMesherNbThreads(int nbThreads){ - _impl->SetMesherNbThreads(nbThreads); -} - //============================================================================= /*! diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index a06ece584..ee22a96bd 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -462,6 +462,21 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): obj,name = name,obj return Mesh(self, self.geompyD, obj, name) + def ParallelMesh(self, obj, param, nbThreads, name=0): + """ + Create a parallel mesh. + + Parameters: + obj: geometrical object for meshing + name: the name for the new mesh. + param: full mesh parameters + nbThreads: Number of threads for parallelisation. + + Returns: + an instance of class :class:`ParallelMesh`. + """ + return ParallelMesh(self, self.geompyD, obj, param, nbThreads, name) + def RemoveMesh( self, mesh ): """ Delete a mesh @@ -1863,31 +1878,6 @@ class Mesh(metaclass = MeshMeta): geom = self.geom return self.smeshpyD.Evaluate(self.mesh, geom) - def ParallelCompute(self, nbThreads, mesherNbThreads=1, geom=0, discardModifs=False, refresh=False): - """ - Parallel computation of the mesh and return the status of the computation - The mesh must contains have be constructed using create_parallel_mesh - - Parameters: - nbThreads: Number of threads to use for a parallel computation - geom: geomtrical shape on which mesh data should be computed - discardModifs: if True and the mesh has been edited since - 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) - - Returns: - True or False - """ - if (nbThreads <= 1): - raise ValueError("nbThreads must be strictly greater than 1") - if (mesherNbThreads < 1): - raise ValueError("nbThreads must be greater than 1") - - self.mesh.SetMesherNbThreads(mesherNbThreads) - self.mesh.SetNbThreads(nbThreads) - return self.Compute(geom=geom, discardModifs=discardModifs, refresh=refresh) - def Compute(self, geom=0, discardModifs=False, refresh=False): """ Compute the mesh and return the status of the computation @@ -7511,6 +7501,121 @@ class Mesh(metaclass = MeshMeta): pass # end of Mesh class +def _copy_netgen_param(dim, local_param, global_param): + if dim==1: + #TODO: Try to identify why we need to substract 1 + local_param.NumberOfSegments(int(global_param.GetNbSegPerEdge())-1) + elif dim==2: + local_param.SetMaxSize(global_param.GetMaxSize()) + local_param.SetMinSize(global_param.GetMinSize()) + local_param.SetOptimize(global_param.GetOptimize()) + local_param.SetFineness(global_param.GetFineness()) + local_param.SetNbSegPerEdge(global_param.GetNbSegPerEdge()) + local_param.SetNbSegPerRadius(global_param.GetNbSegPerRadius()) + local_param.SetGrowthRate(global_param.GetGrowthRate()*0.9) + local_param.SetChordalError(global_param.GetChordalError()) + local_param.SetChordalErrorEnabled(global_param.GetChordalErrorEnabled()) + local_param.SetUseSurfaceCurvature(global_param.GetUseSurfaceCurvature()) + local_param.SetUseDelauney(global_param.GetUseDelauney()) + local_param.SetQuadAllowed(global_param.GetQuadAllowed()) + local_param.SetWorstElemMeasure(global_param.GetWorstElemMeasure()) + local_param.SetCheckChartBoundary(global_param.GetCheckChartBoundary()) + local_param.SetNbThreads(global_param.GetNbThreads()) + else: + local_param.SetMaxSize(global_param.GetMaxSize()) + local_param.SetMinSize(global_param.GetMinSize()) + local_param.SetOptimize(global_param.GetOptimize()) + local_param.SetCheckOverlapping(global_param.GetCheckOverlapping()) + local_param.SetCheckChartBoundary(global_param.GetCheckChartBoundary()) + local_param.SetFineness(global_param.GetFineness()) + local_param.SetNbSegPerEdge(global_param.GetNbSegPerEdge()) + local_param.SetNbSegPerRadius(global_param.GetNbSegPerRadius()) + local_param.SetGrowthRate(global_param.GetGrowthRate()) + local_param.SetNbThreads(global_param.GetNbThreads()) + +class ParallelMesh(Mesh): + """ + Surcharge on Mesh for parallel computation of a mesh + """ + + def __init__(self, smeshpyD, geompyD, geom, param, nbThreads, name=0): + """ + Create a parallel mesh. + + Parameters: + geom: geometrical object for meshing + param: full mesh parameters + nbThreads: Number of threads for parallelisation. + name: the name for the new mesh. + + Returns: + an instance of class :class:`ParallelMesh`. + """ + + if not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object): + raise ValueError("geom argument must be a geometry") + + if not isinstance(param, NETGENPlugin._objref_NETGENPlugin_Hypothesis): + raise ValueError("param must come from NETGENPlugin") + + if nbThreads < 1: + raise ValueError("Number of threads must be stricly greater than 1") + + # Splitting geometry into 3D elements and all the 2D/1D into one compound + object_solids = geompyD.ExtractShapes(geom, geompyD.ShapeType["SOLID"], + True) + + solids = [] + isolid = 0 + for solid in object_solids: + isolid += 1 + geompyD.addToStudyInFather( geom, solid, 'Solid_{}'.format(isolid) ) + solids.append(solid) + + faces = [] + iface = 0 + for isolid, solid in enumerate(solids): + solid_faces = geompyD.ExtractShapes(solid, geompyD.ShapeType["FACE"], + True) + for face in solid_faces: + faces.append(face) + iface += 1 + geompyD.addToStudyInFather(solid, 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') + + super(ParallelMesh, self).__init__(smeshpyD, geompyD, geom, name) + + self.mesh.SetNbThreads(nbThreads) + + self.UseExistingSegments() + self.UseExistingFaces() + + algo2d = self.Triangle(geom=all_faces, algo="NETGEN_2D") + param2d = algo2d.Parameters() + + _copy_netgen_param(2, param2d, param) + + for solid_id, solid in enumerate(solids): + name = "Solid_{}".format(solid_id) + self.UseExistingSegments(geom=solid) + self.UseExistingFaces(geom=solid) + algo3d = self.Tetrahedron(geom=solid, algo="NETGEN_3D_Remote") + + param3d = algo3d.Parameters() + + _copy_netgen_param(3, param3d, param) + + pass # End of ParallelMesh + + class meshProxy(SMESH._objref_SMESH_Mesh): """ Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility diff --git a/test/SMESH_ParallelCompute.py b/test/SMESH_ParallelCompute.py new file mode 100644 index 000000000..eeddd3f02 --- /dev/null +++ b/test/SMESH_ParallelCompute.py @@ -0,0 +1,131 @@ +# contains function to compute a mesh in parallel +from platform import java_ver +import sys +from tkinter import W +import salome + +import time + + +salome.salome_init() +import salome_notebook +notebook = salome_notebook.NoteBook() + +### +### GEOM component +### + +import GEOM +from salome.geom import geomBuilder +from salome.smesh import smeshBuilder +import math +import SALOMEDS + +import numpy as np + +geompy = geomBuilder.New() + +smesh = smeshBuilder.New() + + +def build_seq_mesh(nbox, boxsize, offset): + # Create 3D faces + boxes = [] + # First creating all the boxes + for i in range(nbox): + for j in range(nbox): + for k in range(nbox): + + x_orig = i*(boxsize+offset) + y_orig = j*(boxsize+offset) + z_orig = k*(boxsize+offset) + + tmp_box = geompy.MakeBoxDXDYDZ(boxsize, boxsize, boxsize) + + if not i == j == k == 0: + box = geompy.MakeTranslation(tmp_box, x_orig, + y_orig, z_orig) + else: + box = tmp_box + + geompy.addToStudy(box, 'box_{}:{}:{}'.format(i, j, k)) + + boxes.append(box) + + # Create fuse of all boxes + all_boxes = geompy.MakeCompound(boxes) + geompy.addToStudy(all_boxes, 'Compound_1') + + # Removing duplicates faces and edges + all_boxes = geompy.MakeGlueFaces(all_boxes, 1e-07) + geompy.addToStudy(all_boxes, 'Glued_Faces_1') + + all_boxes = geompy.MakeGlueEdges(all_boxes, 1e-07) + geompy.addToStudy(all_boxes, 'rubik_cube') + + + # Building sequetial mesh + print("Creating mesh") + all_box_mesh = smesh.Mesh(all_boxes, "seq_mesh") + + print("Adding algo") + algo3d = all_box_mesh.Tetrahedron(algo=smeshBuilder.NETGEN_1D2D3D) + + netgen_parameters = algo3d.Parameters() + netgen_parameters.SetMaxSize(34.641) + netgen_parameters.SetMinSize(0.141421) + netgen_parameters.SetOptimize(1) + netgen_parameters.SetCheckOverlapping(0) + netgen_parameters.SetCheckChartBoundary(0) + netgen_parameters.SetFineness(5) + netgen_parameters.SetNbSegPerEdge(16*(boxsize//100)) + netgen_parameters.SetNbSegPerRadius(1.5) + netgen_parameters.SetGrowthRate(0.15) + netgen_parameters.SetChordalError(-1) + netgen_parameters.SetChordalErrorEnabled(0) + netgen_parameters.SetUseSurfaceCurvature(1) + netgen_parameters.SetQuadAllowed(0) + netgen_parameters.SetCheckOverlapping(False) + netgen_parameters.SetNbThreads(2) + + return all_boxes, all_box_mesh, netgen_parameters + +def run_test(nbox=2, boxsize=100): + """ Run sequential mesh and parallel version of it + + nbox: NUmber of boxes + boxsize: Size of each box + """ + geom, seq_mesh, netgen_parameters = build_seq_mesh(nbox, boxsize, 0) + + par_mesh = smesh.ParallelMesh(geom, netgen_parameters, 6, name="par_mesh") + + start = time.monotonic() + is_done = seq_mesh.Compute() + assert is_done + stop = time.monotonic() + time_seq = stop-start + + start = time.monotonic() + is_done = par_mesh.Compute() + assert is_done + stop = time.monotonic() + time_par = stop-start + + print(" Tetrahedron: ", seq_mesh.NbTetras(), par_mesh.NbTetras()) + print(" Triangle: ", seq_mesh.NbTriangles(), par_mesh.NbTriangles()) + print(" edge: ", seq_mesh.NbEdges(), par_mesh.NbEdges()) + + assert par_mesh.NbTetras() > 0 + assert par_mesh.NbTriangles() > 0 + assert par_mesh.NbEdges() > 0 + + print("Time elapsed (seq, par): ", time_seq, time_par) + +def main(): + nbox = 2 + boxsize = 100 + run_test(nbox, boxsize) + +main() + diff --git a/test/netgen_runner.py b/test/netgen_runner.py index a23c7e9ce..be8386fcb 100644 --- a/test/netgen_runner.py +++ b/test/netgen_runner.py @@ -22,7 +22,7 @@ import medcoupling as mc def create_param_file(param_file): """ Create a parameter file for runner """ - param="""1 + param = """1 34.64 0.14 16 @@ -43,8 +43,10 @@ def create_param_file(param_file): 0 0 2 +2 0 +0 0 0""" with open(param_file, "w") as ffile: @@ -57,69 +59,71 @@ def test_netgen3d(): box = geompy.MakeBoxDXDYDZ(200, 200, 200) geompy.ExtractShapes(box, geompy.ShapeType["FACE"], True) - Groupe_1 = geompy.CreateGroup(box, geompy.ShapeType["FACE"]) - geompy.UnionIDs(Groupe_1, [3, 13, 23, 27, 31, 33]) + groupe_1 = geompy.CreateGroup(box, geompy.ShapeType["FACE"]) + geompy.UnionIDs(groupe_1, [3, 13, 23, 27, 31, 33]) - # TODO: useful ? - [_, _, _, _, _, _, Groupe_1] = geompy.GetExistingSubObjects(box, False) + [_, _, _, _, _, _, groupe_1] = geompy.GetExistingSubObjects(box, False) # Creating 2D mesh - NETGEN_2D_Parameters_1 = smesh.CreateHypothesisByAverageLength( + netgen_2d_parameters_1 = smesh.CreateHypothesisByAverageLength( 'NETGEN_Parameters_2D', 'NETGENEngine', 34.641, 0) - Mesh2D = smesh.Mesh(Groupe_1, 'Maillage_1') - status = Mesh2D.AddHypothesis(Groupe_1, NETGEN_2D_Parameters_1) - NETGEN_1D_2D = Mesh2D.Triangle(algo=smeshBuilder.NETGEN_1D2D) - isDone = Mesh2D.Compute() - smesh.SetName(Mesh2D, 'Maillage_1') + mesh_2d = smesh.Mesh(groupe_1, 'Maillage_1') + mesh_2d.AddHypothesis(groupe_1, netgen_2d_parameters_1) + mesh_2d.Triangle(algo=smeshBuilder.NETGEN_1D2D) + is_done = mesh_2d.Compute() + assert is_done + smesh.SetName(mesh_2d, 'Maillage_1') - # tmp_dir = tempfile.mkdtemp() with tempfile.TemporaryDirectory() as tmp_dir: - mesh_file = path.join(tmp_dir, "mesh.med") - shape_file = path.join(tmp_dir, "shape.step") - param_file = path.join(tmp_dir, "param.txt") - output_mesh = path.join(tmp_dir, "mesh3D.med") + mesh_file = path.join(tmp_dir, "mesh.med") + shape_file = path.join(tmp_dir, "shape.step") + param_file = path.join(tmp_dir, "param.txt") + output_mesh = path.join(tmp_dir, "mesh3D.med") - print("Running in folder: ", tmp_dir) - create_param_file(param_file) + print("Running in folder: ", tmp_dir) + create_param_file(param_file) - Mesh2D.ExportMED(mesh_file, 0, 41, 1, Mesh2D, 1, [], '', -1, 1) - geompy.ExportSTEP(box, shape_file, GEOM.LU_METER) + mesh_2d.ExportMED(mesh_file, 0, 41, 1, mesh_2d, 1, [], '', -1, 1) + geompy.ExportSTEP(box, shape_file, GEOM.LU_METER) - runner = path.join("${NETGENPLUGIN_ROOT_DIR}", - "bin", - "salome", - "NETGENPlugin_Runner") + runner = path.join("${NETGENPLUGIN_ROOT_DIR}", + "bin", + "salome", + "NETGENPlugin_Runner") - cmd = "{runner} NETGEN3D {mesh_file} {shape_file} "\ - "{param_file} NONE 2 NONE {output_mesh}"\ - .format(runner=runner, - mesh_file=mesh_file, - shape_file=shape_file, - param_file=param_file, - output_mesh=output_mesh) - print(cmd) - subprocess.check_call(cmd, shell=True) + if sys.platform == 'win32': + runner += ".exe" - meshRead = mc.ReadUMeshFromFile (output_mesh, "MESH", 0) + cmd = "{runner} NETGEN3D {mesh_file} {shape_file} "\ + "{param_file} NONE NONE {output_mesh}"\ + .format(runner=runner, + mesh_file=mesh_file, + shape_file=shape_file, + param_file=param_file, + output_mesh=output_mesh) + print(cmd) + subprocess.check_call(cmd, shell=True) - nbTetras = meshRead.getNumberOfCellsWithType(mc.NORM_TETRA4) - nbPoints = meshRead.getNumberOfNodes() + mesh_read = mc.ReadUMeshFromFile(output_mesh, "MESH", 0) - meshRead = mc.ReadUMeshFromFile (output_mesh, "MESH", -1) - nbTriangles = meshRead.getNumberOfCellsWithType(mc.NORM_TRI3) + nb_tetras = mesh_read.getNumberOfCellsWithType(mc.NORM_TETRA4) + nb_points = mesh_read.getNumberOfNodes() - meshRead = mc.ReadUMeshFromFile (output_mesh, "MESH", -2) - nbSegments = meshRead.getNumberOfCellsWithType(mc.NORM_SEG2) + mesh_read = mc.ReadUMeshFromFile(output_mesh, "MESH", -1) + nb_triangles = mesh_read.getNumberOfCellsWithType(mc.NORM_TRI3) - print("Nb Tetras:", nbTetras) - print("Nb Triangles:", nbTriangles) - print("Nb Segments:", nbSegments) - print("Nb Points:", nbPoints) + mesh_read = mc.ReadUMeshFromFile(output_mesh, "MESH", -2) + nb_segments = mesh_read.getNumberOfCellsWithType(mc.NORM_SEG2) - assert(nbPoints > 0) - assert(nbSegments > 0) - assert(nbTriangles > 0) - assert(nbTetras > 0) + print("Nb Tetras:", nb_tetras) + print("Nb Triangles:", nb_triangles) + print("Nb Segments:", nb_segments) + print("Nb Points:", nb_points) + + assert nb_points > 0 + assert nb_segments > 0 + assert nb_triangles > 0 + assert nb_tetras > 0 if __name__ == "__main__": test_netgen3d() diff --git a/test/tests.set b/test/tests.set index 4664c6a51..2c2d901c8 100644 --- a/test/tests.set +++ b/test/tests.set @@ -64,6 +64,7 @@ SET(BAD_TESTS SMESH_test4.py SMESH_create_dual_mesh_adapt.py netgen_runner.py + SMESH_ParallelCompute.py ) IF(NOT WIN32) LIST(APPEND BAD_TESTS From e2a0dc78153ac4e077cea9f319282f28096dff1c Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Tue, 4 Oct 2022 14:33:09 +0200 Subject: [PATCH 26/29] Adding comments --- src/SMESH/SMESH_Gen.cxx | 15 +++++++++++++-- src/SMESH/SMESH_MeshLocker.cxx | 6 ++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index 922a6df95..2a7e23af9 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -161,6 +161,11 @@ SMESH_Mesh* SMESH_Gen::CreateMesh(bool theIsEmbeddedMode) } +//============================================================================= +/*! + * Algo to run the computation of all the submeshes of a mesh in sequentila + */ +//============================================================================= bool SMESH_Gen::sequentialComputeSubMeshes( SMESH_Mesh & aMesh, @@ -225,8 +230,8 @@ bool SMESH_Gen::sequentialComputeSubMeshes( //============================================================================= /* - * Parallel compute of a submesh - * This function is used to pass to thread_pool + * compute of a submesh + * This function is passed to the thread pool */ //============================================================================= const std::functionLock(); } +/* + * When freed will run the command Unlock from the SMESH_Mesh associated + */ SMESH_MeshLocker::~SMESH_MeshLocker() { _myMesh->Unlock(); From 60aec28a5528da6969b1bb90310a0bf1a4d2fa59 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Mon, 10 Oct 2022 10:54:28 +0200 Subject: [PATCH 27/29] Replacing std::mutex by boost::mutex as std::mutex is not on S10 --- src/SMESH/SMESH_Mesh.hxx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx index ed897979f..18da4e93f 100644 --- a/src/SMESH/SMESH_Mesh.hxx +++ b/src/SMESH/SMESH_Mesh.hxx @@ -47,8 +47,10 @@ #include #include #include + #include #include +#include #ifdef WIN32 #pragma warning(disable:4251) // Warning DLL Interface ... @@ -451,7 +453,7 @@ protected: TCallUp* _callUp; // Mutex for multhitreading write in SMESH_Mesh - std::mutex _my_lock; + boost::mutex _my_lock; int _NbThreads=0; protected: From c8f2626526f8bd2a5a5eb14c6e35876312a8539e Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Wed, 12 Oct 2022 11:24:26 +0200 Subject: [PATCH 28/29] Minor corrections for debug messages --- src/SMESH/SMESH_Mesh.cxx | 3 ++- src/SMESH/SMESH_subMesh.cxx | 11 ++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index bd101248c..077fd7f44 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -242,8 +242,9 @@ SMESH_Mesh::~SMESH_Mesh() if(_pool) DeletePoolThreads(); - if (!MYDEBUG) +#ifndef _DEBUG_ fs::remove_all(tmp_folder); +#endif } //================================================================================ diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index ace4c6f1f..76dfb83e1 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -63,10 +63,9 @@ using namespace std; #ifdef _DEBUG_ // enable printing algo + shape id + hypo used while meshing -//#define PRINT_WHO_COMPUTE_WHAT +#define PRINT_WHO_COMPUTE_WHAT #endif -//#define PRINT_WHO_COMPUTE_WHAT //============================================================================= /*! * \brief Allocate some memory at construction and release it at destruction. @@ -1646,11 +1645,9 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) #ifdef PRINT_WHO_COMPUTE_WHAT for (subS.ReInit(); subS.More(); subS.Next()) { - const std::list & hyps - { - SMESH_MeshLocker myLocker(_father); - hyps = _algo->GetUsedHypothesis( *_father, _subShape ); - } + SMESH_MeshLocker myLocker(_father); + const std::list & hyps = + _algo->GetUsedHypothesis( *_father, _subShape ); SMESH_Comment hypStr; if ( !hyps.empty() ) { From f2b02943880a7cd46c6c91d70cbc628cae4fb421 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Tue, 18 Oct 2022 15:23:33 +0200 Subject: [PATCH 29/29] Restoring comment of unregister to investigate --- src/SMESH_SWIG/smeshBuilder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index ee22a96bd..ec65b9fa9 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -1657,7 +1657,7 @@ class Mesh(metaclass = MeshMeta): Destructor. Clean-up resources """ if self.mesh: - self.mesh.UnRegister() + #self.mesh.UnRegister() pass pass