X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FNETGENPlugin%2FNETGENPlugin_NETGEN_3D.cxx;h=11f0adf40d49e4e66f5b4652a2e5c87aa2572bcc;hb=638fecd6a5b87f817e9df299dfb31b4990332e4d;hp=347f4c3888296292d0064852d11b4460d36cf587;hpb=2e8bc3b2b025120798d2d3178e949b9969f705f5;p=plugins%2Fnetgenplugin.git diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx index 347f4c3..11f0adf 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx @@ -32,8 +32,6 @@ #include "NETGENPlugin_Hypothesis.hxx" -#include "NETGENPlugin_DriverParam.hxx" - #include #include #include @@ -47,10 +45,6 @@ #include #include #include -#include -#include -#include - #include #include @@ -69,10 +63,6 @@ #include #include -#include -#include -namespace fs = boost::filesystem; - /* Netgen include files */ @@ -105,7 +95,7 @@ using namespace std; //============================================================================= /*! - * + * */ //============================================================================= @@ -129,7 +119,7 @@ NETGENPlugin_NETGEN_3D::NETGENPlugin_NETGEN_3D(int hypId, SMESH_Gen* gen) //============================================================================= /*! - * + * */ //============================================================================= @@ -139,7 +129,7 @@ NETGENPlugin_NETGEN_3D::~NETGENPlugin_NETGEN_3D() //============================================================================= /*! - * + * */ //============================================================================= @@ -153,8 +143,8 @@ bool NETGENPlugin_NETGEN_3D::CheckHypothesis (SMESH_Mesh& aMesh, _maxElementVolume = DBL_MAX; // for correct work of GetProgress(): - //netgen::multithread.percent = 0.; - //netgen::multithread.task = "Volume meshing"; + netgen::multithread.percent = 0.; + netgen::multithread.task = "Volume meshing"; _progressByTic = -1.; list::const_iterator itl; @@ -196,256 +186,6 @@ bool NETGENPlugin_NETGEN_3D::CheckHypothesis (SMESH_Mesh& aMesh, return aStatus == HYP_OK; } - -void NETGENPlugin_NETGEN_3D::fillParameters(const NETGENPlugin_Hypothesis* hyp, netgen_params &aParams) -{ - aParams.maxh = hyp->GetMaxSize(); - aParams.minh = hyp->GetMinSize(); - aParams.segmentsperedge = hyp->GetNbSegPerEdge(); - aParams.grading = hyp->GetGrowthRate(); - aParams.curvaturesafety = hyp->GetNbSegPerRadius(); - aParams.secondorder = hyp->GetSecondOrder() ? 1 : 0; - aParams.quad = hyp->GetQuadAllowed() ? 1 : 0; - aParams.optimize = hyp->GetOptimize(); - aParams.fineness = hyp->GetFineness(); - aParams.uselocalh = hyp->GetSurfaceCurvature(); - aParams.merge_solids = hyp->GetFuseEdges(); - aParams.chordalError = hyp->GetChordalErrorEnabled() ? hyp->GetChordalError() : -1.; - aParams.optsteps2d = aParams.optimize ? hyp->GetNbSurfOptSteps() : 0; - aParams.optsteps3d = aParams.optimize ? hyp->GetNbVolOptSteps() : 0; - aParams.elsizeweight = hyp->GetElemSizeWeight(); - aParams.opterrpow = hyp->GetWorstElemMeasure(); - aParams.delaunay = hyp->GetUseDelauney(); - aParams.checkoverlap = hyp->GetCheckOverlapping(); - aParams.checkchartboundary = hyp->GetCheckChartBoundary(); -#ifdef NETGEN_V6 - // std::string - aParams.meshsizefilename = hyp->GetMeshSizeFile(); -#else - // const char* - aParams.meshsizefilename = hyp->GetMeshSizeFile(); -#endif -#ifdef NETGEN_V6 - aParams.closeedgefac = 2; -#else - aParams.closeedgefac = 0; -#endif -} - -// write in a binary file the orientation for each 2D element of the mesh -void NETGENPlugin_NETGEN_3D::exportElementOrientation(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape, - netgen_params& aParams, - const std::string output_file) -{ - SMESH_MesherHelper helper(aMesh); - NETGENPlugin_Internals internals( aMesh, aShape, /*is3D=*/true ); - SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( aMesh )); - std::map elemOrientation; - - for ( TopExp_Explorer exFa( aShape, TopAbs_FACE ); exFa.More(); exFa.Next()) - { - const TopoDS_Shape& aShapeFace = exFa.Current(); - int faceID = aMesh.GetMeshDS()->ShapeToIndex( aShapeFace ); - bool isInternalFace = internals.isInternalShape( faceID ); - bool isRev = false; - if ( !isInternalFace && - helper.NbAncestors(aShapeFace, aMesh, aShape.ShapeType()) > 1 ) - // IsReversedSubMesh() can work wrong on strongly curved faces, - // so we use it as less as possible - isRev = helper.IsReversedSubMesh( TopoDS::Face( aShapeFace )); - - const SMESHDS_SubMesh * aSubMeshDSFace = proxyMesh->GetSubMesh( aShapeFace ); - if ( !aSubMeshDSFace ) continue; - - SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements(); - if ( aParams._quadraticMesh && - dynamic_cast< const SMESH_ProxyMesh::SubMesh*>( aSubMeshDSFace )) - { - // add medium nodes of proxy triangles to helper (#16843) - while ( iteratorElem->more() ) - helper.AddTLinks( static_cast< const SMDS_MeshFace* >( iteratorElem->next() )); - - iteratorElem = aSubMeshDSFace->GetElements(); - } - while ( iteratorElem->more() ) // loop on elements on a geom face - { - // check mesh face - const SMDS_MeshElement* elem = iteratorElem->next(); - if ( !elem ) - error( COMPERR_BAD_INPUT_MESH, "Null element encounters"); - if ( elem->NbCornerNodes() != 3 ) - error( COMPERR_BAD_INPUT_MESH, "Not triangle element encounters"); - elemOrientation[elem->GetID()] = isRev; - } // loop on elements on a face - } // loop on faces of a SOLID or SHELL - - { - std::ofstream df(output_file, ios::out|ios::binary); - int size=elemOrientation.size(); - - df.write((char*)&size, sizeof(int)); - for(auto const& [id, orient]:elemOrientation){ - df.write((char*)&id, sizeof(vtkIdType)); - df.write((char*)&orient, sizeof(bool)); - } - } -} - -int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape) -{ - aMesh.Lock(); - auto time0 = std::chrono::high_resolution_clock::now(); - SMESH_Hypothesis::Hypothesis_Status hypStatus; - CheckHypothesis(aMesh, aShape, hypStatus); - auto time1 = std::chrono::high_resolution_clock::now(); - auto elapsed = std::chrono::duration_cast(time1-time0); - std::cout << "Time for check_hypo: " << elapsed.count() * 1e-9 << std::endl; - - - // Temporary folder for run - fs::path tmp_folder = aMesh.tmp_folder / fs::unique_path(fs::path("Volume-%%%%-%%%%")); - fs::create_directories(tmp_folder); - // Using MESH2D generated after all triangles where created. - fs::path mesh_file=aMesh.tmp_folder / fs::path("Mesh2D.med"); - fs::path element_orientation_file=tmp_folder / fs::path("element_orientation.dat"); - fs::path new_element_file=tmp_folder / fs::path("new_elements.dat"); - fs::path tmp_mesh_file=tmp_folder / fs::path("tmp_mesh.med"); - // TODO: Remove that file we do not use it - fs::path output_mesh_file=tmp_folder / fs::path("output_mesh.med"); - fs::path shape_file=tmp_folder / fs::path("shape.step"); - fs::path param_file=tmp_folder / fs::path("netgen3d_param.txt"); - fs::path log_file=tmp_folder / fs::path("run.log"); - //TODO: Handle variable mesh_name - std::string mesh_name = "Maillage_1"; - - //Writing Shape - exportShape(shape_file.string(), aShape); - auto time2 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time2-time1); - std::cout << "Time for exportShape: " << elapsed.count() * 1e-9 << std::endl; - - //Writing hypo - netgen_params aParams; - fillParameters(_hypParameters, aParams); - - exportNetgenParams(param_file.string(), aParams); - auto time3 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time3-time2); - std::cout << "Time for fill+export param: " << elapsed.count() * 1e-9 << std::endl; - - // Exporting element orientation - exportElementOrientation(aMesh, aShape, aParams, element_orientation_file.string()); - auto time4 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time4-time3); - std::cout << "Time for exportElemOrient: " << elapsed.count() * 1e-9 << std::endl; - - aMesh.Unlock(); - // Calling run_mesher - // TODO: check if we need to handle the .exe for windows - std::string cmd; - fs::path run_mesher_exe = - fs::path(std::getenv("NETGENPLUGIN_ROOT_DIR"))/ - fs::path("bin")/ - fs::path("salome")/ - fs::path("NETGENPlugin_Runner"); - cmd = run_mesher_exe.string() + - " NETGEN3D " + mesh_file.string() + " " - + shape_file.string() + " " - + param_file.string() + " " - + element_orientation_file.string() + " " - + std::to_string(aMesh.GetMesherNbThreads()) + " " - + new_element_file.string() + " " - + "NONE" + - " >> " + log_file.string(); - - //std::cout << "Running command: " << std::endl; - //std::cout << cmd << std::endl; - - // Writing command in log - { - std::ofstream flog(log_file.string()); - flog << cmd << endl; - } - // TODO: Replace system by something else to handle redirection for windows - int ret = system(cmd.c_str()); - auto time5 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time5-time4); - std::cout << "Time for exec of run_mesher: " << elapsed.count() * 1e-9 << std::endl; - - // TODO: better error handling (display log ?) - if(ret != 0){ - // Run crahed - std::cerr << "Issue with command: " << std::endl; - std::cerr << cmd << std::endl; - return false; - } - - aMesh.Lock(); - { - std::ifstream df(new_element_file.string(), ios::binary); - - int Netgen_NbOfNodes; - int Netgen_NbOfNodesNew; - int Netgen_NbOfTetra; - double Netgen_point[3]; - int Netgen_tetrahedron[4]; - int nodeID; - - SMESH_MesherHelper helper(aMesh); - // This function - int _quadraticMesh = helper.IsQuadraticSubMesh(aShape); - helper.SetElementsOnShape( true ); - - // Number of nodes in intial mesh - df.read((char*) &Netgen_NbOfNodes, sizeof(int)); - // Number of nodes added by netgen - df.read((char*) &Netgen_NbOfNodesNew, sizeof(int)); - - // Filling nodevec (correspondence netgen numbering mesh numbering) - vector< const SMDS_MeshNode* > nodeVec ( Netgen_NbOfNodesNew + 1 ); - //vector nodeTmpVec ( Netgen_NbOfNodesNew + 1 ); - SMESHDS_Mesh * meshDS = helper.GetMeshDS(); - for (int nodeIndex = 1 ; nodeIndex <= Netgen_NbOfNodes; ++nodeIndex ) - { - //Id of the point - df.read((char*) &nodeID, sizeof(int)); - nodeVec.at(nodeIndex) = meshDS->FindNode(nodeID); - } - - // Add new points and update nodeVec - for (int nodeIndex = Netgen_NbOfNodes +1 ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) - { - df.read((char *) &Netgen_point, sizeof(double)*3); - - nodeVec.at(nodeIndex) = helper.AddNode(Netgen_point[0], - Netgen_point[1], - Netgen_point[2]); - } - - // Add tetrahedrons - df.read((char*) &Netgen_NbOfTetra, sizeof(int)); - - for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex ) - { - df.read((char*) &Netgen_tetrahedron, sizeof(int)*4); - helper.AddVolume( - nodeVec.at( Netgen_tetrahedron[0] ), - nodeVec.at( Netgen_tetrahedron[1] ), - nodeVec.at( Netgen_tetrahedron[2] ), - nodeVec.at( Netgen_tetrahedron[3] )); - } - } - auto time7 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time7-time5); - std::cout << "Time for exec of add_in_mesh: " << elapsed.count() * 1e-9 << std::endl; - - aMesh.Unlock(); - - return true; -} - //============================================================================= /*! *Here we are going to use the NETGEN mesher @@ -455,10 +195,6 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) { - if(aMesh.IsParallel()) - return RemoteCompute(aMesh, aShape); - auto time0 = std::chrono::high_resolution_clock::now(); - netgen::multithread.terminate = 0; netgen::multithread.task = "Volume meshing"; _progressByTic = -1.; @@ -612,11 +348,8 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, // ------------------------- // Generate the volume mesh // ------------------------- - auto time1 = std::chrono::high_resolution_clock::now(); - auto elapsed = std::chrono::duration_cast(time1-time0); - std::cout << "Time for seq:fill_in_ngmesh: " << elapsed.count() * 1e-9 << std::endl; - return (ngLib._isComputeOk = compute( aMesh, helper, nodeVec, ngLib )); + return ( ngLib._isComputeOk = compute( aMesh, helper, nodeVec, ngLib )); } // namespace @@ -702,8 +435,6 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, vector< const SMDS_MeshNode* >& nodeVec, NETGENPlugin_NetgenLibWrapper& ngLib) { - auto time0 = std::chrono::high_resolution_clock::now(); - netgen::multithread.terminate = 0; netgen::Mesh* ngMesh = ngLib._ngMesh; @@ -744,7 +475,7 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, else if ( _hypMaxElementVolume ) { netgen::mparam.maxh = pow( 72, 1/6. ) * pow( _maxElementVolume, 1/3. ); - // limitVolumeSize( ngMesh, mparam.maxh ); // result is unpredictable + // limitVolumeSize( ngMesh, netgen::mparam.maxh ); // result is unpredictable } else if ( aMesh.HasShapeToMesh() ) { @@ -766,7 +497,6 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, try { OCC_CATCH_SIGNALS; - auto time0 = std::chrono::high_resolution_clock::now(); ngLib.CalcLocalH(ngMesh); err = ngLib.GenerateMesh(occgeo, startWith, endWith); @@ -800,9 +530,6 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, str << " at " << netgen::multithread.task; error(str); } - auto time1 = std::chrono::high_resolution_clock::now(); - auto elapsed = std::chrono::duration_cast(time1-time0); - std::cout << "Time for seq:compute: " << elapsed.count() * 1e-9 << std::endl; int Netgen_NbOfNodesNew = Ng_GetNP(Netgen_mesh); int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh); @@ -849,10 +576,6 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, } } } - auto time2 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time2-time1); - std::cout << "Time for seq:compute: " << elapsed.count() * 1e-9 << std::endl; - return !err; } @@ -918,7 +641,7 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, return error( COMPERR_BAD_INPUT_MESH, "Null element encounters"); if ( elem->NbCornerNodes() != 3 ) return error( COMPERR_BAD_INPUT_MESH, "Not triangle element encounters"); - + // add three nodes of triangle for ( int iN = 0; iN < 3; ++iN ) { @@ -1074,7 +797,7 @@ bool NETGENPlugin_NETGEN_3D::Evaluate(SMESH_Mesh& aMesh, } SMESH_subMesh *sm = aMesh.GetSubMesh(aShape); aResMap.insert(std::make_pair(sm,aVec)); - + return true; }