diff --git a/MeshLib/MeshGenerators/LayeredVolume.cpp b/MeshLib/MeshGenerators/LayeredVolume.cpp
index 7dca13f4f08e49e3f1e68531fd7bffaae445c70c..412b2e59ba4dd88c5976639c69456772445fb174 100644
--- a/MeshLib/MeshGenerators/LayeredVolume.cpp
+++ b/MeshLib/MeshGenerators/LayeredVolume.cpp
@@ -18,10 +18,11 @@
 
 #include "Raster.h"
 
-#include "Elements/Tri.h"
-#include "Elements/Quad.h"
-#include "MeshGenerators/MeshLayerMapper.h"
-#include "MeshEditing/ElementExtraction.h"
+#include "MeshLib/Elements/Tri.h"
+#include "MeshLib/Elements/Quad.h"
+#include "MeshLib/MeshEditing/ElementExtraction.h"
+#include "MeshLib/MeshEditing/DuplicateMeshComponents.h"
+#include "MeshLib/MeshGenerators/MeshLayerMapper.h"
 
 
 bool LayeredVolume::createRasterLayers(const MeshLib::Mesh &mesh, const std::vector<GeoLib::Raster const*> &rasters, double noDataReplacementValue)
@@ -32,52 +33,61 @@ bool LayeredVolume::createRasterLayers(const MeshLib::Mesh &mesh, const std::vec
 	_elevation_epsilon = calcEpsilon(*rasters[0], *rasters.back());
 	if (_elevation_epsilon <= 0)
 		return false;
-
+	
 	// remove line elements, only tri + quad remain
 	MeshLib::ElementExtraction ex(mesh);
 	ex.searchByElementType(MeshElemType::LINE);
-	MeshLib::Mesh* mesh_layer (ex.removeMeshElements("MeshLayer"));
-	if (mesh_layer==nullptr)
-		mesh_layer = new MeshLib::Mesh(mesh);
+	MeshLib::Mesh* top (ex.removeMeshElements("MeshLayer"));
+	if (top==nullptr)
+		top = new MeshLib::Mesh(mesh);
 
-	// map each layer and attach to subsurface mesh
-	const std::size_t nRasters (rasters.size());
-	for (size_t i=0; i<nRasters; ++i)
+	if (!MeshLayerMapper::layerMapping(*top, *rasters[0], noDataReplacementValue))
+		return false;
+
+	MeshLib::Mesh* bottom (new MeshLib::Mesh(*top));
+	if (!MeshLayerMapper::layerMapping(*bottom, *rasters.back(), 0))
 	{
-		const double replacement_value = (i==(nRasters-1)) ? noDataReplacementValue : rasters[i]->getNoDataValue();
-		if (!MeshLayerMapper::layerMapping(*mesh_layer, *rasters[i], replacement_value))
-		{
-			this->cleanUpOnError();
-			return false;
-		}
-		this->addLayerToMesh(*mesh_layer, i, *rasters[i]);
+		delete top;
+		return false;
 	}
+
+	_nodes = MeshLib::copyNodeVector(bottom->getNodes());
+	_elements = MeshLib::copyElementVector(bottom->getElements(), _nodes);
+	delete bottom;
+
+	// map each layer and attach to subsurface mesh
+	const std::size_t nRasters (rasters.size());
+	for (int i=nRasters-2; i>=0; --i)
+		this->addLayerToMesh(*top, nRasters-i-1, *rasters[i]);
+
 	// close boundaries between layers
-	this->addLayerBoundaries(*mesh_layer, nRasters);
-	this->removeCongruentElements(nRasters, mesh_layer->getNElements());
-	delete mesh_layer;
+	this->addLayerBoundaries(*top, nRasters);
+	this->removeCongruentElements(nRasters, top->getNElements());
+	delete top;
 	return true;
 }
 
-void LayeredVolume::addLayerToMesh(const MeshLib::Mesh &mesh_layer, unsigned layer_id, GeoLib::Raster const& raster)
+void LayeredVolume::addLayerToMesh(const MeshLib::Mesh &dem_mesh, unsigned layer_id, GeoLib::Raster const& raster)
 {
-	const std::vector<MeshLib::Node*> &layer_nodes (mesh_layer.getNodes());
-	const std::size_t nNodes (layer_nodes.size());
+	const std::size_t nNodes (dem_mesh.getNNodes());
+	const std::vector<MeshLib::Node*> const& nodes (dem_mesh.getNodes());
 	const std::size_t node_id_offset (_nodes.size());
 	const std::size_t last_layer_offset (node_id_offset-nNodes);
 	const double no_data_value (raster.getNoDataValue());
 
 	for (std::size_t i=0; i<nNodes; ++i)
 	{
-		if ((layer_id > 0) &&
-		    ((std::abs((*layer_nodes[i])[2] - no_data_value) < std::numeric_limits<double>::epsilon()) ||
-		     ((*_nodes[last_layer_offset+i])[2]-(*layer_nodes[i])[2] < _elevation_epsilon)))
+		// min of dem elevation and layer elevation
+		double const elevation = std::min(raster.interpolateValueAtPoint(*nodes[i]), (*nodes[i])[2]);
+
+		if ((std::abs(elevation - no_data_value) < std::numeric_limits<double>::epsilon()) ||
+		    (elevation - (*_nodes[last_layer_offset+i])[2] < _elevation_epsilon))
 			_nodes.push_back(new MeshLib::Node(*_nodes[last_layer_offset+i]));
 		else
-			_nodes.push_back(new MeshLib::Node(layer_nodes[i]->getCoords(), _nodes.size()));
+			_nodes.push_back(new MeshLib::Node((*nodes[i])[0], (*nodes[i])[1], elevation, _nodes.size()));
 	}
 
-	const std::vector<MeshLib::Element*> &layer_elements (mesh_layer.getElements());
+	const std::vector<MeshLib::Element*> &layer_elements (dem_mesh.getElements());
 	for (MeshLib::Element* elem : layer_elements)
 	{
 		if (elem->getGeomType() == MeshElemType::TRIANGLE)
@@ -85,7 +95,7 @@ void LayeredVolume::addLayerToMesh(const MeshLib::Mesh &mesh_layer, unsigned lay
 			std::array<MeshLib::Node*,3> tri_nodes = {{ _nodes[node_id_offset+elem->getNodeIndex(0)],
 			                                            _nodes[node_id_offset+elem->getNodeIndex(1)],
 			                                            _nodes[node_id_offset+elem->getNodeIndex(2)] }};
-			_elements.push_back(new MeshLib::Tri(tri_nodes, layer_id+1));
+			_elements.push_back(new MeshLib::Tri(tri_nodes, layer_id));
 		}
 		else if (elem->getGeomType() == MeshElemType::QUAD)
 		{
@@ -93,7 +103,7 @@ void LayeredVolume::addLayerToMesh(const MeshLib::Mesh &mesh_layer, unsigned lay
 			                                             _nodes[node_id_offset+elem->getNodeIndex(1)],
 			                                             _nodes[node_id_offset+elem->getNodeIndex(2)],
 			                                             _nodes[node_id_offset+elem->getNodeIndex(3)] }};
-			_elements.push_back(new MeshLib::Quad(quad_nodes, layer_id+1));
+			_elements.push_back(new MeshLib::Quad(quad_nodes, layer_id));
 		}
 	}
 }
@@ -132,21 +142,21 @@ void LayeredVolume::addLayerBoundaries(const MeshLib::Mesh &layer, std::size_t n
 
 void LayeredVolume::removeCongruentElements(std::size_t nLayers, std::size_t nElementsPerLayer)
 {
-	for (std::size_t i=1; i<nLayers; ++i)
+	for (std::size_t i=nLayers-1; i>0; --i)
 	{
-		const std::size_t upper_offset ((i-1) * nElementsPerLayer);
-		const std::size_t lower_offset ( i    * nElementsPerLayer);
+		const std::size_t lower_offset ((i-1) * nElementsPerLayer);
+		const std::size_t upper_offset ( i    * nElementsPerLayer);
 		for (std::size_t j=0; j<nElementsPerLayer; ++j)
 		{
-			MeshLib::Element *const high (_elements[upper_offset+j]);
-			MeshLib::Element const*const low  (_elements[lower_offset+j]);
+			MeshLib::Element const*const high (_elements[upper_offset+j]);
+			MeshLib::Element *const low  (_elements[lower_offset+j]);
 
 			unsigned count(0);
 			const std::size_t nElemNodes (low->getNNodes());
 			for (std::size_t k=0; k<nElemNodes; ++k)
 				if (high->getNodeIndex(k) == low->getNodeIndex(k))
 				{
-					high->setNode(k, _nodes[low->getNodeIndex(k)]);
+					low->setNode(k, _nodes[high->getNodeIndex(k)]);
 					count++;
 				}