From 38ddb70eb398533ded1d902c3482e0dc1b67f547 Mon Sep 17 00:00:00 2001
From: Konstantin Kutscher <kutscher@irmb.tu-bs.de>
Date: Fri, 25 Aug 2017 15:13:04 +0000
Subject: [PATCH] fix non reflect outflow add acoustic pulse test add
 MPIIORestartCoProcessor (n checkpoints to m processes) add
 InitDistributionsWithInterpolationGridVisitor add
 CompressibleOffsetMomentsInterpolationProcessor (refinement with bulk
 viscosity)

---
 source/Applications.cmake                     |    5 +-
 .../Applications/AcousticPulse/CMakeLists.txt |   25 +
 source/Applications/AcousticPulse/ap.cpp      |  253 +++
 .../DLR-F16/F16BombadilTest10e-6.cfg          |   17 +-
 source/Applications/DLR-F16/f16-porous.cfg    |   83 +
 source/Applications/DLR-F16/f16.cpp           |  454 ++--
 .../FlowAroundCylinder/cylinder.cfg           |   22 +
 .../FlowAroundCylinder/cylinder.cpp           |  318 ++-
 .../Hagen_Poiseuille_flow/pfDP.cfg            |   18 +-
 .../Hagen_Poiseuille_flow/pflow.cpp           |   85 +-
 .../Hagen_Poiseuille_flow2/CMakeLists.txt     |   25 +
 .../Hagen_Poiseuille_flow2/pf1.cfg            |   18 +
 .../Hagen_Poiseuille_flow2/pf2.cfg            |   18 +
 .../Hagen_Poiseuille_flow2/pf3.cfg            |   18 +
 .../Hagen_Poiseuille_flow2/pf4.cfg            |   19 +
 .../Hagen_Poiseuille_flow2/pfDP.cfg           |   18 +
 .../Hagen_Poiseuille_flow2/pflow2.cpp         |  334 +++
 source/Applications/LaminarTubeFlow/ltf.cfg   |   23 +-
 source/Applications/LaminarTubeFlow/ltf.cpp   |   76 +-
 source/Applications/levels/CMakeLists.txt     |   25 +
 source/Applications/levels/config.txt         |   22 +
 source/Applications/levels/levels.cpp         |  350 ++++
 source/Applications/sphere/config.txt         |    4 +-
 source/Applications/sphere/sphere.cpp         |   87 +-
 .../Library/basics/utilities/UbMath.h         |    1 +
 .../geometry3d/CoordinateTransformation3D.h   |    1 +
 .../numerics/geometry3d/GbTriFaceMesh3D.cpp   |   79 +
 .../numerics/geometry3d/GbVoxelMatrix3D.cpp   |   82 +
 .../numerics/geometry3d/GbVoxelMatrix3D.h     |   78 +-
 .../creator/GbTriFaceMesh3DCreator.cpp        |   76 +
 .../creator/GbTriFaceMesh3DCreator.h          |    1 +
 source/VirtualFluids.h                        |    9 +-
 .../BoundaryConditions/BCAlgorithm.cpp        |   30 +-
 .../BoundaryConditions/BCAlgorithm.h          |   13 +-
 .../BoundaryConditions/BCArray3D.cpp          |    7 +
 .../BoundaryConditions/BCArray3D.h            |    4 +
 .../BoundaryConditions/BoundaryConditions.h   |    1 +
 .../NonReflectingDensityBCAlgorithm.cpp       |  192 --
 .../NonReflectingOutflowBCAlgorithm.cpp       |  185 ++
 ...hm.h => NonReflectingOutflowBCAlgorithm.h} |   15 +-
 .../NonReflectingSlipBCAlgorithm.cpp          |   86 -
 .../NonReflectingSlipBCAlgorithm.h            |   27 -
 .../NonReflectingVelocityBCAlgorithm.cpp      |   59 -
 .../BoundaryConditions/SlipBCAlgorithm.cpp    |    2 +-
 .../VelocityWithDensityBCAlgorithm.cpp        |   82 +
 ...thm.h => VelocityWithDensityBCAlgorithm.h} |   16 +-
 .../CalculateForcesCoProcessor.cpp            |    4 +-
 .../CoProcessors/MPIIORestart2CoProcessor.cpp | 1154 +++++++++++
 .../CoProcessors/MPIIORestart2CoProcessor.h   |  163 ++
 .../CoProcessors/MPIIORestartCoProcessor.cpp  | 1281 +++++++-----
 .../CoProcessors/MPIIORestartCoProcessor.h    |   21 +-
 .../Connectors/D3Q27ETFCOffVectorConnector.h  |    2 +-
 .../FineToCoarseNodeSetBlock3DConnector.cpp   |    2 +-
 .../Data/D3Q27EsoTwist3DSplittedVector.h      |    1 +
 .../VirtualFluidsCore/Geometry/VoxelMatrix.h  |   57 +
 source/VirtualFluidsCore/Grid/Block3D.h       |    1 +
 .../BoostSerializationClassExportHelper.h     |    4 +-
 .../Grid/PrePostBcCalculator.cpp              |   17 +-
 .../LBM/CompressibleCumulantLBMKernel.cpp     | 1821 +++++++++--------
 .../LBM/CompressibleCumulantLBMKernel.h       |    6 +-
 ...mpressibleOffsetInterpolationProcessor.cpp |   98 +-
 ...CompressibleOffsetInterpolationProcessor.h |    2 +-
 ...bleOffsetMomentsInterpolationProcessor.cpp | 1278 ++++++++++++
 ...sibleOffsetMomentsInterpolationProcessor.h |   82 +
 ...mpressibleOffsetInterpolationProcessor.cpp |  125 +-
 .../LBM/InterpolationProcessor.cpp            |   14 +-
 .../LBM/InterpolationProcessor.h              |    1 +
 .../BoundaryConditionsBlockVisitor.cpp        |    4 +-
 .../InitDistributionsBlockVisitor.cpp         |   12 +-
 ...tributionsWithInterpolationGridVisitor.cpp |  311 +++
 ...istributionsWithInterpolationGridVisitor.h |   26 +
 ...butionsWithVelocityProfileBlockVisitor.cpp |  257 ---
 ...ributionsWithVelocityProfileBlockVisitor.h |   24 -
 .../RefineCrossAndInsideGbObjectHelper.cpp    |   47 +-
 .../RefineCrossAndInsideGbObjectHelper.h      |    3 +-
 .../SetUndefinedNodesBlockVisitor.cpp         |    4 +-
 76 files changed, 7456 insertions(+), 2729 deletions(-)
 create mode 100644 source/Applications/AcousticPulse/CMakeLists.txt
 create mode 100644 source/Applications/AcousticPulse/ap.cpp
 create mode 100644 source/Applications/DLR-F16/f16-porous.cfg
 create mode 100644 source/Applications/FlowAroundCylinder/cylinder.cfg
 create mode 100644 source/Applications/Hagen_Poiseuille_flow2/CMakeLists.txt
 create mode 100644 source/Applications/Hagen_Poiseuille_flow2/pf1.cfg
 create mode 100644 source/Applications/Hagen_Poiseuille_flow2/pf2.cfg
 create mode 100644 source/Applications/Hagen_Poiseuille_flow2/pf3.cfg
 create mode 100644 source/Applications/Hagen_Poiseuille_flow2/pf4.cfg
 create mode 100644 source/Applications/Hagen_Poiseuille_flow2/pfDP.cfg
 create mode 100644 source/Applications/Hagen_Poiseuille_flow2/pflow2.cpp
 create mode 100644 source/Applications/levels/CMakeLists.txt
 create mode 100644 source/Applications/levels/config.txt
 create mode 100644 source/Applications/levels/levels.cpp
 delete mode 100644 source/VirtualFluidsCore/BoundaryConditions/NonReflectingDensityBCAlgorithm.cpp
 create mode 100644 source/VirtualFluidsCore/BoundaryConditions/NonReflectingOutflowBCAlgorithm.cpp
 rename source/VirtualFluidsCore/BoundaryConditions/{NonReflectingDensityBCAlgorithm.h => NonReflectingOutflowBCAlgorithm.h} (52%)
 delete mode 100644 source/VirtualFluidsCore/BoundaryConditions/NonReflectingSlipBCAlgorithm.cpp
 delete mode 100644 source/VirtualFluidsCore/BoundaryConditions/NonReflectingSlipBCAlgorithm.h
 delete mode 100644 source/VirtualFluidsCore/BoundaryConditions/NonReflectingVelocityBCAlgorithm.cpp
 create mode 100644 source/VirtualFluidsCore/BoundaryConditions/VelocityWithDensityBCAlgorithm.cpp
 rename source/VirtualFluidsCore/BoundaryConditions/{NonReflectingVelocityBCAlgorithm.h => VelocityWithDensityBCAlgorithm.h} (52%)
 create mode 100644 source/VirtualFluidsCore/CoProcessors/MPIIORestart2CoProcessor.cpp
 create mode 100644 source/VirtualFluidsCore/CoProcessors/MPIIORestart2CoProcessor.h
 create mode 100644 source/VirtualFluidsCore/Geometry/VoxelMatrix.h
 create mode 100644 source/VirtualFluidsCore/LBM/CompressibleOffsetMomentsInterpolationProcessor.cpp
 create mode 100644 source/VirtualFluidsCore/LBM/CompressibleOffsetMomentsInterpolationProcessor.h
 create mode 100644 source/VirtualFluidsCore/Visitors/InitDistributionsWithInterpolationGridVisitor.cpp
 create mode 100644 source/VirtualFluidsCore/Visitors/InitDistributionsWithInterpolationGridVisitor.h
 delete mode 100644 source/VirtualFluidsCore/Visitors/InitDistributionsWithVelocityProfileBlockVisitor.cpp
 delete mode 100644 source/VirtualFluidsCore/Visitors/InitDistributionsWithVelocityProfileBlockVisitor.h

diff --git a/source/Applications.cmake b/source/Applications.cmake
index 4bc288816..e40afffb9 100644
--- a/source/Applications.cmake
+++ b/source/Applications.cmake
@@ -21,6 +21,7 @@ add_subdirectory(Applications/LaminarTubeFlow)
 # add_subdirectory(Applications/bond_benchmark)
 # add_subdirectory(Applications/musis)
 add_subdirectory(Applications/Hagen_Poiseuille_flow)
+add_subdirectory(Applications/Hagen_Poiseuille_flow2)
 add_subdirectory(Applications/mpi_benchmark)
 # add_subdirectory(Applications/shear)
 # add_subdirectory(Applications/wing)
@@ -47,4 +48,6 @@ add_subdirectory(Applications/DHIT)
 add_subdirectory(Applications/DLR-F16)
 add_subdirectory(Applications/aperm)
 add_subdirectory(Applications/f16test)
-add_subdirectory(Applications/mirror)
\ No newline at end of file
+add_subdirectory(Applications/mirror)
+add_subdirectory(Applications/levels)
+add_subdirectory(Applications/AcousticPulse)
\ No newline at end of file
diff --git a/source/Applications/AcousticPulse/CMakeLists.txt b/source/Applications/AcousticPulse/CMakeLists.txt
new file mode 100644
index 000000000..a7148e05a
--- /dev/null
+++ b/source/Applications/AcousticPulse/CMakeLists.txt
@@ -0,0 +1,25 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+
+########################################################
+## C++ PROJECT                                       ###
+########################################################
+PROJECT(AcousticPulse)
+
+INCLUDE(${SOURCE_ROOT}/IncludsList.cmake) 
+
+#################################################################
+###   LOCAL FILES                                             ###
+#################################################################
+FILE(GLOB SPECIFIC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.h
+                         ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
+                         ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp  )
+ 
+SET(ALL_SOURCES ${ALL_SOURCES} ${SPECIFIC_FILES})
+SOURCE_GROUP(src FILES ${SPECIFIC_FILES})
+  
+SET(CAB_ADDITIONAL_LINK_LIBRARIES VirtualFluids)
+
+#################################################################
+###   CREATE PROJECT                                          ###
+#################################################################
+CREATE_CAB_PROJECT(ap BINARY)
diff --git a/source/Applications/AcousticPulse/ap.cpp b/source/Applications/AcousticPulse/ap.cpp
new file mode 100644
index 000000000..6050bd588
--- /dev/null
+++ b/source/Applications/AcousticPulse/ap.cpp
@@ -0,0 +1,253 @@
+#include <iostream>
+#include <string>
+
+#include "VirtualFluids.h"
+
+using namespace std;
+
+
+void run(string configname)
+{
+   try
+   {
+      CommunicatorPtr comm = MPICommunicator::getInstance();
+      int myid = comm->getProcessID();
+
+      int    numOfThreads = 4;
+      double availMem = 5e9;
+
+      //40
+      //string  pathname = "d:/temp/AcousticPulse40Cube2y";
+      //double  endTime = 20;
+      //double  outTime = 20;
+      //LBMReal dx =  0.05;
+
+      //80
+      //string  pathname = "d:/temp/AcousticPulse80Cube2y";
+      //double  endTime = 40;
+      //double  outTime = 40;
+      //LBMReal dx = 0.025;
+
+      //160
+      string  pathname = "d:/temp/AcousticPulse160Cube2y";
+      double  endTime = 80;
+      double  outTime = 80;
+      LBMReal dx = 0.0125;
+
+      //LBMReal dx = 0.1; 
+      //LBMReal dx = 1.66666666667e-2; //120
+      
+      LBMReal rhoLB = 0.0;
+      LBMReal nuLB = 3.97e-7;
+
+      LBMUnitConverterPtr conv = LBMUnitConverterPtr(new LBMUnitConverter());
+
+      int baseLevel = 0;
+      int refineLevel = 1;
+
+      //bounding box
+      double g_minX1 = -1.0;
+      double g_minX2 = -1.0;
+      double g_minX3 = -1.0;
+
+      double g_maxX1 = 1.0;
+      double g_maxX2 = 1.0;
+      double g_maxX3 = 1.0;
+
+      //double g_minX1 = 0.0;
+      //double g_minX2 = 0.0;
+      //double g_minX3 = 0.0;
+
+      //double g_maxX1 = 5.0;
+      //double g_maxX2 = 5.0;
+      //double g_maxX3 = dx;
+
+      vector<int>  blocknx(3);
+      blocknx[0] = 10;
+      blocknx[1] = 10;
+      blocknx[2] = 10;
+
+      //geometry
+      GbObject3DPtr gridCube(new GbCuboid3D(g_minX1, g_minX2, g_minX3, g_maxX1, g_maxX2, g_maxX3));
+      if (myid == 0) GbSystem3D::writeGeoObject(gridCube.get(), pathname + "/geo/gridCube", WbWriterVtkXmlBinary::getInstance());
+
+
+      double blockLength = blocknx[0] * dx;
+
+      Grid3DPtr grid(new Grid3D(comm));
+
+      //////////////////////////////////////////////////////////////////////////
+      //restart
+      Grid3DPtr oldGrid(new Grid3D(comm));
+      UbSchedulerPtr rSch(new UbScheduler(10));
+      //MPIIORestartCoProcessor rcp(oldGrid, rSch, pathname, comm);
+      //rcp.restart(0);
+      //////////////////////////////////////////////////////////////////////////
+
+      grid->setDeltaX(dx);
+      grid->setBlockNX(blocknx[0], blocknx[1], blocknx[2]);
+      grid->setPeriodicX1(true);
+      grid->setPeriodicX2(true);
+      grid->setPeriodicX3(true);
+
+
+      GenBlocksGridVisitor genBlocks(gridCube);
+      grid->accept(genBlocks);
+
+      GbObject3DPtr refCube(new GbCuboid3D(-0.4,-0.4,-0.4,0.4,0.4,0.4));
+      if (myid==0) GbSystem3D::writeGeoObject(refCube.get(), pathname+"/geo/refCube", WbWriterVtkXmlBinary::getInstance());
+
+      if (refineLevel>0)
+      {
+         if (myid==0) UBLOG(logINFO, "Refinement - start");
+         RefineCrossAndInsideGbObjectHelper refineHelper(grid, refineLevel, comm);
+         refineHelper.addGbObject(refCube, refineLevel);
+         refineHelper.refine();
+         if (myid==0) UBLOG(logINFO, "Refinement - end");
+      }
+
+      WriteBlocksCoProcessorPtr ppblocks(new WriteBlocksCoProcessor(grid, UbSchedulerPtr(new UbScheduler(1)), pathname, WbWriterVtkXmlBinary::getInstance(), comm));
+
+      Grid3DVisitorPtr metisVisitor(new MetisPartitioningGridVisitor(comm, MetisPartitioningGridVisitor::LevelBased, D3Q27System::B));
+      InteractorsHelper intHelper(grid, metisVisitor);
+      intHelper.selectBlocks();
+
+      ppblocks->process(0);
+      ppblocks.reset();
+
+      //set connectors
+      //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+      InterpolationProcessorPtr iProcessor(new CompressibleOffsetMomentsInterpolationProcessor());
+      boost::dynamic_pointer_cast<CompressibleOffsetMomentsInterpolationProcessor>(iProcessor)->setBulkOmegaToOmega(true);
+      SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
+
+      UBLOG(logINFO, "SetConnectorsBlockVisitor:start");
+      grid->accept(setConnsVisitor);
+      UBLOG(logINFO, "SetConnectorsBlockVisitor:end");
+
+      //domain decomposition for threads
+      PQueuePartitioningGridVisitor pqPartVisitor(numOfThreads);
+      grid->accept(pqPartVisitor);
+
+
+      unsigned long long numberOfBlocks = (unsigned long long)grid->getNumberOfBlocks();
+      int ghostLayer = 3;
+      unsigned long long numberOfNodesPerBlock = (unsigned long long)(blocknx[0])* (unsigned long long)(blocknx[1])* (unsigned long long)(blocknx[2]);
+      unsigned long long numberOfNodes = numberOfBlocks * numberOfNodesPerBlock;
+      unsigned long long numberOfNodesPerBlockWithGhostLayer = numberOfBlocks * (blocknx[0] + ghostLayer) * (blocknx[1] + ghostLayer) * (blocknx[2] + ghostLayer);
+      double needMemAll = double(numberOfNodesPerBlockWithGhostLayer*(27 * sizeof(double) + sizeof(int) + sizeof(float) * 4));
+      double needMem = needMemAll / double(comm->getNumberOfProcesses());
+
+      if (myid == 0)
+      {
+         UBLOG(logINFO, "Number of blocks = " << numberOfBlocks);
+         UBLOG(logINFO, "Number of nodes  = " << numberOfNodes);
+         int minInitLevel = grid->getCoarsestInitializedLevel();
+         int maxInitLevel = grid->getFinestInitializedLevel();
+         for (int level = minInitLevel; level <= maxInitLevel; level++)
+         {
+            int nobl = grid->getNumberOfBlocks(level);
+            UBLOG(logINFO, "Number of blocks for level " << level << " = " << nobl);
+            UBLOG(logINFO, "Number of nodes for level " << level << " = " << nobl*numberOfNodesPerBlock);
+         }
+         UBLOG(logINFO, "Necessary memory  = " << needMemAll << " bytes");
+         UBLOG(logINFO, "Necessary memory per process = " << needMem << " bytes");
+         UBLOG(logINFO, "Available memory per process = " << availMem << " bytes");
+      }
+
+
+      LBMKernelPtr kernel = LBMKernelPtr(new CompressibleCumulantLBMKernel(blocknx[0], blocknx[1], blocknx[2], CompressibleCumulantLBMKernel::NORMAL));
+      boost::dynamic_pointer_cast<CompressibleCumulantLBMKernel>(kernel)->setBulkOmegaToOmega(true);
+      //
+      BCProcessorPtr bcProcessor(new BCProcessor());
+
+      kernel->setBCProcessor(bcProcessor);
+
+      SetKernelBlockVisitor kernelVisitor(kernel, nuLB, availMem, needMem);
+      grid->accept(kernelVisitor);
+
+      if (refineLevel>0)
+      {
+         SetUndefinedNodesBlockVisitor undefNodesVisitor;
+         grid->accept(undefNodesVisitor);
+      }
+
+      mu::Parser fctRoh;
+      //z
+      //fctRoh.SetExpr("epsilon*exp(-alpha*(x1*x1+x2*x2))");
+      //x
+      //fctRoh.SetExpr("epsilon*exp(-alpha*(x3*x3+x2*x2))");
+      //y
+      fctRoh.SetExpr("epsilon*exp(-alpha*(x3*x3+x1*x1))");
+
+      fctRoh.DefineConst("epsilon", 1e-3);
+      fctRoh.DefineConst("alpha", log(2.0)/(0.01));
+      //fctRoh.SetExpr("x1*0.001");
+
+      //initialization of distributions
+      InitDistributionsBlockVisitor initVisitor(nuLB, rhoLB);
+      initVisitor.setRho(fctRoh);
+      grid->accept(initVisitor);
+
+      //InitDistributionsWithCoarseGridBlockVisitor initVisitor(oldGrid, grid, iProcessor, nuLB);
+      //grid->accept(initVisitor);
+
+
+      //Postrozess
+      UbSchedulerPtr geoSch(new UbScheduler(1));
+      WriteBoundaryConditionsCoProcessorPtr ppgeo(
+         new WriteBoundaryConditionsCoProcessor(grid, geoSch, pathname, WbWriterVtkXmlBinary::getInstance(), conv, comm));
+      ppgeo->process(0);
+      ppgeo.reset();
+
+      if (myid==0) UBLOG(logINFO, "Preprozess - end");
+
+      if (myid == 0)
+      {
+         UBLOG(logINFO, "PID = " << myid << " Total Physical Memory (RAM): " << Utilities::getTotalPhysMem());
+         UBLOG(logINFO, "PID = " << myid << " Physical Memory currently used: " << Utilities::getPhysMemUsed());
+         UBLOG(logINFO, "PID = " << myid << " Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe());
+      }
+
+      UbSchedulerPtr visSch(new UbScheduler(outTime));
+      WriteMacroscopicQuantitiesCoProcessor pp(grid, visSch, pathname, WbWriterVtkXmlBinary::getInstance(), conv, comm);
+
+      UbSchedulerPtr nupsSch(new UbScheduler(10, 30, 100));
+      NUPSCounterCoProcessor npr(grid, nupsSch, numOfThreads, comm);
+
+      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, visSch));
+      if (myid == 0) UBLOG(logINFO, "Simulation-start");
+      calculation->calculate();
+      if (myid == 0) UBLOG(logINFO, "Simulation-end");
+   }
+   catch (std::exception& e)
+   {
+      cerr << e.what() << endl << flush;
+   }
+   catch (std::string& s)
+   {
+      cerr << s << endl;
+   }
+   catch (...)
+   {
+      cerr << "unknown exception" << endl;
+   }
+
+}
+int main(int argc, char* argv[])
+{
+   //if (argv != NULL)
+   //{
+      //if (argv[1] != NULL)
+      //{
+      //   run(string(argv[1]));
+      //}
+      //else
+      //{
+      //   cout << "Configuration file is missing!" << endl;
+      //}
+   //}
+
+   run("hallo");
+}
+
diff --git a/source/Applications/DLR-F16/F16BombadilTest10e-6.cfg b/source/Applications/DLR-F16/F16BombadilTest10e-6.cfg
index 257cda076..9066cf548 100644
--- a/source/Applications/DLR-F16/F16BombadilTest10e-6.cfg
+++ b/source/Applications/DLR-F16/F16BombadilTest10e-6.cfg
@@ -7,9 +7,9 @@ fngFileBodyPart = f16-body-part-ascii.stl
 fngFileTrailingEdge = f16-trailing-edge-ascii.stl
 zigZagTape = 2zackenbaender0.stl
 
-numOfThreads = 4
+numOfThreads = 1
 availMem = 13e9
-refineLevel = 4 #10
+refineLevel = 9 #10
 #blockNx = 7 8 8
 #blockNx = 7 6 7
 blockNx = 21 6 13
@@ -41,29 +41,30 @@ boundingBox = -0.90 1.20 0.035 0.065 -0.65 0.65
 #deltaXfine = 0.0025 #level 1
 #deltaXfine = 0.00125 #level 2
 #deltaXfine = 0.000625 #level 3
-deltaXfine = 0.0003125 #level 4
+#deltaXfine = 0.0003125 #level 4
 #deltaXfine = 0.00015625 #level 5
 #deltaXfine = 0.000078125 #level 6
 #deltaXfine = 0.0000390625 #level 7
 #deltaXfine = 0.00001953125 #level 8
+deltaXfine = 0.000009765625 #level 9
 
 #deltaXfine = 6.5e-6
 
 startDistance = -1.0
-refineDistance = 5.0 #0.3
+refineDistance = 0.3
 
 newStart = true
 restartStep = 10
 
-cpStart = 1000
-cpStep = 1000
+cpStart = 1
+cpStep = 1
 
 outTime = 1000
-endTime = 10000
+endTime = 1
 
 logToFile = false
 
-porousTralingEdge = false
+porousTralingEdge = true
 
 thinWall = false
 
diff --git a/source/Applications/DLR-F16/f16-porous.cfg b/source/Applications/DLR-F16/f16-porous.cfg
new file mode 100644
index 000000000..a8ff108d3
--- /dev/null
+++ b/source/Applications/DLR-F16/f16-porous.cfg
@@ -0,0 +1,83 @@
+pathOut = d:/temp/DLR-F16_L1
+pathGeo = d:/Projects/SFB880/DLR-F16/A1_Forschungsdaten_Profilgeometrie_STL_CATIA_Rossian
+#fngFileWhole = f16-ascii.stl
+fngFileWhole = grundgeometrie-direkter-export.stl
+#fngFileWhole = grundgeometrie-mittel.stl
+fngFileBodyPart = f16-body-part-ascii.stl
+fngFileTrailingEdge = f16-trailing-edge-ascii.stl
+zigZagTape = 2zackenbaender0.stl
+#sampleFilename = f16-pte-669x2945x1119.raw
+#sampleFilename = f16-pte-669x2945x100.raw
+#sampleFilename = f16-pte-15.stl #test10_1.stl
+sampleFilename = output.stl
+
+numOfThreads = 4
+availMem = 13e9
+refineLevel = 0 #10
+#blockNx = 7 8 8
+#blockNx = 7 6 7
+#blockNx = 21 6 13
+#blockNx = 10 10 10
+uLB = 0.1
+
+#x1min x1max x2min x2max x3min x3max [m]
+#deltaXfine = 0.00001171875
+deltaXfine = 0.00075
+boundingBox = -0.90 1.20 0.035 0.065 -0.65 0.65
+blockNx = 10 10 10
+
+#deltaXfine = 13393e-9
+#boundingBox = -0.90 1.19145087 0.035 0.06928608 -0.65 0.65
+#blockNx = 10 10 10
+
+#boundingBox = -0.90 1.19998697917 0.035 6.49869791667e-2 -0.65 0.65
+#deltaXfine = 1.30208333333e-5
+#blockNx = 9 9 9
+
+#deltaXfine = 0.006
+deltaXfine = 0.003 #level 0
+#deltaXfine = 0.0015 #level 1
+#deltaXfine = 0.00075 #level 2
+#deltaXfine = 0.000375 #level 3
+#deltaXfine = 0.0001875 #level 4
+#deltaXfine = 0.00009375 #level 5
+#deltaXfine = 0.000046875 #level 6
+#deltaXfine = 0.0000234375 #level 7
+#deltaXfine = 0.00001171875 #level 8
+#deltaXfine = 13393e-9 #level 8
+
+
+#deltaXfine = 0.005 #level 0
+#deltaXfine = 0.0025 #level 1
+#deltaXfine = 0.00125 #level 2
+#deltaXfine = 0.000625 #level 3
+#deltaXfine = 0.0003125 #level 4
+#deltaXfine = 0.00015625 #level 5
+#deltaXfine = 0.000078125 #level 6
+#deltaXfine = 0.0000390625 #level 7
+#deltaXfine = 0.00001953125 #level 8
+
+#deltaXfine = 6.5e-6
+
+startDistance = -1.0
+refineDistance = 30 #0.3
+
+writeBlocks = true
+
+newStart = true
+restartStep = 1000
+
+cpStart = 1000
+cpStep = 1000
+
+outTime = 1000
+endTime = 1000
+
+logToFile = false
+
+porousTralingEdge = false
+
+thinWall = true
+
+
+nupsStep = 1000 1000 10000000
\ No newline at end of file
diff --git a/source/Applications/DLR-F16/f16.cpp b/source/Applications/DLR-F16/f16.cpp
index 82f3432dc..e1a7f60a8 100644
--- a/source/Applications/DLR-F16/f16.cpp
+++ b/source/Applications/DLR-F16/f16.cpp
@@ -16,35 +16,10 @@ void run(string configname)
 {
    try
    {
+
       ConfigurationFile   config;
       config.load(configname);
 
-      //string          pathOut = config.getString("pathOut");
-      //string          pathGeo = config.getString("pathGeo");
-      //string          fngFileWhole = config.getString("fngFileWhole");
-      //string          fngFileTrailingEdge = config.getString("fngFileTrailingEdge");
-      //string          fngFileBodyPart = config.getString("fngFileBodyPart");
-      //string          zigZagTape = config.getString("zigZagTape");
-      //int             numOfThreads = config.getInt("numOfThreads");
-      //vector<int>     blockNx = config.getVector<int>("blockNx");
-      //vector<double>  boundingBox = config.getVector<double>("boundingBox");
-      //double          uLB = config.getDouble("uLB");
-      //double          restartStep = config.getDouble("restartStep");
-      //double          cpStart = config.getDouble("cpStart");
-      //double          cpStep = config.getDouble("cpStep");
-      //double          endTime = config.getDouble("endTime");
-      //double          outTime = config.getDouble("outTime");
-      //double          availMem = config.getDouble("availMem");
-      //int             refineLevel = config.getInt("refineLevel");
-      //bool            logToFile = config.getBool("logToFile");
-      //bool            porousTralingEdge = config.getBool("porousTralingEdge");
-      //double          deltaXfine = config.getDouble("deltaXfine")*1000.0;
-      //bool            thinWall = config.getBool("thinWall");
-      //double          refineDistance = config.getDouble("refineDistance"); 
-      //double          startDistance = config.getDouble("startDistance");
-      //vector<double>  nupsStep = config.getVector<double>("nupsStep");
-      //bool            newStart = config.getBool("newStart");
-
       string          pathOut = config.getValue<string>("pathOut");
       string          pathGeo = config.getValue<string>("pathGeo");
       string          fngFileWhole = config.getValue<string>("fngFileWhole");
@@ -70,6 +45,10 @@ void run(string configname)
       double          startDistance = config.getValue<double>("startDistance");
       vector<double>  nupsStep = config.getVector<double>("nupsStep");
       bool            newStart = config.getValue<bool>("newStart");
+      bool            writeBlocks = config.getValue<bool>("writeBlocks");
+      string          sampleFilename = config.getValue<string>("sampleFilename");
+
+      //Sleep(30000);
 
       CommunicatorPtr comm = MPICommunicator::getInstance();
       int myid = comm->getProcessID();
@@ -77,21 +56,30 @@ void run(string configname)
       if (logToFile)
       {
 #if defined(__unix__)
-         if (myid == 0)
+         if (myid==0)
          {
             const char* str = pathOut.c_str();
-            mkdir(str, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
+            mkdir(str, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH);
          }
 #endif 
 
-         if (myid == 0)
+         if (myid==0)
          {
             stringstream logFilename;
-            logFilename << pathOut + "/logfile" + UbSystem::toString(UbSystem::getTimeStamp()) + ".txt";
+            logFilename<<pathOut+"/logfile"+UbSystem::toString(UbSystem::getTimeStamp())+".txt";
             UbLog::output_policy::setStream(logFilename.str());
          }
       }
 
+      if (myid==0)
+      {
+         UBLOG(logINFO, "PID = "<<myid<<" Point 1");
+         UBLOG(logINFO, "PID = "<<myid<<" Total Physical Memory (RAM): "<<Utilities::getTotalPhysMem());
+         UBLOG(logINFO, "PID = "<<myid<<" Physical Memory currently used: "<<Utilities::getPhysMemUsed());
+         UBLOG(logINFO, "PID = "<<myid<<" Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+      }
+
+
       //the geometry is in mm
 
       double g_minX1 = boundingBox[0]*1000.0;
@@ -101,16 +89,16 @@ void run(string configname)
       double g_maxX1 = boundingBox[1]*1000.0;
       double g_maxX2 = boundingBox[3]*1000.0;
       double g_maxX3 = boundingBox[5]*1000.0;
-       
+
       //////////////////////////////////////////////////////////////////////////
-      double deltaXcoarse = deltaXfine*(double)(1 << refineLevel);
+      double deltaXcoarse = deltaXfine*(double)(1<<refineLevel);
       //double nx2_temp = floor((g_maxX2 - g_minX2) / (deltaXcoarse*(double)blockNx[0]));
 
       //deltaXcoarse = (g_maxX2 - g_minX2) / (nx2_temp*(double)blockNx[0]);
       //UBLOG(logINFO, "nx2_temp:"<<nx2_temp);
       //g_maxX2 -= 0.5* deltaXcoarse;
       //////////////////////////////////////////////////////////////////////////
-      double blockLength = (double)blockNx[0] * deltaXcoarse;
+      double blockLength = (double)blockNx[0]*deltaXcoarse;
 
       //##########################################################################
       //## physical parameters
@@ -135,7 +123,7 @@ void run(string configname)
 
       //double u_LB = uReal   * unitConverter.getFactorVelocityWToLb();
       //double nu_LB = nueReal * unitConverter.getFactorViscosityWToLb();
-      double lLB = lReal*1000.0 / deltaXcoarse;
+      double lLB = lReal*1000.0/deltaXcoarse;
       double nuLB = (uLB*lLB)/Re; //0.005;
       //double nuLB = 0.005;
 
@@ -166,27 +154,37 @@ void run(string configname)
       fct.SetExpr("U");
       fct.DefineConst("U", uLB);
       BCAdapterPtr velBCAdapter(new VelocityBCAdapter(true, false, false, fct, 0, BCFunction::INFCONST));
-      velBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new NonReflectingVelocityBCAlgorithm()));
+      velBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new VelocityWithDensityBCAlgorithm()));
+      //velBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new VelocityBCAlgorithm()));
 
-      BCAdapterPtr denBCAdapter(new DensityBCAdapter(rhoLB));
-      denBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new NonReflectingDensityBCAlgorithm()));
+      BCAdapterPtr outflowBCAdapter(new DensityBCAdapter(rhoLB));
+      outflowBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new NonReflectingOutflowBCAlgorithm()));
+      //denBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new NonEqDensityBCAlgorithm()));
 
       BoundaryConditionsBlockVisitor bcVisitor;
       bcVisitor.addBC(noSlipBCAdapter);
-      bcVisitor.addBC(slipBCAdapter);
+      //bcVisitor.addBC(slipBCAdapter);
       bcVisitor.addBC(velBCAdapter);
-      bcVisitor.addBC(denBCAdapter);
+      bcVisitor.addBC(outflowBCAdapter);
 
       //////////////////////////////////////////////////////////////////////////
       //restart
+      //Grid3DPtr oldGrid(new Grid3D(comm));
       UbSchedulerPtr rSch(new UbScheduler(cpStep, cpStart));
       //RestartCoProcessor rp(grid, rSch, comm, pathOut, RestartCoProcessor::BINARY);
       MPIIORestartCoProcessor rcp(grid, rSch, pathOut, comm);
+      //rcp.restart(5000);
       //////////////////////////////////////////////////////////////////////////
 
 
+      if (myid==0)
+      {
+         UBLOG(logINFO, "PID = "<<myid<<" Point 2");
+         UBLOG(logINFO, "PID = "<<myid<<" Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+      }
+
       //if (grid->getTimeStep() == 0)
-      if(newStart)
+      if (newStart)
       {
          ////////////////////////////////////////////////////////////////////////
          //define grid
@@ -201,9 +199,9 @@ void run(string configname)
 
          grid->setPeriodicX1(false);
          grid->setPeriodicX2(true);
-         grid->setPeriodicX3(false);
+         grid->setPeriodicX3(true);
 
-         if (myid == 0)
+         if (myid==0)
          {
             UBLOG(logINFO, "Parameters:");
             UBLOG(logINFO, "* Re                  = "<<Re);
@@ -216,9 +214,9 @@ void run(string configname)
             UBLOG(logINFO, "* chord length (l_LB) = "<<lLB<<" dx_base");
             UBLOG(logINFO, "* dx_base             = "<<deltaXcoarse/1000<<" m");
             UBLOG(logINFO, "* dx_refine           = "<<deltaXfine/1000<<" m");
-            UBLOG(logINFO, "* blocknx             = "<<blockNx[0]<<"x"<<blockNx[1]<<"x"<<blockNx[2] );
+            UBLOG(logINFO, "* blocknx             = "<<blockNx[0]<<"x"<<blockNx[1]<<"x"<<blockNx[2]);
             UBLOG(logINFO, "* refineDistance      = "<<refineDistance);
-            UBLOG(logINFO, "* number of levels    = "<<refineLevel + 1);
+            UBLOG(logINFO, "* number of levels    = "<<refineLevel+1);
             UBLOG(logINFO, "* number of threads   = "<<numOfThreads);
             UBLOG(logINFO, "* number of processes = "<<comm->getNumberOfProcesses());
             UBLOG(logINFO, "Preprozess - start");
@@ -227,6 +225,7 @@ void run(string configname)
          GbTriFaceMesh3DPtr fngMeshWhole;
          GbTriFaceMesh3DPtr fngMeshBodyPart;
          GbTriFaceMesh3DPtr fngMeshTrailingEdge;
+         GbTriFaceMesh3DPtr porousTrailingEdge;
          if (porousTralingEdge)
          {
             if (myid==0) UBLOG(logINFO, "Read fngFileBodyPart:start");
@@ -239,8 +238,52 @@ void run(string configname)
             fngMeshTrailingEdge = GbTriFaceMesh3DPtr(GbTriFaceMesh3DCreator::getInstance()->readMeshFromSTLFile(pathGeo+"/"+fngFileTrailingEdge, "fngMeshTrailingEdge", GbTriFaceMesh3D::KDTREE_SAHPLIT, false));
             if (myid==0) UBLOG(logINFO, "Read fngFileTrailingEdge:end");
             fngMeshTrailingEdge->rotate(0.0, 0.5, 0.0);
-            fngMeshTrailingEdge->translate(0,0,1.3);
+            fngMeshTrailingEdge->translate(-0.05, 0, 1.3);
             if (myid==0) GbSystem3D::writeGeoObject(fngMeshTrailingEdge.get(), pathOut+"/geo/fngMeshTrailingEdge", WbWriterVtkXmlBinary::getInstance());
+
+            if (myid==0) UBLOG(logINFO, "Read porousTrailingEdge:start");
+            //porousTrailingEdge = GbTriFaceMesh3DPtr(GbTriFaceMesh3DCreator::getInstance()->readMeshFromSTLFile(pathGeo+"/"+sampleFilename, "porousTrailingEdge", GbTriFaceMesh3D::KDTREE_SAHPLIT, false));
+            porousTrailingEdge = GbTriFaceMesh3DPtr(GbTriFaceMesh3DCreator::getInstance()->readMeshFromSTLFile2(pathGeo+"/"+sampleFilename, "porousTrailingEdge", GbTriFaceMesh3D::KDTREE_SAHPLIT, false));
+            if (myid==0) UBLOG(logINFO, "Read porousTrailingEdge:end");
+            porousTrailingEdge->rotate(90, -90, 0.0);
+            porousTrailingEdge->rotate(0, -4.3, 0.0);
+            //porousTrailingEdge->translate(280.5, 40.0, 3.5);
+            porousTrailingEdge->translate(276, 15.95, 3.5);
+            if (myid==0) GbSystem3D::writeGeoObject(porousTrailingEdge.get(), pathOut+"/geo/porousTrailingEdge", WbWriterVtkXmlASCII::getInstance());
+
+            //string samplePathname = pathGeo+"/"+sampleFilename;
+
+            //int pmNX1 = 669;
+            //int pmNX2 = 2945;
+            //int pmNX3 = 100;
+
+            //double deltaVoxelX1 = 13393e-6;
+            //double deltaVoxelX2 = 13393e-6;
+            //double deltaVoxelX3 = 13393e-6;
+
+            //double lthreshold = 11538;
+            //double uthreshold = 65535;
+
+            //if (myid==0) UBLOG(logINFO, "read voxel matrix: start");
+            //GbVoxelMatrix3DPtr porousTrailingEdge(new GbVoxelMatrix3D(pmNX1, pmNX2, pmNX3, 0.0 , lthreshold, uthreshold));
+            //porousTrailingEdge->readMatrixFromRawFile<unsigned short>(samplePathname, GbVoxelMatrix3D::BigEndian);
+            //porousTrailingEdge->setVoxelMatrixDelta((float)deltaVoxelX1, (float)deltaVoxelX2, (float)deltaVoxelX3);
+            //porousTrailingEdge->setVoxelMatrixMininum(0.0, 0.0, 0.0);
+            //if (myid==0) UBLOG(logINFO, "read voxel matrix: end");
+
+            //if (myid==0) UBLOG(logINFO, "rotate voxel matrix: start");
+            //porousTrailingEdge->rotate90aroundZ();
+            //porousTrailingEdge->rotate90aroundZ();
+            //porousTrailingEdge->rotate90aroundZ();
+            //porousTrailingEdge->rotate90aroundX();
+            //porousTrailingEdge->rotateAroundY(0.07);
+            //porousTrailingEdge->translate(276, 15.95, 3.26);
+            //
+            //if (myid==0) UBLOG(logINFO, "rotate voxel matrix: end");
+
+            ////if (myid==0) porousTrailingEdge->writeToVTKImageDataASCII(pathOut+"/geo/PorousTrailingEdge");
+            //if (myid==0) porousTrailingEdge->writeToVTKImageDataAppended(pathOut+"/geo/PorousTrailingEdge");
+
          }
          else
          {
@@ -277,11 +320,11 @@ void run(string configname)
          //meshBand4->rotate(0.0, 5, 0.0);
          //meshBand4->translate(15, 5, -12.35);
          //if (myid==0) GbSystem3D::writeGeoObject(meshBand4.get(), pathOut+"/geo/zigZagTape4", WbWriterVtkXmlASCII::getInstance());
-        
+
          //bottom
          GbTriFaceMesh3DPtr meshBand5(GbTriFaceMesh3DCreator::getInstance()->readMeshFromSTLFile(ZckbndFilename, "zigZagTape5"));
          meshBand5->rotate(0.0, -1, 0.0);
-         meshBand5->rotate(0.0, 0.0,180.0);
+         meshBand5->rotate(0.0, 0.0, 180.0);
          //meshBand5->translate(30, 0, -37.3);
          meshBand5->translate(30, 0, -37.2);
          if (myid==0) GbSystem3D::writeGeoObject(meshBand5.get(), pathOut+"/geo/zigZagTape5", WbWriterVtkXmlASCII::getInstance());
@@ -304,17 +347,25 @@ void run(string configname)
          //if (myid==0) GbSystem3D::writeGeoObject(meshBan8.get(), pathOut+"/geo/zigZagTape8", WbWriterVtkXmlASCII::getInstance());
          if (myid==0) UBLOG(logINFO, "Read zigZagTape:end");
 
-         
 
+         if (myid==0)
+         {
+            UBLOG(logINFO, "PID = "<<myid<<" Point 3");
+            UBLOG(logINFO, "PID = "<<myid<<" Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+         }
          //////////////////////////////////////////////////////////////////////////
+         //return;
 
          Interactor3DPtr fngIntrWhole;
          Interactor3DPtr fngIntrBodyPart;
          Interactor3DPtr fngIntrTrailingEdge;
+         Interactor3DPtr porousIntrTrailingEdge;
+
          if (porousTralingEdge)
          {
-            fngIntrBodyPart = D3Q27TriFaceMeshInteractorPtr(new D3Q27TriFaceMeshInteractor(fngMeshBodyPart, grid, noSlipBCAdapter, Interactor3D::SOLID));
-            fngIntrTrailingEdge = D3Q27TriFaceMeshInteractorPtr(new D3Q27TriFaceMeshInteractor(fngMeshTrailingEdge, grid, noSlipBCAdapter, Interactor3D::SOLID));
+            fngIntrBodyPart = D3Q27TriFaceMeshInteractorPtr(new D3Q27TriFaceMeshInteractor(fngMeshBodyPart, grid, noSlipBCAdapter, Interactor3D::SOLID, Interactor3D::EDGES));
+            fngIntrTrailingEdge = D3Q27TriFaceMeshInteractorPtr(new D3Q27TriFaceMeshInteractor(fngMeshTrailingEdge, grid, noSlipBCAdapter, Interactor3D::SOLID, Interactor3D::EDGES));
+            porousIntrTrailingEdge = D3Q27TriFaceMeshInteractorPtr(new D3Q27TriFaceMeshInteractor(porousTrailingEdge, grid, noSlipBCAdapter, Interactor3D::SOLID, Interactor3D::EDGES));
          }
          else
          {
@@ -326,25 +377,25 @@ void run(string configname)
          D3Q27TriFaceMeshInteractorPtr triBand3Interactor(new D3Q27TriFaceMeshInteractor(meshBand5, grid, noSlipBCAdapter, Interactor3D::SOLID, Interactor3D::EDGES));
          D3Q27TriFaceMeshInteractorPtr triBand4Interactor(new D3Q27TriFaceMeshInteractor(meshBand6, grid, noSlipBCAdapter, Interactor3D::SOLID, Interactor3D::EDGES));
 
-         if (refineLevel > 0 && myid == 0)
+         if (refineLevel>0&&myid==0&&writeBlocks)
          {
-            if (myid == 0) UBLOG(logINFO, "Refinement - start");
+            if (myid==0) UBLOG(logINFO, "Refinement - start");
             //RefineCrossAndInsideGbObjectHelper refineHelper(grid, refineLevel);
             //refineHelper.addGbObject(geo, refineLevel);
             //refineHelper.refine();
-            
+
             //RefineAroundGbObjectHelper refineHelper1(grid, refineLevel-1, boost::dynamic_pointer_cast<D3Q27TriFaceMeshInteractor>(geoIntr1), 0.0, 10.0, comm);
             //refineHelper1.refine();
             //RefineAroundGbObjectHelper refineHelper2(grid, refineLevel, boost::dynamic_pointer_cast<D3Q27TriFaceMeshInteractor>(geoIntr2), -1.0, 5.0, comm);
             //refineHelper2.refine();
-            
+
 
             int rank = grid->getRank();
             grid->setRank(0);
 
             if (porousTralingEdge)
             {
-               boost::dynamic_pointer_cast<D3Q27TriFaceMeshInteractor>(fngIntrBodyPart)->refineBlockGridToLevel(refineLevel, startDistance, refineDistance);
+               boost::dynamic_pointer_cast<D3Q27TriFaceMeshInteractor>(fngIntrBodyPart)->refineBlockGridToLevel(refineLevel-1, startDistance, refineDistance);
             }
             else
             {
@@ -364,20 +415,33 @@ void run(string configname)
             //RefineCrossAndInsideGbObjectBlockVisitor refVisitor0(fngBox, refineLevel);
             //grid->accept(refVisitor0);
 
-            
-            GbObject3DPtr bandTopBox(new GbCuboid3D(meshBand1->getX1Minimum(), meshBand1->getX2Minimum(), meshBand1->getX3Minimum(), 
-                                                 meshBand1->getX1Maximum(), meshBand1->getX2Maximum(), meshBand1->getX3Maximum()));
-            if (myid==0) GbSystem3D::writeGeoObject(bandTopBox.get(), pathOut+"/geo/bandTopBox", WbWriterVtkXmlASCII::getInstance());
 
-            RefineCrossAndInsideGbObjectBlockVisitor refVisitor1(bandTopBox, refineLevel);
-            grid->accept(refVisitor1);
+            //GbObject3DPtr bandTopBox(new GbCuboid3D(meshBand1->getX1Minimum(), meshBand1->getX2Minimum(), meshBand1->getX3Minimum(),
+            //   meshBand1->getX1Maximum(), meshBand1->getX2Maximum(), meshBand1->getX3Maximum()));
+            //if (myid==0) GbSystem3D::writeGeoObject(bandTopBox.get(), pathOut+"/geo/bandTopBox", WbWriterVtkXmlASCII::getInstance());
+
+            //RefineCrossAndInsideGbObjectBlockVisitor refVisitor1(bandTopBox, refineLevel-1);
+            //grid->accept(refVisitor1);
+
+            //GbObject3DPtr bandBottomBox(new GbCuboid3D(meshBand5->getX1Minimum(), meshBand5->getX2Minimum(), meshBand5->getX3Minimum(),
+            //   meshBand5->getX1Maximum(), meshBand5->getX2Maximum(), meshBand5->getX3Maximum()));
+            //if (myid==0) GbSystem3D::writeGeoObject(bandBottomBox.get(), pathOut+"/geo/bandBottomBox", WbWriterVtkXmlASCII::getInstance());
+
+            //RefineCrossAndInsideGbObjectBlockVisitor refVisitor2(bandBottomBox, refineLevel-1);
+            //grid->accept(refVisitor2);
+
+            //GbObject3DPtr teBox1(new GbCuboid3D(269.0, 0.0, 1.0, 270.0, 100.0, 8.5));
+            GbObject3DPtr teBox1(new GbCuboid3D(269.0, 0.0, -10.0, 310.0, 100.0, 20.5));
+            if (myid==0) GbSystem3D::writeGeoObject(teBox1.get(), pathOut+"/geo/teBox1", WbWriterVtkXmlASCII::getInstance());
 
-            GbObject3DPtr bandBottomBox(new GbCuboid3D(meshBand5->getX1Minimum(), meshBand5->getX2Minimum(), meshBand5->getX3Minimum(), 
-                                                    meshBand5->getX1Maximum(), meshBand5->getX2Maximum(), meshBand5->getX3Maximum()));
-            if (myid==0) GbSystem3D::writeGeoObject(bandBottomBox.get(), pathOut+"/geo/bandBottomBox", WbWriterVtkXmlASCII::getInstance());
+            RefineCrossAndInsideGbObjectBlockVisitor refVisitor3(teBox1, refineLevel);
+            grid->accept(refVisitor3);
 
-            RefineCrossAndInsideGbObjectBlockVisitor refVisitor2(bandBottomBox, refineLevel);
-            grid->accept(refVisitor2);
+            //GbObject3DPtr teBox2(new GbCuboid3D(271.0, 0.0, 3.0, 279.0, 100.0, 5.7));
+            //if (myid==0) GbSystem3D::writeGeoObject(teBox2.get(), pathOut+"/geo/teBox2", WbWriterVtkXmlASCII::getInstance());
+
+            //RefineCrossAndInsideGbObjectBlockVisitor refVisitor4(teBox2, refineLevel);
+            //grid->accept(refVisitor4);
 
             grid->setRank(rank);
 
@@ -391,7 +455,7 @@ void run(string configname)
             //Grid3DVisitorPtr metisVisitor(new MetisPartitioningGridVisitor(comm, MetisPartitioningGridVisitor::LevelBased, D3Q27System::BSW, MetisPartitioner::KWAY));
             ////////////////////////////////////////////
             /////delete solid blocks
-            if (myid == 0) UBLOG(logINFO, "deleteSolidBlocks - start");
+            if (myid==0) UBLOG(logINFO, "deleteSolidBlocks - start");
             //InteractorsHelper intHelper(grid, metisVisitor);
             //if (porousTralingEdge)
             //{
@@ -402,9 +466,9 @@ void run(string configname)
             //   intHelper.addInteractor(fngIntrWhole);
             //}
             //////////////////////////////////////////////////////////////////////////
-            
+
             //intHelper.selectBlocks();
-            
+
             if (porousTralingEdge)
             {
                SetSolidOrTransBlockVisitor v(fngIntrBodyPart, SetSolidOrTransBlockVisitor::SOLID);
@@ -430,32 +494,32 @@ void run(string configname)
                fngIntrWhole->removeTransBlocks();
             }
 
-            if (myid == 0) UBLOG(logINFO, "deleteSolidBlocks - end");
+            if (myid==0) UBLOG(logINFO, "deleteSolidBlocks - end");
             //////////////////////////////////////
 
-            if (porousTralingEdge)
-            {
-               grid->setRank(0);
-               boost::dynamic_pointer_cast<D3Q27TriFaceMeshInteractor>(fngIntrTrailingEdge)->refineBlockGridToLevel(refineLevel, -2.0, refineDistance);
-               grid->setRank(rank);
+            //if (porousTralingEdge)
+            //{
+            //   grid->setRank(0);
+            //   boost::dynamic_pointer_cast<D3Q27TriFaceMeshInteractor>(fngIntrTrailingEdge)->refineBlockGridToLevel(refineLevel, startDistance, refineDistance);
+            //   grid->setRank(rank);
 
-               //GbObject3DPtr trailingEdgeCube(new GbCuboid3D(fngMeshTrailingEdge->getX1Minimum()-blockLength, fngMeshTrailingEdge->getX2Minimum(), fngMeshTrailingEdge->getX3Minimum()-blockLength/2.0,
-               //   fngMeshTrailingEdge->getX1Maximum()+blockLength, fngMeshTrailingEdge->getX2Maximum(), fngMeshTrailingEdge->getX3Maximum()+blockLength/2.0));
-               //if (myid == 0) GbSystem3D::writeGeoObject(trailingEdgeCube.get(), pathOut + "/geo/trailingEdgeCube", WbWriterVtkXmlASCII::getInstance());
+            //   //GbObject3DPtr trailingEdgeCube(new GbCuboid3D(fngMeshTrailingEdge->getX1Minimum()-blockLength, fngMeshTrailingEdge->getX2Minimum(), fngMeshTrailingEdge->getX3Minimum()-blockLength/2.0,
+            //   //   fngMeshTrailingEdge->getX1Maximum()+blockLength, fngMeshTrailingEdge->getX2Maximum(), fngMeshTrailingEdge->getX3Maximum()+blockLength/2.0));
+            //   //if (myid == 0) GbSystem3D::writeGeoObject(trailingEdgeCube.get(), pathOut + "/geo/trailingEdgeCube", WbWriterVtkXmlASCII::getInstance());
 
-               //RefineCrossAndInsideGbObjectBlockVisitor refVisitor(trailingEdgeCube, refineLevel);
-               //grid->accept(refVisitor);
-            }
+            //   //RefineCrossAndInsideGbObjectBlockVisitor refVisitor(trailingEdgeCube, refineLevel);
+            //   //grid->accept(refVisitor);
+            //}
 
             RatioBlockVisitor ratioVisitor(refineLevel);
             CheckRatioBlockVisitor checkRatio(refineLevel);
             int count = 0;
-            
+
             do {
                grid->accept(ratioVisitor);
                checkRatio.resetState();
                grid->accept(checkRatio);
-               if (myid == 0) UBLOG(logINFO, "count ="<<count++<<" state="<<checkRatio.getState());
+               if (myid==0) UBLOG(logINFO, "count = "<<count++<<" state = "<<checkRatio.getState());
             } while (!checkRatio.getState());
 
             //RatioSmoothBlockVisitor ratioSmoothVisitor(refineLevel);
@@ -477,14 +541,24 @@ void run(string configname)
             //SetInterpolationDirsBlockVisitor interDirsVisitor(dirs);
             //grid->accept(interDirsVisitor);
 
-            if (myid == 0) UBLOG(logINFO, "Refinement - end");
+            if (myid==0) UBLOG(logINFO, "Refinement - end");
          }
-
          grid->updateDistributedBlocks(comm);
 
+         //if (writeBlocks)
+         //{
+         //   grid->updateDistributedBlocks(comm);
+         //   rcp.writeBlocks(0);
+         //}
+         //else
+         //{
+         //   rcp.readBlocks(0);
+         //}
 
          //return;
 
+         //Sleep(1000*myid);
+
          std::vector<int> dirs;
          for (int i = D3Q27System::E; i<=D3Q27System::TS; i++)
          {
@@ -503,8 +577,10 @@ void run(string configname)
 
 
          //wall interactors
-         D3Q27InteractorPtr addWallZminInt(new D3Q27Interactor(addWallZmin, grid, slipBCAdapter, Interactor3D::SOLID));
-         D3Q27InteractorPtr addWallZmaxInt(new D3Q27Interactor(addWallZmax, grid, slipBCAdapter, Interactor3D::SOLID));
+         //D3Q27InteractorPtr addWallZminInt(new D3Q27Interactor(addWallZmin, grid, slipBCAdapter, Interactor3D::SOLID));
+         //D3Q27InteractorPtr addWallZmaxInt(new D3Q27Interactor(addWallZmax, grid, slipBCAdapter, Interactor3D::SOLID));
+         D3Q27InteractorPtr addWallZminInt(new D3Q27Interactor(addWallZmin, grid, velBCAdapter, Interactor3D::SOLID));
+         D3Q27InteractorPtr addWallZmaxInt(new D3Q27Interactor(addWallZmax, grid, velBCAdapter, Interactor3D::SOLID));
 
          //inflow
          GbCuboid3DPtr geoInflow(new GbCuboid3D(g_minX1-blockLength, g_minX2-blockLength, g_minX3-blockLength, g_minX1, g_maxX2+blockLength, g_maxX3+blockLength));
@@ -518,14 +594,17 @@ void run(string configname)
          D3Q27InteractorPtr inflowIntr = D3Q27InteractorPtr(new D3Q27Interactor(geoInflow, grid, velBCAdapter, Interactor3D::SOLID));
 
          //outflow
-         D3Q27InteractorPtr outflowIntr = D3Q27InteractorPtr(new D3Q27Interactor(geoOutflow, grid, denBCAdapter, Interactor3D::SOLID));
+         D3Q27InteractorPtr outflowIntr = D3Q27InteractorPtr(new D3Q27Interactor(geoOutflow, grid, outflowBCAdapter, Interactor3D::SOLID));
 
          ////////////////////////////////////////////
          //METIS
+         //grid->deleteBlockIDs();
+         //RenumberBlockVisitor renumber;
+         //grid->accept(renumber);
          Grid3DVisitorPtr metisVisitor(new MetisPartitioningGridVisitor(comm, MetisPartitioningGridVisitor::LevelBased, D3Q27System::BSW, MetisPartitioner::KWAY));
          ////////////////////////////////////////////
          /////delete solid blocks
-         if (myid == 0) UBLOG(logINFO, "deleteSolidBlocks - start");
+         if (myid==0) UBLOG(logINFO, "deleteSolidBlocks - start");
          InteractorsHelper intHelper(grid, metisVisitor);
          intHelper.addInteractor(inflowIntr);
          intHelper.addInteractor(outflowIntr);
@@ -536,24 +615,58 @@ void run(string configname)
          intHelper.addInteractor(triBand3Interactor);
          intHelper.addInteractor(triBand4Interactor);
          
+
          if (porousTralingEdge)
          {
             intHelper.addInteractor(fngIntrBodyPart);
-            //intHelper.addInteractor(fngIntrTrailingEdge);
-         } 
+            intHelper.addInteractor(porousIntrTrailingEdge);
+
+            //string samplePathname = pathGeo+"/"+sampleFilename;
+
+            //double pmNX1 = 669;
+            //double pmNX2 = 2945;
+            //double pmNX3 = 1119;
+
+            //double deltaVoxelX1 = 13393e-6;
+            //double deltaVoxelX2 = 13393e-6;
+            //double deltaVoxelX3 = 13393e-6;
+            //
+            //double lthreshold = 11538;
+            //double uthreshold = 65535;
+
+            //if (myid==0) UBLOG(logINFO, "read voxel matrix: start");
+            //GbVoxelMatrix3DPtr porousTrailingEdge(new GbVoxelMatrix3D(pmNX1, pmNX2, pmNX3, 0, lthreshold, uthreshold));
+            //porousTrailingEdge->readMatrixFromRawFile<unsigned short>(samplePathname, GbVoxelMatrix3D::BigEndian);
+            //porousTrailingEdge->setVoxelMatrixDelta((float)deltaVoxelX1, (float)deltaVoxelX2, (float)deltaVoxelX3);
+            //porousTrailingEdge->setVoxelMatrixMininum(0.0, 0.0, 0.0);
+            //if (myid==0) UBLOG(logINFO, "read voxel matrix: end");
+
+            //if (myid==0) UBLOG(logINFO, "rotate voxel matrix: start");
+            //porousTrailingEdge->rotate90aroundZ();
+            //porousTrailingEdge->rotate90aroundX();
+            //if (myid==0) UBLOG(logINFO, "rotate voxel matrix: end");
+
+            //if (myid==0) porousTrailingEdge->writeToVTKImageDataASCII(pathOut+"/geo/PorousTrailingEdge");
+         }
          else
          {
             intHelper.addInteractor(fngIntrWhole);
          }
-         
+
          //////////////////////////////////////////////////////////////////////////
          intHelper.selectBlocks();
 
-         if (myid == 0) UBLOG(logINFO, "deleteSolidBlocks - end");
+         if (myid==0) UBLOG(logINFO, "deleteSolidBlocks - end");
+
+         if (myid==0)
+         {
+            UBLOG(logINFO, "PID = "<<myid<<" Point 4");
+            UBLOG(logINFO, "PID = "<<myid<<" Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+         }
          //////////////////////////////////////
 
          {
-            WriteBlocksCoProcessor ppblocks(grid, UbSchedulerPtr(new UbScheduler(1)), pathOut, WbWriterVtkXmlASCII::getInstance(), comm);
+            WriteBlocksCoProcessor ppblocks(grid, UbSchedulerPtr(new UbScheduler(1)), pathOut, WbWriterVtkXmlBinary::getInstance(), comm);
             ppblocks.process(2);
          }
 
@@ -561,25 +674,25 @@ void run(string configname)
          int ghostLayer = 3;
          unsigned long long numberOfNodesPerBlock = (unsigned long long)(blockNx[0])* (unsigned long long)(blockNx[1])* (unsigned long long)(blockNx[2]);
          unsigned long long numberOfNodes = numberOfBlocks * numberOfNodesPerBlock;
-         unsigned long long numberOfNodesPerBlockWithGhostLayer = numberOfBlocks * (blockNx[0] + ghostLayer) * (blockNx[1] + ghostLayer) * (blockNx[2] + ghostLayer);
-         double needMemAll = double(numberOfNodesPerBlockWithGhostLayer*(27 * sizeof(double) + sizeof(int) + sizeof(float) * 4));
-         double needMem = needMemAll / double(comm->getNumberOfProcesses());
+         unsigned long long numberOfNodesPerBlockWithGhostLayer = numberOfBlocks * (blockNx[0]+ghostLayer) * (blockNx[1]+ghostLayer) * (blockNx[2]+ghostLayer);
+         double needMemAll = double(numberOfNodesPerBlockWithGhostLayer*(27*sizeof(double)+sizeof(int)+sizeof(float)*4));
+         double needMem = needMemAll/double(comm->getNumberOfProcesses());
 
-         if (myid == 0)
+         if (myid==0)
          {
-            UBLOG(logINFO, "Number of blocks = " << numberOfBlocks);
-            UBLOG(logINFO, "Number of nodes  = " << numberOfNodes);
+            UBLOG(logINFO, "Number of blocks = "<<numberOfBlocks);
+            UBLOG(logINFO, "Number of nodes  = "<<numberOfNodes);
             int minInitLevel = grid->getCoarsestInitializedLevel();
             int maxInitLevel = grid->getFinestInitializedLevel();
-            for (int level = minInitLevel; level <= maxInitLevel; level++)
+            for (int level = minInitLevel; level<=maxInitLevel; level++)
             {
                int nobl = grid->getNumberOfBlocks(level);
-               UBLOG(logINFO, "Number of blocks for level " << level << " = " << nobl);
-               UBLOG(logINFO, "Number of nodes for level " << level << " = " << nobl*numberOfNodesPerBlock);
+               UBLOG(logINFO, "Number of blocks for level "<<level<<" = "<<nobl);
+               UBLOG(logINFO, "Number of nodes for level "<<level<<" = "<<nobl*numberOfNodesPerBlock);
             }
-            UBLOG(logINFO, "Necessary memory  = " << needMemAll << " bytes");
-            UBLOG(logINFO, "Necessary memory per process = " << needMem << " bytes");
-            UBLOG(logINFO, "Available memory per process = " << availMem << " bytes");
+            UBLOG(logINFO, "Necessary memory  = "<<needMemAll<<" bytes");
+            UBLOG(logINFO, "Necessary memory per process = "<<needMem<<" bytes");
+            UBLOG(logINFO, "Available memory per process = "<<availMem<<" bytes");
          }
 
          LBMKernelPtr kernel = LBMKernelPtr(new CompressibleCumulantLBMKernel(blockNx[0], blockNx[1], blockNx[2], CompressibleCumulantLBMKernel::NORMAL));
@@ -601,24 +714,40 @@ void run(string configname)
          SetKernelBlockVisitor kernelVisitor(kernel, nuLB, availMem, needMem);
          grid->accept(kernelVisitor);
 
-         UBLOG(logINFO, "SetKernelBlockVisitor:end");
+         if (myid==0) UBLOG(logINFO, "SetKernelBlockVisitor:end");
 
-         if (refineLevel > 0)
+         if (myid==0)
+         {
+            UBLOG(logINFO, "PID = "<<myid<<" Point 5");
+            UBLOG(logINFO, "PID = "<<myid<<" Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+         }
+
+         if (refineLevel>0)
          {
             SetUndefinedNodesBlockVisitor undefNodesVisitor;
             grid->accept(undefNodesVisitor);
          }
 
-         UBLOG(logINFO, "SetUndefinedNodesBlockVisitor:end");
+         if (myid==0) UBLOG(logINFO, "SetUndefinedNodesBlockVisitor:end");
 
          //BC
          intHelper.setBC();
-         
-         UBLOG(logINFO, "intHelper.setBC():end");
+         if (myid==0) UBLOG(logINFO, "intHelper.setBC():end");
+
+         if (myid==0)
+         {
+            UBLOG(logINFO, "PID = "<<myid<<" Point 6");
+            UBLOG(logINFO, "PID = "<<myid<<" Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+         }
 
          grid->accept(bcVisitor);
+         if (myid==0) UBLOG(logINFO, "grid->accept(bcVisitor);:end");
 
-         UBLOG(logINFO, "grid->accept(bcVisitor);:end");
+         if (myid==0)
+         {
+            UBLOG(logINFO, "PID = "<<myid<<" Point 7");
+            UBLOG(logINFO, "PID = "<<myid<<" Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+         }
 
          //initialization of distributions
          mu::Parser inflowProfileVx1, inflowProfileVx2, inflowProfileVx3;
@@ -631,7 +760,7 @@ void run(string configname)
          inflowProfileVx3.SetExpr("0.1*U*rangeRandom1()");
          inflowProfileVx3.DefineConst("U", uLB);
          inflowProfileVx3.DefineFun("rangeRandom1", rangeRandom1);
-         
+
          InitDistributionsBlockVisitor initVisitor(nuLB, rhoLB);
          initVisitor.setVx1(fct);
          //initVisitor.setVx1(inflowProfileVx1);
@@ -640,27 +769,62 @@ void run(string configname)
          //initVisitor.setNu(nuLB);
          grid->accept(initVisitor);
 
+
+
          ////set connectors
          InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
          //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
+         
+         //Grid3DPtr oldGrid(new Grid3D(comm));
+         //UbSchedulerPtr iSch(new UbScheduler());
+         //MPIIORestartCoProcessor rcpInit(oldGrid, iSch, pathOut, comm);
+         //rcpInit.restart(5000);
+
+         //InitDistributionsWithInterpolationGridVisitor initVisitor(oldGrid, iProcessor, nuLB);
+         //grid->accept(initVisitor);
+
          //domain decomposition for threads
-         PQueuePartitioningGridVisitor pqPartVisitor(numOfThreads);
-         grid->accept(pqPartVisitor);
+         //PQueuePartitioningGridVisitor pqPartVisitor(numOfThreads);
+         //grid->accept(pqPartVisitor);
 
          //Postrozess
-         UbSchedulerPtr geoSch(new UbScheduler(1));
-         WriteBoundaryConditionsCoProcessorPtr ppgeo(
-            new WriteBoundaryConditionsCoProcessor(grid, geoSch, pathOut, WbWriterVtkXmlBinary::getInstance(), conv, comm));
-         ppgeo->process(0);
-         ppgeo.reset();
+         {
+            UbSchedulerPtr geoSch(new UbScheduler(1));
+            WriteBoundaryConditionsCoProcessor ppgeo(grid, geoSch, pathOut, WbWriterVtkXmlBinary::getInstance(), conv, comm);
+            ppgeo.process(0);
+         }
+
+         if (myid==0)
+         {
+            UBLOG(logINFO, "PID = "<<myid<<" Point 8");
+            UBLOG(logINFO, "PID = "<<myid<<" Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+         }
+
+         fngIntrWhole.reset();
 
-         if (myid == 0) UBLOG(logINFO, "Preprozess - end");
+         if (myid==0) UBLOG(logINFO, "Preprozess - end");
       }
       else
       {
+         
+         
+         //////////////////////////////////////////////////////////////////////////
+         //MPIIORestart2CoProcessor test
+         //UbSchedulerPtr iSch(new UbScheduler(10));
+         //MPIIORestart2CoProcessor rcp(grid, iSch, pathOut+"/mpiio2", comm);
+         //rcp.readBlocks(10);
+         ////RenumberBlockVisitor renumber;
+         ////grid->accept(renumber);
+         //Grid3DVisitorPtr metisVisitor(new MetisPartitioningGridVisitor(comm, MetisPartitioningGridVisitor::LevelBased, D3Q27System::BSW, MetisPartitioner::KWAY));
+         //grid->accept(metisVisitor);
+         //rcp.readDataSet(10);
+         //rcp.readBoundaryConds(10);
+         //grid->setTimeStep(10);
+         //////////////////////////////////////////////////////////////////////////
+         
          rcp.restart((int)restartStep);
          grid->setTimeStep(restartStep);
 
@@ -674,8 +838,8 @@ void run(string configname)
          grid->accept(setConnsVisitor);
 
          //domain decomposition for threads
-         PQueuePartitioningGridVisitor pqPartVisitor(numOfThreads);
-         grid->accept(pqPartVisitor);
+         //PQueuePartitioningGridVisitor pqPartVisitor(numOfThreads);
+         //grid->accept(pqPartVisitor);
 
          grid->accept(bcVisitor);
       }
@@ -685,33 +849,45 @@ void run(string configname)
 
       UbSchedulerPtr stepSch(new UbScheduler(outTime));
 
-      WriteMacroscopicQuantitiesCoProcessor pp(grid, stepSch, pathOut, WbWriterVtkXmlBinary::getInstance(), conv,comm);
+      WriteMacroscopicQuantitiesCoProcessor pp(grid, stepSch, pathOut, WbWriterVtkXmlBinary::getInstance(), conv, comm);
 
-      if (myid == 0)
+      if (myid==0)
       {
-         UBLOG(logINFO, "PID = " << myid << " Total Physical Memory (RAM): " << Utilities::getTotalPhysMem());
-         UBLOG(logINFO, "PID = " << myid << " Physical Memory currently used: " << Utilities::getPhysMemUsed());
-         UBLOG(logINFO, "PID = " << myid << " Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe());
+         UBLOG(logINFO, "PID = "<<myid<<" Point 9");
+         UBLOG(logINFO, "PID = "<<myid<<" Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
       }
 
-      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, stepSch));
-      //CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, stepSch, CalculationManager::PrePostBc));
-      //calculation->setTimeAveragedValuesCoProcessor(tav);
-      if (myid == 0) UBLOG(logINFO, "Simulation-start");
+      //////////////////////////////////////////////////////////////////////////
+      //MPIIORestart2CoProcessor test
+      //UbSchedulerPtr iSch(new UbScheduler(100,100));
+      //MPIIORestart2CoProcessor rcpInit(grid, iSch, pathOut+"/mpiio2", comm);
+      //////////////////////////////////////////////////////////////////////////
+
+      //CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, stepSch));
+      //CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, stepSch, CalculationManager::MPI));
+      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, stepSch, CalculationManager::PrePostBc));
+
+      if (myid==0) UBLOG(logINFO, "Simulation-start");
       calculation->calculate();
-      if (myid == 0) UBLOG(logINFO, "Simulation-end");
+      if (myid==0) UBLOG(logINFO, "Simulation-end");
+
+      if (myid==0)
+      {
+         UBLOG(logINFO, "PID = "<<myid<<" Point 10");
+         UBLOG(logINFO, "PID = "<<myid<<" Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+      }
    }
    catch (std::exception& e)
    {
-      cerr << e.what() << endl << flush;
+      cerr<<e.what()<<endl<<flush;
    }
    catch (std::string& s)
    {
-      cerr << s << endl;
+      cerr<<s<<endl;
    }
    catch (...)
    {
-      cerr << "unknown exception" << endl;
+      cerr<<"unknown exception"<<endl;
    }
 
 }
@@ -719,15 +895,15 @@ void run(string configname)
 int main(int argc, char* argv[])
 {
 
-   if (argv != NULL)
+   if (argv!=NULL)
    {
-      if (argv[1] != NULL)
+      if (argv[1]!=NULL)
       {
          run(string(argv[1]));
       }
       else
       {
-         cout << "Configuration file must be set!: " << argv[0] << " <config file>" << endl << std::flush;
+         cout<<"Configuration file must be set!: "<<argv[0]<<" <config file>"<<endl<<std::flush;
       }
    }
 
diff --git a/source/Applications/FlowAroundCylinder/cylinder.cfg b/source/Applications/FlowAroundCylinder/cylinder.cfg
new file mode 100644
index 000000000..9d20b3f73
--- /dev/null
+++ b/source/Applications/FlowAroundCylinder/cylinder.cfg
@@ -0,0 +1,22 @@
+pathOut = d:/temp/cylinder
+
+numOfThreads = 4
+availMem = 15e9
+refineLevel = 1 
+blockNx = 25 41 41
+uLB = 0.001
+dx = 0.005
+#dx = 0.01
+
+logToFile = false
+
+newStart = true
+restartStep = 1000
+
+cpStart = 1000
+cpStep = 1000
+
+outTime = 10
+endTime = 10
+
+nupsStep = 100 100 10000000
\ No newline at end of file
diff --git a/source/Applications/FlowAroundCylinder/cylinder.cpp b/source/Applications/FlowAroundCylinder/cylinder.cpp
index 51856c0eb..767b5f4a6 100644
--- a/source/Applications/FlowAroundCylinder/cylinder.cpp
+++ b/source/Applications/FlowAroundCylinder/cylinder.cpp
@@ -7,123 +7,76 @@ using namespace std;
 
 
 //////////////////////////////////////////////////////////////////////////
-void run()
+void run(string configname)
 {
    try
    {
       //DEBUG///////////////////////////////////////
       //Sleep(30000);
       /////////////////////////////////////////////
-      
-      string machine = QUOTEME(CAB_MACHINE);
-      string pathname; 
-      int numOfThreads = 4;
-      double availMem = 0;
+      ConfigurationFile   config;
+      config.load(configname);
+
+      string          pathOut = config.getValue<string>("pathOut");
+      double          uLB = config.getValue<double>("uLB");
+      double          restartStep = config.getValue<double>("restartStep");
+      double          cpStart = config.getValue<double>("cpStart");
+      double          cpStep = config.getValue<double>("cpStep");
+      double          endTime = config.getValue<double>("endTime");
+      double          outTime = config.getValue<double>("outTime");
+      double          availMem = config.getValue<double>("availMem");
+      int             refineLevel = config.getValue<int>("refineLevel");
+      bool            logToFile = config.getValue<bool>("logToFile");
+      vector<double>  nupsStep = config.getVector<double>("nupsStep");
+      bool            newStart = config.getValue<bool>("newStart");
+      int             numOfThreads = config.getValue<int>("numOfThreads");
+      vector<int>     blockNx = config.getVector<int>("blockNx");
+      double          dx = config.getValue<double>("dx");
 
       CommunicatorPtr comm = MPICommunicator::getInstance();
       int myid = comm->getProcessID();
 
-      if(machine == "BOMBADIL") 
-      {
-         pathname = "d:/temp/cylinderComp";
-         numOfThreads = 1;
-         availMem = 10.0e9;
-      }
-      else if(machine == "M01" || machine == "M02")      
+      if (logToFile)
       {
-         pathname = "/work/koskuche/scratch/cylinder_Re20nu4l";
-         numOfThreads = 1;
-         availMem = 12.0e9;
+#if defined(__unix__)
+         if (myid==0)
+         {
+            const char* str = pathOut.c_str();
+            mkdir(str, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH);
+         }
+#endif 
 
-         if(myid ==0)
+         if (myid==0)
          {
             stringstream logFilename;
-            logFilename <<  pathname + "/logfile"+UbSystem::toString(UbSystem::getTimeStamp())+".txt";
+            logFilename<<pathOut+"/logfile"+UbSystem::toString(UbSystem::getTimeStamp())+".txt";
             UbLog::output_policy::setStream(logFilename.str());
          }
       }
-      else throw UbException(UB_EXARGS, "unknown CAB_MACHINE");
 
-      UBLOG(logINFO, "Test case: flow around cylinder");
+      if (myid == 0) UBLOG(logINFO, "Test case: flow around cylinder");
 
-      double dx = 0.04;
+      
 
-      double L1 = 2.5*2.0;
+      double L1 = 2.5;
       double L2, L3, H;
-      L2 = L3 = H = 0.41*2.0;
+      L2 = L3 = H = 0.41;
 
-      LBMReal radius = 0.05*2.0;
+      LBMReal Re = 20.0;
+      LBMReal radius = 0.05;
       LBMReal rhoReal = 1.0; //kg/m^3
       LBMReal uReal = 0.45;//m/s
-      LBMReal uLB = 0.1;
-      LBMReal Re = 20000.0;
+      LBMReal nueReal = (uReal*radius*2.0)/Re;
+      
       LBMReal rhoLB = 0.0;
-      LBMReal l = L2 / dx;
+      LBMReal nueLB = (((4.0/9.0)*uLB)*2.0*(radius/dx))/Re;
 
-      //LBMUnitConverterPtr conv = LBMUnitConverterPtr(new LBMUnitConverter(1.0, 1/sqrt(3.0)*(uReal/uLB), 1.0, 1.0/dx, dx*dx*dx));
       LBMUnitConverterPtr conv = LBMUnitConverterPtr(new LBMUnitConverter());
 
       const int baseLevel = 0;
-      const int refineLevel = 1;
-
-      //obstacle
-      GbObject3DPtr cylinder(new GbCylinder3D(0.5*2.0, 0.2*2.0, -0.1, 0.5*2.0, 0.2*2.0, L3+0.1, radius));
-      GbSystem3D::writeGeoObject(cylinder.get(),pathname + "/geo/cylinder", WbWriterVtkXmlBinary::getInstance());
-
-      GbObject3DPtr refCylinder(new GbCylinder3D(0.5*2.0, 0.2*2.0, -0.1, 0.5*2.0, 0.2*2.0, L3+0.1, radius+7.0*dx/(1<<refineLevel)));
-      GbSystem3D::writeGeoObject(refCylinder.get(),pathname + "/geo/refCylinder", WbWriterVtkXmlBinary::getInstance());
-
-      D3Q27InteractorPtr cylinderInt;
-
-      //bounding box
-      double d_minX1 = 0.0;
-      double d_minX2 = 0.0;
-      double d_minX3 = 0.0;
-
-      double d_maxX1 = L1;
-      double d_maxX2 = L2;
-      double d_maxX3 = L3;
-
-      //double offs = dx;
-      double offs = 0;
-
-      //double g_minX1 = d_minX1-offs-0.499999*dx;
-      double g_minX1 = d_minX1;
-      double g_minX2 = d_minX2-7.0*dx;
-      double g_minX3 = d_minX3;
-
-      double g_maxX1 = d_maxX1;
-      double g_maxX2 = d_maxX2;
-      double g_maxX3 = d_maxX3;
-
-      GbObject3DPtr gridCube(new GbCuboid3D(g_minX1, g_minX2, g_minX3, g_maxX1, g_maxX2, g_maxX3));
-
-      const int blocknx1 = 8;
-      const int blocknx2 = 8;
-      const int blocknx3 = 8;
-
-      //dx = (0.41+2.0*dx)/(10.0*(int)blocknx2);
-
-      LBMReal nueLB = (((4.0/9.0)*uLB)*2.0*(radius/dx))/Re;
-
-      double blockLength = blocknx1*dx;
-
-      //refinement area
-      double rf = cylinder->getLengthX1()/4;
-      GbObject3DPtr refineCube(new  GbCuboid3D(cylinder->getX1Minimum()-rf, cylinder->getX2Minimum()-rf, cylinder->getX3Minimum(), 
-         cylinder->getX1Maximum()+rf, cylinder->getX2Maximum()+rf, cylinder->getX3Maximum()));
-      //       GbObject3DPtr refineCube(new  GbCuboid3D(g_minX1 + 7.05*blockLength, g_minX2 + 3.05*blockLength, cylinder->getX3Minimum(), 
-      //          g_minX1 + 12.95*blockLength, g_maxX2 - 3.05*blockLength, cylinder->getX3Maximum()));
 
       Grid3DPtr grid(new Grid3D(comm));
 
-      UbSchedulerPtr rSch(new UbScheduler(100000, 100000));
-      //RestartPostprocessorPtr rp(new RestartPostprocessor(grid, rSch, comm, pathname+"/checkpoints", RestartPostprocessor::BINARY));
-
-      //UbSchedulerPtr emSch(new UbScheduler(1000, 1000));
-      //EmergencyExitPostprocessor em(grid, emSch, pathname+"/checkpoints/emex.txt", rp, comm);
-
-
       //BC
       BCAdapterPtr noSlipAdapter(new NoSlipBCAdapter());
       noSlipAdapter->setBcAlgorithm(BCAlgorithmPtr(new NoSlipBCAlgorithm()));
@@ -143,83 +96,105 @@ void run()
       bcVisitor.addBC(velBCAdapter);
       bcVisitor.addBC(denBCAdapter);
 
+      //////////////////////////////////////////////////////////////////////////
+      //restart
+      UbSchedulerPtr rSch(new UbScheduler(cpStep, cpStart));
+      //RestartCoProcessor rp(grid, rSch, comm, pathOut, RestartCoProcessor::BINARY);
+      MPIIORestartCoProcessor rcp(grid, rSch, pathOut, comm);
+      //////////////////////////////////////////////////////////////////////////
+
+      ////cylinder
+      GbObject3DPtr cylinder(new GbCylinder3D(0.5, 0.2, -0.1, 0.5, 0.2, L3+0.1, radius));
+      GbSystem3D::writeGeoObject(cylinder.get(), pathOut+"/geo/cylinder", WbWriterVtkXmlBinary::getInstance());
+      
+      D3Q27InteractorPtr cylinderInt = D3Q27InteractorPtr(new D3Q27Interactor(cylinder, grid, noSlipAdapter, Interactor3D::SOLID));
 
-      if (grid->getTimeStep() == 0)
+      if (newStart)
       {
          if (myid==0)
          {
             UBLOG(logINFO, "Number of processes = "<<comm->getNumberOfProcesses());
             UBLOG(logINFO, "Number of threads = "<<numOfThreads);
-            UBLOG(logINFO, "path = "<<pathname);
+            UBLOG(logINFO, "path = "<<pathOut);
             UBLOG(logINFO, "L = "<<L1/dx);
             UBLOG(logINFO, "H = "<<H/dx);
-            UBLOG(logINFO, "v = "<<uLB);
-            UBLOG(logINFO, "rho = "<<rhoLB);
-            UBLOG(logINFO, "nue = "<<nueLB);
+            UBLOG(logINFO, "uReal = "<<uReal<<" m/s");
+            UBLOG(logINFO, "rhoReal = "<<rhoReal<<" kg/m^3");
+            UBLOG(logINFO, "nueReal = "<<nueReal<<" m^2/s");
+            UBLOG(logINFO, "uLB = "<<uLB);
+            UBLOG(logINFO, "rhoLB = "<<rhoLB);
+            UBLOG(logINFO, "nueLB = "<<nueLB);
             UBLOG(logINFO, "Re = "<<Re);
-            UBLOG(logINFO, "dx = "<<dx);
+            UBLOG(logINFO, "dx coarse= "<<dx);
+            UBLOG(logINFO, "dx fine = "<<dx/(1<<refineLevel) );
             UBLOG(logINFO, "Number of level = "<<refineLevel+1);
-            //UBLOG(logINFO,conv->toString() );
             UBLOG(logINFO, "Preprozess - start");
          }
 
-         grid->setDeltaX(dx);
-         grid->setBlockNX(blocknx1, blocknx2, blocknx3);
-         grid->setPeriodicX3(true);
+         GbObject3DPtr refCylinder(new GbCylinder3D(0.5, 0.2, -0.1, 0.5, 0.2, L3+0.1, radius+7.0*dx/(1<<refineLevel)));
+         GbSystem3D::writeGeoObject(refCylinder.get(), pathOut+"/geo/refCylinder", WbWriterVtkXmlBinary::getInstance());
+
+         //bounding box
+         double g_minX1 = 0.0;
+         double g_minX2 = 0.0;
+         double g_minX3 = 0.0;
+
+         double g_maxX1 = L1;
+         double g_maxX2 = L2;
+         double g_maxX3 = L3;
 
-         // UbTupleDouble6 bouningBox(gridCube->getX1Minimum(),gridCube->getX2Minimum(),gridCube->getX3Minimum(),
-         // gridCube->getX1Maximum(),gridCube->getX2Maximum(),gridCube->getX3Maximum());
-         // UbTupleInt3 blockNx(blocknx1, blocknx2, blocknx3);
-         // UbTupleInt3 gridNx(8, 16, 16);
-         // grid = Grid3DPtr(new Grid3D(bouningBox, blockNx, gridNx));
+         GbObject3DPtr gridCube(new GbCuboid3D(g_minX1, g_minX2, g_minX3, g_maxX1, g_maxX2, g_maxX3));
+         if (myid==0) GbSystem3D::writeGeoObject(gridCube.get(), pathOut+"/geo/gridCube", WbWriterVtkXmlBinary::getInstance());
 
-         if (myid==0) GbSystem3D::writeGeoObject(gridCube.get(), pathname+"/geo/gridCube", WbWriterVtkXmlBinary::getInstance());
-         if (myid==0) GbSystem3D::writeGeoObject(refineCube.get(), pathname+"/geo/refineCube", WbWriterVtkXmlBinary::getInstance());
+         const int blocknx1 = blockNx[0];
+         const int blocknx2 = blockNx[1];
+         const int blocknx3 = blockNx[2];
+
+         double blockLength = blocknx1*dx;
+
+         grid->setDeltaX(dx);
+         grid->setBlockNX(blocknx1, blocknx2, blocknx3);
 
          GenBlocksGridVisitor genBlocks(gridCube);
          grid->accept(genBlocks);
 
          //walls
-         GbCuboid3DPtr addWallYmin(new GbCuboid3D(d_minX1-blockLength, d_minX2-blockLength, d_minX3-blockLength, d_maxX1+blockLength, d_minX2, d_maxX3+blockLength));
-         if (myid==0) GbSystem3D::writeGeoObject(addWallYmin.get(), pathname+"/geo/addWallYmin", WbWriterVtkXmlASCII::getInstance());
+         GbCuboid3DPtr addWallYmin(new GbCuboid3D(g_minX1-blockLength, g_minX2-blockLength, g_minX3-blockLength, g_maxX1+blockLength, g_minX2, g_maxX3+blockLength));
+         if (myid==0) GbSystem3D::writeGeoObject(addWallYmin.get(), pathOut+"/geo/addWallYmin", WbWriterVtkXmlASCII::getInstance());
 
-         GbCuboid3DPtr addWallYmax(new GbCuboid3D(d_minX1-blockLength, d_maxX2, d_minX3-blockLength, d_maxX1+blockLength, d_maxX2+blockLength, d_maxX3+blockLength));
-         if (myid==0) GbSystem3D::writeGeoObject(addWallYmax.get(), pathname+"/geo/addWallYmax", WbWriterVtkXmlASCII::getInstance());
+         GbCuboid3DPtr addWallYmax(new GbCuboid3D(g_minX1-blockLength, g_maxX2, g_minX3-blockLength, g_maxX1+blockLength, g_maxX2+blockLength, g_maxX3+blockLength));
+         if (myid==0) GbSystem3D::writeGeoObject(addWallYmax.get(), pathOut+"/geo/addWallYmax", WbWriterVtkXmlASCII::getInstance());
 
-         //GbCuboid3DPtr addWallZmin(new GbCuboid3D(d_minX1-blockLength, d_minX2-blockLength, d_minX3-blockLength, d_maxX1+blockLength, d_maxX2+blockLength, d_minX3));
-         //if (myid==0) GbSystem3D::writeGeoObject(addWallZmin.get(), pathname+"/geo/addWallZmin", WbWriterVtkXmlASCII::getInstance());
+         GbCuboid3DPtr addWallZmin(new GbCuboid3D(g_minX1-blockLength, g_minX2-blockLength, g_minX3-blockLength, g_maxX1+blockLength, g_maxX2+blockLength, g_minX3));
+         if (myid==0) GbSystem3D::writeGeoObject(addWallZmin.get(), pathOut+"/geo/addWallZmin", WbWriterVtkXmlASCII::getInstance());
 
-         //GbCuboid3DPtr addWallZmax(new GbCuboid3D(d_minX1-blockLength, d_minX2-blockLength, d_maxX3, d_maxX1+blockLength, d_maxX2+blockLength, d_maxX3+blockLength));
-         //if (myid==0) GbSystem3D::writeGeoObject(addWallZmax.get(), pathname+"/geo/addWallZmax", WbWriterVtkXmlASCII::getInstance());
+         GbCuboid3DPtr addWallZmax(new GbCuboid3D(g_minX1-blockLength, g_minX2-blockLength, g_maxX3, g_maxX1+blockLength, g_maxX2+blockLength, g_maxX3+blockLength));
+         if (myid==0) GbSystem3D::writeGeoObject(addWallZmax.get(), pathOut+"/geo/addWallZmax", WbWriterVtkXmlASCII::getInstance());
 
          //inflow
-         GbCuboid3DPtr geoInflow(new GbCuboid3D(d_minX1-blockLength, d_minX2-blockLength, d_minX3-blockLength, d_minX1, d_maxX2+blockLength, d_maxX3+blockLength));
-         if (myid==0) GbSystem3D::writeGeoObject(geoInflow.get(), pathname+"/geo/geoInflow", WbWriterVtkXmlASCII::getInstance());
+         GbCuboid3DPtr geoInflow(new GbCuboid3D(g_minX1-blockLength, g_minX2-blockLength, g_minX3-blockLength, g_minX1, g_maxX2+blockLength, g_maxX3+blockLength));
+         if (myid==0) GbSystem3D::writeGeoObject(geoInflow.get(), pathOut+"/geo/geoInflow", WbWriterVtkXmlASCII::getInstance());
 
          //outflow
-         GbCuboid3DPtr geoOutflow(new GbCuboid3D(d_maxX1, d_minX2-blockLength, d_minX3-blockLength, d_maxX1+blockLength, d_maxX2+blockLength, d_maxX3+blockLength));
-         if (myid==0) GbSystem3D::writeGeoObject(geoOutflow.get(), pathname+"/geo/geoOutflow", WbWriterVtkXmlASCII::getInstance());
+         GbCuboid3DPtr geoOutflow(new GbCuboid3D(g_maxX1, g_minX2-blockLength, g_minX3-blockLength, g_maxX1+blockLength, g_maxX2+blockLength, g_maxX3+blockLength));
+         if (myid==0) GbSystem3D::writeGeoObject(geoOutflow.get(), pathOut+"/geo/geoOutflow", WbWriterVtkXmlASCII::getInstance());
 
-         WriteBlocksCoProcessorPtr ppblocks(new WriteBlocksCoProcessor(grid, UbSchedulerPtr(new UbScheduler(1)), pathname, WbWriterVtkXmlBinary::getInstance(), comm));
+         WriteBlocksCoProcessorPtr ppblocks(new WriteBlocksCoProcessor(grid, UbSchedulerPtr(new UbScheduler(1)), pathOut, WbWriterVtkXmlBinary::getInstance(), comm));
 
          if (refineLevel>0)
          {
             if (myid==0) UBLOG(logINFO, "Refinement - start");
-            RefineCrossAndInsideGbObjectHelper refineHelper(grid, refineLevel);
-            //refineHelper.addGbObject(refineCube, refineLevel);
+            RefineCrossAndInsideGbObjectHelper refineHelper(grid, refineLevel, comm);
             refineHelper.addGbObject(refCylinder, refineLevel);
             refineHelper.refine();
             if (myid==0) UBLOG(logINFO, "Refinement - end");
          }
 
-         //cylinder
-         cylinderInt = D3Q27InteractorPtr(new D3Q27Interactor(cylinder, grid, noSlipAdapter, Interactor3D::SOLID));
-
          //walls
          D3Q27InteractorPtr addWallYminInt(new D3Q27Interactor(addWallYmin, grid, noSlipAdapter, Interactor3D::SOLID));
          D3Q27InteractorPtr addWallYmaxInt(new D3Q27Interactor(addWallYmax, grid, noSlipAdapter, Interactor3D::SOLID));
-         //D3Q27InteractorPtr addWallZminInt(new D3Q27Interactor(addWallZmin, grid, noSlipAdapter, Interactor3D::SOLID));
-         //D3Q27InteractorPtr addWallZmaxInt(new D3Q27Interactor(addWallZmax, grid, noSlipAdapter, Interactor3D::SOLID));
+         D3Q27InteractorPtr addWallZminInt(new D3Q27Interactor(addWallZmin, grid, noSlipAdapter, Interactor3D::SOLID));
+         D3Q27InteractorPtr addWallZmaxInt(new D3Q27Interactor(addWallZmax, grid, noSlipAdapter, Interactor3D::SOLID));
 
          //inflow
          D3Q27InteractorPtr inflowInt = D3Q27InteractorPtr(new D3Q27Interactor(geoInflow, grid, velBCAdapter, Interactor3D::SOLID));
@@ -227,16 +202,14 @@ void run()
          //outflow
          D3Q27InteractorPtr outflowInt = D3Q27InteractorPtr(new D3Q27Interactor(geoOutflow, grid, denBCAdapter, Interactor3D::SOLID));
 
-         //D3Q27InteractorPtr addWallYminInt(new D3Q27Interactor(addWallYmin, grid, denBCAdapter, Interactor3D::SOLID));
-         //D3Q27InteractorPtr addWallYmaxInt(new D3Q27Interactor(addWallYmax, grid, denBCAdapter, Interactor3D::SOLID));
          
          Grid3DVisitorPtr metisVisitor(new MetisPartitioningGridVisitor(comm, MetisPartitioningGridVisitor::LevelBased, D3Q27System::B));
          InteractorsHelper intHelper(grid, metisVisitor);
          intHelper.addInteractor(cylinderInt);
          intHelper.addInteractor(addWallYminInt);
          intHelper.addInteractor(addWallYmaxInt);
-         //intHelper.addInteractor(addWallZminInt);
-         //intHelper.addInteractor(addWallZmaxInt);
+         intHelper.addInteractor(addWallZminInt);
+         intHelper.addInteractor(addWallZmaxInt);
          intHelper.addInteractor(inflowInt);
          intHelper.addInteractor(outflowInt);
          intHelper.selectBlocks();
@@ -251,17 +224,26 @@ void run()
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nueLB, iProcessor);
          grid->accept(setConnsVisitor);
 
-         unsigned long nob = grid->getNumberOfBlocks();
-         int gl = 3;
-         unsigned long nod = nob * (blocknx1+gl) * (blocknx2+gl) * (blocknx3+gl);
-
-         double needMemAll = double(nod*(27*sizeof(double)+sizeof(int)+sizeof(float)*4));
+         unsigned long long numberOfBlocks = (unsigned long long)grid->getNumberOfBlocks();
+         int ghostLayer = 3;
+         unsigned long long numberOfNodesPerBlock = (unsigned long long)(blockNx[0])* (unsigned long long)(blockNx[1])* (unsigned long long)(blockNx[2]);
+         unsigned long long numberOfNodes = numberOfBlocks * numberOfNodesPerBlock;
+         unsigned long long numberOfNodesPerBlockWithGhostLayer = numberOfBlocks * (blockNx[0]+ghostLayer) * (blockNx[1]+ghostLayer) * (blockNx[2]+ghostLayer);
+         double needMemAll = double(numberOfNodesPerBlockWithGhostLayer*(27*sizeof(double)+sizeof(int)+sizeof(float)*4));
          double needMem = needMemAll/double(comm->getNumberOfProcesses());
 
          if (myid==0)
          {
-            UBLOG(logINFO, "Number of blocks = "<<nob);
-            UBLOG(logINFO, "Number of nodes  = "<<nod);
+            UBLOG(logINFO, "Number of blocks = "<<numberOfBlocks);
+            UBLOG(logINFO, "Number of nodes  = "<<numberOfNodes);
+            int minInitLevel = grid->getCoarsestInitializedLevel();
+            int maxInitLevel = grid->getFinestInitializedLevel();
+            for (int level = minInitLevel; level<=maxInitLevel; level++)
+            {
+               int nobl = grid->getNumberOfBlocks(level);
+               UBLOG(logINFO, "Number of blocks for level "<<level<<" = "<<nobl);
+               UBLOG(logINFO, "Number of nodes for level "<<level<<" = "<<nobl*numberOfNodesPerBlock);
+            }
             UBLOG(logINFO, "Necessary memory  = "<<needMemAll<<" bytes");
             UBLOG(logINFO, "Necessary memory per process = "<<needMem<<" bytes");
             UBLOG(logINFO, "Available memory per process = "<<availMem<<" bytes");
@@ -287,8 +269,8 @@ void run()
          grid->accept(bcVisitor);
 
          //domain decomposition
-         PQueuePartitioningGridVisitor pqPartVisitor(numOfThreads);
-         grid->accept(pqPartVisitor);
+         //PQueuePartitioningGridVisitor pqPartVisitor(numOfThreads);
+         //grid->accept(pqPartVisitor);
 
          //initialization of distributions
          InitDistributionsBlockVisitor initVisitor(nueLB, rhoLB);
@@ -298,7 +280,7 @@ void run()
          //Postrozess
          UbSchedulerPtr geoSch(new UbScheduler(1));
          WriteBoundaryConditionsCoProcessorPtr ppgeo(
-            new WriteBoundaryConditionsCoProcessor(grid, geoSch, pathname, WbWriterVtkXmlBinary::getInstance(), conv, comm));
+            new WriteBoundaryConditionsCoProcessor(grid, geoSch, pathOut, WbWriterVtkXmlBinary::getInstance(), conv, comm));
          ppgeo->process(0);
          ppgeo.reset();
 
@@ -306,51 +288,39 @@ void run()
       }
       else
       {
+         rcp.restart((int)restartStep);
+         grid->setTimeStep(restartStep);
+
          //set connectors
          InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nueLB, iProcessor);
          grid->accept(setConnsVisitor);
 
          //domain decomposition
-         PQueuePartitioningGridVisitor pqPartVisitor(numOfThreads);
-         grid->accept(pqPartVisitor);
+         //PQueuePartitioningGridVisitor pqPartVisitor(numOfThreads);
+         //grid->accept(pqPartVisitor);
+
+         SetSolidOrTransBlockVisitor v(cylinderInt, SetSolidOrTransBlockVisitor::TRANS);
+         grid->accept(v);
+         cylinderInt->initInteractor();
 
+         grid->accept(bcVisitor);
       }
 
-      double outTime = 10.0;
       UbSchedulerPtr visSch(new UbScheduler(outTime));
-      //visSch->addSchedule(1000, 1000, 10000);
-      //visSch->addSchedule(10000, 10000, 50000);
-      //visSch->addSchedule(100, 100, 10000);
-
-      WriteMacroscopicQuantitiesCoProcessor pp(grid, visSch, pathname, WbWriterVtkXmlBinary::getInstance(), conv, comm);
-
-      double fdx = grid->getDeltaX(grid->getFinestInitializedLevel());
-      double point1[3] = {0.45, 0.20, 0.205};
-      double point2[3] = {0.55, 0.20, 0.205};
-
-      //D3Q27IntegrateValuesHelperPtr h1(new D3Q27IntegrateValuesHelper(grid, comm, 
-      //   point1[0]-1.0*fdx, point1[1]-1.0*fdx, point1[2]-1.0*fdx, 
-      //   point1[0], point1[1], point1[2]));
-      //if(myid ==0) GbSystem3D::writeGeoObject(h1->getBoundingBox().get(),pathname + "/geo/iv1", WbWriterVtkXmlBinary::getInstance());
-      //D3Q27IntegrateValuesHelperPtr h2(new D3Q27IntegrateValuesHelper(grid, comm, 
-      //   point2[0], point2[1]-1.0*fdx, point2[2]-1.0*fdx, 
-      //   point2[0]+1.0*fdx, point2[1], point2[2]));
-      //if(myid ==0) GbSystem3D::writeGeoObject(h2->getBoundingBox().get(),pathname + "/geo/iv2", WbWriterVtkXmlBinary::getInstance());
-      ////D3Q27PressureDifferencePostprocessor rhopp(grid, visSch, pathname + "/results/rho_diff.txt", h1, h2, conv, comm);
-      //D3Q27PressureDifferencePostprocessor rhopp(grid, visSch, pathname + "/results/rho_diff.txt", h1, h2, rhoReal, uReal, uLB, comm);
-
-      //double area = (2.0*radius*H)/(dx*dx);
-      //double v    = 4.0*uLB/9.0;
-      //CalculateForcesCoProcessor fp(grid, visSch, pathname + "/results/forces.txt", comm, v, area);
-      //fp.addInteractor(cylinderInt);
-
-      UbSchedulerPtr nupsSch(new UbScheduler(10, 10, 40));
+
+      WriteMacroscopicQuantitiesCoProcessor pp(grid, visSch, pathOut, WbWriterVtkXmlBinary::getInstance(), conv, comm);
+
+      double area = (2.0*radius*H)/(dx*dx);
+      double v    = 4.0*uLB/9.0;
+      CalculateForcesCoProcessor fp(grid, visSch, pathOut + "/results/forces.txt", comm, v, area);
+      fp.addInteractor(cylinderInt);
+
+      UbSchedulerPtr nupsSch(new UbScheduler(nupsStep[0], nupsStep[1], nupsStep[2]));
       NUPSCounterCoProcessor npr(grid, nupsSch, numOfThreads, comm);
 
-      double endTime = 100000;
       //CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, visSch));
-      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, visSch, CalculationManager::PrePostBc));
+      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, visSch, CalculationManager::MPI));
       if(myid == 0) UBLOG(logINFO,"Simulation-start");
       calculation->calculate();
       if(myid == 0) UBLOG(logINFO,"Simulation-end");
@@ -372,7 +342,17 @@ void run()
 //////////////////////////////////////////////////////////////////////////
 int main(int argc, char* argv[])
 {
-   run();
+   if (argv!=NULL)
+   {
+      if (argv[1]!=NULL)
+      {
+         run(string(argv[1]));
+      }
+      else
+      {
+         cout<<"Configuration file must be set!: "<<argv[0]<<" <config file>"<<endl<<std::flush;
+      }
+   }
    return 0;
 }
 
diff --git a/source/Applications/Hagen_Poiseuille_flow/pfDP.cfg b/source/Applications/Hagen_Poiseuille_flow/pfDP.cfg
index f8fe50979..8ce76695c 100644
--- a/source/Applications/Hagen_Poiseuille_flow/pfDP.cfg
+++ b/source/Applications/Hagen_Poiseuille_flow/pfDP.cfg
@@ -1,12 +1,12 @@
-pathname = d:/temp/pflowDP2
-numOfThreads = 4
+pathname = d:/temp/pflowDP_Test2
+numOfThreads = 1
 availMem = 8e9
 logToFile = false
-blocknx = 10 10 10
-gridnx = 2 1 2
-nuLB = 1e-2
-dpLB = 1e-7
-deltax = 0.1
+blocknx = 8 8 8
+gridnx = 64 64 8
+nuLB = 0.05842
+dpLB = 9.99685e-7
+deltax = 1
 
 refineLevel = 0
 logToFile=false
@@ -14,5 +14,5 @@ thinWall = false
 
 restartStep = 100000
 
-endTime = 100000
-outTime = 100000
\ No newline at end of file
+endTime = 1000000
+outTime = 1
\ No newline at end of file
diff --git a/source/Applications/Hagen_Poiseuille_flow/pflow.cpp b/source/Applications/Hagen_Poiseuille_flow/pflow.cpp
index f76187532..1b07c687a 100644
--- a/source/Applications/Hagen_Poiseuille_flow/pflow.cpp
+++ b/source/Applications/Hagen_Poiseuille_flow/pflow.cpp
@@ -347,21 +347,53 @@ void pflowdp(string configname)
       double Re = (4 * h*Umax) / (3 * nuLB);
 
       //bc
-      BCAdapterPtr noSlipBCAdapter(new NoSlipBCAdapter());
-      noSlipBCAdapter->setBcAlgorithm(NoSlipBCAlgorithmPtr(new NoSlipBCAlgorithm()));
 
-      BCAdapterPtr denBCAdapterInflow(new DensityBCAdapter(rhoLBinflow));
-      denBCAdapterInflow->setBcAlgorithm(BCAlgorithmPtr(new EqDensityBCAlgorithm()));
+      mu::Parser fct;
+      fct.SetExpr("U");
+      fct.DefineConst("U", 0.1);
+      BCAdapterPtr denBCAdapterInflow(new VelocityBCAdapter(true, false, false, fct, 0, BCFunction::INFCONST));
+      denBCAdapterInflow->setBcAlgorithm(BCAlgorithmPtr(new VelocityWithDensityBCAlgorithm()));
+      //denBCAdapterInflow->setBcAlgorithm(BCAlgorithmPtr(new VelocityBCAlgorithm()));
 
       BCAdapterPtr denBCAdapterOutflow(new DensityBCAdapter(rhoLB));
-      denBCAdapterOutflow->setBcAlgorithm(BCAlgorithmPtr(new EqDensityBCAlgorithm()));
+      denBCAdapterOutflow->setBcAlgorithm(BCAlgorithmPtr(new NonReflectingOutflowBCAlgorithm()));
+      //denBCAdapterOutflow->setBcAlgorithm(BCAlgorithmPtr(new NonEqDensityBCAlgorithm()));
+
+      BCAdapterPtr slipBCAdapter(new SlipBCAdapter());
+      //slipBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new NonReflectingSlipBCAlgorithm()));
+      slipBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new SlipBCAlgorithm()));
+      
+
+      BCAdapterPtr noSlipBCAdapter(new NoSlipBCAdapter());
+      noSlipBCAdapter->setBcAlgorithm(NoSlipBCAlgorithmPtr(new NoSlipBCAlgorithm()));
 
-      //BS visitor
       BoundaryConditionsBlockVisitor bcVisitor;
       bcVisitor.addBC(noSlipBCAdapter);
+      bcVisitor.addBC(slipBCAdapter);
       bcVisitor.addBC(denBCAdapterInflow);
       bcVisitor.addBC(denBCAdapterOutflow);
 
+
+
+
+
+
+
+      //BCAdapterPtr noSlipBCAdapter(new NoSlipBCAdapter());
+      //noSlipBCAdapter->setBcAlgorithm(NoSlipBCAlgorithmPtr(new NoSlipBCAlgorithm()));
+
+      //BCAdapterPtr denBCAdapterInflow(new DensityBCAdapter(rhoLBinflow));
+      //denBCAdapterInflow->setBcAlgorithm(BCAlgorithmPtr(new EqDensityBCAlgorithm()));
+
+      //BCAdapterPtr denBCAdapterOutflow(new DensityBCAdapter(rhoLB));
+      //denBCAdapterOutflow->setBcAlgorithm(BCAlgorithmPtr(new EqDensityBCAlgorithm()));
+
+      ////BS visitor
+      //BoundaryConditionsBlockVisitor bcVisitor;
+      //bcVisitor.addBC(noSlipBCAdapter);
+      //bcVisitor.addBC(denBCAdapterInflow);
+      //bcVisitor.addBC(denBCAdapterOutflow);
+
       Grid3DPtr grid(new Grid3D(comm));
       grid->setPeriodicX1(false);
       grid->setPeriodicX2(false);
@@ -421,17 +453,23 @@ void pflowdp(string configname)
          GbCuboid3DPtr addWallYmin (new GbCuboid3D(g_minX1-4.0*blockLength, g_minX2-4.0*blockLength, g_minX3-4.0*blockLength, g_maxX1+4.0*blockLength, g_minX2, g_maxX3+4.0*blockLength));
          if(myid == 0) GbSystem3D::writeGeoObject(addWallYmin.get(), pathname+"/geo/addWallYmin", WbWriterVtkXmlASCII::getInstance());
 
-         GbCuboid3DPtr addWallYmax (new GbCuboid3D(g_minX1-4.0*blockLength, g_maxX2, g_minX3-4.0*blockLength, g_maxX1+4.0*blockLength, g_maxX2+4.0*blockLength, g_maxX3+4.0*blockLength));
+         GbCuboid3DPtr addWallYmax (new GbCuboid3D(g_minX1-4.0*blockLength, g_maxX2, g_minX3-4.0*blockLength, g_maxX1, g_maxX2+4.0*blockLength, g_maxX3+4.0*blockLength));
          if(myid == 0) GbSystem3D::writeGeoObject(addWallYmax.get(), pathname+"/geo/addWallYmax", WbWriterVtkXmlASCII::getInstance());
 
+         GbCuboid3DPtr addWallXmax(new GbCuboid3D(g_maxX1-4.0*deltax, g_maxX2, g_minX3 - 4.0*blockLength, g_maxX1 + 4.0*blockLength, g_maxX2 + 4.0*blockLength, g_maxX3 + 4.0*blockLength));
+         if (myid == 0) GbSystem3D::writeGeoObject(addWallXmax.get(), pathname+"/geo/addWallXmax", WbWriterVtkXmlASCII::getInstance());
+
          //inflow
          GbCuboid3DPtr geoInflow(new GbCuboid3D(g_minX1 - 4.0*blockLength, g_minX2 - 4.0*blockLength, g_minX3 - 4.0*blockLength, g_minX1, g_maxX2 + 4.0*blockLength, g_maxX3 + 4.0*blockLength));
          if (myid == 0) GbSystem3D::writeGeoObject(geoInflow.get(), pathname + "/geo/geoInflow", WbWriterVtkXmlASCII::getInstance());
 
          //outflow
-         GbCuboid3DPtr geoOutflow(new GbCuboid3D(g_maxX1, g_minX2 - 4.0*blockLength, g_minX3 - 4.0*blockLength, g_maxX1 + 4.0*blockLength, g_maxX2 + 4.0*blockLength, g_maxX3 + 4.0*blockLength));
+         GbCuboid3DPtr geoOutflow(new GbCuboid3D(g_maxX1, g_minX2 - 4.0*blockLength, g_minX3 - 4.0*blockLength, g_maxX1 + 4.0*blockLength, g_maxX2+4.0*blockLength, g_maxX3 + 4.0*blockLength));
          if (myid == 0) GbSystem3D::writeGeoObject(geoOutflow.get(), pathname + "/geo/geoOutflow", WbWriterVtkXmlASCII::getInstance());
 
+         GbCuboid3DPtr geoOutflowSolid(new GbCuboid3D(g_maxX1-1.0*deltax, g_minX2 - 4.0*blockLength, g_minX3 - 4.0*blockLength, g_maxX1 + 4.0*blockLength, g_maxX2+4.0*blockLength, g_maxX3 + 4.0*blockLength));
+         if (myid == 0) GbSystem3D::writeGeoObject(geoOutflowSolid.get(), pathname + "/geo/geoOutflowSolid", WbWriterVtkXmlASCII::getInstance());
+
          ////inflow
          //GbCuboid3DPtr geoInflow (new GbCuboid3D(g_minX1-4.0*blockLength, g_minX2-4.0*blockLength, g_minX3-4.0*blockLength, g_maxX1+4.0*blockLength, g_maxX2+4.0*blockLength, g_minX3));
          //if(myid == 0) GbSystem3D::writeGeoObject(geoInflow.get(), pathname+"/geo/geoInflow", WbWriterVtkXmlASCII::getInstance());
@@ -445,7 +483,7 @@ void pflowdp(string configname)
          if (refineLevel > 0)
          {
             if (myid == 0) UBLOG(logINFO, "Refinement - start");
-            RefineCrossAndInsideGbObjectHelper refineHelper(grid, refineLevel);
+            RefineCrossAndInsideGbObjectHelper refineHelper(grid, refineLevel,comm);
             //refineHelper.addGbObject(refineCube1_1, 1);
             //refineHelper.addGbObject(refineCube1_2, 1);
             //refineHelper.addGbObject(refineCube2_1, 2);
@@ -456,13 +494,16 @@ void pflowdp(string configname)
          }
 
          //walls
-         D3Q27InteractorPtr addWallYminInt(new D3Q27Interactor(addWallYmin, grid, noSlipBCAdapter,Interactor3D::SOLID));
-         D3Q27InteractorPtr addWallYmaxInt(new D3Q27Interactor(addWallYmax, grid, noSlipBCAdapter,Interactor3D::SOLID));
+         D3Q27InteractorPtr addWallYminInt(new D3Q27Interactor(addWallYmin, grid, denBCAdapterInflow,Interactor3D::SOLID));
+         D3Q27InteractorPtr addWallYmaxInt(new D3Q27Interactor(addWallYmax, grid, denBCAdapterInflow,Interactor3D::SOLID));
+
+         D3Q27InteractorPtr addWallXmaxInt(new D3Q27Interactor(addWallXmax, grid, denBCAdapterOutflow,Interactor3D::SOLID));
 
          D3Q27InteractorPtr inflowInt = D3Q27InteractorPtr(new D3Q27Interactor(geoInflow, grid, denBCAdapterInflow, Interactor3D::SOLID));
 
          //outflow
          D3Q27InteractorPtr outflowInt = D3Q27InteractorPtr(new D3Q27Interactor(geoOutflow, grid, denBCAdapterOutflow, Interactor3D::SOLID));
+         D3Q27InteractorPtr outflowSolidInt = D3Q27InteractorPtr(new D3Q27Interactor(geoOutflow, grid, noSlipBCAdapter, Interactor3D::SOLID));
 
          ////////////////////////////////////////////
          //METIS
@@ -471,16 +512,23 @@ void pflowdp(string configname)
          /////delete solid blocks
          if (myid == 0) UBLOG(logINFO, "deleteSolidBlocks - start");
          InteractorsHelper intHelper(grid, metisVisitor);
-         intHelper.addInteractor(addWallYminInt);
-         intHelper.addInteractor(addWallYmaxInt);
+
          intHelper.addInteractor(inflowInt);
+         
          intHelper.addInteractor(outflowInt);
+
+         //die Geschwindigkeit Randbedingung soll Ausflüß überdecken !!!!!
+         intHelper.addInteractor(addWallYminInt);
+         intHelper.addInteractor(addWallYmaxInt);
+
+
          intHelper.selectBlocks();
          if (myid == 0) UBLOG(logINFO, "deleteSolidBlocks - end");
          //////////////////////////////////////
 
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
@@ -518,7 +566,8 @@ void pflowdp(string configname)
 
          int kernelType = 2;
          LBMKernelPtr kernel;
-         kernel = LBMKernelPtr(new IncompressibleCumulantLBMKernel(blocknx[0], blocknx[1], blocknx[2], IncompressibleCumulantLBMKernel::NORMAL));
+         //kernel = LBMKernelPtr(new IncompressibleCumulantLBMKernel(blocknx[0], blocknx[1], blocknx[2], IncompressibleCumulantLBMKernel::NORMAL));
+         kernel = LBMKernelPtr(new CompressibleCumulantLBMKernel(blocknx[0], blocknx[1], blocknx[2], CompressibleCumulantLBMKernel::NORMAL));
          //}
 
          BCProcessorPtr bcProc(new BCProcessor());
@@ -548,7 +597,7 @@ void pflowdp(string configname)
 
          InitDistributionsBlockVisitor initVisitor(nuLB, rhoLB);
          //initVisitor.setVx1(fct);
-         initVisitor.setVx1(0.0);
+         initVisitor.setVx1(0.1);
          //initVisitor.setVx3(fct);
          grid->accept(initVisitor);
 
@@ -579,7 +628,9 @@ void pflowdp(string configname)
 
       WriteMacroscopicQuantitiesCoProcessor pp(grid, stepSch, pathname, WbWriterVtkXmlBinary::getInstance(), conv, comm);
 
-      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, stepSch));
+      //CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, stepSch));
+       //CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, stepSch, CalculationManager::MPI));
+      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, stepSch, CalculationManager::PrePostBc));
       if (myid == 0) UBLOG(logINFO, "Simulation-start");
       calculation->calculate();
       if (myid == 0) UBLOG(logINFO, "Simulation-end");
diff --git a/source/Applications/Hagen_Poiseuille_flow2/CMakeLists.txt b/source/Applications/Hagen_Poiseuille_flow2/CMakeLists.txt
new file mode 100644
index 000000000..f59b6c279
--- /dev/null
+++ b/source/Applications/Hagen_Poiseuille_flow2/CMakeLists.txt
@@ -0,0 +1,25 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+
+########################################################
+## C++ PROJECT                                       ###
+########################################################
+PROJECT(pflow2)
+
+INCLUDE(${SOURCE_ROOT}/IncludsList.cmake) 
+
+#################################################################
+###   LOCAL FILES                                             ###
+#################################################################
+FILE(GLOB SPECIFIC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.h
+                         ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
+                         ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp  )
+ 
+SET(ALL_SOURCES ${ALL_SOURCES} ${SPECIFIC_FILES})
+SOURCE_GROUP(src FILES ${SPECIFIC_FILES})
+  
+SET(CAB_ADDITIONAL_LINK_LIBRARIES VirtualFluids)
+
+#################################################################
+###   CREATE PROJECT                                          ###
+#################################################################
+CREATE_CAB_PROJECT(pflow2 BINARY)
diff --git a/source/Applications/Hagen_Poiseuille_flow2/pf1.cfg b/source/Applications/Hagen_Poiseuille_flow2/pf1.cfg
new file mode 100644
index 000000000..68de4f8f9
--- /dev/null
+++ b/source/Applications/Hagen_Poiseuille_flow2/pf1.cfg
@@ -0,0 +1,18 @@
+pathname = d:/temp/pflow1
+numOfThreads = 4
+availMem = 8e9
+logToFile = false
+blocknx = 10 10 10
+gridnx = 2 1 2
+nuLB = 1e-2
+forcing = 5e-8
+deltax = 0.1
+
+refineLevel = 0
+logToFile=false
+thinWall = false
+
+restartStep = 100000
+
+endTime = 100000
+outTime = 100000
\ No newline at end of file
diff --git a/source/Applications/Hagen_Poiseuille_flow2/pf2.cfg b/source/Applications/Hagen_Poiseuille_flow2/pf2.cfg
new file mode 100644
index 000000000..348eb0c96
--- /dev/null
+++ b/source/Applications/Hagen_Poiseuille_flow2/pf2.cfg
@@ -0,0 +1,18 @@
+pathname = d:/temp/pflow2
+numOfThreads = 4
+availMem = 8e9
+logToFile = false
+blocknx = 10 10 10
+gridnx = 2 0.5 2
+nuLB = 1e-2
+forcing = 6.25e-9
+deltax = 0.05
+
+refineLevel = 0
+logToFile=false
+thinWall = false
+
+restartStep = 400000
+
+endTime = 400000
+outTime = 400000
\ No newline at end of file
diff --git a/source/Applications/Hagen_Poiseuille_flow2/pf3.cfg b/source/Applications/Hagen_Poiseuille_flow2/pf3.cfg
new file mode 100644
index 000000000..1104e0797
--- /dev/null
+++ b/source/Applications/Hagen_Poiseuille_flow2/pf3.cfg
@@ -0,0 +1,18 @@
+pathname = d:/temp/pflow4
+numOfThreads = 8
+availMem = 8e9
+logToFile = false
+blocknx = 10 10 10
+gridnx = 2 0.25 2
+nuLB = 1e-2
+forcing = 7.8125e-10
+deltax = 0.025
+
+refineLevel = 0
+logToFile=false
+thinWall = false
+
+restartStep = 400000
+
+endTime = 1600000
+outTime = 400000
\ No newline at end of file
diff --git a/source/Applications/Hagen_Poiseuille_flow2/pf4.cfg b/source/Applications/Hagen_Poiseuille_flow2/pf4.cfg
new file mode 100644
index 000000000..c7b243012
--- /dev/null
+++ b/source/Applications/Hagen_Poiseuille_flow2/pf4.cfg
@@ -0,0 +1,19 @@
+pathname = d:/temp/pflow4
+numOfThreads = 8
+availMem = 8e9
+logToFile = false
+blocknx = 10 10 10
+gridnx = 2 0.25 2
+nuLB = 1e-2
+forcing = 7.8125e-10
+deltax = 0.025
+
+refineLevel = 1
+logToFile=false
+thinWall = false
+
+restartStep = 400000
+
+endTime = 1600000
+#outTime = 400000
+outTime = 400
\ No newline at end of file
diff --git a/source/Applications/Hagen_Poiseuille_flow2/pfDP.cfg b/source/Applications/Hagen_Poiseuille_flow2/pfDP.cfg
new file mode 100644
index 000000000..9556b2c37
--- /dev/null
+++ b/source/Applications/Hagen_Poiseuille_flow2/pfDP.cfg
@@ -0,0 +1,18 @@
+pathname = d:/temp/pflowDP_compact_5_10-3_NoAveraging
+numOfThreads = 4
+availMem = 8e9
+logToFile = false
+blocknx = 10 10 2
+gridnx = 4 2 0.1
+nuLB = 5e-3
+dpLB = 1e-7
+deltax = 0.1
+
+refineLevel = 1
+logToFile=false
+thinWall = false
+
+restartStep = 100000
+
+endTime = 500000
+outTime = 50000
\ No newline at end of file
diff --git a/source/Applications/Hagen_Poiseuille_flow2/pflow2.cpp b/source/Applications/Hagen_Poiseuille_flow2/pflow2.cpp
new file mode 100644
index 000000000..b8bb08ccc
--- /dev/null
+++ b/source/Applications/Hagen_Poiseuille_flow2/pflow2.cpp
@@ -0,0 +1,334 @@
+#include <iostream>
+#include <string>
+
+#include <VirtualFluids.h>
+
+using namespace std;
+
+
+void pflowdp(string configname)
+{
+   try
+   {
+      ConfigurationFile   config;
+      config.load(configname);
+
+      string          pathname = config.getString("pathname");
+      int             numOfThreads = config.getInt("numOfThreads");
+      vector<int>     blocknx = config.getVector<int>("blocknx");
+      vector<double>  gridnx = config.getVector<double>("gridnx");
+      double          nuLB = config.getDouble("nuLB");
+      double          endTime = config.getDouble("endTime");
+      double          outTime = config.getDouble("outTime");
+      double          availMem = config.getDouble("availMem");
+      int             refineLevel = config.getInt("refineLevel");
+      bool            logToFile = config.getBool("logToFile");
+      double          restartStep = config.getDouble("restartStep");
+      double          dpLB = config.getDouble("dpLB");
+      bool            thinWall = config.getBool("thinWall");
+      double          deltax = config.getDouble("deltax");
+
+
+      CommunicatorPtr comm = MPICommunicator::getInstance();
+      int myid = comm->getProcessID();
+
+      LBMReal rhoLB = 0.0;
+      double rhoLBinflow = dpLB*3.0;
+
+      LBMUnitConverterPtr conv = LBMUnitConverterPtr(new LBMUnitConverter());
+
+      const int baseLevel = 0;
+
+            //bounding box
+            double g_minX1 = 0;
+            double g_minX2 = 0;
+            double g_minX3 = 0;
+      
+            double g_maxX1 = gridnx[0];
+            double g_maxX2 = gridnx[1];
+            double g_maxX3 = gridnx[2];
+
+      double blockLength = (double)blocknx[0]*deltax;
+
+      double h = (g_maxX2) / 2.0;
+      double dex = g_maxX1;
+      double Umax = (1.0 / (4.0*nuLB))*(dpLB / dex)*(h*h);
+      double Re = (4 * h*Umax) / (3 * nuLB);
+
+      //bc
+      BCAdapterPtr noSlipBCAdapter(new NoSlipBCAdapter());
+      noSlipBCAdapter->setBcAlgorithm(NoSlipBCAlgorithmPtr(new NoSlipBCAlgorithm()));
+
+      BCAdapterPtr denBCAdapterInflow(new DensityBCAdapter(rhoLBinflow));
+      denBCAdapterInflow->setBcAlgorithm(BCAlgorithmPtr(new NonEqDensityBCAlgorithm()));
+
+      BCAdapterPtr denBCAdapterOutflow(new DensityBCAdapter(rhoLB));
+      denBCAdapterOutflow->setBcAlgorithm(BCAlgorithmPtr(new NonEqDensityBCAlgorithm()));
+
+      //BS visitor
+      BoundaryConditionsBlockVisitor bcVisitor;
+      bcVisitor.addBC(noSlipBCAdapter);
+      bcVisitor.addBC(denBCAdapterInflow);
+      bcVisitor.addBC(denBCAdapterOutflow);
+
+      Grid3DPtr grid(new Grid3D(comm));
+      grid->setPeriodicX1(false);
+      grid->setPeriodicX2(false);
+      grid->setPeriodicX3(true);
+      grid->setDeltaX(deltax);
+      grid->setBlockNX(blocknx[0], blocknx[1], blocknx[2]);
+
+      GbObject3DPtr gridCube(new GbCuboid3D(g_minX1, g_minX2, g_minX3, g_maxX1, g_maxX2, g_maxX3));
+      if (myid == 0) GbSystem3D::writeGeoObject(gridCube.get(), pathname + "/geo/gridCube", WbWriterVtkXmlBinary::getInstance());
+
+      double k1 = 4;
+      double k2 = 8;
+
+      GbObject3DPtr refineCube1_1(new GbCuboid3D(g_minX1, g_minX2, g_minX3, g_maxX1, g_maxX2 / k1 - 1.0, g_maxX3));
+      if (myid == 0) GbSystem3D::writeGeoObject(refineCube1_1.get(), pathname + "/geo/refineCube1_1", WbWriterVtkXmlBinary::getInstance());
+
+      GbObject3DPtr refineCube1_2(new GbCuboid3D(g_minX1, g_maxX2 - g_maxX2 / k1 + 1.0, g_minX3, g_maxX1, g_maxX2, g_maxX3));
+      if (myid == 0) GbSystem3D::writeGeoObject(refineCube1_2.get(), pathname + "/geo/refineCube1_2", WbWriterVtkXmlBinary::getInstance());
+
+      GbObject3DPtr refineCube2_1(new GbCuboid3D(g_minX1 + 2 * blockLength + 2 * deltax, g_minX2, g_minX3, g_maxX1 - 2 * blockLength - 2 * deltax, g_maxX2 / k2 - 1.0, g_maxX3));
+      if (myid == 0) GbSystem3D::writeGeoObject(refineCube2_1.get(), pathname + "/geo/refineCube2_1", WbWriterVtkXmlBinary::getInstance());
+
+      GbObject3DPtr refineCube2_2(new GbCuboid3D(g_minX1 + 2 * blockLength + 2 * deltax, g_maxX2 - g_maxX2 / k2 + 1.0, g_minX3, g_maxX1 - 2 * blockLength - 2 * deltax, g_maxX2, g_maxX3));
+      if (myid == 0) GbSystem3D::writeGeoObject(refineCube2_2.get(), pathname + "/geo/refineCube2_2", WbWriterVtkXmlBinary::getInstance());
+
+      GbObject3DPtr refineCube2_3(new GbCuboid3D(g_minX1 + blockLength + 2 * deltax, g_minX2 + blockLength + 2 * deltax, g_minX3 + blockLength + 2 * deltax, g_maxX1 - blockLength - 2 * deltax, g_maxX2 - blockLength - 2 * deltax, g_maxX3 - blockLength - 2 * deltax));
+      if (myid == 0) GbSystem3D::writeGeoObject(refineCube2_3.get(), pathname + "/geo/refineCube2_3", WbWriterVtkXmlBinary::getInstance());
+
+      GbObject3DPtr refineCube3(new GbCuboid3D(g_minX1 + 2.0*(g_maxX1/3.0), g_minX2, g_minX3, g_maxX1, g_maxX2, g_maxX3));
+      if (myid == 0) GbSystem3D::writeGeoObject(refineCube3.get(), pathname + "/geo/refineCube3", WbWriterVtkXmlBinary::getInstance());
+
+      //////////////////////////////////////////////////////////////////////////
+      //restart
+      UbSchedulerPtr rSch(new UbScheduler(restartStep));
+      RestartCoProcessor rp(grid, rSch, comm, pathname, RestartCoProcessor::TXT);
+      //////////////////////////////////////////////////////////////////////////
+
+      if (grid->getTimeStep() == 0)
+      {
+         GenBlocksGridVisitor genBlocks(gridCube);
+         grid->accept(genBlocks);
+
+         if (myid == 0)
+         {
+            UBLOG(logINFO, "Parameters:");
+            UBLOG(logINFO, "h = " << h);
+            UBLOG(logINFO, "rho = " << rhoLB);
+            UBLOG(logINFO, "nue = " << nuLB);
+            UBLOG(logINFO, "Re = " << Re);
+            UBLOG(logINFO, "dx = " << deltax);
+            UBLOG(logINFO, "dpLB = " << dpLB);
+            UBLOG(logINFO, "Umax = " << Umax);
+            UBLOG(logINFO, "number of levels = " << refineLevel + 1);
+            UBLOG(logINFO, "numOfThreads = " << numOfThreads);
+            UBLOG(logINFO, "path = " << pathname);
+            UBLOG(logINFO, "Preprozess - start");
+         }
+
+         //walls
+         GbCuboid3DPtr addWallYmin (new GbCuboid3D(g_minX1-4.0*blockLength, g_minX2-4.0*blockLength, g_minX3-4.0*blockLength, g_maxX1+4.0*blockLength, g_minX2, g_maxX3+4.0*blockLength));
+         if(myid == 0) GbSystem3D::writeGeoObject(addWallYmin.get(), pathname+"/geo/addWallYmin", WbWriterVtkXmlASCII::getInstance());
+
+         GbCuboid3DPtr addWallYmax (new GbCuboid3D(g_minX1-4.0*blockLength, g_maxX2, g_minX3-4.0*blockLength, g_maxX1+4.0*blockLength, g_maxX2+4.0*blockLength, g_maxX3+4.0*blockLength));
+         if(myid == 0) GbSystem3D::writeGeoObject(addWallYmax.get(), pathname+"/geo/addWallYmax", WbWriterVtkXmlASCII::getInstance());
+
+         //inflow
+         GbCuboid3DPtr geoInflow(new GbCuboid3D(g_minX1 - 4.0*blockLength, g_minX2 - 4.0*blockLength, g_minX3 - 4.0*blockLength, g_minX1, g_maxX2 + 4.0*blockLength, g_maxX3 + 4.0*blockLength));
+         if (myid == 0) GbSystem3D::writeGeoObject(geoInflow.get(), pathname + "/geo/geoInflow", WbWriterVtkXmlASCII::getInstance());
+
+         //outflow
+         GbCuboid3DPtr geoOutflow(new GbCuboid3D(g_maxX1, g_minX2 - 4.0*blockLength, g_minX3 - 4.0*blockLength, g_maxX1 + 4.0*blockLength, g_maxX2 + 4.0*blockLength, g_maxX3 + 4.0*blockLength));
+         if (myid == 0) GbSystem3D::writeGeoObject(geoOutflow.get(), pathname + "/geo/geoOutflow", WbWriterVtkXmlASCII::getInstance());
+
+         ////inflow
+         //GbCuboid3DPtr geoInflow (new GbCuboid3D(g_minX1-4.0*blockLength, g_minX2-4.0*blockLength, g_minX3-4.0*blockLength, g_maxX1+4.0*blockLength, g_maxX2+4.0*blockLength, g_minX3));
+         //if(myid == 0) GbSystem3D::writeGeoObject(geoInflow.get(), pathname+"/geo/geoInflow", WbWriterVtkXmlASCII::getInstance());
+
+         ////outflow
+         //GbCuboid3DPtr geoOutflow (new GbCuboid3D(g_minX1-4.0*blockLength, g_minX2-4.0*blockLength, g_maxX3, g_maxX1+4.0*blockLength, g_maxX2+4.0*blockLength, g_maxX3+4.0*blockLength));
+         //if(myid == 0) GbSystem3D::writeGeoObject(geoOutflow.get(), pathname+"/geo/geoOutflow", WbWriterVtkXmlASCII::getInstance());
+
+         WriteBlocksCoProcessorPtr ppblocks(new WriteBlocksCoProcessor(grid, UbSchedulerPtr(new UbScheduler(1)), pathname, WbWriterVtkXmlBinary::getInstance(), comm));
+
+         if (refineLevel > 0)
+         {
+            if (myid == 0) UBLOG(logINFO, "Refinement - start");
+            RefineCrossAndInsideGbObjectHelper refineHelper(grid, refineLevel, comm);
+            //refineHelper.addGbObject(refineCube1_1, 1);
+            //refineHelper.addGbObject(refineCube1_2, 1);
+            //refineHelper.addGbObject(refineCube2_1, 2);
+            //refineHelper.addGbObject(refineCube2_2, 2);
+            //refineHelper.addGbObject(refineCube2_3, refineLevel);
+            refineHelper.addGbObject(refineCube3, refineLevel);
+            
+            refineHelper.refine();
+            if (myid == 0) UBLOG(logINFO, "Refinement - end");
+         }
+
+         //walls
+         D3Q27InteractorPtr addWallYminInt(new D3Q27Interactor(addWallYmin, grid, noSlipBCAdapter,Interactor3D::SOLID));
+         D3Q27InteractorPtr addWallYmaxInt(new D3Q27Interactor(addWallYmax, grid, noSlipBCAdapter,Interactor3D::SOLID));
+
+         D3Q27InteractorPtr inflowInt = D3Q27InteractorPtr(new D3Q27Interactor(geoInflow, grid, denBCAdapterInflow, Interactor3D::SOLID));
+
+         //outflow
+         D3Q27InteractorPtr outflowInt = D3Q27InteractorPtr(new D3Q27Interactor(geoOutflow, grid, denBCAdapterOutflow, Interactor3D::SOLID));
+
+         ////////////////////////////////////////////
+         //METIS
+         Grid3DVisitorPtr metisVisitor(new MetisPartitioningGridVisitor(comm, MetisPartitioningGridVisitor::LevelBased, D3Q27System::B));
+         ////////////////////////////////////////////
+         /////delete solid blocks
+         if (myid == 0) UBLOG(logINFO, "deleteSolidBlocks - start");
+         InteractorsHelper intHelper(grid, metisVisitor);
+         intHelper.addInteractor(addWallYminInt);
+         intHelper.addInteractor(addWallYmaxInt);
+         intHelper.addInteractor(inflowInt);
+         intHelper.addInteractor(outflowInt);
+         intHelper.selectBlocks();
+         if (myid == 0) UBLOG(logINFO, "deleteSolidBlocks - end");
+         //////////////////////////////////////
+
+         //set connectors
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
+         grid->accept(setConnsVisitor);
+
+         //domain decomposition for threads
+         PQueuePartitioningGridVisitor pqPartVisitor(numOfThreads);
+         grid->accept(pqPartVisitor);
+
+         ppblocks->process(0);
+         ppblocks.reset();
+
+         unsigned long nob = grid->getNumberOfBlocks();
+         int gl = 3;
+         unsigned long nodb = (blocknx[0]) * (blocknx[1]) * (blocknx[2]);
+         unsigned long nod = nob * (blocknx[0]) * (blocknx[1]) * (blocknx[2]);
+         unsigned long nodg = nob * (blocknx[0] + gl) * (blocknx[1] + gl) * (blocknx[1] + gl);
+         double needMemAll = double(nodg*(27 * sizeof(double) + sizeof(int) + sizeof(float) * 4));
+         double needMem = needMemAll / double(comm->getNumberOfProcesses());
+
+         if (myid == 0)
+         {
+            UBLOG(logINFO, "Number of blocks = " << nob);
+            UBLOG(logINFO, "Number of nodes  = " << nod);
+            int minInitLevel = grid->getCoarsestInitializedLevel();
+            int maxInitLevel = grid->getFinestInitializedLevel();
+            for (int level = minInitLevel; level <= maxInitLevel; level++)
+            {
+               int nobl = grid->getNumberOfBlocks(level);
+               UBLOG(logINFO, "Number of blocks for level " << level << " = " << nobl);
+               UBLOG(logINFO, "Number of nodes for level " << level << " = " << nobl*nodb);
+            }
+            UBLOG(logINFO, "Necessary memory  = " << needMemAll << " bytes");
+            UBLOG(logINFO, "Necessary memory per process = " << needMem << " bytes");
+            UBLOG(logINFO, "Available memory per process = " << availMem << " bytes");
+         }
+
+         int kernelType = 2;
+         LBMKernelPtr kernel;
+         kernel = LBMKernelPtr(new IncompressibleCumulantLBMKernel(blocknx[0], blocknx[1], blocknx[2], IncompressibleCumulantLBMKernel::NORMAL));
+         //}
+
+         BCProcessorPtr bcProc(new BCProcessor());
+         kernel->setBCProcessor(bcProc);
+
+         SetKernelBlockVisitor kernelVisitor(kernel, nuLB, availMem, needMem);
+         grid->accept(kernelVisitor);
+
+         if (refineLevel > 0)
+         {
+            SetUndefinedNodesBlockVisitor undefNodesVisitor;
+            grid->accept(undefNodesVisitor);
+         }
+
+         //walls
+         intHelper.setBC();
+
+         grid->accept(bcVisitor);
+
+         //initialization of distributions
+         mu::Parser fct;
+         fct.SetExpr("-(1.0/(2.0*nu))*(dp/dx)*((x2-h)^2 - h^2)");
+         fct.DefineConst("dp", dpLB);
+         fct.DefineConst("dx", dex);
+         fct.DefineConst("h", h);
+         fct.DefineConst("nu", nuLB);
+
+         InitDistributionsBlockVisitor initVisitor(nuLB, rhoLB);
+         //initVisitor.setVx1(fct);
+         initVisitor.setVx1(0.0);
+         //initVisitor.setVx3(fct);
+         grid->accept(initVisitor);
+
+         //Postrozess
+         UbSchedulerPtr geoSch(new UbScheduler(1));
+         WriteBoundaryConditionsCoProcessorPtr ppgeo(
+            new WriteBoundaryConditionsCoProcessor(grid, geoSch, pathname, WbWriterVtkXmlBinary::getInstance(), conv, comm));
+         ppgeo->process(0);
+         ppgeo.reset();
+
+         if (myid == 0) UBLOG(logINFO, "Preprozess - end");
+      }
+      else
+      {
+         grid->accept(bcVisitor);
+
+         //set connectors
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
+         grid->accept(setConnsVisitor);
+
+         if (myid == 0) UBLOG(logINFO, "Restart - end");
+      }
+      UbSchedulerPtr nupsSch(new UbScheduler(10, 30, 100));
+      NUPSCounterCoProcessor npr(grid, nupsSch, numOfThreads, comm);
+
+      UbSchedulerPtr stepSch(new UbScheduler(outTime));
+
+      WriteMacroscopicQuantitiesCoProcessor pp(grid, stepSch, pathname, WbWriterVtkXmlBinary::getInstance(), conv, comm);
+
+
+
+      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, stepSch));
+      if (myid == 0) UBLOG(logINFO, "Simulation-start");
+      calculation->calculate();
+      if (myid == 0) UBLOG(logINFO, "Simulation-end");
+   }
+   catch (std::exception& e)
+   {
+      cerr << e.what() << endl << flush;
+   }
+   catch (std::string& s)
+   {
+      cerr << s << endl;
+   }
+   catch (...)
+   {
+      cerr << "unknown exception" << endl;
+   }
+
+}
+//////////////////////////////////////////////////////////////////////////
+int main(int argc, char* argv[])
+{
+   if (argv != NULL)
+   {
+      if (argv[1] != NULL)
+      {
+         //pflowForcing(string(argv[1]));
+         pflowdp(string(argv[1]));
+      }
+      else
+      {
+         cout << "Configuration file is missing!" << endl;
+      }
+   }
+
+   return 0;
+}
diff --git a/source/Applications/LaminarTubeFlow/ltf.cfg b/source/Applications/LaminarTubeFlow/ltf.cfg
index 8e4777dd0..27aadee92 100644
--- a/source/Applications/LaminarTubeFlow/ltf.cfg
+++ b/source/Applications/LaminarTubeFlow/ltf.cfg
@@ -1,21 +1,26 @@
-pathname = d:/temp/LaminarTubeFlow2
-numOfThreads = 1
+pathname = d:/temp/LaminarTubeFlow_non_ref_inc
+numOfThreads = 4
 availMem = 10e9
 
 #Grid
-length = 84 6 26
-blocknx = 21 6 13
+length = 64 32 32
+#length = 21 6 13
+blocknx = 8 8 8
 dx = 1
 refineLevel = 0
 
 #Simulation
-uLB = 0.001
+uLB = 0.05
 Re = 10
 
 
-outTime = 100
-endTime = 10000
-
 logToFile = false
 
-restartStep = 10000
\ No newline at end of file
+newStart = true
+restartStep = 100000
+
+cpStart = 100000
+cpStep = 100000
+
+outTime = 1
+endTime = 10000000
\ No newline at end of file
diff --git a/source/Applications/LaminarTubeFlow/ltf.cpp b/source/Applications/LaminarTubeFlow/ltf.cpp
index cc817f2df..5f8675b75 100644
--- a/source/Applications/LaminarTubeFlow/ltf.cpp
+++ b/source/Applications/LaminarTubeFlow/ltf.cpp
@@ -26,6 +26,9 @@ void run(string configname)
       vector<double>  length = config.getVector<double>("length");
       bool            logToFile = config.getBool("logToFile");
       double          restartStep = config.getDouble("restartStep");
+      double          cpStart = config.getValue<double>("cpStart");
+      double          cpStep = config.getValue<double>("cpStep");
+      bool            newStart = config.getValue<bool>("newStart");
 
       CommunicatorPtr comm = MPICommunicator::getInstance();
       int myid = comm->getProcessID();
@@ -48,6 +51,8 @@ void run(string configname)
          }
       }
 
+      //Sleep(30000);
+
       LBMReal dLB = length[1] / dx;
       LBMReal rhoLB = 0.0;
       LBMReal nuLB = (uLB*dLB) / Re;
@@ -66,13 +71,13 @@ void run(string configname)
       noSlipBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new NoSlipBCAlgorithm()));
 
       BCAdapterPtr denBCAdapter(new DensityBCAdapter(rhoLB));
-      denBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new NonReflectingDensityBCAlgorithm()));
+      denBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new NonReflectingOutflowBCAlgorithm()));
 
-      mu::Parser fct;
-      fct.SetExpr("U");
-      fct.DefineConst("U", uLB);
-      BCAdapterPtr velBCAdapter(new VelocityBCAdapter(true, false, false, fct, 0, BCFunction::INFCONST));
-      velBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new NonReflectingVelocityBCAlgorithm()));
+      //mu::Parser fct;
+      //fct.SetExpr("U");
+      //fct.DefineConst("U", uLB);
+      //BCAdapterPtr velBCAdapter(new VelocityBCAdapter(true, false, false, fct, 0, BCFunction::INFCONST));
+      //velBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new NonReflectingVelocityBCAlgorithm()));
 
 
       //////////////////////////////////////////////////////////////////////////////////
@@ -80,17 +85,18 @@ void run(string configname)
       BoundaryConditionsBlockVisitor bcVisitor;
       bcVisitor.addBC(noSlipBCAdapter);
       bcVisitor.addBC(denBCAdapter);
-      bcVisitor.addBC(velBCAdapter);
+      //bcVisitor.addBC(velBCAdapter);
       
       Grid3DPtr grid(new Grid3D(comm));
       
       //////////////////////////////////////////////////////////////////////////
       //restart
-      UbSchedulerPtr rSch(new UbScheduler(restartStep, restartStep));
-      RestartCoProcessor rp(grid, rSch, comm, pathname, RestartCoProcessor::TXT);
+      UbSchedulerPtr rSch(new UbScheduler(cpStep, cpStart));
+      //RestartCoProcessor rp(grid, rSch, comm, pathname, RestartCoProcessor::TXT);
+      MPIIORestartCoProcessor rcp(grid, rSch, pathname, comm);
       //////////////////////////////////////////////////////////////////////////
 
-      if (grid->getTimeStep() == 0)
+      if (newStart)
       {
 
          //bounding box
@@ -132,7 +138,7 @@ void run(string configname)
 
          grid->setPeriodicX1(false);
          grid->setPeriodicX2(true);
-         grid->setPeriodicX3(true);
+         grid->setPeriodicX3(false);
 
          if (myid == 0) GbSystem3D::writeGeoObject(gridCube.get(), pathname + "/geo/gridCube", WbWriterVtkXmlBinary::getInstance());
 
@@ -166,19 +172,19 @@ void run(string configname)
          double cx2 = cylinder->getX2Centroid();
          double cx3 = cylinder->getX3Centroid();
 
-         //mu::Parser fct;
-         //fct.SetExpr("vx1*(1-((x2-y0)^2+(x3-z0)^2)/(R^2))");
-         //fct.DefineConst("x2Vmax", 0.0); //x2-Pos fuer vmax
-         //fct.DefineConst("x3Vmax", 0.0); //x3-Pos fuer vmax
-         //fct.DefineConst("R", r);
-         //fct.DefineConst("vx1", uLB);
-         //fct.DefineConst("x0", cx1);
-         //fct.DefineConst("y0", cx2);
-         //fct.DefineConst("z0", cx3);
-         //fct.DefineConst("nue", nuLB);
-         //BCAdapterPtr velBCAdapter(new VelocityBCAdapter(true, false, false, fct, 0, BCFunction::INFCONST));
-         ////velBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new VelocityBCAlgorithm()));
-         //velBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new NonReflectingVelocityBCAlgorithm()));
+         mu::Parser fct;
+         fct.SetExpr("vx1*(1-((x2-y0)^2+(x3-z0)^2)/(R^2))");
+         fct.DefineConst("x2Vmax", 0.0); //x2-Pos fuer vmax
+         fct.DefineConst("x3Vmax", 0.0); //x3-Pos fuer vmax
+         fct.DefineConst("R", r);
+         fct.DefineConst("vx1", uLB);
+         fct.DefineConst("x0", cx1);
+         fct.DefineConst("y0", cx2);
+         fct.DefineConst("z0", cx3);
+         fct.DefineConst("nue", nuLB);
+         BCAdapterPtr velBCAdapter(new VelocityBCAdapter(true, false, false, fct, 0, BCFunction::INFCONST));
+         //velBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new VelocityBCAlgorithm()));
+         velBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new VelocityWithDensityBCAlgorithm()));
 
 
          D3Q27InteractorPtr inflowInt = D3Q27InteractorPtr(new D3Q27Interactor(geoInflow, grid, velBCAdapter, Interactor3D::SOLID));
@@ -189,7 +195,7 @@ void run(string configname)
 
          Grid3DVisitorPtr metisVisitor(new MetisPartitioningGridVisitor(comm, MetisPartitioningGridVisitor::LevelBased, D3Q27System::B));
          InteractorsHelper intHelper(grid, metisVisitor);
-         //intHelper.addInteractor(cylinderInt);
+         intHelper.addInteractor(cylinderInt);
          intHelper.addInteractor(inflowInt);
          intHelper.addInteractor(outflowInt);
          intHelper.selectBlocks();
@@ -225,8 +231,8 @@ void run(string configname)
 
          LBMKernelPtr kernel;
 
-         //kernel = LBMKernelPtr(new IncompressibleCumulantLBMKernel(blocknx[0], blocknx[1], blocknx[2], IncompressibleCumulantLBMKernel::NORMAL));
-         kernel = LBMKernelPtr(new CompressibleCumulantLBMKernel(blocknx[0], blocknx[1], blocknx[2], CompressibleCumulantLBMKernel::NORMAL));
+         kernel = LBMKernelPtr(new IncompressibleCumulantLBMKernel(blocknx[0], blocknx[1], blocknx[2], IncompressibleCumulantLBMKernel::NORMAL));
+         //kernel = LBMKernelPtr(new CompressibleCumulantLBMKernel(blocknx[0], blocknx[1], blocknx[2], CompressibleCumulantLBMKernel::NORMAL));
 
          //
          BCProcessorPtr bcProc(new BCProcessor());
@@ -245,18 +251,18 @@ void run(string configname)
 
          intHelper.setBC();
 
-         //bcVisitor.addBC(velBCAdapter);
+         bcVisitor.addBC(velBCAdapter);
          grid->accept(bcVisitor);
 
          //initialization of distributions
          InitDistributionsBlockVisitor initVisitor(nuLB, rhoLB);
-         initVisitor.setVx1(fct);
+         //initVisitor.setVx1(fct);
          //initVisitor.setVx1(uLB);
          grid->accept(initVisitor);
 
          //set connectors
-         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
-         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          //ConnectorFactoryPtr factory(new Block3DConnectorFactory());
          //ConnectorBlockVisitor setConnsVisitor(comm, nuLB, iProcessor, factory);
@@ -292,8 +298,12 @@ void run(string configname)
             UBLOG(logINFO, "path = " << pathname);
          }
 
+         rcp.restart((int)restartStep);
+         grid->setTimeStep(restartStep);
+
          BCAdapterPtr velBCAdapter(new VelocityBCAdapter());
-         velBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new VelocityBCAlgorithm()));
+         //velBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new VelocityBCAlgorithm()));
+         velBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new VelocityWithDensityBCAlgorithm()));
          bcVisitor.addBC(velBCAdapter);
          grid->accept(bcVisitor);
 
@@ -311,7 +321,7 @@ void run(string configname)
       UbSchedulerPtr nupsSch(new UbScheduler(10, 30, 100));
       NUPSCounterCoProcessor npr(grid, nupsSch, numOfThreads, comm);
 
-      //CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, visSch,CalculationManager::PrePostBc));
+      //CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, visSch,CalculationManager::MPI));
       CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, visSch));
       if (myid == 0) UBLOG(logINFO, "Simulation-start");
       calculation->calculate();
diff --git a/source/Applications/levels/CMakeLists.txt b/source/Applications/levels/CMakeLists.txt
new file mode 100644
index 000000000..726654984
--- /dev/null
+++ b/source/Applications/levels/CMakeLists.txt
@@ -0,0 +1,25 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+
+########################################################
+## C++ PROJECT                                       ###
+########################################################
+PROJECT(levels)
+
+INCLUDE(${SOURCE_ROOT}/IncludsList.cmake) 
+
+#################################################################
+###   LOCAL FILES                                             ###
+#################################################################
+FILE(GLOB SPECIFIC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.h
+                         ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
+                         ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp  )
+ 
+SET(ALL_SOURCES ${ALL_SOURCES} ${SPECIFIC_FILES})
+SOURCE_GROUP(src FILES ${SPECIFIC_FILES})
+  
+SET(CAB_ADDITIONAL_LINK_LIBRARIES VirtualFluids)
+
+#################################################################
+###   CREATE PROJECT                                          ###
+#################################################################
+CREATE_CAB_PROJECT(levels BINARY)
diff --git a/source/Applications/levels/config.txt b/source/Applications/levels/config.txt
new file mode 100644
index 000000000..f905aba06
--- /dev/null
+++ b/source/Applications/levels/config.txt
@@ -0,0 +1,22 @@
+#Ordner für Simulationsergebnisse
+path=d:/temp/levels
+
+#Verfügbare Arbeitsspeicher in Byte
+memory=5e9
+
+#Ausgabezeitschritt
+outstep=100
+
+#maximale Anzahl Simulationszeitschritte
+endstep=100
+
+#Anzahl von Threads
+threads=4
+
+#max refierment level (1 - 5)
+level=3
+
+blockNx = 8 8 8
+dim = 160 8 160
+
+radius = 1.5
\ No newline at end of file
diff --git a/source/Applications/levels/levels.cpp b/source/Applications/levels/levels.cpp
new file mode 100644
index 000000000..cb890a2ca
--- /dev/null
+++ b/source/Applications/levels/levels.cpp
@@ -0,0 +1,350 @@
+#include <VirtualFluids.h>
+#include <set>
+#include <map>
+using namespace std;
+
+
+////////////////////////////////////////////////////////////////////////
+void run(string configname)
+{
+   try
+   {
+
+      //Sleep(30000);
+
+      string machine = QUOTEME(CAB_MACHINE);
+
+      CommunicatorPtr comm = MPICommunicator::getInstance();
+
+      int myid = comm->getProcessID();
+      int mybundle = comm->getBundleID();
+      int root = comm->getRoot();
+
+      ConfigurationFile   config;
+      config.load(configname);
+
+      string pathname = config.getValue<string>("path");
+      double availMem = config.getValue<double>("memory");
+      double outstep = config.getValue<double>("outstep");
+      double endstep = config.getValue<double>("endstep");
+      int numOfThreads = config.getValue<int>("threads");
+      int refineLevel = config.getValue<int>("level");
+      vector<double> dim = config.getVector<double>("dim");
+      vector<int> blockNx = config.getVector<int>("blockNx");
+      double radius = config.getValue<double>("radius");
+
+      //LBMReal radius = 4;
+      LBMReal uLB = 0.1;
+      LBMReal Re = 1;
+      LBMReal rhoLB = 0.0;
+      //LBMReal nuLB = (uLB*2.0*radius)/Re;
+      //LBMReal nuLB = (uLB*L2)/Re;
+      LBMReal nuLB = 0.168666666667/100;
+
+      double dp_LB = 1e-6;
+      double rhoLBinflow = dp_LB*3.0;
+
+      BCAdapterPtr noSlipBCAdapter(new NoSlipBCAdapter());
+      noSlipBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new NoSlipBCAlgorithm()));
+
+      mu::Parser fct;
+      fct.SetExpr("U");
+      fct.DefineConst("U", uLB);
+      BCAdapterPtr velBCAdapter(new VelocityBCAdapter(true, false, false, fct, 0, BCFunction::INFCONST));
+      velBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new VelocityBCAlgorithm()));
+
+      BCAdapterPtr denBCAdapter(new DensityBCAdapter(rhoLB));
+      denBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new NonEqDensityBCAlgorithm()));
+
+      BoundaryConditionsBlockVisitor bcVisitor;
+      bcVisitor.addBC(noSlipBCAdapter);
+      bcVisitor.addBC(velBCAdapter);
+      bcVisitor.addBC(denBCAdapter);
+
+      LBMUnitConverterPtr conv = LBMUnitConverterPtr(new LBMUnitConverter());
+
+      double dx = 1;
+
+      const int blocknx1 = blockNx[0];
+      const int blocknx2 = blockNx[1];
+      const int blocknx3 = blockNx[2];
+
+      Grid3DPtr grid(new Grid3D(comm));
+      grid->setDeltaX(dx);
+      grid->setBlockNX(blocknx1, blocknx2, blocknx3);
+
+      //////////////////////////////////////////////////////////////////////////
+      //restart
+      UbSchedulerPtr restartSch(new UbScheduler(100000, 100000, 100000));
+      RestartCoProcessor rp(grid, restartSch, comm, pathname, RestartCoProcessor::BINARY);
+      //////////////////////////////////////////////////////////////////////////
+
+      if (grid->getTimeStep()==0)
+      {
+
+         const int baseLevel = 0;
+
+         //bounding box
+         double d_minX1 = 0.0;
+         double d_minX2 = 0.0;
+         double d_minX3 = 0.0;
+
+         double d_maxX1 = dim[0];
+         double d_maxX2 = dim[1];
+         double d_maxX3 = dim[2];
+
+         double blockLength = blocknx1*dx;
+
+         if (myid==0)
+         {
+            UBLOG(logINFO, "Parameters:");
+            UBLOG(logINFO, "uLB = "<<uLB);
+            UBLOG(logINFO, "rhoLB = "<<rhoLB);
+            UBLOG(logINFO, "nueLB = "<<nuLB);
+            UBLOG(logINFO, "Re = "<<Re);
+            UBLOG(logINFO, "dx = "<<dx);
+            UBLOG(logINFO, "number of levels = "<<refineLevel+1);
+            UBLOG(logINFO, "numOfThreads = "<<numOfThreads);
+            UBLOG(logINFO, "Preprozess - start");
+         }
+
+         GbObject3DPtr gridCube(new GbCuboid3D(d_minX1, d_minX2, d_minX3, d_maxX1, d_maxX2, d_maxX3));
+         if (myid==0) GbSystem3D::writeGeoObject(gridCube.get(), pathname+"/geo/gridCube", WbWriterVtkXmlBinary::getInstance());
+
+         GenBlocksGridVisitor genBlocks(gridCube);
+         grid->accept(genBlocks);
+
+         //CoordinateTransformation3DPtr trafo = grid->getCoordinateTransformator();
+         //trafo->setRotationX2Angle(4);
+
+         //sphere
+         //GbObject3DPtr sphereRef(new GbSphere3D(L1/4.0, L2*0.5, L3*0.5, radius+1.0));
+         //GbSystem3D::writeGeoObject(sphereRef.get(),pathname + "/geo/sphereRef", WbWriterVtkXmlBinary::getInstance());
+
+
+         //sphere
+         GbObject3DPtr sphere(new GbSphere3D(d_maxX1*0.5, d_maxX2*0.5, d_maxX3*0.5, radius));
+         //GbObject3DPtr sphere(new GbSphere3D(L1/2.0-4.0, L2*0.5+4.0, L3*0.5+4.0, radius));
+         //GbObject3DPtr sphere(new GbCuboid3D(L1/4.0-radius, L2/2.0-radius, L3/2.0-radius, L1/4.0+radius, L2/2.0+radius, L3/2.0+radius));
+         GbSystem3D::writeGeoObject(sphere.get(), pathname+"/geo/sphere", WbWriterVtkXmlBinary::getInstance());
+
+         double off = 0.0;
+         GbObject3DPtr refCube(new GbCuboid3D(sphere->getX1Minimum()-off, sphere->getX2Minimum()-off, sphere->getX3Minimum(),
+            sphere->getX1Maximum()+off, sphere->getX2Maximum()+off, sphere->getX3Maximum()));
+         if (myid==0) GbSystem3D::writeGeoObject(refCube.get(), pathname+"/geo/refCube", WbWriterVtkXmlBinary::getInstance());
+
+         if (refineLevel>0)
+         {
+            if (myid==0) UBLOG(logINFO, "Refinement - start");
+            RefineCrossAndInsideGbObjectHelper refineHelper(grid, refineLevel, comm);
+            //refineHelper.addGbObject(sphere, refineLevel);
+            refineHelper.addGbObject(refCube, refineLevel);
+            refineHelper.refine();
+            if (myid==0) UBLOG(logINFO, "Refinement - end");
+         }
+
+         //walls
+         GbCuboid3DPtr addWallYmin(new GbCuboid3D(d_minX1-4.0*blockLength, d_minX2-4.0*blockLength, d_minX3-4.0*blockLength, d_maxX1+4.0*blockLength, d_minX2, d_maxX3+4.0*blockLength));
+         if (myid==0) GbSystem3D::writeGeoObject(addWallYmin.get(), pathname+"/geo/addWallYmin", WbWriterVtkXmlASCII::getInstance());
+
+         GbCuboid3DPtr addWallZmin(new GbCuboid3D(d_minX1-4.0*blockLength, d_minX2-4.0*blockLength, d_minX3-4.0*blockLength, d_maxX1+4.0*blockLength, d_maxX2+4.0*blockLength, d_minX3));
+         if (myid==0) GbSystem3D::writeGeoObject(addWallZmin.get(), pathname+"/geo/addWallZmin", WbWriterVtkXmlASCII::getInstance());
+
+         GbCuboid3DPtr addWallYmax(new GbCuboid3D(d_minX1-4.0*blockLength, d_maxX2, d_minX3-4.0*blockLength, d_maxX1+4.0*blockLength, d_maxX2+4.0*blockLength, d_maxX3+4.0*blockLength));
+         if (myid==0) GbSystem3D::writeGeoObject(addWallYmax.get(), pathname+"/geo/addWallYmax", WbWriterVtkXmlASCII::getInstance());
+
+         GbCuboid3DPtr addWallZmax(new GbCuboid3D(d_minX1-4.0*blockLength, d_minX2-4.0*blockLength, d_maxX3, d_maxX1+4.0*blockLength, d_maxX2+4.0*blockLength, d_maxX3+4.0*blockLength));
+         if (myid==0) GbSystem3D::writeGeoObject(addWallZmax.get(), pathname+"/geo/addWallZmax", WbWriterVtkXmlASCII::getInstance());
+
+         //inflow
+         GbCuboid3DPtr geoInflow(new GbCuboid3D(d_minX1-4.0*blockLength, d_minX2-4.0*blockLength, d_minX3-4.0*blockLength, d_minX1, d_maxX2+4.0*blockLength, d_maxX3+4.0*blockLength));
+         if (myid==0) GbSystem3D::writeGeoObject(geoInflow.get(), pathname+"/geo/geoInflow", WbWriterVtkXmlASCII::getInstance());
+
+         //outflow
+         GbCuboid3DPtr geoOutflow(new GbCuboid3D(d_maxX1, d_minX2-4.0*blockLength, d_minX3-4.0*blockLength, d_maxX1+4.0*blockLength, d_maxX2+4.0*blockLength, d_maxX3+4.0*blockLength));
+         if (myid==0) GbSystem3D::writeGeoObject(geoOutflow.get(), pathname+"/geo/geoOutflow", WbWriterVtkXmlASCII::getInstance());
+
+         WriteBlocksCoProcessorPtr ppblocks(new WriteBlocksCoProcessor(grid, UbSchedulerPtr(new UbScheduler(1)), pathname, WbWriterVtkXmlBinary::getInstance(), comm));
+
+
+
+         //sphere
+         D3Q27InteractorPtr sphereInt = D3Q27InteractorPtr(new D3Q27Interactor(sphere, grid, noSlipBCAdapter, Interactor3D::SOLID));
+
+         //walls
+         D3Q27InteractorPtr addWallYminInt(new D3Q27Interactor(addWallYmin, grid, noSlipBCAdapter, Interactor3D::SOLID));
+         D3Q27InteractorPtr addWallZminInt(new D3Q27Interactor(addWallZmin, grid, noSlipBCAdapter, Interactor3D::SOLID));
+         D3Q27InteractorPtr addWallYmaxInt(new D3Q27Interactor(addWallYmax, grid, noSlipBCAdapter, Interactor3D::SOLID));
+         D3Q27InteractorPtr addWallZmaxInt(new D3Q27Interactor(addWallZmax, grid, noSlipBCAdapter, Interactor3D::SOLID));
+
+         mu::Parser fct;
+         fct.SetExpr("U");
+         fct.DefineConst("U", uLB);
+
+         //inflow
+         D3Q27InteractorPtr inflowInt = D3Q27InteractorPtr(new D3Q27Interactor(geoInflow, grid, velBCAdapter, Interactor3D::SOLID));
+
+         //D3Q27BoundaryConditionAdapterPtr denBCAdapterInflow(new D3Q27DensityBCAdapter(rhoLBinflow));
+         //denBCAdapterInflow->setSecondaryBcOption(0);
+         //D3Q27InteractorPtr inflowInt = D3Q27InteractorPtr(new D3Q27Interactor(geoInflow, grid, denBCAdapterInflow, Interactor3D::SOLID));
+
+         //outflow
+         D3Q27InteractorPtr outflowInt = D3Q27InteractorPtr(new D3Q27Interactor(geoOutflow, grid, denBCAdapter, Interactor3D::SOLID));
+
+         Grid3DVisitorPtr metisVisitor(new MetisPartitioningGridVisitor(comm, MetisPartitioningGridVisitor::LevelBased, D3Q27System::B));
+         InteractorsHelper intHelper(grid, metisVisitor);
+         //intHelper.addInteractor(sphereInt);
+         intHelper.addInteractor(addWallYminInt);
+         intHelper.addInteractor(addWallZminInt);
+         intHelper.addInteractor(addWallYmaxInt);
+         intHelper.addInteractor(addWallZmaxInt);
+         intHelper.addInteractor(inflowInt);
+         intHelper.addInteractor(outflowInt);
+         intHelper.selectBlocks();
+
+         //domain decomposition for threads
+         PQueuePartitioningGridVisitor pqPartVisitor(numOfThreads);
+         grid->accept(pqPartVisitor);
+
+
+         //set connectors
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
+         grid->accept(setConnsVisitor);
+
+         //Block3DConnectorFactoryPtr factory(new Block3DConnectorFactory());
+         //ConnectorBlockVisitor setConnsVisitor(comm, nuLB, iProcessor, factory);
+         //grid->accept(setConnsVisitor);
+
+         ppblocks->process(0);
+         ppblocks.reset();
+
+         unsigned long long numberOfBlocks = (unsigned long long)grid->getNumberOfBlocks();
+         int ghostLayer = 3;
+         unsigned long long numberOfNodesPerBlock = (unsigned long long)(blockNx[0])* (unsigned long long)(blockNx[1])* (unsigned long long)(blockNx[2]);
+         unsigned long long numberOfNodes = numberOfBlocks * numberOfNodesPerBlock;
+         unsigned long long numberOfNodesPerBlockWithGhostLayer = numberOfBlocks * (blockNx[0]+ghostLayer) * (blockNx[1]+ghostLayer) * (blockNx[2]+ghostLayer);
+         double needMemAll = double(numberOfNodesPerBlockWithGhostLayer*(27*sizeof(double)+sizeof(int)+sizeof(float)*4));
+         double needMem = needMemAll/double(comm->getNumberOfProcesses());
+
+         if (myid==0)
+         {
+            UBLOG(logINFO, "Number of blocks = "<<numberOfBlocks);
+            UBLOG(logINFO, "Number of nodes  = "<<numberOfNodes);
+            int minInitLevel = grid->getCoarsestInitializedLevel();
+            int maxInitLevel = grid->getFinestInitializedLevel();
+            for (int level = minInitLevel; level<=maxInitLevel; level++)
+            {
+               int nobl = grid->getNumberOfBlocks(level);
+               UBLOG(logINFO, "Number of blocks for level "<<level<<" = "<<nobl);
+               UBLOG(logINFO, "Number of nodes for level "<<level<<" = "<<nobl*numberOfNodesPerBlock);
+            }
+            UBLOG(logINFO, "Necessary memory  = "<<needMemAll<<" bytes");
+            UBLOG(logINFO, "Necessary memory per process = "<<needMem<<" bytes");
+            UBLOG(logINFO, "Available memory per process = "<<availMem<<" bytes");
+         }
+
+         LBMKernelPtr kernel(new IncompressibleCumulantLBMKernel(blocknx1, blocknx2, blocknx3, IncompressibleCumulantLBMKernel::NORMAL));
+
+         BCProcessorPtr bcProcessor(new BCProcessor());
+
+
+         kernel->setBCProcessor(bcProcessor);
+
+         SetKernelBlockVisitor kernelVisitor(kernel, nuLB, availMem, needMem);
+         grid->accept(kernelVisitor);
+
+         if (refineLevel>0)
+         {
+            SetUndefinedNodesBlockVisitor undefNodesVisitor;
+            grid->accept(undefNodesVisitor);
+         }
+
+         intHelper.setBC();
+
+         grid->accept(bcVisitor);
+
+         mu::Parser fctRoh;
+         fctRoh.SetExpr("(x1max-x1)/l*dp*3.0");
+         fctRoh.DefineConst("dp", dp_LB);
+         fctRoh.DefineConst("x1max", d_maxX1);
+         fctRoh.DefineConst("l", d_maxX1-d_minX1);
+
+         //initialization of distributions
+         InitDistributionsBlockVisitor initVisitor(nuLB, rhoLB);
+         initVisitor.setVx1(fct);
+         //initVisitor.setRho(fctRoh);
+         grid->accept(initVisitor);
+
+         //Postrozess
+         UbSchedulerPtr geoSch(new UbScheduler(1));
+         WriteBoundaryConditionsCoProcessorPtr ppgeo(
+            new WriteBoundaryConditionsCoProcessor(grid, geoSch, pathname, WbWriterVtkXmlBinary::getInstance(), conv, comm));
+         ppgeo->process(0);
+         ppgeo.reset();;
+
+         if (myid==0) UBLOG(logINFO, "Preprozess - end");
+      }
+      else
+      {
+         UBLOG(logINFO, "SetConnectors - start, id="<<myid);
+
+         //set connectors
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         //D3Q27SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
+         ConnectorFactoryPtr cFactory(new Block3DConnectorFactory());
+         ConnectorBlockVisitor setConnsVisitor(comm, nuLB, iProcessor, cFactory);
+         grid->accept(setConnsVisitor);
+
+         UBLOG(logINFO, "SetConnectors - end, id="<<myid);
+      }
+
+      UbSchedulerPtr stepSch(new UbScheduler(outstep));
+      //stepSch->addSchedule(10000, 0, 1000000);
+      WriteMacroscopicQuantitiesCoProcessor pp(grid, stepSch, pathname, WbWriterVtkXmlBinary::getInstance(), conv, comm);
+
+      UbSchedulerPtr nupsSch(new UbScheduler(10, 30, 100));
+      NUPSCounterCoProcessor npr(grid, nupsSch, numOfThreads, comm);
+
+      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endstep, stepSch));
+
+      if (myid==0)
+         UBLOG(logINFO, "Simulation-start");
+
+      calculation->calculate();
+
+      if (myid==0)
+         UBLOG(logINFO, "Simulation-end");
+
+   }
+   catch (std::exception& e)
+   {
+      cerr<<e.what()<<endl<<flush;
+   }
+   catch (std::string& s)
+   {
+      cerr<<s<<endl;
+   }
+   catch (...)
+   {
+      cerr<<"unknown exception"<<endl;
+   }
+
+}
+
+//////////////////////////////////////////////////////////////////////////
+int main(int argc, char* argv[])
+{
+   if (argv!=NULL)
+   {
+      if (argv[1]!=NULL)
+      {
+         run(string(argv[1]));
+      }
+      else
+      {
+         cout<<"Configuration file is missing!"<<endl;
+      }
+   }
+}
+
diff --git a/source/Applications/sphere/config.txt b/source/Applications/sphere/config.txt
index c1e511c05..53bd75458 100644
--- a/source/Applications/sphere/config.txt
+++ b/source/Applications/sphere/config.txt
@@ -2,7 +2,7 @@
 path=d:/temp/sphere
 
 #Verfügbare Arbeitsspeicher in Byte
-memory=21e9
+memory=3e9
 
 #Pfad zum Metafile
 metafile=d:/Data/insituDemo/metafile.csv
@@ -17,6 +17,6 @@ endstep=100000
 threads=1
 
 #max refierment level (1 - 5)
-level=1
+level=4
 
 test = true
\ No newline at end of file
diff --git a/source/Applications/sphere/sphere.cpp b/source/Applications/sphere/sphere.cpp
index d610ad3d5..c4daf2166 100644
--- a/source/Applications/sphere/sphere.cpp
+++ b/source/Applications/sphere/sphere.cpp
@@ -47,6 +47,33 @@ void run(string configname)
 
       bool test = config.getValue<bool>("test");
 
+      LBMReal radius = 4;
+      LBMReal uLB = 0.1;
+      LBMReal Re = 1;
+      LBMReal rhoLB = 0.0;
+      //LBMReal nuLB = (uLB*2.0*radius)/Re;
+      //LBMReal nuLB = (uLB*L2)/Re;
+      LBMReal nuLB = 0.168666666667/100;
+
+      double dp_LB = 1e-6;
+      double rhoLBinflow = dp_LB*3.0;
+
+      BCAdapterPtr noSlipBCAdapter(new NoSlipBCAdapter());
+      noSlipBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new NoSlipBCAlgorithm()));
+      
+      mu::Parser fct;
+      fct.SetExpr("U");
+      fct.DefineConst("U", uLB);
+      BCAdapterPtr velBCAdapter(new VelocityBCAdapter(true, false, false, fct, 0, BCFunction::INFCONST));
+      velBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new VelocityBCAlgorithm()));
+
+      BCAdapterPtr denBCAdapter(new DensityBCAdapter(rhoLB));
+      denBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new NonEqDensityBCAlgorithm()));
+
+      BoundaryConditionsBlockVisitor bcVisitor;
+      bcVisitor.addBC(noSlipBCAdapter);
+      bcVisitor.addBC(velBCAdapter);
+      bcVisitor.addBC(denBCAdapter);
 
       LBMUnitConverterPtr conv = LBMUnitConverterPtr(new LBMUnitConverter());
 
@@ -73,16 +100,7 @@ void run(string configname)
       L2 = gridNx2*blocknx1;
       L3 = gridNx3*blocknx1;
 
-      LBMReal radius = 4;
-      LBMReal uLB = 0.1;
-      LBMReal Re = 1;
-      LBMReal rhoLB = 0.0;
-      //LBMReal nuLB = (uLB*2.0*radius)/Re;
-      //LBMReal nuLB = (uLB*L2)/Re;
-      LBMReal nuLB = 0.168666666667 / 100;
 
-      double dp_LB = 1e-6;
-      double rhoLBinflow = dp_LB*3.0;
 
       Grid3DPtr grid(new Grid3D(comm));
       grid->setDeltaX(dx);
@@ -181,21 +199,19 @@ void run(string configname)
 
 
          //sphere
-         D3Q27BoundaryConditionAdapterPtr bcNoSlip(new D3Q27NoSlipBCAdapter());
-         D3Q27InteractorPtr sphereInt = D3Q27InteractorPtr(new D3Q27Interactor(sphere, grid, bcNoSlip, Interactor3D::SOLID));
+         D3Q27InteractorPtr sphereInt = D3Q27InteractorPtr(new D3Q27Interactor(sphere, grid, noSlipBCAdapter, Interactor3D::SOLID));
 
          //walls
-         D3Q27InteractorPtr addWallYminInt(new D3Q27Interactor(addWallYmin, grid, bcNoSlip, Interactor3D::SOLID));
-         D3Q27InteractorPtr addWallZminInt(new D3Q27Interactor(addWallZmin, grid, bcNoSlip, Interactor3D::SOLID));
-         D3Q27InteractorPtr addWallYmaxInt(new D3Q27Interactor(addWallYmax, grid, bcNoSlip, Interactor3D::SOLID));
-         D3Q27InteractorPtr addWallZmaxInt(new D3Q27Interactor(addWallZmax, grid, bcNoSlip, Interactor3D::SOLID));
+         D3Q27InteractorPtr addWallYminInt(new D3Q27Interactor(addWallYmin, grid, noSlipBCAdapter, Interactor3D::SOLID));
+         D3Q27InteractorPtr addWallZminInt(new D3Q27Interactor(addWallZmin, grid, noSlipBCAdapter, Interactor3D::SOLID));
+         D3Q27InteractorPtr addWallYmaxInt(new D3Q27Interactor(addWallYmax, grid, noSlipBCAdapter, Interactor3D::SOLID));
+         D3Q27InteractorPtr addWallZmaxInt(new D3Q27Interactor(addWallZmax, grid, noSlipBCAdapter, Interactor3D::SOLID));
 
          mu::Parser fct;
          fct.SetExpr("U");
          fct.DefineConst("U", uLB);
 
          //inflow
-         D3Q27BoundaryConditionAdapterPtr velBCAdapter(new D3Q27VelocityBCAdapter(true, false, false, fct, 0, D3Q27BCFunction::INFCONST));
          D3Q27InteractorPtr inflowInt = D3Q27InteractorPtr(new D3Q27Interactor(geoInflow, grid, velBCAdapter, Interactor3D::SOLID));
 
          //D3Q27BoundaryConditionAdapterPtr denBCAdapterInflow(new D3Q27DensityBCAdapter(rhoLBinflow));
@@ -203,7 +219,6 @@ void run(string configname)
          //D3Q27InteractorPtr inflowInt = D3Q27InteractorPtr(new D3Q27Interactor(geoInflow, grid, denBCAdapterInflow, Interactor3D::SOLID));
 
          //outflow
-         D3Q27BoundaryConditionAdapterPtr denBCAdapter(new D3Q27DensityBCAdapter(rhoLB));
          D3Q27InteractorPtr outflowInt = D3Q27InteractorPtr(new D3Q27Interactor(geoOutflow, grid, denBCAdapter, Interactor3D::SOLID));
 
          Grid3DVisitorPtr metisVisitor(new MetisPartitioningGridVisitor(comm, MetisPartitioningGridVisitor::LevelBased, D3Q27System::B));
@@ -223,8 +238,8 @@ void run(string configname)
 
 
          //set connectors
-         D3Q27InterpolationProcessorPtr iProcessor(new D3Q27IncompressibleOffsetInterpolationProcessor());
-         D3Q27SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
          //Block3DConnectorFactoryPtr factory(new Block3DConnectorFactory());
@@ -250,20 +265,10 @@ void run(string configname)
             UBLOG(logINFO, "Available memory per process = " << availMem << " bytes");
          }
 
-         LBMKernel3DPtr kernel(new LBMKernelETD3Q27CCLB(blocknx1, blocknx2, blocknx3, LBMKernelETD3Q27CCLB::NORMAL));
-
-         BCProcessorPtr bcProcessor(new D3Q27ETBCProcessor());
-         BoundaryConditionPtr velocityBC(new VelocityBoundaryCondition());
-         BoundaryConditionPtr densityBC(new NonEqDensityBoundaryCondition());
-         BoundaryConditionPtr noSlipBC(new NoSlipBoundaryCondition());
+         LBMKernelPtr kernel(new IncompressibleCumulantLBMKernel(blocknx1, blocknx2, blocknx3, IncompressibleCumulantLBMKernel::NORMAL));
 
-         //BoundaryConditionPtr velocityBC(new NonReflectingVelocityBoundaryCondition());
-         //BoundaryConditionPtr densityBC(new NonReflectingDensityBoundaryCondition());
-         //BoundaryConditionPtr noSlipBC(new HighViscosityNoSlipBoundaryCondition());
+         BCProcessorPtr bcProcessor(new BCProcessor());
 
-         bcProcessor->addBC(velocityBC);
-         bcProcessor->addBC(densityBC);
-         bcProcessor->addBC(noSlipBC);
 
          kernel->setBCProcessor(bcProcessor);
 
@@ -272,13 +277,12 @@ void run(string configname)
 
          if (refineLevel > 0)
          {
-            D3Q27SetUndefinedNodesBlockVisitor undefNodesVisitor;
+            SetUndefinedNodesBlockVisitor undefNodesVisitor;
             grid->accept(undefNodesVisitor);
          }
 
          intHelper.setBC();
 
-         BoundaryConditionBlockVisitor bcVisitor;
          grid->accept(bcVisitor);
 
          mu::Parser fctRoh;
@@ -288,17 +292,17 @@ void run(string configname)
          fctRoh.DefineConst("l", d_maxX1 - d_minX1);
 
          //initialization of distributions
-         D3Q27ETInitDistributionsBlockVisitor initVisitor(nuLB, rhoLB);
+         InitDistributionsBlockVisitor initVisitor(nuLB, rhoLB);
          initVisitor.setVx1(fct);
          //initVisitor.setRho(fctRoh);
          grid->accept(initVisitor);
 
          //Postrozess
          UbSchedulerPtr geoSch(new UbScheduler(1));
-         MacroscopicQuantitiesCoProcessorPtr ppgeo(
-            new MacroscopicQuantitiesCoProcessor(grid, geoSch, pathname, WbWriterVtkXmlBinary::getInstance(), conv, true));
+         WriteBoundaryConditionsCoProcessorPtr ppgeo(
+            new WriteBoundaryConditionsCoProcessor(grid, geoSch, pathname, WbWriterVtkXmlBinary::getInstance(), conv, comm));
          ppgeo->process(0);
-         ppgeo.reset();
+         ppgeo.reset();;
 
          if (myid == 0) UBLOG(logINFO, "Preprozess - end");
       }
@@ -307,7 +311,7 @@ void run(string configname)
          UBLOG(logINFO, "SetConnectors - start, id=" << myid);
 
          //set connectors
-         D3Q27InterpolationProcessorPtr iProcessor(new D3Q27IncompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
          //D3Q27SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          ConnectorFactoryPtr cFactory(new Block3DConnectorFactory());
          ConnectorBlockVisitor setConnsVisitor(comm, nuLB, iProcessor, cFactory);
@@ -318,16 +322,11 @@ void run(string configname)
 
       UbSchedulerPtr stepSch(new UbScheduler(outstep));
       //stepSch->addSchedule(10000, 0, 1000000);
-      MacroscopicQuantitiesCoProcessor pp(grid, stepSch, pathname, WbWriterVtkXmlBinary::getInstance(), conv);
-
-      //D3Q27MacroscopicQuantitiesCoProcessor ppg(grid, stepSch, pathname, WbWriterVtkXmlBinary::getInstance(), conv,true);
-
-      //InSituVTKCoProcessor isp(grid, stepSch, metafile, conv);
+      WriteMacroscopicQuantitiesCoProcessor pp(grid, stepSch, pathname, WbWriterVtkXmlBinary::getInstance(), conv,comm);
 
       UbSchedulerPtr nupsSch(new UbScheduler(10, 30, 100));
       NUPSCounterCoProcessor npr(grid, nupsSch, numOfThreads, comm);
 
-
       CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endstep, stepSch));
 
       if (myid == 0)
diff --git a/source/ThirdParty/Library/basics/utilities/UbMath.h b/source/ThirdParty/Library/basics/utilities/UbMath.h
index a17a2054d..d7dcf4d1f 100644
--- a/source/ThirdParty/Library/basics/utilities/UbMath.h
+++ b/source/ThirdParty/Library/basics/utilities/UbMath.h
@@ -543,6 +543,7 @@ namespace UbMath
    static const double one_over_sqrt3 =  1.0/sqrt(3.0); //0.577350269
    static const double sqrt2  = sqrt(2.0); //1.4142135
    static const double sqrt3  = sqrt(3.0); //1.7320508
+   static const double zeroReal = 0.0;
    static const double one = 1.0;
    static const double two = 2.0;
    static const double three = 3.0;
diff --git a/source/ThirdParty/Library/numerics/geometry3d/CoordinateTransformation3D.h b/source/ThirdParty/Library/numerics/geometry3d/CoordinateTransformation3D.h
index e30495e61..d6ee637b5 100644
--- a/source/ThirdParty/Library/numerics/geometry3d/CoordinateTransformation3D.h
+++ b/source/ThirdParty/Library/numerics/geometry3d/CoordinateTransformation3D.h
@@ -155,6 +155,7 @@ private:
    bool   transformation;
 
    friend class MPIIORestartCoProcessor;
+   friend class MPIIORestart2CoProcessor;
 
    friend class boost::serialization::access;
    template<class Archive>
diff --git a/source/ThirdParty/Library/numerics/geometry3d/GbTriFaceMesh3D.cpp b/source/ThirdParty/Library/numerics/geometry3d/GbTriFaceMesh3D.cpp
index 70cc36cfd..2b89404ed 100644
--- a/source/ThirdParty/Library/numerics/geometry3d/GbTriFaceMesh3D.cpp
+++ b/source/ThirdParty/Library/numerics/geometry3d/GbTriFaceMesh3D.cpp
@@ -1144,3 +1144,82 @@ void GbTriFaceMesh3D::readMeshFromSTLFile(string filename, bool removeRedundantN
       this->calculateValues();
    }
 }
+//////////////////////////////////////////////////////////////////////////
+//void GbTriFaceMesh3D::writeMeshToSTLFile(string filename, bool isBinaryFormat)
+//{
+//   vector<GbTriFaceMesh3D::Vertex>    *nodes     = new vector<GbTriFaceMesh3D::Vertex>;
+//   vector<GbTriFaceMesh3D::TriFace>   *triangles = new vector<GbTriFaceMesh3D::TriFace>;
+//   int nr=0;
+//
+//   if (!isBinaryFormat) {
+//      ofstream out(filename.c_str());
+//      if (!out.good())
+//      {
+//         delete nodes;
+//         delete triangles;
+//         UB_THROW(UbException(UB_EXARGS, "Can not open STL file: "+filename));
+//      }
+//      char title[80] = "ASCII";
+//      std::string s0, s1;
+//      float n0, n1, n2, f0, f1, f2, f3, f4, f5, f6, f7, f8;
+//      out.write(title, 80);
+//      size_t size = nodes->size();
+//      for (size_t i = 0; i < size)
+//      {
+//         out << nodes[i++]
+//         in >> s0;                                // facet || endsolid
+//         if (s0=="facet") {
+//            in >> s1 >> n0 >> n1 >> n2;            // normal x y z
+//            in >> s0 >> s1;                        // outer loop
+//            in >> s0 >> f0 >> f1 >> f2;         // vertex x y z
+//            in >> s0 >> f3 >> f4 >> f5;         // vertex x y z
+//            in >> s0 >> f6 >> f7 >> f8;         // vertex x y z
+//            in >> s0;                            // endloop
+//            in >> s0;                            // endfacet
+//            // Generate a new Triangle without Normal as 3 Vertices
+//            nodes->push_back(GbTriFaceMesh3D::Vertex(f0, f1, f2));
+//            nodes->push_back(GbTriFaceMesh3D::Vertex(f3, f4, f5));
+//            nodes->push_back(GbTriFaceMesh3D::Vertex(f6, f7, f8));
+//            triangles->push_back(GbTriFaceMesh3D::TriFace(nr, nr+1, nr+2));
+//            nr+=3;
+//         }
+//         else if (s0=="endsolid") {
+//            break;
+//         }
+//      }
+//      in.close();
+//   }
+//   else {
+//      FILE *f = fopen(filename.c_str(), "rb");
+//      if (!f)
+//      {
+//         delete nodes;
+//         delete triangles;
+//         UB_THROW(UbException(UB_EXARGS, "Can not open STL file: "+filename));
+//      }
+//      char title[80];
+//      int nFaces;
+//      fread(title, 80, 1, f);
+//      fread((void*)&nFaces, 4, 1, f);
+//      float v[12]; // normal=3, vertices=3*3 = 12
+//      unsigned short uint16;
+//      // Every Face is 50 Bytes: Normal(3*float), Vertices(9*float), 2 Bytes Spacer
+//      for (size_t i=0; i<nFaces; ++i) {
+//         for (size_t j=0; j<12; ++j) {
+//            fread((void*)&v[j], sizeof(float), 1, f);
+//         }
+//         fread((void*)&uint16, sizeof(unsigned short), 1, f); // spacer between successive faces
+//         nodes->push_back(GbTriFaceMesh3D::Vertex(v[3], v[4], v[5]));
+//         nodes->push_back(GbTriFaceMesh3D::Vertex(v[6], v[7], v[8]));
+//         nodes->push_back(GbTriFaceMesh3D::Vertex(v[9], v[10], v[11]));
+//         triangles->push_back(GbTriFaceMesh3D::TriFace(nr, nr+1, nr+2));
+//         nr+=3;
+//      }
+//      fclose(f);
+//   }
+//
+//   GbTriFaceMesh3D* mesh = new GbTriFaceMesh3D(meshName, nodes, triangles, splitAlg, removeRedundantNodes);
+//
+//   return mesh;
+//}
+//////////////////////////////////////////////////////////////////////////
diff --git a/source/ThirdParty/Library/numerics/geometry3d/GbVoxelMatrix3D.cpp b/source/ThirdParty/Library/numerics/geometry3d/GbVoxelMatrix3D.cpp
index 5a88c38b7..2ae644d0a 100644
--- a/source/ThirdParty/Library/numerics/geometry3d/GbVoxelMatrix3D.cpp
+++ b/source/ThirdParty/Library/numerics/geometry3d/GbVoxelMatrix3D.cpp
@@ -830,6 +830,88 @@ void GbVoxelMatrix3D::mirrorZ()
    std::swap(this->voxelMatrix, voxelMatrix_temp);
 }
 //////////////////////////////////////////////////////////////////////////
+void GbVoxelMatrix3D::rotateAroundY(double theta)
+{
+   int nx1 = (int)voxelMatrix.getNX1();
+   int nx2 = (int)voxelMatrix.getNX2();
+   int nx3 = (int)voxelMatrix.getNX3();
+
+   GbVoxelMatrix3D::Matrix3D voxelMatrix_temp(nx1, nx2, nx3, FLUID);
+
+   double newMinX1 = cos(theta)*minX1+sin(theta)*minX3;
+   double newMinX3 = -sin(theta)*minX1+cos(theta)*minX3;
+
+   for (int x3 = 0; x3<nx3; x3++) {
+      for (int x2 = 0; x2<nx2; x2++) {
+         for (int x1 = 0; x1<nx1; x1++)
+         {
+            if (voxelMatrix(x1, x2, x3)==SOLID)
+            {
+               double rcX1 = minX1+deltaX1*x1;
+               double rcX3 = minX3+deltaX3*x3;
+
+               double nrcX1 = cos(theta)*rcX1+sin(theta)*rcX3;
+               double nrcX3 = -sin(theta)*rcX1+cos(theta)*rcX3;
+
+               int newX1 = UbMath::integerRounding((nrcX1-minX1)/deltaX1);
+               int newX2 = x2;
+               int newX3 = UbMath::integerRounding((nrcX3-minX3)/deltaX3);
+
+               if (newX1 < 0)
+               {
+                  int test=1;
+               }
+
+               if (newX1>0 && newX3>0 && newX1<nx1 && newX3<nx3)
+               {
+                  voxelMatrix_temp(newX1, newX2, newX3) = voxelMatrix(x1, x2, x3);
+               }
+
+               //int ix1, ix2, ix3;
+               //double ixx1 = (abs(nrcX1-minX1)/deltaX1);
+               //ix2 = x2;
+               //double ixx3 = (abs(nrcX3-minX3)/deltaX3);
+               //if (ixx1-(int)ixx1>.9999999999) ix1 = (int)ixx1+1; else ix1 = (int)ixx1;
+               ////if (ixx2-(int)ixx2>.9999999999) ix2 = (int)ixx2+1; else ix2 = (int)ixx2;
+               //if (ixx3-(int)ixx3>.9999999999) ix3 = (int)ixx3+1; else ix3 = (int)ixx3;
+
+               //if (ix1>=0 && ix3>=0 && ix1<nx1 && ix3<nx3)
+               //{
+               //   voxelMatrix_temp(ix1, ix2, ix3) = voxelMatrix(x1, x2, x3);
+               //}
+            }
+
+         }
+      }
+   }
+   std::swap(voxelMatrix, voxelMatrix_temp);
+
+   for (int x3 = 0; x3<nx3; x3++)
+      for (int x2 = 0; x2<nx2; x2++)
+         for (int x1 = 0; x1<nx1; x1++)
+         {
+            int count = 0;
+            for (int k3 = -1; k3<=1; k3++)
+               for (int k1 = -1; k1<=1; k1++)
+               {
+                  int j1 = x1+k1;
+                  int j3 = x3+k3;
+                  if (j1>=0 && j3>=0 && j1<nx1 && j3<nx3)
+                  {
+                     if (voxelMatrix(j1, x2, j3)==SOLID)
+                     {
+                        count++;
+                     }
+                  }
+
+               }
+            if (count == 8)
+            {
+               voxelMatrix(x1, x2, x3) = SOLID;
+            }
+         }
+}
+//////////////////////////////////////////////////////////////////////////
 void GbVoxelMatrix3D::writeToLegacyVTKASCII(const std::string& fileName)
 {
    string fn = fileName+".ascii.vtk";
diff --git a/source/ThirdParty/Library/numerics/geometry3d/GbVoxelMatrix3D.h b/source/ThirdParty/Library/numerics/geometry3d/GbVoxelMatrix3D.h
index d95ae2915..66e78fd4c 100644
--- a/source/ThirdParty/Library/numerics/geometry3d/GbVoxelMatrix3D.h
+++ b/source/ThirdParty/Library/numerics/geometry3d/GbVoxelMatrix3D.h
@@ -137,6 +137,8 @@ public:
    void mirrorY();
    void mirrorZ();
 
+   void rotateAroundY(double theta);
+
    void writeToLegacyVTKASCII(const std::string& fileName);
    void writeToLegacyVTKBinary(const std::string& fileName);
    void writeToVTKImageDataASCII(const std::string& fileName);
@@ -163,38 +165,38 @@ protected:
 
    using GbObject3D::isPointInGbObject3D; //Grund: dadurch muss man hier  isPointInGbObject3D(GbPoint3D*) nicht ausprogrammieren, welche sonst hier "ueberdeckt" waere
 
-#ifdef CAB_RCF
-   template<class Archive>
-   void SF_SERIALIZE(Archive & ar)
-   {
-      SF_SERIALIZE_PARENT<GbObject3D>(ar, *this);
-      ar & minX1;
-      ar & minX2;
-      ar & minX3;
-      ar & deltaX1;
-      ar & deltaX2;
-      ar & deltaX3;
-      ar & nodesX1;
-      ar & nodesX2;
-      ar & nodesX3;
-      ar & threshold;
-      ar & transferViaFilename;
-      ar & addSurfaceTriangleSetFlag;
-      if (!transferViaFilename)
-      {
-         ar & voxelMatrix;
-      }
-      else
-      {
-         ar & filename;
-         if (ArchiveTools::isReading(ar))
-         {
-            this->readMatrixFromVtiASCIIFile(filename);
-         }
-      }
-
-   }
-#endif //CAB_RCF
+//#ifdef CAB_RCF
+//   template<class Archive>
+//   void SF_SERIALIZE(Archive & ar)
+//   {
+//      SF_SERIALIZE_PARENT<GbObject3D>(ar, *this);
+//      ar & minX1;
+//      ar & minX2;
+//      ar & minX3;
+//      ar & deltaX1;
+//      ar & deltaX2;
+//      ar & deltaX3;
+//      ar & nodesX1;
+//      ar & nodesX2;
+//      ar & nodesX3;
+//      ar & threshold;
+//      ar & transferViaFilename;
+//      ar & addSurfaceTriangleSetFlag;
+//      if (!transferViaFilename)
+//      {
+//         ar & voxelMatrix;
+//      }
+//      else
+//      {
+//         ar & filename;
+//         if (ArchiveTools::isReading(ar))
+//         {
+//            this->readMatrixFromVtiASCIIFile(filename);
+//         }
+//      }
+//
+//   }
+//#endif //CAB_RCF
 
 protected:
    //for transfer
@@ -219,6 +221,7 @@ protected:
 
    long numberOfSolid;
    long numberOfFluid;
+
 };
 
 //////////////////////////////////////////////////////////////////////////
@@ -330,11 +333,12 @@ void GbVoxelMatrix3D::readBufferedMatrixFromRawFile(std::string filename, GbVoxe
 }
 
 
-#if defined(RCF_USE_SF_SERIALIZATION) && !defined(SWIG)
-UB_AUTO_RUN_NAMED(SF::registerType<GbVoxelMatrix3D>("GbVoxelMatrix3D"), SF_GbVoxelMatrix3D);
-UB_AUTO_RUN_NAMED((SF::registerBaseAndDerived< GbObject3D, GbVoxelMatrix3D >()), SF_GbVoxelMatrix3D_BD1);
-UB_AUTO_RUN_NAMED((SF::registerBaseAndDerived< UbObserver, GbVoxelMatrix3D>()), SF_GbVoxelMatrix3D_BD2);
-#endif //RCF_USE_SF_SERIALIZATION
+
+//#if defined(RCF_USE_SF_SERIALIZATION) && !defined(SWIG)
+//UB_AUTO_RUN_NAMED(SF::registerType<GbVoxelMatrix3D>("GbVoxelMatrix3D"), SF_GbVoxelMatrix3D);
+//UB_AUTO_RUN_NAMED((SF::registerBaseAndDerived< GbObject3D, GbVoxelMatrix3D >()), SF_GbVoxelMatrix3D_BD1);
+//UB_AUTO_RUN_NAMED((SF::registerBaseAndDerived< UbObserver, GbVoxelMatrix3D>()), SF_GbVoxelMatrix3D_BD2);
+//#endif //RCF_USE_SF_SERIALIZATION
 
 
 #endif   
diff --git a/source/ThirdParty/Library/numerics/geometry3d/creator/GbTriFaceMesh3DCreator.cpp b/source/ThirdParty/Library/numerics/geometry3d/creator/GbTriFaceMesh3DCreator.cpp
index 8129dfeaf..64cf0f7f3 100644
--- a/source/ThirdParty/Library/numerics/geometry3d/creator/GbTriFaceMesh3DCreator.cpp
+++ b/source/ThirdParty/Library/numerics/geometry3d/creator/GbTriFaceMesh3DCreator.cpp
@@ -239,6 +239,82 @@ GbTriFaceMesh3D* GbTriFaceMesh3DCreator::readMeshFromSTLFile(UbFileInput *in, st
    
    return mesh;
 }
+//////////////////////////////////////////////////////////////////////////
+GbTriFaceMesh3D* GbTriFaceMesh3DCreator::readMeshFromSTLFile2(string filename, string meshName, GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg, bool removeRedundantNodes,  bool isBinaryFormat)
+{
+   vector<GbTriFaceMesh3D::Vertex>    *nodes     = new vector<GbTriFaceMesh3D::Vertex>;
+   vector<GbTriFaceMesh3D::TriFace>   *triangles = new vector<GbTriFaceMesh3D::TriFace>;
+   int nr=0;
+
+   if (!isBinaryFormat) {
+      ifstream in(filename.c_str());
+      if (!in.good()) 
+      {
+         delete nodes;
+         delete triangles;
+         UB_THROW(UbException(UB_EXARGS, "Can not open STL file: "+filename));
+      }
+      char title[80];
+      std::string s0, s1;
+      float n0, n1, n2, f0, f1, f2, f3, f4, f5, f6, f7, f8;
+      in.read(title, 80);
+      while (!in.eof()) {
+         in >> s0;                                // facet || endsolid
+         if (s0=="facet") {
+            in >> s1 >> n0 >> n1 >> n2;            // normal x y z
+            in >> s0 >> s1;                        // outer loop
+            in >> s0 >> f0 >> f1 >> f2;         // vertex x y z
+            in >> s0 >> f3 >> f4 >> f5;         // vertex x y z
+            in >> s0 >> f6 >> f7 >> f8;         // vertex x y z
+            in >> s0;                            // endloop
+            in >> s0;                            // endfacet
+            // Generate a new Triangle without Normal as 3 Vertices
+            nodes->push_back(GbTriFaceMesh3D::Vertex(f0, f1, f2));
+            nodes->push_back(GbTriFaceMesh3D::Vertex(f3, f4, f5));
+            nodes->push_back(GbTriFaceMesh3D::Vertex(f6, f7, f8));
+            triangles->push_back(GbTriFaceMesh3D::TriFace(nr,nr+1,nr+2));
+            nr+=3;
+         }
+         else if (s0=="endsolid") {
+            break;
+         }
+      }
+      in.close();
+   }
+   else {
+      FILE *f = fopen(filename.c_str(), "rb");
+      if (!f) 
+      {
+         delete nodes;
+         delete triangles;
+         UB_THROW(UbException(UB_EXARGS, "Can not open STL file: "+filename));
+      }
+      char title[80];
+      int nFaces;
+      fread(title, 80, 1, f);
+      fread((void*)&nFaces, 4, 1, f);
+      float v[12]; // normal=3, vertices=3*3 = 12
+      unsigned short uint16;
+      // Every Face is 50 Bytes: Normal(3*float), Vertices(9*float), 2 Bytes Spacer
+      for (size_t i=0; i<nFaces; ++i) {
+         for (size_t j=0; j<12; ++j) {
+            fread((void*)&v[j], sizeof(float), 1, f);
+         }
+         fread((void*)&uint16, sizeof(unsigned short), 1, f); // spacer between successive faces
+         nodes->push_back(GbTriFaceMesh3D::Vertex(v[3], v[4], v[5]));
+         nodes->push_back(GbTriFaceMesh3D::Vertex(v[6], v[7], v[8]));
+         nodes->push_back(GbTriFaceMesh3D::Vertex(v[9], v[10], v[11]));
+         triangles->push_back(GbTriFaceMesh3D::TriFace(nr, nr+1, nr+2));
+         nr+=3;
+      }
+      fclose(f);
+   }
+
+   GbTriFaceMesh3D* mesh = new GbTriFaceMesh3D(meshName, nodes, triangles, splitAlg, removeRedundantNodes);
+
+   return mesh;
+}
+
 /*======================================================================*/
 GbTriFaceMesh3D* GbTriFaceMesh3DCreator::readMeshFromAVSFile(string filename, string meshName, GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg, bool removeRedundantNodes)
 {
diff --git a/source/ThirdParty/Library/numerics/geometry3d/creator/GbTriFaceMesh3DCreator.h b/source/ThirdParty/Library/numerics/geometry3d/creator/GbTriFaceMesh3DCreator.h
index 0fb144d85..99c999a03 100644
--- a/source/ThirdParty/Library/numerics/geometry3d/creator/GbTriFaceMesh3DCreator.h
+++ b/source/ThirdParty/Library/numerics/geometry3d/creator/GbTriFaceMesh3DCreator.h
@@ -31,6 +31,7 @@ public:
 
    static GbTriFaceMesh3D* readMeshFromSTLFile(std::string filename, std::string meshName="", GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SAHPLIT, bool removeRedundantNodes=true); 
    static GbTriFaceMesh3D* readMeshFromSTLFile(UbFileInput* in, std::string meshName="", GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SAHPLIT, bool removeRedundantNodes=true);
+   static GbTriFaceMesh3D* readMeshFromSTLFile2(std::string filename, std::string meshName="", GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SAHPLIT, bool removeRedundantNodes=true,  bool isBinaryFormat=true);
 
    static GbTriFaceMesh3D* readMeshFromAVSFile(std::string filename, std::string meshName="", GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SAHPLIT, bool removeRedundantNodes=true); 
    static GbTriFaceMesh3D* readMeshFromAVSFile(UbFileInput* in, std::string meshName="", GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SAHPLIT, bool removeRedundantNodes=true);
diff --git a/source/VirtualFluids.h b/source/VirtualFluids.h
index ea027ec40..44fbb863d 100644
--- a/source/VirtualFluids.h
+++ b/source/VirtualFluids.h
@@ -101,9 +101,9 @@
 #include <BoundaryConditions/ThinWallNoSlipBCAlgorithm.h>
 #include <BoundaryConditions/HighViscosityNoSlipBCAlgorithm.h>
 #include <BoundaryConditions/SlipBCAlgorithm.h>
-#include <BoundaryConditions/NonReflectingDensityBCAlgorithm.h>
-#include <BoundaryConditions/NonReflectingVelocityBCAlgorithm.h>
-#include <BoundaryConditions/NonReflectingSlipBCAlgorithm.h>
+#include <BoundaryConditions/NonReflectingOutflowBCAlgorithm.h>
+#include <BoundaryConditions/VelocityWithDensityBCAlgorithm.h>
+//#include <BoundaryConditions/NonReflectingSlipBCAlgorithm.h>
 
 #include <Connectors/Block3DConnector.h>
 #include <Connectors/D3Q27ETCFOffVectorConnector.h>
@@ -161,11 +161,13 @@
 #include <CoProcessors/TimeAveragedValuesCoProcessor.h>
 #include <CoProcessors/InSituCatalystCoProcessor.h>
 #include <CoProcessors/MPIIORestartCoProcessor.h>
+#include <CoProcessors/MPIIORestart2CoProcessor.h>
 #include <LineTimeSeriesCoProcessor.h>
 #include <IntegrateValuesHelper.h>
 //#include <LBM/D3Q27CompactInterpolationProcessor.h>
 #include <LBM/IncompressibleOffsetInterpolationProcessor.h>
 #include <LBM/CompressibleOffsetInterpolationProcessor.h>
+#include <LBM/CompressibleOffsetMomentsInterpolationProcessor.h>
 #include <LBM/InterpolationHelper.h>
 #include <LBM/InterpolationProcessor.h>
 //#include <LBM/D3Q27OffsetInterpolationProcessor.h>
@@ -292,6 +294,7 @@
 #include <Visitors/BoundaryConditionsBlockVisitor.h>
 #include <Visitors/ChangeBoundaryDensityBlockVisitor.h>
 #include <InitDistributionsFromFileBlockVisitor.h>
+#include <InitDistributionsWithInterpolationGridVisitor.h>
 #include <CheckRatioBlockVisitor.h>
 #include <SpongeLayerBlockVisitor.h>
 
diff --git a/source/VirtualFluidsCore/BoundaryConditions/BCAlgorithm.cpp b/source/VirtualFluidsCore/BoundaryConditions/BCAlgorithm.cpp
index 8c4e11096..39d1a31b5 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/BCAlgorithm.cpp
+++ b/source/VirtualFluidsCore/BoundaryConditions/BCAlgorithm.cpp
@@ -7,19 +7,6 @@ BCAlgorithm::BCAlgorithm() : compressible(false)
 //////////////////////////////////////////////////////////////////////////
 void BCAlgorithm::apply()
 {
-   //if (this->compressible)
-   //{
-   //   calcFeqsForDirFct = &D3Q27System::getCompFeqForDirection;
-   //   calcMacrosFct = &D3Q27System::calcCompMacroscopicValues;
-   //   calcFeqFct = &D3Q27System::calcCompFeq;
-   //}
-   //else
-   //{
-   //   calcFeqsForDirFct = &D3Q27System::getIncompFeqForDirection;
-   //   calcMacrosFct = &D3Q27System::calcIncompMacroscopicValues;
-   //   calcFeqFct = &D3Q27System::calcIncompFeq;
-   //}
-
    int cbc = 0;
    int cn = 0;
    int j;
@@ -39,11 +26,6 @@ void BCAlgorithm::apply()
       }
       cn = j;
 }
-////////////////////////////////////////////////////////////////////////////
-//void BoundaryCondition::addDistributions(EsoTwist3DPtr distributions)
-//{
-//   this->distributions = distributions;
-//}
 //////////////////////////////////////////////////////////////////////////
 void BCAlgorithm::addNode(int x1, int x2, int x3)
 {
@@ -98,6 +80,14 @@ void BCAlgorithm::clearData()
    nodeVector.clear();
    bcVector.clear();
 }
-
-
+//////////////////////////////////////////////////////////////////////////
+BCArray3DPtr BCAlgorithm::getBcArray()
+{
+   return bcArray;
+}
+//////////////////////////////////////////////////////////////////////////
+void BCAlgorithm::setBcArray(BCArray3DPtr bcarray)
+{
+   bcArray = bcarray;
+}
 
diff --git a/source/VirtualFluidsCore/BoundaryConditions/BCAlgorithm.h b/source/VirtualFluidsCore/BoundaryConditions/BCAlgorithm.h
index 0427d2783..65fecd92f 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/BCAlgorithm.h
+++ b/source/VirtualFluidsCore/BoundaryConditions/BCAlgorithm.h
@@ -8,6 +8,7 @@
 #include "BoundaryConditions.h"
 #include "D3Q27System.h"
 #include "EsoTwist3D.h"
+#include "BCArray3D.h"
 
 #include <boost/serialization/serialization.hpp>
 #include <boost/serialization/base_object.hpp>
@@ -28,9 +29,9 @@ public:
    static const char SlipBCAlgorithm = 4;
    static const char HighViscosityNoSlipBCAlgorithm = 5;
    static const char ThinWallNoSlipBCAlgorithm = 6;
-   static const char NonReflectingVelocityBCAlgorithm = 7;
-   static const char NonReflectingDensityBCAlgorithm = 8;
-   static const char NonReflectingSlipBCAlgorithm = 9;
+   static const char VelocityWithDensityBCAlgorithm = 7;
+   static const char NonReflectingOutflowBCAlgorithm = 8;
+
 public:
    BCAlgorithm();
    virtual ~BCAlgorithm() {}
@@ -45,6 +46,9 @@ public:
    bool isPreCollision();
    virtual BCAlgorithmPtr clone()=0;
    void clearData();
+   BCArray3DPtr getBcArray();
+   void setBcArray(BCArray3DPtr bcarray);
+
 protected:
    virtual void applyBC() = 0;
    
@@ -57,6 +61,7 @@ protected:
 
    BoundaryConditionsPtr bcPtr;
    DistributionArray3DPtr distributions;
+   BCArray3DPtr bcArray;
 
    LBMReal collFactor;
    int x1, x2, x3;
@@ -71,6 +76,8 @@ protected:
    CalcMacrosFct    calcMacrosFct;
    CalcFeqFct       calcFeqFct;
 
+   
+
 private:
    //friend class boost::serialization::access;
    //template<class Archive>
diff --git a/source/VirtualFluidsCore/BoundaryConditions/BCArray3D.cpp b/source/VirtualFluidsCore/BoundaryConditions/BCArray3D.cpp
index 22df9daf1..eeda01489 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/BCArray3D.cpp
+++ b/source/VirtualFluidsCore/BoundaryConditions/BCArray3D.cpp
@@ -173,6 +173,13 @@ std::string BCArray3D::toString() const
 
    return text.str();
 }
+//////////////////////////////////////////////////////////////////////////
+std::vector< int >& BCArray3D::getBcindexmatrixDataVector()
+{
+   return bcindexmatrix.getDataVector();
+}
+
+
 //////////////////////////////////////////////////////////////////////////
 void BCArray3D::deleteBCAndSetType(std::size_t x1, std::size_t x2, std::size_t x3, int type)
    {
diff --git a/source/VirtualFluidsCore/BoundaryConditions/BCArray3D.h b/source/VirtualFluidsCore/BoundaryConditions/BCArray3D.h
index 2c4404424..a6be43f38 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/BCArray3D.h
+++ b/source/VirtualFluidsCore/BoundaryConditions/BCArray3D.h
@@ -86,6 +86,9 @@ public:
    //////////////////////////////////////////////////////////////////////////
    std::string toString() const;
    //////////////////////////////////////////////////////////////////////////
+   std::vector< int >& getBcindexmatrixDataVector();
+   //////////////////////////////////////////////////////////////////////////
+
 
    static const int SOLID;     
    static const int FLUID;     
@@ -100,6 +103,7 @@ private:
    void deleteBC(std::size_t x1, std::size_t x2, std::size_t x3);
 
    friend class MPIIORestartCoProcessor;
+   friend class MPIIORestart2CoProcessor;
 
    friend class boost::serialization::access;
    template<class Archive>
diff --git a/source/VirtualFluidsCore/BoundaryConditions/BoundaryConditions.h b/source/VirtualFluidsCore/BoundaryConditions/BoundaryConditions.h
index 3829c751c..f8cee8cf8 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/BoundaryConditions.h
+++ b/source/VirtualFluidsCore/BoundaryConditions/BoundaryConditions.h
@@ -257,6 +257,7 @@ protected:
 
 private:
    friend class MPIIORestartCoProcessor;
+   friend class MPIIORestart2CoProcessor;
 
    friend class boost::serialization::access;
    template<class Archive>
diff --git a/source/VirtualFluidsCore/BoundaryConditions/NonReflectingDensityBCAlgorithm.cpp b/source/VirtualFluidsCore/BoundaryConditions/NonReflectingDensityBCAlgorithm.cpp
deleted file mode 100644
index 3ef5e9264..000000000
--- a/source/VirtualFluidsCore/BoundaryConditions/NonReflectingDensityBCAlgorithm.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-#include "NonReflectingDensityBCAlgorithm.h"
-#include <boost/pointer_cast.hpp>
-#include "D3Q27System.h"
-
-NonReflectingDensityBCAlgorithm::NonReflectingDensityBCAlgorithm()
-{
-   BCAlgorithm::type = BCAlgorithm::NonReflectingDensityBCAlgorithm;
-   BCAlgorithm::preCollision = false;
-}
-//////////////////////////////////////////////////////////////////////////
-NonReflectingDensityBCAlgorithm::~NonReflectingDensityBCAlgorithm()
-{
-}
-//////////////////////////////////////////////////////////////////////////
-BCAlgorithmPtr NonReflectingDensityBCAlgorithm::clone()
-{
-   BCAlgorithmPtr bc(new NonReflectingDensityBCAlgorithm());
-   return bc;
-}
-//////////////////////////////////////////////////////////////////////////
-void NonReflectingDensityBCAlgorithm::addDistributions(DistributionArray3DPtr distributions)
-{
-   this->distributions = distributions;
-}
-//////////////////////////////////////////////////////////////////////////
-void NonReflectingDensityBCAlgorithm::applyBC()
-{
-   distributions->swap();
-   LBMReal f[D3Q27System::ENDF+1];
-   LBMReal ftemp[D3Q27System::ENDF+1];
-   distributions->getDistribution(f, x1, x2, x3);
-   int nx1 = x1;
-   int nx2 = x2;
-   int nx3 = x3;
-   int direction = -1;
-
-   //flag points in direction of fluid
-   if      (bcPtr->hasDensityBoundaryFlag(D3Q27System::E)) { nx1 += 1; direction = D3Q27System::E; }
-   else if (bcPtr->hasDensityBoundaryFlag(D3Q27System::W)) { nx1 -= 1; direction = D3Q27System::W; }
-   else if (bcPtr->hasDensityBoundaryFlag(D3Q27System::N)) { nx2 += 1; direction = D3Q27System::N; }
-   else if (bcPtr->hasDensityBoundaryFlag(D3Q27System::S)) { nx2 -= 1; direction = D3Q27System::S; }
-   else if (bcPtr->hasDensityBoundaryFlag(D3Q27System::T)) { nx3 += 1; direction = D3Q27System::T; }
-   else if (bcPtr->hasDensityBoundaryFlag(D3Q27System::B)) { nx3 -= 1; direction = D3Q27System::B; }
-   else UB_THROW(UbException(UB_EXARGS, "Danger...no orthogonal BC-Flag on density boundary..."));
-
-   //#ifdef _DEBUG
-   //   if (nx1<0 || nx1>maxX1) UB_THROW(UbException(UB_EXARGS, "nx1<0 || nx1>=lengthX1"));
-   //   if (nx2<0 || nx2>maxX2) UB_THROW(UbException(UB_EXARGS, "nx2<0 || nx2>=lengthX2"));
-   //   if (nx3<0 || nx3>maxX3) UB_THROW(UbException(UB_EXARGS, "nx3<0 || nx3>=lengthX3"));
-   //#endif
-
-   distributions->getDistribution(ftemp, nx1, nx2, nx3);
-   LBMReal rho, vx1, vx2, vx3;
-   calcMacrosFct(f, rho, vx1, vx2, vx3);
-
-   distributions->swap();
-
-   double dim = 0.01;
-
-   switch (direction)
-   {
-   case D3Q27System::E:
-      f[D3Q27System::E]   = ftemp[D3Q27System::E]   * (one_over_sqrt3 + vx1) + (1.0 - one_over_sqrt3 - vx1)*f[D3Q27System::E]  ;// - rho*dim*D3Q27System::WEIGTH[D3Q27System::E];
-      f[D3Q27System::NE]  = ftemp[D3Q27System::NE]  * (one_over_sqrt3 + vx1) + (1.0 - one_over_sqrt3 - vx1)*f[D3Q27System::NE] ;// - rho*dim*D3Q27System::WEIGTH[D3Q27System::NE];
-      f[D3Q27System::SE]  = ftemp[D3Q27System::SE]  * (one_over_sqrt3 + vx1) + (1.0 - one_over_sqrt3 - vx1)*f[D3Q27System::SE] ;// - rho*dim*D3Q27System::WEIGTH[D3Q27System::SE];
-      f[D3Q27System::TE]  = ftemp[D3Q27System::TE]  * (one_over_sqrt3 + vx1) + (1.0 - one_over_sqrt3 - vx1)*f[D3Q27System::TE] ;// - rho*dim*D3Q27System::WEIGTH[D3Q27System::TE];
-      f[D3Q27System::BE]  = ftemp[D3Q27System::BE]  * (one_over_sqrt3 + vx1) + (1.0 - one_over_sqrt3 - vx1)*f[D3Q27System::BE] ;// - rho*dim*D3Q27System::WEIGTH[D3Q27System::BE];
-      f[D3Q27System::TNE] = ftemp[D3Q27System::TNE] * (one_over_sqrt3 + vx1) + (1.0 - one_over_sqrt3 - vx1)*f[D3Q27System::TNE];// - rho*dim*D3Q27System::WEIGTH[D3Q27System::TNE];
-      f[D3Q27System::TSE] = ftemp[D3Q27System::TSE] * (one_over_sqrt3 + vx1) + (1.0 - one_over_sqrt3 - vx1)*f[D3Q27System::TSE];// - rho*dim*D3Q27System::WEIGTH[D3Q27System::TSE];
-      f[D3Q27System::BNE] = ftemp[D3Q27System::BNE] * (one_over_sqrt3 + vx1) + (1.0 - one_over_sqrt3 - vx1)*f[D3Q27System::BNE];// - rho*dim*D3Q27System::WEIGTH[D3Q27System::BNE];
-      f[D3Q27System::BSE] = ftemp[D3Q27System::BSE] * (one_over_sqrt3 + vx1) + (1.0 - one_over_sqrt3 - vx1)*f[D3Q27System::BSE];// - rho*dim*D3Q27System::WEIGTH[D3Q27System::BSE];
-
-      distributions->setDistributionInvForDirection(f[D3Q27System::E],   x1, x2, x3, D3Q27System::E);
-      distributions->setDistributionInvForDirection(f[D3Q27System::NE],  x1, x2, x3, D3Q27System::NE);
-      distributions->setDistributionInvForDirection(f[D3Q27System::SE],  x1, x2, x3, D3Q27System::SE);
-      distributions->setDistributionInvForDirection(f[D3Q27System::TE],  x1, x2, x3, D3Q27System::TE);
-      distributions->setDistributionInvForDirection(f[D3Q27System::BE],  x1, x2, x3, D3Q27System::BE);
-      distributions->setDistributionInvForDirection(f[D3Q27System::TNE], x1, x2, x3, D3Q27System::TNE);
-      distributions->setDistributionInvForDirection(f[D3Q27System::TSE], x1, x2, x3, D3Q27System::TSE);
-      distributions->setDistributionInvForDirection(f[D3Q27System::BNE], x1, x2, x3, D3Q27System::BNE);
-      distributions->setDistributionInvForDirection(f[D3Q27System::BSE], x1, x2, x3, D3Q27System::BSE);
-      break;
-   case D3Q27System::W:
-      f[D3Q27System::W]   = ftemp[D3Q27System::W]   * (one_over_sqrt3 - vx1) + (1.0 - one_over_sqrt3 + vx1)*f[D3Q27System::W]    ;// - rho*dim*D3Q27System::WEIGTH[D3Q27System::W];
-      f[D3Q27System::NW]  = ftemp[D3Q27System::NW]  * (one_over_sqrt3 - vx1) + (1.0 - one_over_sqrt3 + vx1)*f[D3Q27System::NW]   ;// - rho*dim*D3Q27System::WEIGTH[D3Q27System::NW];
-      f[D3Q27System::SW]  = ftemp[D3Q27System::SW]  * (one_over_sqrt3 - vx1) + (1.0 - one_over_sqrt3 + vx1)*f[D3Q27System::SW]   ;// - rho*dim*D3Q27System::WEIGTH[D3Q27System::SW];
-      f[D3Q27System::TW]  = ftemp[D3Q27System::TW]  * (one_over_sqrt3 - vx1) + (1.0 - one_over_sqrt3 + vx1)*f[D3Q27System::TW]   ;// - rho*dim*D3Q27System::WEIGTH[D3Q27System::TW];
-      f[D3Q27System::BW]  = ftemp[D3Q27System::BW]  * (one_over_sqrt3 - vx1) + (1.0 - one_over_sqrt3 + vx1)*f[D3Q27System::BW]   ;// - rho*dim*D3Q27System::WEIGTH[D3Q27System::BW];
-      f[D3Q27System::TNW] = ftemp[D3Q27System::TNW] * (one_over_sqrt3 - vx1) + (1.0 - one_over_sqrt3 + vx1)*f[D3Q27System::TNW];// - rho*dim*D3Q27System::WEIGTH[D3Q27System::TNW];
-      f[D3Q27System::TSW] = ftemp[D3Q27System::TSW] * (one_over_sqrt3 - vx1) + (1.0 - one_over_sqrt3 + vx1)*f[D3Q27System::TSW];// - rho*dim*D3Q27System::WEIGTH[D3Q27System::TSW];
-      f[D3Q27System::BNW] = ftemp[D3Q27System::BNW] * (one_over_sqrt3 - vx1) + (1.0 - one_over_sqrt3 + vx1)*f[D3Q27System::BNW];// - rho*dim*D3Q27System::WEIGTH[D3Q27System::BNW];
-      f[D3Q27System::BSW] = ftemp[D3Q27System::BSW] * (one_over_sqrt3 - vx1) + (1.0 - one_over_sqrt3 + vx1)*f[D3Q27System::BSW];// - rho*dim*D3Q27System::WEIGTH[D3Q27System::BSW];
-
-      distributions->setDistributionInvForDirection(f[D3Q27System::W],   x1, x2, x3, D3Q27System::W);
-      distributions->setDistributionInvForDirection(f[D3Q27System::NW],  x1, x2, x3, D3Q27System::NW);
-      distributions->setDistributionInvForDirection(f[D3Q27System::SW],  x1, x2, x3, D3Q27System::SW);
-      distributions->setDistributionInvForDirection(f[D3Q27System::TW],  x1, x2, x3, D3Q27System::TW);
-      distributions->setDistributionInvForDirection(f[D3Q27System::BW],  x1, x2, x3, D3Q27System::BW);
-      distributions->setDistributionInvForDirection(f[D3Q27System::TNW], x1, x2, x3, D3Q27System::TNW);
-      distributions->setDistributionInvForDirection(f[D3Q27System::TSW], x1, x2, x3, D3Q27System::TSW);
-      distributions->setDistributionInvForDirection(f[D3Q27System::BNW], x1, x2, x3, D3Q27System::BNW);
-      distributions->setDistributionInvForDirection(f[D3Q27System::BSW], x1, x2, x3, D3Q27System::BSW);
-      break;
-   case D3Q27System::N:
-      f[D3Q27System::N]   = ftemp[D3Q27System::N]   * (one_over_sqrt3 + vx2) + (1.0 - one_over_sqrt3 - vx2)*f[D3Q27System::N]   ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::N];
-      f[D3Q27System::NE]  = ftemp[D3Q27System::NE]  * (one_over_sqrt3 + vx2) + (1.0 - one_over_sqrt3 - vx2)*f[D3Q27System::NE]  ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::NE];
-      f[D3Q27System::NW]  = ftemp[D3Q27System::NW]  * (one_over_sqrt3 + vx2) + (1.0 - one_over_sqrt3 - vx2)*f[D3Q27System::NW]  ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::NW];
-      f[D3Q27System::TN]  = ftemp[D3Q27System::TN]  * (one_over_sqrt3 + vx2) + (1.0 - one_over_sqrt3 - vx2)*f[D3Q27System::TN]  ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::TN];
-      f[D3Q27System::BN]  = ftemp[D3Q27System::BN]  * (one_over_sqrt3 + vx2) + (1.0 - one_over_sqrt3 - vx2)*f[D3Q27System::BN]  ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::BN];
-      f[D3Q27System::TNE] = ftemp[D3Q27System::TNE] * (one_over_sqrt3 + vx2) + (1.0 - one_over_sqrt3 - vx2)*f[D3Q27System::TNE] ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::TNE];
-      f[D3Q27System::TNW] = ftemp[D3Q27System::TNW] * (one_over_sqrt3 + vx2) + (1.0 - one_over_sqrt3 - vx2)*f[D3Q27System::TNW] ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::TNW];
-      f[D3Q27System::BNE] = ftemp[D3Q27System::BNE] * (one_over_sqrt3 + vx2) + (1.0 - one_over_sqrt3 - vx2)*f[D3Q27System::BNE] ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::BNE];
-      f[D3Q27System::BNW] = ftemp[D3Q27System::BNW] * (one_over_sqrt3 + vx2) + (1.0 - one_over_sqrt3 - vx2)*f[D3Q27System::BNW] ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::BNW];
-
-      distributions->setDistributionInvForDirection(f[D3Q27System::N], x1, x2, x3, D3Q27System::N);
-      distributions->setDistributionInvForDirection(f[D3Q27System::NE], x1, x2, x3, D3Q27System::NE);
-      distributions->setDistributionInvForDirection(f[D3Q27System::NW], x1, x2, x3, D3Q27System::NW);
-      distributions->setDistributionInvForDirection(f[D3Q27System::TN], x1, x2, x3, D3Q27System::TN);
-      distributions->setDistributionInvForDirection(f[D3Q27System::BN], x1, x2, x3, D3Q27System::BN);
-      distributions->setDistributionInvForDirection(f[D3Q27System::TNE], x1, x2, x3, D3Q27System::TNE);
-      distributions->setDistributionInvForDirection(f[D3Q27System::TNW], x1, x2, x3, D3Q27System::TNW);
-      distributions->setDistributionInvForDirection(f[D3Q27System::BNE], x1, x2, x3, D3Q27System::BNE);
-      distributions->setDistributionInvForDirection(f[D3Q27System::BNW], x1, x2, x3, D3Q27System::BNW);
-      break;
-   case D3Q27System::S:
-      f[D3Q27System::S]   = ftemp[D3Q27System::S]   * (one_over_sqrt3 - vx2) + (1.0 - one_over_sqrt3 + vx2)*f[D3Q27System::S]   ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::S];
-      f[D3Q27System::SE]  = ftemp[D3Q27System::SE]  * (one_over_sqrt3 - vx2) + (1.0 - one_over_sqrt3 + vx2)*f[D3Q27System::SE]  ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::SE];
-      f[D3Q27System::SW]  = ftemp[D3Q27System::SW]  * (one_over_sqrt3 - vx2) + (1.0 - one_over_sqrt3 + vx2)*f[D3Q27System::SW]  ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::SW];
-      f[D3Q27System::TS]  = ftemp[D3Q27System::TS]  * (one_over_sqrt3 - vx2) + (1.0 - one_over_sqrt3 + vx2)*f[D3Q27System::TS]  ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::TS];
-      f[D3Q27System::BS]  = ftemp[D3Q27System::BS]  * (one_over_sqrt3 - vx2) + (1.0 - one_over_sqrt3 + vx2)*f[D3Q27System::BS]  ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::BS];
-      f[D3Q27System::TSE] = ftemp[D3Q27System::TSE] * (one_over_sqrt3 - vx2) + (1.0 - one_over_sqrt3 + vx2)*f[D3Q27System::TSE] ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::TSE];
-      f[D3Q27System::TSW] = ftemp[D3Q27System::TSW] * (one_over_sqrt3 - vx2) + (1.0 - one_over_sqrt3 + vx2)*f[D3Q27System::TSW] ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::TSW];
-      f[D3Q27System::BSE] = ftemp[D3Q27System::BSE] * (one_over_sqrt3 - vx2) + (1.0 - one_over_sqrt3 + vx2)*f[D3Q27System::BSE] ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::BSE];
-      f[D3Q27System::BSW] = ftemp[D3Q27System::BSW] * (one_over_sqrt3 - vx2) + (1.0 - one_over_sqrt3 + vx2)*f[D3Q27System::BSW] ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::BSW];
-
-      distributions->setDistributionInvForDirection(f[D3Q27System::S], x1, x2, x3, D3Q27System::S);
-      distributions->setDistributionInvForDirection(f[D3Q27System::SE], x1, x2, x3, D3Q27System::SE);
-      distributions->setDistributionInvForDirection(f[D3Q27System::SW], x1, x2, x3, D3Q27System::SW);
-      distributions->setDistributionInvForDirection(f[D3Q27System::TS], x1, x2, x3, D3Q27System::TS);
-      distributions->setDistributionInvForDirection(f[D3Q27System::BS], x1, x2, x3, D3Q27System::BS);
-      distributions->setDistributionInvForDirection(f[D3Q27System::TSE], x1, x2, x3, D3Q27System::TSE);
-      distributions->setDistributionInvForDirection(f[D3Q27System::TSW], x1, x2, x3, D3Q27System::TSW);
-      distributions->setDistributionInvForDirection(f[D3Q27System::BSE], x1, x2, x3, D3Q27System::BSE);
-      distributions->setDistributionInvForDirection(f[D3Q27System::BSW], x1, x2, x3, D3Q27System::BSW);
-      break;
-   case D3Q27System::T:
-      f[D3Q27System::T]   = ftemp[D3Q27System::T]   * (one_over_sqrt3 + vx3) + (1.0 - one_over_sqrt3 - vx3)*f[D3Q27System::T]   ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::T];
-      f[D3Q27System::TE]  = ftemp[D3Q27System::TE]  * (one_over_sqrt3 + vx3) + (1.0 - one_over_sqrt3 - vx3)*f[D3Q27System::TE]  ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::TE];
-      f[D3Q27System::TW]  = ftemp[D3Q27System::TW]  * (one_over_sqrt3 + vx3) + (1.0 - one_over_sqrt3 - vx3)*f[D3Q27System::TW]  ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::TW];
-      f[D3Q27System::TN]  = ftemp[D3Q27System::TN]  * (one_over_sqrt3 + vx3) + (1.0 - one_over_sqrt3 - vx3)*f[D3Q27System::TN]  ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::TN];
-      f[D3Q27System::TS]  = ftemp[D3Q27System::TS]  * (one_over_sqrt3 + vx3) + (1.0 - one_over_sqrt3 - vx3)*f[D3Q27System::TS]  ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::TS];
-      f[D3Q27System::TNE] = ftemp[D3Q27System::TNE] * (one_over_sqrt3 + vx3) + (1.0 - one_over_sqrt3 - vx3)*f[D3Q27System::TNE] ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::TNE];
-      f[D3Q27System::TNW] = ftemp[D3Q27System::TNW] * (one_over_sqrt3 + vx3) + (1.0 - one_over_sqrt3 - vx3)*f[D3Q27System::TNW] ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::TNW];
-      f[D3Q27System::TSE] = ftemp[D3Q27System::TSE] * (one_over_sqrt3 + vx3) + (1.0 - one_over_sqrt3 - vx3)*f[D3Q27System::TSE] ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::TSE];
-      f[D3Q27System::TSW] = ftemp[D3Q27System::TSW] * (one_over_sqrt3 + vx3) + (1.0 - one_over_sqrt3 - vx3)*f[D3Q27System::TSW] ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::TSW];
-
-      distributions->setDistributionInvForDirection(f[D3Q27System::T], x1, x2, x3, D3Q27System::T);
-      distributions->setDistributionInvForDirection(f[D3Q27System::TE], x1, x2, x3, D3Q27System::TE);
-      distributions->setDistributionInvForDirection(f[D3Q27System::TW], x1, x2, x3, D3Q27System::TW);
-      distributions->setDistributionInvForDirection(f[D3Q27System::TN], x1, x2, x3, D3Q27System::TN);
-      distributions->setDistributionInvForDirection(f[D3Q27System::TS], x1, x2, x3, D3Q27System::TS);
-      distributions->setDistributionInvForDirection(f[D3Q27System::TNE], x1, x2, x3, D3Q27System::TNE);
-      distributions->setDistributionInvForDirection(f[D3Q27System::TNW], x1, x2, x3, D3Q27System::TNW);
-      distributions->setDistributionInvForDirection(f[D3Q27System::TSE], x1, x2, x3, D3Q27System::TSE);
-      distributions->setDistributionInvForDirection(f[D3Q27System::TSW], x1, x2, x3, D3Q27System::TSW);
-      break;
-   case D3Q27System::B:
-      f[D3Q27System::B]   = ftemp[D3Q27System::B]   * (one_over_sqrt3 - vx3) + (1.0 - one_over_sqrt3 + vx3)*f[D3Q27System::B]   ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::B];
-      f[D3Q27System::BE]  = ftemp[D3Q27System::BE]  * (one_over_sqrt3 - vx3) + (1.0 - one_over_sqrt3 + vx3)*f[D3Q27System::BE]  ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::BE];
-      f[D3Q27System::BW]  = ftemp[D3Q27System::BW]  * (one_over_sqrt3 - vx3) + (1.0 - one_over_sqrt3 + vx3)*f[D3Q27System::BW]  ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::BW];
-      f[D3Q27System::BN]  = ftemp[D3Q27System::BN]  * (one_over_sqrt3 - vx3) + (1.0 - one_over_sqrt3 + vx3)*f[D3Q27System::BN]  ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::BN];
-      f[D3Q27System::BS]  = ftemp[D3Q27System::BS]  * (one_over_sqrt3 - vx3) + (1.0 - one_over_sqrt3 + vx3)*f[D3Q27System::BS]  ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::BS];
-      f[D3Q27System::BNE] = ftemp[D3Q27System::BNE] * (one_over_sqrt3 - vx3) + (1.0 - one_over_sqrt3 + vx3)*f[D3Q27System::BNE] ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::BNE];
-      f[D3Q27System::BNW] = ftemp[D3Q27System::BNW] * (one_over_sqrt3 - vx3) + (1.0 - one_over_sqrt3 + vx3)*f[D3Q27System::BNW] ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::BNW];
-      f[D3Q27System::BSE] = ftemp[D3Q27System::BSE] * (one_over_sqrt3 - vx3) + (1.0 - one_over_sqrt3 + vx3)*f[D3Q27System::BSE] ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::BSE];
-      f[D3Q27System::BSW] = ftemp[D3Q27System::BSW] * (one_over_sqrt3 - vx3) + (1.0 - one_over_sqrt3 + vx3)*f[D3Q27System::BSW] ;//- rho*dim*D3Q27System::WEIGTH[D3Q27System::BSW];
-
-      distributions->setDistributionInvForDirection(f[D3Q27System::B], x1, x2, x3, D3Q27System::B);
-      distributions->setDistributionInvForDirection(f[D3Q27System::BE], x1, x2, x3, D3Q27System::BE);
-      distributions->setDistributionInvForDirection(f[D3Q27System::BW], x1, x2, x3, D3Q27System::BW);
-      distributions->setDistributionInvForDirection(f[D3Q27System::BN], x1, x2, x3, D3Q27System::BN);
-      distributions->setDistributionInvForDirection(f[D3Q27System::BS], x1, x2, x3, D3Q27System::BS);
-      distributions->setDistributionInvForDirection(f[D3Q27System::BNE], x1, x2, x3, D3Q27System::BNE);
-      distributions->setDistributionInvForDirection(f[D3Q27System::BNW], x1, x2, x3, D3Q27System::BNW);
-      distributions->setDistributionInvForDirection(f[D3Q27System::BSE], x1, x2, x3, D3Q27System::BSE);
-      distributions->setDistributionInvForDirection(f[D3Q27System::BSW], x1, x2, x3, D3Q27System::BSW);
-      break;
-   default:
-      UB_THROW(UbException(UB_EXARGS, "It isn't implemented non reflecting density boundary for this direction!"));
-   }
-}
-
diff --git a/source/VirtualFluidsCore/BoundaryConditions/NonReflectingOutflowBCAlgorithm.cpp b/source/VirtualFluidsCore/BoundaryConditions/NonReflectingOutflowBCAlgorithm.cpp
new file mode 100644
index 000000000..129c1aa95
--- /dev/null
+++ b/source/VirtualFluidsCore/BoundaryConditions/NonReflectingOutflowBCAlgorithm.cpp
@@ -0,0 +1,185 @@
+#include "NonReflectingOutflowBCAlgorithm.h"
+#include <boost/pointer_cast.hpp>
+#include "D3Q27System.h"
+
+NonReflectingOutflowBCAlgorithm::NonReflectingOutflowBCAlgorithm()
+{
+   BCAlgorithm::type = BCAlgorithm::NonReflectingOutflowBCAlgorithm;
+   BCAlgorithm::preCollision = true;
+   step=0;
+}
+//////////////////////////////////////////////////////////////////////////
+NonReflectingOutflowBCAlgorithm::~NonReflectingOutflowBCAlgorithm()
+{
+}
+//////////////////////////////////////////////////////////////////////////
+BCAlgorithmPtr NonReflectingOutflowBCAlgorithm::clone()
+{
+   BCAlgorithmPtr bc(new NonReflectingOutflowBCAlgorithm());
+   return bc;
+}
+//////////////////////////////////////////////////////////////////////////
+void NonReflectingOutflowBCAlgorithm::addDistributions(DistributionArray3DPtr distributions)
+{
+   this->distributions = distributions;
+}
+//////////////////////////////////////////////////////////////////////////
+void NonReflectingOutflowBCAlgorithm::applyBC()
+{
+   using namespace D3Q27System;
+   LBMReal f[ENDF+1];
+   LBMReal ftemp[ENDF+1];
+
+   int nx1 = x1;
+   int nx2 = x2;
+   int nx3 = x3;
+   int direction = -1;
+
+   //flag points in direction of fluid
+   if      (bcPtr->hasDensityBoundaryFlag(E)) { nx1 += 1; direction = E; }
+   else if (bcPtr->hasDensityBoundaryFlag(W)) { nx1 -= 1; direction = W; }
+   else if (bcPtr->hasDensityBoundaryFlag(N)) { nx2 += 1; direction = N; }
+   else if (bcPtr->hasDensityBoundaryFlag(S)) { nx2 -= 1; direction = S; }
+   else if (bcPtr->hasDensityBoundaryFlag(T)) { nx3 += 1; direction = T; }
+   else if (bcPtr->hasDensityBoundaryFlag(B)) { nx3 -= 1; direction = B; }
+   else UB_THROW(UbException(UB_EXARGS, "Danger...no orthogonal BC-Flag on density boundary..."));
+
+   distributions->getDistribution(f, x1, x2, x3);
+   distributions->getDistribution(ftemp, nx1, nx2, nx3);
+
+   LBMReal rho, vx1, vx2, vx3;
+   calcMacrosFct(f, rho, vx1, vx2, vx3);
+
+   switch (direction)
+   {
+   case E:
+      f[E]   = ftemp[E]   * (one_over_sqrt3 + vx1) + (1.0 - one_over_sqrt3 - vx1)*f[E]   ;
+      f[NE]  = ftemp[NE]  * (one_over_sqrt3 + vx1) + (1.0 - one_over_sqrt3 - vx1)*f[NE]  ;
+      f[SE]  = ftemp[SE]  * (one_over_sqrt3 + vx1) + (1.0 - one_over_sqrt3 - vx1)*f[SE]  ;
+      f[TE]  = ftemp[TE]  * (one_over_sqrt3 + vx1) + (1.0 - one_over_sqrt3 - vx1)*f[TE]  ;
+      f[BE]  = ftemp[BE]  * (one_over_sqrt3 + vx1) + (1.0 - one_over_sqrt3 - vx1)*f[BE]  ;
+      f[TNE] = ftemp[TNE] * (one_over_sqrt3 + vx1) + (1.0 - one_over_sqrt3 - vx1)*f[TNE] ;
+      f[TSE] = ftemp[TSE] * (one_over_sqrt3 + vx1) + (1.0 - one_over_sqrt3 - vx1)*f[TSE] ;
+      f[BNE] = ftemp[BNE] * (one_over_sqrt3 + vx1) + (1.0 - one_over_sqrt3 - vx1)*f[BNE] ;
+      f[BSE] = ftemp[BSE] * (one_over_sqrt3 + vx1) + (1.0 - one_over_sqrt3 - vx1)*f[BSE] ;
+
+      distributions->setDistributionInvForDirection(f[E],   x1+DX1[W],   x2+DX2[W],   x3+DX3[W],   W);
+      distributions->setDistributionInvForDirection(f[NE],  x1+DX1[SW],  x2+DX2[SW],  x3+DX3[SW],  SW);
+      distributions->setDistributionInvForDirection(f[SE],  x1+DX1[NW],  x2+DX2[NW],  x3+DX3[NW],  NW);
+      distributions->setDistributionInvForDirection(f[TE],  x1+DX1[BW],  x2+DX2[BW],  x3+DX3[BW],  BW);
+      distributions->setDistributionInvForDirection(f[BE],  x1+DX1[TW],  x2+DX2[TW],  x3+DX3[TW],  TW);
+      distributions->setDistributionInvForDirection(f[TNE], x1+DX1[BSW], x2+DX2[BSW], x3+DX3[BSW], BSW);
+      distributions->setDistributionInvForDirection(f[TSE], x1+DX1[BNW], x2+DX2[BNW], x3+DX3[BNW], BNW);
+      distributions->setDistributionInvForDirection(f[BNE], x1+DX1[TSW], x2+DX2[TSW], x3+DX3[TSW], TSW);
+      distributions->setDistributionInvForDirection(f[BSE], x1+DX1[TNW], x2+DX2[TNW], x3+DX3[TNW], TNW);
+      break;
+   case W:
+      f[W]   = ftemp[W]   * (one_over_sqrt3 - vx1) + (1.0 - one_over_sqrt3 + vx1)*f[W]  ;
+      f[NW]  = ftemp[NW]  * (one_over_sqrt3 - vx1) + (1.0 - one_over_sqrt3 + vx1)*f[NW] ;
+      f[SW]  = ftemp[SW]  * (one_over_sqrt3 - vx1) + (1.0 - one_over_sqrt3 + vx1)*f[SW] ;
+      f[TW]  = ftemp[TW]  * (one_over_sqrt3 - vx1) + (1.0 - one_over_sqrt3 + vx1)*f[TW] ;
+      f[BW]  = ftemp[BW]  * (one_over_sqrt3 - vx1) + (1.0 - one_over_sqrt3 + vx1)*f[BW] ;
+      f[TNW] = ftemp[TNW] * (one_over_sqrt3 - vx1) + (1.0 - one_over_sqrt3 + vx1)*f[TNW];
+      f[TSW] = ftemp[TSW] * (one_over_sqrt3 - vx1) + (1.0 - one_over_sqrt3 + vx1)*f[TSW];
+      f[BNW] = ftemp[BNW] * (one_over_sqrt3 - vx1) + (1.0 - one_over_sqrt3 + vx1)*f[BNW];
+      f[BSW] = ftemp[BSW] * (one_over_sqrt3 - vx1) + (1.0 - one_over_sqrt3 + vx1)*f[BSW];
+
+      distributions->setDistributionInvForDirection(f[W],   x1+DX1[E],   x2+DX2[E],   x3+DX3[E],     E);
+      distributions->setDistributionInvForDirection(f[NW],  x1+DX1[SE],  x2+DX2[SE],  x3+DX3[SE],   SE);
+      distributions->setDistributionInvForDirection(f[SW],  x1+DX1[NE],  x2+DX2[NE],  x3+DX3[NE],   NE);
+      distributions->setDistributionInvForDirection(f[TW],  x1+DX1[BE],  x2+DX2[BE],  x3+DX3[BE],   BE);
+      distributions->setDistributionInvForDirection(f[BW],  x1+DX1[TE],  x2+DX2[TE],  x3+DX3[TE],   TE);
+      distributions->setDistributionInvForDirection(f[TNW], x1+DX1[BSE], x2+DX2[BSE], x3+DX3[BSE], BSE);
+      distributions->setDistributionInvForDirection(f[TSW], x1+DX1[BNE], x2+DX2[BNE], x3+DX3[BNE], BNE);
+      distributions->setDistributionInvForDirection(f[BNW], x1+DX1[TSE], x2+DX2[TSE], x3+DX3[TSE], TSE);
+      distributions->setDistributionInvForDirection(f[BSW], x1+DX1[TNE], x2+DX2[TNE], x3+DX3[TNE], TNE);
+      break;
+   case N:
+      f[N]   = ftemp[N]   * (one_over_sqrt3 + vx2) + (1.0 - one_over_sqrt3 - vx2)*f[N]   ;
+      f[NE]  = ftemp[NE]  * (one_over_sqrt3 + vx2) + (1.0 - one_over_sqrt3 - vx2)*f[NE]  ;
+      f[NW]  = ftemp[NW]  * (one_over_sqrt3 + vx2) + (1.0 - one_over_sqrt3 - vx2)*f[NW]  ;
+      f[TN]  = ftemp[TN]  * (one_over_sqrt3 + vx2) + (1.0 - one_over_sqrt3 - vx2)*f[TN]  ;
+      f[BN]  = ftemp[BN]  * (one_over_sqrt3 + vx2) + (1.0 - one_over_sqrt3 - vx2)*f[BN]  ;
+      f[TNE] = ftemp[TNE] * (one_over_sqrt3 + vx2) + (1.0 - one_over_sqrt3 - vx2)*f[TNE] ;
+      f[TNW] = ftemp[TNW] * (one_over_sqrt3 + vx2) + (1.0 - one_over_sqrt3 - vx2)*f[TNW] ;
+      f[BNE] = ftemp[BNE] * (one_over_sqrt3 + vx2) + (1.0 - one_over_sqrt3 - vx2)*f[BNE] ;
+      f[BNW] = ftemp[BNW] * (one_over_sqrt3 + vx2) + (1.0 - one_over_sqrt3 - vx2)*f[BNW] ;
+
+      distributions->setDistributionInvForDirection(f[N],   x1+DX1[S],   x2+DX2[S],   x3+DX3[S],     S);
+      distributions->setDistributionInvForDirection(f[NE],  x1+DX1[SW],  x2+DX2[SW],  x3+DX3[SW],   SW);
+      distributions->setDistributionInvForDirection(f[NW],  x1+DX1[SE],  x2+DX2[SE],  x3+DX3[SE],   SE);
+      distributions->setDistributionInvForDirection(f[TN],  x1+DX1[BS],  x2+DX2[BS],  x3+DX3[BS],   BS);
+      distributions->setDistributionInvForDirection(f[BN],  x1+DX1[TS],  x2+DX2[TS],  x3+DX3[TS],   TS);
+      distributions->setDistributionInvForDirection(f[TNE], x1+DX1[BSW], x2+DX2[BSW], x3+DX3[BSW], BSW);
+      distributions->setDistributionInvForDirection(f[TNW], x1+DX1[BSE], x2+DX2[BSE], x3+DX3[BSE], BSE);
+      distributions->setDistributionInvForDirection(f[BNE], x1+DX1[TSW], x2+DX2[TSW], x3+DX3[TSW], TSW);
+      distributions->setDistributionInvForDirection(f[BNW], x1+DX1[TSE], x2+DX2[TSE], x3+DX3[TSE], TSE);
+      break;
+   case S:
+      f[S]   = ftemp[S]   * (one_over_sqrt3 - vx2) + (1.0 - one_over_sqrt3 + vx2)*f[S]   ;
+      f[SE]  = ftemp[SE]  * (one_over_sqrt3 - vx2) + (1.0 - one_over_sqrt3 + vx2)*f[SE]  ;
+      f[SW]  = ftemp[SW]  * (one_over_sqrt3 - vx2) + (1.0 - one_over_sqrt3 + vx2)*f[SW]  ;
+      f[TS]  = ftemp[TS]  * (one_over_sqrt3 - vx2) + (1.0 - one_over_sqrt3 + vx2)*f[TS]  ;
+      f[BS]  = ftemp[BS]  * (one_over_sqrt3 - vx2) + (1.0 - one_over_sqrt3 + vx2)*f[BS]  ;
+      f[TSE] = ftemp[TSE] * (one_over_sqrt3 - vx2) + (1.0 - one_over_sqrt3 + vx2)*f[TSE] ;
+      f[TSW] = ftemp[TSW] * (one_over_sqrt3 - vx2) + (1.0 - one_over_sqrt3 + vx2)*f[TSW] ;
+      f[BSE] = ftemp[BSE] * (one_over_sqrt3 - vx2) + (1.0 - one_over_sqrt3 + vx2)*f[BSE] ;
+      f[BSW] = ftemp[BSW] * (one_over_sqrt3 - vx2) + (1.0 - one_over_sqrt3 + vx2)*f[BSW] ;
+
+      distributions->setDistributionInvForDirection(f[S],   x1+DX1[N],   x2+DX2[N],   x3+DX3[N],     N);
+      distributions->setDistributionInvForDirection(f[SE],  x1+DX1[NW],  x2+DX2[NW],  x3+DX3[NW],   NW);
+      distributions->setDistributionInvForDirection(f[SW],  x1+DX1[NE],  x2+DX2[NE],  x3+DX3[NE],   NE);
+      distributions->setDistributionInvForDirection(f[TS],  x1+DX1[BN],  x2+DX2[BN],  x3+DX3[BN],   BN);
+      distributions->setDistributionInvForDirection(f[BS],  x1+DX1[TN],  x2+DX2[TN],  x3+DX3[TN],   TN);
+      distributions->setDistributionInvForDirection(f[TSE], x1+DX1[BNW], x2+DX2[BNW], x3+DX3[BNW], BNW);
+      distributions->setDistributionInvForDirection(f[TSW], x1+DX1[BNE], x2+DX2[BNE], x3+DX3[BNE], BNE);
+      distributions->setDistributionInvForDirection(f[BSE], x1+DX1[TNW], x2+DX2[TNW], x3+DX3[TNW], TNW);
+      distributions->setDistributionInvForDirection(f[BSW], x1+DX1[TNE], x2+DX2[TNE], x3+DX3[TNE], TNE);
+      break;
+   case T:
+      f[T]   = ftemp[T]   * (one_over_sqrt3 + vx3) + (1.0 - one_over_sqrt3 - vx3)*f[T]   ;
+      f[TE]  = ftemp[TE]  * (one_over_sqrt3 + vx3) + (1.0 - one_over_sqrt3 - vx3)*f[TE]  ;
+      f[TW]  = ftemp[TW]  * (one_over_sqrt3 + vx3) + (1.0 - one_over_sqrt3 - vx3)*f[TW]  ;
+      f[TN]  = ftemp[TN]  * (one_over_sqrt3 + vx3) + (1.0 - one_over_sqrt3 - vx3)*f[TN]  ;
+      f[TS]  = ftemp[TS]  * (one_over_sqrt3 + vx3) + (1.0 - one_over_sqrt3 - vx3)*f[TS]  ;
+      f[TNE] = ftemp[TNE] * (one_over_sqrt3 + vx3) + (1.0 - one_over_sqrt3 - vx3)*f[TNE] ;
+      f[TNW] = ftemp[TNW] * (one_over_sqrt3 + vx3) + (1.0 - one_over_sqrt3 - vx3)*f[TNW] ;
+      f[TSE] = ftemp[TSE] * (one_over_sqrt3 + vx3) + (1.0 - one_over_sqrt3 - vx3)*f[TSE] ;
+      f[TSW] = ftemp[TSW] * (one_over_sqrt3 + vx3) + (1.0 - one_over_sqrt3 - vx3)*f[TSW] ;
+
+      distributions->setDistributionInvForDirection(f[T],   x1+DX1[B],   x2+DX2[B],   x3+DX3[B],     B);
+      distributions->setDistributionInvForDirection(f[TE],  x1+DX1[BW],  x2+DX2[BW],  x3+DX3[BW],   BW);
+      distributions->setDistributionInvForDirection(f[TW],  x1+DX1[BE],  x2+DX2[BE],  x3+DX3[BE],   BE);
+      distributions->setDistributionInvForDirection(f[TN],  x1+DX1[BS],  x2+DX2[BS],  x3+DX3[BS],   BS);
+      distributions->setDistributionInvForDirection(f[TS],  x1+DX1[BN],  x2+DX2[BN],  x3+DX3[BN],   BN);
+      distributions->setDistributionInvForDirection(f[TNE], x1+DX1[BSW], x2+DX2[BSW], x3+DX3[BSW], BSW);
+      distributions->setDistributionInvForDirection(f[TNW], x1+DX1[BSE], x2+DX2[BSE], x3+DX3[BSE], BSE);
+      distributions->setDistributionInvForDirection(f[TSE], x1+DX1[BNW], x2+DX2[BNW], x3+DX3[BNW], BNW);
+      distributions->setDistributionInvForDirection(f[TSW], x1+DX1[BNE], x2+DX2[BNE], x3+DX3[BNE], BNE);
+      break;
+   case B:
+      f[B]   = ftemp[B]   * (one_over_sqrt3 - vx3) + (1.0 - one_over_sqrt3 + vx3)*f[B]   ;
+      f[BE]  = ftemp[BE]  * (one_over_sqrt3 - vx3) + (1.0 - one_over_sqrt3 + vx3)*f[BE]  ;
+      f[BW]  = ftemp[BW]  * (one_over_sqrt3 - vx3) + (1.0 - one_over_sqrt3 + vx3)*f[BW]  ;
+      f[BN]  = ftemp[BN]  * (one_over_sqrt3 - vx3) + (1.0 - one_over_sqrt3 + vx3)*f[BN]  ;
+      f[BS]  = ftemp[BS]  * (one_over_sqrt3 - vx3) + (1.0 - one_over_sqrt3 + vx3)*f[BS]  ;
+      f[BNE] = ftemp[BNE] * (one_over_sqrt3 - vx3) + (1.0 - one_over_sqrt3 + vx3)*f[BNE] ;
+      f[BNW] = ftemp[BNW] * (one_over_sqrt3 - vx3) + (1.0 - one_over_sqrt3 + vx3)*f[BNW] ;
+      f[BSE] = ftemp[BSE] * (one_over_sqrt3 - vx3) + (1.0 - one_over_sqrt3 + vx3)*f[BSE] ;
+      f[BSW] = ftemp[BSW] * (one_over_sqrt3 - vx3) + (1.0 - one_over_sqrt3 + vx3)*f[BSW] ;
+
+      distributions->setDistributionInvForDirection(f[B],   x1+DX1[T],   x2+DX2[T],   x3+DX3[T],     T);
+      distributions->setDistributionInvForDirection(f[BE],  x1+DX1[TW],  x2+DX2[TW],  x3+DX3[TW],   TW);
+      distributions->setDistributionInvForDirection(f[BW],  x1+DX1[TE],  x2+DX2[TE],  x3+DX3[TE],   TE);
+      distributions->setDistributionInvForDirection(f[BN],  x1+DX1[TS],  x2+DX2[TS],  x3+DX3[TS],   TS);
+      distributions->setDistributionInvForDirection(f[BS],  x1+DX1[TN],  x2+DX2[TN],  x3+DX3[TN],   TN);
+      distributions->setDistributionInvForDirection(f[BNE], x1+DX1[TSW], x2+DX2[TSW], x3+DX3[TSW], TSW);
+      distributions->setDistributionInvForDirection(f[BNW], x1+DX1[TSE], x2+DX2[TSE], x3+DX3[TSE], TSE);
+      distributions->setDistributionInvForDirection(f[BSE], x1+DX1[TNW], x2+DX2[TNW], x3+DX3[TNW], TNW);
+      distributions->setDistributionInvForDirection(f[BSW], x1+DX1[TNE], x2+DX2[TNE], x3+DX3[TNE], TNE);
+      break;
+   default:
+      UB_THROW(UbException(UB_EXARGS, "It isn't implemented non reflecting density boundary for this direction!"));
+   }
+}
+
diff --git a/source/VirtualFluidsCore/BoundaryConditions/NonReflectingDensityBCAlgorithm.h b/source/VirtualFluidsCore/BoundaryConditions/NonReflectingOutflowBCAlgorithm.h
similarity index 52%
rename from source/VirtualFluidsCore/BoundaryConditions/NonReflectingDensityBCAlgorithm.h
rename to source/VirtualFluidsCore/BoundaryConditions/NonReflectingOutflowBCAlgorithm.h
index 69365de31..1b65b022d 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/NonReflectingDensityBCAlgorithm.h
+++ b/source/VirtualFluidsCore/BoundaryConditions/NonReflectingOutflowBCAlgorithm.h
@@ -1,21 +1,22 @@
-#ifndef NonReflectingDensityBCAlgorithm_h__
-#define NonReflectingDensityBCAlgorithm_h__
+#ifndef NonReflectingOutflowBCAlgorithm_h__
+#define NonReflectingOutflowBCAlgorithm_h__
 
 #include "BCAlgorithm.h"
 
-class NonReflectingDensityBCAlgorithm;
-typedef boost::shared_ptr<NonReflectingDensityBCAlgorithm> NonReflectingDensityBCAlgorithmPtr;
+class NonReflectingOutflowBCAlgorithm;
+typedef boost::shared_ptr<NonReflectingOutflowBCAlgorithm> NonReflectingOutflowBCAlgorithmPtr;
 
-class NonReflectingDensityBCAlgorithm : public BCAlgorithm
+class NonReflectingOutflowBCAlgorithm : public BCAlgorithm
 {
 public:
-   NonReflectingDensityBCAlgorithm();
-   ~NonReflectingDensityBCAlgorithm();
+   NonReflectingOutflowBCAlgorithm();
+   ~NonReflectingOutflowBCAlgorithm();
    BCAlgorithmPtr clone();
    void addDistributions(DistributionArray3DPtr distributions);
 protected:
    void applyBC();
 private:
+   int step;
    //friend class boost::serialization::access;
    //template<class Archive>
    //void serialize(Archive & ar, const unsigned int version)
diff --git a/source/VirtualFluidsCore/BoundaryConditions/NonReflectingSlipBCAlgorithm.cpp b/source/VirtualFluidsCore/BoundaryConditions/NonReflectingSlipBCAlgorithm.cpp
deleted file mode 100644
index cf6a30d15..000000000
--- a/source/VirtualFluidsCore/BoundaryConditions/NonReflectingSlipBCAlgorithm.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-#include "NonReflectingSlipBCAlgorithm.h"
-
-NonReflectingSlipBCAlgorithm::NonReflectingSlipBCAlgorithm()
-{
-   BCAlgorithm::type = BCAlgorithm::NonReflectingSlipBCAlgorithm;
-   BCAlgorithm::preCollision = false;
-}
-//////////////////////////////////////////////////////////////////////////
-NonReflectingSlipBCAlgorithm::~NonReflectingSlipBCAlgorithm()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-BCAlgorithmPtr NonReflectingSlipBCAlgorithm::clone()
-{
-   BCAlgorithmPtr bc(new NonReflectingSlipBCAlgorithm());
-   return bc;
-}
-//////////////////////////////////////////////////////////////////////////
-void NonReflectingSlipBCAlgorithm::addDistributions(DistributionArray3DPtr distributions)
-{
-   this->distributions = distributions;
-}
-//////////////////////////////////////////////////////////////////////////
-void NonReflectingSlipBCAlgorithm::applyBC()
-{
-   LBMReal f[D3Q27System::ENDF+1];
-   LBMReal feq[D3Q27System::ENDF+1];
-   distributions->getDistributionInv(f, x1, x2, x3);
-   LBMReal rho, vx1, vx2, vx3, drho;
-   calcMacrosFct(f, drho, vx1, vx2, vx3);
-   calcFeqFct(feq, drho, vx1, vx2, vx3);
-
-   UbTupleFloat3 normale = bcPtr->getNormalVector();
-   LBMReal amp = vx1*val<1>(normale)+vx2*val<2>(normale)+vx3*val<3>(normale);
-
-   vx1 = vx1-amp * val<1>(normale); //normale zeigt von struktur weg!
-   vx2 = vx2-amp * val<2>(normale); //normale zeigt von struktur weg!
-   vx3 = vx3-amp * val<3>(normale); //normale zeigt von struktur weg!
-
-   rho = 1.0+drho*compressibleFactor;
-
-   for (int fdir = D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
-   {
-      if (bcPtr->hasSlipBoundaryFlag(fdir))
-      {
-         //quadratic bounce back
-         const int invDir = D3Q27System::INVDIR[fdir];
-         LBMReal q = 1.0;//bcPtr->getQ(invDir);// m+m q=0 stabiler
-         //vx3=0;
-         LBMReal velocity = 0.0;
-         switch (invDir)
-         {
-         case D3Q27System::E: velocity = (UbMath::c4o9*(+vx1)); break;      //(2/cs^2)(=6)*rho_0(=1 bei imkompr)*wi*u*ei mit cs=1/sqrt(3)
-         case D3Q27System::W: velocity = (UbMath::c4o9*(-vx1)); break;      //z.B. aus paper manfred MRT LB models in three dimensions (2002)   
-         case D3Q27System::N: velocity = (UbMath::c4o9*(+vx2)); break;
-         case D3Q27System::S: velocity = (UbMath::c4o9*(-vx2)); break;
-         case D3Q27System::T: velocity = (UbMath::c4o9*(+vx3)); break;
-         case D3Q27System::B: velocity = (UbMath::c4o9*(-vx3)); break;
-         case D3Q27System::NE: velocity = (UbMath::c1o9*(+vx1+vx2)); break;
-         case D3Q27System::SW: velocity = (UbMath::c1o9*(-vx1-vx2)); break;
-         case D3Q27System::SE: velocity = (UbMath::c1o9*(+vx1-vx2)); break;
-         case D3Q27System::NW: velocity = (UbMath::c1o9*(-vx1+vx2)); break;
-         case D3Q27System::TE: velocity = (UbMath::c1o9*(+vx1+vx3)); break;
-         case D3Q27System::BW: velocity = (UbMath::c1o9*(-vx1-vx3)); break;
-         case D3Q27System::BE: velocity = (UbMath::c1o9*(+vx1-vx3)); break;
-         case D3Q27System::TW: velocity = (UbMath::c1o9*(-vx1+vx3)); break;
-         case D3Q27System::TN: velocity = (UbMath::c1o9*(+vx2+vx3)); break;
-         case D3Q27System::BS: velocity = (UbMath::c1o9*(-vx2-vx3)); break;
-         case D3Q27System::BN: velocity = (UbMath::c1o9*(+vx2-vx3)); break;
-         case D3Q27System::TS: velocity = (UbMath::c1o9*(-vx2+vx3)); break;
-         case D3Q27System::TNE: velocity = (UbMath::c1o36*(+vx1+vx2+vx3)); break;
-         case D3Q27System::BSW: velocity = (UbMath::c1o36*(-vx1-vx2-vx3)); break;
-         case D3Q27System::BNE: velocity = (UbMath::c1o36*(+vx1+vx2-vx3)); break;
-         case D3Q27System::TSW: velocity = (UbMath::c1o36*(-vx1-vx2+vx3)); break;
-         case D3Q27System::TSE: velocity = (UbMath::c1o36*(+vx1-vx2+vx3)); break;
-         case D3Q27System::BNW: velocity = (UbMath::c1o36*(-vx1+vx2-vx3)); break;
-         case D3Q27System::BSE: velocity = (UbMath::c1o36*(+vx1-vx2-vx3)); break;
-         case D3Q27System::TNW: velocity = (UbMath::c1o36*(-vx1+vx2+vx3)); break;
-         default: throw UbException(UB_EXARGS, "unknown error");
-         }
-         LBMReal fReturn = ((1.0 - q) / (1.0 + q))*((f[invDir] - feq[invDir]) / (1.0 - collFactor) + feq[invDir]) + ((q*(f[invDir] + f[fdir]) - velocity*rho) / (1.0 + q))-drho*D3Q27System::WEIGTH[invDir];
-         distributions->setDistributionForDirection(fReturn, x1+D3Q27System::DX1[invDir], x2+D3Q27System::DX2[invDir], x3+D3Q27System::DX3[invDir], fdir);
-      }
-   }
-}
\ No newline at end of file
diff --git a/source/VirtualFluidsCore/BoundaryConditions/NonReflectingSlipBCAlgorithm.h b/source/VirtualFluidsCore/BoundaryConditions/NonReflectingSlipBCAlgorithm.h
deleted file mode 100644
index 597f9e2ea..000000000
--- a/source/VirtualFluidsCore/BoundaryConditions/NonReflectingSlipBCAlgorithm.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef NonReflectingSlipBCAlgorithm_h__
-#define NonReflectingSlipBCAlgorithm_h__
-
-#include "BCAlgorithm.h"
-
-class NonReflectingSlipBCAlgorithm;
-typedef boost::shared_ptr<NonReflectingSlipBCAlgorithm> NonReflectingSlipBCAlgorithmPtr;
-
-class NonReflectingSlipBCAlgorithm : public BCAlgorithm
-{
-public:
-   NonReflectingSlipBCAlgorithm();
-   virtual ~NonReflectingSlipBCAlgorithm();
-   BCAlgorithmPtr clone();
-   void addDistributions(DistributionArray3DPtr distributions);
-protected:
-   void applyBC();
-private:
-   //friend class boost::serialization::access;
-   //template<class Archive>
-   //void serialize(Archive & ar, const unsigned int version)
-   //{
-   //   ar & boost::serialization::base_object<BCAlgorithm>(*this);
-   //}
-};
-#endif // NonReflectingSlipBCAlgorithm_h__
-
diff --git a/source/VirtualFluidsCore/BoundaryConditions/NonReflectingVelocityBCAlgorithm.cpp b/source/VirtualFluidsCore/BoundaryConditions/NonReflectingVelocityBCAlgorithm.cpp
deleted file mode 100644
index 0c6ad8db8..000000000
--- a/source/VirtualFluidsCore/BoundaryConditions/NonReflectingVelocityBCAlgorithm.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-#include "NonReflectingVelocityBCAlgorithm.h"
-
-NonReflectingVelocityBCAlgorithm::NonReflectingVelocityBCAlgorithm()
-{
-   BCAlgorithm::type = BCAlgorithm::NonReflectingVelocityBCAlgorithm;
-   BCAlgorithm::preCollision = false;
-}
-//////////////////////////////////////////////////////////////////////////
-NonReflectingVelocityBCAlgorithm::~NonReflectingVelocityBCAlgorithm()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-BCAlgorithmPtr NonReflectingVelocityBCAlgorithm::clone()
-{
-   BCAlgorithmPtr bc(new NonReflectingVelocityBCAlgorithm());
-   return bc;
-}
-//////////////////////////////////////////////////////////////////////////
-void NonReflectingVelocityBCAlgorithm::addDistributions(DistributionArray3DPtr distributions)
-{
-   this->distributions = distributions;
-}
-//////////////////////////////////////////////////////////////////////////
-void NonReflectingVelocityBCAlgorithm::applyBC()
-{
-   //velocity bc for non reflecting pressure bc
-   LBMReal f[D3Q27System::ENDF+1];
-   LBMReal feq[D3Q27System::ENDF+1];
-   distributions->getDistributionInv(f, x1, x2, x3);
-   LBMReal rho, vx1, vx2, vx3, drho;
-   calcMacrosFct(f, drho, vx1, vx2, vx3);
-   calcFeqFct(feq, drho, vx1, vx2, vx3);
-   
-   //if (compressible)
-   //{
-   //   rho = 1.0+drho;
-   //}
-   //else
-   //{
-   //   rho = 1.0;
-   //}
-
-   rho = 1.0+drho*compressibleFactor;
-
-   for (int fdir = D3Q27System::FSTARTDIR; fdir <= D3Q27System::FENDDIR; fdir++)
-   {
-      if (bcPtr->hasVelocityBoundaryFlag(fdir))
-      {
-         const int invDir = D3Q27System::INVDIR[fdir];
-         LBMReal q = 1.0;//bcPtr->getQ(invDir);// m+m q=0 stabiler
-         LBMReal velocity = bcPtr->getBoundaryVelocity(invDir);
-         //LBMReal fReturn = ((1.0-q)/(1.0+q))*((ftemp[invDir]-feq[invDir]*collFactor)/(1.0-collFactor))+((q*(ftemp[invDir]+ftemp[fdir])-velocity)/(1.0+q));
-         //LBMReal fReturn = ((1.0 - q) / (1.0 + q))*((f[invDir] - feq[invDir]) / (1.0 - collFactor) + feq[invDir]) + ((q*(f[invDir] + f[fdir]) - velocity) / (1.0 + q))-drho*D3Q27System::WEIGTH[invDir];
-         LBMReal fReturn = ((1.0 - q) / (1.0 + q))*((f[invDir] - feq[invDir]) / (1.0 - collFactor) + feq[invDir]) + ((q*(f[invDir] + f[fdir]) - velocity*rho) / (1.0 + q))-drho*D3Q27System::WEIGTH[invDir];
-         distributions->setDistributionForDirection(fReturn, x1 + D3Q27System::DX1[invDir], x2 + D3Q27System::DX2[invDir], x3 + D3Q27System::DX3[invDir], fdir);
-      }
-   }
-}
diff --git a/source/VirtualFluidsCore/BoundaryConditions/SlipBCAlgorithm.cpp b/source/VirtualFluidsCore/BoundaryConditions/SlipBCAlgorithm.cpp
index 118dcba5f..5937fa2b3 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/SlipBCAlgorithm.cpp
+++ b/source/VirtualFluidsCore/BoundaryConditions/SlipBCAlgorithm.cpp
@@ -46,7 +46,7 @@ void SlipBCAlgorithm::applyBC()
       {
          //quadratic bounce back
          const int invDir = D3Q27System::INVDIR[fdir];
-         LBMReal q = 1.0;//bcPtr->getQ(invDir);// m+m q=0 stabiler
+         LBMReal q = bcPtr->getQ(invDir);// m+m q=0 stabiler
          //vx3=0;
          LBMReal velocity = 0.0;
          switch (invDir)
diff --git a/source/VirtualFluidsCore/BoundaryConditions/VelocityWithDensityBCAlgorithm.cpp b/source/VirtualFluidsCore/BoundaryConditions/VelocityWithDensityBCAlgorithm.cpp
new file mode 100644
index 000000000..dcc2a4fe1
--- /dev/null
+++ b/source/VirtualFluidsCore/BoundaryConditions/VelocityWithDensityBCAlgorithm.cpp
@@ -0,0 +1,82 @@
+#include "VelocityWithDensityBCAlgorithm.h"
+
+VelocityWithDensityBCAlgorithm::VelocityWithDensityBCAlgorithm()
+{
+   BCAlgorithm::type = BCAlgorithm::VelocityWithDensityBCAlgorithm;
+   BCAlgorithm::preCollision = false;
+}
+//////////////////////////////////////////////////////////////////////////
+VelocityWithDensityBCAlgorithm::~VelocityWithDensityBCAlgorithm()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+BCAlgorithmPtr VelocityWithDensityBCAlgorithm::clone()
+{
+   BCAlgorithmPtr bc(new VelocityWithDensityBCAlgorithm());
+   return bc;
+}
+//////////////////////////////////////////////////////////////////////////
+void VelocityWithDensityBCAlgorithm::addDistributions(DistributionArray3DPtr distributions)
+{
+   this->distributions = distributions;
+}
+//////////////////////////////////////////////////////////////////////////
+void VelocityWithDensityBCAlgorithm::applyBC()
+{
+   //velocity bc for non reflecting pressure bc
+   LBMReal f[D3Q27System::ENDF+1];
+   LBMReal feq[D3Q27System::ENDF+1];
+   distributions->getDistributionInv(f, x1, x2, x3);
+   LBMReal rho, vx1, vx2, vx3, drho;
+   calcMacrosFct(f, drho, vx1, vx2, vx3);
+   calcFeqFct(feq, drho, vx1, vx2, vx3);
+   
+   rho = 1.0+drho*compressibleFactor;
+
+   for (int fdir = D3Q27System::FSTARTDIR; fdir <= D3Q27System::FENDDIR; fdir++)
+   {
+      //if (bcPtr->hasVelocityBoundaryFlag(fdir))
+      //{
+      //   const int invDir = D3Q27System::INVDIR[fdir];
+      //   LBMReal q = bcPtr->getQ(invDir);// m+m q=0 stabiler
+      //   LBMReal velocity = bcPtr->getBoundaryVelocity(invDir);
+      //   //normal velocity bc: LBMReal fReturn = ((1.0-q)/(1.0+q))*((f[invDir]-feq[invDir])/(1.0-collFactor)+feq[invDir])+((q*(f[invDir]+f[fdir])-velocity*rho)/(1.0+q));
+      //   //LBMReal fReturn = ((1.0 - q) / (1.0 + q))*((f[invDir] - feq[invDir]) / (1.0 - collFactor) + feq[invDir]) + ((q*(f[invDir] + f[fdir]) - velocity) / (1.0 + q))-drho*D3Q27System::WEIGTH[invDir];
+      //   //LBMReal fReturn = ((1.0 - q) / (1.0 + q))*((f[invDir] - feq[invDir]) / (1.0 - collFactor) + feq[invDir]) + ((q*(f[invDir] + f[fdir]) - velocity*rho) / (1.0 + q))-drho*D3Q27System::WEIGTH[invDir];
+      //   LBMReal fReturn = ((1.0 - q) / (1.0 + q))*((f[invDir] - feq[invDir]*collFactor) / (1.0 - collFactor)) + ((q*(f[invDir] + f[fdir]) - velocity*rho) / (1.0 + q))-drho*D3Q27System::WEIGTH[invDir];
+      //   
+      //   distributions->setDistributionForDirection(fReturn, x1 + D3Q27System::DX1[invDir], x2 + D3Q27System::DX2[invDir], x3 + D3Q27System::DX3[invDir], fdir);
+      //}
+      
+      int nX1 = x1 + D3Q27System::DX1[fdir];
+      int nX2 = x2 + D3Q27System::DX2[fdir];
+      int nX3 = x3 + D3Q27System::DX3[fdir];
+
+      int minX1 = 0;
+      int minX2 = 0;
+      int minX3 = 0;
+
+      int maxX1 = (int)bcArray->getNX1();
+      int maxX2 = (int)bcArray->getNX2();
+      int maxX3 = (int)bcArray->getNX3();
+
+      if (minX1 <= nX1 && maxX1 > nX1 && minX2 <= nX2 && maxX2 > nX2 && minX3 <= nX3 && maxX3 > nX3)
+      {
+         if (bcArray->isSolid(nX1,nX2,nX3))
+         {
+            const int invDir = D3Q27System::INVDIR[fdir];
+            LBMReal q =1.0;// bcPtr->getQ(invDir);// m+m q=0 stabiler
+            LBMReal velocity = bcPtr->getBoundaryVelocity(fdir);
+            //LBMReal fReturn = ((1.0 - q) / (1.0 + q))*((f[fdir] - feq[fdir]*collFactor) / (1.0 - collFactor)) + ((q*(f[fdir] + f[invDir]) - velocity*rho) / (1.0 + q))-drho*D3Q27System::WEIGTH[invDir];
+
+            //if q=1
+            //LBMReal fReturn = ((q*(f[fdir] + f[invDir]) - velocity*rho) / (1.0 + q))-drho*D3Q27System::WEIGTH[invDir];
+            LBMReal fReturn = (f[fdir] + f[invDir] - velocity*rho) / 2.0 - drho*D3Q27System::WEIGTH[invDir];
+
+            distributions->setDistributionForDirection(fReturn, nX1, nX2, nX3, invDir);
+         }
+      }
+
+   }
+}
diff --git a/source/VirtualFluidsCore/BoundaryConditions/NonReflectingVelocityBCAlgorithm.h b/source/VirtualFluidsCore/BoundaryConditions/VelocityWithDensityBCAlgorithm.h
similarity index 52%
rename from source/VirtualFluidsCore/BoundaryConditions/NonReflectingVelocityBCAlgorithm.h
rename to source/VirtualFluidsCore/BoundaryConditions/VelocityWithDensityBCAlgorithm.h
index d2bb80487..978a9b006 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/NonReflectingVelocityBCAlgorithm.h
+++ b/source/VirtualFluidsCore/BoundaryConditions/VelocityWithDensityBCAlgorithm.h
@@ -2,21 +2,21 @@
 //!  \brief Class implements velocity bc for non reflecting pressure bc.
 //!  \author Konstantin Kutscher
 
-#ifndef NonReflectingVelocityBCAlgorithm_h__
-#define NonReflectingVelocityBCAlgorithm_h__
+#ifndef VelocityWithDensityBCAlgorithm_h__
+#define VelocityWithDensityBCAlgorithm_h__
 
 #include "BCAlgorithm.h"
 
-class NonReflectingVelocityBCAlgorithm;
-typedef boost::shared_ptr<NonReflectingVelocityBCAlgorithm> NonReflectingVelocityBCAlgorithmPtr;
+class VelocityWithDensityBCAlgorithm;
+typedef boost::shared_ptr<VelocityWithDensityBCAlgorithm> VelocityWithDensityBCAlgorithmPtr;
 
-//!  \brief Class implements velocity boundary condition for non reflecting pressure boundary condition
+//!  \brief Class implements Dirichlet boundary condition for velocity. Set density in system. It is used together with non reflecting outflow.  
 
-class NonReflectingVelocityBCAlgorithm : public BCAlgorithm
+class VelocityWithDensityBCAlgorithm : public BCAlgorithm
 {
 public:
-   NonReflectingVelocityBCAlgorithm();
-   ~NonReflectingVelocityBCAlgorithm();
+   VelocityWithDensityBCAlgorithm();
+   ~VelocityWithDensityBCAlgorithm();
    BCAlgorithmPtr clone();
    void addDistributions(DistributionArray3DPtr distributions);
 protected:
diff --git a/source/VirtualFluidsCore/CoProcessors/CalculateForcesCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/CalculateForcesCoProcessor.cpp
index 09546391c..3a45b5ce6 100644
--- a/source/VirtualFluidsCore/CoProcessors/CalculateForcesCoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/CalculateForcesCoProcessor.cpp
@@ -15,12 +15,12 @@ CalculateForcesCoProcessor::CalculateForcesCoProcessor( Grid3DPtr grid, UbSchedu
    {
       std::ofstream ostr;
       std::string fname = path;
-      ostr.open(fname.c_str(), std::ios_base::out);
+      ostr.open(fname.c_str(), std::ios_base::out | std::ios_base::app);
       if(!ostr)
       { 
          ostr.clear();
          std::string path = UbSystem::getPathFromString(fname);
-         if(path.size()>0){ UbSystem::makeDirectory(path); ostr.open(fname.c_str(), std::ios_base::out);}
+         if(path.size()>0){ UbSystem::makeDirectory(path); ostr.open(fname.c_str(), std::ios_base::out | std::ios_base::app);}
          if(!ostr) throw UbException(UB_EXARGS,"couldn't open file "+fname);
       }
       ostr.width(12);
diff --git a/source/VirtualFluidsCore/CoProcessors/MPIIORestart2CoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/MPIIORestart2CoProcessor.cpp
new file mode 100644
index 000000000..cede788f1
--- /dev/null
+++ b/source/VirtualFluidsCore/CoProcessors/MPIIORestart2CoProcessor.cpp
@@ -0,0 +1,1154 @@
+#include "MPIIORestart2CoProcessor.h"
+#include <boost/foreach.hpp>
+#include "D3Q27System.h"
+#include "CompressibleCumulantLBMKernel.h"
+#include "D3Q27EsoTwist3DSplittedVector.h"
+#include <UbSystem.h>
+#include <MemoryUtil.h>
+
+MPIIORestart2CoProcessor::MPIIORestart2CoProcessor(Grid3DPtr grid, UbSchedulerPtr s,
+   const std::string& path,
+   CommunicatorPtr comm) :
+   CoProcessor(grid, s),
+   path(path),
+   comm(comm),
+   mpiTypeFreeFlag(false)
+{
+   UbSystem::makeDirectory(path+"/mpi_io_cp");
+
+   memset(&blockParamStr, 0, sizeof(blockParamStr));
+
+   //-------------------------   define MPI types  ---------------------------------
+
+   MPI_Datatype typesGP[3] = { MPI_DOUBLE, MPI_INT, MPI_CHAR };
+   int blocksGP[3] = { 34, 6, 5 };
+   MPI_Aint offsetsGP[3], lbGP, extentGP;
+
+   offsetsGP[0] = 0;
+   MPI_Type_get_extent(MPI_DOUBLE, &lbGP, &extentGP);
+   offsetsGP[1] = blocksGP[0]*extentGP;
+
+   MPI_Type_get_extent(MPI_INT, &lbGP, &extentGP);
+   offsetsGP[2] = offsetsGP[1]+blocksGP[1]*extentGP;
+
+   MPI_Type_struct(3, blocksGP, offsetsGP, typesGP, &gridParamType);
+   MPI_Type_commit(&gridParamType);
+
+   //-----------------------------------------------------------------------
+
+   MPI_Type_contiguous(41, MPI_INT, &blockParamType);
+   MPI_Type_commit(&blockParamType);
+
+   //-----------------------------------------------------------------------
+
+   MPI_Datatype typesBlock[2] = { MPI_INT, MPI_CHAR };
+   int blocksBlock[2] = { 13, 1 };
+   MPI_Aint offsetsBlock[2], lbBlock, extentBlock;
+
+   offsetsBlock[0] = 0;
+   MPI_Type_get_extent(MPI_INT, &lbBlock, &extentBlock);
+   offsetsBlock[1] = blocksBlock[0]*extentBlock;
+
+   MPI_Type_create_struct(2, blocksBlock, offsetsBlock, typesBlock, &block3dType);
+   MPI_Type_commit(&block3dType);
+
+   //-----------------------------------------------------------------------
+
+   MPI_Datatype typesDataSet[3] = { MPI_DOUBLE, MPI_INT, MPI_CHAR };
+   int blocksDataSet[3] = { 2, 2, 2 };
+   MPI_Aint offsetsDatatSet[3], lbDataSet, extentDataSet;
+
+   offsetsDatatSet[0] = 0;
+   MPI_Type_get_extent(MPI_DOUBLE, &lbDataSet, &extentDataSet);
+   offsetsDatatSet[1] = blocksDataSet[0]*extentDataSet;
+
+   MPI_Type_get_extent(MPI_INT, &lbDataSet, &extentDataSet);
+   offsetsDatatSet[2] = offsetsDatatSet[1]+blocksDataSet[1]*extentDataSet;
+
+   MPI_Type_create_struct(3, blocksDataSet, offsetsDatatSet, typesDataSet, &dataSetType);
+   MPI_Type_commit(&dataSetType);
+
+   //-----------------------------------------------------------------------
+
+   MPI_Datatype typesBC[3] = { MPI_LONG_LONG_INT, MPI_FLOAT, MPI_CHAR };
+   int blocksBC[3] = { 5, 39, 1 };
+   MPI_Aint offsetsBC[3], lbBC, extentBC;
+
+   offsetsBC[0] = 0;
+   MPI_Type_get_extent(MPI_LONG_LONG_INT, &lbBC, &extentBC);
+   offsetsBC[1] = blocksBC[0]*extentBC;
+
+   MPI_Type_get_extent(MPI_FLOAT, &lbBC, &extentBC);
+   offsetsBC[2] = blocksBC[1]*extentBC;
+
+   MPI_Type_create_struct(3, blocksBC, offsetsBC, typesBC, &boundCondType);
+   MPI_Type_commit(&boundCondType);
+
+   //---------------------------------------
+
+   MPI_Type_contiguous(3, MPI_INT, &boundCondTypeAdd);
+   MPI_Type_commit(&boundCondTypeAdd);
+
+}
+//////////////////////////////////////////////////////////////////////////
+MPIIORestart2CoProcessor::~MPIIORestart2CoProcessor()
+{
+   MPI_Type_free(&gridParamType);
+   MPI_Type_free(&blockParamType);
+   MPI_Type_free(&block3dType);
+   MPI_Type_free(&dataSetType);
+   MPI_Type_free(&boundCondType);
+   MPI_Type_free(&boundCondTypeAdd);
+
+   if (mpiTypeFreeFlag)
+   {
+      MPI_Type_free(&dataSetDoubleType);
+      MPI_Type_free(&bcindexmatrixType);
+   }
+}
+
+//////////////////////////////////////////////////////////////////////////
+void MPIIORestart2CoProcessor::process(double step)
+{
+   if (scheduler->isDue(step))
+   {
+      if (comm->isRoot()) UBLOG(logINFO, "MPIIORestart2CoProcessor save step: "<<step);
+      if (comm->isRoot()) UBLOG(logINFO, "Save check point - start");
+      writeBlocks((int)step);
+      writeDataSet((int)step);
+      writeBoundaryConds((int)step);
+      if (comm->isRoot()) UBLOG(logINFO, "Save check point - end");
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void MPIIORestart2CoProcessor::writeBlocks(int step)
+{
+   int rank, size;
+   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+   //MPI_Comm_size(MPI_COMM_WORLD, &size);
+   size=1;
+   MPI_File file_handler;
+
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestart2CoProcessor::writeBlocks start collect data rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
+
+   MPI_Info info = MPI_INFO_NULL;
+   //MPI_Info_create (&info);
+   //MPI_Info_set(info,"romio_cb_write","enable");
+   //MPI_Info_set(info,"cb_buffer_size","4194304");
+   //MPI_Info_set(info,"striping_unit","4194304");
+
+  // if (comm->isRoot())
+  // {
+      UbSystem::makeDirectory(path+"/mpi_io_cp/mpi_io_cp_"+UbSystem::toString(step));
+      std::string filename = path+"/mpi_io_cp/mpi_io_cp_"+UbSystem::toString(step)+"/cpBlocks.bin";
+      int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE|MPI_MODE_WRONLY, MPI_INFO_NULL, &file_handler);
+      if (rc!=MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file "+filename);
+  // }
+
+   int blocksCount = 0; // quantity of all the blocks in the grid, max 2147483648 blocks!
+   int minInitLevel = this->grid->getCoarsestInitializedLevel();
+   int maxInitLevel = this->grid->getFinestInitializedLevel();
+
+   std::vector<Block3DPtr> blocksVector[25]; // max 25 levels
+   for (int level = minInitLevel; level<=maxInitLevel; level++)
+   {
+      //grid->getBlocks(level, rank, blockVector[level]);
+      grid->getBlocks(level, blocksVector[level]);
+      blocksCount += static_cast<int>(blocksVector[level].size());
+   }
+
+   GridParam* gridParameters = new GridParam;
+   gridParameters->trafoParams[0] = grid->getCoordinateTransformator()->Tx1;
+   gridParameters->trafoParams[1] = grid->getCoordinateTransformator()->Tx2;
+   gridParameters->trafoParams[2] = grid->getCoordinateTransformator()->Tx3;
+   gridParameters->trafoParams[3] = grid->getCoordinateTransformator()->Sx1;
+   gridParameters->trafoParams[4] = grid->getCoordinateTransformator()->Sx2;
+   gridParameters->trafoParams[5] = grid->getCoordinateTransformator()->Sx3;
+   gridParameters->trafoParams[6] = grid->getCoordinateTransformator()->alpha;
+   gridParameters->trafoParams[7] = grid->getCoordinateTransformator()->beta;
+   gridParameters->trafoParams[8] = grid->getCoordinateTransformator()->gamma;
+
+   gridParameters->trafoParams[9] = grid->getCoordinateTransformator()->toX1factorX1;
+   gridParameters->trafoParams[10] = grid->getCoordinateTransformator()->toX1factorX2;
+   gridParameters->trafoParams[11] = grid->getCoordinateTransformator()->toX1factorX3;
+   gridParameters->trafoParams[12] = grid->getCoordinateTransformator()->toX1delta;
+   gridParameters->trafoParams[13] = grid->getCoordinateTransformator()->toX2factorX1;
+   gridParameters->trafoParams[14] = grid->getCoordinateTransformator()->toX2factorX2;
+   gridParameters->trafoParams[15] = grid->getCoordinateTransformator()->toX2factorX3;
+   gridParameters->trafoParams[16] = grid->getCoordinateTransformator()->toX2delta;
+   gridParameters->trafoParams[17] = grid->getCoordinateTransformator()->toX3factorX1;
+   gridParameters->trafoParams[18] = grid->getCoordinateTransformator()->toX3factorX2;
+   gridParameters->trafoParams[19] = grid->getCoordinateTransformator()->toX3factorX3;
+   gridParameters->trafoParams[20] = grid->getCoordinateTransformator()->toX3delta;
+
+   gridParameters->trafoParams[21] = grid->getCoordinateTransformator()->fromX1factorX1;
+   gridParameters->trafoParams[22] = grid->getCoordinateTransformator()->fromX1factorX2;
+   gridParameters->trafoParams[23] = grid->getCoordinateTransformator()->fromX1factorX3;
+   gridParameters->trafoParams[24] = grid->getCoordinateTransformator()->fromX1delta;
+   gridParameters->trafoParams[25] = grid->getCoordinateTransformator()->fromX2factorX1;
+   gridParameters->trafoParams[26] = grid->getCoordinateTransformator()->fromX2factorX2;
+   gridParameters->trafoParams[27] = grid->getCoordinateTransformator()->fromX2factorX3;
+   gridParameters->trafoParams[28] = grid->getCoordinateTransformator()->fromX2delta;
+   gridParameters->trafoParams[29] = grid->getCoordinateTransformator()->fromX3factorX1;
+   gridParameters->trafoParams[30] = grid->getCoordinateTransformator()->fromX3factorX2;
+   gridParameters->trafoParams[31] = grid->getCoordinateTransformator()->fromX3factorX3;
+   gridParameters->trafoParams[32] = grid->getCoordinateTransformator()->fromX3delta;
+
+   gridParameters->active = grid->getCoordinateTransformator()->active;
+   gridParameters->transformation = grid->getCoordinateTransformator()->transformation;
+
+   gridParameters->deltaX = grid->getDeltaX(minInitLevel);
+   UbTupleInt3 blocknx = grid->getBlockNX();
+   gridParameters->blockNx1 = val<1>(blocknx);
+   gridParameters->blockNx2 = val<2>(blocknx);
+   gridParameters->blockNx3 = val<3>(blocknx);
+   gridParameters->nx1 = grid->getNX1();
+   gridParameters->nx2 = grid->getNX2();
+   gridParameters->nx3 = grid->getNX3();
+   gridParameters->periodicX1 = grid->isPeriodicX1();
+   gridParameters->periodicX2 = grid->isPeriodicX2();
+   gridParameters->periodicX3 = grid->isPeriodicX3();
+
+   //----------------------------------------------------------------------
+
+   Block3d* block3dArray = new Block3d[blocksCount];
+   bool firstBlock = true;
+   int ic = 0;
+   for (int level = minInitLevel; level<=maxInitLevel; level++)
+   {
+      BOOST_FOREACH(Block3DPtr block, blocksVector[level])  //	all the blocks of the current level
+      {
+         if (firstBlock && block->getKernel()) // when first (any) valid block...
+         {
+            boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageValuesArray3DPtr = block->getKernel()->getDataSet()->getAverageValues();
+            if (AverageValuesArray3DPtr)
+            {
+               blockParamStr.nx[0][0] = static_cast<int>(AverageValuesArray3DPtr->getNX1());
+               blockParamStr.nx[0][1] = static_cast<int>(AverageValuesArray3DPtr->getNX2());
+               blockParamStr.nx[0][2] = static_cast<int>(AverageValuesArray3DPtr->getNX3());
+               blockParamStr.nx[0][3] = static_cast<int>(AverageValuesArray3DPtr->getNX4());
+            }
+
+            boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageVelocityArray3DPtr = block->getKernel()->getDataSet()->getAverageVelocity();
+            if (AverageVelocityArray3DPtr)
+            {
+               blockParamStr.nx[1][0] = static_cast<int>(AverageVelocityArray3DPtr->getNX1());
+               blockParamStr.nx[1][1] = static_cast<int>(AverageVelocityArray3DPtr->getNX2());
+               blockParamStr.nx[1][2] = static_cast<int>(AverageVelocityArray3DPtr->getNX3());
+               blockParamStr.nx[1][3] = static_cast<int>(AverageVelocityArray3DPtr->getNX4());
+            }
+
+            boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageFluctArray3DPtr = block->getKernel()->getDataSet()->getAverageFluctuations();
+            if (AverageFluctArray3DPtr)
+            {
+               blockParamStr.nx[2][0] = static_cast<int>(AverageFluctArray3DPtr->getNX1());
+               blockParamStr.nx[2][1] = static_cast<int>(AverageFluctArray3DPtr->getNX2());
+               blockParamStr.nx[2][2] = static_cast<int>(AverageFluctArray3DPtr->getNX3());
+               blockParamStr.nx[2][3] = static_cast<int>(AverageFluctArray3DPtr->getNX4());
+            }
+
+            boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageTripleArray3DPtr = block->getKernel()->getDataSet()->getAverageTriplecorrelations();
+            if (AverageTripleArray3DPtr)
+            {
+               blockParamStr.nx[3][0] = static_cast<int>(AverageTripleArray3DPtr->getNX1());
+               blockParamStr.nx[3][1] = static_cast<int>(AverageTripleArray3DPtr->getNX2());
+               blockParamStr.nx[3][2] = static_cast<int>(AverageTripleArray3DPtr->getNX3());
+               blockParamStr.nx[3][3] = static_cast<int>(AverageTripleArray3DPtr->getNX4());
+            }
+
+            boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > ShearStressValArray3DPtr = block->getKernel()->getDataSet()->getShearStressValues();
+            if (ShearStressValArray3DPtr)
+            {
+               blockParamStr.nx[4][0] = static_cast<int>(ShearStressValArray3DPtr->getNX1());
+               blockParamStr.nx[4][1] = static_cast<int>(ShearStressValArray3DPtr->getNX2());
+               blockParamStr.nx[4][2] = static_cast<int>(ShearStressValArray3DPtr->getNX3());
+               blockParamStr.nx[4][3] = static_cast<int>(ShearStressValArray3DPtr->getNX4());
+            }
+
+            boost::shared_ptr< CbArray3D<LBMReal, IndexerX3X2X1> > relaxationFactor3DPtr = block->getKernel()->getDataSet()->getRelaxationFactor();
+            if (relaxationFactor3DPtr)
+            {
+               blockParamStr.nx[5][0] = static_cast<int>(relaxationFactor3DPtr->getNX1());
+               blockParamStr.nx[5][1] = static_cast<int>(relaxationFactor3DPtr->getNX2());
+               blockParamStr.nx[5][2] = static_cast<int>(relaxationFactor3DPtr->getNX3());
+               blockParamStr.nx[5][3] = 1;
+            }
+
+            boost::shared_ptr< D3Q27EsoTwist3DSplittedVector > D3Q27EsoTwist3DSplittedVectorPtr = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(block->getKernel()->getDataSet()->getFdistributions());
+            CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getLocalDistributions();
+            if (localDistributions)
+            {
+               blockParamStr.nx[6][0] = static_cast<int>(localDistributions->getNX1());
+               blockParamStr.nx[6][1] = static_cast<int>(localDistributions->getNX2());
+               blockParamStr.nx[6][2] = static_cast<int>(localDistributions->getNX3());
+               blockParamStr.nx[6][3] = static_cast<int>(localDistributions->getNX4());
+            }
+
+            CbArray4D <LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getNonLocalDistributions();
+            if (nonLocalDistributions)
+            {
+               blockParamStr.nx[7][0] = static_cast<int>(nonLocalDistributions->getNX1());
+               blockParamStr.nx[7][1] = static_cast<int>(nonLocalDistributions->getNX2());
+               blockParamStr.nx[7][2] = static_cast<int>(nonLocalDistributions->getNX3());
+               blockParamStr.nx[7][3] = static_cast<int>(nonLocalDistributions->getNX4());
+            }
+
+            CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr zeroDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getZeroDistributions();
+            if (zeroDistributions)
+            {
+               blockParamStr.nx[8][0] = static_cast<int>(zeroDistributions->getNX1());
+               blockParamStr.nx[8][1] = static_cast<int>(zeroDistributions->getNX2());
+               blockParamStr.nx[8][2] = static_cast<int>(zeroDistributions->getNX3());
+               blockParamStr.nx[8][3] = 1;
+            }
+
+            // ... than save some parameters that are equal in all blocks
+            blockParamStr.nx1 = static_cast<int>(block->getKernel()->getDataSet()->getFdistributions()->getNX1());
+            blockParamStr.nx2 = static_cast<int>(block->getKernel()->getDataSet()->getFdistributions()->getNX2());
+            blockParamStr.nx3 = static_cast<int>(block->getKernel()->getDataSet()->getFdistributions()->getNX3());
+
+            firstBlock = false;
+
+            // how many elements are in all arrays of DataSet (equal in all blocks)
+            int doubleCount = 0, temp;
+            for (int i = 0; i < 9; i++)   // 9 arrays ( averageValues, averageVelocity, averageFluktuations,
+            {                 // averageTriplecorrelations, shearStressValues, relaxationFactor, 3 * fdistributions
+               temp = 1;
+               for (int ii = 0; ii < 4; ii++)   // 4 values (nx1, nx2, nx3, nx4)
+                  temp *= blockParamStr.nx[i][ii];
+               doubleCount += temp;
+            }
+            blockParamStr.doubleCountInBlock = doubleCount;
+
+            // the quantity of elements in the bcindexmatrix array (CbArray3D<int, IndexerX3X2X1>) in bcArray(BCArray3D) is always equal,
+            // this will be the size of the "write-read-block" in MPI_write_.../MPI_read-functions when writing/reading BoundConds
+            BCArray3D bcArr = block->getKernel()->getBCProcessor()->getBCArray();
+            blockParamStr.bcindexmatrix_count = static_cast<int>(bcArr.bcindexmatrix.getDataVector().size());
+         }
+
+         // save data describing the block
+         block3dArray[ic].x1 = block->getX1();
+         block3dArray[ic].x2 = block->getX2();
+         block3dArray[ic].x3 = block->getX3();
+         block3dArray[ic].bundle = block->getBundle();
+         block3dArray[ic].rank = block->getRank();
+         block3dArray[ic].lrank = block->getLocalRank();
+         block3dArray[ic].part = block->getPart();
+         block3dArray[ic].globalID = block->getGlobalID();
+         block3dArray[ic].localID = block->getLocalID();
+         block3dArray[ic].level = block->getLevel();
+         block3dArray[ic].interpolationFlagCF = block->getInterpolationFlagCF();
+         block3dArray[ic].interpolationFlagFC = block->getInterpolationFlagFC();
+         block3dArray[ic].counter = block->getMaxGlobalID();
+         block3dArray[ic].active = block->isActive();
+
+         ic++;
+      }
+   }
+
+   // write to the file
+   // all processes calculate their offsets (quantity of bytes that the process is going to write) 
+   // and notify the next process (with the rank = rank + 1)
+   size_t view_offset = size*sizeof(int);
+
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestart2CoProcessor::writeBlocks start MPI IO rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
+
+   double start, finish;
+   if (comm->isRoot()) start = MPI_Wtime();
+
+   if (comm->isRoot())
+   {
+      // each process writes the quantity of it's blocks
+      MPI_File_write_at(file_handler, 0/*rank*sizeof(int)*/, &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE);
+      // each process writes parameters of the grid
+      MPI_File_write_at(file_handler, view_offset, gridParameters, 1, gridParamType, MPI_STATUS_IGNORE);
+      // each process writes common parameters of a block
+      MPI_File_write_at(file_handler, view_offset+sizeof(GridParam), &blockParamStr, 1, blockParamType, MPI_STATUS_IGNORE);
+      // each process writes it's blocks
+      MPI_File_write_at(file_handler, view_offset+sizeof(GridParam)+sizeof(BlockParam), &block3dArray[0], blocksCount, block3dType, MPI_STATUS_IGNORE);
+      //MPI_File_sync(file_handler);
+   }
+   MPI_File_close(&file_handler);
+ 
+   if (comm->isRoot())
+   {
+      finish = MPI_Wtime();
+      UBLOG(logINFO, "MPIIORestart2CoProcessor::writeBlocks time: "<<finish-start<<" s");
+   }
+
+   // register new MPI-types depending on the block-specific information
+   MPI_Type_contiguous(blockParamStr.doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType);
+   MPI_Type_commit(&dataSetDoubleType);
+   
+   MPI_Type_contiguous(blockParamStr.bcindexmatrix_count, MPI_INT, &bcindexmatrixType);
+   MPI_Type_commit(&bcindexmatrixType);
+
+   mpiTypeFreeFlag = true;
+
+   delete[] block3dArray;
+   delete gridParameters;
+}
+
+void MPIIORestart2CoProcessor::writeDataSet(int step)
+{
+   int rank, size;
+   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+   MPI_Comm_size(MPI_COMM_WORLD, &size);
+
+   int blocksCount = 0; // quantity of blocks, that belong to this process 
+
+   std::vector<Block3DPtr> blocksVector[25];
+   int minInitLevel = this->grid->getCoarsestInitializedLevel();
+   int maxInitLevel = this->grid->getFinestInitializedLevel();
+   for (int level = minInitLevel; level<=maxInitLevel; level++)
+   {
+      grid->getBlocks(level, rank, blocksVector[level]);
+      blocksCount += static_cast<int>(blocksVector[level].size());
+   }
+
+   DataSet* dataSetArray = new DataSet[blocksCount];
+   std::vector<double> doubleValuesArray; // double-values (arrays of f's) in all blocks
+
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestart2CoProcessor::writeDataSet start collect data rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
+
+   int ic = 0;
+   for (int level = minInitLevel; level<=maxInitLevel; level++)
+   {
+      BOOST_FOREACH(Block3DPtr block, blocksVector[level])  //	blocks of the current level
+      {
+         dataSetArray[ic].globalID = block->getGlobalID();     // id of the block needed to find it while regenerating the grid
+         dataSetArray[ic].ghostLayerWidth = block->getKernel()->getGhostLayerWidth();
+         dataSetArray[ic].collFactor = block->getKernel()->getCollisionFactor();
+         dataSetArray[ic].deltaT = block->getKernel()->getDeltaT();
+         dataSetArray[ic].compressible = block->getKernel()->getCompressible();
+         dataSetArray[ic].withForcing = block->getKernel()->getWithForcing();
+
+         boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageValuesArray3DPtr = block->getKernel()->getDataSet()->getAverageValues();
+         if (AverageValuesArray3DPtr&&(blockParamStr.nx[0][0]>0)&&(blockParamStr.nx[0][1]>0)&&(blockParamStr.nx[0][2]>0)&&(blockParamStr.nx[0][3]>0))
+           doubleValuesArray.insert(doubleValuesArray.end(), AverageValuesArray3DPtr->getDataVector().begin(), AverageValuesArray3DPtr->getDataVector().end());
+
+         boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageVelocityArray3DPtr = block->getKernel()->getDataSet()->getAverageVelocity();
+         if (AverageVelocityArray3DPtr&&(blockParamStr.nx[1][0]>0)&&(blockParamStr.nx[1][1]>0)&&(blockParamStr.nx[1][2]>0)&&(blockParamStr.nx[1][3]>0))
+            doubleValuesArray.insert(doubleValuesArray.end(), AverageVelocityArray3DPtr->getDataVector().begin(), AverageVelocityArray3DPtr->getDataVector().end());
+
+         boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageFluctArray3DPtr = block->getKernel()->getDataSet()->getAverageFluctuations();
+         if (AverageFluctArray3DPtr&&(blockParamStr.nx[2][0]>0)&&(blockParamStr.nx[2][1]>0)&&(blockParamStr.nx[2][2]>0)&&(blockParamStr.nx[2][3]>0))
+            doubleValuesArray.insert(doubleValuesArray.end(), AverageFluctArray3DPtr->getDataVector().begin(), AverageFluctArray3DPtr->getDataVector().end());
+
+         boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageTripleArray3DPtr = block->getKernel()->getDataSet()->getAverageTriplecorrelations();
+         if (AverageTripleArray3DPtr&&(blockParamStr.nx[3][0]>0)&&(blockParamStr.nx[3][1]>0)&&(blockParamStr.nx[3][2]>0)&&(blockParamStr.nx[3][3]>0))
+            doubleValuesArray.insert(doubleValuesArray.end(), AverageTripleArray3DPtr->getDataVector().begin(), AverageTripleArray3DPtr->getDataVector().end());
+
+         boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > ShearStressValArray3DPtr = block->getKernel()->getDataSet()->getShearStressValues();
+         if (ShearStressValArray3DPtr&&(blockParamStr.nx[4][0]>0)&&(blockParamStr.nx[4][1]>0)&&(blockParamStr.nx[4][2]>0)&&(blockParamStr.nx[4][3]>0))
+            doubleValuesArray.insert(doubleValuesArray.end(), ShearStressValArray3DPtr->getDataVector().begin(), ShearStressValArray3DPtr->getDataVector().end());
+
+         boost::shared_ptr< CbArray3D<LBMReal, IndexerX3X2X1> > RelaxationFactor3DPtr = block->getKernel()->getDataSet()->getRelaxationFactor();
+         if (RelaxationFactor3DPtr&&(blockParamStr.nx[5][0]>0)&&(blockParamStr.nx[5][1]>0)&&(blockParamStr.nx[5][2]>0))
+            doubleValuesArray.insert(doubleValuesArray.end(), RelaxationFactor3DPtr->getDataVector().begin(), RelaxationFactor3DPtr->getDataVector().end());
+
+         boost::shared_ptr< D3Q27EsoTwist3DSplittedVector > D3Q27EsoTwist3DSplittedVectorPtr = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(block->getKernel()->getDataSet()->getFdistributions());
+         CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getLocalDistributions();
+         if (localDistributions&&(blockParamStr.nx[6][0]>0)&&(blockParamStr.nx[6][1]>0)&&(blockParamStr.nx[6][2]>0)&&(blockParamStr.nx[6][3]>0))
+            doubleValuesArray.insert(doubleValuesArray.end(), localDistributions->getDataVector().begin(), localDistributions->getDataVector().end());
+
+         CbArray4D <LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getNonLocalDistributions();
+         if (nonLocalDistributions&&(blockParamStr.nx[7][0]>0)&&(blockParamStr.nx[7][1]>0)&&(blockParamStr.nx[7][2]>0)&&(blockParamStr.nx[7][3]>0))
+            doubleValuesArray.insert(doubleValuesArray.end(), nonLocalDistributions->getDataVector().begin(), nonLocalDistributions->getDataVector().end());
+
+         CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr zeroDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getZeroDistributions();
+         if (zeroDistributions&&(blockParamStr.nx[8][0]>0)&&(blockParamStr.nx[8][1]>0)&&(blockParamStr.nx[8][2]>0))
+            doubleValuesArray.insert(doubleValuesArray.end(), zeroDistributions->getDataVector().begin(), zeroDistributions->getDataVector().end());
+
+         ic++;
+      }
+   }
+
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestart2CoProcessor::writeDataSet start MPI IO rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
+
+   double start, finish;
+   if (comm->isRoot()) start = MPI_Wtime();
+
+   MPI_Info info = MPI_INFO_NULL;
+   //MPI_Info_create (&info);
+   //MPI_Info_set(info,"romio_cb_write","enable");
+   //MPI_Info_set(info,"cb_buffer_size","4194304");
+   //MPI_Info_set(info,"striping_unit","4194304");
+
+   // write to the file
+   MPI_File file_handler;
+   std::string filename = path+"/mpi_io_cp/mpi_io_cp_"+UbSystem::toString(step)+"/cpDataSet.bin";
+   int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE|MPI_MODE_WRONLY, info, &file_handler);
+   if (rc!=MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file "+filename);
+
+   int sizeofOneDataSet = sizeof(DataSet) + blockParamStr.doubleCountInBlock * sizeof(double);
+   size_t view_offset;
+   for (int nb = 0; nb < blocksCount; nb++)
+   {
+      view_offset = dataSetArray[nb].globalID * sizeofOneDataSet;
+      MPI_File_write_at(file_handler, view_offset, &dataSetArray[nb], 1, dataSetType, MPI_STATUS_IGNORE);
+      MPI_File_write_at(file_handler, view_offset + sizeof(DataSet), &doubleValuesArray[nb * blockParamStr.doubleCountInBlock], 1, dataSetDoubleType, MPI_STATUS_IGNORE);
+   }
+
+   //MPI_File_sync(file_handler);
+   MPI_File_close(&file_handler);
+
+   if (comm->isRoot())
+   {
+      finish = MPI_Wtime();
+      UBLOG(logINFO, "MPIIORestart2CoProcessor::writeDataSet time: "<<finish-start<<" s");
+   }
+
+   delete[] dataSetArray;
+}
+
+void MPIIORestart2CoProcessor::writeBoundaryConds(int step)
+{
+   int rank, size;
+   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+   MPI_Comm_size(MPI_COMM_WORLD, &size);
+
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestart2CoProcessor::writeBoundaryConds start collect data rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
+
+   int blocksCount = 0;    // quantity of blocks, that belong to this process
+   size_t allBytesCount = 0;  // quantity of bytes, that one process writes to the file
+   size_t count_boundCond = 0;	// how many BoundaryConditions in all blocks
+   int count_indexContainer = 0;	// how many indexContainer-values in all blocks
+
+   std::vector<Block3DPtr> blocksVector[25];
+   int minInitLevel = this->grid->getCoarsestInitializedLevel();
+   int maxInitLevel = this->grid->getFinestInitializedLevel();
+   for (int level = minInitLevel; level<=maxInitLevel; level++)
+   {
+      grid->getBlocks(level, rank, blocksVector[level]);
+      blocksCount += static_cast<int>(blocksVector[level].size());
+   }
+
+   BCAdd* bcAddArray = new BCAdd[blocksCount];
+   size_t* bytesCount = new size_t[blocksCount];  // quantity of bytes, that each block writes to the file
+   std::vector<BoundaryCondition>* bcVector = new std::vector<BoundaryCondition>[blocksCount];
+   std::vector<int>* bcindexmatrixVector = new std::vector<int>[blocksCount];
+   std::vector<int>* indexContainerVector = new std::vector<int>[blocksCount];
+
+   int ic = 0;
+   for (int level = minInitLevel; level<=maxInitLevel; level++)
+   {
+      BOOST_FOREACH(Block3DPtr block, blocksVector[level])  // all the blocks of the current level
+      {
+         BCArray3D bcArr = block->getKernel()->getBCProcessor()->getBCArray();
+
+         bcAddArray[ic].globalID = block->getGlobalID(); // id of the block needed to find it while regenerating the grid
+         bcAddArray[ic].boundCond_count = 0;             // how many BoundaryConditions in this block
+         bcAddArray[ic].indexContainer_count = 0;        // how many indexContainer-values in this block
+         bytesCount[ic] = sizeof(BCAdd);
+         bcVector[ic].resize(0);
+         bcindexmatrixVector[ic].resize(0);
+         indexContainerVector[ic].resize(0);
+
+         for (int bc = 0; bc<bcArr.getBCVectorSize(); bc++)
+         {
+            BoundaryCondition* bouCond = new BoundaryCondition();
+            if (bcArr.bcvector[bc]==NULL)
+            {
+               memset(bouCond, 0, sizeof(BoundaryCondition));
+            }
+            else
+            {
+               bouCond->noslipBoundaryFlags = bcArr.bcvector[bc]->getNoSlipBoundary();
+               bouCond->slipBoundaryFlags = bcArr.bcvector[bc]->getSlipBoundary();
+               bouCond->velocityBoundaryFlags = bcArr.bcvector[bc]->getVelocityBoundary();
+               bouCond->densityBoundaryFlags = bcArr.bcvector[bc]->getDensityBoundary();
+               bouCond->wallModelBoundaryFlags = bcArr.bcvector[bc]->getWallModelBoundary();
+               bouCond->bcVelocityX1 = bcArr.bcvector[bc]->getBoundaryVelocityX1();
+               bouCond->bcVelocityX2 = bcArr.bcvector[bc]->getBoundaryVelocityX2();
+               bouCond->bcVelocityX3 = bcArr.bcvector[bc]->getBoundaryVelocityX3();
+               bouCond->bcDensity = bcArr.bcvector[bc]->getBoundaryDensity();
+               bouCond->bcLodiDensity = bcArr.bcvector[bc]->getDensityLodiDensity();
+               bouCond->bcLodiVelocityX1 = bcArr.bcvector[bc]->getDensityLodiVelocityX1();
+               bouCond->bcLodiVelocityX2 = bcArr.bcvector[bc]->getDensityLodiVelocityX2();
+               bouCond->bcLodiVelocityX3 = bcArr.bcvector[bc]->getDensityLodiVelocityX3();
+               bouCond->bcLodiLentgh = bcArr.bcvector[bc]->getDensityLodiLength();
+               bouCond->nx1 = bcArr.bcvector[bc]->nx1;
+               bouCond->nx2 = bcArr.bcvector[bc]->nx2;
+               bouCond->nx3 = bcArr.bcvector[bc]->nx3;
+               for (int iq = 0; iq<26; iq++)
+                  bouCond->q[iq] = bcArr.bcvector[bc]->getQ(iq);
+               bouCond->algorithmType = bcArr.bcvector[bc]->getBcAlgorithmType();
+            }
+
+            bcVector[ic].push_back(*bouCond);
+            bcAddArray[ic].boundCond_count++;
+            count_boundCond++;
+            bytesCount[ic] += sizeof(BoundaryCondition);
+         }
+
+         bcindexmatrixVector[ic].insert(bcindexmatrixVector[ic].begin(), bcArr.bcindexmatrix.getDataVector().begin(), bcArr.bcindexmatrix.getDataVector().end());
+         bytesCount[ic] += blockParamStr.bcindexmatrix_count * sizeof(int);
+
+         indexContainerVector[ic].insert(indexContainerVector[ic].begin(), bcArr.indexContainer.begin(), bcArr.indexContainer.end());
+         bcAddArray[ic].indexContainer_count = static_cast<int>(bcArr.indexContainer.size());
+         count_indexContainer += bcAddArray[ic].indexContainer_count;
+         bytesCount[ic] += bcAddArray[ic].indexContainer_count * sizeof(int);
+
+         allBytesCount += bytesCount[ic];
+
+         ic++;
+      }
+   }
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestart2CoProcessor::writeBoundaryConds start MPI IO rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
+
+   double start, finish;
+   if (comm->isRoot()) start = MPI_Wtime();
+
+   MPI_Info info = MPI_INFO_NULL;
+   //MPI_Info_create (&info);
+   //MPI_Info_set(info,"romio_cb_write","enable");
+   //MPI_Info_set(info,"cb_buffer_size","4194304");
+   //MPI_Info_set(info,"striping_unit","4194304");
+
+   MPI_File file_handler;
+   std::string filename = path+"/mpi_io_cp/mpi_io_cp_"+UbSystem::toString(step)+"/cpBC.bin";
+   int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE|MPI_MODE_WRONLY, info, &file_handler);
+   if (rc!=MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file "+filename);
+   
+   size_t file_offset = grid->getNumberOfBlocks() * sizeof(size_t);
+   size_t next_file_offset = 0;
+   if (size > 1)
+   {
+      if (rank == 0)
+      {
+         next_file_offset = file_offset + allBytesCount;
+         MPI_Send(&next_file_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD);
+      }
+      else
+      {
+         MPI_Recv(&file_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+         next_file_offset = file_offset + allBytesCount;
+         if (rank < size - 1)
+            MPI_Send(&next_file_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD);
+      }
+   }
+
+   size_t file_offsetIndex = 0;
+
+   for (int nb = 0; nb < blocksCount; nb++)
+   {
+      file_offsetIndex = bcAddArray[nb].globalID * sizeof(size_t);
+      MPI_File_write_at(file_handler, file_offsetIndex, &file_offset, 1, MPI_LONG_LONG_INT, MPI_STATUS_IGNORE);
+      
+      MPI_File_write_at(file_handler, file_offset, &bcAddArray[nb], 1, boundCondTypeAdd, MPI_STATUS_IGNORE);
+      if (bcVector[nb].size() > 0)
+         MPI_File_write_at(file_handler, file_offset + sizeof(BCAdd), &bcVector[nb][0], bcAddArray[nb].boundCond_count, boundCondType, MPI_STATUS_IGNORE);
+
+      MPI_File_write_at(file_handler, file_offset + sizeof(BCAdd) + bcAddArray[nb].boundCond_count * sizeof(BoundaryCondition),
+         &bcindexmatrixVector[nb][0], 1, bcindexmatrixType, MPI_STATUS_IGNORE);
+     
+      if (indexContainerVector[nb].size() > 0)
+         MPI_File_write_at(file_handler, file_offset + sizeof(BCAdd) + bcAddArray[nb].boundCond_count * sizeof(BoundaryCondition) + blockParamStr.bcindexmatrix_count * sizeof(int),
+            &indexContainerVector[nb][0], bcAddArray[nb].indexContainer_count, MPI_INT, MPI_STATUS_IGNORE);
+      
+      file_offset += bytesCount[nb];
+   }
+
+   //MPI_File_sync(file_handler);
+   MPI_File_close(&file_handler);
+
+   if (comm->isRoot())
+   {
+      finish = MPI_Wtime();
+      UBLOG(logINFO, "MPIIORestart2CoProcessor::writeBoundaryConds time: "<<finish-start<<" s");
+   }
+
+   delete[] bcAddArray;
+   delete[] bytesCount;
+   delete[] bcVector;
+   delete[] bcindexmatrixVector;
+   delete[] indexContainerVector;
+}
+
+//------------------------------------------- READ -----------------------------------------------
+void MPIIORestart2CoProcessor::restart(int step)
+{
+   if (comm->isRoot()) UBLOG(logINFO, "MPIIORestart2CoProcessor restart step: "<<step);
+   if (comm->isRoot()) UBLOG(logINFO, "Load check point - start");
+   readBlocks(step);
+   readDataSet(step);
+   readBoundaryConds(step);
+   if (comm->isRoot()) UBLOG(logINFO, "Load check point - end");
+   this->reconnect(grid);
+}
+
+void MPIIORestart2CoProcessor::readBlocks(int step)
+{
+   int rank, size;
+   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+   //MPI_Comm_size(MPI_COMM_WORLD, &size);
+   size = 1;
+
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestart2CoProcessor::readBlocks start MPI IO rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
+
+   double start, finish;
+   if (comm->isRoot()) start = MPI_Wtime();
+
+   MPI_File file_handler;
+   std::string filename = path+"/mpi_io_cp/mpi_io_cp_"+UbSystem::toString(step)+"/cpBlocks.bin";
+   int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler);
+   if (rc!=MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file "+filename);
+
+   // read count of blocks
+   int blocksCount = 0;
+   //MPI_File_read_at(file_handler, rank*sizeof(int), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE);
+   MPI_File_read_at(file_handler, 0, &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE);
+   Block3d* block3dArray = new Block3d[blocksCount];
+
+   // calculate the read offset
+   size_t read_offset = size*sizeof(int);
+
+   GridParam* gridParameters = new GridParam;
+
+   // read parameters of the grid
+   MPI_File_read_at(file_handler, read_offset, gridParameters, 1, gridParamType, MPI_STATUS_IGNORE);
+   // read parameters of a block
+   MPI_File_read_at(file_handler, read_offset+sizeof(GridParam), &blockParamStr, 1, blockParamType, MPI_STATUS_IGNORE);
+   // read all the blocks
+   MPI_File_read_at(file_handler, read_offset+sizeof(GridParam)+sizeof(BlockParam), &block3dArray[0], blocksCount, block3dType, MPI_STATUS_IGNORE);
+   //MPI_File_sync(file_handler);
+
+   MPI_File_close(&file_handler);
+
+   if (comm->isRoot())
+   {
+      finish = MPI_Wtime();
+      UBLOG(logINFO, "MPIIORestart2CoProcessor::readBlocks time: "<<finish-start<<" s");
+   }
+
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestart2CoProcessor::readBlocks start of restore of data, rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
+
+   // clear the grid
+   std::vector<Block3DPtr> blocksVector;
+   grid->getBlocks(0, blocksVector);
+   int del = 0;
+   BOOST_FOREACH(Block3DPtr block, blocksVector)
+   {
+      grid->deleteBlock(block);
+      del++;
+   }
+
+   // restore the grid
+   CoordinateTransformation3DPtr trafo(new CoordinateTransformation3D());
+   trafo->Tx1 = gridParameters->trafoParams[0];
+   trafo->Tx2 = gridParameters->trafoParams[1];
+   trafo->Tx3 = gridParameters->trafoParams[2];
+   trafo->Sx1 = gridParameters->trafoParams[3];
+   trafo->Sx2 = gridParameters->trafoParams[4];
+   trafo->Sx3 = gridParameters->trafoParams[5];
+   trafo->alpha = gridParameters->trafoParams[6];
+   trafo->beta = gridParameters->trafoParams[7];
+   trafo->gamma = gridParameters->trafoParams[8];
+
+   trafo->toX1factorX1 = gridParameters->trafoParams[9];
+   trafo->toX1factorX2 = gridParameters->trafoParams[10];
+   trafo->toX1factorX3 = gridParameters->trafoParams[11];
+   trafo->toX1delta = gridParameters->trafoParams[12];
+   trafo->toX2factorX1 = gridParameters->trafoParams[13];
+   trafo->toX2factorX2 = gridParameters->trafoParams[14];
+   trafo->toX2factorX3 = gridParameters->trafoParams[15];
+   trafo->toX2delta = gridParameters->trafoParams[16];
+   trafo->toX3factorX1 = gridParameters->trafoParams[17];
+   trafo->toX3factorX2 = gridParameters->trafoParams[18];
+   trafo->toX3factorX3 = gridParameters->trafoParams[19];
+   trafo->toX3delta = gridParameters->trafoParams[20];
+
+   trafo->fromX1factorX1 = gridParameters->trafoParams[21];
+   trafo->fromX1factorX2 = gridParameters->trafoParams[22];
+   trafo->fromX1factorX3 = gridParameters->trafoParams[23];
+   trafo->fromX1delta = gridParameters->trafoParams[24];
+   trafo->fromX2factorX1 = gridParameters->trafoParams[25];
+   trafo->fromX2factorX2 = gridParameters->trafoParams[26];
+   trafo->fromX2factorX3 = gridParameters->trafoParams[27];
+   trafo->fromX2delta = gridParameters->trafoParams[28];
+   trafo->fromX3factorX1 = gridParameters->trafoParams[29];
+   trafo->fromX3factorX2 = gridParameters->trafoParams[30];
+   trafo->fromX3factorX3 = gridParameters->trafoParams[31];
+   trafo->fromX3delta = gridParameters->trafoParams[32];
+
+   trafo->active = gridParameters->active;
+   trafo->transformation = gridParameters->transformation;
+
+   grid->setCoordinateTransformator(trafo);
+
+   grid->setDeltaX(gridParameters->deltaX);
+   grid->setBlockNX(gridParameters->blockNx1, gridParameters->blockNx2, gridParameters->blockNx3);
+   grid->setNX1(gridParameters->nx1);
+   grid->setNX2(gridParameters->nx2);
+   grid->setNX3(gridParameters->nx3);
+   grid->setPeriodicX1(gridParameters->periodicX1);
+   grid->setPeriodicX2(gridParameters->periodicX2);
+   grid->setPeriodicX3(gridParameters->periodicX3);
+
+   // regenerate blocks
+   for (int n = 0; n<blocksCount; n++)
+   {
+      Block3DPtr block(new Block3D(block3dArray[n].x1, block3dArray[n].x2, block3dArray[n].x3, block3dArray[n].level));
+      block->setActive(block3dArray[n].active);
+      block->setBundle(block3dArray[n].bundle);
+      block->setRank(block3dArray[n].rank);
+      block->setLocalRank(block3dArray[n].lrank);
+      block->setGlobalID(block3dArray[n].globalID);
+      block->setLocalID(block3dArray[n].localID);
+      block->setPart(block3dArray[n].part);
+      block->setLevel(block3dArray[n].level);
+      block->interpolationFlagCF = block3dArray[n].interpolationFlagCF;
+      block->interpolationFlagFC = block3dArray[n].interpolationFlagFC;
+
+      grid->addBlock(block);
+   }
+
+   // define MPI_types depending on the block-specific information
+   MPI_Type_contiguous(blockParamStr.doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType);
+   MPI_Type_commit(&dataSetDoubleType);
+
+   MPI_Type_contiguous(blockParamStr.bcindexmatrix_count, MPI_INT, &bcindexmatrixType);
+   MPI_Type_commit(&bcindexmatrixType);
+
+   mpiTypeFreeFlag = true;
+
+   delete gridParameters;
+   delete[] block3dArray;
+
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestart2CoProcessor::readBlocks end of restore of data, rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
+}
+
+void MPIIORestart2CoProcessor::readDataSet(int step)
+{
+   int rank, size;
+   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+   MPI_Comm_size(MPI_COMM_WORLD, &size);
+
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestart2CoProcessor::readDataSet start MPI IO rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
+   double start, finish;
+   if (comm->isRoot()) start = MPI_Wtime();
+
+   int blocksCount = 0; // quantity of the blocks, that belong to this process
+
+   // read from the grid the blocks, that belong to this process
+   std::vector<Block3DPtr> blocksVector[25];
+   int minInitLevel = this->grid->getCoarsestInitializedLevel();
+   int maxInitLevel = this->grid->getFinestInitializedLevel();
+   for (int level = minInitLevel; level <= maxInitLevel; level++)
+   {
+      grid->getBlocks(level, rank, blocksVector[level]);
+      blocksCount += static_cast<int>(blocksVector[level].size());
+   }
+
+   DataSet* dataSetArray = new DataSet[blocksCount];
+   std::vector<double> doubleValuesArray(blocksCount * blockParamStr.doubleCountInBlock); // double-values in all blocks 
+
+   MPI_File file_handler;
+   std::string filename = path+"/mpi_io_cp/mpi_io_cp_"+UbSystem::toString(step)+"/cpDataSet.bin";
+   int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler);
+   if (rc!=MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file "+filename);
+ 
+   int ic = 0;
+   size_t read_offset;
+   int sizeofOneDataSet = sizeof(DataSet) + blockParamStr.doubleCountInBlock * sizeof(double);
+   for (int level = minInitLevel; level <= maxInitLevel; level++) 
+   {
+      BOOST_FOREACH(Block3DPtr block, blocksVector[level])  //	blocks of the current level
+      {
+         read_offset = block->getGlobalID() * sizeofOneDataSet;
+         MPI_File_read_at(file_handler, read_offset, &dataSetArray[ic], 1, dataSetType, MPI_STATUS_IGNORE);
+         MPI_File_read_at(file_handler, read_offset + sizeof(DataSet), &doubleValuesArray[ic*blockParamStr.doubleCountInBlock], 1, dataSetDoubleType, MPI_STATUS_IGNORE);
+         ic++;
+      }
+   }
+
+   //MPI_File_sync(file_handler);
+   MPI_File_close(&file_handler);
+
+   if (comm->isRoot())
+   {
+      finish = MPI_Wtime();
+      UBLOG(logINFO, "MPIIORestart2CoProcessor::readDataSet time: "<<finish-start<<" s");
+      UBLOG(logINFO, "MPIIORestart2CoProcessor::readDataSet start of restore of data, rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
+
+
+   size_t index = 0, nextVectorSize = 0;
+   std::vector<double> vectorsOfValues[9];
+   for (int n = 0; n<blocksCount; n++)
+   {
+      for (int b = 0; b<9; b++) // assign approciate vectors to 9 dataSet arrays
+      {
+         nextVectorSize = blockParamStr.nx[b][0]*blockParamStr.nx[b][1]*blockParamStr.nx[b][2]*blockParamStr.nx[b][3];
+         vectorsOfValues[b].assign(doubleValuesArray.data()+index, doubleValuesArray.data()+index+nextVectorSize);
+         index += nextVectorSize;
+      }
+
+      // fill dataSet arrays
+      AverageValuesArray3DPtr mAverageValues;
+      if ((blockParamStr.nx[0][0]==0)&&(blockParamStr.nx[0][1]==0)&&(blockParamStr.nx[0][2]==0)&&(blockParamStr.nx[0][3]==0))
+         mAverageValues = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr();
+      else
+         mAverageValues = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[0], blockParamStr.nx[0][0], blockParamStr.nx[0][1], blockParamStr.nx[0][2], blockParamStr.nx[0][3]));
+
+      AverageValuesArray3DPtr mAverageVelocity;
+      if ((blockParamStr.nx[1][0]==0)&&(blockParamStr.nx[1][1]==0)&&(blockParamStr.nx[1][2]==0)&&(blockParamStr.nx[1][3]==0))
+         mAverageVelocity = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr();
+      else
+         mAverageVelocity = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[1], blockParamStr.nx[1][0], blockParamStr.nx[1][1], blockParamStr.nx[1][2], blockParamStr.nx[1][3]));
+
+      AverageValuesArray3DPtr mAverageFluktuations;
+      if ((blockParamStr.nx[2][0]==0)&&(blockParamStr.nx[2][1]==0)&&(blockParamStr.nx[2][2]==0)&&(blockParamStr.nx[2][3]==0))
+         mAverageFluktuations = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr();
+      else
+         mAverageFluktuations = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[2], blockParamStr.nx[2][0], blockParamStr.nx[2][1], blockParamStr.nx[2][2], blockParamStr.nx[2][3]));
+
+      AverageValuesArray3DPtr mAverageTriplecorrelations;
+      if ((blockParamStr.nx[3][0]==0)&&(blockParamStr.nx[3][1]==0)&&(blockParamStr.nx[3][2]==0)&&(blockParamStr.nx[3][3]==0))
+         mAverageTriplecorrelations = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr();
+      else
+         mAverageTriplecorrelations = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[3], blockParamStr.nx[3][0], blockParamStr.nx[3][1], blockParamStr.nx[3][2], blockParamStr.nx[3][3]));
+
+      ShearStressValuesArray3DPtr mShearStressValues;
+      if ((blockParamStr.nx[4][0]==0)&&(blockParamStr.nx[4][1]==0)&&(blockParamStr.nx[4][2]==0)&&(blockParamStr.nx[4][3]==0))
+         mShearStressValues = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr();
+      else
+         mShearStressValues = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[4], blockParamStr.nx[4][0], blockParamStr.nx[4][1], blockParamStr.nx[4][2], blockParamStr.nx[4][3]));
+
+      RelaxationFactorArray3DPtr mRelaxationFactor;
+      if ((blockParamStr.nx[5][0]==0)&&(blockParamStr.nx[5][1]==0)&&(blockParamStr.nx[5][2]==0))
+         mRelaxationFactor = CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr();
+      else
+         mRelaxationFactor = CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<LBMReal, IndexerX3X2X1>(vectorsOfValues[5], blockParamStr.nx[5][0], blockParamStr.nx[5][1], blockParamStr.nx[5][2]));
+
+      DistributionArray3DPtr mFdistributions(new D3Q27EsoTwist3DSplittedVector(blockParamStr.nx1, blockParamStr.nx2, blockParamStr.nx3, -999.0));
+
+      boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[6], blockParamStr.nx[6][0], blockParamStr.nx[6][1], blockParamStr.nx[6][2], blockParamStr.nx[6][3])));
+      boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNonLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[7], blockParamStr.nx[7][0], blockParamStr.nx[7][1], blockParamStr.nx[7][2], blockParamStr.nx[7][3])));
+      boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setZeroDistributions(CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<LBMReal, IndexerX3X2X1>(vectorsOfValues[8], blockParamStr.nx[8][0], blockParamStr.nx[8][1], blockParamStr.nx[8][2])));
+ 
+      boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX1(blockParamStr.nx1);
+      boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX2(blockParamStr.nx2);
+      boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX3(blockParamStr.nx3);
+
+      DataSet3DPtr dataSetPtr = DataSet3DPtr(new DataSet3D());
+      dataSetPtr->setAverageValues(mAverageValues);
+      dataSetPtr->setAverageVelocity(mAverageVelocity);
+      dataSetPtr->setAverageFluctuations(mAverageFluktuations);
+      dataSetPtr->setAverageTriplecorrelations(mAverageTriplecorrelations);
+      dataSetPtr->setShearStressValues(mShearStressValues);
+      dataSetPtr->setRelaxationFactor(mRelaxationFactor);
+      dataSetPtr->setFdistributions(mFdistributions);
+
+      // find the nesessary block and fill it
+      Block3DPtr block = grid->getBlock(dataSetArray[n].globalID);
+      LBMKernelPtr kernel(new CompressibleCumulantLBMKernel(0, 0, 0, CompressibleCumulantLBMKernel::NORMAL));
+      kernel->setGhostLayerWidth(dataSetArray[n].ghostLayerWidth);
+      kernel->setCollisionFactor(dataSetArray[n].collFactor);
+      kernel->setDeltaT(dataSetArray[n].deltaT);
+      kernel->setCompressible(dataSetArray[n].compressible);
+      kernel->setWithForcing(dataSetArray[n].withForcing);
+      kernel->setDataSet(dataSetPtr);
+      block->setKernel(kernel);
+   }
+
+   delete[] dataSetArray;
+
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestart2CoProcessor::readDataSet end of restore of data, rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
+}
+
+void MPIIORestart2CoProcessor::readBoundaryConds(int step)
+{
+   int rank, size;
+   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+   MPI_Comm_size(MPI_COMM_WORLD, &size);
+
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestart2CoProcessor::readBoundaryConds start MPI IO rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
+   double start, finish;
+   if (comm->isRoot()) start = MPI_Wtime();
+
+   MPI_File file_handler;
+   std::string filename = path+"/mpi_io_cp/mpi_io_cp_"+UbSystem::toString(step)+"/cpBC.bin";
+   int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler);
+   if (rc!=MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file "+filename);
+
+   int blocksCount = 0; // quantity of the blocks, that belong to this process 
+   
+   // read from the grid the blocks, that belong to this process 
+   std::vector<Block3DPtr> blocksVector[25];
+   int minInitLevel = this->grid->getCoarsestInitializedLevel();
+   int maxInitLevel = this->grid->getFinestInitializedLevel();
+   for (int level = minInitLevel; level <= maxInitLevel; level++)
+   {
+      grid->getBlocks(level, rank, blocksVector[level]);
+      blocksCount += static_cast<int>(blocksVector[level].size());
+   }
+
+   BCAdd* bcAddArray = new BCAdd[blocksCount];
+   BoundaryCondition* nullBouCond = new BoundaryCondition();
+   memset(nullBouCond, 0, sizeof(BoundaryCondition));
+   BoundaryCondition* bcArray;
+   int* intArray1;
+   int* intArray2;
+   std::vector<BoundaryConditionsPtr> bcVector;
+   std::vector<int> bcindexmatrixV;
+   std::vector<int> indexContainerV;
+
+   if (comm->isRoot())
+   {
+      finish = MPI_Wtime();
+      UBLOG(logINFO, "MPIIORestart2CoProcessor::readBoundaryConds time: " << finish - start << " s");
+      UBLOG(logINFO, "MPIIORestart2CoProcessor::readBoundaryConds start of restore of data, rank = " << rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB");
+   }
+
+   int ic = 0;
+   size_t read_offset1, read_offset2;
+   for (int level = minInitLevel; level <= maxInitLevel; level++)
+   {
+      BOOST_FOREACH(Block3DPtr block, blocksVector[level])  //	blocks of the current level
+      {
+         read_offset1 = block->getGlobalID() * sizeof(size_t);  
+
+         MPI_File_read_at(file_handler, read_offset1, &read_offset2, 1, MPI_LONG_LONG_INT, MPI_STATUS_IGNORE);
+         MPI_File_read_at(file_handler, read_offset2, &bcAddArray[ic], 1, boundCondTypeAdd, MPI_STATUS_IGNORE);
+
+         bcArray = new BoundaryCondition[bcAddArray[ic].boundCond_count];
+         intArray1 = new int[blockParamStr.bcindexmatrix_count];
+         intArray2 = new int[bcAddArray[ic].indexContainer_count];
+
+         if (bcAddArray[ic].boundCond_count > 0)
+         {
+            MPI_File_read_at(file_handler, read_offset2 + sizeof(BCAdd), &bcArray[0], bcAddArray[ic].boundCond_count, boundCondType, MPI_STATUS_IGNORE);
+         }
+         MPI_File_read_at(file_handler, read_offset2 + sizeof(BCAdd) + bcAddArray[ic].boundCond_count * sizeof(BoundaryCondition),
+            &intArray1[0], 1, bcindexmatrixType, MPI_STATUS_IGNORE);
+         if (bcAddArray[ic].indexContainer_count > 0)
+         {
+            MPI_File_read_at(file_handler, read_offset2 + sizeof(BCAdd) + bcAddArray[ic].boundCond_count * sizeof(BoundaryCondition) + blockParamStr.bcindexmatrix_count * sizeof(int),
+               &intArray2[0], bcAddArray[ic].indexContainer_count, MPI_INT, MPI_STATUS_IGNORE);
+         }
+
+         bcindexmatrixV.resize(0);
+         indexContainerV.resize(0);
+         bcVector.resize(0);
+
+         for (size_t ibc = 0; ibc<bcAddArray[ic].boundCond_count; ibc++)
+         {
+            BoundaryConditionsPtr bc;
+            if (memcmp(&bcArray[ibc], nullBouCond, sizeof(BoundaryCondition))==0)
+               bc = BoundaryConditionsPtr();
+            else
+            {
+               bc = BoundaryConditionsPtr(new BoundaryConditions);
+               bc->noslipBoundaryFlags = bcArray[ibc].noslipBoundaryFlags;
+               bc->slipBoundaryFlags = bcArray[ibc].slipBoundaryFlags;
+               bc->densityBoundaryFlags = bcArray[ibc].densityBoundaryFlags;
+               bc->velocityBoundaryFlags = bcArray[ibc].velocityBoundaryFlags;
+               bc->wallModelBoundaryFlags = bcArray[ibc].wallModelBoundaryFlags;
+               bc->bcVelocityX1 = bcArray[ibc].bcVelocityX1;
+               bc->bcVelocityX2 = bcArray[ibc].bcVelocityX2;
+               bc->bcVelocityX3 = bcArray[ibc].bcVelocityX3;
+               bc->bcDensity = bcArray[ibc].bcDensity;
+               bc->bcLodiDensity = bcArray[ibc].bcLodiDensity;
+               bc->bcLodiVelocityX1 = bcArray[ibc].bcLodiVelocityX1;
+               bc->bcLodiVelocityX2 = bcArray[ibc].bcLodiVelocityX2;
+               bc->bcLodiVelocityX3 = bcArray[ibc].bcLodiVelocityX3;
+               bc->bcLodiLentgh = bcArray[ibc].bcLodiLentgh;
+
+               bc->nx1 = bcArray[ibc].nx1;
+               bc->nx2 = bcArray[ibc].nx2;
+               bc->nx3 = bcArray[ibc].nx3;
+               for (int iq = 0; iq<26; iq++)
+                  bc->setQ(bcArray[ibc].q[iq], iq);
+               bc->setBcAlgorithmType(bcArray[ibc].algorithmType);
+            }
+
+            bcVector.push_back(bc);
+         }
+
+
+         for (int b1 = 0; b1 < blockParamStr.bcindexmatrix_count; b1++)
+            bcindexmatrixV.push_back(intArray1[b1]);
+
+         for (int b2 = 0; b2 < bcAddArray[ic].indexContainer_count; b2++)
+            indexContainerV.push_back(intArray2[b2]);
+
+         CbArray3D<int, IndexerX3X2X1> bcim(bcindexmatrixV, blockParamStr.nx1, blockParamStr.nx2, blockParamStr.nx3);
+
+         BCProcessorPtr bcProc(new BCProcessor());
+         BCArray3D &bcArr = bcProc->getBCArray();
+         bcArr.bcindexmatrix = bcim;
+         bcArr.bcvector = bcVector;
+         bcArr.indexContainer = indexContainerV;
+
+         Block3DPtr block1 = grid->getBlock(bcAddArray[ic].globalID);
+         block1->getKernel()->setBCProcessor(bcProc);
+
+        delete bcArray;
+        delete intArray1;
+        delete intArray2;
+
+        ic++;
+      }
+   }
+   MPI_File_close(&file_handler);
+
+   delete nullBouCond;
+
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestart2CoProcessor::readBoundaryConds end of restore of data, rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
+}
diff --git a/source/VirtualFluidsCore/CoProcessors/MPIIORestart2CoProcessor.h b/source/VirtualFluidsCore/CoProcessors/MPIIORestart2CoProcessor.h
new file mode 100644
index 000000000..61bd2e959
--- /dev/null
+++ b/source/VirtualFluidsCore/CoProcessors/MPIIORestart2CoProcessor.h
@@ -0,0 +1,163 @@
+#ifndef _MPIIORestart2CoProcessor_H_
+#define _MPIIORestart2CoProcessor_H_
+
+#include "mpi.h"
+
+#include "CoProcessor.h"
+#include "Communicator.h"
+#include "WbWriter.h"
+
+#include <boost/shared_ptr.hpp>
+
+class MPIIORestart2CoProcessor;
+typedef boost::shared_ptr<MPIIORestart2CoProcessor> MPIIORestart2CoProcessorPtr;
+
+//! \class MPIWriteBlocksCoProcessor 
+//! \brief Writes the grid each timestep into the files and reads the grip from the files before regenerating  
+class MPIIORestart2CoProcessor: public CoProcessor
+{
+   //! \struct GridParam
+   //! \brief Structure describes parameters of the grid
+   //! \details The structure is nessasary to restore the grid correctly
+   struct GridParam
+    {
+      double trafoParams[33];
+      double deltaX;
+      int blockNx1;
+      int blockNx2;
+      int blockNx3;
+      int nx1;
+      int nx2;
+      int nx3;
+      bool periodicX1;
+      bool periodicX2;
+      bool periodicX3;
+      bool active;
+      bool transformation;
+    };
+
+   //! \struct blockParam
+   //! \brief Structure describes parameters of the block that are equal in all blocks
+   //! \details The structure used to store some parameters needed to restore dataSet arrays
+   struct BlockParam
+    {
+       int nx1;   //	to find the right block
+       int nx2;
+       int nx3;
+       int nx[9][4]; // 9 arrays x (nx1, nx2, nx3, nx4)
+       int doubleCountInBlock;   // how many double-values are in all arrays dataSet in one (any) block
+       int bcindexmatrix_count;	// how many bcindexmatrix-values are in one (any) block 
+    };
+
+   //! \struct Block3d
+   //! \brief Structure contains information of the block
+   //! \details The structure is used to write the data describing the block in the grid when saving the grid 
+   //! and to read it when restoring the grid
+   struct Block3d
+	{
+		int x1;
+		int x2;
+		int x3;
+      int bundle;
+		int rank;
+		int lrank;
+		int part;
+		int globalID;
+		int localID;
+		int level;
+		int interpolationFlagCF;
+		int interpolationFlagFC;
+		int counter;
+		bool active;
+	};
+
+   //! \struct dataSet
+   //! \brief Structure containes information identifying the block 
+   //! \details The structure is used to find the needed block in the grid when restoring a dataSet
+   struct DataSet
+	{
+      double collFactor;
+      double deltaT;
+      int globalID;
+      int ghostLayerWidth;
+      bool compressible;
+      bool withForcing;
+   };
+   
+   //! \struct BoundaryCondition
+   //! \brief Structure containes information about boundary conditions of the block 
+   //! \details The structure is used to write data describing boundary conditions of the blocks when saving the grid 
+   //! and to read it when restoring the grid
+   struct BoundaryCondition
+	{
+		long long noslipBoundaryFlags;	//	MPI_LONG_LONG
+		long long slipBoundaryFlags;		
+		long long velocityBoundaryFlags;		
+		long long densityBoundaryFlags;		
+		long long wallModelBoundaryFlags;
+		
+		float  bcVelocityX1;
+		float  bcVelocityX2;
+		float  bcVelocityX3;
+		float  bcDensity;
+		
+		float  bcLodiDensity;
+		float  bcLodiVelocityX1;
+		float  bcLodiVelocityX2;
+		float  bcLodiVelocityX3;
+		float  bcLodiLentgh;
+		
+		float  nx1,nx2,nx3;
+		float q[26];					//	MPI_FLOAT
+
+      char algorithmType;
+   };
+
+   //! \struct BCAdd
+   //! \brief Structure containes information identifying the block 
+   //! and some parameters of the arrays of boundary conditions that are equal in all blocks
+   //! \details The structure is used to find the needed block in the grid when restoring a dataSet
+   //! and to set common parameters
+   struct BCAdd
+	{
+      int globalID;
+		//int x1;		//	to find the right block
+		//int x2;		
+		//int x3;		
+		//int level;	
+      int boundCond_count;		//	how many BoundaryCondition-structures are in this block
+      int indexContainer_count;	// how many indexContainer-values are in this block
+   };
+
+public:
+   MPIIORestart2CoProcessor(Grid3DPtr grid, UbSchedulerPtr s, const std::string& path, CommunicatorPtr comm);
+   virtual ~MPIIORestart2CoProcessor();
+   //! Each timestep writes the grid into the files
+   void process(double step);
+   //! Reads the grid from the files before grid reconstruction
+   void restart(int step);
+   //! Writes the blocks of the grid into the file outputBlocks.bin
+   void writeBlocks(int step);
+   //! Writes the datasets of the blocks into the file outputDataSet.bin
+   void writeDataSet(int step);
+   //! Writes the boundary conditions of the blocks into the file outputBoundCond.bin
+   void writeBoundaryConds(int step);
+   //! Reads the blocks of the grid from the file outputBlocks.bin
+   void readBlocks(int step);
+   //! Reads the datasets of the blocks from the file outputDataSet.bin
+   void readDataSet(int step);
+   //! Reads the boundary conditions of the blocks from the file outputBoundCond.bin
+   void readBoundaryConds(int step);
+
+protected:
+   std::string path;
+   CommunicatorPtr comm;
+   bool mpiTypeFreeFlag;
+
+private:
+	MPI_Datatype gridParamType, blockParamType, block3dType, dataSetType, dataSetDoubleType, boundCondType, boundCondType1000, boundCondTypeAdd, bcindexmatrixType;
+   BlockParam blockParamStr;
+
+};
+
+#endif 
diff --git a/source/VirtualFluidsCore/CoProcessors/MPIIORestartCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/MPIIORestartCoProcessor.cpp
index 27636cc36..56fa7c9c9 100644
--- a/source/VirtualFluidsCore/CoProcessors/MPIIORestartCoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/MPIIORestartCoProcessor.cpp
@@ -5,21 +5,22 @@
 #include "CompressibleCumulantLBMKernel.h"
 #include "D3Q27EsoTwist3DSplittedVector.h"
 #include <UbSystem.h>
+#include <MemoryUtil.h>
 
 //! BLOCK_SIZE defines the quantity of the BoundaryCondition-structures written as one block to the file
 //! To avoid overflow in the parameter \a count of the function MPI_File_write_at 
 //! structures BoundaryCondition are being written in blocks containing each of them BLOCK_SIZE structures
 #define BLOCK_SIZE 1024
 
-MPIIORestartCoProcessor::MPIIORestartCoProcessor(Grid3DPtr grid, UbSchedulerPtr s, 
-                                         const std::string& path, 
-                                         CommunicatorPtr comm) :
-                                         CoProcessor(grid, s),
-                                         path(path),
-                                         comm(comm),
-                                         mpiTypeFreeFlag(false)
+MPIIORestartCoProcessor::MPIIORestartCoProcessor(Grid3DPtr grid, UbSchedulerPtr s,
+   const std::string& path,
+   CommunicatorPtr comm) :
+   CoProcessor(grid, s),
+   path(path),
+   comm(comm),
+   mpiTypeFreeFlag(false)
 {
-   UbSystem::makeDirectory(path + "/mpi_io_cp");
+   UbSystem::makeDirectory(path+"/mpi_io_cp");
 
    memset(&blockParamStr, 0, sizeof(blockParamStr));
 
@@ -31,10 +32,10 @@ MPIIORestartCoProcessor::MPIIORestartCoProcessor(Grid3DPtr grid, UbSchedulerPtr
 
    offsetsGP[0] = 0;
    MPI_Type_get_extent(MPI_DOUBLE, &lbGP, &extentGP);
-   offsetsGP[1] = blocksGP[0] * extentGP;
+   offsetsGP[1] = blocksGP[0]*extentGP;
 
    MPI_Type_get_extent(MPI_INT, &lbGP, &extentGP);
-   offsetsGP[2] = offsetsGP[1] + blocksGP[1] * extentGP;
+   offsetsGP[2] = offsetsGP[1]+blocksGP[1]*extentGP;
 
    MPI_Type_struct(3, blocksGP, offsetsGP, typesGP, &gridParamType);
    MPI_Type_commit(&gridParamType);
@@ -46,23 +47,46 @@ MPIIORestartCoProcessor::MPIIORestartCoProcessor(Grid3DPtr grid, UbSchedulerPtr
 
    //-----------------------------------------------------------------------
 
-   MPI_Datatype types[3] = { MPI_DOUBLE, MPI_INT, MPI_CHAR };
-   int blocks[3] = { 2, 14, 3 };
-   MPI_Aint offsets[3], lb, extent;
+   //MPI_Datatype types[3] = { MPI_DOUBLE, MPI_INT, MPI_CHAR };
+   //int blocks[3] = { 2, 14, 3 };
+   //MPI_Aint offsets[3], lb, extent;
 
-   offsets[0] = 0;
-   MPI_Type_get_extent(MPI_DOUBLE, &lb, &extent);
-   offsets[1] = blocks[0] * extent;
+   //offsets[0] = 0;
+   //MPI_Type_get_extent(MPI_DOUBLE, &lb, &extent);
+   //offsets[1] = blocks[0] * extent;
 
-   MPI_Type_get_extent(MPI_INT, &lb, &extent);
-   offsets[2] = offsets[1] + blocks[1] * extent;
+   //MPI_Type_get_extent(MPI_INT, &lb, &extent);
+   //offsets[2] = offsets[1] + blocks[1] * extent;
 
-   MPI_Type_create_struct(3, blocks, offsets, types, &block3dType);
+   //MPI_Type_create_struct(3, blocks, offsets, types, &block3dType);
+   //MPI_Type_commit(&block3dType);
+
+   MPI_Datatype typesBlock[2] = { MPI_INT, MPI_CHAR };
+   int blocksBlock[2] = { 13, 1 };
+   MPI_Aint offsetsBlock[2], lbBlock, extentBlock;
+
+   offsetsBlock[0] = 0;
+   MPI_Type_get_extent(MPI_INT, &lbBlock, &extentBlock);
+   offsetsBlock[1] = blocksBlock[0]*extentBlock;
+
+   MPI_Type_create_struct(2, blocksBlock, offsetsBlock, typesBlock, &block3dType);
    MPI_Type_commit(&block3dType);
 
    //-----------------------------------------------------------------------
+   MPI_Datatype typesDataSet[3] = { MPI_DOUBLE, MPI_INT, MPI_CHAR };
+   int blocksDataSet[3] = { 2, 5, 2 };
+   MPI_Aint offsetsDatatSet[3], lbDataSet, extentDataSet;
+
+   offsetsDatatSet[0] = 0;
+   MPI_Type_get_extent(MPI_DOUBLE, &lbDataSet, &extentDataSet);
+   offsetsDatatSet[1] = blocksDataSet[0]*extentDataSet;
+
+   MPI_Type_get_extent(MPI_INT, &lbDataSet, &extentDataSet);
+   offsetsDatatSet[2] = offsetsDatatSet[1]+blocksDataSet[1]*extentDataSet;
 
-   MPI_Type_contiguous(4, MPI_INT, &dataSetType);
+   MPI_Type_create_struct(3, blocksDataSet, offsetsDatatSet, typesDataSet, &dataSetType);
+
+   //MPI_Type_contiguous(4, MPI_INT, &dataSetType);
    MPI_Type_commit(&dataSetType);
 
    //-----------------------------------------------------------------------
@@ -73,12 +97,13 @@ MPIIORestartCoProcessor::MPIIORestartCoProcessor(Grid3DPtr grid, UbSchedulerPtr
 
    offsetsBC[0] = 0;
    MPI_Type_get_extent(MPI_LONG_LONG_INT, &lbBC, &extentBC);
-   offsetsBC[1] = blocksBC[0] * extentBC;
-  
+   offsetsBC[1] = blocksBC[0]*extentBC;
+
    MPI_Type_get_extent(MPI_FLOAT, &lbBC, &extentBC);
-   offsetsBC[2] = blocksBC[1] * extentBC;
+   offsetsBC[2] = blocksBC[1]*extentBC;
 
-   MPI_Type_struct(3, blocksBC, offsetsBC, typesBC, &boundCondType);
+   //MPI_Type_struct(3, blocksBC, offsetsBC, typesBC, &boundCondType);
+   MPI_Type_create_struct(3, blocksBC, offsetsBC, typesBC, &boundCondType);
    MPI_Type_commit(&boundCondType);
 
    //---------------------------------------
@@ -93,13 +118,13 @@ MPIIORestartCoProcessor::MPIIORestartCoProcessor(Grid3DPtr grid, UbSchedulerPtr
 
 }
 //////////////////////////////////////////////////////////////////////////
-MPIIORestartCoProcessor::~MPIIORestartCoProcessor() 
+MPIIORestartCoProcessor::~MPIIORestartCoProcessor()
 {
-	MPI_Type_free(&gridParamType);
-	MPI_Type_free(&blockParamType);
+   MPI_Type_free(&gridParamType);
+   MPI_Type_free(&blockParamType);
    MPI_Type_free(&block3dType);
-	MPI_Type_free(&dataSetType);
-	MPI_Type_free(&boundCondType);
+   MPI_Type_free(&dataSetType);
+   MPI_Type_free(&boundCondType);
    MPI_Type_free(&boundCondType1000);
    MPI_Type_free(&boundCondTypeAdd);
 
@@ -113,40 +138,56 @@ MPIIORestartCoProcessor::~MPIIORestartCoProcessor()
 //////////////////////////////////////////////////////////////////////////
 void MPIIORestartCoProcessor::process(double step)
 {
-	if(scheduler->isDue(step))
-	{
-      if(comm->isRoot()) UBLOG(logINFO,"MPIIORestartCoProcessor save step: " << step);
-      if(comm->isRoot()) UBLOG(logINFO,"Save check point - start");
-		writeBlocks((int)step);
-		writeDataSet((int)step);
-		writeBoundaryConds((int)step);
-      if(comm->isRoot()) UBLOG(logINFO,"Save check point - end");
-	}
+   if (scheduler->isDue(step))
+   {
+      if (comm->isRoot()) UBLOG(logINFO, "MPIIORestartCoProcessor save step: "<<step);
+      if (comm->isRoot()) UBLOG(logINFO, "Save check point - start");
+      writeBlocks((int)step);
+      writeDataSet((int)step);
+      writeBoundaryConds((int)step);
+      if (comm->isRoot()) UBLOG(logINFO, "Save check point - end");
+   }
 }
 //////////////////////////////////////////////////////////////////////////
 void MPIIORestartCoProcessor::writeBlocks(int step)
 {
-	int rank, size;
-	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
-	MPI_Comm_size(MPI_COMM_WORLD, &size);
-	MPI_File file_handler;
+   int rank, size;
+   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+   //MPI_Comm_size(MPI_COMM_WORLD, &size);
+   size=1;
+   MPI_File file_handler;
 
-   UbSystem::makeDirectory(path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step));
-   std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpBlocks.bin";
-	int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &file_handler);
-   if(rc != MPI_SUCCESS) throw UbException(UB_EXARGS,"couldn't open file "+filename);
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestartCoProcessor::writeBlocks start collect data rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
+
+   MPI_Info info = MPI_INFO_NULL;
+   //MPI_Info_create (&info);
+   //MPI_Info_set(info,"romio_cb_write","enable");
+   //MPI_Info_set(info,"cb_buffer_size","4194304");
+   //MPI_Info_set(info,"striping_unit","4194304");
+
+  // if (comm->isRoot())
+  // {
+      UbSystem::makeDirectory(path+"/mpi_io_cp/mpi_io_cp_"+UbSystem::toString(step));
+      std::string filename = path+"/mpi_io_cp/mpi_io_cp_"+UbSystem::toString(step)+"/cpBlocks.bin";
+      int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE|MPI_MODE_WRONLY, MPI_INFO_NULL, &file_handler);
+      if (rc!=MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file "+filename);
+  // }
 
    int blocksCount = 0; // quantity of blocks in the grid, max 2147483648 blocks!
    int minInitLevel = this->grid->getCoarsestInitializedLevel();
-	int maxInitLevel = this->grid->getFinestInitializedLevel();
+   int maxInitLevel = this->grid->getFinestInitializedLevel();
 
-	std::vector<Block3DPtr> blocksVector[25]; // max 25 levels
-	for(int level = minInitLevel; level<=maxInitLevel; level++)
-	{
-		//grid->getBlocks(level, rank, blockVector[level]);
-		grid->getBlocks(level, blocksVector[level]);
+   std::vector<Block3DPtr> blocksVector[25]; // max 25 levels
+   for (int level = minInitLevel; level<=maxInitLevel; level++)
+   {
+      //grid->getBlocks(level, rank, blockVector[level]);
+      grid->getBlocks(level, blocksVector[level]);
       blocksCount += static_cast<int>(blocksVector[level].size());
-	}
+   }
 
    GridParam* gridParameters = new GridParam;
    gridParameters->trafoParams[0] = grid->getCoordinateTransformator()->Tx1;
@@ -199,17 +240,17 @@ void MPIIORestartCoProcessor::writeBlocks(int step)
    gridParameters->periodicX1 = grid->isPeriodicX1();
    gridParameters->periodicX2 = grid->isPeriodicX2();
    gridParameters->periodicX3 = grid->isPeriodicX3();
-   
-//----------------------------------------------------------------------
+
+   //----------------------------------------------------------------------
 
    Block3d* block3dArray = new Block3d[blocksCount];
    bool firstBlock = true;
    int ic = 0;
-	for(int level = minInitLevel; level <= maxInitLevel; level++)
-	{
-		BOOST_FOREACH(Block3DPtr block, blocksVector[level])  //	all the blocks of the current level
-		{
-         if(firstBlock && block->getKernel()) // when first (any) valid block...
+   for (int level = minInitLevel; level<=maxInitLevel; level++)
+   {
+      BOOST_FOREACH(Block3DPtr block, blocksVector[level])  //	all the blocks of the current level
+      {
+         if (firstBlock && block->getKernel()) // when first (any) valid block...
          {
             boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageValuesArray3DPtr = block->getKernel()->getDataSet()->getAverageValues();
             if (AverageValuesArray3DPtr)
@@ -268,7 +309,7 @@ void MPIIORestartCoProcessor::writeBlocks(int step)
             boost::shared_ptr< D3Q27EsoTwist3DSplittedVector > D3Q27EsoTwist3DSplittedVectorPtr = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(block->getKernel()->getDataSet()->getFdistributions());
             CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getLocalDistributions();
             if (localDistributions)
-            {  
+            {
                blockParamStr.nx[6][0] = static_cast<int>(localDistributions->getNX1());
                blockParamStr.nx[6][1] = static_cast<int>(localDistributions->getNX2());
                blockParamStr.nx[6][2] = static_cast<int>(localDistributions->getNX3());
@@ -302,89 +343,107 @@ void MPIIORestartCoProcessor::writeBlocks(int step)
 
             // how many elements are in all arrays of DataSet (equal in all blocks)
             int doubleCount = 0, temp;
-            for (int i = 0; i < 9; i++)   // 9 arrays ( averageValues, averageVelocity, averageFluktuations,
+            for (int i = 0; i<9; i++)   // 9 arrays ( averageValues, averageVelocity, averageFluktuations,
             {                 // averageTriplecorrelations, shearStressValues, relaxationFactor, 3 * fdistributions
                temp = 1;
-               for (int ii = 0; ii < 4; ii++)
+               for (int ii = 0; ii<4; ii++)
                   temp *= blockParamStr.nx[i][ii];
                doubleCount += temp;
             }
             blockParamStr.doubleCountInBlock = doubleCount;
 
-      // the quantity of elements in the bcindexmatrix array (CbArray3D<int, IndexerX3X2X1>) in bcArray(BCArray3D) is always equal,
-      // this will be the size of the "write-read-block" in MPI_write_.../MPI_read-functions when writing/reading BoundConds
+            // the quantity of elements in the bcindexmatrix array (CbArray3D<int, IndexerX3X2X1>) in bcArray(BCArray3D) is always equal,
+            // this will be the size of the "write-read-block" in MPI_write_.../MPI_read-functions when writing/reading BoundConds
             BCArray3D bcArr = block->getKernel()->getBCProcessor()->getBCArray();
             blockParamStr.bcindexmatrix_count = static_cast<int>(bcArr.bcindexmatrix.getDataVector().size());
          }
 
          // save data describing the block
-			block3dArray[ic].x1 = block->getX1();
-			block3dArray[ic].x2 = block->getX2();
-			block3dArray[ic].x3 = block->getX3();
-			block3dArray[ic].bundle = block->getBundle();
-			block3dArray[ic].rank = block->getRank();
-			block3dArray[ic].lrank = block->getLocalRank();
-			block3dArray[ic].part = block->getPart();
-			block3dArray[ic].globalID = block->getGlobalID();
-			block3dArray[ic].localID = block->getLocalID();
-			block3dArray[ic].level = block->getLevel();
-			block3dArray[ic].interpolationFlagCF = block->getInterpolationFlagCF();
-			block3dArray[ic].interpolationFlagFC = block->getInterpolationFlagFC();
-			block3dArray[ic].counter = block->getMaxGlobalID();
-			block3dArray[ic].active = block->isActive();
-			if(block->getKernel())
-			{
-				block3dArray[ic].ghostLayerWidth = block->getKernel()->getGhostLayerWidth();
-				block3dArray[ic].collFactor = block->getKernel()->getCollisionFactor();
-            block3dArray[ic].deltaT = block->getKernel()->getDeltaT();
-				block3dArray[ic].compressible = block->getKernel()->getCompressible();
-				block3dArray[ic].withForcing = block->getKernel()->getWithForcing();
-			}
-			else 
-			{
-				block3dArray[ic].ghostLayerWidth = 0;
-				block3dArray[ic].collFactor = 0.0;
-				block3dArray[ic].deltaT = 0.0;
-				block3dArray[ic].compressible = false;
-				block3dArray[ic].withForcing = false;
-			}
-
-			ic++;
-		}
-	}
+         block3dArray[ic].x1 = block->getX1();
+         block3dArray[ic].x2 = block->getX2();
+         block3dArray[ic].x3 = block->getX3();
+         block3dArray[ic].bundle = block->getBundle();
+         block3dArray[ic].rank = block->getRank();
+         block3dArray[ic].lrank = block->getLocalRank();
+         block3dArray[ic].part = block->getPart();
+         block3dArray[ic].globalID = block->getGlobalID();
+         block3dArray[ic].localID = block->getLocalID();
+         block3dArray[ic].level = block->getLevel();
+         block3dArray[ic].interpolationFlagCF = block->getInterpolationFlagCF();
+         block3dArray[ic].interpolationFlagFC = block->getInterpolationFlagFC();
+         block3dArray[ic].counter = block->getMaxGlobalID();
+         block3dArray[ic].active = block->isActive();
+         //if(block->getKernel())
+         //{
+         //	block3dArray[ic].ghostLayerWidth = block->getKernel()->getGhostLayerWidth();
+         //	block3dArray[ic].collFactor = block->getKernel()->getCollisionFactor();
+   //         block3dArray[ic].deltaT = block->getKernel()->getDeltaT();
+         //	block3dArray[ic].compressible = block->getKernel()->getCompressible();
+         //	block3dArray[ic].withForcing = block->getKernel()->getWithForcing();
+         //}
+         //else 
+         //{
+         //	block3dArray[ic].ghostLayerWidth = 0;
+         //	block3dArray[ic].collFactor = 0.0;
+         //	block3dArray[ic].deltaT = 0.0;
+         //	block3dArray[ic].compressible = false;
+         //	block3dArray[ic].withForcing = false;
+         //}
+
+         ic++;
+      }
+   }
 
    // write to the file
    // all processes calculate their offsets (quantity of bytes that the process is going to write) 
    // and notify the next process (with the rank = rank + 1)
-   size_t view_offset = size * sizeof(int);
+   size_t view_offset = size*sizeof(int);
    size_t next_view_offset = 0;
-  
-	if(size > 1)
-	{
-		if(rank == 0)
-		{
-			next_view_offset = view_offset + sizeof(GridParam) + sizeof(BlockParam) + blocksCount * sizeof(Block3d);
-			MPI_Send(&next_view_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD);
-		}
-		else
-		{
-			MPI_Recv(&view_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
-			next_view_offset = view_offset + sizeof(GridParam) + sizeof(BlockParam) + blocksCount * sizeof(Block3d);
-			if(rank < size - 1)
-				MPI_Send(&next_view_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD);
-		}
-	}
 
-   // each process writes the quantity of it's blocks
-	MPI_File_write_at_all(file_handler, rank * sizeof(int), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE);
-   // each process writes parameters of the grid
-   MPI_File_write_at_all(file_handler, view_offset, gridParameters, 1, gridParamType, MPI_STATUS_IGNORE);
-   // each process writes common parameters of a block
-   MPI_File_write_at_all(file_handler, view_offset + sizeof(GridParam), &blockParamStr, 1, blockParamType, MPI_STATUS_IGNORE);
-   // each process writes it's blocks
-   MPI_File_write_at_all(file_handler, view_offset + sizeof(GridParam) + sizeof(BlockParam), &block3dArray[0], blocksCount, block3dType, MPI_STATUS_IGNORE);
-	//MPI_File_sync(file_handler);
-	MPI_File_close(&file_handler);
+   //if (size>1)
+   //{
+   //   if (rank==0)
+   //   {
+   //      next_view_offset = view_offset+sizeof(GridParam)+sizeof(BlockParam)+blocksCount*sizeof(Block3d);
+   //      MPI_Send(&next_view_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD);
+   //   }
+   //   else
+   //   {
+   //      MPI_Recv(&view_offset, 1, MPI_LONG_LONG_INT, rank-1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+   //      next_view_offset = view_offset+sizeof(GridParam)+sizeof(BlockParam)+blocksCount*sizeof(Block3d);
+   //      if (rank<size-1)
+   //         MPI_Send(&next_view_offset, 1, MPI_LONG_LONG_INT, rank+1, 5, MPI_COMM_WORLD);
+   //   }
+   //}
+
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestartCoProcessor::writeBlocks start MPI IO rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
+
+   double start, finish;
+   if (comm->isRoot()) start = MPI_Wtime();
+
+   if (comm->isRoot())
+   {
+      // each process writes the quantity of it's blocks
+      MPI_File_write_at(file_handler, rank*sizeof(int), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE);
+      // each process writes parameters of the grid
+      MPI_File_write_at(file_handler, view_offset, gridParameters, 1, gridParamType, MPI_STATUS_IGNORE);
+      // each process writes common parameters of a block
+      MPI_File_write_at(file_handler, view_offset+sizeof(GridParam), &blockParamStr, 1, blockParamType, MPI_STATUS_IGNORE);
+      // each process writes it's blocks
+      MPI_File_write_at(file_handler, view_offset+sizeof(GridParam)+sizeof(BlockParam), &block3dArray[0], blocksCount, block3dType, MPI_STATUS_IGNORE);
+      //MPI_File_sync(file_handler);
+   }
+   MPI_File_close(&file_handler);
+ 
+   if (comm->isRoot())
+   {
+      finish = MPI_Wtime();
+      UBLOG(logINFO, "MPIIORestartCoProcessor::writeBlocks time: "<<finish-start<<" s");
+   }
 
    // register new MPI-types depending on the block-specific information
    MPI_Type_contiguous(blockParamStr.doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType);
@@ -392,341 +451,436 @@ void MPIIORestartCoProcessor::writeBlocks(int step)
 
    MPI_Type_contiguous(blockParamStr.bcindexmatrix_count, MPI_INT, &bcindexmatrixType);
    MPI_Type_commit(&bcindexmatrixType);
-   
+
    mpiTypeFreeFlag = true;
 
-	delete[] block3dArray;
+   delete[] block3dArray;
    delete gridParameters;
 }
 
 void MPIIORestartCoProcessor::writeDataSet(int step)
 {
-	int rank, size;
-	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
-	MPI_Comm_size(MPI_COMM_WORLD, &size);
+   int rank, size;
+   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+   MPI_Comm_size(MPI_COMM_WORLD, &size);
 
    int blocksCount = 0; // quantity of blocks in the grid, max 2147483648 blocks!
 
-	std::vector<Block3DPtr> blocksVector[25]; 
-	int minInitLevel = this->grid->getCoarsestInitializedLevel();
-	int maxInitLevel = this->grid->getFinestInitializedLevel();
-	for(int level = minInitLevel; level <= maxInitLevel;level++)
-	{
-		grid->getBlocks(level, rank, blocksVector[level]);
+   std::vector<Block3DPtr> blocksVector[25];
+   int minInitLevel = this->grid->getCoarsestInitializedLevel();
+   int maxInitLevel = this->grid->getFinestInitializedLevel();
+   for (int level = minInitLevel; level<=maxInitLevel; level++)
+   {
+      grid->getBlocks(level, rank, blocksVector[level]);
       blocksCount += static_cast<int>(blocksVector[level].size());
-	}
+   }
 
-	DataSet* dataSetArray = new DataSet[blocksCount];
+   DataSet* dataSetArray = new DataSet[blocksCount];
    std::vector<double> doubleValuesArray; // double-values (arrays of f's) in all blocks 
 
-	int ic = 0;		
-	for(int level = minInitLevel; level<=maxInitLevel; level++)
-	{
-		BOOST_FOREACH(Block3DPtr block, blocksVector[level])  //	blocks of the current level
-		{
-			dataSetArray[ic].x1 = block->getX1();     // coordinates of the block needed to find it while regenerating the grid
-			dataSetArray[ic].x2 = block->getX2();
-			dataSetArray[ic].x3 = block->getX3();
-			dataSetArray[ic].level = block->getLevel();
-
-	      boost::shared_ptr< CbArray4D<LBMReal,IndexerX4X3X2X1> > AverageValuesArray3DPtr = block->getKernel()->getDataSet()->getAverageValues();
-			if(AverageValuesArray3DPtr && (blockParamStr.nx[0][0] > 0) && (blockParamStr.nx[0][1] > 0) && (blockParamStr.nx[0][2] > 0) && (blockParamStr.nx[0][3] > 0))
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestartCoProcessor::writeDataSet start collect data rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
+
+   int ic = 0;
+   for (int level = minInitLevel; level<=maxInitLevel; level++)
+   {
+      BOOST_FOREACH(Block3DPtr block, blocksVector[level])  //	blocks of the current level
+      {
+         dataSetArray[ic].x1 = block->getX1();     // coordinates of the block needed to find it while regenerating the grid
+         dataSetArray[ic].x2 = block->getX2();
+         dataSetArray[ic].x3 = block->getX3();
+         dataSetArray[ic].level = block->getLevel();
+         if (block->getKernel())
+         {
+            dataSetArray[ic].ghostLayerWidth = block->getKernel()->getGhostLayerWidth();
+            dataSetArray[ic].collFactor = block->getKernel()->getCollisionFactor();
+            dataSetArray[ic].deltaT = block->getKernel()->getDeltaT();
+            dataSetArray[ic].compressible = block->getKernel()->getCompressible();
+            dataSetArray[ic].withForcing = block->getKernel()->getWithForcing();
+         }
+         else
+         {
+            dataSetArray[ic].ghostLayerWidth = 0;
+            dataSetArray[ic].collFactor = 0.0;
+            dataSetArray[ic].deltaT = 0.0;
+            dataSetArray[ic].compressible = false;
+            dataSetArray[ic].withForcing = false;
+         }
+
+         boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageValuesArray3DPtr = block->getKernel()->getDataSet()->getAverageValues();
+         if (AverageValuesArray3DPtr&&(blockParamStr.nx[0][0]>0)&&(blockParamStr.nx[0][1]>0)&&(blockParamStr.nx[0][2]>0)&&(blockParamStr.nx[0][3]>0))
             doubleValuesArray.insert(doubleValuesArray.end(), AverageValuesArray3DPtr->getDataVector().begin(), AverageValuesArray3DPtr->getDataVector().end());
 
-	      boost::shared_ptr< CbArray4D<LBMReal,IndexerX4X3X2X1> > AverageVelocityArray3DPtr = block->getKernel()->getDataSet()->getAverageVelocity();
-			if(AverageVelocityArray3DPtr && (blockParamStr.nx[1][0] > 0) && (blockParamStr.nx[1][1] > 0) && (blockParamStr.nx[1][2] > 0) && (blockParamStr.nx[1][3] > 0))
+         boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageVelocityArray3DPtr = block->getKernel()->getDataSet()->getAverageVelocity();
+         if (AverageVelocityArray3DPtr&&(blockParamStr.nx[1][0]>0)&&(blockParamStr.nx[1][1]>0)&&(blockParamStr.nx[1][2]>0)&&(blockParamStr.nx[1][3]>0))
             doubleValuesArray.insert(doubleValuesArray.end(), AverageVelocityArray3DPtr->getDataVector().begin(), AverageVelocityArray3DPtr->getDataVector().end());
 
-	      boost::shared_ptr< CbArray4D<LBMReal,IndexerX4X3X2X1> > AverageFluctArray3DPtr = block->getKernel()->getDataSet()->getAverageFluctuations();
-			if(AverageFluctArray3DPtr && (blockParamStr.nx[2][0] > 0) && (blockParamStr.nx[2][1] > 0) && (blockParamStr.nx[2][2] > 0) && (blockParamStr.nx[2][3] > 0))
+         boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageFluctArray3DPtr = block->getKernel()->getDataSet()->getAverageFluctuations();
+         if (AverageFluctArray3DPtr&&(blockParamStr.nx[2][0]>0)&&(blockParamStr.nx[2][1]>0)&&(blockParamStr.nx[2][2]>0)&&(blockParamStr.nx[2][3]>0))
             doubleValuesArray.insert(doubleValuesArray.end(), AverageFluctArray3DPtr->getDataVector().begin(), AverageFluctArray3DPtr->getDataVector().end());
 
-	      boost::shared_ptr< CbArray4D<LBMReal,IndexerX4X3X2X1> > AverageTripleArray3DPtr = block->getKernel()->getDataSet()->getAverageTriplecorrelations();
-			if(AverageTripleArray3DPtr && (blockParamStr.nx[3][0] > 0) && (blockParamStr.nx[3][1] > 0) && (blockParamStr.nx[3][2] > 0) && (blockParamStr.nx[3][3] > 0))
+         boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageTripleArray3DPtr = block->getKernel()->getDataSet()->getAverageTriplecorrelations();
+         if (AverageTripleArray3DPtr&&(blockParamStr.nx[3][0]>0)&&(blockParamStr.nx[3][1]>0)&&(blockParamStr.nx[3][2]>0)&&(blockParamStr.nx[3][3]>0))
             doubleValuesArray.insert(doubleValuesArray.end(), AverageTripleArray3DPtr->getDataVector().begin(), AverageTripleArray3DPtr->getDataVector().end());
 
-	      boost::shared_ptr< CbArray4D<LBMReal,IndexerX4X3X2X1> > ShearStressValArray3DPtr = block->getKernel()->getDataSet()->getShearStressValues();
-			if(ShearStressValArray3DPtr && (blockParamStr.nx[4][0] > 0) && (blockParamStr.nx[4][1] > 0) && (blockParamStr.nx[4][2] > 0) && (blockParamStr.nx[4][3] > 0))
+         boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > ShearStressValArray3DPtr = block->getKernel()->getDataSet()->getShearStressValues();
+         if (ShearStressValArray3DPtr&&(blockParamStr.nx[4][0]>0)&&(blockParamStr.nx[4][1]>0)&&(blockParamStr.nx[4][2]>0)&&(blockParamStr.nx[4][3]>0))
             doubleValuesArray.insert(doubleValuesArray.end(), ShearStressValArray3DPtr->getDataVector().begin(), ShearStressValArray3DPtr->getDataVector().end());
 
          boost::shared_ptr< CbArray3D<LBMReal, IndexerX3X2X1> > RelaxationFactor3DPtr = block->getKernel()->getDataSet()->getRelaxationFactor();
-         if (RelaxationFactor3DPtr && (blockParamStr.nx[5][0] > 0) && (blockParamStr.nx[5][1] > 0) && (blockParamStr.nx[5][2] > 0))
+         if (RelaxationFactor3DPtr&&(blockParamStr.nx[5][0]>0)&&(blockParamStr.nx[5][1]>0)&&(blockParamStr.nx[5][2]>0))
             doubleValuesArray.insert(doubleValuesArray.end(), RelaxationFactor3DPtr->getDataVector().begin(), RelaxationFactor3DPtr->getDataVector().end());
 
          boost::shared_ptr< D3Q27EsoTwist3DSplittedVector > D3Q27EsoTwist3DSplittedVectorPtr = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(block->getKernel()->getDataSet()->getFdistributions());
-			CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr localDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getLocalDistributions(); 
-			if(localDistributions && (blockParamStr.nx[6][0] > 0) && (blockParamStr.nx[6][1] > 0) && (blockParamStr.nx[6][2] > 0) && (blockParamStr.nx[6][3] > 0))
+         CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getLocalDistributions();
+         if (localDistributions&&(blockParamStr.nx[6][0]>0)&&(blockParamStr.nx[6][1]>0)&&(blockParamStr.nx[6][2]>0)&&(blockParamStr.nx[6][3]>0))
             doubleValuesArray.insert(doubleValuesArray.end(), localDistributions->getDataVector().begin(), localDistributions->getDataVector().end());
 
-         CbArray4D <LBMReal,IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getNonLocalDistributions(); 
-			if(nonLocalDistributions && (blockParamStr.nx[7][0] > 0) && (blockParamStr.nx[7][1] > 0) && (blockParamStr.nx[7][2] > 0) && (blockParamStr.nx[7][3] > 0))
+         CbArray4D <LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getNonLocalDistributions();
+         if (nonLocalDistributions&&(blockParamStr.nx[7][0]>0)&&(blockParamStr.nx[7][1]>0)&&(blockParamStr.nx[7][2]>0)&&(blockParamStr.nx[7][3]>0))
             doubleValuesArray.insert(doubleValuesArray.end(), nonLocalDistributions->getDataVector().begin(), nonLocalDistributions->getDataVector().end());
 
-			CbArray3D<LBMReal,IndexerX3X2X1>::CbArray3DPtr zeroDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getZeroDistributions(); 
-			if(zeroDistributions && (blockParamStr.nx[8][0] > 0) && (blockParamStr.nx[8][1] > 0) && (blockParamStr.nx[8][2] > 0))
+         CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr zeroDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getZeroDistributions();
+         if (zeroDistributions&&(blockParamStr.nx[8][0]>0)&&(blockParamStr.nx[8][1]>0)&&(blockParamStr.nx[8][2]>0))
             doubleValuesArray.insert(doubleValuesArray.end(), zeroDistributions->getDataVector().begin(), zeroDistributions->getDataVector().end());
 
-			ic++;
-		}
-	}
-       
+         ic++;
+      }
+   }
+
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestartCoProcessor::writeDataSet start MPI IO rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
+
    // write to the file
    // all processes calculate their offsets (quantity of bytes that the process is going to write) 
    // and notify the next process (with the rank = rank + 1)
-   size_t view_offset = size * sizeof(int);
+   size_t view_offset = size*sizeof(int);
    size_t next_view_offset = 0;
 
-	if(size > 1)
-	{
-		if(rank == 0)
-		{
-			next_view_offset = view_offset + blocksCount * (sizeof(DataSet) + blockParamStr.doubleCountInBlock * sizeof(double));
-			MPI_Send(&next_view_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD);
-		}
-		else
-		{
-			MPI_Recv(&view_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
-			next_view_offset = view_offset + blocksCount * (sizeof(DataSet) + blockParamStr.doubleCountInBlock * sizeof(double));
-			if(rank < size - 1)
-				MPI_Send(&next_view_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD);
-		}
-	}
-
-	MPI_File file_handler;
-   std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpDataSet.bin";
-	int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY , MPI_INFO_NULL, &file_handler);
-   if(rc != MPI_SUCCESS) throw UbException(UB_EXARGS,"couldn't open file "+filename);
+   if (size>1)
+   {
+      if (rank==0)
+      {
+         next_view_offset = view_offset+blocksCount * (sizeof(DataSet)+blockParamStr.doubleCountInBlock*sizeof(double));
+         MPI_Send(&next_view_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD);
+      }
+      else
+      {
+         MPI_Recv(&view_offset, 1, MPI_LONG_LONG_INT, rank-1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+         next_view_offset = view_offset+blocksCount * (sizeof(DataSet)+blockParamStr.doubleCountInBlock*sizeof(double));
+         if (rank<size-1)
+            MPI_Send(&next_view_offset, 1, MPI_LONG_LONG_INT, rank+1, 5, MPI_COMM_WORLD);
+      }
+   }
+
+   double start, finish;
+   if (comm->isRoot()) start = MPI_Wtime();
+
+   MPI_Info info = MPI_INFO_NULL;
+   //MPI_Info_create (&info);
+   //MPI_Info_set(info,"romio_cb_write","enable");
+   //MPI_Info_set(info,"cb_buffer_size","4194304");
+   //MPI_Info_set(info,"striping_unit","4194304");
+
+   MPI_File file_handler;
+   std::string filename = path+"/mpi_io_cp/mpi_io_cp_"+UbSystem::toString(step)+"/cpDataSet.bin";
+   int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE|MPI_MODE_WRONLY, info, &file_handler);
+   if (rc!=MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file "+filename);
 
    // each process writes the quantity of it's blocks
-   MPI_File_write_at_all(file_handler, rank * sizeof(int), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE);
+   MPI_File_write_at_all(file_handler, rank*sizeof(int), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE);
    // each process writes data identifying blocks
-   MPI_File_write_at_all(file_handler, view_offset, &dataSetArray[0], blocksCount, dataSetType, MPI_STATUS_IGNORE);
+   MPI_File_write_at_all(file_handler, view_offset, dataSetArray, blocksCount, dataSetType, MPI_STATUS_IGNORE);
    // each process writes the dataSet arrays
-	MPI_File_write_at_all(file_handler, view_offset + blocksCount * sizeof(DataSet), &doubleValuesArray[0], blocksCount, dataSetDoubleType, MPI_STATUS_IGNORE);
-	//MPI_File_sync(file_handler);
-	MPI_File_close(&file_handler);
+   MPI_File_write_at_all(file_handler, view_offset+blocksCount*sizeof(DataSet), &doubleValuesArray[0], blocksCount, dataSetDoubleType, MPI_STATUS_IGNORE);
+   //MPI_File_sync(file_handler);
+   MPI_File_close(&file_handler);
 
-	delete[] dataSetArray;
+   if (comm->isRoot())
+   {
+      finish = MPI_Wtime();
+      UBLOG(logINFO, "MPIIORestartCoProcessor::writeDataSet time: "<<finish-start<<" s");
+   }
+
+   delete[] dataSetArray;
 }
 
 void MPIIORestartCoProcessor::writeBoundaryConds(int step)
 {
-	int rank, size;
-	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
-	MPI_Comm_size(MPI_COMM_WORLD, &size);
+   int rank, size;
+   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+   MPI_Comm_size(MPI_COMM_WORLD, &size);
+
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestartCoProcessor::writeBoundaryConds start collect data rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
 
    int blocksCount = 0;          // quantity of blocks in the grid, max 2147483648 blocks!
    size_t count_boundCond = 0;	// how many BoundaryConditions in all blocks
    int count_indexContainer = 0;	// how many indexContainer-values in all blocks
    size_t byteCount = 0;			// how many bytes writes this process in the file 
 
-	std::vector<Block3DPtr> blocksVector[25]; 
-	int minInitLevel = this->grid->getCoarsestInitializedLevel();
-	int maxInitLevel = this->grid->getFinestInitializedLevel();
-	for(int level = minInitLevel; level <= maxInitLevel;level++) 
-	{
-		grid->getBlocks(level, rank, blocksVector[level]);
+   std::vector<Block3DPtr> blocksVector[25];
+   int minInitLevel = this->grid->getCoarsestInitializedLevel();
+   int maxInitLevel = this->grid->getFinestInitializedLevel();
+   for (int level = minInitLevel; level<=maxInitLevel; level++)
+   {
+      grid->getBlocks(level, rank, blocksVector[level]);
       blocksCount += static_cast<int>(blocksVector[level].size());
-	}
+   }
 
-	BCAdd* bcAddArray = new BCAdd[blocksCount];
+   BCAdd* bcAddArray = new BCAdd[blocksCount];
    std::vector<BoundaryCondition> bcVector;
    std::vector<int> bcindexmatrixV;
    std::vector<int> indexContainerV;
 
-	int ic = 0;	
-	for(int level = minInitLevel; level <= maxInitLevel; level++)
-	{
-		BOOST_FOREACH(Block3DPtr block, blocksVector[level])  // all the blocks of the current level
-		{
-      	BCArray3D bcArr = block->getKernel()->getBCProcessor()->getBCArray();
-
-			bcAddArray[ic].x1 = block->getX1(); // coordinates of the block needed to find it while regenerating the grid
-			bcAddArray[ic].x2 = block->getX2();
-			bcAddArray[ic].x3 = block->getX3();
-			bcAddArray[ic].level = block->getLevel();
-			bcAddArray[ic].boundCond_count = 0; // how many BoundaryConditions in this block
-			bcAddArray[ic].indexContainer_count = 0;  // how many indexContainer-values in this block
-
-			for(int bc = 0; bc < bcArr.getBCVectorSize(); bc++)
-			{
-				BoundaryCondition* bouCond = new BoundaryCondition();
-				if(bcArr.bcvector[bc] == NULL)
-				{
-					memset(bouCond, 0, sizeof(BoundaryCondition));
-				}
-				else
-				{
-					bouCond->noslipBoundaryFlags = bcArr.bcvector[bc]->getNoSlipBoundary();
-					bouCond->slipBoundaryFlags = bcArr.bcvector[bc]->getSlipBoundary();
-					bouCond->velocityBoundaryFlags = bcArr.bcvector[bc]->getVelocityBoundary();
-					bouCond->densityBoundaryFlags = bcArr.bcvector[bc]->getDensityBoundary();
-					bouCond->wallModelBoundaryFlags = bcArr.bcvector[bc]->getWallModelBoundary();
-					bouCond->bcVelocityX1 = bcArr.bcvector[bc]->getBoundaryVelocityX1();
-					bouCond->bcVelocityX2 = bcArr.bcvector[bc]->getBoundaryVelocityX2();
-					bouCond->bcVelocityX3 = bcArr.bcvector[bc]->getBoundaryVelocityX3();
-					bouCond->bcDensity = bcArr.bcvector[bc]->getBoundaryDensity();
-					bouCond->bcLodiDensity = bcArr.bcvector[bc]->getDensityLodiDensity();
-					bouCond->bcLodiVelocityX1 = bcArr.bcvector[bc]->getDensityLodiVelocityX1();
-					bouCond->bcLodiVelocityX2 = bcArr.bcvector[bc]->getDensityLodiVelocityX2();
-					bouCond->bcLodiVelocityX3 = bcArr.bcvector[bc]->getDensityLodiVelocityX3();
-					bouCond->bcLodiLentgh = bcArr.bcvector[bc]->getDensityLodiLength();
-					bouCond->nx1 = bcArr.bcvector[bc]->nx1;
-					bouCond->nx2 = bcArr.bcvector[bc]->nx2;
-					bouCond->nx3 = bcArr.bcvector[bc]->nx3;
-					for(int iq = 0; iq < 26; iq++)
-						bouCond->q[iq] = bcArr.bcvector[bc]->getQ(iq);
+   int ic = 0;
+   for (int level = minInitLevel; level<=maxInitLevel; level++)
+   {
+      BOOST_FOREACH(Block3DPtr block, blocksVector[level])  // all the blocks of the current level
+      {
+         BCArray3D bcArr = block->getKernel()->getBCProcessor()->getBCArray();
+
+         bcAddArray[ic].x1 = block->getX1(); // coordinates of the block needed to find it while regenerating the grid
+         bcAddArray[ic].x2 = block->getX2();
+         bcAddArray[ic].x3 = block->getX3();
+         bcAddArray[ic].level = block->getLevel();
+         bcAddArray[ic].boundCond_count = 0; // how many BoundaryConditions in this block
+         bcAddArray[ic].indexContainer_count = 0;  // how many indexContainer-values in this block
+
+         for (int bc = 0; bc<bcArr.getBCVectorSize(); bc++)
+         {
+            BoundaryCondition* bouCond = new BoundaryCondition();
+            if (bcArr.bcvector[bc]==NULL)
+            {
+               memset(bouCond, 0, sizeof(BoundaryCondition));
+            }
+            else
+            {
+               bouCond->noslipBoundaryFlags = bcArr.bcvector[bc]->getNoSlipBoundary();
+               bouCond->slipBoundaryFlags = bcArr.bcvector[bc]->getSlipBoundary();
+               bouCond->velocityBoundaryFlags = bcArr.bcvector[bc]->getVelocityBoundary();
+               bouCond->densityBoundaryFlags = bcArr.bcvector[bc]->getDensityBoundary();
+               bouCond->wallModelBoundaryFlags = bcArr.bcvector[bc]->getWallModelBoundary();
+               bouCond->bcVelocityX1 = bcArr.bcvector[bc]->getBoundaryVelocityX1();
+               bouCond->bcVelocityX2 = bcArr.bcvector[bc]->getBoundaryVelocityX2();
+               bouCond->bcVelocityX3 = bcArr.bcvector[bc]->getBoundaryVelocityX3();
+               bouCond->bcDensity = bcArr.bcvector[bc]->getBoundaryDensity();
+               bouCond->bcLodiDensity = bcArr.bcvector[bc]->getDensityLodiDensity();
+               bouCond->bcLodiVelocityX1 = bcArr.bcvector[bc]->getDensityLodiVelocityX1();
+               bouCond->bcLodiVelocityX2 = bcArr.bcvector[bc]->getDensityLodiVelocityX2();
+               bouCond->bcLodiVelocityX3 = bcArr.bcvector[bc]->getDensityLodiVelocityX3();
+               bouCond->bcLodiLentgh = bcArr.bcvector[bc]->getDensityLodiLength();
+               bouCond->nx1 = bcArr.bcvector[bc]->nx1;
+               bouCond->nx2 = bcArr.bcvector[bc]->nx2;
+               bouCond->nx3 = bcArr.bcvector[bc]->nx3;
+               for (int iq = 0; iq<26; iq++)
+                  bouCond->q[iq] = bcArr.bcvector[bc]->getQ(iq);
                bouCond->algorithmType = bcArr.bcvector[bc]->getBcAlgorithmType();
             }
 
-				bcVector.push_back(*bouCond);
+            bcVector.push_back(*bouCond);
             bcAddArray[ic].boundCond_count++;
-				count_boundCond++;
-			}
+            count_boundCond++;
+         }
 
          bcindexmatrixV.insert(bcindexmatrixV.end(), bcArr.bcindexmatrix.getDataVector().begin(), bcArr.bcindexmatrix.getDataVector().end());
 
-         indexContainerV.insert(indexContainerV.end(), bcArr.bcindexmatrix.getDataVector().begin(), bcArr.bcindexmatrix.getDataVector().end());
-			bcAddArray[ic].indexContainer_count = static_cast<int>(bcArr.indexContainer.size());
-			count_indexContainer += bcAddArray[ic].indexContainer_count; 
-	
-			ic++;
-		}
-	}
+         indexContainerV.insert(indexContainerV.end(), bcArr.indexContainer.begin(), bcArr.indexContainer.end());
+      
+         bcAddArray[ic].indexContainer_count = static_cast<int>(bcArr.indexContainer.size());
+         count_indexContainer += bcAddArray[ic].indexContainer_count;
+
+         ic++;
+      }
+   }
 
    //how many "big blocks" of BLOCK_SIZE size can by formed
-   int bcBlockCount = (int)(count_boundCond / BLOCK_SIZE);
-   if(bcBlockCount * BLOCK_SIZE < count_boundCond) 
+   int bcBlockCount = (int)(count_boundCond/BLOCK_SIZE);
+   if (bcBlockCount * BLOCK_SIZE<count_boundCond)
       bcBlockCount += 1;
-   for (int i = (int)count_boundCond; i < bcBlockCount * BLOCK_SIZE; i++)
+   for (int i = (int)count_boundCond; i<bcBlockCount * BLOCK_SIZE; i++)
    {
       BoundaryCondition* bouCond = new BoundaryCondition();
       memset(bouCond, 0, sizeof(BoundaryCondition));
       bcVector.push_back(*bouCond);
    }
 
-   byteCount = bcBlockCount * BLOCK_SIZE * sizeof(BoundaryCondition) + blocksCount * sizeof(BCAdd) + sizeof(int) * (blocksCount * blockParamStr.bcindexmatrix_count + count_indexContainer);
+   byteCount = bcBlockCount * BLOCK_SIZE*sizeof(BoundaryCondition)+blocksCount*sizeof(BCAdd)+sizeof(int) * (blocksCount * blockParamStr.bcindexmatrix_count+count_indexContainer);
 
    // write to the file
    // all processes calculate their offsets (quantity of bytes that the process is going to write) 
    // and notify the next process (with the rank = rank + 1)
-   size_t view_offset = 3 * size * sizeof(int);
+   size_t view_offset = 3*size*sizeof(int);
    size_t next_view_offset = 0;
 
-	if(size > 1)
-	{
-		if(rank == 0)
-		{
-			next_view_offset = view_offset + byteCount;
-			MPI_Send(&next_view_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD);
-		}
-		else
-		{
-			MPI_Recv(&view_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
-			next_view_offset = view_offset + byteCount;
-			if(rank < size - 1)
-				MPI_Send(&next_view_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD);
-		}
-	}
-
-	MPI_File file_handler;
-   std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpBC.bin";
-	int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY , MPI_INFO_NULL, &file_handler);
-   if(rc != MPI_SUCCESS) throw UbException(UB_EXARGS,"couldn't open file "+filename);
+   if (size>1)
+   {
+      if (rank==0)
+      {
+         next_view_offset = view_offset+byteCount;
+         MPI_Send(&next_view_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD);
+      }
+      else
+      {
+         MPI_Recv(&view_offset, 1, MPI_LONG_LONG_INT, rank-1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+         next_view_offset = view_offset+byteCount;
+         if (rank<size-1)
+            MPI_Send(&next_view_offset, 1, MPI_LONG_LONG_INT, rank+1, 5, MPI_COMM_WORLD);
+      }
+   }
+
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestartCoProcessor::writeBoundaryConds start MPI IO rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
+
+   double start, finish;
+   if (comm->isRoot()) start = MPI_Wtime();
+
+   MPI_Info info = MPI_INFO_NULL;
+   //MPI_Info_create (&info);
+   //MPI_Info_set(info,"romio_cb_write","enable");
+   //MPI_Info_set(info,"cb_buffer_size","4194304");
+   //MPI_Info_set(info,"striping_unit","4194304");
+
+   MPI_File file_handler;
+   std::string filename = path+"/mpi_io_cp/mpi_io_cp_"+UbSystem::toString(step)+"/cpBC.bin";
+   int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE|MPI_MODE_WRONLY, info, &file_handler);
+   if (rc!=MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file "+filename);
 
    // each process writes the quantity of it's blocks
-   MPI_File_write_at_all(file_handler, rank * sizeof(int), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE);	//	blocks quantity
+   MPI_File_write_at_all(file_handler, rank*sizeof(int), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE);	//	blocks quantity
    // each process writes the quantity of "big blocks" of BLOCK_SIZE of boundary conditions
-   MPI_File_write_at_all(file_handler, (rank + size) * sizeof(int), &bcBlockCount, 1, MPI_INT, MPI_STATUS_IGNORE); // quantity of BoundConds / BLOCK_SIZE
+   MPI_File_write_at_all(file_handler, (rank+size)*sizeof(int), &bcBlockCount, 1, MPI_INT, MPI_STATUS_IGNORE); // quantity of BoundConds / BLOCK_SIZE
    // each process writes the quantity of indexContainer elements in all blocks
-	MPI_File_write_at_all(file_handler, (rank + 2 * size) * sizeof(int), &count_indexContainer, 1, MPI_INT, MPI_STATUS_IGNORE); // quantity of indexContainer	
+   MPI_File_write_at_all(file_handler, (rank+2*size)*sizeof(int), &count_indexContainer, 1, MPI_INT, MPI_STATUS_IGNORE); // quantity of indexContainer	
 
    // each process writes data identifying the blocks
    MPI_File_write_at_all(file_handler, view_offset, bcAddArray, blocksCount, boundCondTypeAdd, MPI_STATUS_IGNORE);
    // each process writes boundary conditions
-   if (bcVector.size() > 0)
+   if (bcVector.size()>0)
    {
-      	MPI_File_write_at_all(file_handler, view_offset + blocksCount * sizeof(BCAdd), &bcVector[0], bcBlockCount, boundCondType1000, MPI_STATUS_IGNORE);
+      MPI_File_write_at(file_handler, view_offset+blocksCount*sizeof(BCAdd), &bcVector[0], bcBlockCount, boundCondType1000, MPI_STATUS_IGNORE);
    }
    // each process writes bcindexmatrix values
-	MPI_File_write_at_all(file_handler, view_offset + blocksCount * sizeof(BCAdd) + bcBlockCount * BLOCK_SIZE * sizeof(BoundaryCondition), &bcindexmatrixV[0], blocksCount, bcindexmatrixType, MPI_STATUS_IGNORE);
+   MPI_File_write_at_all(file_handler, view_offset+blocksCount*sizeof(BCAdd)+bcBlockCount * BLOCK_SIZE*sizeof(BoundaryCondition), &bcindexmatrixV[0], blocksCount, bcindexmatrixType, MPI_STATUS_IGNORE);
    // each process writes indexContainer values
-	MPI_File_write_at_all(file_handler, view_offset + blocksCount * sizeof(BCAdd) + bcBlockCount * BLOCK_SIZE * sizeof(BoundaryCondition) + blocksCount * blockParamStr.bcindexmatrix_count * sizeof(int), &indexContainerV[0], count_indexContainer, MPI_INT, MPI_STATUS_IGNORE);
-	//MPI_File_sync(file_handler);
-	MPI_File_close(&file_handler);
+   MPI_File_write_at_all(file_handler, view_offset+blocksCount*sizeof(BCAdd)+bcBlockCount * BLOCK_SIZE*sizeof(BoundaryCondition)+blocksCount * blockParamStr.bcindexmatrix_count*sizeof(int), &indexContainerV[0], count_indexContainer, MPI_INT, MPI_STATUS_IGNORE);
+   //MPI_File_sync(file_handler);
+   MPI_File_close(&file_handler);
 
-	delete [] bcAddArray;
+   if (comm->isRoot())
+   {
+      finish = MPI_Wtime();
+      UBLOG(logINFO, "MPIIORestartCoProcessor::writeBoundaryConds time: "<<finish-start<<" s");
+   }
+
+   delete[] bcAddArray;
 }
 
 //------------------------------------------- READ -----------------------------------------------
 void MPIIORestartCoProcessor::restart(int step)
 {
-   if(comm->isRoot()) UBLOG(logINFO,"MPIIORestartCoProcessor restart step: " << step);
-   if(comm->isRoot()) UBLOG(logINFO,"Load check point - start");
-	readBlocks(step);
-	readDataSet(step);
-	readBoundaryConds(step);
-   if(comm->isRoot()) UBLOG(logINFO,"Load check point - end");
-	this->reconnect(grid);
+   if (comm->isRoot()) UBLOG(logINFO, "MPIIORestartCoProcessor restart step: "<<step);
+   if (comm->isRoot()) UBLOG(logINFO, "Load check point - start");
+   readBlocks(step);
+   readDataSet(step);
+   readBoundaryConds(step);
+   if (comm->isRoot()) UBLOG(logINFO, "Load check point - end");
+   this->reconnect(grid);
 }
 
 void MPIIORestartCoProcessor::readBlocks(int step)
 {
-	int rank, size;
-	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
-	MPI_Comm_size(MPI_COMM_WORLD, &size);
+   int rank, size;
+   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+   //MPI_Comm_size(MPI_COMM_WORLD, &size);
+   size = 1;
 
-	MPI_File file_handler;
-   std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpBlocks.bin";
-	int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY , MPI_INFO_NULL, &file_handler);
-   if(rc != MPI_SUCCESS) throw UbException(UB_EXARGS,"couldn't open file "+filename);
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestartCoProcessor::readBlocks start MPI IO rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
+
+   double start, finish;
+   if (comm->isRoot()) start = MPI_Wtime();
+
+   MPI_File file_handler;
+   std::string filename = path+"/mpi_io_cp/mpi_io_cp_"+UbSystem::toString(step)+"/cpBlocks.bin";
+   int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler);
+   if (rc!=MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file "+filename);
 
    // read count of blocks
    int blocksCount = 0;
-	MPI_File_read_at(file_handler, rank * sizeof(int), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE);
-	Block3d* block3dArray = new Block3d[blocksCount];
+   //MPI_File_read_at(file_handler, rank*sizeof(int), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE);
+   MPI_File_read_at(file_handler, 0, &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE);
+   Block3d* block3dArray = new Block3d[blocksCount];
 
    // calculate the read offset
-   size_t read_offset = size * sizeof(int);
+   size_t read_offset = size*sizeof(int);
+   //size_t read_offset = sizeof(int);
    size_t next_read_offset = 0;
 
-	if(size > 1)
-	{
-		if(rank == 0)
-		{
-         next_read_offset = read_offset + sizeof(GridParam) + sizeof(BlockParam) + blocksCount * sizeof(Block3d);
-			MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD);
-		}
-		else
-		{
-			MPI_Recv(&read_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
-			next_read_offset = read_offset + sizeof(GridParam) + sizeof(BlockParam) + blocksCount * sizeof(Block3d);
-			if(rank < size - 1)
-				MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD);
-		}
-	}
+   //if (size>1)
+   //{
+   //   if (rank==0)
+   //   {
+   //      next_read_offset = read_offset+sizeof(GridParam)+sizeof(BlockParam)+blocksCount*sizeof(Block3d);
+   //      MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD);
+   //   }
+   //   else
+   //   {
+   //      MPI_Recv(&read_offset, 1, MPI_LONG_LONG_INT, rank-1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+   //      next_read_offset = read_offset+sizeof(GridParam)+sizeof(BlockParam)+blocksCount*sizeof(Block3d);
+   //      if (rank<size-1)
+   //         MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, rank+1, 5, MPI_COMM_WORLD);
+   //   }
+   //}
 
    GridParam* gridParameters = new GridParam;
 
    // read parameters of the grid
-   MPI_File_read_at_all(file_handler, read_offset, gridParameters, 1, gridParamType, MPI_STATUS_IGNORE);
+   MPI_File_read_at(file_handler, read_offset, gridParameters, 1, gridParamType, MPI_STATUS_IGNORE);
    // read parameters of a block
-   MPI_File_read_at_all(file_handler, read_offset + sizeof(GridParam), &blockParamStr, 1, blockParamType, MPI_STATUS_IGNORE);
+   MPI_File_read_at(file_handler, read_offset+sizeof(GridParam), &blockParamStr, 1, blockParamType, MPI_STATUS_IGNORE);
    // read all the blocks
-	MPI_File_read_at_all(file_handler, read_offset + sizeof(GridParam) + sizeof(BlockParam), &block3dArray[0], blocksCount, block3dType, MPI_STATUS_IGNORE);
-	//MPI_File_sync(file_handler);
+   MPI_File_read_at(file_handler, read_offset+sizeof(GridParam)+sizeof(BlockParam), &block3dArray[0], blocksCount, block3dType, MPI_STATUS_IGNORE);
+   //MPI_File_sync(file_handler);
 
-	MPI_File_close(&file_handler);
+   MPI_File_close(&file_handler);
+
+   if (comm->isRoot())
+   {
+      finish = MPI_Wtime();
+      UBLOG(logINFO, "MPIIORestartCoProcessor::readBlocks time: "<<finish-start<<" s");
+   }
+
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestartCoProcessor::readBlocks start of restore of data, rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
 
    // clear the grid
-	std::vector<Block3DPtr> blocksVector;
-	grid->getBlocks(0, blocksVector);
-	int del = 0;
-	BOOST_FOREACH(Block3DPtr block, blocksVector)
-	{
-		grid->deleteBlock(block);
-		del++;
-	}
+   std::vector<Block3DPtr> blocksVector;
+   grid->getBlocks(0, blocksVector);
+   int del = 0;
+   BOOST_FOREACH(Block3DPtr block, blocksVector)
+   {
+      grid->deleteBlock(block);
+      del++;
+   }
 
    // restore the grid
    CoordinateTransformation3DPtr trafo(new CoordinateTransformation3D());
@@ -781,34 +935,34 @@ void MPIIORestartCoProcessor::readBlocks(int step)
    grid->setPeriodicX3(gridParameters->periodicX3);
 
    // regenerate blocks
-   for(int n = 0; n < blocksCount; n++)
-	{
-      LBMKernelPtr kernel(new CompressibleCumulantLBMKernel(block3dArray[n].x1, block3dArray[n].x2, block3dArray[n].x3, CompressibleCumulantLBMKernel::NORMAL));
-		kernel->setCollisionFactor(block3dArray[n].collFactor);
-		kernel->setGhostLayerWidth(block3dArray[n].ghostLayerWidth);
-		kernel->setCompressible(block3dArray[n].compressible);
-		kernel->setWithForcing(block3dArray[n].withForcing);
-		kernel->setDeltaT(block3dArray[n].deltaT);
+   for (int n = 0; n<blocksCount; n++)
+   {
+      //    LBMKernelPtr kernel(new CompressibleCumulantLBMKernel(block3dArray[n].x1, block3dArray[n].x2, block3dArray[n].x3, CompressibleCumulantLBMKernel::NORMAL));
+          //kernel->setCollisionFactor(block3dArray[n].collFactor);
+          //kernel->setGhostLayerWidth(block3dArray[n].ghostLayerWidth);
+          //kernel->setCompressible(block3dArray[n].compressible);
+          //kernel->setWithForcing(block3dArray[n].withForcing);
+          //kernel->setDeltaT(block3dArray[n].deltaT);
 
       Block3DPtr block(new Block3D(block3dArray[n].x1, block3dArray[n].x2, block3dArray[n].x3, block3dArray[n].level));
-		block->setActive(block3dArray[n].active);
-		block->setBundle(block3dArray[n].bundle);
-		block->setRank(block3dArray[n].rank);
-		block->setLocalRank(block3dArray[n].lrank);
-		block->setGlobalID(block3dArray[n].globalID);
-		block->setLocalID(block3dArray[n].localID);
-		block->setPart(block3dArray[n].part),
-		block->setLevel(block3dArray[n].level);
-		//block->setInterpolationFlagCF(block3dArray[n].interpolationFlagCF);
-		//block->setInterpolationFlagFC(block3dArray[n].interpolationFlagFC);
+      block->setActive(block3dArray[n].active);
+      block->setBundle(block3dArray[n].bundle);
+      block->setRank(block3dArray[n].rank);
+      block->setLocalRank(block3dArray[n].lrank);
+      block->setGlobalID(block3dArray[n].globalID);
+      block->setLocalID(block3dArray[n].localID);
+      block->setPart(block3dArray[n].part),
+         block->setLevel(block3dArray[n].level);
+      //block->setInterpolationFlagCF(block3dArray[n].interpolationFlagCF);
+      //block->setInterpolationFlagFC(block3dArray[n].interpolationFlagFC);
       block->interpolationFlagCF = block3dArray[n].interpolationFlagCF;
       block->interpolationFlagFC = block3dArray[n].interpolationFlagFC;
 
-		if(rank == block3dArray[n].rank)
-			block->setKernel(kernel);
+      //if(rank == block3dArray[n].rank)
+      //	block->setKernel(kernel);
 
-		grid->addBlock(block);
-	}
+      grid->addBlock(block);
+   }
 
    // define MPI_types depending on the block-specific information
    MPI_Type_contiguous(blockParamStr.doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType);
@@ -820,251 +974,310 @@ void MPIIORestartCoProcessor::readBlocks(int step)
    mpiTypeFreeFlag = true;
 
    delete gridParameters;
-	delete [] block3dArray;
+   delete[] block3dArray;
+
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestartCoProcessor::readBlocks end of restore of data, rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
 }
 
 void MPIIORestartCoProcessor::readDataSet(int step)
 {
-	int rank, size;
-	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
-	MPI_Comm_size(MPI_COMM_WORLD, &size);
+   int rank, size;
+   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+   MPI_Comm_size(MPI_COMM_WORLD, &size);
 
-	MPI_File file_handler;
-   std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpDataSet.bin";
-	int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler);
-   if(rc != MPI_SUCCESS) throw UbException(UB_EXARGS,"couldn't open file "+filename);
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestartCoProcessor::readDataSet start MPI IO rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
+   double start, finish;
+   if (comm->isRoot()) start = MPI_Wtime();
+
+   MPI_File file_handler;
+   std::string filename = path+"/mpi_io_cp/mpi_io_cp_"+UbSystem::toString(step)+"/cpDataSet.bin";
+   int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler);
+   if (rc!=MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file "+filename);
 
    // read count of blocks
    int blocksCount = 0;
-	MPI_File_read_at(file_handler, rank * sizeof(int), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE);
+   MPI_File_read_at_all(file_handler, rank*sizeof(int), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE);
 
    DataSet* dataSetArray = new DataSet[blocksCount];
    std::vector<double> doubleValuesArray(blocksCount * blockParamStr.doubleCountInBlock); // double-values in all blocks 
 
    // calculate the read offset
-   size_t read_offset = size * sizeof(int);
+   size_t read_offset = size*sizeof(int);
    size_t next_read_offset = 0;
 
-	if(size > 1)
-	{
-		if(rank == 0)
-		{
-			next_read_offset = read_offset + blocksCount * (sizeof(DataSet) + blockParamStr.doubleCountInBlock * sizeof(double));
-			MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD);
-		}
-		else
-		{
-			MPI_Recv(&read_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+   if(size > 1)
+   {
+   	if(rank == 0)
+   	{
+   		next_read_offset = read_offset + blocksCount * (sizeof(DataSet) + blockParamStr.doubleCountInBlock * sizeof(double));
+   		MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD);
+   	}
+   	else
+   	{
+   		MPI_Recv(&read_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
          next_read_offset = read_offset + blocksCount * (sizeof(DataSet) + blockParamStr.doubleCountInBlock * sizeof(double));
-			if(rank < size - 1)
-				MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD);
-		}
-	}
+   		if(rank < size - 1)
+   			MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD);
+   	}
+   }
 
-   MPI_File_read_at_all(file_handler, read_offset, &dataSetArray[0], blocksCount, dataSetType, MPI_STATUS_IGNORE);
-	MPI_File_read_at_all(file_handler, read_offset + blocksCount * sizeof(DataSet), &doubleValuesArray[0], blocksCount, dataSetDoubleType, MPI_STATUS_IGNORE);
-	//MPI_File_sync(file_handler);
-	MPI_File_close(&file_handler);
+   MPI_File_read_at_all(file_handler, read_offset, dataSetArray, blocksCount, dataSetType, MPI_STATUS_IGNORE);
+   MPI_File_read_at_all(file_handler, read_offset+blocksCount*sizeof(DataSet), &doubleValuesArray[0], blocksCount, dataSetDoubleType, MPI_STATUS_IGNORE);
+   //MPI_File_sync(file_handler);
+   MPI_File_close(&file_handler);
 
-	size_t index = 0, nextVectorSize = 0;
+   if (comm->isRoot())
+   {
+      finish = MPI_Wtime();
+      UBLOG(logINFO, "MPIIORestartCoProcessor::readDataSet time: "<<finish-start<<" s");
+      UBLOG(logINFO, "MPIIORestartCoProcessor::readDataSet start of restore of data, rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
+
+   size_t index = 0, nextVectorSize = 0;
    std::vector<double> vectorsOfValues[9];
-   for (int n = 0; n < blocksCount; n++)
+   for (int n = 0; n<blocksCount; n++)
    {
-      for(int b = 0; b < 9; b++) // assign approciate vectors for 9 dataSet arrays
-		{
-         nextVectorSize = blockParamStr.nx[b][0] * blockParamStr.nx[b][1] * blockParamStr.nx[b][2] * blockParamStr.nx[b][3];
-         vectorsOfValues[b].assign(doubleValuesArray.data() + index, doubleValuesArray.data() + index + nextVectorSize);
+      for (int b = 0; b<9; b++) // assign approciate vectors for 9 dataSet arrays
+      {
+         nextVectorSize = blockParamStr.nx[b][0]*blockParamStr.nx[b][1]*blockParamStr.nx[b][2]*blockParamStr.nx[b][3];
+         vectorsOfValues[b].assign(doubleValuesArray.data()+index, doubleValuesArray.data()+index+nextVectorSize);
          index += nextVectorSize;
-		}
+      }
 
       // fill dataSet arrays
-		AverageValuesArray3DPtr mAverageValues;
-		if((blockParamStr.nx[0][0] == 0)&&(blockParamStr.nx[0][1] == 0)&&(blockParamStr.nx[0][2] == 0)&&(blockParamStr.nx[0][3] == 0))
-			mAverageValues = CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr(); 
-		else
-			mAverageValues = CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal,IndexerX4X3X2X1>(vectorsOfValues[0], blockParamStr.nx[0][0], blockParamStr.nx[0][1], blockParamStr.nx[0][2], blockParamStr.nx[0][3]));
+      AverageValuesArray3DPtr mAverageValues;
+      if ((blockParamStr.nx[0][0]==0)&&(blockParamStr.nx[0][1]==0)&&(blockParamStr.nx[0][2]==0)&&(blockParamStr.nx[0][3]==0))
+         mAverageValues = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr();
+      else
+         mAverageValues = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[0], blockParamStr.nx[0][0], blockParamStr.nx[0][1], blockParamStr.nx[0][2], blockParamStr.nx[0][3]));
 
       AverageValuesArray3DPtr mAverageVelocity;
-		if((blockParamStr.nx[1][0] == 0)&&(blockParamStr.nx[1][1] == 0)&&(blockParamStr.nx[1][2] == 0)&&(blockParamStr.nx[1][3] == 0))
-			mAverageVelocity = CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr(); 
-		else
-			mAverageVelocity = CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal,IndexerX4X3X2X1>(vectorsOfValues[1], blockParamStr.nx[1][0], blockParamStr.nx[1][1], blockParamStr.nx[1][2], blockParamStr.nx[1][3]));
+      if ((blockParamStr.nx[1][0]==0)&&(blockParamStr.nx[1][1]==0)&&(blockParamStr.nx[1][2]==0)&&(blockParamStr.nx[1][3]==0))
+         mAverageVelocity = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr();
+      else
+         mAverageVelocity = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[1], blockParamStr.nx[1][0], blockParamStr.nx[1][1], blockParamStr.nx[1][2], blockParamStr.nx[1][3]));
 
       AverageValuesArray3DPtr mAverageFluktuations;
-		if((blockParamStr.nx[2][0] == 0)&&(blockParamStr.nx[2][1] == 0)&&(blockParamStr.nx[2][2] == 0)&&(blockParamStr.nx[2][3] == 0))
-			mAverageFluktuations = CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr(); 
-		else
-			mAverageFluktuations = CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal,IndexerX4X3X2X1>(vectorsOfValues[2], blockParamStr.nx[2][0], blockParamStr.nx[2][1], blockParamStr.nx[2][2], blockParamStr.nx[2][3]));
+      if ((blockParamStr.nx[2][0]==0)&&(blockParamStr.nx[2][1]==0)&&(blockParamStr.nx[2][2]==0)&&(blockParamStr.nx[2][3]==0))
+         mAverageFluktuations = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr();
+      else
+         mAverageFluktuations = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[2], blockParamStr.nx[2][0], blockParamStr.nx[2][1], blockParamStr.nx[2][2], blockParamStr.nx[2][3]));
 
       AverageValuesArray3DPtr mAverageTriplecorrelations;
-		if((blockParamStr.nx[3][0] == 0)&&(blockParamStr.nx[3][1] == 0)&&(blockParamStr.nx[3][2] == 0)&&(blockParamStr.nx[3][3] == 0))
-			mAverageTriplecorrelations = CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr(); 
-		else
-			mAverageTriplecorrelations = CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal,IndexerX4X3X2X1>(vectorsOfValues[3], blockParamStr.nx[3][0], blockParamStr.nx[3][1], blockParamStr.nx[3][2], blockParamStr.nx[3][3]));
+      if ((blockParamStr.nx[3][0]==0)&&(blockParamStr.nx[3][1]==0)&&(blockParamStr.nx[3][2]==0)&&(blockParamStr.nx[3][3]==0))
+         mAverageTriplecorrelations = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr();
+      else
+         mAverageTriplecorrelations = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[3], blockParamStr.nx[3][0], blockParamStr.nx[3][1], blockParamStr.nx[3][2], blockParamStr.nx[3][3]));
 
       ShearStressValuesArray3DPtr mShearStressValues;
-		if((blockParamStr.nx[4][0] == 0)&&(blockParamStr.nx[4][1] == 0)&&(blockParamStr.nx[4][2] == 0)&&(blockParamStr.nx[4][3] == 0))
-			mShearStressValues = CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr(); 
-		else
-			mShearStressValues = CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal,IndexerX4X3X2X1>(vectorsOfValues[4], blockParamStr.nx[4][0], blockParamStr.nx[4][1], blockParamStr.nx[4][2], blockParamStr.nx[4][3]));
-		
+      if ((blockParamStr.nx[4][0]==0)&&(blockParamStr.nx[4][1]==0)&&(blockParamStr.nx[4][2]==0)&&(blockParamStr.nx[4][3]==0))
+         mShearStressValues = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr();
+      else
+         mShearStressValues = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[4], blockParamStr.nx[4][0], blockParamStr.nx[4][1], blockParamStr.nx[4][2], blockParamStr.nx[4][3]));
+
       RelaxationFactorArray3DPtr mRelaxationFactor;
-      if ((blockParamStr.nx[5][0] == 0) && (blockParamStr.nx[5][1] == 0) && (blockParamStr.nx[5][2] == 0))
+      if ((blockParamStr.nx[5][0]==0)&&(blockParamStr.nx[5][1]==0)&&(blockParamStr.nx[5][2]==0))
          mRelaxationFactor = CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr();
       else
          mRelaxationFactor = CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<LBMReal, IndexerX3X2X1>(vectorsOfValues[5], blockParamStr.nx[5][0], blockParamStr.nx[5][1], blockParamStr.nx[5][2]));
 
-		DistributionArray3DPtr mFdistributions(new D3Q27EsoTwist3DSplittedVector(blockParamStr.nx1, blockParamStr.nx2, blockParamStr.nx3, -999.0));
+      DistributionArray3DPtr mFdistributions(new D3Q27EsoTwist3DSplittedVector(blockParamStr.nx1, blockParamStr.nx2, blockParamStr.nx3, -999.0));
 
-		boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setLocalDistributions( CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal,IndexerX4X3X2X1>(vectorsOfValues[6], blockParamStr.nx[6][0], blockParamStr.nx[6][1], blockParamStr.nx[6][2], blockParamStr.nx[6][3])));
-		boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNonLocalDistributions( CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal,IndexerX4X3X2X1>(vectorsOfValues[7], blockParamStr.nx[7][0], blockParamStr.nx[7][1], blockParamStr.nx[7][2], blockParamStr.nx[7][3])));
-		boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setZeroDistributions( CbArray3D<LBMReal,IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<LBMReal,IndexerX3X2X1>(vectorsOfValues[8], blockParamStr.nx[8][0], blockParamStr.nx[8][1], blockParamStr.nx[8][2])));
+      boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[6], blockParamStr.nx[6][0], blockParamStr.nx[6][1], blockParamStr.nx[6][2], blockParamStr.nx[6][3])));
+      boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNonLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[7], blockParamStr.nx[7][0], blockParamStr.nx[7][1], blockParamStr.nx[7][2], blockParamStr.nx[7][3])));
+      boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setZeroDistributions(CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<LBMReal, IndexerX3X2X1>(vectorsOfValues[8], blockParamStr.nx[8][0], blockParamStr.nx[8][1], blockParamStr.nx[8][2])));
 
-		boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX1(blockParamStr.nx1);
-		boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX2(blockParamStr.nx2);
-		boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX3(blockParamStr.nx3);
+      boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX1(blockParamStr.nx1);
+      boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX2(blockParamStr.nx2);
+      boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX3(blockParamStr.nx3);
 
-		DataSet3DPtr dataSetPtr = DataSet3DPtr(new DataSet3D());
-		dataSetPtr->setAverageValues(mAverageValues);
-		dataSetPtr->setAverageVelocity(mAverageVelocity);
-		dataSetPtr->setAverageFluctuations(mAverageFluktuations);
-		dataSetPtr->setAverageTriplecorrelations(mAverageTriplecorrelations);
-		dataSetPtr->setShearStressValues(mShearStressValues);
-		dataSetPtr->setRelaxationFactor(mRelaxationFactor);
-		dataSetPtr->setFdistributions(mFdistributions);
+      DataSet3DPtr dataSetPtr = DataSet3DPtr(new DataSet3D());
+      dataSetPtr->setAverageValues(mAverageValues);
+      dataSetPtr->setAverageVelocity(mAverageVelocity);
+      dataSetPtr->setAverageFluctuations(mAverageFluktuations);
+      dataSetPtr->setAverageTriplecorrelations(mAverageTriplecorrelations);
+      dataSetPtr->setShearStressValues(mShearStressValues);
+      dataSetPtr->setRelaxationFactor(mRelaxationFactor);
+      dataSetPtr->setFdistributions(mFdistributions);
 
       // find the nesessary block and fill it
-		Block3DPtr block = grid->getBlock(dataSetArray[n].x1, dataSetArray[n].x2, dataSetArray[n].x3, dataSetArray[n].level);
-		block->getKernel()->setDataSet(dataSetPtr);
-	}
-  
-	delete [] dataSetArray;
+      Block3DPtr block = grid->getBlock(dataSetArray[n].x1, dataSetArray[n].x2, dataSetArray[n].x3, dataSetArray[n].level);
+      //LBMKernelPtr kernel(new CompressibleCumulantLBMKernel(0, 0, 0, CompressibleCumulantLBMKernel::NORMAL));
+      LBMKernelPtr kernel(new CompressibleCumulantLBMKernel());
+      kernel->setGhostLayerWidth(dataSetArray[n].ghostLayerWidth);
+      kernel->setCollisionFactor(dataSetArray[n].collFactor);
+      kernel->setDeltaT(dataSetArray[n].deltaT);
+      kernel->setCompressible(dataSetArray[n].compressible);
+      kernel->setWithForcing(dataSetArray[n].withForcing);
+      kernel->setDataSet(dataSetPtr);
+      block->setKernel(kernel);
+      //block->getKernel()->setDataSet(dataSetPtr);
+   }
+
+   delete[] dataSetArray;
+
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestartCoProcessor::readDataSet end of restore of data, rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
 }
 
 void MPIIORestartCoProcessor::readBoundaryConds(int step)
 {
-	int rank, size;
-	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
-	MPI_Comm_size(MPI_COMM_WORLD, &size);
+   int rank, size;
+   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+   MPI_Comm_size(MPI_COMM_WORLD, &size);
 
-	MPI_File file_handler;
-   std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpBC.bin";
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestartCoProcessor::readBoundaryConds start MPI IO rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
+   double start, finish;
+   if (comm->isRoot()) start = MPI_Wtime();
+
+   MPI_File file_handler;
+   std::string filename = path+"/mpi_io_cp/mpi_io_cp_"+UbSystem::toString(step)+"/cpBC.bin";
    int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler);
-   if(rc != MPI_SUCCESS) throw UbException(UB_EXARGS,"couldn't open file "+filename);
+   if (rc!=MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file "+filename);
 
-	int blocksCount = 0;
+   int blocksCount = 0;
    int dataCount1000 = 0;
    int dataCount2 = 0;
    // read count of blocks
-	MPI_File_read_at(file_handler, rank * sizeof(int), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE);
+   MPI_File_read_at_all(file_handler, rank*sizeof(int), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE);
    // read count of big BoundaryCondition blocks
-   MPI_File_read_at(file_handler, (rank + size) * sizeof(int), &dataCount1000, 1, MPI_INT, MPI_STATUS_IGNORE);
+   MPI_File_read_at_all(file_handler, (rank+size)*sizeof(int), &dataCount1000, 1, MPI_INT, MPI_STATUS_IGNORE);
    // read count of indexContainer values in all blocks
-   MPI_File_read_at(file_handler, (rank + 2 * size) * sizeof(int), &dataCount2, 1, MPI_INT, MPI_STATUS_IGNORE);
+   MPI_File_read_at_all(file_handler, (rank+2*size)*sizeof(int), &dataCount2, 1, MPI_INT, MPI_STATUS_IGNORE);
 
    size_t dataCount = dataCount1000 * BLOCK_SIZE;
-	BCAdd* bcAddArray = new BCAdd[blocksCount];
-	BoundaryCondition* bcArray = new BoundaryCondition[dataCount];
-	BoundaryCondition* nullBouCond = new BoundaryCondition();
-	memset(nullBouCond, 0, sizeof(BoundaryCondition));
-	int* intArray1 = new int[blocksCount * blockParamStr.bcindexmatrix_count];
-	int* intArray2 = new int[dataCount2];
-
-   size_t read_offset = 3 * size * sizeof(int);
+   BCAdd* bcAddArray = new BCAdd[blocksCount];
+   BoundaryCondition* bcArray = new BoundaryCondition[dataCount];
+   BoundaryCondition* nullBouCond = new BoundaryCondition();
+   memset(nullBouCond, 0, sizeof(BoundaryCondition));
+   int* intArray1 = new int[blocksCount * blockParamStr.bcindexmatrix_count];
+   int* intArray2 = new int[dataCount2];
+
+   size_t read_offset = 3*size*sizeof(int);
    size_t next_read_offset = 0;
 
-	if(size > 1)
-	{
-		if(rank == 0)
-		{
-			next_read_offset = read_offset + blocksCount * sizeof(BCAdd) + dataCount * sizeof(BoundaryCondition) + (blocksCount * blockParamStr.bcindexmatrix_count + dataCount2) * sizeof(int);
-			MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD);
-		}
-		else
-		{
-			MPI_Recv(&read_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
-			next_read_offset = read_offset + blocksCount * sizeof(BCAdd) + dataCount * sizeof(BoundaryCondition) + (blocksCount * blockParamStr.bcindexmatrix_count + dataCount2) * sizeof(int);
-			if(rank < size - 1)
-				MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD);
-		}
-	}
+   if (size>1)
+   {
+      if (rank==0)
+      {
+         next_read_offset = read_offset+blocksCount*sizeof(BCAdd)+dataCount*sizeof(BoundaryCondition)+(blocksCount * blockParamStr.bcindexmatrix_count+dataCount2)*sizeof(int);
+         MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD);
+      }
+      else
+      {
+         MPI_Recv(&read_offset, 1, MPI_LONG_LONG_INT, rank-1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+         next_read_offset = read_offset+blocksCount*sizeof(BCAdd)+dataCount*sizeof(BoundaryCondition)+(blocksCount * blockParamStr.bcindexmatrix_count+dataCount2)*sizeof(int);
+         if (rank<size-1)
+            MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, rank+1, 5, MPI_COMM_WORLD);
+      }
+   }
 
    MPI_File_read_at_all(file_handler, read_offset, &bcAddArray[0], blocksCount, boundCondTypeAdd, MPI_STATUS_IGNORE);
-	MPI_File_read_at_all(file_handler, read_offset + blocksCount * sizeof(BCAdd), &bcArray[0], dataCount1000, boundCondType1000, MPI_STATUS_IGNORE);
-	MPI_File_read_at_all(file_handler, read_offset + blocksCount * sizeof(BCAdd) + dataCount * sizeof(BoundaryCondition), &intArray1[0], blocksCount, bcindexmatrixType, MPI_STATUS_IGNORE);
-	MPI_File_read_at_all(file_handler, read_offset + blocksCount * sizeof(BCAdd) + dataCount * sizeof(BoundaryCondition) + blocksCount * blockParamStr.bcindexmatrix_count * sizeof(int), &intArray2[0], dataCount2, MPI_INT, MPI_STATUS_IGNORE);
-	//MPI_File_sync(file_handler);
+   MPI_File_read_at_all(file_handler, read_offset+blocksCount*sizeof(BCAdd), &bcArray[0], dataCount1000, boundCondType1000, MPI_STATUS_IGNORE);
+   MPI_File_read_at_all(file_handler, read_offset+blocksCount*sizeof(BCAdd)+dataCount*sizeof(BoundaryCondition), &intArray1[0], blocksCount, bcindexmatrixType, MPI_STATUS_IGNORE);
+   MPI_File_read_at_all(file_handler, read_offset+blocksCount*sizeof(BCAdd)+dataCount*sizeof(BoundaryCondition)+blocksCount * blockParamStr.bcindexmatrix_count*sizeof(int), &intArray2[0], dataCount2, MPI_INT, MPI_STATUS_IGNORE);
+   //MPI_File_sync(file_handler);
 
-	MPI_File_close(&file_handler);
+   MPI_File_close(&file_handler);
 
-	int index = 0, index1 = 0, index2 = 0;
-	std::vector<BoundaryConditionsPtr> bcVector;
-	std::vector<int> bcindexmatrixV;
-	std::vector<int> indexContainerV;
+   if (comm->isRoot())
+   {
+      finish = MPI_Wtime();
+      UBLOG(logINFO, "MPIIORestartCoProcessor::readBoundaryConds time: "<<finish-start<<" s");
+      UBLOG(logINFO, "MPIIORestartCoProcessor::readBoundaryConds start of restore of data, rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
 
-	for(size_t n = 0; n < blocksCount; n++)
-	{
-		bcVector.resize(0);
+   int index = 0, index1 = 0, index2 = 0;
+   std::vector<BoundaryConditionsPtr> bcVector;
+   std::vector<int> bcindexmatrixV;
+   std::vector<int> indexContainerV;
+
+   for (size_t n = 0; n<blocksCount; n++)
+   {
+      bcVector.resize(0);
       bcindexmatrixV.resize(0);
       indexContainerV.resize(0);
 
-		for(size_t ibc = 0; ibc < bcAddArray[n].boundCond_count; ibc++)
-		{
+      for (size_t ibc = 0; ibc<bcAddArray[n].boundCond_count; ibc++)
+      {
          BoundaryConditionsPtr bc;
-			if(memcmp(&bcArray[index], nullBouCond, sizeof(BoundaryCondition)) == 0)
-				bc = BoundaryConditionsPtr();
-			else
-			{
-				bc = BoundaryConditionsPtr(new BoundaryConditions);
-				bc->noslipBoundaryFlags = bcArray[index].noslipBoundaryFlags;
-				bc->slipBoundaryFlags = bcArray[index].slipBoundaryFlags;
-				bc->densityBoundaryFlags = bcArray[index].densityBoundaryFlags;
-				bc->velocityBoundaryFlags = bcArray[index].velocityBoundaryFlags;
-				bc->wallModelBoundaryFlags = bcArray[index].wallModelBoundaryFlags;
-				bc->bcVelocityX1 = bcArray[index].bcVelocityX1;
-				bc->bcVelocityX2 = bcArray[index].bcVelocityX2;
-				bc->bcVelocityX3 = bcArray[index].bcVelocityX3;
-				bc->bcDensity = bcArray[index].bcDensity;
-				bc->bcLodiDensity = bcArray[index].bcLodiDensity;
-				bc->bcLodiVelocityX1 = bcArray[index].bcLodiVelocityX1;
-				bc->bcLodiVelocityX2 = bcArray[index].bcLodiVelocityX2;
-				bc->bcLodiVelocityX3 = bcArray[index].bcLodiVelocityX3;
-				bc->bcLodiLentgh = bcArray[index].bcLodiLentgh;
-
-				bc->nx1 = bcArray[index].nx1;
-				bc->nx2 = bcArray[index].nx2;
-				bc->nx3 = bcArray[index].nx3;
-				for(int iq = 0; iq < 26; iq++)
-					bc->setQ(bcArray[index].q[iq], iq);
+         if (memcmp(&bcArray[index], nullBouCond, sizeof(BoundaryCondition))==0)
+            bc = BoundaryConditionsPtr();
+         else
+         {
+            bc = BoundaryConditionsPtr(new BoundaryConditions);
+            bc->noslipBoundaryFlags = bcArray[index].noslipBoundaryFlags;
+            bc->slipBoundaryFlags = bcArray[index].slipBoundaryFlags;
+            bc->densityBoundaryFlags = bcArray[index].densityBoundaryFlags;
+            bc->velocityBoundaryFlags = bcArray[index].velocityBoundaryFlags;
+            bc->wallModelBoundaryFlags = bcArray[index].wallModelBoundaryFlags;
+            bc->bcVelocityX1 = bcArray[index].bcVelocityX1;
+            bc->bcVelocityX2 = bcArray[index].bcVelocityX2;
+            bc->bcVelocityX3 = bcArray[index].bcVelocityX3;
+            bc->bcDensity = bcArray[index].bcDensity;
+            bc->bcLodiDensity = bcArray[index].bcLodiDensity;
+            bc->bcLodiVelocityX1 = bcArray[index].bcLodiVelocityX1;
+            bc->bcLodiVelocityX2 = bcArray[index].bcLodiVelocityX2;
+            bc->bcLodiVelocityX3 = bcArray[index].bcLodiVelocityX3;
+            bc->bcLodiLentgh = bcArray[index].bcLodiLentgh;
+
+            bc->nx1 = bcArray[index].nx1;
+            bc->nx2 = bcArray[index].nx2;
+            bc->nx3 = bcArray[index].nx3;
+            for (int iq = 0; iq<26; iq++)
+               bc->setQ(bcArray[index].q[iq], iq);
             bc->setBcAlgorithmType(bcArray[index].algorithmType);
          }
 
-			bcVector.push_back(bc);
-			index++;	
-		}
+         bcVector.push_back(bc);
+         index++;
+      }
 
-		for(int b1 = 0; b1 < blockParamStr.bcindexmatrix_count; b1++)
-			bcindexmatrixV.push_back(intArray1[index1++]);
+      for (int b1 = 0; b1<blockParamStr.bcindexmatrix_count; b1++)
+         bcindexmatrixV.push_back(intArray1[index1++]);
 
-		for(int b2 = 0; b2 < bcAddArray[n].indexContainer_count; b2++)
-			indexContainerV.push_back(intArray2[index2++]);
+      for (int b2 = 0; b2<bcAddArray[n].indexContainer_count; b2++)
+         indexContainerV.push_back(intArray2[index2++]);
 
-		CbArray3D<int,IndexerX3X2X1> bcim(bcindexmatrixV, blockParamStr.nx1, blockParamStr.nx2, blockParamStr.nx3);
-      
-		BCProcessorPtr bcProc(new BCProcessor());
-		BCArray3D &bcArr = bcProc->getBCArray();
-		bcArr.bcindexmatrix = bcim;
-		bcArr.bcvector = bcVector;
-		bcArr.indexContainer = indexContainerV;
-		
-		Block3DPtr block = grid->getBlock(bcAddArray[n].x1, bcAddArray[n].x2, bcAddArray[n].x3, bcAddArray[n].level);
-		block->getKernel()->setBCProcessor(bcProc);
-	}
-
-	delete nullBouCond;
-	delete[] bcArray;
-	delete[] bcAddArray;
+      CbArray3D<int, IndexerX3X2X1> bcim(bcindexmatrixV, blockParamStr.nx1, blockParamStr.nx2, blockParamStr.nx3);
+
+      BCProcessorPtr bcProc(new BCProcessor());
+      BCArray3D &bcArr = bcProc->getBCArray();
+      bcArr.bcindexmatrix = bcim;
+      bcArr.bcvector = bcVector;
+      bcArr.indexContainer = indexContainerV;
+
+      Block3DPtr block = grid->getBlock(bcAddArray[n].x1, bcAddArray[n].x2, bcAddArray[n].x3, bcAddArray[n].level);
+      block->getKernel()->setBCProcessor(bcProc);
+   }
+
+   delete nullBouCond;
+   delete[] bcArray;
+   delete[] bcAddArray;
    delete[] intArray1;
    delete[] intArray2;
+   
+   if (comm->isRoot())
+   {
+      UBLOG(logINFO, "MPIIORestartCoProcessor::readBoundaryConds end of restore of data, rank = "<<rank);
+      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
+   }
 }
 
diff --git a/source/VirtualFluidsCore/CoProcessors/MPIIORestartCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/MPIIORestartCoProcessor.h
index a2e970b0b..0bfeebee7 100644
--- a/source/VirtualFluidsCore/CoProcessors/MPIIORestartCoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/MPIIORestartCoProcessor.h
@@ -1,5 +1,5 @@
-#ifndef _MPIWRITEBLOCKSCOPROCESSOR_H_
-#define _MPIWRITEBLOCKSCOPROCESSOR_H_
+#ifndef _MPIIORestartCoProcessor_H_
+#define _MPIIORestartCoProcessor_H_
 
 #include "mpi.h"
 
@@ -55,8 +55,8 @@ class MPIIORestartCoProcessor: public CoProcessor
    //! and to read it when restoring the grid
    struct Block3d
 	{
-		double collFactor;
-		double deltaT;
+		//double collFactor;
+		//double deltaT;
 		int x1;
 		int x2;
 		int x3;
@@ -70,10 +70,10 @@ class MPIIORestartCoProcessor: public CoProcessor
 		int interpolationFlagCF;
 		int interpolationFlagFC;
 		int counter;
-		int ghostLayerWidth;
+		//int ghostLayerWidth;
 		bool active;
-		bool compressible;
-		bool withForcing;
+		//bool compressible;
+		//bool withForcing;
 	};
 
    //! \struct dataSet
@@ -81,10 +81,15 @@ class MPIIORestartCoProcessor: public CoProcessor
    //! \details The structure is used to find the needed block in the grid when restoring a dataSet
    struct DataSet
 	{
-		int x1;  
+      double collFactor;
+      double deltaT;
+      int x1;  
 		int x2;  
 		int x3;  
 		int level;
+      int ghostLayerWidth;
+      bool compressible;
+      bool withForcing;
    };
    
    //! \struct BoundaryCondition
diff --git a/source/VirtualFluidsCore/Connectors/D3Q27ETFCOffVectorConnector.h b/source/VirtualFluidsCore/Connectors/D3Q27ETFCOffVectorConnector.h
index 6d3eafe7f..beac22bfd 100644
--- a/source/VirtualFluidsCore/Connectors/D3Q27ETFCOffVectorConnector.h
+++ b/source/VirtualFluidsCore/Connectors/D3Q27ETFCOffVectorConnector.h
@@ -1074,7 +1074,7 @@ void D3Q27ETFCOffVectorConnector< VectorTransmitter>::distributeReceiveVector(Di
 			{
 				D3Q27ICell icellF;
 				this->readICellFfromData(data, index, icellF);
-				iprocessor->writeICell(fTo, icellF, ix1, ix2, ix3);
+				iprocessor->writeICellInv(fTo, icellF, ix1, ix2, ix3);
 			}
 		}
 	}
diff --git a/source/VirtualFluidsCore/Connectors/FineToCoarseNodeSetBlock3DConnector.cpp b/source/VirtualFluidsCore/Connectors/FineToCoarseNodeSetBlock3DConnector.cpp
index e66ae37bf..dcf57e1d4 100644
--- a/source/VirtualFluidsCore/Connectors/FineToCoarseNodeSetBlock3DConnector.cpp
+++ b/source/VirtualFluidsCore/Connectors/FineToCoarseNodeSetBlock3DConnector.cpp
@@ -1126,7 +1126,7 @@ void FineToCoarseNodeSetBlock3DConnector::distributeReceiveVectors()
    {
       D3Q27ICell icellF;
       this->readICellFfromData(data, index, icellF);
-      iprocessor->writeICell(fTo, icellF, inode[0], inode[1], inode[2]);
+      iprocessor->writeICellInv(fTo, icellF, inode[0], inode[1], inode[2]);
    }
 }
 //////////////////////////////////////////////////////////////////////////
diff --git a/source/VirtualFluidsCore/Data/D3Q27EsoTwist3DSplittedVector.h b/source/VirtualFluidsCore/Data/D3Q27EsoTwist3DSplittedVector.h
index c3badacb8..9793f249f 100644
--- a/source/VirtualFluidsCore/Data/D3Q27EsoTwist3DSplittedVector.h
+++ b/source/VirtualFluidsCore/Data/D3Q27EsoTwist3DSplittedVector.h
@@ -64,6 +64,7 @@ protected:
    size_t NX1, NX2, NX3;
 
    friend class MPIIORestartCoProcessor;
+   friend class MPIIORestart2CoProcessor;
 
    friend class boost::serialization::access;
    template<class Archive>
diff --git a/source/VirtualFluidsCore/Geometry/VoxelMatrix.h b/source/VirtualFluidsCore/Geometry/VoxelMatrix.h
new file mode 100644
index 000000000..088d7e6d8
--- /dev/null
+++ b/source/VirtualFluidsCore/Geometry/VoxelMatrix.h
@@ -0,0 +1,57 @@
+//template <class T>
+//struct OriginVoxelMatrix
+//{
+//   CbArray3D<T> matrix;
+//};
+////////////////////////////////////////////////////////////////////////////
+//template <class T>
+//void GbVoxelMatrix3D::readOriginMatrixFromRawFile(std::string filename, GbVoxelMatrix3D::Endian endian)
+//{
+//   using namespace std;
+//   ifstream in(filename.c_str(), ios::binary);
+//   if (!in) throw UbException(UB_EXARGS, "could not open file "+filename);
+//
+//   in.seekg(0, ios::end);     //Ende springen
+//   fstream::off_type length = in.tellg(); //Position abfragen
+//   in.seekg(0, ios::beg);    //An den Anfang springen 
+//
+//   unsigned long long nofn = (unsigned long long)nodesX1*(unsigned long long)nodesX2*(unsigned long long)nodesX3*(unsigned long long)sizeof(T);
+//   if (nofn!=(unsigned long long)length)
+//   {
+//      throw UbException(UB_EXARGS, "number of nodes("+UbSystem::toString(nofn)+") doesn't match file size("+UbSystem::toString((long)length)+")");
+//   }
+//
+//   GbVoxelMatrix3D::oVoxelMatrix3D<T> = CbArray3D<T>(nodesX1, nodesX2, nodesX3);
+//
+//   T val;
+//   for (int x3 = 0; x3<nodesX3; x3++)
+//      for (int x2 = 0; x2<nodesX2; x2++)
+//         for (int x1 = 0; x1<nodesX1; x1++)
+//         {
+//            in.read((char*)&val, sizeof(T));
+//            if (endian==BigEndian)
+//               UbSystem::swapByteOrder((unsigned char*)(&(val)), sizeof(T));
+//            oVoxelMatrix3D<T>(x1, x2, x3) = val;
+//         }
+//}
+////////////////////////////////////////////////////////////////////////////
+//template <class T>
+//void GbVoxelMatrix3D::writeOriginMatrixFromRawFile(std::string filename)
+//{
+//   using namespace std;
+//
+//   string fn = filename;
+//
+//   FILE *file;
+//   file = fopen(fn.c_str(), "wb");
+//
+//   if (file==NULL)
+//   {
+//      std::string pathf = UbSystem::getPathFromString(fn);
+//      if (fn.size()>0) { UbSystem::makeDirectory(pathf); file = fopen(fn.c_str(), "wb"); }
+//      if (file==NULL) throw UbException(UB_EXARGS, "can not open "+fn);
+//   }
+//
+//   fwrite(GbVoxelMatrix3D::oVoxelMatrix3D<T>.getStartAdressOfSortedArray(0, 0, 0), sizeof(T), GbVoxelMatrix3D::oVoxelMatrix3D<T>.getDataVector().size(), file);
+//   fclose(file);
+//}
diff --git a/source/VirtualFluidsCore/Grid/Block3D.h b/source/VirtualFluidsCore/Grid/Block3D.h
index c0ce971c0..a235c688e 100644
--- a/source/VirtualFluidsCore/Grid/Block3D.h
+++ b/source/VirtualFluidsCore/Grid/Block3D.h
@@ -132,6 +132,7 @@ private:
   static int counter;
 
   friend class MPIIORestartCoProcessor;
+  friend class MPIIORestart2CoProcessor;
 
   friend class boost::serialization::access;
   template<class Archive>
diff --git a/source/VirtualFluidsCore/Grid/BoostSerializationClassExportHelper.h b/source/VirtualFluidsCore/Grid/BoostSerializationClassExportHelper.h
index f216f1c5b..a4d9a48d4 100644
--- a/source/VirtualFluidsCore/Grid/BoostSerializationClassExportHelper.h
+++ b/source/VirtualFluidsCore/Grid/BoostSerializationClassExportHelper.h
@@ -28,8 +28,8 @@
 #include <NoSlipBCAlgorithm.h>
 #include <HighViscosityNoSlipBCAlgorithm.h>
 #include <SlipBCAlgorithm.h>
-#include <NonReflectingDensityBCAlgorithm.h>
-#include <NonReflectingVelocityBCAlgorithm.h>
+#include <NonReflectingOutflowBCAlgorithm.h>
+#include <VelocityWithDensityBCAlgorithm.h>
 
 #include <BCAdapter.h>
 #include <DensityBCAdapter.h>
diff --git a/source/VirtualFluidsCore/Grid/PrePostBcCalculator.cpp b/source/VirtualFluidsCore/Grid/PrePostBcCalculator.cpp
index 4df4946f1..495451ce0 100644
--- a/source/VirtualFluidsCore/Grid/PrePostBcCalculator.cpp
+++ b/source/VirtualFluidsCore/Grid/PrePostBcCalculator.cpp
@@ -47,14 +47,6 @@ void PrePostBcCalculator::calculate(const double& endTime, CalculationManagerPtr
 
       for(calcStep=startStep; calcStep<=anzCalcSteps+1; calcStep++)
       {
-
-         //exchange data between blocks for visualization
-         //sync->wait();
-         ////if(visScheduler->isDue((double)(calcStep-1)))
-         ////{
-         //   //exchangeBlockData(minInitLevel, maxInitLevel, true);
-         ////}
-
          ////wait for write dump files
          //sync->wait();
          //write dump 
@@ -83,8 +75,7 @@ void PrePostBcCalculator::calculate(const double& endTime, CalculationManagerPtr
 #endif
 //////////////////////////////////////////////////////////////////////////
 
-            //applyPreCollisionBC(straightStartLevel, maxInitLevel);
-
+            applyPreCollisionBC(straightStartLevel, maxInitLevel);
 
             calculateBlocks(straightStartLevel, maxInitLevel);
             ////calculateBlocks(minInitLevel, maxInitLevel, staggeredStep);
@@ -104,7 +95,7 @@ void PrePostBcCalculator::calculate(const double& endTime, CalculationManagerPtr
             //UBLOG(logINFO, "exchangeBlockData time = " <<time);
 #endif
 //////////////////////////////////////////////////////////////////////////
-            //applyBCs(straightStartLevel, maxInitLevel);
+
             applyPostCollisionBC(straightStartLevel, maxInitLevel);
             
 //////////////////////////////////////////////////////////////////////////
@@ -117,10 +108,6 @@ void PrePostBcCalculator::calculate(const double& endTime, CalculationManagerPtr
             //swap distributions in kernel
             swapDistributions(straightStartLevel, maxInitLevel);
 
-            //pre-collision boundary conditions
-            exchangeBlockData(straightStartLevel, maxInitLevel);
-            applyPreCollisionBC(straightStartLevel, maxInitLevel);
-
 //////////////////////////////////////////////////////////////////////////
 #ifdef TIMING
             time[3] = timer.stop();
diff --git a/source/VirtualFluidsCore/LBM/CompressibleCumulantLBMKernel.cpp b/source/VirtualFluidsCore/LBM/CompressibleCumulantLBMKernel.cpp
index 5b9b88c27..f2f5c0981 100644
--- a/source/VirtualFluidsCore/LBM/CompressibleCumulantLBMKernel.cpp
+++ b/source/VirtualFluidsCore/LBM/CompressibleCumulantLBMKernel.cpp
@@ -10,7 +10,14 @@
 //////////////////////////////////////////////////////////////////////////
 CompressibleCumulantLBMKernel::CompressibleCumulantLBMKernel()
 {
-
+   this->nx1 = 0;
+   this->nx2 = 0;
+   this->nx3 = 0;
+   this->parameter = NORMAL;
+   this->OxyyMxzz = 1.0;
+   this->compressible = true;
+   this->bulkOmegaToOmega = false;
+   this->OxxPyyPzz = 1.0;
 }
 //////////////////////////////////////////////////////////////////////////
 CompressibleCumulantLBMKernel::CompressibleCumulantLBMKernel(int nx1, int nx2, int nx3, Parameter p) 
@@ -18,8 +25,11 @@ CompressibleCumulantLBMKernel::CompressibleCumulantLBMKernel(int nx1, int nx2, i
    this->nx1 = nx1;
    this->nx2 = nx2;
    this->nx3 = nx3;
-   parameter = p;
+   this->parameter = p;
+   this->OxyyMxzz = 1.0;
    this->compressible = true;
+   this->bulkOmegaToOmega = false;
+   this->OxxPyyPzz = 1.0;
 }
 //////////////////////////////////////////////////////////////////////////
 CompressibleCumulantLBMKernel::~CompressibleCumulantLBMKernel(void)
@@ -49,11 +59,20 @@ LBMKernelPtr CompressibleCumulantLBMKernel::clone()
    {
    case NORMAL:
       boost::dynamic_pointer_cast<CompressibleCumulantLBMKernel>(kernel)->OxyyMxzz = 1.0;
-   	break;
+      break;
    case MAGIC:
       boost::dynamic_pointer_cast<CompressibleCumulantLBMKernel>(kernel)->OxyyMxzz = 2.0 +(-collFactor);
       break;
    }
+
+   if (bulkOmegaToOmega)
+   {
+      boost::dynamic_pointer_cast<CompressibleCumulantLBMKernel>(kernel)->OxxPyyPzz = collFactor;
+   }
+   else
+   {
+       boost::dynamic_pointer_cast<CompressibleCumulantLBMKernel>(kernel)->OxxPyyPzz = one;
+   }
    return kernel;
 }
 //////////////////////////////////////////////////////////////////////////
@@ -71,21 +90,21 @@ void CompressibleCumulantLBMKernel::collideAll()
    //initializing of forcing stuff 
    if (withForcing)
    {
-      muForcingX1.DefineVar("x1",&muX1); muForcingX1.DefineVar("x2",&muX2); muForcingX1.DefineVar("x3",&muX3);
-      muForcingX2.DefineVar("x1",&muX1); muForcingX2.DefineVar("x2",&muX2); muForcingX2.DefineVar("x3",&muX3);
-      muForcingX3.DefineVar("x1",&muX1); muForcingX3.DefineVar("x2",&muX2); muForcingX3.DefineVar("x3",&muX3);
+      muForcingX1.DefineVar("x1", &muX1); muForcingX1.DefineVar("x2", &muX2); muForcingX1.DefineVar("x3", &muX3);
+      muForcingX2.DefineVar("x1", &muX1); muForcingX2.DefineVar("x2", &muX2); muForcingX2.DefineVar("x3", &muX3);
+      muForcingX3.DefineVar("x1", &muX1); muForcingX3.DefineVar("x2", &muX2); muForcingX3.DefineVar("x3", &muX3);
 
       muDeltaT = deltaT;
 
-      muForcingX1.DefineVar("dt",&muDeltaT);
-      muForcingX2.DefineVar("dt",&muDeltaT);
-      muForcingX3.DefineVar("dt",&muDeltaT);
+      muForcingX1.DefineVar("dt", &muDeltaT);
+      muForcingX2.DefineVar("dt", &muDeltaT);
+      muForcingX3.DefineVar("dt", &muDeltaT);
 
       muNu = (1.0/3.0)*(1.0/collFactor - 1.0/2.0);
 
-      muForcingX1.DefineVar("nu",&muNu);
-      muForcingX2.DefineVar("nu",&muNu);
-      muForcingX3.DefineVar("nu",&muNu);
+      muForcingX1.DefineVar("nu", &muNu);
+      muForcingX2.DefineVar("nu", &muNu);
+      muForcingX3.DefineVar("nu", &muNu);
 
       LBMReal forcingX1 = 0;
       LBMReal forcingX2 = 0;
@@ -113,914 +132,915 @@ void CompressibleCumulantLBMKernel::collideAll()
    LBMReal omega = collFactor;
 
 
-//#pragma omp parallel num_threads(8)
-   {
-   //   int i = omp_get_thread_num();
-   //   printf_s("Hello from thread %d\n", i);
-   //}
-//#pragma omp for 
-   for(int x3 = minX3; x3 < maxX3; x3++)
+   //#pragma omp parallel num_threads(8)
    {
-      for(int x2 = minX2; x2 < maxX2; x2++)
+      //   int i = omp_get_thread_num();
+      //   printf_s("Hello from thread %d\n", i);
+      //}
+   //#pragma omp for 
+      for (int x3 = minX3; x3 < maxX3; x3++)
       {
-         for(int x1 = minX1; x1 < maxX1; x1++)
+         for (int x2 = minX2; x2 < maxX2; x2++)
          {
-            if(!bcArray.isSolid(x1,x2,x3) && !bcArray.isUndefined(x1,x2,x3))
+            for (int x1 = minX1; x1 < maxX1; x1++)
             {
-               int x1p = x1 + 1;
-               int x2p = x2 + 1;
-               int x3p = x3 + 1;
-               //////////////////////////////////////////////////////////////////////////
-               //read distribution
-               ////////////////////////////////////////////////////////////////////////////
-               //////////////////////////////////////////////////////////////////////////
-
-               //E   N  T
-               //c   c  c
-               //////////
-               //W   S  B
-               //a   a  a
-
-               //Rest ist b
-
-               //mfxyz
-               //a - negative
-               //b - null
-               //c - positive
-               
-               // a b c
-               //-1 0 1
-
-               LBMReal mfcbb = (*this->localDistributions)(D3Q27System::ET_E, x1,x2,x3);
-               LBMReal mfbcb = (*this->localDistributions)(D3Q27System::ET_N,x1,x2,x3); 
-               LBMReal mfbbc = (*this->localDistributions)(D3Q27System::ET_T,x1,x2,x3);
-               LBMReal mfccb = (*this->localDistributions)(D3Q27System::ET_NE,x1,x2,x3);
-               LBMReal mfacb = (*this->localDistributions)(D3Q27System::ET_NW,x1p,x2,x3);
-               LBMReal mfcbc = (*this->localDistributions)(D3Q27System::ET_TE,x1,x2,x3);
-               LBMReal mfabc = (*this->localDistributions)(D3Q27System::ET_TW, x1p,x2,x3);
-               LBMReal mfbcc = (*this->localDistributions)(D3Q27System::ET_TN,x1,x2,x3);
-               LBMReal mfbac = (*this->localDistributions)(D3Q27System::ET_TS,x1,x2p,x3);
-               LBMReal mfccc = (*this->localDistributions)(D3Q27System::ET_TNE,x1,x2,x3);
-               LBMReal mfacc = (*this->localDistributions)(D3Q27System::ET_TNW,x1p,x2,x3);
-               LBMReal mfcac = (*this->localDistributions)(D3Q27System::ET_TSE,x1,x2p,x3);
-               LBMReal mfaac = (*this->localDistributions)(D3Q27System::ET_TSW,x1p,x2p,x3);
-
-               LBMReal mfabb = (*this->nonLocalDistributions)(D3Q27System::ET_W,x1p,x2,x3  );
-               LBMReal mfbab = (*this->nonLocalDistributions)(D3Q27System::ET_S,x1,x2p,x3  );
-               LBMReal mfbba = (*this->nonLocalDistributions)(D3Q27System::ET_B,x1,x2,x3p  );
-               LBMReal mfaab = (*this->nonLocalDistributions)(D3Q27System::ET_SW,x1p,x2p,x3 );
-               LBMReal mfcab = (*this->nonLocalDistributions)(D3Q27System::ET_SE,x1,x2p,x3 );
-               LBMReal mfaba = (*this->nonLocalDistributions)(D3Q27System::ET_BW,x1p,x2,x3p );
-               LBMReal mfcba = (*this->nonLocalDistributions)(D3Q27System::ET_BE,x1,x2,x3p );
-               LBMReal mfbaa = (*this->nonLocalDistributions)(D3Q27System::ET_BS,x1,x2p,x3p );
-               LBMReal mfbca = (*this->nonLocalDistributions)(D3Q27System::ET_BN,x1,x2,x3p );
-               LBMReal mfaaa = (*this->nonLocalDistributions)(D3Q27System::ET_BSW,x1p,x2p,x3p);
-               LBMReal mfcaa = (*this->nonLocalDistributions)(D3Q27System::ET_BSE,x1,x2p,x3p);
-               LBMReal mfaca = (*this->nonLocalDistributions)(D3Q27System::ET_BNW,x1p,x2,x3p);
-               LBMReal mfcca = (*this->nonLocalDistributions)(D3Q27System::ET_BNE,x1,x2,x3p);
-
-               LBMReal mfbbb = (*this->zeroDistributions)(x1,x2,x3);
-
-               ////////////////////////////////////////////////////////////////////////////////////
-               LBMReal drho = ((((mfccc+mfaaa)+(mfaca+mfcac))+((mfacc+mfcaa)+(mfaac+mfcca)))+
-                  (((mfbac+mfbca)+(mfbaa+mfbcc))+((mfabc+mfcba)+(mfaba+mfcbc))+((mfacb+mfcab)+(mfaab+mfccb)))+
-                  ((mfabb+mfcbb)+(mfbab+mfbcb))+(mfbba+mfbbc))+mfbbb;
-
-               LBMReal rho = one+drho;
-               ////////////////////////////////////////////////////////////////////////////////////
-               LBMReal vvx = ((((mfccc-mfaaa)+(mfcac-mfaca))+((mfcaa-mfacc)+(mfcca-mfaac)))+
-                  (((mfcba-mfabc)+(mfcbc-mfaba))+((mfcab-mfacb)+(mfccb-mfaab)))+
-                  (mfcbb-mfabb))/rho;
-               LBMReal vvy = ((((mfccc-mfaaa)+(mfaca-mfcac))+((mfacc-mfcaa)+(mfcca-mfaac)))+
-                  (((mfbca-mfbac)+(mfbcc-mfbaa))+((mfacb-mfcab)+(mfccb-mfaab)))+
-                  (mfbcb-mfbab))/rho;
-               LBMReal vvz = ((((mfccc-mfaaa)+(mfcac-mfaca))+((mfacc-mfcaa)+(mfaac-mfcca)))+
-                  (((mfbac-mfbca)+(mfbcc-mfbaa))+((mfabc-mfcba)+(mfcbc-mfaba)))+
-                  (mfbbc-mfbba))/rho;
-               ////////////////////////////////////////////////////////////////////////////////////
-
-               //forcing 
-               ///////////////////////////////////////////////////////////////////////////////////////////
-               if (withForcing)
+               if (!bcArray.isSolid(x1, x2, x3) && !bcArray.isUndefined(x1, x2, x3))
                {
-                  muX1 = static_cast<double>(x1-1+ix1*maxX1);
-                  muX2 = static_cast<double>(x2-1+ix2*maxX2);
-                  muX3 = static_cast<double>(x3-1+ix3*maxX3);
+                  int x1p = x1 + 1;
+                  int x2p = x2 + 1;
+                  int x3p = x3 + 1;
+                  //////////////////////////////////////////////////////////////////////////
+                  //read distribution
+                  ////////////////////////////////////////////////////////////////////////////
+                  //////////////////////////////////////////////////////////////////////////
 
-                  forcingX1 = muForcingX1.Eval();
-                  forcingX2 = muForcingX2.Eval();
-                  forcingX3 = muForcingX3.Eval();
+                  //E   N  T
+                  //c   c  c
+                  //////////
+                  //W   S  B
+                  //a   a  a
+
+                  //Rest ist b
+
+                  //mfxyz
+                  //a - negative
+                  //b - null
+                  //c - positive
+
+                  // a b c
+                  //-1 0 1
+
+                  LBMReal mfcbb = (*this->localDistributions)(D3Q27System::ET_E, x1, x2, x3);
+                  LBMReal mfbcb = (*this->localDistributions)(D3Q27System::ET_N, x1, x2, x3);
+                  LBMReal mfbbc = (*this->localDistributions)(D3Q27System::ET_T, x1, x2, x3);
+                  LBMReal mfccb = (*this->localDistributions)(D3Q27System::ET_NE, x1, x2, x3);
+                  LBMReal mfacb = (*this->localDistributions)(D3Q27System::ET_NW, x1p, x2, x3);
+                  LBMReal mfcbc = (*this->localDistributions)(D3Q27System::ET_TE, x1, x2, x3);
+                  LBMReal mfabc = (*this->localDistributions)(D3Q27System::ET_TW, x1p, x2, x3);
+                  LBMReal mfbcc = (*this->localDistributions)(D3Q27System::ET_TN, x1, x2, x3);
+                  LBMReal mfbac = (*this->localDistributions)(D3Q27System::ET_TS, x1, x2p, x3);
+                  LBMReal mfccc = (*this->localDistributions)(D3Q27System::ET_TNE, x1, x2, x3);
+                  LBMReal mfacc = (*this->localDistributions)(D3Q27System::ET_TNW, x1p, x2, x3);
+                  LBMReal mfcac = (*this->localDistributions)(D3Q27System::ET_TSE, x1, x2p, x3);
+                  LBMReal mfaac = (*this->localDistributions)(D3Q27System::ET_TSW, x1p, x2p, x3);
+
+                  LBMReal mfabb = (*this->nonLocalDistributions)(D3Q27System::ET_W, x1p, x2, x3);
+                  LBMReal mfbab = (*this->nonLocalDistributions)(D3Q27System::ET_S, x1, x2p, x3);
+                  LBMReal mfbba = (*this->nonLocalDistributions)(D3Q27System::ET_B, x1, x2, x3p);
+                  LBMReal mfaab = (*this->nonLocalDistributions)(D3Q27System::ET_SW, x1p, x2p, x3);
+                  LBMReal mfcab = (*this->nonLocalDistributions)(D3Q27System::ET_SE, x1, x2p, x3);
+                  LBMReal mfaba = (*this->nonLocalDistributions)(D3Q27System::ET_BW, x1p, x2, x3p);
+                  LBMReal mfcba = (*this->nonLocalDistributions)(D3Q27System::ET_BE, x1, x2, x3p);
+                  LBMReal mfbaa = (*this->nonLocalDistributions)(D3Q27System::ET_BS, x1, x2p, x3p);
+                  LBMReal mfbca = (*this->nonLocalDistributions)(D3Q27System::ET_BN, x1, x2, x3p);
+                  LBMReal mfaaa = (*this->nonLocalDistributions)(D3Q27System::ET_BSW, x1p, x2p, x3p);
+                  LBMReal mfcaa = (*this->nonLocalDistributions)(D3Q27System::ET_BSE, x1, x2p, x3p);
+                  LBMReal mfaca = (*this->nonLocalDistributions)(D3Q27System::ET_BNW, x1p, x2, x3p);
+                  LBMReal mfcca = (*this->nonLocalDistributions)(D3Q27System::ET_BNE, x1, x2, x3p);
+
+                  LBMReal mfbbb = (*this->zeroDistributions)(x1, x2, x3);
+
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  LBMReal drho = ((((mfccc+mfaaa)+(mfaca+mfcac))+((mfacc+mfcaa)+(mfaac+mfcca)))+
+                     (((mfbac+mfbca)+(mfbaa+mfbcc))+((mfabc+mfcba)+(mfaba+mfcbc))+((mfacb+mfcab)+(mfaab+mfccb)))+
+                     ((mfabb+mfcbb)+(mfbab+mfbcb))+(mfbba+mfbbc))+mfbbb;
+
+                  LBMReal rho = one+drho;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  LBMReal vvx = ((((mfccc-mfaaa)+(mfcac-mfaca))+((mfcaa-mfacc)+(mfcca-mfaac)))+
+                     (((mfcba-mfabc)+(mfcbc-mfaba))+((mfcab-mfacb)+(mfccb-mfaab)))+
+                     (mfcbb-mfabb))/rho;
+                  LBMReal vvy = ((((mfccc-mfaaa)+(mfaca-mfcac))+((mfacc-mfcaa)+(mfcca-mfaac)))+
+                     (((mfbca-mfbac)+(mfbcc-mfbaa))+((mfacb-mfcab)+(mfccb-mfaab)))+
+                     (mfbcb-mfbab))/rho;
+                  LBMReal vvz = ((((mfccc-mfaaa)+(mfcac-mfaca))+((mfacc-mfcaa)+(mfaac-mfcca)))+
+                     (((mfbac-mfbca)+(mfbcc-mfbaa))+((mfabc-mfcba)+(mfcbc-mfaba)))+
+                     (mfbbc-mfbba))/rho;
+                  ////////////////////////////////////////////////////////////////////////////////////
+
+                  //forcing 
+                  ///////////////////////////////////////////////////////////////////////////////////////////
+                  if (withForcing)
+                  {
+                     muX1 = static_cast<double>(x1-1+ix1*maxX1);
+                     muX2 = static_cast<double>(x2-1+ix2*maxX2);
+                     muX3 = static_cast<double>(x3-1+ix3*maxX3);
+
+                     forcingX1 = muForcingX1.Eval();
+                     forcingX2 = muForcingX2.Eval();
+                     forcingX3 = muForcingX3.Eval();
+
+                     vvx += forcingX1*deltaT*0.5; // X
+                     vvy += forcingX2*deltaT*0.5; // Y
+                     vvz += forcingX3*deltaT*0.5; // Z
+                  }
+                  ///////////////////////////////////////////////////////////////////////////////////////////               
+            ////////////////////////////////////////////////////////////////////////////////////
+                  LBMReal oMdrho = one; // comp special
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  LBMReal m0, m1, m2;
+                  LBMReal vx2;
+                  LBMReal vy2;
+                  LBMReal vz2;
+                  vx2 = vvx*vvx;
+                  vy2 = vvy*vvy;
+                  vz2 = vvz*vvz;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  LBMReal wadjust;
+                  LBMReal qudricLimitP = 0.01f;// * 0.0001f;
+                  LBMReal qudricLimitM = 0.01f;// * 0.0001f;
+                  LBMReal qudricLimitD = 0.01f;// * 0.001f;
+                  //LBMReal s9 = minusomega;
+                  //test
+                  //s9 = 0.;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  //Hin
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  // mit 1/36, 1/9, 1/36, 1/9, 4/9, 1/9, 1/36, 1/9, 1/36  Konditionieren
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  // Z - Dir
+                  m2 = mfaaa+mfaac;
+                  m1 = mfaac-mfaaa;
+                  m0 = m2+mfaab;
+                  mfaaa = m0;
+                  m0 += c1o36 * oMdrho;
+                  mfaab = m1-m0 * vvz;
+                  mfaac = m2-two*	m1 * vvz+vz2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m2 = mfaba+mfabc;
+                  m1 = mfabc-mfaba;
+                  m0 = m2+mfabb;
+                  mfaba = m0;
+                  m0 += c1o9 * oMdrho;
+                  mfabb = m1-m0 * vvz;
+                  mfabc = m2-two*	m1 * vvz+vz2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m2 = mfaca+mfacc;
+                  m1 = mfacc-mfaca;
+                  m0 = m2+mfacb;
+                  mfaca = m0;
+                  m0 += c1o36 * oMdrho;
+                  mfacb = m1-m0 * vvz;
+                  mfacc = m2-two*	m1 * vvz+vz2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m2 = mfbaa+mfbac;
+                  m1 = mfbac-mfbaa;
+                  m0 = m2+mfbab;
+                  mfbaa = m0;
+                  m0 += c1o9 * oMdrho;
+                  mfbab = m1-m0 * vvz;
+                  mfbac = m2-two*	m1 * vvz+vz2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m2 = mfbba+mfbbc;
+                  m1 = mfbbc-mfbba;
+                  m0 = m2+mfbbb;
+                  mfbba = m0;
+                  m0 += c4o9 * oMdrho;
+                  mfbbb = m1-m0 * vvz;
+                  mfbbc = m2-two*	m1 * vvz+vz2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m2 = mfbca+mfbcc;
+                  m1 = mfbcc-mfbca;
+                  m0 = m2+mfbcb;
+                  mfbca = m0;
+                  m0 += c1o9 * oMdrho;
+                  mfbcb = m1-m0 * vvz;
+                  mfbcc = m2-two*	m1 * vvz+vz2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m2 = mfcaa+mfcac;
+                  m1 = mfcac-mfcaa;
+                  m0 = m2+mfcab;
+                  mfcaa = m0;
+                  m0 += c1o36 * oMdrho;
+                  mfcab = m1-m0 * vvz;
+                  mfcac = m2-two*	m1 * vvz+vz2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m2 = mfcba+mfcbc;
+                  m1 = mfcbc-mfcba;
+                  m0 = m2+mfcbb;
+                  mfcba = m0;
+                  m0 += c1o9 * oMdrho;
+                  mfcbb = m1-m0 * vvz;
+                  mfcbc = m2-two*	m1 * vvz+vz2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m2 = mfcca+mfccc;
+                  m1 = mfccc-mfcca;
+                  m0 = m2+mfccb;
+                  mfcca = m0;
+                  m0 += c1o36 * oMdrho;
+                  mfccb = m1-m0 * vvz;
+                  mfccc = m2-two*	m1 * vvz+vz2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  // mit  1/6, 0, 1/18, 2/3, 0, 2/9, 1/6, 0, 1/18 Konditionieren
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  // Y - Dir
+                  m2 = mfaaa+mfaca;
+                  m1 = mfaca-mfaaa;
+                  m0 = m2+mfaba;
+                  mfaaa = m0;
+                  m0 += c1o6 * oMdrho;
+                  mfaba = m1-m0 * vvy;
+                  mfaca = m2-two*	m1 * vvy+vy2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m2 = mfaab+mfacb;
+                  m1 = mfacb-mfaab;
+                  m0 = m2+mfabb;
+                  mfaab = m0;
+                  mfabb = m1-m0 * vvy;
+                  mfacb = m2-two*	m1 * vvy+vy2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m2 = mfaac+mfacc;
+                  m1 = mfacc-mfaac;
+                  m0 = m2+mfabc;
+                  mfaac = m0;
+                  m0 += c1o18 * oMdrho;
+                  mfabc = m1-m0 * vvy;
+                  mfacc = m2-two*	m1 * vvy+vy2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m2 = mfbaa+mfbca;
+                  m1 = mfbca-mfbaa;
+                  m0 = m2+mfbba;
+                  mfbaa = m0;
+                  m0 += c2o3 * oMdrho;
+                  mfbba = m1-m0 * vvy;
+                  mfbca = m2-two*	m1 * vvy+vy2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m2 = mfbab+mfbcb;
+                  m1 = mfbcb-mfbab;
+                  m0 = m2+mfbbb;
+                  mfbab = m0;
+                  mfbbb = m1-m0 * vvy;
+                  mfbcb = m2-two*	m1 * vvy+vy2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m2 = mfbac+mfbcc;
+                  m1 = mfbcc-mfbac;
+                  m0 = m2+mfbbc;
+                  mfbac = m0;
+                  m0 += c2o9 * oMdrho;
+                  mfbbc = m1-m0 * vvy;
+                  mfbcc = m2-two*	m1 * vvy+vy2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m2 = mfcaa+mfcca;
+                  m1 = mfcca-mfcaa;
+                  m0 = m2+mfcba;
+                  mfcaa = m0;
+                  m0 += c1o6 * oMdrho;
+                  mfcba = m1-m0 * vvy;
+                  mfcca = m2-two*	m1 * vvy+vy2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m2 = mfcab+mfccb;
+                  m1 = mfccb-mfcab;
+                  m0 = m2+mfcbb;
+                  mfcab = m0;
+                  mfcbb = m1-m0 * vvy;
+                  mfccb = m2-two*	m1 * vvy+vy2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m2 = mfcac+mfccc;
+                  m1 = mfccc-mfcac;
+                  m0 = m2+mfcbc;
+                  mfcac = m0;
+                  m0 += c1o18 * oMdrho;
+                  mfcbc = m1-m0 * vvy;
+                  mfccc = m2-two*	m1 * vvy+vy2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  // mit     1, 0, 1/3, 0, 0, 0, 1/3, 0, 1/9		Konditionieren
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  // X - Dir
+                  m2 = mfaaa+mfcaa;
+                  m1 = mfcaa-mfaaa;
+                  m0 = m2+mfbaa;
+                  mfaaa = m0;
+                  m0 += one* oMdrho;
+                  mfbaa = m1-m0 * vvx;
+                  mfcaa = m2-two*	m1 * vvx+vx2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m2 = mfaba+mfcba;
+                  m1 = mfcba-mfaba;
+                  m0 = m2+mfbba;
+                  mfaba = m0;
+                  mfbba = m1-m0 * vvx;
+                  mfcba = m2-two*	m1 * vvx+vx2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m2 = mfaca+mfcca;
+                  m1 = mfcca-mfaca;
+                  m0 = m2+mfbca;
+                  mfaca = m0;
+                  m0 += c1o3 * oMdrho;
+                  mfbca = m1-m0 * vvx;
+                  mfcca = m2-two*	m1 * vvx+vx2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m2 = mfaab+mfcab;
+                  m1 = mfcab-mfaab;
+                  m0 = m2+mfbab;
+                  mfaab = m0;
+                  mfbab = m1-m0 * vvx;
+                  mfcab = m2-two*	m1 * vvx+vx2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m2 = mfabb+mfcbb;
+                  m1 = mfcbb-mfabb;
+                  m0 = m2+mfbbb;
+                  mfabb = m0;
+                  mfbbb = m1-m0 * vvx;
+                  mfcbb = m2-two*	m1 * vvx+vx2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m2 = mfacb+mfccb;
+                  m1 = mfccb-mfacb;
+                  m0 = m2+mfbcb;
+                  mfacb = m0;
+                  mfbcb = m1-m0 * vvx;
+                  mfccb = m2-two*	m1 * vvx+vx2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m2 = mfaac+mfcac;
+                  m1 = mfcac-mfaac;
+                  m0 = m2+mfbac;
+                  mfaac = m0;
+                  m0 += c1o3 * oMdrho;
+                  mfbac = m1-m0 * vvx;
+                  mfcac = m2-two*	m1 * vvx+vx2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m2 = mfabc+mfcbc;
+                  m1 = mfcbc-mfabc;
+                  m0 = m2+mfbbc;
+                  mfabc = m0;
+                  mfbbc = m1-m0 * vvx;
+                  mfcbc = m2-two*	m1 * vvx+vx2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m2 = mfacc+mfccc;
+                  m1 = mfccc-mfacc;
+                  m0 = m2+mfbcc;
+                  mfacc = m0;
+                  m0 += c1o9 * oMdrho;
+                  mfbcc = m1-m0 * vvx;
+                  mfccc = m2-two*	m1 * vvx+vx2 * m0;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  ////////////////////////////////////////////////////////////////////////////////////
+
+
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  // Cumulants
+                  ////////////////////////////////////////////////////////////////////////////////////
+ 
+                  //LBMReal OxxPyyPzz = one; // bulk viscosity
+
+                  ////////////////////////////////////////////////////////////
+                  //3.
+                  //////////////////////////////
+                  LBMReal OxyyPxzz = one;//three  * (two - omega) / (three  - omega);//
+                  //LBMReal OxyyMxzz = one;//six    * (two - omega) / (six    - omega);//
+                  LBMReal Oxyz = one;//twelve * (two - omega) / (twelve + omega);//
+                  //////////////////////////////
+                  //LBMReal OxyyPxzz  = two-omega;//
+                  //LBMReal OxyyMxzz  = two-omega;//
+                  //////////////////////////////
+                  //LBMReal OxyyPxzz  = (eight * (omega - two)) / (omega - eight);//Ginzburg
+                  //LBMReal OxyyMxzz  = (eight * (omega - two)) / (omega - eight);//Ginzburg
+                  //////////////////////////////
+                  //LBMReal OxyyPxzz  = omega;//BGK
+                  //LBMReal OxyyMxzz  = omega;//BGK
+                  //////////////////////////////
+                  //LBMReal OxyyPxzz  = (one + omega) / two;//1P5
+                  //LBMReal OxyyMxzz  = (one + omega) / two;//1P5
+                  //////////////////////////////
+                  //LBMReal OxyyPxzz  = (three - omega) / two;//0P5
+                  //LBMReal OxyyMxzz  = (three - omega) / two;//0P5
+                  //////////////////////////////
+                  //LBMReal OxyyPxzz  = (one + (eight * (omega - two)) / (omega - eight)) / two;//one + Ginzburg / two ... Car
+                  //LBMReal OxyyMxzz  = (one + (eight * (omega - two)) / (omega - eight)) / two;//one + Ginzburg / two ... Car
+                  ////////////////////////////////////////////////////////////
+                  //4.
+                  //////////////////////////////
+                  LBMReal O4 = one;
+                  //////////////////////////////
+                  //LBMReal O4        = omega;//TRT
+                  ////////////////////////////////////////////////////////////
+                  //5.
+                  //////////////////////////////
+                  LBMReal O5 = one;
+                  ////////////////////////////////////////////////////////////
+                  //6.
+                  //////////////////////////////
+                  LBMReal O6 = one;
+                  ////////////////////////////////////////////////////////////
+
+
+                  //central moments to cumulants
+                  //4.
+                  LBMReal CUMcbb = mfcbb-((mfcaa+c1o3) * mfabb+two * mfbba * mfbab)/rho;	//ab 15.05.2015 verwendet
+                  LBMReal CUMbcb = mfbcb-((mfaca+c1o3) * mfbab+two * mfbba * mfabb)/rho; //ab 15.05.2015 verwendet
+                  LBMReal CUMbbc = mfbbc-((mfaac+c1o3) * mfbba+two * mfbab * mfabb)/rho; //ab 15.05.2015 verwendet
+
+                  LBMReal CUMcca = mfcca-(((mfcaa * mfaca+two * mfbba * mfbba)+c1o3 * (mfcaa+mfaca))/rho-c1o9*(drho/rho));
+                  LBMReal CUMcac = mfcac-(((mfcaa * mfaac+two * mfbab * mfbab)+c1o3 * (mfcaa+mfaac))/rho-c1o9*(drho/rho));
+                  LBMReal CUMacc = mfacc-(((mfaac * mfaca+two * mfabb * mfabb)+c1o3 * (mfaac+mfaca))/rho-c1o9*(drho/rho));
+
+                  //5.
+                  LBMReal CUMbcc = mfbcc-((mfaac * mfbca+mfaca * mfbac+four * mfabb * mfbbb+two * (mfbab * mfacb+mfbba * mfabc))+c1o3 * (mfbca+mfbac))/rho;
+                  LBMReal CUMcbc = mfcbc-((mfaac * mfcba+mfcaa * mfabc+four * mfbab * mfbbb+two * (mfabb * mfcab+mfbba * mfbac))+c1o3 * (mfcba+mfabc))/rho;
+                  LBMReal CUMccb = mfccb-((mfcaa * mfacb+mfaca * mfcab+four * mfbba * mfbbb+two * (mfbab * mfbca+mfabb * mfcba))+c1o3 * (mfacb+mfcab))/rho;
+
+                  //6.
+
+                  LBMReal CUMccc = mfccc+((-four *  mfbbb * mfbbb
+                     -(mfcaa * mfacc+mfaca * mfcac+mfaac * mfcca)
+                     -four * (mfabb * mfcbb+mfbab * mfbcb+mfbba * mfbbc)
+                     -two * (mfbca * mfbac+mfcba * mfabc+mfcab * mfacb))/rho
+                     +(four * (mfbab * mfbab * mfaca+mfabb * mfabb * mfcaa+mfbba * mfbba * mfaac)
+                        +two * (mfcaa * mfaca * mfaac)
+                        +sixteen *  mfbba * mfbab * mfabb)/(rho * rho)
+                     -c1o3 * (mfacc+mfcac+mfcca)/rho
+                     -c1o9 * (mfcaa+mfaca+mfaac)/rho
+                     +(two * (mfbab * mfbab+mfabb * mfabb+mfbba * mfbba)
+                        +(mfaac * mfaca+mfaac * mfcaa+mfaca * mfcaa)+c1o3 *(mfaac+mfaca+mfcaa))/(rho * rho) * c2o3
+                     +c1o27*((drho * drho-drho)/(rho*rho)));
+                  //+ c1o27*(one -three/rho +two/(rho*rho)));
+
+
+
+
+      //2.
+      // linear combinations
+                  LBMReal mxxPyyPzz = mfcaa+mfaca+mfaac;
+                  LBMReal mxxMyy = mfcaa-mfaca;
+                  LBMReal mxxMzz = mfcaa-mfaac;
 
-                  vvx += forcingX1*deltaT*0.5; // X
-                  vvy += forcingX2*deltaT*0.5; // Y
-                  vvz += forcingX3*deltaT*0.5; // Z
-               }
-               ///////////////////////////////////////////////////////////////////////////////////////////               
-         ////////////////////////////////////////////////////////////////////////////////////
-               LBMReal oMdrho = one; // comp special
-               ////////////////////////////////////////////////////////////////////////////////////
-               LBMReal m0, m1, m2;
-               LBMReal vx2;
-               LBMReal vy2;
-               LBMReal vz2;
-               vx2 = vvx*vvx;
-               vy2 = vvy*vvy;
-               vz2 = vvz*vvz;
-               ////////////////////////////////////////////////////////////////////////////////////
-               LBMReal wadjust;
-               LBMReal qudricLimitP = 0.01f;// * 0.0001f;
-               LBMReal qudricLimitM = 0.01f;// * 0.0001f;
-               LBMReal qudricLimitD = 0.01f;// * 0.001f;
-               //LBMReal s9 = minusomega;
-               //test
-               //s9 = 0.;
-               ////////////////////////////////////////////////////////////////////////////////////
-               //Hin
-               ////////////////////////////////////////////////////////////////////////////////////
-               // mit 1/36, 1/9, 1/36, 1/9, 4/9, 1/9, 1/36, 1/9, 1/36  Konditionieren
-               ////////////////////////////////////////////////////////////////////////////////////
-               // Z - Dir
-               m2 = mfaaa+mfaac;
-               m1 = mfaac-mfaaa;
-               m0 = m2+mfaab;
-               mfaaa = m0;
-               m0 += c1o36 * oMdrho;
-               mfaab = m1-m0 * vvz;
-               mfaac = m2-two*	m1 * vvz+vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2 = mfaba+mfabc;
-               m1 = mfabc-mfaba;
-               m0 = m2+mfabb;
-               mfaba = m0;
-               m0 += c1o9 * oMdrho;
-               mfabb = m1-m0 * vvz;
-               mfabc = m2-two*	m1 * vvz+vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2 = mfaca+mfacc;
-               m1 = mfacc-mfaca;
-               m0 = m2+mfacb;
-               mfaca = m0;
-               m0 += c1o36 * oMdrho;
-               mfacb = m1-m0 * vvz;
-               mfacc = m2-two*	m1 * vvz+vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2 = mfbaa+mfbac;
-               m1 = mfbac-mfbaa;
-               m0 = m2+mfbab;
-               mfbaa = m0;
-               m0 += c1o9 * oMdrho;
-               mfbab = m1-m0 * vvz;
-               mfbac = m2-two*	m1 * vvz+vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2 = mfbba+mfbbc;
-               m1 = mfbbc-mfbba;
-               m0 = m2+mfbbb;
-               mfbba = m0;
-               m0 += c4o9 * oMdrho;
-               mfbbb = m1-m0 * vvz;
-               mfbbc = m2-two*	m1 * vvz+vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2 = mfbca+mfbcc;
-               m1 = mfbcc-mfbca;
-               m0 = m2+mfbcb;
-               mfbca = m0;
-               m0 += c1o9 * oMdrho;
-               mfbcb = m1-m0 * vvz;
-               mfbcc = m2-two*	m1 * vvz+vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2 = mfcaa+mfcac;
-               m1 = mfcac-mfcaa;
-               m0 = m2+mfcab;
-               mfcaa = m0;
-               m0 += c1o36 * oMdrho;
-               mfcab = m1-m0 * vvz;
-               mfcac = m2-two*	m1 * vvz+vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2 = mfcba+mfcbc;
-               m1 = mfcbc-mfcba;
-               m0 = m2+mfcbb;
-               mfcba = m0;
-               m0 += c1o9 * oMdrho;
-               mfcbb = m1-m0 * vvz;
-               mfcbc = m2-two*	m1 * vvz+vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2 = mfcca+mfccc;
-               m1 = mfccc-mfcca;
-               m0 = m2+mfccb;
-               mfcca = m0;
-               m0 += c1o36 * oMdrho;
-               mfccb = m1-m0 * vvz;
-               mfccc = m2-two*	m1 * vvz+vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               // mit  1/6, 0, 1/18, 2/3, 0, 2/9, 1/6, 0, 1/18 Konditionieren
-               ////////////////////////////////////////////////////////////////////////////////////
-               // Y - Dir
-               m2 = mfaaa+mfaca;
-               m1 = mfaca-mfaaa;
-               m0 = m2+mfaba;
-               mfaaa = m0;
-               m0 += c1o6 * oMdrho;
-               mfaba = m1-m0 * vvy;
-               mfaca = m2-two*	m1 * vvy+vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2 = mfaab+mfacb;
-               m1 = mfacb-mfaab;
-               m0 = m2+mfabb;
-               mfaab = m0;
-               mfabb = m1-m0 * vvy;
-               mfacb = m2-two*	m1 * vvy+vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2 = mfaac+mfacc;
-               m1 = mfacc-mfaac;
-               m0 = m2+mfabc;
-               mfaac = m0;
-               m0 += c1o18 * oMdrho;
-               mfabc = m1-m0 * vvy;
-               mfacc = m2-two*	m1 * vvy+vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2 = mfbaa+mfbca;
-               m1 = mfbca-mfbaa;
-               m0 = m2+mfbba;
-               mfbaa = m0;
-               m0 += c2o3 * oMdrho;
-               mfbba = m1-m0 * vvy;
-               mfbca = m2-two*	m1 * vvy+vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2 = mfbab+mfbcb;
-               m1 = mfbcb-mfbab;
-               m0 = m2+mfbbb;
-               mfbab = m0;
-               mfbbb = m1-m0 * vvy;
-               mfbcb = m2-two*	m1 * vvy+vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2 = mfbac+mfbcc;
-               m1 = mfbcc-mfbac;
-               m0 = m2+mfbbc;
-               mfbac = m0;
-               m0 += c2o9 * oMdrho;
-               mfbbc = m1-m0 * vvy;
-               mfbcc = m2-two*	m1 * vvy+vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2 = mfcaa+mfcca;
-               m1 = mfcca-mfcaa;
-               m0 = m2+mfcba;
-               mfcaa = m0;
-               m0 += c1o6 * oMdrho;
-               mfcba = m1-m0 * vvy;
-               mfcca = m2-two*	m1 * vvy+vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2 = mfcab+mfccb;
-               m1 = mfccb-mfcab;
-               m0 = m2+mfcbb;
-               mfcab = m0;
-               mfcbb = m1-m0 * vvy;
-               mfccb = m2-two*	m1 * vvy+vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2 = mfcac+mfccc;
-               m1 = mfccc-mfcac;
-               m0 = m2+mfcbc;
-               mfcac = m0;
-               m0 += c1o18 * oMdrho;
-               mfcbc = m1-m0 * vvy;
-               mfccc = m2-two*	m1 * vvy+vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               // mit     1, 0, 1/3, 0, 0, 0, 1/3, 0, 1/9		Konditionieren
-               ////////////////////////////////////////////////////////////////////////////////////
-               // X - Dir
-               m2 = mfaaa+mfcaa;
-               m1 = mfcaa-mfaaa;
-               m0 = m2+mfbaa;
-               mfaaa = m0;
-               m0 += one* oMdrho;
-               mfbaa = m1-m0 * vvx;
-               mfcaa = m2-two*	m1 * vvx+vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2 = mfaba+mfcba;
-               m1 = mfcba-mfaba;
-               m0 = m2+mfbba;
-               mfaba = m0;
-               mfbba = m1-m0 * vvx;
-               mfcba = m2-two*	m1 * vvx+vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2 = mfaca+mfcca;
-               m1 = mfcca-mfaca;
-               m0 = m2+mfbca;
-               mfaca = m0;
-               m0 += c1o3 * oMdrho;
-               mfbca = m1-m0 * vvx;
-               mfcca = m2-two*	m1 * vvx+vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2 = mfaab+mfcab;
-               m1 = mfcab-mfaab;
-               m0 = m2+mfbab;
-               mfaab = m0;
-               mfbab = m1-m0 * vvx;
-               mfcab = m2-two*	m1 * vvx+vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2 = mfabb+mfcbb;
-               m1 = mfcbb-mfabb;
-               m0 = m2+mfbbb;
-               mfabb = m0;
-               mfbbb = m1-m0 * vvx;
-               mfcbb = m2-two*	m1 * vvx+vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2 = mfacb+mfccb;
-               m1 = mfccb-mfacb;
-               m0 = m2+mfbcb;
-               mfacb = m0;
-               mfbcb = m1-m0 * vvx;
-               mfccb = m2-two*	m1 * vvx+vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2 = mfaac+mfcac;
-               m1 = mfcac-mfaac;
-               m0 = m2+mfbac;
-               mfaac = m0;
-               m0 += c1o3 * oMdrho;
-               mfbac = m1-m0 * vvx;
-               mfcac = m2-two*	m1 * vvx+vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2 = mfabc+mfcbc;
-               m1 = mfcbc-mfabc;
-               m0 = m2+mfbbc;
-               mfabc = m0;
-               mfbbc = m1-m0 * vvx;
-               mfcbc = m2-two*	m1 * vvx+vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2 = mfacc+mfccc;
-               m1 = mfccc-mfacc;
-               m0 = m2+mfbcc;
-               mfacc = m0;
-               m0 += c1o9 * oMdrho;
-               mfbcc = m1-m0 * vvx;
-               mfccc = m2-two*	m1 * vvx+vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-
-
-               ////////////////////////////////////////////////////////////////////////////////////
-               // Cumulants
-               ////////////////////////////////////////////////////////////////////////////////////
-               LBMReal OxxPyyPzz = one; // bulk viscosity
-
-               ////////////////////////////////////////////////////////////
-               //3.
-               //////////////////////////////
-               LBMReal OxyyPxzz = one;//three  * (two - omega) / (three  - omega);//
-               LBMReal OxyyMxzz = one;//six    * (two - omega) / (six    - omega);//
-               LBMReal Oxyz = one;//twelve * (two - omega) / (twelve + omega);//
-               //////////////////////////////
-               //LBMReal OxyyPxzz  = two-omega;//
-               //LBMReal OxyyMxzz  = two-omega;//
-               //////////////////////////////
-               //LBMReal OxyyPxzz  = (eight * (omega - two)) / (omega - eight);//Ginzburg
-               //LBMReal OxyyMxzz  = (eight * (omega - two)) / (omega - eight);//Ginzburg
-               //////////////////////////////
-               //LBMReal OxyyPxzz  = omega;//BGK
-               //LBMReal OxyyMxzz  = omega;//BGK
-               //////////////////////////////
-               //LBMReal OxyyPxzz  = (one + omega) / two;//1P5
-               //LBMReal OxyyMxzz  = (one + omega) / two;//1P5
-               //////////////////////////////
-               //LBMReal OxyyPxzz  = (three - omega) / two;//0P5
-               //LBMReal OxyyMxzz  = (three - omega) / two;//0P5
-               //////////////////////////////
-               //LBMReal OxyyPxzz  = (one + (eight * (omega - two)) / (omega - eight)) / two;//one + Ginzburg / two ... Car
-               //LBMReal OxyyMxzz  = (one + (eight * (omega - two)) / (omega - eight)) / two;//one + Ginzburg / two ... Car
-               ////////////////////////////////////////////////////////////
-               //4.
-               //////////////////////////////
-               LBMReal O4 = one;
-               //////////////////////////////
-               //LBMReal O4        = omega;//TRT
-               ////////////////////////////////////////////////////////////
-               //5.
-               //////////////////////////////
-               LBMReal O5 = one;
-               ////////////////////////////////////////////////////////////
-               //6.
-               //////////////////////////////
-               LBMReal O6 = one;
-               ////////////////////////////////////////////////////////////
-
-
-               //central moments to cumulants
-               //4.
-               LBMReal CUMcbb = mfcbb-((mfcaa+c1o3) * mfabb+two * mfbba * mfbab)/rho;	//ab 15.05.2015 verwendet
-               LBMReal CUMbcb = mfbcb-((mfaca+c1o3) * mfbab+two * mfbba * mfabb)/rho; //ab 15.05.2015 verwendet
-               LBMReal CUMbbc = mfbbc-((mfaac+c1o3) * mfbba+two * mfbab * mfabb)/rho; //ab 15.05.2015 verwendet
-
-               LBMReal CUMcca = mfcca-(((mfcaa * mfaca+two * mfbba * mfbba)+c1o3 * (mfcaa+mfaca))/rho-c1o9*(drho/rho));
-               LBMReal CUMcac = mfcac-(((mfcaa * mfaac+two * mfbab * mfbab)+c1o3 * (mfcaa+mfaac))/rho-c1o9*(drho/rho));
-               LBMReal CUMacc = mfacc-(((mfaac * mfaca+two * mfabb * mfabb)+c1o3 * (mfaac+mfaca))/rho-c1o9*(drho/rho));
-
-               //5.
-               LBMReal CUMbcc = mfbcc-((mfaac * mfbca+mfaca * mfbac+four * mfabb * mfbbb+two * (mfbab * mfacb+mfbba * mfabc))+c1o3 * (mfbca+mfbac))/rho;
-               LBMReal CUMcbc = mfcbc-((mfaac * mfcba+mfcaa * mfabc+four * mfbab * mfbbb+two * (mfabb * mfcab+mfbba * mfbac))+c1o3 * (mfcba+mfabc))/rho;
-               LBMReal CUMccb = mfccb-((mfcaa * mfacb+mfaca * mfcab+four * mfbba * mfbbb+two * (mfbab * mfbca+mfabb * mfcba))+c1o3 * (mfacb+mfcab))/rho;
-
-               //6.
-
-               LBMReal CUMccc = mfccc+((-four *  mfbbb * mfbbb
-                  -(mfcaa * mfacc+mfaca * mfcac+mfaac * mfcca)
-                  -four * (mfabb * mfcbb+mfbab * mfbcb+mfbba * mfbbc)
-                  -two * (mfbca * mfbac+mfcba * mfabc+mfcab * mfacb))/rho
-                  +(four * (mfbab * mfbab * mfaca+mfabb * mfabb * mfcaa+mfbba * mfbba * mfaac)
-                     +two * (mfcaa * mfaca * mfaac)
-                     +sixteen *  mfbba * mfbab * mfabb)/(rho * rho)
-                  -c1o3 * (mfacc+mfcac+mfcca)/rho
-                  -c1o9 * (mfcaa+mfaca+mfaac)/rho
-                  +(two * (mfbab * mfbab+mfabb * mfabb+mfbba * mfbba)
-                     +(mfaac * mfaca+mfaac * mfcaa+mfaca * mfcaa)+c1o3 *(mfaac+mfaca+mfcaa))/(rho * rho) * c2o3
-                  +c1o27*((drho * drho-drho)/(rho*rho)));
-               //+ c1o27*(one -three/rho +two/(rho*rho)));
-
-
-
-
-   //2.
-   // linear combinations
-               LBMReal mxxPyyPzz = mfcaa+mfaca+mfaac;
-               LBMReal mxxMyy = mfcaa-mfaca;
-               LBMReal mxxMzz = mfcaa-mfaac;
-
-               //////////////////////////////////////////////////////////////////////////
-      // 			LBMReal magicBulk=(CUMacc+CUMcac+CUMcca)*(one/OxxPyyPzz-c1o2)*c3o2*8.;
-
-               //////////////////////////////////////////////////////////////////////////
-               //limiter-Scheise Teil 1
-               //LBMReal oxxyy,oxxzz,oxy,oxz,oyz;
-               //LBMReal smag=0.001;
-               //oxxyy    = omega+(one-omega)*abs(mxxMyy)/(abs(mxxMyy)+smag);
-               //oxxzz    = omega+(one-omega)*abs(mxxMzz)/(abs(mxxMzz)+smag);
-               //oxy      = omega+(one-omega)*abs(mfbba)/(abs(mfbba)+smag);
-               //oxz      = omega+(one-omega)*abs(mfbab)/(abs(mfbab)+smag);
-               //oyz      = omega+(one-omega)*abs(mfabb)/(abs(mfabb)+smag);
-
-               ////////////////////////////////////////////////////////////////////////////
-               ////Teil 1b
-               //LBMReal constante = 1000.0;
-               //LBMReal nuEddi = constante * abs(mxxPyyPzz);
-               //LBMReal omegaLimit = one / (one / omega + three * nuEddi);
-
-               //{
-               //	LBMReal dxux = c1o2 * (-omegaLimit) *(mxxMyy + mxxMzz) +  OxxPyyPzz * (mfaaa - mxxPyyPzz);
-               //	LBMReal dyuy = dxux + omegaLimit * c3o2 * mxxMyy;
-               //	LBMReal dzuz = dxux + omegaLimit * c3o2 * mxxMzz;
-
-                  ////relax
-                  //mxxPyyPzz += OxxPyyPzz*(mfaaa  - mxxPyyPzz)- three * (one - c1o2 * OxxPyyPzz) * (vx2 * dxux + vy2 * dyuy + vz2 * dzuz);
-                  //mxxMyy    += omegaLimit * (-mxxMyy) - three * (one + c1o2 * (-omegaLimit)) * (vx2 * dxux + vy2 * dyuy);
-                  //mxxMzz    += omegaLimit * (-mxxMzz) - three * (one + c1o2 * (-omegaLimit)) * (vx2 * dxux + vz2 * dzuz);
-
-               //}
-               //mfabb     += omegaLimit * (-mfabb);
-               //mfbab     += omegaLimit * (-mfbab);
-               //mfbba     += omegaLimit * (-mfbba);
-               ////////////////////////////////////////////////////////////////////////////
-
-               ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-               //incl. correction		(hat noch nicht so gut funktioniert...Optimierungsbedarf??)
-               {
-                  LBMReal dxux = c1o2 * (-omega) *(mxxMyy+mxxMzz)+c1o2 *  OxxPyyPzz * (mfaaa-mxxPyyPzz);
-                  LBMReal dyuy = dxux+omega * c3o2 * mxxMyy;
-                  LBMReal dzuz = dxux+omega * c3o2 * mxxMzz;
+                  //////////////////////////////////////////////////////////////////////////
+         // 			LBMReal magicBulk=(CUMacc+CUMcac+CUMcca)*(one/OxxPyyPzz-c1o2)*c3o2*8.;
+
+                  //////////////////////////////////////////////////////////////////////////
+                  //limiter-Scheise Teil 1
+                  //LBMReal oxxyy,oxxzz,oxy,oxz,oyz;
+                  //LBMReal smag=0.001;
+                  //oxxyy    = omega+(one-omega)*abs(mxxMyy)/(abs(mxxMyy)+smag);
+                  //oxxzz    = omega+(one-omega)*abs(mxxMzz)/(abs(mxxMzz)+smag);
+                  //oxy      = omega+(one-omega)*abs(mfbba)/(abs(mfbba)+smag);
+                  //oxz      = omega+(one-omega)*abs(mfbab)/(abs(mfbab)+smag);
+                  //oyz      = omega+(one-omega)*abs(mfabb)/(abs(mfabb)+smag);
+
+                  ////////////////////////////////////////////////////////////////////////////
+                  ////Teil 1b
+                  //LBMReal constante = 1000.0;
+                  //LBMReal nuEddi = constante * abs(mxxPyyPzz);
+                  //LBMReal omegaLimit = one / (one / omega + three * nuEddi);
+
+                  //{
+                  //	LBMReal dxux = c1o2 * (-omegaLimit) *(mxxMyy + mxxMzz) +  OxxPyyPzz * (mfaaa - mxxPyyPzz);
+                  //	LBMReal dyuy = dxux + omegaLimit * c3o2 * mxxMyy;
+                  //	LBMReal dzuz = dxux + omegaLimit * c3o2 * mxxMzz;
+
+                     ////relax
+                     //mxxPyyPzz += OxxPyyPzz*(mfaaa  - mxxPyyPzz)- three * (one - c1o2 * OxxPyyPzz) * (vx2 * dxux + vy2 * dyuy + vz2 * dzuz);
+                     //mxxMyy    += omegaLimit * (-mxxMyy) - three * (one + c1o2 * (-omegaLimit)) * (vx2 * dxux + vy2 * dyuy);
+                     //mxxMzz    += omegaLimit * (-mxxMzz) - three * (one + c1o2 * (-omegaLimit)) * (vx2 * dxux + vz2 * dzuz);
+
+                  //}
+                  //mfabb     += omegaLimit * (-mfabb);
+                  //mfbab     += omegaLimit * (-mfbab);
+                  //mfbba     += omegaLimit * (-mfbba);
+                  ////////////////////////////////////////////////////////////////////////////
+
+                  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+                  //incl. correction		(hat noch nicht so gut funktioniert...Optimierungsbedarf??)
+                  {
+                     LBMReal dxux = c1o2 * (-omega) *(mxxMyy+mxxMzz)+c1o2 *  OxxPyyPzz * (mfaaa-mxxPyyPzz);
+                     LBMReal dyuy = dxux+omega * c3o2 * mxxMyy;
+                     LBMReal dzuz = dxux+omega * c3o2 * mxxMzz;
+
+                     //relax
+                     mxxPyyPzz += OxxPyyPzz*(mfaaa-mxxPyyPzz)-three * (one-c1o2 * OxxPyyPzz) * (vx2 * dxux+vy2 * dyuy+vz2 * dzuz);//-magicBulk*OxxPyyPzz;
+                     mxxMyy += omega * (-mxxMyy)-three * (one+c1o2 * (-omega)) * (vx2 * dxux-vy2 * dyuy);
+                     mxxMzz += omega * (-mxxMzz)-three * (one+c1o2 * (-omega)) * (vx2 * dxux-vz2 * dzuz);
+
+                     //////////////////////////////////////////////////////////////////////////
+                     //limiter-Scheise Teil 2
+                     //mxxMyy    += oxxyy * (-mxxMyy) - three * (one + c1o2 * (-omega)) * (vx2 * dxux + vy2 * dyuy);
+                     //mxxMzz    += oxxzz * (-mxxMzz) - three * (one + c1o2 * (-omega)) * (vx2 * dxux + vz2 * dzuz);
+                     //////////////////////////////////////////////////////////////////////////
+
+                  }
+                  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+                  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+                  ////no correction
+                  //mxxPyyPzz += OxxPyyPzz*(mfaaa-mxxPyyPzz);//-magicBulk*OxxPyyPzz;
+                  //mxxMyy    += -(-omega) * (-mxxMyy);
+                  //mxxMzz    += -(-omega) * (-mxxMzz);
+                  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+                  mfabb += omega * (-mfabb);
+                  mfbab += omega * (-mfbab);
+                  mfbba += omega * (-mfbba);
+
+                  //////////////////////////////////////////////////////////////////////////
+                  //limiter-Scheise Teil 3
+                  //mfabb     += oyz * (-mfabb);
+                  //mfbab     += oxz * (-mfbab);
+                  //mfbba     += oxy * (-mfbba);
+                  //////////////////////////////////////////////////////////////////////////
+
+                  // linear combinations back
+                  mfcaa = c1o3 * (mxxMyy+mxxMzz+mxxPyyPzz);
+                  mfaca = c1o3 * (-two*  mxxMyy+mxxMzz+mxxPyyPzz);
+                  mfaac = c1o3 * (mxxMyy-two* mxxMzz+mxxPyyPzz);
+
+                  //3.
+                  // linear combinations
+
+                  LBMReal mxxyPyzz = mfcba+mfabc;
+                  LBMReal mxxyMyzz = mfcba-mfabc;
+
+                  LBMReal mxxzPyyz = mfcab+mfacb;
+                  LBMReal mxxzMyyz = mfcab-mfacb;
+
+                  LBMReal mxyyPxzz = mfbca+mfbac;
+                  LBMReal mxyyMxzz = mfbca-mfbac;
 
                   //relax
-                  mxxPyyPzz += OxxPyyPzz*(mfaaa-mxxPyyPzz)-three * (one-c1o2 * OxxPyyPzz) * (vx2 * dxux+vy2 * dyuy+vz2 * dzuz);//-magicBulk*OxxPyyPzz;
-                  mxxMyy += omega * (-mxxMyy)-three * (one+c1o2 * (-omega)) * (vx2 * dxux-vy2 * dyuy);
-                  mxxMzz += omega * (-mxxMzz)-three * (one+c1o2 * (-omega)) * (vx2 * dxux-vz2 * dzuz);
+                  //////////////////////////////////////////////////////////////////////////
+                  //das ist der limiter
+                  wadjust = Oxyz+(one-Oxyz)*abs(mfbbb)/(abs(mfbbb)+qudricLimitD);
+                  mfbbb += wadjust * (-mfbbb);
+                  wadjust = OxyyPxzz+(one-OxyyPxzz)*abs(mxxyPyzz)/(abs(mxxyPyzz)+qudricLimitP);
+                  mxxyPyzz += wadjust * (-mxxyPyzz);
+                  wadjust = OxyyMxzz+(one-OxyyMxzz)*abs(mxxyMyzz)/(abs(mxxyMyzz)+qudricLimitM);
+                  mxxyMyzz += wadjust * (-mxxyMyzz);
+                  wadjust = OxyyPxzz+(one-OxyyPxzz)*abs(mxxzPyyz)/(abs(mxxzPyyz)+qudricLimitP);
+                  mxxzPyyz += wadjust * (-mxxzPyyz);
+                  wadjust = OxyyMxzz+(one-OxyyMxzz)*abs(mxxzMyyz)/(abs(mxxzMyyz)+qudricLimitM);
+                  mxxzMyyz += wadjust * (-mxxzMyyz);
+                  wadjust = OxyyPxzz+(one-OxyyPxzz)*abs(mxyyPxzz)/(abs(mxyyPxzz)+qudricLimitP);
+                  mxyyPxzz += wadjust * (-mxyyPxzz);
+                  wadjust = OxyyMxzz+(one-OxyyMxzz)*abs(mxyyMxzz)/(abs(mxyyMxzz)+qudricLimitM);
+                  mxyyMxzz += wadjust * (-mxyyMxzz);
+                  //////////////////////////////////////////////////////////////////////////
+                  //ohne limiter
+                  //mfbbb     += OxyyMxzz * (-mfbbb);
+                  //mxxyPyzz  += OxyyPxzz * (-mxxyPyzz);
+                  //mxxyMyzz  += OxyyMxzz * (-mxxyMyzz);
+                  //mxxzPyyz  += OxyyPxzz * (-mxxzPyyz);
+                  //mxxzMyyz  += OxyyMxzz * (-mxxzMyyz);
+                  //mxyyPxzz  += OxyyPxzz * (-mxyyPxzz);
+                  //mxyyMxzz  += OxyyMxzz * (-mxyyMxzz);
+                  //////////////////////////////////////////////////////////////////////////
+
+                  //// linear combinations back
+                  mfcba = (mxxyMyzz+mxxyPyzz) * c1o2;
+                  mfabc = (-mxxyMyzz+mxxyPyzz) * c1o2;
+                  mfcab = (mxxzMyyz+mxxzPyyz) * c1o2;
+                  mfacb = (-mxxzMyyz+mxxzPyyz) * c1o2;
+                  mfbca = (mxyyMxzz+mxyyPxzz) * c1o2;
+                  mfbac = (-mxyyMxzz+mxyyPxzz) * c1o2;
 
+                  //4.
                   //////////////////////////////////////////////////////////////////////////
-                  //limiter-Scheise Teil 2
-                  //mxxMyy    += oxxyy * (-mxxMyy) - three * (one + c1o2 * (-omega)) * (vx2 * dxux + vy2 * dyuy);
-                  //mxxMzz    += oxxzz * (-mxxMzz) - three * (one + c1o2 * (-omega)) * (vx2 * dxux + vz2 * dzuz);
+                  //mit limiter
+               //	wadjust    = O4+(one-O4)*abs(CUMacc)/(abs(CUMacc)+qudricLimit);
+                  //CUMacc    += wadjust * (-CUMacc);
+               //	wadjust    = O4+(one-O4)*abs(CUMcac)/(abs(CUMcac)+qudricLimit);
+                  //CUMcac    += wadjust * (-CUMcac); 
+               //	wadjust    = O4+(one-O4)*abs(CUMcca)/(abs(CUMcca)+qudricLimit);
+                  //CUMcca    += wadjust * (-CUMcca); 
+
+               //	wadjust    = O4+(one-O4)*abs(CUMbbc)/(abs(CUMbbc)+qudricLimit);
+                  //CUMbbc    += wadjust * (-CUMbbc); 
+               //	wadjust    = O4+(one-O4)*abs(CUMbcb)/(abs(CUMbcb)+qudricLimit);
+                  //CUMbcb    += wadjust * (-CUMbcb); 
+               //	wadjust    = O4+(one-O4)*abs(CUMcbb)/(abs(CUMcbb)+qudricLimit);
+                  //CUMcbb    += wadjust * (-CUMcbb); 
+                  //////////////////////////////////////////////////////////////////////////
+                  //ohne limiter
+                  CUMacc += O4 * (-CUMacc);
+                  CUMcac += O4 * (-CUMcac);
+                  CUMcca += O4 * (-CUMcca);
+
+                  CUMbbc += O4 * (-CUMbbc);
+                  CUMbcb += O4 * (-CUMbcb);
+                  CUMcbb += O4 * (-CUMcbb);
                   //////////////////////////////////////////////////////////////////////////
 
-               }
-               ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-               /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-               ////no correction
-               //mxxPyyPzz += OxxPyyPzz*(mfaaa-mxxPyyPzz);//-magicBulk*OxxPyyPzz;
-               //mxxMyy    += -(-omega) * (-mxxMyy);
-               //mxxMzz    += -(-omega) * (-mxxMzz);
-               /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-               mfabb += omega * (-mfabb);
-               mfbab += omega * (-mfbab);
-               mfbba += omega * (-mfbba);
-
-               //////////////////////////////////////////////////////////////////////////
-               //limiter-Scheise Teil 3
-               //mfabb     += oyz * (-mfabb);
-               //mfbab     += oxz * (-mfbab);
-               //mfbba     += oxy * (-mfbba);
-               //////////////////////////////////////////////////////////////////////////
-
-               // linear combinations back
-               mfcaa = c1o3 * (mxxMyy+mxxMzz+mxxPyyPzz);
-               mfaca = c1o3 * (-two*  mxxMyy+mxxMzz+mxxPyyPzz);
-               mfaac = c1o3 * (mxxMyy-two* mxxMzz+mxxPyyPzz);
-
-               //3.
-               // linear combinations
-
-               LBMReal mxxyPyzz = mfcba+mfabc;
-               LBMReal mxxyMyzz = mfcba-mfabc;
-
-               LBMReal mxxzPyyz = mfcab+mfacb;
-               LBMReal mxxzMyyz = mfcab-mfacb;
-
-               LBMReal mxyyPxzz = mfbca+mfbac;
-               LBMReal mxyyMxzz = mfbca-mfbac;
-
-               //relax
-               //////////////////////////////////////////////////////////////////////////
-               //das ist der limiter
-               wadjust = Oxyz+(one-Oxyz)*abs(mfbbb)/(abs(mfbbb)+qudricLimitD);
-               mfbbb += wadjust * (-mfbbb);
-               wadjust = OxyyPxzz+(one-OxyyPxzz)*abs(mxxyPyzz)/(abs(mxxyPyzz)+qudricLimitP);
-               mxxyPyzz += wadjust * (-mxxyPyzz);
-               wadjust = OxyyMxzz+(one-OxyyMxzz)*abs(mxxyMyzz)/(abs(mxxyMyzz)+qudricLimitM);
-               mxxyMyzz += wadjust * (-mxxyMyzz);
-               wadjust = OxyyPxzz+(one-OxyyPxzz)*abs(mxxzPyyz)/(abs(mxxzPyyz)+qudricLimitP);
-               mxxzPyyz += wadjust * (-mxxzPyyz);
-               wadjust = OxyyMxzz+(one-OxyyMxzz)*abs(mxxzMyyz)/(abs(mxxzMyyz)+qudricLimitM);
-               mxxzMyyz += wadjust * (-mxxzMyyz);
-               wadjust = OxyyPxzz+(one-OxyyPxzz)*abs(mxyyPxzz)/(abs(mxyyPxzz)+qudricLimitP);
-               mxyyPxzz += wadjust * (-mxyyPxzz);
-               wadjust = OxyyMxzz+(one-OxyyMxzz)*abs(mxyyMxzz)/(abs(mxyyMxzz)+qudricLimitM);
-               mxyyMxzz += wadjust * (-mxyyMxzz);
-               //////////////////////////////////////////////////////////////////////////
-               //ohne limiter
-               //mfbbb     += OxyyMxzz * (-mfbbb);
-               //mxxyPyzz  += OxyyPxzz * (-mxxyPyzz);
-               //mxxyMyzz  += OxyyMxzz * (-mxxyMyzz);
-               //mxxzPyyz  += OxyyPxzz * (-mxxzPyyz);
-               //mxxzMyyz  += OxyyMxzz * (-mxxzMyyz);
-               //mxyyPxzz  += OxyyPxzz * (-mxyyPxzz);
-               //mxyyMxzz  += OxyyMxzz * (-mxyyMxzz);
-               //////////////////////////////////////////////////////////////////////////
-
-               //// linear combinations back
-               mfcba = (mxxyMyzz+mxxyPyzz) * c1o2;
-               mfabc = (-mxxyMyzz+mxxyPyzz) * c1o2;
-               mfcab = (mxxzMyyz+mxxzPyyz) * c1o2;
-               mfacb = (-mxxzMyyz+mxxzPyyz) * c1o2;
-               mfbca = (mxyyMxzz+mxyyPxzz) * c1o2;
-               mfbac = (-mxyyMxzz+mxyyPxzz) * c1o2;
-
-               //4.
-               //////////////////////////////////////////////////////////////////////////
-               //mit limiter
-            //	wadjust    = O4+(one-O4)*abs(CUMacc)/(abs(CUMacc)+qudricLimit);
-               //CUMacc    += wadjust * (-CUMacc);
-            //	wadjust    = O4+(one-O4)*abs(CUMcac)/(abs(CUMcac)+qudricLimit);
-               //CUMcac    += wadjust * (-CUMcac); 
-            //	wadjust    = O4+(one-O4)*abs(CUMcca)/(abs(CUMcca)+qudricLimit);
-               //CUMcca    += wadjust * (-CUMcca); 
-
-            //	wadjust    = O4+(one-O4)*abs(CUMbbc)/(abs(CUMbbc)+qudricLimit);
-               //CUMbbc    += wadjust * (-CUMbbc); 
-            //	wadjust    = O4+(one-O4)*abs(CUMbcb)/(abs(CUMbcb)+qudricLimit);
-               //CUMbcb    += wadjust * (-CUMbcb); 
-            //	wadjust    = O4+(one-O4)*abs(CUMcbb)/(abs(CUMcbb)+qudricLimit);
-               //CUMcbb    += wadjust * (-CUMcbb); 
-               //////////////////////////////////////////////////////////////////////////
-               //ohne limiter
-               CUMacc += O4 * (-CUMacc);
-               CUMcac += O4 * (-CUMcac);
-               CUMcca += O4 * (-CUMcca);
-
-               CUMbbc += O4 * (-CUMbbc);
-               CUMbcb += O4 * (-CUMbcb);
-               CUMcbb += O4 * (-CUMcbb);
-               //////////////////////////////////////////////////////////////////////////
-
-
-               //5.
-               CUMbcc += O5 * (-CUMbcc);
-               CUMcbc += O5 * (-CUMcbc);
-               CUMccb += O5 * (-CUMccb);
-
-               //6.
-               CUMccc += O6 * (-CUMccc);
-
-
-
-               //back cumulants to central moments
-               //4.
-               mfcbb = CUMcbb+((mfcaa+c1o3) * mfabb+two * mfbba * mfbab)/rho;
-               mfbcb = CUMbcb+((mfaca+c1o3) * mfbab+two * mfbba * mfabb)/rho;
-               mfbbc = CUMbbc+((mfaac+c1o3) * mfbba+two * mfbab * mfabb)/rho;
-
-               mfcca = CUMcca+(((mfcaa * mfaca+two * mfbba * mfbba)+c1o3 * (mfcaa+mfaca))/rho-c1o9*(drho/rho));//(one/rho-one));
-               mfcac = CUMcac+(((mfcaa * mfaac+two * mfbab * mfbab)+c1o3 * (mfcaa+mfaac))/rho-c1o9*(drho/rho));//(one/rho-one));
-               mfacc = CUMacc+(((mfaac * mfaca+two * mfabb * mfabb)+c1o3 * (mfaac+mfaca))/rho-c1o9*(drho/rho));//(one/rho-one));
-
-               //5.
-               mfbcc = CUMbcc+((mfaac * mfbca+mfaca * mfbac+four * mfabb * mfbbb+two * (mfbab * mfacb+mfbba * mfabc))+c1o3 * (mfbca+mfbac))/rho;
-               mfcbc = CUMcbc+((mfaac * mfcba+mfcaa * mfabc+four * mfbab * mfbbb+two * (mfabb * mfcab+mfbba * mfbac))+c1o3 * (mfcba+mfabc))/rho;
-               mfccb = CUMccb+((mfcaa * mfacb+mfaca * mfcab+four * mfbba * mfbbb+two * (mfbab * mfbca+mfabb * mfcba))+c1o3 * (mfacb+mfcab))/rho;
-
-               //6.
-
-               mfccc = CUMccc-((-four *  mfbbb * mfbbb
-                  -(mfcaa * mfacc+mfaca * mfcac+mfaac * mfcca)
-                  -four * (mfabb * mfcbb+mfbab * mfbcb+mfbba * mfbbc)
-                  -two * (mfbca * mfbac+mfcba * mfabc+mfcab * mfacb))/rho
-                  +(four * (mfbab * mfbab * mfaca+mfabb * mfabb * mfcaa+mfbba * mfbba * mfaac)
-                     +two * (mfcaa * mfaca * mfaac)
-                     +sixteen *  mfbba * mfbab * mfabb)/(rho * rho)
-                  -c1o3 * (mfacc+mfcac+mfcca)/rho
-                  -c1o9 * (mfcaa+mfaca+mfaac)/rho
-                  +(two * (mfbab * mfbab+mfabb * mfabb+mfbba * mfbba)
-                     +(mfaac * mfaca+mfaac * mfcaa+mfaca * mfcaa)+c1o3 *(mfaac+mfaca+mfcaa))/(rho * rho) * c2o3
-                  +c1o27*((drho * drho-drho)/(rho*rho)));
-               ////////////////////////////////////////////////////////////////////////////////////
-               //forcing
-               mfbaa=-mfbaa;
-               mfaba=-mfaba;
-               mfaab=-mfaab;
-               //////////////////////////////////////////////////////////////////////////////////////
-
-         ////////////////////////////////////////////////////////////////////////////////////
-         //back
-         ////////////////////////////////////////////////////////////////////////////////////
-         //mit 1, 0, 1/3, 0, 0, 0, 1/3, 0, 1/9   Konditionieren
-         ////////////////////////////////////////////////////////////////////////////////////
-         // Z - Dir
-               m0 = mfaac * c1o2+mfaab * (vvz-c1o2)+(mfaaa+one* oMdrho) * (vz2-vvz) * c1o2;
-               m1 = -mfaac-two* mfaab *  vvz+mfaaa                * (one-vz2)-one* oMdrho * vz2;
-               m2 = mfaac * c1o2+mfaab * (vvz+c1o2)+(mfaaa+one* oMdrho) * (vz2+vvz) * c1o2;
-               mfaaa = m0;
-               mfaab = m1;
-               mfaac = m2;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m0 = mfabc * c1o2+mfabb * (vvz-c1o2)+mfaba * (vz2-vvz) * c1o2;
-               m1 = -mfabc-two* mfabb *  vvz+mfaba * (one-vz2);
-               m2 = mfabc * c1o2+mfabb * (vvz+c1o2)+mfaba * (vz2+vvz) * c1o2;
-               mfaba = m0;
-               mfabb = m1;
-               mfabc = m2;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m0 = mfacc * c1o2+mfacb * (vvz-c1o2)+(mfaca+c1o3 * oMdrho) * (vz2-vvz) * c1o2;
-               m1 = -mfacc-two* mfacb *  vvz+mfaca                  * (one-vz2)-c1o3 * oMdrho * vz2;
-               m2 = mfacc * c1o2+mfacb * (vvz+c1o2)+(mfaca+c1o3 * oMdrho) * (vz2+vvz) * c1o2;
-               mfaca = m0;
-               mfacb = m1;
-               mfacc = m2;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               m0 = mfbac * c1o2+mfbab * (vvz-c1o2)+mfbaa * (vz2-vvz) * c1o2;
-               m1 = -mfbac-two* mfbab *  vvz+mfbaa * (one-vz2);
-               m2 = mfbac * c1o2+mfbab * (vvz+c1o2)+mfbaa * (vz2+vvz) * c1o2;
-               mfbaa = m0;
-               mfbab = m1;
-               mfbac = m2;
-               /////////b//////////////////////////////////////////////////////////////////////////
-               m0 = mfbbc * c1o2+mfbbb * (vvz-c1o2)+mfbba * (vz2-vvz) * c1o2;
-               m1 = -mfbbc-two* mfbbb *  vvz+mfbba * (one-vz2);
-               m2 = mfbbc * c1o2+mfbbb * (vvz+c1o2)+mfbba * (vz2+vvz) * c1o2;
-               mfbba = m0;
-               mfbbb = m1;
-               mfbbc = m2;
-               /////////b//////////////////////////////////////////////////////////////////////////
-               m0 = mfbcc * c1o2+mfbcb * (vvz-c1o2)+mfbca * (vz2-vvz) * c1o2;
-               m1 = -mfbcc-two* mfbcb *  vvz+mfbca * (one-vz2);
-               m2 = mfbcc * c1o2+mfbcb * (vvz+c1o2)+mfbca * (vz2+vvz) * c1o2;
-               mfbca = m0;
-               mfbcb = m1;
-               mfbcc = m2;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               m0 = mfcac * c1o2+mfcab * (vvz-c1o2)+(mfcaa+c1o3 * oMdrho) * (vz2-vvz) * c1o2;
-               m1 = -mfcac-two* mfcab *  vvz+mfcaa                  * (one-vz2)-c1o3 * oMdrho * vz2;
-               m2 = mfcac * c1o2+mfcab * (vvz+c1o2)+(mfcaa+c1o3 * oMdrho) * (vz2+vvz) * c1o2;
-               mfcaa = m0;
-               mfcab = m1;
-               mfcac = m2;
-               /////////c//////////////////////////////////////////////////////////////////////////
-               m0 = mfcbc * c1o2+mfcbb * (vvz-c1o2)+mfcba * (vz2-vvz) * c1o2;
-               m1 = -mfcbc-two* mfcbb *  vvz+mfcba * (one-vz2);
-               m2 = mfcbc * c1o2+mfcbb * (vvz+c1o2)+mfcba * (vz2+vvz) * c1o2;
-               mfcba = m0;
-               mfcbb = m1;
-               mfcbc = m2;
-               /////////c//////////////////////////////////////////////////////////////////////////
-               m0 = mfccc * c1o2+mfccb * (vvz-c1o2)+(mfcca+c1o9 * oMdrho) * (vz2-vvz) * c1o2;
-               m1 = -mfccc-two* mfccb *  vvz+mfcca                  * (one-vz2)-c1o9 * oMdrho * vz2;
-               m2 = mfccc * c1o2+mfccb * (vvz+c1o2)+(mfcca+c1o9 * oMdrho) * (vz2+vvz) * c1o2;
-               mfcca = m0;
-               mfccb = m1;
-               mfccc = m2;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               //mit 1/6, 2/3, 1/6, 0, 0, 0, 1/18, 2/9, 1/18   Konditionieren
-               ////////////////////////////////////////////////////////////////////////////////////
-               // Y - Dir
-               m0 = mfaca * c1o2+mfaba * (vvy-c1o2)+(mfaaa+c1o6 * oMdrho) * (vy2-vvy) * c1o2;
-               m1 = -mfaca-two* mfaba *  vvy+mfaaa                  * (one-vy2)-c1o6 * oMdrho * vy2;
-               m2 = mfaca * c1o2+mfaba * (vvy+c1o2)+(mfaaa+c1o6 * oMdrho) * (vy2+vvy) * c1o2;
-               mfaaa = m0;
-               mfaba = m1;
-               mfaca = m2;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m0 = mfacb * c1o2+mfabb * (vvy-c1o2)+(mfaab+c2o3 * oMdrho) * (vy2-vvy) * c1o2;
-               m1 = -mfacb-two* mfabb *  vvy+mfaab                  * (one-vy2)-c2o3 * oMdrho * vy2;
-               m2 = mfacb * c1o2+mfabb * (vvy+c1o2)+(mfaab+c2o3 * oMdrho) * (vy2+vvy) * c1o2;
-               mfaab = m0;
-               mfabb = m1;
-               mfacb = m2;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m0 = mfacc * c1o2+mfabc * (vvy-c1o2)+(mfaac+c1o6 * oMdrho) * (vy2-vvy) * c1o2;
-               m1 = -mfacc-two* mfabc *  vvy+mfaac                  * (one-vy2)-c1o6 * oMdrho * vy2;
-               m2 = mfacc * c1o2+mfabc * (vvy+c1o2)+(mfaac+c1o6 * oMdrho) * (vy2+vvy) * c1o2;
-               mfaac = m0;
-               mfabc = m1;
-               mfacc = m2;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               m0 = mfbca * c1o2+mfbba * (vvy-c1o2)+mfbaa * (vy2-vvy) * c1o2;
-               m1 = -mfbca-two* mfbba *  vvy+mfbaa * (one-vy2);
-               m2 = mfbca * c1o2+mfbba * (vvy+c1o2)+mfbaa * (vy2+vvy) * c1o2;
-               mfbaa = m0;
-               mfbba = m1;
-               mfbca = m2;
-               /////////b//////////////////////////////////////////////////////////////////////////
-               m0 = mfbcb * c1o2+mfbbb * (vvy-c1o2)+mfbab * (vy2-vvy) * c1o2;
-               m1 = -mfbcb-two* mfbbb *  vvy+mfbab * (one-vy2);
-               m2 = mfbcb * c1o2+mfbbb * (vvy+c1o2)+mfbab * (vy2+vvy) * c1o2;
-               mfbab = m0;
-               mfbbb = m1;
-               mfbcb = m2;
-               /////////b//////////////////////////////////////////////////////////////////////////
-               m0 = mfbcc * c1o2+mfbbc * (vvy-c1o2)+mfbac * (vy2-vvy) * c1o2;
-               m1 = -mfbcc-two* mfbbc *  vvy+mfbac * (one-vy2);
-               m2 = mfbcc * c1o2+mfbbc * (vvy+c1o2)+mfbac * (vy2+vvy) * c1o2;
-               mfbac = m0;
-               mfbbc = m1;
-               mfbcc = m2;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               m0 = mfcca * c1o2+mfcba * (vvy-c1o2)+(mfcaa+c1o18 * oMdrho) * (vy2-vvy) * c1o2;
-               m1 = -mfcca-two* mfcba *  vvy+mfcaa                   * (one-vy2)-c1o18 * oMdrho * vy2;
-               m2 = mfcca * c1o2+mfcba * (vvy+c1o2)+(mfcaa+c1o18 * oMdrho) * (vy2+vvy) * c1o2;
-               mfcaa = m0;
-               mfcba = m1;
-               mfcca = m2;
-               /////////c//////////////////////////////////////////////////////////////////////////
-               m0 = mfccb * c1o2+mfcbb * (vvy-c1o2)+(mfcab+c2o9 * oMdrho) * (vy2-vvy) * c1o2;
-               m1 = -mfccb-two* mfcbb *  vvy+mfcab                  * (one-vy2)-c2o9 * oMdrho * vy2;
-               m2 = mfccb * c1o2+mfcbb * (vvy+c1o2)+(mfcab+c2o9 * oMdrho) * (vy2+vvy) * c1o2;
-               mfcab = m0;
-               mfcbb = m1;
-               mfccb = m2;
-               /////////c//////////////////////////////////////////////////////////////////////////
-               m0 = mfccc * c1o2+mfcbc * (vvy-c1o2)+(mfcac+c1o18 * oMdrho) * (vy2-vvy) * c1o2;
-               m1 = -mfccc-two* mfcbc *  vvy+mfcac                   * (one-vy2)-c1o18 * oMdrho * vy2;
-               m2 = mfccc * c1o2+mfcbc * (vvy+c1o2)+(mfcac+c1o18 * oMdrho) * (vy2+vvy) * c1o2;
-               mfcac = m0;
-               mfcbc = m1;
-               mfccc = m2;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               //mit 1/36, 1/9, 1/36, 1/9, 4/9, 1/9, 1/36, 1/9, 1/36 Konditionieren
-               ////////////////////////////////////////////////////////////////////////////////////
-               // X - Dir
-               m0 = mfcaa * c1o2+mfbaa * (vvx-c1o2)+(mfaaa+c1o36 * oMdrho) * (vx2-vvx) * c1o2;
-               m1 = -mfcaa-two* mfbaa *  vvx+mfaaa                   * (one-vx2)-c1o36 * oMdrho * vx2;
-               m2 = mfcaa * c1o2+mfbaa * (vvx+c1o2)+(mfaaa+c1o36 * oMdrho) * (vx2+vvx) * c1o2;
-               mfaaa = m0;
-               mfbaa = m1;
-               mfcaa = m2;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m0 = mfcba * c1o2+mfbba * (vvx-c1o2)+(mfaba+c1o9 * oMdrho) * (vx2-vvx) * c1o2;
-               m1 = -mfcba-two* mfbba *  vvx+mfaba                  * (one-vx2)-c1o9 * oMdrho * vx2;
-               m2 = mfcba * c1o2+mfbba * (vvx+c1o2)+(mfaba+c1o9 * oMdrho) * (vx2+vvx) * c1o2;
-               mfaba = m0;
-               mfbba = m1;
-               mfcba = m2;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m0 = mfcca * c1o2+mfbca * (vvx-c1o2)+(mfaca+c1o36 * oMdrho) * (vx2-vvx) * c1o2;
-               m1 = -mfcca-two* mfbca *  vvx+mfaca                   * (one-vx2)-c1o36 * oMdrho * vx2;
-               m2 = mfcca * c1o2+mfbca * (vvx+c1o2)+(mfaca+c1o36 * oMdrho) * (vx2+vvx) * c1o2;
-               mfaca = m0;
-               mfbca = m1;
-               mfcca = m2;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               m0 = mfcab * c1o2+mfbab * (vvx-c1o2)+(mfaab+c1o9 * oMdrho) * (vx2-vvx) * c1o2;
-               m1 = -mfcab-two* mfbab *  vvx+mfaab                  * (one-vx2)-c1o9 * oMdrho * vx2;
-               m2 = mfcab * c1o2+mfbab * (vvx+c1o2)+(mfaab+c1o9 * oMdrho) * (vx2+vvx) * c1o2;
-               mfaab = m0;
-               mfbab = m1;
-               mfcab = m2;
-               ///////////b////////////////////////////////////////////////////////////////////////
-               m0 = mfcbb * c1o2+mfbbb * (vvx-c1o2)+(mfabb+c4o9 * oMdrho) * (vx2-vvx) * c1o2;
-               m1 = -mfcbb-two* mfbbb *  vvx+mfabb                  * (one-vx2)-c4o9 * oMdrho * vx2;
-               m2 = mfcbb * c1o2+mfbbb * (vvx+c1o2)+(mfabb+c4o9 * oMdrho) * (vx2+vvx) * c1o2;
-               mfabb = m0;
-               mfbbb = m1;
-               mfcbb = m2;
-               ///////////b////////////////////////////////////////////////////////////////////////
-               m0 = mfccb * c1o2+mfbcb * (vvx-c1o2)+(mfacb+c1o9 * oMdrho) * (vx2-vvx) * c1o2;
-               m1 = -mfccb-two* mfbcb *  vvx+mfacb                  * (one-vx2)-c1o9 * oMdrho * vx2;
-               m2 = mfccb * c1o2+mfbcb * (vvx+c1o2)+(mfacb+c1o9 * oMdrho) * (vx2+vvx) * c1o2;
-               mfacb = m0;
-               mfbcb = m1;
-               mfccb = m2;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               m0 = mfcac * c1o2+mfbac * (vvx-c1o2)+(mfaac+c1o36 * oMdrho) * (vx2-vvx) * c1o2;
-               m1 = -mfcac-two* mfbac *  vvx+mfaac                   * (one-vx2)-c1o36 * oMdrho * vx2;
-               m2 = mfcac * c1o2+mfbac * (vvx+c1o2)+(mfaac+c1o36 * oMdrho) * (vx2+vvx) * c1o2;
-               mfaac = m0;
-               mfbac = m1;
-               mfcac = m2;
-               ///////////c////////////////////////////////////////////////////////////////////////
-               m0 = mfcbc * c1o2+mfbbc * (vvx-c1o2)+(mfabc+c1o9 * oMdrho) * (vx2-vvx) * c1o2;
-               m1 = -mfcbc-two* mfbbc *  vvx+mfabc                  * (one-vx2)-c1o9 * oMdrho * vx2;
-               m2 = mfcbc * c1o2+mfbbc * (vvx+c1o2)+(mfabc+c1o9 * oMdrho) * (vx2+vvx) * c1o2;
-               mfabc = m0;
-               mfbbc = m1;
-               mfcbc = m2;
-               ///////////c////////////////////////////////////////////////////////////////////////
-               m0 = mfccc * c1o2+mfbcc * (vvx-c1o2)+(mfacc+c1o36 * oMdrho) * (vx2-vvx) * c1o2;
-               m1 = -mfccc-two* mfbcc *  vvx+mfacc                   * (one-vx2)-c1o36 * oMdrho * vx2;
-               m2 = mfccc * c1o2+mfbcc * (vvx+c1o2)+(mfacc+c1o36 * oMdrho) * (vx2+vvx) * c1o2;
-               mfacc = m0;
-               mfbcc = m1;
-               mfccc = m2;
-               ////////////////////////////////////////////////////////////////////////////////////
-
-               //////////////////////////////////////////////////////////////////////////
-               //proof correctness
-               //////////////////////////////////////////////////////////////////////////
+
+                  //5.
+                  CUMbcc += O5 * (-CUMbcc);
+                  CUMcbc += O5 * (-CUMcbc);
+                  CUMccb += O5 * (-CUMccb);
+
+                  //6.
+                  CUMccc += O6 * (-CUMccc);
+
+
+
+                  //back cumulants to central moments
+                  //4.
+                  mfcbb = CUMcbb+((mfcaa+c1o3) * mfabb+two * mfbba * mfbab)/rho;
+                  mfbcb = CUMbcb+((mfaca+c1o3) * mfbab+two * mfbba * mfabb)/rho;
+                  mfbbc = CUMbbc+((mfaac+c1o3) * mfbba+two * mfbab * mfabb)/rho;
+
+                  mfcca = CUMcca+(((mfcaa * mfaca+two * mfbba * mfbba)+c1o3 * (mfcaa+mfaca))/rho-c1o9*(drho/rho));//(one/rho-one));
+                  mfcac = CUMcac+(((mfcaa * mfaac+two * mfbab * mfbab)+c1o3 * (mfcaa+mfaac))/rho-c1o9*(drho/rho));//(one/rho-one));
+                  mfacc = CUMacc+(((mfaac * mfaca+two * mfabb * mfabb)+c1o3 * (mfaac+mfaca))/rho-c1o9*(drho/rho));//(one/rho-one));
+
+                  //5.
+                  mfbcc = CUMbcc+((mfaac * mfbca+mfaca * mfbac+four * mfabb * mfbbb+two * (mfbab * mfacb+mfbba * mfabc))+c1o3 * (mfbca+mfbac))/rho;
+                  mfcbc = CUMcbc+((mfaac * mfcba+mfcaa * mfabc+four * mfbab * mfbbb+two * (mfabb * mfcab+mfbba * mfbac))+c1o3 * (mfcba+mfabc))/rho;
+                  mfccb = CUMccb+((mfcaa * mfacb+mfaca * mfcab+four * mfbba * mfbbb+two * (mfbab * mfbca+mfabb * mfcba))+c1o3 * (mfacb+mfcab))/rho;
+
+                  //6.
+
+                  mfccc = CUMccc-((-four *  mfbbb * mfbbb
+                     -(mfcaa * mfacc+mfaca * mfcac+mfaac * mfcca)
+                     -four * (mfabb * mfcbb+mfbab * mfbcb+mfbba * mfbbc)
+                     -two * (mfbca * mfbac+mfcba * mfabc+mfcab * mfacb))/rho
+                     +(four * (mfbab * mfbab * mfaca+mfabb * mfabb * mfcaa+mfbba * mfbba * mfaac)
+                        +two * (mfcaa * mfaca * mfaac)
+                        +sixteen *  mfbba * mfbab * mfabb)/(rho * rho)
+                     -c1o3 * (mfacc+mfcac+mfcca)/rho
+                     -c1o9 * (mfcaa+mfaca+mfaac)/rho
+                     +(two * (mfbab * mfbab+mfabb * mfabb+mfbba * mfbba)
+                        +(mfaac * mfaca+mfaac * mfcaa+mfaca * mfcaa)+c1o3 *(mfaac+mfaca+mfcaa))/(rho * rho) * c2o3
+                     +c1o27*((drho * drho-drho)/(rho*rho)));
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  //forcing
+                  mfbaa=-mfbaa;
+                  mfaba=-mfaba;
+                  mfaab=-mfaab;
+                  //////////////////////////////////////////////////////////////////////////////////////
+
+            ////////////////////////////////////////////////////////////////////////////////////
+            //back
+            ////////////////////////////////////////////////////////////////////////////////////
+            //mit 1, 0, 1/3, 0, 0, 0, 1/3, 0, 1/9   Konditionieren
+            ////////////////////////////////////////////////////////////////////////////////////
+            // Z - Dir
+                  m0 = mfaac * c1o2+mfaab * (vvz-c1o2)+(mfaaa+one* oMdrho) * (vz2-vvz) * c1o2;
+                  m1 = -mfaac-two* mfaab *  vvz+mfaaa                * (one-vz2)-one* oMdrho * vz2;
+                  m2 = mfaac * c1o2+mfaab * (vvz+c1o2)+(mfaaa+one* oMdrho) * (vz2+vvz) * c1o2;
+                  mfaaa = m0;
+                  mfaab = m1;
+                  mfaac = m2;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m0 = mfabc * c1o2+mfabb * (vvz-c1o2)+mfaba * (vz2-vvz) * c1o2;
+                  m1 = -mfabc-two* mfabb *  vvz+mfaba * (one-vz2);
+                  m2 = mfabc * c1o2+mfabb * (vvz+c1o2)+mfaba * (vz2+vvz) * c1o2;
+                  mfaba = m0;
+                  mfabb = m1;
+                  mfabc = m2;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m0 = mfacc * c1o2+mfacb * (vvz-c1o2)+(mfaca+c1o3 * oMdrho) * (vz2-vvz) * c1o2;
+                  m1 = -mfacc-two* mfacb *  vvz+mfaca                  * (one-vz2)-c1o3 * oMdrho * vz2;
+                  m2 = mfacc * c1o2+mfacb * (vvz+c1o2)+(mfaca+c1o3 * oMdrho) * (vz2+vvz) * c1o2;
+                  mfaca = m0;
+                  mfacb = m1;
+                  mfacc = m2;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m0 = mfbac * c1o2+mfbab * (vvz-c1o2)+mfbaa * (vz2-vvz) * c1o2;
+                  m1 = -mfbac-two* mfbab *  vvz+mfbaa * (one-vz2);
+                  m2 = mfbac * c1o2+mfbab * (vvz+c1o2)+mfbaa * (vz2+vvz) * c1o2;
+                  mfbaa = m0;
+                  mfbab = m1;
+                  mfbac = m2;
+                  /////////b//////////////////////////////////////////////////////////////////////////
+                  m0 = mfbbc * c1o2+mfbbb * (vvz-c1o2)+mfbba * (vz2-vvz) * c1o2;
+                  m1 = -mfbbc-two* mfbbb *  vvz+mfbba * (one-vz2);
+                  m2 = mfbbc * c1o2+mfbbb * (vvz+c1o2)+mfbba * (vz2+vvz) * c1o2;
+                  mfbba = m0;
+                  mfbbb = m1;
+                  mfbbc = m2;
+                  /////////b//////////////////////////////////////////////////////////////////////////
+                  m0 = mfbcc * c1o2+mfbcb * (vvz-c1o2)+mfbca * (vz2-vvz) * c1o2;
+                  m1 = -mfbcc-two* mfbcb *  vvz+mfbca * (one-vz2);
+                  m2 = mfbcc * c1o2+mfbcb * (vvz+c1o2)+mfbca * (vz2+vvz) * c1o2;
+                  mfbca = m0;
+                  mfbcb = m1;
+                  mfbcc = m2;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m0 = mfcac * c1o2+mfcab * (vvz-c1o2)+(mfcaa+c1o3 * oMdrho) * (vz2-vvz) * c1o2;
+                  m1 = -mfcac-two* mfcab *  vvz+mfcaa                  * (one-vz2)-c1o3 * oMdrho * vz2;
+                  m2 = mfcac * c1o2+mfcab * (vvz+c1o2)+(mfcaa+c1o3 * oMdrho) * (vz2+vvz) * c1o2;
+                  mfcaa = m0;
+                  mfcab = m1;
+                  mfcac = m2;
+                  /////////c//////////////////////////////////////////////////////////////////////////
+                  m0 = mfcbc * c1o2+mfcbb * (vvz-c1o2)+mfcba * (vz2-vvz) * c1o2;
+                  m1 = -mfcbc-two* mfcbb *  vvz+mfcba * (one-vz2);
+                  m2 = mfcbc * c1o2+mfcbb * (vvz+c1o2)+mfcba * (vz2+vvz) * c1o2;
+                  mfcba = m0;
+                  mfcbb = m1;
+                  mfcbc = m2;
+                  /////////c//////////////////////////////////////////////////////////////////////////
+                  m0 = mfccc * c1o2+mfccb * (vvz-c1o2)+(mfcca+c1o9 * oMdrho) * (vz2-vvz) * c1o2;
+                  m1 = -mfccc-two* mfccb *  vvz+mfcca                  * (one-vz2)-c1o9 * oMdrho * vz2;
+                  m2 = mfccc * c1o2+mfccb * (vvz+c1o2)+(mfcca+c1o9 * oMdrho) * (vz2+vvz) * c1o2;
+                  mfcca = m0;
+                  mfccb = m1;
+                  mfccc = m2;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  //mit 1/6, 2/3, 1/6, 0, 0, 0, 1/18, 2/9, 1/18   Konditionieren
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  // Y - Dir
+                  m0 = mfaca * c1o2+mfaba * (vvy-c1o2)+(mfaaa+c1o6 * oMdrho) * (vy2-vvy) * c1o2;
+                  m1 = -mfaca-two* mfaba *  vvy+mfaaa                  * (one-vy2)-c1o6 * oMdrho * vy2;
+                  m2 = mfaca * c1o2+mfaba * (vvy+c1o2)+(mfaaa+c1o6 * oMdrho) * (vy2+vvy) * c1o2;
+                  mfaaa = m0;
+                  mfaba = m1;
+                  mfaca = m2;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m0 = mfacb * c1o2+mfabb * (vvy-c1o2)+(mfaab+c2o3 * oMdrho) * (vy2-vvy) * c1o2;
+                  m1 = -mfacb-two* mfabb *  vvy+mfaab                  * (one-vy2)-c2o3 * oMdrho * vy2;
+                  m2 = mfacb * c1o2+mfabb * (vvy+c1o2)+(mfaab+c2o3 * oMdrho) * (vy2+vvy) * c1o2;
+                  mfaab = m0;
+                  mfabb = m1;
+                  mfacb = m2;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m0 = mfacc * c1o2+mfabc * (vvy-c1o2)+(mfaac+c1o6 * oMdrho) * (vy2-vvy) * c1o2;
+                  m1 = -mfacc-two* mfabc *  vvy+mfaac                  * (one-vy2)-c1o6 * oMdrho * vy2;
+                  m2 = mfacc * c1o2+mfabc * (vvy+c1o2)+(mfaac+c1o6 * oMdrho) * (vy2+vvy) * c1o2;
+                  mfaac = m0;
+                  mfabc = m1;
+                  mfacc = m2;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m0 = mfbca * c1o2+mfbba * (vvy-c1o2)+mfbaa * (vy2-vvy) * c1o2;
+                  m1 = -mfbca-two* mfbba *  vvy+mfbaa * (one-vy2);
+                  m2 = mfbca * c1o2+mfbba * (vvy+c1o2)+mfbaa * (vy2+vvy) * c1o2;
+                  mfbaa = m0;
+                  mfbba = m1;
+                  mfbca = m2;
+                  /////////b//////////////////////////////////////////////////////////////////////////
+                  m0 = mfbcb * c1o2+mfbbb * (vvy-c1o2)+mfbab * (vy2-vvy) * c1o2;
+                  m1 = -mfbcb-two* mfbbb *  vvy+mfbab * (one-vy2);
+                  m2 = mfbcb * c1o2+mfbbb * (vvy+c1o2)+mfbab * (vy2+vvy) * c1o2;
+                  mfbab = m0;
+                  mfbbb = m1;
+                  mfbcb = m2;
+                  /////////b//////////////////////////////////////////////////////////////////////////
+                  m0 = mfbcc * c1o2+mfbbc * (vvy-c1o2)+mfbac * (vy2-vvy) * c1o2;
+                  m1 = -mfbcc-two* mfbbc *  vvy+mfbac * (one-vy2);
+                  m2 = mfbcc * c1o2+mfbbc * (vvy+c1o2)+mfbac * (vy2+vvy) * c1o2;
+                  mfbac = m0;
+                  mfbbc = m1;
+                  mfbcc = m2;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m0 = mfcca * c1o2+mfcba * (vvy-c1o2)+(mfcaa+c1o18 * oMdrho) * (vy2-vvy) * c1o2;
+                  m1 = -mfcca-two* mfcba *  vvy+mfcaa                   * (one-vy2)-c1o18 * oMdrho * vy2;
+                  m2 = mfcca * c1o2+mfcba * (vvy+c1o2)+(mfcaa+c1o18 * oMdrho) * (vy2+vvy) * c1o2;
+                  mfcaa = m0;
+                  mfcba = m1;
+                  mfcca = m2;
+                  /////////c//////////////////////////////////////////////////////////////////////////
+                  m0 = mfccb * c1o2+mfcbb * (vvy-c1o2)+(mfcab+c2o9 * oMdrho) * (vy2-vvy) * c1o2;
+                  m1 = -mfccb-two* mfcbb *  vvy+mfcab                  * (one-vy2)-c2o9 * oMdrho * vy2;
+                  m2 = mfccb * c1o2+mfcbb * (vvy+c1o2)+(mfcab+c2o9 * oMdrho) * (vy2+vvy) * c1o2;
+                  mfcab = m0;
+                  mfcbb = m1;
+                  mfccb = m2;
+                  /////////c//////////////////////////////////////////////////////////////////////////
+                  m0 = mfccc * c1o2+mfcbc * (vvy-c1o2)+(mfcac+c1o18 * oMdrho) * (vy2-vvy) * c1o2;
+                  m1 = -mfccc-two* mfcbc *  vvy+mfcac                   * (one-vy2)-c1o18 * oMdrho * vy2;
+                  m2 = mfccc * c1o2+mfcbc * (vvy+c1o2)+(mfcac+c1o18 * oMdrho) * (vy2+vvy) * c1o2;
+                  mfcac = m0;
+                  mfcbc = m1;
+                  mfccc = m2;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  //mit 1/36, 1/9, 1/36, 1/9, 4/9, 1/9, 1/36, 1/9, 1/36 Konditionieren
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  // X - Dir
+                  m0 = mfcaa * c1o2+mfbaa * (vvx-c1o2)+(mfaaa+c1o36 * oMdrho) * (vx2-vvx) * c1o2;
+                  m1 = -mfcaa-two* mfbaa *  vvx+mfaaa                   * (one-vx2)-c1o36 * oMdrho * vx2;
+                  m2 = mfcaa * c1o2+mfbaa * (vvx+c1o2)+(mfaaa+c1o36 * oMdrho) * (vx2+vvx) * c1o2;
+                  mfaaa = m0;
+                  mfbaa = m1;
+                  mfcaa = m2;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m0 = mfcba * c1o2+mfbba * (vvx-c1o2)+(mfaba+c1o9 * oMdrho) * (vx2-vvx) * c1o2;
+                  m1 = -mfcba-two* mfbba *  vvx+mfaba                  * (one-vx2)-c1o9 * oMdrho * vx2;
+                  m2 = mfcba * c1o2+mfbba * (vvx+c1o2)+(mfaba+c1o9 * oMdrho) * (vx2+vvx) * c1o2;
+                  mfaba = m0;
+                  mfbba = m1;
+                  mfcba = m2;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m0 = mfcca * c1o2+mfbca * (vvx-c1o2)+(mfaca+c1o36 * oMdrho) * (vx2-vvx) * c1o2;
+                  m1 = -mfcca-two* mfbca *  vvx+mfaca                   * (one-vx2)-c1o36 * oMdrho * vx2;
+                  m2 = mfcca * c1o2+mfbca * (vvx+c1o2)+(mfaca+c1o36 * oMdrho) * (vx2+vvx) * c1o2;
+                  mfaca = m0;
+                  mfbca = m1;
+                  mfcca = m2;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m0 = mfcab * c1o2+mfbab * (vvx-c1o2)+(mfaab+c1o9 * oMdrho) * (vx2-vvx) * c1o2;
+                  m1 = -mfcab-two* mfbab *  vvx+mfaab                  * (one-vx2)-c1o9 * oMdrho * vx2;
+                  m2 = mfcab * c1o2+mfbab * (vvx+c1o2)+(mfaab+c1o9 * oMdrho) * (vx2+vvx) * c1o2;
+                  mfaab = m0;
+                  mfbab = m1;
+                  mfcab = m2;
+                  ///////////b////////////////////////////////////////////////////////////////////////
+                  m0 = mfcbb * c1o2+mfbbb * (vvx-c1o2)+(mfabb+c4o9 * oMdrho) * (vx2-vvx) * c1o2;
+                  m1 = -mfcbb-two* mfbbb *  vvx+mfabb                  * (one-vx2)-c4o9 * oMdrho * vx2;
+                  m2 = mfcbb * c1o2+mfbbb * (vvx+c1o2)+(mfabb+c4o9 * oMdrho) * (vx2+vvx) * c1o2;
+                  mfabb = m0;
+                  mfbbb = m1;
+                  mfcbb = m2;
+                  ///////////b////////////////////////////////////////////////////////////////////////
+                  m0 = mfccb * c1o2+mfbcb * (vvx-c1o2)+(mfacb+c1o9 * oMdrho) * (vx2-vvx) * c1o2;
+                  m1 = -mfccb-two* mfbcb *  vvx+mfacb                  * (one-vx2)-c1o9 * oMdrho * vx2;
+                  m2 = mfccb * c1o2+mfbcb * (vvx+c1o2)+(mfacb+c1o9 * oMdrho) * (vx2+vvx) * c1o2;
+                  mfacb = m0;
+                  mfbcb = m1;
+                  mfccb = m2;
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  ////////////////////////////////////////////////////////////////////////////////////
+                  m0 = mfcac * c1o2+mfbac * (vvx-c1o2)+(mfaac+c1o36 * oMdrho) * (vx2-vvx) * c1o2;
+                  m1 = -mfcac-two* mfbac *  vvx+mfaac                   * (one-vx2)-c1o36 * oMdrho * vx2;
+                  m2 = mfcac * c1o2+mfbac * (vvx+c1o2)+(mfaac+c1o36 * oMdrho) * (vx2+vvx) * c1o2;
+                  mfaac = m0;
+                  mfbac = m1;
+                  mfcac = m2;
+                  ///////////c////////////////////////////////////////////////////////////////////////
+                  m0 = mfcbc * c1o2+mfbbc * (vvx-c1o2)+(mfabc+c1o9 * oMdrho) * (vx2-vvx) * c1o2;
+                  m1 = -mfcbc-two* mfbbc *  vvx+mfabc                  * (one-vx2)-c1o9 * oMdrho * vx2;
+                  m2 = mfcbc * c1o2+mfbbc * (vvx+c1o2)+(mfabc+c1o9 * oMdrho) * (vx2+vvx) * c1o2;
+                  mfabc = m0;
+                  mfbbc = m1;
+                  mfcbc = m2;
+                  ///////////c////////////////////////////////////////////////////////////////////////
+                  m0 = mfccc * c1o2+mfbcc * (vvx-c1o2)+(mfacc+c1o36 * oMdrho) * (vx2-vvx) * c1o2;
+                  m1 = -mfccc-two* mfbcc *  vvx+mfacc                   * (one-vx2)-c1o36 * oMdrho * vx2;
+                  m2 = mfccc * c1o2+mfbcc * (vvx+c1o2)+(mfacc+c1o36 * oMdrho) * (vx2+vvx) * c1o2;
+                  mfacc = m0;
+                  mfbcc = m1;
+                  mfccc = m2;
+                  ////////////////////////////////////////////////////////////////////////////////////
+
+                  //////////////////////////////////////////////////////////////////////////
+                  //proof correctness
+                  //////////////////////////////////////////////////////////////////////////
 #ifdef  PROOF_CORRECTNESS
-               LBMReal drho_post = (mfaaa+mfaac+mfaca+mfcaa+mfacc+mfcac+mfccc+mfcca)
-                  +(mfaab+mfacb+mfcab+mfccb)+(mfaba+mfabc+mfcba+mfcbc)+(mfbaa+mfbac+mfbca+mfbcc)
-                  +(mfabb+mfcbb)+(mfbab+mfbcb)+(mfbba+mfbbc)+mfbbb; 
-               //LBMReal dif = fabs(rho - rho_post);
-               LBMReal dif = drho - drho_post;
+                  LBMReal drho_post = (mfaaa+mfaac+mfaca+mfcaa+mfacc+mfcac+mfccc+mfcca)
+                     +(mfaab+mfacb+mfcab+mfccb)+(mfaba+mfabc+mfcba+mfcbc)+(mfbaa+mfbac+mfbca+mfbcc)
+                     +(mfabb+mfcbb)+(mfbab+mfbcb)+(mfbba+mfbbc)+mfbbb;
+                  //LBMReal dif = fabs(rho - rho_post);
+                  LBMReal dif = drho - drho_post;
 #ifdef SINGLEPRECISION
-               if(dif > 10.0E-7 || dif < -10.0E-7)
+                  if (dif > 10.0E-7 || dif < -10.0E-7)
 #else
-               if(dif > 10.0E-15 || dif < -10.0E-15)
+                  if (dif > 10.0E-15 || dif < -10.0E-15)
 #endif
-               {
-                  UB_THROW(UbException(UB_EXARGS,"rho="+UbSystem::toString(drho)+", rho_post="+UbSystem::toString(drho_post)
-                     +" dif="+UbSystem::toString(dif)
-                     +" rho is not correct for node "+UbSystem::toString(x1)+","+UbSystem::toString(x2)+","+UbSystem::toString(x3)));
-                  //UBLOG(logERROR,"LBMKernelETD3Q27CCLB::collideAll(): rho is not correct for node "+UbSystem::toString(x1)+","+UbSystem::toString(x2)+","+UbSystem::toString(x3));
-                  //exit(EXIT_FAILURE);
-               }
+                  {
+                     UB_THROW(UbException(UB_EXARGS, "rho="+UbSystem::toString(drho)+", rho_post="+UbSystem::toString(drho_post)
+                        +" dif="+UbSystem::toString(dif)
+                        +" rho is not correct for node "+UbSystem::toString(x1)+","+UbSystem::toString(x2)+","+UbSystem::toString(x3)));
+                     //UBLOG(logERROR,"LBMKernelETD3Q27CCLB::collideAll(): rho is not correct for node "+UbSystem::toString(x1)+","+UbSystem::toString(x2)+","+UbSystem::toString(x3));
+                     //exit(EXIT_FAILURE);
+                  }
 #endif
-               //////////////////////////////////////////////////////////////////////////
-               //write distribution
-               //////////////////////////////////////////////////////////////////////////
-               (*this->localDistributions)(D3Q27System::ET_E,x1,  x2,  x3)    = mfabb;
-               (*this->localDistributions)(D3Q27System::ET_N,x1,  x2,  x3)    = mfbab;
-               (*this->localDistributions)(D3Q27System::ET_T,x1,  x2,  x3)    = mfbba;
-               (*this->localDistributions)(D3Q27System::ET_NE,x1,  x2,  x3)   = mfaab;
-               (*this->localDistributions)(D3Q27System::ET_NW,x1p,x2,  x3)   = mfcab;
-               (*this->localDistributions)(D3Q27System::ET_TE,x1,  x2,  x3)   = mfaba;
-               (*this->localDistributions)(D3Q27System::ET_TW,x1p,x2,  x3)   = mfcba;
-               (*this->localDistributions)(D3Q27System::ET_TN,x1,  x2,  x3)   = mfbaa;
-               (*this->localDistributions)(D3Q27System::ET_TS,x1,  x2p,x3)   = mfbca;
-               (*this->localDistributions)(D3Q27System::ET_TNE,x1,  x2,  x3)  = mfaaa;
-               (*this->localDistributions)(D3Q27System::ET_TNW,x1p,x2,  x3)  = mfcaa;
-               (*this->localDistributions)(D3Q27System::ET_TSE,x1,  x2p,x3)  = mfaca;
-               (*this->localDistributions)(D3Q27System::ET_TSW,x1p,x2p,x3)  = mfcca;
-
-               (*this->nonLocalDistributions)(D3Q27System::ET_W,x1p,x2,  x3    ) = mfcbb;
-               (*this->nonLocalDistributions)(D3Q27System::ET_S,x1,  x2p,x3    ) = mfbcb;
-               (*this->nonLocalDistributions)(D3Q27System::ET_B,x1,  x2,  x3p  ) = mfbbc;
-               (*this->nonLocalDistributions)(D3Q27System::ET_SW,x1p,x2p,x3   ) = mfccb;
-               (*this->nonLocalDistributions)(D3Q27System::ET_SE,x1,  x2p,x3   ) = mfacb;
-               (*this->nonLocalDistributions)(D3Q27System::ET_BW,x1p,x2,  x3p ) = mfcbc;
-               (*this->nonLocalDistributions)(D3Q27System::ET_BE,x1,  x2,  x3p ) = mfabc;
-               (*this->nonLocalDistributions)(D3Q27System::ET_BS,x1,  x2p,x3p ) = mfbcc;
-               (*this->nonLocalDistributions)(D3Q27System::ET_BN,x1,  x2,  x3p ) = mfbac;
-               (*this->nonLocalDistributions)(D3Q27System::ET_BSW,x1p,x2p,x3p) = mfccc;
-               (*this->nonLocalDistributions)(D3Q27System::ET_BSE,x1,  x2p,x3p) = mfacc;
-               (*this->nonLocalDistributions)(D3Q27System::ET_BNW,x1p,x2,  x3p) = mfcac;
-               (*this->nonLocalDistributions)(D3Q27System::ET_BNE,x1,  x2,  x3p) = mfaac;
-
-               (*this->zeroDistributions)(x1,x2,x3) = mfbbb;
-               //////////////////////////////////////////////////////////////////////////
+                  //////////////////////////////////////////////////////////////////////////
+                  //write distribution
+                  //////////////////////////////////////////////////////////////////////////
+                  (*this->localDistributions)(D3Q27System::ET_E, x1, x2, x3)    = mfabb;
+                  (*this->localDistributions)(D3Q27System::ET_N, x1, x2, x3)    = mfbab;
+                  (*this->localDistributions)(D3Q27System::ET_T, x1, x2, x3)    = mfbba;
+                  (*this->localDistributions)(D3Q27System::ET_NE, x1, x2, x3)   = mfaab;
+                  (*this->localDistributions)(D3Q27System::ET_NW, x1p, x2, x3)   = mfcab;
+                  (*this->localDistributions)(D3Q27System::ET_TE, x1, x2, x3)   = mfaba;
+                  (*this->localDistributions)(D3Q27System::ET_TW, x1p, x2, x3)   = mfcba;
+                  (*this->localDistributions)(D3Q27System::ET_TN, x1, x2, x3)   = mfbaa;
+                  (*this->localDistributions)(D3Q27System::ET_TS, x1, x2p, x3)   = mfbca;
+                  (*this->localDistributions)(D3Q27System::ET_TNE, x1, x2, x3)  = mfaaa;
+                  (*this->localDistributions)(D3Q27System::ET_TNW, x1p, x2, x3)  = mfcaa;
+                  (*this->localDistributions)(D3Q27System::ET_TSE, x1, x2p, x3)  = mfaca;
+                  (*this->localDistributions)(D3Q27System::ET_TSW, x1p, x2p, x3)  = mfcca;
+
+                  (*this->nonLocalDistributions)(D3Q27System::ET_W, x1p, x2, x3) = mfcbb;
+                  (*this->nonLocalDistributions)(D3Q27System::ET_S, x1, x2p, x3) = mfbcb;
+                  (*this->nonLocalDistributions)(D3Q27System::ET_B, x1, x2, x3p) = mfbbc;
+                  (*this->nonLocalDistributions)(D3Q27System::ET_SW, x1p, x2p, x3) = mfccb;
+                  (*this->nonLocalDistributions)(D3Q27System::ET_SE, x1, x2p, x3) = mfacb;
+                  (*this->nonLocalDistributions)(D3Q27System::ET_BW, x1p, x2, x3p) = mfcbc;
+                  (*this->nonLocalDistributions)(D3Q27System::ET_BE, x1, x2, x3p) = mfabc;
+                  (*this->nonLocalDistributions)(D3Q27System::ET_BS, x1, x2p, x3p) = mfbcc;
+                  (*this->nonLocalDistributions)(D3Q27System::ET_BN, x1, x2, x3p) = mfbac;
+                  (*this->nonLocalDistributions)(D3Q27System::ET_BSW, x1p, x2p, x3p) = mfccc;
+                  (*this->nonLocalDistributions)(D3Q27System::ET_BSE, x1, x2p, x3p) = mfacc;
+                  (*this->nonLocalDistributions)(D3Q27System::ET_BNW, x1p, x2, x3p) = mfcac;
+                  (*this->nonLocalDistributions)(D3Q27System::ET_BNE, x1, x2, x3p) = mfaac;
+
+                  (*this->zeroDistributions)(x1, x2, x3) = mfbbb;
+                  //////////////////////////////////////////////////////////////////////////
 
+               }
             }
          }
       }
-   }
 
    }
 }
@@ -1030,3 +1050,8 @@ double CompressibleCumulantLBMKernel::getCallculationTime()
    //return timer.getDuration();
    return timer.getTotalTime();
 }
+//////////////////////////////////////////////////////////////////////////
+void CompressibleCumulantLBMKernel::setBulkOmegaToOmega(bool value)
+{
+   bulkOmegaToOmega = value;
+}
diff --git a/source/VirtualFluidsCore/LBM/CompressibleCumulantLBMKernel.h b/source/VirtualFluidsCore/LBM/CompressibleCumulantLBMKernel.h
index 23a2a056d..aa0f6c109 100644
--- a/source/VirtualFluidsCore/LBM/CompressibleCumulantLBMKernel.h
+++ b/source/VirtualFluidsCore/LBM/CompressibleCumulantLBMKernel.h
@@ -32,7 +32,7 @@ public:
    virtual void calculate();
    virtual LBMKernelPtr clone();
    double getCallculationTime();
-
+   void setBulkOmegaToOmega(bool value);
 protected:
    friend class boost::serialization::access;
    template<class Archive>
@@ -62,6 +62,10 @@ protected:
    LBMReal forcingX1;
    LBMReal forcingX2;
    LBMReal forcingX3;
+   
+   // bulk viscosity
+   bool bulkOmegaToOmega;
+   LBMReal OxxPyyPzz; 
 };
 #endif // CompressibleCumulantLBMKernel_h__
 
diff --git a/source/VirtualFluidsCore/LBM/CompressibleOffsetInterpolationProcessor.cpp b/source/VirtualFluidsCore/LBM/CompressibleOffsetInterpolationProcessor.cpp
index ce211998a..cf2263f92 100644
--- a/source/VirtualFluidsCore/LBM/CompressibleOffsetInterpolationProcessor.cpp
+++ b/source/VirtualFluidsCore/LBM/CompressibleOffsetInterpolationProcessor.cpp
@@ -49,14 +49,14 @@ void CompressibleOffsetInterpolationProcessor::interpolateCoarseToFine(D3Q27ICel
 {
    setOffsets(xoff, yoff, zoff);
    calcInterpolatedCoefficiets(icellC, omegaC, 0.5);
-   calcInterpolatedNode(icellF.BSW, omegaF, -0.25, -0.25, -0.25, calcPressBSW(), -1, -1, -1);
-   calcInterpolatedNode(icellF.BNE, omegaF,  0.25,  0.25, -0.25, calcPressBNE(),  1,  1, -1);
-   calcInterpolatedNode(icellF.TNW, omegaF, -0.25,  0.25,  0.25, calcPressTNW(), -1,  1,  1);
-   calcInterpolatedNode(icellF.TSE, omegaF,  0.25, -0.25,  0.25, calcPressTSE(),  1, -1,  1);
-   calcInterpolatedNode(icellF.BNW, omegaF, -0.25,  0.25, -0.25, calcPressBNW(), -1,  1, -1);
-   calcInterpolatedNode(icellF.BSE, omegaF,  0.25, -0.25, -0.25, calcPressBSE(),  1, -1, -1);
-   calcInterpolatedNode(icellF.TSW, omegaF, -0.25, -0.25,  0.25, calcPressTSW(), -1, -1,  1);
-   calcInterpolatedNode(icellF.TNE, omegaF,  0.25,  0.25,  0.25, calcPressTNE(),  1,  1,  1);
+   calcInterpolatedNodeCF(icellF.BSW, omegaF, -0.25, -0.25, -0.25, calcPressBSW(), -1, -1, -1);
+   calcInterpolatedNodeCF(icellF.BNE, omegaF,  0.25,  0.25, -0.25, calcPressBNE(),  1,  1, -1);
+   calcInterpolatedNodeCF(icellF.TNW, omegaF, -0.25,  0.25,  0.25, calcPressTNW(), -1,  1,  1);
+   calcInterpolatedNodeCF(icellF.TSE, omegaF,  0.25, -0.25,  0.25, calcPressTSE(),  1, -1,  1);
+   calcInterpolatedNodeCF(icellF.BNW, omegaF, -0.25,  0.25, -0.25, calcPressBNW(), -1,  1, -1);
+   calcInterpolatedNodeCF(icellF.BSE, omegaF,  0.25, -0.25, -0.25, calcPressBSE(),  1, -1, -1);
+   calcInterpolatedNodeCF(icellF.TSW, omegaF, -0.25, -0.25,  0.25, calcPressTSW(), -1, -1,  1);
+   calcInterpolatedNodeCF(icellF.TNE, omegaF,  0.25,  0.25,  0.25, calcPressTNE(),  1,  1,  1);
 }
 //////////////////////////////////////////////////////////////////////////
 void CompressibleOffsetInterpolationProcessor::interpolateFineToCoarse(D3Q27ICell& icellF, LBMReal* icellC, LBMReal xoff, LBMReal yoff, LBMReal zoff)
@@ -288,46 +288,46 @@ void CompressibleOffsetInterpolationProcessor::calcInterpolatedCoefficiets(const
 
 
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-   kxyAverage       =(kxyFromfcNEQ_SWB+
-                      kxyFromfcNEQ_SWT+
-                      kxyFromfcNEQ_SET+
-                      kxyFromfcNEQ_SEB+
-                      kxyFromfcNEQ_NWB+
-                      kxyFromfcNEQ_NWT+
-                      kxyFromfcNEQ_NET+
-                      kxyFromfcNEQ_NEB)*c1o8-(ay+bx);
-   kyzAverage       =(kyzFromfcNEQ_SWB+
-                      kyzFromfcNEQ_SWT+
-                      kyzFromfcNEQ_SET+
-                      kyzFromfcNEQ_SEB+
-                      kyzFromfcNEQ_NWB+
-                      kyzFromfcNEQ_NWT+
-                      kyzFromfcNEQ_NET+
-                      kyzFromfcNEQ_NEB)*c1o8-(bz+cy);
-   kxzAverage       =(kxzFromfcNEQ_SWB+
-                      kxzFromfcNEQ_SWT+
-                      kxzFromfcNEQ_SET+
-                      kxzFromfcNEQ_SEB+
-                      kxzFromfcNEQ_NWB+
-                      kxzFromfcNEQ_NWT+
-                      kxzFromfcNEQ_NET+
-                      kxzFromfcNEQ_NEB)*c1o8-(az+cx);
-   kxxMyyAverage    =(kxxMyyFromfcNEQ_SWB+
-                      kxxMyyFromfcNEQ_SWT+
-                      kxxMyyFromfcNEQ_SET+
-                      kxxMyyFromfcNEQ_SEB+
-                      kxxMyyFromfcNEQ_NWB+
-                      kxxMyyFromfcNEQ_NWT+
-                      kxxMyyFromfcNEQ_NET+
-                      kxxMyyFromfcNEQ_NEB)*c1o8-(ax-by);
-   kxxMzzAverage    =(kxxMzzFromfcNEQ_SWB+
-                     kxxMzzFromfcNEQ_SWT+
-                     kxxMzzFromfcNEQ_SET+
-                     kxxMzzFromfcNEQ_SEB+
-                     kxxMzzFromfcNEQ_NWB+
-                     kxxMzzFromfcNEQ_NWT+
-                     kxxMzzFromfcNEQ_NET+
-                     kxxMzzFromfcNEQ_NEB)*c1o8-(ax-cz);
+   kxyAverage       =0;//(kxyFromfcNEQ_SWB+
+                       //kxyFromfcNEQ_SWT+
+                       //kxyFromfcNEQ_SET+
+                       //kxyFromfcNEQ_SEB+
+                       //kxyFromfcNEQ_NWB+
+                       //kxyFromfcNEQ_NWT+
+                       //kxyFromfcNEQ_NET+
+                       //kxyFromfcNEQ_NEB)*c1o8-(ay+bx);
+   kyzAverage       =0;//(kyzFromfcNEQ_SWB+
+                       //kyzFromfcNEQ_SWT+
+                       //kyzFromfcNEQ_SET+
+                       //kyzFromfcNEQ_SEB+
+                       //kyzFromfcNEQ_NWB+
+                       //kyzFromfcNEQ_NWT+
+                       //kyzFromfcNEQ_NET+
+                       //kyzFromfcNEQ_NEB)*c1o8-(bz+cy);
+   kxzAverage       =0;//(kxzFromfcNEQ_SWB+
+                       //kxzFromfcNEQ_SWT+
+                       //kxzFromfcNEQ_SET+
+                       //kxzFromfcNEQ_SEB+
+                       //kxzFromfcNEQ_NWB+
+                       //kxzFromfcNEQ_NWT+
+                       //kxzFromfcNEQ_NET+
+                       //kxzFromfcNEQ_NEB)*c1o8-(az+cx);
+   kxxMyyAverage    =0;//(kxxMyyFromfcNEQ_SWB+
+                       //kxxMyyFromfcNEQ_SWT+
+                       //kxxMyyFromfcNEQ_SET+
+                       //kxxMyyFromfcNEQ_SEB+
+                       //kxxMyyFromfcNEQ_NWB+
+                       //kxxMyyFromfcNEQ_NWT+
+                       //kxxMyyFromfcNEQ_NET+
+                       //kxxMyyFromfcNEQ_NEB)*c1o8-(ax-by);
+   kxxMzzAverage    =0;//(kxxMzzFromfcNEQ_SWB+
+                       //kxxMzzFromfcNEQ_SWT+
+                       //kxxMzzFromfcNEQ_SET+
+                       //kxxMzzFromfcNEQ_SEB+
+                       //kxxMzzFromfcNEQ_NWB+
+                       //kxxMzzFromfcNEQ_NWT+
+                       //kxxMzzFromfcNEQ_NET+
+                       //kxxMzzFromfcNEQ_NEB)*c1o8-(ax-cz);
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // Bernd das Brot
@@ -464,7 +464,7 @@ void CompressibleOffsetInterpolationProcessor::calcInterpolatedCoefficiets(const
    yz_TNW =   0.0625*eps_new *((                bxyz +     cxyz)/(72.*o));
 }
 //////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetInterpolationProcessor::calcInterpolatedNode(LBMReal* f, LBMReal omega, LBMReal x, LBMReal y, LBMReal z, LBMReal press, LBMReal xs, LBMReal ys, LBMReal zs)
+void CompressibleOffsetInterpolationProcessor::calcInterpolatedNodeCF(LBMReal* f, LBMReal omega, LBMReal x, LBMReal y, LBMReal z, LBMReal press, LBMReal xs, LBMReal ys, LBMReal zs)
 {
    using namespace D3Q27System;
 
diff --git a/source/VirtualFluidsCore/LBM/CompressibleOffsetInterpolationProcessor.h b/source/VirtualFluidsCore/LBM/CompressibleOffsetInterpolationProcessor.h
index 8d20c5aa0..4f8e4d5d0 100644
--- a/source/VirtualFluidsCore/LBM/CompressibleOffsetInterpolationProcessor.h
+++ b/source/VirtualFluidsCore/LBM/CompressibleOffsetInterpolationProcessor.h
@@ -49,7 +49,7 @@ private:
    void calcMoments(const LBMReal* const f, LBMReal omega, LBMReal& rho, LBMReal& vx1, LBMReal& vx2, LBMReal& vx3, 
       LBMReal& kxy, LBMReal& kyz, LBMReal& kxz, LBMReal& kxxMyy, LBMReal& kxxMzz);
    void calcInterpolatedCoefficiets(const D3Q27ICell& icell, LBMReal omega, LBMReal eps_new);
-   void calcInterpolatedNode(LBMReal* f, LBMReal omega, LBMReal x, LBMReal y, LBMReal z, LBMReal press, LBMReal xs, LBMReal ys, LBMReal zs);
+   void calcInterpolatedNodeCF(LBMReal* f, LBMReal omega, LBMReal x, LBMReal y, LBMReal z, LBMReal press, LBMReal xs, LBMReal ys, LBMReal zs);
    LBMReal calcPressBSW();
    LBMReal calcPressTSW();
    LBMReal calcPressTSE();
diff --git a/source/VirtualFluidsCore/LBM/CompressibleOffsetMomentsInterpolationProcessor.cpp b/source/VirtualFluidsCore/LBM/CompressibleOffsetMomentsInterpolationProcessor.cpp
new file mode 100644
index 000000000..dc81684e5
--- /dev/null
+++ b/source/VirtualFluidsCore/LBM/CompressibleOffsetMomentsInterpolationProcessor.cpp
@@ -0,0 +1,1278 @@
+#include "CompressibleOffsetMomentsInterpolationProcessor.h"
+#include "D3Q27System.h"
+
+#include <boost/foreach.hpp>
+
+CompressibleOffsetMomentsInterpolationProcessor::CompressibleOffsetMomentsInterpolationProcessor()
+   : omegaC(0.0), omegaF(0.0)
+{
+   this->bulkOmegaToOmega = false;
+   this->OxxPyyPzzC = one;
+   this->OxxPyyPzzF = one;
+}
+//////////////////////////////////////////////////////////////////////////
+CompressibleOffsetMomentsInterpolationProcessor::CompressibleOffsetMomentsInterpolationProcessor(LBMReal omegaC, LBMReal omegaF)
+   : omegaC(omegaC), omegaF(omegaF)
+{
+   this->bulkOmegaToOmega = false;
+   this->OxxPyyPzzC = one;
+   this->OxxPyyPzzF = one;
+}
+//////////////////////////////////////////////////////////////////////////
+CompressibleOffsetMomentsInterpolationProcessor::~CompressibleOffsetMomentsInterpolationProcessor()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+InterpolationProcessorPtr CompressibleOffsetMomentsInterpolationProcessor::clone()
+{
+   InterpolationProcessorPtr iproc = InterpolationProcessorPtr (new CompressibleOffsetMomentsInterpolationProcessor(this->omegaC, this->omegaF));
+   if (bulkOmegaToOmega)
+   {
+      boost::dynamic_pointer_cast<CompressibleOffsetMomentsInterpolationProcessor>(iproc)->OxxPyyPzzC = omegaC;
+      boost::dynamic_pointer_cast<CompressibleOffsetMomentsInterpolationProcessor>(iproc)->OxxPyyPzzF = omegaF;
+   }
+   else
+   {
+      boost::dynamic_pointer_cast<CompressibleOffsetMomentsInterpolationProcessor>(iproc)->OxxPyyPzzC = one;
+      boost::dynamic_pointer_cast<CompressibleOffsetMomentsInterpolationProcessor>(iproc)->OxxPyyPzzF = one;
+   }
+   return iproc;
+}
+//////////////////////////////////////////////////////////////////////////
+void CompressibleOffsetMomentsInterpolationProcessor::setOmegas( LBMReal omegaC, LBMReal omegaF )
+{
+   this->omegaC = omegaC;
+   this->omegaF = omegaF;
+}
+//////////////////////////////////////////////////////////////////////////
+void CompressibleOffsetMomentsInterpolationProcessor::setOffsets(LBMReal xoff, LBMReal yoff, LBMReal zoff)
+{
+   this->xoff = xoff;
+   this->yoff = yoff;
+   this->zoff = zoff;     
+   this->xoff_sq = xoff * xoff;
+   this->yoff_sq = yoff * yoff;
+   this->zoff_sq = zoff * zoff;
+}
+//////////////////////////////////////////////////////////////////////////
+void CompressibleOffsetMomentsInterpolationProcessor::interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF, LBMReal xoff, LBMReal yoff, LBMReal zoff)
+{
+   setOffsets(xoff, yoff, zoff);
+   calcInterpolatedCoefficiets(icellC, omegaC, 0.5);
+   calcInterpolatedNodeCF(icellF.BSW, omegaF, -0.25, -0.25, -0.25, calcPressBSW(), -1, -1, -1);
+   calcInterpolatedNodeCF(icellF.BNE, omegaF,  0.25,  0.25, -0.25, calcPressBNE(),  1,  1, -1);
+   calcInterpolatedNodeCF(icellF.TNW, omegaF, -0.25,  0.25,  0.25, calcPressTNW(), -1,  1,  1);
+   calcInterpolatedNodeCF(icellF.TSE, omegaF,  0.25, -0.25,  0.25, calcPressTSE(),  1, -1,  1);
+   calcInterpolatedNodeCF(icellF.BNW, omegaF, -0.25,  0.25, -0.25, calcPressBNW(), -1,  1, -1);
+   calcInterpolatedNodeCF(icellF.BSE, omegaF,  0.25, -0.25, -0.25, calcPressBSE(),  1, -1, -1);
+   calcInterpolatedNodeCF(icellF.TSW, omegaF, -0.25, -0.25,  0.25, calcPressTSW(), -1, -1,  1);
+   calcInterpolatedNodeCF(icellF.TNE, omegaF,  0.25,  0.25,  0.25, calcPressTNE(),  1,  1,  1);
+}
+//////////////////////////////////////////////////////////////////////////
+void CompressibleOffsetMomentsInterpolationProcessor::interpolateFineToCoarse(D3Q27ICell& icellF, LBMReal* icellC, LBMReal xoff, LBMReal yoff, LBMReal zoff)
+{
+   setOffsets(xoff, yoff, zoff);
+   calcInterpolatedCoefficiets(icellF, omegaF, 2.0);
+   calcInterpolatedNodeFC(icellC, omegaC);
+}
+//////////////////////////////////////////////////////////////////////////
+void CompressibleOffsetMomentsInterpolationProcessor::calcMoments(const LBMReal* const f, LBMReal omega, LBMReal& press, LBMReal& vx1, LBMReal& vx2, LBMReal& vx3, 
+                                                    LBMReal& kxy, LBMReal& kyz, LBMReal& kxz, LBMReal& kxxMyy, LBMReal& kxxMzz)
+{
+   using namespace D3Q27System;
+
+   LBMReal drho = 0.0;
+   D3Q27System::calcCompMacroscopicValues(f,drho,vx1,vx2,vx3);
+   
+   press = drho; //interpolate rho!
+
+   kxy   = -3.*omega*((((f[TSW]+f[BNE])-(f[TNW]+f[BSE]))+((f[BSW]+f[TNE])-(f[BNW]+f[TSE])))+((f[SW]+f[NE])-(f[NW]+f[SE]))/(one + drho)-(vx1*vx2));// might not be optimal MG 25.2.13
+   kyz   = -3.*omega*((((f[BSW]+f[TNE])-(f[TSE]+f[BNW]))+((f[BSE]+f[TNW])-(f[TSW]+f[BNE])))+((f[BS]+f[TN])-(f[TS]+f[BN]))/(one + drho)-(vx2*vx3));
+   kxz   = -3.*omega*((((f[BNW]+f[TSE])-(f[TSW]+f[BNE]))+((f[BSW]+f[TNE])-(f[BSE]+f[TNW])))+((f[BW]+f[TE])-(f[TW]+f[BE]))/(one + drho)-(vx1*vx3));
+   kxxMyy = -3./2.*omega*((((f[BW]+f[TE])-(f[BS]+f[TN]))+((f[TW]+f[BE])-(f[TS]+f[BN])))+((f[W]+f[E])-(f[S]+f[N]))/(one + drho)-(vx1*vx1-vx2*vx2));
+   kxxMzz = -3./2.*omega*((((f[NW]+f[SE])-(f[BS]+f[TN]))+((f[SW]+f[NE])-(f[TS]+f[BN])))+((f[W]+f[E])-(f[B]+f[T]))/(one + drho)-(vx1*vx1-vx3*vx3));
+}
+//////////////////////////////////////////////////////////////////////////
+void CompressibleOffsetMomentsInterpolationProcessor::calcInterpolatedCoefficiets(const D3Q27ICell& icell, LBMReal omega, LBMReal eps_new)
+{
+   LBMReal        vx1_SWT,vx2_SWT,vx3_SWT;
+   LBMReal        vx1_NWT,vx2_NWT,vx3_NWT;
+   LBMReal        vx1_NET,vx2_NET,vx3_NET;
+   LBMReal        vx1_SET,vx2_SET,vx3_SET;
+   LBMReal        vx1_SWB,vx2_SWB,vx3_SWB;
+   LBMReal        vx1_NWB,vx2_NWB,vx3_NWB;
+   LBMReal        vx1_NEB,vx2_NEB,vx3_NEB;
+   LBMReal        vx1_SEB,vx2_SEB,vx3_SEB;
+
+   LBMReal        kxyFromfcNEQ_SWT, kyzFromfcNEQ_SWT, kxzFromfcNEQ_SWT, kxxMyyFromfcNEQ_SWT, kxxMzzFromfcNEQ_SWT;
+   LBMReal        kxyFromfcNEQ_NWT, kyzFromfcNEQ_NWT, kxzFromfcNEQ_NWT, kxxMyyFromfcNEQ_NWT, kxxMzzFromfcNEQ_NWT;
+   LBMReal        kxyFromfcNEQ_NET, kyzFromfcNEQ_NET, kxzFromfcNEQ_NET, kxxMyyFromfcNEQ_NET, kxxMzzFromfcNEQ_NET;
+   LBMReal        kxyFromfcNEQ_SET, kyzFromfcNEQ_SET, kxzFromfcNEQ_SET, kxxMyyFromfcNEQ_SET, kxxMzzFromfcNEQ_SET;
+   LBMReal        kxyFromfcNEQ_SWB, kyzFromfcNEQ_SWB, kxzFromfcNEQ_SWB, kxxMyyFromfcNEQ_SWB, kxxMzzFromfcNEQ_SWB;
+   LBMReal        kxyFromfcNEQ_NWB, kyzFromfcNEQ_NWB, kxzFromfcNEQ_NWB, kxxMyyFromfcNEQ_NWB, kxxMzzFromfcNEQ_NWB;
+   LBMReal        kxyFromfcNEQ_NEB, kyzFromfcNEQ_NEB, kxzFromfcNEQ_NEB, kxxMyyFromfcNEQ_NEB, kxxMzzFromfcNEQ_NEB;
+   LBMReal        kxyFromfcNEQ_SEB, kyzFromfcNEQ_SEB, kxzFromfcNEQ_SEB, kxxMyyFromfcNEQ_SEB, kxxMzzFromfcNEQ_SEB;
+
+   calcMoments(icell.TSW,omega,press_SWT,vx1_SWT,vx2_SWT,vx3_SWT, kxyFromfcNEQ_SWT, kyzFromfcNEQ_SWT, kxzFromfcNEQ_SWT, kxxMyyFromfcNEQ_SWT, kxxMzzFromfcNEQ_SWT);
+   calcMoments(icell.TNW,omega,press_NWT,vx1_NWT,vx2_NWT,vx3_NWT, kxyFromfcNEQ_NWT, kyzFromfcNEQ_NWT, kxzFromfcNEQ_NWT, kxxMyyFromfcNEQ_NWT, kxxMzzFromfcNEQ_NWT);
+   calcMoments(icell.TNE,omega,press_NET,vx1_NET,vx2_NET,vx3_NET, kxyFromfcNEQ_NET, kyzFromfcNEQ_NET, kxzFromfcNEQ_NET, kxxMyyFromfcNEQ_NET, kxxMzzFromfcNEQ_NET);
+   calcMoments(icell.TSE,omega,press_SET,vx1_SET,vx2_SET,vx3_SET, kxyFromfcNEQ_SET, kyzFromfcNEQ_SET, kxzFromfcNEQ_SET, kxxMyyFromfcNEQ_SET, kxxMzzFromfcNEQ_SET);
+   calcMoments(icell.BSW,omega,press_SWB,vx1_SWB,vx2_SWB,vx3_SWB, kxyFromfcNEQ_SWB, kyzFromfcNEQ_SWB, kxzFromfcNEQ_SWB, kxxMyyFromfcNEQ_SWB, kxxMzzFromfcNEQ_SWB);
+   calcMoments(icell.BNW,omega,press_NWB,vx1_NWB,vx2_NWB,vx3_NWB, kxyFromfcNEQ_NWB, kyzFromfcNEQ_NWB, kxzFromfcNEQ_NWB, kxxMyyFromfcNEQ_NWB, kxxMzzFromfcNEQ_NWB);
+   calcMoments(icell.BNE,omega,press_NEB,vx1_NEB,vx2_NEB,vx3_NEB, kxyFromfcNEQ_NEB, kyzFromfcNEQ_NEB, kxzFromfcNEQ_NEB, kxxMyyFromfcNEQ_NEB, kxxMzzFromfcNEQ_NEB);
+   calcMoments(icell.BSE,omega,press_SEB,vx1_SEB,vx2_SEB,vx3_SEB, kxyFromfcNEQ_SEB, kyzFromfcNEQ_SEB, kxzFromfcNEQ_SEB, kxxMyyFromfcNEQ_SEB, kxxMzzFromfcNEQ_SEB);
+
+   //LBMReal dxRho=c1o4*((press_NET-press_SWB)+(press_SET-press_NWB)+(press_NEB-press_SWT)+(press_SEB-press_NWT));
+   //LBMReal dyRho=c1o4*((press_NET-press_SWB)-(press_SET-press_NWB)+(press_NEB-press_SWT)-(press_SEB-press_NWT));
+   //LBMReal dzRho=c1o4*((press_NET-press_SWB)+(press_SET-press_NWB)-(press_NEB-press_SWT)-(press_SEB-press_NWT));
+
+   //   kxyFromfcNEQ_SWT+=vx1_SWT*dyRho+vx2_SWT*dxRho;
+   //   kxyFromfcNEQ_NWT+=vx1_NWT*dyRho+vx2_NWT*dxRho;
+   //   kxyFromfcNEQ_NET+=vx1_NET*dyRho+vx2_NET*dxRho;
+   //   kxyFromfcNEQ_SET+=vx1_SET*dyRho+vx2_SET*dxRho;
+   //   kxyFromfcNEQ_SWB+=vx1_SWB*dyRho+vx2_SWB*dxRho;
+   //   kxyFromfcNEQ_NWB+=vx1_NWB*dyRho+vx2_NWB*dxRho;
+   //   kxyFromfcNEQ_NEB+=vx1_NEB*dyRho+vx2_NEB*dxRho;
+   //   kxyFromfcNEQ_SEB+=vx1_SEB*dyRho+vx2_SEB*dxRho;
+
+   //   kyzFromfcNEQ_SWT+=vx3_SWT*dyRho+vx2_SWT*dzRho;
+   //   kyzFromfcNEQ_NWT+=vx3_NWT*dyRho+vx2_NWT*dzRho;
+   //   kyzFromfcNEQ_NET+=vx3_NET*dyRho+vx2_NET*dzRho;
+   //   kyzFromfcNEQ_SET+=vx3_SET*dyRho+vx2_SET*dzRho;
+   //   kyzFromfcNEQ_SWB+=vx3_SWB*dyRho+vx2_SWB*dzRho;
+   //   kyzFromfcNEQ_NWB+=vx3_NWB*dyRho+vx2_NWB*dzRho;
+   //   kyzFromfcNEQ_NEB+=vx3_NEB*dyRho+vx2_NEB*dzRho;
+   //   kyzFromfcNEQ_SEB+=vx3_SEB*dyRho+vx2_SEB*dzRho;
+
+   //   kxzFromfcNEQ_SWT+=vx1_SWT*dzRho+vx3_SWT*dxRho;
+   //   kxzFromfcNEQ_NWT+=vx1_NWT*dzRho+vx3_NWT*dxRho;
+   //   kxzFromfcNEQ_NET+=vx1_NET*dzRho+vx3_NET*dxRho;
+   //   kxzFromfcNEQ_SET+=vx1_SET*dzRho+vx3_SET*dxRho;
+   //   kxzFromfcNEQ_SWB+=vx1_SWB*dzRho+vx3_SWB*dxRho;
+   //   kxzFromfcNEQ_NWB+=vx1_NWB*dzRho+vx3_NWB*dxRho;
+   //   kxzFromfcNEQ_NEB+=vx1_NEB*dzRho+vx3_NEB*dxRho;
+   //   kxzFromfcNEQ_SEB+=vx1_SEB*dzRho+vx3_SEB*dxRho;
+
+   //   kxxMyyFromfcNEQ_SWT+=vx1_SWT*dxRho-vx2_SWT*dyRho;
+   //   kxxMyyFromfcNEQ_NWT+=vx1_NWT*dxRho-vx2_NWT*dyRho;
+   //   kxxMyyFromfcNEQ_NET+=vx1_NET*dxRho-vx2_NET*dyRho;
+   //   kxxMyyFromfcNEQ_SET+=vx1_SET*dxRho-vx2_SET*dyRho;
+   //   kxxMyyFromfcNEQ_SWB+=vx1_SWB*dxRho-vx2_SWB*dyRho;
+   //   kxxMyyFromfcNEQ_NWB+=vx1_NWB*dxRho-vx2_NWB*dyRho;
+   //   kxxMyyFromfcNEQ_NEB+=vx1_NEB*dxRho-vx2_NEB*dyRho;
+   //   kxxMyyFromfcNEQ_SEB+=vx1_SEB*dxRho-vx2_SEB*dyRho;
+
+   //   kxxMzzFromfcNEQ_SWT+=vx1_SWT*dxRho-vx3_SWT*dzRho;
+   //   kxxMzzFromfcNEQ_NWT+=vx1_NWT*dxRho-vx3_NWT*dzRho;
+   //   kxxMzzFromfcNEQ_NET+=vx1_NET*dxRho-vx3_NET*dzRho;
+   //   kxxMzzFromfcNEQ_SET+=vx1_SET*dxRho-vx3_SET*dzRho;
+   //   kxxMzzFromfcNEQ_SWB+=vx1_SWB*dxRho-vx3_SWB*dzRho;
+   //   kxxMzzFromfcNEQ_NWB+=vx1_NWB*dxRho-vx3_NWB*dzRho;
+   //   kxxMzzFromfcNEQ_NEB+=vx1_NEB*dxRho-vx3_NEB*dzRho;
+   //   kxxMzzFromfcNEQ_SEB+=vx1_SEB*dxRho-vx3_SEB*dzRho;
+
+
+      //kxxMzzFromfcNEQ_SWT=0.0;
+      //kxxMzzFromfcNEQ_NWT=0.0;
+      //kxxMzzFromfcNEQ_NET=0.0;
+      //kxxMzzFromfcNEQ_SET=0.0;
+      //kxxMzzFromfcNEQ_SWB=0.0;
+      //kxxMzzFromfcNEQ_NWB=0.0;
+      //kxxMzzFromfcNEQ_NEB=0.0;
+      //kxxMzzFromfcNEQ_SEB=0.0;
+
+
+
+
+
+   a0 = (-kxxMyyFromfcNEQ_NEB - kxxMyyFromfcNEQ_NET + kxxMyyFromfcNEQ_NWB + kxxMyyFromfcNEQ_NWT -
+      kxxMyyFromfcNEQ_SEB - kxxMyyFromfcNEQ_SET + kxxMyyFromfcNEQ_SWB + kxxMyyFromfcNEQ_SWT -
+      kxxMzzFromfcNEQ_NEB - kxxMzzFromfcNEQ_NET + kxxMzzFromfcNEQ_NWB + kxxMzzFromfcNEQ_NWT -
+      kxxMzzFromfcNEQ_SEB - kxxMzzFromfcNEQ_SET + kxxMzzFromfcNEQ_SWB + kxxMzzFromfcNEQ_SWT -
+      2.*kxyFromfcNEQ_NEB - 2.*kxyFromfcNEQ_NET - 2.*kxyFromfcNEQ_NWB - 2.*kxyFromfcNEQ_NWT +
+      2.*kxyFromfcNEQ_SEB + 2.*kxyFromfcNEQ_SET + 2.*kxyFromfcNEQ_SWB + 2.*kxyFromfcNEQ_SWT +
+      2.*kxzFromfcNEQ_NEB - 2.*kxzFromfcNEQ_NET + 2.*kxzFromfcNEQ_NWB - 2.*kxzFromfcNEQ_NWT +
+      2.*kxzFromfcNEQ_SEB - 2.*kxzFromfcNEQ_SET + 2.*kxzFromfcNEQ_SWB - 2.*kxzFromfcNEQ_SWT +
+      8.*vx1_NEB + 8.*vx1_NET + 8.*vx1_NWB + 8.*vx1_NWT + 8.*vx1_SEB +
+      8.*vx1_SET + 8.*vx1_SWB + 8.*vx1_SWT + 2.*vx2_NEB + 2.*vx2_NET -
+      2.*vx2_NWB - 2.*vx2_NWT - 2.*vx2_SEB - 2.*vx2_SET + 2.*vx2_SWB +
+      2.*vx2_SWT - 2.*vx3_NEB + 2.*vx3_NET + 2.*vx3_NWB - 2.*vx3_NWT -
+      2.*vx3_SEB + 2.*vx3_SET + 2.*vx3_SWB - 2.*vx3_SWT)/64.;
+   b0 = (2.*kxxMyyFromfcNEQ_NEB + 2.*kxxMyyFromfcNEQ_NET + 2.*kxxMyyFromfcNEQ_NWB + 2.*kxxMyyFromfcNEQ_NWT -
+      2.*kxxMyyFromfcNEQ_SEB - 2.*kxxMyyFromfcNEQ_SET - 2.*kxxMyyFromfcNEQ_SWB - 2.*kxxMyyFromfcNEQ_SWT -
+      kxxMzzFromfcNEQ_NEB - kxxMzzFromfcNEQ_NET - kxxMzzFromfcNEQ_NWB - kxxMzzFromfcNEQ_NWT +
+      kxxMzzFromfcNEQ_SEB + kxxMzzFromfcNEQ_SET + kxxMzzFromfcNEQ_SWB + kxxMzzFromfcNEQ_SWT -
+      2.*kxyFromfcNEQ_NEB - 2.*kxyFromfcNEQ_NET + 2.*kxyFromfcNEQ_NWB + 2.*kxyFromfcNEQ_NWT -
+      2.*kxyFromfcNEQ_SEB - 2.*kxyFromfcNEQ_SET + 2.*kxyFromfcNEQ_SWB + 2.*kxyFromfcNEQ_SWT +
+      2.*kyzFromfcNEQ_NEB - 2.*kyzFromfcNEQ_NET + 2.*kyzFromfcNEQ_NWB - 2.*kyzFromfcNEQ_NWT +
+      2.*kyzFromfcNEQ_SEB - 2.*kyzFromfcNEQ_SET + 2.*kyzFromfcNEQ_SWB - 2.*kyzFromfcNEQ_SWT +
+      2.*vx1_NEB + 2.*vx1_NET - 2.*vx1_NWB - 2.*vx1_NWT -
+      2.*vx1_SEB - 2.*vx1_SET + 2.*vx1_SWB + 2.*vx1_SWT +
+      8.*vx2_NEB + 8.*vx2_NET + 8.*vx2_NWB + 8.*vx2_NWT +
+      8.*vx2_SEB + 8.*vx2_SET + 8.*vx2_SWB + 8.*vx2_SWT -
+      2.*vx3_NEB + 2.*vx3_NET - 2.*vx3_NWB + 2.*vx3_NWT +
+      2.*vx3_SEB - 2.*vx3_SET + 2.*vx3_SWB - 2.*vx3_SWT)/64.;
+   c0 = (kxxMyyFromfcNEQ_NEB - kxxMyyFromfcNEQ_NET + kxxMyyFromfcNEQ_NWB - kxxMyyFromfcNEQ_NWT +
+      kxxMyyFromfcNEQ_SEB - kxxMyyFromfcNEQ_SET + kxxMyyFromfcNEQ_SWB - kxxMyyFromfcNEQ_SWT -
+      2.*kxxMzzFromfcNEQ_NEB + 2.*kxxMzzFromfcNEQ_NET - 2.*kxxMzzFromfcNEQ_NWB + 2.*kxxMzzFromfcNEQ_NWT -
+      2.*kxxMzzFromfcNEQ_SEB + 2.*kxxMzzFromfcNEQ_SET - 2.*kxxMzzFromfcNEQ_SWB + 2.*kxxMzzFromfcNEQ_SWT -
+      2.*kxzFromfcNEQ_NEB - 2.*kxzFromfcNEQ_NET + 2.*kxzFromfcNEQ_NWB + 2.*kxzFromfcNEQ_NWT -
+      2.*kxzFromfcNEQ_SEB - 2.*kxzFromfcNEQ_SET + 2.*kxzFromfcNEQ_SWB + 2.*kxzFromfcNEQ_SWT -
+      2.*kyzFromfcNEQ_NEB - 2.*kyzFromfcNEQ_NET - 2.*kyzFromfcNEQ_NWB - 2.*kyzFromfcNEQ_NWT +
+      2.*kyzFromfcNEQ_SEB + 2.*kyzFromfcNEQ_SET + 2.*kyzFromfcNEQ_SWB + 2.*kyzFromfcNEQ_SWT -
+      2.*vx1_NEB + 2.*vx1_NET + 2.*vx1_NWB - 2.*vx1_NWT -
+      2.*vx1_SEB + 2.*vx1_SET + 2.*vx1_SWB - 2.*vx1_SWT -
+      2.*vx2_NEB + 2.*vx2_NET - 2.*vx2_NWB + 2.*vx2_NWT +
+      2.*vx2_SEB - 2.*vx2_SET + 2.*vx2_SWB - 2.*vx2_SWT +
+      8.*vx3_NEB + 8.*vx3_NET + 8.*vx3_NWB + 8.*vx3_NWT +
+      8.*vx3_SEB + 8.*vx3_SET + 8.*vx3_SWB + 8.*vx3_SWT)/64.;
+   ax = (vx1_NEB + vx1_NET - vx1_NWB - vx1_NWT + vx1_SEB + vx1_SET - vx1_SWB - vx1_SWT)/4.;
+   bx = (vx2_NEB + vx2_NET - vx2_NWB - vx2_NWT + vx2_SEB + vx2_SET - vx2_SWB - vx2_SWT)/4.;
+   cx = (vx3_NEB + vx3_NET - vx3_NWB - vx3_NWT + vx3_SEB + vx3_SET - vx3_SWB - vx3_SWT)/4.;
+   axx= (kxxMyyFromfcNEQ_NEB + kxxMyyFromfcNEQ_NET - kxxMyyFromfcNEQ_NWB - kxxMyyFromfcNEQ_NWT +
+      kxxMyyFromfcNEQ_SEB + kxxMyyFromfcNEQ_SET - kxxMyyFromfcNEQ_SWB - kxxMyyFromfcNEQ_SWT +
+      kxxMzzFromfcNEQ_NEB + kxxMzzFromfcNEQ_NET - kxxMzzFromfcNEQ_NWB - kxxMzzFromfcNEQ_NWT +
+      kxxMzzFromfcNEQ_SEB + kxxMzzFromfcNEQ_SET - kxxMzzFromfcNEQ_SWB - kxxMzzFromfcNEQ_SWT +
+      2.*vx2_NEB + 2.*vx2_NET - 2.*vx2_NWB - 2.*vx2_NWT -
+      2.*vx2_SEB - 2.*vx2_SET + 2.*vx2_SWB + 2.*vx2_SWT -
+      2.*vx3_NEB + 2.*vx3_NET + 2.*vx3_NWB - 2.*vx3_NWT -
+      2.*vx3_SEB + 2.*vx3_SET + 2.*vx3_SWB - 2.*vx3_SWT)/16.;
+   bxx= (kxyFromfcNEQ_NEB + kxyFromfcNEQ_NET - kxyFromfcNEQ_NWB - kxyFromfcNEQ_NWT +
+      kxyFromfcNEQ_SEB + kxyFromfcNEQ_SET - kxyFromfcNEQ_SWB - kxyFromfcNEQ_SWT -
+      2.*vx1_NEB - 2.*vx1_NET + 2.*vx1_NWB + 2.*vx1_NWT +
+      2.*vx1_SEB + 2.*vx1_SET - 2.*vx1_SWB - 2.*vx1_SWT)/8.;
+   cxx= (kxzFromfcNEQ_NEB + kxzFromfcNEQ_NET - kxzFromfcNEQ_NWB - kxzFromfcNEQ_NWT +
+      kxzFromfcNEQ_SEB + kxzFromfcNEQ_SET - kxzFromfcNEQ_SWB - kxzFromfcNEQ_SWT +
+      2.*vx1_NEB - 2.*vx1_NET - 2.*vx1_NWB + 2.*vx1_NWT +
+      2.*vx1_SEB - 2.*vx1_SET - 2.*vx1_SWB + 2.*vx1_SWT)/8.;
+   ay = (vx1_NEB + vx1_NET + vx1_NWB + vx1_NWT - vx1_SEB - vx1_SET - vx1_SWB - vx1_SWT)/4.;
+   by = (vx2_NEB + vx2_NET + vx2_NWB + vx2_NWT - vx2_SEB - vx2_SET - vx2_SWB - vx2_SWT)/4.;
+   cy = (vx3_NEB + vx3_NET + vx3_NWB + vx3_NWT - vx3_SEB - vx3_SET - vx3_SWB - vx3_SWT)/4.;
+   ayy= (kxyFromfcNEQ_NEB + kxyFromfcNEQ_NET + kxyFromfcNEQ_NWB + kxyFromfcNEQ_NWT -
+      kxyFromfcNEQ_SEB - kxyFromfcNEQ_SET - kxyFromfcNEQ_SWB - kxyFromfcNEQ_SWT -
+      2.*vx2_NEB - 2.*vx2_NET + 2.*vx2_NWB + 2.*vx2_NWT +
+      2.*vx2_SEB + 2.*vx2_SET - 2.*vx2_SWB - 2.*vx2_SWT)/8.;
+   byy= (-2.*kxxMyyFromfcNEQ_NEB - 2.*kxxMyyFromfcNEQ_NET - 2.*kxxMyyFromfcNEQ_NWB - 2.*kxxMyyFromfcNEQ_NWT +
+      2.*kxxMyyFromfcNEQ_SEB + 2.*kxxMyyFromfcNEQ_SET + 2.*kxxMyyFromfcNEQ_SWB + 2.*kxxMyyFromfcNEQ_SWT +
+      kxxMzzFromfcNEQ_NEB + kxxMzzFromfcNEQ_NET + kxxMzzFromfcNEQ_NWB + kxxMzzFromfcNEQ_NWT -
+      kxxMzzFromfcNEQ_SEB - kxxMzzFromfcNEQ_SET - kxxMzzFromfcNEQ_SWB - kxxMzzFromfcNEQ_SWT +
+      2.*vx1_NEB + 2.*vx1_NET - 2.*vx1_NWB - 2.*vx1_NWT -
+      2.*vx1_SEB - 2.*vx1_SET + 2.*vx1_SWB + 2.*vx1_SWT -
+      2.*vx3_NEB + 2.*vx3_NET - 2.*vx3_NWB + 2.*vx3_NWT +
+      2.*vx3_SEB - 2.*vx3_SET + 2.*vx3_SWB - 2.*vx3_SWT)/16.;
+   cyy= (kyzFromfcNEQ_NEB + kyzFromfcNEQ_NET + kyzFromfcNEQ_NWB + kyzFromfcNEQ_NWT -
+      kyzFromfcNEQ_SEB - kyzFromfcNEQ_SET - kyzFromfcNEQ_SWB - kyzFromfcNEQ_SWT +
+      2.*vx2_NEB - 2.*vx2_NET + 2.*vx2_NWB - 2.*vx2_NWT -
+      2.*vx2_SEB + 2.*vx2_SET - 2.*vx2_SWB + 2.*vx2_SWT)/8.;
+   az = (-vx1_NEB + vx1_NET - vx1_NWB + vx1_NWT - vx1_SEB + vx1_SET - vx1_SWB + vx1_SWT)/4.;
+   bz = (-vx2_NEB + vx2_NET - vx2_NWB + vx2_NWT - vx2_SEB + vx2_SET - vx2_SWB + vx2_SWT)/4.;
+   cz = (-vx3_NEB + vx3_NET - vx3_NWB + vx3_NWT - vx3_SEB + vx3_SET - vx3_SWB + vx3_SWT)/4.;
+   azz= (-kxzFromfcNEQ_NEB + kxzFromfcNEQ_NET - kxzFromfcNEQ_NWB + kxzFromfcNEQ_NWT -
+      kxzFromfcNEQ_SEB + kxzFromfcNEQ_SET - kxzFromfcNEQ_SWB + kxzFromfcNEQ_SWT +
+      2.*vx3_NEB - 2.*vx3_NET - 2.*vx3_NWB + 2.*vx3_NWT +
+      2.*vx3_SEB - 2.*vx3_SET - 2.*vx3_SWB + 2.*vx3_SWT)/8.;
+   bzz= (-kyzFromfcNEQ_NEB + kyzFromfcNEQ_NET - kyzFromfcNEQ_NWB + kyzFromfcNEQ_NWT -
+      kyzFromfcNEQ_SEB + kyzFromfcNEQ_SET - kyzFromfcNEQ_SWB + kyzFromfcNEQ_SWT +
+      2.*vx3_NEB - 2.*vx3_NET + 2.*vx3_NWB - 2.*vx3_NWT -
+      2.*vx3_SEB + 2.*vx3_SET - 2.*vx3_SWB + 2.*vx3_SWT)/8.;
+   czz= (-kxxMyyFromfcNEQ_NEB + kxxMyyFromfcNEQ_NET - kxxMyyFromfcNEQ_NWB + kxxMyyFromfcNEQ_NWT -
+      kxxMyyFromfcNEQ_SEB + kxxMyyFromfcNEQ_SET - kxxMyyFromfcNEQ_SWB + kxxMyyFromfcNEQ_SWT +
+      2.*kxxMzzFromfcNEQ_NEB - 2.*kxxMzzFromfcNEQ_NET + 2.*kxxMzzFromfcNEQ_NWB - 2.*kxxMzzFromfcNEQ_NWT +
+      2.*kxxMzzFromfcNEQ_SEB - 2.*kxxMzzFromfcNEQ_SET + 2.*kxxMzzFromfcNEQ_SWB - 2.*kxxMzzFromfcNEQ_SWT -
+      2.*vx1_NEB + 2.*vx1_NET + 2.*vx1_NWB - 2.*vx1_NWT -
+      2.*vx1_SEB + 2.*vx1_SET + 2.*vx1_SWB - 2.*vx1_SWT -
+      2.*vx2_NEB + 2.*vx2_NET - 2.*vx2_NWB + 2.*vx2_NWT +
+      2.*vx2_SEB - 2.*vx2_SET + 2.*vx2_SWB - 2.*vx2_SWT)/16.;
+   axy= (vx1_NEB + vx1_NET - vx1_NWB - vx1_NWT - vx1_SEB - vx1_SET + vx1_SWB + vx1_SWT)/2.;
+   bxy= (vx2_NEB + vx2_NET - vx2_NWB - vx2_NWT - vx2_SEB - vx2_SET + vx2_SWB + vx2_SWT)/2.;
+   cxy= (vx3_NEB + vx3_NET - vx3_NWB - vx3_NWT - vx3_SEB - vx3_SET + vx3_SWB + vx3_SWT)/2.;
+   axz= (-vx1_NEB + vx1_NET + vx1_NWB - vx1_NWT - vx1_SEB + vx1_SET + vx1_SWB - vx1_SWT)/2.;
+   bxz= (-vx2_NEB + vx2_NET + vx2_NWB - vx2_NWT - vx2_SEB + vx2_SET + vx2_SWB - vx2_SWT)/2.;
+   cxz= (-vx3_NEB + vx3_NET + vx3_NWB - vx3_NWT - vx3_SEB + vx3_SET + vx3_SWB - vx3_SWT)/2.;
+   ayz= (-vx1_NEB + vx1_NET - vx1_NWB + vx1_NWT + vx1_SEB - vx1_SET + vx1_SWB - vx1_SWT)/2.;
+   byz= (-vx2_NEB + vx2_NET - vx2_NWB + vx2_NWT + vx2_SEB - vx2_SET + vx2_SWB - vx2_SWT)/2.;
+   cyz= (-vx3_NEB + vx3_NET - vx3_NWB + vx3_NWT + vx3_SEB - vx3_SET + vx3_SWB - vx3_SWT)/2.;
+   axyz=-vx1_NEB + vx1_NET + vx1_NWB - vx1_NWT + vx1_SEB - vx1_SET - vx1_SWB + vx1_SWT;
+   bxyz=-vx2_NEB + vx2_NET + vx2_NWB - vx2_NWT + vx2_SEB - vx2_SET - vx2_SWB + vx2_SWT;
+   cxyz=-vx3_NEB + vx3_NET + vx3_NWB - vx3_NWT + vx3_SEB - vx3_SET - vx3_SWB + vx3_SWT;
+
+
+   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+   kxyAverage       =0;//(kxyFromfcNEQ_SWB+
+                       //kxyFromfcNEQ_SWT+
+                       //kxyFromfcNEQ_SET+
+                       //kxyFromfcNEQ_SEB+
+                       //kxyFromfcNEQ_NWB+
+                       //kxyFromfcNEQ_NWT+
+                       //kxyFromfcNEQ_NET+
+                       //kxyFromfcNEQ_NEB)*c1o8-(ay+bx);
+   kyzAverage       =0;//(kyzFromfcNEQ_SWB+
+                       //kyzFromfcNEQ_SWT+
+                       //kyzFromfcNEQ_SET+
+                       //kyzFromfcNEQ_SEB+
+                       //kyzFromfcNEQ_NWB+
+                       //kyzFromfcNEQ_NWT+
+                       //kyzFromfcNEQ_NET+
+                       //kyzFromfcNEQ_NEB)*c1o8-(bz+cy);
+   kxzAverage       =0;//(kxzFromfcNEQ_SWB+
+                       //kxzFromfcNEQ_SWT+
+                       //kxzFromfcNEQ_SET+
+                       //kxzFromfcNEQ_SEB+
+                       //kxzFromfcNEQ_NWB+
+                       //kxzFromfcNEQ_NWT+
+                       //kxzFromfcNEQ_NET+
+                       //kxzFromfcNEQ_NEB)*c1o8-(az+cx);
+   kxxMyyAverage    =0;//(kxxMyyFromfcNEQ_SWB+
+                       //kxxMyyFromfcNEQ_SWT+
+                       //kxxMyyFromfcNEQ_SET+
+                       //kxxMyyFromfcNEQ_SEB+
+                       //kxxMyyFromfcNEQ_NWB+
+                       //kxxMyyFromfcNEQ_NWT+
+                       //kxxMyyFromfcNEQ_NET+
+                       //kxxMyyFromfcNEQ_NEB)*c1o8-(ax-by);
+   kxxMzzAverage    =0;//(kxxMzzFromfcNEQ_SWB+
+                       //kxxMzzFromfcNEQ_SWT+
+                       //kxxMzzFromfcNEQ_SET+
+                       //kxxMzzFromfcNEQ_SEB+
+                       //kxxMzzFromfcNEQ_NWB+
+                       //kxxMzzFromfcNEQ_NWT+
+                       //kxxMzzFromfcNEQ_NET+
+                       //kxxMzzFromfcNEQ_NEB)*c1o8-(ax-cz);
+   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+   //
+   // Bernd das Brot
+   //
+   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+   a0 = a0 + xoff * ax + yoff * ay + zoff * az + xoff_sq * axx + yoff_sq * ayy + zoff_sq * azz + xoff*yoff*axy + xoff*zoff*axz + yoff*zoff*ayz + xoff*yoff*zoff*axyz ;
+   ax = ax + 2. * xoff * axx + yoff * axy + zoff * axz + yoff*zoff*axyz;
+   ay = ay + 2. * yoff * ayy + xoff * axy + zoff * ayz + xoff*zoff*axyz;
+   az = az + 2. * zoff * azz + xoff * axz + yoff * ayz + xoff*yoff*axyz;
+   b0 = b0 + xoff * bx + yoff * by + zoff * bz + xoff_sq * bxx + yoff_sq * byy + zoff_sq * bzz + xoff*yoff*bxy + xoff*zoff*bxz + yoff*zoff*byz + xoff*yoff*zoff*bxyz;
+   bx = bx + 2. * xoff * bxx + yoff * bxy + zoff * bxz + yoff*zoff*bxyz;
+   by = by + 2. * yoff * byy + xoff * bxy + zoff * byz + xoff*zoff*bxyz;
+   bz = bz + 2. * zoff * bzz + xoff * bxz + yoff * byz + xoff*yoff*bxyz;
+   c0 = c0 + xoff * cx + yoff * cy + zoff * cz + xoff_sq * cxx + yoff_sq * cyy + zoff_sq * czz + xoff*yoff*cxy + xoff*zoff*cxz + yoff*zoff*cyz + xoff*yoff*zoff*cxyz;
+   cx = cx + 2. * xoff * cxx + yoff * cxy + zoff * cxz + yoff*zoff*cxyz;
+   cy = cy + 2. * yoff * cyy + xoff * cxy + zoff * cyz + xoff*zoff*cxyz;
+   cz = cz + 2. * zoff * czz + xoff * cxz + yoff * cyz + xoff*yoff*cxyz;
+   axy= axy + zoff*axyz;
+   axz= axz + yoff*axyz;
+   ayz= ayz + xoff*axyz;
+   bxy= bxy + zoff*bxyz;
+   bxz= bxz + yoff*bxyz;
+   byz= byz + xoff*bxyz;
+   cxy= cxy + zoff*cxyz;
+   cxz= cxz + yoff*cxyz;
+   cyz= cyz + xoff*cxyz;
+   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+   const LBMReal o = omega;
+
+   f_E = eps_new*((2*(-2*ax + by + cz-kxxMzzAverage-kxxMyyAverage))/(27.*o));
+   f_N = eps_new*((2*(ax - 2*by + cz+2*kxxMyyAverage-kxxMzzAverage))/(27.*o));
+   f_T = eps_new*((2*(ax + by - 2*cz-kxxMyyAverage+2*kxxMzzAverage))/(27.*o));
+   f_NE = eps_new*(-(ax + 3*ay + 3*bx + by - 2*cz+2*kxxMyyAverage-kxxMyyAverage+3*kxyAverage)/(54.*o));
+   f_SE = eps_new*(-(ax - 3*ay - 3*bx + by - 2*cz+2*kxxMyyAverage-kxxMyyAverage-3*kxyAverage)/(54.*o));
+   f_TE = eps_new*(-(ax + 3*az - 2*by + 3*cx + cz+2*kxxMyyAverage-kxxMzzAverage+3*kxzAverage)/(54.*o));
+   f_BE = eps_new*(-(ax - 3*az - 2*by - 3*cx + cz+2*kxxMyyAverage-kxxMzzAverage-3*kxzAverage)/(54.*o));
+   f_TN = eps_new*(-(-2*ax + by + 3*bz + 3*cy + cz-kxxMyyAverage-kxxMzzAverage+3*kyzAverage)/(54.*o));
+   f_BN = eps_new*(-(-2*ax + by - 3*bz - 3*cy + cz-kxxMyyAverage-kxxMzzAverage-3*kyzAverage)/(54.*o));
+   f_ZERO = 0.;
+   f_TNE = eps_new*(-(ay + az + bx + bz + cx + cy+kxyAverage+kxzAverage+kyzAverage)/(72.*o));
+   f_TSW = eps_new*((-ay + az - bx + bz + cx + cy-kxyAverage+kxzAverage+kyzAverage)/(72.*o));
+   f_TSE = eps_new*((ay - az + bx + bz - cx + cy+kxyAverage-kxzAverage+kyzAverage)/(72.*o));
+   f_TNW = eps_new*((ay + az + bx - bz + cx - cy+kxyAverage+kxzAverage-kyzAverage)/(72.*o));
+
+   x_E = 0.25*eps_new*((2*(-4*axx + bxy + cxz))/(27.*o));
+   x_N = 0.25*eps_new*((2*(2*axx - 2*bxy + cxz))/(27.*o));
+   x_T = 0.25*eps_new*((2*(2*axx + bxy - 2*cxz))/(27.*o));
+   x_NE = 0.25*eps_new*(-((2*axx + 3*axy + 6*bxx + bxy - 2*cxz))/(54.*o));
+   x_SE = 0.25*eps_new*(-((2*axx - 3*axy - 6*bxx + bxy - 2*cxz))/(54.*o));
+   x_TE = 0.25*eps_new*(-((2*axx + 3*axz - 2*bxy + 6*cxx + cxz))/(54.*o));
+   x_BE = 0.25*eps_new*(-((2*axx - 3*axz - 2*bxy - 6*cxx + cxz))/(54.*o));
+   x_TN = 0.25*eps_new*(-((-4*axx + bxy + 3*bxz + 3*cxy + cxz))/(54.*o));
+   x_BN = 0.25*eps_new*(-((-4*axx + bxy - 3*bxz - 3*cxy + cxz))/(54.*o));
+   x_ZERO = 0.;
+   x_TNE = 0.25*eps_new*(-((axy + axz + 2*bxx + bxz + 2*cxx + cxy))/(72.*o));
+   x_TSW = 0.25*eps_new*(((-axy + axz - 2*bxx + bxz + 2*cxx + cxy))/(72.*o));
+   x_TSE = 0.25*eps_new*(((axy - axz + 2*bxx + bxz - 2*cxx + cxy))/(72.*o));
+   x_TNW = 0.25*eps_new*(((axy + axz + 2*bxx - bxz + 2*cxx - cxy))/(72.*o));
+
+   y_E = 0.25*eps_new*(2*(-2*axy + 2*byy + cyz))/(27.*o);
+   y_N = 0.25*eps_new*(2*(axy - 4*byy + cyz))/(27.*o);
+   y_T = 0.25*eps_new*(2*(axy + 2*byy - 2*cyz))/(27.*o);
+   y_NE = 0.25*eps_new*(-((axy + 6*ayy + 3*bxy + 2*byy - 2*cyz))/(54.*o));
+   y_SE = 0.25*eps_new*(-((axy - 6*ayy - 3*bxy + 2*byy - 2*cyz))/(54.*o));
+   y_TE = 0.25*eps_new*(-((axy + 3*ayz - 4*byy + 3*cxy + cyz))/(54.*o));
+   y_BE = 0.25*eps_new*(-((axy - 3*ayz - 4*byy - 3*cxy + cyz))/(54.*o));
+   y_TN = 0.25*eps_new*(-((-2*axy + 2*byy + 3*byz + 6*cyy + cyz))/(54.*o));
+   y_BN = 0.25*eps_new*(-((-2*axy + 2*byy - 3*byz - 6*cyy + cyz))/(54.*o));
+   y_ZERO = 0.;
+   y_TNE = 0.25*eps_new*(-((2*ayy + ayz + bxy + byz + cxy + 2*cyy))/(72.*o));
+   y_TSW = 0.25*eps_new*(((-2*ayy + ayz - bxy + byz + cxy + 2*cyy))/(72.*o));
+   y_TSE = 0.25*eps_new*(((2*ayy - ayz + bxy + byz - cxy + 2*cyy))/(72.*o));
+   y_TNW = 0.25*eps_new*(((2*ayy + ayz + bxy - byz + cxy - 2*cyy))/(72.*o));
+
+   z_E = 0.25*eps_new*((2*(-2*axz + byz + 2*czz))/(27.*o));
+   z_N = 0.25*eps_new*((2*(axz - 2*byz + 2*czz))/(27.*o));
+   z_T = 0.25*eps_new*((2*(axz + byz - 4*czz))/(27.*o));
+   z_NE = 0.25*eps_new*(-((axz + 3*ayz + 3*bxz + byz - 4*czz))/(54.*o));
+   z_SE = 0.25*eps_new*(-((axz - 3*ayz - 3*bxz + byz - 4*czz))/(54.*o));
+   z_TE = 0.25*eps_new*(-((axz + 6*azz - 2*byz + 3*cxz + 2*czz))/(54.*o));
+   z_BE = 0.25*eps_new*(-((axz - 6*azz - 2*byz - 3*cxz + 2*czz))/(54.*o));
+   z_TN = 0.25*eps_new*(-((-2*axz + byz + 6*bzz + 3*cyz + 2*czz))/(54.*o));
+   z_BN = 0.25*eps_new*(-((-2*axz + byz - 6*bzz - 3*cyz + 2*czz))/(54.*o));
+   z_ZERO = 0.;
+   z_TNE = 0.25*eps_new*(-((ayz + 2*azz + bxz + 2*bzz + cxz + cyz))/(72.*o));
+   z_TSW = 0.25*eps_new*(((-ayz + 2*azz - bxz + 2*bzz + cxz + cyz))/(72.*o));
+   z_TSE = 0.25*eps_new*(((ayz - 2*azz + bxz + 2*bzz - cxz + cyz))/(72.*o));
+   z_TNW = 0.25*eps_new*(((ayz + 2*azz + bxz - 2*bzz + cxz - cyz))/(72.*o));
+
+   xy_E   =   0.0625*eps_new *((                       2.*cxyz)/(27.*o));
+   xy_N   =   0.0625*eps_new *((                       2.*cxyz)/(27.*o));
+   xy_T   = -(0.0625*eps_new *((                       4.*cxyz)/(27.*o)));
+   xy_NE  =   0.0625*eps_new *(                            cxyz /(27.*o));
+   xy_SE  =   0.0625*eps_new *(                            cxyz /(27.*o));
+   xy_TE  = -(0.0625*eps_new *(( 3.*axyz            +     cxyz)/(54.*o)));
+   xy_BE  = -(0.0625*eps_new *((-3.*axyz            +     cxyz)/(54.*o)));
+   xy_TN  = -(0.0625*eps_new *((            3.*bxyz +     cxyz)/(54.*o)));
+   xy_BN  = -(0.0625*eps_new *((          - 3.*bxyz +     cxyz)/(54.*o)));
+   //xy_ZERO=   0.0625*eps_new;
+   xy_TNE = -(0.0625*eps_new *((     axyz +     bxyz           )/(72.*o)));
+   xy_TSW =   0.0625*eps_new *((     axyz +     bxyz           )/(72.*o));
+   xy_TSE =   0.0625*eps_new *((-    axyz +     bxyz           )/(72.*o));
+   xy_TNW =   0.0625*eps_new *((     axyz -     bxyz           )/(72.*o));
+
+   xz_E   =   0.0625*eps_new *((            2.*bxyz           )/(27.*o));
+   xz_N   = -(0.0625*eps_new *((            4.*bxyz           )/(27.*o)));
+   xz_T   =   0.0625*eps_new *((            2.*bxyz           )/(27.*o));
+   xz_NE  = -(0.0625*eps_new *(( 3.*axyz +     bxyz           )/(54.*o)));
+   xz_SE  = -(0.0625*eps_new *((-3.*axyz +     bxyz           )/(54.*o)));
+   xz_TE  =   0.0625*eps_new *((                bxyz           )/(27.*o));
+   xz_BE  =   0.0625*eps_new *((                bxyz           )/(27.*o));
+   xz_TN  = -(0.0625*eps_new *((                bxyz + 3.*cxyz)/(54.*o)));
+   xz_BN  = -(0.0625*eps_new *((                bxyz - 3.*cxyz)/(54.*o)));
+   //xz_ZERO=   0.0625*eps_new;
+   xz_TNE = -(0.0625*eps_new *((     axyz            +     cxyz)/(72.*o)));
+   xz_TSW =   0.0625*eps_new *((-    axyz            +     cxyz)/(72.*o));
+   xz_TSE =   0.0625*eps_new *((     axyz            +     cxyz)/(72.*o));
+   xz_TNW =   0.0625*eps_new *((     axyz            -     cxyz)/(72.*o));
+
+   yz_E   = -(0.0625*eps_new *(( 4.*axyz                      )/(27.*o)));
+   yz_N   =   0.0625*eps_new *(( 2.*axyz                      )/(27.*o));
+   yz_T   =   0.0625*eps_new *(( 2.*axyz                      )/(27.*o));
+   yz_NE  = -(0.0625*eps_new *((     axyz + 3.*bxyz           )/(54.*o)));
+   yz_SE  = -(0.0625*eps_new *((     axyz - 3.*bxyz           )/(54.*o)));
+   yz_TE  = -(0.0625*eps_new *((     axyz            + 3.*cxyz)/(54.*o)));
+   yz_BE  = -(0.0625*eps_new *((     axyz            - 3.*cxyz)/(54.*o)));
+   yz_TN  =   0.0625*eps_new *((     axyz                      )/(27.*o));
+   yz_BN  =   0.0625*eps_new *((     axyz                      )/(27.*o));
+   //yz_ZERO=   0.0625*eps_new;
+   yz_TNE = -(0.0625*eps_new *((                bxyz +     cxyz)/(72.*o)));
+   yz_TSW =   0.0625*eps_new *((          -     bxyz +     cxyz)/(72.*o));
+   yz_TSE =   0.0625*eps_new *((                bxyz -     cxyz)/(72.*o));
+   yz_TNW =   0.0625*eps_new *((                bxyz +     cxyz)/(72.*o));
+}
+//////////////////////////////////////////////////////////////////////////
+void CompressibleOffsetMomentsInterpolationProcessor::calcInterpolatedNodeCF(LBMReal* f, LBMReal omega, LBMReal x, LBMReal y, LBMReal z, LBMReal press, LBMReal xs, LBMReal ys, LBMReal zs)
+{
+   using namespace D3Q27System;
+
+   LBMReal eps_new = 0.5;
+   LBMReal o = omega;
+   //bulk viscosity
+   LBMReal oP = OxxPyyPzzF;
+
+   LBMReal rho  = press ;//+ (2.*axx*x+axy*y+axz*z+axyz*y*z+ax + 2.*byy*y+bxy*x+byz*z+bxyz*x*z+by + 2.*czz*z+cxz*x+cyz*y+cxyz*x*y+cz)/3.;
+   LBMReal vx1  = a0 + 0.25*( xs*ax + ys*ay + zs*az) + 0.0625*(axx + xs*ys*axy + xs*zs*axz + ayy + ys*zs*ayz + azz) + 0.015625*(xs*ys*zs*axyz);
+   LBMReal vx2  = b0 + 0.25*( xs*bx + ys*by + zs*bz) + 0.0625*(bxx + xs*ys*bxy + xs*zs*bxz + byy + ys*zs*byz + bzz) + 0.015625*(xs*ys*zs*bxyz);
+   LBMReal vx3  = c0 + 0.25*( xs*cx + ys*cy + zs*cz) + 0.0625*(cxx + xs*ys*cxy + xs*zs*cxz + cyy + ys*zs*cyz + czz) + 0.015625*(xs*ys*zs*cxyz);
+
+   LBMReal mfcbb = zeroReal;
+   LBMReal mfabb = zeroReal;
+   LBMReal mfbcb = zeroReal;
+   LBMReal mfbab = zeroReal;
+   LBMReal mfbbc = zeroReal;
+   LBMReal mfbba = zeroReal;
+   LBMReal mfccb = zeroReal;
+   LBMReal mfaab = zeroReal;
+   LBMReal mfcab = zeroReal;
+   LBMReal mfacb = zeroReal;
+   LBMReal mfcbc = zeroReal;
+   LBMReal mfaba = zeroReal;
+   LBMReal mfcba = zeroReal;
+   LBMReal mfabc = zeroReal;
+   LBMReal mfbcc = zeroReal;
+   LBMReal mfbaa = zeroReal;
+   LBMReal mfbca = zeroReal;
+   LBMReal mfbac = zeroReal;
+   LBMReal mfbbb = zeroReal;
+   LBMReal mfccc = zeroReal;
+   LBMReal mfaac = zeroReal;
+   LBMReal mfcac = zeroReal;
+   LBMReal mfacc = zeroReal;
+   LBMReal mfcca = zeroReal;
+   LBMReal mfaaa = zeroReal;
+   LBMReal mfcaa = zeroReal;
+   LBMReal mfaca = zeroReal;
+
+   mfaaa = press; // if drho is interpolated directly
+
+   LBMReal vx1Sq = vx1*vx1;
+   LBMReal vx2Sq = vx2*vx2;
+   LBMReal vx3Sq = vx3*vx3;
+   LBMReal oMdrho = one;
+
+   //2.f
+
+   // linear combinations
+   LBMReal mxxPyyPzz = mfaaa - c2o3*(ax + by + two*axx*x + bxy*x + axy*y + two*byy*y + axz*z + byz*z + bxyz*x*z + axyz*y*z + cz - cxz*x + cyz*y + cxyz*x*y + two*czz*z)*eps_new / oP* (one + press);
+   LBMReal mxxMyy    = -c2o3*(ax - by + kxxMyyAverage + two*axx*x - bxy*x + axy*y - two*byy*y + axz*z - byz*z - bxyz*x*z + axyz*y*z)*eps_new/o * (one + press);
+   LBMReal mxxMzz    = -c2o3*(ax - cz + kxxMzzAverage + two*axx*x - cxz*x + axy*y - cyz*y - cxyz*x*y + axz*z - two*czz*z + axyz*y*z)*eps_new/o * (one + press);
+
+   mfabb     = -c1o3 * (bz + cy + kyzAverage + bxz*x + cxy*x + byz*y + two*cyy*y + bxyz*x*y + two*bzz*z + cyz*z + cxyz*x*z)*eps_new/o * (one + press);
+   mfbab     = -c1o3 * (az + cx + kxzAverage + axz*x + two*cxx*x + ayz*y + cxy*y + axyz*x*y + two*azz*z + cxz*z + cxyz*y*z)*eps_new/o * (one + press);
+   mfbba     = -c1o3 * (ay + bx + kxyAverage + axy*x + two*bxx*x + two*ayy*y + bxy*y + ayz*z + bxz*z + axyz*x*z + bxyz*y*z)*eps_new/o * (one + press);
+
+   // linear combinations back
+   mfcaa = c1o3 * (mxxMyy +       mxxMzz + mxxPyyPzz) ;
+   mfaca = c1o3 * (-two * mxxMyy +       mxxMzz + mxxPyyPzz) ;
+   mfaac = c1o3 * (mxxMyy - two * mxxMzz + mxxPyyPzz) ;
+
+   //three
+   mfbbb = zeroReal;
+   LBMReal mxxyPyzz = zeroReal;
+   LBMReal mxxyMyzz = zeroReal;
+   LBMReal mxxzPyyz = zeroReal;
+   LBMReal mxxzMyyz = zeroReal;
+   LBMReal mxyyPxzz =  zeroReal;
+   LBMReal mxyyMxzz = zeroReal;
+
+   // linear combinations back
+   mfcba = (mxxyMyzz + mxxyPyzz) * c1o2;
+   mfabc = (-mxxyMyzz + mxxyPyzz) * c1o2;
+   mfcab = (mxxzMyyz + mxxzPyyz) * c1o2;
+   mfacb = (-mxxzMyyz + mxxzPyyz) * c1o2;
+   mfbca = (mxyyMxzz + mxyyPxzz) * c1o2;
+   mfbac = (-mxyyMxzz + mxyyPxzz) * c1o2;
+
+   //4.f
+   mfacc = mfaaa*c1o9;
+   mfcac = mfacc;
+   mfcca = mfacc;
+
+   //5.
+
+   //6.
+
+   mfccc = mfaaa*c1o27;
+   ////////////////////////////////////////////////////////////////////////////////////
+   //back
+   ////////////////////////////////////////////////////////////////////////////////////
+   //mit 1, 0, 1/3, 0, 0, 0, 1/3, 0, 1/9   Konditionieren
+   ////////////////////////////////////////////////////////////////////////////////////
+   // Z - Dir
+   LBMReal m0 =  mfaac * c1o2 +      mfaab * (vx3 - c1o2) + (mfaaa + one * oMdrho) * (vx3Sq - vx3) * c1o2;
+   LBMReal m1 = -mfaac        - two * mfaab *  vx3         +  mfaaa                * (one - vx3Sq)              - one * oMdrho * vx3Sq;
+   LBMReal m2 =  mfaac * c1o2 +      mfaab * (vx3 + c1o2) + (mfaaa + one * oMdrho) * (vx3Sq + vx3) * c1o2;
+   mfaaa = m0;
+   mfaab = m1;
+   mfaac = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   m0 =  mfabc * c1o2 +      mfabb * (vx3 - c1o2) + mfaba * (vx3Sq - vx3) * c1o2;
+   m1 = -mfabc        - two * mfabb *  vx3         + mfaba * (one - vx3Sq);
+   m2 =  mfabc * c1o2 +      mfabb * (vx3 + c1o2) + mfaba * (vx3Sq + vx3) * c1o2;
+   mfaba = m0;
+   mfabb = m1;
+   mfabc = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   m0 =  mfacc * c1o2 +      mfacb * (vx3 - c1o2) + (mfaca + c1o3 * oMdrho) * (vx3Sq - vx3) * c1o2;
+   m1 = -mfacc        - two * mfacb *  vx3         +  mfaca                  * (one - vx3Sq)              - c1o3 * oMdrho * vx3Sq;
+   m2 =  mfacc * c1o2 +      mfacb * (vx3 + c1o2) + (mfaca + c1o3 * oMdrho) * (vx3Sq + vx3) * c1o2;
+   mfaca = m0;
+   mfacb = m1;
+   mfacc = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   ////////////////////////////////////////////////////////////////////////////////////
+   m0 =  mfbac * c1o2 +      mfbab * (vx3 - c1o2) + mfbaa * (vx3Sq - vx3) * c1o2;
+   m1 = -mfbac        - two * mfbab *  vx3         + mfbaa * (one - vx3Sq);
+   m2 =  mfbac * c1o2 +      mfbab * (vx3 + c1o2) + mfbaa * (vx3Sq + vx3) * c1o2;
+   mfbaa = m0;
+   mfbab = m1;
+   mfbac = m2;
+   /////////b//////////////////////////////////////////////////////////////////////////
+   m0 =  mfbbc * c1o2 +      mfbbb * (vx3 - c1o2) + mfbba * (vx3Sq - vx3) * c1o2;
+   m1 = -mfbbc        - two * mfbbb *  vx3         + mfbba * (one - vx3Sq);
+   m2 =  mfbbc * c1o2 +      mfbbb * (vx3 + c1o2) + mfbba * (vx3Sq + vx3) * c1o2;
+   mfbba = m0;
+   mfbbb = m1;
+   mfbbc = m2;
+   /////////b//////////////////////////////////////////////////////////////////////////
+   m0 =  mfbcc * c1o2 +      mfbcb * (vx3 - c1o2) + mfbca * (vx3Sq - vx3) * c1o2;
+   m1 = -mfbcc        - two * mfbcb *  vx3         + mfbca * (one - vx3Sq);
+   m2 =  mfbcc * c1o2 +      mfbcb * (vx3 + c1o2) + mfbca * (vx3Sq + vx3) * c1o2;
+   mfbca = m0;
+   mfbcb = m1;
+   mfbcc = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   ////////////////////////////////////////////////////////////////////////////////////
+   m0 =  mfcac * c1o2 +      mfcab * (vx3 - c1o2) + (mfcaa + c1o3 * oMdrho) * (vx3Sq - vx3) * c1o2;
+   m1 = -mfcac        - two * mfcab *  vx3         +  mfcaa                  * (one - vx3Sq)              - c1o3 * oMdrho * vx3Sq;
+   m2 =  mfcac * c1o2 +      mfcab * (vx3 + c1o2) + (mfcaa + c1o3 * oMdrho) * (vx3Sq + vx3) * c1o2;
+   mfcaa = m0;
+   mfcab = m1;
+   mfcac = m2;
+   /////////c//////////////////////////////////////////////////////////////////////////
+   m0 =  mfcbc * c1o2 +      mfcbb * (vx3 - c1o2) + mfcba * (vx3Sq - vx3) * c1o2;
+   m1 = -mfcbc        - two * mfcbb *  vx3         + mfcba * (one - vx3Sq);
+   m2 =  mfcbc * c1o2 +      mfcbb * (vx3 + c1o2) + mfcba * (vx3Sq + vx3) * c1o2;
+   mfcba = m0;
+   mfcbb = m1;
+   mfcbc = m2;
+   /////////c//////////////////////////////////////////////////////////////////////////
+   m0 =  mfccc * c1o2 +      mfccb * (vx3 - c1o2) + (mfcca + c1o9 * oMdrho) * (vx3Sq - vx3) * c1o2;
+   m1 = -mfccc        - two * mfccb *  vx3         +  mfcca                  * (one - vx3Sq)              - c1o9 * oMdrho * vx3Sq;
+   m2 =  mfccc * c1o2 +      mfccb * (vx3 + c1o2) + (mfcca + c1o9 * oMdrho) * (vx3Sq + vx3) * c1o2;
+   mfcca = m0;
+   mfccb = m1;
+   mfccc = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   ////////////////////////////////////////////////////////////////////////////////////
+   //mit 1/6, 2/3, 1/6, 0, 0, 0, 1/18, 2/9, 1/18   Konditionieren
+   ////////////////////////////////////////////////////////////////////////////////////
+   // Y - Dir
+   m0 =  mfaca * c1o2 +      mfaba * (vx2 - c1o2) + (mfaaa + c1o6 * oMdrho) * (vx2Sq - vx2) * c1o2;
+   m1 = -mfaca        - two * mfaba *  vx2         +  mfaaa                  * (one - vx2Sq)              - c1o6 * oMdrho * vx2Sq;
+   m2 =  mfaca * c1o2 +      mfaba * (vx2 + c1o2) + (mfaaa + c1o6 * oMdrho) * (vx2Sq + vx2) * c1o2;
+   mfaaa = m0;
+   mfaba = m1;
+   mfaca = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   m0 =  mfacb * c1o2 +      mfabb * (vx2 - c1o2) + (mfaab + c2o3 * oMdrho) * (vx2Sq - vx2) * c1o2;
+   m1 = -mfacb        - two * mfabb *  vx2         +  mfaab                  * (one - vx2Sq)              - c2o3 * oMdrho * vx2Sq;
+   m2 =  mfacb * c1o2 +      mfabb * (vx2 + c1o2) + (mfaab + c2o3 * oMdrho) * (vx2Sq + vx2) * c1o2;
+   mfaab = m0;
+   mfabb = m1;
+   mfacb = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   m0 =  mfacc * c1o2 +      mfabc * (vx2 - c1o2) + (mfaac + c1o6 * oMdrho) * (vx2Sq - vx2) * c1o2;
+   m1 = -mfacc        - two * mfabc *  vx2         +  mfaac                  * (one - vx2Sq)              - c1o6 * oMdrho * vx2Sq;
+   m2 =  mfacc * c1o2 +      mfabc * (vx2 + c1o2) + (mfaac + c1o6 * oMdrho) * (vx2Sq + vx2) * c1o2;
+   mfaac = m0;
+   mfabc = m1;
+   mfacc = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   ////////////////////////////////////////////////////////////////////////////////////
+   m0 =  mfbca * c1o2 +      mfbba * (vx2 - c1o2) + mfbaa * (vx2Sq - vx2) * c1o2;
+   m1 = -mfbca        - two * mfbba *  vx2         + mfbaa * (one - vx2Sq);
+   m2 =  mfbca * c1o2 +      mfbba * (vx2 + c1o2) + mfbaa * (vx2Sq + vx2) * c1o2;
+   mfbaa = m0;
+   mfbba = m1;
+   mfbca = m2;
+   /////////b//////////////////////////////////////////////////////////////////////////
+   m0 =  mfbcb * c1o2 +      mfbbb * (vx2 - c1o2) + mfbab * (vx2Sq - vx2) * c1o2;
+   m1 = -mfbcb        - two * mfbbb *  vx2         + mfbab * (one - vx2Sq);
+   m2 =  mfbcb * c1o2 +      mfbbb * (vx2 + c1o2) + mfbab * (vx2Sq + vx2) * c1o2;
+   mfbab = m0;
+   mfbbb = m1;
+   mfbcb = m2;
+   /////////b//////////////////////////////////////////////////////////////////////////
+   m0 =  mfbcc * c1o2 +      mfbbc * (vx2 - c1o2) + mfbac * (vx2Sq - vx2) * c1o2;
+   m1 = -mfbcc        - two * mfbbc *  vx2         + mfbac * (one - vx2Sq);
+   m2 =  mfbcc * c1o2 +      mfbbc * (vx2 + c1o2) + mfbac * (vx2Sq + vx2) * c1o2;
+   mfbac = m0;
+   mfbbc = m1;
+   mfbcc = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   ////////////////////////////////////////////////////////////////////////////////////
+   m0 =  mfcca * c1o2 +      mfcba * (vx2 - c1o2) + (mfcaa + c1o18 * oMdrho) * (vx2Sq - vx2) * c1o2;
+   m1 = -mfcca        - two * mfcba *  vx2         +  mfcaa                   * (one - vx2Sq)              - c1o18 * oMdrho * vx2Sq;
+   m2 =  mfcca * c1o2 +      mfcba * (vx2 + c1o2) + (mfcaa + c1o18 * oMdrho) * (vx2Sq + vx2) * c1o2;
+   mfcaa = m0;
+   mfcba = m1;
+   mfcca = m2;
+   /////////c//////////////////////////////////////////////////////////////////////////
+   m0 =  mfccb * c1o2 +      mfcbb * (vx2 - c1o2) + (mfcab + c2o9 * oMdrho) * (vx2Sq - vx2) * c1o2;
+   m1 = -mfccb        - two * mfcbb *  vx2         +  mfcab                  * (one - vx2Sq)              - c2o9 * oMdrho * vx2Sq;
+   m2 =  mfccb * c1o2 +      mfcbb * (vx2 + c1o2) + (mfcab + c2o9 * oMdrho) * (vx2Sq + vx2) * c1o2;
+   mfcab = m0;
+   mfcbb = m1;
+   mfccb = m2;
+   /////////c//////////////////////////////////////////////////////////////////////////
+   m0 =  mfccc * c1o2 +      mfcbc * (vx2 - c1o2) + (mfcac + c1o18 * oMdrho) * (vx2Sq - vx2) * c1o2;
+   m1 = -mfccc        - two * mfcbc *  vx2         +  mfcac                   * (one - vx2Sq)              - c1o18 * oMdrho * vx2Sq;
+   m2 =  mfccc * c1o2 +      mfcbc * (vx2 + c1o2) + (mfcac + c1o18 * oMdrho) * (vx2Sq + vx2) * c1o2;
+   mfcac = m0;
+   mfcbc = m1;
+   mfccc = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   ////////////////////////////////////////////////////////////////////////////////////
+   //mit 1/36, 1/9, 1/36, 1/9, 4/9, 1/9, 1/36, 1/9, 1/36 Konditionieren
+   ////////////////////////////////////////////////////////////////////////////////////
+   // X - Dir
+   m0 =  mfcaa * c1o2 +      mfbaa * (vx1 - c1o2) + (mfaaa + c1o36 * oMdrho) * (vx1Sq - vx1) * c1o2;
+   m1 = -mfcaa        - two * mfbaa *  vx1         +  mfaaa                   * (one - vx1Sq)              - c1o36 * oMdrho * vx1Sq;
+   m2 =  mfcaa * c1o2 +      mfbaa * (vx1 + c1o2) + (mfaaa + c1o36 * oMdrho) * (vx1Sq + vx1) * c1o2;
+   mfaaa = m0;
+   mfbaa = m1;
+   mfcaa = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   m0 =  mfcba * c1o2 +      mfbba * (vx1 - c1o2) + (mfaba + c1o9 * oMdrho) * (vx1Sq - vx1) * c1o2;
+   m1 = -mfcba        - two * mfbba *  vx1         +  mfaba                  * (one - vx1Sq)              - c1o9 * oMdrho * vx1Sq;
+   m2 =  mfcba * c1o2 +      mfbba * (vx1 + c1o2) + (mfaba + c1o9 * oMdrho) * (vx1Sq + vx1) * c1o2;
+   mfaba = m0;
+   mfbba = m1;
+   mfcba = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   m0 =  mfcca * c1o2 +      mfbca * (vx1 - c1o2) + (mfaca + c1o36 * oMdrho) * (vx1Sq - vx1) * c1o2;
+   m1 = -mfcca        - two * mfbca *  vx1         +  mfaca                   * (one - vx1Sq)              - c1o36 * oMdrho * vx1Sq;
+   m2 =  mfcca * c1o2 +      mfbca * (vx1 + c1o2) + (mfaca + c1o36 * oMdrho) * (vx1Sq + vx1) * c1o2;
+   mfaca = m0;
+   mfbca = m1;
+   mfcca = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   ////////////////////////////////////////////////////////////////////////////////////
+   m0 =  mfcab * c1o2 +      mfbab * (vx1 - c1o2) + (mfaab + c1o9 * oMdrho) * (vx1Sq - vx1) * c1o2;
+   m1 = -mfcab        - two * mfbab *  vx1         +  mfaab                  * (one - vx1Sq)              - c1o9 * oMdrho * vx1Sq;
+   m2 =  mfcab * c1o2 +      mfbab * (vx1 + c1o2) + (mfaab + c1o9 * oMdrho) * (vx1Sq + vx1) * c1o2;
+   mfaab = m0;
+   mfbab = m1;
+   mfcab = m2;
+   ///////////b////////////////////////////////////////////////////////////////////////
+   m0 =  mfcbb * c1o2 +      mfbbb * (vx1 - c1o2) + (mfabb + c4o9 * oMdrho) * (vx1Sq - vx1) * c1o2;
+   m1 = -mfcbb        - two * mfbbb *  vx1         +  mfabb                  * (one - vx1Sq)              - c4o9 * oMdrho * vx1Sq;
+   m2 =  mfcbb * c1o2 +      mfbbb * (vx1 + c1o2) + (mfabb + c4o9 * oMdrho) * (vx1Sq + vx1) * c1o2;
+   mfabb = m0;
+   mfbbb = m1;
+   mfcbb = m2;
+   ///////////b////////////////////////////////////////////////////////////////////////
+   m0 =  mfccb * c1o2 +      mfbcb * (vx1 - c1o2) + (mfacb + c1o9 * oMdrho) * (vx1Sq - vx1) * c1o2;
+   m1 = -mfccb        - two * mfbcb *  vx1         +  mfacb                  * (one - vx1Sq)              - c1o9 * oMdrho * vx1Sq;
+   m2 =  mfccb * c1o2 +      mfbcb * (vx1 + c1o2) + (mfacb + c1o9 * oMdrho) * (vx1Sq + vx1) * c1o2;
+   mfacb = m0;
+   mfbcb = m1;
+   mfccb = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   ////////////////////////////////////////////////////////////////////////////////////
+   m0 =  mfcac * c1o2 +      mfbac * (vx1 - c1o2) + (mfaac + c1o36 * oMdrho) * (vx1Sq - vx1) * c1o2;
+   m1 = -mfcac        - two * mfbac *  vx1         +  mfaac                   * (one - vx1Sq)              - c1o36 * oMdrho * vx1Sq;
+   m2 =  mfcac * c1o2 +      mfbac * (vx1 + c1o2) + (mfaac + c1o36 * oMdrho) * (vx1Sq + vx1) * c1o2;
+   mfaac = m0;
+   mfbac = m1;
+   mfcac = m2;
+   ///////////c////////////////////////////////////////////////////////////////////////
+   m0 =  mfcbc * c1o2 +      mfbbc * (vx1 - c1o2) + (mfabc + c1o9 * oMdrho) * (vx1Sq - vx1) * c1o2;
+   m1 = -mfcbc        - two * mfbbc *  vx1         +  mfabc                  * (one - vx1Sq)              - c1o9 * oMdrho * vx1Sq;
+   m2 =  mfcbc * c1o2 +      mfbbc * (vx1 + c1o2) + (mfabc + c1o9 * oMdrho) * (vx1Sq + vx1) * c1o2;
+   mfabc = m0;
+   mfbbc = m1;
+   mfcbc = m2;
+   ///////////c////////////////////////////////////////////////////////////////////////
+   m0 =  mfccc * c1o2 +      mfbcc * (vx1 - c1o2) + (mfacc + c1o36 * oMdrho) * (vx1Sq - vx1) * c1o2;
+   m1 = -mfccc        - two * mfbcc *  vx1         +  mfacc                   * (one - vx1Sq)              - c1o36 * oMdrho * vx1Sq;
+   m2 =  mfccc * c1o2 +      mfbcc * (vx1 + c1o2) + (mfacc + c1o36 * oMdrho) * (vx1Sq + vx1) * c1o2;
+   mfacc = m0;
+   mfbcc = m1;
+   mfccc = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+
+   f[E]    = mfcbb;
+   f[W]    = mfabb;
+   f[N]    = mfbcb;
+   f[S]    = mfbab;
+   f[T]    = mfbbc;
+   f[B]    = mfbba;
+   f[NE]   = mfccb;
+   f[SW]   = mfaab;
+   f[SE]   = mfcab;
+   f[NW]   = mfacb;
+   f[TE]   = mfcbc;
+   f[BW]   = mfaba;
+   f[BE]   = mfcba;
+   f[TW]   = mfabc;
+   f[TN]   = mfbcc;
+   f[BS]   = mfbaa;
+   f[BN]   = mfbca;
+   f[TS]   = mfbac;
+   f[ZERO] = mfbbb;
+   f[TNE]  = mfccc;
+   f[TSE]  = mfcac;
+   f[BNE]  = mfcca;
+   f[BSE]  = mfcaa;
+   f[TNW]  = mfacc;
+   f[TSW]  = mfaac;
+   f[BNW]  = mfaca;
+   f[BSW]  = mfaaa;
+}
+//////////////////////////////////////////////////////////////////////////
+//Position SWB -0.25, -0.25, -0.25
+LBMReal CompressibleOffsetMomentsInterpolationProcessor::calcPressBSW()
+{
+   return   press_SWT * (0.140625 + 0.1875 * xoff + 0.1875 * yoff - 0.5625 * zoff) +
+      press_NWT * (0.046875 + 0.0625 * xoff - 0.1875 * yoff - 0.1875 * zoff) +
+      press_SET * (0.046875 - 0.1875 * xoff + 0.0625 * yoff - 0.1875 * zoff) +
+      press_NET * (0.015625 - 0.0625 * xoff - 0.0625 * yoff - 0.0625 * zoff) +
+      press_NEB * (0.046875 - 0.1875 * xoff - 0.1875 * yoff + 0.0625 * zoff) +
+      press_NWB * (0.140625 + 0.1875 * xoff - 0.5625 * yoff + 0.1875 * zoff) +
+      press_SEB * (0.140625 - 0.5625 * xoff + 0.1875 * yoff + 0.1875 * zoff) +
+      press_SWB * (0.421875 + 0.5625 * xoff + 0.5625 * yoff + 0.5625 * zoff);
+}
+//////////////////////////////////////////////////////////////////////////
+//Position SWT -0.25, -0.25, 0.25
+LBMReal CompressibleOffsetMomentsInterpolationProcessor::calcPressTSW()
+{
+   return   press_SWT * (0.421875 + 0.5625 * xoff + 0.5625 * yoff - 0.5625 * zoff) +
+      press_NWT * (0.140625 + 0.1875 * xoff - 0.5625 * yoff - 0.1875 * zoff) +
+      press_SET * (0.140625 - 0.5625 * xoff + 0.1875 * yoff - 0.1875 * zoff) +
+      press_NET * (0.046875 - 0.1875 * xoff - 0.1875 * yoff - 0.0625 * zoff) +
+      press_NEB * (0.015625 - 0.0625 * xoff - 0.0625 * yoff + 0.0625 * zoff) +
+      press_NWB * (0.046875 + 0.0625 * xoff - 0.1875 * yoff + 0.1875 * zoff) +
+      press_SEB * (0.046875 - 0.1875 * xoff + 0.0625 * yoff + 0.1875 * zoff) +
+      press_SWB * (0.140625 + 0.1875 * xoff + 0.1875 * yoff + 0.5625 * zoff);
+}
+//////////////////////////////////////////////////////////////////////////
+//Position SET 0.25, -0.25, 0.25
+LBMReal CompressibleOffsetMomentsInterpolationProcessor::calcPressTSE()
+{
+   return   press_SET * (0.421875 - 0.5625 * xoff + 0.5625 * yoff - 0.5625 * zoff) +
+      press_NET * (0.140625 - 0.1875 * xoff - 0.5625 * yoff - 0.1875 * zoff) +
+      press_SWT * (0.140625 + 0.5625 * xoff + 0.1875 * yoff - 0.1875 * zoff) +
+      press_NWT * (0.046875 + 0.1875 * xoff - 0.1875 * yoff - 0.0625 * zoff) +
+      press_NWB * (0.015625 + 0.0625 * xoff - 0.0625 * yoff + 0.0625 * zoff) +
+      press_NEB * (0.046875 - 0.0625 * xoff - 0.1875 * yoff + 0.1875 * zoff) +
+      press_SWB * (0.046875 + 0.1875 * xoff + 0.0625 * yoff + 0.1875 * zoff) +
+      press_SEB * (0.140625 - 0.1875 * xoff + 0.1875 * yoff + 0.5625 * zoff);
+}
+//////////////////////////////////////////////////////////////////////////
+//Position SEB 0.25, -0.25, -0.25
+LBMReal CompressibleOffsetMomentsInterpolationProcessor::calcPressBSE()
+{
+   return   press_SET * (0.140625 - 0.1875 * xoff + 0.1875 * yoff - 0.5625 * zoff) +
+      press_NET * (0.046875 - 0.0625 * xoff - 0.1875 * yoff - 0.1875 * zoff) +
+      press_SWT * (0.046875 + 0.1875 * xoff + 0.0625 * yoff - 0.1875 * zoff) +
+      press_NWT * (0.015625 + 0.0625 * xoff - 0.0625 * yoff - 0.0625 * zoff) +
+      press_NWB * (0.046875 + 0.1875 * xoff - 0.1875 * yoff + 0.0625 * zoff) +
+      press_NEB * (0.140625 - 0.1875 * xoff - 0.5625 * yoff + 0.1875 * zoff) +
+      press_SWB * (0.140625 + 0.5625 * xoff + 0.1875 * yoff + 0.1875 * zoff) +
+      press_SEB * (0.421875 - 0.5625 * xoff + 0.5625 * yoff + 0.5625 * zoff);
+}
+//////////////////////////////////////////////////////////////////////////
+//Position NWB -0.25, 0.25, -0.25
+LBMReal CompressibleOffsetMomentsInterpolationProcessor::calcPressBNW()
+{
+   return   press_NWT * (0.140625 + 0.1875 * xoff - 0.1875 * yoff - 0.5625 * zoff) +
+      press_NET * (0.046875 - 0.1875 * xoff - 0.0625 * yoff - 0.1875 * zoff) +
+      press_SWT * (0.046875 + 0.0625 * xoff + 0.1875 * yoff - 0.1875 * zoff) +
+      press_SET * (0.015625 - 0.0625 * xoff + 0.0625 * yoff - 0.0625 * zoff) +
+      press_SEB * (0.046875 - 0.1875 * xoff + 0.1875 * yoff + 0.0625 * zoff) +
+      press_NEB * (0.140625 - 0.5625 * xoff - 0.1875 * yoff + 0.1875 * zoff) +
+      press_SWB * (0.140625 + 0.1875 * xoff + 0.5625 * yoff + 0.1875 * zoff) +
+      press_NWB * (0.421875 + 0.5625 * xoff - 0.5625 * yoff + 0.5625 * zoff);
+}
+//////////////////////////////////////////////////////////////////////////
+//Position NWT -0.25, 0.25, 0.25
+LBMReal CompressibleOffsetMomentsInterpolationProcessor::calcPressTNW()
+{
+   return   press_NWT * (0.421875 + 0.5625 * xoff - 0.5625 * yoff - 0.5625 * zoff) +
+      press_NET * (0.140625 - 0.5625 * xoff - 0.1875 * yoff - 0.1875 * zoff) +
+      press_SWT * (0.140625 + 0.1875 * xoff + 0.5625 * yoff - 0.1875 * zoff) +
+      press_SET * (0.046875 - 0.1875 * xoff + 0.1875 * yoff - 0.0625 * zoff) +
+      press_SEB * (0.015625 - 0.0625 * xoff + 0.0625 * yoff + 0.0625 * zoff) +
+      press_NEB * (0.046875 - 0.1875 * xoff - 0.0625 * yoff + 0.1875 * zoff) +
+      press_SWB * (0.046875 + 0.0625 * xoff + 0.1875 * yoff + 0.1875 * zoff) +
+      press_NWB * (0.140625 + 0.1875 * xoff - 0.1875 * yoff + 0.5625 * zoff);
+}
+//////////////////////////////////////////////////////////////////////////
+//Position NET 0.25, 0.25, 0.25
+LBMReal CompressibleOffsetMomentsInterpolationProcessor::calcPressTNE()
+{
+   return   press_NET * (0.421875 - 0.5625 * xoff - 0.5625 * yoff - 0.5625 * zoff) +
+      press_NWT * (0.140625 + 0.5625 * xoff - 0.1875 * yoff - 0.1875 * zoff) +
+      press_SET * (0.140625 - 0.1875 * xoff + 0.5625 * yoff - 0.1875 * zoff) +
+      press_SWT * (0.046875 + 0.1875 * xoff + 0.1875 * yoff - 0.0625 * zoff) +
+      press_SWB * (0.015625 + 0.0625 * xoff + 0.0625 * yoff + 0.0625 * zoff) +
+      press_NWB * (0.046875 + 0.1875 * xoff - 0.0625 * yoff + 0.1875 * zoff) +
+      press_SEB * (0.046875 - 0.0625 * xoff + 0.1875 * yoff + 0.1875 * zoff) +
+      press_NEB * (0.140625 - 0.1875 * xoff - 0.1875 * yoff + 0.5625 * zoff);
+}
+//////////////////////////////////////////////////////////////////////////
+//Position NEB 0.25, 0.25, -0.25
+LBMReal CompressibleOffsetMomentsInterpolationProcessor::calcPressBNE()
+{
+   return   press_NET * (0.140625 - 0.1875 * xoff - 0.1875 * yoff - 0.5625 * zoff) +
+      press_NWT * (0.046875 + 0.1875 * xoff - 0.0625 * yoff - 0.1875 * zoff) +
+      press_SET * (0.046875 - 0.0625 * xoff + 0.1875 * yoff - 0.1875 * zoff) +
+      press_SWT * (0.015625 + 0.0625 * xoff + 0.0625 * yoff - 0.0625 * zoff) +
+      press_SWB * (0.046875 + 0.1875 * xoff + 0.1875 * yoff + 0.0625 * zoff) +
+      press_NWB * (0.140625 + 0.5625 * xoff - 0.1875 * yoff + 0.1875 * zoff) +
+      press_SEB * (0.140625 - 0.1875 * xoff + 0.5625 * yoff + 0.1875 * zoff) +
+      press_NEB * (0.421875 - 0.5625 * xoff - 0.5625 * yoff + 0.5625 * zoff);
+}
+//////////////////////////////////////////////////////////////////////////
+//Position C 0.0, 0.0, 0.0
+void CompressibleOffsetMomentsInterpolationProcessor::calcInterpolatedNodeFC(LBMReal* f, LBMReal omega)
+{
+   using namespace D3Q27System;
+
+   LBMReal press  =  press_NET * (0.125 - 0.25 * xoff - 0.25 * yoff - 0.25 * zoff) +
+      press_NWT * (0.125 + 0.25 * xoff - 0.25 * yoff - 0.25 * zoff) +
+      press_SET * (0.125 - 0.25 * xoff + 0.25 * yoff - 0.25 * zoff) +
+      press_SWT * (0.125 + 0.25 * xoff + 0.25 * yoff - 0.25 * zoff) +
+      press_NEB * (0.125 - 0.25 * xoff - 0.25 * yoff + 0.25 * zoff) +
+      press_NWB * (0.125 + 0.25 * xoff - 0.25 * yoff + 0.25 * zoff) +
+      press_SEB * (0.125 - 0.25 * xoff + 0.25 * yoff + 0.25 * zoff) +
+      press_SWB * (0.125 + 0.25 * xoff + 0.25 * yoff + 0.25 * zoff);
+   LBMReal vx1  = a0;
+   LBMReal vx2  = b0;
+   LBMReal vx3  = c0;
+
+   LBMReal rho = press ;//+ (ax+by+cz)/3.;
+
+   LBMReal eps_new = 2.;
+   LBMReal o  = omega;
+   //bulk viscosity
+   LBMReal oP = OxxPyyPzzC;
+
+   LBMReal mfcbb = zeroReal;
+   LBMReal mfabb = zeroReal;
+   LBMReal mfbcb = zeroReal;
+   LBMReal mfbab = zeroReal;
+   LBMReal mfbbc = zeroReal;
+   LBMReal mfbba = zeroReal;
+   LBMReal mfccb = zeroReal;
+   LBMReal mfaab = zeroReal;
+   LBMReal mfcab = zeroReal;
+   LBMReal mfacb = zeroReal;
+   LBMReal mfcbc = zeroReal;
+   LBMReal mfaba = zeroReal;
+   LBMReal mfcba = zeroReal;
+   LBMReal mfabc = zeroReal;
+   LBMReal mfbcc = zeroReal;
+   LBMReal mfbaa = zeroReal;
+   LBMReal mfbca = zeroReal;
+   LBMReal mfbac = zeroReal;
+   LBMReal mfbbb = zeroReal;
+   LBMReal mfccc = zeroReal;
+   LBMReal mfaac = zeroReal;
+   LBMReal mfcac = zeroReal;
+   LBMReal mfacc = zeroReal;
+   LBMReal mfcca = zeroReal;
+   LBMReal mfaaa = zeroReal;
+   LBMReal mfcaa = zeroReal;
+   LBMReal mfaca = zeroReal;
+
+   mfaaa = press; // if drho is interpolated directly
+
+   LBMReal vx1Sq = vx1*vx1;
+   LBMReal vx2Sq = vx2*vx2;
+   LBMReal vx3Sq = vx3*vx3;
+   LBMReal oMdrho = one;
+   //oMdrho = one - mfaaa;
+
+   //2.f
+   // linear combinations
+
+/////////////////////////
+   LBMReal mxxPyyPzz = mfaaa    -c2o3*(ax+by+cz)*eps_new/oP*(one+press);
+
+   LBMReal mxxMyy    = -c2o3*((ax - by)+kxxMyyAverage)*eps_new/o * (one + press);
+   LBMReal mxxMzz    = -c2o3*((ax - cz)+kxxMzzAverage)*eps_new/o * (one + press);
+
+   mfabb     = -c1o3 * ((bz + cy)+kyzAverage)*eps_new/o * (one + press);
+   mfbab     = -c1o3 * ((az + cx)+kxzAverage)*eps_new/o * (one + press);
+   mfbba     = -c1o3 * ((ay + bx)+kxyAverage)*eps_new/o * (one + press);
+
+   ////////////////////////
+   // linear combinations back
+   mfcaa = c1o3 * (mxxMyy +       mxxMzz + mxxPyyPzz);
+   mfaca = c1o3 * (-two * mxxMyy +       mxxMzz + mxxPyyPzz);
+   mfaac = c1o3 * (mxxMyy - two * mxxMzz + mxxPyyPzz);
+
+   //three
+   mfbbb = zeroReal;
+
+   LBMReal mxxyPyzz = zeroReal;
+   LBMReal mxxyMyzz = zeroReal;
+   LBMReal mxxzPyyz = zeroReal;
+   LBMReal mxxzMyyz = zeroReal;
+   LBMReal mxyyPxzz =  zeroReal;
+   LBMReal mxyyMxzz = zeroReal;
+
+   // linear combinations back
+   mfcba = (mxxyMyzz + mxxyPyzz) * c1o2;
+   mfabc = (-mxxyMyzz + mxxyPyzz) * c1o2;
+   mfcab = (mxxzMyyz + mxxzPyyz) * c1o2;
+   mfacb = (-mxxzMyyz + mxxzPyyz) * c1o2;
+   mfbca = (mxyyMxzz + mxyyPxzz) * c1o2;
+   mfbac = (-mxyyMxzz + mxyyPxzz) * c1o2;
+
+   //4.f
+   mfacc = mfaaa*c1o9;
+   mfcac = mfacc;
+   mfcca = mfacc;
+   //5.
+
+   //6.
+   mfccc = mfaaa*c1o27;
+   ////////////////////////////////////////////////////////////////////////////////////
+   //back
+   ////////////////////////////////////////////////////////////////////////////////////
+   //mit 1, 0, 1/3, 0, 0, 0, 1/3, 0, 1/9   Konditionieren
+   ////////////////////////////////////////////////////////////////////////////////////
+   // Z - Dir
+   LBMReal m0 =  mfaac * c1o2 +      mfaab * (vx3 - c1o2) + (mfaaa + one * oMdrho) * (vx3Sq - vx3) * c1o2;
+   LBMReal m1 = -mfaac        - two * mfaab *  vx3         +  mfaaa                * (one - vx3Sq)              - one * oMdrho * vx3Sq;
+   LBMReal m2 =  mfaac * c1o2 +      mfaab * (vx3 + c1o2) + (mfaaa + one * oMdrho) * (vx3Sq + vx3) * c1o2;
+   mfaaa = m0;
+   mfaab = m1;
+   mfaac = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   m0 =  mfabc * c1o2 +      mfabb * (vx3 - c1o2) + mfaba * (vx3Sq - vx3) * c1o2;
+   m1 = -mfabc        - two * mfabb *  vx3         + mfaba * (one - vx3Sq);
+   m2 =  mfabc * c1o2 +      mfabb * (vx3 + c1o2) + mfaba * (vx3Sq + vx3) * c1o2;
+   mfaba = m0;
+   mfabb = m1;
+   mfabc = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   m0 =  mfacc * c1o2 +      mfacb * (vx3 - c1o2) + (mfaca + c1o3 * oMdrho) * (vx3Sq - vx3) * c1o2;
+   m1 = -mfacc        - two * mfacb *  vx3         +  mfaca                  * (one - vx3Sq)              - c1o3 * oMdrho * vx3Sq;
+   m2 =  mfacc * c1o2 +      mfacb * (vx3 + c1o2) + (mfaca + c1o3 * oMdrho) * (vx3Sq + vx3) * c1o2;
+   mfaca = m0;
+   mfacb = m1;
+   mfacc = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   ////////////////////////////////////////////////////////////////////////////////////
+   m0 =  mfbac * c1o2 +      mfbab * (vx3 - c1o2) + mfbaa * (vx3Sq - vx3) * c1o2;
+   m1 = -mfbac        - two * mfbab *  vx3         + mfbaa * (one - vx3Sq);
+   m2 =  mfbac * c1o2 +      mfbab * (vx3 + c1o2) + mfbaa * (vx3Sq + vx3) * c1o2;
+   mfbaa = m0;
+   mfbab = m1;
+   mfbac = m2;
+   /////////b//////////////////////////////////////////////////////////////////////////
+   m0 =  mfbbc * c1o2 +      mfbbb * (vx3 - c1o2) + mfbba * (vx3Sq - vx3) * c1o2;
+   m1 = -mfbbc        - two * mfbbb *  vx3         + mfbba * (one - vx3Sq);
+   m2 =  mfbbc * c1o2 +      mfbbb * (vx3 + c1o2) + mfbba * (vx3Sq + vx3) * c1o2;
+   mfbba = m0;
+   mfbbb = m1;
+   mfbbc = m2;
+   /////////b//////////////////////////////////////////////////////////////////////////
+   m0 =  mfbcc * c1o2 +      mfbcb * (vx3 - c1o2) + mfbca * (vx3Sq - vx3) * c1o2;
+   m1 = -mfbcc        - two * mfbcb *  vx3         + mfbca * (one - vx3Sq);
+   m2 =  mfbcc * c1o2 +      mfbcb * (vx3 + c1o2) + mfbca * (vx3Sq + vx3) * c1o2;
+   mfbca = m0;
+   mfbcb = m1;
+   mfbcc = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   ////////////////////////////////////////////////////////////////////////////////////
+   m0 =  mfcac * c1o2 +      mfcab * (vx3 - c1o2) + (mfcaa + c1o3 * oMdrho) * (vx3Sq - vx3) * c1o2;
+   m1 = -mfcac        - two * mfcab *  vx3         +  mfcaa                  * (one - vx3Sq)              - c1o3 * oMdrho * vx3Sq;
+   m2 =  mfcac * c1o2 +      mfcab * (vx3 + c1o2) + (mfcaa + c1o3 * oMdrho) * (vx3Sq + vx3) * c1o2;
+   mfcaa = m0;
+   mfcab = m1;
+   mfcac = m2;
+   /////////c//////////////////////////////////////////////////////////////////////////
+   m0 =  mfcbc * c1o2 +      mfcbb * (vx3 - c1o2) + mfcba * (vx3Sq - vx3) * c1o2;
+   m1 = -mfcbc        - two * mfcbb *  vx3         + mfcba * (one - vx3Sq);
+   m2 =  mfcbc * c1o2 +      mfcbb * (vx3 + c1o2) + mfcba * (vx3Sq + vx3) * c1o2;
+   mfcba = m0;
+   mfcbb = m1;
+   mfcbc = m2;
+   /////////c//////////////////////////////////////////////////////////////////////////
+   m0 =  mfccc * c1o2 +      mfccb * (vx3 - c1o2) + (mfcca + c1o9 * oMdrho) * (vx3Sq - vx3) * c1o2;
+   m1 = -mfccc        - two * mfccb *  vx3         +  mfcca                  * (one - vx3Sq)              - c1o9 * oMdrho * vx3Sq;
+   m2 =  mfccc * c1o2 +      mfccb * (vx3 + c1o2) + (mfcca + c1o9 * oMdrho) * (vx3Sq + vx3) * c1o2;
+   mfcca = m0;
+   mfccb = m1;
+   mfccc = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   ////////////////////////////////////////////////////////////////////////////////////
+   //mit 1/6, 2/3, 1/6, 0, 0, 0, 1/18, 2/9, 1/18   Konditionieren
+   ////////////////////////////////////////////////////////////////////////////////////
+   // Y - Dir
+   m0 =  mfaca * c1o2 +      mfaba * (vx2 - c1o2) + (mfaaa + c1o6 * oMdrho) * (vx2Sq - vx2) * c1o2;
+   m1 = -mfaca        - two * mfaba *  vx2         +  mfaaa                  * (one - vx2Sq)              - c1o6 * oMdrho * vx2Sq;
+   m2 =  mfaca * c1o2 +      mfaba * (vx2 + c1o2) + (mfaaa + c1o6 * oMdrho) * (vx2Sq + vx2) * c1o2;
+   mfaaa = m0;
+   mfaba = m1;
+   mfaca = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   m0 =  mfacb * c1o2 +      mfabb * (vx2 - c1o2) + (mfaab + c2o3 * oMdrho) * (vx2Sq - vx2) * c1o2;
+   m1 = -mfacb        - two * mfabb *  vx2         +  mfaab                  * (one - vx2Sq)              - c2o3 * oMdrho * vx2Sq;
+   m2 =  mfacb * c1o2 +      mfabb * (vx2 + c1o2) + (mfaab + c2o3 * oMdrho) * (vx2Sq + vx2) * c1o2;
+   mfaab = m0;
+   mfabb = m1;
+   mfacb = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   m0 =  mfacc * c1o2 +      mfabc * (vx2 - c1o2) + (mfaac + c1o6 * oMdrho) * (vx2Sq - vx2) * c1o2;
+   m1 = -mfacc        - two * mfabc *  vx2         +  mfaac                  * (one - vx2Sq)              - c1o6 * oMdrho * vx2Sq;
+   m2 =  mfacc * c1o2 +      mfabc * (vx2 + c1o2) + (mfaac + c1o6 * oMdrho) * (vx2Sq + vx2) * c1o2;
+   mfaac = m0;
+   mfabc = m1;
+   mfacc = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   ////////////////////////////////////////////////////////////////////////////////////
+   m0 =  mfbca * c1o2 +      mfbba * (vx2 - c1o2) + mfbaa * (vx2Sq - vx2) * c1o2;
+   m1 = -mfbca        - two * mfbba *  vx2         + mfbaa * (one - vx2Sq);
+   m2 =  mfbca * c1o2 +      mfbba * (vx2 + c1o2) + mfbaa * (vx2Sq + vx2) * c1o2;
+   mfbaa = m0;
+   mfbba = m1;
+   mfbca = m2;
+   /////////b//////////////////////////////////////////////////////////////////////////
+   m0 =  mfbcb * c1o2 +      mfbbb * (vx2 - c1o2) + mfbab * (vx2Sq - vx2) * c1o2;
+   m1 = -mfbcb        - two * mfbbb *  vx2         + mfbab * (one - vx2Sq);
+   m2 =  mfbcb * c1o2 +      mfbbb * (vx2 + c1o2) + mfbab * (vx2Sq + vx2) * c1o2;
+   mfbab = m0;
+   mfbbb = m1;
+   mfbcb = m2;
+   /////////b//////////////////////////////////////////////////////////////////////////
+   m0 =  mfbcc * c1o2 +      mfbbc * (vx2 - c1o2) + mfbac * (vx2Sq - vx2) * c1o2;
+   m1 = -mfbcc        - two * mfbbc *  vx2         + mfbac * (one - vx2Sq);
+   m2 =  mfbcc * c1o2 +      mfbbc * (vx2 + c1o2) + mfbac * (vx2Sq + vx2) * c1o2;
+   mfbac = m0;
+   mfbbc = m1;
+   mfbcc = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   ////////////////////////////////////////////////////////////////////////////////////
+   m0 =  mfcca * c1o2 +      mfcba * (vx2 - c1o2) + (mfcaa + c1o18 * oMdrho) * (vx2Sq - vx2) * c1o2;
+   m1 = -mfcca        - two * mfcba *  vx2         +  mfcaa                   * (one - vx2Sq)              - c1o18 * oMdrho * vx2Sq;
+   m2 =  mfcca * c1o2 +      mfcba * (vx2 + c1o2) + (mfcaa + c1o18 * oMdrho) * (vx2Sq + vx2) * c1o2;
+   mfcaa = m0;
+   mfcba = m1;
+   mfcca = m2;
+   /////////c//////////////////////////////////////////////////////////////////////////
+   m0 =  mfccb * c1o2 +      mfcbb * (vx2 - c1o2) + (mfcab + c2o9 * oMdrho) * (vx2Sq - vx2) * c1o2;
+   m1 = -mfccb        - two * mfcbb *  vx2         +  mfcab                  * (one - vx2Sq)              - c2o9 * oMdrho * vx2Sq;
+   m2 =  mfccb * c1o2 +      mfcbb * (vx2 + c1o2) + (mfcab + c2o9 * oMdrho) * (vx2Sq + vx2) * c1o2;
+   mfcab = m0;
+   mfcbb = m1;
+   mfccb = m2;
+   /////////c//////////////////////////////////////////////////////////////////////////
+   m0 =  mfccc * c1o2 +      mfcbc * (vx2 - c1o2) + (mfcac + c1o18 * oMdrho) * (vx2Sq - vx2) * c1o2;
+   m1 = -mfccc        - two * mfcbc *  vx2         +  mfcac                   * (one - vx2Sq)              - c1o18 * oMdrho * vx2Sq;
+   m2 =  mfccc * c1o2 +      mfcbc * (vx2 + c1o2) + (mfcac + c1o18 * oMdrho) * (vx2Sq + vx2) * c1o2;
+   mfcac = m0;
+   mfcbc = m1;
+   mfccc = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   ////////////////////////////////////////////////////////////////////////////////////
+   //mit 1/36, 1/9, 1/36, 1/9, 4/9, 1/9, 1/36, 1/9, 1/36 Konditionieren
+   ////////////////////////////////////////////////////////////////////////////////////
+   // X - Dir
+   m0 =  mfcaa * c1o2 +      mfbaa * (vx1 - c1o2) + (mfaaa + c1o36 * oMdrho) * (vx1Sq - vx1) * c1o2;
+   m1 = -mfcaa        - two * mfbaa *  vx1         +  mfaaa                   * (one - vx1Sq)              - c1o36 * oMdrho * vx1Sq;
+   m2 =  mfcaa * c1o2 +      mfbaa * (vx1 + c1o2) + (mfaaa + c1o36 * oMdrho) * (vx1Sq + vx1) * c1o2;
+   mfaaa = m0;
+   mfbaa = m1;
+   mfcaa = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   m0 =  mfcba * c1o2 +      mfbba * (vx1 - c1o2) + (mfaba + c1o9 * oMdrho) * (vx1Sq - vx1) * c1o2;
+   m1 = -mfcba        - two * mfbba *  vx1         +  mfaba                  * (one - vx1Sq)              - c1o9 * oMdrho * vx1Sq;
+   m2 =  mfcba * c1o2 +      mfbba * (vx1 + c1o2) + (mfaba + c1o9 * oMdrho) * (vx1Sq + vx1) * c1o2;
+   mfaba = m0;
+   mfbba = m1;
+   mfcba = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   m0 =  mfcca * c1o2 +      mfbca * (vx1 - c1o2) + (mfaca + c1o36 * oMdrho) * (vx1Sq - vx1) * c1o2;
+   m1 = -mfcca        - two * mfbca *  vx1         +  mfaca                   * (one - vx1Sq)              - c1o36 * oMdrho * vx1Sq;
+   m2 =  mfcca * c1o2 +      mfbca * (vx1 + c1o2) + (mfaca + c1o36 * oMdrho) * (vx1Sq + vx1) * c1o2;
+   mfaca = m0;
+   mfbca = m1;
+   mfcca = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   ////////////////////////////////////////////////////////////////////////////////////
+   m0 =  mfcab * c1o2 +      mfbab * (vx1 - c1o2) + (mfaab + c1o9 * oMdrho) * (vx1Sq - vx1) * c1o2;
+   m1 = -mfcab        - two * mfbab *  vx1         +  mfaab                  * (one - vx1Sq)              - c1o9 * oMdrho * vx1Sq;
+   m2 =  mfcab * c1o2 +      mfbab * (vx1 + c1o2) + (mfaab + c1o9 * oMdrho) * (vx1Sq + vx1) * c1o2;
+   mfaab = m0;
+   mfbab = m1;
+   mfcab = m2;
+   ///////////b////////////////////////////////////////////////////////////////////////
+   m0 =  mfcbb * c1o2 +      mfbbb * (vx1 - c1o2) + (mfabb + c4o9 * oMdrho) * (vx1Sq - vx1) * c1o2;
+   m1 = -mfcbb        - two * mfbbb *  vx1         +  mfabb                  * (one - vx1Sq)              - c4o9 * oMdrho * vx1Sq;
+   m2 =  mfcbb * c1o2 +      mfbbb * (vx1 + c1o2) + (mfabb + c4o9 * oMdrho) * (vx1Sq + vx1) * c1o2;
+   mfabb = m0;
+   mfbbb = m1;
+   mfcbb = m2;
+   ///////////b////////////////////////////////////////////////////////////////////////
+   m0 =  mfccb * c1o2 +      mfbcb * (vx1 - c1o2) + (mfacb + c1o9 * oMdrho) * (vx1Sq - vx1) * c1o2;
+   m1 = -mfccb        - two * mfbcb *  vx1         +  mfacb                  * (one - vx1Sq)              - c1o9 * oMdrho * vx1Sq;
+   m2 =  mfccb * c1o2 +      mfbcb * (vx1 + c1o2) + (mfacb + c1o9 * oMdrho) * (vx1Sq + vx1) * c1o2;
+   mfacb = m0;
+   mfbcb = m1;
+   mfccb = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+   ////////////////////////////////////////////////////////////////////////////////////
+   m0 =  mfcac * c1o2 +      mfbac * (vx1 - c1o2) + (mfaac + c1o36 * oMdrho) * (vx1Sq - vx1) * c1o2;
+   m1 = -mfcac        - two * mfbac *  vx1         +  mfaac                   * (one - vx1Sq)              - c1o36 * oMdrho * vx1Sq;
+   m2 =  mfcac * c1o2 +      mfbac * (vx1 + c1o2) + (mfaac + c1o36 * oMdrho) * (vx1Sq + vx1) * c1o2;
+   mfaac = m0;
+   mfbac = m1;
+   mfcac = m2;
+   ///////////c////////////////////////////////////////////////////////////////////////
+   m0 =  mfcbc * c1o2 +      mfbbc * (vx1 - c1o2) + (mfabc + c1o9 * oMdrho) * (vx1Sq - vx1) * c1o2;
+   m1 = -mfcbc        - two * mfbbc *  vx1         +  mfabc                  * (one - vx1Sq)              - c1o9 * oMdrho * vx1Sq;
+   m2 =  mfcbc * c1o2 +      mfbbc * (vx1 + c1o2) + (mfabc + c1o9 * oMdrho) * (vx1Sq + vx1) * c1o2;
+   mfabc = m0;
+   mfbbc = m1;
+   mfcbc = m2;
+   ///////////c////////////////////////////////////////////////////////////////////////
+   m0 =  mfccc * c1o2 +      mfbcc * (vx1 - c1o2) + (mfacc + c1o36 * oMdrho) * (vx1Sq - vx1) * c1o2;
+   m1 = -mfccc        - two * mfbcc *  vx1         +  mfacc                   * (one - vx1Sq)              - c1o36 * oMdrho * vx1Sq;
+   m2 =  mfccc * c1o2 +      mfbcc * (vx1 + c1o2) + (mfacc + c1o36 * oMdrho) * (vx1Sq + vx1) * c1o2;
+   mfacc = m0;
+   mfbcc = m1;
+   mfccc = m2;
+   ////////////////////////////////////////////////////////////////////////////////////
+
+   f[E]    = mfcbb;
+   f[W]    = mfabb;
+   f[N]    = mfbcb;
+   f[S]    = mfbab;
+   f[T]    = mfbbc;
+   f[B]    = mfbba;
+   f[NE]   = mfccb;
+   f[SW]   = mfaab;
+   f[SE]   = mfcab;
+   f[NW]   = mfacb;
+   f[TE]   = mfcbc;
+   f[BW]   = mfaba;
+   f[BE]   = mfcba;
+   f[TW]   = mfabc;
+   f[TN]   = mfbcc;
+   f[BS]   = mfbaa;
+   f[BN]   = mfbca;
+   f[TS]   = mfbac;
+   f[ZERO] = mfbbb;
+   f[TNE]  = mfccc;
+   f[TSE]  = mfcac;
+   f[BNE]  = mfcca;
+   f[BSE]  = mfcaa;
+   f[TNW]  = mfacc;
+   f[TSW]  = mfaac;
+   f[BNW]  = mfaca;
+   f[BSW]  = mfaaa;
+}
+//////////////////////////////////////////////////////////////////////////
+void CompressibleOffsetMomentsInterpolationProcessor::calcInterpolatedVelocity(LBMReal x, LBMReal y, LBMReal z, LBMReal& vx1, LBMReal& vx2, LBMReal& vx3)
+{
+	vx1  = a0 + ax*x + ay*y + az*z + axx*x*x + ayy*y*y + azz*z*z + axy*x*y + axz*x*z + ayz*y*z+axyz*x*y*z;
+	vx2  = b0 + bx*x + by*y + bz*z + bxx*x*x + byy*y*y + bzz*z*z + bxy*x*y + bxz*x*z + byz*y*z+bxyz*x*y*z;
+	vx3  = c0 + cx*x + cy*y + cz*z + cxx*x*x + cyy*y*y + czz*z*z + cxy*x*y + cxz*x*z + cyz*y*z+cxyz*x*y*z;
+}
+//////////////////////////////////////////////////////////////////////////
+void CompressibleOffsetMomentsInterpolationProcessor::calcInterpolatedShearStress(LBMReal x, LBMReal y, LBMReal z,LBMReal& tauxx, LBMReal& tauyy, LBMReal& tauzz,LBMReal& tauxy, LBMReal& tauxz, LBMReal& tauyz)
+{
+	tauxx=ax+2*axx*x+axy*y+axz*z+axyz*y*z;
+	tauyy=by+2*byy*y+bxy*x+byz*z+bxyz*x*z;
+	tauzz=cz+2*czz*z+cxz*x+cyz*y+cxyz*x*y;
+	tauxy=0.5*((ay+2.0*ayy*y+axy*x+ayz*z+axyz*x*z)+(bx+2.0*bxx*x+bxy*y+bxz*z+bxyz*y*z));
+	tauxz=0.5*((az+2.0*azz*z+axz*x+ayz*y+axyz*x*y)+(cx+2.0*cxx*x+cxy*y+cxz*z+cxyz*y*z));
+	tauyz=0.5*((bz+2.0*bzz*z+bxz*x+byz*y+bxyz*x*y)+(cy+2.0*cyy*y+cxy*x+cyz*z+cxyz*x*z));
+}
+//////////////////////////////////////////////////////////////////////////
+void CompressibleOffsetMomentsInterpolationProcessor::setBulkOmegaToOmega(bool value)
+{
+   bulkOmegaToOmega = value;
+}
+
diff --git a/source/VirtualFluidsCore/LBM/CompressibleOffsetMomentsInterpolationProcessor.h b/source/VirtualFluidsCore/LBM/CompressibleOffsetMomentsInterpolationProcessor.h
new file mode 100644
index 000000000..09bf98119
--- /dev/null
+++ b/source/VirtualFluidsCore/LBM/CompressibleOffsetMomentsInterpolationProcessor.h
@@ -0,0 +1,82 @@
+#ifndef CompressibleOffsetMomentsInterpolationProcessor_H_
+#define CompressibleOffsetMomentsInterpolationProcessor_H_
+
+#include "InterpolationProcessor.h"
+#include "D3Q27System.h"
+
+//////////////////////////////////////////////////////////////////////////
+//it works only for cascaded LBM
+//super compact interpolation method by Martin Geier
+//////////////////////////////////////////////////////////////////////////
+
+class CompressibleOffsetMomentsInterpolationProcessor;
+typedef boost::shared_ptr<CompressibleOffsetMomentsInterpolationProcessor> CompressibleOffsetMomentsInterpolationProcessorPtr;
+
+class CompressibleOffsetMomentsInterpolationProcessor : public InterpolationProcessor
+{
+public:
+   CompressibleOffsetMomentsInterpolationProcessor();
+   CompressibleOffsetMomentsInterpolationProcessor(LBMReal omegaC, LBMReal omegaF);
+   virtual ~CompressibleOffsetMomentsInterpolationProcessor();
+   InterpolationProcessorPtr clone();
+   void setOmegas(LBMReal omegaC, LBMReal omegaF);
+   void interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF);
+   void interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF, LBMReal xoff, LBMReal yoff, LBMReal zoff);
+   void interpolateFineToCoarse(D3Q27ICell& icellF, LBMReal* icellC); 
+   void interpolateFineToCoarse(D3Q27ICell& icellF, LBMReal* icellC, LBMReal xoff, LBMReal yoff, LBMReal zoff); 
+   void setBulkOmegaToOmega(bool value);
+protected:   
+private:
+   LBMReal omegaC, omegaF;
+   LBMReal a0, ax, ay, az, axx, ayy, azz, axy, axz, ayz, b0, bx, by, bz, bxx, byy, bzz, bxy, bxz, byz, c0, cx, cy, cz, cxx, cyy, czz, cxy, cxz, cyz, axyz, bxyz, cxyz;
+   LBMReal xoff,    yoff,    zoff;
+   LBMReal xoff_sq, yoff_sq, zoff_sq;
+   LBMReal press_SWT, press_NWT, press_NET, press_SET, press_SWB, press_NWB, press_NEB, press_SEB;
+
+   LBMReal  f_E,  f_N,  f_T,  f_NE,  f_SE,  f_BE,  f_TE,  f_TN,  f_BN,  f_TNE,  f_TNW,  f_TSE,  f_TSW,  f_ZERO;
+   LBMReal  x_E,  x_N,  x_T,  x_NE,  x_SE,  x_BE,  x_TE,  x_TN,  x_BN,  x_TNE,  x_TNW,  x_TSE,  x_TSW,  x_ZERO;
+   LBMReal  y_E,  y_N,  y_T,  y_NE,  y_SE,  y_BE,  y_TE,  y_TN,  y_BN,  y_TNE,  y_TNW,  y_TSE,  y_TSW,  y_ZERO;
+   LBMReal  z_E,  z_N,  z_T,  z_NE,  z_SE,  z_BE,  z_TE,  z_TN,  z_BN,  z_TNE,  z_TNW,  z_TSE,  z_TSW,  z_ZERO;
+   LBMReal xy_E, xy_N, xy_T, xy_NE, xy_SE, xy_BE, xy_TE, xy_TN, xy_BN, xy_TNE, xy_TNW, xy_TSE, xy_TSW/*, xy_ZERO*/;
+   LBMReal xz_E, xz_N, xz_T, xz_NE, xz_SE, xz_BE, xz_TE, xz_TN, xz_BN, xz_TNE, xz_TNW, xz_TSE, xz_TSW/*, xz_ZERO*/;
+   LBMReal yz_E, yz_N, yz_T, yz_NE, yz_SE, yz_BE, yz_TE, yz_TN, yz_BN, yz_TNE, yz_TNW, yz_TSE, yz_TSW/*, yz_ZERO*/;
+
+   LBMReal kxyAverage, kyzAverage, kxzAverage, kxxMyyAverage, kxxMzzAverage; 
+
+   LBMReal a,b,c;
+
+   // bulk viscosity
+   bool bulkOmegaToOmega;
+   LBMReal OxxPyyPzzC;
+   LBMReal OxxPyyPzzF;
+
+   void setOffsets(LBMReal xoff, LBMReal yoff, LBMReal zoff);
+   void calcMoments(const LBMReal* const f, LBMReal omega, LBMReal& rho, LBMReal& vx1, LBMReal& vx2, LBMReal& vx3, 
+      LBMReal& kxy, LBMReal& kyz, LBMReal& kxz, LBMReal& kxxMyy, LBMReal& kxxMzz);
+   void calcInterpolatedCoefficiets(const D3Q27ICell& icell, LBMReal omega, LBMReal eps_new);
+   void calcInterpolatedNodeCF(LBMReal* f, LBMReal omega, LBMReal x, LBMReal y, LBMReal z, LBMReal press, LBMReal xs, LBMReal ys, LBMReal zs);
+   LBMReal calcPressBSW();
+   LBMReal calcPressTSW();
+   LBMReal calcPressTSE();
+   LBMReal calcPressBSE();
+   LBMReal calcPressBNW();
+   LBMReal calcPressTNW();
+   LBMReal calcPressTNE();
+   LBMReal calcPressBNE();
+   void calcInterpolatedNodeFC(LBMReal* f, LBMReal omega);
+   void calcInterpolatedVelocity(LBMReal x, LBMReal y, LBMReal z,LBMReal& vx1, LBMReal& vx2, LBMReal& vx3);
+   void calcInterpolatedShearStress(LBMReal x, LBMReal y, LBMReal z,LBMReal& tauxx, LBMReal& tauyy, LBMReal& tauzz,LBMReal& tauxy, LBMReal& tauxz, LBMReal& tauyz);
+};
+
+//////////////////////////////////////////////////////////////////////////
+inline void CompressibleOffsetMomentsInterpolationProcessor::interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF)
+{
+   this->interpolateCoarseToFine(icellC, icellF, 0.0, 0.0, 0.0);
+}
+//////////////////////////////////////////////////////////////////////////
+inline void CompressibleOffsetMomentsInterpolationProcessor::interpolateFineToCoarse(D3Q27ICell& icellF, LBMReal* icellC)
+{
+   this->interpolateFineToCoarse(icellF, icellC, 0.0, 0.0, 0.0);
+}
+
+#endif
diff --git a/source/VirtualFluidsCore/LBM/IncompressibleOffsetInterpolationProcessor.cpp b/source/VirtualFluidsCore/LBM/IncompressibleOffsetInterpolationProcessor.cpp
index d4f015730..d5038cce1 100644
--- a/source/VirtualFluidsCore/LBM/IncompressibleOffsetInterpolationProcessor.cpp
+++ b/source/VirtualFluidsCore/LBM/IncompressibleOffsetInterpolationProcessor.cpp
@@ -313,48 +313,93 @@ void IncompressibleOffsetInterpolationProcessor::calcInterpolatedCoefficiets(con
    bxyz=-vx2_NEB + vx2_NET + vx2_NWB - vx2_NWT + vx2_SEB - vx2_SET - vx2_SWB + vx2_SWT;
    cxyz=-vx3_NEB + vx3_NET + vx3_NWB - vx3_NWT + vx3_SEB - vx3_SET - vx3_SWB + vx3_SWT;
 
+   /////////////////////BÖSE!!!
+   //axx=0;   ayy=0;   azz=0;
+   //bxx=0;   byy=0;   bzz=0;
+   //cxx=0;   cyy=0;   czz=0;
+   ////////////////////!!!BÖSE
 
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-   kxyAverage       =(kxyFromfcNEQ_SWB+
-                      kxyFromfcNEQ_SWT+
-                      kxyFromfcNEQ_SET+
-                      kxyFromfcNEQ_SEB+
-                      kxyFromfcNEQ_NWB+
-                      kxyFromfcNEQ_NWT+
-                      kxyFromfcNEQ_NET+
-                      kxyFromfcNEQ_NEB)*c1o8-(ay+bx);
-   kyzAverage       =(kyzFromfcNEQ_SWB+
-                      kyzFromfcNEQ_SWT+
-                      kyzFromfcNEQ_SET+
-                      kyzFromfcNEQ_SEB+
-                      kyzFromfcNEQ_NWB+
-                      kyzFromfcNEQ_NWT+
-                      kyzFromfcNEQ_NET+
-                      kyzFromfcNEQ_NEB)*c1o8-(bz+cy);
-   kxzAverage       =(kxzFromfcNEQ_SWB+
-                      kxzFromfcNEQ_SWT+
-                      kxzFromfcNEQ_SET+
-                      kxzFromfcNEQ_SEB+
-                      kxzFromfcNEQ_NWB+
-                      kxzFromfcNEQ_NWT+
-                      kxzFromfcNEQ_NET+
-                      kxzFromfcNEQ_NEB)*c1o8-(az+cx);
-   kxxMyyAverage    =(kxxMyyFromfcNEQ_SWB+
-                      kxxMyyFromfcNEQ_SWT+
-                      kxxMyyFromfcNEQ_SET+
-                      kxxMyyFromfcNEQ_SEB+
-                      kxxMyyFromfcNEQ_NWB+
-                      kxxMyyFromfcNEQ_NWT+
-                      kxxMyyFromfcNEQ_NET+
-                      kxxMyyFromfcNEQ_NEB)*c1o8-(ax-by);
-   kxxMzzAverage    =(kxxMzzFromfcNEQ_SWB+
-                     kxxMzzFromfcNEQ_SWT+
-                     kxxMzzFromfcNEQ_SET+
-                     kxxMzzFromfcNEQ_SEB+
-                     kxxMzzFromfcNEQ_NWB+
-                     kxxMzzFromfcNEQ_NWT+
-                     kxxMzzFromfcNEQ_NET+
-                     kxxMzzFromfcNEQ_NEB)*c1o8-(ax-cz);
+   //kxyAverage       =(kxyFromfcNEQ_SWB+
+   //                   kxyFromfcNEQ_SWT+
+   //                   kxyFromfcNEQ_SET+
+   //                   kxyFromfcNEQ_SEB+
+   //                   kxyFromfcNEQ_NWB+
+   //                   kxyFromfcNEQ_NWT+
+   //                   kxyFromfcNEQ_NET+
+   //                   kxyFromfcNEQ_NEB)*c1o8-(ay+bx);
+   //kyzAverage       =(kyzFromfcNEQ_SWB+
+   //                   kyzFromfcNEQ_SWT+
+   //                   kyzFromfcNEQ_SET+
+   //                   kyzFromfcNEQ_SEB+
+   //                   kyzFromfcNEQ_NWB+
+   //                   kyzFromfcNEQ_NWT+
+   //                   kyzFromfcNEQ_NET+
+   //                   kyzFromfcNEQ_NEB)*c1o8-(bz+cy);
+   //kxzAverage       =(kxzFromfcNEQ_SWB+
+   //                   kxzFromfcNEQ_SWT+
+   //                   kxzFromfcNEQ_SET+
+   //                   kxzFromfcNEQ_SEB+
+   //                   kxzFromfcNEQ_NWB+
+   //                   kxzFromfcNEQ_NWT+
+   //                   kxzFromfcNEQ_NET+
+   //                   kxzFromfcNEQ_NEB)*c1o8-(az+cx);
+   //kxxMyyAverage    =(kxxMyyFromfcNEQ_SWB+
+   //                   kxxMyyFromfcNEQ_SWT+
+   //                   kxxMyyFromfcNEQ_SET+
+   //                   kxxMyyFromfcNEQ_SEB+
+   //                   kxxMyyFromfcNEQ_NWB+
+   //                   kxxMyyFromfcNEQ_NWT+
+   //                   kxxMyyFromfcNEQ_NET+
+   //                   kxxMyyFromfcNEQ_NEB)*c1o8-(ax-by);
+   //kxxMzzAverage    =(kxxMzzFromfcNEQ_SWB+
+   //                  kxxMzzFromfcNEQ_SWT+
+   //                  kxxMzzFromfcNEQ_SET+
+   //                  kxxMzzFromfcNEQ_SEB+
+   //                  kxxMzzFromfcNEQ_NWB+
+   //                  kxxMzzFromfcNEQ_NWT+
+   //                  kxxMzzFromfcNEQ_NET+
+   //                  kxxMzzFromfcNEQ_NEB)*c1o8-(ax-cz);
+   kxyAverage       =0;//(kxyFromfcNEQ_SWB+
+                    //kxyFromfcNEQ_SWT+
+                    //kxyFromfcNEQ_SET+
+                    //kxyFromfcNEQ_SEB+
+                    //kxyFromfcNEQ_NWB+
+                    //kxyFromfcNEQ_NWT+
+                    //kxyFromfcNEQ_NET+
+                    //kxyFromfcNEQ_NEB)*c1o8-(ay+bx);
+   kyzAverage       =0;//(kyzFromfcNEQ_SWB+
+                       //kyzFromfcNEQ_SWT+
+                       //kyzFromfcNEQ_SET+
+                       //kyzFromfcNEQ_SEB+
+                       //kyzFromfcNEQ_NWB+
+                       //kyzFromfcNEQ_NWT+
+                       //kyzFromfcNEQ_NET+
+                       //kyzFromfcNEQ_NEB)*c1o8-(bz+cy);
+   kxzAverage       =0;//(kxzFromfcNEQ_SWB+
+                       //kxzFromfcNEQ_SWT+
+                       //kxzFromfcNEQ_SET+
+                       //kxzFromfcNEQ_SEB+
+                       //kxzFromfcNEQ_NWB+
+                       //kxzFromfcNEQ_NWT+
+                       //kxzFromfcNEQ_NET+
+                       //kxzFromfcNEQ_NEB)*c1o8-(az+cx);
+   kxxMyyAverage    =0;//(kxxMyyFromfcNEQ_SWB+
+                       //kxxMyyFromfcNEQ_SWT+
+                       //kxxMyyFromfcNEQ_SET+
+                       //kxxMyyFromfcNEQ_SEB+
+                       //kxxMyyFromfcNEQ_NWB+
+                       //kxxMyyFromfcNEQ_NWT+
+                       //kxxMyyFromfcNEQ_NET+
+                       //kxxMyyFromfcNEQ_NEB)*c1o8-(ax-by);
+   kxxMzzAverage    =0;//(kxxMzzFromfcNEQ_SWB+
+                       //kxxMzzFromfcNEQ_SWT+
+                       //kxxMzzFromfcNEQ_SET+
+                       //kxxMzzFromfcNEQ_SEB+
+                       //kxxMzzFromfcNEQ_NWB+
+                       //kxxMzzFromfcNEQ_NWT+
+                       //kxxMzzFromfcNEQ_NET+
+                       //kxxMzzFromfcNEQ_NEB)*c1o8-(ax-cz);
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // Bernd das Brot
diff --git a/source/VirtualFluidsCore/LBM/InterpolationProcessor.cpp b/source/VirtualFluidsCore/LBM/InterpolationProcessor.cpp
index 23d8861a4..976fef8d6 100644
--- a/source/VirtualFluidsCore/LBM/InterpolationProcessor.cpp
+++ b/source/VirtualFluidsCore/LBM/InterpolationProcessor.cpp
@@ -25,7 +25,19 @@ void InterpolationProcessor::readICell(DistributionArray3DPtr f, D3Q27ICell& ice
    f->getDistribution(icell.TNE, x1+1, x2+1, x3+1);
 }
 //////////////////////////////////////////////////////////////////////////
-void InterpolationProcessor::writeICell(DistributionArray3DPtr f, const D3Q27ICell& icell, int x1, int x2, int x3) 
+void InterpolationProcessor::writeICell(DistributionArray3DPtr f, const D3Q27ICell& icell, int x1, int x2, int x3)
+{
+   f->setDistribution(icell.BSW, x1, x2, x3);
+   f->setDistribution(icell.BSE, x1+1, x2, x3);
+   f->setDistribution(icell.BNW, x1, x2+1, x3);
+   f->setDistribution(icell.BNE, x1+1, x2+1, x3);
+   f->setDistribution(icell.TSW, x1, x2, x3+1);
+   f->setDistribution(icell.TSE, x1+1, x2, x3+1);
+   f->setDistribution(icell.TNW, x1, x2+1, x3+1);
+   f->setDistribution(icell.TNE, x1+1, x2+1, x3+1);
+}
+//////////////////////////////////////////////////////////////////////////
+void InterpolationProcessor::writeICellInv(DistributionArray3DPtr f, const D3Q27ICell& icell, int x1, int x2, int x3) 
 {
    f->setDistributionInv(icell.BSW, x1, x2, x3);
    f->setDistributionInv(icell.BSE, x1+1, x2, x3);
diff --git a/source/VirtualFluidsCore/LBM/InterpolationProcessor.h b/source/VirtualFluidsCore/LBM/InterpolationProcessor.h
index 9a9b61bd8..48150378b 100644
--- a/source/VirtualFluidsCore/LBM/InterpolationProcessor.h
+++ b/source/VirtualFluidsCore/LBM/InterpolationProcessor.h
@@ -39,6 +39,7 @@ public:
 
    static void readICell(DistributionArray3DPtr f, D3Q27ICell& icell, int x1, int x2, int x3);
    static void writeICell(DistributionArray3DPtr f, const D3Q27ICell& icell, int x1, int x2, int x3);
+   static void writeICellInv(DistributionArray3DPtr f, const D3Q27ICell& icell, int x1, int x2, int x3);
    static void writeINode(DistributionArray3DPtr f, const LBMReal* const inode, int x1, int x2, int x3);
    static bool iCellHasSolid(const BCArray3D& bcArray, int x1, int x2, int x3);
    static int  iCellHowManySolids(const BCArray3D& bcArray, int x1, int x2, int x3);
diff --git a/source/VirtualFluidsCore/Visitors/BoundaryConditionsBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/BoundaryConditionsBlockVisitor.cpp
index ffc3b28d8..720092245 100644
--- a/source/VirtualFluidsCore/Visitors/BoundaryConditionsBlockVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/BoundaryConditionsBlockVisitor.cpp
@@ -29,6 +29,7 @@ void BoundaryConditionsBlockVisitor::visit(Grid3DPtr grid, Block3DPtr block)
       }
 
       BCArray3D& bcArray = bcProcessor->getBCArray();
+
       bool compressible = kernel->getCompressible();
       double collFactor = kernel->getCollisionFactor();
       int level = block->getLevel();
@@ -43,7 +44,6 @@ void BoundaryConditionsBlockVisitor::visit(Grid3DPtr grid, Block3DPtr block)
 
       bcProcessor->clearBC();
 
-      //DistributionArray3DPtr distributions = boost::dynamic_pointer_cast<EsoTwist3D>(kernel->getDataSet()->getFdistributions());
       DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();
 
       for (int x3 = minX3; x3 < maxX3; x3++)
@@ -58,6 +58,7 @@ void BoundaryConditionsBlockVisitor::visit(Grid3DPtr grid, Block3DPtr block)
                   {
                      char alg = bcPtr->getBcAlgorithmType();
                      BCAlgorithmPtr bca = bcMap[alg];
+                     
                      if (bca)
                      {
                         bca = bca->clone();
@@ -67,6 +68,7 @@ void BoundaryConditionsBlockVisitor::visit(Grid3DPtr grid, Block3DPtr block)
                         bca->setCollFactor(collFactor);
                         bca->setCompressible(compressible);
                         bcProcessor->addBC(bca);
+                        bca->setBcArray(BCArray3DPtr(&bcArray));
                      }
                   }
                }
diff --git a/source/VirtualFluidsCore/Visitors/InitDistributionsBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/InitDistributionsBlockVisitor.cpp
index 34b8fec59..157529a4f 100644
--- a/source/VirtualFluidsCore/Visitors/InitDistributionsBlockVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/InitDistributionsBlockVisitor.cpp
@@ -109,8 +109,8 @@ void InitDistributionsBlockVisitor::visit(const Grid3DPtr grid, Block3DPtr block
 
    if(!block) UB_THROW( UbException(UB_EXARGS,"block is not exist") );
 
-   UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
-   UbTupleDouble3 nodeOffset   = grid->getNodeOffset(block);
+   //UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
+   //UbTupleDouble3 nodeOffset   = grid->getNodeOffset(block);
    double dx = grid->getDeltaX(block);
    LBMReal o  = LBMSystem::calcCollisionFactor(nu, block->getLevel());
    
@@ -142,7 +142,7 @@ void InitDistributionsBlockVisitor::visit(const Grid3DPtr grid, Block3DPtr block
       else                                                        
          calcFeqsFct   = &D3Q27System::calcIncompFeq; 
 
-      UbTupleDouble3 org = grid->getBlockWorldCoordinates(block);
+      //UbTupleDouble3 org = grid->getBlockWorldCoordinates(block);
 
       BCArray3D& bcArray = kernel->getBCProcessor()->getBCArray();
       EsoTwist3DPtr distributions = boost::dynamic_pointer_cast<EsoTwist3D>(kernel->getDataSet()->getFdistributions());     
@@ -268,6 +268,12 @@ void InitDistributionsBlockVisitor::visit(const Grid3DPtr grid, Block3DPtr block
                //calcFeqsFct(f,rho,vx1,vx2,vx3);
                distributions->setDistribution(f, ix1, ix2, ix3);
                distributions->setDistributionInv(f, ix1, ix2, ix3);
+
+               //distributions->swap();
+               //distributions->setDistribution(f, ix1, ix2, ix3);
+               //distributions->setDistributionInv(f, ix1, ix2, ix3);
+               //distributions->swap();
+
             }
    }
 
diff --git a/source/VirtualFluidsCore/Visitors/InitDistributionsWithInterpolationGridVisitor.cpp b/source/VirtualFluidsCore/Visitors/InitDistributionsWithInterpolationGridVisitor.cpp
new file mode 100644
index 000000000..9c07dbba1
--- /dev/null
+++ b/source/VirtualFluidsCore/Visitors/InitDistributionsWithInterpolationGridVisitor.cpp
@@ -0,0 +1,311 @@
+#include "InitDistributionsWithInterpolationGridVisitor.h"
+#include <basics/utilities/UbFileInputASCII.h>
+#include "LBMKernel.h"
+#include "BCProcessor.h"
+#include "Grid3DSystem.h"
+#include <CbArray2D.h>
+#include "D3Q27EsoTwist3DSplittedVector.h"
+
+
+using namespace std;
+
+InitDistributionsWithInterpolationGridVisitor::InitDistributionsWithInterpolationGridVisitor(Grid3DPtr oldGrid, InterpolationProcessorPtr iProcessor, LBMReal nu)
+   : oldGrid(oldGrid), iProcessor(iProcessor), nu(nu)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+InitDistributionsWithInterpolationGridVisitor::~InitDistributionsWithInterpolationGridVisitor()
+{
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsWithInterpolationGridVisitor::visit(Grid3DPtr grid)
+{
+   newGrid = grid;
+   int minInitLevel = newGrid->getCoarsestInitializedLevel();
+   int maxInitLevel = newGrid->getFinestInitializedLevel();
+   int newGridRank = newGrid->getRank();
+
+   for (int l = minInitLevel; l<=maxInitLevel; l++)
+   {
+      int n = 0;
+      vector<Block3DPtr> blockVector;
+      newGrid->getBlocks(l, blockVector);
+      vector<Block3DPtr> tBlockID;
+
+      BOOST_FOREACH(Block3DPtr newBlock, blockVector)
+      {
+         if (!newBlock) 
+            UB_THROW(UbException(UB_EXARGS, "block is not exist"));
+
+         int newBlockRank = newBlock->getRank();
+
+            Block3DPtr oldBlock = oldGrid->getBlock(newBlock->getX1(), newBlock->getX2(), newBlock->getX3(), newBlock->getLevel());
+            if (oldBlock)
+            {
+               int oldBlockRank = oldBlock->getRank();
+               if (oldBlockRank == newBlockRank && oldBlock->isActive() && newBlockRank == newGridRank && newBlock->isActive())
+               {
+                  copyLocalBlock(oldBlock, newBlock);
+               }
+               else
+               {
+                  copyRemoteBlock(oldBlock, newBlock);
+               }
+            }
+            else
+            {
+               int newlevel = newBlock->getLevel();
+               UbTupleDouble3 coord = newGrid->getNodeCoordinates(newBlock, 1, 1, 1);
+               UbTupleInt3 oldGridBlockIndexes = oldGrid->getBlockIndexes(val<1>(coord), val<2>(coord), val<3>(coord), newlevel-1);
+               Block3DPtr oldBlock = oldGrid->getBlock(val<1>(oldGridBlockIndexes), val<2>(oldGridBlockIndexes), val<3>(oldGridBlockIndexes), newlevel-1);
+
+               if (oldBlock)
+               {
+                  int oldBlockRank = oldBlock->getRank();
+
+                  if (oldBlockRank == newBlockRank && oldBlock->isActive() && newBlockRank == newGridRank && newBlock->isActive())
+                  {
+                     interpolateLocalBlock(oldBlock, newBlock);
+                  }
+                  else
+                  {
+                     interpolateRemoteBlock(oldBlock, newBlock);
+                  }
+               }
+            }
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsWithInterpolationGridVisitor::copyLocalBlock(Block3DPtr oldBlock, Block3DPtr newBlock)
+{
+   LBMKernelPtr oldKernel = oldBlock->getKernel();
+   if (!oldKernel)
+      throw UbException(UB_EXARGS, "The LBM kernel isn't exist in block: "+oldBlock->toString());
+   EsoTwist3DPtr oldDistributions = boost::dynamic_pointer_cast<EsoTwist3D>(oldKernel->getDataSet()->getFdistributions());
+
+   LBMKernelPtr kernel = newBlock->getKernel();
+   if (!kernel)
+      throw UbException(UB_EXARGS, "The LBM kernel isn't exist in new block: "+newBlock->toString());
+   kernel->getDataSet()->setFdistributions(oldDistributions);
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsWithInterpolationGridVisitor::interpolateLocalBlock(Block3DPtr oldBlock, Block3DPtr newBlock)
+{
+   D3Q27ICell icellC;
+   D3Q27ICell icellF;
+
+   LBMReal omegaC = LBMSystem::calcCollisionFactor(nu, oldBlock->getLevel());
+   LBMReal omegaF =LBMSystem::calcCollisionFactor(nu, newBlock->getLevel());
+
+   iProcessor->setOmegas(omegaC, omegaF);
+
+   LBMKernelPtr oldKernel = oldBlock->getKernel();
+   if (!oldKernel)
+      throw UbException(UB_EXARGS, "The LBM kernel isn't exist in old block: "+oldBlock->toString());
+
+   EsoTwist3DPtr oldDistributions = boost::dynamic_pointer_cast<EsoTwist3D>(oldKernel->getDataSet()->getFdistributions());
+
+   LBMKernelPtr newKernel = newBlock->getKernel();
+   if (!newKernel)
+      throw UbException(UB_EXARGS, "The LBM kernel isn't exist in new block: "+newBlock->toString());
+
+   EsoTwist3DPtr newDistributions = boost::dynamic_pointer_cast<EsoTwist3D>(newKernel->getDataSet()->getFdistributions());
+
+   int minX1 = 0;
+   int minX2 = 0;
+   int minX3 = 0;
+
+   int maxX1 = (int)newDistributions->getNX1()-1;
+   int maxX2 = (int)newDistributions->getNX2()-1;
+   int maxX3 = (int)newDistributions->getNX3()-1;
+
+   for (int ix3 = minX3; ix3 < maxX3; ix3+=2)
+      for (int ix2 = minX2; ix2 < maxX2; ix2+=2)
+         for (int ix1 = minX1; ix1 < maxX1; ix1+=2)
+         {
+            UbTupleDouble3 coord = newGrid->getNodeCoordinates(newBlock, ix1, ix2, ix3);
+            UbTupleInt3 oldGridIndexMin = oldGrid->getNodeIndexes(oldBlock, val<1>(coord), val<2>(coord), val<3>(coord));
+            iProcessor->readICell(oldDistributions, icellC, val<1>(oldGridIndexMin), val<2>(oldGridIndexMin), val<3>(oldGridIndexMin));
+            iProcessor->interpolateCoarseToFine(icellC, icellF);
+
+            iProcessor->writeICell(newDistributions, icellF, ix1, ix2, ix3);
+            iProcessor->writeICellInv(newDistributions, icellF, ix1, ix2, ix3);
+         }
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsWithInterpolationGridVisitor::copyRemoteBlock(Block3DPtr oldBlock, Block3DPtr newBlock)
+{
+   int newGridRank = newGrid->getRank();
+   int oldBlockRank = oldBlock->getRank();
+   int newBlockRank = newBlock->getRank();
+
+   if (oldBlockRank == newGridRank && oldBlock->isActive())
+   {
+      LBMKernelPtr oldKernel = oldBlock->getKernel();
+      if (!oldKernel)
+         throw UbException(UB_EXARGS, "The LBM kernel isn't exist in block: "+oldBlock->toString());
+      EsoTwist3DPtr oldDistributions = boost::dynamic_pointer_cast<EsoTwist3D>(oldKernel->getDataSet()->getFdistributions());
+
+      CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(oldDistributions)->getLocalDistributions();
+      CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(oldDistributions)->getNonLocalDistributions();
+      CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr   zeroDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(oldDistributions)->getZeroDistributions();
+      
+      MPI_Send(localDistributions->getStartAdressOfSortedArray(0, 0, 0, 0), localDistributions->getDataVector().size(), MPI_DOUBLE, newBlockRank, 0, MPI_COMM_WORLD);
+      MPI_Send(nonLocalDistributions->getStartAdressOfSortedArray(0, 0, 0, 0), nonLocalDistributions->getDataVector().size(), MPI_DOUBLE, newBlockRank, 0, MPI_COMM_WORLD);
+      MPI_Send(zeroDistributions->getStartAdressOfSortedArray(0, 0, 0), zeroDistributions->getDataVector().size(), MPI_DOUBLE, newBlockRank, 0, MPI_COMM_WORLD);
+   }
+   else if(newBlockRank == newGridRank && newBlock->isActive())
+   {
+      LBMKernelPtr newKernel = newBlock->getKernel();
+      if (!newKernel)
+         throw UbException(UB_EXARGS, "The LBM kernel isn't exist in new block: "+newBlock->toString()+UbSystem::toString(newGridRank));
+
+      EsoTwist3DPtr newDistributions = boost::dynamic_pointer_cast<EsoTwist3D>(newKernel->getDataSet()->getFdistributions());
+
+      CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(newDistributions)->getLocalDistributions();
+      CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(newDistributions)->getNonLocalDistributions();
+      CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr   zeroDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(newDistributions)->getZeroDistributions();
+
+      MPI_Recv(localDistributions->getStartAdressOfSortedArray(0, 0, 0, 0), localDistributions->getDataVector().size(), MPI_DOUBLE, oldBlockRank, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+      MPI_Recv(nonLocalDistributions->getStartAdressOfSortedArray(0, 0, 0, 0), nonLocalDistributions->getDataVector().size(), MPI_DOUBLE, oldBlockRank, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+      MPI_Recv(zeroDistributions->getStartAdressOfSortedArray(0, 0, 0), zeroDistributions->getDataVector().size(), MPI_DOUBLE, oldBlockRank, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsWithInterpolationGridVisitor::interpolateRemoteBlock(Block3DPtr oldBlock, Block3DPtr newBlock)
+{
+   int newGridRank = newGrid->getRank();
+   int oldBlockRank = oldBlock->getRank();
+   int newBlockRank = newBlock->getRank();
+
+   if (oldBlockRank == newGridRank)
+   {
+      LBMKernelPtr oldKernel = oldBlock->getKernel();
+      if (!oldKernel)
+         throw UbException(UB_EXARGS, "The LBM kernel isn't exist in block: "+oldBlock->toString());
+      EsoTwist3DPtr oldDistributions = boost::dynamic_pointer_cast<EsoTwist3D>(oldKernel->getDataSet()->getFdistributions());
+
+      CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(oldDistributions)->getLocalDistributions();
+      CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(oldDistributions)->getNonLocalDistributions();
+      CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr   zeroDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(oldDistributions)->getZeroDistributions();
+
+      MPI_Send(localDistributions->getStartAdressOfSortedArray(0, 0, 0, 0), localDistributions->getDataVector().size(), MPI_DOUBLE, newBlockRank, 0, MPI_COMM_WORLD);
+      MPI_Send(nonLocalDistributions->getStartAdressOfSortedArray(0, 0, 0, 0), nonLocalDistributions->getDataVector().size(), MPI_DOUBLE, newBlockRank, 0, MPI_COMM_WORLD);
+      MPI_Send(zeroDistributions->getStartAdressOfSortedArray(0, 0, 0), zeroDistributions->getDataVector().size(), MPI_DOUBLE, newBlockRank, 0, MPI_COMM_WORLD);
+
+      BCArray3D& bcArrayOldBlock = oldBlock->getKernel()->getBCProcessor()->getBCArray();
+      std::vector< int >& bcDataVector = bcArrayOldBlock.getBcindexmatrixDataVector(); 
+      MPI_Send(&bcDataVector[0], bcDataVector.size(), MPI_INT, newBlockRank, 0, MPI_COMM_WORLD);
+   }
+   else if(newBlockRank == newGridRank && newBlock->isActive())
+   {
+      D3Q27ICell icellC;
+      D3Q27ICell icellF;
+      LBMReal xoff, yoff, zoff;
+
+      LBMReal omegaC = LBMSystem::calcCollisionFactor(nu, oldBlock->getLevel());
+      LBMReal omegaF =LBMSystem::calcCollisionFactor(nu, newBlock->getLevel());
+
+      iProcessor->setOmegas(omegaC, omegaF);
+
+      LBMKernelPtr newKernel = newBlock->getKernel();
+      if (!newKernel)
+         throw UbException(UB_EXARGS, "The LBM kernel isn't exist in new block: "+newBlock->toString());
+
+      EsoTwist3DPtr newDistributions = boost::dynamic_pointer_cast<EsoTwist3D>(newKernel->getDataSet()->getFdistributions());
+
+      int minX1 = 0;
+      int minX2 = 0;
+      int minX3 = 0;
+
+      int maxX1 = (int)newDistributions->getNX1()-1;
+      int maxX2 = (int)newDistributions->getNX2()-1;
+      int maxX3 = (int)newDistributions->getNX3()-1;
+
+      int bMaxX1 = (int)newDistributions->getNX1();
+      int bMaxX2 = (int)newDistributions->getNX2();
+      int bMaxX3 = (int)newDistributions->getNX3();
+
+      EsoTwist3DPtr oldDistributions(new D3Q27EsoTwist3DSplittedVector(bMaxX1, bMaxX2, bMaxX3, 0));
+
+      CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(oldDistributions)->getLocalDistributions();
+      CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(oldDistributions)->getNonLocalDistributions();
+      CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr   zeroDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(oldDistributions)->getZeroDistributions();
+
+      MPI_Recv(localDistributions->getStartAdressOfSortedArray(0, 0, 0, 0), localDistributions->getDataVector().size(), MPI_DOUBLE, oldBlockRank, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+      MPI_Recv(nonLocalDistributions->getStartAdressOfSortedArray(0, 0, 0, 0), nonLocalDistributions->getDataVector().size(), MPI_DOUBLE, oldBlockRank, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+      MPI_Recv(zeroDistributions->getStartAdressOfSortedArray(0, 0, 0), zeroDistributions->getDataVector().size(), MPI_DOUBLE, oldBlockRank, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+
+      BCArray3D bcArrayOldBlock(bMaxX1, bMaxX2, bMaxX3, BCArray3D::FLUID);
+      std::vector< int >& bcDataVector = bcArrayOldBlock.getBcindexmatrixDataVector(); 
+      MPI_Recv(&bcDataVector[0], bcDataVector.size(), MPI_INT, oldBlockRank, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+
+      for (int ix3 = minX3; ix3 < maxX3; ix3+=2)
+         for (int ix2 = minX2; ix2 < maxX2; ix2+=2)
+            for (int ix1 = minX1; ix1 < maxX1; ix1+=2)
+            {
+               UbTupleDouble3 coord = newGrid->getNodeCoordinates(newBlock, ix1, ix2, ix3);
+               UbTupleInt3 oldGridIndexMin = oldGrid->getNodeIndexes(oldBlock, val<1>(coord), val<2>(coord), val<3>(coord));
+               //iProcessor->readICell(oldDistributions, icellC, val<1>(oldGridIndexMin), val<2>(oldGridIndexMin), val<3>(oldGridIndexMin));
+               //iProcessor->interpolateCoarseToFine(icellC, icellF);
+
+               int howManySolids= iProcessor->iCellHowManySolids(bcArrayOldBlock, val<1>(oldGridIndexMin), val<2>(oldGridIndexMin), val<3>(oldGridIndexMin));
+
+               if (howManySolids == 0 || howManySolids == 8)
+               {
+                  iProcessor->readICell(oldDistributions, icellC, val<1>(oldGridIndexMin), val<2>(oldGridIndexMin), val<3>(oldGridIndexMin));
+                  //xoff=0.0;
+                  //yoff=0.0;
+                  //zoff=0.0;
+                  iProcessor->interpolateCoarseToFine(icellC, icellF);
+               }
+               else
+               {
+                  if (iProcessor->findNeighborICell(bcArrayOldBlock, oldDistributions, icellC, bMaxX1, bMaxX2, bMaxX3, 
+                                                     val<1>(oldGridIndexMin), val<2>(oldGridIndexMin), val<3>(oldGridIndexMin), xoff, yoff, zoff))
+                  {
+                     //std::string err = "For "+oldBlock->toString()+
+                     //   " x1="+UbSystem::toString(val<1>(oldGridIndexMin))+
+                     //   ", x2=" + UbSystem::toString(val<2>(oldGridIndexMin))+
+                     //   ", x3=" + UbSystem::toString(val<3>(oldGridIndexMin))+
+                     //   " interpolation is not implemented for other direction"+
+                     //   " by using in: "+(std::string)typeid(*this).name()+
+                     //   " or maybe you have a solid on the block boundary";
+                     //UB_THROW(UbException(UB_EXARGS, err));
+                     iProcessor->interpolateCoarseToFine(icellC, icellF, xoff, yoff, zoff);
+                  }
+                  else
+                  {
+                     for (int i=0; i<27; i++)
+                     {
+                        icellF.BSW[i]=0.0;
+                        icellF.BSE[i]=0.0;
+                        icellF.BNW[i]=0.0;
+                        icellF.BNE[i]=0.0;
+                        icellF.TSW[i]=0.0;
+                        icellF.TSE[i]=0.0;
+                        icellF.TNW[i]=0.0;
+                        icellF.TNE[i]=0.0;
+                     }
+                     //                     std::string err = "For "+oldBlock->toString()+
+                     //   " x1="+UbSystem::toString(val<1>(oldGridIndexMin))+
+                     //   ", x2=" + UbSystem::toString(val<2>(oldGridIndexMin))+
+                     //   ", x3=" + UbSystem::toString(val<3>(oldGridIndexMin))+
+                     //   " interpolation is not implemented for other direction"+
+                     //   " by using in: "+(std::string)typeid(*this).name()+
+                     //   " or maybe you have a solid on the block boundary";
+                     ////UB_THROW(UbException(UB_EXARGS, err));
+                     //                     UBLOG(logINFO, err);
+                  }
+               }
+
+               
+
+               iProcessor->writeICell(newDistributions, icellF, ix1, ix2, ix3);
+               iProcessor->writeICellInv(newDistributions, icellF, ix1, ix2, ix3);
+            }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
diff --git a/source/VirtualFluidsCore/Visitors/InitDistributionsWithInterpolationGridVisitor.h b/source/VirtualFluidsCore/Visitors/InitDistributionsWithInterpolationGridVisitor.h
new file mode 100644
index 000000000..5b6eee7f6
--- /dev/null
+++ b/source/VirtualFluidsCore/Visitors/InitDistributionsWithInterpolationGridVisitor.h
@@ -0,0 +1,26 @@
+#ifndef InitDistributionsWithCoarseGridBlockVisitor_h__
+#define InitDistributionsWithCoarseGridBlockVisitor_h__
+
+#include "Block3DVisitor.h"
+#include <mpi.h>
+
+class InitDistributionsWithInterpolationGridVisitor : public Grid3DVisitor
+{
+public:
+   InitDistributionsWithInterpolationGridVisitor(Grid3DPtr oldGrid, InterpolationProcessorPtr iProcessor, LBMReal nu);
+   ~InitDistributionsWithInterpolationGridVisitor();
+   void visit(Grid3DPtr grid);
+private:
+   void copyLocalBlock(Block3DPtr oldBlock, Block3DPtr newBlock);
+   void interpolateLocalBlock(Block3DPtr oldBlock, Block3DPtr newBlock);
+   void copyRemoteBlock(Block3DPtr oldBlock, Block3DPtr newBlock);
+   void interpolateRemoteBlock(Block3DPtr oldBlock, Block3DPtr newBlock);
+
+   Grid3DPtr newGrid;
+   Grid3DPtr oldGrid;
+   LBMReal nu;
+
+   InterpolationProcessorPtr iProcessor;
+};
+
+#endif // InitDistributionsWithVelocityProfileBlockVisitor_h__
diff --git a/source/VirtualFluidsCore/Visitors/InitDistributionsWithVelocityProfileBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/InitDistributionsWithVelocityProfileBlockVisitor.cpp
deleted file mode 100644
index 220edde44..000000000
--- a/source/VirtualFluidsCore/Visitors/InitDistributionsWithVelocityProfileBlockVisitor.cpp
+++ /dev/null
@@ -1,257 +0,0 @@
-//#include "InitDistributionsWithVelocityProfileBlockVisitor.h"
-//#include <basics/utilities/UbFileInputASCII.h>
-//#include "LBMKernel3D.h"
-//#include "D3Q27ETBCProcessor.h"
-//#include "Grid3DSystem.h"
-//
-//using namespace std;
-//
-//InitDistributionsWithVelocityProfileBlockVisitor::InitDistributionsWithVelocityProfileBlockVisitor(LBMReal nu, LBMReal rho, double dx, int size, std::string filename)
-//   : Block3DVisitor(0, Grid3DSystem::MAXLEVEL), nu(nu), rho(rho)
-//{
-//   UbFileInputASCII in(filename);
-//   if (!in)
-//   {
-//      throw UbException(UB_EXARGS, "could not open file " + filename);
-//   }
-//   
-//   in.readLine();
-//
-//   while(!in.eof())
-//   {
-//      z.push_back(in.readDouble());
-//      vx1.push_back(in.readDouble());
-//      vx2.push_back(in.readDouble());
-//      vx3.push_back(in.readDouble());
-//   }
-//
-//   double startCoord = z[0];
-//   int old_size = (int)z.size();
-//   for (int i = 0; i < old_size; i++)
-//   {
-//      z[i] = (z[i] - startCoord) / dx;
-//   }
-//
-//
-//}
-////////////////////////////////////////////////////////////////////////////
-//InitDistributionsWithVelocityProfileBlockVisitor::~InitDistributionsWithVelocityProfileBlockVisitor()
-//{
-//}
-////////////////////////////////////////////////////////////////////////////
-//void InitDistributionsWithVelocityProfileBlockVisitor::visit(Grid3DPtr grid, Block3DPtr block)
-//{
-//   using namespace D3Q27System;
-//
-//   int gridRank = oldGrid->getRank();
-//
-//   int minInitLevel = oldGrid->getCoarsestInitializedLevel();
-//   int maxInitLevel = oldGrid->getFinestInitializedLevel();
-//
-//   for (int level = minInitLevel; level <= maxInitLevel; level++)
-//   {
-//      vector<Block3DPtr> blockVector;
-//      grid->getBlocks(level, gridRank, true, blockVector);
-//      BOOST_FOREACH(Block3DPtr block, blockVector)
-//      {
-//         if (block)
-//         {
-//            UbTupleDouble3 coords = oldGrid->getBlockWorldCoordinates(block);
-//
-//         }
-//      }
-//   }
-//
-//   grid->getBlockWorldCoordinates(0,0,0,)
-//
-//   int size = z.size();
-//   for (int i = 0; i < size; i++)
-//   {
-//      for (int j; j < )
-//      {
-//      }
-//      grid->getBlockIndexes(z[i], grid->, 0);
-//   }
-//
-//   
-//   
-//   
-//   if (!block) UB_THROW(UbException(UB_EXARGS, "block is not exist"));
-//
-//   UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
-//   UbTupleDouble3 nodeOffset = grid->getNodeOffset(block);
-//   double dx = grid->getDeltaX(block);
-//   LBMReal o = LBMSystem::calcCollisionFactor(nu, block->getLevel());
-//
-//
-//   //Funktionszeiger
-//   typedef void(*CalcFeqsFct)(LBMReal* const& /*feq[27]*/, const LBMReal& /*(d)rho*/, const LBMReal& /*vx1*/, const LBMReal& /*vx2*/, const LBMReal& /*vx3*/);
-//   CalcFeqsFct   calcFeqsFct = NULL;
-//
-//   LBMReal vx1, vx2, vx3, rho;
-//
-//   int gridRank = grid->getRank();
-//   int blockRank = block->getRank();
-//
-//   if (blockRank == gridRank && block->isActive())
-//   {
-//      LBMKernel3DPtr kernel = block->getKernel();
-//      if (!kernel)
-//         throw UbException(UB_EXARGS, "The LBM kernel isn't exist in block: " + block->toString());
-//
-//      if (kernel->getCompressible())
-//         calcFeqsFct = &D3Q27System::calcCompFeq;
-//      else
-//         calcFeqsFct = &D3Q27System::calcIncompFeq;
-//
-//      UbTupleDouble3 org = grid->getBlockWorldCoordinates(block);
-//
-//      BCArray3D<D3Q27BoundaryCondition> bcArray = boost::dynamic_pointer_cast<D3Q27ETBCProcessor>(kernel->getBCProcessor())->getBCArray();
-//      EsoTwist3DPtr           distributions = boost::dynamic_pointer_cast<EsoTwist3D>(kernel->getDataSet()->getFdistributions());
-//
-//      LBMReal f[D3Q27System::ENDF + 1];
-//
-//      size_t nx1 = distributions->getNX1();
-//      size_t nx2 = distributions->getNX2();
-//      size_t nx3 = distributions->getNX3();
-//
-//      int minX1 = 0;
-//      int minX2 = 0;
-//      int minX3 = 0;
-//
-//      int maxX1 = (int)bcArray.getNX1();
-//      int maxX2 = (int)bcArray.getNX2();
-//      int maxX3 = (int)bcArray.getNX3();
-//
-//      int level = block->getLevel();
-//      int lMax = grid->getFinestInitializedLevel();
-//
-//      for (int ix3 = minX1; ix3 < maxX3; ix3++)
-//         for (int ix2 = minX2; ix2 < maxX2; ix2++)
-//            for (int ix1 = minX1; ix1 < maxX1; ix1++)
-//            {
-//               int x3f = ix3 + pow(2, lMax - level);
-//
-//
-//
-//               UbTupleInt3 coords = grid->getNodeIndexes(block, ix1, ix2, ix3);
-//               int x1 = val<1>(coords);
-//               int x2 = val<2>(coords);
-//               int x3 = val<3>(coords);
-//
-//               vx1 = matrix(Vx1, x1, x2, x3);
-//               vx2 = matrix(Vx2, x1, x2, x3);
-//               vx3 = matrix(Vx3, x1, x2, x3);
-//
-//
-//               //x-derivative
-//               //double deltaX = dx*0.5;
-//               int deltaX = 1;
-//               x1 = val<1>(coords) + deltaX;
-//               if (x1 > maxX1) x1 = val<1>(coords);
-//               double vx1Plusx1 = matrix(Vx1, x1, x2, x3);
-//               double vx2Plusx1 = matrix(Vx2, x1, x2, x3);
-//               double vx3Plusx1 = matrix(Vx3, x1, x2, x3);
-//
-//               x1 = val<1>(coords) - deltaX;
-//               if (x1 < minX1) x1 = val<1>(coords);
-//               double vx1Minusx1 = matrix(Vx1, x1, x2, x3);
-//               double vx2Minusx1 = matrix(Vx2, x1, x2, x3);
-//               double vx3Minusx1 = matrix(Vx3, x1, x2, x3);
-//
-//               //y-derivative
-//               x1 = val<1>(coords);
-//               x2 = val<2>(coords) + deltaX;
-//               if (x2 > maxX2) x2 = val<2>(coords);
-//               double vx1Plusx2 = matrix(Vx1, x1, x2, x3);
-//               double vx2Plusx2 = matrix(Vx2, x1, x2, x3);
-//               double vx3Plusx2 = matrix(Vx3, x1, x2, x3);
-//
-//               x2 = val<2>(coords) - deltaX;
-//               if (x2 < minX2) x2 = val<2>(coords);
-//               double vx1Minusx2 = matrix(Vx1, x1, x2, x3);
-//               double vx2Minusx2 = matrix(Vx2, x1, x2, x3);
-//               double vx3Minusx2 = matrix(Vx3, x1, x2, x3);
-//
-//               //z-derivative
-//               x2 = val<2>(coords);
-//               x3 = val<3>(coords) + deltaX;
-//               if (x3 > maxX3) x3 = val<3>(coords);
-//               double vx1Plusx3 = matrix(Vx1, x1, x2, x3);
-//               double vx2Plusx3 = matrix(Vx2, x1, x2, x3);
-//               double vx3Plusx3 = matrix(Vx3, x1, x2, x3);
-//
-//               x3 = val<3>(coords) - deltaX;
-//               if (x3 < minX3) x3 = val<3>(coords);
-//               double vx1Minusx3 = matrix(Vx1, x1, x2, x3);
-//               double vx2Minusx3 = matrix(Vx2, x1, x2, x3);
-//               double vx3Minusx3 = matrix(Vx3, x1, x2, x3);
-//
-//               double ax = (vx1Plusx1 - vx1Minusx1) / (2.0*deltaX);
-//               double bx = (vx2Plusx1 - vx2Minusx1) / (2.0*deltaX);
-//               double cx = (vx3Plusx1 - vx3Minusx1) / (2.0*deltaX);
-//
-//               double ay = (vx1Plusx2 - vx1Minusx2) / (2.0*deltaX);
-//               double by = (vx2Plusx2 - vx2Minusx2) / (2.0*deltaX);
-//               double cy = (vx3Plusx2 - vx3Minusx2) / (2.0*deltaX);
-//
-//               double az = (vx1Plusx3 - vx1Minusx3) / (2.0*deltaX);
-//               double bz = (vx2Plusx3 - vx2Minusx3) / (2.0*deltaX);
-//               double cz = (vx3Plusx3 - vx3Minusx3) / (2.0*deltaX);
-//               double eps_new = 1.0;
-//               LBMReal op = 1.;
-//
-//               LBMReal feq[27];
-//
-//               calcFeqsFct(feq, rho, vx1, vx2, vx3);
-//
-//               double f_E = eps_new *((5.*ax*o + 5.*by*o + 5.*cz*o - 8.*ax*op + 4.*by*op + 4.*cz*op) / (54.*o*op));
-//               double f_N = f_E + eps_new *((2.*(ax - by)) / (9.*o));
-//               double f_T = f_E + eps_new *((2.*(ax - cz)) / (9.*o));
-//               double f_NE = eps_new *(-(5.*cz*o + 3.*(ay + bx)*op - 2.*cz*op + ax*(5.*o + op) + by*(5.*o + op)) / (54.*o*op));
-//               double f_SE = f_NE + eps_new *((ay + bx) / (9.*o));
-//               double f_TE = eps_new *(-(5.*cz*o + by*(5.*o - 2.*op) + 3.*(az + cx)*op + cz*op + ax*(5.*o + op)) / (54.*o*op));
-//               double f_BE = f_TE + eps_new *((az + cx) / (9.*o));
-//               double f_TN = eps_new *(-(5.*ax*o + 5.*by*o + 5.*cz*o - 2.*ax*op + by*op + 3.*bz*op + 3.*cy*op + cz*op) / (54.*o*op));
-//               double f_BN = f_TN + eps_new *((bz + cy) / (9.*o));
-//               double f_ZERO = eps_new *((5.*(ax + by + cz)) / (9.*op));
-//               double f_TNE = eps_new *(-(ay + az + bx + bz + cx + cy) / (72.*o));
-//               double f_TSW = -eps_new *((ay + bx) / (36.*o)) - f_TNE;
-//               double f_TSE = -eps_new *((az + cx) / (36.*o)) - f_TNE;
-//               double f_TNW = -eps_new *((bz + cy) / (36.*o)) - f_TNE;
-//
-//
-//               f[E] = f_E + feq[E];
-//               f[W] = f_E + feq[W];
-//               f[N] = f_N + feq[N];
-//               f[S] = f_N + feq[S];
-//               f[T] = f_T + feq[T];
-//               f[B] = f_T + feq[B];
-//               f[NE] = f_NE + feq[NE];
-//               f[SW] = f_NE + feq[SW];
-//               f[SE] = f_SE + feq[SE];
-//               f[NW] = f_SE + feq[NW];
-//               f[TE] = f_TE + feq[TE];
-//               f[BW] = f_TE + feq[BW];
-//               f[BE] = f_BE + feq[BE];
-//               f[TW] = f_BE + feq[TW];
-//               f[TN] = f_TN + feq[TN];
-//               f[BS] = f_TN + feq[BS];
-//               f[BN] = f_BN + feq[BN];
-//               f[TS] = f_BN + feq[TS];
-//               f[TNE] = f_TNE + feq[TNE];
-//               f[TNW] = f_TNW + feq[TNW];
-//               f[TSE] = f_TSE + feq[TSE];
-//               f[TSW] = f_TSW + feq[TSW];
-//               f[BNE] = f_TSW + feq[BNE];
-//               f[BNW] = f_TSE + feq[BNW];
-//               f[BSE] = f_TNW + feq[BSE];
-//               f[BSW] = f_TNE + feq[BSW];
-//               f[ZERO] = f_ZERO + feq[ZERO];
-//
-//               distributions->setDistribution(f, ix1, ix2, ix3);
-//               distributions->setDistributionInv(f, ix1, ix2, ix3);
-//            }
-//   }
-//}
-////////////////////////////////////////////////////////////////////////////
diff --git a/source/VirtualFluidsCore/Visitors/InitDistributionsWithVelocityProfileBlockVisitor.h b/source/VirtualFluidsCore/Visitors/InitDistributionsWithVelocityProfileBlockVisitor.h
deleted file mode 100644
index ee49bc606..000000000
--- a/source/VirtualFluidsCore/Visitors/InitDistributionsWithVelocityProfileBlockVisitor.h
+++ /dev/null
@@ -1,24 +0,0 @@
-//#ifndef InitDistributionsWithVelocityProfileBlockVisitor_h__
-//#define InitDistributionsWithVelocityProfileBlockVisitor_h__
-//
-//#include "Block3DVisitor.h"
-//
-//class InitDistributionsWithVelocityProfileBlockVisitor : public Block3DVisitor
-//{
-//public:
-//   InitDistributionsWithVelocityProfileBlockVisitor(LBMReal nu, LBMReal rho, double dx, std::string file);
-//   ~InitDistributionsWithVelocityProfileBlockVisitor();
-//   void visit(Grid3DPtr grid, Block3DPtr block);
-//private:
-//   std::vector<double> z;
-//   std::vector<double> vx1;
-//   std::vector<double> vx2;
-//   std::vector<double> vx3;
-//
-//   LBMReal nu;
-//   LBMReal rho;
-//
-//   Grid3DPtr oldGrid;
-//};
-//
-//#endif // InitDistributionsWithVelocityProfileBlockVisitor_h__
diff --git a/source/VirtualFluidsCore/Visitors/RefineCrossAndInsideGbObjectHelper.cpp b/source/VirtualFluidsCore/Visitors/RefineCrossAndInsideGbObjectHelper.cpp
index b48829751..e5f30bbe7 100644
--- a/source/VirtualFluidsCore/Visitors/RefineCrossAndInsideGbObjectHelper.cpp
+++ b/source/VirtualFluidsCore/Visitors/RefineCrossAndInsideGbObjectHelper.cpp
@@ -2,14 +2,16 @@
 #include "RefineCrossAndInsideGbObjectBlockVisitor.h"
 #include "RatioBlockVisitor.h"
 #include "RatioSmoothBlockVisitor.h"
+#include "CheckRatioBlockVisitor.h"
 #include "OverlapBlockVisitor.h"
 #include "SetInterpolationDirsBlockVisitor.h"
 #include <D3Q27System.h>
 
 
-RefineCrossAndInsideGbObjectHelper::RefineCrossAndInsideGbObjectHelper(Grid3DPtr grid, int maxRefineLevel) :
+RefineCrossAndInsideGbObjectHelper::RefineCrossAndInsideGbObjectHelper(Grid3DPtr grid, int maxRefineLevel, CommunicatorPtr comm) :
                                     grid(grid),
-                                    maxRefineLevel(maxRefineLevel)
+                                    maxRefineLevel(maxRefineLevel),
+                                    comm(comm)
 {
 }
 //////////////////////////////////////////////////////////////////////////
@@ -21,22 +23,39 @@ void RefineCrossAndInsideGbObjectHelper::refine()
 {
    UBLOG(logDEBUG5,"RefineCrossAndInsideGbObjectHelper: refine - start");	
    
-   int size = (int)objects.size();
-
-   for (int i = 0; i < size; i++)
+   if (comm->isRoot())
    {
-      RefineCrossAndInsideGbObjectBlockVisitor refVisitor(objects[i], levels[i]);
-      grid->accept(refVisitor);
-   }
+      int size = (int)objects.size();
+
+      for (int i = 0; i<size; i++)
+      {
+         RefineCrossAndInsideGbObjectBlockVisitor refVisitor(objects[i], levels[i]);
+         grid->accept(refVisitor);
+      }
+
+      //RatioBlockVisitor ratioVisitor(maxRefineLevel);
+      //grid->accept(ratioVisitor);
 
-   RatioBlockVisitor ratioVisitor(maxRefineLevel);
-   grid->accept(ratioVisitor);
+      //RatioSmoothBlockVisitor ratioSmoothVisitor(maxRefineLevel);
+      //grid->accept(ratioSmoothVisitor);
 
-   RatioSmoothBlockVisitor ratioSmoothVisitor(maxRefineLevel);
-   grid->accept(ratioSmoothVisitor);
+      RatioBlockVisitor ratioVisitor(maxRefineLevel);
+      CheckRatioBlockVisitor checkRatio(maxRefineLevel);
+      int count = 0;
+
+      do {
+         grid->accept(ratioVisitor);
+         checkRatio.resetState();
+         grid->accept(checkRatio);
+         UBLOG(logINFO, "count = "<<count++<<" state = "<<checkRatio.getState());
+      } while (!checkRatio.getState());
+
+
+      OverlapBlockVisitor overlapVisitor(maxRefineLevel, false);
+      grid->accept(overlapVisitor);
+   }
 
-   OverlapBlockVisitor overlapVisitor(maxRefineLevel);
-   grid->accept(overlapVisitor);
+   grid->updateDistributedBlocks(comm);
 
    std::vector<int> dirs;
 
diff --git a/source/VirtualFluidsCore/Visitors/RefineCrossAndInsideGbObjectHelper.h b/source/VirtualFluidsCore/Visitors/RefineCrossAndInsideGbObjectHelper.h
index 4f9e21587..d63481f79 100644
--- a/source/VirtualFluidsCore/Visitors/RefineCrossAndInsideGbObjectHelper.h
+++ b/source/VirtualFluidsCore/Visitors/RefineCrossAndInsideGbObjectHelper.h
@@ -15,7 +15,7 @@ public:
    //! Constructor
    //! \param grid a smart pointer to the grid object
    //! \param maxRefineLevel an integer for maximal refinement level
-   RefineCrossAndInsideGbObjectHelper(Grid3DPtr grid, int maxRefineLevel);
+   RefineCrossAndInsideGbObjectHelper(Grid3DPtr grid, int maxRefineLevel, CommunicatorPtr comm);
    virtual ~RefineCrossAndInsideGbObjectHelper(void);
    //! add geometric object
    //! \param object a smart pointer to bounding box
@@ -28,6 +28,7 @@ private:
    std::vector<GbObject3DPtr> objects;
    std::vector<int> levels;
    int maxRefineLevel;
+   CommunicatorPtr comm;
 };
 
 #endif 
diff --git a/source/VirtualFluidsCore/Visitors/SetUndefinedNodesBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/SetUndefinedNodesBlockVisitor.cpp
index 47e8c3a1b..af6c9e85a 100644
--- a/source/VirtualFluidsCore/Visitors/SetUndefinedNodesBlockVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/SetUndefinedNodesBlockVisitor.cpp
@@ -633,11 +633,11 @@ void SetUndefinedNodesBlockVisitor::visit(Grid3DPtr grid, Block3DPtr block)
    {
       if(block->hasInterpolationFlagFC()) 
       {
-         for (int i = D3Q27System::E; i <= D3Q27System::TS; i++)
+         for (int i = D3Q27System::E; i <= D3Q27System::BSW; i++)
          {
              UBLOG(logINFO, "FC in dir="<<i<<" "<<block->hasInterpolationFlagFC(i));
          }
-         for (int i = D3Q27System::E; i<=D3Q27System::TS; i++)
+         for (int i = D3Q27System::E; i<=D3Q27System::BSW; i++)
          {
             UBLOG(logINFO, "CF in dir="<<i<<" "<<block->hasInterpolationFlagCF(i));
          }
-- 
GitLab