diff --git a/apps/gpu/tests/NumericalTests/Utilities/DataWriter/AnalyticalResults2DToVTKWriter/AnalyticalResults2DToVTKWriterImp.cpp b/apps/gpu/tests/NumericalTests/Utilities/DataWriter/AnalyticalResults2DToVTKWriter/AnalyticalResults2DToVTKWriterImp.cpp
index 15032a8fd4ec6ce8f7684c33ceae0085d92f54c4..2bb7908b30a1c02afcc29d4244805df49263e62e 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/DataWriter/AnalyticalResults2DToVTKWriter/AnalyticalResults2DToVTKWriterImp.cpp
+++ b/apps/gpu/tests/NumericalTests/Utilities/DataWriter/AnalyticalResults2DToVTKWriter/AnalyticalResults2DToVTKWriterImp.cpp
@@ -16,6 +16,7 @@
 
 #include "Utilities/Results/AnalyticalResults/AnalyticalResult.h"
 #include <mpi.h>
+#include "core/Output/FilePartCalculator.h"
 
 std::shared_ptr<AnalyticalResults2DToVTKWriterImp>
 AnalyticalResults2DToVTKWriterImp::getInstance(bool writeAnalyticalResults)
@@ -40,7 +41,7 @@ void AnalyticalResults2DToVTKWriterImp::writeAnalyticalResult(std::shared_ptr<Pa
         for (int level = para->getCoarse(); level <= para->getFine(); level++) {
 #pragma omp parallel for
             for (int timeStep = 0; timeStep < analyticalResult->getNumberOfTimeSteps(); timeStep++) {
-                const unsigned int numberOfParts = para->getParH(level)->size_Mat / para->getLimitOfNodesForVTK() + 1;
+                const unsigned int numberOfParts = FilePartCalculator::calculateNumberOfParts(para->getParH(level)->size_Mat);
                 std::vector<std::string> fname;
                 unsigned int time =
                     analyticalResult->getTimeSteps().at(timeStep) * analyticalResult->getTimeStepLength();
@@ -93,13 +94,10 @@ void AnalyticalResults2DToVTKWriterImp::writeTimeStep(std::shared_ptr<Parameter>
     std::vector<double> vz = analyticalResult->getVz()[timeStep];
 
     for (unsigned int part = 0; part < fname.size(); part++) {
-        if (((part + 1) * para->getLimitOfNodesForVTK()) > para->getParH(level)->size_Mat)
-            sizeOfNodes = para->getParH(level)->size_Mat - (part * para->getLimitOfNodesForVTK());
-        else
-            sizeOfNodes = para->getLimitOfNodesForVTK();
+        sizeOfNodes = FilePartCalculator::calculateNumberOfNodesInPart(para->getParH(level)->size_Mat, part);
 
         //////////////////////////////////////////////////////////////////////////
-        startpos = part * para->getLimitOfNodesForVTK();
+        startpos = FilePartCalculator::calculateStartingPostionOfPart(part);
         endpos = startpos + sizeOfNodes;
         //////////////////////////////////////////////////////////////////////////
         cells.clear();
diff --git a/src/gpu/core/LBM/Simulation.cpp b/src/gpu/core/LBM/Simulation.cpp
index af3b3e70ff1c7bd822f659dcf7f0d63e5a3b6e81..1cf5dcf46e0e144f886b92473b11987846897043 100644
--- a/src/gpu/core/LBM/Simulation.cpp
+++ b/src/gpu/core/LBM/Simulation.cpp
@@ -102,11 +102,10 @@ void Simulation::init(GridProvider &gridProvider, BoundaryConditionFactory *bcFa
     gridProvider.setBoundingBox();
 
     para->setRe(para->getVelocity() * (real)1.0 / para->getViscosity());
-    para->setLimitOfNodesForVTK(30000000); // max 30 Million nodes per VTK file
     if (para->getDoRestart())
         para->setStartTurn(para->getTimeDoRestart());
     else
-        para->setStartTurn((unsigned int)0); // 100000
+        para->setStartTurn((unsigned int)0);
 
     restart_object = std::make_shared<ASCIIRestartObject>();
 
diff --git a/src/gpu/core/Output/FilePartCalculator.cpp b/src/gpu/core/Output/FilePartCalculator.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3e4e1353b8174273cc8dababba044561141df763
--- /dev/null
+++ b/src/gpu/core/Output/FilePartCalculator.cpp
@@ -0,0 +1,23 @@
+#include "FilePartCalculator.h"
+#include <stdexcept>
+
+uint FilePartCalculator::calculateNumberOfNodesInPart(uint numberOfNodes, uint indexOfFilePart)
+{
+    uint indexOfLastFilePart = FilePartCalculator::calculateNumberOfParts(numberOfNodes) - 1;
+
+    if (indexOfFilePart > indexOfLastFilePart)
+        throw std::runtime_error("The number of nodes for a non-existing part can not be calculated");
+    if (indexOfFilePart == indexOfLastFilePart)
+        return numberOfNodes - (indexOfFilePart * FilePartCalculator::limitOfNodesForVTK);
+    return FilePartCalculator::limitOfNodesForVTK;
+}
+
+uint FilePartCalculator::calculateNumberOfParts(uint numberOfNodes)
+{
+    return numberOfNodes / FilePartCalculator::limitOfNodesForVTK + 1;
+}
+
+uint FilePartCalculator::calculateStartingPostionOfPart(uint indexOfPart)
+{
+    return indexOfPart * FilePartCalculator::limitOfNodesForVTK;
+}
diff --git a/src/gpu/core/Output/FilePartCalculator.h b/src/gpu/core/Output/FilePartCalculator.h
new file mode 100644
index 0000000000000000000000000000000000000000..f0eaf4d5dc4b716edd29a3fbb663287f5b117872
--- /dev/null
+++ b/src/gpu/core/Output/FilePartCalculator.h
@@ -0,0 +1,23 @@
+#ifndef FILE_PART_CALCULATOR
+#define FILE_PART_CALCULATOR
+
+#include <basics/DataTypes.h>
+
+//! \brief calculations needed for writing the simulation's output into multiple file parts
+//! \details To prevent output files from becoming to large, they are split into multiple part files. For this process some
+//! calculations are needed.
+class FilePartCalculator
+{
+public:
+    //! \brief calculate how many output vtk-files are created for one timestep of the given grid level
+    static uint calculateNumberOfParts(uint numberOfNodes);
+    //! \brief calculate how many grid nodes are written to the file with the given index
+    static uint calculateNumberOfNodesInPart(uint numberOfNodes, uint indexOfFilePart);
+    //! \returns index of the first node in this file part
+    static uint calculateStartingPostionOfPart(uint indexOfPart);
+
+    //! \brief limits how many grid nodes are written into a single vtk file
+    static const uint limitOfNodesForVTK = 30e6; // max 30 million nodes per VTK file
+};
+
+#endif
diff --git a/src/gpu/core/Output/FilePartCalculatorTest.cpp b/src/gpu/core/Output/FilePartCalculatorTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c85e0ce2bb0f318b457e00a109e24fbed0a93aca
--- /dev/null
+++ b/src/gpu/core/Output/FilePartCalculatorTest.cpp
@@ -0,0 +1,36 @@
+#include "FilePartCalculator.h"
+#include "gpu/core/Utilities/testUtilitiesGPU.h"
+#include <gmock/gmock.h>
+
+TEST(FilePartCalculatorTest, calculateNumberOfParts)
+{
+    EXPECT_THAT(FilePartCalculator::calculateNumberOfParts(FilePartCalculator::limitOfNodesForVTK * 2), testing::Eq(3));
+
+    EXPECT_THAT(FilePartCalculator::calculateNumberOfParts(FilePartCalculator::limitOfNodesForVTK), testing::Eq(2));
+
+    EXPECT_THAT(FilePartCalculator::calculateNumberOfParts( FilePartCalculator::limitOfNodesForVTK - 1), testing::Eq(1));
+
+    EXPECT_THAT(FilePartCalculator::calculateNumberOfParts(1), testing::Eq(1));
+}
+
+TEST(FilePartCalculatorTest, calculateNumberOfNodesInPart)
+{
+    uint part = 0;
+    EXPECT_THAT(FilePartCalculator::calculateNumberOfNodesInPart(FilePartCalculator::limitOfNodesForVTK + 13, part),
+                FilePartCalculator::limitOfNodesForVTK);
+
+    part = 1;
+    EXPECT_THAT(FilePartCalculator::calculateNumberOfNodesInPart(FilePartCalculator::limitOfNodesForVTK + 13, part), 13);
+
+    part = 2;
+    EXPECT_THROW(FilePartCalculator::calculateNumberOfNodesInPart(FilePartCalculator::limitOfNodesForVTK + 13, part), std::runtime_error);
+}
+
+TEST(FilePartCalculatorTest, getStartingPostionOfPart)
+{
+    uint part = 0;
+    EXPECT_THAT(FilePartCalculator::calculateStartingPostionOfPart(part), 0);
+
+    part = 1;
+    EXPECT_THAT(FilePartCalculator::calculateStartingPostionOfPart(part), FilePartCalculator::limitOfNodesForVTK);
+}
diff --git a/src/gpu/core/Output/FileWriter.cpp b/src/gpu/core/Output/FileWriter.cpp
index 0e923204bfbe4b477d0698561b2167229ff91818..773bd58fafc63c4aad324605b0babde2a0acaac5 100644
--- a/src/gpu/core/Output/FileWriter.cpp
+++ b/src/gpu/core/Output/FileWriter.cpp
@@ -19,6 +19,7 @@
 #include "Parameter/Parameter.h"
 #include "GPU/CudaMemoryManager.h"
 #include "WriterUtilities.h"
+#include "FilePartCalculator.h"
 
 #include "LBM/LB.h"
 #include "lbm/constants/D3Q27.h"
@@ -87,7 +88,7 @@ void FileWriter::writeTimestep(std::shared_ptr<Parameter> para, unsigned int tim
 
 void FileWriter::writeTimestep(std::shared_ptr<Parameter> para, unsigned int timestep, int level)
 {
-    const unsigned int numberOfParts = WriterUtilities::calculateNumberOfParts(para.get(), level);
+    const unsigned int numberOfParts = FilePartCalculator::calculateNumberOfParts(para->getParH(level)->numberOfNodes);
     std::vector<std::string> fnames;
     std::vector<std::string> fnamesMed;
 
@@ -224,10 +225,11 @@ std::vector<std::string> FileWriter::writeUnstructuredGridLT(std::shared_ptr<Par
 
     for (unsigned int part = 0; part < fname.size(); part++)
     {
-        sizeOfNodes = WriterUtilities::calculateNumberOfNodesInPart(para.get(), level, part);
+        const LBMSimulationParameter& parH = para->getParHostAsReference(level);
+        sizeOfNodes = FilePartCalculator::calculateNumberOfNodesInPart(parH.numberOfNodes, part);
 
         //////////////////////////////////////////////////////////////////////////
-        startPosition = part * para->getLimitOfNodesForVTK();
+        startPosition = FilePartCalculator::calculateStartingPostionOfPart(part);
         endPosition = startPosition + sizeOfNodes;
         //////////////////////////////////////////////////////////////////////////
         cells.clear();
@@ -237,50 +239,49 @@ std::vector<std::string> FileWriter::writeUnstructuredGridLT(std::shared_ptr<Par
 
         //////////////////////////////////////////////////////////////////////////
         for (unsigned int pos = startPosition; pos < endPosition; pos++) {
-            const LBMSimulationParameter* parH = para->getParHConst(level).get();
-            if (parH->typeOfGridNode[pos] == GEO_FLUID) {
+            if (parH.typeOfGridNode[pos] == GEO_FLUID) {
                 //////////////////////////////////////////////////////////////////////////
-                double x1 = parH->coordinateX[pos];
-                double x2 = parH->coordinateY[pos];
-                double x3 = parH->coordinateZ[pos];
+                double x1 = parH.coordinateX[pos];
+                double x2 = parH.coordinateY[pos];
+                double x3 = parH.coordinateZ[pos];
                 //////////////////////////////////////////////////////////////////////////
                 relPosInPart = pos - startPosition;
                 //////////////////////////////////////////////////////////////////////////
                 nodes[relPosInPart] = (makeUbTuple((float)(x1), (float)(x2), (float)(x3)));
-                nodeData[0][relPosInPart] = (double)parH->pressure[pos] / (double)3.0 * (double)para->getDensityRatio() * (double)para->getVelocityRatio() * (double)para->getVelocityRatio();
-                nodeData[1][relPosInPart] = (double)parH->rho[pos] / (double)3.0 * (double)para->getDensityRatio() * (double)para->getVelocityRatio() * (double)para->getVelocityRatio();
-                nodeData[2][relPosInPart] = (double)parH->velocityX[pos] * (double)para->getVelocityRatio();
-                nodeData[3][relPosInPart] = (double)parH->velocityY[pos] * (double)para->getVelocityRatio();
-                nodeData[4][relPosInPart] = (double)parH->velocityZ[pos] * (double)para->getVelocityRatio();
-                nodeData[5][relPosInPart] = (double)parH->typeOfGridNode[pos];
+                nodeData[0][relPosInPart] = (double)parH.pressure[pos] / (double)3.0 * (double)para->getDensityRatio() * (double)para->getVelocityRatio() * (double)para->getVelocityRatio();
+                nodeData[1][relPosInPart] = (double)parH.rho[pos] / (double)3.0 * (double)para->getDensityRatio() * (double)para->getVelocityRatio() * (double)para->getVelocityRatio();
+                nodeData[2][relPosInPart] = (double)parH.velocityX[pos] * (double)para->getVelocityRatio();
+                nodeData[3][relPosInPart] = (double)parH.velocityY[pos] * (double)para->getVelocityRatio();
+                nodeData[4][relPosInPart] = (double)parH.velocityZ[pos] * (double)para->getVelocityRatio();
+                nodeData[5][relPosInPart] = (double)parH.typeOfGridNode[pos];
 
                 if(para->getDiffOn())
-                    nodeData[firstConcNode][relPosInPart] = (double)parH->concentration[pos];
+                    nodeData[firstConcNode][relPosInPart] = (double)parH.concentration[pos];
 
                 if(para->getIsBodyForce())
                 {
-                    nodeData[firstBodyForceNode    ][relPosInPart] = (double)parH->forceX_SP[pos] * (double)para->getScaledForceRatio(level);
-                    nodeData[firstBodyForceNode + 1][relPosInPart] = (double)parH->forceY_SP[pos] * (double)para->getScaledForceRatio(level);
-                    nodeData[firstBodyForceNode + 2][relPosInPart] = (double)parH->forceZ_SP[pos] * (double)para->getScaledForceRatio(level);
+                    nodeData[firstBodyForceNode    ][relPosInPart] = (double)parH.forceX_SP[pos] * (double)para->getScaledForceRatio(level);
+                    nodeData[firstBodyForceNode + 1][relPosInPart] = (double)parH.forceY_SP[pos] * (double)para->getScaledForceRatio(level);
+                    nodeData[firstBodyForceNode + 2][relPosInPart] = (double)parH.forceZ_SP[pos] * (double)para->getScaledForceRatio(level);
                 }
 
                 if(para->getUseTurbulentViscosity())
                 {
-                    nodeData[firstNutNode][relPosInPart] = (double)parH->turbViscosity[pos] * (double)para->getScaledViscosityRatio(level);
+                    nodeData[firstNutNode][relPosInPart] = (double)parH.turbViscosity[pos] * (double)para->getScaledViscosityRatio(level);
                 }
 
                 if (para->getCalcTurbulenceIntensity()) {
-                    nodeData[firstTurbulenceNode    ][relPosInPart] = (double)parH->vxx[pos];
-                    nodeData[firstTurbulenceNode + 1][relPosInPart] = (double)parH->vyy[pos];
-                    nodeData[firstTurbulenceNode + 2][relPosInPart] = (double)parH->vzz[pos];
-                    nodeData[firstTurbulenceNode + 3][relPosInPart] = (double)parH->vxy[pos];
-                    nodeData[firstTurbulenceNode + 4][relPosInPart] = (double)parH->vxz[pos];
-                    nodeData[firstTurbulenceNode + 5][relPosInPart] = (double)parH->vyz[pos];
+                    nodeData[firstTurbulenceNode    ][relPosInPart] = (double)parH.vxx[pos];
+                    nodeData[firstTurbulenceNode + 1][relPosInPart] = (double)parH.vyy[pos];
+                    nodeData[firstTurbulenceNode + 2][relPosInPart] = (double)parH.vzz[pos];
+                    nodeData[firstTurbulenceNode + 3][relPosInPart] = (double)parH.vxy[pos];
+                    nodeData[firstTurbulenceNode + 4][relPosInPart] = (double)parH.vxz[pos];
+                    nodeData[firstTurbulenceNode + 5][relPosInPart] = (double)parH.vyz[pos];
                 }
 
                 //////////////////////////////////////////////////////////////////////////
 
-                WriterUtilities::getIndicesOfAllNodesInOct(indicesOfOct, pos, para->getParHConst(level).get());
+                WriterUtilities::getIndicesOfAllNodesInOct(indicesOfOct, pos, para->getParHostAsReference(level));
 
                 if (WriterUtilities::isPeriodicCell(parH, indicesOfOct[0], indicesOfOct[6])) {
                     continue;
@@ -324,9 +325,9 @@ std::vector<std::string> FileWriter::writeUnstructuredGridMedianLT(std::shared_p
     {
         //printf("\n test in if I... \n");
         //////////////////////////////////////////////////////////////////////////
-        sizeOfNodes = WriterUtilities::calculateNumberOfNodesInPart(para.get(), level, part);
+        sizeOfNodes = FilePartCalculator::calculateNumberOfNodesInPart(para->getParH(level)->numberOfNodes, part);
         //////////////////////////////////////////////////////////////////////////
-        startPosition = part * para->getLimitOfNodesForVTK();
+        startPosition = FilePartCalculator::calculateStartingPostionOfPart(part);
         endPosition = startPosition + sizeOfNodes;
         //////////////////////////////////////////////////////////////////////////
         cells.clear();
@@ -390,7 +391,7 @@ std::vector<std::string> FileWriter::writeUnstructuredGridMedianLT(std::shared_p
                 dn7 = number7 - startPosition;
                 dn8 = number8 - startPosition;
                 //////////////////////////////////////////////////////////////////////////
-                if (WriterUtilities::isPeriodicCell(para->getParHConst(level).get(), number1, number7))
+                if (WriterUtilities::isPeriodicCell(para->getParHostAsReference(level), number1, number7))
                     continue;
                 //////////////////////////////////////////////////////////////////////////
                 if (neighborsFluid == true) cells.push_back(makeUbTuple(dn1, dn2, dn3, dn4, dn5, dn6, dn7, dn8));
diff --git a/src/gpu/core/Output/UnstructuredGridWriter.hpp b/src/gpu/core/Output/UnstructuredGridWriter.hpp
index a2aee7f94910af1c44af1d7444cde55fcacd2ee0..b86ed947879d94740f30668a9d53c4181d956ebf 100644
--- a/src/gpu/core/Output/UnstructuredGridWriter.hpp
+++ b/src/gpu/core/Output/UnstructuredGridWriter.hpp
@@ -193,22 +193,17 @@ namespace UnstructuredGridWriter
 		for (unsigned int part=0; part < fname.size(); part++)
 		{
 			vxmax = 0;
-			//printf("\n test in if I... \n");
-			//////////////////////////////////////////////////////////////////////////
-			if ( ((part+1)*para->getLimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
-			{
-                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
-			}
-			else
-			{
-				sizeOfNodes = para->getLimitOfNodesForVTK();
-			}
-			//////////////////////////////////////////////////////////////////////////
-			startpos = part * para->getLimitOfNodesForVTK();
-			endpos = startpos + sizeOfNodes;
-			//////////////////////////////////////////////////////////////////////////
-			cells.clear();
-			nodes.resize(sizeOfNodes);
+            // printf("\n test in if I... \n");
+            //////////////////////////////////////////////////////////////////////////
+
+            sizeOfNodes = FilePartCalculator::calculateNumberOfNodesInPart(para->getParH(level)->numberOfNodes);
+
+            //////////////////////////////////////////////////////////////////////////
+            startpos = FilePartCalculator::calculateStartingPostionOfPart(part);
+            endpos = startpos + sizeOfNodes;
+            //////////////////////////////////////////////////////////////////////////
+            cells.clear();
+            nodes.resize(sizeOfNodes);
 			nodedata[0].resize(sizeOfNodes);
 			nodedata[1].resize(sizeOfNodes);
 			nodedata[2].resize(sizeOfNodes);
@@ -338,16 +333,11 @@ namespace UnstructuredGridWriter
 			vxmax = 0;
 			//printf("\n test in if I... \n");
 			//////////////////////////////////////////////////////////////////////////
-            if (((part + 1) * para->getLimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
-			{
-                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
-			}
-			else
-			{
-				sizeOfNodes = para->getLimitOfNodesForVTK();
-			}
-			//////////////////////////////////////////////////////////////////////////
-			startpos = part * para->getLimitOfNodesForVTK();
+
+            sizeOfNodes = FilePartCalculator::calculateNumberOfNodesInPart(para->getParH(level)->numberOfNodes);
+
+            //////////////////////////////////////////////////////////////////////////
+			startpos = FilePartCalculator::calculateStartingPostionOfPart(part);
 			endpos = startpos + sizeOfNodes;
 			//////////////////////////////////////////////////////////////////////////
 			cells.clear();
@@ -477,16 +467,9 @@ namespace UnstructuredGridWriter
 			vxmax = 0;
 			//printf("\n test in if I... \n");
 			//////////////////////////////////////////////////////////////////////////
-            if (((part + 1) * para->getLimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
-			{
-                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
-			}
-			else
-			{
-				sizeOfNodes = para->getLimitOfNodesForVTK();
-			}
+            sizeOfNodes = FilePartCalculator::calculateNumberOfNodesInPart(para->getParH(level)->numberOfNodes);
 			//////////////////////////////////////////////////////////////////////////
-			startpos = part * para->getLimitOfNodesForVTK();
+			startpos = FilePartCalculator::calculateStartingPostionOfPart(part);
 			endpos = startpos + sizeOfNodes;
 			//////////////////////////////////////////////////////////////////////////
 			cells.clear();
@@ -626,16 +609,9 @@ namespace UnstructuredGridWriter
 			vxmax = 0;
 			//printf("\n test in if I... \n");
 			//////////////////////////////////////////////////////////////////////////
-            if (((part + 1) * para->getLimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
-			{
-                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
-			}
-			else
-			{
-				sizeOfNodes = para->getLimitOfNodesForVTK();
-			}
+            sizeOfNodes = FilePartCalculator::calculateNumberOfNodesInPart(para->getParH(level)->numberOfNodes);
 			//////////////////////////////////////////////////////////////////////////
-			startpos = part * para->getLimitOfNodesForVTK();
+			startpos = FilePartCalculator::calculateStartingPostionOfPart(part);
 			endpos = startpos + sizeOfNodes;
 			//////////////////////////////////////////////////////////////////////////
 			cells.clear();
@@ -769,16 +745,9 @@ namespace UnstructuredGridWriter
 			vxmax = 0;
 			//printf("\n test in if I... \n");
 			//////////////////////////////////////////////////////////////////////////
-            if (((part + 1) * para->getLimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
-			{
-                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
-			}
-			else
-			{
-				sizeOfNodes = para->getLimitOfNodesForVTK();
-			}
-			//////////////////////////////////////////////////////////////////////////
-			startpos = part * para->getLimitOfNodesForVTK();
+            sizeOfNodes = FilePartCalculator::calculateNumberOfNodesInPart(para->getParH(level)->numberOfNodes);
+            //////////////////////////////////////////////////////////////////////////
+			startpos = FilePartCalculator::calculateStartingPostionOfPart(part);
 			endpos = startpos + sizeOfNodes;
 			//////////////////////////////////////////////////////////////////////////
 			cells.clear();
@@ -1340,18 +1309,14 @@ namespace UnstructuredGridWriter
 			vxmax = 0;
 			//printf("\n test in if I... \n");
 			//////////////////////////////////////////////////////////////////////////
-			if ( ((part+1)*para->getLimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
-			{
-                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
-			}
-			else
-			{
-				sizeOfNodes = para->getLimitOfNodesForVTK();
-			}
-			//////////////////////////////////////////////////////////////////////////
-			startpos = part * para->getLimitOfNodesForVTK();
-			endpos = startpos + sizeOfNodes;
-			//////////////////////////////////////////////////////////////////////////
+
+            sizeOfNodes = FilePartCalculator::calculateNumberOfNodesInPart(para->getParH(level)->numberOfNodes);
+
+            //////////////////////////////////////////////////////////////////////////
+            startpos = FilePartCalculator::calculateStartingPostionOfPart(part);
+            endpos = startpos + sizeOfNodes;
+
+            //////////////////////////////////////////////////////////////////////////
 			cells.clear();
 			nodes.resize(sizeOfNodes);
 			nodedata[0].resize(sizeOfNodes);
@@ -1463,16 +1428,9 @@ namespace UnstructuredGridWriter
 			vxmax = 0;
 			//printf("\n test in if I... \n");
 			//////////////////////////////////////////////////////////////////////////
-            if (((part + 1) * para->getLimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
-			{
-                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
-			}
-			else
-			{
-				sizeOfNodes = para->getLimitOfNodesForVTK();
-			}
+            sizeOfNodes = FilePartCalculator::calculateNumberOfNodesInPart(para->getParH(level)->numberOfNodes);
 			//////////////////////////////////////////////////////////////////////////
-			startpos = part * para->getLimitOfNodesForVTK();
+			startpos = FilePartCalculator::calculateStartingPostionOfPart(part);
 			endpos = startpos + sizeOfNodes;
 			//////////////////////////////////////////////////////////////////////////
 			cells.clear();
@@ -1593,16 +1551,9 @@ namespace UnstructuredGridWriter
 			vxmax = 0;
 			//printf("\n test in if I... \n");
 			//////////////////////////////////////////////////////////////////////////
-            if (((part + 1) * para->getLimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
-			{
-                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
-			}
-			else
-			{
-				sizeOfNodes = para->getLimitOfNodesForVTK();
-			}
+            sizeOfNodes = FilePartCalculator::calculateNumberOfNodesInPart(para->getParH(level)->numberOfNodes);
 			//////////////////////////////////////////////////////////////////////////
-			startpos = part * para->getLimitOfNodesForVTK();
+			startpos = FilePartCalculator::calculateStartingPostionOfPart(part);
 			endpos = startpos + sizeOfNodes;
 			//////////////////////////////////////////////////////////////////////////
 			cells.clear();
@@ -1973,16 +1924,9 @@ namespace UnstructuredGridWriter
 			vxmax = 0;
 			//printf("\n test in if I... \n");
 			//////////////////////////////////////////////////////////////////////////
-            if (((part + 1) * para->getLimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
-			{
-                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
-			}
-			else
-			{
-				sizeOfNodes = para->getLimitOfNodesForVTK();
-			}
+            sizeOfNodes = FilePartCalculator::calculateNumberOfNodesInPart(para->getParH(level)->numberOfNodes);
 			//////////////////////////////////////////////////////////////////////////
-			startpos = part * para->getLimitOfNodesForVTK();
+			startpos = FilePartCalculator::calculateStartingPostionOfPart(part);
 			endpos = startpos + sizeOfNodes;
 			//////////////////////////////////////////////////////////////////////////
 			cells.clear();
@@ -2078,16 +2022,9 @@ namespace UnstructuredGridWriter
 			vxmax = 0;
 			//printf("\n test in if I... \n");
 			//////////////////////////////////////////////////////////////////////////
-            if (((part + 1) * para->getLimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
-			{
-                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
-			}
-			else
-			{
-				sizeOfNodes = para->getLimitOfNodesForVTK();
-			}
+            sizeOfNodes = FilePartCalculator::calculateNumberOfNodesInPart(para->getParH(level)->numberOfNodes);
 			//////////////////////////////////////////////////////////////////////////
-			startpos = part * para->getLimitOfNodesForVTK();
+			startpos = FilePartCalculator::calculateStartingPostionOfPart(part);
 			endpos = startpos + sizeOfNodes;
 			//////////////////////////////////////////////////////////////////////////
 			cells.clear();
@@ -2190,16 +2127,9 @@ namespace UnstructuredGridWriter
 			vxmax = 0;
 			//printf("\n test in if I... \n");
 			//////////////////////////////////////////////////////////////////////////
-            if (((part + 1) * para->getLimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
-			{
-                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
-			}
-			else
-			{
-				sizeOfNodes = para->getLimitOfNodesForVTK();
-			}
+            sizeOfNodes = FilePartCalculator::calculateNumberOfNodesInPart(para->getParH(level)->numberOfNodes);
 			//////////////////////////////////////////////////////////////////////////
-			startpos = part * para->getLimitOfNodesForVTK();
+			startpos = FilePartCalculator::calculateStartingPostionOfPart(part);
 			endpos = startpos + sizeOfNodes;
 			//////////////////////////////////////////////////////////////////////////
 			cells.clear();
diff --git a/src/gpu/core/Output/WriterUtilities.cpp b/src/gpu/core/Output/WriterUtilities.cpp
index 033f37c17b68a17099804ca2cef104e376d695bf..9752eb923ac8eb58850018f21697f9a32119f775 100644
--- a/src/gpu/core/Output/WriterUtilities.cpp
+++ b/src/gpu/core/Output/WriterUtilities.cpp
@@ -8,45 +8,32 @@ std::string WriterUtilities::makePartFileNameEnding(uint level, int ID, int part
            StringUtil::toString<int>(part) + "_t_" + StringUtil::toString<int>(timestep) + ".vtk";
 }
 
-uint WriterUtilities::calculateNumberOfParts(const Parameter* parameter, uint level)
-{
-    return (uint)parameter->getParHConst(level)->numberOfNodes / parameter->getLimitOfNodesForVTK() + 1;
-}
-
-bool WriterUtilities::isPeriodicCell(const LBMSimulationParameter* parH, unsigned int baseNodeOfCell,
+bool WriterUtilities::isPeriodicCell(const LBMSimulationParameter& parH, unsigned int baseNodeOfCell,
                                      unsigned int otherNodeInCell)
 {
-    real distance = sqrt(
-        pow(parH->coordinateX[otherNodeInCell] - parH->coordinateX[baseNodeOfCell], 2.) +
-        pow(parH->coordinateY[otherNodeInCell] - parH->coordinateY[baseNodeOfCell], 2.) +
-        pow(parH->coordinateZ[otherNodeInCell] - parH->coordinateZ[baseNodeOfCell], 2.));
-    return distance > 1.01 * sqrt(3 * pow(parH->gridSpacing, 2.));
-}
-
-uint WriterUtilities::calculateNumberOfNodesInPart(const Parameter* para, uint level, uint part)
-{
-    if (part >= WriterUtilities::calculateNumberOfParts(para, level))
-        throw std::runtime_error("The number of nodes for a non-existing part can not be calculated");
-    if (((part + 1) * para->getLimitOfNodesForVTK()) > (uint)para->getParHConst(level)->numberOfNodes)
-        return (uint)para->getParHConst(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
-    return para->getLimitOfNodesForVTK();
+    // perform periodicity check by calculating the length of the grid cell's space diagonal
+    const real distance = sqrt(
+        pow(parH.coordinateX[otherNodeInCell] - parH.coordinateX[baseNodeOfCell], 2.) +
+        pow(parH.coordinateY[otherNodeInCell] - parH.coordinateY[baseNodeOfCell], 2.) +
+        pow(parH.coordinateZ[otherNodeInCell] - parH.coordinateZ[baseNodeOfCell], 2.));
+    return distance > 1.01 * sqrt(3 * pow(parH.gridSpacing, 2.));
 }
 
 void WriterUtilities::getIndicesOfAllNodesInOct(std::array<uint, 8>& nodeIndices, uint baseNodeOfOct,
-                                                const LBMSimulationParameter* parH)
+                                                const LBMSimulationParameter& parH)
 {
     nodeIndices[0] = baseNodeOfOct;
-    nodeIndices[1] = parH->neighborX[nodeIndices[0]];
-    nodeIndices[2] = parH->neighborY[nodeIndices[1]];
-    nodeIndices[3] = parH->neighborY[nodeIndices[0]];
-    nodeIndices[4] = parH->neighborZ[nodeIndices[0]];
-    nodeIndices[5] = parH->neighborZ[nodeIndices[1]];
-    nodeIndices[6] = parH->neighborZ[nodeIndices[2]];
-    nodeIndices[7] = parH->neighborZ[nodeIndices[3]];
+    nodeIndices[1] = parH.neighborX[nodeIndices[0]];
+    nodeIndices[2] = parH.neighborY[nodeIndices[1]];
+    nodeIndices[3] = parH.neighborY[nodeIndices[0]];
+    nodeIndices[4] = parH.neighborZ[nodeIndices[0]];
+    nodeIndices[5] = parH.neighborZ[nodeIndices[1]];
+    nodeIndices[6] = parH.neighborZ[nodeIndices[2]];
+    nodeIndices[7] = parH.neighborZ[nodeIndices[3]];
 }
 
 void WriterUtilities::calculateRelativeNodeIndexInPart(std::array<uint, 8>& relativePositionInPart,
-                                                      const std::array<uint, 8>& indicesOfOct, uint startPositionOfPart)
+                                                       const std::array<uint, 8>& indicesOfOct, uint startPositionOfPart)
 {
     for (size_t i = 0; i < relativePositionInPart.size(); i++) {
         relativePositionInPart[i] = indicesOfOct[i] - startPositionOfPart;
@@ -54,13 +41,13 @@ void WriterUtilities::calculateRelativeNodeIndexInPart(std::array<uint, 8>& rela
 }
 
 bool WriterUtilities::areAllNodesInOctValidForWriting(const std::array<uint, 8>& indicesOfOct,
-                                                      const LBMSimulationParameter* parH, uint endPositionOfPart)
+                                                      const LBMSimulationParameter& parH, uint endPositionOfPart)
 {
-    bool neighborsAreFluid = std::all_of(indicesOfOct.begin(), indicesOfOct.end(),
-                                         [&](uint index) { return parH->typeOfGridNode[index] == GEO_FLUID; });
+    const bool neighborsAreFluid = std::all_of(indicesOfOct.begin(), indicesOfOct.end(),
+                                               [&](uint index) { return parH.typeOfGridNode[index] == GEO_FLUID; });
 
-    bool neighborIsOutOfPart =
+    const bool neighborIsOutOfPart =
         (std::any_of(indicesOfOct.begin(), indicesOfOct.end(), [&](uint index) { return index > endPositionOfPart; }));
 
     return neighborsAreFluid && !neighborIsOutOfPart;
-}
\ No newline at end of file
+}
diff --git a/src/gpu/core/Output/WriterUtilities.h b/src/gpu/core/Output/WriterUtilities.h
index eaa26dd549ef9190cf7e58197b2425732610078b..56bc756ddc26aa4090b1249d891640af7f8c909c 100644
--- a/src/gpu/core/Output/WriterUtilities.h
+++ b/src/gpu/core/Output/WriterUtilities.h
@@ -11,17 +11,28 @@ struct LBMSimulationParameter;
 class WriterUtilities
 {
 public:
-    static uint calculateNumberOfParts(const Parameter* para, uint level);
-    static uint calculateNumberOfNodesInPart(const Parameter* para, uint level, uint part);
-    static bool isPeriodicCell(const LBMSimulationParameter* parH, unsigned int baseNodeOfCell,
+    //! \brief check whether a grid cell is part of a periodic boundary condition
+    //! \param baseNodeOfCell is the index of one node of the grid cell
+    //! \param otherNodeInCell is the index of the node which is not on the same face of the grid cell as the base node (i.e.
+    //! it is on the other end of the space diagonal)
+    static bool isPeriodicCell(const LBMSimulationParameter& parH, unsigned int baseNodeOfCell,
                                unsigned int otherNodeInCell);
+
+    //! \brief use the neighbor relations to find the indices of all nodes in an oct cell
     static void getIndicesOfAllNodesInOct(std::array<uint, 8>& nodeIndices, uint baseNodeOfOct,
-                                          const LBMSimulationParameter* parH);
+                                          const LBMSimulationParameter& parH);
+
+    //! \brief calculate the node index relative to the start position of the part
     static void calculateRelativeNodeIndexInPart(std::array<uint, 8>& relativePositionInPart,
                                                  const std::array<uint, 8>& indicesOfOct, uint startPositionOfPart);
-    static bool areAllNodesInOctValidForWriting(const std::array<uint, 8>& indicesOfOct, const LBMSimulationParameter* parH,
+
+    //! \brief check if all nodes in an oct are valid to be written into an output file
+    //! \details to be valid the nodes need to be: 1. have the type GEO_FLUID, 2. not be outside the current file part
+    //! \param endPositionOfPart specifies the index of the last node in the current file part
+    static bool areAllNodesInOctValidForWriting(const std::array<uint, 8>& indicesOfOct, const LBMSimulationParameter& parH,
                                                 uint endPositionOfPart);
 
+    //! \brief create the ending of the file name for a file part
     static std::string makePartFileNameEnding(uint level, int processID, int part, int timestep);
 };
 
diff --git a/src/gpu/core/Output/WriterUtilitiesTest.cpp b/src/gpu/core/Output/WriterUtilitiesTest.cpp
index 4f90328177530d4e612dd7b4dbaa2625b8e280e9..2989abcf6194144d5d5ea9527977571916f7234a 100644
--- a/src/gpu/core/Output/WriterUtilitiesTest.cpp
+++ b/src/gpu/core/Output/WriterUtilitiesTest.cpp
@@ -4,43 +4,10 @@
 #include <gmock/gmock.h>
 #include <numeric>
 
-TEST(WriterUtilitiesTest, calculateNumberOfParts)
-{
-    const uint level = 0;
-    auto parameter = testingVF::createParameterForLevel(level);
-    parameter->setLimitOfNodesForVTK(10);
-
-    parameter->getParH(level)->numberOfNodes = 23;
-    EXPECT_THAT(WriterUtilities::calculateNumberOfParts(parameter.get(), level), testing::Eq(3));
-
-    parameter->getParH(level)->numberOfNodes = 13;
-    EXPECT_THAT(WriterUtilities::calculateNumberOfParts(parameter.get(), level), testing::Eq(2));
-
-    parameter->getParH(level)->numberOfNodes = 3;
-    EXPECT_THAT(WriterUtilities::calculateNumberOfParts(parameter.get(), level), testing::Eq(1));
-}
-
-TEST(WriterUtilitiesTest, calculateNumberOfNodesInPart)
-{
-    const uint level = 0;
-    auto parameter = testingVF::createParameterForLevel(level);
-    parameter->getParH(level)->numberOfNodes = 13;
-    parameter->setLimitOfNodesForVTK(10);
-
-    uint part = 0;
-    EXPECT_THAT(WriterUtilities::calculateNumberOfNodesInPart(parameter.get(), level, part), testing::Eq(10));
-
-    part = 1;
-    EXPECT_THAT(WriterUtilities::calculateNumberOfNodesInPart(parameter.get(), level, part), testing::Eq(3));
-
-    part = 2;
-    EXPECT_THROW(WriterUtilities::calculateNumberOfNodesInPart(parameter.get(), level, part), std::runtime_error);
-}
-
 class WriterUtilitiesPeriodicCellTest : public testing::Test
 {
 protected:
-    std::unique_ptr<LBMSimulationParameter> parH = std::make_unique<LBMSimulationParameter>();
+    LBMSimulationParameter parH = LBMSimulationParameter();
     const uint level = 0;
     const uint baseNodeIndex = 0;
     const uint otherNodeIndex = 1;
@@ -50,90 +17,91 @@ protected:
     {
         // create a domain with only three layers of nodes
         // nodes are at the coordinates 0.0, 1.0 and 2.0
-        parH->gridSpacing = 1.0;
-
-        parH->coordinateX = new real[2];
-        parH->coordinateY = new real[2];
-        parH->coordinateZ = new real[2];
-
-        parH->coordinateX[baseNodeIndex] = coordinates[baseNodeIndex];
-        parH->coordinateY[baseNodeIndex] = coordinates[baseNodeIndex];
-        parH->coordinateZ[baseNodeIndex] = coordinates[baseNodeIndex];
-        parH->coordinateX[otherNodeIndex] = coordinates[otherNodeIndex];
-        parH->coordinateY[otherNodeIndex] = coordinates[otherNodeIndex];
-        parH->coordinateZ[otherNodeIndex] = coordinates[otherNodeIndex];
+
+        parH.gridSpacing = 1.0;
+
+        parH.coordinateX = new real[2];
+        parH.coordinateY = new real[2];
+        parH.coordinateZ = new real[2];
+
+        parH.coordinateX[baseNodeIndex] = coordinates[baseNodeIndex];
+        parH.coordinateY[baseNodeIndex] = coordinates[baseNodeIndex];
+        parH.coordinateZ[baseNodeIndex] = coordinates[baseNodeIndex];
+        parH.coordinateX[otherNodeIndex] = coordinates[otherNodeIndex];
+        parH.coordinateY[otherNodeIndex] = coordinates[otherNodeIndex];
+        parH.coordinateZ[otherNodeIndex] = coordinates[otherNodeIndex];
     }
 
     void TearDown() override
     {
-        delete[] parH->coordinateX;
-        delete[] parH->coordinateY;
-        delete[] parH->coordinateZ;
+        delete[] parH.coordinateX;
+        delete[] parH.coordinateY;
+        delete[] parH.coordinateZ;
     }
 };
 
 TEST_F(WriterUtilitiesPeriodicCellTest, cellIsNotPeriodic)
 {
-    EXPECT_FALSE(WriterUtilities::isPeriodicCell(parH.get(), baseNodeIndex, otherNodeIndex));
-    EXPECT_FALSE(WriterUtilities::isPeriodicCell(parH.get(), otherNodeIndex, baseNodeIndex));
+    EXPECT_FALSE(WriterUtilities::isPeriodicCell(parH, baseNodeIndex, otherNodeIndex));
+    EXPECT_FALSE(WriterUtilities::isPeriodicCell(parH, otherNodeIndex, baseNodeIndex));
 }
 
 TEST_F(WriterUtilitiesPeriodicCellTest, cellIsPeriodicInX)
 {
-    parH->coordinateX[1] = 2.0;
-    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH.get(), baseNodeIndex, otherNodeIndex));
-    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH.get(), otherNodeIndex, baseNodeIndex));
+    parH.coordinateX[1] = 2.0;
+    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH, baseNodeIndex, otherNodeIndex));
+    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH, otherNodeIndex, baseNodeIndex));
 }
 
 TEST_F(WriterUtilitiesPeriodicCellTest, cellIsPeriodicInY)
 {
-    parH->coordinateY[1] = 2.0;
-    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH.get(), baseNodeIndex, otherNodeIndex));
-    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH.get(), otherNodeIndex, baseNodeIndex));
+    parH.coordinateY[1] = 2.0;
+    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH, baseNodeIndex, otherNodeIndex));
+    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH, otherNodeIndex, baseNodeIndex));
 }
 
 TEST_F(WriterUtilitiesPeriodicCellTest, cellIsPeriodicInZ)
 {
-    parH->coordinateZ[1] = 2.0;
-    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH.get(), baseNodeIndex, otherNodeIndex));
-    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH.get(), otherNodeIndex, baseNodeIndex));
+    parH.coordinateZ[1] = 2.0;
+    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH, baseNodeIndex, otherNodeIndex));
+    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH, otherNodeIndex, baseNodeIndex));
 }
 TEST_F(WriterUtilitiesPeriodicCellTest, cellIsPeriodicInXY)
 {
-    parH->coordinateX[1] = 2.0;
-    parH->coordinateY[1] = 2.0;
-    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH.get(), baseNodeIndex, otherNodeIndex));
-    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH.get(), otherNodeIndex, baseNodeIndex));
+    parH.coordinateX[1] = 2.0;
+    parH.coordinateY[1] = 2.0;
+    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH, baseNodeIndex, otherNodeIndex));
+    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH, otherNodeIndex, baseNodeIndex));
 }
 
 TEST_F(WriterUtilitiesPeriodicCellTest, cellIsPeriodicInXZ)
 {
-    parH->coordinateX[1] = 2.0;
-    parH->coordinateZ[1] = 2.0;
-    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH.get(), baseNodeIndex, otherNodeIndex));
-    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH.get(), otherNodeIndex, baseNodeIndex));
+    parH.coordinateX[1] = 2.0;
+    parH.coordinateZ[1] = 2.0;
+    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH, baseNodeIndex, otherNodeIndex));
+    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH, otherNodeIndex, baseNodeIndex));
 }
 
 TEST_F(WriterUtilitiesPeriodicCellTest, cellIsPeriodicInYZ)
 {
-    parH->coordinateY[1] = 2.0;
-    parH->coordinateZ[1] = 2.0;
-    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH.get(), baseNodeIndex, otherNodeIndex));
-    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH.get(), otherNodeIndex, baseNodeIndex));
+    parH.coordinateY[1] = 2.0;
+    parH.coordinateZ[1] = 2.0;
+    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH, baseNodeIndex, otherNodeIndex));
+    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH, otherNodeIndex, baseNodeIndex));
 }
 
 TEST_F(WriterUtilitiesPeriodicCellTest, cellIsPeriodicInXYZ)
 {
-    parH->coordinateX[1] = 2.0;
-    parH->coordinateY[1] = 2.0;
-    parH->coordinateZ[1] = 2.0;
-    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH.get(), baseNodeIndex, otherNodeIndex));
-    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH.get(), otherNodeIndex, baseNodeIndex));
+    parH.coordinateX[1] = 2.0;
+    parH.coordinateY[1] = 2.0;
+    parH.coordinateZ[1] = 2.0;
+    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH, baseNodeIndex, otherNodeIndex));
+    EXPECT_TRUE(WriterUtilities::isPeriodicCell(parH, otherNodeIndex, baseNodeIndex));
 }
 
 class WriterUtilitiesNeighborOctTest : public testing::Test
 {
-    static void setUpNeighborsNeighborsForOct(LBMSimulationParameter* parH, const std::array<uint, 8>& nodeIndices)
+    static void setUpNeighborsNeighborsForOct(LBMSimulationParameter& parH, const std::array<uint, 8>& nodeIndices)
     {
         // node indices: MMM, PMM, PPM, MPM,
         //               MMP, PMP, PPP, MPP
@@ -141,28 +109,28 @@ class WriterUtilitiesNeighborOctTest : public testing::Test
         for (uint i = 0; i < (uint)nodeIndices.size(); i++) {
             const uint currentNodeIndex = nodeIndices[i];
             if (i < 4)
-                parH->neighborZ[currentNodeIndex] = nodeIndices[i + 4];
+                parH.neighborZ[currentNodeIndex] = nodeIndices[i + 4];
             else
-                parH->neighborZ[currentNodeIndex] = 99;
+                parH.neighborZ[currentNodeIndex] = 99;
 
             if (i == 0 || i == 4)
-                parH->neighborY[currentNodeIndex] = nodeIndices[i + 3];
+                parH.neighborY[currentNodeIndex] = nodeIndices[i + 3];
             else if (i == 1 || i == 5)
-                parH->neighborY[currentNodeIndex] = nodeIndices[i + 1];
+                parH.neighborY[currentNodeIndex] = nodeIndices[i + 1];
             else
-                parH->neighborY[currentNodeIndex] = 999;
+                parH.neighborY[currentNodeIndex] = 999;
 
             if (i == 0 || i == 4)
-                parH->neighborX[currentNodeIndex] = nodeIndices[i + 1];
+                parH.neighborX[currentNodeIndex] = nodeIndices[i + 1];
             else if (i == 3 || i == 7)
-                parH->neighborX[currentNodeIndex] = nodeIndices[i - 1];
+                parH.neighborX[currentNodeIndex] = nodeIndices[i - 1];
             else
-                parH->neighborX[currentNodeIndex] = 9999;
+                parH.neighborX[currentNodeIndex] = 9999;
         }
     }
 
 public:
-    std::unique_ptr<LBMSimulationParameter> parH = std::make_unique<LBMSimulationParameter>();
+    LBMSimulationParameter parH = LBMSimulationParameter();
     std::array<uint, 8> nodeIndices;
 
     void SetUp() override
@@ -171,24 +139,24 @@ public:
         std::iota(nodeIndices.begin(), nodeIndices.end(), 0);
         std::reverse(nodeIndices.begin(), nodeIndices.end());
 
-        parH->neighborX = new uint[8];
-        parH->neighborY = new uint[8];
-        parH->neighborZ = new uint[8];
-        setUpNeighborsNeighborsForOct(parH.get(), nodeIndices);
+        parH.neighborX = new uint[8];
+        parH.neighborY = new uint[8];
+        parH.neighborZ = new uint[8];
+        setUpNeighborsNeighborsForOct(parH, nodeIndices);
     }
 
     void TearDown() override
     {
-        delete[] parH->neighborX;
-        delete[] parH->neighborY;
-        delete[] parH->neighborZ;
+        delete[] parH.neighborX;
+        delete[] parH.neighborY;
+        delete[] parH.neighborZ;
     }
 };
 
 TEST_F(WriterUtilitiesNeighborOctTest, getIndicesOfAllNodesInOct)
 {
     std::array<uint, 8> resultingNodeIndices;
-    WriterUtilities::getIndicesOfAllNodesInOct(resultingNodeIndices, nodeIndices[0], parH.get());
+    WriterUtilities::getIndicesOfAllNodesInOct(resultingNodeIndices, nodeIndices[0], parH);
     for (uint i = 0; i < 8; i++)
         EXPECT_THAT(resultingNodeIndices[i], testing::Eq(nodeIndices[i])) << "for index i = " << i << " in nodeIndices";
 }
@@ -207,7 +175,7 @@ TEST(WriterUtilitiesTest, calculateRelativeNodeIndexInPart)
 class WriterUtilitiesTestNodeValidity : public testing::Test
 {
 protected:
-    std::unique_ptr<LBMSimulationParameter> parH = std::make_unique<LBMSimulationParameter>();
+    LBMSimulationParameter parH = LBMSimulationParameter();
     std::array<uint, 8> nodeIndices;
     std::array<uint, 8> typeOfGridNode;
 
@@ -217,32 +185,32 @@ protected:
         std::iota(nodeIndices.begin(), nodeIndices.end(), 0);
 
         std::fill(typeOfGridNode.begin(), typeOfGridNode.end(), GEO_FLUID);
-        parH->typeOfGridNode = typeOfGridNode.data();
+        parH.typeOfGridNode = typeOfGridNode.data();
     }
 };
 
 TEST_F(WriterUtilitiesTestNodeValidity, allNodesInOctValidForWriting)
 {
     uint endPositionOfPart = 7;
-    EXPECT_TRUE(WriterUtilities::areAllNodesInOctValidForWriting(nodeIndices, parH.get(), endPositionOfPart));
+    EXPECT_TRUE(WriterUtilities::areAllNodesInOctValidForWriting(nodeIndices, parH, endPositionOfPart));
 }
 
 TEST_F(WriterUtilitiesTestNodeValidity, areAllNodesInOctValidForWriting_NodeOutOfPart)
 {
     uint endPositionOfPart = 6;
-    EXPECT_FALSE(WriterUtilities::areAllNodesInOctValidForWriting(nodeIndices, parH.get(), endPositionOfPart));
+    EXPECT_FALSE(WriterUtilities::areAllNodesInOctValidForWriting(nodeIndices, parH, endPositionOfPart));
 }
 
 TEST_F(WriterUtilitiesTestNodeValidity, areAllNodesInOctValidForWriting_NonFluidNode)
 {
     uint endPositionOfPart = 7;
     typeOfGridNode[0] = GEO_SOLID;
-    EXPECT_FALSE(WriterUtilities::areAllNodesInOctValidForWriting(nodeIndices, parH.get(), endPositionOfPart));
+    EXPECT_FALSE(WriterUtilities::areAllNodesInOctValidForWriting(nodeIndices, parH, endPositionOfPart));
 }
 
 TEST_F(WriterUtilitiesTestNodeValidity, areAllNodesInOctValidForWriting_NonFluidNodeAtEnd)
 {
     uint endPositionOfPart = 7;
     typeOfGridNode[7] = GEO_SOLID;
-    EXPECT_FALSE(WriterUtilities::areAllNodesInOctValidForWriting(nodeIndices, parH.get(), endPositionOfPart));
+    EXPECT_FALSE(WriterUtilities::areAllNodesInOctValidForWriting(nodeIndices, parH, endPositionOfPart));
 }
diff --git a/src/gpu/core/Parameter/Parameter.cpp b/src/gpu/core/Parameter/Parameter.cpp
index a3e975d4f4fb93c70fa5978281a9dfdd4fbb2494..135f19160b1eee0456dacdd31cfaf5db2021572e 100644
--- a/src/gpu/core/Parameter/Parameter.cpp
+++ b/src/gpu/core/Parameter/Parameter.cpp
@@ -665,10 +665,6 @@ void Parameter::setOutputCount(unsigned int outputCount)
 {
     this->outputCount = outputCount;
 }
-void Parameter::setLimitOfNodesForVTK(unsigned int limitOfNodesForVTK)
-{
-    this->limitOfNodesForVTK = limitOfNodesForVTK;
-}
 void Parameter::setStartTurn(unsigned int inStartTurn)
 {
     startTurn = inStartTurn;
@@ -1732,10 +1728,6 @@ unsigned int Parameter::getOutputCount()
 {
     return this->outputCount;
 }
-unsigned int Parameter::getLimitOfNodesForVTK() const
-{
-    return this->limitOfNodesForVTK;
-}
 unsigned int Parameter::getStartTurn()
 {
     return startTurn;
@@ -1749,14 +1741,14 @@ std::shared_ptr<LBMSimulationParameter> Parameter::getParH(int level)
     return parH[level];
 }
 
-std::shared_ptr<const LBMSimulationParameter> Parameter::getParDConst(int level) const
+LBMSimulationParameter& Parameter::getParDeviceAsReference(int level) const
 {
-    return parD[level];
+    return *parD[level];
 }
 
-std::shared_ptr<const LBMSimulationParameter> Parameter::getParHConst(int level) const
+LBMSimulationParameter& Parameter::getParHostAsReference(int level) const
 {
-    return parH[level];
+    return *parH[level];
 }
 
 const std::vector<std::shared_ptr<LBMSimulationParameter>> &Parameter::getParHallLevels()
diff --git a/src/gpu/core/Parameter/Parameter.h b/src/gpu/core/Parameter/Parameter.h
index 3db46194f24742c07a3c1f3e6d00ab11d0b5e285..5882b1524612aeb5c78d908a8936e4c296c47628 100644
--- a/src/gpu/core/Parameter/Parameter.h
+++ b/src/gpu/core/Parameter/Parameter.h
@@ -472,8 +472,8 @@ public:
     //! \brief Pointer to instance of LBMSimulationParameter - stored on Device (GPU)
     std::shared_ptr<LBMSimulationParameter> getParD(int level);
 
-    std::shared_ptr<const LBMSimulationParameter> getParHConst(int level) const;
-    std::shared_ptr<const LBMSimulationParameter> getParDConst(int level) const;
+    LBMSimulationParameter& getParHostAsReference(int level) const;
+    LBMSimulationParameter& getParDeviceAsReference(int level) const;
 
     const std::vector<std::shared_ptr<LBMSimulationParameter>>& getParHallLevels();
     const std::vector<std::shared_ptr<LBMSimulationParameter>>& getParDallLevels();
@@ -488,7 +488,6 @@ public:
     void setAngularVelocity(real inAngVel);
     void setStepEnsight(unsigned int step);
     void setOutputCount(unsigned int outputCount);
-    void setLimitOfNodesForVTK(unsigned int limitOfNodesForVTK);
     void setStartTurn(unsigned int inStartTurn);
     void setDiffOn(bool isDiff);
     void setCompOn(bool isComp);
@@ -710,7 +709,6 @@ public:
     real getEndXHotWall();
     unsigned int getStepEnsight();
     unsigned int getOutputCount();
-    unsigned int getLimitOfNodesForVTK() const;
     unsigned int getStartTurn();
     bool getEvenOrOdd(int level);
     bool getDiffOn();
@@ -1045,8 +1043,7 @@ private:
     int maxdev{ 1 };
 
     double memsizeGPU;
-    
-    uint limitOfNodesForVTK;
+
     uint outputCount;
     uint timestep;
     uint tDoCheckPoint{ 0 };
diff --git a/src/gpu/core/PreCollisionInteractor/PrecursorWriter.cu b/src/gpu/core/PreCollisionInteractor/PrecursorWriter.cu
index cae1ca5620caf5086f38f81dc81b931ae8ad0288..d1099b8d42ec14f2a4001b18f7b9fceecf660704 100644
--- a/src/gpu/core/PreCollisionInteractor/PrecursorWriter.cu
+++ b/src/gpu/core/PreCollisionInteractor/PrecursorWriter.cu
@@ -44,6 +44,7 @@
 #include "Parameter/Parameter.h"
 #include "DataStructureInitializer/GridProvider.h"
 #include "GPU/CudaMemoryManager.h"
+#include "Output/FilePartCalculator.h"
 
 using namespace vf::lbm::dir;
 using namespace vf::gpu;
@@ -208,7 +209,7 @@ void PrecursorWriter::init(Parameter* para, GridProvider* gridProvider, CudaMemo
         precursorStructs[level]->origin = makeUbTuple(lowestY, lowestZ);
         precursorStructs[level]->extent = makeUbTuple(0, ny-1, 0, nz-1);
         precursorStructs[level]->numberOfPointsInData = ny*nz;
-        precursorStructs[level]->numberOfTimestepsPerFile = min(para->getLimitOfNodesForVTK()/(ny*nz), maxtimestepsPerFile);
+        precursorStructs[level]->numberOfTimestepsPerFile = min(FilePartCalculator::limitOfNodesForVTK/(ny*nz), maxtimestepsPerFile);
         precursorStructs[level]->numberOfFilesWritten = 0;
         precursorStructs[level]->numberOfTimestepsBuffered = 0;
         
diff --git a/src/gpu/core/PreCollisionInteractor/Probes/Probe.cu b/src/gpu/core/PreCollisionInteractor/Probes/Probe.cu
index 5aa106e8c86bddeb75b9d3a0c1a6cc810a08d965..0bed2fff2e9861950a502cc7cc5017ee63ad4f36 100644
--- a/src/gpu/core/PreCollisionInteractor/Probes/Probe.cu
+++ b/src/gpu/core/PreCollisionInteractor/Probes/Probe.cu
@@ -44,6 +44,7 @@
 #include "Parameter/Parameter.h"
 #include "DataStructureInitializer/GridProvider.h"
 #include "GPU/CudaMemoryManager.h"
+#include "Output/FilePartCalculator.h"
 
 using namespace vf::basics::constant;
 
@@ -418,7 +419,7 @@ void Probe::write(Parameter* para, int level, int t)
     {
         int t_write = this->fileNameLU ? t: t/this->tOut; 
 
-        const uint numberOfParts = this->getProbeStruct(level)->nPoints / para->getLimitOfNodesForVTK() + 1;
+        const uint numberOfParts = this->getProbeStruct(level)->nPoints / FilePartCalculator::limitOfNodesForVTK + 1;
 
         std::vector<std::string> fnames;
         for (uint i = 1; i <= numberOfParts; i++)
@@ -453,8 +454,8 @@ void Probe::writeGridFile(Parameter* para, int level, int t, uint part)
 
     SPtr<ProbeStruct> probeStruct = this->getProbeStruct(level);
 
-    uint startpos = (part-1) * para->getLimitOfNodesForVTK();
-    uint sizeOfNodes = min(para->getLimitOfNodesForVTK(), probeStruct->nPoints - startpos);
+    uint startpos = (part-1) * FilePartCalculator::limitOfNodesForVTK;
+    uint sizeOfNodes = min(FilePartCalculator::limitOfNodesForVTK, probeStruct->nPoints - startpos);
     uint endpos = startpos + sizeOfNodes;
 
     //////////////////////////////////////////////////////////////////////////