From 63d1380bdbf83e7f663d5d3ce32ecea2fe1f74b3 Mon Sep 17 00:00:00 2001 From: Bryn Lloyd Date: Wed, 27 Feb 2019 20:32:57 +0100 Subject: [PATCH] add Ng_OptimizeVolume add Ng_AddLockedPoint extend API so user can set/get domain for element (optional -> does not break existing API) the commit also (optionally) allows to send log messages (cout, cerr, testout) to a Null stream buffer. this allows applications to make netgen quiet --- nglib/nglib.cpp | 119 +++++++++++++++++++++++++++++++++++++----------- nglib/nglib.h | 29 ++++++++---- 2 files changed, 112 insertions(+), 36 deletions(-) diff --git a/nglib/nglib.cpp b/nglib/nglib.cpp index 54fff096..8f6be7cd 100644 --- a/nglib/nglib.cpp +++ b/nglib/nglib.cpp @@ -23,8 +23,6 @@ #include #endif -#include - namespace netgen { extern void MeshFromSpline2D (SplineGeometry2d & geometry, @@ -73,16 +71,26 @@ using namespace netgen; namespace nglib { - inline void NOOP_Deleter(void *) { ; } + inline void NOOP_Deleter(void *) { ; } - - // initialize, deconstruct Netgen library: - DLL_HEADER void Ng_Init () + class NullStreambuf : public std::streambuf { - mycout = &cout; - myerr = &cerr; - // netgen::testout->SetOutStream (new ofstream ("test.out")); - testout = new ofstream ("test.out"); + char dummyBuffer[64]; + protected: + virtual int overflow(int c) + { + setp(dummyBuffer, dummyBuffer + sizeof(dummyBuffer)); + return (c == traits_type::eof()) ? '\0' : c; + } + }; + + // initialize, deconstruct Netgen library: + DLL_HEADER void Ng_Init (bool cout_to_null, bool cerr_to_null, bool testout_to_null) + { + static ostream* null_stream = new ostream(new NullStreambuf); + mycout = cout_to_null ? null_stream : &cout; + myerr = cerr_to_null ? null_stream : &cerr; + testout = testout_to_null ? null_stream : new ofstream("test.out"); } @@ -205,18 +213,39 @@ namespace nglib } + // Manually lock a specific point + DLL_HEADER void Ng_AddLockedPoint(Ng_Mesh * mesh, int pi) + { + Mesh * m = (Mesh*)mesh; + m->AddLockedPoint(pi); + } // Manually add a surface element of a given type to an existing mesh object DLL_HEADER void Ng_AddSurfaceElement (Ng_Mesh * mesh, Ng_Surface_Element_Type et, - int * pi) + int * pi, int domain) { + int n = 3; + switch (et) + { + case NG_TRIG: + n = 3; break; + case NG_QUAD: + n = 4; break; + case NG_QUAD6: + n = 6; break; + case NG_TRIG6: + n = 6; break; + case NG_QUAD8: + n = 8; break; + default: break; + } + Mesh * m = (Mesh*)mesh; - Element2d el (3); - el.SetIndex (1); - el.PNum(1) = pi[0]; - el.PNum(2) = pi[1]; - el.PNum(3) = pi[2]; + Element2d el (n); + el.SetIndex (domain); + for (int i=0; iAddSurfaceElement (el); } @@ -225,15 +254,27 @@ namespace nglib // Manually add a volume element of a given type to an existing mesh object DLL_HEADER void Ng_AddVolumeElement (Ng_Mesh * mesh, Ng_Volume_Element_Type et, - int * pi) + int * pi, int domain) { + int n = 4; + switch (et) + { + case NG_TET: + n = 4; break; + case NG_PYRAMID: + n = 5; break; + case NG_PRISM: + n = 6; break; + case NG_TET10: + n = 10; break; + default: break; + } + Mesh * m = (Mesh*)mesh; - Element el (4); - el.SetIndex (1); - el.PNum(1) = pi[0]; - el.PNum(2) = pi[1]; - el.PNum(3) = pi[2]; - el.PNum(4) = pi[3]; + Element el (n); + el.SetIndex (domain); + for (int i=0; iAddVolumeElement (el); } @@ -281,7 +322,7 @@ namespace nglib // Return the surface element at a given index "pi" DLL_HEADER Ng_Surface_Element_Type - Ng_GetSurfaceElement (Ng_Mesh * mesh, int num, int * pi) + Ng_GetSurfaceElement (Ng_Mesh * mesh, int num, int * pi, int * domain) { const Element2d & el = ((Mesh*)mesh)->SurfaceElement(num); for (int i = 1; i <= el.GetNP(); i++) @@ -304,6 +345,8 @@ namespace nglib default: et = NG_TRIG; break; // for the compiler } + if (domain) + *domain = el.GetIndex(); return et; } @@ -312,7 +355,7 @@ namespace nglib // Return the volume element at a given index "pi" DLL_HEADER Ng_Volume_Element_Type - Ng_GetVolumeElement (Ng_Mesh * mesh, int num, int * pi) + Ng_GetVolumeElement (Ng_Mesh * mesh, int num, int * pi, int * domain) { const Element & el = ((Mesh*)mesh)->VolumeElement(num); for (int i = 1; i <= el.GetNP(); i++) @@ -327,6 +370,8 @@ namespace nglib default: et = NG_TET; break; // for the compiler } + if (domain) + *domain = el.GetIndex(); return et; } @@ -386,6 +431,24 @@ namespace nglib + // Optimize existing mesh + DLL_HEADER Ng_Result Ng_OptimizeVolume(Ng_Mesh *mesh, Ng_Meshing_Parameters *mp) + { + Mesh * m = (Mesh*)mesh; + + mp->Transfer_Parameters(); + + m->CalcLocalH(mparam.grading); + + RemoveIllegalElements(*m); + OptimizeVolume(mparam, *m); + + return NG_OK; + } + + + + /* ------------------ 2D Meshing Functions ------------------------- */ DLL_HEADER void Ng_AddPoint_2D (Ng_Mesh * mesh, double * x) { @@ -397,14 +460,16 @@ namespace nglib - DLL_HEADER void Ng_AddBoundarySeg_2D (Ng_Mesh * mesh, int pi1, int pi2) + DLL_HEADER void Ng_AddBoundarySeg_2D (Ng_Mesh * mesh, int pi1, int pi2, int domain_in, int domain_out) { Mesh * m = (Mesh*)mesh; Segment seg; seg[0] = pi1; seg[1] = pi2; - m->AddSegment (seg); + seg.domin = domain_in; + seg.domout = domain_out; + m->AddSegment(seg); } diff --git a/nglib/nglib.h b/nglib/nglib.h index 8a78da07..da3bee50 100644 --- a/nglib/nglib.h +++ b/nglib/nglib.h @@ -193,7 +193,7 @@ public: program before beginning to use the other Netgen specific functions. */ -DLL_HEADER void Ng_Init (); +DLL_HEADER void Ng_Init (bool cout_to_null = false, bool cerr_to_null = false, bool testout_to_null = false); /*! \brief Exit the Netgen meshing kernel in a clean manner @@ -312,6 +312,11 @@ DLL_HEADER Ng_Result Ng_MergeMesh(Ng_Mesh * mesh1, Ng_Mesh * mesh2); DLL_HEADER void Ng_AddPoint (Ng_Mesh * mesh, double * x); +/*! Add locked point which should not get modified by optimization routines + +*/ +DLL_HEADER void Ng_AddLockedPoint(Ng_Mesh * mesh, int pi); + /*! \brief Add a surface element to a given Netgen Mesh Structure This function allows the top-level code to directly add individual @@ -332,7 +337,7 @@ DLL_HEADER void Ng_AddPoint (Ng_Mesh * mesh, double * x); \param pi Pointer to an array of integers containing the indices of the points which constitute the surface element being added */ -DLL_HEADER void Ng_AddSurfaceElement (Ng_Mesh * mesh, Ng_Surface_Element_Type et, int * pi); +DLL_HEADER void Ng_AddSurfaceElement (Ng_Mesh * mesh, Ng_Surface_Element_Type et, int * pi, int domain=1); /*! \brief Add a volume element to a given Netgen Mesh Structure @@ -356,7 +361,7 @@ DLL_HEADER void Ng_AddSurfaceElement (Ng_Mesh * mesh, Ng_Surface_Element_Type et points which constitute the volume element being added */ -DLL_HEADER void Ng_AddVolumeElement (Ng_Mesh * mesh, Ng_Volume_Element_Type et, int * pi); +DLL_HEADER void Ng_AddVolumeElement (Ng_Mesh * mesh, Ng_Volume_Element_Type et, int * pi, int domain=1); // ------------------------------------------------------------------ @@ -471,6 +476,12 @@ DLL_HEADER void Ng_RestrictMeshSizeBox (Ng_Mesh * mesh, double * pmin, double * */ DLL_HEADER Ng_Result Ng_GenerateVolumeMesh (Ng_Mesh * mesh, Ng_Meshing_Parameters * mp); + +/*! \brief Improve quality of an existing 3D Volume Mesh + +*/ +DLL_HEADER Ng_Result Ng_OptimizeVolume(Ng_Mesh *mesh, Ng_Meshing_Parameters *mp); + // ------------------------------------------------------------------ @@ -536,10 +547,10 @@ DLL_HEADER void Ng_GetPoint (Ng_Mesh * mesh, int num, double * x); // return surface and volume element in pi DLL_HEADER Ng_Surface_Element_Type -Ng_GetSurfaceElement (Ng_Mesh * mesh, int num, int * pi); +Ng_GetSurfaceElement (Ng_Mesh * mesh, int num, int * pi, int * domain = nullptr); DLL_HEADER Ng_Volume_Element_Type -Ng_GetVolumeElement (Ng_Mesh * mesh, int num, int * pi); +Ng_GetVolumeElement (Ng_Mesh * mesh, int num, int * pi, int * domain = nullptr); // ------------------------------------------------------------------ @@ -554,7 +565,7 @@ Ng_GetVolumeElement (Ng_Mesh * mesh, int num, int * pi); // feeds points and boundary to mesh DLL_HEADER void Ng_AddPoint_2D (Ng_Mesh * mesh, double * x); -DLL_HEADER void Ng_AddBoundarySeg_2D (Ng_Mesh * mesh, int pi1, int pi2); +DLL_HEADER void Ng_AddBoundarySeg_2D (Ng_Mesh * mesh, int pi1, int pi2, int domain_in = -1, int domain_out = -1); // ask for number of points, elements and boundary segments DLL_HEADER int Ng_GetNP_2D (Ng_Mesh * mesh); @@ -566,10 +577,10 @@ DLL_HEADER void Ng_GetPoint_2D (Ng_Mesh * mesh, int num, double * x); // return 2d elements DLL_HEADER Ng_Surface_Element_Type -Ng_GetElement_2D (Ng_Mesh * mesh, int num, int * pi, int * matnum = NULL); +Ng_GetElement_2D (Ng_Mesh * mesh, int num, int * pi, int * matnum = nullptr); // return 2d boundary segment -DLL_HEADER void Ng_GetSegment_2D (Ng_Mesh * mesh, int num, int * pi, int * matnum = NULL); +DLL_HEADER void Ng_GetSegment_2D (Ng_Mesh * mesh, int num, int * pi, int * matnum = nullptr); // load 2d netgen spline geometry @@ -606,7 +617,7 @@ DLL_HEADER Ng_STL_Geometry * Ng_STL_NewGeometry (); // normal vector may be null-pointer DLL_HEADER void Ng_STL_AddTriangle (Ng_STL_Geometry * geom, double * p1, double * p2, double * p3, - double * nv = NULL); + double * nv = nullptr); // add (optional) edges : DLL_HEADER void Ng_STL_AddEdge (Ng_STL_Geometry * geom,