From c129153e120fff83b1f7e93be09076a069b61c90 Mon Sep 17 00:00:00 2001
From: Karsten Rink <karsten.rink@ufz.de>
Date: Wed, 2 May 2012 17:08:52 +0200
Subject: [PATCH] Added basic meshlib classes for nodes, elements and meshes.

---
 CMakeLists.txt               |  1 +
 MathLib/MathTools.cpp        | 24 +++++++++++++++
 MathLib/MathTools.h          |  4 +++
 MeshLib/CMakeLists.txt       | 24 +++++++++++++++
 MeshLib/Elements/Cell.cpp    | 27 +++++++++++++++++
 MeshLib/Elements/Cell.h      | 39 ++++++++++++++++++++++++
 MeshLib/Elements/Edge.cpp    | 46 ++++++++++++++++++++++++++++
 MeshLib/Elements/Edge.h      | 47 ++++++++++++++++++++++++++++
 MeshLib/Elements/Element.cpp | 42 +++++++++++++++++++++++++
 MeshLib/Elements/Element.h   | 54 +++++++++++++++++++++++++++++++++
 MeshLib/Elements/Face.cpp    | 27 +++++++++++++++++
 MeshLib/Elements/Face.h      | 42 +++++++++++++++++++++++++
 MeshLib/Elements/Hex.cpp     | 44 +++++++++++++++++++++++++++
 MeshLib/Elements/Hex.h       | 48 +++++++++++++++++++++++++++++
 MeshLib/Elements/Prism.cpp   | 49 ++++++++++++++++++++++++++++++
 MeshLib/Elements/Prism.h     | 47 ++++++++++++++++++++++++++++
 MeshLib/Elements/Pyramid.cpp | 48 +++++++++++++++++++++++++++++
 MeshLib/Elements/Pyramid.h   | 47 ++++++++++++++++++++++++++++
 MeshLib/Elements/Quad.cpp    | 47 ++++++++++++++++++++++++++++
 MeshLib/Elements/Quad.h      | 47 ++++++++++++++++++++++++++++
 MeshLib/Elements/Tet.cpp     | 46 ++++++++++++++++++++++++++++
 MeshLib/Elements/Tet.h       | 48 +++++++++++++++++++++++++++++
 MeshLib/Elements/Tri.cpp     | 46 ++++++++++++++++++++++++++++
 MeshLib/Elements/Tri.h       | 47 ++++++++++++++++++++++++++++
 MeshLib/FemMesh.cpp          | 38 +++++++++++++++++++++++
 MeshLib/FemMesh.h            | 29 ++++++++++++++++++
 MeshLib/FemNode.cpp          | 36 ++++++++++++++++++++++
 MeshLib/FemNode.h            | 28 +++++++++++++++++
 MeshLib/Mesh.cpp             | 53 ++++++++++++++++++++++++++++++++
 MeshLib/Mesh.h               | 42 +++++++++++++++++++++++++
 MeshLib/MshEnums.cpp         | 59 ++++++++++++++++++++++++++++++++++++
 MeshLib/MshEnums.h           | 49 ++++++++++++++++++++++++++++++
 MeshLib/Node.cpp             | 31 +++++++++++++++++++
 MeshLib/Node.h               | 38 +++++++++++++++++++++++
 34 files changed, 1344 insertions(+)
 create mode 100644 MeshLib/CMakeLists.txt
 create mode 100644 MeshLib/Elements/Cell.cpp
 create mode 100644 MeshLib/Elements/Cell.h
 create mode 100644 MeshLib/Elements/Edge.cpp
 create mode 100644 MeshLib/Elements/Edge.h
 create mode 100644 MeshLib/Elements/Element.cpp
 create mode 100644 MeshLib/Elements/Element.h
 create mode 100644 MeshLib/Elements/Face.cpp
 create mode 100644 MeshLib/Elements/Face.h
 create mode 100644 MeshLib/Elements/Hex.cpp
 create mode 100644 MeshLib/Elements/Hex.h
 create mode 100644 MeshLib/Elements/Prism.cpp
 create mode 100644 MeshLib/Elements/Prism.h
 create mode 100644 MeshLib/Elements/Pyramid.cpp
 create mode 100644 MeshLib/Elements/Pyramid.h
 create mode 100644 MeshLib/Elements/Quad.cpp
 create mode 100644 MeshLib/Elements/Quad.h
 create mode 100644 MeshLib/Elements/Tet.cpp
 create mode 100644 MeshLib/Elements/Tet.h
 create mode 100644 MeshLib/Elements/Tri.cpp
 create mode 100644 MeshLib/Elements/Tri.h
 create mode 100644 MeshLib/FemMesh.cpp
 create mode 100644 MeshLib/FemMesh.h
 create mode 100644 MeshLib/FemNode.cpp
 create mode 100644 MeshLib/FemNode.h
 create mode 100644 MeshLib/Mesh.cpp
 create mode 100644 MeshLib/Mesh.h
 create mode 100644 MeshLib/MshEnums.cpp
 create mode 100644 MeshLib/MshEnums.h
 create mode 100644 MeshLib/Node.cpp
 create mode 100644 MeshLib/Node.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index cb48bf44777..287c95026d7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -33,6 +33,7 @@ ENDIF() # GCC AND GPROF_PATH
 ADD_SUBDIRECTORY( Base )
 ADD_SUBDIRECTORY( GeoLib )
 ADD_SUBDIRECTORY( MathLib )
+ADD_SUBDIRECTORY( MeshLib )
 ADD_SUBDIRECTORY( SimpleTests/MatrixTests )
 IF(NOT MSVC)
         ADD_SUBDIRECTORY( SimpleTests/SolverTests )
diff --git a/MathLib/MathTools.cpp b/MathLib/MathTools.cpp
index de68f0338d4..c6c20e40b9c 100644
--- a/MathLib/MathTools.cpp
+++ b/MathLib/MathTools.cpp
@@ -86,4 +86,28 @@ double getAngle (const double p0[3], const double p1[3], const double p2[3])
 	return acos (scpr (v0,v1,3) / (sqrt(scpr(v0,v0,3)) * sqrt(scpr (v1,v1,3))));
 }
 
+double calcDetTriangle(const double p0[3], const double p1[3],	const double p2[3])
+{
+	const double u0 (p2[0] - p0[0]);
+	const double u1 (p2[1] - p0[1]);
+	const double u2 (p2[2] - p0[2]);
+
+	const double v0 (p1[0] - p0[0]);
+	const double v1 (p1[1] - p0[1]);
+	const double v2 (p1[2] - p0[2]);
+
+	const double z0 (u1*v2 - u2*v1);
+	const double z1 (u2*v0 - u0*v2);
+	const double z2 (u0*v1 - u1*v0);
+
+	return 0.5 * sqrt(z0*z0 + z1*z1 + z2 * z2);
+}
+
+double calcDetTetrahedron(const double* x1, const double* x2, const double* x3, const double* x4)
+{
+	return fabs((x1[0] - x4[0]) * ((x2[1] - x4[1]) * (x3[2] - x4[2]) - (x2[2] - x4[2]) * (x3[1] - x4[1]))
+	          - (x1[1] - x4[1]) * ((x2[0] - x4[0]) * (x3[2] - x4[2]) - (x2[2] - x4[2]) * (x3[0] - x4[0]))
+	          + (x1[2] - x4[2]) * ((x2[0] - x4[0]) * (x3[1] - x4[1]) - (x2[1] - x4[1]) * (x3[0] - x4[0]))) / 6.0;
+}
+
 } // namespace
diff --git a/MathLib/MathTools.h b/MathLib/MathTools.h
index ea6109150ae..d6086565275 100644
--- a/MathLib/MathTools.h
+++ b/MathLib/MathTools.h
@@ -94,6 +94,10 @@ float normalize(float min, float max, float val);
  */
 double getAngle (const double p0[3], const double p1[3], const double p2[3]);
 
+double calcDetTriangle(const double p0[3], const double p1[3],	const double p2[3]);
+
+double calcDetTetrahedron(const double* x1, const double* x2, const double* x3, const double* x4);
+
 /**
  * simple power function that takes as a second argument an integer instead of a float
  * @param base basis of the expression
diff --git a/MeshLib/CMakeLists.txt b/MeshLib/CMakeLists.txt
new file mode 100644
index 00000000000..d7521eae62c
--- /dev/null
+++ b/MeshLib/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Source files
+GET_SOURCE_FILES(SOURCES_MESHLIB)
+SET ( SOURCES ${SOURCES_MESHLIB})
+
+GET_SOURCE_FILES(SOURCES_ELEMENTS Elements)
+SET ( SOURCES ${SOURCES} ${SOURCES_ELEMENTS})
+
+# Create the library
+ADD_LIBRARY(MeshLib STATIC ${SOURCES})
+
+include_directories(
+	.
+	../Base
+	../GeoLib
+	../MathLib
+)
+
+
+target_link_libraries (MeshLib
+	Base
+	GeoLib
+	MathLib
+)
+
diff --git a/MeshLib/Elements/Cell.cpp b/MeshLib/Elements/Cell.cpp
new file mode 100644
index 00000000000..e9844c418ce
--- /dev/null
+++ b/MeshLib/Elements/Cell.cpp
@@ -0,0 +1,27 @@
+/**
+ * Cell.cpp
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#include "Cell.h"
+
+namespace MeshLib {
+
+Cell::Cell(Node** nodes, MshElemType::type type, size_t value)
+	: Element(nodes, type, value)
+{
+}
+
+Cell::Cell(MshElemType::type type, size_t value)
+	: Element(type, value)
+{
+}
+
+Cell::~Cell()
+{
+}
+
+
+}
\ No newline at end of file
diff --git a/MeshLib/Elements/Cell.h b/MeshLib/Elements/Cell.h
new file mode 100644
index 00000000000..c6438980407
--- /dev/null
+++ b/MeshLib/Elements/Cell.h
@@ -0,0 +1,39 @@
+/**
+ * Cell.h
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#ifndef CELL_H_
+#define CELL_H_
+
+#include "Element.h"
+
+namespace MeshLib {
+
+/**
+ * Virtual base class for 3d mesh elements.
+ */
+class Cell : public Element
+{
+public:
+	virtual double getVolume() const { return _volume; };
+
+	size_t getDimension() const { return 3; };
+
+	virtual ~Cell();
+
+protected:
+	Cell(Node** nodes, MshElemType::type type, size_t value = 0);
+	Cell(MshElemType::type type, size_t value = 0);
+
+	virtual double calcVolume() = 0;
+
+	double _volume;
+
+}; /* class */
+
+} /* namespace */
+
+#endif /* CELL_H_ */
diff --git a/MeshLib/Elements/Edge.cpp b/MeshLib/Elements/Edge.cpp
new file mode 100644
index 00000000000..b91c6a13e55
--- /dev/null
+++ b/MeshLib/Elements/Edge.cpp
@@ -0,0 +1,46 @@
+/**
+ * Edge.cpp
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#include "Edge.h"
+#include "Node.h"
+
+#include "MathTools.h"
+
+namespace MeshLib {
+
+Edge::Edge(Node* nodes[2], size_t value)
+	: Element(nodes, MshElemType::LINE, value)
+{
+	this->_length = this->calcLength();
+}
+
+Edge::Edge(Node* n0, Node* n1, size_t value)
+	: Element(MshElemType::LINE, value)
+{
+	Node* nodes[2] = { n0, n1 };
+	_nodes = nodes;
+
+	this->_length = this->calcLength();
+}
+
+Edge::Edge(const Edge &edge)
+	: Element(MshElemType::LINE, edge.getValue())
+{
+	Node* nodes[2] = { new Node(*edge.getNode(0)), new Node(*edge.getNode(1)) };
+	_length = edge.getLength();
+}
+
+Edge::~Edge()
+{
+}
+
+double Edge::calcLength()
+{
+	return sqrt(MathLib::sqrDist(_nodes[0]->getData(), _nodes[1]->getData()));
+}
+
+}
\ No newline at end of file
diff --git a/MeshLib/Elements/Edge.h b/MeshLib/Elements/Edge.h
new file mode 100644
index 00000000000..34b0ded9319
--- /dev/null
+++ b/MeshLib/Elements/Edge.h
@@ -0,0 +1,47 @@
+/**
+ * Edge.h
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#ifndef EDGE_H_
+#define EDGE_H_
+
+#include "Element.h"
+
+namespace MeshLib {
+
+class Node;
+
+/**
+ * A 1d Edge or Line Element.
+ *
+ *  Edge: o--------o
+ *        0        1
+ */
+class Edge : public Element
+{
+public:
+	Edge(Node* nodes[2], size_t value = 0);
+	Edge(Node* n1, Node* n2, size_t value = 0);
+	Edge(const Edge &edge);
+	virtual ~Edge();
+
+	double getLength() const { return _length; };
+
+	size_t getDimension() const { return 1; };
+
+	size_t getNNodes() const { return 2; };
+
+
+protected:
+	double calcLength();
+
+	double _length;
+
+}; /* class */
+
+} /* namespace */
+
+#endif /* EDGE_H_ */
diff --git a/MeshLib/Elements/Element.cpp b/MeshLib/Elements/Element.cpp
new file mode 100644
index 00000000000..fd37bb3ed23
--- /dev/null
+++ b/MeshLib/Elements/Element.cpp
@@ -0,0 +1,42 @@
+/**
+ * Element.cpp
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#include "Element.h"
+#include "Node.h"
+
+#include <cassert>
+
+namespace MeshLib {
+
+Element::Element(Node** nodes, MshElemType::type type, size_t value)
+	: _nodes(nodes), _type(type), _value(value)
+{
+}
+
+Element::Element(MshElemType::type type, size_t value)
+	: _type(type), _value(value)
+{
+}
+
+Element::~Element()
+{
+	delete[] this->_nodes;
+}
+
+const Node* Element::getNode(size_t i) const
+{
+	assert(i<getNNodes() && "Error in MeshLib::Element - Index does not exist.");
+	return _nodes[i];
+}
+
+size_t Element::getNodeIndex(size_t i) const 
+{
+	assert(i<getNNodes() && "Error in MeshLib::Element - Index does not exist.");
+	return _nodes[i]->getID();
+}
+
+}
\ No newline at end of file
diff --git a/MeshLib/Elements/Element.h b/MeshLib/Elements/Element.h
new file mode 100644
index 00000000000..6b00d1639aa
--- /dev/null
+++ b/MeshLib/Elements/Element.h
@@ -0,0 +1,54 @@
+/**
+ * Element.h
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#ifndef ELEMENT_H_
+#define ELEMENT_H_
+
+#include <vector>
+#include "MshEnums.h"
+
+namespace MeshLib {
+
+class Node;
+
+/**
+ * Virtual base class for mesh elements.
+ */
+class Element
+{
+public:
+	const Node* getNode(size_t i) const;
+	Node* const* getNodes() const { return _nodes; };
+
+	virtual size_t getDimension() const = 0;
+
+	virtual size_t getNNodes() const = 0;
+
+	size_t getNodeIndex(size_t i) const;
+
+	MshElemType::type getType() const { return _type; };
+
+	size_t getValue() const { return _value; };
+
+	virtual ~Element();
+
+protected:
+	Element(Node** nodes, MshElemType::type type, size_t value = 0);
+	Element(MshElemType::type type, size_t value = 0);
+
+	MshElemType::type _type;
+	size_t _value;
+	Node** _nodes;
+	std::vector<Element*> _neighbors;
+
+private:
+
+}; /* class */
+
+} /* namespace */
+
+#endif /* ELEMENT_H_ */
diff --git a/MeshLib/Elements/Face.cpp b/MeshLib/Elements/Face.cpp
new file mode 100644
index 00000000000..e61c5665648
--- /dev/null
+++ b/MeshLib/Elements/Face.cpp
@@ -0,0 +1,27 @@
+/**
+ * Face.cpp
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#include "Face.h"
+
+namespace MeshLib {
+
+Face::Face(Node** nodes, MshElemType::type type, size_t value)
+	: Element(nodes, type, value)
+{
+}
+
+Face::Face(MshElemType::type type, size_t value)
+	: Element(type, value)
+{
+}
+
+Face::~Face()
+{
+}
+
+
+}
\ No newline at end of file
diff --git a/MeshLib/Elements/Face.h b/MeshLib/Elements/Face.h
new file mode 100644
index 00000000000..0e3500c8a4d
--- /dev/null
+++ b/MeshLib/Elements/Face.h
@@ -0,0 +1,42 @@
+/**
+ * Face.h
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#ifndef FACE_H_
+#define FACE_H_
+
+#include "Element.h"
+
+namespace MeshLib {
+
+/**
+ * Virtual base class for 2d mesh elements.
+ */
+class Face : public Element
+{
+public:
+	virtual double getArea() const { return _area; };
+
+	size_t getDimension() const { return 2; };
+
+	virtual ~Face();
+
+protected:
+	Face(Node** nodes, MshElemType::type type, size_t value = 0);
+	Face(MshElemType::type type, size_t value = 0);
+
+	virtual double calcArea() = 0;
+
+	double _area;
+
+private:
+	
+
+}; /* class */
+
+} /* namespace */
+
+#endif /* FACE_H_ */
diff --git a/MeshLib/Elements/Hex.cpp b/MeshLib/Elements/Hex.cpp
new file mode 100644
index 00000000000..c5cd0fb7e72
--- /dev/null
+++ b/MeshLib/Elements/Hex.cpp
@@ -0,0 +1,44 @@
+/**
+ * Hex.cpp
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#include "Hex.h"
+#include "Node.h"
+
+#include "MathTools.h"
+
+
+namespace MeshLib {
+
+Hex::Hex(Node* nodes[8], size_t value)
+	: Cell(nodes, MshElemType::HEXAHEDRON, value)
+{
+	this->_volume = this->calcVolume();
+}
+
+Hex::Hex(const Hex &hex)
+	: Cell(MshElemType::HEXAHEDRON, hex.getValue())
+{
+	Node* nodes[8] = { new Node(*hex.getNode(0)), new Node(*hex.getNode(1)), new Node(*hex.getNode(2)), new Node(*hex.getNode(3)),
+	                   new Node(*hex.getNode(4)), new Node(*hex.getNode(5)), new Node(*hex.getNode(6)), new Node(*hex.getNode(7)) };
+	_volume = hex.getVolume();
+}
+
+Hex::~Hex()
+{
+}
+
+double Hex::calcVolume()
+{
+	return MathLib::calcDetTetrahedron(_nodes[4]->getData(), _nodes[7]->getData(), _nodes[5]->getData(), _nodes[0]->getData())
+		 + MathLib::calcDetTetrahedron(_nodes[5]->getData(), _nodes[3]->getData(), _nodes[1]->getData(), _nodes[0]->getData())
+		 + MathLib::calcDetTetrahedron(_nodes[5]->getData(), _nodes[7]->getData(), _nodes[3]->getData(), _nodes[0]->getData())
+		 + MathLib::calcDetTetrahedron(_nodes[5]->getData(), _nodes[7]->getData(), _nodes[6]->getData(), _nodes[2]->getData())
+		 + MathLib::calcDetTetrahedron(_nodes[1]->getData(), _nodes[3]->getData(), _nodes[5]->getData(), _nodes[2]->getData())
+		 + MathLib::calcDetTetrahedron(_nodes[3]->getData(), _nodes[7]->getData(), _nodes[5]->getData(), _nodes[2]->getData());
+}
+
+}
\ No newline at end of file
diff --git a/MeshLib/Elements/Hex.h b/MeshLib/Elements/Hex.h
new file mode 100644
index 00000000000..d2dbacbf66d
--- /dev/null
+++ b/MeshLib/Elements/Hex.h
@@ -0,0 +1,48 @@
+/**
+ * Hex.h
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#ifndef HEX_H_
+#define HEX_H_
+
+#include "Cell.h"
+
+namespace MeshLib {
+
+/**
+ * A 3d Hexahedron Element.
+ *
+ *  Hex:  7        6
+ *        o--------o
+ *       /:       /|
+ *      / :      / |
+ *   4 /  :   5 /  |
+ *    o--------o   |
+ *    |   o....|...o 2
+ *    |  .3    |  /
+ *    | .      | /
+ *    |.       |/
+ *    o--------o
+ *    0        1
+ */
+class Hex : public Cell
+{
+public:
+	Hex(Node* nodes[8], size_t value = 0);
+	Hex(const Hex &hex);
+	virtual ~Hex();
+
+	size_t getNNodes() const { return 8; };
+
+protected:
+	/// Calculates the volume of a convex hexahedron by partitioning it into six tetrahedra.
+	double calcVolume();
+
+}; /* class */
+
+} /* namespace */
+
+#endif /* HEX_H_ */
diff --git a/MeshLib/Elements/Prism.cpp b/MeshLib/Elements/Prism.cpp
new file mode 100644
index 00000000000..4f8a2dea6c5
--- /dev/null
+++ b/MeshLib/Elements/Prism.cpp
@@ -0,0 +1,49 @@
+/**
+ * Prism.cpp
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#include "Prism.h"
+#include "Node.h"
+
+#include "MathTools.h"
+
+namespace MeshLib {
+
+Prism::Prism(Node* nodes[6], size_t value)
+	: Cell(nodes, MshElemType::PRISM, value)
+{
+	this->_volume = this->calcVolume();
+}
+
+Prism::Prism(Node* n0, Node* n1, Node* n2, Node* n3, Node* n4, Node* n5, size_t value)
+	: Cell(MshElemType::PRISM, value)
+{
+	Node* nodes[6] = { n0, n1, n2, n3, n4, n5 };
+	_nodes = nodes;
+
+	this->_volume = this->calcVolume();
+}
+
+Prism::Prism(const Prism &prism)
+	: Cell(MshElemType::PRISM, prism.getValue())
+{
+	Node* nodes[6] = { new Node(*prism.getNode(0)), new Node(*prism.getNode(1)), new Node(*prism.getNode(2)), 
+		               new Node(*prism.getNode(3)), new Node(*prism.getNode(4)), new Node(*prism.getNode(5)) };
+	_volume = prism.getVolume();
+}
+
+Prism::~Prism()
+{
+}
+
+double Prism::calcVolume()
+{
+	return MathLib::calcDetTetrahedron(_nodes[0]->getData(), _nodes[1]->getData(), _nodes[2]->getData(), _nodes[3]->getData())
+		 + MathLib::calcDetTetrahedron(_nodes[1]->getData(), _nodes[4]->getData(), _nodes[2]->getData(), _nodes[3]->getData())
+		 + MathLib::calcDetTetrahedron(_nodes[2]->getData(), _nodes[4]->getData(), _nodes[5]->getData(), _nodes[3]->getData());
+}
+
+}
\ No newline at end of file
diff --git a/MeshLib/Elements/Prism.h b/MeshLib/Elements/Prism.h
new file mode 100644
index 00000000000..e73a3650e63
--- /dev/null
+++ b/MeshLib/Elements/Prism.h
@@ -0,0 +1,47 @@
+/**
+ * Prism.h
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#ifndef PRISM_H_
+#define PRISM_H_
+
+#include "Cell.h"
+
+namespace MeshLib {
+
+/**
+ * A 3d Prism Element.
+ *
+ *  Prism:   5
+ *           o
+ *          /:\
+ *         / : \
+ *        /  o  \
+ *     3 o-------o 4
+ *       | . 2 . |
+ *       |.     .|
+ *       o-------o
+ *       0       1
+ */
+class Prism : public Cell
+{
+public:
+	Prism(Node* nodes[6], size_t value = 0);
+	Prism(Node* n0, Node* n1, Node* n2, Node* n3, Node* n4, Node* n5, size_t value = 0);
+	Prism(const Prism &prism);
+	virtual ~Prism();
+
+	size_t getNNodes() const { return 6; };
+
+protected:
+	/// Calculates the volume of a prism by subdividing it into three tetrahedra.
+	double calcVolume();
+
+}; /* class */
+
+} /* namespace */
+
+#endif /* PRISM_H_ */
diff --git a/MeshLib/Elements/Pyramid.cpp b/MeshLib/Elements/Pyramid.cpp
new file mode 100644
index 00000000000..e3f122d0d58
--- /dev/null
+++ b/MeshLib/Elements/Pyramid.cpp
@@ -0,0 +1,48 @@
+/**
+ * Pyramid.cpp
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#include "Pyramid.h"
+#include "Node.h"
+
+#include "MathTools.h"
+
+namespace MeshLib {
+
+Pyramid::Pyramid(Node* nodes[5], size_t value)
+	: Cell(nodes, MshElemType::PYRAMID, value)
+{
+	this->_volume = this->calcVolume();
+}
+
+Pyramid::Pyramid(Node* n0, Node* n1, Node* n2, Node* n3, Node* n4, size_t value)
+	: Cell(MshElemType::PYRAMID, value)
+{
+	Node* nodes[5] = { n0, n1, n2, n3, n4 };
+	_nodes = nodes;
+
+	this->_volume = this->calcVolume();
+}
+
+Pyramid::Pyramid(const Pyramid &prism)
+	: Cell(MshElemType::PYRAMID, prism.getValue())
+{
+	Node* nodes[5] = { new Node(*prism.getNode(0)), new Node(*prism.getNode(1)), new Node(*prism.getNode(2)), 
+		               new Node(*prism.getNode(3)), new Node(*prism.getNode(4)) };
+	_volume = prism.getVolume();
+}
+
+Pyramid::~Pyramid()
+{
+}
+
+double Pyramid::calcVolume()
+{
+	return MathLib::calcDetTetrahedron(_nodes[0]->getData(), _nodes[1]->getData(), _nodes[2]->getData(), _nodes[4]->getData())
+		 + MathLib::calcDetTetrahedron(_nodes[2]->getData(), _nodes[3]->getData(), _nodes[0]->getData(), _nodes[4]->getData());
+}
+
+}
\ No newline at end of file
diff --git a/MeshLib/Elements/Pyramid.h b/MeshLib/Elements/Pyramid.h
new file mode 100644
index 00000000000..86a0fb27c46
--- /dev/null
+++ b/MeshLib/Elements/Pyramid.h
@@ -0,0 +1,47 @@
+/**
+ * Pyramid.h
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#ifndef PYRAMID_H_
+#define PYRAMID_H_
+
+#include "Cell.h"
+
+namespace MeshLib {
+
+/**
+ * A 3d Pyramid Element.
+ *
+ *  Pyramid:   o 4
+ *           //|\
+ *          // | \
+ *         //  |  \
+ *      3 o/...|...o 2
+ *       ./    |  /
+ *      ./     | /
+ *     ./      |/
+ *    o--------o
+ *    0        1
+ */
+class Pyramid : public Cell
+{
+public:
+	Pyramid(Node* nodes[5], size_t value = 0);
+	Pyramid(Node* n0, Node* n1, Node* n2, Node* n3, Node* n4, size_t value = 0);
+	Pyramid(const Pyramid &pyramid);
+	virtual ~Pyramid();
+
+	size_t getNNodes() const { return 5; };
+
+protected:
+	/// Calculates the volume of a prism by subdividing it into two tetrahedra.
+	double calcVolume();
+
+}; /* class */
+
+} /* namespace */
+
+#endif /* PYRAMID_H_ */
diff --git a/MeshLib/Elements/Quad.cpp b/MeshLib/Elements/Quad.cpp
new file mode 100644
index 00000000000..b63d1842585
--- /dev/null
+++ b/MeshLib/Elements/Quad.cpp
@@ -0,0 +1,47 @@
+/**
+ * Quad.cpp
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#include "Quad.h"
+#include "Node.h"
+
+#include "MathTools.h"
+	
+namespace MeshLib {
+
+Quad::Quad(Node* nodes[4], size_t value)
+	: Face(nodes, MshElemType::TRIANGLE, value)
+{
+	this->_area = this->calcArea();
+}
+
+Quad::Quad(Node* n0, Node* n1, Node* n2, Node* n3, size_t value)
+	: Face(MshElemType::TRIANGLE, value)
+{
+	Node* nodes[4] = { n0, n1, n2, n3 };
+	_nodes = nodes;
+
+	this->_area = this->calcArea();
+}
+
+Quad::Quad(const Quad &quad)
+	: Face(MshElemType::QUAD, quad.getValue())
+{
+	Node* nodes[4] = { new Node(*quad.getNode(0)), new Node(*quad.getNode(1)), new Node(*quad.getNode(2)), new Node(*quad.getNode(3)) };
+	_area = quad.getArea();
+}
+
+Quad::~Quad()
+{
+}
+
+double Quad::calcArea()
+{
+	return MathLib::calcDetTriangle(_nodes[0]->getData(), _nodes[1]->getData(), _nodes[2]->getData())
+         + MathLib::calcDetTriangle(_nodes[2]->getData(), _nodes[3]->getData(), _nodes[0]->getData());
+}
+
+}
\ No newline at end of file
diff --git a/MeshLib/Elements/Quad.h b/MeshLib/Elements/Quad.h
new file mode 100644
index 00000000000..a938464ab17
--- /dev/null
+++ b/MeshLib/Elements/Quad.h
@@ -0,0 +1,47 @@
+/**
+ * Quad.h
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#ifndef QUAD_H_
+#define QUAD_H_
+
+#include "Face.h"
+
+namespace MeshLib {
+
+/**
+ * A 2d Quadliteral Element.
+ *
+ *        3           2
+ * QUAD4: o-----------o
+ *        |           |
+ *        |           |
+ *        |           |
+ *        |           |
+ *        |           |
+ *        o-----------o
+ *        0           1
+ */
+class Quad : public Face
+{
+public:
+	Quad(Node* nodes[4], size_t value = 0);
+	Quad(Node* n0, Node* n1, Node* n2, Node* n3, size_t value = 0);
+	Quad(const Quad &quad);
+	virtual ~Quad();
+
+	size_t getNNodes() const { return 4; };
+
+protected:
+	/// Calculates the area of a convex quadliteral by dividing it into two triangles.
+	double calcArea();
+
+
+}; /* class */
+
+} /* namespace */
+
+#endif /* QUAD_H_ */
diff --git a/MeshLib/Elements/Tet.cpp b/MeshLib/Elements/Tet.cpp
new file mode 100644
index 00000000000..c1b3c414c14
--- /dev/null
+++ b/MeshLib/Elements/Tet.cpp
@@ -0,0 +1,46 @@
+/**
+ * Tet.cpp
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#include "Tet.h"
+#include "Node.h"
+
+#include "MathTools.h"
+
+namespace MeshLib {
+
+Tet::Tet(Node* nodes[4], size_t value)
+	: Cell(nodes, MshElemType::TETRAHEDRON, value)
+{
+	this->_volume = this->calcVolume();
+}
+
+Tet::Tet(Node* n0, Node* n1, Node* n2, Node* n3, size_t value)
+	: Cell(MshElemType::TETRAHEDRON, value)
+{
+	Node* nodes[4] = { n0, n1, n2, n3 };
+	_nodes = nodes;
+
+	this->_volume = this->calcVolume();
+}
+
+Tet::Tet(const Tet &tet)
+	: Cell(MshElemType::TETRAHEDRON, tet.getValue())
+{
+	Node* nodes[4] = { new Node(*tet.getNode(0)), new Node(*tet.getNode(1)), new Node(*tet.getNode(2)), new Node(*tet.getNode(3)) };
+	_volume = tet.getVolume();
+}
+
+Tet::~Tet()
+{
+}
+
+double Tet::calcVolume()
+{
+	return MathLib::calcDetTetrahedron(_nodes[0]->getData(), _nodes[1]->getData(), _nodes[2]->getData(), _nodes[3]->getData());
+}
+
+}
\ No newline at end of file
diff --git a/MeshLib/Elements/Tet.h b/MeshLib/Elements/Tet.h
new file mode 100644
index 00000000000..28cf9c1dec0
--- /dev/null
+++ b/MeshLib/Elements/Tet.h
@@ -0,0 +1,48 @@
+/**
+ * Tet.h
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#ifndef TET_H_
+#define TET_H_
+
+#include "Cell.h"
+
+namespace MeshLib {
+
+/**
+ * A 3d Tetrahedron Element.
+ * 
+ * Tet:   3
+ *        o
+ *       /|\
+ *      / | \
+ *     /  |  \
+ *  0 o...|...o 2
+ *     \  |  /
+ *      \ | /
+ *       \|/
+ *        o
+ *        1
+ */
+class Tet : public Cell
+{
+public:
+	Tet(Node* nodes[4], size_t value = 0);
+	Tet(Node* n0, Node* n1, Node* n2, Node* n3, size_t value = 0);
+	Tet(const Tet &tet);
+	virtual ~Tet();
+
+	size_t getNNodes() const { return 4; };
+
+protected:
+	/// Calculates the volume of a tetrahedron via the determinant of the matrix given by its four points.
+	double calcVolume();
+
+}; /* class */
+
+} /* namespace */
+
+#endif /* TET_H_ */
diff --git a/MeshLib/Elements/Tri.cpp b/MeshLib/Elements/Tri.cpp
new file mode 100644
index 00000000000..f5b337d573e
--- /dev/null
+++ b/MeshLib/Elements/Tri.cpp
@@ -0,0 +1,46 @@
+/**
+ * Tri.cpp
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#include "Tri.h"
+#include "Node.h"
+
+#include "MathTools.h"
+
+namespace MeshLib {
+
+Tri::Tri(Node* nodes[3], size_t value)
+	: Face(nodes, MshElemType::TRIANGLE, value)
+{
+	this->_area = this->calcArea();
+}
+
+Tri::Tri(Node* n0, Node* n1, Node* n2, size_t value)
+	: Face(MshElemType::TRIANGLE, value)
+{
+	Node* nodes[3] = { n0, n1, n2 };
+	_nodes = nodes;
+
+	this->_area = this->calcArea();
+}
+
+Tri::Tri(const Tri &tri)
+	: Face(MshElemType::TRIANGLE, tri.getValue())
+{
+	Node* nodes[3] = { new Node(*tri.getNode(0)), new Node(*tri.getNode(1)), new Node(*tri.getNode(2)) };
+	_area = tri.getArea();
+}
+
+Tri::~Tri()
+{
+}
+
+double Tri::calcArea()
+{
+	return MathLib::calcDetTriangle(_nodes[0]->getData(), _nodes[1]->getData(), _nodes[2]->getData());
+}
+
+}
\ No newline at end of file
diff --git a/MeshLib/Elements/Tri.h b/MeshLib/Elements/Tri.h
new file mode 100644
index 00000000000..f884b5c8753
--- /dev/null
+++ b/MeshLib/Elements/Tri.h
@@ -0,0 +1,47 @@
+/**
+ * Tri.h
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#ifndef TRI_H_
+#define TRI_H_
+
+#include "Face.h"
+
+namespace MeshLib {
+
+/**
+ * A 2d Triangle Element.
+ *
+ *   Tri:   2
+ *          o
+ *         / \
+ *        /   \
+ *       /     \
+ *      /       \
+ *     /         \
+ *    o-----------o
+ *    0           1
+ *
+ */
+class Tri : public Face
+{
+public:
+	Tri(Node* nodes[3], size_t value = 0);
+	Tri(Node* n0, Node* n1, Node* n2, size_t value = 0);
+	Tri(const Tri &tri);
+	virtual ~Tri();
+
+	size_t getNNodes() const { return 3; };
+
+protected:
+	/// Calculates the area of the triangle by returning half of the area of the corresponding parallelogram.
+	double calcArea();
+
+}; /* class */
+
+} /* namespace */
+
+#endif /* TRI_H_ */
diff --git a/MeshLib/FemMesh.cpp b/MeshLib/FemMesh.cpp
new file mode 100644
index 00000000000..d67f2159ae1
--- /dev/null
+++ b/MeshLib/FemMesh.cpp
@@ -0,0 +1,38 @@
+/**
+ * FemMesh.cpp
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#include "FemMesh.h"
+
+namespace MeshLib {
+
+FemMesh::FemMesh(const std::string &name, const std::vector<Node*> &nodes, const std::vector<Element*> &elements)
+	: Mesh(name, nodes, elements)
+{
+	this->removeIdenticalNodes();
+}
+
+FemMesh::FemMesh(const Mesh &mesh)
+	: Mesh(mesh.getName(), mesh.getNodes(), mesh.getElements())
+{
+}
+
+FemMesh::FemMesh(const FemMesh &mesh)
+	: Mesh(mesh.getName(), mesh.getNodes(), mesh.getElements())
+{
+}
+
+FemMesh::FemMesh(const std::string &file_name)
+	: Mesh(file_name)
+{
+}
+
+FemMesh::~FemMesh()
+{
+
+}
+
+}
\ No newline at end of file
diff --git a/MeshLib/FemMesh.h b/MeshLib/FemMesh.h
new file mode 100644
index 00000000000..93975f25ca6
--- /dev/null
+++ b/MeshLib/FemMesh.h
@@ -0,0 +1,29 @@
+/**
+ * FemMesh.h
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#ifndef FEMMESH_H_
+#define FEMMESH_H_
+
+#include "Mesh.h"
+
+namespace MeshLib {
+
+class FemMesh : public Mesh
+{
+public:
+	FemMesh(const std::string &name, const std::vector<Node*> &nodes, const std::vector<Element*> &elements);
+	FemMesh(const Mesh &mesh);
+	FemMesh(const FemMesh &mesh);
+	FemMesh(const std::string &file_name);
+	~FemMesh();
+
+
+}; /* class */
+
+} /* namespace */
+
+#endif /* FEMMESH_H_ */
diff --git a/MeshLib/FemNode.cpp b/MeshLib/FemNode.cpp
new file mode 100644
index 00000000000..160d6ec4fe0
--- /dev/null
+++ b/MeshLib/FemNode.cpp
@@ -0,0 +1,36 @@
+/**
+ * FemNode.cpp
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#include "FemNode.h"
+
+namespace MeshLib {
+
+FemNode::FemNode(double const*const coords, size_t id)
+	: Node(coords, id)
+{
+}
+
+FemNode::FemNode(double x, double y, double z, size_t id)
+	: Node(x, y, z, id)
+{
+}
+
+FemNode::FemNode(const Node &node)
+	: Node(node.getData(), node.getID())
+{
+}
+
+FemNode::FemNode(const FemNode &node)
+	: Node(node.getData(), node.getID())
+{
+}
+
+FemNode::~FemNode()
+{
+}
+
+}
\ No newline at end of file
diff --git a/MeshLib/FemNode.h b/MeshLib/FemNode.h
new file mode 100644
index 00000000000..988ab28123f
--- /dev/null
+++ b/MeshLib/FemNode.h
@@ -0,0 +1,28 @@
+/**
+ * FemNode.h
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#ifndef FEMNODE_H_
+#define FEMNODE_H_
+
+#include "Node.h"
+
+namespace MeshLib {
+
+class FemNode : public Node
+{
+public:
+	FemNode(double const*const coords, size_t id = std::numeric_limits<size_t>::max());
+	FemNode(double x, double y, double z, size_t id = std::numeric_limits<size_t>::max());
+	FemNode(const Node &node);
+	FemNode(const FemNode &node);
+	~FemNode();
+
+}; /* class */
+
+} /* namespace */
+
+#endif /* FEMNODE_H_ */
diff --git a/MeshLib/Mesh.cpp b/MeshLib/Mesh.cpp
new file mode 100644
index 00000000000..61a93f18f6c
--- /dev/null
+++ b/MeshLib/Mesh.cpp
@@ -0,0 +1,53 @@
+/**
+ * Mesh.cpp
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#include "Mesh.h"
+
+#include "Node.h"
+#include "Elements/Tri.h"
+#include "Elements/Quad.h"
+#include "Elements/Tet.h"
+#include "Elements/Hex.h"
+#include "Elements/Pyramid.h"
+#include "Elements/Prism.h"
+
+namespace MeshLib {
+
+Mesh::Mesh(const std::string &name, const std::vector<Node*> &nodes, const std::vector<Element*> &elements)
+	: _name(name), _nodes(nodes), _elements(elements)
+{
+	this->removeIdenticalNodes();
+}
+
+Mesh::Mesh(const Mesh &mesh)
+	: _name(mesh.getName()), _nodes(mesh.getNodes()), _elements(mesh.getElements())
+{
+}
+
+Mesh::Mesh(const std::string &file_name)
+{
+	// read mesh
+	this->removeIdenticalNodes();
+}
+
+Mesh::~Mesh()
+{
+	const size_t nElements (_elements.size());
+	for (size_t i=0; i<nElements; i++)
+		delete _elements[i];
+
+	const size_t nNodes (_nodes.size());
+	for (size_t i=0; i<nNodes; i++)
+		delete _nodes[i];
+}
+
+void Mesh::removeIdenticalNodes()
+{
+	//check for unique mesh nodes
+}
+
+}
\ No newline at end of file
diff --git a/MeshLib/Mesh.h b/MeshLib/Mesh.h
new file mode 100644
index 00000000000..2237e49a2c4
--- /dev/null
+++ b/MeshLib/Mesh.h
@@ -0,0 +1,42 @@
+/**
+ * Mesh.h
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#ifndef MESH_H_
+#define MESH_H_
+
+#include <cstdlib>
+#include <vector>
+
+namespace MeshLib {
+
+class Node;
+class Element;
+
+class Mesh
+{
+public:
+	Mesh(const std::string &name, const std::vector<Node*> &nodes, const std::vector<Element*> &elements);
+	Mesh(const Mesh &mesh);
+	Mesh(const std::string &file_name);
+	virtual ~Mesh();
+
+	const std::string getName() const { return _name; };
+	const std::vector<Node*> getNodes() const { return _nodes; };
+	const std::vector<Element*> getElements() const { return _elements; };
+
+protected:
+	void removeIdenticalNodes();
+
+	std::string _name;
+	std::vector<Node*> _nodes;
+	std::vector<Element*> _elements;
+
+}; /* class */
+
+} /* namespace */
+
+#endif /* MESH_H_ */
diff --git a/MeshLib/MshEnums.cpp b/MeshLib/MshEnums.cpp
new file mode 100644
index 00000000000..f7366cfd566
--- /dev/null
+++ b/MeshLib/MshEnums.cpp
@@ -0,0 +1,59 @@
+/**
+ * MSHEnums.cpp
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#include "MSHEnums.h"
+
+const std::string MshElemType2String(const MshElemType::type t)
+{
+	if (t == MshElemType::LINE)
+		return "line";
+	if (t == MshElemType::QUAD)
+		return "quad";
+	if (t == MshElemType::HEXAHEDRON)
+		return "hex";
+	if (t == MshElemType::TRIANGLE)
+		return "tri";
+	if (t == MshElemType::TETRAHEDRON)
+		return "tet";
+	if (t == MshElemType::PRISM)
+		return "pris";
+	if (t == MshElemType::PYRAMID)
+		return "pyra";
+	return "none";
+}
+
+MshElemType::type String2MshElemType(const std::string &s)
+{
+	if (s.compare("line") == 0)
+		return MshElemType::LINE;
+	if (s.compare("quad") == 0)
+		return MshElemType::QUAD;
+	if (s.compare("hex")  == 0)
+		return MshElemType::HEXAHEDRON;
+	if (s.compare("tri")  == 0)
+		return MshElemType::TRIANGLE;
+	if (s.compare("tet")  == 0)
+		return MshElemType::TETRAHEDRON;
+	if (s.compare("pris") == 0)
+		return MshElemType::PRISM;
+	if (s.compare("pyra") == 0)
+		return MshElemType::PYRAMID;
+	return MshElemType::INVALID;
+}
+
+const std::string MshQualityType2String(const MshQualityType::type t)
+{
+	if (t == MshQualityType::AREA)
+		return "Area";
+	if (t == MshQualityType::EDGERATIO)
+		return "EdgeRatio";
+	if (t == MshQualityType::EQUIANGLESKEW)
+		return "EquiAngleSkew";
+	if (t == MshQualityType::VOLUME)
+		return "Volume";
+	return "none";
+}
diff --git a/MeshLib/MshEnums.h b/MeshLib/MshEnums.h
new file mode 100644
index 00000000000..13211fc7e93
--- /dev/null
+++ b/MeshLib/MshEnums.h
@@ -0,0 +1,49 @@
+/**
+ * MSHEnums.h
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#ifndef MSHENUMS_H
+#define MSHENUMS_H
+
+#include <string>
+
+/**
+ * \brief Types of mesh elements supported by OpenGeoSys.
+ */
+struct MshElemType
+{
+	enum type {
+		INVALID,
+		LINE,
+		QUAD,
+		HEXAHEDRON,
+		TRIANGLE,
+		TETRAHEDRON,
+		PRISM,
+		PYRAMID
+	};
+};
+
+struct MshQualityType
+{
+	enum type {
+		INVALID = 0,
+		AREA,
+		VOLUME,
+		EDGERATIO,
+		EQUIANGLESKEW
+	};
+};
+
+/// Given a MshElemType this returns the appropriate string.
+const std::string MshElemType2String(const MshElemType::type t);
+
+/// Given a string describing an element type this returns the corresponding MshElemType.
+MshElemType::type String2MshElemType(const std::string &s);
+
+const std::string MshQualityType2String(const MshQualityType::type t);
+
+#endif //MSHENUMS_H
diff --git a/MeshLib/Node.cpp b/MeshLib/Node.cpp
new file mode 100644
index 00000000000..1da42acc9c0
--- /dev/null
+++ b/MeshLib/Node.cpp
@@ -0,0 +1,31 @@
+/**
+ * Node.cpp
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#include "Node.h"
+
+namespace MeshLib {
+
+Node::Node(double const*const coords, size_t id)
+	: GEOLIB::PointWithID(coords, id)
+{
+}
+
+Node::Node(double x, double y, double z, size_t id)
+	: GEOLIB::PointWithID(x, y, z, id)
+{
+}
+
+Node::Node(const Node &node)
+	: GEOLIB::PointWithID(node.getData(), node.getID())
+{
+}
+
+Node::~Node()
+{
+}
+
+}
\ No newline at end of file
diff --git a/MeshLib/Node.h b/MeshLib/Node.h
new file mode 100644
index 00000000000..9c08f4a5d21
--- /dev/null
+++ b/MeshLib/Node.h
@@ -0,0 +1,38 @@
+/**
+ * Node.h
+ *
+ *      Date: 2012/05/02
+ *      Author: KR
+ */
+
+#ifndef NODE_H_
+#define NODE_H_
+
+#include <cstdlib>
+#include <limits>
+#include <vector>
+#include "PointWithID.h"
+
+namespace MeshLib {
+
+class Element;
+
+/**
+ * A mesh node with coordinates in 3D space.
+ */
+class Node : public GEOLIB::PointWithID
+{
+public:
+	Node(double const*const coords, size_t id = std::numeric_limits<size_t>::max());
+	Node(double x, double y, double z, size_t id = std::numeric_limits<size_t>::max());
+	Node(const Node &node);
+	~Node();
+
+private:
+	std::vector<Element*> _elements;
+
+}; /* class */
+
+} /* namespace */
+
+#endif /* NODE_H_ */
-- 
GitLab