netgen/libsrc/include/nginterface.h

477 lines
15 KiB
C
Raw Normal View History

2009-01-13 04:40:13 +05:00
#ifndef NGINTERFACE
#define NGINTERFACE
2009-07-20 14:36:36 +06:00
2009-01-13 04:40:13 +05:00
/**************************************************************************/
/* File: nginterface.h */
/* Author: Joachim Schoeberl */
/* Date: 20. Nov. 99 */
/**************************************************************************/
/*
Application program interface to Netgen
*/
2009-04-04 19:43:02 +06:00
#ifdef WIN32
2011-08-31 21:08:16 +06:00
#if NGINTERFACE_EXPORTS || NGLIB_EXPORTS || nglib_EXPORTS
2009-04-04 19:43:02 +06:00
#define DLL_HEADER __declspec(dllexport)
#else
#define DLL_HEADER __declspec(dllimport)
#endif
#else
#define DLL_HEADER
#endif
2009-01-13 04:40:13 +05:00
// max number of nodes per element
#define NG_ELEMENT_MAXPOINTS 12
// max number of nodes per surface element
#define NG_SURFACE_ELEMENT_MAXPOINTS 8
// implemented element types:
enum NG_ELEMENT_TYPE {
2012-06-25 22:20:01 +06:00
NG_PNT = 0,
2009-01-13 04:40:13 +05:00
NG_SEGM = 1, NG_SEGM3 = 2,
NG_TRIG = 10, NG_QUAD=11, NG_TRIG6 = 12, NG_QUAD6 = 13,
NG_TET = 20, NG_TET10 = 21,
NG_PYRAMID = 22, NG_PRISM = 23, NG_PRISM12 = 24,
NG_HEX = 25
};
typedef double NG_POINT[3]; // coordinates
typedef int NG_EDGE[2]; // initial point, end point
typedef int NG_FACE[4]; // points, last one is 0 for trig
#ifdef __cplusplus
extern "C" {
#endif
// load geomtry from file
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_LoadGeometry (const char * filename);
2009-01-13 04:40:13 +05:00
// load netgen mesh
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_LoadMesh (const char * filename);
2009-01-13 04:40:13 +05:00
// load netgen mesh
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_LoadMeshFromString (const char * mesh_as_string);
2009-01-13 04:40:13 +05:00
// space dimension (2 or 3)
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetDimension ();
2009-01-13 04:40:13 +05:00
// number of mesh points
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetNP ();
2009-01-13 04:40:13 +05:00
// number of mesh vertices (differs from GetNP for 2nd order elements)
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetNV ();
2009-01-13 04:40:13 +05:00
// number of mesh elements
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetNE ();
2009-01-13 04:40:13 +05:00
// number of surface triangles
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetNSE ();
2009-01-13 04:40:13 +05:00
// Get Point coordintes, index from 1 .. np
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_GetPoint (int pi, double * p);
2009-01-13 04:40:13 +05:00
// Get Element Points
2009-04-04 19:43:02 +06:00
DLL_HEADER NG_ELEMENT_TYPE Ng_GetElement (int ei, int * epi, int * np = 0);
2009-01-13 04:40:13 +05:00
// Get Element Type
2009-04-04 19:43:02 +06:00
DLL_HEADER NG_ELEMENT_TYPE Ng_GetElementType (int ei);
2009-01-13 04:40:13 +05:00
// Get sub-domain of element ei
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetElementIndex (int ei);
2009-01-13 04:40:13 +05:00
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_SetElementIndex(const int ei, const int index);
2009-01-13 04:40:13 +05:00
// Get Material of element ei
2009-04-04 19:43:02 +06:00
DLL_HEADER char * Ng_GetElementMaterial (int ei);
2009-01-13 04:40:13 +05:00
// Get Material of domain dom
2009-04-04 19:43:02 +06:00
DLL_HEADER char * Ng_GetDomainMaterial (int dom);
2009-01-13 04:40:13 +05:00
// Get User Data
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetUserDataSize (char * id);
DLL_HEADER void Ng_GetUserData (char * id, double * data);
2009-01-13 04:40:13 +05:00
// Get Surface Element Points
2009-04-04 19:43:02 +06:00
DLL_HEADER NG_ELEMENT_TYPE Ng_GetSurfaceElement (int ei, int * epi, int * np = 0);
2009-01-13 04:40:13 +05:00
// Get Surface Element Type
2009-04-04 19:43:02 +06:00
DLL_HEADER NG_ELEMENT_TYPE Ng_GetSurfaceElementType (int ei);
2009-01-13 04:40:13 +05:00
// Get Surface Element Index
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetSurfaceElementIndex (int ei);
2009-01-13 04:40:13 +05:00
// Get Surface Element Surface Number
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetSurfaceElementSurfaceNumber (int ei);
2009-01-13 04:40:13 +05:00
// Get Surface Element Number
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetSurfaceElementFDNumber (int ei);
2009-01-13 04:40:13 +05:00
// Get BCName for Surface Element
2009-04-04 19:43:02 +06:00
DLL_HEADER char * Ng_GetSurfaceElementBCName (int ei);
2009-01-13 04:40:13 +05:00
//void Ng_GetSurfaceElementBCName (int ei, char * name);
// Get BCName for bc-number
2009-04-04 19:43:02 +06:00
DLL_HEADER char * Ng_GetBCNumBCName (int bcnr);
2009-01-13 04:40:13 +05:00
//void Ng_GetBCNumBCName (int bcnr, char * name);
// Get normal vector of surface element node
2014-10-12 17:40:12 +06:00
// DLL_HEADER void Ng_GetNormalVector (int sei, int locpi, double * nv);
2009-01-13 04:40:13 +05:00
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_SetPointSearchStartElement(int el);
2009-01-13 04:40:13 +05:00
// Find element of point, returns local coordinates
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_FindElementOfPoint (double * p, double * lami,
int build_searchtrees = 0,
const int * const indices = NULL, const int numind = 0);
2009-01-13 04:40:13 +05:00
// Find surface element of point, returns local coordinates
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_FindSurfaceElementOfPoint (double * p, double * lami,
int build_searchtrees = 0,
const int * const indices = NULL, const int numind = 0);
2009-01-13 04:40:13 +05:00
// is elment ei curved ?
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_IsElementCurved (int ei);
2009-01-13 04:40:13 +05:00
// is elment sei curved ?
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_IsSurfaceElementCurved (int sei);
2009-01-13 04:40:13 +05:00
/// Curved Elemens:
/// xi..local coordinates
/// x ..global coordinates
/// dxdxi...D x D Jacobian matrix (row major storage)
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_GetElementTransformation (int ei, const double * xi,
double * x, double * dxdxi);
2009-01-13 04:40:13 +05:00
/// buffer must be at least 100 doubles, alignment of double
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_GetBufferedElementTransformation (int ei, const double * xi,
double * x, double * dxdxi,
void * buffer, int buffervalid);
2009-01-13 04:40:13 +05:00
/// Curved Elemens:
/// xi..local coordinates
/// x ..global coordinates
/// dxdxi...D x D-1 Jacobian matrix (row major storage)
/// curved ...is element curved ?
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_GetSurfaceElementTransformation (int sei, const double * xi,
double * x, double * dxdxi);
2009-01-13 04:40:13 +05:00
/// Curved Elemens:
/// xi..local coordinates
/// sxi..step xi
/// x ..global coordinates
/// dxdxi...D x D Jacobian matrix (row major storage)
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_GetMultiElementTransformation (int ei, int n,
2010-04-22 18:28:55 +06:00
const double * xi, size_t sxi,
double * x, size_t sx,
double * dxdxi, size_t sdxdxi);
2009-01-13 04:40:13 +05:00
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetSegmentIndex (int elnr);
DLL_HEADER NG_ELEMENT_TYPE Ng_GetSegment (int elnr, int * epi, int * np = 0);
2009-01-13 04:40:13 +05:00
// Mark element for refinement
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_SetRefinementFlag (int ei, int flag);
DLL_HEADER void Ng_SetSurfaceRefinementFlag (int sei, int flag);
2009-01-13 04:40:13 +05:00
// Do local refinement
enum NG_REFINEMENT_TYPE { NG_REFINE_H = 0, NG_REFINE_P = 1, NG_REFINE_HP = 2 };
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_Refine (NG_REFINEMENT_TYPE reftype);
2009-01-13 04:40:13 +05:00
// Use second order elements
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_SecondOrder ();
DLL_HEADER void Ng_HighOrder (int order, bool rational = false);
2009-01-13 04:40:13 +05:00
//void Ng_HPRefinement (int levels, double parameter = 0.125);
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_HPRefinement (int levels, double parameter = 0.125,
bool setorders = true,bool ref_level = false);
2009-01-13 04:40:13 +05:00
// void Ng_HPRefinement (int levels);
// void Ng_HPRefinement (int levels, double parameter);
// Topology and coordinate information of master element:
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_ME_GetNVertices (NG_ELEMENT_TYPE et);
DLL_HEADER int Ng_ME_GetNEdges (NG_ELEMENT_TYPE et);
DLL_HEADER int Ng_ME_GetNFaces (NG_ELEMENT_TYPE et);
2009-01-13 04:40:13 +05:00
2009-04-04 19:43:02 +06:00
DLL_HEADER const NG_POINT * Ng_ME_GetVertices (NG_ELEMENT_TYPE et);
DLL_HEADER const NG_EDGE * Ng_ME_GetEdges (NG_ELEMENT_TYPE et);
DLL_HEADER const NG_FACE * Ng_ME_GetFaces (NG_ELEMENT_TYPE et);
2009-01-13 04:40:13 +05:00
2011-03-07 21:38:43 +05:00
DLL_HEADER void Ng_UpdateTopology();
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetNEdges();
DLL_HEADER int Ng_GetNFaces();
2009-01-13 04:40:13 +05:00
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetElement_Edges (int elnr, int * edges, int * orient = 0);
DLL_HEADER int Ng_GetElement_Faces (int elnr, int * faces, int * orient = 0);
2009-01-13 04:40:13 +05:00
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetSurfaceElement_Edges (int selnr, int * edges, int * orient = 0);
DLL_HEADER int Ng_GetSurfaceElement_Face (int selnr, int * orient = 0);
2009-01-13 04:40:13 +05:00
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_GetSurfaceElementNeighbouringDomains(const int selnr, int & in, int & out);
2009-01-13 04:40:13 +05:00
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetFace_Vertices (int fnr, int * vert);
DLL_HEADER void Ng_GetEdge_Vertices (int ednr, int * vert);
DLL_HEADER int Ng_GetFace_Edges (int fnr, int * edge);
2009-01-13 04:40:13 +05:00
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetNVertexElements (int vnr);
DLL_HEADER void Ng_GetVertexElements (int vnr, int * els);
2009-01-13 04:40:13 +05:00
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetElementOrder (int enr);
DLL_HEADER void Ng_GetElementOrders (int enr, int * ox, int * oy, int * oz);
2009-01-13 04:40:13 +05:00
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_SetElementOrder (int enr, int order);
DLL_HEADER void Ng_SetElementOrders (int enr, int ox, int oy, int oz);
2009-01-13 04:40:13 +05:00
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetSurfaceElementOrder (int enr);
DLL_HEADER void Ng_GetSurfaceElementOrders (int enr, int * ox, int * oy);
2009-01-13 04:40:13 +05:00
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_SetSurfaceElementOrder (int enr, int order);
DLL_HEADER void Ng_SetSurfaceElementOrders (int enr, int ox, int oy);
2009-01-13 04:40:13 +05:00
// Multilevel functions:
// number of levels:
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetNLevels ();
2009-01-13 04:40:13 +05:00
// get two parent nodes (indeed vertices !) of node ni
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_GetParentNodes (int ni, int * parents);
2009-01-13 04:40:13 +05:00
// get parent element (first child has always same number)
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetParentElement (int ei);
2009-01-13 04:40:13 +05:00
// get parent surface element (first child has always same number)
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetParentSElement (int ei);
2009-01-13 04:40:13 +05:00
// representant of anisotropic cluster
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetClusterRepVertex (int vi);
DLL_HEADER int Ng_GetClusterRepEdge (int edi);
DLL_HEADER int Ng_GetClusterRepFace (int fai);
DLL_HEADER int Ng_GetClusterRepElement (int eli);
2009-01-13 04:40:13 +05:00
void Ng_SurfaceElementTransformation (int eli, double x, double y,
double * p3d, double * jacobian);
#ifdef PARALLEL
2011-08-29 16:09:11 +06:00
// the folling functions are 0-base !!
// number on distant processor
2012-06-13 15:07:11 +06:00
// returns pairs (dist_proc, num_on_dist_proc)
2011-08-29 16:09:11 +06:00
int NgPar_GetDistantNodeNums ( int nodetype, int locnum, int * pnums );
int NgPar_GetNDistantNodeNums ( int nodetype, int locnum );
2012-06-13 15:07:11 +06:00
int NgPar_GetGlobalNodeNum (int nodetype, int locnum);
2011-08-29 16:09:11 +06:00
2009-01-13 04:40:13 +05:00
#endif
2009-01-18 00:37:57 +05:00
namespace netgen {
// #include "../visualization/soldata.hpp"
class SolutionData;
2012-08-30 19:40:17 +06:00
class MouseEventHandler;
2014-02-24 01:31:40 +06:00
class UserVisualizationObject;
2009-01-18 00:37:57 +05:00
}
2009-01-13 04:40:13 +05:00
enum Ng_SolutionType
{ NG_SOLUTION_NODAL = 1,
NG_SOLUTION_ELEMENT = 2,
NG_SOLUTION_SURFACE_ELEMENT = 3,
NG_SOLUTION_NONCONTINUOUS = 4,
NG_SOLUTION_SURFACE_NONCONTINUOUS = 5,
NG_SOLUTION_VIRTUAL_FUNCTION = 6,
NG_SOLUTION_MARKED_ELEMENTS = 10,
NG_SOLUTION_ELEMENT_ORDER = 11
};
struct Ng_SolutionData
{
const char * name; // name of gridfunction
double * data; // solution values
int components; // relevant (double) components in solution vector
int dist; // # doubles per entry alignment!
int iscomplex; // complex vector ?
bool draw_surface;
bool draw_volume;
int order; // order of elements, only partially supported
Ng_SolutionType soltype; // type of solution function
netgen::SolutionData * solclass;
};
// initialize solution data with default arguments
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_InitSolutionData (Ng_SolutionData * soldata);
2009-01-13 04:40:13 +05:00
// set solution data
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_SetSolutionData (Ng_SolutionData * soldata);
2009-01-13 04:40:13 +05:00
/// delete gridfunctions
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_ClearSolutionData();
2009-01-13 04:40:13 +05:00
// redraw
2014-12-04 15:24:45 +05:00
DLL_HEADER void Ng_Redraw(bool blocking = false);
2012-08-30 19:40:17 +06:00
///
DLL_HEADER void Ng_SetMouseEventHandler (netgen::MouseEventHandler * handler);
2014-02-24 01:31:40 +06:00
///
DLL_HEADER void Ng_SetUserVisualizationObject (netgen::UserVisualizationObject * vis);
2009-01-13 04:40:13 +05:00
//
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_SetVisualizationParameter (const char * name,
const char * value);
2009-01-13 04:40:13 +05:00
// number of periodic vertices
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetNPeriodicVertices (int idnr);
2009-01-13 04:40:13 +05:00
// pairs should be an integer array of 2*npairs
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_GetPeriodicVertices (int idnr, int * pairs);
2009-01-13 04:40:13 +05:00
// number of periodic edges
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetNPeriodicEdges (int idnr);
2009-01-13 04:40:13 +05:00
// pairs should be an integer array of 2*npairs
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_GetPeriodicEdges (int idnr, int * pairs);
2009-01-13 04:40:13 +05:00
2009-05-09 15:48:16 +06:00
DLL_HEADER void RunParallel ( void * (*fun)(void *), void * in);
2009-01-13 04:40:13 +05:00
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_PushStatus (const char * str);
DLL_HEADER void Ng_PopStatus ();
DLL_HEADER void Ng_SetThreadPercentage (double percent);
DLL_HEADER void Ng_GetStatus (char ** str, double & percent);
2009-01-13 04:40:13 +05:00
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_SetTerminate(void);
DLL_HEADER void Ng_UnSetTerminate(void);
DLL_HEADER int Ng_ShouldTerminate(void);
DLL_HEADER void Ng_SetRunning(int flag);
DLL_HEADER int Ng_IsRunning();
2009-01-13 04:40:13 +05:00
//// added by Roman Stainko ....
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetVertex_Elements( int vnr, int* elems);
DLL_HEADER int Ng_GetVertex_SurfaceElements( int vnr, int* elems );
DLL_HEADER int Ng_GetVertex_NElements( int vnr );
DLL_HEADER int Ng_GetVertex_NSurfaceElements( int vnr );
2009-01-13 04:40:13 +05:00
#ifdef SOCKETS
int Ng_SocketClientOpen( const int port, const char * host );
void Ng_SocketClientWrite( const char * write, char ** reply);
void Ng_SocketClientClose ( void );
void Ng_SocketClientGetServerHost ( const int number, char ** host );
void Ng_SocketClientGetServerPort ( const int number, int * port );
void Ng_SocketClientGetServerClientID ( const int number, int * id );
#endif
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_InitPointCurve(double red, double green, double blue);
DLL_HEADER void Ng_AddPointCurvePoint(const double * point);
2009-01-13 04:40:13 +05:00
#ifdef PARALLEL
void Ng_SetElementPartition ( int elnr, int part );
int Ng_GetElementPartition ( int elnr );
#endif
2009-04-04 19:43:02 +06:00
DLL_HEADER void Ng_SaveMesh ( const char * meshfile );
DLL_HEADER void Ng_Bisect ( const char * refinementfile );
2009-01-13 04:40:13 +05:00
// if qualityloss is not equal to NULL at input, a (1-based) list of qualitylosses (due to projection)
// is saved in *qualityloss, its size is the return value
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_Bisect_WithInfo ( const char * refinementfile, double ** qualityloss);
2011-03-07 21:38:43 +05:00
typedef void * Ng_Mesh;
DLL_HEADER Ng_Mesh Ng_SelectMesh (Ng_Mesh mesh);
2012-07-06 13:49:05 +06:00
DLL_HEADER void Ng_GetArgs (int & argc, char ** &argv);
2009-01-13 04:40:13 +05:00
#ifdef __cplusplus
}
#endif
#endif
/*
The new node interface ...
it is 0-based !
*/
extern "C" {
/*
number of nodes of type nt
nt = 0 is Vertex
nt = 1 is Edge
nt = 2 is Face
nt = 3 is Cell
*/
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetNNodes (int nt);
2009-01-13 04:40:13 +05:00
/*
closure nodes of node (nt, nodenr):
nodeset is bit-coded, bit 0 includes Vertices, bit 1 edges, etc
E.g., nodeset = 6 includes edge and face nodes
nodes consists of pairs of integers (nodetype, nodenr)
return value is number of nodes
*/
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetClosureNodes (int nt, int nodenr, int nodeset, int * nodes);
2009-01-13 04:40:13 +05:00
/*
number of dim-dimensional elements
dim = 3 ... volume elements
dim = 2 ... surface elements
dim = 1 ... segments
dim = 0 ... not available
*/
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetNElements (int dim);
2009-01-13 04:40:13 +05:00
/*
closure nodes of dim-dimensional element elmentnr:
nodeset is bit-coded, bit 0 includes Vertices, bit 1 edges, etc
E.g., nodeset = 6 includes edge and face nodes
nodes consists of pairs of integers (nodetype, nodenr)
return value is number of nodes
*/
2009-04-04 19:43:02 +06:00
DLL_HEADER int Ng_GetElementClosureNodes (int dim, int elementnr, int nodeset, int * nodes);
2009-01-13 04:40:13 +05:00
2009-05-09 16:22:16 +06:00
struct Ng_Tcl_Interp;
typedef int (Ng_Tcl_CmdProc) (Ng_Tcl_Interp *interp, int argc, const char *argv[]);
DLL_HEADER void Ng_Tcl_CreateCommand (Ng_Tcl_Interp * interp,
const char * cmdName, Ng_Tcl_CmdProc * proc);
void Ng_Tcl_SetResult (Ng_Tcl_Interp * interp, const char * result);
2009-01-13 04:40:13 +05:00
}
2009-04-15 01:20:09 +06:00
#ifdef __cplusplus
#include <iostream>
namespace netgen
{
DLL_HEADER extern std::ostream * testout;
DLL_HEADER extern int printmessage_importance;
}
#endif