mirror of
https://github.com/NGSolve/netgen.git
synced 2024-11-14 18:08:33 +05:00
395 lines
11 KiB
C++
395 lines
11 KiB
C++
#ifndef FILE_SURFACE
|
|
#define FILE_SURFACE
|
|
|
|
/**************************************************************************/
|
|
/* File: surface.hh */
|
|
/* Author: Joachim Schoeberl */
|
|
/* Date: 1. Dez. 95 */
|
|
/**************************************************************************/
|
|
|
|
|
|
namespace netgen
|
|
{
|
|
|
|
class TriangleApproximation;
|
|
|
|
|
|
/**
|
|
Basis class for implicit surface geometry.
|
|
This class is used for generation of surface meshes
|
|
in NETGEN
|
|
*/
|
|
class Surface
|
|
{
|
|
protected:
|
|
/// invert normal vector
|
|
bool inverse;
|
|
/// maximal h in surface
|
|
double maxh;
|
|
/// name of surface
|
|
char * name;
|
|
/// boundary condition nr
|
|
int bcprop;
|
|
/// boundary condition label
|
|
string bcname;
|
|
|
|
public:
|
|
Surface ();
|
|
/** @name Tangential plane.
|
|
The tangential plane is used for surface mesh generation.
|
|
*/
|
|
|
|
virtual ~Surface();
|
|
|
|
protected:
|
|
/** @name Points in the surface defining tangential plane.
|
|
Tangential plane is taken in p1, the local x-axis
|
|
is directed to p2.
|
|
*/
|
|
//@{
|
|
///
|
|
Point<3> p1;
|
|
///
|
|
Point<3> p2;
|
|
//@}
|
|
/** @name Base-vectos for local coordinate system. */
|
|
//@{
|
|
/// in plane, directed p1->p2
|
|
Vec<3> ex;
|
|
/// in plane
|
|
Vec<3> ey;
|
|
/// outer normal direction
|
|
Vec<3> ez;
|
|
//@}
|
|
public:
|
|
|
|
virtual void DoArchive(Archive& archive)
|
|
{
|
|
archive & inverse & maxh & name & bcprop & bcname
|
|
& p1 & p2 & ex & ey & ez;
|
|
}
|
|
|
|
void SetName (const char * aname);
|
|
const char * Name () const { return name; }
|
|
|
|
//@{
|
|
/**
|
|
Defines tangential plane in ap1.
|
|
The local x-coordinate axis points to the direction of ap2 */
|
|
virtual void DefineTangentialPlane (const Point<3> & ap1,
|
|
const Point<3> & ap2);
|
|
|
|
/// Transforms 3d point p3d to local coordinates pplane
|
|
virtual void ToPlane (const Point<3> & p3d, Point<2> & pplane,
|
|
double h, int & zone) const;
|
|
|
|
/// Transforms point pplane in local coordinates to 3d point
|
|
virtual void FromPlane (const Point<2> & pplane,
|
|
Point<3> & p3d, double h) const;
|
|
//@}
|
|
|
|
|
|
/// Project point p onto surface (closest point)
|
|
virtual void Project (Point<3> & p) const;
|
|
|
|
/// Project along direction
|
|
virtual void SkewProject(Point<3> & p, const Vec<3> & direction) const;
|
|
|
|
/// Is current surface identic to surface 2 ?
|
|
virtual int IsIdentic (const Surface & /* s2 */, int & /* inv */,
|
|
double /* eps */) const
|
|
{ return 0; }
|
|
|
|
///
|
|
virtual int PointOnSurface (const Point<3> & p,
|
|
double eps = 1e-6) const;
|
|
|
|
|
|
/** @name Implicit function.
|
|
Calculate function value and derivatives.
|
|
*/
|
|
//@{
|
|
/// Calculate implicit function value in point point
|
|
virtual double CalcFunctionValue (const Point<3> & point) const = 0;
|
|
|
|
/**
|
|
Calc gradient of implicit function.
|
|
gradient should be O(1) at surface
|
|
*/
|
|
virtual void CalcGradient (const Point<3> & point, Vec<3> & grad) const = 0;
|
|
|
|
/**
|
|
Calculate second derivatives of implicit function.
|
|
*/
|
|
virtual void CalcHesse (const Point<3> & point, Mat<3> & hesse) const;
|
|
|
|
/**
|
|
Returns outer normal vector.
|
|
*/
|
|
// virtual void GetNormalVector (const Point<3> & p, Vec<3> & n) const;
|
|
virtual Vec<3> GetNormalVector (const Point<3> & p) const;
|
|
|
|
/**
|
|
Upper bound for spectral norm of Hesse-matrix
|
|
*/
|
|
virtual double HesseNorm () const = 0;
|
|
|
|
/**
|
|
Upper bound for spectral norm of Hesse-matrix in the
|
|
rad - environment of point c.
|
|
*/
|
|
virtual double HesseNormLoc (const Point<3> & /* c */,
|
|
double /* rad */) const
|
|
{ return HesseNorm (); }
|
|
//@}
|
|
|
|
|
|
///
|
|
virtual double MaxCurvature () const;
|
|
///
|
|
virtual double MaxCurvatureLoc (const Point<3> & /* c */ ,
|
|
double /* rad */) const;
|
|
|
|
/** Returns any point in the surface.
|
|
Needed to start surface mesh generation e.g. on sphere */
|
|
virtual Point<3> GetSurfacePoint () const = 0;
|
|
|
|
///
|
|
bool Inverse () const { return inverse; }
|
|
///
|
|
void SetInverse (bool ainverse) { inverse = ainverse; }
|
|
///
|
|
virtual void Print (ostream & str) const = 0;
|
|
|
|
///
|
|
virtual void Reduce (const BoxSphere<3> & /* box */) { };
|
|
///
|
|
virtual void UnReduce () { };
|
|
|
|
/// set max h in surface
|
|
void SetMaxH (double amaxh) { maxh = amaxh; }
|
|
///
|
|
double GetMaxH () const { return maxh; }
|
|
///
|
|
int GetBCProperty () const { return bcprop; }
|
|
///
|
|
void SetBCProperty (int abc) { bcprop = abc; }
|
|
|
|
/** Determine local mesh-size.
|
|
Find
|
|
\[ h \leq hmax, \]
|
|
such that
|
|
\[ h \times \kappa (x) \leq c \qquad \mbox{in} B(x, h), \]
|
|
where kappa(x) is the curvature in x. */
|
|
virtual double LocH (const Point<3> & p, double x,
|
|
double c,
|
|
const MeshingParameters & mparam,
|
|
double hmax) const;
|
|
|
|
/**
|
|
Gets Approximation by triangles,
|
|
where qual is about the number of triangles per radius
|
|
*/
|
|
virtual void GetTriangleApproximation (TriangleApproximation & /* tas */,
|
|
const Box<3> & /* boundingbox */,
|
|
double /* facets */ ) const { };
|
|
|
|
|
|
string GetBCName() const { return bcname; }
|
|
|
|
void SetBCName( string abc ) { bcname = abc; }
|
|
};
|
|
|
|
|
|
inline ostream & operator<< (ostream & ost, const Surface & surf)
|
|
{
|
|
surf.Print(ost);
|
|
return ost;
|
|
}
|
|
|
|
|
|
|
|
typedef enum { IS_OUTSIDE = 0, IS_INSIDE = 1, DOES_INTERSECT = 2}
|
|
INSOLID_TYPE;
|
|
|
|
|
|
class DummySurface : public Surface
|
|
{
|
|
virtual double CalcFunctionValue (const Point<3> & /* point */) const
|
|
{ return 0; }
|
|
|
|
virtual void CalcGradient (const Point<3> & /* point */, Vec<3> & grad) const
|
|
{ grad = Vec<3> (0,0,0); }
|
|
|
|
virtual Point<3> GetSurfacePoint () const
|
|
{ return Point<3> (0,0,0); }
|
|
|
|
virtual double HesseNorm () const
|
|
{ return 0; }
|
|
|
|
virtual void Project (Point<3> & /* p */) const
|
|
{ ; }
|
|
|
|
virtual void Print (ostream & ost) const
|
|
{ ost << "dummy surface"; }
|
|
};
|
|
|
|
|
|
|
|
class Primitive
|
|
{
|
|
protected:
|
|
NgArray<int> surfaceids;
|
|
NgArray<int> surfaceactive;
|
|
|
|
public:
|
|
|
|
Primitive ();
|
|
|
|
virtual ~Primitive();
|
|
|
|
virtual void DoArchive(Archive& archive)
|
|
{
|
|
archive & surfaceids & surfaceactive;
|
|
}
|
|
|
|
/*
|
|
Check, whether box intersects solid defined by surface.
|
|
|
|
return values:
|
|
0 .. box outside solid \\
|
|
1 .. box in solid \\
|
|
2 .. can't decide (allowed, iff box is close to solid)
|
|
*/
|
|
virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const = 0;
|
|
virtual INSOLID_TYPE PointInSolid (const Point<3> & p,
|
|
double eps) const = 0;
|
|
|
|
virtual void GetTangentialSurfaceIndices (const Point<3> & p,
|
|
NgArray<int> & surfind, double eps) const;
|
|
|
|
virtual INSOLID_TYPE VecInSolid (const Point<3> & p,
|
|
const Vec<3> & v,
|
|
double eps) const = 0;
|
|
|
|
// checks if lim s->0 lim t->0 p + t(v1 + s v2) in solid
|
|
virtual INSOLID_TYPE VecInSolid2 (const Point<3> & p,
|
|
const Vec<3> & v1,
|
|
const Vec<3> & v2,
|
|
double eps) const;
|
|
|
|
// checks if p + s v1 + s*s/2 v2 is inside
|
|
virtual INSOLID_TYPE VecInSolid3 (const Point<3> & p,
|
|
const Vec<3> & v1,
|
|
const Vec<3> & v2,
|
|
double eps) const;
|
|
|
|
// like VecInSolid2, but second order approximation
|
|
virtual INSOLID_TYPE VecInSolid4 (const Point<3> & p,
|
|
const Vec<3> & v,
|
|
const Vec<3> & v2,
|
|
const Vec<3> & m,
|
|
double eps) const;
|
|
|
|
// for a point p in the surface, into which (closed) surfaces does v point into ?
|
|
virtual void GetTangentialVecSurfaceIndices (const Point<3> & p, const Vec<3> & v,
|
|
NgArray<int> & surfind, double eps) const;
|
|
|
|
// a point p in the surface, and v a tangential vector
|
|
// for arbitrary small, but positive t consider q := Project(p+t*v)
|
|
// into which (closed) surfaces does v2 point into, when starting from q ?
|
|
virtual void GetTangentialVecSurfaceIndices2 (const Point<3> & p, const Vec<3> & v1, const Vec<3> & v2,
|
|
NgArray<int> & surfind, double eps) const;
|
|
|
|
|
|
virtual void CalcSpecialPoints (NgArray<Point<3> > & /* pts */) const { ; }
|
|
virtual void AnalyzeSpecialPoint (const Point<3> & /* pt */,
|
|
NgArray<Point<3> > & /* specpts */) const { ; }
|
|
virtual Vec<3> SpecialPointTangentialVector (const Point<3> & /* p */,
|
|
int /* s1 */, int /* s2 */) const
|
|
{ return Vec<3> (0,0,0); }
|
|
|
|
|
|
virtual int GetNSurfaces() const = 0;
|
|
virtual Surface & GetSurface (int i = 0) = 0;
|
|
virtual const Surface & GetSurface (int i = 0) const = 0;
|
|
|
|
int GetSurfaceId (int i = 0) const;
|
|
void SetSurfaceId (int i, int id);
|
|
int SurfaceActive (int i) const { return surfaceactive[i]; }
|
|
virtual int SurfaceInverted (int /* i */ = 0) const { return 0; }
|
|
|
|
virtual void GetPrimitiveData (const char *& classname,
|
|
NgArray<double> & coeffs) const;
|
|
virtual void SetPrimitiveData (NgArray<double> & coeffs);
|
|
static Primitive * CreatePrimitive (const char * classname);
|
|
|
|
|
|
virtual void Reduce (const BoxSphere<3> & /* box */) { };
|
|
virtual void UnReduce () { };
|
|
|
|
virtual Primitive * Copy () const;
|
|
virtual void Transform (Transformation<3> & trans);
|
|
};
|
|
|
|
|
|
|
|
|
|
class OneSurfacePrimitive : public Surface, public Primitive
|
|
{
|
|
public:
|
|
OneSurfacePrimitive();
|
|
~OneSurfacePrimitive();
|
|
|
|
virtual void DoArchive(Archive& archive)
|
|
{
|
|
Surface::DoArchive(archive);
|
|
Primitive::DoArchive(archive);
|
|
}
|
|
|
|
virtual INSOLID_TYPE PointInSolid (const Point<3> & p,
|
|
double eps) const;
|
|
virtual INSOLID_TYPE VecInSolid (const Point<3> & p,
|
|
const Vec<3> & v,
|
|
double eps) const;
|
|
virtual INSOLID_TYPE VecInSolid2 (const Point<3> & p,
|
|
const Vec<3> & v1,
|
|
const Vec<3> & v2,
|
|
double eps) const;
|
|
|
|
virtual INSOLID_TYPE VecInSolid3 (const Point<3> & p,
|
|
const Vec<3> & v1,
|
|
const Vec<3> & v2,
|
|
double eps) const;
|
|
|
|
virtual INSOLID_TYPE VecInSolid4 (const Point<3> & p,
|
|
const Vec<3> & v,
|
|
const Vec<3> & v2,
|
|
const Vec<3> & m,
|
|
double eps) const;
|
|
|
|
virtual int GetNSurfaces() const;
|
|
virtual Surface & GetSurface (int i = 0);
|
|
virtual const Surface & GetSurface (int i = 0) const;
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
Projects point to edge.
|
|
The point hp is projected to the edge described by f1 and f2.
|
|
It is assumed that the edge is non-degenerated, and the
|
|
(generalized) Newton method converges.
|
|
*/
|
|
extern void ProjectToEdge (const Surface * f1,
|
|
const Surface * f2,
|
|
Point<3> & hp);
|
|
|
|
|
|
}
|
|
|
|
#endif
|