diff --git a/FileIO/Legacy/MeshIO.cpp b/FileIO/Legacy/MeshIO.cpp
index 3c047059cfee40f08c88b4c90f05e6b4039feca3..5aa53bd677eb9761c9e3f3d3c4593fc96242ad84 100644
--- a/FileIO/Legacy/MeshIO.cpp
+++ b/FileIO/Legacy/MeshIO.cpp
@@ -231,14 +231,11 @@ void MeshIO::writeElementsExceptLines(std::vector<MeshLib::Element*> const& ele_
 		}
 	}
 	out << n_elements << std::endl;
-	for (size_t i(0), k(0); i < ele_vector_size; i++) 
-	{
-		if (non_line_element[i] && non_null_element[i]) 
-		{
-			out << k << " 0 " << MshElemType2String(ele_vec[i]->getType()) << " ";
-			const size_t nElemNodes (ele_vec[i]->getNNodes()-1);
-			for(size_t j = 0; j < nElemNodes; j++)
-				out << ele_vec[i]->getNode(nElemNodes-j-1)->getID() << " ";
+	for (size_t i(0), k(0); i < ele_vector_size; i++) {
+		if (non_line_element[i] && non_null_element[i]) {
+			out << k << " " << ele_vec[i]->getValue() << " " << MshElemType2String(ele_vec[i]->getType()) << " ";
+			for(size_t j = 0; j < ele_vec[i]->getNNodes()-1; j++)
+				out << ele_vec[i]->getNode(j)->getID() << " ";
 			out << ele_vec[i]->getNode(ele_vec[i]->getNNodes()-1)->getID() << std::endl;
 			k++;
 		}
diff --git a/MathLib/MathTools.h b/MathLib/MathTools.h
index 505e58f990014a9abe05c417b2c5ad71900bd168..ad83ef5618b9aecbe10617b0cf21176a21d33154 100644
--- a/MathLib/MathTools.h
+++ b/MathLib/MathTools.h
@@ -121,7 +121,7 @@ double sqrDist(const double* p0, const double* p1);
 float normalize(float min, float max, float val);
 
 /**
- * Let \f$p_0, p_1, p_2 \in \mathbb{R}^3\f$. The function getAngle
+ * Let \f$p_0, p_1, p_2 \in R^3\f$. The function getAngle
  * computes the angle between the edges \f$(p_0,p_1)\f$ and \f$(p_1,p_2)\f$
  * @param p0 start point of edge 0
  * @param p1 end point of edge 0 and start point of edge 1
diff --git a/MeshLib/CMakeLists.txt b/MeshLib/CMakeLists.txt
index 537a0e1d6ad731059adac494570d900211dc4660..51087b6a8c68ab5ddbd7f07ebf06ff089938f8d0 100644
--- a/MeshLib/CMakeLists.txt
+++ b/MeshLib/CMakeLists.txt
@@ -12,6 +12,7 @@ include_directories(
 	../BaseLib
 	../GeoLib
 	../MathLib
+	${CMAKE_SOURCE_DIR}/BaseLib/logog/include
 )
 
 
@@ -19,5 +20,6 @@ target_link_libraries (MeshLib
 	BaseLib
 	GeoLib
 	MathLib
+	logog
 )
 
diff --git a/MeshLib/Elements/Edge.cpp b/MeshLib/Elements/Edge.cpp
index 3c0dca2874215119989f50817311895a42a93a96..a5db2266f985feb9e6bb1d0d53a4488d481f4139 100644
--- a/MeshLib/Elements/Edge.cpp
+++ b/MeshLib/Elements/Edge.cpp
@@ -57,5 +57,14 @@ Element* Edge::clone() const
 	return new Edge(*this);
 }
 
+Element* Edge::reviseElement() const
+{
+	if (_nodes[0] == _nodes[1]) {
+		return NULL;
+	}
+
+	return NULL;
+}
+
 }
 
diff --git a/MeshLib/Elements/Edge.h b/MeshLib/Elements/Edge.h
index cc6894d32cd0341fabd3849dcadeba95f7420963..5a4461d0b7a7576bf305fc223412f91f2e537fd0 100644
--- a/MeshLib/Elements/Edge.h
+++ b/MeshLib/Elements/Edge.h
@@ -22,10 +22,7 @@ class Node;
 /**
  * A 1d Edge or Line Element.
  * @code
- *
- *  Edge: o--------o
- *        0        1
- *
+ *  0--------1
  * @endcode
  */
 class Edge : public Element
@@ -80,12 +77,18 @@ public:
 
 	virtual Element* clone() const;
 
+	/**
+	 * If for instance two nodes of the element are collapsed the Edge element disappears.
+	 * @return NULL
+	 */
+	virtual Element* reviseElement() const;
+
 protected:
 	/// Calculate the length of this 1d element.
 	double computeLength();
 
 	/// 1D elements have no edges.
-	Node* getEdgeNode(unsigned edge_id, unsigned node_id) const { (void)edge_id; (void)node_id; return NULL; };
+	Node const* getEdgeNode(unsigned edge_id, unsigned node_id) const { (void)edge_id; (void)node_id; return NULL; };
 
 	/// 1D elements have no faces.
 	Node* getFaceNode(unsigned face_id, unsigned node_id) const { (void)face_id; (void)node_id; return NULL; };
diff --git a/MeshLib/Elements/Element.cpp b/MeshLib/Elements/Element.cpp
index a8572c56414295b49e0cd7917363f116ad5a3588..c751a180e46254e6c197d678022153be1c142ee9 100644
--- a/MeshLib/Elements/Element.cpp
+++ b/MeshLib/Elements/Element.cpp
@@ -72,8 +72,8 @@ const Element* Element::getEdge(unsigned i) const
 	if (i < getNEdges())
 	{
 		Node** nodes = new Node*[2];
-		nodes[0] = getEdgeNode(i,0);
-		nodes[1] = getEdgeNode(i,1);
+		nodes[0] = const_cast<Node*>(getEdgeNode(i,0));
+		nodes[1] = const_cast<Node*>(getEdgeNode(i,1));
 		return new Edge(nodes);
 	}
 	std::cerr << "Error in MeshLib::Element::getEdge() - Index does not exist." << std::endl;
@@ -87,7 +87,7 @@ void Element::computeSqrEdgeLengthRange(double &min, double &max) const
 	unsigned nEdges (this->getNEdges());
 	for (unsigned i=0; i<nEdges; i++)
 	{
-		double dist (MathLib::sqrDist(getEdgeNode(i,0)->getCoords(), getEdgeNode(i,1)->getCoords()));
+		double dist (MathLib::sqrDist(getEdgeNode(i,0), getEdgeNode(i,1)));
 		min = (dist<min) ? dist : min;
 		max = (dist>max) ? dist : max;
 	}
diff --git a/MeshLib/Elements/Element.h b/MeshLib/Elements/Element.h
index 3913348f83dff5ee063d79f45b104d90470aa7ef..20dd2b8b994fac02e3a9e4a95ba5e09eaa6b3481 100644
--- a/MeshLib/Elements/Element.h
+++ b/MeshLib/Elements/Element.h
@@ -36,16 +36,24 @@ public:
 	virtual void computeSqrEdgeLengthRange(double &min, double &max) const;
 
 	/**
-	 * \brief Tries to add an element e as neighbour to this element. 
+	 * \brief Tries to add an element e as neighbour to this element.
 	 * If the elements really are neighbours, the element is added to the
-	 * neighbour-ist and true is returned. Otherwise false is returned.
+	 * neighbour-list and true is returned. Otherwise false is returned.
 	 */
 	bool addNeighbor(Element* e);
 
 	/// Returns the length, area or volume of a 1D, 2D or 3D element
 	virtual double getContent() const = 0;
 
-	/// Get node with local index i.
+	/**
+	 * Get node with local index i where i should be at most the number
+	 * of nodes of the element
+	 * @param i local index of node, at most the number of nodes of the
+	 * element that you can obtain with Element::getNNodes()
+	 * @return a pointer to the appropriate (and constant, i.e. not
+	 * modifiable by the user) instance of class Node or a NULL pointer
+	 * @sa Element::getNodeIndex()
+	 */
 	const Node* getNode(unsigned i) const;
 
 	/**
@@ -85,7 +93,14 @@ public:
 	/// Get the number of nodes for this element.
 	virtual unsigned getNNodes() const = 0;
 
-	/// Get the global index for the node with local index i.
+	/**
+	 * Get the global index for the Node with local index i.
+	 * The index i should be at most the number of nodes of the element.
+	 * @param i local index of Node, at most the number of nodes of the
+	 * element that you can obtain with Element::getNNodes()
+	 * @return the global index or std::numeric_limits<unsigned>::max()
+	 * @sa Element::getNode()
+	 */
 	unsigned getNodeIndex(unsigned i) const;
 
 	/// Get the type of the mesh element (as a MshElemType-enum).
@@ -106,12 +121,22 @@ public:
 	 */
 	virtual Element* clone() const = 0;
 
+	/**
+	 * This method should be called after at least two nodes of an element
+	 * are collapsed. The node collapsing can/have to lead to an edge collapse.
+	 * This method tries to create a new element of an appropriate type. The
+	 * value of the attribute _value is carried over. In contrast to this the
+	 * neighbor information is not carried over.
+	 * @return an element of a different element type (MshElemType) or NULL
+	 */
+	virtual Element* reviseElement() const = 0;
+
 protected:
 	/// Constructor for a generic mesh element without an array of mesh nodes.
 	Element(unsigned value = 0);
 
 	/// Return a specific edge node.
-	virtual Node* getEdgeNode(unsigned edge_id, unsigned node_id) const = 0;
+	virtual Node const* getEdgeNode(unsigned edge_id, unsigned node_id) const = 0;
 
 	Node** _nodes;
 	unsigned _value;
diff --git a/MeshLib/Elements/Hex.cpp b/MeshLib/Elements/Hex.cpp
index f296292fd41373c18448b7070fee3a2cf497b696..b12fd76501bb10cf3c3e5f204997ad8b2f2da2de 100644
--- a/MeshLib/Elements/Hex.cpp
+++ b/MeshLib/Elements/Hex.cpp
@@ -13,6 +13,7 @@
 #include "Hex.h"
 #include "Node.h"
 #include "Quad.h"
+#include "Prism.h"
 
 #include "MathTools.h"
 
@@ -119,4 +120,50 @@ Element* Hex::clone() const
 	return new Hex(*this);
 }
 
+Element* Hex::reviseElement() const
+{
+	std::vector<size_t> collapsed_edges;
+	for (size_t edge(0); edge<getNEdges(); edge++) {
+		if (_nodes[_edge_nodes[edge][0]] == _nodes[_edge_nodes[edge][1]]) {
+			collapsed_edges.push_back(edge);
+		}
+	}
+
+	if (collapsed_edges.size() == 1) {
+		std::cerr << "[Hex::reviseElement()] collapsing of one edge in hexahedron not handled" << std::endl;
+		return NULL;
+	}
+
+	if (collapsed_edges.size() == 2) {
+		// try to create a prism out of the hex
+		if (collapsed_edges[0] == 0 && collapsed_edges[1] == 2) {
+			return new Prism(_nodes[0],_nodes[4], _nodes[5], _nodes[3], _nodes[7], _nodes[6], _value);
+		}
+		if (collapsed_edges[0] == 1 && collapsed_edges[1] == 3) {
+			return new Prism(_nodes[0],_nodes[4], _nodes[7], _nodes[1], _nodes[5], _nodes[6], _value);
+		}
+		if (collapsed_edges[0] == 4 && collapsed_edges[1] == 5) {
+			return new Prism(_nodes[0],_nodes[7], _nodes[3], _nodes[1], _nodes[6], _nodes[2], _value);
+		}
+		if (collapsed_edges[0] == 5 && collapsed_edges[1] == 6) {
+			return new Prism(_nodes[0],_nodes[1], _nodes[4], _nodes[3], _nodes[2], _nodes[7], _value);
+		}
+		if (collapsed_edges[0] == 6 && collapsed_edges[1] == 7) {
+			return new Prism(_nodes[0],_nodes[3], _nodes[4], _nodes[1], _nodes[2], _nodes[5], _value);
+		}
+		if (collapsed_edges[0] == 7 && collapsed_edges[1] == 4) {
+			return new Prism(_nodes[0],_nodes[1], _nodes[5], _nodes[3], _nodes[2], _nodes[6], _value);
+		}
+		if (collapsed_edges[0] == 8 && collapsed_edges[1] == 10) {
+			return new Prism(_nodes[0],_nodes[1], _nodes[4], _nodes[3], _nodes[2], _nodes[7], _value);
+		}
+		if (collapsed_edges[0] == 9 && collapsed_edges[1] == 11) {
+			return new Prism(_nodes[0],_nodes[3], _nodes[4], _nodes[1], _nodes[2], _nodes[5], _value);
+		}
+		return NULL;
+	}
+
+	return NULL;
+}
+
 } // end namespace MeshLib
diff --git a/MeshLib/Elements/Hex.h b/MeshLib/Elements/Hex.h
index f38b0217a60bfc63b4c01d915425395b0472ea62..172c9200604f1ccf1f906563a687cd1415074228 100644
--- a/MeshLib/Elements/Hex.h
+++ b/MeshLib/Elements/Hex.h
@@ -21,18 +21,24 @@ namespace MeshLib {
  * A 3d Hexahedron Element.
  * @code
  *
- *  Hex:  7        6
- *        o--------o
- *       /:       /|
- *      / :      / |
- *   4 /  :   5 /  |
- *    o--------o   |
- *    |   o....|...o 2
- *    |  .3    |  /
- *    | .      | /
- *    |.       |/
- *    o--------o
- *    0        1
+ *  Hex:
+ *                10
+ *          7-----------6
+ *         /:          /|
+ *        / :         / |
+ *     11/  :        /9 |
+ *      /  7:       /   | 6
+ *     /    : 8    /    |
+ *    4-----------5     |
+ *    |     :     | 2   |
+ *    |     3.....|.....2
+ *    |    .      |    /
+ *  4 |   .       |5  /
+ *    | 3.        |  / 1
+ *    | .         | /
+ *    |.          |/
+ *    0-----------1
+ *          0
  *
  * @endcode
  */
@@ -81,12 +87,18 @@ public:
 	 */
 	virtual Element* clone() const;
 
+	/**
+	 * Change the element type from hexahedron to a prism if two appropriate edges of the hexahedron are collapsed.
+	 * @return a prism element with nice properties or NULL
+	 */
+	virtual Element* reviseElement() const;
+
 protected:
 	/// Calculates the volume of a convex hexahedron by partitioning it into six tetrahedra.
 	double computeVolume();
 
 	/// Return a specific edge node.
-	inline Node* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; };
+	inline Node const* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; };
 
 	static const unsigned _face_nodes[6][4];
 	static const unsigned _edge_nodes[12][2];
diff --git a/MeshLib/Elements/Prism.cpp b/MeshLib/Elements/Prism.cpp
index ad5d9a6f8ef0ab3fc4bc0b730917ecd394588197..dde1cd3193d573678aa27273a59c8ad1cb91faf5 100644
--- a/MeshLib/Elements/Prism.cpp
+++ b/MeshLib/Elements/Prism.cpp
@@ -13,6 +13,7 @@
 #include "Prism.h"
 #include "Node.h"
 #include "Tri.h"
+#include "Pyramid.h"
 #include "Quad.h"
 
 #include "MathTools.h"
@@ -124,5 +125,23 @@ Element* Prism::clone() const
 	return new Prism(*this);
 }
 
+Element* Prism::reviseElement() const
+{
+	// try to create Pyramid
+	if (_nodes[_edge_nodes[3][0]] == _nodes[_edge_nodes[3][1]]) {
+		return new Pyramid(_nodes[1], _nodes[4], _nodes[5], _nodes[2], _nodes[0], _value);
+	}
+
+	if (_nodes[_edge_nodes[4][0]] == _nodes[_edge_nodes[4][1]]) {
+		return new Pyramid(_nodes[0], _nodes[2], _nodes[5], _nodes[3], _nodes[1], _value);
+	}
+
+	if (_nodes[_edge_nodes[5][0]] == _nodes[_edge_nodes[5][1]]) {
+		return new Pyramid(_nodes[0], _nodes[1], _nodes[4], _nodes[3], _nodes[2], _value);
+	}
+
+	return NULL;
+}
+
 } // end namespace MeshLib
 
diff --git a/MeshLib/Elements/Prism.h b/MeshLib/Elements/Prism.h
index 9ae85f7c102604396571ccac2cf4ec6d01f8e6c6..7649559424aabd8c46268d1cea297938f9b13bfb 100644
--- a/MeshLib/Elements/Prism.h
+++ b/MeshLib/Elements/Prism.h
@@ -18,19 +18,25 @@
 namespace MeshLib {
 
 /**
- * A 3d Prism Element.
+ * This class represents a 3d prism element. The following sketch shows the node and edge numbering.
+ * @anchor PrismNodeAndEdgeNumbering
  * @code
- *
- *  Prism:   5
- *           o
- *          /:\
- *         / : \
- *        /  o  \
- *     3 o-------o 4
- *       | . 2 . |
- *       |.     .|
- *       o-------o
- *       0       1
+ *            5
+ *           / \
+ *          / : \
+ *        8/  :  \7
+ *        /   :5  \
+ *       /    :  6 \
+ *      3-----------4
+ *      |     :     |
+ *      |     2     |
+ *      |    . .    |
+ *     3|   .   .   |4
+ *      | 2.     .1 |
+ *      | .       . |
+ *      |.         .|
+ *      0-----------1
+ *            0
  *
  * @endcode
  */
@@ -80,12 +86,23 @@ public:
 	 */
 	virtual Element* clone() const;
 
+	/**
+	 * This method should be called after at least two nodes of the prism
+	 * element are collapsed. As a consequence of the node collapsing an edge
+	 * of the prism will be collapsed. If one of the edges 3, 4 or 5 (see
+	 * sketch @ref PrismNodeAndEdgeNumbering) is collapsed we obtain a
+	 * pyramid. In this case the method will create the appropriate
+	 * object of class Pyramid.
+	 * @return a pyramid object or NULL
+	 */
+	virtual Element* reviseElement() const;
+
 protected:
 	/// Calculates the volume of a prism by subdividing it into three tetrahedra.
 	double computeVolume();
 
 	/// Return a specific edge node.
-	inline Node* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; };
+	inline Node const* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; };
 
 	static const unsigned _face_nodes[5][4];
 	static const unsigned _edge_nodes[9][2];
diff --git a/MeshLib/Elements/Pyramid.cpp b/MeshLib/Elements/Pyramid.cpp
index 5cf90b0b1d74ca1cc09aa52d31f4ed6e452a29d7..55b1cf0edbf07e0ff9c2e80b176c4d7cc61c2e40 100644
--- a/MeshLib/Elements/Pyramid.cpp
+++ b/MeshLib/Elements/Pyramid.cpp
@@ -13,6 +13,7 @@
 #include "Pyramid.h"
 #include "Node.h"
 #include "Tri.h"
+#include "Tet.h"
 #include "Quad.h"
 
 #include "MathTools.h"
@@ -123,4 +124,20 @@ Element* Pyramid::clone() const
 	return new Pyramid(*this);
 }
 
+Element* Pyramid::reviseElement() const
+{
+	// try to create tetrahedron
+	if (_nodes[_edge_nodes[0][0]] == _nodes[_edge_nodes[0][1]]
+		|| _nodes[_edge_nodes[1][0]] == _nodes[_edge_nodes[1][1]]) {
+		return new Tet(_nodes[0], _nodes[2], _nodes[3], _nodes[4], _value);
+	}
+
+	if (_nodes[_edge_nodes[2][0]] == _nodes[_edge_nodes[2][1]]
+	|| _nodes[_edge_nodes[3][0]] == _nodes[_edge_nodes[3][1]]) {
+		return new Tet(_nodes[0], _nodes[1], _nodes[2], _nodes[4], _value);
+	}
+
+	return NULL;
+}
+
 } // end namespace MeshLib
diff --git a/MeshLib/Elements/Pyramid.h b/MeshLib/Elements/Pyramid.h
index 0564fff185b686a23f483fb4bce82495e607caf6..4345d8bd3d0f9c9f0e6f16aec6bad1a052001012 100644
--- a/MeshLib/Elements/Pyramid.h
+++ b/MeshLib/Elements/Pyramid.h
@@ -18,20 +18,24 @@
 namespace MeshLib {
 
 /**
- * A 3d Pyramid Element.
+ * This class represents a 3d pyramid element. The following sketch shows the node and edge numbering.
+ * @anchor PyramidNodeAndEdgeNumbering
  * @code
  *
- *  Pyramid:   o 4
- *           //|\
- *          // | \
- *         //  |  \
- *      3 o/...|...o 2
- *       ./    |  /
- *      ./     | /
- *     ./      |/
- *    o--------o
- *    0        1
- *
+ *               4
+ *             //|\
+ *            // | \
+ *          7//  |  \6
+ *          //   |5  \
+ *         //    |    \
+ *        3/.... |.....2
+ *       ./      |  2 /
+ *      ./4      |   /
+ *    3./        |  /1
+ *    ./         | /
+ *   ./          |/
+ *  0------------1
+ *        0
  * @endcode
  */
 class Pyramid : public Cell
@@ -80,12 +84,23 @@ public:
 	 */
 	virtual Element* clone() const;
 
+	/**
+	 * This method should be called after at least two nodes of the pyramid
+	 * element are collapsed. As a consequence of the node collapsing an edge
+	 * of the pyramid will be collapsed. If one of the edges 0, 1, 2 or 3 (see
+	 * sketch @ref PyramidNodeAndEdgeNumbering) is collapsed we obtain a
+	 * tetrahedron. In this case the method will create the appropriate
+	 * object of class Tetrahedron.
+	 * @return a Tetrahedron object or NULL
+	 */
+	virtual Element* reviseElement() const;
+
 protected:
 	/// Calculates the volume of a prism by subdividing it into two tetrahedra.
 	double computeVolume();
 
 	/// Return a specific edge node.
-	inline Node* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; };
+	inline Node const* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; };
 
 	static const unsigned _face_nodes[5][4];
 	static const unsigned _edge_nodes[8][2];
diff --git a/MeshLib/Elements/Quad.cpp b/MeshLib/Elements/Quad.cpp
index a4b632f16ea245b8eaa3b515c2b57f6b8592c1ce..922871ddbee54da7015e137f04d08dbbc75e3991 100644
--- a/MeshLib/Elements/Quad.cpp
+++ b/MeshLib/Elements/Quad.cpp
@@ -12,6 +12,7 @@
 
 #include "Quad.h"
 #include "Node.h"
+#include "Tri.h"
 
 #include "MathTools.h"
 
@@ -22,7 +23,7 @@ const unsigned Quad::_edge_nodes[4][2] =
 {
 	{0, 1}, // Edge 0
 	{1, 2}, // Edge 1
-	{0, 2}, // Edge 2
+	{2, 3}, // Edge 2
 	{0, 3}  // Edge 3
 };
 
@@ -79,6 +80,19 @@ Element* Quad::clone() const
 	return new Quad(*this);
 }
 
+Element* Quad::reviseElement() const
+{
+	if (_nodes[0] == _nodes[1] || _nodes[1] == _nodes[2]) {
+		return new Tri(_nodes[0], _nodes[2], _nodes[3], _value);
+	}
+
+	if (_nodes[2] == _nodes[3] || _nodes[3] == _nodes[0]) {
+		return new Tri(_nodes[0], _nodes[1], _nodes[2], _value);
+	}
+
+	// this should not happen
+	return NULL;
+}
 
 }
 
diff --git a/MeshLib/Elements/Quad.h b/MeshLib/Elements/Quad.h
index e633c5df7faf73e780db4dd31c13f043e76021dd..2dfef14ab9ad8e27589d2a809bf163fd2dce1a49 100644
--- a/MeshLib/Elements/Quad.h
+++ b/MeshLib/Elements/Quad.h
@@ -18,19 +18,18 @@
 namespace MeshLib {
 
 /**
- * A 2d Quadliteral Element.
+ * This class represents a 2d quadliteral element. The following sketch shows the node and edge numbering.
+ * @anchor QuadNodeAndEdgeNumbering
  * @code
- *
- *        3           2
- *  Quad: o-----------o
- *        |           |
+ *              2
+ *        3-----------2
  *        |           |
  *        |           |
+ *       3|           |1
  *        |           |
  *        |           |
- *        o-----------o
- *        0           1
- *
+ *        0-----------1
+ *              0
  * @endcode
  */
 class Quad : public Face
@@ -69,12 +68,23 @@ public:
 	 */
 	virtual Element* clone() const;
 
+	/**
+	 * This method should be called after at least two nodes of the quad
+	 * element are collapsed. As a consequence of the node collapsing an edge
+	 * of the quad will be collapsed. If one of the edges (see
+	 * sketch @ref PyramidNodeAndEdgeNumbering) is collapsed we obtain a
+	 * triangle. In this case the method will create the appropriate
+	 * object of class Tri.
+	 * @return a Tri object or NULL
+	 */
+	virtual Element* reviseElement() const;
+
 protected:
 	/// Calculates the area of a convex quadliteral by dividing it into two triangles.
 	double computeArea();
 
 	/// Return a specific edge node.
-	inline Node* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; };
+	inline Node const* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; };
 
 	static const unsigned _edge_nodes[4][2];
 
diff --git a/MeshLib/Elements/Tet.cpp b/MeshLib/Elements/Tet.cpp
index d4c1aa3ef910065ce9629fd9460c0962dd167cc3..966ec3cfb5c7522c5d7d9c11b49e8f9135aa3406 100644
--- a/MeshLib/Elements/Tet.cpp
+++ b/MeshLib/Elements/Tet.cpp
@@ -111,6 +111,23 @@ Element* Tet::clone() const
 	return new Tet(*this);
 }
 
+Element* Tet::reviseElement() const
+{
+	if (_nodes[0] == _nodes[1] || _nodes[1] == _nodes[2]) {
+		return new Tri(_nodes[0], _nodes[2], _nodes[3], _value);
+	}
+
+	if (_nodes[2] == _nodes[0]) {
+		return new Tri(_nodes[0], _nodes[1], _nodes[3], _value);
+	}
 
+	if (_nodes[0] == _nodes[3] || _nodes[1] == _nodes[3] || _nodes[2] == _nodes[3]) {
+		return new Tri(_nodes[0], _nodes[1], _nodes[2], _value);
+	}
+
+	// this should not happen
+	return NULL;
 }
 
+} // end namespace MeshLib
+
diff --git a/MeshLib/Elements/Tet.h b/MeshLib/Elements/Tet.h
index 7164b02a93a2b17e1e5a602155c4ec36b2608ea4..6a8ac29f00882916f8889df97ca0ac967761c31d 100644
--- a/MeshLib/Elements/Tet.h
+++ b/MeshLib/Elements/Tet.h
@@ -18,20 +18,22 @@
 namespace MeshLib {
 
 /**
- * A 3d Tetrahedron Element.
+ * This class represents a 3d tetrahedron element. The following sketch shows the node and edge numbering.
+ * @anchor TetrahedronNodeAndEdgeNumbering
  * @code
- *
- *  Tet:  3
- *        o
- *       /|\
- *      / | \
- *     /  |  \
- *  0 o...|...o 2
- *     \  |  /
- *      \ | /
- *       \|/
- *        o
- *        1
+ *          3
+ *         /|\
+ *        / | \
+ *      3/  |  \5
+ *      /   |4  \
+ *     /    |    \
+ *    0.....|.....2
+ *     \    |  2 /
+ *      \   |   /
+ *      0\  |  /1
+ *        \ | /
+ *         \|/
+ *          1
  *
  * @endcode
  */
@@ -80,6 +82,15 @@ public:
 	 */
 	virtual Element* clone() const;
 
+	/**
+	 * This method should be called after at least two nodes of the tetrahedron
+	 * element are collapsed. As a consequence of the node collapsing an edge
+	 * of the tetrahedron will be collapsed. If one edge is collapsed we obtain
+	 * a triangle.
+	 * @return a Triangle object or NULL
+	 */
+	virtual Element* reviseElement() const;
+
 protected:
 	/// Constructor without nodes (for use of derived classes)
 	Tet(unsigned value = 0);
@@ -87,8 +98,13 @@ protected:
 	/// Calculates the volume of a tetrahedron via the determinant of the matrix given by its four points.
 	double computeVolume();
 
-	/// Return a specific edge node.
-	inline Node* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; };
+	/**
+	 * Return a specific edge node, see @ref TetrahedronNodeAndEdgeNumbering for numbering
+	 * @param edge_id the id/number of the edge, have to be an integer value in the interval [0,6]
+	 * @param node_id the id of the node within the edge (either 0 or 1)
+	 * @return a pointer to the internal Node
+	 */
+	inline Node const* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; };
 
 	static const unsigned _face_nodes[4][3];
 	static const unsigned _edge_nodes[6][2];
diff --git a/MeshLib/Elements/Tri.cpp b/MeshLib/Elements/Tri.cpp
index 3778b7c0e160609ddc2577364d04f7c443b731b0..653343ca2a3c43d63876252fa971f87d7262516a 100644
--- a/MeshLib/Elements/Tri.cpp
+++ b/MeshLib/Elements/Tri.cpp
@@ -11,6 +11,7 @@
  */
 
 #include "Tri.h"
+#include "Edge.h"
 #include "Node.h"
 
 #include "MathTools.h"
@@ -76,5 +77,19 @@ double Tri::computeArea()
 	return MathLib::calcTriangleArea(_nodes[0]->getCoords(), _nodes[1]->getCoords(), _nodes[2]->getCoords());
 }
 
+Element* Tri::reviseElement() const
+{
+	// try to create an edge
+	if (_nodes[0] == _nodes[1] || _nodes[1] == _nodes[2]) {
+		return new Edge(_nodes[0], _nodes[2], _value);
+	}
+
+	if (_nodes[0] == _nodes[2]) {
+		return new Edge(_nodes[0], _nodes[1], _value);
+	}
+
+	return NULL;
+}
+
 }
 
diff --git a/MeshLib/Elements/Tri.h b/MeshLib/Elements/Tri.h
index 3440323edb945e5c9068379babfc1a6fda810f18..d6ebcfce0538de9b3b5b02368fc9274ab536382f 100644
--- a/MeshLib/Elements/Tri.h
+++ b/MeshLib/Elements/Tri.h
@@ -18,18 +18,19 @@
 namespace MeshLib {
 
 /**
- * A 2d Triangle Element.
+ * This class represents a 2d triangle element. The following sketch shows the node and edge numbering.
+ * @anchor TriNodeAndEdgeNumbering
  * @code
  *
- *  Tri:    2
+ *          2
  *          o
  *         / \
  *        /   \
- *       /     \
+ *      2/     \1
  *      /       \
  *     /         \
- *    o-----------o
- *    0           1
+ *    0-----------1
+ *          0
  *
  * @endcode
  */
@@ -69,12 +70,22 @@ public:
 	 */
 	virtual Element* clone() const;
 
+	/**
+	 * This method should be called after at least two nodes of the triangle
+	 * element are collapsed. As a consequence of the node collapsing an edge
+	 * of the triangle will be collapsed. If one of the edges is collapsed we
+	 * obtain an edge. In this case the method will create the appropriate
+	 * object of class Edge.
+	 * @return an Edge object or NULL
+	 */
+	virtual Element* reviseElement() const;
+
 protected:
 	/// Calculates the area of the triangle by returning half of the area of the corresponding parallelogram.
 	double computeArea();
 
 	/// Return a specific edge node.
-	inline Node* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; };
+	inline Node const* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; };
 
 	static const unsigned _edge_nodes[3][2];
 
diff --git a/MeshLib/MeshCoarsener.cpp b/MeshLib/MeshCoarsener.cpp
index 8abd103d3f7b1320c5a9649247b8a578d02460e0..a739714207ffc0d39a6bcf33d2dcde412ad4ec45 100644
--- a/MeshLib/MeshCoarsener.cpp
+++ b/MeshLib/MeshCoarsener.cpp
@@ -9,6 +9,9 @@
  *  Created on  Aug 3, 2012 by Thomas Fischer
  */
 
+// BaseLib/logog
+#include "logog.hpp"
+
 #include "MeshCoarsener.h"
 
 // GeoLib
@@ -56,7 +59,7 @@ Mesh* MeshCoarsener::operator()(double min_distance)
 	for (size_t k(0); k < n_nodes; k++) {
 		std::vector<std::vector<Node*> const*> node_vecs_intersecting_cube;
 		Node const*const node(nodes[k]);
-		const size_t node_id(node->getID());
+		const size_t node_id_k(node->getID());
 		grid->getVecsOfGridCellsIntersectingCube(node->getCoords(), min_distance, node_vecs_intersecting_cube);
 
 		const size_t n_vecs (node_vecs_intersecting_cube.size());
@@ -64,10 +67,15 @@ Mesh* MeshCoarsener::operator()(double min_distance)
 			std::vector<Node*> const* node_vec (node_vecs_intersecting_cube[i]);
 			const size_t n_loc_nodes (node_vec->size());
 			for (size_t j(0); j<n_loc_nodes; j++) {
-				if (node_id < (*node_vec)[j]->getID()) {
-					if (MathLib::sqrDist(node->getCoords(), (*node_vec)[j]->getCoords()) < sqr_min_distance) {
+				Node const*const test_node((*node_vec)[j]);
+				const size_t test_node_id (test_node->getID());
+				if (node_id_k < test_node_id) {
+					if (MathLib::sqrDist(node->getCoords(), test_node->getCoords()) < sqr_min_distance) {
 						// two nodes are very close to each other
-						id_map[j] = k;
+						id_map[test_node_id] = node_id_k;
+#ifndef NDEBUG
+						INFO ("distance of nodes with ids %d and %d is %f", node_id_k, test_node_id, sqrt(MathLib::sqrDist(node->getCoords(), test_node->getCoords())));
+#endif
 					}
 				}
 			}
@@ -86,10 +94,12 @@ Mesh* MeshCoarsener::operator()(double min_distance)
 	}
 
 	// delete unused nodes
-	for (size_t k(0); k < n_nodes; k++) {
-		if (id_map[k] != k) {
+	for (size_t k(0), cnt(0); k < n_nodes; k++) {
+		if (id_map[k] != cnt) {
 			delete nodes[k];
 			nodes[k] = NULL;
+		} else {
+			cnt++;
 		}
 	}
 
@@ -102,26 +112,70 @@ Mesh* MeshCoarsener::operator()(double min_distance)
 		}
 	}
 
+	// reset mesh node ids
+	const size_t new_n_nodes(nodes.size());
+	for (size_t k(0); k < new_n_nodes; k++) {
+		nodes[k]->setID(k);
+	}
+
 	// copy mesh elements, reset the node pointers
 	std::vector<Element*> const& orig_elements(_orig_mesh->getElements());
 	const size_t n_elements(orig_elements.size());
 	std::vector<Element*> elements(n_elements);
-	for (size_t k(0); k < n_elements; k++) {
-		elements[k] = orig_elements[k]->clone();
-		const size_t n_nodes_element (elements[k]->getNNodes());
+	std::vector<size_t> mapped_node_ids_of_element;
+	for (size_t k(0), cnt(0); k < n_elements; k++) {
+		Element const*const kth_orig_elem(orig_elements[k]);
+		const size_t n_nodes_element (kth_orig_elem->getNNodes());
+		mapped_node_ids_of_element.clear();
 		for (size_t i(0); i<n_nodes_element; i++) {
-			const size_t orig_node_id (elements[k]->getNode(i)->getID());
-			size_t orig_node_pos (std::numeric_limits<size_t>::max());
+			const size_t orig_node_id (kth_orig_elem->getNode(i)->getID());
 			std::map<size_t, size_t>::const_iterator it(orig_ids_map.find(orig_node_id));
 			if (it == orig_ids_map.end()) {
 				std::cerr << "[MeshCoarsener::operator()] could not found mesh node id" << std::endl;
+			} else {
+				mapped_node_ids_of_element.push_back(id_map[it->second]);
+			}
+		}
+
+		// check if nodes of the element are collapsed
+		bool not_collapsed (true);
+		for (size_t i(0); i<n_nodes_element-1 && not_collapsed; i++) {
+			const size_t id_i(mapped_node_ids_of_element[i]);
+			for (size_t j(i+1); j<n_nodes_element && not_collapsed; j++) {
+				if (id_i == mapped_node_ids_of_element[j]) {
+					not_collapsed = false;
+				}
 			}
-			orig_node_pos = it->second;
-			elements[k]->setNode(i, nodes[id_map[orig_node_pos]]);
+		}
+		if (! not_collapsed) {
+			Element* elem (kth_orig_elem->clone());
+			if (elem != NULL) {
+				for (size_t i(0); i<n_nodes_element; i++) {
+					elem->setNode(i, nodes[mapped_node_ids_of_element[i]]);
+				}
+				Element* revised_elem(elem->reviseElement());
+				elements[cnt] = revised_elem;
+				delete elem;
+				cnt++;
+			}
+		} else {
+			elements[cnt] = kth_orig_elem->clone();
+			for (size_t i(0); i<n_nodes_element; i++) {
+				elements[cnt]->setNode(i, nodes[mapped_node_ids_of_element[i]]);
+			}
+			cnt++;
+		}
+	}
+
+	for (std::vector<Element*>::iterator it(elements.begin()); it != elements.end(); ) {
+		if (*it == NULL) {
+			it = elements.erase(it);
+		} else {
+			it++;
 		}
 	}
 
-	return new Mesh ("test", nodes, elements);
+	return new Mesh (_orig_mesh->getName() + "Collapsed", nodes, elements);
 }
 
 } // end namespace MeshLib
diff --git a/MeshLib/Node.h b/MeshLib/Node.h
index 703afbb8d2c3ed2cc8ef9b9fb3e7ce712c3444f2..740c05bb58959020ebbab69226da01ec9b900759 100644
--- a/MeshLib/Node.h
+++ b/MeshLib/Node.h
@@ -29,8 +29,9 @@ class Element;
  */
 class Node : public GeoLib::PointWithID
 {
-	/* friend functions: */
+	/* friend classes: */
 	friend class Mesh;//void Mesh::setElementInformationForNodes();
+	friend class MeshCoarsener;
 	//friend void Mesh::addElement(Element*);
 
 
diff --git a/SimpleTests/MeshTests/CollapseMeshNodes.cpp b/SimpleTests/MeshTests/CollapseMeshNodes.cpp
index 9e901b5860db5142cbbbfe36b2b1b3a71ed075a0..ee44736e2088a4aa288366480f328231f6cb9542 100644
--- a/SimpleTests/MeshTests/CollapseMeshNodes.cpp
+++ b/SimpleTests/MeshTests/CollapseMeshNodes.cpp
@@ -24,22 +24,42 @@
 #include "Legacy/MeshIO.h"
 #include "MeshCoarsener.h"
 
+
+/**
+ * new formatter for logog
+ */
+class FormatterCustom : public logog::FormatterGCC
+{
+    virtual TOPIC_FLAGS GetTopicFlags( const logog::Topic &topic )
+    {
+        return ( Formatter::GetTopicFlags( topic ) &
+                 ~( TOPIC_FILE_NAME_FLAG | TOPIC_LINE_NUMBER_FLAG ));
+    }
+};
+
 int main(int argc, char *argv[])
 {
 	LOGOG_INITIALIZE();
-	logog::Cout* logogCout = new logog::Cout;
+	FormatterCustom *custom_format (new FormatterCustom);
+	logog::Cout *logogCout(new logog::Cout);
+	logogCout->SetFormatter(*custom_format);
 
 	TCLAP::CmdLine cmd("Collapse mesh nodes and, if necessary, remove elements", ' ', "0.1");
 
 	// Define a value argument and add it to the command line.
 	// A value arg defines a flag and a type of value that it expects,
 	// such as "-m meshfile".
-	TCLAP::ValueArg<std::string> input_mesh_arg("m","mesh","input mesh file",true,"","string");
-
+	TCLAP::ValueArg<std::string> input_mesh_arg("m","mesh","input mesh file name",true,"","string");
 	// Add the argument mesh_arg to the CmdLine object. The CmdLine object
 	// uses this Arg to parse the command line.
 	cmd.add( input_mesh_arg );
 
+	TCLAP::ValueArg<std::string> output_mesh_arg("","out-mesh","mesh file name for output",false,"","string");
+	cmd.add( output_mesh_arg );
+
+	TCLAP::ValueArg<double> distance_arg("d","collapse-distance","maximal distance two nodes are collapsed",false,0.01,"for example you can set this parameter to 10^{-6} times maximal area length");
+	cmd.add( distance_arg );
+
 	cmd.parse( argc, argv );
 
 	std::string fname (input_mesh_arg.getValue());
@@ -55,11 +75,9 @@ int main(int argc, char *argv[])
 #ifndef WIN32
 	if (mesh) {
 		unsigned long mem_with_mesh (mem_watch.getVirtMemUsage());
-//	std::cout << "mem for mesh: " << (mem_with_mesh - mem_without_mesh)/(1024*1024) << " MB" << std::endl;
 		INFO ("mem for mesh: %i MB", (mem_with_mesh - mem_without_mesh)/(1024*1024));
 	}
 	run_time.stop();
-//	std::cout << "time for reading: " << run_time.elapsed() << " s" << std::endl;
 	if (mesh) {
 		INFO ("time for reading: %f s", run_time.elapsed());
 	}
@@ -70,7 +88,8 @@ int main(int argc, char *argv[])
 	run_time.start();
 #endif
 	MeshLib::MeshCoarsener mesh_coarsener(mesh);
-	MeshLib::Mesh *collapsed_mesh(mesh_coarsener (10));
+	MeshLib::Mesh *collapsed_mesh(mesh_coarsener (distance_arg.getValue()));
+
 #ifndef WIN32
 	run_time.stop();
 	unsigned long mem_with_meshgrid (mem_watch.getVirtMemUsage());
@@ -79,13 +98,19 @@ int main(int argc, char *argv[])
 #endif
 
 	mesh_io.setMesh(collapsed_mesh);
-	std::string out_fname("/home/fischeth/workspace/OGS-6/Build/CollapsedMesh.msh");
+	std::string out_fname (output_mesh_arg.getValue());
+	if (out_fname.empty()) {
+		out_fname = "/home/fischeth/workspace/OGS-6/Build/CollapsedMesh.msh";
+	}
 	INFO ("writing collapsed mesh to %s", out_fname.c_str());
 	mesh_io.writeToFile(out_fname);
 	INFO ("done");
 
 	delete mesh;
 	delete collapsed_mesh;
+	delete custom_format;
 	delete logogCout;
 	LOGOG_SHUTDOWN();
+
+	return 0;
 }