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
This commit is contained in:
Bryn Lloyd 2019-02-27 20:32:57 +01:00
parent fa1353dd07
commit 63d1380bdb
2 changed files with 112 additions and 36 deletions

View File

@ -23,8 +23,6 @@
#include <occgeom.hpp> #include <occgeom.hpp>
#endif #endif
#include <nginterface.h>
namespace netgen { namespace netgen {
extern void MeshFromSpline2D (SplineGeometry2d & geometry, extern void MeshFromSpline2D (SplineGeometry2d & geometry,
@ -73,16 +71,26 @@ using namespace netgen;
namespace nglib namespace nglib
{ {
inline void NOOP_Deleter(void *) { ; } inline void NOOP_Deleter(void *) { ; }
class NullStreambuf : public std::streambuf
{
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: // initialize, deconstruct Netgen library:
DLL_HEADER void Ng_Init () DLL_HEADER void Ng_Init (bool cout_to_null, bool cerr_to_null, bool testout_to_null)
{ {
mycout = &cout; static ostream* null_stream = new ostream(new NullStreambuf);
myerr = &cerr; mycout = cout_to_null ? null_stream : &cout;
// netgen::testout->SetOutStream (new ofstream ("test.out")); myerr = cerr_to_null ? null_stream : &cerr;
testout = new ofstream ("test.out"); 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 // 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, 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; Mesh * m = (Mesh*)mesh;
Element2d el (3); Element2d el (n);
el.SetIndex (1); el.SetIndex (domain);
el.PNum(1) = pi[0]; for (int i=0; i<n; ++i)
el.PNum(2) = pi[1]; el.PNum(i+1) = pi[i];
el.PNum(3) = pi[2];
m->AddSurfaceElement (el); m->AddSurfaceElement (el);
} }
@ -225,15 +254,27 @@ namespace nglib
// Manually add a volume element of a given type to an existing mesh object // 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, 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; Mesh * m = (Mesh*)mesh;
Element el (4); Element el (n);
el.SetIndex (1); el.SetIndex (domain);
el.PNum(1) = pi[0]; for (int i=0; i<n; ++i)
el.PNum(2) = pi[1]; el.PNum(i+1) = pi[i];
el.PNum(3) = pi[2];
el.PNum(4) = pi[3];
m->AddVolumeElement (el); m->AddVolumeElement (el);
} }
@ -281,7 +322,7 @@ namespace nglib
// Return the surface element at a given index "pi" // Return the surface element at a given index "pi"
DLL_HEADER Ng_Surface_Element_Type 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); const Element2d & el = ((Mesh*)mesh)->SurfaceElement(num);
for (int i = 1; i <= el.GetNP(); i++) for (int i = 1; i <= el.GetNP(); i++)
@ -304,6 +345,8 @@ namespace nglib
default: default:
et = NG_TRIG; break; // for the compiler et = NG_TRIG; break; // for the compiler
} }
if (domain)
*domain = el.GetIndex();
return et; return et;
} }
@ -312,7 +355,7 @@ namespace nglib
// Return the volume element at a given index "pi" // Return the volume element at a given index "pi"
DLL_HEADER Ng_Volume_Element_Type 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); const Element & el = ((Mesh*)mesh)->VolumeElement(num);
for (int i = 1; i <= el.GetNP(); i++) for (int i = 1; i <= el.GetNP(); i++)
@ -327,6 +370,8 @@ namespace nglib
default: default:
et = NG_TET; break; // for the compiler et = NG_TET; break; // for the compiler
} }
if (domain)
*domain = el.GetIndex();
return et; 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 ------------------------- */ /* ------------------ 2D Meshing Functions ------------------------- */
DLL_HEADER void Ng_AddPoint_2D (Ng_Mesh * mesh, double * x) 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; Mesh * m = (Mesh*)mesh;
Segment seg; Segment seg;
seg[0] = pi1; seg[0] = pi1;
seg[1] = pi2; seg[1] = pi2;
m->AddSegment (seg); seg.domin = domain_in;
seg.domout = domain_out;
m->AddSegment(seg);
} }

View File

@ -193,7 +193,7 @@ public:
program before beginning to use the other Netgen program before beginning to use the other Netgen
specific functions. 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 /*! \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); 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 /*! \brief Add a surface element to a given Netgen Mesh Structure
This function allows the top-level code to directly add individual 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 \param pi Pointer to an array of integers containing the indices of the
points which constitute the surface element being added 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 /*! \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 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); 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 // return surface and volume element in pi
DLL_HEADER Ng_Surface_Element_Type 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 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 // feeds points and boundary to mesh
DLL_HEADER void Ng_AddPoint_2D (Ng_Mesh * mesh, double * x); 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 // ask for number of points, elements and boundary segments
DLL_HEADER int Ng_GetNP_2D (Ng_Mesh * mesh); 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 // return 2d elements
DLL_HEADER Ng_Surface_Element_Type 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 // 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 // load 2d netgen spline geometry
@ -606,7 +617,7 @@ DLL_HEADER Ng_STL_Geometry * Ng_STL_NewGeometry ();
// normal vector may be null-pointer // normal vector may be null-pointer
DLL_HEADER void Ng_STL_AddTriangle (Ng_STL_Geometry * geom, DLL_HEADER void Ng_STL_AddTriangle (Ng_STL_Geometry * geom,
double * p1, double * p2, double * p3, double * p1, double * p2, double * p3,
double * nv = NULL); double * nv = nullptr);
// add (optional) edges : // add (optional) edges :
DLL_HEADER void Ng_STL_AddEdge (Ng_STL_Geometry * geom, DLL_HEADER void Ng_STL_AddEdge (Ng_STL_Geometry * geom,