From 02e1107b5265d65be4c026c43609d20ff65bfbb7 Mon Sep 17 00:00:00 2001
From: Soeren Peters <peters@irmb.tu-bs.de>
Date: Wed, 3 Jan 2018 11:10:39 +0100
Subject: [PATCH] - refactoring: eliminate unnecessary dependencies and forward
 declarate - completly switch to std::shared_ptr - introduce IKernel Interface
 and CalculatorFactory - extract Vector3D from UbMath - introduce
 WriteObjectsCoProcessor

---
 .gitignore                                    |    1 +
 source/Applications/AcousticPulse/ap.cpp      |    8 +-
 source/Applications/BoxBenchmark/bb.cpp       |    3 +-
 source/Applications/DHIT/dhit.cpp             |    7 +-
 source/Applications/DLR-F16-Solid/f16.cpp     |    7 +-
 source/Applications/DLR-F16/f16.cpp           |   37 +-
 .../FlowAroundCylinder/cylinder.cpp           |    6 +-
 .../Hagen_Poiseuille_flow/pflow.cpp           |    3 +-
 .../Hagen_Poiseuille_flow2/pflow2.cpp         |    4 +-
 source/Applications/LaminarTubeFlow/ltf.cpp   |    7 +-
 source/Applications/PoiseuilleFlow/pf1.cpp    |    3 +-
 source/Applications/aperm/aperm.cpp           |    7 +-
 source/Applications/f16Test/f16test.cpp       |   15 +-
 source/Applications/levels/levels.cpp         |    3 +-
 source/Applications/mirror/mirror.cpp         |    5 +-
 source/Applications/mpi_benchmark/mpib.cpp    |    3 +-
 source/Applications/pChannel/pChannel.cpp     |    3 +-
 source/Applications/screw/screw.cpp           |    3 +-
 source/Applications/sphere/sphere.cpp         |    5 +-
 .../cmake_config_files/ELENDUR.config.cmake   |   18 +
 source/CMakeLists.txt                         |    2 +-
 .../Library/basics/container/CbArray3D.h      |    3 +-
 .../Library/basics/container/CbArray4D.h      |    3 +-
 .../basics/memory/MbSharedPointerDefines.h    |   27 +-
 .../Library/basics/utilities/UbException.h    |    4 +-
 .../Library/basics/utilities/UbLogger.h       |  723 ++-
 .../Library/basics/utilities/UbMath.cpp       |  610 +--
 .../Library/basics/utilities/UbMath.h         | 1034 ++---
 .../Library/basics/utilities/UbScheduler.h    |    4 +-
 .../Library/basics/utilities/UbTuple.cpp      |    2 +
 .../Library/basics/utilities/UbTuple.h        |  561 +--
 .../Library/basics/utilities/Vector3D.cpp     |  610 +++
 .../Library/basics/utilities/Vector3D.h       |  131 +
 .../geometry3d/CoordinateTransformation3D.h   |  367 +-
 .../Library/numerics/geometry3d/GbObject3D.h  |    3 +-
 .../numerics/geometry3d/GbSphere3D.cpp        |   13 +-
 .../Library/numerics/geometry3d/GbSphere3D.h  |    4 +
 .../numerics/geometry3d/GbTriFaceMesh3D.h     |   13 +-
 source/VirtualFluids.h                        |    3 +-
 .../BoundaryConditions/BCAdapter.h            |    4 +-
 .../BoundaryConditions/BCAlgorithm.cpp        |  135 +-
 .../BoundaryConditions/BCAlgorithm.h          |  144 +-
 .../BoundaryConditions/BCArray3D.h            |  394 +-
 .../BoundaryConditions/BCProcessor.cpp        |  138 +-
 .../BoundaryConditions/BCProcessor.h          |   33 +-
 .../BoundaryConditions/BoundaryConditions.h   |  603 +--
 .../EqDensityBCAlgorithm.cpp                  |  118 +-
 .../BoundaryConditions/EqDensityBCAlgorithm.h |   53 +-
 .../HighViscosityNoSlipBCAlgorithm.cpp        |   92 +-
 .../HighViscosityNoSlipBCAlgorithm.h          |   56 +-
 .../BoundaryConditions/NoSlipBCAlgorithm.cpp  |   92 +-
 .../BoundaryConditions/NoSlipBCAlgorithm.h    |   54 +-
 .../NonEqDensityBCAlgorithm.cpp               |  120 +-
 .../NonEqDensityBCAlgorithm.h                 |   54 +-
 .../NonReflectingOutflowBCAlgorithm.cpp       |  373 +-
 .../NonReflectingOutflowBCAlgorithm.h         |   55 +-
 .../BoundaryConditions/SlipBCAdapter.cpp      |    4 +-
 .../BoundaryConditions/SlipBCAlgorithm.cpp    |  172 +-
 .../BoundaryConditions/SlipBCAlgorithm.h      |   53 +-
 .../ThinWallBCProcessor.cpp                   |   84 +-
 .../BoundaryConditions/ThinWallBCProcessor.h  |   15 +-
 .../ThinWallNoSlipBCAlgorithm.cpp             |  132 +-
 .../ThinWallNoSlipBCAlgorithm.h               |   65 +-
 .../VelocityBCAlgorithm.cpp                   |   99 +-
 .../BoundaryConditions/VelocityBCAlgorithm.h  |   59 +-
 .../VelocityWithDensityBCAlgorithm.cpp        |  166 +-
 .../VelocityWithDensityBCAlgorithm.h          |   65 +-
 .../CoProcessors/AdjustForcingCoProcessor.cpp |   21 +-
 .../CoProcessors/AdjustForcingCoProcessor.h   |   27 +-
 .../CoProcessors/AverageValuesCoProcessor.cpp | 1142 ++---
 .../CoProcessors/AverageValuesCoProcessor.h   |   35 +-
 .../CalculateForcesCoProcessor.cpp            |   25 +-
 .../CoProcessors/CalculateForcesCoProcessor.h |   28 +-
 .../CoProcessors/CoProcessor.cpp              |   31 +
 .../CoProcessors/CoProcessor.h                |  107 +-
 .../DecreaseViscosityCoProcessor.cpp          |   22 +-
 .../DecreaseViscosityCoProcessor.h            |   19 +-
 .../CoProcessors/EmergencyExitCoProcessor.cpp |    5 +
 .../CoProcessors/EmergencyExitCoProcessor.h   |   42 +-
 .../InSituCatalystCoProcessor.cpp             |    4 +-
 .../CoProcessors/InSituVTKCoProcessor.cpp     |    2 +-
 .../CoProcessors/IntegrateValuesHelper.cpp    | 1118 ++---
 .../CoProcessors/IntegrateValuesHelper.h      |    3 +-
 .../LineTimeSeriesCoProcessor.cpp             |  484 +-
 .../CoProcessors/LineTimeSeriesCoProcessor.h  |   21 +-
 .../MPIIORestart11CoProcessor.cpp             |   54 +-
 .../CoProcessors/MPIIORestart11CoProcessor.h  |    7 +-
 .../CoProcessors/MPIIORestart1CoProcessor.cpp |   58 +-
 .../CoProcessors/MPIIORestart1CoProcessor.h   |    6 +-
 .../MPIIORestart21CoProcessor.cpp             |   58 +-
 .../CoProcessors/MPIIORestart21CoProcessor.h  |    5 +-
 .../CoProcessors/MPIIORestart2CoProcessor.cpp | 2550 +++++------
 .../CoProcessors/MPIIORestart2CoProcessor.h   |  357 +-
 .../CoProcessors/NUPSCounterCoProcessor.cpp   |    3 +
 .../CoProcessors/NUPSCounterCoProcessor.h     |   19 +-
 .../PressureCoefficientCoProcessor.cpp        |   23 +-
 .../PressureCoefficientCoProcessor.h          |   33 +-
 .../PressureDifferenceCoProcessor.cpp         |   21 +-
 .../PressureDifferenceCoProcessor.h           |   29 +-
 .../CoProcessors/QCriterionCoProcessor.cpp    |  778 ++--
 .../CoProcessors/QCriterionCoProcessor.h      |   33 +-
 .../CoProcessors/RestartCoProcessor.cpp       |  749 +--
 .../CoProcessors/RestartCoProcessor.h         |   47 +-
 .../CoProcessors/ShearStressCoProcessor.cpp   | 1394 +++---
 .../CoProcessors/ShearStressCoProcessor.h     |   45 +-
 .../TimeAveragedValuesCoProcessor.cpp         | 1510 +++---
 .../TimeAveragedValuesCoProcessor.h           |   44 +-
 .../TimeDependentBCCoProcessor.cpp            |    7 +-
 .../CoProcessors/TimeDependentBCCoProcessor.h |   25 +-
 .../CoProcessors/TimeseriesCoProcessor.cpp    |   13 +-
 .../CoProcessors/TimeseriesCoProcessor.h      |   42 +-
 .../TurbulenceIntensityCoProcessor.cpp        |  533 +--
 .../TurbulenceIntensityCoProcessor.h          |   27 +-
 .../CoProcessors/WriteBlocksCoProcessor.cpp   |    8 +-
 .../CoProcessors/WriteBlocksCoProcessor.h     |   25 +-
 .../WriteBoundaryConditionsCoProcessor.cpp    |  474 +-
 .../WriteBoundaryConditionsCoProcessor.h      |   36 +-
 .../WriteMacroscopicQuantitiesCoProcessor.cpp |  515 +--
 .../WriteMacroscopicQuantitiesCoProcessor.h   |   44 +-
 .../CoProcessors/WriteObjectsCoProcessor.cpp  |   52 +
 .../CoProcessors/WriteObjectsCoProcessor.h    |   45 +
 .../Connectors/Block3DConnector.h             |    4 +-
 .../Connectors/Block3DConnectorFactory.h      |    4 +-
 .../Connectors/CoarseToFineBlock3DConnector.h |    6 +-
 .../CoarseToFineNodeSetBlock3DConnector.cpp   |   18 +-
 .../CoarseToFineNodeSetBlock3DConnector.h     |    4 +-
 .../Connectors/ConnectorFactory.h             |    4 +-
 .../Connectors/D3Q27ETCFOffVectorConnector.h  |    8 +-
 .../Connectors/D3Q27ETFCOffVectorConnector.h  |    9 +-
 .../Connectors/D3Q27ETFullDirectConnector.cpp |   18 +-
 .../Connectors/D3Q27ETFullDirectConnector.h   |    1 +
 .../Connectors/D3Q27ETFullVectorConnector.cpp |   16 +-
 .../Connectors/D3Q27ETFullVectorConnector.h   |    1 +
 .../Connectors/D3Q27ETOffConnectorFactory.h   |    4 +-
 .../Connectors/FineToCoarseBlock3DConnector.h |    6 +-
 .../FineToCoarseNodeSetBlock3DConnector.cpp   |    6 +-
 .../FineToCoarseNodeSetBlock3DConnector.h     |    4 +-
 .../Connectors/LocalBlock3DConnector.h        |    6 +-
 .../Connectors/RemoteBlock3DConnector.h       |    2 +-
 .../Connectors/TransmitterType.h              |    4 +-
 .../Data/D3Q27EsoTwist3DSplittedVector.h      |  171 +-
 source/VirtualFluidsCore/Data/DataSet3D.h     |    9 +-
 .../Data/DistributionArray3D.h                |    3 +-
 source/VirtualFluidsCore/Data/EsoTwist3D.h    |    4 +-
 .../Data/EsoTwistD3Q27SparseData.h            |    6 +-
 .../VirtualFluidsCore/Data/SparseMatrix3D.h   |    4 +-
 .../VirtualFluidsCore/Data/SparseMatrix4D.h   |    6 +-
 source/VirtualFluidsCore/Data/VoidData3D.h    |    3 +-
 source/VirtualFluidsCore/Grid/Block3D.cpp     |   17 +-
 source/VirtualFluidsCore/Grid/Block3D.h       |  319 +-
 .../Grid/CalculationManager.cpp               |  259 +-
 .../Grid/CalculationManager.h                 |   55 +-
 source/VirtualFluidsCore/Grid/Calculator.cpp  | 1215 ++---
 source/VirtualFluidsCore/Grid/Calculator.h    |  178 +-
 .../Grid/CalculatorFactory.h                  |   33 +
 .../Grid/ConcreteCalculatorFactory.h          |   55 +
 source/VirtualFluidsCore/Grid/Grid3D.cpp      | 4054 ++++++++---------
 source/VirtualFluidsCore/Grid/Grid3D.h        |  565 +--
 .../VirtualFluidsCore/Grid/MPICalculator.cpp  |  740 +--
 source/VirtualFluidsCore/Grid/MPICalculator.h |   13 +-
 .../Grid/PrePostBcCalculator.cpp              |  392 +-
 .../Grid/PrePostBcCalculator.h                |    4 +-
 .../Interactors/D3Q27Interactor.cpp           | 2190 ++++-----
 .../Interactors/D3Q27Interactor.h             |  228 +-
 .../D3Q27TriFaceMeshInteractor.cpp            | 3671 +++++++--------
 .../Interactors/D3Q27TriFaceMeshInteractor.h  |   38 +-
 .../Interactors/Interactor3D.cpp              |  232 +-
 .../Interactors/Interactor3D.h                |   63 +-
 .../Interactors/InteractorsHelper.cpp         |   95 +-
 .../Interactors/InteractorsHelper.h           |   31 +-
 .../LBM/CompressibleCumulant2LBMKernel.cpp    |   20 +-
 .../LBM/CompressibleCumulant2LBMKernel.h      |    4 +-
 .../LBM/CompressibleCumulantLBMKernel.cpp     | 2114 ++++-----
 .../LBM/CompressibleCumulantLBMKernel.h       |    4 +-
 ...mpressibleOffsetInterpolationProcessor.cpp |    6 +-
 ...CompressibleOffsetInterpolationProcessor.h |    2 +-
 ...bleOffsetMomentsInterpolationProcessor.cpp | 1150 ++---
 ...sibleOffsetMomentsInterpolationProcessor.h |    2 +-
 source/VirtualFluidsCore/LBM/D3Q27System.cpp  |  331 +-
 source/VirtualFluidsCore/LBM/D3Q27System.h    |    2 +
 source/VirtualFluidsCore/LBM/ILBMKernel.h     |   34 +
 .../LBM/IncompressibleCumulantLBMKernel.cpp   | 1837 ++++----
 .../LBM/IncompressibleCumulantLBMKernel.h     |    4 +-
 ...ssibleCumulantWithSpongeLayerLBMKernel.cpp | 2040 ++++-----
 ...ressibleCumulantWithSpongeLayerLBMKernel.h |    2 +-
 ...mpressibleOffsetInterpolationProcessor.cpp |    6 +-
 ...compressibleOffsetInterpolationProcessor.h |    2 +-
 .../LBM/InitDensityLBMKernel.cpp              | 2156 ++++-----
 .../LBM/InitDensityLBMKernel.h                |   63 +-
 .../LBM/InterpolationHelper.h                 |    2 +-
 .../LBM/InterpolationProcessor.h              |    2 +-
 source/VirtualFluidsCore/LBM/LBMKernel.cpp    |  422 +-
 source/VirtualFluidsCore/LBM/LBMKernel.h      |  250 +-
 .../VirtualFluidsCore/LBM/LBMUnitConverter.h  |    2 +-
 .../VirtualFluidsCore/LBM/VoidLBMKernel.cpp   |    4 +-
 source/VirtualFluidsCore/LBM/VoidLBMKernel.h  |    2 +-
 .../Parallel/BlocksDistributor.h              |    4 +-
 .../VirtualFluidsCore/Parallel/Communicator.h |    4 +-
 .../Parallel/LoadBalancer.cpp                 |   50 +-
 .../VirtualFluidsCore/Parallel/LoadBalancer.h |    7 +-
 .../Parallel/MPICommunicator.cpp              |    2 +-
 .../Parallel/MPICommunicator.h                |    4 +-
 .../Parallel/MetisPartitioner.h               |    4 +-
 .../Parallel/NullCommunicator.h               |    4 +-
 .../Parallel/PriorityQueueDecompositor.h      |  136 +-
 .../VirtualFluidsCore/Parallel/Synchronizer.h |    4 +-
 .../Utilities/ChangeRandomQs.hpp              |    6 +-
 .../Utilities/ConfigurationFile.hpp           |    6 +-
 .../VirtualFluidsCore/Utilities/MemoryUtil.h  |  231 +-
 .../Utilities/StringUtil.hpp                  |    4 +-
 .../Utilities/VoxelMatrixUtil.hpp             |    6 +-
 .../Visitors/Block3DVisitor.h                 |   11 +-
 .../BoundaryConditionsBlockVisitor.cpp        |  191 +-
 .../Visitors/BoundaryConditionsBlockVisitor.h |   16 +-
 .../ChangeBoundaryDensityBlockVisitor.cpp     |  121 +-
 .../ChangeBoundaryDensityBlockVisitor.h       |   13 +-
 .../Visitors/CheckRatioBlockVisitor.cpp       |    2 +
 .../Visitors/CheckRatioBlockVisitor.h         |   12 +-
 ...rsenCrossAndInsideGbObjectBlockVisitor.cpp |    3 +
 ...oarsenCrossAndInsideGbObjectBlockVisitor.h |   13 +-
 .../Visitors/ConnectorBlockVisitor.cpp        |    4 +
 .../Visitors/ConnectorBlockVisitor.h          |   28 +-
 .../Visitors/CreateTransmittersHelper.h       |    4 +-
 .../Visitors/GenBlocksGridVisitor.cpp         |  159 +-
 .../Visitors/GenBlocksGridVisitor.h           |   50 +-
 .../Visitors/Grid3DVisitor.h                  |    9 +-
 .../InitDistributionsBlockVisitor.cpp         |  627 +--
 .../Visitors/InitDistributionsBlockVisitor.h  |    7 +-
 .../InitDistributionsFromFileBlockVisitor.cpp |  510 ++-
 .../InitDistributionsFromFileBlockVisitor.h   |   10 +-
 ...tributionsWithInterpolationGridVisitor.cpp |  114 +-
 ...istributionsWithInterpolationGridVisitor.h |   32 +-
 .../Visitors/MetisPartitioningGridVisitor.cpp |   16 +-
 .../Visitors/MetisPartitioningGridVisitor.h   |   34 +-
 .../Visitors/OverlapBlockVisitor.cpp          |    2 +
 .../Visitors/OverlapBlockVisitor.h            |    9 +-
 .../PQueuePartitioningGridVisitor.cpp         |   23 +-
 .../Visitors/PQueuePartitioningGridVisitor.h  |    8 +-
 .../Visitors/RatioBlockVisitor.cpp            |    2 +
 .../Visitors/RatioBlockVisitor.h              |   12 +-
 .../Visitors/RatioSmoothBlockVisitor.cpp      |    2 +
 .../Visitors/RatioSmoothBlockVisitor.h        |   11 +-
 .../Visitors/RefineAroundGbObjectHelper.cpp   |    4 +-
 .../Visitors/RefineAroundGbObjectHelper.h     |   15 +-
 ...fineCrossAndInsideGbObjectBlockVisitor.cpp |    5 +
 ...RefineCrossAndInsideGbObjectBlockVisitor.h |   16 +-
 .../RefineCrossAndInsideGbObjectHelper.cpp    |    3 +
 .../RefineCrossAndInsideGbObjectHelper.h      |   18 +-
 .../Visitors/RefineInterGbObjectsVisitor.cpp  |    5 +
 .../Visitors/RefineInterGbObjectsVisitor.h    |   16 +-
 .../Visitors/RenumberBlockVisitor.cpp         |    2 +
 .../Visitors/RenumberBlockVisitor.h           |    6 +-
 .../Visitors/SetConnectorsBlockVisitor.cpp    |    3 +
 .../Visitors/SetConnectorsBlockVisitor.h      |   22 +-
 .../Visitors/SetForcingBlockVisitor.cpp       |   38 +-
 .../Visitors/SetForcingBlockVisitor.h         |    5 +-
 .../SetInterpolationDirsBlockVisitor.cpp      |    6 +-
 .../SetInterpolationDirsBlockVisitor.h        |   12 +-
 .../Visitors/SetKernelBlockVisitor.cpp        |    5 +
 .../Visitors/SetKernelBlockVisitor.h          |   16 +-
 .../Visitors/SetSolidBlockVisitor.cpp         |   11 +-
 .../Visitors/SetSolidBlockVisitor.h           |   21 +-
 .../Visitors/SetSpongeLayerBlockVisitor.cpp   |   11 +-
 .../Visitors/SetSpongeLayerBlockVisitor.h     |   12 +-
 .../SetUndefinedNodesBlockVisitor.cpp         |    7 +-
 .../Visitors/SetUndefinedNodesBlockVisitor.h  |   14 +-
 .../Visitors/SpongeLayerBlockVisitor.cpp      |   83 +-
 .../Visitors/SpongeLayerBlockVisitor.h        |   16 +-
 .../Visitors/ViscosityBlockVisitor.cpp        |    3 +
 .../Visitors/ViscosityBlockVisitor.h          |    8 +-
 .../ZoltanPartitioningGridVisitor.cpp         |    4 +-
 271 files changed, 24077 insertions(+), 24580 deletions(-)
 create mode 100644 source/CMake/cmake_config_files/ELENDUR.config.cmake
 create mode 100644 source/ThirdParty/Library/basics/utilities/UbTuple.cpp
 create mode 100644 source/ThirdParty/Library/basics/utilities/Vector3D.cpp
 create mode 100644 source/ThirdParty/Library/basics/utilities/Vector3D.h
 create mode 100644 source/VirtualFluidsCore/CoProcessors/CoProcessor.cpp
 create mode 100644 source/VirtualFluidsCore/CoProcessors/WriteObjectsCoProcessor.cpp
 create mode 100644 source/VirtualFluidsCore/CoProcessors/WriteObjectsCoProcessor.h
 create mode 100644 source/VirtualFluidsCore/Grid/CalculatorFactory.h
 create mode 100644 source/VirtualFluidsCore/Grid/ConcreteCalculatorFactory.h
 create mode 100644 source/VirtualFluidsCore/LBM/ILBMKernel.h

diff --git a/.gitignore b/.gitignore
index e660fd93d..4136c81a2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
 bin/
+source/MSVC2015/
diff --git a/source/Applications/AcousticPulse/ap.cpp b/source/Applications/AcousticPulse/ap.cpp
index 4d5fe15d5..7a4e54816 100644
--- a/source/Applications/AcousticPulse/ap.cpp
+++ b/source/Applications/AcousticPulse/ap.cpp
@@ -118,7 +118,7 @@ void run(string configname)
       //set connectors
       //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
       InterpolationProcessorPtr iProcessor(new CompressibleOffsetMomentsInterpolationProcessor());
-      boost::dynamic_pointer_cast<CompressibleOffsetMomentsInterpolationProcessor>(iProcessor)->setBulkOmegaToOmega(true);
+      std::dynamic_pointer_cast<CompressibleOffsetMomentsInterpolationProcessor>(iProcessor)->setBulkOmegaToOmega(true);
       SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
 
       UBLOG(logINFO, "SetConnectorsBlockVisitor:start");
@@ -157,7 +157,7 @@ void run(string configname)
 
 
       LBMKernelPtr kernel = LBMKernelPtr(new CompressibleCumulantLBMKernel(blocknx[0], blocknx[1], blocknx[2], CompressibleCumulantLBMKernel::NORMAL));
-      boost::dynamic_pointer_cast<CompressibleCumulantLBMKernel>(kernel)->setBulkOmegaToOmega(true);
+      std::dynamic_pointer_cast<CompressibleCumulantLBMKernel>(kernel)->setBulkOmegaToOmega(true);
       //
       BCProcessorPtr bcProcessor(new BCProcessor());
 
@@ -215,7 +215,9 @@ 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));
+      const std::shared_ptr<ConcreteCalculatorFactory> calculatorFactory = std::make_shared<ConcreteCalculatorFactory>(visSch);
+
+      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, calculatorFactory, CalculatorType::MPI));
       if (myid == 0) UBLOG(logINFO, "Simulation-start");
       calculation->calculate();
       if (myid == 0) UBLOG(logINFO, "Simulation-end");
diff --git a/source/Applications/BoxBenchmark/bb.cpp b/source/Applications/BoxBenchmark/bb.cpp
index 3f631a98a..c768144a6 100644
--- a/source/Applications/BoxBenchmark/bb.cpp
+++ b/source/Applications/BoxBenchmark/bb.cpp
@@ -221,7 +221,8 @@ 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::MPI));
+      const std::shared_ptr<ConcreteCalculatorFactory> calculatorFactory = std::make_shared<ConcreteCalculatorFactory>(visSch);
+      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, calculatorFactory, CalculatorType::MPI));
       if (myid == 0) UBLOG(logINFO, "Simulation-start");
       calculation->calculate();
       if (myid == 0) UBLOG(logINFO, "Simulation-end");
diff --git a/source/Applications/DHIT/dhit.cpp b/source/Applications/DHIT/dhit.cpp
index 3211d71ff..879524183 100644
--- a/source/Applications/DHIT/dhit.cpp
+++ b/source/Applications/DHIT/dhit.cpp
@@ -214,7 +214,8 @@ void run(string configname)
       UbSchedulerPtr nupsSch(new UbScheduler(10, 30, 100));
       NUPSCounterCoProcessor npr(grid, nupsSch, numOfThreads, comm);
 
-      CalculationManagerPtr initialisation(new CalculationManager(grid, numOfThreads, initTime, outputSch));
+      const std::shared_ptr<ConcreteCalculatorFactory> calculatorFactory = std::make_shared<ConcreteCalculatorFactory>(outputSch);
+      CalculationManagerPtr initialisation(new CalculationManager(grid, numOfThreads, endTime, calculatorFactory, CalculatorType::HYBRID));
       if (myid == 0) UBLOG(logINFO, "Initialisation-start");
       initialisation->calculate();
       if (myid == 0) UBLOG(logINFO, "Initialisation-end");
@@ -229,7 +230,9 @@ void run(string configname)
 
       if (myid==0) UBLOG(logINFO, "Simulation-start");
       grid->setTimeStep(initTime+1.0);
-      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, visSch));
+
+      const std::shared_ptr<ConcreteCalculatorFactory> calculatorFactory2 = std::make_shared<ConcreteCalculatorFactory>(visSch);
+      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, calculatorFactory2, CalculatorType::HYBRID));
       calculation->calculate();
       if (myid==0) UBLOG(logINFO, "Simulation-end");
 
diff --git a/source/Applications/DLR-F16-Solid/f16.cpp b/source/Applications/DLR-F16-Solid/f16.cpp
index b99153d50..ed8261e7f 100644
--- a/source/Applications/DLR-F16-Solid/f16.cpp
+++ b/source/Applications/DLR-F16-Solid/f16.cpp
@@ -353,10 +353,10 @@ void run(string configname)
             /////delete solid blocks
             if (myid==0) UBLOG(logINFO, "deleteSolidBlocks - start");
 
-            SetSolidBlockVisitor v(fngIntrWhole, SetSolidBlockVisitor::SOLID);
+            SetSolidBlockVisitor v(fngIntrWhole, BlockType::SOLID);
             grid->accept(v);
             std::vector<Block3DPtr>& sb = fngIntrWhole->getSolidBlockSet();
-            BOOST_FOREACH(Block3DPtr block, sb)
+            for(Block3DPtr block : sb)
             {
                grid->deleteBlock(block);
             }
@@ -612,8 +612,9 @@ void run(string configname)
       UbSchedulerPtr stepMV(new UbScheduler(1));
       //TimeseriesCoProcessor tsp1(grid, stepMV, mic1, pathOut+"/mic/mic1", comm);
 
+      const std::shared_ptr<ConcreteCalculatorFactory> calculatorFactory = std::make_shared<ConcreteCalculatorFactory>(stepSch);
+      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, calculatorFactory, CalculatorType::MPI));
       //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, tavSch, CalculationManager::PrePostBc));
 
       if (myid==0) UBLOG(logINFO, "Simulation-start");
diff --git a/source/Applications/DLR-F16/f16.cpp b/source/Applications/DLR-F16/f16.cpp
index ccee347b3..a731b30b9 100644
--- a/source/Applications/DLR-F16/f16.cpp
+++ b/source/Applications/DLR-F16/f16.cpp
@@ -33,11 +33,11 @@ void setBC(Grid3DPtr grid, string pathGeo, string fngFileWhole, string zigZagTap
 
    for (int level = minInitLevel; level<=maxInitLevel; level++)
    {
-      BOOST_FOREACH(Block3DPtr block, blockVector[level])
+      for(Block3DPtr block : blockVector[level])
       {
          if (block)
          {
-            LBMKernelPtr kernel = block->getKernel();
+            ILBMKernelPtr kernel = block->getKernel();
             kernel->setBCProcessor(bcProcessor->clone(kernel));
          }
       }
@@ -114,34 +114,34 @@ void setBC(Grid3DPtr grid, string pathGeo, string fngFileWhole, string zigZagTap
    //outflow
    D3Q27InteractorPtr outflowIntr = D3Q27InteractorPtr(new D3Q27Interactor(geoOutflow, grid, outflowBCAdapter, Interactor3D::SOLID));
 
-   SetSolidBlockVisitor v1(fngIntrWhole, SetSolidBlockVisitor::BC);
+   SetSolidBlockVisitor v1(fngIntrWhole, BlockType::BC);
    grid->accept(v1);
 
-   SetSolidBlockVisitor v2(triBand1Interactor, SetSolidBlockVisitor::BC);
+   SetSolidBlockVisitor v2(triBand1Interactor, BlockType::BC);
    grid->accept(v2);
 
-   SetSolidBlockVisitor v3(triBand1Interactor, SetSolidBlockVisitor::BC);
+   SetSolidBlockVisitor v3(triBand1Interactor, BlockType::BC);
    grid->accept(v3);
 
-   SetSolidBlockVisitor v4(triBand2Interactor, SetSolidBlockVisitor::BC);
+   SetSolidBlockVisitor v4(triBand2Interactor, BlockType::BC);
    grid->accept(v4);
    
-   SetSolidBlockVisitor v5(triBand3Interactor, SetSolidBlockVisitor::BC);
+   SetSolidBlockVisitor v5(triBand3Interactor, BlockType::BC);
    grid->accept(v5);
 
-   SetSolidBlockVisitor v6(triBand4Interactor, SetSolidBlockVisitor::BC);
+   SetSolidBlockVisitor v6(triBand4Interactor, BlockType::BC);
    grid->accept(v6);
 
-   SetSolidBlockVisitor v7(addWallZminInt, SetSolidBlockVisitor::BC);
+   SetSolidBlockVisitor v7(addWallZminInt, BlockType::BC);
    grid->accept(v7);
 
-   SetSolidBlockVisitor v8(addWallZmaxInt, SetSolidBlockVisitor::BC);
+   SetSolidBlockVisitor v8(addWallZmaxInt, BlockType::BC);
    grid->accept(v8);
 
-   SetSolidBlockVisitor v9(inflowIntr, SetSolidBlockVisitor::BC);
+   SetSolidBlockVisitor v9(inflowIntr, BlockType::BC);
    grid->accept(v9);
 
-   SetSolidBlockVisitor v10(outflowIntr, SetSolidBlockVisitor::BC);
+   SetSolidBlockVisitor v10(outflowIntr, BlockType::BC);
    grid->accept(v10);
    
    inflowIntr->initInteractor();
@@ -681,10 +681,10 @@ void run(string configname)
 
             if (porousTralingEdge)
             {
-               SetSolidBlockVisitor v(fngIntrBodyPart, SetSolidBlockVisitor::SOLID);
+               SetSolidBlockVisitor v(fngIntrBodyPart, BlockType::SOLID);
                grid->accept(v);
                std::vector<Block3DPtr>& sb = fngIntrBodyPart->getSolidBlockSet();
-               BOOST_FOREACH(Block3DPtr block, sb)
+               for(Block3DPtr block : sb)
                {
                   grid->deleteBlock(block);
                }
@@ -693,10 +693,10 @@ void run(string configname)
             }
             else
             {
-               SetSolidBlockVisitor v(fngIntrWhole2, SetSolidBlockVisitor::SOLID);
+               SetSolidBlockVisitor v(fngIntrWhole2, BlockType::SOLID);
                grid->accept(v);
                std::vector<Block3DPtr>& sb = fngIntrWhole2->getSolidBlockSet();
-               BOOST_FOREACH(Block3DPtr block, sb)
+               for(Block3DPtr block : sb)
                {
                   grid->deleteBlock(block);
                }
@@ -1246,7 +1246,10 @@ void run(string configname)
 
       //CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, stepSch));
       //CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, tavSch, CalculationManager::MPI));
-      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, tavSch, CalculationManager::PrePostBc));
+
+
+      const std::shared_ptr<ConcreteCalculatorFactory> calculatorFactory = std::make_shared<ConcreteCalculatorFactory>(stepSch);
+      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, calculatorFactory, CalculatorType::PREPOSTBC));
 
       if (myid==0) UBLOG(logINFO, "Simulation-start");
       calculation->calculate();
diff --git a/source/Applications/FlowAroundCylinder/cylinder.cpp b/source/Applications/FlowAroundCylinder/cylinder.cpp
index 55091a963..2965576d0 100644
--- a/source/Applications/FlowAroundCylinder/cylinder.cpp
+++ b/source/Applications/FlowAroundCylinder/cylinder.cpp
@@ -300,7 +300,7 @@ void run(string configname)
          //PQueuePartitioningGridVisitor pqPartVisitor(numOfThreads);
          //grid->accept(pqPartVisitor);
 
-         SetSolidBlockVisitor v(cylinderInt, SetSolidBlockVisitor::TRANS);
+         SetSolidBlockVisitor v(cylinderInt, BlockType::BC);
          grid->accept(v);
          cylinderInt->initInteractor();
 
@@ -321,7 +321,9 @@ void run(string configname)
 
       //CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, visSch));
       //CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, visSch, CalculationManager::MPI));
-      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, visSch, CalculationManager::PrePostBc));
+
+      const std::shared_ptr<ConcreteCalculatorFactory> calculatorFactory = std::make_shared<ConcreteCalculatorFactory>(visSch);
+      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, calculatorFactory, CalculatorType::PREPOSTBC));
       if(myid == 0) UBLOG(logINFO,"Simulation-start");
       calculation->calculate();
       if(myid == 0) UBLOG(logINFO,"Simulation-end");
diff --git a/source/Applications/Hagen_Poiseuille_flow/pflow.cpp b/source/Applications/Hagen_Poiseuille_flow/pflow.cpp
index f6fc90362..354793eb8 100644
--- a/source/Applications/Hagen_Poiseuille_flow/pflow.cpp
+++ b/source/Applications/Hagen_Poiseuille_flow/pflow.cpp
@@ -686,7 +686,8 @@ void pflowdp(string configname)
       double vxTarget=uLB;
       AdjustForcingCoProcessor AdjForcPPPtr(grid, AdjForcSch, pathname, intValHelp, vxTarget, comm);
 
-      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, stepSch));
+      const std::shared_ptr<ConcreteCalculatorFactory> calculatorFactory = std::make_shared<ConcreteCalculatorFactory>(stepSch);
+      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, calculatorFactory, CalculatorType::HYBRID));
        //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");
diff --git a/source/Applications/Hagen_Poiseuille_flow2/pflow2.cpp b/source/Applications/Hagen_Poiseuille_flow2/pflow2.cpp
index b8bb08ccc..6c884dcdd 100644
--- a/source/Applications/Hagen_Poiseuille_flow2/pflow2.cpp
+++ b/source/Applications/Hagen_Poiseuille_flow2/pflow2.cpp
@@ -294,8 +294,8 @@ void pflowdp(string configname)
       WriteMacroscopicQuantitiesCoProcessor pp(grid, stepSch, pathname, WbWriterVtkXmlBinary::getInstance(), conv, comm);
 
 
-
-      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, stepSch));
+      const std::shared_ptr<ConcreteCalculatorFactory> calculatorFactory = std::make_shared<ConcreteCalculatorFactory>(stepSch);
+      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, calculatorFactory, CalculatorType::HYBRID));
       if (myid == 0) UBLOG(logINFO, "Simulation-start");
       calculation->calculate();
       if (myid == 0) UBLOG(logINFO, "Simulation-end");
diff --git a/source/Applications/LaminarTubeFlow/ltf.cpp b/source/Applications/LaminarTubeFlow/ltf.cpp
index 2e35d5e63..247fefc8d 100644
--- a/source/Applications/LaminarTubeFlow/ltf.cpp
+++ b/source/Applications/LaminarTubeFlow/ltf.cpp
@@ -167,7 +167,7 @@ void run(string configname)
 
          D3Q27InteractorPtr cylinderInt(new D3Q27Interactor(cylinder, grid, noSlipBCAdapter, Interactor3D::INVERSESOLID));
 
-         double r = boost::dynamic_pointer_cast<GbCylinder3D>(cylinder)->getRadius();
+         double r = std::dynamic_pointer_cast<GbCylinder3D>(cylinder)->getRadius();
          double cx1 = g_minX1;
          double cx2 = cylinder->getX2Centroid();
          double cx3 = cylinder->getX3Centroid();
@@ -322,7 +322,10 @@ void run(string configname)
       NUPSCounterCoProcessor npr(grid, nupsSch, numOfThreads, comm);
 
       //CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, visSch,CalculationManager::MPI));
-      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, visSch));
+
+
+      const std::shared_ptr<ConcreteCalculatorFactory> calculatorFactory = std::make_shared<ConcreteCalculatorFactory>(visSch);
+      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, calculatorFactory, CalculatorType::PREPOSTBC));
       if (myid == 0) UBLOG(logINFO, "Simulation-start");
       calculation->calculate();
       if (myid == 0) UBLOG(logINFO, "Simulation-end");
diff --git a/source/Applications/PoiseuilleFlow/pf1.cpp b/source/Applications/PoiseuilleFlow/pf1.cpp
index 79c7cbf29..66b4a0609 100644
--- a/source/Applications/PoiseuilleFlow/pf1.cpp
+++ b/source/Applications/PoiseuilleFlow/pf1.cpp
@@ -160,7 +160,8 @@ void pf1()
    NUPSCounterCoProcessor npr(grid, nupsSch, numOfThreads, comm);
 
    //start simulation 
-   CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, visSch));
+   const std::shared_ptr<ConcreteCalculatorFactory> calculatorFactory = std::make_shared<ConcreteCalculatorFactory>(visSch);
+   CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, calculatorFactory, CalculatorType::HYBRID));
    if (myid == 0) UBLOG(logINFO, "Simulation-start");
    calculation->calculate();
    if (myid == 0) UBLOG(logINFO, "Simulation-end");
diff --git a/source/Applications/aperm/aperm.cpp b/source/Applications/aperm/aperm.cpp
index 2a7092d23..a70480f9e 100644
--- a/source/Applications/aperm/aperm.cpp
+++ b/source/Applications/aperm/aperm.cpp
@@ -450,10 +450,10 @@ void run(string configname)
          {
             Grid3D::Interactor3DSet interactors = grid->getInteractors();
             interactors[0]->setGrid3D(grid);
-            boost::dynamic_pointer_cast<D3Q27Interactor>(interactors[0])->deleteBCAdapter();
+            std::dynamic_pointer_cast<D3Q27Interactor>(interactors[0])->deleteBCAdapter();
             BCAdapterPtr denBCAdapterFront(new DensityBCAdapter(rhoLBinflow));
             denBCAdapterFront->setBcAlgorithm(BCAlgorithmPtr(new EqDensityBCAlgorithm()));
-            boost::dynamic_pointer_cast<D3Q27Interactor>(interactors[0])->addBCAdapter(denBCAdapterFront);
+            std::dynamic_pointer_cast<D3Q27Interactor>(interactors[0])->addBCAdapter(denBCAdapterFront);
             interactors[0]->updateInteractor();
          }
 
@@ -526,7 +526,8 @@ void run(string configname)
          UBLOG(logINFO, "PID = "<<myid<<" Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe());
       }
 
-      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, stepSch));
+      const std::shared_ptr<ConcreteCalculatorFactory> calculatorFactory = std::make_shared<ConcreteCalculatorFactory>(stepSch);
+      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, calculatorFactory, CalculatorType::HYBRID));
       if (myid==0) UBLOG(logINFO, "Simulation-start");
       calculation->calculate();
       if (myid==0) UBLOG(logINFO, "Simulation-end");
diff --git a/source/Applications/f16Test/f16test.cpp b/source/Applications/f16Test/f16test.cpp
index f6b985d45..9cb49dc16 100644
--- a/source/Applications/f16Test/f16test.cpp
+++ b/source/Applications/f16Test/f16test.cpp
@@ -147,10 +147,10 @@ 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 NonReflectingOutflowBCAlgorithm()));
 
       BCAdapterPtr denBCAdapter(new DensityBCAdapter(rhoLB));
-      denBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new NonReflectingDensityBCAlgorithm()));
+      denBCAdapter->setBcAlgorithm(BCAlgorithmPtr(new NonReflectingOutflowBCAlgorithm()));
 
       BoundaryConditionsBlockVisitor bcVisitor;
       bcVisitor.addBC(noSlipBCAdapter);
@@ -343,10 +343,10 @@ void run(string configname)
             
             if (porousTralingEdge)
             {
-               SetSolidBlockVisitor v(fngIntrBodyPart, SetSolidBlockVisitor::SOLID);
+               SetSolidBlockVisitor v(fngIntrBodyPart, BlockType::SOLID);
                grid->accept(v);
                std::vector<Block3DPtr>& sb = fngIntrBodyPart->getSolidBlockSet();
-               BOOST_FOREACH(Block3DPtr block, sb)
+               for(Block3DPtr block : sb)
                {
                   grid->deleteBlock(block);
                }
@@ -355,10 +355,10 @@ void run(string configname)
             }
             else
             {
-               SetSolidBlockVisitor v(fngIntrWhole, SetSolidBlockVisitor::SOLID);
+               SetSolidBlockVisitor v(fngIntrWhole, BlockType::SOLID);
                grid->accept(v);
                std::vector<Block3DPtr>& sb = fngIntrWhole->getSolidBlockSet();
-               BOOST_FOREACH(Block3DPtr block, sb)
+               for(Block3DPtr block : sb)
                {
                   grid->deleteBlock(block);
                }
@@ -616,7 +616,8 @@ void run(string configname)
          UBLOG(logINFO, "PID = " << myid << " Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe());
       }
 
-      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, stepSch));
+      const std::shared_ptr<ConcreteCalculatorFactory> calculatorFactory = std::make_shared<ConcreteCalculatorFactory>(stepSch);
+      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, calculatorFactory, CalculatorType::HYBRID));
       //CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, stepSch, CalculationManager::PrePostBc));
       //calculation->setTimeAveragedValuesCoProcessor(tav);
       if (myid == 0) UBLOG(logINFO, "Simulation-start");
diff --git a/source/Applications/levels/levels.cpp b/source/Applications/levels/levels.cpp
index cb890a2ca..f7c4f50a6 100644
--- a/source/Applications/levels/levels.cpp
+++ b/source/Applications/levels/levels.cpp
@@ -306,7 +306,8 @@ void run(string configname)
       UbSchedulerPtr nupsSch(new UbScheduler(10, 30, 100));
       NUPSCounterCoProcessor npr(grid, nupsSch, numOfThreads, comm);
 
-      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endstep, stepSch));
+      const std::shared_ptr<ConcreteCalculatorFactory> calculatorFactory = std::make_shared<ConcreteCalculatorFactory>(stepSch);
+      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endstep, calculatorFactory, CalculatorType::HYBRID));
 
       if (myid==0)
          UBLOG(logINFO, "Simulation-start");
diff --git a/source/Applications/mirror/mirror.cpp b/source/Applications/mirror/mirror.cpp
index c9830e019..8c5084135 100644
--- a/source/Applications/mirror/mirror.cpp
+++ b/source/Applications/mirror/mirror.cpp
@@ -260,7 +260,7 @@ void run(string configname)
             D3Q27TriFaceMeshInteractorPtr meshVRES1100SpiegelFineInteractor(new D3Q27TriFaceMeshInteractor(meshVRES1100SpiegelFine, grid, noSlipBCAdapter, Interactor3D::SOLID));
 
             UBLOG(logINFO, "Refinement - start");
-            RefineCrossAndInsideGbObjectHelper refineHelper(grid, refineLevel);
+            RefineCrossAndInsideGbObjectHelper refineHelper(grid, refineLevel, comm);
             ////refineHelper.addGbObject(geoVRES0100, refineLevel-4);
             //refineHelper.addGbObject(geoVRES0200, 1);
             //refineHelper.addGbObject(geoVRES0300, 2);
@@ -537,7 +537,8 @@ void run(string configname)
          UBLOG(logINFO, "PID = "<<myid<<" Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe());
       }
 
-      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, stepSch));
+      const std::shared_ptr<ConcreteCalculatorFactory> calculatorFactory = std::make_shared<ConcreteCalculatorFactory>(stepSch);
+      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, calculatorFactory, CalculatorType::HYBRID));
       if (myid==0) UBLOG(logINFO, "Simulation-start");
       calculation->calculate();
       if (myid==0) UBLOG(logINFO, "Simulation-end");
diff --git a/source/Applications/mpi_benchmark/mpib.cpp b/source/Applications/mpi_benchmark/mpib.cpp
index d1205929b..1b0ffcb47 100644
--- a/source/Applications/mpi_benchmark/mpib.cpp
+++ b/source/Applications/mpi_benchmark/mpib.cpp
@@ -231,7 +231,8 @@ void run(string configname)
          UBLOG(logINFO, "//////////////////////////////////////////////////////////////////////////");
       }
 
-      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, visSch,CalculationManager::MPI));
+      const std::shared_ptr<ConcreteCalculatorFactory> calculatorFactory = std::make_shared<ConcreteCalculatorFactory>(visSch);
+      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, calculatorFactory, CalculatorType::MPI));
       if (myid==0) UBLOG(logINFO, "Simulation-start");
       calculation->calculate();
       if (myid==0) UBLOG(logINFO, "Simulation-end");
diff --git a/source/Applications/pChannel/pChannel.cpp b/source/Applications/pChannel/pChannel.cpp
index c6aab304e..efc48e6ae 100644
--- a/source/Applications/pChannel/pChannel.cpp
+++ b/source/Applications/pChannel/pChannel.cpp
@@ -767,7 +767,8 @@ void run(string configname)
          UBLOG(logINFO, "PID = " << myid << " Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe());
       }
 
-      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, stepSch));
+      const std::shared_ptr<ConcreteCalculatorFactory> calculatorFactory = std::make_shared<ConcreteCalculatorFactory>(stepSch);
+      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, calculatorFactory, CalculatorType::HYBRID));
       if (averaging)
       {
          calculation->setTimeAveragedValuesCoProcessor(tav);
diff --git a/source/Applications/screw/screw.cpp b/source/Applications/screw/screw.cpp
index 03c15597b..d7918eecc 100644
--- a/source/Applications/screw/screw.cpp
+++ b/source/Applications/screw/screw.cpp
@@ -233,7 +233,8 @@ int main(int argc, char* argv[])
 
       WriteMacroscopicQuantitiesCoProcessor pp(grid, stepSch, pathname, WbWriterVtkXmlBinary::getInstance(), conv, comm);
 
-      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, stepSch));
+      const std::shared_ptr<ConcreteCalculatorFactory> calculatorFactory = std::make_shared<ConcreteCalculatorFactory>(stepSch);
+      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endTime, calculatorFactory, CalculatorType::HYBRID));
       if (myid == 0) UBLOG(logINFO, "Simulation-start");
       calculation->calculate();
       if (myid == 0) UBLOG(logINFO, "Simulation-end");
diff --git a/source/Applications/sphere/sphere.cpp b/source/Applications/sphere/sphere.cpp
index c4daf2166..94a57109c 100644
--- a/source/Applications/sphere/sphere.cpp
+++ b/source/Applications/sphere/sphere.cpp
@@ -166,7 +166,7 @@ void run(string configname)
          if (refineLevel > 0)
          {
             if (myid == 0) UBLOG(logINFO, "Refinement - start");
-            RefineCrossAndInsideGbObjectHelper refineHelper(grid, refineLevel);
+            RefineCrossAndInsideGbObjectHelper refineHelper(grid, refineLevel, comm);
             refineHelper.addGbObject(sphere, refineLevel);
             //refineHelper.addGbObject(refCube, refineLevel);
             refineHelper.refine();
@@ -327,7 +327,8 @@ void run(string configname)
       UbSchedulerPtr nupsSch(new UbScheduler(10, 30, 100));
       NUPSCounterCoProcessor npr(grid, nupsSch, numOfThreads, comm);
 
-      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endstep, stepSch));
+      const std::shared_ptr<ConcreteCalculatorFactory> calculatorFactory = std::make_shared<ConcreteCalculatorFactory>(stepSch);
+      CalculationManagerPtr calculation(new CalculationManager(grid, numOfThreads, endstep, calculatorFactory, CalculatorType::HYBRID));
 
       if (myid == 0)
          UBLOG(logINFO, "Simulation-start");
diff --git a/source/CMake/cmake_config_files/ELENDUR.config.cmake b/source/CMake/cmake_config_files/ELENDUR.config.cmake
new file mode 100644
index 000000000..0ec17a47a
--- /dev/null
+++ b/source/CMake/cmake_config_files/ELENDUR.config.cmake
@@ -0,0 +1,18 @@
+#################################################################################
+#  BOOST  
+#################################################################################
+SET(BOOST_VERSION "1.65.1")
+SET(BOOST_ROOT "c:/Libraries/boost/boost_1_65_1")
+SET(BOOST_DIR ${BOOST_ROOT})
+SET(BOOST_LIBRARYDIR ${BOOST_ROOT}"/stage/lib")  
+#################################################################################
+
+#################################################################################
+#################################################################################
+#  METIS  
+#################################################################################
+IF(${USE_METIS})
+  SET(METIS_INCLUDEDIR "c:/Libraries/metis/metis-5.1.0/include")
+  SET(METIS_DEBUG_LIBRARY "c:/Libraries/metis/metis-5.1.0/MSVC2015/libmetis/Debug/metis.lib") 
+  SET(METIS_RELEASE_LIBRARY "c:/Libraries/metis/metis-5.1.0/MSVC2015/libmetis/Release/metis.lib") 
+ENDIF()
\ No newline at end of file
diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt
index 951b10e5a..5def8cca7 100644
--- a/source/CMakeLists.txt
+++ b/source/CMakeLists.txt
@@ -77,7 +77,7 @@ IF(${USE_CATALYST})
     include("${PARAVIEW_USE_FILE}")
 ENDIF()
 
-LIST(APPEND CAB_ADDTIONAL_COMPILER_FLAGS -DCAB_BOOST)
+#LIST(APPEND CAB_ADDTIONAL_COMPILER_FLAGS -DCAB_BOOST)
 LIST(APPEND CAB_ADDTIONAL_COMPILER_FLAGS -DNOMINMAX)
 #LIST(APPEND CAB_ADDTIONAL_COMPILER_FLAGS -DBOOST_SIGNALS_NO_DEPRECATION_WARNING)
 #LIST(APPEND CAB_ADDTIONAL_COMPILER_FLAGS -DCAB_RUBY)
diff --git a/source/ThirdParty/Library/basics/container/CbArray3D.h b/source/ThirdParty/Library/basics/container/CbArray3D.h
index e3a172a37..56e297815 100644
--- a/source/ThirdParty/Library/basics/container/CbArray3D.h
+++ b/source/ThirdParty/Library/basics/container/CbArray3D.h
@@ -36,7 +36,6 @@
 #include <algorithm>
 #include <typeinfo>
 #include <boost/serialization/serialization.hpp>
-#include <boost/smart_ptr/shared_ptr.hpp>
 
 #ifdef CAB_RCF
    #include <3rdParty/rcf/RcfSerializationIncludes.h>
@@ -127,7 +126,7 @@ template<typename T, typename IndexClass = IndexerX3X2X1>
 class CbArray3D
 {
 public:
-   typedef boost::shared_ptr< CbArray3D <T,IndexClass> > CbArray3DPtr;
+   typedef std::shared_ptr< CbArray3D <T,IndexClass> > CbArray3DPtr;
 
    typedef T                                                   value_type;
    typedef IndexClass                                          indexer_type;
diff --git a/source/ThirdParty/Library/basics/container/CbArray4D.h b/source/ThirdParty/Library/basics/container/CbArray4D.h
index ed2e6aa77..4f63e9f76 100644
--- a/source/ThirdParty/Library/basics/container/CbArray4D.h
+++ b/source/ThirdParty/Library/basics/container/CbArray4D.h
@@ -32,7 +32,6 @@
 #include <typeinfo>
 #include <boost/serialization/serialization.hpp>
 
-#include <boost/smart_ptr/shared_ptr.hpp>
 
 
 #ifdef CAB_RCF
@@ -100,7 +99,7 @@ template<typename T, typename IndexClass = IndexerX4X3X2X1>
 class CbArray4D
 {
 public:
-   typedef boost::shared_ptr< CbArray4D <T,IndexClass> > CbArray4DPtr;
+   typedef std::shared_ptr< CbArray4D <T,IndexClass> > CbArray4DPtr;
 
    typedef T                                                   value_type;
    typedef IndexClass                                          indexer_type;
diff --git a/source/ThirdParty/Library/basics/memory/MbSharedPointerDefines.h b/source/ThirdParty/Library/basics/memory/MbSharedPointerDefines.h
index 25c9311e7..f40792bc7 100644
--- a/source/ThirdParty/Library/basics/memory/MbSharedPointerDefines.h
+++ b/source/ThirdParty/Library/basics/memory/MbSharedPointerDefines.h
@@ -3,15 +3,12 @@
 #define MBSHAREDPOINTERDEFINES_H
 
 
-// Boost includes
-#include <boost/shared_ptr.hpp>
-#include <boost/weak_ptr.hpp>
-#include <boost/enable_shared_from_this.hpp>
+#include <memory>
 
-#define VFSharedFromThis boost::enable_shared_from_this
-#define VFSharedPtr boost::shared_ptr
-#define VFWeakPtr   boost::weak_ptr
-#define VFDynamicPtrCast boost::dynamic_pointer_cast
+#define VFSharedFromThis std::enable_shared_from_this
+#define VFSharedPtr std::shared_ptr
+#define VFWeakPtr   std::weak_ptr
+#define VFDynamicPtrCast std::dynamic_pointer_cast
 
 template<typename T>
 class VFPtrDeleter
@@ -22,18 +19,4 @@ public:
 
 
 
-// std includes
-#include <vector>
-
-//#ifdef WIN32
-//#  include <memory>
-//#else
-//#  include<tr1/memory>
-//#endif
-
-//#  define DCSharedFromThis std::tr1::enable_shared_from_this
-//#  define DCSharedPtr std::tr1::shared_ptr
-//#  define DCWeakPtr   std::tr1::weak_ptr
-//#  define DCDynamicPtrCast std::tr1::dynamic_pointer_cast
-
 #endif
diff --git a/source/ThirdParty/Library/basics/utilities/UbException.h b/source/ThirdParty/Library/basics/utilities/UbException.h
index 48d1e1a60..c9e338081 100644
--- a/source/ThirdParty/Library/basics/utilities/UbException.h
+++ b/source/ThirdParty/Library/basics/utilities/UbException.h
@@ -13,8 +13,6 @@
 #include <sstream>
 #include <stdexcept>
 
-#include <boost/exception/all.hpp>
-
 #include "./UbTuple.h"
 
 /*=========================================================================*/
@@ -63,7 +61,7 @@ usage: UB_THROW( UbException("error message") );
    #define UB_THROW(e) throw e
 #endif
 
-class UbException : public std::runtime_error, public boost::exception
+class UbException : public std::runtime_error
 {
 public:
    typedef UbTuple< std::string, int, std::string, std::string > ExceptionData;
diff --git a/source/ThirdParty/Library/basics/utilities/UbLogger.h b/source/ThirdParty/Library/basics/utilities/UbLogger.h
index 7d4e432ce..e531f47f4 100644
--- a/source/ThirdParty/Library/basics/utilities/UbLogger.h
+++ b/source/ThirdParty/Library/basics/utilities/UbLogger.h
@@ -1,362 +1,361 @@
-//  _    ___      __              __________      _     __
-// | |  / (_)____/ /___  ______ _/ / ____/ /_  __(_)___/ /____
-// | | / / / ___/ __/ / / / __ `/ / /_  / / / / / / __  / ___/
-// | |/ / / /  / /_/ /_/ / /_/ / / __/ / / /_/ / / /_/ (__  )
-// |___/_/_/   \__/\__,_/\__,_/_/_/   /_/\__,_/_/\__,_/____/
-//
-#ifndef UBLOGGER_H
-#define UBLOGGER_H
-
-#include <sstream>
-#include <string>
-#include <iostream>
-#include <fstream>
-#include <iomanip>
-#include <memory>
-
-#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)  || defined(_WIN64)  || defined(__WIN64__)
-   #include <windows.h>
-#else
-   #include <sys/time.h>
-#endif
-
-#if defined(CAB_BOOST) && !defined(NO_THREADSAFE_LOGGING)
-   #include <boost/thread.hpp>
-#endif // CAB_BOOST
-
-//////////////////////////////////////////////////////////////////////////
-// UbLogger
-// C++ Logger
-// Funktionsweise:
-// pro Logeintrag wird ein UbLogger-Objekt erstellt, der logstring uebergeben und beim "zerstroeren"
-// wird der logstring mittels der entsprechenden policy (=template paramter)  z.B. in eine Datei
-// oder auf dem Bildschirm ausgegeben. Es werden verschiedene LogLevel unterstuetzt 
-//
-// Hilfsmakro:  UBLOG
-// Bsp1:        UBLOG(logINFO) << "Klasse::foo entered"; //endl wir nicht benötigt
-//              --> Eintrag:
-//
-// Bsp2: siehe Dateiende!
-//
-//Idee basierend auf: 
-//Artikel von Dr. Dobbs Portal
-//September 05, 2007
-//Logging In C++
-//
-//@author <A HREF="mailto:muffmolch@gmx.de">S. Freudiger</A>
-//@version 1.0 - 12.10.2008
-
-enum LogLevel {logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4, logDEBUG5};
-
-//////////////////////////////////////////////////////////////////////////
-// template <typename OutputPolicy> class Log  - declaration
-//////////////////////////////////////////////////////////////////////////
-template <typename OutputPolicy>
-class UbLogger
-{   
-public:
-   typedef OutputPolicy output_policy;
-public:
-    UbLogger();
-    virtual ~UbLogger();
-    std::ostringstream& get(const LogLevel& level = logINFO);
-public:
-   //static, weil man so später die ObjErstellunge ersparen kann,
-   //falls level kleiner als Level
-   static LogLevel&   reportingLevel();
-    
-    static std::string logLevelToString(const LogLevel& level);
-    static LogLevel    logLevelFromString(const std::string& level);
-
-    static std::string logTimeString();
-
-protected:
-    std::ostringstream os;
-
-private:
-    UbLogger(const UbLogger&);
-    UbLogger& operator =(const UbLogger&);
-};
-
-//////////////////////////////////////////////////////////////////////////
-// template <typename OutputPolicy> class Log  - implementation
-//////////////////////////////////////////////////////////////////////////
-template <typename OutputPolicy>
-UbLogger<OutputPolicy>::UbLogger()
-{
-}
-/*==========================================================*/
-template <typename OutputPolicy>
-std::ostringstream& UbLogger<OutputPolicy>::get(const LogLevel& level) 
-{
-   os << logTimeString() << " " << std::setw(6) 
-#if defined(CAB_BOOST) && !defined(NO_MT_LOGGING)
-      <<boost::this_thread::get_id() << " "
-#endif
-      << std::setw(8) << std::left << UbLogger<OutputPolicy>::logLevelToString(level) << ": "
-      << std::string(level > logDEBUG ? 3*(level - logDEBUG) : 0, ' '); //<baumartiger output :D
-   
-    return os;
-}
-/*==========================================================*/
-template <typename OutputPolicy>
-UbLogger<OutputPolicy>::~UbLogger()
-{
-    os << std::endl;
-    OutputPolicy::output(os.str());
-}
-/*==========================================================*/
-template <typename OutputPolicy>
-LogLevel& UbLogger<OutputPolicy>::reportingLevel()
-{
-    static LogLevel reportLevel = logINFO;
-    return reportLevel;
-}
-/*==========================================================*/
-template <typename OutputPolicy>
-std::string UbLogger<OutputPolicy>::logLevelToString(const LogLevel& level)
-{
-   static std::string const buffer[] = {"ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4", "DEBUG5"};
-   return buffer[level];
-}
-/*==========================================================*/
-template <typename OutputPolicy>
-LogLevel UbLogger<OutputPolicy>::logLevelFromString(const std::string& level)
-{
-   if (level == "DEBUG5" ) return logDEBUG5;
-   if (level == "DEBUG4" ) return logDEBUG4;
-   if (level == "DEBUG3" ) return logDEBUG3;
-   if (level == "DEBUG2" ) return logDEBUG2;
-   if (level == "DEBUG1" ) return logDEBUG1;
-   if (level == "DEBUG"  ) return logDEBUG;
-   if (level == "INFO"   ) return logINFO;
-   if (level == "WARNING") return logWARNING;
-   if (level == "ERROR"  ) return logERROR;
-       
-   UbLogger<OutputPolicy>().get(logWARNING) << "UbLogger<OutputPolicy>::logLevelFromString(level) - unknown logging level '" << level << "'. Using INFO level as default.";
-   return logINFO;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// logTimeString
-//////////////////////////////////////////////////////////////////////////
-#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)  || defined(_WIN64)  || defined(__WIN64__)
-template <typename OutputPolicy>
-inline std::string UbLogger<OutputPolicy>::logTimeString()
-{
-   const int MAX_LEN = 200;
-   char buffer[MAX_LEN];
-   if (GetTimeFormatA(LOCALE_USER_DEFAULT, 0, 0, "HH':'mm':'ss", buffer, MAX_LEN) == 0 )
-   {
-      return "Error in std::string UbLogger<OutputPolicy>::logTimeString()";
-   }
-
-   char result[100] = {0};
-   static DWORD first = GetTickCount();
-   std::sprintf(result, "%s.%03ld", buffer, (long)(GetTickCount() - first) % 1000); 
-   return result;
-}
-#else
-template <typename OutputPolicy>
-inline std::string UbLogger<OutputPolicy>::logTimeString()
-{
-   char buffer[11];
-   time_t t;
-   time(&t);
-   tm r = {0};
-   strftime(buffer, sizeof(buffer), "%X", localtime_r(&t, &r));
-   struct timeval tv;
-   gettimeofday(&tv, 0);
-   char result[100] = {0};
-   std::sprintf(result, "%s.%03ld", buffer, (long)tv.tv_usec / 1000); 
-   return result;
-}
-#endif 
-
-
-//////////////////////////////////////////////////////////////////////////
-// Output2Stream (=implementation of OutputPolicy)
-//////////////////////////////////////////////////////////////////////////
-//Anm: die erste Version mit auto_ptr fuer den stream fuehrte zu
-//     exceptions bei Verwedung vom Logger in dtors stat. globaler
-//     Objekte. Aber auch die Pointer-Lsg. ist noch nicht die 
-//     optimale Lösung
-class Output2Stream // implementation of OutputPolicy
-{
-public:
-   static std::ostream*& getStream();
-   static void output(const std::string& msg);
-   
-   //creates output-file-stream (of file opening fails -> stream is set to std::cerr)
-   static void setStream(const std::string& filename);
-   
-   //direct set outputstream, gcControl = true -> object will be deleted by Output2Stream 
-   static void setStream(std::ostream* pStream, const bool& gcControl = false);
-
-protected:
-#if defined(CAB_BOOST) && !defined(NO_MT_LOGGING)
-   static boost::mutex mtx;
-#endif
-};
-/*==========================================================*/
-inline std::ostream*& Output2Stream::getStream()
-{
-   static std::ostream* pStream = &std::clog;
-   return pStream;
-}
-/*==========================================================*/
-inline void Output2Stream::setStream(std::ostream* pFile, const bool& gcControl)
-{
-#if defined(CAB_BOOST) && !defined(NO_MT_LOGGING)
-   boost::mutex::scoped_lock lock(mtx);
-#endif
-   static bool s_gcControl = false;
-   
-   if( s_gcControl && Output2Stream::getStream() ) 
-   {
-      delete Output2Stream::getStream();
-   }
-   
-   s_gcControl = gcControl;
-   
-   Output2Stream::getStream() = pFile;
-}
-/*==========================================================*/
-inline void Output2Stream::setStream(const std::string& filename)
-{
-   std::ofstream* file = new std::ofstream( filename.c_str() );
-   if( !(*file) ) 
-   {
-      delete file;
-      Output2Stream::setStream(&std::cerr, false);
-      UbLogger<Output2Stream>().get(logERROR) << " Output2Stream::setStream(const std::string& filename) could not open file "
-                                               << filename << " -> std::cerr is used instead " << std::endl;
-      return;
-   }
-   std::cout<<"UbLog writes to "<<filename<<std::endl;
-   Output2Stream::setStream(file,true);
-}
-/*==========================================================*/
-inline void Output2Stream::output(const std::string& msg)
-{
-#if defined(CAB_BOOST) && !defined(NO_MT_LOGGING)
-   boost::mutex::scoped_lock lock(mtx);
-#endif
-   std::ostream* pStream = getStream();
-   if (!pStream) return;
-   (*pStream) << msg << std::flush;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// UbLog
-//////////////////////////////////////////////////////////////////////////
-class UbLog : public UbLogger< Output2Stream > 
-{
-public:
-   typedef Output2Stream output_policy;
-};
-
-//Makro um compilerseitig maxLevel zu beschränken
-#ifndef UBLOG_MAX_LEVEL
-   #define UBLOG_MAX_LEVEL logDEBUG5
-#endif
-
-//////////////////////////////////////////////////////////////////////////
-//Hauptmakro fuers Loggen
-// example UBLOG(logINFO) << "das ist ein log eintrag";
-//////////////////////////////////////////////////////////////////////////
-#define UBLOG(level, logtext) \
-   if(level > UBLOG_MAX_LEVEL || level > UbLog::reportingLevel() || !Output2Stream::getStream()) ; \
-   else UbLog().get(level) << logtext;                                                             
-   
-//wieso dieses Macro (was der der scheaeaeaesss???)
-// z.B. UBLOG(logDEBUG2) << "Ich bin sooo toll " << username;
-//also, was macht der praeprozessor draus?:
-// if(level > UBLOG_MAX_LEVEL || level > UbLog::reportingLevel() || !Output2Stream::getStream()) ;
-// else // Log().Get(logINFO) << "Ich bin sooo toll " << username;
-//Ergo: das prinzip des logging beruht auf: Log-Objekt erstellen und rauschreiben beim zerstoeren
-//    -> ist der zu loggende Level < als der im UBLOG angegebene erspart man sich hier die
-//       Objekt erstellung -> optimale Performance -> laut Petru Marginean (dem Verfasser des
-//       Ursprungslogger ist der Performance Unterschied kaum messbar, wenn NICHT geloggt wird!
-
-//////////////////////////////////////////////////////////////////////////
-//makro 2 fuer korrekten MultiLineOutput (teuer!!)
-// example1: UBLOGML(logINFO, "line1"<<endl<<"line2"<<endl<<"line3" )
-// example2: UBLOGML(logINFO, "line1\nline2\nendl\nline3" )
-//////////////////////////////////////////////////////////////////////////
-#define UBLOGML(level, multiline) \
-   if(level > UBLOG_MAX_LEVEL || level > UbLog::reportingLevel() || !Output2Stream::getStream()) ; \
-   else                                                                                            \
-   {                                                                                               \
-      std::ostringstream output;                                                                   \
-      output << multiline;                                                                         \
-      std::istringstream input( output.str() );                                                    \
-      while(!input.eof())                                                                          \
-      {                                                                                            \
-         std::string dummy;                                                                        \
-         getline(input,dummy,'\n');                                                                \
-         UbLog().get(level) << dummy;                                                              \
-      }                                                                                            \
-   }                                                                                          
-//////////////////////////////////////////////////////////////////////////
-//makro3, falls auch bildschirmausgabe erwünscht
-//   -> es wird sowohl ins logfile als auch auf den "stream" geschrieben
-//      wenn reporting level und level passen :D
-//example1: UBLOG2ML(logINFO, std::cout,  "line1"<<endl<<"line2"<<endl<<"line3" ) 
-//example2: UBLOG2ML(logINFO, std::cout,  "line1\nline2\nendl\nline3" ) 
-//////////////////////////////////////////////////////////////////////////
-#define UBLOG2(level, stream,  text ) \
-   if(level > UBLOG_MAX_LEVEL || level > UbLog::reportingLevel() || !Output2Stream::getStream()) ; \
-   else { stream << text <<std::endl; UbLog().get(level) << text;   }                             
-
-//////////////////////////////////////////////////////////////////////////
-//makro4, wie 3 nur mit multiline
-//example: UBLOG2(logINFO, std::cout,  "test" ) 
-//////////////////////////////////////////////////////////////////////////
-#define UBLOG2ML(level, stream,  multiline ) \
-   if(level > UBLOG_MAX_LEVEL || level > UbLog::reportingLevel() || !Output2Stream::getStream()) ; \
-   else                                                                                            \
-   {                                                                                               \
-      stream << multiline << std::endl;                                                            \
-      std::ostringstream output;                                                                   \
-      output << multiline;                                                                         \
-      std::istringstream input( output.str() );                                                    \
-      while(!input.eof())                                                                          \
-      {                                                                                            \
-         std::string dummy;                                                                        \
-         getline(input,dummy,'\n');                                                                \
-         UbLog().get(level) << dummy;                                                              \
-      }                                                                                            \
-   }                                                                                               
-
-//////////////////////////////////////////////////////////////////////////
-// example 2
-//////////////////////////////////////////////////////////////////////////
-// try
-// {
-//    UbLog::reportingLevel() = UbLog::logLevelFromString("DEBUG3");
-//    //UbLog::output_policy::setStream(&std::cerr); //<- clog ist stdandard
-//    UbLog::output_policy::setStream("c:/temp/out.txt");  //kann man diese nicht oeffnen -> fehlermeldung -> Log wird in cerr ausgegben
-// 
-//    int count = 3;
-//    UBLOG(logINFO, "A loop with " << count << " iterations");
-//    for (int i = 0; i != count; ++i)
-//    {
-//        UBLOG(logERROR , "error  - the counter i = " << i );
-//        UBLOG(logDEBUG1, "debug1 - the counter i = " << i );
-//        UBLOG(logDEBUG2, "debug2 - the counter i = " << i );
-//        UBLOG(logDEBUG3, "debug3 - the counter i = " << i );
-//        //fuer MultiLine Eintraege: --> koerrekte formatierung im logfile
-//        UBLOGML(logDEBUG3, "debug3 - the counter i = "<<endl<<" 2 zeile "<< "3. Zeile" << i);
-//        UBLOGML(logDEBUG3, "debug3 - the counter i = "<<endl<<" 2 zeile "<< "3. Zeile" << i);
-//        UBLOG2ML(logDEBUG3,std:cout,"debug3 - the counter i = "<<endl<<" 2 zeile "<< "3. Zeile" << i);
-//    }
-//    return 0;
-// }
-// catch(const std::exception& e)
-// {
-//    UBLOG(logERROR) << e.what();
-// }
-
-
-#endif //UBLOGGER_H
+//  _    ___      __              __________      _     __
+// | |  / (_)____/ /___  ______ _/ / ____/ /_  __(_)___/ /____
+// | | / / / ___/ __/ / / / __ `/ / /_  / / / / / / __  / ___/
+// | |/ / / /  / /_/ /_/ / /_/ / / __/ / / /_/ / / /_/ (__  )
+// |___/_/_/   \__/\__,_/\__,_/_/_/   /_/\__,_/_/\__,_/____/
+//
+#ifndef UBLOGGER_H
+#define UBLOGGER_H
+
+#include <sstream>
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <memory>
+
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)  || defined(_WIN64)  || defined(__WIN64__)
+   #include <windows.h>
+#else
+   #include <sys/time.h>
+#endif
+
+#if defined(CAB_BOOST) && !defined(NO_THREADSAFE_LOGGING)
+   #include <boost/thread.hpp>
+#endif // CAB_BOOST
+
+//////////////////////////////////////////////////////////////////////////
+// UbLogger
+// C++ Logger
+// Funktionsweise:
+// pro Logeintrag wird ein UbLogger-Objekt erstellt, der logstring uebergeben und beim "zerstroeren"
+// wird der logstring mittels der entsprechenden policy (=template paramter)  z.B. in eine Datei
+// oder auf dem Bildschirm ausgegeben. Es werden verschiedene LogLevel unterstuetzt 
+//
+// Hilfsmakro:  UBLOG
+// Bsp1:        UBLOG(logINFO) << "Klasse::foo entered"; //endl wir nicht benötigt
+//              --> Eintrag:
+//
+// Bsp2: siehe Dateiende!
+//
+//Idee basierend auf: 
+//Artikel von Dr. Dobbs Portal
+//September 05, 2007
+//Logging In C++
+//
+//@author <A HREF="mailto:muffmolch@gmx.de">S. Freudiger</A>
+//@version 1.0 - 12.10.2008
+
+enum LogLevel {logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4, logDEBUG5};
+
+//////////////////////////////////////////////////////////////////////////
+// template <typename OutputPolicy> class Log  - declaration
+//////////////////////////////////////////////////////////////////////////
+template <typename OutputPolicy>
+class UbLogger
+{   
+public:
+   typedef OutputPolicy output_policy;
+public:
+    UbLogger();
+    virtual ~UbLogger();
+    std::ostringstream& get(const LogLevel& level = logINFO);
+public:
+   //static, weil man so später die ObjErstellunge ersparen kann,
+   //falls level kleiner als Level
+   static LogLevel&   reportingLevel();
+    
+    static std::string logLevelToString(const LogLevel& level);
+    static LogLevel    logLevelFromString(const std::string& level);
+
+    static std::string logTimeString();
+
+protected:
+    std::ostringstream os;
+
+private:
+    UbLogger(const UbLogger&);
+    UbLogger& operator =(const UbLogger&);
+};
+
+//////////////////////////////////////////////////////////////////////////
+// template <typename OutputPolicy> class Log  - implementation
+//////////////////////////////////////////////////////////////////////////
+template <typename OutputPolicy>
+UbLogger<OutputPolicy>::UbLogger()
+{
+}
+/*==========================================================*/
+template <typename OutputPolicy>
+std::ostringstream& UbLogger<OutputPolicy>::get(const LogLevel& level) 
+{
+   os << logTimeString() << " " << std::setw(6) 
+#if defined(CAB_BOOST) && !defined(NO_MT_LOGGING)
+      <<boost::this_thread::get_id() << " "
+#endif
+      << std::setw(8) << std::left << UbLogger<OutputPolicy>::logLevelToString(level) << ": "
+      << std::string(level > logDEBUG ? 3*(level - logDEBUG) : 0, ' '); //<baumartiger output :D
+   
+    return os;
+}
+/*==========================================================*/
+template <typename OutputPolicy>
+UbLogger<OutputPolicy>::~UbLogger()
+{
+    os << std::endl;
+    OutputPolicy::output(os.str());
+}
+/*==========================================================*/
+template <typename OutputPolicy>
+LogLevel& UbLogger<OutputPolicy>::reportingLevel()
+{
+    static LogLevel reportLevel = logINFO;
+    return reportLevel;
+}
+/*==========================================================*/
+template <typename OutputPolicy>
+std::string UbLogger<OutputPolicy>::logLevelToString(const LogLevel& level)
+{
+   static std::string const buffer[] = {"ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4", "DEBUG5"};
+   return buffer[level];
+}
+/*==========================================================*/
+template <typename OutputPolicy>
+LogLevel UbLogger<OutputPolicy>::logLevelFromString(const std::string& level)
+{
+   if (level == "DEBUG5" ) return logDEBUG5;
+   if (level == "DEBUG4" ) return logDEBUG4;
+   if (level == "DEBUG3" ) return logDEBUG3;
+   if (level == "DEBUG2" ) return logDEBUG2;
+   if (level == "DEBUG1" ) return logDEBUG1;
+   if (level == "DEBUG"  ) return logDEBUG;
+   if (level == "INFO"   ) return logINFO;
+   if (level == "WARNING") return logWARNING;
+   if (level == "ERROR"  ) return logERROR;
+       
+   UbLogger<OutputPolicy>().get(logWARNING) << "UbLogger<OutputPolicy>::logLevelFromString(level) - unknown logging level '" << level << "'. Using INFO level as default.";
+   return logINFO;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// logTimeString
+//////////////////////////////////////////////////////////////////////////
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)  || defined(_WIN64)  || defined(__WIN64__)
+template <typename OutputPolicy>
+inline std::string UbLogger<OutputPolicy>::logTimeString()
+{
+   const int MAX_LEN = 200;
+   char buffer[MAX_LEN];
+   if (GetTimeFormatA(LOCALE_USER_DEFAULT, 0, 0, "HH':'mm':'ss", buffer, MAX_LEN) == 0 )
+   {
+      return "Error in std::string UbLogger<OutputPolicy>::logTimeString()";
+   }
+
+   char result[100] = {0};
+   static DWORD first = GetTickCount();
+   std::sprintf(result, "%s.%03ld", buffer, (long)(GetTickCount() - first) % 1000); 
+   return result;
+}
+#else
+template <typename OutputPolicy>
+inline std::string UbLogger<OutputPolicy>::logTimeString()
+{
+   char buffer[11];
+   time_t t;
+   time(&t);
+   tm r = {0};
+   strftime(buffer, sizeof(buffer), "%X", localtime_r(&t, &r));
+   struct timeval tv;
+   gettimeofday(&tv, 0);
+   char result[100] = {0};
+   std::sprintf(result, "%s.%03ld", buffer, (long)tv.tv_usec / 1000); 
+   return result;
+}
+#endif 
+
+
+//////////////////////////////////////////////////////////////////////////
+// Output2Stream (=implementation of OutputPolicy)
+//////////////////////////////////////////////////////////////////////////
+//Anm: die erste Version mit auto_ptr fuer den stream fuehrte zu
+//     exceptions bei Verwedung vom Logger in dtors stat. globaler
+//     Objekte. Aber auch die Pointer-Lsg. ist noch nicht die 
+//     optimale Lösung
+class Output2Stream // implementation of OutputPolicy
+{
+public:
+   static std::ostream*& getStream();
+   static void output(const std::string& msg);
+   
+   //creates output-file-stream (of file opening fails -> stream is set to std::cerr)
+   static void setStream(const std::string& filename);
+   
+   //direct set outputstream, gcControl = true -> object will be deleted by Output2Stream 
+   static void setStream(std::ostream* pStream, const bool& gcControl = false);
+
+protected:
+#if defined(CAB_BOOST) && !defined(NO_MT_LOGGING)
+   static boost::mutex mtx;
+#endif
+};
+/*==========================================================*/
+inline std::ostream*& Output2Stream::getStream()
+{
+   static std::ostream* pStream = &std::clog;
+   return pStream;
+}
+/*==========================================================*/
+inline void Output2Stream::setStream(std::ostream* pFile, const bool& gcControl)
+{
+#if defined(CAB_BOOST) && !defined(NO_MT_LOGGING)
+   boost::mutex::scoped_lock lock(mtx);
+#endif
+   static bool s_gcControl = false;
+   
+   if( s_gcControl && Output2Stream::getStream() ) 
+   {
+      delete Output2Stream::getStream();
+   }
+   
+   s_gcControl = gcControl;
+   
+   Output2Stream::getStream() = pFile;
+}
+/*==========================================================*/
+inline void Output2Stream::setStream(const std::string& filename)
+{
+   std::ofstream* file = new std::ofstream( filename.c_str() );
+   if( !(*file) ) 
+   {
+      delete file;
+      Output2Stream::setStream(&std::cerr, false);
+      UbLogger<Output2Stream>().get(logERROR) << " Output2Stream::setStream(const std::string& filename) could not open file "
+                                               << filename << " -> std::cerr is used instead " << std::endl;
+      return;
+   }
+   std::cout<<"UbLog writes to "<<filename<<std::endl;
+   Output2Stream::setStream(file,true);
+}
+/*==========================================================*/
+inline void Output2Stream::output(const std::string& msg)
+{
+#if defined(CAB_BOOST) && !defined(NO_MT_LOGGING)
+   boost::mutex::scoped_lock lock(mtx);
+#endif
+   std::ostream* pStream = getStream();
+   if (!pStream) return;
+   (*pStream) << msg << std::flush;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// UbLog
+//////////////////////////////////////////////////////////////////////////
+class UbLog : public UbLogger< Output2Stream > 
+{
+
+};
+
+//Makro um compilerseitig maxLevel zu beschränken
+#ifndef UBLOG_MAX_LEVEL
+   #define UBLOG_MAX_LEVEL logDEBUG5
+#endif
+
+//////////////////////////////////////////////////////////////////////////
+//Hauptmakro fuers Loggen
+// example UBLOG(logINFO) << "das ist ein log eintrag";
+//////////////////////////////////////////////////////////////////////////
+#define UBLOG(level, logtext) \
+   if(level > UBLOG_MAX_LEVEL || level > UbLog::reportingLevel() || !Output2Stream::getStream()) ; \
+   else UbLog().get(level) << logtext;                                                             
+   
+//wieso dieses Macro (was der der scheaeaeaesss???)
+// z.B. UBLOG(logDEBUG2) << "Ich bin sooo toll " << username;
+//also, was macht der praeprozessor draus?:
+// if(level > UBLOG_MAX_LEVEL || level > UbLog::reportingLevel() || !Output2Stream::getStream()) ;
+// else // Log().Get(logINFO) << "Ich bin sooo toll " << username;
+//Ergo: das prinzip des logging beruht auf: Log-Objekt erstellen und rauschreiben beim zerstoeren
+//    -> ist der zu loggende Level < als der im UBLOG angegebene erspart man sich hier die
+//       Objekt erstellung -> optimale Performance -> laut Petru Marginean (dem Verfasser des
+//       Ursprungslogger ist der Performance Unterschied kaum messbar, wenn NICHT geloggt wird!
+
+//////////////////////////////////////////////////////////////////////////
+//makro 2 fuer korrekten MultiLineOutput (teuer!!)
+// example1: UBLOGML(logINFO, "line1"<<endl<<"line2"<<endl<<"line3" )
+// example2: UBLOGML(logINFO, "line1\nline2\nendl\nline3" )
+//////////////////////////////////////////////////////////////////////////
+#define UBLOGML(level, multiline) \
+   if(level > UBLOG_MAX_LEVEL || level > UbLog::reportingLevel() || !Output2Stream::getStream()) ; \
+   else                                                                                            \
+   {                                                                                               \
+      std::ostringstream output;                                                                   \
+      output << multiline;                                                                         \
+      std::istringstream input( output.str() );                                                    \
+      while(!input.eof())                                                                          \
+      {                                                                                            \
+         std::string dummy;                                                                        \
+         getline(input,dummy,'\n');                                                                \
+         UbLog().get(level) << dummy;                                                              \
+      }                                                                                            \
+   }                                                                                          
+//////////////////////////////////////////////////////////////////////////
+//makro3, falls auch bildschirmausgabe erwünscht
+//   -> es wird sowohl ins logfile als auch auf den "stream" geschrieben
+//      wenn reporting level und level passen :D
+//example1: UBLOG2ML(logINFO, std::cout,  "line1"<<endl<<"line2"<<endl<<"line3" ) 
+//example2: UBLOG2ML(logINFO, std::cout,  "line1\nline2\nendl\nline3" ) 
+//////////////////////////////////////////////////////////////////////////
+#define UBLOG2(level, stream,  text ) \
+   if(level > UBLOG_MAX_LEVEL || level > UbLog::reportingLevel() || !Output2Stream::getStream()) ; \
+   else { stream << text <<std::endl; UbLog().get(level) << text;   }                             
+
+//////////////////////////////////////////////////////////////////////////
+//makro4, wie 3 nur mit multiline
+//example: UBLOG2(logINFO, std::cout,  "test" ) 
+//////////////////////////////////////////////////////////////////////////
+#define UBLOG2ML(level, stream,  multiline ) \
+   if(level > UBLOG_MAX_LEVEL || level > UbLog::reportingLevel() || !Output2Stream::getStream()) ; \
+   else                                                                                            \
+   {                                                                                               \
+      stream << multiline << std::endl;                                                            \
+      std::ostringstream output;                                                                   \
+      output << multiline;                                                                         \
+      std::istringstream input( output.str() );                                                    \
+      while(!input.eof())                                                                          \
+      {                                                                                            \
+         std::string dummy;                                                                        \
+         getline(input,dummy,'\n');                                                                \
+         UbLog().get(level) << dummy;                                                              \
+      }                                                                                            \
+   }                                                                                               
+
+//////////////////////////////////////////////////////////////////////////
+// example 2
+//////////////////////////////////////////////////////////////////////////
+// try
+// {
+//    UbLog::reportingLevel() = UbLog::logLevelFromString("DEBUG3");
+//    //UbLog::output_policy::setStream(&std::cerr); //<- clog ist stdandard
+//    UbLog::output_policy::setStream("c:/temp/out.txt");  //kann man diese nicht oeffnen -> fehlermeldung -> Log wird in cerr ausgegben
+// 
+//    int count = 3;
+//    UBLOG(logINFO, "A loop with " << count << " iterations");
+//    for (int i = 0; i != count; ++i)
+//    {
+//        UBLOG(logERROR , "error  - the counter i = " << i );
+//        UBLOG(logDEBUG1, "debug1 - the counter i = " << i );
+//        UBLOG(logDEBUG2, "debug2 - the counter i = " << i );
+//        UBLOG(logDEBUG3, "debug3 - the counter i = " << i );
+//        //fuer MultiLine Eintraege: --> koerrekte formatierung im logfile
+//        UBLOGML(logDEBUG3, "debug3 - the counter i = "<<endl<<" 2 zeile "<< "3. Zeile" << i);
+//        UBLOGML(logDEBUG3, "debug3 - the counter i = "<<endl<<" 2 zeile "<< "3. Zeile" << i);
+//        UBLOG2ML(logDEBUG3,std:cout,"debug3 - the counter i = "<<endl<<" 2 zeile "<< "3. Zeile" << i);
+//    }
+//    return 0;
+// }
+// catch(const std::exception& e)
+// {
+//    UBLOG(logERROR) << e.what();
+// }
+
+
+#endif //UBLOGGER_H
diff --git a/source/ThirdParty/Library/basics/utilities/UbMath.cpp b/source/ThirdParty/Library/basics/utilities/UbMath.cpp
index ad38b9cf9..14c5fcf3b 100644
--- a/source/ThirdParty/Library/basics/utilities/UbMath.cpp
+++ b/source/ThirdParty/Library/basics/utilities/UbMath.cpp
@@ -2,613 +2,5 @@
 #include <basics/utilities/UbInfinity.h>
 #include <cstring> //for memcmp
 
-// namespace UbMath
-// {
-//double UbMath::EPSILON  = 1.0E-10;           
+       
 const double UbMath::PI = 4.0* std::atan(1.0);   //3.1415926535897932384626433832795
-//}
-namespace UbMath{
-
-//////////////////////////////////////////////////////////////////////////
-const Vector3D Vector3D::ZERO(0.0,0.0,0.0);
-const Vector3D Vector3D::UNIT_X1(1.0,0.0,0.0);
-const Vector3D Vector3D::UNIT_X2(0.0,1.0,0.0);
-const Vector3D Vector3D::UNIT_X3(0.0,0.0,1.0);
-
-/*=======================================================*/
-Vector3D::Vector3D() 
-{                                      
-   m_afTuple[0] = 0.0;
-   m_afTuple[1] = 0.0;
-   m_afTuple[2] = 0.0;
-}
-/*=======================================================*/
-Vector3D::Vector3D(const double& fX, const double& fY, const double& fZ) 
-{
-   m_afTuple[0] = fX;
-   m_afTuple[1] = fY;
-   m_afTuple[2] = fZ;
-}
-/*=======================================================*/
-Vector3D::Vector3D (const Vector3D& rkV) 
-{
-   m_afTuple[0] = rkV.m_afTuple[0];
-   m_afTuple[1] = rkV.m_afTuple[1];
-   m_afTuple[2] = rkV.m_afTuple[2];
-}
-/*=======================================================*/
-std::string Vector3D::toString()  const
-{
-   std::stringstream os;
-   os<< "Vector3D["<<m_afTuple[0]<<","<<m_afTuple[1]<<","<<m_afTuple[2]<<"]";
-   return os.str();
-}
-/*=======================================================*/
-Vector3D::operator const double*() const
-{
-   return m_afTuple;
-}
-/*=======================================================*/
-Vector3D::operator double*()
-{
-   return m_afTuple;
-}
-/*=======================================================*/
-double Vector3D::operator[](const int& i) const
-{
-   assert( i >= 0 && i <= 2 );
-   return m_afTuple[i];
-}
-/*=======================================================*/
-double& Vector3D::operator[](const int& i)
-{
-   assert( i >= 0 && i <= 2 );
-   return m_afTuple[i];
-}
-/*=======================================================*/
-double Vector3D::X1() const
-{
-   return m_afTuple[0];
-}
-/*=======================================================*/
-double& Vector3D::X1()
-{
-   return m_afTuple[0];
-}
-/*=======================================================*/
-double Vector3D::X2() const
-{
-   return m_afTuple[1];
-}
-/*=======================================================*/
-double& Vector3D::X2()
-{
-   return m_afTuple[1];
-}
-/*=======================================================*/
-double Vector3D::X3() const
-{
-   return m_afTuple[2];
-}
-/*=======================================================*/
-double& Vector3D::X3()
-{
-   return m_afTuple[2];
-}
-/*=======================================================*/
-Vector3D& Vector3D::operator=(const Vector3D& rkV)
-{
-   m_afTuple[0] = rkV.m_afTuple[0];
-   m_afTuple[1] = rkV.m_afTuple[1];
-   m_afTuple[2] = rkV.m_afTuple[2];
-   return *this;
-}
-/*=======================================================*/
-int Vector3D::CompareArrays(const Vector3D& rkV) const
-{
-   return memcmp(m_afTuple,rkV.m_afTuple,3*sizeof(double));
-}
-/*=======================================================*/
-bool Vector3D::operator==(const Vector3D& rkV) const
-{
-   return CompareArrays(rkV) == 0;
-}
-/*=======================================================*/
-bool Vector3D::operator!=(const Vector3D& rkV) const
-{
-   return CompareArrays(rkV) != 0;
-}
-/*=======================================================*/
-bool Vector3D::operator<(const Vector3D& rkV) const
-{
-   return CompareArrays(rkV) < 0;
-}
-/*=======================================================*/
-bool Vector3D::operator<=(const Vector3D& rkV) const
-{
-   return CompareArrays(rkV) <= 0;
-}
-/*=======================================================*/
-bool Vector3D::operator> (const Vector3D& rkV) const
-{
-   return CompareArrays(rkV) > 0;
-}
-/*=======================================================*/
-bool Vector3D::operator>=(const Vector3D& rkV) const
-{
-   return CompareArrays(rkV) >= 0;
-}
-/*=======================================================*/
-Vector3D Vector3D::operator+(const Vector3D& rkV) const
-{
-   return Vector3D( m_afTuple[0]+rkV.m_afTuple[0],
-                    m_afTuple[1]+rkV.m_afTuple[1],
-                    m_afTuple[2]+rkV.m_afTuple[2] );
-}
-/*=======================================================*/
-Vector3D Vector3D::Add(Vector3D& vector)
-{
-   return Vector3D( m_afTuple[0]+vector.m_afTuple[0],
-                    m_afTuple[1]+vector.m_afTuple[1],
-                    m_afTuple[2]+vector.m_afTuple[2] );
-}
-/*=======================================================*/
-Vector3D Vector3D::operator- (const Vector3D& rkV) const
-{
-   return Vector3D( m_afTuple[0]-rkV.m_afTuple[0],
-                    m_afTuple[1]-rkV.m_afTuple[1],
-                    m_afTuple[2]-rkV.m_afTuple[2] );
-}
-/*=======================================================*/
-Vector3D Vector3D::Subtract(Vector3D& vector)
-{
-   return Vector3D( m_afTuple[0]-vector.m_afTuple[0],
-                    m_afTuple[1]-vector.m_afTuple[1],
-                    m_afTuple[2]-vector.m_afTuple[2] );
-}
-/*=======================================================*/
-Vector3D Vector3D::operator*(const double& fScalar) const
-{
-   return Vector3D( fScalar*m_afTuple[0],
-                    fScalar*m_afTuple[1],
-                    fScalar*m_afTuple[2]  );
-}
-/*=======================================================*/
-Vector3D Vector3D::operator/(const double& fScalar) const
-{
-   Vector3D kQuot;
-
-   if ( fScalar != 0.0 )
-   {
-      double fInvScalar = 1.0/fScalar;
-      kQuot.m_afTuple[0] = fInvScalar*m_afTuple[0];
-      kQuot.m_afTuple[1] = fInvScalar*m_afTuple[1];
-      kQuot.m_afTuple[2] = fInvScalar*m_afTuple[2];
-   }
-   else
-   {
-      kQuot.m_afTuple[0] = Ub::inf;
-      kQuot.m_afTuple[1] = Ub::inf;
-      kQuot.m_afTuple[2] = Ub::inf;
-   }
-
-   return kQuot;
-}
-/*=======================================================*/
-Vector3D Vector3D::operator-() const
-{
-   return Vector3D( -m_afTuple[0],
-                    -m_afTuple[1],
-                    -m_afTuple[2] );
-}
-/*=======================================================*/
-Vector3D& Vector3D::operator+=(const Vector3D& rkV)
-{
-   m_afTuple[0] += rkV.m_afTuple[0];
-   m_afTuple[1] += rkV.m_afTuple[1];
-   m_afTuple[2] += rkV.m_afTuple[2];
-   return *this;
-}
-/*=======================================================*/
-Vector3D& Vector3D::operator-=(const Vector3D& rkV)
-{
-   m_afTuple[0] -= rkV.m_afTuple[0];
-   m_afTuple[1] -= rkV.m_afTuple[1];
-   m_afTuple[2] -= rkV.m_afTuple[2];
-   return *this;
-}
-/*=======================================================*/
-Vector3D& Vector3D::operator*=(const double& fScalar)
-{
-   m_afTuple[0] *= fScalar;
-   m_afTuple[1] *= fScalar;
-   m_afTuple[2] *= fScalar;
-   return *this;
-}
-/*=======================================================*/
-Vector3D& Vector3D::operator/=(const double& fScalar)
-{
-   if ( !zero(fScalar) )
-   {
-      double fInvScalar = 1.0/fScalar;
-      m_afTuple[0] *= fInvScalar;
-      m_afTuple[1] *= fInvScalar;
-      m_afTuple[2] *= fInvScalar;
-   }
-   else
-   {
-      m_afTuple[0] = Ub::inf;
-      m_afTuple[1] = Ub::inf;
-      m_afTuple[2] = Ub::inf;
-   }
-
-   return *this;
-}
-/*=======================================================*/
-Vector3D Vector3D::Scale(const double& x)
-{
-   Vector3D PointA(0.0,0.0,0.0);
-   PointA.m_afTuple[0] = x * m_afTuple[0];
-   PointA.m_afTuple[1] = x * m_afTuple[1];
-   PointA.m_afTuple[2] = x * m_afTuple[2];
-   return PointA;	
-}
-/*=======================================================*/
-double Vector3D::Length() const
-{
-   return std::sqrt( m_afTuple[0]*m_afTuple[0] +
-                     m_afTuple[1]*m_afTuple[1] +
-                     m_afTuple[2]*m_afTuple[2] );
-}
-/*=======================================================*/
-double Vector3D::SquaredLength() const
-{
-   return m_afTuple[0]*m_afTuple[0] +
-          m_afTuple[1]*m_afTuple[1] +
-          m_afTuple[2]*m_afTuple[2];
-}
-/*=======================================================*/
-double Vector3D::Dot(const Vector3D& rkV) const
-{
-   return m_afTuple[0]*rkV.m_afTuple[0] +
-          m_afTuple[1]*rkV.m_afTuple[1] +
-          m_afTuple[2]*rkV.m_afTuple[2];
-}
-/*=======================================================*/
-double Vector3D::Normalize()
-{
-   double fLength = Length();
-
-   if( !zero(fLength) )
-   {
-      double fInvLength = 1.0/fLength;
-      m_afTuple[0] *= fInvLength;
-      m_afTuple[1] *= fInvLength;
-      m_afTuple[2] *= fInvLength;
-   }
-   else
-   {
-      fLength = 0.0;
-      m_afTuple[0] = 0.0;
-      m_afTuple[1] = 0.0;
-      m_afTuple[2] = 0.0;
-   }
-
-   return fLength;
-}
-/*=======================================================*/
-Vector3D Vector3D::Cross(const Vector3D& rkV) const
-{
-   return Vector3D( m_afTuple[1]*rkV.m_afTuple[2] - m_afTuple[2]*rkV.m_afTuple[1],
-                    m_afTuple[2]*rkV.m_afTuple[0] - m_afTuple[0]*rkV.m_afTuple[2],
-                    m_afTuple[0]*rkV.m_afTuple[1] - m_afTuple[1]*rkV.m_afTuple[0] );
-}
-/*=======================================================*/
-Vector3D Vector3D::UnitCross(const Vector3D& rkV) const
-{
-   Vector3D kCross( m_afTuple[1]*rkV.m_afTuple[2] - m_afTuple[2]*rkV.m_afTuple[1],
-                    m_afTuple[2]*rkV.m_afTuple[0] - m_afTuple[0]*rkV.m_afTuple[2],
-                    m_afTuple[0]*rkV.m_afTuple[1] - m_afTuple[1]*rkV.m_afTuple[0] );
-   kCross.Normalize();
-   return kCross;
-}
-/*=======================================================*/
-void Vector3D::GetBarycentrics(const Vector3D& rkV0,const Vector3D& rkV1, const Vector3D& rkV2,const Vector3D& rkV3, double afBary[4]) const
-{
-   // compute the vectors relative to V3 of the tetrahedron
-   Vector3D akDiff[4] = { rkV0  - rkV3,
-                          rkV1  - rkV3,
-                          rkV2  - rkV3,
-                          *this - rkV3 };
-
-   // If the vertices have large magnitude, the linear system of
-   // equations for computing barycentric coordinates can be
-   // ill-conditioned.  To avoid this, uniformly scale the tetrahedron
-   // edges to be of order 1.  The scaling of all differences does not
-   // change the barycentric coordinates.
-   double fMax = 0.0,fValue=0.0;
-   for(int i=0; i<3; i++)
-      for (int j=0; j<3; j++)
-      {
-         fValue = std::fabs(akDiff[i][j]);
-         if ( fValue > fMax )  fMax = fValue;
-      }
-   
-   // scale down only large data
-   if( greater(fMax,1.0) )
-   {
-      double fInvMax = ((double)1.0)/fMax;
-      for( int i=0; i<4; i++)
-         akDiff[i] *= fInvMax;
-   }
-
-   double     fDet = akDiff[0].Dot(akDiff[1].Cross(akDiff[2]));
-   Vector3D kE1cE2 = akDiff[1].Cross(akDiff[2]);
-   Vector3D kE2cE0 = akDiff[2].Cross(akDiff[0]);
-   Vector3D kE0cE1 = akDiff[0].Cross(akDiff[1]);
-   
-   if( !zero( fDet ) )
-   {
-      double fInvDet = 1.0/fDet;
-      afBary[0] = akDiff[3].Dot(kE1cE2)*fInvDet;
-      afBary[1] = akDiff[3].Dot(kE2cE0)*fInvDet;
-      afBary[2] = akDiff[3].Dot(kE0cE1)*fInvDet;
-      afBary[3] = 1.0 - afBary[0] - afBary[1] - afBary[2];
-   }
-   else
-   {
-      // The tetrahedron is potentially flat.  Determine the face of
-      // maximum area and compute barycentric coordinates with respect
-      // to that face.
-      Vector3D kE02 = rkV0 - rkV2;
-      Vector3D kE12 = rkV1 - rkV2;
-      Vector3D kE02cE12 = kE02.Cross(kE12);
-      double fMaxSqrArea = kE02cE12.SquaredLength();
-      int iMaxIndex = 3;
-      double fSqrArea = kE0cE1.SquaredLength();
-      if ( fSqrArea > fMaxSqrArea )
-      {
-         iMaxIndex = 0;
-         fMaxSqrArea = fSqrArea;
-      }
-      fSqrArea = kE1cE2.SquaredLength();
-      if ( fSqrArea > fMaxSqrArea )
-      {
-         iMaxIndex = 1;
-         fMaxSqrArea = fSqrArea;
-      }
-      fSqrArea = kE2cE0.SquaredLength();
-      if ( fSqrArea > fMaxSqrArea )
-      {
-         iMaxIndex = 2;
-         fMaxSqrArea = fSqrArea;
-      }
-
-      if ( greater(fMaxSqrArea,0.0)  )
-      {
-         double fInvSqrArea = 1.0/fMaxSqrArea;
-         Vector3D kTmp;
-         if( iMaxIndex==0 )
-         {
-            kTmp      = akDiff[3].Cross(akDiff[1]);
-            afBary[0] = kE0cE1.Dot(kTmp)*fInvSqrArea;
-            kTmp      = akDiff[0].Cross(akDiff[3]);
-            afBary[1] = kE0cE1.Dot(kTmp)*fInvSqrArea;
-            afBary[2] = 0.0;
-            afBary[3] = 1.0 - afBary[0] - afBary[1];
-         }
-         else if( iMaxIndex == 1 )
-         {
-            afBary[0] = 0.0;
-            kTmp      = akDiff[3].Cross(akDiff[2]);
-            afBary[1] = kE1cE2.Dot(kTmp)*fInvSqrArea;
-            kTmp      = akDiff[1].Cross(akDiff[3]);
-            afBary[2] = kE1cE2.Dot(kTmp)*fInvSqrArea;
-            afBary[3] = 1.0 - afBary[1] - afBary[2];
-         }
-         else if( iMaxIndex == 2 )
-         {
-            kTmp      = akDiff[2].Cross(akDiff[3]);
-            afBary[0] = kE2cE0.Dot(kTmp)*fInvSqrArea;
-            afBary[1] = 0.0;
-            kTmp      = akDiff[3].Cross(akDiff[0]);
-            afBary[2] = kE2cE0.Dot(kTmp)*fInvSqrArea;
-            afBary[3] = 1.0 - afBary[0] - afBary[2];
-         }
-         else
-         {
-            akDiff[3] = *this - rkV2;
-            kTmp      = akDiff[3].Cross(kE12);
-            afBary[0] = kE02cE12.Dot(kTmp)*fInvSqrArea;
-            kTmp      = kE02.Cross(akDiff[3]);
-            afBary[1] = kE02cE12.Dot(kTmp)*fInvSqrArea;
-            afBary[2] = 1.0 - afBary[0] - afBary[1];
-            afBary[3] = 0.0;
-         }
-      }
-      else
-      {
-         // The tetrahedron is potentially a sliver.  Determine the edge of
-         // maximum length and compute barycentric coordinates with respect
-         // to that edge.
-         double fMaxSqrLength = akDiff[0].SquaredLength();
-         iMaxIndex            = 0;  // <V0,V3>
-         double fSqrLength    = akDiff[1].SquaredLength();
-         
-         if( fSqrLength > fMaxSqrLength )
-         {
-            iMaxIndex     = 1;  // <V1,V3>
-            fMaxSqrLength = fSqrLength;
-         }
-         fSqrLength = akDiff[2].SquaredLength();
-         
-         if( fSqrLength > fMaxSqrLength )
-         {
-            iMaxIndex     = 2;  // <V2,V3>
-            fMaxSqrLength = fSqrLength;
-         }
-         fSqrLength = kE02.SquaredLength();
-         
-         if( fSqrLength > fMaxSqrLength )
-         {
-            iMaxIndex     = 3;  // <V0,V2>
-            fMaxSqrLength = fSqrLength;
-         }
-         fSqrLength = kE12.SquaredLength();
-         
-         if( fSqrLength > fMaxSqrLength )
-         {
-            iMaxIndex     = 4;  // <V1,V2>
-            fMaxSqrLength = fSqrLength;
-         }
-         
-         Vector3D kE01 = rkV0 - rkV1;
-         fSqrLength    = kE01.SquaredLength();
-         
-         if( fSqrLength > fMaxSqrLength )
-         {
-            iMaxIndex     = 5;  // <V0,V1>
-            fMaxSqrLength = fSqrLength;
-         }
-
-         if( greater(fMaxSqrLength, 0.0) )
-         {
-            double fInvSqrLength = 1.0/fMaxSqrLength;
-            if( iMaxIndex == 0 )
-            {
-               // P-V3 = t*(V0-V3)
-               afBary[0] = akDiff[3].Dot(akDiff[0])*fInvSqrLength;
-               afBary[1] = 0.0;
-               afBary[2] = 0.0;
-               afBary[3] = 1.0 - afBary[0];
-            }
-            else if( iMaxIndex == 1 )
-            {
-               // P-V3 = t*(V1-V3)
-               afBary[0] = 0.0;
-               afBary[1] = akDiff[3].Dot(akDiff[1])*fInvSqrLength;
-               afBary[2] = 0.0;
-               afBary[3] = 1.0 - afBary[1];
-            }
-            else if( iMaxIndex == 2 )
-            {
-               // P-V3 = t*(V2-V3)
-               afBary[0] = 0.0;
-               afBary[1] = 0.0;
-               afBary[2] = akDiff[3].Dot(akDiff[2])*fInvSqrLength;
-               afBary[3] = 1.0 - afBary[2];
-            }
-            else if( iMaxIndex == 3 )
-            {      
-               // P-V2 = t*(V0-V2)
-               akDiff[3] = *this - rkV2;
-               afBary[0] = akDiff[3].Dot(kE02)*fInvSqrLength;
-               afBary[1] = 0.0;
-               afBary[2] = 1.0 - afBary[0];
-               afBary[3] = 0.0;
-            }
-            else if( iMaxIndex == 4 )
-            {
-               // P-V2 = t*(V1-V2)
-               akDiff[3] = *this - rkV2;
-               afBary[0] = 0.0;
-               afBary[1] = akDiff[3].Dot(kE12)*fInvSqrLength;
-               afBary[2] = 1.0 - afBary[1];
-               afBary[3] = 0.0;
-            }
-            else
-            {
-               // P-V1 = t*(V0-V1)
-               akDiff[3] = *this - rkV1;
-               afBary[0] = akDiff[3].Dot(kE01)*fInvSqrLength;
-               afBary[1] = 1.0 - afBary[0];
-               afBary[2] = 0.0;
-               afBary[3] = 0.0;
-            }
-         }
-         else
-         {
-            // tetrahedron is a nearly a point, just return equal weights
-            afBary[0] = 0.25;
-            afBary[1] = afBary[0];
-            afBary[2] = afBary[0];
-            afBary[3] = afBary[0];
-         }
-      }
-   }
-}
-/*=======================================================*/
-void Vector3D::Orthonormalize(Vector3D& rkU, Vector3D& rkV, Vector3D& rkW)
-{
-   // If the input vectors are v0, v1, and v2, then the Gram-Schmidt
-   // orthonormalization produces vectors u0, u1, and u2 as follows,
-   //
-   //   u0 = v0/|v0|
-   //   u1 = (v1-(u0*v1)u0)/|v1-(u0*v1)u0|
-   //   u2 = (v2-(u0*v2)u0-(u1*v2)u1)/|v2-(u0*v2)u0-(u1*v2)u1|
-   //
-   // where |A| indicates length of vector A and A*B indicates dot
-   // product of vectors A and B.
-
-   // compute u0
-   rkU.Normalize();
-
-   // compute u1
-   double fDot0 = rkU.Dot(rkV); 
-   rkV -= fDot0*rkU;
-   rkV.Normalize();
-
-   // compute u2
-   double fDot1 = rkV.Dot(rkW);
-   fDot0 = rkU.Dot(rkW);
-   rkW  -= fDot0*rkU + fDot1*rkV;
-   rkW.Normalize();
-}
-/*=======================================================*/
-void Vector3D::Orthonormalize(Vector3D* akV)
-{
-   Orthonormalize(akV[0],akV[1],akV[2]);
-}
-/*=======================================================*/
-void Vector3D::GenerateOrthonormalBasis(Vector3D& rkU, Vector3D& rkV,Vector3D& rkW, bool bUnitLengthW)
-{
-   if ( !bUnitLengthW )
-      rkW.Normalize();
-
-   double fInvLength;
-
-   if ( greaterEqual( std::fabs(rkW.m_afTuple[0]),std::fabs(rkW.m_afTuple[1]) ) )
-   {
-      // W.x or W.z is the largest magnitude component, swap them
-      fInvLength = UbMath::invSqrt(rkW.m_afTuple[0]*rkW.m_afTuple[0] + rkW.m_afTuple[2]*rkW.m_afTuple[2]);
-      rkU.m_afTuple[0] = -rkW.m_afTuple[2]*fInvLength;
-      rkU.m_afTuple[1] = (double)0.0;
-      rkU.m_afTuple[2] = +rkW.m_afTuple[0]*fInvLength;
-   }
-   else
-   {
-      // W.y or W.z is the largest magnitude component, swap them
-      fInvLength = UbMath::invSqrt(rkW.m_afTuple[1]*rkW.m_afTuple[1] + rkW.m_afTuple[2]*rkW.m_afTuple[2]);
-      rkU.m_afTuple[0] = (double)0.0;
-      rkU.m_afTuple[1] = +rkW.m_afTuple[2]*fInvLength;
-      rkU.m_afTuple[2] = -rkW.m_afTuple[1]*fInvLength;
-   }
-
-   rkV = rkW.Cross(rkU);
-}
-/*=======================================================*/
-//globaler operator* 
-Vector3D operator*(const double& fScalar, const Vector3D& rkV)
-{
-   return Vector3D( fScalar*rkV[0],
-                    fScalar*rkV[1],
-                    fScalar*rkV[2] );
-}
-/*=======================================================*/
-std::ostream& operator* (std::ostream& os, const Vector3D& rkV)
-{
-   os<<rkV.toString();
-   return os;
-}
-} //end namespace UbMath
-
diff --git a/source/ThirdParty/Library/basics/utilities/UbMath.h b/source/ThirdParty/Library/basics/utilities/UbMath.h
index 2b33eb532..98034171b 100644
--- a/source/ThirdParty/Library/basics/utilities/UbMath.h
+++ b/source/ThirdParty/Library/basics/utilities/UbMath.h
@@ -1,570 +1,464 @@
-//  _    ___      __              __________      _     __
-// | |  / (_)____/ /___  ______ _/ / ____/ /_  __(_)___/ /____
-// | | / / / ___/ __/ / / / __ `/ / /_  / / / / / / __  / ___/
-// | |/ / / /  / /_/ /_/ / /_/ / / __/ / / /_/ / / /_/ (__  )
-// |___/_/_/   \__/\__,_/\__,_/_/_/   /_/\__,_/_/\__,_/____/
-//
-#ifndef UBMATH_H
-#define UBMATH_H
-
-#include <cmath>
-#include <limits>
-#include <iostream>
-#include <cassert>
-#include <basics/utilities/UbSystem.h>
-#include <basics/utilities/UbEqual.h>
-
-/*=========================================================================*/
-/*  UbMath                                                             */
-/*                                                                         */
-/**
-namespace for global math-functions
-<BR><BR>
-@author <A HREF="mailto:muffmolch@gmx.de">S. Freudiger</A>
-@version 1.4 - 04.10.07
-*/ 
-
-/*
-usage: ...
-*/
-
-namespace UbMath 
-{
-   extern const double PI;
-   
-   
-   //////////////////////////////////////////////////////////////////////////
-   //Hilfsfunktion fuer Genauigkeit
-   template< typename T >
-   struct Epsilon {  };
-
-   //////////////////////////////////////////////////////////////////////////
-   //  SPECIALIZATIONS von Epsilon
-   //////////////////////////////////////////////////////////////////////////
-   template<>
-   struct Epsilon<double>        { static inline double      val() { return 1.0E-11; } };
-   template<>
-   struct Epsilon<float>         { static inline float       val() { return 1.0E-7f; } };
-   template<>
-   struct Epsilon<long double>   { static inline long double val() { return 1.0E-15; } };
-   template<>
-   struct Epsilon<int>           { static inline int         val() { return 0;       } };
-
-   /*=======================================================*/
-   // -------------------------------------------------------------------------------------------------
-   // Funktion berechnet den Logarithmus einer Zahl z bzgl. der Basis b
-   // -------------------------------------------------------------------------------------------------
-   template<typename T>
-   inline T log(const T& z, const T& base)
-   {
-      if( ::log(base)==0 ) return 1.0f;
-      return ::log(z) / ::log(base);
-   }
-   /*=======================================================*/
-   //double x = UbMath::getNegativeInfinity<double>();
-   template<typename T>
-   inline T getNegativeInfinity()
-   {
-      //assert(std::numeric_limits<T>::has_infinity);
-      UB_STATIC_ASSERT(std::numeric_limits<T>::has_infinity);
-      return -std::numeric_limits<T>::infinity();
-   }
-   /*=======================================================*/
-   //double x = UbMath::getPositiveInfinity<double>();
-   template<typename T>
-   inline T getPositiveInfinity()
-   {
-      //assert(std::numeric_limits<T>::has_infinity);
-      UB_STATIC_ASSERT(std::numeric_limits<T>::has_infinity);
-      return std::numeric_limits<T>::infinity();
-   }
-   /*=======================================================*/
-   //double x; bool b = UbMath::isInfinity(x);
-   template<typename T>
-   inline bool isInfinity(const T& value)
-   {
-      if(value==getNegativeInfinity<T>()) return true;
-      if(value==getPositiveInfinity<T>()) return true;
-      return false;
-   }
-   /*=======================================================*/
-   //double x = UbMath::getNaN<double>(x);
-   template<typename T>
-   inline T getNaN()
-   {
-      UB_STATIC_ASSERT(std::numeric_limits<T>::has_quiet_NaN);
-      return std::numeric_limits<T>::quiet_NaN();
-   }
-   /*=======================================================*/
-   //double x; bool b = UbMath::isNaN(x);
-   // x!=x liefert bei #QNAN "true"!
-   template<typename T>
-   inline bool isNaN(const T& x)
-   {
-      UB_STATIC_ASSERT(std::numeric_limits<T>::has_quiet_NaN);
-      return (x != x); 
-   }
-   /*=======================================================*/
-   template<typename T>
-   inline T getEqualityEpsilon()		  
-   { 
-      return  Epsilon<T>::val();  
-   }
-   /*=======================================================*/
-   template<typename T>
-   inline bool zero(const T& value)		  
-   { 
-      return std::fabs( value ) < Epsilon<T>::val();
-      //return value >= -UbMath::EPSILON && value <= UbMath::EPSILON;	
-   }
-   /*=======================================================*/
-   //spezialisierung fuer ints
-   template<>
-   inline bool zero(const int& value)		  
-   { 
-      return value == 0;
-   }
-   /*=======================================================*/
-   template<typename T1, typename T2>
-   inline bool zero(const T1& value1, const T2& value2)		  
-   { 
-      return !(!UbMath::zero(value1) || !UbMath::zero(value2));	
-   }
-   /*=======================================================*/
-   template<typename T1, typename T2, typename T3>
-   inline bool zero(const T1& value1, const T2& value2, const T3& value3)		  
-   { 
-      return !(!UbMath::zero(value1) || !UbMath::zero(value2,value3));	
-   }
-   /*=======================================================*/
-   template<typename T>
-   inline bool negative(const T& value)    
-   { 
-      return value < -Epsilon<T>::val();  
-   }
-   /*=======================================================*/
-   template<typename T>
-   inline bool nonPositive(const T& value) 
-   { 
-      return value <= Epsilon<T>::val(); 
-   }
-   /*=======================================================*/
-   template<typename T>
-   inline bool positive(const T& value)    
-   { 
-      return value > +Epsilon<T>::val();   
-   }
-   /*=======================================================*/
-   template<typename T>
-   inline bool nonNegative(const T& value) 
-   { 
-      return value >= -Epsilon<T>::val(); 
-   }
-   /*=======================================================*/
-   template<typename T1, typename T2>
-   inline bool equal(const T1& value, const T2& reference) 
-   { 
-      typedef typename UbEqualTrait<T1,T2>::High High;
-      return std::fabs(value-reference) < Epsilon<High>::val(); 
-   }
-   /*=======================================================*/
-   template<typename T1, typename T2, typename T3>
-   inline bool equal(const T1& val1, const T2& val2, const T3& val3) 
-   { 
-      return ( UbMath::equal(val1,val2) && UbMath::equal(val1,val3) ); 
-   }
-   /*=======================================================*/
-   template<typename T1, typename T2>
-   inline bool less(const T1& value, const T2& reference)   
-   { 
-      typedef typename UbEqualTrait<T1,T2>::High High;
-      return value < reference - Epsilon<High>::val(); 
-   }
-   /*=======================================================*/
-   template<typename T1, typename T2>
-   inline bool lessEqual(const T1& value, const T2& reference) 
-   { 
-      typedef typename UbEqualTrait<T1,T2>::High High;
-      return value <= reference + Epsilon<High>::val();
-   }
-   /*=======================================================*/
-   template<typename T1, typename T2>
-   inline bool greater(const T1& value, const T2& reference)      
-   { 
-      typedef typename UbEqualTrait<T1,T2>::High High;
-      return value > reference + Epsilon<High>::val();  
-   }
-   /*=======================================================*/
-   template<typename T1, typename T2>
-   inline bool greaterEqual(const T1& value, const T2& reference) 
-   { 
-      typedef typename UbEqualTrait<T1,T2>::High High;
-      return value >= reference - Epsilon<High>::val(); 
-   }
-   /*=======================================================*/
-   template<typename T>
-   inline T round(const T& value, const int& decimalPlaces) 
-   { 
-      return static_cast<T>(floor(value * pow( 10.0, decimalPlaces) + 0.5 ) * pow(10.0, -decimalPlaces)); 
-   } 
-   /*=======================================================*/
-   template<typename T>
-   inline int integerRounding(const T& value) 
-   { 
-      return static_cast<int>( UbMath::zero(value) ?  0 : ( (value<0.0) ? (value-0.5) : (value+0.5) ) );
-   } 
-   /*=======================================================*/
-   template<typename T>
-   inline T getRad(const T& degrees) 
-   {
-      return degrees*static_cast<T>(UbMath::PI/180.0);
-   }
-   /*=======================================================*/
-   template<typename T>
-   inline T getDegrees(const T& rad) 
-   {
-      return rad*static_cast<T>(UbMath::PI/180.0);
-   }
-   /*=======================================================*/
-   //aus wildmagic
-   template<typename T>
-   inline T ACos (const T& fValue)
-   {
-      if ( -1.0 < fValue )
-      {
-         if ( fValue < 1.0 ) return static_cast<T>( acos(fValue) );
-         else                return static_cast<T>( 0.0          );
-      }
-      else return static_cast<T>( PI );
-   }
-   /*=======================================================*/
-   template<typename T>
-   inline T ASin(const T& fValue)
-   {
-      double HALF_PI = 0.5*UbMath::PI;
-      if ( -1.0 < fValue )
-      {
-         if ( fValue < 1.0 ) return static_cast<T>( asin(fValue) );
-         else                return static_cast<T>( HALF_PI      );
-      }
-      else return -static_cast<T>( HALF_PI );         
-   }
-   /*=======================================================*/
-   template<typename T>
-   inline T invSqrt(const T& fValue)   
-   { 
-      return static_cast<T>(1.0/sqrt(fValue));
-   }
-
-   /*=======================================================*/
-   /**
-   * Returns true, if specified values a and b are less both values c and d.
-   * @param a the first value to check
-   * @param b the second value to check
-   * @param c the first value to check against
-   * @param d the second value to check against
-   * @return true, if specified values a and b are less both values c and d
-   **/
-   template<typename T1, typename T2, typename T3, typename T4>
-   inline bool less2(const T1& value1, const T2& value2, T3 toBeLessAs1, T4 toBeLessAs2) 
-   {	
-      return (   less(value1,toBeLessAs1)
-              && less(value1,toBeLessAs2)
-              && less(value2,toBeLessAs1)
-              && less(value2,toBeLessAs2) );
-   }
-   /*=======================================================*/
-   template<typename T1, typename T2, typename T3, typename T4>
-   inline bool greater2(const T1& value1, const T2& value2, T3 toBeGreaterAs1, T4 toBeGreaterAs2)
-   { 
-      return (   greater(value1,toBeGreaterAs1)
-              && greater(value1,toBeGreaterAs2)
-              && greater(value2,toBeGreaterAs1)
-              && greater(value2,toBeGreaterAs2) );
-   }
-   /*=======================================================*/
-   template<typename T1, typename T2, typename T3>
-   inline bool inClosedInterval(const T1& value, const T2& threshold1, const T3& threshold2)
-   { 
-      if(threshold1 < threshold2)
-      {
-         return ( greaterEqual( value, threshold1) && lessEqual( value, threshold2) );
-      }
-
-      return ( greaterEqual( value, threshold2) && lessEqual( value, threshold1) );
-   }
-   /*=======================================================*/
-   template<typename T1, typename T2, typename T3>
-   inline bool inOpenInterval(const T1& value, const T2& threshold1, const T3& threshold2)
-   {	
-      if(threshold1 < threshold2) 
-      {
-         return (greater( value, threshold1) && less( value, threshold2));
-      }
-
-      return (greater( value, threshold2) && less( value, threshold1));
-   }
-   /*=======================================================*/
-   template<typename T1, typename T2, typename T3>
-   inline double adaptToClosedInterval(const T1& value, const T2& threshold1, const T3& threshold2)
-   { 
-      if(threshold1 < threshold2)
-      {
-         if     ( less(   value, threshold1) ) return threshold1;
-         else if( greater(value, threshold2) ) return threshold2;
-      }
-      else
-      {
-         if     ( less(   value, threshold2) ) return threshold2;
-         else if( greater(value, threshold1) ) return threshold1;
-      }
-      return value;
-   }
-   /*=======================================================*/
-   // -------------------------------------------------------------------------------------------------
-   // Funktion berechnet den groessten gemeinsamen Teiler zweier Zahlen (MK)
-   // -------------------------------------------------------------------------------------------------
-   /*=======================================================*/
-   inline int calcGgt(int val1, int val2)
-   {
-      if( val1 < val2 ) std::swap(val1,val2);
-      int ggt=val2;
-      while(ggt > 1)
-      {
-         if( (val1%ggt)==0 && (val2%ggt)==0 ) break;
-
-         ggt -=1;
-      }
-      return ggt;
-   }
-   /*=======================================================*/
-   // -------------------------------------------------------------------------------------------------
-   // Funktion berechnet den groessten gemeinsamen Teiler von drei Zahlen (MK)
-   // -------------------------------------------------------------------------------------------------
-   inline int calcGgt(int val1, const int& val2, int val3)
-   {
-      return UbMath::calcGgt( UbMath::calcGgt(val1, val2), val3 );
-   }
-   /*=======================================================*/
-   //returns the max of two values
-   //to avoid errors at mixed argument-types use: double myMax = max<double>(2,2.3);
-   template< typename T >
-   inline const T& max(const T& a1, const T& a2) 
-   { 
-     return (a1<a2) ? a2 : a1;
-   }
-   /*=======================================================*/
-   template< typename T >
-   inline const T& max(const T& a1, const T& a2, const T& a3) 
-   { 
-      return max(max(a1,a2),a3);
-   }
-   /*=======================================================*/
-   template< typename T >
-   inline const T& max(const T& a1, const T& a2, const T& a3, const T& a4)
-   {
-      return max(max(max(a1,a2),a3),a4);
-   }
-   /*=======================================================*/
-   template< typename T >
-   inline const T& min(const T& a1,const T& a2) 
-   { 
-      return (a1<a2) ? a1 : a2;
-   }
-   /*=======================================================*/
-   template< typename T >
-   inline const T& min(const T& a1, const T& a2, const T& a3) 
-   { 
-      return min(min(a1,a2),a3);
-   }
-   /*=======================================================*/
-   template< typename T >
-   inline const T& min(const T& a1, const T& a2, const T& a3, const T& a4)
-   {
-      return min(min(min(a1,a2),a3),a4);
-      
-//       double tmp = a1;
-//       if(tmp>a2) tmp=a2;
-//       if(tmp>a3) tmp=a3;
-//       if(tmp>a4) tmp=a4;
-//       return tmp;
-   }
-   /*=======================================================*/
-
-   class Vector3D
-   {
-   public:
-      // construction
-      Vector3D(); 
-      Vector3D(const double& fX1, const double& fX2, const double& fX3);
-      Vector3D(const Vector3D& rkV);
-
-      std::string toString() const;
-
-      // coordinate access
-      operator const double*() const;
-      operator double*();
-      double   operator[](const int& i) const;
-      double&  operator[](const int& i);
-      double   X1() const;
-      double&  X1();
-      double   X2() const;
-      double&  X2();                                    
-      double   X3() const;
-      double&  X3();
-
-      // assignment
-      Vector3D& operator=(const Vector3D& rkV);
-
-      // comparison
-      bool operator==(const Vector3D& rkV) const;
-      bool operator!=(const Vector3D& rkV) const;
-      bool operator< (const Vector3D& rkV) const;
-      bool operator<=(const Vector3D& rkV) const;
-      bool operator> (const Vector3D& rkV) const;
-      bool operator>=(const Vector3D& rkV) const;
-
-      // arithmetic operations
-      Vector3D operator+(const Vector3D& rkV) const;
-      Vector3D operator-(const Vector3D& rkV) const;
-      Vector3D operator*(const double& fScalar) const;
-      Vector3D operator/(const double& fScalar) const;
-      Vector3D operator-() const;
-
-      // arithmetic updates
-      Vector3D& operator+= (const Vector3D& rkV);
-      Vector3D& operator-= (const Vector3D& rkV);
-      Vector3D& operator*= (const double& fScalar);
-      Vector3D& operator/= (const double& fScalar);
-
-      Vector3D Add(Vector3D& vector);
-      Vector3D Subtract(Vector3D& vector);
-      Vector3D Scale(const double& x);
-
-      // vector operations
-      double Length () const;
-      double SquaredLength () const;
-      double Dot (const Vector3D& rkV) const;
-      double Normalize ();
-
-      // The cross products are computed using the right-handed rule.  Be aware
-      // that some graphics APIs use a left-handed rule.  If you have to compute
-      // a cross product with these functions and send the result to the API
-      // that expects left-handed, you will need to change sign on the vector
-      // (replace each component value c by -c).
-      Vector3D Cross (const Vector3D& rkV) const;
-      Vector3D UnitCross (const Vector3D& rkV) const;
-
-      // Compute the barycentric coordinates of the point with respect to the
-      // tetrahedron <V0,V1,V2,V3>, P = b0*V0 + b1*V1 + b2*V2 + b3*V3, where
-      // b0 + b1 + b2 + b3 = 1.
-      void GetBarycentrics (const Vector3D& rkV0, const Vector3D& rkV1, const Vector3D& rkV2, const Vector3D& rkV3, double afBary[4]) const;
-
-      // Gram-Schmidt orthonormalization.  Take linearly independent vectors
-      // U, V, and W and compute an orthonormal set (unit length, mutually
-      // perpendicular).
-      static void Orthonormalize (Vector3D& rkU, Vector3D& rkV, Vector3D& rkW);
-      static void Orthonormalize (Vector3D* akV);
-
-      // Input W must be initialized to a nonzero vector, output is {U,V,W},
-      // an orthonormal basis.  A hint is provided about whether or not W
-      // is already unit length.
-      static void GenerateOrthonormalBasis (Vector3D& rkU, Vector3D& rkV, Vector3D& rkW, bool bUnitLengthW);
-
-      // special vectors
-      static const Vector3D ZERO;
-      static const Vector3D UNIT_X1;
-      static const Vector3D UNIT_X2;
-      static const Vector3D UNIT_X3;
-
-   #ifdef CAB_RCF
-         template<class Archive>
-         void serialize(Archive & ar, const unsigned int version)
-         {
-            ar & m_afTuple;
-         }
-   #endif //CAB_RCF
-
-   protected:
-      // support for comparisons
-      int CompareArrays (const Vector3D& rkV) const;
-
-      double m_afTuple[3];
-   };
-   
-   //globaler multiplaktor mit skalar
-   Vector3D operator*(const double& fScalar, const Vector3D& rkV);
-   std::ostream& operator<<(std::ostream& os, const Vector3D& rkV);
-
-   //////////////////////////////////////////////////////////////////////////
-   //
-   //constants
-   //
-   //////////////////////////////////////////////////////////////////////////
-   static const double c8o27=8./27.;
-   static const double c2o27=2./27.;
-   static const double c1o54=1./54.;
-   static const double c1o216=1./216.;
-   static const double c9o2=9./2.;
-   static const double c3o9=3./9.;
-   static const double c3o54=3./54.;
-   static const double c3o216=3./216.;
-
-   static const double c1o27=1./27.;
-
-   static const double c1o72  = 1./72.;          //0.01388888
-   static const double c1o36  = 1./36.;          //0.02777777
-   static const double c1o48  = 1./48.;          //0.02083333
-   static const double c1o32  = 1./32.;          //0.03125
-   static const double c1o24  = 1./24.;          //0.04166666
-   static const double c1o20  = 1./20.;          //0.05
-   static const double c1o18  = 1./18.;          //0.05555555
-   static const double c1o16  = 1./16.;          //0.0625
-   static const double c1o12  = 1./12.;          //0.08333333
-   static const double c1o9   = 1./9.;           //0.11111111
-   static const double c1o8   = 1./8.;           //0.125
-   static const double c1o6   = 1./6.;           //0.16666666
-   static const double c1o5   = 1./5.;           //0.2
-   static const double c1o4   = 1./4.;           //0.25
-   static const double c5o16  = 5./16.;          //0.3125
-   static const double c1o3   = 1./3.;           //0.33333333
-   static const double c3o8   = 3./8.;           //0.375
-   static const double c4o9   = 4./9.;           //0.44444444
-   static const double c1o2   = 1./2.;           //0.5
-   static const double c9o16  = 9./16.;          //0.5625
-   static const double c2o3   = 2./3.;           //0.66666666
-   static const double c3o4   = 3./4.;           //0.75
-   static const double c3o2   = 3./2.;           //1.5
-   static const double c4o3   = 4./3.;           //1.33333333
-   static const double c5o3   = 5./3.;           //1.66666666
-   static const double c9o5   = 9./5.;           //1.8
-   static const double c2o9   = 2./9.;           //0.22222222
-   static const double one_over_sqrt2 =  1.0/sqrt(2.0); //0.707106781
-   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;
-   static const double four = 4.0;
-   static const double five = 5.0;
-   static const double six = 6.0;
-   static const double seven = 7.0;
-   static const double eight = 8.0;
-   static const double nine = 9.0;
-   static const double fourteen = 14.0;
-   static const double fiveteen = 15.0;
-   static const double sixteen = 16.0;
-   static const double twentyone = 21.0;
-   static const double twentyfour = 24.0;
-   static const double twentyeight = 28.0;
-   static const double twentynine = 29.0;
-   static const double fourtyeight = 48.0;
-   static const double fifty = 50.0;
-   static const double fiftysix = 56.0;
-   static const double c152 = 152.0;
-   static const double c130 = 130.0;
-}
-
-#endif
+//  _    ___      __              __________      _     __
+// | |  / (_)____/ /___  ______ _/ / ____/ /_  __(_)___/ /____
+// | | / / / ___/ __/ / / / __ `/ / /_  / / / / / / __  / ___/
+// | |/ / / /  / /_/ /_/ / /_/ / / __/ / / /_/ / / /_/ (__  )
+// |___/_/_/   \__/\__,_/\__,_/_/_/   /_/\__,_/_/\__,_/____/
+//
+#ifndef UBMATH_H
+#define UBMATH_H
+
+#include <cmath>
+#include <limits>
+#include <iostream>
+#include <cassert>
+#include <basics/utilities/UbSystem.h>
+#include <basics/utilities/UbEqual.h>
+
+/*=========================================================================*/
+/*  UbMath                                                             */
+/*                                                                         */
+/**
+namespace for global math-functions
+<BR><BR>
+@author <A HREF="mailto:muffmolch@gmx.de">S. Freudiger</A>
+@version 1.4 - 04.10.07
+*/ 
+
+/*
+usage: ...
+*/
+
+namespace UbMath 
+{
+   extern const double PI;
+   
+   
+   //////////////////////////////////////////////////////////////////////////
+   //Hilfsfunktion fuer Genauigkeit
+   template< typename T >
+   struct Epsilon {  };
+
+   //////////////////////////////////////////////////////////////////////////
+   //  SPECIALIZATIONS von Epsilon
+   //////////////////////////////////////////////////////////////////////////
+   template<>
+   struct Epsilon<double>        { static inline double      val() { return 1.0E-11; } };
+   template<>
+   struct Epsilon<float>         { static inline float       val() { return 1.0E-7f; } };
+   template<>
+   struct Epsilon<long double>   { static inline long double val() { return 1.0E-15; } };
+   template<>
+   struct Epsilon<int>           { static inline int         val() { return 0;       } };
+
+   /*=======================================================*/
+   // -------------------------------------------------------------------------------------------------
+   // Funktion berechnet den Logarithmus einer Zahl z bzgl. der Basis b
+   // -------------------------------------------------------------------------------------------------
+   template<typename T>
+   inline T log(const T& z, const T& base)
+   {
+      if( ::log(base)==0 ) return 1.0f;
+      return ::log(z) / ::log(base);
+   }
+   /*=======================================================*/
+   //double x = UbMath::getNegativeInfinity<double>();
+   template<typename T>
+   inline T getNegativeInfinity()
+   {
+      //assert(std::numeric_limits<T>::has_infinity);
+      UB_STATIC_ASSERT(std::numeric_limits<T>::has_infinity);
+      return -std::numeric_limits<T>::infinity();
+   }
+   /*=======================================================*/
+   //double x = UbMath::getPositiveInfinity<double>();
+   template<typename T>
+   inline T getPositiveInfinity()
+   {
+      //assert(std::numeric_limits<T>::has_infinity);
+      UB_STATIC_ASSERT(std::numeric_limits<T>::has_infinity);
+      return std::numeric_limits<T>::infinity();
+   }
+   /*=======================================================*/
+   //double x; bool b = UbMath::isInfinity(x);
+   template<typename T>
+   inline bool isInfinity(const T& value)
+   {
+      if(value==getNegativeInfinity<T>()) return true;
+      if(value==getPositiveInfinity<T>()) return true;
+      return false;
+   }
+   /*=======================================================*/
+   //double x = UbMath::getNaN<double>(x);
+   template<typename T>
+   inline T getNaN()
+   {
+      UB_STATIC_ASSERT(std::numeric_limits<T>::has_quiet_NaN);
+      return std::numeric_limits<T>::quiet_NaN();
+   }
+   /*=======================================================*/
+   //double x; bool b = UbMath::isNaN(x);
+   // x!=x liefert bei #QNAN "true"!
+   template<typename T>
+   inline bool isNaN(const T& x)
+   {
+      UB_STATIC_ASSERT(std::numeric_limits<T>::has_quiet_NaN);
+      return (x != x); 
+   }
+   /*=======================================================*/
+   template<typename T>
+   inline T getEqualityEpsilon()		  
+   { 
+      return  Epsilon<T>::val();  
+   }
+   /*=======================================================*/
+   template<typename T>
+   inline bool zero(const T& value)		  
+   { 
+      return std::fabs( value ) < Epsilon<T>::val();
+      //return value >= -UbMath::EPSILON && value <= UbMath::EPSILON;	
+   }
+   /*=======================================================*/
+   //spezialisierung fuer ints
+   template<>
+   inline bool zero(const int& value)		  
+   { 
+      return value == 0;
+   }
+   /*=======================================================*/
+   template<typename T1, typename T2>
+   inline bool zero(const T1& value1, const T2& value2)		  
+   { 
+      return !(!UbMath::zero(value1) || !UbMath::zero(value2));	
+   }
+   /*=======================================================*/
+   template<typename T1, typename T2, typename T3>
+   inline bool zero(const T1& value1, const T2& value2, const T3& value3)		  
+   { 
+      return !(!UbMath::zero(value1) || !UbMath::zero(value2,value3));	
+   }
+   /*=======================================================*/
+   template<typename T>
+   inline bool negative(const T& value)    
+   { 
+      return value < -Epsilon<T>::val();  
+   }
+   /*=======================================================*/
+   template<typename T>
+   inline bool nonPositive(const T& value) 
+   { 
+      return value <= Epsilon<T>::val(); 
+   }
+   /*=======================================================*/
+   template<typename T>
+   inline bool positive(const T& value)    
+   { 
+      return value > +Epsilon<T>::val();   
+   }
+   /*=======================================================*/
+   template<typename T>
+   inline bool nonNegative(const T& value) 
+   { 
+      return value >= -Epsilon<T>::val(); 
+   }
+   /*=======================================================*/
+   template<typename T1, typename T2>
+   inline bool equal(const T1& value, const T2& reference) 
+   { 
+      typedef typename UbEqualTrait<T1,T2>::High High;
+      return std::fabs(value-reference) < Epsilon<High>::val(); 
+   }
+   /*=======================================================*/
+   template<typename T1, typename T2, typename T3>
+   inline bool equal(const T1& val1, const T2& val2, const T3& val3) 
+   { 
+      return ( UbMath::equal(val1,val2) && UbMath::equal(val1,val3) ); 
+   }
+   /*=======================================================*/
+   template<typename T1, typename T2>
+   inline bool less(const T1& value, const T2& reference)   
+   { 
+      typedef typename UbEqualTrait<T1,T2>::High High;
+      return value < reference - Epsilon<High>::val(); 
+   }
+   /*=======================================================*/
+   template<typename T1, typename T2>
+   inline bool lessEqual(const T1& value, const T2& reference) 
+   { 
+      typedef typename UbEqualTrait<T1,T2>::High High;
+      return value <= reference + Epsilon<High>::val();
+   }
+   /*=======================================================*/
+   template<typename T1, typename T2>
+   inline bool greater(const T1& value, const T2& reference)      
+   { 
+      typedef typename UbEqualTrait<T1,T2>::High High;
+      return value > reference + Epsilon<High>::val();  
+   }
+   /*=======================================================*/
+   template<typename T1, typename T2>
+   inline bool greaterEqual(const T1& value, const T2& reference) 
+   { 
+      typedef typename UbEqualTrait<T1,T2>::High High;
+      return value >= reference - Epsilon<High>::val(); 
+   }
+   /*=======================================================*/
+   template<typename T>
+   inline T round(const T& value, const int& decimalPlaces) 
+   { 
+      return static_cast<T>(floor(value * pow( 10.0, decimalPlaces) + 0.5 ) * pow(10.0, -decimalPlaces)); 
+   } 
+   /*=======================================================*/
+   template<typename T>
+   inline int integerRounding(const T& value) 
+   { 
+      return static_cast<int>( UbMath::zero(value) ?  0 : ( (value<0.0) ? (value-0.5) : (value+0.5) ) );
+   } 
+   /*=======================================================*/
+   template<typename T>
+   inline T getRad(const T& degrees) 
+   {
+      return degrees*static_cast<T>(UbMath::PI/180.0);
+   }
+   /*=======================================================*/
+   template<typename T>
+   inline T getDegrees(const T& rad) 
+   {
+      return rad*static_cast<T>(UbMath::PI/180.0);
+   }
+   /*=======================================================*/
+   //aus wildmagic
+   template<typename T>
+   inline T ACos (const T& fValue)
+   {
+      if ( -1.0 < fValue )
+      {
+         if ( fValue < 1.0 ) return static_cast<T>( acos(fValue) );
+         else                return static_cast<T>( 0.0          );
+      }
+      else return static_cast<T>( PI );
+   }
+   /*=======================================================*/
+   template<typename T>
+   inline T ASin(const T& fValue)
+   {
+      double HALF_PI = 0.5*UbMath::PI;
+      if ( -1.0 < fValue )
+      {
+         if ( fValue < 1.0 ) return static_cast<T>( asin(fValue) );
+         else                return static_cast<T>( HALF_PI      );
+      }
+      else return -static_cast<T>( HALF_PI );         
+   }
+   /*=======================================================*/
+   template<typename T>
+   inline T invSqrt(const T& fValue)   
+   { 
+      return static_cast<T>(1.0/sqrt(fValue));
+   }
+
+   /*=======================================================*/
+   /**
+   * Returns true, if specified values a and b are less both values c and d.
+   * @param a the first value to check
+   * @param b the second value to check
+   * @param c the first value to check against
+   * @param d the second value to check against
+   * @return true, if specified values a and b are less both values c and d
+   **/
+   template<typename T1, typename T2, typename T3, typename T4>
+   inline bool less2(const T1& value1, const T2& value2, T3 toBeLessAs1, T4 toBeLessAs2) 
+   {	
+      return (   less(value1,toBeLessAs1)
+              && less(value1,toBeLessAs2)
+              && less(value2,toBeLessAs1)
+              && less(value2,toBeLessAs2) );
+   }
+   /*=======================================================*/
+   template<typename T1, typename T2, typename T3, typename T4>
+   inline bool greater2(const T1& value1, const T2& value2, T3 toBeGreaterAs1, T4 toBeGreaterAs2)
+   { 
+      return (   greater(value1,toBeGreaterAs1)
+              && greater(value1,toBeGreaterAs2)
+              && greater(value2,toBeGreaterAs1)
+              && greater(value2,toBeGreaterAs2) );
+   }
+   /*=======================================================*/
+   template<typename T1, typename T2, typename T3>
+   inline bool inClosedInterval(const T1& value, const T2& threshold1, const T3& threshold2)
+   { 
+      if(threshold1 < threshold2)
+      {
+         return ( greaterEqual( value, threshold1) && lessEqual( value, threshold2) );
+      }
+
+      return ( greaterEqual( value, threshold2) && lessEqual( value, threshold1) );
+   }
+   /*=======================================================*/
+   template<typename T1, typename T2, typename T3>
+   inline bool inOpenInterval(const T1& value, const T2& threshold1, const T3& threshold2)
+   {	
+      if(threshold1 < threshold2) 
+      {
+         return (greater( value, threshold1) && less( value, threshold2));
+      }
+
+      return (greater( value, threshold2) && less( value, threshold1));
+   }
+   /*=======================================================*/
+   template<typename T1, typename T2, typename T3>
+   inline double adaptToClosedInterval(const T1& value, const T2& threshold1, const T3& threshold2)
+   { 
+      if(threshold1 < threshold2)
+      {
+         if     ( less(   value, threshold1) ) return threshold1;
+         else if( greater(value, threshold2) ) return threshold2;
+      }
+      else
+      {
+         if     ( less(   value, threshold2) ) return threshold2;
+         else if( greater(value, threshold1) ) return threshold1;
+      }
+      return value;
+   }
+   /*=======================================================*/
+   // -------------------------------------------------------------------------------------------------
+   // Funktion berechnet den groessten gemeinsamen Teiler zweier Zahlen (MK)
+   // -------------------------------------------------------------------------------------------------
+   /*=======================================================*/
+   inline int calcGgt(int val1, int val2)
+   {
+      if( val1 < val2 ) std::swap(val1,val2);
+      int ggt=val2;
+      while(ggt > 1)
+      {
+         if( (val1%ggt)==0 && (val2%ggt)==0 ) break;
+
+         ggt -=1;
+      }
+      return ggt;
+   }
+   /*=======================================================*/
+   // -------------------------------------------------------------------------------------------------
+   // Funktion berechnet den groessten gemeinsamen Teiler von drei Zahlen (MK)
+   // -------------------------------------------------------------------------------------------------
+   inline int calcGgt(int val1, const int& val2, int val3)
+   {
+      return UbMath::calcGgt( UbMath::calcGgt(val1, val2), val3 );
+   }
+   /*=======================================================*/
+   //returns the max of two values
+   //to avoid errors at mixed argument-types use: double myMax = max<double>(2,2.3);
+   template< typename T >
+   inline const T& max(const T& a1, const T& a2) 
+   { 
+     return (a1<a2) ? a2 : a1;
+   }
+   /*=======================================================*/
+   template< typename T >
+   inline const T& max(const T& a1, const T& a2, const T& a3) 
+   { 
+      return max(max(a1,a2),a3);
+   }
+   /*=======================================================*/
+   template< typename T >
+   inline const T& max(const T& a1, const T& a2, const T& a3, const T& a4)
+   {
+      return max(max(max(a1,a2),a3),a4);
+   }
+   /*=======================================================*/
+   template< typename T >
+   inline const T& min(const T& a1,const T& a2) 
+   { 
+      return (a1<a2) ? a1 : a2;
+   }
+   /*=======================================================*/
+   template< typename T >
+   inline const T& min(const T& a1, const T& a2, const T& a3) 
+   { 
+      return min(min(a1,a2),a3);
+   }
+   /*=======================================================*/
+   template< typename T >
+   inline const T& min(const T& a1, const T& a2, const T& a3, const T& a4)
+   {
+      return min(min(min(a1,a2),a3),a4);
+      
+//       double tmp = a1;
+//       if(tmp>a2) tmp=a2;
+//       if(tmp>a3) tmp=a3;
+//       if(tmp>a4) tmp=a4;
+//       return tmp;
+   }
+
+   //////////////////////////////////////////////////////////////////////////
+   //
+   //constants
+   //
+   //////////////////////////////////////////////////////////////////////////
+   static const double c8o27 = 8. / 27.;
+   static const double c2o27 = 2. / 27.;
+   static const double c1o54 = 1. / 54.;
+   static const double c1o216 = 1. / 216.;
+   static const double c9o2 = 9. / 2.;
+   static const double c3o9 = 3. / 9.;
+   static const double c3o54 = 3. / 54.;
+   static const double c3o216 = 3. / 216.;
+
+   static const double c1o27 = 1. / 27.;
+
+   static const double c1o72 = 1. / 72.;          //0.01388888
+   static const double c1o36 = 1. / 36.;          //0.02777777
+   static const double c1o48 = 1. / 48.;          //0.02083333
+   static const double c1o32 = 1. / 32.;          //0.03125
+   static const double c1o24 = 1. / 24.;          //0.04166666
+   static const double c1o20 = 1. / 20.;          //0.05
+   static const double c1o18 = 1. / 18.;          //0.05555555
+   static const double c1o16 = 1. / 16.;          //0.0625
+   static const double c1o12 = 1. / 12.;          //0.08333333
+   static const double c1o9 = 1. / 9.;           //0.11111111
+   static const double c1o8 = 1. / 8.;           //0.125
+   static const double c1o6 = 1. / 6.;           //0.16666666
+   static const double c1o5 = 1. / 5.;           //0.2
+   static const double c1o4 = 1. / 4.;           //0.25
+   static const double c5o16 = 5. / 16.;          //0.3125
+   static const double c1o3 = 1. / 3.;           //0.33333333
+   static const double c3o8 = 3. / 8.;           //0.375
+   static const double c4o9 = 4. / 9.;           //0.44444444
+   static const double c1o2 = 1. / 2.;           //0.5
+   static const double c9o16 = 9. / 16.;          //0.5625
+   static const double c2o3 = 2. / 3.;           //0.66666666
+   static const double c3o4 = 3. / 4.;           //0.75
+   static const double c3o2 = 3. / 2.;           //1.5
+   static const double c4o3 = 4. / 3.;           //1.33333333
+   static const double c5o3 = 5. / 3.;           //1.66666666
+   static const double c9o5 = 9. / 5.;           //1.8
+   static const double c2o9 = 2. / 9.;           //0.22222222
+   static const double one_over_sqrt2 = 1.0 / sqrt(2.0); //0.707106781
+   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;
+   static const double four = 4.0;
+   static const double five = 5.0;
+   static const double six = 6.0;
+   static const double seven = 7.0;
+   static const double eight = 8.0;
+   static const double nine = 9.0;
+   static const double fourteen = 14.0;
+   static const double fiveteen = 15.0;
+   static const double sixteen = 16.0;
+   static const double twentyone = 21.0;
+   static const double twentyfour = 24.0;
+   static const double twentyeight = 28.0;
+   static const double twentynine = 29.0;
+   static const double fourtyeight = 48.0;
+   static const double fifty = 50.0;
+   static const double fiftysix = 56.0;
+   static const double c152 = 152.0;
+   static const double c130 = 130.0;
+}
+
+#endif
diff --git a/source/ThirdParty/Library/basics/utilities/UbScheduler.h b/source/ThirdParty/Library/basics/utilities/UbScheduler.h
index 493b567c8..67fafaf86 100644
--- a/source/ThirdParty/Library/basics/utilities/UbScheduler.h
+++ b/source/ThirdParty/Library/basics/utilities/UbScheduler.h
@@ -46,9 +46,9 @@ usage: ...
 
 // this class is not thread save
 //
-#include <boost/smart_ptr.hpp>
+
 class UbScheduler;
-typedef boost::shared_ptr<UbScheduler> UbSchedulerPtr;
+typedef std::shared_ptr<UbScheduler> UbSchedulerPtr;
 
 class UbScheduler
 {
diff --git a/source/ThirdParty/Library/basics/utilities/UbTuple.cpp b/source/ThirdParty/Library/basics/utilities/UbTuple.cpp
new file mode 100644
index 000000000..f778fc71a
--- /dev/null
+++ b/source/ThirdParty/Library/basics/utilities/UbTuple.cpp
@@ -0,0 +1,2 @@
+#include "UbTuple.h"
+
diff --git a/source/ThirdParty/Library/basics/utilities/UbTuple.h b/source/ThirdParty/Library/basics/utilities/UbTuple.h
index bb711c9dc..94132fcaf 100644
--- a/source/ThirdParty/Library/basics/utilities/UbTuple.h
+++ b/source/ThirdParty/Library/basics/utilities/UbTuple.h
@@ -9,6 +9,7 @@
 
 #include <iostream>
 #include <string>
+#include <ostream>
 
 #ifdef CAB_RCF
    #include <3rdParty/rcf/RcfSerializationIncludes.h>
@@ -124,6 +125,12 @@ public:
 };
 /**** end of typeop4.hpp ****/
 
+template <typename T1, typename T2>
+class  UbDuo;
+
+template <typename T1, typename T2>
+std::ostream& operator << (std::ostream& os, UbDuo<T1, T2> const& d1);
+
 //duo1.hpp
 template <typename T1, typename T2>
 class UbDuo 
@@ -194,7 +201,14 @@ inline bool operator < (UbDuo<T1,T2> const& d1, UbDuo<U1,U2> const& d2)
    return false;
 }
 
-// convenience function for creation and initialization
+template <typename T1, typename T2>
+std::ostream& operator << (std::ostream& os, UbDuo<T1, T2> const& d1)
+{
+    os << d1.v1() << ", " << d1.v2();
+    return os;
+}
+
+// convenience function  for creation and initialization
 template <typename T1, typename T2> 
 inline UbDuo<T1,T2> makeUbDuo(T1 const & a, T2 const & b)
 {
@@ -590,549 +604,4 @@ typedef UbTuple<int,double,double>                         UbTupleIntDouble2;
 typedef UbTuple<int, bool>                                 UbTupleIntBool;
 
 
-// class UbTupleWrapper
-// {
-// public:
-//    UbTuple<int, int> a;
-// 
-// #ifdef CAB_RCF
-//    template<class Archive>
-//    void serialize(Archive & ar, const unsigned int version)
-//    {
-//       ar & a;
-//    }
-//    void tuWas()
-//    {
-//       std::cout<<val<1>(a)<<std::endl;
-// 
-//       std::cout<<val<2>(a)<<std::endl;
-//    }
-// 
-// #endif
-// 
-// };
-
-
 #endif //UBTUPLE_H
-
-
-//#ifndef AAAAAAAAAAAAAAAAAAAAAAAAAAAAA //UBTUPLE_H
-//#define AAAAAAAAAAAAAAAAAAAAAAAAAAAAA //UBTUPLE_H
-//class UbTuble;
-//#include <iostream>
-//#include <string>
-//#include <algorithm> 
-//
-//
-//// a helper traits to make the make_tuple functions shorter (Vesa Karvonen's suggestion)
-//struct UbNullType{};
-//
-//template < class T0 = UbNullType, class T1 = UbNullType, class T2 = UbNullType,
-//class T3 = UbNullType, class T4 = UbNullType, class T5 = UbNullType,
-//class T6 = UbNullType, class T7 = UbNullType, class T8 = UbNullType >
-//class UbSimpleTuple
-//{
-//public:  
-//   UbSimpleTuple() {}
-//   UbSimpleTuple(T0 t0) {}
-//   UbSimpleTuple( const T0& t0) 
-//      : t0(t0) {}
-//   UbSimpleTuple( const T0& t0,  const T1& t1)
-//      : t0(t0), t1(t1){}
-//   UbSimpleTuple( const T0& t0,  const T1& t1,  const T2& t2) 
-//      : t0(t0), t1(t1), t2(t2) {}
-//   UbSimpleTuple( const T0& t0,  const T1& t1,  const T2& t2,  const T3& t3)
-//      : t0(t0), t1(t1), t2(t2), t3(t3){}
-//   UbSimpleTuple( const T0& t0,  const T1& t1,  const T2& t2,  const T3& t3,  const T4& t4) 
-//      : t0(t0), t1(t1), t2(t2), t3(t3), t4(t4){}
-//   UbSimpleTuple( const T0& t0,  const T1& t1,  const T2& t2,  const T3& t3,  const T4& t4,  const T5& t5) 
-//      : t0(t0), t1(t1), t2(t2), t3(t3), t4(t4), t5(t5){}
-//   UbSimpleTuple( const T0& t0,  const T1& t1,  const T2& t2,  const T3& t3,  const T4& t4,  const T5& t5,  const T6& t6) 
-//      : t0(t0), t1(t1), t2(t2), t3(t3), t4(t4), t5(t5), t6(t6){}
-//   UbSimpleTuple( const T0& t0,  const T1& t1,  const T2& t2,  const T3& t3,  const T4& t4,  const T5& t5,  const T6& t6,  const T7& t7) 
-//      : t0(t0), t1(t1), t2(t2), t3(t3), t4(t4), t5(t5), t6(t6), t7(t7){}
-//   UbSimpleTuple( const T0& t0,  const T1& t1,  const T2& t2,  const T3& t3,  const T4& t4,  const T5& t5,  const T6& t6,  const T7& t7, const T8& t8) 
-//      : t0(t0), t1(t1), t2(t2), t3(t3), t4(t4), t5(t5), t6(t6), t7(t7), t8(t8){}
-//
-//   T0 t0;
-//   T1 t1;
-//   T2 t2;
-//   T3 t3;
-//   T4 t4;
-//   T5 t5;
-//   T6 t6;
-//   T7 t7;
-//   T8 t8;
-//};
-// 
-//
-//UbSimpleTuple<> 
-//inline makeUbSimpleTuple() { return UbSimpleTuple<>(); }
-//
-//template<class T0>
-//inline UbSimpleTuple<T0> makeUbSimpleTuple(const T0& t0) { return UbSimpleTuple<T0>(t0); }
-//
-//template<class T0, class T1>
-//inline UbSimpleTuple<T0,T1> makeUbSimpleTuple(const T0& t0, const T1& t1)  { return UbSimpleTuple<T0,T1>(t0,t1); }
-//
-//template<class T0, class T1, class T2>
-//inline UbSimpleTuple<T0,T1,T2> makeUbSimpleTuple(const T0& t0, const T1& t1, const T2& t2)  { return UbSimpleTuple<T0,T1,T2>(t0,t1,t2); }
-//
-//template<class T0, class T1, class T2, class T3>
-//inline UbSimpleTuple<T0,T1,T2,T3> makeUbSimpleTuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3)  { return UbSimpleTuple<T0,T1,T2,T3>(t0,t1,t2,t2); }
-//
-////////////////////////////////////////////////////////////////////////////
-////Advanced UbTuple
-////Bsp:
-// //// create and use tuple with only one field
-// //UbTuple<int,int,int,int,int> t1;
-// //val<1>(t1) += 42;
-// //std::cout << t1.v1() << std::endl;
-//
-// //UbTuple<int,double,double> ttt3;
-// //val<3>(t3);
-// //
-// //// create and use duo
-// //UbType<bool,int> t2;
-// //std::cout << val<1>(t2) << ", ";
-// //std::cout << t2.v1() << std::endl;
-//
-// //// create and use triple
-// //UbType<bool,int,double> t3;
-// //val<1>(t3) = true;
-// //val<2>(t3) = 42;
-// //val<3>(t3) = 0.2;
-//
-// //std::cout << val<1>(t3) << ", ";
-// //std::cout << val<2>(t3) << ", ";
-// //std::cout << val<3>(t3) << std::endl;
-//
-// //t3 = make_tuple(false, 23, 13.13);
-//
-// //std::cout << val<1>(t3) << ", ";
-// //std::cout << val<2>(t3) << ", ";
-// //std::cout << val<3>(t3) << std::endl;
-//
-// //// create and use quadruple
-// //UbType<bool,int,float,double> t4(true,42,13,1.95583);
-// //std::cout << val<4>(t4) << std::endl;
-// //std::cout << t4.v2().v2().v2() << std::endl;
-//
-////typeop.hpp
-//// primary template
-///**********************************
-//* typeop1.hpp:
-//**********************************/
-//template <typename T>
-//class UbTypeOp             // primary template
-//{
-//public:
-//   typedef T         ArgT;
-//   typedef T         BareT;
-//   typedef T const   ConstT;
-//   typedef T &       RefT;
-//   typedef T &       RefBareT;
-//   typedef T const & RefConstT;
-//};
-///**** end of typeop1.hpp ****/
-//
-//// partial specialization for const
-///**********************************
-//* typeop2.hpp:
-//**********************************/
-//template <typename T>
-//class UbTypeOp <T const>   // partial specialization for const types
-//{
-//   public:
-//   typedef T const   ArgT;
-//   typedef T         BareT;
-//   typedef T const   ConstT;
-//   typedef T const & RefT;
-//   typedef T &       RefBareT;
-//   typedef T const & RefConstT;
-//};
-///**** end of typeop2.hpp ****/
-//
-//// partial specialization for references
-///**********************************
-//* typeop3.hpp:
-//**********************************/
-//template <typename T>
-//class UbTypeOp <T&>        // partial specialization for references
-//{
-//public:
-//   typedef T &                         ArgT;
-//   typedef typename UbTypeOp<T>::BareT   BareT;
-//   typedef T const                     ConstT;
-//   typedef T &                         RefT;
-//   typedef typename UbTypeOp<T>::BareT & RefBareT;
-//   typedef T const &                   RefConstT;
-//};
-///**** end of typeop3.hpp ****/
-//
-//// full specialization for void
-///**********************************
-//* typeop4.hpp:
-//**********************************/
-//template<>
-//class UbTypeOp <void>      // full specialization for void
-//{
-//public:
-//   typedef void       ArgT;
-//   typedef void       BareT;
-//   typedef void const ConstT;
-//   typedef void       RefT;
-//   typedef void       RefBareT;
-//   typedef void       RefConstT;
-//};
-///**** end of typeop4.hpp ****/
-//
-////duo1.hpp
-//template <typename T1, typename T2>
-//class UbDuo 
-//{
-//public:
-//   typedef T1 Type1;  // type of first field
-//   typedef T2 Type2;  // type of second field
-//   enum { N = 2 };    // number of fields
-//
-//private:
-//   T1 value1;         // value of first field
-//   T2 value2;         // value of second field
-//
-//public:
-//   // constructors
-//   UbDuo() : value1(), value2() { }
-//   UbDuo (T1 const & a, T2 const & b) : value1(a), value2(b) { }
-//
-//   // for implicit type conversion during construction
-//   template <typename U1, typename U2>
-//   UbDuo (UbDuo<U1,U2> const & d) : value1(d.v1()), value2(d.v2()) { }
-//
-//   // for implicit type conversion during assignments
-//   template <typename U1, typename U2>
-//   UbDuo<T1, T2>& operator = (UbDuo<U1,U2> const & d)
-//   {
-//      value1 = d.value1;
-//      value2 = d.value2;
-//      return *this;
-//   }
-//
-//   // field access
-//   T1& v1() { return value1; }
-//   T1 const& v1() const { return value1; }
-//
-//   T2& v2() { return value2; }
-//   T2 const& v2() const { return value2; }
-//};
-//
-//// comparison operators (allow mixed types):
-//template <typename T1, typename T2,
-//typename U1, typename U2>
-//inline bool operator == (UbDuo<T1,T2> const& d1, UbDuo<U1,U2> const& d2)
-//{
-//   return d1.v1()==d2.v1() && d1.v2()==d2.v2();
-//}
-//
-//template <typename T1, typename T2,
-//typename U1, typename U2>
-//inline bool operator != (UbDuo<T1,T2> const& d1, UbDuo<U1,U2> const& d2)
-//{
-//   return !(d1==d2);
-//}
-//
-//// convenience function for creation and initialization
-//template <typename T1, typename T2> 
-//inline UbDuo<T1,T2> makeUbDuo(T1 const & a, T2 const & b)
-//{
-//   return UbDuo<T1,T2>(a,b);
-//}
-//
-////duo2.hpp
-//template <typename A, typename B, typename C>
-//class UbDuo<A, UbDuo<B,C> >
-//{
-//public:
-//   typedef A          T1;           // type of first field
-//   typedef UbDuo<B,C> T2;           // type of second field
-//   enum { N = UbDuo<B,C>::N + 1 };  // number of fields
-//
-//private:
-//   T1 value1;         // value of first field
-//   T2 value2;         // value of second field
-//
-//public:
-//   // constructors
-//   UbDuo() : value1(), value2() {}
-//   UbDuo (T1 const & a, T2 const & b) : value1(a), value2(b) { }
-//
-//   // for implicit type conversion during construction
-//   template <typename U1, typename U2>
-//   UbDuo (UbDuo<U1,U2> const & d) : value1(d.v1()), value2(d.v2()) { }
-//
-//   // for implicit type conversion during assignments
-//   template <typename U1, typename U2>
-//   UbDuo<T1, T2>& operator = (UbDuo<U1,U2> const & d) 
-//   {
-//      value1 = d.value1;
-//      value2 = d.value2;
-//      return *this;
-//   }
-//
-//   // field access
-//   T1& v1() { return value1; }
-//   T1 const& v1() const { return value1; }
-//
-//   T2& v2() { return value2; }
-//   T2 const& v2() const { return value2; }
-//};
-//
-////duo3.hpp
-//// primary template for type of Nth field of (duo) T
-//template <int N, typename T>
-//class UbDuoT 
-//{
-//public:
-//   typedef void ResultT;    // in general, the result type is void
-//};
-//
-//// specialization for 1st field of a plain duo
-//template <typename A, typename B>
-//class UbDuoT<1, UbDuo<A,B> > 
-//{
-//public:
-//   typedef A ResultT;
-//};
-//
-//// specialization for 2nd field of a plain duo
-//template <typename A, typename B>
-//class UbDuoT<2, UbDuo<A,B> > 
-//{
-//public:
-//   typedef B ResultT;
-//};
-//
-//// specialization for Nth field of a recursive duo
-//template <int N, typename A, typename B, typename C>
-//class UbDuoT<N, UbDuo<A, UbDuo<B,C> > > 
-//{
-//public:
-//   typedef typename UbDuoT<N-1, UbDuo<B,C> >::ResultT ResultT;
-//};
-//
-//// specialization for 1st field of a recursive duo
-//template <typename A, typename B, typename C>
-//class UbDuoT<1, UbDuo<A, UbDuo<B,C> > > 
-//{
-//public:
-//   typedef A ResultT;
-//};
-//
-//// specialization for 2nd field of a recursive duo
-//template <typename A, typename B, typename C>
-//class UbDuoT<2, UbDuo<A, UbDuo<B,C> > > 
-//{
-//public:
-//   typedef B ResultT;
-//};
-//
-////duo4.hpp
-//// primary template for value of Nth field of (duo) T
-//template <int N, typename T>
-//class UbDuoValue 
-//{
-//public:
-//   static void get(T&) { }       // in general, we have no value
-//   static void get(T const&) { }
-//};
-//
-//// specialization for 1st field of a plain duo
-//template <typename A, typename B>
-//class UbDuoValue<1, UbDuo<A, B> > 
-//{
-//public:
-//   static A& get(UbDuo<A, B> &d) { return d.v1(); }
-//   static A const& get(UbDuo<A, B> const &d) { return d.v1();}
-//};
-//
-//// specialization for 2nd field of a plain duo
-//template <typename A, typename B>
-//class UbDuoValue<2, UbDuo<A, B> > 
-//{
-//public:
-//   static B& get(UbDuo<A, B> &d) 
-//   { 
-//      return d.v2(); 
-//   }
-//   static B const& get(UbDuo<A, B> const &d) { return d.v2(); }
-//};
-//
-//// specialization for Nth field of recursive duo
-//template <int N, typename A, typename B, typename C>
-//struct UbDuoValue<N, UbDuo<A, UbDuo<B,C> > > 
-//{
-//   static typename UbTypeOp<typename UbDuoT<N-1, UbDuo<B,C> >::ResultT>::RefT
-//   get(UbDuo<A, UbDuo<B,C> > &d) { return UbDuoValue<N-1, UbDuo<B,C> >::get(d.v2()); }
-//
-//   static typename UbTypeOp<typename UbDuoT<N-1, UbDuo<B,C> >::ResultT>::RefConstT
-//   get(UbDuo<A, UbDuo<B,C> > const &d) { return UbDuoValue<N-1, UbDuo<B,C> >::get(d.v2()); }
-//};
-//
-//// specialization for 1st field of recursive duo
-//template <typename A, typename B, typename C>
-//class UbDuoValue<1, UbDuo<A, UbDuo<B,C> > > 
-//{
-//public:
-//   static A& get(UbDuo<A, UbDuo<B,C> > &d) { return d.v1(); }
-//   static A const& get(UbDuo<A, UbDuo<B,C> > const &d) { return d.v1(); }
-//};
-//
-//// specialization for 2nd field of recursive duo
-//template <typename A, typename B, typename C>
-//class UbDuoValue<2, UbDuo<A, UbDuo<B,C> > > 
-//{
-//public:
-//   static B& get(UbDuo<A, UbDuo<B,C> > &d) { return d.v2().v1(); }
-//   static B const& get(UbDuo<A, UbDuo<B,C> > const &d) { return d.v2().v1(); }
-//};
-//
-////duo5.hpp
-//// return Nth value of variable duo
-//template <int N, typename A, typename B> 
-//inline typename UbTypeOp<typename UbDuoT<N, UbDuo<A, B> >::ResultT>::RefT
-//val(UbDuo<A, B>& d)
-//{
-//   return UbDuoValue<N, UbDuo<A, B> >::get(d);
-//}
-//
-//// return Nth value of constant duo
-//template <int N, typename A, typename B> 
-//inline typename UbTypeOp<typename UbDuoT<N, UbDuo<A, B> >::ResultT>::RefConstT
-//val(UbDuo<A, B> const& d)
-//{
-//   return UbDuoValue<N, UbDuo<A, B> >::get(d);
-//}
-//
-////duo6.hpp
-//// partial specialization for UbDuo<> with only one field
-//template <typename A>
-//struct UbDuo<A,void> 
-//{
-//public:
-//   typedef A    T1;  // type of first field
-//   typedef void T2;  // type of second field
-//   enum { N = 1 };   // number of fields
-//
-//private:
-//   T1 value1;        // value of first field
-//
-//public:
-//   // constructors
-//   UbDuo() : value1() { }
-//   UbDuo (T1 const & a) : value1(a) { }
-//
-//   // field access
-//   T1& v1() { return value1; }
-//   T1 const& v1() const { return value1; }
-//
-//   void v2() { }
-//   void v2() const { }
-//   //...
-//};
-//
-////tuple1.hpp
-//// a helper traits to make the make_tuple functions shorter (Vesa Karvonen's suggestion)
-//struct UbNullT{};
-//
-//// UbType<> in general derives from UbType<> with one more UbNullT
-//template <typename P1,
-//          typename P2 = UbNullT,
-//          typename P3 = UbNullT,
-//          typename P4 = UbNullT,
-//          typename P5 = UbNullT>
-//class UbType : public UbDuo<P1, typename UbType<P2,P3,P4,P5,UbNullT>::BaseT> 
-//{
-//public:
-//   typedef UbDuo<P1, typename UbType<P2,P3,P4,P5,UbNullT>::BaseT> BaseT;
-//
-//   // constructors:
-//   UbType() {}
-//   UbType(typename UbTypeOp<P1>::RefConstT a1,
-//          typename UbTypeOp<P2>::RefConstT a2,
-//          typename UbTypeOp<P3>::RefConstT a3 = UbNullT(),
-//          typename UbTypeOp<P4>::RefConstT a4 = UbNullT(),
-//          typename UbTypeOp<P5>::RefConstT a5 = UbNullT() ) : BaseT(a1, UbType<P2,P3,P4,P5,UbNullT>(a2,a3,a4,a5)) 
-//   {
-//   }
-//};
-//
-//// specialization to end deriving recursion
-//template <typename P1, typename P2>
-//class UbType<P1,P2,UbNullT,UbNullT,UbNullT> : public UbDuo<P1,P2> 
-//{
-//public:
-//   typedef UbDuo<P1,P2> BaseT;
-//   UbType() {}
-//   UbType(typename UbTypeOp<P1>::RefConstT a1,
-//          typename UbTypeOp<P2>::RefConstT a2,
-//          typename UbTypeOp<UbNullT>::RefConstT = UbNullT(),
-//          typename UbTypeOp<UbNullT>::RefConstT = UbNullT(),
-//          typename UbTypeOp<UbNullT>::RefConstT = UbNullT() ) : BaseT(a1, a2) 
-//   {
-//   }
-//};
-//
-//// specialization for singletons
-//template <typename P1>
-//class UbType<P1,UbNullT,UbNullT,UbNullT,UbNullT> : public UbDuo<P1,void> 
-//{
-//public:
-//   typedef UbDuo<P1,void> BaseT;
-//   UbType() {}
-//   UbType(typename UbTypeOp<P1>::RefConstT a1,
-//          typename UbTypeOp<UbNullT>::RefConstT = UbNullT(),
-//          typename UbTypeOp<UbNullT>::RefConstT = UbNullT(),
-//          typename UbTypeOp<UbNullT>::RefConstT = UbNullT(),
-//          typename UbTypeOp<UbNullT>::RefConstT = UbNullT() ) : BaseT(a1) 
-//   {
-//   }
-//};
-//
-//// convenience function for 1 argument
-//template <typename T1>
-//inline UbType<T1> makeUbTuple(T1 const &a1)
-//{
-//   return UbType<T1>(a1);
-//}
-//
-//// convenience function for 2 arguments
-//template <typename T1, typename T2>
-//inline UbType<T1,T2> makeUbTuple(T1 const &a1, T2 const &a2)
-//{
-//   return UbType<T1,T2>(a1,a2);
-//}
-//
-//// convenience function for 3 arguments
-//template <typename T1, typename T2, typename T3>
-//inline UbType<T1,T2,T3> makeUbTuple(T1 const &a1, T2 const &a2, T3 const &a3)
-//{
-//   return UbType<T1,T2,T3>(a1,a2,a3);
-//}
-//
-//// convenience function for 4 arguments
-//template <typename T1, typename T2, typename T3, typename T4>
-//inline UbType<T1,T2,T3,T4> make_tuple(T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4)
-//{
-//   return UbType<T1,T2,T3,T4>(a1,a2,a3,a4);
-//}
-//
-//// convenience function for 5 arguments
-//template <typename T1, typename T2, typename T3,
-//typename T4, typename T5>
-//inline UbType<T1,T2,T3,T4,T5> make_tuple(T1 const &a1, T2 const &a2,T3 const &a3, T4 const &a4,T5 const &a5)
-//{
-//   return UbType<T1,T2,T3,T4,T5>(a1,a2,a3,a4,a5);
-//}
-//
-//#endif
-
diff --git a/source/ThirdParty/Library/basics/utilities/Vector3D.cpp b/source/ThirdParty/Library/basics/utilities/Vector3D.cpp
new file mode 100644
index 000000000..34074babd
--- /dev/null
+++ b/source/ThirdParty/Library/basics/utilities/Vector3D.cpp
@@ -0,0 +1,610 @@
+#include <basics/utilities/Vector3D.h>
+
+#include <cassert>
+#include <sstream>
+
+#include <basics/utilities/UbMath.h>
+#include <basics/utilities/UbInfinity.h>
+
+
+
+const Vector3D Vector3D::ZERO(0.0,0.0,0.0);
+const Vector3D Vector3D::UNIT_X1(1.0,0.0,0.0);
+const Vector3D Vector3D::UNIT_X2(0.0,1.0,0.0);
+const Vector3D Vector3D::UNIT_X3(0.0,0.0,1.0);
+
+/*=======================================================*/
+Vector3D::Vector3D() 
+{                                      
+   m_afTuple[0] = 0.0;
+   m_afTuple[1] = 0.0;
+   m_afTuple[2] = 0.0;
+}
+/*=======================================================*/
+Vector3D::Vector3D(const double& fX, const double& fY, const double& fZ) 
+{
+   m_afTuple[0] = fX;
+   m_afTuple[1] = fY;
+   m_afTuple[2] = fZ;
+}
+/*=======================================================*/
+Vector3D::Vector3D (const Vector3D& rkV) 
+{
+   m_afTuple[0] = rkV.m_afTuple[0];
+   m_afTuple[1] = rkV.m_afTuple[1];
+   m_afTuple[2] = rkV.m_afTuple[2];
+}
+/*=======================================================*/
+std::string Vector3D::toString()  const
+{
+   std::stringstream os;
+   os<< "Vector3D["<<m_afTuple[0]<<","<<m_afTuple[1]<<","<<m_afTuple[2]<<"]";
+   return os.str();
+}
+/*=======================================================*/
+Vector3D::operator const double*() const
+{
+   return m_afTuple;
+}
+/*=======================================================*/
+Vector3D::operator double*()
+{
+   return m_afTuple;
+}
+/*=======================================================*/
+double Vector3D::operator[](const int& i) const
+{
+   assert( i >= 0 && i <= 2 );
+   return m_afTuple[i];
+}
+/*=======================================================*/
+double& Vector3D::operator[](const int& i)
+{
+   assert( i >= 0 && i <= 2 );
+   return m_afTuple[i];
+}
+/*=======================================================*/
+double Vector3D::X1() const
+{
+   return m_afTuple[0];
+}
+/*=======================================================*/
+double& Vector3D::X1()
+{
+   return m_afTuple[0];
+}
+/*=======================================================*/
+double Vector3D::X2() const
+{
+   return m_afTuple[1];
+}
+/*=======================================================*/
+double& Vector3D::X2()
+{
+   return m_afTuple[1];
+}
+/*=======================================================*/
+double Vector3D::X3() const
+{
+   return m_afTuple[2];
+}
+/*=======================================================*/
+double& Vector3D::X3()
+{
+   return m_afTuple[2];
+}
+/*=======================================================*/
+Vector3D& Vector3D::operator=(const Vector3D& rkV)
+{
+   m_afTuple[0] = rkV.m_afTuple[0];
+   m_afTuple[1] = rkV.m_afTuple[1];
+   m_afTuple[2] = rkV.m_afTuple[2];
+   return *this;
+}
+/*=======================================================*/
+int Vector3D::CompareArrays(const Vector3D& rkV) const
+{
+   return memcmp(m_afTuple,rkV.m_afTuple,3*sizeof(double));
+}
+/*=======================================================*/
+bool Vector3D::operator==(const Vector3D& rkV) const
+{
+   return CompareArrays(rkV) == 0;
+}
+/*=======================================================*/
+bool Vector3D::operator!=(const Vector3D& rkV) const
+{
+   return CompareArrays(rkV) != 0;
+}
+/*=======================================================*/
+bool Vector3D::operator<(const Vector3D& rkV) const
+{
+   return CompareArrays(rkV) < 0;
+}
+/*=======================================================*/
+bool Vector3D::operator<=(const Vector3D& rkV) const
+{
+   return CompareArrays(rkV) <= 0;
+}
+/*=======================================================*/
+bool Vector3D::operator> (const Vector3D& rkV) const
+{
+   return CompareArrays(rkV) > 0;
+}
+/*=======================================================*/
+bool Vector3D::operator>=(const Vector3D& rkV) const
+{
+   return CompareArrays(rkV) >= 0;
+}
+/*=======================================================*/
+Vector3D Vector3D::operator+(const Vector3D& rkV) const
+{
+   return Vector3D( m_afTuple[0]+rkV.m_afTuple[0],
+                    m_afTuple[1]+rkV.m_afTuple[1],
+                    m_afTuple[2]+rkV.m_afTuple[2] );
+}
+/*=======================================================*/
+Vector3D Vector3D::Add(Vector3D& vector)
+{
+   return Vector3D( m_afTuple[0]+vector.m_afTuple[0],
+                    m_afTuple[1]+vector.m_afTuple[1],
+                    m_afTuple[2]+vector.m_afTuple[2] );
+}
+/*=======================================================*/
+Vector3D Vector3D::operator- (const Vector3D& rkV) const
+{
+   return Vector3D( m_afTuple[0]-rkV.m_afTuple[0],
+                    m_afTuple[1]-rkV.m_afTuple[1],
+                    m_afTuple[2]-rkV.m_afTuple[2] );
+}
+/*=======================================================*/
+Vector3D Vector3D::Subtract(Vector3D& vector)
+{
+   return Vector3D( m_afTuple[0]-vector.m_afTuple[0],
+                    m_afTuple[1]-vector.m_afTuple[1],
+                    m_afTuple[2]-vector.m_afTuple[2] );
+}
+/*=======================================================*/
+Vector3D Vector3D::operator*(const double& fScalar) const
+{
+   return Vector3D( fScalar*m_afTuple[0],
+                    fScalar*m_afTuple[1],
+                    fScalar*m_afTuple[2]  );
+}
+/*=======================================================*/
+Vector3D Vector3D::operator/(const double& fScalar) const
+{
+   Vector3D kQuot;
+
+   if ( fScalar != 0.0 )
+   {
+      double fInvScalar = 1.0/fScalar;
+      kQuot.m_afTuple[0] = fInvScalar*m_afTuple[0];
+      kQuot.m_afTuple[1] = fInvScalar*m_afTuple[1];
+      kQuot.m_afTuple[2] = fInvScalar*m_afTuple[2];
+   }
+   else
+   {
+      kQuot.m_afTuple[0] = Ub::inf;
+      kQuot.m_afTuple[1] = Ub::inf;
+      kQuot.m_afTuple[2] = Ub::inf;
+   }
+
+   return kQuot;
+}
+/*=======================================================*/
+Vector3D Vector3D::operator-() const
+{
+   return Vector3D( -m_afTuple[0],
+                    -m_afTuple[1],
+                    -m_afTuple[2] );
+}
+/*=======================================================*/
+Vector3D& Vector3D::operator+=(const Vector3D& rkV)
+{
+   m_afTuple[0] += rkV.m_afTuple[0];
+   m_afTuple[1] += rkV.m_afTuple[1];
+   m_afTuple[2] += rkV.m_afTuple[2];
+   return *this;
+}
+/*=======================================================*/
+Vector3D& Vector3D::operator-=(const Vector3D& rkV)
+{
+   m_afTuple[0] -= rkV.m_afTuple[0];
+   m_afTuple[1] -= rkV.m_afTuple[1];
+   m_afTuple[2] -= rkV.m_afTuple[2];
+   return *this;
+}
+/*=======================================================*/
+Vector3D& Vector3D::operator*=(const double& fScalar)
+{
+   m_afTuple[0] *= fScalar;
+   m_afTuple[1] *= fScalar;
+   m_afTuple[2] *= fScalar;
+   return *this;
+}
+/*=======================================================*/
+Vector3D& Vector3D::operator/=(const double& fScalar)
+{
+   if ( !UbMath::zero(fScalar) )
+   {
+      double fInvScalar = 1.0/fScalar;
+      m_afTuple[0] *= fInvScalar;
+      m_afTuple[1] *= fInvScalar;
+      m_afTuple[2] *= fInvScalar;
+   }
+   else
+   {
+      m_afTuple[0] = Ub::inf;
+      m_afTuple[1] = Ub::inf;
+      m_afTuple[2] = Ub::inf;
+   }
+
+   return *this;
+}
+/*=======================================================*/
+Vector3D Vector3D::Scale(const double& x)
+{
+   Vector3D PointA(0.0,0.0,0.0);
+   PointA.m_afTuple[0] = x * m_afTuple[0];
+   PointA.m_afTuple[1] = x * m_afTuple[1];
+   PointA.m_afTuple[2] = x * m_afTuple[2];
+   return PointA;	
+}
+/*=======================================================*/
+double Vector3D::Length() const
+{
+   return std::sqrt( m_afTuple[0]*m_afTuple[0] +
+                     m_afTuple[1]*m_afTuple[1] +
+                     m_afTuple[2]*m_afTuple[2] );
+}
+/*=======================================================*/
+double Vector3D::SquaredLength() const
+{
+   return m_afTuple[0]*m_afTuple[0] +
+          m_afTuple[1]*m_afTuple[1] +
+          m_afTuple[2]*m_afTuple[2];
+}
+/*=======================================================*/
+double Vector3D::Dot(const Vector3D& rkV) const
+{
+   return m_afTuple[0]*rkV.m_afTuple[0] +
+          m_afTuple[1]*rkV.m_afTuple[1] +
+          m_afTuple[2]*rkV.m_afTuple[2];
+}
+/*=======================================================*/
+double Vector3D::Normalize()
+{
+   double fLength = Length();
+
+   if( !UbMath::zero(fLength) )
+   {
+      double fInvLength = 1.0/fLength;
+      m_afTuple[0] *= fInvLength;
+      m_afTuple[1] *= fInvLength;
+      m_afTuple[2] *= fInvLength;
+   }
+   else
+   {
+      fLength = 0.0;
+      m_afTuple[0] = 0.0;
+      m_afTuple[1] = 0.0;
+      m_afTuple[2] = 0.0;
+   }
+
+   return fLength;
+}
+/*=======================================================*/
+Vector3D Vector3D::Cross(const Vector3D& rkV) const
+{
+   return Vector3D( m_afTuple[1]*rkV.m_afTuple[2] - m_afTuple[2]*rkV.m_afTuple[1],
+                    m_afTuple[2]*rkV.m_afTuple[0] - m_afTuple[0]*rkV.m_afTuple[2],
+                    m_afTuple[0]*rkV.m_afTuple[1] - m_afTuple[1]*rkV.m_afTuple[0] );
+}
+/*=======================================================*/
+Vector3D Vector3D::UnitCross(const Vector3D& rkV) const
+{
+   Vector3D kCross( m_afTuple[1]*rkV.m_afTuple[2] - m_afTuple[2]*rkV.m_afTuple[1],
+                    m_afTuple[2]*rkV.m_afTuple[0] - m_afTuple[0]*rkV.m_afTuple[2],
+                    m_afTuple[0]*rkV.m_afTuple[1] - m_afTuple[1]*rkV.m_afTuple[0] );
+   kCross.Normalize();
+   return kCross;
+}
+/*=======================================================*/
+void Vector3D::GetBarycentrics(const Vector3D& rkV0,const Vector3D& rkV1, const Vector3D& rkV2,const Vector3D& rkV3, double afBary[4]) const
+{
+   // compute the vectors relative to V3 of the tetrahedron
+   Vector3D akDiff[4] = { rkV0  - rkV3,
+                          rkV1  - rkV3,
+                          rkV2  - rkV3,
+                          *this - rkV3 };
+
+   // If the vertices have large magnitude, the linear system of
+   // equations for computing barycentric coordinates can be
+   // ill-conditioned.  To avoid this, uniformly scale the tetrahedron
+   // edges to be of order 1.  The scaling of all differences does not
+   // change the barycentric coordinates.
+   double fMax = 0.0,fValue=0.0;
+   for(int i=0; i<3; i++)
+      for (int j=0; j<3; j++)
+      {
+         fValue = std::fabs(akDiff[i][j]);
+         if ( fValue > fMax )  fMax = fValue;
+      }
+   
+   // scale down only large data
+   if(UbMath::greater(fMax,1.0) )
+   {
+      double fInvMax = ((double)1.0)/fMax;
+      for( int i=0; i<4; i++)
+         akDiff[i] *= fInvMax;
+   }
+
+   double     fDet = akDiff[0].Dot(akDiff[1].Cross(akDiff[2]));
+   Vector3D kE1cE2 = akDiff[1].Cross(akDiff[2]);
+   Vector3D kE2cE0 = akDiff[2].Cross(akDiff[0]);
+   Vector3D kE0cE1 = akDiff[0].Cross(akDiff[1]);
+   
+   if( !UbMath::zero( fDet ) )
+   {
+      double fInvDet = 1.0/fDet;
+      afBary[0] = akDiff[3].Dot(kE1cE2)*fInvDet;
+      afBary[1] = akDiff[3].Dot(kE2cE0)*fInvDet;
+      afBary[2] = akDiff[3].Dot(kE0cE1)*fInvDet;
+      afBary[3] = 1.0 - afBary[0] - afBary[1] - afBary[2];
+   }
+   else
+   {
+      // The tetrahedron is potentially flat.  Determine the face of
+      // maximum area and compute barycentric coordinates with respect
+      // to that face.
+      Vector3D kE02 = rkV0 - rkV2;
+      Vector3D kE12 = rkV1 - rkV2;
+      Vector3D kE02cE12 = kE02.Cross(kE12);
+      double fMaxSqrArea = kE02cE12.SquaredLength();
+      int iMaxIndex = 3;
+      double fSqrArea = kE0cE1.SquaredLength();
+      if ( fSqrArea > fMaxSqrArea )
+      {
+         iMaxIndex = 0;
+         fMaxSqrArea = fSqrArea;
+      }
+      fSqrArea = kE1cE2.SquaredLength();
+      if ( fSqrArea > fMaxSqrArea )
+      {
+         iMaxIndex = 1;
+         fMaxSqrArea = fSqrArea;
+      }
+      fSqrArea = kE2cE0.SquaredLength();
+      if ( fSqrArea > fMaxSqrArea )
+      {
+         iMaxIndex = 2;
+         fMaxSqrArea = fSqrArea;
+      }
+
+      if (UbMath::greater(fMaxSqrArea,0.0)  )
+      {
+         double fInvSqrArea = 1.0/fMaxSqrArea;
+         Vector3D kTmp;
+         if( iMaxIndex==0 )
+         {
+            kTmp      = akDiff[3].Cross(akDiff[1]);
+            afBary[0] = kE0cE1.Dot(kTmp)*fInvSqrArea;
+            kTmp      = akDiff[0].Cross(akDiff[3]);
+            afBary[1] = kE0cE1.Dot(kTmp)*fInvSqrArea;
+            afBary[2] = 0.0;
+            afBary[3] = 1.0 - afBary[0] - afBary[1];
+         }
+         else if( iMaxIndex == 1 )
+         {
+            afBary[0] = 0.0;
+            kTmp      = akDiff[3].Cross(akDiff[2]);
+            afBary[1] = kE1cE2.Dot(kTmp)*fInvSqrArea;
+            kTmp      = akDiff[1].Cross(akDiff[3]);
+            afBary[2] = kE1cE2.Dot(kTmp)*fInvSqrArea;
+            afBary[3] = 1.0 - afBary[1] - afBary[2];
+         }
+         else if( iMaxIndex == 2 )
+         {
+            kTmp      = akDiff[2].Cross(akDiff[3]);
+            afBary[0] = kE2cE0.Dot(kTmp)*fInvSqrArea;
+            afBary[1] = 0.0;
+            kTmp      = akDiff[3].Cross(akDiff[0]);
+            afBary[2] = kE2cE0.Dot(kTmp)*fInvSqrArea;
+            afBary[3] = 1.0 - afBary[0] - afBary[2];
+         }
+         else
+         {
+            akDiff[3] = *this - rkV2;
+            kTmp      = akDiff[3].Cross(kE12);
+            afBary[0] = kE02cE12.Dot(kTmp)*fInvSqrArea;
+            kTmp      = kE02.Cross(akDiff[3]);
+            afBary[1] = kE02cE12.Dot(kTmp)*fInvSqrArea;
+            afBary[2] = 1.0 - afBary[0] - afBary[1];
+            afBary[3] = 0.0;
+         }
+      }
+      else
+      {
+         // The tetrahedron is potentially a sliver.  Determine the edge of
+         // maximum length and compute barycentric coordinates with respect
+         // to that edge.
+         double fMaxSqrLength = akDiff[0].SquaredLength();
+         iMaxIndex            = 0;  // <V0,V3>
+         double fSqrLength    = akDiff[1].SquaredLength();
+         
+         if( fSqrLength > fMaxSqrLength )
+         {
+            iMaxIndex     = 1;  // <V1,V3>
+            fMaxSqrLength = fSqrLength;
+         }
+         fSqrLength = akDiff[2].SquaredLength();
+         
+         if( fSqrLength > fMaxSqrLength )
+         {
+            iMaxIndex     = 2;  // <V2,V3>
+            fMaxSqrLength = fSqrLength;
+         }
+         fSqrLength = kE02.SquaredLength();
+         
+         if( fSqrLength > fMaxSqrLength )
+         {
+            iMaxIndex     = 3;  // <V0,V2>
+            fMaxSqrLength = fSqrLength;
+         }
+         fSqrLength = kE12.SquaredLength();
+         
+         if( fSqrLength > fMaxSqrLength )
+         {
+            iMaxIndex     = 4;  // <V1,V2>
+            fMaxSqrLength = fSqrLength;
+         }
+         
+         Vector3D kE01 = rkV0 - rkV1;
+         fSqrLength    = kE01.SquaredLength();
+         
+         if( fSqrLength > fMaxSqrLength )
+         {
+            iMaxIndex     = 5;  // <V0,V1>
+            fMaxSqrLength = fSqrLength;
+         }
+
+         if(UbMath::greater(fMaxSqrLength, 0.0) )
+         {
+            double fInvSqrLength = 1.0/fMaxSqrLength;
+            if( iMaxIndex == 0 )
+            {
+               // P-V3 = t*(V0-V3)
+               afBary[0] = akDiff[3].Dot(akDiff[0])*fInvSqrLength;
+               afBary[1] = 0.0;
+               afBary[2] = 0.0;
+               afBary[3] = 1.0 - afBary[0];
+            }
+            else if( iMaxIndex == 1 )
+            {
+               // P-V3 = t*(V1-V3)
+               afBary[0] = 0.0;
+               afBary[1] = akDiff[3].Dot(akDiff[1])*fInvSqrLength;
+               afBary[2] = 0.0;
+               afBary[3] = 1.0 - afBary[1];
+            }
+            else if( iMaxIndex == 2 )
+            {
+               // P-V3 = t*(V2-V3)
+               afBary[0] = 0.0;
+               afBary[1] = 0.0;
+               afBary[2] = akDiff[3].Dot(akDiff[2])*fInvSqrLength;
+               afBary[3] = 1.0 - afBary[2];
+            }
+            else if( iMaxIndex == 3 )
+            {      
+               // P-V2 = t*(V0-V2)
+               akDiff[3] = *this - rkV2;
+               afBary[0] = akDiff[3].Dot(kE02)*fInvSqrLength;
+               afBary[1] = 0.0;
+               afBary[2] = 1.0 - afBary[0];
+               afBary[3] = 0.0;
+            }
+            else if( iMaxIndex == 4 )
+            {
+               // P-V2 = t*(V1-V2)
+               akDiff[3] = *this - rkV2;
+               afBary[0] = 0.0;
+               afBary[1] = akDiff[3].Dot(kE12)*fInvSqrLength;
+               afBary[2] = 1.0 - afBary[1];
+               afBary[3] = 0.0;
+            }
+            else
+            {
+               // P-V1 = t*(V0-V1)
+               akDiff[3] = *this - rkV1;
+               afBary[0] = akDiff[3].Dot(kE01)*fInvSqrLength;
+               afBary[1] = 1.0 - afBary[0];
+               afBary[2] = 0.0;
+               afBary[3] = 0.0;
+            }
+         }
+         else
+         {
+            // tetrahedron is a nearly a point, just return equal weights
+            afBary[0] = 0.25;
+            afBary[1] = afBary[0];
+            afBary[2] = afBary[0];
+            afBary[3] = afBary[0];
+         }
+      }
+   }
+}
+/*=======================================================*/
+void Vector3D::Orthonormalize(Vector3D& rkU, Vector3D& rkV, Vector3D& rkW)
+{
+   // If the input vectors are v0, v1, and v2, then the Gram-Schmidt
+   // orthonormalization produces vectors u0, u1, and u2 as follows,
+   //
+   //   u0 = v0/|v0|
+   //   u1 = (v1-(u0*v1)u0)/|v1-(u0*v1)u0|
+   //   u2 = (v2-(u0*v2)u0-(u1*v2)u1)/|v2-(u0*v2)u0-(u1*v2)u1|
+   //
+   // where |A| indicates length of vector A and A*B indicates dot
+   // product of vectors A and B.
+
+   // compute u0
+   rkU.Normalize();
+
+   // compute u1
+   double fDot0 = rkU.Dot(rkV); 
+   rkV -= fDot0*rkU;
+   rkV.Normalize();
+
+   // compute u2
+   double fDot1 = rkV.Dot(rkW);
+   fDot0 = rkU.Dot(rkW);
+   rkW  -= fDot0*rkU + fDot1*rkV;
+   rkW.Normalize();
+}
+/*=======================================================*/
+void Vector3D::Orthonormalize(Vector3D* akV)
+{
+   Orthonormalize(akV[0],akV[1],akV[2]);
+}
+/*=======================================================*/
+void Vector3D::GenerateOrthonormalBasis(Vector3D& rkU, Vector3D& rkV,Vector3D& rkW, bool bUnitLengthW)
+{
+   if ( !bUnitLengthW )
+      rkW.Normalize();
+
+   double fInvLength;
+
+   if (UbMath::greaterEqual( std::fabs(rkW.m_afTuple[0]),std::fabs(rkW.m_afTuple[1]) ) )
+   {
+      // W.x or W.z is the largest magnitude component, swap them
+      fInvLength = UbMath::invSqrt(rkW.m_afTuple[0]*rkW.m_afTuple[0] + rkW.m_afTuple[2]*rkW.m_afTuple[2]);
+      rkU.m_afTuple[0] = -rkW.m_afTuple[2]*fInvLength;
+      rkU.m_afTuple[1] = (double)0.0;
+      rkU.m_afTuple[2] = +rkW.m_afTuple[0]*fInvLength;
+   }
+   else
+   {
+      // W.y or W.z is the largest magnitude component, swap them
+      fInvLength = UbMath::invSqrt(rkW.m_afTuple[1]*rkW.m_afTuple[1] + rkW.m_afTuple[2]*rkW.m_afTuple[2]);
+      rkU.m_afTuple[0] = (double)0.0;
+      rkU.m_afTuple[1] = +rkW.m_afTuple[2]*fInvLength;
+      rkU.m_afTuple[2] = -rkW.m_afTuple[1]*fInvLength;
+   }
+
+   rkV = rkW.Cross(rkU);
+}
+/*=======================================================*/
+//globaler operator* 
+Vector3D operator*(const double& fScalar, const Vector3D& rkV)
+{
+   return Vector3D( fScalar*rkV[0],
+                    fScalar*rkV[1],
+                    fScalar*rkV[2] );
+}
+/*=======================================================*/
+std::ostream& operator<< (std::ostream& os, const Vector3D& rkV)
+{
+   os<<rkV.toString();
+   return os;
+}
diff --git a/source/ThirdParty/Library/basics/utilities/Vector3D.h b/source/ThirdParty/Library/basics/utilities/Vector3D.h
new file mode 100644
index 000000000..76d2ae3aa
--- /dev/null
+++ b/source/ThirdParty/Library/basics/utilities/Vector3D.h
@@ -0,0 +1,131 @@
+//  _    ___      __              __________      _     __
+// | |  / (_)____/ /___  ______ _/ / ____/ /_  __(_)___/ /____
+// | | / / / ___/ __/ / / / __ `/ / /_  / / / / / / __  / ___/
+// | |/ / / /  / /_/ /_/ / /_/ / / __/ / / /_/ / / /_/ (__  )
+// |___/_/_/   \__/\__,_/\__,_/_/_/   /_/\__,_/_/\__,_/____/
+//
+#ifndef VECTOR_3D_H
+#define VECTOR_3D_H
+
+#include <string>
+
+/*=========================================================================*/
+/*  Vector3D                                                             */
+/*                                                                         */
+/**
+<BR><BR>
+@author <A HREF="mailto:muffmolch@gmx.de">S. Freudiger</A>
+@version 1.4 - 04.10.07
+*/ 
+
+/*
+usage: ...
+*/
+
+   class Vector3D
+   {
+   public:
+      // construction
+      Vector3D(); 
+      Vector3D(const double& fX1, const double& fX2, const double& fX3);
+      Vector3D(const Vector3D& rkV);
+
+      std::string toString() const;
+
+      // coordinate access
+      operator const double*() const;
+      operator double*();
+      double   operator[](const int& i) const;
+      double&  operator[](const int& i);
+      double   X1() const;
+      double&  X1();
+      double   X2() const;
+      double&  X2();                                    
+      double   X3() const;
+      double&  X3();
+
+      // assignment
+      Vector3D& operator=(const Vector3D& rkV);
+
+      // comparison
+      bool operator==(const Vector3D& rkV) const;
+      bool operator!=(const Vector3D& rkV) const;
+      bool operator< (const Vector3D& rkV) const;
+      bool operator<=(const Vector3D& rkV) const;
+      bool operator> (const Vector3D& rkV) const;
+      bool operator>=(const Vector3D& rkV) const;
+
+      // arithmetic operations
+      Vector3D operator+(const Vector3D& rkV) const;
+      Vector3D operator-(const Vector3D& rkV) const;
+      Vector3D operator*(const double& fScalar) const;
+      Vector3D operator/(const double& fScalar) const;
+      Vector3D operator-() const;
+
+      // arithmetic updates
+      Vector3D& operator+= (const Vector3D& rkV);
+      Vector3D& operator-= (const Vector3D& rkV);
+      Vector3D& operator*= (const double& fScalar);
+      Vector3D& operator/= (const double& fScalar);
+
+      Vector3D Add(Vector3D& vector);
+      Vector3D Subtract(Vector3D& vector);
+      Vector3D Scale(const double& x);
+
+      // vector operations
+      double Length () const;
+      double SquaredLength () const;
+      double Dot (const Vector3D& rkV) const;
+      double Normalize ();
+
+      // The cross products are computed using the right-handed rule.  Be aware
+      // that some graphics APIs use a left-handed rule.  If you have to compute
+      // a cross product with these functions and send the result to the API
+      // that expects left-handed, you will need to change sign on the vector
+      // (replace each component value c by -c).
+      Vector3D Cross (const Vector3D& rkV) const;
+      Vector3D UnitCross (const Vector3D& rkV) const;
+
+      // Compute the barycentric coordinates of the point with respect to the
+      // tetrahedron <V0,V1,V2,V3>, P = b0*V0 + b1*V1 + b2*V2 + b3*V3, where
+      // b0 + b1 + b2 + b3 = 1.
+      void GetBarycentrics (const Vector3D& rkV0, const Vector3D& rkV1, const Vector3D& rkV2, const Vector3D& rkV3, double afBary[4]) const;
+
+      // Gram-Schmidt orthonormalization.  Take linearly independent vectors
+      // U, V, and W and compute an orthonormal set (unit length, mutually
+      // perpendicular).
+      static void Orthonormalize (Vector3D& rkU, Vector3D& rkV, Vector3D& rkW);
+      static void Orthonormalize (Vector3D* akV);
+
+      // Input W must be initialized to a nonzero vector, output is {U,V,W},
+      // an orthonormal basis.  A hint is provided about whether or not W
+      // is already unit length.
+      static void GenerateOrthonormalBasis (Vector3D& rkU, Vector3D& rkV, Vector3D& rkW, bool bUnitLengthW);
+
+      // special vectors
+      static const Vector3D ZERO;
+      static const Vector3D UNIT_X1;
+      static const Vector3D UNIT_X2;
+      static const Vector3D UNIT_X3;
+
+   #ifdef CAB_RCF
+         template<class Archive>
+         void serialize(Archive & ar, const unsigned int version)
+         {
+            ar & m_afTuple;
+         }
+   #endif //CAB_RCF
+
+   protected:
+      // support for comparisons
+      int CompareArrays (const Vector3D& rkV) const;
+
+      double m_afTuple[3];
+   };
+   
+   //globaler multiplaktor mit skalar
+   Vector3D operator*(const double& fScalar, const Vector3D& rkV);
+   std::ostream& operator<<(std::ostream& os, const Vector3D& rkV);
+
+  
+#endif
diff --git a/source/ThirdParty/Library/numerics/geometry3d/CoordinateTransformation3D.h b/source/ThirdParty/Library/numerics/geometry3d/CoordinateTransformation3D.h
index 23cf071a5..203ef5df1 100644
--- a/source/ThirdParty/Library/numerics/geometry3d/CoordinateTransformation3D.h
+++ b/source/ThirdParty/Library/numerics/geometry3d/CoordinateTransformation3D.h
@@ -1,183 +1,184 @@
-//  _    ___      __              __________      _     __
-// | |  / (_)____/ /___  ______ _/ / ____/ /_  __(_)___/ /____
-// | | / / / ___/ __/ / / / __ `/ / /_  / / / / / / __  / ___/
-// | |/ / / /  / /_/ /_/ / /_/ / / __/ / / /_/ / / /_/ (__  )
-// |___/_/_/   \__/\__,_/\__,_/_/_/   /_/\__,_/_/\__,_/____/
-//
-#ifndef COORDINATETRANSFORMATION3D_H
-#define COORDINATETRANSFORMATION3D_H
-
-#ifdef RCF_USE_BOOST_SERIALIZATION
-   #include <boost/archive/text_oarchive.hpp>
-   #include <boost/archive/text_iarchive.hpp>	
-#endif //RCF_USE_BOOST_SERIALIZATION
-
-#include <cmath>
-#include <string>
-#include <sstream>
-
-#include <basics/utilities/UbException.h>
-#include <basics/utilities/UbFileInput.h>
-#include <basics/utilities/UbFileOutput.h>
-
-#include <basics/memory/MbSharedPointerDefines.h>
-class CoordinateTransformation3D;
-typedef VFSharedPtr<CoordinateTransformation3D> CoordinateTransformation3DPtr;
-
-#include <boost/serialization/serialization.hpp>
-
-//description:     x1/x2/x3 = alt, x1*/x2*/x3* = neu
-//   x2      
-//   ^             x*
-//   |            /
-//   |           2*
-//   4          /
-//   |         /
-//   3        1*                     => neues coordsys ist um originX1=originX2=originX3=2 verschoben
-//   |       /                          neues dx1=dx2=dx2=2 -> skalierung um 2 in x1-,x2- und x3-richtung
-//   2      /                           ERST verdrehung um alpha um "x1" achse
-//   |       \                          DANN verdrehung um beta  um "x2" achse
-//   1         \                        DANN verdrehung um gamma um "x3" achse
-//   |           x1*
-//   |--1--2--3--4--5------------- > x1
-//
-// Bemerkung: kann sein, dass die Verdrehung um x1 und x3 vertauschst sind 
-//            - muss mal einer prüfen ...
-
-
-
-class CoordinateTransformation3D
-{
-public:
-   CoordinateTransformation3D();
-   CoordinateTransformation3D(const double& originX1, const double& originX2, const double& originX3, const double& dx1, const double& dx2, const double& dx3, const double& alpha, const double& beta, const double& gamma);
-   CoordinateTransformation3D(const double& originX1, const double& originX2, const double& originX3, const double& dx1, const double& dx2, const double& dx3);
-   CoordinateTransformation3D(CoordinateTransformation3D* transformation);
-   
-   void setTransformationValues(const double& originX1, const double& originX2, const double& originX3, const double& dx1, const double& dx2, const double& dx3, const double& alpha, const double& beta, const double& gamma);
-   double getX1CoordinateOffset()  const { return this->Tx1;   }   //Translation
-   double getX2CoordinateOffset()  const { return this->Tx2;   }
-   double getX3CoordinateOffset()  const { return this->Tx3;   }
-   double getX1CoordinateScaling() const { return this->Sx1;   }	 //Scaling
-   double getX2CoordinateScaling() const { return this->Sx2;   }
-   double getX3CoordinateScaling() const { return this->Sx3;   }
-   double getRotationX1Angle()     const { return this->alpha; }
-   double getRotationX2Angle()     const { return this->beta;  }
-   double getRotationX3Angle()     const { return this->gamma; }	 //Rotation
-
-   //Achtung die Winkel passen nicht überein -siehe setTransformationValues 
-   void setRotationX1Angle(double alpha) { this->setTransformationValues(this->Tx1, this->Tx2, this->Tx3, this->Sx1, this->Sx2, this->Sx3, alpha, this->beta, this->gamma); }
-   void setRotationX2Angle(double beta ) { this->setTransformationValues(this->Tx1, this->Tx2, this->Tx3, this->Sx1, this->Sx2, this->Sx3, this->alpha, beta, this->gamma); }
-   void setRotationX3Angle(double gamma) { this->setTransformationValues(this->Tx1, this->Tx2, this->Tx3, this->Sx1, this->Sx2, this->Sx3, this->alpha, this->beta, gamma); }
-
-   void setActive(const bool& active);
-   bool isActive()          const { return this->active; }
-   bool isTransformation()  const { return this->transformation; }
-
-   double transformForwardToX1Coordinate(const double& x1, const double& x2, const double& x3) const;
-   double transformForwardToX2Coordinate(const double& x1, const double& x2, const double& x3) const;
-   double transformForwardToX3Coordinate(const double& x1, const double& x2, const double& x3) const;
-   double transformForwardToX1CoordinateIgnoringRotation(const double& x1) const;
-   double transformForwardToX2CoordinateIgnoringRotation(const double& x2) const;
-   double transformForwardToX3CoordinateIgnoringRotation(const double& x3) const;
-   double transformBackwardToX1Coordinate(const double& x1, const double& x2, const double& x3) const;
-   double transformBackwardToX2Coordinate(const double& x1, const double& x2, const double& x3) const;
-   double transformBackwardToX3Coordinate(const double& x1, const double& x2, const double& x3) const;
-   double transformBackwardToX1CoordinateIgnoringRotation(const double& x1) const;
-   double transformBackwardToX2CoordinateIgnoringRotation(const double& x2) const;
-   double transformBackwardToX3CoordinateIgnoringRotation(const double& x3) const;
-   std::string toString() const;
-
-   //------------- implements CAB serialization ----- start
-   void write(UbFileOutput* out) const
-   {
-      out->writeString("Coordtransfomartion3D");
-      out->writeDouble(this->Tx1);
-      out->writeDouble(this->Tx2);
-      out->writeDouble(this->Tx3);
-      out->writeDouble(this->Sx1);
-      out->writeDouble(this->Sx2);
-      out->writeDouble(this->Sx3);
-      out->writeDouble(this->alpha);
-      out->writeDouble(this->beta );
-      out->writeDouble(this->gamma);
-   }
-   void read(UbFileInput* in)
-   {
-      in->readString();
-      this->Tx1   = in->readDouble();
-      this->Tx2   = in->readDouble();
-      this->Tx3   = in->readDouble();
-      this->Sx1   = in->readDouble();
-      this->Sx2   = in->readDouble();
-      this->Sx3   = in->readDouble();
-      this->alpha = in->readDouble();
-      this->beta  = in->readDouble();
-      this->gamma = in->readDouble();
-
-      this->setTransformationValues(Tx1,Tx2,Tx3,Sx1,Sx2,Sx3,alpha,beta,gamma);
-   }
-   //------------- implements CAB serialization ----- end
-
-#ifdef CAB_RCF
-   template<class Archive>
-   void SF_SERIALIZE(Archive & ar)
-   {
-      ar & Tx1;   ar & Tx2; ar & Tx3; 
-      ar & Sx1;   ar & Sx2; ar & Sx3; 
-      ar & alpha; ar & beta; ar & gamma;
-      
-      ar & toX1factorX1; ar & toX1factorX2; ar & toX1factorX3; ar & toX1delta;
-      ar & toX2factorX1; ar & toX2factorX2; ar & toX2factorX3; ar & toX2delta;
-      ar & toX3factorX1; ar & toX3factorX2; ar & toX3factorX3; ar & toX3delta;
-
-      ar & fromX1factorX1; ar & fromX1factorX2; ar & fromX1factorX3; ar & fromX1delta;
-      ar & fromX2factorX1; ar & fromX2factorX2; ar & fromX2factorX3; ar & fromX2delta;
-      ar & fromX3factorX1; ar & fromX3factorX2; ar & fromX3factorX3; ar & fromX3delta;
-
-      ar & active;
-      ar & transformation;
-   }
-#endif //CAB_RCF
-
-private:
-   double Tx1, Tx2, Tx3, Sx1, Sx2, Sx3, alpha, beta, gamma;
-
-   double toX1factorX1, toX1factorX2, toX1factorX3, toX1delta;
-   double toX2factorX1, toX2factorX2, toX2factorX3, toX2delta;
-   double toX3factorX1, toX3factorX2, toX3factorX3, toX3delta;
-
-   double fromX1factorX1, fromX1factorX2, fromX1factorX3, fromX1delta;
-   double fromX2factorX1, fromX2factorX2, fromX2factorX3, fromX2delta;
-   double fromX3factorX1, fromX3factorX2, fromX3factorX3, fromX3delta;
-
-   bool   active;
-   bool   transformation;
-
-   friend class MPIIORestart1CoProcessor;
-   friend class MPIIORestart2CoProcessor;
-   friend class MPIIORestart11CoProcessor;
-   friend class MPIIORestart21CoProcessor;
-
-   friend class boost::serialization::access;
-   template<class Archive>
-   void serialize(Archive & ar, const unsigned int version)
-   {
-      ar & Tx1;   ar & Tx2; ar & Tx3; 
-      ar & Sx1;   ar & Sx2; ar & Sx3; 
-      ar & alpha; ar & beta; ar & gamma;
-
-      ar & toX1factorX1; ar & toX1factorX2; ar & toX1factorX3; ar & toX1delta;
-      ar & toX2factorX1; ar & toX2factorX2; ar & toX2factorX3; ar & toX2delta;
-      ar & toX3factorX1; ar & toX3factorX2; ar & toX3factorX3; ar & toX3delta;
-
-      ar & fromX1factorX1; ar & fromX1factorX2; ar & fromX1factorX3; ar & fromX1delta;
-      ar & fromX2factorX1; ar & fromX2factorX2; ar & fromX2factorX3; ar & fromX2delta;
-      ar & fromX3factorX1; ar & fromX3factorX2; ar & fromX3factorX3; ar & fromX3delta;
-
-      ar & active;
-      ar & transformation;
-   }
-};
-
-#endif //COORDINATETRANSFORMATION3D_H
+//  _    ___      __              __________      _     __
+// | |  / (_)____/ /___  ______ _/ / ____/ /_  __(_)___/ /____
+// | | / / / ___/ __/ / / / __ `/ / /_  / / / / / / __  / ___/
+// | |/ / / /  / /_/ /_/ / /_/ / / __/ / / /_/ / / /_/ (__  )
+// |___/_/_/   \__/\__,_/\__,_/_/_/   /_/\__,_/_/\__,_/____/
+//
+#ifndef COORDINATETRANSFORMATION3D_H
+#define COORDINATETRANSFORMATION3D_H
+
+#ifdef RCF_USE_BOOST_SERIALIZATION
+   #include <boost/archive/text_oarchive.hpp>
+   #include <boost/archive/text_iarchive.hpp>	
+#endif //RCF_USE_BOOST_SERIALIZATION
+
+#include <cmath>
+#include <string>
+#include <sstream>
+
+#include <basics/utilities/UbException.h>
+#include <basics/utilities/UbFileInput.h>
+#include <basics/utilities/UbFileOutput.h>
+
+#include <basics/memory/MbSharedPointerDefines.h>
+class CoordinateTransformation3D;
+typedef std::shared_ptr<CoordinateTransformation3D> CoordinateTransformation3DPtr;
+
+#include <boost/serialization/serialization.hpp>
+
+//description:     x1/x2/x3 = alt, x1*/x2*/x3* = neu
+//   x2      
+//   ^             x*
+//   |            /
+//   |           2*
+//   4          /
+//   |         /
+//   3        1*                     => neues coordsys ist um originX1=originX2=originX3=2 verschoben
+//   |       /                          neues dx1=dx2=dx2=2 -> skalierung um 2 in x1-,x2- und x3-richtung
+//   2      /                           ERST verdrehung um alpha um "x1" achse
+//   |       \                          DANN verdrehung um beta  um "x2" achse
+//   1         \                        DANN verdrehung um gamma um "x3" achse
+//   |           x1*
+//   |--1--2--3--4--5------------- > x1
+//
+// Bemerkung: kann sein, dass die Verdrehung um x1 und x3 vertauschst sind 
+//            - muss mal einer prüfen ...
+
+
+
+class CoordinateTransformation3D
+{
+public:
+   CoordinateTransformation3D();
+   CoordinateTransformation3D(const double& originX1, const double& originX2, const double& originX3, const double& dx1, const double& dx2, const double& dx3, const double& alpha, const double& beta, const double& gamma);
+   CoordinateTransformation3D(const double& originX1, const double& originX2, const double& originX3, const double& dx1, const double& dx2, const double& dx3);
+   CoordinateTransformation3D(CoordinateTransformation3D* transformation);
+   
+   void setTransformationValues(const double& originX1, const double& originX2, const double& originX3, const double& dx1, const double& dx2, const double& dx3, const double& alpha, const double& beta, const double& gamma);
+   double getX1CoordinateOffset()  const { return this->Tx1;   }   //Translation
+   double getX2CoordinateOffset()  const { return this->Tx2;   }
+   double getX3CoordinateOffset()  const { return this->Tx3;   }
+   double getX1CoordinateScaling() const { return this->Sx1;   }	 //Scaling
+   double getX2CoordinateScaling() const { return this->Sx2;   }
+   double getX3CoordinateScaling() const { return this->Sx3;   }
+   double getRotationX1Angle()     const { return this->alpha; }
+   double getRotationX2Angle()     const { return this->beta;  }
+   double getRotationX3Angle()     const { return this->gamma; }	 //Rotation
+
+   //Achtung die Winkel passen nicht überein -siehe setTransformationValues 
+   void setRotationX1Angle(double alpha) { this->setTransformationValues(this->Tx1, this->Tx2, this->Tx3, this->Sx1, this->Sx2, this->Sx3, alpha, this->beta, this->gamma); }
+   void setRotationX2Angle(double beta ) { this->setTransformationValues(this->Tx1, this->Tx2, this->Tx3, this->Sx1, this->Sx2, this->Sx3, this->alpha, beta, this->gamma); }
+   void setRotationX3Angle(double gamma) { this->setTransformationValues(this->Tx1, this->Tx2, this->Tx3, this->Sx1, this->Sx2, this->Sx3, this->alpha, this->beta, gamma); }
+
+   void setActive(const bool& active);
+   bool isActive()          const { return this->active; }
+   bool isTransformation()  const { return this->transformation; }
+
+   double transformForwardToX1Coordinate(const double& x1, const double& x2, const double& x3) const;
+   double transformForwardToX2Coordinate(const double& x1, const double& x2, const double& x3) const;
+   double transformForwardToX3Coordinate(const double& x1, const double& x2, const double& x3) const;
+   double transformForwardToX1CoordinateIgnoringRotation(const double& x1) const;
+   double transformForwardToX2CoordinateIgnoringRotation(const double& x2) const;
+   double transformForwardToX3CoordinateIgnoringRotation(const double& x3) const;
+   double transformBackwardToX1Coordinate(const double& x1, const double& x2, const double& x3) const;
+   double transformBackwardToX2Coordinate(const double& x1, const double& x2, const double& x3) const;
+   double transformBackwardToX3Coordinate(const double& x1, const double& x2, const double& x3) const;
+   double transformBackwardToX1CoordinateIgnoringRotation(const double& x1) const;
+   double transformBackwardToX2CoordinateIgnoringRotation(const double& x2) const;
+   double transformBackwardToX3CoordinateIgnoringRotation(const double& x3) const;
+   std::string toString() const;
+
+   //------------- implements CAB serialization ----- start
+   void write(UbFileOutput* out) const
+   {
+      out->writeString("Coordtransfomartion3D");
+      out->writeDouble(this->Tx1);
+      out->writeDouble(this->Tx2);
+      out->writeDouble(this->Tx3);
+      out->writeDouble(this->Sx1);
+      out->writeDouble(this->Sx2);
+      out->writeDouble(this->Sx3);
+      out->writeDouble(this->alpha);
+      out->writeDouble(this->beta );
+      out->writeDouble(this->gamma);
+   }
+   void read(UbFileInput* in)
+   {
+      in->readString();
+      this->Tx1   = in->readDouble();
+      this->Tx2   = in->readDouble();
+      this->Tx3   = in->readDouble();
+      this->Sx1   = in->readDouble();
+      this->Sx2   = in->readDouble();
+      this->Sx3   = in->readDouble();
+      this->alpha = in->readDouble();
+      this->beta  = in->readDouble();
+      this->gamma = in->readDouble();
+
+      this->setTransformationValues(Tx1,Tx2,Tx3,Sx1,Sx2,Sx3,alpha,beta,gamma);
+   }
+   //------------- implements CAB serialization ----- end
+
+#ifdef CAB_RCF
+   template<class Archive>
+   void SF_SERIALIZE(Archive & ar)
+   {
+      ar & Tx1;   ar & Tx2; ar & Tx3; 
+      ar & Sx1;   ar & Sx2; ar & Sx3; 
+      ar & alpha; ar & beta; ar & gamma;
+      
+      ar & toX1factorX1; ar & toX1factorX2; ar & toX1factorX3; ar & toX1delta;
+      ar & toX2factorX1; ar & toX2factorX2; ar & toX2factorX3; ar & toX2delta;
+      ar & toX3factorX1; ar & toX3factorX2; ar & toX3factorX3; ar & toX3delta;
+
+      ar & fromX1factorX1; ar & fromX1factorX2; ar & fromX1factorX3; ar & fromX1delta;
+      ar & fromX2factorX1; ar & fromX2factorX2; ar & fromX2factorX3; ar & fromX2delta;
+      ar & fromX3factorX1; ar & fromX3factorX2; ar & fromX3factorX3; ar & fromX3delta;
+
+      ar & active;
+      ar & transformation;
+   }
+#endif //CAB_RCF
+
+private:
+   double Tx1, Tx2, Tx3, Sx1, Sx2, Sx3, alpha, beta, gamma;
+
+   double toX1factorX1, toX1factorX2, toX1factorX3, toX1delta;
+   double toX2factorX1, toX2factorX2, toX2factorX3, toX2delta;
+   double toX3factorX1, toX3factorX2, toX3factorX3, toX3delta;
+
+   double fromX1factorX1, fromX1factorX2, fromX1factorX3, fromX1delta;
+   double fromX2factorX1, fromX2factorX2, fromX2factorX3, fromX2delta;
+   double fromX3factorX1, fromX3factorX2, fromX3factorX3, fromX3delta;
+
+   bool   active;
+   bool   transformation;
+
+   friend class MPIIORestartCoProcessor;
+   friend class MPIIORestart1CoProcessor;
+   friend class MPIIORestart2CoProcessor;
+   friend class MPIIORestart11CoProcessor;
+   friend class MPIIORestart21CoProcessor;
+
+   friend class boost::serialization::access;
+   template<class Archive>
+   void serialize(Archive & ar, const unsigned int version)
+   {
+      ar & Tx1;   ar & Tx2; ar & Tx3; 
+      ar & Sx1;   ar & Sx2; ar & Sx3; 
+      ar & alpha; ar & beta; ar & gamma;
+
+      ar & toX1factorX1; ar & toX1factorX2; ar & toX1factorX3; ar & toX1delta;
+      ar & toX2factorX1; ar & toX2factorX2; ar & toX2factorX3; ar & toX2delta;
+      ar & toX3factorX1; ar & toX3factorX2; ar & toX3factorX3; ar & toX3delta;
+
+      ar & fromX1factorX1; ar & fromX1factorX2; ar & fromX1factorX3; ar & fromX1delta;
+      ar & fromX2factorX1; ar & fromX2factorX2; ar & fromX2factorX3; ar & fromX2delta;
+      ar & fromX3factorX1; ar & fromX3factorX2; ar & fromX3factorX3; ar & fromX3delta;
+
+      ar & active;
+      ar & transformation;
+   }
+};
+
+#endif //COORDINATETRANSFORMATION3D_H
diff --git a/source/ThirdParty/Library/numerics/geometry3d/GbObject3D.h b/source/ThirdParty/Library/numerics/geometry3d/GbObject3D.h
index 48cb40af7..a8d8fbc8d 100644
--- a/source/ThirdParty/Library/numerics/geometry3d/GbObject3D.h
+++ b/source/ThirdParty/Library/numerics/geometry3d/GbObject3D.h
@@ -121,7 +121,8 @@ public:
    virtual void setCenterX1Coordinate(const double& value) { throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() ); }
    virtual void setCenterX2Coordinate(const double& value) { throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() ); }
    virtual void setCenterX3Coordinate(const double& value) { throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() ); }
-   virtual void setCenterCoordinates(const double& x1, const double& x2, const double& x3) { throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() ); }
+   virtual void setCenterCoordinates(const double& x1, const double& x2, const double& x3) { throw UbException(UB_EXARGS, "not implemented for " + (std::string)typeid(*this).name()); }
+   virtual void setCenterCoordinates(const UbTupleDouble3& position) { throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() ); }
 
    //Rotates the Point in relation to the origen.
    //Parameters must be radian measure.
diff --git a/source/ThirdParty/Library/numerics/geometry3d/GbSphere3D.cpp b/source/ThirdParty/Library/numerics/geometry3d/GbSphere3D.cpp
index 064cc0cff..c6a5f98f1 100644
--- a/source/ThirdParty/Library/numerics/geometry3d/GbSphere3D.cpp
+++ b/source/ThirdParty/Library/numerics/geometry3d/GbSphere3D.cpp
@@ -73,11 +73,22 @@ void GbSphere3D::finalize()
 
    if(this->midPoint) this->midPoint->removeObserver(this);
 }
+/*=====================================================*/
+bool GbSphere3D::intersects(GbSphere3DPtr sphere)
+{
+    return this->getDistance(sphere->midPoint) < radius + sphere->radius;
+}
 /*=======================================================*/
 void GbSphere3D::setCenterCoordinates(const double& x1, const double& x2, const double& x3)
 {
    this->translate(x1-getX1Centroid(), x2-getX2Centroid(), x3-getX3Centroid() );
 }
+
+void GbSphere3D::setCenterCoordinates(const UbTupleDouble3& position)
+{
+    this->setCenterCoordinates(val<1>(position), val<2>(position), val<3>(position));
+}
+
 /*=====================================================*/
 double GbSphere3D::getDistance(GbPoint3D* p)
 {
@@ -410,7 +421,7 @@ void GbSphere3D::addSurfaceTriangleSet(vector<UbTupleFloat3>& nodes, vector<UbTu
       float deltaPhi = (float)UbMath::PI/(float)segments;
       float phiX1a,phiX1b,phiX3a,phiX3b;
       float x1a,x2a,x3a,x1b,x2b,x3b,x1c,x2c,x3c,x1d,x2d,x3d;
-      int nodeNr = 0;
+      int nodeNr = nodes.size();
       for(phiX3a=(float)(0.5*UbMath::PI); phiX3a > (float)(-1.5*UbMath::PI); phiX3a-=deltaPhi)
       {
          for(phiX1a=0.0; phiX1a<UbMath::PI; phiX1a+=deltaPhi)
diff --git a/source/ThirdParty/Library/numerics/geometry3d/GbSphere3D.h b/source/ThirdParty/Library/numerics/geometry3d/GbSphere3D.h
index f9d4d86ea..86e526df3 100644
--- a/source/ThirdParty/Library/numerics/geometry3d/GbSphere3D.h
+++ b/source/ThirdParty/Library/numerics/geometry3d/GbSphere3D.h
@@ -48,6 +48,9 @@ public:
    GbSphere3D* clone() { return new GbSphere3D(*this);}
    void finalize();
 
+
+   bool intersects(GbSphere3DPtr sphere);
+
    double getRadius() const	{	return this->radius;	}
 
    double getX1Centroid()  { return midPoint->getX1Coordinate();}
@@ -64,6 +67,7 @@ public:
    void setCenterX2Coordinate(const double& value);
    void setCenterX3Coordinate(const double& value);
    void setCenterCoordinates(const double& x1, const double& x2, const double& x3);
+   virtual void setCenterCoordinates(const UbTupleDouble3& position);
    void setRadius(const double& radius);
 
    GbLine3D* createClippedLine3D(GbPoint3D& point1, GbPoint3D& point2);
diff --git a/source/ThirdParty/Library/numerics/geometry3d/GbTriFaceMesh3D.h b/source/ThirdParty/Library/numerics/geometry3d/GbTriFaceMesh3D.h
index 05c3635e9..21912a2cc 100644
--- a/source/ThirdParty/Library/numerics/geometry3d/GbTriFaceMesh3D.h
+++ b/source/ThirdParty/Library/numerics/geometry3d/GbTriFaceMesh3D.h
@@ -18,6 +18,7 @@
 
 #include <basics/utilities/UbException.h>
 #include <basics/utilities/UbMath.h>
+#include <basics/utilities/Vector3D.h>
 #include <basics/writer/WbWriter.h>
 
 #include <basics/memory/MbSmartPtr.h>
@@ -186,12 +187,12 @@ public:
          //GbVector3D AC = C-A;
          //GbVector3D N = AB.Cross(AC);
          //return 0.5*N.Length();
-         UbMath::Vector3D A(nodes[v1].x, nodes[v1].y, nodes[v1].z);
-         UbMath::Vector3D B(nodes[v2].x, nodes[v2].y, nodes[v2].z);
-         UbMath::Vector3D C(nodes[v3].x, nodes[v3].y, nodes[v3].z);
-         UbMath::Vector3D AB = B-A;
-         UbMath::Vector3D AC = C-A;
-         UbMath::Vector3D N = AB.Cross(AC);
+         Vector3D A(nodes[v1].x, nodes[v1].y, nodes[v1].z);
+         Vector3D B(nodes[v2].x, nodes[v2].y, nodes[v2].z);
+         Vector3D C(nodes[v3].x, nodes[v3].y, nodes[v3].z);
+         Vector3D AB = B-A;
+         Vector3D AC = C-A;
+         Vector3D N = AB.Cross(AC);
          return 0.5*N.Length();
       }
       void calculateNormal(std::vector<Vertex>& nodes)
diff --git a/source/VirtualFluids.h b/source/VirtualFluids.h
index 04a1916ec..147db5204 100644
--- a/source/VirtualFluids.h
+++ b/source/VirtualFluids.h
@@ -304,10 +304,11 @@
 #include <InitDistributionsWithInterpolationGridVisitor.h>
 #include <CheckRatioBlockVisitor.h>
 #include <SpongeLayerBlockVisitor.h>
-
 #include <Visitors/RefineCrossAndInsideGbObjectHelper.h>
 #include <RefineAroundGbObjectHelper.h>
 
+#include <Grid/ConcreteCalculatorFactory.h>
+
 #if defined VF_FETOL
    #include <FETOL/FETOLCalculator.h>
    #include <FETOL/FETOLCommunicator.h>
diff --git a/source/VirtualFluidsCore/BoundaryConditions/BCAdapter.h b/source/VirtualFluidsCore/BoundaryConditions/BCAdapter.h
index c8e29bfc7..075ff2e9b 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/BCAdapter.h
+++ b/source/VirtualFluidsCore/BoundaryConditions/BCAdapter.h
@@ -14,10 +14,10 @@
 #include <boost/serialization/serialization.hpp>
 #include <boost/serialization/base_object.hpp>
 #include <boost/serialization/export.hpp>
-#include <boost/shared_ptr.hpp>
+#include <memory>
 
 class BCAdapter;
-typedef boost::shared_ptr<BCAdapter> BCAdapterPtr;
+typedef std::shared_ptr<BCAdapter> BCAdapterPtr;
 
 #include "BoundaryConditions.h"
 #include "basics/objects/ObObject.h"
diff --git a/source/VirtualFluidsCore/BoundaryConditions/BCAlgorithm.cpp b/source/VirtualFluidsCore/BoundaryConditions/BCAlgorithm.cpp
index a7ea21360..54894d8f8 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/BCAlgorithm.cpp
+++ b/source/VirtualFluidsCore/BoundaryConditions/BCAlgorithm.cpp
@@ -1,65 +1,70 @@
-#include "BCAlgorithm.h"
-
-BCAlgorithm::BCAlgorithm() : compressible(false)
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-void BCAlgorithm::setNodeIndex(int x1, int x2, int x3)
-{
-   this->x1 = x1;
-   this->x2 = x2;
-   this->x3 = x3;
-}
-//////////////////////////////////////////////////////////////////////////
-void BCAlgorithm::setBcPointer(BoundaryConditionsPtr bcPtr)
-{
-   this->bcPtr = bcPtr;
-}
-//////////////////////////////////////////////////////////////////////////
-void BCAlgorithm::setCompressible(bool c)
-{
-   compressible = c;
-
-   if (this->compressible)
-   {
-      calcFeqsForDirFct = &D3Q27System::getCompFeqForDirection;
-      calcMacrosFct = &D3Q27System::calcCompMacroscopicValues;
-      calcFeqFct = &D3Q27System::calcCompFeq;
-      compressibleFactor = 1.0;
-   }
-   else
-   {
-      calcFeqsForDirFct = &D3Q27System::getIncompFeqForDirection;
-      calcMacrosFct = &D3Q27System::calcIncompMacroscopicValues;
-      calcFeqFct = &D3Q27System::calcIncompFeq;
-      compressibleFactor = 0.0;
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void BCAlgorithm::setCollFactor(LBMReal cf)
-{
-   collFactor = cf;
-}
-
-//////////////////////////////////////////////////////////////////////////
-char BCAlgorithm::getType()
-{
-   return type;
-}
-//////////////////////////////////////////////////////////////////////////
-bool BCAlgorithm::isPreCollision()
-{
-   return preCollision;
-}
-//////////////////////////////////////////////////////////////////////////
-BCArray3DPtr BCAlgorithm::getBcArray()
-{
-   return bcArray;
-}
-//////////////////////////////////////////////////////////////////////////
-void BCAlgorithm::setBcArray(BCArray3DPtr bcarray)
-{
-   bcArray = bcarray;
-}
-
+#include "BCAlgorithm.h"
+
+#include "BoundaryConditions.h"
+#include "EsoTwist3D.h"
+#include "BCArray3D.h"
+
+
+BCAlgorithm::BCAlgorithm() : compressible(false)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void BCAlgorithm::setNodeIndex(int x1, int x2, int x3)
+{
+    this->x1 = x1;
+    this->x2 = x2;
+    this->x3 = x3;
+}
+//////////////////////////////////////////////////////////////////////////
+void BCAlgorithm::setBcPointer(BoundaryConditionsPtr bcPtr)
+{
+    this->bcPtr = bcPtr;
+}
+//////////////////////////////////////////////////////////////////////////
+void BCAlgorithm::setCompressible(bool c)
+{
+   compressible = c;
+
+   if (this->compressible)
+   {
+      calcFeqsForDirFct = &D3Q27System::getCompFeqForDirection;
+      calcMacrosFct = &D3Q27System::calcCompMacroscopicValues;
+      calcFeqFct = &D3Q27System::calcCompFeq;
+      compressibleFactor = 1.0;
+   }
+   else
+   {
+      calcFeqsForDirFct = &D3Q27System::getIncompFeqForDirection;
+      calcMacrosFct = &D3Q27System::calcIncompMacroscopicValues;
+      calcFeqFct = &D3Q27System::calcIncompFeq;
+      compressibleFactor = 0.0;
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void BCAlgorithm::setCollFactor(LBMReal cf)
+{
+   collFactor = cf;
+}
+
+//////////////////////////////////////////////////////////////////////////
+char BCAlgorithm::getType()
+{
+   return type;
+}
+//////////////////////////////////////////////////////////////////////////
+bool BCAlgorithm::isPreCollision()
+{
+   return preCollision;
+}
+//////////////////////////////////////////////////////////////////////////
+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 2b4342a1c..7781e7ba3 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/BCAlgorithm.h
+++ b/source/VirtualFluidsCore/BoundaryConditions/BCAlgorithm.h
@@ -1,75 +1,69 @@
-
-#ifndef BOUNDARYCONDITIONS_H
-#define BOUNDARYCONDITIONS_H
-
-#include <vector>
-#include <string>
-
-#include "BoundaryConditions.h"
-#include "D3Q27System.h"
-#include "EsoTwist3D.h"
-#include "BCArray3D.h"
-
-#include <boost/serialization/serialization.hpp>
-#include <boost/serialization/base_object.hpp>
-#include <boost/serialization/export.hpp>
-
-#include <boost/shared_ptr.hpp>
-
-class BCAlgorithm;
-typedef boost::shared_ptr<BCAlgorithm> BCAlgorithmPtr;
-
-class BCAlgorithm
-{
-public:
-   static const char VelocityBCAlgorithm = 0;
-   static const char EqDensityBCAlgorithm = 1;
-   static const char NonEqDensityBCAlgorithm = 2;
-   static const char NoSlipBCAlgorithm = 3;
-   static const char SlipBCAlgorithm = 4;
-   static const char HighViscosityNoSlipBCAlgorithm = 5;
-   static const char ThinWallNoSlipBCAlgorithm = 6;
-   static const char VelocityWithDensityBCAlgorithm = 7;
-   static const char NonReflectingOutflowBCAlgorithm = 8;
-
-public:
-   BCAlgorithm();
-   virtual ~BCAlgorithm() {}
-   
-   virtual void addDistributions(DistributionArray3DPtr distributions) = 0;
-   void setNodeIndex(int x1, int x2, int x3);
-   void setBcPointer(BoundaryConditionsPtr bcPtr);
-   void setCompressible(bool c);
-   void setCollFactor(LBMReal cf);
-   char getType();
-   bool isPreCollision();
-   virtual BCAlgorithmPtr clone()=0;
-   BCArray3DPtr getBcArray();
-   void setBcArray(BCArray3DPtr bcarray);
-   virtual void applyBC() = 0;
-
-protected:
-   bool compressible;
-   char type;
-   bool preCollision;
-
-   BoundaryConditionsPtr bcPtr;
-   DistributionArray3DPtr distributions;
-   BCArray3DPtr bcArray;
-
-   LBMReal collFactor;
-   int x1, x2, x3;
-
-   LBMReal compressibleFactor;
-
-   typedef void(*CalcMacrosFct)(const LBMReal* const& /*f[27]*/, LBMReal& /*rho*/, LBMReal& /*vx1*/, LBMReal& /*vx2*/, LBMReal& /*vx3*/);
-   typedef LBMReal(*CalcFeqForDirFct)(const int& /*direction*/, const LBMReal& /*(d)rho*/, const LBMReal& /*vx1*/, const LBMReal& /*vx2*/, const LBMReal& /*vx3*/);
-   typedef  void(*CalcFeqFct)(LBMReal* const& /*feq/*[27]*/, const LBMReal& /*rho*/, const LBMReal& /*vx1*/, const LBMReal& /*vx2*/, const LBMReal& /*vx3*/);
-   
-   CalcFeqForDirFct calcFeqsForDirFct ;
-   CalcMacrosFct    calcMacrosFct;
-   CalcFeqFct       calcFeqFct;
-};
-
-
-#endif 
+
+#ifndef BOUNDARYCONDITIONS_H
+#define BOUNDARYCONDITIONS_H
+
+#include <memory>
+
+#include "D3Q27System.h"
+
+class DistributionArray3D;
+class BCArray3D;
+class BoundaryConditions;
+
+class BCAlgorithm;
+typedef std::shared_ptr<BCAlgorithm> BCAlgorithmPtr;
+
+class BCAlgorithm
+{
+public:
+   static const char VelocityBCAlgorithm = 0;
+   static const char EqDensityBCAlgorithm = 1;
+   static const char NonEqDensityBCAlgorithm = 2;
+   static const char NoSlipBCAlgorithm = 3;
+   static const char SlipBCAlgorithm = 4;
+   static const char HighViscosityNoSlipBCAlgorithm = 5;
+   static const char ThinWallNoSlipBCAlgorithm = 6;
+   static const char VelocityWithDensityBCAlgorithm = 7;
+   static const char NonReflectingOutflowBCAlgorithm = 8;
+
+public:
+   BCAlgorithm();
+   virtual ~BCAlgorithm() {}
+   
+   virtual void addDistributions(std::shared_ptr<DistributionArray3D> distributions) = 0;
+   void setNodeIndex(int x1, int x2, int x3);
+   void setBcPointer(std::shared_ptr<BoundaryConditions> bcPtr);
+   void setCompressible(bool c);
+   void setCollFactor(LBMReal cf);
+   char getType();
+   bool isPreCollision();
+   virtual BCAlgorithmPtr clone() = 0;
+   std::shared_ptr<BCArray3D> getBcArray();
+   void setBcArray(std::shared_ptr<BCArray3D> bcarray);
+   virtual void applyBC() = 0;
+
+protected:
+   bool compressible;
+   char type;
+   bool preCollision;
+
+   std::shared_ptr<BoundaryConditions> bcPtr;
+   std::shared_ptr<DistributionArray3D> distributions;
+   std::shared_ptr<BCArray3D> bcArray;
+
+   LBMReal collFactor;
+   int x1, x2, x3;
+
+   LBMReal compressibleFactor;
+
+   typedef void(*CalcMacrosFct)(const LBMReal* const& /*f[27]*/, LBMReal& /*rho*/, LBMReal& /*vx1*/, LBMReal& /*vx2*/, LBMReal& /*vx3*/);
+   typedef LBMReal(*CalcFeqForDirFct)(const int& /*direction*/, const LBMReal& /*(d)rho*/, const LBMReal& /*vx1*/, const LBMReal& /*vx2*/, const LBMReal& /*vx3*/);
+   typedef  void(*CalcFeqFct)(LBMReal* const& /*feq/*[27]*/, const LBMReal& /*rho*/, const LBMReal& /*vx1*/, const LBMReal& /*vx2*/, const LBMReal& /*vx3*/);
+   
+   CalcFeqForDirFct calcFeqsForDirFct ;
+   CalcMacrosFct    calcMacrosFct;
+   CalcFeqFct       calcFeqFct; 
+};
+
+
+#endif 
diff --git a/source/VirtualFluidsCore/BoundaryConditions/BCArray3D.h b/source/VirtualFluidsCore/BoundaryConditions/BCArray3D.h
index 4cc7cb6f4..29c1a99f1 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/BCArray3D.h
+++ b/source/VirtualFluidsCore/BoundaryConditions/BCArray3D.h
@@ -1,191 +1,203 @@
-#ifndef BCArray_H
-#define BCArray_H
-
-#include "BoundaryConditions.h"
-#include "basics/container/CbArray3D.h"
-
-#include <typeinfo>
-
-#include <boost/serialization/serialization.hpp>
-#include <boost/shared_ptr.hpp>
-
-class BCArray3D;
-typedef boost::shared_ptr<BCArray3D> BCArray3DPtr;
-
-class BCArray3D
-{
-public:
-   //////////////////////////////////////////////////////////////////////////
-   BCArray3D();
-   //////////////////////////////////////////////////////////////////////////
-   BCArray3D(std::size_t nx1, std::size_t nx2, std::size_t nx3);
-   //////////////////////////////////////////////////////////////////////////
-   BCArray3D(std::size_t nx1, std::size_t nx2, std::size_t nx3, int val);
-   //////////////////////////////////////////////////////////////////////////
-   virtual ~BCArray3D();
-   //////////////////////////////////////////////////////////////////////////
-   inline std::size_t getNX1() const;
-   //////////////////////////////////////////////////////////////////////////
-   inline std::size_t getNX2() const;
-   //////////////////////////////////////////////////////////////////////////
-   inline std::size_t getNX3() const;
-   //////////////////////////////////////////////////////////////////////////
-   void resize(std::size_t nx1, std::size_t nx2, std::size_t nx3);
-   //////////////////////////////////////////////////////////////////////////
-   void resize(std::size_t nx1, std::size_t nx2, std::size_t nx3, int val);
-   //////////////////////////////////////////////////////////////////////////
-   bool validIndices(std::size_t x1, std::size_t x2, std::size_t x3)  const;
-   //////////////////////////////////////////////////////////////////////////
-   inline bool hasBC(std::size_t x1, std::size_t x2, std::size_t x3)  const;
-   //////////////////////////////////////////////////////////////////////////
-   void setBC(std::size_t x1, std::size_t x2, std::size_t x3, BoundaryConditionsPtr const& bc);
-   //////////////////////////////////////////////////////////////////////////
-   inline int getBCVectorIndex(std::size_t x1, std::size_t x2, std::size_t x3) const;
-   //////////////////////////////////////////////////////////////////////////
-   inline const BoundaryConditionsPtr getBC(std::size_t x1, std::size_t x2, std::size_t x3) const;
-   //////////////////////////////////////////////////////////////////////////
-   inline BoundaryConditionsPtr getBC(std::size_t x1, std::size_t x2, std::size_t x3);
-   //////////////////////////////////////////////////////////////////////////
-   void setSolid(std::size_t x1, std::size_t x2, std::size_t x3);
-   //////////////////////////////////////////////////////////////////////////
-   inline bool isSolid(std::size_t x1, std::size_t x2, std::size_t x3) const;
-   //////////////////////////////////////////////////////////////////////////
-   void setFluid(std::size_t x1, std::size_t x2, std::size_t x3);
-   //////////////////////////////////////////////////////////////////////////
-   //true : FLUID or BC
-   //false: UNDEFINED or SOLID
-   inline bool isFluid(std::size_t x1, std::size_t x2, std::size_t x3) const;
-   //////////////////////////////////////////////////////////////////////////
-   inline bool isFluidWithoutBC(std::size_t x1, std::size_t x2, std::size_t x3) const;
-   //////////////////////////////////////////////////////////////////////////
-   inline bool isUndefined(std::size_t x1, std::size_t x2, std::size_t x3) const;
-   //////////////////////////////////////////////////////////////////////////
-   void setUndefined(std::size_t x1, std::size_t x2, std::size_t x3);
-   //////////////////////////////////////////////////////////////////////////
-   inline bool isInterfaceCF(std::size_t x1, std::size_t x2, std::size_t x3) const;
-   //////////////////////////////////////////////////////////////////////////
-   void setInterfaceCF(std::size_t x1, std::size_t x2, std::size_t x3);
-   //////////////////////////////////////////////////////////////////////////
-   inline bool isInterfaceFC(std::size_t x1, std::size_t x2, std::size_t x3) const;
-   //////////////////////////////////////////////////////////////////////////
-   void setInterfaceFC(std::size_t x1, std::size_t x2, std::size_t x3);
-   //////////////////////////////////////////////////////////////////////////
-   std::size_t getNumberOfSolidEntries() const;
-   //////////////////////////////////////////////////////////////////////////
-   std::size_t getNumberOfFluidEntries() const;
-   //////////////////////////////////////////////////////////////////////////
-   std::size_t getNumberOfFluidWithoutBCEntries() const;
-   //////////////////////////////////////////////////////////////////////////
-   std::size_t getNumberOfBCEntries() const;
-   //////////////////////////////////////////////////////////////////////////
-   std::size_t getNumberOfUndefinedEntries() const;
-   //////////////////////////////////////////////////////////////////////////
-   std::size_t getBCVectorSize() const;
-   //////////////////////////////////////////////////////////////////////////
-   std::string toString() const;
-   //////////////////////////////////////////////////////////////////////////
-   std::vector< int >& getBcindexmatrixDataVector();
-   //////////////////////////////////////////////////////////////////////////
-
-
-   static const int SOLID;     
-   static const int FLUID;     
-   static const int INTERFACECF; 
-   static const int INTERFACEFC; 
-   static const int UNDEFINED; 
-
-private:
-   //////////////////////////////////////////////////////////////////////////
-   void deleteBCAndSetType(std::size_t x1, std::size_t x2, std::size_t x3, int type);
-   //////////////////////////////////////////////////////////////////////////
-   void deleteBC(std::size_t x1, std::size_t x2, std::size_t x3);
-
-   friend class MPIIORestart1CoProcessor;
-   friend class MPIIORestart2CoProcessor;
-   friend class MPIIORestart11CoProcessor;
-   friend class MPIIORestart21CoProcessor;
-
-   friend class boost::serialization::access;
-   template<class Archive>
-   void serialize(Archive & ar, const unsigned int version)
-   {
-      ar & bcindexmatrix;
-      ar & bcvector;
-      ar & indexContainer;
-   }
-protected:
-   //////////////////////////////////////////////////////////////////////////
-   //-1 solid // -2 fluid -...
-   CbArray3D<int, IndexerX3X2X1> bcindexmatrix;
-   std::vector<BoundaryConditionsPtr> bcvector;
-   std::vector<int> indexContainer;
-};
-
-
-//////////////////////////////////////////////////////////////////////////
-inline std::size_t BCArray3D::getNX1() const { return bcindexmatrix.getNX1(); }
-//////////////////////////////////////////////////////////////////////////
-inline std::size_t BCArray3D::getNX2() const { return bcindexmatrix.getNX2(); }
-//////////////////////////////////////////////////////////////////////////
-inline std::size_t BCArray3D::getNX3() const { return bcindexmatrix.getNX3(); }
-//////////////////////////////////////////////////////////////////////////
-inline bool BCArray3D::hasBC(std::size_t x1, std::size_t x2, std::size_t x3)  const
-{
-   return bcindexmatrix(x1, x2, x3) >= 0;
-}
-//////////////////////////////////////////////////////////////////////////
-inline int BCArray3D::getBCVectorIndex(std::size_t x1, std::size_t x2, std::size_t x3) const
-{
-   return bcindexmatrix(x1, x2, x3);
-}
-//////////////////////////////////////////////////////////////////////////
-inline const BoundaryConditionsPtr  BCArray3D::getBC(std::size_t x1, std::size_t x2, std::size_t x3) const
-{
-   int index = bcindexmatrix(x1, x2, x3);
-   if (index < 0) return BoundaryConditionsPtr(); //=> NULL Pointer
-
-   return bcvector[index];
-}
-//////////////////////////////////////////////////////////////////////////
-inline BoundaryConditionsPtr BCArray3D::getBC(std::size_t x1, std::size_t x2, std::size_t x3)
-{
-   int index = bcindexmatrix(x1, x2, x3);
-   if (index < 0) return BoundaryConditionsPtr(); //=> NULL Pointer
-
-   return bcvector[index];
-}
-//////////////////////////////////////////////////////////////////////////
-inline bool BCArray3D::isSolid(std::size_t x1, std::size_t x2, std::size_t x3) const
-{
-   return bcindexmatrix(x1, x2, x3) == SOLID;
-}
-//////////////////////////////////////////////////////////////////////////
-//true : FLUID or BC
-//false: UNDEFINED or SOLID
-inline bool BCArray3D::isFluid(std::size_t x1, std::size_t x2, std::size_t x3) const
-{
-   int tmp = bcindexmatrix(x1, x2, x3);
-   return (tmp == FLUID || tmp >= 0);
-}
-//////////////////////////////////////////////////////////////////////////
-inline bool BCArray3D::isFluidWithoutBC(std::size_t x1, std::size_t x2, std::size_t x3) const
-{
-   return bcindexmatrix(x1, x2, x3) == FLUID;
-}
-//////////////////////////////////////////////////////////////////////////
-inline bool BCArray3D::isUndefined(std::size_t x1, std::size_t x2, std::size_t x3) const
-{
-   return bcindexmatrix(x1, x2, x3) == UNDEFINED;
-}
-//////////////////////////////////////////////////////////////////////////
-inline bool BCArray3D::isInterfaceCF(std::size_t x1, std::size_t x2, std::size_t x3) const
-{
-   return bcindexmatrix(x1, x2, x3) == INTERFACECF;
-}
-//////////////////////////////////////////////////////////////////////////
-inline bool BCArray3D::isInterfaceFC(std::size_t x1, std::size_t x2, std::size_t x3) const
-{
-   return bcindexmatrix(x1, x2, x3) == INTERFACEFC;
-}
-
-#endif 
+#ifndef BCArray_H
+#define BCArray_H
+
+#include "BoundaryConditions.h"
+#include "basics/container/CbArray3D.h"
+
+#include <typeinfo>
+
+#include <boost/serialization/serialization.hpp>
+#include <memory>
+
+class BCArray3D;
+typedef std::shared_ptr<BCArray3D> BCArray3DPtr;
+
+class BCArray3D
+{
+public:
+   //////////////////////////////////////////////////////////////////////////
+   BCArray3D();
+   //////////////////////////////////////////////////////////////////////////
+   BCArray3D(std::size_t nx1, std::size_t nx2, std::size_t nx3);
+   //////////////////////////////////////////////////////////////////////////
+   BCArray3D(std::size_t nx1, std::size_t nx2, std::size_t nx3, int val);
+   //////////////////////////////////////////////////////////////////////////
+   virtual ~BCArray3D();
+   //////////////////////////////////////////////////////////////////////////
+   inline std::size_t getNX1() const;
+   //////////////////////////////////////////////////////////////////////////
+   inline std::size_t getNX2() const;
+   //////////////////////////////////////////////////////////////////////////
+   inline std::size_t getNX3() const;
+   //////////////////////////////////////////////////////////////////////////
+   void resize(std::size_t nx1, std::size_t nx2, std::size_t nx3);
+   //////////////////////////////////////////////////////////////////////////
+   void resize(std::size_t nx1, std::size_t nx2, std::size_t nx3, int val);
+   //////////////////////////////////////////////////////////////////////////
+   bool validIndices(std::size_t x1, std::size_t x2, std::size_t x3)  const;
+   //////////////////////////////////////////////////////////////////////////
+   inline bool hasBC(std::size_t x1, std::size_t x2, std::size_t x3)  const;
+   //////////////////////////////////////////////////////////////////////////
+   void setBC(std::size_t x1, std::size_t x2, std::size_t x3, BoundaryConditionsPtr const& bc);
+   //////////////////////////////////////////////////////////////////////////
+   inline int getBCVectorIndex(std::size_t x1, std::size_t x2, std::size_t x3) const;
+   //////////////////////////////////////////////////////////////////////////
+   inline const BoundaryConditionsPtr getBC(std::size_t x1, std::size_t x2, std::size_t x3) const;
+   //////////////////////////////////////////////////////////////////////////
+   inline BoundaryConditionsPtr getBC(std::size_t x1, std::size_t x2, std::size_t x3);
+   //////////////////////////////////////////////////////////////////////////
+   void setSolid(std::size_t x1, std::size_t x2, std::size_t x3);
+   //////////////////////////////////////////////////////////////////////////
+   inline bool isSolid(std::size_t x1, std::size_t x2, std::size_t x3) const;
+   //////////////////////////////////////////////////////////////////////////
+   void setFluid(std::size_t x1, std::size_t x2, std::size_t x3);
+   //////////////////////////////////////////////////////////////////////////
+   //true : FLUID or BC
+   //false: UNDEFINED or SOLID
+   inline bool isFluid(std::size_t x1, std::size_t x2, std::size_t x3) const;
+   //////////////////////////////////////////////////////////////////////////
+   inline bool isFluidWithoutBC(std::size_t x1, std::size_t x2, std::size_t x3) const;
+   //////////////////////////////////////////////////////////////////////////
+   inline bool isUndefined(std::size_t x1, std::size_t x2, std::size_t x3) const;
+   //////////////////////////////////////////////////////////////////////////
+   void setUndefined(std::size_t x1, std::size_t x2, std::size_t x3);
+   //////////////////////////////////////////////////////////////////////////
+   inline bool isInterfaceCF(std::size_t x1, std::size_t x2, std::size_t x3) const;
+   //////////////////////////////////////////////////////////////////////////
+   void setInterfaceCF(std::size_t x1, std::size_t x2, std::size_t x3);
+   //////////////////////////////////////////////////////////////////////////
+   inline bool isInterfaceFC(std::size_t x1, std::size_t x2, std::size_t x3) const;
+   //////////////////////////////////////////////////////////////////////////
+   void setInterfaceFC(std::size_t x1, std::size_t x2, std::size_t x3);
+   //////////////////////////////////////////////////////////////////////////
+   std::size_t getNumberOfSolidEntries() const;
+   //////////////////////////////////////////////////////////////////////////
+   std::size_t getNumberOfFluidEntries() const;
+   //////////////////////////////////////////////////////////////////////////
+   std::size_t getNumberOfFluidWithoutBCEntries() const;
+   //////////////////////////////////////////////////////////////////////////
+   std::size_t getNumberOfBCEntries() const;
+   //////////////////////////////////////////////////////////////////////////
+   std::size_t getNumberOfUndefinedEntries() const;
+   //////////////////////////////////////////////////////////////////////////
+   std::size_t getBCVectorSize() const;
+   //////////////////////////////////////////////////////////////////////////
+   std::string toString() const;
+   //////////////////////////////////////////////////////////////////////////
+   std::vector< int >& getBcindexmatrixDataVector();
+   //////////////////////////////////////////////////////////////////////////
+   bool isInsideOfDomain(const int &x1, const int &x2, const int &x3, const int& ghostLayerWidth) const;
+
+   static const int SOLID;     
+   static const int FLUID;     
+   static const int INTERFACECF; 
+   static const int INTERFACEFC; 
+   static const int UNDEFINED; 
+
+private:
+   //////////////////////////////////////////////////////////////////////////
+   void deleteBCAndSetType(std::size_t x1, std::size_t x2, std::size_t x3, int type);
+   //////////////////////////////////////////////////////////////////////////
+   void deleteBC(std::size_t x1, std::size_t x2, std::size_t x3);
+
+   friend class MPIIORestart1CoProcessor;
+   friend class MPIIORestart2CoProcessor;
+   friend class MPIIORestart11CoProcessor;
+   friend class MPIIORestart21CoProcessor;
+
+   friend class boost::serialization::access;
+   template<class Archive>
+   void serialize(Archive & ar, const unsigned int version)
+   {
+      ar & bcindexmatrix;
+      ar & bcvector;
+      ar & indexContainer;
+   }
+protected:
+   //////////////////////////////////////////////////////////////////////////
+   //-1 solid // -2 fluid -...
+   CbArray3D<int, IndexerX3X2X1> bcindexmatrix;
+   std::vector<BoundaryConditionsPtr> bcvector;
+   std::vector<int> indexContainer;
+};
+
+
+//////////////////////////////////////////////////////////////////////////
+inline std::size_t BCArray3D::getNX1() const { return bcindexmatrix.getNX1(); }
+//////////////////////////////////////////////////////////////////////////
+inline std::size_t BCArray3D::getNX2() const { return bcindexmatrix.getNX2(); }
+//////////////////////////////////////////////////////////////////////////
+inline std::size_t BCArray3D::getNX3() const { return bcindexmatrix.getNX3(); }
+//////////////////////////////////////////////////////////////////////////
+inline bool BCArray3D::hasBC(std::size_t x1, std::size_t x2, std::size_t x3)  const
+{
+   return bcindexmatrix(x1, x2, x3) >= 0;
+}
+//////////////////////////////////////////////////////////////////////////
+inline int BCArray3D::getBCVectorIndex(std::size_t x1, std::size_t x2, std::size_t x3) const
+{
+   return bcindexmatrix(x1, x2, x3);
+}
+//////////////////////////////////////////////////////////////////////////
+inline const BoundaryConditionsPtr  BCArray3D::getBC(std::size_t x1, std::size_t x2, std::size_t x3) const
+{
+   int index = bcindexmatrix(x1, x2, x3);
+   if (index < 0) return BoundaryConditionsPtr(); //=> NULL Pointer
+
+   return bcvector[index];
+}
+//////////////////////////////////////////////////////////////////////////
+inline BoundaryConditionsPtr BCArray3D::getBC(std::size_t x1, std::size_t x2, std::size_t x3)
+{
+   int index = bcindexmatrix(x1, x2, x3);
+   if (index < 0) return BoundaryConditionsPtr(); //=> NULL Pointer
+
+   return bcvector[index];
+}
+//////////////////////////////////////////////////////////////////////////
+inline bool BCArray3D::isSolid(std::size_t x1, std::size_t x2, std::size_t x3) const
+{
+   return bcindexmatrix(x1, x2, x3) == SOLID;
+}
+//////////////////////////////////////////////////////////////////////////
+//true : FLUID or BC
+//false: UNDEFINED or SOLID
+inline bool BCArray3D::isFluid(std::size_t x1, std::size_t x2, std::size_t x3) const
+{
+   int tmp = bcindexmatrix(x1, x2, x3);
+   return (tmp == FLUID || tmp >= 0);
+}
+//////////////////////////////////////////////////////////////////////////
+inline bool BCArray3D::isFluidWithoutBC(std::size_t x1, std::size_t x2, std::size_t x3) const
+{
+   return bcindexmatrix(x1, x2, x3) == FLUID;
+}
+//////////////////////////////////////////////////////////////////////////
+inline bool BCArray3D::isUndefined(std::size_t x1, std::size_t x2, std::size_t x3) const
+{
+   return bcindexmatrix(x1, x2, x3) == UNDEFINED;
+}
+//////////////////////////////////////////////////////////////////////////
+inline bool BCArray3D::isInterfaceCF(std::size_t x1, std::size_t x2, std::size_t x3) const
+{
+   return bcindexmatrix(x1, x2, x3) == INTERFACECF;
+}
+//////////////////////////////////////////////////////////////////////////
+inline bool BCArray3D::isInterfaceFC(std::size_t x1, std::size_t x2, std::size_t x3) const
+{
+   return bcindexmatrix(x1, x2, x3) == INTERFACEFC;
+}
+//////////////////////////////////////////////////////////////////////////
+inline bool BCArray3D::isInsideOfDomain(const int& x1, const int& x2, const int& x3, const int& ghostLayerWidth) const
+{
+    const int minX1 = ghostLayerWidth;
+    const int maxX1 = (int)this->getNX1() - 1 - ghostLayerWidth;
+    const int minX2 = ghostLayerWidth;
+    const int maxX2 = (int)this->getNX2() - 1 - ghostLayerWidth;
+    const int minX3 = ghostLayerWidth;
+    const int maxX3 = (int)this->getNX3() - 1 - ghostLayerWidth;
+
+    return (!(x1 < minX1 || x1 > maxX1 || x2 < minX2 || x2 > maxX2 || x3 < minX3 || x3 > maxX3));
+}
+
+#endif 
diff --git a/source/VirtualFluidsCore/BoundaryConditions/BCProcessor.cpp b/source/VirtualFluidsCore/BoundaryConditions/BCProcessor.cpp
index b93647dd2..464b4e502 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/BCProcessor.cpp
+++ b/source/VirtualFluidsCore/BoundaryConditions/BCProcessor.cpp
@@ -1,69 +1,69 @@
-#include "BCProcessor.h"
-#include "D3Q27EsoTwist3DSplittedVector.h"
-
-BCProcessor::BCProcessor()
-{
-   
-}
-//////////////////////////////////////////////////////////////////////////
-BCProcessor::BCProcessor(LBMKernelPtr kernel)
-{
-   DistributionArray3DPtr distributions = boost::dynamic_pointer_cast<EsoTwist3D>(kernel->getDataSet()->getFdistributions());
-   bcArray = BCArray3DPtr(new BCArray3D( distributions->getNX1(), distributions->getNX2(), distributions->getNX3(), BCArray3D::FLUID));
-}
-//////////////////////////////////////////////////////////////////////////
-BCProcessor::~BCProcessor()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-BCProcessorPtr BCProcessor::clone(LBMKernelPtr kernel)
-{
-   BCProcessorPtr bcProcessor(new BCProcessor(kernel));
-   return bcProcessor;
-}
-//////////////////////////////////////////////////////////////////////////
-BCArray3DPtr BCProcessor::getBCArray()
-{ 
-   return bcArray; 
-}
-//////////////////////////////////////////////////////////////////////////
-void BCProcessor::setBCArray(BCArray3DPtr bcarray)
-{
-   bcArray = bcarray;
-}
-//////////////////////////////////////////////////////////////////////////
-void BCProcessor::addBC(BCAlgorithmPtr bc)
-{
-   if (bc->isPreCollision())
-   {
-      preBC.push_back(bc);
-   }
-   else
-   {
-      postBC.push_back(bc);
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void BCProcessor::applyPreCollisionBC()
-{
-   BOOST_FOREACH(BCAlgorithmPtr bc, preBC)
-   {
-      bc->applyBC();
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void BCProcessor::applyPostCollisionBC()
-{
-   BOOST_FOREACH(BCAlgorithmPtr bc, postBC)
-   {
-      bc->applyBC();
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void BCProcessor::clearBC()
-{
-   preBC.clear();
-   postBC.clear();
-}
-
+#include "BCProcessor.h"
+#include "D3Q27EsoTwist3DSplittedVector.h"
+#include "DataSet3D.h"
+#include "ILBMKernel.h"
+#include "BCArray3D.h"
+#include "BCAlgorithm.h"
+
+BCProcessor::BCProcessor()
+{
+   
+}
+//////////////////////////////////////////////////////////////////////////
+BCProcessor::BCProcessor(ILBMKernelPtr kernel)
+{
+   DistributionArray3DPtr distributions = std::dynamic_pointer_cast<EsoTwist3D>(kernel->getDataSet()->getFdistributions());
+   bcArray = BCArray3DPtr(new BCArray3D( distributions->getNX1(), distributions->getNX2(), distributions->getNX3(), BCArray3D::FLUID));
+}
+//////////////////////////////////////////////////////////////////////////
+BCProcessor::~BCProcessor()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+BCProcessorPtr BCProcessor::clone(ILBMKernelPtr kernel)
+{
+   BCProcessorPtr bcProcessor(new BCProcessor(kernel));
+   return bcProcessor;
+}
+//////////////////////////////////////////////////////////////////////////
+BCArray3DPtr BCProcessor::getBCArray()
+{ 
+   return bcArray; 
+}
+//////////////////////////////////////////////////////////////////////////
+void BCProcessor::setBCArray(BCArray3DPtr bcarray)
+{
+   bcArray = bcarray;
+}
+//////////////////////////////////////////////////////////////////////////
+void BCProcessor::addBC(BCAlgorithmPtr bc)
+{
+   if (bc->isPreCollision())
+   {
+      preBC.push_back(bc);
+   }
+   else
+   {
+      postBC.push_back(bc);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void BCProcessor::applyPreCollisionBC()
+{
+   for(BCAlgorithmPtr bc : preBC)
+      bc->applyBC();
+}
+//////////////////////////////////////////////////////////////////////////
+void BCProcessor::applyPostCollisionBC()
+{
+    for (BCAlgorithmPtr bc : postBC)
+        bc->applyBC();
+}
+//////////////////////////////////////////////////////////////////////////
+void BCProcessor::clearBC()
+{
+   preBC.clear();
+   postBC.clear();
+}
+
diff --git a/source/VirtualFluidsCore/BoundaryConditions/BCProcessor.h b/source/VirtualFluidsCore/BoundaryConditions/BCProcessor.h
index b36097a98..e2c32b461 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/BCProcessor.h
+++ b/source/VirtualFluidsCore/BoundaryConditions/BCProcessor.h
@@ -1,39 +1,36 @@
-#ifndef BCPROCESSSOR_H
-#define BCPROCESSSOR_H
-
-#include "BCAlgorithm.h"
-#include "EsoTwist3D.h"
-#include "BCArray3D.h"
-#include "basics/container/CbArray4D.h"
-#include "basics/container/CbArray3D.h"
+#ifndef BC_PROCESSSOR_H
+#define BC_PROCESSSOR_H
 
+#include <memory>
 #include <vector>
 
 #include <boost/serialization/base_object.hpp>
 
 class BCProcessor;
-typedef boost::shared_ptr<BCProcessor> BCProcessorPtr;
+typedef std::shared_ptr<BCProcessor> BCProcessorPtr;
 
-#include "LBMKernel.h"
+class BCArray3D;
+class BCAlgorithm;
+class ILBMKernel;
 
 class BCProcessor
 {
 public:
    BCProcessor();
-   BCProcessor(LBMKernelPtr kernel);
+   BCProcessor(std::shared_ptr<ILBMKernel> kernel);
    virtual ~BCProcessor();
-   virtual BCArray3DPtr getBCArray();
-   virtual void setBCArray(BCArray3DPtr bcarray);
-   virtual BCProcessorPtr clone(LBMKernelPtr kernel);
+   virtual std::shared_ptr<BCArray3D> getBCArray();
+   virtual void setBCArray(std::shared_ptr<BCArray3D> bcarray);
+   virtual BCProcessorPtr clone(std::shared_ptr<ILBMKernel> kernel);
 
-   void addBC(BCAlgorithmPtr bc);
+   void addBC(std::shared_ptr<BCAlgorithm> bc);
    void applyPreCollisionBC();
    void applyPostCollisionBC();
    void clearBC();
 protected:
-   std::vector<BCAlgorithmPtr> preBC;
-   std::vector<BCAlgorithmPtr> postBC;
-   BCArray3DPtr bcArray;
+   std::vector<std::shared_ptr<BCAlgorithm> > preBC;
+   std::vector<std::shared_ptr<BCAlgorithm> > postBC;
+   std::shared_ptr<BCArray3D> bcArray;
 
 private:
    friend class boost::serialization::access;
diff --git a/source/VirtualFluidsCore/BoundaryConditions/BoundaryConditions.h b/source/VirtualFluidsCore/BoundaryConditions/BoundaryConditions.h
index e4da79f0c..f9390f787 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/BoundaryConditions.h
+++ b/source/VirtualFluidsCore/BoundaryConditions/BoundaryConditions.h
@@ -1,297 +1,306 @@
-//  _    ___      __              __________      _     __
-// | |  / (_)____/ /___  ______ _/ / ____/ /_  __(_)___/ /____
-// | | / / / ___/ __/ / / / __ `/ / /_  / / / / / / __  / ___/
-// | |/ / / /  / /_/ /_/ / /_/ / / __/ / / /_/ / / /_/ (__  )
-// |___/_/_/   \__/\__,_/\__,_/_/_/   /_/\__,_/_/\__,_/____/
-//
-#ifndef BoundaryConditions_H
-#define BoundaryConditions_H
-
-#include <vector>
-#include <string>
-
-#include <basics/utilities/UbException.h>                  
-#include <basics/utilities/UbSystem.h>
-#include <basics/utilities/UbTuple.h>
-#include "D3Q27System.h"
-
-#include <boost/serialization/serialization.hpp>
-
-class BoundaryConditions;
-typedef boost::shared_ptr<BoundaryConditions> BoundaryConditionsPtr;
-
-class BoundaryConditions 
-{
-//public:
-//   enum BcAlgorithm{VelocityBC, SlipBC, NoSlipBC, ThinWallNoSlipBC, HighViscosityNoSlipBC, EqDensityBC, NonEqDensityBC, NonReflectingVelocityBC, NonReflectingDensityBC};
-public:
-   BoundaryConditions() 
-      : noslipBoundaryFlags(0)		
-      , slipBoundaryFlags(0)		
-      , velocityBoundaryFlags(0)		
-      , densityBoundaryFlags(0)		
-      , wallModelBoundaryFlags(0)
-      , bcVelocityX1(0.0f)
-      , bcVelocityX2(0.0f)
-      , bcVelocityX3(0.0f)
-      , bcDensity(0.0f)
-      , bcLodiDensity(0.0f)
-      , bcLodiVelocityX1(0.0f)
-      , bcLodiVelocityX2(0.0f)
-      , bcLodiVelocityX3(0.0f)
-      , bcLodiLentgh(0.0f)
-      , nx1(0.0f)
-      , nx2(0.0f)
-      , nx3(0.0f)
-      , algorithmType(-1)
-   {
-      //wenn folgendes nicht geht, dann hat man weiter unten bei der bit-geschichte ein ernstes problem!!!
-      UB_STATIC_ASSERT( sizeof(long long) >= 8);
-      //UB_STATIC_ASSERT( sizeof(double) >= 16);
-      //UB_STATIC_ASSERT( sizeof(long long) == 32);
-      UB_STATIC_ASSERT( (sizeof(long long)*8) >= (D3Q27System::FENDDIR+1)*BoundaryConditions::optionDigits );
-
-      for(int fdir=D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++) 
-         q[fdir] = -999.; 
-   }
-   virtual ~BoundaryConditions() {}
-
-   virtual bool isEmpty() { return (noslipBoundaryFlags&slipBoundaryFlags&velocityBoundaryFlags&densityBoundaryFlags)==0;}
-   virtual bool hasBoundaryCondition()
-   {
-      return (  hasNoSlipBoundary() || hasSlipBoundary() 
-             || hasDensityBoundary() || hasVelocityBoundary() || hasWallModelBoundary() );
-   }
-
-   virtual bool hasBoundaryConditionFlag(const int& direction)
-   {
-      assert( direction >= D3Q27System::FSTARTDIR && direction <= D3Q27System::FENDDIR );
-
-      return (   hasNoSlipBoundaryFlag(direction) || hasSlipBoundaryFlag(direction) 
-              || hasDensityBoundaryFlag(direction) || hasVelocityBoundaryFlag(direction)  || hasWallModelBoundaryFlag(direction));
-   }
-protected:
-   void setFlagBits(long long& flag, const int& direction, const short& secOpt)
-   {
-      if( (secOpt+1)>maxOptionVal ) 
-         throw UbException(UB_EXARGS,"error: option > "+UbSystem::toString(maxOptionVal-1));
-      
-      //alle digits an den betreffenden postionen auf "0"
-      flag &= ~( maxOptionVal<<(direction*optionDigits) );
-      //alle digitsan den betreffenden postionen entsprechend der marke setzen
-      flag |= ((long long)(secOpt+1)<<(direction*optionDigits));
-   }
-public:
-   /*===================== NoSlip Boundary ==================================================*/	
-   void       setNoSlipBoundaryFlag(const int& direction, const short& secOpt=0)    { this->setFlagBits(noslipBoundaryFlags,direction,secOpt);                                     }  
-   void       unsetNoSlipBoundaryFlag(const int& direction)                         { this->noslipBoundaryFlags &= ~( maxOptionVal<<(direction*optionDigits) );                    }
-   void       unsetNoSlipBoundary()                                                 { this->noslipBoundaryFlags = 0;                                                               }
-   long long  getNoSlipBoundary()	                                                { return this->noslipBoundaryFlags;                                                            }
-   bool       hasNoSlipBoundary()					                                    { return (noslipBoundaryFlags!=0);                                                             }
-   bool       hasNoSlipBoundaryFlag(const int& direction)                           { return ( ( ( noslipBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) != 0);         }
-   short      getNoSlipSecondaryOption(const int& direction)                        { return (short)( (  ( noslipBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) - 1 ); }
-   /*===================== WallModel Boundary ==================================================*/	
-   void       setWallModelBoundaryFlag(const int& direction, const short& secOpt=0) { this->setFlagBits(wallModelBoundaryFlags,direction,secOpt);                                     }  
-   void       unsetWallModelBoundaryFlag(const int& direction)                      { this->wallModelBoundaryFlags &= ~( maxOptionVal<<(direction*optionDigits) );                    }
-   void       unsetWallModelBoundary()                                              { this->wallModelBoundaryFlags = 0;                                                               }
-   long long  getWallModelBoundary()	                                             { return this->wallModelBoundaryFlags;                                                            }
-   bool       hasWallModelBoundary()					                                 { return (wallModelBoundaryFlags!=0);                                                             }
-   bool       hasWallModelBoundaryFlag(const int& direction)                        { return ( ( ( wallModelBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) != 0);         }
-   short      getWallModelSecondaryOption(const int& direction)                     { return (short)( (  ( wallModelBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) - 1 ); }
-   /*===================== Slip-Solid Boundary ==================================================*/	
-   void       setSlipBoundaryFlag(const int& direction, const short& secOpt=0)      { this->setFlagBits(slipBoundaryFlags,direction,secOpt);                                     }  
-   void       unsetSlipBoundaryFlag(const int& direction)                           { this->slipBoundaryFlags &= ~( maxOptionVal<<(direction*optionDigits) );                    }
-   void       unsetSlipBoundary()                                                   { this->slipBoundaryFlags = 0;                                                               }
-   long long  getSlipBoundary()	                                                   { return this->slipBoundaryFlags;                                                            }
-   bool       hasSlipBoundary()					                                       { return (slipBoundaryFlags!=0);                                                             }
-   bool       hasSlipBoundaryFlag(const int& direction)	                           { return ( ( ( slipBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) != 0);         }
-   short      getSlipSecondaryOption(const int& direction)                          { return (short)( (  ( slipBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) - 1 ); }
-   void       setNormalVector(const float& nx1,const float& nx2,const float& nx3)   { this->nx1 = nx1; this->nx2 = nx2;  this->nx3 = nx3;}
-   UbTupleFloat3 getNormalVector()                                                  { return makeUbTuple(nx1,nx2,nx3); }
-
-   /*============== Velocity Boundary ========================*/
-   void       setVelocityBoundaryFlag(const int& direction, const short& secOpt=0)  { this->setFlagBits(velocityBoundaryFlags,direction,secOpt);                                     }  
-   void       unsetVelocityBoundaryFlag(const int& direction)                       { this->velocityBoundaryFlags &= ~( maxOptionVal<<(direction*optionDigits) );                    }
-   void       unsetVelocityBoundary()                 		                        { this->velocityBoundaryFlags = 0;                                                               }
-   long long  getVelocityBoundary()	               		                           { return this->velocityBoundaryFlags;                                                            }
-   bool       hasVelocityBoundary()   					 		                           { return this->velocityBoundaryFlags!=0;                                                         }
-   bool       hasVelocityBoundaryFlag(const int& direction)                         { return ( ( ( velocityBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) != 0);         }
-   short      getVelocitySecondaryOption(const int& direction)                      { return (short)( (  ( velocityBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) - 1 ); }
-
-   void  setBoundaryVelocityX1(const float& vx1) { this->bcVelocityX1 = vx1;  } 
-   void  setBoundaryVelocityX2(const float& vx2) { this->bcVelocityX2 = vx2;  } 
-   void  setBoundaryVelocityX3(const float& vx3) { this->bcVelocityX3 = vx3;  } 
-   float getBoundaryVelocityX1()                 { return this->bcVelocityX1; }
-   float getBoundaryVelocityX2()                 { return this->bcVelocityX2; }
-   float getBoundaryVelocityX3()                 { return this->bcVelocityX3; }
-   float getBoundaryVelocity(const int& direction) 
-   {                   
-      switch(direction)
-      {
-      case D3Q27System::E : return (float)( UbMath::c4o9*(+bcVelocityX1) );      //(2/cs^2)(=6)*rho_0(=1 bei inkompr)*wi*u*ei mit cs=1/sqrt(3)
-      case D3Q27System::W : return (float)( UbMath::c4o9*(-bcVelocityX1) );      //z.B. aus paper manfred MRT LB models in three dimensions (2002)   
-      case D3Q27System::N : return (float)( UbMath::c4o9*(+bcVelocityX2) );   
-      case D3Q27System::S : return (float)( UbMath::c4o9*(-bcVelocityX2) );
-      case D3Q27System::T : return (float)( UbMath::c4o9*(+bcVelocityX3) );
-      case D3Q27System::B : return (float)( UbMath::c4o9*(-bcVelocityX3) );
-      case D3Q27System::NE: return (float)( UbMath::c1o9*(+bcVelocityX1+bcVelocityX2             ) );
-      case D3Q27System::SW: return (float)( UbMath::c1o9*(-bcVelocityX1-bcVelocityX2             ) );
-      case D3Q27System::SE: return (float)( UbMath::c1o9*(+bcVelocityX1-bcVelocityX2             ) );
-      case D3Q27System::NW: return (float)( UbMath::c1o9*(-bcVelocityX1+bcVelocityX2             ) );
-      case D3Q27System::TE: return (float)( UbMath::c1o9*(+bcVelocityX1             +bcVelocityX3) );
-      case D3Q27System::BW: return (float)( UbMath::c1o9*(-bcVelocityX1             -bcVelocityX3) );
-      case D3Q27System::BE: return (float)( UbMath::c1o9*(+bcVelocityX1             -bcVelocityX3) );
-      case D3Q27System::TW: return (float)( UbMath::c1o9*(-bcVelocityX1             +bcVelocityX3) );
-      case D3Q27System::TN: return (float)( UbMath::c1o9*(             +bcVelocityX2+bcVelocityX3) );
-      case D3Q27System::BS: return (float)( UbMath::c1o9*(             -bcVelocityX2-bcVelocityX3) );
-      case D3Q27System::BN: return (float)( UbMath::c1o9*(             +bcVelocityX2-bcVelocityX3) );
-      case D3Q27System::TS: return (float)( UbMath::c1o9*(             -bcVelocityX2+bcVelocityX3) );
-      case D3Q27System::TNE: return (float)( UbMath::c1o36*(+bcVelocityX1+bcVelocityX2+bcVelocityX3) );
-      case D3Q27System::BSW: return (float)( UbMath::c1o36*(-bcVelocityX1-bcVelocityX2-bcVelocityX3) );
-      case D3Q27System::BNE: return (float)( UbMath::c1o36*(+bcVelocityX1+bcVelocityX2-bcVelocityX3) );
-      case D3Q27System::TSW: return (float)( UbMath::c1o36*(-bcVelocityX1-bcVelocityX2+bcVelocityX3) );
-      case D3Q27System::TSE: return (float)( UbMath::c1o36*(+bcVelocityX1-bcVelocityX2+bcVelocityX3) );
-      case D3Q27System::BNW: return (float)( UbMath::c1o36*(-bcVelocityX1+bcVelocityX2-bcVelocityX3) );
-      case D3Q27System::BSE: return (float)( UbMath::c1o36*(+bcVelocityX1-bcVelocityX2-bcVelocityX3) );
-      case D3Q27System::TNW: return (float)( UbMath::c1o36*(-bcVelocityX1+bcVelocityX2+bcVelocityX3) ); 
-      default: throw UbException(UB_EXARGS,"unknown error");
-      }
-   }
-
-   /*============== Density Boundary ========================*/
-   void       setDensityBoundaryFlag(const int& direction, const short& secOpt=0) { this->setFlagBits(densityBoundaryFlags,direction,secOpt);                                     }  
-   void       unsetDensityBoundaryFlag(const int& direction)                      { this->densityBoundaryFlags &= ~( maxOptionVal<<(direction*optionDigits) );                    }
-   void       unsetDensityBoundary()                                              { this->densityBoundaryFlags = 0;                                                               }
-   long long  getDensityBoundary()	                                              { return this->densityBoundaryFlags;                                                            }
-   bool       hasDensityBoundary()					                                  { return (this->densityBoundaryFlags!=0);                                                       }
-   bool       hasDensityBoundaryFlag(const int& direction)	                      { return ( ( ( densityBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) != 0);         }
-   short      getDensitySecondaryOption(const int& direction)                     { return (short)( (  ( densityBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) - 1 ); }
-
-   void  setBoundaryDensity(float density) { this->bcDensity = density; } 
-   float getBoundaryDensity()              { return this->bcDensity;    }
-
-   //Lodi extension
-   void  setDensityLodiDensity(const float& bcLodiDensity)       { this->bcLodiDensity    = bcLodiDensity;    } 
-   void  setDensityLodiVelocityX1(const float& bcLodiVelocityX1) { this->bcLodiVelocityX1 = bcLodiVelocityX1; } 
-   void  setDensityLodiVelocityX2(const float& bcLodiVelocityX2) { this->bcLodiVelocityX2 = bcLodiVelocityX2; } 
-   void  setDensityLodiVelocityX3(const float& bcLodiVelocityX3) { this->bcLodiVelocityX3 = bcLodiVelocityX3; } 
-   void  setDensityLodiLength(const float& bcLodiLentgh)         { this->bcLodiLentgh     = bcLodiLentgh;     } 
-   float getDensityLodiDensity() const                           { return this->bcLodiDensity;    } 
-   float getDensityLodiVelocityX1() const                        { return this->bcLodiVelocityX1; }
-   float getDensityLodiVelocityX2() const                        { return this->bcLodiVelocityX2; }
-   float getDensityLodiVelocityX3() const                        { return this->bcLodiVelocityX3; }
-   float getDensityLodiLength() const                            { return this->bcLodiLentgh;     }
-
-   float& densityLodiDensity()                                   { return this->bcLodiDensity;    } 
-   float& densityLodiVelocityX1()                                { return this->bcLodiVelocityX1; }
-   float& densityLodiVelocityX2()                                { return this->bcLodiVelocityX2; }
-   float& densityLodiVelocityX3()                                { return this->bcLodiVelocityX3; }
-   float& densityLodiLentgh()                                    { return this->bcLodiLentgh;     }
-
-   const float& densityLodiDensity()  const                      { return this->bcLodiDensity;    } 
-   const float& densityLodiVelocityX1() const                    { return this->bcLodiVelocityX1; }
-   const float& densityLodiVelocityX2() const                    { return this->bcLodiVelocityX2; }
-   const float& densityLodiVelocityX3() const                    { return this->bcLodiVelocityX3; }
-   const float& densityLodiLentgh()  const                       { return this->bcLodiLentgh;     }
-
-
-   /*======================= Qs =============================*/
-   void  setQ(const float& val, const int& direction) { q[direction] = val; }
-   float getQ(const int& direction)                   { return q[direction]; }
-   
-   virtual std::vector< std::string > getBCNames()
-   {
-      std::vector< std::string > tmp;
-      tmp.push_back( "NoSlipBC"   );
-      tmp.push_back( "SlipBC"     );
-      tmp.push_back( "VelocityBC" );
-      tmp.push_back( "DensityBC"  );
-      return tmp;
-   }
-   virtual std::vector< long long > getBCFlags()
-   {
-      std::vector< long long > tmp;
-      tmp.push_back( noslipBoundaryFlags   );
-      tmp.push_back( slipBoundaryFlags     );
-      tmp.push_back( velocityBoundaryFlags );
-      tmp.push_back( densityBoundaryFlags  );
-      return tmp;
-   }
-
-   static bool hasFlagForDirection(const long long& flag, const int& direction)
-   {
-      return ( ( ( flag>>(optionDigits*direction) ) & maxOptionVal ) != 0);
-   }
-
-   void setBcAlgorithmType(char alg) { algorithmType = alg; }
-   char getBcAlgorithmType() { return algorithmType; }
-
-public:
-   static const int       optionDigits = 2;  //--> 3 bits für secondary Option --> maxOptionVal = 7, da man mit drei Digits max die 7 darstellen kann
-   static const long long maxOptionVal;// = ( 1<<optionDigits ) - 1; //2^3-1 -> 7
-
-protected:
-   float q[D3Q27System::FENDDIR+1];
-   //float q[D3Q27System::STARTF+1];
-
-   long long noslipBoundaryFlags;		
-   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;
-
-   char algorithmType;
-
-private:
-   friend class MPIIORestart1CoProcessor;
-   friend class MPIIORestart2CoProcessor;
-   friend class MPIIORestart11CoProcessor;
-   friend class MPIIORestart21CoProcessor;
-
-   friend class boost::serialization::access;
-   template<class Archive>
-   void serialize(Archive & ar, const unsigned int version)
-   {
-      ar & q; 
-
-      ar & noslipBoundaryFlags;		
-      ar & slipBoundaryFlags;		
-      ar & velocityBoundaryFlags;		
-      ar & densityBoundaryFlags;		
-
-      ar & bcVelocityX1;
-      ar & bcVelocityX2;
-      ar & bcVelocityX3;
-      ar & bcDensity;
-
-      ar & bcLodiDensity;
-      ar & bcLodiVelocityX1;
-      ar & bcLodiVelocityX2;
-      ar & bcLodiVelocityX3;
-      ar & bcLodiLentgh;
-
-      ar & wallModelBoundaryFlags;
-
-      ar & nx1;
-      ar & nx2;
-      ar & nx3;
-
-      ar & algorithmType;
-   }
-
-};
-
-#endif //D3Q27BOUNDARYCONDITION_H
+//  _    ___      __              __________      _     __
+// | |  / (_)____/ /___  ______ _/ / ____/ /_  __(_)___/ /____
+// | | / / / ___/ __/ / / / __ `/ / /_  / / / / / / __  / ___/
+// | |/ / / /  / /_/ /_/ / /_/ / / __/ / / /_/ / / /_/ (__  )
+// |___/_/_/   \__/\__,_/\__,_/_/_/   /_/\__,_/_/\__,_/____/
+//
+#ifndef BoundaryConditions_H
+#define BoundaryConditions_H
+
+#include <vector>
+#include <string>
+
+#include "basics/utilities/Vector3D.h"
+
+#include <basics/utilities/UbException.h>                  
+#include <basics/utilities/UbSystem.h>
+#include <basics/utilities/UbTuple.h>
+#include "D3Q27System.h"
+
+#include <boost/serialization/serialization.hpp>
+
+class BoundaryConditions;
+typedef std::shared_ptr<BoundaryConditions> BoundaryConditionsPtr;
+
+class BoundaryConditions 
+{
+//public:
+//   enum BcAlgorithm{VelocityBC, SlipBC, NoSlipBC, ThinWallNoSlipBC, HighViscosityNoSlipBC, EqDensityBC, NonEqDensityBC, NonReflectingVelocityBC, NonReflectingDensityBC};
+public:
+   BoundaryConditions() 
+      : noslipBoundaryFlags(0)		
+      , slipBoundaryFlags(0)		
+      , velocityBoundaryFlags(0)		
+      , densityBoundaryFlags(0)		
+      , wallModelBoundaryFlags(0)
+      , bcVelocityX1(0.0f)
+      , bcVelocityX2(0.0f)
+      , bcVelocityX3(0.0f)
+      , bcDensity(0.0f)
+      , bcLodiDensity(0.0f)
+      , bcLodiVelocityX1(0.0f)
+      , bcLodiVelocityX2(0.0f)
+      , bcLodiVelocityX3(0.0f)
+      , bcLodiLentgh(0.0f)
+      , nx1(0.0f)
+      , nx2(0.0f)
+      , nx3(0.0f)
+      , algorithmType(-1)
+   {
+      //wenn folgendes nicht geht, dann hat man weiter unten bei der bit-geschichte ein ernstes problem!!!
+      UB_STATIC_ASSERT( sizeof(long long) >= 8);
+      //UB_STATIC_ASSERT( sizeof(double) >= 16);
+      //UB_STATIC_ASSERT( sizeof(long long) == 32);
+      UB_STATIC_ASSERT( (sizeof(long long)*8) >= (D3Q27System::FENDDIR+1)*BoundaryConditions::optionDigits );
+
+      for(int fdir=D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++) 
+         q[fdir] = -999.; 
+   }
+   virtual ~BoundaryConditions() {}
+
+   virtual bool isEmpty() { return (noslipBoundaryFlags&slipBoundaryFlags&velocityBoundaryFlags&densityBoundaryFlags)==0;}
+   virtual bool hasBoundaryCondition()
+   {
+      return (  hasNoSlipBoundary() || hasSlipBoundary() 
+             || hasDensityBoundary() || hasVelocityBoundary() || hasWallModelBoundary() );
+   }
+
+   virtual bool hasBoundaryConditionFlag(const int& direction)
+   {
+      assert( direction >= D3Q27System::FSTARTDIR && direction <= D3Q27System::FENDDIR );
+
+      return (   hasNoSlipBoundaryFlag(direction) || hasSlipBoundaryFlag(direction) 
+              || hasDensityBoundaryFlag(direction) || hasVelocityBoundaryFlag(direction)  || hasWallModelBoundaryFlag(direction));
+   }
+protected:
+   void setFlagBits(long long& flag, const int& direction, const short& secOpt)
+   {
+      if( (secOpt+1)>maxOptionVal ) 
+         throw UbException(UB_EXARGS,"error: option > "+UbSystem::toString(maxOptionVal-1));
+      
+      //alle digits an den betreffenden postionen auf "0"
+      flag &= ~( maxOptionVal<<(direction*optionDigits) );
+      //alle digitsan den betreffenden postionen entsprechend der marke setzen
+      flag |= ((long long)(secOpt+1)<<(direction*optionDigits));
+   }
+public:
+   /*===================== NoSlip Boundary ==================================================*/	
+   void       setNoSlipBoundaryFlag(const int& direction, const short& secOpt=0)    { this->setFlagBits(noslipBoundaryFlags,direction,secOpt);                                     }  
+   void       unsetNoSlipBoundaryFlag(const int& direction)                         { this->noslipBoundaryFlags &= ~( maxOptionVal<<(direction*optionDigits) );                    }
+   void       unsetNoSlipBoundary()                                                 { this->noslipBoundaryFlags = 0;                                                               }
+   long long  getNoSlipBoundary()	                                                { return this->noslipBoundaryFlags;                                                            }
+   bool       hasNoSlipBoundary()					                                    { return (noslipBoundaryFlags!=0);                                                             }
+   bool       hasNoSlipBoundaryFlag(const int& direction)                           { return ( ( ( noslipBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) != 0);         }
+   short      getNoSlipSecondaryOption(const int& direction)                        { return (short)( (  ( noslipBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) - 1 ); }
+   /*===================== WallModel Boundary ==================================================*/	
+   void       setWallModelBoundaryFlag(const int& direction, const short& secOpt=0) { this->setFlagBits(wallModelBoundaryFlags,direction,secOpt);                                     }  
+   void       unsetWallModelBoundaryFlag(const int& direction)                      { this->wallModelBoundaryFlags &= ~( maxOptionVal<<(direction*optionDigits) );                    }
+   void       unsetWallModelBoundary()                                              { this->wallModelBoundaryFlags = 0;                                                               }
+   long long  getWallModelBoundary()	                                             { return this->wallModelBoundaryFlags;                                                            }
+   bool       hasWallModelBoundary()					                                 { return (wallModelBoundaryFlags!=0);                                                             }
+   bool       hasWallModelBoundaryFlag(const int& direction)                        { return ( ( ( wallModelBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) != 0);         }
+   short      getWallModelSecondaryOption(const int& direction)                     { return (short)( (  ( wallModelBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) - 1 ); }
+   /*===================== Slip-Solid Boundary ==================================================*/	
+   void       setSlipBoundaryFlag(const int& direction, const short& secOpt=0)      { this->setFlagBits(slipBoundaryFlags,direction,secOpt);                                     }  
+   void       unsetSlipBoundaryFlag(const int& direction)                           { this->slipBoundaryFlags &= ~( maxOptionVal<<(direction*optionDigits) );                    }
+   void       unsetSlipBoundary()                                                   { this->slipBoundaryFlags = 0;                                                               }
+   long long  getSlipBoundary()	                                                   { return this->slipBoundaryFlags;                                                            }
+   bool       hasSlipBoundary()					                                       { return (slipBoundaryFlags!=0);                                                             }
+   bool       hasSlipBoundaryFlag(const int& direction)	                           { return ( ( ( slipBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) != 0);         }
+   short      getSlipSecondaryOption(const int& direction)                          { return (short)( (  ( slipBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) - 1 ); }
+   void       setNormalVector(const float& nx1,const float& nx2,const float& nx3)   { this->nx1 = nx1; this->nx2 = nx2;  this->nx3 = nx3;}
+   UbTupleFloat3 getNormalVector()                                                  { return makeUbTuple(nx1,nx2,nx3); }
+
+   /*============== Velocity Boundary ========================*/
+   void       setVelocityBoundaryFlag(const int& direction, const short& secOpt=0)  { this->setFlagBits(velocityBoundaryFlags,direction,secOpt);                                     }  
+   void       unsetVelocityBoundaryFlag(const int& direction)                       { this->velocityBoundaryFlags &= ~( maxOptionVal<<(direction*optionDigits) );                    }
+   void       unsetVelocityBoundary()                 		                        { this->velocityBoundaryFlags = 0;                                                               }
+   long long  getVelocityBoundary()	               		                           { return this->velocityBoundaryFlags;                                                            }
+   bool       hasVelocityBoundary()   					 		                           { return this->velocityBoundaryFlags!=0;                                                         }
+   bool       hasVelocityBoundaryFlag(const int& direction)                         { return ( ( ( velocityBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) != 0);         }
+   short      getVelocitySecondaryOption(const int& direction)                      { return (short)( (  ( velocityBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) - 1 ); }
+
+   void setBoundaryVelocity(const Vector3D& vx) 
+    {
+       setBoundaryVelocityX1((float)vx[0]); 
+       setBoundaryVelocityX2((float)vx[1]);
+       setBoundaryVelocityX3((float)vx[2]);
+   }
+   void  setBoundaryVelocityX1(const float& vx1) { this->bcVelocityX1 = vx1;  } 
+   void  setBoundaryVelocityX2(const float& vx2) { this->bcVelocityX2 = vx2;  } 
+   void  setBoundaryVelocityX3(const float& vx3) { this->bcVelocityX3 = vx3;  } 
+   float getBoundaryVelocityX1()                 { return this->bcVelocityX1; }
+   float getBoundaryVelocityX2()                 { return this->bcVelocityX2; }
+   float getBoundaryVelocityX3()                 { return this->bcVelocityX3; }
+   float getBoundaryVelocity(const int& direction) 
+   {                   
+      switch(direction)
+      {
+      case D3Q27System::E : return (float)( UbMath::c4o9*(+bcVelocityX1) );      //(2/cs^2)(=6)*rho_0(=1 bei inkompr)*wi*u*ei mit cs=1/sqrt(3)
+      case D3Q27System::W : return (float)( UbMath::c4o9*(-bcVelocityX1) );      //z.B. aus paper manfred MRT LB models in three dimensions (2002)   
+      case D3Q27System::N : return (float)( UbMath::c4o9*(+bcVelocityX2) );   
+      case D3Q27System::S : return (float)( UbMath::c4o9*(-bcVelocityX2) );
+      case D3Q27System::T : return (float)( UbMath::c4o9*(+bcVelocityX3) );
+      case D3Q27System::B : return (float)( UbMath::c4o9*(-bcVelocityX3) );
+      case D3Q27System::NE: return (float)( UbMath::c1o9*(+bcVelocityX1+bcVelocityX2             ) );
+      case D3Q27System::SW: return (float)( UbMath::c1o9*(-bcVelocityX1-bcVelocityX2             ) );
+      case D3Q27System::SE: return (float)( UbMath::c1o9*(+bcVelocityX1-bcVelocityX2             ) );
+      case D3Q27System::NW: return (float)( UbMath::c1o9*(-bcVelocityX1+bcVelocityX2             ) );
+      case D3Q27System::TE: return (float)( UbMath::c1o9*(+bcVelocityX1             +bcVelocityX3) );
+      case D3Q27System::BW: return (float)( UbMath::c1o9*(-bcVelocityX1             -bcVelocityX3) );
+      case D3Q27System::BE: return (float)( UbMath::c1o9*(+bcVelocityX1             -bcVelocityX3) );
+      case D3Q27System::TW: return (float)( UbMath::c1o9*(-bcVelocityX1             +bcVelocityX3) );
+      case D3Q27System::TN: return (float)( UbMath::c1o9*(             +bcVelocityX2+bcVelocityX3) );
+      case D3Q27System::BS: return (float)( UbMath::c1o9*(             -bcVelocityX2-bcVelocityX3) );
+      case D3Q27System::BN: return (float)( UbMath::c1o9*(             +bcVelocityX2-bcVelocityX3) );
+      case D3Q27System::TS: return (float)( UbMath::c1o9*(             -bcVelocityX2+bcVelocityX3) );
+      case D3Q27System::TNE: return (float)( UbMath::c1o36*(+bcVelocityX1+bcVelocityX2+bcVelocityX3) );
+      case D3Q27System::BSW: return (float)( UbMath::c1o36*(-bcVelocityX1-bcVelocityX2-bcVelocityX3) );
+      case D3Q27System::BNE: return (float)( UbMath::c1o36*(+bcVelocityX1+bcVelocityX2-bcVelocityX3) );
+      case D3Q27System::TSW: return (float)( UbMath::c1o36*(-bcVelocityX1-bcVelocityX2+bcVelocityX3) );
+      case D3Q27System::TSE: return (float)( UbMath::c1o36*(+bcVelocityX1-bcVelocityX2+bcVelocityX3) );
+      case D3Q27System::BNW: return (float)( UbMath::c1o36*(-bcVelocityX1+bcVelocityX2-bcVelocityX3) );
+      case D3Q27System::BSE: return (float)( UbMath::c1o36*(+bcVelocityX1-bcVelocityX2-bcVelocityX3) );
+      case D3Q27System::TNW: return (float)( UbMath::c1o36*(-bcVelocityX1+bcVelocityX2+bcVelocityX3) ); 
+      default: throw UbException(UB_EXARGS,"unknown error");
+      }
+   }
+
+   /*============== Density Boundary ========================*/
+   void       setDensityBoundaryFlag(const int& direction, const short& secOpt=0) { this->setFlagBits(densityBoundaryFlags,direction,secOpt);                                     }  
+   void       unsetDensityBoundaryFlag(const int& direction)                      { this->densityBoundaryFlags &= ~( maxOptionVal<<(direction*optionDigits) );                    }
+   void       unsetDensityBoundary()                                              { this->densityBoundaryFlags = 0;                                                               }
+   long long  getDensityBoundary()	                                              { return this->densityBoundaryFlags;                                                            }
+   bool       hasDensityBoundary()					                                  { return (this->densityBoundaryFlags!=0);                                                       }
+   bool       hasDensityBoundaryFlag(const int& direction)	                      { return ( ( ( densityBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) != 0);         }
+   short      getDensitySecondaryOption(const int& direction)                     { return (short)( (  ( densityBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) - 1 ); }
+
+   void  setBoundaryDensity(float density) { this->bcDensity = density; } 
+   float getBoundaryDensity()              { return this->bcDensity;    }
+
+   //Lodi extension
+   void  setDensityLodiDensity(const float& bcLodiDensity)       { this->bcLodiDensity    = bcLodiDensity;    } 
+   void  setDensityLodiVelocityX1(const float& bcLodiVelocityX1) { this->bcLodiVelocityX1 = bcLodiVelocityX1; } 
+   void  setDensityLodiVelocityX2(const float& bcLodiVelocityX2) { this->bcLodiVelocityX2 = bcLodiVelocityX2; } 
+   void  setDensityLodiVelocityX3(const float& bcLodiVelocityX3) { this->bcLodiVelocityX3 = bcLodiVelocityX3; } 
+   void  setDensityLodiLength(const float& bcLodiLentgh)         { this->bcLodiLentgh     = bcLodiLentgh;     } 
+   float getDensityLodiDensity() const                           { return this->bcLodiDensity;    } 
+   float getDensityLodiVelocityX1() const                        { return this->bcLodiVelocityX1; }
+   float getDensityLodiVelocityX2() const                        { return this->bcLodiVelocityX2; }
+   float getDensityLodiVelocityX3() const                        { return this->bcLodiVelocityX3; }
+   float getDensityLodiLength() const                            { return this->bcLodiLentgh;     }
+
+   float& densityLodiDensity()                                   { return this->bcLodiDensity;    } 
+   float& densityLodiVelocityX1()                                { return this->bcLodiVelocityX1; }
+   float& densityLodiVelocityX2()                                { return this->bcLodiVelocityX2; }
+   float& densityLodiVelocityX3()                                { return this->bcLodiVelocityX3; }
+   float& densityLodiLentgh()                                    { return this->bcLodiLentgh;     }
+
+   const float& densityLodiDensity()  const                      { return this->bcLodiDensity;    } 
+   const float& densityLodiVelocityX1() const                    { return this->bcLodiVelocityX1; }
+   const float& densityLodiVelocityX2() const                    { return this->bcLodiVelocityX2; }
+   const float& densityLodiVelocityX3() const                    { return this->bcLodiVelocityX3; }
+   const float& densityLodiLentgh()  const                       { return this->bcLodiLentgh;     }
+
+
+   /*======================= Qs =============================*/
+   void  setQ(const float& val, const int& direction) { q[direction] = val; }
+   float getQ(const int& direction)                   { return q[direction]; }
+   
+   virtual std::vector< std::string > getBCNames()
+   {
+      std::vector< std::string > tmp;
+      tmp.push_back( "NoSlipBC"   );
+      tmp.push_back( "SlipBC"     );
+      tmp.push_back( "VelocityBC" );
+      tmp.push_back( "DensityBC"  );
+      return tmp;
+   }
+   virtual std::vector< long long > getBCFlags()
+   {
+      std::vector< long long > tmp;
+      tmp.push_back( noslipBoundaryFlags   );
+      tmp.push_back( slipBoundaryFlags     );
+      tmp.push_back( velocityBoundaryFlags );
+      tmp.push_back( densityBoundaryFlags  );
+      return tmp;
+   }
+
+   static bool hasFlagForDirection(const long long& flag, const int& direction)
+   {
+      return ( ( ( flag>>(optionDigits*direction) ) & maxOptionVal ) != 0);
+   }
+
+   void setBcAlgorithmType(char alg) { algorithmType = alg; }
+   char getBcAlgorithmType() { return algorithmType; }
+
+public:
+   static const int       optionDigits = 2;  //--> 3 bits für secondary Option --> maxOptionVal = 7, da man mit drei Digits max die 7 darstellen kann
+   static const long long maxOptionVal;// = ( 1<<optionDigits ) - 1; //2^3-1 -> 7
+
+protected:
+   float q[D3Q27System::FENDDIR+1];
+   //float q[D3Q27System::STARTF+1];
+
+   long long noslipBoundaryFlags;		
+   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;
+
+   char algorithmType;
+
+private:
+   friend class MPIIORestart1CoProcessor;
+   friend class MPIIORestart2CoProcessor;
+   friend class MPIIORestart11CoProcessor;
+   friend class MPIIORestart21CoProcessor;
+
+
+   friend class boost::serialization::access;
+   template<class Archive>
+   void serialize(Archive & ar, const unsigned int version)
+   {
+      ar & q; 
+
+      ar & noslipBoundaryFlags;		
+      ar & slipBoundaryFlags;		
+      ar & velocityBoundaryFlags;		
+      ar & densityBoundaryFlags;		
+
+      ar & bcVelocityX1;
+      ar & bcVelocityX2;
+      ar & bcVelocityX3;
+      ar & bcDensity;
+
+      ar & bcLodiDensity;
+      ar & bcLodiVelocityX1;
+      ar & bcLodiVelocityX2;
+      ar & bcLodiVelocityX3;
+      ar & bcLodiLentgh;
+
+      ar & wallModelBoundaryFlags;
+
+      ar & nx1;
+      ar & nx2;
+      ar & nx3;
+
+      ar & algorithmType;
+   }
+
+};
+
+#endif //D3Q27BOUNDARYCONDITION_H
diff --git a/source/VirtualFluidsCore/BoundaryConditions/EqDensityBCAlgorithm.cpp b/source/VirtualFluidsCore/BoundaryConditions/EqDensityBCAlgorithm.cpp
index 4ef545ab6..91faa3da0 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/EqDensityBCAlgorithm.cpp
+++ b/source/VirtualFluidsCore/BoundaryConditions/EqDensityBCAlgorithm.cpp
@@ -1,58 +1,60 @@
-#include "EqDensityBCAlgorithm.h"
-#include <boost/pointer_cast.hpp>
-
-EqDensityBCAlgorithm::EqDensityBCAlgorithm()
-{
-   BCAlgorithm::type = BCAlgorithm::EqDensityBCAlgorithm;
-   BCAlgorithm::preCollision = false;
-}
-//////////////////////////////////////////////////////////////////////////
-EqDensityBCAlgorithm::~EqDensityBCAlgorithm()
-{
-}
-//////////////////////////////////////////////////////////////////////////
-BCAlgorithmPtr EqDensityBCAlgorithm::clone()
-{
-   BCAlgorithmPtr bc(new EqDensityBCAlgorithm());
-   return bc;
-}
-//////////////////////////////////////////////////////////////////////////
-void EqDensityBCAlgorithm::addDistributions(DistributionArray3DPtr distributions)
-{
-   this->distributions = distributions;
-}
-//////////////////////////////////////////////////////////////////////////
-void EqDensityBCAlgorithm::applyBC()
-{
-   LBMReal f[D3Q27System::ENDF+1];
-
-   distributions->getDistributionInv(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..."));
-
-   LBMReal rho, vx1, vx2, vx3;
-   calcMacrosFct(f, rho, vx1, vx2, vx3);
-   LBMReal rhoBC = bcPtr->getBoundaryDensity();
-   for (int fdir = D3Q27System::STARTF; fdir<=D3Q27System::ENDF; fdir++)
-   {
-      if (bcPtr->hasDensityBoundaryFlag(fdir))
-      {
-         //Ehsan: 15.2.2013:
-         LBMReal ftemp = calcFeqsForDirFct(fdir, rhoBC, vx1, vx2, vx3);
-         distributions->setDistributionForDirection(ftemp, nx1, nx2, nx3, fdir);
-      }
-   }
-
-}
-
+#include "EqDensityBCAlgorithm.h"
+#include "DistributionArray3D.h"
+#include "BoundaryConditions.h"
+
+
+EqDensityBCAlgorithm::EqDensityBCAlgorithm()
+{
+   BCAlgorithm::type = BCAlgorithm::EqDensityBCAlgorithm;
+   BCAlgorithm::preCollision = false;
+}
+//////////////////////////////////////////////////////////////////////////
+EqDensityBCAlgorithm::~EqDensityBCAlgorithm()
+{
+}
+//////////////////////////////////////////////////////////////////////////
+BCAlgorithmPtr EqDensityBCAlgorithm::clone()
+{
+   BCAlgorithmPtr bc(new EqDensityBCAlgorithm());
+   return bc;
+}
+//////////////////////////////////////////////////////////////////////////
+void EqDensityBCAlgorithm::addDistributions(DistributionArray3DPtr distributions)
+{
+   this->distributions = distributions;
+}
+//////////////////////////////////////////////////////////////////////////
+void EqDensityBCAlgorithm::applyBC()
+{
+   LBMReal f[D3Q27System::ENDF+1];
+
+   distributions->getDistributionInv(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..."));
+
+   LBMReal rho, vx1, vx2, vx3;
+   calcMacrosFct(f, rho, vx1, vx2, vx3);
+   LBMReal rhoBC = bcPtr->getBoundaryDensity();
+   for (int fdir = D3Q27System::STARTF; fdir<=D3Q27System::ENDF; fdir++)
+   {
+      if (bcPtr->hasDensityBoundaryFlag(fdir))
+      {
+         //Ehsan: 15.2.2013:
+         LBMReal ftemp = calcFeqsForDirFct(fdir, rhoBC, vx1, vx2, vx3);
+         distributions->setDistributionForDirection(ftemp, nx1, nx2, nx3, fdir);
+      }
+   }
+
+}
+
diff --git a/source/VirtualFluidsCore/BoundaryConditions/EqDensityBCAlgorithm.h b/source/VirtualFluidsCore/BoundaryConditions/EqDensityBCAlgorithm.h
index c37b7b5a5..2ae0e57e1 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/EqDensityBCAlgorithm.h
+++ b/source/VirtualFluidsCore/BoundaryConditions/EqDensityBCAlgorithm.h
@@ -1,26 +1,27 @@
-#ifndef EqDensityBCAlgorithm_h__
-#define EqDensityBCAlgorithm_h__
-
-#include "BCAlgorithm.h"
-
-class EqDensityBCAlgorithm;
-typedef boost::shared_ptr<EqDensityBCAlgorithm> EqDensityBCAlgorithmPtr;
-
-class EqDensityBCAlgorithm : public BCAlgorithm
-{
-public:
-   EqDensityBCAlgorithm();
-   ~EqDensityBCAlgorithm();
-   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 // EqDensityBCAlgorithm_h__
+#ifndef EqDensityBCAlgorithm_h__
+#define EqDensityBCAlgorithm_h__
+
+#include "BCAlgorithm.h"
+
+class DistributionArray3D;
+
+class EqDensityBCAlgorithm;
+typedef std::shared_ptr<EqDensityBCAlgorithm> EqDensityBCAlgorithmPtr;
+
+class EqDensityBCAlgorithm : public BCAlgorithm
+{
+public:
+   EqDensityBCAlgorithm();
+   ~EqDensityBCAlgorithm();
+   BCAlgorithmPtr clone();
+   void addDistributions(std::shared_ptr<DistributionArray3D> distributions);
+   void applyBC() override;
+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 // EqDensityBCAlgorithm_h__
diff --git a/source/VirtualFluidsCore/BoundaryConditions/HighViscosityNoSlipBCAlgorithm.cpp b/source/VirtualFluidsCore/BoundaryConditions/HighViscosityNoSlipBCAlgorithm.cpp
index 187c7045c..20bb7bf94 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/HighViscosityNoSlipBCAlgorithm.cpp
+++ b/source/VirtualFluidsCore/BoundaryConditions/HighViscosityNoSlipBCAlgorithm.cpp
@@ -1,45 +1,47 @@
-#include "HighViscosityNoSlipBCAlgorithm.h"
-
-HighViscosityNoSlipBCAlgorithm::HighViscosityNoSlipBCAlgorithm()
-{
-   BCAlgorithm::type = BCAlgorithm::HighViscosityNoSlipBCAlgorithm;
-   BCAlgorithm::preCollision = true;
-}
-//////////////////////////////////////////////////////////////////////////
-HighViscosityNoSlipBCAlgorithm::~HighViscosityNoSlipBCAlgorithm()
-{
-}
-//////////////////////////////////////////////////////////////////////////
-BCAlgorithmPtr HighViscosityNoSlipBCAlgorithm::clone()
-{
-   BCAlgorithmPtr bc(new HighViscosityNoSlipBCAlgorithm());
-   return bc;
-}
-//////////////////////////////////////////////////////////////////////////
-void HighViscosityNoSlipBCAlgorithm::addDistributions(DistributionArray3DPtr distributions)
-{
-   this->distributions = distributions;
-}
-//////////////////////////////////////////////////////////////////////////
-void HighViscosityNoSlipBCAlgorithm::applyBC()
-{
-   LBMReal f[D3Q27System::ENDF+1];
-   LBMReal feq[D3Q27System::ENDF+1];
-   distributions->getDistribution(f, x1, x2, x3);
-   LBMReal rho, vx1, vx2, vx3;
-   calcMacrosFct(f, rho, vx1, vx2, vx3);
-   calcFeqFct(feq, rho, vx1, vx2, vx3);
-
-   for (int fDir = D3Q27System::FSTARTDIR; fDir<=D3Q27System::FENDDIR; fDir++)
-   {
-      if (bcPtr->hasNoSlipBoundaryFlag(fDir))
-      {
-         //quadratic bounce back
-         const int invDir = D3Q27System::INVDIR[fDir];
-         LBMReal q = bcPtr->getQ(invDir);
-         LBMReal fReturn = (f[invDir]+q*f[fDir]+q*collFactor*(feq[invDir]-f[invDir]+feq[fDir]-f[fDir]))/(1.0+q);
-         distributions->setDistributionInvForDirection(fReturn, x1+D3Q27System::DX1[invDir], x2+D3Q27System::DX2[invDir], x3+D3Q27System::DX3[invDir], invDir);
-      }
-   }
-}
-
+#include "HighViscosityNoSlipBCAlgorithm.h"
+#include "DistributionArray3D.h"
+#include "BoundaryConditions.h"
+
+HighViscosityNoSlipBCAlgorithm::HighViscosityNoSlipBCAlgorithm()
+{
+   BCAlgorithm::type = BCAlgorithm::HighViscosityNoSlipBCAlgorithm;
+   BCAlgorithm::preCollision = true;
+}
+//////////////////////////////////////////////////////////////////////////
+HighViscosityNoSlipBCAlgorithm::~HighViscosityNoSlipBCAlgorithm()
+{
+}
+//////////////////////////////////////////////////////////////////////////
+BCAlgorithmPtr HighViscosityNoSlipBCAlgorithm::clone()
+{
+   BCAlgorithmPtr bc(new HighViscosityNoSlipBCAlgorithm());
+   return bc;
+}
+//////////////////////////////////////////////////////////////////////////
+void HighViscosityNoSlipBCAlgorithm::addDistributions(DistributionArray3DPtr distributions)
+{
+   this->distributions = distributions;
+}
+//////////////////////////////////////////////////////////////////////////
+void HighViscosityNoSlipBCAlgorithm::applyBC()
+{
+   LBMReal f[D3Q27System::ENDF+1];
+   LBMReal feq[D3Q27System::ENDF+1];
+   distributions->getDistribution(f, x1, x2, x3);
+   LBMReal rho, vx1, vx2, vx3;
+   calcMacrosFct(f, rho, vx1, vx2, vx3);
+   calcFeqFct(feq, rho, vx1, vx2, vx3);
+
+   for (int fDir = D3Q27System::FSTARTDIR; fDir<=D3Q27System::FENDDIR; fDir++)
+   {
+      if (bcPtr->hasNoSlipBoundaryFlag(fDir))
+      {
+         //quadratic bounce back
+         const int invDir = D3Q27System::INVDIR[fDir];
+         LBMReal q = bcPtr->getQ(invDir);
+         LBMReal fReturn = (f[invDir]+q*f[fDir]+q*collFactor*(feq[invDir]-f[invDir]+feq[fDir]-f[fDir]))/(1.0+q);
+         distributions->setDistributionInvForDirection(fReturn, x1+D3Q27System::DX1[invDir], x2+D3Q27System::DX2[invDir], x3+D3Q27System::DX3[invDir], invDir);
+      }
+   }
+}
+
diff --git a/source/VirtualFluidsCore/BoundaryConditions/HighViscosityNoSlipBCAlgorithm.h b/source/VirtualFluidsCore/BoundaryConditions/HighViscosityNoSlipBCAlgorithm.h
index c7d0d3587..792639c7e 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/HighViscosityNoSlipBCAlgorithm.h
+++ b/source/VirtualFluidsCore/BoundaryConditions/HighViscosityNoSlipBCAlgorithm.h
@@ -1,27 +1,29 @@
-#ifndef HighViscosityNoSlipBCAlgorithm_h__
-#define HighViscosityNoSlipBCAlgorithm_h__
-
-#include "BCAlgorithm.h"
-
-class HighViscosityNoSlipBCAlgorithm;
-typedef boost::shared_ptr<HighViscosityNoSlipBCAlgorithm> HighViscosityNoSlipBCAlgorithmPtr;
-
-class HighViscosityNoSlipBCAlgorithm : public BCAlgorithm
-{
-public:
-   HighViscosityNoSlipBCAlgorithm();
-   ~HighViscosityNoSlipBCAlgorithm();
-   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 // HighViscosityNoSlipBCAlgorithm_h__
-
+#ifndef HighViscosityNoSlipBCAlgorithm_h__
+#define HighViscosityNoSlipBCAlgorithm_h__
+
+#include "BCAlgorithm.h"
+
+class DistributionArray3D;
+
+class HighViscosityNoSlipBCAlgorithm;
+typedef std::shared_ptr<HighViscosityNoSlipBCAlgorithm> HighViscosityNoSlipBCAlgorithmPtr;
+
+class HighViscosityNoSlipBCAlgorithm : public BCAlgorithm
+{
+public:
+   HighViscosityNoSlipBCAlgorithm();
+   ~HighViscosityNoSlipBCAlgorithm();
+   BCAlgorithmPtr clone();
+   void addDistributions(std::shared_ptr<DistributionArray3D> distributions);
+
+   void applyBC() override;
+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 // HighViscosityNoSlipBCAlgorithm_h__
+
diff --git a/source/VirtualFluidsCore/BoundaryConditions/NoSlipBCAlgorithm.cpp b/source/VirtualFluidsCore/BoundaryConditions/NoSlipBCAlgorithm.cpp
index 2c00cbce5..f1537aea1 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/NoSlipBCAlgorithm.cpp
+++ b/source/VirtualFluidsCore/BoundaryConditions/NoSlipBCAlgorithm.cpp
@@ -1,45 +1,47 @@
-#include "NoSlipBCAlgorithm.h"
-
-NoSlipBCAlgorithm::NoSlipBCAlgorithm()
-{
-   BCAlgorithm::type = BCAlgorithm::NoSlipBCAlgorithm;
-   BCAlgorithm::preCollision = false;
-}
-//////////////////////////////////////////////////////////////////////////
-NoSlipBCAlgorithm::~NoSlipBCAlgorithm()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-BCAlgorithmPtr NoSlipBCAlgorithm::clone()
-{
-   BCAlgorithmPtr bc(new NoSlipBCAlgorithm());
-   return bc;
-}
-//////////////////////////////////////////////////////////////////////////
-void NoSlipBCAlgorithm::addDistributions(DistributionArray3DPtr distributions)
-{
-   this->distributions = distributions;
-}
-//////////////////////////////////////////////////////////////////////////
-void NoSlipBCAlgorithm::applyBC()
-{
-   LBMReal f[D3Q27System::ENDF+1];
-   LBMReal feq[D3Q27System::ENDF+1];
-   distributions->getDistributionInv(f, x1, x2, x3);
-   LBMReal rho, vx1, vx2, vx3;
-   calcMacrosFct(f, rho, vx1, vx2, vx3);
-   calcFeqFct(feq, rho, vx1, vx2, vx3);
-
-   for (int fdir = D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
-   {
-      if (bcPtr->hasNoSlipBoundaryFlag(fdir))
-      {
-         //quadratic bounce back
-         const int invDir = D3Q27System::INVDIR[fdir];
-         LBMReal q = bcPtr->getQ(invDir);
-         LBMReal fReturn = ((1.0-q)/(1.0+q))*((f[invDir]-feq[invDir])/(1.0-collFactor)+feq[invDir])+((q/(1.0+q))*(f[invDir]+f[fdir]));
-         distributions->setDistributionForDirection(fReturn, x1+D3Q27System::DX1[invDir], x2+D3Q27System::DX2[invDir], x3+D3Q27System::DX3[invDir], fdir);
-      }
-   }
-}
+#include "NoSlipBCAlgorithm.h"
+#include "DistributionArray3D.h"
+#include "BoundaryConditions.h"
+
+NoSlipBCAlgorithm::NoSlipBCAlgorithm()
+{
+   BCAlgorithm::type = BCAlgorithm::NoSlipBCAlgorithm;
+   BCAlgorithm::preCollision = false;
+}
+//////////////////////////////////////////////////////////////////////////
+NoSlipBCAlgorithm::~NoSlipBCAlgorithm()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+BCAlgorithmPtr NoSlipBCAlgorithm::clone()
+{
+   BCAlgorithmPtr bc(new NoSlipBCAlgorithm());
+   return bc;
+}
+//////////////////////////////////////////////////////////////////////////
+void NoSlipBCAlgorithm::addDistributions(DistributionArray3DPtr distributions)
+{
+   this->distributions = distributions;
+}
+//////////////////////////////////////////////////////////////////////////
+void NoSlipBCAlgorithm::applyBC()
+{
+   LBMReal f[D3Q27System::ENDF+1];
+   LBMReal feq[D3Q27System::ENDF+1];
+   distributions->getDistributionInv(f, x1, x2, x3);
+   LBMReal rho, vx1, vx2, vx3;
+   calcMacrosFct(f, rho, vx1, vx2, vx3);
+   calcFeqFct(feq, rho, vx1, vx2, vx3);
+
+   for (int fdir = D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
+   {
+      if (bcPtr->hasNoSlipBoundaryFlag(fdir))
+      {
+         //quadratic bounce back
+         const int invDir = D3Q27System::INVDIR[fdir];
+         LBMReal q = bcPtr->getQ(invDir);
+         LBMReal fReturn = ((1.0-q)/(1.0+q))*((f[invDir]-feq[invDir])/(1.0-collFactor)+feq[invDir])+((q/(1.0+q))*(f[invDir]+f[fdir]));
+         distributions->setDistributionForDirection(fReturn, x1+D3Q27System::DX1[invDir], x2+D3Q27System::DX2[invDir], x3+D3Q27System::DX3[invDir], fdir);
+      }
+   }
+}
diff --git a/source/VirtualFluidsCore/BoundaryConditions/NoSlipBCAlgorithm.h b/source/VirtualFluidsCore/BoundaryConditions/NoSlipBCAlgorithm.h
index d6f2a8b54..862d2972e 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/NoSlipBCAlgorithm.h
+++ b/source/VirtualFluidsCore/BoundaryConditions/NoSlipBCAlgorithm.h
@@ -1,27 +1,27 @@
-#ifndef NoSlipBCAlgorithm_h__
-#define NoSlipBCAlgorithm_h__
-
-#include "BCAlgorithm.h"
-
-class NoSlipBCAlgorithm;
-typedef boost::shared_ptr<NoSlipBCAlgorithm> NoSlipBCAlgorithmPtr;
-
-class NoSlipBCAlgorithm : public BCAlgorithm
-{
-public:
-   NoSlipBCAlgorithm();
-   virtual ~NoSlipBCAlgorithm();
-   BCAlgorithmPtr clone();
-   void addDistributions(DistributionArray3DPtr distributions);
-   void applyBC();
-protected:
-   
-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 // NoSlipBCAlgorithm_h__
+#ifndef NoSlipBCAlgorithm_h__
+#define NoSlipBCAlgorithm_h__
+
+#include "BCAlgorithm.h"
+
+class DistributionArray3D;
+
+class NoSlipBCAlgorithm;
+typedef std::shared_ptr<NoSlipBCAlgorithm> NoSlipBCAlgorithmPtr;
+
+class NoSlipBCAlgorithm : public BCAlgorithm
+{
+public:
+   NoSlipBCAlgorithm();
+   virtual ~NoSlipBCAlgorithm();
+   BCAlgorithmPtr clone();
+   void addDistributions(std::shared_ptr<DistributionArray3D> distributions);
+   void applyBC() override;
+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 // NoSlipBCAlgorithm_h__
diff --git a/source/VirtualFluidsCore/BoundaryConditions/NonEqDensityBCAlgorithm.cpp b/source/VirtualFluidsCore/BoundaryConditions/NonEqDensityBCAlgorithm.cpp
index ca7bcc7f5..ca27148c7 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/NonEqDensityBCAlgorithm.cpp
+++ b/source/VirtualFluidsCore/BoundaryConditions/NonEqDensityBCAlgorithm.cpp
@@ -1,59 +1,61 @@
-#include "NonEqDensityBCAlgorithm.h"
-#include <boost/pointer_cast.hpp>
-
-NonEqDensityBCAlgorithm::NonEqDensityBCAlgorithm()
-{
-   BCAlgorithm::type = BCAlgorithm::NonEqDensityBCAlgorithm;
-   BCAlgorithm::preCollision = false;
-}
-//////////////////////////////////////////////////////////////////////////
-NonEqDensityBCAlgorithm::~NonEqDensityBCAlgorithm()
-{
-}
-//////////////////////////////////////////////////////////////////////////
-BCAlgorithmPtr NonEqDensityBCAlgorithm::clone()
-{
-   BCAlgorithmPtr bc(new NonEqDensityBCAlgorithm());
-   return bc;
-}
-//////////////////////////////////////////////////////////////////////////
-void NonEqDensityBCAlgorithm::addDistributions(DistributionArray3DPtr distributions)
-{
-   this->distributions = distributions;
-}
-//////////////////////////////////////////////////////////////////////////
-void NonEqDensityBCAlgorithm::applyBC()
-{
-   LBMReal f[D3Q27System::ENDF+1];
-   distributions->getDistributionInv(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..."));
-
-   LBMReal rho, vx1, vx2, vx3;
-   calcMacrosFct(f, rho, vx1, vx2, vx3);
-   LBMReal rhoBC = bcPtr->getBoundaryDensity();
-   for (int fdir = D3Q27System::STARTF; fdir<=D3Q27System::ENDF; fdir++)
-   {
-      if (bcPtr->hasDensityBoundaryFlag(fdir))
-      {
-         // Martins NEQ ADDON
-         ////original: 15.2.2013:
-         LBMReal ftemp = calcFeqsForDirFct(fdir, rho, vx1, vx2, vx3);
-         ftemp = calcFeqsForDirFct(fdir, rhoBC, vx1, vx2, vx3)+f[fdir]-ftemp;
-         distributions->setDistributionForDirection(ftemp, nx1, nx2, nx3, fdir);
-      }
-   }
-
-}
-
+#include "NonEqDensityBCAlgorithm.h"
+
+#include "DistributionArray3D.h"
+#include "BoundaryConditions.h"
+
+NonEqDensityBCAlgorithm::NonEqDensityBCAlgorithm()
+{
+   BCAlgorithm::type = BCAlgorithm::NonEqDensityBCAlgorithm;
+   BCAlgorithm::preCollision = false;
+}
+//////////////////////////////////////////////////////////////////////////
+NonEqDensityBCAlgorithm::~NonEqDensityBCAlgorithm()
+{
+}
+//////////////////////////////////////////////////////////////////////////
+BCAlgorithmPtr NonEqDensityBCAlgorithm::clone()
+{
+   BCAlgorithmPtr bc(new NonEqDensityBCAlgorithm());
+   return bc;
+}
+//////////////////////////////////////////////////////////////////////////
+void NonEqDensityBCAlgorithm::addDistributions(DistributionArray3DPtr distributions)
+{
+   this->distributions = distributions;
+}
+//////////////////////////////////////////////////////////////////////////
+void NonEqDensityBCAlgorithm::applyBC()
+{
+   LBMReal f[D3Q27System::ENDF+1];
+   distributions->getDistributionInv(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..."));
+
+   LBMReal rho, vx1, vx2, vx3;
+   calcMacrosFct(f, rho, vx1, vx2, vx3);
+   LBMReal rhoBC = bcPtr->getBoundaryDensity();
+   for (int fdir = D3Q27System::STARTF; fdir<=D3Q27System::ENDF; fdir++)
+   {
+      if (bcPtr->hasDensityBoundaryFlag(fdir))
+      {
+         // Martins NEQ ADDON
+         ////original: 15.2.2013:
+         LBMReal ftemp = calcFeqsForDirFct(fdir, rho, vx1, vx2, vx3);
+         ftemp = calcFeqsForDirFct(fdir, rhoBC, vx1, vx2, vx3)+f[fdir]-ftemp;
+         distributions->setDistributionForDirection(ftemp, nx1, nx2, nx3, fdir);
+      }
+   }
+
+}
+
diff --git a/source/VirtualFluidsCore/BoundaryConditions/NonEqDensityBCAlgorithm.h b/source/VirtualFluidsCore/BoundaryConditions/NonEqDensityBCAlgorithm.h
index 52753316b..b0fb870cc 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/NonEqDensityBCAlgorithm.h
+++ b/source/VirtualFluidsCore/BoundaryConditions/NonEqDensityBCAlgorithm.h
@@ -1,27 +1,27 @@
-#ifndef NonEqDensityBCAlgorithm_h__
-#define NonEqDensityBCAlgorithm_h__
-
-#include "BCAlgorithm.h"
-
-class NonEqDensityBCAlgorithm;
-typedef boost::shared_ptr<NonEqDensityBCAlgorithm> NonEqDensityBCAlgorithmPtr;
-
-class NonEqDensityBCAlgorithm : public BCAlgorithm
-{
-public:
-   NonEqDensityBCAlgorithm();
-   ~NonEqDensityBCAlgorithm();
-   BCAlgorithmPtr clone();
-   void addDistributions(DistributionArray3DPtr distributions);
-   void applyBC();
-protected:
-   
-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 // NonEqDensityBCAlgorithm_h__
+#ifndef NonEqDensityBCAlgorithm_h__
+#define NonEqDensityBCAlgorithm_h__
+
+#include "BCAlgorithm.h"
+
+class DistributionArray3D;
+
+class NonEqDensityBCAlgorithm;
+typedef std::shared_ptr<NonEqDensityBCAlgorithm> NonEqDensityBCAlgorithmPtr;
+
+class NonEqDensityBCAlgorithm : public BCAlgorithm
+{
+public:
+   NonEqDensityBCAlgorithm();
+   ~NonEqDensityBCAlgorithm();
+   BCAlgorithmPtr clone();
+   void addDistributions(std::shared_ptr<DistributionArray3D> distributions);
+   void applyBC() override;
+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 // NonEqDensityBCAlgorithm_h__
diff --git a/source/VirtualFluidsCore/BoundaryConditions/NonReflectingOutflowBCAlgorithm.cpp b/source/VirtualFluidsCore/BoundaryConditions/NonReflectingOutflowBCAlgorithm.cpp
index 129c1aa95..1d682393d 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/NonReflectingOutflowBCAlgorithm.cpp
+++ b/source/VirtualFluidsCore/BoundaryConditions/NonReflectingOutflowBCAlgorithm.cpp
@@ -1,185 +1,188 @@
-#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!"));
-   }
-}
-
+#include "NonReflectingOutflowBCAlgorithm.h"
+
+#include "D3Q27System.h"
+#include "DistributionArray3D.h"
+#include "BoundaryConditions.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/NonReflectingOutflowBCAlgorithm.h b/source/VirtualFluidsCore/BoundaryConditions/NonReflectingOutflowBCAlgorithm.h
index 1b65b022d..e83592889 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/NonReflectingOutflowBCAlgorithm.h
+++ b/source/VirtualFluidsCore/BoundaryConditions/NonReflectingOutflowBCAlgorithm.h
@@ -1,27 +1,28 @@
-#ifndef NonReflectingOutflowBCAlgorithm_h__
-#define NonReflectingOutflowBCAlgorithm_h__
-
-#include "BCAlgorithm.h"
-
-class NonReflectingOutflowBCAlgorithm;
-typedef boost::shared_ptr<NonReflectingOutflowBCAlgorithm> NonReflectingOutflowBCAlgorithmPtr;
-
-class NonReflectingOutflowBCAlgorithm : public BCAlgorithm
-{
-public:
-   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)
-   //{
-   //   ar & boost::serialization::base_object<BCAlgorithm>(*this);
-   //}
-};
-#endif // NonReflectingDensityBCAlgorithm_h__
+#ifndef NonReflectingOutflowBCAlgorithm_h__
+#define NonReflectingOutflowBCAlgorithm_h__
+
+#include "BCAlgorithm.h"
+
+class DistributionArray3D;
+
+class NonReflectingOutflowBCAlgorithm;
+typedef std::shared_ptr<NonReflectingOutflowBCAlgorithm> NonReflectingOutflowBCAlgorithmPtr;
+
+class NonReflectingOutflowBCAlgorithm : public BCAlgorithm
+{
+public:
+   NonReflectingOutflowBCAlgorithm();
+   ~NonReflectingOutflowBCAlgorithm();
+   BCAlgorithmPtr clone();
+   void addDistributions(std::shared_ptr<DistributionArray3D> distributions);
+   void applyBC() override;
+private:
+   int step;
+   //friend class boost::serialization::access;
+   //template<class Archive>
+   //void serialize(Archive & ar, const unsigned int version)
+   //{
+   //   ar & boost::serialization::base_object<BCAlgorithm>(*this);
+   //}
+};
+#endif // NonReflectingDensityBCAlgorithm_h__
diff --git a/source/VirtualFluidsCore/BoundaryConditions/SlipBCAdapter.cpp b/source/VirtualFluidsCore/BoundaryConditions/SlipBCAdapter.cpp
index 71c273d53..5a56981eb 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/SlipBCAdapter.cpp
+++ b/source/VirtualFluidsCore/BoundaryConditions/SlipBCAdapter.cpp
@@ -2,7 +2,7 @@
 #include "D3Q27System.h"
 #include "D3Q27Interactor.h"
 #include "numerics/geometry3d/GbCuboid3D.h"
-#include <boost/pointer_cast.hpp>
+
 
 //*==========================================================*/
 //ObObject* D3Q27SlipBCAdapterCreator::createObObject()
@@ -20,7 +20,7 @@ void SlipBCAdapter::adaptBC(const D3Q27Interactor& interactor, BoundaryCondition
    //////////////////////////////////////////////////////////////////////////
    //>>> nur workaround! -> Hendrick nach normalen berechnung aus qs fragen
    
-   GbCuboid3DPtr geo = boost::dynamic_pointer_cast<GbCuboid3D>(interactor.getGbObject3D());
+   GbCuboid3DPtr geo = std::dynamic_pointer_cast<GbCuboid3D>(interactor.getGbObject3D());
    if(!geo) throw UbException(UB_EXARGS,"derzeit nur fuer Cubes valide");
 
    if     ( bc->hasSlipBoundaryFlag(D3Q27System::E) ) bc->setNormalVector( 1.0, 0.0, 0.0);  
diff --git a/source/VirtualFluidsCore/BoundaryConditions/SlipBCAlgorithm.cpp b/source/VirtualFluidsCore/BoundaryConditions/SlipBCAlgorithm.cpp
index 5937fa2b3..84eca6852 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/SlipBCAlgorithm.cpp
+++ b/source/VirtualFluidsCore/BoundaryConditions/SlipBCAlgorithm.cpp
@@ -1,86 +1,88 @@
-#include "SlipBCAlgorithm.h"
-
-SlipBCAlgorithm::SlipBCAlgorithm()
-{
-   BCAlgorithm::type = BCAlgorithm::SlipBCAlgorithm;
-   BCAlgorithm::preCollision = false;
-}
-//////////////////////////////////////////////////////////////////////////
-SlipBCAlgorithm::~SlipBCAlgorithm()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-BCAlgorithmPtr SlipBCAlgorithm::clone()
-{
-   BCAlgorithmPtr bc(new SlipBCAlgorithm());
-   return bc;
-}
-//////////////////////////////////////////////////////////////////////////
-void SlipBCAlgorithm::addDistributions(DistributionArray3DPtr distributions)
-{
-   this->distributions = distributions;
-}
-//////////////////////////////////////////////////////////////////////////
-void SlipBCAlgorithm::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 = 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));
-         distributions->setDistributionForDirection(fReturn, x1+D3Q27System::DX1[invDir], x2+D3Q27System::DX2[invDir], x3+D3Q27System::DX3[invDir], fdir);
-      }
-   }
+#include "SlipBCAlgorithm.h"
+#include "DistributionArray3D.h"
+#include "BoundaryConditions.h"
+
+SlipBCAlgorithm::SlipBCAlgorithm()
+{
+   BCAlgorithm::type = BCAlgorithm::SlipBCAlgorithm;
+   BCAlgorithm::preCollision = false;
+}
+//////////////////////////////////////////////////////////////////////////
+SlipBCAlgorithm::~SlipBCAlgorithm()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+BCAlgorithmPtr SlipBCAlgorithm::clone()
+{
+   BCAlgorithmPtr bc(new SlipBCAlgorithm());
+   return bc;
+}
+//////////////////////////////////////////////////////////////////////////
+void SlipBCAlgorithm::addDistributions(DistributionArray3DPtr distributions)
+{
+   this->distributions = distributions;
+}
+//////////////////////////////////////////////////////////////////////////
+void SlipBCAlgorithm::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 = 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));
+         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/SlipBCAlgorithm.h b/source/VirtualFluidsCore/BoundaryConditions/SlipBCAlgorithm.h
index ffe061523..7cd34f278 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/SlipBCAlgorithm.h
+++ b/source/VirtualFluidsCore/BoundaryConditions/SlipBCAlgorithm.h
@@ -1,26 +1,27 @@
-#ifndef SlipBCAlgorithm_h__
-#define SlipBCAlgorithm_h__
-
-#include "BCAlgorithm.h"
-
-class SlipBCAlgorithm;
-typedef boost::shared_ptr<SlipBCAlgorithm> SlipBCAlgorithmPtr;
-
-class SlipBCAlgorithm : public BCAlgorithm
-{
-public:
-   SlipBCAlgorithm();
-   virtual ~SlipBCAlgorithm();
-   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 // SlipBCAlgorithm_h__
+#ifndef SlipBCAlgorithm_h__
+#define SlipBCAlgorithm_h__
+
+#include "BCAlgorithm.h"
+
+class DistributionArray3D;
+
+class SlipBCAlgorithm;
+typedef std::shared_ptr<SlipBCAlgorithm> SlipBCAlgorithmPtr;
+
+class SlipBCAlgorithm : public BCAlgorithm
+{
+public:
+   SlipBCAlgorithm();
+   virtual ~SlipBCAlgorithm();
+   BCAlgorithmPtr clone();
+   void addDistributions(std::shared_ptr<DistributionArray3D> distributions);
+   void applyBC() override;
+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 // SlipBCAlgorithm_h__
diff --git a/source/VirtualFluidsCore/BoundaryConditions/ThinWallBCProcessor.cpp b/source/VirtualFluidsCore/BoundaryConditions/ThinWallBCProcessor.cpp
index 56e84fee5..d851f2aff 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/ThinWallBCProcessor.cpp
+++ b/source/VirtualFluidsCore/BoundaryConditions/ThinWallBCProcessor.cpp
@@ -1,41 +1,43 @@
-#include "ThinWallBCProcessor.h"
-
-#include "ThinWallNoSlipBCAlgorithm.h"
-
-ThinWallBCProcessor::ThinWallBCProcessor()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-ThinWallBCProcessor::ThinWallBCProcessor(LBMKernelPtr kernel) : BCProcessor(kernel)
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-ThinWallBCProcessor::~ThinWallBCProcessor()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-BCProcessorPtr ThinWallBCProcessor::clone(LBMKernelPtr kernel)
-{
-   BCProcessorPtr bcProcessor(new ThinWallBCProcessor(kernel));
-   return bcProcessor;
-}
-//////////////////////////////////////////////////////////////////////////
-void ThinWallBCProcessor::applyPostCollisionBC()
-{
-   BCProcessor::applyPostCollisionBC();
-
-   BOOST_FOREACH(BCAlgorithmPtr bc, postBC)
-   {
-      if (bc->getType() == BCAlgorithm::ThinWallNoSlipBCAlgorithm)
-      {
-         boost::dynamic_pointer_cast<ThinWallNoSlipBCAlgorithm>(bc)->setPass(2); 
-         bc->applyBC();
-         boost::dynamic_pointer_cast<ThinWallNoSlipBCAlgorithm>(bc)->setPass(1);
-      }
-   }
-}
-
-
+#include "ThinWallBCProcessor.h"
+
+#include "ThinWallNoSlipBCAlgorithm.h"
+
+#include "LBMKernel.h"
+
+ThinWallBCProcessor::ThinWallBCProcessor()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+ThinWallBCProcessor::ThinWallBCProcessor(LBMKernelPtr kernel) : BCProcessor(kernel)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+ThinWallBCProcessor::~ThinWallBCProcessor()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+BCProcessorPtr ThinWallBCProcessor::clone(LBMKernelPtr kernel)
+{
+   BCProcessorPtr bcProcessor(new ThinWallBCProcessor(kernel));
+   return bcProcessor;
+}
+//////////////////////////////////////////////////////////////////////////
+void ThinWallBCProcessor::applyPostCollisionBC()
+{
+   BCProcessor::applyPostCollisionBC();
+
+   for(BCAlgorithmPtr bc : postBC)
+   {
+      if (bc->getType() == BCAlgorithm::ThinWallNoSlipBCAlgorithm)
+      {
+         std::dynamic_pointer_cast<ThinWallNoSlipBCAlgorithm>(bc)->setPass(2); 
+         bc->applyBC();
+         std::dynamic_pointer_cast<ThinWallNoSlipBCAlgorithm>(bc)->setPass(1);
+      }
+   }
+}
+
+
diff --git a/source/VirtualFluidsCore/BoundaryConditions/ThinWallBCProcessor.h b/source/VirtualFluidsCore/BoundaryConditions/ThinWallBCProcessor.h
index a0a04f40b..3125180ef 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/ThinWallBCProcessor.h
+++ b/source/VirtualFluidsCore/BoundaryConditions/ThinWallBCProcessor.h
@@ -1,25 +1,24 @@
 #ifndef ThinWallBCProcessor_H
 #define ThinWallBCProcessor_H
 
+#include <memory>
+
 #include "BCProcessor.h"
-#include "BoundaryConditions.h"
-#include "EsoTwist3D.h"
-#include "BCArray3D.h"
-#include "basics/container/CbArray4D.h"
-#include "basics/container/CbArray3D.h"
 
 #include <boost/serialization/base_object.hpp>
 
 class ThinWallBCProcessor;
-typedef boost::shared_ptr<ThinWallBCProcessor> ThinWallBCProcessorPtr;
+typedef std::shared_ptr<ThinWallBCProcessor> ThinWallBCProcessorPtr;
+
+class LBMKernel;
 
 class ThinWallBCProcessor : public BCProcessor
 {
 public:
    ThinWallBCProcessor();
-   ThinWallBCProcessor(LBMKernelPtr kernel);
+   ThinWallBCProcessor(std::shared_ptr<LBMKernel> kernel);
    ~ThinWallBCProcessor();
-   BCProcessorPtr clone(LBMKernelPtr kernel);
+   std::shared_ptr<BCProcessor> clone(std::shared_ptr<LBMKernel> kernel);
    void applyPostCollisionBC();
 protected:
 private:
diff --git a/source/VirtualFluidsCore/BoundaryConditions/ThinWallNoSlipBCAlgorithm.cpp b/source/VirtualFluidsCore/BoundaryConditions/ThinWallNoSlipBCAlgorithm.cpp
index dbe5be4d7..d29f56e93 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/ThinWallNoSlipBCAlgorithm.cpp
+++ b/source/VirtualFluidsCore/BoundaryConditions/ThinWallNoSlipBCAlgorithm.cpp
@@ -1,66 +1,66 @@
-#include "ThinWallNoSlipBCAlgorithm.h"
-
-#include "D3Q27EsoTwist3DSplittedVector.h"
-
-
-ThinWallNoSlipBCAlgorithm::ThinWallNoSlipBCAlgorithm()
-{
-   BCAlgorithm::type = BCAlgorithm::ThinWallNoSlipBCAlgorithm;
-   BCAlgorithm::preCollision = false;
-   pass = 1;
-}
-//////////////////////////////////////////////////////////////////////////
-ThinWallNoSlipBCAlgorithm::~ThinWallNoSlipBCAlgorithm()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-BCAlgorithmPtr ThinWallNoSlipBCAlgorithm::clone()
-{
-   BCAlgorithmPtr bc(new ThinWallNoSlipBCAlgorithm());
-   return bc;
-}
-//////////////////////////////////////////////////////////////////////////
-void ThinWallNoSlipBCAlgorithm::applyBC()
-{
-   LBMReal f[D3Q27System::ENDF + 1];
-   LBMReal feq[D3Q27System::ENDF + 1];
-   distributions->getDistributionInv(f, x1, x2, x3);
-   LBMReal rho, vx1, vx2, vx3;
-   calcMacrosFct(f, rho, vx1, vx2, vx3);
-   calcFeqFct(feq, rho, vx1, vx2, vx3);
-
-   LBMReal fReturn;
-
-   for (int fdir = D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
-   {
-      if (bcPtr->hasNoSlipBoundaryFlag(fdir))
-      {
-         const int invDir = D3Q27System::INVDIR[fdir];
-         if (pass == 1)
-         {
-            LBMReal q = bcPtr->getQ(invDir);
-            LBMReal fReturn = ((1.0 - q) / (1.0 + q))*0.5*(f[invDir] - f[fdir] + (f[invDir] + f[fdir] - collFactor*(feq[fdir] + feq[invDir])) / (1.0 - collFactor));
-            //distributionsTemp->setDistributionForDirection(fReturn, x1 + D3Q27System::DX1[invDir], x2 + D3Q27System::DX2[invDir], x3 + D3Q27System::DX3[invDir], fdir);
-            fTemp[fdir] = fReturn;
-         }
-         else
-         {
-            //quadratic bounce back with for thin walls
-            //fReturn = distributionsTemp->getDistributionInvForDirection(x1 + D3Q27System::DX1[invDir], x2 + D3Q27System::DX2[invDir], x3 + D3Q27System::DX3[invDir], fdir);
-            fReturn = fTemp[fdir];
-            distributions->setDistributionForDirection(fReturn, x1 + D3Q27System::DX1[invDir], x2 + D3Q27System::DX2[invDir], x3 + D3Q27System::DX3[invDir], fdir);
-         }
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void ThinWallNoSlipBCAlgorithm::addDistributions(DistributionArray3DPtr distributions)
-{
-   this->distributions = distributions;
-}
-//////////////////////////////////////////////////////////////////////////
-void ThinWallNoSlipBCAlgorithm::setPass(int pass)
-{
-   this->pass = pass;
-}
+#include "ThinWallNoSlipBCAlgorithm.h"
+
+#include "D3Q27EsoTwist3DSplittedVector.h"
+#include "BoundaryConditions.h"
+
+ThinWallNoSlipBCAlgorithm::ThinWallNoSlipBCAlgorithm()
+{
+   BCAlgorithm::type = BCAlgorithm::ThinWallNoSlipBCAlgorithm;
+   BCAlgorithm::preCollision = false;
+   pass = 1;
+}
+//////////////////////////////////////////////////////////////////////////
+ThinWallNoSlipBCAlgorithm::~ThinWallNoSlipBCAlgorithm()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+BCAlgorithmPtr ThinWallNoSlipBCAlgorithm::clone()
+{
+   BCAlgorithmPtr bc(new ThinWallNoSlipBCAlgorithm());
+   return bc;
+}
+//////////////////////////////////////////////////////////////////////////
+void ThinWallNoSlipBCAlgorithm::applyBC()
+{
+   LBMReal f[D3Q27System::ENDF + 1];
+   LBMReal feq[D3Q27System::ENDF + 1];
+   distributions->getDistributionInv(f, x1, x2, x3);
+   LBMReal rho, vx1, vx2, vx3;
+   calcMacrosFct(f, rho, vx1, vx2, vx3);
+   calcFeqFct(feq, rho, vx1, vx2, vx3);
+
+   LBMReal fReturn;
+
+   for (int fdir = D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
+   {
+      if (bcPtr->hasNoSlipBoundaryFlag(fdir))
+      {
+         const int invDir = D3Q27System::INVDIR[fdir];
+         if (pass == 1)
+         {
+            LBMReal q = bcPtr->getQ(invDir);
+            LBMReal fReturn = ((1.0 - q) / (1.0 + q))*0.5*(f[invDir] - f[fdir] + (f[invDir] + f[fdir] - collFactor*(feq[fdir] + feq[invDir])) / (1.0 - collFactor));
+            //distributionsTemp->setDistributionForDirection(fReturn, x1 + D3Q27System::DX1[invDir], x2 + D3Q27System::DX2[invDir], x3 + D3Q27System::DX3[invDir], fdir);
+            fTemp[fdir] = fReturn;
+         }
+         else
+         {
+            //quadratic bounce back with for thin walls
+            //fReturn = distributionsTemp->getDistributionInvForDirection(x1 + D3Q27System::DX1[invDir], x2 + D3Q27System::DX2[invDir], x3 + D3Q27System::DX3[invDir], fdir);
+            fReturn = fTemp[fdir];
+            distributions->setDistributionForDirection(fReturn, x1 + D3Q27System::DX1[invDir], x2 + D3Q27System::DX2[invDir], x3 + D3Q27System::DX3[invDir], fdir);
+         }
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void ThinWallNoSlipBCAlgorithm::addDistributions(DistributionArray3DPtr distributions)
+{
+   this->distributions = distributions;
+}
+//////////////////////////////////////////////////////////////////////////
+void ThinWallNoSlipBCAlgorithm::setPass(int pass)
+{
+   this->pass = pass;
+}
diff --git a/source/VirtualFluidsCore/BoundaryConditions/ThinWallNoSlipBCAlgorithm.h b/source/VirtualFluidsCore/BoundaryConditions/ThinWallNoSlipBCAlgorithm.h
index 94e462b50..7f00c20e7 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/ThinWallNoSlipBCAlgorithm.h
+++ b/source/VirtualFluidsCore/BoundaryConditions/ThinWallNoSlipBCAlgorithm.h
@@ -1,31 +1,34 @@
-#ifndef ThinWallNoSlipBCAlgorithm_h__
-#define ThinWallNoSlipBCAlgorithm_h__
-
-#include "NoSlipBCAlgorithm.h"
-
-class ThinWallNoSlipBCAlgorithm;
-typedef boost::shared_ptr<ThinWallNoSlipBCAlgorithm> ThinWallNoSlipBCAlgorithmPtr;
-
-class ThinWallNoSlipBCAlgorithm : public BCAlgorithm
-{
-public:
-   ThinWallNoSlipBCAlgorithm();
-   virtual ~ThinWallNoSlipBCAlgorithm();
-   BCAlgorithmPtr clone();
-   void addDistributions(DistributionArray3DPtr distributions);
-   void setPass(int pass);
-protected:
-   void applyBC();
-   DistributionArray3DPtr distributionsTemp;
-private:
-   int pass;
-   LBMReal fTemp[D3Q27System::ENDF + 1];
-
-   //friend class boost::serialization::access;
-   //template<class Archive>
-   //void serialize(Archive & ar, const unsigned int version)
-   //{
-   //   ar & boost::serialization::base_object<BCAlgorithm>(*this);
-   //}
-};
-#endif // ThinWallNoSlipBCAlgorithm_h__
+#ifndef ThinWallNoSlipBCAlgorithm_h__
+#define ThinWallNoSlipBCAlgorithm_h__
+
+#include "BCAlgorithm.h"
+
+class DistributionArray3D;
+
+class ThinWallNoSlipBCAlgorithm;
+typedef std::shared_ptr<ThinWallNoSlipBCAlgorithm> ThinWallNoSlipBCAlgorithmPtr;
+
+class ThinWallNoSlipBCAlgorithm : public BCAlgorithm
+{
+public:
+   ThinWallNoSlipBCAlgorithm();
+   virtual ~ThinWallNoSlipBCAlgorithm();
+   BCAlgorithmPtr clone();
+   void addDistributions(std::shared_ptr<DistributionArray3D> distributions);
+   void setPass(int pass);
+   void applyBC() override;
+
+protected:
+   std::shared_ptr<DistributionArray3D> distributionsTemp;
+private:
+   int pass;
+   LBMReal fTemp[D3Q27System::ENDF + 1];
+
+   //friend class boost::serialization::access;
+   //template<class Archive>
+   //void serialize(Archive & ar, const unsigned int version)
+   //{
+   //   ar & boost::serialization::base_object<BCAlgorithm>(*this);
+   //}
+};
+#endif // ThinWallNoSlipBCAlgorithm_h__
diff --git a/source/VirtualFluidsCore/BoundaryConditions/VelocityBCAlgorithm.cpp b/source/VirtualFluidsCore/BoundaryConditions/VelocityBCAlgorithm.cpp
index c573ae03b..bb1cc3131 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/VelocityBCAlgorithm.cpp
+++ b/source/VirtualFluidsCore/BoundaryConditions/VelocityBCAlgorithm.cpp
@@ -1,49 +1,50 @@
-#include "VelocityBCAlgorithm.h"
-#include <boost/pointer_cast.hpp>
-
-VelocityBCAlgorithm::VelocityBCAlgorithm()
-{
-   BCAlgorithm::type = BCAlgorithm::VelocityBCAlgorithm;
-   BCAlgorithm::preCollision = false;
-}
-//////////////////////////////////////////////////////////////////////////
-VelocityBCAlgorithm::~VelocityBCAlgorithm()
-{
-}
-//////////////////////////////////////////////////////////////////////////
-BCAlgorithmPtr VelocityBCAlgorithm::clone()
-{
-   BCAlgorithmPtr bc(new VelocityBCAlgorithm());
-   return bc;
-}
-//////////////////////////////////////////////////////////////////////////
-void VelocityBCAlgorithm::addDistributions(DistributionArray3DPtr distributions)
-{
-   this->distributions = distributions;
-}
-//////////////////////////////////////////////////////////////////////////
-void VelocityBCAlgorithm::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);
-
-   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);
-         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));
-         distributions->setDistributionForDirection(fReturn, x1+D3Q27System::DX1[invDir], x2+D3Q27System::DX2[invDir], x3+D3Q27System::DX3[invDir], fdir);
-      }
-   }
-
-}
-
+#include "VelocityBCAlgorithm.h"
+#include "DistributionArray3D.h"
+#include "BoundaryConditions.h"
+
+VelocityBCAlgorithm::VelocityBCAlgorithm()
+{
+   BCAlgorithm::type = BCAlgorithm::VelocityBCAlgorithm;
+   BCAlgorithm::preCollision = false;
+}
+//////////////////////////////////////////////////////////////////////////
+VelocityBCAlgorithm::~VelocityBCAlgorithm()
+{
+}
+//////////////////////////////////////////////////////////////////////////
+BCAlgorithmPtr VelocityBCAlgorithm::clone()
+{
+   BCAlgorithmPtr bc(new VelocityBCAlgorithm());
+   return bc;
+}
+//////////////////////////////////////////////////////////////////////////
+void VelocityBCAlgorithm::addDistributions(DistributionArray3DPtr distributions)
+{
+   this->distributions = distributions;
+}
+//////////////////////////////////////////////////////////////////////////
+void VelocityBCAlgorithm::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);
+
+   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);
+         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));
+         distributions->setDistributionForDirection(fReturn, x1+D3Q27System::DX1[invDir], x2+D3Q27System::DX2[invDir], x3+D3Q27System::DX3[invDir], fdir);
+      }
+   }
+
+}
+
diff --git a/source/VirtualFluidsCore/BoundaryConditions/VelocityBCAlgorithm.h b/source/VirtualFluidsCore/BoundaryConditions/VelocityBCAlgorithm.h
index ff5564acd..667e4ae3d 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/VelocityBCAlgorithm.h
+++ b/source/VirtualFluidsCore/BoundaryConditions/VelocityBCAlgorithm.h
@@ -1,29 +1,30 @@
-#ifndef VelocityBoundaryCondition_h__
-#define VelocityBoundaryCondition_h__
-
-#include "BCAlgorithm.h"
-
-class VelocityBCAlgorithm;
-typedef boost::shared_ptr<VelocityBCAlgorithm> VelocityBCAlgorithmPtr;
-
-class VelocityBCAlgorithm : public BCAlgorithm
-{
-public:
-   VelocityBCAlgorithm();
-   ~VelocityBCAlgorithm();
-   BCAlgorithmPtr clone();
-   void addDistributions(DistributionArray3DPtr distributions);
-   void applyBC();
-protected:
-   
-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 // VelocityBoundaryCondition_h__
-
+#ifndef VelocityBoundaryCondition_h__
+#define VelocityBoundaryCondition_h__
+
+#include "BCAlgorithm.h"
+
+class DistributionArray3D;
+
+class VelocityBCAlgorithm;
+typedef std::shared_ptr<VelocityBCAlgorithm> VelocityBCAlgorithmPtr;
+
+class VelocityBCAlgorithm : public BCAlgorithm
+{
+public:
+   VelocityBCAlgorithm();
+   ~VelocityBCAlgorithm();
+   BCAlgorithmPtr clone();
+   void addDistributions(std::shared_ptr<DistributionArray3D> distributions);
+
+   void applyBC() override;
+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 // VelocityBoundaryCondition_h__
+
diff --git a/source/VirtualFluidsCore/BoundaryConditions/VelocityWithDensityBCAlgorithm.cpp b/source/VirtualFluidsCore/BoundaryConditions/VelocityWithDensityBCAlgorithm.cpp
index dcc2a4fe1..ee945daf5 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/VelocityWithDensityBCAlgorithm.cpp
+++ b/source/VirtualFluidsCore/BoundaryConditions/VelocityWithDensityBCAlgorithm.cpp
@@ -1,82 +1,84 @@
-#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);
-         }
-      }
-
-   }
-}
+#include "VelocityWithDensityBCAlgorithm.h"
+#include "DistributionArray3D.h"
+#include "BCArray3D.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/VelocityWithDensityBCAlgorithm.h b/source/VirtualFluidsCore/BoundaryConditions/VelocityWithDensityBCAlgorithm.h
index 978a9b006..5aca0a97e 100644
--- a/source/VirtualFluidsCore/BoundaryConditions/VelocityWithDensityBCAlgorithm.h
+++ b/source/VirtualFluidsCore/BoundaryConditions/VelocityWithDensityBCAlgorithm.h
@@ -1,32 +1,33 @@
-//!  \file NonReflectingVelocityBCAlgorithm.h
-//!  \brief Class implements velocity bc for non reflecting pressure bc.
-//!  \author Konstantin Kutscher
-
-#ifndef VelocityWithDensityBCAlgorithm_h__
-#define VelocityWithDensityBCAlgorithm_h__
-
-#include "BCAlgorithm.h"
-
-class VelocityWithDensityBCAlgorithm;
-typedef boost::shared_ptr<VelocityWithDensityBCAlgorithm> VelocityWithDensityBCAlgorithmPtr;
-
-//!  \brief Class implements Dirichlet boundary condition for velocity. Set density in system. It is used together with non reflecting outflow.  
-
-class VelocityWithDensityBCAlgorithm : public BCAlgorithm
-{
-public:
-   VelocityWithDensityBCAlgorithm();
-   ~VelocityWithDensityBCAlgorithm();
-   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 // NonReflectingVelocityBCAlgorithm_h__
+//!  \file NonReflectingVelocityBCAlgorithm.h
+//!  \brief Class implements velocity bc for non reflecting pressure bc.
+//!  \author Konstantin Kutscher
+
+#ifndef VelocityWithDensityBCAlgorithm_h__
+#define VelocityWithDensityBCAlgorithm_h__
+
+#include "BCAlgorithm.h"
+
+class DistributionArray3D;
+
+class VelocityWithDensityBCAlgorithm;
+typedef std::shared_ptr<VelocityWithDensityBCAlgorithm> VelocityWithDensityBCAlgorithmPtr;
+
+//!  \brief Class implements Dirichlet boundary condition for velocity. Set density in system. It is used together with non reflecting outflow.  
+
+class VelocityWithDensityBCAlgorithm : public BCAlgorithm
+{
+public:
+   VelocityWithDensityBCAlgorithm();
+   ~VelocityWithDensityBCAlgorithm();
+   BCAlgorithmPtr clone();
+   void addDistributions(std::shared_ptr<DistributionArray3D> distributions);
+   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 // NonReflectingVelocityBCAlgorithm_h__
diff --git a/source/VirtualFluidsCore/CoProcessors/AdjustForcingCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/AdjustForcingCoProcessor.cpp
index 62059756d..611852a5d 100644
--- a/source/VirtualFluidsCore/CoProcessors/AdjustForcingCoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/AdjustForcingCoProcessor.cpp
@@ -1,20 +1,17 @@
 /*
 * D3Q27AdjustForcingCoProcessor.cpp
-*
-*
 *  Author: Konstantin Kutscher
 */
-
 #include "AdjustForcingCoProcessor.h"
 
-#include <SetForcingBlockVisitor.h>
-
-#include <iostream>
 #include <fstream>
 
-#include <boost/foreach.hpp>
+#include <SetForcingBlockVisitor.h>
+#include "IntegrateValuesHelper.h"
+#include "Communicator.h"
+#include "UbScheduler.h"
+#include "Grid3D.h"
 
-using namespace std;
 
 AdjustForcingCoProcessor::AdjustForcingCoProcessor(Grid3DPtr grid, UbSchedulerPtr s,
    const std::string& path,
@@ -57,7 +54,7 @@ AdjustForcingCoProcessor::AdjustForcingCoProcessor(Grid3DPtr grid, UbSchedulerPt
       if (!ostr)
       {
          ostr.clear();
-         string path = UbSystem::getPathFromString(fname);
+         std::string path = UbSystem::getPathFromString(fname);
          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);
       }
@@ -102,7 +99,7 @@ void AdjustForcingCoProcessor::collectData(double step)
       if (!ostr2)
       {
          ostr2.clear();
-         string path = UbSystem::getPathFromString(fNameCfg);
+         std::string path = UbSystem::getPathFromString(fNameCfg);
          if (path.size() > 0) { UbSystem::makeDirectory(path); ostr2.open(fNameCfg.c_str(), std::ios_base::out); }
          if (!ostr2) throw UbException(UB_EXARGS, "couldn't open file " + fNameCfg);
       }
@@ -140,7 +137,7 @@ void AdjustForcingCoProcessor::collectData(double step)
    SetForcingBlockVisitor forcingVisitor(fctForcingX1, fctForcingX2, fctForcingX3);
    grid->accept(forcingVisitor);
 
-   //BOOST_FOREACH(CalcNodes cn, cnodes)
+   //for(CalcNodes cn : cnodes)
    //{
    //   LBMKernel3DPtr kernel = cn.block->getKernel();
    //   if (kernel)
@@ -162,7 +159,7 @@ void AdjustForcingCoProcessor::collectData(double step)
       if (!ostr)
       {
          ostr.clear();
-         string path = UbSystem::getPathFromString(fname);
+         std::string path = UbSystem::getPathFromString(fname);
          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);
       }
diff --git a/source/VirtualFluidsCore/CoProcessors/AdjustForcingCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/AdjustForcingCoProcessor.h
index 5ddbe6fe5..aed89ac47 100644
--- a/source/VirtualFluidsCore/CoProcessors/AdjustForcingCoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/AdjustForcingCoProcessor.h
@@ -1,14 +1,19 @@
 #ifndef D3Q27ADJUSTFORCINGCoProcessor_H
 #define D3Q27ADJUSTFORCINGCoProcessor_H
 
+#include <memory>
+#include <string>
+
 #include "CoProcessor.h"
-#include "IntegrateValuesHelper.h"
-#include "LBMUnitConverter.h"
-#include "Communicator.h"
 
-#include <boost/shared_ptr.hpp>
+
+class Communicator;
+class UbScheduler;
+class Grid3D;
+class IntegrateValuesHelper;
+
 class AdjustForcingCoProcessor;
-typedef boost::shared_ptr<AdjustForcingCoProcessor> AdjustForcingCoProcessorPtr;
+typedef std::shared_ptr<AdjustForcingCoProcessor> AdjustForcingCoProcessorPtr;
 
 //! \brief   Computes forcing such that a given velocity (vx1Targed) is reached inside an averaging domain (h1). 
 //! \details Algorithm based on PID controller (proportional–integral–derivative controller). The parameters of PID controller estimation based on Ziegler–Nichols method. 
@@ -17,19 +22,19 @@ typedef boost::shared_ptr<AdjustForcingCoProcessor> AdjustForcingCoProcessorPtr;
 
 class AdjustForcingCoProcessor: public CoProcessor {
 public:
-	AdjustForcingCoProcessor(Grid3DPtr grid, UbSchedulerPtr s,
+	AdjustForcingCoProcessor(std::shared_ptr<Grid3D> grid, std::shared_ptr<UbScheduler> s,
                                    const std::string& path,
-                                   IntegrateValuesHelperPtr integrateValues,
-                                   double vTarged, CommunicatorPtr comm);
+                                   std::shared_ptr<IntegrateValuesHelper> integrateValues,
+                                   double vTarged, std::shared_ptr<Communicator> comm);
 	virtual ~AdjustForcingCoProcessor();
 	 //!< calls collect PostprocessData
-   void process(double step);
+   void process(double step) override;
 protected:
    //!< object that can compute spacial average values in 3D-subdomain.
-   IntegrateValuesHelperPtr integrateValues;
+    std::shared_ptr<IntegrateValuesHelper> integrateValues;
    //!< compares velocity in integrateValues with target velocity and adjusts forcing accordingly.
 	void collectData(double step);  
-   CommunicatorPtr comm;
+    std::shared_ptr<Communicator> comm;
 private:
    double vx1Targed; //!< target velocity.
    double forcing; //!< forcing at previous update step. 
diff --git a/source/VirtualFluidsCore/CoProcessors/AverageValuesCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/AverageValuesCoProcessor.cpp
index bcd7606e5..1658b7f52 100644
--- a/source/VirtualFluidsCore/CoProcessors/AverageValuesCoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/AverageValuesCoProcessor.cpp
@@ -1,569 +1,573 @@
-#include "AverageValuesCoProcessor.h"
-#include "LBMKernel.h"
-#include "BCProcessor.h"
-#include <vector>
-#include <sstream>
-#include <string>
-#include <iostream>
-#include <boost/foreach.hpp>
-#include "basics/writer/WbWriterVtkXmlASCII.h"
-#include "basics/utilities/UbMath.h"
-
-using namespace std;
-
-AverageValuesCoProcessor::AverageValuesCoProcessor()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-AverageValuesCoProcessor::AverageValuesCoProcessor(Grid3DPtr grid, const std::string& path,	WbWriter* const writer, 
-   UbSchedulerPtr s, UbSchedulerPtr Avs, UbSchedulerPtr rsMeans, UbSchedulerPtr rsRMS, bool restart)
-	                                                   : CoProcessor(grid, s),
-	                                                   averageScheduler(Avs),
-	                                                   resetSchedulerMeans(rsMeans),
-	                                                   resetSchedulerRMS(rsRMS),
-	                                                   path(path),
-	                                                   writer(writer)
-{
-   resetStepMeans = (int)rsMeans->getMinBegin();
-   resetStepRMS = (int)rsRMS->getMinBegin();
-   averageInterval = (double)Avs->getMinStep();
-
-   gridRank  = grid->getRank();
-   minInitLevel = this->grid->getCoarsestInitializedLevel();
-   maxInitLevel = this->grid->getFinestInitializedLevel();
-
-   blockVector.resize(maxInitLevel+1);
-
-   for(int level = minInitLevel; level<=maxInitLevel;level++)
-   {
-      grid->getBlocks(level, gridRank, true, blockVector[level]);
-      
-      if (blockVector[level].size() > 0)
-         compressible = blockVector[level][0]->getKernel()->getCompressible();
-
-      if (!restart)
-      {
-         BOOST_FOREACH(Block3DPtr block, blockVector[level])
-         {
-            UbTupleInt3 nx = grid->getBlockNX();
-            AverageValuesArray3DPtr averageValues = AverageValuesArray3DPtr(new AverageValuesArray3D(11, val<1>(nx)+1, val<2>(nx)+1, val<3>(nx)+1, 0.0));
-            block->getKernel()->getDataSet()->setAverageValues(averageValues);
-         }
-      }
-   }
-
-   // for musis special use
-	//initPlotDataZ(0.0);
-	//restartStep = 0.0;
-}
-//////////////////////////////////////////////////////////////////////////
-void AverageValuesCoProcessor::process(double step)
-{
-	//resetRMS(step);
-	if(resetSchedulerRMS->isDue(step) )
-		resetDataRMS(step);
-
-	//reset(step);
-	if(resetSchedulerMeans->isDue(step) )
-		resetDataMeans(step);
-
-	if(averageScheduler->isDue(step) ){
-		calculateAverageValues(step);
-			// for musis special use
-			//collectPlotDataZ(step);
-	}
-	if(scheduler->isDue(step) ){
-			collectData(step);
-
-		}
-
-		UBLOG(logDEBUG3, "AverageValuesCoProcessor::update:" << step);
-}
-
-void AverageValuesCoProcessor::resetDataRMS(double step)
-{
-	resetStepRMS=(int)step;
-
-	for(int level = minInitLevel; level<=maxInitLevel;level++)
-	{
-		BOOST_FOREACH(Block3DPtr block, blockVector[level])
-		{
-			if (block)
-			{
-				LBMKernelPtr kernel = block->getKernel();
-				BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
-				DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions(); 
-				AverageValuesArray3DPtr av = kernel->getDataSet()->getAverageValues();
-
-				int minX1 = 0;
-				int minX2 = 0;
-				int minX3 = 0;
-
-				int maxX1 = int(distributions->getNX1());
-				int maxX2 = int(distributions->getNX2());
-				int maxX3 = int(distributions->getNX3());
-
-				for(int ix3=minX3; ix3<maxX3-1; ix3++)
-				{
-					for(int ix2=minX2; ix2<maxX2-1; ix2++)
-					{
-						for(int ix1=minX1; ix1<maxX1-1; ix1++)
-						{
-							if(!bcArray->isUndefined(ix1,ix2,ix3) && !bcArray->isSolid(ix1,ix2,ix3))
-							{
-								//////////////////////////////////////////////////////////////////////////
-								//compute average values
-								//////////////////////////////////////////////////////////////////////////
-								(*av)(AvVxx,ix1,ix2,ix3) = 0.0;
-								(*av)(AvVyy,ix1,ix2,ix3) = 0.0;
-								(*av)(AvVzz,ix1,ix2,ix3) = 0.0;
-                        (*av)(AvVxy,ix1,ix2,ix3) = 0.0;
-                        (*av)(AvVxz,ix1,ix2,ix3) = 0.0;
-                        (*av)(AvVyz,ix1,ix2,ix3) = 0.0;
-                        (*av)(AvPrms,ix1,ix2,ix3) = 0.0;
-								//////////////////////////////////////////////////////////////////////////
-							}
-						}
-					}
-				}
-			}
-		}
-	}
-}
-//////////////////////////////////////////////////////////////////////////
-void AverageValuesCoProcessor::resetDataMeans(double step)
-{
-	resetStepMeans=(int)step;
-
-	for(int level = minInitLevel; level<=maxInitLevel;level++)
-	{
-		BOOST_FOREACH(Block3DPtr block, blockVector[level])
-		{
-			if (block)
-			{
-				LBMKernelPtr kernel = block->getKernel();
-				BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
-				DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions(); 
-				AverageValuesArray3DPtr av = kernel->getDataSet()->getAverageValues();
-
-				int minX1 = 0;
-				int minX2 = 0;
-				int minX3 = 0;
-
-				int maxX1 = int(distributions->getNX1());
-				int maxX2 = int(distributions->getNX2());
-				int maxX3 = int(distributions->getNX3());
-
-				for(int ix3=minX3; ix3<maxX3-1; ix3++)
-				{
-					for(int ix2=minX2; ix2<maxX2-1; ix2++)
-					{
-						for(int ix1=minX1; ix1<maxX1-1; ix1++)
-						{
-							if(!bcArray->isUndefined(ix1,ix2,ix3) && !bcArray->isSolid(ix1,ix2,ix3))
-							{
-								//////////////////////////////////////////////////////////////////////////
-								//compute average values
-								//////////////////////////////////////////////////////////////////////////
-								(*av)(AvVx,ix1,ix2,ix3) = 0.0;
-								(*av)(AvVy,ix1,ix2,ix3) = 0.0;
-								(*av)(AvVz,ix1,ix2,ix3) = 0.0;
-                        (*av)(AvP,ix1,ix2,ix3) = 0.0;
-								//////////////////////////////////////////////////////////////////////////
-							}
-						}
-					}
-				}
-			}
-		}
-	}
-}
-//////////////////////////////////////////////////////////////////////////
-void AverageValuesCoProcessor::collectData(double step)
-{
-	int istep = int(step);
-
-	for(int level = minInitLevel; level<=maxInitLevel;level++)
-	{
-		BOOST_FOREACH(Block3DPtr block, blockVector[level])
-		{
-			if (block)
-			{
-				addData(block);
-			}
-		}
-	}
-
-   string pfilePath, partPath, subfolder, cfilePath;
-   subfolder = "av"+UbSystem::toString(istep);
-   pfilePath =  path+"/av/"+subfolder;
-   cfilePath =  path+"/av/av_collection";
-   partPath = pfilePath+"/av"+UbSystem::toString(gridRank)+ "_" + UbSystem::toString(istep);
-
-   string partName = writer->writeOctsWithNodeData(partPath,nodes,cells,datanames,data);
-   size_t found=partName.find_last_of("/");
-   string piece = partName.substr(found+1);
-   piece = subfolder + "/" + piece;
-
-   vector<string> cellDataNames;
-   CommunicatorPtr comm = Communicator::getInstance();
-   vector<string> pieces = comm->gather(piece);
-   if (comm->getProcessID() == comm->getRoot())
-   {
-      string pname = WbWriterVtkXmlASCII::getInstance()->writeParallelFile(pfilePath,pieces,datanames,cellDataNames);
-      found=pname.find_last_of("/");
-      piece = pname.substr(found+1);
-
-      vector<string> filenames;
-      filenames.push_back(piece);
-      if (step == CoProcessor::scheduler->getMinBegin())
-      {
-         WbWriterVtkXmlASCII::getInstance()->writeCollection(cfilePath,filenames,istep,false);
-      } 
-      else
-      {
-         WbWriterVtkXmlASCII::getInstance()->addFilesToCollection(cfilePath,filenames,istep,false);
-      }
-      UBLOG(logINFO,"AverageValuesCoProcessor step: " << istep);
-   }
-
-	clearData();
-}
-//////////////////////////////////////////////////////////////////////////
-void AverageValuesCoProcessor::clearData()
-{
-	nodes.clear();
-	cells.clear();
-	datanames.clear();
-	data.clear();
-}
-//////////////////////////////////////////////////////////////////////////
-void AverageValuesCoProcessor::addData(const Block3DPtr block)
-{
-	UbTupleDouble3 org          = grid->getBlockWorldCoordinates(block);
-	UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
-	UbTupleDouble3 nodeOffset   = grid->getNodeOffset(block);
-	double         dx           = grid->getDeltaX(block);
-
-	//Diese Daten werden geschrieben:
-	datanames.resize(0);
-	datanames.push_back("AvVx");
-   datanames.push_back("AvVy");
-   datanames.push_back("AvVz");
-	datanames.push_back("AvVxx");
-	datanames.push_back("AvVyy");
-	datanames.push_back("AvVzz");
-   datanames.push_back("AvVxy");
-   datanames.push_back("AvVxz");
-   datanames.push_back("AvVyz");
-   datanames.push_back("AvP");
-   datanames.push_back("AvPrms");
-
-
-	data.resize(datanames.size());
-
-	LBMKernelPtr kernel = block->getKernel();
-	BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
-	DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions(); 
-	AverageValuesArray3DPtr av = kernel->getDataSet()->getAverageValues();
-	//int ghostLayerWidth = kernel->getGhostLayerWidth();
-
-	//knotennummerierung faengt immer bei 0 an!
-	int SWB,SEB,NEB,NWB,SWT,SET,NET,NWT;
-
-	int minX1 = 0;
-	int minX2 = 0;
-	int minX3 = 0;
-
-	int maxX1 = int(distributions->getNX1());
-	int maxX2 = int(distributions->getNX2());
-	int maxX3 = int(distributions->getNX3());
-
-	//nummern vergeben und node vector erstellen + daten sammeln
-	CbArray3D<int> nodeNumbers((int)maxX1, (int)maxX2, (int)maxX3,-1);
-
-	maxX1 -= 2;
-	maxX2 -= 2;
-	maxX3 -= 2;
-
-	//D3Q27BoundaryConditionPtr bcPtr;
-
-	int nr = (int)nodes.size();
-
-	for(int ix3=minX3; ix3<=maxX3; ix3++)
-	{
-		for(int ix2=minX2; ix2<=maxX2; ix2++)
-		{
-			for(int ix1=minX1; ix1<=maxX1; ix1++)
-			{
-				if(!bcArray->isUndefined(ix1,ix2,ix3) && !bcArray->isSolid(ix1,ix2,ix3))
-				{
-					int index = 0;
-					nodeNumbers(ix1,ix2,ix3) = nr++;
-					nodes.push_back( makeUbTuple(float(val<1>(org) - val<1>(nodeOffset) + ix1*dx),
-						float(val<2>(org) - val<2>(nodeOffset) + ix2*dx),
-						float(val<3>(org) - val<3>(nodeOffset) + ix3*dx)) );
-
-					LBMReal vx=(*av)(AvVx,ix1,ix2,ix3);
-					LBMReal vy=(*av)(AvVy,ix1,ix2,ix3);
-					LBMReal vz=(*av)(AvVz,ix1,ix2,ix3);
-               
-               LBMReal vxx=(*av)(AvVxx,ix1,ix2,ix3);
-               LBMReal vyy=(*av)(AvVyy,ix1,ix2,ix3);
-               LBMReal vzz=(*av)(AvVzz,ix1,ix2,ix3);
-               
-               LBMReal vxy=(*av)(AvVxy,ix1,ix2,ix3);
-               LBMReal vxz=(*av)(AvVxz,ix1,ix2,ix3);
-               LBMReal vyz=(*av)(AvVyz,ix1,ix2,ix3);
-
-               LBMReal vp=(*av)(AvP,ix1,ix2,ix3);
-               LBMReal vprms=(*av)(AvPrms,ix1,ix2,ix3);
- 
-					
-					data[index++].push_back(vx);
-               data[index++].push_back(vy);
-               data[index++].push_back(vz);
-
-					data[index++].push_back(vxx);
-					data[index++].push_back(vyy);
-					data[index++].push_back(vzz);
-
-               data[index++].push_back(vxy);
-               data[index++].push_back(vxz);
-               data[index++].push_back(vyz);
-
-               data[index++].push_back(vp);
-               data[index++].push_back(vprms);
-				}
-			}
-		}
-	}
-
-	maxX1 -= 1;
-	maxX2 -= 1;
-	maxX3 -= 1;
-
-	//cell vector erstellen
-	for(int ix3=minX3; ix3<=maxX3; ix3++)
-	{
-		for(int ix2=minX2; ix2<=maxX2; ix2++)
-		{
-			for(int ix1=minX1; ix1<=maxX1; ix1++)
-			{
-				if(   (SWB=nodeNumbers( ix1  , ix2,   ix3   )) >= 0
-					&& (SEB=nodeNumbers( ix1+1, ix2,   ix3   )) >= 0
-					&& (NEB=nodeNumbers( ix1+1, ix2+1, ix3   )) >= 0
-					&& (NWB=nodeNumbers( ix1  , ix2+1, ix3   )) >= 0 
-					&& (SWT=nodeNumbers( ix1  , ix2,   ix3+1 )) >= 0
-					&& (SET=nodeNumbers( ix1+1, ix2,   ix3+1 )) >= 0
-					&& (NET=nodeNumbers( ix1+1, ix2+1, ix3+1 )) >= 0
-					&& (NWT=nodeNumbers( ix1  , ix2+1, ix3+1 )) >= 0                )
-				{
-					cells.push_back( makeUbTuple(SWB,SEB,NEB,NWB,SWT,SET,NET,NWT) );
-				}
-			}
-		}
-	}
-}
-//////////////////////////////////////////////////////////////////////////
-void AverageValuesCoProcessor::calculateAverageValues(double timeStep)
-{
-	using namespace D3Q27System;
-
-   //Funktionszeiger
-   calcMacros = NULL;
-   if (compressible)
-   {
-      calcMacros = &calcCompMacroscopicValues;
-   }
-   else
-   {
-      calcMacros = &calcIncompMacroscopicValues;
-   }
-
-	LBMReal f[27];
-
-	for(int level = minInitLevel; level<=maxInitLevel;level++)
-	{
-		BOOST_FOREACH(Block3DPtr block, blockVector[level])
-		{
-			if (block)
-			{
-				LBMKernelPtr kernel = block->getKernel();
-				BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
-				DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions(); 
-				AverageValuesArray3DPtr av = kernel->getDataSet()->getAverageValues();
-
-				int minX1 = 0;
-				int minX2 = 0;
-				int minX3 = 0;
-
-				int maxX1 = int(distributions->getNX1());
-				int maxX2 = int(distributions->getNX2());
-				int maxX3 = int(distributions->getNX3());
-
-				maxX1 -= 2;
-				maxX2 -= 2;
-				maxX3 -= 2;
-
-				for(int ix3=minX3; ix3<=maxX3; ix3++)
-				{
-					for(int ix2=minX2; ix2<=maxX2; ix2++)
-					{
-						for(int ix1=minX1; ix1<=maxX1; ix1++)
-						{
-							if(!bcArray->isUndefined(ix1,ix2,ix3) && !bcArray->isSolid(ix1,ix2,ix3))
-							{
-								//////////////////////////////////////////////////////////////////////////
-								//read distribution
-								////////////////////////////////////////////////////////////////////////////
-								distributions->getDistribution(f, ix1, ix2, ix3);
-								//////////////////////////////////////////////////////////////////////////
-								//compute velocity
-								//////////////////////////////////////////////////////////////////////////
-                        LBMReal vx,vy,vz,rho;
-                        calcMacros(f,rho,vx,vy,vz);
-                        double press = D3Q27System::calcPress(f,rho,vx,vy,vz);
-
-								//////////////////////////////////////////////////////////////////////////
-								//compute average values
-								//////////////////////////////////////////////////////////////////////////
-
-								LBMReal timeStepAfterResetRMS=(double)(timeStep-resetStepRMS)/((double)averageInterval);
-								LBMReal timeStepAfterResetMeans=(double)(timeStep-resetStepMeans)/((double)averageInterval);
-
-                        //mean velocity
-                        (*av)(AvVx,ix1,ix2,ix3) = ((*av)(AvVx,ix1,ix2,ix3)*timeStepAfterResetMeans + vx)/(timeStepAfterResetMeans+1.0);
-                        (*av)(AvVy,ix1,ix2,ix3) = ((*av)(AvVy,ix1,ix2,ix3)*timeStepAfterResetMeans + vy)/(timeStepAfterResetMeans+1.0);
-                        (*av)(AvVz,ix1,ix2,ix3) = ((*av)(AvVz,ix1,ix2,ix3)*timeStepAfterResetMeans + vz)/(timeStepAfterResetMeans+1.0);
-
-                        //rms
-								(*av)(AvVxx,ix1,ix2,ix3) = ((vx-(*av)(AvVx,ix1,ix2,ix3))*(vx-(*av)(AvVx,ix1,ix2,ix3)) +
-									(*av)(AvVxx,ix1,ix2,ix3)*timeStepAfterResetRMS)/(timeStepAfterResetRMS+1.0);
-								(*av)(AvVyy,ix1,ix2,ix3) = ((vy-(*av)(AvVy,ix1,ix2,ix3))*(vy-(*av)(AvVy,ix1,ix2,ix3)) +
-									(*av)(AvVyy,ix1,ix2,ix3)*timeStepAfterResetRMS)/(timeStepAfterResetRMS+1.0);
-								(*av)(AvVzz,ix1,ix2,ix3) = ((vz-(*av)(AvVz,ix1,ix2,ix3))*(vz-(*av)(AvVz,ix1,ix2,ix3)) +
-									(*av)(AvVzz,ix1,ix2,ix3)*timeStepAfterResetRMS)/(timeStepAfterResetRMS+1.0);
-
-                        //cross-correlations
-                        (*av)(AvVxy,ix1,ix2,ix3) = ((vx-(*av)(AvVx,ix1,ix2,ix3))*(vy-(*av)(AvVy,ix1,ix2,ix3)) +
-                           (*av)(AvVxy,ix1,ix2,ix3)*timeStepAfterResetRMS)/(timeStepAfterResetRMS+1.0);
-                        (*av)(AvVxz,ix1,ix2,ix3) = ((vx-(*av)(AvVx,ix1,ix2,ix3))*(vz-(*av)(AvVz,ix1,ix2,ix3)) +
-                           (*av)(AvVxz,ix1,ix2,ix3)*timeStepAfterResetRMS)/(timeStepAfterResetRMS+1.0);
-                        (*av)(AvVyz,ix1,ix2,ix3) = ((vy-(*av)(AvVy,ix1,ix2,ix3))*(vz-(*av)(AvVz,ix1,ix2,ix3)) +
-                           (*av)(AvVyz,ix1,ix2,ix3)*timeStepAfterResetRMS)/(timeStepAfterResetRMS+1.0);
-
-                        //mean and rms press
-                        (*av)(AvP,ix1,ix2,ix3) = ((*av)(AvP,ix1,ix2,ix3)*timeStepAfterResetMeans + press)/(timeStepAfterResetMeans+1.0);
-                        (*av)(AvPrms,ix1,ix2,ix3) = ((press-(*av)(AvP,ix1,ix2,ix3))*(press-(*av)(AvP,ix1,ix2,ix3)) +
-                           (*av)(AvPrms,ix1,ix2,ix3)*timeStepAfterResetRMS)/(timeStepAfterResetRMS+1.0);
-
-								//////////////////////////////////////////////////////////////////////////
-							}
-						}
-					}
-				}
-			}
-		}
-	}
-}
-////////////////////////////////////////////////////////////////////////////
-//void AverageValuesCoProcessor::initPlotData(double step)
-//{
-//   CommunicatorPtr comm = Communicator::getInstance();
-//	if (comm->getProcessID() == comm->getRoot())
-//	{
-//		std::ofstream ostr;
-//		string fname = path + "_PlotData_" + UbSystem::toString(step) + ".txt"; 
-//		ostr.open(fname.c_str(), std::ios_base::out);
-//		if(!ostr)
-//		{ 
-//			ostr.clear();
-//			string path = UbSystem::getPathFromString(fname);
-//			if(path.size()>0){ UbSystem::makeDirectory(path); ostr.open(fname.c_str(), std::ios_base::out);}
-//			if(!ostr) throw UbException(UB_EXARGS,"couldn't open file "+fname);
-//		}
-//		ostr << "Time"<< "\t" <<"Ref.Time"<<"\t"<< "Z_Coor"<< "\t" << "Pore fraction" << "\t";
-//		ostr << "Vx"  << "\t" << "Vy" << "\t" << "Vz" << "\t";
-//		ostr << "TSx" << "\t" << "TSy"<< "\t" << "TSz"<< "TSxz";
-//		ostr << endl;
-//		ostr.close();
-//	}
-//}
-//////////////////////////////////////////////////////////////////////////////
-//void AverageValuesCoProcessor::collectPlotData(double step)
-//{
-//
-//	double hminX1 = 0.9;
-//	double hminX2 = 0.0;
-//	double hmaxX1 = 0.95;
-//	double hmaxX2 = 0.01; //systemabmessungen world units
-//
-//	// 3 level platte standard:
-//	double hX3_level[] = {0.305, 0.309,0.3365,0.35};
-//	//0.004, 0,0365,0.045
-//	//musis: 3 level refinement
-//	//double hX3_level[] = {0.42, 0.28, 0.105, 0.0}; //refinement coords
-//	                    //bsislevel von 0.42-0.28,... (level 0 bis 2 , 3 insgesamt)
-//	//musis: 4 level refinement
-//	//double hX3_level[] = {0.42, 0.3, 0.195, 0.078, 0.0};
-//	//musis: 5 level refinement
-//	//double hX3_level[] = {0.396, 0.28, 0.18, 0.08, 0.006, 0.0};
-//
-//	ostringstream Str;
-//	Str << step;
-//	string step2string(Str.str());
-//	string fname = path + "_PlotZ_" + step2string + ".txt"; 
-//
-//
-//	for(int level = minInitLevel; level<=maxInitLevel;level++)
-//	{
-//		double dx = grid->getDeltaX(level);
-//
-//		for (double hi =hX3_level[level]; hi >= hX3_level[level+1]; hi=hi-dx ){
-//			D3Q27IntegrateValuesHelper h1(grid, comm, 
-//				hminX1, hminX2, hi, 
-//				hmaxX1, hmaxX2, hi-dx);
-//
-//			h1.calculateAV();
-//			double nn1 = h1.getNumberOfNodes();
-//			double ns1 = h1.getNumberOfSolids();
-//			if (nn1 > 0.0){
-//				// get data and write into txt files
-//				if (comm->getProcessID() == comm->getRoot())
-//				{
-//					int istep = static_cast<int>(step);
-//					std::ofstream ostr;
-//
-//					double AvVx1 = h1.getAvVx1()/nn1;
-//					double AvVx2 = h1.getAvVx2()/nn1;
-//					double AvVx3 = h1.getAvVx3()/nn1;
-//
-//					double AvTSx1 = h1.getTSx1()/nn1;
-//					double AvTSx2 = h1.getTSx2()/nn1;
-//					double AvTSx3 = h1.getTSx3()/nn1;
-//
-//					double AvTSx1x3 = h1.getTSx1x3()/nn1;
-//
-//					ostr.open(fname.c_str(), std::ios_base::out | std::ios_base::app);
-//					if(!ostr)
-//					{ 
-//						ostr.clear();
-//						string path = UbSystem::getPathFromString(fname);
-//						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 << istep << "\t" << resetStep << "\t" << hi+0.5*dx << "\t" << nn1/(nn1+ns1)*100.0 << "%\t";
-//					ostr << AvVx1 << "\t" << AvVx2 << "\t" << AvVx3 << "\t";
-//					ostr << AvTSx1<< "\t" << AvTSx2<< "\t" << AvTSx3<< "\t" << AvTSx1x3;
-//					ostr << endl;
-//					ostr.close();
-//
-//				}
-//			}
-//		}
-//
-//	}
-//}
-
+#include "AverageValuesCoProcessor.h"
+
+#include "LBMKernel.h"
+#include "BCProcessor.h"
+
+#include "basics/writer/WbWriterVtkXmlASCII.h"
+
+#include "DataSet3D.h"
+#include "WbWriter.h"
+#include "Grid3D.h"
+#include "Block3D.h"
+#include "UbScheduler.h"
+#include "Communicator.h"
+#include "BCArray3D.h"
+
+using namespace std;
+
+AverageValuesCoProcessor::AverageValuesCoProcessor()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+AverageValuesCoProcessor::AverageValuesCoProcessor(Grid3DPtr grid, const std::string& path,	WbWriter* const writer, 
+   UbSchedulerPtr s, UbSchedulerPtr Avs, UbSchedulerPtr rsMeans, UbSchedulerPtr rsRMS, bool restart)
+	                                                   : CoProcessor(grid, s),
+	                                                   averageScheduler(Avs),
+	                                                   resetSchedulerMeans(rsMeans),
+	                                                   resetSchedulerRMS(rsRMS),
+	                                                   path(path),
+	                                                   writer(writer)
+{
+   resetStepMeans = (int)rsMeans->getMinBegin();
+   resetStepRMS = (int)rsRMS->getMinBegin();
+   averageInterval = (double)Avs->getMinStep();
+
+   gridRank  = grid->getRank();
+   minInitLevel = this->grid->getCoarsestInitializedLevel();
+   maxInitLevel = this->grid->getFinestInitializedLevel();
+
+   blockVector.resize(maxInitLevel+1);
+
+   for(int level = minInitLevel; level<=maxInitLevel;level++)
+   {
+      grid->getBlocks(level, gridRank, true, blockVector[level]);
+      
+      if (blockVector[level].size() > 0)
+         compressible = blockVector[level][0]->getKernel()->getCompressible();
+
+      if (!restart)
+      {
+         for(Block3DPtr block : blockVector[level])
+         {
+            UbTupleInt3 nx = grid->getBlockNX();
+            AverageValuesArray3DPtr averageValues = AverageValuesArray3DPtr(new AverageValuesArray3D(11, val<1>(nx)+1, val<2>(nx)+1, val<3>(nx)+1, 0.0));
+            block->getKernel()->getDataSet()->setAverageValues(averageValues);
+         }
+      }
+   }
+
+   // for musis special use
+	//initPlotDataZ(0.0);
+	//restartStep = 0.0;
+}
+//////////////////////////////////////////////////////////////////////////
+void AverageValuesCoProcessor::process(double step)
+{
+	//resetRMS(step);
+	if(resetSchedulerRMS->isDue(step) )
+		resetDataRMS(step);
+
+	//reset(step);
+	if(resetSchedulerMeans->isDue(step) )
+		resetDataMeans(step);
+
+	if(averageScheduler->isDue(step) ){
+		calculateAverageValues(step);
+			// for musis special use
+			//collectPlotDataZ(step);
+	}
+	if(scheduler->isDue(step) ){
+			collectData(step);
+
+		}
+
+		UBLOG(logDEBUG3, "AverageValuesCoProcessor::update:" << step);
+}
+
+void AverageValuesCoProcessor::resetDataRMS(double step)
+{
+	resetStepRMS=(int)step;
+
+	for(int level = minInitLevel; level<=maxInitLevel;level++)
+	{
+		for(Block3DPtr block : blockVector[level])
+		{
+			if (block)
+			{
+				ILBMKernelPtr kernel = block->getKernel();
+				BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
+				DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions(); 
+				AverageValuesArray3DPtr av = kernel->getDataSet()->getAverageValues();
+
+				int minX1 = 0;
+				int minX2 = 0;
+				int minX3 = 0;
+
+				int maxX1 = int(distributions->getNX1());
+				int maxX2 = int(distributions->getNX2());
+				int maxX3 = int(distributions->getNX3());
+
+				for(int ix3=minX3; ix3<maxX3-1; ix3++)
+				{
+					for(int ix2=minX2; ix2<maxX2-1; ix2++)
+					{
+						for(int ix1=minX1; ix1<maxX1-1; ix1++)
+						{
+							if(!bcArray->isUndefined(ix1,ix2,ix3) && !bcArray->isSolid(ix1,ix2,ix3))
+							{
+								//////////////////////////////////////////////////////////////////////////
+								//compute average values
+								//////////////////////////////////////////////////////////////////////////
+								(*av)(AvVxx,ix1,ix2,ix3) = 0.0;
+								(*av)(AvVyy,ix1,ix2,ix3) = 0.0;
+								(*av)(AvVzz,ix1,ix2,ix3) = 0.0;
+                        (*av)(AvVxy,ix1,ix2,ix3) = 0.0;
+                        (*av)(AvVxz,ix1,ix2,ix3) = 0.0;
+                        (*av)(AvVyz,ix1,ix2,ix3) = 0.0;
+                        (*av)(AvPrms,ix1,ix2,ix3) = 0.0;
+								//////////////////////////////////////////////////////////////////////////
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+}
+//////////////////////////////////////////////////////////////////////////
+void AverageValuesCoProcessor::resetDataMeans(double step)
+{
+	resetStepMeans=(int)step;
+
+	for(int level = minInitLevel; level<=maxInitLevel;level++)
+	{
+		for(Block3DPtr block : blockVector[level])
+		{
+			if (block)
+			{
+				ILBMKernelPtr kernel = block->getKernel();
+				BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
+				DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions(); 
+				AverageValuesArray3DPtr av = kernel->getDataSet()->getAverageValues();
+
+				int minX1 = 0;
+				int minX2 = 0;
+				int minX3 = 0;
+
+				int maxX1 = int(distributions->getNX1());
+				int maxX2 = int(distributions->getNX2());
+				int maxX3 = int(distributions->getNX3());
+
+				for(int ix3=minX3; ix3<maxX3-1; ix3++)
+				{
+					for(int ix2=minX2; ix2<maxX2-1; ix2++)
+					{
+						for(int ix1=minX1; ix1<maxX1-1; ix1++)
+						{
+							if(!bcArray->isUndefined(ix1,ix2,ix3) && !bcArray->isSolid(ix1,ix2,ix3))
+							{
+								//////////////////////////////////////////////////////////////////////////
+								//compute average values
+								//////////////////////////////////////////////////////////////////////////
+								(*av)(AvVx,ix1,ix2,ix3) = 0.0;
+								(*av)(AvVy,ix1,ix2,ix3) = 0.0;
+								(*av)(AvVz,ix1,ix2,ix3) = 0.0;
+                        (*av)(AvP,ix1,ix2,ix3) = 0.0;
+								//////////////////////////////////////////////////////////////////////////
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+}
+//////////////////////////////////////////////////////////////////////////
+void AverageValuesCoProcessor::collectData(double step)
+{
+	int istep = int(step);
+
+	for(int level = minInitLevel; level<=maxInitLevel;level++)
+	{
+		for(Block3DPtr block : blockVector[level])
+		{
+			if (block)
+			{
+				addData(block);
+			}
+		}
+	}
+
+   string pfilePath, partPath, subfolder, cfilePath;
+   subfolder = "av"+UbSystem::toString(istep);
+   pfilePath =  path+"/av/"+subfolder;
+   cfilePath =  path+"/av/av_collection";
+   partPath = pfilePath+"/av"+UbSystem::toString(gridRank)+ "_" + UbSystem::toString(istep);
+
+   string partName = writer->writeOctsWithNodeData(partPath,nodes,cells,datanames,data);
+   size_t found=partName.find_last_of("/");
+   string piece = partName.substr(found+1);
+   piece = subfolder + "/" + piece;
+
+   vector<string> cellDataNames;
+   CommunicatorPtr comm = Communicator::getInstance();
+   vector<string> pieces = comm->gather(piece);
+   if (comm->getProcessID() == comm->getRoot())
+   {
+      string pname = WbWriterVtkXmlASCII::getInstance()->writeParallelFile(pfilePath,pieces,datanames,cellDataNames);
+      found=pname.find_last_of("/");
+      piece = pname.substr(found+1);
+
+      vector<string> filenames;
+      filenames.push_back(piece);
+      if (step == CoProcessor::scheduler->getMinBegin())
+      {
+         WbWriterVtkXmlASCII::getInstance()->writeCollection(cfilePath,filenames,istep,false);
+      } 
+      else
+      {
+         WbWriterVtkXmlASCII::getInstance()->addFilesToCollection(cfilePath,filenames,istep,false);
+      }
+      UBLOG(logINFO,"AverageValuesCoProcessor step: " << istep);
+   }
+
+	clearData();
+}
+//////////////////////////////////////////////////////////////////////////
+void AverageValuesCoProcessor::clearData()
+{
+	nodes.clear();
+	cells.clear();
+	datanames.clear();
+	data.clear();
+}
+//////////////////////////////////////////////////////////////////////////
+void AverageValuesCoProcessor::addData(const Block3DPtr block)
+{
+	UbTupleDouble3 org          = grid->getBlockWorldCoordinates(block);
+	UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
+	UbTupleDouble3 nodeOffset   = grid->getNodeOffset(block);
+	double         dx           = grid->getDeltaX(block);
+
+	//Diese Daten werden geschrieben:
+	datanames.resize(0);
+	datanames.push_back("AvVx");
+   datanames.push_back("AvVy");
+   datanames.push_back("AvVz");
+	datanames.push_back("AvVxx");
+	datanames.push_back("AvVyy");
+	datanames.push_back("AvVzz");
+   datanames.push_back("AvVxy");
+   datanames.push_back("AvVxz");
+   datanames.push_back("AvVyz");
+   datanames.push_back("AvP");
+   datanames.push_back("AvPrms");
+
+
+	data.resize(datanames.size());
+
+	ILBMKernelPtr kernel = block->getKernel();
+	BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
+	DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions(); 
+	AverageValuesArray3DPtr av = kernel->getDataSet()->getAverageValues();
+	//int ghostLayerWidth = kernel->getGhostLayerWidth();
+
+	//knotennummerierung faengt immer bei 0 an!
+	int SWB,SEB,NEB,NWB,SWT,SET,NET,NWT;
+
+	int minX1 = 0;
+	int minX2 = 0;
+	int minX3 = 0;
+
+	int maxX1 = int(distributions->getNX1());
+	int maxX2 = int(distributions->getNX2());
+	int maxX3 = int(distributions->getNX3());
+
+	//nummern vergeben und node vector erstellen + daten sammeln
+	CbArray3D<int> nodeNumbers((int)maxX1, (int)maxX2, (int)maxX3,-1);
+
+	maxX1 -= 2;
+	maxX2 -= 2;
+	maxX3 -= 2;
+
+	//D3Q27BoundaryConditionPtr bcPtr;
+
+	int nr = (int)nodes.size();
+
+	for(int ix3=minX3; ix3<=maxX3; ix3++)
+	{
+		for(int ix2=minX2; ix2<=maxX2; ix2++)
+		{
+			for(int ix1=minX1; ix1<=maxX1; ix1++)
+			{
+				if(!bcArray->isUndefined(ix1,ix2,ix3) && !bcArray->isSolid(ix1,ix2,ix3))
+				{
+					int index = 0;
+					nodeNumbers(ix1,ix2,ix3) = nr++;
+					nodes.push_back( makeUbTuple(float(val<1>(org) - val<1>(nodeOffset) + ix1*dx),
+						float(val<2>(org) - val<2>(nodeOffset) + ix2*dx),
+						float(val<3>(org) - val<3>(nodeOffset) + ix3*dx)) );
+
+					LBMReal vx=(*av)(AvVx,ix1,ix2,ix3);
+					LBMReal vy=(*av)(AvVy,ix1,ix2,ix3);
+					LBMReal vz=(*av)(AvVz,ix1,ix2,ix3);
+               
+               LBMReal vxx=(*av)(AvVxx,ix1,ix2,ix3);
+               LBMReal vyy=(*av)(AvVyy,ix1,ix2,ix3);
+               LBMReal vzz=(*av)(AvVzz,ix1,ix2,ix3);
+               
+               LBMReal vxy=(*av)(AvVxy,ix1,ix2,ix3);
+               LBMReal vxz=(*av)(AvVxz,ix1,ix2,ix3);
+               LBMReal vyz=(*av)(AvVyz,ix1,ix2,ix3);
+
+               LBMReal vp=(*av)(AvP,ix1,ix2,ix3);
+               LBMReal vprms=(*av)(AvPrms,ix1,ix2,ix3);
+ 
+					
+					data[index++].push_back(vx);
+               data[index++].push_back(vy);
+               data[index++].push_back(vz);
+
+					data[index++].push_back(vxx);
+					data[index++].push_back(vyy);
+					data[index++].push_back(vzz);
+
+               data[index++].push_back(vxy);
+               data[index++].push_back(vxz);
+               data[index++].push_back(vyz);
+
+               data[index++].push_back(vp);
+               data[index++].push_back(vprms);
+				}
+			}
+		}
+	}
+
+	maxX1 -= 1;
+	maxX2 -= 1;
+	maxX3 -= 1;
+
+	//cell vector erstellen
+	for(int ix3=minX3; ix3<=maxX3; ix3++)
+	{
+		for(int ix2=minX2; ix2<=maxX2; ix2++)
+		{
+			for(int ix1=minX1; ix1<=maxX1; ix1++)
+			{
+				if(   (SWB=nodeNumbers( ix1  , ix2,   ix3   )) >= 0
+					&& (SEB=nodeNumbers( ix1+1, ix2,   ix3   )) >= 0
+					&& (NEB=nodeNumbers( ix1+1, ix2+1, ix3   )) >= 0
+					&& (NWB=nodeNumbers( ix1  , ix2+1, ix3   )) >= 0 
+					&& (SWT=nodeNumbers( ix1  , ix2,   ix3+1 )) >= 0
+					&& (SET=nodeNumbers( ix1+1, ix2,   ix3+1 )) >= 0
+					&& (NET=nodeNumbers( ix1+1, ix2+1, ix3+1 )) >= 0
+					&& (NWT=nodeNumbers( ix1  , ix2+1, ix3+1 )) >= 0                )
+				{
+					cells.push_back( makeUbTuple(SWB,SEB,NEB,NWB,SWT,SET,NET,NWT) );
+				}
+			}
+		}
+	}
+}
+//////////////////////////////////////////////////////////////////////////
+void AverageValuesCoProcessor::calculateAverageValues(double timeStep)
+{
+	using namespace D3Q27System;
+
+   //Funktionszeiger
+   calcMacros = NULL;
+   if (compressible)
+   {
+      calcMacros = &calcCompMacroscopicValues;
+   }
+   else
+   {
+      calcMacros = &calcIncompMacroscopicValues;
+   }
+
+	LBMReal f[27];
+
+	for(int level = minInitLevel; level<=maxInitLevel;level++)
+	{
+		for(Block3DPtr block : blockVector[level])
+		{
+			if (block)
+			{
+				ILBMKernelPtr kernel = block->getKernel();
+				BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
+				DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions(); 
+				AverageValuesArray3DPtr av = kernel->getDataSet()->getAverageValues();
+
+				int minX1 = 0;
+				int minX2 = 0;
+				int minX3 = 0;
+
+				int maxX1 = int(distributions->getNX1());
+				int maxX2 = int(distributions->getNX2());
+				int maxX3 = int(distributions->getNX3());
+
+				maxX1 -= 2;
+				maxX2 -= 2;
+				maxX3 -= 2;
+
+				for(int ix3=minX3; ix3<=maxX3; ix3++)
+				{
+					for(int ix2=minX2; ix2<=maxX2; ix2++)
+					{
+						for(int ix1=minX1; ix1<=maxX1; ix1++)
+						{
+							if(!bcArray->isUndefined(ix1,ix2,ix3) && !bcArray->isSolid(ix1,ix2,ix3))
+							{
+								//////////////////////////////////////////////////////////////////////////
+								//read distribution
+								////////////////////////////////////////////////////////////////////////////
+								distributions->getDistribution(f, ix1, ix2, ix3);
+								//////////////////////////////////////////////////////////////////////////
+								//compute velocity
+								//////////////////////////////////////////////////////////////////////////
+                        LBMReal vx,vy,vz,rho;
+                        calcMacros(f,rho,vx,vy,vz);
+                        double press = D3Q27System::calcPress(f,rho,vx,vy,vz);
+
+								//////////////////////////////////////////////////////////////////////////
+								//compute average values
+								//////////////////////////////////////////////////////////////////////////
+
+								LBMReal timeStepAfterResetRMS=(double)(timeStep-resetStepRMS)/((double)averageInterval);
+								LBMReal timeStepAfterResetMeans=(double)(timeStep-resetStepMeans)/((double)averageInterval);
+
+                        //mean velocity
+                        (*av)(AvVx,ix1,ix2,ix3) = ((*av)(AvVx,ix1,ix2,ix3)*timeStepAfterResetMeans + vx)/(timeStepAfterResetMeans+1.0);
+                        (*av)(AvVy,ix1,ix2,ix3) = ((*av)(AvVy,ix1,ix2,ix3)*timeStepAfterResetMeans + vy)/(timeStepAfterResetMeans+1.0);
+                        (*av)(AvVz,ix1,ix2,ix3) = ((*av)(AvVz,ix1,ix2,ix3)*timeStepAfterResetMeans + vz)/(timeStepAfterResetMeans+1.0);
+
+                        //rms
+								(*av)(AvVxx,ix1,ix2,ix3) = ((vx-(*av)(AvVx,ix1,ix2,ix3))*(vx-(*av)(AvVx,ix1,ix2,ix3)) +
+									(*av)(AvVxx,ix1,ix2,ix3)*timeStepAfterResetRMS)/(timeStepAfterResetRMS+1.0);
+								(*av)(AvVyy,ix1,ix2,ix3) = ((vy-(*av)(AvVy,ix1,ix2,ix3))*(vy-(*av)(AvVy,ix1,ix2,ix3)) +
+									(*av)(AvVyy,ix1,ix2,ix3)*timeStepAfterResetRMS)/(timeStepAfterResetRMS+1.0);
+								(*av)(AvVzz,ix1,ix2,ix3) = ((vz-(*av)(AvVz,ix1,ix2,ix3))*(vz-(*av)(AvVz,ix1,ix2,ix3)) +
+									(*av)(AvVzz,ix1,ix2,ix3)*timeStepAfterResetRMS)/(timeStepAfterResetRMS+1.0);
+
+                        //cross-correlations
+                        (*av)(AvVxy,ix1,ix2,ix3) = ((vx-(*av)(AvVx,ix1,ix2,ix3))*(vy-(*av)(AvVy,ix1,ix2,ix3)) +
+                           (*av)(AvVxy,ix1,ix2,ix3)*timeStepAfterResetRMS)/(timeStepAfterResetRMS+1.0);
+                        (*av)(AvVxz,ix1,ix2,ix3) = ((vx-(*av)(AvVx,ix1,ix2,ix3))*(vz-(*av)(AvVz,ix1,ix2,ix3)) +
+                           (*av)(AvVxz,ix1,ix2,ix3)*timeStepAfterResetRMS)/(timeStepAfterResetRMS+1.0);
+                        (*av)(AvVyz,ix1,ix2,ix3) = ((vy-(*av)(AvVy,ix1,ix2,ix3))*(vz-(*av)(AvVz,ix1,ix2,ix3)) +
+                           (*av)(AvVyz,ix1,ix2,ix3)*timeStepAfterResetRMS)/(timeStepAfterResetRMS+1.0);
+
+                        //mean and rms press
+                        (*av)(AvP,ix1,ix2,ix3) = ((*av)(AvP,ix1,ix2,ix3)*timeStepAfterResetMeans + press)/(timeStepAfterResetMeans+1.0);
+                        (*av)(AvPrms,ix1,ix2,ix3) = ((press-(*av)(AvP,ix1,ix2,ix3))*(press-(*av)(AvP,ix1,ix2,ix3)) +
+                           (*av)(AvPrms,ix1,ix2,ix3)*timeStepAfterResetRMS)/(timeStepAfterResetRMS+1.0);
+
+								//////////////////////////////////////////////////////////////////////////
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+}
+////////////////////////////////////////////////////////////////////////////
+//void AverageValuesCoProcessor::initPlotData(double step)
+//{
+//   CommunicatorPtr comm = Communicator::getInstance();
+//	if (comm->getProcessID() == comm->getRoot())
+//	{
+//		std::ofstream ostr;
+//		string fname = path + "_PlotData_" + UbSystem::toString(step) + ".txt"; 
+//		ostr.open(fname.c_str(), std::ios_base::out);
+//		if(!ostr)
+//		{ 
+//			ostr.clear();
+//			string path = UbSystem::getPathFromString(fname);
+//			if(path.size()>0){ UbSystem::makeDirectory(path); ostr.open(fname.c_str(), std::ios_base::out);}
+//			if(!ostr) throw UbException(UB_EXARGS,"couldn't open file "+fname);
+//		}
+//		ostr << "Time"<< "\t" <<"Ref.Time"<<"\t"<< "Z_Coor"<< "\t" << "Pore fraction" << "\t";
+//		ostr << "Vx"  << "\t" << "Vy" << "\t" << "Vz" << "\t";
+//		ostr << "TSx" << "\t" << "TSy"<< "\t" << "TSz"<< "TSxz";
+//		ostr << endl;
+//		ostr.close();
+//	}
+//}
+//////////////////////////////////////////////////////////////////////////////
+//void AverageValuesCoProcessor::collectPlotData(double step)
+//{
+//
+//	double hminX1 = 0.9;
+//	double hminX2 = 0.0;
+//	double hmaxX1 = 0.95;
+//	double hmaxX2 = 0.01; //systemabmessungen world units
+//
+//	// 3 level platte standard:
+//	double hX3_level[] = {0.305, 0.309,0.3365,0.35};
+//	//0.004, 0,0365,0.045
+//	//musis: 3 level refinement
+//	//double hX3_level[] = {0.42, 0.28, 0.105, 0.0}; //refinement coords
+//	                    //bsislevel von 0.42-0.28,... (level 0 bis 2 , 3 insgesamt)
+//	//musis: 4 level refinement
+//	//double hX3_level[] = {0.42, 0.3, 0.195, 0.078, 0.0};
+//	//musis: 5 level refinement
+//	//double hX3_level[] = {0.396, 0.28, 0.18, 0.08, 0.006, 0.0};
+//
+//	ostringstream Str;
+//	Str << step;
+//	string step2string(Str.str());
+//	string fname = path + "_PlotZ_" + step2string + ".txt"; 
+//
+//
+//	for(int level = minInitLevel; level<=maxInitLevel;level++)
+//	{
+//		double dx = grid->getDeltaX(level);
+//
+//		for (double hi =hX3_level[level]; hi >= hX3_level[level+1]; hi=hi-dx ){
+//			D3Q27IntegrateValuesHelper h1(grid, comm, 
+//				hminX1, hminX2, hi, 
+//				hmaxX1, hmaxX2, hi-dx);
+//
+//			h1.calculateAV();
+//			double nn1 = h1.getNumberOfNodes();
+//			double ns1 = h1.getNumberOfSolids();
+//			if (nn1 > 0.0){
+//				// get data and write into txt files
+//				if (comm->getProcessID() == comm->getRoot())
+//				{
+//					int istep = static_cast<int>(step);
+//					std::ofstream ostr;
+//
+//					double AvVx1 = h1.getAvVx1()/nn1;
+//					double AvVx2 = h1.getAvVx2()/nn1;
+//					double AvVx3 = h1.getAvVx3()/nn1;
+//
+//					double AvTSx1 = h1.getTSx1()/nn1;
+//					double AvTSx2 = h1.getTSx2()/nn1;
+//					double AvTSx3 = h1.getTSx3()/nn1;
+//
+//					double AvTSx1x3 = h1.getTSx1x3()/nn1;
+//
+//					ostr.open(fname.c_str(), std::ios_base::out | std::ios_base::app);
+//					if(!ostr)
+//					{ 
+//						ostr.clear();
+//						string path = UbSystem::getPathFromString(fname);
+//						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 << istep << "\t" << resetStep << "\t" << hi+0.5*dx << "\t" << nn1/(nn1+ns1)*100.0 << "%\t";
+//					ostr << AvVx1 << "\t" << AvVx2 << "\t" << AvVx3 << "\t";
+//					ostr << AvTSx1<< "\t" << AvTSx2<< "\t" << AvTSx3<< "\t" << AvTSx1x3;
+//					ostr << endl;
+//					ostr.close();
+//
+//				}
+//			}
+//		}
+//
+//	}
+//}
+
diff --git a/source/VirtualFluidsCore/CoProcessors/AverageValuesCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/AverageValuesCoProcessor.h
index 3689e0192..e6962b5f3 100644
--- a/source/VirtualFluidsCore/CoProcessors/AverageValuesCoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/AverageValuesCoProcessor.h
@@ -1,18 +1,21 @@
 #ifndef AverageValuesCoProcessor_H
 #define AverageValuesCoProcessor_H
 
-#include "CoProcessor.h"
-#include "Grid3D.h"
-#include "Block3D.h"
-#include "LBMUnitConverter.h"
-#include "Communicator.h"
-#include "IntegrateValuesHelper.h"
+#include <memory>
+#include <vector>
+#include <string>
 
-#include "WbWriter.h"
+#include "CoProcessor.h"
+#include "LBMSystem.h"
+#include "UbTuple.h"
 
-#include <boost/shared_ptr.hpp>
 class AverageValuesCoProcessor;
-typedef boost::shared_ptr<AverageValuesCoProcessor> AverageValuesCoProcessorPtr;
+typedef std::shared_ptr<AverageValuesCoProcessor> AverageValuesCoProcessorPtr;
+
+class UbScheduler;
+class WbWriter;
+class Grid3D;
+class Block3D;
 
 //! \brief  Computes the time averaged mean velocity and RMS values and writes to parallel .vtk
 //! \details writes at given time intervals specified in scheduler (s), does averaging according to scheduler (Avs) and resets according to scheduler (rs).  <br>
@@ -24,8 +27,8 @@ class AverageValuesCoProcessor : public CoProcessor
 {
 public:
    AverageValuesCoProcessor();
-   AverageValuesCoProcessor(Grid3DPtr grid, const std::string& path, WbWriter* const writer, 
-                              UbSchedulerPtr s, UbSchedulerPtr Avs, UbSchedulerPtr rsMeans, UbSchedulerPtr rsRMS, bool restart);
+   AverageValuesCoProcessor(std::shared_ptr<Grid3D> grid, const std::string& path, WbWriter* const writer,
+       std::shared_ptr<UbScheduler> s, std::shared_ptr<UbScheduler> Avs, std::shared_ptr<UbScheduler> rsMeans, std::shared_ptr<UbScheduler> rsRMS, bool restart);
 	//! Make update
 	void process(double step); 
 	//! Resets averaged velocity and RMS-values according to ResetSceduler
@@ -37,7 +40,7 @@ protected:
 	void resetDataRMS(double step);
 	void resetDataMeans(double step);
 	//! prepare data
-	void addData(const Block3DPtr block);
+	void addData(const std::shared_ptr<Block3D> block);
 	void clearData();
 	//! Computes average and RMS values of macroscopic quantities 
 	void calculateAverageValues(double timeStep);
@@ -51,7 +54,7 @@ private:
 	std::vector<UbTupleInt8> cells;
 	std::vector<std::string> datanames;
 	std::vector<std::vector<double> > data; 
-	std::vector<std::vector<Block3DPtr> > blockVector;
+	std::vector<std::vector<std::shared_ptr<Block3D>> > blockVector;
 	int minInitLevel; //min init level
 	int maxInitLevel;
 	int gridRank;
@@ -61,9 +64,9 @@ private:
 	std::string path;
 	WbWriter* writer;
    bool restart, compressible;
-	UbSchedulerPtr averageScheduler;  //additional scheduler to averaging after a given interval
-	UbSchedulerPtr resetSchedulerRMS;  //additional scheduler to restart averaging after a given interval
-	UbSchedulerPtr resetSchedulerMeans;  //additional scheduler to restart averaging after a given interval
+   std::shared_ptr<UbScheduler> averageScheduler;  //additional scheduler to averaging after a given interval
+   std::shared_ptr<UbScheduler> resetSchedulerRMS;  //additional scheduler to restart averaging after a given interval
+   std::shared_ptr<UbScheduler> resetSchedulerMeans;  //additional scheduler to restart averaging after a given interval
 	//labels for the different components, e.g. AvVxx for time averaged RMS: 1/n SUM((U-Umean)^2)
    //you need to calculate a square root before plotting RMS
 	enum Values{AvVx = 0, AvVy = 1, AvVz = 2, AvVxx = 3, AvVyy = 4, AvVzz = 5, AvVxy = 6, AvVxz = 7, AvVyz = 8, AvP = 9, AvPrms = 10}; 
diff --git a/source/VirtualFluidsCore/CoProcessors/CalculateForcesCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/CalculateForcesCoProcessor.cpp
index 29853ebc4..a6a818bcb 100644
--- a/source/VirtualFluidsCore/CoProcessors/CalculateForcesCoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/CalculateForcesCoProcessor.cpp
@@ -1,6 +1,16 @@
 #include "CalculateForcesCoProcessor.h"
 #include "BCProcessor.h"
-#include <boost/foreach.hpp>
+
+#include "Communicator.h"
+#include "D3Q27Interactor.h"
+#include "UbScheduler.h"
+#include "Grid3D.h"
+#include "BoundaryConditions.h"
+#include "DataSet3D.h"
+#include "Block3D.h"
+#include "LBMKernel.h"
+#include "BCArray3D.h"
+#include "EsoTwist3D.h"
 
 CalculateForcesCoProcessor::CalculateForcesCoProcessor( Grid3DPtr grid, UbSchedulerPtr s, 
                                                     const std::string &path,
@@ -94,10 +104,9 @@ void CalculateForcesCoProcessor::calculateForces()
    forceX2global = 0.0;
    forceX3global = 0.0;
 
-   BOOST_FOREACH(D3Q27InteractorPtr interactor, interactors)
+   for(D3Q27InteractorPtr interactor : interactors)
    {
-      typedef std::map<Block3DPtr, std::set< std::vector<int> > > TransNodeIndicesMap;
-      BOOST_FOREACH(TransNodeIndicesMap::value_type t, interactor->getBcNodeIndicesMap())
+      for(BcNodeIndicesMap::value_type t : interactor->getBcNodeIndicesMap())
       {
          double forceX1 = 0.0;
          double forceX2 = 0.0;
@@ -106,7 +115,7 @@ void CalculateForcesCoProcessor::calculateForces()
          Block3DPtr block = t.first;
          std::set< std::vector<int> >& transNodeIndicesSet = t.second;
 
-         LBMKernelPtr kernel = block->getKernel();
+         ILBMKernelPtr kernel = block->getKernel();
          BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
          DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions(); 
          distributions->swap();
@@ -119,7 +128,7 @@ void CalculateForcesCoProcessor::calculateForces()
          int minX3 = ghostLayerWidth;
          int maxX3 = (int)bcArray->getNX3() - 1 - ghostLayerWidth;
 
-         BOOST_FOREACH(std::vector<int> node, transNodeIndicesSet)
+         for(std::vector<int> node : transNodeIndicesSet)
          {
             int x1 = node[0];
             int x2 = node[1];
@@ -191,8 +200,8 @@ UbTupleDouble3 CalculateForcesCoProcessor::getForces(int x1, int x2, int x3, Dis
          if(bc->hasNoSlipBoundaryFlag(fdir))
          {
             const int invDir = D3Q27System::INVDIR[fdir];
-            f = boost::dynamic_pointer_cast<EsoTwist3D>(distributions)->getDistributionInvForDirection(x1, x2, x3, invDir);
-            fnbr = boost::dynamic_pointer_cast<EsoTwist3D>(distributions)->getDistributionInvForDirection(x1+D3Q27System::DX1[invDir], x2+D3Q27System::DX2[invDir], x3+D3Q27System::DX3[invDir], fdir);
+            f = std::dynamic_pointer_cast<EsoTwist3D>(distributions)->getDistributionInvForDirection(x1, x2, x3, invDir);
+            fnbr = std::dynamic_pointer_cast<EsoTwist3D>(distributions)->getDistributionInvForDirection(x1+D3Q27System::DX1[invDir], x2+D3Q27System::DX2[invDir], x3+D3Q27System::DX3[invDir], fdir);
 
             forceX1 += (f + fnbr)*D3Q27System::DX1[invDir];
             forceX2 += (f + fnbr)*D3Q27System::DX2[invDir];
diff --git a/source/VirtualFluidsCore/CoProcessors/CalculateForcesCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/CalculateForcesCoProcessor.h
index 07688665f..87993c1b4 100644
--- a/source/VirtualFluidsCore/CoProcessors/CalculateForcesCoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/CalculateForcesCoProcessor.h
@@ -8,9 +8,19 @@
 #ifndef D3Q27ForcesCoProcessor_H
 #define D3Q27ForcesCoProcessor_H
 
-#include "CoProcessor.h"
-#include "Communicator.h"
-#include "D3Q27Interactor.h"
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "CoProcessor.h"
+
+class ForceCalculator;
+class Communicator;
+class Grid3D;
+class UbScheduler;
+class D3Q27Interactor;
+class DistributionArray3D;
+class BoundaryConditions;
 
 class CalculateForcesCoProcessor: public CoProcessor 
 {
@@ -18,22 +28,22 @@ public:
    //! Constructor
    //! \param v - velocity of fluid in LB units
    //! \param a - area of object in LB units
-   CalculateForcesCoProcessor(Grid3DPtr grid, UbSchedulerPtr s,
+   CalculateForcesCoProcessor(std::shared_ptr<Grid3D> grid, std::shared_ptr<UbScheduler> s,
                             const std::string &path,
-                            CommunicatorPtr comm, double v, double a);
+       std::shared_ptr<Communicator> comm, double v, double a);
 	virtual ~CalculateForcesCoProcessor();             
 	void process(double step); 
-   void addInteractor(D3Q27InteractorPtr interactor);
+   void addInteractor(std::shared_ptr<D3Q27Interactor> interactor);
 protected:
 	void collectData(double step);
    void calculateForces();
-   UbTupleDouble3 getForces(int x1, int x2, int x3, DistributionArray3DPtr distributions, BoundaryConditionsPtr bc);
+   UbTupleDouble3 getForces(int x1, int x2, int x3, std::shared_ptr<DistributionArray3D> distributions, std::shared_ptr<BoundaryConditions> bc);
    void calculateCoefficients();
    void write(std::ofstream *fileObject, double value, char *separator);
 private:
    std::string path;
-   CommunicatorPtr comm;
-   std::vector<D3Q27InteractorPtr> interactors;
+   std::shared_ptr<Communicator> comm;
+   std::vector<std::shared_ptr<D3Q27Interactor> > interactors;
    double forceX1global;
    double forceX2global;
    double forceX3global;
diff --git a/source/VirtualFluidsCore/CoProcessors/CoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/CoProcessor.cpp
new file mode 100644
index 000000000..be71b9c22
--- /dev/null
+++ b/source/VirtualFluidsCore/CoProcessors/CoProcessor.cpp
@@ -0,0 +1,31 @@
+#include "CoProcessor.h"
+
+#include <basics/utilities/UbScheduler.h>
+#include <boost/bind.hpp>
+
+
+CoProcessor::CoProcessor()
+{
+}
+
+CoProcessor::CoProcessor(std::shared_ptr<Grid3D> grid, UbSchedulerPtr s): grid(grid), scheduler(s)
+{
+    connection = grid->connect(boost::bind(&CoProcessor::process, this, _1));
+}
+
+CoProcessor::~CoProcessor()
+{
+    grid->disconnect(connection);
+}
+
+void CoProcessor::disconnect()
+{
+    grid->disconnect(connection);
+}
+
+void CoProcessor::reconnect(std::shared_ptr<Grid3D> grid)
+{
+    this->grid = grid;
+    this->grid->disconnect(connection);
+    connection = this->grid->connect(boost::bind(&CoProcessor::process, this, _1));
+}
diff --git a/source/VirtualFluidsCore/CoProcessors/CoProcessor.h b/source/VirtualFluidsCore/CoProcessors/CoProcessor.h
index e666dc626..e5f0343da 100644
--- a/source/VirtualFluidsCore/CoProcessors/CoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/CoProcessor.h
@@ -1,65 +1,42 @@
-#ifndef CoProcessor_H
-#define CoProcessor_H
-
-#include <boost/bind.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/serialization/serialization.hpp>
-
-#include <Grid3D.h>
-#include <basics/utilities/UbScheduler.h>
-
-class CoProcessor;
-typedef boost::shared_ptr<CoProcessor> CoProcessorPtr;
-
-class CoProcessor
-{
-public:
-   CoProcessor()
-   {
-
-   }
-
-   CoProcessor(Grid3DPtr grid, UbSchedulerPtr s)
-      : grid(grid)
-      , scheduler(s)
-   {
-      connection = grid->connect(boost::bind(&CoProcessor::process, this, _1));
-   }
-
-   virtual ~CoProcessor()
-   {
-      grid->disconnect(connection);
-   }
-
-   virtual void process(double step) = 0;
-
-   virtual void disconnect()
-   {
-      grid->disconnect(connection);
-   }
-
-   virtual void reconnect(Grid3DPtr grid)
-   {
-      this->grid = grid;
-      this->grid->disconnect(connection);
-      connection = this->grid->connect(boost::bind(&CoProcessor::process, this, _1));
-   }
-
-protected:
-   Grid3DPtr grid;
-   UbSchedulerPtr scheduler;
-   Grid3D::connection_t connection;
-private:
-   
-
-private:
-   friend class boost::serialization::access;
-   template<class Archive>
-   void serialize(Archive & ar, const unsigned int version)
-   {
-      //ar & grid;
-      ar & scheduler;
-   }
-};
-#endif
-
+#ifndef CoProcessor_H
+#define CoProcessor_H
+
+#include <memory>
+
+#include <boost/serialization/serialization.hpp>
+
+#include "Grid3D.h"
+
+class UbScheduler;
+
+class CoProcessor;
+typedef std::shared_ptr<CoProcessor> CoProcessorPtr;
+
+class CoProcessor
+{
+public:
+    CoProcessor();
+    CoProcessor(std::shared_ptr<Grid3D> grid, std::shared_ptr<UbScheduler> s);
+    virtual ~CoProcessor();
+
+   virtual void process(double step) = 0;
+
+   virtual void disconnect();
+   virtual void reconnect(std::shared_ptr<Grid3D> grid);
+
+protected:
+   std::shared_ptr<Grid3D> grid;
+   std::shared_ptr<UbScheduler> scheduler;
+   Grid3D::connection_t connection;
+
+private:
+   friend class boost::serialization::access;
+   template<class Archive>
+   void serialize(Archive & ar, const unsigned int version)
+   {
+      //ar & grid;
+      ar & scheduler;
+   }
+};
+#endif
+
diff --git a/source/VirtualFluidsCore/CoProcessors/DecreaseViscosityCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/DecreaseViscosityCoProcessor.cpp
index 429bf3e6e..31d677377 100644
--- a/source/VirtualFluidsCore/CoProcessors/DecreaseViscosityCoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/DecreaseViscosityCoProcessor.cpp
@@ -6,12 +6,14 @@
 */
 
 #include "DecreaseViscosityCoProcessor.h"
-#include <boost/foreach.hpp>
 
-#include <iostream>
-#include <fstream>
+#include <vector>
 
-using namespace std;
+#include "LBMKernel.h"
+#include "Communicator.h"
+#include "UbScheduler.h"
+#include "Grid3D.h"
+#include "Block3D.h"
 
 DecreaseViscosityCoProcessor::DecreaseViscosityCoProcessor(Grid3DPtr grid, UbSchedulerPtr s,
                                                                mu::Parser* nueFunc, CommunicatorPtr comm)
@@ -49,11 +51,11 @@ void DecreaseViscosityCoProcessor::setViscosity(double step)
 
       for(int level = minInitLevel; level<=maxInitLevel;level++)
       {
-         vector<Block3DPtr> blockVector;
+         std::vector<Block3DPtr> blockVector;
          grid->getBlocks(level, gridRank, blockVector);
-         BOOST_FOREACH(Block3DPtr block, blockVector)
+         for(Block3DPtr block : blockVector)
          {
-            LBMKernelPtr kernel =block->getKernel();
+            ILBMKernelPtr kernel = block->getKernel();
          }
       }
 
@@ -64,11 +66,11 @@ void DecreaseViscosityCoProcessor::setViscosity(double step)
 
       for(int level = minInitLevel; level<=maxInitLevel;level++)
       {
-         vector<Block3DPtr> blockVector;
+          std::vector<Block3DPtr> blockVector;
          grid->getBlocks(level, gridRank, blockVector);
-         BOOST_FOREACH(Block3DPtr block, blockVector)
+         for(Block3DPtr block : blockVector)
          {
-            LBMKernelPtr kernel =block->getKernel();
+            ILBMKernelPtr kernel =block->getKernel();
             if(kernel)      
             {
                LBMReal collFactor = LBMSystem::calcCollisionFactor(nue, block->getLevel());
diff --git a/source/VirtualFluidsCore/CoProcessors/DecreaseViscosityCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/DecreaseViscosityCoProcessor.h
index 515b7bf8c..10de48bec 100644
--- a/source/VirtualFluidsCore/CoProcessors/DecreaseViscosityCoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/DecreaseViscosityCoProcessor.h
@@ -1,14 +1,21 @@
 #ifndef DecreaseViscosityCoProcessor_H
 #define DecreaseViscosityCoProcessor_H
 
+#include <memory>
+
 #include "CoProcessor.h"
 #include "IntegrateValuesHelper.h"
 #include "LBMUnitConverter.h"
-#include "Communicator.h"
 
-#include <boost/shared_ptr.hpp>
+#include "MuParser/include/muParser.h"
+
+
 class DecreaseViscosityCoProcessor;
-typedef boost::shared_ptr<DecreaseViscosityCoProcessor> DecreaseViscosityCoProcessorPtr;
+typedef std::shared_ptr<DecreaseViscosityCoProcessor> DecreaseViscosityCoProcessorPtr;
+
+class UbScheduler;
+class Grid3D;
+class Communicator;
 
 //! \brief The class sets viscosity/collision factor according to a previously defined function in time. 
 //! \details initialization in test case (example): 
@@ -26,15 +33,15 @@ typedef boost::shared_ptr<DecreaseViscosityCoProcessor> DecreaseViscosityCoProce
 class DecreaseViscosityCoProcessor: public CoProcessor 
 { 
 public:
-   DecreaseViscosityCoProcessor(Grid3DPtr grid, UbSchedulerPtr s,
-      mu::Parser* nueFunc, CommunicatorPtr comm);
+   DecreaseViscosityCoProcessor(std::shared_ptr<Grid3D> grid, std::shared_ptr<UbScheduler> s,
+      mu::Parser* nueFunc, std::shared_ptr<Communicator> comm);
    virtual ~DecreaseViscosityCoProcessor();
    //! calls collect PostprocessData.
    void process(double step); 
 protected:
    //! resets the collision factor depending on the current timestep.
    void setViscosity(double step);  
-   CommunicatorPtr comm;
+   std::shared_ptr<Communicator>  comm;
 private:
    mutable mu::value_type timeStep;
    mu::Parser* nueFunc;
diff --git a/source/VirtualFluidsCore/CoProcessors/EmergencyExitCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/EmergencyExitCoProcessor.cpp
index eb10d750d..e787515e6 100644
--- a/source/VirtualFluidsCore/CoProcessors/EmergencyExitCoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/EmergencyExitCoProcessor.cpp
@@ -1,6 +1,11 @@
 #include "EmergencyExitCoProcessor.h"
 #include <basics/utilities/UbFileOutputASCII.h>
 #include <basics/utilities/UbFileInputASCII.h>
+#include "UbLogger.h"
+#include "UbScheduler.h"
+#include "Communicator.h"
+#include "RestartCoProcessor.h"
+#include "Grid3D.h"
 
 EmergencyExitCoProcessor::EmergencyExitCoProcessor( Grid3DPtr grid, UbSchedulerPtr s, 
                                                         const std::string& path, 
diff --git a/source/VirtualFluidsCore/CoProcessors/EmergencyExitCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/EmergencyExitCoProcessor.h
index ca7ffef59..7ededc126 100644
--- a/source/VirtualFluidsCore/CoProcessors/EmergencyExitCoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/EmergencyExitCoProcessor.h
@@ -8,32 +8,38 @@
 #ifndef EmergencyExitCoProcessor_H
 #define EmergencyExitCoProcessor_H
 
+#include <memory>
+#include <string>
+
 #include "CoProcessor.h"
-#include "Communicator.h"
-#include "RestartCoProcessor.h"
 
-#include <boost/shared_ptr.hpp>
+class RestartCoProcessor;
+class Communicator;
+class Grid3D;
+class UbScheduler;
+
 class EmergencyExitCoProcessor;
-typedef boost::shared_ptr<EmergencyExitCoProcessor> EmergencyExitCoProcessorPtr;
+typedef std::shared_ptr<EmergencyExitCoProcessor> EmergencyExitCoProcessorPtr;
 
-class EmergencyExitCoProcessor: public CoProcessor 
+class EmergencyExitCoProcessor : public CoProcessor
 {
 public:
-	EmergencyExitCoProcessor(Grid3DPtr grid, UbSchedulerPtr s,
-                              const std::string& path, RestartCoProcessorPtr rp,
-                              CommunicatorPtr comm);
-	virtual ~EmergencyExitCoProcessor();
-	void process(double step);
+    EmergencyExitCoProcessor(std::shared_ptr<Grid3D> grid, std::shared_ptr<UbScheduler> s, const std::string& path, std::shared_ptr<RestartCoProcessor> rp, std::shared_ptr<Communicator> comm);
+    virtual ~EmergencyExitCoProcessor();
+
+    void process(double step) override;
+
 protected:
-	void collectData(double step);
-   void writeMetafile(int status);
-   bool readMetafile();
-   void checkMetafile();
+    void collectData(double step);
+    void writeMetafile(int status);
+    bool readMetafile();
+    void checkMetafile();
+
 private:
-   std::string path;
-   CommunicatorPtr comm;
-   RestartCoProcessorPtr rp;
-   std::string metafile;
+    std::string path;
+    std::shared_ptr<Communicator> comm;
+    std::shared_ptr<RestartCoProcessor> rp;
+    std::string metafile;
 };
 
 
diff --git a/source/VirtualFluidsCore/CoProcessors/InSituCatalystCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/InSituCatalystCoProcessor.cpp
index 36f2fc1e5..394a146fa 100644
--- a/source/VirtualFluidsCore/CoProcessors/InSituCatalystCoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/InSituCatalystCoProcessor.cpp
@@ -71,7 +71,7 @@ void InSituCatalystCoProcessor::collectData(double step)
 
       for (int level = minInitLevel; level <= maxInitLevel; level++)
       {
-         BOOST_FOREACH(Block3DPtr block, blockVector[level])
+         for(Block3DPtr block : blockVector[level])
          {
             if (block)
             {
@@ -194,7 +194,7 @@ void InSituCatalystCoProcessor::buildVTKGrid()
 
    for (int level = minInitLevel; level <= maxInitLevel; level++)
    {
-      BOOST_FOREACH(Block3DPtr block, blockVector[level])
+      for(Block3DPtr block : blockVector[level])
       {
          if (block)
          {
diff --git a/source/VirtualFluidsCore/CoProcessors/InSituVTKCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/InSituVTKCoProcessor.cpp
index 0576fe488..e891ea42b 100644
--- a/source/VirtualFluidsCore/CoProcessors/InSituVTKCoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/InSituVTKCoProcessor.cpp
@@ -88,7 +88,7 @@ void InSituVTKCoProcessor::collectData( double step )
 
    for(int level = minInitLevel; level<=maxInitLevel;level++)
    {
-      BOOST_FOREACH(Block3DPtr block, blockVector[level])
+      for(Block3DPtr block : blockVector[level])
       {
          if (block)
          {
diff --git a/source/VirtualFluidsCore/CoProcessors/IntegrateValuesHelper.cpp b/source/VirtualFluidsCore/CoProcessors/IntegrateValuesHelper.cpp
index 5ba5d10a4..c88e4c23e 100644
--- a/source/VirtualFluidsCore/CoProcessors/IntegrateValuesHelper.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/IntegrateValuesHelper.cpp
@@ -1,559 +1,559 @@
-#include "IntegrateValuesHelper.h"
-
-#include <boost/foreach.hpp>
-#include <numerics/geometry3d/GbCuboid3D.h>
-#include <numerics/geometry3d/CoordinateTransformation3D.h>
-#include <vector>
-
-#include "LBMKernel.h"
-#include "BCProcessor.h"
-
-using namespace std;
-//////////////////////////////////////////////////////////////////////////
-IntegrateValuesHelper::IntegrateValuesHelper(Grid3DPtr grid, CommunicatorPtr comm,
-   double minX1, double minX2,
-   double minX3, double maxX1,
-   double maxX2, double maxX3) :
-
-   grid(grid),
-   comm(comm),
-   sVx1(0.0), sVx2(0.0), sVx3(0.0), sRho(0.0), sCellVolume(0.0),
-   numberOfFluidsNodes(0),
-   numberOfSolidNodes(0)
-{
-   boundingBox = GbCuboid3DPtr(new GbCuboid3D(minX1, minX2, minX3, maxX1, maxX2, maxX3));
-   init(-1);
-}
-//////////////////////////////////////////////////////////////////////////
-IntegrateValuesHelper::IntegrateValuesHelper(Grid3DPtr grid, CommunicatorPtr comm,
-   double minX1, double minX2,
-   double minX3, double maxX1,
-   double maxX2, double maxX3,
-   int level) :
-
-   grid(grid),
-   comm(comm),
-   sVx1(0.0), sVx2(0.0), sVx3(0.0), sRho(0.0), sCellVolume(0.0),
-   numberOfFluidsNodes(0),
-   numberOfSolidNodes(0)
-{
-   boundingBox = GbCuboid3DPtr(new GbCuboid3D(minX1, minX2, minX3, maxX1, maxX2, maxX3));
-   init(level);
-}
-//////////////////////////////////////////////////////////////////////////
-IntegrateValuesHelper::~IntegrateValuesHelper()
-{
-}
-//////////////////////////////////////////////////////////////////////////
-void IntegrateValuesHelper::init(int level)
-{
-   root = comm->isRoot();
-
-   double orgX1, orgX2, orgX3;
-   int gridRank = grid->getRank();
-   int minInitLevel, maxInitLevel;
-   if (level < 0)
-   {
-      minInitLevel = this->grid->getCoarsestInitializedLevel();
-      maxInitLevel = this->grid->getFinestInitializedLevel();
-   }
-   else
-   {
-      minInitLevel = level;
-      maxInitLevel = level;
-   }
-
-   double numSolids = 0.0;
-   double numFluids = 0.0;
-   for (int level = minInitLevel; level <= maxInitLevel; level++)
-   {
-      vector<Block3DPtr> blockVector;
-      grid->getBlocks(level, gridRank, blockVector);
-      BOOST_FOREACH(Block3DPtr block, blockVector)
-      {
-         CalcNodes cn;
-         cn.block = block;
-         //Koords bestimmen
-         UbTupleDouble3 org = grid->getBlockWorldCoordinates(block);
-
-         orgX1 = val<1>(org);
-         orgX2 = val<2>(org);
-         orgX3 = val<3>(org);
-
-         LBMKernelPtr kernel = boost::dynamic_pointer_cast<LBMKernel>(block->getKernel());
-         BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
-         int ghostLayerWitdh = kernel->getGhostLayerWidth();
-         DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();
-         double internX1, internX2, internX3;
-
-         double         dx = grid->getDeltaX(block);
-         UbTupleDouble3 orgDelta = grid->getNodeOffset(block);
-
-         for (int ix3 = ghostLayerWitdh; ix3 < (int)distributions->getNX3() - ghostLayerWitdh; ix3++)
-         {
-            for (int ix2 = ghostLayerWitdh; ix2 < (int)distributions->getNX2() - ghostLayerWitdh; ix2++)
-            {
-               for (int ix1 = ghostLayerWitdh; ix1 < (int)distributions->getNX1() - ghostLayerWitdh; ix1++)
-               {
-                  internX1 = orgX1 - val<1>(orgDelta) + ix1 * dx;
-                  internX2 = orgX2 - val<2>(orgDelta) + ix2 * dx;
-                  internX3 = orgX3 - val<3>(orgDelta) + ix3 * dx;
-                  if (boundingBox->isPointInGbObject3D(internX1, internX2, internX3))
-                  {
-                     if (!bcArray->isSolid(ix1, ix2, ix3) && !bcArray->isUndefined(ix1, ix2, ix3))
-                     {
-                        cn.nodes.push_back(UbTupleInt3(ix1, ix2, ix3));
-                        numFluids++;
-                     }
-                     else if (bcArray->isSolid(ix1, ix2, ix3))
-                     {
-                        numSolids++;
-                     }
-                  }
-               }
-            }
-         }
-         if (cn.nodes.size() > 0)
-            cnodes.push_back(cn);
-      }
-   }
-   vector<double> rvalues;
-   vector<double> values;
-   values.push_back(numSolids);
-   values.push_back(numFluids);
-   rvalues = comm->gather(values);
-
-   if (root)
-   {
-      numberOfSolidNodes = 0.0;
-      numberOfFluidsNodes = 0.0;
-      int rsize = (int)rvalues.size();
-      int vsize = (int)values.size();
-      for (int i = 0; i < rsize; i += vsize)
-      {
-         numberOfSolidNodes += rvalues[i];
-         numberOfFluidsNodes += rvalues[i + 1];
-      }
-   }
-
-}
-//////////////////////////////////////////////////////////////////////////
-void IntegrateValuesHelper::prepare2DMatrix(int level)
-{
-   root = comm->isRoot();
-
-   double orgX1, orgX2, orgX3;
-   int gridRank = grid->getRank();
-   int minInitLevel, maxInitLevel;
-   if (level<0)
-   {
-      minInitLevel = this->grid->getCoarsestInitializedLevel();
-      maxInitLevel = this->grid->getFinestInitializedLevel();
-   }
-   else
-   {
-      minInitLevel = level;
-      maxInitLevel = level;
-   }
-   double dx = grid->getDeltaX(level);
-   CoordinateTransformation3D trafo(boundingBox->getX1Minimum(),boundingBox->getX2Minimum(),boundingBox->getX3Minimum(),dx,dx,dx);
-   cnodes2DMatrix.resize(UbMath::integerRounding<double>(boundingBox->getX1Maximum()/dx),UbMath::integerRounding<double>(boundingBox->getX2Maximum()/dx));
-
-   double numSolids = 0.0;
-   double numFluids = 0.0;
-   for (int level = minInitLevel; level<=maxInitLevel; level++)
-   {
-      vector<Block3DPtr> blockVector;
-      grid->getBlocks(level, gridRank, blockVector);
-      BOOST_FOREACH(Block3DPtr block, blockVector)
-      {
-         Node cn;
-         cn.block = block;
-         //Koords bestimmen
-         UbTupleDouble3 org = grid->getBlockWorldCoordinates(block);
-
-         orgX1 = val<1>(org);
-         orgX2 = val<2>(org);
-         orgX3 = val<3>(org);
-
-         LBMKernelPtr kernel = block->getKernel();
-         BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
-         int ghostLayerWitdh = kernel->getGhostLayerWidth();
-         DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();
-         double internX1, internX2, internX3;
-
-         double         dx = grid->getDeltaX(block);
-         UbTupleDouble3 orgDelta = grid->getNodeOffset(block);
-
-         for (int ix3 = ghostLayerWitdh; ix3<(int)distributions->getNX3()-ghostLayerWitdh; ix3++)
-         {
-            for (int ix2 = ghostLayerWitdh; ix2<(int)distributions->getNX2()-ghostLayerWitdh; ix2++)
-            {
-               for (int ix1 = ghostLayerWitdh; ix1<(int)distributions->getNX1()-ghostLayerWitdh; ix1++)
-               {
-                  internX1 = orgX1-val<1>(orgDelta)+ix1 * dx;
-                  internX2 = orgX2-val<2>(orgDelta)+ix2 * dx;
-                  internX3 = orgX3-val<3>(orgDelta)+ix3 * dx;
-                  if (boundingBox->isPointInGbObject3D(internX1, internX2, internX3))
-                  {
-                     if (!bcArray->isSolid(ix1, ix2, ix3)&&!bcArray->isUndefined(ix1, ix2, ix3))
-                     {
-                        cn.node = UbTupleInt3(ix1, ix2, ix3);
-                        int x1 = (int)trafo.transformForwardToX1Coordinate(internX1, internX2, internX3);
-                        int x2 = (int)trafo.transformForwardToX2Coordinate(internX1, internX2, internX3);
-                        cnodes2DMatrix(x1,x2)=cn;
-                        numFluids++;
-                     }
-                     else if (bcArray->isSolid(ix1, ix2, ix3))
-                     {
-                        numSolids++;
-                     }
-                  }
-               }
-            }
-         }
-
-      }
-   }
-   vector<double> rvalues;
-   vector<double> values;
-   values.push_back(numSolids);
-   values.push_back(numFluids);
-   rvalues = comm->gather(values);
-
-   if (root)
-   {
-      numberOfSolidNodes = 0.0;
-      numberOfFluidsNodes = 0.0;
-      int rsize = (int)rvalues.size();
-      int vsize = (int)values.size();
-      for (int i = 0; i<rsize; i += vsize)
-      {
-         numberOfSolidNodes += rvalues[i];
-         numberOfFluidsNodes += rvalues[i+1];
-      }
-   }
-
-}
-// calculation conventional rho, velocity and averaged data
-void IntegrateValuesHelper::calculateAV()
-{
-   clearData();
-
-   BOOST_FOREACH(CalcNodes cn, cnodes)
-   {
-      LBMKernelPtr kernel = cn.block->getKernel();
-      AverageValuesArray3DPtr averagedValues = kernel->getDataSet()->getAverageValues();
-
-      BOOST_FOREACH(UbTupleInt3 node, cn.nodes)
-      {
-         double Avx = (*averagedValues)(val<1>(node), val<2>(node), val<3>(node), AvVx);
-         double Avy = (*averagedValues)(val<1>(node), val<2>(node), val<3>(node), AvVy);
-         double Avz = (*averagedValues)(val<1>(node), val<2>(node), val<3>(node), AvVz);
-
-         double Avxx = (*averagedValues)(val<1>(node), val<2>(node), val<3>(node), AvVxx);
-         double Avyy = (*averagedValues)(val<1>(node), val<2>(node), val<3>(node), AvVyy);
-         double Avzz = (*averagedValues)(val<1>(node), val<2>(node), val<3>(node), AvVzz);
-
-         double Avxz = (*averagedValues)(val<1>(node), val<2>(node), val<3>(node), AvVxz);
-         sAvVx1 += abs(Avx);
-         sAvVx2 += abs(Avy);
-         sAvVx3 += abs(Avz);
-
-         sTSx1 += sqrt(Avxx);
-         sTSx2 += sqrt(Avyy);
-         sTSx3 += sqrt(Avzz);
-
-         sTSx1x3 += Avxz;
-         numberOfFluidsNodes++;
-      }
-   }
-   vector<double> values;
-   vector<double> rvalues;
-   values.push_back(sAvVx1);
-   values.push_back(sAvVx2);
-   values.push_back(sAvVx3);
-   values.push_back(sTSx1);
-   values.push_back(sTSx2);
-   values.push_back(sTSx3);
-   values.push_back(sTSx1x3);
-   values.push_back(numberOfFluidsNodes);
-
-   rvalues = comm->gather(values);
-   if (root)
-   {
-      clearData();
-      for (int i = 0; i < (int)rvalues.size(); i += 8)
-      {
-         sAvVx1 += rvalues[i];
-         sAvVx2 += rvalues[i + 1];
-         sAvVx3 += rvalues[i + 2];
-         sTSx1 += rvalues[i + 3];
-         sTSx2 += rvalues[i + 4];
-         sTSx3 += rvalues[i + 5];
-         sTSx1x3 += rvalues[i + 6];
-         numberOfFluidsNodes += rvalues[i + 7];
-      }
-   }
-}
-// calculation conventional rho, velocity and averaged data
-void IntegrateValuesHelper::calculateAV2()
-{
-   saVx = 0;
-   saVy = 0;
-   saVz = 0;
-
-   saVxx = 0;
-   saVyy = 0;
-   saVzz = 0;
-   saVxy = 0;
-   saVxz = 0;
-   saVyz = 0;
-
-   saVxxx = 0;
-   saVxxy = 0;
-   saVxxz = 0;
-   saVyyy = 0;
-   saVyyx = 0;
-   saVyyz = 0;
-   saVzzz = 0;
-   saVzzx = 0;
-   saVzzy = 0;
-   saVxyz = 0;
-
-   double lsaVx = 0;
-   double lsaVy = 0;
-   double lsaVz = 0;
-
-   double lsaVxx = 0;
-   double lsaVyy = 0;
-   double lsaVzz = 0;
-   double lsaVxy = 0;
-   double lsaVxz = 0;
-   double lsaVyz = 0;
-
-   double lsaVxxx = 0;
-   double lsaVxxy = 0;
-   double lsaVxxz = 0;
-   double lsaVyyy = 0;
-   double lsaVyyx = 0;
-   double lsaVyyz = 0;
-   double lsaVzzz = 0;
-   double lsaVzzx = 0;
-   double lsaVzzy = 0;
-   double lsaVxyz = 0;
-
-   BOOST_FOREACH(CalcNodes cn, cnodes)
-   {
-      LBMKernelPtr kernel = cn.block->getKernel();
-      AverageValuesArray3DPtr averagedVelocity = kernel->getDataSet()->getAverageVelocity();
-      AverageValuesArray3DPtr averagedFluctuations = kernel->getDataSet()->getAverageFluctuations();
-      AverageValuesArray3DPtr averagedTriplecorrelations = kernel->getDataSet()->getAverageTriplecorrelations();
-
-      BOOST_FOREACH(UbTupleInt3 node, cn.nodes)
-      {
-         double aVx = (*averagedVelocity)(Vx, val<1>(node), val<2>(node), val<3>(node));
-         double aVy = (*averagedVelocity)(Vy, val<1>(node), val<2>(node), val<3>(node));
-         double aVz = (*averagedVelocity)(Vz, val<1>(node), val<2>(node), val<3>(node));
-
-         double aVxx = (*averagedFluctuations)(Vxx, val<1>(node), val<2>(node), val<3>(node));
-         double aVyy = (*averagedFluctuations)(Vyy, val<1>(node), val<2>(node), val<3>(node));
-         double aVzz = (*averagedFluctuations)(Vzz, val<1>(node), val<2>(node), val<3>(node));
-         double aVxy = (*averagedFluctuations)(Vxy, val<1>(node), val<2>(node), val<3>(node));
-         double aVxz = (*averagedFluctuations)(Vxz, val<1>(node), val<2>(node), val<3>(node));
-         double aVyz = (*averagedFluctuations)(Vyz, val<1>(node), val<2>(node), val<3>(node));
-
-         double aVxxx = (*averagedTriplecorrelations)(Vxxx, val<1>(node), val<2>(node), val<3>(node));
-         double aVxxy = (*averagedTriplecorrelations)(Vxxy, val<1>(node), val<2>(node), val<3>(node));
-         double aVxxz = (*averagedTriplecorrelations)(Vxxz, val<1>(node), val<2>(node), val<3>(node));
-         double aVyyy = (*averagedTriplecorrelations)(Vyyy, val<1>(node), val<2>(node), val<3>(node));
-         double aVyyx = (*averagedTriplecorrelations)(Vyyx, val<1>(node), val<2>(node), val<3>(node));
-         double aVyyz = (*averagedTriplecorrelations)(Vyyz, val<1>(node), val<2>(node), val<3>(node));
-         double aVzzz = (*averagedTriplecorrelations)(Vzzz, val<1>(node), val<2>(node), val<3>(node));
-         double aVzzx = (*averagedTriplecorrelations)(Vzzx, val<1>(node), val<2>(node), val<3>(node));
-         double aVzzy = (*averagedTriplecorrelations)(Vzzy, val<1>(node), val<2>(node), val<3>(node));
-         double aVxyz = (*averagedTriplecorrelations)(Vxyz, val<1>(node), val<2>(node), val<3>(node));
-
-         lsaVx += aVx;
-         lsaVy += aVy;
-         lsaVz += aVz;
-
-         lsaVxx += aVxx;
-         lsaVyy += aVyy;
-         lsaVzz += aVzz;
-         lsaVxy += aVxy;
-         lsaVxz += aVxz;
-         lsaVyz += aVyz;
-
-         lsaVxxx += aVxxx;
-         lsaVxxy += aVxxy;
-         lsaVxxz += aVxxz;
-         lsaVyyy += aVyyy;
-         lsaVyyx += aVyyx;
-         lsaVyyz += aVyyz;
-         lsaVzzz += aVzzz;
-         lsaVzzx += aVzzx;
-         lsaVzzy += aVzzy;
-         lsaVxyz += aVxyz;
-
-         //numberOfFluidsNodes++;
-      }
-   }
-   vector<double> values;
-   vector<double> rvalues;
-   values.push_back(lsaVx);
-   values.push_back(lsaVy);
-   values.push_back(lsaVz);
-
-   values.push_back(lsaVxx);
-   values.push_back(lsaVyy);
-   values.push_back(lsaVzz);
-   values.push_back(lsaVxy);
-   values.push_back(lsaVxz);
-   values.push_back(lsaVyz);
-
-   values.push_back(lsaVxxx);
-   values.push_back(lsaVxxy);
-   values.push_back(lsaVxxz);
-   values.push_back(lsaVyyy);
-   values.push_back(lsaVyyx);
-   values.push_back(lsaVyyz);
-   values.push_back(lsaVzzz);
-   values.push_back(lsaVzzx);
-   values.push_back(lsaVzzy);
-   values.push_back(lsaVxyz);
-
-   rvalues = comm->gather(values);
-   if (root)
-   {
-      for (int i = 0; i < (int)rvalues.size(); i += 19)
-      {
-         saVx += rvalues[i];
-         saVy += rvalues[i + 1];
-         saVz += rvalues[i + 2];
-
-         saVxx += rvalues[i + 3];
-         saVyy += rvalues[i + 4];
-         saVzz += rvalues[i + 5];
-         saVxy += rvalues[i + 6];
-         saVxz += rvalues[i + 7];
-         saVyz += rvalues[i + 8];
-
-         saVxxx += rvalues[i + 9];
-         saVxxy += rvalues[i + 10];
-         saVxxz += rvalues[i + 11];
-         saVyyy += rvalues[i + 12];
-         saVyyx += rvalues[i + 13];
-         saVyyz += rvalues[i + 14];
-         saVzzz += rvalues[i + 15];
-         saVzzx += rvalues[i + 16];
-         saVzzy += rvalues[i + 17];
-         saVxyz += rvalues[i + 18];
-
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void IntegrateValuesHelper::calculateMQ()
-{
-   LBMReal f[D3Q27System::ENDF + 1];
-   LBMReal vx1, vx2, vx3, rho;
-   clearData();
-
-   //Funktionszeiger
-   typedef void(*CalcMacrosFct)(const LBMReal* const& /*feq[27]*/, LBMReal& /*(d)rho*/, LBMReal& /*vx1*/, LBMReal& /*vx2*/, LBMReal& /*vx3*/);
-
-   CalcMacrosFct calcMacros = NULL;
-
-   BOOST_FOREACH(CalcNodes cn, cnodes)
-   {
-      LBMKernelPtr kernel = cn.block->getKernel();
-      LBMReal dx = 1.0 / (LBMReal)(1 << cn.block->getLevel());
-      LBMReal cellVolume = dx*dx*dx;
-
-      if (kernel->getCompressible())
-      {
-         calcMacros = &D3Q27System::calcCompMacroscopicValues;
-      }
-      else
-      {
-         calcMacros = &D3Q27System::calcIncompMacroscopicValues;
-      }
-
-      BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
-      int ghostLayerWitdh = kernel->getGhostLayerWidth();
-      DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();
-      BOOST_FOREACH(UbTupleInt3 node, cn.nodes)
-      {
-         distributions->getDistribution(f, val<1>(node), val<2>(node), val<3>(node));
-         calcMacros(f, rho, vx1, vx2, vx3);
-         sRho += rho*cellVolume;
-         sVx1 += vx1*cellVolume;
-         sVx2 += vx2*cellVolume;
-         sVx3 += vx3*cellVolume;
-         sCellVolume += cellVolume;
-      }
-   }
-   vector<double> values(5);
-   vector<double> rvalues;
-   values[0] = sRho;
-   values[1] = sVx1;
-   values[2] = sVx2;
-   values[3] = sVx3;
-   values[4] = sCellVolume;
-
-   rvalues = comm->gather(values);
-   if (root)
-   {
-      clearData();
-      int rsize = (int)rvalues.size();
-      int vsize = (int)values.size();
-      for (int i = 0; i < rsize; i += vsize)
-      {
-         sRho += rvalues[i];
-         sVx1 += rvalues[i + 1];
-         sVx2 += rvalues[i + 2];
-         sVx3 += rvalues[i + 3];
-         sCellVolume += rvalues[i + 4];
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void IntegrateValuesHelper::clearData()
-{
-   sRho = 0.0;
-   sVx1 = 0.0;
-   sVx2 = 0.0;
-   sVx3 = 0.0;
-   sCellVolume = 0.0;
-   //sVm = 0.0;
-   //sPress = 0.0;
-   //numberOfFluidsNodes = 0.0;
-   sAvVx1 = 0.0;
-   sAvVx2 = 0.0;
-   sAvVx3 = 0.0;
-   sTSx1 = 0.0;
-   sTSx2 = 0.0;
-   sTSx3 = 0.0;
-   sTSx1x3 = 0.0;
-}
-//////////////////////////////////////////////////////////////////////////
-LBMReal IntegrateValuesHelper::getNumberOfFluidsNodes()
-{
-   return this->numberOfFluidsNodes;
-}
-//////////////////////////////////////////////////////////////////////////
-LBMReal IntegrateValuesHelper::getNumberOfSolidNodes()
-{
-   return this->numberOfSolidNodes;
-}
-//////////////////////////////////////////////////////////////////////////
-GbCuboid3DPtr IntegrateValuesHelper::getBoundingBox()
-{
-   return this->boundingBox;
-}
-//////////////////////////////////////////////////////////////////////////
-std::vector<IntegrateValuesHelper::CalcNodes> IntegrateValuesHelper::getCNodes()
-{
-   return cnodes;
-}
+#include "IntegrateValuesHelper.h"
+
+
+#include <numerics/geometry3d/GbCuboid3D.h>
+#include <numerics/geometry3d/CoordinateTransformation3D.h>
+#include <vector>
+
+#include "LBMKernel.h"
+#include "BCProcessor.h"
+#include "DataSet3D.h"
+#include "BCArray3D.h"
+
+//////////////////////////////////////////////////////////////////////////
+IntegrateValuesHelper::IntegrateValuesHelper(Grid3DPtr grid, CommunicatorPtr comm,
+   double minX1, double minX2,
+   double minX3, double maxX1,
+   double maxX2, double maxX3) :
+
+   grid(grid),
+   comm(comm),
+   sVx1(0.0), sVx2(0.0), sVx3(0.0), sRho(0.0), sCellVolume(0.0),
+   numberOfFluidsNodes(0),
+   numberOfSolidNodes(0)
+{
+   boundingBox = GbCuboid3DPtr(new GbCuboid3D(minX1, minX2, minX3, maxX1, maxX2, maxX3));
+   init(-1);
+}
+//////////////////////////////////////////////////////////////////////////
+IntegrateValuesHelper::IntegrateValuesHelper(Grid3DPtr grid, CommunicatorPtr comm,
+   double minX1, double minX2,
+   double minX3, double maxX1,
+   double maxX2, double maxX3,
+   int level) :
+
+   grid(grid),
+   comm(comm),
+   sVx1(0.0), sVx2(0.0), sVx3(0.0), sRho(0.0), sCellVolume(0.0),
+   numberOfFluidsNodes(0),
+   numberOfSolidNodes(0)
+{
+   boundingBox = GbCuboid3DPtr(new GbCuboid3D(minX1, minX2, minX3, maxX1, maxX2, maxX3));
+   init(level);
+}
+//////////////////////////////////////////////////////////////////////////
+IntegrateValuesHelper::~IntegrateValuesHelper()
+{
+}
+//////////////////////////////////////////////////////////////////////////
+void IntegrateValuesHelper::init(int level)
+{
+   root = comm->isRoot();
+
+   double orgX1, orgX2, orgX3;
+   int gridRank = grid->getRank();
+   int minInitLevel, maxInitLevel;
+   if (level < 0)
+   {
+      minInitLevel = this->grid->getCoarsestInitializedLevel();
+      maxInitLevel = this->grid->getFinestInitializedLevel();
+   }
+   else
+   {
+      minInitLevel = level;
+      maxInitLevel = level;
+   }
+
+   double numSolids = 0.0;
+   double numFluids = 0.0;
+   for (int level = minInitLevel; level <= maxInitLevel; level++)
+   {
+      std::vector<Block3DPtr> blockVector;
+      grid->getBlocks(level, gridRank, blockVector);
+      for(Block3DPtr block : blockVector)
+      {
+         CalcNodes cn;
+         cn.block = block;
+         //Koords bestimmen
+         UbTupleDouble3 org = grid->getBlockWorldCoordinates(block);
+
+         orgX1 = val<1>(org);
+         orgX2 = val<2>(org);
+         orgX3 = val<3>(org);
+
+         LBMKernelPtr kernel = std::dynamic_pointer_cast<LBMKernel>(block->getKernel());
+         BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
+         int ghostLayerWitdh = kernel->getGhostLayerWidth();
+         DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();
+         double internX1, internX2, internX3;
+
+         double         dx = grid->getDeltaX(block);
+         UbTupleDouble3 orgDelta = grid->getNodeOffset(block);
+
+         for (int ix3 = ghostLayerWitdh; ix3 < (int)distributions->getNX3() - ghostLayerWitdh; ix3++)
+         {
+            for (int ix2 = ghostLayerWitdh; ix2 < (int)distributions->getNX2() - ghostLayerWitdh; ix2++)
+            {
+               for (int ix1 = ghostLayerWitdh; ix1 < (int)distributions->getNX1() - ghostLayerWitdh; ix1++)
+               {
+                  internX1 = orgX1 - val<1>(orgDelta) + ix1 * dx;
+                  internX2 = orgX2 - val<2>(orgDelta) + ix2 * dx;
+                  internX3 = orgX3 - val<3>(orgDelta) + ix3 * dx;
+                  if (boundingBox->isPointInGbObject3D(internX1, internX2, internX3))
+                  {
+                     if (!bcArray->isSolid(ix1, ix2, ix3) && !bcArray->isUndefined(ix1, ix2, ix3))
+                     {
+                        cn.nodes.push_back(UbTupleInt3(ix1, ix2, ix3));
+                        numFluids++;
+                     }
+                     else if (bcArray->isSolid(ix1, ix2, ix3))
+                     {
+                        numSolids++;
+                     }
+                  }
+               }
+            }
+         }
+         if (cn.nodes.size() > 0)
+            cnodes.push_back(cn);
+      }
+   }
+   std::vector<double> rvalues;
+   std::vector<double> values;
+   values.push_back(numSolids);
+   values.push_back(numFluids);
+   rvalues = comm->gather(values);
+
+   if (root)
+   {
+      numberOfSolidNodes = 0.0;
+      numberOfFluidsNodes = 0.0;
+      int rsize = (int)rvalues.size();
+      int vsize = (int)values.size();
+      for (int i = 0; i < rsize; i += vsize)
+      {
+         numberOfSolidNodes += rvalues[i];
+         numberOfFluidsNodes += rvalues[i + 1];
+      }
+   }
+
+}
+//////////////////////////////////////////////////////////////////////////
+void IntegrateValuesHelper::prepare2DMatrix(int level)
+{
+   root = comm->isRoot();
+
+   double orgX1, orgX2, orgX3;
+   int gridRank = grid->getRank();
+   int minInitLevel, maxInitLevel;
+   if (level<0)
+   {
+      minInitLevel = this->grid->getCoarsestInitializedLevel();
+      maxInitLevel = this->grid->getFinestInitializedLevel();
+   }
+   else
+   {
+      minInitLevel = level;
+      maxInitLevel = level;
+   }
+   double dx = grid->getDeltaX(level);
+   CoordinateTransformation3D trafo(boundingBox->getX1Minimum(),boundingBox->getX2Minimum(),boundingBox->getX3Minimum(),dx,dx,dx);
+   cnodes2DMatrix.resize(UbMath::integerRounding<double>(boundingBox->getX1Maximum()/dx),UbMath::integerRounding<double>(boundingBox->getX2Maximum()/dx));
+
+   double numSolids = 0.0;
+   double numFluids = 0.0;
+   for (int level = minInitLevel; level<=maxInitLevel; level++)
+   {
+      std::vector<Block3DPtr> blockVector;
+      grid->getBlocks(level, gridRank, blockVector);
+      for(Block3DPtr block : blockVector)
+      {
+         Node cn;
+         cn.block = block;
+         //Koords bestimmen
+         UbTupleDouble3 org = grid->getBlockWorldCoordinates(block);
+
+         orgX1 = val<1>(org);
+         orgX2 = val<2>(org);
+         orgX3 = val<3>(org);
+
+         ILBMKernelPtr kernel = block->getKernel();
+         BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
+         int ghostLayerWitdh = kernel->getGhostLayerWidth();
+         DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();
+         double internX1, internX2, internX3;
+
+         double         dx = grid->getDeltaX(block);
+         UbTupleDouble3 orgDelta = grid->getNodeOffset(block);
+
+         for (int ix3 = ghostLayerWitdh; ix3<(int)distributions->getNX3()-ghostLayerWitdh; ix3++)
+         {
+            for (int ix2 = ghostLayerWitdh; ix2<(int)distributions->getNX2()-ghostLayerWitdh; ix2++)
+            {
+               for (int ix1 = ghostLayerWitdh; ix1<(int)distributions->getNX1()-ghostLayerWitdh; ix1++)
+               {
+                  internX1 = orgX1-val<1>(orgDelta)+ix1 * dx;
+                  internX2 = orgX2-val<2>(orgDelta)+ix2 * dx;
+                  internX3 = orgX3-val<3>(orgDelta)+ix3 * dx;
+                  if (boundingBox->isPointInGbObject3D(internX1, internX2, internX3))
+                  {
+                     if (!bcArray->isSolid(ix1, ix2, ix3)&&!bcArray->isUndefined(ix1, ix2, ix3))
+                     {
+                        cn.node = UbTupleInt3(ix1, ix2, ix3);
+                        int x1 = (int)trafo.transformForwardToX1Coordinate(internX1, internX2, internX3);
+                        int x2 = (int)trafo.transformForwardToX2Coordinate(internX1, internX2, internX3);
+                        cnodes2DMatrix(x1,x2)=cn;
+                        numFluids++;
+                     }
+                     else if (bcArray->isSolid(ix1, ix2, ix3))
+                     {
+                        numSolids++;
+                     }
+                  }
+               }
+            }
+         }
+
+      }
+   }
+   std::vector<double> rvalues;
+   std::vector<double> values;
+   values.push_back(numSolids);
+   values.push_back(numFluids);
+   rvalues = comm->gather(values);
+
+   if (root)
+   {
+      numberOfSolidNodes = 0.0;
+      numberOfFluidsNodes = 0.0;
+      int rsize = (int)rvalues.size();
+      int vsize = (int)values.size();
+      for (int i = 0; i<rsize; i += vsize)
+      {
+         numberOfSolidNodes += rvalues[i];
+         numberOfFluidsNodes += rvalues[i+1];
+      }
+   }
+
+}
+// calculation conventional rho, velocity and averaged data
+void IntegrateValuesHelper::calculateAV()
+{
+   clearData();
+
+   for(CalcNodes cn : cnodes)
+   {
+      ILBMKernelPtr kernel = cn.block->getKernel();
+      AverageValuesArray3DPtr averagedValues = kernel->getDataSet()->getAverageValues();
+
+      for(UbTupleInt3 node : cn.nodes)
+      {
+         double Avx = (*averagedValues)(val<1>(node), val<2>(node), val<3>(node), AvVx);
+         double Avy = (*averagedValues)(val<1>(node), val<2>(node), val<3>(node), AvVy);
+         double Avz = (*averagedValues)(val<1>(node), val<2>(node), val<3>(node), AvVz);
+
+         double Avxx = (*averagedValues)(val<1>(node), val<2>(node), val<3>(node), AvVxx);
+         double Avyy = (*averagedValues)(val<1>(node), val<2>(node), val<3>(node), AvVyy);
+         double Avzz = (*averagedValues)(val<1>(node), val<2>(node), val<3>(node), AvVzz);
+
+         double Avxz = (*averagedValues)(val<1>(node), val<2>(node), val<3>(node), AvVxz);
+         sAvVx1 += abs(Avx);
+         sAvVx2 += abs(Avy);
+         sAvVx3 += abs(Avz);
+
+         sTSx1 += sqrt(Avxx);
+         sTSx2 += sqrt(Avyy);
+         sTSx3 += sqrt(Avzz);
+
+         sTSx1x3 += Avxz;
+         numberOfFluidsNodes++;
+      }
+   }
+   std::vector<double> values;
+   std::vector<double> rvalues;
+   values.push_back(sAvVx1);
+   values.push_back(sAvVx2);
+   values.push_back(sAvVx3);
+   values.push_back(sTSx1);
+   values.push_back(sTSx2);
+   values.push_back(sTSx3);
+   values.push_back(sTSx1x3);
+   values.push_back(numberOfFluidsNodes);
+
+   rvalues = comm->gather(values);
+   if (root)
+   {
+      clearData();
+      for (int i = 0; i < (int)rvalues.size(); i += 8)
+      {
+         sAvVx1 += rvalues[i];
+         sAvVx2 += rvalues[i + 1];
+         sAvVx3 += rvalues[i + 2];
+         sTSx1 += rvalues[i + 3];
+         sTSx2 += rvalues[i + 4];
+         sTSx3 += rvalues[i + 5];
+         sTSx1x3 += rvalues[i + 6];
+         numberOfFluidsNodes += rvalues[i + 7];
+      }
+   }
+}
+// calculation conventional rho, velocity and averaged data
+void IntegrateValuesHelper::calculateAV2()
+{
+   saVx = 0;
+   saVy = 0;
+   saVz = 0;
+
+   saVxx = 0;
+   saVyy = 0;
+   saVzz = 0;
+   saVxy = 0;
+   saVxz = 0;
+   saVyz = 0;
+
+   saVxxx = 0;
+   saVxxy = 0;
+   saVxxz = 0;
+   saVyyy = 0;
+   saVyyx = 0;
+   saVyyz = 0;
+   saVzzz = 0;
+   saVzzx = 0;
+   saVzzy = 0;
+   saVxyz = 0;
+
+   double lsaVx = 0;
+   double lsaVy = 0;
+   double lsaVz = 0;
+
+   double lsaVxx = 0;
+   double lsaVyy = 0;
+   double lsaVzz = 0;
+   double lsaVxy = 0;
+   double lsaVxz = 0;
+   double lsaVyz = 0;
+
+   double lsaVxxx = 0;
+   double lsaVxxy = 0;
+   double lsaVxxz = 0;
+   double lsaVyyy = 0;
+   double lsaVyyx = 0;
+   double lsaVyyz = 0;
+   double lsaVzzz = 0;
+   double lsaVzzx = 0;
+   double lsaVzzy = 0;
+   double lsaVxyz = 0;
+
+   for(CalcNodes cn : cnodes)
+   {
+      ILBMKernelPtr kernel = cn.block->getKernel();
+      AverageValuesArray3DPtr averagedVelocity = kernel->getDataSet()->getAverageVelocity();
+      AverageValuesArray3DPtr averagedFluctuations = kernel->getDataSet()->getAverageFluctuations();
+      AverageValuesArray3DPtr averagedTriplecorrelations = kernel->getDataSet()->getAverageTriplecorrelations();
+
+      for(UbTupleInt3 node : cn.nodes)
+      {
+         double aVx = (*averagedVelocity)(Vx, val<1>(node), val<2>(node), val<3>(node));
+         double aVy = (*averagedVelocity)(Vy, val<1>(node), val<2>(node), val<3>(node));
+         double aVz = (*averagedVelocity)(Vz, val<1>(node), val<2>(node), val<3>(node));
+
+         double aVxx = (*averagedFluctuations)(Vxx, val<1>(node), val<2>(node), val<3>(node));
+         double aVyy = (*averagedFluctuations)(Vyy, val<1>(node), val<2>(node), val<3>(node));
+         double aVzz = (*averagedFluctuations)(Vzz, val<1>(node), val<2>(node), val<3>(node));
+         double aVxy = (*averagedFluctuations)(Vxy, val<1>(node), val<2>(node), val<3>(node));
+         double aVxz = (*averagedFluctuations)(Vxz, val<1>(node), val<2>(node), val<3>(node));
+         double aVyz = (*averagedFluctuations)(Vyz, val<1>(node), val<2>(node), val<3>(node));
+
+         double aVxxx = (*averagedTriplecorrelations)(Vxxx, val<1>(node), val<2>(node), val<3>(node));
+         double aVxxy = (*averagedTriplecorrelations)(Vxxy, val<1>(node), val<2>(node), val<3>(node));
+         double aVxxz = (*averagedTriplecorrelations)(Vxxz, val<1>(node), val<2>(node), val<3>(node));
+         double aVyyy = (*averagedTriplecorrelations)(Vyyy, val<1>(node), val<2>(node), val<3>(node));
+         double aVyyx = (*averagedTriplecorrelations)(Vyyx, val<1>(node), val<2>(node), val<3>(node));
+         double aVyyz = (*averagedTriplecorrelations)(Vyyz, val<1>(node), val<2>(node), val<3>(node));
+         double aVzzz = (*averagedTriplecorrelations)(Vzzz, val<1>(node), val<2>(node), val<3>(node));
+         double aVzzx = (*averagedTriplecorrelations)(Vzzx, val<1>(node), val<2>(node), val<3>(node));
+         double aVzzy = (*averagedTriplecorrelations)(Vzzy, val<1>(node), val<2>(node), val<3>(node));
+         double aVxyz = (*averagedTriplecorrelations)(Vxyz, val<1>(node), val<2>(node), val<3>(node));
+
+         lsaVx += aVx;
+         lsaVy += aVy;
+         lsaVz += aVz;
+
+         lsaVxx += aVxx;
+         lsaVyy += aVyy;
+         lsaVzz += aVzz;
+         lsaVxy += aVxy;
+         lsaVxz += aVxz;
+         lsaVyz += aVyz;
+
+         lsaVxxx += aVxxx;
+         lsaVxxy += aVxxy;
+         lsaVxxz += aVxxz;
+         lsaVyyy += aVyyy;
+         lsaVyyx += aVyyx;
+         lsaVyyz += aVyyz;
+         lsaVzzz += aVzzz;
+         lsaVzzx += aVzzx;
+         lsaVzzy += aVzzy;
+         lsaVxyz += aVxyz;
+
+         //numberOfFluidsNodes++;
+      }
+   }
+   std::vector<double> values;
+   std::vector<double> rvalues;
+   values.push_back(lsaVx);
+   values.push_back(lsaVy);
+   values.push_back(lsaVz);
+
+   values.push_back(lsaVxx);
+   values.push_back(lsaVyy);
+   values.push_back(lsaVzz);
+   values.push_back(lsaVxy);
+   values.push_back(lsaVxz);
+   values.push_back(lsaVyz);
+
+   values.push_back(lsaVxxx);
+   values.push_back(lsaVxxy);
+   values.push_back(lsaVxxz);
+   values.push_back(lsaVyyy);
+   values.push_back(lsaVyyx);
+   values.push_back(lsaVyyz);
+   values.push_back(lsaVzzz);
+   values.push_back(lsaVzzx);
+   values.push_back(lsaVzzy);
+   values.push_back(lsaVxyz);
+
+   rvalues = comm->gather(values);
+   if (root)
+   {
+      for (int i = 0; i < (int)rvalues.size(); i += 19)
+      {
+         saVx += rvalues[i];
+         saVy += rvalues[i + 1];
+         saVz += rvalues[i + 2];
+
+         saVxx += rvalues[i + 3];
+         saVyy += rvalues[i + 4];
+         saVzz += rvalues[i + 5];
+         saVxy += rvalues[i + 6];
+         saVxz += rvalues[i + 7];
+         saVyz += rvalues[i + 8];
+
+         saVxxx += rvalues[i + 9];
+         saVxxy += rvalues[i + 10];
+         saVxxz += rvalues[i + 11];
+         saVyyy += rvalues[i + 12];
+         saVyyx += rvalues[i + 13];
+         saVyyz += rvalues[i + 14];
+         saVzzz += rvalues[i + 15];
+         saVzzx += rvalues[i + 16];
+         saVzzy += rvalues[i + 17];
+         saVxyz += rvalues[i + 18];
+
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void IntegrateValuesHelper::calculateMQ()
+{
+   LBMReal f[D3Q27System::ENDF + 1];
+   LBMReal vx1, vx2, vx3, rho;
+   clearData();
+
+   //Funktionszeiger
+   typedef void(*CalcMacrosFct)(const LBMReal* const& /*feq[27]*/, LBMReal& /*(d)rho*/, LBMReal& /*vx1*/, LBMReal& /*vx2*/, LBMReal& /*vx3*/);
+
+   CalcMacrosFct calcMacros = NULL;
+
+   for(CalcNodes cn : cnodes)
+   {
+      ILBMKernelPtr kernel = cn.block->getKernel();
+      LBMReal dx = 1.0 / (LBMReal)(1 << cn.block->getLevel());
+      LBMReal cellVolume = dx*dx*dx;
+
+      if (kernel->getCompressible())
+      {
+         calcMacros = &D3Q27System::calcCompMacroscopicValues;
+      }
+      else
+      {
+         calcMacros = &D3Q27System::calcIncompMacroscopicValues;
+      }
+
+      BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
+      DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();
+      for(UbTupleInt3 node : cn.nodes)
+      {
+         distributions->getDistribution(f, val<1>(node), val<2>(node), val<3>(node));
+         calcMacros(f, rho, vx1, vx2, vx3);
+         sRho += rho*cellVolume;
+         sVx1 += vx1*cellVolume;
+         sVx2 += vx2*cellVolume;
+         sVx3 += vx3*cellVolume;
+         sCellVolume += cellVolume;
+      }
+   }
+   std::vector<double> values(5);
+   std::vector<double> rvalues;
+   values[0] = sRho;
+   values[1] = sVx1;
+   values[2] = sVx2;
+   values[3] = sVx3;
+   values[4] = sCellVolume;
+
+   rvalues = comm->gather(values);
+   if (root)
+   {
+      clearData();
+      int rsize = (int)rvalues.size();
+      int vsize = (int)values.size();
+      for (int i = 0; i < rsize; i += vsize)
+      {
+         sRho += rvalues[i];
+         sVx1 += rvalues[i + 1];
+         sVx2 += rvalues[i + 2];
+         sVx3 += rvalues[i + 3];
+         sCellVolume += rvalues[i + 4];
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void IntegrateValuesHelper::clearData()
+{
+   sRho = 0.0;
+   sVx1 = 0.0;
+   sVx2 = 0.0;
+   sVx3 = 0.0;
+   sCellVolume = 0.0;
+   //sVm = 0.0;
+   //sPress = 0.0;
+   //numberOfFluidsNodes = 0.0;
+   sAvVx1 = 0.0;
+   sAvVx2 = 0.0;
+   sAvVx3 = 0.0;
+   sTSx1 = 0.0;
+   sTSx2 = 0.0;
+   sTSx3 = 0.0;
+   sTSx1x3 = 0.0;
+}
+//////////////////////////////////////////////////////////////////////////
+LBMReal IntegrateValuesHelper::getNumberOfFluidsNodes()
+{
+   return this->numberOfFluidsNodes;
+}
+//////////////////////////////////////////////////////////////////////////
+LBMReal IntegrateValuesHelper::getNumberOfSolidNodes()
+{
+   return this->numberOfSolidNodes;
+}
+//////////////////////////////////////////////////////////////////////////
+GbCuboid3DPtr IntegrateValuesHelper::getBoundingBox()
+{
+   return this->boundingBox;
+}
+//////////////////////////////////////////////////////////////////////////
+std::vector<IntegrateValuesHelper::CalcNodes> IntegrateValuesHelper::getCNodes()
+{
+   return cnodes;
+}
diff --git a/source/VirtualFluidsCore/CoProcessors/IntegrateValuesHelper.h b/source/VirtualFluidsCore/CoProcessors/IntegrateValuesHelper.h
index 3c1e1a204..9573b1bf6 100644
--- a/source/VirtualFluidsCore/CoProcessors/IntegrateValuesHelper.h
+++ b/source/VirtualFluidsCore/CoProcessors/IntegrateValuesHelper.h
@@ -6,6 +6,7 @@
 #include "Communicator.h"
 #include "GbCuboid3D.h"
 #include "CbArray2D.h"
+#include "Block3D.h"
 
 //struct CalcNodes 
 //{
@@ -20,7 +21,7 @@
 //};
 
 class IntegrateValuesHelper;
-typedef boost::shared_ptr<IntegrateValuesHelper> IntegrateValuesHelperPtr;
+typedef std::shared_ptr<IntegrateValuesHelper> IntegrateValuesHelperPtr;
 
 class IntegrateValuesHelper
 {
diff --git a/source/VirtualFluidsCore/CoProcessors/LineTimeSeriesCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/LineTimeSeriesCoProcessor.cpp
index 8210430d2..e6b9f0cb1 100644
--- a/source/VirtualFluidsCore/CoProcessors/LineTimeSeriesCoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/LineTimeSeriesCoProcessor.cpp
@@ -1,237 +1,247 @@
-#include "LineTimeSeriesCoProcessor.h"
-#include "BCProcessor.h"
-#include "WbWriterVtkXmlASCII.h"
-
-LineTimeSeriesCoProcessor::LineTimeSeriesCoProcessor(Grid3DPtr grid, UbSchedulerPtr s, const std::string& path, GbLine3DPtr line, int level, CommunicatorPtr comm) :
-   CoProcessor(grid, s),
-   path(path),
-   length(0),
-   ix1(0),
-   ix2(0),
-   ix3(0),
-   level(level),
-   line(line)
-{
-   root = comm->isRoot();
-   fname = path;
-   
-   mpi_comm = *((MPI_Comm*)comm->getNativeCommunicator());
-   numOfProc = comm->getNumberOfProcesses();
-   gridRank = comm->getProcessID();
-
-   double dx = CoProcessor::grid->getDeltaX(level);
-
-   CoordinateTransformation3DPtr trafo = grid->getCoordinateTransformator();
-   double orgX1 = trafo->getX1CoordinateOffset();
-   double orgX2 = trafo->getX2CoordinateOffset();
-   double orgX3 = trafo->getX3CoordinateOffset();
-
-
-   int x1min = (int)((line->getX1Minimum()-orgX1)/dx);
-   int x1max = (int)((line->getX1Maximum()-orgX1)/dx);
-   int x2min = (int)((line->getX2Minimum()-orgX2)/dx);
-   int x2max = (int)((line->getX2Maximum()-orgX2)/dx);
-   int x3min = (int)((line->getX3Minimum()-orgX3)/dx);
-   int x3max = (int)((line->getX3Maximum()-orgX3)/dx);
-
-   UbTupleInt3 blockNx = grid->getBlockNX();
-
-   if (x1min!=x1max)
-   {
-      dir = X1;
-      blocknx = val<1>(blockNx);
-      length = x1max;
-   }
-   else if (x2min!=x2max)
-   {
-      dir = X2;
-      blocknx = val<2>(blockNx);
-      length = x2max;
-   }
-   else if (x3min!=x3max)
-   {
-      dir = X3;
-      blocknx = val<3>(blockNx);
-      length = x3max;
-   }
-   blockix1 = x1min/val<1>(blockNx);
-   blockix2 = x2min/val<2>(blockNx);
-   blockix3 = x3min/val<3>(blockNx);
-
-   ix1 = x1min%val<1>(blockNx)+1;
-   ix2 = x2min%val<2>(blockNx)+1;
-   ix3 = x3min%val<3>(blockNx)+1;
-}
-//////////////////////////////////////////////////////////////////////////
-void LineTimeSeriesCoProcessor::process(double step)
-{
-   if (scheduler->isDue(step))
-   {
-      collectData();
-   }
-
-   UBLOG(logDEBUG3, "MacroscopicQuantitiesCoProcessor::update:"<<step);
-}
-//////////////////////////////////////////////////////////////////////////
-void LineTimeSeriesCoProcessor::writeLine(const std::string& path)
-{
-   std::vector<UbTupleFloat3 > nodes(2); 
-   std::vector<UbTupleInt2 > lines(1);
-   val<1>(nodes[0]) = (float)line->getX1Minimum();
-   val<2>(nodes[0]) = (float)line->getX2Minimum();
-   val<3>(nodes[0]) = (float)line->getX3Minimum();
-   val<1>(nodes[1]) = (float)line->getX1Maximum();
-   val<2>(nodes[1]) = (float)line->getX2Maximum();
-   val<3>(nodes[1]) = (float)line->getX3Maximum();
-   val<1>(lines[0]) = 0;
-   val<1>(lines[0]) = 1;
-   WbWriterVtkXmlASCII *writer = WbWriterVtkXmlASCII::getInstance();
-   writer->writeLines(path, nodes, lines);
-}
-//////////////////////////////////////////////////////////////////////////
-void LineTimeSeriesCoProcessor::collectData()
-{
-   LBMReal f[27];
-   LBMReal vx1, vx2, vx3, rho;
-   MPI_Status    status;
-   std::vector<double> v1(length, 0);
-   std::vector<double> v2(length, 0);
-   std::vector<double> v3(length, 0);
-   std::vector<double>  p(length, 0);
-   for (int x = 0; x<length; x += blocknx)
-   {
-      if (dir == X1)
-      {
-         blockix1 = x/blocknx;
-      }
-      else if (dir == X2)
-      {
-         blockix2 = x/blocknx;
-      }
-      else if (dir == X3)
-      {
-         blockix3 = x/blocknx;
-      }
-
-      Block3DPtr block = CoProcessor::grid->getBlock(blockix1, blockix2, blockix3, level);
-      if (block)
-      {
-         if (block->getRank()==gridRank)
-         {
-            LBMKernelPtr kernel = block->getKernel();
-            calcMacros = NULL;
-            if (kernel->getCompressible())
-            {
-               calcMacros = &D3Q27System::calcCompMacroscopicValues;
-            }
-            else
-            {
-               calcMacros = &D3Q27System::calcIncompMacroscopicValues;
-            }
-            DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();
-
-            for (int ix = 1; ix<=blocknx; ix++)
-            {
-               if (dir==X1)
-               {
-                  ix1 = ix;
-               }
-               else if (dir==X2)
-               {
-                  ix2 = ix;
-               }
-               else if (dir==X3)
-               {
-                  ix3 = ix;
-               }
-               distributions->getDistribution(f, ix1, ix2, ix3);
-               calcMacros(f, rho, vx1, vx2, vx3);
-               v1[x+(ix-1)] = vx1;
-               v2[x+(ix-1)] = vx2;
-               v3[x+(ix-1)] = vx3;
-                p[x+(ix-1)] = rho;
-            }
-         }
-      }
-
-   }
-
-   if (root)
-   {
-      for (int i = 1; i<numOfProc; i++)
-      {
-         std::vector<double> v1temp(length, 0);
-         std::vector<double> v2temp(length, 0);
-         std::vector<double> v3temp(length, 0);
-         std::vector<double>  ptemp(length, 0);
-         MPI_Recv(&v1temp[0], length, MPI_DOUBLE, i, 1, mpi_comm, &status);
-         MPI_Recv(&v2temp[0], length, MPI_DOUBLE, i, 2, mpi_comm, &status);
-         MPI_Recv(&v3temp[0], length, MPI_DOUBLE, i, 3, mpi_comm, &status);
-         MPI_Recv( &ptemp[0], length, MPI_DOUBLE, i, 4, mpi_comm, &status);
-         for (int j = 0; j<length; j++)
-         {
-            v1[j] += v1temp[j];
-            v2[j] += v2temp[j];
-            v3[j] += v3temp[j];
-             p[j] +=  ptemp[j];
-         }
-      }
-
-      std::ofstream ostr;
-      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|std::ios_base::app); }
-         if (!ostr) throw UbException(UB_EXARGS, "couldn't open file "+fname);
-      }
-
-      for (int x = 0; x<length; x++)
-      {
-         ostr<<v1[x];
-         if (x<length-1)
-         {
-            ostr<<";";
-         }
-      }
-      ostr<<"\n";
-      for (int x = 0; x<length; x++)
-      {
-         ostr<<v2[x];
-         if (x<length-1)
-         {
-            ostr<<";";
-         }
-      }
-      ostr<<"\n";
-      for (int x = 0; x<length; x++)
-      {
-         ostr<<v3[x];
-         if (x<length-1)
-         {
-            ostr<<";";
-         }
-      }
-      ostr<<"\n";
-      for (int x = 0; x<length; x++)
-      {
-         ostr<<p[x];
-         if (x<length-1)
-         {
-            ostr<<";";
-         }
-      }
-      ostr<<"\n";
-      ostr.close();
-   }
-   else
-   {
-      MPI_Send(&v1[0], length, MPI_DOUBLE, 0, 1, mpi_comm);
-      MPI_Send(&v2[0], length, MPI_DOUBLE, 0, 2, mpi_comm);
-      MPI_Send(&v3[0], length, MPI_DOUBLE, 0, 3, mpi_comm);
-      MPI_Send( &p[0], length, MPI_DOUBLE, 0, 4, mpi_comm);
-   }
-}
-
-
+#include "LineTimeSeriesCoProcessor.h"
+#include "BCProcessor.h"
+#include "WbWriterVtkXmlASCII.h"
+
+#include "DataSet3D.h"
+#include "LBMKernel.h"
+#include "CoordinateTransformation3D.h"
+#include "Block3D.h"
+#include "GbLine3D.h"
+#include "UbScheduler.h"
+#include "Grid3D.h"
+#include "Communicator.h"
+#include "CompressibleCumulantLBMKernel.h"
+
+LineTimeSeriesCoProcessor::LineTimeSeriesCoProcessor(Grid3DPtr grid, UbSchedulerPtr s, const std::string& path, GbLine3DPtr line, int level, CommunicatorPtr comm) :
+   CoProcessor(grid, s),
+   path(path),
+   length(0),
+   ix1(0),
+   ix2(0),
+   ix3(0),
+   level(level),
+   line(line)
+{
+   root = comm->isRoot();
+   fname = path;
+   
+   mpi_comm = *((MPI_Comm*)comm->getNativeCommunicator());
+   numOfProc = comm->getNumberOfProcesses();
+   gridRank = comm->getProcessID();
+
+   double dx = CoProcessor::grid->getDeltaX(level);
+
+   CoordinateTransformation3DPtr trafo = grid->getCoordinateTransformator();
+   double orgX1 = trafo->getX1CoordinateOffset();
+   double orgX2 = trafo->getX2CoordinateOffset();
+   double orgX3 = trafo->getX3CoordinateOffset();
+
+
+   int x1min = (int)((line->getX1Minimum()-orgX1)/dx);
+   int x1max = (int)((line->getX1Maximum()-orgX1)/dx);
+   int x2min = (int)((line->getX2Minimum()-orgX2)/dx);
+   int x2max = (int)((line->getX2Maximum()-orgX2)/dx);
+   int x3min = (int)((line->getX3Minimum()-orgX3)/dx);
+   int x3max = (int)((line->getX3Maximum()-orgX3)/dx);
+
+   UbTupleInt3 blockNx = grid->getBlockNX();
+
+   if (x1min!=x1max)
+   {
+      dir = X1;
+      blocknx = val<1>(blockNx);
+      length = x1max;
+   }
+   else if (x2min!=x2max)
+   {
+      dir = X2;
+      blocknx = val<2>(blockNx);
+      length = x2max;
+   }
+   else if (x3min!=x3max)
+   {
+      dir = X3;
+      blocknx = val<3>(blockNx);
+      length = x3max;
+   }
+   blockix1 = x1min/val<1>(blockNx);
+   blockix2 = x2min/val<2>(blockNx);
+   blockix3 = x3min/val<3>(blockNx);
+
+   ix1 = x1min%val<1>(blockNx)+1;
+   ix2 = x2min%val<2>(blockNx)+1;
+   ix3 = x3min%val<3>(blockNx)+1;
+}
+//////////////////////////////////////////////////////////////////////////
+void LineTimeSeriesCoProcessor::process(double step)
+{
+   if (scheduler->isDue(step))
+   {
+      collectData();
+   }
+
+   UBLOG(logDEBUG3, "MacroscopicQuantitiesCoProcessor::update:"<<step);
+}
+//////////////////////////////////////////////////////////////////////////
+void LineTimeSeriesCoProcessor::writeLine(const std::string& path)
+{
+   std::vector<UbTupleFloat3 > nodes(2); 
+   std::vector<UbTupleInt2 > lines(1);
+   val<1>(nodes[0]) = (float)line->getX1Minimum();
+   val<2>(nodes[0]) = (float)line->getX2Minimum();
+   val<3>(nodes[0]) = (float)line->getX3Minimum();
+   val<1>(nodes[1]) = (float)line->getX1Maximum();
+   val<2>(nodes[1]) = (float)line->getX2Maximum();
+   val<3>(nodes[1]) = (float)line->getX3Maximum();
+   val<1>(lines[0]) = 0;
+   val<1>(lines[0]) = 1;
+   WbWriterVtkXmlASCII *writer = WbWriterVtkXmlASCII::getInstance();
+   writer->writeLines(path, nodes, lines);
+}
+//////////////////////////////////////////////////////////////////////////
+void LineTimeSeriesCoProcessor::collectData()
+{
+   LBMReal f[27];
+   LBMReal vx1, vx2, vx3, rho;
+   MPI_Status    status;
+   std::vector<double> v1(length, 0);
+   std::vector<double> v2(length, 0);
+   std::vector<double> v3(length, 0);
+   std::vector<double>  p(length, 0);
+   for (int x = 0; x<length; x += blocknx)
+   {
+      if (dir == X1)
+      {
+         blockix1 = x/blocknx;
+      }
+      else if (dir == X2)
+      {
+         blockix2 = x/blocknx;
+      }
+      else if (dir == X3)
+      {
+         blockix3 = x/blocknx;
+      }
+
+      Block3DPtr block = CoProcessor::grid->getBlock(blockix1, blockix2, blockix3, level);
+      if (block)
+      {
+         if (block->getRank()==gridRank)
+         {
+             ILBMKernelPtr kernel = block->getKernel();
+            calcMacros = NULL;
+            if (kernel->getCompressible())
+            {
+               calcMacros = &D3Q27System::calcCompMacroscopicValues;
+            }
+            else
+            {
+               calcMacros = &D3Q27System::calcIncompMacroscopicValues;
+            }
+            DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();
+
+            for (int ix = 1; ix<=blocknx; ix++)
+            {
+               if (dir==X1)
+               {
+                  ix1 = ix;
+               }
+               else if (dir==X2)
+               {
+                  ix2 = ix;
+               }
+               else if (dir==X3)
+               {
+                  ix3 = ix;
+               }
+               distributions->getDistribution(f, ix1, ix2, ix3);
+               calcMacros(f, rho, vx1, vx2, vx3);
+               v1[x+(ix-1)] = vx1;
+               v2[x+(ix-1)] = vx2;
+               v3[x+(ix-1)] = vx3;
+                p[x+(ix-1)] = rho;
+            }
+         }
+      }
+
+   }
+
+   if (root)
+   {
+      for (int i = 1; i<numOfProc; i++)
+      {
+         std::vector<double> v1temp(length, 0);
+         std::vector<double> v2temp(length, 0);
+         std::vector<double> v3temp(length, 0);
+         std::vector<double>  ptemp(length, 0);
+         MPI_Recv(&v1temp[0], length, MPI_DOUBLE, i, 1, mpi_comm, &status);
+         MPI_Recv(&v2temp[0], length, MPI_DOUBLE, i, 2, mpi_comm, &status);
+         MPI_Recv(&v3temp[0], length, MPI_DOUBLE, i, 3, mpi_comm, &status);
+         MPI_Recv( &ptemp[0], length, MPI_DOUBLE, i, 4, mpi_comm, &status);
+         for (int j = 0; j<length; j++)
+         {
+            v1[j] += v1temp[j];
+            v2[j] += v2temp[j];
+            v3[j] += v3temp[j];
+             p[j] +=  ptemp[j];
+         }
+      }
+
+      std::ofstream ostr;
+      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|std::ios_base::app); }
+         if (!ostr) throw UbException(UB_EXARGS, "couldn't open file "+fname);
+      }
+
+      for (int x = 0; x<length; x++)
+      {
+         ostr<<v1[x];
+         if (x<length-1)
+         {
+            ostr<<";";
+         }
+      }
+      ostr<<"\n";
+      for (int x = 0; x<length; x++)
+      {
+         ostr<<v2[x];
+         if (x<length-1)
+         {
+            ostr<<";";
+         }
+      }
+      ostr<<"\n";
+      for (int x = 0; x<length; x++)
+      {
+         ostr<<v3[x];
+         if (x<length-1)
+         {
+            ostr<<";";
+         }
+      }
+      ostr<<"\n";
+      for (int x = 0; x<length; x++)
+      {
+         ostr<<p[x];
+         if (x<length-1)
+         {
+            ostr<<";";
+         }
+      }
+      ostr<<"\n";
+      ostr.close();
+   }
+   else
+   {
+      MPI_Send(&v1[0], length, MPI_DOUBLE, 0, 1, mpi_comm);
+      MPI_Send(&v2[0], length, MPI_DOUBLE, 0, 2, mpi_comm);
+      MPI_Send(&v3[0], length, MPI_DOUBLE, 0, 3, mpi_comm);
+      MPI_Send( &p[0], length, MPI_DOUBLE, 0, 4, mpi_comm);
+   }
+}
+
+
diff --git a/source/VirtualFluidsCore/CoProcessors/LineTimeSeriesCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/LineTimeSeriesCoProcessor.h
index 9cedcfdde..53b47768b 100644
--- a/source/VirtualFluidsCore/CoProcessors/LineTimeSeriesCoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/LineTimeSeriesCoProcessor.h
@@ -1,9 +1,18 @@
 #ifndef LineTimeSeriesCoProcessor_h__
 #define LineTimeSeriesCoProcessor_h__
 
+#include <memory>
+#include <string>
+
+#include <mpi.h>
+
 #include "CoProcessor.h"
-#include "GbLine3D.h"
-#include "MPICommunicator.h"
+#include "LBMSystem.h"
+
+class Communicator;
+class Grid3D;
+class UbScheduler;
+class GbLine3D;
 
 //! \brief  Writes to .csv file time series for a line in x1 direction.
 //! \details It can be used to compute for given time range  the time averaged two-point correlations for a line. <br>
@@ -16,17 +25,19 @@ class LineTimeSeriesCoProcessor : public CoProcessor
 public:
 enum Direction {X1, X2, X3};
 public:
-   LineTimeSeriesCoProcessor(Grid3DPtr grid, UbSchedulerPtr s, const std::string& path, GbLine3DPtr line, int level, CommunicatorPtr comm);
+   LineTimeSeriesCoProcessor(std::shared_ptr<Grid3D> grid, std::shared_ptr<UbScheduler> s, const std::string& path, std::shared_ptr<GbLine3D> line, int level,std::shared_ptr<Communicator> comm);
    ~LineTimeSeriesCoProcessor(){}
-   void process(double step);
+
+   void process(double step) override;
    void writeLine(const std::string& path);
+
 protected:
    void collectData();
 private:
    std::string path;
    std::string fname;
    bool root;
-   GbLine3DPtr line;
+   std::shared_ptr<GbLine3D> line;
    //function pointer
    typedef void(*CalcMacrosFct)(const LBMReal* const& /*feq[27]*/, LBMReal& /*(d)rho*/, LBMReal& /*vx1*/, LBMReal& /*vx2*/, LBMReal& /*vx3*/);
    CalcMacrosFct calcMacros;
diff --git a/source/VirtualFluidsCore/CoProcessors/MPIIORestart11CoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/MPIIORestart11CoProcessor.cpp
index 34cf47802..b63477019 100644
--- a/source/VirtualFluidsCore/CoProcessors/MPIIORestart11CoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/MPIIORestart11CoProcessor.cpp
@@ -8,6 +8,12 @@
 #include "D3Q27EsoTwist3DSplittedVector.h"
 #include <UbSystem.h>
 #include <MemoryUtil.h>
+#include "BoundaryConditions.h"
+#include "Block3D.h"
+#include "CoordinateTransformation3D.h"
+#include "DataSet3D.h"
+#include "Grid3D.h"
+#include "BCArray3D.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 
@@ -261,7 +267,7 @@ void MPIIORestart11CoProcessor::writeBlocks(int step)
    int ic = 0;
    for (int level = minInitLevel; level<=maxInitLevel; level++)
    {
-      BOOST_FOREACH(Block3DPtr block, blocksVector[level])  //	all the blocks of the current level
+      for(Block3DPtr block : blocksVector[level])  //	all the blocks of the current level
       {
          // save data describing the block
          block3dArray[ic].x1 = block->getX1();
@@ -362,7 +368,7 @@ void MPIIORestart11CoProcessor::writeDataSet(int step)
    int ic = 0;
    for (int level = minInitLevel; level<=maxInitLevel; level++)
    {
-      BOOST_FOREACH(Block3DPtr block, blocksVector[level])  //	blocks of the current level
+      for(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();
@@ -398,7 +404,7 @@ void MPIIORestart11CoProcessor::writeDataSet(int step)
 
          if (firstBlock /*&& block->getKernel()*/) // when first (any) valid block...
          {
-            boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > averageDensityArray = block->getKernel()->getDataSet()->getAverageDencity();
+            std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > averageDensityArray = block->getKernel()->getDataSet()->getAverageDencity();
             if (averageDensityArray)
             {
                dataSetParamStr.nx[0][0] = static_cast<int>(averageDensityArray->getNX1());
@@ -407,7 +413,7 @@ void MPIIORestart11CoProcessor::writeDataSet(int step)
                dataSetParamStr.nx[0][3] = static_cast<int>(averageDensityArray->getNX4());
             }
 
-            boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageVelocityArray3DPtr = block->getKernel()->getDataSet()->getAverageVelocity();
+            std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageVelocityArray3DPtr = block->getKernel()->getDataSet()->getAverageVelocity();
             if (AverageVelocityArray3DPtr)
             {
                dataSetParamStr.nx[1][0] = static_cast<int>(AverageVelocityArray3DPtr->getNX1());
@@ -416,7 +422,7 @@ void MPIIORestart11CoProcessor::writeDataSet(int step)
                dataSetParamStr.nx[1][3] = static_cast<int>(AverageVelocityArray3DPtr->getNX4());
             }
 
-            boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageFluctArray3DPtr = block->getKernel()->getDataSet()->getAverageFluctuations();
+            std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageFluctArray3DPtr = block->getKernel()->getDataSet()->getAverageFluctuations();
             if (AverageFluctArray3DPtr)
             {
                dataSetParamStr.nx[2][0] = static_cast<int>(AverageFluctArray3DPtr->getNX1());
@@ -425,7 +431,7 @@ void MPIIORestart11CoProcessor::writeDataSet(int step)
                dataSetParamStr.nx[2][3] = static_cast<int>(AverageFluctArray3DPtr->getNX4());
             }
 
-            boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageTripleArray3DPtr = block->getKernel()->getDataSet()->getAverageTriplecorrelations();
+            std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageTripleArray3DPtr = block->getKernel()->getDataSet()->getAverageTriplecorrelations();
             if (AverageTripleArray3DPtr)
             {
                dataSetParamStr.nx[3][0] = static_cast<int>(AverageTripleArray3DPtr->getNX1());
@@ -434,7 +440,7 @@ void MPIIORestart11CoProcessor::writeDataSet(int step)
                dataSetParamStr.nx[3][3] = static_cast<int>(AverageTripleArray3DPtr->getNX4());
             }
 
-            boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > ShearStressValArray3DPtr = block->getKernel()->getDataSet()->getShearStressValues();
+            std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > ShearStressValArray3DPtr = block->getKernel()->getDataSet()->getShearStressValues();
             if (ShearStressValArray3DPtr)
             {
                dataSetParamStr.nx[4][0] = static_cast<int>(ShearStressValArray3DPtr->getNX1());
@@ -443,7 +449,7 @@ void MPIIORestart11CoProcessor::writeDataSet(int step)
                dataSetParamStr.nx[4][3] = static_cast<int>(ShearStressValArray3DPtr->getNX4());
             }
 
-            boost::shared_ptr< CbArray3D<LBMReal, IndexerX3X2X1> > relaxationFactor3DPtr = block->getKernel()->getDataSet()->getRelaxationFactor();
+            std::shared_ptr< CbArray3D<LBMReal, IndexerX3X2X1> > relaxationFactor3DPtr = block->getKernel()->getDataSet()->getRelaxationFactor();
             if (relaxationFactor3DPtr)
             {
                dataSetParamStr.nx[5][0] = static_cast<int>(relaxationFactor3DPtr->getNX1());
@@ -452,7 +458,7 @@ void MPIIORestart11CoProcessor::writeDataSet(int step)
                dataSetParamStr.nx[5][3] = 1;
             }
 
-            boost::shared_ptr< D3Q27EsoTwist3DSplittedVector > D3Q27EsoTwist3DSplittedVectorPtr = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(block->getKernel()->getDataSet()->getFdistributions());
+            std::shared_ptr< D3Q27EsoTwist3DSplittedVector > D3Q27EsoTwist3DSplittedVectorPtr = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(block->getKernel()->getDataSet()->getFdistributions());
             CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getLocalDistributions();
             if (localDistributions)
             {
@@ -503,31 +509,31 @@ void MPIIORestart11CoProcessor::writeDataSet(int step)
          }
          //std::cout << ",doubleCountInBlock="<<dataSetParamStr.doubleCountInBlock<< "," << dataSetParamStr.nx1 << "," << dataSetParamStr.nx2 << "," << dataSetParamStr.nx3 << std::endl;
 
-         boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageValuesArray3DPtr = block->getKernel()->getDataSet()->getAverageDencity();
+         std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageValuesArray3DPtr = block->getKernel()->getDataSet()->getAverageDencity();
          if (AverageValuesArray3DPtr&&(dataSetParamStr.nx[0][0]>0)&&(dataSetParamStr.nx[0][1]>0)&&(dataSetParamStr.nx[0][2]>0)&&(dataSetParamStr.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();
+         std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageVelocityArray3DPtr = block->getKernel()->getDataSet()->getAverageVelocity();
          if (AverageVelocityArray3DPtr&&(dataSetParamStr.nx[1][0]>0)&&(dataSetParamStr.nx[1][1]>0)&&(dataSetParamStr.nx[1][2]>0)&&(dataSetParamStr.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();
+         std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageFluctArray3DPtr = block->getKernel()->getDataSet()->getAverageFluctuations();
          if (AverageFluctArray3DPtr&&(dataSetParamStr.nx[2][0]>0)&&(dataSetParamStr.nx[2][1]>0)&&(dataSetParamStr.nx[2][2]>0)&&(dataSetParamStr.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();
+         std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageTripleArray3DPtr = block->getKernel()->getDataSet()->getAverageTriplecorrelations();
          if (AverageTripleArray3DPtr&&(dataSetParamStr.nx[3][0]>0)&&(dataSetParamStr.nx[3][1]>0)&&(dataSetParamStr.nx[3][2]>0)&&(dataSetParamStr.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();
+         std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > ShearStressValArray3DPtr = block->getKernel()->getDataSet()->getShearStressValues();
          if (ShearStressValArray3DPtr&&(dataSetParamStr.nx[4][0]>0)&&(dataSetParamStr.nx[4][1]>0)&&(dataSetParamStr.nx[4][2]>0)&&(dataSetParamStr.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();
+         std::shared_ptr< CbArray3D<LBMReal, IndexerX3X2X1> > RelaxationFactor3DPtr = block->getKernel()->getDataSet()->getRelaxationFactor();
          if (RelaxationFactor3DPtr&&(dataSetParamStr.nx[5][0]>0)&&(dataSetParamStr.nx[5][1]>0)&&(dataSetParamStr.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());
+         std::shared_ptr< D3Q27EsoTwist3DSplittedVector > D3Q27EsoTwist3DSplittedVectorPtr = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(block->getKernel()->getDataSet()->getFdistributions());
          CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getLocalDistributions();
          if (localDistributions&&(dataSetParamStr.nx[6][0]>0)&&(dataSetParamStr.nx[6][1]>0)&&(dataSetParamStr.nx[6][2]>0)&&(dataSetParamStr.nx[6][3]>0))
             doubleValuesArray.insert(doubleValuesArray.end(), localDistributions->getDataVector().begin(), localDistributions->getDataVector().end());
@@ -658,7 +664,7 @@ void MPIIORestart11CoProcessor::writeBoundaryConds(int step)
    int ic = 0;
    for (int level = minInitLevel; level<=maxInitLevel; level++)
    {
-      BOOST_FOREACH(Block3DPtr block, blocksVector[level])  // all the blocks of the current level
+      for(Block3DPtr block : blocksVector[level])  // all the blocks of the current level
       {
          BCArray3DPtr bcArr = block->getKernel()->getBCProcessor()->getBCArray();
 
@@ -902,7 +908,7 @@ void MPIIORestart11CoProcessor::readBlocks(int step)
    std::vector<Block3DPtr> blocksVector;
    grid->getBlocks(0, blocksVector);
    int del = 0;
-   BOOST_FOREACH(Block3DPtr block, blocksVector)
+   for(Block3DPtr block : blocksVector)
    {
       grid->deleteBlock(block);
       del++;
@@ -1160,13 +1166,13 @@ void MPIIORestart11CoProcessor::readDataSet(int step)
       //DistributionArray3DPtr mFdistributions(new D3Q27EsoTwist3DSplittedVector(dataSetParamStr.nx1, dataSetParamStr.nx2, dataSetParamStr.nx3, -999.0));
       DistributionArray3DPtr mFdistributions(new D3Q27EsoTwist3DSplittedVector());
 
-      boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[6], dataSetParamStr.nx[6][0], dataSetParamStr.nx[6][1], dataSetParamStr.nx[6][2], dataSetParamStr.nx[6][3])));
-      boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNonLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[7], dataSetParamStr.nx[7][0], dataSetParamStr.nx[7][1], dataSetParamStr.nx[7][2], dataSetParamStr.nx[7][3])));
-      boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setZeroDistributions(CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<LBMReal, IndexerX3X2X1>(vectorsOfValues[8], dataSetParamStr.nx[8][0], dataSetParamStr.nx[8][1], dataSetParamStr.nx[8][2])));
+      std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[6], dataSetParamStr.nx[6][0], dataSetParamStr.nx[6][1], dataSetParamStr.nx[6][2], dataSetParamStr.nx[6][3])));
+      std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNonLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[7], dataSetParamStr.nx[7][0], dataSetParamStr.nx[7][1], dataSetParamStr.nx[7][2], dataSetParamStr.nx[7][3])));
+      std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setZeroDistributions(CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<LBMReal, IndexerX3X2X1>(vectorsOfValues[8], dataSetParamStr.nx[8][0], dataSetParamStr.nx[8][1], dataSetParamStr.nx[8][2])));
 
-      boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX1(dataSetParamStr.nx1);
-      boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX2(dataSetParamStr.nx2);
-      boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX3(dataSetParamStr.nx3);
+      std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX1(dataSetParamStr.nx1);
+      std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX2(dataSetParamStr.nx2);
+      std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX3(dataSetParamStr.nx3);
 
       DataSet3DPtr dataSetPtr = DataSet3DPtr(new DataSet3D());
       dataSetPtr->setAverageDencity(mAverageDensity);
diff --git a/source/VirtualFluidsCore/CoProcessors/MPIIORestart11CoProcessor.h b/source/VirtualFluidsCore/CoProcessors/MPIIORestart11CoProcessor.h
index 56ea4d9a5..2bb652863 100644
--- a/source/VirtualFluidsCore/CoProcessors/MPIIORestart11CoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/MPIIORestart11CoProcessor.h
@@ -7,10 +7,13 @@
 #include "Communicator.h"
 #include "WbWriter.h"
 
-#include <boost/shared_ptr.hpp>
+
+#include "UbScheduler.h"
+#include "LBMKernel.h"
+#include "BCProcessor.h"
 
 class MPIIORestart11CoProcessor;
-typedef boost::shared_ptr<MPIIORestart11CoProcessor> MPIIORestart11CoProcessorPtr;
+typedef std::shared_ptr<MPIIORestart11CoProcessor> MPIIORestart11CoProcessorPtr;
 
 //! \class MPIWriteBlocksCoProcessor 
 //! \brief Writes the grid each timestep into the files and reads the grip from the files before regenerating  
diff --git a/source/VirtualFluidsCore/CoProcessors/MPIIORestart1CoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/MPIIORestart1CoProcessor.cpp
index dfdfeaa68..2f2645f2c 100644
--- a/source/VirtualFluidsCore/CoProcessors/MPIIORestart1CoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/MPIIORestart1CoProcessor.cpp
@@ -8,6 +8,14 @@
 #include "D3Q27EsoTwist3DSplittedVector.h"
 #include <UbSystem.h>
 #include <MemoryUtil.h>
+#include "BoundaryConditions.h"
+#include "Block3D.h"
+#include "CoordinateTransformation3D.h"
+#include "DataSet3D.h"
+#include "Grid3D.h"
+#include "BCArray3D.h"
+#include "UbScheduler.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 
@@ -253,11 +261,11 @@ void MPIIORestart1CoProcessor::writeBlocks(int step)
    int ic = 0;
    for (int level = minInitLevel; level<=maxInitLevel; level++)
    {
-      BOOST_FOREACH(Block3DPtr block, blocksVector[level])  //	all the blocks of the current level
+      for(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> > averageDensityArray = block->getKernel()->getDataSet()->getAverageDencity();
+            std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > averageDensityArray = block->getKernel()->getDataSet()->getAverageDencity();
             if (averageDensityArray)
             {
                blockParamStr.nx[0][0] = static_cast<int>(averageDensityArray->getNX1());
@@ -266,7 +274,7 @@ void MPIIORestart1CoProcessor::writeBlocks(int step)
                blockParamStr.nx[0][3] = static_cast<int>(averageDensityArray->getNX4());
             }
 
-            boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageVelocityArray3DPtr = block->getKernel()->getDataSet()->getAverageVelocity();
+            std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageVelocityArray3DPtr = block->getKernel()->getDataSet()->getAverageVelocity();
             if (AverageVelocityArray3DPtr)
             {
                blockParamStr.nx[1][0] = static_cast<int>(AverageVelocityArray3DPtr->getNX1());
@@ -275,7 +283,7 @@ void MPIIORestart1CoProcessor::writeBlocks(int step)
                blockParamStr.nx[1][3] = static_cast<int>(AverageVelocityArray3DPtr->getNX4());
             }
 
-            boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageFluctArray3DPtr = block->getKernel()->getDataSet()->getAverageFluctuations();
+            std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageFluctArray3DPtr = block->getKernel()->getDataSet()->getAverageFluctuations();
             if (AverageFluctArray3DPtr)
             {
                blockParamStr.nx[2][0] = static_cast<int>(AverageFluctArray3DPtr->getNX1());
@@ -284,7 +292,7 @@ void MPIIORestart1CoProcessor::writeBlocks(int step)
                blockParamStr.nx[2][3] = static_cast<int>(AverageFluctArray3DPtr->getNX4());
             }
 
-            boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageTripleArray3DPtr = block->getKernel()->getDataSet()->getAverageTriplecorrelations();
+            std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageTripleArray3DPtr = block->getKernel()->getDataSet()->getAverageTriplecorrelations();
             if (AverageTripleArray3DPtr)
             {
                blockParamStr.nx[3][0] = static_cast<int>(AverageTripleArray3DPtr->getNX1());
@@ -293,7 +301,7 @@ void MPIIORestart1CoProcessor::writeBlocks(int step)
                blockParamStr.nx[3][3] = static_cast<int>(AverageTripleArray3DPtr->getNX4());
             }
 
-            boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > ShearStressValArray3DPtr = block->getKernel()->getDataSet()->getShearStressValues();
+            std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > ShearStressValArray3DPtr = block->getKernel()->getDataSet()->getShearStressValues();
             if (ShearStressValArray3DPtr)
             {
                blockParamStr.nx[4][0] = static_cast<int>(ShearStressValArray3DPtr->getNX1());
@@ -302,7 +310,7 @@ void MPIIORestart1CoProcessor::writeBlocks(int step)
                blockParamStr.nx[4][3] = static_cast<int>(ShearStressValArray3DPtr->getNX4());
             }
 
-            boost::shared_ptr< CbArray3D<LBMReal, IndexerX3X2X1> > relaxationFactor3DPtr = block->getKernel()->getDataSet()->getRelaxationFactor();
+            std::shared_ptr< CbArray3D<LBMReal, IndexerX3X2X1> > relaxationFactor3DPtr = block->getKernel()->getDataSet()->getRelaxationFactor();
             if (relaxationFactor3DPtr)
             {
                blockParamStr.nx[5][0] = static_cast<int>(relaxationFactor3DPtr->getNX1());
@@ -311,7 +319,7 @@ void MPIIORestart1CoProcessor::writeBlocks(int step)
                blockParamStr.nx[5][3] = 1;
             }
 
-            boost::shared_ptr< D3Q27EsoTwist3DSplittedVector > D3Q27EsoTwist3DSplittedVectorPtr = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(block->getKernel()->getDataSet()->getFdistributions());
+            std::shared_ptr< D3Q27EsoTwist3DSplittedVector > D3Q27EsoTwist3DSplittedVectorPtr = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(block->getKernel()->getDataSet()->getFdistributions());
             CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getLocalDistributions();
             if (localDistributions)
             {
@@ -475,7 +483,7 @@ void MPIIORestart1CoProcessor::writeDataSet(int step)
    int ic = 0;
    for (int level = minInitLevel; level<=maxInitLevel; level++)
    {
-      BOOST_FOREACH(Block3DPtr block, blocksVector[level])  //	blocks of the current level
+      for(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();
@@ -507,31 +515,31 @@ void MPIIORestart1CoProcessor::writeDataSet(int step)
          //dataSetArrayGW[ic].compressible = dataSetArray[ic].compressible;
          //dataSetArrayGW[ic].withForcing = dataSetArray[ic].withForcing;
 
-         boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageValuesArray3DPtr = block->getKernel()->getDataSet()->getAverageDencity();
+         std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageValuesArray3DPtr = block->getKernel()->getDataSet()->getAverageDencity();
          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();
+         std::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();
+         std::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();
+         std::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();
+         std::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();
+         std::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());
+         std::shared_ptr< D3Q27EsoTwist3DSplittedVector > D3Q27EsoTwist3DSplittedVectorPtr = std::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());
@@ -658,7 +666,7 @@ void MPIIORestart1CoProcessor::writeBoundaryConds(int step)
    int ic = 0;
    for (int level = minInitLevel; level<=maxInitLevel; level++)
    {
-      BOOST_FOREACH(Block3DPtr block, blocksVector[level])  // all the blocks of the current level
+      for(Block3DPtr block : blocksVector[level])  // all the blocks of the current level
       {
          BCArray3DPtr bcArr = block->getKernel()->getBCProcessor()->getBCArray();
 
@@ -879,7 +887,7 @@ void MPIIORestart1CoProcessor::readBlocks(int step)
    std::vector<Block3DPtr> blocksVector;
    grid->getBlocks(0, blocksVector);
    int del = 0;
-   BOOST_FOREACH(Block3DPtr block, blocksVector)
+   for(Block3DPtr block : blocksVector)
    {
       grid->deleteBlock(block);
       del++;
@@ -1135,13 +1143,13 @@ void MPIIORestart1CoProcessor::readDataSet(int step)
       //DistributionArray3DPtr mFdistributions(new D3Q27EsoTwist3DSplittedVector(blockParamStr.nx1, blockParamStr.nx2, blockParamStr.nx3, -999.0));
       DistributionArray3DPtr mFdistributions(new D3Q27EsoTwist3DSplittedVector());
 
-      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])));
+      std::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])));
+      std::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])));
+      std::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);
+      std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX1(blockParamStr.nx1);
+      std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX2(blockParamStr.nx2);
+      std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX3(blockParamStr.nx3);
 
       DataSet3DPtr dataSetPtr = DataSet3DPtr(new DataSet3D());
       dataSetPtr->setAverageDencity(mAverageDensity);
@@ -1311,7 +1319,7 @@ void MPIIORestart1CoProcessor::readBoundaryConds(int step)
 
       Block3DPtr block = grid->getBlock(bcAddArray[n].x1, bcAddArray[n].x2, bcAddArray[n].x3, bcAddArray[n].level);
       
-      LBMKernelPtr kernel = block->getKernel();
+      ILBMKernelPtr kernel = block->getKernel();
 
       if (!kernel)
       {
diff --git a/source/VirtualFluidsCore/CoProcessors/MPIIORestart1CoProcessor.h b/source/VirtualFluidsCore/CoProcessors/MPIIORestart1CoProcessor.h
index 5dcd74214..e500aa2b9 100644
--- a/source/VirtualFluidsCore/CoProcessors/MPIIORestart1CoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/MPIIORestart1CoProcessor.h
@@ -6,11 +6,13 @@
 #include "CoProcessor.h"
 #include "Communicator.h"
 #include "WbWriter.h"
+#include "UbScheduler.h"
+#include "LBMKernel.h"
+#include "BCProcessor.h"
 
-#include <boost/shared_ptr.hpp>
 
 class MPIIORestart1CoProcessor;
-typedef boost::shared_ptr<MPIIORestart1CoProcessor> MPIIORestart1CoProcessorPtr;
+typedef std::shared_ptr<MPIIORestart1CoProcessor> MPIIORestart1CoProcessorPtr;
 
 //! \class MPIWriteBlocksCoProcessor 
 //! \brief Writes the grid each timestep into the files and reads the grip from the files before regenerating  
diff --git a/source/VirtualFluidsCore/CoProcessors/MPIIORestart21CoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/MPIIORestart21CoProcessor.cpp
index 4ecd193eb..f938c9015 100644
--- a/source/VirtualFluidsCore/CoProcessors/MPIIORestart21CoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/MPIIORestart21CoProcessor.cpp
@@ -6,6 +6,12 @@
 #include <UbSystem.h>
 #include <MemoryUtil.h>
 #include "RenumberBlockVisitor.h"
+#include "BoundaryConditions.h"
+#include "Block3D.h"
+#include "CoordinateTransformation3D.h"
+#include "DataSet3D.h"
+#include "Grid3D.h"
+#include "BCArray3D.h"
 
 MPIIORestart21CoProcessor::MPIIORestart21CoProcessor(Grid3DPtr grid, UbSchedulerPtr s,
    const std::string& path,
@@ -249,7 +255,7 @@ void MPIIORestart21CoProcessor::writeBlocks(int step)
    int ic = 0;
    for (int level = minInitLevel; level<=maxInitLevel; level++)
    {
-      BOOST_FOREACH(Block3DPtr block, blocksVector[level])  //	all the blocks of the current level
+      for(Block3DPtr block : blocksVector[level])  //	all the blocks of the current level
       {
          // save data describing the block
          block3dArray[ic].x1 = block->getX1();
@@ -350,7 +356,7 @@ void MPIIORestart21CoProcessor::writeDataSet(int step)
    int ic = 0;
    for (int level = minInitLevel; level<=maxInitLevel; level++)
    {
-      BOOST_FOREACH(Block3DPtr block, blocksVector[level])  //	blocks of the current level
+      for(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();
@@ -361,7 +367,7 @@ void MPIIORestart21CoProcessor::writeDataSet(int step)
 
          if (firstBlock)// && block->getKernel()) // when first (any) valid block...
          {
-            boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageValuesArray3DPtr = block->getKernel()->getDataSet()->getAverageValues();
+           std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageValuesArray3DPtr = block->getKernel()->getDataSet()->getAverageValues();
             if (AverageValuesArray3DPtr)
             {
                dataSetParamStr.nx[0][0] = static_cast<int>(AverageValuesArray3DPtr->getNX1());
@@ -370,7 +376,7 @@ void MPIIORestart21CoProcessor::writeDataSet(int step)
                dataSetParamStr.nx[0][3] = static_cast<int>(AverageValuesArray3DPtr->getNX4());
             }
 
-            boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageVelocityArray3DPtr = block->getKernel()->getDataSet()->getAverageVelocity();
+           std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageVelocityArray3DPtr = block->getKernel()->getDataSet()->getAverageVelocity();
             if (AverageVelocityArray3DPtr)
             {
                dataSetParamStr.nx[1][0] = static_cast<int>(AverageVelocityArray3DPtr->getNX1());
@@ -379,7 +385,7 @@ void MPIIORestart21CoProcessor::writeDataSet(int step)
                dataSetParamStr.nx[1][3] = static_cast<int>(AverageVelocityArray3DPtr->getNX4());
             }
 
-            boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageFluctArray3DPtr = block->getKernel()->getDataSet()->getAverageFluctuations();
+           std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageFluctArray3DPtr = block->getKernel()->getDataSet()->getAverageFluctuations();
             if (AverageFluctArray3DPtr)
             {
                dataSetParamStr.nx[2][0] = static_cast<int>(AverageFluctArray3DPtr->getNX1());
@@ -388,7 +394,7 @@ void MPIIORestart21CoProcessor::writeDataSet(int step)
                dataSetParamStr.nx[2][3] = static_cast<int>(AverageFluctArray3DPtr->getNX4());
             }
 
-            boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageTripleArray3DPtr = block->getKernel()->getDataSet()->getAverageTriplecorrelations();
+           std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageTripleArray3DPtr = block->getKernel()->getDataSet()->getAverageTriplecorrelations();
             if (AverageTripleArray3DPtr)
             {
                dataSetParamStr.nx[3][0] = static_cast<int>(AverageTripleArray3DPtr->getNX1());
@@ -397,7 +403,7 @@ void MPIIORestart21CoProcessor::writeDataSet(int step)
                dataSetParamStr.nx[3][3] = static_cast<int>(AverageTripleArray3DPtr->getNX4());
             }
 
-            boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > ShearStressValArray3DPtr = block->getKernel()->getDataSet()->getShearStressValues();
+           std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > ShearStressValArray3DPtr = block->getKernel()->getDataSet()->getShearStressValues();
             if (ShearStressValArray3DPtr)
             {
                dataSetParamStr.nx[4][0] = static_cast<int>(ShearStressValArray3DPtr->getNX1());
@@ -406,7 +412,7 @@ void MPIIORestart21CoProcessor::writeDataSet(int step)
                dataSetParamStr.nx[4][3] = static_cast<int>(ShearStressValArray3DPtr->getNX4());
             }
 
-            boost::shared_ptr< CbArray3D<LBMReal, IndexerX3X2X1> > relaxationFactor3DPtr = block->getKernel()->getDataSet()->getRelaxationFactor();
+           std::shared_ptr< CbArray3D<LBMReal, IndexerX3X2X1> > relaxationFactor3DPtr = block->getKernel()->getDataSet()->getRelaxationFactor();
             if (relaxationFactor3DPtr)
             {
                dataSetParamStr.nx[5][0] = static_cast<int>(relaxationFactor3DPtr->getNX1());
@@ -415,7 +421,7 @@ void MPIIORestart21CoProcessor::writeDataSet(int step)
                dataSetParamStr.nx[5][3] = 1;
             }
 
-            boost::shared_ptr< D3Q27EsoTwist3DSplittedVector > D3Q27EsoTwist3DSplittedVectorPtr = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(block->getKernel()->getDataSet()->getFdistributions());
+           std::shared_ptr< D3Q27EsoTwist3DSplittedVector > D3Q27EsoTwist3DSplittedVectorPtr = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(block->getKernel()->getDataSet()->getFdistributions());
             CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getLocalDistributions();
             if (localDistributions)
             {
@@ -462,31 +468,31 @@ void MPIIORestart21CoProcessor::writeDataSet(int step)
             dataSetParamStr.doubleCountInBlock = doubleCount;
          }
 
-         boost::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageValuesArray3DPtr = block->getKernel()->getDataSet()->getAverageValues();
+        std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageValuesArray3DPtr = block->getKernel()->getDataSet()->getAverageValues();
          if (AverageValuesArray3DPtr&&(dataSetParamStr.nx[0][0]>0)&&(dataSetParamStr.nx[0][1]>0)&&(dataSetParamStr.nx[0][2]>0)&&(dataSetParamStr.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();
+        std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageVelocityArray3DPtr = block->getKernel()->getDataSet()->getAverageVelocity();
          if (AverageVelocityArray3DPtr&&(dataSetParamStr.nx[1][0]>0)&&(dataSetParamStr.nx[1][1]>0)&&(dataSetParamStr.nx[1][2]>0)&&(dataSetParamStr.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();
+        std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageFluctArray3DPtr = block->getKernel()->getDataSet()->getAverageFluctuations();
          if (AverageFluctArray3DPtr&&(dataSetParamStr.nx[2][0]>0)&&(dataSetParamStr.nx[2][1]>0)&&(dataSetParamStr.nx[2][2]>0)&&(dataSetParamStr.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();
+        std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageTripleArray3DPtr = block->getKernel()->getDataSet()->getAverageTriplecorrelations();
          if (AverageTripleArray3DPtr&&(dataSetParamStr.nx[3][0]>0)&&(dataSetParamStr.nx[3][1]>0)&&(dataSetParamStr.nx[3][2]>0)&&(dataSetParamStr.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();
+        std::shared_ptr< CbArray4D<LBMReal, IndexerX4X3X2X1> > ShearStressValArray3DPtr = block->getKernel()->getDataSet()->getShearStressValues();
          if (ShearStressValArray3DPtr&&(dataSetParamStr.nx[4][0]>0)&&(dataSetParamStr.nx[4][1]>0)&&(dataSetParamStr.nx[4][2]>0)&&(dataSetParamStr.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();
+        std::shared_ptr< CbArray3D<LBMReal, IndexerX3X2X1> > RelaxationFactor3DPtr = block->getKernel()->getDataSet()->getRelaxationFactor();
          if (RelaxationFactor3DPtr&&(dataSetParamStr.nx[5][0]>0)&&(dataSetParamStr.nx[5][1]>0)&&(dataSetParamStr.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());
+        std::shared_ptr< D3Q27EsoTwist3DSplittedVector > D3Q27EsoTwist3DSplittedVectorPtr = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(block->getKernel()->getDataSet()->getFdistributions());
          CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getLocalDistributions();
          if (localDistributions&&(dataSetParamStr.nx[6][0]>0)&&(dataSetParamStr.nx[6][1]>0)&&(dataSetParamStr.nx[6][2]>0)&&(dataSetParamStr.nx[6][3]>0))
             doubleValuesArray.insert(doubleValuesArray.end(), localDistributions->getDataVector().begin(), localDistributions->getDataVector().end());
@@ -589,7 +595,7 @@ void MPIIORestart21CoProcessor::writeBoundaryConds(int step)
    int ic = 0;
    for (int level = minInitLevel; level<=maxInitLevel; level++)
    {
-      BOOST_FOREACH(Block3DPtr block, blocksVector[level])  // all the blocks of the current level
+      for(Block3DPtr block : blocksVector[level])  // all the blocks of the current level
       {
          BCArray3DPtr bcArr = block->getKernel()->getBCProcessor()->getBCArray();
 
@@ -809,7 +815,7 @@ void MPIIORestart21CoProcessor::readBlocks(int step)
    std::vector<Block3DPtr> blocksVector;
    grid->getBlocks(0, blocksVector);
    int del = 0;
-   BOOST_FOREACH(Block3DPtr block, blocksVector)
+   for(Block3DPtr block : blocksVector)
    {
       grid->deleteBlock(block);
       del++;
@@ -942,7 +948,7 @@ void MPIIORestart21CoProcessor::readDataSet(int step)
    size_t sizeofOneDataSet = size_t(sizeof(DataSet) + dataSetParamStr.doubleCountInBlock * sizeof(double));
    for (int level = minInitLevel; level <= maxInitLevel; level++)
    {
-      BOOST_FOREACH(Block3DPtr block, blocksVector[level])  //	blocks of the current level
+      for(Block3DPtr block : blocksVector[level])  //	blocks of the current level
       {
          read_offset = (MPI_Offset)(sizeof(dataSetParam) + block->getGlobalID() * sizeofOneDataSet);
          MPI_File_read_at(file_handler, read_offset, &dataSetArray[ic], 1, dataSetType, MPI_STATUS_IGNORE);
@@ -1011,13 +1017,13 @@ void MPIIORestart21CoProcessor::readDataSet(int step)
 
       DistributionArray3DPtr mFdistributions(new D3Q27EsoTwist3DSplittedVector());
 
-      boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[6], dataSetParamStr.nx[6][0], dataSetParamStr.nx[6][1], dataSetParamStr.nx[6][2], dataSetParamStr.nx[6][3])));
-      boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNonLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[7], dataSetParamStr.nx[7][0], dataSetParamStr.nx[7][1], dataSetParamStr.nx[7][2], dataSetParamStr.nx[7][3])));
-      boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setZeroDistributions(CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<LBMReal, IndexerX3X2X1>(vectorsOfValues[8], dataSetParamStr.nx[8][0], dataSetParamStr.nx[8][1], dataSetParamStr.nx[8][2])));
+      std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[6], dataSetParamStr.nx[6][0], dataSetParamStr.nx[6][1], dataSetParamStr.nx[6][2], dataSetParamStr.nx[6][3])));
+      std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNonLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[7], dataSetParamStr.nx[7][0], dataSetParamStr.nx[7][1], dataSetParamStr.nx[7][2], dataSetParamStr.nx[7][3])));
+      std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setZeroDistributions(CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<LBMReal, IndexerX3X2X1>(vectorsOfValues[8], dataSetParamStr.nx[8][0], dataSetParamStr.nx[8][1], dataSetParamStr.nx[8][2])));
  
-      boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX1(dataSetParamStr.nx1);
-      boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX2(dataSetParamStr.nx2);
-      boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX3(dataSetParamStr.nx3);
+      std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX1(dataSetParamStr.nx1);
+      std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX2(dataSetParamStr.nx2);
+      std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX3(dataSetParamStr.nx3);
 
       DataSet3DPtr dataSetPtr = DataSet3DPtr(new DataSet3D());
       dataSetPtr->setAverageValues(mAverageValues);
@@ -1109,7 +1115,7 @@ void MPIIORestart21CoProcessor::readBoundaryConds(int step)
    MPI_Offset read_offset1, read_offset2;
    for (int level = minInitLevel; level <= maxInitLevel; level++)
    {
-      BOOST_FOREACH(Block3DPtr block, blocksVector[level])  //	blocks of the current level
+      for(Block3DPtr block : blocksVector[level])  //	blocks of the current level
       {
          read_offset1 = (MPI_Offset)(sizeof(boundCondParam) + block->getGlobalID() * sizeof(size_t));
 
diff --git a/source/VirtualFluidsCore/CoProcessors/MPIIORestart21CoProcessor.h b/source/VirtualFluidsCore/CoProcessors/MPIIORestart21CoProcessor.h
index 038292d33..9592ad283 100644
--- a/source/VirtualFluidsCore/CoProcessors/MPIIORestart21CoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/MPIIORestart21CoProcessor.h
@@ -8,9 +8,12 @@
 #include "WbWriter.h"
 
 #include <boost/shared_ptr.hpp>
+#include "UbScheduler.h"
+#include "LBMKernel.h"
+#include "BCProcessor.h"
 
 class MPIIORestart21CoProcessor;
-typedef boost::shared_ptr<MPIIORestart21CoProcessor> MPIIORestart21CoProcessorPtr;
+typedef std::shared_ptr<MPIIORestart21CoProcessor> MPIIORestart21CoProcessorPtr;
 
 //! \class MPIWriteBlocksCoProcessor 
 //! \brief Writes the grid each timestep into the files and reads the grip from the files before regenerating  
diff --git a/source/VirtualFluidsCore/CoProcessors/MPIIORestart2CoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/MPIIORestart2CoProcessor.cpp
index 29776c614..7a72918fa 100644
--- a/source/VirtualFluidsCore/CoProcessors/MPIIORestart2CoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/MPIIORestart2CoProcessor.cpp
@@ -1,1275 +1,1285 @@
-#include "MPIIORestart2CoProcessor.h"
-#include <boost/foreach.hpp>
-#include "D3Q27System.h"
-#include "CompressibleCumulantLBMKernel.h"
-#include "D3Q27EsoTwist3DSplittedVector.h"
-#include <UbSystem.h>
-#include <MemoryUtil.h>
-#include "MetisPartitioningGridVisitor.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_create_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] = offsetsBC[1]+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");
-      /*if (comm->isRoot())*/ clearAllFiles((int)step);
-      writeBlocks((int)step);
-      writeDataSet((int)step);
-      writeBoundaryConds((int)step);
-
-      
-      //MPI_Barrier(MPI_COMM_WORLD);
-      
-      if (comm->isRoot()) UBLOG(logINFO, "Save check point - end");
-      
-      
-      //readDataSet((int)step);
-
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void MPIIORestart2CoProcessor::clearAllFiles(int step)
-{
-   MPI_File file_handler1, file_handler2, file_handler3;
-   MPI_Info info = MPI_INFO_NULL;
-   MPI_Offset new_size = 0;
-
-   UbSystem::makeDirectory(path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step));
-   std::string filename1 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpBlocks.bin";
-   //MPI_File_delete(filename1.c_str(), info);
-   int rc1 = MPI_File_open(MPI_COMM_WORLD, filename1.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &file_handler1);
-   if (rc1 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename1);
-   MPI_File_set_size(file_handler1, new_size);
-   //MPI_File_sync(file_handler1);
-   MPI_File_close(&file_handler1);
-
-   std::string filename2 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpDataSet.bin";
-   //MPI_File_delete(filename2.c_str(), info);
-   int rc2 = MPI_File_open(MPI_COMM_WORLD, filename2.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler2);
-   if (rc2 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename2);
-   MPI_File_set_size(file_handler2, new_size);
-   //MPI_File_sync(file_handler2);
-   MPI_File_close(&file_handler2);
-
-   std::string filename3 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpBC.bin";
-   //MPI_File_delete(filename3.c_str(), info);
-   int rc3 = MPI_File_open(MPI_COMM_WORLD, filename3.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler3);
-   if (rc3 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename3);
-   MPI_File_set_size(file_handler3, new_size);
-   //MPI_File_sync(file_handler3);
-   MPI_File_close(&file_handler3);
-}
-//////////////////////////////////////////////////////////////////////////
-void MPIIORestart2CoProcessor::writeBlocks(int step)
-{
-   int rank, size;
-   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
-   //MPI_Comm_size(MPI_COMM_WORLD, &size);
-   size=1;
-
-   
-   //if (comm->isRoot())
-   {
-      //grid->deleteBlockIDs();
-      //RenumberBlockVisitor renumber;
-      //grid->accept(renumber);
-      grid->renumberBlockIDs();
-   }
-   //grid->updateDistributedBlocks(comm);
-
-//UBLOG(logINFO, "MPIIORestart2CoProcessor::writeBlocks BlockIDs size =  "<<grid->getBlockIDs().size()<<" rank = "<<rank);
-
-   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");
-   }
-
-   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
-            BCArray3DPtr 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++;
-      }
-   }
-
-   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");
-   }
-
-   // write to the file
-   MPI_File file_handler;
-   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);
-   // }
-
-   double start, finish;
-   MPI_Offset write_offset = (MPI_Offset)(size*sizeof(int));
-   //MPI_Offset new_size = 0; 
-   //MPI_File_set_size(file_handler, new_size);
-      
-   if (comm->isRoot())
-   {
-      start = MPI_Wtime();
-      
-      // 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, write_offset, gridParameters, 1, gridParamType, MPI_STATUS_IGNORE);
-      // each process writes common parameters of a block
-      MPI_File_write_at(file_handler, (MPI_Offset)(write_offset +sizeof(GridParam)), &blockParamStr, 1, blockParamType, MPI_STATUS_IGNORE);
-      // each process writes it's blocks
-      MPI_File_write_at(file_handler, (MPI_Offset)(write_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
-   
-   //dataSetArrayTest = new DataSet[blocksCount];
-
-   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");
-   }
-
-//UBLOG(logINFO, "MPIIORestart2CoProcessor::writeDataSet minInitLevel="<<minInitLevel<<" maxInitLevel="<<maxInitLevel<<" blocksCount="<<blocksCount<<" rank = "<<rank);
-   
-   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
-         //UBLOG(logINFO, "MPIIORestart2CoProcessor::writeDataSet dataSetArray[n].globalID: "<<dataSetArray[ic].globalID<< " rank = "<<rank<<" ic = "<<ic);
-         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();
-         
-         //dataSetArrayTest[ic].globalID = block->getGlobalID();     // id of the block needed to find it while regenerating the grid
-         //dataSetArrayTest[ic].ghostLayerWidth = block->getKernel()->getGhostLayerWidth();
-         //dataSetArrayTest[ic].collFactor = block->getKernel()->getCollisionFactor();
-         //dataSetArrayTest[ic].deltaT = block->getKernel()->getDeltaT();
-         //dataSetArrayTest[ic].compressible = block->getKernel()->getCompressible();
-         //dataSetArrayTest[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);
-   
-   //MPI_Offset new_size = 0;
-   //MPI_File_set_size(file_handler, new_size);
-
-   size_t sizeofOneDataSet = sizeof(DataSet) + blockParamStr.doubleCountInBlock * sizeof(double);
-   MPI_Offset write_offset;
-   for (int nb = 0; nb < blocksCount; nb++)
-   {
-      write_offset = (MPI_Offset)(dataSetArray[nb].globalID * sizeofOneDataSet);
-      MPI_File_write_at(file_handler, write_offset, &dataSetArray[nb], 1, dataSetType, MPI_STATUS_IGNORE);
-      MPI_File_write_at(file_handler, (MPI_Offset)(write_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
-      {
-         BCArray3DPtr 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);
-
-   //MPI_Offset new_size = 0;
-   //MPI_File_set_size(file_handler, new_size);
-
-   MPI_Offset write_offset = (MPI_Offset)(grid->getNumberOfBlocks() * sizeof(size_t));
-   size_t next_file_offset = 0;
-   if (size > 1)
-   {
-      if (rank == 0)
-      {
-         next_file_offset = write_offset + allBytesCount;
-         MPI_Send(&next_file_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD);
-      }
-      else
-      {
-         MPI_Recv(&write_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
-         next_file_offset = write_offset + allBytesCount;
-         if (rank < size - 1)
-            MPI_Send(&next_file_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD);
-      }
-   }
-
-   MPI_Offset write_offsetIndex = 0;
-
-   for (int nb = 0; nb < blocksCount; nb++)
-   {
-      write_offsetIndex = (MPI_Offset)(bcAddArray[nb].globalID * sizeof(size_t));
-      MPI_File_write_at(file_handler, write_offsetIndex, &write_offset, 1, MPI_LONG_LONG_INT, MPI_STATUS_IGNORE);
-      
-      MPI_File_write_at(file_handler, write_offset, &bcAddArray[nb], 1, boundCondTypeAdd, MPI_STATUS_IGNORE);
-      if (bcVector[nb].size() > 0)
-         MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(BCAdd)), &bcVector[nb][0], bcAddArray[nb].boundCond_count, boundCondType, MPI_STATUS_IGNORE);
-
-      if (bcindexmatrixVector[nb].size() > 0)
-         MPI_File_write_at(file_handler, (MPI_Offset)(write_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, (MPI_Offset)(write_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);
-      
-      write_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 -----------------------------------------------
+#include "MPIIORestart2CoProcessor.h"
+
+#include "CompressibleCumulantLBMKernel.h"
+#include "D3Q27EsoTwist3DSplittedVector.h"
+#include <UbSystem.h>
+#include <MemoryUtil.h>
+#include "MetisPartitioningGridVisitor.h"
+
+#include "DataSet3D.h"
+#include "CoordinateTransformation3D.h"
+#include "Block3D.h"
+#include "Communicator.h"
+#include "UbScheduler.h"
+#include "Grid3D.h"
+#include "LBMKernel.h"
+#include "BCProcessor.h"
+#include "BCArray3D.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_create_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] = offsetsBC[1] + 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");
+        /*if (comm->isRoot())*/ clearAllFiles((int)step);
+        writeBlocks((int)step);
+        writeDataSet((int)step);
+        writeBoundaryConds((int)step);
+
+
+        //MPI_Barrier(MPI_COMM_WORLD);
+
+        if (comm->isRoot()) UBLOG(logINFO, "Save check point - end");
+
+
+        //readDataSet((int)step);
+
+    }
+}
+//////////////////////////////////////////////////////////////////////////
+void MPIIORestart2CoProcessor::clearAllFiles(int step)
+{
+    MPI_File file_handler1, file_handler2, file_handler3;
+    MPI_Info info = MPI_INFO_NULL;
+    MPI_Offset new_size = 0;
+
+    UbSystem::makeDirectory(path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step));
+    std::string filename1 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpBlocks.bin";
+    //MPI_File_delete(filename1.c_str(), info);
+    int rc1 = MPI_File_open(MPI_COMM_WORLD, filename1.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &file_handler1);
+    if (rc1 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename1);
+    MPI_File_set_size(file_handler1, new_size);
+    //MPI_File_sync(file_handler1);
+    MPI_File_close(&file_handler1);
+
+    std::string filename2 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpDataSet.bin";
+    //MPI_File_delete(filename2.c_str(), info);
+    int rc2 = MPI_File_open(MPI_COMM_WORLD, filename2.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler2);
+    if (rc2 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename2);
+    MPI_File_set_size(file_handler2, new_size);
+    //MPI_File_sync(file_handler2);
+    MPI_File_close(&file_handler2);
+
+    std::string filename3 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpBC.bin";
+    //MPI_File_delete(filename3.c_str(), info);
+    int rc3 = MPI_File_open(MPI_COMM_WORLD, filename3.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler3);
+    if (rc3 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename3);
+    MPI_File_set_size(file_handler3, new_size);
+    //MPI_File_sync(file_handler3);
+    MPI_File_close(&file_handler3);
+}
+//////////////////////////////////////////////////////////////////////////
+void MPIIORestart2CoProcessor::writeBlocks(int step)
+{
+    int rank, size;
+    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+    //MPI_Comm_size(MPI_COMM_WORLD, &size);
+    size = 1;
+
+
+    //if (comm->isRoot())
+    {
+        //grid->deleteBlockIDs();
+        //RenumberBlockVisitor renumber;
+        //grid->accept(renumber);
+        grid->renumberBlockIDs();
+    }
+    //grid->updateDistributedBlocks(comm);
+
+    //UBLOG(logINFO, "MPIIORestart2CoProcessor::writeBlocks BlockIDs size =  "<<grid->getBlockIDs().size()<<" rank = "<<rank);
+
+    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");
+    }
+
+    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++)
+    {
+        for(Block3DPtr block : blocksVector[level])  //	all the blocks of the current level
+        {
+            if (firstBlock && block->getKernel()) // when first (any) valid block...
+            {
+                std::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());
+                }
+
+                std::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());
+                }
+
+                std::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());
+                }
+
+                std::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());
+                }
+
+                std::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());
+                }
+
+                std::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;
+                }
+
+                std::shared_ptr< D3Q27EsoTwist3DSplittedVector > D3Q27EsoTwist3DSplittedVectorPtr = std::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
+                BCArray3DPtr 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++;
+        }
+    }
+
+    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");
+    }
+
+    // write to the file
+    MPI_File file_handler;
+    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);
+    // }
+
+    double start, finish;
+    MPI_Offset write_offset = (MPI_Offset)(size * sizeof(int));
+    //MPI_Offset new_size = 0; 
+    //MPI_File_set_size(file_handler, new_size);
+
+    if (comm->isRoot())
+    {
+        start = MPI_Wtime();
+
+        // 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, write_offset, gridParameters, 1, gridParamType, MPI_STATUS_IGNORE);
+        // each process writes common parameters of a block
+        MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(GridParam)), &blockParamStr, 1, blockParamType, MPI_STATUS_IGNORE);
+        // each process writes it's blocks
+        MPI_File_write_at(file_handler, (MPI_Offset)(write_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
+
+                                           //dataSetArrayTest = new DataSet[blocksCount];
+
+    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");
+    }
+
+    //UBLOG(logINFO, "MPIIORestart2CoProcessor::writeDataSet minInitLevel="<<minInitLevel<<" maxInitLevel="<<maxInitLevel<<" blocksCount="<<blocksCount<<" rank = "<<rank);
+
+    int ic = 0;
+    for (int level = minInitLevel; level <= maxInitLevel; level++)
+    {
+        for(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
+                                                                  //UBLOG(logINFO, "MPIIORestart2CoProcessor::writeDataSet dataSetArray[n].globalID: "<<dataSetArray[ic].globalID<< " rank = "<<rank<<" ic = "<<ic);
+            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();
+
+            //dataSetArrayTest[ic].globalID = block->getGlobalID();     // id of the block needed to find it while regenerating the grid
+            //dataSetArrayTest[ic].ghostLayerWidth = block->getKernel()->getGhostLayerWidth();
+            //dataSetArrayTest[ic].collFactor = block->getKernel()->getCollisionFactor();
+            //dataSetArrayTest[ic].deltaT = block->getKernel()->getDeltaT();
+            //dataSetArrayTest[ic].compressible = block->getKernel()->getCompressible();
+            //dataSetArrayTest[ic].withForcing = block->getKernel()->getWithForcing();
+
+            std::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());
+
+            std::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());
+
+            std::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());
+
+            std::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());
+
+            std::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());
+
+            std::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());
+
+            std::shared_ptr< D3Q27EsoTwist3DSplittedVector > D3Q27EsoTwist3DSplittedVectorPtr = std::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);
+
+    //MPI_Offset new_size = 0;
+    //MPI_File_set_size(file_handler, new_size);
+
+    size_t sizeofOneDataSet = sizeof(DataSet) + blockParamStr.doubleCountInBlock * sizeof(double);
+    MPI_Offset write_offset;
+    for (int nb = 0; nb < blocksCount; nb++)
+    {
+        write_offset = (MPI_Offset)(dataSetArray[nb].globalID * sizeofOneDataSet);
+        MPI_File_write_at(file_handler, write_offset, &dataSetArray[nb], 1, dataSetType, MPI_STATUS_IGNORE);
+        MPI_File_write_at(file_handler, (MPI_Offset)(write_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++)
+    {
+        for(Block3DPtr block : blocksVector[level])  // all the blocks of the current level
+        {
+            BCArray3DPtr 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);
+
+    //MPI_Offset new_size = 0;
+    //MPI_File_set_size(file_handler, new_size);
+
+    MPI_Offset write_offset = (MPI_Offset)(grid->getNumberOfBlocks() * sizeof(size_t));
+    size_t next_file_offset = 0;
+    if (size > 1)
+    {
+        if (rank == 0)
+        {
+            next_file_offset = write_offset + allBytesCount;
+            MPI_Send(&next_file_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD);
+        }
+        else
+        {
+            MPI_Recv(&write_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+            next_file_offset = write_offset + allBytesCount;
+            if (rank < size - 1)
+                MPI_Send(&next_file_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD);
+        }
+    }
+
+    MPI_Offset write_offsetIndex = 0;
+
+    for (int nb = 0; nb < blocksCount; nb++)
+    {
+        write_offsetIndex = (MPI_Offset)(bcAddArray[nb].globalID * sizeof(size_t));
+        MPI_File_write_at(file_handler, write_offsetIndex, &write_offset, 1, MPI_LONG_LONG_INT, MPI_STATUS_IGNORE);
+
+        MPI_File_write_at(file_handler, write_offset, &bcAddArray[nb], 1, boundCondTypeAdd, MPI_STATUS_IGNORE);
+        if (bcVector[nb].size() > 0)
+            MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(BCAdd)), &bcVector[nb][0], bcAddArray[nb].boundCond_count, boundCondType, MPI_STATUS_IGNORE);
+
+        if (bcindexmatrixVector[nb].size() > 0)
+            MPI_File_write_at(file_handler, (MPI_Offset)(write_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, (MPI_Offset)(write_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);
+
+        write_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);
-   
-   Grid3DVisitorPtr metisVisitor(new MetisPartitioningGridVisitor(comm, MetisPartitioningGridVisitor::LevelBased, D3Q27System::BSW, MetisPartitioner::KWAY));
-   grid->accept(metisVisitor);
-   
-   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];
-   
-   GridParam* gridParameters = new GridParam;
-
-   // calculate the read offset
-   MPI_Offset read_offset = (MPI_Offset)(size*sizeof(int));
-
-   // 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, (MPI_Offset)(read_offset+sizeof(GridParam)), &blockParamStr, 1, blockParamType, MPI_STATUS_IGNORE);
-   // read all the blocks
-   MPI_File_read_at(file_handler, (MPI_Offset)(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 restart step: " << step);
+    if (comm->isRoot()) UBLOG(logINFO, "Load check point - start");
+    readBlocks(step);
 
-   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();
+    Grid3DVisitorPtr metisVisitor(new MetisPartitioningGridVisitor(comm, MetisPartitioningGridVisitor::LevelBased, D3Q27System::BSW, MetisPartitioner::KWAY));
+    grid->accept(metisVisitor);
 
-   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;
-   MPI_Offset read_offset;
-   size_t sizeofOneDataSet = size_t(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 = (MPI_Offset)(block->getGlobalID() * sizeofOneDataSet);
-         //UBLOG(logINFO, "MPIIORestart2CoProcessor::readDataSet read_offset="<<read_offset<<" sizeofOneDataSet="<<sizeofOneDataSet<<" GlobalID="<<block->getGlobalID()<< " rank="<<rank);
-         MPI_File_read_at(file_handler, read_offset, &dataSetArray[ic], 1, dataSetType, MPI_STATUS_IGNORE);
-         MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(DataSet)), &doubleValuesArray[ic*blockParamStr.doubleCountInBlock], 1, dataSetDoubleType, MPI_STATUS_IGNORE);
-         ic++;
-      }
-   }
-
-   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");
-   }
-
-   //for (int n = 0; n<blocksCount; n++)
-   //{
-      //if(dataSetArray[n].globalID != dataSetArrayTest[n].globalID)
-      //{
-         //UBLOG(logINFO, "MPIIORestart2CoProcessor::readDataSet dataSetArray[n].globalID: "<<dataSetArray[n].globalID<< " rank = "<<rank<<" n = "<<n);
-         ////UBLOG(logINFO, "MPIIORestart2CoProcessor::readDataSet dataSetArray[n].globalID: "<<dataSetArray[n].globalID);
-         ////UBLOG(logINFO, "MPIIORestart2CoProcessor::readDataSet SetArrayTest[n].globalID: "<<dataSetArrayTest[n].globalID);
-      //}
-   //}
-   
-   //UBLOG(logINFO, "MPIIORestart2CoProcessor::readDataSet grid size 1: "<<grid->getNumberOfBlocks()<<" rank = "<<rank);
-   //UBLOG(logINFO, "MPIIORestart2CoProcessor::readDataSet BlockIDs size 1: "<<grid->getBlockIDs().size()<<" rank = "<<rank);
-   
-   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));
-      DistributionArray3DPtr mFdistributions(new D3Q27EsoTwist3DSplittedVector());
-
-      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);
-      //Block3DPtr block = grid->getBlock(2);
-      if (!block)
-      {
-         UBLOG(logINFO, "MPIIORestart2CoProcessor::readDataSet don't find block dataSetArray[n].globalID: "<<dataSetArray[n].globalID<< " rank = "<<rank<<" n = "<<n);
-         UBLOG(logINFO, "MPIIORestart2CoProcessor::readDataSet grid size 2: "<<grid->getNumberOfBlocks()<<" rank = "<<rank);
-      }
-      ////LBMKernelPtr kernel(new CompressibleCumulantLBMKernel(0, 0, 0, CompressibleCumulantLBMKernel::NORMAL));
-      LBMKernelPtr kernel = this->lbmKernel->clone();
-      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");
-   }
+    readDataSet(step);
+    readBoundaryConds(step);
+    if (comm->isRoot()) UBLOG(logINFO, "Load check point - end");
+    this->reconnect(grid);
 }
-
-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;
-   MPI_Offset read_offset1, read_offset2;
-   for (int level = minInitLevel; level <= maxInitLevel; level++)
-   {
-      BOOST_FOREACH(Block3DPtr block, blocksVector[level])  //	blocks of the current level
-      {
-         read_offset1 = (MPI_Offset)(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, (MPI_Offset)(read_offset2 + sizeof(BCAdd)), &bcArray[0], bcAddArray[ic].boundCond_count, boundCondType, MPI_STATUS_IGNORE);
-         }
-         MPI_File_read_at(file_handler, (MPI_Offset)(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, (MPI_Offset)(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);
-         Block3DPtr block1 = grid->getBlock(bcAddArray[ic].globalID);
-
-         //BCProcessorPtr bcProc(new BCProcessor());
-         BCProcessorPtr bcProc = bcProcessor->clone(block1->getKernel());
-         //BCArray3DPtr bcArr = bcProc->getBCArray();
-         BCArray3DPtr bcArr(new BCArray3D());
-         bcArr->bcindexmatrix = bcim;
-         bcArr->bcvector = bcVector;
-         bcArr->indexContainer = indexContainerV;
-         bcProc->setBCArray(bcArr);
-
-         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);
-      finish = MPI_Wtime();
-      UBLOG(logINFO, "MPIIORestart2CoProcessor::readBoundaryConds time: " << finish - start << " s");
-      UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB");
-   }
-}
-
-void MPIIORestart2CoProcessor::setChunk(int val)
-{
-   chunk = val;
-}
-//////////////////////////////////////////////////////////////////////////
-void MPIIORestart2CoProcessor::setLBMKernel(LBMKernelPtr kernel)
-{
-   this->lbmKernel = kernel;
-}
-//////////////////////////////////////////////////////////////////////////
-void MPIIORestart2CoProcessor::setBCProcessor(BCProcessorPtr bcProcessor)
-{
-   this->bcProcessor = bcProcessor;
-}
-
+
+
+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];
+
+    GridParam* gridParameters = new GridParam;
+
+    // calculate the read offset
+    MPI_Offset read_offset = (MPI_Offset)(size * sizeof(int));
+
+    // 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, (MPI_Offset)(read_offset + sizeof(GridParam)), &blockParamStr, 1, blockParamType, MPI_STATUS_IGNORE);
+    // read all the blocks
+    MPI_File_read_at(file_handler, (MPI_Offset)(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;
+    for(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;
+    MPI_Offset read_offset;
+    size_t sizeofOneDataSet = size_t(sizeof(DataSet) + blockParamStr.doubleCountInBlock * sizeof(double));
+    for (int level = minInitLevel; level <= maxInitLevel; level++)
+    {
+        for(Block3DPtr block : blocksVector[level])  //	blocks of the current level
+        {
+            read_offset = (MPI_Offset)(block->getGlobalID() * sizeofOneDataSet);
+            //UBLOG(logINFO, "MPIIORestart2CoProcessor::readDataSet read_offset="<<read_offset<<" sizeofOneDataSet="<<sizeofOneDataSet<<" GlobalID="<<block->getGlobalID()<< " rank="<<rank);
+            MPI_File_read_at(file_handler, read_offset, &dataSetArray[ic], 1, dataSetType, MPI_STATUS_IGNORE);
+            MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(DataSet)), &doubleValuesArray[ic*blockParamStr.doubleCountInBlock], 1, dataSetDoubleType, MPI_STATUS_IGNORE);
+            ic++;
+        }
+    }
+
+    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");
+    }
+
+    //for (int n = 0; n<blocksCount; n++)
+    //{
+    //if(dataSetArray[n].globalID != dataSetArrayTest[n].globalID)
+    //{
+    //UBLOG(logINFO, "MPIIORestart2CoProcessor::readDataSet dataSetArray[n].globalID: "<<dataSetArray[n].globalID<< " rank = "<<rank<<" n = "<<n);
+    ////UBLOG(logINFO, "MPIIORestart2CoProcessor::readDataSet dataSetArray[n].globalID: "<<dataSetArray[n].globalID);
+    ////UBLOG(logINFO, "MPIIORestart2CoProcessor::readDataSet SetArrayTest[n].globalID: "<<dataSetArrayTest[n].globalID);
+    //}
+    //}
+
+    //UBLOG(logINFO, "MPIIORestart2CoProcessor::readDataSet grid size 1: "<<grid->getNumberOfBlocks()<<" rank = "<<rank);
+    //UBLOG(logINFO, "MPIIORestart2CoProcessor::readDataSet BlockIDs size 1: "<<grid->getBlockIDs().size()<<" rank = "<<rank);
+
+    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));
+        DistributionArray3DPtr mFdistributions(new D3Q27EsoTwist3DSplittedVector());
+
+        std::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])));
+        std::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])));
+        std::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])));
+
+        std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX1(blockParamStr.nx1);
+        std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX2(blockParamStr.nx2);
+        std::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);
+        //Block3DPtr block = grid->getBlock(2);
+        if (!block)
+        {
+            UBLOG(logINFO, "MPIIORestart2CoProcessor::readDataSet don't find block dataSetArray[n].globalID: " << dataSetArray[n].globalID << " rank = " << rank << " n = " << n);
+            UBLOG(logINFO, "MPIIORestart2CoProcessor::readDataSet grid size 2: " << grid->getNumberOfBlocks() << " rank = " << rank);
+        }
+        ////LBMKernelPtr kernel(new CompressibleCumulantLBMKernel(0, 0, 0, CompressibleCumulantLBMKernel::NORMAL));
+        LBMKernelPtr kernel = this->lbmKernel->clone();
+        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;
+    MPI_Offset read_offset1, read_offset2;
+    for (int level = minInitLevel; level <= maxInitLevel; level++)
+    {
+        for(Block3DPtr block : blocksVector[level])  //	blocks of the current level
+        {
+            read_offset1 = (MPI_Offset)(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, (MPI_Offset)(read_offset2 + sizeof(BCAdd)), &bcArray[0], bcAddArray[ic].boundCond_count, boundCondType, MPI_STATUS_IGNORE);
+            }
+            MPI_File_read_at(file_handler, (MPI_Offset)(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, (MPI_Offset)(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);
+            Block3DPtr block1 = grid->getBlock(bcAddArray[ic].globalID);
+
+            //BCProcessorPtr bcProc(new BCProcessor());
+            BCProcessorPtr bcProc = bcProcessor->clone(block1->getKernel());
+            //BCArray3DPtr bcArr = bcProc->getBCArray();
+            BCArray3DPtr bcArr(new BCArray3D());
+            bcArr->bcindexmatrix = bcim;
+            bcArr->bcvector = bcVector;
+            bcArr->indexContainer = indexContainerV;
+            bcProc->setBCArray(bcArr);
+
+            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);
+        finish = MPI_Wtime();
+        UBLOG(logINFO, "MPIIORestart2CoProcessor::readBoundaryConds time: " << finish - start << " s");
+        UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB");
+    }
+}
+
+void MPIIORestart2CoProcessor::setChunk(int val)
+{
+    chunk = val;
+}
+//////////////////////////////////////////////////////////////////////////
+void MPIIORestart2CoProcessor::setLBMKernel(LBMKernelPtr kernel)
+{
+    this->lbmKernel = kernel;
+}
+//////////////////////////////////////////////////////////////////////////
+void MPIIORestart2CoProcessor::setBCProcessor(BCProcessorPtr bcProcessor)
+{
+    this->bcProcessor = bcProcessor;
+}
+
diff --git a/source/VirtualFluidsCore/CoProcessors/MPIIORestart2CoProcessor.h b/source/VirtualFluidsCore/CoProcessors/MPIIORestart2CoProcessor.h
index 9500ac7cb..5fed488f5 100644
--- a/source/VirtualFluidsCore/CoProcessors/MPIIORestart2CoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/MPIIORestart2CoProcessor.h
@@ -1,176 +1,181 @@
-#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);
-   //! The function sets number of ranks that read simultaneously 
-   void setChunk(int val);
-   //! The function sets LBMKernel
-   void setLBMKernel(LBMKernelPtr kernel);
-   //!The function sets BCProcessor
-   void setBCProcessor(BCProcessorPtr bcProcessor);
-   //!The function truncates the data files
-   void clearAllFiles(int step);
-
-protected:
-   std::string path;
-   CommunicatorPtr comm;
-   bool mpiTypeFreeFlag;
-
-private:
-	MPI_Datatype gridParamType, blockParamType, block3dType, dataSetType, dataSetDoubleType, boundCondType, boundCondType1000, boundCondTypeAdd, bcindexmatrixType;
-   BlockParam blockParamStr;
-   int chunk;
-   LBMKernelPtr lbmKernel;
-   BCProcessorPtr bcProcessor;
-   
-   DataSet* dataSetArrayTest;
-
-};
-
-#endif 
+#ifndef _MPIIORestart2CoProcessor_H_
+#define _MPIIORestart2CoProcessor_H_
+
+#include <memory>
+#include <string>
+
+#include "mpi.h"
+
+#include "CoProcessor.h"
+
+class Communicator;
+class Grid3D;
+class UbScheduler;
+class LBMKernel;
+class BCProcessor;
+
+class MPIIORestart2CoProcessor;
+typedef std::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(std::shared_ptr<Grid3D> grid, std::shared_ptr<UbScheduler> s, const std::string& path, std::shared_ptr<Communicator> 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);
+   //! The function sets number of ranks that read simultaneously 
+   void setChunk(int val);
+   //! The function sets LBMKernel
+   void setLBMKernel(std::shared_ptr<LBMKernel> kernel);
+   //!The function sets BCProcessor
+   void setBCProcessor(std::shared_ptr<BCProcessor> bcProcessor);
+   //!The function truncates the data files
+   void clearAllFiles(int step);
+
+protected:
+   std::string path;
+   std::shared_ptr<Communicator> comm;
+   bool mpiTypeFreeFlag;
+
+private:
+	MPI_Datatype gridParamType, blockParamType, block3dType, dataSetType, dataSetDoubleType, boundCondType, boundCondType1000, boundCondTypeAdd, bcindexmatrixType;
+   BlockParam blockParamStr;
+   int chunk;
+   std::shared_ptr<LBMKernel> lbmKernel;
+   std::shared_ptr<BCProcessor> bcProcessor;
+
+   DataSet* dataSetArrayTest;
+
+};
+
+#endif 
diff --git a/source/VirtualFluidsCore/CoProcessors/NUPSCounterCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/NUPSCounterCoProcessor.cpp
index 73bfac4cb..1b4aff099 100644
--- a/source/VirtualFluidsCore/CoProcessors/NUPSCounterCoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/NUPSCounterCoProcessor.cpp
@@ -1,5 +1,8 @@
 #include "NUPSCounterCoProcessor.h"
 
+#include "Communicator.h"
+#include "UbScheduler.h"
+#include "Grid3D.h"
 
 NUPSCounterCoProcessor::NUPSCounterCoProcessor(Grid3DPtr grid, UbSchedulerPtr s, int numOfThreads, CommunicatorPtr comm)
                                                    : CoProcessor(grid, s),
diff --git a/source/VirtualFluidsCore/CoProcessors/NUPSCounterCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/NUPSCounterCoProcessor.h
index d0f26a2e2..bd3f877ca 100644
--- a/source/VirtualFluidsCore/CoProcessors/NUPSCounterCoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/NUPSCounterCoProcessor.h
@@ -8,16 +8,23 @@
 #ifndef NUPSCOUNTERCoProcessor_H_
 #define NUPSCOUNTERCoProcessor_H_
 
+#include <memory>
+
 #include "CoProcessor.h"
-#include "Communicator.h"
 #include "basics/utilities/UbTiming.h"
-#include <boost/timer.hpp>
 
-class NUPSCounterCoProcessor: public CoProcessor {
+class Communicator;
+class Grid3D;
+class UbScheduler;
+
+class NUPSCounterCoProcessor: public CoProcessor
+{
 public:
-   NUPSCounterCoProcessor(Grid3DPtr grid, UbSchedulerPtr s, int numOfThreads, CommunicatorPtr comm);
+   NUPSCounterCoProcessor(std::shared_ptr<Grid3D> grid, std::shared_ptr<UbScheduler> s, int numOfThreads, std::shared_ptr<Communicator> comm);
    virtual ~NUPSCounterCoProcessor();
-   void process(double step);
+
+   void process(double step)override;
+
 protected:
    void collectData(double step);
    UbTimer timer;
@@ -28,7 +35,7 @@ protected:
    double nup;
    double nup_t;
    double nupsStep;
-   CommunicatorPtr comm;
+   std::shared_ptr<Communicator> comm;
 };
 
 
diff --git a/source/VirtualFluidsCore/CoProcessors/PressureCoefficientCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/PressureCoefficientCoProcessor.cpp
index b6c1e3c19..9962ffd03 100644
--- a/source/VirtualFluidsCore/CoProcessors/PressureCoefficientCoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/PressureCoefficientCoProcessor.cpp
@@ -1,6 +1,17 @@
 #include "PressureCoefficientCoProcessor.h"
 #include <WbWriterVtkXmlASCII.h>
 
+#include "LBMKernel.h"
+#include "BCProcessor.h"
+#include "DataSet3D.h"
+#include "Block3D.h"
+#include "UbScheduler.h"
+#include "Grid3D.h"
+#include "Communicator.h"
+#include "GbCuboid3D.h"
+#include "D3Q27Interactor.h"
+#include "BCArray3D.h"
+
 PressureCoefficientCoProcessor::PressureCoefficientCoProcessor(Grid3DPtr grid, UbSchedulerPtr s,
    GbCuboid3DPtr plane,
    const std::string& path, CommunicatorPtr comm)
@@ -43,15 +54,15 @@ void PressureCoefficientCoProcessor::calculateRho()
    std::vector<double> values;
    std::vector<double> rvalues;
 
-   BOOST_FOREACH(D3Q27InteractorPtr interactor, interactors)
+   for(D3Q27InteractorPtr interactor : interactors)
    {
       typedef std::map<Block3DPtr, std::set< std::vector<int> > > TransNodeIndicesMap;
-      BOOST_FOREACH(TransNodeIndicesMap::value_type t, interactor->getBcNodeIndicesMap())
+      for(TransNodeIndicesMap::value_type t : interactor->getBcNodeIndicesMap())
       {
          Block3DPtr block = t.first;
          std::set< std::vector<int> >& bcNodeIndicesSet = t.second;
 
-         LBMKernelPtr kernel = block->getKernel();
+         ILBMKernelPtr kernel = block->getKernel();
          BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
          DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();
 
@@ -77,7 +88,7 @@ void PressureCoefficientCoProcessor::calculateRho()
          int minX3 = ghostLayerWidth;
          int maxX3 = (int)bcArray->getNX3() - 1 - ghostLayerWidth;
 
-         BOOST_FOREACH(std::vector<int> node, bcNodeIndicesSet)
+         for(std::vector<int> node : bcNodeIndicesSet)
          {
             int x1 = node[0];
             int x2 = node[1];
@@ -182,7 +193,7 @@ void PressureCoefficientCoProcessor::writeValues(int step)
 }
 void PressureCoefficientCoProcessor::readValues(int step)
 {
-   if (comm->getProcessID() == comm->getRoot())
+   if (comm->isRoot())
    {
       std::string fname = path+UbSystem::toString(step)+".bin";
       std::ifstream in(fname.c_str(), std::ios::in | std::ios::binary);
@@ -193,7 +204,7 @@ void PressureCoefficientCoProcessor::readValues(int step)
 
       // get length of file:
       in.seekg(0, in.end);
-      int length = in.tellg();
+      int length = (int)in.tellg();
       in.seekg(0, in.beg);
 
       outValues.resize(length/sizeof(double));
diff --git a/source/VirtualFluidsCore/CoProcessors/PressureCoefficientCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/PressureCoefficientCoProcessor.h
index cab13d549..bd9b2e1c7 100644
--- a/source/VirtualFluidsCore/CoProcessors/PressureCoefficientCoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/PressureCoefficientCoProcessor.h
@@ -1,29 +1,42 @@
 #ifndef PressureCoefficientCoProcessor_h__
 #define PressureCoefficientCoProcessor_h__
 
+#include <memory>
+#include <string>
+#include <vector>
+
 #include "CoProcessor.h"
-#include "Communicator.h"
-#include "GbCuboid3D.h"
-#include "D3Q27Interactor.h"
+#include "LBMSystem.h"
+
+
+class GbCuboid3D;
+class D3Q27Interactor;
+class Communicator;
+class Grid3D;
+class UbScheduler;
 
 class PressureCoefficientCoProcessor: public CoProcessor
 {
 public:
-   PressureCoefficientCoProcessor(Grid3DPtr grid, UbSchedulerPtr s,
-      GbCuboid3DPtr plane, const std::string& path, CommunicatorPtr comm);
+   PressureCoefficientCoProcessor(std::shared_ptr<Grid3D> grid, std::shared_ptr<UbScheduler> s,
+       std::shared_ptr<GbCuboid3D> plane, const std::string& path, std::shared_ptr<Communicator> comm);
    ~PressureCoefficientCoProcessor();
-   void process(double step);
-   void addInteractor(D3Q27InteractorPtr interactor);
+
+   void process(double step) override;
+
+   void addInteractor(std::shared_ptr<D3Q27Interactor> interactor);
    void readValues(int step);
+
 protected:
    void collectData(double step);
    void calculateRho();
    void writeValues(int step);
+
 private:
-   GbCuboid3DPtr plane;
+    std::shared_ptr<GbCuboid3D> plane;
    std::string path;
-   CommunicatorPtr comm;
-   std::vector<D3Q27InteractorPtr> interactors;
+   std::shared_ptr<Communicator> comm;
+   std::vector<std::shared_ptr<D3Q27Interactor> > interactors;
    int numberOfSteps;
    double maxStep;
 
diff --git a/source/VirtualFluidsCore/CoProcessors/PressureDifferenceCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/PressureDifferenceCoProcessor.cpp
index 035bd7505..8da16eaa5 100644
--- a/source/VirtualFluidsCore/CoProcessors/PressureDifferenceCoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/PressureDifferenceCoProcessor.cpp
@@ -7,11 +7,14 @@
 
 #include "PressureDifferenceCoProcessor.h"
 
-
-#include <iostream>
 #include <fstream>
 
-using namespace std;
+#include "IntegrateValuesHelper.h"
+#include "LBMUnitConverter.h"
+#include "Communicator.h"
+#include "UbScheduler.h"
+#include "Grid3D.h"
+
 
 PressureDifferenceCoProcessor::PressureDifferenceCoProcessor(Grid3DPtr grid, UbSchedulerPtr s, const std::string& path,
                                                                  IntegrateValuesHelperPtr h1, IntegrateValuesHelperPtr h2, 
@@ -27,19 +30,19 @@ PressureDifferenceCoProcessor::PressureDifferenceCoProcessor(Grid3DPtr grid, UbS
    if (comm->getProcessID() == comm->getRoot())
    {
       std::ofstream ostr;
-      string fname = path;
+      std::string fname = path;
       ostr.open(fname.c_str(), std::ios_base::out);
       if(!ostr)
       { 
          ostr.clear();
-         string path = UbSystem::getPathFromString(fname);
+         std::string path = UbSystem::getPathFromString(fname);
          if(path.size()>0){ UbSystem::makeDirectory(path); ostr.open(fname.c_str(), std::ios_base::out);}
          if(!ostr) throw UbException(UB_EXARGS,"couldn't open file "+fname);
       }
       ostr << "step" << "\t" << "nodes1" << "\t" << "nodes2" << "\t";
       ostr << "sRho1" << "\t" << "p1_1"  << "\t" << "sRho2" << "\t" << "p1_2" << "\t" << "deltaP1"<< "\t";
       ostr << "sPress1" << "\t" << "p2_1" << "\t" << "sPress2" << "\t" << "p2_2" << "\t" << "deltaP2";
-      ostr << endl;
+      ostr << std::endl;
       ostr.close();
 
       factor1 = (1.0/3.0)*rhoReal*(uReal/uLB)*(uReal/uLB);
@@ -80,12 +83,12 @@ void PressureDifferenceCoProcessor::collectData(double step)
       //double p2_2 = (press2/nn2) * factor2;
       //double dp2 = p2_1 - p2_2;
 
-      string fname = path;
+      std::string fname = path;
       ostr.open(fname.c_str(), std::ios_base::out | std::ios_base::app);
       if(!ostr)
       { 
          ostr.clear();
-         string path = UbSystem::getPathFromString(fname);
+         std::string path = UbSystem::getPathFromString(fname);
          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);
       }
@@ -93,7 +96,7 @@ void PressureDifferenceCoProcessor::collectData(double step)
       ostr << istep << "\t" << nn1 << "\t"  << nn2 << "\t"; 
       ostr << rho1 << "\t" << p1_1 << "\t" << rho2 << "\t" << p1_2 << "\t" << dp1 << "\t";
       //ostr << press1 << "\t" << p2_1 << "\t" << press2 << "\t" << p2_2 << "\t" << dp2;
-      ostr << endl;
+      ostr << std::endl;
       ostr.close();
    }
 }
diff --git a/source/VirtualFluidsCore/CoProcessors/PressureDifferenceCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/PressureDifferenceCoProcessor.h
index 136f2b060..b6d63fa67 100644
--- a/source/VirtualFluidsCore/CoProcessors/PressureDifferenceCoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/PressureDifferenceCoProcessor.h
@@ -8,25 +8,34 @@
 #ifndef D3Q27PRESSUREDIFFERENCECoProcessor_H
 #define D3Q27PRESSUREDIFFERENCECoProcessor_H
 
+#include <memory>
+#include <string>
+
 #include "CoProcessor.h"
-#include "IntegrateValuesHelper.h"
-#include "LBMUnitConverter.h"
-#include "Communicator.h"
+#include "LBMSystem.h"
+
+class Communicator;
+class Grid3D;
+class UbScheduler;
+class LBMUnitConverter;
+class IntegrateValuesHelper;
 
 class PressureDifferenceCoProcessor: public CoProcessor {
 public:
-	PressureDifferenceCoProcessor(Grid3DPtr grid, UbSchedulerPtr s, const std::string& path, 
-                                   IntegrateValuesHelperPtr h1, IntegrateValuesHelperPtr h2, 
+	PressureDifferenceCoProcessor(std::shared_ptr<Grid3D> grid, std::shared_ptr<UbScheduler> s, const std::string& path,
+        std::shared_ptr<IntegrateValuesHelper> h1, std::shared_ptr<IntegrateValuesHelper> h2,
                                    LBMReal rhoReal, LBMReal uReal, LBMReal uLB,
-                                   /*const LBMUnitConverterPtr conv,*/ CommunicatorPtr comm);
+                                   /*const LBMUnitConverterPtr conv,*/ std::shared_ptr<Communicator> comm);
 	virtual ~PressureDifferenceCoProcessor();
-	void process(double step);
+
+	void process(double step) override;
+
 protected:
-	IntegrateValuesHelperPtr h1, h2;
+    std::shared_ptr<IntegrateValuesHelper> h1, h2;
    std::string path;
-   LBMUnitConverterPtr conv;
+   std::shared_ptr<LBMUnitConverter> conv;
 	void collectData(double step);
-   CommunicatorPtr comm;
+    std::shared_ptr<Communicator> comm;
    LBMReal factor1; //= (1/3)*rhoReal*(uReal/uLB)^2 for calculation pReal = rhoLB * (1/3)*rhoReal*(uReal/uLB)^2, rhoReal and uReal in SI
    LBMReal factor2; //= rhoReal*(uReal/uLB)^2       for calculation pReal = press * rhoReal*(uReal/uLB)^2,       rhoReal and uReal in SI
 };
diff --git a/source/VirtualFluidsCore/CoProcessors/QCriterionCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/QCriterionCoProcessor.cpp
index 08a0ef832..80c7f57ec 100644
--- a/source/VirtualFluidsCore/CoProcessors/QCriterionCoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/QCriterionCoProcessor.cpp
@@ -1,389 +1,389 @@
-#include "QCriterionCoProcessor.h"
-#include "LBMKernel.h"
-#include "LBMKernel.h"
-#include "BCProcessor.h"
-#include <vector>
-#include <string>
-#include <boost/foreach.hpp>
-#include "basics/writer/WbWriterVtkXmlASCII.h"
-
-
-using namespace std;
-using namespace D3Q27System;
-
-QCriterionCoProcessor::QCriterionCoProcessor(Grid3DPtr grid, const std::string& path, 
-	WbWriter* const writer,
-	UbSchedulerPtr s, CommunicatorPtr comm)
-	: CoProcessor(grid, s),
-	path(path),
-	comm(comm),
-	writer(writer)
-{
-	init();
-}
-//////////////////////////////////////////////////////////////////////////
-void QCriterionCoProcessor::init()
-{
-	gridRank  = comm->getProcessID(); 
-	minInitLevel = this->grid->getCoarsestInitializedLevel();
-	maxInitLevel = this->grid->getFinestInitializedLevel();
-
-	blockVector.resize(maxInitLevel+1);
-
-	for(int level = minInitLevel; level<=maxInitLevel;level++)
-	{
-		grid->getBlocks(level, gridRank, true, blockVector[level]); //grid: private variable in CoProcessor. Initialized by filling with blocks
-	}
-}
-//////////////////////////////////////////////////////////////////////////
-void QCriterionCoProcessor::process(double step)
-{
-	if(scheduler->isDue(step) )
-		collectData(step);
-
-	UBLOG(logDEBUG3, "QCriterionCoProcessor::update:" << step);
-}
-//////////////////////////////////////////////////////////////////////////
-void QCriterionCoProcessor::collectData(double step)
-{
-	int istep = static_cast<int>(step);
-
-	for(int level = minInitLevel; level<=maxInitLevel;level++)
-	{
-		BOOST_FOREACH(Block3DPtr block, blockVector[level])
-		{
-			if (block)
-			{
-				addData(block);
-
-			}
-		}
-	}
-
-	string partName = writer->writeOctsWithNodeData(path+ UbSystem::toString(gridRank)+ "_" + UbSystem::toString(istep),nodes,cells,datanames,data);
-	size_t found=partName.find_last_of("//");
-	string piece = partName.substr(found+1);
-
-	vector<string> cellDataNames;
-
-	//distributed writing as in MacroscopicValuesCoProcessor.cpp
-	vector<string> pieces = comm->gather(piece); //comm: MPI-Wrapper
-	if (comm->getProcessID() == comm->getRoot())
-	{
-		string pname = WbWriterVtkXmlASCII::getInstance()->writeParallelFile(path+"_"+UbSystem::toString(istep),pieces,datanames,cellDataNames);
-
-		vector<string> filenames;
-		filenames.push_back(pname);
-		if (step == CoProcessor::scheduler->getMinBegin()) //first time in timeseries
-		{
-			WbWriterVtkXmlASCII::getInstance()->writeCollection(path+"_collection",filenames,istep,false);
-		} 
-		else
-		{
-			WbWriterVtkXmlASCII::getInstance()->addFilesToCollection(path+"_collection",filenames,istep,false);
-		}
-		UBLOG(logINFO,"QCriterionCoProcessor step: " << istep);
-	}
-
-	clearData();
-
-
-}
-//////////////////////////////////////////////////////////////////////////
-void QCriterionCoProcessor::clearData()
-{
-	nodes.clear();
-	cells.clear();
-	datanames.clear();
-	data.clear();
-}
-//////////////////////////////////////////////////////////////////////////
-void QCriterionCoProcessor::addData(const Block3DPtr block)
-{
-	UbTupleDouble3 org          = grid->getBlockWorldCoordinates(block);
-	UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
-	UbTupleDouble3 nodeOffset   = grid->getNodeOffset(block);
-	double         dx           = grid->getDeltaX(block);
-
-	//Diese Daten werden geschrieben:
-	datanames.resize(0);
-	datanames.push_back("q");
-	datanames.push_back("scaleFactor");
-	data.resize(datanames.size());
-
-
-	LBMKernelPtr kernel = block->getKernel();
-	BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
-	DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();  
-
-	int SWB,SEB,NEB,NWB,SWT,SET,NET,NWT;
-
-	int minX1 = 0;
-	int minX2 = 0;
-	int minX3 = 0;
-
-	int maxX1 = (int)(distributions->getNX1());
-	int maxX2 = (int)(distributions->getNX2());
-	int maxX3 = (int)(distributions->getNX3());
-
-	int currentLevel = block->getLevel();
-	//nummern vergeben und node vector erstellen + daten sammeln
-	CbArray3D<int> nodeNumbers((int)maxX1, (int)maxX2, (int)maxX3,-1);
-	maxX1 -= 2; //-2 wegen ghost layer: 
-	maxX2 -= 2; //0-maxXi-1 ist arraygroesse. 
-	maxX3 -= 2; //ueberlapp 1 in +,- Richtung. zum schreiben werden statt feldern von 1 bis (max-2) felder von 0 bis max-3 verwendet! 
-
-
-	int nr = (int)nodes.size();
-
-	for(int ix3=minX3; ix3<=maxX3; ix3++)
-	{
-		for(int ix2=minX2; ix2<=maxX2; ix2++)
-		{
-			for(int ix1=minX1; ix1<=maxX1; ix1++)
-			{
-				if(!bcArray->isUndefined(ix1,ix2,ix3) && !bcArray->isSolid(ix1,ix2,ix3))
-				{
-					//nodeNumbers-vektor wird mit koordinaten befuellt
-					int index = 0;
-					nodeNumbers(ix1,ix2,ix3) = nr++;
-					nodes.push_back( makeUbTuple(float(val<1>(org) - val<1>(nodeOffset) + ix1*dx),
-						float(val<2>(org) - val<2>(nodeOffset) + ix2*dx),
-						float(val<3>(org) - val<3>(nodeOffset) + ix3*dx)) );			
-
-					/////////////////////////////
-					// Geschwindigkeitsvektoren 
-					LBMReal vE[3];
-					LBMReal vW[3];
-					LBMReal vN[3];
-					LBMReal vS[3];
-					LBMReal vT[3];
-					LBMReal vB[3];
-					//hole geschwindigkeiten an nachbarknoten
-					getNeighborVelocities(1,0,0, ix1,  ix2,  ix3, block, vE, vW);
-					getNeighborVelocities(0,1,0, ix1,  ix2,  ix3, block, vN, vS);
-					getNeighborVelocities(0,0,1, ix1,  ix2,  ix3, block, vT, vB);
-					//////////////////////////////////
-					//derivatives
-					LBMReal duxdy=(vN[xdir]-vS[xdir])*0.5;
-					LBMReal duydx=(vE[ydir]-vW[ydir])*0.5;
-					LBMReal duxdz=(vT[xdir]-vB[xdir])*0.5;
-					LBMReal duzdx=(vE[zdir]-vW[zdir])*0.5;
-					LBMReal duydz=(vT[ydir]-vB[ydir])*0.5;
-					LBMReal duzdy=(vN[zdir]-vS[zdir])*0.5;
-
-					LBMReal duxdx=(vE[xdir]-vW[xdir])*0.5;
-					LBMReal duydy=(vN[ydir]-vS[ydir])*0.5;
-					LBMReal duzdz=(vT[zdir]-vB[zdir])*0.5;					
-
-					LBMReal scaleFactor=(double)(1<<(currentLevel-minInitLevel));//pow(2.0,(double)(currentLevel-minInitLevel));//finer grid -> current level higher. coarsest grid: currentLevel=minInitLevel=0
-					// Q=-0.5*(S_ij S_ij - Omega_ij Omega_ij) => regions where vorticity is larger than strain rate
-					LBMReal q=-(duxdy*duydx+duxdz*duzdx+duydz*duzdy+duxdx*duxdx+duydy*duydy+duzdz*duzdz)*scaleFactor;
-
-					data[index++].push_back( q );
-					data[index++].push_back( scaleFactor );
-
-				}
-			}
-		}
-	}
-	maxX1 -= 1;
-	maxX2 -= 1;
-	maxX3 -= 1;
-	//cell vector erstellen
-	for(int ix3=minX3; ix3<=maxX3; ix3++)
-	{
-		for(int ix2=minX2; ix2<=maxX2; ix2++)
-		{
-			for(int ix1=minX1; ix1<=maxX1; ix1++)
-			{
-				if(   (SWB=nodeNumbers( ix1  , ix2,   ix3   )) >= 0
-					&& (SEB=nodeNumbers( ix1+1, ix2,   ix3   )) >= 0
-					&& (NEB=nodeNumbers( ix1+1, ix2+1, ix3   )) >= 0
-					&& (NWB=nodeNumbers( ix1  , ix2+1, ix3   )) >= 0 
-					&& (SWT=nodeNumbers( ix1  , ix2,   ix3+1 )) >= 0
-					&& (SET=nodeNumbers( ix1+1, ix2,   ix3+1 )) >= 0
-					&& (NET=nodeNumbers( ix1+1, ix2+1, ix3+1 )) >= 0
-					&& (NWT=nodeNumbers( ix1  , ix2+1, ix3+1 )) >= 0                )
-				{
-					// for valid points: neighbors are added to cells-vector
-					cells.push_back( makeUbTuple(SWB,SEB,NEB,NWB,SWT,SET,NET,NWT) );
-				}
-			}
-		}
-	}
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void QCriterionCoProcessor::getNeighborVelocities(int offx, int offy, int offz, int ix1, int ix2, int ix3, const Block3DPtr block, LBMReal* vE, LBMReal* vW)
-{
-	LBMKernelPtr kernel = block->getKernel();
-	BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
-	DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();   
-
-   bool compressible = block->getKernel()->getCompressible();
-
-	int minX1 = 0;
-	int minX2 = 0;
-	int minX3 = 0;
-
-	int maxX1 = (int)(distributions->getNX1());
-	int maxX2 = (int)(distributions->getNX2());
-	int maxX3 = (int)(distributions->getNX3());
-	if (maxX1<3) throw UbException(UB_EXARGS,"QCriterionCoProcessor: NX1 too small for FD stencils!");
-	maxX1 -= 2;
-	maxX2 -= 2;
-	maxX3 -= 2;
-	bool checkInterpolation=true;
-	bool neighNodeIsBC=false;
-	BoundaryConditionsPtr bcPtr;
-
-	int rankSelf= block->getRank(); 
-	if (!(offx+offy+offz)==1) throw UbException(UB_EXARGS,"getNeighborVelocities called for diagonal directions!");
-	//////get neighbor nodes, if existent
-	if ((ix1==0 && offx==1) || (ix2==0 && offy==1) || (ix3==0 && offz==1))
-	{
-		int RankNeighborW; 
-		UbTupleDouble3 orgNodeRW =  grid->getNodeCoordinates(block,  ix1, ix2, ix3);
-		double xp000= ( val<1>(orgNodeRW));
-		double yp000= ( val<2>(orgNodeRW));
-		double zp000= ( val<3>(orgNodeRW));
-
-		int currentLevel = block->getLevel();
-		UbTupleInt3 blockIndexes = grid->getBlockIndexes(xp000,yp000, zp000,currentLevel);
-		Block3DPtr blockNeighW;
-
-		if ((val<1>(blockIndexes)!=0 && offx==1) || (val<2>(blockIndexes)!=0 && offy==1) || (val<3>(blockIndexes)!=0 && offz==1))
-		{
-
-			blockNeighW = grid->getBlock(val<1>(blockIndexes)-offx, val<2>(blockIndexes)-offy, val<3>(blockIndexes)-offz, currentLevel);
-
-		}
-		else if (offx==1 && grid->isPeriodicX1())
-		{
-			blockNeighW = grid->getBlock((grid->getNX1()-1), val<2>(blockIndexes), val<3>(blockIndexes), currentLevel);
-		}
-		else if (offy==1 && grid->isPeriodicX1())
-		{
-			blockNeighW = grid->getBlock(val<1>(blockIndexes),(grid->getNX2()-1),  val<3>(blockIndexes), currentLevel);
-		}
-		else if (offz==1 && grid->isPeriodicX1())
-		{
-			blockNeighW = grid->getBlock( val<1>(blockIndexes), val<2>(blockIndexes),(grid->getNX3()-1), currentLevel);
-		}
-		else neighNodeIsBC;
-
-		if(blockNeighW && blockNeighW->isActive())
-		{	     		     
-			RankNeighborW= blockNeighW->getRank();   
-		}
-		else
-		{
-
-			blockNeighW = block;
-			RankNeighborW= blockNeighW->getRank();
-			checkInterpolation=false;
-		}
-		if (RankNeighborW!=rankSelf)
-		{
-
-			blockNeighW = block;
-			RankNeighborW= blockNeighW->getRank();
-			checkInterpolation=false;
-		}
-
-		///////////////////////////////////////
-		////compute distribution at neighboring nodes from neighboring blocks
-
-		if (checkInterpolation==false || neighNodeIsBC)
-		{
-			LBMKernelPtr kernelW = blockNeighW->getKernel();
-			BCArray3DPtr bcArrayW = kernelW->getBCProcessor()->getBCArray();          
-			DistributionArray3DPtr distributionsW = kernelW->getDataSet()->getFdistributions();
-			LBMReal fW2[27];
-			LBMReal fW[27];
-			LBMReal f0[27];
-			LBMReal fE[27];
-			LBMReal v0[3];
-			LBMReal vW2[3];
-			//distributionsW->getDistribution(fW2, std::max(ix1+2*offx,1), std::max(ix2+2*offy,1), std::max(ix3+2*offz,1));
-			//distributionsW->getDistribution(fW, std::max(ix1+offx,1), std::max(ix2+offy,1), std::max(ix3+offz,1));
-			//distributionsW->getDistribution(f0, std::max(ix1    ,1), std::max(ix2    ,1), std::max(ix3    ,1));
-			//distributions->getDistribution(fE, std::max(ix1+offx    ,1), std::max(ix2+offy    ,1), std::max(ix3+offz    ,1)); //E:= plus 1
-			distributionsW->getDistribution(fW2, std::max(ix1+2*offx,0), std::max(ix2+2*offy,0), std::max(ix3+2*offz,0));
-			distributionsW->getDistribution(fW, std::max(ix1+offx,0), std::max(ix2+offy,0), std::max(ix3+offz,0));
-			distributionsW->getDistribution(f0, std::max(ix1    ,0), std::max(ix2    ,0), std::max(ix3    ,0));
-			distributions->getDistribution(fE, std::max(ix1+offx    ,0), std::max(ix2+offy    ,0), std::max(ix3+offz    ,0)); //E:= plus 1
-
-			computeVelocity(fE,vE,compressible);
-			computeVelocity(fW,vW,compressible);
-			computeVelocity(fW2,vW2,compressible);
-			computeVelocity(f0,v0,compressible);
-			//second order non-symetric interpolation
-			vW[0]=v0[0]*1.5-vW[0]+0.5*vW2[0];
-			vW[1]=v0[1]*1.5-vW[1]+0.5*vW2[1];
-			vW[2]=v0[2]*1.5-vW[2]+0.5*vW2[2];
-		    //throw UbException(UB_EXARGS,"Parallel or Non-Uniform Simulation -- not yet implemented");
-		}
-		else
-		{
-			LBMKernelPtr kernelW = blockNeighW->getKernel();
-			BCArray3DPtr bcArrayW = kernelW->getBCProcessor()->getBCArray();          
-			DistributionArray3DPtr distributionsW = kernelW->getDataSet()->getFdistributions();
-			LBMReal fW[27];
-
-			if (offx==1)
-			{
-				distributionsW->getDistribution(fW, (distributions->getNX1())-1, ix2, ix3); //moved one block backward, now get last entry
-			}
-			else if (offy==1)
-			{
-				distributionsW->getDistribution(fW, ix1,(distributions->getNX2())-1, ix3); 
-
-			}
-			else if (offz==1)
-			{
-				distributionsW->getDistribution(fW, ix1,ix2,distributions->getNX3()-1); 
-			}
-			computeVelocity(fW,vW,compressible);
-		}
-
-
-	}					 
-	else
-	{
-		//data available in current block:
-		LBMReal fW[27];
-		distributions->getDistribution(fW, ix1-offx, ix2-offy, ix3-offz);
-		computeVelocity(fW,vW,compressible);
-
-	}
-	if (checkInterpolation==true)
-	{
-		//in plus-direction data is available in current block because of ghost layers
-		LBMReal fE[27];
-		distributions->getDistribution(fE, ix1+offx, ix2+offy, ix3+offz); //E:= plus 1
-		computeVelocity(fE,vE,compressible);
-	}
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void QCriterionCoProcessor::computeVelocity(LBMReal* f, LBMReal* v, bool compressible)
-{
-	//////////////////////////////////////////////////////////////////////////
-	//compute x,y,z-velocity components from distribution
-	//////////////////////////////////////////////////////////////////////////
-   if (compressible)
-   {
-      v[xdir] = D3Q27System::getCompVelocityX1(f);
-      v[ydir] = D3Q27System::getCompVelocityX2(f);
-      v[zdir] = D3Q27System::getCompVelocityX3(f);
-   } 
-   else
-   {
-      v[xdir] = D3Q27System::getIncompVelocityX1(f);
-      v[ydir] = D3Q27System::getIncompVelocityX2(f);
-      v[zdir] = D3Q27System::getIncompVelocityX3(f);
-   }
-}
+#include "QCriterionCoProcessor.h"
+#include "LBMKernel.h"
+#include "BCProcessor.h"
+#include "basics/writer/WbWriterVtkXmlASCII.h"
+#include "DataSet3D.h"
+#include "Grid3D.h"
+#include "Block3D.h"
+
+#include "Communicator.h"
+#include "UbScheduler.h"
+#include "BCArray3D.h"
+
+
+QCriterionCoProcessor::QCriterionCoProcessor(Grid3DPtr grid, const std::string& path, 
+	WbWriter* const writer,
+	UbSchedulerPtr s, CommunicatorPtr comm)
+	: CoProcessor(grid, s),
+	path(path),
+	comm(comm),
+	writer(writer)
+{
+	init();
+}
+//////////////////////////////////////////////////////////////////////////
+void QCriterionCoProcessor::init()
+{
+	gridRank  = comm->getProcessID(); 
+	minInitLevel = this->grid->getCoarsestInitializedLevel();
+	maxInitLevel = this->grid->getFinestInitializedLevel();
+
+	blockVector.resize(maxInitLevel+1);
+
+	for(int level = minInitLevel; level<=maxInitLevel;level++)
+	{
+		grid->getBlocks(level, gridRank, true, blockVector[level]); //grid: private variable in CoProcessor. Initialized by filling with blocks
+	}
+}
+//////////////////////////////////////////////////////////////////////////
+void QCriterionCoProcessor::process(double step)
+{
+	if(scheduler->isDue(step) )
+		collectData(step);
+
+	UBLOG(logDEBUG3, "QCriterionCoProcessor::update:" << step);
+}
+//////////////////////////////////////////////////////////////////////////
+void QCriterionCoProcessor::collectData(double step)
+{
+	int istep = static_cast<int>(step);
+
+	for(int level = minInitLevel; level<=maxInitLevel;level++)
+	{
+		for(Block3DPtr block : blockVector[level])
+		{
+			if (block)
+			{
+				addData(block);
+
+			}
+		}
+	}
+
+	std::string partName = writer->writeOctsWithNodeData(path+ UbSystem::toString(gridRank)+ "_" + UbSystem::toString(istep),nodes,cells,datanames,data);
+	size_t found=partName.find_last_of("//");
+	std::string piece = partName.substr(found+1);
+
+	std::vector<std::string> cellDataNames;
+
+	//distributed writing as in MacroscopicValuesCoProcessor.cpp
+	std::vector<std::string> pieces = comm->gather(piece); //comm: MPI-Wrapper
+	if (comm->getProcessID() == comm->getRoot())
+	{
+		std::string pname = WbWriterVtkXmlASCII::getInstance()->writeParallelFile(path+"_"+UbSystem::toString(istep),pieces,datanames,cellDataNames);
+
+		std::vector<std::string> filenames;
+		filenames.push_back(pname);
+		if (step == CoProcessor::scheduler->getMinBegin()) //first time in timeseries
+		{
+			WbWriterVtkXmlASCII::getInstance()->writeCollection(path+"_collection",filenames,istep,false);
+		} 
+		else
+		{
+			WbWriterVtkXmlASCII::getInstance()->addFilesToCollection(path+"_collection",filenames,istep,false);
+		}
+		UBLOG(logINFO,"QCriterionCoProcessor step: " << istep);
+	}
+
+	clearData();
+
+
+}
+//////////////////////////////////////////////////////////////////////////
+void QCriterionCoProcessor::clearData()
+{
+	nodes.clear();
+	cells.clear();
+	datanames.clear();
+	data.clear();
+}
+//////////////////////////////////////////////////////////////////////////
+void QCriterionCoProcessor::addData(const Block3DPtr block)
+{
+	UbTupleDouble3 org          = grid->getBlockWorldCoordinates(block);
+	UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
+	UbTupleDouble3 nodeOffset   = grid->getNodeOffset(block);
+	double         dx           = grid->getDeltaX(block);
+
+	//Diese Daten werden geschrieben:
+	datanames.resize(0);
+	datanames.push_back("q");
+	datanames.push_back("scaleFactor");
+	data.resize(datanames.size());
+
+
+	ILBMKernelPtr kernel = block->getKernel();
+	BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
+	DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();  
+
+	int SWB,SEB,NEB,NWB,SWT,SET,NET,NWT;
+
+	int minX1 = 0;
+	int minX2 = 0;
+	int minX3 = 0;
+
+	int maxX1 = (int)(distributions->getNX1());
+	int maxX2 = (int)(distributions->getNX2());
+	int maxX3 = (int)(distributions->getNX3());
+
+	int currentLevel = block->getLevel();
+	//nummern vergeben und node std::vector erstellen + daten sammeln
+	CbArray3D<int> nodeNumbers((int)maxX1, (int)maxX2, (int)maxX3,-1);
+	maxX1 -= 2; //-2 wegen ghost layer: 
+	maxX2 -= 2; //0-maxXi-1 ist arraygroesse. 
+	maxX3 -= 2; //ueberlapp 1 in +,- Richtung. zum schreiben werden statt feldern von 1 bis (max-2) felder von 0 bis max-3 verwendet! 
+
+
+	int nr = (int)nodes.size();
+
+	for(int ix3=minX3; ix3<=maxX3; ix3++)
+	{
+		for(int ix2=minX2; ix2<=maxX2; ix2++)
+		{
+			for(int ix1=minX1; ix1<=maxX1; ix1++)
+			{
+				if(!bcArray->isUndefined(ix1,ix2,ix3) && !bcArray->isSolid(ix1,ix2,ix3))
+				{
+					//nodeNumbers-vektor wird mit koordinaten befuellt
+					int index = 0;
+					nodeNumbers(ix1,ix2,ix3) = nr++;
+					nodes.push_back( makeUbTuple(float(val<1>(org) - val<1>(nodeOffset) + ix1*dx),
+						float(val<2>(org) - val<2>(nodeOffset) + ix2*dx),
+						float(val<3>(org) - val<3>(nodeOffset) + ix3*dx)) );			
+
+					/////////////////////////////
+					// Geschwindigkeitsvektoren 
+					LBMReal vE[3];
+					LBMReal vW[3];
+					LBMReal vN[3];
+					LBMReal vS[3];
+					LBMReal vT[3];
+					LBMReal vB[3];
+					//hole geschwindigkeiten an nachbarknoten
+					getNeighborVelocities(1,0,0, ix1,  ix2,  ix3, block, vE, vW);
+					getNeighborVelocities(0,1,0, ix1,  ix2,  ix3, block, vN, vS);
+					getNeighborVelocities(0,0,1, ix1,  ix2,  ix3, block, vT, vB);
+					//////////////////////////////////
+					//derivatives
+					LBMReal duxdy=(vN[xdir]-vS[xdir])*0.5;
+					LBMReal duydx=(vE[ydir]-vW[ydir])*0.5;
+					LBMReal duxdz=(vT[xdir]-vB[xdir])*0.5;
+					LBMReal duzdx=(vE[zdir]-vW[zdir])*0.5;
+					LBMReal duydz=(vT[ydir]-vB[ydir])*0.5;
+					LBMReal duzdy=(vN[zdir]-vS[zdir])*0.5;
+
+					LBMReal duxdx=(vE[xdir]-vW[xdir])*0.5;
+					LBMReal duydy=(vN[ydir]-vS[ydir])*0.5;
+					LBMReal duzdz=(vT[zdir]-vB[zdir])*0.5;					
+
+					LBMReal scaleFactor=(double)(1<<(currentLevel-minInitLevel));//pow(2.0,(double)(currentLevel-minInitLevel));//finer grid -> current level higher. coarsest grid: currentLevel=minInitLevel=0
+					// Q=-0.5*(S_ij S_ij - Omega_ij Omega_ij) => regions where vorticity is larger than strain rate
+					LBMReal q=-(duxdy*duydx+duxdz*duzdx+duydz*duzdy+duxdx*duxdx+duydy*duydy+duzdz*duzdz)*scaleFactor;
+
+					data[index++].push_back( q );
+					data[index++].push_back( scaleFactor );
+
+				}
+			}
+		}
+	}
+	maxX1 -= 1;
+	maxX2 -= 1;
+	maxX3 -= 1;
+	//cell vector erstellen
+	for(int ix3=minX3; ix3<=maxX3; ix3++)
+	{
+		for(int ix2=minX2; ix2<=maxX2; ix2++)
+		{
+			for(int ix1=minX1; ix1<=maxX1; ix1++)
+			{
+				if(   (SWB=nodeNumbers( ix1  , ix2,   ix3   )) >= 0
+					&& (SEB=nodeNumbers( ix1+1, ix2,   ix3   )) >= 0
+					&& (NEB=nodeNumbers( ix1+1, ix2+1, ix3   )) >= 0
+					&& (NWB=nodeNumbers( ix1  , ix2+1, ix3   )) >= 0 
+					&& (SWT=nodeNumbers( ix1  , ix2,   ix3+1 )) >= 0
+					&& (SET=nodeNumbers( ix1+1, ix2,   ix3+1 )) >= 0
+					&& (NET=nodeNumbers( ix1+1, ix2+1, ix3+1 )) >= 0
+					&& (NWT=nodeNumbers( ix1  , ix2+1, ix3+1 )) >= 0                )
+				{
+					// for valid points: neighbors are added to cells-vector
+					cells.push_back( makeUbTuple(SWB,SEB,NEB,NWB,SWT,SET,NET,NWT) );
+				}
+			}
+		}
+	}
+
+}
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void QCriterionCoProcessor::getNeighborVelocities(int offx, int offy, int offz, int ix1, int ix2, int ix3, const Block3DPtr block, LBMReal* vE, LBMReal* vW)
+{
+	ILBMKernelPtr kernel = block->getKernel();
+	BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
+	DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();   
+
+   bool compressible = block->getKernel()->getCompressible();
+
+	int minX1 = 0;
+	int minX2 = 0;
+	int minX3 = 0;
+
+	int maxX1 = (int)(distributions->getNX1());
+	int maxX2 = (int)(distributions->getNX2());
+	int maxX3 = (int)(distributions->getNX3());
+	if (maxX1<3) throw UbException(UB_EXARGS,"QCriterionCoProcessor: NX1 too small for FD stencils!");
+	maxX1 -= 2;
+	maxX2 -= 2;
+	maxX3 -= 2;
+	bool checkInterpolation=true;
+	bool neighNodeIsBC=false;
+	BoundaryConditionsPtr bcPtr;
+
+	int rankSelf= block->getRank(); 
+	if (!(offx+offy+offz)==1) throw UbException(UB_EXARGS,"getNeighborVelocities called for diagonal directions!");
+	//////get neighbor nodes, if existent
+	if ((ix1==0 && offx==1) || (ix2==0 && offy==1) || (ix3==0 && offz==1))
+	{
+		int RankNeighborW; 
+		Vector3D orgNodeRW =  grid->getNodeCoordinates(block,  ix1, ix2, ix3);
+		double xp000= orgNodeRW[0];
+		double yp000= orgNodeRW[1];
+		double zp000= orgNodeRW[2];
+
+		int currentLevel = block->getLevel();
+		UbTupleInt3 blockIndexes = grid->getBlockIndexes(xp000,yp000, zp000,currentLevel);
+		Block3DPtr blockNeighW;
+
+		if ((val<1>(blockIndexes)!=0 && offx==1) || (val<2>(blockIndexes)!=0 && offy==1) || (val<3>(blockIndexes)!=0 && offz==1))
+		{
+
+			blockNeighW = grid->getBlock(val<1>(blockIndexes)-offx, val<2>(blockIndexes)-offy, val<3>(blockIndexes)-offz, currentLevel);
+
+		}
+		else if (offx==1 && grid->isPeriodicX1())
+		{
+			blockNeighW = grid->getBlock((grid->getNX1()-1), val<2>(blockIndexes), val<3>(blockIndexes), currentLevel);
+		}
+		else if (offy==1 && grid->isPeriodicX1())
+		{
+			blockNeighW = grid->getBlock(val<1>(blockIndexes),(grid->getNX2()-1),  val<3>(blockIndexes), currentLevel);
+		}
+		else if (offz==1 && grid->isPeriodicX1())
+		{
+			blockNeighW = grid->getBlock( val<1>(blockIndexes), val<2>(blockIndexes),(grid->getNX3()-1), currentLevel);
+		}
+		else neighNodeIsBC;
+
+		if(blockNeighW && blockNeighW->isActive())
+		{	     		     
+			RankNeighborW= blockNeighW->getRank();   
+		}
+		else
+		{
+
+			blockNeighW = block;
+			RankNeighborW= blockNeighW->getRank();
+			checkInterpolation=false;
+		}
+		if (RankNeighborW!=rankSelf)
+		{
+
+			blockNeighW = block;
+			RankNeighborW= blockNeighW->getRank();
+			checkInterpolation=false;
+		}
+
+		///////////////////////////////////////
+		////compute distribution at neighboring nodes from neighboring blocks
+
+		if (checkInterpolation==false || neighNodeIsBC)
+		{
+			ILBMKernelPtr kernelW = blockNeighW->getKernel();
+			BCArray3DPtr bcArrayW = kernelW->getBCProcessor()->getBCArray();          
+			DistributionArray3DPtr distributionsW = kernelW->getDataSet()->getFdistributions();
+			LBMReal fW2[27];
+			LBMReal fW[27];
+			LBMReal f0[27];
+			LBMReal fE[27];
+			LBMReal v0[3];
+			LBMReal vW2[3];
+			//distributionsW->getDistribution(fW2, std::max(ix1+2*offx,1), std::max(ix2+2*offy,1), std::max(ix3+2*offz,1));
+			//distributionsW->getDistribution(fW, std::max(ix1+offx,1), std::max(ix2+offy,1), std::max(ix3+offz,1));
+			//distributionsW->getDistribution(f0, std::max(ix1    ,1), std::max(ix2    ,1), std::max(ix3    ,1));
+			//distributions->getDistribution(fE, std::max(ix1+offx    ,1), std::max(ix2+offy    ,1), std::max(ix3+offz    ,1)); //E:= plus 1
+			distributionsW->getDistribution(fW2, std::max(ix1+2*offx,0), std::max(ix2+2*offy,0), std::max(ix3+2*offz,0));
+			distributionsW->getDistribution(fW, std::max(ix1+offx,0), std::max(ix2+offy,0), std::max(ix3+offz,0));
+			distributionsW->getDistribution(f0, std::max(ix1    ,0), std::max(ix2    ,0), std::max(ix3    ,0));
+			distributions->getDistribution(fE, std::max(ix1+offx    ,0), std::max(ix2+offy    ,0), std::max(ix3+offz    ,0)); //E:= plus 1
+
+			computeVelocity(fE,vE,compressible);
+			computeVelocity(fW,vW,compressible);
+			computeVelocity(fW2,vW2,compressible);
+			computeVelocity(f0,v0,compressible);
+			//second order non-symetric interpolation
+			vW[0]=v0[0]*1.5-vW[0]+0.5*vW2[0];
+			vW[1]=v0[1]*1.5-vW[1]+0.5*vW2[1];
+			vW[2]=v0[2]*1.5-vW[2]+0.5*vW2[2];
+		    //throw UbException(UB_EXARGS,"Parallel or Non-Uniform Simulation -- not yet implemented");
+		}
+		else
+		{
+			ILBMKernelPtr kernelW = blockNeighW->getKernel();
+			BCArray3DPtr bcArrayW = kernelW->getBCProcessor()->getBCArray();          
+			DistributionArray3DPtr distributionsW = kernelW->getDataSet()->getFdistributions();
+			LBMReal fW[27];
+
+			if (offx==1)
+			{
+				distributionsW->getDistribution(fW, (distributions->getNX1())-1, ix2, ix3); //moved one block backward, now get last entry
+			}
+			else if (offy==1)
+			{
+				distributionsW->getDistribution(fW, ix1,(distributions->getNX2())-1, ix3); 
+
+			}
+			else if (offz==1)
+			{
+				distributionsW->getDistribution(fW, ix1,ix2,distributions->getNX3()-1); 
+			}
+			computeVelocity(fW,vW,compressible);
+		}
+
+
+	}					 
+	else
+	{
+		//data available in current block:
+		LBMReal fW[27];
+		distributions->getDistribution(fW, ix1-offx, ix2-offy, ix3-offz);
+		computeVelocity(fW,vW,compressible);
+
+	}
+	if (checkInterpolation==true)
+	{
+		//in plus-direction data is available in current block because of ghost layers
+		LBMReal fE[27];
+		distributions->getDistribution(fE, ix1+offx, ix2+offy, ix3+offz); //E:= plus 1
+		computeVelocity(fE,vE,compressible);
+	}
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void QCriterionCoProcessor::computeVelocity(LBMReal* f, LBMReal* v, bool compressible)
+{
+	//////////////////////////////////////////////////////////////////////////
+	//compute x,y,z-velocity components from distribution
+	//////////////////////////////////////////////////////////////////////////
+   if (compressible)
+   {
+      v[xdir] = D3Q27System::getCompVelocityX1(f);
+      v[ydir] = D3Q27System::getCompVelocityX2(f);
+      v[zdir] = D3Q27System::getCompVelocityX3(f);
+   } 
+   else
+   {
+      v[xdir] = D3Q27System::getIncompVelocityX1(f);
+      v[ydir] = D3Q27System::getIncompVelocityX2(f);
+      v[zdir] = D3Q27System::getIncompVelocityX3(f);
+   }
+}
diff --git a/source/VirtualFluidsCore/CoProcessors/QCriterionCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/QCriterionCoProcessor.h
index df84a6109..7651d9fca 100644
--- a/source/VirtualFluidsCore/CoProcessors/QCriterionCoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/QCriterionCoProcessor.h
@@ -6,16 +6,21 @@
 #ifndef QCriterionCoProcessor_H
 #define QCriterionCoProcessor_H
 
+#include <memory>
+#include <string>
+#include <vector>
+
 #include "CoProcessor.h"
-#include "Grid3D.h"
-#include "Block3D.h"
+#include "LBMSystem.h"
 
-#include "Communicator.h"
-#include "WbWriter.h"
+class Communicator;
+class Grid3D;
+class UbScheduler;
+class WbWriter;
+class Block3D;
 
-#include <boost/shared_ptr.hpp>
 class QCriterionCoProcessor;
-typedef boost::shared_ptr<QCriterionCoProcessor> QCriterionCoProcessorPtr;
+typedef std::shared_ptr<QCriterionCoProcessor> QCriterionCoProcessorPtr;
 
 //! \brief  Computes the value Q with which vortices can be visualized as isocontours to Q=0, writes to .vtk, For uniform, serial setups only!
 //! \details writes at given time intervals specified in scheduler (s)  
@@ -26,21 +31,22 @@ typedef boost::shared_ptr<QCriterionCoProcessor> QCriterionCoProcessorPtr;
 class QCriterionCoProcessor : public CoProcessor
 {
 public:
-	QCriterionCoProcessor(Grid3DPtr grid, const std::string& path, WbWriter* const writer, 
-		UbSchedulerPtr s, CommunicatorPtr comm);
+	QCriterionCoProcessor(std::shared_ptr<Grid3D> grid, const std::string& path, WbWriter* const writer,
+        std::shared_ptr<UbScheduler> s, std::shared_ptr<Communicator> comm);
 	//! Make update if timestep is write-timestep specified in UbSchedulerPtr s
-	void process(double step); 
+	void process(double step) override; 
+
 protected:
 	//! Prepare data and write in .vtk file
 	void collectData(double step);
 	//! Q is computed for all points in a block. Data for writing is added to data and cell vectors. 
-	void addData(const Block3DPtr block);
+	void addData(const std::shared_ptr<Block3D> block);
 	//! After writing to .vtk-file, all vectors are reset 
 	void clearData();
 	//! Computes macroscopic velocities 
 	void computeVelocity(LBMReal* f, LBMReal* v, bool compressible);
 	//! Computes average and RMS values of macroscopic quantities 
-	void getNeighborVelocities(int offx, int offy, int offz, int ix1, int ix2, int ix3,const Block3DPtr block, LBMReal* vE,LBMReal* vW);
+	void getNeighborVelocities(int offx, int offy, int offz, int ix1, int ix2, int ix3,const std::shared_ptr<Block3D> block, LBMReal* vE,LBMReal* vW);
 
 private:
 	void init();
@@ -48,15 +54,16 @@ private:
 	std::vector<UbTupleInt8> cells;
 	std::vector<std::string> datanames; //only one entry for QKrit-CoProcessor: Q
 	std::vector<std::vector<double> > data; 
-	std::vector<std::vector<Block3DPtr> > blockVector;
+	std::vector<std::vector<std::shared_ptr<Block3D> > > blockVector;
 	int minInitLevel; //go through all levels for block vector of current process from minInitLevel to maxInitLevel
 	int maxInitLevel;
 	int gridRank;     //comm-Rank des aktuellen prozesses
 	std::string path;
 	WbWriter* writer;
-	CommunicatorPtr comm;
+    std::shared_ptr<Communicator> comm;
 	enum Values{xdir = 0, ydir = 1, zdir = 2};  	//labels for the different components
 };
+
 #endif
 
 
diff --git a/source/VirtualFluidsCore/CoProcessors/RestartCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/RestartCoProcessor.cpp
index c65602e3a..a7f6caae6 100644
--- a/source/VirtualFluidsCore/CoProcessors/RestartCoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/RestartCoProcessor.cpp
@@ -1,369 +1,380 @@
-#include "RestartCoProcessor.h"
-#include <boost/archive/binary_oarchive.hpp>
-#include <boost/archive/binary_iarchive.hpp>
-
-#include <boost/archive/text_oarchive.hpp>
-#include <boost/archive/text_iarchive.hpp>
-
-#include <basics/utilities/UbFileOutputASCII.h>
-#include <basics/utilities/UbFileInputASCII.h>
-
-#include "MetisPartitioningGridVisitor.h"
-
-#include "BoostSerializationClassExportHelper.h"
-
-#include <MemoryUtil.h>
-#include <vector>
-
-RestartCoProcessor::RestartCoProcessor(Grid3DPtr& grid, UbSchedulerPtr s, CommunicatorPtr comm, const std::string& path, ArchiveType type) :
-   CoProcessor(grid, s),
-   grid(grid),
-   path(path),
-   archiveType(type),
-   comm(comm)
-{
-   restartStep = 0;
-   this->path = path + "/checkpoints";
-   metafile = this->path + "/LastCP.txt";
-   if (comm->getProcessID() == comm->getRoot())
-   {
-      checkMetafile();
-   }
-   comm->barrier();
-   grid = restart();
-}
-//////////////////////////////////////////////////////////////////////////
-RestartCoProcessor::RestartCoProcessor(Grid3DPtr& grid, UbSchedulerPtr s, CommunicatorPtr comm, const std::string& path, int restartStep, ArchiveType type) :
-CoProcessor(grid, s),
-grid(grid),
-path(path),
-archiveType(type),
-comm(comm),
-restartStep(restartStep)
-{
-   this->path = path + "/checkpoints";
-   metafile = this->path + "/LastCP.txt";
-   if (comm->getProcessID() == comm->getRoot())
-   {
-      writeMetafile(restartStep);
-   }
-   comm->barrier();
-   grid = restart();
-}
-//////////////////////////////////////////////////////////////////////////
-RestartCoProcessor::~RestartCoProcessor()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-void RestartCoProcessor::process(double step)
-{
-   if(scheduler->isDue(step) && step != restartStep)
-   {
-      doCheckPoint(int(step));
-
-      if(comm->getProcessID() == comm->getRoot()) UBLOG(logINFO,"RestartCoProcessor save step: " << step);
-
-      UBLOG(logDEBUG3, "RestartCoProcessor::update:" << step);
-   }   
-}
-//////////////////////////////////////////////////////////////////////////
-void RestartCoProcessor::addCoProcessor( CoProcessorPtr p )
-{
-   CoProcessors.push_back(p);
-}
-//////////////////////////////////////////////////////////////////////////
-CoProcessorPtr RestartCoProcessor::getCoProcessor(int index)
-{
-   return CoProcessors[index];
-}
-//////////////////////////////////////////////////////////////////////////
-std::vector<CoProcessorPtr> RestartCoProcessor::getCoProcessors()
-{
-   return CoProcessors;
-}
-//////////////////////////////////////////////////////////////////////////
-void RestartCoProcessor::doCheckPoint(int step)
-{
-   UBLOG(logDEBUG3,"Save check point - start");
-
-   int pid = comm->getProcessID();
-   std::string filename = path + "/checkpoint" + UbSystem::toString(step) + "/checkpoint" + UbSystem::toString(pid) + "_" + UbSystem::toString(step);
-
-   if (archiveType == TXT)
-   {
-      saveTxtArchive(filename + ".txt", grid);
-   } 
-   else if(archiveType == BINARY)
-   {
-      saveBinArchive(filename + ".bin", grid);
-   }
-
-   comm->barrier();
-
-   if (comm->getProcessID() == comm->getRoot())
-   {
-      writeMetafile(step);
-   }
-
-   UBLOG(logDEBUG3,"Save check point - end");
-}
-//////////////////////////////////////////////////////////////////////////
-Grid3DPtr RestartCoProcessor::restart()
-{
-   restartStep = readMetafile();
-
-   comm->barrier();
-
-   if (restartStep > 0)
-   {
-      if(comm->getProcessID() == comm->getRoot()) UBLOG(logINFO,"Load check point - start");
-      int pid = comm->getProcessID();
-      std::string filename = path + "/checkpoint" + UbSystem::toString(restartStep) + "/checkpoint" + UbSystem::toString(pid) + "_" + UbSystem::toString(restartStep);
-
-      if (archiveType == TXT)
-      {
-         loadTxtArchive(filename + ".txt");
-      } 
-      else if(archiveType == BINARY)
-      {
-         loadBinArchive(filename + ".bin");
-      }
-
-      this->reconnect(grid);
-      if(comm->getProcessID() == comm->getRoot()) UBLOG(logINFO,"Load check point - end");
-
-      if(comm->getProcessID() == comm->getRoot()) UBLOG(logINFO,"RestartCoProcessor restart step: " << restartStep);
-
-      return grid;
-   } 
-   else
-   {
-      return grid;
-   }
-
-}
-//////////////////////////////////////////////////////////////////////////
-void RestartCoProcessor::acceptGridVisitors()
-{
-   BOOST_FOREACH(Grid3DVisitorPtr v, gridVisitors)
-   {
-      grid->accept(*(v.get()));
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void RestartCoProcessor::acceptBlockVisitors()
-{
-   BOOST_FOREACH(Block3DVisitorPtr v, blockVisitors)
-   {
-      grid->accept(*(v.get()));
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void RestartCoProcessor::addGridVisitor( Grid3DVisitorPtr v )
-{
-   gridVisitors.push_back(v);
-}
-//////////////////////////////////////////////////////////////////////////
-void RestartCoProcessor::addBlockVisitor( Block3DVisitorPtr v )
-{
-   blockVisitors.push_back(v);
-}
-//////////////////////////////////////////////////////////////////////////
-void RestartCoProcessor::saveTxtArchive( std::string filename, Grid3DPtr grid )
-{
-   std::ofstream file(filename.c_str()); 
-   if(!file)
-   { 
-      file.clear(); 
-      std::string path = UbSystem::getPathFromString(filename);
-      if(path.size()>0){ UbSystem::makeDirectory(path); file.open(filename.c_str());}
-      if(!file) throw UbException(UB_EXARGS,"couldn't open file "+filename);
-   }
-   boost::archive::text_oarchive oa(file);
-   oa.register_type<Grid3D>();
-   oa << grid;
-
-   int psize = (int)CoProcessors.size(); 
-   oa << psize;
-
-   oa.register_type<CoProcessorPtr>();
-   BOOST_FOREACH(CoProcessorPtr pp, CoProcessors)
-   {
-      oa << pp;
-   }
-   file.close();
-}
-//////////////////////////////////////////////////////////////////////////
-void RestartCoProcessor::loadTxtArchive( std::string filename )
-{
-   std::ifstream file(filename.c_str()); 
-   if (!file.is_open()) UB_THROW( UbException(UB_EXARGS,"Can not open check point file \"" + filename + "\""));
-   boost::archive::text_iarchive ia(file);
-   ia.register_type<Grid3D>();
-   ia >> grid; 
-
-   int psize;
-   ia >> psize;
-
-   ia.register_type<CoProcessorPtr>();
-   for (int i = 0; i < psize; i++)
-   {
-      CoProcessorPtr pp;
-      ia >> pp;
-      pp->reconnect(grid);
-      CoProcessors.push_back(pp);
-   }
-   file.close();
-}
-//////////////////////////////////////////////////////////////////////////
-void RestartCoProcessor::saveBinArchive( std::string filename, Grid3DPtr grid )
-{
-   //impotent for binary archive add std::ios::binary
-   std::ofstream file(filename.c_str(), std::ios::binary); 
-   if(!file)
-   { 
-      file.clear(); 
-      std::string path = UbSystem::getPathFromString(filename);
-      if(path.size()>0){ UbSystem::makeDirectory(path); file.open(filename.c_str());}
-      if(!file) throw UbException(UB_EXARGS,"couldn't open file "+filename);
-   }
-   boost::archive::binary_oarchive oa(file);
-   oa.register_type<Grid3D>();
-   oa << grid;
-
-   int psize = (int)CoProcessors.size(); 
-   oa << psize;
-
-   oa.register_type<CoProcessorPtr>();
-   BOOST_FOREACH(CoProcessorPtr pp, CoProcessors)
-   {
-      oa << pp;
-   }
-   file.close();
-}
-//////////////////////////////////////////////////////////////////////////
-void RestartCoProcessor::loadBinArchive( std::string filename )
-{
-   //impotent for binary archive add std::ios::binary
-   std::ifstream file(filename.c_str(), std::ios::binary); 
-   if (!file.is_open()) UB_THROW( UbException(UB_EXARGS,"Can not open check point file \"" + filename + "\""));
-   boost::archive::binary_iarchive ia(file);
-   ia.register_type<Grid3D>();
-   ia >> grid;
-
-   int psize;
-   ia >> psize;
-
-   ia.register_type<CoProcessorPtr>();
-   for (int i = 0; i < psize; i++)
-   {
-      CoProcessorPtr pp;
-      ia >> pp;
-      pp->reconnect(grid);
-      CoProcessors.push_back(pp);
-   }
-   file.close();
-}
-//////////////////////////////////////////////////////////////////////////
-void RestartCoProcessor::writeMetafile(int step )
-{
-   UbFileOutputASCII out(metafile);
-   out.writeInteger(step);
-}
-//////////////////////////////////////////////////////////////////////////
-int RestartCoProcessor::readMetafile()
-{
-   UbFileInputASCII in(metafile);
-   return in.readInteger();
-}
-//////////////////////////////////////////////////////////////////////////
-void RestartCoProcessor::checkMetafile()
-{
-   std::ifstream file(metafile.c_str()); 
-   if (!file.is_open()) 
-   {
-      writeMetafile(0);
-      return;
-   }
-   file.close();
-}
-//////////////////////////////////////////////////////////////////////////
-void RestartCoProcessor::writeDistributedGrid(Grid3DPtr sgrid, int numberOfProcesses)
-{
-   using namespace std;
-
-   Grid3DVisitorPtr metisVisitor(new MetisPartitioningGridVisitor(comm, MetisPartitioningGridVisitor::LevelBased, D3Q27System::BSW, MetisPartitioner::RECURSIVE));
-   boost::dynamic_pointer_cast<MetisPartitioningGridVisitor>(metisVisitor)->setNumberOfProcesses(numberOfProcesses);
-   sgrid->accept(metisVisitor);
-
-   int minInitLevel = sgrid->getCoarsestInitializedLevel();
-   int maxInitLevel = sgrid->getFinestInitializedLevel();
-
-   for (int i = 0; i<numberOfProcesses; i++)
-   {
-      UBLOG(logINFO, "Create dump file for rank " << i <<" - start");
-      Grid3DPtr newGrid(new Grid3D());
-      newGrid->setRank(i);
-      newGrid->setDeltaX(sgrid->getDeltaX(0));
-      newGrid->setNX1(sgrid->getNX1());
-      newGrid->setNX2(sgrid->getNX2());
-      newGrid->setNX3(sgrid->getNX3());
-      newGrid->setCoordinateTransformator(sgrid->getCoordinateTransformator());
-      UbTupleInt3 blockNX = sgrid->getBlockNX();
-      newGrid->setBlockNX(val<1>(blockNX), val<2>(blockNX), val<3>(blockNX));
-      Grid3D::Interactor3DSet interactors = sgrid->getInteractors();
-      for(int inter=0; inter < interactors.size(); inter++)
-      {
-         newGrid->addInteractor(interactors[inter]);
-      }
-
-      for (int level = minInitLevel; level<=maxInitLevel; level++)
-      {
-         vector<Block3DPtr> blockVector;
-         grid->getBlocks(level, blockVector);
-         BOOST_FOREACH(Block3DPtr block, blockVector)
-         {
-            if (block)
-            {
-               if (block->getRank() == i)
-               {
-                  newGrid->addBlock(block);
-               } 
-               else
-               {
-                  Block3DPtr newBlock(new Block3D(block->getX1(), block->getX2(), block->getX3(), block->getLevel()));
-                  newBlock->setRank(block->getRank());
-                  newGrid->addBlock(newBlock);
-               }
-            }
-         }
-      }
-
-      std::string filename = path+"/checkpoint"+UbSystem::toString(1)+"/checkpoint"+UbSystem::toString(i)+"_"+UbSystem::toString(1);
-
-      if (archiveType==TXT)
-      {
-         saveTxtArchive(filename+".txt", newGrid);
-      }
-      else if (archiveType==BINARY)
-      {
-         saveBinArchive(filename+".bin", newGrid);
-      }
-
-      UBLOG(logINFO, "Create dump file for rank " << i <<" - end");
-   }
-   writeMetafile(1);
-}
-//////////////////////////////////////////////////////////////////////////
-void RestartCoProcessor::setArchiveType(ArchiveType type)
-{
-   archiveType = type;
-}
-//////////////////////////////////////////////////////////////////////////
-RestartCoProcessor::ArchiveType RestartCoProcessor::getArchiveType()
-{
-   return archiveType;
-}
-
-
+#include "RestartCoProcessor.h"
+#include <boost/archive/binary_oarchive.hpp>
+#include <boost/archive/binary_iarchive.hpp>
+
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+
+#include <basics/utilities/UbFileOutputASCII.h>
+#include <basics/utilities/UbFileInputASCII.h>
+
+#include <boost/serialization/map.hpp>
+
+#include "MetisPartitioningGridVisitor.h"
+#include "BCArray3D.h"
+#include "CoordinateTransformation3D.h"
+#include "BoostSerializationClassExportHelper.h"
+
+#include <MemoryUtil.h>
+
+
+#include "Grid3D.h"
+#include "Grid3DVisitor.h"
+#include "Block3DVisitor.h"
+#include "Communicator.h"
+#include "UbScheduler.h"
+#include "Block3D.h"
+
+
+RestartCoProcessor::RestartCoProcessor(Grid3DPtr& grid, UbSchedulerPtr s, CommunicatorPtr comm, const std::string& path, ArchiveType type) :
+   CoProcessor(grid, s),
+   grid(grid),
+   path(path),
+   archiveType(type),
+   comm(comm)
+{
+   restartStep = 0;
+   this->path = path + "/checkpoints";
+   metafile = this->path + "/LastCP.txt";
+   if (comm->getProcessID() == comm->getRoot())
+   {
+      checkMetafile();
+   }
+   comm->barrier();
+   grid = restart();
+}
+//////////////////////////////////////////////////////////////////////////
+RestartCoProcessor::RestartCoProcessor(Grid3DPtr& grid, UbSchedulerPtr s, CommunicatorPtr comm, const std::string& path, int restartStep, ArchiveType type) :
+CoProcessor(grid, s),
+grid(grid),
+path(path),
+archiveType(type),
+comm(comm),
+restartStep(restartStep)
+{
+   this->path = path + "/checkpoints";
+   metafile = this->path + "/LastCP.txt";
+   if (comm->getProcessID() == comm->getRoot())
+   {
+      writeMetafile(restartStep);
+   }
+   comm->barrier();
+   grid = restart();
+}
+//////////////////////////////////////////////////////////////////////////
+RestartCoProcessor::~RestartCoProcessor()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void RestartCoProcessor::process(double step)
+{
+   if(scheduler->isDue(step) && step != restartStep)
+   {
+      doCheckPoint(int(step));
+
+      if(comm->getProcessID() == comm->getRoot()) UBLOG(logINFO,"RestartCoProcessor save step: " << step);
+
+      UBLOG(logDEBUG3, "RestartCoProcessor::update:" << step);
+   }   
+}
+//////////////////////////////////////////////////////////////////////////
+void RestartCoProcessor::addCoProcessor( CoProcessorPtr p )
+{
+   CoProcessors.push_back(p);
+}
+//////////////////////////////////////////////////////////////////////////
+CoProcessorPtr RestartCoProcessor::getCoProcessor(int index)
+{
+   return CoProcessors[index];
+}
+//////////////////////////////////////////////////////////////////////////
+std::vector<CoProcessorPtr> RestartCoProcessor::getCoProcessors()
+{
+   return CoProcessors;
+}
+//////////////////////////////////////////////////////////////////////////
+void RestartCoProcessor::doCheckPoint(int step)
+{
+   UBLOG(logDEBUG3,"Save check point - start");
+
+   int pid = comm->getProcessID();
+   std::string filename = path + "/checkpoint" + UbSystem::toString(step) + "/checkpoint" + UbSystem::toString(pid) + "_" + UbSystem::toString(step);
+
+   if (archiveType == TXT)
+   {
+      saveTxtArchive(filename + ".txt", grid);
+   } 
+   else if(archiveType == BINARY)
+   {
+      saveBinArchive(filename + ".bin", grid);
+   }
+
+   comm->barrier();
+
+   if (comm->getProcessID() == comm->getRoot())
+   {
+      writeMetafile(step);
+   }
+
+   UBLOG(logDEBUG3,"Save check point - end");
+}
+//////////////////////////////////////////////////////////////////////////
+Grid3DPtr RestartCoProcessor::restart()
+{
+   restartStep = readMetafile();
+
+   comm->barrier();
+
+   if (restartStep > 0)
+   {
+      if(comm->getProcessID() == comm->getRoot()) UBLOG(logINFO,"Load check point - start");
+      int pid = comm->getProcessID();
+      std::string filename = path + "/checkpoint" + UbSystem::toString(restartStep) + "/checkpoint" + UbSystem::toString(pid) + "_" + UbSystem::toString(restartStep);
+
+      if (archiveType == TXT)
+      {
+         loadTxtArchive(filename + ".txt");
+      } 
+      else if(archiveType == BINARY)
+      {
+         loadBinArchive(filename + ".bin");
+      }
+
+      this->reconnect(grid);
+      if(comm->getProcessID() == comm->getRoot()) UBLOG(logINFO,"Load check point - end");
+
+      if(comm->getProcessID() == comm->getRoot()) UBLOG(logINFO,"RestartCoProcessor restart step: " << restartStep);
+
+      return grid;
+   } 
+   else
+   {
+      return grid;
+   }
+
+}
+//////////////////////////////////////////////////////////////////////////
+void RestartCoProcessor::acceptGridVisitors()
+{
+   for(Grid3DVisitorPtr v : gridVisitors)
+   {
+      grid->accept(*(v.get()));
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void RestartCoProcessor::acceptBlockVisitors()
+{
+   for(Block3DVisitorPtr v : blockVisitors)
+   {
+      grid->accept(*(v.get()));
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void RestartCoProcessor::addGridVisitor( Grid3DVisitorPtr v )
+{
+   gridVisitors.push_back(v);
+}
+//////////////////////////////////////////////////////////////////////////
+void RestartCoProcessor::addBlockVisitor( Block3DVisitorPtr v )
+{
+   blockVisitors.push_back(v);
+}
+//////////////////////////////////////////////////////////////////////////
+void RestartCoProcessor::saveTxtArchive( std::string filename, Grid3DPtr grid )
+{
+   std::ofstream file(filename.c_str()); 
+   if(!file)
+   { 
+      file.clear(); 
+      std::string path = UbSystem::getPathFromString(filename);
+      if(path.size()>0){ UbSystem::makeDirectory(path); file.open(filename.c_str());}
+      if(!file) throw UbException(UB_EXARGS,"couldn't open file "+filename);
+   }
+   boost::archive::text_oarchive oa(file);
+   oa.register_type<Grid3D>();
+   oa << grid;
+
+   int psize = (int)CoProcessors.size(); 
+   oa << psize;
+
+   oa.register_type<CoProcessorPtr>();
+   for(CoProcessorPtr pp : CoProcessors)
+   {
+      oa << pp;
+   }
+   file.close();
+}
+//////////////////////////////////////////////////////////////////////////
+void RestartCoProcessor::loadTxtArchive( std::string filename )
+{
+   std::ifstream file(filename.c_str()); 
+   if (!file.is_open()) UB_THROW( UbException(UB_EXARGS,"Can not open check point file \"" + filename + "\""));
+   boost::archive::text_iarchive ia(file);
+   ia.register_type<Grid3D>();
+   ia >> grid; 
+
+   int psize;
+   ia >> psize;
+
+   ia.register_type<CoProcessorPtr>();
+   for (int i = 0; i < psize; i++)
+   {
+      CoProcessorPtr pp;
+      ia >> pp;
+      pp->reconnect(grid);
+      CoProcessors.push_back(pp);
+   }
+   file.close();
+}
+//////////////////////////////////////////////////////////////////////////
+void RestartCoProcessor::saveBinArchive( std::string filename, Grid3DPtr grid )
+{
+   //impotent for binary archive add std::ios::binary
+   std::ofstream file(filename.c_str(), std::ios::binary); 
+   if(!file)
+   { 
+      file.clear(); 
+      std::string path = UbSystem::getPathFromString(filename);
+      if(path.size()>0){ UbSystem::makeDirectory(path); file.open(filename.c_str());}
+      if(!file) throw UbException(UB_EXARGS,"couldn't open file "+filename);
+   }
+   boost::archive::binary_oarchive oa(file);
+   oa.register_type<Grid3D>();
+   oa << grid;
+
+   int psize = (int)CoProcessors.size(); 
+   oa << psize;
+
+   oa.register_type<CoProcessorPtr>();
+   for(CoProcessorPtr pp : CoProcessors)
+   {
+      oa << pp;
+   }
+   file.close();
+}
+//////////////////////////////////////////////////////////////////////////
+void RestartCoProcessor::loadBinArchive( std::string filename )
+{
+   //impotent for binary archive add std::ios::binary
+   std::ifstream file(filename.c_str(), std::ios::binary); 
+   if (!file.is_open()) UB_THROW( UbException(UB_EXARGS,"Can not open check point file \"" + filename + "\""));
+   boost::archive::binary_iarchive ia(file);
+   ia.register_type<Grid3D>();
+   ia >> grid;
+
+   int psize;
+   ia >> psize;
+
+   ia.register_type<CoProcessorPtr>();
+   for (int i = 0; i < psize; i++)
+   {
+      CoProcessorPtr pp;
+      ia >> pp;
+      pp->reconnect(grid);
+      CoProcessors.push_back(pp);
+   }
+   file.close();
+}
+//////////////////////////////////////////////////////////////////////////
+void RestartCoProcessor::writeMetafile(int step )
+{
+   UbFileOutputASCII out(metafile);
+   out.writeInteger(step);
+}
+//////////////////////////////////////////////////////////////////////////
+int RestartCoProcessor::readMetafile()
+{
+   UbFileInputASCII in(metafile);
+   return in.readInteger();
+}
+//////////////////////////////////////////////////////////////////////////
+void RestartCoProcessor::checkMetafile()
+{
+   std::ifstream file(metafile.c_str()); 
+   if (!file.is_open()) 
+   {
+      writeMetafile(0);
+      return;
+   }
+   file.close();
+}
+//////////////////////////////////////////////////////////////////////////
+void RestartCoProcessor::writeDistributedGrid(Grid3DPtr sgrid, int numberOfProcesses)
+{
+   using namespace std;
+
+   Grid3DVisitorPtr metisVisitor(new MetisPartitioningGridVisitor(comm, MetisPartitioningGridVisitor::LevelBased, D3Q27System::BSW, MetisPartitioner::RECURSIVE));
+   std::dynamic_pointer_cast<MetisPartitioningGridVisitor>(metisVisitor)->setNumberOfProcesses(numberOfProcesses);
+   sgrid->accept(metisVisitor);
+
+   int minInitLevel = sgrid->getCoarsestInitializedLevel();
+   int maxInitLevel = sgrid->getFinestInitializedLevel();
+
+   for (int i = 0; i<numberOfProcesses; i++)
+   {
+      UBLOG(logINFO, "Create dump file for rank " << i <<" - start");
+      Grid3DPtr newGrid(new Grid3D());
+      newGrid->setRank(i);
+      newGrid->setDeltaX(sgrid->getDeltaX(0));
+      newGrid->setNX1(sgrid->getNX1());
+      newGrid->setNX2(sgrid->getNX2());
+      newGrid->setNX3(sgrid->getNX3());
+      newGrid->setCoordinateTransformator(sgrid->getCoordinateTransformator());
+      UbTupleInt3 blockNX = sgrid->getBlockNX();
+      newGrid->setBlockNX(val<1>(blockNX), val<2>(blockNX), val<3>(blockNX));
+      Grid3D::Interactor3DSet interactors = sgrid->getInteractors();
+      for(int inter=0; inter < interactors.size(); inter++)
+      {
+         newGrid->addInteractor(interactors[inter]);
+      }
+
+      for (int level = minInitLevel; level<=maxInitLevel; level++)
+      {
+         std::vector<Block3DPtr> blockVector;
+         grid->getBlocks(level, blockVector);
+         for(Block3DPtr block : blockVector)
+         {
+            if (block)
+            {
+               if (block->getRank() == i)
+               {
+                  newGrid->addBlock(block);
+               } 
+               else
+               {
+                  Block3DPtr newBlock(new Block3D(block->getX1(), block->getX2(), block->getX3(), block->getLevel()));
+                  newBlock->setRank(block->getRank());
+                  newGrid->addBlock(newBlock);
+               }
+            }
+         }
+      }
+
+      std::string filename = path+"/checkpoint"+UbSystem::toString(1)+"/checkpoint"+UbSystem::toString(i)+"_"+UbSystem::toString(1);
+
+      if (archiveType==TXT)
+      {
+         saveTxtArchive(filename+".txt", newGrid);
+      }
+      else if (archiveType==BINARY)
+      {
+         saveBinArchive(filename+".bin", newGrid);
+      }
+
+      UBLOG(logINFO, "Create dump file for rank " << i <<" - end");
+   }
+   writeMetafile(1);
+}
+//////////////////////////////////////////////////////////////////////////
+void RestartCoProcessor::setArchiveType(ArchiveType type)
+{
+   archiveType = type;
+}
+//////////////////////////////////////////////////////////////////////////
+RestartCoProcessor::ArchiveType RestartCoProcessor::getArchiveType()
+{
+   return archiveType;
+}
+
+
diff --git a/source/VirtualFluidsCore/CoProcessors/RestartCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/RestartCoProcessor.h
index ba0c25335..977bfa640 100644
--- a/source/VirtualFluidsCore/CoProcessors/RestartCoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/RestartCoProcessor.h
@@ -1,52 +1,61 @@
-#ifndef Restarter_H
-#define Restarter_H
+#ifndef RESTARTER_H
+#define RESTARTER_H
+
+#include <memory>
+#include <string>
+#include <vector>
 
 #include "CoProcessor.h"
-#include "Grid3DVisitor.h"
-#include "Block3DVisitor.h"
-#include "Communicator.h"
 
-#include <boost/shared_ptr.hpp>
+
+class Grid3D;
+class Grid3DVisitor;
+class Block3DVisitor;
+class Communicator;
+class UbScheduler;
+
 class RestartCoProcessor;
-typedef boost::shared_ptr<RestartCoProcessor> RestartCoProcessorPtr;
+typedef std::shared_ptr<RestartCoProcessor> RestartCoProcessorPtr;
 
 class RestartCoProcessor : public CoProcessor
 {
 public:
    enum ArchiveType {TXT, BINARY};
 public:
-   RestartCoProcessor(Grid3DPtr& grid, UbSchedulerPtr s, CommunicatorPtr comm, const std::string& path, ArchiveType type = BINARY);
-   RestartCoProcessor(Grid3DPtr& grid, UbSchedulerPtr s, CommunicatorPtr comm, const std::string& path, int restartStep, ArchiveType type = BINARY);
+   RestartCoProcessor(std::shared_ptr<Grid3D>& grid, std::shared_ptr<UbScheduler> s, std::shared_ptr<Communicator> comm, const std::string& path, ArchiveType type = BINARY);
+   RestartCoProcessor(std::shared_ptr<Grid3D>& grid, std::shared_ptr<UbScheduler> s, std::shared_ptr<Communicator> comm, const std::string& path, int restartStep, ArchiveType type = BINARY);
    ~RestartCoProcessor();
    void process(double step);
    void addCoProcessor(CoProcessorPtr p);
    CoProcessorPtr getCoProcessor(int index);
    std::vector<CoProcessorPtr> getCoProcessors();
-   void addGridVisitor(Grid3DVisitorPtr v);
-   void addBlockVisitor(Block3DVisitorPtr v);
+   void addGridVisitor(std::shared_ptr<Grid3DVisitor> v);
+   void addBlockVisitor(std::shared_ptr<Block3DVisitor> v);
    void doCheckPoint(int step);
-   Grid3DPtr restart();
-   void writeDistributedGrid(Grid3DPtr grid, int numberOfProcesses);
+   std::shared_ptr<Grid3D> restart();
+   void writeDistributedGrid(std::shared_ptr<Grid3D> grid, int numberOfProcesses);
    void setArchiveType(ArchiveType type);
    ArchiveType getArchiveType();
+
 protected:
    void acceptGridVisitors();
    void acceptBlockVisitors();
-   void saveTxtArchive(std::string filename, Grid3DPtr grid);
+   void saveTxtArchive(std::string filename, std::shared_ptr<Grid3D> grid);
    void loadTxtArchive(std::string filename);
-   void saveBinArchive(std::string filename, Grid3DPtr grid);
+   void saveBinArchive(std::string filename, std::shared_ptr<Grid3D> grid);
    void loadBinArchive(std::string filename);
    void writeMetafile(int step);
    int readMetafile();
    void checkMetafile();
+
 private:
    std::vector<CoProcessorPtr> CoProcessors;
-   std::vector<Grid3DVisitorPtr> gridVisitors;
-   std::vector<Block3DVisitorPtr> blockVisitors;
-   Grid3DPtr grid;
+   std::vector<std::shared_ptr<Grid3DVisitor> > gridVisitors;
+   std::vector<std::shared_ptr<Block3DVisitor>> blockVisitors;
+   std::shared_ptr<Grid3D> grid;
    std::string path;
    ArchiveType archiveType;
-   CommunicatorPtr comm;
+   std::shared_ptr<Communicator> comm;
    int restartStep;
    std::string metafile;
 };
diff --git a/source/VirtualFluidsCore/CoProcessors/ShearStressCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/ShearStressCoProcessor.cpp
index c3b139806..367ab8c97 100644
--- a/source/VirtualFluidsCore/CoProcessors/ShearStressCoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/ShearStressCoProcessor.cpp
@@ -1,693 +1,701 @@
-#include "ShearStressCoProcessor.h"
-#include "BCProcessor.h"
-#include "WbWriterVtkXmlASCII.h"
-
-
-ShearStressCoProcessor::ShearStressCoProcessor(Grid3DPtr grid, const std::string& path, 
-                                                             WbWriter* const writer,
-                                                             UbSchedulerPtr s,UbSchedulerPtr rs)
-                                                             : CoProcessor(grid, s),
-                                                             Resetscheduler(rs),
-                                                             path(path),
-                                                             writer(writer)
-{
-   CommunicatorPtr comm = Communicator::getInstance();
-   normals.push_back(0);
-   normals.push_back(0);
-   normals.push_back(1);
-   gridRank  = grid->getRank();
-   minInitLevel = this->grid->getCoarsestInitializedLevel();
-   maxInitLevel = this->grid->getFinestInitializedLevel();
-
-   blockVector.resize(maxInitLevel+1);
-   for(int level = minInitLevel; level<=maxInitLevel;level++)
-   {
-      grid->getBlocks(level, gridRank, true, blockVector[level]);
-      BOOST_FOREACH(Block3DPtr block, blockVector[level])
-      {
-         UbTupleInt3 nx = grid->getBlockNX();
-         ShearStressValuesArray3DPtr shearStressValues = ShearStressValuesArray3DPtr(new ShearStressValuesArray3D(14, val<1>(nx)+1, val<2>(nx)+1, val<3>(nx)+1, 0.0));
-         block->getKernel()->getDataSet()->setShearStressValues(shearStressValues);
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-ShearStressCoProcessor::~ShearStressCoProcessor()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-void ShearStressCoProcessor::process( double step )
-{
-   if (step==0)
-   {
-      initDistance();
-   }
-   calculateShearStress(step);
-   if(scheduler->isDue(step) )
-      collectData(step);
-   UBLOG(logDEBUG3, "D3Q27ShearStressCoProcessor::update:" << step);
-}
-//////////////////////////////////////////////////////////////////////////
-void ShearStressCoProcessor::collectData(double step)
-{
-   using namespace std;
-
-   int istep = int(step);
-   addData();
-
-   //string partName = writer->writeNodesWithNodeData(path+ UbSystem::toString(gridRank)+ "_" + UbSystem::toString(istep),nodes,datanames,data);
-   //size_t found=partName.find_last_of("//");
-   //string piece = partName.substr(found+1);
-
-   //vector<string> cellDataNames;
-
-   //CommunicatorPtr comm = Communicator::getInstance();
-   //vector<string> pieces = comm->gatherStrings(piece);
-   //if (comm->getProcessID() == comm->getRoot())
-   //{
-   //   string pname = WbWriterVtkXmlASCII::getInstance()->writeParallelFile(path+"_"+UbSystem::toString(istep),pieces,datanames,cellDataNames);
-
-   //   vector<string> filenames;
-   //   filenames.push_back(pname);
-   //   if (step == CoProcessor::scheduler->getMinBegin())
-   //   {
-   //      WbWriterVtkXmlASCII::getInstance()->writeCollection(path+"__Shear_collection",filenames,istep,false);
-   //   } 
-   //   else
-   //   {
-   //      WbWriterVtkXmlASCII::getInstance()->addFilesToCollection(path+"__Shear_collection",filenames,istep,false);
-   //   }
-   //   UBLOG(logINFO,"D3Q27ShearStressCoProcessor step: " << istep);
-   //}
-
-   string pfilePath, partPath, subfolder, cfilePath;
-   subfolder = "shs"+UbSystem::toString(istep);
-   pfilePath =  path+"/shs/"+subfolder;
-   cfilePath =  path+"/shs/shs_collection";
-   partPath = pfilePath+"/shs"+UbSystem::toString(gridRank)+ "_" + UbSystem::toString(istep);
-
-   string partName = writer->writeNodesWithNodeData(partPath,nodes,datanames,data);
-   size_t found=partName.find_last_of("/");
-   string piece = partName.substr(found+1);
-   piece = subfolder + "/" + piece;
-
-   vector<string> cellDataNames;
-   CommunicatorPtr comm = Communicator::getInstance();
-   vector<string> pieces = comm->gather(piece);
-   if (comm->getProcessID() == comm->getRoot())
-   {
-      string pname = WbWriterVtkXmlASCII::getInstance()->writeParallelFile(pfilePath,pieces,datanames,cellDataNames);
-      found=pname.find_last_of("/");
-      piece = pname.substr(found+1);
-
-      vector<string> filenames;
-      filenames.push_back(piece);
-      if (step == CoProcessor::scheduler->getMinBegin())
-      {
-         WbWriterVtkXmlASCII::getInstance()->writeCollection(cfilePath,filenames,istep,false);
-      } 
-      else
-      {
-         WbWriterVtkXmlASCII::getInstance()->addFilesToCollection(cfilePath,filenames,istep,false);
-      }
-      UBLOG(logINFO,"D3Q27ShearStressCoProcessor step: " << istep);
-   }
-
-   clearData();
-}
-//////////////////////////////////////////////////////////////////////////
-void ShearStressCoProcessor::clearData()
-{
-   nodes.clear();
-   datanames.clear();
-   data.clear();
-}
-//////////////////////////////////////////////////////////////////////////
-void ShearStressCoProcessor::calculateShearStress(double timeStep)
-{
-   using namespace D3Q27System;
-
-   LBMReal f[27];
-   LBMReal vx, vy, vz, sxx, syy, szz, sxy, syz, sxz;
-
-   BOOST_FOREACH(D3Q27InteractorPtr interactor, interactors)
-   {
-      typedef std::map<Block3DPtr, std::set< std::vector<int> > > TransNodeIndicesMap;
-      BOOST_FOREACH(TransNodeIndicesMap::value_type t, interactor->getBcNodeIndicesMap())
-      {
-         Block3DPtr block = t.first;
-         std::set< std::vector<int> >& transNodeIndicesSet = t.second;
-
-         LBMKernelPtr kernel = block->getKernel();
-         BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
-         DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions(); 
-         ShearStressValuesArray3DPtr ssv = kernel->getDataSet()->getShearStressValues();
-
-         int ghostLayer = kernel->getGhostLayerWidth();
-         LBMReal collFactor = kernel->getCollisionFactor();
-
-         int minX1 = ghostLayer;
-         int maxX1 = (int)bcArray->getNX1() - 1 - ghostLayer;
-         int minX2 = ghostLayer;
-         int maxX2 = (int)bcArray->getNX2() - 1 - ghostLayer;
-         int minX3 = ghostLayer;
-         int maxX3 = (int)bcArray->getNX3() - 1 - ghostLayer;
-
-         BOOST_FOREACH(std::vector<int> node, transNodeIndicesSet)
-         {
-            int ix1 = node[0];
-            int ix2 = node[1];
-            int ix3 = node[2];
-
-            //without ghost nodes
-            if (ix1 < minX1 || ix1 > maxX1 || ix2 < minX2 || ix2 > maxX2 ||ix3 < minX3 || ix3 > maxX3 ) continue;
-
-            if(bcArray->isFluid(ix1,ix2,ix3)) 
-            {
-               double q=(*ssv)(normalq,ix1,ix2,ix3) ;
-               double numPoint=(*ssv)(numberOfPoint,ix1,ix2,ix3) ;
-               if (q==0||numPoint!=3)continue;
-               // if (q==0)continue;
-               //////////////////////////////////////////////////////////////////////////
-               //read distribution
-               ////////////////////////////////////////////////////////////////////////////
-               distributions->getDistribution(f, ix1, ix2, ix3);
-               //////////////////////////////////////////////////////////////////////////
-               //compute velocity
-               //////////////////////////////////////////////////////////////////////////
-               vx = ((((f[TNE]-f[BSW]) + (f[TSE]-f[BNW])) + ((f[BSE]-f[TNW]) + (f[BNE]-f[TSW]))) +
-                  (((f[BE]-f[TW]) + (f[TE]-f[BW])) + ((f[SE]-f[NW]) + (f[NE]-f[SW]))) +
-                  (f[E]-f[W])); 
-
-               vy = ((((f[TNE]-f[BSW]) + (f[BNW]-f[TSE])) + ((f[TNW]-f[BSE]) + (f[BNE]-f[TSW]))) +
-                  (((f[BN]-f[TS]) + (f[TN]-f[BS])) + ((f[NW]-f[SE]) + (f[NE]-f[SW]))) +
-                  (f[N]-f[S])); 
-
-               vz = ((((f[TNE]-f[BSW]) + (f[TSE]-f[BNW])) + ((f[TNW]-f[BSE]) + (f[TSW]-f[BNE]))) +
-                  (((f[TS]-f[BN]) + (f[TN]-f[BS])) + ((f[TW]-f[BE]) + (f[TE]-f[BW]))) +
-                  (f[T]-f[B]));
-
-
-               sxy = 3.0 * collFactor/(collFactor - 1.0)* ( ((f[TNE] + f[BSW])-(f[TSE]+f[BNW]))+(-(f[BSE]+f[TNW])+ (f[TSW]+f[BNE]))
-                  +(((f[NE] + f[SW]) - (f[SE] + f[NW])))  -vx*vy);
-
-               sxz = 3.0 * collFactor/(collFactor-1.0)*(((f[TNE] + f[BSW])+(f[TSE]+f[BNW]))+(-(f[BSE]+f[TNW])- (f[TSW]+f[BNE]))
-                  +((f[TE] + f[BW])-(f[BE]+ f[TW])) -vx*vz);
-
-               syz = 3.0 * collFactor/(collFactor-1.0)*(((f[TNE] + f[BSW])-(f[TSE]+f[BNW]))+((f[BSE]+f[TNW])- (f[TSW]+f[BNE]))
-                  +(-(f[BN] + f[TS]) + (f[TN] + f[BS])) -vy*vz);                 
-
-               LBMReal dxxMyy =3.0/2.0 * collFactor/(collFactor-1.0)* (((f[TE] + f[BW])+(f[BE]+ f[TW]))
-                  -((f[BN] + f[TS]) + (f[TN] + f[BS]))+((f[E] + f[W])-(f[N] + f[S]))-vx*vx+vy*vy);
-
-               LBMReal dxxMzz =3.0/2.0 * collFactor/(collFactor-1.0)*((((f[NE] + f[SW]) + (f[SE] + f[NW]))
-                  -((f[BN] + f[TS]) + (f[TN] + f[BS])))+((f[E] + f[W])-(f[T] + f[B])) -vx*vx +vz*vz);
-
-               // LBMReal dyyMzz =3.0/2.0 *collFactor/(collFactor-1.0)*((((f[NE] + f[SW]) + (f[SE] + f[NW]))-((f[TE] + f[BW])+(f[BE]+ f[TW])))
-               //    +((f[N] + f[S])-(f[T] + f[B])) -vy*vy +vz*vz);
-
-               sxx=(dxxMyy+dxxMzz)/3.0; // weil dxxPyyPzz=0
-
-               syy=(dxxMzz-2*dxxMyy)/3.0;
-
-               szz=(dxxMyy-2*dxxMzz)/3.0;
-
-               //////////////////////////////////////////////////////////////////////////
-               //compute average values
-               //////////////////////////////////////////////////////////////////////////
-               (*ssv)(AvVx,ix1,ix2,ix3) = ((*ssv)(AvVx,ix1,ix2,ix3)*timeStep + vx)/(timeStep+1.0);
-               (*ssv)(AvVy,ix1,ix2,ix3) = ((*ssv)(AvVy,ix1,ix2,ix3)*timeStep + vy)/(timeStep+1.0);
-               (*ssv)(AvVz,ix1,ix2,ix3) = ((*ssv)(AvVz,ix1,ix2,ix3)*timeStep + vz)/(timeStep+1.0);
-
-               (*ssv)(AvSxx,ix1,ix2,ix3) = ((*ssv)(AvSxx,ix1,ix2,ix3)*timeStep + sxx)/(timeStep+1.0);
-               (*ssv)(AvSyy,ix1,ix2,ix3) = ((*ssv)(AvSyy,ix1,ix2,ix3)*timeStep + syy)/(timeStep+1.0);
-               (*ssv)(AvSzz,ix1,ix2,ix3) = ((*ssv)(AvSzz,ix1,ix2,ix3)*timeStep + szz)/(timeStep+1.0);
-               (*ssv)(AvSxy,ix1,ix2,ix3) = ((*ssv)(AvSxy,ix1,ix2,ix3)*timeStep + sxy)/(timeStep+1.0);
-               (*ssv)(AvSyz,ix1,ix2,ix3) = ((*ssv)(AvSyz,ix1,ix2,ix3)*timeStep + syz)/(timeStep+1.0);
-               (*ssv)(AvSxz,ix1,ix2,ix3) = ((*ssv)(AvSxz,ix1,ix2,ix3)*timeStep + sxz)/(timeStep+1.0);
-            }
-         }
-
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void ShearStressCoProcessor::addData()
-{
-   //Diese Daten werden geschrieben:
-   datanames.resize(0);
-   datanames.push_back("y^plus");
-   datanames.push_back("u_tau");
-   //datanames.push_back("yPlusFD");
-
-   data.resize(datanames.size());
-
-   BOOST_FOREACH(D3Q27InteractorPtr interactor, interactors)
-   {
-      typedef std::map<Block3DPtr, std::set< std::vector<int> > > TransNodeIndicesMap;
-      BOOST_FOREACH(TransNodeIndicesMap::value_type t, interactor->getBcNodeIndicesMap())
-      {
-         Block3DPtr block = t.first;
-         std::set< std::vector<int> >& transNodeIndicesSet = t.second;
-
-         UbTupleDouble3 org          = grid->getBlockWorldCoordinates(block);
-         UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
-         UbTupleDouble3 nodeOffset   = grid->getNodeOffset(block);
-         double         dx           = grid->getDeltaX(block);
-
-         LBMKernelPtr kernel = block->getKernel();
-         BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
-         DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions(); 
-         ShearStressValuesArray3DPtr ssv = kernel->getDataSet()->getShearStressValues();
-
-         int ghostLayer = kernel->getGhostLayerWidth();
-         LBMReal collFactor = kernel->getCollisionFactor();
-
-         int minX1 = ghostLayer;
-         int maxX1 = (int)bcArray->getNX1() - 1 - ghostLayer;
-         int minX2 = ghostLayer;
-         int maxX2 = (int)bcArray->getNX2() - 1 - ghostLayer;
-         int minX3 = ghostLayer;
-         int maxX3 = (int)bcArray->getNX3() - 1 - ghostLayer;
-
-         int level=block->getLevel();
-         if(level==1)
-         {
-            int le=0;
-         }
-         BOOST_FOREACH(std::vector<int> node, transNodeIndicesSet)
-         {
-            int ix1 = node[0];
-            int ix2 = node[1];
-            int ix3 = node[2];
-
-            //without ghost nodes
-            if (ix1 < minX1 || ix1 > maxX1 || ix2 < minX2 || ix2 > maxX2 ||ix3 < minX3 || ix3 > maxX3 ) continue;
-
-            if(bcArray->isFluid(ix1,ix2,ix3)) 
-            {
-               double q=(*ssv)(normalq,ix1,ix2,ix3) ;
-               double numPoint=(*ssv)(numberOfPoint,ix1,ix2,ix3) ;
-               if (q==0||numPoint!=3)continue;
-               // if (q==0)continue;
-
-               int index = 0;
-               nodes.push_back( makeUbTuple(float(val<1>(org) - val<1>(nodeOffset) + ix1*dx),
-                  float(val<2>(org) - val<2>(nodeOffset) + ix2*dx),
-                  float(val<3>(org) - val<3>(nodeOffset) + ix3*dx)) );
-
-               //////get normal and distance//////
-               double A,B,C;
-               A=	(*ssv)(normalX1,ix1,ix2,ix3)	;
-               B=	(*ssv)(normalX2,ix1,ix2,ix3)	;
-               C=	(*ssv)(normalX3,ix1,ix2,ix3)	;
-
-               ///////////
-               //compute y plus
-               //double vtxSonja, vtySonja, vtzSonja; //tangent velocity
-               // double temp = (*av)(ix1,ix2,ix3,AvVx)*A+(*av)(ix1,ix2,ix3,AvVy)*B+(*av)(ix1,ix2,ix3,AvVz)*C;
-               // vtxSonja = (*av)(ix1,ix2,ix3,AvVx)-normals[0]*temp;
-               // vtySonja = (*av)(ix1,ix2,ix3,AvVy)-normals[1]*temp;
-               // vtzSonja = (*av)(ix1,ix2,ix3,AvVz)-normals[2]*temp;
-
-               double vtx=  (B*B*(*ssv)(AvVx,ix1,ix2,ix3) +  C*C*(*ssv)(AvVx,ix1,ix2,ix3) - A*B*(*ssv)(AvVy,ix1,ix2,ix3) - A*C*(*ssv)(AvVy,ix1,ix2,ix3))/(A*A+B*B+C*C);
-               double vty=(-(A*B*(*ssv)(AvVx,ix1,ix2,ix3)) + A*A*(*ssv)(AvVy,ix1,ix2,ix3) + C*C*(*ssv)(AvVy,ix1,ix2,ix3) - B*C*(*ssv)(AvVz,ix1,ix2,ix3))/(A*A+B*B+C*C);
-               double vtz=(-(A*C*(*ssv)(AvVx,ix1,ix2,ix3)) - B*C*(*ssv)(AvVy,ix1,ix2,ix3) + A*A*(*ssv)(AvVz,ix1,ix2,ix3) + B*B*(*ssv)(AvVz,ix1,ix2,ix3))/(A*A+B*B+C*C);
-
-               double normVt = sqrt(vtx*vtx+vty*vty+vtz*vtz)+1e-100;
-               double nvtx = vtx / normVt;
-               double nvty = vty / normVt;
-               double nvtz = vtz / normVt;
-
-               double sx=0.5*((*ssv)(AvSxx,ix1,ix2,ix3)*nvtx+(*ssv)(AvSxy,ix1,ix2,ix3)*nvty+(*ssv)(AvSxz,ix1,ix2,ix3)*nvtz);
-               double sy=0.5*((*ssv)(AvSxy,ix1,ix2,ix3)*nvtx+(*ssv)(AvSyy,ix1,ix2,ix3)*nvty+(*ssv)(AvSyz,ix1,ix2,ix3)*nvtz);
-               double sz=0.5*((*ssv)(AvSxz,ix1,ix2,ix3)*nvtx+(*ssv)(AvSyz,ix1,ix2,ix3)*nvty+(*ssv)(AvSzz,ix1,ix2,ix3)*nvtz);
-               double sabs=sqrt(sx*sx+sy*sy+sz*sz);
-
-               double viscosity = (1.0/3.0)*(1.0/collFactor-0.5);
-               double rho = 1.0;
-               double utau=sqrt(viscosity/rho*sabs);
-
-               // double q=(*av)(ix1,ix2,ix3,normalq) ;
-               double yPlus = (utau*q)/viscosity;
-
-               data[index++].push_back(yPlus);
-               data[index++].push_back(utau);
-            }
-         }
-      }
-   }
-
-}
-//////////////////////////////////////////////////////////////////////////
-void ShearStressCoProcessor::reset(double step)
-{
-   if(Resetscheduler->isDue(step) )
-      resetData(step);
-
-   UBLOG(logDEBUG3, "resetCoProcessor::update:" << step);
-}
-//////////////////////////////////////////////////////////////////////////
-void ShearStressCoProcessor::resetData(double step)
-{
-   for(int level = minInitLevel; level<=maxInitLevel;level++)
-   {
-      BOOST_FOREACH(Block3DPtr block, blockVector[level])
-      {
-         if (block)
-         {
-            UbTupleDouble3 org          = grid->getBlockWorldCoordinates(block);
-            UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
-            UbTupleDouble3 nodeOffset   = grid->getNodeOffset(block);
-            double         dx           = grid->getDeltaX(block);
-
-            LBMKernelPtr kernel = block->getKernel();
-            BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
-            DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions(); 
-            ShearStressValuesArray3DPtr ssv = kernel->getDataSet()->getShearStressValues();
-
-            int minX1 = 0;
-            int minX2 = 0;
-            int minX3 = 0;
-
-            int maxX1 = int(distributions->getNX1());
-            int maxX2 = int(distributions->getNX2());
-            int maxX3 = int(distributions->getNX3());
-
-            for(int ix3=minX3; ix3<maxX3-1; ix3++)
-            {
-               for(int ix2=minX2; ix2<maxX2-1; ix2++)
-               {
-                  for(int ix1=minX1; ix1<maxX1-1; ix1++)
-                  {
-                     if(!bcArray->isUndefined(ix1,ix2,ix3) && !bcArray->isSolid(ix1,ix2,ix3))
-                     {
-                        //////////////////////////////////////////////////////////////////////////
-                        //compute average values
-                        //////////////////////////////////////////////////////////////////////////
-                        (*ssv)(AvVx,ix1,ix2,ix3) = 0.0;
-                        (*ssv)(AvVy,ix1,ix2,ix3) = 0.0;
-                        (*ssv)(AvVz,ix1,ix2,ix3) = 0.0;
-
-                        (*ssv)(AvSxx,ix1,ix2,ix3) = 0.0;
-                        (*ssv)(AvSyy,ix1,ix2,ix3) = 0.0;
-                        (*ssv)(AvSzz,ix1,ix2,ix3) = 0.0;
-                        (*ssv)(AvSxy,ix1,ix2,ix3) = 0.0;
-                        (*ssv)(AvSyz,ix1,ix2,ix3) = 0.0;
-                        (*ssv)(AvSxz,ix1,ix2,ix3) = 0.0;
-                        //////////////////////////////////////////////////////////////////////////
-                     }
-                  }
-               }
-            }
-         }
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void ShearStressCoProcessor::addInteractor( D3Q27InteractorPtr interactor )
-{
-   interactors.push_back(interactor);
-}
-//////////////////////////////////////////////////////////////////////////
-void ShearStressCoProcessor::findPlane(int ix1,int ix2,int ix3,Grid3DPtr grid,Block3DPtr block,double &A,double &B,double &C,double &D,double &ii)
-{
-   double x1plane=0.0,y1plane=0.0,z1plane=0.0;
-   double x2plane=0.0,y2plane=0.0,z2plane=0.0;
-   double x3plane=0.0,y3plane=0.0,z3plane=0.0;
-   BoundaryConditionsPtr bcPtr;
-   double dx = grid->getDeltaX(block);
-   LBMKernelPtr kernel = block->getKernel();
-   DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();
-   BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
-   bcPtr=bcArray->getBC(ix1,ix2,ix3);
-   int x,y,z;
-
-
-   if(InterpolationProcessor::iCellHasSolid(bcArray, ix1, ix2, ix3)) { x = ix1;y = ix2;z = ix3;}   
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1  , ix2-1, ix3  )) { x = ix1+0; y = ix2-1; z = ix3+0;}//S
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1  , ix2  , ix3-1)) { x = ix1+0; y = ix2+0; z = ix3-1;}//B		   
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1-1, ix2  , ix3  )) { x = ix1-1; y = ix2+0; z = ix3+0;}//w
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1  , ix2-1, ix3-1)) { x = ix1+0; y = ix2-1; z = ix3-1;}//BS
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1-1, ix2  , ix3-1)) { x = ix1-1; y = ix2+0; z = ix3-1;}//BW
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1-1, ix2-1, ix3  )) { x = ix1-1; y = ix2-1; z = ix3+0;}//SW
-
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1-1, ix2-1, ix3-1)) { x = ix1-1; y = ix2-1; z = ix3-1;}//BSW	  
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1+1, ix2  , ix3  )) { x = ix1+1; y = ix2+0; z = ix3+0;}//E
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1  , ix2+1, ix3  )) { x = ix1+0; y = ix2+1; z = ix3+0;}//N
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1  , ix2  , ix3+1)) { x = ix1+0; y = ix2+0; z = ix3+1;}//T	
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1+1, ix2+1, ix3  )) { x = ix1+1; y = ix2+1; z = ix3+0;}//NE
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1+1, ix2  , ix3+1)) { x = ix1+1; y = ix2+0; z = ix3+1;}//TE
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1  , ix2+1, ix3+1)) { x = ix1+0; y = ix2+1; z = ix3+1;}//TN
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1+1, ix2+1, ix3+1)) { x = ix1+1; y = ix2+1; z = ix3+1;}//TNE
-
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1+1, ix2-1, ix3  )) { x = ix1+1; y = ix2-1; z = ix3+0;}//SE
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1-1, ix2+1, ix3  )) { x = ix1-1; y = ix2+1; z = ix3+0;}//NW
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1+1, ix2  , ix3-1)) { x = ix1+1; y = ix2+0; z = ix3-1;}//BE
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1-1, ix2  , ix3+1)) { x = ix1-1; y = ix2+0; z = ix3+1;}//TW
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1+0, ix2+1, ix3-1)) { x = ix1+0; y = ix2+1; z = ix3-1;}//BN
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1+0, ix2-1, ix3+1)) { x = ix1+0; y = ix2-1; z = ix3+1;}//TS
-
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1-1, ix2+1, ix3+1)) { x = ix1-1; y = ix2+1; z = ix3+1;}//TNW 
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1+1, ix2-1, ix3+1)) { x = ix1+1; y = ix2-1; z = ix3+1;}//TSE 
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1-1, ix2-1, ix3+1)) { x = ix1-1; y = ix2-1; z = ix3+1;}//TSW 
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1+1, ix2+1, ix3-1)) { x = ix1+1; y = ix2+1; z = ix3-1;}//BNE 
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1-1, ix2+1, ix3-1)) { x = ix1-1; y = ix2+1; z = ix3-1;}//BNW 
-   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1+1, ix2-1, ix3-1)) { x = ix1+1; y = ix2-1; z = ix3-1;}//BSE 
-
-
-   else   {{UB_THROW( UbException(UB_EXARGS,"there is no cell  ix1="+UbSystem::toString(ix1)+"ix2="+UbSystem::toString(ix2)+"ix3="+UbSystem::toString(ix3)+"GlobalID="+UbSystem::toString(block->getGlobalID())+"dx="+UbSystem::toString(dx)
-      +"T="+UbSystem::toString(bcPtr->getQ(D3Q27System::T))+"B="+UbSystem::toString(bcPtr->getQ(D3Q27System::B))
-      +"E="+UbSystem::toString(bcPtr->getQ(D3Q27System::E))+"W="+UbSystem::toString(bcPtr->getQ(D3Q27System::W))+"N="+UbSystem::toString(bcPtr->getQ(D3Q27System::N))	
-      +"S="+UbSystem::toString(bcPtr->getQ(D3Q27System::S))+"NE="+UbSystem::toString(bcPtr->getQ(D3Q27System::NE))+"SW="+UbSystem::toString(bcPtr->getQ(D3Q27System::SW))
-      +"SE="+UbSystem::toString(bcPtr->getQ(D3Q27System::SE))+"NW="+UbSystem::toString(bcPtr->getQ(D3Q27System::NW))    
-      +"TE="+
-      UbSystem::toString(bcPtr->getQ(D3Q27System::TE))+"BW="+UbSystem::toString(bcPtr->getQ(D3Q27System::BW))+"BE="+UbSystem::toString(bcPtr->getQ(D3Q27System::BE))+"TW="+
-      UbSystem::toString(bcPtr->getQ(D3Q27System::TW))+"TN="+UbSystem::toString(bcPtr->getQ(D3Q27System::TN))+"BS="+UbSystem::toString(bcPtr->getQ(D3Q27System::BS))+"BN="+
-      UbSystem::toString(bcPtr->getQ(D3Q27System::BN))+"TS="+UbSystem::toString(bcPtr->getQ(D3Q27System::TS))+"TNE="+UbSystem::toString(bcPtr->getQ(D3Q27System::TNE))+"TNW="+
-      UbSystem::toString(bcPtr->getQ(D3Q27System::TNW))+"TSE="+UbSystem::toString(bcPtr->getQ(D3Q27System::TSE))+"TSW="+UbSystem::toString(bcPtr->getQ(D3Q27System::TSW))+"BNE="+
-      UbSystem::toString(bcPtr->getQ(D3Q27System::BNE))+"BNW="+UbSystem::toString(bcPtr->getQ(D3Q27System::BNW))+"BSE="+UbSystem::toString(bcPtr->getQ(D3Q27System::BSE))+"BSW="+UbSystem::toString(bcPtr->getQ(D3Q27System::BSW)*dx)
-      ) ) ;}} 
-
-
-   if(InterpolationProcessor::iCellHasSolid(bcArray, x, y, z))
-   {  
-      for(int i = x; i <= x + 1; i++){
-         for(int j = y; j <= y + 1; j++){
-            for (int k = z; k <= z + 1; k++)
-            {
-               UbTupleDouble3 pointplane1 =  grid->getNodeCoordinates(block,  i,	  j,	 k);
-
-               double   iph=val<1>(pointplane1);
-               double   jph=val<2>(pointplane1);
-               double   kph=val<3>(pointplane1);
-
-               if(!bcArray->isSolid(i, j, k))
-               {
-                  BoundaryConditionsPtr bcPtrIn=bcArray->getBC(i,j,k);
-                  if(bcPtrIn)
-                  {	 
-                     for(int fdir=D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
-                     {
-                        if( ii<=2)
-                        {
-                           LBMReal q = bcPtrIn->getQ(fdir);
-                           if (q!=999.00000)
-                           {	  
-                              if     ( fdir==D3Q27System::E ) 
-                              {
-                                 //if(!bcArray->isSolid(i, j, k))continue;
-                                 if (i+q<=x+1)
-                                 {
-                                    if      (ii==0)	    {	x1plane=iph+q*dx;	  y1plane=jph;	 z1plane=kph;    	ii++;	} 
-                                    else if (ii==1) 	{	x2plane=iph+q*dx;     y2plane=jph;	 z2plane=kph;	    if  (x1plane!=x2plane||y1plane!=y2plane||z1plane!=z2plane) 	ii++;	}
-                                    else if(ii==2) 	    {   x3plane=iph+q*dx;     y3plane=jph;	 z3plane=kph;       if ((x3plane!=x1plane||y3plane!=y1plane||z3plane!=z1plane)&&(x2plane!=x3plane||y2plane!=y3plane||z2plane!=z3plane)) ii++;} 
-                                 }
-                              }
-                              if     ( fdir==D3Q27System::W ) 
-                              {
-                                 //if(!bcArray->isSolid(i, j, k))continue;
-                                 if (i-q>=x)
-                                 {
-                                    if      (ii==0)	    {	x1plane=iph-q*dx;	  y1plane=jph;	 z1plane=kph;    	ii++;	} 
-                                    else if (ii==1) 	    {	x2plane=iph-q*dx;    y2plane=jph;	 z2plane=kph;	    if  (x1plane!=x2plane||y1plane!=y2plane||z1plane!=z2plane) 	ii++;	}
-                                    else if(ii==2) 	    {   x3plane=iph-q*dx;    y3plane=jph;	 z3plane=kph;       if ((x3plane!=x1plane||y3plane!=y1plane||z3plane!=z1plane)&&(x2plane!=x3plane||y2plane!=y3plane||z2plane!=z3plane)) ii++;} 
-                                 }
-                              }
-                              if     ( fdir==D3Q27System::N ) 
-                              {
-                                 //if(!bcArray->isSolid(i, j, k))continue;
-                                 if(j+q<=y+1)
-                                 {
-                                    if      (ii==0)	    {	x1plane=iph;	y1plane=jph+q*dx;	 z1plane=kph; 	    ii++;	} 
-                                    else if (ii==1) 	    {	x2plane=iph;    y2plane=jph+q*dx;	 z2plane=kph;	    if  (x1plane!=x2plane||y1plane!=y2plane||z1plane!=z2plane) 	ii++;	}
-                                    else if (ii==2) 	    {   x3plane=iph;    y3plane=jph+q*dx;	 z3plane=kph;       if ((x3plane!=x1plane||y3plane!=y1plane||z3plane!=z1plane)&&(x2plane!=x3plane||y2plane!=y3plane||z2plane!=z3plane)) ii++;} 
-                                 }
-                              }
-                              if     ( fdir==D3Q27System::S ) 
-                              {
-                                 //if(!bcArray->isSolid(i, j, k))continue;
-                                 if (j-q>=y)
-                                 {
-                                    if      (ii==0)	    {	x1plane=iph;	y1plane=jph-q*dx;	 z1plane=kph; 	ii++;	} 
-                                    else if (ii==1) 	    {	x2plane=iph;    y2plane=jph-q*dx;	 z2plane=kph;	if  (x1plane!=x2plane||y1plane!=y2plane||z1plane!=z2plane) 	ii++;	}
-                                    else if (ii==2) 	    {   x3plane=iph;    y3plane=jph-q*dx;	 z3plane=kph;   if ((x3plane!=x1plane||y3plane!=y1plane||z3plane!=z1plane)&&(x2plane!=x3plane||y2plane!=y3plane||z2plane!=z3plane)) ii++;} 
-                                 }
-                              }
-
-                              if     ( fdir==D3Q27System::T ) 
-                              {
-                                 //if(!bcArray->isSolid(i, j, k))continue;
-                                 if(k+q<=z+1)
-                                 {
-                                    if      (ii==0)	    {	x1plane=iph;	y1plane=jph;	 z1plane=kph+q*dx; 	    ii++;	} 
-                                    else if (ii==1) 	    {	x2plane=iph;    y2plane=jph;	 z2plane=kph+q*dx;	    if  (x1plane!=x2plane||y1plane!=y2plane||z1plane!=z2plane) 	ii++;	}
-                                    else if (ii==2) 	    {   x3plane=iph;    y3plane=jph;	 z3plane=kph+q*dx;      if ((x3plane!=x1plane||y3plane!=y1plane||z3plane!=z1plane)&&(x2plane!=x3plane||y2plane!=y3plane||z2plane!=z3plane)) ii++;} 
-                                 }
-                              }
-                              if     ( fdir==D3Q27System::B ) 
-                              {
-                                 //if(!bcArray->isSolid(i, j, k))continue;
-                                 if (k-q>=z)
-                                 {
-                                    if      (ii==0)	    {	x1plane=iph;	y1plane=jph;	 z1plane=kph-q*dx; 	ii++;	} 
-                                    else if (ii==1) 	    {	x2plane=iph;    y2plane=jph;	 z2plane=kph-q*dx;	  if  (x1plane!=x2plane||y1plane!=y2plane||z1plane!=z2plane) 	ii++;	}
-                                    else if (ii==2) 	    {   x3plane=iph;    y3plane=jph;	 z3plane=kph-q*dx;     if ((x3plane!=x1plane||y3plane!=y1plane||z3plane!=z1plane)&&(x2plane!=x3plane||y2plane!=y3plane||z2plane!=z3plane)) ii++;} 
-                                 }
-                              }
-
-                           }
-                        }
-                     }
-                  }
-               }
-            }
-         }
-      }
-
-      A =   y1plane* (z2plane - z3plane) + y2plane*(z3plane - z1plane) + y3plane* (z1plane - z2plane);   
-      B =   z1plane* (x2plane - x3plane) + z2plane*(x3plane - x1plane) + z3plane* (x1plane - x2plane) ;      
-      C =   x1plane* (y2plane - y3plane) + x2plane*(y3plane - y1plane) + x3plane* (y1plane - y2plane) ;       
-      D =-( x1plane*(y2plane*z3plane - y3plane*z2plane)+x2plane*(y3plane*z1plane - y1plane*z3plane) + x3plane* (y1plane* z2plane - y2plane* z1plane));	
-   }
-   if(ii!=3){
-
-      {{UB_THROW( UbException(UB_EXARGS,"ii is="+UbSystem::toString(ii)+"  ix1="+UbSystem::toString(ix1)+" ix2="+UbSystem::toString(ix2)+" ix3="+UbSystem::toString(ix3)+" Block3D::GlobalID="+UbSystem::toString(block->getGlobalID())+" dx="+UbSystem::toString(dx)
-         +" T="+UbSystem::toString(bcPtr->getQ(D3Q27System::T))+" B="+UbSystem::toString(bcPtr->getQ(D3Q27System::B))
-         +" E="+UbSystem::toString(bcPtr->getQ(D3Q27System::E))+" W="+UbSystem::toString(bcPtr->getQ(D3Q27System::W))+" N="+UbSystem::toString(bcPtr->getQ(D3Q27System::N))	
-         +" S="+UbSystem::toString(bcPtr->getQ(D3Q27System::S))+" NE="+UbSystem::toString(bcPtr->getQ(D3Q27System::NE))+" SW="+UbSystem::toString(bcPtr->getQ(D3Q27System::SW))
-         +" SE="+UbSystem::toString(bcPtr->getQ(D3Q27System::SE))+" NW="+UbSystem::toString(bcPtr->getQ(D3Q27System::NW))    
-         +" TE="+
-         UbSystem::toString(bcPtr->getQ(D3Q27System::TE))+" BW="+UbSystem::toString(bcPtr->getQ(D3Q27System::BW))+" BE="+UbSystem::toString(bcPtr->getQ(D3Q27System::BE))+" TW="+
-         UbSystem::toString(bcPtr->getQ(D3Q27System::TW))+" TN="+UbSystem::toString(bcPtr->getQ(D3Q27System::TN))+" BS="+UbSystem::toString(bcPtr->getQ(D3Q27System::BS))+" BN="+
-         UbSystem::toString(bcPtr->getQ(D3Q27System::BN))+" TS="+UbSystem::toString(bcPtr->getQ(D3Q27System::TS))+" TNE="+UbSystem::toString(bcPtr->getQ(D3Q27System::TNE))+" TNW="+
-         UbSystem::toString(bcPtr->getQ(D3Q27System::TNW))+" TSE="+UbSystem::toString(bcPtr->getQ(D3Q27System::TSE))+" TSW="+UbSystem::toString(bcPtr->getQ(D3Q27System::TSW))+" BNE="+
-         UbSystem::toString(bcPtr->getQ(D3Q27System::BNE))+" BNW="+UbSystem::toString(bcPtr->getQ(D3Q27System::BNW))+" BSE="+UbSystem::toString(bcPtr->getQ(D3Q27System::BSE))+" BSW="+UbSystem::toString(bcPtr->getQ(D3Q27System::BSW))
-         ) ) ;}}
-
-   }	
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool ShearStressCoProcessor::checkUndefindedNodes( BCArray3DPtr bcArray,int ix1,int ix2,int ix3)
-{
-   for(int i = ix1; i <= ix1 + 1; i++){
-      for(int j = ix2; j <= ix2 + 1; j++){
-         for (int k = ix3; k <= ix3 + 1; k++)
-         {	
-            if(bcArray->isUndefined(i, j, k)) return true;
-         }  
-      }
-   }
-   return false;
-}
-//////////////////////////////////////////////////////////////////////////////////////
-void ShearStressCoProcessor::initDistance()
-{
-   BOOST_FOREACH(D3Q27InteractorPtr interactor, interactors)
-   {
-      typedef std::map<Block3DPtr, std::set< std::vector<int> > > TransNodeIndicesMap;
-      BOOST_FOREACH(TransNodeIndicesMap::value_type t, interactor->getBcNodeIndicesMap())
-      {
-         Block3DPtr block = t.first;
-         std::set< std::vector<int> >& transNodeIndicesSet = t.second;
-
-         UbTupleDouble3 org          = grid->getBlockWorldCoordinates(block);
-         UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
-         UbTupleDouble3 nodeOffset   = grid->getNodeOffset(block);
-         double         dx           = grid->getDeltaX(block);
-
-         LBMKernelPtr kernel = block->getKernel();
-         BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
-         DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions(); 
-         ShearStressValuesArray3DPtr ssv = kernel->getDataSet()->getShearStressValues();
-
-         int ghostLayer = kernel->getGhostLayerWidth();
-         LBMReal collFactor = kernel->getCollisionFactor();
-
-         int minX1 = ghostLayer;
-         int maxX1 = (int)bcArray->getNX1() - 1 - ghostLayer;
-         int minX2 = ghostLayer;
-         int maxX2 = (int)bcArray->getNX2() - 1 - ghostLayer;
-         int minX3 = ghostLayer;
-         int maxX3 = (int)bcArray->getNX3() - 1 - ghostLayer;
-
-         BOOST_FOREACH(std::vector<int> node, transNodeIndicesSet)
-         {
-            int ix1 = node[0];
-            int ix2 = node[1];
-            int ix3 = node[2];
-
-            //without ghost nodes
-            if (ix1 < minX1 || ix1 > maxX1 || ix2 < minX2 || ix2 > maxX2 ||ix3 < minX3 || ix3 > maxX3 ) continue;
-
-            if(bcArray->isFluid(ix1,ix2,ix3) )
-            {
-               BoundaryConditionsPtr bc = bcArray->getBC(ix1,ix2,ix3);
-               if((bc->hasDensityBoundary()||bc->hasVelocityBoundary()))continue;
-               int numberOfCorner=0;
-
-               if(bc->getQ(D3Q27System::T)  !=999.000){ numberOfCorner++;}
-               if(bc->getQ(D3Q27System::B)  !=999.000){ numberOfCorner++;}
-               if(bc->getQ(D3Q27System::E)  !=999.000){ numberOfCorner++;}
-               if(bc->getQ(D3Q27System::W)  !=999.000){ numberOfCorner++;}
-               if(bc->getQ(D3Q27System::N)  !=999.000){ numberOfCorner++;}
-               if(bc->getQ(D3Q27System::S)  !=999.000){ numberOfCorner++;}
-               // if(bc->hasVelocityBoundary()||bc->hasDensityBoundary())continue;
-               if(numberOfCorner>1)continue;
-               if(checkUndefindedNodes( bcArray, ix1,ix2,ix3))continue;
-
-
-               //////get normal and distance//////
-               double A,B,C,D,ii=0.0;
-               findPlane(ix1,ix2,ix3,grid,block,A,B,C,D,ii);
-               UbTupleDouble3 pointplane1 =  grid->getNodeCoordinates(block, ix1,ix2,ix3);
-               double   ix1ph=val<1>(pointplane1);
-               double   ix2ph=val<2>(pointplane1);
-               double   ix3ph=val<3>(pointplane1);
-               double normalDis;
-               if(ii!=3)
-               {
-                  UB_THROW( UbException(UB_EXARGS,"not enough points to create plane"+UbSystem::toString(ii)));
-               }
-               else
-               {    
-                  double s = A*ix1ph + B*ix2ph + C*ix3ph + D;//The sign of s = Ax + By + Cz + D determines which side the point (x,y,z) lies with respect to the plane. If s > 0 then the point lies on the same side as the normal (A,B,C). If s < 0 then it lies on the opposite side, if s = 0 then the point (x,y,z) lies on the plane.
-                  if (s>0){s=1;} else if (s<0){s=-1;}else {s=0;}
-
-                  normalDis=((A*ix1ph + B*ix2ph + C*ix3ph + D)/sqrt(A*A+B*B+C*C));///distance point to plane xp-Xw=distance
-                  normalDis*=s;
-
-                  (*ssv)(normalX1,ix1,ix2,ix3) = A;
-                  (*ssv)(normalX2,ix1,ix2,ix3) = B;
-                  (*ssv)(normalX3,ix1,ix2,ix3) = C;
-                  (*ssv)(normalq,ix1,ix2,ix3) = normalDis;
-                  (*ssv)(numberOfPoint,ix1,ix2,ix3) = ii;
-
-               }
-            }
-         }
-      }
-   }
-}
+#include "ShearStressCoProcessor.h"
+#include "BCProcessor.h"
+#include "WbWriterVtkXmlASCII.h"
+
+#include "Block3D.h"
+#include "DataSet3D.h"
+#include "LBMKernel.h"
+#include "Communicator.h"
+#include "D3Q27Interactor.h"
+#include "UbScheduler.h"
+#include "BCArray3D.h"
+#include "InterpolationProcessor.h"
+
+ShearStressCoProcessor::ShearStressCoProcessor(Grid3DPtr grid, const std::string& path, 
+                                                             WbWriter* const writer,
+                                                             UbSchedulerPtr s,UbSchedulerPtr rs)
+                                                             : CoProcessor(grid, s),
+                                                             Resetscheduler(rs),
+                                                             path(path),
+                                                             writer(writer)
+{
+   CommunicatorPtr comm = Communicator::getInstance();
+   normals.push_back(0);
+   normals.push_back(0);
+   normals.push_back(1);
+   gridRank  = grid->getRank();
+   minInitLevel = this->grid->getCoarsestInitializedLevel();
+   maxInitLevel = this->grid->getFinestInitializedLevel();
+
+   blockVector.resize(maxInitLevel+1);
+   for(int level = minInitLevel; level<=maxInitLevel;level++)
+   {
+      grid->getBlocks(level, gridRank, true, blockVector[level]);
+      for(Block3DPtr block : blockVector[level])
+      {
+         UbTupleInt3 nx = grid->getBlockNX();
+         ShearStressValuesArray3DPtr shearStressValues = ShearStressValuesArray3DPtr(new ShearStressValuesArray3D(14, val<1>(nx)+1, val<2>(nx)+1, val<3>(nx)+1, 0.0));
+         block->getKernel()->getDataSet()->setShearStressValues(shearStressValues);
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+ShearStressCoProcessor::~ShearStressCoProcessor()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void ShearStressCoProcessor::process( double step )
+{
+   if (step==0)
+   {
+      initDistance();
+   }
+   calculateShearStress(step);
+   if(scheduler->isDue(step) )
+      collectData(step);
+   UBLOG(logDEBUG3, "D3Q27ShearStressCoProcessor::update:" << step);
+}
+//////////////////////////////////////////////////////////////////////////
+void ShearStressCoProcessor::collectData(double step)
+{
+   using namespace std;
+
+   int istep = int(step);
+   addData();
+
+   //string partName = writer->writeNodesWithNodeData(path+ UbSystem::toString(gridRank)+ "_" + UbSystem::toString(istep),nodes,datanames,data);
+   //size_t found=partName.find_last_of("//");
+   //string piece = partName.substr(found+1);
+
+   //vector<string> cellDataNames;
+
+   //CommunicatorPtr comm = Communicator::getInstance();
+   //vector<string> pieces = comm->gatherStrings(piece);
+   //if (comm->getProcessID() == comm->getRoot())
+   //{
+   //   string pname = WbWriterVtkXmlASCII::getInstance()->writeParallelFile(path+"_"+UbSystem::toString(istep),pieces,datanames,cellDataNames);
+
+   //   vector<string> filenames;
+   //   filenames.push_back(pname);
+   //   if (step == CoProcessor::scheduler->getMinBegin())
+   //   {
+   //      WbWriterVtkXmlASCII::getInstance()->writeCollection(path+"__Shear_collection",filenames,istep,false);
+   //   } 
+   //   else
+   //   {
+   //      WbWriterVtkXmlASCII::getInstance()->addFilesToCollection(path+"__Shear_collection",filenames,istep,false);
+   //   }
+   //   UBLOG(logINFO,"D3Q27ShearStressCoProcessor step: " << istep);
+   //}
+
+   string pfilePath, partPath, subfolder, cfilePath;
+   subfolder = "shs"+UbSystem::toString(istep);
+   pfilePath =  path+"/shs/"+subfolder;
+   cfilePath =  path+"/shs/shs_collection";
+   partPath = pfilePath+"/shs"+UbSystem::toString(gridRank)+ "_" + UbSystem::toString(istep);
+
+   string partName = writer->writeNodesWithNodeData(partPath,nodes,datanames,data);
+   size_t found=partName.find_last_of("/");
+   string piece = partName.substr(found+1);
+   piece = subfolder + "/" + piece;
+
+   vector<string> cellDataNames;
+   CommunicatorPtr comm = Communicator::getInstance();
+   vector<string> pieces = comm->gather(piece);
+   if (comm->getProcessID() == comm->getRoot())
+   {
+      string pname = WbWriterVtkXmlASCII::getInstance()->writeParallelFile(pfilePath,pieces,datanames,cellDataNames);
+      found=pname.find_last_of("/");
+      piece = pname.substr(found+1);
+
+      vector<string> filenames;
+      filenames.push_back(piece);
+      if (step == CoProcessor::scheduler->getMinBegin())
+      {
+         WbWriterVtkXmlASCII::getInstance()->writeCollection(cfilePath,filenames,istep,false);
+      } 
+      else
+      {
+         WbWriterVtkXmlASCII::getInstance()->addFilesToCollection(cfilePath,filenames,istep,false);
+      }
+      UBLOG(logINFO,"D3Q27ShearStressCoProcessor step: " << istep);
+   }
+
+   clearData();
+}
+//////////////////////////////////////////////////////////////////////////
+void ShearStressCoProcessor::clearData()
+{
+   nodes.clear();
+   datanames.clear();
+   data.clear();
+}
+//////////////////////////////////////////////////////////////////////////
+void ShearStressCoProcessor::calculateShearStress(double timeStep)
+{
+   using namespace D3Q27System;
+
+   LBMReal f[27];
+   LBMReal vx, vy, vz, sxx, syy, szz, sxy, syz, sxz;
+
+   for(D3Q27InteractorPtr interactor : interactors)
+   {
+      typedef std::map<Block3DPtr, std::set< std::vector<int> > > TransNodeIndicesMap;
+      for(TransNodeIndicesMap::value_type t : interactor->getBcNodeIndicesMap())
+      {
+         Block3DPtr block = t.first;
+         std::set< std::vector<int> >& transNodeIndicesSet = t.second;
+
+         ILBMKernelPtr kernel = block->getKernel();
+         BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
+         DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions(); 
+         ShearStressValuesArray3DPtr ssv = kernel->getDataSet()->getShearStressValues();
+
+         int ghostLayer = kernel->getGhostLayerWidth();
+         LBMReal collFactor = kernel->getCollisionFactor();
+
+         int minX1 = ghostLayer;
+         int maxX1 = (int)bcArray->getNX1() - 1 - ghostLayer;
+         int minX2 = ghostLayer;
+         int maxX2 = (int)bcArray->getNX2() - 1 - ghostLayer;
+         int minX3 = ghostLayer;
+         int maxX3 = (int)bcArray->getNX3() - 1 - ghostLayer;
+
+         for(std::vector<int> node : transNodeIndicesSet)
+         {
+            int ix1 = node[0];
+            int ix2 = node[1];
+            int ix3 = node[2];
+
+            //without ghost nodes
+            if (ix1 < minX1 || ix1 > maxX1 || ix2 < minX2 || ix2 > maxX2 ||ix3 < minX3 || ix3 > maxX3 ) continue;
+
+            if(bcArray->isFluid(ix1,ix2,ix3)) 
+            {
+               double q=(*ssv)(normalq,ix1,ix2,ix3) ;
+               double numPoint=(*ssv)(numberOfPoint,ix1,ix2,ix3) ;
+               if (q==0||numPoint!=3)continue;
+               // if (q==0)continue;
+               //////////////////////////////////////////////////////////////////////////
+               //read distribution
+               ////////////////////////////////////////////////////////////////////////////
+               distributions->getDistribution(f, ix1, ix2, ix3);
+               //////////////////////////////////////////////////////////////////////////
+               //compute velocity
+               //////////////////////////////////////////////////////////////////////////
+               vx = ((((f[TNE]-f[BSW]) + (f[TSE]-f[BNW])) + ((f[BSE]-f[TNW]) + (f[BNE]-f[TSW]))) +
+                  (((f[BE]-f[TW]) + (f[TE]-f[BW])) + ((f[SE]-f[NW]) + (f[NE]-f[SW]))) +
+                  (f[E]-f[W])); 
+
+               vy = ((((f[TNE]-f[BSW]) + (f[BNW]-f[TSE])) + ((f[TNW]-f[BSE]) + (f[BNE]-f[TSW]))) +
+                  (((f[BN]-f[TS]) + (f[TN]-f[BS])) + ((f[NW]-f[SE]) + (f[NE]-f[SW]))) +
+                  (f[N]-f[S])); 
+
+               vz = ((((f[TNE]-f[BSW]) + (f[TSE]-f[BNW])) + ((f[TNW]-f[BSE]) + (f[TSW]-f[BNE]))) +
+                  (((f[TS]-f[BN]) + (f[TN]-f[BS])) + ((f[TW]-f[BE]) + (f[TE]-f[BW]))) +
+                  (f[T]-f[B]));
+
+
+               sxy = 3.0 * collFactor/(collFactor - 1.0)* ( ((f[TNE] + f[BSW])-(f[TSE]+f[BNW]))+(-(f[BSE]+f[TNW])+ (f[TSW]+f[BNE]))
+                  +(((f[NE] + f[SW]) - (f[SE] + f[NW])))  -vx*vy);
+
+               sxz = 3.0 * collFactor/(collFactor-1.0)*(((f[TNE] + f[BSW])+(f[TSE]+f[BNW]))+(-(f[BSE]+f[TNW])- (f[TSW]+f[BNE]))
+                  +((f[TE] + f[BW])-(f[BE]+ f[TW])) -vx*vz);
+
+               syz = 3.0 * collFactor/(collFactor-1.0)*(((f[TNE] + f[BSW])-(f[TSE]+f[BNW]))+((f[BSE]+f[TNW])- (f[TSW]+f[BNE]))
+                  +(-(f[BN] + f[TS]) + (f[TN] + f[BS])) -vy*vz);                 
+
+               LBMReal dxxMyy =3.0/2.0 * collFactor/(collFactor-1.0)* (((f[TE] + f[BW])+(f[BE]+ f[TW]))
+                  -((f[BN] + f[TS]) + (f[TN] + f[BS]))+((f[E] + f[W])-(f[N] + f[S]))-vx*vx+vy*vy);
+
+               LBMReal dxxMzz =3.0/2.0 * collFactor/(collFactor-1.0)*((((f[NE] + f[SW]) + (f[SE] + f[NW]))
+                  -((f[BN] + f[TS]) + (f[TN] + f[BS])))+((f[E] + f[W])-(f[T] + f[B])) -vx*vx +vz*vz);
+
+               // LBMReal dyyMzz =3.0/2.0 *collFactor/(collFactor-1.0)*((((f[NE] + f[SW]) + (f[SE] + f[NW]))-((f[TE] + f[BW])+(f[BE]+ f[TW])))
+               //    +((f[N] + f[S])-(f[T] + f[B])) -vy*vy +vz*vz);
+
+               sxx=(dxxMyy+dxxMzz)/3.0; // weil dxxPyyPzz=0
+
+               syy=(dxxMzz-2*dxxMyy)/3.0;
+
+               szz=(dxxMyy-2*dxxMzz)/3.0;
+
+               //////////////////////////////////////////////////////////////////////////
+               //compute average values
+               //////////////////////////////////////////////////////////////////////////
+               (*ssv)(AvVx,ix1,ix2,ix3) = ((*ssv)(AvVx,ix1,ix2,ix3)*timeStep + vx)/(timeStep+1.0);
+               (*ssv)(AvVy,ix1,ix2,ix3) = ((*ssv)(AvVy,ix1,ix2,ix3)*timeStep + vy)/(timeStep+1.0);
+               (*ssv)(AvVz,ix1,ix2,ix3) = ((*ssv)(AvVz,ix1,ix2,ix3)*timeStep + vz)/(timeStep+1.0);
+
+               (*ssv)(AvSxx,ix1,ix2,ix3) = ((*ssv)(AvSxx,ix1,ix2,ix3)*timeStep + sxx)/(timeStep+1.0);
+               (*ssv)(AvSyy,ix1,ix2,ix3) = ((*ssv)(AvSyy,ix1,ix2,ix3)*timeStep + syy)/(timeStep+1.0);
+               (*ssv)(AvSzz,ix1,ix2,ix3) = ((*ssv)(AvSzz,ix1,ix2,ix3)*timeStep + szz)/(timeStep+1.0);
+               (*ssv)(AvSxy,ix1,ix2,ix3) = ((*ssv)(AvSxy,ix1,ix2,ix3)*timeStep + sxy)/(timeStep+1.0);
+               (*ssv)(AvSyz,ix1,ix2,ix3) = ((*ssv)(AvSyz,ix1,ix2,ix3)*timeStep + syz)/(timeStep+1.0);
+               (*ssv)(AvSxz,ix1,ix2,ix3) = ((*ssv)(AvSxz,ix1,ix2,ix3)*timeStep + sxz)/(timeStep+1.0);
+            }
+         }
+
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void ShearStressCoProcessor::addData()
+{
+   //Diese Daten werden geschrieben:
+   datanames.resize(0);
+   datanames.push_back("y^plus");
+   datanames.push_back("u_tau");
+   //datanames.push_back("yPlusFD");
+
+   data.resize(datanames.size());
+
+   for(D3Q27InteractorPtr interactor : interactors)
+   {
+      typedef std::map<Block3DPtr, std::set< std::vector<int> > > TransNodeIndicesMap;
+      for(TransNodeIndicesMap::value_type t : interactor->getBcNodeIndicesMap())
+      {
+         Block3DPtr block = t.first;
+         std::set< std::vector<int> >& transNodeIndicesSet = t.second;
+
+         UbTupleDouble3 org          = grid->getBlockWorldCoordinates(block);
+         UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
+         UbTupleDouble3 nodeOffset   = grid->getNodeOffset(block);
+         double         dx           = grid->getDeltaX(block);
+
+         ILBMKernelPtr kernel = block->getKernel();
+         BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
+         DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions(); 
+         ShearStressValuesArray3DPtr ssv = kernel->getDataSet()->getShearStressValues();
+
+         int ghostLayer = kernel->getGhostLayerWidth();
+         LBMReal collFactor = kernel->getCollisionFactor();
+
+         int minX1 = ghostLayer;
+         int maxX1 = (int)bcArray->getNX1() - 1 - ghostLayer;
+         int minX2 = ghostLayer;
+         int maxX2 = (int)bcArray->getNX2() - 1 - ghostLayer;
+         int minX3 = ghostLayer;
+         int maxX3 = (int)bcArray->getNX3() - 1 - ghostLayer;
+
+         int level=block->getLevel();
+         if(level==1)
+         {
+            int le=0;
+         }
+         for(std::vector<int> node : transNodeIndicesSet)
+         {
+            int ix1 = node[0];
+            int ix2 = node[1];
+            int ix3 = node[2];
+
+            //without ghost nodes
+            if (ix1 < minX1 || ix1 > maxX1 || ix2 < minX2 || ix2 > maxX2 ||ix3 < minX3 || ix3 > maxX3 ) continue;
+
+            if(bcArray->isFluid(ix1,ix2,ix3)) 
+            {
+               double q=(*ssv)(normalq,ix1,ix2,ix3) ;
+               double numPoint=(*ssv)(numberOfPoint,ix1,ix2,ix3) ;
+               if (q==0||numPoint!=3)continue;
+               // if (q==0)continue;
+
+               int index = 0;
+               nodes.push_back( makeUbTuple(float(val<1>(org) - val<1>(nodeOffset) + ix1*dx),
+                  float(val<2>(org) - val<2>(nodeOffset) + ix2*dx),
+                  float(val<3>(org) - val<3>(nodeOffset) + ix3*dx)) );
+
+               //////get normal and distance//////
+               double A,B,C;
+               A=	(*ssv)(normalX1,ix1,ix2,ix3)	;
+               B=	(*ssv)(normalX2,ix1,ix2,ix3)	;
+               C=	(*ssv)(normalX3,ix1,ix2,ix3)	;
+
+               ///////////
+               //compute y plus
+               //double vtxSonja, vtySonja, vtzSonja; //tangent velocity
+               // double temp = (*av)(ix1,ix2,ix3,AvVx)*A+(*av)(ix1,ix2,ix3,AvVy)*B+(*av)(ix1,ix2,ix3,AvVz)*C;
+               // vtxSonja = (*av)(ix1,ix2,ix3,AvVx)-normals[0]*temp;
+               // vtySonja = (*av)(ix1,ix2,ix3,AvVy)-normals[1]*temp;
+               // vtzSonja = (*av)(ix1,ix2,ix3,AvVz)-normals[2]*temp;
+
+               double vtx=  (B*B*(*ssv)(AvVx,ix1,ix2,ix3) +  C*C*(*ssv)(AvVx,ix1,ix2,ix3) - A*B*(*ssv)(AvVy,ix1,ix2,ix3) - A*C*(*ssv)(AvVy,ix1,ix2,ix3))/(A*A+B*B+C*C);
+               double vty=(-(A*B*(*ssv)(AvVx,ix1,ix2,ix3)) + A*A*(*ssv)(AvVy,ix1,ix2,ix3) + C*C*(*ssv)(AvVy,ix1,ix2,ix3) - B*C*(*ssv)(AvVz,ix1,ix2,ix3))/(A*A+B*B+C*C);
+               double vtz=(-(A*C*(*ssv)(AvVx,ix1,ix2,ix3)) - B*C*(*ssv)(AvVy,ix1,ix2,ix3) + A*A*(*ssv)(AvVz,ix1,ix2,ix3) + B*B*(*ssv)(AvVz,ix1,ix2,ix3))/(A*A+B*B+C*C);
+
+               double normVt = sqrt(vtx*vtx+vty*vty+vtz*vtz)+1e-100;
+               double nvtx = vtx / normVt;
+               double nvty = vty / normVt;
+               double nvtz = vtz / normVt;
+
+               double sx=0.5*((*ssv)(AvSxx,ix1,ix2,ix3)*nvtx+(*ssv)(AvSxy,ix1,ix2,ix3)*nvty+(*ssv)(AvSxz,ix1,ix2,ix3)*nvtz);
+               double sy=0.5*((*ssv)(AvSxy,ix1,ix2,ix3)*nvtx+(*ssv)(AvSyy,ix1,ix2,ix3)*nvty+(*ssv)(AvSyz,ix1,ix2,ix3)*nvtz);
+               double sz=0.5*((*ssv)(AvSxz,ix1,ix2,ix3)*nvtx+(*ssv)(AvSyz,ix1,ix2,ix3)*nvty+(*ssv)(AvSzz,ix1,ix2,ix3)*nvtz);
+               double sabs=sqrt(sx*sx+sy*sy+sz*sz);
+
+               double viscosity = (1.0/3.0)*(1.0/collFactor-0.5);
+               double rho = 1.0;
+               double utau=sqrt(viscosity/rho*sabs);
+
+               // double q=(*av)(ix1,ix2,ix3,normalq) ;
+               double yPlus = (utau*q)/viscosity;
+
+               data[index++].push_back(yPlus);
+               data[index++].push_back(utau);
+            }
+         }
+      }
+   }
+
+}
+//////////////////////////////////////////////////////////////////////////
+void ShearStressCoProcessor::reset(double step)
+{
+   if(Resetscheduler->isDue(step) )
+      resetData(step);
+
+   UBLOG(logDEBUG3, "resetCoProcessor::update:" << step);
+}
+//////////////////////////////////////////////////////////////////////////
+void ShearStressCoProcessor::resetData(double step)
+{
+   for(int level = minInitLevel; level<=maxInitLevel;level++)
+   {
+      for(Block3DPtr block : blockVector[level])
+      {
+         if (block)
+         {
+            UbTupleDouble3 org          = grid->getBlockWorldCoordinates(block);
+            UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
+            UbTupleDouble3 nodeOffset   = grid->getNodeOffset(block);
+            double         dx           = grid->getDeltaX(block);
+
+            ILBMKernelPtr kernel = block->getKernel();
+            BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
+            DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions(); 
+            ShearStressValuesArray3DPtr ssv = kernel->getDataSet()->getShearStressValues();
+
+            int minX1 = 0;
+            int minX2 = 0;
+            int minX3 = 0;
+
+            int maxX1 = int(distributions->getNX1());
+            int maxX2 = int(distributions->getNX2());
+            int maxX3 = int(distributions->getNX3());
+
+            for(int ix3=minX3; ix3<maxX3-1; ix3++)
+            {
+               for(int ix2=minX2; ix2<maxX2-1; ix2++)
+               {
+                  for(int ix1=minX1; ix1<maxX1-1; ix1++)
+                  {
+                     if(!bcArray->isUndefined(ix1,ix2,ix3) && !bcArray->isSolid(ix1,ix2,ix3))
+                     {
+                        //////////////////////////////////////////////////////////////////////////
+                        //compute average values
+                        //////////////////////////////////////////////////////////////////////////
+                        (*ssv)(AvVx,ix1,ix2,ix3) = 0.0;
+                        (*ssv)(AvVy,ix1,ix2,ix3) = 0.0;
+                        (*ssv)(AvVz,ix1,ix2,ix3) = 0.0;
+
+                        (*ssv)(AvSxx,ix1,ix2,ix3) = 0.0;
+                        (*ssv)(AvSyy,ix1,ix2,ix3) = 0.0;
+                        (*ssv)(AvSzz,ix1,ix2,ix3) = 0.0;
+                        (*ssv)(AvSxy,ix1,ix2,ix3) = 0.0;
+                        (*ssv)(AvSyz,ix1,ix2,ix3) = 0.0;
+                        (*ssv)(AvSxz,ix1,ix2,ix3) = 0.0;
+                        //////////////////////////////////////////////////////////////////////////
+                     }
+                  }
+               }
+            }
+         }
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void ShearStressCoProcessor::addInteractor( D3Q27InteractorPtr interactor )
+{
+   interactors.push_back(interactor);
+}
+//////////////////////////////////////////////////////////////////////////
+void ShearStressCoProcessor::findPlane(int ix1,int ix2,int ix3,Grid3DPtr grid,Block3DPtr block,double &A,double &B,double &C,double &D,double &ii)
+{
+   double x1plane=0.0,y1plane=0.0,z1plane=0.0;
+   double x2plane=0.0,y2plane=0.0,z2plane=0.0;
+   double x3plane=0.0,y3plane=0.0,z3plane=0.0;
+   BoundaryConditionsPtr bcPtr;
+   double dx = grid->getDeltaX(block);
+   ILBMKernelPtr kernel = block->getKernel();
+   DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();
+   BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
+   bcPtr=bcArray->getBC(ix1,ix2,ix3);
+   int x,y,z;
+
+
+   if(InterpolationProcessor::iCellHasSolid(bcArray, ix1, ix2, ix3)) { x = ix1;y = ix2;z = ix3;}   
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1  , ix2-1, ix3  )) { x = ix1+0; y = ix2-1; z = ix3+0;}//S
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1  , ix2  , ix3-1)) { x = ix1+0; y = ix2+0; z = ix3-1;}//B		   
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1-1, ix2  , ix3  )) { x = ix1-1; y = ix2+0; z = ix3+0;}//w
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1  , ix2-1, ix3-1)) { x = ix1+0; y = ix2-1; z = ix3-1;}//BS
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1-1, ix2  , ix3-1)) { x = ix1-1; y = ix2+0; z = ix3-1;}//BW
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1-1, ix2-1, ix3  )) { x = ix1-1; y = ix2-1; z = ix3+0;}//SW
+
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1-1, ix2-1, ix3-1)) { x = ix1-1; y = ix2-1; z = ix3-1;}//BSW	  
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1+1, ix2  , ix3  )) { x = ix1+1; y = ix2+0; z = ix3+0;}//E
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1  , ix2+1, ix3  )) { x = ix1+0; y = ix2+1; z = ix3+0;}//N
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1  , ix2  , ix3+1)) { x = ix1+0; y = ix2+0; z = ix3+1;}//T	
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1+1, ix2+1, ix3  )) { x = ix1+1; y = ix2+1; z = ix3+0;}//NE
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1+1, ix2  , ix3+1)) { x = ix1+1; y = ix2+0; z = ix3+1;}//TE
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1  , ix2+1, ix3+1)) { x = ix1+0; y = ix2+1; z = ix3+1;}//TN
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1+1, ix2+1, ix3+1)) { x = ix1+1; y = ix2+1; z = ix3+1;}//TNE
+
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1+1, ix2-1, ix3  )) { x = ix1+1; y = ix2-1; z = ix3+0;}//SE
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1-1, ix2+1, ix3  )) { x = ix1-1; y = ix2+1; z = ix3+0;}//NW
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1+1, ix2  , ix3-1)) { x = ix1+1; y = ix2+0; z = ix3-1;}//BE
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1-1, ix2  , ix3+1)) { x = ix1-1; y = ix2+0; z = ix3+1;}//TW
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1+0, ix2+1, ix3-1)) { x = ix1+0; y = ix2+1; z = ix3-1;}//BN
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1+0, ix2-1, ix3+1)) { x = ix1+0; y = ix2-1; z = ix3+1;}//TS
+
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1-1, ix2+1, ix3+1)) { x = ix1-1; y = ix2+1; z = ix3+1;}//TNW 
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1+1, ix2-1, ix3+1)) { x = ix1+1; y = ix2-1; z = ix3+1;}//TSE 
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1-1, ix2-1, ix3+1)) { x = ix1-1; y = ix2-1; z = ix3+1;}//TSW 
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1+1, ix2+1, ix3-1)) { x = ix1+1; y = ix2+1; z = ix3-1;}//BNE 
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1-1, ix2+1, ix3-1)) { x = ix1-1; y = ix2+1; z = ix3-1;}//BNW 
+   else if(InterpolationProcessor::iCellHasSolid(bcArray, ix1+1, ix2-1, ix3-1)) { x = ix1+1; y = ix2-1; z = ix3-1;}//BSE 
+
+
+   else   {{UB_THROW( UbException(UB_EXARGS,"there is no cell  ix1="+UbSystem::toString(ix1)+"ix2="+UbSystem::toString(ix2)+"ix3="+UbSystem::toString(ix3)+"GlobalID="+UbSystem::toString(block->getGlobalID())+"dx="+UbSystem::toString(dx)
+      +"T="+UbSystem::toString(bcPtr->getQ(D3Q27System::T))+"B="+UbSystem::toString(bcPtr->getQ(D3Q27System::B))
+      +"E="+UbSystem::toString(bcPtr->getQ(D3Q27System::E))+"W="+UbSystem::toString(bcPtr->getQ(D3Q27System::W))+"N="+UbSystem::toString(bcPtr->getQ(D3Q27System::N))	
+      +"S="+UbSystem::toString(bcPtr->getQ(D3Q27System::S))+"NE="+UbSystem::toString(bcPtr->getQ(D3Q27System::NE))+"SW="+UbSystem::toString(bcPtr->getQ(D3Q27System::SW))
+      +"SE="+UbSystem::toString(bcPtr->getQ(D3Q27System::SE))+"NW="+UbSystem::toString(bcPtr->getQ(D3Q27System::NW))    
+      +"TE="+
+      UbSystem::toString(bcPtr->getQ(D3Q27System::TE))+"BW="+UbSystem::toString(bcPtr->getQ(D3Q27System::BW))+"BE="+UbSystem::toString(bcPtr->getQ(D3Q27System::BE))+"TW="+
+      UbSystem::toString(bcPtr->getQ(D3Q27System::TW))+"TN="+UbSystem::toString(bcPtr->getQ(D3Q27System::TN))+"BS="+UbSystem::toString(bcPtr->getQ(D3Q27System::BS))+"BN="+
+      UbSystem::toString(bcPtr->getQ(D3Q27System::BN))+"TS="+UbSystem::toString(bcPtr->getQ(D3Q27System::TS))+"TNE="+UbSystem::toString(bcPtr->getQ(D3Q27System::TNE))+"TNW="+
+      UbSystem::toString(bcPtr->getQ(D3Q27System::TNW))+"TSE="+UbSystem::toString(bcPtr->getQ(D3Q27System::TSE))+"TSW="+UbSystem::toString(bcPtr->getQ(D3Q27System::TSW))+"BNE="+
+      UbSystem::toString(bcPtr->getQ(D3Q27System::BNE))+"BNW="+UbSystem::toString(bcPtr->getQ(D3Q27System::BNW))+"BSE="+UbSystem::toString(bcPtr->getQ(D3Q27System::BSE))+"BSW="+UbSystem::toString(bcPtr->getQ(D3Q27System::BSW)*dx)
+      ) ) ;}} 
+
+
+   if(InterpolationProcessor::iCellHasSolid(bcArray, x, y, z))
+   {  
+      for(int i = x; i <= x + 1; i++){
+         for(int j = y; j <= y + 1; j++){
+            for (int k = z; k <= z + 1; k++)
+            {
+               Vector3D pointplane1 =  grid->getNodeCoordinates(block,  i,	  j,	 k);
+
+               double   iph=pointplane1[0];
+               double   jph=pointplane1[1];
+               double   kph=pointplane1[2];
+
+               if(!bcArray->isSolid(i, j, k))
+               {
+                  BoundaryConditionsPtr bcPtrIn=bcArray->getBC(i,j,k);
+                  if(bcPtrIn)
+                  {	 
+                     for(int fdir=D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
+                     {
+                        if( ii<=2)
+                        {
+                           LBMReal q = bcPtrIn->getQ(fdir);
+                           if (q!=999.00000)
+                           {	  
+                              if     ( fdir==D3Q27System::E ) 
+                              {
+                                 //if(!bcArray->isSolid(i, j, k))continue;
+                                 if (i+q<=x+1)
+                                 {
+                                    if      (ii==0)	    {	x1plane=iph+q*dx;	  y1plane=jph;	 z1plane=kph;    	ii++;	} 
+                                    else if (ii==1) 	{	x2plane=iph+q*dx;     y2plane=jph;	 z2plane=kph;	    if  (x1plane!=x2plane||y1plane!=y2plane||z1plane!=z2plane) 	ii++;	}
+                                    else if(ii==2) 	    {   x3plane=iph+q*dx;     y3plane=jph;	 z3plane=kph;       if ((x3plane!=x1plane||y3plane!=y1plane||z3plane!=z1plane)&&(x2plane!=x3plane||y2plane!=y3plane||z2plane!=z3plane)) ii++;} 
+                                 }
+                              }
+                              if     ( fdir==D3Q27System::W ) 
+                              {
+                                 //if(!bcArray->isSolid(i, j, k))continue;
+                                 if (i-q>=x)
+                                 {
+                                    if      (ii==0)	    {	x1plane=iph-q*dx;	  y1plane=jph;	 z1plane=kph;    	ii++;	} 
+                                    else if (ii==1) 	    {	x2plane=iph-q*dx;    y2plane=jph;	 z2plane=kph;	    if  (x1plane!=x2plane||y1plane!=y2plane||z1plane!=z2plane) 	ii++;	}
+                                    else if(ii==2) 	    {   x3plane=iph-q*dx;    y3plane=jph;	 z3plane=kph;       if ((x3plane!=x1plane||y3plane!=y1plane||z3plane!=z1plane)&&(x2plane!=x3plane||y2plane!=y3plane||z2plane!=z3plane)) ii++;} 
+                                 }
+                              }
+                              if     ( fdir==D3Q27System::N ) 
+                              {
+                                 //if(!bcArray->isSolid(i, j, k))continue;
+                                 if(j+q<=y+1)
+                                 {
+                                    if      (ii==0)	    {	x1plane=iph;	y1plane=jph+q*dx;	 z1plane=kph; 	    ii++;	} 
+                                    else if (ii==1) 	    {	x2plane=iph;    y2plane=jph+q*dx;	 z2plane=kph;	    if  (x1plane!=x2plane||y1plane!=y2plane||z1plane!=z2plane) 	ii++;	}
+                                    else if (ii==2) 	    {   x3plane=iph;    y3plane=jph+q*dx;	 z3plane=kph;       if ((x3plane!=x1plane||y3plane!=y1plane||z3plane!=z1plane)&&(x2plane!=x3plane||y2plane!=y3plane||z2plane!=z3plane)) ii++;} 
+                                 }
+                              }
+                              if     ( fdir==D3Q27System::S ) 
+                              {
+                                 //if(!bcArray->isSolid(i, j, k))continue;
+                                 if (j-q>=y)
+                                 {
+                                    if      (ii==0)	    {	x1plane=iph;	y1plane=jph-q*dx;	 z1plane=kph; 	ii++;	} 
+                                    else if (ii==1) 	    {	x2plane=iph;    y2plane=jph-q*dx;	 z2plane=kph;	if  (x1plane!=x2plane||y1plane!=y2plane||z1plane!=z2plane) 	ii++;	}
+                                    else if (ii==2) 	    {   x3plane=iph;    y3plane=jph-q*dx;	 z3plane=kph;   if ((x3plane!=x1plane||y3plane!=y1plane||z3plane!=z1plane)&&(x2plane!=x3plane||y2plane!=y3plane||z2plane!=z3plane)) ii++;} 
+                                 }
+                              }
+
+                              if     ( fdir==D3Q27System::T ) 
+                              {
+                                 //if(!bcArray->isSolid(i, j, k))continue;
+                                 if(k+q<=z+1)
+                                 {
+                                    if      (ii==0)	    {	x1plane=iph;	y1plane=jph;	 z1plane=kph+q*dx; 	    ii++;	} 
+                                    else if (ii==1) 	    {	x2plane=iph;    y2plane=jph;	 z2plane=kph+q*dx;	    if  (x1plane!=x2plane||y1plane!=y2plane||z1plane!=z2plane) 	ii++;	}
+                                    else if (ii==2) 	    {   x3plane=iph;    y3plane=jph;	 z3plane=kph+q*dx;      if ((x3plane!=x1plane||y3plane!=y1plane||z3plane!=z1plane)&&(x2plane!=x3plane||y2plane!=y3plane||z2plane!=z3plane)) ii++;} 
+                                 }
+                              }
+                              if     ( fdir==D3Q27System::B ) 
+                              {
+                                 //if(!bcArray->isSolid(i, j, k))continue;
+                                 if (k-q>=z)
+                                 {
+                                    if      (ii==0)	    {	x1plane=iph;	y1plane=jph;	 z1plane=kph-q*dx; 	ii++;	} 
+                                    else if (ii==1) 	    {	x2plane=iph;    y2plane=jph;	 z2plane=kph-q*dx;	  if  (x1plane!=x2plane||y1plane!=y2plane||z1plane!=z2plane) 	ii++;	}
+                                    else if (ii==2) 	    {   x3plane=iph;    y3plane=jph;	 z3plane=kph-q*dx;     if ((x3plane!=x1plane||y3plane!=y1plane||z3plane!=z1plane)&&(x2plane!=x3plane||y2plane!=y3plane||z2plane!=z3plane)) ii++;} 
+                                 }
+                              }
+
+                           }
+                        }
+                     }
+                  }
+               }
+            }
+         }
+      }
+
+      A =   y1plane* (z2plane - z3plane) + y2plane*(z3plane - z1plane) + y3plane* (z1plane - z2plane);   
+      B =   z1plane* (x2plane - x3plane) + z2plane*(x3plane - x1plane) + z3plane* (x1plane - x2plane) ;      
+      C =   x1plane* (y2plane - y3plane) + x2plane*(y3plane - y1plane) + x3plane* (y1plane - y2plane) ;       
+      D =-( x1plane*(y2plane*z3plane - y3plane*z2plane)+x2plane*(y3plane*z1plane - y1plane*z3plane) + x3plane* (y1plane* z2plane - y2plane* z1plane));	
+   }
+   if(ii!=3){
+
+      {{UB_THROW( UbException(UB_EXARGS,"ii is="+UbSystem::toString(ii)+"  ix1="+UbSystem::toString(ix1)+" ix2="+UbSystem::toString(ix2)+" ix3="+UbSystem::toString(ix3)+" Block3D::GlobalID="+UbSystem::toString(block->getGlobalID())+" dx="+UbSystem::toString(dx)
+         +" T="+UbSystem::toString(bcPtr->getQ(D3Q27System::T))+" B="+UbSystem::toString(bcPtr->getQ(D3Q27System::B))
+         +" E="+UbSystem::toString(bcPtr->getQ(D3Q27System::E))+" W="+UbSystem::toString(bcPtr->getQ(D3Q27System::W))+" N="+UbSystem::toString(bcPtr->getQ(D3Q27System::N))	
+         +" S="+UbSystem::toString(bcPtr->getQ(D3Q27System::S))+" NE="+UbSystem::toString(bcPtr->getQ(D3Q27System::NE))+" SW="+UbSystem::toString(bcPtr->getQ(D3Q27System::SW))
+         +" SE="+UbSystem::toString(bcPtr->getQ(D3Q27System::SE))+" NW="+UbSystem::toString(bcPtr->getQ(D3Q27System::NW))    
+         +" TE="+
+         UbSystem::toString(bcPtr->getQ(D3Q27System::TE))+" BW="+UbSystem::toString(bcPtr->getQ(D3Q27System::BW))+" BE="+UbSystem::toString(bcPtr->getQ(D3Q27System::BE))+" TW="+
+         UbSystem::toString(bcPtr->getQ(D3Q27System::TW))+" TN="+UbSystem::toString(bcPtr->getQ(D3Q27System::TN))+" BS="+UbSystem::toString(bcPtr->getQ(D3Q27System::BS))+" BN="+
+         UbSystem::toString(bcPtr->getQ(D3Q27System::BN))+" TS="+UbSystem::toString(bcPtr->getQ(D3Q27System::TS))+" TNE="+UbSystem::toString(bcPtr->getQ(D3Q27System::TNE))+" TNW="+
+         UbSystem::toString(bcPtr->getQ(D3Q27System::TNW))+" TSE="+UbSystem::toString(bcPtr->getQ(D3Q27System::TSE))+" TSW="+UbSystem::toString(bcPtr->getQ(D3Q27System::TSW))+" BNE="+
+         UbSystem::toString(bcPtr->getQ(D3Q27System::BNE))+" BNW="+UbSystem::toString(bcPtr->getQ(D3Q27System::BNW))+" BSE="+UbSystem::toString(bcPtr->getQ(D3Q27System::BSE))+" BSW="+UbSystem::toString(bcPtr->getQ(D3Q27System::BSW))
+         ) ) ;}}
+
+   }	
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+bool ShearStressCoProcessor::checkUndefindedNodes( BCArray3DPtr bcArray,int ix1,int ix2,int ix3)
+{
+   for(int i = ix1; i <= ix1 + 1; i++){
+      for(int j = ix2; j <= ix2 + 1; j++){
+         for (int k = ix3; k <= ix3 + 1; k++)
+         {	
+            if(bcArray->isUndefined(i, j, k)) return true;
+         }  
+      }
+   }
+   return false;
+}
+//////////////////////////////////////////////////////////////////////////////////////
+void ShearStressCoProcessor::initDistance()
+{
+   for(D3Q27InteractorPtr interactor : interactors)
+   {
+      typedef std::map<Block3DPtr, std::set< std::vector<int> > > TransNodeIndicesMap;
+      for (TransNodeIndicesMap::value_type t : interactor->getBcNodeIndicesMap())
+      {
+         Block3DPtr block = t.first;
+         std::set< std::vector<int> >& transNodeIndicesSet = t.second;
+
+         UbTupleDouble3 org          = grid->getBlockWorldCoordinates(block);
+         UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
+         UbTupleDouble3 nodeOffset   = grid->getNodeOffset(block);
+         double         dx           = grid->getDeltaX(block);
+
+         ILBMKernelPtr kernel = block->getKernel();
+         BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
+         DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions(); 
+         ShearStressValuesArray3DPtr ssv = kernel->getDataSet()->getShearStressValues();
+
+         int ghostLayer = kernel->getGhostLayerWidth();
+         LBMReal collFactor = kernel->getCollisionFactor();
+
+         int minX1 = ghostLayer;
+         int maxX1 = (int)bcArray->getNX1() - 1 - ghostLayer;
+         int minX2 = ghostLayer;
+         int maxX2 = (int)bcArray->getNX2() - 1 - ghostLayer;
+         int minX3 = ghostLayer;
+         int maxX3 = (int)bcArray->getNX3() - 1 - ghostLayer;
+
+         for(std::vector<int> node : transNodeIndicesSet)
+         {
+            int ix1 = node[0];
+            int ix2 = node[1];
+            int ix3 = node[2];
+
+            //without ghost nodes
+            if (ix1 < minX1 || ix1 > maxX1 || ix2 < minX2 || ix2 > maxX2 ||ix3 < minX3 || ix3 > maxX3 ) continue;
+
+            if(bcArray->isFluid(ix1,ix2,ix3) )
+            {
+               BoundaryConditionsPtr bc = bcArray->getBC(ix1,ix2,ix3);
+               if((bc->hasDensityBoundary()||bc->hasVelocityBoundary()))continue;
+               int numberOfCorner=0;
+
+               if(bc->getQ(D3Q27System::T)  !=999.000){ numberOfCorner++;}
+               if(bc->getQ(D3Q27System::B)  !=999.000){ numberOfCorner++;}
+               if(bc->getQ(D3Q27System::E)  !=999.000){ numberOfCorner++;}
+               if(bc->getQ(D3Q27System::W)  !=999.000){ numberOfCorner++;}
+               if(bc->getQ(D3Q27System::N)  !=999.000){ numberOfCorner++;}
+               if(bc->getQ(D3Q27System::S)  !=999.000){ numberOfCorner++;}
+               // if(bc->hasVelocityBoundary()||bc->hasDensityBoundary())continue;
+               if(numberOfCorner>1)continue;
+               if(checkUndefindedNodes( bcArray, ix1,ix2,ix3))continue;
+
+
+               //////get normal and distance//////
+               double A,B,C,D,ii=0.0;
+               findPlane(ix1,ix2,ix3,grid,block,A,B,C,D,ii);
+               Vector3D pointplane1 =  grid->getNodeCoordinates(block, ix1,ix2,ix3);
+               double   ix1ph= pointplane1[0];
+               double   ix2ph= pointplane1[1];
+               double   ix3ph= pointplane1[2];
+               double normalDis;
+               if(ii!=3)
+               {
+                  UB_THROW( UbException(UB_EXARGS,"not enough points to create plane"+UbSystem::toString(ii)));
+               }
+               else
+               {    
+                  double s = A*ix1ph + B*ix2ph + C*ix3ph + D;//The sign of s = Ax + By + Cz + D determines which side the point (x,y,z) lies with respect to the plane. If s > 0 then the point lies on the same side as the normal (A,B,C). If s < 0 then it lies on the opposite side, if s = 0 then the point (x,y,z) lies on the plane.
+                  if (s>0){s=1;} else if (s<0){s=-1;}else {s=0;}
+
+                  normalDis=((A*ix1ph + B*ix2ph + C*ix3ph + D)/sqrt(A*A+B*B+C*C));///distance point to plane xp-Xw=distance
+                  normalDis*=s;
+
+                  (*ssv)(normalX1,ix1,ix2,ix3) = A;
+                  (*ssv)(normalX2,ix1,ix2,ix3) = B;
+                  (*ssv)(normalX3,ix1,ix2,ix3) = C;
+                  (*ssv)(normalq,ix1,ix2,ix3) = normalDis;
+                  (*ssv)(numberOfPoint,ix1,ix2,ix3) = ii;
+
+               }
+            }
+         }
+      }
+   }
+}
diff --git a/source/VirtualFluidsCore/CoProcessors/ShearStressCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/ShearStressCoProcessor.h
index c6c28181d..82ef32dda 100644
--- a/source/VirtualFluidsCore/CoProcessors/ShearStressCoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/ShearStressCoProcessor.h
@@ -1,15 +1,23 @@
 #ifndef D3Q27ShearStressCoProcessor_H
 #define D3Q27ShearStressCoProcessor_H
 
+#include <memory>
+#include <vector>
+#include <string>
+
+#include <basics/utilities/UbTuple.h>
+
 #include "CoProcessor.h"
-#include "Communicator.h"
-#include "D3Q27Interactor.h"
-#include "InterpolationProcessor.h"
-#include "WbWriter.h"
 
-#include <boost/shared_ptr.hpp>
 class ShearStressCoProcessor;
-typedef boost::shared_ptr<ShearStressCoProcessor> ShearStressCoProcessorPtr;
+typedef std::shared_ptr<ShearStressCoProcessor> ShearStressCoProcessorPtr;
+
+class Block3D;
+class Grid3D;
+class UbScheduler;
+class D3Q27Interactor;
+class BCArray3D;
+class WbWriter;
 
 //! \brief  Computes the shear stress and y plus values and writes to parallel .vtk
 //! \details writes at given time intervals specified in scheduler (s) and resets according to scheduler (rs).  
@@ -19,14 +27,16 @@ typedef boost::shared_ptr<ShearStressCoProcessor> ShearStressCoProcessorPtr;
 class ShearStressCoProcessor: public CoProcessor 
 {
 public:
-   //! Defoult constructor
+   //! Default constructor
    ShearStressCoProcessor(){}
    //! Constructor
-   ShearStressCoProcessor(Grid3DPtr grid, const std::string& path, WbWriter* const writer, 
-      UbSchedulerPtr s, UbSchedulerPtr rs);
-   virtual ~ShearStressCoProcessor();             
-   void process(double step); 
-   void addInteractor(D3Q27InteractorPtr interactor);
+   ShearStressCoProcessor(std::shared_ptr<Grid3D> grid, const std::string& path, WbWriter* const writer,
+       std::shared_ptr<UbScheduler> s, std::shared_ptr<UbScheduler> rs);
+   virtual ~ShearStressCoProcessor(); 
+    
+   void process(double step) override; 
+
+   void addInteractor(std::shared_ptr<D3Q27Interactor> interactor);
 protected:
    //! Computes average and shear stress values of macroscopic quantities 
    void calculateShearStress(double timeStep);
@@ -38,22 +48,23 @@ protected:
    void addData();
    void clearData();
    void reset(double step);
-   void findPlane(int ix1,int ix2,int ix3,Grid3DPtr grid,Block3DPtr block,double &A,double &B,double &C,double &D,double &ii);
-   bool checkUndefindedNodes( BCArray3DPtr bcArray,int ix1,int ix2,int ix3);
+   void findPlane(int ix1,int ix2,int ix3, std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block,double &A,double &B,double &C,double &D,double &ii);
+   bool checkUndefindedNodes(std::shared_ptr<BCArray3D> bcArray,int ix1,int ix2,int ix3);
    void initDistance();
+
 private:
    std::vector<UbTupleFloat3> nodes;
    std::vector<std::string> datanames;
    std::vector<std::vector<double> > data;
    std::string path;
-   std::vector<D3Q27InteractorPtr> interactors;
+   std::vector<std::shared_ptr<D3Q27Interactor> > interactors;
    std::vector<double> normals;
    int gridRank;
    WbWriter* writer;
-   UbSchedulerPtr Resetscheduler;  //additional scheduler to restart averaging after a given interval
+   std::shared_ptr<UbScheduler> Resetscheduler;  //additional scheduler to restart averaging after a given interval
    int minInitLevel; //min init level
    int maxInitLevel;
-   std::vector<std::vector<Block3DPtr> > blockVector;
+   std::vector<std::vector<std::shared_ptr<Block3D> > > blockVector;
    enum Values{AvVx = 0, AvVy = 1, AvVz = 2, AvSxx = 3, AvSyy = 4, AvSzz = 5, AvSxy = 6, AvSyz = 7, AvSxz = 8, normalX1 = 9, normalX2 = 10, normalX3 = 11, normalq = 12,numberOfPoint=13}; 
 
    friend class boost::serialization::access;
diff --git a/source/VirtualFluidsCore/CoProcessors/TimeAveragedValuesCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/TimeAveragedValuesCoProcessor.cpp
index 47774d6cc..79b43bc28 100644
--- a/source/VirtualFluidsCore/CoProcessors/TimeAveragedValuesCoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/TimeAveragedValuesCoProcessor.cpp
@@ -1,753 +1,757 @@
-#include "TimeAveragedValuesCoProcessor.h"
-#include "LBMKernel.h"
-#include "BCProcessor.h"
-#include <vector>
-#include <sstream>
-#include <string>
-#include <iostream>
-#include <boost/foreach.hpp>
-#include "basics/writer/WbWriterVtkXmlASCII.h"
-#include "basics/utilities/UbMath.h"
-
-using namespace std;
-
-TimeAveragedValuesCoProcessor::TimeAveragedValuesCoProcessor()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-TimeAveragedValuesCoProcessor::TimeAveragedValuesCoProcessor(Grid3DPtr grid, const std::string& path, WbWriter* const writer,
-   UbSchedulerPtr s, CommunicatorPtr comm, int options)
-   : CoProcessor(grid, s),
-   path(path),
-   writer(writer),
-   comm(comm),
-   options(options)
-{
-   init(s);
-   planarAveraging = false;
-   timeAveraging = true;
-}
-//////////////////////////////////////////////////////////////////////////
-TimeAveragedValuesCoProcessor::TimeAveragedValuesCoProcessor(Grid3DPtr grid, const std::string& path, WbWriter* const writer,
-   UbSchedulerPtr s, CommunicatorPtr comm, int options,
-   std::vector<int> levels, std::vector<double>& levelCoords, std::vector<double>& bounds, bool timeAveraging)
-   : CoProcessor(grid, s),
-   path(path),
-   writer(writer),
-   comm(comm),
-   options(options),
-   levels(levels),
-   levelCoords(levelCoords),
-   bounds(bounds),
-   timeAveraging(timeAveraging)
-{
-   init(s);
-   planarAveraging = true;
-}
-//////////////////////////////////////////////////////////////////////////
-void TimeAveragedValuesCoProcessor::init(UbSchedulerPtr s)
-{
-   root = comm->isRoot();
-   gridRank = grid->getRank();
-   minInitLevel = this->grid->getCoarsestInitializedLevel();
-   maxInitLevel = this->grid->getFinestInitializedLevel();
-
-   blockVector.resize(maxInitLevel + 1);
-
-   for (int level = minInitLevel; level <= maxInitLevel; level++)
-   {
-      grid->getBlocks(level, gridRank, true, blockVector[level]);
-
-      if (blockVector[level].size() > 0)
-         compressible = blockVector[level][0]->getKernel()->getCompressible();
-
-      double begin = s->getMinBegin();
-      double gridTimeStep = grid->getTimeStep();
-
-      if (gridTimeStep == begin || gridTimeStep == 0)
-      {
-         BOOST_FOREACH(Block3DPtr block, blockVector[level])
-         {
-            UbTupleInt3 nx = grid->getBlockNX();
-            
-            if ((options&Density) == Density)
-            {
-               AverageValuesArray3DPtr ar = AverageValuesArray3DPtr(new AverageValuesArray3D(1, val<1>(nx) + 1, val<2>(nx) + 1, val<3>(nx) + 1, 0.0));
-               block->getKernel()->getDataSet()->setAverageDencity(ar);
-            }
-
-            if ((options&Velocity) == Velocity)
-            {
-               AverageValuesArray3DPtr av = AverageValuesArray3DPtr(new AverageValuesArray3D(3, val<1>(nx) + 1, val<2>(nx) + 1, val<3>(nx) + 1, 0.0));
-               block->getKernel()->getDataSet()->setAverageVelocity(av);
-            }
-
-            if ((options&Fluctuations) == Fluctuations)
-            {
-               AverageValuesArray3DPtr af = AverageValuesArray3DPtr(new AverageValuesArray3D(6, val<1>(nx) + 1, val<2>(nx) + 1, val<3>(nx) + 1, 0.0));
-               block->getKernel()->getDataSet()->setAverageFluctuations(af);
-            }
-
-            if ((options&Triplecorrelations) == Triplecorrelations)
-            {
-               AverageValuesArray3DPtr at = AverageValuesArray3DPtr(new AverageValuesArray3D(10, val<1>(nx) + 1, val<2>(nx) + 1, val<3>(nx) + 1, 0.0));
-               block->getKernel()->getDataSet()->setAverageTriplecorrelations(at);
-            }
-         }
-      }
-   }
-
-   //breakStep = scheduler->getMaxEnd() - scheduler->getMinBegin()+1;
-   //UBLOG(logINFO, "breakSteps = " << breakStep);
-   //breakStep = breakStep * (double)(1 << maxInitLevel);
-   //breakStep = scheduler->getMaxEnd()*(double)(1 << maxInitLevel);
-   //UBLOG(logINFO, "breakSteps = " << breakStep);
-
-   withGhostLayer = false;
-   iMinC = 1;
-
-   lcounter = 0;
-
-   levelFactor = 1 << maxInitLevel;
-   maxStep = scheduler->getMaxEnd();
-   numberOfFineSteps = int(maxStep - scheduler->getMinBegin()) * levelFactor;
-   numberOfSteps = int(maxStep - scheduler->getMinBegin());
-
-   //function pointer
-   using namespace D3Q27System;
-   calcMacros = NULL;
-   if (compressible)
-   {
-      calcMacros = &calcCompMacroscopicValues;
-   }
-   else
-   {
-      calcMacros = &calcIncompMacroscopicValues;
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void TimeAveragedValuesCoProcessor::process(double step)
-{
-   calculateSubtotal(step);
-
-   if (step == maxStep)
-   {
-      //DEBUG/////////////////////
-      //UBLOG(logINFO, "process::step = " << step << ", maxStep = " << maxStep << ", levelFactor = " << levelFactor << ", numberOfFineSteps = " << numberOfFineSteps);
-      ////////////////////////////
-
-      //calculateAverageValues((double)numberOfFineSteps);
-      calculateAverageValues((double)numberOfSteps);
-      
-      if (timeAveraging)
-      {
-         collectData(step);
-      }
-      
-      if (planarAveraging)
-      {
-         planarAverage(step);
-      }
-   }
-
-   UBLOG(logDEBUG3, "AverageValuesCoProcessor::update:" << step);
-}
-//////////////////////////////////////////////////////////////////////////
-void TimeAveragedValuesCoProcessor::collectData(double step)
-{
-   int istep = int(step);
-
-   for (int level = minInitLevel; level <= maxInitLevel; level++)
-   {
-      BOOST_FOREACH(Block3DPtr block, blockVector[level])
-      {
-         if (block)
-         {
-            addData(block);
-         }
-      }
-   }
-
-   string pfilePath, partPath, subfolder, cfilePath;
-   subfolder = "tav" + UbSystem::toString(istep);
-   pfilePath = path + "/tav/" + subfolder;
-   partPath = pfilePath + "/tav" + UbSystem::toString(gridRank) + "_" + UbSystem::toString(istep);
-
-   string partName = writer->writeOctsWithNodeData(partPath, nodes, cells, datanames, data);
-   size_t found = partName.find_last_of("/");
-   string piece = partName.substr(found + 1);
-   piece = subfolder + "/" + piece;
-
-   vector<string> cellDataNames;
-   vector<string> pieces = comm->gather(piece);
-   if (root)
-   {
-      string pname = WbWriterVtkXmlASCII::getInstance()->writeParallelFile(pfilePath, pieces, datanames, cellDataNames);
-      UBLOG(logINFO, "TimeAveragedValuesCoProcessor::collectData() step: " << istep);
-   }
-
-   clearData();
-}
-//////////////////////////////////////////////////////////////////////////
-void TimeAveragedValuesCoProcessor::clearData()
-{
-   nodes.clear();
-   cells.clear();
-   datanames.clear();
-   data.clear();
-}
-//////////////////////////////////////////////////////////////////////////
-void TimeAveragedValuesCoProcessor::addData(const Block3DPtr block)
-{
-   UbTupleDouble3 org = grid->getBlockWorldCoordinates(block);
-   UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
-   UbTupleDouble3 nodeOffset = grid->getNodeOffset(block);
-   double         dx = grid->getDeltaX(block);
-   int            level = block->getLevel();      
-
-   //Diese Daten werden geschrieben:
-   datanames.resize(0);
-
-   datanames.push_back("level");
-   
-   datanames.push_back("Rho");
-
-   if ((options&Density) == Density)
-   {
-      datanames.push_back("taRho");
-   }
-
-   if ((options&Velocity) == Velocity)
-   {
-      datanames.push_back("taVx");
-      datanames.push_back("taVy");
-      datanames.push_back("taVz");
-   }
-
-   if ((options&Fluctuations) == Fluctuations)
-   {
-      datanames.push_back("taVxx");
-      datanames.push_back("taVyy");
-      datanames.push_back("taVzz");
-      datanames.push_back("taVxy");
-      datanames.push_back("taVxz");
-      datanames.push_back("taVyz");
-   }
-
-   if ((options&Triplecorrelations) == Triplecorrelations)
-   {
-      datanames.push_back("taVxxx");
-      datanames.push_back("taVxxy");
-      datanames.push_back("taVxxz");
-      datanames.push_back("taVyyy");
-      datanames.push_back("taVyyx");
-      datanames.push_back("taVyyz");
-      datanames.push_back("taVzzz");
-      datanames.push_back("taVzzx");
-      datanames.push_back("taVzzy");
-      datanames.push_back("taVxyz");
-   }
-
-
-   //datanames.push_back("AvP");
-   //datanames.push_back("AvPrms");
-
-
-   data.resize(datanames.size());
-
-   LBMKernelPtr kernel = block->getKernel();
-   BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
-   DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();
-   AverageValuesArray3DPtr ar = kernel->getDataSet()->getAverageDencity();
-   AverageValuesArray3DPtr av = kernel->getDataSet()->getAverageVelocity();
-   AverageValuesArray3DPtr af = kernel->getDataSet()->getAverageFluctuations();
-   AverageValuesArray3DPtr at = kernel->getDataSet()->getAverageTriplecorrelations();
-   //int ghostLayerWidth = kernel->getGhostLayerWidth();
-
-   //knotennummerierung faengt immer bei 0 an!
-   int SWB, SEB, NEB, NWB, SWT, SET, NET, NWT;
-
-   int minX1 = iMinC;
-   int minX2 = iMinC;
-   int minX3 = iMinC;
-
-   int maxX1 = int(distributions->getNX1());
-   int maxX2 = int(distributions->getNX2());
-   int maxX3 = int(distributions->getNX3());
-
-   //nummern vergeben und node vector erstellen + daten sammeln
-   CbArray3D<int> nodeNumbers((int)maxX1, (int)maxX2, (int)maxX3, -1);
-
-   maxX1 -= 2;
-   maxX2 -= 2;
-   maxX3 -= 2;
-
-   LBMReal f[D3Q27System::ENDF+1];
-   LBMReal vx1,vx2,vx3,rho;
-
-   //D3Q27BoundaryConditionPtr bcPtr;
-
-   int nr = (int)nodes.size();
-
-   for (int ix3 = minX3; ix3 <= maxX3; ix3++)
-   {
-      for (int ix2 = minX2; ix2 <= maxX2; ix2++)
-      {
-         for (int ix1 = minX1; ix1 <= maxX1; ix1++)
-         {
-            if (!bcArray->isUndefined(ix1, ix2, ix3) && !bcArray->isSolid(ix1, ix2, ix3))
-            {
-               int index = 0;
-               nodeNumbers(ix1, ix2, ix3) = nr++;
-               nodes.push_back(makeUbTuple(float(val<1>(org) - val<1>(nodeOffset) + ix1*dx),
-                  float(val<2>(org) - val<2>(nodeOffset) + ix2*dx),
-                  float(val<3>(org) - val<3>(nodeOffset) + ix3*dx)));
-
-               data[index++].push_back(level);
-
-               distributions->getDistribution(f, ix1, ix2, ix3);
-               calcMacros(f, rho, vx1, vx2, vx3);
-
-               data[index++].push_back(rho);
-
-               if ((options&Density) == Density)
-               {
-                  data[index++].push_back((*ar)(0, ix1, ix2, ix3));
-               }
-
-               if ((options&Velocity) == Velocity)
-               {
-                  data[index++].push_back((*av)(Vx, ix1, ix2, ix3));
-                  data[index++].push_back((*av)(Vy, ix1, ix2, ix3));
-                  data[index++].push_back((*av)(Vz, ix1, ix2, ix3));
-               }
-
-               if ((options&Fluctuations) == Fluctuations)
-               {
-                  data[index++].push_back((*af)(Vxx, ix1, ix2, ix3));
-                  data[index++].push_back((*af)(Vyy, ix1, ix2, ix3));
-                  data[index++].push_back((*af)(Vzz, ix1, ix2, ix3));
-                  data[index++].push_back((*af)(Vxy, ix1, ix2, ix3));
-                  data[index++].push_back((*af)(Vxz, ix1, ix2, ix3));
-                  data[index++].push_back((*af)(Vyz, ix1, ix2, ix3));
-               }
-
-               if ((options&Triplecorrelations) == Triplecorrelations)
-               {
-                  data[index++].push_back((*at)(Vxxx, ix1, ix2, ix3));
-                  data[index++].push_back((*at)(Vxxy, ix1, ix2, ix3));
-                  data[index++].push_back((*at)(Vxxz, ix1, ix2, ix3));
-                  data[index++].push_back((*at)(Vyyy, ix1, ix2, ix3));
-                  data[index++].push_back((*at)(Vyyx, ix1, ix2, ix3));
-                  data[index++].push_back((*at)(Vyyz, ix1, ix2, ix3));
-                  data[index++].push_back((*at)(Vzzz, ix1, ix2, ix3));
-                  data[index++].push_back((*at)(Vzzx, ix1, ix2, ix3));
-                  data[index++].push_back((*at)(Vzzy, ix1, ix2, ix3));
-                  data[index++].push_back((*at)(Vxyz, ix1, ix2, ix3));
-               }
-            }
-         }
-      }
-   }
-
-   maxX1 -= 1;
-   maxX2 -= 1;
-   maxX3 -= 1;
-
-   //cell vector erstellen
-   for (int ix3 = minX3; ix3 <= maxX3; ix3++)
-   {
-      for (int ix2 = minX2; ix2 <= maxX2; ix2++)
-      {
-         for (int ix1 = minX1; ix1 <= maxX1; ix1++)
-         {
-            if ((SWB = nodeNumbers(ix1, ix2, ix3)) >= 0
-               && (SEB = nodeNumbers(ix1 + 1, ix2, ix3)) >= 0
-               && (NEB = nodeNumbers(ix1 + 1, ix2 + 1, ix3)) >= 0
-               && (NWB = nodeNumbers(ix1, ix2 + 1, ix3)) >= 0
-               && (SWT = nodeNumbers(ix1, ix2, ix3 + 1)) >= 0
-               && (SET = nodeNumbers(ix1 + 1, ix2, ix3 + 1)) >= 0
-               && (NET = nodeNumbers(ix1 + 1, ix2 + 1, ix3 + 1)) >= 0
-               && (NWT = nodeNumbers(ix1, ix2 + 1, ix3 + 1)) >= 0)
-            {
-               cells.push_back(makeUbTuple(SWB, SEB, NEB, NWB, SWT, SET, NET, NWT));
-            }
-         }
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void TimeAveragedValuesCoProcessor::calculateAverageValues(double timeSteps)
-{
-   for (int level = minInitLevel; level <= maxInitLevel; level++)
-   {
-      int i;
-      //#ifdef _OPENMP
-      //   #pragma omp parallel for 
-      //#endif
-            //BOOST_FOREACH(Block3DPtr block, blockVector[level])
-      for (i = 0; i < blockVector[level].size(); i++)
-      {
-         Block3DPtr block = blockVector[level][i];
-         if (block)
-         {
-            LBMKernelPtr kernel = block->getKernel();
-            BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
-            DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();
-            AverageValuesArray3DPtr ar = kernel->getDataSet()->getAverageDencity();
-            AverageValuesArray3DPtr av = kernel->getDataSet()->getAverageVelocity();
-            AverageValuesArray3DPtr af = kernel->getDataSet()->getAverageFluctuations();
-            AverageValuesArray3DPtr at = kernel->getDataSet()->getAverageTriplecorrelations();
-
-            int minX1 = iMinC;
-            int minX2 = iMinC;
-            int minX3 = iMinC;
-
-            int maxX1 = int(distributions->getNX1());
-            int maxX2 = int(distributions->getNX2());
-            int maxX3 = int(distributions->getNX3());
-
-            maxX1 -= 2;
-            maxX2 -= 2;
-            maxX3 -= 2;
-
-            LBMReal rho, ux, uy, uz, uxx, uzz, uyy, uxy, uxz, uyz;
-
-            for (int ix3 = minX3; ix3 <= maxX3; ix3++)
-            {
-               for (int ix2 = minX2; ix2 <= maxX2; ix2++)
-               {
-                  for (int ix1 = minX1; ix1 <= maxX1; ix1++)
-                  {
-                     if (!bcArray->isUndefined(ix1, ix2, ix3) && !bcArray->isSolid(ix1, ix2, ix3))
-                     {
-                        //////////////////////////////////////////////////////////////////////////
-                        //compute average values
-                        //////////////////////////////////////////////////////////////////////////
-
-                        //mean density
-                        if ((options&Density) == Density)
-                        {
-                           rho = (*ar)(0, ix1, ix2, ix3) / timeSteps;
-                           
-                           (*ar)(0, ix1, ix2, ix3) = rho; 
-                        }
-
-                        //mean velocity
-                        if ((options&Velocity) == Velocity)
-                        {
-                           ux = (*av)(Vx, ix1, ix2, ix3) / timeSteps;
-                           uy = (*av)(Vy, ix1, ix2, ix3) / timeSteps;
-                           uz = (*av)(Vz, ix1, ix2, ix3) / timeSteps;
-
-                           (*av)(Vx, ix1, ix2, ix3) = ux;
-                           (*av)(Vy, ix1, ix2, ix3) = uy;
-                           (*av)(Vz, ix1, ix2, ix3) = uz;
-                        }
-
-                        //fluctuations
-                        if ((options&Fluctuations) == Fluctuations)
-                        {
-                           uxx = (*af)(Vxx, ix1, ix2, ix3) / timeSteps;
-                           uyy = (*af)(Vyy, ix1, ix2, ix3) / timeSteps;
-                           uzz = (*af)(Vzz, ix1, ix2, ix3) / timeSteps;
-                           uxy = (*af)(Vxy, ix1, ix2, ix3) / timeSteps;
-                           uxz = (*af)(Vxz, ix1, ix2, ix3) / timeSteps;
-                           uyz = (*af)(Vyz, ix1, ix2, ix3) / timeSteps;
-
-                           (*af)(Vxx, ix1, ix2, ix3) = uxx - ux*ux;
-                           (*af)(Vyy, ix1, ix2, ix3) = uyy - uy*uy;
-                           (*af)(Vzz, ix1, ix2, ix3) = uzz - uz*uz;
-                           (*af)(Vxy, ix1, ix2, ix3) = uxy - ux*uy;
-                           (*af)(Vxz, ix1, ix2, ix3) = uxz - ux*uz;
-                           (*af)(Vyz, ix1, ix2, ix3) = uyz - uy*uz;
-                        }
-
-                        if ((options&Triplecorrelations) == Triplecorrelations)
-                        {
-                           //triple-correlations
-                           (*at)(Vxxx, ix1, ix2, ix3) = (*at)(Vxxx, ix1, ix2, ix3) / timeSteps - 3.0 * uxx*ux + 2.0 * ux*ux*ux;
-                           (*at)(Vxxy, ix1, ix2, ix3) = (*at)(Vxxy, ix1, ix2, ix3) / timeSteps - 2.0 * uxy*ux - uxx*uy + 2.0 * ux*ux*uy;
-                           (*at)(Vxxz, ix1, ix2, ix3) = (*at)(Vxxz, ix1, ix2, ix3) / timeSteps - 2.0 * uxz*ux - uxx*uz + 2.0 * ux*ux*uz;
-                           (*at)(Vyyy, ix1, ix2, ix3) = (*at)(Vyyy, ix1, ix2, ix3) / timeSteps - 3.0 * uyy*uy + 2.0 * uy*uy*uy;
-                           (*at)(Vyyx, ix1, ix2, ix3) = (*at)(Vyyx, ix1, ix2, ix3) / timeSteps - 2.0 * uxy*uy - uyy*ux + 2.0 * uy*uy*ux;
-                           (*at)(Vyyz, ix1, ix2, ix3) = (*at)(Vyyz, ix1, ix2, ix3) / timeSteps - 2.0 * uyz*uy - uyy*uz + 2.0 * uy*uy*uz;
-                           (*at)(Vzzz, ix1, ix2, ix3) = (*at)(Vzzz, ix1, ix2, ix3) / timeSteps - 3.0 * uzz*uz + 2.0 * uz*uz*uz;
-                           (*at)(Vzzx, ix1, ix2, ix3) = (*at)(Vzzx, ix1, ix2, ix3) / timeSteps - 2.0 * uxz*uz - uzz*ux + 2.0 * uz*uz*ux;
-                           (*at)(Vzzy, ix1, ix2, ix3) = (*at)(Vzzy, ix1, ix2, ix3) / timeSteps - 2.0 * uyz*uz - uzz*uy + 2.0 * uz*uz*uy;
-                           (*at)(Vxyz, ix1, ix2, ix3) = (*at)(Vxyz, ix1, ix2, ix3) / timeSteps - uxy*uz - uxz*uy - uyz*ux + 2.0 * ux*uy*uz;
-                        }
-                        //////////////////////////////////////////////////////////////////////////
-                     }
-                  }
-               }
-            }
-         }
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void TimeAveragedValuesCoProcessor::calculateSubtotal(double step)
-{
-   if (scheduler->isDue(step))
-   {
-
-      //DEBUG/////////////////////
-      //UBLOG(logINFO, "calculateSubtotal::step = " << step);
-      ////////////////////////////
-
-      LBMReal f[27];
-
-#ifdef _OPENMP
-#pragma omp parallel private (f)
-#endif
-      {
-         for (int level = minInitLevel; level <= maxInitLevel; level++)
-         {
-            int i;
-#ifdef _OPENMP
-#pragma omp for schedule(dynamic)
-#endif
-            //BOOST_FOREACH(Block3DPtr block, blockVector[level])
-            for (i = 0; i < blockVector[level].size(); i++)
-            {
-               Block3DPtr block = blockVector[level][i];
-               if (block)
-               {
-                  LBMKernelPtr kernel = block->getKernel();
-                  BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
-                  DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();
-                  AverageValuesArray3DPtr ar = kernel->getDataSet()->getAverageDencity();
-                  AverageValuesArray3DPtr av = kernel->getDataSet()->getAverageVelocity();
-                  AverageValuesArray3DPtr af = kernel->getDataSet()->getAverageFluctuations();
-                  AverageValuesArray3DPtr at = kernel->getDataSet()->getAverageTriplecorrelations();
-
-                  int minX1 = iMinC;
-                  int minX2 = iMinC;
-                  int minX3 = iMinC;
-
-                  int maxX1 = int(distributions->getNX1());
-                  int maxX2 = int(distributions->getNX2());
-                  int maxX3 = int(distributions->getNX3());
-
-                  maxX1 -= 2;
-                  maxX2 -= 2;
-                  maxX3 -= 2;
-
-                  for (int ix3 = minX3; ix3 <= maxX3; ix3++)
-                  {
-                     for (int ix2 = minX2; ix2 <= maxX2; ix2++)
-                     {
-                        for (int ix1 = minX1; ix1 <= maxX1; ix1++)
-                        {
-                           if (!bcArray->isUndefined(ix1, ix2, ix3) && !bcArray->isSolid(ix1, ix2, ix3))
-                           {
-                              //////////////////////////////////////////////////////////////////////////
-                              //read distribution
-                              ////////////////////////////////////////////////////////////////////////////
-                              distributions->getDistribution(f, ix1, ix2, ix3);
-                              //////////////////////////////////////////////////////////////////////////
-                              //compute velocity
-                              //////////////////////////////////////////////////////////////////////////
-                              LBMReal vx, vy, vz, rho;
-                              calcMacros(f, rho, vx, vy, vz);
-                              //double press = D3Q27System::calcPress(f, rho, vx, vy, vz);
-
-                              //////////////////////////////////////////////////////////////////////////
-                              //compute subtotals
-                              //////////////////////////////////////////////////////////////////////////
-
-                              //mean density
-                              if ((options&Density) == Density)
-                              {
-                                 (*ar)(0, ix1, ix2, ix3) = (*ar)(0, ix1, ix2, ix3) + rho;
-                              }
-
-                              //mean velocity
-                              if ((options&Velocity) == Velocity)
-                              {
-                                 (*av)(Vx, ix1, ix2, ix3) = (*av)(Vx, ix1, ix2, ix3) + vx;
-                                 (*av)(Vy, ix1, ix2, ix3) = (*av)(Vy, ix1, ix2, ix3) + vy;
-                                 (*av)(Vz, ix1, ix2, ix3) = (*av)(Vz, ix1, ix2, ix3) + vz;
-                              }
-
-                              //fluctuations
-                              if ((options&Fluctuations) == Fluctuations)
-                              {
-                                 (*af)(Vxx, ix1, ix2, ix3) = (*af)(Vxx, ix1, ix2, ix3) + vx*vx;
-                                 (*af)(Vyy, ix1, ix2, ix3) = (*af)(Vyy, ix1, ix2, ix3) + vy*vy;
-                                 (*af)(Vzz, ix1, ix2, ix3) = (*af)(Vzz, ix1, ix2, ix3) + vz*vz;
-                                 (*af)(Vxy, ix1, ix2, ix3) = (*af)(Vxy, ix1, ix2, ix3) + vx*vy;
-                                 (*af)(Vxz, ix1, ix2, ix3) = (*af)(Vxz, ix1, ix2, ix3) + vx*vz;
-                                 (*af)(Vyz, ix1, ix2, ix3) = (*af)(Vyz, ix1, ix2, ix3) + vy*vz;
-                              }
-
-                              //triple-correlations
-                              if ((options&Triplecorrelations) == Triplecorrelations)
-                              {
-                                 (*at)(Vxxx, ix1, ix2, ix3) = (*at)(Vxxx, ix1, ix2, ix3) + vx*vx*vx;
-                                 (*at)(Vxxy, ix1, ix2, ix3) = (*at)(Vxxy, ix1, ix2, ix3) + vx*vx*vy;
-                                 (*at)(Vxxz, ix1, ix2, ix3) = (*at)(Vxxz, ix1, ix2, ix3) + vx*vx*vz;
-                                 (*at)(Vyyy, ix1, ix2, ix3) = (*at)(Vyyy, ix1, ix2, ix3) + vy*vy*vy;
-                                 (*at)(Vyyx, ix1, ix2, ix3) = (*at)(Vyyx, ix1, ix2, ix3) + vy*vy*vx;
-                                 (*at)(Vyyz, ix1, ix2, ix3) = (*at)(Vyyz, ix1, ix2, ix3) + vy*vy*vz;
-                                 (*at)(Vzzz, ix1, ix2, ix3) = (*at)(Vzzz, ix1, ix2, ix3) + vz*vz*vz;
-                                 (*at)(Vzzx, ix1, ix2, ix3) = (*at)(Vzzx, ix1, ix2, ix3) + vz*vz*vx;
-                                 (*at)(Vzzy, ix1, ix2, ix3) = (*at)(Vzzy, ix1, ix2, ix3) + vz*vz*vy;
-                                 (*at)(Vxyz, ix1, ix2, ix3) = (*at)(Vxyz, ix1, ix2, ix3) + vx*vy*vz;
-                              }
-                              //////////////////////////////////////////////////////////////////////////
-                           }
-                        }
-                     }
-                  }
-               }
-            }
-         }
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void TimeAveragedValuesCoProcessor::planarAverage(double step)
-{
-   std::ofstream ostr;
-
-   if (root)
-   {
-      int istep = int(step);
-      string fname = path + "/tav/" + "tav" + UbSystem::toString(istep) + ".csv";
-
-
-      ostr.open(fname.c_str(), std::ios_base::out);
-      if (!ostr)
-      {
-         ostr.clear();
-         string path = UbSystem::getPathFromString(fname);
-         if (path.size() > 0) { UbSystem::makeDirectory(path); ostr.open(fname.c_str(), std::ios_base::out); }
-         if (!ostr) throw UbException(UB_EXARGS, "couldn't open file " + fname);
-      }
-      ostr << "z;Vx;Vy;Vz;Vxx;Vyy;Vzz;Vxy;Vxz;Vyz;Vxxx;Vxxy;Vxxz;Vyyy;Vyyx;Vyyz;Vzzz;Vzzx;Vzzy;Vxyz\n";
-   }
-
-   int size = (int)levels.size();
-   int sizeOfLevelCoords = (int)levelCoords.size();
-   
-   if (2 * size != sizeOfLevelCoords)
-   {
-      UB_THROW(UbException(UB_EXARGS, "Number of levels coordinates don't match number of levels!"));
-   }
-   
-   int k = 0;
-
-   for (int i = 0; i < size; i++)
-   {
-      int level = levels[i];
-      double dx = grid->getDeltaX(level);
-      double start = levelCoords[k];
-      double stop  = levelCoords[k + 1];
-
-      for (double j = start; j <stop; j += dx)
-      {
-         IntegrateValuesHelper intValHelp(grid, comm,
-            bounds[0], bounds[1], j,
-            bounds[3], bounds[4], j + dx, level);
-
-         intValHelp.calculateAV2();
-
-         if (root)
-         {
-            double numberOfFluidsNodes = intValHelp.getNumberOfFluidsNodes();
-            if (numberOfFluidsNodes > 0)
-            {
-               ostr << j + 0.5*dx;
-
-               ////mean density
-               //if ((options&Density) == Density)
-               //{
-               //   double rho = intValHelp.getARho() / numberOfFluidsNodes;
-               //}
-
-               //mean velocity
-               if ((options&Velocity) == Velocity)
-               {
-                  double Vx = intValHelp.getAVx() / numberOfFluidsNodes;
-                  double Vy = intValHelp.getAVy() / numberOfFluidsNodes;
-                  double Vz = intValHelp.getAVz() / numberOfFluidsNodes;
-                  ostr << ";" << Vx << ";" << Vy << ";" << Vz;
-               }
-               //fluctuations
-               if ((options&Fluctuations) == Fluctuations)
-               {
-                  double Vxx = intValHelp.getAVxx() / numberOfFluidsNodes;
-                  double Vyy = intValHelp.getAVyy() / numberOfFluidsNodes;
-                  double Vzz = intValHelp.getAVzz() / numberOfFluidsNodes;
-                  double Vxy = intValHelp.getAVxy() / numberOfFluidsNodes;
-                  double Vxz = intValHelp.getAVxz() / numberOfFluidsNodes;
-                  double Vyz = intValHelp.getAVyz() / numberOfFluidsNodes;
-                  ostr << ";" << Vxx << ";" << Vyy << ";" << Vzz << ";" << Vxy << ";" << Vxz << ";" << Vyz;
-               }
-               //triple-correlations
-               if ((options&Triplecorrelations) == Triplecorrelations)
-               {
-                  double Vxxx = intValHelp.getAVxxx() / numberOfFluidsNodes;
-                  double Vxxy = intValHelp.getAVxxy() / numberOfFluidsNodes;
-                  double Vxxz = intValHelp.getAVxxz() / numberOfFluidsNodes;
-                  double Vyyy = intValHelp.getAVyyy() / numberOfFluidsNodes;
-                  double Vyyx = intValHelp.getAVyyx() / numberOfFluidsNodes;
-                  double Vyyz = intValHelp.getAVyyz() / numberOfFluidsNodes;
-                  double Vzzz = intValHelp.getAVzzz() / numberOfFluidsNodes;
-                  double Vzzx = intValHelp.getAVzzx() / numberOfFluidsNodes;
-                  double Vzzy = intValHelp.getAVzzy() / numberOfFluidsNodes;
-                  double Vxyz = intValHelp.getAVxyz() / numberOfFluidsNodes;
-                  ostr << ";" << Vxxx << ";" << Vxxy << ";" << Vxxz << ";" << Vyyy << ";" << Vyyx << ";" << Vyyz << ";" << Vzzz << ";" << Vzzx << ";" << Vzzy << ";" << Vxyz;
-               }
-               ostr << "\n";
-            }
-         }
-      }
-      k += 2;
-   }
-
-   if (root)
-   {
-      ostr.close();
-      UBLOG(logINFO, "TimeAveragedValuesCoProcessor::planarAverage() step: " << (int)step);
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void TimeAveragedValuesCoProcessor::reset()
-{
-   for (int level = minInitLevel; level <= maxInitLevel; level++)
-   {
-      BOOST_FOREACH(Block3DPtr block, blockVector[level])
-      {
-         if (block)
-         {
-            block->getKernel()->getDataSet()->getAverageVelocity()->reset(0.0);
-            block->getKernel()->getDataSet()->getAverageFluctuations()->reset(0.0);
-            block->getKernel()->getDataSet()->getAverageTriplecorrelations()->reset(0.0);
-         }
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void TimeAveragedValuesCoProcessor::setWithGhostLayer(bool val)
-{
-   withGhostLayer = val;
-
-   if (withGhostLayer)
-   {
-      iMinC = 0;
-   } 
-   else
-   {
-      iMinC = 1;
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-bool TimeAveragedValuesCoProcessor::getWithGhostLayer()
-{
-   return withGhostLayer;
-}
-
+#include "TimeAveragedValuesCoProcessor.h"
+
+
+#include "LBMKernel.h"
+#include "BCProcessor.h"
+
+#include "basics/writer/WbWriterVtkXmlASCII.h"
+#include "DataSet3D.h"
+#include "Grid3D.h"
+#include "Block3D.h"
+#include "Communicator.h"
+#include "UbScheduler.h"
+#include "IntegrateValuesHelper.h"
+#include "BCArray3D.h"
+
+
+TimeAveragedValuesCoProcessor::TimeAveragedValuesCoProcessor()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+TimeAveragedValuesCoProcessor::TimeAveragedValuesCoProcessor(Grid3DPtr grid, const std::string& path, WbWriter* const writer,
+   UbSchedulerPtr s, CommunicatorPtr comm, int options)
+   : CoProcessor(grid, s),
+   path(path),
+   writer(writer),
+   comm(comm),
+   options(options)
+{
+   init(s);
+   planarAveraging = false;
+   timeAveraging = true;
+}
+//////////////////////////////////////////////////////////////////////////
+TimeAveragedValuesCoProcessor::TimeAveragedValuesCoProcessor(Grid3DPtr grid, const std::string& path, WbWriter* const writer,
+   UbSchedulerPtr s, CommunicatorPtr comm, int options,
+   std::vector<int> levels, std::vector<double>& levelCoords, std::vector<double>& bounds, bool timeAveraging)
+   : CoProcessor(grid, s),
+   path(path),
+   writer(writer),
+   comm(comm),
+   options(options),
+   levels(levels),
+   levelCoords(levelCoords),
+   bounds(bounds),
+   timeAveraging(timeAveraging)
+{
+   init(s);
+   planarAveraging = true;
+}
+//////////////////////////////////////////////////////////////////////////
+void TimeAveragedValuesCoProcessor::init(UbSchedulerPtr s)
+{
+   root = comm->isRoot();
+   gridRank = grid->getRank();
+   minInitLevel = this->grid->getCoarsestInitializedLevel();
+   maxInitLevel = this->grid->getFinestInitializedLevel();
+
+   blockVector.resize(maxInitLevel + 1);
+
+   for (int level = minInitLevel; level <= maxInitLevel; level++)
+   {
+      grid->getBlocks(level, gridRank, true, blockVector[level]);
+
+      if (blockVector[level].size() > 0)
+         compressible = blockVector[level][0]->getKernel()->getCompressible();
+
+      double begin = s->getMinBegin();
+      double gridTimeStep = grid->getTimeStep();
+
+      if (gridTimeStep == begin || gridTimeStep == 0)
+      {
+         for(Block3DPtr block : blockVector[level])
+         {
+            UbTupleInt3 nx = grid->getBlockNX();
+            
+            if ((options&Density) == Density)
+            {
+               AverageValuesArray3DPtr ar = AverageValuesArray3DPtr(new AverageValuesArray3D(1, val<1>(nx) + 1, val<2>(nx) + 1, val<3>(nx) + 1, 0.0));
+               block->getKernel()->getDataSet()->setAverageDencity(ar);
+            }
+
+            if ((options&Velocity) == Velocity)
+            {
+               AverageValuesArray3DPtr av = AverageValuesArray3DPtr(new AverageValuesArray3D(3, val<1>(nx) + 1, val<2>(nx) + 1, val<3>(nx) + 1, 0.0));
+               block->getKernel()->getDataSet()->setAverageVelocity(av);
+            }
+
+            if ((options&Fluctuations) == Fluctuations)
+            {
+               AverageValuesArray3DPtr af = AverageValuesArray3DPtr(new AverageValuesArray3D(6, val<1>(nx) + 1, val<2>(nx) + 1, val<3>(nx) + 1, 0.0));
+               block->getKernel()->getDataSet()->setAverageFluctuations(af);
+            }
+
+            if ((options&Triplecorrelations) == Triplecorrelations)
+            {
+               AverageValuesArray3DPtr at = AverageValuesArray3DPtr(new AverageValuesArray3D(10, val<1>(nx) + 1, val<2>(nx) + 1, val<3>(nx) + 1, 0.0));
+               block->getKernel()->getDataSet()->setAverageTriplecorrelations(at);
+            }
+         }
+      }
+   }
+
+   //breakStep = scheduler->getMaxEnd() - scheduler->getMinBegin()+1;
+   //UBLOG(logINFO, "breakSteps = " << breakStep);
+   //breakStep = breakStep * (double)(1 << maxInitLevel);
+   //breakStep = scheduler->getMaxEnd()*(double)(1 << maxInitLevel);
+   //UBLOG(logINFO, "breakSteps = " << breakStep);
+
+   withGhostLayer = false;
+   iMinC = 1;
+
+   lcounter = 0;
+
+   levelFactor = 1 << maxInitLevel;
+   maxStep = scheduler->getMaxEnd();
+   numberOfFineSteps = int(maxStep - scheduler->getMinBegin()) * levelFactor;
+   numberOfSteps = int(maxStep - scheduler->getMinBegin());
+
+   //function pointer
+   using namespace D3Q27System;
+   calcMacros = NULL;
+   if (compressible)
+   {
+      calcMacros = &calcCompMacroscopicValues;
+   }
+   else
+   {
+      calcMacros = &calcIncompMacroscopicValues;
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void TimeAveragedValuesCoProcessor::process(double step)
+{
+   calculateSubtotal(step);
+
+   if (step == maxStep)
+   {
+      //DEBUG/////////////////////
+      //UBLOG(logINFO, "process::step = " << step << ", maxStep = " << maxStep << ", levelFactor = " << levelFactor << ", numberOfFineSteps = " << numberOfFineSteps);
+      ////////////////////////////
+
+      //calculateAverageValues((double)numberOfFineSteps);
+      calculateAverageValues((double)numberOfSteps);
+      
+      if (timeAveraging)
+      {
+         collectData(step);
+      }
+      
+      if (planarAveraging)
+      {
+         planarAverage(step);
+      }
+   }
+
+   UBLOG(logDEBUG3, "AverageValuesCoProcessor::update:" << step);
+}
+//////////////////////////////////////////////////////////////////////////
+void TimeAveragedValuesCoProcessor::collectData(double step)
+{
+   int istep = int(step);
+
+   for (int level = minInitLevel; level <= maxInitLevel; level++)
+   {
+      for(Block3DPtr block : blockVector[level])
+      {
+         if (block)
+         {
+            addData(block);
+         }
+      }
+   }
+
+   std::string pfilePath, partPath, subfolder, cfilePath;
+   subfolder = "tav" + UbSystem::toString(istep);
+   pfilePath = path + "/tav/" + subfolder;
+   partPath = pfilePath + "/tav" + UbSystem::toString(gridRank) + "_" + UbSystem::toString(istep);
+
+   std::string partName = writer->writeOctsWithNodeData(partPath, nodes, cells, datanames, data);
+   size_t found = partName.find_last_of("/");
+   std::string piece = partName.substr(found + 1);
+   piece = subfolder + "/" + piece;
+
+   std::vector<std::string> cellDataNames;
+   std::vector<std::string> pieces = comm->gather(piece);
+   if (root)
+   {
+      std::string pname = WbWriterVtkXmlASCII::getInstance()->writeParallelFile(pfilePath, pieces, datanames, cellDataNames);
+      UBLOG(logINFO, "TimeAveragedValuesCoProcessor::collectData() step: " << istep);
+   }
+
+   clearData();
+}
+//////////////////////////////////////////////////////////////////////////
+void TimeAveragedValuesCoProcessor::clearData()
+{
+   nodes.clear();
+   cells.clear();
+   datanames.clear();
+   data.clear();
+}
+//////////////////////////////////////////////////////////////////////////
+void TimeAveragedValuesCoProcessor::addData(const Block3DPtr block)
+{
+   UbTupleDouble3 org = grid->getBlockWorldCoordinates(block);
+   UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
+   UbTupleDouble3 nodeOffset = grid->getNodeOffset(block);
+   double         dx = grid->getDeltaX(block);
+   int            level = block->getLevel();      
+
+   //Diese Daten werden geschrieben:
+   datanames.resize(0);
+
+   datanames.push_back("level");
+   datanames.push_back("Rho");
+
+   if ((options&Density) == Density)
+   {
+      datanames.push_back("taRho");
+   }
+
+   if ((options&Velocity) == Velocity)
+   {
+      datanames.push_back("taVx");
+      datanames.push_back("taVy");
+      datanames.push_back("taVz");
+   }
+
+   if ((options&Fluctuations) == Fluctuations)
+   {
+      datanames.push_back("taVxx");
+      datanames.push_back("taVyy");
+      datanames.push_back("taVzz");
+      datanames.push_back("taVxy");
+      datanames.push_back("taVxz");
+      datanames.push_back("taVyz");
+   }
+
+   if ((options&Triplecorrelations) == Triplecorrelations)
+   {
+      datanames.push_back("taVxxx");
+      datanames.push_back("taVxxy");
+      datanames.push_back("taVxxz");
+      datanames.push_back("taVyyy");
+      datanames.push_back("taVyyx");
+      datanames.push_back("taVyyz");
+      datanames.push_back("taVzzz");
+      datanames.push_back("taVzzx");
+      datanames.push_back("taVzzy");
+      datanames.push_back("taVxyz");
+   }
+
+
+   //datanames.push_back("AvP");
+   //datanames.push_back("AvPrms");
+
+
+   data.resize(datanames.size());
+
+   ILBMKernelPtr kernel = block->getKernel();
+   BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
+   DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();
+   AverageValuesArray3DPtr ar = kernel->getDataSet()->getAverageDencity();
+   AverageValuesArray3DPtr av = kernel->getDataSet()->getAverageVelocity();
+   AverageValuesArray3DPtr af = kernel->getDataSet()->getAverageFluctuations();
+   AverageValuesArray3DPtr at = kernel->getDataSet()->getAverageTriplecorrelations();
+   //int ghostLayerWidth = kernel->getGhostLayerWidth();
+
+   //knotennummerierung faengt immer bei 0 an!
+   int SWB, SEB, NEB, NWB, SWT, SET, NET, NWT;
+
+   int minX1 = iMinC;
+   int minX2 = iMinC;
+   int minX3 = iMinC;
+
+   int maxX1 = int(distributions->getNX1());
+   int maxX2 = int(distributions->getNX2());
+   int maxX3 = int(distributions->getNX3());
+
+   //nummern vergeben und node vector erstellen + daten sammeln
+   CbArray3D<int> nodeNumbers((int)maxX1, (int)maxX2, (int)maxX3, -1);
+
+   maxX1 -= 2;
+   maxX2 -= 2;
+   maxX3 -= 2;
+
+   LBMReal f[D3Q27System::ENDF + 1];
+   LBMReal vx1, vx2, vx3, rho;
+
+   //D3Q27BoundaryConditionPtr bcPtr;
+
+   int nr = (int)nodes.size();
+
+   for (int ix3 = minX3; ix3 <= maxX3; ix3++)
+   {
+      for (int ix2 = minX2; ix2 <= maxX2; ix2++)
+      {
+         for (int ix1 = minX1; ix1 <= maxX1; ix1++)
+         {
+            if (!bcArray->isUndefined(ix1, ix2, ix3) && !bcArray->isSolid(ix1, ix2, ix3))
+            {
+               int index = 0;
+               nodeNumbers(ix1, ix2, ix3) = nr++;
+               nodes.push_back(makeUbTuple(float(val<1>(org) - val<1>(nodeOffset) + ix1*dx),
+                  float(val<2>(org) - val<2>(nodeOffset) + ix2*dx),
+                  float(val<3>(org) - val<3>(nodeOffset) + ix3*dx)));
+
+               data[index++].push_back(level);          
+
+                distributions->getDistribution(f, ix1, ix2, ix3);
+               calcMacros(f, rho, vx1, vx2, vx3);
+
+               data[index++].push_back(rho);
+
+
+
+               if ((options&Density) == Density)
+               {
+                  data[index++].push_back((*ar)(0, ix1, ix2, ix3));
+               }
+
+               if ((options&Velocity) == Velocity)
+               {
+                  data[index++].push_back((*av)(Vx, ix1, ix2, ix3));
+                  data[index++].push_back((*av)(Vy, ix1, ix2, ix3));
+                  data[index++].push_back((*av)(Vz, ix1, ix2, ix3));
+               }
+
+               if ((options&Fluctuations) == Fluctuations)
+               {
+                  data[index++].push_back((*af)(Vxx, ix1, ix2, ix3));
+                  data[index++].push_back((*af)(Vyy, ix1, ix2, ix3));
+                  data[index++].push_back((*af)(Vzz, ix1, ix2, ix3));
+                  data[index++].push_back((*af)(Vxy, ix1, ix2, ix3));
+                  data[index++].push_back((*af)(Vxz, ix1, ix2, ix3));
+                  data[index++].push_back((*af)(Vyz, ix1, ix2, ix3));
+               }
+
+               if ((options&Triplecorrelations) == Triplecorrelations)
+               {
+                  data[index++].push_back((*at)(Vxxx, ix1, ix2, ix3));
+                  data[index++].push_back((*at)(Vxxy, ix1, ix2, ix3));
+                  data[index++].push_back((*at)(Vxxz, ix1, ix2, ix3));
+                  data[index++].push_back((*at)(Vyyy, ix1, ix2, ix3));
+                  data[index++].push_back((*at)(Vyyx, ix1, ix2, ix3));
+                  data[index++].push_back((*at)(Vyyz, ix1, ix2, ix3));
+                  data[index++].push_back((*at)(Vzzz, ix1, ix2, ix3));
+                  data[index++].push_back((*at)(Vzzx, ix1, ix2, ix3));
+                  data[index++].push_back((*at)(Vzzy, ix1, ix2, ix3));
+                  data[index++].push_back((*at)(Vxyz, ix1, ix2, ix3));
+               }
+            }
+         }
+      }
+   }
+
+   maxX1 -= 1;
+   maxX2 -= 1;
+   maxX3 -= 1;
+
+   //cell vector erstellen
+   for (int ix3 = minX3; ix3 <= maxX3; ix3++)
+   {
+      for (int ix2 = minX2; ix2 <= maxX2; ix2++)
+      {
+         for (int ix1 = minX1; ix1 <= maxX1; ix1++)
+         {
+            if ((SWB = nodeNumbers(ix1, ix2, ix3)) >= 0
+               && (SEB = nodeNumbers(ix1 + 1, ix2, ix3)) >= 0
+               && (NEB = nodeNumbers(ix1 + 1, ix2 + 1, ix3)) >= 0
+               && (NWB = nodeNumbers(ix1, ix2 + 1, ix3)) >= 0
+               && (SWT = nodeNumbers(ix1, ix2, ix3 + 1)) >= 0
+               && (SET = nodeNumbers(ix1 + 1, ix2, ix3 + 1)) >= 0
+               && (NET = nodeNumbers(ix1 + 1, ix2 + 1, ix3 + 1)) >= 0
+               && (NWT = nodeNumbers(ix1, ix2 + 1, ix3 + 1)) >= 0)
+            {
+               cells.push_back(makeUbTuple(SWB, SEB, NEB, NWB, SWT, SET, NET, NWT));
+            }
+         }
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void TimeAveragedValuesCoProcessor::calculateAverageValues(double timeSteps)
+{
+   for (int level = minInitLevel; level <= maxInitLevel; level++)
+   {
+      int i;
+      //#ifdef _OPENMP
+      //   #pragma omp parallel for 
+      //#endif
+            //for(Block3DPtr block : blockVector[level])
+      for (i = 0; i < blockVector[level].size(); i++)
+      {
+         Block3DPtr block = blockVector[level][i];
+         if (block)
+         {
+            ILBMKernelPtr kernel = block->getKernel();
+            BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
+            DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();
+            AverageValuesArray3DPtr ar = kernel->getDataSet()->getAverageDencity();
+            AverageValuesArray3DPtr av = kernel->getDataSet()->getAverageVelocity();
+            AverageValuesArray3DPtr af = kernel->getDataSet()->getAverageFluctuations();
+            AverageValuesArray3DPtr at = kernel->getDataSet()->getAverageTriplecorrelations();
+
+            int minX1 = iMinC;
+            int minX2 = iMinC;
+            int minX3 = iMinC;
+
+            int maxX1 = int(distributions->getNX1());
+            int maxX2 = int(distributions->getNX2());
+            int maxX3 = int(distributions->getNX3());
+
+            maxX1 -= 2;
+            maxX2 -= 2;
+            maxX3 -= 2;
+
+            LBMReal rho, ux, uy, uz, uxx, uzz, uyy, uxy, uxz, uyz;
+
+            for (int ix3 = minX3; ix3 <= maxX3; ix3++)
+            {
+               for (int ix2 = minX2; ix2 <= maxX2; ix2++)
+               {
+                  for (int ix1 = minX1; ix1 <= maxX1; ix1++)
+                  {
+                     if (!bcArray->isUndefined(ix1, ix2, ix3) && !bcArray->isSolid(ix1, ix2, ix3))
+                     {
+                        //////////////////////////////////////////////////////////////////////////
+                        //compute average values
+                        //////////////////////////////////////////////////////////////////////////
+
+                        //mean density
+                        if ((options&Density) == Density)
+                        {
+                           rho = (*ar)(0, ix1, ix2, ix3) / timeSteps;
+                           
+                           (*ar)(0, ix1, ix2, ix3) = rho; 
+                        }
+
+                        //mean velocity
+                        if ((options&Velocity) == Velocity)
+                        {
+                           ux = (*av)(Vx, ix1, ix2, ix3) / timeSteps;
+                           uy = (*av)(Vy, ix1, ix2, ix3) / timeSteps;
+                           uz = (*av)(Vz, ix1, ix2, ix3) / timeSteps;
+
+                           (*av)(Vx, ix1, ix2, ix3) = ux;
+                           (*av)(Vy, ix1, ix2, ix3) = uy;
+                           (*av)(Vz, ix1, ix2, ix3) = uz;
+                        }
+
+                        //fluctuations
+                        if ((options&Fluctuations) == Fluctuations)
+                        {
+                           uxx = (*af)(Vxx, ix1, ix2, ix3) / timeSteps;
+                           uyy = (*af)(Vyy, ix1, ix2, ix3) / timeSteps;
+                           uzz = (*af)(Vzz, ix1, ix2, ix3) / timeSteps;
+                           uxy = (*af)(Vxy, ix1, ix2, ix3) / timeSteps;
+                           uxz = (*af)(Vxz, ix1, ix2, ix3) / timeSteps;
+                           uyz = (*af)(Vyz, ix1, ix2, ix3) / timeSteps;
+
+                           (*af)(Vxx, ix1, ix2, ix3) = uxx - ux*ux;
+                           (*af)(Vyy, ix1, ix2, ix3) = uyy - uy*uy;
+                           (*af)(Vzz, ix1, ix2, ix3) = uzz - uz*uz;
+                           (*af)(Vxy, ix1, ix2, ix3) = uxy - ux*uy;
+                           (*af)(Vxz, ix1, ix2, ix3) = uxz - ux*uz;
+                           (*af)(Vyz, ix1, ix2, ix3) = uyz - uy*uz;
+                        }
+
+                        if ((options&Triplecorrelations) == Triplecorrelations)
+                        {
+                           //triple-correlations
+                           (*at)(Vxxx, ix1, ix2, ix3) = (*at)(Vxxx, ix1, ix2, ix3) / timeSteps - 3.0 * uxx*ux + 2.0 * ux*ux*ux;
+                           (*at)(Vxxy, ix1, ix2, ix3) = (*at)(Vxxy, ix1, ix2, ix3) / timeSteps - 2.0 * uxy*ux - uxx*uy + 2.0 * ux*ux*uy;
+                           (*at)(Vxxz, ix1, ix2, ix3) = (*at)(Vxxz, ix1, ix2, ix3) / timeSteps - 2.0 * uxz*ux - uxx*uz + 2.0 * ux*ux*uz;
+                           (*at)(Vyyy, ix1, ix2, ix3) = (*at)(Vyyy, ix1, ix2, ix3) / timeSteps - 3.0 * uyy*uy + 2.0 * uy*uy*uy;
+                           (*at)(Vyyx, ix1, ix2, ix3) = (*at)(Vyyx, ix1, ix2, ix3) / timeSteps - 2.0 * uxy*uy - uyy*ux + 2.0 * uy*uy*ux;
+                           (*at)(Vyyz, ix1, ix2, ix3) = (*at)(Vyyz, ix1, ix2, ix3) / timeSteps - 2.0 * uyz*uy - uyy*uz + 2.0 * uy*uy*uz;
+                           (*at)(Vzzz, ix1, ix2, ix3) = (*at)(Vzzz, ix1, ix2, ix3) / timeSteps - 3.0 * uzz*uz + 2.0 * uz*uz*uz;
+                           (*at)(Vzzx, ix1, ix2, ix3) = (*at)(Vzzx, ix1, ix2, ix3) / timeSteps - 2.0 * uxz*uz - uzz*ux + 2.0 * uz*uz*ux;
+                           (*at)(Vzzy, ix1, ix2, ix3) = (*at)(Vzzy, ix1, ix2, ix3) / timeSteps - 2.0 * uyz*uz - uzz*uy + 2.0 * uz*uz*uy;
+                           (*at)(Vxyz, ix1, ix2, ix3) = (*at)(Vxyz, ix1, ix2, ix3) / timeSteps - uxy*uz - uxz*uy - uyz*ux + 2.0 * ux*uy*uz;
+                        }
+                        //////////////////////////////////////////////////////////////////////////
+                     }
+                  }
+               }
+            }
+         }
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void TimeAveragedValuesCoProcessor::calculateSubtotal(double step)
+{
+   if (scheduler->isDue(step))
+   {
+
+      //DEBUG/////////////////////
+      //UBLOG(logINFO, "calculateSubtotal::step = " << step);
+      ////////////////////////////
+
+      LBMReal f[27];
+
+#ifdef _OPENMP
+#pragma omp parallel private (f)
+#endif
+      {
+         for (int level = minInitLevel; level <= maxInitLevel; level++)
+         {
+            int i;
+#ifdef _OPENMP
+#pragma omp for schedule(dynamic)
+#endif
+            //for(Block3DPtr block : blockVector[level])
+            for (i = 0; i < blockVector[level].size(); i++)
+            {
+               Block3DPtr block = blockVector[level][i];
+               if (block)
+               {
+                  ILBMKernelPtr kernel = block->getKernel();
+                  BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
+                  DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();
+                  AverageValuesArray3DPtr ar = kernel->getDataSet()->getAverageDencity();
+                  AverageValuesArray3DPtr av = kernel->getDataSet()->getAverageVelocity();
+                  AverageValuesArray3DPtr af = kernel->getDataSet()->getAverageFluctuations();
+                  AverageValuesArray3DPtr at = kernel->getDataSet()->getAverageTriplecorrelations();
+
+                  int minX1 = iMinC;
+                  int minX2 = iMinC;
+                  int minX3 = iMinC;
+
+                  int maxX1 = int(distributions->getNX1());
+                  int maxX2 = int(distributions->getNX2());
+                  int maxX3 = int(distributions->getNX3());
+
+                  maxX1 -= 2;
+                  maxX2 -= 2;
+                  maxX3 -= 2;
+
+                  for (int ix3 = minX3; ix3 <= maxX3; ix3++)
+                  {
+                     for (int ix2 = minX2; ix2 <= maxX2; ix2++)
+                     {
+                        for (int ix1 = minX1; ix1 <= maxX1; ix1++)
+                        {
+                           if (!bcArray->isUndefined(ix1, ix2, ix3) && !bcArray->isSolid(ix1, ix2, ix3))
+                           {
+                              //////////////////////////////////////////////////////////////////////////
+                              //read distribution
+                              ////////////////////////////////////////////////////////////////////////////
+                              distributions->getDistribution(f, ix1, ix2, ix3);
+                              //////////////////////////////////////////////////////////////////////////
+                              //compute velocity
+                              //////////////////////////////////////////////////////////////////////////
+                              LBMReal vx, vy, vz, rho;
+                              calcMacros(f, rho, vx, vy, vz);
+                              //double press = D3Q27System::calcPress(f, rho, vx, vy, vz);
+
+                              //////////////////////////////////////////////////////////////////////////
+                              //compute subtotals
+                              //////////////////////////////////////////////////////////////////////////
+
+                              //mean density
+                              if ((options&Density) == Density)
+                              {
+                                 (*ar)(0, ix1, ix2, ix3) = (*ar)(0, ix1, ix2, ix3) + rho;
+                              }
+
+                              //mean velocity
+                              if ((options&Velocity) == Velocity)
+                              {
+                                 (*av)(Vx, ix1, ix2, ix3) = (*av)(Vx, ix1, ix2, ix3) + vx;
+                                 (*av)(Vy, ix1, ix2, ix3) = (*av)(Vy, ix1, ix2, ix3) + vy;
+                                 (*av)(Vz, ix1, ix2, ix3) = (*av)(Vz, ix1, ix2, ix3) + vz;
+                              }
+
+                              //fluctuations
+                              if ((options&Fluctuations) == Fluctuations)
+                              {
+                                 (*af)(Vxx, ix1, ix2, ix3) = (*af)(Vxx, ix1, ix2, ix3) + vx*vx;
+                                 (*af)(Vyy, ix1, ix2, ix3) = (*af)(Vyy, ix1, ix2, ix3) + vy*vy;
+                                 (*af)(Vzz, ix1, ix2, ix3) = (*af)(Vzz, ix1, ix2, ix3) + vz*vz;
+                                 (*af)(Vxy, ix1, ix2, ix3) = (*af)(Vxy, ix1, ix2, ix3) + vx*vy;
+                                 (*af)(Vxz, ix1, ix2, ix3) = (*af)(Vxz, ix1, ix2, ix3) + vx*vz;
+                                 (*af)(Vyz, ix1, ix2, ix3) = (*af)(Vyz, ix1, ix2, ix3) + vy*vz;
+                              }
+
+                              //triple-correlations
+                              if ((options&Triplecorrelations) == Triplecorrelations)
+                              {
+                                 (*at)(Vxxx, ix1, ix2, ix3) = (*at)(Vxxx, ix1, ix2, ix3) + vx*vx*vx;
+                                 (*at)(Vxxy, ix1, ix2, ix3) = (*at)(Vxxy, ix1, ix2, ix3) + vx*vx*vy;
+                                 (*at)(Vxxz, ix1, ix2, ix3) = (*at)(Vxxz, ix1, ix2, ix3) + vx*vx*vz;
+                                 (*at)(Vyyy, ix1, ix2, ix3) = (*at)(Vyyy, ix1, ix2, ix3) + vy*vy*vy;
+                                 (*at)(Vyyx, ix1, ix2, ix3) = (*at)(Vyyx, ix1, ix2, ix3) + vy*vy*vx;
+                                 (*at)(Vyyz, ix1, ix2, ix3) = (*at)(Vyyz, ix1, ix2, ix3) + vy*vy*vz;
+                                 (*at)(Vzzz, ix1, ix2, ix3) = (*at)(Vzzz, ix1, ix2, ix3) + vz*vz*vz;
+                                 (*at)(Vzzx, ix1, ix2, ix3) = (*at)(Vzzx, ix1, ix2, ix3) + vz*vz*vx;
+                                 (*at)(Vzzy, ix1, ix2, ix3) = (*at)(Vzzy, ix1, ix2, ix3) + vz*vz*vy;
+                                 (*at)(Vxyz, ix1, ix2, ix3) = (*at)(Vxyz, ix1, ix2, ix3) + vx*vy*vz;
+                              }
+                              //////////////////////////////////////////////////////////////////////////
+                           }
+                        }
+                     }
+                  }
+               }
+            }
+         }
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void TimeAveragedValuesCoProcessor::planarAverage(double step)
+{
+   std::ofstream ostr;
+
+   if (root)
+   {
+      int istep = int(step);
+      std::string fname = path + "/tav/" + "tav" + UbSystem::toString(istep) + ".csv";
+
+
+      ostr.open(fname.c_str(), std::ios_base::out);
+      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 (!ostr) throw UbException(UB_EXARGS, "couldn't open file " + fname);
+      }
+      ostr << "z;Vx;Vy;Vz;Vxx;Vyy;Vzz;Vxy;Vxz;Vyz;Vxxx;Vxxy;Vxxz;Vyyy;Vyyx;Vyyz;Vzzz;Vzzx;Vzzy;Vxyz\n";
+   }
+
+   int size = (int)levels.size();
+   int sizeOfLevelCoords = (int)levelCoords.size();
+   
+   if (2 * size != sizeOfLevelCoords)
+   {
+      UB_THROW(UbException(UB_EXARGS, "Number of levels coordinates don't match number of levels!"));
+   }
+   
+   int k = 0;
+
+   for (int i = 0; i < size; i++)
+   {
+      int level = levels[i];
+      double dx = grid->getDeltaX(level);
+      double start = levelCoords[k];
+      double stop  = levelCoords[k + 1];
+
+      for (double j = start; j <stop; j += dx)
+      {
+         IntegrateValuesHelper intValHelp(grid, comm,
+            bounds[0], bounds[1], j,
+            bounds[3], bounds[4], j + dx, level);
+
+         intValHelp.calculateAV2();
+
+         if (root)
+         {
+            double numberOfFluidsNodes = intValHelp.getNumberOfFluidsNodes();
+            if (numberOfFluidsNodes > 0)
+            {
+               ostr << j + 0.5*dx;
+
+               ////mean density
+               //if ((options&Density) == Density)
+               //{
+               //   double rho = intValHelp.getARho() / numberOfFluidsNodes;
+               //}
+
+               //mean velocity
+               if ((options&Velocity) == Velocity)
+               {
+                  double Vx = intValHelp.getAVx() / numberOfFluidsNodes;
+                  double Vy = intValHelp.getAVy() / numberOfFluidsNodes;
+                  double Vz = intValHelp.getAVz() / numberOfFluidsNodes;
+                  ostr << ";" << Vx << ";" << Vy << ";" << Vz;
+               }
+               //fluctuations
+               if ((options&Fluctuations) == Fluctuations)
+               {
+                  double Vxx = intValHelp.getAVxx() / numberOfFluidsNodes;
+                  double Vyy = intValHelp.getAVyy() / numberOfFluidsNodes;
+                  double Vzz = intValHelp.getAVzz() / numberOfFluidsNodes;
+                  double Vxy = intValHelp.getAVxy() / numberOfFluidsNodes;
+                  double Vxz = intValHelp.getAVxz() / numberOfFluidsNodes;
+                  double Vyz = intValHelp.getAVyz() / numberOfFluidsNodes;
+                  ostr << ";" << Vxx << ";" << Vyy << ";" << Vzz << ";" << Vxy << ";" << Vxz << ";" << Vyz;
+               }
+               //triple-correlations
+               if ((options&Triplecorrelations) == Triplecorrelations)
+               {
+                  double Vxxx = intValHelp.getAVxxx() / numberOfFluidsNodes;
+                  double Vxxy = intValHelp.getAVxxy() / numberOfFluidsNodes;
+                  double Vxxz = intValHelp.getAVxxz() / numberOfFluidsNodes;
+                  double Vyyy = intValHelp.getAVyyy() / numberOfFluidsNodes;
+                  double Vyyx = intValHelp.getAVyyx() / numberOfFluidsNodes;
+                  double Vyyz = intValHelp.getAVyyz() / numberOfFluidsNodes;
+                  double Vzzz = intValHelp.getAVzzz() / numberOfFluidsNodes;
+                  double Vzzx = intValHelp.getAVzzx() / numberOfFluidsNodes;
+                  double Vzzy = intValHelp.getAVzzy() / numberOfFluidsNodes;
+                  double Vxyz = intValHelp.getAVxyz() / numberOfFluidsNodes;
+                  ostr << ";" << Vxxx << ";" << Vxxy << ";" << Vxxz << ";" << Vyyy << ";" << Vyyx << ";" << Vyyz << ";" << Vzzz << ";" << Vzzx << ";" << Vzzy << ";" << Vxyz;
+               }
+               ostr << "\n";
+            }
+         }
+      }
+      k += 2;
+   }
+
+   if (root)
+   {
+      ostr.close();
+      UBLOG(logINFO, "TimeAveragedValuesCoProcessor::planarAverage() step: " << (int)step);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void TimeAveragedValuesCoProcessor::reset()
+{
+   for (int level = minInitLevel; level <= maxInitLevel; level++)
+   {
+      for(Block3DPtr block : blockVector[level])
+      {
+         if (block)
+         {
+            block->getKernel()->getDataSet()->getAverageVelocity()->reset(0.0);
+            block->getKernel()->getDataSet()->getAverageFluctuations()->reset(0.0);
+            block->getKernel()->getDataSet()->getAverageTriplecorrelations()->reset(0.0);
+         }
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void TimeAveragedValuesCoProcessor::setWithGhostLayer(bool val)
+{
+   withGhostLayer = val;
+
+   if (withGhostLayer)
+   {
+      iMinC = 0;
+   } 
+   else
+   {
+      iMinC = 1;
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+bool TimeAveragedValuesCoProcessor::getWithGhostLayer()
+{
+   return withGhostLayer;
+}
+
diff --git a/source/VirtualFluidsCore/CoProcessors/TimeAveragedValuesCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/TimeAveragedValuesCoProcessor.h
index 71a47a22b..b14066041 100644
--- a/source/VirtualFluidsCore/CoProcessors/TimeAveragedValuesCoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/TimeAveragedValuesCoProcessor.h
@@ -1,17 +1,21 @@
 #ifndef TimeAveragedValuesCoProcessor_H
 #define TimeAveragedValuesCoProcessor_H
 
+#include <memory>
+#include <string>
+#include <vector>
+
 #include "CoProcessor.h"
-#include "Grid3D.h"
-#include "Block3D.h"
-#include "LBMUnitConverter.h"
-#include "Communicator.h"
-#include "IntegrateValuesHelper.h"
-#include "WbWriter.h"
-
-#include <boost/shared_ptr.hpp>
+#include "LBMSystem.h"
+
+class Communicator;
+class Grid3D;
+class UbScheduler;
+class WbWriter;
+class Block3D;
+
 class TimeAveragedValuesCoProcessor;
-typedef boost::shared_ptr<TimeAveragedValuesCoProcessor> TimeAveragedValuesCoProcessorPtr;
+typedef std::shared_ptr<TimeAveragedValuesCoProcessor> TimeAveragedValuesCoProcessorPtr;
 
 //! \brief  Computes the time averaged mean velocity and RMS values and writes to parallel .vtk
 //! \details writes at given time intervals specified in scheduler (s), does averaging according to scheduler (Avs) and resets according to scheduler (rs).  <br>
@@ -37,10 +41,10 @@ public:
    };
 public:
    TimeAveragedValuesCoProcessor();
-   TimeAveragedValuesCoProcessor(Grid3DPtr grid, const std::string& path, WbWriter* const writer,
-      UbSchedulerPtr s, CommunicatorPtr comm, int options);
-   TimeAveragedValuesCoProcessor(Grid3DPtr grid, const std::string& path, WbWriter* const writer,
-      UbSchedulerPtr s, CommunicatorPtr comm, int options, std::vector<int> levels, std::vector<double>& levelCoords, std::vector<double>& bounds, bool timeAveraging = true);
+   TimeAveragedValuesCoProcessor(std::shared_ptr<Grid3D> grid, const std::string& path, WbWriter* const writer,
+       std::shared_ptr<UbScheduler> s, std::shared_ptr<Communicator> comm, int options);
+   TimeAveragedValuesCoProcessor(std::shared_ptr<Grid3D> grid, const std::string& path, WbWriter* const writer,
+       std::shared_ptr<UbScheduler> s, std::shared_ptr<Communicator> comm, int options, std::vector<int> levels, std::vector<double>& levelCoords, std::vector<double>& bounds, bool timeAveraging = true);
    //! Make update
    void process(double step);
    //! Computes subtotal of velocity , fluctuations and triple correlations
@@ -54,21 +58,21 @@ protected:
    //! Prepare data and write in .vtk file
    void collectData(double step);
    //! prepare data
-   void addData(const Block3DPtr block);
+   void addData(const std::shared_ptr<Block3D> block);
    void clearData();
    //! Computes average values of velocity , fluctuations and triple correlations 
    void calculateAverageValues(double timeStep);
 
-   void init(UbSchedulerPtr s);
+   void init(std::shared_ptr<UbScheduler> s);
    void planarAverage(double step);
 
 private:
-   CommunicatorPtr comm;
+    std::shared_ptr<Communicator> comm;
    std::vector<UbTupleFloat3> nodes;
    std::vector<UbTupleInt8> cells;
    std::vector<std::string> datanames;
    std::vector<std::vector<double> > data;
-   std::vector<std::vector<Block3DPtr> > blockVector;
+   std::vector<std::vector<std::shared_ptr<Block3D> > > blockVector;
    bool root;
    int minInitLevel; //min init level
    int maxInitLevel;
@@ -79,9 +83,9 @@ private:
    std::string path;
    WbWriter* writer;
    bool restart, compressible;
-   UbSchedulerPtr averageScheduler;  //additional scheduler to averaging after a given interval
-   UbSchedulerPtr resetSchedulerRMS;  //additional scheduler to restart averaging after a given interval
-   UbSchedulerPtr resetSchedulerMeans;  //additional scheduler to restart averaging after a given interval
+   std::shared_ptr<UbScheduler> averageScheduler;  //additional scheduler to averaging after a given interval
+   std::shared_ptr<UbScheduler> resetSchedulerRMS;  //additional scheduler to restart averaging after a given interval
+   std::shared_ptr<UbScheduler> resetSchedulerMeans;  //additional scheduler to restart averaging after a given interval
    //labels for the different components, e.g. AvVxx for time averaged RMS: 1/n SUM((U-Umean)^2)
    //you need to calculate a square root before plotting RMS
    enum Velocity { Vx, Vy, Vz };
diff --git a/source/VirtualFluidsCore/CoProcessors/TimeDependentBCCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/TimeDependentBCCoProcessor.cpp
index f0b8c5350..ee080d6cc 100644
--- a/source/VirtualFluidsCore/CoProcessors/TimeDependentBCCoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/TimeDependentBCCoProcessor.cpp
@@ -1,7 +1,8 @@
 #include "TimeDependentBCCoProcessor.h"
-#include <boost/foreach.hpp>
 
-using namespace std;
+#include "Interactor3D.h"
+#include "UbScheduler.h"
+#include "Grid3D.h"
 
 TimeDependentBCCoProcessor::TimeDependentBCCoProcessor(Grid3DPtr grid) : CoProcessor(grid,  UbSchedulerPtr(new UbScheduler(1)))
 {
@@ -15,7 +16,7 @@ TimeDependentBCCoProcessor::~TimeDependentBCCoProcessor()
 //////////////////////////////////////////////////////////////////////////
 void TimeDependentBCCoProcessor::process(double step)
 {
-   BOOST_FOREACH(Interactor3DPtr inter, interactors)
+   for(Interactor3DPtr inter : interactors)
       inter->updateInteractor( step );
    UBLOG(logDEBUG3, "TimeDependentBCCoProcessor::update:" << step);
 }
diff --git a/source/VirtualFluidsCore/CoProcessors/TimeDependentBCCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/TimeDependentBCCoProcessor.h
index d81a9ff8e..a80794155 100644
--- a/source/VirtualFluidsCore/CoProcessors/TimeDependentBCCoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/TimeDependentBCCoProcessor.h
@@ -1,26 +1,33 @@
 #ifndef TimeDependentBCCoProcessor_H
 #define TimeDependentBCCoProcessor_H
 
+#include <vector>
+#include <memory>
+
 #include "CoProcessor.h"
-#include "Interactor3D.h"
 
-#include <boost/shared_ptr.hpp>
+class Interactor3D;
+class Grid3D;
+
 class TimeDependentBCCoProcessor;
-typedef boost::shared_ptr<TimeDependentBCCoProcessor> TimeDependentBCCoProcessorPtr;
+typedef std::shared_ptr<TimeDependentBCCoProcessor> TimeDependentBCCoProcessorPtr;
 
 //! \brief The class update interactors depend of time step. 
 //! \details TimeDependentBCCoProcessor update every time step information in BCAdapters throw Interactors
 //! \author Sonja Uphoff, Kostyantyn Kucher
-class TimeDependentBCCoProcessor: public CoProcessor {
+class TimeDependentBCCoProcessor : public CoProcessor
+{
 public:
-	TimeDependentBCCoProcessor(Grid3DPtr grid);
+	TimeDependentBCCoProcessor(std::shared_ptr<Grid3D> grid);
 	virtual ~TimeDependentBCCoProcessor();
-	void process(double step);
+
+	void process(double step) override;
+
    //! add interactors to CoProcessor
-   void addInteractor(Interactor3DPtr interactor);
-protected:
+   void addInteractor(std::shared_ptr<Interactor3D> interactor);
+
 private:
-   std::vector<Interactor3DPtr> interactors;
+   std::vector<std::shared_ptr<Interactor3D> > interactors;
 };
 
 
diff --git a/source/VirtualFluidsCore/CoProcessors/TimeseriesCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/TimeseriesCoProcessor.cpp
index e66f3a6ce..ef63db141 100644
--- a/source/VirtualFluidsCore/CoProcessors/TimeseriesCoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/TimeseriesCoProcessor.cpp
@@ -7,11 +7,14 @@
 
 #include "TimeseriesCoProcessor.h"
 
-
-#include <iostream>
 #include <fstream>
 
-using namespace std;
+#include "IntegrateValuesHelper.h"
+#include "LBMUnitConverter.h"
+#include "Communicator.h"
+#include "UbScheduler.h"
+#include "Grid3D.h"
+
 
 TimeseriesCoProcessor::TimeseriesCoProcessor(Grid3DPtr grid, UbSchedulerPtr s,
                                                              IntegrateValuesHelperPtr h1,
@@ -31,7 +34,7 @@ TimeseriesCoProcessor::TimeseriesCoProcessor(Grid3DPtr grid, UbSchedulerPtr s,
       if(!ostr)
       { 
          ostr.clear();
-         string path = UbSystem::getPathFromString(fname);
+         std::string path = UbSystem::getPathFromString(fname);
          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);
       }
@@ -73,7 +76,7 @@ void TimeseriesCoProcessor::collectData(double step)
       if(!ostr)
       { 
          ostr.clear();
-         string path = UbSystem::getPathFromString(fname);
+         std::string path = UbSystem::getPathFromString(fname);
          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);
       }
diff --git a/source/VirtualFluidsCore/CoProcessors/TimeseriesCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/TimeseriesCoProcessor.h
index 337665d8f..7cb0e1612 100644
--- a/source/VirtualFluidsCore/CoProcessors/TimeseriesCoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/TimeseriesCoProcessor.h
@@ -8,37 +8,43 @@
 #ifndef TimeseriesCoProcessor_H
 #define TimeseriesCoProcessor_H
 
+#include <memory>
+#include <string>
+
 #include "CoProcessor.h"
-#include "IntegrateValuesHelper.h"
-#include "LBMUnitConverter.h"
-#include "Communicator.h"
 
-#include <boost/shared_ptr.hpp>
+class Communicator;
+class Grid3D;
+class UbScheduler;
+class IntegrateValuesHelper;
 
 class TimeseriesCoProcessor;
-typedef boost::shared_ptr<TimeseriesCoProcessor> TimeseriesCoProcessorPtr;
+typedef std::shared_ptr<TimeseriesCoProcessor> TimeseriesCoProcessorPtr;
 
 //! \brief     Writes timeseries of density and velocity to a file.
 //! \details   Uses Integrate values helper, scheduler must be set in testcase.
 //! \author    Sonja Uphoff
 //! \date      May 2013
 
-class TimeseriesCoProcessor: public CoProcessor {
+class TimeseriesCoProcessor : public CoProcessor
+{
 public:
-	TimeseriesCoProcessor(Grid3DPtr grid, UbSchedulerPtr s,
-                                   IntegrateValuesHelperPtr h1,
-                                   const std::string& path, CommunicatorPtr comm);
-	virtual ~TimeseriesCoProcessor();
-	//! calls collectData.
-   void process(double step); 
+    TimeseriesCoProcessor(std::shared_ptr<Grid3D> grid, std::shared_ptr<UbScheduler> s, std::shared_ptr<IntegrateValuesHelper> h1, const std::string& path, std::shared_ptr<Communicator> comm);
+    virtual ~TimeseriesCoProcessor();
+
+    //! calls collectData.
+    void process(double step) override;
+
 protected:
-   //! object that can compute spacial average values in 3D-subdomain.
-	IntegrateValuesHelperPtr h1;  
-	void collectData(double step);  
-   CommunicatorPtr comm;
+    void collectData(double step);
+
+    //! object that can compute spacial average values in 3D-subdomain.
+    std::shared_ptr<IntegrateValuesHelper> h1;
+    std::shared_ptr<Communicator> comm;
+
 private:
-	std::string path; //! output filename, e.g.  pathname + "/steps/timeseries"
-   std::string fname;
+    std::string path; //! output filename, e.g.  pathname + "/steps/timeseries"
+    std::string fname;
 };
 
 
diff --git a/source/VirtualFluidsCore/CoProcessors/TurbulenceIntensityCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/TurbulenceIntensityCoProcessor.cpp
index 02294a625..ce275d58a 100644
--- a/source/VirtualFluidsCore/CoProcessors/TurbulenceIntensityCoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/TurbulenceIntensityCoProcessor.cpp
@@ -1,265 +1,268 @@
-#include "TurbulenceIntensityCoProcessor.h"
-#include "LBMKernel.h"
-#include "BCProcessor.h"
-#include <vector>
-#include <string>
-#include <boost/foreach.hpp>
-#include "basics/writer/WbWriterVtkXmlASCII.h"
-#include "basics/utilities/UbMath.h"
-
-using namespace std;
-
-TurbulenceIntensityCoProcessor::TurbulenceIntensityCoProcessor(Grid3DPtr grid, const std::string& path, 
-                                                                                       WbWriter* const writer,
-                                                                                       UbSchedulerPtr s, CommunicatorPtr comm)
-                                                                                     : CoProcessor(grid, s),
-                                                                                       path(path),
-                                                                                       comm(comm),
-                                                                                       writer(writer)
-{
-   init();
-}
-//////////////////////////////////////////////////////////////////////////
-void TurbulenceIntensityCoProcessor::init()
-{
-   gridRank  = grid->getRank();
-   minInitLevel = this->grid->getCoarsestInitializedLevel();
-   maxInitLevel = this->grid->getFinestInitializedLevel();
-
-   blockVector.resize(maxInitLevel+1);
-
-   for(int level = minInitLevel; level<=maxInitLevel;level++)
-   {
-      grid->getBlocks(level, gridRank, true, blockVector[level]);
-
-      BOOST_FOREACH(Block3DPtr block, blockVector[level])
-      {
-         UbTupleInt3 nx = grid->getBlockNX();
-         AverageValuesArray3DPtr averageValues = AverageValuesArray3DPtr(new AverageValuesArray3D(val<1>(nx)+1, val<2>(nx)+1, val<3>(nx)+1, 4, 0.0));
-         block->getKernel()->getDataSet()->setAverageValues(averageValues);
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void TurbulenceIntensityCoProcessor::process(double step)
-{
-   calculateAverageValues(int(step));
-
-   if(scheduler->isDue(step) )
-      collectData(step);
-
-   UBLOG(logDEBUG3, "TurbulenceIntensityCoProcessor::update:" << step);
-}
-//////////////////////////////////////////////////////////////////////////
-void TurbulenceIntensityCoProcessor::collectData(double step)
-{
-   int istep = int(step);
-
-   for(int level = minInitLevel; level<=maxInitLevel;level++)
-   {
-      BOOST_FOREACH(Block3DPtr block, blockVector[level])
-      {
-         if (block)
-         {
-            addData(block);
-         }
-      }
-   }
-
-   string partName = writer->writeOctsWithNodeData(path+ UbSystem::toString(gridRank)+ "_" + UbSystem::toString(istep),nodes,cells,datanames,data);
-   size_t found=partName.find_last_of("//");
-   string piece = partName.substr(found+1);
-
-   vector<string> cellDataNames;
-
-   vector<string> pieces = comm->gather(piece);
-   if (comm->getProcessID() == comm->getRoot())
-   {
-      string pname = WbWriterVtkXmlASCII::getInstance()->writeParallelFile(path+"_"+UbSystem::toString(istep),pieces,datanames,cellDataNames);
-
-      vector<string> filenames;
-      filenames.push_back(pname);
-      if (step == CoProcessor::scheduler->getMinBegin())
-      {
-         WbWriterVtkXmlASCII::getInstance()->writeCollection(path+"_collection",filenames,istep,false);
-      } 
-      else
-      {
-         WbWriterVtkXmlASCII::getInstance()->addFilesToCollection(path+"_collection",filenames,istep,false);
-      }
-      UBLOG(logINFO,"TurbulenceIntensityCoProcessor step: " << istep);
-   }
-
-   clearData();
-}
-//////////////////////////////////////////////////////////////////////////
-void TurbulenceIntensityCoProcessor::clearData()
-{
-   nodes.clear();
-   cells.clear();
-   datanames.clear();
-   data.clear();
-}
-//////////////////////////////////////////////////////////////////////////
-void TurbulenceIntensityCoProcessor::addData(const Block3DPtr block)
-{
-   UbTupleDouble3 org          = grid->getBlockWorldCoordinates(block);
-   UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
-   UbTupleDouble3 nodeOffset   = grid->getNodeOffset(block);
-   double         dx           = grid->getDeltaX(block);
-
-   //Diese Daten werden geschrieben:
-   datanames.resize(0);
-   datanames.push_back("TI");
-
-   data.resize(datanames.size());
-
-   LBMKernelPtr kernel = block->getKernel();
-   BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
-   DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions(); 
-   AverageValuesArray3DPtr av = kernel->getDataSet()->getAverageValues();
-   //int ghostLayerWidth = kernel->getGhostLayerWidth();
-
-   //knotennummerierung faengt immer bei 0 an!
-   int SWB,SEB,NEB,NWB,SWT,SET,NET,NWT;
-
-   int minX1 = 0;
-   int minX2 = 0;
-   int minX3 = 0;
-
-   int maxX1 = int(distributions->getNX1());
-   int maxX2 = int(distributions->getNX2());
-   int maxX3 = int(distributions->getNX3());
-
-   //nummern vergeben und node vector erstellen + daten sammeln
-   CbArray3D<int> nodeNumbers((int)maxX1, (int)maxX2, (int)maxX3,-1);
-   //D3Q27BoundaryConditionPtr bcPtr;
-   int nr = (int)nodes.size();
- 
-   for(int ix3=minX3; ix3<maxX3-1; ix3++)
-   {
-      for(int ix2=minX2; ix2<maxX2-1; ix2++)
-      {
-         for(int ix1=minX1; ix1<maxX1-1; ix1++)
-         {
-            if(!bcArray->isUndefined(ix1,ix2,ix3) && !bcArray->isSolid(ix1,ix2,ix3))
-            {
-               int index = 0;
-               nodeNumbers(ix1,ix2,ix3) = nr++;
-               nodes.push_back( makeUbTuple(float(val<1>(org) - val<1>(nodeOffset) + ix1*dx),
-                                            float(val<2>(org) - val<2>(nodeOffset) + ix2*dx),
-                                            float(val<3>(org) - val<3>(nodeOffset) + ix3*dx)) );
-
-               //compute turbulence intensity
-               double temp = (*av)(ix1,ix2,ix3,AvVxxyyzz)/
-                            ((*av)(ix1,ix2,ix3,AvVx)*(*av)(ix1,ix2,ix3,AvVx)+
-                             (*av)(ix1,ix2,ix3,AvVy)*(*av)(ix1,ix2,ix3,AvVy)+
-                             (*av)(ix1,ix2,ix3,AvVz)*(*av)(ix1,ix2,ix3,AvVz));
-
-               LBMReal ti = sqrt(temp);
-
-               if (UbMath::isNaN(ti)) UB_THROW( UbException(UB_EXARGS,"TI is not a number (nan or -1.#IND), sqrt(temp), where temp = "+UbSystem::toString(temp)+", AvVx = "+UbSystem::toString((*av)(ix1,ix2,ix3,AvVx))+" AvVy = "+UbSystem::toString((*av)(ix1,ix2,ix3,AvVy))+" AvVz = "+UbSystem::toString((*av)(ix1,ix2,ix3,AvVz))));
-
-               data[index++].push_back(ti);
-            }
-         }
-      }
-   }
-   //cell vector erstellen
-   for(int ix3=minX3; ix3<maxX3-1; ix3++)
-   {
-      for(int ix2=minX2; ix2<maxX2-1; ix2++)
-      {
-         for(int ix1=minX1; ix1<maxX1-1; ix1++)
-         {
-            if(   (SWB=nodeNumbers( ix1  , ix2,   ix3   )) >= 0
-               && (SEB=nodeNumbers( ix1+1, ix2,   ix3   )) >= 0
-               && (NEB=nodeNumbers( ix1+1, ix2+1, ix3   )) >= 0
-               && (NWB=nodeNumbers( ix1  , ix2+1, ix3   )) >= 0 
-               && (SWT=nodeNumbers( ix1  , ix2,   ix3+1 )) >= 0
-               && (SET=nodeNumbers( ix1+1, ix2,   ix3+1 )) >= 0
-               && (NET=nodeNumbers( ix1+1, ix2+1, ix3+1 )) >= 0
-               && (NWT=nodeNumbers( ix1  , ix2+1, ix3+1 )) >= 0                )
-            {
-               cells.push_back( makeUbTuple(SWB,SEB,NEB,NWB,SWT,SET,NET,NWT) );
-            }
-         }
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void TurbulenceIntensityCoProcessor::calculateAverageValues(double timeStep)
-{
-   using namespace D3Q27System;
-
-   int minInitLevel = this->grid->getCoarsestInitializedLevel();
-   int maxInitLevel = this->grid->getFinestInitializedLevel();
-   LBMReal f[27];
-   LBMReal vx, vy, vz;
-
-   for(int level = minInitLevel; level<=maxInitLevel;level++)
-   {
-      BOOST_FOREACH(Block3DPtr block, blockVector[level])
-      {
-         if (block)
-         {
-            LBMKernelPtr kernel = block->getKernel();
-            BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
-            DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions(); 
-            AverageValuesArray3DPtr av = kernel->getDataSet()->getAverageValues();
-
-            int minX1 = 0;
-            int minX2 = 0;
-            int minX3 = 0;
-
-            int maxX1 = int(distributions->getNX1());
-            int maxX2 = int(distributions->getNX2());
-            int maxX3 = int(distributions->getNX3());
-
-            for(int ix3=minX3; ix3<maxX3-1; ix3++)
-            {
-               for(int ix2=minX2; ix2<maxX2-1; ix2++)
-               {
-                  for(int ix1=minX1; ix1<maxX1-1; ix1++)
-                  {
-                     if(!bcArray->isUndefined(ix1,ix2,ix3) && !bcArray->isSolid(ix1,ix2,ix3))
-                     {
-                        //////////////////////////////////////////////////////////////////////////
-                        //read distribution
-                        ////////////////////////////////////////////////////////////////////////////
-                        distributions->getDistribution(f, ix1, ix2, ix3);
-                        //////////////////////////////////////////////////////////////////////////
-                        //compute velocity
-                        //////////////////////////////////////////////////////////////////////////
-                        vx = f[E] - f[W] + f[NE] - f[SW] + f[SE] - f[NW] + f[TE] - f[BW]
-                        + f[BE] - f[TW] + f[TNE] - f[TSW] + f[TSE] - f[TNW] + f[BNE] - f[BSW]
-                        + f[BSE] - f[BNW]; 
-
-                        vy = f[N] - f[S] + f[NE] - f[SW] - f[SE] + f[NW] + f[TN] - f[BS] + f[BN]
-                        - f[TS] + f[TNE] - f[TSW] - f[TSE] + f[TNW] + f[BNE] - f[BSW] - f[BSE] 
-                        + f[BNW]; 
-
-                        vz = f[T] - f[B] + f[TE] - f[BW] - f[BE] + f[TW] + f[TN] - f[BS] - f[BN] 
-                        + f[TS] + f[TNE] + f[TSW] + f[TSE] + f[TNW] - f[BNE] - f[BSW] - f[BSE] 
-                        - f[BNW];
-                        //////////////////////////////////////////////////////////////////////////
-                        //compute average values
-                        //////////////////////////////////////////////////////////////////////////
-                        (*av)(ix1,ix2,ix3,AvVx) = ((*av)(ix1,ix2,ix3,AvVx)*timeStep + vx)/(timeStep+1.0);
-                        (*av)(ix1,ix2,ix3,AvVy) = ((*av)(ix1,ix2,ix3,AvVy)*timeStep + vy)/(timeStep+1.0);
-                        (*av)(ix1,ix2,ix3,AvVz) = ((*av)(ix1,ix2,ix3,AvVz)*timeStep + vz)/(timeStep+1.0);
-
-                        (*av)(ix1,ix2,ix3,AvVxxyyzz) = ((vx-(*av)(ix1,ix2,ix3,AvVx))*(vx-(*av)(ix1,ix2,ix3,AvVx)) +
-                                                         (vy-(*av)(ix1,ix2,ix3,AvVy))*(vy-(*av)(ix1,ix2,ix3,AvVy)) +
-                                                         (vz-(*av)(ix1,ix2,ix3,AvVz))*(vz-(*av)(ix1,ix2,ix3,AvVz)) +
-                                                         (*av)(ix1,ix2,ix3,AvVxxyyzz)*timeStep)/(timeStep+1.0);
-                        //////////////////////////////////////////////////////////////////////////
-                     }
-                  }
-               }
-            }
-         }
-      }
-   }
-}
-
+#include "TurbulenceIntensityCoProcessor.h"
+
+#include "LBMKernel.h"
+#include "BCProcessor.h"
+#include "basics/writer/WbWriterVtkXmlASCII.h"
+#include "basics/utilities/UbMath.h"
+#include "DataSet3D.h"
+#include "Grid3D.h"
+#include "Block3D.h"
+#include "LBMUnitConverter.h"
+#include "Communicator.h"
+#include "UbScheduler.h"
+#include "BCArray3D.h"
+
+TurbulenceIntensityCoProcessor::TurbulenceIntensityCoProcessor(Grid3DPtr grid, const std::string& path, 
+                                                                                       WbWriter* const writer,
+                                                                                       UbSchedulerPtr s, CommunicatorPtr comm)
+                                                                                     : CoProcessor(grid, s),
+                                                                                       path(path),
+                                                                                       comm(comm),
+                                                                                       writer(writer)
+{
+   init();
+}
+//////////////////////////////////////////////////////////////////////////
+void TurbulenceIntensityCoProcessor::init()
+{
+   gridRank  = grid->getRank();
+   minInitLevel = this->grid->getCoarsestInitializedLevel();
+   maxInitLevel = this->grid->getFinestInitializedLevel();
+
+   blockVector.resize(maxInitLevel+1);
+
+   for(int level = minInitLevel; level<=maxInitLevel;level++)
+   {
+      grid->getBlocks(level, gridRank, true, blockVector[level]);
+
+      for(Block3DPtr block : blockVector[level])
+      {
+         UbTupleInt3 nx = grid->getBlockNX();
+         AverageValuesArray3DPtr averageValues = AverageValuesArray3DPtr(new AverageValuesArray3D(val<1>(nx)+1, val<2>(nx)+1, val<3>(nx)+1, 4, 0.0));
+         block->getKernel()->getDataSet()->setAverageValues(averageValues);
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void TurbulenceIntensityCoProcessor::process(double step)
+{
+   calculateAverageValues(int(step));
+
+   if(scheduler->isDue(step) )
+      collectData(step);
+
+   UBLOG(logDEBUG3, "TurbulenceIntensityCoProcessor::update:" << step);
+}
+//////////////////////////////////////////////////////////////////////////
+void TurbulenceIntensityCoProcessor::collectData(double step)
+{
+   int istep = int(step);
+
+   for(int level = minInitLevel; level<=maxInitLevel;level++)
+   {
+      for(Block3DPtr block : blockVector[level])
+      {
+         if (block)
+         {
+            addData(block);
+         }
+      }
+   }
+
+   std::string partName = writer->writeOctsWithNodeData(path+ UbSystem::toString(gridRank)+ "_" + UbSystem::toString(istep),nodes,cells,datanames,data);
+   size_t found=partName.find_last_of("//");
+   std::string piece = partName.substr(found+1);
+
+   std::vector<std::string> cellDataNames;
+
+   std::vector<std::string> pieces = comm->gather(piece);
+   if (comm->getProcessID() == comm->getRoot())
+   {
+      std::string pname = WbWriterVtkXmlASCII::getInstance()->writeParallelFile(path+"_"+UbSystem::toString(istep),pieces,datanames,cellDataNames);
+
+      std::vector<std::string> filenames;
+      filenames.push_back(pname);
+      if (step == CoProcessor::scheduler->getMinBegin())
+      {
+         WbWriterVtkXmlASCII::getInstance()->writeCollection(path+"_collection",filenames,istep,false);
+      } 
+      else
+      {
+         WbWriterVtkXmlASCII::getInstance()->addFilesToCollection(path+"_collection",filenames,istep,false);
+      }
+      UBLOG(logINFO,"TurbulenceIntensityCoProcessor step: " << istep);
+   }
+
+   clearData();
+}
+//////////////////////////////////////////////////////////////////////////
+void TurbulenceIntensityCoProcessor::clearData()
+{
+   nodes.clear();
+   cells.clear();
+   datanames.clear();
+   data.clear();
+}
+//////////////////////////////////////////////////////////////////////////
+void TurbulenceIntensityCoProcessor::addData(const Block3DPtr block)
+{
+   UbTupleDouble3 org          = grid->getBlockWorldCoordinates(block);
+   UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
+   UbTupleDouble3 nodeOffset   = grid->getNodeOffset(block);
+   double         dx           = grid->getDeltaX(block);
+
+   //Diese Daten werden geschrieben:
+   datanames.resize(0);
+   datanames.push_back("TI");
+
+   data.resize(datanames.size());
+
+   ILBMKernelPtr kernel = block->getKernel();
+   BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
+   DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions(); 
+   AverageValuesArray3DPtr av = kernel->getDataSet()->getAverageValues();
+   //int ghostLayerWidth = kernel->getGhostLayerWidth();
+
+   //knotennummerierung faengt immer bei 0 an!
+   int SWB,SEB,NEB,NWB,SWT,SET,NET,NWT;
+
+   int minX1 = 0;
+   int minX2 = 0;
+   int minX3 = 0;
+
+   int maxX1 = int(distributions->getNX1());
+   int maxX2 = int(distributions->getNX2());
+   int maxX3 = int(distributions->getNX3());
+
+   //nummern vergeben und node std::vector erstellen + daten sammeln
+   CbArray3D<int> nodeNumbers((int)maxX1, (int)maxX2, (int)maxX3,-1);
+   //D3Q27BoundaryConditionPtr bcPtr;
+   int nr = (int)nodes.size();
+ 
+   for(int ix3=minX3; ix3<maxX3-1; ix3++)
+   {
+      for(int ix2=minX2; ix2<maxX2-1; ix2++)
+      {
+         for(int ix1=minX1; ix1<maxX1-1; ix1++)
+         {
+            if(!bcArray->isUndefined(ix1,ix2,ix3) && !bcArray->isSolid(ix1,ix2,ix3))
+            {
+               int index = 0;
+               nodeNumbers(ix1,ix2,ix3) = nr++;
+               nodes.push_back( makeUbTuple(float(val<1>(org) - val<1>(nodeOffset) + ix1*dx),
+                                            float(val<2>(org) - val<2>(nodeOffset) + ix2*dx),
+                                            float(val<3>(org) - val<3>(nodeOffset) + ix3*dx)) );
+
+               //compute turbulence intensity
+               double temp = (*av)(ix1,ix2,ix3,AvVxxyyzz)/
+                            ((*av)(ix1,ix2,ix3,AvVx)*(*av)(ix1,ix2,ix3,AvVx)+
+                             (*av)(ix1,ix2,ix3,AvVy)*(*av)(ix1,ix2,ix3,AvVy)+
+                             (*av)(ix1,ix2,ix3,AvVz)*(*av)(ix1,ix2,ix3,AvVz));
+
+               LBMReal ti = sqrt(temp);
+
+               if (UbMath::isNaN(ti)) UB_THROW( UbException(UB_EXARGS,"TI is not a number (nan or -1.#IND), sqrt(temp), where temp = "+UbSystem::toString(temp)+", AvVx = "+UbSystem::toString((*av)(ix1,ix2,ix3,AvVx))+" AvVy = "+UbSystem::toString((*av)(ix1,ix2,ix3,AvVy))+" AvVz = "+UbSystem::toString((*av)(ix1,ix2,ix3,AvVz))));
+
+               data[index++].push_back(ti);
+            }
+         }
+      }
+   }
+   //cell std::vector erstellen
+   for(int ix3=minX3; ix3<maxX3-1; ix3++)
+   {
+      for(int ix2=minX2; ix2<maxX2-1; ix2++)
+      {
+         for(int ix1=minX1; ix1<maxX1-1; ix1++)
+         {
+            if(   (SWB=nodeNumbers( ix1  , ix2,   ix3   )) >= 0
+               && (SEB=nodeNumbers( ix1+1, ix2,   ix3   )) >= 0
+               && (NEB=nodeNumbers( ix1+1, ix2+1, ix3   )) >= 0
+               && (NWB=nodeNumbers( ix1  , ix2+1, ix3   )) >= 0 
+               && (SWT=nodeNumbers( ix1  , ix2,   ix3+1 )) >= 0
+               && (SET=nodeNumbers( ix1+1, ix2,   ix3+1 )) >= 0
+               && (NET=nodeNumbers( ix1+1, ix2+1, ix3+1 )) >= 0
+               && (NWT=nodeNumbers( ix1  , ix2+1, ix3+1 )) >= 0                )
+            {
+               cells.push_back( makeUbTuple(SWB,SEB,NEB,NWB,SWT,SET,NET,NWT) );
+            }
+         }
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void TurbulenceIntensityCoProcessor::calculateAverageValues(double timeStep)
+{
+   using namespace D3Q27System;
+
+   int minInitLevel = this->grid->getCoarsestInitializedLevel();
+   int maxInitLevel = this->grid->getFinestInitializedLevel();
+   LBMReal f[27];
+   LBMReal vx, vy, vz;
+
+   for(int level = minInitLevel; level<=maxInitLevel;level++)
+   {
+      for(Block3DPtr block : blockVector[level])
+      {
+         if (block)
+         {
+            ILBMKernelPtr kernel = block->getKernel();
+            BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
+            DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions(); 
+            AverageValuesArray3DPtr av = kernel->getDataSet()->getAverageValues();
+
+            int minX1 = 0;
+            int minX2 = 0;
+            int minX3 = 0;
+
+            int maxX1 = int(distributions->getNX1());
+            int maxX2 = int(distributions->getNX2());
+            int maxX3 = int(distributions->getNX3());
+
+            for(int ix3=minX3; ix3<maxX3-1; ix3++)
+            {
+               for(int ix2=minX2; ix2<maxX2-1; ix2++)
+               {
+                  for(int ix1=minX1; ix1<maxX1-1; ix1++)
+                  {
+                     if(!bcArray->isUndefined(ix1,ix2,ix3) && !bcArray->isSolid(ix1,ix2,ix3))
+                     {
+                        //////////////////////////////////////////////////////////////////////////
+                        //read distribution
+                        ////////////////////////////////////////////////////////////////////////////
+                        distributions->getDistribution(f, ix1, ix2, ix3);
+                        //////////////////////////////////////////////////////////////////////////
+                        //compute velocity
+                        //////////////////////////////////////////////////////////////////////////
+                        vx = f[E] - f[W] + f[NE] - f[SW] + f[SE] - f[NW] + f[TE] - f[BW]
+                        + f[BE] - f[TW] + f[TNE] - f[TSW] + f[TSE] - f[TNW] + f[BNE] - f[BSW]
+                        + f[BSE] - f[BNW]; 
+
+                        vy = f[N] - f[S] + f[NE] - f[SW] - f[SE] + f[NW] + f[TN] - f[BS] + f[BN]
+                        - f[TS] + f[TNE] - f[TSW] - f[TSE] + f[TNW] + f[BNE] - f[BSW] - f[BSE] 
+                        + f[BNW]; 
+
+                        vz = f[T] - f[B] + f[TE] - f[BW] - f[BE] + f[TW] + f[TN] - f[BS] - f[BN] 
+                        + f[TS] + f[TNE] + f[TSW] + f[TSE] + f[TNW] - f[BNE] - f[BSW] - f[BSE] 
+                        - f[BNW];
+                        //////////////////////////////////////////////////////////////////////////
+                        //compute average values
+                        //////////////////////////////////////////////////////////////////////////
+                        (*av)(ix1,ix2,ix3,AvVx) = ((*av)(ix1,ix2,ix3,AvVx)*timeStep + vx)/(timeStep+1.0);
+                        (*av)(ix1,ix2,ix3,AvVy) = ((*av)(ix1,ix2,ix3,AvVy)*timeStep + vy)/(timeStep+1.0);
+                        (*av)(ix1,ix2,ix3,AvVz) = ((*av)(ix1,ix2,ix3,AvVz)*timeStep + vz)/(timeStep+1.0);
+
+                        (*av)(ix1,ix2,ix3,AvVxxyyzz) = ((vx-(*av)(ix1,ix2,ix3,AvVx))*(vx-(*av)(ix1,ix2,ix3,AvVx)) +
+                                                         (vy-(*av)(ix1,ix2,ix3,AvVy))*(vy-(*av)(ix1,ix2,ix3,AvVy)) +
+                                                         (vz-(*av)(ix1,ix2,ix3,AvVz))*(vz-(*av)(ix1,ix2,ix3,AvVz)) +
+                                                         (*av)(ix1,ix2,ix3,AvVxxyyzz)*timeStep)/(timeStep+1.0);
+                        //////////////////////////////////////////////////////////////////////////
+                     }
+                  }
+               }
+            }
+         }
+      }
+   }
+}
+
diff --git a/source/VirtualFluidsCore/CoProcessors/TurbulenceIntensityCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/TurbulenceIntensityCoProcessor.h
index 6f0926b9a..119b2668b 100644
--- a/source/VirtualFluidsCore/CoProcessors/TurbulenceIntensityCoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/TurbulenceIntensityCoProcessor.h
@@ -1,27 +1,30 @@
 #ifndef TurbulenceIntensityCoProcessor_H
 #define TurbulenceIntensityCoProcessor_H
 
+#include <memory>
+#include <string>
+#include <string>
+
 #include "CoProcessor.h"
-#include "Grid3D.h"
-#include "Block3D.h"
-#include "LBMUnitConverter.h"
-#include "Communicator.h"
 
-#include "WbWriter.h"
+class Communicator;
+class Grid3D;
+class UbScheduler;
+class WbWriter;
+class Block3D;
 
-#include <boost/shared_ptr.hpp>
 class TurbulenceIntensityCoProcessor;
-typedef boost::shared_ptr<TurbulenceIntensityCoProcessor> TurbulenceIntensityCoProcessorPtr;
+typedef std::shared_ptr<TurbulenceIntensityCoProcessor> TurbulenceIntensityCoProcessorPtr;
 
 class TurbulenceIntensityCoProcessor : public CoProcessor
 {
 public:
-   TurbulenceIntensityCoProcessor(Grid3DPtr grid, const std::string& path, WbWriter* const writer, 
-                          UbSchedulerPtr s, CommunicatorPtr comm);
+   TurbulenceIntensityCoProcessor(std::shared_ptr<Grid3D> grid, const std::string& path, WbWriter* const writer,
+       std::shared_ptr<UbScheduler> s, std::shared_ptr<Communicator> comm);
    void process(double step);
 protected:
    void collectData(double step);
-   void addData(const Block3DPtr block);
+   void addData(const std::shared_ptr<Block3D> block);
    void clearData();
    void calculateAverageValues(double timeStep);
 private:
@@ -30,13 +33,13 @@ private:
    std::vector<UbTupleInt8> cells;
    std::vector<std::string> datanames;
    std::vector<std::vector<double> > data; 
-   std::vector<std::vector<Block3DPtr> > blockVector;
+   std::vector<std::vector<std::shared_ptr<Block3D> > > blockVector;
    int minInitLevel;
    int maxInitLevel;
    int gridRank;
    std::string path;
    WbWriter* writer;
-   CommunicatorPtr comm;
+   std::shared_ptr<Communicator> comm;
    enum Values{AvVx = 0, AvVy = 1, AvVz = 2, AvVxxyyzz = 3};
 };
 #endif
diff --git a/source/VirtualFluidsCore/CoProcessors/WriteBlocksCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/WriteBlocksCoProcessor.cpp
index baf95617a..0448f924d 100644
--- a/source/VirtualFluidsCore/CoProcessors/WriteBlocksCoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/WriteBlocksCoProcessor.cpp
@@ -1,7 +1,11 @@
 #include "WriteBlocksCoProcessor.h"
 #include "basics/writer/WbWriterVtkXmlASCII.h"
-#include <boost/foreach.hpp>
+
 #include "D3Q27System.h"
+#include "Block3D.h"
+#include "UbScheduler.h"
+#include "Communicator.h"
+#include "Grid3D.h"
 
 WriteBlocksCoProcessor::WriteBlocksCoProcessor(Grid3DPtr grid, UbSchedulerPtr s, 
                                          const std::string& path, WbWriter* const writer, 
@@ -56,7 +60,7 @@ void WriteBlocksCoProcessor::collectData(double step)
       {
          std::vector<Block3DPtr> blockVector;
          grid->getBlocks(level, blockVector);
-         BOOST_FOREACH(Block3DPtr block, blockVector)
+         for(Block3DPtr block : blockVector)
          {
             UbTupleDouble3 org = grid->getBlockWorldCoordinates(block);
             UbTupleDouble3 blockLength = grid->getBlockLengths(block);
diff --git a/source/VirtualFluidsCore/CoProcessors/WriteBlocksCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/WriteBlocksCoProcessor.h
index 0dc8cc30b..de6928e0a 100644
--- a/source/VirtualFluidsCore/CoProcessors/WriteBlocksCoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/WriteBlocksCoProcessor.h
@@ -8,24 +8,33 @@
 #ifndef BlocksCoProcessor_H_
 #define BlocksCoProcessor_H_
 
+#include <memory>
+#include <string>
+
 #include "CoProcessor.h"
-#include "Communicator.h"
-#include "WbWriter.h"
 
-#include <boost/shared_ptr.hpp>
+class Communicator;
+class Grid3D;
+class UbScheduler;
+class WbWriter;
+
 class WriteBlocksCoProcessor;
-typedef boost::shared_ptr<WriteBlocksCoProcessor> WriteBlocksCoProcessorPtr;
+typedef std::shared_ptr<WriteBlocksCoProcessor> WriteBlocksCoProcessorPtr;
 
-class WriteBlocksCoProcessor: public CoProcessor {
+class WriteBlocksCoProcessor: public CoProcessor 
+{
 public:
-   WriteBlocksCoProcessor(Grid3DPtr grid, UbSchedulerPtr s, const std::string& path, WbWriter* const writer, CommunicatorPtr comm);
+   WriteBlocksCoProcessor(std::shared_ptr<Grid3D> grid, std::shared_ptr<UbScheduler> s, const std::string& path, WbWriter* const writer, std::shared_ptr<Communicator> comm);
    virtual ~WriteBlocksCoProcessor();
-   void process(double step);
+
+   void process(double step) override;
+
 protected:
    void collectData(double step);
+
    std::string path;
    WbWriter* writer;
-   CommunicatorPtr comm;
+   std::shared_ptr<Communicator>  comm;
 };
 
 
diff --git a/source/VirtualFluidsCore/CoProcessors/WriteBoundaryConditionsCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/WriteBoundaryConditionsCoProcessor.cpp
index b9ba47778..1f2feafbe 100644
--- a/source/VirtualFluidsCore/CoProcessors/WriteBoundaryConditionsCoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/WriteBoundaryConditionsCoProcessor.cpp
@@ -1,233 +1,241 @@
-#include "WriteBoundaryConditionsCoProcessor.h"
-#include "LBMKernel.h"
-#include "BCProcessor.h"
-#include <vector>
-#include <string>
-#include <boost/foreach.hpp>
-#include "basics/writer/WbWriterVtkXmlASCII.h"
-
-using namespace std;
-
-WriteBoundaryConditionsCoProcessor::WriteBoundaryConditionsCoProcessor()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-WriteBoundaryConditionsCoProcessor::WriteBoundaryConditionsCoProcessor(Grid3DPtr grid, UbSchedulerPtr s,
-   const std::string& path, WbWriter* const writer,
-   LBMUnitConverterPtr conv, CommunicatorPtr comm)
-   : CoProcessor(grid, s),
-   path(path),
-   writer(writer),
-   conv(conv),
-   comm(comm)
-{
-   gridRank = comm->getProcessID();
-   minInitLevel = this->grid->getCoarsestInitializedLevel();
-   maxInitLevel = this->grid->getFinestInitializedLevel();
-
-   blockVector.resize(maxInitLevel+1);
-
-   for (int level = minInitLevel; level<=maxInitLevel; level++)
-   {
-      grid->getBlocks(level, gridRank, true, blockVector[level]);
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void WriteBoundaryConditionsCoProcessor::process(double step)
-{
-   if (scheduler->isDue(step))
-      collectData(step);
-
-   UBLOG(logDEBUG3, "WriteBoundaryConditionsCoProcessor::update:"<<step);
-}
-//////////////////////////////////////////////////////////////////////////
-void WriteBoundaryConditionsCoProcessor::collectData(double step)
-{
-   int istep = static_cast<int>(step);
-
-   for (int level = minInitLevel; level<=maxInitLevel; level++)
-   {
-      BOOST_FOREACH(Block3DPtr block, blockVector[level])
-      {
-         if (block)
-         {
-            addDataGeo(block);
-         }
-      }
-   }
-
-   string pfilePath, partPath, subfolder, cfilePath;
-
-   subfolder = "bc"+UbSystem::toString(istep);
-   pfilePath = path+"/bc/"+subfolder;
-   cfilePath = path+"/bc/bc_collection";
-   partPath = pfilePath+"/bc"+UbSystem::toString(gridRank)+"_"+UbSystem::toString(istep);
-
-
-   string partName = writer->writeOctsWithNodeData(partPath, nodes, cells, datanames, data);
-   size_t found = partName.find_last_of("/");
-   string piece = partName.substr(found+1);
-   piece = subfolder+"/"+piece;
-
-   vector<string> cellDataNames;
-   vector<string> pieces = comm->gather(piece);
-   if (comm->getProcessID()==comm->getRoot())
-   {
-      string pname = WbWriterVtkXmlASCII::getInstance()->writeParallelFile(pfilePath, pieces, datanames, cellDataNames);
-      found = pname.find_last_of("/");
-      piece = pname.substr(found+1);
-
-      vector<string> filenames;
-      filenames.push_back(piece);
-      if (step==CoProcessor::scheduler->getMinBegin())
-      {
-         WbWriterVtkXmlASCII::getInstance()->writeCollection(cfilePath, filenames, istep, false);
-      }
-      else
-      {
-         WbWriterVtkXmlASCII::getInstance()->addFilesToCollection(cfilePath, filenames, istep, false);
-      }
-      UBLOG(logINFO, "WriteBoundaryConditionsCoProcessor step: "<<istep);
-   }
-
-   clearData();
-}
-//////////////////////////////////////////////////////////////////////////
-void WriteBoundaryConditionsCoProcessor::clearData()
-{
-   nodes.clear();
-   cells.clear();
-   datanames.clear();
-   data.clear();
-}
-//////////////////////////////////////////////////////////////////////////
-void WriteBoundaryConditionsCoProcessor::addDataGeo(Block3DPtr block)
-{
-   UbTupleDouble3 org = grid->getBlockWorldCoordinates(block);
-   UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
-   UbTupleDouble3 nodeOffset = grid->getNodeOffset(block);
-   double         dx = grid->getDeltaX(block);
-
-   double level = (double)block->getLevel();
-
-   //Diese Daten werden geschrieben:
-   datanames.resize(0);
-   datanames.push_back("Boundary Conditions");
-   datanames.push_back("Geometry");
-   datanames.push_back("Level");
-   //datanames.push_back("Interface CF");
-
-   data.resize(datanames.size());
-
-   LBMKernelPtr kernel = block->getKernel();
-   BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
-
-   //knotennummerierung faengt immer bei 0 an!
-   int SWB, SEB, NEB, NWB, SWT, SET, NET, NWT;
-
-   int minX1 = 0;
-   int minX2 = 0;
-   int minX3 = 0;
-
-   int maxX1 = (int)bcArray->getNX1();
-   int maxX2 = (int)bcArray->getNX2();
-   int maxX3 = (int)bcArray->getNX3();
-
-   //nummern vergeben und node vector erstellen + daten sammeln
-   CbArray3D<int> nodeNumbers((int)maxX1, (int)maxX2, (int)maxX3, -1);
-   //D3Q27BoundaryConditionPtr bcPtr;
-   int nr = (int)nodes.size();
-
-   maxX1 -= 1;
-   maxX2 -= 1;
-   maxX3 -= 1;
-
-   int s=0;
-
-   
-
-   for (size_t ix3 = minX3; ix3<=maxX3; ix3++)
-   {
-      for (size_t ix2 = minX2; ix2<=maxX2; ix2++)
-      {
-         for (size_t ix1 = minX1; ix1<=maxX1; ix1++)
-         {
-            if (!bcArray->isUndefined(ix1, ix2, ix3))
-            {
-               //int index = 0;
-               nodeNumbers(ix1, ix2, ix3) = nr++;
-               nodes.push_back(makeUbTuple(float(val<1>(org)-val<1>(nodeOffset)+ix1*dx),
-                  float(val<2>(org)-val<2>(nodeOffset)+ix2*dx),
-                  float(val<3>(org)-val<3>(nodeOffset)+ix3*dx)));
-
-
-
-               if (!bcArray->hasBC(ix1, ix2, ix3))
-               {
-                  data[0].push_back(0.0);
-               }
-               else if (bcArray->getBC(ix1, ix2, ix3)->hasNoSlipBoundary())
-                  data[0].push_back(1.0);
-               else if (bcArray->getBC(ix1, ix2, ix3)->hasVelocityBoundary())
-                  data[0].push_back(2.0);
-               else if (bcArray->getBC(ix1, ix2, ix3)->hasDensityBoundary())
-                  data[0].push_back(3.0);
-               else if (bcArray->getBC(ix1, ix2, ix3)->hasSlipBoundary())
-                  data[0].push_back(4.0);
-               else
-                  data[0].push_back(5.0);
-
-
-               if (bcArray->isSolid(ix1, ix2, ix3))
-               {
-                  data[1].push_back(1.0);
-               }
-               else
-               {
-                  data[1].push_back(0.0);
-               }
-                  
-
-               data[2].push_back(level);
-
-               //if (bcArray->isInterfaceCF(ix1, ix2, ix3))
-               //{
-               //   data[3].push_back(1.0);
-               //} 
-               //else
-               //{
-               //   data[3].push_back(0.0);
-               //}
-
-            }
-         }
-      }
-   }
-
-   maxX1 -= 1;
-   maxX2 -= 1;
-   maxX3 -= 1;
-
-   //cell vector erstellen
-   for (int ix3 = minX3; ix3<=maxX3; ix3++)
-   {
-      for (int ix2 = minX2; ix2<=maxX2; ix2++)
-      {
-         for (int ix1 = minX1; ix1<=maxX1; ix1++)
-         {
-            if ((SWB = nodeNumbers(ix1, ix2, ix3))>=0
-               &&(SEB = nodeNumbers(ix1+1, ix2, ix3))>=0
-               &&(NEB = nodeNumbers(ix1+1, ix2+1, ix3))>=0
-               &&(NWB = nodeNumbers(ix1, ix2+1, ix3))>=0
-               &&(SWT = nodeNumbers(ix1, ix2, ix3+1))>=0
-               &&(SET = nodeNumbers(ix1+1, ix2, ix3+1))>=0
-               &&(NET = nodeNumbers(ix1+1, ix2+1, ix3+1))>=0
-               &&(NWT = nodeNumbers(ix1, ix2+1, ix3+1))>=0)
-            {
-               cells.push_back(makeUbTuple(SWB, SEB, NEB, NWB, SWT, SET, NET, NWT));
-            }
-         }
-      }
-   }
-}
+#include "WriteBoundaryConditionsCoProcessor.h"
+#include "LBMKernel.h"
+#include "BCProcessor.h"
+#include <vector>
+#include <string>
+
+#include "basics/writer/WbWriterVtkXmlASCII.h"
+#include "Grid3D.h"
+#include "Block3D.h"
+#include "LBMUnitConverter.h"
+#include "Communicator.h"
+#include "WbWriter.h"
+#include "UbScheduler.h"
+#include "CbArray3D.h"
+#include "BCArray3D.h"
+
+using namespace std;
+
+WriteBoundaryConditionsCoProcessor::WriteBoundaryConditionsCoProcessor()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+WriteBoundaryConditionsCoProcessor::WriteBoundaryConditionsCoProcessor(Grid3DPtr grid, UbSchedulerPtr s,
+   const std::string& path, WbWriter* const writer,
+   LBMUnitConverterPtr conv, CommunicatorPtr comm)
+   : CoProcessor(grid, s),
+   path(path),
+   writer(writer),
+   conv(conv),
+   comm(comm)
+{
+   gridRank = comm->getProcessID();
+   minInitLevel = this->grid->getCoarsestInitializedLevel();
+   maxInitLevel = this->grid->getFinestInitializedLevel();
+
+   blockVector.resize(maxInitLevel+1);
+
+   for (int level = minInitLevel; level<=maxInitLevel; level++)
+   {
+      grid->getBlocks(level, gridRank, true, blockVector[level]);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void WriteBoundaryConditionsCoProcessor::process(double step)
+{
+   if (scheduler->isDue(step))
+      collectData(step);
+
+   UBLOG(logDEBUG3, "WriteBoundaryConditionsCoProcessor::update:"<<step);
+}
+//////////////////////////////////////////////////////////////////////////
+void WriteBoundaryConditionsCoProcessor::collectData(double step)
+{
+   int istep = static_cast<int>(step);
+
+   for (int level = minInitLevel; level<=maxInitLevel; level++)
+   {
+      for(Block3DPtr block : blockVector[level])
+      {
+         if (block)
+         {
+            addDataGeo(block);
+         }
+      }
+   }
+
+   string pfilePath, partPath, subfolder, cfilePath;
+
+   subfolder = "bc"+UbSystem::toString(istep);
+   pfilePath = path+"/bc/"+subfolder;
+   cfilePath = path+"/bc/bc_collection";
+   partPath = pfilePath+"/bc"+UbSystem::toString(gridRank)+"_"+UbSystem::toString(istep);
+
+
+   string partName = writer->writeOctsWithNodeData(partPath, nodes, cells, datanames, data);
+   size_t found = partName.find_last_of("/");
+   string piece = partName.substr(found+1);
+   piece = subfolder+"/"+piece;
+
+   vector<string> cellDataNames;
+   vector<string> pieces = comm->gather(piece);
+   if (comm->getProcessID()==comm->getRoot())
+   {
+      string pname = WbWriterVtkXmlASCII::getInstance()->writeParallelFile(pfilePath, pieces, datanames, cellDataNames);
+      found = pname.find_last_of("/");
+      piece = pname.substr(found+1);
+
+      vector<string> filenames;
+      filenames.push_back(piece);
+      if (step==CoProcessor::scheduler->getMinBegin())
+      {
+         WbWriterVtkXmlASCII::getInstance()->writeCollection(cfilePath, filenames, istep, false);
+      }
+      else
+      {
+         WbWriterVtkXmlASCII::getInstance()->addFilesToCollection(cfilePath, filenames, istep, false);
+      }
+      UBLOG(logINFO, "WriteBoundaryConditionsCoProcessor step: "<<istep);
+   }
+
+   clearData();
+}
+//////////////////////////////////////////////////////////////////////////
+void WriteBoundaryConditionsCoProcessor::clearData()
+{
+   nodes.clear();
+   cells.clear();
+   datanames.clear();
+   data.clear();
+}
+//////////////////////////////////////////////////////////////////////////
+void WriteBoundaryConditionsCoProcessor::addDataGeo(Block3DPtr block)
+{
+   UbTupleDouble3 org = grid->getBlockWorldCoordinates(block);
+   UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
+   UbTupleDouble3 nodeOffset = grid->getNodeOffset(block);
+   double         dx = grid->getDeltaX(block);
+
+   double level = (double)block->getLevel();
+
+   //Diese Daten werden geschrieben:
+   datanames.resize(0);
+   datanames.push_back("Boundary Conditions");
+   datanames.push_back("Geometry");
+   datanames.push_back("Level");
+   //datanames.push_back("Interface CF");
+
+   data.resize(datanames.size());
+
+   ILBMKernelPtr kernel = block->getKernel();
+   BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
+
+   //knotennummerierung faengt immer bei 0 an!
+   int SWB, SEB, NEB, NWB, SWT, SET, NET, NWT;
+
+   int minX1 = 0;
+   int minX2 = 0;
+   int minX3 = 0;
+
+   int maxX1 = (int)bcArray->getNX1();
+   int maxX2 = (int)bcArray->getNX2();
+   int maxX3 = (int)bcArray->getNX3();
+
+   //nummern vergeben und node vector erstellen + daten sammeln
+   CbArray3D<int> nodeNumbers((int)maxX1, (int)maxX2, (int)maxX3, -1);
+   //D3Q27BoundaryConditionPtr bcPtr;
+   int nr = (int)nodes.size();
+
+   maxX1 -= 1;
+   maxX2 -= 1;
+   maxX3 -= 1;
+
+   int s=0;
+
+   
+
+   for (size_t ix3 = minX3; ix3<=maxX3; ix3++)
+   {
+      for (size_t ix2 = minX2; ix2<=maxX2; ix2++)
+      {
+         for (size_t ix1 = minX1; ix1<=maxX1; ix1++)
+         {
+            if (!bcArray->isUndefined(ix1, ix2, ix3))
+            {
+               //int index = 0;
+               nodeNumbers(ix1, ix2, ix3) = nr++;
+               nodes.push_back(makeUbTuple(float(val<1>(org)-val<1>(nodeOffset)+ix1*dx),
+                  float(val<2>(org)-val<2>(nodeOffset)+ix2*dx),
+                  float(val<3>(org)-val<3>(nodeOffset)+ix3*dx)));
+
+
+
+               if (!bcArray->hasBC(ix1, ix2, ix3))
+               {
+                  data[0].push_back(0.0);
+               }
+               else if (bcArray->getBC(ix1, ix2, ix3)->hasNoSlipBoundary())
+                  data[0].push_back(1.0);
+               else if (bcArray->getBC(ix1, ix2, ix3)->hasVelocityBoundary())
+                  data[0].push_back(2.0);
+               else if (bcArray->getBC(ix1, ix2, ix3)->hasDensityBoundary())
+                  data[0].push_back(3.0);
+               else if (bcArray->getBC(ix1, ix2, ix3)->hasSlipBoundary())
+                  data[0].push_back(4.0);
+               else
+                  data[0].push_back(5.0);
+
+
+               if (bcArray->isSolid(ix1, ix2, ix3))
+               {
+                  data[1].push_back(1.0);
+               }
+               else
+               {
+                  data[1].push_back(0.0);
+               }
+                  
+
+               data[2].push_back(level);
+
+               //if (bcArray->isInterfaceCF(ix1, ix2, ix3))
+               //{
+               //   data[3].push_back(1.0);
+               //} 
+               //else
+               //{
+               //   data[3].push_back(0.0);
+               //}
+
+            }
+         }
+      }
+   }
+
+   maxX1 -= 1;
+   maxX2 -= 1;
+   maxX3 -= 1;
+
+   //cell vector erstellen
+   for (int ix3 = minX3; ix3<=maxX3; ix3++)
+   {
+      for (int ix2 = minX2; ix2<=maxX2; ix2++)
+      {
+         for (int ix1 = minX1; ix1<=maxX1; ix1++)
+         {
+            if ((SWB = nodeNumbers(ix1, ix2, ix3))>=0
+               &&(SEB = nodeNumbers(ix1+1, ix2, ix3))>=0
+               &&(NEB = nodeNumbers(ix1+1, ix2+1, ix3))>=0
+               &&(NWB = nodeNumbers(ix1, ix2+1, ix3))>=0
+               &&(SWT = nodeNumbers(ix1, ix2, ix3+1))>=0
+               &&(SET = nodeNumbers(ix1+1, ix2, ix3+1))>=0
+               &&(NET = nodeNumbers(ix1+1, ix2+1, ix3+1))>=0
+               &&(NWT = nodeNumbers(ix1, ix2+1, ix3+1))>=0)
+            {
+               cells.push_back(makeUbTuple(SWB, SEB, NEB, NWB, SWT, SET, NET, NWT));
+            }
+         }
+      }
+   }
+}
diff --git a/source/VirtualFluidsCore/CoProcessors/WriteBoundaryConditionsCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/WriteBoundaryConditionsCoProcessor.h
index 5fa07449d..bc695378a 100644
--- a/source/VirtualFluidsCore/CoProcessors/WriteBoundaryConditionsCoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/WriteBoundaryConditionsCoProcessor.h
@@ -1,30 +1,38 @@
 #ifndef WriteBoundaryConditionsCoProcessor_H
 #define WriteBoundaryConditionsCoProcessor_H
 
+#include <memory>
+#include <string>
+#include <vector>
+
 #include "CoProcessor.h"
-#include "Grid3D.h"
-#include "Block3D.h"
-#include "LBMUnitConverter.h"
-#include "Communicator.h"
-#include "WbWriter.h"
 
-#include <boost/shared_ptr.hpp>
+class Communicator;
+class Grid3D;
+class UbScheduler;
+class WbWriter;
+class Block3D;
+class LBMUnitConverter;
+
 class WriteBoundaryConditionsCoProcessor;
-typedef boost::shared_ptr<WriteBoundaryConditionsCoProcessor> WriteBoundaryConditionsCoProcessorPtr;
+typedef std::shared_ptr<WriteBoundaryConditionsCoProcessor> WriteBoundaryConditionsCoProcessorPtr;
 
 class WriteBoundaryConditionsCoProcessor : public  CoProcessor
 {
 public:
    WriteBoundaryConditionsCoProcessor();
-   WriteBoundaryConditionsCoProcessor(Grid3DPtr grid, UbSchedulerPtr s,
+   WriteBoundaryConditionsCoProcessor(std::shared_ptr<Grid3D> grid, std::shared_ptr<UbScheduler> s,
       const std::string& path, WbWriter* const writer,
-      LBMUnitConverterPtr conv, CommunicatorPtr comm);
+       std::shared_ptr<LBMUnitConverter> conv, std::shared_ptr<Communicator> comm);
    ~WriteBoundaryConditionsCoProcessor() {}
-   void process(double step);
+
+   void process(double step) override;
+
 protected:
    void collectData(double step);
-   void addDataGeo(Block3DPtr block);
+   void addDataGeo(std::shared_ptr<Block3D> block);
    void clearData();
+
 private:
    std::vector<UbTupleFloat3> nodes;
    std::vector<UbTupleInt8> cells;
@@ -32,13 +40,13 @@ private:
    std::vector<std::vector<double> > data;
    std::string path;
    WbWriter* writer;
-   LBMUnitConverterPtr conv;
+   std::shared_ptr<LBMUnitConverter> conv;
    bool bcInformation;
-   std::vector<std::vector<Block3DPtr> > blockVector;
+   std::vector<std::vector<std::shared_ptr<Block3D> > > blockVector;
    int minInitLevel;
    int maxInitLevel;
    int gridRank;
-   CommunicatorPtr comm;
+   std::shared_ptr<Communicator> comm;
 
    friend class boost::serialization::access;
    template<class Archive>
diff --git a/source/VirtualFluidsCore/CoProcessors/WriteMacroscopicQuantitiesCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/WriteMacroscopicQuantitiesCoProcessor.cpp
index 48404ed68..b474de985 100644
--- a/source/VirtualFluidsCore/CoProcessors/WriteMacroscopicQuantitiesCoProcessor.cpp
+++ b/source/VirtualFluidsCore/CoProcessors/WriteMacroscopicQuantitiesCoProcessor.cpp
@@ -1,257 +1,258 @@
-#include "WriteMacroscopicQuantitiesCoProcessor.h"
-#include "LBMKernel.h"
-#include "BCProcessor.h"
-#include <vector>
-#include <string>
-#include <boost/foreach.hpp>
-#include "basics/writer/WbWriterVtkXmlASCII.h"
-
-using namespace std;
-
-WriteMacroscopicQuantitiesCoProcessor::WriteMacroscopicQuantitiesCoProcessor()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-WriteMacroscopicQuantitiesCoProcessor::WriteMacroscopicQuantitiesCoProcessor(Grid3DPtr grid, UbSchedulerPtr s,
-                                                                                 const std::string& path, WbWriter* const writer, 
-                                                                                 LBMUnitConverterPtr conv, 
-                                                                                 CommunicatorPtr comm)
-                                                                                 : CoProcessor(grid, s),
-                                                                                 path(path),
-                                                                                 writer(writer),
-                                                                                 conv(conv),
-                                                                                 comm(comm)
-{
-   gridRank = comm->getProcessID();
-   minInitLevel = this->grid->getCoarsestInitializedLevel();
-   maxInitLevel = this->grid->getFinestInitializedLevel();
-
-   blockVector.resize(maxInitLevel+1);
-
-   for (int level = minInitLevel; level<=maxInitLevel; level++)
-   {
-      grid->getBlocks(level, gridRank, true, blockVector[level]);
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void WriteMacroscopicQuantitiesCoProcessor::init()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-void WriteMacroscopicQuantitiesCoProcessor::process(double step)
-{
-   if(scheduler->isDue(step) )
-      collectData(step);
-
-   UBLOG(logDEBUG3, "WriteMacroscopicQuantitiesCoProcessor::update:" << step);
-}
-//////////////////////////////////////////////////////////////////////////
-void WriteMacroscopicQuantitiesCoProcessor::collectData(double step)
-{
-   int istep = static_cast<int>(step);
-
-   for(int level = minInitLevel; level<=maxInitLevel;level++)
-   {
-      BOOST_FOREACH(Block3DPtr block, blockVector[level])
-      {
-         if (block)
-         {
-            addDataMQ(block);
-         }
-      }
-   }
-
-   string pfilePath, partPath, subfolder, cfilePath;
-
-      subfolder = "mq"+UbSystem::toString(istep);
-      pfilePath =  path+"/mq/"+subfolder;
-      cfilePath =  path+"/mq/mq_collection";
-      partPath = pfilePath+"/mq"+UbSystem::toString(gridRank)+ "_" + UbSystem::toString(istep);
-
-
-   string partName = writer->writeOctsWithNodeData(partPath,nodes,cells,datanames,data);
-   size_t found=partName.find_last_of("/");
-   string piece = partName.substr(found+1);
-   piece = subfolder + "/" + piece;
-
-   vector<string> cellDataNames;
-   CommunicatorPtr comm = Communicator::getInstance();
-   vector<string> pieces = comm->gather(piece);
-   if (comm->getProcessID() == comm->getRoot())
-   {
-      string pname = WbWriterVtkXmlASCII::getInstance()->writeParallelFile(pfilePath,pieces,datanames,cellDataNames);
-      found=pname.find_last_of("/");
-      piece = pname.substr(found+1);
-
-      vector<string> filenames;
-      filenames.push_back(piece);
-      if (step == CoProcessor::scheduler->getMinBegin())
-      {
-         WbWriterVtkXmlASCII::getInstance()->writeCollection(cfilePath,filenames,istep,false);
-      } 
-      else
-      {
-         WbWriterVtkXmlASCII::getInstance()->addFilesToCollection(cfilePath,filenames,istep,false);
-      }
-      UBLOG(logINFO,"WriteMacroscopicQuantitiesCoProcessor step: " << istep);
-   }
-
-   clearData();
-}
-//////////////////////////////////////////////////////////////////////////
-void WriteMacroscopicQuantitiesCoProcessor::clearData()
-{
-   nodes.clear();
-   cells.clear();
-   datanames.clear();
-   data.clear();
-}
-//////////////////////////////////////////////////////////////////////////
-void WriteMacroscopicQuantitiesCoProcessor::addDataMQ(Block3DPtr block)
-{
-   UbTupleDouble3 org          = grid->getBlockWorldCoordinates(block);
-   UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
-   UbTupleDouble3 nodeOffset   = grid->getNodeOffset(block);
-   double         dx           = grid->getDeltaX(block);
-
-   double level = (double)block->getLevel();
-   double blockID = (double)block->getGlobalID();
-
-   //Diese Daten werden geschrieben:
-   datanames.resize(0);
-   datanames.push_back("Rho");
-   datanames.push_back("Vx");
-   datanames.push_back("Vy");
-   datanames.push_back("Vz");
-   //datanames.push_back("Press");
-   datanames.push_back("Level");
-   //datanames.push_back("BlockID");
-
-     
-
-   data.resize(datanames.size());
-
-   LBMKernelPtr kernel = block->getKernel();
-   BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
-   DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();     
-   LBMReal f[D3Q27System::ENDF+1];
-   LBMReal vx1,vx2,vx3,rho;
-
-   //knotennummerierung faengt immer bei 0 an!
-   int SWB,SEB,NEB,NWB,SWT,SET,NET,NWT;
-
-   if(block->getKernel()->getCompressible())
-   {
-      calcMacros = &D3Q27System::calcCompMacroscopicValues;
-   }
-   else
-   {
-      calcMacros = &D3Q27System::calcIncompMacroscopicValues;
-   }
-
-   int minX1 = 0;
-   int minX2 = 0;
-   int minX3 = 0;
-
-   int maxX1 = (int)(distributions->getNX1());
-   int maxX2 = (int)(distributions->getNX2());
-   int maxX3 = (int)(distributions->getNX3());
-
-   //int minX1 = 1;
-   //int minX2 = 1;
-   //int minX3 = 1;
-
-   //int maxX1 = (int)(distributions->getNX1());
-   //int maxX2 = (int)(distributions->getNX2());
-   //int maxX3 = (int)(distributions->getNX3());
-
-   //nummern vergeben und node vector erstellen + daten sammeln
-   CbArray3D<int> nodeNumbers((int)maxX1, (int)maxX2, (int)maxX3,-1);
-   maxX1 -= 2;
-   maxX2 -= 2;
-   maxX3 -= 2;
-
-   //D3Q27BoundaryConditionPtr bcPtr;
-   int nr = (int)nodes.size();
- 
-   for(size_t ix3=minX3; ix3<=maxX3; ix3++)
-   {
-      for(size_t ix2=minX2; ix2<=maxX2; ix2++)
-      {
-         for(size_t ix1=minX1; ix1<=maxX1; ix1++)
-         {
-            if(!bcArray->isUndefined(ix1,ix2,ix3) && !bcArray->isSolid(ix1,ix2,ix3))
-            {
-               int index = 0;
-               nodeNumbers(ix1,ix2,ix3) = nr++;
-               nodes.push_back( makeUbTuple(float(val<1>(org) - val<1>(nodeOffset) + ix1*dx),
-                                            float(val<2>(org) - val<2>(nodeOffset) + ix2*dx),
-                                            float(val<3>(org) - val<3>(nodeOffset) + ix3*dx)) );
-
-               distributions->getDistribution(f, ix1, ix2, ix3);
-               calcMacros(f,rho,vx1,vx2,vx3);
-               //double press = D3Q27System::calcPress(f,rho,vx1,vx2,vx3);
-
-               if (UbMath::isNaN(rho) || UbMath::isInfinity(rho)) 
-                  UB_THROW( UbException(UB_EXARGS,"rho is not a number (nan or -1.#IND) or infinity number -1.#INF in block="+block->toString()+
-                   ", node="+UbSystem::toString(ix1)+","+UbSystem::toString(ix2)+","+UbSystem::toString(ix3)));
-                     //rho=999.0;
-               //if (UbMath::isNaN(press) || UbMath::isInfinity(press)) 
-               //   UB_THROW( UbException(UB_EXARGS,"press is not a number (nan or -1.#IND) or infinity number -1.#INF in block="+block->toString()+
-               //   ", node="+UbSystem::toString(ix1)+","+UbSystem::toString(ix2)+","+UbSystem::toString(ix3)));
-                  //press=999.0;
-               if (UbMath::isNaN(vx1) || UbMath::isInfinity(vx1)) 
-                  UB_THROW( UbException(UB_EXARGS,"vx1 is not a number (nan or -1.#IND) or infinity number -1.#INF in block="+block->toString()+
-                  ", node="+UbSystem::toString(ix1)+","+UbSystem::toString(ix2)+","+UbSystem::toString(ix3)));
-                     //vx1=999.0;
-               if (UbMath::isNaN(vx2) || UbMath::isInfinity(vx2)) 
-                  UB_THROW( UbException(UB_EXARGS,"vx2 is not a number (nan or -1.#IND) or infinity number -1.#INF in block="+block->toString()+
-                  ", node="+UbSystem::toString(ix1)+","+UbSystem::toString(ix2)+","+UbSystem::toString(ix3)));
-                     //vx2=999.0;
-               if (UbMath::isNaN(vx3) || UbMath::isInfinity(vx3)) 
-                  UB_THROW( UbException(UB_EXARGS,"vx3 is not a number (nan or -1.#IND) or infinity number -1.#INF in block="+block->toString()+
-                  ", node="+UbSystem::toString(ix1)+","+UbSystem::toString(ix2)+","+UbSystem::toString(ix3)));
-
-               data[index++].push_back(rho);
-               data[index++].push_back(vx1);
-               data[index++].push_back(vx2);
-               data[index++].push_back(vx3);
-               
-               //data[index++].push_back(rho * conv->getFactorDensityLbToW2() );
-               //data[index++].push_back(vx1 * conv->getFactorVelocityLbToW2());
-               //data[index++].push_back(vx2 * conv->getFactorVelocityLbToW2());
-               //data[index++].push_back(vx3 * conv->getFactorVelocityLbToW2());
-               //data[index++].push_back(press * conv->getFactorPressureLbToW2());
-               data[index++].push_back(level);
-               //data[index++].push_back(blockID);
-            }
-         }
-      }
-   }
-   maxX1 -= 1;
-   maxX2 -= 1;
-   maxX3 -= 1;
-   //cell vector erstellen
-   for(int ix3=minX3; ix3<=maxX3; ix3++)
-   {
-      for(int ix2=minX2; ix2<=maxX2; ix2++)
-      {
-         for(int ix1=minX1; ix1<=maxX1; ix1++)
-         {
-            if(   (SWB=nodeNumbers( ix1  , ix2,   ix3   )) >= 0
-               && (SEB=nodeNumbers( ix1+1, ix2,   ix3   )) >= 0
-               && (NEB=nodeNumbers( ix1+1, ix2+1, ix3   )) >= 0
-               && (NWB=nodeNumbers( ix1  , ix2+1, ix3   )) >= 0 
-               && (SWT=nodeNumbers( ix1  , ix2,   ix3+1 )) >= 0
-               && (SET=nodeNumbers( ix1+1, ix2,   ix3+1 )) >= 0
-               && (NET=nodeNumbers( ix1+1, ix2+1, ix3+1 )) >= 0
-               && (NWT=nodeNumbers( ix1  , ix2+1, ix3+1 )) >= 0                )
-            {
-               cells.push_back( makeUbTuple(SWB,SEB,NEB,NWB,SWT,SET,NET,NWT) );
-            }
-         }
-      }
-   }
-}
+#include "WriteMacroscopicQuantitiesCoProcessor.h"
+#include "LBMKernel.h"
+#include "BCProcessor.h"
+#include <vector>
+#include <string>
+
+#include "basics/writer/WbWriterVtkXmlASCII.h"
+#include "DataSet3D.h"
+#include "UbScheduler.h"
+#include "Grid3D.h"
+#include "Communicator.h"
+#include "LBMUnitConverter.h"
+#include "Block3D.h"
+#include "BCArray3D.h"
+
+WriteMacroscopicQuantitiesCoProcessor::WriteMacroscopicQuantitiesCoProcessor()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+WriteMacroscopicQuantitiesCoProcessor::WriteMacroscopicQuantitiesCoProcessor(Grid3DPtr grid, UbSchedulerPtr s,
+                                                                                 const std::string& path, WbWriter* const writer, 
+                                                                                 LBMUnitConverterPtr conv, 
+                                                                                 CommunicatorPtr comm)
+                                                                                 : CoProcessor(grid, s),
+                                                                                 path(path),
+                                                                                 writer(writer),
+                                                                                 conv(conv),
+                                                                                 comm(comm)
+{
+   gridRank = comm->getProcessID();
+   minInitLevel = this->grid->getCoarsestInitializedLevel();
+   maxInitLevel = this->grid->getFinestInitializedLevel();
+
+   blockVector.resize(maxInitLevel+1);
+
+   for (int level = minInitLevel; level<=maxInitLevel; level++)
+   {
+      grid->getBlocks(level, gridRank, true, blockVector[level]);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void WriteMacroscopicQuantitiesCoProcessor::init()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void WriteMacroscopicQuantitiesCoProcessor::process(double step)
+{
+   if(scheduler->isDue(step) )
+      collectData(step);
+
+   UBLOG(logDEBUG3, "WriteMacroscopicQuantitiesCoProcessor::update:" << step);
+}
+//////////////////////////////////////////////////////////////////////////
+void WriteMacroscopicQuantitiesCoProcessor::collectData(double step)
+{
+   int istep = static_cast<int>(step);
+
+   for(int level = minInitLevel; level<=maxInitLevel;level++)
+   {
+      for(Block3DPtr block : blockVector[level])
+      {
+         if (block)
+         {
+            addDataMQ(block);
+         }
+      }
+   }
+
+   std::string pfilePath, partPath, subfolder, cfilePath;
+
+      subfolder = "mq"+UbSystem::toString(istep);
+      pfilePath =  path+"/mq/"+subfolder;
+      cfilePath =  path+"/mq/mq_collection";
+      partPath = pfilePath+"/mq"+UbSystem::toString(gridRank)+ "_" + UbSystem::toString(istep);
+
+
+   std::string partName = writer->writeOctsWithNodeData(partPath,nodes,cells,datanames,data);
+   size_t found=partName.find_last_of("/");
+   std::string piece = partName.substr(found+1);
+   piece = subfolder + "/" + piece;
+
+   std::vector<std::string> cellDataNames;
+   CommunicatorPtr comm = Communicator::getInstance();
+   std::vector<std::string> pieces = comm->gather(piece);
+   if (comm->getProcessID() == comm->getRoot())
+   {
+      std::string pname = WbWriterVtkXmlASCII::getInstance()->writeParallelFile(pfilePath,pieces,datanames,cellDataNames);
+      found=pname.find_last_of("/");
+      piece = pname.substr(found+1);
+
+      std::vector<std::string> filenames;
+      filenames.push_back(piece);
+      if (step == CoProcessor::scheduler->getMinBegin())
+      {
+         WbWriterVtkXmlASCII::getInstance()->writeCollection(cfilePath,filenames,istep,false);
+      } 
+      else
+      {
+         WbWriterVtkXmlASCII::getInstance()->addFilesToCollection(cfilePath,filenames,istep,false);
+      }
+      UBLOG(logINFO,"WriteMacroscopicQuantitiesCoProcessor step: " << istep);
+   }
+
+   clearData();
+}
+//////////////////////////////////////////////////////////////////////////
+void WriteMacroscopicQuantitiesCoProcessor::clearData()
+{
+   nodes.clear();
+   cells.clear();
+   datanames.clear();
+   data.clear();
+}
+//////////////////////////////////////////////////////////////////////////
+void WriteMacroscopicQuantitiesCoProcessor::addDataMQ(Block3DPtr block)
+{
+   double level = (double)block->getLevel();
+   double blockID = (double)block->getGlobalID();
+
+   //Diese Daten werden geschrieben:
+   datanames.resize(0);
+   datanames.push_back("Rho");
+   datanames.push_back("Vx");
+   datanames.push_back("Vy");
+   datanames.push_back("Vz");
+   //datanames.push_back("Press");
+   datanames.push_back("Level");
+   //datanames.push_back("BlockID");
+
+     
+
+   data.resize(datanames.size());
+
+   ILBMKernelPtr kernel = block->getKernel();
+   BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();          
+   DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();     
+   LBMReal f[D3Q27System::ENDF+1];
+   LBMReal vx1,vx2,vx3,rho;
+
+   //knotennummerierung faengt immer bei 0 an!
+   int SWB,SEB,NEB,NWB,SWT,SET,NET,NWT;
+
+   if(block->getKernel()->getCompressible())
+   {
+      calcMacros = &D3Q27System::calcCompMacroscopicValues;
+   }
+   else
+   {
+      calcMacros = &D3Q27System::calcIncompMacroscopicValues;
+   }
+
+   int minX1 = 0;
+   int minX2 = 0;
+   int minX3 = 0;
+
+   int maxX1 = (int)(distributions->getNX1());
+   int maxX2 = (int)(distributions->getNX2());
+   int maxX3 = (int)(distributions->getNX3());
+
+   //int minX1 = 1;
+   //int minX2 = 1;
+   //int minX3 = 1;
+
+   //int maxX1 = (int)(distributions->getNX1());
+   //int maxX2 = (int)(distributions->getNX2());
+   //int maxX3 = (int)(distributions->getNX3());
+
+   //nummern vergeben und node vector erstellen + daten sammeln
+   CbArray3D<int> nodeNumbers((int)maxX1, (int)maxX2, (int)maxX3,-1);
+   maxX1 -= 2;
+   maxX2 -= 2;
+   maxX3 -= 2;
+
+   //D3Q27BoundaryConditionPtr bcPtr;
+   int nr = (int)nodes.size();
+ 
+   for(size_t ix3=minX3; ix3<=maxX3; ix3++)
+   {
+      for(size_t ix2=minX2; ix2<=maxX2; ix2++)
+      {
+         for(size_t ix1=minX1; ix1<=maxX1; ix1++)
+         {
+            if(!bcArray->isUndefined(ix1,ix2,ix3) && !bcArray->isSolid(ix1,ix2,ix3))
+            {
+               int index = 0;
+               nodeNumbers(ix1,ix2,ix3) = nr++;
+               Vector3D worldCoordinates = grid->getNodeCoordinates(block, ix1, ix2, ix3);
+               nodes.push_back( UbTupleFloat3(float(worldCoordinates[0]),
+                                              float(worldCoordinates[1]),
+                                              float(worldCoordinates[2]) ));
+
+               distributions->getDistribution(f, ix1, ix2, ix3);
+               calcMacros(f,rho,vx1,vx2,vx3);
+               //double press = D3Q27System::calcPress(f,rho,vx1,vx2,vx3);
+
+               if (UbMath::isNaN(rho) || UbMath::isInfinity(rho)) 
+                  UB_THROW( UbException(UB_EXARGS,"rho is not a number (nan or -1.#IND) or infinity number -1.#INF in block="+block->toString()+
+                   ", node="+UbSystem::toString(ix1)+","+UbSystem::toString(ix2)+","+UbSystem::toString(ix3)));
+                     //rho=999.0;
+               //if (UbMath::isNaN(press) || UbMath::isInfinity(press)) 
+               //   UB_THROW( UbException(UB_EXARGS,"press is not a number (nan or -1.#IND) or infinity number -1.#INF in block="+block->toString()+
+               //   ", node="+UbSystem::toString(ix1)+","+UbSystem::toString(ix2)+","+UbSystem::toString(ix3)));
+                  //press=999.0;
+               if (UbMath::isNaN(vx1) || UbMath::isInfinity(vx1)) 
+                  UB_THROW( UbException(UB_EXARGS,"vx1 is not a number (nan or -1.#IND) or infinity number -1.#INF in block="+block->toString()+
+                  ", node="+UbSystem::toString(ix1)+","+UbSystem::toString(ix2)+","+UbSystem::toString(ix3)));
+                     //vx1=999.0;
+               if (UbMath::isNaN(vx2) || UbMath::isInfinity(vx2)) 
+                  UB_THROW( UbException(UB_EXARGS,"vx2 is not a number (nan or -1.#IND) or infinity number -1.#INF in block="+block->toString()+
+                  ", node="+UbSystem::toString(ix1)+","+UbSystem::toString(ix2)+","+UbSystem::toString(ix3)));
+                     //vx2=999.0;
+               if (UbMath::isNaN(vx3) || UbMath::isInfinity(vx3)) 
+                  UB_THROW( UbException(UB_EXARGS,"vx3 is not a number (nan or -1.#IND) or infinity number -1.#INF in block="+block->toString()+
+                  ", node="+UbSystem::toString(ix1)+","+UbSystem::toString(ix2)+","+UbSystem::toString(ix3)));
+
+               data[index++].push_back(rho);
+               data[index++].push_back(vx1);
+               data[index++].push_back(vx2);
+               data[index++].push_back(vx3);
+               
+               //data[index++].push_back(rho * conv->getFactorDensityLbToW2() );
+               //data[index++].push_back(vx1 * conv->getFactorVelocityLbToW2());
+               //data[index++].push_back(vx2 * conv->getFactorVelocityLbToW2());
+               //data[index++].push_back(vx3 * conv->getFactorVelocityLbToW2());
+               //data[index++].push_back(press * conv->getFactorPressureLbToW2());
+               data[index++].push_back(level);
+               //data[index++].push_back(blockID);
+            }
+         }
+      }
+   }
+   maxX1 -= 1;
+   maxX2 -= 1;
+   maxX3 -= 1;
+   //cell vector erstellen
+   for(int ix3=minX3; ix3<=maxX3; ix3++)
+   {
+      for(int ix2=minX2; ix2<=maxX2; ix2++)
+      {
+         for(int ix1=minX1; ix1<=maxX1; ix1++)
+         {
+            if(   (SWB=nodeNumbers( ix1  , ix2,   ix3   )) >= 0
+               && (SEB=nodeNumbers( ix1+1, ix2,   ix3   )) >= 0
+               && (NEB=nodeNumbers( ix1+1, ix2+1, ix3   )) >= 0
+               && (NWB=nodeNumbers( ix1  , ix2+1, ix3   )) >= 0 
+               && (SWT=nodeNumbers( ix1  , ix2,   ix3+1 )) >= 0
+               && (SET=nodeNumbers( ix1+1, ix2,   ix3+1 )) >= 0
+               && (NET=nodeNumbers( ix1+1, ix2+1, ix3+1 )) >= 0
+               && (NWT=nodeNumbers( ix1  , ix2+1, ix3+1 )) >= 0                )
+            {
+               cells.push_back( makeUbTuple(SWB,SEB,NEB,NWB,SWT,SET,NET,NWT) );
+            }
+         }
+      }
+   }
+}
diff --git a/source/VirtualFluidsCore/CoProcessors/WriteMacroscopicQuantitiesCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/WriteMacroscopicQuantitiesCoProcessor.h
index 798c9be0b..ef1eb436c 100644
--- a/source/VirtualFluidsCore/CoProcessors/WriteMacroscopicQuantitiesCoProcessor.h
+++ b/source/VirtualFluidsCore/CoProcessors/WriteMacroscopicQuantitiesCoProcessor.h
@@ -1,32 +1,41 @@
 #ifndef D3Q27MACROSCOPICQUANTITIESCoProcessor_H
 #define D3Q27MACROSCOPICQUANTITIESCoProcessor_H
 
+#include <memory>
+#include <string>
+#include <vector>
+
 #include "CoProcessor.h"
-#include "Grid3D.h"
-#include "Block3D.h"
-#include "LBMUnitConverter.h"
-#include "Communicator.h"
-#include "WbWriter.h"
 
-#include <boost/shared_ptr.hpp>
+#include "LBMSystem.h"
+
+class Communicator;
+class Grid3D;
+class UbScheduler;
+class LBMUnitConverter;
+class WbWriter;
+class Block3D;
+
 class WriteMacroscopicQuantitiesCoProcessor;
-typedef boost::shared_ptr<WriteMacroscopicQuantitiesCoProcessor> MacroscopicQuantitiesCoProcessorPtr;
+typedef std::shared_ptr<WriteMacroscopicQuantitiesCoProcessor> MacroscopicQuantitiesCoProcessorPtr;
 
-class WriteMacroscopicQuantitiesCoProcessor : public  CoProcessor 
+class WriteMacroscopicQuantitiesCoProcessor : public CoProcessor 
 {
 public:
    WriteMacroscopicQuantitiesCoProcessor();
-   WriteMacroscopicQuantitiesCoProcessor(Grid3DPtr grid, UbSchedulerPtr s, 
+   WriteMacroscopicQuantitiesCoProcessor(std::shared_ptr<Grid3D> grid, std::shared_ptr<UbScheduler> s,
                                            const std::string& path, WbWriter* const writer, 
-                                           LBMUnitConverterPtr conv,  
-                                           CommunicatorPtr comm);
+                                           std::shared_ptr<LBMUnitConverter> conv, std::shared_ptr<Communicator> comm);
    ~WriteMacroscopicQuantitiesCoProcessor(){}
-   void process(double step);
+
+   void process(double step) override;
+
 protected:
    void collectData(double step);
-   void addDataMQ(Block3DPtr block);
-   void addDataGeo(Block3DPtr block);
+   void addDataMQ(std::shared_ptr<Block3D> block);
+   void addDataGeo(std::shared_ptr<Block3D> block);
    void clearData();
+
 private:
    void init();
    std::vector<UbTupleFloat3> nodes;
@@ -35,13 +44,13 @@ private:
    std::vector<std::vector<double> > data; 
    std::string path;
    WbWriter* writer;
-   LBMUnitConverterPtr conv;
+   std::shared_ptr<LBMUnitConverter> conv;
    bool bcInformation;
-   std::vector<std::vector<Block3DPtr> > blockVector;
+   std::vector<std::vector<std::shared_ptr<Block3D> > > blockVector;
    int minInitLevel;
    int maxInitLevel;
    int gridRank;
-   CommunicatorPtr comm;
+   std::shared_ptr<Communicator> comm;
 
    typedef void(*CalcMacrosFct)(const LBMReal* const& /*feq[27]*/, LBMReal& /*(d)rho*/, LBMReal& /*vx1*/, LBMReal& /*vx2*/, LBMReal& /*vx3*/);
    CalcMacrosFct calcMacros;
@@ -60,4 +69,5 @@ private:
    //   ar & writer;
    //}
 };
+
 #endif
diff --git a/source/VirtualFluidsCore/CoProcessors/WriteObjectsCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/WriteObjectsCoProcessor.cpp
new file mode 100644
index 000000000..337525ef1
--- /dev/null
+++ b/source/VirtualFluidsCore/CoProcessors/WriteObjectsCoProcessor.cpp
@@ -0,0 +1,52 @@
+#include "WriteObjectsCoProcessor.h"
+#include "LBMKernel.h"
+#include "BCProcessor.h"
+
+#include "basics/writer/WbWriterVtkXmlBinary.h"
+#include "basics/writer/WbWriterVtkXmlASCII.h"
+
+#include "GbSphere3D.h"
+#include "Communicator.h"
+#include "UbScheduler.h"
+#include "Grid3D.h"
+
+WriteObjectsCoProcessor::WriteObjectsCoProcessor()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+WriteObjectsCoProcessor::WriteObjectsCoProcessor(Grid3DPtr grid, UbSchedulerPtr s,
+   const std::string& path, CommunicatorPtr comm)
+   : CoProcessor(grid, s),
+   path(path),
+   comm(comm)
+{
+    this->path += "/geo/objects/sphere";
+}
+
+
+void WriteObjectsCoProcessor::addGbObject(GbSphere3DPtr sphere)
+{
+    objects.push_back(sphere);
+}
+
+void WriteObjectsCoProcessor::process(double step)
+{
+   if (scheduler->isDue(step))
+   {
+       std::vector<UbTupleFloat3> nodes;
+       std::vector<UbTupleInt3>   triangles;
+
+       for (size_t i = 0; i < objects.size(); i++)
+       {
+           objects[i]->addSurfaceTriangleSet(nodes, triangles);
+  
+
+       }
+       int stepInt = (int)step;
+       std::string outFilename = WbWriterVtkXmlBinary::getInstance()->writeTriangles(path + std::to_string(stepInt), nodes, triangles);
+
+   }
+     
+
+}
diff --git a/source/VirtualFluidsCore/CoProcessors/WriteObjectsCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/WriteObjectsCoProcessor.h
new file mode 100644
index 000000000..cf7d3a84b
--- /dev/null
+++ b/source/VirtualFluidsCore/CoProcessors/WriteObjectsCoProcessor.h
@@ -0,0 +1,45 @@
+/*
+*  Author: S. Peters
+*  mail: peters@irmb.tu-bs.de
+*/
+#ifndef WriteObjectsCoProcessor_H
+#define WriteObjectsCoProcessor_H
+
+#include <memory>
+#include <string>
+#include <memory>
+
+#include "CoProcessor.h"
+
+class GbSphere3D;
+class Communicator;
+class Grid3D;
+class UbScheduler;
+
+class WriteObjectsCoProcessor;
+typedef std::shared_ptr<WriteObjectsCoProcessor> WriteObjectsCoProcessorPtr;
+
+class WriteObjectsCoProcessor : public  CoProcessor
+{
+public:
+    WriteObjectsCoProcessor();
+    WriteObjectsCoProcessor(std::shared_ptr<Grid3D> grid, std::shared_ptr<UbScheduler> s, const std::string& path, std::shared_ptr<Communicator> comm);
+   ~WriteObjectsCoProcessor() {}
+   void process(double step) override;
+
+   void addGbObject(std::shared_ptr<GbSphere3D> sphere);
+
+private:
+    std::string path;
+    std::shared_ptr<Communicator> comm;
+
+    std::vector<std::shared_ptr<GbSphere3D> > objects;
+
+   friend class boost::serialization::access;
+   template<class Archive>
+   void serialize(Archive & ar, const unsigned int version)
+   {
+
+   }
+};
+#endif
diff --git a/source/VirtualFluidsCore/Connectors/Block3DConnector.h b/source/VirtualFluidsCore/Connectors/Block3DConnector.h
index 95a15b1c0..481a1d4f6 100644
--- a/source/VirtualFluidsCore/Connectors/Block3DConnector.h
+++ b/source/VirtualFluidsCore/Connectors/Block3DConnector.h
@@ -12,10 +12,10 @@
 
 #include <basics/utilities/UbTuple.h>
 
-#include <boost/shared_ptr.hpp>
+#include <memory>
 
 class Block3DConnector;
-typedef boost::shared_ptr<Block3DConnector> Block3DConnectorPtr;
+typedef std::shared_ptr<Block3DConnector> Block3DConnectorPtr;
 
 class Block3DConnector
 {
diff --git a/source/VirtualFluidsCore/Connectors/Block3DConnectorFactory.h b/source/VirtualFluidsCore/Connectors/Block3DConnectorFactory.h
index dd4df79e3..684db540e 100644
--- a/source/VirtualFluidsCore/Connectors/Block3DConnectorFactory.h
+++ b/source/VirtualFluidsCore/Connectors/Block3DConnectorFactory.h
@@ -3,9 +3,9 @@
 
 #include "ConnectorFactory.h"
 
-#include <boost/shared_ptr.hpp>
+#include <memory>
 class Block3DConnectorFactory;
-typedef boost::shared_ptr<Block3DConnectorFactory> Block3DConnectorFactoryPtr;
+typedef std::shared_ptr<Block3DConnectorFactory> Block3DConnectorFactoryPtr;
 
 class Block3DConnectorFactory : public ConnectorFactory
 {
diff --git a/source/VirtualFluidsCore/Connectors/CoarseToFineBlock3DConnector.h b/source/VirtualFluidsCore/Connectors/CoarseToFineBlock3DConnector.h
index 70cd811ee..648ae6480 100644
--- a/source/VirtualFluidsCore/Connectors/CoarseToFineBlock3DConnector.h
+++ b/source/VirtualFluidsCore/Connectors/CoarseToFineBlock3DConnector.h
@@ -11,8 +11,8 @@
 #include "D3Q27System.h"
 #include "Block3D.h"
 #include "InterpolationProcessor.h"
-#include <boost/shared_ptr.hpp>
-#include <boost/weak_ptr.hpp>
+#include <memory>
+
 
 class Block3D;
 
@@ -88,7 +88,7 @@ public:
    void receiveVectorsX3() {}
 
 protected:
-   boost::weak_ptr<Block3D> block; //dieser nvd sendet daten und die empfangenen werden diesem nvd zugeordnet
+   std::weak_ptr<Block3D> block; //dieser nvd sendet daten und die empfangenen werden diesem nvd zugeordnet
    VectorTransmitterPtr sender00, receiver00,
                         sender01, receiver01,
                         sender10, receiver10,
diff --git a/source/VirtualFluidsCore/Connectors/CoarseToFineNodeSetBlock3DConnector.cpp b/source/VirtualFluidsCore/Connectors/CoarseToFineNodeSetBlock3DConnector.cpp
index 4c1640cb2..6ea6c834f 100644
--- a/source/VirtualFluidsCore/Connectors/CoarseToFineNodeSetBlock3DConnector.cpp
+++ b/source/VirtualFluidsCore/Connectors/CoarseToFineNodeSetBlock3DConnector.cpp
@@ -1,4 +1,6 @@
 #include "CoarseToFineNodeSetBlock3DConnector.h"
+#include "DataSet3D.h"
+
 
 ////////////////////////////////////////////////////////////////////////////
 CoarseToFineNodeSetBlock3DConnector::CoarseToFineNodeSetBlock3DConnector(Block3DPtr block,
@@ -528,7 +530,7 @@ void CoarseToFineNodeSetBlock3DConnector::fillSendVectors()
    vector_type& data10 = this->sender10->getData();
    vector_type& data11 = this->sender11->getData();
 
-   BOOST_FOREACH(INodeVector inode, iNodeSetSender00)
+   for(INodeVector inode : iNodeSetSender00)
    {
       D3Q27ICell icellC;
       D3Q27ICell icellF;
@@ -536,7 +538,7 @@ void CoarseToFineNodeSetBlock3DConnector::fillSendVectors()
       iprocessor->interpolateCoarseToFine(icellC, icellF, inode[3], inode[4], inode[5]);
       writeICellFtoData(data00, index00, icellF);
    }
-   BOOST_FOREACH(INodeVector inode, iNodeSetSender01)
+   for(INodeVector inode : iNodeSetSender01)
    {
       D3Q27ICell icellC;
       D3Q27ICell icellF;
@@ -544,7 +546,7 @@ void CoarseToFineNodeSetBlock3DConnector::fillSendVectors()
       iprocessor->interpolateCoarseToFine(icellC, icellF, inode[3], inode[4], inode[5]);
       writeICellFtoData(data01, index01, icellF);
    }
-   BOOST_FOREACH(INodeVector inode, iNodeSetSender10)
+   for(INodeVector inode : iNodeSetSender10)
    {
       D3Q27ICell icellC;
       D3Q27ICell icellF;
@@ -552,7 +554,7 @@ void CoarseToFineNodeSetBlock3DConnector::fillSendVectors()
       iprocessor->interpolateCoarseToFine(icellC, icellF, inode[3], inode[4], inode[5]);
       writeICellFtoData(data10, index10, icellF);
    }
-   BOOST_FOREACH(INodeVector inode, iNodeSetSender11)
+   for(INodeVector inode : iNodeSetSender11)
    {
       D3Q27ICell icellC;
       D3Q27ICell icellF;
@@ -1245,25 +1247,25 @@ void CoarseToFineNodeSetBlock3DConnector::distributeReceiveVectors()
    vector_type& data10 = this->receiver10->getData();
    vector_type& data11 = this->receiver11->getData();
 
-   BOOST_FOREACH(INodeVector inode, iNodeSetReceiver00)
+   for(INodeVector inode : iNodeSetReceiver00)
    {
       LBMReal icellC[27];
       this->readICellCfromData(data00, index00, icellC);
       iprocessor->writeINodeInv(fTo, icellC, inode[0], inode[1], inode[2]);
    }
-   BOOST_FOREACH(INodeVector inode, iNodeSetReceiver01)
+   for(INodeVector inode : iNodeSetReceiver01)
    {
       LBMReal icellC[27];
       this->readICellCfromData(data01, index01, icellC);
       iprocessor->writeINodeInv(fTo, icellC, inode[0], inode[1], inode[2]);
    }
-   BOOST_FOREACH(INodeVector inode, iNodeSetReceiver10)
+   for(INodeVector inode : iNodeSetReceiver10)
    {
       LBMReal icellC[27];
       this->readICellCfromData(data10, index10, icellC);
       iprocessor->writeINodeInv(fTo, icellC, inode[0], inode[1], inode[2]);
    }
-   BOOST_FOREACH(INodeVector inode, iNodeSetReceiver11)
+   for(INodeVector inode : iNodeSetReceiver11)
    {
       LBMReal icellC[27];
       this->readICellCfromData(data11, index11, icellC);
diff --git a/source/VirtualFluidsCore/Connectors/CoarseToFineNodeSetBlock3DConnector.h b/source/VirtualFluidsCore/Connectors/CoarseToFineNodeSetBlock3DConnector.h
index b8d95cdf6..41341e7b9 100644
--- a/source/VirtualFluidsCore/Connectors/CoarseToFineNodeSetBlock3DConnector.h
+++ b/source/VirtualFluidsCore/Connectors/CoarseToFineNodeSetBlock3DConnector.h
@@ -21,8 +21,8 @@
 #include "InterpolationProcessor.h"
 #include "MathUtil.hpp"
 #include "Grid3D.h"
-#include <boost/shared_ptr.hpp>
-#include <boost/weak_ptr.hpp>
+#include <memory>
+
 
 class Block3D;
 
diff --git a/source/VirtualFluidsCore/Connectors/ConnectorFactory.h b/source/VirtualFluidsCore/Connectors/ConnectorFactory.h
index b5a041798..668bf9151 100644
--- a/source/VirtualFluidsCore/Connectors/ConnectorFactory.h
+++ b/source/VirtualFluidsCore/Connectors/ConnectorFactory.h
@@ -6,9 +6,9 @@
 #include "InterpolationProcessor.h"
 #include "FineToCoarseBlock3DConnector.h"
 
-#include <boost/shared_ptr.hpp>
+#include <memory>
 class ConnectorFactory;
-typedef boost::shared_ptr<ConnectorFactory> ConnectorFactoryPtr;
+typedef std::shared_ptr<ConnectorFactory> ConnectorFactoryPtr;
 
 class ConnectorFactory
 {
diff --git a/source/VirtualFluidsCore/Connectors/D3Q27ETCFOffVectorConnector.h b/source/VirtualFluidsCore/Connectors/D3Q27ETCFOffVectorConnector.h
index 0612543b4..3a254d635 100644
--- a/source/VirtualFluidsCore/Connectors/D3Q27ETCFOffVectorConnector.h
+++ b/source/VirtualFluidsCore/Connectors/D3Q27ETCFOffVectorConnector.h
@@ -20,8 +20,8 @@
 #include "InterpolationProcessor.h"
 #include "MathUtil.hpp"
 #include "Grid3D.h"
-#include <boost/shared_ptr.hpp>
-#include <boost/weak_ptr.hpp>
+#include <memory>
+
 #include "D3Q27ETFCOffVectorConnector.h"
 #include "BCProcessor.h"
 
@@ -45,7 +45,7 @@ class D3Q27ETCFOffVectorConnector : public Block3DConnector
 {
 public:
    typedef typename VectorTransmitter::value_type  vector_type;
-   typedef boost::shared_ptr< VectorTransmitter > VectorTransmitterPtr;
+   typedef std::shared_ptr< VectorTransmitter > VectorTransmitterPtr;
 public:
    D3Q27ETCFOffVectorConnector(Block3DPtr block,
       VectorTransmitterPtr senderEvenEvenSW, VectorTransmitterPtr receiverEvenEvenSW,
@@ -92,7 +92,7 @@ public:
    void receiveVectorsX3() {}
 
 protected:
-   boost::weak_ptr<Block3D> block; //dieser nvd sendet daten und die empfangenen werden diesem nvd zugeordnet
+   std::weak_ptr<Block3D> block; //dieser nvd sendet daten und die empfangenen werden diesem nvd zugeordnet
    VectorTransmitterPtr senderEvenEvenSW, receiverEvenEvenSW,
       senderEvenOddNW, receiverEvenOddNW,
       senderOddEvenSE, receiverOddEvenSE,
diff --git a/source/VirtualFluidsCore/Connectors/D3Q27ETFCOffVectorConnector.h b/source/VirtualFluidsCore/Connectors/D3Q27ETFCOffVectorConnector.h
index cd822e388..c010bab94 100644
--- a/source/VirtualFluidsCore/Connectors/D3Q27ETFCOffVectorConnector.h
+++ b/source/VirtualFluidsCore/Connectors/D3Q27ETFCOffVectorConnector.h
@@ -18,9 +18,10 @@
 #include "LBMKernel.h"
 #include "InterpolationProcessor.h"
 #include "MathUtil.hpp"
-#include <boost/shared_ptr.hpp>
-#include <boost/weak_ptr.hpp>
+#include <memory>
+
 #include "BCProcessor.h"
+#include "DataSet3D.h"
 
 class Block3D;
 
@@ -38,7 +39,7 @@ public:
 
 protected:
 	typedef typename VectorTransmitter::value_type  vector_type;
-	typedef boost::shared_ptr< VectorTransmitter > VectorTransmitterPtr;
+	typedef std::shared_ptr< VectorTransmitter > VectorTransmitterPtr;
 public:
    D3Q27ETFCOffVectorConnector(Block3DPtr block, VectorTransmitterPtr sender, VectorTransmitterPtr receiver, int sendDir, 
       InterpolationProcessorPtr iprocessor, CFconnectorType connType);
@@ -81,7 +82,7 @@ public:
 	void receiveVectorsX3() {}
 
 protected:
-	boost::weak_ptr<Block3D> block; //dieser nvd sendet daten und die empfangenen werden diesem nvd zugeordnet
+	std::weak_ptr<Block3D> block; //dieser nvd sendet daten und die empfangenen werden diesem nvd zugeordnet
 	//gegenstelle muss "inversen" connector besitzen
 	VectorTransmitterPtr sender, receiver;
 
diff --git a/source/VirtualFluidsCore/Connectors/D3Q27ETFullDirectConnector.cpp b/source/VirtualFluidsCore/Connectors/D3Q27ETFullDirectConnector.cpp
index ab4b68e9c..ea2619c2a 100644
--- a/source/VirtualFluidsCore/Connectors/D3Q27ETFullDirectConnector.cpp
+++ b/source/VirtualFluidsCore/Connectors/D3Q27ETFullDirectConnector.cpp
@@ -1,7 +1,7 @@
 #include "D3Q27ETFullDirectConnector.h"
 #include "LBMKernel.h"
 #include "D3Q27EsoTwist3DSplittedVector.h"
-
+#include "DataSet3D.h"
 
 using namespace std;
 
@@ -18,19 +18,19 @@ void D3Q27ETFullDirectConnector::init()
    maxX2 = (int)this->from.lock()->getKernel()->getDataSet()->getFdistributions()->getNX2() - 1;
    maxX3 = (int)this->from.lock()->getKernel()->getDataSet()->getFdistributions()->getNX3() - 1;
 
-   fFrom = boost::dynamic_pointer_cast<EsoTwist3D>(from.lock()->getKernel()->getDataSet()->getFdistributions());
-   fTo = boost::dynamic_pointer_cast<EsoTwist3D>(to.lock()->getKernel()->getDataSet()->getFdistributions());
+   fFrom = std::dynamic_pointer_cast<EsoTwist3D>(from.lock()->getKernel()->getDataSet()->getFdistributions());
+   fTo = std::dynamic_pointer_cast<EsoTwist3D>(to.lock()->getKernel()->getDataSet()->getFdistributions());
 }
 //////////////////////////////////////////////////////////////////////////
 void D3Q27ETFullDirectConnector::sendVectors()
 {
-   localDistributionsFrom = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fFrom)->getLocalDistributions();
-   nonLocalDistributionsFrom = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fFrom)->getNonLocalDistributions();
-   zeroDistributionsFrom = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fFrom)->getZeroDistributions();
+   localDistributionsFrom = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fFrom)->getLocalDistributions();
+   nonLocalDistributionsFrom = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fFrom)->getNonLocalDistributions();
+   zeroDistributionsFrom = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fFrom)->getZeroDistributions();
 
-   localDistributionsTo = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fTo)->getLocalDistributions();
-   nonLocalDistributionsTo = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fTo)->getNonLocalDistributions();
-   zeroDistributionsTo = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fTo)->getZeroDistributions();
+   localDistributionsTo = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fTo)->getLocalDistributions();
+   nonLocalDistributionsTo = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fTo)->getNonLocalDistributions();
+   zeroDistributionsTo = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fTo)->getZeroDistributions();
 
    //EAST
    if (sendDir == D3Q27System::E)
diff --git a/source/VirtualFluidsCore/Connectors/D3Q27ETFullDirectConnector.h b/source/VirtualFluidsCore/Connectors/D3Q27ETFullDirectConnector.h
index 3dfbbf490..330b3eacd 100644
--- a/source/VirtualFluidsCore/Connectors/D3Q27ETFullDirectConnector.h
+++ b/source/VirtualFluidsCore/Connectors/D3Q27ETFullDirectConnector.h
@@ -13,6 +13,7 @@
 #include "D3Q27System.h"
 #include "basics/container/CbArray3D.h"
 #include "basics/container/CbArray4D.h"
+#include "EsoTwist3D.h"
 
 //! \brief   Exchange data between blocks. 
 //! \details Connector send and receive full distributions between two blocks in shared memory.
diff --git a/source/VirtualFluidsCore/Connectors/D3Q27ETFullVectorConnector.cpp b/source/VirtualFluidsCore/Connectors/D3Q27ETFullVectorConnector.cpp
index 8af8a71a5..9bf60df86 100644
--- a/source/VirtualFluidsCore/Connectors/D3Q27ETFullVectorConnector.cpp
+++ b/source/VirtualFluidsCore/Connectors/D3Q27ETFullVectorConnector.cpp
@@ -1,7 +1,7 @@
 #include "D3Q27ETFullVectorConnector.h"
 #include "D3Q27EsoTwist3DSplittedVector.h"
 #include "LBMKernel.h"
-
+#include "DataSet3D.h"
 //////////////////////////////////////////////////////////////////////////
 D3Q27ETFullVectorConnector::D3Q27ETFullVectorConnector(Block3DPtr block
    , VectorTransmitterPtr sender
@@ -20,7 +20,7 @@ void D3Q27ETFullVectorConnector::init()
    maxX2 = (int)block.lock()->getKernel()->getDataSet()->getFdistributions()->getNX2() - 1;
    maxX3 = (int)block.lock()->getKernel()->getDataSet()->getFdistributions()->getNX3() - 1;
 
-   fDis = boost::dynamic_pointer_cast<EsoTwist3D>(block.lock()->getKernel()->getDataSet()->getFdistributions());
+   fDis = std::dynamic_pointer_cast<EsoTwist3D>(block.lock()->getKernel()->getDataSet()->getFdistributions());
 
    int anz = 27;
    switch (sendDir)
@@ -63,9 +63,9 @@ void D3Q27ETFullVectorConnector::init()
 //////////////////////////////////////////////////////////////////////////
 void D3Q27ETFullVectorConnector::fillSendVectors()
 {
-   localDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fDis)->getLocalDistributions();
-   nonLocalDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fDis)->getNonLocalDistributions();
-   zeroDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fDis)->getZeroDistributions();
+   localDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fDis)->getLocalDistributions();
+   nonLocalDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fDis)->getNonLocalDistributions();
+   zeroDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fDis)->getZeroDistributions();
 
    vector_type& sdata = sender->getData();
 
@@ -250,9 +250,9 @@ void D3Q27ETFullVectorConnector::distributeReceiveVectors()
 {
    /*e.g. connector sendet nach EAST --> empfaengt daten aus WEST ;-)*/
 
-   localDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fDis)->getLocalDistributions();
-   nonLocalDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fDis)->getNonLocalDistributions();
-   zeroDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fDis)->getZeroDistributions();
+   localDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fDis)->getLocalDistributions();
+   nonLocalDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fDis)->getNonLocalDistributions();
+   zeroDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fDis)->getZeroDistributions();
 
    vector_type& rdata = receiver->getData();
 
diff --git a/source/VirtualFluidsCore/Connectors/D3Q27ETFullVectorConnector.h b/source/VirtualFluidsCore/Connectors/D3Q27ETFullVectorConnector.h
index 7247e39b9..ad0b82f37 100644
--- a/source/VirtualFluidsCore/Connectors/D3Q27ETFullVectorConnector.h
+++ b/source/VirtualFluidsCore/Connectors/D3Q27ETFullVectorConnector.h
@@ -10,6 +10,7 @@
 #include "EsoTwistD3Q27System.h"
 #include "basics/container/CbArray3D.h"
 #include "basics/container/CbArray4D.h"
+#include "EsoTwist3D.h"
 
 
 //daten werden in einen vector (dieser befindet sich im transmitter) kopiert
diff --git a/source/VirtualFluidsCore/Connectors/D3Q27ETOffConnectorFactory.h b/source/VirtualFluidsCore/Connectors/D3Q27ETOffConnectorFactory.h
index 2ad0c48de..f4e2fbc5c 100644
--- a/source/VirtualFluidsCore/Connectors/D3Q27ETOffConnectorFactory.h
+++ b/source/VirtualFluidsCore/Connectors/D3Q27ETOffConnectorFactory.h
@@ -3,9 +3,9 @@
 //
 //#include "Block3DConnectorFactory.h"
 //
-//#include <boost/shared_ptr.hpp>
+//#include <memory>
 //class D3Q27ETOffConnectorFactory;
-//typedef boost::shared_ptr<D3Q27ETOffConnectorFactory> D3Q27ETOffConnectorFactoryPtr;
+//typedef std::shared_ptr<D3Q27ETOffConnectorFactory> D3Q27ETOffConnectorFactoryPtr;
 //
 //class D3Q27ETOffConnectorFactory : public Block3DConnectorFactory
 //{
diff --git a/source/VirtualFluidsCore/Connectors/FineToCoarseBlock3DConnector.h b/source/VirtualFluidsCore/Connectors/FineToCoarseBlock3DConnector.h
index 50bb2e78b..066cc712b 100644
--- a/source/VirtualFluidsCore/Connectors/FineToCoarseBlock3DConnector.h
+++ b/source/VirtualFluidsCore/Connectors/FineToCoarseBlock3DConnector.h
@@ -13,8 +13,8 @@
 #include "LBMKernel.h"
 #include "InterpolationProcessor.h"
 
-#include <boost/shared_ptr.hpp>
-#include <boost/weak_ptr.hpp>
+#include <memory>
+
 
 class Block3D;
 
@@ -83,7 +83,7 @@ public:
    void receiveVectorsX3() {}
 
 protected:
-   boost::weak_ptr<Block3D> block; 
+   std::weak_ptr<Block3D> block; 
    VectorTransmitterPtr sender, receiver;
    InterpolationProcessorPtr iprocessor;
    CFconnectorType connType;
diff --git a/source/VirtualFluidsCore/Connectors/FineToCoarseNodeSetBlock3DConnector.cpp b/source/VirtualFluidsCore/Connectors/FineToCoarseNodeSetBlock3DConnector.cpp
index 825d3904a..317755ae9 100644
--- a/source/VirtualFluidsCore/Connectors/FineToCoarseNodeSetBlock3DConnector.cpp
+++ b/source/VirtualFluidsCore/Connectors/FineToCoarseNodeSetBlock3DConnector.cpp
@@ -1,5 +1,7 @@
 #include "FineToCoarseNodeSetBlock3DConnector.h"
 #include "BCProcessor.h"
+#include "DataSet3D.h"
+
 
 //////////////////////////////////////////////////////////////////////////
 FineToCoarseNodeSetBlock3DConnector::FineToCoarseNodeSetBlock3DConnector(Block3DPtr block, VectorTransmitterPtr sender, VectorTransmitterPtr receiver,
@@ -696,7 +698,7 @@ void FineToCoarseNodeSetBlock3DConnector::fillSendVectors()
 
    vector_type& data = this->sender->getData();
 
-   BOOST_FOREACH(INodeVector inode, iNodeSetSender)
+   for(INodeVector  inode : iNodeSetSender)
    {
       LBMReal icellC[27];
       D3Q27ICell icellF;
@@ -1122,7 +1124,7 @@ void FineToCoarseNodeSetBlock3DConnector::distributeReceiveVectors()
 
    vector_type& data = this->receiver->getData();
 
-   BOOST_FOREACH(INodeVector inode, iNodeSetReceiver)
+   for(INodeVector  inode : iNodeSetReceiver)
    {
       D3Q27ICell icellF;
       this->readICellFfromData(data, index, icellF);
diff --git a/source/VirtualFluidsCore/Connectors/FineToCoarseNodeSetBlock3DConnector.h b/source/VirtualFluidsCore/Connectors/FineToCoarseNodeSetBlock3DConnector.h
index ea4f54bb2..c6e7b645b 100644
--- a/source/VirtualFluidsCore/Connectors/FineToCoarseNodeSetBlock3DConnector.h
+++ b/source/VirtualFluidsCore/Connectors/FineToCoarseNodeSetBlock3DConnector.h
@@ -15,8 +15,8 @@
 #include "LBMKernel.h"
 #include "InterpolationProcessor.h"
 #include "MathUtil.hpp"
-#include <boost/shared_ptr.hpp>
-#include <boost/weak_ptr.hpp>
+#include <memory>
+
 
 class Block3D;
 
diff --git a/source/VirtualFluidsCore/Connectors/LocalBlock3DConnector.h b/source/VirtualFluidsCore/Connectors/LocalBlock3DConnector.h
index 10d7bb7a5..039feea07 100644
--- a/source/VirtualFluidsCore/Connectors/LocalBlock3DConnector.h
+++ b/source/VirtualFluidsCore/Connectors/LocalBlock3DConnector.h
@@ -1,7 +1,7 @@
 #ifndef LocalBlock3DConnector_H
 #define LocalBlock3DConnector_H
 
-#include <boost/weak_ptr.hpp>
+
 
 #include "Block3DConnector.h"
 #include "Block3D.h"
@@ -52,8 +52,8 @@ public:
    void receiveVectorsX3() {}
 
 protected:
-   boost::weak_ptr<Block3D> from;
-   boost::weak_ptr<Block3D> to;
+   std::weak_ptr<Block3D> from;
+   std::weak_ptr<Block3D> to;
 };
 
 #endif //LocalBlock3DConnector_H
diff --git a/source/VirtualFluidsCore/Connectors/RemoteBlock3DConnector.h b/source/VirtualFluidsCore/Connectors/RemoteBlock3DConnector.h
index c2f17557f..c99ee5720 100644
--- a/source/VirtualFluidsCore/Connectors/RemoteBlock3DConnector.h
+++ b/source/VirtualFluidsCore/Connectors/RemoteBlock3DConnector.h
@@ -62,7 +62,7 @@ public:
    void receiveVectorsX3() {}
 
 protected:
-   boost::weak_ptr<Block3D> block; 
+   std::weak_ptr<Block3D> block; 
    VectorTransmitterPtr sender;
    VectorTransmitterPtr receiver;
 };
diff --git a/source/VirtualFluidsCore/Connectors/TransmitterType.h b/source/VirtualFluidsCore/Connectors/TransmitterType.h
index aaeb295a3..b159a9c25 100644
--- a/source/VirtualFluidsCore/Connectors/TransmitterType.h
+++ b/source/VirtualFluidsCore/Connectors/TransmitterType.h
@@ -5,12 +5,12 @@
 #include "basics/transmitter/TbTransmitterLocal.h"
 #include "basics/container/CbVector.h"
 #include "D3Q27System.h"
-#include <boost/shared_ptr.hpp>
+#include <memory>
 
 
 typedef TbTransmitter< CbVector< LBMReal > > VectorTransmitter;
 typedef VectorTransmitter::value_type  vector_type;
-typedef boost::shared_ptr< TbTransmitter< CbVector< LBMReal > > > VectorTransmitterPtr;
+typedef std::shared_ptr< TbTransmitter< CbVector< LBMReal > > > VectorTransmitterPtr;
 
 #endif // TransmitterType_h__
 
diff --git a/source/VirtualFluidsCore/Data/D3Q27EsoTwist3DSplittedVector.h b/source/VirtualFluidsCore/Data/D3Q27EsoTwist3DSplittedVector.h
index 767c85a23..1429eb286 100644
--- a/source/VirtualFluidsCore/Data/D3Q27EsoTwist3DSplittedVector.h
+++ b/source/VirtualFluidsCore/Data/D3Q27EsoTwist3DSplittedVector.h
@@ -1,85 +1,86 @@
-#ifndef D3Q27EsoTwist3DSplittedVector_h
-#define D3Q27EsoTwist3DSplittedVector_h
-
-#include "EsoTwist3D.h"
-#include "D3Q27System.h"
-#include "basics/container/CbArray4D.h"
-#include "basics/container/CbArray3D.h"
-#include <boost/serialization/serialization.hpp>
-#include <boost/serialization/base_object.hpp>
-
-class D3Q27EsoTwist3DSplittedVector : public EsoTwist3D
-{
-public:
-   D3Q27EsoTwist3DSplittedVector();
-   D3Q27EsoTwist3DSplittedVector(size_t nx1, size_t nx2, size_t nx3, LBMReal value);
-   //////////////////////////////////////////////////////////////////////////
-   ~D3Q27EsoTwist3DSplittedVector();
-   //////////////////////////////////////////////////////////////////////////
-   void swap();
-   //////////////////////////////////////////////////////////////////////////
-   virtual void getDistribution( LBMReal* const f, size_t x1, size_t x2, size_t x3);
-   //////////////////////////////////////////////////////////////////////////
-   virtual void setDistribution(const LBMReal* const f, size_t x1, size_t x2, size_t x3);
-   ////////////////////////////////////////////////////////////////////////
-   virtual void getDistributionInv( LBMReal* const f, size_t x1, size_t x2, size_t x3);
-   //////////////////////////////////////////////////////////////////////////
-   virtual void setDistributionInv(const LBMReal* const f, size_t x1, size_t x2, size_t x3);
-   //////////////////////////////////////////////////////////////////////////
-   virtual void setDistributionForDirection(const LBMReal* const f, size_t x1, size_t x2, size_t x3, unsigned long int direction);
-   //////////////////////////////////////////////////////////////////////////
-   virtual void setDistributionForDirection(LBMReal f, size_t x1, size_t x2, size_t x3, int direction);
-   //////////////////////////////////////////////////////////////////////////
-   virtual LBMReal getDistributionInvForDirection(size_t x1, size_t x2, size_t x3, int direction);
-   //////////////////////////////////////////////////////////////////////////
-   virtual void setDistributionInvForDirection(const LBMReal* const f, size_t x1, size_t x2, size_t x3, unsigned long int direction);
-   //////////////////////////////////////////////////////////////////////////
-   virtual void setDistributionInvForDirection(LBMReal f, size_t x1, size_t x2, size_t x3, unsigned long int direction);
-   //////////////////////////////////////////////////////////////////////////
-   virtual LBMReal getDistributionForDirection(size_t x1, size_t x2, size_t x3, int direction);
-   //////////////////////////////////////////////////////////////////////////
-   size_t getNX1() const;
-   //////////////////////////////////////////////////////////////////////////
-   size_t getNX2() const;
-   //////////////////////////////////////////////////////////////////////////
-   size_t getNX3() const;
-   //////////////////////////////////////////////////////////////////////////
-   CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr getLocalDistributions();
-   //////////////////////////////////////////////////////////////////////////
-   CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr getNonLocalDistributions();
-   //////////////////////////////////////////////////////////////////////////
-   CbArray3D<LBMReal,IndexerX3X2X1>::CbArray3DPtr getZeroDistributions();
-   //////////////////////////////////////////////////////////////////////////
-   void setNX1(size_t newNX1);
-   void setNX2(size_t newNX2);
-   void setNX3(size_t newNX3);
-   void setLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr array);
-   void setNonLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr array);
-   void setZeroDistributions(CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr array);
-   
-protected:
-   CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr localDistributions;
-   CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions;
-   CbArray3D<LBMReal,IndexerX3X2X1>::CbArray3DPtr   zeroDistributions;
-   size_t NX1, NX2, NX3;
-
-   friend class MPIIORestart1CoProcessor;
-   friend class MPIIORestart2CoProcessor;
-   friend class MPIIORestart11CoProcessor;
-   friend class MPIIORestart21CoProcessor;
-
-   friend class boost::serialization::access;
-   template<class Archive>
-   void serialize(Archive & ar, const unsigned int version)
-   {
-      ar & boost::serialization::base_object< EsoTwist3D >(*this);
-      ar & NX1; 
-      ar & NX2; 
-      ar & NX3;
-      ar &  localDistributions;
-      ar &  nonLocalDistributions;
-      ar &  zeroDistributions;
-   }
-};
-
-#endif
+#ifndef D3Q27EsoTwist3DSplittedVector_h
+#define D3Q27EsoTwist3DSplittedVector_h
+
+#include "EsoTwist3D.h"
+#include "D3Q27System.h"
+#include "basics/container/CbArray4D.h"
+#include "basics/container/CbArray3D.h"
+#include <boost/serialization/serialization.hpp>
+#include <boost/serialization/base_object.hpp>
+
+class D3Q27EsoTwist3DSplittedVector : public EsoTwist3D
+{
+public:
+   D3Q27EsoTwist3DSplittedVector();
+   D3Q27EsoTwist3DSplittedVector(size_t nx1, size_t nx2, size_t nx3, LBMReal value);
+   //////////////////////////////////////////////////////////////////////////
+   ~D3Q27EsoTwist3DSplittedVector();
+   //////////////////////////////////////////////////////////////////////////
+   void swap();
+   //////////////////////////////////////////////////////////////////////////
+   virtual void getDistribution( LBMReal* const f, size_t x1, size_t x2, size_t x3);
+   //////////////////////////////////////////////////////////////////////////
+   virtual void setDistribution(const LBMReal* const f, size_t x1, size_t x2, size_t x3);
+   ////////////////////////////////////////////////////////////////////////
+   virtual void getDistributionInv( LBMReal* const f, size_t x1, size_t x2, size_t x3);
+   //////////////////////////////////////////////////////////////////////////
+   virtual void setDistributionInv(const LBMReal* const f, size_t x1, size_t x2, size_t x3);
+   //////////////////////////////////////////////////////////////////////////
+   virtual void setDistributionForDirection(const LBMReal* const f, size_t x1, size_t x2, size_t x3, unsigned long int direction);
+   //////////////////////////////////////////////////////////////////////////
+   virtual void setDistributionForDirection(LBMReal f, size_t x1, size_t x2, size_t x3, int direction);
+   //////////////////////////////////////////////////////////////////////////
+   virtual LBMReal getDistributionInvForDirection(size_t x1, size_t x2, size_t x3, int direction);
+   //////////////////////////////////////////////////////////////////////////
+   virtual void setDistributionInvForDirection(const LBMReal* const f, size_t x1, size_t x2, size_t x3, unsigned long int direction);
+   //////////////////////////////////////////////////////////////////////////
+   virtual void setDistributionInvForDirection(LBMReal f, size_t x1, size_t x2, size_t x3, unsigned long int direction);
+   //////////////////////////////////////////////////////////////////////////
+   virtual LBMReal getDistributionForDirection(size_t x1, size_t x2, size_t x3, int direction);
+   //////////////////////////////////////////////////////////////////////////
+   size_t getNX1() const;
+   //////////////////////////////////////////////////////////////////////////
+   size_t getNX2() const;
+   //////////////////////////////////////////////////////////////////////////
+   size_t getNX3() const;
+   //////////////////////////////////////////////////////////////////////////
+   CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr getLocalDistributions();
+   //////////////////////////////////////////////////////////////////////////
+   CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr getNonLocalDistributions();
+   //////////////////////////////////////////////////////////////////////////
+   CbArray3D<LBMReal,IndexerX3X2X1>::CbArray3DPtr getZeroDistributions();
+   //////////////////////////////////////////////////////////////////////////
+   void setNX1(size_t newNX1);
+   void setNX2(size_t newNX2);
+   void setNX3(size_t newNX3);
+   void setLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr array);
+   void setNonLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr array);
+   void setZeroDistributions(CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr array);
+   
+protected:
+   CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr localDistributions;
+   CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions;
+   CbArray3D<LBMReal,IndexerX3X2X1>::CbArray3DPtr   zeroDistributions;
+   size_t NX1, NX2, NX3;
+
+   friend class MPIIORestart1CoProcessor;
+   friend class MPIIORestart2CoProcessor;
+   friend class MPIIORestart11CoProcessor;
+   friend class MPIIORestart21CoProcessor;
+
+
+   friend class boost::serialization::access;
+   template<class Archive>
+   void serialize(Archive & ar, const unsigned int version)
+   {
+      ar & boost::serialization::base_object< EsoTwist3D >(*this);
+      ar & NX1; 
+      ar & NX2; 
+      ar & NX3;
+      ar &  localDistributions;
+      ar &  nonLocalDistributions;
+      ar &  zeroDistributions;
+   }
+};
+
+#endif
diff --git a/source/VirtualFluidsCore/Data/DataSet3D.h b/source/VirtualFluidsCore/Data/DataSet3D.h
index 4832c4ae0..1046027ac 100644
--- a/source/VirtualFluidsCore/Data/DataSet3D.h
+++ b/source/VirtualFluidsCore/Data/DataSet3D.h
@@ -2,22 +2,21 @@
 #define DataSet3D_h
 
 #include <boost/serialization/serialization.hpp>
-#include <boost/smart_ptr/shared_ptr.hpp>
 #include "basics/container/CbArray4D.h"
 #include "basics/container/CbArray3D.h"
 #include "DistributionArray3D.h"
 
 class DataSet3D;
-typedef boost::shared_ptr<DataSet3D> DataSet3DPtr;
+typedef std::shared_ptr<DataSet3D> DataSet3DPtr;
 
 typedef CbArray4D<LBMReal,IndexerX4X3X2X1> AverageValuesArray3D;
-typedef boost::shared_ptr< AverageValuesArray3D > AverageValuesArray3DPtr;
+typedef std::shared_ptr< AverageValuesArray3D > AverageValuesArray3DPtr;
 
 typedef CbArray4D<LBMReal,IndexerX4X3X2X1> ShearStressValuesArray3D;
-typedef boost::shared_ptr< ShearStressValuesArray3D > ShearStressValuesArray3DPtr;
+typedef std::shared_ptr< ShearStressValuesArray3D > ShearStressValuesArray3DPtr;
 
 typedef CbArray3D<LBMReal, IndexerX3X2X1> RelaxationFactorArray3D;
-typedef boost::shared_ptr< RelaxationFactorArray3D > RelaxationFactorArray3DPtr;
+typedef std::shared_ptr< RelaxationFactorArray3D > RelaxationFactorArray3DPtr;
 
 class DataSet3D
 {
diff --git a/source/VirtualFluidsCore/Data/DistributionArray3D.h b/source/VirtualFluidsCore/Data/DistributionArray3D.h
index b27ffb702..39d0a175c 100644
--- a/source/VirtualFluidsCore/Data/DistributionArray3D.h
+++ b/source/VirtualFluidsCore/Data/DistributionArray3D.h
@@ -3,10 +3,9 @@
 
 #include <LBMSystem.h>
 #include <boost/serialization/serialization.hpp>
-#include <boost/smart_ptr/shared_ptr.hpp>
 
 class DistributionArray3D;
-typedef boost::shared_ptr<DistributionArray3D> DistributionArray3DPtr;
+typedef std::shared_ptr<DistributionArray3D> DistributionArray3DPtr;
 
 class DistributionArray3D
 {
diff --git a/source/VirtualFluidsCore/Data/EsoTwist3D.h b/source/VirtualFluidsCore/Data/EsoTwist3D.h
index b127bce28..f62572206 100644
--- a/source/VirtualFluidsCore/Data/EsoTwist3D.h
+++ b/source/VirtualFluidsCore/Data/EsoTwist3D.h
@@ -5,9 +5,9 @@
 #include <LBMSystem.h>
 #include <boost/serialization/serialization.hpp>
 #include <boost/serialization/base_object.hpp>
-#include <boost/smart_ptr/shared_ptr.hpp>
+
 class EsoTwist3D;
-typedef boost::shared_ptr<EsoTwist3D> EsoTwist3DPtr;
+typedef std::shared_ptr<EsoTwist3D> EsoTwist3DPtr;
 
 class EsoTwistD3Q27UnrollArray{};
 class EsoTwistPlusD3Q27UnrollArray{};
diff --git a/source/VirtualFluidsCore/Data/EsoTwistD3Q27SparseData.h b/source/VirtualFluidsCore/Data/EsoTwistD3Q27SparseData.h
index 9798891d9..77d84ca38 100644
--- a/source/VirtualFluidsCore/Data/EsoTwistD3Q27SparseData.h
+++ b/source/VirtualFluidsCore/Data/EsoTwistD3Q27SparseData.h
@@ -10,15 +10,15 @@
 #include <boost/serialization/base_object.hpp>
 
 class EsoTwistD3Q27SparseData;
-typedef boost::shared_ptr<EsoTwistD3Q27SparseData> EsoTwistD3Q27SparseDataPtr;
+typedef std::shared_ptr<EsoTwistD3Q27SparseData> EsoTwistD3Q27SparseDataPtr;
 
 class EsoTwistD3Q27SparseData : public EsoTwist3D
 {
 public:
    typedef boost::unordered_map<size_t, LBMReal> SparseData;
-   typedef boost::shared_ptr<SparseData> SparseDataPtr;
+   typedef std::shared_ptr<SparseData> SparseDataPtr;
    //typedef std::map<size_t, LBMReal> SparseData;
-   //typedef boost::shared_ptr<SparseData> SparseDataPtr;
+   //typedef std::shared_ptr<SparseData> SparseDataPtr;
 public:
    EsoTwistD3Q27SparseData();
    EsoTwistD3Q27SparseData(size_t ibx[3], size_t nx[3], size_t level, double value );
diff --git a/source/VirtualFluidsCore/Data/SparseMatrix3D.h b/source/VirtualFluidsCore/Data/SparseMatrix3D.h
index fa4ad47da..849a114a2 100644
--- a/source/VirtualFluidsCore/Data/SparseMatrix3D.h
+++ b/source/VirtualFluidsCore/Data/SparseMatrix3D.h
@@ -3,9 +3,9 @@
 
 #include <boost/unordered_map.hpp>
 
-#include <boost/shared_ptr.hpp>
+#include <memory>
 class SparseMatrix3D;
-typedef boost::shared_ptr<SparseMatrix3D> SparseMatrix3DPtr;
+typedef std::shared_ptr<SparseMatrix3D> SparseMatrix3DPtr;
 
 class SparseMatrix3D
 {
diff --git a/source/VirtualFluidsCore/Data/SparseMatrix4D.h b/source/VirtualFluidsCore/Data/SparseMatrix4D.h
index 011112472..8d3f5db6e 100644
--- a/source/VirtualFluidsCore/Data/SparseMatrix4D.h
+++ b/source/VirtualFluidsCore/Data/SparseMatrix4D.h
@@ -1,11 +1,10 @@
 #ifndef SparseMatrix4D_h
 #define SparseMatrix4D_h
 
-#include <boost/unordered_map.hpp>
 
-#include <boost/shared_ptr.hpp>
+#include <memory>
 class SparseMatrix4D;
-typedef boost::shared_ptr<SparseMatrix4D> SparseMatrix4DPtr;
+typedef std::shared_ptr<SparseMatrix4D> SparseMatrix4DPtr;
 
 class SparseMatrix4D
 {
@@ -19,7 +18,6 @@ public:
    {
       return nx4*(nx3*(nx2*x1+x2)+x3)+x4;
    }
-protected:
 private:
    SparseMatrix4D();
    static SparseMatrix4DPtr instance;
diff --git a/source/VirtualFluidsCore/Data/VoidData3D.h b/source/VirtualFluidsCore/Data/VoidData3D.h
index 482277eb8..6cbcaae32 100644
--- a/source/VirtualFluidsCore/Data/VoidData3D.h
+++ b/source/VirtualFluidsCore/Data/VoidData3D.h
@@ -3,10 +3,9 @@
 
 #include "EsoTwist3D.h"
 #include <boost/serialization/serialization.hpp>
-#include <boost/smart_ptr/shared_ptr.hpp>
 
 class VoidData3D;
-typedef boost::shared_ptr<VoidData3D> VoidData3DPtr;
+typedef std::shared_ptr<VoidData3D> VoidData3DPtr;
 
 class VoidData3D : public EsoTwist3D
 {
diff --git a/source/VirtualFluidsCore/Grid/Block3D.cpp b/source/VirtualFluidsCore/Grid/Block3D.cpp
index 12a0edea7..c42b67af7 100644
--- a/source/VirtualFluidsCore/Grid/Block3D.cpp
+++ b/source/VirtualFluidsCore/Grid/Block3D.cpp
@@ -1,6 +1,9 @@
 #include "Block3D.h"
+
 #include "Grid3DSystem.h"
-#include <boost/foreach.hpp>
+#include "Block3DConnector.h"
+#include "LBMKernel.h"
+
 
 int Block3D::counter = 0;
 //////////////////////////////////////////////////////////////////////////
@@ -77,7 +80,7 @@ void  Block3D::setKernel(LBMKernelPtr kernel)
    this->kernel = kernel; 
 }
 //////////////////////////////////////////////////////////////////////////
-LBMKernelPtr Block3D::getKernel() const              
+ILBMKernelPtr Block3D::getKernel() const              
 {  
    return this->kernel; 
 }
@@ -159,7 +162,7 @@ void Block3D::setLevel(int level)
 //////////////////////////////////////////////////////////////////////////
 Block3DConnectorPtr Block3D::getConnector(int dir) const
 { 
-   BOOST_FOREACH(Block3DConnectorPtr c, connectors)
+   for(Block3DConnectorPtr c : connectors)
    {
       if( c ) 
       {
@@ -181,7 +184,7 @@ void Block3D::deleteConnectors()
 //////////////////////////////////////////////////////////////////////////
 bool Block3D::hasConnectors()
 {
-   BOOST_FOREACH(Block3DConnectorPtr c, connectors)
+   for(Block3DConnectorPtr c : connectors)
       if( c ) return true;
    
    return false;
@@ -419,7 +422,7 @@ void Block3D::deleteInterpolationFlag()
 //////////////////////////////////////////////////////////////////////////
 double Block3D::getWorkLoad()
 {
-   double l = kernel->getCallculationTime();
+   double l = kernel->getCalculationTime();
    l *= static_cast<double>(1<<level);
    return l;
 }
@@ -474,7 +477,7 @@ void Block3D::addWeight( int rank, int weight )
 void Block3D::addWeightForAll( int weight )
 {
    typedef std::map<int, int> wMap;
-   BOOST_FOREACH(wMap::value_type &w, this->weight)
+   for (wMap::value_type &w : this->weight)
    {
       w.second += weight;
    }
@@ -489,5 +492,3 @@ int Block3D::getWeightSize()
 {
    return static_cast<int>(this->weight.size());
 }
-
-
diff --git a/source/VirtualFluidsCore/Grid/Block3D.h b/source/VirtualFluidsCore/Grid/Block3D.h
index aaba47197..ab5d05134 100644
--- a/source/VirtualFluidsCore/Grid/Block3D.h
+++ b/source/VirtualFluidsCore/Grid/Block3D.h
@@ -1,162 +1,157 @@
-#ifndef BLOCK3D_H
-#define BLOCK3D_H
-
-#include <sstream>
-#include <iostream>
-
-#include "UbMath.h"
-#include "CoordinateTransformation3D.h"
-
-#include "Block3DConnector.h"
-
-#include <boost/serialization/shared_ptr.hpp>
-#include <boost/serialization/vector.hpp>
-#include <boost/foreach.hpp>
-
-#include <boost/shared_ptr.hpp>
-class Block3D;
-typedef boost::shared_ptr<Block3D> Block3DPtr;
-
-#include "LBMKernel.h"
-
-class Block3D
-{
-public:
-   Block3D();
-   Block3D(int x1, int x2, int x3, int level);
-   virtual ~Block3D();
-   bool operator==(const Block3D& src) const;
-   bool operator!=(const Block3D& src) const;
-
-   int getX1() const;
-   int getX2() const;
-   int getX3() const;
-
-   void setActive(bool active);
-   bool isActive()    const;
-   bool isNotActive() const;
-
-   void setKernel(LBMKernelPtr kernel);
-   LBMKernelPtr getKernel() const;
-   void deleteKernel();
-
-   void setBundle(int bundle);
-   int  getBundle() const;
-
-   void setRank(int rank);
-   int  getRank() const;
-
-   void setLocalRank(int rank);
-   int  getLocalRank() const;
-
-   int  getGlobalID() const;
-   void setGlobalID(int id);
-
-   int  getLocalID() const;
-   void setLocalID(int id);
-
-   int  getPart() const;
-   void setPart(int part);
-
-   int  getLevel() const;
-   void setLevel(int level);
-
-   //Connector-Section
-   void                 setConnector(Block3DConnectorPtr connector);
-   Block3DConnectorPtr  getConnector(int dir) const;
-   bool                 hasConnectors();
-   void                 deleteConnectors();
-   void pushBackSameLevelConnectors(  std::vector<Block3DConnectorPtr>& localSameLevelConnectors
-                                    , std::vector<Block3DConnectorPtr>& remoteSameLevelConnectors );
-   void pushBackLocalSameLevelConnectors( std::vector<Block3DConnectorPtr>& localSameLevelConnectors );
-   void pushBackRemoteSameLevelConnectors( std::vector<Block3DConnectorPtr>& remoteSameLevelConnectors );
-   void pushBackLocalInterpolationConnectorsCF( std::vector<Block3DConnectorPtr>& localInterpolationConnectors );
-   void pushBackRemoteInterpolationConnectorsCF( std::vector<Block3DConnectorPtr>& remoteInterpolationConnectors );
-   void pushBackLocalInterpolationConnectorsFC( std::vector<Block3DConnectorPtr>& localInterpolationConnectors );
-   void pushBackRemoteInterpolationConnectorsFC( std::vector<Block3DConnectorPtr>& remoteInterpolationConnectors );
-   void pushBackLocalSameLevelConnectors( std::vector<Block3DConnectorPtr>& localSameLevelConnectors, const int& dir);
-   void pushBackRemoteSameLevelConnectors( std::vector<Block3DConnectorPtr>& remoteSameLevelConnectors, const int& dir );
-   int getNumberOfLocalConnectors();
-   int getNumberOfRemoteConnectors();
-   int getNumberOfLocalConnectorsForSurfaces();
-   int getNumberOfRemoteConnectorsForSurfaces();
-
-   void setWeight(int rank, int weight);
-   int  getWeight(int rank);
-   void addWeightForAll(int weight);
-   void addWeight(int rank, int weight);
-   void clearWeight();
-   int  getWeightSize();
-
-   //interpolation
-   bool hasInterpolationFlag();
-   bool hasInterpolationFlag(int dir);
-   void deleteInterpolationFlag();
-
-   void setInterpolationFlagCF(int dir);
-   int  getInterpolationFlagCF();
-   bool hasInterpolationFlagCF(int dir);
-   bool hasInterpolationFlagCF();
-
-   void setInterpolationFlagFC(int dir);
-   int  getInterpolationFlagFC();
-   bool hasInterpolationFlagFC(int dir);
-   bool hasInterpolationFlagFC();
-
-   double getWorkLoad();
-
-   std::string toString() ;
-
-   static int getMaxGlobalID() { return counter; }
-   static void setMaxGlobalID(int c) { counter = 0; }
-private:
-  int   x1;
-  int   x2;
-  int   x3;
-
-  bool active;
-
-  int interpolationFlagCF;
-  int interpolationFlagFC;
-
-  LBMKernelPtr kernel;
-  std::vector<Block3DConnectorPtr> connectors;
-  std::map<int, int> weight;
-
-  int bundle;
-  int rank;
-  int lrank;
-  int globalID;
-  int localID;
-  int part;
-  int level;
-  static int counter;
-
-  friend class MPIIORestart1CoProcessor;
-  friend class MPIIORestart2CoProcessor;
-  friend class MPIIORestart11CoProcessor;
-  friend class MPIIORestart21CoProcessor;
-
-  friend class boost::serialization::access;
-  template<class Archive>
-  void serialize(Archive & ar, const unsigned int version)
-  {
-     ar & x1;
-     ar & x2;
-     ar & x3;
-     ar & active;
-     ar & bundle;
-     ar & rank;
-     ar & lrank;
-     ar & part;
-     ar & globalID;
-     ar & localID;
-     ar & level;
-     ar & kernel;
-     ar & interpolationFlagCF;
-     ar & interpolationFlagFC;
-     ar & counter;
-  }
-};
-
-#endif  //BLOCK3D_H
+#ifndef BLOCK3D_H
+#define BLOCK3D_H
+
+#include <boost/serialization/shared_ptr.hpp>
+#include <boost/serialization/vector.hpp>
+#include <memory>
+
+class Block3DConnector;
+class LBMKernel;
+class ILBMKernel;
+
+class Block3D;
+typedef std::shared_ptr<Block3D> Block3DPtr;
+
+class Block3D
+{
+public:
+   Block3D();
+   Block3D(int x1, int x2, int x3, int level);
+   virtual ~Block3D();
+   bool operator==(const Block3D& src) const;
+   bool operator!=(const Block3D& src) const;
+
+   int getX1() const;
+   int getX2() const;
+   int getX3() const;
+
+   void setActive(bool active);
+   bool isActive()    const;
+   bool isNotActive() const;
+
+   void setKernel(std::shared_ptr<LBMKernel> kernel);
+   std::shared_ptr<ILBMKernel> getKernel() const;
+   void deleteKernel();
+
+   void setBundle(int bundle);
+   int  getBundle() const;
+
+   void setRank(int rank);
+   int  getRank() const;
+
+   void setLocalRank(int rank);
+   int  getLocalRank() const;
+
+   int  getGlobalID() const;
+   void setGlobalID(int id);
+
+   int  getLocalID() const;
+   void setLocalID(int id);
+
+   int  getPart() const;
+   void setPart(int part);
+
+   int  getLevel() const;
+   void setLevel(int level);
+
+   //Connector-Section
+   void                 setConnector(std::shared_ptr<Block3DConnector> connector);
+   std::shared_ptr<Block3DConnector>  getConnector(int dir) const;
+   bool                 hasConnectors();
+   void                 deleteConnectors();
+   void pushBackSameLevelConnectors(  std::vector<std::shared_ptr<Block3DConnector> >& localSameLevelConnectors
+                                    , std::vector<std::shared_ptr<Block3DConnector> >& remoteSameLevelConnectors );
+   void pushBackLocalSameLevelConnectors( std::vector<std::shared_ptr<Block3DConnector> >& localSameLevelConnectors );
+   void pushBackRemoteSameLevelConnectors( std::vector<std::shared_ptr<Block3DConnector> >& remoteSameLevelConnectors );
+   void pushBackLocalInterpolationConnectorsCF( std::vector<std::shared_ptr<Block3DConnector> >& localInterpolationConnectors );
+   void pushBackRemoteInterpolationConnectorsCF( std::vector<std::shared_ptr<Block3DConnector> >& remoteInterpolationConnectors );
+   void pushBackLocalInterpolationConnectorsFC( std::vector<std::shared_ptr<Block3DConnector> >& localInterpolationConnectors );
+   void pushBackRemoteInterpolationConnectorsFC( std::vector<std::shared_ptr<Block3DConnector> >& remoteInterpolationConnectors );
+   void pushBackLocalSameLevelConnectors( std::vector<std::shared_ptr<Block3DConnector> >& localSameLevelConnectors, const int& dir);
+   void pushBackRemoteSameLevelConnectors( std::vector<std::shared_ptr<Block3DConnector> >& remoteSameLevelConnectors, const int& dir );
+   int getNumberOfLocalConnectors();
+   int getNumberOfRemoteConnectors();
+   int getNumberOfLocalConnectorsForSurfaces();
+   int getNumberOfRemoteConnectorsForSurfaces();
+
+   void setWeight(int rank, int weight);
+   int  getWeight(int rank);
+   void addWeightForAll(int weight);
+   void addWeight(int rank, int weight);
+   void clearWeight();
+   int  getWeightSize();
+
+   //interpolation
+   bool hasInterpolationFlag();
+   bool hasInterpolationFlag(int dir);
+   void deleteInterpolationFlag();
+
+   void setInterpolationFlagCF(int dir);
+   int  getInterpolationFlagCF();
+   bool hasInterpolationFlagCF(int dir);
+   bool hasInterpolationFlagCF();
+
+   void setInterpolationFlagFC(int dir);
+   int  getInterpolationFlagFC();
+   bool hasInterpolationFlagFC(int dir);
+   bool hasInterpolationFlagFC();
+
+   double getWorkLoad();
+
+   std::string toString() ;
+
+   static int getMaxGlobalID() { return counter; }
+   static void setMaxGlobalID(int c) { counter = 0; }
+
+private:
+  int   x1;
+  int   x2;
+  int   x3;
+
+  bool active;
+
+  int interpolationFlagCF;
+  int interpolationFlagFC;
+
+  std::shared_ptr<LBMKernel> kernel;
+  std::vector<std::shared_ptr<Block3DConnector> > connectors;
+  std::map<int, int> weight;
+
+  int bundle;
+  int rank;
+  int lrank;
+  int globalID;
+  int localID;
+  int part;
+  int level;
+  static int counter;
+
+  friend class MPIIORestart1CoProcessor;
+  friend class MPIIORestart2CoProcessor;
+  friend class MPIIORestart11CoProcessor;
+  friend class MPIIORestart21CoProcessor;
+
+
+  friend class boost::serialization::access;
+  template<class Archive>
+  void serialize(Archive & ar, const unsigned int version)
+  {
+     ar & x1;
+     ar & x2;
+     ar & x3;
+     ar & active;
+     ar & bundle;
+     ar & rank;
+     ar & lrank;
+     ar & part;
+     ar & globalID;
+     ar & localID;
+     ar & level;
+     ar & kernel;
+     ar & interpolationFlagCF;
+     ar & interpolationFlagFC;
+     ar & counter;
+  }
+};
+
+#endif  //BLOCK3D_H
diff --git a/source/VirtualFluidsCore/Grid/CalculationManager.cpp b/source/VirtualFluidsCore/Grid/CalculationManager.cpp
index 902d081ca..dd5e481a4 100644
--- a/source/VirtualFluidsCore/Grid/CalculationManager.cpp
+++ b/source/VirtualFluidsCore/Grid/CalculationManager.cpp
@@ -1,214 +1,155 @@
 #include "CalculationManager.h"
 
-#include <iomanip>
-#include <list>
-#include <vector>
-
 #include <boost/thread.hpp>
-#include <boost/foreach.hpp>
+
+#include "CalculatorFactory.h"
 
 #include <Calculator.h>
 #include <MPICalculator.h>
-#include <PrePostBcCalculator.h>
-#include <Communicator.h>
-
 #if defined VF_FETOL
 #include <FETOLCalculator.h>
 #endif
 
-using namespace std;
+#include <Communicator.h>
+#include "TimeAveragedValuesCoProcessor.h"
+#include "Grid3D.h"
+#include "LoadBalancer.h"
+
+
 //////////////////////////////////////////////////////////////////////////
-CalculationManager::CalculationManager(Grid3DPtr grid, int numOfThreads, double endTime, UbSchedulerPtr visScheduler, CalculationManager::CalculatorType calcType)
-                                       : grid(grid),
-                                         numOfThreads(numOfThreads),
-                                         endTime(endTime),
-                                         visScheduler(visScheduler),
-                                         calcType(calcType)
+CalculationManager::CalculationManager(Grid3DPtr grid, int numOfThreads, double endTime, std::shared_ptr<CalculatorFactory> calculatorFactory, CalculatorType type)
+    : grid(grid),
+    numOfThreads(numOfThreads),
+    endTime(endTime),
+    calculatorFactory(calculatorFactory),
+    type(type)
 {
-   init();
+    this->initCalcThreads();
 }
 //////////////////////////////////////////////////////////////////////////
-CalculationManager::CalculationManager(Grid3DPtr grid, int numOfThreads, double endTime, UbSchedulerPtr visScheduler, 
-                                       CommunicatorPtr comm, int endDir, LBMReal nu, CalculatorType calcType)
-                                       : grid(grid),
-                                       numOfThreads(numOfThreads),
-                                       endTime(endTime),
-                                       visScheduler(visScheduler),
-                                       calcType(calcType), 
-                                       comm(comm),
-                                       endDir(endDir),
-                                       nu(nu)
+CalculationManager::CalculationManager(Grid3DPtr grid, int numOfThreads, double endTime, CommunicatorPtr comm, int endDir, std::shared_ptr<CalculatorFactory> calculatorFactory)
+    : grid(grid),
+    numOfThreads(numOfThreads),
+    endTime(endTime),
+    calculatorFactory(calculatorFactory),
+    type(type)
 {
-   init();
-   loadBalancer = LoadBalancerPtr(new LoadBalancer(grid, comm, endDir));
+    this->initCalcThreads();
+    loadBalancer = LoadBalancerPtr(new LoadBalancer(grid, comm, endDir));
 }
 //////////////////////////////////////////////////////////////////////////
 CalculationManager::~CalculationManager()
 {
+
 }
 //////////////////////////////////////////////////////////////////////////
-void CalculationManager::init()
+void CalculationManager::mpiCalculate()
 {
-   this->rank = grid->getRank();
-   initCalcThreads();
+    try
+    {
+        std::dynamic_pointer_cast<MPICalculator>(calcThreads[0])->calculate(endTime, shared_from_this());
+    }
+    catch (std::exception& e)
+    {
+        UBLOG(logERROR, e.what());
+        //throw e;
+        exit(EXIT_FAILURE);
+    }
 }
+
 //////////////////////////////////////////////////////////////////////////
 void CalculationManager::calculate()
 {
-   try
-   {
-      boost::shared_ptr<CalculationManager> this_ = shared_from_this();
-      if (calcType == CalculationManager::Hybrid || calcType == CalculationManager::PrePostBc)
-      {
-         boost::thread_group threads;
-         boost::exception_ptr error;
-
-         for (int i = 1; i<calcThreads.size(); i++)
-         {
-            threads.create_thread(boost::bind(&Calculator::calculate, calcThreads[i], endTime, this_, boost::ref(error)));
-         }
-
-         calcThreads[0]->calculate(endTime, this_, boost::ref(error));
-
-         threads.join_all();
-      } 
-      else
-      {
-         boost::dynamic_pointer_cast<MPICalculator>(calcThreads[0])->calculate(endTime, this_);
-      }
-
-
-      //if( error )
-      //{
-      //   boost::rethrow_exception(error);
-      //}
-   }
-   catch(std::exception& e)
-   {
-      UBLOG(logERROR, e.what());
-      //throw e;
-      exit (EXIT_FAILURE);
-   }
+    try
+    {
+        boost::thread_group threads;
+        boost::exception_ptr error;
+
+        for (int i = 1; i < calcThreads.size(); i++)
+            threads.create_thread(boost::bind(&Calculator::calculate, calcThreads[i], endTime, shared_from_this(), boost::ref(error)));
+
+        calcThreads[0]->calculate(endTime, shared_from_this(), boost::ref(error));
+
+        threads.join_all();
+    }
+    catch (std::exception& e)
+    {
+        UBLOG(logERROR, e.what());
+        //throw e;
+        exit(EXIT_FAILURE);
+    }
 }
 //////////////////////////////////////////////////////////////////////////
 void CalculationManager::initCalcThreads()
 {
-   UBLOG(logDEBUG1, "CalculationManager::initCalcThreads() - started");
-   
-   SynchronizerPtr sync( new Synchronizer(numOfThreads));
-   
-   for (int i =0; i<numOfThreads; i++)
-   {
-      //CalculatorPtr calc = CalculatorPtr (new Calculator(grid, sync, i == 0 ? true : false));
-      CalculatorPtr calc = createCalculator(grid, sync, i == 0 ? true : false);
-      calc->setVisScheduler(visScheduler);
-      calcThreads.push_back(calc);
-   }
-
-   UBLOG(logDEBUG5, "calcThreads - initialized");
-
-   addBlocksToCalcThreads();
-
-   UBLOG(logDEBUG5, "calcThreads - filled with Blocks");
-
-   //BOOST_FOREACH(CalculatorPtr calc,  calcThreads)
-   //{
-   //   calc->initConnectors();
-   //}
-   UBLOG(logDEBUG1, "CalculationManager::initCalcThreads() - stoped");
-}
-//////////////////////////////////////////////////////////////////////////
-void CalculationManager::setVisScheduler(UbSchedulerPtr s)
-{
-   visScheduler = s;
+    UBLOG(logDEBUG1, "CalculationManager::initCalcThreads() - started");
+
+    SynchronizerPtr sync(new Synchronizer(numOfThreads));
+    for (int i = 0; i < numOfThreads; i++)
+        calcThreads.push_back(this->calculatorFactory->makeCalculator(grid, sync, i == 0 ? true : false, type));
+
+    this->addBlocksToCalcThreads();
 }
+
 //////////////////////////////////////////////////////////////////////////
 bool CalculationManager::balance()
 {
-   //if(loadBalancer->balance())
-   //   return true;
-   //else
-   //{
-   //   grid->deleteConnectors();
+    //if(loadBalancer->balance())
+    //   return true;
+    //else
+    //{
+    //   grid->deleteConnectors();
 
-   //   BOOST_FOREACH(CalculatorPtr calc,  calcThreads)
-   //   {
-   //      calc->deleteConnectors();
-   //   }
+    //   for(CalculatorPtr calc,  calcThreads)
+    //   {
+    //      calc->deleteConnectors();
+    //   }
 
-   //   TbCbVectorMpiPool<LBMReal>::eraseMap();
+    //   TbCbVectorMpiPool<LBMReal>::eraseMap();
 
-   //   D3Q27SetInterfaceBlocksPatchVisitor setInterfaceBlocksPatchVisitor(nue, comm);
-   //   grid->accept(setInterfaceBlocksPatchVisitor);
+    //   D3Q27SetInterfaceBlocksPatchVisitor setInterfaceBlocksPatchVisitor(nue, comm);
+    //   grid->accept(setInterfaceBlocksPatchVisitor);
 
-   //   D3Q27SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR);
-   //   grid->accept( setConnsVisitor );
+    //   D3Q27SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR);
+    //   grid->accept( setConnsVisitor );
 
-   //   PQueuePartitioningPatchVisitor pqPartVisitor(numOfThreads);
-   //   grid->accept(pqPartVisitor);
+    //   PQueuePartitioningPatchVisitor pqPartVisitor(numOfThreads);
+    //   grid->accept(pqPartVisitor);
 
-   //   reinitCalcThreads();
-      return false;
-   //}
+    //   reinitCalcThreads();
+    return false;
+    //}
 }
 //////////////////////////////////////////////////////////////////////////
 void CalculationManager::reinitCalcThreads()
 {
-   BOOST_FOREACH(CalculatorPtr c, calcThreads)
-   {
-      c->deleteBlocks();
-   }
+    for (std::shared_ptr<Calculator> c : calcThreads)
+        c->deleteBlocks();
 
-   addBlocksToCalcThreads();
+    addBlocksToCalcThreads();
 
-   BOOST_FOREACH(CalculatorPtr calc,  calcThreads)
-   {
-      calc->initConnectors();
-   }
+    for (std::shared_ptr<Calculator> c : calcThreads)
+        c->initConnectors();
 }
 //////////////////////////////////////////////////////////////////////////
 void CalculationManager::addBlocksToCalcThreads()
 {
-   int gridRank = grid->getRank();
-   int minInitLevel = this->grid->getCoarsestInitializedLevel();
-   int maxInitLevel = this->grid->getFinestInitializedLevel();
-
-   for(int level = minInitLevel; level<=maxInitLevel;level++)
-   {
-      vector<Block3DPtr> blockVector;
-      grid->getBlocks(level, gridRank, true, blockVector);
-      BOOST_FOREACH(Block3DPtr block, blockVector)
-      {
-         if (block)
-         {
-            calcThreads[block->getPart()]->addBlock(block);
-         }
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-CalculatorPtr CalculationManager::createCalculator(Grid3DPtr grid, SynchronizerPtr sync, bool mainThread)
-{
-   switch (calcType)
-   {
-   case CalculationManager::Hybrid:
-      return CalculatorPtr(new Calculator(grid, sync, mainThread));
-   case CalculationManager::MPI:
-      return CalculatorPtr (new MPICalculator(grid));
-#if defined VF_FETOL
-   case CalculationManager::FETOL:
-      return CalculatorPtr (new FETOLCalculator(grid, sync, mainThread));
-#endif
-   case CalculationManager::PrePostBc:
-      return CalculatorPtr(new PrePostBcCalculator(grid, sync, mainThread));
-   default:
-      UB_THROW(UbException(UB_EXARGS,"This Calculator is not defined!"));
-   }
+    const int gridRank = grid->getRank();
+    const int minInitLevel = this->grid->getCoarsestInitializedLevel();
+    const int maxInitLevel = this->grid->getFinestInitializedLevel();
+
+    for (int level = minInitLevel; level <= maxInitLevel; level++)
+    {
+        std::vector<Block3DPtr> blockVector;
+        grid->getBlocks(level, gridRank, true, blockVector);
+        for (Block3DPtr const block : blockVector)
+            if (block)
+                calcThreads[block->getPart()]->addBlock(block);
+    }
 }
+
 //////////////////////////////////////////////////////////////////////////
 void CalculationManager::setTimeAveragedValuesCoProcessor(TimeAveragedValuesCoProcessorPtr coProcessor)
 {
-   calcThreads[0]->setTimeAveragedValuesCoProcessor(coProcessor);
+    calcThreads[0]->setTimeAveragedValuesCoProcessor(coProcessor);
 }
-
-
diff --git a/source/VirtualFluidsCore/Grid/CalculationManager.h b/source/VirtualFluidsCore/Grid/CalculationManager.h
index f94162c11..ec41e466a 100644
--- a/source/VirtualFluidsCore/Grid/CalculationManager.h
+++ b/source/VirtualFluidsCore/Grid/CalculationManager.h
@@ -1,46 +1,51 @@
 #ifndef CALCULATORMANAGER_H
 #define CALCULATORMANAGER_H
 
-#include "Grid3D.h"
-#include "Communicator.h"
+
+#include <memory>
+#include <vector>
 
 class CalculationManager;
-typedef boost::shared_ptr<CalculationManager> CalculationManagerPtr;
+typedef std::shared_ptr<CalculationManager> CalculationManagerPtr;
+
+class LoadBalancer;
+class Communicator;
+class Grid3D;
+class Calculator;
+class CalculatorFactory;
+class TimeAveragedValuesCoProcessor;
+enum class CalculatorType;
 
-#include "Calculator.h"
 
-class CalculationManager : public boost::enable_shared_from_this<CalculationManager>
+class CalculationManager : public std::enable_shared_from_this<CalculationManager>
 {
+
 public:
-   enum CalculatorType{Hybrid, MPI, FETOL, PrePostBc};
-public:
-   CalculationManager(Grid3DPtr grid, int numOfThreads, double endTime, UbSchedulerPtr visScheduler, CalculatorType calcType = CalculationManager::Hybrid);
-   CalculationManager(Grid3DPtr grid, int numOfThreads, double endTime, UbSchedulerPtr visScheduler, 
-                      CommunicatorPtr comm, int endDir, LBMReal nu, CalculatorType calcType = CalculationManager::MPI);
+   CalculationManager(std::shared_ptr<Grid3D> grid, int numOfThreads, double endTime, std::shared_ptr<CalculatorFactory> calculatorFactory, CalculatorType type);
+   CalculationManager(std::shared_ptr<Grid3D> grid, int numOfThreads, double endTime, std::shared_ptr<Communicator> comm, int endDir, std::shared_ptr<CalculatorFactory> calculatorFactory);
    virtual ~CalculationManager();
+
    void calculate();
-   void setVisScheduler(UbSchedulerPtr s);
+   void mpiCalculate();
    bool balance();
-   void setTimeAveragedValuesCoProcessor(TimeAveragedValuesCoProcessorPtr coProcessor);
+   void setTimeAveragedValuesCoProcessor(std::shared_ptr<TimeAveragedValuesCoProcessor> coProcessor);
+
 private:
-   void init();
-   void calculateMain();
    void initCalcThreads();
    void reinitCalcThreads();
    void addBlocksToCalcThreads();
-   CalculatorPtr createCalculator(Grid3DPtr grid, SynchronizerPtr sync, bool mainThread);
-   Grid3DPtr grid;
+
+   std::shared_ptr<Grid3D> grid;
    int numOfThreads;
-   //boost::exception_ptr error;
-   CalculatorType calcType;
-   std::vector<CalculatorPtr> calcThreads;
    double endTime;
-   UbSchedulerPtr visScheduler;
-   CommunicatorPtr comm;   
-   int endDir;
-   LoadBalancerPtr loadBalancer;
-   int rank;
-   LBMReal nu;
+
+   std::vector<std::shared_ptr<Calculator> > calcThreads;
+
+   std::shared_ptr<LoadBalancer> loadBalancer;
+
+   std::shared_ptr<CalculatorFactory> calculatorFactory;
+   CalculatorType type;
+
 }; 
 
 #endif 
diff --git a/source/VirtualFluidsCore/Grid/Calculator.cpp b/source/VirtualFluidsCore/Grid/Calculator.cpp
index 895b1dd64..b6b1e3b97 100644
--- a/source/VirtualFluidsCore/Grid/Calculator.cpp
+++ b/source/VirtualFluidsCore/Grid/Calculator.cpp
@@ -1,602 +1,613 @@
-#include "Calculator.h"
-#include <basics/utilities/UbException.h>
-#include <boost/foreach.hpp>
-#include "MathUtil.hpp"
-#include "basics/writer/WbWriterVtkXmlASCII.h"
-
-//#define TIMING
-//#define PRECOLLISIONBC
-
-Calculator::Calculator()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-Calculator::Calculator(Grid3DPtr grid, SynchronizerPtr sync, bool mainThread) : 
-                       grid(grid),
-                       sync(sync),
-                       mainThread(mainThread),
-                       refinement(false)
-{
-   minLevel = grid->getCoarsestInitializedLevel();
-   maxLevel = grid->getFinestInitializedLevel();
-   if(maxLevel > 0)
-      refinement = true;
-   else
-      refinement = false;
-   blocks.resize(maxLevel+1);
-   localConns.resize(maxLevel+1);
-   remoteConns.resize(maxLevel+1);
-   localInterfaceBlockConns.resize(maxLevel+1);
-   remoteInterfaceBlockConns.resize(maxLevel+1);
-   localInterConns.resize(maxLevel);
-   remoteInterConns.resize(maxLevel);
-   loadBalancingComp = false;
-}
-//////////////////////////////////////////////////////////////////////////
-void Calculator::calculate(const double& endTime, CalculationManagerPtr cm, boost::exception_ptr& error)
-{
-   UBLOG(logDEBUG1, "Calculator::calculate() - started");
-   try
-   {
-      initConnectors();
-
-      int anzLevel = maxLevel-minLevel+1;
-
-      int minInitLevel       = minLevel;
-      int maxInitLevel       = maxLevel-minLevel;
-      int straightStartLevel = minInitLevel;
-      int internalIterations = 1 << (maxInitLevel-minInitLevel);
-      int forwardStartLevel;
-      int threshold;
-      int startStep = int(grid->getTimeStep())+1;
-
-      //UBLOG(logINFO, "startStep="<<startStep);
-      int anzCalcSteps = static_cast<int>(endTime);
-#ifdef TIMING
-      UbTimer timer;
-      double time[6];
-#endif
-
-//////////////////////////////////////////////////////////////////////////
-//      UBLOG(logINFO, "Number of connectors = " <<this->localConns[0].size());
-//////////////////////////////////////////////////////////////////////////
-
-      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 
-         if (mainThread) grid->coProcess((double)(calcStep-1));
-         sync->wait();
-
-
-//////////////////////////////////////////////////////////////////////////
-#ifdef TIMING
-         UBLOG(logINFO, "calcStep = " <<calcStep);
-#endif
-//////////////////////////////////////////////////////////////////////////
-         
-         for(int staggeredStep=1; staggeredStep<=internalIterations; staggeredStep++)
-         {
-            forwardStartLevel = straightStartLevel;
-            if(staggeredStep == internalIterations) straightStartLevel = minInitLevel;
-            else
-            {
-               for(straightStartLevel=maxInitLevel,threshold=1;
-                  (staggeredStep&threshold)!=threshold; straightStartLevel--,threshold<<=1);
-            }
-//////////////////////////////////////////////////////////////////////////
-#ifdef TIMING
-            timer.resetAndStart();
-#endif
-//////////////////////////////////////////////////////////////////////////
-
-            //applyPreCollisionBC(straightStartLevel, maxInitLevel);
-
-
-             
-            calculateBlocks(straightStartLevel, maxInitLevel);
-            ////calculateBlocks(minInitLevel, maxInitLevel, staggeredStep);
-//////////////////////////////////////////////////////////////////////////
-#ifdef TIMING
-            time[0] = timer.stop();
-            UBLOG(logINFO, "calculateBlocks time = " <<time[0]);
-#endif
-//////////////////////////////////////////////////////////////////////////
-
-            //exchange data between blocks
-            //Sleep(10000);
-            exchangeBlockData(straightStartLevel, maxInitLevel);
-//////////////////////////////////////////////////////////////////////////
-#ifdef TIMING
-            time[1] = timer.stop();
-            UBLOG(logINFO, "exchangeBlockData time = " <<time[1]);
-#endif
-//////////////////////////////////////////////////////////////////////////
-            //applyBCs(straightStartLevel, maxInitLevel);
-            applyPostCollisionBC(straightStartLevel, maxInitLevel);
-            
-//////////////////////////////////////////////////////////////////////////
-#ifdef TIMING
-            time[2] = timer.stop();
-            UBLOG(logINFO, "applyBCs time = " <<time[2]);
-#endif
-//////////////////////////////////////////////////////////////////////////
-
-            //swap distributions in kernel
-            swapDistributions(straightStartLevel, maxInitLevel);
-
-#ifdef PRECOLLISIONBC
-            exchangeBlockData(straightStartLevel, maxInitLevel);
-            applyPreCollisionBC(straightStartLevel, maxInitLevel);
-#endif
-            
-
-//////////////////////////////////////////////////////////////////////////
-#ifdef TIMING
-            time[3] = timer.stop();
-            UBLOG(logINFO, "swapDistributions time = " <<time[3]);
-#endif
-//////////////////////////////////////////////////////////////////////////
-
-            if (refinement)
-            {
-         //      //exchange data between blocks for grid refinement
-			      ////exchangeInterfaceBlockData(straightStartLevel, maxInitLevel, true);
-         //DOES NOT NEED 
-                     if(straightStartLevel<maxInitLevel)
-                        exchangeBlockData(straightStartLevel, maxInitLevel);
-         //         //exchangeInterfaceBlockData(straightStartLevel, maxInitLevel, true);
-//////////////////////////////////////////////////////////////////////////
-#ifdef TIMING
-               time[4] = timer.stop();
-               UBLOG(logINFO, "refinement exchangeBlockData time = " <<time[4]);
-#endif
-//////////////////////////////////////////////////////////////////////////
-               //now ghost nodes have actual values
-			      //interpolation of interface nodes between grid levels
-               interpolation(straightStartLevel, maxInitLevel);
-//////////////////////////////////////////////////////////////////////////
-#ifdef TIMING
-               time[5] = timer.stop();
-               UBLOG(logINFO, "refinement interpolation time = " <<time[5]);
-#endif
-//////////////////////////////////////////////////////////////////////////
-            }
-
-            sync->wait();
-            if (taValuesCoProcessor && mainThread)
-            {
-               taValuesCoProcessor->calculateSubtotal(calcStep-1);
-            }
-            sync->wait();
-            
-         }
-         //exchange data between blocks for visualization
-        if(mainThread) visScheduler->isDue((double)(calcStep-1));
-        if((int)visScheduler->getNextDueTime() == calcStep)
-        {
-            exchangeBlockData(straightStartLevel, maxInitLevel);
-        }
-         //now ghost nodes have actual values
-
-         //dynamic load balancing
-         //sync->wait();
-         //if (mainThread && !loadBalancingComp)
-         //{
-         //   loadBalancingComp = cm->balance();
-         //}
-
-      }
-      error = boost::exception_ptr();
-      UBLOG(logDEBUG1, "Calculator::calculate() - stoped");
-   }
-   catch( std::exception& e )
-   {
-      //error = boost::current_exception();
-      UBLOG(logERROR, e.what());
-      UBLOG(logERROR, " step = "<<calcStep);
-      Communicator::getInstance()->abort(1);
-      exit(EXIT_FAILURE);
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void Calculator::calculateBlocks(int startLevel, int maxInitLevel)
-{
-   Block3DPtr blockTemp;
-   try
-   {
-      //startLevel bis maxInitLevel
-      for(int level=startLevel; level<=maxInitLevel; level++)
-      {
-         //timer.resetAndStart();
-         //call LBM kernel
-         BOOST_FOREACH(Block3DPtr block, blocks[level])
-         {
-            blockTemp = block;
-            block->getKernel()->calculate();
-         }
-         //timer.stop();
-         //UBLOG(logINFO, "level = " << level << " blocks = " << blocks[level].size() << " collision time = " << timer.getTotalTime());
-      }
-   }
-   catch( std::exception& e )
-   {      
-      //error = boost::current_exception();
-      UBLOG(logERROR, e.what());
-      UBLOG(logERROR, blockTemp->toString()<<" step = "<<calcStep);
-      exit(EXIT_FAILURE);
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void Calculator::calculateBlocks(int minInitLevel, int maxInitLevel, int staggeredStep)
-{
-   int p, maxi, maxir, maxidp, start, end;
-   for(int level=minInitLevel; level<=maxInitLevel; level++)
-   {
-      p = 1<<(maxInitLevel-level);
-      maxi = maxir = static_cast<int>(blocks[level].size());
-      maxidp = maxi/p;
-      if(p > maxi && maxi != 0){
-         maxidp = 1;
-         maxi = p;
-      }
-      start = (staggeredStep-1)*maxidp;
-      if(start >= maxi)
-         start = 0;
-      end = start + maxidp;
-      if((end + p) >= maxi)
-         end = maxi;
-      for (int i = start; i < end; i++)
-      {
-         if(i < maxir)
-            blocks[level][i]->getKernel()->calculate();
-      }
-   }
- }
-//////////////////////////////////////////////////////////////////////////
-void Calculator::addBlock(Block3DPtr block)
-{
-   blocks[block->getLevel()].push_back(block);
-}
-//////////////////////////////////////////////////////////////////////////
-void Calculator::initConnectors()
-{
-   UBLOG(logDEBUG1, "Calculator::initLocalConnectors() - start");
-
-   for (int l = minLevel; l <= maxLevel; l++)
-   {
-      BOOST_FOREACH(Block3DPtr block, blocks[l])
-      {     
-         block->pushBackLocalSameLevelConnectors(localConns[l]);
-
-         if(block->hasInterpolationFlag())
-            block->pushBackLocalSameLevelConnectors(localInterfaceBlockConns[l]);
-         if (l != maxLevel)
-            block->pushBackLocalInterpolationConnectorsCF(localInterConns[l]);
-      }
-      if (l != maxLevel)
-      {
-         BOOST_FOREACH(Block3DPtr block, blocks[l+1])
-         {     
-            block->pushBackLocalInterpolationConnectorsFC(localInterConns[l]);
-         }
-      }
-      UBLOG(logDEBUG5, "Calculator::initConnectors()-initConnectors(localConns["<<l<<"])");
-      initConnectors(localConns[l]);
-
-      if (l != maxLevel)
-      {
-         UBLOG(logDEBUG5, "Calculator::initConnectors()-initConnectors(localInterConns["<<l<<"])");
-         initConnectors(localInterConns[l]);
-      }
-   }
-   
-   if (mainThread)
-      initRemoteConnectors();
-
-   UBLOG(logDEBUG1, "Calculator::initLocalConnectors() - end");
-}
-//////////////////////////////////////////////////////////////////////////
-void Calculator::initRemoteConnectors()
-{
-   std::vector< std::vector< Block3DConnectorPtr > > remoteInterConnsCF;
-   std::vector< std::vector< Block3DConnectorPtr > > remoteInterConnsFC;
-   remoteInterConnsCF.resize(maxLevel+1);
-   remoteInterConnsFC.resize(maxLevel+1);
-
-   int minInitLevel = this->grid->getCoarsestInitializedLevel();
-   int maxInitLevel = this->grid->getFinestInitializedLevel();
-   int gridRank = grid->getRank();
-
-   for(int level = minInitLevel; level<=maxInitLevel;level++)
-   {
-      std::vector<Block3DPtr> blockVector;
-      //grid->getBlocks(level, gridRank, true, blockVector);
-      grid->getBlocks(level, blockVector);
-      BOOST_FOREACH(Block3DPtr block, blockVector)
-      {
-         int l = block->getLevel();
-         block->pushBackRemoteSameLevelConnectors(remoteConns[l]);
-
-         //if(block->isInterface())
-         //   block->pushBackRemoteSameLevelConnectors(remoteInterfaceBlockConns[l]);
-         block->pushBackRemoteInterpolationConnectorsCF(remoteInterConnsCF[l]);
-         block->pushBackRemoteInterpolationConnectorsFC(remoteInterConnsFC[l]);
-      }
-   }
-
-   for (int l = minLevel; l <= maxLevel; l++)
-   {
-      UBLOG(logDEBUG5, "Calculator::initRemoteConnectors()-initConnectors(remoteConns["<<l<<"])");
-      initConnectors(remoteConns[l]);
-      if (l != maxLevel)
-      {
-		 for(int i = 0; i < remoteInterConnsCF[l].size(); i++)
-			remoteInterConns[l].push_back(remoteInterConnsCF[l][i]);
-		 for(int i = 0; i < remoteInterConnsFC[l+1].size(); i++)
-	      remoteInterConns[l].push_back(remoteInterConnsFC[l+1][i]);
-       //UBLOG(logDEBUG5, "Calculator::initRemoteConnectors()-initConnectors(remoteInterConns["<<l<<"])");
-       //initConnectors(remoteInterConns[l]);
-      }
-   }
-   //////////////////////////////////////////////////////////////////////////
-   //UBLOG(logDEBUG5, "Calculator::initConnectors() - connectoren initialisieren - start");
-   for (int l = minLevel; l <= maxLevel; l++)
-   {
-      if (l != maxLevel)
-      {
-         UBLOG(logDEBUG5, "Calculator::initRemoteConnectors()-initConnectors(remoteInterConns["<<l<<"])");
-         BOOST_FOREACH(Block3DConnectorPtr c, remoteInterConns[l] ) c->init();
-      }
-   }
-   //UBLOG(logDEBUG5, "Calculator::initConnectors() - connectoren initialisieren - end");
-   //////////////////////////////////////////////////////////////////////////
-   //sendTransmitterDataSize
-   //UBLOG(logDEBUG5, "Calculator::initConnectors() - sendTransmitterDataSize - start");
-   for (int l = minLevel; l <= maxLevel; l++)
-   {
-      if (l != maxLevel)
-      {
-         UBLOG(logDEBUG5, "Calculator::initRemoteConnectors()-sendTransmitterDataSize(remoteInterConns["<<l<<"])");
-         BOOST_FOREACH(Block3DConnectorPtr c, remoteInterConns[l] ) c->sendTransmitterDataSize();
-      }
-   }
-   //UBLOG(logDEBUG5, "Calculator::initConnectors() - sendTransmitterDataSize - end");
-   //////////////////////////////////////////////////////////////////////////
-   //receiveTransmitterDataSize
-   //wenn er hier bei verteilten berechnungen stopped, dann ist vermutlich auf einer seite ein nicht aktiver block!!!
-   //UBLOG(logDEBUG5, "Calculator::initConnectors() - receiveTransmitterDataSize - start");
-   for (int l = minLevel; l <= maxLevel; l++)
-   {
-      if (l != maxLevel)
-      {
-         UBLOG(logDEBUG5, "Calculator::initRemoteConnectors()-receiveTransmitterDataSize(remoteInterConns["<<l<<"])");
-         BOOST_FOREACH(Block3DConnectorPtr c, remoteInterConns[l] ) c->receiveTransmitterDataSize();
-      }
-   }
-   //UBLOG(logDEBUG5, "Calculator::initConnectors() - receiveTransmitterDataSize - end");
-   //////////////////////////////////////////////////////////////////////////
-}
-//////////////////////////////////////////////////////////////////////////
-void Calculator::initConnectors(std::vector<Block3DConnectorPtr>& connectors)
-{
-   UBLOG(logDEBUG1, "Calculator::initConnectors() - start");
-
-   //initialization
-   //////////////////////////////////////////////////////////////////////////
-   //initialize connectors
-   UBLOG(logDEBUG5, "Calculator::initConnectors() - connectoren initialisieren - start");
-   BOOST_FOREACH(Block3DConnectorPtr c, connectors ) c->init();
-   UBLOG(logDEBUG5, "Calculator::initConnectors() - connectoren initialisieren - end");
-   //////////////////////////////////////////////////////////////////////////
-   //sendTransmitterDataSize
-   UBLOG(logDEBUG5, "Calculator::initConnectors() - sendTransmitterDataSize - start");
-   BOOST_FOREACH(Block3DConnectorPtr c, connectors ) c->sendTransmitterDataSize();
-   UBLOG(logDEBUG5, "Calculator::initConnectors() - sendTransmitterDataSize - end");
-   //////////////////////////////////////////////////////////////////////////
-   //receiveTransmitterDataSize
-   //wenn er hier bei verteilten berechnungen stopped, dann ist vermutlich auf einer seite ein nicht aktiver block!!!
-   UBLOG(logDEBUG5, "Calculator::initConnectors() - receiveTransmitterDataSize - start");
-   BOOST_FOREACH(Block3DConnectorPtr c, connectors ) c->receiveTransmitterDataSize();
-   UBLOG(logDEBUG5, "Calculator::initConnectors() - receiveTransmitterDataSize - end");
-
-   UBLOG(logDEBUG1, "Calculator::initConnectors() - end");
-}
-//////////////////////////////////////////////////////////////////////////
-void Calculator::exchangeBlockData(int startLevel, int maxInitLevel)
-{
-   sync->wait();
-   //startLevel bis maxInitLevel
-   for(int level=startLevel; level<=maxInitLevel; level++)
-   {
-      connectorsPrepare(localConns[level]);
-      connectorsPrepare(remoteConns[level]);
-
-      connectorsSend(localConns[level]);
-      connectorsSend(remoteConns[level]);
-
-      connectorsReceive(localConns[level]);
-      connectorsReceive(remoteConns[level]);
-   }
-   sync->wait();
-}
-//////////////////////////////////////////////////////////////////////////
-void Calculator::exchangeInterfaceBlockData(int startLevel, int maxInitLevel)
-{
-   sync->wait();
-   //startLevel bis maxInitLevel
-   for(int level=startLevel; level<=maxInitLevel; level++)
-   {
-      connectorsPrepare(localInterfaceBlockConns[level]);
-      connectorsPrepare(remoteInterfaceBlockConns[level]);
-
-      connectorsSend(localInterfaceBlockConns[level]);
-      connectorsSend(remoteInterfaceBlockConns[level]);
-
-      connectorsReceive(localInterfaceBlockConns[level]);
-      connectorsReceive(remoteInterfaceBlockConns[level]);
-   }
-   sync->wait();
-}
-//////////////////////////////////////////////////////////////////////////
-void Calculator::swapDistributions(int startLevel, int maxInitLevel)
-{
-   //startLevel bis maxInitLevel
-   for(int level=startLevel; level<=maxInitLevel; level++)
-   {
-      BOOST_FOREACH(Block3DPtr block, blocks[level])
-      {
-         block->getKernel()->swapDistributions();
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void Calculator::connectorsPrepare(std::vector< Block3DConnectorPtr >& connectors)
-{
-   BOOST_FOREACH(Block3DConnectorPtr c, connectors)
-   {
-      c->prepareForReceive();
-      c->prepareForSend();
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void Calculator::connectorsSend(std::vector< Block3DConnectorPtr >& connectors)
-{
-   BOOST_FOREACH(Block3DConnectorPtr c, connectors)
-   {
-      c->fillSendVectors();
-      c->sendVectors();
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void Calculator::connectorsReceive(std::vector< Block3DConnectorPtr >& connectors)
-{
-   BOOST_FOREACH(Block3DConnectorPtr c, connectors)
-   {
-      c->receiveVectors();
-      c->distributeReceiveVectors();
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void Calculator::interpolation(int startLevel, int maxInitLevel)
-{
-   sync->wait();
-
-   for(int level=startLevel; level<maxInitLevel; level++)
-   {
-      connectorsPrepare(localInterConns[level]);
-      connectorsPrepare(remoteInterConns[level]);
-   }
-
-   sync->wait();
-
-   for(int level=startLevel; level<maxInitLevel; level++)
-   {
-      connectorsSend(localInterConns[level]);
-      connectorsSend(remoteInterConns[level]);
-   }
-
-   sync->wait();
-
-   for(int level=startLevel; level<maxInitLevel; level++)
-   {
-      connectorsReceive(localInterConns[level]);
-      connectorsReceive(remoteInterConns[level]);
-   }
-
-   sync->wait();
-
-}
-//////////////////////////////////////////////////////////////////////////
-void Calculator::setVisScheduler(UbSchedulerPtr s)
-{
-   visScheduler = s;
-}
-//////////////////////////////////////////////////////////////////////////
-//double Calculator::getCallculationTime()
-//{
-//   return timer.getTotalTime();
-//}
-//////////////////////////////////////////////////////////////////////////
-std::vector< std::vector< Block3DPtr > > Calculator::getBlocks()
-{
-   return blocks;
-}
-//////////////////////////////////////////////////////////////////////////
-void Calculator::deleteBlocks()
-{
-   BOOST_FOREACH(std::vector< Block3DPtr > &bs, blocks)
-      bs.resize(0);
-}
-//////////////////////////////////////////////////////////////////////////
-void Calculator::deleteConnectors()
-{
-   deleteConnectors(localConns);
-   deleteConnectors(remoteConns);
-
-   deleteConnectors(localInterfaceBlockConns);
-   deleteConnectors(remoteInterfaceBlockConns);
-
-   deleteConnectors(localInterConns);
-   deleteConnectors(remoteInterConns);
-}
-//////////////////////////////////////////////////////////////////////////
-void Calculator::deleteConnectors(std::vector< std::vector< Block3DConnectorPtr > >& conns)
-{
-   BOOST_FOREACH(std::vector< Block3DConnectorPtr > &c, conns)
-      c.resize(0);
-}
-//////////////////////////////////////////////////////////////////////////
-void Calculator::setTimeAveragedValuesCoProcessor(TimeAveragedValuesCoProcessorPtr coProcessor)
-{
-   taValuesCoProcessor = coProcessor;
-}
-
-//////////////////////////////////////////////////////////////////////////
-//void Calculator::applyBCs( int startLevel, int maxInitLevel )
-//{
-//   //startLevel bis maxInitLevel
-//   for(int level=startLevel; level<=maxInitLevel; level++)
-//   {
-//      //call LBM kernel
-//      BOOST_FOREACH(Block3DPtr block, blocks[level])
-//      {
-//         block->getKernel()->getBCProcessor()->applyBC();
-//      }
-//   }
-//}
-//////////////////////////////////////////////////////////////////////////
-void Calculator::applyPreCollisionBC(int startLevel, int maxInitLevel)
-{
-   //startLevel bis maxInitLevel
-   for (int level = startLevel; level<=maxInitLevel; level++)
-   {
-      BOOST_FOREACH(Block3DPtr block, blocks[level])
-      {
-         block->getKernel()->getBCProcessor()->applyPreCollisionBC();
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void Calculator::applyPostCollisionBC(int startLevel, int maxInitLevel)
-{
-   //startLevel bis maxInitLevel
-   for (int level = startLevel; level<=maxInitLevel; level++)
-   {
-      BOOST_FOREACH(Block3DPtr block, blocks[level])
-      {
-         block->getKernel()->getBCProcessor()->applyPostCollisionBC();
-      }
-   }
-}
-
+#include "Calculator.h"
+#include <basics/utilities/UbException.h>
+
+#include "Grid3D.h"
+#include "Synchronizer.h"
+
+#include "basics/writer/WbWriterVtkXmlASCII.h"
+
+#include "LBMKernel.h"
+#include "CalculationManager.h"
+#include "Block3DConnector.h"
+#include "Block3D.h"
+#include "BCProcessor.h"
+#include "TimeAveragedValuesCoProcessor.h"
+#include "UbScheduler.h"
+#include "Communicator.h"
+
+//#define TIMING
+//#define PRECOLLISIONBC
+
+Calculator::Calculator()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+Calculator::Calculator(Grid3DPtr grid, SynchronizerPtr sync, bool mainThread) : 
+                       grid(grid),
+                       sync(sync),
+                       mainThread(mainThread),
+                       refinement(false)
+{
+   minLevel = grid->getCoarsestInitializedLevel();
+   maxLevel = grid->getFinestInitializedLevel();
+   if(maxLevel > 0)
+      refinement = true;
+   else
+      refinement = false;
+   blocks.resize(maxLevel+1);
+   localConns.resize(maxLevel+1);
+   remoteConns.resize(maxLevel+1);
+   localInterfaceBlockConns.resize(maxLevel+1);
+   remoteInterfaceBlockConns.resize(maxLevel+1);
+   localInterConns.resize(maxLevel);
+   remoteInterConns.resize(maxLevel);
+   loadBalancingComp = false;
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::calculate(const double& endTime, CalculationManagerPtr cm, boost::exception_ptr& error)
+{
+   UBLOG(logDEBUG1, "Calculator::calculate() - started");
+   try
+   {
+      initConnectors();
+
+      int anzLevel = maxLevel-minLevel+1;
+
+      int minInitLevel       = minLevel;
+      int maxInitLevel       = maxLevel-minLevel;
+      int straightStartLevel = minInitLevel;
+      int internalIterations = 1 << (maxInitLevel-minInitLevel);
+      int forwardStartLevel;
+      int threshold;
+      int startStep = int(grid->getTimeStep())+1;
+
+      //UBLOG(logINFO, "startStep="<<startStep);
+      int anzCalcSteps = static_cast<int>(endTime);
+#ifdef TIMING
+      UbTimer timer;
+      double time[6];
+#endif
+
+//////////////////////////////////////////////////////////////////////////
+//      UBLOG(logINFO, "Number of connectors = " <<this->localConns[0].size());
+//////////////////////////////////////////////////////////////////////////
+
+      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 
+         if (mainThread) grid->coProcess((double)(calcStep-1));
+         sync->wait();
+
+
+//////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+         UBLOG(logINFO, "calcStep = " <<calcStep);
+#endif
+//////////////////////////////////////////////////////////////////////////
+         
+         for(int staggeredStep=1; staggeredStep<=internalIterations; staggeredStep++)
+         {
+            forwardStartLevel = straightStartLevel;
+            if(staggeredStep == internalIterations) straightStartLevel = minInitLevel;
+            else
+            {
+               for(straightStartLevel=maxInitLevel,threshold=1;
+                  (staggeredStep&threshold)!=threshold; straightStartLevel--,threshold<<=1);
+            }
+//////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+            timer.resetAndStart();
+#endif
+//////////////////////////////////////////////////////////////////////////
+
+            //applyPreCollisionBC(straightStartLevel, maxInitLevel);
+
+
+             
+            calculateBlocks(straightStartLevel, maxInitLevel);
+            ////calculateBlocks(minInitLevel, maxInitLevel, staggeredStep);
+//////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+            time[0] = timer.stop();
+            UBLOG(logINFO, "calculateBlocks time = " <<time[0]);
+#endif
+//////////////////////////////////////////////////////////////////////////
+
+            //exchange data between blocks
+            //Sleep(10000);
+            exchangeBlockData(straightStartLevel, maxInitLevel);
+//////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+            time[1] = timer.stop();
+            UBLOG(logINFO, "exchangeBlockData time = " <<time[1]);
+#endif
+//////////////////////////////////////////////////////////////////////////
+            //applyBCs(straightStartLevel, maxInitLevel);
+            applyPostCollisionBC(straightStartLevel, maxInitLevel);
+            
+//////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+            time[2] = timer.stop();
+            UBLOG(logINFO, "applyBCs time = " <<time[2]);
+#endif
+//////////////////////////////////////////////////////////////////////////
+
+            //swap distributions in kernel
+            swapDistributions(straightStartLevel, maxInitLevel);
+
+#ifdef PRECOLLISIONBC
+            exchangeBlockData(straightStartLevel, maxInitLevel);
+            applyPreCollisionBC(straightStartLevel, maxInitLevel);
+#endif
+            
+
+//////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+            time[3] = timer.stop();
+            UBLOG(logINFO, "swapDistributions time = " <<time[3]);
+#endif
+//////////////////////////////////////////////////////////////////////////
+
+            if (refinement)
+            {
+         //      //exchange data between blocks for grid refinement
+			      ////exchangeInterfaceBlockData(straightStartLevel, maxInitLevel, true);
+         //DOES NOT NEED 
+                     if(straightStartLevel<maxInitLevel)
+                        exchangeBlockData(straightStartLevel, maxInitLevel);
+         //         //exchangeInterfaceBlockData(straightStartLevel, maxInitLevel, true);
+//////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+               time[4] = timer.stop();
+               UBLOG(logINFO, "refinement exchangeBlockData time = " <<time[4]);
+#endif
+//////////////////////////////////////////////////////////////////////////
+               //now ghost nodes have actual values
+			      //interpolation of interface nodes between grid levels
+               interpolation(straightStartLevel, maxInitLevel);
+//////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+               time[5] = timer.stop();
+               UBLOG(logINFO, "refinement interpolation time = " <<time[5]);
+#endif
+//////////////////////////////////////////////////////////////////////////
+            }
+
+            sync->wait();
+            if (taValuesCoProcessor && mainThread)
+            {
+               taValuesCoProcessor->calculateSubtotal(calcStep-1);
+            }
+            sync->wait();
+            
+         }
+         //exchange data between blocks for visualization
+        if(mainThread) visScheduler->isDue((double)(calcStep-1));
+        if((int)visScheduler->getNextDueTime() == calcStep)
+        {
+            exchangeBlockData(straightStartLevel, maxInitLevel);
+        }
+         //now ghost nodes have actual values
+
+         //dynamic load balancing
+         //sync->wait();
+         //if (mainThread && !loadBalancingComp)
+         //{
+         //   loadBalancingComp = cm->balance();
+         //}
+
+      }
+      error = boost::exception_ptr();
+      UBLOG(logDEBUG1, "Calculator::calculate() - stoped");
+   }
+   catch( std::exception& e )
+   {
+      //error = boost::current_exception();
+      UBLOG(logERROR, e.what());
+      UBLOG(logERROR, " step = "<<calcStep);
+      Communicator::getInstance()->abort(1);
+      exit(EXIT_FAILURE);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::calculateBlocks(int startLevel, int maxInitLevel)
+{
+   Block3DPtr blockTemp;
+   try
+   {
+      //startLevel bis maxInitLevel
+      for(int level = startLevel; level <= maxInitLevel; level++)
+      {
+         //timer.resetAndStart();
+         //call LBM kernel
+         for(Block3DPtr block : blocks[level])
+         {
+            blockTemp = block;
+            block->getKernel()->calculate();
+         }
+         //timer.stop();
+         //UBLOG(logINFO, "level = " << level << " blocks = " << blocks[level].size() << " collision time = " << timer.getTotalTime());
+      }
+   }
+   catch( std::exception& e )
+   {      
+      //error = boost::current_exception();
+      UBLOG(logERROR, e.what());
+      UBLOG(logERROR, blockTemp->toString()<<" step = "<<calcStep);
+      exit(EXIT_FAILURE);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::calculateBlocks(int minInitLevel, int maxInitLevel, int staggeredStep)
+{
+   int p, maxi, maxir, maxidp, start, end;
+   for(int level=minInitLevel; level<=maxInitLevel; level++)
+   {
+      p = 1<<(maxInitLevel-level);
+      maxi = maxir = static_cast<int>(blocks[level].size());
+      maxidp = maxi/p;
+      if(p > maxi && maxi != 0){
+         maxidp = 1;
+         maxi = p;
+      }
+      start = (staggeredStep-1)*maxidp;
+      if(start >= maxi)
+         start = 0;
+      end = start + maxidp;
+      if((end + p) >= maxi)
+         end = maxi;
+      for (int i = start; i < end; i++)
+      {
+         if(i < maxir)
+            blocks[level][i]->getKernel()->calculate();
+      }
+   }
+ }
+//////////////////////////////////////////////////////////////////////////
+void Calculator::addBlock(Block3DPtr block)
+{
+   blocks[block->getLevel()].push_back(block);
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::initConnectors()
+{
+   UBLOG(logDEBUG1, "Calculator::initLocalConnectors() - start");
+
+   for (int l = minLevel; l <= maxLevel; l++)
+   {
+      for(Block3DPtr block : blocks[l])
+      {     
+         block->pushBackLocalSameLevelConnectors(localConns[l]);
+
+         if(block->hasInterpolationFlag())
+            block->pushBackLocalSameLevelConnectors(localInterfaceBlockConns[l]);
+         if (l != maxLevel)
+            block->pushBackLocalInterpolationConnectorsCF(localInterConns[l]);
+      }
+      if (l != maxLevel)
+      {
+         for(Block3DPtr block : blocks[l+1])
+         {     
+            block->pushBackLocalInterpolationConnectorsFC(localInterConns[l]);
+         }
+      }
+      UBLOG(logDEBUG5, "Calculator::initConnectors()-initConnectors(localConns["<<l<<"])");
+      initConnectors(localConns[l]);
+
+      if (l != maxLevel)
+      {
+         UBLOG(logDEBUG5, "Calculator::initConnectors()-initConnectors(localInterConns["<<l<<"])");
+         initConnectors(localInterConns[l]);
+      }
+   }
+   
+   if (mainThread)
+      initRemoteConnectors();
+
+   UBLOG(logDEBUG1, "Calculator::initLocalConnectors() - end");
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::initRemoteConnectors()
+{
+   std::vector< std::vector< Block3DConnectorPtr > > remoteInterConnsCF;
+   std::vector< std::vector< Block3DConnectorPtr > > remoteInterConnsFC;
+   remoteInterConnsCF.resize(maxLevel+1);
+   remoteInterConnsFC.resize(maxLevel+1);
+
+   int minInitLevel = this->grid->getCoarsestInitializedLevel();
+   int maxInitLevel = this->grid->getFinestInitializedLevel();
+   int gridRank = grid->getRank();
+
+   for(int level = minInitLevel; level<=maxInitLevel;level++)
+   {
+      std::vector<Block3DPtr> blockVector;
+      //grid->getBlocks(level, gridRank, true, blockVector);
+      grid->getBlocks(level, blockVector);
+      for(Block3DPtr block : blockVector)
+      {
+         int l = block->getLevel();
+         block->pushBackRemoteSameLevelConnectors(remoteConns[l]);
+
+         //if(block->isInterface())
+         //   block->pushBackRemoteSameLevelConnectors(remoteInterfaceBlockConns[l]);
+         block->pushBackRemoteInterpolationConnectorsCF(remoteInterConnsCF[l]);
+         block->pushBackRemoteInterpolationConnectorsFC(remoteInterConnsFC[l]);
+      }
+   }
+
+   for (int l = minLevel; l <= maxLevel; l++)
+   {
+      UBLOG(logDEBUG5, "Calculator::initRemoteConnectors()-initConnectors(remoteConns["<<l<<"])");
+      initConnectors(remoteConns[l]);
+      if (l != maxLevel)
+      {
+		 for(int i = 0; i < remoteInterConnsCF[l].size(); i++)
+			remoteInterConns[l].push_back(remoteInterConnsCF[l][i]);
+		 for(int i = 0; i < remoteInterConnsFC[l+1].size(); i++)
+	      remoteInterConns[l].push_back(remoteInterConnsFC[l+1][i]);
+       //UBLOG(logDEBUG5, "Calculator::initRemoteConnectors()-initConnectors(remoteInterConns["<<l<<"])");
+       //initConnectors(remoteInterConns[l]);
+      }
+   }
+   //////////////////////////////////////////////////////////////////////////
+   //UBLOG(logDEBUG5, "Calculator::initConnectors() - connectoren initialisieren - start");
+   for (int l = minLevel; l <= maxLevel; l++)
+   {
+      if (l != maxLevel)
+      {
+         UBLOG(logDEBUG5, "Calculator::initRemoteConnectors()-initConnectors(remoteInterConns["<<l<<"])");
+         for(Block3DConnectorPtr c : remoteInterConns[l] ) c->init();
+      }
+   }
+   //UBLOG(logDEBUG5, "Calculator::initConnectors() - connectoren initialisieren - end");
+   //////////////////////////////////////////////////////////////////////////
+   //sendTransmitterDataSize
+   //UBLOG(logDEBUG5, "Calculator::initConnectors() - sendTransmitterDataSize - start");
+   for (int l = minLevel; l <= maxLevel; l++)
+   {
+      if (l != maxLevel)
+      {
+         UBLOG(logDEBUG5, "Calculator::initRemoteConnectors()-sendTransmitterDataSize(remoteInterConns["<<l<<"])");
+         for(Block3DConnectorPtr c : remoteInterConns[l] ) c->sendTransmitterDataSize();
+      }
+   }
+   //UBLOG(logDEBUG5, "Calculator::initConnectors() - sendTransmitterDataSize - end");
+   //////////////////////////////////////////////////////////////////////////
+   //receiveTransmitterDataSize
+   //wenn er hier bei verteilten berechnungen stopped, dann ist vermutlich auf einer seite ein nicht aktiver block!!!
+   //UBLOG(logDEBUG5, "Calculator::initConnectors() - receiveTransmitterDataSize - start");
+   for (int l = minLevel; l <= maxLevel; l++)
+   {
+      if (l != maxLevel)
+      {
+         UBLOG(logDEBUG5, "Calculator::initRemoteConnectors()-receiveTransmitterDataSize(remoteInterConns["<<l<<"])");
+         for(Block3DConnectorPtr c : remoteInterConns[l] ) c->receiveTransmitterDataSize();
+      }
+   }
+   //UBLOG(logDEBUG5, "Calculator::initConnectors() - receiveTransmitterDataSize - end");
+   //////////////////////////////////////////////////////////////////////////
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::initConnectors(std::vector<Block3DConnectorPtr>& connectors)
+{
+   UBLOG(logDEBUG1, "Calculator::initConnectors() - start");
+
+   //initialization
+   //////////////////////////////////////////////////////////////////////////
+   //initialize connectors
+   UBLOG(logDEBUG5, "Calculator::initConnectors() - connectoren initialisieren - start");
+   for(Block3DConnectorPtr c : connectors ) c->init();
+   UBLOG(logDEBUG5, "Calculator::initConnectors() - connectoren initialisieren - end");
+   //////////////////////////////////////////////////////////////////////////
+   //sendTransmitterDataSize
+   UBLOG(logDEBUG5, "Calculator::initConnectors() - sendTransmitterDataSize - start");
+   for(Block3DConnectorPtr c : connectors ) c->sendTransmitterDataSize();
+   UBLOG(logDEBUG5, "Calculator::initConnectors() - sendTransmitterDataSize - end");
+   //////////////////////////////////////////////////////////////////////////
+   //receiveTransmitterDataSize
+   //wenn er hier bei verteilten berechnungen stopped, dann ist vermutlich auf einer seite ein nicht aktiver block!!!
+   UBLOG(logDEBUG5, "Calculator::initConnectors() - receiveTransmitterDataSize - start");
+   for(Block3DConnectorPtr c : connectors ) c->receiveTransmitterDataSize();
+   UBLOG(logDEBUG5, "Calculator::initConnectors() - receiveTransmitterDataSize - end");
+
+   UBLOG(logDEBUG1, "Calculator::initConnectors() - end");
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::exchangeBlockData(int startLevel, int maxInitLevel)
+{
+   sync->wait();
+   //startLevel bis maxInitLevel
+   for(int level=startLevel; level<=maxInitLevel; level++)
+   {
+      connectorsPrepare(localConns[level]);
+      connectorsPrepare(remoteConns[level]);
+
+      connectorsSend(localConns[level]);
+      connectorsSend(remoteConns[level]);
+
+      connectorsReceive(localConns[level]);
+      connectorsReceive(remoteConns[level]);
+   }
+   sync->wait();
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::exchangeInterfaceBlockData(int startLevel, int maxInitLevel)
+{
+   sync->wait();
+   //startLevel bis maxInitLevel
+   for(int level=startLevel; level<=maxInitLevel; level++)
+   {
+      connectorsPrepare(localInterfaceBlockConns[level]);
+      connectorsPrepare(remoteInterfaceBlockConns[level]);
+
+      connectorsSend(localInterfaceBlockConns[level]);
+      connectorsSend(remoteInterfaceBlockConns[level]);
+
+      connectorsReceive(localInterfaceBlockConns[level]);
+      connectorsReceive(remoteInterfaceBlockConns[level]);
+   }
+   sync->wait();
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::swapDistributions(int startLevel, int maxInitLevel)
+{
+   //startLevel bis maxInitLevel
+   for(int level=startLevel; level<=maxInitLevel; level++)
+   {
+      for(Block3DPtr block : blocks[level])
+      {
+         block->getKernel()->swapDistributions();
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::connectorsPrepare(std::vector< Block3DConnectorPtr >& connectors)
+{
+   for(Block3DConnectorPtr c : connectors)
+   {
+      c->prepareForReceive();
+      c->prepareForSend();
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::connectorsSend(std::vector< Block3DConnectorPtr >& connectors)
+{
+   for(Block3DConnectorPtr c : connectors)
+   {
+      c->fillSendVectors();
+      c->sendVectors();
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::connectorsReceive(std::vector< Block3DConnectorPtr >& connectors)
+{
+   for(Block3DConnectorPtr c : connectors)
+   {
+      c->receiveVectors();
+      c->distributeReceiveVectors();
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::interpolation(int startLevel, int maxInitLevel)
+{
+   sync->wait();
+
+   for(int level=startLevel; level<maxInitLevel; level++)
+   {
+      connectorsPrepare(localInterConns[level]);
+      connectorsPrepare(remoteInterConns[level]);
+   }
+
+   sync->wait();
+
+   for(int level=startLevel; level<maxInitLevel; level++)
+   {
+      connectorsSend(localInterConns[level]);
+      connectorsSend(remoteInterConns[level]);
+   }
+
+   sync->wait();
+
+   for(int level=startLevel; level<maxInitLevel; level++)
+   {
+      connectorsReceive(localInterConns[level]);
+      connectorsReceive(remoteInterConns[level]);
+   }
+
+   sync->wait();
+
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::setVisScheduler(UbSchedulerPtr s)
+{
+   visScheduler = s;
+}
+//////////////////////////////////////////////////////////////////////////
+//double Calculator::getCalculationTime()
+//{
+//   return timer.getTotalTime();
+//}
+//////////////////////////////////////////////////////////////////////////
+std::vector< std::vector< Block3DPtr > > Calculator::getBlocks() const
+{
+   return blocks;
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::deleteBlocks()
+{
+   for(std::vector< Block3DPtr > &bs : blocks)
+      bs.resize(0);
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::deleteConnectors()
+{
+   deleteConnectors(localConns);
+   deleteConnectors(remoteConns);
+
+   deleteConnectors(localInterfaceBlockConns);
+   deleteConnectors(remoteInterfaceBlockConns);
+
+   deleteConnectors(localInterConns);
+   deleteConnectors(remoteInterConns);
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::deleteConnectors(std::vector< std::vector< Block3DConnectorPtr > >& conns)
+{
+   for(std::vector< Block3DConnectorPtr > &c : conns)
+      c.resize(0);
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::setTimeAveragedValuesCoProcessor(TimeAveragedValuesCoProcessorPtr coProcessor)
+{
+   taValuesCoProcessor = coProcessor;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//void Calculator::applyBCs( int startLevel, int maxInitLevel )
+//{
+//   //startLevel bis maxInitLevel
+//   for(int level=startLevel; level<=maxInitLevel; level++)
+//   {
+//      //call LBM kernel
+//      for(Block3DPtr block : blocks[level])
+//      {
+//         block->getKernel()->getBCProcessor()->applyBC();
+//      }
+//   }
+//}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::applyPreCollisionBC(int startLevel, int maxInitLevel)
+{
+   //startLevel bis maxInitLevel
+   for (int level = startLevel; level<=maxInitLevel; level++)
+   {
+      for(Block3DPtr block : blocks[level])
+      {
+         block->getKernel()->getBCProcessor()->applyPreCollisionBC();
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::applyPostCollisionBC(int startLevel, int maxInitLevel)
+{
+   //startLevel bis maxInitLevel
+   for (int level = startLevel; level<=maxInitLevel; level++)
+   {
+      for(Block3DPtr block : blocks[level])
+      {
+         block->getKernel()->getBCProcessor()->applyPostCollisionBC();
+      }
+   }
+}
+
diff --git a/source/VirtualFluidsCore/Grid/Calculator.h b/source/VirtualFluidsCore/Grid/Calculator.h
index fbb9e20e8..12c40d3d6 100644
--- a/source/VirtualFluidsCore/Grid/Calculator.h
+++ b/source/VirtualFluidsCore/Grid/Calculator.h
@@ -1,87 +1,91 @@
-#ifndef CALCULATOR_H
-#define CALCULATOR_H
-
-#include "Grid3D.h"
-#include "Block3D.h"
-#include "Synchronizer.h"
-#include "MathUtil.hpp"
-#include "basics/utilities/UbScheduler.h"
-#include "basics/utilities/UbTiming.h"
-#include "LoadBalancer.h"
-#include "TimeAveragedValuesCoProcessor.h"
-
-
-class Calculator;
-typedef boost::shared_ptr<Calculator> CalculatorPtr;
-
-#include "CalculationManager.h"
-
-class Calculator 
-{
-public:
-   Calculator();
-   Calculator(Grid3DPtr grid, SynchronizerPtr sync, bool mainThread = true);
-   virtual ~Calculator(){}
-   virtual void calculate(const double& endTime, CalculationManagerPtr cm, boost::exception_ptr& error);
-   void addBlock(Block3DPtr block);
-   void initConnectors();
-   void setVisScheduler(UbSchedulerPtr s);
-   //double getCallculationTime();
-   std::vector< std::vector< Block3DPtr > > getBlocks(); 
-   void deleteBlocks();
-   void deleteConnectors();
-
-   void setTimeAveragedValuesCoProcessor(TimeAveragedValuesCoProcessorPtr coProcessor);
-
-protected:
-   void calculateBlocks(int startLevel, int maxInitLevel);
-   void calculateBlocks(int minInitLevel, int maxInitLevel, int staggeredStep);
-   void initConnectors(std::vector<Block3DConnectorPtr>& connectors);
-   virtual void initRemoteConnectors();
-   void swapDistributions(int startLevel, int maxInitLevel);
-   virtual void exchangeBlockData(int startLevel, int maxInitLevel);
-   void exchangeInterfaceBlockData(int startLevel, int maxInitLevel);
-   virtual void connectorsPrepare(std::vector< Block3DConnectorPtr >& connectors);
-   virtual void connectorsSend(std::vector< Block3DConnectorPtr >& connectors);
-   virtual void connectorsReceive(std::vector< Block3DConnectorPtr >& connectors);
-   void interpolation(int startLevel, int maxInitLevel);
-   void deleteConnectors(std::vector< std::vector< Block3DConnectorPtr > >& conns);
-   //void applyBCs(int startLevel, int maxInitLevel);
-   void applyPreCollisionBC(int startLevel, int maxInitLevel);
-   void applyPostCollisionBC(int startLevel, int maxInitLevel);
-   int minLevel, maxLevel;
-   std::vector< std::vector< Block3DConnectorPtr > > localConns;
-   std::vector< std::vector< Block3DConnectorPtr > > remoteConns;
-   SynchronizerPtr sync;
-
-   boost::barrier* bar;
-   //double time;
-
-   bool mainThread;
-   bool refinement;
-   Grid3DPtr grid;
-   UbSchedulerPtr visScheduler;
-   int calcStep;
-   std::vector< std::vector<Block3DPtr> > blocks;
-
-
-   std::vector< std::vector< Block3DConnectorPtr > > localInterfaceBlockConns;
-   std::vector< std::vector< Block3DConnectorPtr > > remoteInterfaceBlockConns;
-
-   //localInterConns and remoteInterConns save interpolation connectors 
-   //every element save CF connectors for current level and FC connectors for next level
-   //e.g. 
-   //localInterConns[0] = CF(0), FC(1)
-   //localInterConns[1] = CF(1), FC(2)
-   //localInterConns[2] 
-   std::vector< std::vector< Block3DConnectorPtr > > localInterConns;
-   std::vector< std::vector< Block3DConnectorPtr > > remoteInterConns;
-
-   //UbTimer timer, timer2, timer3;
-   bool loadBalancingComp;
-
-   TimeAveragedValuesCoProcessorPtr taValuesCoProcessor;
-
-};
-
-#endif
+#ifndef CALCULATOR_H
+#define CALCULATOR_H
+
+#include <memory>
+#include <vector>
+
+class Grid3D;
+class Synchronizer;
+class UbScheduler;
+class CalculationManager;
+class Block3D;
+class Block3DConnector;
+class TimeAveragedValuesCoProcessor;
+
+
+#include <boost/thread/barrier.hpp>
+#include <boost/exception_ptr.hpp>
+
+class Calculator;
+typedef std::shared_ptr<Calculator> CalculatorPtr;
+
+
+class Calculator 
+{
+public:
+   Calculator();
+   Calculator(std::shared_ptr<Grid3D> grid, std::shared_ptr<Synchronizer> sync, bool mainThread = true);
+   virtual ~Calculator(){}
+   virtual void calculate(const double& endTime, std::shared_ptr<CalculationManager> cm, boost::exception_ptr& error);
+   void addBlock(std::shared_ptr<Block3D> block);
+   void initConnectors();
+   void setVisScheduler(std::shared_ptr<UbScheduler> s);
+   //double getCalculationTime();
+   std::vector< std::vector< std::shared_ptr<Block3D> > > getBlocks() const;
+   void deleteBlocks();
+   void deleteConnectors();
+
+   void setTimeAveragedValuesCoProcessor(std::shared_ptr<TimeAveragedValuesCoProcessor> coProcessor);
+
+protected:
+   void calculateBlocks(int startLevel, int maxInitLevel);
+   void calculateBlocks(int minInitLevel, int maxInitLevel, int staggeredStep);
+   void initConnectors(std::vector<std::shared_ptr<Block3DConnector> >& connectors);
+   virtual void initRemoteConnectors();
+   void swapDistributions(int startLevel, int maxInitLevel);
+   virtual void exchangeBlockData(int startLevel, int maxInitLevel);
+   void exchangeInterfaceBlockData(int startLevel, int maxInitLevel);
+   virtual void connectorsPrepare(std::vector< std::shared_ptr<Block3DConnector> >& connectors);
+   virtual void connectorsSend(std::vector< std::shared_ptr<Block3DConnector> >& connectors);
+   virtual void connectorsReceive(std::vector< std::shared_ptr<Block3DConnector> >& connectors);
+   void interpolation(int startLevel, int maxInitLevel);
+   void deleteConnectors(std::vector< std::vector< std::shared_ptr<Block3DConnector> > >& conns);
+   //void applyBCs(int startLevel, int maxInitLevel);
+   void applyPreCollisionBC(int startLevel, int maxInitLevel);
+   void applyPostCollisionBC(int startLevel, int maxInitLevel);
+   int minLevel, maxLevel;
+   std::vector< std::vector< std::shared_ptr<Block3DConnector> > > localConns;
+   std::vector< std::vector< std::shared_ptr<Block3DConnector> > > remoteConns;
+   std::shared_ptr<Synchronizer> sync;
+
+   boost::barrier* bar;
+   //double time;
+
+   bool mainThread;
+   bool refinement;
+   std::shared_ptr<Grid3D> grid;
+   std::shared_ptr<UbScheduler> visScheduler;
+   int calcStep;
+   std::vector< std::vector<std::shared_ptr<Block3D> > > blocks;
+
+
+   std::vector< std::vector< std::shared_ptr<Block3DConnector> > > localInterfaceBlockConns;
+   std::vector< std::vector< std::shared_ptr<Block3DConnector> > > remoteInterfaceBlockConns;
+
+   //localInterConns and remoteInterConns save interpolation connectors 
+   //every element save CF connectors for current level and FC connectors for next level
+   //e.g. 
+   //localInterConns[0] = CF(0), FC(1)
+   //localInterConns[1] = CF(1), FC(2)
+   //localInterConns[2] 
+   std::vector< std::vector< std::shared_ptr<Block3DConnector> > > localInterConns;
+   std::vector< std::vector< std::shared_ptr<Block3DConnector> > > remoteInterConns;
+
+   //UbTimer timer, timer2, timer3;
+   bool loadBalancingComp;
+
+   std::shared_ptr<TimeAveragedValuesCoProcessor> taValuesCoProcessor;
+
+};
+
+#endif
diff --git a/source/VirtualFluidsCore/Grid/CalculatorFactory.h b/source/VirtualFluidsCore/Grid/CalculatorFactory.h
new file mode 100644
index 000000000..e530102ce
--- /dev/null
+++ b/source/VirtualFluidsCore/Grid/CalculatorFactory.h
@@ -0,0 +1,33 @@
+/*
+*  Author: S. Peters
+*  mail: peters@irmb.tu-bs.de
+*/
+#ifndef CalculatorFactory_H
+#define CalculatorFactory_H
+
+#include <memory>
+
+class Calculator;
+class UbScheduler;
+class Synchronizer;
+class Grid3D;
+
+enum class CalculatorType
+{
+    HYBRID, MPI, PREPOSTBC, FETOL, DEM
+};
+
+class CalculatorFactory
+{
+public:
+    explicit CalculatorFactory(std::shared_ptr<UbScheduler> visScheduler) : visScheduler(visScheduler) { }
+    virtual ~CalculatorFactory() {}
+
+    virtual std::shared_ptr<Calculator> makeCalculator(std::shared_ptr<Grid3D> grid, std::shared_ptr<Synchronizer> sync, bool isMainThread, CalculatorType type) = 0;
+
+protected:
+    std::shared_ptr<UbScheduler> visScheduler;
+}; 
+
+#endif 
+
diff --git a/source/VirtualFluidsCore/Grid/ConcreteCalculatorFactory.h b/source/VirtualFluidsCore/Grid/ConcreteCalculatorFactory.h
new file mode 100644
index 000000000..281b809bf
--- /dev/null
+++ b/source/VirtualFluidsCore/Grid/ConcreteCalculatorFactory.h
@@ -0,0 +1,55 @@
+#ifndef ConcreteCalculatorFactory_H
+#define ConcreteCalculatorFactory_H
+
+
+#include <memory>
+
+#include "Grid3D.h"
+
+#include "Calculator.h"
+#include "MPICalculator.h"
+#include "PrePostBcCalculator.h"
+
+#include "CalculatorFactory.h"
+
+
+class ConcreteCalculatorFactory : public CalculatorFactory
+{
+public:
+    ConcreteCalculatorFactory(UbSchedulerPtr visScheduler) : CalculatorFactory(visScheduler){}
+    virtual ~ConcreteCalculatorFactory() {}
+
+    std::shared_ptr<Calculator> makeCalculator(Grid3DPtr grid, SynchronizerPtr sync, bool isMainThread, CalculatorType type) override
+    {
+        std::shared_ptr<Calculator> calculator;
+        switch(type)
+        {
+        case CalculatorType::HYBRID:
+            calculator = std::make_shared<Calculator>(grid, sync, isMainThread);
+            break;
+        case CalculatorType::MPI:
+            calculator = std::make_shared<MPICalculator>(grid);
+            break;
+        case CalculatorType::PREPOSTBC:
+            calculator = std::make_shared<PrePostBcCalculator>(grid, sync, isMainThread);
+            break;
+        #if defined CalculatorType::VF_FETOL
+        case FETOL:
+            calculator = std::make_shared<FetolCalculator>(grid);
+            break;
+        #endif
+        default: 
+            throw std::runtime_error("CalculatorType not valid in ConcreteCalculatorFactory");
+        }
+ 
+        calculator->setVisScheduler(visScheduler);
+        return calculator;
+    }
+
+
+};
+
+
+
+#endif 
+
diff --git a/source/VirtualFluidsCore/Grid/Grid3D.cpp b/source/VirtualFluidsCore/Grid/Grid3D.cpp
index 7943635ee..8323279de 100644
--- a/source/VirtualFluidsCore/Grid/Grid3D.cpp
+++ b/source/VirtualFluidsCore/Grid/Grid3D.cpp
@@ -1,2027 +1,2027 @@
-#include "Grid3D.h"
-
-#include <vector>
-#include <boost/foreach.hpp>
-#include <boost/functional/hash.hpp>
-
-#include <basics/writer/WbWriterVtkXmlASCII.h>
-#include "Grid3DVisitor.h"
-#include "Block3DVisitor.h"
-#include "Interactor3D.h"
-#include "Grid3DSystem.h"
-
-
-using namespace std;
-
-Grid3D::Grid3D() : 
-                     rank(0),
-                     bundle(0),
-                     orgDeltaX(1.0),
-                     periodicX1(false),
-                     periodicX2(false),
-                     periodicX3(false),
-                     timeStep(0.0),
-                     blockNx1(0),
-                     blockNx2(0),
-                     blockNx3(0),
-                     nx1(0),
-                     nx2(0),
-                     nx3(0)
-{
-   levelSet.resize(Grid3DSystem::MAXLEVEL+1);
-}
-//////////////////////////////////////////////////////////////////////////
-Grid3D::Grid3D(CommunicatorPtr comm) : 
-   rank(0),
-   bundle(0),
-   orgDeltaX(1.0),
-   periodicX1(false),
-   periodicX2(false),
-   periodicX3(false),
-   timeStep(0.0),
-   blockNx1(0),
-   blockNx2(0),
-   blockNx3(0),
-   nx1(0),
-   nx2(0),
-   nx3(0)
-{
-   levelSet.resize(Grid3DSystem::MAXLEVEL+1);
-   bundle = comm->getBundleID();
-   rank = comm->getProcessID();
-}
-//////////////////////////////////////////////////////////////////////////
-Grid3D::Grid3D( CommunicatorPtr comm, int blockNx1, int blockNx2, int blockNx3, int gridNx1, int gridNx2, int gridNx3 ) : 
-   rank(0),
-   bundle(0),
-   orgDeltaX(1.0),
-   periodicX1(false),
-   periodicX2(false),
-   periodicX3(false),
-   timeStep(0.0),
-   blockNx1(blockNx1),
-   blockNx2(blockNx2),
-   blockNx3(blockNx2),
-   nx1(gridNx1),
-   nx2(gridNx2),
-   nx3(gridNx3)
-{
-   levelSet.resize(Grid3DSystem::MAXLEVEL+1);
-   bundle = comm->getBundleID();
-   rank = comm->getProcessID();
-   trafo = CoordinateTransformation3DPtr(new CoordinateTransformation3D(0.0, 0.0, 0.0, (double)blockNx1, (double)blockNx2, (double)blockNx3));
-   UbTupleInt3 minInd(0, 0, 0);
-   UbTupleInt3 maxInd(gridNx1, gridNx2, gridNx3);
-   this->fillExtentWithBlocks(minInd, maxInd);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::addInteractor(Interactor3DPtr interactor)
-{
-   interactors.push_back(interactor);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::addAndInitInteractor(Interactor3DPtr interactor,double timestep)
-{
-   interactors.push_back(interactor);
-   interactor->initInteractor(timestep);
-}
-//////////////////////////////////////////////////////////////////////////
-Grid3D::Interactor3DSet Grid3D::getInteractors()
-{
-   return interactors;
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::accept(Block3DVisitor& blockVisitor)
-{
-   int startLevel   = blockVisitor.getStartLevel();
-   int stopLevel    = blockVisitor.getStopLevel();
-
-   if(startLevel < 0 || stopLevel < 0 || startLevel > Grid3DSystem::MAXLEVEL || stopLevel > Grid3DSystem::MAXLEVEL) 
-      throw UbException(UB_EXARGS,"not valid level!");
-
-   bool dir     = startLevel < stopLevel;
-   if(dir) stopLevel += 1;
-   else stopLevel    -= 1;
-
-
-//   for (int l = startLevel; l!=stopLevel;)
-//   {
-//      std::vector<Block3DPtr> blockVector;
-//      getBlocks(l, blockVector);
-//      int sizeb = (int)blockVector.size();
-//#pragma omp parallel
-//#pragma omp for
-//      for(int i = 0; i < sizeb; i++)
-//      {
-//         blockVisitor.visit(shared_from_this(), blockVector[i]);
-//      }
-//      if (dir)  l++;
-//      else     l--;
-//   }
-   for(int l=startLevel; l!=stopLevel;)
-   {
-      std::vector<Block3DPtr> blockVector;
-      getBlocks(l, blockVector);
-      BOOST_FOREACH(Block3DPtr b, blockVector)
-      {
-         blockVisitor.visit( shared_from_this(), b );
-      }
-      if(dir)  l++;
-      else     l--;
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::accept(Grid3DVisitor& gridVisitor)
-{
-   std::size_t counter =0;
-   gridVisitor.visit( shared_from_this() );
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::accept(Grid3DVisitorPtr gridVisitor)
-{
-   gridVisitor->visit( shared_from_this() );
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::addBlock( Block3DPtr block )
-{
-   if (block)
-   {
-      this->blockIdMap.insert( std::make_pair( block->getGlobalID(), block) );
-      int level = block->getLevel();
-      this->levelSet[level].insert( std::make_pair( Block3DKey( block->getX1(), block->getX2(),  block->getX3() ), block) ).second;
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-bool Grid3D::deleteBlock( Block3DPtr block )
-{
-   return this->deleteBlock(block->getX1(), block->getX2(), block->getX3(), block->getLevel());
-}
-//////////////////////////////////////////////////////////////////////////
-bool Grid3D::deleteBlock(int ix1, int ix2, int ix3, int level)
-{
-   Block3DPtr block = this->getBlock(ix1, ix2, ix3, level);
-   if(block) 
-   {
-      this->blockIdMap.erase(block->getGlobalID());
-      return this->levelSet[level].erase( Block3DKey(ix1, ix2, ix3) ) > 0;
-   }
-   else
-   {
-      return false;
-   }
-}	
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::replaceBlock(Block3DPtr block)
-{
-   if (block)
-   {
-      this->deleteBlock(block);
-      this->addBlock(block);
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-Block3DPtr Grid3D::getBlock( int ix1, int ix2, int ix3, int level ) const
-{
-   if( !this->hasLevel(level) ) return Block3DPtr();
-
-   int N1 = (nx1<<level);
-   int N2 = (nx2<<level);
-   int N3 = (nx3<<level);
-
-   if     (!this->isPeriodicX1() && (ix1>N1-1  || ix1<0)) return Block3DPtr();
-   else if( this->isPeriodicX1() && (ix1>=N1-1 || ix1<0)) { ix1=((ix1%N1)+N1)%N1; }
-   if     (!this->isPeriodicX2() && (ix2>N2-1  || ix2<0)) return Block3DPtr();
-   else if( this->isPeriodicX2() && (ix2>=N2-1 || ix2<0)) { ix2=((ix2%N2)+N2)%N2; }
-   if     (!this->isPeriodicX3() && (ix3>N3-1  || ix3<0)) return Block3DPtr();
-   else if( this->isPeriodicX3() && (ix3>=N3-1 || ix3<0)) { ix3=((ix3%N3)+N3)%N3; }
-
-   Block3DMap::const_iterator it;
-   it = levelSet[level].find( Block3DKey(ix1,ix2,ix3) );
-   if( it == levelSet[level].end() )
-      return Block3DPtr();
-   else
-      return it->second;
-}
-//////////////////////////////////////////////////////////////////////////
-Block3DPtr Grid3D::getBlock(int id) const
-{
-   BlockIDMap::const_iterator it;
-   if( ( it=blockIdMap.find( id ) ) == blockIdMap.end() )
-   {
-      return Block3DPtr();
-   }
-
-   return it->second;
-}
-//////////////////////////////////////////////////////////////////////////
-//const Grid3D::Block3DMap& Grid3D::getBlocks(int level) 
-//{ 
-//   return levelSet[level];
-//}
-//////////////////////////////////////////////////////////////////////////
-const Grid3D::BlockIDMap& Grid3D::getBlockIDs() 
-{ 
-   return blockIdMap;
-}
-//////////////////////////////////////////////////////////////////////////
-Block3DPtr Grid3D::getSuperBlock(Block3DPtr block)
-{
-   int ix1 = block->getX1();
-   int ix2 = block->getX2();
-   int ix3 = block->getX3();
-   int level = block->getLevel();
-   return getSuperBlock(ix1, ix2, ix3, level);
-}
-//////////////////////////////////////////////////////////////////////////
-Block3DPtr Grid3D::getSuperBlock(int ix1, int ix2, int ix3, int level)
-{
-   if(!this->hasLevel(level)) return Block3DPtr();
-   if(level <  1) throw UbException(UB_EXARGS,"level <1");
-   
-   //from Lower Level to higher:	 >> 	1 in x1,x2,x3 
-   Block3DPtr block;
-   for(int l=level-1; l>=0; l--)
-   {
-      ix1 = ix1 >> 1;
-      ix2 = ix2 >> 1;
-      ix3 = ix3 >> 1;
-
-      block = this->getBlock(ix1, ix2, ix3, l);
-      if(block) return block;
-   }
-   return Block3DPtr();
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocks(Block3DPtr block, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   int ix1 = block->getX1();
-   int ix2 = block->getX2();
-   int ix3 = block->getX3();
-   int level = block->getLevel();
-   getSubBlocks(ix1, ix2, ix3, level, levelDepth, blocks);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocks(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   if(!this->getBlock(ix1, ix2, ix3, level)) return;
-   if(level > 0 && !this->getSuperBlock(ix1, ix2, ix3, level)) return;
-   if(level >=  Grid3DSystem::MAXLEVEL)    throw UbException(UB_EXARGS,"Level bigger then MAXLEVEL");
-   
-   int x1[] = { ix1<<1, (ix1<<1)+1 };
-   int x2[] = { ix2<<1, (ix2<<1)+1 };
-   int x3[] = { ix3<<1, (ix3<<1)+1 };
-   int l    = level + 1;
-
-   for(int i=0; i<2; i++)
-      for(int j=0; j<2; j++)
-         for(int k=0; k<2; k++)
-         {
-            Block3DPtr block = this->getBlock(x1[i], x2[j], x3[k], l);
-            if(block) blocks.push_back(block);
-            else if(l < levelDepth) this->getSubBlocks(x1[i], x2[j], x3[k], l, levelDepth, blocks);
-         }
-}
-//////////////////////////////////////////////////////////////////////////
-bool Grid3D::expandBlock(int ix1, int ix2, int ix3, int level)
-{
-   this->checkLevel(level);
-
-   Block3DPtr block = this->getBlock( ix1, ix2, ix3, level );
-   if(!block)             throw UbException(UB_EXARGS,"block(x1="+UbSystem::toString(ix1)+", x2="+UbSystem::toString(ix2)+", x3="+UbSystem::toString(ix3)+", l="+UbSystem::toString(level)+") is not exist");
-   //if(!block->isActive()) throw UbException(UB_EXARGS,"block(x1="+UbSystem::toString(ix1)+", x2="+UbSystem::toString(ix2)+", x3="+UbSystem::toString(ix3)+", l="+UbSystem::toString(level)+") is not active");
-
-   //da bei periodic der eigentliche block andere indizes hat:
-   ix1 = block->getX1();
-   ix2 = block->getX2();
-   ix3 = block->getX3();
-
-   int l      = level+1;
-   if( l>Grid3DSystem::MAXLEVEL ) throw UbException(UB_EXARGS,"level > Grid3D::MAXLEVEL");
-
-   int west   = ix1<<1;
-   int east   = west+1;
-   int south  = ix2<<1;
-   int north  = south+1;
-   int bottom = ix3<<1;
-   int top    = bottom+1;
-
-   Block3DPtr blockBSW = Block3DPtr(new Block3D(west, south, bottom, l));
-   Block3DPtr blockBSE = Block3DPtr(new Block3D(east, south, bottom, l));
-   Block3DPtr blockBNW = Block3DPtr(new Block3D(west, north, bottom, l));
-   Block3DPtr blockBNE = Block3DPtr(new Block3D(east, north, bottom, l));
-   Block3DPtr blockTSW = Block3DPtr(new Block3D(west, south, top   , l));
-   Block3DPtr blockTSE = Block3DPtr(new Block3D(east, south, top   , l));
-   Block3DPtr blockTNW = Block3DPtr(new Block3D(west, north, top   , l));
-   Block3DPtr blockTNE = Block3DPtr(new Block3D(east, north, top   , l));
-
-   if( !this->deleteBlock( ix1, ix2, ix3, level ) )
-      throw UbException(UB_EXARGS,"could not delete block");
-
-   this->addBlock(blockBSW);
-   this->addBlock(blockBSE);
-   this->addBlock(blockBNW);
-   this->addBlock(blockBNE);
-   this->addBlock(blockTSW);
-   this->addBlock(blockTSE);
-   this->addBlock(blockTNW);
-   this->addBlock(blockTNE);
-
-   return true;
-}
-//////////////////////////////////////////////////////////////////////////
-Block3DPtr Grid3D::collapseBlock(int fix1, int fix2, int fix3, int flevel, int levelDepth)
-{
-   using UbSystem::toString;
-
-   Block3DPtr fblock = this->getBlock(fix1, fix2, fix3, flevel);
-   if( flevel <  1         ) throw UbException(UB_EXARGS,"level of block ("+toString(fix1)+","+toString(fix2)+","+toString(fix3)+","+toString(flevel)+") is < 1");
-   if( !fblock             ) 
-   {
-      throw UbException(UB_EXARGS,"specific block("+toString(fix1)+","+toString(fix2)+","+toString(fix3)+","+toString(flevel)+") doesn't exists");
-   }
-   if( !fblock->isActive() ) throw UbException(UB_EXARGS,"block("+toString(fix1)+","+toString(fix2)+","+toString(fix3)+","+toString(flevel)+") is not active");
-
-   //da bei periodic der eigentliche block andere indizes hat:
-   fix1 = fblock->getX1();
-   fix2 = fblock->getX2();
-   fix3 = fblock->getX3();
-
-   int cix1 = fblock->getX1() >> 1;
-   int cix2 = fblock->getX2() >> 1;
-   int cix3 = fblock->getX3() >> 1;
-
-   int fx1[2] = { cix1<<1,  (cix1<<1)+1 };
-   int fx2[2] = { cix2<<1,  (cix2<<1)+1 };
-   int fx3[2] = { cix3<<1,  (cix3<<1)+1 };
-   int clevel = flevel - 1;
-
-   vector<Block3DPtr> blocks;
-   for(int i=0; i<2; i++)
-      for(int k=0; k<2; k++)
-         for(int l=0; l<2; l++)
-         {
-            this->getSubBlocks(fx1[k], fx2[i], fx3[l], flevel, levelDepth, blocks);
-            while(!blocks.empty())
-            {
-               //man muss nur eine von den moeglichen acht "collapsen", die anderen werden
-               //dann (rekursiv) collapsed, da die schleife oben alle vier abfragt
-               this->collapseBlock(blocks[0]->getX1(), blocks[0]->getX2(), blocks[0]->getX3(), blocks[0]->getLevel(), levelDepth);
-               this->getSubBlocks(fx1[k], fx2[i], fx3[l], flevel, levelDepth, blocks);
-            }
-         }
-
-         vector<Block3DPtr> fineBlocks(8);
-         /*BSW*/fineBlocks[0] = this->getBlock( fx1[0], fx2[0], fx3[0], flevel );
-         /*BSE*/fineBlocks[1] = this->getBlock( fx1[1], fx2[0], fx3[0], flevel );
-         /*BNE*/fineBlocks[2] = this->getBlock( fx1[1], fx2[1], fx3[0], flevel );
-         /*BNW*/fineBlocks[3] = this->getBlock( fx1[0], fx2[1], fx3[0], flevel );
-         /*TSW*/fineBlocks[4] = this->getBlock( fx1[0], fx2[0], fx3[1], flevel );
-         /*TSE*/fineBlocks[5] = this->getBlock( fx1[1], fx2[0], fx3[1], flevel );
-         /*TNE*/fineBlocks[6] = this->getBlock( fx1[1], fx2[1], fx3[1], flevel );
-         /*TNW*/fineBlocks[7] = this->getBlock( fx1[0], fx2[1], fx3[1], flevel );
-
-         Block3DPtr cblock = Block3DPtr(new Block3D(cix1, cix2, cix3, clevel));
-
-         for(int i=0; i<2; i++)
-            for(int k=0; k<2; k++)
-               for(int l=0; l<2; l++)
-                  if( !this->deleteBlock( fx1[k], fx2[i], fx3[l], flevel ) )
-                     throw UbException(UB_EXARGS,"could not delete block");
-
-         this->addBlock(cblock);
-
-         return cblock;
-}
-//////////////////////////////////////////////////////////////////////////
-// TODO: make visitor for this
-void Grid3D::deleteConnectors()
-{
-   BOOST_FOREACH(Block3DMap blockMap, levelSet)
-   {
-      BOOST_FOREACH(Block3DMap::value_type b, blockMap)
-      {
-         Block3DPtr block =  b.second;
-         block->deleteConnectors();
-         //block->deleteInterpolationConnectors();
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-Grid3D::connection_t Grid3D::connect(Grid3D::signal_t::slot_function_type subscriber)
-{
-   return sig.connect(subscriber);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::disconnect(Grid3D::connection_t subscriber)
-{
-   subscriber.disconnect();
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::coProcess(double step)
-{
-   timeStep = step;
-   sig(step);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::setRank(int rank)
-{
-   this->rank = rank;
-}
-//////////////////////////////////////////////////////////////////////////
-int Grid3D::getRank() const
-{
-   return rank;
-}
-//////////////////////////////////////////////////////////////////////////
-int  Grid3D::getBundle() const          
-{ 
-   return bundle;       
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::setBundle(int bundle) 
-{ 
-   this->bundle = bundle; 
-} 
-//////////////////////////////////////////////////////////////////////////
-bool Grid3D::isPeriodicX1() const 
-{ 
-   return this->periodicX1; 
-}
-//////////////////////////////////////////////////////////////////////////
-bool Grid3D::isPeriodicX2() const 
-{ 
-   return this->periodicX2; 
-}
-//////////////////////////////////////////////////////////////////////////
-bool Grid3D::isPeriodicX3() const 
-{ 
-   return this->periodicX3; 
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::setPeriodicX1(bool value)
-{
-   this->periodicX1 = value;
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::setPeriodicX2(bool value)
-{
-   this->periodicX2 = value;
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::setPeriodicX3(bool value)
-{
-   this->periodicX3 = value;
-}
-//////////////////////////////////////////////////////////////////////////
-UbTupleInt3 Grid3D::getBlockIndexes(double blockX1Coord, double blockX2Coord, double blockX3Coord)  const
-{
-   if(!trafo)
-   {
-      return makeUbTuple( (int)blockX1Coord, (int)blockX2Coord, (int)blockX3Coord );
-   }
-
-   return makeUbTuple(  (int)trafo->transformForwardToX1Coordinate( blockX1Coord, blockX2Coord, blockX3Coord )
-      , (int)trafo->transformForwardToX2Coordinate( blockX1Coord, blockX2Coord, blockX3Coord )
-      , (int)trafo->transformForwardToX3Coordinate( blockX1Coord, blockX2Coord, blockX3Coord ) );
-
-}
-//////////////////////////////////////////////////////////////////////////
-UbTupleInt3 Grid3D::getBlockIndexes(double blockX1Coord, double blockX2Coord, double blockX3Coord, int level)  const
-{
-   if(!trafo)
-   {
-      return makeUbTuple( (int)blockX1Coord, (int)blockX2Coord, (int)blockX3Coord );
-   }
-
-   double dx = getDeltaX(level);
-   double blockLentghX1, blockLentghX2, blockLentghX3; 
-   blockLentghX1 = blockNx1*dx;
-   blockLentghX2 = blockNx2*dx;
-   blockLentghX3 = blockNx3*dx;
-   UbTupleDouble3 org = getBlockWorldCoordinates(0, 0, 0, 0);
-
-   CoordinateTransformation3DPtr trafo_temp(new CoordinateTransformation3D(val<1>(org),val<2>(org),val<3>(org),blockLentghX1,blockLentghX2,blockLentghX3));
-
-   if(!trafo_temp)
-   {
-      return makeUbTuple( (int)blockX1Coord, (int)blockX2Coord, (int)blockX3Coord );
-   }
-
-   return makeUbTuple(  (int)trafo_temp->transformForwardToX1Coordinate( blockX1Coord, blockX2Coord, blockX3Coord )
-      , (int)trafo_temp->transformForwardToX2Coordinate( blockX1Coord, blockX2Coord, blockX3Coord )
-      , (int)trafo_temp->transformForwardToX3Coordinate( blockX1Coord, blockX2Coord, blockX3Coord ) );
-
-}
-//////////////////////////////////////////////////////////////////////////
-UbTupleDouble3  Grid3D::getBlockLengths(const Block3DPtr block) const
-{
-   int    level = block->getLevel();
-   double delta = 1.0/(double)(1<<level);
-
-   if(!trafo) makeUbTuple<double, double, double>(delta,delta,delta);
-
-   return makeUbTuple(   trafo->getX1CoordinateScaling()*delta,
-                                                       trafo->getX2CoordinateScaling()*delta,
-                                                       trafo->getX3CoordinateScaling()*delta );
-}
-//////////////////////////////////////////////////////////////////////////
-UbTupleDouble6 Grid3D::getBlockOversize() const 
-{ 
-   return makeUbTuple(0.0,0.0,0.0,0.0,0.0,0.0); 
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::setCoordinateTransformator(CoordinateTransformation3DPtr trafo)
-{
-   this->trafo = trafo;
-}
-//////////////////////////////////////////////////////////////////////////
-const CoordinateTransformation3DPtr Grid3D::getCoordinateTransformator() const 
-{ 
-   return this->trafo; 
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::setDeltaX(double dx)
-{
-   this->orgDeltaX = dx;
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::setDeltaX(double worldUnit, double gridUnit)
-{
-   this->orgDeltaX = worldUnit/gridUnit;
-}
-//////////////////////////////////////////////////////////////////////////
-double Grid3D::getDeltaX(int level) const 
-{ 
-   double delta = this->orgDeltaX/(double)(1<<level);
-   return delta; 
-}
-//////////////////////////////////////////////////////////////////////////
-double Grid3D::getDeltaX(Block3DPtr block) const 
-{ 
-   return getDeltaX(block->getLevel()); 
-}
-//////////////////////////////////////////////////////////////////////////
-UbTupleDouble3  Grid3D::getNodeOffset(Block3DPtr block) const 
-{ 
-   double delta = this->getDeltaX(block);
-   return makeUbTuple(0.5*delta,0.5*delta,0.5*delta);
-}
-////////////////////////////////////////////////////////////////////////////
-UbTupleDouble3 Grid3D::getNodeCoordinates(Block3DPtr block, int ix1, int ix2, int ix3) const
-{
-   UbTupleDouble3 org = this->getBlockWorldCoordinates(block);
-   UbTupleDouble3 nodeOffset = this->getNodeOffset(block);
-   double deltaX = getDeltaX(block);
-
-   double x1 = val<1>(org) - val<1>(nodeOffset) + (double)ix1*deltaX;
-   double x2 = val<2>(org) - val<2>(nodeOffset) + (double)ix2*deltaX;
-   double x3 = val<3>(org) - val<3>(nodeOffset) + (double)ix3*deltaX;
-
-   return makeUbTuple(x1, x2, x3);
-}
-////////////////////////////////////////////////////////////////////////////
-UbTupleInt3 Grid3D::getNodeIndexes(Block3DPtr block, double nodeX1Coord, double nodeX2Coord, double nodeX3Coord) const
-{
-   UbTupleDouble3 org = this->getBlockWorldCoordinates(block);
-   UbTupleDouble3 nodeOffset = this->getNodeOffset(block);
-   double deltaX = getDeltaX(block);
-
-   int ix1,ix2,ix3;
-   double ixx1=(abs(nodeX1Coord - val<1>(org) + val<1>(nodeOffset)) / deltaX);
-   double ixx2=(abs(nodeX2Coord - val<2>(org) + val<2>(nodeOffset)) / deltaX);
-   double ixx3=(abs(nodeX3Coord - val<3>(org) + val<3>(nodeOffset)) / deltaX);
-   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; 
-
-   return makeUbTuple(ix1, ix2, ix3);
-}
-//////////////////////////////////////////////////////////////////////////
-//returns tuple with origin of block in world-coordinates
-UbTupleDouble3 Grid3D::getBlockWorldCoordinates(Block3DPtr block) const
-{
-   if(!block)
-      throw UbException(UB_EXARGS,"block " + block->toString() + "is not exist");
-
-   int blockX1Index = block->getX1();
-   int blockX2Index = block->getX2();
-   int blockX3Index = block->getX3();
-   int level = block->getLevel();
-
-   return this->getBlockWorldCoordinates(blockX1Index, blockX2Index, blockX3Index, level);
-}
-//////////////////////////////////////////////////////////////////////////
-UbTupleDouble3 Grid3D::getBlockWorldCoordinates(int blockX1Index, int blockX2Index, int blockX3Index, int level) const
-{
-   double c1oShiftedLevel = 1.0/(double)(1<<level);
-   double x1 = (double)blockX1Index*c1oShiftedLevel;
-   double x2 = (double)blockX2Index*c1oShiftedLevel;
-   double x3 = (double)blockX3Index*c1oShiftedLevel;
-
-   if(!trafo) return UbTupleDouble3( x1,x2,x3 );
-
-   return UbTupleDouble3( trafo->transformBackwardToX1Coordinate( x1,x2,x3 )
-      ,trafo->transformBackwardToX2Coordinate( x1,x2,x3 )
-      ,trafo->transformBackwardToX3Coordinate( x1,x2,x3 ) );
-}
-//////////////////////////////////////////////////////////////////////////
-//double Grid3D::getDeltaT(Block3DPtr block) const 
-//{ 
-//   int    level = block->getLevel();
-//   double delta = 1.0/(double)(1<<level);
-//   return delta; 
-//}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::checkLevel(int level)
-{
-   if(level < 0)
-   {
-      throw UbException(UB_EXARGS,"l("+UbSystem::toString(level)+(string)")<0");
-   }
-   if(level > Grid3DSystem::MAXLEVEL)
-   {
-      throw UbException(UB_EXARGS,"l("+UbSystem::toString(level)+(string)")>MAXLEVEL");
-   }
-   if(this->levelSet[level].size() == 0)
-   {
-      throw UbException(UB_EXARGS,"levelMap for level("+UbSystem::toString(level)+(string)")==NULL");
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-bool Grid3D::hasLevel(int level) const
-{
-   if(level < 0                        ) return false;
-   if(level > Grid3DSystem::MAXLEVEL                 ) return false;
-   if(this->levelSet[level].size() == 0) return false;
-
-   return true;
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::setBlockNX( int nx1, int nx2, int nx3 )
-{
-   blockNx1 = nx1;    
-   blockNx2 = nx2;    
-   blockNx3 = nx3; 
-}
-//////////////////////////////////////////////////////////////////////////
-UbTupleInt3 Grid3D::getBlockNX() const
-{
-   return makeUbTuple(blockNx1, blockNx2, blockNx3);
-}
-//////////////////////////////////////////////////////////////////////////
-
-Block3DPtr Grid3D::getNeighborBlock( int dir, int ix1, int ix2, int ix3, int level ) const
-{
-   return this->getBlock(  ix1+Grid3DSystem::EX1[dir], ix2+Grid3DSystem::EX2[dir], ix3+Grid3DSystem::EX3[dir], level );
-}
-//////////////////////////////////////////////////////////////////////////
-Block3DPtr Grid3D::getNeighborBlock(int dir, Block3DPtr block) const
-{
-   int x1 = block->getX1();
-   int x2 = block->getX2();
-   int x3 = block->getX3();
-   int level = block->getLevel();
-   return this->getNeighborBlock( dir, x1, x2, x3, level);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getAllNeighbors(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   for(int dir=Grid3DSystem::STARTDIR; dir<=Grid3DSystem::ENDDIR; dir++)
-   //for (int dir = Grid3DSystem::STARTDIR; dir<=Grid3DSystem::TS; dir++)
-   {
-      this->getNeighborBlocksForDirection(dir,ix1,ix2,ix3,level,levelDepth,blocks);
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getAllNeighbors(Block3DPtr block, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   int x1 = block->getX1();
-   int x2 = block->getX2();
-   int x3 = block->getX3();
-   getAllNeighbors(x1,x2,x3,level,levelDepth,blocks);
-}
-//////////////////////////////////////////////////////////////////////////
-  /**
-   * Returns all direct northern neighbor cells of the specified grid cell (may be NULL!).
-   * @param ix1 index in x1 direction
-   * @param ix2 index in x2 direction
-   * @param ix3 index in x3 direction
-   * @param level the level
-   */
-void Grid3D::getNeighborsNorth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-	Block3DPtr block = this->getBlock(ix1, ix2+1, ix3, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1, ix2+1, ix3, level);
-      if(block) { blocks.push_back(block); }
-   }
-   this->getSubBlocksSouth(ix1, ix2+1, ix3, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsTop(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1, ix2, ix3+1, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1, ix2, ix3+1, level);
-      if(block) { blocks.push_back(block); }
-   }
-   this->getSubBlocksBottom(ix1, ix2, ix3+1, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsBottom(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1, ix2, ix3-1, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1, ix2, ix3-1, level);
-      if(block) { blocks.push_back(block); }
-
-   }
-   this->getSubBlocksTop(ix1, ix2, ix3-1, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsSouth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1, ix2-1, ix3, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1, ix2-1, ix3, level);
-      if(block) { blocks.push_back(block); }
-
-   }
-   this->getSubBlocksNorth(ix1, ix2-1, ix3, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-	Block3DPtr block = this->getBlock(ix1+1, ix2, ix3, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1+1, ix2, ix3, level);
-      if(block) { blocks.push_back(block); }
-   }
-   this->getSubBlocksWest(ix1+1, ix2, ix3, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1-1, ix2, ix3, level);
-   if(block) { blocks.push_back(block);  }
-
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1-1, ix2, ix3, level);
-      if(block) { blocks.push_back(block); }
-   }
-   this->getSubBlocksEast(ix1-1, ix2, ix3, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-//   diagonals                                            
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsNorthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1+1, ix2+1, ix3, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1+1, ix2+1, ix3, level);
-      if(block) { blocks.push_back(block); }
-   }
-   this->getSubBlocksSouthWest(ix1+1, ix2+1, ix3, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsNorthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1-1, ix2+1, ix3, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1-1, ix2+1, ix3, level);
-      if(block) { blocks.push_back(block); }
-   }
-   this->getSubBlocksSouthEast(ix1-1, ix2+1, ix3, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsSouthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1+1, ix2-1, ix3, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1+1, ix2-1, ix3, level);
-      if(block) { blocks.push_back(block); }
-   }
-   this->getSubBlocksNorthWest(ix1+1, ix2-1, ix3, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsSouthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1-1, ix2-1, ix3, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1-1, ix2-1, ix3, level);
-      if(block) { blocks.push_back(block); }
-   }
-   this->getSubBlocksNorthEast(ix1-1, ix2-1, ix3, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-//   diagonals  top                                     
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsTopEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1+1, ix2, ix3+1, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1+1, ix2, ix3+1, level);
-      if(block) { blocks.push_back(block); }
-   }
-   this->getSubBlocksBottomWest(ix1+1, ix2, ix3+1, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsTopWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1-1, ix2, ix3+1, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1-1, ix2, ix3+1, level);
-      if(block) { blocks.push_back(block); }
-   }
-   this->getSubBlocksBottomEast(ix1-1, ix2, ix3+1, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsTopNorth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1, ix2+1, ix3+1, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1, ix2+1, ix3+1, level);
-      if(block) { blocks.push_back(block); }
-   }
-   this->getSubBlocksBottomSouth(ix1, ix2+1, ix3+1, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsTopSouth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1, ix2-1, ix3+1, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1, ix2-1, ix3+1, level);
-      if(block) { blocks.push_back(block); }
-   }
-   this->getSubBlocksBottomNorth(ix1, ix2-1, ix3+1, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-//   diagonals  bottom                                
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsBottomEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1+1, ix2, ix3-1, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1+1, ix2, ix3-1, level);
-      if(block) { blocks.push_back(block); }
-   }
-   this->getSubBlocksTopWest(ix1+1, ix2, ix3-1, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsBottomWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1-1, ix2, ix3-1, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1-1, ix2, ix3-1, level);
-      if(block) { blocks.push_back(block); }
-   }
-   this->getSubBlocksTopEast(ix1-1, ix2, ix3-1, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsBottomNorth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1, ix2+1, ix3-1, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1, ix2+1, ix3-1, level);
-      if(block) { blocks.push_back(block); }
-   }
-   this->getSubBlocksTopSouth(ix1, ix2+1, ix3-1, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsBottomSouth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1, ix2-1, ix3-1, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1, ix2-1, ix3-1, level);
-      if(block) { blocks.push_back(block); }
-   }
-   this->getSubBlocksTopNorth(ix1, ix2-1, ix3-1, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsTopNorthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1+1, ix2+1, ix3+1, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1+1, ix2+1, ix3+1, level);
-      if(block) { blocks.push_back(block); }
-   }
-   this->getSubBlocksBottomSouthWest(ix1+1, ix2+1, ix3+1, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsTopNorthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1-1, ix2+1, ix3+1, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1-1, ix2+1, ix3+1, level);
-      if(block) { blocks.push_back(block); }
-   }
-   this->getSubBlocksBottomSouthEast(ix1-1, ix2+1, ix3+1, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsTopSouthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1+1, ix2-1, ix3+1, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1+1, ix2-1, ix3+1, level);
-      if(block) { blocks.push_back(block); }
-   }
-   this->getSubBlocksBottomNorthWest(ix1+1, ix2-1, ix3+1, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsTopSouthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1-1, ix2-1, ix3+1, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1-1, ix2-1, ix3+1, level);
-      if(block) { blocks.push_back(block); }
-   }
-   this->getSubBlocksBottomNorthEast(ix1-1, ix2-1, ix3+1, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsBottomNorthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1+1, ix2+1, ix3-1, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1+1, ix2+1, ix3-1, level);
-      if(block) { blocks.push_back(block); }
-   }
-   this->getSubBlocksTopSouthWest(ix1+1, ix2+1, ix3-1, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsBottomNorthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1-1, ix2+1, ix3-1, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1-1, ix2+1, ix3-1, level);
-      if(block) { blocks.push_back(block); }
-   }
-   this->getSubBlocksTopSouthEast(ix1-1, ix2+1, ix3-1, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsBottomSouthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1+1, ix2-1, ix3-1, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1+1, ix2-1, ix3-1, level);
-      if(block) { blocks.push_back(block); }
-   }
-   this->getSubBlocksTopNorthWest(ix1+1, ix2-1, ix3-1, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsBottomSouthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1-1, ix2-1, ix3-1, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1-1, ix2-1, ix3-1, level);
-      if(block) { blocks.push_back(block); }
-   }
-   this->getSubBlocksTopNorthEast(ix1-1, ix2-1, ix3-1, level, blocks, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborBlocksForDirection(int dir, int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   switch(dir)
-   {
-   case Grid3DSystem::E  : this->getNeighborsEast(ix1, ix2, ix3, level,levelDepth, blocks);break;
-   case Grid3DSystem::W  : this->getNeighborsWest(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::N  : this->getNeighborsNorth(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::S  : this->getNeighborsSouth(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::T  : this->getNeighborsTop(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::B  : this->getNeighborsBottom(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::NE : this->getNeighborsNorthEast(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::SW : this->getNeighborsSouthWest(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::SE : this->getNeighborsSouthEast(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::NW : this->getNeighborsNorthWest(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::TE : this->getNeighborsTopEast(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::BW : this->getNeighborsBottomWest(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::BE : this->getNeighborsBottomEast(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::TW : this->getNeighborsTopWest(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::TN : this->getNeighborsTopNorth(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::BS : this->getNeighborsBottomSouth(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::BN : this->getNeighborsBottomNorth(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::TS : this->getNeighborsTopSouth(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::TNE: this->getNeighborsTopNorthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
-   case Grid3DSystem::TNW: this->getNeighborsTopNorthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
-   case Grid3DSystem::TSE: this->getNeighborsTopSouthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
-   case Grid3DSystem::TSW: this->getNeighborsTopSouthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
-   case Grid3DSystem::BNE: this->getNeighborsBottomNorthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
-   case Grid3DSystem::BNW: this->getNeighborsBottomNorthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
-   case Grid3DSystem::BSE: this->getNeighborsBottomSouthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
-   case Grid3DSystem::BSW: this->getNeighborsBottomSouthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
-   default:throw UbException(UB_EXARGS,"direction "+UbSystem::toString(dir)+" is not exist");
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborsZero(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   Block3DPtr block = this->getBlock(ix1, ix2, ix3, level);
-   if(block) { blocks.push_back(block); }
-
-   if(level > 0)
-   {
-      block = this->getSuperBlock(ix1, ix2, ix3, level);
-      if(block) { blocks.push_back(block); }
-   }
-   // this->getSubBlocksNull(ix1, ix2, ix3, level, blocks, levelDepth);
-   this->getSubBlocks(ix1, ix2, ix3, level, levelDepth, blocks);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksZero(int ix1, int ix2, int ix3, int level,vector<Block3DPtr> &blockVector, int levelDepth)
-{
-   int x1E  = (ix1 << 1) + 1;
-   int x1W  = (ix1 << 1) ;
-   int x2S = ix2 << 1;
-   int x2N = x2S + 1;
-   int x3B = ix3 << 1;
-   int x3T = x3B + 1;
-   int l   = level + 1;
-
-   Block3DPtr block = this->getBlock(x1E, x2S, x3B, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksEast(x1E, x2S, x3B, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1E, x2N, x3B, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksEast(x1E, x2N, x3B, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1E, x2S, x3T, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksEast(x1E, x2S, x3T, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1E, x2N, x3T, l);
-   if(block != NULL)      blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksEast(x1E, x2N, x3T, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1W, x2S, x3B, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksEast(x1W, x2S, x3B, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1W, x2N, x3B, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksEast(x1W, x2N, x3B, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1W, x2S, x3T, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksEast(x1W, x2S, x3T, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1W, x2N, x3T, l);
-   if(block != NULL)      blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksEast(x1W, x2N, x3T, l, blockVector,levelDepth);  
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborBlocksForDirectionWithDirZero(int dir, int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
-{
-   switch(dir)
-   {
-   case Grid3DSystem::E  : this->getNeighborsEast(ix1, ix2, ix3, level,levelDepth, blocks);break;
-   case Grid3DSystem::W  : this->getNeighborsWest(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::N  : this->getNeighborsNorth(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::S  : this->getNeighborsSouth(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::T  : this->getNeighborsTop(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::B  : this->getNeighborsBottom(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::NE : this->getNeighborsNorthEast(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::SW : this->getNeighborsSouthWest(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::SE : this->getNeighborsSouthEast(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::NW : this->getNeighborsNorthWest(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::TE : this->getNeighborsTopEast(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::BW : this->getNeighborsBottomWest(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::BE : this->getNeighborsBottomEast(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::TW : this->getNeighborsTopWest(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::TN : this->getNeighborsTopNorth(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::BS : this->getNeighborsBottomSouth(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::BN : this->getNeighborsBottomNorth(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::TS : this->getNeighborsTopSouth(ix1, ix2, ix3, level,levelDepth, blocks); break;
-   case Grid3DSystem::TNE: this->getNeighborsTopNorthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
-   case Grid3DSystem::TNW: this->getNeighborsTopNorthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
-   case Grid3DSystem::TSE: this->getNeighborsTopSouthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
-   case Grid3DSystem::TSW: this->getNeighborsTopSouthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
-   case Grid3DSystem::BNE: this->getNeighborsBottomNorthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
-   case Grid3DSystem::BNW: this->getNeighborsBottomNorthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
-   case Grid3DSystem::BSE: this->getNeighborsBottomSouthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
-   case Grid3DSystem::BSW: this->getNeighborsBottomSouthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
-   case Grid3DSystem::ZERO: this->getNeighborsZero(ix1, ix2, ix3, level,levelDepth, blocks);break;
-   default:throw UbException(UB_EXARGS,"direction "+UbSystem::toString(dir)+" is not exist");
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksEast(int ix1, int ix2, int ix3, int level,vector<Block3DPtr> &blockVector, int levelDepth)
-{
-   int x1  = (ix1 << 1) + 1;
-   int x2S = ix2 << 1;
-   int x2N = x2S + 1;
-   int x3B = ix3 << 1;
-   int x3T = x3B + 1;
-   int l   = level + 1;
-
-   Block3DPtr block = this->getBlock(x1, x2S, x3B, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksEast(x1, x2S, x3B, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1, x2N, x3B, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksEast(x1, x2N, x3B, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1, x2S, x3T, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksEast(x1, x2S, x3T, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1, x2N, x3T, l);
-   if(block != NULL)      blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksEast(x1, x2N, x3T, l, blockVector,levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksWest(int ix1, int ix2, int ix3, int level,vector<Block3DPtr> &blockVector, int levelDepth)
-{
-   int x1  = ix1 << 1;
-   int x2S = ix2 << 1;
-   int x2N = x2S + 1;
-   int x3B = ix3 << 1;
-   int x3T = x3B + 1;
-   int l   = level + 1;
-
-   Block3DPtr block = this->getBlock(x1, x2S, x3B, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksWest(x1, x2S, x3B, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1, x2N, x3B, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksWest(x1, x2N, x3B, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1, x2S, x3T, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksWest(x1, x2S, x3T, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1, x2N, x3T, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksWest(x1, x2N, x3T, l, blockVector,levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksNorth(int ix1, int ix2, int ix3, int level,vector<Block3DPtr> &blockVector, int levelDepth)
-{
-   int x1W = ix1 << 1;
-   int x1E = x1W + 1;
-   int x2  = (ix2 << 1) + 1;
-   int x3B = ix3 << 1;
-   int x3T = x3B + 1;
-   int l   = level + 1;
-
-   Block3DPtr block = this->getBlock(x1W, x2, x3B, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksNorth(x1W, x2, x3B, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1E, x2, x3B, l);
-   if(block != NULL)      blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksNorth(x1E, x2, x3B, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1W, x2, x3T, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksNorth(x1W, x2, x3T, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1E, x2, x3T, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksNorth(x1E, x2, x3T, l, blockVector,levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksSouth(int ix1, int ix2, int ix3, int level,vector<Block3DPtr> &blockVector, int levelDepth)
-{
-   int x1W = ix1 << 1;
-   int x1E = x1W + 1;
-   int x2  = ix2 << 1;
-   int x3B = ix3 << 1;
-   int x3T = x3B + 1;
-   int l   = level + 1;
-
-   Block3DPtr block = this->getBlock(x1W, x2, x3B, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksSouth(x1W, x2, x3B, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1E, x2, x3B, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksSouth(x1E, x2, x3B, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1W, x2, x3T, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksSouth(x1W, x2, x3T, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1E, x2, x3T, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksSouth(x1E, x2, x3T, l, blockVector,levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksTop(int ix1, int ix2, int ix3, int level,vector<Block3DPtr> &blockVector, int levelDepth)
-{
-   int x1W = ix1 << 1;
-   int x1E = x1W + 1;
-   int x2S = ix2 << 1;
-   int x2N = x2S + 1;
-   int x3  = (ix3 << 1) + 1;
-   int l   = level + 1;
-
-   Block3DPtr block = this->getBlock(x1W, x2N, x3, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksTop(x1W, x2N, x3, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1E, x2N, x3, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksTop(x1E, x2N, x3, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1W, x2S, x3, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksTop(x1W, x2S, x3, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1E, x2S, x3, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksTop(x1E, x2S, x3, l, blockVector,levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksBottom(int ix1, int ix2, int ix3, int level,vector<Block3DPtr> &blockVector, int levelDepth)
-{
-   int x1W = ix1 << 1;
-   int x1E = x1W + 1;
-   int x2S = ix2 << 1;
-   int x2N = x2S + 1;
-   int x3  = ix3 << 1;
-   int l   = level + 1;
-
-   Block3DPtr block = this->getBlock(x1W, x2N, x3, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksBottom(x1W, x2N, x3, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1E, x2N, x3, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksBottom(x1E, x2N, x3, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1W, x2S, x3, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksBottom(x1W, x2S, x3, l, blockVector,levelDepth);
-
-   block = this->getBlock(x1E, x2S, x3, l);
-   if(block != NULL)       blockVector.push_back(block);
-   else if(l < levelDepth) this->getSubBlocksBottom(x1E, x2S, x3, l, blockVector,levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-//  diagonals
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksNorthEast(int ix1, int ix2, int ix3, int level, vector<Block3DPtr>& blockVector, int levelDepth)
-{
-   int x1  = (ix1 << 1) + 1;
-   int x2  = (ix2 << 1) + 1;
-   int x3B = (ix3 << 1);
-   int x3T = x3B+1;
-   int l   = level + 1;
-
-   Block3DPtr blockB = this->getBlock(x1, x2, x3B, l);
-   if(blockB) blockVector.push_back(blockB);
-   else if(l < levelDepth) this->getSubBlocksNorthEast(x1, x2, x3B, l, blockVector, levelDepth);
-
-   Block3DPtr blockT = this->getBlock(x1, x2, x3T, l);
-   if(blockT) blockVector.push_back(blockT);
-   else if(l < levelDepth) this->getSubBlocksNorthEast(x1, x2, x3T, l, blockVector, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksNorthWest(int ix1, int ix2, int ix3, int level, vector<Block3DPtr>& blockVector, int levelDepth)
-{
-   int x1  = (ix1 << 1);
-   int x2  = (ix2 << 1) + 1;
-   int x3B = (ix3 << 1);
-   int x3T = x3B+1;
-   int l   = level + 1;
-
-   Block3DPtr blockB = this->getBlock(x1, x2,x3B, l);
-   if(blockB) blockVector.push_back(blockB);
-   else if(l < levelDepth) this->getSubBlocksNorthWest(x1, x2, x3B, l, blockVector, levelDepth);
-
-   Block3DPtr blockT = this->getBlock(x1, x2,x3T, l);
-   if(blockT) blockVector.push_back(blockT);
-   else if(l < levelDepth) this->getSubBlocksNorthWest(x1, x2, x3T, l, blockVector, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksSouthWest(int ix1, int ix2, int ix3, int level, vector<Block3DPtr>& blockVector, int levelDepth)
-{
-   int x1  = ix1 << 1;
-   int x2  = ix2 << 1;
-   int x3B = (ix3 << 1);
-   int x3T = x3B+1;
-   int l  = level + 1;
-
-   Block3DPtr blockB = this->getBlock(x1, x2,x3B, l);
-   if(blockB) blockVector.push_back(blockB);
-   else if(l < levelDepth) this->getSubBlocksSouthWest(x1, x2, x3B, l, blockVector, levelDepth);
-
-   Block3DPtr blockT = this->getBlock(x1, x2,x3T, l);
-   if(blockT) blockVector.push_back(blockT);
-   else if(l < levelDepth) this->getSubBlocksSouthWest(x1, x2, x3T, l, blockVector, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksSouthEast(int ix1, int ix2, int ix3, int level, vector<Block3DPtr>& blockVector, int levelDepth)
-{
-   int x1  = (ix1 << 1) + 1;
-   int x2  = ix2 << 1;
-   int x3B = (ix3 << 1);
-   int x3T = x3B+1;
-   int l   = level + 1;
-
-   Block3DPtr blockB = this->getBlock(x1, x2,x3B, l);
-   if(blockB) blockVector.push_back(blockB);
-   else if(l < levelDepth) this->getSubBlocksSouthEast(x1, x2, x3B, l, blockVector, levelDepth);
-
-   Block3DPtr blockT = this->getBlock(x1, x2,x3T, l);
-   if(blockT) blockVector.push_back(blockT);
-   else if(l < levelDepth) this->getSubBlocksSouthEast(x1, x2, x3T, l, blockVector, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-//  diagonals
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksTopEast(int ix1, int ix2, int ix3, int level, vector<Block3DPtr>& blockVector, int levelDepth)
-{
-   int x1  = (ix1 << 1) + 1;
-   int x2S = (ix2 << 1);
-   int x2N = x2S + 1;
-   int x3  = (ix3 << 1)+1;
-   int l   = level + 1;
-
-   Block3DPtr blockN = this->getBlock(x1, x2N, x3, l);
-   if(blockN) blockVector.push_back(blockN);
-   else if(l < levelDepth) this->getSubBlocksTopEast(x1, x2N, x3, l, blockVector, levelDepth);
-
-   Block3DPtr blockS = this->getBlock(x1, x2S, x3, l);
-   if(blockS) blockVector.push_back(blockS);
-   else if(l < levelDepth) this->getSubBlocksTopEast(x1, x2S, x3, l, blockVector, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksTopWest(int ix1, int ix2, int ix3, int level, vector<Block3DPtr>& blockVector, int levelDepth)
-{
-   int x1  = ix1 << 1;
-   int x2S = ix2 << 1;
-   int x2N = x2S + 1;
-   int x3  = (ix3 << 1)+1;
-   int l   = level + 1;
-
-   Block3DPtr blockN = this->getBlock(x1, x2N, x3, l);
-   if(blockN) blockVector.push_back(blockN);
-   else if(l < levelDepth) this->getSubBlocksTopEast(x1, x2N, x3, l, blockVector, levelDepth);
-
-   Block3DPtr blockS = this->getBlock(x1, x2S, x3, l);
-   if(blockS) blockVector.push_back(blockS);
-   else if(l < levelDepth) this->getSubBlocksTopEast(x1, x2S, x3, l, blockVector, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksBottomEast(int ix1, int ix2, int ix3, int level, vector<Block3DPtr>& blockVector, int levelDepth)
-{
-   int x1  = (ix1 << 1) + 1;
-   int x2S = ix2 << 1;
-   int x2N = x2S + 1;
-   int x3  = ix3 << 1;
-   int l   = level + 1;
-
-   Block3DPtr blockN = this->getBlock(x1, x2N, x3, l);
-   if(blockN) blockVector.push_back(blockN);
-   else if(l < levelDepth) this->getSubBlocksTopEast(x1, x2N, x3, l, blockVector, levelDepth);
-
-   Block3DPtr blockS = this->getBlock(x1, x2S, x3, l);
-   if(blockS) blockVector.push_back(blockS);
-   else if(l < levelDepth) this->getSubBlocksTopEast(x1, x2S, x3, l, blockVector, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksBottomWest(int ix1, int ix2, int ix3, int level, vector<Block3DPtr>& blockVector, int levelDepth)
-{
-   int x1  = (ix1 << 1);
-   int x2S = (ix2 << 1);
-   int x2N = x2S + 1;
-   int x3  = ix3 << 1;
-   int l   = level + 1;
-
-   Block3DPtr blockN = this->getBlock(x1, x2N, x3, l);
-   if(blockN) blockVector.push_back(blockN);
-   else if(l < levelDepth) this->getSubBlocksTopEast(x1, x2N, x3, l, blockVector, levelDepth);
-
-   Block3DPtr blockS = this->getBlock(x1, x2S, x3, l);
-   if(blockS) blockVector.push_back(blockS);
-   else if(l < levelDepth) this->getSubBlocksTopEast(x1, x2S, x3, l, blockVector, levelDepth);
-}
-
-//////////////////////////////////////////////////////////////////////////
-//  edge-diagonals
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksTopNorth(int ix1, int ix2, int ix3, int level, vector<Block3DPtr>& blockVector, int levelDepth)
-{
-   int x1E = (ix1 << 1);
-   int x1W = x1E + 1;
-   int x2  = (ix2 << 1)+1;
-   int x3  = (ix3 << 1)+1;
-   int l   = level + 1;
-
-   Block3DPtr blockE = this->getBlock(x1E, x2, x3, l);
-   if(blockE) blockVector.push_back(blockE);
-   else if(l < levelDepth) this->getSubBlocksTopNorth(x1E, x2, x3, l, blockVector, levelDepth);
-
-   Block3DPtr blockW = this->getBlock(x1W, x2, x3, l);
-   if(blockW) blockVector.push_back(blockW);
-   else if(l < levelDepth) this->getSubBlocksTopNorth(x1W, x2, x3, l, blockVector, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksTopSouth(int ix1, int ix2, int ix3, int level, vector<Block3DPtr>& blockVector, int levelDepth)
-{
-   int x1E = (ix1 << 1);
-   int x1W = x1E + 1;
-   int x2  = (ix2 << 1);
-   int x3  = (ix3 << 1)+1;
-   int l   = level + 1;
-
-   Block3DPtr blockE = this->getBlock(x1E, x2, x3, l);
-   if(blockE) blockVector.push_back(blockE);
-   else if(l < levelDepth) this->getSubBlocksTopSouth(x1E, x2, x3, l, blockVector, levelDepth);
-
-   Block3DPtr blockW = this->getBlock(x1W, x2, x3, l);
-   if(blockW) blockVector.push_back(blockW);
-   else if(l < levelDepth) this->getSubBlocksTopSouth(x1W, x2, x3, l, blockVector, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksBottomNorth(int ix1, int ix2, int ix3, int level, vector<Block3DPtr>& blockVector, int levelDepth)
-{
-   int x1E = ix1 << 1;
-   int x1W = x1E + 1;
-   int x2  = (ix2 << 1)+1;
-   int x3  = ix3 << 1;
-   int l   = level + 1;
-
-   Block3DPtr blockE = this->getBlock(x1E, x2, x3, l);
-   if(blockE) blockVector.push_back(blockE);
-   else if(l < levelDepth) this->getSubBlocksBottomNorth(x1E, x2, x3, l, blockVector, levelDepth);
-
-   Block3DPtr blockW = this->getBlock(x1W, x2, x3, l);
-   if(blockW) blockVector.push_back(blockW);
-   else if(l < levelDepth) this->getSubBlocksBottomNorth(x1W, x2, x3, l, blockVector, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksBottomSouth(int ix1, int ix2, int ix3, int level, vector<Block3DPtr>& blockVector, int levelDepth)
-{
-   int x1E = (ix1 << 1);
-   int x1W = x1E + 1;
-   int x2  = ix2 << 1;
-   int x3  = ix3 << 1;
-   int l   = level + 1;
-
-   Block3DPtr blockE = this->getBlock(x1E, x2, x3, l);
-   if(blockE) blockVector.push_back(blockE);
-   else if(l < levelDepth) this->getSubBlocksBottomSouth(x1E, x2, x3, l, blockVector, levelDepth);
-
-   Block3DPtr blockW = this->getBlock(x1W, x2, x3, l);
-   if(blockW) blockVector.push_back(blockW);
-   else if(l < levelDepth) this->getSubBlocksBottomSouth(x1W, x2, x3, l, blockVector, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-//  space-diagonals
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksTopNorthEast(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth)
-{
-   int x1 = (ix1 << 1) + 1;
-   int x2 = (ix2 << 1) + 1;
-   int x3 = (ix3 << 1) + 1;
-   int l  = level + 1;
-
-   Block3DPtr blockTNE = this->getBlock(x1, x2, x3, l);
-   if(blockTNE) blockVector.push_back(blockTNE);
-   else if(l < levelDepth) this->getSubBlocksTopNorthEast(x1, x2, x3, l, blockVector, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksTopNorthWest(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth)
-{
-   int x1 = ix1 << 1;
-   int x2 = (ix2 << 1) + 1;
-   int x3 = (ix3 << 1) + 1;
-   int l  = level + 1;
-
-   Block3DPtr blockTNW = this->getBlock(x1, x2, x3, l);
-   if(blockTNW) blockVector.push_back(blockTNW);
-   else if(l < levelDepth) this->getSubBlocksTopNorthWest(x1, x2, x3, l, blockVector, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksTopSouthEast(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth)
-{
-   int x1 = (ix1 << 1) + 1;
-   int x2 =  ix2 << 1;
-   int x3 = (ix3 << 1) + 1;
-   int l  = level + 1;
-
-   Block3DPtr blockTNW = this->getBlock(x1, x2, x3, l);
-   if(blockTNW) blockVector.push_back(blockTNW);
-   else if(l < levelDepth) this->getSubBlocksTopSouthEast(x1, x2, x3, l, blockVector, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksTopSouthWest(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth)
-{
-   int x1 =  ix1 << 1;
-   int x2 =  ix2 << 1;
-   int x3 = (ix3 << 1) + 1;
-   int l  = level + 1;
-
-   Block3DPtr blockTSW = this->getBlock(x1, x2, x3, l);
-   if(blockTSW) blockVector.push_back(blockTSW);
-   else if(l < levelDepth) this->getSubBlocksTopSouthWest(x1, x2, x3, l, blockVector, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksBottomNorthEast(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth)
-{
-   int x1 = (ix1 << 1) + 1;
-   int x2 = (ix2 << 1) + 1;
-   int x3 =  ix3 << 1;
-   int l  = level + 1;
-
-   Block3DPtr blockBNE = this->getBlock(x1, x2, x3, l);
-   if(blockBNE) blockVector.push_back(blockBNE);
-   else if(l < levelDepth) this->getSubBlocksBottomNorthEast(x1, x2, x3, l, blockVector, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksBottomNorthWest(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth)
-{
-   int x1 =  ix1 << 1;
-   int x2 = (ix2 << 1) + 1;
-   int x3 =  ix3 << 1;
-   int l  = level + 1;
-
-   Block3DPtr blockBNW = this->getBlock(x1, x2, x3, l);
-   if(blockBNW) blockVector.push_back(blockBNW);
-   else if(l < levelDepth) this->getSubBlocksBottomNorthWest(x1, x2, x3, l, blockVector, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksBottomSouthEast(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth)
-{
-   int x1 = (ix1 << 1) + 1;
-   int x2 =  ix2 << 1;
-   int x3 =  ix3 << 1;
-   int l  = level + 1;
-
-   Block3DPtr blockBSE = this->getBlock(x1, x2, x3, l);
-   if(blockBSE) blockVector.push_back(blockBSE);
-   else if(l < levelDepth) this->getSubBlocksBottomSouthEast(x1, x2, x3, l, blockVector, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getSubBlocksBottomSouthWest(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth)
-{
-   int x1 = ix1 << 1;
-   int x2 = ix2 << 1;
-   int x3 = ix3 << 1;
-   int l  = level + 1;
-
-   Block3DPtr blockBSW = this->getBlock(x1, x2, x3, l);
-   if(blockBSW) blockVector.push_back(blockBSW);
-   else if(l < levelDepth) this->getSubBlocksBottomSouthWest(x1, x2, x3, l, blockVector, levelDepth);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getBlocks(int level, std::vector<Block3DPtr>& blockVector)
-{
-   BOOST_FOREACH(Block3DMap::value_type b, levelSet[level])
-   {
-      blockVector.push_back(b.second);
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getBlocks(int level, int rank, std::vector<Block3DPtr>& blockVector)
-{
-   BOOST_FOREACH(Block3DMap::value_type b, levelSet[level])
-   {
-      Block3DPtr block = b.second;
-      int blockRank = block->getRank();
-      if (blockRank == rank)
-      {
-         blockVector.push_back(b.second);
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getBlocks(int level, int rank, bool active, std::vector<Block3DPtr>& blockVector)
-{
-   BOOST_FOREACH(Block3DMap::value_type b, levelSet[level])
-   {
-      Block3DPtr block = b.second;
-      int blockRank = block->getRank();
-
-      if (blockRank == rank && active ? block->isActive() : block->isNotActive())
-      {
-         blockVector.push_back(b.second);
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-int Grid3D::getFinestInitializedLevel()
-{
-   for(int i=Grid3DSystem::MAXLEVEL; i>=0; i--) if(this->levelSet[i].size() > 0) return(i);
-   return(-1);
-}
-//////////////////////////////////////////////////////////////////////////
-int Grid3D::getCoarsestInitializedLevel()
-{
-   for(int i=0; i<=Grid3DSystem::MAXLEVEL; i++) if(this->levelSet[i].size() > 0) return(i);
-   return(-1);
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::setNX1(int nx1)  
-{ 
-   this->nx1 = nx1; 
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::setNX2(int nx2)  
-{ 
-   this->nx2 = nx2; 
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::setNX3(int nx3)  
-{ 
-   this->nx3 = nx3; 
-}
-//////////////////////////////////////////////////////////////////////////
-int Grid3D::getNX1() const 
-{ 
-   return this->nx1; 
-}
-//////////////////////////////////////////////////////////////////////////
-int Grid3D::getNX2() const 
-{ 
-   return this->nx2; 
-}
-//////////////////////////////////////////////////////////////////////////
-int Grid3D::getNX3() const 
-{
-   return this->nx3;
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::deleteBlocks( const std::vector<int>& ids )
-{
-   BOOST_FOREACH(int i, ids)
-   {
-      Block3DPtr block = getBlock(i);
-      if(block) this->deleteBlock(block);
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-int Grid3D::getNumberOfBlocks()
-{
-   int c = 0;
-   BOOST_FOREACH(Block3DMap l, levelSet)
-   {
-      c += (int)l.size();
-   }
-   return c;
-}
-//////////////////////////////////////////////////////////////////////////
-int Grid3D::getNumberOfBlocks(int level)
-{
-   return (int)levelSet[level].size();
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getBlocksByCuboid( double minX1, double minX2, double minX3, double maxX1, double maxX2, double maxX3, std::vector<Block3DPtr>& blocks )
-{
-   int coarsestLevel = this->getCoarsestInitializedLevel();
-   int finestLevel   = this->getFinestInitializedLevel();
-
-   //////////////////////////////////////////////////////////////////////////
-   //MINIMALE BLOCK-INDIZES BESTIMMEN
-   //  
-   //min:
-   double dMinX1 = trafo->transformForwardToX1Coordinate( minX1,minX2,minX3 )*(1<<finestLevel);
-   double dMinX2 = trafo->transformForwardToX2Coordinate( minX1,minX2,minX3 )*(1<<finestLevel);
-   double dMinX3 = trafo->transformForwardToX3Coordinate( minX1,minX2,minX3 )*(1<<finestLevel);
-
-   //Achtung, wenn minX1 genau auf grenze zwischen zwei bloecken -> der "kleinere" muss genommen werden,
-   //da beim Transformieren der "groessere" Index rauskommt
-   int iMinX1 = (int)dMinX1; if( UbMath::zero(dMinX1-iMinX1) ) iMinX1-=1;   
-   int iMinX2 = (int)dMinX2; if( UbMath::zero(dMinX2-iMinX2) ) iMinX2-=1;
-   int iMinX3 = (int)dMinX3; if( UbMath::zero(dMinX3-iMinX3) ) iMinX3-=1;
-
-   //max (hier kann die Zusatzabfrage vernachlaessigt werden):
-   int iMaxX1 = (int)(trafo->transformForwardToX1Coordinate( maxX1,maxX2,maxX3 )*(1<<finestLevel));
-   int iMaxX2 = (int)(trafo->transformForwardToX2Coordinate( maxX1,maxX2,maxX3 )*(1<<finestLevel));
-   int iMaxX3 = (int)(trafo->transformForwardToX3Coordinate( maxX1,maxX2,maxX3 )*(1<<finestLevel));
-
-   Block3DPtr block;
-
-   //set, um doppelte bloecke zu vermeiden, die u.U. bei periodic auftreten koennen
-   std::set<Block3DPtr> blockset; 
-   for(int level=coarsestLevel; level<=finestLevel; level++)
-   {
-      //damit bei negativen werten auch der "kleinere" genommen wird -> floor!
-      int minx1 = (int)std::floor( (double)iMinX1/(1<<(finestLevel-level)) );
-      int minx2 = (int)std::floor( (double)iMinX2/(1<<(finestLevel-level)) );
-      int minx3 = (int)std::floor( (double)iMinX3/(1<<(finestLevel-level)) );
-
-      int maxx1 = iMaxX1/(1<<(finestLevel-level));
-      int maxx2 = iMaxX2/(1<<(finestLevel-level));
-      int maxx3 = iMaxX3/(1<<(finestLevel-level));
-
-      for(int ix1=minx1; ix1<=maxx1; ix1++)
-         for(int ix2=minx2; ix2<=maxx2; ix2++)
-            for(int ix3=minx3; ix3<=maxx3; ix3++)
-            if( (block=this->getBlock(ix1,ix2,ix3,level)) )
-            {
-               if (block->getRank() == rank)
-               {
-                  blockset.insert(block);
-               }
-            }
-   }
-
-   blocks.resize(blockset.size());
-   std::copy(blockset.begin(), blockset.end(), blocks.begin());
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::getBlocksByCuboid( int level, double minX1, double minX2, double minX3, double maxX1, double maxX2, double maxX3, std::vector<Block3DPtr>& blocks )
-{
-   //////////////////////////////////////////////////////////////////////////
-   //MINIMALE BLOCK-INDIZES BESTIMMEN
-   //
-   //min:
-   double dMinX1 = trafo->transformForwardToX1Coordinate( minX1,minX2,minX3 )*(1<<level);
-   double dMinX2 = trafo->transformForwardToX2Coordinate( minX1,minX2,minX3 )*(1<<level);
-   double dMinX3 = trafo->transformForwardToX3Coordinate( minX1,minX2,minX3 )*(1<<level);
-
-   //Achtung, wenn minX1 genau auf grenze zwischen zwei bloecken -> der "kleinere" muss genommen werden:
-   int iMinX1 = (int)dMinX1; if( UbMath::zero(dMinX1-iMinX1) ) iMinX1-=1;
-   int iMinX2 = (int)dMinX2; if( UbMath::zero(dMinX2-iMinX2) ) iMinX2-=1;
-   int iMinX3 = (int)dMinX3; if( UbMath::zero(dMinX3-iMinX3) ) iMinX3-=1;
-
-   //max:
-   int iMaxX1 = (int)(trafo->transformForwardToX1Coordinate( maxX1,maxX2,maxX3 )*(1<<level));
-   int iMaxX2 = (int)(trafo->transformForwardToX2Coordinate( maxX1,maxX2,maxX3 )*(1<<level));
-   int iMaxX3 = (int)(trafo->transformForwardToX3Coordinate( maxX1,maxX2,maxX3 )*(1<<level));
-
-
-   //set, um doppelte bloecke zu vermeiden, die u.U. bei periodic auftreten koennen
-   std::set<Block3DPtr> blockset; 
-   Block3DPtr block;
-
-   for(int ix1=iMinX1; ix1<=iMaxX1; ix1++)
-      for(int ix2=iMinX2; ix2<=iMaxX2; ix2++)
-         for(int ix3=iMinX3; ix3<=iMaxX3; ix3++)
-            if( (block=this->getBlock(ix1,ix2,ix3,level)) )
-            {
-               if (block->getRank() == rank)
-               {
-                  blockset.insert(block);
-               }
-            }
-
-   blocks.resize(blockset.size());
-   std::copy(blockset.begin(), blockset.end(), blocks.begin());
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::calcStartCoordinatesAndDelta(Block3DPtr block, double& worldX1, double& worldX2, double& worldX3, double& deltaX)
-{
-   int blocklevel  = block->getLevel();
-   worldX1  = block->getX1()/(float)(1<<blocklevel);
-   worldX2  = block->getX2()/(float)(1<<blocklevel);
-   worldX3  = block->getX3()/(float)(1<<blocklevel);
-   deltaX   = (double)1.0/(double)(this->blockNx1*(double)(1<<blocklevel));
-
-   if(this->trafo)
-   {
-      double x1tmp = worldX1, x2tmp = worldX2, x3tmp = worldX3;
-      worldX1 = this->trafo->transformBackwardToX1Coordinate(x1tmp, x2tmp, x3tmp);
-      worldX2 = this->trafo->transformBackwardToX2Coordinate(x1tmp, x2tmp, x3tmp);
-      worldX3 = this->trafo->transformBackwardToX3Coordinate(x1tmp, x2tmp, x3tmp);
-      deltaX  = this->trafo->getX1CoordinateScaling()/(double)(this->blockNx1*(double)(1<<blocklevel));
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::calcStartCoordinatesWithOutOverlap(Block3DPtr block, double& worldX1, double& worldX2, double& worldX3)
-{
-   int blocklevel  = block->getLevel();
-   worldX1  = block->getX1()/(float)(1<<blocklevel);
-   worldX2  = block->getX2()/(float)(1<<blocklevel);
-   worldX3  = block->getX3()/(float)(1<<blocklevel);
-
-   if(this->trafo)
-   {
-      double x1tmp = worldX1, x2tmp = worldX2, x3tmp = worldX3;
-      worldX1 = this->trafo->transformBackwardToX1Coordinate(x1tmp, x2tmp, x3tmp);
-      worldX2 = this->trafo->transformBackwardToX2Coordinate(x1tmp, x2tmp, x3tmp);
-      worldX3 = this->trafo->transformBackwardToX3Coordinate(x1tmp, x2tmp, x3tmp);
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::setTimeStep( double step )
-{
-   timeStep = step;
-}
-//////////////////////////////////////////////////////////////////////////
-double Grid3D::getTimeStep() const
-{
-   return timeStep;
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::fillExtentWithBlocks( UbTupleInt3 minInd, UbTupleInt3 maxInd )
-{
-   for(int x3 =  val<3>(minInd); x3 <  val<3>(maxInd); x3++)
-   {
-      for(int x2 =  val<2>(minInd); x2 <  val<2>(maxInd); x2++)
-      {
-         for(int x1 =  val<1>(minInd); x1 <  val<1>(maxInd); x1++)
-         {
-            Block3DPtr block( new Block3D(x1,x2,x3,0) );
-            this->addBlock(block);
-         }
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-//void Grid3D::notifyObservers( double step )
-//{
-//   BOOST_FOREACH(ObserverPtr o, observers)
-//   {
-//      o->update(step);
-//   }
-//
-//   //std::list<ObserverWeakPtr>::iterator iter = observers.begin();
-//
-//   //GridObserversSet::iterator iter = observers.begin();
-//   //while(iter != observers.end())
-//   //{
-//   //   if ((*iter).expired())
-//   //   {
-//   //      iter = observers.erase(iter);
-//   //   }
-//   //   else
-//   //   {
-//   //      ObserverPtr observer = (*iter).lock(); // create a shared_ptr from the weak_ptr
-//   //      observer->update(step);
-//   //      ++iter;
-//   //   }
-//   //}
-//
-//}
-//////////////////////////////////////////////////////////////////////////
-//void Grid3D::addObserver( ObserverPtr observer )
-//{
-//   observers.insert(observer);
-//   //observers.push_back(observer);
-//}
-////////////////////////////////////////////////////////////////////////////
-//void Grid3D::removeObserver( ObserverPtr observer )
-//{
-//   observers.erase(observer);
-//   //observers.remove(observer);
-//}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::deleteBlockIDs()
-{
-   this->blockIdMap.clear();
-}
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::renumberBlockIDs()
-{
-   deleteBlockIDs();
-
-   int startLevel = getCoarsestInitializedLevel();
-   int stopLevel = getFinestInitializedLevel();
-   int counter = 0;
-   
-   for (int l = startLevel; l <= stopLevel; l++)
-   {
-      std::vector<Block3DPtr> blockVector;
-      getBlocks(l, blockVector);
-      BOOST_FOREACH(Block3DPtr block, blockVector)
-      {
-         block->setGlobalID(counter);
-         blockIdMap.insert(std::make_pair(counter, block));
-         Block3D::setMaxGlobalID(counter);
-         counter++;
-      }
-   }
-}
-
-//////////////////////////////////////////////////////////////////////////
-void Grid3D::updateDistributedBlocks(CommunicatorPtr comm)
-{
-   
-   std::vector<int> blocks;
-   
-   if (comm->isRoot())
-   {
-      int startLevel = getCoarsestInitializedLevel();
-      int stopLevel = getFinestInitializedLevel();
-
-      for (int l = startLevel; l <= stopLevel; l++)
-      {
-         std::vector<Block3DPtr> blockVector;
-         getBlocks(l, blockVector);
-         BOOST_FOREACH(Block3DPtr block, blockVector)
-         {
-            blocks.push_back(block->getX1());
-            blocks.push_back(block->getX2());
-            blocks.push_back(block->getX3());
-            blocks.push_back(l);
-            blocks.push_back(block->getGlobalID());
-            blocks.push_back(block->getRank());
-         }
-      }
-   }
-   
-   comm->broadcast(blocks);
-
-   if (!comm->isRoot())
-   {
-      int startLevel = getCoarsestInitializedLevel();
-      int stopLevel = getFinestInitializedLevel();
-
-      blockIdMap.clear();
-
-      for (int l = startLevel; l<=stopLevel; l++)
-      {
-         levelSet[l].clear();
-      }
-      this->levelSet.clear();
-      levelSet.resize(Grid3DSystem::MAXLEVEL+1);
-
-      int rsize = blocks.size();
-      for (int i = 0; i < rsize; i+=6)
-      {
-         Block3DPtr block(new Block3D(blocks[i], blocks[i+1], blocks[i+2], blocks[i+3]));
-         block->setGlobalID(blocks[i+4]);
-         block->setRank(blocks[i+5]);
-         this->addBlock(block);
-      }
-
-   }
-
-}
-
-//////////////////////////////////////////////////////////////////////////
-
-
+#include "Grid3D.h"
+
+#include <set>
+
+#include <numerics/geometry3d/CoordinateTransformation3D.h>
+#include <basics/writer/WbWriterVtkXmlASCII.h>
+
+#include "Grid3DVisitor.h"
+#include "Block3DVisitor.h"
+#include "Interactor3D.h"
+#include "Grid3DSystem.h"
+#include "LBMSystem.h"
+#include <Block3D.h>
+#include <Communicator.h>
+
+
+using namespace std;
+
+Grid3D::Grid3D() : 
+                     rank(0),
+                     bundle(0),
+                     orgDeltaX(1.0),
+                     periodicX1(false),
+                     periodicX2(false),
+                     periodicX3(false),
+                     timeStep(0.0),
+                     blockNx1(0),
+                     blockNx2(0),
+                     blockNx3(0),
+                     nx1(0),
+                     nx2(0),
+                     nx3(0)
+{
+   levelSet.resize(Grid3DSystem::MAXLEVEL+1);
+}
+//////////////////////////////////////////////////////////////////////////
+Grid3D::Grid3D(CommunicatorPtr comm) : 
+   rank(0),
+   bundle(0),
+   orgDeltaX(1.0),
+   periodicX1(false),
+   periodicX2(false),
+   periodicX3(false),
+   timeStep(0.0),
+   blockNx1(0),
+   blockNx2(0),
+   blockNx3(0),
+   nx1(0),
+   nx2(0),
+   nx3(0)
+{
+   levelSet.resize(Grid3DSystem::MAXLEVEL+1);
+   bundle = comm->getBundleID();
+   rank = comm->getProcessID();
+}
+//////////////////////////////////////////////////////////////////////////
+Grid3D::Grid3D( CommunicatorPtr comm, int blockNx1, int blockNx2, int blockNx3, int gridNx1, int gridNx2, int gridNx3 ) : 
+   rank(0),
+   bundle(0),
+   orgDeltaX(1.0),
+   periodicX1(false),
+   periodicX2(false),
+   periodicX3(false),
+   timeStep(0.0),
+   blockNx1(blockNx1),
+   blockNx2(blockNx2),
+   blockNx3(blockNx2),
+   nx1(gridNx1),
+   nx2(gridNx2),
+   nx3(gridNx3)
+{
+   levelSet.resize(Grid3DSystem::MAXLEVEL+1);
+   bundle = comm->getBundleID();
+   rank = comm->getProcessID();
+   trafo = CoordinateTransformation3DPtr(new CoordinateTransformation3D(0.0, 0.0, 0.0, (double)blockNx1, (double)blockNx2, (double)blockNx3));
+   UbTupleInt3 minInd(0, 0, 0);
+   UbTupleInt3 maxInd(gridNx1, gridNx2, gridNx3);
+   this->fillExtentWithBlocks(minInd, maxInd);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::addInteractor(Interactor3DPtr interactor)
+{
+   interactors.push_back(interactor);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::addAndInitInteractor(Interactor3DPtr interactor,double timestep)
+{
+   interactors.push_back(interactor);
+   interactor->initInteractor(timestep);
+}
+//////////////////////////////////////////////////////////////////////////
+Grid3D::Interactor3DSet Grid3D::getInteractors()
+{
+   return interactors;
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::accept(Block3DVisitor& blockVisitor)
+{
+   int startLevel   = blockVisitor.getStartLevel();
+   int stopLevel    = blockVisitor.getStopLevel();
+
+   if(startLevel < 0 || stopLevel < 0 || startLevel > Grid3DSystem::MAXLEVEL || stopLevel > Grid3DSystem::MAXLEVEL) 
+      throw UbException(UB_EXARGS,"not valid level!");
+
+   bool dir     = startLevel < stopLevel;
+   if(dir) stopLevel += 1;
+   else stopLevel    -= 1;
+
+
+//   for (int l = startLevel; l!=stopLevel;)
+//   {
+//      std::vector<Block3DPtr> blockVector;
+//      getBlocks(l, blockVector);
+//      int sizeb = (int)blockVector.size();
+//#pragma omp parallel
+//#pragma omp for
+//      for(int i = 0; i < sizeb; i++)
+//      {
+//         blockVisitor.visit(shared_from_this(), blockVector[i]);
+//      }
+//      if (dir)  l++;
+//      else     l--;
+//   }
+   for(int l=startLevel; l!=stopLevel;)
+   {
+      std::vector<Block3DPtr> blockVector;
+      getBlocks(l, blockVector);
+      for(Block3DPtr b : blockVector)
+      {
+         blockVisitor.visit( shared_from_this(), b );
+      }
+      if(dir)  l++;
+      else     l--;
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::accept(Grid3DVisitor& gridVisitor)
+{
+   gridVisitor.visit( shared_from_this() );
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::accept(Grid3DVisitorPtr gridVisitor)
+{
+   gridVisitor->visit( shared_from_this() );
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::addBlock( Block3DPtr block )
+{
+   if (block)
+   {
+      this->blockIdMap.insert( std::make_pair( block->getGlobalID(), block) );
+      int level = block->getLevel();
+      this->levelSet[level].insert( std::make_pair( Block3DKey( block->getX1(), block->getX2(),  block->getX3() ), block) ).second;
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+bool Grid3D::deleteBlock( Block3DPtr block )
+{
+   return this->deleteBlock(block->getX1(), block->getX2(), block->getX3(), block->getLevel());
+}
+//////////////////////////////////////////////////////////////////////////
+bool Grid3D::deleteBlock(int ix1, int ix2, int ix3, int level)
+{
+   Block3DPtr block = this->getBlock(ix1, ix2, ix3, level);
+   if(block) 
+   {
+      this->blockIdMap.erase(block->getGlobalID());
+      return this->levelSet[level].erase( Block3DKey(ix1, ix2, ix3) ) > 0;
+   }
+   else
+   {
+      return false;
+   }
+}	
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::replaceBlock(Block3DPtr block)
+{
+   if (block)
+   {
+      this->deleteBlock(block);
+      this->addBlock(block);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+Block3DPtr Grid3D::getBlock( int ix1, int ix2, int ix3, int level ) const
+{
+   if( !this->hasLevel(level) ) return Block3DPtr();
+
+   int N1 = (nx1<<level);
+   int N2 = (nx2<<level);
+   int N3 = (nx3<<level);
+
+   if     (!this->isPeriodicX1() && (ix1>N1-1  || ix1<0)) return Block3DPtr();
+   else if( this->isPeriodicX1() && (ix1>=N1-1 || ix1<0)) { ix1=((ix1%N1)+N1)%N1; }
+   if     (!this->isPeriodicX2() && (ix2>N2-1  || ix2<0)) return Block3DPtr();
+   else if( this->isPeriodicX2() && (ix2>=N2-1 || ix2<0)) { ix2=((ix2%N2)+N2)%N2; }
+   if     (!this->isPeriodicX3() && (ix3>N3-1  || ix3<0)) return Block3DPtr();
+   else if( this->isPeriodicX3() && (ix3>=N3-1 || ix3<0)) { ix3=((ix3%N3)+N3)%N3; }
+
+   Block3DMap::const_iterator it;
+   it = levelSet[level].find( Block3DKey(ix1,ix2,ix3) );
+   if( it == levelSet[level].end() )
+      return Block3DPtr();
+   else
+      return it->second;
+}
+//////////////////////////////////////////////////////////////////////////
+Block3DPtr Grid3D::getBlock(int id) const
+{
+   BlockIDMap::const_iterator it;
+   if( ( it=blockIdMap.find( id ) ) == blockIdMap.end() )
+   {
+      return Block3DPtr();
+   }
+
+   return it->second;
+}
+//////////////////////////////////////////////////////////////////////////
+//const Grid3D::Block3DMap& Grid3D::getBlocks(int level) 
+//{ 
+//   return levelSet[level];
+//}
+//////////////////////////////////////////////////////////////////////////
+const Grid3D::BlockIDMap& Grid3D::getBlockIDs() 
+{ 
+   return blockIdMap;
+}
+//////////////////////////////////////////////////////////////////////////
+Block3DPtr Grid3D::getSuperBlock(Block3DPtr block)
+{
+   int ix1 = block->getX1();
+   int ix2 = block->getX2();
+   int ix3 = block->getX3();
+   int level = block->getLevel();
+   return getSuperBlock(ix1, ix2, ix3, level);
+}
+//////////////////////////////////////////////////////////////////////////
+Block3DPtr Grid3D::getSuperBlock(int ix1, int ix2, int ix3, int level)
+{
+   if(!this->hasLevel(level)) return Block3DPtr();
+   if(level <  1) throw UbException(UB_EXARGS,"level <1");
+   
+   //from Lower Level to higher:	 >> 	1 in x1,x2,x3 
+   Block3DPtr block;
+   for(int l=level-1; l>=0; l--)
+   {
+      ix1 = ix1 >> 1;
+      ix2 = ix2 >> 1;
+      ix3 = ix3 >> 1;
+
+      block = this->getBlock(ix1, ix2, ix3, l);
+      if(block) return block;
+   }
+   return Block3DPtr();
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocks(Block3DPtr block, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   int ix1 = block->getX1();
+   int ix2 = block->getX2();
+   int ix3 = block->getX3();
+   int level = block->getLevel();
+   getSubBlocks(ix1, ix2, ix3, level, levelDepth, blocks);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocks(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   if(!this->getBlock(ix1, ix2, ix3, level)) return;
+   if(level > 0 && !this->getSuperBlock(ix1, ix2, ix3, level)) return;
+   if(level >=  Grid3DSystem::MAXLEVEL)    throw UbException(UB_EXARGS,"Level bigger then MAXLEVEL");
+   
+   int x1[] = { ix1<<1, (ix1<<1)+1 };
+   int x2[] = { ix2<<1, (ix2<<1)+1 };
+   int x3[] = { ix3<<1, (ix3<<1)+1 };
+   int l    = level + 1;
+
+   for(int i=0; i<2; i++)
+      for(int j=0; j<2; j++)
+         for(int k=0; k<2; k++)
+         {
+            Block3DPtr block = this->getBlock(x1[i], x2[j], x3[k], l);
+            if(block) blocks.push_back(block);
+            else if(l < levelDepth) this->getSubBlocks(x1[i], x2[j], x3[k], l, levelDepth, blocks);
+         }
+}
+//////////////////////////////////////////////////////////////////////////
+bool Grid3D::expandBlock(int ix1, int ix2, int ix3, int level)
+{
+   this->checkLevel(level);
+
+   Block3DPtr block = this->getBlock( ix1, ix2, ix3, level );
+   if(!block)             throw UbException(UB_EXARGS,"block(x1="+UbSystem::toString(ix1)+", x2="+UbSystem::toString(ix2)+", x3="+UbSystem::toString(ix3)+", l="+UbSystem::toString(level)+") is not exist");
+   //if(!block->isActive()) throw UbException(UB_EXARGS,"block(x1="+UbSystem::toString(ix1)+", x2="+UbSystem::toString(ix2)+", x3="+UbSystem::toString(ix3)+", l="+UbSystem::toString(level)+") is not active");
+
+   //da bei periodic der eigentliche block andere indizes hat:
+   ix1 = block->getX1();
+   ix2 = block->getX2();
+   ix3 = block->getX3();
+
+   int l      = level+1;
+   if( l>Grid3DSystem::MAXLEVEL ) throw UbException(UB_EXARGS,"level > Grid3D::MAXLEVEL");
+
+   int west   = ix1<<1;
+   int east   = west+1;
+   int south  = ix2<<1;
+   int north  = south+1;
+   int bottom = ix3<<1;
+   int top    = bottom+1;
+
+   Block3DPtr blockBSW = Block3DPtr(new Block3D(west, south, bottom, l));
+   Block3DPtr blockBSE = Block3DPtr(new Block3D(east, south, bottom, l));
+   Block3DPtr blockBNW = Block3DPtr(new Block3D(west, north, bottom, l));
+   Block3DPtr blockBNE = Block3DPtr(new Block3D(east, north, bottom, l));
+   Block3DPtr blockTSW = Block3DPtr(new Block3D(west, south, top   , l));
+   Block3DPtr blockTSE = Block3DPtr(new Block3D(east, south, top   , l));
+   Block3DPtr blockTNW = Block3DPtr(new Block3D(west, north, top   , l));
+   Block3DPtr blockTNE = Block3DPtr(new Block3D(east, north, top   , l));
+
+   if( !this->deleteBlock( ix1, ix2, ix3, level ) )
+      throw UbException(UB_EXARGS,"could not delete block");
+
+   this->addBlock(blockBSW);
+   this->addBlock(blockBSE);
+   this->addBlock(blockBNW);
+   this->addBlock(blockBNE);
+   this->addBlock(blockTSW);
+   this->addBlock(blockTSE);
+   this->addBlock(blockTNW);
+   this->addBlock(blockTNE);
+
+   return true;
+}
+//////////////////////////////////////////////////////////////////////////
+Block3DPtr Grid3D::collapseBlock(int fix1, int fix2, int fix3, int flevel, int levelDepth)
+{
+   using UbSystem::toString;
+
+   Block3DPtr fblock = this->getBlock(fix1, fix2, fix3, flevel);
+   if( flevel <  1         ) throw UbException(UB_EXARGS,"level of block ("+toString(fix1)+","+toString(fix2)+","+toString(fix3)+","+toString(flevel)+") is < 1");
+   if( !fblock             ) 
+   {
+      throw UbException(UB_EXARGS,"specific block("+toString(fix1)+","+toString(fix2)+","+toString(fix3)+","+toString(flevel)+") doesn't exists");
+   }
+   if( !fblock->isActive() ) throw UbException(UB_EXARGS,"block("+toString(fix1)+","+toString(fix2)+","+toString(fix3)+","+toString(flevel)+") is not active");
+
+   //da bei periodic der eigentliche block andere indizes hat:
+   fix1 = fblock->getX1();
+   fix2 = fblock->getX2();
+   fix3 = fblock->getX3();
+
+   int cix1 = fblock->getX1() >> 1;
+   int cix2 = fblock->getX2() >> 1;
+   int cix3 = fblock->getX3() >> 1;
+
+   int fx1[2] = { cix1<<1,  (cix1<<1)+1 };
+   int fx2[2] = { cix2<<1,  (cix2<<1)+1 };
+   int fx3[2] = { cix3<<1,  (cix3<<1)+1 };
+   int clevel = flevel - 1;
+
+   vector<Block3DPtr> blocks;
+   for(int i=0; i<2; i++)
+      for(int k=0; k<2; k++)
+         for(int l=0; l<2; l++)
+         {
+            this->getSubBlocks(fx1[k], fx2[i], fx3[l], flevel, levelDepth, blocks);
+            while(!blocks.empty())
+            {
+               //man muss nur eine von den moeglichen acht "collapsen", die anderen werden
+               //dann (rekursiv) collapsed, da die schleife oben alle vier abfragt
+               this->collapseBlock(blocks[0]->getX1(), blocks[0]->getX2(), blocks[0]->getX3(), blocks[0]->getLevel(), levelDepth);
+               this->getSubBlocks(fx1[k], fx2[i], fx3[l], flevel, levelDepth, blocks);
+            }
+         }
+
+         vector<Block3DPtr> fineBlocks(8);
+         /*BSW*/fineBlocks[0] = this->getBlock( fx1[0], fx2[0], fx3[0], flevel );
+         /*BSE*/fineBlocks[1] = this->getBlock( fx1[1], fx2[0], fx3[0], flevel );
+         /*BNE*/fineBlocks[2] = this->getBlock( fx1[1], fx2[1], fx3[0], flevel );
+         /*BNW*/fineBlocks[3] = this->getBlock( fx1[0], fx2[1], fx3[0], flevel );
+         /*TSW*/fineBlocks[4] = this->getBlock( fx1[0], fx2[0], fx3[1], flevel );
+         /*TSE*/fineBlocks[5] = this->getBlock( fx1[1], fx2[0], fx3[1], flevel );
+         /*TNE*/fineBlocks[6] = this->getBlock( fx1[1], fx2[1], fx3[1], flevel );
+         /*TNW*/fineBlocks[7] = this->getBlock( fx1[0], fx2[1], fx3[1], flevel );
+
+         Block3DPtr cblock = Block3DPtr(new Block3D(cix1, cix2, cix3, clevel));
+
+         for(int i=0; i<2; i++)
+            for(int k=0; k<2; k++)
+               for(int l=0; l<2; l++)
+                  if( !this->deleteBlock( fx1[k], fx2[i], fx3[l], flevel ) )
+                     throw UbException(UB_EXARGS,"could not delete block");
+
+         this->addBlock(cblock);
+
+         return cblock;
+}
+//////////////////////////////////////////////////////////////////////////
+// TODO: make visitor for this
+void Grid3D::deleteConnectors()
+{
+   for(Block3DMap blockMap : levelSet)
+   {
+      for(Block3DMap::value_type b : blockMap)
+      {
+         Block3DPtr block =  b.second;
+         block->deleteConnectors();
+         //block->deleteInterpolationConnectors();
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+Grid3D::connection_t Grid3D::connect(Grid3D::signal_t::slot_function_type subscriber)
+{
+   return sig.connect(subscriber);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::disconnect(Grid3D::connection_t subscriber)
+{
+   subscriber.disconnect();
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::coProcess(double step)
+{
+   timeStep = step;
+   sig(step);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setRank(int rank)
+{
+   this->rank = rank;
+}
+//////////////////////////////////////////////////////////////////////////
+int Grid3D::getRank() const
+{
+   return rank;
+}
+//////////////////////////////////////////////////////////////////////////
+int  Grid3D::getBundle() const          
+{ 
+   return bundle;       
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setBundle(int bundle) 
+{ 
+   this->bundle = bundle; 
+} 
+//////////////////////////////////////////////////////////////////////////
+bool Grid3D::isPeriodicX1() const 
+{ 
+   return this->periodicX1; 
+}
+//////////////////////////////////////////////////////////////////////////
+bool Grid3D::isPeriodicX2() const 
+{ 
+   return this->periodicX2; 
+}
+//////////////////////////////////////////////////////////////////////////
+bool Grid3D::isPeriodicX3() const 
+{ 
+   return this->periodicX3; 
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setPeriodicX1(bool value)
+{
+   this->periodicX1 = value;
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setPeriodicX2(bool value)
+{
+   this->periodicX2 = value;
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setPeriodicX3(bool value)
+{
+   this->periodicX3 = value;
+}
+//////////////////////////////////////////////////////////////////////////
+UbTupleInt3 Grid3D::getBlockIndexes(double blockX1Coord, double blockX2Coord, double blockX3Coord)  const
+{
+   if(!trafo)
+   {
+      return makeUbTuple( (int)blockX1Coord, (int)blockX2Coord, (int)blockX3Coord );
+   }
+
+   return makeUbTuple(  (int)trafo->transformForwardToX1Coordinate( blockX1Coord, blockX2Coord, blockX3Coord )
+      , (int)trafo->transformForwardToX2Coordinate( blockX1Coord, blockX2Coord, blockX3Coord )
+      , (int)trafo->transformForwardToX3Coordinate( blockX1Coord, blockX2Coord, blockX3Coord ) );
+
+}
+//////////////////////////////////////////////////////////////////////////
+UbTupleInt3 Grid3D::getBlockIndexes(double blockX1Coord, double blockX2Coord, double blockX3Coord, int level)  const
+{
+   if(!trafo)
+   {
+      return makeUbTuple( (int)blockX1Coord, (int)blockX2Coord, (int)blockX3Coord );
+   }
+
+   double dx = getDeltaX(level);
+   double blockLentghX1, blockLentghX2, blockLentghX3; 
+   blockLentghX1 = blockNx1*dx;
+   blockLentghX2 = blockNx2*dx;
+   blockLentghX3 = blockNx3*dx;
+   UbTupleDouble3 org = getBlockWorldCoordinates(0, 0, 0, 0);
+
+   CoordinateTransformation3DPtr trafo_temp(new CoordinateTransformation3D(val<1>(org),val<2>(org),val<3>(org),blockLentghX1,blockLentghX2,blockLentghX3));
+
+   if(!trafo_temp)
+   {
+      return makeUbTuple( (int)blockX1Coord, (int)blockX2Coord, (int)blockX3Coord );
+   }
+
+   return makeUbTuple(  (int)trafo_temp->transformForwardToX1Coordinate( blockX1Coord, blockX2Coord, blockX3Coord )
+      , (int)trafo_temp->transformForwardToX2Coordinate( blockX1Coord, blockX2Coord, blockX3Coord )
+      , (int)trafo_temp->transformForwardToX3Coordinate( blockX1Coord, blockX2Coord, blockX3Coord ) );
+
+}
+//////////////////////////////////////////////////////////////////////////
+UbTupleDouble3  Grid3D::getBlockLengths(const Block3DPtr block) const
+{
+   int    level = block->getLevel();
+   double delta = 1.0/(double)(1<<level);
+
+   if(!trafo) makeUbTuple<double, double, double>(delta,delta,delta);
+
+   return makeUbTuple(   trafo->getX1CoordinateScaling()*delta,
+                                                       trafo->getX2CoordinateScaling()*delta,
+                                                       trafo->getX3CoordinateScaling()*delta );
+}
+//////////////////////////////////////////////////////////////////////////
+UbTupleDouble6 Grid3D::getBlockOversize() const 
+{ 
+   return makeUbTuple(0.0,0.0,0.0,0.0,0.0,0.0); 
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setCoordinateTransformator(CoordinateTransformation3DPtr trafo)
+{
+   this->trafo = trafo;
+}
+//////////////////////////////////////////////////////////////////////////
+const CoordinateTransformation3DPtr Grid3D::getCoordinateTransformator() const 
+{ 
+   return this->trafo; 
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setDeltaX(double dx)
+{
+   this->orgDeltaX = dx;
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setDeltaX(double worldUnit, double gridUnit)
+{
+   this->orgDeltaX = worldUnit/gridUnit;
+}
+//////////////////////////////////////////////////////////////////////////
+double Grid3D::getDeltaX(int level) const 
+{ 
+   double delta = this->orgDeltaX/(double)(1<<level);
+   return delta; 
+}
+//////////////////////////////////////////////////////////////////////////
+double Grid3D::getDeltaX(Block3DPtr block) const 
+{ 
+   return getDeltaX(block->getLevel()); 
+}
+//////////////////////////////////////////////////////////////////////////
+UbTupleDouble3  Grid3D::getNodeOffset(Block3DPtr block) const 
+{ 
+   double delta = this->getDeltaX(block);
+   return makeUbTuple(OFFSET * delta, OFFSET * delta, OFFSET * delta);
+}
+////////////////////////////////////////////////////////////////////////////
+Vector3D Grid3D::getNodeCoordinates(Block3DPtr block, int ix1, int ix2, int ix3) const
+{
+   UbTupleDouble3 org = this->getBlockWorldCoordinates(block);
+   UbTupleDouble3 nodeOffset = this->getNodeOffset(block);
+   double deltaX = getDeltaX(block);
+
+   double x1 = val<1>(org) - val<1>(nodeOffset) + (double)ix1*deltaX;
+   double x2 = val<2>(org) - val<2>(nodeOffset) + (double)ix2*deltaX;
+   double x3 = val<3>(org) - val<3>(nodeOffset) + (double)ix3*deltaX;
+
+   return Vector3D(x1, x2, x3);
+}
+////////////////////////////////////////////////////////////////////////////
+UbTupleInt3 Grid3D::getNodeIndexes(Block3DPtr block, double nodeX1Coord, double nodeX2Coord, double nodeX3Coord) const
+{
+   UbTupleDouble3 org = this->getBlockWorldCoordinates(block);
+   UbTupleDouble3 nodeOffset = this->getNodeOffset(block);
+   double deltaX = getDeltaX(block);
+
+   int ix1,ix2,ix3;
+   double ixx1=(abs(nodeX1Coord - val<1>(org) + val<1>(nodeOffset)) / deltaX);
+   double ixx2=(abs(nodeX2Coord - val<2>(org) + val<2>(nodeOffset)) / deltaX);
+   double ixx3=(abs(nodeX3Coord - val<3>(org) + val<3>(nodeOffset)) / deltaX);
+   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; 
+
+   return makeUbTuple(ix1, ix2, ix3);
+}
+//////////////////////////////////////////////////////////////////////////
+//returns tuple with origin of block in world-coordinates
+UbTupleDouble3 Grid3D::getBlockWorldCoordinates(Block3DPtr block) const
+{
+   if(!block)
+      throw UbException(UB_EXARGS,"block " + block->toString() + "is not exist");
+
+   int blockX1Index = block->getX1();
+   int blockX2Index = block->getX2();
+   int blockX3Index = block->getX3();
+   int level = block->getLevel();
+
+   return this->getBlockWorldCoordinates(blockX1Index, blockX2Index, blockX3Index, level);
+}
+//////////////////////////////////////////////////////////////////////////
+UbTupleDouble3 Grid3D::getBlockWorldCoordinates(int blockX1Index, int blockX2Index, int blockX3Index, int level) const
+{
+   double c1oShiftedLevel = 1.0/(double)(1<<level);
+   double x1 = (double)blockX1Index*c1oShiftedLevel;
+   double x2 = (double)blockX2Index*c1oShiftedLevel;
+   double x3 = (double)blockX3Index*c1oShiftedLevel;
+
+   if(!trafo) return UbTupleDouble3( x1,x2,x3 );
+
+   return UbTupleDouble3( trafo->transformBackwardToX1Coordinate( x1,x2,x3 )
+      ,trafo->transformBackwardToX2Coordinate( x1,x2,x3 )
+      ,trafo->transformBackwardToX3Coordinate( x1,x2,x3 ) );
+}
+//////////////////////////////////////////////////////////////////////////
+//double Grid3D::getDeltaT(Block3DPtr block) const 
+//{ 
+//   int    level = block->getLevel();
+//   double delta = 1.0/(double)(1<<level);
+//   return delta; 
+//}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::checkLevel(int level)
+{
+   if(level < 0)
+   {
+      throw UbException(UB_EXARGS,"l("+UbSystem::toString(level)+(string)")<0");
+   }
+   if(level > Grid3DSystem::MAXLEVEL)
+   {
+      throw UbException(UB_EXARGS,"l("+UbSystem::toString(level)+(string)")>MAXLEVEL");
+   }
+   if(this->levelSet[level].size() == 0)
+   {
+      throw UbException(UB_EXARGS,"levelMap for level("+UbSystem::toString(level)+(string)")==NULL");
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+bool Grid3D::hasLevel(int level) const
+{
+   if(level < 0                        ) return false;
+   if(level > Grid3DSystem::MAXLEVEL                 ) return false;
+   if(this->levelSet[level].size() == 0) return false;
+
+   return true;
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setBlockNX( int nx1, int nx2, int nx3 )
+{
+   blockNx1 = nx1;    
+   blockNx2 = nx2;    
+   blockNx3 = nx3; 
+}
+//////////////////////////////////////////////////////////////////////////
+UbTupleInt3 Grid3D::getBlockNX() const
+{
+   return makeUbTuple(blockNx1, blockNx2, blockNx3);
+}
+//////////////////////////////////////////////////////////////////////////
+
+Block3DPtr Grid3D::getNeighborBlock( int dir, int ix1, int ix2, int ix3, int level ) const
+{
+   return this->getBlock(  ix1+Grid3DSystem::EX1[dir], ix2+Grid3DSystem::EX2[dir], ix3+Grid3DSystem::EX3[dir], level );
+}
+//////////////////////////////////////////////////////////////////////////
+Block3DPtr Grid3D::getNeighborBlock(int dir, Block3DPtr block) const
+{
+   int x1 = block->getX1();
+   int x2 = block->getX2();
+   int x3 = block->getX3();
+   int level = block->getLevel();
+   return this->getNeighborBlock( dir, x1, x2, x3, level);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getAllNeighbors(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   for(int dir=Grid3DSystem::STARTDIR; dir<=Grid3DSystem::ENDDIR; dir++)
+   //for (int dir = Grid3DSystem::STARTDIR; dir<=Grid3DSystem::TS; dir++)
+   {
+      this->getNeighborBlocksForDirection(dir,ix1,ix2,ix3,level,levelDepth,blocks);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getAllNeighbors(Block3DPtr block, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   int x1 = block->getX1();
+   int x2 = block->getX2();
+   int x3 = block->getX3();
+   getAllNeighbors(x1,x2,x3,level,levelDepth,blocks);
+}
+//////////////////////////////////////////////////////////////////////////
+  /**
+   * Returns all direct northern neighbor cells of the specified grid cell (may be NULL!).
+   * @param ix1 index in x1 direction
+   * @param ix2 index in x2 direction
+   * @param ix3 index in x3 direction
+   * @param level the level
+   */
+void Grid3D::getNeighborsNorth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+	Block3DPtr block = this->getBlock(ix1, ix2+1, ix3, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1, ix2+1, ix3, level);
+      if(block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksSouth(ix1, ix2+1, ix3, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsTop(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1, ix2, ix3+1, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1, ix2, ix3+1, level);
+      if(block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksBottom(ix1, ix2, ix3+1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsBottom(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1, ix2, ix3-1, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1, ix2, ix3-1, level);
+      if(block) { blocks.push_back(block); }
+
+   }
+   this->getSubBlocksTop(ix1, ix2, ix3-1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsSouth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1, ix2-1, ix3, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1, ix2-1, ix3, level);
+      if(block) { blocks.push_back(block); }
+
+   }
+   this->getSubBlocksNorth(ix1, ix2-1, ix3, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+	Block3DPtr block = this->getBlock(ix1+1, ix2, ix3, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1+1, ix2, ix3, level);
+      if(block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksWest(ix1+1, ix2, ix3, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1-1, ix2, ix3, level);
+   if(block) { blocks.push_back(block);  }
+
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1-1, ix2, ix3, level);
+      if(block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksEast(ix1-1, ix2, ix3, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+//   diagonals                                            
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsNorthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1+1, ix2+1, ix3, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1+1, ix2+1, ix3, level);
+      if(block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksSouthWest(ix1+1, ix2+1, ix3, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsNorthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1-1, ix2+1, ix3, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1-1, ix2+1, ix3, level);
+      if(block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksSouthEast(ix1-1, ix2+1, ix3, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsSouthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1+1, ix2-1, ix3, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1+1, ix2-1, ix3, level);
+      if(block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksNorthWest(ix1+1, ix2-1, ix3, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsSouthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1-1, ix2-1, ix3, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1-1, ix2-1, ix3, level);
+      if(block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksNorthEast(ix1-1, ix2-1, ix3, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+//   diagonals  top                                     
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsTopEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1+1, ix2, ix3+1, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1+1, ix2, ix3+1, level);
+      if(block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksBottomWest(ix1+1, ix2, ix3+1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsTopWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1-1, ix2, ix3+1, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1-1, ix2, ix3+1, level);
+      if(block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksBottomEast(ix1-1, ix2, ix3+1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsTopNorth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1, ix2+1, ix3+1, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1, ix2+1, ix3+1, level);
+      if(block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksBottomSouth(ix1, ix2+1, ix3+1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsTopSouth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1, ix2-1, ix3+1, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1, ix2-1, ix3+1, level);
+      if(block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksBottomNorth(ix1, ix2-1, ix3+1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+//   diagonals  bottom                                
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsBottomEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1+1, ix2, ix3-1, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1+1, ix2, ix3-1, level);
+      if(block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksTopWest(ix1+1, ix2, ix3-1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsBottomWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1-1, ix2, ix3-1, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1-1, ix2, ix3-1, level);
+      if(block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksTopEast(ix1-1, ix2, ix3-1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsBottomNorth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1, ix2+1, ix3-1, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1, ix2+1, ix3-1, level);
+      if(block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksTopSouth(ix1, ix2+1, ix3-1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsBottomSouth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1, ix2-1, ix3-1, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1, ix2-1, ix3-1, level);
+      if(block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksTopNorth(ix1, ix2-1, ix3-1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsTopNorthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1+1, ix2+1, ix3+1, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1+1, ix2+1, ix3+1, level);
+      if(block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksBottomSouthWest(ix1+1, ix2+1, ix3+1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsTopNorthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1-1, ix2+1, ix3+1, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1-1, ix2+1, ix3+1, level);
+      if(block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksBottomSouthEast(ix1-1, ix2+1, ix3+1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsTopSouthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1+1, ix2-1, ix3+1, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1+1, ix2-1, ix3+1, level);
+      if(block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksBottomNorthWest(ix1+1, ix2-1, ix3+1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsTopSouthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1-1, ix2-1, ix3+1, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1-1, ix2-1, ix3+1, level);
+      if(block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksBottomNorthEast(ix1-1, ix2-1, ix3+1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsBottomNorthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1+1, ix2+1, ix3-1, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1+1, ix2+1, ix3-1, level);
+      if(block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksTopSouthWest(ix1+1, ix2+1, ix3-1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsBottomNorthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1-1, ix2+1, ix3-1, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1-1, ix2+1, ix3-1, level);
+      if(block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksTopSouthEast(ix1-1, ix2+1, ix3-1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsBottomSouthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1+1, ix2-1, ix3-1, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1+1, ix2-1, ix3-1, level);
+      if(block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksTopNorthWest(ix1+1, ix2-1, ix3-1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsBottomSouthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1-1, ix2-1, ix3-1, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1-1, ix2-1, ix3-1, level);
+      if(block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksTopNorthEast(ix1-1, ix2-1, ix3-1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborBlocksForDirection(int dir, int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   switch(dir)
+   {
+   case Grid3DSystem::E  : this->getNeighborsEast(ix1, ix2, ix3, level,levelDepth, blocks);break;
+   case Grid3DSystem::W  : this->getNeighborsWest(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::N  : this->getNeighborsNorth(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::S  : this->getNeighborsSouth(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::T  : this->getNeighborsTop(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::B  : this->getNeighborsBottom(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::NE : this->getNeighborsNorthEast(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::SW : this->getNeighborsSouthWest(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::SE : this->getNeighborsSouthEast(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::NW : this->getNeighborsNorthWest(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::TE : this->getNeighborsTopEast(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::BW : this->getNeighborsBottomWest(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::BE : this->getNeighborsBottomEast(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::TW : this->getNeighborsTopWest(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::TN : this->getNeighborsTopNorth(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::BS : this->getNeighborsBottomSouth(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::BN : this->getNeighborsBottomNorth(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::TS : this->getNeighborsTopSouth(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::TNE: this->getNeighborsTopNorthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::TNW: this->getNeighborsTopNorthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::TSE: this->getNeighborsTopSouthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::TSW: this->getNeighborsTopSouthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::BNE: this->getNeighborsBottomNorthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::BNW: this->getNeighborsBottomNorthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::BSE: this->getNeighborsBottomSouthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::BSW: this->getNeighborsBottomSouthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   default:throw UbException(UB_EXARGS,"direction "+UbSystem::toString(dir)+" is not exist");
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsZero(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   Block3DPtr block = this->getBlock(ix1, ix2, ix3, level);
+   if(block) { blocks.push_back(block); }
+
+   if(level > 0)
+   {
+      block = this->getSuperBlock(ix1, ix2, ix3, level);
+      if(block) { blocks.push_back(block); }
+   }
+   // this->getSubBlocksNull(ix1, ix2, ix3, level, blocks, levelDepth);
+   this->getSubBlocks(ix1, ix2, ix3, level, levelDepth, blocks);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksZero(int ix1, int ix2, int ix3, int level,vector<Block3DPtr> &blockVector, int levelDepth)
+{
+   int x1E  = (ix1 << 1) + 1;
+   int x1W  = (ix1 << 1) ;
+   int x2S = ix2 << 1;
+   int x2N = x2S + 1;
+   int x3B = ix3 << 1;
+   int x3T = x3B + 1;
+   int l   = level + 1;
+
+   Block3DPtr block = this->getBlock(x1E, x2S, x3B, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksEast(x1E, x2S, x3B, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1E, x2N, x3B, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksEast(x1E, x2N, x3B, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1E, x2S, x3T, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksEast(x1E, x2S, x3T, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1E, x2N, x3T, l);
+   if(block != NULL)      blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksEast(x1E, x2N, x3T, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1W, x2S, x3B, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksEast(x1W, x2S, x3B, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1W, x2N, x3B, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksEast(x1W, x2N, x3B, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1W, x2S, x3T, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksEast(x1W, x2S, x3T, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1W, x2N, x3T, l);
+   if(block != NULL)      blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksEast(x1W, x2N, x3T, l, blockVector,levelDepth);  
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborBlocksForDirectionWithDirZero(int dir, int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks)
+{
+   switch(dir)
+   {
+   case Grid3DSystem::E  : this->getNeighborsEast(ix1, ix2, ix3, level,levelDepth, blocks);break;
+   case Grid3DSystem::W  : this->getNeighborsWest(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::N  : this->getNeighborsNorth(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::S  : this->getNeighborsSouth(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::T  : this->getNeighborsTop(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::B  : this->getNeighborsBottom(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::NE : this->getNeighborsNorthEast(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::SW : this->getNeighborsSouthWest(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::SE : this->getNeighborsSouthEast(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::NW : this->getNeighborsNorthWest(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::TE : this->getNeighborsTopEast(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::BW : this->getNeighborsBottomWest(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::BE : this->getNeighborsBottomEast(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::TW : this->getNeighborsTopWest(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::TN : this->getNeighborsTopNorth(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::BS : this->getNeighborsBottomSouth(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::BN : this->getNeighborsBottomNorth(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::TS : this->getNeighborsTopSouth(ix1, ix2, ix3, level,levelDepth, blocks); break;
+   case Grid3DSystem::TNE: this->getNeighborsTopNorthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::TNW: this->getNeighborsTopNorthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::TSE: this->getNeighborsTopSouthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::TSW: this->getNeighborsTopSouthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::BNE: this->getNeighborsBottomNorthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::BNW: this->getNeighborsBottomNorthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::BSE: this->getNeighborsBottomSouthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::BSW: this->getNeighborsBottomSouthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::ZERO: this->getNeighborsZero(ix1, ix2, ix3, level,levelDepth, blocks);break;
+   default:throw UbException(UB_EXARGS,"direction "+UbSystem::toString(dir)+" is not exist");
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksEast(int ix1, int ix2, int ix3, int level,vector<Block3DPtr> &blockVector, int levelDepth)
+{
+   int x1  = (ix1 << 1) + 1;
+   int x2S = ix2 << 1;
+   int x2N = x2S + 1;
+   int x3B = ix3 << 1;
+   int x3T = x3B + 1;
+   int l   = level + 1;
+
+   Block3DPtr block = this->getBlock(x1, x2S, x3B, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksEast(x1, x2S, x3B, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1, x2N, x3B, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksEast(x1, x2N, x3B, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1, x2S, x3T, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksEast(x1, x2S, x3T, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1, x2N, x3T, l);
+   if(block != NULL)      blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksEast(x1, x2N, x3T, l, blockVector,levelDepth);
+}
+
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksWest(int ix1, int ix2, int ix3, int level,vector<Block3DPtr> &blockVector, int levelDepth)
+{
+   int x1  = ix1 << 1;
+   int x2S = ix2 << 1;
+   int x2N = x2S + 1;
+   int x3B = ix3 << 1;
+   int x3T = x3B + 1;
+   int l   = level + 1;
+
+   Block3DPtr block = this->getBlock(x1, x2S, x3B, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksWest(x1, x2S, x3B, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1, x2N, x3B, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksWest(x1, x2N, x3B, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1, x2S, x3T, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksWest(x1, x2S, x3T, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1, x2N, x3T, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksWest(x1, x2N, x3T, l, blockVector,levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksNorth(int ix1, int ix2, int ix3, int level,vector<Block3DPtr> &blockVector, int levelDepth)
+{
+   int x1W = ix1 << 1;
+   int x1E = x1W + 1;
+   int x2  = (ix2 << 1) + 1;
+   int x3B = ix3 << 1;
+   int x3T = x3B + 1;
+   int l   = level + 1;
+
+   Block3DPtr block = this->getBlock(x1W, x2, x3B, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksNorth(x1W, x2, x3B, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1E, x2, x3B, l);
+   if(block != NULL)      blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksNorth(x1E, x2, x3B, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1W, x2, x3T, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksNorth(x1W, x2, x3T, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1E, x2, x3T, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksNorth(x1E, x2, x3T, l, blockVector,levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksSouth(int ix1, int ix2, int ix3, int level,vector<Block3DPtr> &blockVector, int levelDepth)
+{
+   int x1W = ix1 << 1;
+   int x1E = x1W + 1;
+   int x2  = ix2 << 1;
+   int x3B = ix3 << 1;
+   int x3T = x3B + 1;
+   int l   = level + 1;
+
+   Block3DPtr block = this->getBlock(x1W, x2, x3B, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksSouth(x1W, x2, x3B, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1E, x2, x3B, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksSouth(x1E, x2, x3B, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1W, x2, x3T, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksSouth(x1W, x2, x3T, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1E, x2, x3T, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksSouth(x1E, x2, x3T, l, blockVector,levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksTop(int ix1, int ix2, int ix3, int level,vector<Block3DPtr> &blockVector, int levelDepth)
+{
+   int x1W = ix1 << 1;
+   int x1E = x1W + 1;
+   int x2S = ix2 << 1;
+   int x2N = x2S + 1;
+   int x3  = (ix3 << 1) + 1;
+   int l   = level + 1;
+
+   Block3DPtr block = this->getBlock(x1W, x2N, x3, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksTop(x1W, x2N, x3, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1E, x2N, x3, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksTop(x1E, x2N, x3, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1W, x2S, x3, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksTop(x1W, x2S, x3, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1E, x2S, x3, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksTop(x1E, x2S, x3, l, blockVector,levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksBottom(int ix1, int ix2, int ix3, int level,vector<Block3DPtr> &blockVector, int levelDepth)
+{
+   int x1W = ix1 << 1;
+   int x1E = x1W + 1;
+   int x2S = ix2 << 1;
+   int x2N = x2S + 1;
+   int x3  = ix3 << 1;
+   int l   = level + 1;
+
+   Block3DPtr block = this->getBlock(x1W, x2N, x3, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksBottom(x1W, x2N, x3, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1E, x2N, x3, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksBottom(x1E, x2N, x3, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1W, x2S, x3, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksBottom(x1W, x2S, x3, l, blockVector,levelDepth);
+
+   block = this->getBlock(x1E, x2S, x3, l);
+   if(block != NULL)       blockVector.push_back(block);
+   else if(l < levelDepth) this->getSubBlocksBottom(x1E, x2S, x3, l, blockVector,levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+//  diagonals
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksNorthEast(int ix1, int ix2, int ix3, int level, vector<Block3DPtr>& blockVector, int levelDepth)
+{
+   int x1  = (ix1 << 1) + 1;
+   int x2  = (ix2 << 1) + 1;
+   int x3B = (ix3 << 1);
+   int x3T = x3B+1;
+   int l   = level + 1;
+
+   Block3DPtr blockB = this->getBlock(x1, x2, x3B, l);
+   if(blockB) blockVector.push_back(blockB);
+   else if(l < levelDepth) this->getSubBlocksNorthEast(x1, x2, x3B, l, blockVector, levelDepth);
+
+   Block3DPtr blockT = this->getBlock(x1, x2, x3T, l);
+   if(blockT) blockVector.push_back(blockT);
+   else if(l < levelDepth) this->getSubBlocksNorthEast(x1, x2, x3T, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksNorthWest(int ix1, int ix2, int ix3, int level, vector<Block3DPtr>& blockVector, int levelDepth)
+{
+   int x1  = (ix1 << 1);
+   int x2  = (ix2 << 1) + 1;
+   int x3B = (ix3 << 1);
+   int x3T = x3B+1;
+   int l   = level + 1;
+
+   Block3DPtr blockB = this->getBlock(x1, x2,x3B, l);
+   if(blockB) blockVector.push_back(blockB);
+   else if(l < levelDepth) this->getSubBlocksNorthWest(x1, x2, x3B, l, blockVector, levelDepth);
+
+   Block3DPtr blockT = this->getBlock(x1, x2,x3T, l);
+   if(blockT) blockVector.push_back(blockT);
+   else if(l < levelDepth) this->getSubBlocksNorthWest(x1, x2, x3T, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksSouthWest(int ix1, int ix2, int ix3, int level, vector<Block3DPtr>& blockVector, int levelDepth)
+{
+   int x1  = ix1 << 1;
+   int x2  = ix2 << 1;
+   int x3B = (ix3 << 1);
+   int x3T = x3B+1;
+   int l  = level + 1;
+
+   Block3DPtr blockB = this->getBlock(x1, x2,x3B, l);
+   if(blockB) blockVector.push_back(blockB);
+   else if(l < levelDepth) this->getSubBlocksSouthWest(x1, x2, x3B, l, blockVector, levelDepth);
+
+   Block3DPtr blockT = this->getBlock(x1, x2,x3T, l);
+   if(blockT) blockVector.push_back(blockT);
+   else if(l < levelDepth) this->getSubBlocksSouthWest(x1, x2, x3T, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksSouthEast(int ix1, int ix2, int ix3, int level, vector<Block3DPtr>& blockVector, int levelDepth)
+{
+   int x1  = (ix1 << 1) + 1;
+   int x2  = ix2 << 1;
+   int x3B = (ix3 << 1);
+   int x3T = x3B+1;
+   int l   = level + 1;
+
+   Block3DPtr blockB = this->getBlock(x1, x2,x3B, l);
+   if(blockB) blockVector.push_back(blockB);
+   else if(l < levelDepth) this->getSubBlocksSouthEast(x1, x2, x3B, l, blockVector, levelDepth);
+
+   Block3DPtr blockT = this->getBlock(x1, x2,x3T, l);
+   if(blockT) blockVector.push_back(blockT);
+   else if(l < levelDepth) this->getSubBlocksSouthEast(x1, x2, x3T, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+//  diagonals
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksTopEast(int ix1, int ix2, int ix3, int level, vector<Block3DPtr>& blockVector, int levelDepth)
+{
+   int x1  = (ix1 << 1) + 1;
+   int x2S = (ix2 << 1);
+   int x2N = x2S + 1;
+   int x3  = (ix3 << 1)+1;
+   int l   = level + 1;
+
+   Block3DPtr blockN = this->getBlock(x1, x2N, x3, l);
+   if(blockN) blockVector.push_back(blockN);
+   else if(l < levelDepth) this->getSubBlocksTopEast(x1, x2N, x3, l, blockVector, levelDepth);
+
+   Block3DPtr blockS = this->getBlock(x1, x2S, x3, l);
+   if(blockS) blockVector.push_back(blockS);
+   else if(l < levelDepth) this->getSubBlocksTopEast(x1, x2S, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksTopWest(int ix1, int ix2, int ix3, int level, vector<Block3DPtr>& blockVector, int levelDepth)
+{
+   int x1  = ix1 << 1;
+   int x2S = ix2 << 1;
+   int x2N = x2S + 1;
+   int x3  = (ix3 << 1)+1;
+   int l   = level + 1;
+
+   Block3DPtr blockN = this->getBlock(x1, x2N, x3, l);
+   if(blockN) blockVector.push_back(blockN);
+   else if(l < levelDepth) this->getSubBlocksTopEast(x1, x2N, x3, l, blockVector, levelDepth);
+
+   Block3DPtr blockS = this->getBlock(x1, x2S, x3, l);
+   if(blockS) blockVector.push_back(blockS);
+   else if(l < levelDepth) this->getSubBlocksTopEast(x1, x2S, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksBottomEast(int ix1, int ix2, int ix3, int level, vector<Block3DPtr>& blockVector, int levelDepth)
+{
+   int x1  = (ix1 << 1) + 1;
+   int x2S = ix2 << 1;
+   int x2N = x2S + 1;
+   int x3  = ix3 << 1;
+   int l   = level + 1;
+
+   Block3DPtr blockN = this->getBlock(x1, x2N, x3, l);
+   if(blockN) blockVector.push_back(blockN);
+   else if(l < levelDepth) this->getSubBlocksTopEast(x1, x2N, x3, l, blockVector, levelDepth);
+
+   Block3DPtr blockS = this->getBlock(x1, x2S, x3, l);
+   if(blockS) blockVector.push_back(blockS);
+   else if(l < levelDepth) this->getSubBlocksTopEast(x1, x2S, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksBottomWest(int ix1, int ix2, int ix3, int level, vector<Block3DPtr>& blockVector, int levelDepth)
+{
+   int x1  = (ix1 << 1);
+   int x2S = (ix2 << 1);
+   int x2N = x2S + 1;
+   int x3  = ix3 << 1;
+   int l   = level + 1;
+
+   Block3DPtr blockN = this->getBlock(x1, x2N, x3, l);
+   if(blockN) blockVector.push_back(blockN);
+   else if(l < levelDepth) this->getSubBlocksTopEast(x1, x2N, x3, l, blockVector, levelDepth);
+
+   Block3DPtr blockS = this->getBlock(x1, x2S, x3, l);
+   if(blockS) blockVector.push_back(blockS);
+   else if(l < levelDepth) this->getSubBlocksTopEast(x1, x2S, x3, l, blockVector, levelDepth);
+}
+
+//////////////////////////////////////////////////////////////////////////
+//  edge-diagonals
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksTopNorth(int ix1, int ix2, int ix3, int level, vector<Block3DPtr>& blockVector, int levelDepth)
+{
+   int x1E = (ix1 << 1);
+   int x1W = x1E + 1;
+   int x2  = (ix2 << 1)+1;
+   int x3  = (ix3 << 1)+1;
+   int l   = level + 1;
+
+   Block3DPtr blockE = this->getBlock(x1E, x2, x3, l);
+   if(blockE) blockVector.push_back(blockE);
+   else if(l < levelDepth) this->getSubBlocksTopNorth(x1E, x2, x3, l, blockVector, levelDepth);
+
+   Block3DPtr blockW = this->getBlock(x1W, x2, x3, l);
+   if(blockW) blockVector.push_back(blockW);
+   else if(l < levelDepth) this->getSubBlocksTopNorth(x1W, x2, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksTopSouth(int ix1, int ix2, int ix3, int level, vector<Block3DPtr>& blockVector, int levelDepth)
+{
+   int x1E = (ix1 << 1);
+   int x1W = x1E + 1;
+   int x2  = (ix2 << 1);
+   int x3  = (ix3 << 1)+1;
+   int l   = level + 1;
+
+   Block3DPtr blockE = this->getBlock(x1E, x2, x3, l);
+   if(blockE) blockVector.push_back(blockE);
+   else if(l < levelDepth) this->getSubBlocksTopSouth(x1E, x2, x3, l, blockVector, levelDepth);
+
+   Block3DPtr blockW = this->getBlock(x1W, x2, x3, l);
+   if(blockW) blockVector.push_back(blockW);
+   else if(l < levelDepth) this->getSubBlocksTopSouth(x1W, x2, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksBottomNorth(int ix1, int ix2, int ix3, int level, vector<Block3DPtr>& blockVector, int levelDepth)
+{
+   int x1E = ix1 << 1;
+   int x1W = x1E + 1;
+   int x2  = (ix2 << 1)+1;
+   int x3  = ix3 << 1;
+   int l   = level + 1;
+
+   Block3DPtr blockE = this->getBlock(x1E, x2, x3, l);
+   if(blockE) blockVector.push_back(blockE);
+   else if(l < levelDepth) this->getSubBlocksBottomNorth(x1E, x2, x3, l, blockVector, levelDepth);
+
+   Block3DPtr blockW = this->getBlock(x1W, x2, x3, l);
+   if(blockW) blockVector.push_back(blockW);
+   else if(l < levelDepth) this->getSubBlocksBottomNorth(x1W, x2, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksBottomSouth(int ix1, int ix2, int ix3, int level, vector<Block3DPtr>& blockVector, int levelDepth)
+{
+   int x1E = (ix1 << 1);
+   int x1W = x1E + 1;
+   int x2  = ix2 << 1;
+   int x3  = ix3 << 1;
+   int l   = level + 1;
+
+   Block3DPtr blockE = this->getBlock(x1E, x2, x3, l);
+   if(blockE) blockVector.push_back(blockE);
+   else if(l < levelDepth) this->getSubBlocksBottomSouth(x1E, x2, x3, l, blockVector, levelDepth);
+
+   Block3DPtr blockW = this->getBlock(x1W, x2, x3, l);
+   if(blockW) blockVector.push_back(blockW);
+   else if(l < levelDepth) this->getSubBlocksBottomSouth(x1W, x2, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+//  space-diagonals
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksTopNorthEast(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth)
+{
+   int x1 = (ix1 << 1) + 1;
+   int x2 = (ix2 << 1) + 1;
+   int x3 = (ix3 << 1) + 1;
+   int l  = level + 1;
+
+   Block3DPtr blockTNE = this->getBlock(x1, x2, x3, l);
+   if(blockTNE) blockVector.push_back(blockTNE);
+   else if(l < levelDepth) this->getSubBlocksTopNorthEast(x1, x2, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksTopNorthWest(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth)
+{
+   int x1 = ix1 << 1;
+   int x2 = (ix2 << 1) + 1;
+   int x3 = (ix3 << 1) + 1;
+   int l  = level + 1;
+
+   Block3DPtr blockTNW = this->getBlock(x1, x2, x3, l);
+   if(blockTNW) blockVector.push_back(blockTNW);
+   else if(l < levelDepth) this->getSubBlocksTopNorthWest(x1, x2, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksTopSouthEast(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth)
+{
+   int x1 = (ix1 << 1) + 1;
+   int x2 =  ix2 << 1;
+   int x3 = (ix3 << 1) + 1;
+   int l  = level + 1;
+
+   Block3DPtr blockTNW = this->getBlock(x1, x2, x3, l);
+   if(blockTNW) blockVector.push_back(blockTNW);
+   else if(l < levelDepth) this->getSubBlocksTopSouthEast(x1, x2, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksTopSouthWest(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth)
+{
+   int x1 =  ix1 << 1;
+   int x2 =  ix2 << 1;
+   int x3 = (ix3 << 1) + 1;
+   int l  = level + 1;
+
+   Block3DPtr blockTSW = this->getBlock(x1, x2, x3, l);
+   if(blockTSW) blockVector.push_back(blockTSW);
+   else if(l < levelDepth) this->getSubBlocksTopSouthWest(x1, x2, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksBottomNorthEast(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth)
+{
+   int x1 = (ix1 << 1) + 1;
+   int x2 = (ix2 << 1) + 1;
+   int x3 =  ix3 << 1;
+   int l  = level + 1;
+
+   Block3DPtr blockBNE = this->getBlock(x1, x2, x3, l);
+   if(blockBNE) blockVector.push_back(blockBNE);
+   else if(l < levelDepth) this->getSubBlocksBottomNorthEast(x1, x2, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksBottomNorthWest(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth)
+{
+   int x1 =  ix1 << 1;
+   int x2 = (ix2 << 1) + 1;
+   int x3 =  ix3 << 1;
+   int l  = level + 1;
+
+   Block3DPtr blockBNW = this->getBlock(x1, x2, x3, l);
+   if(blockBNW) blockVector.push_back(blockBNW);
+   else if(l < levelDepth) this->getSubBlocksBottomNorthWest(x1, x2, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksBottomSouthEast(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth)
+{
+   int x1 = (ix1 << 1) + 1;
+   int x2 =  ix2 << 1;
+   int x3 =  ix3 << 1;
+   int l  = level + 1;
+
+   Block3DPtr blockBSE = this->getBlock(x1, x2, x3, l);
+   if(blockBSE) blockVector.push_back(blockBSE);
+   else if(l < levelDepth) this->getSubBlocksBottomSouthEast(x1, x2, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksBottomSouthWest(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth)
+{
+   int x1 = ix1 << 1;
+   int x2 = ix2 << 1;
+   int x3 = ix3 << 1;
+   int l  = level + 1;
+
+   Block3DPtr blockBSW = this->getBlock(x1, x2, x3, l);
+   if(blockBSW) blockVector.push_back(blockBSW);
+   else if(l < levelDepth) this->getSubBlocksBottomSouthWest(x1, x2, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getBlocks(int level, std::vector<Block3DPtr>& blockVector)
+{
+   for(Block3DMap::value_type b : levelSet[level])
+   {
+      blockVector.push_back(b.second);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getBlocks(int level, int rank, std::vector<Block3DPtr>& blockVector)
+{
+   for(Block3DMap::value_type b : levelSet[level])
+   {
+      Block3DPtr block = b.second;
+      int blockRank = block->getRank();
+      if (blockRank == rank)
+      {
+         blockVector.push_back(b.second);
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getBlocks(int level, int rank, bool active, std::vector<Block3DPtr>& blockVector)
+{
+   for(Block3DMap::value_type b : levelSet[level])
+   {
+      Block3DPtr block = b.second;
+      int blockRank = block->getRank();
+
+      if (blockRank == rank && active ? block->isActive() : block->isNotActive())
+      {
+         blockVector.push_back(b.second);
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+int Grid3D::getFinestInitializedLevel()
+{
+   for(int i=Grid3DSystem::MAXLEVEL; i>=0; i--) if(this->levelSet[i].size() > 0) return(i);
+   return(-1);
+}
+//////////////////////////////////////////////////////////////////////////
+int Grid3D::getCoarsestInitializedLevel()
+{
+   for(int i=0; i<=Grid3DSystem::MAXLEVEL; i++) if(this->levelSet[i].size() > 0) return(i);
+   return(-1);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setNX1(int nx1)  
+{ 
+   this->nx1 = nx1; 
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setNX2(int nx2)  
+{ 
+   this->nx2 = nx2; 
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setNX3(int nx3)  
+{ 
+   this->nx3 = nx3; 
+}
+//////////////////////////////////////////////////////////////////////////
+int Grid3D::getNX1() const 
+{ 
+   return this->nx1; 
+}
+//////////////////////////////////////////////////////////////////////////
+int Grid3D::getNX2() const 
+{ 
+   return this->nx2; 
+}
+//////////////////////////////////////////////////////////////////////////
+int Grid3D::getNX3() const 
+{
+   return this->nx3;
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::deleteBlocks( const std::vector<int>& ids )
+{
+   for(int i : ids)
+   {
+      Block3DPtr block = getBlock(i);
+      if(block) this->deleteBlock(block);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+int Grid3D::getNumberOfBlocks()
+{
+   int c = 0;
+   for(Block3DMap l : levelSet)
+   {
+      c += (int)l.size();
+   }
+   return c;
+}
+//////////////////////////////////////////////////////////////////////////
+int Grid3D::getNumberOfBlocks(int level)
+{
+   return (int)levelSet[level].size();
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getBlocksByCuboid( double minX1, double minX2, double minX3, double maxX1, double maxX2, double maxX3, std::vector<Block3DPtr>& blocks )
+{
+   int coarsestLevel = this->getCoarsestInitializedLevel();
+   int finestLevel   = this->getFinestInitializedLevel();
+
+   //////////////////////////////////////////////////////////////////////////
+   //MINIMALE BLOCK-INDIZES BESTIMMEN
+   //  
+   //min:
+   double dMinX1 = trafo->transformForwardToX1Coordinate( minX1,minX2,minX3 )*(1<<finestLevel);
+   double dMinX2 = trafo->transformForwardToX2Coordinate( minX1,minX2,minX3 )*(1<<finestLevel);
+   double dMinX3 = trafo->transformForwardToX3Coordinate( minX1,minX2,minX3 )*(1<<finestLevel);
+
+   //Achtung, wenn minX1 genau auf grenze zwischen zwei bloecken -> der "kleinere" muss genommen werden,
+   //da beim Transformieren der "groessere" Index rauskommt
+   int iMinX1 = (int)dMinX1; if( UbMath::zero(dMinX1-iMinX1) ) iMinX1-=1;   
+   int iMinX2 = (int)dMinX2; if( UbMath::zero(dMinX2-iMinX2) ) iMinX2-=1;
+   int iMinX3 = (int)dMinX3; if( UbMath::zero(dMinX3-iMinX3) ) iMinX3-=1;
+
+   //max (hier kann die Zusatzabfrage vernachlaessigt werden):
+   int iMaxX1 = (int)(trafo->transformForwardToX1Coordinate( maxX1,maxX2,maxX3 )*(1<<finestLevel));
+   int iMaxX2 = (int)(trafo->transformForwardToX2Coordinate( maxX1,maxX2,maxX3 )*(1<<finestLevel));
+   int iMaxX3 = (int)(trafo->transformForwardToX3Coordinate( maxX1,maxX2,maxX3 )*(1<<finestLevel));
+
+   Block3DPtr block;
+
+   //set, um doppelte bloecke zu vermeiden, die u.U. bei periodic auftreten koennen
+   std::set<Block3DPtr> blockset; 
+   for(int level=coarsestLevel; level<=finestLevel; level++)
+   {
+      //damit bei negativen werten auch der "kleinere" genommen wird -> floor!
+      int minx1 = (int)std::floor( (double)iMinX1/(1<<(finestLevel-level)) );
+      int minx2 = (int)std::floor( (double)iMinX2/(1<<(finestLevel-level)) );
+      int minx3 = (int)std::floor( (double)iMinX3/(1<<(finestLevel-level)) );
+
+      int maxx1 = iMaxX1/(1<<(finestLevel-level));
+      int maxx2 = iMaxX2/(1<<(finestLevel-level));
+      int maxx3 = iMaxX3/(1<<(finestLevel-level));
+
+      for(int ix1=minx1; ix1<=maxx1; ix1++)
+         for(int ix2=minx2; ix2<=maxx2; ix2++)
+            for(int ix3=minx3; ix3<=maxx3; ix3++)
+            if( (block=this->getBlock(ix1,ix2,ix3,level)) )
+            {
+               if (block->getRank() == rank)
+               {
+                  blockset.insert(block);
+               }
+            }
+   }
+
+   blocks.resize(blockset.size());
+   std::copy(blockset.begin(), blockset.end(), blocks.begin());
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getBlocksByCuboid( int level, double minX1, double minX2, double minX3, double maxX1, double maxX2, double maxX3, std::vector<Block3DPtr>& blocks )
+{
+   //////////////////////////////////////////////////////////////////////////
+   //MINIMALE BLOCK-INDIZES BESTIMMEN
+   //
+   //min:
+   double dMinX1 = trafo->transformForwardToX1Coordinate( minX1,minX2,minX3 )*(1<<level);
+   double dMinX2 = trafo->transformForwardToX2Coordinate( minX1,minX2,minX3 )*(1<<level);
+   double dMinX3 = trafo->transformForwardToX3Coordinate( minX1,minX2,minX3 )*(1<<level);
+
+   //Achtung, wenn minX1 genau auf grenze zwischen zwei bloecken -> der "kleinere" muss genommen werden:
+   int iMinX1 = (int)dMinX1; if( UbMath::zero(dMinX1-iMinX1) ) iMinX1-=1;
+   int iMinX2 = (int)dMinX2; if( UbMath::zero(dMinX2-iMinX2) ) iMinX2-=1;
+   int iMinX3 = (int)dMinX3; if( UbMath::zero(dMinX3-iMinX3) ) iMinX3-=1;
+
+   //max:
+   int iMaxX1 = (int)(trafo->transformForwardToX1Coordinate( maxX1,maxX2,maxX3 )*(1<<level));
+   int iMaxX2 = (int)(trafo->transformForwardToX2Coordinate( maxX1,maxX2,maxX3 )*(1<<level));
+   int iMaxX3 = (int)(trafo->transformForwardToX3Coordinate( maxX1,maxX2,maxX3 )*(1<<level));
+
+
+   //set, um doppelte bloecke zu vermeiden, die u.U. bei periodic auftreten koennen
+   std::set<Block3DPtr> blockset; 
+   Block3DPtr block;
+
+   for(int ix1=iMinX1; ix1<=iMaxX1; ix1++)
+      for(int ix2=iMinX2; ix2<=iMaxX2; ix2++)
+         for(int ix3=iMinX3; ix3<=iMaxX3; ix3++)
+            if( (block=this->getBlock(ix1,ix2,ix3,level)) )
+            {
+               if (block->getRank() == rank)
+               {
+                  blockset.insert(block);
+               }
+            }
+
+   blocks.resize(blockset.size());
+   std::copy(blockset.begin(), blockset.end(), blocks.begin());
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::calcStartCoordinatesAndDelta(Block3DPtr block, double& worldX1, double& worldX2, double& worldX3, double& deltaX)
+{
+   int blocklevel  = block->getLevel();
+   worldX1  = block->getX1()/(float)(1<<blocklevel);
+   worldX2  = block->getX2()/(float)(1<<blocklevel);
+   worldX3  = block->getX3()/(float)(1<<blocklevel);
+   deltaX   = (double)1.0/(double)(this->blockNx1*(double)(1<<blocklevel));
+
+   if(this->trafo)
+   {
+      double x1tmp = worldX1, x2tmp = worldX2, x3tmp = worldX3;
+      worldX1 = this->trafo->transformBackwardToX1Coordinate(x1tmp, x2tmp, x3tmp);
+      worldX2 = this->trafo->transformBackwardToX2Coordinate(x1tmp, x2tmp, x3tmp);
+      worldX3 = this->trafo->transformBackwardToX3Coordinate(x1tmp, x2tmp, x3tmp);
+      deltaX  = this->trafo->getX1CoordinateScaling()/(double)(this->blockNx1*(double)(1<<blocklevel));
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::calcStartCoordinatesWithOutOverlap(Block3DPtr block, double& worldX1, double& worldX2, double& worldX3)
+{
+   int blocklevel  = block->getLevel();
+   worldX1  = block->getX1()/(float)(1<<blocklevel);
+   worldX2  = block->getX2()/(float)(1<<blocklevel);
+   worldX3  = block->getX3()/(float)(1<<blocklevel);
+
+   if(this->trafo)
+   {
+      double x1tmp = worldX1, x2tmp = worldX2, x3tmp = worldX3;
+      worldX1 = this->trafo->transformBackwardToX1Coordinate(x1tmp, x2tmp, x3tmp);
+      worldX2 = this->trafo->transformBackwardToX2Coordinate(x1tmp, x2tmp, x3tmp);
+      worldX3 = this->trafo->transformBackwardToX3Coordinate(x1tmp, x2tmp, x3tmp);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setTimeStep( double step )
+{
+   timeStep = step;
+}
+//////////////////////////////////////////////////////////////////////////
+double Grid3D::getTimeStep() const
+{
+   return timeStep;
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::fillExtentWithBlocks( UbTupleInt3 minInd, UbTupleInt3 maxInd )
+{
+   for(int x3 =  val<3>(minInd); x3 <  val<3>(maxInd); x3++)
+   {
+      for(int x2 =  val<2>(minInd); x2 <  val<2>(maxInd); x2++)
+      {
+         for(int x1 =  val<1>(minInd); x1 <  val<1>(maxInd); x1++)
+         {
+            Block3DPtr block( new Block3D(x1,x2,x3,0) );
+            this->addBlock(block);
+         }
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+//void Grid3D::notifyObservers( double step )
+//{
+//   for(ObserverPtr o, observers)
+//   {
+//      o->update(step);
+//   }
+//
+//   //std::list<ObserverWeakPtr>::iterator iter = observers.begin();
+//
+//   //GridObserversSet::iterator iter = observers.begin();
+//   //while(iter != observers.end())
+//   //{
+//   //   if ((*iter).expired())
+//   //   {
+//   //      iter = observers.erase(iter);
+//   //   }
+//   //   else
+//   //   {
+//   //      ObserverPtr observer = (*iter).lock(); // create a shared_ptr from the weak_ptr
+//   //      observer->update(step);
+//   //      ++iter;
+//   //   }
+//   //}
+//
+//}
+//////////////////////////////////////////////////////////////////////////
+//void Grid3D::addObserver( ObserverPtr observer )
+//{
+//   observers.insert(observer);
+//   //observers.push_back(observer);
+//}
+////////////////////////////////////////////////////////////////////////////
+//void Grid3D::removeObserver( ObserverPtr observer )
+//{
+//   observers.erase(observer);
+//   //observers.remove(observer);
+//}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::deleteBlockIDs()
+{
+   this->blockIdMap.clear();
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::renumberBlockIDs()
+{
+    deleteBlockIDs();
+
+    int startLevel = getCoarsestInitializedLevel();
+    int stopLevel = getFinestInitializedLevel();
+    int counter = 0;
+
+    for (int l = startLevel; l <= stopLevel; l++)
+    {
+        std::vector<Block3DPtr> blockVector;
+        getBlocks(l, blockVector);
+        for(Block3DPtr block : blockVector)
+        {
+            block->setGlobalID(counter);
+            blockIdMap.insert(std::make_pair(counter, block));
+            Block3D::setMaxGlobalID(counter);
+            counter++;
+        }
+    }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::updateDistributedBlocks(CommunicatorPtr comm)
+{
+   
+   std::vector<int> blocks;
+   
+   if (comm->isRoot())
+   {
+      int startLevel = getCoarsestInitializedLevel();
+      int stopLevel = getFinestInitializedLevel();
+
+      for (int l = startLevel; l <= stopLevel; l++)
+      {
+         std::vector<Block3DPtr> blockVector;
+         getBlocks(l, blockVector);
+         for(Block3DPtr block : blockVector)
+         {
+            blocks.push_back(block->getX1());
+            blocks.push_back(block->getX2());
+            blocks.push_back(block->getX3());
+            blocks.push_back(l);
+            blocks.push_back(block->getGlobalID());
+         }
+      }
+   }
+   
+   comm->broadcast(blocks);
+
+   if (!comm->isRoot())
+   {
+      int startLevel = getCoarsestInitializedLevel();
+      int stopLevel = getFinestInitializedLevel();
+
+      blockIdMap.clear();
+
+      for (int l = startLevel; l<=stopLevel; l++)
+      {
+         levelSet[l].clear();
+      }
+      this->levelSet.clear();
+      levelSet.resize(Grid3DSystem::MAXLEVEL+1);
+
+      int rsize = (int)blocks.size();
+      for (int i = 0; i < rsize; i+=5)
+      {
+         Block3DPtr block(new Block3D(blocks[i], blocks[i+1], blocks[i+2], blocks[i+3]));
+         block->setGlobalID(blocks[i+4]);
+         this->addBlock(block);
+      }
+
+   }
+
+}
+
+//////////////////////////////////////////////////////////////////////////
diff --git a/source/VirtualFluidsCore/Grid/Grid3D.h b/source/VirtualFluidsCore/Grid/Grid3D.h
index 5662b51cb..658695cfa 100644
--- a/source/VirtualFluidsCore/Grid/Grid3D.h
+++ b/source/VirtualFluidsCore/Grid/Grid3D.h
@@ -1,282 +1,283 @@
-#ifndef GRID3D_H
-#define GRID3D_H
-
-#include <sstream>
-#include <iostream>
-#include <vector>
-#include <set>
-
-#include <boost/shared_ptr.hpp>
-#include <boost/enable_shared_from_this.hpp>
-#include <boost/signals2/signal.hpp>
-#include <boost/bind.hpp>
-#include <boost/serialization/shared_ptr.hpp>
-#include <boost/serialization/vector.hpp>
-#include <boost/serialization/map.hpp>
-
-#include "UbKeys.h"
-#include "CoordinateTransformation3D.h"
-
-#include <Communicator.h>
-//#include <Observer.h>
-//#include <FastSignal.hpp>
-
-class Grid3D;
-typedef boost::shared_ptr<Grid3D> Grid3DPtr;
-typedef boost::weak_ptr<Grid3D>   Grid3DWeakPtr;
-
-#include <Block3D.h>
-#include <Block3DVisitor.h>
-#include <Grid3DVisitor.h>
-#include <Interactor3D.h>
-
-//////////////////////////////////////////////////////////////////////////
-class Grid3D : public boost::enable_shared_from_this<Grid3D>
-{
-public:
-   typedef UbKeys::Key3<int>                  Block3DKey;
-   typedef std::map< Block3DKey, Block3DPtr > Block3DMap;
-   typedef std::map< int, Block3DPtr >    BlockIDMap;
-   typedef std::vector<Block3DMap>        LevelSet;
-   typedef std::vector<Interactor3DPtr>   Interactor3DSet;
-   //typedef std::set<ObserverPtr>     GridObserversSet;
-
-   typedef boost::signals2::signal<void (double)>  signal_t;
-   typedef boost::signals2::connection  connection_t;
-
-public:
-   Grid3D();
-   Grid3D(CommunicatorPtr comm);
-   Grid3D(CommunicatorPtr comm, int blockNx1, int blockNx2, int blockNx3, int gridNx1, int gridNx2, int gridNx3);
-   virtual ~Grid3D(){}
-   //////////////////////////////////////////////////////////////////////////
-   //blocks control
-   void addBlock(Block3DPtr block);
-   bool deleteBlock(Block3DPtr block);
-   bool deleteBlock(int ix1, int ix2, int ix3, int level);
-   void deleteBlocks(const std::vector<int>& ids);
-   void replaceBlock(Block3DPtr block);
-   Block3DPtr getBlock(int ix1, int ix2, int ix3, int level) const;
-   Block3DPtr getBlock(int id) const;
-   void getBlocksByCuboid(double minX1, double minX2, double minX3, 
-                          double maxX1, double maxX2, double maxX3, 
-                          std::vector<Block3DPtr>& blocks);
-   void getBlocksByCuboid(int level, double minX1, double minX2, double minX3, 
-                          double maxX1, double maxX2, double maxX3, 
-                          std::vector<Block3DPtr>& blocks);
-   //!get blocks for level
-   void getBlocks(int level, std::vector<Block3DPtr>& blockVector);
-   //!get blocks for level with current rank
-   void getBlocks(int level, int rank, std::vector<Block3DPtr>& blockVector);
-   //!get only active or not active blocks 
-   void getBlocks(int level, int rank, bool active, std::vector<Block3DPtr>& blockVector);
-   int getNumberOfBlocks();
-   int getNumberOfBlocks(int level);
-   //const Block3DMap& getBlocks(int level);
-   const BlockIDMap& getBlockIDs();
-   void deleteBlockIDs();
-   void renumberBlockIDs();
-   void updateDistributedBlocks(CommunicatorPtr comm);
-   Block3DPtr getSuperBlock(Block3DPtr block);
-   Block3DPtr getSuperBlock(int ix1, int ix2, int ix3, int level);
-   void getSubBlocks(Block3DPtr block, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getSubBlocks(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blockVector);
-   Block3DPtr getNeighborBlock(int dir, int ix1, int ix2, int ix3, int level) const;
-   Block3DPtr getNeighborBlock(int dir, Block3DPtr block) const;
-   bool expandBlock(int ix1, int ix2, int ix3, int level);
-   Block3DPtr collapseBlock(int fix1, int fix2, int fix3, int flevel, int levelDepth);
-   void getAllNeighbors(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getAllNeighbors(Block3DPtr block, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getNeighborBlocksForDirection(int dir, int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getNeighborBlocksForDirectionWithDirZero(int dir, int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-
-   void getNeighborsZero(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getNeighborsNorth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getNeighborsSouth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getNeighborsEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getNeighborsWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getNeighborsTop(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getNeighborsBottom(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-
-   void getNeighborsNorthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getNeighborsNorthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getNeighborsSouthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getNeighborsSouthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-
-   void getNeighborsTopNorth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getNeighborsTopSouth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getNeighborsTopEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getNeighborsTopWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-
-   void getNeighborsBottomNorth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getNeighborsBottomSouth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getNeighborsBottomEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getNeighborsBottomWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-
-   void getNeighborsTopNorthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getNeighborsTopNorthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getNeighborsTopSouthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getNeighborsTopSouthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getNeighborsBottomNorthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getNeighborsBottomNorthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getNeighborsBottomSouthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   void getNeighborsBottomSouthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<Block3DPtr>& blocks);
-   //////////////////////////////////////////////////////////////////////////
-   //level control
-   int getFinestInitializedLevel();
-   int getCoarsestInitializedLevel();
-   //////////////////////////////////////////////////////////////////////////
-   void deleteConnectors();
-   //////////////////////////////////////////////////////////////////////////
-   //interactors control
-   void addInteractor(Interactor3DPtr interactor);
-   void addAndInitInteractor(Interactor3DPtr interactor, double timestep=0);
-   Interactor3DSet getInteractors();
-   //////////////////////////////////////////////////////////////////////////
-   //visitors
-   void accept(Block3DVisitor& blockVisitor);
-   void accept(Grid3DVisitor& gridVisitor);
-   void accept(Grid3DVisitorPtr gridVisitor);
-   //////////////////////////////////////////////////////////////////////////
-   //post processing
-   connection_t connect(signal_t::slot_function_type subscriber);
-   void disconnect(connection_t subscriber);
-   void coProcess(double step);
-   //////////////////////////////////////////////////////////////////////////
-   //bundle and rank for distributed memory
-   void setBundle(int bundle);
-   int  getBundle() const;
-   int  getRank() const;
-   void setRank(int rank);
-   //////////////////////////////////////////////////////////////////////////
-   //periodic boundary
-   bool isPeriodicX1() const;
-   bool isPeriodicX2() const;
-   bool isPeriodicX3() const;
-   void setPeriodicX1(bool value);
-   void setPeriodicX2(bool value);
-   void setPeriodicX3(bool value);
-   //////////////////////////////////////////////////////////////////////////
-   //Topology
-   UbTupleInt3 getBlockIndexes(double blockX1Coord, double blockX2Coord, double blockX3Coord)  const;
-   UbTupleInt3 getBlockIndexes(double blockX1Coord, double blockX2Coord, double blockX3Coord, int level)  const;
-   UbTupleDouble3 getBlockLengths(Block3DPtr block) const;
-   UbTupleDouble6 getBlockOversize() const ;
-   void setCoordinateTransformator(CoordinateTransformation3DPtr trafo);
-   const CoordinateTransformation3DPtr getCoordinateTransformator() const ;
-   void setDeltaX(double dx);
-   void setDeltaX(double worldUnit, double gridUnit);
-   double getDeltaX(int level) const;
-   double getDeltaX(Block3DPtr block) const;
-   UbTupleDouble3 getNodeOffset(Block3DPtr block) const ;
-   UbTupleDouble3 getNodeCoordinates(Block3DPtr block, int ix1, int ix2, int ix3) const;
-   UbTupleInt3 getNodeIndexes(Block3DPtr block, double nodeX1Coord, double nodeX2Coord, double nodeX3Coord) const;
-   void setBlockNX(int nx1, int nx2, int nx3);
-   UbTupleInt3 getBlockNX() const;
-   UbTupleDouble3 getBlockWorldCoordinates(Block3DPtr block) const;
-   UbTupleDouble3 getBlockWorldCoordinates(int blockX1Index, int blockX2Index, int blockX3Index, int level) const;
-   void setNX1(int nx1);
-   void setNX2(int nx2);
-   void setNX3(int nx3);
-   int  getNX1() const;
-   int  getNX2() const;
-   int  getNX3() const;
-   void calcStartCoordinatesAndDelta(Block3DPtr block, double& worldX1, double& worldX2, double& worldX3, double& deltaX);
-   void calcStartCoordinatesWithOutOverlap(Block3DPtr block, double& worldX1, double& worldX2, double& worldX3);
-   //////////////////////////////////////////////////////////////////////////
-   //LBM
-   //double getDeltaT(Block3DPtr) const;
-   //////////////////////////////////////////////////////////////////////////
-   void setTimeStep(double step);
-   double getTimeStep() const;
-protected:
-   void checkLevel(int level);
-   bool hasLevel(int level) const;
-
-   void fillExtentWithBlocks( UbTupleInt3 minInd, UbTupleInt3 maxInd );
-
-   void getSubBlocksZero(int ix1, int ix2, int ix3, int level,std::vector<Block3DPtr>& blockVector, int levelDepth);
-
-   void getSubBlocksEast(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-   void getSubBlocksWest(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-   void getSubBlocksNorth(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-   void getSubBlocksSouth(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-   void getSubBlocksTop(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-   void getSubBlocksBottom(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-
-   void getSubBlocksSouthEast(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-   void getSubBlocksSouthWest(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-   void getSubBlocksNorthEast(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-   void getSubBlocksNorthWest(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-
-   void getSubBlocksTopEast(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-   void getSubBlocksTopWest(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-   void getSubBlocksTopNorth(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-   void getSubBlocksTopSouth(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-
-   void getSubBlocksBottomEast(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-   void getSubBlocksBottomWest(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-   void getSubBlocksBottomNorth(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-   void getSubBlocksBottomSouth(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-
-   void getSubBlocksTopNorthEast(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-   void getSubBlocksTopNorthWest(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-   void getSubBlocksTopSouthEast(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-   void getSubBlocksTopSouthWest(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-   void getSubBlocksBottomNorthEast(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-   void getSubBlocksBottomNorthWest(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-   void getSubBlocksBottomSouthEast(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-   void getSubBlocksBottomSouthWest(int ix1, int ix2, int ix3, int level, std::vector<Block3DPtr>& blockVector, int levelDepth);
-
-private:
-   LevelSet levelSet;
-   BlockIDMap blockIdMap;
-   Interactor3DSet interactors;
-   //GridObserversSet observers;
-
-   signal_t sig;
-   int rank;
-   int bundle;
-   
-   bool periodicX1;
-   bool periodicX2;
-   bool periodicX3;
-
-   int blockNx1;    
-   int blockNx2;    
-   int blockNx3; 
-
-   int nx1;    
-   int nx2;    
-   int nx3;    
-
-   CoordinateTransformation3DPtr trafo;
-   double orgDeltaX;
-
-   double timeStep;
-   
-   friend class boost::serialization::access;
-   template<class Archive>
-   void serialize(Archive & ar, const unsigned int version)
-   {
-      ar & nx1;
-      ar & nx2;
-      ar & nx3;
-      ar & orgDeltaX;
-      ar & trafo;
-      ar & blockNx1;
-      ar & blockNx2;
-      ar & blockNx3;
-      ar & rank;
-      ar & bundle;
-      ar & periodicX1;
-      ar & periodicX2;
-      ar & periodicX3;
-      ar & levelSet;
-      ar & blockIdMap;
-      ar & timeStep;
-      ar & interactors;
-   }
-};
-
-#endif 
+#ifndef GRID3D_H
+#define GRID3D_H
+
+
+#include <vector>
+#include <map>
+#include <memory>
+
+#include <boost/signals2/signal.hpp>
+#include <boost/serialization/vector.hpp>
+
+#include <basics/utilities/Vector3D.h>
+#include <basics/utilities/UbTuple.h>
+#include <basics/utilities/UbKeys.h>
+
+class CoordinateTransformation3D;
+
+
+class Grid3D;
+typedef std::shared_ptr<Grid3D> Grid3DPtr;
+typedef std::weak_ptr<Grid3D>   Grid3DWeakPtr;
+
+#include <Block3DVisitor.h>
+#include <Grid3DVisitor.h>
+
+class Communicator;
+class Block3D;
+class Interactor3D;
+//class Grid3DVisitor;
+
+#define OFFSET 0.5
+
+//////////////////////////////////////////////////////////////////////////
+class Grid3D : public std::enable_shared_from_this<Grid3D>
+{
+public:
+   typedef UbKeys::Key3<int>                  Block3DKey;
+   typedef std::map< Block3DKey, std::shared_ptr<Block3D> > Block3DMap;
+   typedef std::map< int, std::shared_ptr<Block3D> >    BlockIDMap;
+   typedef std::vector<Block3DMap>        LevelSet;
+   typedef std::vector<std::shared_ptr<Interactor3D> >   Interactor3DSet;
+   //typedef std::set<ObserverPtr>     GridObserversSet;
+
+   typedef boost::signals2::signal<void (double)>  signal_t;
+   typedef boost::signals2::connection  connection_t;
+
+public:
+   Grid3D();
+   Grid3D(std::shared_ptr<Communicator> comm);
+   Grid3D(std::shared_ptr<Communicator> comm, int blockNx1, int blockNx2, int blockNx3, int gridNx1, int gridNx2, int gridNx3);
+   virtual ~Grid3D(){}
+   //////////////////////////////////////////////////////////////////////////
+   //blocks control
+   void addBlock(std::shared_ptr<Block3D> block);
+   bool deleteBlock(std::shared_ptr<Block3D> block);
+   bool deleteBlock(int ix1, int ix2, int ix3, int level);
+   void deleteBlocks(const std::vector<int>& ids);
+   void replaceBlock(std::shared_ptr<Block3D> block);
+   std::shared_ptr<Block3D> getBlock(int ix1, int ix2, int ix3, int level) const;
+   std::shared_ptr<Block3D> getBlock(int id) const;
+   void getBlocksByCuboid(double minX1, double minX2, double minX3, 
+                          double maxX1, double maxX2, double maxX3, 
+                          std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getBlocksByCuboid(int level, double minX1, double minX2, double minX3, 
+                          double maxX1, double maxX2, double maxX3, 
+                          std::vector<std::shared_ptr<Block3D>>& blocks);
+   //!get blocks for level
+   void getBlocks(int level, std::vector<std::shared_ptr<Block3D>>& blockVector);
+   //!get blocks for level with current rank
+   void getBlocks(int level, int rank, std::vector<std::shared_ptr<Block3D>>& blockVector);
+   //!get only active or not active blocks 
+   void getBlocks(int level, int rank, bool active, std::vector<std::shared_ptr<Block3D>>& blockVector);
+   int getNumberOfBlocks();
+   int getNumberOfBlocks(int level);
+   //const Block3DMap& getBlocks(int level);
+   const BlockIDMap& getBlockIDs();
+   void deleteBlockIDs();
+   void renumberBlockIDs();
+   void updateDistributedBlocks(std::shared_ptr<Communicator> comm);
+   std::shared_ptr<Block3D> getSuperBlock(std::shared_ptr<Block3D> block);
+   std::shared_ptr<Block3D> getSuperBlock(int ix1, int ix2, int ix3, int level);
+   void getSubBlocks(std::shared_ptr<Block3D> block, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getSubBlocks(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blockVector);
+   std::shared_ptr<Block3D> getNeighborBlock(int dir, int ix1, int ix2, int ix3, int level) const;
+   std::shared_ptr<Block3D> getNeighborBlock(int dir, std::shared_ptr<Block3D> block) const;
+   bool expandBlock(int ix1, int ix2, int ix3, int level);
+   std::shared_ptr<Block3D> collapseBlock(int fix1, int fix2, int fix3, int flevel, int levelDepth);
+   void getAllNeighbors(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getAllNeighbors(std::shared_ptr<Block3D> block, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getNeighborBlocksForDirection(int dir, int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getNeighborBlocksForDirectionWithDirZero(int dir, int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+
+   void getNeighborsZero(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getNeighborsNorth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getNeighborsSouth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getNeighborsEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getNeighborsWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getNeighborsTop(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getNeighborsBottom(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+
+   void getNeighborsNorthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getNeighborsNorthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getNeighborsSouthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getNeighborsSouthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+
+   void getNeighborsTopNorth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getNeighborsTopSouth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getNeighborsTopEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getNeighborsTopWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+
+   void getNeighborsBottomNorth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getNeighborsBottomSouth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getNeighborsBottomEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getNeighborsBottomWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+
+   void getNeighborsTopNorthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getNeighborsTopNorthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getNeighborsTopSouthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getNeighborsTopSouthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getNeighborsBottomNorthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getNeighborsBottomNorthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getNeighborsBottomSouthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   void getNeighborsBottomSouthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<std::shared_ptr<Block3D>>& blocks);
+   //////////////////////////////////////////////////////////////////////////
+   //level control
+   int getFinestInitializedLevel();
+   int getCoarsestInitializedLevel();
+   //////////////////////////////////////////////////////////////////////////
+   void deleteConnectors();
+   //////////////////////////////////////////////////////////////////////////
+   //interactors control
+   void addInteractor(std::shared_ptr<Interactor3D> interactor);
+   void addAndInitInteractor(std::shared_ptr<Interactor3D> interactor, double timestep=0);
+   Interactor3DSet getInteractors();
+   //////////////////////////////////////////////////////////////////////////
+   //visitors
+   void accept(Block3DVisitor& blockVisitor);
+   void accept(Grid3DVisitor& gridVisitor);
+   void accept(std::shared_ptr<Grid3DVisitor> gridVisitor);
+   //////////////////////////////////////////////////////////////////////////
+   //post processing
+   connection_t connect(signal_t::slot_function_type subscriber);
+   void disconnect(connection_t subscriber);
+   void coProcess(double step);
+   //////////////////////////////////////////////////////////////////////////
+   //bundle and rank for distributed memory
+   void setBundle(int bundle);
+   int  getBundle() const;
+   int  getRank() const;
+   void setRank(int rank);
+   //////////////////////////////////////////////////////////////////////////
+   //periodic boundary
+   bool isPeriodicX1() const;
+   bool isPeriodicX2() const;
+   bool isPeriodicX3() const;
+   void setPeriodicX1(bool value);
+   void setPeriodicX2(bool value);
+   void setPeriodicX3(bool value);
+   //////////////////////////////////////////////////////////////////////////
+   //Topology
+   UbTupleInt3 getBlockIndexes(double blockX1Coord, double blockX2Coord, double blockX3Coord)  const;
+   UbTupleInt3 getBlockIndexes(double blockX1Coord, double blockX2Coord, double blockX3Coord, int level)  const;
+   UbTupleDouble3 getBlockLengths(std::shared_ptr<Block3D> block) const;
+   UbTupleDouble6 getBlockOversize() const ;
+   void setCoordinateTransformator(std::shared_ptr<CoordinateTransformation3D>  trafo);
+   const std::shared_ptr<CoordinateTransformation3D>  getCoordinateTransformator() const ;
+   void setDeltaX(double dx);
+   void setDeltaX(double worldUnit, double gridUnit);
+   double getDeltaX(int level) const;
+   double getDeltaX(std::shared_ptr<Block3D> block) const;
+   UbTupleDouble3 getNodeOffset(std::shared_ptr<Block3D> block) const ;
+    Vector3D getNodeCoordinates(std::shared_ptr<Block3D> block, int ix1, int ix2, int ix3) const;
+   UbTupleInt3 getNodeIndexes(std::shared_ptr<Block3D> block, double nodeX1Coord, double nodeX2Coord, double nodeX3Coord) const;
+   void setBlockNX(int nx1, int nx2, int nx3);
+   UbTupleInt3 getBlockNX() const;
+   UbTupleDouble3 getBlockWorldCoordinates(std::shared_ptr<Block3D> block) const;
+   UbTupleDouble3 getBlockWorldCoordinates(int blockX1Index, int blockX2Index, int blockX3Index, int level) const;
+   void setNX1(int nx1);
+   void setNX2(int nx2);
+   void setNX3(int nx3);
+   int  getNX1() const;
+   int  getNX2() const;
+   int  getNX3() const;
+   void calcStartCoordinatesAndDelta(std::shared_ptr<Block3D> block, double& worldX1, double& worldX2, double& worldX3, double& deltaX);
+   void calcStartCoordinatesWithOutOverlap(std::shared_ptr<Block3D> block, double& worldX1, double& worldX2, double& worldX3);
+   //////////////////////////////////////////////////////////////////////////
+   //LBM
+   //double getDeltaT(std::shared_ptr<Block3D>) const;
+   //////////////////////////////////////////////////////////////////////////
+   void setTimeStep(double step);
+   double getTimeStep() const;
+
+protected:
+   void checkLevel(int level);
+   bool hasLevel(int level) const;
+
+   void fillExtentWithBlocks( UbTupleInt3 minInd, UbTupleInt3 maxInd );
+
+   void getSubBlocksZero(int ix1, int ix2, int ix3, int level,std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+
+   void getSubBlocksEast(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksWest(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksNorth(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksSouth(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksTop(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksBottom(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+
+   void getSubBlocksSouthEast(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksSouthWest(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksNorthEast(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksNorthWest(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+
+   void getSubBlocksTopEast(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksTopWest(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksTopNorth(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksTopSouth(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+
+   void getSubBlocksBottomEast(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksBottomWest(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksBottomNorth(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksBottomSouth(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+
+   void getSubBlocksTopNorthEast(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksTopNorthWest(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksTopSouthEast(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksTopSouthWest(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksBottomNorthEast(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksBottomNorthWest(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksBottomSouthEast(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksBottomSouthWest(int ix1, int ix2, int ix3, int level, std::vector<std::shared_ptr<Block3D>>& blockVector, int levelDepth);
+
+private:
+   LevelSet levelSet;
+   BlockIDMap blockIdMap;
+   Interactor3DSet interactors;
+   //GridObserversSet observers;
+
+   signal_t sig;
+   int rank;
+   int bundle;
+   
+   bool periodicX1;
+   bool periodicX2;
+   bool periodicX3;
+
+   int blockNx1;    
+   int blockNx2;    
+   int blockNx3; 
+
+   int nx1;    
+   int nx2;    
+   int nx3;    
+
+   std::shared_ptr<CoordinateTransformation3D> trafo;
+   double orgDeltaX;
+
+   double timeStep;
+   
+   friend class boost::serialization::access;
+   template<class Archive>
+   void serialize(Archive & ar, const unsigned int version)
+   {
+      ar & nx1;
+      ar & nx2;
+      ar & nx3;
+      ar & orgDeltaX;
+      ar & trafo;
+      ar & blockNx1;
+      ar & blockNx2;
+      ar & blockNx3;
+      ar & rank;
+      ar & bundle;
+      ar & periodicX1;
+      ar & periodicX2;
+      ar & periodicX3;
+      ar & levelSet;
+      ar & blockIdMap;
+      ar & timeStep;
+      ar & interactors;
+   }
+};
+
+#endif 
diff --git a/source/VirtualFluidsCore/Grid/MPICalculator.cpp b/source/VirtualFluidsCore/Grid/MPICalculator.cpp
index a8d920028..06efb714a 100644
--- a/source/VirtualFluidsCore/Grid/MPICalculator.cpp
+++ b/source/VirtualFluidsCore/Grid/MPICalculator.cpp
@@ -1,368 +1,372 @@
-#include "MPICalculator.h"
-#include <basics/utilities/UbException.h>
-#include <boost/foreach.hpp>
-#include "MathUtil.hpp"
-#include "basics/writer/WbWriterVtkXmlASCII.h"
-
-//#define TIMING
-//#define PRECOLLISIONBC
-
-MPICalculator::MPICalculator()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-MPICalculator::MPICalculator(Grid3DPtr grid) :
-Calculator(grid, SynchronizerPtr(), true)
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-void MPICalculator::calculate(const double& endTime, CalculationManagerPtr cm)
-{
-   UBLOG(logDEBUG1, "MPICalculator::calculate() - started");
-   try
-   {
-      initConnectors();
-
-      int anzLevel = maxLevel-minLevel+1;
-
-      int minInitLevel = minLevel;
-      int maxInitLevel = maxLevel-minLevel;
-      int straightStartLevel = minInitLevel;
-      int internalIterations = 1<<(maxInitLevel-minInitLevel);
-      int forwardStartLevel;
-      int threshold;
-      int startStep = int(grid->getTimeStep())+1;
-
-      //UBLOG(logINFO, "startStep="<<startStep);
-      int anzCalcSteps = static_cast<int>(endTime);
-#ifdef TIMING
-      UbTimer timer;
-      double time[6];
-#endif
-
-      //////////////////////////////////////////////////////////////////////////
-      //      UBLOG(logINFO, "Number of connectors = " <<this->localConns[0].size());
-      //////////////////////////////////////////////////////////////////////////
-
-      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
-         //write dump 
-         grid->coProcess((double)(calcStep-1));
-
-         //////////////////////////////////////////////////////////////////////////
-#ifdef TIMING
-         UBLOG(logINFO, "calcStep = "<<calcStep);
-#endif
-         //////////////////////////////////////////////////////////////////////////
-
-         for (int staggeredStep = 1; staggeredStep<=internalIterations; staggeredStep++)
-         {
-            forwardStartLevel = straightStartLevel;
-            if (staggeredStep==internalIterations) straightStartLevel = minInitLevel;
-            else
-            {
-               for (straightStartLevel = maxInitLevel, threshold = 1;
-                  (staggeredStep&threshold)!=threshold; straightStartLevel--, threshold <<= 1);
-            }
-            //////////////////////////////////////////////////////////////////////////
-#ifdef TIMING
-            timer.resetAndStart();
-#endif
-            //////////////////////////////////////////////////////////////////////////
-            applyPreCollisionBC(straightStartLevel, maxInitLevel);
-
-            calculateBlocks(straightStartLevel, maxInitLevel);
-            ////calculateBlocks(minInitLevel, maxInitLevel, staggeredStep);
-//////////////////////////////////////////////////////////////////////////
-#ifdef TIMING
-            time[0] = timer.stop();
-            UBLOG(logINFO, "calculateBlocks time = "<<time[0]);
-#endif
-            //////////////////////////////////////////////////////////////////////////
-
-                        //exchange data between blocks
-                        //Sleep(10000);
-            exchangeBlockData(straightStartLevel, maxInitLevel);
-            //////////////////////////////////////////////////////////////////////////
-#ifdef TIMING
-            time[1] = timer.stop();
-            UBLOG(logINFO, "exchangeBlockData time = "<<time[1]);
-#endif
-            //////////////////////////////////////////////////////////////////////////
-                        //applyBCs(straightStartLevel, maxInitLevel);
-            applyPostCollisionBC(straightStartLevel, maxInitLevel);
-
-            //////////////////////////////////////////////////////////////////////////
-#ifdef TIMING
-            time[2] = timer.stop();
-            UBLOG(logINFO, "applyBCs time = "<<time[2]);
-#endif
-            //////////////////////////////////////////////////////////////////////////
-
-                        //swap distributions in kernel
-            swapDistributions(straightStartLevel, maxInitLevel);
-
-#ifdef PRECOLLISIONBC
-            exchangeBlockData(straightStartLevel, maxInitLevel);
-            applyPreCollisionBC(straightStartLevel, maxInitLevel);
-#endif
-
-
-            //////////////////////////////////////////////////////////////////////////
-#ifdef TIMING
-            time[3] = timer.stop();
-            UBLOG(logINFO, "swapDistributions time = "<<time[3]);
-#endif
-            //////////////////////////////////////////////////////////////////////////
-
-            if (refinement)
-            {
-               //      //exchange data between blocks for grid refinement
-                     ////exchangeInterfaceBlockData(straightStartLevel, maxInitLevel, true);
-               //DOES NOT NEED 
-               if (straightStartLevel<maxInitLevel)
-                  exchangeBlockData(straightStartLevel, maxInitLevel);
-               //         //exchangeInterfaceBlockData(straightStartLevel, maxInitLevel, true);
-      //////////////////////////////////////////////////////////////////////////
-#ifdef TIMING
-               time[4] = timer.stop();
-               UBLOG(logINFO, "refinement exchangeBlockData time = "<<time[4]);
-#endif
-               //////////////////////////////////////////////////////////////////////////
-                              //now ghost nodes have actual values
-                              //interpolation of interface nodes between grid levels
-               interpolation(straightStartLevel, maxInitLevel);
-               //////////////////////////////////////////////////////////////////////////
-#ifdef TIMING
-               time[5] = timer.stop();
-               UBLOG(logINFO, "refinement interpolation time = "<<time[5]);
-#endif
-               //////////////////////////////////////////////////////////////////////////
-            }
-
-            if (taValuesCoProcessor)
-            {
-               taValuesCoProcessor->calculateSubtotal(calcStep-1);
-            }
-
-
-         }
-         //exchange data between blocks for visualization
-         if (mainThread) visScheduler->isDue((double)(calcStep-1));
-         if ((int)visScheduler->getNextDueTime()==calcStep)
-         {
-            exchangeBlockData(straightStartLevel, maxInitLevel);
-         }
-         //now ghost nodes have actual values
-
-         //dynamic load balancing
-         //sync->wait();
-         //if (mainThread && !loadBalancingComp)
-         //{
-         //   loadBalancingComp = cm->balance();
-         //}
-
-      }
-      UBLOG(logDEBUG1, "MPICalculator::calculate() - stoped");
-   }
-   catch (std::exception& e)
-   {
-      //error = boost::current_exception();
-      UBLOG(logERROR, e.what());
-      UBLOG(logERROR, " step = "<<calcStep);
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void MPICalculator::calculateBlocks(int startLevel, int maxInitLevel)
-{
-   Block3DPtr blockTemp;
-   try
-   {
-      //startLevel bis maxInitLevel
-      for (int level = startLevel; level<=maxInitLevel; level++)
-      {
-         //timer.resetAndStart();
-         //call LBM kernel
-         BOOST_FOREACH(Block3DPtr block, blocks[level])
-         {
-            blockTemp = block;
-            block->getKernel()->calculate();
-         }
-         //timer.stop();
-         //UBLOG(logINFO, "level = " << level << " blocks = " << blocks[level].size() << " collision time = " << timer.getTotalTime());
-      }
-   }
-   catch (std::exception& e)
-   {
-      //error = boost::current_exception();
-      UBLOG(logERROR, e.what());
-      UBLOG(logERROR, blockTemp->toString()<<" step = "<<calcStep);
-      exit(EXIT_FAILURE);
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void MPICalculator::calculateBlocks(int minInitLevel, int maxInitLevel, int staggeredStep)
-{
-   int p, maxi, maxir, maxidp, start, end;
-   for (int level = minInitLevel; level<=maxInitLevel; level++)
-   {
-      p = 1<<(maxInitLevel-level);
-      maxi = maxir = static_cast<int>(blocks[level].size());
-      maxidp = maxi/p;
-      if (p>maxi && maxi!=0) {
-         maxidp = 1;
-         maxi = p;
-      }
-      start = (staggeredStep-1)*maxidp;
-      if (start>=maxi)
-         start = 0;
-      end = start+maxidp;
-      if ((end+p)>=maxi)
-         end = maxi;
-      for (int i = start; i<end; i++)
-      {
-         if (i<maxir)
-            blocks[level][i]->getKernel()->calculate();
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////////////////
-void MPICalculator::exchangeBlockData(int startLevel, int maxInitLevel)
-{
-   //startLevel bis maxInitLevel
-   for (int level = startLevel; level<=maxInitLevel; level++)
-   {
-      connectorsPrepare(localConns[level]);
-      connectorsPrepare(remoteConns[level]);
-
-      connectorsSend(localConns[level]);
-      connectorsSend(remoteConns[level]);
-
-      connectorsReceive(localConns[level]);
-      connectorsReceive(remoteConns[level]);
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void MPICalculator::exchangeInterfaceBlockData(int startLevel, int maxInitLevel)
-{
-   //startLevel bis maxInitLevel
-   for (int level = startLevel; level<=maxInitLevel; level++)
-   {
-      connectorsPrepare(localInterfaceBlockConns[level]);
-      connectorsPrepare(remoteInterfaceBlockConns[level]);
-
-      connectorsSend(localInterfaceBlockConns[level]);
-      connectorsSend(remoteInterfaceBlockConns[level]);
-
-      connectorsReceive(localInterfaceBlockConns[level]);
-      connectorsReceive(remoteInterfaceBlockConns[level]);
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void MPICalculator::swapDistributions(int startLevel, int maxInitLevel)
-{
-   //startLevel bis maxInitLevel
-   for (int level = startLevel; level<=maxInitLevel; level++)
-   {
-      BOOST_FOREACH(Block3DPtr block, blocks[level])
-      {
-         block->getKernel()->swapDistributions();
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void MPICalculator::connectorsPrepare(std::vector< Block3DConnectorPtr >& connectors)
-{
-   BOOST_FOREACH(Block3DConnectorPtr c, connectors)
-   {
-      c->prepareForReceive();
-      c->prepareForSend();
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void MPICalculator::connectorsSend(std::vector< Block3DConnectorPtr >& connectors)
-{
-   BOOST_FOREACH(Block3DConnectorPtr c, connectors)
-   {
-      c->fillSendVectors();
-      c->sendVectors();
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void MPICalculator::connectorsReceive(std::vector< Block3DConnectorPtr >& connectors)
-{
-   BOOST_FOREACH(Block3DConnectorPtr c, connectors)
-   {
-      c->receiveVectors();
-      c->distributeReceiveVectors();
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void MPICalculator::interpolation(int startLevel, int maxInitLevel)
-{
-
-
-   for (int level = startLevel; level<maxInitLevel; level++)
-   {
-      connectorsPrepare(localInterConns[level]);
-      connectorsPrepare(remoteInterConns[level]);
-   }
-
-
-
-   for (int level = startLevel; level<maxInitLevel; level++)
-   {
-      connectorsSend(localInterConns[level]);
-      connectorsSend(remoteInterConns[level]);
-   }
-
-
-
-   for (int level = startLevel; level<maxInitLevel; level++)
-   {
-      connectorsReceive(localInterConns[level]);
-      connectorsReceive(remoteInterConns[level]);
-   }
-
-
-
-}
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-void MPICalculator::applyPreCollisionBC(int startLevel, int maxInitLevel)
-{
-   //startLevel bis maxInitLevel
-   for (int level = startLevel; level<=maxInitLevel; level++)
-   {
-      BOOST_FOREACH(Block3DPtr block, blocks[level])
-      {
-         block->getKernel()->getBCProcessor()->applyPreCollisionBC();
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void MPICalculator::applyPostCollisionBC(int startLevel, int maxInitLevel)
-{
-   //startLevel bis maxInitLevel
-   for (int level = startLevel; level<=maxInitLevel; level++)
-   {
-      BOOST_FOREACH(Block3DPtr block, blocks[level])
-      {
-         block->getKernel()->getBCProcessor()->applyPostCollisionBC();
-      }
-   }
-}
-
+#include "MPICalculator.h"
+#include <basics/utilities/UbException.h>
+
+#include "MathUtil.hpp"
+#include "basics/writer/WbWriterVtkXmlASCII.h"
+
+#include "BCProcessor.h"
+#include "LBMKernel.h"
+//#define TIMING
+//#define PRECOLLISIONBC
+
+#include "Block3DConnector.h"
+
+MPICalculator::MPICalculator()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+MPICalculator::MPICalculator(Grid3DPtr grid) :
+Calculator(grid, SynchronizerPtr(), true)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void MPICalculator::calculate(const double& endTime, CalculationManagerPtr cm)
+{
+   UBLOG(logDEBUG1, "MPICalculator::calculate() - started");
+   try
+   {
+      initConnectors();
+
+      int anzLevel = maxLevel-minLevel+1;
+
+      int minInitLevel = minLevel;
+      int maxInitLevel = maxLevel-minLevel;
+      int straightStartLevel = minInitLevel;
+      int internalIterations = 1<<(maxInitLevel-minInitLevel);
+      int forwardStartLevel;
+      int threshold;
+      int startStep = int(grid->getTimeStep())+1;
+
+      //UBLOG(logINFO, "startStep="<<startStep);
+      int anzCalcSteps = static_cast<int>(endTime);
+#ifdef TIMING
+      UbTimer timer;
+      double time[6];
+#endif
+
+      //////////////////////////////////////////////////////////////////////////
+      //      UBLOG(logINFO, "Number of connectors = " <<this->localConns[0].size());
+      //////////////////////////////////////////////////////////////////////////
+
+      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
+         //write dump 
+         grid->coProcess((double)(calcStep-1));
+
+         //////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+         UBLOG(logINFO, "calcStep = "<<calcStep);
+#endif
+         //////////////////////////////////////////////////////////////////////////
+
+         for (int staggeredStep = 1; staggeredStep<=internalIterations; staggeredStep++)
+         {
+            forwardStartLevel = straightStartLevel;
+            if (staggeredStep==internalIterations) straightStartLevel = minInitLevel;
+            else
+            {
+               for (straightStartLevel = maxInitLevel, threshold = 1;
+                  (staggeredStep&threshold)!=threshold; straightStartLevel--, threshold <<= 1);
+            }
+            //////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+            timer.resetAndStart();
+#endif
+            //////////////////////////////////////////////////////////////////////////
+            applyPreCollisionBC(straightStartLevel, maxInitLevel);
+
+            calculateBlocks(straightStartLevel, maxInitLevel);
+            ////calculateBlocks(minInitLevel, maxInitLevel, staggeredStep);
+//////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+            time[0] = timer.stop();
+            UBLOG(logINFO, "calculateBlocks time = "<<time[0]);
+#endif
+            //////////////////////////////////////////////////////////////////////////
+
+                        //exchange data between blocks
+                        //Sleep(10000);
+            exchangeBlockData(straightStartLevel, maxInitLevel);
+            //////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+            time[1] = timer.stop();
+            UBLOG(logINFO, "exchangeBlockData time = "<<time[1]);
+#endif
+            //////////////////////////////////////////////////////////////////////////
+                        //applyBCs(straightStartLevel, maxInitLevel);
+            applyPostCollisionBC(straightStartLevel, maxInitLevel);
+
+            //////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+            time[2] = timer.stop();
+            UBLOG(logINFO, "applyBCs time = "<<time[2]);
+#endif
+            //////////////////////////////////////////////////////////////////////////
+
+                        //swap distributions in kernel
+            swapDistributions(straightStartLevel, maxInitLevel);
+
+#ifdef PRECOLLISIONBC
+            exchangeBlockData(straightStartLevel, maxInitLevel);
+            applyPreCollisionBC(straightStartLevel, maxInitLevel);
+#endif
+
+
+            //////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+            time[3] = timer.stop();
+            UBLOG(logINFO, "swapDistributions time = "<<time[3]);
+#endif
+            //////////////////////////////////////////////////////////////////////////
+
+            if (refinement)
+            {
+               //      //exchange data between blocks for grid refinement
+                     ////exchangeInterfaceBlockData(straightStartLevel, maxInitLevel, true);
+               //DOES NOT NEED 
+               if (straightStartLevel<maxInitLevel)
+                  exchangeBlockData(straightStartLevel, maxInitLevel);
+               //         //exchangeInterfaceBlockData(straightStartLevel, maxInitLevel, true);
+      //////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+               time[4] = timer.stop();
+               UBLOG(logINFO, "refinement exchangeBlockData time = "<<time[4]);
+#endif
+               //////////////////////////////////////////////////////////////////////////
+                              //now ghost nodes have actual values
+                              //interpolation of interface nodes between grid levels
+               interpolation(straightStartLevel, maxInitLevel);
+               //////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+               time[5] = timer.stop();
+               UBLOG(logINFO, "refinement interpolation time = "<<time[5]);
+#endif
+               //////////////////////////////////////////////////////////////////////////
+            }
+
+            if (taValuesCoProcessor)
+            {
+               taValuesCoProcessor->calculateSubtotal(calcStep-1);
+            }
+
+
+         }
+         //exchange data between blocks for visualization
+         if (mainThread) visScheduler->isDue((double)(calcStep-1));
+         if ((int)visScheduler->getNextDueTime()==calcStep)
+         {
+            exchangeBlockData(straightStartLevel, maxInitLevel);
+         }
+         //now ghost nodes have actual values
+
+         //dynamic load balancing
+         //sync->wait();
+         //if (mainThread && !loadBalancingComp)
+         //{
+         //   loadBalancingComp = cm->balance();
+         //}
+
+      }
+      UBLOG(logDEBUG1, "MPICalculator::calculate() - stoped");
+   }
+   catch (std::exception& e)
+   {
+      //error = boost::current_exception();
+      UBLOG(logERROR, e.what());
+      UBLOG(logERROR, " step = "<<calcStep);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void MPICalculator::calculateBlocks(int startLevel, int maxInitLevel)
+{
+   Block3DPtr blockTemp;
+   try
+   {
+      //startLevel bis maxInitLevel
+      for (int level = startLevel; level<=maxInitLevel; level++)
+      {
+         //timer.resetAndStart();
+         //call LBM kernel
+         for(Block3DPtr block : blocks[level])
+         {
+            blockTemp = block;
+            block->getKernel()->calculate();
+         }
+         //timer.stop();
+         //UBLOG(logINFO, "level = " << level << " blocks = " << blocks[level].size() << " collision time = " << timer.getTotalTime());
+      }
+   }
+   catch (std::exception& e)
+   {
+      //error = boost::current_exception();
+      UBLOG(logERROR, e.what());
+      UBLOG(logERROR, blockTemp->toString()<<" step = "<<calcStep);
+      exit(EXIT_FAILURE);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void MPICalculator::calculateBlocks(int minInitLevel, int maxInitLevel, int staggeredStep)
+{
+   int p, maxi, maxir, maxidp, start, end;
+   for (int level = minInitLevel; level<=maxInitLevel; level++)
+   {
+      p = 1<<(maxInitLevel-level);
+      maxi = maxir = static_cast<int>(blocks[level].size());
+      maxidp = maxi/p;
+      if (p>maxi && maxi!=0) {
+         maxidp = 1;
+         maxi = p;
+      }
+      start = (staggeredStep-1)*maxidp;
+      if (start>=maxi)
+         start = 0;
+      end = start+maxidp;
+      if ((end+p)>=maxi)
+         end = maxi;
+      for (int i = start; i<end; i++)
+      {
+         if (i<maxir)
+            blocks[level][i]->getKernel()->calculate();
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////
+void MPICalculator::exchangeBlockData(int startLevel, int maxInitLevel)
+{
+   //startLevel bis maxInitLevel
+   for (int level = startLevel; level<=maxInitLevel; level++)
+   {
+      connectorsPrepare(localConns[level]);
+      connectorsPrepare(remoteConns[level]);
+
+      connectorsSend(localConns[level]);
+      connectorsSend(remoteConns[level]);
+
+      connectorsReceive(localConns[level]);
+      connectorsReceive(remoteConns[level]);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void MPICalculator::exchangeInterfaceBlockData(int startLevel, int maxInitLevel)
+{
+   //startLevel bis maxInitLevel
+   for (int level = startLevel; level<=maxInitLevel; level++)
+   {
+      connectorsPrepare(localInterfaceBlockConns[level]);
+      connectorsPrepare(remoteInterfaceBlockConns[level]);
+
+      connectorsSend(localInterfaceBlockConns[level]);
+      connectorsSend(remoteInterfaceBlockConns[level]);
+
+      connectorsReceive(localInterfaceBlockConns[level]);
+      connectorsReceive(remoteInterfaceBlockConns[level]);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void MPICalculator::swapDistributions(int startLevel, int maxInitLevel)
+{
+   //startLevel bis maxInitLevel
+   for (int level = startLevel; level<=maxInitLevel; level++)
+   {
+      for(Block3DPtr block : blocks[level])
+      {
+         block->getKernel()->swapDistributions();
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void MPICalculator::connectorsPrepare(std::vector< Block3DConnectorPtr >& connectors)
+{
+   for(Block3DConnectorPtr c : connectors)
+   {
+      c->prepareForReceive();
+      c->prepareForSend();
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void MPICalculator::connectorsSend(std::vector< Block3DConnectorPtr >& connectors)
+{
+   for(Block3DConnectorPtr c : connectors)
+   {
+      c->fillSendVectors();
+      c->sendVectors();
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void MPICalculator::connectorsReceive(std::vector< Block3DConnectorPtr >& connectors)
+{
+   for(Block3DConnectorPtr c : connectors)
+   {
+      c->receiveVectors();
+      c->distributeReceiveVectors();
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void MPICalculator::interpolation(int startLevel, int maxInitLevel)
+{
+
+
+   for (int level = startLevel; level<maxInitLevel; level++)
+   {
+      connectorsPrepare(localInterConns[level]);
+      connectorsPrepare(remoteInterConns[level]);
+   }
+
+
+
+   for (int level = startLevel; level<maxInitLevel; level++)
+   {
+      connectorsSend(localInterConns[level]);
+      connectorsSend(remoteInterConns[level]);
+   }
+
+
+
+   for (int level = startLevel; level<maxInitLevel; level++)
+   {
+      connectorsReceive(localInterConns[level]);
+      connectorsReceive(remoteInterConns[level]);
+   }
+
+
+
+}
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+void MPICalculator::applyPreCollisionBC(int startLevel, int maxInitLevel)
+{
+   //startLevel bis maxInitLevel
+   for (int level = startLevel; level<=maxInitLevel; level++)
+   {
+      for(Block3DPtr block : blocks[level])
+      {
+         block->getKernel()->getBCProcessor()->applyPreCollisionBC();
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void MPICalculator::applyPostCollisionBC(int startLevel, int maxInitLevel)
+{
+   //startLevel bis maxInitLevel
+   for (int level = startLevel; level<=maxInitLevel; level++)
+   {
+      for(Block3DPtr block : blocks[level])
+      {
+         block->getKernel()->getBCProcessor()->applyPostCollisionBC();
+      }
+   }
+}
+
diff --git a/source/VirtualFluidsCore/Grid/MPICalculator.h b/source/VirtualFluidsCore/Grid/MPICalculator.h
index ae5c07017..8643b25e4 100644
--- a/source/VirtualFluidsCore/Grid/MPICalculator.h
+++ b/source/VirtualFluidsCore/Grid/MPICalculator.h
@@ -10,12 +10,15 @@
 #include "LoadBalancer.h"
 #include "TimeAveragedValuesCoProcessor.h"
 
+#include "Calculator.h"
 
 class MPICalculator;
-typedef boost::shared_ptr<MPICalculator> MPICalculatorPtr;
+typedef std::shared_ptr<MPICalculator> MPICalculatorPtr;
 
 #include "CalculationManager.h"
 
+class Block3DConnector;
+
 class MPICalculator  : public Calculator
 {
 public:
@@ -30,11 +33,11 @@ protected:
    void swapDistributions(int startLevel, int maxInitLevel);
    virtual void exchangeBlockData(int startLevel, int maxInitLevel);
    void exchangeInterfaceBlockData(int startLevel, int maxInitLevel);
-   virtual void connectorsPrepare(std::vector< Block3DConnectorPtr >& connectors);
-   virtual void connectorsSend(std::vector< Block3DConnectorPtr >& connectors);
-   virtual void connectorsReceive(std::vector< Block3DConnectorPtr >& connectors);
+   virtual void connectorsPrepare(std::vector< std::shared_ptr<Block3DConnector> >& connectors);
+   virtual void connectorsSend(std::vector< std::shared_ptr<Block3DConnector> >& connectors);
+   virtual void connectorsReceive(std::vector< std::shared_ptr<Block3DConnector> >& connectors);
    void interpolation(int startLevel, int maxInitLevel);
-   void deleteConnectors(std::vector< std::vector< Block3DConnectorPtr > >& conns);
+   void deleteConnectors(std::vector< std::vector< std::shared_ptr<Block3DConnector> > >& conns);
    void applyPreCollisionBC(int startLevel, int maxInitLevel);
    void applyPostCollisionBC(int startLevel, int maxInitLevel);
 private:
diff --git a/source/VirtualFluidsCore/Grid/PrePostBcCalculator.cpp b/source/VirtualFluidsCore/Grid/PrePostBcCalculator.cpp
index 3f20561a9..40bd90e2e 100644
--- a/source/VirtualFluidsCore/Grid/PrePostBcCalculator.cpp
+++ b/source/VirtualFluidsCore/Grid/PrePostBcCalculator.cpp
@@ -1,195 +1,197 @@
-#include "PrePostBcCalculator.h"
-#include <basics/utilities/UbException.h>
-#include <boost/foreach.hpp>
-#include "MathUtil.hpp"
-#include "basics/writer/WbWriterVtkXmlASCII.h"
-
-//#define TIMING
-
-PrePostBcCalculator::PrePostBcCalculator()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-PrePostBcCalculator::PrePostBcCalculator(Grid3DPtr grid, SynchronizerPtr sync, bool mainThread) : 
-Calculator(grid, sync, mainThread)
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-void PrePostBcCalculator::calculate(const double& endTime, CalculationManagerPtr cm, boost::exception_ptr& error)
-{
-   UBLOG(logDEBUG1, "PrePostBcCalculator::calculate() - started");
-   try
-   {
-      initConnectors();
-
-      int anzLevel = maxLevel-minLevel+1;
-
-      int minInitLevel       = minLevel;
-      int maxInitLevel       = maxLevel-minLevel;
-      int straightStartLevel = minInitLevel;
-      int internalIterations = 1 << (maxInitLevel-minInitLevel);
-      int forwardStartLevel;
-      int threshold;
-      int startStep = int(grid->getTimeStep())+1;
-
-      //UBLOG(logINFO, "startStep="<<startStep);
-      int anzCalcSteps = static_cast<int>(endTime);
-#ifdef TIMING
-      UbTimer timer;
-      double time[6];
-#endif
-
-//////////////////////////////////////////////////////////////////////////
-//      UBLOG(logINFO, "Number of connectors = " <<this->localConns[0].size());
-//////////////////////////////////////////////////////////////////////////
-
-      for(calcStep=startStep; calcStep<=anzCalcSteps+1; calcStep++)
-      {
-         ////wait for write dump files
-         //sync->wait();
-         //write dump 
-         if (mainThread) grid->coProcess((double)(calcStep-1));
-         sync->wait();
-
-
-//////////////////////////////////////////////////////////////////////////
-#ifdef TIMING
-         //UBLOG(logINFO, "calcStep = " <<calcStep);
-#endif
-//////////////////////////////////////////////////////////////////////////
-         
-         for(int staggeredStep=1; staggeredStep<=internalIterations; staggeredStep++)
-         {
-            forwardStartLevel = straightStartLevel;
-            if(staggeredStep == internalIterations) straightStartLevel = minInitLevel;
-            else
-            {
-               for(straightStartLevel=maxInitLevel,threshold=1;
-                  (staggeredStep&threshold)!=threshold; straightStartLevel--,threshold<<=1);
-            }
-//////////////////////////////////////////////////////////////////////////
-#ifdef TIMING
-            timer.resetAndStart();
-#endif
-//////////////////////////////////////////////////////////////////////////
-
-            applyPreCollisionBC(straightStartLevel, maxInitLevel);
-
-            calculateBlocks(straightStartLevel, maxInitLevel);
-            ////calculateBlocks(minInitLevel, maxInitLevel, staggeredStep);
-//////////////////////////////////////////////////////////////////////////
-#ifdef TIMING
-            time[0] = timer.stop();
-            //UBLOG(logINFO, "calculateBlocks time = " <<time);
-#endif
-//////////////////////////////////////////////////////////////////////////
-
-            //exchange data between blocks
-            //Sleep(10000);
-            exchangeBlockData(straightStartLevel, maxInitLevel);
-//////////////////////////////////////////////////////////////////////////
-#ifdef TIMING
-            time[1] = timer.stop();
-            //UBLOG(logINFO, "exchangeBlockData time = " <<time);
-#endif
-//////////////////////////////////////////////////////////////////////////
-
-            applyPostCollisionBC(straightStartLevel, maxInitLevel);
-            
-//////////////////////////////////////////////////////////////////////////
-#ifdef TIMING
-            time[2] = timer.stop();
-            //UBLOG(logINFO, "applyBCs time = " <<time);
-#endif
-//////////////////////////////////////////////////////////////////////////
-
-            //swap distributions in kernel
-            swapDistributions(straightStartLevel, maxInitLevel);
-
-//////////////////////////////////////////////////////////////////////////
-#ifdef TIMING
-            time[3] = timer.stop();
-            //UBLOG(logINFO, "swapDistributions time = " <<time);
-#endif
-//////////////////////////////////////////////////////////////////////////
-
-            if (refinement)
-            {
-         //      //exchange data between blocks for grid refinement
-			      ////exchangeInterfaceBlockData(straightStartLevel, maxInitLevel, true);
-         //DOES NOT NEED 
-                     if(straightStartLevel<maxInitLevel)
-                  exchangeBlockData(straightStartLevel, maxInitLevel);
-         //         //exchangeInterfaceBlockData(straightStartLevel, maxInitLevel, true);
-//////////////////////////////////////////////////////////////////////////
-#ifdef TIMING
-               time[4] = timer.stop();
-               UBLOG(logINFO, "refinement exchangeBlockData time = " <<time);
-#endif
-//////////////////////////////////////////////////////////////////////////
-               //now ghost nodes have actual values
-			      //interpolation of interface nodes between grid levels
-               interpolation(straightStartLevel, maxInitLevel);
-//////////////////////////////////////////////////////////////////////////
-#ifdef TIMING
-               time[5] = timer.stop();
-               UBLOG(logINFO, "refinement interpolation time = " <<time);
-#endif
-//////////////////////////////////////////////////////////////////////////
-            }
-            
-         }
-         //exchange data between blocks for visualization
-        if(mainThread) visScheduler->isDue((double)(calcStep-1));
-        if((int)visScheduler->getNextDueTime() == calcStep)
-        {
-            exchangeBlockData(straightStartLevel, maxInitLevel);
-        }
-         //now ghost nodes have actual values
-
-         //dynamic load balancing
-         //sync->wait();
-         //if (mainThread && !loadBalancingComp)
-         //{
-         //   loadBalancingComp = cm->balance();
-         //}
-      }
-      error = boost::exception_ptr();
-      UBLOG(logDEBUG1, "PrePostBcCalculator::calculate() - stoped");
-   }
-   catch( std::exception& e )
-   {
-      //error = boost::current_exception();
-      UBLOG(logERROR, e.what());
-      UBLOG(logERROR, " step = "<<calcStep);
-      boost::dynamic_pointer_cast<MPICommunicator>(Communicator::getInstance())->~MPICommunicator();
-      exit(EXIT_FAILURE);
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void PrePostBcCalculator::applyPreCollisionBC(int startLevel, int maxInitLevel)
-{
-   //startLevel bis maxInitLevel
-   for (int level = startLevel; level<=maxInitLevel; level++)
-   {
-      BOOST_FOREACH(Block3DPtr block, blocks[level])
-      {
-         block->getKernel()->getBCProcessor()->applyPreCollisionBC();
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void PrePostBcCalculator::applyPostCollisionBC(int startLevel, int maxInitLevel)
-{
-   //startLevel bis maxInitLevel
-   for (int level = startLevel; level<=maxInitLevel; level++)
-   {
-      BOOST_FOREACH(Block3DPtr block, blocks[level])
-      {
-         block->getKernel()->getBCProcessor()->applyPostCollisionBC();
-      }
-   }
-}
-
+#include "PrePostBcCalculator.h"
+#include <basics/utilities/UbException.h>
+
+#include "MathUtil.hpp"
+#include "basics/writer/WbWriterVtkXmlASCII.h"
+
+#include "LBMKernel.h"
+#include "BCProcessor.h"
+//#define TIMING
+
+PrePostBcCalculator::PrePostBcCalculator()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+PrePostBcCalculator::PrePostBcCalculator(Grid3DPtr grid, SynchronizerPtr sync, bool mainThread) : 
+Calculator(grid, sync, mainThread)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void PrePostBcCalculator::calculate(const double& endTime, CalculationManagerPtr cm, boost::exception_ptr& error)
+{
+   UBLOG(logDEBUG1, "PrePostBcCalculator::calculate() - started");
+   try
+   {
+      initConnectors();
+
+      int anzLevel = maxLevel-minLevel+1;
+
+      int minInitLevel       = minLevel;
+      int maxInitLevel       = maxLevel-minLevel;
+      int straightStartLevel = minInitLevel;
+      int internalIterations = 1 << (maxInitLevel-minInitLevel);
+      int forwardStartLevel;
+      int threshold;
+      int startStep = int(grid->getTimeStep())+1;
+
+      //UBLOG(logINFO, "startStep="<<startStep);
+      int anzCalcSteps = static_cast<int>(endTime);
+#ifdef TIMING
+      UbTimer timer;
+      double time[6];
+#endif
+
+//////////////////////////////////////////////////////////////////////////
+//      UBLOG(logINFO, "Number of connectors = " <<this->localConns[0].size());
+//////////////////////////////////////////////////////////////////////////
+
+      for(calcStep=startStep; calcStep<=anzCalcSteps+1; calcStep++)
+      {
+         ////wait for write dump files
+         //sync->wait();
+         //write dump 
+         if (mainThread) grid->coProcess((double)(calcStep-1));
+         sync->wait();
+
+
+//////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+         //UBLOG(logINFO, "calcStep = " <<calcStep);
+#endif
+//////////////////////////////////////////////////////////////////////////
+         
+         for(int staggeredStep=1; staggeredStep<=internalIterations; staggeredStep++)
+         {
+            forwardStartLevel = straightStartLevel;
+            if(staggeredStep == internalIterations) straightStartLevel = minInitLevel;
+            else
+            {
+               for(straightStartLevel=maxInitLevel,threshold=1;
+                  (staggeredStep&threshold)!=threshold; straightStartLevel--,threshold<<=1);
+            }
+//////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+            timer.resetAndStart();
+#endif
+//////////////////////////////////////////////////////////////////////////
+
+            applyPreCollisionBC(straightStartLevel, maxInitLevel);
+
+            calculateBlocks(straightStartLevel, maxInitLevel);
+            ////calculateBlocks(minInitLevel, maxInitLevel, staggeredStep);
+//////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+            time[0] = timer.stop();
+            //UBLOG(logINFO, "calculateBlocks time = " <<time);
+#endif
+//////////////////////////////////////////////////////////////////////////
+
+            //exchange data between blocks
+            //Sleep(10000);
+            exchangeBlockData(straightStartLevel, maxInitLevel);
+//////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+            time[1] = timer.stop();
+            //UBLOG(logINFO, "exchangeBlockData time = " <<time);
+#endif
+//////////////////////////////////////////////////////////////////////////
+
+            applyPostCollisionBC(straightStartLevel, maxInitLevel);
+            
+//////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+            time[2] = timer.stop();
+            //UBLOG(logINFO, "applyBCs time = " <<time);
+#endif
+//////////////////////////////////////////////////////////////////////////
+
+            //swap distributions in kernel
+            swapDistributions(straightStartLevel, maxInitLevel);
+
+//////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+            time[3] = timer.stop();
+            //UBLOG(logINFO, "swapDistributions time = " <<time);
+#endif
+//////////////////////////////////////////////////////////////////////////
+
+            if (refinement)
+            {
+         //      //exchange data between blocks for grid refinement
+			      ////exchangeInterfaceBlockData(straightStartLevel, maxInitLevel, true);
+         //DOES NOT NEED 
+                     if(straightStartLevel<maxInitLevel)
+                  exchangeBlockData(straightStartLevel, maxInitLevel);
+         //         //exchangeInterfaceBlockData(straightStartLevel, maxInitLevel, true);
+//////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+               time[4] = timer.stop();
+               UBLOG(logINFO, "refinement exchangeBlockData time = " <<time);
+#endif
+//////////////////////////////////////////////////////////////////////////
+               //now ghost nodes have actual values
+			      //interpolation of interface nodes between grid levels
+               interpolation(straightStartLevel, maxInitLevel);
+//////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+               time[5] = timer.stop();
+               UBLOG(logINFO, "refinement interpolation time = " <<time);
+#endif
+//////////////////////////////////////////////////////////////////////////
+            }
+            
+         }
+         //exchange data between blocks for visualization
+        if(mainThread) visScheduler->isDue((double)(calcStep-1));
+        if((int)visScheduler->getNextDueTime() == calcStep)
+        {
+            exchangeBlockData(straightStartLevel, maxInitLevel);
+        }
+         //now ghost nodes have actual values
+
+         //dynamic load balancing
+         //sync->wait();
+         //if (mainThread && !loadBalancingComp)
+         //{
+         //   loadBalancingComp = cm->balance();
+         //}
+      }
+      error = boost::exception_ptr();
+      UBLOG(logDEBUG1, "PrePostBcCalculator::calculate() - stoped");
+   }
+   catch( std::exception& e )
+   {
+      //error = boost::current_exception();
+      UBLOG(logERROR, e.what());
+      UBLOG(logERROR, " step = "<<calcStep);
+      std::dynamic_pointer_cast<MPICommunicator>(Communicator::getInstance())->~MPICommunicator();
+      exit(EXIT_FAILURE);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void PrePostBcCalculator::applyPreCollisionBC(int startLevel, int maxInitLevel)
+{
+   //startLevel bis maxInitLevel
+   for (int level = startLevel; level<=maxInitLevel; level++)
+   {
+      for(Block3DPtr block : blocks[level])
+      {
+         block->getKernel()->getBCProcessor()->applyPreCollisionBC();
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void PrePostBcCalculator::applyPostCollisionBC(int startLevel, int maxInitLevel)
+{
+   //startLevel bis maxInitLevel
+   for (int level = startLevel; level<=maxInitLevel; level++)
+   {
+      for(Block3DPtr block : blocks[level])
+      {
+         block->getKernel()->getBCProcessor()->applyPostCollisionBC();
+      }
+   }
+}
+
diff --git a/source/VirtualFluidsCore/Grid/PrePostBcCalculator.h b/source/VirtualFluidsCore/Grid/PrePostBcCalculator.h
index 3caeb94da..cfdf3ebf2 100644
--- a/source/VirtualFluidsCore/Grid/PrePostBcCalculator.h
+++ b/source/VirtualFluidsCore/Grid/PrePostBcCalculator.h
@@ -8,11 +8,11 @@
 #include "basics/utilities/UbScheduler.h"
 #include "basics/utilities/UbTiming.h"
 #include "LoadBalancer.h"
-#include "PrePostBcCalculator.h"
 
+#include "Calculator.h"
 
 class PrePostBcCalculator;
-typedef boost::shared_ptr<PrePostBcCalculator> PrePostBcCalculatorPtr;
+typedef std::shared_ptr<PrePostBcCalculator> PrePostBcCalculatorPtr;
 
 #include "CalculationManager.h"
 
diff --git a/source/VirtualFluidsCore/Interactors/D3Q27Interactor.cpp b/source/VirtualFluidsCore/Interactors/D3Q27Interactor.cpp
index 12dd8cc6f..afe893dba 100644
--- a/source/VirtualFluidsCore/Interactors/D3Q27Interactor.cpp
+++ b/source/VirtualFluidsCore/Interactors/D3Q27Interactor.cpp
@@ -1,1408 +1,782 @@
-#include "D3Q27Interactor.h"
-#include <basics/utilities/UbMath.h>
-#include <basics/utilities/UbLogger.h>
-
-#include <basics/writer/WbWriterVtkXmlBinary.h>
-
-
-#include <numerics/geometry3d/GbCuboid3D.h>
-#include <numerics/geometry3d/GbLine3D.h>
-#include <numerics/geometry3d/GbCylinder3D.h>
-#include "Block3D.h"
-#include "Grid3D.h"
-#include "BCArray3D.h"
-#include "BoundaryConditions.h"
-#include "VelocityBCAdapter.h"
-#include "LBMKernel.h"
-#include "BCProcessor.h"
-
-//#include <3rdParty/MarchingCubes/MarchingCubes.h>
-
-#include <boost/pointer_cast.hpp>
-
-#include <vector>
-
-using namespace std;
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-D3Q27Interactor::D3Q27Interactor() : Interactor3D()
-{
-   this->reinitWithStoredQsFlag = false;
-   this->initRayVectors();
-}
-//////////////////////////////////////////////////////////////////////////
-D3Q27Interactor::D3Q27Interactor(GbObject3DPtr geoObject3D, Grid3DPtr grid, int type)
-: Interactor3D(geoObject3D, grid, type), relevantForForces(false)
-{
-   this->reinitWithStoredQsFlag = false;
-   this->initRayVectors();
-}
-//////////////////////////////////////////////////////////////////////////
-D3Q27Interactor::D3Q27Interactor(GbObject3DPtr geoObject3D, Grid3DPtr grid, BCAdapterPtr bcAdapter,  int type)
-   :   Interactor3D(geoObject3D, grid, type), relevantForForces(false)
-{
-   this->reinitWithStoredQsFlag = false;
-   this->addBCAdapter(bcAdapter); 
-   this->initRayVectors();
-}
-//////////////////////////////////////////////////////////////////////////
-D3Q27Interactor::D3Q27Interactor(GbObject3DPtr geoObject3D, Grid3DPtr grid, BCAdapterPtr bcAdapter,  int type, Interactor3D::Accuracy a)
-   :   Interactor3D(geoObject3D, grid, type, a), relevantForForces(false)
-{
-   this->reinitWithStoredQsFlag = false;
-   this->addBCAdapter(bcAdapter); 
-   this->initRayVectors();
-}
-//////////////////////////////////////////////////////////////////////////
-D3Q27Interactor::~D3Q27Interactor()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-void D3Q27Interactor::initRayVectors()
-{
-   int fdir; double c1oS2 = UbMath::one_over_sqrt2;
-   fdir = D3Q27System::E;  rayX1[fdir] =  1.0;   rayX2[fdir] =  0.0;   rayX3[fdir] =  0.0;
-   fdir = D3Q27System::W;  rayX1[fdir] = -1.0;   rayX2[fdir] =  0.0;   rayX3[fdir] =  0.0;
-   fdir = D3Q27System::N;  rayX1[fdir] =  0.0;   rayX2[fdir] =  1.0;   rayX3[fdir] =  0.0;
-   fdir = D3Q27System::S;  rayX1[fdir] =  0.0;   rayX2[fdir] = -1.0;   rayX3[fdir] =  0.0;
-   fdir = D3Q27System::T;  rayX1[fdir] =  0.0;   rayX2[fdir] =  0.0;   rayX3[fdir] =  1.0;
-   fdir = D3Q27System::B;  rayX1[fdir] =  0.0;   rayX2[fdir] =  0.0;   rayX3[fdir] = -1.0;
-   fdir = D3Q27System::NE; rayX1[fdir] =  c1oS2; rayX2[fdir] =  c1oS2; rayX3[fdir] =  0.0;
-   fdir = D3Q27System::SW; rayX1[fdir] = -c1oS2; rayX2[fdir] = -c1oS2; rayX3[fdir] =  0.0;
-   fdir = D3Q27System::SE; rayX1[fdir] =  c1oS2; rayX2[fdir] = -c1oS2; rayX3[fdir] =  0.0;
-   fdir = D3Q27System::NW; rayX1[fdir] = -c1oS2; rayX2[fdir] =  c1oS2; rayX3[fdir] =  0.0;
-   fdir = D3Q27System::TE; rayX1[fdir] =  c1oS2; rayX2[fdir] = 0.0;    rayX3[fdir] =  c1oS2;
-   fdir = D3Q27System::BW; rayX1[fdir] = -c1oS2; rayX2[fdir] = 0.0;    rayX3[fdir] = -c1oS2;
-   fdir = D3Q27System::BE; rayX1[fdir] =  c1oS2; rayX2[fdir] = 0.0;    rayX3[fdir] = -c1oS2;
-   fdir = D3Q27System::TW; rayX1[fdir] = -c1oS2; rayX2[fdir] = 0.0;    rayX3[fdir] =  c1oS2;
-   fdir = D3Q27System::TN; rayX1[fdir] =  0.0;   rayX2[fdir] = c1oS2;  rayX3[fdir] =  c1oS2;
-   fdir = D3Q27System::BS; rayX1[fdir] =  0.0;   rayX2[fdir] =-c1oS2;  rayX3[fdir] = -c1oS2;
-   fdir = D3Q27System::BN; rayX1[fdir] =  0.0;   rayX2[fdir] = c1oS2;  rayX3[fdir] = -c1oS2;
-   fdir = D3Q27System::TS; rayX1[fdir] =  0.0;   rayX2[fdir] =-c1oS2;  rayX3[fdir] =  c1oS2;
-
-   fdir = D3Q27System::TNW; rayX1[fdir] = -c1oS2; rayX2[fdir] = c1oS2; rayX3[fdir] =  c1oS2;;
-   fdir = D3Q27System::TNE; rayX1[fdir] =  c1oS2; rayX2[fdir] = c1oS2; rayX3[fdir] =  c1oS2;
-   fdir = D3Q27System::TSW; rayX1[fdir] = -c1oS2; rayX2[fdir] =-c1oS2; rayX3[fdir] =  c1oS2;
-   fdir = D3Q27System::TSE; rayX1[fdir] =  c1oS2; rayX2[fdir] =-c1oS2; rayX3[fdir] =  c1oS2;
-   fdir = D3Q27System::BNW; rayX1[fdir] = -c1oS2; rayX2[fdir] = c1oS2; rayX3[fdir] =  -c1oS2;
-   fdir = D3Q27System::BNE; rayX1[fdir] =  c1oS2; rayX2[fdir] = c1oS2; rayX3[fdir] =  -c1oS2;
-   fdir = D3Q27System::BSW; rayX1[fdir] = -c1oS2; rayX2[fdir] =-c1oS2; rayX3[fdir] =  -c1oS2;
-   fdir = D3Q27System::BSE; rayX1[fdir] =  c1oS2; rayX2[fdir] =-c1oS2; rayX3[fdir] =  -c1oS2;
-}
-//////////////////////////////////////////////////////////////////////////
-void D3Q27Interactor::initInteractor(const double& timeStep)
-{
-   UBLOG(logDEBUG5,"D3Q27Interactor::initInteractor - "<<" for timestep = "<<timeStep);
-   
-   //////////////////////////////////////////////////////////////////////////
-   //init bcs
-   int nofAdapter = (int)bcAdapterVector.size();
-   if(nofAdapter==0) UBLOG(logWARNING,"WARNING - D3Q27Interactor::initInteractor Warning - no nodeAdapter available");
-   bool needTimeDependence = false;
-   for(int pos=0; pos<nofAdapter; ++pos)
-   {
-      bcAdapterVector[pos]->init(this,timeStep);
-      if(bcAdapterVector[pos]->isTimeDependent()) needTimeDependence = true;
-   }
-   if(needTimeDependence) this->setTimeDependent();
-   else                   this->unsetTimeDependent();
-
-   Interactor3D::initInteractor(timeStep);
-
-  ////calcForces arbeitet nicht korrekt, wenn Geo mit Bloecken 
-  // //unterschiedlicher Leveltiefe diskretisiert -> exception
-  // //abfrage steht hier, weil es theoretisch sein kann, dass bei parallelen rechnungen
-  // //genau der block mit dem anderen level auf einem anderen prozess liegt...
-  // //Update: es kann u.U. passieren, dass Bl�cke in der Liste nicht aktiv sin
-  // //(falls diese z.B. duch andere Interactoren solid gesetzt wurden)
-  // //diese werden nicht ber�cksichtigt (auch nicht beid er kraftauswertung sp�ter)
-  // if(this->isRelevantForForces() )
-  // {
-  //    int level = -1;     
-  //    for( vector<Block3D*>::const_iterator pos = transBlockSet->begin(); pos!=transBlockSet->end(); ++pos)
-  //       if( (*pos)->isActive() )
-  //       {
-  //          level = (*pos)->getLevel();
-  //          break;
-  //       }
-  //    
-  //    bool check = false;
-  //    for( vector<Block3D*>::const_iterator pos = transBlockSet->begin(); pos!=transBlockSet->end(); ++pos)
-  //       if( (*pos)->isActive() && (*pos)->getLevel()!=level)
-  //       {
-  //          throw UbException(UB_EXARGS,"interactor is relevant for forces,"
-  //                                  +(string)" but has transblocks with different levels"
-  //                                  +(string)" -> not supportet by D3Q27Interactor::getForces()"
-  //                                  +(string)" -> increase refineWidth");
-  //       }
-  // }
-}
-//////////////////////////////////////////////////////////////////////////
-void D3Q27Interactor::updateInteractor(const double& timestep)
-{
-   //UB_THROW( UbException(UB_EXARGS,"toDo") );
-   //if(this->isFluid()) return;
-
-   UBLOG(logDEBUG5,"D3Q27Interactor::updateInteractor - for timestep = "<<timestep);
-
-   //////////////////////////////////////////////////////////////////////////
-   //update bcs
-   int nofAdapter = (int)bcAdapterVector.size();
-   if(nofAdapter==0) UBLOG(logERROR,"WARNING - D3Q27Interactor::updateInteractor Warning - no nodeAdapter available for ");
-
-   bool needTimeDependence = false;
-
-   for(int pos=0; pos<nofAdapter; ++pos)
-   {
-      bcAdapterVector[pos]->update(this,timestep);
-      if(bcAdapterVector[pos]->isTimeDependent()) needTimeDependence = true;
-   }
-   if(needTimeDependence) this->setTimeDependent();
-   else                   this->unsetTimeDependent();
-
-   //update transNodes
-   typedef std::map<Block3DPtr, std::set< std::vector<int> > > TransNodeIndicesMap;
-   
-   //UBLOG(logINFO, "transNodeIndicesMap = "<<transNodeIndicesMap.size());
-   
-   BOOST_FOREACH(TransNodeIndicesMap::value_type t, bcNodeIndicesMap)
-   {
-      Block3DPtr block = t.first;
-      std::set< std::vector<int> >& transNodeIndicesSet = t.second;
-
-      //UBLOG(logINFO, "transNodeIndicesSet = "<<transNodeIndicesSet.size());
-
-      if(block->isNotActive() || !block) continue;
-
-      LBMKernelPtr kernel = block->getKernel();
-      BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
-
-      set< std::vector<int> >::iterator setPos;
-
-      for(setPos=transNodeIndicesSet.begin(); setPos!=transNodeIndicesSet.end();  ++setPos)
-      {
-         int    x1      = (*setPos)[0];
-         int    x2      = (*setPos)[1];
-         int    x3      = (*setPos)[2];
-         UbTupleDouble3 coords = grid.lock()->getNodeCoordinates(block, x1, x2, x3);
-         double worldX1 = val<1>(coords);
-         double worldX2 = val<2>(coords);
-         double worldX3 = val<3>(coords);
-
-         BoundaryConditionsPtr bc = bcArray->getBC(x1,x2,x3);
-         if(bc) //kann sein, dass die BC durch das solid setzen eines andern interactors geloescht wurde
-         {
-            for(size_t i=0; i<bcAdapterVector.size(); i++)
-               bcAdapterVector[i]->adaptBC(*this,bc,worldX1,worldX2,worldX3,timestep);
-         }
-         //else 
-         //{
-         //   UBLOG(logERROR,"D3Q27Interactor.updateInteractor (Z."<<__LINE__<<"): da ist kein BC dran ... kann aber korrekt sein s.h. code");
-         //}
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-// Berechnung findet im realen Koordinatensystem statt !!!
-// nicht im normierten !
-//x1,x2,x3 sind die Koordinaten unten links vom "System"
-//extendedBoundingGeoOfGeoObject MUSS bereits um delta_x_level in jede richtung vergroesert worden sein fuer SOLID
-bool D3Q27Interactor::setDifferencesToGbObject3D(const Block3DPtr block/*,const double& orgX1,const double& orgX2,const double& orgX3,const double& blockLengthX1,const double& blockLengthX2,const double& blockLengthX3, const double& timestep*/)
-{
-   if(!block) return false;
-
-   if(block->isNotActive()) return false;//continue;
-
-   bcNodeIndicesMap[block] = set< std::vector<int> >();
-   set< std::vector<int> >& transNodeIndices = bcNodeIndicesMap[block];
-   solidNodeIndicesMap[block] = set< UbTupleInt3 >();
-   set< UbTupleInt3 >& solidNodeIndices = solidNodeIndicesMap[block];
-
-
-   double timestep = 0;
-   bool oneEntryGotBC = false; //ob ueberhaupt ein eintrag ein BC zugewiesen wurde
-   bool gotQs         = false; //true, wenn "difference" gesetzt wurde
-   BoundaryConditionsPtr bc;
-
-   LBMKernelPtr kernel = block->getKernel();
-   BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
-
-   double internX1,internX2,internX3;
-
-
-   //width of ghost layer 
-   int gl = kernel->getGhostLayerWidth();
-
-   int startIX1 = 0;
-   int startIX2 = 0;
-   int startIX3 = 0; 
-   int stopIX1  = (int)bcArray->getNX1();
-   int stopIX2  = (int)bcArray->getNX2();
-   int stopIX3  = (int)bcArray->getNX3(); 
-
-   double         dx       = grid.lock()->getDeltaX(block);
-   UbTupleDouble3 orgDelta = grid.lock()->getNodeOffset(block);
-
-   //anderes boundingRect als in init, da hier das boundrect um ein dx vergroessert werden muss
-   GbCuboid3D extendedBoundingGeoOfGeoObject(  geoObject3D->getX1Minimum()-1.02*dx 
-                                             , geoObject3D->getX2Minimum()-1.02*dx 
-                                             , geoObject3D->getX3Minimum()-1.02*dx 
-                                             , geoObject3D->getX1Maximum()+1.02*dx 
-                                             , geoObject3D->getX2Maximum()+1.02*dx 
-                                             , geoObject3D->getX3Maximum()+1.02*dx );
-
-   double deltaX1=dx, deltaX2 =dx, deltaX3=dx;
-
-   if(   geoObject3D->hasRaytracing() 
-        || (this->isInverseSolid() && geoObject3D->raytracingSupportsPointsInside() ) )
-   {
-      //wenn deltaX1==deltaX2==deltaX3 (muss fuer LB!!)
-      if(!UbMath::zero( deltaX1-deltaX2 + deltaX1-deltaX3 + deltaX2-deltaX3 ) )
-         throw UbException(UB_EXARGS,"fuer den bei LB nicht vorkommenden Fall deltaX1!=deltaX2!=deltaX3  nicht implementiert ");
-
-      vector<double> distNeigh(D3Q27System::FENDDIR+1, UbMath::sqrt2*deltaX1);
-      distNeigh[D3Q27System::E] = distNeigh[D3Q27System::W] = distNeigh[D3Q27System::N] = deltaX1;
-      distNeigh[D3Q27System::S] = distNeigh[D3Q27System::T] = distNeigh[D3Q27System::B] = deltaX1;
-
-      double q;
-      bool pointOnBoundary = false;
-
-//#ifdef _OPENMP
-//      #pragma omp parallel for private(internX1,internX2,internX3,gotQs,bc,q )
-//#endif
-      for(int ix3=startIX3; ix3<stopIX3; ix3++)
-      {
-         for(int ix2=startIX2; ix2<stopIX2; ix2++)
-         {
-            for(int ix1=startIX1; ix1<stopIX1; ix1++)
-            {
-               //TODO weiter untersuchen, ob das nicht ein Fehler ist
-               if(bcArray->isUndefined(ix1, ix2, ix3)) continue;
-
-               UbTupleDouble3 coords = grid.lock()->getNodeCoordinates(block, ix1, ix2, ix3);
-               internX1 = val<1>(coords);
-               internX2 = val<2>(coords);
-               internX3 = val<3>(coords);
-
-               //point in object test ist ueberfluessig, weil die start und stop indices bereits zuvor 
-               //ermittelt werden -> es werden nur point-IN-cube indizes betrachtet
-               if(extendedBoundingGeoOfGeoObject.isPointInGbObject3D(internX1,internX2,internX3))
-               {
-                  if(this->isSolid() )
-                  {
-                     if(this->geoObject3D->isPointInGbObject3D(internX1, internX2, internX3))
-                     {
-//#ifdef _OPENMP
-//                        #pragma omp critical (SOLIDNODE_SET_CHANGE)
-//#endif
-                        {
-                           solidNodeIndices.insert(UbTupleInt3(ix1, ix2, ix3));
-                           bcArray->setSolid(ix1,ix2,ix3); 
-                        }
-                        continue;
-                     }
-                  }
-                  else if( this->isInverseSolid()  )
-                  {
-                     //bei inverse solid sind alle Knoten AUSSERHALB und auf der boundary SOLID
-                     if( !this->geoObject3D->isPointInGbObject3D(internX1, internX2, internX3, pointOnBoundary) 
-                        || pointOnBoundary == true )
-                     {
-//#ifdef _OPENMP
-//                        #pragma omp critical (SOLID_SET_CHANGE)
-//#endif
-                        {
-                           solidNodeIndices.insert(UbTupleInt3(ix1, ix2, ix3));
-                           bcArray->setSolid(ix1,ix2,ix3); 
-                        }
-                        continue;
-                     }
-                  }
-
-                  //evtl wurde node von anderen interactoren solid gesetzt (muss hie rein->sonst evtl bei
-                  //ueberschneidender geo -> solidNodeIndicesMap unvollstaendig)
-                  if(bcArray->isSolid(ix1,ix2,ix3)) 
-                     continue;
-
-                  gotQs = false;
-
-                  //TODO: prüfen was passiert wenn ein Geoobjekt zwischen zwei knoten rausguckt
-                  //  * /
-                  //<
-                  //  * \  //
-                  //sollen dann keine qs gesetzt werden
-                  for(int fdir=D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
-                  {
-                     q = geoObject3D->getIntersectionRaytraceFactor(internX1,internX2,internX3,rayX1[fdir],rayX2[fdir],rayX3[fdir]);
-                     q /= distNeigh[fdir];
-
-                     //assert(UbMath::lessEqual(q, 1.0));
-
-                     if( UbMath::inClosedInterval(q, 1.0, 1.0) ) q = 1.0;
-                     if( UbMath::greater(q, 0.0) && UbMath::lessEqual(q, 1.0) )
-                     {
-                        #pragma omp critical (BC_CHANGE)
-                        {
-                           bc = bcArray->getBC(ix1,ix2,ix3);
-                           if(!bc)
-                           {
-                              //bc = bvd->createD3Q27BoundaryCondition(); //= new D3Q27BoundaryCondition();
-                              bc = BoundaryConditionsPtr(new BoundaryConditions);
-                              bcArray->setBC(ix1,ix2,ix3,bc);
-                           }
-                     //TODO: man muss ueberlegen, wie kann man, dass die Geschwindigkeit auf 0.0 gesetzt werden, vermeiden
-                     //das folgt zu unguenstigen "design rules"
-                      //SG 31.08.2010 das Problem - bewegter Interactor angrenzend an stehenden noslip interactor
-                      // hier sollte die Geschwindigkeit auf 0.0 gesetzt werden
-                           if(bc->hasNoSlipBoundary())
-                           {
-                              bc->setBoundaryVelocityX1(0.0);
-                              bc->setBoundaryVelocityX2(0.0);
-                              bc->setBoundaryVelocityX3(0.0);
-                           }
-                       //SG 31.08.2010
-                        
-                           for(int index=(int)bcAdapterVector.size()-1; index>=0; --index)
-                              bcAdapterVector[index]->adaptBCForDirection(*this,bc,internX1,internX2,internX3,q,fdir, timestep);
-                        }
-
-                        gotQs=true;
-                     }
-                  }
-
-                  if(gotQs)
-                  {
-#ifdef _OPENMP
-                     #pragma omp critical (TRANSNODE_SET_CHANGE)
-#endif
-                     {
-                        oneEntryGotBC = true;
-
-                        std::vector<int> p(3);
-                        p[0]=ix1; p[1]=ix2; p[2]=ix3;
-                        transNodeIndices.insert(p);
-                     
-                        for(int index=(int)bcAdapterVector.size()-1; index>=0; --index)
-                           bcAdapterVector[index]->adaptBC(*this,bc,internX1,internX2,internX3, timestep);
-                     }
-                  }
-               }
-               else if( this->isInverseSolid()  )
-               {
-                  //bei inverse solid sind alle Knoten AUSSERHALB und auf der boundary SOLID
-                  if( !this->geoObject3D->isPointInGbObject3D(internX1, internX2, internX3, pointOnBoundary) 
-                     || pointOnBoundary == true )
-                 {
-#ifdef _OPENMP 
-   #pragma omp critical (SOLID_SET_CHANGE)
-#endif
-                     {
-                        solidNodeIndices.insert(UbTupleInt3(ix1, ix2, ix3));
-                        bcArray->setSolid(ix1,ix2,ix3); 
-                     }
-                     continue;
-                  }
-               }
-            }
-         }
-      }
-   }
-   else  //clipping -> langsamer (wird derzeit auch fuer alle inverseSolid objekte verwendet deren raytracing nicht fuer nodes INNERHALB der geo funzt)
-   {
-      bool pointOnBoundary = false;
-      #pragma omp parallel for private(internX1,internX2,internX3,gotQs,bc,pointOnBoundary )
-      for(int ix1=startIX1; ix1<stopIX1; ix1++)
-      {
-         for(int ix2=startIX2; ix2<stopIX2; ix2++)
-         {
-            for(int ix3=startIX3; ix3<stopIX3; ix3++)
-            {
-               if(bcArray->isSolid(ix1,ix2,ix3) || bcArray->isUndefined(ix1, ix2, ix3)) continue;
-
-               UbTupleDouble3 coords = grid.lock()->getNodeCoordinates(block, ix1, ix2, ix3);
-               internX1 = val<1>(coords);
-               internX2 = val<2>(coords);
-               internX3 = val<3>(coords);
-
-               if(extendedBoundingGeoOfGeoObject.isPointInGbObject3D(internX1,internX2,internX3))
-               {
-                  if( this->isSolid() && this->geoObject3D->isPointInGbObject3D(internX1, internX2, internX3) )
-                  {
-                     #pragma omp critical (SOLID_SET_CHANGE)
-                     {
-                        solidNodeIndices.insert(UbTupleInt3(ix1, ix2, ix3));
-                        bcArray->setSolid(ix1,ix2,ix3); 
-                     }
-                     continue;
-                  }
-                  else if( this->isInverseSolid()  )
-                  {
-                     //bei inverse solid sind alle Knoten AUSSERHALB und auf der boundary SOLID
-                     if( !this->geoObject3D->isPointInGbObject3D(internX1, internX2, internX3, pointOnBoundary) 
-                         || pointOnBoundary == true )
-                     {
-                        #pragma omp critical (SOLID_SET_CHANGE)
-                        {
-                           solidNodeIndices.insert(UbTupleInt3(ix1, ix2, ix3));
-                           bcArray->setSolid(ix1,ix2,ix3); 
-                        }
-                        continue;
-                     }
-                  }
-
-                  gotQs = false;
-
-                  GbPoint3D pointA(internX1,internX2,internX3);
-                  for(int fdir=D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
-                  {
-                     double x1B = internX1+D3Q27System::DX1[fdir]*deltaX1;
-                     double x2B = internX2+D3Q27System::DX2[fdir]*deltaX2;
-                     double x3B = internX3+D3Q27System::DX3[fdir]*deltaX3;
-
-                     GbPoint3D pointB(x1B,x2B,x3B);
-                     GbLine3D* clippedLine = this->geoObject3D->createClippedLine3D(pointA, pointB);
-
-                     if(clippedLine)
-                     {
-                        double q=0.0;
-                        if( !this->isInverseSolid() )  //A liegt auf jeden Fall aussen
-                        {
-                           double distanceAB = pointA.getDistance(&pointB); //pointA to B
-                           double distanceAP = UbMath::min(pointA.getDistance(clippedLine->getPoint1()),
-                                                           pointA.getDistance(clippedLine->getPoint2()) );
-                           q = distanceAP/distanceAB;
-                        }
-                        else
-                        {
-                           bool pointIsOnBoundary = false;
-                           if(   !clippedLine->getPoint1()->equals(&pointB)
-                              && !clippedLine->getPoint2()->equals(&pointB) )
-                           {
-                              //A liegt auf jeden Fall drinnen, clipped line darf B nicht enthalten
-                              double distanceAB = pointA.getDistance(&pointB); //pointA to B
-                              double distanceAP = clippedLine->getLength();
-                              q = distanceAP/distanceAB;
-                           }
-                           else if(  this->geoObject3D->isPointInGbObject3D( pointB.getX1Coordinate()
-                                                                            ,pointB.getX2Coordinate()
-                                                                            ,pointB.getX3Coordinate()
-                                                                            ,pointIsOnBoundary )
-                                   && pointIsOnBoundary )
-                           {
-                              //A liegt auf jeden Fall drinnen, B liegt genau auf ObjektBoundary => q=1.0
-                              q=1.0;
-                           }
-                           else
-                           {
-                              q = 0.0;
-                           }
-                        }
-
-                        if(UbMath::inClosedInterval(q, 1.0, 1.0)) q = 1.0;
-                        if(UbMath::lessEqual(q, 1.0) && UbMath::greater(q, 0.0))
-                        {
-                           #pragma omp critical (BC_CHANGE)
-                           {
-                              bc = bcArray->getBC(ix1,ix2,ix3);
-                              if(!bc)
-                              {
-                                 //bc = bvd->createD3Q27BoundaryCondition(); //= new D3Q27BoundaryCondition();
-                                 bc = BoundaryConditionsPtr(new BoundaryConditions);
-                                 bcArray->setBC(ix1,ix2,ix3,bc);
-                              }
-                              for(int index=(int)bcAdapterVector.size()-1; index>=0; --index)
-                                 bcAdapterVector[index]->adaptBCForDirection(*this,bc,internX1,internX2,internX3,q,fdir,timestep);
-                           }
-                                          
-                           gotQs=true;
-                        }
-
-                        clippedLine->deletePoint1();
-                        clippedLine->deletePoint2();
-                        delete clippedLine;
-                     }
-                  }
-
-                  if(gotQs)
-                  {
-                     #pragma omp critical (TRANSNODE_SET_CHANGE)
-                     {
-                        oneEntryGotBC = true;
-
-                        std::vector<int> p(3);
-                        p[0]=ix1; p[1]=ix2; p[2]=ix3;
-                        transNodeIndices.insert(p);
-
-                        for(int index=(int)bcAdapterVector.size()-1; index>=0; --index)
-                           bcAdapterVector[index]->adaptBC(*this,bc,internX1,internX2,internX3,timestep);
-                     }
-                  }
-               }
-            }
-         }
-      }
-   }
-
-   return oneEntryGotBC;
-}
-//////////////////////////////////////////////////////////////////////////
-void D3Q27Interactor::addQsLineSet(std::vector<UbTupleFloat3 >& nodes, std::vector<UbTupleInt2 >& lines)
-{
-      BOOST_FOREACH(Block3DPtr block, bcBlocks)
-      {
-         if(!block) continue;
-
-         double         dx       = grid.lock()->getDeltaX(block);
-         UbTupleDouble3 orgDelta = grid.lock()->getNodeOffset(block);
-
-         LBMKernelPtr kernel = block->getKernel();
-         BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
-
-         map<Block3DPtr, set< std::vector<int> > >::iterator pos = bcNodeIndicesMap.find(block);
-         if(pos==bcNodeIndicesMap.end()) 
-         {
-            UB_THROW( UbException(UB_EXARGS,"block nicht in indizes map!!!") );
-         }
-         set< std::vector<int> >& transNodeIndicesSet = pos->second;
-         set< std::vector<int> >::iterator setPos;
-
-         std::size_t node1Index, node2Index;
-
-         UbTupleDouble3 blockOrg = grid.lock()->getBlockWorldCoordinates(block);
-
-         for(setPos=transNodeIndicesSet.begin(); setPos!=transNodeIndicesSet.end();  ++setPos)
-         {
-            int ix1 = (*setPos)[0];
-            int ix2 = (*setPos)[1];
-            int ix3 = (*setPos)[2];
-
-            if(bcArray->isFluid(ix1,ix2,ix3)) //es kann sein, dass der node von einem anderen interactor z.B. als solid gemarkt wurde!!!
-            {
-               if( !bcArray->hasBC(ix1,ix2,ix3) ) continue;
-               BoundaryConditionsPtr bc = bcArray->getBC(ix1,ix2,ix3);
-
-               double x1a = val<1>(blockOrg) - val<1>(orgDelta) + ix1 * dx;
-               double x2a = val<2>(blockOrg) - val<2>(orgDelta) + ix2 * dx;
-               double x3a = val<3>(blockOrg) - val<3>(orgDelta) + ix3 * dx;
-               nodes.push_back( makeUbTuple( (float)x1a, (float)x2a, (float)x3a ) );
-               node1Index = nodes.size()-1;
-
-               for(int dir = D3Q27System::FSTARTDIR; dir<=D3Q27System::FENDDIR; dir++)
-               {
-                  if (bc->hasBoundaryConditionFlag(D3Q27System::INVDIR[dir]))
-                  {
-                     double x1b, x2b, x3b, q = bc->getQ(dir);
-                     switch(dir)
-                     {
-                     case D3Q27System::E : x1b = x1a+q*dx; x2b = x2a         ; x3b = x3a         ; break;
-                     case D3Q27System::N : x1b = x1a         ; x2b = x2a+q*dx; x3b = x3a         ; break;
-                     case D3Q27System::W : x1b = x1a-q*dx; x2b = x2a         ; x3b = x3a         ; break;
-                     case D3Q27System::S : x1b = x1a         ; x2b = x2a-q*dx; x3b = x3a         ; break;
-                     case D3Q27System::NE: x1b = x1a+q*dx; x2b = x2a+q*dx; x3b = x3a         ; break;
-                     case D3Q27System::NW: x1b = x1a-q*dx; x2b = x2a+q*dx; x3b = x3a         ; break;
-                     case D3Q27System::SW: x1b = x1a-q*dx; x2b = x2a-q*dx; x3b = x3a         ; break;
-                     case D3Q27System::SE: x1b = x1a+q*dx; x2b = x2a-q*dx; x3b = x3a         ; break;
-                     case D3Q27System::T : x1b = x1a         ; x2b = x2a         ; x3b = x3a+q*dx; break;
-                     case D3Q27System::TE: x1b = x1a+q*dx; x2b = x2a         ; x3b = x3a+q*dx; break;
-                     case D3Q27System::TN: x1b = x1a         ; x2b = x2a+q*dx; x3b = x3a+q*dx; break;
-                     case D3Q27System::TW: x1b = x1a-q*dx; x2b = x2a         ; x3b = x3a+q*dx; break;
-                     case D3Q27System::TS: x1b = x1a         ; x2b = x2a-q*dx; x3b = x3a+q*dx; break;
-                     case D3Q27System::B : x1b = x1a         ; x2b = x2a         ; x3b = x3a-q*dx; break;
-                     case D3Q27System::BE: x1b = x1a+q*dx; x2b = x2a         ; x3b = x3a-q*dx; break;
-                     case D3Q27System::BN: x1b = x1a         ; x2b = x2a+q*dx; x3b = x3a-q*dx; break;
-                     case D3Q27System::BW: x1b = x1a-q*dx; x2b = x2a         ; x3b = x3a-q*dx; break;
-                     case D3Q27System::BS: x1b = x1a         ; x2b = x2a-q*dx; x3b = x3a-q*dx; break;
-                     case D3Q27System::TNE : x1b = x1a+q*dx  ; x2b = x2a+q*dx; x3b = x3a+q*dx; break;
-                     case D3Q27System::BSW : x1b = x1a-q*dx  ; x2b = x2a-q*dx; x3b = x3a-q*dx; break;
-                     case D3Q27System::BNE : x1b = x1a+q*dx  ; x2b = x2a+q*dx; x3b = x3a-q*dx; break;
-                     case D3Q27System::TSW : x1b = x1a-q*dx  ; x2b = x2a-q*dx; x3b = x3a+q*dx; break;
-                     case D3Q27System::TSE : x1b = x1a+q*dx  ; x2b = x2a-q*dx; x3b = x3a+q*dx; break;
-                     case D3Q27System::BNW : x1b = x1a-q*dx  ; x2b = x2a+q*dx; x3b = x3a-q*dx; break;
-                     case D3Q27System::BSE : x1b = x1a+q*dx  ; x2b = x2a-q*dx; x3b = x3a-q*dx; break;
-                     case D3Q27System::TNW : x1b = x1a-q*dx  ; x2b = x2a+q*dx; x3b = x3a+q*dx; break;
-                     default: throw UbException(UB_EXARGS,"unknown direction");
-                     }
-
-                     nodes.push_back( makeUbTuple( (float)x1b, (float)x2b, (float)x3b ) );
-                     node2Index = nodes.size()-1;
-
-                     lines.push_back( makeUbTuple( (int)node1Index, (int)node2Index) );
-                  }
-               }
-            }
-         }
-      }
-}
-////////////////////////////////////////////////////////////////////////////
-vector< pair<GbPoint3D,GbPoint3D> >  D3Q27Interactor::getQsLineSet()
-{
-   vector< pair<GbPoint3D,GbPoint3D> >  QsLineSet;
-   pair<GbPoint3D,GbPoint3D> pointpair;
-
-   UbTupleInt3 blocknx = grid.lock()->getBlockNX();
-
-   int blocknx1 = val<1>(blocknx);
-   int blocknx2 = val<2>(blocknx);
-   int blocknx3 = val<3>(blocknx);
-   //   vector<double> deltaT = grid->getD3Q27Calculator()->getDeltaT();
-
-   BOOST_FOREACH(Block3DPtr block, bcBlocks)
-   {
-      LBMKernelPtr kernel = block->getKernel();
-      BCArray3DPtr bcMatrix = kernel->getBCProcessor()->getBCArray();
-      UbTupleDouble3 nodeOffset   = grid.lock()->getNodeOffset(block);
-
-      //double collFactor = ((LbD3Q27Calculator*)grid->getCalculator())->getCollisionsFactors()[block->getLevel()];
-      //checken ob obere reihe doppelt im system vorhanden oder nicht
-      bool include_N_Face  = false; //x1=[0..blocknx1[ && x3=[0..blocknx3[
-      bool include_E_Face  = false; //x2=[0..blocknx2[ && x3=[0..blocknx3[
-      bool include_T_Face  = false; //x1=[0..blocknx1[ && x2=[0..blocknx2[
-      bool include_NE_Edge = false; //(x1/x2/x3)=(blocknx1/blocknx2/[0..blocknx3[)
-      bool include_TN_Edge = false; //(x1/x2/x3)=([0..blocknx1[/blocknx2/blocknx1)
-      bool include_TE_Edge = false; //(x1/x2/x3)=(blocknx1/[0..blocknx2[/blocknx2)
-      if(block)
-      {
-         if( !block->getConnector(D3Q27System::N ) ) include_N_Face  = true;
-         if( !block->getConnector(D3Q27System::E ) ) include_E_Face  = true;
-         if( !block->getConnector(D3Q27System::T ) ) include_T_Face  = true;
-         if( !block->getConnector(D3Q27System::NE) && include_N_Face && include_E_Face ) include_NE_Edge = true;
-         if( !block->getConnector(D3Q27System::TN) && include_T_Face && include_N_Face ) include_TN_Edge = true;
-         if( !block->getConnector(D3Q27System::TE) && include_T_Face && include_E_Face ) include_TE_Edge = true;
-      }
-
-      //      double dT = deltaT[block->getLevel()];
-
-      map<Block3DPtr, set< std::vector<int> > >::iterator pos = bcNodeIndicesMap.find(block);
-      if(pos==bcNodeIndicesMap.end()) throw UbException(UB_EXARGS,"block nicht in indizes map!!!"+block->toString());
-      set< std::vector<int> >& transNodeIndicesSet = pos->second;
-      set< std::vector<int> >::iterator setPos;
-
-      double x1,x2,x3,dx;
-      grid.lock()->calcStartCoordinatesAndDelta(block,x1,x2,x3,dx);
-
-      //cout<<"getQs: "<<transBlockSet->size()<<" "<<transNodeIndicesVec.size()<<endl;
-
-      for(setPos=transNodeIndicesSet.begin(); setPos!=transNodeIndicesSet.end();  ++setPos)
-      {
-         int ix1 = (*setPos)[0];
-         int ix2 = (*setPos)[1];
-         int ix3 = (*setPos)[2];
-
-         if(   ( ix1<blocknx1 && ix2<blocknx2 && ix3<blocknx3 ) //std fall
-            || ( include_E_Face  && ix1==blocknx1 && ix2<blocknx2  && ix3<blocknx3  )
-            || ( include_N_Face  && ix2==blocknx2 && ix1<blocknx1  && ix3<blocknx3  )
-            || ( include_T_Face  && ix3==blocknx3 && ix1<blocknx1  && ix2<blocknx2  )
-            || ( include_NE_Edge && ix1==blocknx1 && ix2==blocknx2 )
-            || ( include_TN_Edge && ix2==blocknx2 && ix3==blocknx3 )
-            || ( include_TE_Edge && ix1==blocknx1 && ix3==blocknx3 ) ) //ansonsten doppelt im kraftwert
-         {
-            if(bcMatrix->isFluid(ix1,ix2,ix3)) //es kann sein, dass der node von einem anderen interactor z.B. als solid gemarkt wurde!!!
-            {
-               if( !bcMatrix->hasBC(ix1,ix2,ix3) ) continue;
-               BoundaryConditionsPtr bc = bcMatrix->getBC(ix1,ix2,ix3);
-               double x1a = x1-val<1>(nodeOffset)+dx * ix1;
-               double x2a = x2-val<2>(nodeOffset)+dx * ix2;
-               double x3a = x3-val<3>(nodeOffset)+dx * ix3;
-               pointpair.first.setX1(x1a);
-               pointpair.first.setX2(x2a);
-               pointpair.first.setX3(x3a);
-               for(int dir = D3Q27System::FSTARTDIR; dir<=D3Q27System::FENDDIR; dir++)
-               {
-                  if (bc->hasBoundaryConditionFlag(D3Q27System::INVDIR[dir]))
-                  {
-                     double x1b, x2b, x3b, q = bc->getQ(dir);
-                     switch(dir)
-                     {
-                     case D3Q27System::E : x1b = x1a+q*dx; x2b = x2a         ; x3b = x3a         ; break;
-                     case D3Q27System::N : x1b = x1a         ; x2b = x2a+q*dx; x3b = x3a         ; break;
-                     case D3Q27System::W : x1b = x1a-q*dx; x2b = x2a         ; x3b = x3a         ; break;
-                     case D3Q27System::S : x1b = x1a         ; x2b = x2a-q*dx; x3b = x3a         ; break;
-                     case D3Q27System::NE: x1b = x1a+q*dx; x2b = x2a+q*dx; x3b = x3a         ; break;
-                     case D3Q27System::NW: x1b = x1a-q*dx; x2b = x2a+q*dx; x3b = x3a         ; break;
-                     case D3Q27System::SW: x1b = x1a-q*dx; x2b = x2a-q*dx; x3b = x3a         ; break;
-                     case D3Q27System::SE: x1b = x1a+q*dx; x2b = x2a-q*dx; x3b = x3a         ; break;
-                     case D3Q27System::T : x1b = x1a         ; x2b = x2a         ; x3b = x3a+q*dx; break;
-                     case D3Q27System::TE: x1b = x1a+q*dx; x2b = x2a         ; x3b = x3a+q*dx; break;
-                     case D3Q27System::TN: x1b = x1a         ; x2b = x2a+q*dx; x3b = x3a+q*dx; break;
-                     case D3Q27System::TW: x1b = x1a-q*dx; x2b = x2a         ; x3b = x3a+q*dx; break;
-                     case D3Q27System::TS: x1b = x1a         ; x2b = x2a-q*dx; x3b = x3a+q*dx; break;
-                     case D3Q27System::B : x1b = x1a         ; x2b = x2a         ; x3b = x3a-q*dx; break;
-                     case D3Q27System::BE: x1b = x1a+q*dx; x2b = x2a         ; x3b = x3a-q*dx; break;
-                     case D3Q27System::BN: x1b = x1a         ; x2b = x2a+q*dx; x3b = x3a-q*dx; break;
-                     case D3Q27System::BW: x1b = x1a-q*dx; x2b = x2a         ; x3b = x3a-q*dx; break;
-                     case D3Q27System::BS: x1b = x1a         ; x2b = x2a-q*dx; x3b = x3a-q*dx; break;
-                     case D3Q27System::TNE : x1b = x1a+q*dx  ; x2b = x2a+q*dx; x3b = x3a+q*dx; break;
-                     case D3Q27System::BSW : x1b = x1a-q*dx  ; x2b = x2a-q*dx; x3b = x3a-q*dx; break;
-                     case D3Q27System::BNE : x1b = x1a+q*dx  ; x2b = x2a+q*dx; x3b = x3a-q*dx; break;
-                     case D3Q27System::TSW : x1b = x1a-q*dx  ; x2b = x2a-q*dx; x3b = x3a+q*dx; break;
-                     case D3Q27System::TSE : x1b = x1a+q*dx  ; x2b = x2a-q*dx; x3b = x3a+q*dx; break;
-                     case D3Q27System::BNW : x1b = x1a-q*dx  ; x2b = x2a+q*dx; x3b = x3a-q*dx; break;
-                     case D3Q27System::BSE : x1b = x1a+q*dx  ; x2b = x2a-q*dx; x3b = x3a-q*dx; break;
-                     case D3Q27System::TNW : x1b = x1a-q*dx  ; x2b = x2a+q*dx; x3b = x3a+q*dx; break;
-                     default: throw UbException(UB_EXARGS,"unknown direction");
-                     }
-                     pointpair.second.setX1(x1b);
-                     pointpair.second.setX2(x2b);
-                     pointpair.second.setX3(x3b);
-                     QsLineSet.push_back(pointpair);
-                  }
-               }
-
-            }
-         }
-      }
-   }
-   //cout<<"getQs: "<<QsLineSet.size()<<endl;
-   return QsLineSet;
-}
-
-//////////////////////////////////////////////////////////////////////////
-void D3Q27Interactor::removeBoundaryInformationOnBcNodes()
-{
-//   if(this->reinitWithStoredQsFlag) return;
-//
-//   oldSolidBlockSet.clear();
-//   vector<Block3D*>& solidBlocks = *this->getSolidBlockSet();
-//   for(int i=0; i<(int)solidBlocks.size(); i++)
-//   {
-//      oldSolidBlockSet.push_back(solidBlocks[i]);
-//
-//      solidBlocks[i]->setActive(true); //<- quick n dirty
-//      D3Q27Block* bvd = (D3Q27Block*) solidBlocks[i]->getBlock();
-//      D3Q27BCMatrix<D3Q27BoundaryCondition>& bcMatrix = *bvd->getBcMatrix();
-//
-//      for(int ix1=bcMatrix->getNX1()-1; ix1>=0; ix1--)
-//         for(int ix2=bcMatrix->getNX2()-1; ix2>=0; ix2--)
-//            for(int ix3=bcMatrix->getNX3()-1; ix3>=0; ix3--)
-//               bcMatrix->setFluid(ix1,ix2,ix3);
-//   }
-//   //BC wird entfernt und node wird Fluid-Node
-//   oldSolidNodeIndicesMap.clear();
-//   for(int b=0; b<(int)transBlockSet->size(); b++)
-//   {
-//      Block3D*& block = (*transBlockSet)[b];
-//      D3Q27Block* bvd = (D3Q27Block*)block->getBlock();
-//      D3Q27BCMatrix<D3Q27BoundaryCondition>& bcMatrix = *bvd->getBcMatrix();
-//      map<Block3D*, set< UbTupleInt3 > >::iterator pos = transNodeIndicesMap.find(block);
-//      if(pos==transNodeIndicesMap.end()) throw UbException(UB_EXARGS,"block nicht in indizes map!!!");
-////new active node stuff//
-//      oldTransNodeIndicesMap[block] = set< UbTupleInt3LongLong >();
-//      set< UbTupleInt3LongLong >& oldTransNodeIndices = oldTransNodeIndicesMap[block];
-////new active node stuff//
-//      set< UbTupleInt3 >& transNodeIndicesSet = pos->second;
-//      set< UbTupleInt3 >::iterator setPos;
-//      for(setPos=transNodeIndicesSet.begin(); setPos!=transNodeIndicesSet.end();  ++setPos)
-//      {
-////new active node stuff//
-//         D3Q27BoundaryCondition* bc = bcMatrix->getBC(val<1>(*setPos),val<2>(*setPos),val<3>(*setPos));
-//         if(bc) oldTransNodeIndices.insert(UbTupleInt3LongLong(val<1>(*setPos),val<2>(*setPos),val<3>(*setPos), bc->getNoSlipBoundary()));
-//         else UBLOG(logDEBUG5,"Warum fehlt die BC?");
-////new active node stuff//
-//         bcMatrix->setFluid(val<1>(*setPos),val<2>(*setPos),val<3>(*setPos));
-//      }
-//      transNodeIndicesSet.clear();
-//
-//      map<Block3D*, set< UbTupleInt3 > >::iterator posSolid = solidNodeIndicesMap.find(block);
-//      if(posSolid==solidNodeIndicesMap.end()) throw UbException(UB_EXARGS,"block nicht in indizes map!!!");
-//
-////new active node stuff//
-//      oldSolidNodeIndicesMap[block] = set< UbTupleInt3 >();
-//      set< UbTupleInt3 >& oldSolidNodeIndices = oldSolidNodeIndicesMap[block];
-////new active node stuff//
-//
-//      set< UbTupleInt3 >& solidNodeIndicesSet = posSolid->second;
-//      //set< UbTupleInt3 >::iterator setPos;
-//      for(setPos=solidNodeIndicesSet.begin(); setPos!=solidNodeIndicesSet.end();  ++setPos)
-//      {
-//         oldSolidNodeIndices.insert(UbTupleInt3(val<1>(*setPos),val<2>(*setPos),val<3>(*setPos)));
-//         bcMatrix->setFluid(val<1>(*setPos),val<2>(*setPos),val<3>(*setPos));
-//      }
-//      solidNodeIndicesSet.clear();
-//   }
-//   transNodeIndicesMap.clear();
-//   solidNodeIndicesMap.clear();
-//
-//   this->removeTransBlocks();
-//   this->removeSolidBlocks();
-}
-//////////////////////////////////////////////////////////////////////////
-//void D3Q27Interactor::updateMovedGeometry(const double& timeStep)
-//{
-//   //*************quick n dirty***********
-//   //achtung stark vereinfacht, damit es ueberhaupt geht
-//   //zuvor musste fuer alle interactoren removeBoundaryInformationOnTransNodes aufgerufen werden
-//
-//   //alle notActive blocke active setzen und alle nodes als fluid
-//   //haut natuerlich nur hin, wenn kein block zwei interactoren hat...
-//   //nodes muessen zuvor initilaisiert sein, sonst geht goar nichts
-//
-//   //vector<Block3D*>& solidBlocks = *this->getSolidBlockSet();
-//   //for(int i=0; i<(int)solidBlocks.size(); i++)
-//   //{
-//   //   solidBlocks[i]->setActive(true); //<- quick n dirty
-//   //   D3Q27Block* bvd = (D3Q27Block*) solidBlocks[i]->getBlock();
-//   //   D3Q27BCMatrix<D3Q27BoundaryCondition>& bcMatrix = *bvd->getBcMatrix();
-//
-//   //   for(int ix1=bcMatrix->getNX1()-1; ix1>=0; ix1--)
-//   //      for(int ix2=bcMatrix->getNX2()-1; ix2>=0; ix2--)
-//   //         for(int ix3=bcMatrix->getNX3()-1; ix3>=0; ix3--)
-//   //            bcMatrix->setFluid(ix1,ix2,ix3);
-//   //}
-//
-//   //vector<Block3D*>& transBlocks = *this->getTransBlockSet();
-//   //for(int i=0; i<(int)transBlocks.size(); i++)
-//   //{
-//   //   transBlocks[i]->setActive(true); //<- quick n dirty
-//   //   D3Q27Block* bvd = (D3Q27Block*) transBlocks[i]->getBlock();
-//   //   D3Q27BCMatrix<D3Q27BoundaryCondition>& bcMatrix = *bvd->getBcMatrix();
-//
-//   //   for(int ix1=bcMatrix->getNX1()-1; ix1>=0; ix1--)
-//   //      for(int ix2=bcMatrix->getNX2()-1; ix2>=0; ix2--)
-//   //         for(int ix3=bcMatrix->getNX3()-1; ix3>=0; ix3--)
-//   //            bcMatrix->setFluid(ix1,ix2,ix3);
-//   //}
-//
-//   //komplett neu initialisieren
-//   //1. velcBC aktualisieren
-//   bool hasVelBC = false;
-//   for(int index=(int)bcAdapterVector.size()-1; index>=0; --index)
-//   {
-//      D3Q27VelocityBCAdapter* velBC = dynamic_cast<D3Q27VelocityBCAdapter*>(bcAdapterVector[index].get());
-//      if(velBC)
-//      {
-//         velBC->setNewVelocities(this->getVelocityX1(),0,D3Q27BCFunction::INFCONST,
-//                                 this->getVelocityX2(),0,D3Q27BCFunction::INFCONST,
-//                                 this->getVelocityX3(),0,D3Q27BCFunction::INFCONST );
-//         hasVelBC = true; 
-//      }
-//   }
-//   if(!hasVelBC) throw UbException(UB_EXARGS,"movingInteractors MUESSEN velBC besitzen");
-//
-//   //2. einfach nochmal initialisieren
-//   D3Q27Interactor::initInteractor(timeStep);  //damit nicht die BCs wieder initialisert werden
-//   this->updateNewNodes();
-//}
-////////////////////////////////////////////////////////////////////////////
-//void D3Q27Interactor::updateNewNodes()
-//{
-//   if(!grid) throw UbException(UB_EXARGS,"no grid");
-//
-////new active node stuff//
-//   std::map<Block3D*, std::set< UbTupleInt3 > > newFluidNodeIndicesMap;
-//   for(size_t i=0; i<this->oldSolidBlockSet.size(); i++)
-//   {
-//      Block3D* oldsolidblock = oldSolidBlockSet[i];
-//      for(size_t b=0; b<transBlockSet->size(); b++)
-//      {
-//         Block3D* block = (*transBlockSet)[b];
-//         if(oldsolidblock==block)
-//         {
-//            newFluidNodeIndicesMap[block] = set< UbTupleInt3 >();
-//            set< UbTupleInt3 >& newFluidNodeIndices = newFluidNodeIndicesMap[block];
-//
-//            D3Q27Block* bvd = dynamic_cast<D3Q27Block*>(block->getBlock());
-//            if(!bvd) throw UbException(UB_EXARGS,"kein D3Q27Block");
-//            D3Q27BCMatrix<D3Q27BoundaryCondition>& bcMatrix = *bvd->getBcMatrix();
-//
-//            for(int ix1=bcMatrix->getNX1()-1; ix1>=0; ix1--)
-//               for(int ix2=bcMatrix->getNX2()-1; ix2>=0; ix2--)
-//                  for(int ix3=bcMatrix->getNX3()-1; ix3>=0; ix3--)
-//                     if(bcMatrix->isFluid(ix1,ix2,ix3))
-//                        newFluidNodeIndices.insert(UbTupleInt3(ix1,ix2,ix3));
-//            //continue; <-HAEH an Geller: wozu das continue? kam da frueher noch was?
-//         }
-//      }
-//   }
-//
-//   std::map<Block3D*, std::set< UbTupleInt3 > >::iterator oldsolidpos;
-//   for(oldsolidpos=oldSolidNodeIndicesMap.begin(); oldsolidpos!=oldSolidNodeIndicesMap.end();  ++oldsolidpos)
-//   {
-//      Block3D* block = oldsolidpos->first;
-//
-//      map<Block3D*, set< UbTupleInt3 > >::iterator pos = transNodeIndicesMap.find(block);
-//      //wenn ein Block ein Solid hatte sollte er in der TransBlockListe sein
-//      //es sei denn der Block hat jetzt alle Solid und ist somit bei den SolidBl�cken
-//      if(pos==transNodeIndicesMap.end()) 
-//         continue;
-//         //throw UbException(UB_EXARGS,"block nicht in indizes map!!!");
-//
-//      set< UbTupleInt3 >& transNodeIndicesSet = pos->second;
-//      set< UbTupleInt3 >& oldSolidIndicesSet = oldsolidpos->second;
-//      set< UbTupleInt3 >::iterator setPos1;
-//      set< UbTupleInt3 >::iterator setPos2;
-//
-//      for(setPos1=oldSolidIndicesSet.begin(); setPos1!=oldSolidIndicesSet.end();  ++setPos1)
-//      {
-//         int osix1 = val<1>(*setPos1);
-//         int osix2 = val<2>(*setPos1);
-//         int osix3 = val<3>(*setPos1);
-//         for(setPos2=transNodeIndicesSet.begin(); setPos2!=transNodeIndicesSet.end();  ++setPos2)
-//         {
-//            int tix1 = val<1>(*setPos2);
-//            int tix2 = val<2>(*setPos2);
-//            int tix3 = val<3>(*setPos2);
-//            if((osix1==tix1) && (osix2==tix2) && (osix3==tix3))
-//            {
-//               map<Block3D*, set< UbTupleInt3 > >::iterator posX = newFluidNodeIndicesMap.find(block);
-//               if(posX==newFluidNodeIndicesMap.end()) newFluidNodeIndicesMap[block] = set< UbTupleInt3 >();
-//
-//               set< UbTupleInt3 >& newFluidNodeIndices = newFluidNodeIndicesMap[block];
-//               newFluidNodeIndices.insert(UbTupleInt3(tix1,tix2,tix3));
-//            }
-//         }
-//      }
-//   }
-////hier wird gepr�ft ob ein Randknoten die Seite wechselt
-//   std::map<Block3D*, std::set< UbTupleInt3LongLong > >::iterator oldtranspos;
-//   for(oldtranspos=oldTransNodeIndicesMap.begin(); oldtranspos!=oldTransNodeIndicesMap.end();  ++oldtranspos)
-//   {
-//      Block3D* block = oldtranspos->first;
-//
-//      map<Block3D*, set< UbTupleInt3 > >::iterator pos = transNodeIndicesMap.find(block);
-//      //wenn ein Block ein Solid hatte sollte er in der TransBlockListe sein
-//      //es sei denn der Block hat jetzt alle Solid und ist somit bei den SolidBl�cken
-//      if(pos==transNodeIndicesMap.end()) 
-//         continue;
-//      //throw UbException(UB_EXARGS,"block nicht in indizes map!!!");
-//
-//      set< UbTupleInt3 >&        transNodeIndicesSet = pos->second;
-//      set< UbTupleInt3LongLong >& oldTransIndicesSet = oldtranspos->second;
-//      set< UbTupleInt3LongLong >::iterator setPos1;
-//      set< UbTupleInt3 >::iterator setPos2;
-//
-//      D3Q27Block* bvd = dynamic_cast<D3Q27Block*>(block->getBlock());
-//      D3Q27BCMatrix<D3Q27BoundaryCondition>& bcMatrix = *bvd->getBcMatrix();
-//
-//      for(setPos1=oldTransIndicesSet.begin(); setPos1!=oldTransIndicesSet.end();  ++setPos1)
-//      {
-//         int osix1 = val<1>(*setPos1);
-//         int osix2 = val<2>(*setPos1);
-//         int osix3 = val<3>(*setPos1);
-//         for(setPos2=transNodeIndicesSet.begin(); setPos2!=transNodeIndicesSet.end();  ++setPos2)
-//         {
-//            int tix1 = val<1>(*setPos2);
-//            int tix2 = val<2>(*setPos2);
-//            int tix3 = val<3>(*setPos2);
-//            if((osix1==tix1) && (osix2==tix2) && (osix3==tix3))
-//            {
-//               long long oldNoSlipBoundary = val<4>(*setPos1);
-//               D3Q27BoundaryCondition* bc = bcMatrix->getBC(tix1,tix2,tix3);
-//               long long newNoSlipBoundary = bc->getNoSlipBoundary();
-//
-//               if(oldNoSlipBoundary==newNoSlipBoundary) continue;
-//               bool newNode = false;
-//               for(int fdir=D3Q27System::STARTF; fdir<=D3Q27System::ENDF; fdir++)
-//               {
-//                  int invDir = D3Q27System::getInvertDirection(fdir);
-//                  //vom 2D code
-//                  //if(((oldNoSlipBoundary&(1<<fdir))==(1<<fdir)) && ((newNoSlipBoundary&(1<<invDir))==(1<<invDir)))
-//                  //{
-//                  //   if((oldNoSlipBoundary&(1<<invDir))==(1<<invDir)) continue;
-//                  //   newNode = true;
-//                  //}
-//                  if((((oldNoSlipBoundary>>(D3Q27BoundaryCondition::optionDigits*fdir)) & D3Q27BoundaryCondition::maxOptionVal) != 0)  
-//                   &&(((newNoSlipBoundary>>(D3Q27BoundaryCondition::optionDigits*invDir)) & D3Q27BoundaryCondition::maxOptionVal) != 0))
-//                  {
-//                     if(((oldNoSlipBoundary>>(D3Q27BoundaryCondition::optionDigits*invDir)) & D3Q27BoundaryCondition::maxOptionVal) != 0) continue;
-//                     newNode = true;
-//                  }
-//               }
-//               if(newNode)
-//               {
-//                  map<Block3D*, set< UbTupleInt3 > >::iterator posX = newFluidNodeIndicesMap.find(block);
-//                  if(posX==newFluidNodeIndicesMap.end()) newFluidNodeIndicesMap[block] = set< UbTupleInt3 >();
-//
-//                  set< UbTupleInt3 >& newFluidNodeIndices = newFluidNodeIndicesMap[block];
-//                  newFluidNodeIndices.insert(UbTupleInt3(tix1,tix2,tix3));
-//               }
-//            }
-//         }
-//      }
-//   }
-////<hier wird gepr�ft ob ein Randknoten die Seite wechselt
-//
-//   //cout<<"newFluidNodeIndicesMap:"<<newFluidNodeIndicesMap.size()<<endl;
-//   std::map<Block3D*, std::set< UbTupleInt3 > >::iterator newfluidpos;
-//   D3Q27PatchGrid* grid = dynamic_cast<D3Q27PatchGrid*>(this->grid);
-//   for(newfluidpos=newFluidNodeIndicesMap.begin(); newfluidpos!=newFluidNodeIndicesMap.end();  ++newfluidpos)
-//   {
-//      Block3D* block = newfluidpos->first;
-//      D3Q27Block* bvd = dynamic_cast<D3Q27Block*>(block->getBlock());
-//      if(!bvd) throw UbException(UB_EXARGS,"kein D3Q27Block");
-//      bvd->getTimer().start();
-//
-//      set< UbTupleInt3 >& newNodes = newfluidpos->second;
-//      UBLOGML(logDEBUG4,"\n set-size:"<<newNodes.size());
-//      bvd->makeInternalIterations(grid,block->getLevel(),newNodes);
-//
-//      bvd->getTimer().stop();
-//
-//   }
-//   //end new active node stuff//
-//}
-////////////////////////////////////////////////////////////////////////////
-//UbTupleDouble3 D3Q27Interactor::getForces()
-//{
-//   D3Q27PatchGrid* grid = dynamic_cast<D3Q27PatchGrid*>(this->grid);
-//   if(!grid) throw UbException(UB_EXARGS,"grid is not a D3Q27PatchGrid");
-//
-//   int blocknx1 = grid->getBlockNX1();
-//   int blocknx2 = grid->getBlockNX2();
-//   int blocknx3 = grid->getBlockNX3();
-//   vector<double> deltaT = grid->getD3Q27Calculator()->getDeltaT();
-//
-//   double forceX1=0.0, forceX2=0.0, forceX3=0.0;
-//
-//   //!!// for(size_t b=0; b<transBlockSet->size(); b++)
-//   //!!// {
-//   //!!//    Block3D*& block = (*transBlockSet)[b];
-//
-//   std::map<Block3D*, std::set< UbTupleInt3 > >::iterator pos;
-//   for ( pos=transNodeIndicesMap.begin() ; pos != transNodeIndicesMap.end(); pos++ )
-//   {
-//      Block3D* block = pos->first;
-//      
-//      if( block->isNotActive() ) 
-//      {
-//         continue;
-//      }
-//      
-//      D3Q27Block* bvd = (D3Q27Block*)block->getBlock();
-//      D3Q27BCMatrix<D3Q27BoundaryCondition>& bcMatrix = *bvd->getBcMatrix();
-//
-//      //pruefen ob obere reihe doppelt im system vorhanden oder nicht
-//      //ACHTUNG: so macht es probleme bei bloecken unterschiedlicher Leveltiefe
-//      bool include_N_Face  = false; //x1=[0..blocknx1[ && x3=[0..blocknx3[
-//      bool include_E_Face  = false; //x2=[0..blocknx2[ && x3=[0..blocknx3[
-//      bool include_T_Face  = false; //x1=[0..blocknx1[ && x2=[0..blocknx2[
-//      bool include_NE_Edge = false; //(x1/x2/x3)=(blocknx1/blocknx2/[0..blocknx3[)
-//      bool include_TN_Edge = false; //(x1/x2/x3)=([0..blocknx1[/blocknx2/blocknx1)
-//      bool include_TE_Edge = false; //(x1/x2/x3)=(blocknx1/[0..blocknx2[/blocknx2)
-//      if( !bvd->getConnector(D3Q27System::N ) ) include_N_Face  = true;
-//      if( !bvd->getConnector(D3Q27System::E ) ) include_E_Face  = true;
-//      if( !bvd->getConnector(D3Q27System::T ) ) include_T_Face  = true;
-//      if( !bvd->getConnector(D3Q27System::NE) && include_N_Face && include_E_Face ) include_NE_Edge = true;
-//      if( !bvd->getConnector(D3Q27System::TN) && include_T_Face && include_N_Face ) include_TN_Edge = true;
-//      if( !bvd->getConnector(D3Q27System::TE) && include_T_Face && include_E_Face ) include_TE_Edge = true;
-//
-//      if( (int)deltaT.size()<=block->getLevel() )
-//         throw UbException(UB_EXARGS, "ups, no deltaT for that level... delta not initialized in grid?");
-//      double dT = deltaT[block->getLevel()];
-//
-//  //!!// map<Block3D*, set< UbTupleInt3 > >::iterator pos = transNodeIndicesMap.find(block);
-//      if(pos==transNodeIndicesMap.end()) throw UbException(UB_EXARGS,"block nicht in indizes map!!!"+block->toString());
-//      set< UbTupleInt3 >& transNodeIndicesSet = pos->second;
-//      set< UbTupleInt3 >::iterator setPos;
-//      for(setPos=transNodeIndicesSet.begin(); setPos!=transNodeIndicesSet.end();  ++setPos)
-//      {
-//         int x1 = val<1>(*setPos);
-//         int x2 = val<2>(*setPos);
-//         int x3 = val<3>(*setPos);
-//
-//         if(   ( x1<blocknx1 && x2<blocknx2 && x3<blocknx3 ) //std fall
-//            || ( include_E_Face  && x1==blocknx1 && x2<blocknx2  && x3<blocknx3  )
-//            || ( include_N_Face  && x2==blocknx2 && x1<blocknx1  && x3<blocknx3  )
-//            || ( include_T_Face  && x3==blocknx3 && x1<blocknx1  && x2<blocknx2  )
-//            || ( include_NE_Edge && x1==blocknx1 && x2==blocknx2 )
-//            || ( include_TN_Edge && x2==blocknx2 && x3==blocknx3 )
-//            || ( include_TE_Edge && x1==blocknx1 && x3==blocknx3 ) ) //ansonsten doppelt im kraftwert
-//         {
-//            if(bcMatrix->isFluid(x1,x2,x3)) //es kann sein, dass der node von einem anderen interactor z.B. als solid gemarkt wurde!!!
-//            {
-//               UbTupleDouble3 forceVec = bvd->getForces(x1,x2,x3,dT);
-//               forceX1 += val<1>(forceVec);
-//               forceX2 += val<2>(forceVec);
-//               forceX3 += val<3>(forceVec);
-//            }
-//         }
-//      }
-//   }
-//   // Bisher wurde die Reaktionskraft der geometrie berechnet,
-//   // Kraft des Fluids ist entgegengesetzt gleich gross -> return -force
-//   return UbTupleDouble3(-forceX1,-forceX2,-forceX3);
-//}
-////////////////////////////////////////////////////////////////////////////
-//string D3Q27Interactor::toString()
-//{
-//   stringstream ss;
-//   ss<< "Interactor3D[label="<<this->getName();
-//   if(this->isSolid()) ss<<", solid";
-//   if(this->isInverseSolid()) ss<<", inversesolid";
-//   if(this->isTimeDependent()) ss<<", timedependent";
-//   if(geoObject3D!=NULL) ss<<", Interactor3D: "<<geoObject3D->toString();
-//   ss<<"]";
-//
-//   return ss.str();
-//}
-////////////////////////////////////////////////////////////////////////////
-//void D3Q27Interactor::write(UbFileOutput* out)
-//{
-//   Interactor3D::write(out);
-//   out->writeLine();
-//
-//   out->writeString("D3Q27InteractorBCAdapter");
-//   out->writeInteger((int)bcAdapterVector.size());
-//   for(int i=0; i<(int)bcAdapterVector.size(); i++)
-//   {
-//      out->writeLine();
-//      bcAdapterVector[i]->write(out);
-//   }
-//}
-//////////////////////////////////////////////////////////////////////////
-//void D3Q27Interactor::read(UbFileInput* in)
-//{
-//   this->initRayVectors();
-//   transNodeIndicesMap.clear();
-//
-//   Interactor3D::read(in);
-//   in->readLine();
-//
-//   in->readString();
-//   bcAdapterVector.resize(in->readInteger(),MbSmartPtr<D3Q27BoundaryConditionAdapter>(NULL));
-//   for(int i=0; i<(int)bcAdapterVector.size(); i++)
-//   {
-//      in->readLine();
-//      bcAdapterVector[i] = MbSmartPtr<D3Q27BoundaryConditionAdapter>(D3Q27BCAdapterFactory::getInstance()->createD3Q27BCAdapter(in));
-//   }
-//}
-//////////////////////////////////////////////////////////////////////////
-void D3Q27Interactor::writeValidationAVSFile(string filename)
-{
-   UBLOG(logINFO,"D3Q27Interactor::writeValidationAVSFile("<<filename<<") - start ");
-   ofstream out(filename.c_str(),ios::out);
-   if(!out) throw UbException(UB_EXARGS,"couldn't open file "+filename);
-
-   int numpoints, numlines;
-   vector< pair<GbPoint3D,GbPoint3D> > qsLineSet = this->getQsLineSet();
-   numlines  = (unsigned)qsLineSet.size();
-   numpoints = numlines*2;
-
-   out<<"# UCD-File created by D3Q27Interactor\n";
-   out<<numpoints<<" "<<numlines<<" 0 0 0 "<<endl;
-   int nr=1;
-   for (int i=0; i<numlines; i++)
-   {
-      out<<nr++<<" "<<qsLineSet[i].first.getX1Coordinate() <<" " <<qsLineSet[i].first.getX2Coordinate() <<" " <<qsLineSet[i].first.getX3Coordinate() <<" \n";
-      out<<nr++<<" "<<qsLineSet[i].second.getX1Coordinate()<<" " <<qsLineSet[i].second.getX2Coordinate()<<" " <<qsLineSet[i].second.getX3Coordinate() <<" \n";
-   }
-   nr = 1;
-   for (int i=0; i<numlines; i++)
-   {
-      int el = nr+1;
-      out<<i+1<<" "<<2<<" line "<<nr<<" "<<el<<" "<<endl;
-      nr=el+1;
-   }
-   UBLOG(logINFO,"D3Q27Interactor::writeValidationAVSFile("<<filename<<") - end");
-}
-//////////////////////////////////////////////////////////////////////////
-//string D3Q27Interactor::writeTransNodes(string filename)
-//{
-//   D3Q27PatchGrid* grid = dynamic_cast<D3Q27PatchGrid*>(this->grid);
-//   if(!grid) throw UbException(UB_EXARGS,"grid is not a D3Q27PatchGrid");
-//
-//   int blocknx1 = grid->getBlockNX1();
-//   int blocknx2 = grid->getBlockNX2();
-//   int blocknx3 = grid->getBlockNX3();
-//
-//   vector< UbTupleFloat3 > nodes;
-//   vector< string > datanames;
-//   datanames.push_back("rho");
-//   datanames.push_back("vx1");
-//   datanames.push_back("vx2");
-//   datanames.push_back("vx3");
-//   vector< vector < double > > nodedata(datanames.size());
-//
-//   double orgX1,orgX2,orgX3,deltaX;
-//
-//   for(size_t b=0; b<transBlockSet->size(); b++)
-//   {
-//      Block3D*& block = (*transBlockSet)[b];
-//
-//      map<Block3D*, set< UbTupleInt3 > >::iterator pos = transNodeIndicesMap.find(block);
-//      if(pos==transNodeIndicesMap.end()) throw UbException(UB_EXARGS,"block nicht in indizes map!!!"+block->toString());
-//
-//      D3Q27Block* bvd = (D3Q27Block*)block->getBlock();
-//      D3Q27BCMatrix<D3Q27BoundaryCondition>& bcMatrix = *bvd->getBcMatrix();
-//      D3Q27DistributionsMatrix&              fMatrix  = *bvd->getDistributionMatrix();
-//      
-//      grid->calcStartCoordinatesAndDelta(block,orgX1,orgX2,orgX3,deltaX);
-//
-//      bool include_N_Face  = false; //x1=[0..blocknx1[ && x3=[0..blocknx3[
-//      bool include_E_Face  = false; //x2=[0..blocknx2[ && x3=[0..blocknx3[
-//      bool include_T_Face  = false; //x1=[0..blocknx1[ && x2=[0..blocknx2[
-//      bool include_NE_Edge = false; //(x1/x2/x3)=(blocknx1/blocknx2/[0..blocknx3[)
-//      bool include_TN_Edge = false; //(x1/x2/x3)=([0..blocknx1[/blocknx2/blocknx1)
-//      bool include_TE_Edge = false; //(x1/x2/x3)=(blocknx1/[0..blocknx2[/blocknx2)
-//      if( !bvd->getConnector(D3Q27System::N ) ) include_N_Face  = true;
-//      if( !bvd->getConnector(D3Q27System::E ) ) include_E_Face  = true;
-//      if( !bvd->getConnector(D3Q27System::T ) ) include_T_Face  = true;
-//      if( !bvd->getConnector(D3Q27System::NE) && include_N_Face && include_E_Face ) include_NE_Edge = true;
-//      if( !bvd->getConnector(D3Q27System::TN) && include_T_Face && include_N_Face ) include_TN_Edge = true;
-//      if( !bvd->getConnector(D3Q27System::TE) && include_T_Face && include_E_Face ) include_TE_Edge = true;
-//      
-//      set< UbTupleInt3 >& transNodeIndicesSet = pos->second;
-//      set< UbTupleInt3 >::iterator setPos;
-//
-//      for(setPos=transNodeIndicesSet.begin(); setPos!=transNodeIndicesSet.end();  ++setPos)
-//      {
-//         int ix1 = val<1>(*setPos);
-//         int ix2 = val<2>(*setPos);
-//         int ix3 = val<3>(*setPos);
-//         if(   ( ix1<blocknx1 && ix2<blocknx2 && ix3<blocknx3 ) //std fall
-//            || ( include_E_Face  && ix1==blocknx1 && ix2<blocknx2  && ix3<blocknx3  )
-//            || ( include_N_Face  && ix2==blocknx2 && ix1<blocknx1  && ix3<blocknx3  )
-//            || ( include_T_Face  && ix3==blocknx3 && ix1<blocknx1  && ix2<blocknx2  )
-//            || ( include_NE_Edge && ix1==blocknx1 && ix2==blocknx2 )
-//            || ( include_TN_Edge && ix2==blocknx2 && ix3==blocknx3 )
-//            || ( include_TE_Edge && ix1==blocknx1 && ix3==blocknx3 ) ) //ansonsten doppelt im kraftwert
-//         {
-//            if(bcMatrix->isFluid(ix1,ix2,ix3)) //es kann sein, dass der node von einem anderen interactor z.B. als solid gemarkt wurde!!!
-//            {
-//               nodes.push_back(makeUbTuple(  float( orgX1 + ix1 * deltaX )
-//                                           , float( orgX2 + ix2 * deltaX )
-//                                           , float( orgX3 + ix3 * deltaX ) ));
-//
-//               if(grid->getCollisionModel()!=D3Q27System::UNDEFINED)
-//               {
-//                  LBMReal* f = fMatrix.getStartAdressOfSortedArray(ix1,ix2,ix3,0);
-//                  nodedata[0].push_back( D3Q27System::getDensity(f) );
-//
-//                  if(D3Q27System::isCompModel(grid->getCollisionModel()))
-//                  {
-//                     nodedata[1].push_back( D3Q27System::getCompVelocityX1(f) );
-//                     nodedata[2].push_back( D3Q27System::getCompVelocityX2(f) );
-//                     nodedata[3].push_back( D3Q27System::getCompVelocityX3(f) );
-//                  }
-//                  else
-//                  {
-//                     nodedata[1].push_back( D3Q27System::getIncompVelocityX1(f) );
-//                     nodedata[2].push_back( D3Q27System::getIncompVelocityX2(f) );
-//                     nodedata[3].push_back( D3Q27System::getIncompVelocityX3(f) );
-//                  }
-//
-//               }
-//            }
-//         }
-//      }
-//   }
-//
-//   if( nodedata[0].empty() ) 
-//      return WbWriterVtkXmlBinary::getInstance()->writeNodes(filename,nodes);
-//   
-//   return WbWriterVtkXmlBinary::getInstance()->writeNodesWithNodeData(filename,nodes,datanames,nodedata);
-//}
-//////////////////////////////////////////////////////////////////////////
-//string D3Q27Interactor::writeTransNodesAsTriangles(string filename)
-//{
-   //D3Q27PatchGrid* grid = dynamic_cast<D3Q27PatchGrid*>(this->grid);
-   //if(!grid) throw UbException(UB_EXARGS,"grid is not a D3Q27PatchGrid");
-
-   //int blocknx1 = grid->getBlockNX1();
-   //int blocknx2 = grid->getBlockNX2();
-   //int blocknx3 = grid->getBlockNX3();
-
-   //vector< UbTupleFloat3 > nodes;
-   //vector< UbTupleInt3 >   triangles;
-   //vector< string >        datanames;
-   //datanames.push_back("rho");
-   //datanames.push_back("vx1");
-   //datanames.push_back("vx2");
-   //datanames.push_back("vx3");
-   //vector< vector < double > > nodedata(datanames.size());
-
-   //double orgX1,orgX2,orgX3,deltaX;
-   //int counter=0;
-
-   //for(size_t b=0; b<transBlockSet->size(); b++)
-   //{
-   //   Block3D*& block = (*transBlockSet)[b];
-
-   //   map<Block3D*, set< UbTupleInt3 > >::iterator pos = transNodeIndicesMap.find(block);
-   //   if(pos==transNodeIndicesMap.end()) throw UbException(UB_EXARGS,"block not in indices map!!!"+block->toString());
-
-   //   D3Q27Block* bvd = (D3Q27Block*)block->getBlock();
-   //   D3Q27BCMatrix<D3Q27BoundaryCondition>& bcMatrix = *bvd->getBcMatrix();
-   //   D3Q27DistributionsMatrix&              fMatrix  = *bvd->getDistributionMatrix();
-
-   //   grid->calcStartCoordinatesAndDelta(block,orgX1,orgX2,orgX3,deltaX);
-
-   //   set< UbTupleInt3 >& transNodeIndicesSet = pos->second;
-   //   set< UbTupleInt3 >::iterator setPos;
-   //   CbUniformMatrix3D<float> bcs(bcMatrix->getNX1(),bcMatrix->getNX2(),bcMatrix->getNX3(),0.0f);
-
-   //   for(setPos=transNodeIndicesSet.begin(); setPos!=transNodeIndicesSet.end();  ++setPos)
-   //   {
-   //      int ix1 = val<1>(*setPos);
-   //      int ix2 = val<2>(*setPos);
-   //      int ix3 = val<3>(*setPos);
-
-   //      if(bcMatrix->isFluid(ix1,ix2,ix3)) //es kann sein, dass der node von einem anderen interactor z.B. als solid gemarkt wurde!!!
-   //      {
-   //         bcs(ix1,ix2,ix3) = 1.0f;
-   //      }
-   //   }
-
-   //   //////////////////////////////////////////////////////////////////////////
-   //   //MC (Dreicksgenerierung)
-   //   //////////////////////////////////////////////////////////////////////////
-   //   typedef McCubes::Matrix3DWrapper< CbUniformMatrix3D<float> > McMatrixWrapper;
-   //   typedef McCubes::MarchingCubes< McMatrixWrapper >            McMarchingCubesGenerator;
-   //   typedef McMarchingCubesGenerator::Vertex                     McVertex;
-   //   typedef McMarchingCubesGenerator::Triangle                   McTriangle;
-
-   //   McMatrixWrapper wrapper(&bcs);
-   //   McMarchingCubesGenerator mc(wrapper);
-
-   //   mc.set_method(true);
-   //   mc.init_all();
-   //   mc.run(1.0f);
-
-   //   const int   nofVertices  = mc.nverts();
-   //   McVertex*   mcvertices   = mc.vertices();
-   //   const int   nofTriangles = mc.ntrigs();
-   //   McTriangle* mctriangles  = mc.triangles();
-
-   //   for(int n=0; n<nofVertices; n++)
-   //   {
-   //      //Da Dreickspunkte hie rper DDefinitionauf den LB-Knoten liegen sollen
-   //      //entsprichen die Knotenkoordinaten den Matrixindizes
-   //      int ix1 = (int)(mcvertices[n].x+0.5);
-   //      int ix2 = (int)(mcvertices[n].y+0.5);
-   //      int ix3 = (int)(mcvertices[n].z+0.5);
-   //      
-   //      nodes.push_back( makeUbTuple(  (float)(orgX1 + deltaX * ix1)    
-   //                                   , (float)(orgX2 + deltaX * ix2)
-   //                                   , (float)(orgX3 + deltaX * ix3) ) );
-
-   //      if(grid->getCollisionModel()!=D3Q27System::UNDEFINED)
-   //      {
-   //         LBMReal* f = fMatrix.getStartAdressOfSortedArray(ix1,ix2,ix3,0);
-   //         nodedata[0].push_back( D3Q27System::getDensity(f) );
-
-   //         if(D3Q27System::isCompModel(grid->getCollisionModel()))
-   //         {
-   //            nodedata[1].push_back( D3Q27System::getCompVelocityX1(f) );
-   //            nodedata[2].push_back( D3Q27System::getCompVelocityX2(f) );
-   //            nodedata[3].push_back( D3Q27System::getCompVelocityX3(f) );
-   //         }
-   //         else
-   //         {
-   //            nodedata[1].push_back( D3Q27System::getIncompVelocityX1(f) );
-   //            nodedata[2].push_back( D3Q27System::getIncompVelocityX2(f) );
-   //            nodedata[3].push_back( D3Q27System::getIncompVelocityX3(f) );
-   //         }
-   //      }
-   //   }
-   //   for(int t=0; t<nofTriangles; t++)
-   //      triangles.push_back( makeUbTuple( mctriangles[t].v1+counter, mctriangles[t].v2+counter, mctriangles[t].v3+counter ) );
-
-   //   counter+=nofVertices;
-   //}
-
-   //if( nodedata[0].empty() ) 
-   //   return WbWriterVtkXmlBinary::getInstance()->writeTriangles(filename,nodes,triangles);
-
-   //return WbWriterVtkXmlBinary::getInstance()->writeTrianglesWithNodeData(filename,nodes,triangles,datanames,nodedata);
-//}
+#include "D3Q27Interactor.h"
+#include <basics/utilities/UbMath.h>
+#include <basics/utilities/UbLogger.h>
+
+#include <basics/writer/WbWriterVtkXmlBinary.h>
+
+#include <numerics/geometry3d/GbCuboid3D.h>
+#include <numerics/geometry3d/GbLine3D.h>
+#include "Block3D.h"
+#include "Grid3D.h"
+#include "BCArray3D.h"
+#include "BoundaryConditions.h"
+#include "LBMKernel.h"
+#include "BCProcessor.h"
+#include "BCAdapter.h"
+
+//#include <3rdParty/MarchingCubes/MarchingCubes.h>
+
+
+
+
+using namespace std;
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+D3Q27Interactor::D3Q27Interactor() : Interactor3D()
+{
+   this->reinitWithStoredQsFlag = false;
+   this->initRayVectors();
+}
+//////////////////////////////////////////////////////////////////////////
+D3Q27Interactor::D3Q27Interactor(GbObject3DPtr geoObject3D, Grid3DPtr grid, int type)
+: Interactor3D(geoObject3D, grid, type), relevantForForces(false)
+{
+   this->reinitWithStoredQsFlag = false;
+   this->initRayVectors();
+}
+//////////////////////////////////////////////////////////////////////////
+D3Q27Interactor::D3Q27Interactor(GbObject3DPtr geoObject3D, Grid3DPtr grid, BCAdapterPtr bcAdapter,  int type)
+   :   Interactor3D(geoObject3D, grid, type), relevantForForces(false)
+{
+   this->reinitWithStoredQsFlag = false;
+   this->addBCAdapter(bcAdapter); 
+   this->initRayVectors();
+}
+//////////////////////////////////////////////////////////////////////////
+D3Q27Interactor::D3Q27Interactor(GbObject3DPtr geoObject3D, Grid3DPtr grid, BCAdapterPtr bcAdapter,  int type, Interactor3D::Accuracy a)
+   :   Interactor3D(geoObject3D, grid, type, a), relevantForForces(false)
+{
+   this->reinitWithStoredQsFlag = false;
+   this->addBCAdapter(bcAdapter); 
+   this->initRayVectors();
+}
+//////////////////////////////////////////////////////////////////////////
+D3Q27Interactor::~D3Q27Interactor()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27Interactor::initRayVectors()
+{
+   int fdir; double c1oS2 = UbMath::one_over_sqrt2;
+   fdir = D3Q27System::E;  rayX1[fdir] =  1.0;   rayX2[fdir] =  0.0;   rayX3[fdir] =  0.0;
+   fdir = D3Q27System::W;  rayX1[fdir] = -1.0;   rayX2[fdir] =  0.0;   rayX3[fdir] =  0.0;
+   fdir = D3Q27System::N;  rayX1[fdir] =  0.0;   rayX2[fdir] =  1.0;   rayX3[fdir] =  0.0;
+   fdir = D3Q27System::S;  rayX1[fdir] =  0.0;   rayX2[fdir] = -1.0;   rayX3[fdir] =  0.0;
+   fdir = D3Q27System::T;  rayX1[fdir] =  0.0;   rayX2[fdir] =  0.0;   rayX3[fdir] =  1.0;
+   fdir = D3Q27System::B;  rayX1[fdir] =  0.0;   rayX2[fdir] =  0.0;   rayX3[fdir] = -1.0;
+   fdir = D3Q27System::NE; rayX1[fdir] =  c1oS2; rayX2[fdir] =  c1oS2; rayX3[fdir] =  0.0;
+   fdir = D3Q27System::SW; rayX1[fdir] = -c1oS2; rayX2[fdir] = -c1oS2; rayX3[fdir] =  0.0;
+   fdir = D3Q27System::SE; rayX1[fdir] =  c1oS2; rayX2[fdir] = -c1oS2; rayX3[fdir] =  0.0;
+   fdir = D3Q27System::NW; rayX1[fdir] = -c1oS2; rayX2[fdir] =  c1oS2; rayX3[fdir] =  0.0;
+   fdir = D3Q27System::TE; rayX1[fdir] =  c1oS2; rayX2[fdir] = 0.0;    rayX3[fdir] =  c1oS2;
+   fdir = D3Q27System::BW; rayX1[fdir] = -c1oS2; rayX2[fdir] = 0.0;    rayX3[fdir] = -c1oS2;
+   fdir = D3Q27System::BE; rayX1[fdir] =  c1oS2; rayX2[fdir] = 0.0;    rayX3[fdir] = -c1oS2;
+   fdir = D3Q27System::TW; rayX1[fdir] = -c1oS2; rayX2[fdir] = 0.0;    rayX3[fdir] =  c1oS2;
+   fdir = D3Q27System::TN; rayX1[fdir] =  0.0;   rayX2[fdir] = c1oS2;  rayX3[fdir] =  c1oS2;
+   fdir = D3Q27System::BS; rayX1[fdir] =  0.0;   rayX2[fdir] =-c1oS2;  rayX3[fdir] = -c1oS2;
+   fdir = D3Q27System::BN; rayX1[fdir] =  0.0;   rayX2[fdir] = c1oS2;  rayX3[fdir] = -c1oS2;
+   fdir = D3Q27System::TS; rayX1[fdir] =  0.0;   rayX2[fdir] =-c1oS2;  rayX3[fdir] =  c1oS2;
+
+   fdir = D3Q27System::TNW; rayX1[fdir] = -c1oS2; rayX2[fdir] = c1oS2; rayX3[fdir] =  c1oS2;;
+   fdir = D3Q27System::TNE; rayX1[fdir] =  c1oS2; rayX2[fdir] = c1oS2; rayX3[fdir] =  c1oS2;
+   fdir = D3Q27System::TSW; rayX1[fdir] = -c1oS2; rayX2[fdir] =-c1oS2; rayX3[fdir] =  c1oS2;
+   fdir = D3Q27System::TSE; rayX1[fdir] =  c1oS2; rayX2[fdir] =-c1oS2; rayX3[fdir] =  c1oS2;
+   fdir = D3Q27System::BNW; rayX1[fdir] = -c1oS2; rayX2[fdir] = c1oS2; rayX3[fdir] =  -c1oS2;
+   fdir = D3Q27System::BNE; rayX1[fdir] =  c1oS2; rayX2[fdir] = c1oS2; rayX3[fdir] =  -c1oS2;
+   fdir = D3Q27System::BSW; rayX1[fdir] = -c1oS2; rayX2[fdir] =-c1oS2; rayX3[fdir] =  -c1oS2;
+   fdir = D3Q27System::BSE; rayX1[fdir] =  c1oS2; rayX2[fdir] =-c1oS2; rayX3[fdir] =  -c1oS2;
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27Interactor::initInteractor(const double& timeStep)
+{
+   UBLOG(logDEBUG5,"D3Q27Interactor::initInteractor - "<<" for timestep = "<<timeStep);
+   
+   //////////////////////////////////////////////////////////////////////////
+   //init bcs
+   int nofAdapter = (int)bcAdapters.size();
+   if(nofAdapter==0) UBLOG(logWARNING,"WARNING - D3Q27Interactor::initInteractor Warning - no nodeAdapter available");
+   bool needTimeDependence = false;
+   for(int pos=0; pos<nofAdapter; ++pos)
+   {
+      bcAdapters[pos]->init(this,timeStep);
+      if(bcAdapters[pos]->isTimeDependent()) needTimeDependence = true;
+   }
+   if(needTimeDependence) this->setTimeDependent();
+   else                   this->unsetTimeDependent();
+
+   Interactor3D::initInteractor(timeStep);
+
+  ////calcForces arbeitet nicht korrekt, wenn Geo mit Bloecken 
+  // //unterschiedlicher Leveltiefe diskretisiert -> exception
+  // //abfrage steht hier, weil es theoretisch sein kann, dass bei parallelen rechnungen
+  // //genau der block mit dem anderen level auf einem anderen prozess liegt...
+  // //Update: es kann u.U. passieren, dass Bl�cke in der Liste nicht aktiv sin
+  // //(falls diese z.B. duch andere Interactoren solid gesetzt wurden)
+  // //diese werden nicht ber�cksichtigt (auch nicht beid er kraftauswertung sp�ter)
+  // if(this->isRelevantForForces() )
+  // {
+  //    int level = -1;     
+  //    for( vector<Block3D*>::const_iterator pos = transBlockSet->begin(); pos!=transBlockSet->end(); ++pos)
+  //       if( (*pos)->isActive() )
+  //       {
+  //          level = (*pos)->getLevel();
+  //          break;
+  //       }
+  //    
+  //    bool check = false;
+  //    for( vector<Block3D*>::const_iterator pos = transBlockSet->begin(); pos!=transBlockSet->end(); ++pos)
+  //       if( (*pos)->isActive() && (*pos)->getLevel()!=level)
+  //       {
+  //          throw UbException(UB_EXARGS,"interactor is relevant for forces,"
+  //                                  +(string)" but has transblocks with different levels"
+  //                                  +(string)" -> not supportet by D3Q27Interactor::getForces()"
+  //                                  +(string)" -> increase refineWidth");
+  //       }
+  // }
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27Interactor::updateInteractor(const double& timestep)
+{
+   //UB_THROW( UbException(UB_EXARGS,"toDo") );
+   //if(this->isFluid()) return;
+
+   UBLOG(logDEBUG5,"D3Q27Interactor::updateInteractor - for timestep = "<<timestep);
+
+   //////////////////////////////////////////////////////////////////////////
+   //update bcs
+   int nofAdapter = (int)bcAdapters.size();
+   if(nofAdapter==0) UBLOG(logERROR,"WARNING - D3Q27Interactor::updateInteractor Warning - no nodeAdapter available for ");
+
+   bool needTimeDependence = false;
+
+   for(int pos=0; pos<nofAdapter; ++pos)
+   {
+      bcAdapters[pos]->update(this,timestep);
+      if(bcAdapters[pos]->isTimeDependent()) needTimeDependence = true;
+   }
+   if(needTimeDependence) this->setTimeDependent();
+   else                   this->unsetTimeDependent();
+   
+   //UBLOG(logINFO, "transNodeIndicesMap = "<<transNodeIndicesMap.size());
+   
+   for(BcNodeIndicesMap::value_type t : bcNodeIndicesMap)
+   {
+      Block3DPtr block = t.first;
+      std::set< std::vector<int> >& transNodeIndicesSet = t.second;
+
+      //UBLOG(logINFO, "transNodeIndicesSet = "<<transNodeIndicesSet.size());
+
+      if(block->isNotActive() || !block) continue;
+
+      ILBMKernelPtr kernel = block->getKernel();
+      BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
+
+      set< std::vector<int> >::iterator setPos;
+
+      for(setPos=transNodeIndicesSet.begin(); setPos!=transNodeIndicesSet.end();  ++setPos)
+      {
+         int    x1      = (*setPos)[0];
+         int    x2      = (*setPos)[1];
+         int    x3      = (*setPos)[2];
+         Vector3D coords = grid.lock()->getNodeCoordinates(block, x1, x2, x3);
+         double worldX1 = coords[0];
+         double worldX2 = coords[1];
+         double worldX3 = coords[2];
+
+         BoundaryConditionsPtr bc = bcArray->getBC(x1,x2,x3);
+         if(bc) //kann sein, dass die BC durch das solid setzen eines andern interactors geloescht wurde
+         {
+            for(size_t i=0; i<bcAdapters.size(); i++)
+               bcAdapters[i]->adaptBC(*this,bc,worldX1,worldX2,worldX3,timestep);
+         }
+         //else 
+         //{
+         //   UBLOG(logERROR,"D3Q27Interactor.updateInteractor (Z."<<__LINE__<<"): da ist kein BC dran ... kann aber korrekt sein s.h. code");
+         //}
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+// Berechnung findet im realen Koordinatensystem statt !!!
+// nicht im normierten !
+//x1,x2,x3 sind die Koordinaten unten links vom "System"
+//extendedBoundingGeoOfGeoObject MUSS bereits um delta_x_level in jede richtung vergroesert worden sein fuer SOLID
+bool D3Q27Interactor::setDifferencesToGbObject3D(const Block3DPtr block/*,const double& orgX1,const double& orgX2,const double& orgX3,const double& blockLengthX1,const double& blockLengthX2,const double& blockLengthX3, const double& timestep*/)
+{
+   if(!block) return false;
+
+   if(block->isNotActive()) return false;//continue;
+
+   bcNodeIndicesMap[block] = set< std::vector<int> >();
+   set< std::vector<int> >& transNodeIndices = bcNodeIndicesMap[block];
+   solidNodeIndicesMap[block] = set< UbTupleInt3 >();
+   set< UbTupleInt3 >& solidNodeIndices = solidNodeIndicesMap[block];
+
+
+   double timestep = 0;
+   bool oneEntryGotBC = false; //ob ueberhaupt ein eintrag ein BC zugewiesen wurde
+   bool gotQs         = false; //true, wenn "difference" gesetzt wurde
+   BoundaryConditionsPtr bc;
+
+   ILBMKernelPtr kernel = block->getKernel();
+   BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
+
+   double internX1,internX2,internX3;
+
+
+   //width of ghost layer 
+   int gl = kernel->getGhostLayerWidth();
+
+   int startIX1 = 0;
+   int startIX2 = 0;
+   int startIX3 = 0; 
+   int stopIX1  = (int)bcArray->getNX1();
+   int stopIX2  = (int)bcArray->getNX2();
+   int stopIX3  = (int)bcArray->getNX3(); 
+
+   double         dx       = grid.lock()->getDeltaX(block);
+   UbTupleDouble3 orgDelta = grid.lock()->getNodeOffset(block);
+
+   //anderes boundingRect als in init, da hier das boundrect um ein dx vergroessert werden muss
+   GbCuboid3D extendedBoundingGeoOfGeoObject(  geoObject3D->getX1Minimum()-1.02*dx 
+                                             , geoObject3D->getX2Minimum()-1.02*dx 
+                                             , geoObject3D->getX3Minimum()-1.02*dx 
+                                             , geoObject3D->getX1Maximum()+1.02*dx 
+                                             , geoObject3D->getX2Maximum()+1.02*dx 
+                                             , geoObject3D->getX3Maximum()+1.02*dx );
+
+   double deltaX1=dx, deltaX2 =dx, deltaX3=dx;
+
+   if(   geoObject3D->hasRaytracing() 
+        || (this->isInverseSolid() && geoObject3D->raytracingSupportsPointsInside() ) )
+   {
+      //wenn deltaX1==deltaX2==deltaX3 (muss fuer LB!!)
+      if(!UbMath::zero( deltaX1-deltaX2 + deltaX1-deltaX3 + deltaX2-deltaX3 ) )
+         throw UbException(UB_EXARGS,"fuer den bei LB nicht vorkommenden Fall deltaX1!=deltaX2!=deltaX3  nicht implementiert ");
+
+      vector<double> distNeigh(D3Q27System::FENDDIR+1, UbMath::sqrt2*deltaX1);
+      distNeigh[D3Q27System::E] = distNeigh[D3Q27System::W] = distNeigh[D3Q27System::N] = deltaX1;
+      distNeigh[D3Q27System::S] = distNeigh[D3Q27System::T] = distNeigh[D3Q27System::B] = deltaX1;
+
+      double q;
+      bool pointOnBoundary = false;
+
+//#ifdef _OPENMP
+//      #pragma omp parallel for private(internX1,internX2,internX3,gotQs,bc,q )
+//#endif
+      for(int ix3=startIX3; ix3<stopIX3; ix3++)
+      {
+         for(int ix2=startIX2; ix2<stopIX2; ix2++)
+         {
+            for(int ix1=startIX1; ix1<stopIX1; ix1++)
+            {
+               //TODO weiter untersuchen, ob das nicht ein Fehler ist
+               if(bcArray->isUndefined(ix1, ix2, ix3)) continue;
+
+               Vector3D coords = grid.lock()->getNodeCoordinates(block, ix1, ix2, ix3);
+               internX1 = coords[0];
+               internX2 = coords[1];
+               internX3 = coords[2];
+
+               //point in object test ist ueberfluessig, weil die start und stop indices bereits zuvor 
+               //ermittelt werden -> es werden nur point-IN-cube indizes betrachtet
+               if(extendedBoundingGeoOfGeoObject.isPointInGbObject3D(internX1,internX2,internX3))
+               {
+                  if(this->isSolid() )
+                  {
+                     if(this->geoObject3D->isPointInGbObject3D(internX1, internX2, internX3))
+                     {
+//#ifdef _OPENMP
+//                        #pragma omp critical (SOLIDNODE_SET_CHANGE)
+//#endif
+                        {
+                           solidNodeIndices.insert(UbTupleInt3(ix1, ix2, ix3));
+                           bcArray->setSolid(ix1,ix2,ix3); 
+                        }
+                        continue;
+                     }
+                  }
+                  else if( this->isInverseSolid()  )
+                  {
+                     //bei inverse solid sind alle Knoten AUSSERHALB und auf der boundary SOLID
+                     if( !this->geoObject3D->isPointInGbObject3D(internX1, internX2, internX3, pointOnBoundary) 
+                        || pointOnBoundary == true )
+                     {
+//#ifdef _OPENMP
+//                        #pragma omp critical (SOLID_SET_CHANGE)
+//#endif
+                        {
+                           solidNodeIndices.insert(UbTupleInt3(ix1, ix2, ix3));
+                           bcArray->setSolid(ix1,ix2,ix3); 
+                        }
+                        continue;
+                     }
+                  }
+
+                  //evtl wurde node von anderen interactoren solid gesetzt (muss hie rein->sonst evtl bei
+                  //ueberschneidender geo -> solidNodeIndicesMap unvollstaendig)
+                  if(bcArray->isSolid(ix1,ix2,ix3)) 
+                     continue;
+
+                  gotQs = false;
+
+                  //TODO: prüfen was passiert wenn ein Geoobjekt zwischen zwei knoten rausguckt
+                  //  * /
+                  //<
+                  //  * \  //
+                  //sollen dann keine qs gesetzt werden
+                  for(int fdir=D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
+                  {
+                     q = geoObject3D->getIntersectionRaytraceFactor(internX1,internX2,internX3,rayX1[fdir],rayX2[fdir],rayX3[fdir]);
+                     q /= distNeigh[fdir];
+
+                     //assert(UbMath::lessEqual(q, 1.0));
+
+                     if( UbMath::inClosedInterval(q, 1.0, 1.0) ) q = 1.0;
+                     if( UbMath::greater(q, 0.0) && UbMath::lessEqual(q, 1.0) )
+                     {
+                        #pragma omp critical (BC_CHANGE)
+                        {
+                           bc = bcArray->getBC(ix1,ix2,ix3);
+                           if(!bc)
+                           {
+                              //bc = bvd->createD3Q27BoundaryCondition(); //= new D3Q27BoundaryCondition();
+                              bc = BoundaryConditionsPtr(new BoundaryConditions);
+                              bcArray->setBC(ix1,ix2,ix3,bc);
+                           }
+                     //TODO: man muss ueberlegen, wie kann man, dass die Geschwindigkeit auf 0.0 gesetzt werden, vermeiden
+                     //das folgt zu unguenstigen "design rules"
+                      //SG 31.08.2010 das Problem - bewegter Interactor angrenzend an stehenden noslip interactor
+                      // hier sollte die Geschwindigkeit auf 0.0 gesetzt werden
+                           if(bc->hasNoSlipBoundary())
+                           {
+                              bc->setBoundaryVelocityX1(0.0);
+                              bc->setBoundaryVelocityX2(0.0);
+                              bc->setBoundaryVelocityX3(0.0);
+                           }
+                       //SG 31.08.2010
+                        
+                           for(int index=(int)bcAdapters.size()-1; index>=0; --index)
+                              bcAdapters[index]->adaptBCForDirection(*this,bc,internX1,internX2,internX3,q,fdir, timestep);
+                        }
+
+                        gotQs=true;
+                     }
+                  }
+
+                  if(gotQs)
+                  {
+#ifdef _OPENMP
+                     #pragma omp critical (TRANSNODE_SET_CHANGE)
+#endif
+                     {
+                        oneEntryGotBC = true;
+
+                        std::vector<int> p(3);
+                        p[0]=ix1; p[1]=ix2; p[2]=ix3;
+                        transNodeIndices.insert(p);
+                     
+                        for(int index=(int)bcAdapters.size()-1; index>=0; --index)
+                           bcAdapters[index]->adaptBC(*this,bc,internX1,internX2,internX3, timestep);
+                     }
+                  }
+               }
+               else if( this->isInverseSolid()  )
+               {
+                  //bei inverse solid sind alle Knoten AUSSERHALB und auf der boundary SOLID
+                  if( !this->geoObject3D->isPointInGbObject3D(internX1, internX2, internX3, pointOnBoundary) 
+                     || pointOnBoundary == true )
+                 {
+#ifdef _OPENMP 
+   #pragma omp critical (SOLID_SET_CHANGE)
+#endif
+                     {
+                        solidNodeIndices.insert(UbTupleInt3(ix1, ix2, ix3));
+                        bcArray->setSolid(ix1,ix2,ix3); 
+                     }
+                     continue;
+                  }
+               }
+            }
+         }
+      }
+   }
+   else  //clipping -> langsamer (wird derzeit auch fuer alle inverseSolid objekte verwendet deren raytracing nicht fuer nodes INNERHALB der geo funzt)
+   {
+      bool pointOnBoundary = false;
+      #pragma omp parallel for private(internX1,internX2,internX3,gotQs,bc,pointOnBoundary )
+      for(int ix1=startIX1; ix1<stopIX1; ix1++)
+      {
+         for(int ix2=startIX2; ix2<stopIX2; ix2++)
+         {
+            for(int ix3=startIX3; ix3<stopIX3; ix3++)
+            {
+               if(bcArray->isSolid(ix1,ix2,ix3) || bcArray->isUndefined(ix1, ix2, ix3)) continue;
+
+               Vector3D coords = grid.lock()->getNodeCoordinates(block, ix1, ix2, ix3);
+               internX1 = coords[0];
+               internX2 = coords[1];
+               internX3 = coords[2];
+
+               if(extendedBoundingGeoOfGeoObject.isPointInGbObject3D(internX1,internX2,internX3))
+               {
+                  if( this->isSolid() && this->geoObject3D->isPointInGbObject3D(internX1, internX2, internX3) )
+                  {
+                     #pragma omp critical (SOLID_SET_CHANGE)
+                     {
+                        solidNodeIndices.insert(UbTupleInt3(ix1, ix2, ix3));
+                        bcArray->setSolid(ix1,ix2,ix3); 
+                     }
+                     continue;
+                  }
+                  else if( this->isInverseSolid()  )
+                  {
+                     //bei inverse solid sind alle Knoten AUSSERHALB und auf der boundary SOLID
+                     if( !this->geoObject3D->isPointInGbObject3D(internX1, internX2, internX3, pointOnBoundary) 
+                         || pointOnBoundary == true )
+                     {
+                        #pragma omp critical (SOLID_SET_CHANGE)
+                        {
+                           solidNodeIndices.insert(UbTupleInt3(ix1, ix2, ix3));
+                           bcArray->setSolid(ix1,ix2,ix3); 
+                        }
+                        continue;
+                     }
+                  }
+
+                  gotQs = false;
+
+                  GbPoint3D pointA(internX1,internX2,internX3);
+                  for(int fdir=D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
+                  {
+                     double x1B = internX1+D3Q27System::DX1[fdir]*deltaX1;
+                     double x2B = internX2+D3Q27System::DX2[fdir]*deltaX2;
+                     double x3B = internX3+D3Q27System::DX3[fdir]*deltaX3;
+
+                     GbPoint3D pointB(x1B,x2B,x3B);
+                     GbLine3D* clippedLine = this->geoObject3D->createClippedLine3D(pointA, pointB);
+
+                     if(clippedLine)
+                     {
+                        double q=0.0;
+                        if( !this->isInverseSolid() )  //A liegt auf jeden Fall aussen
+                        {
+                           double distanceAB = pointA.getDistance(&pointB); //pointA to B
+                           double distanceAP = UbMath::min(pointA.getDistance(clippedLine->getPoint1()),
+                                                           pointA.getDistance(clippedLine->getPoint2()) );
+                           q = distanceAP/distanceAB;
+                        }
+                        else
+                        {
+                           bool pointIsOnBoundary = false;
+                           if(   !clippedLine->getPoint1()->equals(&pointB)
+                              && !clippedLine->getPoint2()->equals(&pointB) )
+                           {
+                              //A liegt auf jeden Fall drinnen, clipped line darf B nicht enthalten
+                              double distanceAB = pointA.getDistance(&pointB); //pointA to B
+                              double distanceAP = clippedLine->getLength();
+                              q = distanceAP/distanceAB;
+                           }
+                           else if(  this->geoObject3D->isPointInGbObject3D( pointB.getX1Coordinate()
+                                                                            ,pointB.getX2Coordinate()
+                                                                            ,pointB.getX3Coordinate()
+                                                                            ,pointIsOnBoundary )
+                                   && pointIsOnBoundary )
+                           {
+                              //A liegt auf jeden Fall drinnen, B liegt genau auf ObjektBoundary => q=1.0
+                              q=1.0;
+                           }
+                           else
+                           {
+                              q = 0.0;
+                           }
+                        }
+
+                        if(UbMath::inClosedInterval(q, 1.0, 1.0)) q = 1.0;
+                        if(UbMath::lessEqual(q, 1.0) && UbMath::greater(q, 0.0))
+                        {
+                           #pragma omp critical (BC_CHANGE)
+                           {
+                              bc = bcArray->getBC(ix1,ix2,ix3);
+                              if(!bc)
+                              {
+                                 //bc = bvd->createD3Q27BoundaryCondition(); //= new D3Q27BoundaryCondition();
+                                 bc = BoundaryConditionsPtr(new BoundaryConditions);
+                                 bcArray->setBC(ix1,ix2,ix3,bc);
+                              }
+                              for(int index=(int)bcAdapters.size()-1; index>=0; --index)
+                                 bcAdapters[index]->adaptBCForDirection(*this,bc,internX1,internX2,internX3,q,fdir,timestep);
+                           }
+                                          
+                           gotQs=true;
+                        }
+
+                        clippedLine->deletePoint1();
+                        clippedLine->deletePoint2();
+                        delete clippedLine;
+                     }
+                  }
+
+                  if(gotQs)
+                  {
+                     #pragma omp critical (TRANSNODE_SET_CHANGE)
+                     {
+                        oneEntryGotBC = true;
+
+                        std::vector<int> p(3);
+                        p[0]=ix1; p[1]=ix2; p[2]=ix3;
+                        transNodeIndices.insert(p);
+
+                        for(int index=(int)bcAdapters.size()-1; index>=0; --index)
+                           bcAdapters[index]->adaptBC(*this,bc,internX1,internX2,internX3,timestep);
+                     }
+                  }
+               }
+            }
+         }
+      }
+   }
+
+   return oneEntryGotBC;
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27Interactor::addQsLineSet(std::vector<UbTupleFloat3 >& nodes, std::vector<UbTupleInt2 >& lines)
+{
+      for(Block3DPtr block : bcBlocks)
+      {
+         if(!block) continue;
+
+         double         dx       = grid.lock()->getDeltaX(block);
+         UbTupleDouble3 orgDelta = grid.lock()->getNodeOffset(block);
+
+         ILBMKernelPtr kernel = block->getKernel();
+         BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
+
+         map<Block3DPtr, set< std::vector<int> > >::iterator pos = bcNodeIndicesMap.find(block);
+         if(pos==bcNodeIndicesMap.end()) 
+         {
+            UB_THROW( UbException(UB_EXARGS,"block nicht in indizes map!!!") );
+         }
+         set< std::vector<int> >& transNodeIndicesSet = pos->second;
+         set< std::vector<int> >::iterator setPos;
+
+         std::size_t node1Index, node2Index;
+
+         UbTupleDouble3 blockOrg = grid.lock()->getBlockWorldCoordinates(block);
+
+         for(setPos=transNodeIndicesSet.begin(); setPos!=transNodeIndicesSet.end();  ++setPos)
+         {
+            int ix1 = (*setPos)[0];
+            int ix2 = (*setPos)[1];
+            int ix3 = (*setPos)[2];
+
+            if(bcArray->isFluid(ix1,ix2,ix3)) //es kann sein, dass der node von einem anderen interactor z.B. als solid gemarkt wurde!!!
+            {
+               if( !bcArray->hasBC(ix1,ix2,ix3) ) continue;
+               BoundaryConditionsPtr bc = bcArray->getBC(ix1,ix2,ix3);
+
+               double x1a = val<1>(blockOrg) - val<1>(orgDelta) + ix1 * dx;
+               double x2a = val<2>(blockOrg) - val<2>(orgDelta) + ix2 * dx;
+               double x3a = val<3>(blockOrg) - val<3>(orgDelta) + ix3 * dx;
+               nodes.push_back( makeUbTuple( (float)x1a, (float)x2a, (float)x3a ) );
+               node1Index = nodes.size()-1;
+
+               for(int dir = D3Q27System::FSTARTDIR; dir<=D3Q27System::FENDDIR; dir++)
+               {
+                  if (bc->hasBoundaryConditionFlag(D3Q27System::INVDIR[dir]))
+                  {
+                     double x1b, x2b, x3b, q = bc->getQ(dir);
+                     switch(dir)
+                     {
+                     case D3Q27System::E : x1b = x1a+q*dx; x2b = x2a         ; x3b = x3a         ; break;
+                     case D3Q27System::N : x1b = x1a         ; x2b = x2a+q*dx; x3b = x3a         ; break;
+                     case D3Q27System::W : x1b = x1a-q*dx; x2b = x2a         ; x3b = x3a         ; break;
+                     case D3Q27System::S : x1b = x1a         ; x2b = x2a-q*dx; x3b = x3a         ; break;
+                     case D3Q27System::NE: x1b = x1a+q*dx; x2b = x2a+q*dx; x3b = x3a         ; break;
+                     case D3Q27System::NW: x1b = x1a-q*dx; x2b = x2a+q*dx; x3b = x3a         ; break;
+                     case D3Q27System::SW: x1b = x1a-q*dx; x2b = x2a-q*dx; x3b = x3a         ; break;
+                     case D3Q27System::SE: x1b = x1a+q*dx; x2b = x2a-q*dx; x3b = x3a         ; break;
+                     case D3Q27System::T : x1b = x1a         ; x2b = x2a         ; x3b = x3a+q*dx; break;
+                     case D3Q27System::TE: x1b = x1a+q*dx; x2b = x2a         ; x3b = x3a+q*dx; break;
+                     case D3Q27System::TN: x1b = x1a         ; x2b = x2a+q*dx; x3b = x3a+q*dx; break;
+                     case D3Q27System::TW: x1b = x1a-q*dx; x2b = x2a         ; x3b = x3a+q*dx; break;
+                     case D3Q27System::TS: x1b = x1a         ; x2b = x2a-q*dx; x3b = x3a+q*dx; break;
+                     case D3Q27System::B : x1b = x1a         ; x2b = x2a         ; x3b = x3a-q*dx; break;
+                     case D3Q27System::BE: x1b = x1a+q*dx; x2b = x2a         ; x3b = x3a-q*dx; break;
+                     case D3Q27System::BN: x1b = x1a         ; x2b = x2a+q*dx; x3b = x3a-q*dx; break;
+                     case D3Q27System::BW: x1b = x1a-q*dx; x2b = x2a         ; x3b = x3a-q*dx; break;
+                     case D3Q27System::BS: x1b = x1a         ; x2b = x2a-q*dx; x3b = x3a-q*dx; break;
+                     case D3Q27System::TNE : x1b = x1a+q*dx  ; x2b = x2a+q*dx; x3b = x3a+q*dx; break;
+                     case D3Q27System::BSW : x1b = x1a-q*dx  ; x2b = x2a-q*dx; x3b = x3a-q*dx; break;
+                     case D3Q27System::BNE : x1b = x1a+q*dx  ; x2b = x2a+q*dx; x3b = x3a-q*dx; break;
+                     case D3Q27System::TSW : x1b = x1a-q*dx  ; x2b = x2a-q*dx; x3b = x3a+q*dx; break;
+                     case D3Q27System::TSE : x1b = x1a+q*dx  ; x2b = x2a-q*dx; x3b = x3a+q*dx; break;
+                     case D3Q27System::BNW : x1b = x1a-q*dx  ; x2b = x2a+q*dx; x3b = x3a-q*dx; break;
+                     case D3Q27System::BSE : x1b = x1a+q*dx  ; x2b = x2a-q*dx; x3b = x3a-q*dx; break;
+                     case D3Q27System::TNW : x1b = x1a-q*dx  ; x2b = x2a+q*dx; x3b = x3a+q*dx; break;
+                     default: throw UbException(UB_EXARGS,"unknown direction");
+                     }
+
+                     nodes.push_back( makeUbTuple( (float)x1b, (float)x2b, (float)x3b ) );
+                     node2Index = nodes.size()-1;
+
+                     lines.push_back( makeUbTuple( (int)node1Index, (int)node2Index) );
+                  }
+               }
+            }
+         }
+      }
+}
+////////////////////////////////////////////////////////////////////////////
+vector< pair<GbPoint3D,GbPoint3D> >  D3Q27Interactor::getQsLineSet()
+{
+   vector< pair<GbPoint3D,GbPoint3D> >  QsLineSet;
+   pair<GbPoint3D,GbPoint3D> pointpair;
+
+   UbTupleInt3 blocknx = grid.lock()->getBlockNX();
+
+   int blocknx1 = val<1>(blocknx);
+   int blocknx2 = val<2>(blocknx);
+   int blocknx3 = val<3>(blocknx);
+   //   vector<double> deltaT = grid->getD3Q27Calculator()->getDeltaT();
+
+   for(Block3DPtr block : bcBlocks)
+   {
+       ILBMKernelPtr kernel = block->getKernel();
+      BCArray3DPtr bcMatrix = kernel->getBCProcessor()->getBCArray();
+      UbTupleDouble3 nodeOffset   = grid.lock()->getNodeOffset(block);
+
+      //double collFactor = ((LbD3Q27Calculator*)grid->getCalculator())->getCollisionsFactors()[block->getLevel()];
+      //checken ob obere reihe doppelt im system vorhanden oder nicht
+      bool include_N_Face  = false; //x1=[0..blocknx1[ && x3=[0..blocknx3[
+      bool include_E_Face  = false; //x2=[0..blocknx2[ && x3=[0..blocknx3[
+      bool include_T_Face  = false; //x1=[0..blocknx1[ && x2=[0..blocknx2[
+      bool include_NE_Edge = false; //(x1/x2/x3)=(blocknx1/blocknx2/[0..blocknx3[)
+      bool include_TN_Edge = false; //(x1/x2/x3)=([0..blocknx1[/blocknx2/blocknx1)
+      bool include_TE_Edge = false; //(x1/x2/x3)=(blocknx1/[0..blocknx2[/blocknx2)
+      if(block)
+      {
+         if( !block->getConnector(D3Q27System::N ) ) include_N_Face  = true;
+         if( !block->getConnector(D3Q27System::E ) ) include_E_Face  = true;
+         if( !block->getConnector(D3Q27System::T ) ) include_T_Face  = true;
+         if( !block->getConnector(D3Q27System::NE) && include_N_Face && include_E_Face ) include_NE_Edge = true;
+         if( !block->getConnector(D3Q27System::TN) && include_T_Face && include_N_Face ) include_TN_Edge = true;
+         if( !block->getConnector(D3Q27System::TE) && include_T_Face && include_E_Face ) include_TE_Edge = true;
+      }
+
+      //      double dT = deltaT[block->getLevel()];
+
+      map<Block3DPtr, set< std::vector<int> > >::iterator pos = bcNodeIndicesMap.find(block);
+      if(pos==bcNodeIndicesMap.end()) throw UbException(UB_EXARGS,"block nicht in indizes map!!!"+block->toString());
+      set< std::vector<int> >& transNodeIndicesSet = pos->second;
+      set< std::vector<int> >::iterator setPos;
+
+      double x1,x2,x3,dx;
+      grid.lock()->calcStartCoordinatesAndDelta(block,x1,x2,x3,dx);
+
+      //cout<<"getQs: "<<transBlockSet->size()<<" "<<transNodeIndicesVec.size()<<endl;
+
+      for(setPos=transNodeIndicesSet.begin(); setPos!=transNodeIndicesSet.end();  ++setPos)
+      {
+         int ix1 = (*setPos)[0];
+         int ix2 = (*setPos)[1];
+         int ix3 = (*setPos)[2];
+
+         if(   ( ix1<blocknx1 && ix2<blocknx2 && ix3<blocknx3 ) //std fall
+            || ( include_E_Face  && ix1==blocknx1 && ix2<blocknx2  && ix3<blocknx3  )
+            || ( include_N_Face  && ix2==blocknx2 && ix1<blocknx1  && ix3<blocknx3  )
+            || ( include_T_Face  && ix3==blocknx3 && ix1<blocknx1  && ix2<blocknx2  )
+            || ( include_NE_Edge && ix1==blocknx1 && ix2==blocknx2 )
+            || ( include_TN_Edge && ix2==blocknx2 && ix3==blocknx3 )
+            || ( include_TE_Edge && ix1==blocknx1 && ix3==blocknx3 ) ) //ansonsten doppelt im kraftwert
+         {
+            if(bcMatrix->isFluid(ix1,ix2,ix3)) //es kann sein, dass der node von einem anderen interactor z.B. als solid gemarkt wurde!!!
+            {
+               if( !bcMatrix->hasBC(ix1,ix2,ix3) ) continue;
+               BoundaryConditionsPtr bc = bcMatrix->getBC(ix1,ix2,ix3);
+               double x1a = x1-val<1>(nodeOffset)+dx * ix1;
+               double x2a = x2-val<2>(nodeOffset)+dx * ix2;
+               double x3a = x3-val<3>(nodeOffset)+dx * ix3;
+               pointpair.first.setX1(x1a);
+               pointpair.first.setX2(x2a);
+               pointpair.first.setX3(x3a);
+               for(int dir = D3Q27System::FSTARTDIR; dir<=D3Q27System::FENDDIR; dir++)
+               {
+                  if (bc->hasBoundaryConditionFlag(D3Q27System::INVDIR[dir]))
+                  {
+                     double x1b, x2b, x3b, q = bc->getQ(dir);
+                     switch(dir)
+                     {
+                     case D3Q27System::E : x1b = x1a+q*dx; x2b = x2a         ; x3b = x3a         ; break;
+                     case D3Q27System::N : x1b = x1a         ; x2b = x2a+q*dx; x3b = x3a         ; break;
+                     case D3Q27System::W : x1b = x1a-q*dx; x2b = x2a         ; x3b = x3a         ; break;
+                     case D3Q27System::S : x1b = x1a         ; x2b = x2a-q*dx; x3b = x3a         ; break;
+                     case D3Q27System::NE: x1b = x1a+q*dx; x2b = x2a+q*dx; x3b = x3a         ; break;
+                     case D3Q27System::NW: x1b = x1a-q*dx; x2b = x2a+q*dx; x3b = x3a         ; break;
+                     case D3Q27System::SW: x1b = x1a-q*dx; x2b = x2a-q*dx; x3b = x3a         ; break;
+                     case D3Q27System::SE: x1b = x1a+q*dx; x2b = x2a-q*dx; x3b = x3a         ; break;
+                     case D3Q27System::T : x1b = x1a         ; x2b = x2a         ; x3b = x3a+q*dx; break;
+                     case D3Q27System::TE: x1b = x1a+q*dx; x2b = x2a         ; x3b = x3a+q*dx; break;
+                     case D3Q27System::TN: x1b = x1a         ; x2b = x2a+q*dx; x3b = x3a+q*dx; break;
+                     case D3Q27System::TW: x1b = x1a-q*dx; x2b = x2a         ; x3b = x3a+q*dx; break;
+                     case D3Q27System::TS: x1b = x1a         ; x2b = x2a-q*dx; x3b = x3a+q*dx; break;
+                     case D3Q27System::B : x1b = x1a         ; x2b = x2a         ; x3b = x3a-q*dx; break;
+                     case D3Q27System::BE: x1b = x1a+q*dx; x2b = x2a         ; x3b = x3a-q*dx; break;
+                     case D3Q27System::BN: x1b = x1a         ; x2b = x2a+q*dx; x3b = x3a-q*dx; break;
+                     case D3Q27System::BW: x1b = x1a-q*dx; x2b = x2a         ; x3b = x3a-q*dx; break;
+                     case D3Q27System::BS: x1b = x1a         ; x2b = x2a-q*dx; x3b = x3a-q*dx; break;
+                     case D3Q27System::TNE : x1b = x1a+q*dx  ; x2b = x2a+q*dx; x3b = x3a+q*dx; break;
+                     case D3Q27System::BSW : x1b = x1a-q*dx  ; x2b = x2a-q*dx; x3b = x3a-q*dx; break;
+                     case D3Q27System::BNE : x1b = x1a+q*dx  ; x2b = x2a+q*dx; x3b = x3a-q*dx; break;
+                     case D3Q27System::TSW : x1b = x1a-q*dx  ; x2b = x2a-q*dx; x3b = x3a+q*dx; break;
+                     case D3Q27System::TSE : x1b = x1a+q*dx  ; x2b = x2a-q*dx; x3b = x3a+q*dx; break;
+                     case D3Q27System::BNW : x1b = x1a-q*dx  ; x2b = x2a+q*dx; x3b = x3a-q*dx; break;
+                     case D3Q27System::BSE : x1b = x1a+q*dx  ; x2b = x2a-q*dx; x3b = x3a-q*dx; break;
+                     case D3Q27System::TNW : x1b = x1a-q*dx  ; x2b = x2a+q*dx; x3b = x3a+q*dx; break;
+                     default: throw UbException(UB_EXARGS,"unknown direction");
+                     }
+                     pointpair.second.setX1(x1b);
+                     pointpair.second.setX2(x2b);
+                     pointpair.second.setX3(x3b);
+                     QsLineSet.push_back(pointpair);
+                  }
+               }
+
+            }
+         }
+      }
+   }
+   //cout<<"getQs: "<<QsLineSet.size()<<endl;
+   return QsLineSet;
+}
+
+void D3Q27Interactor::writeValidationAVSFile(string filename)
+{
+   UBLOG(logINFO,"D3Q27Interactor::writeValidationAVSFile("<<filename<<") - start ");
+   ofstream out(filename.c_str(),ios::out);
+   if(!out) throw UbException(UB_EXARGS,"couldn't open file "+filename);
+
+   int numpoints, numlines;
+   vector< pair<GbPoint3D,GbPoint3D> > qsLineSet = this->getQsLineSet();
+   numlines  = (unsigned)qsLineSet.size();
+   numpoints = numlines*2;
+
+   out<<"# UCD-File created by D3Q27Interactor\n";
+   out<<numpoints<<" "<<numlines<<" 0 0 0 "<<endl;
+   int nr=1;
+   for (int i=0; i<numlines; i++)
+   {
+      out<<nr++<<" "<<qsLineSet[i].first.getX1Coordinate() <<" " <<qsLineSet[i].first.getX2Coordinate() <<" " <<qsLineSet[i].first.getX3Coordinate() <<" \n";
+      out<<nr++<<" "<<qsLineSet[i].second.getX1Coordinate()<<" " <<qsLineSet[i].second.getX2Coordinate()<<" " <<qsLineSet[i].second.getX3Coordinate() <<" \n";
+   }
+   nr = 1;
+   for (int i=0; i<numlines; i++)
+   {
+      int el = nr+1;
+      out<<i+1<<" "<<2<<" line "<<nr<<" "<<el<<" "<<endl;
+      nr=el+1;
+   }
+   UBLOG(logINFO,"D3Q27Interactor::writeValidationAVSFile("<<filename<<") - end");
+}
diff --git a/source/VirtualFluidsCore/Interactors/D3Q27Interactor.h b/source/VirtualFluidsCore/Interactors/D3Q27Interactor.h
index fa350478c..f36f4a156 100644
--- a/source/VirtualFluidsCore/Interactors/D3Q27Interactor.h
+++ b/source/VirtualFluidsCore/Interactors/D3Q27Interactor.h
@@ -1,124 +1,104 @@
-//  _    ___      __              __________      _     __
-// | |  / (_)____/ /___  ______ _/ / ____/ /_  __(_)___/ /____
-// | | / / / ___/ __/ / / / __ `/ / /_  / / / / / / __  / ___/
-// | |/ / / /  / /_/ /_/ / /_/ / / __/ / / /_/ / / /_/ (__  )
-// |___/_/_/   \__/\__,_/\__,_/_/_/   /_/\__,_/_/\__,_/____/
-//
-#ifndef D3Q27INTERACTOR_H
-#define D3Q27INTERACTOR_H
-
-#include <string>
-#include <sstream>
-#include <vector>
-#include <list>
-#include <map>
-#include <set>
-#include <cmath>
-
-#include <boost/serialization/base_object.hpp>
-#include <boost/serialization/set.hpp>
-
-#include <boost/shared_ptr.hpp>
-
-class D3Q27Interactor;
-typedef boost::shared_ptr<D3Q27Interactor> D3Q27InteractorPtr;
-
-
-#include "UbException.h"
-#include "UbTuple.h"
-#include "ObFactory.h"
-#include "CoordinateTransformation3D.h"
-#include "GbPoint3D.h"
-#include "Interactor3D.h"
-#include "BCArray3D.h"
-#include "BCAdapter.h"
-#include "BoundaryConditions.h"
-#include "D3Q27System.h"
-
-class UbFileInput;
-class UbFileOutput;
-class GbObject3D;
-
-//////////////////////////////////////////////////////////////////////////
-class D3Q27Interactor : public Interactor3D 
-{
-public:
-   D3Q27Interactor();
-   D3Q27Interactor(GbObject3DPtr geoObject3D, Grid3DPtr grid, int type);
-   D3Q27Interactor(GbObject3DPtr geoObject3D, Grid3DPtr grid, BCAdapterPtr bcAdapter,  int type);
-   D3Q27Interactor(GbObject3DPtr geoObject3D, Grid3DPtr grid, BCAdapterPtr bcAdapter,  int type, Interactor3D::Accuracy a);
-
-   virtual ~D3Q27Interactor();
-
-   void setRelevantForForces(const bool& value) {  this->relevantForForces = value; }
-   bool isRelevantForForces() { return this->relevantForForces; }
-   //UbTupleDouble3 getForces();
-   //UbTupleDouble3 getForces(Patch3DPtr patch);
-
-   virtual void addBCAdapter(const BCAdapterPtr bcAdapter) { bcAdapterVector.push_back(bcAdapter); }
-   void deleteBCAdapter() { bcAdapterVector.clear(); }
-   //virtual std::vector< MbSmartPtr<D3Q27BoundaryConditionAdapter> > getBcAdapters() { return bcAdapterVector; }
-
- 
-   virtual void initInteractor(const double& timeStep=0);
-   void updateInteractor(const double& timestep=0); 
-   //virtual void updateMovedGeometry(const double& timeStep=0); 
-   //void updateNewNodes();
-   void setReinitWithStoredQs(bool reinitWithStoredQsFlag) { this->reinitWithStoredQsFlag = reinitWithStoredQsFlag; }
-   
-   void removeSolidBlocks() { Interactor3D::removeSolidBlocks(); solidNodeIndicesMap.clear(); }
-   void removeBcBlocks() { Interactor3D::removeBcBlocks(); bcNodeIndicesMap.clear(); }
-   virtual void removeBoundaryInformationOnBcNodes();
-
-   bool setDifferencesToGbObject3D(const Block3DPtr block/*, const double& x1, const double& x2, const double& x3, const double& blockLengthX1, const double& blockLengthX2, const double& blockLengthX3, const double& timestep=0*/);
-
-   ObObject* clone() { throw UbException(UB_EXARGS,"not implemented");	}
-   ObObjectCreator* getCreator();
-
-   //std::string toString();
-
-   //------------- implements CAB serialization ----- start
-   //void write(UbFileOutput* out);
-   //void read(UbFileInput* in);
-   //std::string writeTransNodes(std::string filename);
-   //std::string writeTransNodesAsTriangles(std::string filename);
-   void writeValidationAVSFile(std::string filename);  
-   virtual std::vector< std::pair<GbPoint3D,GbPoint3D> >  getQsLineSet();
-
-   void addQsLineSet(std::vector<UbTupleFloat3 >& nodes, std::vector<UbTupleInt2 >& lines);
-
-   const std::map<Block3DPtr, std::set< std::vector<int> > > & getBcNodeIndicesMap() { return bcNodeIndicesMap; }
-
-protected:
-   bool relevantForForces;
-   bool reinitWithStoredQsFlag;
-
-   //std::vector< MbSmartPtr<D3Q27BoundaryConditionAdapter> > bcAdapterVector;
-   std::vector<BCAdapterPtr> bcAdapterVector;
-   
-   typedef UbTuple<int,int,int,long long>  UbTupleInt3LongLong;
-
-   std::map<Block3DPtr, std::set< UbTupleInt3 > > solidNodeIndicesMap;  
-   std::map<Block3DPtr, std::set< std::vector<int> > > bcNodeIndicesMap;
-                                                                         //!!! es kann sein, dass in diesem interactor
-                                                                         //an eine rpos eine BC gesetzt wurde, aber derselbe node in
-                                                                         //in einem anderen in einen anderen Typ (z.B. Solid) geaendert
-                                                                         //wurde --> es ist keine BC mehr an der stelle!
-   
-   void   initRayVectors();
-   double rayX1[D3Q27System::FENDDIR+1];
-   double rayX2[D3Q27System::FENDDIR+1];
-   double rayX3[D3Q27System::FENDDIR+1];
-
-   friend class boost::serialization::access;
-   template<class Archive>
-   void serialize(Archive & ar, const unsigned int version)
-   {
-      ar & boost::serialization::base_object<Interactor3D>(*this);
-      ar & bcNodeIndicesMap;
-      ar & bcAdapterVector;
-   }
-};
-
-
-#endif
+//  _    ___      __              __________      _     __
+// | |  / (_)____/ /___  ______ _/ / ____/ /_  __(_)___/ /____
+// | | / / / ___/ __/ / / / __ `/ / /_  / / / / / / __  / ___/
+// | |/ / / /  / /_/ /_/ / /_/ / / __/ / / /_/ / / /_/ (__  )
+// |___/_/_/   \__/\__,_/\__,_/_/_/   /_/\__,_/_/\__,_/____/
+//
+#ifndef D3Q27INTERACTOR_H
+#define D3Q27INTERACTOR_H
+
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+#include <memory>
+
+#include <boost/serialization/base_object.hpp>
+#include <boost/serialization/set.hpp>
+
+#include "UbException.h"
+#include "UbTuple.h"
+#include "GbPoint3D.h"
+#include "Interactor3D.h"
+#include "D3Q27System.h"
+
+class D3Q27Interactor;
+typedef std::shared_ptr<D3Q27Interactor> D3Q27InteractorPtr;
+
+class BCAdapter;
+class Block3D;
+class Grid3D;
+class GbObject3D;
+
+typedef std::map<std::shared_ptr<Block3D>, std::set< std::vector<int> > > BcNodeIndicesMap;
+typedef std::map<std::shared_ptr<Block3D>, std::set< UbTupleInt3 > > SolidNodeIndicesMap;
+
+class D3Q27Interactor : public Interactor3D 
+{
+public:
+   D3Q27Interactor();
+   D3Q27Interactor(std::shared_ptr<GbObject3D> geoObject3D, std::shared_ptr<Grid3D> grid, int type);
+   D3Q27Interactor(std::shared_ptr<GbObject3D> geoObject3D, std::shared_ptr<Grid3D> grid, std::shared_ptr<BCAdapter> bcAdapter,  int type);
+   D3Q27Interactor(std::shared_ptr<GbObject3D> geoObject3D, std::shared_ptr<Grid3D> grid, std::shared_ptr<BCAdapter> bcAdapter,  int type, Interactor3D::Accuracy a);
+
+   virtual ~D3Q27Interactor();
+
+   void setRelevantForForces(const bool& value) {  this->relevantForForces = value; }
+   bool isRelevantForForces() { return this->relevantForForces; }
+
+   virtual void addBCAdapter(const std::shared_ptr<BCAdapter> bcAdapter) { bcAdapters.push_back(bcAdapter); }
+   void deleteBCAdapter() { bcAdapters.clear(); }
+
+ 
+   virtual void initInteractor(const double& timeStep=0);
+   void updateInteractor(const double& timestep=0); 
+
+   void setReinitWithStoredQs(bool reinitWithStoredQsFlag) { this->reinitWithStoredQsFlag = reinitWithStoredQsFlag; }
+   
+   void removeSolidBlocks() { Interactor3D::removeSolidBlocks(); solidNodeIndicesMap.clear(); }
+   void removeBcBlocks() { Interactor3D::removeBcBlocks(); bcNodeIndicesMap.clear(); }
+
+   bool setDifferencesToGbObject3D(const std::shared_ptr<Block3D> block/*, const double& x1, const double& x2, const double& x3, const double& blockLengthX1, const double& blockLengthX2, const double& blockLengthX3, const double& timestep=0*/);
+
+   ObObject* clone() { throw UbException(UB_EXARGS,"not implemented");	}
+   ObObjectCreator* getCreator();
+
+
+   void writeValidationAVSFile(std::string filename);  
+   virtual std::vector< std::pair<GbPoint3D,GbPoint3D> >  getQsLineSet();
+
+   void addQsLineSet(std::vector<UbTupleFloat3 >& nodes, std::vector<UbTupleInt2 >& lines);
+
+   const BcNodeIndicesMap& getBcNodeIndicesMap() const { return bcNodeIndicesMap; }
+
+protected:
+   bool relevantForForces;
+   bool reinitWithStoredQsFlag;
+
+   std::vector<std::shared_ptr<BCAdapter> > bcAdapters;
+   
+
+   SolidNodeIndicesMap solidNodeIndicesMap;
+   BcNodeIndicesMap bcNodeIndicesMap;
+                                                                         //!!! es kann sein, dass in diesem interactor
+                                                                         //an eine rpos eine BC gesetzt wurde, aber derselbe node in
+                                                                         //in einem anderen in einen anderen Typ (z.B. Solid) geaendert
+                                                                         //wurde --> es ist keine BC mehr an der stelle!
+   
+   void   initRayVectors();
+   double rayX1[D3Q27System::FENDDIR+1];
+   double rayX2[D3Q27System::FENDDIR+1];
+   double rayX3[D3Q27System::FENDDIR+1];
+
+   friend class boost::serialization::access;
+   template<class Archive>
+   void serialize(Archive & ar, const unsigned int version)
+   {
+      ar & boost::serialization::base_object<Interactor3D>(*this);
+      ar & bcNodeIndicesMap;
+      ar & bcAdapters;
+   }
+};
+
+
+#endif
diff --git a/source/VirtualFluidsCore/Interactors/D3Q27TriFaceMeshInteractor.cpp b/source/VirtualFluidsCore/Interactors/D3Q27TriFaceMeshInteractor.cpp
index f091eda64..ea9a6478d 100644
--- a/source/VirtualFluidsCore/Interactors/D3Q27TriFaceMeshInteractor.cpp
+++ b/source/VirtualFluidsCore/Interactors/D3Q27TriFaceMeshInteractor.cpp
@@ -1,1834 +1,1837 @@
-#include "D3Q27TriFaceMeshInteractor.h"
-#include <basics/utilities/UbMath.h>
-#include <basics/utilities/UbLogger.h>
-#include <basics/utilities/UbStaticPathMap.h>
-
-#include <basics/writer/WbWriterVtkBinary.h>
-#include <basics/writer/WbWriterVtkXmlBinary.h>
-#include <basics/writer/WbWriterVtkASCII.h>
-#include "basics/writer/WbWriterVtkXmlASCII.h"
-
-#include <numerics/geometry3d/GbSystem3D.h>
-#include <numerics/geometry3d/GbCuboid3D.h>
-#include <numerics/geometry3d/GbHalfSpace3D.h>
-#include <numerics/geometry3d/GbMeshTools3D.h>
-#include "Block3D.h"
-#include "Grid3D.h"
-#include "BCArray3D.h"
-#include "BoundaryConditions.h"
-#include "VelocityBCAdapter.h"
-#include "LBMKernel.h"
-#include "BCProcessor.h"
-#include "basics/utilities/UbTiming.h"
-
-#include <omp.h>
-
-#include <stack>
-
-using namespace std;
-
-D3Q27TriFaceMeshInteractor::D3Q27TriFaceMeshInteractor()
-: D3Q27Interactor(), forceshift(0.0), velocityshift(0.0), forceshiftpolicy(false), velocityshiftpolicy(false), useHalfSpace(true), regardPIOTest(true)
-{
-   this->stressMode = STRESSNORMAL;
-}
-//////////////////////////////////////////////////////////////////////////
-D3Q27TriFaceMeshInteractor::D3Q27TriFaceMeshInteractor(Grid3DPtr grid, std::string name)
-{
-   this->stressMode = STRESSNORMAL;
-}
-//////////////////////////////////////////////////////////////////////////
-D3Q27TriFaceMeshInteractor::D3Q27TriFaceMeshInteractor(GbTriFaceMesh3DPtr triFaceMesh, Grid3DPtr grid, BCAdapterPtr bcAdapter, int type)
-: D3Q27Interactor(triFaceMesh, grid, bcAdapter, type), forceshift(0.0), velocityshift(0.0), forceshiftpolicy(false), velocityshiftpolicy(false), useHalfSpace(true), regardPIOTest(true)
-{
-   this->stressMode = STRESSNORMAL;
-}
-//////////////////////////////////////////////////////////////////////////
-D3Q27TriFaceMeshInteractor::D3Q27TriFaceMeshInteractor(GbTriFaceMesh3DPtr triFaceMesh, Grid3DPtr grid, BCAdapterPtr bcAdapter, int type, Interactor3D::Accuracy a)
-   : D3Q27Interactor(triFaceMesh, grid, bcAdapter, type, a), forceshift(0.0), velocityshift(0.0), forceshiftpolicy(false), velocityshiftpolicy(false), useHalfSpace(true), regardPIOTest(true)
-{
-   this->stressMode = STRESSNORMAL;
-}
-//////////////////////////////////////////////////////////////////////////
-D3Q27TriFaceMeshInteractor::~D3Q27TriFaceMeshInteractor()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-void D3Q27TriFaceMeshInteractor::initInteractor(const double& timeStep)
-{
-   Interactor3D::initInteractor(timeStep);
-   setQs(timeStep);
-}
-//////////////////////////////////////////////////////////////////////////
-bool D3Q27TriFaceMeshInteractor::setDifferencesToGbObject3D(const Block3DPtr block/*,const double& orgX1,const double& orgX2,const double& orgX3,const double& blockLengthX1,const double& blockLengthX2,const double& blockLengthX3, const double& timestep*/)
-{
-   if(!block) return false;
-
-   bcNodeIndicesMap[block] = set< std::vector<int> >();
-   set< std::vector<int> >& transNodeIndices = bcNodeIndicesMap[block];
-   solidNodeIndicesMap[block] = set< UbTupleInt3 >();
-   set< UbTupleInt3 >& solidNodeIndices = solidNodeIndicesMap[block];
-
-
-   bool oneEntryGotBC = false; //ob ueberhaupt ein eintrag ein BC zugewiesen wurde
-   bool gotQs         = false; //true, wenn "difference" gesetzt wurde
-   BoundaryConditionsPtr bc;
-
-   LBMKernelPtr kernel = block->getKernel();
-   BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
-
-   double internX1,internX2,internX3;
-  
-   int startIX1 = 0, startIX2 = 0, startIX3 = 0; 
-   int stopIX1  = (int)bcArray->getNX1(), stopIX2  = (int)bcArray->getNX2(), stopIX3  = (int)bcArray->getNX3(); 
-
-   double         dx       = grid.lock()->getDeltaX(block);
-   UbTupleDouble3 orgDelta = grid.lock()->getNodeOffset(block);
-
-   bool pointOnBoundary = false;
-
-   for(int ix3=startIX3; ix3<stopIX3; ix3++)
-   {
-      for(int ix2=startIX2; ix2<stopIX2; ix2++)
-      {
-         for(int ix1=startIX1; ix1<stopIX1; ix1++)
-         {
-            UbTupleDouble3 coords = grid.lock()->getNodeCoordinates(block, ix1, ix2, ix3);
-            internX1 = val<1>(coords);
-            internX2 = val<2>(coords);
-            internX3 = val<3>(coords);
-
-            if(this->isSolid() )
-            {
-               if(this->geoObject3D->isPointInGbObject3D(internX1, internX2, internX3))
-               {
-                  if(bcArray->isFluid(ix1,ix2,ix3))
-                  {
-                     solidNodeIndices.insert(UbTupleInt3(ix1, ix2, ix3));
-                     bcArray->setSolid(ix1,ix2,ix3); 
-                  }
-               }
-            }
-            else if( this->isInverseSolid()  )
-            {
-               //bei inverse solid sind alle Knoten AUSSERHALB und auf der boundary SOLID
-               if( !this->geoObject3D->isPointInGbObject3D(internX1, internX2, internX3, pointOnBoundary) || pointOnBoundary == true )
-               {
-                  if(bcArray->isFluid(ix1,ix2,ix3))
-                  {
-                     solidNodeIndices.insert(UbTupleInt3(ix1, ix2, ix3));
-                     bcArray->setSolid(ix1,ix2,ix3);
-                  }
-               }
-            }
-         }
-      }
-   }
-
-   return oneEntryGotBC;
-}
-//////////////////////////////////////////////////////////////////////////
-//E.F. /4/16/2013
-void D3Q27TriFaceMeshInteractor::setQs(const double& timeStep)
-{
-   UBLOGML(logDEBUG1,"\nLBMTriFaceMeshInteractor - setQs start ");
-   if( !this->grid.lock() ) throw UbException(UB_EXARGS,"ups, no grid.lock()!!");
-
-   if( this->reinitWithStoredQsFlag && !bcNodeIndicesAndQsMap.empty() )
-   {
-      this->reinitWithStoredQs(timeStep);
-      return;
-   }
-
-   GbTriFaceMesh3D* mesh  = dynamic_cast<GbTriFaceMesh3D*>(this->geoObject3D.get());
-
-   //////////////////////////////////////////////////////////////////////////
-   //init bcs
-   //////////////////////////////////////////////////////////////////////////
-   int nofAdapter = (int)this->bcAdapterVector.size();
-   if(nofAdapter==0) std::cout<<"WARNING - D3Q27TriFaceMeshInteractor::initInteractor Warning - no nodeAdapter available for "/*<<this->getName()*/<<std::endl;
-   bool needTimeDependence = false;
-   for(int pos=0; pos<nofAdapter; ++pos)
-   {
-      this->bcAdapterVector[pos]->init(this,timeStep);
-      if(this->bcAdapterVector[pos]->isTimeDependent()) needTimeDependence = true;
-   }
-   if(needTimeDependence) this->setTimeDependent();
-   else                   this->unsetTimeDependent();
-
-   //////////////////////////////////////////////////////////////////////////
-   //grid.lock() info
-   //////////////////////////////////////////////////////////////////////////
-   int coarsestInitLevel = grid.lock()->getCoarsestInitializedLevel();
-   int finestInitLevel   = grid.lock()->getFinestInitializedLevel();
-
-   UbTupleInt3 blocknx = grid.lock()->getBlockNX();
-   int blocknx1 = val<1>(blocknx); //gilt fuer alle Level
-   int blocknx2 = val<2>(blocknx); //gilt fuer alle Level
-   int blocknx3 = val<3>(blocknx); //gilt fuer alle Level
-
-   //grobe Blocklaengen
-   CoordinateTransformation3DPtr trafo = grid.lock()->getCoordinateTransformator();
-   double cblockDeltaX1,cblockDeltaX2,cblockDeltaX3, delta ;
-   cblockDeltaX1 = cblockDeltaX2 = cblockDeltaX3 = delta = 1.0/(double)(1<<coarsestInitLevel);
-   if(trafo)
-   {
-      cblockDeltaX1 = trafo->getX1CoordinateScaling()*delta;
-      cblockDeltaX2 = trafo->getX2CoordinateScaling()*delta;
-      cblockDeltaX3 = trafo->getX3CoordinateScaling()*delta;
-   }
-   //levelspezifische blocklaengen und knotenabstaende
-   std::vector< std::vector<double> > nodeDeltaToNeigh(finestInitLevel+1);
-   std::vector<float>  deltaMinX1(finestInitLevel+1),deltaMinX2(finestInitLevel+1),deltaMinX3(finestInitLevel+1);
-   std::vector<float>  deltaMaxX1(finestInitLevel+1),deltaMaxX2(finestInitLevel+1),deltaMaxX3(finestInitLevel+1);
-
-   //Im Boltzmankontext muss dx1==dx2==dx3 sein!!
-   assert( UbMath::equal(cblockDeltaX1/(double)blocknx1, cblockDeltaX2/(double)blocknx2 ) );
-   assert( UbMath::equal(cblockDeltaX1/(double)blocknx1, cblockDeltaX3/(double)blocknx3 ) );
-
-   for(int level = coarsestInitLevel; level<=finestInitLevel; level++)
-   {
-      double nodeDeltaX1 = cblockDeltaX1/(double)(blocknx1*(1<<(level-coarsestInitLevel)));
-      double nodeDeltaX2 = cblockDeltaX2/(double)(blocknx2*(1<<(level-coarsestInitLevel)));
-      double nodeDeltaX3 = cblockDeltaX3/(double)(blocknx3*(1<<(level-coarsestInitLevel)));
-
-      std::vector<double> distNeigh(D3Q27System::FENDDIR+1, 0.0);
-      D3Q27System::calcDistanceToNeighbors(distNeigh, nodeDeltaX1,nodeDeltaX2,nodeDeltaX3);
-      //D3Q27System::calcDistanceToNeighbors(distNeigh, nodeDeltaX1);
-
-
-      nodeDeltaToNeigh[level].resize(D3Q27System::ENDDIR+1,0.0);
-      for(int fdir=D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
-      {
-         nodeDeltaToNeigh[level][fdir] = distNeigh[fdir];
-      }
-
-      //im gegensatz zum allg. Cell3DInteractor kann man hier auf max(0.02*blockDeltaX1[level],fabs(...)) verzichten
-      //da dies nur für blockDeltaCalculator->getMinX1Delta(level)==0.0 benötigt wird. ist im D3Q19... aber nie so
-      //Geller: kann man nicht diesen befuckten DeltaCalculator weglassen und hier einfach die Formel zum Delta rechnen reinpacken
-      //SirAnn: klar, mann kann auch weißwuerste am Alex verkaufen... aber zum einen ist das Ding dazu da
-      // und zum anderen sollt eman mal überlegen: "Formel zum Delta rechnen"->man muss rechnen
-      // blockDeltaCalculator->getMinX1Delta(level) -> ein geinlinter wert wird geholt 
-
-      //TODO: set 5.0 as variable parameter in constructor, default 2.0 
-      deltaMinX1[level] = (float)( 5.0*nodeDeltaX1); //kein minus da unten -deltaMin
-      deltaMinX2[level] = (float)( 5.0*nodeDeltaX2);
-      deltaMinX3[level] = (float)( 5.0*nodeDeltaX3);
-      deltaMaxX1[level] = (float)( 5.0*nodeDeltaX1);
-      deltaMaxX2[level] = (float)( 5.0*nodeDeltaX2);
-      deltaMaxX3[level] = (float)( 5.0*nodeDeltaX3);
-   }
-
-   //////////////////////////////////////////////////////////////////////////
-   //bounding cubes des TriFaceMesh ermitteln (pro level)
-   //////////////////////////////////////////////////////////////////////////
-   //min/max Werte des Dreiecksnetzes holen
-   double geoMinX1(0.0), geoMinX2(0.0), geoMinX3(0.0), geoMaxX1(0.0), geoMaxX2(0.0), geoMaxX3(0.0);
-
-   geoMinX1 = this->geoObject3D->getX1Minimum();  geoMaxX1 = this->geoObject3D->getX1Maximum();
-   geoMinX2 = this->geoObject3D->getX2Minimum();  geoMaxX2 = this->geoObject3D->getX2Maximum();
-   geoMinX3 = this->geoObject3D->getX3Minimum();  geoMaxX3 = this->geoObject3D->getX3Maximum();
-
-
-   //////////////////////////////////////////////////////////////////////////
-   //DREIECKE: q-Bestimmung
-   //////////////////////////////////////////////////////////////////////////
-
-   //notwendige variablen initialisieren (u.a. blockDeltas des groben levels)
-   float triPoints[3][3];
-   float vx1=0.0, vx2=0.0, vx3=0.0;
-   unsigned counterTriBoxOverlap=0, counterAABBTriFace=0, counterHalfspace=0, counterBilligOBB=0;
-   std::vector<GbTriFaceMesh3D::TriFace>& triangles = *mesh->getTriangles();
-   std::vector<GbTriFaceMesh3D::Vertex>&  nodes     = *mesh->getNodes();
-   std::map< Block3DPtr, std::set< UbTupleInt3 > > tmpSolidNodesFromOtherInteractors;
-
-   int onePercent = UbMath::integerRounding(triangles.size()*0.01);
-   if(onePercent==0) onePercent=1;
-   UbTimer setQTimer; setQTimer.start();
-   UBLOG(logDEBUG3, " - setQs for "<<(int)triangles.size()<<" triangles");
-
-   bool solidFromOtherInteractor = false;
-   float blockMinX[3],blockMaxX[3],boxCenter[3],halfBoxSize[3];
-
-   for(size_t t=0; t<triangles.size(); t++)
-   {
-      //////////////////////////////////////////////////////////////////////////
-      // Halfspace zum Dreieck generieren und min/max des Dreiecks ermitteln
-      //////////////////////////////////////////////////////////////////////////
-      GbTriFaceMesh3D::TriFace& triangle = triangles[t];
-
-      GbTriFaceMesh3D::Vertex& v1 = nodes[triangle.v1];
-      GbTriFaceMesh3D::Vertex& v2 = nodes[triangle.v2];
-      GbTriFaceMesh3D::Vertex& v3 = nodes[triangle.v3];
-
-      if(this->isInverseSolid() )
-      {					
-         triangle.nx*=(-1);
-         triangle.ny*=(-1);
-         triangle.nz*=(-1);	
-      }
-      GbHalfSpace3D halfSpace(  v1.x,v1.y,v1.z,triangle.nx,triangle.ny,triangle.nz );
-
-      //////////////////////////////////////////////////////////////////////////
-      //fuer GbMeshTools3D::triBoxOverlap
-      //////////////////////////////////////////////////////////////////////////
-      triPoints[0][0] = v1.x; triPoints[0][1] = v1.y; triPoints[0][2] = v1.z;
-      triPoints[1][0] = v2.x; triPoints[1][1] = v2.y; triPoints[1][2] = v2.z;
-      triPoints[2][0] = v3.x; triPoints[2][1] = v3.y; triPoints[2][2] = v3.z;
-
-      double minX1 = triangle.getMinX(nodes);   double maxX1 = triangle.getMaxX(nodes);
-      double minX2 = triangle.getMinY(nodes);   double maxX2 = triangle.getMaxY(nodes);
-      double minX3 = triangle.getMinZ(nodes);   double maxX3 = triangle.getMaxZ(nodes);
-
-      //////////////////////////////////////////////////////////////////////////
-      // Schleife ueber alle Level
-      //////////////////////////////////////////////////////////////////////////
-      double e1x1,e1x2,e1x3,e2x1,e2x2,e2x3,px1,px2,px3,a,f,sx1,sx2,sx3,u,qx1,qx2,qx3,v;
-      bool gotQs = false;
-      BoundaryConditionsPtr bc;
-
-      for(int level=coarsestInitLevel; level<=finestInitLevel; level++)
-      {
-         //////////////////////////////////////////////////////////////////////////
-         // levelspezifisches BoundCube des Dreicks ermitteln und zugehörige Bloecke beziehen
-         //////////////////////////////////////////////////////////////////////////
-         double boundCubeTriangleMinX1 = minX1-deltaMinX1[level];  double boundCubeTriangleMaxX1 = maxX1+deltaMaxX1[level];
-         double boundCubeTriangleMinX2 = minX2-deltaMinX2[level];  double boundCubeTriangleMaxX2 = maxX2+deltaMaxX2[level];
-         double boundCubeTriangleMinX3 = minX3-deltaMinX3[level];  double boundCubeTriangleMaxX3 = maxX3+deltaMaxX3[level];
-
-         GbCuboid3D boundingCubeTriangle(  boundCubeTriangleMinX1, boundCubeTriangleMinX2, boundCubeTriangleMinX3
-            , boundCubeTriangleMaxX1, boundCubeTriangleMaxX2, boundCubeTriangleMaxX3 );
-
-         std::vector<Block3DPtr> triBlocks;
-         grid.lock()->getBlocksByCuboid(level, boundCubeTriangleMinX1, boundCubeTriangleMinX2, boundCubeTriangleMinX3
-            , boundCubeTriangleMaxX1, boundCubeTriangleMaxX2, boundCubeTriangleMaxX3, triBlocks );
-
-         //////////////////////////////////////////////////////////////////////////
-         // Schleife ueber bloecke des level, die das dreieck beinhalten
-         //////////////////////////////////////////////////////////////////////////
-         for(std::size_t b=0; b<triBlocks.size(); b++)
-         {
-            Block3DPtr block = triBlocks[b];
-
-            ////////////////////////////////////////////////////////////////////////////
-            //// Block Dreieck-/test
-            ////////////////////////////////////////////////////////////////////////////
-            UbTupleDouble3 coords = grid.lock()->getBlockWorldCoordinates(block);
-            UbTupleDouble3 deltas = grid.lock()->getBlockLengths(block);
-
-            blockMinX[0]   = (float)(val<1>(coords)-deltaMinX1[level]);
-            blockMinX[1]   = (float)(val<2>(coords)-deltaMinX2[level]);
-            blockMinX[2]   = (float)(val<3>(coords)-deltaMinX3[level]);
-
-            blockMaxX[0]   = (float)(val<1>(coords)+val<1>(deltas)+deltaMaxX1[level]);
-            blockMaxX[1]   = (float)(val<2>(coords)+val<2>(deltas)+deltaMaxX2[level]);
-            blockMaxX[2]   = (float)(val<3>(coords)+val<3>(deltas)+deltaMaxX3[level]);
-
-            boxCenter[0]   = (float)(0.5*(blockMaxX[0]+blockMinX[0]));
-            boxCenter[1]   = (float)(0.5*(blockMaxX[1]+blockMinX[1]));
-            boxCenter[2]   = (float)(0.5*(blockMaxX[2]+blockMinX[2]));
-
-            halfBoxSize[0] = (float)(0.5*(blockMaxX[0]-blockMinX[0]));
-            halfBoxSize[1] = (float)(0.5*(blockMaxX[1]-blockMinX[1]));
-            halfBoxSize[2] = (float)(0.5*(blockMaxX[2]-blockMinX[2]));
-
-            //wenn dreieck "vergroesserten cube" nicht schneidet/beruehrt -> keine BC moeglich -> continue
-            if( !GbMeshTools3D::triBoxOverlap(boxCenter,halfBoxSize,triPoints) )
-            {
-               counterTriBoxOverlap++;
-               continue;
-            }
-
-            //////////////////////////////////////////////////////////////////////////
-            //Untersuchung der einzelnen nodes
-            //////////////////////////////////////////////////////////////////////////
-            bool blockGotBCs = false;
-
-            LBMKernelPtr kernel = block->getKernel();
-            BCArray3DPtr bcMatrix = kernel->getBCProcessor()->getBCArray();
-
-            int indexMinX1 = 0;
-            int indexMinX2 = 0;
-            int indexMinX3 = 0;
-
-            int indexMaxX1 = (int)bcMatrix->getNX1();
-            int indexMaxX2 = (int)bcMatrix->getNX2();
-            int indexMaxX3 = (int)bcMatrix->getNX3();
-
-            std::set< std::vector<int> >& bcNodeIndices           = this->bcNodeIndicesMap[block];
-            std::set< UbTupleInt3 >& solidsFromOtherInteractors = tmpSolidNodesFromOtherInteractors[block];
-            double q, distance;
-
-            double& nodeDx1 = nodeDeltaToNeigh[level][D3Q27System::E];
-            double& nodeDx2 = nodeDeltaToNeigh[level][D3Q27System::N];
-            double& nodeDx3 = nodeDeltaToNeigh[level][D3Q27System::T];
-
-            //fuer OBB-Test
-            double qEinflussDelta = 1.1 * sqrt( nodeDx1*nodeDx1 + nodeDx2*nodeDx2 + nodeDx3*nodeDx3);
-
-            for(int ix3=indexMinX3; ix3<indexMaxX3; ix3++)
-            {
-               for(int ix2=indexMinX2; ix2<indexMaxX2; ix2++)
-               {
-                  for(int ix1=indexMinX1; ix1<indexMaxX1; ix1++)
-                  {	
-                     UbTupleDouble3 pointplane1 =  grid.lock()->getNodeCoordinates(block, ix1,ix2,ix3);
-                     double   internX1=val<1>(pointplane1);
-                     double   internX2=val<2>(pointplane1);
-                     double   internX3=val<3>(pointplane1);
-
-                     int blx1 =block->getX1();
-                     int blx2 = block->getX2();
-                     int blx3 = block->getX3();
-
-                     if(bcMatrix->isSolid(ix1,ix2,ix3) || bcMatrix->isUndefined(ix1,ix2,ix3))
-                     {
-                        continue;
-                     }
-
-                     //////////////////////////////////////////////////////////////////////////
-                     //Punkt in AABB von Dreieck?                     
-                     //////////////////////////////////////////////////////////////////////////
-                     //ehsan changed
-                     bool pointIsOnBoundary = true;
-                     if( !boundingCubeTriangle.isPointInGbObject3D(internX1, internX2, internX3,pointIsOnBoundary) ) 
-                     {
-                        counterAABBTriFace++;
-                        continue;
-                     }
-                     //std::cout<<"internX3  "<<internX3<<"  internX2"<<internX2<<" internX1 "<<internX1<<"\n";
-                     //////////////////////////////////////////////////////////////////////////
-                     // Halbebenentests
-                     //////////////////////////////////////////////////////////////////////////
-                     distance = halfSpace.getDistance( internX1, internX2, internX3 );
-                     //Punkt in Halbebene? (nein, wenn distance<0)
-                     if(useHalfSpace && UbMath::less(distance, 0.0) )//== !halfSpace.ptInside(internX1,internX2,internX3) )
-                     {
-                        counterHalfspace++;
-                        continue;
-                     }
-
-                     //BilligOBB-Test: wenn distance > qEinflussDelta -> kein q
-                     if( UbMath::greater( fabs(distance), qEinflussDelta ) )
-                     {
-                        counterBilligOBB++;
-                        continue;
-                     }
-
-                     /////////////////////////////////////////////////////////////////////////////
-                     //Raytracingfür diskrete Boltzmannrichtungen
-                     /////////////////////////////////////////////////////////////////////////////
-                     gotQs = false;
-                     bc    = BoundaryConditionsPtr();
-
-                     //RAYTRACING - diskrete LB-dir zu Dreick
-                     //e1 = v1 - v0
-                     e1x1 = v2.x-v1.x;
-                     e1x2 = v2.y-v1.y;
-                     e1x3 = v2.z-v1.z;
-
-                     //e2 = v2 - v0
-                     e2x1 = v3.x-v1.x;
-                     e2x2 = v3.y-v1.y;
-                     e2x3 = v3.z-v1.z;
-
-                     //s = o - v0
-                     sx1 = internX1 - v1.x;
-                     sx2 = internX2 - v1.y;
-                     sx3 = internX3 - v1.z;
-
-                     for(int fdir=D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
-                     {
-                        //p = d x e2
-                        px1 = this->rayX2[fdir]*e2x3 - this->rayX3[fdir]*e2x2;
-                        px2 = this->rayX3[fdir]*e2x1 - this->rayX1[fdir]*e2x3;
-                        px3 = this->rayX1[fdir]*e2x2 - this->rayX2[fdir]*e2x1;
-
-                        //a = e1 dot p
-                        a = e1x1*px1 + e1x2*px2 + e1x3*px3;
-                        if(fabs(a)<1.E-10) continue;
-                        f = 1.0/a;
-
-                        //u = f * ( s dot p)
-                        u = f * ( sx1*px1 + sx2*px2 + sx3*px3 );
-                        if(u<-1.E-10 || u>1.0+1.E-10) continue;
-
-                        //q = s x e1
-                        qx1 = sx2*e1x3 - sx3*e1x2;
-                        qx2 = sx3*e1x1 - sx1*e1x3;
-                        qx3 = sx1*e1x2 - sx2*e1x1;
-
-                        //v = f*(e2 dot q)
-                        v = f * (this->rayX1[fdir]*qx1 + this->rayX2[fdir]*qx2 + this->rayX3[fdir]*qx3);
-                        if(v<-1.E-10 || (u+v)>1.0+1.E-10) continue;
-
-                        //t = f * (e2 dot q)
-                        q = f * (e2x1*qx1 + e2x2*qx2 + e2x3*qx3);
-                        q /= nodeDeltaToNeigh[level][fdir];
-                        /////ehsan q/////////////////////////////////////////////////////////////////////
-                        double det=triangle.nx * this->rayX1[fdir]+ triangle.ny * this->rayX2[fdir]+ triangle.nz * this->rayX3[fdir];
-
-                        if(det>-1.E-10) continue;
-                        double d=triangle.nx*v1.x+triangle.ny*v1.y+triangle.nz*v1.z;
-                        double x1= -((-d* this->rayX1[fdir] - triangle.ny *this->rayX2[fdir]* internX1 - triangle.nz *this->rayX3[fdir]* internX1 + triangle.ny *this->rayX1[fdir]* internX2 + triangle.nz* this->rayX1[fdir]* internX3))/det;
-                        double y1= -((-d* this->rayX2[fdir] + triangle.nx* this->rayX2[fdir]* internX1 - triangle.nx* this->rayX1[fdir]* internX2 - triangle.nz* this->rayX3[fdir] *internX2 + triangle.nz* this->rayX2[fdir]* internX3))/det;
-                        double z1=	-((-d* this->rayX3[fdir] + triangle.nx* this->rayX3[fdir]* internX1 + triangle.ny* this->rayX3[fdir]* internX2 - triangle.nx* this->rayX1[fdir]* internX3 - triangle.ny* this->rayX2[fdir]* internX3))/det;
-                        double q_ehsan=sqrt((x1-internX1)*(x1-internX1)+(y1-internX2)*(y1-internX2)+(z1-internX3)*(z1-internX3));
-                        q_ehsan /= nodeDeltaToNeigh[level][fdir];
-                        q=q_ehsan;	 
-                        if( UbMath::greater(q, 1.0) || UbMath::lessEqual(q, 0.0) )continue;
-
-                        //gefundenes q auf gueltigkeit pruefen
-                        if( UbMath::zero(q) )
-                        {
-                           //neu (18.05.2010)
-                           //es kann vorkommen, dass bei dünnwandigen geos punkte, die auf einem dreieck liegen, qs bekommen, die durch die geo
-                           //durchgehen. diese punkte werden später jedoch nicht mehr auf solid getestet, da sie ja ne BC bekommen haben
-                           //--> da mind ein q==0.0 für eines der dreiecke -> dort solid setzen
-                           this->solidNodeIndicesMap[block].insert( UbTupleInt3(ix1,ix2,ix3) );
-                           bcMatrix->setSolid( ix1, ix2, ix3 );
-                           continue;
-                        }
-
-                        if( UbMath::inClosedInterval(q, 1.0, 1.0) ) q = 1.0;
-                        if( UbMath::greater(q, 0.0) && UbMath::lessEqual(q, 1.0) )
-                        {
-                           gotQs=blockGotBCs=true;
-
-                           bc = bcMatrix->getBC(ix1,ix2,ix3);
-
-                           //SG 26.08.2010 if(!bc && !bcMatrix->isSolid())
-                           if(!bc)
-                           {
-                              bc = BoundaryConditionsPtr(new BoundaryConditions);;
-                              bcMatrix->setBC(ix1,ix2,ix3,bc);
-                           }
-                           else if( UbMath::less( bc->getQ(fdir), q ) )  //schon ein kuerzeres q voehanden?
-                           {
-                              //neu:: 18.05.2010
-                              //um falsche qs die evtl durch die "wand" gehen zu vermeiden 
-                              //q nur dann neu setzen, wenn neues q kleiner als vorhandenes!
-                              //Zudem: insbesondere an ecken mit zwei BC geos ist nur das 
-                              //naehere gueltig
-                              continue;
-                           }
-
-                           bc->setBoundaryVelocityX1(vx1);
-                           bc->setBoundaryVelocityX2(vx2);
-                           bc->setBoundaryVelocityX3(vx3);
-
-                           for(int index=(int)this->bcAdapterVector.size()-1; index>=0; --index)
-                              this->bcAdapterVector[index]->adaptBCForDirection(*this,bc,internX1,internX2,internX3,q,fdir);
-
-                           //fuer beschleunigtes wiedereinlesen
-                           if(this->reinitWithStoredQsFlag)
-                           {
-                              bcNodeIndicesAndQsMap[block][ UbTupleInt3(ix1, ix2, ix3) ].resize(D3Q27System::FENDDIR+1+3, -1.0f);
-                              bcNodeIndicesAndQsMap[block][ UbTupleInt3(ix1, ix2, ix3) ][fdir                    ] = float(q);
-                              bcNodeIndicesAndQsMap[block][ UbTupleInt3(ix1, ix2, ix3) ][D3Q27System::FENDDIR+1+0] = float(internX1);
-                              bcNodeIndicesAndQsMap[block][ UbTupleInt3(ix1, ix2, ix3) ][D3Q27System::FENDDIR+1+1] = float(internX2);
-                              bcNodeIndicesAndQsMap[block][ UbTupleInt3(ix1, ix2, ix3) ][D3Q27System::FENDDIR+1+2] = float(internX3);
-                           }
-                        }
-                     }
-
-                     if(gotQs)
-                     {
-                        std::vector<int> p(3);
-                        p[0]=ix1; p[1]=ix2; p[2]=ix3;
-                        bcNodeIndices.insert(p);
-
-                        for(int index=(int)this->bcAdapterVector.size()-1; index>=0; --index)
-                           this->bcAdapterVector[index]->adaptBC(*this,bc,internX1,internX2,internX3);
-                     }
-                  }
-               }
-            }
-         }
-         //dynamische Punkte des GbCuboids muessen leider per "Hand" geloescht werden :-(
-         boundingCubeTriangle.finalize();
-      }
-   }
-   UBLOGML(logDEBUG1,"\nLBMTriFaceMeshInteractor - setQs end ");
-}
-//////////////////////////////////////////////////////////////////////////
-//Vorgehesnweise
-//A – Bestimmung der q's
-//  1. fuer jeden Bounding cube eines Dreiecks des netzes werden die Bloecke des Blockgitter ermittelt
-//  2. mittels eines Dreieck/Block Verschneidungstest werden weitere nicht relevante Bloecke aussortiert
-//     (fuer lange „schief“ im Raum stehende Dreicke, bei denen das Bounding Cube suboptimal ist)
-//  3. jeder Knoten dieser blöcke wird gegen das bound cube des dreiecks getestet
-//  4. Knoten die innerhalb des Cubes aber „innerhalb“ des Netzes liegen werden mittels Halbebenentest aussoriert
-//  5. fuer die restliche Knoten erfolgt die q bestimmung mittels effizienter raytracing algorithmen
-//     fuer die diskreten Boltzmannrichtungen
-//B – Setzen der nicht aktiven Bloecke und Solid Nodes
-//  alle Bloecke des Bounding Cube des Netzes, die mind eine BC erhielten, wurden in A markiert
-//  1. fuer nicht markierte Bloecke genuegt EIN pointInObject(Dreicksnetz)-Test um den gesamten Block bei Erfolg als „not active“ zu markieren
-//  2. fuer markiertre Bloecke wird ein rekursiver Fuellalgorithmus durchgefuehrt
-void D3Q27TriFaceMeshInteractor::initInteractor2(const double& timeStep)
-{
-   UBLOGML(logDEBUG1,"\nLBMTriFaceMeshInteractor - initInteractor start ");
-   if( !this->grid.lock() ) throw UbException(UB_EXARGS,"ups, no grid.lock()!!");
-
-   if( this->reinitWithStoredQsFlag && !bcNodeIndicesAndQsMap.empty() )
-   {
-      this->reinitWithStoredQs(timeStep);
-      return;
-   }
-
-   GbTriFaceMesh3D* mesh  = dynamic_cast<GbTriFaceMesh3D*>(this->geoObject3D.get());
-
-   UBLOGML(logDEBUG1,"\nLBMTriFaceMeshInteractor - initInteractor for \""<<mesh->getName()<<" \" t="<<timeStep);
-   //cout<<" - init basics ...";
-
-   this->removeBcBlocks();  //hier wird auch die nodeIndicesMap geloescht!
-   this->removeSolidBlocks();
-
-   //////////////////////////////////////////////////////////////////////////
-   //init bcs
-   //////////////////////////////////////////////////////////////////////////
-   int nofAdapter = (int)this->bcAdapterVector.size();
-   if(nofAdapter==0) std::cout<<"WARNING - D3Q27TriFaceMeshInteractor::initInteractor Warning - no nodeAdapter available for "/*<<this->getName()*/<<std::endl;
-   bool needTimeDependence = false;
-   for(int pos=0; pos<nofAdapter; ++pos)
-   {
-      this->bcAdapterVector[pos]->init(this,timeStep);
-      if(this->bcAdapterVector[pos]->isTimeDependent()) needTimeDependence = true;
-   }
-   if(needTimeDependence) this->setTimeDependent();
-   else                   this->unsetTimeDependent();
-
-   //////////////////////////////////////////////////////////////////////////
-   //grid.lock() info
-   //////////////////////////////////////////////////////////////////////////
-   int coarsestInitLevel = grid.lock()->getCoarsestInitializedLevel();
-   int finestInitLevel   = grid.lock()->getFinestInitializedLevel();
-
-   UbTupleInt3 blocknx = grid.lock()->getBlockNX();
-   int blocknx1 = val<1>(blocknx); //gilt fuer alle Level
-   int blocknx2 = val<2>(blocknx); //gilt fuer alle Level
-   int blocknx3 = val<3>(blocknx); //gilt fuer alle Level
-
-   //grobe Blocklaengen
-   CoordinateTransformation3DPtr trafo = grid.lock()->getCoordinateTransformator();
-   double cblockDeltaX1,cblockDeltaX2,cblockDeltaX3, delta ;
-   cblockDeltaX1 = cblockDeltaX2 = cblockDeltaX3 = delta = 1.0/(double)(1<<coarsestInitLevel);
-   if(trafo)
-   {
-      cblockDeltaX1 = trafo->getX1CoordinateScaling()*delta;
-      cblockDeltaX2 = trafo->getX2CoordinateScaling()*delta;
-      cblockDeltaX3 = trafo->getX3CoordinateScaling()*delta;
-   }
-   //levelspezifische blocklaengen und knotenabstaende
-   std::vector< std::vector<double> > nodeDeltaToNeigh(finestInitLevel+1);
-   //vector<double> blockDeltaX1(finestInitLevel+1), blockDeltaX2(finestInitLevel+1), blockDeltaX3(finestInitLevel+1);
-   std::vector<float>  deltaMinX1(finestInitLevel+1),deltaMinX2(finestInitLevel+1),deltaMinX3(finestInitLevel+1);
-   std::vector<float>  deltaMaxX1(finestInitLevel+1),deltaMaxX2(finestInitLevel+1),deltaMaxX3(finestInitLevel+1);
-
-   //Im Boltzmankontext muss dx1==dx2==dx3 sein!!
-   assert( UbMath::equal(cblockDeltaX1/(double)blocknx1, cblockDeltaX2/(double)blocknx2 ) );
-   assert( UbMath::equal(cblockDeltaX1/(double)blocknx1, cblockDeltaX3/(double)blocknx3 ) );
-
-   for(int level = coarsestInitLevel; level<=finestInitLevel; level++)
-   {
-      double nodeDelta = cblockDeltaX1/(double)(blocknx1*(1<<(level-coarsestInitLevel)));
-
-      std::vector<double> distNeigh(D3Q27System::FENDDIR+1, 0.0);
-      D3Q27System::calcDistanceToNeighbors(distNeigh, nodeDelta);
-
-      nodeDeltaToNeigh[level].resize(D3Q27System::ENDDIR+1,0.0);
-      for(int fdir=D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
-      {
-         nodeDeltaToNeigh[level][fdir] = distNeigh[fdir];
-      }
-
-      //im gegensatz zum allg. Cell3DInteractor kann man hier auf max(0.02*blockDeltaX1[level],fabs(...)) verzichten
-      //da dies nur für blockDeltaCalculator->getMinX1Delta(level)==0.0 benötigt wird. ist im D3Q19... aber nie so
-      //Geller: kann man nicht diesen befuckten DeltaCalculator weglassen und hier einfach die Formel zum Delta rechnen reinpacken
-      //SirAnn: klar, mann kann auch weißwuerste am Alex verkaufen... aber zum einen ist das Ding dazu da
-      // und zum anderen sollt eman mal überlegen: "Formel zum Delta rechnen"->man muss rechnen
-      // blockDeltaCalculator->getMinX1Delta(level) -> ein geinlinter wert wird geholt 
-
-      deltaMinX1[level] = (float)( 1.2*nodeDelta); //kein minus da unten -deltaMin
-      deltaMinX2[level] = (float)( 1.2*nodeDelta);
-      deltaMinX3[level] = (float)( 1.2*nodeDelta);
-      deltaMaxX1[level] = (float)( 1.2*nodeDelta);
-      deltaMaxX2[level] = (float)( 1.2*nodeDelta);
-      deltaMaxX3[level] = (float)( 1.2*nodeDelta);
-   }
-
-   //////////////////////////////////////////////////////////////////////////
-   //bounding cubes des TriFaceMesh ermitteln (pro level)
-   //////////////////////////////////////////////////////////////////////////
-   //min/max Werte des Dreiecksnetzes holen
-   double geoMinX1(0.0), geoMinX2(0.0), geoMinX3(0.0), geoMaxX1(0.0), geoMaxX2(0.0), geoMaxX3(0.0);
-   if(this->isSolid() || this->isMoveable())
-   {
-      geoMinX1 = this->geoObject3D->getX1Minimum();  geoMaxX1 = this->geoObject3D->getX1Maximum();
-      geoMinX2 = this->geoObject3D->getX2Minimum();  geoMaxX2 = this->geoObject3D->getX2Maximum();
-      geoMinX3 = this->geoObject3D->getX3Minimum();  geoMaxX3 = this->geoObject3D->getX3Maximum();
-   }
-   else throw UbException(UB_EXARGS,"only TYPE==SOLID is implemented" );
-
-   std::map<Block3DPtr,SolidCheckMethod> blocksForSolidCheck;
-
-   for(int level = coarsestInitLevel; level<=finestInitLevel; level++)
-   {
-      if(this->isSolid() || this->isMoveable())
-      {
-         //bloecke fuer "bounding cube gesamt"
-         std::vector<Block3DPtr> tmpblocks;
-         grid.lock()->getBlocksByCuboid(level,geoMinX1-deltaMinX1[level], geoMinX2-deltaMinX2[level], geoMinX3-deltaMinX3[level],
-            geoMaxX1+deltaMaxX1[level], geoMaxX2+deltaMaxX2[level], geoMaxX3+deltaMaxX3[level],tmpblocks );
-
-         for( size_t i=0; i<tmpblocks.size(); i++ )
-            blocksForSolidCheck[tmpblocks[i]] = PointInObject;
-      }
-   }
-
-   //////////////////////////////////////////////////////////////////////////
-   //FE-specific
-   //////////////////////////////////////////////////////////////////////////
-   //bool calcVelocities = false;
-   //FeTriFaceMesh3D* feMesh = dynamic_cast<FeTriFaceMesh3D*>(mesh);
-   //std::vector<FeTriFaceMesh3D::VertexAttributes>* attributes = NULL;
-   //if(feMesh)
-   //{
-   //   calcVelocities = true;
-   //   attributes     = feMesh->getAttributes();
-   //}
-
-   //////////////////////////////////////////////////////////////////////////
-   //DREIECKE: q-Bestimmung
-   //////////////////////////////////////////////////////////////////////////
-
-   //notwendige variablen initialisieren (u.a. blockDeltas des groben levels)
-   float triPoints[3][3];
-   float vx1=0.0, vx2=0.0, vx3=0.0;
-   unsigned counterTriBoxOverlap=0, counterAABBTriFace=0, counterHalfspace=0, counterBilligOBB=0;
-   std::vector<GbTriFaceMesh3D::TriFace>& triangles = *mesh->getTriangles();
-   std::vector<GbTriFaceMesh3D::Vertex>&  nodes     = *mesh->getNodes();
-   std::map< Block3DPtr, std::set< std::vector<int> > > tmpSolidNodesFromOtherInteractors;
-
-   int onePercent = UbMath::integerRounding(triangles.size()*0.01);
-   if(onePercent==0) onePercent=1;
-   UbTimer setQTimer; setQTimer.start();
-   UBLOG(logDEBUG3, " - setQs for "<<(int)triangles.size()<<" triangles");
-
-   bool solidFromOtherInteractor = false;
-   float blockMinX[3],blockMaxX[3],boxCenter[3],halfBoxSize[3];
-
-   for(size_t t=0; t<triangles.size(); t++)
-   {
-	   //if (t==10577)
-	   //{
-		  // int ehsan=0;
-	   //}
-      //////////////////////////////////////////////////////////////////////////
-      // Halfspace zum Dreieck generieren und min/max des Dreiecks ermitteln
-      //////////////////////////////////////////////////////////////////////////
-      GbTriFaceMesh3D::TriFace& triangle = triangles[t];
-
-      GbTriFaceMesh3D::Vertex& v1 = nodes[triangle.v1];
-      GbTriFaceMesh3D::Vertex& v2 = nodes[triangle.v2];
-      GbTriFaceMesh3D::Vertex& v3 = nodes[triangle.v3];
-
-      GbHalfSpace3D halfSpace(  v1.x,v1.y,v1.z,v2.x,v2.y,v2.z,v3.x,v3.y,v3.z );
-
-      //if(calcVelocities)
-      //{
-      //   FeTriFaceMesh3D::VertexAttributes& vAttribut1 = (*attributes)[triangle.v1];
-      //   FeTriFaceMesh3D::VertexAttributes& vAttribut2 = (*attributes)[triangle.v2];
-      //   FeTriFaceMesh3D::VertexAttributes& vAttribut3 = (*attributes)[triangle.v3];
-      //   vx1 = (float)(UbMath::c1o3*(vAttribut1.getVelocityX()+vAttribut2.getVelocityX()+vAttribut3.getVelocityX()));
-      //   vx2 = (float)(UbMath::c1o3*(vAttribut1.getVelocityY()+vAttribut2.getVelocityY()+vAttribut3.getVelocityY()));
-      //   vx3 = (float)(UbMath::c1o3*(vAttribut1.getVelocityZ()+vAttribut2.getVelocityZ()+vAttribut3.getVelocityZ()));
-      //}
-
-      //////////////////////////////////////////////////////////////////////////
-      //fuer GbMeshTools3D::triBoxOverlap
-      //////////////////////////////////////////////////////////////////////////
-      triPoints[0][0] = v1.x; triPoints[0][1] = v1.y; triPoints[0][2] = v1.z;
-      triPoints[1][0] = v2.x; triPoints[1][1] = v2.y; triPoints[1][2] = v2.z;
-      triPoints[2][0] = v3.x; triPoints[2][1] = v3.y; triPoints[2][2] = v3.z;
-
-      double minX1 = triangle.getMinX(nodes);   double maxX1 = triangle.getMaxX(nodes);
-      double minX2 = triangle.getMinY(nodes);   double maxX2 = triangle.getMaxY(nodes);
-      double minX3 = triangle.getMinZ(nodes);   double maxX3 = triangle.getMaxZ(nodes);
-
-      //////////////////////////////////////////////////////////////////////////
-      // Schleife ueber alle Level
-      //////////////////////////////////////////////////////////////////////////
-      double e1x1,e1x2,e1x3,e2x1,e2x2,e2x3,px1,px2,px3,a,f,sx1,sx2,sx3,u,qx1,qx2,qx3,v;
-      bool gotQs = false;
-      BoundaryConditionsPtr bc;
-
-      for(int level=coarsestInitLevel; level<=finestInitLevel; level++)
-      {
-         //////////////////////////////////////////////////////////////////////////
-         // levelspezifisches BoundCube des Dreicks ermitteln und zugehörige Bloecke beziehen
-         //////////////////////////////////////////////////////////////////////////
-         double boundCubeTriangleMinX1 = minX1-deltaMinX1[level];  double boundCubeTriangleMaxX1 = maxX1+deltaMaxX1[level];
-         double boundCubeTriangleMinX2 = minX2-deltaMinX2[level];  double boundCubeTriangleMaxX2 = maxX2+deltaMaxX2[level];
-         double boundCubeTriangleMinX3 = minX3-deltaMinX3[level];  double boundCubeTriangleMaxX3 = maxX3+deltaMaxX3[level];
-
-         GbCuboid3D boundingCubeTriangle(  boundCubeTriangleMinX1, boundCubeTriangleMinX2, boundCubeTriangleMinX3
-            , boundCubeTriangleMaxX1, boundCubeTriangleMaxX2, boundCubeTriangleMaxX3 );
-
-         std::vector<Block3DPtr> triBlocks;
-         grid.lock()->getBlocksByCuboid(level, boundCubeTriangleMinX1, boundCubeTriangleMinX2, boundCubeTriangleMinX3
-            , boundCubeTriangleMaxX1, boundCubeTriangleMaxX2, boundCubeTriangleMaxX3, triBlocks );
-
-         //////////////////////////////////////////////////////////////////////////
-         // Schleife ueber bloecke des level, die das dreieck beinhalten
-         //////////////////////////////////////////////////////////////////////////
-         for(std::size_t b=0; b<triBlocks.size(); b++)
-         {
-            Block3DPtr block = triBlocks[b];
-
-            ////////////////////////////////////////////////////////////////////////////
-            //// Block Dreieck-/test
-            ////////////////////////////////////////////////////////////////////////////
-            UbTupleDouble3 coords = grid.lock()->getBlockWorldCoordinates(block);
-            UbTupleDouble3 deltas = grid.lock()->getBlockLengths(block);
-
-            blockMinX[0]   = (float)(val<1>(coords)-deltaMinX1[level]);
-            blockMinX[1]   = (float)(val<2>(coords)-deltaMinX2[level]);
-            blockMinX[2]   = (float)(val<3>(coords)-deltaMinX3[level]);
-
-            blockMaxX[0]   = (float)(val<1>(coords)+val<1>(deltas)+deltaMaxX1[level]);
-            blockMaxX[1]   = (float)(val<2>(coords)+val<2>(deltas)+deltaMaxX2[level]);
-            blockMaxX[2]   = (float)(val<3>(coords)+val<3>(deltas)+deltaMaxX3[level]);
-
-            boxCenter[0]   = (float)(0.5*(blockMaxX[0]+blockMinX[0]));
-            boxCenter[1]   = (float)(0.5*(blockMaxX[1]+blockMinX[1]));
-            boxCenter[2]   = (float)(0.5*(blockMaxX[2]+blockMinX[2]));
-
-            halfBoxSize[0] = (float)(0.5*(blockMaxX[0]-blockMinX[0]));
-            halfBoxSize[1] = (float)(0.5*(blockMaxX[1]-blockMinX[1]));
-            halfBoxSize[2] = (float)(0.5*(blockMaxX[2]-blockMinX[2]));
-
-            //wenn dreieck "vergroesserten cube" nicht schneidet/beruehrt -> keine BC moeglich -> continue
-            if( !GbMeshTools3D::triBoxOverlap(boxCenter,halfBoxSize,triPoints) )
-            {
-               counterTriBoxOverlap++;
-               continue;
-            }
-
-            //////////////////////////////////////////////////////////////////////////
-            //Untersuchung der einzelnen nodes
-            //////////////////////////////////////////////////////////////////////////
-            bool blockGotBCs = false;
-
-            LBMKernelPtr kernel = block->getKernel();
-            BCArray3DPtr bcMatrix = kernel->getBCProcessor()->getBCArray();
-
-            int indexMinX1 = 0;
-            int indexMinX2 = 0;
-            int indexMinX3 = 0;
-
-            int indexMaxX1 = (int)bcMatrix->getNX1();
-            int indexMaxX2 = (int)bcMatrix->getNX2();
-            int indexMaxX3 = (int)bcMatrix->getNX3();
-
-            std::set< std::vector<int> >& bcNodeIndices           = this->bcNodeIndicesMap[block];
-            std::set< std::vector<int> >& solidsFromOtherInteractors = tmpSolidNodesFromOtherInteractors[block];
-            double q, internX1, internX2, internX3,distance;
-
-            double& nodeDx1 = nodeDeltaToNeigh[level][D3Q27System::E];
-            double& nodeDx2 = nodeDeltaToNeigh[level][D3Q27System::N];
-            double& nodeDx3 = nodeDeltaToNeigh[level][D3Q27System::T];
-
-            //fuer OBB-Test
-            double qEinflussDelta = 1.1 * sqrt( nodeDx1*nodeDx1 + nodeDx2*nodeDx2 + nodeDx3*nodeDx3);
-
-            for(int ix3=indexMinX3; ix3<indexMaxX3; ix3++)
-            {
-               internX3 = val<3>(coords)+nodeDx3*ix3-0.5*nodeDx3;
-               for(int ix2=indexMinX2; ix2<indexMaxX2; ix2++)
-               {
-                  internX2 = val<2>(coords)+nodeDx2*ix2-0.5*nodeDx2;
-                  for(int ix1=indexMinX1; ix1<indexMaxX1; ix1++)
-                  {
-					 
-					  int blx1 =block->getX1();
-					  int blx2 = block->getX2();
-					  int blx3 = block->getX3();
-
-					  if (blx1==0&&blx2==1&&blx3==0)
-					  {
-						  //if (ix2==39&&ix3==4)
-							   if (ix2==39&&ix3==4)
-						  {
-							 int seb=0;
-						  }
-
-					  }
-                     //Problem: wenn voher der punkt durch eine andere geo not active gesetzt wird und
-                     //dieser nun uebersprungen wird, dann hat man spaeter beim fuellalgorithmus luecken
-                     //in der front und der block wird u.U. faelschlicher weise komplett solid markiert
-                     //Lsg: positionen merken und erst Nach dem fuellarlgo wieder auf not active setzen :-)
-                     solidFromOtherInteractor = false;
-                     if(bcMatrix->isSolid(ix1,ix2,ix3))
-                     {
-                        if(this->reinitWithStoredQsFlag)
-                        {
-                           solidFromOtherInteractor = true;   //hier muss man weitermachen
-                           //SG //oje 
-                           std::vector<int> p(3);
-                           p[0]=ix1; p[1]=ix2; p[2]=ix3;
-                           solidsFromOtherInteractors.insert( p );
-                        }
-                        else
-                        {
-                           //SG //oje 
-                           std::vector<int> p(3);
-                           p[0]=ix1; p[1]=ix2; p[2]=ix3;
-                           solidsFromOtherInteractors.insert(p);
-                           //SG continue;   
-                           solidFromOtherInteractor = true;   
-                        }
-                     }
-
-                     internX1 = val<1>(coords)+nodeDx1*ix1-0.5*nodeDx1;
-
-                     //////////////////////////////////////////////////////////////////////////
-                     //Punkt in AABB von Dreieck?                     
-                     //////////////////////////////////////////////////////////////////////////
-					//ehsan changedâ—˜
-					 bool pointIsOnBoundary = false;
-					 if( !boundingCubeTriangle.isPointInGbObject3D(internX1, internX2, internX3,pointIsOnBoundary) ) 
-                    // if( !boundingCubeTriangle.isPointInGbObject3D(internX1, internX2, internX3) ) 
-                     {
-                        counterAABBTriFace++;
-                        continue;
-                     }
-
-                     //////////////////////////////////////////////////////////////////////////
-                     // Halbebenentests
-                     //////////////////////////////////////////////////////////////////////////
-                     distance = halfSpace.getDistance( internX1, internX2, internX3 );
-
-                     //Punkt in Halbebene? (nein, wenn distance<0)
-                     if(useHalfSpace && UbMath::less(distance, 0.0) )//== !halfSpace.ptInside(internX1,internX2,internX3) )
-                     {
-                        counterHalfspace++;
-                        continue;
-                     }
-
-                     //BilligOBB-Test: wenn distance > qEinflussDelta -> kein q
-                     if( UbMath::greater( fabs(distance), qEinflussDelta ) )
-                     {
-                        counterBilligOBB++;
-                        continue;
-                     }
-
-                     /////////////////////////////////////////////////////////////////////////////
-                     //Raytracingfür diskrete Boltzmannrichtungen
-                     /////////////////////////////////////////////////////////////////////////////
-                     gotQs = false;
-                     bc    = BoundaryConditionsPtr();
-
-                     //RAYTRACING - diskrete LB-dir zu Dreick
-                     //e1 = v1 - v0
-                     e1x1 = v2.x-v1.x;
-                     e1x2 = v2.y-v1.y;
-                     e1x3 = v2.z-v1.z;
-
-                     //e2 = v2 - v0
-                     e2x1 = v3.x-v1.x;
-                     e2x2 = v3.y-v1.y;
-                     e2x3 = v3.z-v1.z;
-
-                     //s = o - v0
-                     sx1 = internX1 - v1.x;
-                     sx2 = internX2 - v1.y;
-                     sx3 = internX3 - v1.z;
-
-                     for(int fdir=D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
-                     {
-                        //p = d x e2
-                        px1 = this->rayX2[fdir]*e2x3 - this->rayX3[fdir]*e2x2;
-                        px2 = this->rayX3[fdir]*e2x1 - this->rayX1[fdir]*e2x3;
-                        px3 = this->rayX1[fdir]*e2x2 - this->rayX2[fdir]*e2x1;
-
-                        //a = e1 dot p
-                        a = e1x1*px1 + e1x2*px2 + e1x3*px3;
-                        if(fabs(a)<1.E-10) continue;
-                        f = 1.0/a;
-
-                        //u = f * ( s dot p)
-                        u = f * ( sx1*px1 + sx2*px2 + sx3*px3 );
-                        if(u<-1.E-10 || u>1.0+1.E-10) continue;
-
-                        //q = s x e1
-                        qx1 = sx2*e1x3 - sx3*e1x2;
-                        qx2 = sx3*e1x1 - sx1*e1x3;
-                        qx3 = sx1*e1x2 - sx2*e1x1;
-
-                        //v = f*(e2 dot q)
-                        v = f * (this->rayX1[fdir]*qx1 + this->rayX2[fdir]*qx2 + this->rayX3[fdir]*qx3);
-                        if(v<-1.E-10 || (u+v)>1.0+1.E-10) continue;
-
-                        //t = f * (e2 dot q)
-                        q = f * (e2x1*qx1 + e2x2*qx2 + e2x3*qx3);
-                        q /= nodeDeltaToNeigh[level][fdir];
-
-                        //gefundenes q auf gueltigkeit pruefen
-                        if( UbMath::zero(q) )
-                        {
-                           //neu (18.05.2010)
-                           //es kann vorkommen, dass bei dünnwandigen geos punkte, die auf einem dreieck liegen, qs bekommen, die durch die geo
-                           //durchgehen. diese punkte werden später jedoch nicht mehr auf solid getestet, da sie ja ne BC bekommen haben
-                           //--> da mind ein q==0.0 für eines der dreiecke -> dort solid setzen
-                           this->solidNodeIndicesMap[block].insert( UbTupleInt3(ix1,ix2,ix3) );
-                           bcMatrix->setSolid( ix1, ix2, ix3 );
-                           continue;
-                        }
-
-                        if( UbMath::inClosedInterval(q, 1.0, 1.0) ) q = 1.0;
-                        if( UbMath::greater(q, 0.0) && UbMath::lessEqual(q, 1.0) )
-                        {
-                           //if( !solidFromOtherInteractor ) //--> Knoten schon solid-->BC setzen ueberfluessig 
-                           //SG changed to
-                           //if( solidFromOtherInteractor ) //--> Knoten schon solid-->BC setzen ueberfluessig 
-                           {
-                              //SG 26.08.2010 muss bereits hierhin, da das continue sonst den Knoten nicht als transNode fürs
-                              //markiert
-                              gotQs=blockGotBCs=true;
-
-                              bc = bcMatrix->getBC(ix1,ix2,ix3);
-
-                              //SG 26.08.2010 if(!bc && !bcMatrix->isSolid())
-                              if(!bc)
-                              {
-                                 bc = BoundaryConditionsPtr(new BoundaryConditions);;
-                                 bcMatrix->setBC(ix1,ix2,ix3,bc);
-                              }
-                              else if( UbMath::less( bc->getQ(fdir), q ) )  //schon ein kuerzeres q voehanden?
-                              {
-                                 //neu:: 18.05.2010
-                                 //um falsche qs die evtl durch die "wand" gehen zu vermeiden 
-                                 //q nur dann neu setzen, wenn neues q kleiner als vorhandenes!
-                                 //Zudem: insbesondere an ecken mit zwei BC geos ist nur das 
-                                 //naehere gueltig
-                                 continue;
-                              }
-
-                              bc->setBoundaryVelocityX1(vx1);
-                              bc->setBoundaryVelocityX2(vx2);
-                              bc->setBoundaryVelocityX3(vx3);
-
-                              for(int index=(int)this->bcAdapterVector.size()-1; index>=0; --index)
-                                 this->bcAdapterVector[index]->adaptBCForDirection(*this,bc,internX1,internX2,internX3,q,fdir);
-
-                              //SG 26.08.2010 gotQs=blockGotBCs=true;
-                           }
-                           //fuer beschleunigtes wiedereinlesen
-                           if(this->reinitWithStoredQsFlag)
-                           {
-                              bcNodeIndicesAndQsMap[block][ UbTupleInt3(ix1, ix2, ix3) ].resize(D3Q27System::FENDDIR+1+3, -1.0f);
-                              bcNodeIndicesAndQsMap[block][ UbTupleInt3(ix1, ix2, ix3) ][fdir                    ] = float(q);
-                              bcNodeIndicesAndQsMap[block][ UbTupleInt3(ix1, ix2, ix3) ][D3Q27System::FENDDIR+1+0] = float(internX1);
-                              bcNodeIndicesAndQsMap[block][ UbTupleInt3(ix1, ix2, ix3) ][D3Q27System::FENDDIR+1+1] = float(internX2);
-                              bcNodeIndicesAndQsMap[block][ UbTupleInt3(ix1, ix2, ix3) ][D3Q27System::FENDDIR+1+2] = float(internX3);
-                           }
-                        }
-                     }
-
-                     if(gotQs)
-                     {
-                        std::vector<int> p(3);
-                        p[0]=ix1; p[1]=ix2; p[2]=ix3;
-                        bcNodeIndices.insert(p);
-
-                        for(int index=(int)this->bcAdapterVector.size()-1; index>=0; --index)
-                           this->bcAdapterVector[index]->adaptBC(*this,bc,internX1,internX2,internX3);
-                     }
-                  }
-               }
-            }
-            //Block wird für scanline-check "anmelden", dieser wird dann spaeter zu "transBlocks" hinzugefuegt
-            if(blockGotBCs)
-            {
-               blocksForSolidCheck[block] = ScanLine;
-            }
-            //            bvd->getTimer().stop();
-         }
-         //dynamische Punkte des GbCuboids muessen leider per "Hand" geloescht werden :-(
-         boundingCubeTriangle.finalize();
-      }
-   }
-   setQTimer.stop();
-
-   UBLOG(logDEBUG1," - setQs for "/*<< this->getName()*/ << " - " <<(int)triangles.size()<<" triangles: 100% done in "<<setQTimer.getTotalTime()<<"sec");
-   UBLOG(logDEBUG1,"       * rejected blocks with tribox overlap test : " << counterTriBoxOverlap);
-   UBLOG(logDEBUG1,"       * rejected nodes  with AABB           test : " << counterAABBTriFace);
-   UBLOG(logDEBUG1,"       * rejected nodes  with halfspace      test : " << counterHalfspace);
-   UBLOG(logDEBUG1,"       * rejected nodes  with OBB            test : " << counterBilligOBB);
-
-   typedef std::map<Block3DPtr,SolidCheckMethod>::iterator BlockSolidCheckMethodIterator;
-
-   //////////////////////////////////////////////////////////////////////////
-   // SOLID checks
-   //////////////////////////////////////////////////////////////////////////
-   if( regardPIOTest )
-   {
-      int pointInObjectCounter = 0;
-      int scanlineCounter      = 0;
-      int counter              = 0;
-
-      //sollte die matrix groesse zu gross sein und der rekursive floodFill mehr speicher
-      //benoetigen als der Stack hergibt -> keinen floodFill verwenden!
-      void (D3Q27TriFaceMeshInteractor::*gridFill)(CbArray3D<FLAGS>&, const short&, const short&, const short&, const FLAGS&) = NULL;
-      /*if(blocknx1*blocknx2*blocknx3 < 200000 ) gridFill = &D3Q27TriFaceMeshInteractor::recursiveGridFill;*/
-      /*else */                                    gridFill = &D3Q27TriFaceMeshInteractor::iterativeGridFill; 
-
-      UBLOG(logDEBUG1," - setSolids for "<< blocksForSolidCheck.size() << " blocks");
-
-      UbTimer scanLineTimer;
-      UbTimer solidTimer; 
-      solidTimer.start();
-
-      for(BlockSolidCheckMethodIterator pos=blocksForSolidCheck.begin(); pos!=blocksForSolidCheck.end(); ++pos)
-      {
-         Block3DPtr const& block = pos->first;
-         int level = block->getLevel();
-
-         UbTupleDouble3 coords = grid.lock()->getBlockWorldCoordinates(block);
-
-         //Bloecke, die keinerlei Verschneidung mit Dreicken bzw. deren BoundCubes hatten
-         //hier: durch inside/outside Tests EINES knotens gilt fuer ALLE Knoten des blockes
-         if( pos->second == PointInObject ) 
-         {
-            pointInObjectCounter++;
-            if(mesh->isPointInGbObject3D(val<1>(coords),val<2>(coords),val<3>(coords)) )
-            {
-               //block->setActive(false);
-               //this->solidBlocks.push_back(block);
-            }
-         }
-         //Bloecke, die Verschneidung mit Dreicken bzw. deren BoundCubes hatten
-         //scanline algortihmus. dieser berücksichtigt durch weitere tests, dass innerhalb evtl schon andere
-         //geos bcs gesetzt haben. es werden ausschließelich solids gesetzt (also keine FLUIDS oder neuen BCs)
-         else if( pos->second == ScanLine ) 
-         {
-            scanlineCounter++;
-            scanLineTimer.start();
-
-            LBMKernelPtr kernel = block->getKernel();
-            if(!kernel) throw UbException(UB_EXARGS,"na sowas kein kernel bzw. kernel=NULL (2)");
-            BCArray3DPtr bcMatrix = kernel->getBCProcessor()->getBCArray();
-
-            //            bvd->getTimer().start();
-            int indexMinX1 = 0;
-            int indexMinX2 = 0;
-            int indexMinX3 = 0;
-            int indexMaxX1 = (int)bcMatrix->getNX1();
-            int indexMaxX2 = (int)bcMatrix->getNX2();
-            int indexMaxX3 = (int)bcMatrix->getNX3();
-
-            //quick and dirty
-            blocknx1 = indexMaxX1;
-            blocknx2 = indexMaxX2;
-            blocknx3 = indexMaxX3;
-
-            std::set< UbTupleInt3 >& solidNodeIndices = this->solidNodeIndicesMap[block];
-
-            float nodeDeltaX1 = (float)nodeDeltaToNeigh[level][D3Q27System::E];
-            float nodeDeltaX2 = (float)nodeDeltaToNeigh[level][D3Q27System::N];
-            float nodeDeltaX3 = (float)nodeDeltaToNeigh[level][D3Q27System::T];
-
-            //flagfield matrix initialisieren
-            CbArray3D<FLAGS> flagField(blocknx1,blocknx2,blocknx3,UNDEF_FLAG);
-
-            //hier gesetzte bcs markieren
-            std::set< std::vector<int> >& transNodeIndices = this->bcNodeIndicesMap[block];
-            std::set< std::vector<int> >::iterator setPos;
-            for(setPos=transNodeIndices.begin(); setPos!=transNodeIndices.end();  ++setPos)
-               flagField( (*setPos)[0], (*setPos)[1], (*setPos)[2] ) = BC_FLAG;
-
-            //solids die bereits durch andere interaktoren gesetzt wurden (wurden oben gespeichert)
-            //ist EMPTY bei reinitWithStoredQsFlag == true
-            //SG 28.08.2010            std::set< UbTupleInt3 >& tmpSolidNodeIndices = tmpSolidNodesFromOtherInteractors[block];
-            //SG 28.08.2010  if(reinitWithStoredQsFlag && !tmpSolidNodeIndices.empty() ) throw UbException(UB_EXARGS, "tmpSolidNodeIndices darf bei reinitWithStoredQsFlag==true keine Knoten enthalten");
-            //SG 28.08.2010            for(setPos=tmpSolidNodeIndices.begin(); setPos!=tmpSolidNodeIndices.end();  ++setPos)
-            //SG 28.08.2010               flagField( val<1>(*setPos), val<2>(*setPos), val<3>(*setPos) ) = OLDSOLID_FLAG;
-
-            //flagfield matrix belegen
-            for(int bx3=0; bx3<blocknx3; ++bx3)
-            {
-               for(int bx2=0; bx2<blocknx2; ++bx2)
-               {
-                  for(int bx1=0; bx1<blocknx1; ++bx1)
-                  {
-                     
-					  if (bx2==9&&bx3==29)
-					  {
-						  int ride=0;
-					  }
-					  if( flagField(bx1,bx2,bx3)==UNDEF_FLAG )
-                     { 
-						 if( mesh->isPointInGbObject3D(  val<1>(coords) + bx1*nodeDeltaX1 - 0.5*nodeDeltaX1 
-                           , val<2>(coords) + bx2*nodeDeltaX2 - 0.5*nodeDeltaX2
-                           , val<3>(coords) + bx3*nodeDeltaX3 - 0.5*nodeDeltaX3) )
-                        {
-                           (this->*gridFill)(flagField,bx1,bx2,bx3,SOLID_FLAG);
-                        }
-                        else
-                        {
-                           (this->*gridFill)(flagField,bx1,bx2,bx3,FLUID_FLAG);
-                        }
-                     }
-
-                     if( flagField(bx1,bx2,bx3)==SOLID_FLAG )
-                     {
-                        //hier ist noch das Problem, das "alle" solid in die solidNodeIndices kommen
-                        //evtl. Abhilfe durch einführen eines anderen Flags bei tmpSolidNodeIndices ..
-                        solidNodeIndices.insert(UbTupleInt3(bx1,bx2,bx3));
-                        bcMatrix->setSolid(bx1,bx2,bx3);
-                     }
-                     //SG 28.08.2010  else if( flagField(bx1,bx2,bx3)==OLDSOLID_FLAG )
-                     //SG 28.08.2010  {
-                     //SG 28.08.2010     bcMatrix->setSolid(bx1,bx2,bx3);
-                     //SG 28.08.2010  }
-                  }
-               }
-            }
-
-            //SG 28.08.2010 halt danach setzen, damit die BCs die fälschlicherweise gesetzt wurden korrigiert werden
-            std::set< std::vector<int> >& tmpSolidNodeIndices = tmpSolidNodesFromOtherInteractors[block];
-            for(setPos=tmpSolidNodeIndices.begin(); setPos!=tmpSolidNodeIndices.end();  ++setPos)
-               bcMatrix->setSolid((*setPos)[0], (*setPos)[1], (*setPos)[2] );
-
-            //block hat  in initInteractor mind eine BC erhalten -> transBlock
-            this->bcBlocks.push_back(block);
-            scanLineTimer.stop();
-
-            //            bvd->getTimer().stop();
-         }
-         else throw UbException(UB_EXARGS,"unknown option for in object test");
-      }
-
-      solidTimer.stop();
-
-      UBLOG(logDEBUG1, " - setSolids for "<<blocksForSolidCheck.size()<<" blocks: 100% done in "<<solidTimer.getTotalTime()<<"s");
-      UBLOG(logDEBUG1, "       * pointInObject for "<<pointInObjectCounter<<" blocks in "<<solidTimer.getTotalTime()-scanLineTimer.getTotalTime()<<"s");
-      UBLOG(logDEBUG1, "       * flood fill    for "<<scanlineCounter     <<" blocks in "<<scanLineTimer.getTotalTime()<<" secs");
-      UBLOG(logDEBUG1, "LBMTriFaceMeshInteractor::initInteractor for \""<<mesh->getName()<<"\" done in "<<setQTimer.getTotalTime()+solidTimer.getTotalTime()<<"s");
-   }
-
-   //calcForces arbeitet nicht korrekt, wenn Geo mit Bloecken 
-   //unterschiedlicher Leveltiefe diskretisiert -> exception
-   //abfrage steht hier, weil es theoretisch sein kann, dass bei parallelen rechnungen
-   //genau der block mit dem anderen level auf einem anderen prozess liegt...
-   //Update: es kann u.U. passieren, dass Blöcke in der Liste nicht aktiv sin
-   //(falls diese z.B. duch andere Interactoren solid gesetzt wurden)
-   //diese werden nicht berücksichtigt (auch nicht beid er kraftauswertung später)
-   //if( this->isRelevantForForces() )
-   //{
-   //   int level = -1;     
-   //   for( std::vector<Block3DPtr>::const_iterator pos = this->transBlocks.begin(); pos!=this->transBlocks.end(); ++pos)
-   //      if( (*pos)->isActive() )
-   //      {
-   //         level = (*pos)->getLevel();
-   //         break;
-   //      }
-
-   //      bool check = false;
-   //      for( std::vector<Block3DPtr>::const_iterator pos = this->transBlocks.begin(); pos!=this->transBlocks.end(); ++pos)
-   //         if( (*pos)->isActive() && (*pos)->getLevel()!=level)
-   //         {
-   //            (*pos)->setRank(1000);
-   //            check = true;
-   //            UbTupleDouble3 coords = grid.lock()->getBlockWorldCoordinates((*pos));
-   //            std::cout<<(*pos)->getLevel()<<","<<(*pos)->getX1()<<","<<(*pos)->getX2()<<","<<(*pos)->getX3()<<std::endl;
-   //            std::cout<<std::setprecision(15)<<val<1>(coords)<<","<<val<2>(coords)<<","<<val<3>(coords)<<std::endl<<std::endl;
-
-   //         }
-   //         if(check)
-   //         {
-   //            //this->grid.lock()->writeBlocks(UbStaticPathMap::getPath(UbStaticPathMap::GLOBAL)+"/error_grid",0, WbWriterVtkXmlASCII::getInstance(), false);
-
-   //            throw UbException(UB_EXARGS,"interactor is relevant for forces,"
-   //               +(std::string)" but has transblocks with different levels (wrote error_grid)"
-   //               +(std::string)" -> not supportet by LBMInteractor::getForces()"
-   //               +(std::string)" -> increase refineWidth");
-
-   //         }
-   //}
-}
-//////////////////////////////////////////////////////////////////////////
-void D3Q27TriFaceMeshInteractor::refineBlockGridToLevel(int level, double startDistance, double stopDistance)
-{
-   UBLOG(logDEBUG1, "D3Q27TriFaceMeshInteractor::refineBlockGridToLevel - start");
-
-   //ToDo: evtl checken, ob man noch einen HalbraumCheck für StopDistance einbaut
-   //      oder ob man schneller ist, wenn man gar keinen halbraum test macht...
-   if(!grid.lock())
-      throw UbException(UB_EXARGS,"Grid isn't exist!");
-   if( UbMath::greater(startDistance,0.0) )
-      throw UbException(UB_EXARGS,"startDistance>0.0 not supported by this interactor");
-   if( UbMath::less(stopDistance,0.0) )
-      throw UbException(UB_EXARGS,"stopDistance<0.0  not supported by this interactor");
-
-   Grid3DPtr  bgrid = this->grid.lock();
-   GbTriFaceMesh3D& mesh  = dynamic_cast<GbTriFaceMesh3D&>(*this->geoObject3D.get());
-
-   int coarsestLevel = bgrid->getCoarsestInitializedLevel();
-
-   std::vector<GbTriFaceMesh3D::TriFace>& triangles = *mesh.getTriangles();
-   std::vector<GbTriFaceMesh3D::Vertex>&  nodes     = *mesh.getNodes();
-
-   double minX1,minX2,minX3,maxX1,maxX2,maxX3;
-   float blockMinX[3],blockMaxX[3],boxCenter[3],halfBoxSize[3];
-   float triPoints[3][3];
-
-   size_t nofTriangles = (int)triangles.size();
-
-//#pragma omp parallel
-//#pragma omp for
-   for(size_t i=0; i<nofTriangles; i++)
-   //for(int i=0; i<nofTriangles; i++)
-   {
-//#pragma omp master  
-      //{
-      //    printf_s("num_threads=%d\n", omp_get_num_threads( ));
-      //}
-     
-
-      GbTriFaceMesh3D::TriFace& triangle = triangles[i];
-
-      GbTriFaceMesh3D::Vertex& v1 = nodes[triangle.v1];
-      GbTriFaceMesh3D::Vertex& v2 = nodes[triangle.v2];
-      GbTriFaceMesh3D::Vertex& v3 = nodes[triangle.v3];
-
-      //dreick muss normal besitzen!
-      assert( !UbMath::zero(triangle.nx) || !UbMath::zero(triangle.ny) || !UbMath::zero(triangle.nz) );
-      //Normale muss normiert sein!
-      assert( (fabs(std::sqrt( triangle.nx*triangle.nx + triangle.ny*triangle.ny + triangle.nz*triangle.nz ))-1.0f)<1.0E-6);
-
-      //Halfspace um  startDistance entgegen normale verscheiebn, ansonsten werden spaeter
-      //zu testende bloecke auf der dreicksrueckseite nicht getestet!!!
-      GbHalfSpace3D halfSpace(  v1.x+startDistance*triangle.nx, v1.y+startDistance*triangle.ny, v1.z+startDistance*triangle.nz
-         , v2.x+startDistance*triangle.nx, v2.y+startDistance*triangle.ny, v2.z+startDistance*triangle.nz
-         , v3.x+startDistance*triangle.nx, v3.y+startDistance*triangle.ny, v3.z+startDistance*triangle.nz );
-
-      //Boundingbox um massgebliches dx erweitern -> zur Bestimmung der zu testenden Bloecke
-      if( triangle.nx>1.0E-8 ) { minX1 = triangle.getMinX(nodes)+1.05*triangle.nx*startDistance; 
-      maxX1 = triangle.getMaxX(nodes)+1.05*triangle.nx*stopDistance;  }     
-      else                     { minX1 = triangle.getMinX(nodes)+1.05*triangle.nx*stopDistance;  
-      maxX1 = triangle.getMaxX(nodes)+1.05*triangle.nx*startDistance; }     
-
-      if( triangle.ny>1.0E-8 ) { minX2 = triangle.getMinY(nodes)+1.05*triangle.ny*startDistance;
-      maxX2 = triangle.getMaxY(nodes)+1.05*triangle.ny*stopDistance;  }     
-      else                     { minX2 = triangle.getMinY(nodes)+1.05*triangle.ny*stopDistance; 
-      maxX2 = triangle.getMaxY(nodes)+1.05*triangle.ny*startDistance; }     
-
-      if( triangle.nz>1.0E-8 ) { minX3 = triangle.getMinZ(nodes)+1.05*triangle.nz*startDistance;
-      maxX3 = triangle.getMaxZ(nodes)+1.05*triangle.nz*stopDistance;  }     
-      else                     { minX3 = triangle.getMinZ(nodes)+1.05*triangle.nz*stopDistance; 
-      maxX3 = triangle.getMaxZ(nodes)+1.05*triangle.nz*startDistance; }     
-
-
-      int flag = 0;
-      //Levelweise alle Bloecke holen, die erweiterte BB schneiden 
-      //und bearbeiten
-      for(int l=coarsestLevel; l<level; l++)
-      {
-         std::vector<Block3DPtr> consideredBlocks;
-         bgrid->getBlocksByCuboid(l,minX1, minX2, minX3, maxX1, maxX2, maxX3, consideredBlocks);
-         double x1a,x2a,x3a,x1b,x2b,x3b;
-
-         for(size_t b=0; b<consideredBlocks.size(); b++)
-         {
-            Block3DPtr block = consideredBlocks[b];
-            if(block->getLevel()>=level) continue;
-
-            //start coordinaten des blocks ermitteln
-            UbTupleDouble3 coords = bgrid->getBlockWorldCoordinates(block);
-            UbTupleDouble3 deltas = bgrid->getBlockLengths(block);
-
-            //Check, ob block komplett im Halbraum
-            x1a = val<1>(coords);   x1b = val<1>(coords)+val<1>(deltas);
-            x2a = val<2>(coords);   x2b = val<2>(coords)+val<2>(deltas);
-            x3a = val<3>(coords);   x3b = val<3>(coords)+val<3>(deltas);
-
-            flag = 0;
-            if( !halfSpace.ptInside(x1a,x2a,x3a) )  flag |= (1<<0); //1
-            if( !halfSpace.ptInside(x1b,x2a,x3a) )  flag |= (1<<1); //2
-            if( !halfSpace.ptInside(x1b,x2b,x3a) )  flag |= (1<<2); //4
-            if( !halfSpace.ptInside(x1a,x2b,x3a) )  flag |= (1<<3); //8
-            if( !halfSpace.ptInside(x1a,x2a,x3b) )  flag |= (1<<4); //16
-            if( !halfSpace.ptInside(x1b,x2a,x3b) )  flag |= (1<<5); //32
-            if( !halfSpace.ptInside(x1b,x2b,x3b) )  flag |= (1<<6); //64
-            if( !halfSpace.ptInside(x1a,x2b,x3b) )  flag |= (1<<7); //128
-
-
-            if( true && flag!=255 )
-            {
-               //blockseite ermitteln (skalarprodukt dreiecks-normale, vector (midTri->midCub) )
-               //je nachdem muss für den massgeblichen block start oder stopdistance verwendet werden
-               //liegt block auf pos seite -> stopdistance ansonsten startdistance
-               double skalarprod =   triangle.nx * ( 0.5*(x1a+x1b)-triangle.getX1Centroid(nodes) )
-                  + triangle.ny * ( 0.5*(x2a+x2b)-triangle.getX2Centroid(nodes) )
-                  + triangle.nz * ( 0.5*(x3a+x3b)-triangle.getX3Centroid(nodes) );
-
-               double blockdelta  = 1.05*stopDistance;
-               if     (skalarprod<1.E-8       ) blockdelta = -1.05*startDistance;  //startDistance<0!!
-               else if( fabs(skalarprod)<1.E-8) blockdelta =  1.05*UbMath::max(-startDistance,stopDistance);
-
-               //block anpassen
-               blockMinX[0]   = (float)(val<1>(coords)-blockdelta );
-               blockMinX[1]   = (float)(val<2>(coords)-blockdelta );
-               blockMinX[2]   = (float)(val<3>(coords)-blockdelta );
-
-               blockMaxX[0]   = (float)(val<1>(coords)+val<1>(deltas)+blockdelta );
-               blockMaxX[1]   = (float)(val<2>(coords)+val<2>(deltas)+blockdelta );
-               blockMaxX[2]   = (float)(val<3>(coords)+val<3>(deltas)+blockdelta );
-
-               boxCenter[0]   = (float)(0.5*(blockMaxX[0]+blockMinX[0]));
-               boxCenter[1]   = (float)(0.5*(blockMaxX[1]+blockMinX[1]));
-               boxCenter[2]   = (float)(0.5*(blockMaxX[2]+blockMinX[2]));
-
-               halfBoxSize[0] = (float)(0.5*(blockMaxX[0]-blockMinX[0]));
-               halfBoxSize[1] = (float)(0.5*(blockMaxX[1]-blockMinX[1]));
-               halfBoxSize[2] = (float)(0.5*(blockMaxX[2]-blockMinX[2]));
-
-               GbTriFaceMesh3D::Vertex& v1 = nodes[triangle.v1];
-               GbTriFaceMesh3D::Vertex& v2 = nodes[triangle.v2];
-               GbTriFaceMesh3D::Vertex& v3 = nodes[triangle.v3];
-
-               triPoints[0][0] = v1.x; triPoints[0][1] = v1.y; triPoints[0][2] = v1.z; 
-               triPoints[1][0] = v2.x; triPoints[1][1] = v2.y; triPoints[1][2] = v2.z; 
-               triPoints[2][0] = v3.x; triPoints[2][1] = v3.y; triPoints[2][2] = v3.z; 
-
-               //wenn block dreick schneidet, dann muss er verfeinert werden
-               if( GbMeshTools3D::triBoxOverlap(boxCenter,halfBoxSize,triPoints) )
-               {
-                  bgrid->expandBlock(block->getX1(), block->getX2(),block->getX3(),block->getLevel());
-               }
-            }
-         }
-      }
-   }
-   UBLOG(logDEBUG1, " - refine done");
-}
-//////////////////////////////////////////////////////////////////////////
-void D3Q27TriFaceMeshInteractor::updateMovedGeometry(const double& timeStep)
-{
-
-}
-////////////////////////////////////////////////////////////////////////////
-void D3Q27TriFaceMeshInteractor::recursiveGridFill(CbArray3D<FLAGS>& flagfield, const short& xs, const short& ys, const short& zs, const FLAGS& type)
-{
-   // Algorithmus zum Füllen eines Polyeders, ausgehend vom Saatpunkt xs,ys,zs
-
-   //Saatknoten einfärben
-   if( flagfield(xs,ys,zs)==UNDEF_FLAG )
-   {
-      flagfield(xs,ys,zs) = type;
-
-      if ( flagfield.indicesInRange( xs+1, ys  , zs   ) ) this->recursiveGridFill(flagfield,xs+1, ys  , zs  ,type);
-      if ( flagfield.indicesInRange( xs  , ys+1, zs   ) ) this->recursiveGridFill(flagfield,xs  , ys+1, zs  ,type);
-      if ( flagfield.indicesInRange( xs  , ys  , zs+1 ) ) this->recursiveGridFill(flagfield,xs  , ys  , zs+1,type);
-      if ( flagfield.indicesInRange( xs-1, ys  , zs   ) ) this->recursiveGridFill(flagfield,xs-1, ys  , zs  ,type);
-      if ( flagfield.indicesInRange( xs  , ys-1, zs   ) ) this->recursiveGridFill(flagfield,xs  , ys-1, zs  ,type);
-      if ( flagfield.indicesInRange( xs  , ys  , zs-1 ) ) this->recursiveGridFill(flagfield,xs  , ys  , zs-1,type);
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void D3Q27TriFaceMeshInteractor::iterativeGridFill(CbArray3D<FLAGS>& flagfield, const short& xs, const short& ys, const short& zs, const FLAGS& type)
-{
-   std::stack< UbTupleInt3 > stck;
-   stck.push( UbTupleInt3(xs,ys,zs) );
-
-   int x,y,z;
-
-   while( !stck.empty() )  
-   {
-      x = val<1>( stck.top() );
-      y = val<2>( stck.top() );
-      z = val<3>( stck.top() );
-      stck.pop();
-
-      FLAGS& flagType = flagfield( x, y, z );
-
-      if( flagType == UNDEF_FLAG ) 
-      {     
-         flagType = type;
-
-         if ( flagfield.indicesInRange( x+1, y  , z   ) ) stck.push( UbTupleInt3( x+1, y  , z   ) );
-         if ( flagfield.indicesInRange( x  , y+1, z   ) ) stck.push( UbTupleInt3( x  , y+1, z   ) );
-         if ( flagfield.indicesInRange( x  , y  , z+1 ) ) stck.push( UbTupleInt3( x  , y  , z+1 ) );
-         if ( flagfield.indicesInRange( x-1, y  , z   ) ) stck.push( UbTupleInt3( x-1, y  , z   ) );
-         if ( flagfield.indicesInRange( x  , y-1, z   ) ) stck.push( UbTupleInt3( x  , y-1, z   ) );
-         if ( flagfield.indicesInRange( x  , y  , z-1 ) ) stck.push( UbTupleInt3( x  , y  , z-1 ) );
-      }
-   }
-   return;
-}
-//////////////////////////////////////////////////////////////////////////
-UbTupleDouble3 D3Q27TriFaceMeshInteractor::getForces()
-{
-   //FeTriFaceMesh3D* feMesh = dynamic_cast<FeTriFaceMesh3D*>(this->geoObject3D.get());
-   //if(!feMesh)
-   //{
-   //   return D3Q19AMRInteractor::getForces();
-   //}
-   ////return getForcesTriangle();
-   //this->calculateForces();
-
-   double forceX1=0.0;
-   double forceX2=0.0;
-   double forceX3=0.0;
-
-   //double area = 0.0;
-
-   //vector<FeTriFaceMesh3D::VertexAttributes>* attributes = feMesh->getAttributes();
-
-   //for(size_t i=0; i<attributes->size(); i++)
-   //{
-   //   FeTriFaceMesh3D::VertexAttributes& attribut = (*attributes)[i];
-   //   area = attribut.getArea();
-   //   forceX1 += attribut.getFX()*area;
-   //   forceX2 += attribut.getFY()*area;
-   //   forceX3 += attribut.getFZ()*area;
-   //}
-   return UbTupleDouble3(forceX1,forceX2,forceX3);
-}
-//////////////////////////////////////////////////////////////////////////
-UbTupleDouble3 D3Q27TriFaceMeshInteractor::getForcesTriangle()
-{
-   double forceX1=0.0;
-   double forceX2=0.0;
-   double forceX3=0.0;
-
-   //D3Q19BlockGrid& grid.lock() = dynamic_cast<D3Q19BlockGrid&>(*this->grid.lock());
-   ////   CoordinateTransformation3D *trafo = this->grid.lock()->getTransformation();
-   ////   int minLevel = this->grid.lock()->getFinestInitializedLevel();
-   ////    double scaleX = trafo->getX1CoordinateScaling()/(1<<minLevel);
-   ////    double scaleY = trafo->getX2CoordinateScaling()/(1<<minLevel);
-   ////    double scaleZ = trafo->getX3CoordinateScaling()/(1<<minLevel);
-   ////    int blocknx1 = grid.lock()->getBlockNX1();
-   ////    int blocknx2 = grid.lock()->getBlockNX2();
-   ////    int blocknx3 = grid.lock()->getBlockNX3();
-   ////    double xOffset = trafo->getX1CoordinateOffset();
-   ////    double yOffset = trafo->getX2CoordinateOffset();
-   ////    double zOffset = trafo->getX3CoordinateOffset();
-   //vector<D3Q19Real> collFactors = ((D3Q19Calculator*)grid.lock()->getCalculator())->getCollisionsFactors();
-
-   ////for (int i=0;i<(int)gbTriangle3DInteractors.size(); i++)
-   ////{
-   ////   GbTriangle3D* tri = (GbTriangle3D*)gbTriangle3DInteractors[i]->getGbObject3D();
-
-   ////   double px0 = tri->getX1Centroid();
-   ////   double py0 = tri->getX2Centroid();
-   ////   double pz0 = tri->getX3Centroid();
-   ////   double px = px0-xOffset;
-   ////   double py = py0-yOffset;
-   ////   double pz = pz0-zOffset;
-   ////   px = px/scaleX;
-   ////   py = py/scaleY;
-   ////   pz = pz/scaleZ;
-   ////   int x1 = (int)px;
-   ////   int y1 = (int)py;
-   ////   int z1 = (int)pz;
-   ////   AMR3DBlock* block = this->grid.lock()->getBlock(x1,y1,z1,minLevel);
-   ////   if(!block)  block = this->grid.lock()->getSuperBlock(x1,y1,z1,minLevel);
-   ////   if(!block) throw UbException(__FILE__,__LINE__,"kein Block ...");
-
-   ////   double collFactor = collFactors[block->getLevel()];
-   ////   double nodeDistance = grid.lock()->getNodeDeltaX(block->getLevel());
-   ////   double bertX1 = ((px0-xOffset)/(1000.*nodeDistance));
-   ////   double bertX2 = ((py0-yOffset)/(1000.*nodeDistance));
-   ////   double bertX3 = ((pz0-zOffset)/(1000.*nodeDistance));
-   ////   int abstaendeX1 = (int)(bertX1*1000.);
-   ////   int abstaendeX2 = (int)(bertX2*1000.);
-   ////   int abstaendeX3 = (int)(bertX3*1000.);
-   ////   int posW = abstaendeX1 - block->getX1Index()*blocknx1;
-   ////   int posS = abstaendeX2 - block->getX2Index()*blocknx2;
-   ////   int posB = abstaendeX3 - block->getX3Index()*blocknx3;
-   ////   int posE=posW+1;
-   ////   int posN=posS+1;
-   ////   int posT=posB+1;
-
-   ////   D3Q19BlockDescriptor *bvd = dynamic_cast<D3Q19BlockDescriptor*>(block->getBlockDescriptor());
-   ////   if(!bvd) throw UbException(__FILE__,__LINE__,"kein Bvd ...");
-
-   ////   CbUniformMatrix4D<double,IndexerX1X2X3X4>* tempdistributions = bvd->getTempDistributionMatrix();
-   ////   D3Q19BCMatrix<D3Q19BoundaryCondition> *bcMatrix = bvd->getBcMatrix();
-
-   ////   UbTupleDouble6 stresses;
-   ////   double dX = px0-this->geoObject3D->getX1Centroid();
-   ////   double dY = py0-this->geoObject3D->getX2Centroid();
-   ////   double dZ = pz0-this->geoObject3D->getX3Centroid();
-   ////   if(dX<=0.0 && dY<=0.0 && dZ<=0.0)
-   ////   {
-   ////      double *fWSB  = tempdistributions->getStartAdressOfSortedArray(posW,posS,posB,0);
-   ////      if(bcMatrix->isFluid(posW,posS,posB)) stresses = D3Q19System::getIncompStresses(fWSB, collFactor );
-   ////      else cout<<__LINE__<<" nicht fluid ...";
-   ////   }
-   ////   else if(dX<=0.0 && dY>0.0 && dZ<=0.0)
-   ////   {
-   ////      double *fWNB  = tempdistributions->getStartAdressOfSortedArray(posW,posN,posB,0);
-   ////      if(bcMatrix->isFluid(posW,posN,posB)) stresses = D3Q19System::getIncompStresses(fWNB, collFactor );
-   ////      else cout<<__LINE__<<" nicht fluid ...";
-   ////   }
-   ////   else if(dX<=0.0 && dY<=0.0 && dZ>0.0)
-   ////   {
-   ////      double *fWST  = tempdistributions->getStartAdressOfSortedArray(posW,posS,posT,0);
-   ////      if(bcMatrix->isFluid(posW,posS,posT)) stresses = D3Q19System::getIncompStresses(fWST, collFactor );
-   ////      else cout<<__LINE__<<" nicht fluid ...";
-   ////   }
-   ////   else if(dX<=0.0 && dY>0.0 && dZ>0.0)
-   ////   {
-   ////      double *fWNT  = tempdistributions->getStartAdressOfSortedArray(posW,posN,posT,0);
-   ////      if(bcMatrix->isFluid(posW,posN,posT)) stresses = D3Q19System::getIncompStresses(fWNT, collFactor );
-   ////      else cout<<__LINE__<<" nicht fluid ...";
-   ////   }
-   ////   else if(dX>0.0 && dY<=0.0 && dZ<=0.0)
-   ////   {
-   ////      double *fESB  = tempdistributions->getStartAdressOfSortedArray(posE,posS,posB,0);
-   ////      if(bcMatrix->isFluid(posE,posS,posB)) stresses = D3Q19System::getIncompStresses(fESB, collFactor );
-   ////      else cout<<__LINE__<<" nicht fluid ...";
-   ////   }
-   ////   else if(dX>0.0 && dY>0.0 && dZ<=0.0)
-   ////   {
-   ////      double *fENB  = tempdistributions->getStartAdressOfSortedArray(posE,posN,posB,0);
-   ////      if(bcMatrix->isFluid(posE,posN,posB)) stresses = D3Q19System::getIncompStresses(fENB, collFactor );
-   ////      else cout<<__LINE__<<" nicht fluid ...";
-   ////   }
-   ////   else if(dX>0.0 && dY<=0.0 && dZ>0.0)
-   ////   {
-   ////      double *fEST  = tempdistributions->getStartAdressOfSortedArray(posE,posS,posT,0);
-   ////      if(bcMatrix->isFluid(posE,posS,posT)) stresses = D3Q19System::getIncompStresses(fEST, collFactor );
-   ////      else cout<<__LINE__<<" nicht fluid ...";
-   ////   }
-   ////   else if(dX>0.0 && dY>0.0 && dZ>0.0)
-   ////   {
-   ////      double *fENT  = tempdistributions->getStartAdressOfSortedArray(posE,posN,posT,0);
-   ////      if(bcMatrix->isFluid(posE,posN,posT)) stresses = D3Q19System::getIncompStresses(fENT, collFactor );
-   ////      else cout<<__LINE__<<" nicht fluid ...";
-   ////   }
-   ////   else cout<<"punkt mit:"<<dX<<" "<<dY<<" "<<dZ<<" ist nicht bei \n";
-
-   ////   double S11 = val<1>(stresses);
-   ////   double S22 = val<2>(stresses);
-   ////   double S33 = val<3>(stresses);
-   ////   double S12 = val<4>(stresses);
-   ////   double S13 = val<5>(stresses);
-   ////   double S23 = val<6>(stresses);
-
-   ////   GbVector3D normal = tri->getNormal();
-   ////   double nx = normal.X1();
-   ////   double ny = normal.X2();
-   ////   double nz = normal.X3();
-   ////   double area = tri->getArea();
-
-   ////   double Fx1 = area*(S11*nx+S12*ny+S13*nz);
-   ////   double Fy1 = area*(S12*nx+S22*ny+S23*nz);
-   ////   double Fz1 = area*(S13*nx+S23*ny+S33*nz);
-   ////   forceX1 += Fx1;
-   ////   forceX2 += Fy1;
-   ////   forceX3 += Fz1;
-   ////}
-   return UbTupleDouble3(forceX1,forceX2,forceX3);
-}
-//////////////////////////////////////////////////////////////////////////
-void D3Q27TriFaceMeshInteractor::calculateForces()
-{
-   //FeTriFaceMesh3D* feMesh = dynamic_cast<FeTriFaceMesh3D*>(this->geoObject3D.get());
-   //if(!feMesh) throw UbException(UB_EXARGS,"geoObject is not a FeTriFaceMesh3D!");
-
-   //if(this->stressMode == STRESSNORMAL) this->calculateStresses();
-   //else if(this->stressMode == STRESSALTERNATIV) this->calculateStressesAlternativ();
-
-   //vector<FeTriFaceMesh3D::VertexAttributes>* attributes = feMesh->getAttributes();
-
-   //for (int i=0;i<(int)attributes->size() ;i++)
-   //{
-   //   FeTriFaceMesh3D::VertexAttributes& attribut = (*attributes)[i];
-   //   attribut.setFX(0.0);
-   //   attribut.setFY(0.0);
-   //   attribut.setFZ(0.0);
-   //   attribut.setArea(0.0);
-   //}
-   //vector<GbTriFaceMesh3D::TriFace>& triangles = *feMesh->getTriangles();
-   //vector<GbTriFaceMesh3D::Vertex>&  nodes = *feMesh->getNodes();
-   //for (size_t i=0; i<triangles.size(); i++)
-   //{
-   //   GbTriFaceMesh3D::TriFace& triangle = triangles[i];
-   //   FeTriFaceMesh3D::VertexAttributes& vAttribut1 = (*attributes)[triangle.v1];
-   //   FeTriFaceMesh3D::VertexAttributes& vAttribut2 = (*attributes)[triangle.v2];
-   //   FeTriFaceMesh3D::VertexAttributes& vAttribut3 = (*attributes)[triangle.v3];
-   //   UbTupleDouble6& stressesP1 = vAttribut1.getStresses();
-   //   UbTupleDouble6& stressesP2 = vAttribut2.getStresses();
-   //   UbTupleDouble6& stressesP3 = vAttribut3.getStresses();
-   //   double p1S11 = val<1>(stressesP1); double p2S11 = val<1>(stressesP2); double p3S11 = val<1>(stressesP3);
-   //   double p1S22 = val<2>(stressesP1); double p2S22 = val<2>(stressesP2); double p3S22 = val<2>(stressesP3);
-   //   double p1S33 = val<3>(stressesP1); double p2S33 = val<3>(stressesP2); double p3S33 = val<3>(stressesP3);
-   //   double p1S12 = val<4>(stressesP1); double p2S12 = val<4>(stressesP2); double p3S12 = val<4>(stressesP3);
-   //   double p1S13 = val<5>(stressesP1); double p2S13 = val<5>(stressesP2); double p3S13 = val<5>(stressesP3);
-   //   double p1S23 = val<6>(stressesP1); double p2S23 = val<6>(stressesP2); double p3S23 = val<6>(stressesP3);
-
-   //   triangle.calculateNormal(nodes);
-   //   double nx = triangle.nx;
-   //   double ny = triangle.ny;
-   //   double nz = triangle.nz;
-   //   double area = 0.3333*triangle.getArea(nodes);
-
-   //   if(UbMath::lessEqual(area,0.0)) cout<<__FILE__<<" "<<__LINE__<<" area <= 0 "<<endl;
-
-   //   double Fx1 = area*(0.333*(p1S11*nx+p1S12*ny+p1S13*nz)+0.333*(p2S11*nx+p2S12*ny+p2S13*nz)+0.333*(p3S11*nx+p3S12*ny+p3S13*nz));
-   //   double Fx2 = Fx1;
-   //   double Fx3 = Fx1;
-
-   //   double Fy1 = area*(0.333*(p1S12*nx+p1S22*ny+p1S23*nz)+0.333*(p2S12*nx+p2S22*ny+p2S23*nz)+0.333*(p3S12*nx+p3S22*ny+p3S23*nz));
-   //   double Fy2 = Fy1;
-   //   double Fy3 = Fy1;
-
-   //   double Fz1 = area*(0.333*(p1S13*nx+p1S23*ny+p1S33*nz)+0.333*(p2S13*nx+p2S23*ny+p2S33*nz)+0.333*(p3S13*nx+p3S23*ny+p3S33*nz));
-   //   double Fz2 = Fz1;
-   //   double Fz3 = Fz1;
-   //   //  cout<<Fx1<<" "<<Fy1<<" "<<Fz1<<endl;
-   //   vAttribut1.addFX(Fx1);    vAttribut2.addFX(Fx2);    vAttribut3.addFX(Fx3);
-   //   vAttribut1.addFY(Fy1);    vAttribut2.addFY(Fy2);    vAttribut3.addFY(Fy3);
-   //   vAttribut1.addFZ(Fz1);    vAttribut2.addFZ(Fz2);    vAttribut3.addFZ(Fz3);
-   //   vAttribut1.addArea(area); vAttribut2.addArea(area); vAttribut3.addArea(area);
-   //}
-   //for (size_t i=0; i<attributes->size(); i++)
-   //{
-   //   FeTriFaceMesh3D::VertexAttributes& attribut = (*attributes)[i];
-
-   //   double newFX = attribut.getFX()/attribut.getArea();
-   //   double newFY = attribut.getFY()/attribut.getArea();
-   //   double newFZ = attribut.getFZ()/attribut.getArea();
-   //   //if(i==100) cout<<"F:"<<newFX<<" "<<newFY<<" "<<newFZ<<endl;
-   //   //double oldFX = p->getOldFX();
-   //   //double oldFY = p->getOldFY();
-   //   //int alphaSteps = p->getFilteringSteps();
-   //   //double alpha = 1.0;
-   //   //if(alphaSteps != 0)
-   //   //{
-   //   //   alpha = (1.0-alphaSteps*0.1);
-   //   // //  cout<<p->toString()<<" alpha:"<<alpha<<" steps:"<<alphaSteps<<endl;
-   //   //   p->reduceFilteringSteps();
-   //   //}
-   //   //newFX = (1.-alpha)*oldFX+alpha*newFX;
-   //   //newFY = (1.-alpha)*oldFY+alpha*newFY;
-
-   //   attribut.setFX(newFX);
-   //   attribut.setFY(newFY);
-   //   attribut.setFZ(newFZ);
-   //   //cout<<i<<" "<<newFX<<" "<<newFY<<" "<<newFZ<<endl;
-   //   //cout<<i<<" "<<p->toString()<<endl;
-
-   //}
-}
-//////////////////////////////////////////////////////////////////////////
-string D3Q27TriFaceMeshInteractor::toString()
-{
-   stringstream ss;
-   ss<< "D3Q27TriFaceMeshInteractor[label=D3Q27TriFaceMeshInteractor";
-   if(this->isSolid()) ss<<", solid";
-   if(this->isInverseSolid()) ss<<", inversesolid";
-   if(this->isTimeDependent()) ss<<", timedependent";
-   if(geoObject3D!=NULL) ss<<", AMR3DInteractor: "<<geoObject3D->toString();
-   ss<<"]";
-
-   return ss.str();
-}
-//////////////////////////////////////////////////////////////////////////
-void D3Q27TriFaceMeshInteractor::reinitWithStoredQs( const double& timeStep )
-{
-   //alle solid Bloecke wieder solid setzen
-   std::vector<Block3DPtr>& solidBlocks = this->getSolidBlockSet();
-   for(size_t i=0; i<solidBlocks.size(); i++)
-   {
-      solidBlocks[i]->setActive(false); //<- quick n dirty
-   }
-
-   //alle solid-nodes wieder solid setzen (solids die quasi in den TransBloecken liegen)
-   std::map<Block3DPtr, std::set< UbTupleInt3 > >::iterator it1;
-   for( it1=this->solidNodeIndicesMap.begin(); it1!=this->solidNodeIndicesMap.end(); ++it1 )
-   {
-      Block3DPtr block = it1->first;
-
-      LBMKernelPtr kernel = block->getKernel();
-      BCArray3DPtr bcMatrix = kernel->getBCProcessor()->getBCArray();
-      std::set< UbTupleInt3 >&  indicesSet = it1->second;
-
-      for( std::set< UbTupleInt3 >::iterator setIt=indicesSet.begin(); setIt!=indicesSet.end(); ++setIt )
-      {
-         bcMatrix->setSolid( val<1>(*setIt), val<2>(*setIt), val<3>(*setIt) );
-      }
-   }
-
-   //BCS WIEDERHERSTELLEN
-   std::map<Block3DPtr, std::map< UbTupleInt3, std::vector<float> > >::iterator it;
-   for( it=bcNodeIndicesAndQsMap.begin(); it!=bcNodeIndicesAndQsMap.end(); ++it )
-   {   
-      Block3DPtr  block    = it->first;
-      LBMKernelPtr kernel = block->getKernel();
-      BCArray3DPtr bcMatrix = kernel->getBCProcessor()->getBCArray();
-
-      std::map< UbTupleInt3, std::vector<float> >::iterator it2;
-      for( it2=it->second.begin(); it2!=it->second.end(); ++it2 )
-      {   
-         const UbTupleInt3&    pos = it2->first;
-         std::vector< float >       qs  = it2->second;
-
-         //SG_27.08.2010 
-         if(bcMatrix->isSolid(val<1>(pos), val<2>(pos), val<3>(pos))) continue;
-
-         BoundaryConditionsPtr   bc = bcMatrix->getBC( val<1>(pos), val<2>(pos), val<3>(pos) );
-         if(!bc)
-         {
-            bc = BoundaryConditionsPtr(new BoundaryConditions);
-            bcMatrix->setBC( val<1>(pos), val<2>(pos), val<3>(pos), bc );
-         }
-
-         double x1w = qs[D3Q27System::FENDDIR+1+0];
-         double x2w = qs[D3Q27System::FENDDIR+1+1];
-         double x3w = qs[D3Q27System::FENDDIR+1+2];
-
-
-         //TODO: HACK GEHOERT NICHT HIERHIER!!! - start
-         //es handelt sich un ein statisches Objekt und beim Propeller gibt
-         // es Schwierigkeiten an den Flügelspitzen, dass kann daher kommen,
-         //dass dort zuviel bc-flaggs sind und mit Geschwindigkeit ergibt dies ziemlich grosse Werte
-         bc->setBoundaryVelocityX1(0.0);
-         bc->setBoundaryVelocityX2(0.0);
-         bc->setBoundaryVelocityX3(0.0);
-         //TODO: HACK GEHOERT NICHT HIERHIER!!! - end
-
-         bool gotQs = false;
-         for(int fdir=D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
-         {
-            if( UbMath::greater(qs[fdir], -1.0) && UbMath::less( qs[fdir], bc->getQ(fdir) ) )
-            {
-               gotQs = true;
-               for(size_t index=0; index<this->bcAdapterVector.size(); index++)
-                  this->bcAdapterVector[index]->adaptBCForDirection( *this, bc, x1w, x2w, x3w, qs[fdir], fdir);
-            }
-         }
-
-         if(gotQs)
-            for(size_t index=0; index<this->bcAdapterVector.size(); index++)
-               this->bcAdapterVector[index]->adaptBC( *this, bc, x1w, x2w, x3w);
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void D3Q27TriFaceMeshInteractor::updateInteractor( const double& timestep/*=0*/ )
-{
-   UB_THROW( UbException("D3Q27TriFaceMeshInteractor::updateInteractor - toDo") );
-}
-
-
-
-
-
-
+#include "D3Q27TriFaceMeshInteractor.h"
+#include <basics/utilities/UbMath.h>
+#include <basics/utilities/UbLogger.h>
+#include <basics/utilities/UbStaticPathMap.h>
+
+#include <basics/writer/WbWriterVtkBinary.h>
+#include <basics/writer/WbWriterVtkXmlBinary.h>
+#include <basics/writer/WbWriterVtkASCII.h>
+#include "basics/writer/WbWriterVtkXmlASCII.h"
+
+#include <numerics/geometry3d/GbSystem3D.h>
+#include <numerics/geometry3d/GbCuboid3D.h>
+#include <numerics/geometry3d/GbHalfSpace3D.h>
+#include <numerics/geometry3d/GbMeshTools3D.h>
+#include "Block3D.h"
+#include "Grid3D.h"
+#include "BCArray3D.h"
+#include "BoundaryConditions.h"
+#include "VelocityBCAdapter.h"
+#include "LBMKernel.h"
+#include "BCProcessor.h"
+#include "basics/utilities/UbTiming.h"
+
+#include <numerics/geometry3d/GbTriFaceMesh3D.h>
+
+//#include <omp.h>
+
+#include <stack>
+#include "CoordinateTransformation3D.h"
+
+using namespace std;
+
+D3Q27TriFaceMeshInteractor::D3Q27TriFaceMeshInteractor()
+: D3Q27Interactor(), forceshift(0.0), velocityshift(0.0), forceshiftpolicy(false), velocityshiftpolicy(false), useHalfSpace(true), regardPIOTest(true)
+{
+   this->stressMode = STRESSNORMAL;
+}
+//////////////////////////////////////////////////////////////////////////
+D3Q27TriFaceMeshInteractor::D3Q27TriFaceMeshInteractor(Grid3DPtr grid, std::string name)
+{
+   this->stressMode = STRESSNORMAL;
+}
+//////////////////////////////////////////////////////////////////////////
+D3Q27TriFaceMeshInteractor::D3Q27TriFaceMeshInteractor(GbTriFaceMesh3DPtr triFaceMesh, Grid3DPtr grid, BCAdapterPtr bcAdapter, int type)
+: D3Q27Interactor(triFaceMesh, grid, bcAdapter, type), forceshift(0.0), velocityshift(0.0), forceshiftpolicy(false), velocityshiftpolicy(false), useHalfSpace(true), regardPIOTest(true)
+{
+   this->stressMode = STRESSNORMAL;
+}
+//////////////////////////////////////////////////////////////////////////
+D3Q27TriFaceMeshInteractor::D3Q27TriFaceMeshInteractor(GbTriFaceMesh3DPtr triFaceMesh, Grid3DPtr grid, BCAdapterPtr bcAdapter, int type, Interactor3D::Accuracy a)
+   : D3Q27Interactor(triFaceMesh, grid, bcAdapter, type, a), forceshift(0.0), velocityshift(0.0), forceshiftpolicy(false), velocityshiftpolicy(false), useHalfSpace(true), regardPIOTest(true)
+{
+   this->stressMode = STRESSNORMAL;
+}
+//////////////////////////////////////////////////////////////////////////
+D3Q27TriFaceMeshInteractor::~D3Q27TriFaceMeshInteractor()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27TriFaceMeshInteractor::initInteractor(const double& timeStep)
+{
+   Interactor3D::initInteractor(timeStep);
+   setQs(timeStep);
+}
+//////////////////////////////////////////////////////////////////////////
+bool D3Q27TriFaceMeshInteractor::setDifferencesToGbObject3D(const Block3DPtr block/*,const double& orgX1,const double& orgX2,const double& orgX3,const double& blockLengthX1,const double& blockLengthX2,const double& blockLengthX3, const double& timestep*/)
+{
+   if(!block) return false;
+
+   bcNodeIndicesMap[block] = set< std::vector<int> >();
+   set< std::vector<int> >& transNodeIndices = bcNodeIndicesMap[block];
+   solidNodeIndicesMap[block] = set< UbTupleInt3 >();
+   set< UbTupleInt3 >& solidNodeIndices = solidNodeIndicesMap[block];
+
+
+   bool oneEntryGotBC = false; //ob ueberhaupt ein eintrag ein BC zugewiesen wurde
+   bool gotQs         = false; //true, wenn "difference" gesetzt wurde
+   BoundaryConditionsPtr bc;
+
+   ILBMKernelPtr kernel = block->getKernel();
+   BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
+
+   double internX1,internX2,internX3;
+  
+   int startIX1 = 0, startIX2 = 0, startIX3 = 0; 
+   int stopIX1  = (int)bcArray->getNX1(), stopIX2  = (int)bcArray->getNX2(), stopIX3  = (int)bcArray->getNX3(); 
+
+   double         dx       = grid.lock()->getDeltaX(block);
+   UbTupleDouble3 orgDelta = grid.lock()->getNodeOffset(block);
+
+   bool pointOnBoundary = false;
+
+   for(int ix3=startIX3; ix3<stopIX3; ix3++)
+   {
+      for(int ix2=startIX2; ix2<stopIX2; ix2++)
+      {
+         for(int ix1=startIX1; ix1<stopIX1; ix1++)
+         {
+            Vector3D coords = grid.lock()->getNodeCoordinates(block, ix1, ix2, ix3);
+            internX1 = coords[0];
+            internX2 = coords[1];
+            internX3 = coords[2];
+
+            if(this->isSolid() )
+            {
+               if(this->geoObject3D->isPointInGbObject3D(internX1, internX2, internX3))
+               {
+                  if(bcArray->isFluid(ix1,ix2,ix3))
+                  {
+                     solidNodeIndices.insert(UbTupleInt3(ix1, ix2, ix3));
+                     bcArray->setSolid(ix1,ix2,ix3); 
+                  }
+               }
+            }
+            else if( this->isInverseSolid()  )
+            {
+               //bei inverse solid sind alle Knoten AUSSERHALB und auf der boundary SOLID
+               if( !this->geoObject3D->isPointInGbObject3D(internX1, internX2, internX3, pointOnBoundary) || pointOnBoundary == true )
+               {
+                  if(bcArray->isFluid(ix1,ix2,ix3))
+                  {
+                     solidNodeIndices.insert(UbTupleInt3(ix1, ix2, ix3));
+                     bcArray->setSolid(ix1,ix2,ix3);
+                  }
+               }
+            }
+         }
+      }
+   }
+
+   return oneEntryGotBC;
+}
+//////////////////////////////////////////////////////////////////////////
+//E.F. /4/16/2013
+void D3Q27TriFaceMeshInteractor::setQs(const double& timeStep)
+{
+   UBLOGML(logDEBUG1,"\nLBMTriFaceMeshInteractor - setQs start ");
+   if( !this->grid.lock() ) throw UbException(UB_EXARGS,"ups, no grid.lock()!!");
+
+   if( this->reinitWithStoredQsFlag && !bcNodeIndicesAndQsMap.empty() )
+   {
+      this->reinitWithStoredQs(timeStep);
+      return;
+   }
+
+   GbTriFaceMesh3D* mesh  = dynamic_cast<GbTriFaceMesh3D*>(this->geoObject3D.get());
+
+   //////////////////////////////////////////////////////////////////////////
+   //init bcs
+   //////////////////////////////////////////////////////////////////////////
+   int nofAdapter = (int)this->bcAdapters.size();
+   if(nofAdapter==0) std::cout<<"WARNING - D3Q27TriFaceMeshInteractor::initInteractor Warning - no nodeAdapter available for "/*<<this->getName()*/<<std::endl;
+   bool needTimeDependence = false;
+   for(int pos=0; pos<nofAdapter; ++pos)
+   {
+      this->bcAdapters[pos]->init(this,timeStep);
+      if(this->bcAdapters[pos]->isTimeDependent()) needTimeDependence = true;
+   }
+   if(needTimeDependence) this->setTimeDependent();
+   else                   this->unsetTimeDependent();
+
+   //////////////////////////////////////////////////////////////////////////
+   //grid.lock() info
+   //////////////////////////////////////////////////////////////////////////
+   int coarsestInitLevel = grid.lock()->getCoarsestInitializedLevel();
+   int finestInitLevel   = grid.lock()->getFinestInitializedLevel();
+
+   UbTupleInt3 blocknx = grid.lock()->getBlockNX();
+   int blocknx1 = val<1>(blocknx); //gilt fuer alle Level
+   int blocknx2 = val<2>(blocknx); //gilt fuer alle Level
+   int blocknx3 = val<3>(blocknx); //gilt fuer alle Level
+
+   //grobe Blocklaengen
+   CoordinateTransformation3DPtr trafo = grid.lock()->getCoordinateTransformator();
+   double cblockDeltaX1,cblockDeltaX2,cblockDeltaX3, delta ;
+   cblockDeltaX1 = cblockDeltaX2 = cblockDeltaX3 = delta = 1.0/(double)(1<<coarsestInitLevel);
+   if(trafo)
+   {
+      cblockDeltaX1 = trafo->getX1CoordinateScaling()*delta;
+      cblockDeltaX2 = trafo->getX2CoordinateScaling()*delta;
+      cblockDeltaX3 = trafo->getX3CoordinateScaling()*delta;
+   }
+   //levelspezifische blocklaengen und knotenabstaende
+   std::vector< std::vector<double> > nodeDeltaToNeigh(finestInitLevel+1);
+   std::vector<float>  deltaMinX1(finestInitLevel+1),deltaMinX2(finestInitLevel+1),deltaMinX3(finestInitLevel+1);
+   std::vector<float>  deltaMaxX1(finestInitLevel+1),deltaMaxX2(finestInitLevel+1),deltaMaxX3(finestInitLevel+1);
+
+   //Im Boltzmankontext muss dx1==dx2==dx3 sein!!
+   assert( UbMath::equal(cblockDeltaX1/(double)blocknx1, cblockDeltaX2/(double)blocknx2 ) );
+   assert( UbMath::equal(cblockDeltaX1/(double)blocknx1, cblockDeltaX3/(double)blocknx3 ) );
+
+   for(int level = coarsestInitLevel; level<=finestInitLevel; level++)
+   {
+      double nodeDeltaX1 = cblockDeltaX1/(double)(blocknx1*(1<<(level-coarsestInitLevel)));
+      double nodeDeltaX2 = cblockDeltaX2/(double)(blocknx2*(1<<(level-coarsestInitLevel)));
+      double nodeDeltaX3 = cblockDeltaX3/(double)(blocknx3*(1<<(level-coarsestInitLevel)));
+
+      std::vector<double> distNeigh(D3Q27System::FENDDIR+1, 0.0);
+      D3Q27System::calcDistanceToNeighbors(distNeigh, nodeDeltaX1,nodeDeltaX2,nodeDeltaX3);
+      //D3Q27System::calcDistanceToNeighbors(distNeigh, nodeDeltaX1);
+
+
+      nodeDeltaToNeigh[level].resize(D3Q27System::ENDDIR+1,0.0);
+      for(int fdir=D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
+      {
+         nodeDeltaToNeigh[level][fdir] = distNeigh[fdir];
+      }
+
+      //im gegensatz zum allg. Cell3DInteractor kann man hier auf max(0.02*blockDeltaX1[level],fabs(...)) verzichten
+      //da dies nur für blockDeltaCalculator->getMinX1Delta(level)==0.0 benötigt wird. ist im D3Q19... aber nie so
+      //Geller: kann man nicht diesen befuckten DeltaCalculator weglassen und hier einfach die Formel zum Delta rechnen reinpacken
+      //SirAnn: klar, mann kann auch weißwuerste am Alex verkaufen... aber zum einen ist das Ding dazu da
+      // und zum anderen sollt eman mal überlegen: "Formel zum Delta rechnen"->man muss rechnen
+      // blockDeltaCalculator->getMinX1Delta(level) -> ein geinlinter wert wird geholt 
+
+      //TODO: set 5.0 as variable parameter in constructor, default 2.0 
+      deltaMinX1[level] = (float)( 5.0*nodeDeltaX1); //kein minus da unten -deltaMin
+      deltaMinX2[level] = (float)( 5.0*nodeDeltaX2);
+      deltaMinX3[level] = (float)( 5.0*nodeDeltaX3);
+      deltaMaxX1[level] = (float)( 5.0*nodeDeltaX1);
+      deltaMaxX2[level] = (float)( 5.0*nodeDeltaX2);
+      deltaMaxX3[level] = (float)( 5.0*nodeDeltaX3);
+   }
+
+   //////////////////////////////////////////////////////////////////////////
+   //bounding cubes des TriFaceMesh ermitteln (pro level)
+   //////////////////////////////////////////////////////////////////////////
+   //min/max Werte des Dreiecksnetzes holen
+   double geoMinX1(0.0), geoMinX2(0.0), geoMinX3(0.0), geoMaxX1(0.0), geoMaxX2(0.0), geoMaxX3(0.0);
+
+   geoMinX1 = this->geoObject3D->getX1Minimum();  geoMaxX1 = this->geoObject3D->getX1Maximum();
+   geoMinX2 = this->geoObject3D->getX2Minimum();  geoMaxX2 = this->geoObject3D->getX2Maximum();
+   geoMinX3 = this->geoObject3D->getX3Minimum();  geoMaxX3 = this->geoObject3D->getX3Maximum();
+
+
+   //////////////////////////////////////////////////////////////////////////
+   //DREIECKE: q-Bestimmung
+   //////////////////////////////////////////////////////////////////////////
+
+   //notwendige variablen initialisieren (u.a. blockDeltas des groben levels)
+   float triPoints[3][3];
+   float vx1=0.0, vx2=0.0, vx3=0.0;
+   unsigned counterTriBoxOverlap=0, counterAABBTriFace=0, counterHalfspace=0, counterBilligOBB=0;
+   std::vector<GbTriFaceMesh3D::TriFace>& triangles = *mesh->getTriangles();
+   std::vector<GbTriFaceMesh3D::Vertex>&  nodes     = *mesh->getNodes();
+   std::map< Block3DPtr, std::set< UbTupleInt3 > > tmpSolidNodesFromOtherInteractors;
+
+   int onePercent = UbMath::integerRounding(triangles.size()*0.01);
+   if(onePercent==0) onePercent=1;
+   UbTimer setQTimer; setQTimer.start();
+   UBLOG(logDEBUG3, " - setQs for "<<(int)triangles.size()<<" triangles");
+
+   bool solidFromOtherInteractor = false;
+   float blockMinX[3],blockMaxX[3],boxCenter[3],halfBoxSize[3];
+
+   for(size_t t=0; t<triangles.size(); t++)
+   {
+      //////////////////////////////////////////////////////////////////////////
+      // Halfspace zum Dreieck generieren und min/max des Dreiecks ermitteln
+      //////////////////////////////////////////////////////////////////////////
+      GbTriFaceMesh3D::TriFace& triangle = triangles[t];
+
+      GbTriFaceMesh3D::Vertex& v1 = nodes[triangle.v1];
+      GbTriFaceMesh3D::Vertex& v2 = nodes[triangle.v2];
+      GbTriFaceMesh3D::Vertex& v3 = nodes[triangle.v3];
+
+      if(this->isInverseSolid() )
+      {					
+         triangle.nx*=(-1);
+         triangle.ny*=(-1);
+         triangle.nz*=(-1);	
+      }
+      GbHalfSpace3D halfSpace(  v1.x,v1.y,v1.z,triangle.nx,triangle.ny,triangle.nz );
+
+      //////////////////////////////////////////////////////////////////////////
+      //fuer GbMeshTools3D::triBoxOverlap
+      //////////////////////////////////////////////////////////////////////////
+      triPoints[0][0] = v1.x; triPoints[0][1] = v1.y; triPoints[0][2] = v1.z;
+      triPoints[1][0] = v2.x; triPoints[1][1] = v2.y; triPoints[1][2] = v2.z;
+      triPoints[2][0] = v3.x; triPoints[2][1] = v3.y; triPoints[2][2] = v3.z;
+
+      double minX1 = triangle.getMinX(nodes);   double maxX1 = triangle.getMaxX(nodes);
+      double minX2 = triangle.getMinY(nodes);   double maxX2 = triangle.getMaxY(nodes);
+      double minX3 = triangle.getMinZ(nodes);   double maxX3 = triangle.getMaxZ(nodes);
+
+      //////////////////////////////////////////////////////////////////////////
+      // Schleife ueber alle Level
+      //////////////////////////////////////////////////////////////////////////
+      double e1x1,e1x2,e1x3,e2x1,e2x2,e2x3,px1,px2,px3,a,f,sx1,sx2,sx3,u,qx1,qx2,qx3,v;
+      bool gotQs = false;
+      BoundaryConditionsPtr bc;
+
+      for(int level=coarsestInitLevel; level<=finestInitLevel; level++)
+      {
+         //////////////////////////////////////////////////////////////////////////
+         // levelspezifisches BoundCube des Dreicks ermitteln und zugehörige Bloecke beziehen
+         //////////////////////////////////////////////////////////////////////////
+         double boundCubeTriangleMinX1 = minX1-deltaMinX1[level];  double boundCubeTriangleMaxX1 = maxX1+deltaMaxX1[level];
+         double boundCubeTriangleMinX2 = minX2-deltaMinX2[level];  double boundCubeTriangleMaxX2 = maxX2+deltaMaxX2[level];
+         double boundCubeTriangleMinX3 = minX3-deltaMinX3[level];  double boundCubeTriangleMaxX3 = maxX3+deltaMaxX3[level];
+
+         GbCuboid3D boundingCubeTriangle(  boundCubeTriangleMinX1, boundCubeTriangleMinX2, boundCubeTriangleMinX3
+            , boundCubeTriangleMaxX1, boundCubeTriangleMaxX2, boundCubeTriangleMaxX3 );
+
+         std::vector<Block3DPtr> triBlocks;
+         grid.lock()->getBlocksByCuboid(level, boundCubeTriangleMinX1, boundCubeTriangleMinX2, boundCubeTriangleMinX3
+            , boundCubeTriangleMaxX1, boundCubeTriangleMaxX2, boundCubeTriangleMaxX3, triBlocks );
+
+         //////////////////////////////////////////////////////////////////////////
+         // Schleife ueber bloecke des level, die das dreieck beinhalten
+         //////////////////////////////////////////////////////////////////////////
+         for(std::size_t b=0; b<triBlocks.size(); b++)
+         {
+            Block3DPtr block = triBlocks[b];
+
+            ////////////////////////////////////////////////////////////////////////////
+            //// Block Dreieck-/test
+            ////////////////////////////////////////////////////////////////////////////
+            UbTupleDouble3 coords = grid.lock()->getBlockWorldCoordinates(block);
+            UbTupleDouble3 deltas = grid.lock()->getBlockLengths(block);
+
+            blockMinX[0]   = (float)(val<1>(coords)-deltaMinX1[level]);
+            blockMinX[1]   = (float)(val<2>(coords)-deltaMinX2[level]);
+            blockMinX[2]   = (float)(val<3>(coords)-deltaMinX3[level]);
+
+            blockMaxX[0]   = (float)(val<1>(coords)+val<1>(deltas)+deltaMaxX1[level]);
+            blockMaxX[1]   = (float)(val<2>(coords)+val<2>(deltas)+deltaMaxX2[level]);
+            blockMaxX[2]   = (float)(val<3>(coords)+val<3>(deltas)+deltaMaxX3[level]);
+
+            boxCenter[0]   = (float)(0.5*(blockMaxX[0]+blockMinX[0]));
+            boxCenter[1]   = (float)(0.5*(blockMaxX[1]+blockMinX[1]));
+            boxCenter[2]   = (float)(0.5*(blockMaxX[2]+blockMinX[2]));
+
+            halfBoxSize[0] = (float)(0.5*(blockMaxX[0]-blockMinX[0]));
+            halfBoxSize[1] = (float)(0.5*(blockMaxX[1]-blockMinX[1]));
+            halfBoxSize[2] = (float)(0.5*(blockMaxX[2]-blockMinX[2]));
+
+            //wenn dreieck "vergroesserten cube" nicht schneidet/beruehrt -> keine BC moeglich -> continue
+            if( !GbMeshTools3D::triBoxOverlap(boxCenter,halfBoxSize,triPoints) )
+            {
+               counterTriBoxOverlap++;
+               continue;
+            }
+
+            //////////////////////////////////////////////////////////////////////////
+            //Untersuchung der einzelnen nodes
+            //////////////////////////////////////////////////////////////////////////
+            bool blockGotBCs = false;
+
+            ILBMKernelPtr kernel = block->getKernel();
+            BCArray3DPtr bcMatrix = kernel->getBCProcessor()->getBCArray();
+
+            int indexMinX1 = 0;
+            int indexMinX2 = 0;
+            int indexMinX3 = 0;
+
+            int indexMaxX1 = (int)bcMatrix->getNX1();
+            int indexMaxX2 = (int)bcMatrix->getNX2();
+            int indexMaxX3 = (int)bcMatrix->getNX3();
+
+            std::set< std::vector<int> >& bcNodeIndices           = this->bcNodeIndicesMap[block];
+            std::set< UbTupleInt3 >& solidsFromOtherInteractors = tmpSolidNodesFromOtherInteractors[block];
+            double q, distance;
+
+            double& nodeDx1 = nodeDeltaToNeigh[level][D3Q27System::E];
+            double& nodeDx2 = nodeDeltaToNeigh[level][D3Q27System::N];
+            double& nodeDx3 = nodeDeltaToNeigh[level][D3Q27System::T];
+
+            //fuer OBB-Test
+            double qEinflussDelta = 1.1 * sqrt( nodeDx1*nodeDx1 + nodeDx2*nodeDx2 + nodeDx3*nodeDx3);
+
+            for(int ix3=indexMinX3; ix3<indexMaxX3; ix3++)
+            {
+               for(int ix2=indexMinX2; ix2<indexMaxX2; ix2++)
+               {
+                  for(int ix1=indexMinX1; ix1<indexMaxX1; ix1++)
+                  {	
+                     Vector3D pointplane1 =  grid.lock()->getNodeCoordinates(block, ix1,ix2,ix3);
+                     double   internX1 = pointplane1[0];
+                     double   internX2 = pointplane1[1];
+                     double   internX3 = pointplane1[2];
+
+                     int blx1 = block->getX1();
+                     int blx2 = block->getX2();
+                     int blx3 = block->getX3();
+
+                     if(bcMatrix->isSolid(ix1,ix2,ix3) || bcMatrix->isUndefined(ix1,ix2,ix3))
+                     {
+                        continue;
+                     }
+
+                     //////////////////////////////////////////////////////////////////////////
+                     //Punkt in AABB von Dreieck?                     
+                     //////////////////////////////////////////////////////////////////////////
+                     //ehsan changed
+                     bool pointIsOnBoundary = true;
+                     if( !boundingCubeTriangle.isPointInGbObject3D(internX1, internX2, internX3,pointIsOnBoundary) ) 
+                     {
+                        counterAABBTriFace++;
+                        continue;
+                     }
+                     //std::cout<<"internX3  "<<internX3<<"  internX2"<<internX2<<" internX1 "<<internX1<<"\n";
+                     //////////////////////////////////////////////////////////////////////////
+                     // Halbebenentests
+                     //////////////////////////////////////////////////////////////////////////
+                     distance = halfSpace.getDistance( internX1, internX2, internX3 );
+                     //Punkt in Halbebene? (nein, wenn distance<0)
+                     if(useHalfSpace && UbMath::less(distance, 0.0) )//== !halfSpace.ptInside(internX1,internX2,internX3) )
+                     {
+                        counterHalfspace++;
+                        continue;
+                     }
+
+                     //BilligOBB-Test: wenn distance > qEinflussDelta -> kein q
+                     if( UbMath::greater( fabs(distance), qEinflussDelta ) )
+                     {
+                        counterBilligOBB++;
+                        continue;
+                     }
+
+                     /////////////////////////////////////////////////////////////////////////////
+                     //Raytracingfür diskrete Boltzmannrichtungen
+                     /////////////////////////////////////////////////////////////////////////////
+                     gotQs = false;
+                     bc    = BoundaryConditionsPtr();
+
+                     //RAYTRACING - diskrete LB-dir zu Dreick
+                     //e1 = v1 - v0
+                     e1x1 = v2.x-v1.x;
+                     e1x2 = v2.y-v1.y;
+                     e1x3 = v2.z-v1.z;
+
+                     //e2 = v2 - v0
+                     e2x1 = v3.x-v1.x;
+                     e2x2 = v3.y-v1.y;
+                     e2x3 = v3.z-v1.z;
+
+                     //s = o - v0
+                     sx1 = internX1 - v1.x;
+                     sx2 = internX2 - v1.y;
+                     sx3 = internX3 - v1.z;
+
+                     for(int fdir=D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
+                     {
+                        //p = d x e2
+                        px1 = this->rayX2[fdir]*e2x3 - this->rayX3[fdir]*e2x2;
+                        px2 = this->rayX3[fdir]*e2x1 - this->rayX1[fdir]*e2x3;
+                        px3 = this->rayX1[fdir]*e2x2 - this->rayX2[fdir]*e2x1;
+
+                        //a = e1 dot p
+                        a = e1x1*px1 + e1x2*px2 + e1x3*px3;
+                        if(fabs(a)<1.E-10) continue;
+                        f = 1.0/a;
+
+                        //u = f * ( s dot p)
+                        u = f * ( sx1*px1 + sx2*px2 + sx3*px3 );
+                        if(u<-1.E-10 || u>1.0+1.E-10) continue;
+
+                        //q = s x e1
+                        qx1 = sx2*e1x3 - sx3*e1x2;
+                        qx2 = sx3*e1x1 - sx1*e1x3;
+                        qx3 = sx1*e1x2 - sx2*e1x1;
+
+                        //v = f*(e2 dot q)
+                        v = f * (this->rayX1[fdir]*qx1 + this->rayX2[fdir]*qx2 + this->rayX3[fdir]*qx3);
+                        if(v<-1.E-10 || (u+v)>1.0+1.E-10) continue;
+
+                        //t = f * (e2 dot q)
+                        q = f * (e2x1*qx1 + e2x2*qx2 + e2x3*qx3);
+                        q /= nodeDeltaToNeigh[level][fdir];
+                        /////ehsan q/////////////////////////////////////////////////////////////////////
+                        double det=triangle.nx * this->rayX1[fdir]+ triangle.ny * this->rayX2[fdir]+ triangle.nz * this->rayX3[fdir];
+
+                        if(det>-1.E-10) continue;
+                        double d=triangle.nx*v1.x+triangle.ny*v1.y+triangle.nz*v1.z;
+                        double x1= -((-d* this->rayX1[fdir] - triangle.ny *this->rayX2[fdir]* internX1 - triangle.nz *this->rayX3[fdir]* internX1 + triangle.ny *this->rayX1[fdir]* internX2 + triangle.nz* this->rayX1[fdir]* internX3))/det;
+                        double y1= -((-d* this->rayX2[fdir] + triangle.nx* this->rayX2[fdir]* internX1 - triangle.nx* this->rayX1[fdir]* internX2 - triangle.nz* this->rayX3[fdir] *internX2 + triangle.nz* this->rayX2[fdir]* internX3))/det;
+                        double z1=	-((-d* this->rayX3[fdir] + triangle.nx* this->rayX3[fdir]* internX1 + triangle.ny* this->rayX3[fdir]* internX2 - triangle.nx* this->rayX1[fdir]* internX3 - triangle.ny* this->rayX2[fdir]* internX3))/det;
+                        double q_ehsan=sqrt((x1-internX1)*(x1-internX1)+(y1-internX2)*(y1-internX2)+(z1-internX3)*(z1-internX3));
+                        q_ehsan /= nodeDeltaToNeigh[level][fdir];
+                        q=q_ehsan;	 
+                        if( UbMath::greater(q, 1.0) || UbMath::lessEqual(q, 0.0) )continue;
+
+                        //gefundenes q auf gueltigkeit pruefen
+                        if( UbMath::zero(q) )
+                        {
+                           //neu (18.05.2010)
+                           //es kann vorkommen, dass bei dünnwandigen geos punkte, die auf einem dreieck liegen, qs bekommen, die durch die geo
+                           //durchgehen. diese punkte werden später jedoch nicht mehr auf solid getestet, da sie ja ne BC bekommen haben
+                           //--> da mind ein q==0.0 für eines der dreiecke -> dort solid setzen
+                           this->solidNodeIndicesMap[block].insert( UbTupleInt3(ix1,ix2,ix3) );
+                           bcMatrix->setSolid( ix1, ix2, ix3 );
+                           continue;
+                        }
+
+                        if( UbMath::inClosedInterval(q, 1.0, 1.0) ) q = 1.0;
+                        if( UbMath::greater(q, 0.0) && UbMath::lessEqual(q, 1.0) )
+                        {
+                           gotQs=blockGotBCs=true;
+
+                           bc = bcMatrix->getBC(ix1,ix2,ix3);
+
+                           //SG 26.08.2010 if(!bc && !bcMatrix->isSolid())
+                           if(!bc)
+                           {
+                              bc = BoundaryConditionsPtr(new BoundaryConditions);;
+                              bcMatrix->setBC(ix1,ix2,ix3,bc);
+                           }
+                           else if( UbMath::less( bc->getQ(fdir), q ) )  //schon ein kuerzeres q voehanden?
+                           {
+                              //neu:: 18.05.2010
+                              //um falsche qs die evtl durch die "wand" gehen zu vermeiden 
+                              //q nur dann neu setzen, wenn neues q kleiner als vorhandenes!
+                              //Zudem: insbesondere an ecken mit zwei BC geos ist nur das 
+                              //naehere gueltig
+                              continue;
+                           }
+
+                           bc->setBoundaryVelocityX1(vx1);
+                           bc->setBoundaryVelocityX2(vx2);
+                           bc->setBoundaryVelocityX3(vx3);
+
+                           for(int index=(int)this->bcAdapters.size()-1; index>=0; --index)
+                              this->bcAdapters[index]->adaptBCForDirection(*this,bc,internX1,internX2,internX3,q,fdir);
+
+                           //fuer beschleunigtes wiedereinlesen
+                           if(this->reinitWithStoredQsFlag)
+                           {
+                              bcNodeIndicesAndQsMap[block][ UbTupleInt3(ix1, ix2, ix3) ].resize(D3Q27System::FENDDIR+1+3, -1.0f);
+                              bcNodeIndicesAndQsMap[block][ UbTupleInt3(ix1, ix2, ix3) ][fdir                    ] = float(q);
+                              bcNodeIndicesAndQsMap[block][ UbTupleInt3(ix1, ix2, ix3) ][D3Q27System::FENDDIR+1+0] = float(internX1);
+                              bcNodeIndicesAndQsMap[block][ UbTupleInt3(ix1, ix2, ix3) ][D3Q27System::FENDDIR+1+1] = float(internX2);
+                              bcNodeIndicesAndQsMap[block][ UbTupleInt3(ix1, ix2, ix3) ][D3Q27System::FENDDIR+1+2] = float(internX3);
+                           }
+                        }
+                     }
+
+                     if(gotQs)
+                     {
+                        std::vector<int> p(3);
+                        p[0]=ix1; p[1]=ix2; p[2]=ix3;
+                        bcNodeIndices.insert(p);
+
+                        for(int index=(int)this->bcAdapters.size()-1; index>=0; --index)
+                           this->bcAdapters[index]->adaptBC(*this,bc,internX1,internX2,internX3);
+                     }
+                  }
+               }
+            }
+         }
+         //dynamische Punkte des GbCuboids muessen leider per "Hand" geloescht werden :-(
+         boundingCubeTriangle.finalize();
+      }
+   }
+   UBLOGML(logDEBUG1,"\nLBMTriFaceMeshInteractor - setQs end ");
+}
+//////////////////////////////////////////////////////////////////////////
+//Vorgehesnweise
+//A – Bestimmung der q's
+//  1. fuer jeden Bounding cube eines Dreiecks des netzes werden die Bloecke des Blockgitter ermittelt
+//  2. mittels eines Dreieck/Block Verschneidungstest werden weitere nicht relevante Bloecke aussortiert
+//     (fuer lange „schief“ im Raum stehende Dreicke, bei denen das Bounding Cube suboptimal ist)
+//  3. jeder Knoten dieser blöcke wird gegen das bound cube des dreiecks getestet
+//  4. Knoten die innerhalb des Cubes aber „innerhalb“ des Netzes liegen werden mittels Halbebenentest aussoriert
+//  5. fuer die restliche Knoten erfolgt die q bestimmung mittels effizienter raytracing algorithmen
+//     fuer die diskreten Boltzmannrichtungen
+//B – Setzen der nicht aktiven Bloecke und Solid Nodes
+//  alle Bloecke des Bounding Cube des Netzes, die mind eine BC erhielten, wurden in A markiert
+//  1. fuer nicht markierte Bloecke genuegt EIN pointInObject(Dreicksnetz)-Test um den gesamten Block bei Erfolg als „not active“ zu markieren
+//  2. fuer markiertre Bloecke wird ein rekursiver Fuellalgorithmus durchgefuehrt
+void D3Q27TriFaceMeshInteractor::initInteractor2(const double& timeStep)
+{
+   UBLOGML(logDEBUG1,"\nLBMTriFaceMeshInteractor - initInteractor start ");
+   if( !this->grid.lock() ) throw UbException(UB_EXARGS,"ups, no grid.lock()!!");
+
+   if( this->reinitWithStoredQsFlag && !bcNodeIndicesAndQsMap.empty() )
+   {
+      this->reinitWithStoredQs(timeStep);
+      return;
+   }
+
+   GbTriFaceMesh3D* mesh  = dynamic_cast<GbTriFaceMesh3D*>(this->geoObject3D.get());
+
+   UBLOGML(logDEBUG1,"\nLBMTriFaceMeshInteractor - initInteractor for \""<<mesh->getName()<<" \" t="<<timeStep);
+   //cout<<" - init basics ...";
+
+   this->removeBcBlocks();  //hier wird auch die nodeIndicesMap geloescht!
+   this->removeSolidBlocks();
+
+   //////////////////////////////////////////////////////////////////////////
+   //init bcs
+   //////////////////////////////////////////////////////////////////////////
+   int nofAdapter = (int)this->bcAdapters.size();
+   if(nofAdapter==0) std::cout<<"WARNING - D3Q27TriFaceMeshInteractor::initInteractor Warning - no nodeAdapter available for "/*<<this->getName()*/<<std::endl;
+   bool needTimeDependence = false;
+   for(int pos=0; pos<nofAdapter; ++pos)
+   {
+      this->bcAdapters[pos]->init(this,timeStep);
+      if(this->bcAdapters[pos]->isTimeDependent()) needTimeDependence = true;
+   }
+   if(needTimeDependence) this->setTimeDependent();
+   else                   this->unsetTimeDependent();
+
+   //////////////////////////////////////////////////////////////////////////
+   //grid.lock() info
+   //////////////////////////////////////////////////////////////////////////
+   int coarsestInitLevel = grid.lock()->getCoarsestInitializedLevel();
+   int finestInitLevel   = grid.lock()->getFinestInitializedLevel();
+
+   UbTupleInt3 blocknx = grid.lock()->getBlockNX();
+   int blocknx1 = val<1>(blocknx); //gilt fuer alle Level
+   int blocknx2 = val<2>(blocknx); //gilt fuer alle Level
+   int blocknx3 = val<3>(blocknx); //gilt fuer alle Level
+
+   //grobe Blocklaengen
+   CoordinateTransformation3DPtr trafo = grid.lock()->getCoordinateTransformator();
+   double cblockDeltaX1,cblockDeltaX2,cblockDeltaX3, delta ;
+   cblockDeltaX1 = cblockDeltaX2 = cblockDeltaX3 = delta = 1.0/(double)(1<<coarsestInitLevel);
+   if(trafo)
+   {
+      cblockDeltaX1 = trafo->getX1CoordinateScaling()*delta;
+      cblockDeltaX2 = trafo->getX2CoordinateScaling()*delta;
+      cblockDeltaX3 = trafo->getX3CoordinateScaling()*delta;
+   }
+   //levelspezifische blocklaengen und knotenabstaende
+   std::vector< std::vector<double> > nodeDeltaToNeigh(finestInitLevel+1);
+   //vector<double> blockDeltaX1(finestInitLevel+1), blockDeltaX2(finestInitLevel+1), blockDeltaX3(finestInitLevel+1);
+   std::vector<float>  deltaMinX1(finestInitLevel+1),deltaMinX2(finestInitLevel+1),deltaMinX3(finestInitLevel+1);
+   std::vector<float>  deltaMaxX1(finestInitLevel+1),deltaMaxX2(finestInitLevel+1),deltaMaxX3(finestInitLevel+1);
+
+   //Im Boltzmankontext muss dx1==dx2==dx3 sein!!
+   assert( UbMath::equal(cblockDeltaX1/(double)blocknx1, cblockDeltaX2/(double)blocknx2 ) );
+   assert( UbMath::equal(cblockDeltaX1/(double)blocknx1, cblockDeltaX3/(double)blocknx3 ) );
+
+   for(int level = coarsestInitLevel; level<=finestInitLevel; level++)
+   {
+      double nodeDelta = cblockDeltaX1/(double)(blocknx1*(1<<(level-coarsestInitLevel)));
+
+      std::vector<double> distNeigh(D3Q27System::FENDDIR+1, 0.0);
+      D3Q27System::calcDistanceToNeighbors(distNeigh, nodeDelta);
+
+      nodeDeltaToNeigh[level].resize(D3Q27System::ENDDIR+1,0.0);
+      for(int fdir=D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
+      {
+         nodeDeltaToNeigh[level][fdir] = distNeigh[fdir];
+      }
+
+      //im gegensatz zum allg. Cell3DInteractor kann man hier auf max(0.02*blockDeltaX1[level],fabs(...)) verzichten
+      //da dies nur für blockDeltaCalculator->getMinX1Delta(level)==0.0 benötigt wird. ist im D3Q19... aber nie so
+      //Geller: kann man nicht diesen befuckten DeltaCalculator weglassen und hier einfach die Formel zum Delta rechnen reinpacken
+      //SirAnn: klar, mann kann auch weißwuerste am Alex verkaufen... aber zum einen ist das Ding dazu da
+      // und zum anderen sollt eman mal überlegen: "Formel zum Delta rechnen"->man muss rechnen
+      // blockDeltaCalculator->getMinX1Delta(level) -> ein geinlinter wert wird geholt 
+
+      deltaMinX1[level] = (float)( 1.2*nodeDelta); //kein minus da unten -deltaMin
+      deltaMinX2[level] = (float)( 1.2*nodeDelta);
+      deltaMinX3[level] = (float)( 1.2*nodeDelta);
+      deltaMaxX1[level] = (float)( 1.2*nodeDelta);
+      deltaMaxX2[level] = (float)( 1.2*nodeDelta);
+      deltaMaxX3[level] = (float)( 1.2*nodeDelta);
+   }
+
+   //////////////////////////////////////////////////////////////////////////
+   //bounding cubes des TriFaceMesh ermitteln (pro level)
+   //////////////////////////////////////////////////////////////////////////
+   //min/max Werte des Dreiecksnetzes holen
+   double geoMinX1(0.0), geoMinX2(0.0), geoMinX3(0.0), geoMaxX1(0.0), geoMaxX2(0.0), geoMaxX3(0.0);
+   if(this->isSolid() || this->isMoveable())
+   {
+      geoMinX1 = this->geoObject3D->getX1Minimum();  geoMaxX1 = this->geoObject3D->getX1Maximum();
+      geoMinX2 = this->geoObject3D->getX2Minimum();  geoMaxX2 = this->geoObject3D->getX2Maximum();
+      geoMinX3 = this->geoObject3D->getX3Minimum();  geoMaxX3 = this->geoObject3D->getX3Maximum();
+   }
+   else throw UbException(UB_EXARGS,"only TYPE==SOLID is implemented" );
+
+   std::map<Block3DPtr,SolidCheckMethod> blocksForSolidCheck;
+
+   for(int level = coarsestInitLevel; level<=finestInitLevel; level++)
+   {
+      if(this->isSolid() || this->isMoveable())
+      {
+         //bloecke fuer "bounding cube gesamt"
+         std::vector<Block3DPtr> tmpblocks;
+         grid.lock()->getBlocksByCuboid(level,geoMinX1-deltaMinX1[level], geoMinX2-deltaMinX2[level], geoMinX3-deltaMinX3[level],
+            geoMaxX1+deltaMaxX1[level], geoMaxX2+deltaMaxX2[level], geoMaxX3+deltaMaxX3[level],tmpblocks );
+
+         for( size_t i=0; i<tmpblocks.size(); i++ )
+            blocksForSolidCheck[tmpblocks[i]] = PointInObject;
+      }
+   }
+
+   //////////////////////////////////////////////////////////////////////////
+   //FE-specific
+   //////////////////////////////////////////////////////////////////////////
+   //bool calcVelocities = false;
+   //FeTriFaceMesh3D* feMesh = dynamic_cast<FeTriFaceMesh3D*>(mesh);
+   //std::vector<FeTriFaceMesh3D::VertexAttributes>* attributes = NULL;
+   //if(feMesh)
+   //{
+   //   calcVelocities = true;
+   //   attributes     = feMesh->getAttributes();
+   //}
+
+   //////////////////////////////////////////////////////////////////////////
+   //DREIECKE: q-Bestimmung
+   //////////////////////////////////////////////////////////////////////////
+
+   //notwendige variablen initialisieren (u.a. blockDeltas des groben levels)
+   float triPoints[3][3];
+   float vx1=0.0, vx2=0.0, vx3=0.0;
+   unsigned counterTriBoxOverlap=0, counterAABBTriFace=0, counterHalfspace=0, counterBilligOBB=0;
+   std::vector<GbTriFaceMesh3D::TriFace>& triangles = *mesh->getTriangles();
+   std::vector<GbTriFaceMesh3D::Vertex>&  nodes     = *mesh->getNodes();
+   std::map< Block3DPtr, std::set< std::vector<int> > > tmpSolidNodesFromOtherInteractors;
+
+   int onePercent = UbMath::integerRounding(triangles.size()*0.01);
+   if(onePercent==0) onePercent=1;
+   UbTimer setQTimer; setQTimer.start();
+   UBLOG(logDEBUG3, " - setQs for "<<(int)triangles.size()<<" triangles");
+
+   bool solidFromOtherInteractor = false;
+   float blockMinX[3],blockMaxX[3],boxCenter[3],halfBoxSize[3];
+
+   for(size_t t=0; t<triangles.size(); t++)
+   {
+	   //if (t==10577)
+	   //{
+		  // int ehsan=0;
+	   //}
+      //////////////////////////////////////////////////////////////////////////
+      // Halfspace zum Dreieck generieren und min/max des Dreiecks ermitteln
+      //////////////////////////////////////////////////////////////////////////
+      GbTriFaceMesh3D::TriFace& triangle = triangles[t];
+
+      GbTriFaceMesh3D::Vertex& v1 = nodes[triangle.v1];
+      GbTriFaceMesh3D::Vertex& v2 = nodes[triangle.v2];
+      GbTriFaceMesh3D::Vertex& v3 = nodes[triangle.v3];
+
+      GbHalfSpace3D halfSpace(  v1.x,v1.y,v1.z,v2.x,v2.y,v2.z,v3.x,v3.y,v3.z );
+
+      //if(calcVelocities)
+      //{
+      //   FeTriFaceMesh3D::VertexAttributes& vAttribut1 = (*attributes)[triangle.v1];
+      //   FeTriFaceMesh3D::VertexAttributes& vAttribut2 = (*attributes)[triangle.v2];
+      //   FeTriFaceMesh3D::VertexAttributes& vAttribut3 = (*attributes)[triangle.v3];
+      //   vx1 = (float)(UbMath::c1o3*(vAttribut1.getVelocityX()+vAttribut2.getVelocityX()+vAttribut3.getVelocityX()));
+      //   vx2 = (float)(UbMath::c1o3*(vAttribut1.getVelocityY()+vAttribut2.getVelocityY()+vAttribut3.getVelocityY()));
+      //   vx3 = (float)(UbMath::c1o3*(vAttribut1.getVelocityZ()+vAttribut2.getVelocityZ()+vAttribut3.getVelocityZ()));
+      //}
+
+      //////////////////////////////////////////////////////////////////////////
+      //fuer GbMeshTools3D::triBoxOverlap
+      //////////////////////////////////////////////////////////////////////////
+      triPoints[0][0] = v1.x; triPoints[0][1] = v1.y; triPoints[0][2] = v1.z;
+      triPoints[1][0] = v2.x; triPoints[1][1] = v2.y; triPoints[1][2] = v2.z;
+      triPoints[2][0] = v3.x; triPoints[2][1] = v3.y; triPoints[2][2] = v3.z;
+
+      double minX1 = triangle.getMinX(nodes);   double maxX1 = triangle.getMaxX(nodes);
+      double minX2 = triangle.getMinY(nodes);   double maxX2 = triangle.getMaxY(nodes);
+      double minX3 = triangle.getMinZ(nodes);   double maxX3 = triangle.getMaxZ(nodes);
+
+      //////////////////////////////////////////////////////////////////////////
+      // Schleife ueber alle Level
+      //////////////////////////////////////////////////////////////////////////
+      double e1x1,e1x2,e1x3,e2x1,e2x2,e2x3,px1,px2,px3,a,f,sx1,sx2,sx3,u,qx1,qx2,qx3,v;
+      bool gotQs = false;
+      BoundaryConditionsPtr bc;
+
+      for(int level=coarsestInitLevel; level<=finestInitLevel; level++)
+      {
+         //////////////////////////////////////////////////////////////////////////
+         // levelspezifisches BoundCube des Dreicks ermitteln und zugehörige Bloecke beziehen
+         //////////////////////////////////////////////////////////////////////////
+         double boundCubeTriangleMinX1 = minX1-deltaMinX1[level];  double boundCubeTriangleMaxX1 = maxX1+deltaMaxX1[level];
+         double boundCubeTriangleMinX2 = minX2-deltaMinX2[level];  double boundCubeTriangleMaxX2 = maxX2+deltaMaxX2[level];
+         double boundCubeTriangleMinX3 = minX3-deltaMinX3[level];  double boundCubeTriangleMaxX3 = maxX3+deltaMaxX3[level];
+
+         GbCuboid3D boundingCubeTriangle(  boundCubeTriangleMinX1, boundCubeTriangleMinX2, boundCubeTriangleMinX3
+            , boundCubeTriangleMaxX1, boundCubeTriangleMaxX2, boundCubeTriangleMaxX3 );
+
+         std::vector<Block3DPtr> triBlocks;
+         grid.lock()->getBlocksByCuboid(level, boundCubeTriangleMinX1, boundCubeTriangleMinX2, boundCubeTriangleMinX3
+            , boundCubeTriangleMaxX1, boundCubeTriangleMaxX2, boundCubeTriangleMaxX3, triBlocks );
+
+         //////////////////////////////////////////////////////////////////////////
+         // Schleife ueber bloecke des level, die das dreieck beinhalten
+         //////////////////////////////////////////////////////////////////////////
+         for(std::size_t b=0; b<triBlocks.size(); b++)
+         {
+            Block3DPtr block = triBlocks[b];
+
+            ////////////////////////////////////////////////////////////////////////////
+            //// Block Dreieck-/test
+            ////////////////////////////////////////////////////////////////////////////
+            UbTupleDouble3 coords = grid.lock()->getBlockWorldCoordinates(block);
+            UbTupleDouble3 deltas = grid.lock()->getBlockLengths(block);
+
+            blockMinX[0]   = (float)(val<1>(coords)-deltaMinX1[level]);
+            blockMinX[1]   = (float)(val<2>(coords)-deltaMinX2[level]);
+            blockMinX[2]   = (float)(val<3>(coords)-deltaMinX3[level]);
+
+            blockMaxX[0]   = (float)(val<1>(coords)+val<1>(deltas)+deltaMaxX1[level]);
+            blockMaxX[1]   = (float)(val<2>(coords)+val<2>(deltas)+deltaMaxX2[level]);
+            blockMaxX[2]   = (float)(val<3>(coords)+val<3>(deltas)+deltaMaxX3[level]);
+
+            boxCenter[0]   = (float)(0.5*(blockMaxX[0]+blockMinX[0]));
+            boxCenter[1]   = (float)(0.5*(blockMaxX[1]+blockMinX[1]));
+            boxCenter[2]   = (float)(0.5*(blockMaxX[2]+blockMinX[2]));
+
+            halfBoxSize[0] = (float)(0.5*(blockMaxX[0]-blockMinX[0]));
+            halfBoxSize[1] = (float)(0.5*(blockMaxX[1]-blockMinX[1]));
+            halfBoxSize[2] = (float)(0.5*(blockMaxX[2]-blockMinX[2]));
+
+            //wenn dreieck "vergroesserten cube" nicht schneidet/beruehrt -> keine BC moeglich -> continue
+            if( !GbMeshTools3D::triBoxOverlap(boxCenter,halfBoxSize,triPoints) )
+            {
+               counterTriBoxOverlap++;
+               continue;
+            }
+
+            //////////////////////////////////////////////////////////////////////////
+            //Untersuchung der einzelnen nodes
+            //////////////////////////////////////////////////////////////////////////
+            bool blockGotBCs = false;
+
+            ILBMKernelPtr kernel = block->getKernel();
+            BCArray3DPtr bcMatrix = kernel->getBCProcessor()->getBCArray();
+
+            int indexMinX1 = 0;
+            int indexMinX2 = 0;
+            int indexMinX3 = 0;
+
+            int indexMaxX1 = (int)bcMatrix->getNX1();
+            int indexMaxX2 = (int)bcMatrix->getNX2();
+            int indexMaxX3 = (int)bcMatrix->getNX3();
+
+            std::set< std::vector<int> >& bcNodeIndices           = this->bcNodeIndicesMap[block];
+            std::set< std::vector<int> >& solidsFromOtherInteractors = tmpSolidNodesFromOtherInteractors[block];
+            double q, internX1, internX2, internX3,distance;
+
+            double& nodeDx1 = nodeDeltaToNeigh[level][D3Q27System::E];
+            double& nodeDx2 = nodeDeltaToNeigh[level][D3Q27System::N];
+            double& nodeDx3 = nodeDeltaToNeigh[level][D3Q27System::T];
+
+            //fuer OBB-Test
+            double qEinflussDelta = 1.1 * sqrt( nodeDx1*nodeDx1 + nodeDx2*nodeDx2 + nodeDx3*nodeDx3);
+
+            for(int ix3=indexMinX3; ix3<indexMaxX3; ix3++)
+            {
+               internX3 = val<3>(coords)+nodeDx3*ix3-0.5*nodeDx3;
+               for(int ix2=indexMinX2; ix2<indexMaxX2; ix2++)
+               {
+                  internX2 = val<2>(coords)+nodeDx2*ix2-0.5*nodeDx2;
+                  for(int ix1=indexMinX1; ix1<indexMaxX1; ix1++)
+                  {
+					 
+					  int blx1 =block->getX1();
+					  int blx2 = block->getX2();
+					  int blx3 = block->getX3();
+
+					  if (blx1==0&&blx2==1&&blx3==0)
+					  {
+						  //if (ix2==39&&ix3==4)
+							   if (ix2==39&&ix3==4)
+						  {
+							 int seb=0;
+						  }
+
+					  }
+                     //Problem: wenn voher der punkt durch eine andere geo not active gesetzt wird und
+                     //dieser nun uebersprungen wird, dann hat man spaeter beim fuellalgorithmus luecken
+                     //in der front und der block wird u.U. faelschlicher weise komplett solid markiert
+                     //Lsg: positionen merken und erst Nach dem fuellarlgo wieder auf not active setzen :-)
+                     solidFromOtherInteractor = false;
+                     if(bcMatrix->isSolid(ix1,ix2,ix3))
+                     {
+                        if(this->reinitWithStoredQsFlag)
+                        {
+                           solidFromOtherInteractor = true;   //hier muss man weitermachen
+                           //SG //oje 
+                           std::vector<int> p(3);
+                           p[0]=ix1; p[1]=ix2; p[2]=ix3;
+                           solidsFromOtherInteractors.insert( p );
+                        }
+                        else
+                        {
+                           //SG //oje 
+                           std::vector<int> p(3);
+                           p[0]=ix1; p[1]=ix2; p[2]=ix3;
+                           solidsFromOtherInteractors.insert(p);
+                           //SG continue;   
+                           solidFromOtherInteractor = true;   
+                        }
+                     }
+
+                     internX1 = val<1>(coords)+nodeDx1*ix1-0.5*nodeDx1;
+
+                     //////////////////////////////////////////////////////////////////////////
+                     //Punkt in AABB von Dreieck?                     
+                     //////////////////////////////////////////////////////////////////////////
+					//ehsan changedâ—˜
+					 bool pointIsOnBoundary = false;
+					 if( !boundingCubeTriangle.isPointInGbObject3D(internX1, internX2, internX3,pointIsOnBoundary) ) 
+                    // if( !boundingCubeTriangle.isPointInGbObject3D(internX1, internX2, internX3) ) 
+                     {
+                        counterAABBTriFace++;
+                        continue;
+                     }
+
+                     //////////////////////////////////////////////////////////////////////////
+                     // Halbebenentests
+                     //////////////////////////////////////////////////////////////////////////
+                     distance = halfSpace.getDistance( internX1, internX2, internX3 );
+
+                     //Punkt in Halbebene? (nein, wenn distance<0)
+                     if(useHalfSpace && UbMath::less(distance, 0.0) )//== !halfSpace.ptInside(internX1,internX2,internX3) )
+                     {
+                        counterHalfspace++;
+                        continue;
+                     }
+
+                     //BilligOBB-Test: wenn distance > qEinflussDelta -> kein q
+                     if( UbMath::greater( fabs(distance), qEinflussDelta ) )
+                     {
+                        counterBilligOBB++;
+                        continue;
+                     }
+
+                     /////////////////////////////////////////////////////////////////////////////
+                     //Raytracingfür diskrete Boltzmannrichtungen
+                     /////////////////////////////////////////////////////////////////////////////
+                     gotQs = false;
+                     bc    = BoundaryConditionsPtr();
+
+                     //RAYTRACING - diskrete LB-dir zu Dreick
+                     //e1 = v1 - v0
+                     e1x1 = v2.x-v1.x;
+                     e1x2 = v2.y-v1.y;
+                     e1x3 = v2.z-v1.z;
+
+                     //e2 = v2 - v0
+                     e2x1 = v3.x-v1.x;
+                     e2x2 = v3.y-v1.y;
+                     e2x3 = v3.z-v1.z;
+
+                     //s = o - v0
+                     sx1 = internX1 - v1.x;
+                     sx2 = internX2 - v1.y;
+                     sx3 = internX3 - v1.z;
+
+                     for(int fdir=D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
+                     {
+                        //p = d x e2
+                        px1 = this->rayX2[fdir]*e2x3 - this->rayX3[fdir]*e2x2;
+                        px2 = this->rayX3[fdir]*e2x1 - this->rayX1[fdir]*e2x3;
+                        px3 = this->rayX1[fdir]*e2x2 - this->rayX2[fdir]*e2x1;
+
+                        //a = e1 dot p
+                        a = e1x1*px1 + e1x2*px2 + e1x3*px3;
+                        if(fabs(a)<1.E-10) continue;
+                        f = 1.0/a;
+
+                        //u = f * ( s dot p)
+                        u = f * ( sx1*px1 + sx2*px2 + sx3*px3 );
+                        if(u<-1.E-10 || u>1.0+1.E-10) continue;
+
+                        //q = s x e1
+                        qx1 = sx2*e1x3 - sx3*e1x2;
+                        qx2 = sx3*e1x1 - sx1*e1x3;
+                        qx3 = sx1*e1x2 - sx2*e1x1;
+
+                        //v = f*(e2 dot q)
+                        v = f * (this->rayX1[fdir]*qx1 + this->rayX2[fdir]*qx2 + this->rayX3[fdir]*qx3);
+                        if(v<-1.E-10 || (u+v)>1.0+1.E-10) continue;
+
+                        //t = f * (e2 dot q)
+                        q = f * (e2x1*qx1 + e2x2*qx2 + e2x3*qx3);
+                        q /= nodeDeltaToNeigh[level][fdir];
+
+                        //gefundenes q auf gueltigkeit pruefen
+                        if( UbMath::zero(q) )
+                        {
+                           //neu (18.05.2010)
+                           //es kann vorkommen, dass bei dünnwandigen geos punkte, die auf einem dreieck liegen, qs bekommen, die durch die geo
+                           //durchgehen. diese punkte werden später jedoch nicht mehr auf solid getestet, da sie ja ne BC bekommen haben
+                           //--> da mind ein q==0.0 für eines der dreiecke -> dort solid setzen
+                           this->solidNodeIndicesMap[block].insert( UbTupleInt3(ix1,ix2,ix3) );
+                           bcMatrix->setSolid( ix1, ix2, ix3 );
+                           continue;
+                        }
+
+                        if( UbMath::inClosedInterval(q, 1.0, 1.0) ) q = 1.0;
+                        if( UbMath::greater(q, 0.0) && UbMath::lessEqual(q, 1.0) )
+                        {
+                           //if( !solidFromOtherInteractor ) //--> Knoten schon solid-->BC setzen ueberfluessig 
+                           //SG changed to
+                           //if( solidFromOtherInteractor ) //--> Knoten schon solid-->BC setzen ueberfluessig 
+                           {
+                              //SG 26.08.2010 muss bereits hierhin, da das continue sonst den Knoten nicht als transNode fürs
+                              //markiert
+                              gotQs=blockGotBCs=true;
+
+                              bc = bcMatrix->getBC(ix1,ix2,ix3);
+
+                              //SG 26.08.2010 if(!bc && !bcMatrix->isSolid())
+                              if(!bc)
+                              {
+                                 bc = BoundaryConditionsPtr(new BoundaryConditions);;
+                                 bcMatrix->setBC(ix1,ix2,ix3,bc);
+                              }
+                              else if( UbMath::less( bc->getQ(fdir), q ) )  //schon ein kuerzeres q voehanden?
+                              {
+                                 //neu:: 18.05.2010
+                                 //um falsche qs die evtl durch die "wand" gehen zu vermeiden 
+                                 //q nur dann neu setzen, wenn neues q kleiner als vorhandenes!
+                                 //Zudem: insbesondere an ecken mit zwei BC geos ist nur das 
+                                 //naehere gueltig
+                                 continue;
+                              }
+
+                              bc->setBoundaryVelocityX1(vx1);
+                              bc->setBoundaryVelocityX2(vx2);
+                              bc->setBoundaryVelocityX3(vx3);
+
+                              for(int index=(int)this->bcAdapters.size()-1; index>=0; --index)
+                                 this->bcAdapters[index]->adaptBCForDirection(*this,bc,internX1,internX2,internX3,q,fdir);
+
+                              //SG 26.08.2010 gotQs=blockGotBCs=true;
+                           }
+                           //fuer beschleunigtes wiedereinlesen
+                           if(this->reinitWithStoredQsFlag)
+                           {
+                              bcNodeIndicesAndQsMap[block][ UbTupleInt3(ix1, ix2, ix3) ].resize(D3Q27System::FENDDIR+1+3, -1.0f);
+                              bcNodeIndicesAndQsMap[block][ UbTupleInt3(ix1, ix2, ix3) ][fdir                    ] = float(q);
+                              bcNodeIndicesAndQsMap[block][ UbTupleInt3(ix1, ix2, ix3) ][D3Q27System::FENDDIR+1+0] = float(internX1);
+                              bcNodeIndicesAndQsMap[block][ UbTupleInt3(ix1, ix2, ix3) ][D3Q27System::FENDDIR+1+1] = float(internX2);
+                              bcNodeIndicesAndQsMap[block][ UbTupleInt3(ix1, ix2, ix3) ][D3Q27System::FENDDIR+1+2] = float(internX3);
+                           }
+                        }
+                     }
+
+                     if(gotQs)
+                     {
+                        std::vector<int> p(3);
+                        p[0]=ix1; p[1]=ix2; p[2]=ix3;
+                        bcNodeIndices.insert(p);
+
+                        for(int index=(int)this->bcAdapters.size()-1; index>=0; --index)
+                           this->bcAdapters[index]->adaptBC(*this,bc,internX1,internX2,internX3);
+                     }
+                  }
+               }
+            }
+            //Block wird für scanline-check "anmelden", dieser wird dann spaeter zu "transBlocks" hinzugefuegt
+            if(blockGotBCs)
+            {
+               blocksForSolidCheck[block] = ScanLine;
+            }
+            //            bvd->getTimer().stop();
+         }
+         //dynamische Punkte des GbCuboids muessen leider per "Hand" geloescht werden :-(
+         boundingCubeTriangle.finalize();
+      }
+   }
+   setQTimer.stop();
+
+   UBLOG(logDEBUG1," - setQs for "/*<< this->getName()*/ << " - " <<(int)triangles.size()<<" triangles: 100% done in "<<setQTimer.getTotalTime()<<"sec");
+   UBLOG(logDEBUG1,"       * rejected blocks with tribox overlap test : " << counterTriBoxOverlap);
+   UBLOG(logDEBUG1,"       * rejected nodes  with AABB           test : " << counterAABBTriFace);
+   UBLOG(logDEBUG1,"       * rejected nodes  with halfspace      test : " << counterHalfspace);
+   UBLOG(logDEBUG1,"       * rejected nodes  with OBB            test : " << counterBilligOBB);
+
+   typedef std::map<Block3DPtr,SolidCheckMethod>::iterator BlockSolidCheckMethodIterator;
+
+   //////////////////////////////////////////////////////////////////////////
+   // SOLID checks
+   //////////////////////////////////////////////////////////////////////////
+   if( regardPIOTest )
+   {
+      int pointInObjectCounter = 0;
+      int scanlineCounter      = 0;
+      int counter              = 0;
+
+      //sollte die matrix groesse zu gross sein und der rekursive floodFill mehr speicher
+      //benoetigen als der Stack hergibt -> keinen floodFill verwenden!
+      void (D3Q27TriFaceMeshInteractor::*gridFill)(CbArray3D<FLAGS>&, const short&, const short&, const short&, const FLAGS&) = NULL;
+      /*if(blocknx1*blocknx2*blocknx3 < 200000 ) gridFill = &D3Q27TriFaceMeshInteractor::recursiveGridFill;*/
+      /*else */                                    gridFill = &D3Q27TriFaceMeshInteractor::iterativeGridFill; 
+
+      UBLOG(logDEBUG1," - setSolids for "<< blocksForSolidCheck.size() << " blocks");
+
+      UbTimer scanLineTimer;
+      UbTimer solidTimer; 
+      solidTimer.start();
+
+      for(BlockSolidCheckMethodIterator pos=blocksForSolidCheck.begin(); pos!=blocksForSolidCheck.end(); ++pos)
+      {
+         Block3DPtr const& block = pos->first;
+         int level = block->getLevel();
+
+         UbTupleDouble3 coords = grid.lock()->getBlockWorldCoordinates(block);
+
+         //Bloecke, die keinerlei Verschneidung mit Dreicken bzw. deren BoundCubes hatten
+         //hier: durch inside/outside Tests EINES knotens gilt fuer ALLE Knoten des blockes
+         if( pos->second == PointInObject ) 
+         {
+            pointInObjectCounter++;
+            if(mesh->isPointInGbObject3D(val<1>(coords),val<2>(coords),val<3>(coords)) )
+            {
+               //block->setActive(false);
+               //this->solidBlocks.push_back(block);
+            }
+         }
+         //Bloecke, die Verschneidung mit Dreicken bzw. deren BoundCubes hatten
+         //scanline algortihmus. dieser berücksichtigt durch weitere tests, dass innerhalb evtl schon andere
+         //geos bcs gesetzt haben. es werden ausschließelich solids gesetzt (also keine FLUIDS oder neuen BCs)
+         else if( pos->second == ScanLine ) 
+         {
+            scanlineCounter++;
+            scanLineTimer.start();
+
+            ILBMKernelPtr kernel = block->getKernel();
+            if(!kernel) throw UbException(UB_EXARGS,"na sowas kein kernel bzw. kernel=NULL (2)");
+            BCArray3DPtr bcMatrix = kernel->getBCProcessor()->getBCArray();
+
+            //            bvd->getTimer().start();
+            int indexMinX1 = 0;
+            int indexMinX2 = 0;
+            int indexMinX3 = 0;
+            int indexMaxX1 = (int)bcMatrix->getNX1();
+            int indexMaxX2 = (int)bcMatrix->getNX2();
+            int indexMaxX3 = (int)bcMatrix->getNX3();
+
+            //quick and dirty
+            blocknx1 = indexMaxX1;
+            blocknx2 = indexMaxX2;
+            blocknx3 = indexMaxX3;
+
+            std::set< UbTupleInt3 >& solidNodeIndices = this->solidNodeIndicesMap[block];
+
+            float nodeDeltaX1 = (float)nodeDeltaToNeigh[level][D3Q27System::E];
+            float nodeDeltaX2 = (float)nodeDeltaToNeigh[level][D3Q27System::N];
+            float nodeDeltaX3 = (float)nodeDeltaToNeigh[level][D3Q27System::T];
+
+            //flagfield matrix initialisieren
+            CbArray3D<FLAGS> flagField(blocknx1,blocknx2,blocknx3,UNDEF_FLAG);
+
+            //hier gesetzte bcs markieren
+            std::set< std::vector<int> >& transNodeIndices = this->bcNodeIndicesMap[block];
+            std::set< std::vector<int> >::iterator setPos;
+            for(setPos=transNodeIndices.begin(); setPos!=transNodeIndices.end();  ++setPos)
+               flagField( (*setPos)[0], (*setPos)[1], (*setPos)[2] ) = BC_FLAG;
+
+            //solids die bereits durch andere interaktoren gesetzt wurden (wurden oben gespeichert)
+            //ist EMPTY bei reinitWithStoredQsFlag == true
+            //SG 28.08.2010            std::set< UbTupleInt3 >& tmpSolidNodeIndices = tmpSolidNodesFromOtherInteractors[block];
+            //SG 28.08.2010  if(reinitWithStoredQsFlag && !tmpSolidNodeIndices.empty() ) throw UbException(UB_EXARGS, "tmpSolidNodeIndices darf bei reinitWithStoredQsFlag==true keine Knoten enthalten");
+            //SG 28.08.2010            for(setPos=tmpSolidNodeIndices.begin(); setPos!=tmpSolidNodeIndices.end();  ++setPos)
+            //SG 28.08.2010               flagField( val<1>(*setPos), val<2>(*setPos), val<3>(*setPos) ) = OLDSOLID_FLAG;
+
+            //flagfield matrix belegen
+            for(int bx3=0; bx3<blocknx3; ++bx3)
+            {
+               for(int bx2=0; bx2<blocknx2; ++bx2)
+               {
+                  for(int bx1=0; bx1<blocknx1; ++bx1)
+                  {
+                     
+					  if (bx2==9&&bx3==29)
+					  {
+						  int ride=0;
+					  }
+					  if( flagField(bx1,bx2,bx3)==UNDEF_FLAG )
+                     { 
+						 if( mesh->isPointInGbObject3D(  val<1>(coords) + bx1*nodeDeltaX1 - 0.5*nodeDeltaX1 
+                           , val<2>(coords) + bx2*nodeDeltaX2 - 0.5*nodeDeltaX2
+                           , val<3>(coords) + bx3*nodeDeltaX3 - 0.5*nodeDeltaX3) )
+                        {
+                           (this->*gridFill)(flagField,bx1,bx2,bx3,SOLID_FLAG);
+                        }
+                        else
+                        {
+                           (this->*gridFill)(flagField,bx1,bx2,bx3,FLUID_FLAG);
+                        }
+                     }
+
+                     if( flagField(bx1,bx2,bx3)==SOLID_FLAG )
+                     {
+                        //hier ist noch das Problem, das "alle" solid in die solidNodeIndices kommen
+                        //evtl. Abhilfe durch einführen eines anderen Flags bei tmpSolidNodeIndices ..
+                        solidNodeIndices.insert(UbTupleInt3(bx1,bx2,bx3));
+                        bcMatrix->setSolid(bx1,bx2,bx3);
+                     }
+                     //SG 28.08.2010  else if( flagField(bx1,bx2,bx3)==OLDSOLID_FLAG )
+                     //SG 28.08.2010  {
+                     //SG 28.08.2010     bcMatrix->setSolid(bx1,bx2,bx3);
+                     //SG 28.08.2010  }
+                  }
+               }
+            }
+
+            //SG 28.08.2010 halt danach setzen, damit die BCs die fälschlicherweise gesetzt wurden korrigiert werden
+            std::set< std::vector<int> >& tmpSolidNodeIndices = tmpSolidNodesFromOtherInteractors[block];
+            for(setPos=tmpSolidNodeIndices.begin(); setPos!=tmpSolidNodeIndices.end();  ++setPos)
+               bcMatrix->setSolid((*setPos)[0], (*setPos)[1], (*setPos)[2] );
+
+            //block hat  in initInteractor mind eine BC erhalten -> transBlock
+            this->bcBlocks.push_back(block);
+            scanLineTimer.stop();
+
+            //            bvd->getTimer().stop();
+         }
+         else throw UbException(UB_EXARGS,"unknown option for in object test");
+      }
+
+      solidTimer.stop();
+
+      UBLOG(logDEBUG1, " - setSolids for "<<blocksForSolidCheck.size()<<" blocks: 100% done in "<<solidTimer.getTotalTime()<<"s");
+      UBLOG(logDEBUG1, "       * pointInObject for "<<pointInObjectCounter<<" blocks in "<<solidTimer.getTotalTime()-scanLineTimer.getTotalTime()<<"s");
+      UBLOG(logDEBUG1, "       * flood fill    for "<<scanlineCounter     <<" blocks in "<<scanLineTimer.getTotalTime()<<" secs");
+      UBLOG(logDEBUG1, "LBMTriFaceMeshInteractor::initInteractor for \""<<mesh->getName()<<"\" done in "<<setQTimer.getTotalTime()+solidTimer.getTotalTime()<<"s");
+   }
+
+   //calcForces arbeitet nicht korrekt, wenn Geo mit Bloecken 
+   //unterschiedlicher Leveltiefe diskretisiert -> exception
+   //abfrage steht hier, weil es theoretisch sein kann, dass bei parallelen rechnungen
+   //genau der block mit dem anderen level auf einem anderen prozess liegt...
+   //Update: es kann u.U. passieren, dass Blöcke in der Liste nicht aktiv sin
+   //(falls diese z.B. duch andere Interactoren solid gesetzt wurden)
+   //diese werden nicht berücksichtigt (auch nicht beid er kraftauswertung später)
+   //if( this->isRelevantForForces() )
+   //{
+   //   int level = -1;     
+   //   for( std::vector<Block3DPtr>::const_iterator pos = this->transBlocks.begin(); pos!=this->transBlocks.end(); ++pos)
+   //      if( (*pos)->isActive() )
+   //      {
+   //         level = (*pos)->getLevel();
+   //         break;
+   //      }
+
+   //      bool check = false;
+   //      for( std::vector<Block3DPtr>::const_iterator pos = this->transBlocks.begin(); pos!=this->transBlocks.end(); ++pos)
+   //         if( (*pos)->isActive() && (*pos)->getLevel()!=level)
+   //         {
+   //            (*pos)->setRank(1000);
+   //            check = true;
+   //            UbTupleDouble3 coords = grid.lock()->getBlockWorldCoordinates((*pos));
+   //            std::cout<<(*pos)->getLevel()<<","<<(*pos)->getX1()<<","<<(*pos)->getX2()<<","<<(*pos)->getX3()<<std::endl;
+   //            std::cout<<std::setprecision(15)<<val<1>(coords)<<","<<val<2>(coords)<<","<<val<3>(coords)<<std::endl<<std::endl;
+
+   //         }
+   //         if(check)
+   //         {
+   //            //this->grid.lock()->writeBlocks(UbStaticPathMap::getPath(UbStaticPathMap::GLOBAL)+"/error_grid",0, WbWriterVtkXmlASCII::getInstance(), false);
+
+   //            throw UbException(UB_EXARGS,"interactor is relevant for forces,"
+   //               +(std::string)" but has transblocks with different levels (wrote error_grid)"
+   //               +(std::string)" -> not supportet by LBMInteractor::getForces()"
+   //               +(std::string)" -> increase refineWidth");
+
+   //         }
+   //}
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27TriFaceMeshInteractor::refineBlockGridToLevel(int level, double startDistance, double stopDistance)
+{
+   UBLOG(logDEBUG1, "D3Q27TriFaceMeshInteractor::refineBlockGridToLevel - start");
+
+   //ToDo: evtl checken, ob man noch einen HalbraumCheck für StopDistance einbaut
+   //      oder ob man schneller ist, wenn man gar keinen halbraum test macht...
+   if(!grid.lock())
+      throw UbException(UB_EXARGS,"Grid isn't exist!");
+   if( UbMath::greater(startDistance,0.0) )
+      throw UbException(UB_EXARGS,"startDistance>0.0 not supported by this interactor");
+   if( UbMath::less(stopDistance,0.0) )
+      throw UbException(UB_EXARGS,"stopDistance<0.0  not supported by this interactor");
+
+   Grid3DPtr  bgrid = this->grid.lock();
+   GbTriFaceMesh3D& mesh  = dynamic_cast<GbTriFaceMesh3D&>(*this->geoObject3D.get());
+
+   int coarsestLevel = bgrid->getCoarsestInitializedLevel();
+
+   std::vector<GbTriFaceMesh3D::TriFace>& triangles = *mesh.getTriangles();
+   std::vector<GbTriFaceMesh3D::Vertex>&  nodes     = *mesh.getNodes();
+
+   double minX1,minX2,minX3,maxX1,maxX2,maxX3;
+   float blockMinX[3],blockMaxX[3],boxCenter[3],halfBoxSize[3];
+   float triPoints[3][3];
+
+   size_t nofTriangles = (int)triangles.size();
+
+//#pragma omp parallel
+//#pragma omp for
+   for(size_t i=0; i<nofTriangles; i++)
+   //for(int i=0; i<nofTriangles; i++)
+   {
+//#pragma omp master  
+      //{
+      //    printf_s("num_threads=%d\n", omp_get_num_threads( ));
+      //}
+     
+
+      GbTriFaceMesh3D::TriFace& triangle = triangles[i];
+
+      GbTriFaceMesh3D::Vertex& v1 = nodes[triangle.v1];
+      GbTriFaceMesh3D::Vertex& v2 = nodes[triangle.v2];
+      GbTriFaceMesh3D::Vertex& v3 = nodes[triangle.v3];
+
+      //dreick muss normal besitzen!
+      assert( !UbMath::zero(triangle.nx) || !UbMath::zero(triangle.ny) || !UbMath::zero(triangle.nz) );
+      //Normale muss normiert sein!
+      assert( (fabs(std::sqrt( triangle.nx*triangle.nx + triangle.ny*triangle.ny + triangle.nz*triangle.nz ))-1.0f)<1.0E-6);
+
+      //Halfspace um  startDistance entgegen normale verscheiebn, ansonsten werden spaeter
+      //zu testende bloecke auf der dreicksrueckseite nicht getestet!!!
+      GbHalfSpace3D halfSpace(  v1.x+startDistance*triangle.nx, v1.y+startDistance*triangle.ny, v1.z+startDistance*triangle.nz
+         , v2.x+startDistance*triangle.nx, v2.y+startDistance*triangle.ny, v2.z+startDistance*triangle.nz
+         , v3.x+startDistance*triangle.nx, v3.y+startDistance*triangle.ny, v3.z+startDistance*triangle.nz );
+
+      //Boundingbox um massgebliches dx erweitern -> zur Bestimmung der zu testenden Bloecke
+      if( triangle.nx>1.0E-8 ) { minX1 = triangle.getMinX(nodes)+1.05*triangle.nx*startDistance; 
+      maxX1 = triangle.getMaxX(nodes)+1.05*triangle.nx*stopDistance;  }     
+      else                     { minX1 = triangle.getMinX(nodes)+1.05*triangle.nx*stopDistance;  
+      maxX1 = triangle.getMaxX(nodes)+1.05*triangle.nx*startDistance; }     
+
+      if( triangle.ny>1.0E-8 ) { minX2 = triangle.getMinY(nodes)+1.05*triangle.ny*startDistance;
+      maxX2 = triangle.getMaxY(nodes)+1.05*triangle.ny*stopDistance;  }     
+      else                     { minX2 = triangle.getMinY(nodes)+1.05*triangle.ny*stopDistance; 
+      maxX2 = triangle.getMaxY(nodes)+1.05*triangle.ny*startDistance; }     
+
+      if( triangle.nz>1.0E-8 ) { minX3 = triangle.getMinZ(nodes)+1.05*triangle.nz*startDistance;
+      maxX3 = triangle.getMaxZ(nodes)+1.05*triangle.nz*stopDistance;  }     
+      else                     { minX3 = triangle.getMinZ(nodes)+1.05*triangle.nz*stopDistance; 
+      maxX3 = triangle.getMaxZ(nodes)+1.05*triangle.nz*startDistance; }     
+
+
+      int flag = 0;
+      //Levelweise alle Bloecke holen, die erweiterte BB schneiden 
+      //und bearbeiten
+      for(int l=coarsestLevel; l<level; l++)
+      {
+         std::vector<Block3DPtr> consideredBlocks;
+         bgrid->getBlocksByCuboid(l,minX1, minX2, minX3, maxX1, maxX2, maxX3, consideredBlocks);
+         double x1a,x2a,x3a,x1b,x2b,x3b;
+
+         for(size_t b=0; b<consideredBlocks.size(); b++)
+         {
+            Block3DPtr block = consideredBlocks[b];
+            if(block->getLevel()>=level) continue;
+
+            //start coordinaten des blocks ermitteln
+            UbTupleDouble3 coords = bgrid->getBlockWorldCoordinates(block);
+            UbTupleDouble3 deltas = bgrid->getBlockLengths(block);
+
+            //Check, ob block komplett im Halbraum
+            x1a = val<1>(coords);   x1b = val<1>(coords)+val<1>(deltas);
+            x2a = val<2>(coords);   x2b = val<2>(coords)+val<2>(deltas);
+            x3a = val<3>(coords);   x3b = val<3>(coords)+val<3>(deltas);
+
+            flag = 0;
+            if( !halfSpace.ptInside(x1a,x2a,x3a) )  flag |= (1<<0); //1
+            if( !halfSpace.ptInside(x1b,x2a,x3a) )  flag |= (1<<1); //2
+            if( !halfSpace.ptInside(x1b,x2b,x3a) )  flag |= (1<<2); //4
+            if( !halfSpace.ptInside(x1a,x2b,x3a) )  flag |= (1<<3); //8
+            if( !halfSpace.ptInside(x1a,x2a,x3b) )  flag |= (1<<4); //16
+            if( !halfSpace.ptInside(x1b,x2a,x3b) )  flag |= (1<<5); //32
+            if( !halfSpace.ptInside(x1b,x2b,x3b) )  flag |= (1<<6); //64
+            if( !halfSpace.ptInside(x1a,x2b,x3b) )  flag |= (1<<7); //128
+
+
+            if( true && flag!=255 )
+            {
+               //blockseite ermitteln (skalarprodukt dreiecks-normale, vector (midTri->midCub) )
+               //je nachdem muss für den massgeblichen block start oder stopdistance verwendet werden
+               //liegt block auf pos seite -> stopdistance ansonsten startdistance
+               double skalarprod =   triangle.nx * ( 0.5*(x1a+x1b)-triangle.getX1Centroid(nodes) )
+                  + triangle.ny * ( 0.5*(x2a+x2b)-triangle.getX2Centroid(nodes) )
+                  + triangle.nz * ( 0.5*(x3a+x3b)-triangle.getX3Centroid(nodes) );
+
+               double blockdelta  = 1.05*stopDistance;
+               if     (skalarprod<1.E-8       ) blockdelta = -1.05*startDistance;  //startDistance<0!!
+               else if( fabs(skalarprod)<1.E-8) blockdelta =  1.05*UbMath::max(-startDistance,stopDistance);
+
+               //block anpassen
+               blockMinX[0]   = (float)(val<1>(coords)-blockdelta );
+               blockMinX[1]   = (float)(val<2>(coords)-blockdelta );
+               blockMinX[2]   = (float)(val<3>(coords)-blockdelta );
+
+               blockMaxX[0]   = (float)(val<1>(coords)+val<1>(deltas)+blockdelta );
+               blockMaxX[1]   = (float)(val<2>(coords)+val<2>(deltas)+blockdelta );
+               blockMaxX[2]   = (float)(val<3>(coords)+val<3>(deltas)+blockdelta );
+
+               boxCenter[0]   = (float)(0.5*(blockMaxX[0]+blockMinX[0]));
+               boxCenter[1]   = (float)(0.5*(blockMaxX[1]+blockMinX[1]));
+               boxCenter[2]   = (float)(0.5*(blockMaxX[2]+blockMinX[2]));
+
+               halfBoxSize[0] = (float)(0.5*(blockMaxX[0]-blockMinX[0]));
+               halfBoxSize[1] = (float)(0.5*(blockMaxX[1]-blockMinX[1]));
+               halfBoxSize[2] = (float)(0.5*(blockMaxX[2]-blockMinX[2]));
+
+               GbTriFaceMesh3D::Vertex& v1 = nodes[triangle.v1];
+               GbTriFaceMesh3D::Vertex& v2 = nodes[triangle.v2];
+               GbTriFaceMesh3D::Vertex& v3 = nodes[triangle.v3];
+
+               triPoints[0][0] = v1.x; triPoints[0][1] = v1.y; triPoints[0][2] = v1.z; 
+               triPoints[1][0] = v2.x; triPoints[1][1] = v2.y; triPoints[1][2] = v2.z; 
+               triPoints[2][0] = v3.x; triPoints[2][1] = v3.y; triPoints[2][2] = v3.z; 
+
+               //wenn block dreick schneidet, dann muss er verfeinert werden
+               if( GbMeshTools3D::triBoxOverlap(boxCenter,halfBoxSize,triPoints) )
+               {
+                  bgrid->expandBlock(block->getX1(), block->getX2(),block->getX3(),block->getLevel());
+               }
+            }
+         }
+      }
+   }
+   UBLOG(logDEBUG1, " - refine done");
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27TriFaceMeshInteractor::updateMovedGeometry(const double& timeStep)
+{
+
+}
+////////////////////////////////////////////////////////////////////////////
+void D3Q27TriFaceMeshInteractor::recursiveGridFill(CbArray3D<FLAGS>& flagfield, const short& xs, const short& ys, const short& zs, const FLAGS& type)
+{
+   // Algorithmus zum Füllen eines Polyeders, ausgehend vom Saatpunkt xs,ys,zs
+
+   //Saatknoten einfärben
+   if( flagfield(xs,ys,zs)==UNDEF_FLAG )
+   {
+      flagfield(xs,ys,zs) = type;
+
+      if ( flagfield.indicesInRange( xs+1, ys  , zs   ) ) this->recursiveGridFill(flagfield,xs+1, ys  , zs  ,type);
+      if ( flagfield.indicesInRange( xs  , ys+1, zs   ) ) this->recursiveGridFill(flagfield,xs  , ys+1, zs  ,type);
+      if ( flagfield.indicesInRange( xs  , ys  , zs+1 ) ) this->recursiveGridFill(flagfield,xs  , ys  , zs+1,type);
+      if ( flagfield.indicesInRange( xs-1, ys  , zs   ) ) this->recursiveGridFill(flagfield,xs-1, ys  , zs  ,type);
+      if ( flagfield.indicesInRange( xs  , ys-1, zs   ) ) this->recursiveGridFill(flagfield,xs  , ys-1, zs  ,type);
+      if ( flagfield.indicesInRange( xs  , ys  , zs-1 ) ) this->recursiveGridFill(flagfield,xs  , ys  , zs-1,type);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27TriFaceMeshInteractor::iterativeGridFill(CbArray3D<FLAGS>& flagfield, const short& xs, const short& ys, const short& zs, const FLAGS& type)
+{
+   std::stack< UbTupleInt3 > stck;
+   stck.push( UbTupleInt3(xs,ys,zs) );
+
+   int x,y,z;
+
+   while( !stck.empty() )  
+   {
+      x = val<1>( stck.top() );
+      y = val<2>( stck.top() );
+      z = val<3>( stck.top() );
+      stck.pop();
+
+      FLAGS& flagType = flagfield( x, y, z );
+
+      if( flagType == UNDEF_FLAG ) 
+      {     
+         flagType = type;
+
+         if ( flagfield.indicesInRange( x+1, y  , z   ) ) stck.push( UbTupleInt3( x+1, y  , z   ) );
+         if ( flagfield.indicesInRange( x  , y+1, z   ) ) stck.push( UbTupleInt3( x  , y+1, z   ) );
+         if ( flagfield.indicesInRange( x  , y  , z+1 ) ) stck.push( UbTupleInt3( x  , y  , z+1 ) );
+         if ( flagfield.indicesInRange( x-1, y  , z   ) ) stck.push( UbTupleInt3( x-1, y  , z   ) );
+         if ( flagfield.indicesInRange( x  , y-1, z   ) ) stck.push( UbTupleInt3( x  , y-1, z   ) );
+         if ( flagfield.indicesInRange( x  , y  , z-1 ) ) stck.push( UbTupleInt3( x  , y  , z-1 ) );
+      }
+   }
+   return;
+}
+//////////////////////////////////////////////////////////////////////////
+UbTupleDouble3 D3Q27TriFaceMeshInteractor::getForces()
+{
+   //FeTriFaceMesh3D* feMesh = dynamic_cast<FeTriFaceMesh3D*>(this->geoObject3D.get());
+   //if(!feMesh)
+   //{
+   //   return D3Q19AMRInteractor::getForces();
+   //}
+   ////return getForcesTriangle();
+   //this->calculateForces();
+
+   double forceX1=0.0;
+   double forceX2=0.0;
+   double forceX3=0.0;
+
+   //double area = 0.0;
+
+   //vector<FeTriFaceMesh3D::VertexAttributes>* attributes = feMesh->getAttributes();
+
+   //for(size_t i=0; i<attributes->size(); i++)
+   //{
+   //   FeTriFaceMesh3D::VertexAttributes& attribut = (*attributes)[i];
+   //   area = attribut.getArea();
+   //   forceX1 += attribut.getFX()*area;
+   //   forceX2 += attribut.getFY()*area;
+   //   forceX3 += attribut.getFZ()*area;
+   //}
+   return UbTupleDouble3(forceX1,forceX2,forceX3);
+}
+//////////////////////////////////////////////////////////////////////////
+UbTupleDouble3 D3Q27TriFaceMeshInteractor::getForcesTriangle()
+{
+   double forceX1=0.0;
+   double forceX2=0.0;
+   double forceX3=0.0;
+
+   //D3Q19BlockGrid& grid.lock() = dynamic_cast<D3Q19BlockGrid&>(*this->grid.lock());
+   ////   CoordinateTransformation3D *trafo = this->grid.lock()->getTransformation();
+   ////   int minLevel = this->grid.lock()->getFinestInitializedLevel();
+   ////    double scaleX = trafo->getX1CoordinateScaling()/(1<<minLevel);
+   ////    double scaleY = trafo->getX2CoordinateScaling()/(1<<minLevel);
+   ////    double scaleZ = trafo->getX3CoordinateScaling()/(1<<minLevel);
+   ////    int blocknx1 = grid.lock()->getBlockNX1();
+   ////    int blocknx2 = grid.lock()->getBlockNX2();
+   ////    int blocknx3 = grid.lock()->getBlockNX3();
+   ////    double xOffset = trafo->getX1CoordinateOffset();
+   ////    double yOffset = trafo->getX2CoordinateOffset();
+   ////    double zOffset = trafo->getX3CoordinateOffset();
+   //vector<D3Q19Real> collFactors = ((D3Q19Calculator*)grid.lock()->getCalculator())->getCollisionsFactors();
+
+   ////for (int i=0;i<(int)gbTriangle3DInteractors.size(); i++)
+   ////{
+   ////   GbTriangle3D* tri = (GbTriangle3D*)gbTriangle3DInteractors[i]->getGbObject3D();
+
+   ////   double px0 = tri->getX1Centroid();
+   ////   double py0 = tri->getX2Centroid();
+   ////   double pz0 = tri->getX3Centroid();
+   ////   double px = px0-xOffset;
+   ////   double py = py0-yOffset;
+   ////   double pz = pz0-zOffset;
+   ////   px = px/scaleX;
+   ////   py = py/scaleY;
+   ////   pz = pz/scaleZ;
+   ////   int x1 = (int)px;
+   ////   int y1 = (int)py;
+   ////   int z1 = (int)pz;
+   ////   AMR3DBlock* block = this->grid.lock()->getBlock(x1,y1,z1,minLevel);
+   ////   if(!block)  block = this->grid.lock()->getSuperBlock(x1,y1,z1,minLevel);
+   ////   if(!block) throw UbException(__FILE__,__LINE__,"kein Block ...");
+
+   ////   double collFactor = collFactors[block->getLevel()];
+   ////   double nodeDistance = grid.lock()->getNodeDeltaX(block->getLevel());
+   ////   double bertX1 = ((px0-xOffset)/(1000.*nodeDistance));
+   ////   double bertX2 = ((py0-yOffset)/(1000.*nodeDistance));
+   ////   double bertX3 = ((pz0-zOffset)/(1000.*nodeDistance));
+   ////   int abstaendeX1 = (int)(bertX1*1000.);
+   ////   int abstaendeX2 = (int)(bertX2*1000.);
+   ////   int abstaendeX3 = (int)(bertX3*1000.);
+   ////   int posW = abstaendeX1 - block->getX1Index()*blocknx1;
+   ////   int posS = abstaendeX2 - block->getX2Index()*blocknx2;
+   ////   int posB = abstaendeX3 - block->getX3Index()*blocknx3;
+   ////   int posE=posW+1;
+   ////   int posN=posS+1;
+   ////   int posT=posB+1;
+
+   ////   D3Q19BlockDescriptor *bvd = dynamic_cast<D3Q19BlockDescriptor*>(block->getBlockDescriptor());
+   ////   if(!bvd) throw UbException(__FILE__,__LINE__,"kein Bvd ...");
+
+   ////   CbUniformMatrix4D<double,IndexerX1X2X3X4>* tempdistributions = bvd->getTempDistributionMatrix();
+   ////   D3Q19BCMatrix<D3Q19BoundaryCondition> *bcMatrix = bvd->getBcMatrix();
+
+   ////   UbTupleDouble6 stresses;
+   ////   double dX = px0-this->geoObject3D->getX1Centroid();
+   ////   double dY = py0-this->geoObject3D->getX2Centroid();
+   ////   double dZ = pz0-this->geoObject3D->getX3Centroid();
+   ////   if(dX<=0.0 && dY<=0.0 && dZ<=0.0)
+   ////   {
+   ////      double *fWSB  = tempdistributions->getStartAdressOfSortedArray(posW,posS,posB,0);
+   ////      if(bcMatrix->isFluid(posW,posS,posB)) stresses = D3Q19System::getIncompStresses(fWSB, collFactor );
+   ////      else cout<<__LINE__<<" nicht fluid ...";
+   ////   }
+   ////   else if(dX<=0.0 && dY>0.0 && dZ<=0.0)
+   ////   {
+   ////      double *fWNB  = tempdistributions->getStartAdressOfSortedArray(posW,posN,posB,0);
+   ////      if(bcMatrix->isFluid(posW,posN,posB)) stresses = D3Q19System::getIncompStresses(fWNB, collFactor );
+   ////      else cout<<__LINE__<<" nicht fluid ...";
+   ////   }
+   ////   else if(dX<=0.0 && dY<=0.0 && dZ>0.0)
+   ////   {
+   ////      double *fWST  = tempdistributions->getStartAdressOfSortedArray(posW,posS,posT,0);
+   ////      if(bcMatrix->isFluid(posW,posS,posT)) stresses = D3Q19System::getIncompStresses(fWST, collFactor );
+   ////      else cout<<__LINE__<<" nicht fluid ...";
+   ////   }
+   ////   else if(dX<=0.0 && dY>0.0 && dZ>0.0)
+   ////   {
+   ////      double *fWNT  = tempdistributions->getStartAdressOfSortedArray(posW,posN,posT,0);
+   ////      if(bcMatrix->isFluid(posW,posN,posT)) stresses = D3Q19System::getIncompStresses(fWNT, collFactor );
+   ////      else cout<<__LINE__<<" nicht fluid ...";
+   ////   }
+   ////   else if(dX>0.0 && dY<=0.0 && dZ<=0.0)
+   ////   {
+   ////      double *fESB  = tempdistributions->getStartAdressOfSortedArray(posE,posS,posB,0);
+   ////      if(bcMatrix->isFluid(posE,posS,posB)) stresses = D3Q19System::getIncompStresses(fESB, collFactor );
+   ////      else cout<<__LINE__<<" nicht fluid ...";
+   ////   }
+   ////   else if(dX>0.0 && dY>0.0 && dZ<=0.0)
+   ////   {
+   ////      double *fENB  = tempdistributions->getStartAdressOfSortedArray(posE,posN,posB,0);
+   ////      if(bcMatrix->isFluid(posE,posN,posB)) stresses = D3Q19System::getIncompStresses(fENB, collFactor );
+   ////      else cout<<__LINE__<<" nicht fluid ...";
+   ////   }
+   ////   else if(dX>0.0 && dY<=0.0 && dZ>0.0)
+   ////   {
+   ////      double *fEST  = tempdistributions->getStartAdressOfSortedArray(posE,posS,posT,0);
+   ////      if(bcMatrix->isFluid(posE,posS,posT)) stresses = D3Q19System::getIncompStresses(fEST, collFactor );
+   ////      else cout<<__LINE__<<" nicht fluid ...";
+   ////   }
+   ////   else if(dX>0.0 && dY>0.0 && dZ>0.0)
+   ////   {
+   ////      double *fENT  = tempdistributions->getStartAdressOfSortedArray(posE,posN,posT,0);
+   ////      if(bcMatrix->isFluid(posE,posN,posT)) stresses = D3Q19System::getIncompStresses(fENT, collFactor );
+   ////      else cout<<__LINE__<<" nicht fluid ...";
+   ////   }
+   ////   else cout<<"punkt mit:"<<dX<<" "<<dY<<" "<<dZ<<" ist nicht bei \n";
+
+   ////   double S11 = val<1>(stresses);
+   ////   double S22 = val<2>(stresses);
+   ////   double S33 = val<3>(stresses);
+   ////   double S12 = val<4>(stresses);
+   ////   double S13 = val<5>(stresses);
+   ////   double S23 = val<6>(stresses);
+
+   ////   GbVector3D normal = tri->getNormal();
+   ////   double nx = normal.X1();
+   ////   double ny = normal.X2();
+   ////   double nz = normal.X3();
+   ////   double area = tri->getArea();
+
+   ////   double Fx1 = area*(S11*nx+S12*ny+S13*nz);
+   ////   double Fy1 = area*(S12*nx+S22*ny+S23*nz);
+   ////   double Fz1 = area*(S13*nx+S23*ny+S33*nz);
+   ////   forceX1 += Fx1;
+   ////   forceX2 += Fy1;
+   ////   forceX3 += Fz1;
+   ////}
+   return UbTupleDouble3(forceX1,forceX2,forceX3);
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27TriFaceMeshInteractor::calculateForces()
+{
+   //FeTriFaceMesh3D* feMesh = dynamic_cast<FeTriFaceMesh3D*>(this->geoObject3D.get());
+   //if(!feMesh) throw UbException(UB_EXARGS,"geoObject is not a FeTriFaceMesh3D!");
+
+   //if(this->stressMode == STRESSNORMAL) this->calculateStresses();
+   //else if(this->stressMode == STRESSALTERNATIV) this->calculateStressesAlternativ();
+
+   //vector<FeTriFaceMesh3D::VertexAttributes>* attributes = feMesh->getAttributes();
+
+   //for (int i=0;i<(int)attributes->size() ;i++)
+   //{
+   //   FeTriFaceMesh3D::VertexAttributes& attribut = (*attributes)[i];
+   //   attribut.setFX(0.0);
+   //   attribut.setFY(0.0);
+   //   attribut.setFZ(0.0);
+   //   attribut.setArea(0.0);
+   //}
+   //vector<GbTriFaceMesh3D::TriFace>& triangles = *feMesh->getTriangles();
+   //vector<GbTriFaceMesh3D::Vertex>&  nodes = *feMesh->getNodes();
+   //for (size_t i=0; i<triangles.size(); i++)
+   //{
+   //   GbTriFaceMesh3D::TriFace& triangle = triangles[i];
+   //   FeTriFaceMesh3D::VertexAttributes& vAttribut1 = (*attributes)[triangle.v1];
+   //   FeTriFaceMesh3D::VertexAttributes& vAttribut2 = (*attributes)[triangle.v2];
+   //   FeTriFaceMesh3D::VertexAttributes& vAttribut3 = (*attributes)[triangle.v3];
+   //   UbTupleDouble6& stressesP1 = vAttribut1.getStresses();
+   //   UbTupleDouble6& stressesP2 = vAttribut2.getStresses();
+   //   UbTupleDouble6& stressesP3 = vAttribut3.getStresses();
+   //   double p1S11 = val<1>(stressesP1); double p2S11 = val<1>(stressesP2); double p3S11 = val<1>(stressesP3);
+   //   double p1S22 = val<2>(stressesP1); double p2S22 = val<2>(stressesP2); double p3S22 = val<2>(stressesP3);
+   //   double p1S33 = val<3>(stressesP1); double p2S33 = val<3>(stressesP2); double p3S33 = val<3>(stressesP3);
+   //   double p1S12 = val<4>(stressesP1); double p2S12 = val<4>(stressesP2); double p3S12 = val<4>(stressesP3);
+   //   double p1S13 = val<5>(stressesP1); double p2S13 = val<5>(stressesP2); double p3S13 = val<5>(stressesP3);
+   //   double p1S23 = val<6>(stressesP1); double p2S23 = val<6>(stressesP2); double p3S23 = val<6>(stressesP3);
+
+   //   triangle.calculateNormal(nodes);
+   //   double nx = triangle.nx;
+   //   double ny = triangle.ny;
+   //   double nz = triangle.nz;
+   //   double area = 0.3333*triangle.getArea(nodes);
+
+   //   if(UbMath::lessEqual(area,0.0)) cout<<__FILE__<<" "<<__LINE__<<" area <= 0 "<<endl;
+
+   //   double Fx1 = area*(0.333*(p1S11*nx+p1S12*ny+p1S13*nz)+0.333*(p2S11*nx+p2S12*ny+p2S13*nz)+0.333*(p3S11*nx+p3S12*ny+p3S13*nz));
+   //   double Fx2 = Fx1;
+   //   double Fx3 = Fx1;
+
+   //   double Fy1 = area*(0.333*(p1S12*nx+p1S22*ny+p1S23*nz)+0.333*(p2S12*nx+p2S22*ny+p2S23*nz)+0.333*(p3S12*nx+p3S22*ny+p3S23*nz));
+   //   double Fy2 = Fy1;
+   //   double Fy3 = Fy1;
+
+   //   double Fz1 = area*(0.333*(p1S13*nx+p1S23*ny+p1S33*nz)+0.333*(p2S13*nx+p2S23*ny+p2S33*nz)+0.333*(p3S13*nx+p3S23*ny+p3S33*nz));
+   //   double Fz2 = Fz1;
+   //   double Fz3 = Fz1;
+   //   //  cout<<Fx1<<" "<<Fy1<<" "<<Fz1<<endl;
+   //   vAttribut1.addFX(Fx1);    vAttribut2.addFX(Fx2);    vAttribut3.addFX(Fx3);
+   //   vAttribut1.addFY(Fy1);    vAttribut2.addFY(Fy2);    vAttribut3.addFY(Fy3);
+   //   vAttribut1.addFZ(Fz1);    vAttribut2.addFZ(Fz2);    vAttribut3.addFZ(Fz3);
+   //   vAttribut1.addArea(area); vAttribut2.addArea(area); vAttribut3.addArea(area);
+   //}
+   //for (size_t i=0; i<attributes->size(); i++)
+   //{
+   //   FeTriFaceMesh3D::VertexAttributes& attribut = (*attributes)[i];
+
+   //   double newFX = attribut.getFX()/attribut.getArea();
+   //   double newFY = attribut.getFY()/attribut.getArea();
+   //   double newFZ = attribut.getFZ()/attribut.getArea();
+   //   //if(i==100) cout<<"F:"<<newFX<<" "<<newFY<<" "<<newFZ<<endl;
+   //   //double oldFX = p->getOldFX();
+   //   //double oldFY = p->getOldFY();
+   //   //int alphaSteps = p->getFilteringSteps();
+   //   //double alpha = 1.0;
+   //   //if(alphaSteps != 0)
+   //   //{
+   //   //   alpha = (1.0-alphaSteps*0.1);
+   //   // //  cout<<p->toString()<<" alpha:"<<alpha<<" steps:"<<alphaSteps<<endl;
+   //   //   p->reduceFilteringSteps();
+   //   //}
+   //   //newFX = (1.-alpha)*oldFX+alpha*newFX;
+   //   //newFY = (1.-alpha)*oldFY+alpha*newFY;
+
+   //   attribut.setFX(newFX);
+   //   attribut.setFY(newFY);
+   //   attribut.setFZ(newFZ);
+   //   //cout<<i<<" "<<newFX<<" "<<newFY<<" "<<newFZ<<endl;
+   //   //cout<<i<<" "<<p->toString()<<endl;
+
+   //}
+}
+//////////////////////////////////////////////////////////////////////////
+string D3Q27TriFaceMeshInteractor::toString()
+{
+   stringstream ss;
+   ss<< "D3Q27TriFaceMeshInteractor[label=D3Q27TriFaceMeshInteractor";
+   if(this->isSolid()) ss<<", solid";
+   if(this->isInverseSolid()) ss<<", inversesolid";
+   if(this->isTimeDependent()) ss<<", timedependent";
+   if(geoObject3D!=NULL) ss<<", AMR3DInteractor: "<<geoObject3D->toString();
+   ss<<"]";
+
+   return ss.str();
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27TriFaceMeshInteractor::reinitWithStoredQs( const double& timeStep )
+{
+   //alle solid Bloecke wieder solid setzen
+   std::vector<Block3DPtr>& solidBlocks = this->getSolidBlockSet();
+   for(size_t i=0; i<solidBlocks.size(); i++)
+   {
+      solidBlocks[i]->setActive(false); //<- quick n dirty
+   }
+
+   //alle solid-nodes wieder solid setzen (solids die quasi in den TransBloecken liegen)
+   std::map<Block3DPtr, std::set< UbTupleInt3 > >::iterator it1;
+   for( it1=this->solidNodeIndicesMap.begin(); it1!=this->solidNodeIndicesMap.end(); ++it1 )
+   {
+      Block3DPtr block = it1->first;
+
+      ILBMKernelPtr kernel = block->getKernel();
+      BCArray3DPtr bcMatrix = kernel->getBCProcessor()->getBCArray();
+      std::set< UbTupleInt3 >&  indicesSet = it1->second;
+
+      for( std::set< UbTupleInt3 >::iterator setIt=indicesSet.begin(); setIt!=indicesSet.end(); ++setIt )
+      {
+         bcMatrix->setSolid( val<1>(*setIt), val<2>(*setIt), val<3>(*setIt) );
+      }
+   }
+
+   //BCS WIEDERHERSTELLEN
+   std::map<Block3DPtr, std::map< UbTupleInt3, std::vector<float> > >::iterator it;
+   for( it=bcNodeIndicesAndQsMap.begin(); it!=bcNodeIndicesAndQsMap.end(); ++it )
+   {   
+      Block3DPtr  block    = it->first;
+      ILBMKernelPtr kernel = block->getKernel();
+      BCArray3DPtr bcMatrix = kernel->getBCProcessor()->getBCArray();
+
+      std::map< UbTupleInt3, std::vector<float> >::iterator it2;
+      for( it2=it->second.begin(); it2!=it->second.end(); ++it2 )
+      {   
+         const UbTupleInt3&    pos = it2->first;
+         std::vector< float >       qs  = it2->second;
+
+         //SG_27.08.2010 
+         if(bcMatrix->isSolid(val<1>(pos), val<2>(pos), val<3>(pos))) continue;
+
+         BoundaryConditionsPtr   bc = bcMatrix->getBC( val<1>(pos), val<2>(pos), val<3>(pos) );
+         if(!bc)
+         {
+            bc = BoundaryConditionsPtr(new BoundaryConditions);
+            bcMatrix->setBC( val<1>(pos), val<2>(pos), val<3>(pos), bc );
+         }
+
+         double x1w = qs[D3Q27System::FENDDIR+1+0];
+         double x2w = qs[D3Q27System::FENDDIR+1+1];
+         double x3w = qs[D3Q27System::FENDDIR+1+2];
+
+
+         //TODO: HACK GEHOERT NICHT HIERHIER!!! - start
+         //es handelt sich un ein statisches Objekt und beim Propeller gibt
+         // es Schwierigkeiten an den Flügelspitzen, dass kann daher kommen,
+         //dass dort zuviel bc-flaggs sind und mit Geschwindigkeit ergibt dies ziemlich grosse Werte
+         bc->setBoundaryVelocityX1(0.0);
+         bc->setBoundaryVelocityX2(0.0);
+         bc->setBoundaryVelocityX3(0.0);
+         //TODO: HACK GEHOERT NICHT HIERHIER!!! - end
+
+         bool gotQs = false;
+         for(int fdir=D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
+         {
+            if( UbMath::greater(qs[fdir], -1.0) && UbMath::less( qs[fdir], bc->getQ(fdir) ) )
+            {
+               gotQs = true;
+               for(size_t index=0; index<this->bcAdapters.size(); index++)
+                  this->bcAdapters[index]->adaptBCForDirection( *this, bc, x1w, x2w, x3w, qs[fdir], fdir);
+            }
+         }
+
+         if(gotQs)
+            for(size_t index=0; index<this->bcAdapters.size(); index++)
+               this->bcAdapters[index]->adaptBC( *this, bc, x1w, x2w, x3w);
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27TriFaceMeshInteractor::updateInteractor( const double& timestep/*=0*/ )
+{
+   UB_THROW( UbException("D3Q27TriFaceMeshInteractor::updateInteractor - toDo") );
+}
+
+
+
+
+
+
diff --git a/source/VirtualFluidsCore/Interactors/D3Q27TriFaceMeshInteractor.h b/source/VirtualFluidsCore/Interactors/D3Q27TriFaceMeshInteractor.h
index 8d195c3c7..fdcf1a3ba 100644
--- a/source/VirtualFluidsCore/Interactors/D3Q27TriFaceMeshInteractor.h
+++ b/source/VirtualFluidsCore/Interactors/D3Q27TriFaceMeshInteractor.h
@@ -2,32 +2,24 @@
 #define D3Q19AMRTRIFACEMESHINTERACTOR_H
 
 #include <string>
-#include <sstream>
 #include <vector>
-#include <list>
 #include <map>
-#include <cmath>
-
+#include <memory>
 
 #include "D3Q27Interactor.h"
-#include <numerics/geometry3d/GbTriFaceMesh3D.h>
+#include "CbArray3D.h"
 
-class UbFileInput;
-class UbFileOutput;
-class GbObject3D;
-class Grid3D;
+class D3Q27TriFaceMeshInteractor;
+typedef std::shared_ptr<D3Q27TriFaceMeshInteractor> D3Q27TriFaceMeshInteractorPtr;
 
-//////////////////////////////////////////////////////////////////////////
 
-#include <boost/shared_ptr.hpp>
+class GbObject3D;
+class Grid3D;
+class BCAdapter;
+class GbTriFaceMesh3D;
+class Block3D;
 
-class D3Q27TriFaceMeshInteractor;
-typedef boost::shared_ptr<D3Q27TriFaceMeshInteractor> D3Q27TriFaceMeshInteractorPtr;
 
-//////////////////////////////////////////////////////////////////////////
-// D3Q27TriFaceMeshInteractor
-//
-//////////////////////////////////////////////////////////////////////////
 class D3Q27TriFaceMeshInteractor : public D3Q27Interactor 
 {
 public:
@@ -35,10 +27,10 @@ public:
    static const int STRESSALTERNATIV=1;
 
    D3Q27TriFaceMeshInteractor();
-   D3Q27TriFaceMeshInteractor(Grid3DPtr grid, std::string name="D3Q27TriFaceMeshInteractor");
-   D3Q27TriFaceMeshInteractor(GbObject3DPtr geoObject3D, Grid3DPtr grid, int type);
-   D3Q27TriFaceMeshInteractor(GbTriFaceMesh3DPtr triFaceMesh, Grid3DPtr grid, BCAdapterPtr bcAdapter, int type);
-   D3Q27TriFaceMeshInteractor(GbTriFaceMesh3DPtr triFaceMesh, Grid3DPtr grid, BCAdapterPtr bcAdapter, int type, Interactor3D::Accuracy a);
+   D3Q27TriFaceMeshInteractor(std::shared_ptr<Grid3D> grid, std::string name="D3Q27TriFaceMeshInteractor");
+   D3Q27TriFaceMeshInteractor(std::shared_ptr<GbObject3D> geoObject3D, std::shared_ptr<Grid3D> grid, int type);
+   D3Q27TriFaceMeshInteractor(std::shared_ptr<GbTriFaceMesh3D> triFaceMesh, std::shared_ptr<Grid3D> grid, std::shared_ptr<BCAdapter> bcAdapter, int type);
+   D3Q27TriFaceMeshInteractor(std::shared_ptr<GbTriFaceMesh3D> triFaceMesh, std::shared_ptr<Grid3D> grid, std::shared_ptr<BCAdapter> bcAdapter, int type, Interactor3D::Accuracy a);
    //D3Q27TriFaceMeshInteractor(GbTriFaceMesh3DPtr triFaceMesh, D3Q27BoundaryConditionAdapterPtr bcAdapter, int type, std::string name="D3Q27TriFaceMeshInteractor");
 
    ~D3Q27TriFaceMeshInteractor();
@@ -52,7 +44,7 @@ public:
    void setQs(const double& timeStep);
    void refineBlockGridToLevel(int level, double startDistance, double stopDistance);
 
-   bool setDifferencesToGbObject3D(const Block3DPtr block/*,const double& orgX1,const double& orgX2,const double& orgX3,const double& blockLengthX1,const double& blockLengthX2,const double& blockLengthX3, const double& timestep=0*/);
+   bool setDifferencesToGbObject3D(const std::shared_ptr<Block3D> block/*,const double& orgX1,const double& orgX2,const double& orgX3,const double& blockLengthX1,const double& blockLengthX2,const double& blockLengthX3, const double& timestep=0*/);
 
    void setRegardPointInObjectTest( bool opt ) { this->regardPIOTest = opt; }
 
@@ -103,7 +95,7 @@ protected:
 
    void reinitWithStoredQs(const double& timeStep);
    //   bool reinitWithStoredQsFlag;
-   std::map< Block3DPtr, std::map < UbTupleInt3, std::vector< float > > > bcNodeIndicesAndQsMap;    //!!! es kann sein, dass in diesem interactor
+   std::map< std::shared_ptr<Block3D>, std::map < UbTupleInt3, std::vector< float > > > bcNodeIndicesAndQsMap;    //!!! es kann sein, dass in diesem interactor
    //an eine rpos eine BC gesetzt wurde, aber derselbe node in
    //in einem anderen in einen anderen Typ (z.B. Solid) geaendert
    //wurde --> es ist keine BC mehr an der stelle!
diff --git a/source/VirtualFluidsCore/Interactors/Interactor3D.cpp b/source/VirtualFluidsCore/Interactors/Interactor3D.cpp
index c80282bf1..7d5eb0836 100644
--- a/source/VirtualFluidsCore/Interactors/Interactor3D.cpp
+++ b/source/VirtualFluidsCore/Interactors/Interactor3D.cpp
@@ -1,11 +1,17 @@
 #include "Interactor3D.h"
 
-#include <boost/foreach.hpp>
+
 
 #include <fstream>
 #include <numerics/geometry3d/GbCuboid3D.h>
 #include <basics/utilities/UbMath.h>
 #include <basics/utilities/UbFileOutput.h>
+#include "UbException.h"
+
+#include "Grid3D.h"
+#include "Block3D.h"
+#include "GbObject3D.h"
+
 
 using namespace std;
 
@@ -49,131 +55,6 @@ Interactor3D::~Interactor3D()
 {
 }
 //////////////////////////////////////////////////////////////////////////
-//void Interactor3D::deleteSolidBlocks(int level)
-//{
-//   //hier werden die Bloecke aktiv oder nicht aktiv gesetzt
-//   double minX1,minX2,minX3,maxX1,maxX2,maxX3,x1,x2,x3;
-//   int gridRank = grid.lock()->getRank();
-//
-//   vector<Block3DPtr> blockVector;
-//   bool activ = true;
-//   grid.lock()->getBlocks(level, gridRank, activ, blockVector);
-//   BOOST_FOREACH(Block3DPtr block, blockVector)
-//   {
-//      double deltaX = grid.lock()->getDeltaX(block);
-//      UbTupleDouble3 blockLengths  = grid.lock()->getBlockLengths(block);
-//
-//      //Koords bestimmen
-//      UbTupleDouble3 org = grid.lock()->getBlockWorldCoordinates(block);
-//
-//      x1 = val<1>(org);
-//      x2 = val<2>(org);
-//      x3 = val<3>(org);
-//
-//      minX1 = x1;
-//      minX2 = x2;
-//      minX3 = x3;
-//      maxX1 = x1 + val<1>(blockLengths);
-//      maxX2 = x2 + val<2>(blockLengths);
-//      maxX3 = x3 + val<3>(blockLengths);
-//
-//      if(this->isInverseSolid())
-//      {
-//         switch (accuracy)
-//         {
-//         //simple duff
-//         case SIMPLE:
-//            if(!this->geoObject3D->isCellInsideOrCuttingGbObject3D(minX1,minX2,minX3,maxX1,maxX2,maxX3))
-//               block->setActive(false);
-//            break;
-//         //test only edges
-//         case EDGES:
-//            if(arePointsOutsideGeoObject(minX1, minX2, minX3, maxX1, minX2, minX3, deltaX) &&
-//               arePointsOutsideGeoObject(minX1, maxX2, minX3, maxX1, maxX2, minX3, deltaX) &&
-//               arePointsOutsideGeoObject(minX1, minX2, maxX3, maxX1, minX2, maxX3, deltaX) &&
-//               arePointsOutsideGeoObject(minX1, maxX2, maxX3, maxX1, maxX2, maxX3, deltaX) &&
-//
-//               arePointsOutsideGeoObject(minX1, minX2, minX3, minX1, maxX2, minX3, deltaX) &&
-//               arePointsOutsideGeoObject(maxX1, minX2, minX3, maxX1, maxX2, minX3, deltaX) &&
-//               arePointsOutsideGeoObject(minX1, minX2, maxX3, maxX1, minX2, maxX3, deltaX) &&
-//               arePointsOutsideGeoObject(maxX1, minX2, maxX3, maxX1, maxX2, maxX3, deltaX) &&
-//
-//               arePointsOutsideGeoObject(minX1, minX2, minX3, minX1, maxX2, maxX3, deltaX) &&
-//               arePointsOutsideGeoObject(maxX1, minX2, minX3, maxX1, maxX2, maxX3, deltaX) &&
-//               arePointsOutsideGeoObject(minX1, maxX2, minX3, maxX1, minX2, maxX3, deltaX) &&
-//               arePointsOutsideGeoObject(maxX1, maxX2, minX3, maxX1, maxX2, maxX3, deltaX))   
-//                  block->setActive(false);
-//            break;
-//         //test only faces
-//         case FACES:
-//            if(arePointsOutsideGeoObject(minX1, minX2, minX3, minX1, maxX2, maxX3, deltaX) &&
-//               arePointsOutsideGeoObject(maxX1, minX2, minX3, maxX1, maxX2, maxX3, deltaX) &&
-//               arePointsOutsideGeoObject(minX1, minX2, minX3, maxX1, minX2, maxX3, deltaX) &&
-//               arePointsOutsideGeoObject(minX1, maxX2, minX3, maxX1, maxX2, maxX3, deltaX) &&
-//               arePointsOutsideGeoObject(minX1, minX2, minX3, maxX1, maxX2, minX3, deltaX) &&
-//               arePointsOutsideGeoObject(minX1, minX2, maxX3, maxX1, maxX2, maxX3, deltaX))
-//                  block->setActive(false);
-//            break;
-//         //test all points
-//         case POINTS:
-//            if(arePointsOutsideGeoObject(minX1, minX2, minX3, maxX1, maxX2, maxX3, deltaX))
-//               block->setActive(false);
-//            break;
-//         default:
-//            UB_THROW( UbException(UB_EXARGS, "Accuracy isn't correct") );
-//            break;
-//         }
-//      }
-//      else //solid 
-//      {
-//         switch (accuracy)
-//         {
-//         //simple duff
-//         case SIMPLE:
-//            if(this->geoObject3D->isCellInsideGbObject3D(minX1,minX2,minX3,maxX1,maxX2,maxX3))
-//               block->setActive(false);
-//            break;
-//         //test only edges
-//         case EDGES:
-//            if(arePointsInsideGeoObject(minX1, minX2, minX3, maxX1, minX2, minX3, deltaX) &&
-//               arePointsInsideGeoObject(minX1, maxX2, minX3, maxX1, maxX2, minX3, deltaX) &&
-//               arePointsInsideGeoObject(minX1, minX2, maxX3, maxX1, minX2, maxX3, deltaX) &&
-//               arePointsInsideGeoObject(minX1, maxX2, maxX3, maxX1, maxX2, maxX3, deltaX) &&
-//
-//               arePointsInsideGeoObject(minX1, minX2, minX3, minX1, maxX2, minX3, deltaX) &&
-//               arePointsInsideGeoObject(maxX1, minX2, minX3, maxX1, maxX2, minX3, deltaX) &&
-//               arePointsInsideGeoObject(minX1, minX2, maxX3, maxX1, minX2, maxX3, deltaX) &&
-//               arePointsInsideGeoObject(maxX1, minX2, maxX3, maxX1, maxX2, maxX3, deltaX) &&
-//
-//               arePointsInsideGeoObject(minX1, minX2, minX3, minX1, maxX2, maxX3, deltaX) &&
-//               arePointsInsideGeoObject(maxX1, minX2, minX3, maxX1, maxX2, maxX3, deltaX) &&
-//               arePointsInsideGeoObject(minX1, maxX2, minX3, maxX1, minX2, maxX3, deltaX) &&
-//               arePointsInsideGeoObject(maxX1, maxX2, minX3, maxX1, maxX2, maxX3, deltaX))   
-//               block->setActive(false);
-//            break;
-//         //test only faces
-//         case FACES:
-//            if(arePointsInsideGeoObject(minX1, minX2, minX3, minX1, maxX2, maxX3, deltaX) &&
-//               arePointsInsideGeoObject(maxX1, minX2, minX3, maxX1, maxX2, maxX3, deltaX) &&
-//               arePointsInsideGeoObject(minX1, minX2, minX3, maxX1, minX2, maxX3, deltaX) &&
-//               arePointsInsideGeoObject(minX1, maxX2, minX3, maxX1, maxX2, maxX3, deltaX) &&
-//               arePointsInsideGeoObject(minX1, minX2, minX3, maxX1, maxX2, minX3, deltaX) &&
-//               arePointsInsideGeoObject(minX1, minX2, maxX3, maxX1, maxX2, maxX3, deltaX))
-//               block->setActive(false);
-//            break;
-//         //test all points
-//         case POINTS:
-//            if(arePointsInsideGeoObject(minX1, minX2, minX3, maxX1, maxX2, maxX3, deltaX))
-//               block->setActive(false);
-//            break;
-//         default:
-//            UB_THROW( UbException(UB_EXARGS, "Accuracy isn't correct") );
-//            break;
-//         }
-//      }
-//   }
-//}
-//////////////////////////////////////////////////////////////////////////
 bool Interactor3D::arePointsInsideGeoObject(double minX1, double minX2, double minX3, double maxX1, double maxX2, double maxX3, double delta)
 {
    bool result = true;
@@ -382,108 +263,23 @@ void Interactor3D::setBCBlock(Block3DPtr block)
    if(isBlockCuttingGeoObject(minX1, minX2, minX3, maxX1, maxX2, maxX3, deltaX))
       this->bcBlocks.push_back(block);
 }
+
+UbTupleDouble3 Interactor3D::getForces()
+{
+    UB_THROW( UbException("UbTupleDouble3 getForces() - gehoert in die abgeleitete klasse") );
+}
+
 //////////////////////////////////////////////////////////////////////////
 void Interactor3D::initInteractor(const double& timeStep)
 {
    //UBLOG(logINFO, "transBlocks.size = "<<transBlocks.size());
 
-   BOOST_FOREACH(Block3DPtr block, bcBlocks)
+   for(Block3DPtr block : bcBlocks)
    {
       this->setDifferencesToGbObject3D(block);
    }
 }
 //////////////////////////////////////////////////////////////////////////
-//SOLID:
-//bloecke werden nicht activ gesetzt, wenn der Block vollstaendig in der Geometrie
-//blocke werden in transBlock hinzugefuegt, wenn block+delta schnittpunkt oder beruehrungspunkt mit geo hat
-//fuer jeden transblock wird "setDifferencesToGbObject3D aufgerufen
-//void Interactor3D::initInteractor(const double& timeStep)
-//{
-   //this->removeTransBlocks();
-   //this->removeSolidBlocks();
-
-   ////hier werden die Bloecke aktiv oder nicht aktiv gesetzt
-   //double minX1,minX2,minX3,maxX1,maxX2,maxX3,x1,x2,x3;
-   //int gridRank = grid.lock()->getRank();
-
-   //int minInitLevel = this->grid.lock()->getCoarsestInitializedLevel();
-   //int maxInitLevel = this->grid.lock()->getFinestInitializedLevel();
-
-   //for(int level = minInitLevel; level<=maxInitLevel;level++)
-   //{
-   //   vector<Block3DPtr> blockVector;
-   //   grid.lock()->getBlocks(level, gridRank, blockVector);
-   //   BOOST_FOREACH(Block3DPtr block, blockVector)
-   //   {
-   //      //Koords bestimmen
-   //      UbTupleDouble3 org = grid.lock()->getBlockWorldCoordinates(block);
-   //      UbTupleDouble3 blockLengths  = grid.lock()->getBlockLengths(block);
-   //      double dx = grid.lock()->getDeltaX(block);
-   //      UbTupleDouble3 orgDelta = grid.lock()->getNodeOffset(block);
-   //      UbTupleDouble3 coords = grid.lock()->getNodeCoordinates(block, 0, 0, 0);
-
-   //      //x1 = val<1>(org);
-   //      //x2 = val<2>(org);
-   //      //x3 = val<3>(org);
-   //      x1 = val<1>(coords);
-   //      x2 = val<2>(coords);
-   //      x3 = val<3>(coords);
-
-   //      minX1 = x1;
-   //      minX2 = x2;
-   //      minX3 = x3;
-   //      //maxX1 = x1 + val<1>(blockLengths);
-   //      //maxX2 = x2 + val<2>(blockLengths);
-   //      //maxX3 = x3 + val<3>(blockLengths);
-   //      maxX1 = val<1>(coords);
-   //      maxX2 = val<2>(coords);
-   //      maxX3 = val<3>(coords);
-
-   //      if(this->isInverseSolid())
-   //      {
-   //         if(   UbMath::lessEqual(minX1,geoObject3D->getX1Minimum()) 
-   //            && UbMath::lessEqual(minX2,geoObject3D->getX2Minimum())
-   //            && UbMath::lessEqual(minX3,geoObject3D->getX2Minimum())
-   //            && UbMath::greaterEqual(maxX1,geoObject3D->getX1Maximum())
-   //            && UbMath::greaterEqual(maxX2,geoObject3D->getX2Maximum()) 
-   //            && UbMath::greaterEqual(maxX3,geoObject3D->getX2Maximum()))
-   //         {
-   //            this->transBlocks.push_back(block);
-   //            this->setDifferencesToGbObject3D(block/*, x1, x2, x3, val<1>(blockLengths), val<2>(blockLengths), val<3>(blockLengths), timeStep*/);
-   //         }
-   //         else if(this->geoObject3D->isCellCuttingGbObject3D(minX1,minX2,minX3,maxX1,maxX2,maxX3))
-   //         {
-   //            this->transBlocks.push_back(block);
-   //            this->setDifferencesToGbObject3D(block/*, x1, x2, x3, val<1>(blockLengths), val<2>(blockLengths), val<3>(blockLengths), timeStep*/);
-   //         }
-   //      }
-   //      else //solid 
-   //      {
-   //         //1. Fall: block komlett in geo ist in deleteSolidBlocks() erledigt
-   //         //2. Fall:  Celle umhuellt Geo oder Cell schneidet Geo
-   //         if( this->geoObject3D->isCellCuttingGbObject3D(minX1,minX2,minX3,maxX1,maxX2,maxX3) )
-   //         {
-   //            this->transBlocks.push_back(block);
-   //            this->setDifferencesToGbObject3D(block/*,x1,x2,x3,val<1>(blockLengths),val<2>(blockLengths),val<3>(blockLengths),timeStep*/);
-   //         }
-   //         //3. Fall: cell umhuellt geo:
-   //         else if(   UbMath::lessEqual(    minX1, geoObject3D->getX1Minimum() )
-   //            && UbMath::lessEqual(    minX2, geoObject3D->getX2Minimum() )
-   //            && UbMath::lessEqual(    minX3, geoObject3D->getX3Minimum() )
-   //            && UbMath::greaterEqual( maxX1, geoObject3D->getX1Maximum() )
-   //            && UbMath::greaterEqual( maxX2, geoObject3D->getX2Maximum() )
-   //            && UbMath::greaterEqual( maxX3, geoObject3D->getX3Maximum() ) ) //block umhuellt geo
-   //         {
-   //            throw UbException(UB_EXARGS,"//3. Fall: cell umhuellt geo sollte mit Fall 2 abgedeckt sein!!!");
-
-   //            this->transBlocks.push_back(block);
-   //            this->setDifferencesToGbObject3D(block/*,x1,x2,x3,val<1>(blockLengths),val<2>(blockLengths),val<3>(blockLengths),timeStep*/);
-   //         }
-   //      }
-   //   }
-   //}
-//}
-//////////////////////////////////////////////////////////////////////////
 void Interactor3D::updateInteractor(const double& timeStep)
 {
    UB_THROW( UbException("Interactor3D::updateInteractor - toDo") );
diff --git a/source/VirtualFluidsCore/Interactors/Interactor3D.h b/source/VirtualFluidsCore/Interactors/Interactor3D.h
index dd6d2f2c6..343056c2c 100644
--- a/source/VirtualFluidsCore/Interactors/Interactor3D.h
+++ b/source/VirtualFluidsCore/Interactors/Interactor3D.h
@@ -1,51 +1,44 @@
 #ifndef INTERACTOR3D_H
 #define INTERACTOR3D_H
 
-#include <string>
-#include <sstream>
 #include <vector>
-#include <map>
-#include <list>
-#include <cmath>
+#include <memory>
 
+#include "UbSystem.h"
+#include "UbTuple.h"
+
+#include <boost/serialization/serialization.hpp>
+#include <boost/serialization/shared_ptr.hpp>
+
+class Block3D;
+class Grid3D;
 class UbFileInput;
 class UbFileOutput;
 class GbObject3D;
 class Block3D;
 
-#include <boost/serialization/shared_ptr.hpp>
 class Interactor3D;
-typedef boost::shared_ptr<Interactor3D> Interactor3DPtr;
-
-#include "UbException.h"
-#include "UbTuple.h"
-#include "ObObject.h"
-#include "GbObject3D.h"
-#include "Grid3D.h"
+typedef std::shared_ptr<Interactor3D> Interactor3DPtr;
 
-#include <boost/serialization/serialization.hpp>
-#include <boost/enable_shared_from_this.hpp>
-
-class Interactor3D 
+class Interactor3D : public std::enable_shared_from_this<Interactor3D>
 {
 public:
    enum Accuracy{SIMPLE, EDGES, FACES, POINTS};
    Interactor3D();
-   Interactor3D(Grid3DPtr grid, int type=Interactor3D::SOLID);
-   Interactor3D(GbObject3DPtr geoObject3D, Grid3DPtr grid, int type);
+   Interactor3D(std::shared_ptr<Grid3D> grid, int type=Interactor3D::SOLID);
+   Interactor3D(std::shared_ptr<GbObject3D> geoObject3D, std::shared_ptr<Grid3D> grid, int type);
    //! constructor
    //! \param a set accuracy for arePointsInObject() and arePointsNotInObject()
-   Interactor3D(GbObject3DPtr geoObject3D, Grid3DPtr grid, int type, Interactor3D::Accuracy a);
+   Interactor3D(std::shared_ptr<GbObject3D> geoObject3D, std::shared_ptr<Grid3D> grid, int type, Interactor3D::Accuracy a);
    
    virtual ~Interactor3D();
    virtual void initInteractor(const double& timestep=0); 
    virtual void updateInteractor(const double& timestep=0)=0;
-   //virtual void deleteSolidBlocks(int level);
 
-   void setSolidBlock(Block3DPtr block);
-   void setBCBlock(Block3DPtr block);
-      
-   virtual UbTupleDouble3 getForces() { UB_THROW( UbException("UbTupleDouble3 getForces() - gehoert in die abgeleitete klasse") ); }
+   void setSolidBlock(std::shared_ptr<Block3D> block);
+   void setBCBlock(std::shared_ptr<Block3D> block);
+
+    virtual UbTupleDouble3 getForces();
 
    void setSolid()        { UbSystem::setBit(this->type, SOLID   ); }
    void setMoveable()     { UbSystem::setBit(this->type, MOVEABLE); }
@@ -55,17 +48,17 @@ public:
    bool isTimeDependent() { return UbSystem::bitCheck(this->type, TIMEDEPENDENT); }
    bool isMoveable()      { return UbSystem::bitCheck(this->type, MOVEABLE     ); }
    
-   Grid3DPtr getGrid3D()  const { return grid.lock();   }
-   void setGrid3D(Grid3DPtr grid) { this->grid = grid; }
-   virtual GbObject3DPtr  getGbObject3D() const { return geoObject3D; }
-   virtual bool setDifferencesToGbObject3D(const Block3DPtr block/*, const double& x1, const double& x2, const double& x3, const double& blockLengthX1, const double& blockLengthX2, const double& blockLengthX3, const double& timestep=0*/)
+   std::shared_ptr<Grid3D> getGrid3D()  const { return grid.lock();   }
+   void setGrid3D(std::shared_ptr<Grid3D> grid) { this->grid = grid; }
+   virtual std::shared_ptr<GbObject3D>  getGbObject3D() const { return geoObject3D; }
+   virtual bool setDifferencesToGbObject3D(const std::shared_ptr<Block3D> block/*, const double& x1, const double& x2, const double& x3, const double& blockLengthX1, const double& blockLengthX2, const double& blockLengthX3, const double& timestep=0*/)
    {
       return false;  
    }
 
-   virtual std::vector<Block3DPtr>& getBcBlocks() { return this->bcBlocks; }
+   virtual std::vector<std::shared_ptr<Block3D> >& getBcBlocks() { return this->bcBlocks; }
    virtual void removeBcBlocks() { this->bcBlocks.clear(); }
-   virtual std::vector<Block3DPtr>& getSolidBlockSet() { return this->solidBlocks; }
+   virtual std::vector<std::shared_ptr<Block3D> >& getSolidBlockSet() { return this->solidBlocks; }
    virtual void removeSolidBlocks() { this->solidBlocks.clear(); }
 
 protected:
@@ -93,11 +86,11 @@ protected:
 
    int type;
    
-   Grid3DWeakPtr grid;
-   GbObject3DPtr geoObject3D;
+   std::weak_ptr<Grid3D> grid;
+   std::shared_ptr<GbObject3D> geoObject3D;
 
-   std::vector<Block3DPtr> bcBlocks;
-   std::vector<Block3DPtr> solidBlocks;
+   std::vector<std::shared_ptr<Block3D> > bcBlocks;
+   std::vector<std::shared_ptr<Block3D> > solidBlocks;
    int accuracy;
 
 public:
diff --git a/source/VirtualFluidsCore/Interactors/InteractorsHelper.cpp b/source/VirtualFluidsCore/Interactors/InteractorsHelper.cpp
index aceeb7975..da3bf1cf4 100644
--- a/source/VirtualFluidsCore/Interactors/InteractorsHelper.cpp
+++ b/source/VirtualFluidsCore/Interactors/InteractorsHelper.cpp
@@ -1,7 +1,11 @@
 #include "InteractorsHelper.h"
+
 #include <SetSolidBlockVisitor.h>
 #include <Grid3DVisitor.h>
-#include <boost/foreach.hpp>
+#include <Grid3D.h>
+#include <Interactor3D.h>
+#include "Block3D.h"
+#include "Communicator.h"
 
 
 InteractorsHelper::InteractorsHelper(Grid3DPtr grid, Grid3DVisitorPtr visitor) :
@@ -20,65 +24,62 @@ void InteractorsHelper::addInteractor( Interactor3DPtr interactor )
    interactors.push_back(interactor);
 }
 //////////////////////////////////////////////////////////////////////////
-void InteractorsHelper::deleteSolidBlocks()
+void InteractorsHelper::setBC()
+{
+    for(Interactor3DPtr i : interactors)
+        i->initInteractor();
+}
+
+void InteractorsHelper::sendDomainDecompositionVisitor() const
 {
-   BOOST_FOREACH(Interactor3DPtr i, interactors)
-   {
-      //UBLOG(logINFO,"rank="<<grid->getRank()<<", SetSolidOrTransBlockVisitor::start");
-      SetSolidBlockVisitor v(i, SetSolidBlockVisitor::SOLID);
-      grid->accept(v);
-      //UBLOG(logINFO,"rank="<<grid->getRank()<<", SetSolidOrTransBlockVisitor::end");
-      std::vector<Block3DPtr>& sb = i->getSolidBlockSet();
-      solidBlocks.insert(solidBlocks.end(), sb.begin(), sb.end());
-      i->removeSolidBlocks();
-   }
-   
-   //UBLOG(logINFO,"rank="<<grid->getRank()<<", solidBlocks.size = " <<solidBlocks.size());
-   
-   updateGrid();
+    grid->accept( visitor );
 }
+
 //////////////////////////////////////////////////////////////////////////
-void InteractorsHelper::updateGrid()
+void InteractorsHelper::selectBlocks()
+{
+   sendDomainDecompositionVisitor();
+   deleteSolidBlocks();
+
+   sendDomainDecompositionVisitor();
+   setBcBlocks();
+}
+//////////////////////////////////////////////////////////////////////////
+void InteractorsHelper::deleteSolidBlocks()
 {
-   std::vector<int> ids;
+    for(Interactor3DPtr interactor : interactors)
+    {
+        setBlocks(interactor, BlockType::SOLID);
 
-   BOOST_FOREACH(Block3DPtr block, solidBlocks)
-   {
-      ids.push_back(block->getGlobalID());
-   }
-   
-   //UBLOG(logINFO,"rank="<<grid->getRank()<<", ids.size = " <<ids.size());
+        std::vector<Block3DPtr>& sb = interactor->getSolidBlockSet();
+        solidBlocks.insert(solidBlocks.end(), sb.begin(), sb.end());
+        interactor->removeSolidBlocks();
+    }
 
-   std::vector<int> rids;
-   Communicator::getInstance()->allGather(ids, rids);
-   grid->deleteBlocks(rids);
+    updateGrid();
 }
 //////////////////////////////////////////////////////////////////////////
-void InteractorsHelper::setTransBlocks()
+void InteractorsHelper::setBlocks(const Interactor3DPtr interactor, BlockType type) const
 {
-   BOOST_FOREACH(Interactor3DPtr i, interactors)
-   {
-      SetSolidBlockVisitor v(i, SetSolidBlockVisitor::BC);
-      grid->accept(v);
-   }
+    SetSolidBlockVisitor v(interactor, type);
+    grid->accept(v);
 }
 //////////////////////////////////////////////////////////////////////////
-void InteractorsHelper::selectBlocks()
+void InteractorsHelper::setBcBlocks()
 {
-   //domain decomposition visitor
-   grid->accept( visitor );
-   //delete solid blocks
-   deleteSolidBlocks();
-   //domain decomposition visitor
-   grid->accept( visitor );
-   //set trans blocks
-   setTransBlocks();
+    for(const Interactor3DPtr interactor : interactors)
+        setBlocks(interactor, BlockType::BC);
 }
 //////////////////////////////////////////////////////////////////////////
-void InteractorsHelper::setBC()
+void InteractorsHelper::updateGrid()
 {
-   BOOST_FOREACH(Interactor3DPtr i, interactors)
-   {
-      i->initInteractor();
-   }
+    std::vector<int> ids;
+
+    for(const Block3DPtr block : solidBlocks)
+        ids.push_back(block->getGlobalID());
+
+    std::vector<int> rids;
+    Communicator::getInstance()->allGather(ids, rids);
+    grid->deleteBlocks(rids);
 }
+
diff --git a/source/VirtualFluidsCore/Interactors/InteractorsHelper.h b/source/VirtualFluidsCore/Interactors/InteractorsHelper.h
index 32bf591ef..75233964c 100644
--- a/source/VirtualFluidsCore/Interactors/InteractorsHelper.h
+++ b/source/VirtualFluidsCore/Interactors/InteractorsHelper.h
@@ -1,27 +1,38 @@
 #ifndef SolidBlocksHelper_h 
 #define SolidBlocksHelper_h
 
-#include <Grid3D.h>
-#include <Communicator.h>
-#include <Interactor3D.h>
+#include <vector>
+#include <memory>
+
+class Interactor3D;
+class Block3D;
+class Grid3D;
+class Grid3DVisitor;
+enum class BlockType;
 
 class InteractorsHelper
 {
 public:
-   InteractorsHelper(Grid3DPtr grid, Grid3DVisitorPtr visitor);
+   InteractorsHelper(std::shared_ptr<Grid3D> grid, std::shared_ptr<Grid3DVisitor> visitor);
    ~InteractorsHelper();
-   void addInteractor(Interactor3DPtr interactor);
+
+   void addInteractor(std::shared_ptr<Interactor3D> interactor);
    void selectBlocks();
    void setBC();
+    void sendDomainDecompositionVisitor() const;
+
 protected:
    void deleteSolidBlocks();
-   void setTransBlocks();
+    void setBlocks(const std::shared_ptr<Interactor3D> interactor, BlockType type) const;
+    void setBcBlocks();
+
 private:
    void updateGrid();
-   std::vector<Interactor3DPtr> interactors;
-   Grid3DPtr grid;
-   std::vector<Block3DPtr> solidBlocks;
-   Grid3DVisitorPtr visitor;
+
+   std::vector<std::shared_ptr<Interactor3D> > interactors;
+   std::shared_ptr<Grid3D> grid;
+   std::vector<std::shared_ptr<Block3D> > solidBlocks;
+   std::shared_ptr<Grid3DVisitor> visitor;
 };
 
 #endif
diff --git a/source/VirtualFluidsCore/LBM/CompressibleCumulant2LBMKernel.cpp b/source/VirtualFluidsCore/LBM/CompressibleCumulant2LBMKernel.cpp
index 4a19222bf..d8c8ecfa8 100644
--- a/source/VirtualFluidsCore/LBM/CompressibleCumulant2LBMKernel.cpp
+++ b/source/VirtualFluidsCore/LBM/CompressibleCumulant2LBMKernel.cpp
@@ -4,6 +4,8 @@
 #include "D3Q27EsoTwist3DSplittedVector.h"
 #include <math.h>
 #include <omp.h>
+#include "DataSet3D.h"
+#include "LBMKernel.h"
 
 #define PROOF_CORRECTNESS
 
@@ -46,7 +48,7 @@ void CompressibleCumulant2LBMKernel::init()
 LBMKernelPtr CompressibleCumulant2LBMKernel::clone()
 {
    LBMKernelPtr kernel(new CompressibleCumulant2LBMKernel(nx1, nx2, nx3, parameter));
-   boost::dynamic_pointer_cast<CompressibleCumulant2LBMKernel>(kernel)->init();
+   std::dynamic_pointer_cast<CompressibleCumulant2LBMKernel>(kernel)->init();
    kernel->setCollisionFactor(this->collFactor);
    kernel->setBCProcessor(bcProcessor->clone(kernel));
    kernel->setWithForcing(withForcing);
@@ -58,20 +60,20 @@ LBMKernelPtr CompressibleCumulant2LBMKernel::clone()
    switch (parameter)
    {
    case NORMAL:
-      boost::dynamic_pointer_cast<CompressibleCumulant2LBMKernel>(kernel)->OxyyMxzz = 1.0;
+       std::dynamic_pointer_cast<CompressibleCumulant2LBMKernel>(kernel)->OxyyMxzz = 1.0;
       break;
    case MAGIC:
-      boost::dynamic_pointer_cast<CompressibleCumulant2LBMKernel>(kernel)->OxyyMxzz = 2.0 +(-collFactor);
+      std::dynamic_pointer_cast<CompressibleCumulant2LBMKernel>(kernel)->OxyyMxzz = 2.0 +(-collFactor);
       break;
    }
 
    if (bulkOmegaToOmega)
    {
-      boost::dynamic_pointer_cast<CompressibleCumulant2LBMKernel>(kernel)->OxxPyyPzz = collFactor;
+       std::dynamic_pointer_cast<CompressibleCumulant2LBMKernel>(kernel)->OxxPyyPzz = collFactor;
    }
    else
    {
-       boost::dynamic_pointer_cast<CompressibleCumulant2LBMKernel>(kernel)->OxxPyyPzz = one;
+       std::dynamic_pointer_cast<CompressibleCumulant2LBMKernel>(kernel)->OxxPyyPzz = one;
    }
    return kernel;
 }
@@ -112,9 +114,9 @@ void CompressibleCumulant2LBMKernel::collideAll()
    }
    /////////////////////////////////////
 
-   localDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getLocalDistributions();
-   nonLocalDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getNonLocalDistributions();
-   zeroDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getZeroDistributions();
+   localDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getLocalDistributions();
+   nonLocalDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getNonLocalDistributions();
+   zeroDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getZeroDistributions();
 
    BCArray3DPtr bcArray = this->getBCProcessor()->getBCArray();
 
@@ -1069,7 +1071,7 @@ void CompressibleCumulant2LBMKernel::collideAll()
    }
 }
 //////////////////////////////////////////////////////////////////////////
-double CompressibleCumulant2LBMKernel::getCallculationTime()
+double CompressibleCumulant2LBMKernel::getCalculationTime()
 {
    //return timer.getDuration();
    return timer.getTotalTime();
diff --git a/source/VirtualFluidsCore/LBM/CompressibleCumulant2LBMKernel.h b/source/VirtualFluidsCore/LBM/CompressibleCumulant2LBMKernel.h
index 5b720e695..44c051097 100644
--- a/source/VirtualFluidsCore/LBM/CompressibleCumulant2LBMKernel.h
+++ b/source/VirtualFluidsCore/LBM/CompressibleCumulant2LBMKernel.h
@@ -10,7 +10,7 @@
 #include "basics/container/CbArray3D.h"
 
 class CompressibleCumulant2LBMKernel;
-typedef boost::shared_ptr<CompressibleCumulant2LBMKernel> CompressibleCumulant2LBMKernelPtr;
+typedef std::shared_ptr<CompressibleCumulant2LBMKernel> CompressibleCumulant2LBMKernelPtr;
 
 //! \brief   compressible cumulant LBM kernel. 
 //! \details CFD solver that use Cascaded Cumulant Lattice Boltzmann method for D3Q27 model
@@ -31,7 +31,7 @@ public:
    virtual ~CompressibleCumulant2LBMKernel(void);
    virtual void calculate();
    virtual LBMKernelPtr clone();
-   double getCallculationTime();
+   double getCalculationTime() override;
    void setBulkOmegaToOmega(bool value);
 protected:
    friend class boost::serialization::access;
diff --git a/source/VirtualFluidsCore/LBM/CompressibleCumulantLBMKernel.cpp b/source/VirtualFluidsCore/LBM/CompressibleCumulantLBMKernel.cpp
index 2dc7ef899..1e123360e 100644
--- a/source/VirtualFluidsCore/LBM/CompressibleCumulantLBMKernel.cpp
+++ b/source/VirtualFluidsCore/LBM/CompressibleCumulantLBMKernel.cpp
@@ -1,1057 +1,1057 @@
-#include "CompressibleCumulantLBMKernel.h"
-#include "D3Q27System.h"
-#include "InterpolationProcessor.h"
-#include "D3Q27EsoTwist3DSplittedVector.h"
-#include <math.h>
-#include <omp.h>
-
-#define PROOF_CORRECTNESS
-
-//////////////////////////////////////////////////////////////////////////
-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) 
-{
-   this->nx1 = nx1;
-   this->nx2 = nx2;
-   this->nx3 = nx3;
-   this->parameter = p;
-   this->OxyyMxzz = 1.0;
-   this->compressible = true;
-   this->bulkOmegaToOmega = false;
-   this->OxxPyyPzz = 1.0;
-}
-//////////////////////////////////////////////////////////////////////////
-CompressibleCumulantLBMKernel::~CompressibleCumulantLBMKernel(void)
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-void CompressibleCumulantLBMKernel::init()
-{
-   DistributionArray3DPtr d(new D3Q27EsoTwist3DSplittedVector(nx1+2, nx2+2, nx3+2, -999.0));
-   dataSet->setFdistributions(d);
-}
-//////////////////////////////////////////////////////////////////////////
-LBMKernelPtr CompressibleCumulantLBMKernel::clone()
-{
-   LBMKernelPtr kernel(new CompressibleCumulantLBMKernel(nx1, nx2, nx3, parameter));
-   boost::dynamic_pointer_cast<CompressibleCumulantLBMKernel>(kernel)->init();
-   kernel->setCollisionFactor(this->collFactor);
-   kernel->setBCProcessor(bcProcessor->clone(kernel));
-   kernel->setWithForcing(withForcing);
-   kernel->setForcingX1(muForcingX1);
-   kernel->setForcingX2(muForcingX2);
-   kernel->setForcingX3(muForcingX3);
-   kernel->setIndex(ix1, ix2, ix3);
-   kernel->setDeltaT(deltaT);
-   switch (parameter)
-   {
-   case NORMAL:
-      boost::dynamic_pointer_cast<CompressibleCumulantLBMKernel>(kernel)->OxyyMxzz = 1.0;
-      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;
-}
-//////////////////////////////////////////////////////////////////////////
-void CompressibleCumulantLBMKernel::calculate()
-{
-   timer.resetAndStart();
-   collideAll();
-   timer.stop();
-}
-//////////////////////////////////////////////////////////////////////////
-void CompressibleCumulantLBMKernel::collideAll()
-{
-   using namespace D3Q27System;
-
-   //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);
-
-      muDeltaT = deltaT;
-
-      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);
-
-      LBMReal forcingX1 = 0;
-      LBMReal forcingX2 = 0;
-      LBMReal forcingX3 = 0;
-   }
-   /////////////////////////////////////
-
-   localDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getLocalDistributions();
-   nonLocalDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getNonLocalDistributions();
-   zeroDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getZeroDistributions();
-
-   BCArray3DPtr bcArray = this->getBCProcessor()->getBCArray();
-
-   const int bcArrayMaxX1 = (int)bcArray->getNX1();
-   const int bcArrayMaxX2 = (int)bcArray->getNX2();
-   const int bcArrayMaxX3 = (int)bcArray->getNX3();
-
-   int minX1 = ghostLayerWidth;
-   int minX2 = ghostLayerWidth;
-   int minX3 = ghostLayerWidth;
-   int maxX1 = bcArrayMaxX1-ghostLayerWidth;
-   int maxX2 = bcArrayMaxX2-ghostLayerWidth;
-   int maxX3 = bcArrayMaxX3-ghostLayerWidth;
-
-   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++)
-      {
-         for (int x2 = minX2; x2 < maxX2; x2++)
-         {
-            for (int x1 = minX1; x1 < maxX1; x1++)
-            {
-               if (!bcArray->isSolid(x1, x2, x3) && !bcArray->isUndefined(x1, x2, x3))
-               {
-                  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)
-                  {
-                     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;
-
-                  //////////////////////////////////////////////////////////////////////////
-         // 			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
-                  //////////////////////////////////////////////////////////////////////////
-                  //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
-                  //////////////////////////////////////////////////////////////////////////
-#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;
-#ifdef SINGLEPRECISION
-                  if (dif > 10.0E-7 || dif < -10.0E-7)
-#else
-                  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);
-                  }
-#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;
-                  //////////////////////////////////////////////////////////////////////////
-
-               }
-            }
-         }
-      }
-
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-double CompressibleCumulantLBMKernel::getCallculationTime()
-{
-   //return timer.getDuration();
-   return timer.getTotalTime();
-}
-//////////////////////////////////////////////////////////////////////////
-void CompressibleCumulantLBMKernel::setBulkOmegaToOmega(bool value)
-{
-   bulkOmegaToOmega = value;
-}
+#include "CompressibleCumulantLBMKernel.h"
+#include "D3Q27System.h"
+#include "InterpolationProcessor.h"
+#include "D3Q27EsoTwist3DSplittedVector.h"
+#include <math.h>
+//#include <omp.h>
+#include "DataSet3D.h"
+#define PROOF_CORRECTNESS
+
+//////////////////////////////////////////////////////////////////////////
+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) 
+{
+   this->nx1 = nx1;
+   this->nx2 = nx2;
+   this->nx3 = nx3;
+   this->parameter = p;
+   this->OxyyMxzz = 1.0;
+   this->compressible = true;
+   this->bulkOmegaToOmega = false;
+   this->OxxPyyPzz = 1.0;
+}
+//////////////////////////////////////////////////////////////////////////
+CompressibleCumulantLBMKernel::~CompressibleCumulantLBMKernel(void)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void CompressibleCumulantLBMKernel::init()
+{
+   DistributionArray3DPtr d(new D3Q27EsoTwist3DSplittedVector(nx1+2, nx2+2, nx3+2, -999.0));
+   dataSet->setFdistributions(d);
+}
+//////////////////////////////////////////////////////////////////////////
+LBMKernelPtr CompressibleCumulantLBMKernel::clone()
+{
+   LBMKernelPtr kernel(new CompressibleCumulantLBMKernel(nx1, nx2, nx3, parameter));
+   std::dynamic_pointer_cast<CompressibleCumulantLBMKernel>(kernel)->init();
+   kernel->setCollisionFactor(this->collFactor);
+   kernel->setBCProcessor(bcProcessor->clone(kernel));
+   kernel->setWithForcing(withForcing);
+   kernel->setForcingX1(muForcingX1);
+   kernel->setForcingX2(muForcingX2);
+   kernel->setForcingX3(muForcingX3);
+   kernel->setIndex(ix1, ix2, ix3);
+   kernel->setDeltaT(deltaT);
+   switch (parameter)
+   {
+   case NORMAL:
+      std::dynamic_pointer_cast<CompressibleCumulantLBMKernel>(kernel)->OxyyMxzz = 1.0;
+      break;
+   case MAGIC:
+      std::dynamic_pointer_cast<CompressibleCumulantLBMKernel>(kernel)->OxyyMxzz = 2.0 +(-collFactor);
+      break;
+   }
+
+   if (bulkOmegaToOmega)
+   {
+      std::dynamic_pointer_cast<CompressibleCumulantLBMKernel>(kernel)->OxxPyyPzz = collFactor;
+   }
+   else
+   {
+       std::dynamic_pointer_cast<CompressibleCumulantLBMKernel>(kernel)->OxxPyyPzz = one;
+   }
+   return kernel;
+}
+//////////////////////////////////////////////////////////////////////////
+void CompressibleCumulantLBMKernel::calculate()
+{
+   timer.resetAndStart();
+   collideAll();
+   timer.stop();
+}
+//////////////////////////////////////////////////////////////////////////
+void CompressibleCumulantLBMKernel::collideAll()
+{
+   using namespace D3Q27System;
+
+   //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);
+
+      muDeltaT = deltaT;
+
+      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);
+
+      LBMReal forcingX1 = 0;
+      LBMReal forcingX2 = 0;
+      LBMReal forcingX3 = 0;
+   }
+   /////////////////////////////////////
+
+   localDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getLocalDistributions();
+   nonLocalDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getNonLocalDistributions();
+   zeroDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getZeroDistributions();
+
+   BCArray3DPtr bcArray = this->getBCProcessor()->getBCArray();
+
+   const int bcArrayMaxX1 = (int)bcArray->getNX1();
+   const int bcArrayMaxX2 = (int)bcArray->getNX2();
+   const int bcArrayMaxX3 = (int)bcArray->getNX3();
+
+   int minX1 = ghostLayerWidth;
+   int minX2 = ghostLayerWidth;
+   int minX3 = ghostLayerWidth;
+   int maxX1 = bcArrayMaxX1-ghostLayerWidth;
+   int maxX2 = bcArrayMaxX2-ghostLayerWidth;
+   int maxX3 = bcArrayMaxX3-ghostLayerWidth;
+
+   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++)
+      {
+         for (int x2 = minX2; x2 < maxX2; x2++)
+         {
+            for (int x1 = minX1; x1 < maxX1; x1++)
+            {
+               if (!bcArray->isSolid(x1, x2, x3) && !bcArray->isUndefined(x1, x2, x3))
+               {
+                  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)
+                  {
+                     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;
+
+                  //////////////////////////////////////////////////////////////////////////
+         // 			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
+                  //////////////////////////////////////////////////////////////////////////
+                  //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
+                  //////////////////////////////////////////////////////////////////////////
+#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;
+#ifdef SINGLEPRECISION
+                  if (dif > 10.0E-7 || dif < -10.0E-7)
+#else
+                  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);
+                  }
+#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;
+                  //////////////////////////////////////////////////////////////////////////
+
+               }
+            }
+         }
+      }
+
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+double CompressibleCumulantLBMKernel::getCalculationTime()
+{
+   //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 aa0f6c109..50d6ce9b6 100644
--- a/source/VirtualFluidsCore/LBM/CompressibleCumulantLBMKernel.h
+++ b/source/VirtualFluidsCore/LBM/CompressibleCumulantLBMKernel.h
@@ -10,7 +10,7 @@
 #include "basics/container/CbArray3D.h"
 
 class CompressibleCumulantLBMKernel;
-typedef boost::shared_ptr<CompressibleCumulantLBMKernel> CompressibleCumulantLBMKernelPtr;
+typedef std::shared_ptr<CompressibleCumulantLBMKernel> CompressibleCumulantLBMKernelPtr;
 
 //! \brief   compressible cumulant LBM kernel. 
 //! \details CFD solver that use Cascaded Cumulant Lattice Boltzmann method for D3Q27 model
@@ -31,7 +31,7 @@ public:
    virtual ~CompressibleCumulantLBMKernel(void);
    virtual void calculate();
    virtual LBMKernelPtr clone();
-   double getCallculationTime();
+   double getCalculationTime();
    void setBulkOmegaToOmega(bool value);
 protected:
    friend class boost::serialization::access;
diff --git a/source/VirtualFluidsCore/LBM/CompressibleOffsetInterpolationProcessor.cpp b/source/VirtualFluidsCore/LBM/CompressibleOffsetInterpolationProcessor.cpp
index cf2263f92..48c6356ae 100644
--- a/source/VirtualFluidsCore/LBM/CompressibleOffsetInterpolationProcessor.cpp
+++ b/source/VirtualFluidsCore/LBM/CompressibleOffsetInterpolationProcessor.cpp
@@ -1,7 +1,7 @@
 #include "CompressibleOffsetInterpolationProcessor.h"
 #include "D3Q27System.h"
 
-#include <boost/foreach.hpp>
+
 
 CompressibleOffsetInterpolationProcessor::CompressibleOffsetInterpolationProcessor()
    : omegaC(0.0), omegaF(0.0)
@@ -24,8 +24,8 @@ CompressibleOffsetInterpolationProcessor::~CompressibleOffsetInterpolationProces
 InterpolationProcessorPtr CompressibleOffsetInterpolationProcessor::clone()
 {
    InterpolationProcessorPtr iproc = InterpolationProcessorPtr (new CompressibleOffsetInterpolationProcessor(this->omegaC, this->omegaF));
-   //boost::dynamic_pointer_cast<D3Q27IncompressibleOffsetInterpolationProcessor>(iproc)->forcingC = forcingC;
-   //boost::dynamic_pointer_cast<D3Q27IncompressibleOffsetInterpolationProcessor>(iproc)->forcingF = forcingF;
+   //std::dynamic_pointer_cast<D3Q27IncompressibleOffsetInterpolationProcessor>(iproc)->forcingC = forcingC;
+   //std::dynamic_pointer_cast<D3Q27IncompressibleOffsetInterpolationProcessor>(iproc)->forcingF = forcingF;
    return iproc;
 }
 //////////////////////////////////////////////////////////////////////////
diff --git a/source/VirtualFluidsCore/LBM/CompressibleOffsetInterpolationProcessor.h b/source/VirtualFluidsCore/LBM/CompressibleOffsetInterpolationProcessor.h
index 4f8e4d5d0..fd48f9073 100644
--- a/source/VirtualFluidsCore/LBM/CompressibleOffsetInterpolationProcessor.h
+++ b/source/VirtualFluidsCore/LBM/CompressibleOffsetInterpolationProcessor.h
@@ -10,7 +10,7 @@
 //////////////////////////////////////////////////////////////////////////
 
 class CompressibleOffsetInterpolationProcessor;
-typedef boost::shared_ptr<CompressibleOffsetInterpolationProcessor> CompressibleOffsetInterpolationProcessorPtr;
+typedef std::shared_ptr<CompressibleOffsetInterpolationProcessor> CompressibleOffsetInterpolationProcessorPtr;
 
 class CompressibleOffsetInterpolationProcessor : public InterpolationProcessor
 {
diff --git a/source/VirtualFluidsCore/LBM/CompressibleOffsetMomentsInterpolationProcessor.cpp b/source/VirtualFluidsCore/LBM/CompressibleOffsetMomentsInterpolationProcessor.cpp
index dc81684e5..5078ecc09 100644
--- a/source/VirtualFluidsCore/LBM/CompressibleOffsetMomentsInterpolationProcessor.cpp
+++ b/source/VirtualFluidsCore/LBM/CompressibleOffsetMomentsInterpolationProcessor.cpp
@@ -1,7 +1,7 @@
 #include "CompressibleOffsetMomentsInterpolationProcessor.h"
 #include "D3Q27System.h"
 
-#include <boost/foreach.hpp>
+
 
 CompressibleOffsetMomentsInterpolationProcessor::CompressibleOffsetMomentsInterpolationProcessor()
    : omegaC(0.0), omegaF(0.0)
@@ -29,13 +29,13 @@ 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;
+      std::dynamic_pointer_cast<CompressibleOffsetMomentsInterpolationProcessor>(iproc)->OxxPyyPzzC = omegaC;
+      std::dynamic_pointer_cast<CompressibleOffsetMomentsInterpolationProcessor>(iproc)->OxxPyyPzzF = omegaF;
    }
    else
    {
-      boost::dynamic_pointer_cast<CompressibleOffsetMomentsInterpolationProcessor>(iproc)->OxxPyyPzzC = one;
-      boost::dynamic_pointer_cast<CompressibleOffsetMomentsInterpolationProcessor>(iproc)->OxxPyyPzzF = one;
+      std::dynamic_pointer_cast<CompressibleOffsetMomentsInterpolationProcessor>(iproc)->OxxPyyPzzC = one;
+      std::dynamic_pointer_cast<CompressibleOffsetMomentsInterpolationProcessor>(iproc)->OxxPyyPzzF = one;
    }
    return iproc;
 }
@@ -489,32 +489,32 @@ void CompressibleOffsetMomentsInterpolationProcessor::calcInterpolatedNodeCF(LBM
    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 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
@@ -572,237 +572,237 @@ void CompressibleOffsetMomentsInterpolationProcessor::calcInterpolatedNodeCF(LBM
    ////////////////////////////////////////////////////////////////////////////////////
    //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;
+   // 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;
 }
 //////////////////////////////////////////////////////////////////////////
@@ -934,323 +934,323 @@ void CompressibleOffsetMomentsInterpolationProcessor::calcInterpolatedNodeFC(LBM
    //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 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 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;
+   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;
 }
 //////////////////////////////////////////////////////////////////////////
diff --git a/source/VirtualFluidsCore/LBM/CompressibleOffsetMomentsInterpolationProcessor.h b/source/VirtualFluidsCore/LBM/CompressibleOffsetMomentsInterpolationProcessor.h
index 09bf98119..5331e2b82 100644
--- a/source/VirtualFluidsCore/LBM/CompressibleOffsetMomentsInterpolationProcessor.h
+++ b/source/VirtualFluidsCore/LBM/CompressibleOffsetMomentsInterpolationProcessor.h
@@ -10,7 +10,7 @@
 //////////////////////////////////////////////////////////////////////////
 
 class CompressibleOffsetMomentsInterpolationProcessor;
-typedef boost::shared_ptr<CompressibleOffsetMomentsInterpolationProcessor> CompressibleOffsetMomentsInterpolationProcessorPtr;
+typedef std::shared_ptr<CompressibleOffsetMomentsInterpolationProcessor> CompressibleOffsetMomentsInterpolationProcessorPtr;
 
 class CompressibleOffsetMomentsInterpolationProcessor : public InterpolationProcessor
 {
diff --git a/source/VirtualFluidsCore/LBM/D3Q27System.cpp b/source/VirtualFluidsCore/LBM/D3Q27System.cpp
index 99b6e5b54..ef96b2dc9 100644
--- a/source/VirtualFluidsCore/LBM/D3Q27System.cpp
+++ b/source/VirtualFluidsCore/LBM/D3Q27System.cpp
@@ -1,146 +1,195 @@
 #include "D3Q27System.h"
 namespace D3Q27System
 {
-   //index             0   1   2   3   4   5  6   7   8    9  10  11  12  13  14  15  16  17  18//falsch
-   //f:              ZERO, E,  W,  N,  S,  T,  B, NE, SW, SE, NW, TE, BW, BE, TW, TN, BS, BN, TS, TNE TNW TSE TSW BNE BNW BSE BSW
-   //const int EX1[] = { 0,  1, -1,  0,  0,  0,  0,  1, -1,  1, -1,  1, -1,  1, -1,  0,  0,  0,  0,  1, -1,  1, -1,  1, -1,  1, -1 };
-   //const int EX2[] = { 0,  0,  0,  1, -1,  0,  0,  1, -1, -1,  1,  0,  0,  0,  0,  1, -1,  1, -1,  1,  1, -1, -1,  1,  1, -1, -1 };
-   //const int EX3[] = { 0,  0,  0,  0,  0,  1, -1,  0,  0,  0,  0,  1, -1, -1,  1,  1, -1, -1,  1,  1,  1,  1,  1, -1, -1, -1, -1 };
-
-   //index             0   1   2   3   4   5  6   7   8    9  10  11  12  13  14  15  16  17  18
-   //f:                E,  W,  N,  S,  T,  B, NE, SW, SE, NW, TE, BW, BE, TW, TN, BS, BN, TS, TNE TNW TSE TSW BNE BNW BSE BSW
-   const int DX1[] = { 1, -1,  0,  0,  0,  0,  1, -1,  1, -1,  1, -1,  1, -1,  0,  0,  0,  0,  1, -1,  1, -1,  1, -1,  1, -1 };
-   const int DX2[] = { 0,  0,  1, -1,  0,  0,  1, -1, -1,  1,  0,  0,  0,  0,  1, -1,  1, -1,  1,  1, -1, -1,  1,  1, -1, -1 };
-   const int DX3[] = { 0,  0,  0,  0,  1, -1,  0,  0,  0,  0,  1, -1, -1,  1,  1, -1, -1,  1,  1,  1,  1,  1, -1, -1, -1, -1 };
-
-   ////index                0   1   2   3   4   5  6   7   8    9  10  11  12  13  14  15  16  17  18
-   ////f:                   E,  W,  N,  S,  T,  B, NE, SW, SE, NW, TE, BW, BE, TW, TN, BS, BN, TS, TNE TNW TSE TSW BNE BNW BSE BSW
-   const double WEIGTH[] = { c2o27, c2o27,  c2o27,  c2o27,  c2o27,  c2o27,  c1o54, c1o54, c1o54, c1o54, c1o54, c1o54, c1o54, c1o54, c1o54, c1o54, c1o54, c1o54, c1o216, c1o216, c1o216, c1o216, c1o216, c1o216, c1o216, c1o216 , c8o27};
-  
-
-   const int INVDIR[] = { 
-                          INV_E,   
-                          INV_W,  
-                          INV_N,  
-                          INV_S,  
-                          INV_T,  
-                          INV_B,  
-                          INV_NE, 
-                          INV_SW, 
-                          INV_SE, 
-                          INV_NW,
-                          INV_TE, 
-                          INV_BW, 
-                          INV_BE, 
-                          INV_TW, 
-                          INV_TN, 
-                          INV_BS, 
-                          INV_BN, 
-                          INV_TS, 
-                          INV_TNE,
-                          INV_TNW,
-                          INV_TSE,
-                          INV_TSW,
-                          INV_BNE,
-                          INV_BNW,
-                          INV_BSE,
-                          INV_BSW    };
+    //index             0   1   2   3   4   5  6   7   8    9  10  11  12  13  14  15  16  17  18//falsch
+    //f:              ZERO, E,  W,  N,  S,  T,  B, NE, SW, SE, NW, TE, BW, BE, TW, TN, BS, BN, TS, TNE TNW TSE TSW BNE BNW BSE BSW
+    //const int EX1[] = { 0,  1, -1,  0,  0,  0,  0,  1, -1,  1, -1,  1, -1,  1, -1,  0,  0,  0,  0,  1, -1,  1, -1,  1, -1,  1, -1 };
+    //const int EX2[] = { 0,  0,  0,  1, -1,  0,  0,  1, -1, -1,  1,  0,  0,  0,  0,  1, -1,  1, -1,  1,  1, -1, -1,  1,  1, -1, -1 };
+    //const int EX3[] = { 0,  0,  0,  0,  0,  1, -1,  0,  0,  0,  0,  1, -1, -1,  1,  1, -1, -1,  1,  1,  1,  1,  1, -1, -1, -1, -1 };
+
+    //index             0   1   2   3   4   5  6   7   8    9  10  11  12  13  14  15  16  17  18
+    //f:                E,  W,  N,  S,  T,  B, NE, SW, SE, NW, TE, BW, BE, TW, TN, BS, BN, TS, TNE TNW TSE TSW BNE BNW BSE BSW
+    const int DX1[] = { 1, -1,  0,  0,  0,  0,  1, -1,  1, -1,  1, -1,  1, -1,  0,  0,  0,  0,  1, -1,  1, -1,  1, -1,  1, -1 };
+    const int DX2[] = { 0,  0,  1, -1,  0,  0,  1, -1, -1,  1,  0,  0,  0,  0,  1, -1,  1, -1,  1,  1, -1, -1,  1,  1, -1, -1 };
+    const int DX3[] = { 0,  0,  0,  0,  1, -1,  0,  0,  0,  0,  1, -1, -1,  1,  1, -1, -1,  1,  1,  1,  1,  1, -1, -1, -1, -1 };
+
+    ////index                0   1   2   3   4   5  6   7   8    9  10  11  12  13  14  15  16  17  18
+    ////f:                   E,  W,  N,  S,  T,  B, NE, SW, SE, NW, TE, BW, BE, TW, TN, BS, BN, TS, TNE TNW TSE TSW BNE BNW BSE BSW
+    const double WEIGTH[] = { c2o27, c2o27,  c2o27,  c2o27,  c2o27,  c2o27,  c1o54, c1o54, c1o54, c1o54, c1o54, c1o54, c1o54, c1o54, c1o54, c1o54, c1o54, c1o54, c1o216, c1o216, c1o216, c1o216, c1o216, c1o216, c1o216, c1o216 , c8o27 };
+
+
+    const int INVDIR[] = {
+                           INV_E,
+                           INV_W,
+                           INV_N,
+                           INV_S,
+                           INV_T,
+                           INV_B,
+                           INV_NE,
+                           INV_SW,
+                           INV_SE,
+                           INV_NW,
+                           INV_TE,
+                           INV_BW,
+                           INV_BE,
+                           INV_TW,
+                           INV_TN,
+                           INV_BS,
+                           INV_BN,
+                           INV_TS,
+                           INV_TNE,
+                           INV_TNW,
+                           INV_TSE,
+                           INV_TSW,
+                           INV_BNE,
+                           INV_BNW,
+                           INV_BSE,
+                           INV_BSW };
+
+
+    // The x,y,z component for each normalized direction
+    const double cNorm[3][ENDDIR] = {
+        {
+            double(DX1[0]), double(DX1[1]),
+            double(DX1[2]), double(DX1[3]),
+            double(DX1[4]), double(DX1[5]),
+            double(DX1[6]) / std::sqrt(double(2)), double(DX1[7]) / std::sqrt(double(2)),
+            double(DX1[8]) / std::sqrt(double(2)), double(DX1[9]) / std::sqrt(double(2)),
+            double(DX1[10]) / std::sqrt(double(2)), double(DX1[11]) / std::sqrt(double(2)),
+            double(DX1[12]) / std::sqrt(double(2)), double(DX1[13]) / std::sqrt(double(2)),
+            double(DX1[14]), double(DX1[15]),
+            double(DX1[16]), double(DX1[17]),
+            double(DX1[18]) / std::sqrt(double(3)), double(DX1[19]) / std::sqrt(double(3)),
+            double(DX1[20]) / std::sqrt(double(3)), double(DX1[21]) / std::sqrt(double(3)),
+            double(DX1[22]) / std::sqrt(double(3)), double(DX1[23]) / std::sqrt(double(3)),
+            double(DX1[24]) / std::sqrt(double(3)), double(DX1[25]) / std::sqrt(double(3))
+        },{
+            double(DX2[0]), double(DX2[1]),
+            double(DX2[2]), double(DX2[3]),
+            double(DX2[4]), double(DX2[5]),
+            double(DX2[6]) / std::sqrt(double(2)), double(DX2[7]) / std::sqrt(double(2)),
+            double(DX2[8]) / std::sqrt(double(2)), double(DX2[9]) / std::sqrt(double(2)),
+            double(DX2[10]), double(DX2[11]),
+            double(DX2[12]), double(DX2[13]),
+            double(DX2[14]) / std::sqrt(double(2)), double(DX2[15]) / std::sqrt(double(2)),
+            double(DX2[16]) / std::sqrt(double(2)), double(DX2[17]) / std::sqrt(double(2)),
+            double(DX2[18]) / std::sqrt(double(3)), double(DX2[19]) / std::sqrt(double(3)),
+            double(DX2[20]) / std::sqrt(double(3)), double(DX2[21]) / std::sqrt(double(3)),
+            double(DX2[22]) / std::sqrt(double(3)), double(DX2[23]) / std::sqrt(double(3)),
+            double(DX2[24]) / std::sqrt(double(3)), double(DX2[25]) / std::sqrt(double(3))
+        },{
+            double(DX3[0]), double(DX3[1]),
+            double(DX3[2]), double(DX3[3]),
+            double(DX3[4]), double(DX3[5]),
+            double(DX3[6]), double(DX3[7]),
+            double(DX3[8]), double(DX3[9]),
+            double(DX3[10]) / std::sqrt(double(2)), double(DX3[11]) / std::sqrt(double(2)),
+            double(DX3[12]) / std::sqrt(double(2)), double(DX3[13]) / std::sqrt(double(2)),
+            double(DX3[14]) / std::sqrt(double(2)), double(DX3[15]) / std::sqrt(double(2)),
+            double(DX3[16]) / std::sqrt(double(2)), double(DX3[17]) / std::sqrt(double(2)),
+            double(DX3[18]) / std::sqrt(double(3)), double(DX3[19]) / std::sqrt(double(3)),
+            double(DX3[20]) / std::sqrt(double(3)), double(DX3[21]) / std::sqrt(double(3)),
+            double(DX3[22]) / std::sqrt(double(3)), double(DX3[23]) / std::sqrt(double(3)),
+            double(DX3[24]) / std::sqrt(double(3)), double(DX3[25]) / std::sqrt(double(3))
+        }
+    };
+
 }
 
-    //const int FSTARTDIR = 0;
-    //const int FENDDIR   = 25;   //D3Q27
-
-    //const int STARTF = 0;
-    //const int ENDF   = 26;   //D3Q27
-
-    //const int EX1[ENDF+1];
-    //const int EX2[ENDF+1];
-    //const int EX3[ENDF+1];
-
-    //const int STARTDIR = 0;
-    //const int ENDDIR   = 26; //alle geometrischen richtungen
-
-    //const int DX1[ENDDIR+1];
-    //const int DX2[ENDDIR+1];
-    //const int DX3[ENDDIR+1];
-
-
-    //const int E    /*f1 */ = 0;
-    //const int W    /*f2 */ = 1;
-    //const int N    /*f3 */ = 2;
-    //const int S    /*f4 */ = 3;
-    //const int T    /*f5 */ = 4;
-    //const int B    /*f6 */ = 5;
-    //const int NE   /*f7 */ = 6;
-    //const int SW   /*f8 */ = 7;
-    //const int SE   /*f9 */ = 8;
-    //const int NW   /*f10*/ = 9;
-    //const int TE   /*f11*/ = 10;
-    //const int BW   /*f12*/ = 11;
-    //const int BE   /*f13*/ = 12;
-    //const int TW   /*f14*/ = 13;
-    //const int TN   /*f15*/ = 14;
-    //const int BS   /*f16*/ = 15;
-    //const int BN   /*f17*/ = 16;
-    //const int TS   /*f18*/ = 17;
-    //const int TNE          = 18;
-    //const int TNW          = 19;
-    //const int TSE          = 20;
-    //const int TSW          = 21;
-    //const int BNE          = 22;
-    //const int BNW          = 23;
-    //const int BSE          = 24;
-    //const int BSW          = 25;
-    //const int ZERO /*f0 */ = 26;
-
-    //const int INV_E   = W;  
-    //const int INV_W   = E;  
-    //const int INV_N   = S;  
-    //const int INV_S   = N;  
-    //const int INV_T   = B;  
-    //const int INV_B   = T;  
-    //const int INV_NE  = SW; 
-    //const int INV_SW  = NE; 
-    //const int INV_SE  = NW; 
-    //const int INV_NW  = SE; 
-    //const int INV_TE  = BW; 
-    //const int INV_BW  = TE; 
-    //const int INV_BE  = TW; 
-    //const int INV_TW  = BE; 
-    //const int INV_TN  = BS; 
-    //const int INV_BS  = TN; 
-    //const int INV_BN  = TS; 
-    //const int INV_TS  = BN; 
-    //const int INV_TNE = BSW;
-    //const int INV_TNW = BSE;
-    //const int INV_TSE = BNW;
-    //const int INV_TSW = BNE;
-    //const int INV_BNE = TSW;
-    //const int INV_BNW = TSE;
-    //const int INV_BSE = TNW;
-    //const int INV_BSW = TNE;
-
-    //const int INVDIR[ENDDIR+1];
-
-    //const int M_RHO     = 0;  
-    //const int M_EN      = 1;  
-    //const int M_EPS     = 2;  
-    //const int M_JX1     = 3;  
-    //const int M_QX1     = 4;  
-    //const int M_JX2     = 5;  
-    //const int M_QX2     = 6;  
-    //const int M_JX3     = 7;  
-    //const int M_QX3     = 8;  
-    //const int M_3PX1X1  = 9;  
-    //const int M_3PIX1X1 = 10; 
-    //const int M_PWW     = 11; 
-    //const int M_PIWW    = 12; 
-    //const int M_PX1X2   = 13; 
-    //const int M_PX2X3   = 14; 
-    //const int M_PX1X3   = 15; 
-    //const int M_MX1     = 16; 
-    //const int M_MX2     = 17; 
-    //const int M_MX3     = 18; 
-
-    //const int STARTM = 0;
-    //const int ENDM   = 18;   //D3Q27
+//const int FSTARTDIR = 0;
+//const int FENDDIR   = 25;   //D3Q27
+
+//const int STARTF = 0;
+//const int ENDF   = 26;   //D3Q27
+
+//const int EX1[ENDF+1];
+//const int EX2[ENDF+1];
+//const int EX3[ENDF+1];
+
+//const int STARTDIR = 0;
+//const int ENDDIR   = 26; //alle geometrischen richtungen
+
+//const int DX1[ENDDIR+1];
+//const int DX2[ENDDIR+1];
+//const int DX3[ENDDIR+1];
+
+
+//const int E    /*f1 */ = 0;
+//const int W    /*f2 */ = 1;
+//const int N    /*f3 */ = 2;
+//const int S    /*f4 */ = 3;
+//const int T    /*f5 */ = 4;
+//const int B    /*f6 */ = 5;
+//const int NE   /*f7 */ = 6;
+//const int SW   /*f8 */ = 7;
+//const int SE   /*f9 */ = 8;
+//const int NW   /*f10*/ = 9;
+//const int TE   /*f11*/ = 10;
+//const int BW   /*f12*/ = 11;
+//const int BE   /*f13*/ = 12;
+//const int TW   /*f14*/ = 13;
+//const int TN   /*f15*/ = 14;
+//const int BS   /*f16*/ = 15;
+//const int BN   /*f17*/ = 16;
+//const int TS   /*f18*/ = 17;
+//const int TNE          = 18;
+//const int TNW          = 19;
+//const int TSE          = 20;
+//const int TSW          = 21;
+//const int BNE          = 22;
+//const int BNW          = 23;
+//const int BSE          = 24;
+//const int BSW          = 25;
+//const int ZERO /*f0 */ = 26;
+
+//const int INV_E   = W;  
+//const int INV_W   = E;  
+//const int INV_N   = S;  
+//const int INV_S   = N;  
+//const int INV_T   = B;  
+//const int INV_B   = T;  
+//const int INV_NE  = SW; 
+//const int INV_SW  = NE; 
+//const int INV_SE  = NW; 
+//const int INV_NW  = SE; 
+//const int INV_TE  = BW; 
+//const int INV_BW  = TE; 
+//const int INV_BE  = TW; 
+//const int INV_TW  = BE; 
+//const int INV_TN  = BS; 
+//const int INV_BS  = TN; 
+//const int INV_BN  = TS; 
+//const int INV_TS  = BN; 
+//const int INV_TNE = BSW;
+//const int INV_TNW = BSE;
+//const int INV_TSE = BNW;
+//const int INV_TSW = BNE;
+//const int INV_BNE = TSW;
+//const int INV_BNW = TSE;
+//const int INV_BSE = TNW;
+//const int INV_BSW = TNE;
+
+//const int INVDIR[ENDDIR+1];
+
+//const int M_RHO     = 0;  
+//const int M_EN      = 1;  
+//const int M_EPS     = 2;  
+//const int M_JX1     = 3;  
+//const int M_QX1     = 4;  
+//const int M_JX2     = 5;  
+//const int M_QX2     = 6;  
+//const int M_JX3     = 7;  
+//const int M_QX3     = 8;  
+//const int M_3PX1X1  = 9;  
+//const int M_3PIX1X1 = 10; 
+//const int M_PWW     = 11; 
+//const int M_PIWW    = 12; 
+//const int M_PX1X2   = 13; 
+//const int M_PX2X3   = 14; 
+//const int M_PX1X3   = 15; 
+//const int M_MX1     = 16; 
+//const int M_MX2     = 17; 
+//const int M_MX3     = 18; 
+
+//const int STARTM = 0;
+//const int ENDM   = 18;   //D3Q27
diff --git a/source/VirtualFluidsCore/LBM/D3Q27System.h b/source/VirtualFluidsCore/LBM/D3Q27System.h
index 45fb79d7a..7e0d8f4f5 100644
--- a/source/VirtualFluidsCore/LBM/D3Q27System.h
+++ b/source/VirtualFluidsCore/LBM/D3Q27System.h
@@ -139,6 +139,8 @@ namespace D3Q27System
    extern const int DX2[ENDDIR+1];
    extern const int DX3[ENDDIR+1];
    extern const double WEIGTH[ENDDIR+1];
+
+   extern const double cNorm[3][ENDDIR];
    
    //static const int ZERO /*f0 */ = 0;
    //static const int E    /*f1 */ = 1;
diff --git a/source/VirtualFluidsCore/LBM/ILBMKernel.h b/source/VirtualFluidsCore/LBM/ILBMKernel.h
new file mode 100644
index 000000000..bcebbe941
--- /dev/null
+++ b/source/VirtualFluidsCore/LBM/ILBMKernel.h
@@ -0,0 +1,34 @@
+#ifndef I_LBMKERNEL_H
+#define I_LBMKERNEL_H
+
+#include <memory>
+
+
+class ILBMKernel;
+typedef std::shared_ptr<ILBMKernel> ILBMKernelPtr;
+
+class BCProcessor;
+class DataSet3D;
+
+class ILBMKernel
+{
+public:
+    virtual ~ILBMKernel() {};
+
+    virtual void calculate() = 0;
+    virtual double getCalculationTime() = 0;
+    virtual void swapDistributions() = 0;
+
+    virtual bool getCompressible() const = 0;
+    virtual std::shared_ptr<BCProcessor> getBCProcessor() const = 0;
+    virtual void setBCProcessor(std::shared_ptr<BCProcessor> bcProcessor) = 0;
+    virtual std::shared_ptr<DataSet3D> getDataSet() const = 0;
+    virtual double getCollisionFactor() const = 0;
+    virtual void setCollisionFactor(double collFactor) = 0;
+    virtual bool isInsideOfDomain(const int &x1, const int &x2, const int &x3) const = 0;
+    virtual int getGhostLayerWidth() const = 0;
+    virtual double getDeltaT() const = 0;
+    virtual bool getWithForcing() const = 0;
+};
+
+#endif
diff --git a/source/VirtualFluidsCore/LBM/IncompressibleCumulantLBMKernel.cpp b/source/VirtualFluidsCore/LBM/IncompressibleCumulantLBMKernel.cpp
index d8c4e04d3..1af8ad8c4 100644
--- a/source/VirtualFluidsCore/LBM/IncompressibleCumulantLBMKernel.cpp
+++ b/source/VirtualFluidsCore/LBM/IncompressibleCumulantLBMKernel.cpp
@@ -1,918 +1,919 @@
-#include "IncompressibleCumulantLBMKernel.h"
-#include "D3Q27System.h"
-#include "InterpolationProcessor.h"
-#include "D3Q27EsoTwist3DSplittedVector.h"
-#include <math.h>
-#include <omp.h>
-
-#define PROOF_CORRECTNESS
-
-//////////////////////////////////////////////////////////////////////////
-IncompressibleCumulantLBMKernel::IncompressibleCumulantLBMKernel()
-{
-   this->nx1 = 0;
-   this->nx2 = 0;
-   this->nx3 = 0;
-   this->parameter = NORMAL;
-   this->OxyyMxzz = 1.0;
-   this->compressible = false;
-}
-//////////////////////////////////////////////////////////////////////////
-IncompressibleCumulantLBMKernel::IncompressibleCumulantLBMKernel(int nx1, int nx2, int nx3, Parameter p) 
-{
-   this->nx1 = nx1;
-   this->nx2 = nx2;
-   this->nx3 = nx3;
-   parameter = p;
-   this->compressible = false;
-}
-//////////////////////////////////////////////////////////////////////////
-IncompressibleCumulantLBMKernel::~IncompressibleCumulantLBMKernel(void)
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-void IncompressibleCumulantLBMKernel::init()
-{
-   //DistributionArray3DPtr d(new D3Q27EsoTwist3DSplittedVector(nx1+ghostLayerWitdh*2, nx2+ghostLayerWitdh*2, nx3+ghostLayerWitdh*2, -999.0));
-   DistributionArray3DPtr d(new D3Q27EsoTwist3DSplittedVector(nx1+2, nx2+2, nx3+2, -999.0));
-   dataSet->setFdistributions(d);
-}
-//////////////////////////////////////////////////////////////////////////
-LBMKernelPtr IncompressibleCumulantLBMKernel::clone()
-{
-   LBMKernelPtr kernel(new IncompressibleCumulantLBMKernel(nx1, nx2, nx3, parameter));
-   boost::dynamic_pointer_cast<IncompressibleCumulantLBMKernel>(kernel)->init();
-   kernel->setCollisionFactor(this->collFactor);
-   kernel->setBCProcessor(bcProcessor->clone(kernel));
-   kernel->setWithForcing(withForcing);
-   kernel->setForcingX1(muForcingX1);
-   kernel->setForcingX2(muForcingX2);
-   kernel->setForcingX3(muForcingX3);
-   kernel->setIndex(ix1, ix2, ix3);
-   kernel->setDeltaT(deltaT);
-   switch (parameter)
-   {
-   case NORMAL:
-      boost::dynamic_pointer_cast<IncompressibleCumulantLBMKernel>(kernel)->OxyyMxzz = 1.0;
-   	break;
-   case MAGIC:
-      boost::dynamic_pointer_cast<IncompressibleCumulantLBMKernel>(kernel)->OxyyMxzz = 2.0 +(-collFactor);
-      break;
-   }
-   return kernel;
-}
-//////////////////////////////////////////////////////////////////////////
-void IncompressibleCumulantLBMKernel::calculate()
-{
-   timer.resetAndStart();
-   collideAll();
-   timer.stop();
-}
-//////////////////////////////////////////////////////////////////////////
-void IncompressibleCumulantLBMKernel::collideAll()
-{
-   using namespace D3Q27System;
-
-   //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);
-
-      muDeltaT = deltaT;
-
-      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);
-
-      LBMReal forcingX1 = 0;
-      LBMReal forcingX2 = 0;
-      LBMReal forcingX3 = 0;
-   }
-   /////////////////////////////////////
-
-   localDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getLocalDistributions();
-   nonLocalDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getNonLocalDistributions();
-   zeroDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getZeroDistributions();
-
-   BCArray3DPtr bcArray = this->getBCProcessor()->getBCArray();
-
-   const int bcArrayMaxX1 = (int)bcArray->getNX1();
-   const int bcArrayMaxX2 = (int)bcArray->getNX2();
-   const int bcArrayMaxX3 = (int)bcArray->getNX3();
-
-   int minX1 = ghostLayerWidth;
-   int minX2 = ghostLayerWidth;
-   int minX3 = ghostLayerWidth;
-   int maxX1 = bcArrayMaxX1-ghostLayerWidth;
-   int maxX2 = bcArrayMaxX2-ghostLayerWidth;
-   int maxX3 = bcArrayMaxX3-ghostLayerWidth;
-
-
-//#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++)
-   {
-      for(int x2 = minX2; x2 < maxX2; x2++)
-      {
-         for(int x1 = minX1; x1 < maxX1; x1++)
-         {
-            if(!bcArray->isSolid(x1,x2,x3) && !bcArray->isUndefined(x1,x2,x3))
-            {
-               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 m0, m1, m2;
-
-               LBMReal rho=(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 vvx    =((((mfccc-mfaaa) + (mfcac-mfaca)) + ((mfcaa-mfacc) + (mfcca-mfaac))) +
-                  (((mfcba-mfabc) + (mfcbc-mfaba)) + ((mfcab-mfacb) + (mfccb-mfaab))) +
-                  (mfcbb-mfabb));
-               LBMReal vvy    =((((mfccc-mfaaa) + (mfaca-mfcac)) + ((mfacc-mfcaa) + (mfcca-mfaac))) +
-                  (((mfbca-mfbac) + (mfbcc-mfbaa)) + ((mfacb-mfcab) + (mfccb-mfaab))) +
-                  (mfbcb-mfbab));
-               LBMReal vvz    =((((mfccc-mfaaa) + (mfcac-mfaca)) + ((mfacc-mfcaa) + (mfaac-mfcca))) +
-                  (((mfbac-mfbca) + (mfbcc-mfbaa)) + ((mfabc-mfcba) + (mfcbc-mfaba))) +
-                  (mfbbc-mfbba));
-
-               //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;
-
-               oMdrho=mfccc+mfaaa;
-               m0=mfaca+mfcac;
-               m1=mfacc+mfcaa;
-               m2=mfaac+mfcca;
-               oMdrho+=m0;
-               m1+=m2;
-               oMdrho+=m1;
-               m0=mfbac+mfbca;
-               m1=mfbaa+mfbcc;
-               m0+=m1;
-               m1=mfabc+mfcba;
-               m2=mfaba+mfcbc;
-               m1+=m2;
-               m0+=m1;
-               m1=mfacb+mfcab;
-               m2=mfaab+mfccb;
-               m1+=m2;
-               m0+=m1;
-               oMdrho+=m0;
-               m0=mfabb+mfcbb;
-               m1=mfbab+mfbcb;
-               m2=mfbba+mfbbc;
-               m0+=m1+m2;
-               m0+=mfbbb; //hat gefehlt
-               oMdrho = 1. - (oMdrho + m0);
-
-               LBMReal vx2;
-               LBMReal vy2;
-               LBMReal vz2;
-               vx2=vvx*vvx;
-               vy2=vvy*vvy;
-               vz2=vvz*vvz;
-               ////////////////////////////////////////////////////////////////////////////////////
-               LBMReal wadjust;
-               LBMReal qudricLimit = 0.01;
-               ////////////////////////////////////////////////////////////////////////////////////
-               //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 - 2. *   m1 * vvz + vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfaba  + mfabc;
-               m1    = mfabc  - mfaba;
-               m0    = m2          + mfabb;
-               mfaba = m0;
-               m0   += c1o9 * oMdrho;
-               mfabb = m1 -        m0 * vvz;
-               mfabc = m2 - 2. *   m1 * vvz + vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfaca  + mfacc;
-               m1    = mfacc  - mfaca;
-               m0    = m2          + mfacb;
-               mfaca = m0;
-               m0   += c1o36 * oMdrho;
-               mfacb = m1 -        m0 * vvz;
-               mfacc = m2 - 2. *   m1 * vvz + vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfbaa + mfbac;
-               m1    = mfbac - mfbaa;
-               m0    = m2          + mfbab;
-               mfbaa = m0;
-               m0   += c1o9 * oMdrho;
-               mfbab = m1 -        m0 * vvz;
-               mfbac = m2 - 2. *   m1 * vvz + vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfbba  + mfbbc;
-               m1    = mfbbc  - mfbba;
-               m0    = m2          + mfbbb;
-               mfbba = m0;
-               m0   += c4o9 * oMdrho;
-               mfbbb = m1 -        m0 * vvz;
-               mfbbc = m2 - 2. *   m1 * vvz + vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfbca  + mfbcc;
-               m1    = mfbcc  - mfbca;
-               m0    = m2          + mfbcb;
-               mfbca = m0;
-               m0   += c1o9 * oMdrho;
-               mfbcb = m1 -        m0 * vvz;
-               mfbcc = m2 - 2. *   m1 * vvz + vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfcaa + mfcac;
-               m1    = mfcac - mfcaa;
-               m0    = m2          + mfcab;
-               mfcaa = m0;
-               m0   += c1o36 * oMdrho;
-               mfcab = m1 -        m0 * vvz;
-               mfcac = m2 - 2. *   m1 * vvz + vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfcba  + mfcbc;
-               m1    = mfcbc  - mfcba;
-               m0    = m2          + mfcbb;
-               mfcba = m0;
-               m0   += c1o9 * oMdrho;
-               mfcbb = m1 -        m0 * vvz;
-               mfcbc = m2 - 2. *   m1 * vvz + vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfcca  + mfccc;
-               m1    = mfccc  - mfcca;
-               m0    = m2          + mfccb;
-               mfcca = m0;
-               m0   += c1o36 * oMdrho;
-               mfccb = m1 -        m0 * vvz;
-               mfccc = m2 - 2. *   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 - 2. *   m1 * vvy + vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfaab  + mfacb;
-               m1    = mfacb  - mfaab;
-               m0    = m2          + mfabb;
-               mfaab = m0;
-               mfabb = m1 -        m0 * vvy;
-               mfacb = m2 - 2. *   m1 * vvy + vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfaac  + mfacc;
-               m1    = mfacc  - mfaac;
-               m0    = m2          + mfabc;
-               mfaac = m0;
-               m0   += c1o18 * oMdrho;
-               mfabc = m1 -        m0 * vvy;
-               mfacc = m2 - 2. *   m1 * vvy + vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfbaa + mfbca;
-               m1    = mfbca - mfbaa;
-               m0    = m2          + mfbba;
-               mfbaa = m0;
-               m0   += c2o3 * oMdrho;
-               mfbba = m1 -        m0 * vvy;
-               mfbca = m2 - 2. *   m1 * vvy + vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfbab  + mfbcb;
-               m1    = mfbcb  - mfbab;
-               m0    = m2          + mfbbb;
-               mfbab = m0;
-               mfbbb = m1 -        m0 * vvy;
-               mfbcb = m2 - 2. *   m1 * vvy + vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfbac  + mfbcc;
-               m1    = mfbcc  - mfbac;
-               m0    = m2          + mfbbc;
-               mfbac = m0;
-               m0   += c2o9 * oMdrho;
-               mfbbc = m1 -        m0 * vvy;
-               mfbcc = m2 - 2. *   m1 * vvy + vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfcaa + mfcca;
-               m1    = mfcca - mfcaa;
-               m0    = m2          + mfcba;
-               mfcaa = m0;
-               m0   += c1o6 * oMdrho;
-               mfcba = m1 -        m0 * vvy;
-               mfcca = m2 - 2. *   m1 * vvy + vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfcab  + mfccb;
-               m1    = mfccb  - mfcab;
-               m0    = m2          + mfcbb;
-               mfcab = m0;
-               mfcbb = m1 -        m0 * vvy;
-               mfccb = m2 - 2. *   m1 * vvy + vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfcac  + mfccc;
-               m1    = mfccc  - mfcac;
-               m0    = m2          + mfcbc;
-               mfcac = m0;
-               m0   += c1o18 * oMdrho;
-               mfcbc = m1 -        m0 * vvy;
-               mfccc = m2 - 2. *   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   += 1. * oMdrho;
-               mfbaa = m1 -        m0 * vvx;
-               mfcaa = m2 - 2. *   m1 * vvx + vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfaba  + mfcba;
-               m1    = mfcba  - mfaba;
-               m0    = m2          + mfbba;
-               mfaba = m0;
-               mfbba = m1 -        m0 * vvx;
-               mfcba = m2 - 2. *   m1 * vvx + vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfaca  + mfcca;
-               m1    = mfcca  - mfaca;
-               m0    = m2          + mfbca;
-               mfaca = m0;
-               m0   += c1o3 * oMdrho;
-               mfbca = m1 -        m0 * vvx;
-               mfcca = m2 - 2. *   m1 * vvx + vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfaab + mfcab;
-               m1    = mfcab - mfaab;
-               m0    = m2          + mfbab;
-               mfaab = m0;
-               mfbab = m1 -        m0 * vvx;
-               mfcab = m2 - 2. *   m1 * vvx + vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfabb  + mfcbb;
-               m1    = mfcbb  - mfabb;
-               m0    = m2          + mfbbb;
-               mfabb = m0;
-               mfbbb = m1 -        m0 * vvx;
-               mfcbb = m2 - 2. *   m1 * vvx + vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfacb  + mfccb;
-               m1    = mfccb  - mfacb;
-               m0    = m2          + mfbcb;
-               mfacb = m0;
-               mfbcb = m1 -        m0 * vvx;
-               mfccb = m2 - 2. *   m1 * vvx + vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfaac + mfcac;
-               m1    = mfcac - mfaac;
-               m0    = m2          + mfbac;
-               mfaac = m0;
-               m0   += c1o3 * oMdrho;
-               mfbac = m1 -        m0 * vvx;
-               mfcac = m2 - 2. *   m1 * vvx + vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfabc  + mfcbc;
-               m1    = mfcbc  - mfabc;
-               m0    = m2          + mfbbc;
-               mfabc = m0;
-               mfbbc = m1 -        m0 * vvx;
-               mfcbc = m2 - 2. *   m1 * vvx + vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfacc  + mfccc;
-               m1    = mfccc  - mfacc;
-               m0    = m2          + mfbcc;
-               mfacc = m0;
-               m0   += c1o9 * oMdrho;
-               mfbcc = m1 -        m0 * vvx;
-               mfccc = m2 - 2. *   m1 * vvx + vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               // Cumulants
-               ////////////////////////////////////////////////////////////////////////////////////
-               LBMReal OxxPyyPzz = 1.; //omega2 or bulk viscosity
-               LBMReal OxyyPxzz  = 1.;//-s9;//2+s9;//
-               //LBMReal OxyyMxzz  = 1.;//2+s9;//
-               LBMReal O4        = 1.;
-               LBMReal O5        = 1.;
-               LBMReal O6        = 1.;
-
-               //Cum 4.
-               //LBMReal CUMcbb = mfcbb - ((mfcaa + c1o3 * oMdrho) * mfabb + 2. * mfbba * mfbab); // till 18.05.2015
-               //LBMReal CUMbcb = mfbcb - ((mfaca + c1o3 * oMdrho) * mfbab + 2. * mfbba * mfabb); // till 18.05.2015
-               //LBMReal CUMbbc = mfbbc - ((mfaac + c1o3 * oMdrho) * mfbba + 2. * mfbab * mfabb); // till 18.05.2015
-
-               LBMReal CUMcbb = mfcbb - ((mfcaa + c1o3 ) * mfabb + 2. * mfbba * mfbab);
-               LBMReal CUMbcb = mfbcb - ((mfaca + c1o3 ) * mfbab + 2. * mfbba * mfabb);
-               LBMReal CUMbbc = mfbbc - ((mfaac + c1o3 ) * mfbba + 2. * mfbab * mfabb);
-
-               LBMReal CUMcca = mfcca - ((mfcaa * mfaca + 2. * mfbba * mfbba) + c1o3 * (mfcaa + mfaca) * oMdrho + c1o9*(oMdrho-1)*oMdrho);
-               LBMReal CUMcac = mfcac - ((mfcaa * mfaac + 2. * mfbab * mfbab) + c1o3 * (mfcaa + mfaac) * oMdrho + c1o9*(oMdrho-1)*oMdrho);
-               LBMReal CUMacc = mfacc - ((mfaac * mfaca + 2. * mfabb * mfabb) + c1o3 * (mfaac + mfaca) * oMdrho + c1o9*(oMdrho-1)*oMdrho);
-
-               //Cum 5.
-               LBMReal CUMbcc = mfbcc - (mfaac * mfbca + mfaca * mfbac + 4. * mfabb * mfbbb + 2. * (mfbab * mfacb + mfbba * mfabc)) - c1o3 * (mfbca + mfbac) * oMdrho;
-               LBMReal CUMcbc = mfcbc - (mfaac * mfcba + mfcaa * mfabc + 4. * mfbab * mfbbb + 2. * (mfabb * mfcab + mfbba * mfbac)) - c1o3 * (mfcba + mfabc) * oMdrho;
-               LBMReal CUMccb = mfccb - (mfcaa * mfacb + mfaca * mfcab + 4. * mfbba * mfbbb + 2. * (mfbab * mfbca + mfabb * mfcba)) - c1o3 * (mfacb + mfcab) * oMdrho;
-
-               //Cum 6.
-               LBMReal CUMccc = mfccc  +((-4. *  mfbbb * mfbbb 
-                  -       (mfcaa * mfacc + mfaca * mfcac + mfaac * mfcca)
-                  -  4. * (mfabb * mfcbb + mfbab * mfbcb + mfbba * mfbbc)
-                  -  2. * (mfbca * mfbac + mfcba * mfabc + mfcab * mfacb))
-                  +( 4. * (mfbab * mfbab * mfaca + mfabb * mfabb * mfcaa + mfbba * mfbba * mfaac)
-                  +  2. * (mfcaa * mfaca * mfaac)
-                  + 16. *  mfbba * mfbab * mfabb)
-                  - c1o3* (mfacc + mfcac + mfcca) * oMdrho  -c1o9*oMdrho*oMdrho
-                  - c1o9* (mfcaa + mfaca + mfaac) * oMdrho*(1.-2.* oMdrho)- c1o27* oMdrho * oMdrho*(-2.* oMdrho)
-                  +( 2. * (mfbab * mfbab + mfabb * mfabb + mfbba * mfbba)
-                  +       (mfaac * mfaca + mfaac * mfcaa + mfaca * mfcaa)) * c2o3*oMdrho) +c1o27*oMdrho;
-
-               //2.
-               // linear combinations
-               LBMReal mxxPyyPzz = mfcaa + mfaca + mfaac;
-               LBMReal mxxMyy    = mfcaa - mfaca;
-               LBMReal mxxMzz         = mfcaa - mfaac;
-
-               LBMReal dxux = -c1o2 * collFactor *(mxxMyy + mxxMzz) + c1o2 * OxxPyyPzz*(mfaaa - mxxPyyPzz);
-               LBMReal dyuy = dxux + collFactor * c3o2 * mxxMyy;
-               LBMReal dzuz = dxux + collFactor * c3o2 * mxxMzz;
-
-               //relax
-               mxxPyyPzz += OxxPyyPzz*(mfaaa  - mxxPyyPzz)- 3. * (1. - c1o2 * OxxPyyPzz) * (vx2 * dxux + vy2 * dyuy + vz2 * dzuz);
-               mxxMyy    += collFactor * (-mxxMyy) - 3. * (1. - c1o2 * collFactor) * (vx2 * dxux - vy2 * dyuy);
-               mxxMzz    += collFactor * (-mxxMzz) - 3. * (1. - c1o2 * collFactor) * (vx2 * dxux - vz2 * dzuz);
-
-               mfabb     += collFactor * (-mfabb);
-               mfbab     += collFactor * (-mfbab);
-               mfbba     += collFactor * (-mfbba);
-
-               // linear combinations back
-               mfcaa = c1o3 * (       mxxMyy +      mxxMzz + mxxPyyPzz);
-               mfaca = c1o3 * (-2. *  mxxMyy +      mxxMzz + mxxPyyPzz);
-               mfaac = c1o3 * (       mxxMyy - 2. * 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
-               wadjust    = OxyyMxzz+(1.-OxyyMxzz)*fabs(mfbbb)/(fabs(mfbbb)+qudricLimit);
-               mfbbb     += wadjust * (-mfbbb);
-               wadjust    = OxyyPxzz+(1.-OxyyPxzz)*fabs(mxxyPyzz)/(fabs(mxxyPyzz)+qudricLimit);
-               mxxyPyzz  += wadjust * (-mxxyPyzz);
-               wadjust    = OxyyMxzz+(1.-OxyyMxzz)*fabs(mxxyMyzz)/(fabs(mxxyMyzz)+qudricLimit);
-               mxxyMyzz  += wadjust * (-mxxyMyzz);
-               wadjust    = OxyyPxzz+(1.-OxyyPxzz)*fabs(mxxzPyyz)/(fabs(mxxzPyyz)+qudricLimit);
-               mxxzPyyz  += wadjust * (-mxxzPyyz);
-               wadjust    = OxyyMxzz+(1.-OxyyMxzz)*fabs(mxxzMyyz)/(fabs(mxxzMyyz)+qudricLimit);
-               mxxzMyyz  += wadjust * (-mxxzMyyz);
-               wadjust    = OxyyPxzz+(1.-OxyyPxzz)*fabs(mxyyPxzz)/(fabs(mxyyPxzz)+qudricLimit);
-               mxyyPxzz  += wadjust * (-mxyyPxzz);
-               wadjust    = OxyyMxzz+(1.-OxyyMxzz)*fabs(mxyyMxzz)/(fabs(mxyyMxzz)+qudricLimit);
-               mxyyMxzz  += wadjust * (-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.
-               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 * oMdrho) * mfabb + 2. * mfbba * mfbab); // till 18.05.2015
-               //mfbcb = CUMbcb + ((mfaca + c1o3 * oMdrho) * mfbab + 2. * mfbba * mfabb); // till 18.05.2015
-               //mfbbc = CUMbbc + ((mfaac + c1o3 * oMdrho) * mfbba + 2. * mfbab * mfabb); // till 18.05.2015
-
-               mfcbb = CUMcbb + ((mfcaa + c1o3 ) * mfabb + 2. * mfbba * mfbab);
-               mfbcb = CUMbcb + ((mfaca + c1o3 ) * mfbab + 2. * mfbba * mfabb);
-               mfbbc = CUMbbc + ((mfaac + c1o3 ) * mfbba + 2. * mfbab * mfabb);
-
-               mfcca = CUMcca + (mfcaa * mfaca + 2. * mfbba * mfbba) + c1o3 * (mfcaa + mfaca) * oMdrho + c1o9*(oMdrho-1)*oMdrho;
-               mfcac = CUMcac + (mfcaa * mfaac + 2. * mfbab * mfbab) + c1o3 * (mfcaa + mfaac) * oMdrho + c1o9*(oMdrho-1)*oMdrho;
-               mfacc = CUMacc + (mfaac * mfaca + 2. * mfabb * mfabb) + c1o3 * (mfaac + mfaca) * oMdrho + c1o9*(oMdrho-1)*oMdrho;
-
-               //5.
-               mfbcc = CUMbcc + (mfaac * mfbca + mfaca * mfbac + 4. * mfabb * mfbbb + 2. * (mfbab * mfacb + mfbba * mfabc)) + c1o3 * (mfbca + mfbac) * oMdrho;
-               mfcbc = CUMcbc + (mfaac * mfcba + mfcaa * mfabc + 4. * mfbab * mfbbb + 2. * (mfabb * mfcab + mfbba * mfbac)) + c1o3 * (mfcba + mfabc) * oMdrho;
-               mfccb = CUMccb + (mfcaa * mfacb + mfaca * mfcab + 4. * mfbba * mfbbb + 2. * (mfbab * mfbca + mfabb * mfcba)) + c1o3 * (mfacb + mfcab) * oMdrho;
-
-               //6.
-               mfccc = CUMccc  -((-4. *  mfbbb * mfbbb 
-                  -       (mfcaa * mfacc + mfaca * mfcac + mfaac * mfcca)
-                  -  4. * (mfabb * mfcbb + mfbac * mfbca + mfbba * mfbbc)
-                  -  2. * (mfbca * mfbac + mfcba * mfabc + mfcab * mfacb))
-                  +( 4. * (mfbab * mfbab * mfaca + mfabb * mfabb * mfcaa + mfbba * mfbba * mfaac)
-                  +  2. * (mfcaa * mfaca * mfaac)
-                  + 16. *  mfbba * mfbab * mfabb)
-                  - c1o3* (mfacc + mfcac + mfcca) * oMdrho  -c1o9*oMdrho*oMdrho
-                  - c1o9* (mfcaa + mfaca + mfaac) * oMdrho*(1.-2.* oMdrho)- c1o27* oMdrho * oMdrho*(-2.* oMdrho)
-                  +( 2. * (mfbab * mfbab + mfabb * mfabb + mfbba * mfbba)
-                  +       (mfaac * mfaca + mfaac * mfcaa + mfaca * mfcaa)) * c2o3*oMdrho) -c1o27*oMdrho;
-
-               ////////////////////////////////////////////////////////////////////////////////////
-               //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 + 1. * oMdrho) * (     vz2 - vvz) * c1o2;
-               m1 = -mfaac        - 2. * mfaab *  vvz         +  mfaaa                * (1. - vz2)              - 1. * oMdrho * vz2;
-               m2 =  mfaac * c1o2 +      mfaab * (vvz + c1o2) + (mfaaa + 1. * oMdrho) * (     vz2 + vvz) * c1o2;
-               mfaaa = m0;
-               mfaab = m1;
-               mfaac = m2;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m0 =  mfabc * c1o2 +      mfabb * (vvz - c1o2) + mfaba * (     vz2 - vvz) * c1o2;
-               m1 = -mfabc        - 2. * mfabb *  vvz         + mfaba * (1. - 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        - 2. * mfacb *  vvz         +  mfaca                  * (1. - 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        - 2. * mfbab *  vvz         + mfbaa * (1. - 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        - 2. * mfbbb *  vvz         + mfbba * (1. - 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        - 2. * mfbcb *  vvz         + mfbca * (1. - 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        - 2. * mfcab *  vvz         +  mfcaa                  * (1. - 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        - 2. * mfcbb *  vvz         + mfcba * (1. - 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        - 2. * mfccb *  vvz         +  mfcca                  * (1. - 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        - 2. * mfaba *  vvy         +  mfaaa                  * (1. - 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        - 2. * mfabb *  vvy         +  mfaab                  * (1. - 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        - 2. * mfabc *  vvy         +  mfaac                  * (1. - 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        - 2. * mfbba *  vvy         + mfbaa * (1. - 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        - 2. * mfbbb *  vvy         + mfbab * (1. - 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        - 2. * mfbbc *  vvy         + mfbac * (1. - 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        - 2. * mfcba *  vvy         +  mfcaa                   * (1. - 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        - 2. * mfcbb *  vvy         +  mfcab                  * (1. - 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        - 2. * mfcbc *  vvy         +  mfcac                   * (1. - 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        - 2. * mfbaa *  vvx         +  mfaaa                   * (1. - 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        - 2. * mfbba *  vvx         +  mfaba                  * (1. - 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        - 2. * mfbca *  vvx         +  mfaca                   * (1. - 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        - 2. * mfbab *  vvx         +  mfaab                  * (1. - 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        - 2. * mfbbb *  vvx         +  mfabb                  * (1. - 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        - 2. * mfbcb *  vvx         +  mfacb                  * (1. - 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        - 2. * mfbac *  vvx         +  mfaac                   * (1. - 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        - 2. * mfbbc *  vvx         +  mfabc                  * (1. - 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        - 2. * mfbcc *  vvx         +  mfacc                   * (1. - 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 rho_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 = rho - rho_post;
-#ifdef SINGLEPRECISION
-               if(dif > 10.0E-7 || dif < -10.0E-7)
-#else
-               if(dif > 10.0E-15 || dif < -10.0E-15)
-#endif
-               {
-                  UB_THROW(UbException(UB_EXARGS,"rho="+UbSystem::toString(rho)+", rho_post="+UbSystem::toString(rho_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;
-               //////////////////////////////////////////////////////////////////////////
-
-            }
-         }
-      }
-   }
-
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-double IncompressibleCumulantLBMKernel::getCallculationTime()
-{
-   //return timer.getDuration();
-   return timer.getTotalTime();
-}
+#include "IncompressibleCumulantLBMKernel.h"
+#include "D3Q27System.h"
+#include "InterpolationProcessor.h"
+#include "D3Q27EsoTwist3DSplittedVector.h"
+#include "DataSet3D.h"
+#include <math.h>
+//#include <omp.h>
+
+#define PROOF_CORRECTNESS
+
+//////////////////////////////////////////////////////////////////////////
+IncompressibleCumulantLBMKernel::IncompressibleCumulantLBMKernel()
+{
+   this->nx1 = 0;
+   this->nx2 = 0;
+   this->nx3 = 0;
+   this->parameter = NORMAL;
+   this->OxyyMxzz = 1.0;
+   this->compressible = false;
+}
+//////////////////////////////////////////////////////////////////////////
+IncompressibleCumulantLBMKernel::IncompressibleCumulantLBMKernel(int nx1, int nx2, int nx3, Parameter p) 
+{
+   this->nx1 = nx1;
+   this->nx2 = nx2;
+   this->nx3 = nx3;
+   parameter = p;
+   this->compressible = false;
+}
+//////////////////////////////////////////////////////////////////////////
+IncompressibleCumulantLBMKernel::~IncompressibleCumulantLBMKernel(void)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void IncompressibleCumulantLBMKernel::init()
+{
+   //DistributionArray3DPtr d(new D3Q27EsoTwist3DSplittedVector(nx1+ghostLayerWitdh*2, nx2+ghostLayerWitdh*2, nx3+ghostLayerWitdh*2, -999.0));
+   DistributionArray3DPtr d(new D3Q27EsoTwist3DSplittedVector(nx1+2, nx2+2, nx3+2, -999.0));
+   dataSet->setFdistributions(d);
+}
+//////////////////////////////////////////////////////////////////////////
+LBMKernelPtr IncompressibleCumulantLBMKernel::clone()
+{
+   LBMKernelPtr kernel(new IncompressibleCumulantLBMKernel(nx1, nx2, nx3, parameter));
+   std::dynamic_pointer_cast<IncompressibleCumulantLBMKernel>(kernel)->init();
+   kernel->setCollisionFactor(this->collFactor);
+   kernel->setBCProcessor(bcProcessor->clone(kernel));
+   kernel->setWithForcing(withForcing);
+   kernel->setForcingX1(muForcingX1);
+   kernel->setForcingX2(muForcingX2);
+   kernel->setForcingX3(muForcingX3);
+   kernel->setIndex(ix1, ix2, ix3);
+   kernel->setDeltaT(deltaT);
+   switch (parameter)
+   {
+   case NORMAL:
+      std::dynamic_pointer_cast<IncompressibleCumulantLBMKernel>(kernel)->OxyyMxzz = 1.0;
+   	break;
+   case MAGIC:
+      std::dynamic_pointer_cast<IncompressibleCumulantLBMKernel>(kernel)->OxyyMxzz = 2.0 +(-collFactor);
+      break;
+   }
+   return kernel;
+}
+//////////////////////////////////////////////////////////////////////////
+void IncompressibleCumulantLBMKernel::calculate()
+{
+   timer.resetAndStart();
+   collideAll();
+   timer.stop();
+}
+//////////////////////////////////////////////////////////////////////////
+void IncompressibleCumulantLBMKernel::collideAll()
+{
+   using namespace D3Q27System;
+
+   //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);
+
+      muDeltaT = deltaT;
+
+      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);
+
+      LBMReal forcingX1 = 0;
+      LBMReal forcingX2 = 0;
+      LBMReal forcingX3 = 0;
+   }
+   /////////////////////////////////////
+
+   localDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getLocalDistributions();
+   nonLocalDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getNonLocalDistributions();
+   zeroDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getZeroDistributions();
+
+   BCArray3DPtr bcArray = this->getBCProcessor()->getBCArray();
+
+   const int bcArrayMaxX1 = (int)bcArray->getNX1();
+   const int bcArrayMaxX2 = (int)bcArray->getNX2();
+   const int bcArrayMaxX3 = (int)bcArray->getNX3();
+
+   int minX1 = ghostLayerWidth;
+   int minX2 = ghostLayerWidth;
+   int minX3 = ghostLayerWidth;
+   int maxX1 = bcArrayMaxX1-ghostLayerWidth;
+   int maxX2 = bcArrayMaxX2-ghostLayerWidth;
+   int maxX3 = bcArrayMaxX3-ghostLayerWidth;
+
+
+//#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++)
+   {
+      for(int x2 = minX2; x2 < maxX2; x2++)
+      {
+         for(int x1 = minX1; x1 < maxX1; x1++)
+         {
+            if(!bcArray->isSolid(x1,x2,x3) && !bcArray->isUndefined(x1,x2,x3))
+            {
+               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 m0, m1, m2;
+
+               LBMReal rho=(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 vvx    =((((mfccc-mfaaa) + (mfcac-mfaca)) + ((mfcaa-mfacc) + (mfcca-mfaac))) +
+                  (((mfcba-mfabc) + (mfcbc-mfaba)) + ((mfcab-mfacb) + (mfccb-mfaab))) +
+                  (mfcbb-mfabb));
+               LBMReal vvy    =((((mfccc-mfaaa) + (mfaca-mfcac)) + ((mfacc-mfcaa) + (mfcca-mfaac))) +
+                  (((mfbca-mfbac) + (mfbcc-mfbaa)) + ((mfacb-mfcab) + (mfccb-mfaab))) +
+                  (mfbcb-mfbab));
+               LBMReal vvz    =((((mfccc-mfaaa) + (mfcac-mfaca)) + ((mfacc-mfcaa) + (mfaac-mfcca))) +
+                  (((mfbac-mfbca) + (mfbcc-mfbaa)) + ((mfabc-mfcba) + (mfcbc-mfaba))) +
+                  (mfbbc-mfbba));
+
+               //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;
+
+               oMdrho=mfccc+mfaaa;
+               m0=mfaca+mfcac;
+               m1=mfacc+mfcaa;
+               m2=mfaac+mfcca;
+               oMdrho+=m0;
+               m1+=m2;
+               oMdrho+=m1;
+               m0=mfbac+mfbca;
+               m1=mfbaa+mfbcc;
+               m0+=m1;
+               m1=mfabc+mfcba;
+               m2=mfaba+mfcbc;
+               m1+=m2;
+               m0+=m1;
+               m1=mfacb+mfcab;
+               m2=mfaab+mfccb;
+               m1+=m2;
+               m0+=m1;
+               oMdrho+=m0;
+               m0=mfabb+mfcbb;
+               m1=mfbab+mfbcb;
+               m2=mfbba+mfbbc;
+               m0+=m1+m2;
+               m0+=mfbbb; //hat gefehlt
+               oMdrho = 1. - (oMdrho + m0);
+
+               LBMReal vx2;
+               LBMReal vy2;
+               LBMReal vz2;
+               vx2=vvx*vvx;
+               vy2=vvy*vvy;
+               vz2=vvz*vvz;
+               ////////////////////////////////////////////////////////////////////////////////////
+               LBMReal wadjust;
+               LBMReal qudricLimit = 0.01;
+               ////////////////////////////////////////////////////////////////////////////////////
+               //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 - 2. *   m1 * vvz + vz2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfaba  + mfabc;
+               m1    = mfabc  - mfaba;
+               m0    = m2          + mfabb;
+               mfaba = m0;
+               m0   += c1o9 * oMdrho;
+               mfabb = m1 -        m0 * vvz;
+               mfabc = m2 - 2. *   m1 * vvz + vz2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfaca  + mfacc;
+               m1    = mfacc  - mfaca;
+               m0    = m2          + mfacb;
+               mfaca = m0;
+               m0   += c1o36 * oMdrho;
+               mfacb = m1 -        m0 * vvz;
+               mfacc = m2 - 2. *   m1 * vvz + vz2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfbaa + mfbac;
+               m1    = mfbac - mfbaa;
+               m0    = m2          + mfbab;
+               mfbaa = m0;
+               m0   += c1o9 * oMdrho;
+               mfbab = m1 -        m0 * vvz;
+               mfbac = m2 - 2. *   m1 * vvz + vz2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfbba  + mfbbc;
+               m1    = mfbbc  - mfbba;
+               m0    = m2          + mfbbb;
+               mfbba = m0;
+               m0   += c4o9 * oMdrho;
+               mfbbb = m1 -        m0 * vvz;
+               mfbbc = m2 - 2. *   m1 * vvz + vz2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfbca  + mfbcc;
+               m1    = mfbcc  - mfbca;
+               m0    = m2          + mfbcb;
+               mfbca = m0;
+               m0   += c1o9 * oMdrho;
+               mfbcb = m1 -        m0 * vvz;
+               mfbcc = m2 - 2. *   m1 * vvz + vz2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfcaa + mfcac;
+               m1    = mfcac - mfcaa;
+               m0    = m2          + mfcab;
+               mfcaa = m0;
+               m0   += c1o36 * oMdrho;
+               mfcab = m1 -        m0 * vvz;
+               mfcac = m2 - 2. *   m1 * vvz + vz2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfcba  + mfcbc;
+               m1    = mfcbc  - mfcba;
+               m0    = m2          + mfcbb;
+               mfcba = m0;
+               m0   += c1o9 * oMdrho;
+               mfcbb = m1 -        m0 * vvz;
+               mfcbc = m2 - 2. *   m1 * vvz + vz2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfcca  + mfccc;
+               m1    = mfccc  - mfcca;
+               m0    = m2          + mfccb;
+               mfcca = m0;
+               m0   += c1o36 * oMdrho;
+               mfccb = m1 -        m0 * vvz;
+               mfccc = m2 - 2. *   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 - 2. *   m1 * vvy + vy2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfaab  + mfacb;
+               m1    = mfacb  - mfaab;
+               m0    = m2          + mfabb;
+               mfaab = m0;
+               mfabb = m1 -        m0 * vvy;
+               mfacb = m2 - 2. *   m1 * vvy + vy2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfaac  + mfacc;
+               m1    = mfacc  - mfaac;
+               m0    = m2          + mfabc;
+               mfaac = m0;
+               m0   += c1o18 * oMdrho;
+               mfabc = m1 -        m0 * vvy;
+               mfacc = m2 - 2. *   m1 * vvy + vy2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfbaa + mfbca;
+               m1    = mfbca - mfbaa;
+               m0    = m2          + mfbba;
+               mfbaa = m0;
+               m0   += c2o3 * oMdrho;
+               mfbba = m1 -        m0 * vvy;
+               mfbca = m2 - 2. *   m1 * vvy + vy2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfbab  + mfbcb;
+               m1    = mfbcb  - mfbab;
+               m0    = m2          + mfbbb;
+               mfbab = m0;
+               mfbbb = m1 -        m0 * vvy;
+               mfbcb = m2 - 2. *   m1 * vvy + vy2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfbac  + mfbcc;
+               m1    = mfbcc  - mfbac;
+               m0    = m2          + mfbbc;
+               mfbac = m0;
+               m0   += c2o9 * oMdrho;
+               mfbbc = m1 -        m0 * vvy;
+               mfbcc = m2 - 2. *   m1 * vvy + vy2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfcaa + mfcca;
+               m1    = mfcca - mfcaa;
+               m0    = m2          + mfcba;
+               mfcaa = m0;
+               m0   += c1o6 * oMdrho;
+               mfcba = m1 -        m0 * vvy;
+               mfcca = m2 - 2. *   m1 * vvy + vy2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfcab  + mfccb;
+               m1    = mfccb  - mfcab;
+               m0    = m2          + mfcbb;
+               mfcab = m0;
+               mfcbb = m1 -        m0 * vvy;
+               mfccb = m2 - 2. *   m1 * vvy + vy2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfcac  + mfccc;
+               m1    = mfccc  - mfcac;
+               m0    = m2          + mfcbc;
+               mfcac = m0;
+               m0   += c1o18 * oMdrho;
+               mfcbc = m1 -        m0 * vvy;
+               mfccc = m2 - 2. *   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   += 1. * oMdrho;
+               mfbaa = m1 -        m0 * vvx;
+               mfcaa = m2 - 2. *   m1 * vvx + vx2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfaba  + mfcba;
+               m1    = mfcba  - mfaba;
+               m0    = m2          + mfbba;
+               mfaba = m0;
+               mfbba = m1 -        m0 * vvx;
+               mfcba = m2 - 2. *   m1 * vvx + vx2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfaca  + mfcca;
+               m1    = mfcca  - mfaca;
+               m0    = m2          + mfbca;
+               mfaca = m0;
+               m0   += c1o3 * oMdrho;
+               mfbca = m1 -        m0 * vvx;
+               mfcca = m2 - 2. *   m1 * vvx + vx2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfaab + mfcab;
+               m1    = mfcab - mfaab;
+               m0    = m2          + mfbab;
+               mfaab = m0;
+               mfbab = m1 -        m0 * vvx;
+               mfcab = m2 - 2. *   m1 * vvx + vx2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfabb  + mfcbb;
+               m1    = mfcbb  - mfabb;
+               m0    = m2          + mfbbb;
+               mfabb = m0;
+               mfbbb = m1 -        m0 * vvx;
+               mfcbb = m2 - 2. *   m1 * vvx + vx2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfacb  + mfccb;
+               m1    = mfccb  - mfacb;
+               m0    = m2          + mfbcb;
+               mfacb = m0;
+               mfbcb = m1 -        m0 * vvx;
+               mfccb = m2 - 2. *   m1 * vvx + vx2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfaac + mfcac;
+               m1    = mfcac - mfaac;
+               m0    = m2          + mfbac;
+               mfaac = m0;
+               m0   += c1o3 * oMdrho;
+               mfbac = m1 -        m0 * vvx;
+               mfcac = m2 - 2. *   m1 * vvx + vx2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfabc  + mfcbc;
+               m1    = mfcbc  - mfabc;
+               m0    = m2          + mfbbc;
+               mfabc = m0;
+               mfbbc = m1 -        m0 * vvx;
+               mfcbc = m2 - 2. *   m1 * vvx + vx2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfacc  + mfccc;
+               m1    = mfccc  - mfacc;
+               m0    = m2          + mfbcc;
+               mfacc = m0;
+               m0   += c1o9 * oMdrho;
+               mfbcc = m1 -        m0 * vvx;
+               mfccc = m2 - 2. *   m1 * vvx + vx2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               // Cumulants
+               ////////////////////////////////////////////////////////////////////////////////////
+               LBMReal OxxPyyPzz = 1.; //omega2 or bulk viscosity
+               LBMReal OxyyPxzz  = 1.;//-s9;//2+s9;//
+               //LBMReal OxyyMxzz  = 1.;//2+s9;//
+               LBMReal O4        = 1.;
+               LBMReal O5        = 1.;
+               LBMReal O6        = 1.;
+
+               //Cum 4.
+               //LBMReal CUMcbb = mfcbb - ((mfcaa + c1o3 * oMdrho) * mfabb + 2. * mfbba * mfbab); // till 18.05.2015
+               //LBMReal CUMbcb = mfbcb - ((mfaca + c1o3 * oMdrho) * mfbab + 2. * mfbba * mfabb); // till 18.05.2015
+               //LBMReal CUMbbc = mfbbc - ((mfaac + c1o3 * oMdrho) * mfbba + 2. * mfbab * mfabb); // till 18.05.2015
+
+               LBMReal CUMcbb = mfcbb - ((mfcaa + c1o3 ) * mfabb + 2. * mfbba * mfbab);
+               LBMReal CUMbcb = mfbcb - ((mfaca + c1o3 ) * mfbab + 2. * mfbba * mfabb);
+               LBMReal CUMbbc = mfbbc - ((mfaac + c1o3 ) * mfbba + 2. * mfbab * mfabb);
+
+               LBMReal CUMcca = mfcca - ((mfcaa * mfaca + 2. * mfbba * mfbba) + c1o3 * (mfcaa + mfaca) * oMdrho + c1o9*(oMdrho-1)*oMdrho);
+               LBMReal CUMcac = mfcac - ((mfcaa * mfaac + 2. * mfbab * mfbab) + c1o3 * (mfcaa + mfaac) * oMdrho + c1o9*(oMdrho-1)*oMdrho);
+               LBMReal CUMacc = mfacc - ((mfaac * mfaca + 2. * mfabb * mfabb) + c1o3 * (mfaac + mfaca) * oMdrho + c1o9*(oMdrho-1)*oMdrho);
+
+               //Cum 5.
+               LBMReal CUMbcc = mfbcc - (mfaac * mfbca + mfaca * mfbac + 4. * mfabb * mfbbb + 2. * (mfbab * mfacb + mfbba * mfabc)) - c1o3 * (mfbca + mfbac) * oMdrho;
+               LBMReal CUMcbc = mfcbc - (mfaac * mfcba + mfcaa * mfabc + 4. * mfbab * mfbbb + 2. * (mfabb * mfcab + mfbba * mfbac)) - c1o3 * (mfcba + mfabc) * oMdrho;
+               LBMReal CUMccb = mfccb - (mfcaa * mfacb + mfaca * mfcab + 4. * mfbba * mfbbb + 2. * (mfbab * mfbca + mfabb * mfcba)) - c1o3 * (mfacb + mfcab) * oMdrho;
+
+               //Cum 6.
+               LBMReal CUMccc = mfccc  +((-4. *  mfbbb * mfbbb 
+                  -       (mfcaa * mfacc + mfaca * mfcac + mfaac * mfcca)
+                  -  4. * (mfabb * mfcbb + mfbab * mfbcb + mfbba * mfbbc)
+                  -  2. * (mfbca * mfbac + mfcba * mfabc + mfcab * mfacb))
+                  +( 4. * (mfbab * mfbab * mfaca + mfabb * mfabb * mfcaa + mfbba * mfbba * mfaac)
+                  +  2. * (mfcaa * mfaca * mfaac)
+                  + 16. *  mfbba * mfbab * mfabb)
+                  - c1o3* (mfacc + mfcac + mfcca) * oMdrho  -c1o9*oMdrho*oMdrho
+                  - c1o9* (mfcaa + mfaca + mfaac) * oMdrho*(1.-2.* oMdrho)- c1o27* oMdrho * oMdrho*(-2.* oMdrho)
+                  +( 2. * (mfbab * mfbab + mfabb * mfabb + mfbba * mfbba)
+                  +       (mfaac * mfaca + mfaac * mfcaa + mfaca * mfcaa)) * c2o3*oMdrho) +c1o27*oMdrho;
+
+               //2.
+               // linear combinations
+               LBMReal mxxPyyPzz = mfcaa + mfaca + mfaac;
+               LBMReal mxxMyy    = mfcaa - mfaca;
+               LBMReal mxxMzz         = mfcaa - mfaac;
+
+               LBMReal dxux = -c1o2 * collFactor *(mxxMyy + mxxMzz) + c1o2 * OxxPyyPzz*(mfaaa - mxxPyyPzz);
+               LBMReal dyuy = dxux + collFactor * c3o2 * mxxMyy;
+               LBMReal dzuz = dxux + collFactor * c3o2 * mxxMzz;
+
+               //relax
+               mxxPyyPzz += OxxPyyPzz*(mfaaa  - mxxPyyPzz)- 3. * (1. - c1o2 * OxxPyyPzz) * (vx2 * dxux + vy2 * dyuy + vz2 * dzuz);
+               mxxMyy    += collFactor * (-mxxMyy) - 3. * (1. - c1o2 * collFactor) * (vx2 * dxux - vy2 * dyuy);
+               mxxMzz    += collFactor * (-mxxMzz) - 3. * (1. - c1o2 * collFactor) * (vx2 * dxux - vz2 * dzuz);
+
+               mfabb     += collFactor * (-mfabb);
+               mfbab     += collFactor * (-mfbab);
+               mfbba     += collFactor * (-mfbba);
+
+               // linear combinations back
+               mfcaa = c1o3 * (       mxxMyy +      mxxMzz + mxxPyyPzz);
+               mfaca = c1o3 * (-2. *  mxxMyy +      mxxMzz + mxxPyyPzz);
+               mfaac = c1o3 * (       mxxMyy - 2. * 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
+               wadjust    = OxyyMxzz+(1.-OxyyMxzz)*fabs(mfbbb)/(fabs(mfbbb)+qudricLimit);
+               mfbbb     += wadjust * (-mfbbb);
+               wadjust    = OxyyPxzz+(1.-OxyyPxzz)*fabs(mxxyPyzz)/(fabs(mxxyPyzz)+qudricLimit);
+               mxxyPyzz  += wadjust * (-mxxyPyzz);
+               wadjust    = OxyyMxzz+(1.-OxyyMxzz)*fabs(mxxyMyzz)/(fabs(mxxyMyzz)+qudricLimit);
+               mxxyMyzz  += wadjust * (-mxxyMyzz);
+               wadjust    = OxyyPxzz+(1.-OxyyPxzz)*fabs(mxxzPyyz)/(fabs(mxxzPyyz)+qudricLimit);
+               mxxzPyyz  += wadjust * (-mxxzPyyz);
+               wadjust    = OxyyMxzz+(1.-OxyyMxzz)*fabs(mxxzMyyz)/(fabs(mxxzMyyz)+qudricLimit);
+               mxxzMyyz  += wadjust * (-mxxzMyyz);
+               wadjust    = OxyyPxzz+(1.-OxyyPxzz)*fabs(mxyyPxzz)/(fabs(mxyyPxzz)+qudricLimit);
+               mxyyPxzz  += wadjust * (-mxyyPxzz);
+               wadjust    = OxyyMxzz+(1.-OxyyMxzz)*fabs(mxyyMxzz)/(fabs(mxyyMxzz)+qudricLimit);
+               mxyyMxzz  += wadjust * (-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.
+               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 * oMdrho) * mfabb + 2. * mfbba * mfbab); // till 18.05.2015
+               //mfbcb = CUMbcb + ((mfaca + c1o3 * oMdrho) * mfbab + 2. * mfbba * mfabb); // till 18.05.2015
+               //mfbbc = CUMbbc + ((mfaac + c1o3 * oMdrho) * mfbba + 2. * mfbab * mfabb); // till 18.05.2015
+
+               mfcbb = CUMcbb + ((mfcaa + c1o3 ) * mfabb + 2. * mfbba * mfbab);
+               mfbcb = CUMbcb + ((mfaca + c1o3 ) * mfbab + 2. * mfbba * mfabb);
+               mfbbc = CUMbbc + ((mfaac + c1o3 ) * mfbba + 2. * mfbab * mfabb);
+
+               mfcca = CUMcca + (mfcaa * mfaca + 2. * mfbba * mfbba) + c1o3 * (mfcaa + mfaca) * oMdrho + c1o9*(oMdrho-1)*oMdrho;
+               mfcac = CUMcac + (mfcaa * mfaac + 2. * mfbab * mfbab) + c1o3 * (mfcaa + mfaac) * oMdrho + c1o9*(oMdrho-1)*oMdrho;
+               mfacc = CUMacc + (mfaac * mfaca + 2. * mfabb * mfabb) + c1o3 * (mfaac + mfaca) * oMdrho + c1o9*(oMdrho-1)*oMdrho;
+
+               //5.
+               mfbcc = CUMbcc + (mfaac * mfbca + mfaca * mfbac + 4. * mfabb * mfbbb + 2. * (mfbab * mfacb + mfbba * mfabc)) + c1o3 * (mfbca + mfbac) * oMdrho;
+               mfcbc = CUMcbc + (mfaac * mfcba + mfcaa * mfabc + 4. * mfbab * mfbbb + 2. * (mfabb * mfcab + mfbba * mfbac)) + c1o3 * (mfcba + mfabc) * oMdrho;
+               mfccb = CUMccb + (mfcaa * mfacb + mfaca * mfcab + 4. * mfbba * mfbbb + 2. * (mfbab * mfbca + mfabb * mfcba)) + c1o3 * (mfacb + mfcab) * oMdrho;
+
+               //6.
+               mfccc = CUMccc  -((-4. *  mfbbb * mfbbb 
+                  -       (mfcaa * mfacc + mfaca * mfcac + mfaac * mfcca)
+                  -  4. * (mfabb * mfcbb + mfbac * mfbca + mfbba * mfbbc)
+                  -  2. * (mfbca * mfbac + mfcba * mfabc + mfcab * mfacb))
+                  +( 4. * (mfbab * mfbab * mfaca + mfabb * mfabb * mfcaa + mfbba * mfbba * mfaac)
+                  +  2. * (mfcaa * mfaca * mfaac)
+                  + 16. *  mfbba * mfbab * mfabb)
+                  - c1o3* (mfacc + mfcac + mfcca) * oMdrho  -c1o9*oMdrho*oMdrho
+                  - c1o9* (mfcaa + mfaca + mfaac) * oMdrho*(1.-2.* oMdrho)- c1o27* oMdrho * oMdrho*(-2.* oMdrho)
+                  +( 2. * (mfbab * mfbab + mfabb * mfabb + mfbba * mfbba)
+                  +       (mfaac * mfaca + mfaac * mfcaa + mfaca * mfcaa)) * c2o3*oMdrho) -c1o27*oMdrho;
+
+               ////////////////////////////////////////////////////////////////////////////////////
+               //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 + 1. * oMdrho) * (     vz2 - vvz) * c1o2;
+               m1 = -mfaac        - 2. * mfaab *  vvz         +  mfaaa                * (1. - vz2)              - 1. * oMdrho * vz2;
+               m2 =  mfaac * c1o2 +      mfaab * (vvz + c1o2) + (mfaaa + 1. * oMdrho) * (     vz2 + vvz) * c1o2;
+               mfaaa = m0;
+               mfaab = m1;
+               mfaac = m2;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m0 =  mfabc * c1o2 +      mfabb * (vvz - c1o2) + mfaba * (     vz2 - vvz) * c1o2;
+               m1 = -mfabc        - 2. * mfabb *  vvz         + mfaba * (1. - 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        - 2. * mfacb *  vvz         +  mfaca                  * (1. - 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        - 2. * mfbab *  vvz         + mfbaa * (1. - 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        - 2. * mfbbb *  vvz         + mfbba * (1. - 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        - 2. * mfbcb *  vvz         + mfbca * (1. - 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        - 2. * mfcab *  vvz         +  mfcaa                  * (1. - 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        - 2. * mfcbb *  vvz         + mfcba * (1. - 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        - 2. * mfccb *  vvz         +  mfcca                  * (1. - 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        - 2. * mfaba *  vvy         +  mfaaa                  * (1. - 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        - 2. * mfabb *  vvy         +  mfaab                  * (1. - 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        - 2. * mfabc *  vvy         +  mfaac                  * (1. - 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        - 2. * mfbba *  vvy         + mfbaa * (1. - 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        - 2. * mfbbb *  vvy         + mfbab * (1. - 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        - 2. * mfbbc *  vvy         + mfbac * (1. - 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        - 2. * mfcba *  vvy         +  mfcaa                   * (1. - 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        - 2. * mfcbb *  vvy         +  mfcab                  * (1. - 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        - 2. * mfcbc *  vvy         +  mfcac                   * (1. - 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        - 2. * mfbaa *  vvx         +  mfaaa                   * (1. - 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        - 2. * mfbba *  vvx         +  mfaba                  * (1. - 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        - 2. * mfbca *  vvx         +  mfaca                   * (1. - 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        - 2. * mfbab *  vvx         +  mfaab                  * (1. - 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        - 2. * mfbbb *  vvx         +  mfabb                  * (1. - 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        - 2. * mfbcb *  vvx         +  mfacb                  * (1. - 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        - 2. * mfbac *  vvx         +  mfaac                   * (1. - 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        - 2. * mfbbc *  vvx         +  mfabc                  * (1. - 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        - 2. * mfbcc *  vvx         +  mfacc                   * (1. - 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 rho_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 = rho - rho_post;
+#ifdef SINGLEPRECISION
+               if(dif > 10.0E-7 || dif < -10.0E-7)
+#else
+               if(dif > 10.0E-15 || dif < -10.0E-15)
+#endif
+               {
+                  UB_THROW(UbException(UB_EXARGS,"rho="+UbSystem::toString(rho)+", rho_post="+UbSystem::toString(rho_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;
+               //////////////////////////////////////////////////////////////////////////
+
+            }
+         }
+      }
+   }
+
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+double IncompressibleCumulantLBMKernel::getCalculationTime()
+{
+   //return timer.getDuration();
+   return timer.getTotalTime();
+}
diff --git a/source/VirtualFluidsCore/LBM/IncompressibleCumulantLBMKernel.h b/source/VirtualFluidsCore/LBM/IncompressibleCumulantLBMKernel.h
index ce052ff8d..5c929af67 100644
--- a/source/VirtualFluidsCore/LBM/IncompressibleCumulantLBMKernel.h
+++ b/source/VirtualFluidsCore/LBM/IncompressibleCumulantLBMKernel.h
@@ -12,7 +12,7 @@
 #include "basics/container/CbArray3D.h"
 
 class IncompressibleCumulantLBMKernel;
-typedef boost::shared_ptr<IncompressibleCumulantLBMKernel> LBMKernelETD3Q27CCLBPtr;
+typedef std::shared_ptr<IncompressibleCumulantLBMKernel> LBMKernelETD3Q27CCLBPtr;
 
 //! \brief   Cascaded Cumulant LBM kernel. 
 //! \details CFD solver that use Cascaded Cumulant Lattice Boltzmann method for D3Q27 model
@@ -33,7 +33,7 @@ public:
    virtual ~IncompressibleCumulantLBMKernel(void);
    virtual void calculate();
    virtual LBMKernelPtr clone();
-   double getCallculationTime();
+   double getCalculationTime();
 
 protected:
    friend class boost::serialization::access;
diff --git a/source/VirtualFluidsCore/LBM/IncompressibleCumulantWithSpongeLayerLBMKernel.cpp b/source/VirtualFluidsCore/LBM/IncompressibleCumulantWithSpongeLayerLBMKernel.cpp
index 11997784d..325e1c800 100644
--- a/source/VirtualFluidsCore/LBM/IncompressibleCumulantWithSpongeLayerLBMKernel.cpp
+++ b/source/VirtualFluidsCore/LBM/IncompressibleCumulantWithSpongeLayerLBMKernel.cpp
@@ -1,1019 +1,1021 @@
-#include "IncompressibleCumulantWithSpongeLayerLBMKernel.h"
-#include "D3Q27System.h"
-#include "D3Q27EsoTwist3DSplittedVector.h"
-#include <math.h>
-
-#define PROOF_CORRECTNESS
-
-//////////////////////////////////////////////////////////////////////////
-IncompressibleCumulantWithSpongeLayerLBMKernel::IncompressibleCumulantWithSpongeLayerLBMKernel()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-IncompressibleCumulantWithSpongeLayerLBMKernel::IncompressibleCumulantWithSpongeLayerLBMKernel(int nx1, int nx2, int nx3, Parameter p) 
-   : IncompressibleCumulantLBMKernel(nx1, nx2, nx3, p)
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-IncompressibleCumulantWithSpongeLayerLBMKernel::~IncompressibleCumulantWithSpongeLayerLBMKernel(void)
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-void IncompressibleCumulantWithSpongeLayerLBMKernel::init()
-{
-   //DistributionArray3DPtr d(new D3Q27EsoTwist3DSplittedVector(nx1+ghostLayerWitdh*2, nx2+ghostLayerWitdh*2, nx3+ghostLayerWitdh*2, -999.0));
-   DistributionArray3DPtr d(new D3Q27EsoTwist3DSplittedVector(nx1+2, nx2+2, nx3+2, -999.0));
-   dataSet->setFdistributions(d);
-}
-//////////////////////////////////////////////////////////////////////////
-void IncompressibleCumulantWithSpongeLayerLBMKernel::setRelaxFactorParam(int vdir, double vL1, double vdx, double vSP)
-{
-   direction = vdir;
-   L1 = vL1;
-   dx = vdx;
-   SP = vSP;
-}
-//////////////////////////////////////////////////////////////////////////
-void IncompressibleCumulantWithSpongeLayerLBMKernel::initRelaxFactor(int vdir, double vL1, double vdx, double vSP)
-{
-   direction = vdir;
-   L1 = vL1;
-   dx = vdx;
-   SP = vSP;
-
-   double sizeX = L1 / dx;
-   double sizeSP = SP / dx;
-   double muX1, muX2, muX3;
-
-   LBMReal spongeFactor;
-
-   BCArray3DPtr bcArray = this->getBCProcessor()->getBCArray();
-
-   const int bcArrayMaxX1 = (int)bcArray->getNX1();
-   const int bcArrayMaxX2 = (int)bcArray->getNX2();
-   const int bcArrayMaxX3 = (int)bcArray->getNX3();
-
-   int minX1 = 0;
-   int minX2 = 0;
-   int minX3 = 0;
-   int maxX1 = bcArrayMaxX1 - ghostLayerWidth - 1;
-   int maxX2 = bcArrayMaxX2 - ghostLayerWidth - 1;
-   int maxX3 = bcArrayMaxX3 - ghostLayerWidth - 1;
-
-   RelaxationFactorArray3DPtr relaxationFactorPtr = CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<LBMReal, IndexerX3X2X1>(maxX1, maxX2, maxX3));
-   dataSet->setRelaxationFactor(relaxationFactorPtr);
-
-   for (int x3 = minX3; x3 < maxX3; x3++)
-   {
-      for (int x2 = minX2; x2 < maxX2; x2++)
-      {
-         for (int x1 = minX1; x1 < maxX1; x1++)
-         {
-            switch (direction)
-            {
-            case D3Q27System::E:
-               muX1 = (double)(x1 + ix1 * maxX1);
-               if (muX1 >= (sizeX - sizeSP) / deltaT)
-                  spongeFactor = (sizeX - (muX1 * deltaT + 1)) / sizeSP / 2.0 + 0.5;
-               else spongeFactor = 1.0;
-               break;
-            case D3Q27System::W:
-               muX1 = (double)(x1 + ix1 * maxX1);
-               if (muX1 <= sizeSP / deltaT)
-                  spongeFactor = (sizeSP - (muX1 * deltaT + 1)) / sizeSP / 2.0 + 0.5;
-               else spongeFactor = 1.0;
-               break;
-            case D3Q27System::N:
-               muX2 = (double)(x2 + ix2 * maxX2);
-               if (muX2 >= (sizeX - sizeSP) / deltaT)
-                  spongeFactor = (sizeX - (muX2 * deltaT + 1)) / sizeSP / 2.0 + 0.5;
-               else spongeFactor = 1.0;
-               break;
-            case D3Q27System::S:
-               muX2 = (double)(x2 + ix2 * maxX2);
-               if (muX2 <= sizeSP / deltaT)
-                  spongeFactor = (sizeSP - (muX2 * deltaT + 1)) / sizeSP / 2.0 + 0.5;
-               else spongeFactor = 1.0;
-               break;
-            case D3Q27System::T:
-               muX3 = (double)(x3 + ix3 * maxX3);
-               if (muX3 >= (sizeX - sizeSP) / deltaT)
-                  spongeFactor = (sizeX - (muX3 * deltaT + 1)) / sizeSP / 2.0 + 0.5;
-               else spongeFactor = 1.0;
-               break;
-            case D3Q27System::B:
-               muX3 = (double)(x3 + ix3 * maxX3);
-               if (muX3 <= sizeSP / deltaT)
-                  spongeFactor = (sizeSP - (muX3 * deltaT + 1)) / sizeSP / 2.0 + 0.5;
-               else spongeFactor = 1.0;
-               break;
-            default: throw UbException(UB_EXARGS, "unknown dir");
-            }
-            (*relaxationFactorPtr)(x1, x2, x3) = spongeFactor;
-         }
-      }
-   }
-}
-
-//////////////////////////////////////////////////////////////////////////
-LBMKernelPtr IncompressibleCumulantWithSpongeLayerLBMKernel::clone()
-{
-   LBMKernelPtr kernel(new IncompressibleCumulantWithSpongeLayerLBMKernel(nx1, nx2, nx3, parameter));
-   boost::dynamic_pointer_cast<IncompressibleCumulantWithSpongeLayerLBMKernel>(kernel)->init();
-   kernel->setCollisionFactor(this->collFactor);
-   kernel->setBCProcessor(bcProcessor->clone(kernel));
-   kernel->setWithForcing(withForcing);
-   kernel->setForcingX1(muForcingX1);
-   kernel->setForcingX2(muForcingX2);
-   kernel->setForcingX3(muForcingX3);
-   kernel->setIndex(ix1, ix2, ix3);
-   kernel->setDeltaT(deltaT);
-   switch (parameter)
-   {
-   case NORMAL:
-      boost::dynamic_pointer_cast<IncompressibleCumulantWithSpongeLayerLBMKernel>(kernel)->OxyyMxzz = 1.0;
-      break;
-   case MAGIC:
-      boost::dynamic_pointer_cast<IncompressibleCumulantWithSpongeLayerLBMKernel>(kernel)->OxyyMxzz = 2.0 +(-collFactor);
-      break;
-   }
-
-   kernel->setWithSpongeLayer(withSpongeLayer);
-   if(withSpongeLayer) kernel->setSpongeLayer(muSpongeLayer);
-   boost::dynamic_pointer_cast<IncompressibleCumulantWithSpongeLayerLBMKernel>(kernel)->initRelaxFactor(direction, L1, dx, SP);
-   return kernel;
-}  
-//////////////////////////////////////////////////////////////////////////
-void IncompressibleCumulantWithSpongeLayerLBMKernel::calculate()
-{
-   timer.resetAndStart();
-   collideAll();
-   timer.stop();
-}
-//////////////////////////////////////////////////////////////////////////
-void IncompressibleCumulantWithSpongeLayerLBMKernel::collideAll()
-{
-   using namespace D3Q27System;
-
-   if(!withSpongeLayer)
-   {
-      UB_THROW(UbException(UB_EXARGS,"Sponge layer isn't initialized!"));
-   }
-   //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);
-
-   //   muDeltaT = deltaT;
-
-   //   muForcingX1.DefineVar("dx",&muDeltaT);
-   //   muForcingX2.DefineVar("dx",&muDeltaT);
-   //   muForcingX3.DefineVar("dx",&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);
-
-   //   LBMReal forcingX1 = 0;
-   //   LBMReal forcingX2 = 0;
-   //   LBMReal forcingX3 = 0;
-   //}
-   /////////////////////////////////////
-   //initialization of sponge layer variables
-   //if (withSpongeLayer)
-   //{
-      //muDeltaT = deltaT;
-      //muSpongeLayer.DefineVar("dt",&muDeltaT);
-      //muSpongeLayer.DefineVar("x1",&muX1); muSpongeLayer.DefineVar("x2",&muX2); muSpongeLayer.DefineVar("x3",&muX3);
-   //}
-   /////////////////////////////////////
-
-   localDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getLocalDistributions();
-   nonLocalDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getNonLocalDistributions();
-   zeroDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getZeroDistributions();
-
-   BCArray3DPtr bcArray = this->getBCProcessor()->getBCArray();
-   RelaxationFactorArray3DPtr relaxationFactorPtr = dataSet->getRelaxationFactor();
-
-   const int bcArrayMaxX1 = (int)bcArray->getNX1();
-   const int bcArrayMaxX2 = (int)bcArray->getNX2();
-   const int bcArrayMaxX3 = (int)bcArray->getNX3();
-
-   int minX1 = ghostLayerWidth;
-   int minX2 = ghostLayerWidth;
-   int minX3 = ghostLayerWidth;
-   int maxX1 = bcArrayMaxX1-ghostLayerWidth-1;
-   int maxX2 = bcArrayMaxX2-ghostLayerWidth-1;
-   int maxX3 = bcArrayMaxX3-ghostLayerWidth-1;
-
-   LBMReal collFactor0 = collFactor;
-   LBMReal spongeFactor;
-
-   for(int x3 = minX3; x3 <= maxX3; x3++)
-   {
-      for(int x2 = minX2; x2 <= maxX2; x2++)
-      {
-         for(int x1 = minX1; x1 <= maxX1; x1++)
-         {
-            if(!bcArray->isSolid(x1,x2,x3) && !bcArray->isUndefined(x1,x2,x3))
-            {
-               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
-
-               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 m0, m1, m2;
-               
-               LBMReal rho=(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 vvx    =((((mfccc-mfaaa) + (mfcac-mfaca)) + ((mfcaa-mfacc) + (mfcca-mfaac))) +
-                  (((mfcba-mfabc) + (mfcbc-mfaba)) + ((mfcab-mfacb) + (mfccb-mfaab))) +
-                  (mfcbb-mfabb));
-               LBMReal vvy    =((((mfccc-mfaaa) + (mfaca-mfcac)) + ((mfacc-mfcaa) + (mfcca-mfaac))) +
-                  (((mfbca-mfbac) + (mfbcc-mfbaa)) + ((mfacb-mfcab) + (mfccb-mfaab))) +
-                  (mfbcb-mfbab));
-               LBMReal vvz    =((((mfccc-mfaaa) + (mfcac-mfaca)) + ((mfacc-mfcaa) + (mfaac-mfcca))) +
-                  (((mfbac-mfbca) + (mfbcc-mfbaa)) + ((mfabc-mfcba) + (mfcbc-mfaba))) +
-                  (mfbbc-mfbba));
-               //////////////////////////////////////////////////////////////////////////
-               //forcing 
-               ///////////////////////////////////////////////////////////////////////////////////////////
-               //if (withForcing)
-               //{
-               //   muX1 = (double)(x1-1+ix1*maxX1);
-               //   muX2 = (double)(x2-1+ix2*maxX2);
-               //   muX3 = (double)(x3-1+ix3*maxX3);
-
-               //   forcingX1 = muForcingX1.Eval();
-               //   forcingX2 = muForcingX2.Eval();
-               //   forcingX3 = muForcingX3.Eval();
-
-               //   vvx += forcingX1*0.5; // X
-               //   vvy += forcingX2*0.5; // Y
-               //   vvz += forcingX3*0.5; // Z
-               //}
-               ///////////////////////////////////////////////////////////////////////////////////////////      
-               //sponge layer
-               ///////////////////////////////////////////////////////////////////////////////////////////
-               //if (withSpongeLayer)
-               //{
-                  //if (!withForcing)
-                  //{
-                    //lk// muX1 = (double)(x1-1+ix1*maxX1);
-                     //muX2 = (double)(x2-1+ix2*maxX2);
-                     //muX3 = (double)(x3-1+ix3*maxX3);
-                  //}
-                  //spongeFactor ist von Funktion in muSpongeLayer abhängich und variiert zwischen 1 (nix tun) und 0.5 (collFactor etwa auf 1);
-                  //lk //LBMReal spongeFactor = muSpongeLayer.Eval();
-
-                  //if (spongeFactor == 0.5)
-                  //{
-                  //   int Test=0;
-                  //}
-
-                  //if(muX3 == ix3*maxX3/2 && muX2==ix2*maxX2/2)
-                  //   UBLOG(logINFO," x1="<<muX1<<" spongeFactor = " << spongeFactor <<" collFactor="<<collFactor);
-
-                  spongeFactor = (*relaxationFactorPtr)(x1-1, x2-1, x3-1);
-                  collFactor *= spongeFactor;
-                  //if(muX3 == ix3*maxX3/2 && muX2==ix2*maxX2/2)
-                  //   UBLOG(logINFO," x1="<<muX1<<" spongeFactor = " << spongeFactor <<" collFactor="<<collFactor);
-
-               //}
-               //////////////////////////////////////////////////////////////////////////
-
-               LBMReal oMdrho;
-
-               oMdrho=mfccc+mfaaa;
-               m0=mfaca+mfcac;
-               m1=mfacc+mfcaa;
-               m2=mfaac+mfcca;
-               oMdrho+=m0;
-               m1+=m2; 
-               oMdrho+=m1;
-               m0=mfbac+mfbca;
-               m1=mfbaa+mfbcc;
-               m0+=m1;
-               m1=mfabc+mfcba;
-               m2=mfaba+mfcbc;
-               m1+=m2;
-               m0+=m1;
-               m1=mfacb+mfcab;
-               m2=mfaab+mfccb;
-               m1+=m2;
-               m0+=m1;
-               oMdrho+=m0;
-               m0=mfabb+mfcbb;
-               m1=mfbab+mfbcb;
-               m2=mfbba+mfbbc;
-               m0+=m1+m2;
-               m0+=mfbbb; //hat gefehlt
-               oMdrho = 1. - (oMdrho + m0);
-
-               LBMReal vx2;
-               LBMReal vy2;
-               LBMReal vz2;
-               vx2=vvx*vvx;
-               vy2=vvy*vvy;
-               vz2=vvz*vvz;
-               ////////////////////////////////////////////////////////////////////////////////////
-               LBMReal wadjust;
-               LBMReal qudricLimit = 0.01;
-               ////////////////////////////////////////////////////////////////////////////////////
-               //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 - 2. *   m1 * vvz + vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfaba  + mfabc;
-               m1    = mfabc  - mfaba;
-               m0    = m2          + mfabb;
-               mfaba = m0;
-               m0   += c1o9 * oMdrho;
-               mfabb = m1 -        m0 * vvz;
-               mfabc = m2 - 2. *   m1 * vvz + vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfaca  + mfacc;
-               m1    = mfacc  - mfaca;
-               m0    = m2          + mfacb;
-               mfaca = m0;
-               m0   += c1o36 * oMdrho;
-               mfacb = m1 -        m0 * vvz;
-               mfacc = m2 - 2. *   m1 * vvz + vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfbaa + mfbac;
-               m1    = mfbac - mfbaa;
-               m0    = m2          + mfbab;
-               mfbaa = m0;
-               m0   += c1o9 * oMdrho;
-               mfbab = m1 -        m0 * vvz;
-               mfbac = m2 - 2. *   m1 * vvz + vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfbba  + mfbbc;
-               m1    = mfbbc  - mfbba;
-               m0    = m2          + mfbbb;
-               mfbba = m0;
-               m0   += c4o9 * oMdrho;
-               mfbbb = m1 -        m0 * vvz;
-               mfbbc = m2 - 2. *   m1 * vvz + vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfbca  + mfbcc;
-               m1    = mfbcc  - mfbca;
-               m0    = m2          + mfbcb;
-               mfbca = m0;
-               m0   += c1o9 * oMdrho;
-               mfbcb = m1 -        m0 * vvz;
-               mfbcc = m2 - 2. *   m1 * vvz + vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfcaa + mfcac;
-               m1    = mfcac - mfcaa;
-               m0    = m2          + mfcab;
-               mfcaa = m0;
-               m0   += c1o36 * oMdrho;
-               mfcab = m1 -        m0 * vvz;
-               mfcac = m2 - 2. *   m1 * vvz + vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfcba  + mfcbc;
-               m1    = mfcbc  - mfcba;
-               m0    = m2          + mfcbb;
-               mfcba = m0;
-               m0   += c1o9 * oMdrho;
-               mfcbb = m1 -        m0 * vvz;
-               mfcbc = m2 - 2. *   m1 * vvz + vz2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfcca  + mfccc;
-               m1    = mfccc  - mfcca;
-               m0    = m2          + mfccb;
-               mfcca = m0;
-               m0   += c1o36 * oMdrho;
-               mfccb = m1 -        m0 * vvz;
-               mfccc = m2 - 2. *   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 - 2. *   m1 * vvy + vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfaab  + mfacb;
-               m1    = mfacb  - mfaab;
-               m0    = m2          + mfabb;
-               mfaab = m0;
-               mfabb = m1 -        m0 * vvy;
-               mfacb = m2 - 2. *   m1 * vvy + vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfaac  + mfacc;
-               m1    = mfacc  - mfaac;
-               m0    = m2          + mfabc;
-               mfaac = m0;
-               m0   += c1o18 * oMdrho;
-               mfabc = m1 -        m0 * vvy;
-               mfacc = m2 - 2. *   m1 * vvy + vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfbaa + mfbca;
-               m1    = mfbca - mfbaa;
-               m0    = m2          + mfbba;
-               mfbaa = m0;
-               m0   += c2o3 * oMdrho;
-               mfbba = m1 -        m0 * vvy;
-               mfbca = m2 - 2. *   m1 * vvy + vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfbab  + mfbcb;
-               m1    = mfbcb  - mfbab;
-               m0    = m2          + mfbbb;
-               mfbab = m0;
-               mfbbb = m1 -        m0 * vvy;
-               mfbcb = m2 - 2. *   m1 * vvy + vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfbac  + mfbcc;
-               m1    = mfbcc  - mfbac;
-               m0    = m2          + mfbbc;
-               mfbac = m0;
-               m0   += c2o9 * oMdrho;
-               mfbbc = m1 -        m0 * vvy;
-               mfbcc = m2 - 2. *   m1 * vvy + vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfcaa + mfcca;
-               m1    = mfcca - mfcaa;
-               m0    = m2          + mfcba;
-               mfcaa = m0;
-               m0   += c1o6 * oMdrho;
-               mfcba = m1 -        m0 * vvy;
-               mfcca = m2 - 2. *   m1 * vvy + vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfcab  + mfccb;
-               m1    = mfccb  - mfcab;
-               m0    = m2          + mfcbb;
-               mfcab = m0;
-               mfcbb = m1 -        m0 * vvy;
-               mfccb = m2 - 2. *   m1 * vvy + vy2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfcac  + mfccc;
-               m1    = mfccc  - mfcac;
-               m0    = m2          + mfcbc;
-               mfcac = m0;
-               m0   += c1o18 * oMdrho;
-               mfcbc = m1 -        m0 * vvy;
-               mfccc = m2 - 2. *   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   += 1. * oMdrho;
-               mfbaa = m1 -        m0 * vvx;
-               mfcaa = m2 - 2. *   m1 * vvx + vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfaba  + mfcba;
-               m1    = mfcba  - mfaba;
-               m0    = m2          + mfbba;
-               mfaba = m0;
-               mfbba = m1 -        m0 * vvx;
-               mfcba = m2 - 2. *   m1 * vvx + vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfaca  + mfcca;
-               m1    = mfcca  - mfaca;
-               m0    = m2          + mfbca;
-               mfaca = m0;
-               m0   += c1o3 * oMdrho;
-               mfbca = m1 -        m0 * vvx;
-               mfcca = m2 - 2. *   m1 * vvx + vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfaab + mfcab;
-               m1    = mfcab - mfaab;
-               m0    = m2          + mfbab;
-               mfaab = m0;
-               mfbab = m1 -        m0 * vvx;
-               mfcab = m2 - 2. *   m1 * vvx + vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfabb  + mfcbb;
-               m1    = mfcbb  - mfabb;
-               m0    = m2          + mfbbb;
-               mfabb = m0;
-               mfbbb = m1 -        m0 * vvx;
-               mfcbb = m2 - 2. *   m1 * vvx + vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfacb  + mfccb;
-               m1    = mfccb  - mfacb;
-               m0    = m2          + mfbcb;
-               mfacb = m0;
-               mfbcb = m1 -        m0 * vvx;
-               mfccb = m2 - 2. *   m1 * vvx + vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfaac + mfcac;
-               m1    = mfcac - mfaac;
-               m0    = m2          + mfbac;
-               mfaac = m0;
-               m0   += c1o3 * oMdrho;
-               mfbac = m1 -        m0 * vvx;
-               mfcac = m2 - 2. *   m1 * vvx + vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfabc  + mfcbc;
-               m1    = mfcbc  - mfabc;
-               m0    = m2          + mfbbc;
-               mfabc = m0;
-               mfbbc = m1 -        m0 * vvx;
-               mfcbc = m2 - 2. *   m1 * vvx + vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m2    = mfacc  + mfccc;
-               m1    = mfccc  - mfacc;
-               m0    = m2          + mfbcc;
-               mfacc = m0;
-               m0   += c1o9 * oMdrho;
-               mfbcc = m1 -        m0 * vvx;
-               mfccc = m2 - 2. *   m1 * vvx + vx2 * m0;
-               ////////////////////////////////////////////////////////////////////////////////////
-               // Cumulants
-               ////////////////////////////////////////////////////////////////////////////////////
-               LBMReal OxxPyyPzz = 1.;
-               LBMReal OxyyPxzz  = 1.;//-s9;//2+s9;//
-               //LBMReal OxyyMxzz  = 1.;//2+s9;//
-               LBMReal O4        = 1.;
-               LBMReal O5        = 1.;
-               LBMReal O6        = 1.;
-
-               //Cum 4.
-               LBMReal CUMcbb = mfcbb - ((mfcaa + c1o3 * oMdrho) * mfabb + 2. * mfbba * mfbab);
-               LBMReal CUMbcb = mfbcb - ((mfaca + c1o3 * oMdrho) * mfbab + 2. * mfbba * mfabb);
-               LBMReal CUMbbc = mfbbc - ((mfaac + c1o3 * oMdrho) * mfbba + 2. * mfbab * mfabb);
-
-               LBMReal CUMcca = mfcca - (mfcaa * mfaca + 2. * mfbba * mfbba) + c1o3 * (mfcaa + mfaca) * oMdrho + c1o9*(oMdrho-1)*oMdrho;
-               LBMReal CUMcac = mfcac - (mfcaa * mfaac + 2. * mfbab * mfbab) + c1o3 * (mfcaa + mfaac) * oMdrho + c1o9*(oMdrho-1)*oMdrho;
-               LBMReal CUMacc = mfacc - (mfaac * mfaca + 2. * mfabb * mfabb) + c1o3 * (mfaac + mfaca) * oMdrho + c1o9*(oMdrho-1)*oMdrho;
-
-               //Cum 5.
-               LBMReal CUMbcc = mfbcc - (mfaac * mfbca + mfaca * mfbac + 4. * mfabb * mfbbb + 2. * (mfbab * mfacb + mfbba * mfabc)) - c1o3 * (mfbca + mfbac) * oMdrho;
-               LBMReal CUMcbc = mfcbc - (mfaac * mfcba + mfcaa * mfabc + 4. * mfbab * mfbbb + 2. * (mfabb * mfcab + mfbba * mfbac)) - c1o3 * (mfcba + mfabc) * oMdrho;
-               LBMReal CUMccb = mfccb - (mfcaa * mfacb + mfaca * mfcab + 4. * mfbba * mfbbb + 2. * (mfbab * mfbca + mfabb * mfcba)) - c1o3 * (mfacb + mfcab) * oMdrho;
-
-               //Cum 6.
-               LBMReal CUMccc = mfccc  +((-4. *  mfbbb * mfbbb 
-                  -       (mfcaa * mfacc + mfaca * mfcac + mfaac * mfcca)
-                  -  4. * (mfabb * mfcbb + mfbab * mfbcb + mfbba * mfbbc)
-                  -  2. * (mfbca * mfbac + mfcba * mfabc + mfcab * mfacb))
-                  +( 4. * (mfbab * mfbab * mfaca + mfabb * mfabb * mfcaa + mfbba * mfbba * mfaac)
-                  +  2. * (mfcaa * mfaca * mfaac)
-                  + 16. *  mfbba * mfbab * mfabb)
-                  - c1o3* (mfacc + mfcac + mfcca) * oMdrho  -c1o9*oMdrho*oMdrho
-                  - c1o9* (mfcaa + mfaca + mfaac) * oMdrho*(1.-2.* oMdrho)- c1o27* oMdrho * oMdrho*(-2.* oMdrho)
-                  +( 2. * (mfbab * mfbab + mfabb * mfabb + mfbba * mfbba)
-                  +       (mfaac * mfaca + mfaac * mfcaa + mfaca * mfcaa)) * c2o3*oMdrho) +c1o27*oMdrho;
-
-               //2.
-               // linear combinations
-               LBMReal mxxPyyPzz = mfcaa + mfaca + mfaac;
-               LBMReal mxxMyy    = mfcaa - mfaca;
-               LBMReal mxxMzz         = mfcaa - mfaac;
-
-               LBMReal dxux = -c1o2 * collFactor *(mxxMyy + mxxMzz) + c1o2 * OxxPyyPzz*(mfaaa - mxxPyyPzz);
-               LBMReal dyuy = dxux + collFactor * c3o2 * mxxMyy;
-               LBMReal dzuz = dxux + collFactor * c3o2 * mxxMzz;
-
-               //relax
-               mxxPyyPzz += OxxPyyPzz*(mfaaa  - mxxPyyPzz)- 3. * (1. - c1o2 * OxxPyyPzz) * (vx2 * dxux + vy2 * dyuy + vz2 * dzuz);
-               mxxMyy    += collFactor * (-mxxMyy) - 3. * (1. - c1o2 * collFactor) * (vx2 * dxux - vy2 * dyuy);
-               mxxMzz    += collFactor * (-mxxMzz) - 3. * (1. - c1o2 * collFactor) * (vx2 * dxux - vz2 * dzuz);
-
-               mfabb     += collFactor * (-mfabb);
-               mfbab     += collFactor * (-mfbab);
-               mfbba     += collFactor * (-mfbba);
-
-               // linear combinations back
-               mfcaa = c1o3 * (       mxxMyy +      mxxMzz + mxxPyyPzz);
-               mfaca = c1o3 * (-2. *  mxxMyy +      mxxMzz + mxxPyyPzz);
-               mfaac = c1o3 * (       mxxMyy - 2. * 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
-               wadjust    = OxyyMxzz+(1.-OxyyMxzz)*fabs(mfbbb)/(fabs(mfbbb)+qudricLimit);
-               mfbbb     += wadjust * (-mfbbb);
-               wadjust    = OxyyPxzz+(1.-OxyyPxzz)*fabs(mxxyPyzz)/(fabs(mxxyPyzz)+qudricLimit);
-               mxxyPyzz  += wadjust * (-mxxyPyzz);
-               wadjust    = OxyyMxzz+(1.-OxyyMxzz)*fabs(mxxyMyzz)/(fabs(mxxyMyzz)+qudricLimit);
-               mxxyMyzz  += wadjust * (-mxxyMyzz);
-               wadjust    = OxyyPxzz+(1.-OxyyPxzz)*fabs(mxxzPyyz)/(fabs(mxxzPyyz)+qudricLimit);
-               mxxzPyyz  += wadjust * (-mxxzPyyz);
-               wadjust    = OxyyMxzz+(1.-OxyyMxzz)*fabs(mxxzMyyz)/(fabs(mxxzMyyz)+qudricLimit);
-               mxxzMyyz  += wadjust * (-mxxzMyyz);
-               wadjust    = OxyyPxzz+(1.-OxyyPxzz)*fabs(mxyyPxzz)/(fabs(mxyyPxzz)+qudricLimit);
-               mxyyPxzz  += wadjust * (-mxyyPxzz);
-               wadjust    = OxyyMxzz+(1.-OxyyMxzz)*fabs(mxyyMxzz)/(fabs(mxyyMxzz)+qudricLimit);
-               mxyyMxzz  += wadjust * (-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.
-               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 * oMdrho) * mfabb + 2. * mfbba * mfbab);
-               mfbcb = CUMbcb + ((mfaca + c1o3 * oMdrho) * mfbab + 2. * mfbba * mfabb);
-               mfbbc = CUMbbc + ((mfaac + c1o3 * oMdrho) * mfbba + 2. * mfbab * mfabb);
-
-               mfcca = CUMcca + (mfcaa * mfaca + 2. * mfbba * mfbba) + c1o3 * (mfcaa + mfaca) * oMdrho + c1o9*(oMdrho-1)*oMdrho;
-               mfcac = CUMcac + (mfcaa * mfaac + 2. * mfbab * mfbab) + c1o3 * (mfcaa + mfaac) * oMdrho + c1o9*(oMdrho-1)*oMdrho;
-               mfacc = CUMacc + (mfaac * mfaca + 2. * mfabb * mfabb) + c1o3 * (mfaac + mfaca) * oMdrho + c1o9*(oMdrho-1)*oMdrho;
-
-               //5.
-               mfbcc = CUMbcc + (mfaac * mfbca + mfaca * mfbac + 4. * mfabb * mfbbb + 2. * (mfbab * mfacb + mfbba * mfabc)) + c1o3 * (mfbca + mfbac) * oMdrho;
-               mfcbc = CUMcbc + (mfaac * mfcba + mfcaa * mfabc + 4. * mfbab * mfbbb + 2. * (mfabb * mfcab + mfbba * mfbac)) + c1o3 * (mfcba + mfabc) * oMdrho;
-               mfccb = CUMccb + (mfcaa * mfacb + mfaca * mfcab + 4. * mfbba * mfbbb + 2. * (mfbab * mfbca + mfabb * mfcba)) + c1o3 * (mfacb + mfcab) * oMdrho;
-
-               //6.
-               mfccc = CUMccc  -((-4. *  mfbbb * mfbbb 
-                  -       (mfcaa * mfacc + mfaca * mfcac + mfaac * mfcca)
-                  -  4. * (mfabb * mfcbb + mfbac * mfbca + mfbba * mfbbc)
-                  -  2. * (mfbca * mfbac + mfcba * mfabc + mfcab * mfacb))
-                  +( 4. * (mfbab * mfbab * mfaca + mfabb * mfabb * mfcaa + mfbba * mfbba * mfaac)
-                  +  2. * (mfcaa * mfaca * mfaac)
-                  + 16. *  mfbba * mfbab * mfabb)
-                  - c1o3* (mfacc + mfcac + mfcca) * oMdrho  -c1o9*oMdrho*oMdrho
-                  - c1o9* (mfcaa + mfaca + mfaac) * oMdrho*(1.-2.* oMdrho)- c1o27* oMdrho * oMdrho*(-2.* oMdrho)
-                  +( 2. * (mfbab * mfbab + mfabb * mfabb + mfbba * mfbba)
-                  +       (mfaac * mfaca + mfaac * mfcaa + mfaca * mfcaa)) * c2o3*oMdrho) -c1o27*oMdrho;
-
-               ////////////////////////////////////////////////////////////////////////////////////
-               //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 + 1. * oMdrho) * (     vz2 - vvz) * c1o2;
-               m1 = -mfaac        - 2. * mfaab *  vvz         +  mfaaa                * (1. - vz2)              - 1. * oMdrho * vz2;
-               m2 =  mfaac * c1o2 +      mfaab * (vvz + c1o2) + (mfaaa + 1. * oMdrho) * (     vz2 + vvz) * c1o2;
-               mfaaa = m0;
-               mfaab = m1;
-               mfaac = m2;
-               ////////////////////////////////////////////////////////////////////////////////////
-               m0 =  mfabc * c1o2 +      mfabb * (vvz - c1o2) + mfaba * (     vz2 - vvz) * c1o2;
-               m1 = -mfabc        - 2. * mfabb *  vvz         + mfaba * (1. - 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        - 2. * mfacb *  vvz         +  mfaca                  * (1. - 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        - 2. * mfbab *  vvz         + mfbaa * (1. - 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        - 2. * mfbbb *  vvz         + mfbba * (1. - 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        - 2. * mfbcb *  vvz         + mfbca * (1. - 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        - 2. * mfcab *  vvz         +  mfcaa                  * (1. - 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        - 2. * mfcbb *  vvz         + mfcba * (1. - 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        - 2. * mfccb *  vvz         +  mfcca                  * (1. - 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        - 2. * mfaba *  vvy         +  mfaaa                  * (1. - 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        - 2. * mfabb *  vvy         +  mfaab                  * (1. - 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        - 2. * mfabc *  vvy         +  mfaac                  * (1. - 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        - 2. * mfbba *  vvy         + mfbaa * (1. - 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        - 2. * mfbbb *  vvy         + mfbab * (1. - 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        - 2. * mfbbc *  vvy         + mfbac * (1. - 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        - 2. * mfcba *  vvy         +  mfcaa                   * (1. - 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        - 2. * mfcbb *  vvy         +  mfcab                  * (1. - 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        - 2. * mfcbc *  vvy         +  mfcac                   * (1. - 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        - 2. * mfbaa *  vvx         +  mfaaa                   * (1. - 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        - 2. * mfbba *  vvx         +  mfaba                  * (1. - 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        - 2. * mfbca *  vvx         +  mfaca                   * (1. - 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        - 2. * mfbab *  vvx         +  mfaab                  * (1. - 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        - 2. * mfbbb *  vvx         +  mfabb                  * (1. - 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        - 2. * mfbcb *  vvx         +  mfacb                  * (1. - 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        - 2. * mfbac *  vvx         +  mfaac                   * (1. - 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        - 2. * mfbbc *  vvx         +  mfabc                  * (1. - 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        - 2. * mfbcc *  vvx         +  mfacc                   * (1. - 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 rho_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 = rho - rho_post;
-#ifdef SINGLEPRECISION
-               if(dif > 10.0E-7 || dif < -10.0E-7)
-#else
-               if(dif > 10.0E-15 || dif < -10.0E-15)
-#endif
-               {
-                  UB_THROW(UbException(UB_EXARGS,"rho="+UbSystem::toString(rho)+", rho_post="+UbSystem::toString(rho_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;
-               //////////////////////////////////////////////////////////////////////////
-
-               collFactor = collFactor0;
-
-            }
-         }
-      }
-   }
-}
-
+#include "IncompressibleCumulantWithSpongeLayerLBMKernel.h"
+#include "D3Q27System.h"
+#include "D3Q27EsoTwist3DSplittedVector.h"
+#include <math.h>
+#include "DataSet3D.h"
+#include "BCArray3D.h"
+
+#define PROOF_CORRECTNESS
+
+//////////////////////////////////////////////////////////////////////////
+IncompressibleCumulantWithSpongeLayerLBMKernel::IncompressibleCumulantWithSpongeLayerLBMKernel()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+IncompressibleCumulantWithSpongeLayerLBMKernel::IncompressibleCumulantWithSpongeLayerLBMKernel(int nx1, int nx2, int nx3, Parameter p) 
+   : IncompressibleCumulantLBMKernel(nx1, nx2, nx3, p)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+IncompressibleCumulantWithSpongeLayerLBMKernel::~IncompressibleCumulantWithSpongeLayerLBMKernel(void)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void IncompressibleCumulantWithSpongeLayerLBMKernel::init()
+{
+   //DistributionArray3DPtr d(new D3Q27EsoTwist3DSplittedVector(nx1+ghostLayerWitdh*2, nx2+ghostLayerWitdh*2, nx3+ghostLayerWitdh*2, -999.0));
+   DistributionArray3DPtr d(new D3Q27EsoTwist3DSplittedVector(nx1+2, nx2+2, nx3+2, -999.0));
+   dataSet->setFdistributions(d);
+}
+//////////////////////////////////////////////////////////////////////////
+void IncompressibleCumulantWithSpongeLayerLBMKernel::setRelaxFactorParam(int vdir, double vL1, double vdx, double vSP)
+{
+   direction = vdir;
+   L1 = vL1;
+   dx = vdx;
+   SP = vSP;
+}
+//////////////////////////////////////////////////////////////////////////
+void IncompressibleCumulantWithSpongeLayerLBMKernel::initRelaxFactor(int vdir, double vL1, double vdx, double vSP)
+{
+   direction = vdir;
+   L1 = vL1;
+   dx = vdx;
+   SP = vSP;
+
+   double sizeX = L1 / dx;
+   double sizeSP = SP / dx;
+   double muX1, muX2, muX3;
+
+   LBMReal spongeFactor;
+
+   BCArray3DPtr bcArray = this->getBCProcessor()->getBCArray();
+
+   const int bcArrayMaxX1 = (int)bcArray->getNX1();
+   const int bcArrayMaxX2 = (int)bcArray->getNX2();
+   const int bcArrayMaxX3 = (int)bcArray->getNX3();
+
+   int minX1 = 0;
+   int minX2 = 0;
+   int minX3 = 0;
+   int maxX1 = bcArrayMaxX1 - ghostLayerWidth - 1;
+   int maxX2 = bcArrayMaxX2 - ghostLayerWidth - 1;
+   int maxX3 = bcArrayMaxX3 - ghostLayerWidth - 1;
+
+   RelaxationFactorArray3DPtr relaxationFactorPtr = CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<LBMReal, IndexerX3X2X1>(maxX1, maxX2, maxX3));
+   dataSet->setRelaxationFactor(relaxationFactorPtr);
+
+   for (int x3 = minX3; x3 < maxX3; x3++)
+   {
+      for (int x2 = minX2; x2 < maxX2; x2++)
+      {
+         for (int x1 = minX1; x1 < maxX1; x1++)
+         {
+            switch (direction)
+            {
+            case D3Q27System::E:
+               muX1 = (double)(x1 + ix1 * maxX1);
+               if (muX1 >= (sizeX - sizeSP) / deltaT)
+                  spongeFactor = (sizeX - (muX1 * deltaT + 1)) / sizeSP / 2.0 + 0.5;
+               else spongeFactor = 1.0;
+               break;
+            case D3Q27System::W:
+               muX1 = (double)(x1 + ix1 * maxX1);
+               if (muX1 <= sizeSP / deltaT)
+                  spongeFactor = (sizeSP - (muX1 * deltaT + 1)) / sizeSP / 2.0 + 0.5;
+               else spongeFactor = 1.0;
+               break;
+            case D3Q27System::N:
+               muX2 = (double)(x2 + ix2 * maxX2);
+               if (muX2 >= (sizeX - sizeSP) / deltaT)
+                  spongeFactor = (sizeX - (muX2 * deltaT + 1)) / sizeSP / 2.0 + 0.5;
+               else spongeFactor = 1.0;
+               break;
+            case D3Q27System::S:
+               muX2 = (double)(x2 + ix2 * maxX2);
+               if (muX2 <= sizeSP / deltaT)
+                  spongeFactor = (sizeSP - (muX2 * deltaT + 1)) / sizeSP / 2.0 + 0.5;
+               else spongeFactor = 1.0;
+               break;
+            case D3Q27System::T:
+               muX3 = (double)(x3 + ix3 * maxX3);
+               if (muX3 >= (sizeX - sizeSP) / deltaT)
+                  spongeFactor = (sizeX - (muX3 * deltaT + 1)) / sizeSP / 2.0 + 0.5;
+               else spongeFactor = 1.0;
+               break;
+            case D3Q27System::B:
+               muX3 = (double)(x3 + ix3 * maxX3);
+               if (muX3 <= sizeSP / deltaT)
+                  spongeFactor = (sizeSP - (muX3 * deltaT + 1)) / sizeSP / 2.0 + 0.5;
+               else spongeFactor = 1.0;
+               break;
+            default: throw UbException(UB_EXARGS, "unknown dir");
+            }
+            (*relaxationFactorPtr)(x1, x2, x3) = spongeFactor;
+         }
+      }
+   }
+}
+
+//////////////////////////////////////////////////////////////////////////
+LBMKernelPtr IncompressibleCumulantWithSpongeLayerLBMKernel::clone()
+{
+   LBMKernelPtr kernel(new IncompressibleCumulantWithSpongeLayerLBMKernel(nx1, nx2, nx3, parameter));
+   std::dynamic_pointer_cast<IncompressibleCumulantWithSpongeLayerLBMKernel>(kernel)->init();
+   kernel->setCollisionFactor(this->collFactor);
+   kernel->setBCProcessor(bcProcessor->clone(kernel));
+   kernel->setWithForcing(withForcing);
+   kernel->setForcingX1(muForcingX1);
+   kernel->setForcingX2(muForcingX2);
+   kernel->setForcingX3(muForcingX3);
+   kernel->setIndex(ix1, ix2, ix3);
+   kernel->setDeltaT(deltaT);
+   switch (parameter)
+   {
+   case NORMAL:
+      std::dynamic_pointer_cast<IncompressibleCumulantWithSpongeLayerLBMKernel>(kernel)->OxyyMxzz = 1.0;
+      break;
+   case MAGIC:
+      std::dynamic_pointer_cast<IncompressibleCumulantWithSpongeLayerLBMKernel>(kernel)->OxyyMxzz = 2.0 +(-collFactor);
+      break;
+   }
+
+   kernel->setWithSpongeLayer(withSpongeLayer);
+   if(withSpongeLayer) kernel->setSpongeLayer(muSpongeLayer);
+   std::dynamic_pointer_cast<IncompressibleCumulantWithSpongeLayerLBMKernel>(kernel)->initRelaxFactor(direction, L1, dx, SP);
+   return kernel;
+}  
+//////////////////////////////////////////////////////////////////////////
+void IncompressibleCumulantWithSpongeLayerLBMKernel::calculate()
+{
+   timer.resetAndStart();
+   collideAll();
+   timer.stop();
+}
+//////////////////////////////////////////////////////////////////////////
+void IncompressibleCumulantWithSpongeLayerLBMKernel::collideAll()
+{
+   using namespace D3Q27System;
+
+   if(!withSpongeLayer)
+   {
+      UB_THROW(UbException(UB_EXARGS,"Sponge layer isn't initialized!"));
+   }
+   //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);
+
+   //   muDeltaT = deltaT;
+
+   //   muForcingX1.DefineVar("dx",&muDeltaT);
+   //   muForcingX2.DefineVar("dx",&muDeltaT);
+   //   muForcingX3.DefineVar("dx",&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);
+
+   //   LBMReal forcingX1 = 0;
+   //   LBMReal forcingX2 = 0;
+   //   LBMReal forcingX3 = 0;
+   //}
+   /////////////////////////////////////
+   //initialization of sponge layer variables
+   //if (withSpongeLayer)
+   //{
+      //muDeltaT = deltaT;
+      //muSpongeLayer.DefineVar("dt",&muDeltaT);
+      //muSpongeLayer.DefineVar("x1",&muX1); muSpongeLayer.DefineVar("x2",&muX2); muSpongeLayer.DefineVar("x3",&muX3);
+   //}
+   /////////////////////////////////////
+
+   localDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getLocalDistributions();
+   nonLocalDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getNonLocalDistributions();
+   zeroDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getZeroDistributions();
+
+   BCArray3DPtr bcArray = this->getBCProcessor()->getBCArray();
+   RelaxationFactorArray3DPtr relaxationFactorPtr = dataSet->getRelaxationFactor();
+
+   const int bcArrayMaxX1 = (int)bcArray->getNX1();
+   const int bcArrayMaxX2 = (int)bcArray->getNX2();
+   const int bcArrayMaxX3 = (int)bcArray->getNX3();
+
+   int minX1 = ghostLayerWidth;
+   int minX2 = ghostLayerWidth;
+   int minX3 = ghostLayerWidth;
+   int maxX1 = bcArrayMaxX1-ghostLayerWidth-1;
+   int maxX2 = bcArrayMaxX2-ghostLayerWidth-1;
+   int maxX3 = bcArrayMaxX3-ghostLayerWidth-1;
+
+   LBMReal collFactor0 = collFactor;
+   LBMReal spongeFactor;
+
+   for(int x3 = minX3; x3 <= maxX3; x3++)
+   {
+      for(int x2 = minX2; x2 <= maxX2; x2++)
+      {
+         for(int x1 = minX1; x1 <= maxX1; x1++)
+         {
+            if(!bcArray->isSolid(x1,x2,x3) && !bcArray->isUndefined(x1,x2,x3))
+            {
+               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
+
+               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 m0, m1, m2;
+               
+               LBMReal rho=(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 vvx    =((((mfccc-mfaaa) + (mfcac-mfaca)) + ((mfcaa-mfacc) + (mfcca-mfaac))) +
+                  (((mfcba-mfabc) + (mfcbc-mfaba)) + ((mfcab-mfacb) + (mfccb-mfaab))) +
+                  (mfcbb-mfabb));
+               LBMReal vvy    =((((mfccc-mfaaa) + (mfaca-mfcac)) + ((mfacc-mfcaa) + (mfcca-mfaac))) +
+                  (((mfbca-mfbac) + (mfbcc-mfbaa)) + ((mfacb-mfcab) + (mfccb-mfaab))) +
+                  (mfbcb-mfbab));
+               LBMReal vvz    =((((mfccc-mfaaa) + (mfcac-mfaca)) + ((mfacc-mfcaa) + (mfaac-mfcca))) +
+                  (((mfbac-mfbca) + (mfbcc-mfbaa)) + ((mfabc-mfcba) + (mfcbc-mfaba))) +
+                  (mfbbc-mfbba));
+               //////////////////////////////////////////////////////////////////////////
+               //forcing 
+               ///////////////////////////////////////////////////////////////////////////////////////////
+               //if (withForcing)
+               //{
+               //   muX1 = (double)(x1-1+ix1*maxX1);
+               //   muX2 = (double)(x2-1+ix2*maxX2);
+               //   muX3 = (double)(x3-1+ix3*maxX3);
+
+               //   forcingX1 = muForcingX1.Eval();
+               //   forcingX2 = muForcingX2.Eval();
+               //   forcingX3 = muForcingX3.Eval();
+
+               //   vvx += forcingX1*0.5; // X
+               //   vvy += forcingX2*0.5; // Y
+               //   vvz += forcingX3*0.5; // Z
+               //}
+               ///////////////////////////////////////////////////////////////////////////////////////////      
+               //sponge layer
+               ///////////////////////////////////////////////////////////////////////////////////////////
+               //if (withSpongeLayer)
+               //{
+                  //if (!withForcing)
+                  //{
+                    //lk// muX1 = (double)(x1-1+ix1*maxX1);
+                     //muX2 = (double)(x2-1+ix2*maxX2);
+                     //muX3 = (double)(x3-1+ix3*maxX3);
+                  //}
+                  //spongeFactor ist von Funktion in muSpongeLayer abhängich und variiert zwischen 1 (nix tun) und 0.5 (collFactor etwa auf 1);
+                  //lk //LBMReal spongeFactor = muSpongeLayer.Eval();
+
+                  //if (spongeFactor == 0.5)
+                  //{
+                  //   int Test=0;
+                  //}
+
+                  //if(muX3 == ix3*maxX3/2 && muX2==ix2*maxX2/2)
+                  //   UBLOG(logINFO," x1="<<muX1<<" spongeFactor = " << spongeFactor <<" collFactor="<<collFactor);
+
+                  spongeFactor = (*relaxationFactorPtr)(x1-1, x2-1, x3-1);
+                  collFactor *= spongeFactor;
+                  //if(muX3 == ix3*maxX3/2 && muX2==ix2*maxX2/2)
+                  //   UBLOG(logINFO," x1="<<muX1<<" spongeFactor = " << spongeFactor <<" collFactor="<<collFactor);
+
+               //}
+               //////////////////////////////////////////////////////////////////////////
+
+               LBMReal oMdrho;
+
+               oMdrho=mfccc+mfaaa;
+               m0=mfaca+mfcac;
+               m1=mfacc+mfcaa;
+               m2=mfaac+mfcca;
+               oMdrho+=m0;
+               m1+=m2; 
+               oMdrho+=m1;
+               m0=mfbac+mfbca;
+               m1=mfbaa+mfbcc;
+               m0+=m1;
+               m1=mfabc+mfcba;
+               m2=mfaba+mfcbc;
+               m1+=m2;
+               m0+=m1;
+               m1=mfacb+mfcab;
+               m2=mfaab+mfccb;
+               m1+=m2;
+               m0+=m1;
+               oMdrho+=m0;
+               m0=mfabb+mfcbb;
+               m1=mfbab+mfbcb;
+               m2=mfbba+mfbbc;
+               m0+=m1+m2;
+               m0+=mfbbb; //hat gefehlt
+               oMdrho = 1. - (oMdrho + m0);
+
+               LBMReal vx2;
+               LBMReal vy2;
+               LBMReal vz2;
+               vx2=vvx*vvx;
+               vy2=vvy*vvy;
+               vz2=vvz*vvz;
+               ////////////////////////////////////////////////////////////////////////////////////
+               LBMReal wadjust;
+               LBMReal qudricLimit = 0.01;
+               ////////////////////////////////////////////////////////////////////////////////////
+               //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 - 2. *   m1 * vvz + vz2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfaba  + mfabc;
+               m1    = mfabc  - mfaba;
+               m0    = m2          + mfabb;
+               mfaba = m0;
+               m0   += c1o9 * oMdrho;
+               mfabb = m1 -        m0 * vvz;
+               mfabc = m2 - 2. *   m1 * vvz + vz2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfaca  + mfacc;
+               m1    = mfacc  - mfaca;
+               m0    = m2          + mfacb;
+               mfaca = m0;
+               m0   += c1o36 * oMdrho;
+               mfacb = m1 -        m0 * vvz;
+               mfacc = m2 - 2. *   m1 * vvz + vz2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfbaa + mfbac;
+               m1    = mfbac - mfbaa;
+               m0    = m2          + mfbab;
+               mfbaa = m0;
+               m0   += c1o9 * oMdrho;
+               mfbab = m1 -        m0 * vvz;
+               mfbac = m2 - 2. *   m1 * vvz + vz2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfbba  + mfbbc;
+               m1    = mfbbc  - mfbba;
+               m0    = m2          + mfbbb;
+               mfbba = m0;
+               m0   += c4o9 * oMdrho;
+               mfbbb = m1 -        m0 * vvz;
+               mfbbc = m2 - 2. *   m1 * vvz + vz2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfbca  + mfbcc;
+               m1    = mfbcc  - mfbca;
+               m0    = m2          + mfbcb;
+               mfbca = m0;
+               m0   += c1o9 * oMdrho;
+               mfbcb = m1 -        m0 * vvz;
+               mfbcc = m2 - 2. *   m1 * vvz + vz2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfcaa + mfcac;
+               m1    = mfcac - mfcaa;
+               m0    = m2          + mfcab;
+               mfcaa = m0;
+               m0   += c1o36 * oMdrho;
+               mfcab = m1 -        m0 * vvz;
+               mfcac = m2 - 2. *   m1 * vvz + vz2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfcba  + mfcbc;
+               m1    = mfcbc  - mfcba;
+               m0    = m2          + mfcbb;
+               mfcba = m0;
+               m0   += c1o9 * oMdrho;
+               mfcbb = m1 -        m0 * vvz;
+               mfcbc = m2 - 2. *   m1 * vvz + vz2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfcca  + mfccc;
+               m1    = mfccc  - mfcca;
+               m0    = m2          + mfccb;
+               mfcca = m0;
+               m0   += c1o36 * oMdrho;
+               mfccb = m1 -        m0 * vvz;
+               mfccc = m2 - 2. *   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 - 2. *   m1 * vvy + vy2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfaab  + mfacb;
+               m1    = mfacb  - mfaab;
+               m0    = m2          + mfabb;
+               mfaab = m0;
+               mfabb = m1 -        m0 * vvy;
+               mfacb = m2 - 2. *   m1 * vvy + vy2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfaac  + mfacc;
+               m1    = mfacc  - mfaac;
+               m0    = m2          + mfabc;
+               mfaac = m0;
+               m0   += c1o18 * oMdrho;
+               mfabc = m1 -        m0 * vvy;
+               mfacc = m2 - 2. *   m1 * vvy + vy2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfbaa + mfbca;
+               m1    = mfbca - mfbaa;
+               m0    = m2          + mfbba;
+               mfbaa = m0;
+               m0   += c2o3 * oMdrho;
+               mfbba = m1 -        m0 * vvy;
+               mfbca = m2 - 2. *   m1 * vvy + vy2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfbab  + mfbcb;
+               m1    = mfbcb  - mfbab;
+               m0    = m2          + mfbbb;
+               mfbab = m0;
+               mfbbb = m1 -        m0 * vvy;
+               mfbcb = m2 - 2. *   m1 * vvy + vy2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfbac  + mfbcc;
+               m1    = mfbcc  - mfbac;
+               m0    = m2          + mfbbc;
+               mfbac = m0;
+               m0   += c2o9 * oMdrho;
+               mfbbc = m1 -        m0 * vvy;
+               mfbcc = m2 - 2. *   m1 * vvy + vy2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfcaa + mfcca;
+               m1    = mfcca - mfcaa;
+               m0    = m2          + mfcba;
+               mfcaa = m0;
+               m0   += c1o6 * oMdrho;
+               mfcba = m1 -        m0 * vvy;
+               mfcca = m2 - 2. *   m1 * vvy + vy2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfcab  + mfccb;
+               m1    = mfccb  - mfcab;
+               m0    = m2          + mfcbb;
+               mfcab = m0;
+               mfcbb = m1 -        m0 * vvy;
+               mfccb = m2 - 2. *   m1 * vvy + vy2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfcac  + mfccc;
+               m1    = mfccc  - mfcac;
+               m0    = m2          + mfcbc;
+               mfcac = m0;
+               m0   += c1o18 * oMdrho;
+               mfcbc = m1 -        m0 * vvy;
+               mfccc = m2 - 2. *   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   += 1. * oMdrho;
+               mfbaa = m1 -        m0 * vvx;
+               mfcaa = m2 - 2. *   m1 * vvx + vx2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfaba  + mfcba;
+               m1    = mfcba  - mfaba;
+               m0    = m2          + mfbba;
+               mfaba = m0;
+               mfbba = m1 -        m0 * vvx;
+               mfcba = m2 - 2. *   m1 * vvx + vx2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfaca  + mfcca;
+               m1    = mfcca  - mfaca;
+               m0    = m2          + mfbca;
+               mfaca = m0;
+               m0   += c1o3 * oMdrho;
+               mfbca = m1 -        m0 * vvx;
+               mfcca = m2 - 2. *   m1 * vvx + vx2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfaab + mfcab;
+               m1    = mfcab - mfaab;
+               m0    = m2          + mfbab;
+               mfaab = m0;
+               mfbab = m1 -        m0 * vvx;
+               mfcab = m2 - 2. *   m1 * vvx + vx2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfabb  + mfcbb;
+               m1    = mfcbb  - mfabb;
+               m0    = m2          + mfbbb;
+               mfabb = m0;
+               mfbbb = m1 -        m0 * vvx;
+               mfcbb = m2 - 2. *   m1 * vvx + vx2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfacb  + mfccb;
+               m1    = mfccb  - mfacb;
+               m0    = m2          + mfbcb;
+               mfacb = m0;
+               mfbcb = m1 -        m0 * vvx;
+               mfccb = m2 - 2. *   m1 * vvx + vx2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfaac + mfcac;
+               m1    = mfcac - mfaac;
+               m0    = m2          + mfbac;
+               mfaac = m0;
+               m0   += c1o3 * oMdrho;
+               mfbac = m1 -        m0 * vvx;
+               mfcac = m2 - 2. *   m1 * vvx + vx2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfabc  + mfcbc;
+               m1    = mfcbc  - mfabc;
+               m0    = m2          + mfbbc;
+               mfabc = m0;
+               mfbbc = m1 -        m0 * vvx;
+               mfcbc = m2 - 2. *   m1 * vvx + vx2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m2    = mfacc  + mfccc;
+               m1    = mfccc  - mfacc;
+               m0    = m2          + mfbcc;
+               mfacc = m0;
+               m0   += c1o9 * oMdrho;
+               mfbcc = m1 -        m0 * vvx;
+               mfccc = m2 - 2. *   m1 * vvx + vx2 * m0;
+               ////////////////////////////////////////////////////////////////////////////////////
+               // Cumulants
+               ////////////////////////////////////////////////////////////////////////////////////
+               LBMReal OxxPyyPzz = 1.;
+               LBMReal OxyyPxzz  = 1.;//-s9;//2+s9;//
+               //LBMReal OxyyMxzz  = 1.;//2+s9;//
+               LBMReal O4        = 1.;
+               LBMReal O5        = 1.;
+               LBMReal O6        = 1.;
+
+               //Cum 4.
+               LBMReal CUMcbb = mfcbb - ((mfcaa + c1o3 * oMdrho) * mfabb + 2. * mfbba * mfbab);
+               LBMReal CUMbcb = mfbcb - ((mfaca + c1o3 * oMdrho) * mfbab + 2. * mfbba * mfabb);
+               LBMReal CUMbbc = mfbbc - ((mfaac + c1o3 * oMdrho) * mfbba + 2. * mfbab * mfabb);
+
+               LBMReal CUMcca = mfcca - (mfcaa * mfaca + 2. * mfbba * mfbba) + c1o3 * (mfcaa + mfaca) * oMdrho + c1o9*(oMdrho-1)*oMdrho;
+               LBMReal CUMcac = mfcac - (mfcaa * mfaac + 2. * mfbab * mfbab) + c1o3 * (mfcaa + mfaac) * oMdrho + c1o9*(oMdrho-1)*oMdrho;
+               LBMReal CUMacc = mfacc - (mfaac * mfaca + 2. * mfabb * mfabb) + c1o3 * (mfaac + mfaca) * oMdrho + c1o9*(oMdrho-1)*oMdrho;
+
+               //Cum 5.
+               LBMReal CUMbcc = mfbcc - (mfaac * mfbca + mfaca * mfbac + 4. * mfabb * mfbbb + 2. * (mfbab * mfacb + mfbba * mfabc)) - c1o3 * (mfbca + mfbac) * oMdrho;
+               LBMReal CUMcbc = mfcbc - (mfaac * mfcba + mfcaa * mfabc + 4. * mfbab * mfbbb + 2. * (mfabb * mfcab + mfbba * mfbac)) - c1o3 * (mfcba + mfabc) * oMdrho;
+               LBMReal CUMccb = mfccb - (mfcaa * mfacb + mfaca * mfcab + 4. * mfbba * mfbbb + 2. * (mfbab * mfbca + mfabb * mfcba)) - c1o3 * (mfacb + mfcab) * oMdrho;
+
+               //Cum 6.
+               LBMReal CUMccc = mfccc  +((-4. *  mfbbb * mfbbb 
+                  -       (mfcaa * mfacc + mfaca * mfcac + mfaac * mfcca)
+                  -  4. * (mfabb * mfcbb + mfbab * mfbcb + mfbba * mfbbc)
+                  -  2. * (mfbca * mfbac + mfcba * mfabc + mfcab * mfacb))
+                  +( 4. * (mfbab * mfbab * mfaca + mfabb * mfabb * mfcaa + mfbba * mfbba * mfaac)
+                  +  2. * (mfcaa * mfaca * mfaac)
+                  + 16. *  mfbba * mfbab * mfabb)
+                  - c1o3* (mfacc + mfcac + mfcca) * oMdrho  -c1o9*oMdrho*oMdrho
+                  - c1o9* (mfcaa + mfaca + mfaac) * oMdrho*(1.-2.* oMdrho)- c1o27* oMdrho * oMdrho*(-2.* oMdrho)
+                  +( 2. * (mfbab * mfbab + mfabb * mfabb + mfbba * mfbba)
+                  +       (mfaac * mfaca + mfaac * mfcaa + mfaca * mfcaa)) * c2o3*oMdrho) +c1o27*oMdrho;
+
+               //2.
+               // linear combinations
+               LBMReal mxxPyyPzz = mfcaa + mfaca + mfaac;
+               LBMReal mxxMyy    = mfcaa - mfaca;
+               LBMReal mxxMzz         = mfcaa - mfaac;
+
+               LBMReal dxux = -c1o2 * collFactor *(mxxMyy + mxxMzz) + c1o2 * OxxPyyPzz*(mfaaa - mxxPyyPzz);
+               LBMReal dyuy = dxux + collFactor * c3o2 * mxxMyy;
+               LBMReal dzuz = dxux + collFactor * c3o2 * mxxMzz;
+
+               //relax
+               mxxPyyPzz += OxxPyyPzz*(mfaaa  - mxxPyyPzz)- 3. * (1. - c1o2 * OxxPyyPzz) * (vx2 * dxux + vy2 * dyuy + vz2 * dzuz);
+               mxxMyy    += collFactor * (-mxxMyy) - 3. * (1. - c1o2 * collFactor) * (vx2 * dxux - vy2 * dyuy);
+               mxxMzz    += collFactor * (-mxxMzz) - 3. * (1. - c1o2 * collFactor) * (vx2 * dxux - vz2 * dzuz);
+
+               mfabb     += collFactor * (-mfabb);
+               mfbab     += collFactor * (-mfbab);
+               mfbba     += collFactor * (-mfbba);
+
+               // linear combinations back
+               mfcaa = c1o3 * (       mxxMyy +      mxxMzz + mxxPyyPzz);
+               mfaca = c1o3 * (-2. *  mxxMyy +      mxxMzz + mxxPyyPzz);
+               mfaac = c1o3 * (       mxxMyy - 2. * 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
+               wadjust    = OxyyMxzz+(1.-OxyyMxzz)*fabs(mfbbb)/(fabs(mfbbb)+qudricLimit);
+               mfbbb     += wadjust * (-mfbbb);
+               wadjust    = OxyyPxzz+(1.-OxyyPxzz)*fabs(mxxyPyzz)/(fabs(mxxyPyzz)+qudricLimit);
+               mxxyPyzz  += wadjust * (-mxxyPyzz);
+               wadjust    = OxyyMxzz+(1.-OxyyMxzz)*fabs(mxxyMyzz)/(fabs(mxxyMyzz)+qudricLimit);
+               mxxyMyzz  += wadjust * (-mxxyMyzz);
+               wadjust    = OxyyPxzz+(1.-OxyyPxzz)*fabs(mxxzPyyz)/(fabs(mxxzPyyz)+qudricLimit);
+               mxxzPyyz  += wadjust * (-mxxzPyyz);
+               wadjust    = OxyyMxzz+(1.-OxyyMxzz)*fabs(mxxzMyyz)/(fabs(mxxzMyyz)+qudricLimit);
+               mxxzMyyz  += wadjust * (-mxxzMyyz);
+               wadjust    = OxyyPxzz+(1.-OxyyPxzz)*fabs(mxyyPxzz)/(fabs(mxyyPxzz)+qudricLimit);
+               mxyyPxzz  += wadjust * (-mxyyPxzz);
+               wadjust    = OxyyMxzz+(1.-OxyyMxzz)*fabs(mxyyMxzz)/(fabs(mxyyMxzz)+qudricLimit);
+               mxyyMxzz  += wadjust * (-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.
+               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 * oMdrho) * mfabb + 2. * mfbba * mfbab);
+               mfbcb = CUMbcb + ((mfaca + c1o3 * oMdrho) * mfbab + 2. * mfbba * mfabb);
+               mfbbc = CUMbbc + ((mfaac + c1o3 * oMdrho) * mfbba + 2. * mfbab * mfabb);
+
+               mfcca = CUMcca + (mfcaa * mfaca + 2. * mfbba * mfbba) + c1o3 * (mfcaa + mfaca) * oMdrho + c1o9*(oMdrho-1)*oMdrho;
+               mfcac = CUMcac + (mfcaa * mfaac + 2. * mfbab * mfbab) + c1o3 * (mfcaa + mfaac) * oMdrho + c1o9*(oMdrho-1)*oMdrho;
+               mfacc = CUMacc + (mfaac * mfaca + 2. * mfabb * mfabb) + c1o3 * (mfaac + mfaca) * oMdrho + c1o9*(oMdrho-1)*oMdrho;
+
+               //5.
+               mfbcc = CUMbcc + (mfaac * mfbca + mfaca * mfbac + 4. * mfabb * mfbbb + 2. * (mfbab * mfacb + mfbba * mfabc)) + c1o3 * (mfbca + mfbac) * oMdrho;
+               mfcbc = CUMcbc + (mfaac * mfcba + mfcaa * mfabc + 4. * mfbab * mfbbb + 2. * (mfabb * mfcab + mfbba * mfbac)) + c1o3 * (mfcba + mfabc) * oMdrho;
+               mfccb = CUMccb + (mfcaa * mfacb + mfaca * mfcab + 4. * mfbba * mfbbb + 2. * (mfbab * mfbca + mfabb * mfcba)) + c1o3 * (mfacb + mfcab) * oMdrho;
+
+               //6.
+               mfccc = CUMccc  -((-4. *  mfbbb * mfbbb 
+                  -       (mfcaa * mfacc + mfaca * mfcac + mfaac * mfcca)
+                  -  4. * (mfabb * mfcbb + mfbac * mfbca + mfbba * mfbbc)
+                  -  2. * (mfbca * mfbac + mfcba * mfabc + mfcab * mfacb))
+                  +( 4. * (mfbab * mfbab * mfaca + mfabb * mfabb * mfcaa + mfbba * mfbba * mfaac)
+                  +  2. * (mfcaa * mfaca * mfaac)
+                  + 16. *  mfbba * mfbab * mfabb)
+                  - c1o3* (mfacc + mfcac + mfcca) * oMdrho  -c1o9*oMdrho*oMdrho
+                  - c1o9* (mfcaa + mfaca + mfaac) * oMdrho*(1.-2.* oMdrho)- c1o27* oMdrho * oMdrho*(-2.* oMdrho)
+                  +( 2. * (mfbab * mfbab + mfabb * mfabb + mfbba * mfbba)
+                  +       (mfaac * mfaca + mfaac * mfcaa + mfaca * mfcaa)) * c2o3*oMdrho) -c1o27*oMdrho;
+
+               ////////////////////////////////////////////////////////////////////////////////////
+               //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 + 1. * oMdrho) * (     vz2 - vvz) * c1o2;
+               m1 = -mfaac        - 2. * mfaab *  vvz         +  mfaaa                * (1. - vz2)              - 1. * oMdrho * vz2;
+               m2 =  mfaac * c1o2 +      mfaab * (vvz + c1o2) + (mfaaa + 1. * oMdrho) * (     vz2 + vvz) * c1o2;
+               mfaaa = m0;
+               mfaab = m1;
+               mfaac = m2;
+               ////////////////////////////////////////////////////////////////////////////////////
+               m0 =  mfabc * c1o2 +      mfabb * (vvz - c1o2) + mfaba * (     vz2 - vvz) * c1o2;
+               m1 = -mfabc        - 2. * mfabb *  vvz         + mfaba * (1. - 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        - 2. * mfacb *  vvz         +  mfaca                  * (1. - 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        - 2. * mfbab *  vvz         + mfbaa * (1. - 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        - 2. * mfbbb *  vvz         + mfbba * (1. - 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        - 2. * mfbcb *  vvz         + mfbca * (1. - 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        - 2. * mfcab *  vvz         +  mfcaa                  * (1. - 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        - 2. * mfcbb *  vvz         + mfcba * (1. - 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        - 2. * mfccb *  vvz         +  mfcca                  * (1. - 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        - 2. * mfaba *  vvy         +  mfaaa                  * (1. - 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        - 2. * mfabb *  vvy         +  mfaab                  * (1. - 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        - 2. * mfabc *  vvy         +  mfaac                  * (1. - 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        - 2. * mfbba *  vvy         + mfbaa * (1. - 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        - 2. * mfbbb *  vvy         + mfbab * (1. - 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        - 2. * mfbbc *  vvy         + mfbac * (1. - 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        - 2. * mfcba *  vvy         +  mfcaa                   * (1. - 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        - 2. * mfcbb *  vvy         +  mfcab                  * (1. - 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        - 2. * mfcbc *  vvy         +  mfcac                   * (1. - 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        - 2. * mfbaa *  vvx         +  mfaaa                   * (1. - 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        - 2. * mfbba *  vvx         +  mfaba                  * (1. - 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        - 2. * mfbca *  vvx         +  mfaca                   * (1. - 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        - 2. * mfbab *  vvx         +  mfaab                  * (1. - 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        - 2. * mfbbb *  vvx         +  mfabb                  * (1. - 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        - 2. * mfbcb *  vvx         +  mfacb                  * (1. - 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        - 2. * mfbac *  vvx         +  mfaac                   * (1. - 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        - 2. * mfbbc *  vvx         +  mfabc                  * (1. - 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        - 2. * mfbcc *  vvx         +  mfacc                   * (1. - 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 rho_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 = rho - rho_post;
+#ifdef SINGLEPRECISION
+               if(dif > 10.0E-7 || dif < -10.0E-7)
+#else
+               if(dif > 10.0E-15 || dif < -10.0E-15)
+#endif
+               {
+                  UB_THROW(UbException(UB_EXARGS,"rho="+UbSystem::toString(rho)+", rho_post="+UbSystem::toString(rho_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;
+               //////////////////////////////////////////////////////////////////////////
+
+               collFactor = collFactor0;
+
+            }
+         }
+      }
+   }
+}
+
diff --git a/source/VirtualFluidsCore/LBM/IncompressibleCumulantWithSpongeLayerLBMKernel.h b/source/VirtualFluidsCore/LBM/IncompressibleCumulantWithSpongeLayerLBMKernel.h
index 0931848fc..1072b6b2e 100644
--- a/source/VirtualFluidsCore/LBM/IncompressibleCumulantWithSpongeLayerLBMKernel.h
+++ b/source/VirtualFluidsCore/LBM/IncompressibleCumulantWithSpongeLayerLBMKernel.h
@@ -10,7 +10,7 @@
 #include "basics/container/CbArray3D.h"
 
 class IncompressibleCumulantWithSpongeLayerLBMKernel;
-typedef boost::shared_ptr<IncompressibleCumulantWithSpongeLayerLBMKernel> LBMKernelETD3Q27CCLBWithSpongeLayerPtr;
+typedef std::shared_ptr<IncompressibleCumulantWithSpongeLayerLBMKernel> LBMKernelETD3Q27CCLBWithSpongeLayerPtr;
 
 //! \brief   Cascaded Cumulant LBM kernel. 
 //! \details CFD solver with sponge layer that use Cascaded Cumulant Lattice Boltzmann method for D3Q27 model <br>
diff --git a/source/VirtualFluidsCore/LBM/IncompressibleOffsetInterpolationProcessor.cpp b/source/VirtualFluidsCore/LBM/IncompressibleOffsetInterpolationProcessor.cpp
index d5038cce1..70961b99e 100644
--- a/source/VirtualFluidsCore/LBM/IncompressibleOffsetInterpolationProcessor.cpp
+++ b/source/VirtualFluidsCore/LBM/IncompressibleOffsetInterpolationProcessor.cpp
@@ -1,7 +1,7 @@
 #include "IncompressibleOffsetInterpolationProcessor.h"
 #include "D3Q27System.h"
 
-#include <boost/foreach.hpp>
+
 
 IncompressibleOffsetInterpolationProcessor::IncompressibleOffsetInterpolationProcessor()
    : omegaC(0.0), omegaF(0.0)
@@ -24,8 +24,8 @@ IncompressibleOffsetInterpolationProcessor::~IncompressibleOffsetInterpolationPr
 InterpolationProcessorPtr IncompressibleOffsetInterpolationProcessor::clone()
 {
    InterpolationProcessorPtr iproc = InterpolationProcessorPtr (new IncompressibleOffsetInterpolationProcessor(this->omegaC, this->omegaF));
-   //boost::dynamic_pointer_cast<D3Q27IncompressibleOffsetInterpolationProcessor>(iproc)->forcingC = forcingC;
-   //boost::dynamic_pointer_cast<D3Q27IncompressibleOffsetInterpolationProcessor>(iproc)->forcingF = forcingF;
+   //std::dynamic_pointer_cast<D3Q27IncompressibleOffsetInterpolationProcessor>(iproc)->forcingC = forcingC;
+   //std::dynamic_pointer_cast<D3Q27IncompressibleOffsetInterpolationProcessor>(iproc)->forcingF = forcingF;
    return iproc;
 }
 //////////////////////////////////////////////////////////////////////////
diff --git a/source/VirtualFluidsCore/LBM/IncompressibleOffsetInterpolationProcessor.h b/source/VirtualFluidsCore/LBM/IncompressibleOffsetInterpolationProcessor.h
index c3df12a8a..6cef073ab 100644
--- a/source/VirtualFluidsCore/LBM/IncompressibleOffsetInterpolationProcessor.h
+++ b/source/VirtualFluidsCore/LBM/IncompressibleOffsetInterpolationProcessor.h
@@ -10,7 +10,7 @@
 //////////////////////////////////////////////////////////////////////////
 
 class IncompressibleOffsetInterpolationProcessor;
-typedef boost::shared_ptr<IncompressibleOffsetInterpolationProcessor> D3Q27IncompressibleOffsetInterpolationProcessorPtr;
+typedef std::shared_ptr<IncompressibleOffsetInterpolationProcessor> D3Q27IncompressibleOffsetInterpolationProcessorPtr;
 
 class IncompressibleOffsetInterpolationProcessor : public InterpolationProcessor
 {
diff --git a/source/VirtualFluidsCore/LBM/InitDensityLBMKernel.cpp b/source/VirtualFluidsCore/LBM/InitDensityLBMKernel.cpp
index 8440ed46c..a8f4aa4c0 100644
--- a/source/VirtualFluidsCore/LBM/InitDensityLBMKernel.cpp
+++ b/source/VirtualFluidsCore/LBM/InitDensityLBMKernel.cpp
@@ -1,1078 +1,1080 @@
-#include "InitDensityLBMKernel.h"
-#include "D3Q27EsoTwist3DSplittedVector.h"
-#include "BCProcessor.h"
-
-InitDensityLBMKernel::InitDensityLBMKernel()
-{
-}
-
-InitDensityLBMKernel::~InitDensityLBMKernel()
-{
-}
-
-InitDensityLBMKernel::InitDensityLBMKernel(int nx1, int nx2, int nx3)
-{
-   this->nx1 = nx1;
-   this->nx2 = nx2;
-   this->nx3 = nx3;
-   this->compressible = false;
-}
-
-void InitDensityLBMKernel::calculate()
-{
-   collideAll();
-}
-
-LBMKernelPtr InitDensityLBMKernel::clone()
-{
-   LBMKernelPtr kernel(new InitDensityLBMKernel(nx1, nx2, nx3));
-   boost::dynamic_pointer_cast<InitDensityLBMKernel>(kernel)->init();
-   kernel->setCollisionFactor(this->collFactor);
-   kernel->setBCProcessor(bcProcessor->clone(kernel));
-   kernel->setWithForcing(withForcing);
-   kernel->setForcingX1(muForcingX1);
-   kernel->setForcingX2(muForcingX2);
-   kernel->setForcingX3(muForcingX3);
-   kernel->setIndex(ix1, ix2, ix3);
-   kernel->setDeltaT(deltaT);
-   boost::dynamic_pointer_cast<InitDensityLBMKernel>(kernel)->OxyyMxzz = 1.0;
-   return kernel;
-}
-
-void InitDensityLBMKernel::setVelocity(int x1, int x2, int x3, LBMReal vvx, LBMReal vvy, LBMReal vvz)
-{
-   v(0, x1, x2, x3) = vvx;
-   v(1, x1, x2, x3) = vvy;
-   v(2, x1, x2, x3) = vvz;
-}
-
-double InitDensityLBMKernel::getCallculationTime()
-{
-   return 0;
-}
-
-//void InitDensityLBMKernel::collideAll()
-//{
-//   using namespace D3Q27System;
-//
-//   localDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getLocalDistributions();
-//   nonLocalDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getNonLocalDistributions();
-//   zeroDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getZeroDistributions();
-//
-//   BCArray3D<D3Q27BoundaryCondition>& bcArray = boost::dynamic_pointer_cast<D3Q27ETBCProcessor>(this->getBCProcessor())->getBCArray();
-//
-//   const int bcArrayMaxX1 = (int)bcArray->getNX1();
-//   const int bcArrayMaxX2 = (int)bcArray->getNX2();
-//   const int bcArrayMaxX3 = (int)bcArray->getNX3();
-//
-//   int minX1 = ghostLayerWidth;
-//   int minX2 = ghostLayerWidth;
-//   int minX3 = ghostLayerWidth;
-//   int maxX1 = bcArrayMaxX1-ghostLayerWidth;
-//   int maxX2 = bcArrayMaxX2-ghostLayerWidth;
-//   int maxX3 = bcArrayMaxX3-ghostLayerWidth;
-//
-//
-//   for (int x3 = minX3; x3<maxX3; x3++)
-//   {
-//      for (int x2 = minX2; x2<maxX2; x2++)
-//      {
-//         for (int x1 = minX1; x1<maxX1; x1++)
-//         {
-//            if (!bcArray->isSolid(x1, x2, x3)&&!bcArray->isUndefined(x1, x2, x3))
-//            {
-//               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 m0, m1, m2;
-//
-//               LBMReal rho = (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 vvx = ((((mfccc-mfaaa)+(mfcac-mfaca))+((mfcaa-mfacc)+(mfcca-mfaac)))+
-//               //   (((mfcba-mfabc)+(mfcbc-mfaba))+((mfcab-mfacb)+(mfccb-mfaab)))+
-//               //   (mfcbb-mfabb));
-//               //LBMReal vvy = ((((mfccc-mfaaa)+(mfaca-mfcac))+((mfacc-mfcaa)+(mfcca-mfaac)))+
-//               //   (((mfbca-mfbac)+(mfbcc-mfbaa))+((mfacb-mfcab)+(mfccb-mfaab)))+
-//               //   (mfbcb-mfbab));
-//               //LBMReal vvz = ((((mfccc-mfaaa)+(mfcac-mfaca))+((mfacc-mfcaa)+(mfaac-mfcca)))+
-//               //   (((mfbac-mfbca)+(mfbcc-mfbaa))+((mfabc-mfcba)+(mfcbc-mfaba)))+
-//               //   (mfbbc-mfbba));
-//
-//               LBMReal vvx = v(0,x1,x2,x3);
-//               LBMReal vvy = v(1,x1,x2,x3);
-//               LBMReal vvz = v(2,x1,x2,x3);
-//               //LBMReal rho = v(3,x1,x2,x3);
-//          
-//               LBMReal oMdrho;
-//
-//               oMdrho = mfccc+mfaaa;
-//               m0 = mfaca+mfcac;
-//               m1 = mfacc+mfcaa;
-//               m2 = mfaac+mfcca;
-//               oMdrho += m0;
-//               m1 += m2;
-//               oMdrho += m1;
-//               m0 = mfbac+mfbca;
-//               m1 = mfbaa+mfbcc;
-//               m0 += m1;
-//               m1 = mfabc+mfcba;
-//               m2 = mfaba+mfcbc;
-//               m1 += m2;
-//               m0 += m1;
-//               m1 = mfacb+mfcab;
-//               m2 = mfaab+mfccb;
-//               m1 += m2;
-//               m0 += m1;
-//               oMdrho += m0;
-//               m0 = mfabb+mfcbb;
-//               m1 = mfbab+mfbcb;
-//               m2 = mfbba+mfbbc;
-//               m0 += m1+m2;
-//               m0 += mfbbb; //hat gefehlt
-//               oMdrho = 1.-(oMdrho+m0);
-//
-//               LBMReal vx2;
-//               LBMReal vy2;
-//               LBMReal vz2;
-//               vx2 = vvx*vvx;
-//               vy2 = vvy*vvy;
-//               vz2 = vvz*vvz;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               LBMReal wadjust;
-//               LBMReal qudricLimit = 0.01;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               //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-2. *   m1 * vvz+vz2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m2 = mfaba+mfabc;
-//               m1 = mfabc-mfaba;
-//               m0 = m2+mfabb;
-//               mfaba = m0;
-//               m0 += c1o9 * oMdrho;
-//               mfabb = m1-m0 * vvz;
-//               mfabc = m2-2. *   m1 * vvz+vz2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m2 = mfaca+mfacc;
-//               m1 = mfacc-mfaca;
-//               m0 = m2+mfacb;
-//               mfaca = m0;
-//               m0 += c1o36 * oMdrho;
-//               mfacb = m1-m0 * vvz;
-//               mfacc = m2-2. *   m1 * vvz+vz2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m2 = mfbaa+mfbac;
-//               m1 = mfbac-mfbaa;
-//               m0 = m2+mfbab;
-//               mfbaa = m0;
-//               m0 += c1o9 * oMdrho;
-//               mfbab = m1-m0 * vvz;
-//               mfbac = m2-2. *   m1 * vvz+vz2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m2 = mfbba+mfbbc;
-//               m1 = mfbbc-mfbba;
-//               m0 = m2+mfbbb;
-//               mfbba = m0;
-//               m0 += c4o9 * oMdrho;
-//               mfbbb = m1-m0 * vvz;
-//               mfbbc = m2-2. *   m1 * vvz+vz2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m2 = mfbca+mfbcc;
-//               m1 = mfbcc-mfbca;
-//               m0 = m2+mfbcb;
-//               mfbca = m0;
-//               m0 += c1o9 * oMdrho;
-//               mfbcb = m1-m0 * vvz;
-//               mfbcc = m2-2. *   m1 * vvz+vz2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m2 = mfcaa+mfcac;
-//               m1 = mfcac-mfcaa;
-//               m0 = m2+mfcab;
-//               mfcaa = m0;
-//               m0 += c1o36 * oMdrho;
-//               mfcab = m1-m0 * vvz;
-//               mfcac = m2-2. *   m1 * vvz+vz2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m2 = mfcba+mfcbc;
-//               m1 = mfcbc-mfcba;
-//               m0 = m2+mfcbb;
-//               mfcba = m0;
-//               m0 += c1o9 * oMdrho;
-//               mfcbb = m1-m0 * vvz;
-//               mfcbc = m2-2. *   m1 * vvz+vz2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m2 = mfcca+mfccc;
-//               m1 = mfccc-mfcca;
-//               m0 = m2+mfccb;
-//               mfcca = m0;
-//               m0 += c1o36 * oMdrho;
-//               mfccb = m1-m0 * vvz;
-//               mfccc = m2-2. *   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-2. *   m1 * vvy+vy2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m2 = mfaab+mfacb;
-//               m1 = mfacb-mfaab;
-//               m0 = m2+mfabb;
-//               mfaab = m0;
-//               mfabb = m1-m0 * vvy;
-//               mfacb = m2-2. *   m1 * vvy+vy2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m2 = mfaac+mfacc;
-//               m1 = mfacc-mfaac;
-//               m0 = m2+mfabc;
-//               mfaac = m0;
-//               m0 += c1o18 * oMdrho;
-//               mfabc = m1-m0 * vvy;
-//               mfacc = m2-2. *   m1 * vvy+vy2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m2 = mfbaa+mfbca;
-//               m1 = mfbca-mfbaa;
-//               m0 = m2+mfbba;
-//               mfbaa = m0;
-//               m0 += c2o3 * oMdrho;
-//               mfbba = m1-m0 * vvy;
-//               mfbca = m2-2. *   m1 * vvy+vy2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m2 = mfbab+mfbcb;
-//               m1 = mfbcb-mfbab;
-//               m0 = m2+mfbbb;
-//               mfbab = m0;
-//               mfbbb = m1-m0 * vvy;
-//               mfbcb = m2-2. *   m1 * vvy+vy2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m2 = mfbac+mfbcc;
-//               m1 = mfbcc-mfbac;
-//               m0 = m2+mfbbc;
-//               mfbac = m0;
-//               m0 += c2o9 * oMdrho;
-//               mfbbc = m1-m0 * vvy;
-//               mfbcc = m2-2. *   m1 * vvy+vy2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m2 = mfcaa+mfcca;
-//               m1 = mfcca-mfcaa;
-//               m0 = m2+mfcba;
-//               mfcaa = m0;
-//               m0 += c1o6 * oMdrho;
-//               mfcba = m1-m0 * vvy;
-//               mfcca = m2-2. *   m1 * vvy+vy2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m2 = mfcab+mfccb;
-//               m1 = mfccb-mfcab;
-//               m0 = m2+mfcbb;
-//               mfcab = m0;
-//               mfcbb = m1-m0 * vvy;
-//               mfccb = m2-2. *   m1 * vvy+vy2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m2 = mfcac+mfccc;
-//               m1 = mfccc-mfcac;
-//               m0 = m2+mfcbc;
-//               mfcac = m0;
-//               m0 += c1o18 * oMdrho;
-//               mfcbc = m1-m0 * vvy;
-//               mfccc = m2-2. *   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 += 1. * oMdrho;
-//               mfbaa = m1-m0 * vvx;
-//               mfcaa = m2-2. *   m1 * vvx+vx2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m2 = mfaba+mfcba;
-//               m1 = mfcba-mfaba;
-//               m0 = m2+mfbba;
-//               mfaba = m0;
-//               mfbba = m1-m0 * vvx;
-//               mfcba = m2-2. *   m1 * vvx+vx2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m2 = mfaca+mfcca;
-//               m1 = mfcca-mfaca;
-//               m0 = m2+mfbca;
-//               mfaca = m0;
-//               m0 += c1o3 * oMdrho;
-//               mfbca = m1-m0 * vvx;
-//               mfcca = m2-2. *   m1 * vvx+vx2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m2 = mfaab+mfcab;
-//               m1 = mfcab-mfaab;
-//               m0 = m2+mfbab;
-//               mfaab = m0;
-//               mfbab = m1-m0 * vvx;
-//               mfcab = m2-2. *   m1 * vvx+vx2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m2 = mfabb+mfcbb;
-//               m1 = mfcbb-mfabb;
-//               m0 = m2+mfbbb;
-//               mfabb = m0;
-//               mfbbb = m1-m0 * vvx;
-//               mfcbb = m2-2. *   m1 * vvx+vx2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m2 = mfacb+mfccb;
-//               m1 = mfccb-mfacb;
-//               m0 = m2+mfbcb;
-//               mfacb = m0;
-//               mfbcb = m1-m0 * vvx;
-//               mfccb = m2-2. *   m1 * vvx+vx2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m2 = mfaac+mfcac;
-//               m1 = mfcac-mfaac;
-//               m0 = m2+mfbac;
-//               mfaac = m0;
-//               m0 += c1o3 * oMdrho;
-//               mfbac = m1-m0 * vvx;
-//               mfcac = m2-2. *   m1 * vvx+vx2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m2 = mfabc+mfcbc;
-//               m1 = mfcbc-mfabc;
-//               m0 = m2+mfbbc;
-//               mfabc = m0;
-//               mfbbc = m1-m0 * vvx;
-//               mfcbc = m2-2. *   m1 * vvx+vx2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m2 = mfacc+mfccc;
-//               m1 = mfccc-mfacc;
-//               m0 = m2+mfbcc;
-//               mfacc = m0;
-//               m0 += c1o9 * oMdrho;
-//               mfbcc = m1-m0 * vvx;
-//               mfccc = m2-2. *   m1 * vvx+vx2 * m0;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               // Cumulants
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               LBMReal OxxPyyPzz = 1.; //omega2 or bulk viscosity
-//               LBMReal OxyyPxzz = 1.;//-s9;//2+s9;//
-//               //LBMReal OxyyMxzz  = 1.;//2+s9;//
-//               LBMReal O4 = 1.;
-//               LBMReal O5 = 1.;
-//               LBMReal O6 = 1.;
-//
-//               //Cum 4.
-//               //LBMReal CUMcbb = mfcbb - ((mfcaa + c1o3 * oMdrho) * mfabb + 2. * mfbba * mfbab); // till 18.05.2015
-//               //LBMReal CUMbcb = mfbcb - ((mfaca + c1o3 * oMdrho) * mfbab + 2. * mfbba * mfabb); // till 18.05.2015
-//               //LBMReal CUMbbc = mfbbc - ((mfaac + c1o3 * oMdrho) * mfbba + 2. * mfbab * mfabb); // till 18.05.2015
-//
-//               LBMReal CUMcbb = mfcbb-((mfcaa+c1o3) * mfabb+2. * mfbba * mfbab);
-//               LBMReal CUMbcb = mfbcb-((mfaca+c1o3) * mfbab+2. * mfbba * mfabb);
-//               LBMReal CUMbbc = mfbbc-((mfaac+c1o3) * mfbba+2. * mfbab * mfabb);
-//
-//               LBMReal CUMcca = mfcca-((mfcaa * mfaca+2. * mfbba * mfbba)+c1o3 * (mfcaa+mfaca) * oMdrho+c1o9*(oMdrho-1)*oMdrho);
-//               LBMReal CUMcac = mfcac-((mfcaa * mfaac+2. * mfbab * mfbab)+c1o3 * (mfcaa+mfaac) * oMdrho+c1o9*(oMdrho-1)*oMdrho);
-//               LBMReal CUMacc = mfacc-((mfaac * mfaca+2. * mfabb * mfabb)+c1o3 * (mfaac+mfaca) * oMdrho+c1o9*(oMdrho-1)*oMdrho);
-//
-//               //Cum 5.
-//               LBMReal CUMbcc = mfbcc-(mfaac * mfbca+mfaca * mfbac+4. * mfabb * mfbbb+2. * (mfbab * mfacb+mfbba * mfabc))-c1o3 * (mfbca+mfbac) * oMdrho;
-//               LBMReal CUMcbc = mfcbc-(mfaac * mfcba+mfcaa * mfabc+4. * mfbab * mfbbb+2. * (mfabb * mfcab+mfbba * mfbac))-c1o3 * (mfcba+mfabc) * oMdrho;
-//               LBMReal CUMccb = mfccb-(mfcaa * mfacb+mfaca * mfcab+4. * mfbba * mfbbb+2. * (mfbab * mfbca+mfabb * mfcba))-c1o3 * (mfacb+mfcab) * oMdrho;
-//
-//               //Cum 6.
-//               LBMReal CUMccc = mfccc+((-4. *  mfbbb * mfbbb
-//                  -(mfcaa * mfacc+mfaca * mfcac+mfaac * mfcca)
-//                  -4. * (mfabb * mfcbb+mfbab * mfbcb+mfbba * mfbbc)
-//                  -2. * (mfbca * mfbac+mfcba * mfabc+mfcab * mfacb))
-//                  +(4. * (mfbab * mfbab * mfaca+mfabb * mfabb * mfcaa+mfbba * mfbba * mfaac)
-//                     +2. * (mfcaa * mfaca * mfaac)
-//                     +16. *  mfbba * mfbab * mfabb)
-//                  -c1o3* (mfacc+mfcac+mfcca) * oMdrho-c1o9*oMdrho*oMdrho
-//                  -c1o9* (mfcaa+mfaca+mfaac) * oMdrho*(1.-2.* oMdrho)-c1o27* oMdrho * oMdrho*(-2.* oMdrho)
-//                  +(2. * (mfbab * mfbab+mfabb * mfabb+mfbba * mfbba)
-//                     +(mfaac * mfaca+mfaac * mfcaa+mfaca * mfcaa)) * c2o3*oMdrho)+c1o27*oMdrho;
-//
-//               //2.
-//               // linear combinations
-//               LBMReal mxxPyyPzz = mfcaa+mfaca+mfaac;
-//               LBMReal mxxMyy = mfcaa-mfaca;
-//               LBMReal mxxMzz = mfcaa-mfaac;
-//
-//               LBMReal dxux = -c1o2 * collFactor *(mxxMyy+mxxMzz)+c1o2 * OxxPyyPzz*(mfaaa-mxxPyyPzz);
-//               LBMReal dyuy = dxux+collFactor * c3o2 * mxxMyy;
-//               LBMReal dzuz = dxux+collFactor * c3o2 * mxxMzz;
-//
-//               //relax
-//               mxxPyyPzz += OxxPyyPzz*(mfaaa-mxxPyyPzz)-3. * (1.-c1o2 * OxxPyyPzz) * (vx2 * dxux+vy2 * dyuy+vz2 * dzuz);
-//               mxxMyy += collFactor * (-mxxMyy)-3. * (1.-c1o2 * collFactor) * (vx2 * dxux-vy2 * dyuy);
-//               mxxMzz += collFactor * (-mxxMzz)-3. * (1.-c1o2 * collFactor) * (vx2 * dxux-vz2 * dzuz);
-//
-//               mfabb += collFactor * (-mfabb);
-//               mfbab += collFactor * (-mfbab);
-//               mfbba += collFactor * (-mfbba);
-//
-//               // linear combinations back
-//               mfcaa = c1o3 * (mxxMyy+mxxMzz+mxxPyyPzz);
-//               mfaca = c1o3 * (-2. *  mxxMyy+mxxMzz+mxxPyyPzz);
-//               mfaac = c1o3 * (mxxMyy-2. * 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
-//               wadjust = OxyyMxzz+(1.-OxyyMxzz)*fabs(mfbbb)/(fabs(mfbbb)+qudricLimit);
-//               mfbbb += wadjust * (-mfbbb);
-//               wadjust = OxyyPxzz+(1.-OxyyPxzz)*fabs(mxxyPyzz)/(fabs(mxxyPyzz)+qudricLimit);
-//               mxxyPyzz += wadjust * (-mxxyPyzz);
-//               wadjust = OxyyMxzz+(1.-OxyyMxzz)*fabs(mxxyMyzz)/(fabs(mxxyMyzz)+qudricLimit);
-//               mxxyMyzz += wadjust * (-mxxyMyzz);
-//               wadjust = OxyyPxzz+(1.-OxyyPxzz)*fabs(mxxzPyyz)/(fabs(mxxzPyyz)+qudricLimit);
-//               mxxzPyyz += wadjust * (-mxxzPyyz);
-//               wadjust = OxyyMxzz+(1.-OxyyMxzz)*fabs(mxxzMyyz)/(fabs(mxxzMyyz)+qudricLimit);
-//               mxxzMyyz += wadjust * (-mxxzMyyz);
-//               wadjust = OxyyPxzz+(1.-OxyyPxzz)*fabs(mxyyPxzz)/(fabs(mxyyPxzz)+qudricLimit);
-//               mxyyPxzz += wadjust * (-mxyyPxzz);
-//               wadjust = OxyyMxzz+(1.-OxyyMxzz)*fabs(mxyyMxzz)/(fabs(mxyyMxzz)+qudricLimit);
-//               mxyyMxzz += wadjust * (-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.
-//               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 * oMdrho) * mfabb + 2. * mfbba * mfbab); // till 18.05.2015
-//               //mfbcb = CUMbcb + ((mfaca + c1o3 * oMdrho) * mfbab + 2. * mfbba * mfabb); // till 18.05.2015
-//               //mfbbc = CUMbbc + ((mfaac + c1o3 * oMdrho) * mfbba + 2. * mfbab * mfabb); // till 18.05.2015
-//
-//               mfcbb = CUMcbb+((mfcaa+c1o3) * mfabb+2. * mfbba * mfbab);
-//               mfbcb = CUMbcb+((mfaca+c1o3) * mfbab+2. * mfbba * mfabb);
-//               mfbbc = CUMbbc+((mfaac+c1o3) * mfbba+2. * mfbab * mfabb);
-//
-//               mfcca = CUMcca+(mfcaa * mfaca+2. * mfbba * mfbba)+c1o3 * (mfcaa+mfaca) * oMdrho+c1o9*(oMdrho-1)*oMdrho;
-//               mfcac = CUMcac+(mfcaa * mfaac+2. * mfbab * mfbab)+c1o3 * (mfcaa+mfaac) * oMdrho+c1o9*(oMdrho-1)*oMdrho;
-//               mfacc = CUMacc+(mfaac * mfaca+2. * mfabb * mfabb)+c1o3 * (mfaac+mfaca) * oMdrho+c1o9*(oMdrho-1)*oMdrho;
-//
-//               //5.
-//               mfbcc = CUMbcc+(mfaac * mfbca+mfaca * mfbac+4. * mfabb * mfbbb+2. * (mfbab * mfacb+mfbba * mfabc))+c1o3 * (mfbca+mfbac) * oMdrho;
-//               mfcbc = CUMcbc+(mfaac * mfcba+mfcaa * mfabc+4. * mfbab * mfbbb+2. * (mfabb * mfcab+mfbba * mfbac))+c1o3 * (mfcba+mfabc) * oMdrho;
-//               mfccb = CUMccb+(mfcaa * mfacb+mfaca * mfcab+4. * mfbba * mfbbb+2. * (mfbab * mfbca+mfabb * mfcba))+c1o3 * (mfacb+mfcab) * oMdrho;
-//
-//               //6.
-//               mfccc = CUMccc-((-4. *  mfbbb * mfbbb
-//                  -(mfcaa * mfacc+mfaca * mfcac+mfaac * mfcca)
-//                  -4. * (mfabb * mfcbb+mfbac * mfbca+mfbba * mfbbc)
-//                  -2. * (mfbca * mfbac+mfcba * mfabc+mfcab * mfacb))
-//                  +(4. * (mfbab * mfbab * mfaca+mfabb * mfabb * mfcaa+mfbba * mfbba * mfaac)
-//                     +2. * (mfcaa * mfaca * mfaac)
-//                     +16. *  mfbba * mfbab * mfabb)
-//                  -c1o3* (mfacc+mfcac+mfcca) * oMdrho-c1o9*oMdrho*oMdrho
-//                  -c1o9* (mfcaa+mfaca+mfaac) * oMdrho*(1.-2.* oMdrho)-c1o27* oMdrho * oMdrho*(-2.* oMdrho)
-//                  +(2. * (mfbab * mfbab+mfabb * mfabb+mfbba * mfbba)
-//                     +(mfaac * mfaca+mfaac * mfcaa+mfaca * mfcaa)) * c2o3*oMdrho)-c1o27*oMdrho;
-//
-//               mfaab = 0.0;
-//               mfaba = 0.0;
-//               mfbaa = 0.0;
-//
-//               //mfaab *= -0.5;
-//               //mfaba *= -0.5;
-//               //mfbaa *= -0.5;
-//
-//
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               //back
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               //mit 1, 0, 1/3, 0, 0, 0, 1/3, 0, 1/9   Konditionieren
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               // Z - Dir
-//               m0 = mfaac * c1o2+mfaab * (vvz-c1o2)+(mfaaa+1. * oMdrho) * (vz2-vvz) * c1o2;
-//               m1 = -mfaac-2. * mfaab *  vvz+mfaaa                * (1.-vz2)-1. * oMdrho * vz2;
-//               m2 = mfaac * c1o2+mfaab * (vvz+c1o2)+(mfaaa+1. * oMdrho) * (vz2+vvz) * c1o2;
-//               mfaaa = m0;
-//               mfaab = m1;
-//               mfaac = m2;
-//               ////////////////////////////////////////////////////////////////////////////////////
-//               m0 = mfabc * c1o2+mfabb * (vvz-c1o2)+mfaba * (vz2-vvz) * c1o2;
-//               m1 = -mfabc-2. * mfabb *  vvz+mfaba * (1.-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-2. * mfacb *  vvz+mfaca                  * (1.-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-2. * mfbab *  vvz+mfbaa * (1.-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-2. * mfbbb *  vvz+mfbba * (1.-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-2. * mfbcb *  vvz+mfbca * (1.-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-2. * mfcab *  vvz+mfcaa                  * (1.-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-2. * mfcbb *  vvz+mfcba * (1.-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-2. * mfccb *  vvz+mfcca                  * (1.-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-2. * mfaba *  vvy+mfaaa                  * (1.-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-2. * mfabb *  vvy+mfaab                  * (1.-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-2. * mfabc *  vvy+mfaac                  * (1.-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-2. * mfbba *  vvy+mfbaa * (1.-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-2. * mfbbb *  vvy+mfbab * (1.-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-2. * mfbbc *  vvy+mfbac * (1.-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-2. * mfcba *  vvy+mfcaa                   * (1.-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-2. * mfcbb *  vvy+mfcab                  * (1.-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-2. * mfcbc *  vvy+mfcac                   * (1.-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-2. * mfbaa *  vvx+mfaaa                   * (1.-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-2. * mfbba *  vvx+mfaba                  * (1.-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-2. * mfbca *  vvx+mfaca                   * (1.-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-2. * mfbab *  vvx+mfaab                  * (1.-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-2. * mfbbb *  vvx+mfabb                  * (1.-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-2. * mfbcb *  vvx+mfacb                  * (1.-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-2. * mfbac *  vvx+mfaac                   * (1.-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-2. * mfbbc *  vvx+mfabc                  * (1.-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-2. * mfbcc *  vvx+mfacc                   * (1.-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 rho_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 = rho-rho_post;
-//#ifdef SINGLEPRECISION
-//               if (dif>10.0E-7||dif<-10.0E-7)
-//#else
-//               if (dif>10.0E-15||dif<-10.0E-15)
-//#endif
-//               {
-//                  UB_THROW(UbException(UB_EXARGS, "rho="+UbSystem::toString(rho)+", rho_post="+UbSystem::toString(rho_post)
-//                     +" dif="+UbSystem::toString(dif)
-//                     +" rho is not correct for node "+UbSystem::toString(x1)+","+UbSystem::toString(x2)+","+UbSystem::toString(x3)));
-//                  //UBLOG(logERROR,"LBMKernel3DCCLB::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;
-//               ////////////////////////////////////////////////////////////////////////////
-//
-//            }
-//         }
-//      }
-//   }
-//
-//}
-
-void InitDensityLBMKernel::init()
-{
-   DistributionArray3DPtr d(new D3Q27EsoTwist3DSplittedVector(nx1+2, nx2+2, nx3+2, -999.0));
-   dataSet->setFdistributions(d);
-   v.resize(3, nx1+2, nx2+2, nx3+2);
-
-}
-
-
-void InitDensityLBMKernel::collideAll()
-{
-   using namespace D3Q27System;
-
-   localDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getLocalDistributions();
-   nonLocalDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getNonLocalDistributions();
-   zeroDistributions = boost::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getZeroDistributions();
-
-   BCArray3DPtr bcArray = this->getBCProcessor()->getBCArray();
-   BoundaryConditionsPtr bcPtr;
-   LBMReal f[D3Q27System::ENDF+1];
-   LBMReal feq[D3Q27System::ENDF+1];
-   LBMReal drho, vx1, vx2, vx3;
-   const int bcArrayMaxX1 = (int)bcArray->getNX1();
-   const int bcArrayMaxX2 = (int)bcArray->getNX2();
-   const int bcArrayMaxX3 = (int)bcArray->getNX3();
-
-   int minX1 = ghostLayerWidth;
-   int minX2 = ghostLayerWidth;
-   int minX3 = ghostLayerWidth;
-   int maxX1 = bcArrayMaxX1-ghostLayerWidth;
-   int maxX2 = bcArrayMaxX2-ghostLayerWidth;
-   int maxX3 = bcArrayMaxX3-ghostLayerWidth;
-
-   //collFactor = 1.0/(1.0/2.0+1.0/sqrt(6.0));
-   collFactor = 1.0;
-
-   for (int x3 = minX3; x3<maxX3; x3++)
-   {
-      for (int x2 = minX2; x2<maxX2; x2++)
-      {
-         for (int x1 = minX1; x1<maxX1; x1++)
-         {
-            if (!bcArray->isSolid(x1, x2, x3)&&!bcArray->isUndefined(x1, x2, x3))
-            {
-               int x1p = x1+1;
-               int x2p = x2+1;
-               int x3p = x3+1;
-               //////////////////////////////////////////////////////////////////////////
-               //read distribution
-               ////////////////////////////////////////////////////////////////////////////
-               f[ZERO] = (*this->zeroDistributions)(x1, x2, x3);
-
-               f[E] = (*this->localDistributions)(D3Q27System::ET_E, x1, x2, x3);
-               f[N] = (*this->localDistributions)(D3Q27System::ET_N, x1, x2, x3);
-               f[T] = (*this->localDistributions)(D3Q27System::ET_T, x1, x2, x3);
-               f[NE] = (*this->localDistributions)(D3Q27System::ET_NE, x1, x2, x3);
-               f[NW] = (*this->localDistributions)(D3Q27System::ET_NW, x1p, x2, x3);
-               f[TE] = (*this->localDistributions)(D3Q27System::ET_TE, x1, x2, x3);
-               f[TW] = (*this->localDistributions)(D3Q27System::ET_TW, x1p, x2, x3);
-               f[TN] = (*this->localDistributions)(D3Q27System::ET_TN, x1, x2, x3);
-               f[TS] = (*this->localDistributions)(D3Q27System::ET_TS, x1, x2p, x3);
-               f[TNE] = (*this->localDistributions)(D3Q27System::ET_TNE, x1, x2, x3);
-               f[TNW] = (*this->localDistributions)(D3Q27System::ET_TNW, x1p, x2, x3);
-               f[TSE] = (*this->localDistributions)(D3Q27System::ET_TSE, x1, x2p, x3);
-               f[TSW] = (*this->localDistributions)(D3Q27System::ET_TSW, x1p, x2p, x3);
-
-               f[W] = (*this->nonLocalDistributions)(D3Q27System::ET_W, x1p, x2, x3);
-               f[S] = (*this->nonLocalDistributions)(D3Q27System::ET_S, x1, x2p, x3);
-               f[B] = (*this->nonLocalDistributions)(D3Q27System::ET_B, x1, x2, x3p);
-               f[SW] = (*this->nonLocalDistributions)(D3Q27System::ET_SW, x1p, x2p, x3);
-               f[SE] = (*this->nonLocalDistributions)(D3Q27System::ET_SE, x1, x2p, x3);
-               f[BW] = (*this->nonLocalDistributions)(D3Q27System::ET_BW, x1p, x2, x3p);
-               f[BE] = (*this->nonLocalDistributions)(D3Q27System::ET_BE, x1, x2, x3p);
-               f[BS] = (*this->nonLocalDistributions)(D3Q27System::ET_BS, x1, x2p, x3p);
-               f[BN] = (*this->nonLocalDistributions)(D3Q27System::ET_BN, x1, x2, x3p);
-               f[BSW] = (*this->nonLocalDistributions)(D3Q27System::ET_BSW, x1p, x2p, x3p);
-               f[BSE] = (*this->nonLocalDistributions)(D3Q27System::ET_BSE, x1, x2p, x3p);
-               f[BNW] = (*this->nonLocalDistributions)(D3Q27System::ET_BNW, x1p, x2, x3p);
-               f[BNE] = (*this->nonLocalDistributions)(D3Q27System::ET_BNE, x1, x2, x3p);
-               //////////////////////////////////////////////////////////////////////////
-
-               drho = ((f[TNE]+f[BSW])+(f[TSE]+f[BNW]))+((f[BSE]+f[TNW])+(f[TSW]+f[BNE]))
-                  +(((f[NE]+f[SW])+(f[SE]+f[NW]))+((f[TE]+f[BW])+(f[BE]+f[TW]))
-                     +((f[BN]+f[TS])+(f[TN]+f[BS])))+((f[E]+f[W])+(f[N]+f[S])
-                        +(f[T]+f[B]))+f[ZERO];
-
-               //vx1 = ((((f[TNE]-f[BSW])+(f[TSE]-f[BNW]))+((f[BSE]-f[TNW])+(f[BNE]-f[TSW])))+
-               //   (((f[BE]-f[TW])+(f[TE]-f[BW]))+((f[SE]-f[NW])+(f[NE]-f[SW])))+
-               //   (f[E]-f[W]));
-
-               //vx2 = ((((f[TNE]-f[BSW])+(f[BNW]-f[TSE]))+((f[TNW]-f[BSE])+(f[BNE]-f[TSW])))+
-               //   (((f[BN]-f[TS])+(f[TN]-f[BS]))+((f[NW]-f[SE])+(f[NE]-f[SW])))+
-               //   (f[N]-f[S]));
-
-               //vx3 = ((((f[TNE]-f[BSW])+(f[TSE]-f[BNW]))+((f[TNW]-f[BSE])+(f[TSW]-f[BNE])))+
-               //   (((f[TS]-f[BN])+(f[TN]-f[BS]))+((f[TW]-f[BE])+(f[TE]-f[BW])))+
-               //   (f[T]-f[B]));
-
-               vx1 = v(0,x1,x2,x3);
-               vx2 = v(1,x1,x2,x3);
-               vx3 = v(2,x1,x2,x3);
-
-               //LBMReal vvx = v(0,x1,x2,x3);
-               //LBMReal vvy = v(1,x1,x2,x3);
-               //LBMReal vvz = v(2,x1,x2,x3);
-
-               //vx1 = vx1+(vvx-vx1);
-               //vx2 = vx2+(vvy-vx2);
-               //vx3 = vx3+(vvz-vx3);
-
-               LBMReal cu_sq = 1.5*(vx1*vx1+vx2*vx2+vx3*vx3);
-
-               feq[ZERO] = c8o27*(drho-cu_sq);
-               feq[E] = c2o27*(drho+3.0*(vx1)+c9o2*(vx1)*(vx1)-cu_sq);
-               feq[W] = c2o27*(drho+3.0*(-vx1)+c9o2*(-vx1)*(-vx1)-cu_sq);
-               feq[N] = c2o27*(drho+3.0*(vx2)+c9o2*(vx2)*(vx2)-cu_sq);
-               feq[S] = c2o27*(drho+3.0*(-vx2)+c9o2*(-vx2)*(-vx2)-cu_sq);
-               feq[T] = c2o27*(drho+3.0*(vx3)+c9o2*(vx3)*(vx3)-cu_sq);
-               feq[B] = c2o27*(drho+3.0*(-vx3)+c9o2*(-vx3)*(-vx3)-cu_sq);
-               feq[NE] = c1o54*(drho+3.0*(vx1+vx2)+c9o2*(vx1+vx2)*(vx1+vx2)-cu_sq);
-               feq[SW] = c1o54*(drho+3.0*(-vx1-vx2)+c9o2*(-vx1-vx2)*(-vx1-vx2)-cu_sq);
-               feq[SE] = c1o54*(drho+3.0*(vx1-vx2)+c9o2*(vx1-vx2)*(vx1-vx2)-cu_sq);
-               feq[NW] = c1o54*(drho+3.0*(-vx1+vx2)+c9o2*(-vx1+vx2)*(-vx1+vx2)-cu_sq);
-               feq[TE] = c1o54*(drho+3.0*(vx1+vx3)+c9o2*(vx1+vx3)*(vx1+vx3)-cu_sq);
-               feq[BW] = c1o54*(drho+3.0*(-vx1-vx3)+c9o2*(-vx1-vx3)*(-vx1-vx3)-cu_sq);
-               feq[BE] = c1o54*(drho+3.0*(vx1-vx3)+c9o2*(vx1-vx3)*(vx1-vx3)-cu_sq);
-               feq[TW] = c1o54*(drho+3.0*(-vx1+vx3)+c9o2*(-vx1+vx3)*(-vx1+vx3)-cu_sq);
-               feq[TN] = c1o54*(drho+3.0*(vx2+vx3)+c9o2*(vx2+vx3)*(vx2+vx3)-cu_sq);
-               feq[BS] = c1o54*(drho+3.0*(-vx2-vx3)+c9o2*(-vx2-vx3)*(-vx2-vx3)-cu_sq);
-               feq[BN] = c1o54*(drho+3.0*(vx2-vx3)+c9o2*(vx2-vx3)*(vx2-vx3)-cu_sq);
-               feq[TS] = c1o54*(drho+3.0*(-vx2+vx3)+c9o2*(-vx2+vx3)*(-vx2+vx3)-cu_sq);
-               feq[TNE] = c1o216*(drho+3.0*(vx1+vx2+vx3)+c9o2*(vx1+vx2+vx3)*(vx1+vx2+vx3)-cu_sq);
-               feq[BSW] = c1o216*(drho+3.0*(-vx1-vx2-vx3)+c9o2*(-vx1-vx2-vx3)*(-vx1-vx2-vx3)-cu_sq);
-               feq[BNE] = c1o216*(drho+3.0*(vx1+vx2-vx3)+c9o2*(vx1+vx2-vx3)*(vx1+vx2-vx3)-cu_sq);
-               feq[TSW] = c1o216*(drho+3.0*(-vx1-vx2+vx3)+c9o2*(-vx1-vx2+vx3)*(-vx1-vx2+vx3)-cu_sq);
-               feq[TSE] = c1o216*(drho+3.0*(vx1-vx2+vx3)+c9o2*(vx1-vx2+vx3)*(vx1-vx2+vx3)-cu_sq);
-               feq[BNW] = c1o216*(drho+3.0*(-vx1+vx2-vx3)+c9o2*(-vx1+vx2-vx3)*(-vx1+vx2-vx3)-cu_sq);
-               feq[BSE] = c1o216*(drho+3.0*(vx1-vx2-vx3)+c9o2*(vx1-vx2-vx3)*(vx1-vx2-vx3)-cu_sq);
-               feq[TNW] = c1o216*(drho+3.0*(-vx1+vx2+vx3)+c9o2*(-vx1+vx2+vx3)*(-vx1+vx2+vx3)-cu_sq);
-
-               //Relaxation
-               f[ZERO] += (feq[ZERO]-f[ZERO])*collFactor;
-               f[E] += (feq[E]-f[E])*collFactor;
-               f[W] += (feq[W]-f[W])*collFactor;
-               f[N] += (feq[N]-f[N])*collFactor;
-               f[S] += (feq[S]-f[S])*collFactor;
-               f[T] += (feq[T]-f[T])*collFactor;
-               f[B] += (feq[B]-f[B])*collFactor;
-               f[NE] += (feq[NE]-f[NE])*collFactor;
-               f[SW] += (feq[SW]-f[SW])*collFactor;
-               f[SE] += (feq[SE]-f[SE])*collFactor;
-               f[NW] += (feq[NW]-f[NW])*collFactor;
-               f[TE] += (feq[TE]-f[TE])*collFactor;
-               f[BW] += (feq[BW]-f[BW])*collFactor;
-               f[BE] += (feq[BE]-f[BE])*collFactor;
-               f[TW] += (feq[TW]-f[TW])*collFactor;
-               f[TN] += (feq[TN]-f[TN])*collFactor;
-               f[BS] += (feq[BS]-f[BS])*collFactor;
-               f[BN] += (feq[BN]-f[BN])*collFactor;
-               f[TS] += (feq[TS]-f[TS])*collFactor;
-
-               f[TNE] += (feq[TNE]-f[TNE])*collFactor;
-               f[BSW] += (feq[BSW]-f[BSW])*collFactor;
-               f[BNE] += (feq[BNE]-f[BNE])*collFactor;
-               f[TSW] += (feq[TSW]-f[TSW])*collFactor;
-               f[TSE] += (feq[TSE]-f[TSE])*collFactor;
-               f[BNW] += (feq[BNW]-f[BNW])*collFactor;
-               f[BSE] += (feq[BSE]-f[BSE])*collFactor;
-               f[TNW] += (feq[TNW]-f[TNW])*collFactor;
-
-               //////////////////////////////////////////////////////////////////////////
-#ifdef  PROOF_CORRECTNESS
-               LBMReal rho_post = f[ZERO]+f[E]+f[W]+f[N]+f[S]+f[T]+f[B]
-                  +f[NE]+f[SW]+f[SE]+f[NW]+f[TE]+f[BW]+f[BE]
-                  +f[TW]+f[TN]+f[BS]+f[BN]+f[TS]+f[TNE]+f[TSW]
-                  +f[TSE]+f[TNW]+f[BNE]+f[BSW]+f[BSE]+f[BNW];
-               LBMReal dif = drho-rho_post;
-#ifdef SINGLEPRECISION
-               if (dif>10.0E-7||dif<-10.0E-7)
-#else
-               if (dif>10.0E-15||dif<-10.0E-15)
-#endif
-               {
-                  UB_THROW(UbException(UB_EXARGS, "rho is not correct"));
-               }
-#endif
-               //////////////////////////////////////////////////////////////////////////
-               //write distribution
-               //////////////////////////////////////////////////////////////////////////
-               (*this->localDistributions)(D3Q27System::ET_E, x1, x2, x3) = f[D3Q27System::INV_E];
-               (*this->localDistributions)(D3Q27System::ET_N, x1, x2, x3) = f[D3Q27System::INV_N];
-               (*this->localDistributions)(D3Q27System::ET_T, x1, x2, x3) = f[D3Q27System::INV_T];
-               (*this->localDistributions)(D3Q27System::ET_NE, x1, x2, x3) = f[D3Q27System::INV_NE];
-               (*this->localDistributions)(D3Q27System::ET_NW, x1p, x2, x3) = f[D3Q27System::INV_NW];
-               (*this->localDistributions)(D3Q27System::ET_TE, x1, x2, x3) = f[D3Q27System::INV_TE];
-               (*this->localDistributions)(D3Q27System::ET_TW, x1p, x2, x3) = f[D3Q27System::INV_TW];
-               (*this->localDistributions)(D3Q27System::ET_TN, x1, x2, x3) = f[D3Q27System::INV_TN];
-               (*this->localDistributions)(D3Q27System::ET_TS, x1, x2p, x3) = f[D3Q27System::INV_TS];
-               (*this->localDistributions)(D3Q27System::ET_TNE, x1, x2, x3) = f[D3Q27System::INV_TNE];
-               (*this->localDistributions)(D3Q27System::ET_TNW, x1p, x2, x3) = f[D3Q27System::INV_TNW];
-               (*this->localDistributions)(D3Q27System::ET_TSE, x1, x2p, x3) = f[D3Q27System::INV_TSE];
-               (*this->localDistributions)(D3Q27System::ET_TSW, x1p, x2p, x3) = f[D3Q27System::INV_TSW];
-
-               (*this->nonLocalDistributions)(D3Q27System::ET_W, x1p, x2, x3) = f[D3Q27System::INV_W];
-               (*this->nonLocalDistributions)(D3Q27System::ET_S, x1, x2p, x3) = f[D3Q27System::INV_S];
-               (*this->nonLocalDistributions)(D3Q27System::ET_B, x1, x2, x3p) = f[D3Q27System::INV_B];
-               (*this->nonLocalDistributions)(D3Q27System::ET_SW, x1p, x2p, x3) = f[D3Q27System::INV_SW];
-               (*this->nonLocalDistributions)(D3Q27System::ET_SE, x1, x2p, x3) = f[D3Q27System::INV_SE];
-               (*this->nonLocalDistributions)(D3Q27System::ET_BW, x1p, x2, x3p) = f[D3Q27System::INV_BW];
-               (*this->nonLocalDistributions)(D3Q27System::ET_BE, x1, x2, x3p) = f[D3Q27System::INV_BE];
-               (*this->nonLocalDistributions)(D3Q27System::ET_BS, x1, x2p, x3p) = f[D3Q27System::INV_BS];
-               (*this->nonLocalDistributions)(D3Q27System::ET_BN, x1, x2, x3p) = f[D3Q27System::INV_BN];
-               (*this->nonLocalDistributions)(D3Q27System::ET_BSW, x1p, x2p, x3p) = f[D3Q27System::INV_BSW];
-               (*this->nonLocalDistributions)(D3Q27System::ET_BSE, x1, x2p, x3p) = f[D3Q27System::INV_BSE];
-               (*this->nonLocalDistributions)(D3Q27System::ET_BNW, x1p, x2, x3p) = f[D3Q27System::INV_BNW];
-               (*this->nonLocalDistributions)(D3Q27System::ET_BNE, x1, x2, x3p) = f[D3Q27System::INV_BNE];
-
-               (*this->zeroDistributions)(x1, x2, x3) = f[D3Q27System::ZERO];
-               //////////////////////////////////////////////////////////////////////////
-
-
-            }
-         }
-      }
-   }
+#include "InitDensityLBMKernel.h"
+#include "D3Q27EsoTwist3DSplittedVector.h"
+#include "BCProcessor.h"
+#include "DataSet3D.h"
+#include "BCArray3D.h"
+
+InitDensityLBMKernel::InitDensityLBMKernel()
+{
+}
+
+InitDensityLBMKernel::~InitDensityLBMKernel()
+{
+}
+
+InitDensityLBMKernel::InitDensityLBMKernel(int nx1, int nx2, int nx3)
+{
+   this->nx1 = nx1;
+   this->nx2 = nx2;
+   this->nx3 = nx3;
+   this->compressible = false;
+}
+
+void InitDensityLBMKernel::calculate()
+{
+   collideAll();
+}
+
+LBMKernelPtr InitDensityLBMKernel::clone()
+{
+   LBMKernelPtr kernel(new InitDensityLBMKernel(nx1, nx2, nx3));
+   std::dynamic_pointer_cast<InitDensityLBMKernel>(kernel)->init();
+   kernel->setCollisionFactor(this->collFactor);
+   kernel->setBCProcessor(bcProcessor->clone(kernel));
+   kernel->setWithForcing(withForcing);
+   kernel->setForcingX1(muForcingX1);
+   kernel->setForcingX2(muForcingX2);
+   kernel->setForcingX3(muForcingX3);
+   kernel->setIndex(ix1, ix2, ix3);
+   kernel->setDeltaT(deltaT);
+   std::dynamic_pointer_cast<InitDensityLBMKernel>(kernel)->OxyyMxzz = 1.0;
+   return kernel;
+}
+
+void InitDensityLBMKernel::setVelocity(int x1, int x2, int x3, LBMReal vvx, LBMReal vvy, LBMReal vvz)
+{
+   v(0, x1, x2, x3) = vvx;
+   v(1, x1, x2, x3) = vvy;
+   v(2, x1, x2, x3) = vvz;
+}
+
+double InitDensityLBMKernel::getCalculationTime()
+{
+   return 0;
+}
+
+//void InitDensityLBMKernel::collideAll()
+//{
+//   using namespace D3Q27System;
+//
+//   localDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getLocalDistributions();
+//   nonLocalDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getNonLocalDistributions();
+//   zeroDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getZeroDistributions();
+//
+//   BCArray3D<D3Q27BoundaryCondition>& bcArray = std::dynamic_pointer_cast<D3Q27ETBCProcessor>(this->getBCProcessor())->getBCArray();
+//
+//   const int bcArrayMaxX1 = (int)bcArray->getNX1();
+//   const int bcArrayMaxX2 = (int)bcArray->getNX2();
+//   const int bcArrayMaxX3 = (int)bcArray->getNX3();
+//
+//   int minX1 = ghostLayerWidth;
+//   int minX2 = ghostLayerWidth;
+//   int minX3 = ghostLayerWidth;
+//   int maxX1 = bcArrayMaxX1-ghostLayerWidth;
+//   int maxX2 = bcArrayMaxX2-ghostLayerWidth;
+//   int maxX3 = bcArrayMaxX3-ghostLayerWidth;
+//
+//
+//   for (int x3 = minX3; x3<maxX3; x3++)
+//   {
+//      for (int x2 = minX2; x2<maxX2; x2++)
+//      {
+//         for (int x1 = minX1; x1<maxX1; x1++)
+//         {
+//            if (!bcArray->isSolid(x1, x2, x3)&&!bcArray->isUndefined(x1, x2, x3))
+//            {
+//               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 m0, m1, m2;
+//
+//               LBMReal rho = (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 vvx = ((((mfccc-mfaaa)+(mfcac-mfaca))+((mfcaa-mfacc)+(mfcca-mfaac)))+
+//               //   (((mfcba-mfabc)+(mfcbc-mfaba))+((mfcab-mfacb)+(mfccb-mfaab)))+
+//               //   (mfcbb-mfabb));
+//               //LBMReal vvy = ((((mfccc-mfaaa)+(mfaca-mfcac))+((mfacc-mfcaa)+(mfcca-mfaac)))+
+//               //   (((mfbca-mfbac)+(mfbcc-mfbaa))+((mfacb-mfcab)+(mfccb-mfaab)))+
+//               //   (mfbcb-mfbab));
+//               //LBMReal vvz = ((((mfccc-mfaaa)+(mfcac-mfaca))+((mfacc-mfcaa)+(mfaac-mfcca)))+
+//               //   (((mfbac-mfbca)+(mfbcc-mfbaa))+((mfabc-mfcba)+(mfcbc-mfaba)))+
+//               //   (mfbbc-mfbba));
+//
+//               LBMReal vvx = v(0,x1,x2,x3);
+//               LBMReal vvy = v(1,x1,x2,x3);
+//               LBMReal vvz = v(2,x1,x2,x3);
+//               //LBMReal rho = v(3,x1,x2,x3);
+//          
+//               LBMReal oMdrho;
+//
+//               oMdrho = mfccc+mfaaa;
+//               m0 = mfaca+mfcac;
+//               m1 = mfacc+mfcaa;
+//               m2 = mfaac+mfcca;
+//               oMdrho += m0;
+//               m1 += m2;
+//               oMdrho += m1;
+//               m0 = mfbac+mfbca;
+//               m1 = mfbaa+mfbcc;
+//               m0 += m1;
+//               m1 = mfabc+mfcba;
+//               m2 = mfaba+mfcbc;
+//               m1 += m2;
+//               m0 += m1;
+//               m1 = mfacb+mfcab;
+//               m2 = mfaab+mfccb;
+//               m1 += m2;
+//               m0 += m1;
+//               oMdrho += m0;
+//               m0 = mfabb+mfcbb;
+//               m1 = mfbab+mfbcb;
+//               m2 = mfbba+mfbbc;
+//               m0 += m1+m2;
+//               m0 += mfbbb; //hat gefehlt
+//               oMdrho = 1.-(oMdrho+m0);
+//
+//               LBMReal vx2;
+//               LBMReal vy2;
+//               LBMReal vz2;
+//               vx2 = vvx*vvx;
+//               vy2 = vvy*vvy;
+//               vz2 = vvz*vvz;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               LBMReal wadjust;
+//               LBMReal qudricLimit = 0.01;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               //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-2. *   m1 * vvz+vz2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m2 = mfaba+mfabc;
+//               m1 = mfabc-mfaba;
+//               m0 = m2+mfabb;
+//               mfaba = m0;
+//               m0 += c1o9 * oMdrho;
+//               mfabb = m1-m0 * vvz;
+//               mfabc = m2-2. *   m1 * vvz+vz2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m2 = mfaca+mfacc;
+//               m1 = mfacc-mfaca;
+//               m0 = m2+mfacb;
+//               mfaca = m0;
+//               m0 += c1o36 * oMdrho;
+//               mfacb = m1-m0 * vvz;
+//               mfacc = m2-2. *   m1 * vvz+vz2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m2 = mfbaa+mfbac;
+//               m1 = mfbac-mfbaa;
+//               m0 = m2+mfbab;
+//               mfbaa = m0;
+//               m0 += c1o9 * oMdrho;
+//               mfbab = m1-m0 * vvz;
+//               mfbac = m2-2. *   m1 * vvz+vz2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m2 = mfbba+mfbbc;
+//               m1 = mfbbc-mfbba;
+//               m0 = m2+mfbbb;
+//               mfbba = m0;
+//               m0 += c4o9 * oMdrho;
+//               mfbbb = m1-m0 * vvz;
+//               mfbbc = m2-2. *   m1 * vvz+vz2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m2 = mfbca+mfbcc;
+//               m1 = mfbcc-mfbca;
+//               m0 = m2+mfbcb;
+//               mfbca = m0;
+//               m0 += c1o9 * oMdrho;
+//               mfbcb = m1-m0 * vvz;
+//               mfbcc = m2-2. *   m1 * vvz+vz2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m2 = mfcaa+mfcac;
+//               m1 = mfcac-mfcaa;
+//               m0 = m2+mfcab;
+//               mfcaa = m0;
+//               m0 += c1o36 * oMdrho;
+//               mfcab = m1-m0 * vvz;
+//               mfcac = m2-2. *   m1 * vvz+vz2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m2 = mfcba+mfcbc;
+//               m1 = mfcbc-mfcba;
+//               m0 = m2+mfcbb;
+//               mfcba = m0;
+//               m0 += c1o9 * oMdrho;
+//               mfcbb = m1-m0 * vvz;
+//               mfcbc = m2-2. *   m1 * vvz+vz2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m2 = mfcca+mfccc;
+//               m1 = mfccc-mfcca;
+//               m0 = m2+mfccb;
+//               mfcca = m0;
+//               m0 += c1o36 * oMdrho;
+//               mfccb = m1-m0 * vvz;
+//               mfccc = m2-2. *   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-2. *   m1 * vvy+vy2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m2 = mfaab+mfacb;
+//               m1 = mfacb-mfaab;
+//               m0 = m2+mfabb;
+//               mfaab = m0;
+//               mfabb = m1-m0 * vvy;
+//               mfacb = m2-2. *   m1 * vvy+vy2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m2 = mfaac+mfacc;
+//               m1 = mfacc-mfaac;
+//               m0 = m2+mfabc;
+//               mfaac = m0;
+//               m0 += c1o18 * oMdrho;
+//               mfabc = m1-m0 * vvy;
+//               mfacc = m2-2. *   m1 * vvy+vy2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m2 = mfbaa+mfbca;
+//               m1 = mfbca-mfbaa;
+//               m0 = m2+mfbba;
+//               mfbaa = m0;
+//               m0 += c2o3 * oMdrho;
+//               mfbba = m1-m0 * vvy;
+//               mfbca = m2-2. *   m1 * vvy+vy2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m2 = mfbab+mfbcb;
+//               m1 = mfbcb-mfbab;
+//               m0 = m2+mfbbb;
+//               mfbab = m0;
+//               mfbbb = m1-m0 * vvy;
+//               mfbcb = m2-2. *   m1 * vvy+vy2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m2 = mfbac+mfbcc;
+//               m1 = mfbcc-mfbac;
+//               m0 = m2+mfbbc;
+//               mfbac = m0;
+//               m0 += c2o9 * oMdrho;
+//               mfbbc = m1-m0 * vvy;
+//               mfbcc = m2-2. *   m1 * vvy+vy2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m2 = mfcaa+mfcca;
+//               m1 = mfcca-mfcaa;
+//               m0 = m2+mfcba;
+//               mfcaa = m0;
+//               m0 += c1o6 * oMdrho;
+//               mfcba = m1-m0 * vvy;
+//               mfcca = m2-2. *   m1 * vvy+vy2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m2 = mfcab+mfccb;
+//               m1 = mfccb-mfcab;
+//               m0 = m2+mfcbb;
+//               mfcab = m0;
+//               mfcbb = m1-m0 * vvy;
+//               mfccb = m2-2. *   m1 * vvy+vy2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m2 = mfcac+mfccc;
+//               m1 = mfccc-mfcac;
+//               m0 = m2+mfcbc;
+//               mfcac = m0;
+//               m0 += c1o18 * oMdrho;
+//               mfcbc = m1-m0 * vvy;
+//               mfccc = m2-2. *   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 += 1. * oMdrho;
+//               mfbaa = m1-m0 * vvx;
+//               mfcaa = m2-2. *   m1 * vvx+vx2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m2 = mfaba+mfcba;
+//               m1 = mfcba-mfaba;
+//               m0 = m2+mfbba;
+//               mfaba = m0;
+//               mfbba = m1-m0 * vvx;
+//               mfcba = m2-2. *   m1 * vvx+vx2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m2 = mfaca+mfcca;
+//               m1 = mfcca-mfaca;
+//               m0 = m2+mfbca;
+//               mfaca = m0;
+//               m0 += c1o3 * oMdrho;
+//               mfbca = m1-m0 * vvx;
+//               mfcca = m2-2. *   m1 * vvx+vx2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m2 = mfaab+mfcab;
+//               m1 = mfcab-mfaab;
+//               m0 = m2+mfbab;
+//               mfaab = m0;
+//               mfbab = m1-m0 * vvx;
+//               mfcab = m2-2. *   m1 * vvx+vx2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m2 = mfabb+mfcbb;
+//               m1 = mfcbb-mfabb;
+//               m0 = m2+mfbbb;
+//               mfabb = m0;
+//               mfbbb = m1-m0 * vvx;
+//               mfcbb = m2-2. *   m1 * vvx+vx2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m2 = mfacb+mfccb;
+//               m1 = mfccb-mfacb;
+//               m0 = m2+mfbcb;
+//               mfacb = m0;
+//               mfbcb = m1-m0 * vvx;
+//               mfccb = m2-2. *   m1 * vvx+vx2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m2 = mfaac+mfcac;
+//               m1 = mfcac-mfaac;
+//               m0 = m2+mfbac;
+//               mfaac = m0;
+//               m0 += c1o3 * oMdrho;
+//               mfbac = m1-m0 * vvx;
+//               mfcac = m2-2. *   m1 * vvx+vx2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m2 = mfabc+mfcbc;
+//               m1 = mfcbc-mfabc;
+//               m0 = m2+mfbbc;
+//               mfabc = m0;
+//               mfbbc = m1-m0 * vvx;
+//               mfcbc = m2-2. *   m1 * vvx+vx2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m2 = mfacc+mfccc;
+//               m1 = mfccc-mfacc;
+//               m0 = m2+mfbcc;
+//               mfacc = m0;
+//               m0 += c1o9 * oMdrho;
+//               mfbcc = m1-m0 * vvx;
+//               mfccc = m2-2. *   m1 * vvx+vx2 * m0;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               // Cumulants
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               LBMReal OxxPyyPzz = 1.; //omega2 or bulk viscosity
+//               LBMReal OxyyPxzz = 1.;//-s9;//2+s9;//
+//               //LBMReal OxyyMxzz  = 1.;//2+s9;//
+//               LBMReal O4 = 1.;
+//               LBMReal O5 = 1.;
+//               LBMReal O6 = 1.;
+//
+//               //Cum 4.
+//               //LBMReal CUMcbb = mfcbb - ((mfcaa + c1o3 * oMdrho) * mfabb + 2. * mfbba * mfbab); // till 18.05.2015
+//               //LBMReal CUMbcb = mfbcb - ((mfaca + c1o3 * oMdrho) * mfbab + 2. * mfbba * mfabb); // till 18.05.2015
+//               //LBMReal CUMbbc = mfbbc - ((mfaac + c1o3 * oMdrho) * mfbba + 2. * mfbab * mfabb); // till 18.05.2015
+//
+//               LBMReal CUMcbb = mfcbb-((mfcaa+c1o3) * mfabb+2. * mfbba * mfbab);
+//               LBMReal CUMbcb = mfbcb-((mfaca+c1o3) * mfbab+2. * mfbba * mfabb);
+//               LBMReal CUMbbc = mfbbc-((mfaac+c1o3) * mfbba+2. * mfbab * mfabb);
+//
+//               LBMReal CUMcca = mfcca-((mfcaa * mfaca+2. * mfbba * mfbba)+c1o3 * (mfcaa+mfaca) * oMdrho+c1o9*(oMdrho-1)*oMdrho);
+//               LBMReal CUMcac = mfcac-((mfcaa * mfaac+2. * mfbab * mfbab)+c1o3 * (mfcaa+mfaac) * oMdrho+c1o9*(oMdrho-1)*oMdrho);
+//               LBMReal CUMacc = mfacc-((mfaac * mfaca+2. * mfabb * mfabb)+c1o3 * (mfaac+mfaca) * oMdrho+c1o9*(oMdrho-1)*oMdrho);
+//
+//               //Cum 5.
+//               LBMReal CUMbcc = mfbcc-(mfaac * mfbca+mfaca * mfbac+4. * mfabb * mfbbb+2. * (mfbab * mfacb+mfbba * mfabc))-c1o3 * (mfbca+mfbac) * oMdrho;
+//               LBMReal CUMcbc = mfcbc-(mfaac * mfcba+mfcaa * mfabc+4. * mfbab * mfbbb+2. * (mfabb * mfcab+mfbba * mfbac))-c1o3 * (mfcba+mfabc) * oMdrho;
+//               LBMReal CUMccb = mfccb-(mfcaa * mfacb+mfaca * mfcab+4. * mfbba * mfbbb+2. * (mfbab * mfbca+mfabb * mfcba))-c1o3 * (mfacb+mfcab) * oMdrho;
+//
+//               //Cum 6.
+//               LBMReal CUMccc = mfccc+((-4. *  mfbbb * mfbbb
+//                  -(mfcaa * mfacc+mfaca * mfcac+mfaac * mfcca)
+//                  -4. * (mfabb * mfcbb+mfbab * mfbcb+mfbba * mfbbc)
+//                  -2. * (mfbca * mfbac+mfcba * mfabc+mfcab * mfacb))
+//                  +(4. * (mfbab * mfbab * mfaca+mfabb * mfabb * mfcaa+mfbba * mfbba * mfaac)
+//                     +2. * (mfcaa * mfaca * mfaac)
+//                     +16. *  mfbba * mfbab * mfabb)
+//                  -c1o3* (mfacc+mfcac+mfcca) * oMdrho-c1o9*oMdrho*oMdrho
+//                  -c1o9* (mfcaa+mfaca+mfaac) * oMdrho*(1.-2.* oMdrho)-c1o27* oMdrho * oMdrho*(-2.* oMdrho)
+//                  +(2. * (mfbab * mfbab+mfabb * mfabb+mfbba * mfbba)
+//                     +(mfaac * mfaca+mfaac * mfcaa+mfaca * mfcaa)) * c2o3*oMdrho)+c1o27*oMdrho;
+//
+//               //2.
+//               // linear combinations
+//               LBMReal mxxPyyPzz = mfcaa+mfaca+mfaac;
+//               LBMReal mxxMyy = mfcaa-mfaca;
+//               LBMReal mxxMzz = mfcaa-mfaac;
+//
+//               LBMReal dxux = -c1o2 * collFactor *(mxxMyy+mxxMzz)+c1o2 * OxxPyyPzz*(mfaaa-mxxPyyPzz);
+//               LBMReal dyuy = dxux+collFactor * c3o2 * mxxMyy;
+//               LBMReal dzuz = dxux+collFactor * c3o2 * mxxMzz;
+//
+//               //relax
+//               mxxPyyPzz += OxxPyyPzz*(mfaaa-mxxPyyPzz)-3. * (1.-c1o2 * OxxPyyPzz) * (vx2 * dxux+vy2 * dyuy+vz2 * dzuz);
+//               mxxMyy += collFactor * (-mxxMyy)-3. * (1.-c1o2 * collFactor) * (vx2 * dxux-vy2 * dyuy);
+//               mxxMzz += collFactor * (-mxxMzz)-3. * (1.-c1o2 * collFactor) * (vx2 * dxux-vz2 * dzuz);
+//
+//               mfabb += collFactor * (-mfabb);
+//               mfbab += collFactor * (-mfbab);
+//               mfbba += collFactor * (-mfbba);
+//
+//               // linear combinations back
+//               mfcaa = c1o3 * (mxxMyy+mxxMzz+mxxPyyPzz);
+//               mfaca = c1o3 * (-2. *  mxxMyy+mxxMzz+mxxPyyPzz);
+//               mfaac = c1o3 * (mxxMyy-2. * 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
+//               wadjust = OxyyMxzz+(1.-OxyyMxzz)*fabs(mfbbb)/(fabs(mfbbb)+qudricLimit);
+//               mfbbb += wadjust * (-mfbbb);
+//               wadjust = OxyyPxzz+(1.-OxyyPxzz)*fabs(mxxyPyzz)/(fabs(mxxyPyzz)+qudricLimit);
+//               mxxyPyzz += wadjust * (-mxxyPyzz);
+//               wadjust = OxyyMxzz+(1.-OxyyMxzz)*fabs(mxxyMyzz)/(fabs(mxxyMyzz)+qudricLimit);
+//               mxxyMyzz += wadjust * (-mxxyMyzz);
+//               wadjust = OxyyPxzz+(1.-OxyyPxzz)*fabs(mxxzPyyz)/(fabs(mxxzPyyz)+qudricLimit);
+//               mxxzPyyz += wadjust * (-mxxzPyyz);
+//               wadjust = OxyyMxzz+(1.-OxyyMxzz)*fabs(mxxzMyyz)/(fabs(mxxzMyyz)+qudricLimit);
+//               mxxzMyyz += wadjust * (-mxxzMyyz);
+//               wadjust = OxyyPxzz+(1.-OxyyPxzz)*fabs(mxyyPxzz)/(fabs(mxyyPxzz)+qudricLimit);
+//               mxyyPxzz += wadjust * (-mxyyPxzz);
+//               wadjust = OxyyMxzz+(1.-OxyyMxzz)*fabs(mxyyMxzz)/(fabs(mxyyMxzz)+qudricLimit);
+//               mxyyMxzz += wadjust * (-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.
+//               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 * oMdrho) * mfabb + 2. * mfbba * mfbab); // till 18.05.2015
+//               //mfbcb = CUMbcb + ((mfaca + c1o3 * oMdrho) * mfbab + 2. * mfbba * mfabb); // till 18.05.2015
+//               //mfbbc = CUMbbc + ((mfaac + c1o3 * oMdrho) * mfbba + 2. * mfbab * mfabb); // till 18.05.2015
+//
+//               mfcbb = CUMcbb+((mfcaa+c1o3) * mfabb+2. * mfbba * mfbab);
+//               mfbcb = CUMbcb+((mfaca+c1o3) * mfbab+2. * mfbba * mfabb);
+//               mfbbc = CUMbbc+((mfaac+c1o3) * mfbba+2. * mfbab * mfabb);
+//
+//               mfcca = CUMcca+(mfcaa * mfaca+2. * mfbba * mfbba)+c1o3 * (mfcaa+mfaca) * oMdrho+c1o9*(oMdrho-1)*oMdrho;
+//               mfcac = CUMcac+(mfcaa * mfaac+2. * mfbab * mfbab)+c1o3 * (mfcaa+mfaac) * oMdrho+c1o9*(oMdrho-1)*oMdrho;
+//               mfacc = CUMacc+(mfaac * mfaca+2. * mfabb * mfabb)+c1o3 * (mfaac+mfaca) * oMdrho+c1o9*(oMdrho-1)*oMdrho;
+//
+//               //5.
+//               mfbcc = CUMbcc+(mfaac * mfbca+mfaca * mfbac+4. * mfabb * mfbbb+2. * (mfbab * mfacb+mfbba * mfabc))+c1o3 * (mfbca+mfbac) * oMdrho;
+//               mfcbc = CUMcbc+(mfaac * mfcba+mfcaa * mfabc+4. * mfbab * mfbbb+2. * (mfabb * mfcab+mfbba * mfbac))+c1o3 * (mfcba+mfabc) * oMdrho;
+//               mfccb = CUMccb+(mfcaa * mfacb+mfaca * mfcab+4. * mfbba * mfbbb+2. * (mfbab * mfbca+mfabb * mfcba))+c1o3 * (mfacb+mfcab) * oMdrho;
+//
+//               //6.
+//               mfccc = CUMccc-((-4. *  mfbbb * mfbbb
+//                  -(mfcaa * mfacc+mfaca * mfcac+mfaac * mfcca)
+//                  -4. * (mfabb * mfcbb+mfbac * mfbca+mfbba * mfbbc)
+//                  -2. * (mfbca * mfbac+mfcba * mfabc+mfcab * mfacb))
+//                  +(4. * (mfbab * mfbab * mfaca+mfabb * mfabb * mfcaa+mfbba * mfbba * mfaac)
+//                     +2. * (mfcaa * mfaca * mfaac)
+//                     +16. *  mfbba * mfbab * mfabb)
+//                  -c1o3* (mfacc+mfcac+mfcca) * oMdrho-c1o9*oMdrho*oMdrho
+//                  -c1o9* (mfcaa+mfaca+mfaac) * oMdrho*(1.-2.* oMdrho)-c1o27* oMdrho * oMdrho*(-2.* oMdrho)
+//                  +(2. * (mfbab * mfbab+mfabb * mfabb+mfbba * mfbba)
+//                     +(mfaac * mfaca+mfaac * mfcaa+mfaca * mfcaa)) * c2o3*oMdrho)-c1o27*oMdrho;
+//
+//               mfaab = 0.0;
+//               mfaba = 0.0;
+//               mfbaa = 0.0;
+//
+//               //mfaab *= -0.5;
+//               //mfaba *= -0.5;
+//               //mfbaa *= -0.5;
+//
+//
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               //back
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               //mit 1, 0, 1/3, 0, 0, 0, 1/3, 0, 1/9   Konditionieren
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               // Z - Dir
+//               m0 = mfaac * c1o2+mfaab * (vvz-c1o2)+(mfaaa+1. * oMdrho) * (vz2-vvz) * c1o2;
+//               m1 = -mfaac-2. * mfaab *  vvz+mfaaa                * (1.-vz2)-1. * oMdrho * vz2;
+//               m2 = mfaac * c1o2+mfaab * (vvz+c1o2)+(mfaaa+1. * oMdrho) * (vz2+vvz) * c1o2;
+//               mfaaa = m0;
+//               mfaab = m1;
+//               mfaac = m2;
+//               ////////////////////////////////////////////////////////////////////////////////////
+//               m0 = mfabc * c1o2+mfabb * (vvz-c1o2)+mfaba * (vz2-vvz) * c1o2;
+//               m1 = -mfabc-2. * mfabb *  vvz+mfaba * (1.-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-2. * mfacb *  vvz+mfaca                  * (1.-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-2. * mfbab *  vvz+mfbaa * (1.-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-2. * mfbbb *  vvz+mfbba * (1.-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-2. * mfbcb *  vvz+mfbca * (1.-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-2. * mfcab *  vvz+mfcaa                  * (1.-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-2. * mfcbb *  vvz+mfcba * (1.-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-2. * mfccb *  vvz+mfcca                  * (1.-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-2. * mfaba *  vvy+mfaaa                  * (1.-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-2. * mfabb *  vvy+mfaab                  * (1.-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-2. * mfabc *  vvy+mfaac                  * (1.-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-2. * mfbba *  vvy+mfbaa * (1.-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-2. * mfbbb *  vvy+mfbab * (1.-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-2. * mfbbc *  vvy+mfbac * (1.-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-2. * mfcba *  vvy+mfcaa                   * (1.-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-2. * mfcbb *  vvy+mfcab                  * (1.-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-2. * mfcbc *  vvy+mfcac                   * (1.-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-2. * mfbaa *  vvx+mfaaa                   * (1.-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-2. * mfbba *  vvx+mfaba                  * (1.-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-2. * mfbca *  vvx+mfaca                   * (1.-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-2. * mfbab *  vvx+mfaab                  * (1.-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-2. * mfbbb *  vvx+mfabb                  * (1.-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-2. * mfbcb *  vvx+mfacb                  * (1.-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-2. * mfbac *  vvx+mfaac                   * (1.-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-2. * mfbbc *  vvx+mfabc                  * (1.-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-2. * mfbcc *  vvx+mfacc                   * (1.-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 rho_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 = rho-rho_post;
+//#ifdef SINGLEPRECISION
+//               if (dif>10.0E-7||dif<-10.0E-7)
+//#else
+//               if (dif>10.0E-15||dif<-10.0E-15)
+//#endif
+//               {
+//                  UB_THROW(UbException(UB_EXARGS, "rho="+UbSystem::toString(rho)+", rho_post="+UbSystem::toString(rho_post)
+//                     +" dif="+UbSystem::toString(dif)
+//                     +" rho is not correct for node "+UbSystem::toString(x1)+","+UbSystem::toString(x2)+","+UbSystem::toString(x3)));
+//                  //UBLOG(logERROR,"LBMKernel3DCCLB::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;
+//               ////////////////////////////////////////////////////////////////////////////
+//
+//            }
+//         }
+//      }
+//   }
+//
+//}
+
+void InitDensityLBMKernel::init()
+{
+   DistributionArray3DPtr d(new D3Q27EsoTwist3DSplittedVector(nx1+2, nx2+2, nx3+2, -999.0));
+   dataSet->setFdistributions(d);
+   v.resize(3, nx1+2, nx2+2, nx3+2);
+
+}
+
+
+void InitDensityLBMKernel::collideAll()
+{
+   using namespace D3Q27System;
+
+   localDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getLocalDistributions();
+   nonLocalDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getNonLocalDistributions();
+   zeroDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getZeroDistributions();
+
+   BCArray3DPtr bcArray = this->getBCProcessor()->getBCArray();
+   BoundaryConditionsPtr bcPtr;
+   LBMReal f[D3Q27System::ENDF+1];
+   LBMReal feq[D3Q27System::ENDF+1];
+   LBMReal drho, vx1, vx2, vx3;
+   const int bcArrayMaxX1 = (int)bcArray->getNX1();
+   const int bcArrayMaxX2 = (int)bcArray->getNX2();
+   const int bcArrayMaxX3 = (int)bcArray->getNX3();
+
+   int minX1 = ghostLayerWidth;
+   int minX2 = ghostLayerWidth;
+   int minX3 = ghostLayerWidth;
+   int maxX1 = bcArrayMaxX1-ghostLayerWidth;
+   int maxX2 = bcArrayMaxX2-ghostLayerWidth;
+   int maxX3 = bcArrayMaxX3-ghostLayerWidth;
+
+   //collFactor = 1.0/(1.0/2.0+1.0/sqrt(6.0));
+   collFactor = 1.0;
+
+   for (int x3 = minX3; x3<maxX3; x3++)
+   {
+      for (int x2 = minX2; x2<maxX2; x2++)
+      {
+         for (int x1 = minX1; x1<maxX1; x1++)
+         {
+            if (!bcArray->isSolid(x1, x2, x3)&&!bcArray->isUndefined(x1, x2, x3))
+            {
+               int x1p = x1+1;
+               int x2p = x2+1;
+               int x3p = x3+1;
+               //////////////////////////////////////////////////////////////////////////
+               //read distribution
+               ////////////////////////////////////////////////////////////////////////////
+               f[ZERO] = (*this->zeroDistributions)(x1, x2, x3);
+
+               f[E] = (*this->localDistributions)(D3Q27System::ET_E, x1, x2, x3);
+               f[N] = (*this->localDistributions)(D3Q27System::ET_N, x1, x2, x3);
+               f[T] = (*this->localDistributions)(D3Q27System::ET_T, x1, x2, x3);
+               f[NE] = (*this->localDistributions)(D3Q27System::ET_NE, x1, x2, x3);
+               f[NW] = (*this->localDistributions)(D3Q27System::ET_NW, x1p, x2, x3);
+               f[TE] = (*this->localDistributions)(D3Q27System::ET_TE, x1, x2, x3);
+               f[TW] = (*this->localDistributions)(D3Q27System::ET_TW, x1p, x2, x3);
+               f[TN] = (*this->localDistributions)(D3Q27System::ET_TN, x1, x2, x3);
+               f[TS] = (*this->localDistributions)(D3Q27System::ET_TS, x1, x2p, x3);
+               f[TNE] = (*this->localDistributions)(D3Q27System::ET_TNE, x1, x2, x3);
+               f[TNW] = (*this->localDistributions)(D3Q27System::ET_TNW, x1p, x2, x3);
+               f[TSE] = (*this->localDistributions)(D3Q27System::ET_TSE, x1, x2p, x3);
+               f[TSW] = (*this->localDistributions)(D3Q27System::ET_TSW, x1p, x2p, x3);
+
+               f[W] = (*this->nonLocalDistributions)(D3Q27System::ET_W, x1p, x2, x3);
+               f[S] = (*this->nonLocalDistributions)(D3Q27System::ET_S, x1, x2p, x3);
+               f[B] = (*this->nonLocalDistributions)(D3Q27System::ET_B, x1, x2, x3p);
+               f[SW] = (*this->nonLocalDistributions)(D3Q27System::ET_SW, x1p, x2p, x3);
+               f[SE] = (*this->nonLocalDistributions)(D3Q27System::ET_SE, x1, x2p, x3);
+               f[BW] = (*this->nonLocalDistributions)(D3Q27System::ET_BW, x1p, x2, x3p);
+               f[BE] = (*this->nonLocalDistributions)(D3Q27System::ET_BE, x1, x2, x3p);
+               f[BS] = (*this->nonLocalDistributions)(D3Q27System::ET_BS, x1, x2p, x3p);
+               f[BN] = (*this->nonLocalDistributions)(D3Q27System::ET_BN, x1, x2, x3p);
+               f[BSW] = (*this->nonLocalDistributions)(D3Q27System::ET_BSW, x1p, x2p, x3p);
+               f[BSE] = (*this->nonLocalDistributions)(D3Q27System::ET_BSE, x1, x2p, x3p);
+               f[BNW] = (*this->nonLocalDistributions)(D3Q27System::ET_BNW, x1p, x2, x3p);
+               f[BNE] = (*this->nonLocalDistributions)(D3Q27System::ET_BNE, x1, x2, x3p);
+               //////////////////////////////////////////////////////////////////////////
+
+               drho = ((f[TNE]+f[BSW])+(f[TSE]+f[BNW]))+((f[BSE]+f[TNW])+(f[TSW]+f[BNE]))
+                  +(((f[NE]+f[SW])+(f[SE]+f[NW]))+((f[TE]+f[BW])+(f[BE]+f[TW]))
+                     +((f[BN]+f[TS])+(f[TN]+f[BS])))+((f[E]+f[W])+(f[N]+f[S])
+                        +(f[T]+f[B]))+f[ZERO];
+
+               //vx1 = ((((f[TNE]-f[BSW])+(f[TSE]-f[BNW]))+((f[BSE]-f[TNW])+(f[BNE]-f[TSW])))+
+               //   (((f[BE]-f[TW])+(f[TE]-f[BW]))+((f[SE]-f[NW])+(f[NE]-f[SW])))+
+               //   (f[E]-f[W]));
+
+               //vx2 = ((((f[TNE]-f[BSW])+(f[BNW]-f[TSE]))+((f[TNW]-f[BSE])+(f[BNE]-f[TSW])))+
+               //   (((f[BN]-f[TS])+(f[TN]-f[BS]))+((f[NW]-f[SE])+(f[NE]-f[SW])))+
+               //   (f[N]-f[S]));
+
+               //vx3 = ((((f[TNE]-f[BSW])+(f[TSE]-f[BNW]))+((f[TNW]-f[BSE])+(f[TSW]-f[BNE])))+
+               //   (((f[TS]-f[BN])+(f[TN]-f[BS]))+((f[TW]-f[BE])+(f[TE]-f[BW])))+
+               //   (f[T]-f[B]));
+
+               vx1 = v(0,x1,x2,x3);
+               vx2 = v(1,x1,x2,x3);
+               vx3 = v(2,x1,x2,x3);
+
+               //LBMReal vvx = v(0,x1,x2,x3);
+               //LBMReal vvy = v(1,x1,x2,x3);
+               //LBMReal vvz = v(2,x1,x2,x3);
+
+               //vx1 = vx1+(vvx-vx1);
+               //vx2 = vx2+(vvy-vx2);
+               //vx3 = vx3+(vvz-vx3);
+
+               LBMReal cu_sq = 1.5*(vx1*vx1+vx2*vx2+vx3*vx3);
+
+               feq[ZERO] = c8o27*(drho-cu_sq);
+               feq[E] = c2o27*(drho+3.0*(vx1)+c9o2*(vx1)*(vx1)-cu_sq);
+               feq[W] = c2o27*(drho+3.0*(-vx1)+c9o2*(-vx1)*(-vx1)-cu_sq);
+               feq[N] = c2o27*(drho+3.0*(vx2)+c9o2*(vx2)*(vx2)-cu_sq);
+               feq[S] = c2o27*(drho+3.0*(-vx2)+c9o2*(-vx2)*(-vx2)-cu_sq);
+               feq[T] = c2o27*(drho+3.0*(vx3)+c9o2*(vx3)*(vx3)-cu_sq);
+               feq[B] = c2o27*(drho+3.0*(-vx3)+c9o2*(-vx3)*(-vx3)-cu_sq);
+               feq[NE] = c1o54*(drho+3.0*(vx1+vx2)+c9o2*(vx1+vx2)*(vx1+vx2)-cu_sq);
+               feq[SW] = c1o54*(drho+3.0*(-vx1-vx2)+c9o2*(-vx1-vx2)*(-vx1-vx2)-cu_sq);
+               feq[SE] = c1o54*(drho+3.0*(vx1-vx2)+c9o2*(vx1-vx2)*(vx1-vx2)-cu_sq);
+               feq[NW] = c1o54*(drho+3.0*(-vx1+vx2)+c9o2*(-vx1+vx2)*(-vx1+vx2)-cu_sq);
+               feq[TE] = c1o54*(drho+3.0*(vx1+vx3)+c9o2*(vx1+vx3)*(vx1+vx3)-cu_sq);
+               feq[BW] = c1o54*(drho+3.0*(-vx1-vx3)+c9o2*(-vx1-vx3)*(-vx1-vx3)-cu_sq);
+               feq[BE] = c1o54*(drho+3.0*(vx1-vx3)+c9o2*(vx1-vx3)*(vx1-vx3)-cu_sq);
+               feq[TW] = c1o54*(drho+3.0*(-vx1+vx3)+c9o2*(-vx1+vx3)*(-vx1+vx3)-cu_sq);
+               feq[TN] = c1o54*(drho+3.0*(vx2+vx3)+c9o2*(vx2+vx3)*(vx2+vx3)-cu_sq);
+               feq[BS] = c1o54*(drho+3.0*(-vx2-vx3)+c9o2*(-vx2-vx3)*(-vx2-vx3)-cu_sq);
+               feq[BN] = c1o54*(drho+3.0*(vx2-vx3)+c9o2*(vx2-vx3)*(vx2-vx3)-cu_sq);
+               feq[TS] = c1o54*(drho+3.0*(-vx2+vx3)+c9o2*(-vx2+vx3)*(-vx2+vx3)-cu_sq);
+               feq[TNE] = c1o216*(drho+3.0*(vx1+vx2+vx3)+c9o2*(vx1+vx2+vx3)*(vx1+vx2+vx3)-cu_sq);
+               feq[BSW] = c1o216*(drho+3.0*(-vx1-vx2-vx3)+c9o2*(-vx1-vx2-vx3)*(-vx1-vx2-vx3)-cu_sq);
+               feq[BNE] = c1o216*(drho+3.0*(vx1+vx2-vx3)+c9o2*(vx1+vx2-vx3)*(vx1+vx2-vx3)-cu_sq);
+               feq[TSW] = c1o216*(drho+3.0*(-vx1-vx2+vx3)+c9o2*(-vx1-vx2+vx3)*(-vx1-vx2+vx3)-cu_sq);
+               feq[TSE] = c1o216*(drho+3.0*(vx1-vx2+vx3)+c9o2*(vx1-vx2+vx3)*(vx1-vx2+vx3)-cu_sq);
+               feq[BNW] = c1o216*(drho+3.0*(-vx1+vx2-vx3)+c9o2*(-vx1+vx2-vx3)*(-vx1+vx2-vx3)-cu_sq);
+               feq[BSE] = c1o216*(drho+3.0*(vx1-vx2-vx3)+c9o2*(vx1-vx2-vx3)*(vx1-vx2-vx3)-cu_sq);
+               feq[TNW] = c1o216*(drho+3.0*(-vx1+vx2+vx3)+c9o2*(-vx1+vx2+vx3)*(-vx1+vx2+vx3)-cu_sq);
+
+               //Relaxation
+               f[ZERO] += (feq[ZERO]-f[ZERO])*collFactor;
+               f[E] += (feq[E]-f[E])*collFactor;
+               f[W] += (feq[W]-f[W])*collFactor;
+               f[N] += (feq[N]-f[N])*collFactor;
+               f[S] += (feq[S]-f[S])*collFactor;
+               f[T] += (feq[T]-f[T])*collFactor;
+               f[B] += (feq[B]-f[B])*collFactor;
+               f[NE] += (feq[NE]-f[NE])*collFactor;
+               f[SW] += (feq[SW]-f[SW])*collFactor;
+               f[SE] += (feq[SE]-f[SE])*collFactor;
+               f[NW] += (feq[NW]-f[NW])*collFactor;
+               f[TE] += (feq[TE]-f[TE])*collFactor;
+               f[BW] += (feq[BW]-f[BW])*collFactor;
+               f[BE] += (feq[BE]-f[BE])*collFactor;
+               f[TW] += (feq[TW]-f[TW])*collFactor;
+               f[TN] += (feq[TN]-f[TN])*collFactor;
+               f[BS] += (feq[BS]-f[BS])*collFactor;
+               f[BN] += (feq[BN]-f[BN])*collFactor;
+               f[TS] += (feq[TS]-f[TS])*collFactor;
+
+               f[TNE] += (feq[TNE]-f[TNE])*collFactor;
+               f[BSW] += (feq[BSW]-f[BSW])*collFactor;
+               f[BNE] += (feq[BNE]-f[BNE])*collFactor;
+               f[TSW] += (feq[TSW]-f[TSW])*collFactor;
+               f[TSE] += (feq[TSE]-f[TSE])*collFactor;
+               f[BNW] += (feq[BNW]-f[BNW])*collFactor;
+               f[BSE] += (feq[BSE]-f[BSE])*collFactor;
+               f[TNW] += (feq[TNW]-f[TNW])*collFactor;
+
+               //////////////////////////////////////////////////////////////////////////
+#ifdef  PROOF_CORRECTNESS
+               LBMReal rho_post = f[ZERO]+f[E]+f[W]+f[N]+f[S]+f[T]+f[B]
+                  +f[NE]+f[SW]+f[SE]+f[NW]+f[TE]+f[BW]+f[BE]
+                  +f[TW]+f[TN]+f[BS]+f[BN]+f[TS]+f[TNE]+f[TSW]
+                  +f[TSE]+f[TNW]+f[BNE]+f[BSW]+f[BSE]+f[BNW];
+               LBMReal dif = drho-rho_post;
+#ifdef SINGLEPRECISION
+               if (dif>10.0E-7||dif<-10.0E-7)
+#else
+               if (dif>10.0E-15||dif<-10.0E-15)
+#endif
+               {
+                  UB_THROW(UbException(UB_EXARGS, "rho is not correct"));
+               }
+#endif
+               //////////////////////////////////////////////////////////////////////////
+               //write distribution
+               //////////////////////////////////////////////////////////////////////////
+               (*this->localDistributions)(D3Q27System::ET_E, x1, x2, x3) = f[D3Q27System::INV_E];
+               (*this->localDistributions)(D3Q27System::ET_N, x1, x2, x3) = f[D3Q27System::INV_N];
+               (*this->localDistributions)(D3Q27System::ET_T, x1, x2, x3) = f[D3Q27System::INV_T];
+               (*this->localDistributions)(D3Q27System::ET_NE, x1, x2, x3) = f[D3Q27System::INV_NE];
+               (*this->localDistributions)(D3Q27System::ET_NW, x1p, x2, x3) = f[D3Q27System::INV_NW];
+               (*this->localDistributions)(D3Q27System::ET_TE, x1, x2, x3) = f[D3Q27System::INV_TE];
+               (*this->localDistributions)(D3Q27System::ET_TW, x1p, x2, x3) = f[D3Q27System::INV_TW];
+               (*this->localDistributions)(D3Q27System::ET_TN, x1, x2, x3) = f[D3Q27System::INV_TN];
+               (*this->localDistributions)(D3Q27System::ET_TS, x1, x2p, x3) = f[D3Q27System::INV_TS];
+               (*this->localDistributions)(D3Q27System::ET_TNE, x1, x2, x3) = f[D3Q27System::INV_TNE];
+               (*this->localDistributions)(D3Q27System::ET_TNW, x1p, x2, x3) = f[D3Q27System::INV_TNW];
+               (*this->localDistributions)(D3Q27System::ET_TSE, x1, x2p, x3) = f[D3Q27System::INV_TSE];
+               (*this->localDistributions)(D3Q27System::ET_TSW, x1p, x2p, x3) = f[D3Q27System::INV_TSW];
+
+               (*this->nonLocalDistributions)(D3Q27System::ET_W, x1p, x2, x3) = f[D3Q27System::INV_W];
+               (*this->nonLocalDistributions)(D3Q27System::ET_S, x1, x2p, x3) = f[D3Q27System::INV_S];
+               (*this->nonLocalDistributions)(D3Q27System::ET_B, x1, x2, x3p) = f[D3Q27System::INV_B];
+               (*this->nonLocalDistributions)(D3Q27System::ET_SW, x1p, x2p, x3) = f[D3Q27System::INV_SW];
+               (*this->nonLocalDistributions)(D3Q27System::ET_SE, x1, x2p, x3) = f[D3Q27System::INV_SE];
+               (*this->nonLocalDistributions)(D3Q27System::ET_BW, x1p, x2, x3p) = f[D3Q27System::INV_BW];
+               (*this->nonLocalDistributions)(D3Q27System::ET_BE, x1, x2, x3p) = f[D3Q27System::INV_BE];
+               (*this->nonLocalDistributions)(D3Q27System::ET_BS, x1, x2p, x3p) = f[D3Q27System::INV_BS];
+               (*this->nonLocalDistributions)(D3Q27System::ET_BN, x1, x2, x3p) = f[D3Q27System::INV_BN];
+               (*this->nonLocalDistributions)(D3Q27System::ET_BSW, x1p, x2p, x3p) = f[D3Q27System::INV_BSW];
+               (*this->nonLocalDistributions)(D3Q27System::ET_BSE, x1, x2p, x3p) = f[D3Q27System::INV_BSE];
+               (*this->nonLocalDistributions)(D3Q27System::ET_BNW, x1p, x2, x3p) = f[D3Q27System::INV_BNW];
+               (*this->nonLocalDistributions)(D3Q27System::ET_BNE, x1, x2, x3p) = f[D3Q27System::INV_BNE];
+
+               (*this->zeroDistributions)(x1, x2, x3) = f[D3Q27System::ZERO];
+               //////////////////////////////////////////////////////////////////////////
+
+
+            }
+         }
+      }
+   }
 }
\ No newline at end of file
diff --git a/source/VirtualFluidsCore/LBM/InitDensityLBMKernel.h b/source/VirtualFluidsCore/LBM/InitDensityLBMKernel.h
index bf0b52614..1c0bad607 100644
--- a/source/VirtualFluidsCore/LBM/InitDensityLBMKernel.h
+++ b/source/VirtualFluidsCore/LBM/InitDensityLBMKernel.h
@@ -1,30 +1,33 @@
-#ifndef InitDensityLBMKernel_h__
-#define InitDensityLBMKernel_h__
-
-#include "LBMKernel.h"
-#include "basics/utilities/UbTiming.h"
-
-class InitDensityLBMKernel :  public LBMKernel
-{
-public:
-   InitDensityLBMKernel();
-   ~InitDensityLBMKernel();
-   InitDensityLBMKernel(int nx1, int nx2, int nx3);
-   void calculate();
-   LBMKernelPtr clone();
-   void setVelocity(int x1, int x2, int x3, LBMReal vvx, LBMReal vvy, LBMReal vvz);
-   double getCallculationTime();
-protected:
-   void init();
-   void collideAll();
-private:
-   LBMReal f[D3Q27System::ENDF+1];
-   CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions;
-   CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions;
-   CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr   zeroDistributions;
-   LBMReal OxyyMxzz;
-   CbArray4D<LBMReal, IndexerX4X3X2X1> v;
-};
-
-#endif // InitDensityLBMKernel_h__
-
+#ifndef InitDensityLBMKernel_h__
+#define InitDensityLBMKernel_h__
+
+#include "LBMKernel.h"
+#include "basics/utilities/UbTiming.h"
+#include "CbArray4D.h"
+#include "D3Q27System.h"
+#include "CbArray3D.h"
+
+class InitDensityLBMKernel :  public LBMKernel
+{
+public:
+   InitDensityLBMKernel();
+   ~InitDensityLBMKernel();
+   InitDensityLBMKernel(int nx1, int nx2, int nx3);
+   void calculate();
+   LBMKernelPtr clone();
+   void setVelocity(int x1, int x2, int x3, LBMReal vvx, LBMReal vvy, LBMReal vvz);
+   double getCalculationTime();
+protected:
+   void init();
+   void collideAll();
+private:
+   LBMReal f[D3Q27System::ENDF+1];
+   CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions;
+   CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions;
+   CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr   zeroDistributions;
+   LBMReal OxyyMxzz;
+   CbArray4D<LBMReal, IndexerX4X3X2X1> v;
+};
+
+#endif // InitDensityLBMKernel_h__
+
diff --git a/source/VirtualFluidsCore/LBM/InterpolationHelper.h b/source/VirtualFluidsCore/LBM/InterpolationHelper.h
index fe6ab190f..4e88bc8d5 100644
--- a/source/VirtualFluidsCore/LBM/InterpolationHelper.h
+++ b/source/VirtualFluidsCore/LBM/InterpolationHelper.h
@@ -4,7 +4,7 @@
 #include "InterpolationProcessor.h"
 
 class InterpolationHelper;
-typedef boost::shared_ptr<InterpolationHelper> InterpolationHelperPtr;
+typedef std::shared_ptr<InterpolationHelper> InterpolationHelperPtr;
 
 class InterpolationHelper
 {
diff --git a/source/VirtualFluidsCore/LBM/InterpolationProcessor.h b/source/VirtualFluidsCore/LBM/InterpolationProcessor.h
index ad0919e7f..3d66d2f9f 100644
--- a/source/VirtualFluidsCore/LBM/InterpolationProcessor.h
+++ b/source/VirtualFluidsCore/LBM/InterpolationProcessor.h
@@ -21,7 +21,7 @@ struct D3Q27ICell
 };
 
 class InterpolationProcessor;
-typedef boost::shared_ptr<InterpolationProcessor> InterpolationProcessorPtr;
+typedef std::shared_ptr<InterpolationProcessor> InterpolationProcessorPtr;
 
 #include "InterpolationHelper.h"
 
diff --git a/source/VirtualFluidsCore/LBM/LBMKernel.cpp b/source/VirtualFluidsCore/LBM/LBMKernel.cpp
index b36369732..44a31a045 100644
--- a/source/VirtualFluidsCore/LBM/LBMKernel.cpp
+++ b/source/VirtualFluidsCore/LBM/LBMKernel.cpp
@@ -1,207 +1,215 @@
-#include "LBMKernel.h"
-
-
-LBMKernel::LBMKernel() : ghostLayerWidth(1),
-                             deltaT(1.0),
-                             withForcing(false),
-                             withSpongeLayer(false),
-                             compressible(false)
-{
-   this->setForcingX1(0.0);
-   this->setForcingX2(0.0);
-   this->setForcingX3(0.0);
-   dataSet = DataSet3DPtr(new DataSet3D());
-}
-//////////////////////////////////////////////////////////////////////////
-LBMKernel::~LBMKernel()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-void LBMKernel::setBCProcessor(BCProcessorPtr bcp)
-{
-   bcProcessor = bcp;
-}
-//////////////////////////////////////////////////////////////////////////
-BCProcessorPtr LBMKernel::getBCProcessor() 
-{
-   return bcProcessor;
-}
-//////////////////////////////////////////////////////////////////////////
-void LBMKernel::setCollisionFactor(double collFactor) 
-{
-   this->collFactor = collFactor;
-}
-//////////////////////////////////////////////////////////////////////////
-double LBMKernel::getCollisionFactor() const
-{
-   return collFactor;
-}
-//////////////////////////////////////////////////////////////////////////
-void LBMKernel::setForcingX1(LBMReal forcingX1)
-{
-    this->muForcingX1.SetExpr( UbSystem::toString(forcingX1,LBMRealLim::digits10) );  
-    this->checkFunction(muForcingX1); 
-}
-//////////////////////////////////////////////////////////////////////////
-void LBMKernel::setForcingX2(LBMReal forcingX2)
-{
-   this->muForcingX2.SetExpr( UbSystem::toString(forcingX2,LBMRealLim::digits10) );  
-   this->checkFunction(muForcingX2);
-}
-void LBMKernel::setForcingX3(LBMReal forcingX3)
-{
-   this->muForcingX3.SetExpr( UbSystem::toString(forcingX3,LBMRealLim::digits10) );  
-   this->checkFunction(muForcingX3); 
-}
-//////////////////////////////////////////////////////////////////////////
-void LBMKernel::setForcingX1( const mu::Parser& parser)
-{ 
-   this->checkFunction(parser); 
-   this->muForcingX1 = parser;  
-}
-//////////////////////////////////////////////////////////////////////////
-void LBMKernel::setForcingX2( const mu::Parser& parser)  
-{ 
-   this->checkFunction(parser); 
-   this->muForcingX2 = parser;  
-}
-//////////////////////////////////////////////////////////////////////////
-void LBMKernel::setForcingX3( const mu::Parser& parser)  
-{ 
-   this->checkFunction(parser); 
-   this->muForcingX3 = parser;  
-}
-//////////////////////////////////////////////////////////////////////////
-void LBMKernel::setForcingX1( const std::string& muParserString)  
-{ 
-   this->muForcingX1.SetExpr(muParserString); 
-   this->checkFunction(muForcingX1); 
-}
-//////////////////////////////////////////////////////////////////////////
-void LBMKernel::setForcingX2( const std::string& muParserString)  
-{ 
-   this->muForcingX2.SetExpr(muParserString); 
-   this->checkFunction(muForcingX2); 
-}
-void LBMKernel::setForcingX3( const std::string& muParserString)  
-{ 
-   this->muForcingX3.SetExpr(muParserString); 
-   this->checkFunction(muForcingX3); 
-}
-//////////////////////////////////////////////////////////////////////////
-void LBMKernel::checkFunction(mu::Parser fct)
-{
-   double x1=1.0,x2=1.0,x3=1.0, dt=1.0, nue=1.0;
-   fct.DefineVar("x1",&x1); 
-   fct.DefineVar("x2",&x2); 
-   fct.DefineVar("x3",&x3);
-   fct.DefineVar("dt",&dt);
-   fct.DefineVar("nue",&nue);
-
-   try
-   {
-      fct.Eval();
-      fct.ClearVar();
-   }
-   catch(mu::ParserError& e)
-   {
-      throw UbException(UB_EXARGS,"function: "+e.GetExpr() + (std::string)"error: "+e.GetMsg()
-         +(std::string)", only x1,x2,x3,dx are allowed as variables" );
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void LBMKernel::setGhostLayerWidth(int witdh)
-{
-   ghostLayerWidth = witdh;
-}
-//////////////////////////////////////////////////////////////////////////
-int  LBMKernel::getGhostLayerWidth() const
-{
-   return ghostLayerWidth;
-}
-//////////////////////////////////////////////////////////////////////////
-void LBMKernel::setIndex( int x1, int x2, int x3 )
-{
-   this->ix1 = x1;
-   this->ix2 = x2;
-   this->ix3 = x3;
-}
-//////////////////////////////////////////////////////////////////////////
-DataSet3DPtr LBMKernel::getDataSet() const
-{
-   return this->dataSet;
-}
-//////////////////////////////////////////////////////////////////////////
-LBMReal LBMKernel::getDeltaT()
-{
-   return this->deltaT;
-}
-//////////////////////////////////////////////////////////////////////////
-void LBMKernel::setDeltaT( LBMReal dt )
-{
-   deltaT = dt;
-}
-//////////////////////////////////////////////////////////////////////////
-bool LBMKernel::getCompressible() const 
-{ 
-   return compressible; 
-}
-//////////////////////////////////////////////////////////////////////////
-void LBMKernel::setCompressible(bool val) 
-{ 
-   compressible = val; 
-}
-//////////////////////////////////////////////////////////////////////////
-bool LBMKernel::getWithForcing() const
-{
-   return withForcing;
-}
-//////////////////////////////////////////////////////////////////////////
-void LBMKernel::setWithForcing( bool val )
-{
-   withForcing = val;
-}
-//////////////////////////////////////////////////////////////////////////
-void LBMKernel::setBlock( Block3DPtr block )
-{
-   this->block = block;
-}
-//////////////////////////////////////////////////////////////////////////
-Block3DPtr LBMKernel::getBlock() const
-{
-   return block.lock();
-}
-//////////////////////////////////////////////////////////////////////////
-bool LBMKernel::getWithSpongeLayer() const
-{
-   return withSpongeLayer;
-}
-//////////////////////////////////////////////////////////////////////////
-void LBMKernel::setWithSpongeLayer( bool val )
-{
-   withSpongeLayer = val;
-}
-//////////////////////////////////////////////////////////////////////////
-void LBMKernel::setSpongeLayer( const mu::Parser& parser )
-{
-   this->checkFunction(parser); 
-   this->muSpongeLayer = parser;
-}
-//////////////////////////////////////////////////////////////////////////
-void LBMKernel::setSpongeLayer( const std::string& muParserString )
-{
-   this->muSpongeLayer.SetExpr(muParserString); 
-   this->checkFunction(muSpongeLayer); 
-}
-//////////////////////////////////////////////////////////////////////////
-void LBMKernel::setDataSet(DataSet3DPtr dataSet)
-{
-   this->dataSet = dataSet;
-}
-//////////////////////////////////////////////////////////////////////////
-void LBMKernel::swapDistributions()
-{
-   dataSet->getFdistributions()->swap();
-}
-
+#include "LBMKernel.h"
+#include "DataSet3D.h"
+#include "BCProcessor.h"
+#include "Block3D.h"
+#include "BCArray3D.h"
+
+LBMKernel::LBMKernel() : ghostLayerWidth(1),
+                             deltaT(1.0),
+                             withForcing(false),
+                             withSpongeLayer(false),
+                             compressible(false)
+{
+   this->setForcingX1(0.0);
+   this->setForcingX2(0.0);
+   this->setForcingX3(0.0);
+   dataSet = DataSet3DPtr(new DataSet3D());
+}
+//////////////////////////////////////////////////////////////////////////
+LBMKernel::~LBMKernel()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setBCProcessor(BCProcessorPtr bcp)
+{
+   bcProcessor = bcp;
+}
+//////////////////////////////////////////////////////////////////////////
+BCProcessorPtr LBMKernel::getBCProcessor() const
+{
+   return bcProcessor;
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setCollisionFactor(double collFactor) 
+{
+   this->collFactor = collFactor;
+}
+//////////////////////////////////////////////////////////////////////////
+double LBMKernel::getCollisionFactor() const
+{
+   return collFactor;
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setForcingX1(LBMReal forcingX1)
+{
+    this->muForcingX1.SetExpr( UbSystem::toString(forcingX1,LBMRealLim::digits10) );  
+    this->checkFunction(muForcingX1); 
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setForcingX2(LBMReal forcingX2)
+{
+   this->muForcingX2.SetExpr( UbSystem::toString(forcingX2,LBMRealLim::digits10) );  
+   this->checkFunction(muForcingX2);
+}
+void LBMKernel::setForcingX3(LBMReal forcingX3)
+{
+   this->muForcingX3.SetExpr( UbSystem::toString(forcingX3,LBMRealLim::digits10) );  
+   this->checkFunction(muForcingX3); 
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setForcingX1( const mu::Parser& parser)
+{ 
+   this->checkFunction(parser); 
+   this->muForcingX1 = parser;  
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setForcingX2( const mu::Parser& parser)  
+{ 
+   this->checkFunction(parser); 
+   this->muForcingX2 = parser;  
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setForcingX3( const mu::Parser& parser)  
+{ 
+   this->checkFunction(parser); 
+   this->muForcingX3 = parser;  
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setForcingX1( const std::string& muParserString)  
+{ 
+   this->muForcingX1.SetExpr(muParserString); 
+   this->checkFunction(muForcingX1); 
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setForcingX2( const std::string& muParserString)  
+{ 
+   this->muForcingX2.SetExpr(muParserString); 
+   this->checkFunction(muForcingX2); 
+}
+void LBMKernel::setForcingX3( const std::string& muParserString)  
+{ 
+   this->muForcingX3.SetExpr(muParserString); 
+   this->checkFunction(muForcingX3); 
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::checkFunction(mu::Parser fct)
+{
+   double x1=1.0,x2=1.0,x3=1.0, dt=1.0, nue=1.0;
+   fct.DefineVar("x1",&x1); 
+   fct.DefineVar("x2",&x2); 
+   fct.DefineVar("x3",&x3);
+   fct.DefineVar("dt",&dt);
+   fct.DefineVar("nue",&nue);
+
+   try
+   {
+      fct.Eval();
+      fct.ClearVar();
+   }
+   catch(mu::ParserError& e)
+   {
+      throw UbException(UB_EXARGS,"function: "+e.GetExpr() + (std::string)"error: "+e.GetMsg()
+         +(std::string)", only x1,x2,x3,dx are allowed as variables" );
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setGhostLayerWidth(int witdh)
+{
+   ghostLayerWidth = witdh;
+}
+//////////////////////////////////////////////////////////////////////////
+int  LBMKernel::getGhostLayerWidth() const
+{
+   return ghostLayerWidth;
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setIndex( int x1, int x2, int x3 )
+{
+   this->ix1 = x1;
+   this->ix2 = x2;
+   this->ix3 = x3;
+}
+//////////////////////////////////////////////////////////////////////////
+DataSet3DPtr LBMKernel::getDataSet() const
+{
+   return this->dataSet;
+}
+//////////////////////////////////////////////////////////////////////////
+LBMReal LBMKernel::getDeltaT() const
+{
+   return this->deltaT;
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setDeltaT( LBMReal dt )
+{
+   deltaT = dt;
+}
+//////////////////////////////////////////////////////////////////////////
+bool LBMKernel::getCompressible() const 
+{ 
+   return compressible; 
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setCompressible(bool val) 
+{ 
+   compressible = val; 
+}
+//////////////////////////////////////////////////////////////////////////
+bool LBMKernel::getWithForcing() const
+{
+   return withForcing;
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setWithForcing( bool val )
+{
+   withForcing = val;
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setBlock( Block3DPtr block )
+{
+   this->block = block;
+}
+//////////////////////////////////////////////////////////////////////////
+Block3DPtr LBMKernel::getBlock() const
+{
+   return block.lock();
+}
+//////////////////////////////////////////////////////////////////////////
+bool LBMKernel::getWithSpongeLayer() const
+{
+   return withSpongeLayer;
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setWithSpongeLayer( bool val )
+{
+   withSpongeLayer = val;
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setSpongeLayer( const mu::Parser& parser )
+{
+   this->checkFunction(parser); 
+   this->muSpongeLayer = parser;
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setSpongeLayer( const std::string& muParserString )
+{
+   this->muSpongeLayer.SetExpr(muParserString); 
+   this->checkFunction(muSpongeLayer); 
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setDataSet(DataSet3DPtr dataSet)
+{
+   this->dataSet = dataSet;
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::swapDistributions()
+{
+   dataSet->getFdistributions()->swap();
+}
+//////////////////////////////////////////////////////////////////////////
+bool LBMKernel::isInsideOfDomain(const int& x1, const int& x2, const int& x3) const
+{
+    const BCArray3DPtr bcArray = this->bcProcessor->getBCArray();
+    return bcArray->isInsideOfDomain(x1, x2, x3, ghostLayerWidth);
+}
diff --git a/source/VirtualFluidsCore/LBM/LBMKernel.h b/source/VirtualFluidsCore/LBM/LBMKernel.h
index c88a7f92a..6ad17dac1 100644
--- a/source/VirtualFluidsCore/LBM/LBMKernel.h
+++ b/source/VirtualFluidsCore/LBM/LBMKernel.h
@@ -1,124 +1,126 @@
-#ifndef LBMKERNEL_H
-#define LBMKERNEL_H
-
-#include "LBMSystem.h"
-#include "DistributionArray3D.h"
-#include "DataSet3D.h"
-
-#include "InterpolationProcessor.h"
-#include <MuParser/include/muParser.h>
-
-#include <boost/serialization/serialization.hpp>
-#include <boost/enable_shared_from_this.hpp>
-
-#include <boost/weak_ptr.hpp>
-#include <boost/shared_ptr.hpp>
-class LBMKernel;
-typedef boost::shared_ptr<LBMKernel> LBMKernelPtr;
-
-#include "BCProcessor.h"
-#include "Block3D.h"
-
-class LBMKernel : public boost::enable_shared_from_this<LBMKernel>
-{
-public:
-   typedef std::numeric_limits<LBMReal> LBMRealLim;
-public:
-   LBMKernel();
-   virtual ~LBMKernel();
-
-   virtual LBMKernelPtr clone() = 0;
-
-   virtual void calculate() = 0;
-   virtual double getCallculationTime() = 0;
-
-   void setBCProcessor(BCProcessorPtr bcp);
-   BCProcessorPtr getBCProcessor();
-   
-   void setCollisionFactor(double collFactor);
-   double getCollisionFactor() const;
-   
-   void setGhostLayerWidth(int witdh);
-   int  getGhostLayerWidth() const;
-
-   void setDataSet(DataSet3DPtr dataSet);
-   DataSet3DPtr getDataSet() const;
-
-   void setForcingX1(LBMReal forcingX1);
-   void setForcingX2(LBMReal forcingX2);
-   void setForcingX3(LBMReal forcingX3);
-
-   void setForcingX1( const mu::Parser& parser);
-   void setForcingX2( const mu::Parser& parser);
-   void setForcingX3( const mu::Parser& parser);
-
-   void setForcingX1( const std::string& muParserString);
-   void setForcingX2( const std::string& muParserString);
-   void setForcingX3( const std::string& muParserString);
-
-   void setIndex(int x1, int x2, int x3);
-
-   LBMReal getDeltaT();
-   void setDeltaT(LBMReal dt);
-
-   bool getCompressible() const;
-   void setCompressible(bool val);
-
-   bool getWithForcing() const;
-   void setWithForcing(bool val);
-
-   bool getWithSpongeLayer() const;
-   void setWithSpongeLayer(bool val);
-
-   void setSpongeLayer(const mu::Parser& parser);
-   void setSpongeLayer(const std::string& muParserString);
-
-   void setBlock(Block3DPtr block);
-   Block3DPtr getBlock() const;
-
-   void swapDistributions();
-
-protected:
-   DataSet3DPtr dataSet;
-   BCProcessorPtr bcProcessor; 
-   LBMReal collFactor;
-   int ghostLayerWidth;
-   bool compressible;
-   
-   //forcing 
-   bool withForcing;
-   mu::Parser muForcingX1;
-   mu::Parser muForcingX2;
-   mu::Parser muForcingX3;
-   int ix1, ix2, ix3;
-   LBMReal deltaT;
-
-   //sponge layer
-   bool withSpongeLayer;
-   mu::Parser muSpongeLayer;
-
-   boost::weak_ptr<Block3D> block;
-
-   int nx1, nx2, nx3;
-
-private:
-   friend class boost::serialization::access;
-   template<class Archive>
-   void serialize(Archive & ar, const unsigned int version)
-   {
-      ar & collFactor;
-      ar & ghostLayerWidth;
-      ar & compressible;
-      ar & withForcing;
-      //ar & withSpongeLayer;
-      ar & deltaT;
-      ar & dataSet;
-      ar & bcProcessor;
-      ar & ix1 & ix2 & ix3;
-      ar & nx1 & nx2 & nx3;
-   }
-
-   void checkFunction(mu::Parser fct);
-};
-
-#endif
+#ifndef LBMKERNEL_H
+#define LBMKERNEL_H
+
+#include <memory>
+
+#include "LBMSystem.h"
+
+#include <MuParser/include/muParser.h>
+
+#include <boost/serialization/serialization.hpp>
+
+#include "ILBMKernel.h"
+
+class LBMKernel;
+typedef std::shared_ptr<LBMKernel> LBMKernelPtr;
+
+class BCProcessor;
+class DataSet3D;
+class Block3D;
+
+class LBMKernel : public ILBMKernel, public std::enable_shared_from_this<LBMKernel>
+{
+public:
+    typedef std::numeric_limits<LBMReal> LBMRealLim;
+public:
+    LBMKernel();
+    virtual ~LBMKernel();
+
+    virtual LBMKernelPtr clone() = 0;
+
+    virtual void calculate() = 0;
+    virtual double getCalculationTime() = 0;
+
+    void setBCProcessor(std::shared_ptr<BCProcessor> bcp);
+    std::shared_ptr<BCProcessor> getBCProcessor() const;
+
+    void setCollisionFactor(double collFactor);
+    double getCollisionFactor() const;
+
+    void setGhostLayerWidth(int witdh);
+    int  getGhostLayerWidth() const;
+
+    void setDataSet(std::shared_ptr<DataSet3D> dataSet);
+    std::shared_ptr<DataSet3D> getDataSet() const;
+
+    void setForcingX1(LBMReal forcingX1);
+    void setForcingX2(LBMReal forcingX2);
+    void setForcingX3(LBMReal forcingX3);
+
+    void setForcingX1(const mu::Parser& parser);
+    void setForcingX2(const mu::Parser& parser);
+    void setForcingX3(const mu::Parser& parser);
+
+    void setForcingX1(const std::string& muParserString);
+    void setForcingX2(const std::string& muParserString);
+    void setForcingX3(const std::string& muParserString);
+
+    void setIndex(int x1, int x2, int x3);
+
+    LBMReal getDeltaT() const;
+    void setDeltaT(LBMReal dt);
+
+    bool getCompressible() const;
+    void setCompressible(bool val);
+
+    bool getWithForcing() const;
+    void setWithForcing(bool val);
+
+    bool getWithSpongeLayer() const;
+    void setWithSpongeLayer(bool val);
+
+    void setSpongeLayer(const mu::Parser& parser);
+    void setSpongeLayer(const std::string& muParserString);
+
+    void setBlock(std::shared_ptr<Block3D> block);
+    std::shared_ptr<Block3D> getBlock() const;
+
+    bool isInsideOfDomain(const int &x1, const int &x2, const int &x3) const;
+
+
+    void swapDistributions();
+
+protected:
+    std::shared_ptr<DataSet3D> dataSet;
+    std::shared_ptr<BCProcessor> bcProcessor;
+    LBMReal collFactor;
+    int ghostLayerWidth;
+    bool compressible;
+
+    //forcing 
+    bool withForcing;
+    mu::Parser muForcingX1;
+    mu::Parser muForcingX2;
+    mu::Parser muForcingX3;
+    int ix1, ix2, ix3;
+    LBMReal deltaT;
+
+    //sponge layer
+    bool withSpongeLayer;
+    mu::Parser muSpongeLayer;
+
+    std::weak_ptr<Block3D> block;
+
+    int nx1, nx2, nx3;
+
+private:
+    friend class boost::serialization::access;
+    template<class Archive>
+    void serialize(Archive & ar, const unsigned int version)
+    {
+        ar & collFactor;
+        ar & ghostLayerWidth;
+        ar & compressible;
+        ar & withForcing;
+        //ar & withSpongeLayer;
+        ar & deltaT;
+        ar & dataSet;
+        ar & bcProcessor;
+        ar & ix1 & ix2 & ix3;
+        ar & nx1 & nx2 & nx3;
+    }
+
+    void checkFunction(mu::Parser fct);
+};
+
+#endif
diff --git a/source/VirtualFluidsCore/LBM/LBMUnitConverter.h b/source/VirtualFluidsCore/LBM/LBMUnitConverter.h
index 47de7303b..b393b6bda 100644
--- a/source/VirtualFluidsCore/LBM/LBMUnitConverter.h
+++ b/source/VirtualFluidsCore/LBM/LBMUnitConverter.h
@@ -29,7 +29,7 @@
 // LBMUnitConverter conv(, 100 /*L_World*/, LBMUnitConverter::WATER, 1000/*L_LB*/  );
 
 class LBMUnitConverter;
-typedef boost::shared_ptr<LBMUnitConverter> LBMUnitConverterPtr;
+typedef std::shared_ptr<LBMUnitConverter> LBMUnitConverterPtr;
 
 class LBMUnitConverter
 {
diff --git a/source/VirtualFluidsCore/LBM/VoidLBMKernel.cpp b/source/VirtualFluidsCore/LBM/VoidLBMKernel.cpp
index a8e479559..bfbbcf00d 100644
--- a/source/VirtualFluidsCore/LBM/VoidLBMKernel.cpp
+++ b/source/VirtualFluidsCore/LBM/VoidLBMKernel.cpp
@@ -1,5 +1,7 @@
 #include "VoidLBMKernel.h"
 #include "VoidData3D.h"
+#include "BCProcessor.h"
+#include "DataSet3D.h"
 
 VoidLBMKernel::VoidLBMKernel()
 {
@@ -41,7 +43,7 @@ void VoidLBMKernel::swapDistributions()
 
 }
 
-double VoidLBMKernel::getCallculationTime()
+double VoidLBMKernel::getCalculationTime()
 {
    return 0.0;
 }
diff --git a/source/VirtualFluidsCore/LBM/VoidLBMKernel.h b/source/VirtualFluidsCore/LBM/VoidLBMKernel.h
index ad5346555..1a5219085 100644
--- a/source/VirtualFluidsCore/LBM/VoidLBMKernel.h
+++ b/source/VirtualFluidsCore/LBM/VoidLBMKernel.h
@@ -12,7 +12,7 @@ public:
    LBMKernelPtr clone();
    void calculate();
    void swapDistributions();
-   double getCallculationTime();
+   double getCalculationTime();
 protected:
 private:
    int nx1, nx2, nx3;
diff --git a/source/VirtualFluidsCore/Parallel/BlocksDistributor.h b/source/VirtualFluidsCore/Parallel/BlocksDistributor.h
index 52063ff9b..85c2417b1 100644
--- a/source/VirtualFluidsCore/Parallel/BlocksDistributor.h
+++ b/source/VirtualFluidsCore/Parallel/BlocksDistributor.h
@@ -4,10 +4,10 @@
 #include "Communicator.h"
 #include "Grid3D.h"
 
-#include <boost/shared_ptr.hpp>
+#include <memory>
 
 class BlocksDistributor;
-typedef boost::shared_ptr<BlocksDistributor> BlocksDistributorPtr;
+typedef std::shared_ptr<BlocksDistributor> BlocksDistributorPtr;
 
 class BlocksDistributor
 {
diff --git a/source/VirtualFluidsCore/Parallel/Communicator.h b/source/VirtualFluidsCore/Parallel/Communicator.h
index f9ffbe626..49e075910 100644
--- a/source/VirtualFluidsCore/Parallel/Communicator.h
+++ b/source/VirtualFluidsCore/Parallel/Communicator.h
@@ -4,9 +4,9 @@
 #include <vector>
 #include <string>
 
-#include <boost/shared_ptr.hpp>
+#include <memory>
 class Communicator;
-typedef boost::shared_ptr<Communicator> CommunicatorPtr;
+typedef std::shared_ptr<Communicator> CommunicatorPtr;
 
 class Communicator
 {
diff --git a/source/VirtualFluidsCore/Parallel/LoadBalancer.cpp b/source/VirtualFluidsCore/Parallel/LoadBalancer.cpp
index 4b3f2049b..43600a588 100644
--- a/source/VirtualFluidsCore/Parallel/LoadBalancer.cpp
+++ b/source/VirtualFluidsCore/Parallel/LoadBalancer.cpp
@@ -1,7 +1,7 @@
 #if defined VF_MPI
 
 #include "LoadBalancer.h"
-#include <boost/foreach.hpp>
+
 #include <boost/archive/text_oarchive.hpp>
 #include <boost/archive/text_iarchive.hpp>
 #include <boost/algorithm/string.hpp>
@@ -57,7 +57,7 @@ void LoadBalancer::prepareToSendLoad()
    sendBuffer.clear();
    removeBlocksSend.resize(0);
    int conv = 1;
-   BOOST_FOREACH(NeighbourProcess neighbProzess, neighbourProcesses)
+   for(NeighbourProcess neighbProzess : neighbourProcesses)
    {
       if (this->load != neighbProzess.load)
       {
@@ -89,14 +89,14 @@ void LoadBalancer::prepareToSendLoad(const int& nProcessID, const double& transL
 
       std::string str_out;
 
-      BOOST_FOREACH(LoadBalancer::BBlocks::value_type b, boundaryBlocks)
+      for(LoadBalancer::BBlocks::value_type b : boundaryBlocks)
       {
          TransferBlock &tBlock = b.second;
          tBlocks.insert(std::make_pair(tBlock.weight, tBlock));
       }
 
       double lsum = 0;
-      BOOST_FOREACH(LoadBalancer::TBlocks::value_type t, tBlocks)
+      for(LoadBalancer::TBlocks::value_type t : tBlocks)
       {
          TransferBlock &tBlock = t.second;
          lsum += tBlock.load;
@@ -105,7 +105,7 @@ void LoadBalancer::prepareToSendLoad(const int& nProcessID, const double& transL
             break;
 
          sendBlocks.push_back(tBlock.block);
-         BOOST_FOREACH(BBlocksMap::value_type &bbm, neighboursMap)
+         for(BBlocksMap::value_type &bbm : neighboursMap)
             bbm.second.erase(tBlock.block);
 
          //if(lsum >= transLoad)
@@ -116,7 +116,7 @@ void LoadBalancer::prepareToSendLoad(const int& nProcessID, const double& transL
          boost::archive::text_oarchive oa(ss_out);
          oa.register_type<Block3D>();
 
-         BOOST_FOREACH(Block3DPtr b, sendBlocks)
+         for(Block3DPtr b : sendBlocks)
          {
             oa << b;
          }
@@ -128,7 +128,7 @@ void LoadBalancer::prepareToSendLoad(const int& nProcessID, const double& transL
          sbuf.comFlag = 1;
          sendBuffer.insert(std::make_pair(nProcessID, sbuf));
 
-         BOOST_FOREACH(Block3DPtr b, sendBlocks)
+         for(Block3DPtr b : sendBlocks)
          {
             b->deleteKernel();
             b->setRank(nProcessID);
@@ -155,9 +155,9 @@ void LoadBalancer::prepareToSendLoad(const int& nProcessID, const double& transL
 //////////////////////////////////////////////////////////////////////////
 void LoadBalancer::prepareToRecieveLoad()
 {
-   recieveBuffer.clear();
+   receiveBuffer.clear();
    int conv = 1;
-   BOOST_FOREACH(NeighbourProcess neighbProzess, neighbourProcesses)
+   for(NeighbourProcess neighbProzess : neighbourProcesses)
    {
       if (this->load != neighbProzess.load)
       {
@@ -170,7 +170,7 @@ void LoadBalancer::prepareToRecieveLoad()
                   UBLOG(logINFO,"rank = " << comm->getProcessID() << " : recieve Abweichung =  " << (static_cast<double>(neighbProzess.load)/static_cast<double>(this->load) - 1.0)*100.0);
                conv *= 0;
                TransferBuffer rbuf;
-               recieveBuffer.insert(std::make_pair(neighbProzess.processID, rbuf));
+               receiveBuffer.insert(std::make_pair(neighbProzess.processID, rbuf));
             }
          }
       }
@@ -183,7 +183,7 @@ void LoadBalancer::sendRecieveLoad()
    std::vector<MPI_Request> request;
    request.resize(0);
    int rcount = 0;
-   BOOST_FOREACH(TransferBufferMap::value_type &tb, recieveBuffer)
+   for(TransferBufferMap::value_type &tb : receiveBuffer)
    {
       int nProcessID = tb.first;
       TransferBuffer &rbuf = tb.second;
@@ -191,7 +191,7 @@ void LoadBalancer::sendRecieveLoad()
       MPI_Irecv(&rbuf.comFlag, 1, MPI_INT, nProcessID, 0, mpi_comm, &request[rcount]);
       rcount++;
    }
-   BOOST_FOREACH(TransferBufferMap::value_type &tb, sendBuffer)
+   for(TransferBufferMap::value_type &tb : sendBuffer)
    {
       int nProcessID = tb.first;
       TransferBuffer &sbuf = tb.second;
@@ -206,7 +206,7 @@ void LoadBalancer::sendRecieveLoad()
    //////////////////////////////////////////////////////////////////////////
    request.resize(0);
    rcount = 0;
-   BOOST_FOREACH(TransferBufferMap::value_type &tb, recieveBuffer)
+   for(TransferBufferMap::value_type &tb : receiveBuffer)
    {
       int nProcessID = tb.first;
       TransferBuffer &rbuf = tb.second;
@@ -217,7 +217,7 @@ void LoadBalancer::sendRecieveLoad()
          rcount++;
       }
    }
-   BOOST_FOREACH(TransferBufferMap::value_type &tb, sendBuffer)
+   for(TransferBufferMap::value_type &tb : sendBuffer)
    {
       int nProcessID = tb.first;
       TransferBuffer &sbuf = tb.second;
@@ -235,7 +235,7 @@ void LoadBalancer::sendRecieveLoad()
    //////////////////////////////////////////////////////////////////////////
    request.resize(0);
    rcount = 0;
-   BOOST_FOREACH(TransferBufferMap::value_type &tb, recieveBuffer)
+   for(TransferBufferMap::value_type &tb : receiveBuffer)
    {
       int nProcessID = tb.first;
       TransferBuffer &rbuf = tb.second;
@@ -246,7 +246,7 @@ void LoadBalancer::sendRecieveLoad()
          rcount++;
       }
    }
-   BOOST_FOREACH(TransferBufferMap::value_type &tb, sendBuffer)
+   for(TransferBufferMap::value_type &tb : sendBuffer)
    {
       int nProcessID = tb.first;
       TransferBuffer &sbuf = tb.second;
@@ -264,7 +264,7 @@ void LoadBalancer::sendRecieveLoad()
    //////////////////////////////////////////////////////////////////////////
    request.resize(0);
    rcount = 0;
-   BOOST_FOREACH(TransferBufferMap::value_type &tb, recieveBuffer)
+   for(TransferBufferMap::value_type &tb : receiveBuffer)
    {
       int nProcessID = tb.first;
       TransferBuffer &rbuf = tb.second;
@@ -276,7 +276,7 @@ void LoadBalancer::sendRecieveLoad()
          rcount++;
       }
    }
-   BOOST_FOREACH(TransferBufferMap::value_type &tb, sendBuffer)
+   for(TransferBufferMap::value_type &tb : sendBuffer)
    {
       int nProcessID = tb.first;
       TransferBuffer &sbuf = tb.second;
@@ -318,7 +318,7 @@ void LoadBalancer::sendRecieveChanges()
 //////////////////////////////////////////////////////////////////////////
 void LoadBalancer::saveRecievedLoad()
 {
-   BOOST_FOREACH(TransferBufferMap::value_type &tb, recieveBuffer)
+   for(TransferBufferMap::value_type &tb : receiveBuffer)
    {
       int nProcessID = tb.first;
       TransferBuffer &rbuf = tb.second;
@@ -347,7 +347,7 @@ void LoadBalancer::saveRecievedLoad()
 bool LoadBalancer::isConverged()
 {
    int conv = 1;
-   BOOST_FOREACH(int c, converged)
+   for(int c : converged)
       conv *= c;
    
    if(conv)
@@ -382,7 +382,7 @@ void LoadBalancer::collectData()
    {
       std::vector<Block3DPtr> blockVector;
       grid->getBlocks(level, gridRank, true, blockVector);
-      BOOST_FOREACH(Block3DPtr block, blockVector)
+      for(Block3DPtr block : blockVector)
       {
          if (block)
          {
@@ -404,7 +404,7 @@ void LoadBalancer::collectData()
             //search for child blocks
             std::vector<Block3DPtr> childBlocks;
             grid->getSubBlocks(block, 1, childBlocks);
-            BOOST_FOREACH(Block3DPtr b, childBlocks)
+            for(Block3DPtr b : childBlocks)
             {
                int childRank = b->getRank();
                if(childRank != blockRank && b->isActive())
@@ -437,7 +437,7 @@ void LoadBalancer::collectNeighboursLoad()
 {
    loadThreshold = 0;
    neighbourProcesses.resize(0);
-   BOOST_FOREACH(BBlocksMap::value_type b,  neighboursMap)
+   for(BBlocksMap::value_type b :  neighboursMap)
    {
       int neighbourProcessID = b.first;
       NeighbourProcess nProc;
@@ -452,7 +452,7 @@ void LoadBalancer::collectNeighboursLoad()
    request.resize(0);
    int rcount = 0;
 
-   BOOST_FOREACH(NeighbourProcess &np, neighbourProcesses)
+   for(NeighbourProcess &np : neighbourProcesses)
    {
       request.push_back(0);
       MPI_Irecv(&np.load, 1, MPI_DOUBLE, np.processID, 0, mpi_comm, &request[rcount]);
@@ -467,7 +467,7 @@ void LoadBalancer::collectNeighboursLoad()
    if(request.size() > 0)
       MPI_Waitall(static_cast<int>(request.size()), &request[0], MPI_STATUSES_IGNORE);
 
-   BOOST_FOREACH(NeighbourProcess &np, neighbourProcesses)
+   for(NeighbourProcess &np : neighbourProcesses)
    {
       loadThreshold += np.load;
       //std::cout<<"rank = " << comm->getProcessID() << " : neighbor process load =  " << np.load <<std::endl;
diff --git a/source/VirtualFluidsCore/Parallel/LoadBalancer.h b/source/VirtualFluidsCore/Parallel/LoadBalancer.h
index f77055488..ed2417658 100644
--- a/source/VirtualFluidsCore/Parallel/LoadBalancer.h
+++ b/source/VirtualFluidsCore/Parallel/LoadBalancer.h
@@ -9,6 +9,7 @@
 #include "Communicator.h"
 #include "MPICommunicator.h"
 #include "Grid3D.h"
+#include "LBMKernel.h"
 
 struct NeighbourProcess
 {
@@ -39,9 +40,9 @@ struct  TransferBlock
    Block3DPtr block;
 };
 
-#include <boost/smart_ptr.hpp>
+
 class LoadBalancer;
-typedef boost::shared_ptr<LoadBalancer> LoadBalancerPtr;
+typedef std::shared_ptr<LoadBalancer> LoadBalancerPtr;
 
 class LoadBalancer
 {
@@ -91,7 +92,7 @@ private:
    MPI_Comm mpi_comm;
 
    TransferBufferMap sendBuffer;
-   TransferBufferMap recieveBuffer;
+   TransferBufferMap receiveBuffer;
 
    std::vector<int> removeBlocksSend;
    
diff --git a/source/VirtualFluidsCore/Parallel/MPICommunicator.cpp b/source/VirtualFluidsCore/Parallel/MPICommunicator.cpp
index a4fcebd90..b837cca4c 100644
--- a/source/VirtualFluidsCore/Parallel/MPICommunicator.cpp
+++ b/source/VirtualFluidsCore/Parallel/MPICommunicator.cpp
@@ -2,7 +2,7 @@
 
 #include "MPICommunicator.h"
 #include <mpi.h>
-#include <boost/foreach.hpp>
+
 #include <sstream>
 using namespace std;
 //////////////////////////////////////////////////////////////////////////
diff --git a/source/VirtualFluidsCore/Parallel/MPICommunicator.h b/source/VirtualFluidsCore/Parallel/MPICommunicator.h
index c57e9a749..32dde5f82 100644
--- a/source/VirtualFluidsCore/Parallel/MPICommunicator.h
+++ b/source/VirtualFluidsCore/Parallel/MPICommunicator.h
@@ -6,13 +6,13 @@
 #include <mpi.h>
 #include <vector>
 #include <string>
-#include <boost/shared_ptr.hpp>
+#include <memory>
 #include <basics/utilities/UbException.h>
 #include <basics/utilities/UbLogger.h>
 #include "Communicator.h"
 
 class MPICommunicator;
-typedef boost::shared_ptr<MPICommunicator> MPICommunicatorPtr;
+typedef std::shared_ptr<MPICommunicator> MPICommunicatorPtr;
 
 //! \brief A class uses MPI library to communication.
 //! \details Support MPI communication. Implements singleton pattern.
diff --git a/source/VirtualFluidsCore/Parallel/MetisPartitioner.h b/source/VirtualFluidsCore/Parallel/MetisPartitioner.h
index a5e0f65f9..3ba7e42e5 100644
--- a/source/VirtualFluidsCore/Parallel/MetisPartitioner.h
+++ b/source/VirtualFluidsCore/Parallel/MetisPartitioner.h
@@ -13,12 +13,12 @@
 #include "metis.h"
 #include <vector>
 #include <string>
-#include <boost/shared_ptr.hpp>
+#include <memory>
 #include "basics/utilities/UbLogger.h"
 #include "basics/utilities/UbSystem.h"
 
 class MetisPartitioner;
-typedef boost::shared_ptr<MetisPartitioner> MetisPartitionerPtr;
+typedef std::shared_ptr<MetisPartitioner> MetisPartitionerPtr;
 
 class MetisPartitioner
 {
diff --git a/source/VirtualFluidsCore/Parallel/NullCommunicator.h b/source/VirtualFluidsCore/Parallel/NullCommunicator.h
index 9378f16cb..1e71ccb5c 100644
--- a/source/VirtualFluidsCore/Parallel/NullCommunicator.h
+++ b/source/VirtualFluidsCore/Parallel/NullCommunicator.h
@@ -3,10 +3,10 @@
 
 #include "Communicator.h"
 
-#include <boost/shared_ptr.hpp>
+#include <memory>
 
 class NullCommunicator;
-typedef boost::shared_ptr<NullCommunicator> NullCommunicatorPtr;
+typedef std::shared_ptr<NullCommunicator> NullCommunicatorPtr;
 
 class NullCommunicator : public Communicator
 {
diff --git a/source/VirtualFluidsCore/Parallel/PriorityQueueDecompositor.h b/source/VirtualFluidsCore/Parallel/PriorityQueueDecompositor.h
index 9b51c3116..67f1e52d4 100644
--- a/source/VirtualFluidsCore/Parallel/PriorityQueueDecompositor.h
+++ b/source/VirtualFluidsCore/Parallel/PriorityQueueDecompositor.h
@@ -1,68 +1,68 @@
-/**
-* @file PriorityQueueDecompositor.h
-* @brief Priority Queue for threads decomposition.
-* @author Kostyantyn Kucher
-* @date 06/06/2011
-*/
-#ifndef PRIORITYQUEUEDECOMPOSITOR_H
-#define PRIORITYQUEUEDECOMPOSITOR_H
-
-#include <algorithm>
-#include <vector>
-#include <map>
-
-struct sortMinMax {
-   bool operator() (int i,int j) { return (i<j);}
-};
-
-struct sortMaxMin {
-   bool operator() (int i,int j) { return (i>j);}
-};
-
-template <class T>
-class PriorityQueueDecompositor
-{
-public:
-   PriorityQueueDecompositor(const std::vector<T>& objcts, const std::vector<int>& weights, const int& numberOfParts)
-   {
-      for (int i = 0; i < (int)objcts.size(); i++)
-      {
-         objects.insert(std::pair<int, T>(weights[i], objcts[i]));
-      }
-      for (int i = 0; i < numberOfParts; i++)
-      {
-         std::vector<T> part;
-         parts.insert(std::pair<int,std::vector<T> >(0, part));
-      }
-   }
-   virtual ~PriorityQueueDecompositor()
-   {
-
-   }
-   void getDecomposition(std::vector< std::vector<T> >& prts)
-   {
-      for( itOb=objects.begin() ; itOb != objects.end(); itOb++)
-      {
-         itP = parts.begin();
-         int weight = (*itP).first;
-         std::vector<T> obj = (*itP).second;
-         parts.erase(itP);
-         weight += (*itOb).first;
-         obj.push_back((*itOb).second);
-         parts.insert(std::pair<int,std::vector<T> >(weight, obj));
-      }
-
-      for( itP=parts.begin() ; itP != parts.end(); itP++)
-      {
-         prts.push_back((*itP).second);
-      }
-   }
-protected:
-private:
-   std::multimap<int, T, sortMaxMin> objects;
-   typename std::multimap<int, T, sortMaxMin>::iterator itOb;
-   std::multimap<int, std::vector<T>, sortMinMax> parts;
-   typename std::multimap<int, std::vector<T>, sortMinMax>::iterator itP;
-};
-
-#endif
+/**
+* @file PriorityQueueDecompositor.h
+* @brief Priority Queue for threads decomposition.
+* @author Kostyantyn Kucher
+* @date 06/06/2011
+*/
+#ifndef PRIORITYQUEUEDECOMPOSITOR_H
+#define PRIORITYQUEUEDECOMPOSITOR_H
+
+#include <algorithm>
+#include <vector>
+#include <map>
+
+struct sortMinMax {
+   bool operator() (int i,int j) const { return (i<j);}
+};
+
+struct sortMaxMin {
+   bool operator() (int i,int j) const { return (i>j);}
+};
+
+template <class T>
+class PriorityQueueDecompositor
+{
+public:
+   PriorityQueueDecompositor(const std::vector<T>& objcts, const std::vector<int>& weights, const int& numberOfParts)
+   {
+      for (int i = 0; i < (int)objcts.size(); i++)
+      {
+         objects.insert(std::pair<int, T>(weights[i], objcts[i]));
+      }
+      for (int i = 0; i < numberOfParts; i++)
+      {
+         std::vector<T> part;
+         parts.insert(std::pair<int,std::vector<T> >(0, part));
+      }
+   }
+   virtual ~PriorityQueueDecompositor()
+   {
+
+   }
+   void getDecomposition(std::vector< std::vector<T> >& prts)
+   {
+      for( itOb=objects.begin() ; itOb != objects.end(); itOb++)
+      {
+         itP = parts.begin();
+         int weight = (*itP).first;
+         std::vector<T> obj = (*itP).second;
+         parts.erase(itP);
+         weight += (*itOb).first;
+         obj.push_back((*itOb).second);
+         parts.insert(std::pair<int,std::vector<T> >(weight, obj));
+      }
+
+      for( itP=parts.begin() ; itP != parts.end(); itP++)
+      {
+         prts.push_back((*itP).second);
+      }
+   }
+protected:
+private:
+   std::multimap<int, T, sortMaxMin> objects;
+   typename std::multimap<int, T, sortMaxMin>::iterator itOb;
+   std::multimap<int, std::vector<T>, sortMinMax> parts;
+   typename std::multimap<int, std::vector<T>, sortMinMax>::iterator itP;
+};
+
+#endif
diff --git a/source/VirtualFluidsCore/Parallel/Synchronizer.h b/source/VirtualFluidsCore/Parallel/Synchronizer.h
index ae12bc862..faee45128 100644
--- a/source/VirtualFluidsCore/Parallel/Synchronizer.h
+++ b/source/VirtualFluidsCore/Parallel/Synchronizer.h
@@ -1,14 +1,14 @@
 #ifndef SYNCHRONIZER_H
 #define SYNCHRONIZER_H
 
-#include <boost/shared_ptr.hpp>
+#include <memory>
 #include <boost/thread/thread.hpp>
 #include <boost/thread/mutex.hpp>
 #include <boost/thread/condition.hpp>
 
 
 class Synchronizer;
-typedef boost::shared_ptr<Synchronizer> SynchronizerPtr;
+typedef std::shared_ptr<Synchronizer> SynchronizerPtr;
 
 class Synchronizer
 {
diff --git a/source/VirtualFluidsCore/Utilities/ChangeRandomQs.hpp b/source/VirtualFluidsCore/Utilities/ChangeRandomQs.hpp
index 2596ee8aa..814e620c9 100644
--- a/source/VirtualFluidsCore/Utilities/ChangeRandomQs.hpp
+++ b/source/VirtualFluidsCore/Utilities/ChangeRandomQs.hpp
@@ -13,11 +13,11 @@ namespace Utilities
    {
       std::vector<IntegrateValuesHelper::CalcNodes> cnodes = integrateValues->getCNodes();
       
-      BOOST_FOREACH(IntegrateValuesHelper::CalcNodes cn, cnodes)
+      for(IntegrateValuesHelper::CalcNodes cn : cnodes)
       {
-         LBMKernelPtr kernel = cn.block->getKernel();
+         ILBMKernelPtr kernel = cn.block->getKernel();
          BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
-         BOOST_FOREACH(UbTupleInt3 node, cn.nodes)
+         for(UbTupleInt3 node : cn.nodes)
          {
             BoundaryConditionsPtr bc = bcArray->getBC(val<1>(node), val<2>(node), val<3>(node));
             if (bc)
diff --git a/source/VirtualFluidsCore/Utilities/ConfigurationFile.hpp b/source/VirtualFluidsCore/Utilities/ConfigurationFile.hpp
index 7231f601f..f75f2c2a0 100644
--- a/source/VirtualFluidsCore/Utilities/ConfigurationFile.hpp
+++ b/source/VirtualFluidsCore/Utilities/ConfigurationFile.hpp
@@ -1,5 +1,5 @@
-#ifndef ConfigurationFile_h__
-#define ConfigurationFile_h__
+#ifndef Configuration_h__
+#define Configuration_h__
 
 #include <map>
 #include <string>
@@ -206,7 +206,7 @@ std::vector<T> ConfigurationFile::getVector(const std::string& key) const
    std::vector<T> v;
    std::vector<std::string> strings;
    boost::algorithm::split(strings, str, boost::algorithm::is_any_of("\t\n\r;, "));
-   BOOST_FOREACH(std::string s, strings)
+   for(std::string s : strings)
    {
       if (s != "")
       {
diff --git a/source/VirtualFluidsCore/Utilities/MemoryUtil.h b/source/VirtualFluidsCore/Utilities/MemoryUtil.h
index c19d62e80..f94757aa7 100644
--- a/source/VirtualFluidsCore/Utilities/MemoryUtil.h
+++ b/source/VirtualFluidsCore/Utilities/MemoryUtil.h
@@ -1,110 +1,121 @@
-#ifndef _MEMORYUTIL_H_
-#define _MEMORYUTIL_H_
-
-#if defined(_WIN32) || defined(_WIN64)
-   #define MEMORYUTIL_WINDOWS
-   #include "windows.h"
-   #include "psapi.h"
-   #pragma comment(lib, "psapi.lib")
-#elif (defined(__amd64) || defined(__amd64__) || defined(__unix__) || defined(__CYGWIN__)) && !defined(__AIX__) 
-   #define MEMORYUTIL_LINUX
-   #include "sys/types.h"
-   #include "sys/sysinfo.h"
-   #include "stdlib.h"
-   #include "stdio.h"
-   #include "string.h"
-#else
-   #error "MemoryUtil::UnknownMachine"
-#endif
-//////////////////////////////////////////////////////////////////////////
-//MemoryUtil
-//////////////////////////////////////////////////////////////////////////
-namespace Utilities
-{
-//////////////////////////////////////////////////////////////////////////
-   static long long getTotalPhysMem()
-   {
-      #if defined MEMORYUTIL_WINDOWS
-         MEMORYSTATUSEX memInfo;
-         memInfo.dwLength = sizeof(MEMORYSTATUSEX);
-         GlobalMemoryStatusEx(&memInfo);
-         DWORDLONG totalPhysMem = memInfo.ullTotalPhys;            
-      #elif defined(MEMORYUTIL_LINUX)
-         struct sysinfo memInfo;
-         sysinfo (&memInfo);
-         long long totalPhysMem = memInfo.totalram;
-         //Multiply in next statement to avoid int overflow on right hand side...
-         totalPhysMem *= memInfo.mem_unit;
-      #else
-      #error "MemoryUtil::getTotalPhysMem - UnknownMachine"
-      #endif
-
-      return (long long)totalPhysMem;
-   }
-//////////////////////////////////////////////////////////////////////////
-   static long long getPhysMemUsed()
-   {
-      #if defined MEMORYUTIL_WINDOWS
-         MEMORYSTATUSEX memInfo;
-         memInfo.dwLength = sizeof(MEMORYSTATUSEX);
-         GlobalMemoryStatusEx(&memInfo);
-         DWORDLONG physMemUsed = memInfo.ullTotalPhys - memInfo.ullAvailPhys;          
-      #elif defined(MEMORYUTIL_LINUX)
-         struct sysinfo memInfo;
-         sysinfo (&memInfo);
-         long long physMemUsed = memInfo.totalram - memInfo.freeram;
-         //Multiply in next statement to avoid int overflow on right hand side...
-         physMemUsed *= memInfo.mem_unit;
-      #else
-      #error "MemoryUtil::getPhysMemUsed - UnknownMachine"
-      #endif
-
-      return (long long)physMemUsed;
-   }
-//////////////////////////////////////////////////////////////////////////
-#if defined(MEMORYUTIL_LINUX)
-   static int parseLine(char* line){
-      int i = strlen(line);
-      while (*line < '0' || *line > '9') line++;
-      line[i-3] = '\0';
-      i = atoi(line);
-      return i;
-   }
-
-   static int getValue(){ //Note: this value is in KB!
-      FILE* file = fopen("/proc/self/status", "r");
-      int result = -1;
-      char line[128];
-
-
-      while (fgets(line, 128, file) != NULL){
-         if (strncmp(line, "VmRSS:", 6) == 0){
-            result = parseLine(line);
-            break;
-         }
-      }
-      fclose(file);
-      return result;
-   }
-#endif
-//////////////////////////////////////////////////////////////////////////
-   static long long getPhysMemUsedByMe()
-   {
-      #if defined MEMORYUTIL_WINDOWS
-         PROCESS_MEMORY_COUNTERS pmc;
-         GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc));
-         SIZE_T physMemUsedByMe = pmc.WorkingSetSize;          
-      #elif defined(MEMORYUTIL_LINUX)
-         long long physMemUsedByMe = (long long)getValue() * (long long)1024;
-      #else
-         #error "MemoryUtil::getPhysMemUsedByMe - UnknownMachine"
-      #endif
-
-      return (long long)physMemUsedByMe;
-   }
-//////////////////////////////////////////////////////////////////////////
-
-}
-
-#endif
-
+#ifndef _MEMORYUTIL_H_
+#define _MEMORYUTIL_H_
+
+#if defined(_WIN32) || defined(_WIN64)
+   #define MEMORYUTIL_WINDOWS
+   #include "windows.h"
+   #include "psapi.h"
+   #pragma comment(lib, "psapi.lib")
+#elif defined __APPLE__
+#define MEMORYUTIL_APPLE
+   #include "sys/types.h"
+   #include "sys/sysctl.h"
+   #include "stdlib.h"
+   #include "stdio.h"
+   #include "string.h"
+#elif (defined(__amd64) || defined(__amd64__) || defined(__unix__) || defined(__CYGWIN__)) && !defined(__AIX__) 
+   #define MEMORYUTIL_LINUX
+   #include "sys/types.h"
+   #include "sys/sysinfo.h"
+   #include "stdlib.h"
+   #include "stdio.h"
+   #include "string.h"
+#else
+   #error "MemoryUtil::UnknownMachine"
+#endif
+//////////////////////////////////////////////////////////////////////////
+//MemoryUtil
+//////////////////////////////////////////////////////////////////////////
+namespace Utilities
+{
+//////////////////////////////////////////////////////////////////////////
+   static long long getTotalPhysMem()
+   {
+      #if defined MEMORYUTIL_WINDOWS
+         MEMORYSTATUSEX memInfo;
+         memInfo.dwLength = sizeof(MEMORYSTATUSEX);
+         GlobalMemoryStatusEx(&memInfo);
+         DWORDLONG totalPhysMem = memInfo.ullTotalPhys;            
+      #elif defined(MEMORYUTIL_LINUX)
+         struct sysinfo memInfo;
+         sysinfo (&memInfo);
+         long long totalPhysMem = memInfo.totalram;
+         //Multiply in next statement to avoid int overflow on right hand side...
+         totalPhysMem *= memInfo.mem_unit;
+    #elif defined(MEMORYUTIL_APPLE)
+    long long totalPhysMem = 0;
+      #else
+      #error "MemoryUtil::getTotalPhysMem - UnknownMachine"
+      #endif
+
+      return (long long)totalPhysMem;
+   }
+//////////////////////////////////////////////////////////////////////////
+   static long long getPhysMemUsed()
+   {
+      #if defined MEMORYUTIL_WINDOWS
+         MEMORYSTATUSEX memInfo;
+         memInfo.dwLength = sizeof(MEMORYSTATUSEX);
+         GlobalMemoryStatusEx(&memInfo);
+         DWORDLONG physMemUsed = memInfo.ullTotalPhys - memInfo.ullAvailPhys;          
+      #elif defined(MEMORYUTIL_LINUX)
+         struct sysinfo memInfo;
+         sysinfo (&memInfo);
+         long long physMemUsed = memInfo.totalram - memInfo.freeram;
+         //Multiply in next statement to avoid int overflow on right hand side...
+         physMemUsed *= memInfo.mem_unit;
+         #elif defined(MEMORYUTIL_APPLE)
+         long long physMemUsed = 0;
+      #else
+      #error "MemoryUtil::getPhysMemUsed - UnknownMachine"
+      #endif
+
+      return (long long)physMemUsed;
+   }
+//////////////////////////////////////////////////////////////////////////
+#if defined(MEMORYUTIL_LINUX) || defined(MEMORYUTIL_APPLE)
+   static int parseLine(char* line){
+      int i = strlen(line);
+      while (*line < '0' || *line > '9') line++;
+      line[i-3] = '\0';
+      i = atoi(line);
+      return i;
+   }
+
+   static int getValue(){ //Note: this value is in KB!
+      FILE* file = fopen("/proc/self/status", "r");
+      int result = -1;
+      char line[128];
+
+
+      while (fgets(line, 128, file) != NULL){
+         if (strncmp(line, "VmRSS:", 6) == 0){
+            result = parseLine(line);
+            break;
+         }
+      }
+      fclose(file);
+      return result;
+   }
+#endif
+//////////////////////////////////////////////////////////////////////////
+   static long long getPhysMemUsedByMe()
+   {
+      #if defined MEMORYUTIL_WINDOWS
+         PROCESS_MEMORY_COUNTERS pmc;
+         GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc));
+         SIZE_T physMemUsedByMe = pmc.WorkingSetSize;          
+      #elif defined(MEMORYUTIL_LINUX) || defined(MEMORYUTIL_APPLE)
+         long long physMemUsedByMe = (long long)getValue() * (long long)1024;
+      #else
+         #error "MemoryUtil::getPhysMemUsedByMe - UnknownMachine"
+      #endif
+
+      return (long long)physMemUsedByMe;
+   }
+//////////////////////////////////////////////////////////////////////////
+
+}
+
+#endif
+
diff --git a/source/VirtualFluidsCore/Utilities/StringUtil.hpp b/source/VirtualFluidsCore/Utilities/StringUtil.hpp
index 790e9d47f..08be63554 100644
--- a/source/VirtualFluidsCore/Utilities/StringUtil.hpp
+++ b/source/VirtualFluidsCore/Utilities/StringUtil.hpp
@@ -5,7 +5,7 @@
 #include <sstream>
 #include <iostream>
 #include <string>
-#include <boost/foreach.hpp>
+
 #include <boost/algorithm/string.hpp>
 
 template <class T>
@@ -271,7 +271,7 @@ public:
       std::vector<T> v;
       std::vector<std::string> strings;
       boost::algorithm::split(strings, s,  boost::algorithm::is_any_of("\t\n "));
-      BOOST_FOREACH(std::string s, strings){
+      for(std::string s : strings){
          if (s != "")
          {
             v.push_back(fromString<T>(s));
diff --git a/source/VirtualFluidsCore/Utilities/VoxelMatrixUtil.hpp b/source/VirtualFluidsCore/Utilities/VoxelMatrixUtil.hpp
index bb6597f95..84a8f225d 100644
--- a/source/VirtualFluidsCore/Utilities/VoxelMatrixUtil.hpp
+++ b/source/VirtualFluidsCore/Utilities/VoxelMatrixUtil.hpp
@@ -24,9 +24,9 @@ namespace Utilities
       GbCuboid3DPtr vmBox(new GbCuboid3D(matrix->getX1Minimum(), matrix->getX2Minimum(), matrix->getX3Minimum(), matrix->getX1Maximum(), matrix->getX2Maximum(), matrix->getX3Maximum()));
       if (myid == 0) GbSystem3D::writeGeoObject(vmBox.get(), pathname + "/geo/vmbox" + UbSystem::toString(fileCounter), WbWriterVtkXmlASCII::getInstance());
       D3Q27InteractorPtr vmBoxInt = D3Q27InteractorPtr(new D3Q27Interactor(vmBox, grid, noSlipPM, Interactor3D::SOLID));
-      SetSolidBlockVisitor v1(vmBoxInt, SetSolidBlockVisitor::SOLID);
+      SetSolidBlockVisitor v1(vmBoxInt, BlockType::SOLID);
       grid->accept(v1);
-      SetSolidBlockVisitor v2(vmBoxInt, SetSolidBlockVisitor::BC);
+      SetSolidBlockVisitor v2(vmBoxInt, BlockType::BC);
       grid->accept(v2);
 
       std::vector<Block3DPtr> blocks;
@@ -39,7 +39,7 @@ namespace Utilities
 
       if (myid == 0) UBLOG(logINFO, "number of blocks = " << blocks.size());
 
-      BOOST_FOREACH(Block3DPtr block, blocks)
+      for(Block3DPtr block : blocks)
       {
          block->setActive(true);
          vmInt->setDifferencesToGbObject3D(block);
diff --git a/source/VirtualFluidsCore/Visitors/Block3DVisitor.h b/source/VirtualFluidsCore/Visitors/Block3DVisitor.h
index 3460a9b2c..7d7234df9 100644
--- a/source/VirtualFluidsCore/Visitors/Block3DVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/Block3DVisitor.h
@@ -1,12 +1,13 @@
 #ifndef Block3DVisitor_h
 #define Block3DVisitor_h
 
-#include <boost/shared_ptr.hpp>
+#include <memory>
+
 class Block3DVisitor;
-typedef boost::shared_ptr<Block3DVisitor> Block3DVisitorPtr;
+typedef std::shared_ptr<Block3DVisitor> Block3DVisitorPtr;
 
-#include "Grid3D.h"
-#include "Block3D.h"
+class Block3D;
+class Grid3D;
 
 class Block3DVisitor
 {
@@ -23,7 +24,7 @@ public:
    {
    }
 	
-   virtual void visit(Grid3DPtr grid, Block3DPtr block)=0;
+   virtual void visit(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block) = 0;
    
    int  getStartLevel() const; 
    int  getStopLevel() const;
diff --git a/source/VirtualFluidsCore/Visitors/BoundaryConditionsBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/BoundaryConditionsBlockVisitor.cpp
index 59265a084..82e09a37d 100644
--- a/source/VirtualFluidsCore/Visitors/BoundaryConditionsBlockVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/BoundaryConditionsBlockVisitor.cpp
@@ -1,93 +1,98 @@
-#include "BoundaryConditionsBlockVisitor.h"
-#include "LBMKernel.h"
-#include "BCProcessor.h"
-#include "Grid3DSystem.h"
-#include "D3Q27EsoTwist3DSplittedVector.h"
-#include "ThinWallNoSlipBCAlgorithm.h"
-
-BoundaryConditionsBlockVisitor::BoundaryConditionsBlockVisitor() :
-Block3DVisitor(0, Grid3DSystem::MAXLEVEL)
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-BoundaryConditionsBlockVisitor::~BoundaryConditionsBlockVisitor()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-void BoundaryConditionsBlockVisitor::visit(Grid3DPtr grid, Block3DPtr block)
-{
-   if (block->getRank() == grid->getRank())
-   {
-      LBMKernelPtr kernel = block->getKernel();
-
-      if (!kernel)
-      {
-         throw UbException(UB_EXARGS, "LBMKernel in " + block->toString() + "is not exist!");
-      }
-
-      BCProcessorPtr bcProcessor = kernel->getBCProcessor();
-
-      if (!bcProcessor)
-      {
-         throw UbException(UB_EXARGS,"Boundary Conditions Processor is not exist!" );
-      }
-
-      BCArray3DPtr bcArray = bcProcessor->getBCArray();
-
-      bool compressible = kernel->getCompressible();
-      double collFactor = kernel->getCollisionFactor();
-      int level = block->getLevel();
-
-      int minX1 = 0;
-      int minX2 = 0;
-      int minX3 = 0;
-      int maxX1 = (int)bcArray->getNX1();
-      int maxX2 = (int)bcArray->getNX2();
-      int maxX3 = (int)bcArray->getNX3();
-      BoundaryConditionsPtr bcPtr;
-
-      bcProcessor->clearBC();
-
-      DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();
-
-      for (int x3 = minX3; x3 < maxX3; x3++)
-      {
-         for (int x2 = minX2; x2 < maxX2; x2++)
-         {
-            for (int x1 = minX1; x1 < maxX1; x1++)
-            {
-               if (!bcArray->isSolid(x1, x2, x3) && !bcArray->isUndefined(x1, x2, x3))
-               {
-                  if ((bcPtr = bcArray->getBC(x1, x2, x3)) != NULL)
-                  {
-                     char alg = bcPtr->getBcAlgorithmType();
-                     BCAlgorithmPtr bca = bcMap[alg];
-                     
-                     if (bca)
-                     {
-                        bca = bca->clone();
-                        bca->setNodeIndex(x1, x2, x3);
-                        bca->setBcPointer(bcPtr);
-                        bca->addDistributions(distributions);
-                        bca->setCollFactor(collFactor);
-                        bca->setCompressible(compressible);
-                        bca->setBcArray(bcArray);
-                        bcProcessor->addBC(bca);
-                     }
-                  }
-               }
-            }
-         }
-      }
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void BoundaryConditionsBlockVisitor::addBC(BCAdapterPtr bc)
-{
-   bcMap.insert(std::make_pair(bc->getBcAlgorithmType(), bc->getAlgorithm()));
-}
-
-
-
+#include "BoundaryConditionsBlockVisitor.h"
+#include "LBMKernel.h"
+#include "BCProcessor.h"
+#include "Grid3DSystem.h"
+#include "D3Q27EsoTwist3DSplittedVector.h"
+#include "ThinWallNoSlipBCAlgorithm.h"
+#include "DataSet3D.h"
+#include "Grid3D.h"
+#include "BCAdapter.h"
+#include "Block3D.h"
+#include "BCArray3D.h"
+
+BoundaryConditionsBlockVisitor::BoundaryConditionsBlockVisitor() :
+Block3DVisitor(0, Grid3DSystem::MAXLEVEL)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+BoundaryConditionsBlockVisitor::~BoundaryConditionsBlockVisitor()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void BoundaryConditionsBlockVisitor::visit(Grid3DPtr grid, Block3DPtr block)
+{
+   if (block->getRank() == grid->getRank())
+   {
+      ILBMKernelPtr kernel = block->getKernel();
+
+      if (!kernel)
+      {
+         throw UbException(UB_EXARGS, "LBMKernel in " + block->toString() + "is not exist!");
+      }
+
+      BCProcessorPtr bcProcessor = kernel->getBCProcessor();
+
+      if (!bcProcessor)
+      {
+         throw UbException(UB_EXARGS,"Boundary Conditions Processor is not exist!" );
+      }
+
+      BCArray3DPtr bcArray = bcProcessor->getBCArray();
+
+      bool compressible = kernel->getCompressible();
+      double collFactor = kernel->getCollisionFactor();
+      int level = block->getLevel();
+
+      int minX1 = 0;
+      int minX2 = 0;
+      int minX3 = 0;
+      int maxX1 = (int)bcArray->getNX1();
+      int maxX2 = (int)bcArray->getNX2();
+      int maxX3 = (int)bcArray->getNX3();
+      BoundaryConditionsPtr bcPtr;
+
+      bcProcessor->clearBC();
+
+      DistributionArray3DPtr distributions = kernel->getDataSet()->getFdistributions();
+
+      for (int x3 = minX3; x3 < maxX3; x3++)
+      {
+         for (int x2 = minX2; x2 < maxX2; x2++)
+         {
+            for (int x1 = minX1; x1 < maxX1; x1++)
+            {
+               if (!bcArray->isSolid(x1, x2, x3) && !bcArray->isUndefined(x1, x2, x3))
+               {
+                  if ((bcPtr = bcArray->getBC(x1, x2, x3)) != NULL)
+                  {
+                     char alg = bcPtr->getBcAlgorithmType();
+                     BCAlgorithmPtr bca = bcMap[alg];
+                     
+                     if (bca)
+                     {
+                        bca = bca->clone();
+                        bca->setNodeIndex(x1, x2, x3);
+                        bca->setBcPointer(bcPtr);
+                        bca->addDistributions(distributions);
+                        bca->setCollFactor(collFactor);
+                        bca->setCompressible(compressible);
+                        bca->setBcArray(bcArray);
+                        bcProcessor->addBC(bca);
+                     }
+                  }
+               }
+            }
+         }
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void BoundaryConditionsBlockVisitor::addBC(BCAdapterPtr bc)
+{
+   bcMap.insert(std::make_pair(bc->getBcAlgorithmType(), bc->getAlgorithm()));
+}
+
+
+
diff --git a/source/VirtualFluidsCore/Visitors/BoundaryConditionsBlockVisitor.h b/source/VirtualFluidsCore/Visitors/BoundaryConditionsBlockVisitor.h
index 160139467..8775df40e 100644
--- a/source/VirtualFluidsCore/Visitors/BoundaryConditionsBlockVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/BoundaryConditionsBlockVisitor.h
@@ -1,8 +1,16 @@
 #ifndef BoundaryConditionBlockVisitor_h__
 #define BoundaryConditionBlockVisitor_h__
 
+#include <map>
+#include <memory>
+
 #include "Block3DVisitor.h"
-#include "BCAdapter.h"
+
+
+class Grid3D;
+class Block3D;
+class BCAlgorithm;
+class BCAdapter;
 
 class BoundaryConditionsBlockVisitor : public Block3DVisitor
 {
@@ -10,10 +18,10 @@ public:
    BoundaryConditionsBlockVisitor();
    virtual ~BoundaryConditionsBlockVisitor();
    
-   void visit(Grid3DPtr grid, Block3DPtr block);
-   void addBC(BCAdapterPtr bc);
+      void visit(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block) override;
+   void addBC(std::shared_ptr<BCAdapter> bc);
 protected:
 private:
-   std::map<char, BCAlgorithmPtr> bcMap;
+   std::map<char, std::shared_ptr<BCAlgorithm> > bcMap;
 };
 #endif // BoundaryConditionBlockVisitor_h__
diff --git a/source/VirtualFluidsCore/Visitors/ChangeBoundaryDensityBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/ChangeBoundaryDensityBlockVisitor.cpp
index f7d61ba07..770364d98 100644
--- a/source/VirtualFluidsCore/Visitors/ChangeBoundaryDensityBlockVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/ChangeBoundaryDensityBlockVisitor.cpp
@@ -1,59 +1,62 @@
-#include "ChangeBoundaryDensityBlockVisitor.h"
-#include "LBMKernel.h"
-#include "Grid3DSystem.h"
-#include "BoundaryConditions.h"
-#include "BCProcessor.h"
-
-ChangeBoundaryDensityBlockVisitor::ChangeBoundaryDensityBlockVisitor(float oldBoundaryDensity, float newBoundaryDensity) :
-Block3DVisitor(0, Grid3DSystem::MAXLEVEL), 
-oldBoundaryDensity(oldBoundaryDensity), 
-newBoundaryDensity(newBoundaryDensity)
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-ChangeBoundaryDensityBlockVisitor::~ChangeBoundaryDensityBlockVisitor()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-void ChangeBoundaryDensityBlockVisitor::visit(Grid3DPtr grid, Block3DPtr block)
-{
-   if (block->getRank() == grid->getRank())
-   {
-      LBMKernelPtr kernel = block->getKernel();
-      BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
-
-      int minX1 = 0;
-      int minX2 = 0;
-      int minX3 = 0;
-      int maxX1 = (int)bcArray->getNX1();
-      int maxX2 = (int)bcArray->getNX2();
-      int maxX3 = (int)bcArray->getNX3();
-
-      for (int x3 = minX3; x3 < maxX3; x3++)
-      {
-         for (int x2 = minX2; x2 < maxX2; x2++)
-         {
-            for (int x1 = minX1; x1 < maxX1; x1++)
-            {
-               if (!bcArray->isSolid(x1, x2, x3) && !bcArray->isUndefined(x1, x2, x3))
-               {
-                  bcPtr = bcArray->getBC(x1, x2, x3);
-                  if (bcPtr)
-                  {
-                     if (bcPtr->hasDensityBoundary())
-                     {
-                        float bcDensity = bcPtr->getBoundaryDensity();
-                        if (bcDensity == oldBoundaryDensity)
-                        {
-                           bcPtr->setBoundaryDensity(newBoundaryDensity);
-                        }
-                     }
-                  }
-               }
-            }
-         }
-      }
-   }
-}
+#include "ChangeBoundaryDensityBlockVisitor.h"
+#include "LBMKernel.h"
+#include "Grid3DSystem.h"
+#include "BoundaryConditions.h"
+#include "BCProcessor.h"
+#include "Grid3D.h"
+#include "Block3D.h"
+#include "BCArray3D.h"
+
+ChangeBoundaryDensityBlockVisitor::ChangeBoundaryDensityBlockVisitor(float oldBoundaryDensity, float newBoundaryDensity) :
+Block3DVisitor(0, Grid3DSystem::MAXLEVEL), 
+oldBoundaryDensity(oldBoundaryDensity), 
+newBoundaryDensity(newBoundaryDensity)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+ChangeBoundaryDensityBlockVisitor::~ChangeBoundaryDensityBlockVisitor()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void ChangeBoundaryDensityBlockVisitor::visit(Grid3DPtr grid, Block3DPtr block)
+{
+   if (block->getRank() == grid->getRank())
+   {
+       ILBMKernelPtr kernel = block->getKernel();
+      BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
+
+      int minX1 = 0;
+      int minX2 = 0;
+      int minX3 = 0;
+      int maxX1 = (int)bcArray->getNX1();
+      int maxX2 = (int)bcArray->getNX2();
+      int maxX3 = (int)bcArray->getNX3();
+
+      for (int x3 = minX3; x3 < maxX3; x3++)
+      {
+         for (int x2 = minX2; x2 < maxX2; x2++)
+         {
+            for (int x1 = minX1; x1 < maxX1; x1++)
+            {
+               if (!bcArray->isSolid(x1, x2, x3) && !bcArray->isUndefined(x1, x2, x3))
+               {
+                  bcPtr = bcArray->getBC(x1, x2, x3);
+                  if (bcPtr)
+                  {
+                     if (bcPtr->hasDensityBoundary())
+                     {
+                        float bcDensity = bcPtr->getBoundaryDensity();
+                        if (bcDensity == oldBoundaryDensity)
+                        {
+                           bcPtr->setBoundaryDensity(newBoundaryDensity);
+                        }
+                     }
+                  }
+               }
+            }
+         }
+      }
+   }
+}
diff --git a/source/VirtualFluidsCore/Visitors/ChangeBoundaryDensityBlockVisitor.h b/source/VirtualFluidsCore/Visitors/ChangeBoundaryDensityBlockVisitor.h
index 06fff8280..082840a40 100644
--- a/source/VirtualFluidsCore/Visitors/ChangeBoundaryDensityBlockVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/ChangeBoundaryDensityBlockVisitor.h
@@ -1,19 +1,24 @@
 #ifndef ChangeBoundaryDensityBlockVisitor_h__
 #define ChangeBoundaryDensityBlockVisitor_h__
 
+#include <memory>
+
 #include "Block3DVisitor.h"
-#include "BoundaryConditions.h"
+
+class Block3D;
+class Grid3D;
+class BoundaryConditions;
 
 class ChangeBoundaryDensityBlockVisitor : public Block3DVisitor
 {
 public:
    ChangeBoundaryDensityBlockVisitor(float oldBoundaryDensity, float newBoundaryDensity);
    virtual ~ChangeBoundaryDensityBlockVisitor();
-   virtual void visit(Grid3DPtr grid, Block3DPtr block);
-protected:
+
+   void visit(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block) override;
 private:
    float oldBoundaryDensity; 
    float newBoundaryDensity;
-   BoundaryConditionsPtr bcPtr;
+   std::shared_ptr<BoundaryConditions> bcPtr;
 };
 #endif // ChangeBoundaryDensityBlockVisitor_h__
diff --git a/source/VirtualFluidsCore/Visitors/CheckRatioBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/CheckRatioBlockVisitor.cpp
index 06b3ba745..37d704811 100644
--- a/source/VirtualFluidsCore/Visitors/CheckRatioBlockVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/CheckRatioBlockVisitor.cpp
@@ -1,5 +1,7 @@
 #include "CheckRatioBlockVisitor.h"
 #include "Grid3DSystem.h"
+#include "Block3D.h"
+#include "Grid3D.h"
 
 CheckRatioBlockVisitor::CheckRatioBlockVisitor(int levelDepth/*shut be maxGridLevel*/, bool includeNotActiveBlocks)
    : Block3DVisitor(0, Grid3DSystem::MAXLEVEL)
diff --git a/source/VirtualFluidsCore/Visitors/CheckRatioBlockVisitor.h b/source/VirtualFluidsCore/Visitors/CheckRatioBlockVisitor.h
index eceb912f4..312e842fd 100644
--- a/source/VirtualFluidsCore/Visitors/CheckRatioBlockVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/CheckRatioBlockVisitor.h
@@ -1,8 +1,14 @@
 #ifndef CheckRatioBlockVisitor_H
 #define CheckRatioBlockVisitor_H
 
+#include <string>
+#include <memory>
+
 #include "Block3DVisitor.h"
 
+class Grid3D;
+class Block3D;
+
 class CheckRatioBlockVisitor : public Block3DVisitor
 {
 public:
@@ -14,15 +20,13 @@ public:
    void resetState();
    std::string getStateString();
 
-   void visit(Grid3DPtr grid, Block3DPtr block);
-
-protected:
+      void visit(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block) override;
 
 private:
    int  levelDepth;
    bool includeNotActiveBlocks;
    bool state;
-   Block3DPtr falseBlock;
+   std::shared_ptr<Block3D> falseBlock;
 };
 
 #endif //OverlapBlockVisitor_H
diff --git a/source/VirtualFluidsCore/Visitors/CoarsenCrossAndInsideGbObjectBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/CoarsenCrossAndInsideGbObjectBlockVisitor.cpp
index 4806e8dfe..6feee3f2a 100644
--- a/source/VirtualFluidsCore/Visitors/CoarsenCrossAndInsideGbObjectBlockVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/CoarsenCrossAndInsideGbObjectBlockVisitor.cpp
@@ -1,4 +1,7 @@
 #include "CoarsenCrossAndInsideGbObjectBlockVisitor.h"
+#include "Block3D.h"
+#include "Grid3D.h"
+#include <numerics/geometry3d/GbObject3D.h>
 
 CoarsenCrossAndInsideGbObjectBlockVisitor::CoarsenCrossAndInsideGbObjectBlockVisitor()
    : Block3DVisitor(), notActive(true)
diff --git a/source/VirtualFluidsCore/Visitors/CoarsenCrossAndInsideGbObjectBlockVisitor.h b/source/VirtualFluidsCore/Visitors/CoarsenCrossAndInsideGbObjectBlockVisitor.h
index 90ca0137a..8d67daec7 100644
--- a/source/VirtualFluidsCore/Visitors/CoarsenCrossAndInsideGbObjectBlockVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/CoarsenCrossAndInsideGbObjectBlockVisitor.h
@@ -1,8 +1,13 @@
 #ifndef CoarsenCrossAndInsideGbObjectBlockVisitor_H
 #define CoarsenCrossAndInsideGbObjectBlockVisitor_H
 
+#include <memory>
+
 #include "Block3DVisitor.h"
-#include <numerics/geometry3d/GbObject3D.h>
+
+class GbObject3D;
+class Block3D;
+class Grid3D;
 
 //! \brief Refine blocks on base of bounding box which is defined with <i>geoObject</i>
 //! \details The class uses a geometry object for define a bounding box. Inside and across this bounding box will be grid on block basis refinement.
@@ -15,12 +20,12 @@ public:
    //! A constructor
    //! \param geoObject a smart pointer to bounding box
    //! \param refineLevel an integer for refine on this level
-   CoarsenCrossAndInsideGbObjectBlockVisitor(GbObject3DPtr geoObject, int fineLevel, int coarseLevel);
+   CoarsenCrossAndInsideGbObjectBlockVisitor(std::shared_ptr<GbObject3D> geoObject, int fineLevel, int coarseLevel);
    virtual ~CoarsenCrossAndInsideGbObjectBlockVisitor();
-   void visit(Grid3DPtr grid, Block3DPtr block);
+      void visit(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block) override;
    //////////////////////////////////////////////////////////////////////////
 protected:
-   GbObject3DPtr geoObject;
+    std::shared_ptr<GbObject3D> geoObject;
    bool notActive;
    int coarseLevel;
 };
diff --git a/source/VirtualFluidsCore/Visitors/ConnectorBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/ConnectorBlockVisitor.cpp
index 658a46a52..2d849cd52 100644
--- a/source/VirtualFluidsCore/Visitors/ConnectorBlockVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/ConnectorBlockVisitor.cpp
@@ -1,5 +1,9 @@
 #include "ConnectorBlockVisitor.h"
 #include "Grid3DSystem.h"
+#include "ConnectorFactory.h"
+#include "InterpolationProcessor.h"
+#include "Communicator.h"
+#include "Grid3D.h"
 
 ConnectorBlockVisitor::ConnectorBlockVisitor(CommunicatorPtr comm, LBMReal nu, InterpolationProcessorPtr iProcessor, ConnectorFactoryPtr cFactory) :
    Block3DVisitor(0, Grid3DSystem::MAXLEVEL),
diff --git a/source/VirtualFluidsCore/Visitors/ConnectorBlockVisitor.h b/source/VirtualFluidsCore/Visitors/ConnectorBlockVisitor.h
index b49f148cd..f7a38b047 100644
--- a/source/VirtualFluidsCore/Visitors/ConnectorBlockVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/ConnectorBlockVisitor.h
@@ -1,26 +1,30 @@
 #ifndef ConnectorBlockVisitor_H
 #define ConnectorBlockVisitor_H
 
+#include <memory>
+
 #include "Block3DVisitor.h"
 #include "D3Q27System.h"
-#include "Communicator.h"
-#include "InterpolationProcessor.h"
 #include "CreateTransmittersHelper.h"
-#include "ConnectorFactory.h"
+
+class Grid3D;
+class Block3D;
+class InterpolationProcessor;
+class ConnectorFactory;
 
 class ConnectorBlockVisitor : public Block3DVisitor
 {
 public:
-   ConnectorBlockVisitor(CommunicatorPtr comm, LBMReal nu, InterpolationProcessorPtr iProcessor, ConnectorFactoryPtr cFactory);
+   ConnectorBlockVisitor(CommunicatorPtr comm, LBMReal nu, std::shared_ptr<InterpolationProcessor> iProcessor, std::shared_ptr<ConnectorFactory> cFactory);
    virtual ~ConnectorBlockVisitor();
-   void visit(Grid3DPtr grid, Block3DPtr block);
+      void visit(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block) override;
    //////////////////////////////////////////////////////////////////////////
 protected:
-   void setSameLevelConnectors(Grid3DPtr grid, Block3DPtr block);
-   void setRemoteConnectors(Block3DPtr sblock, Block3DPtr tblock, int dir);
-   void setInterpolationConnectors(Grid3DPtr grid, Block3DPtr block);
-   void setInterpolationConnectors(Block3DPtr fBlockSW, Block3DPtr fBlockSE, Block3DPtr fBlockNW, Block3DPtr fBlockNE, Block3DPtr cBlock, int dir);
-   void createTransmitters(Block3DPtr cBlock, Block3DPtr fBlock, int dir,
+   void setSameLevelConnectors(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block);
+   void setRemoteConnectors(std::shared_ptr<Block3D> sblock, std::shared_ptr<Block3D> tblock, int dir);
+   void setInterpolationConnectors(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block);
+   void setInterpolationConnectors(std::shared_ptr<Block3D> fBlockSW, std::shared_ptr<Block3D> fBlockSE, std::shared_ptr<Block3D> fBlockNW, std::shared_ptr<Block3D> fBlockNE, std::shared_ptr<Block3D> cBlock, int dir);
+   void createTransmitters(std::shared_ptr<Block3D> cBlock, std::shared_ptr<Block3D> fBlock, int dir,
       CreateTransmittersHelper::IBlock ib,
       CreateTransmittersHelper::TransmitterPtr& senderCF,
       CreateTransmittersHelper::TransmitterPtr& receiverCF,
@@ -29,8 +33,8 @@ protected:
    CommunicatorPtr comm;
    int gridRank;
    LBMReal nu;
-   InterpolationProcessorPtr iProcessor;
-   ConnectorFactoryPtr cFactory;
+   std::shared_ptr<InterpolationProcessor> iProcessor;
+   std::shared_ptr<ConnectorFactory> cFactory;
 };
 
 #endif //ConnectorBlockVisitor_H
diff --git a/source/VirtualFluidsCore/Visitors/CreateTransmittersHelper.h b/source/VirtualFluidsCore/Visitors/CreateTransmittersHelper.h
index ad02aa30a..c556c2b6f 100644
--- a/source/VirtualFluidsCore/Visitors/CreateTransmittersHelper.h
+++ b/source/VirtualFluidsCore/Visitors/CreateTransmittersHelper.h
@@ -4,6 +4,8 @@
 #include "Block3D.h"
 #include "Communicator.h"
 
+#include "LBMSystem.h"
+
 #include <basics/transmitter/TbTransmitter.h>
 #include <basics/transmitter/TbTransmitterMpiPool.h>
 #include <basics/container/CbVector.h>
@@ -20,7 +22,7 @@ public:
    enum TransmitterType {MPI, BOND, MPI2BOND};
 public:
    typedef CbVector <LBMReal> DataType;
-   typedef boost::shared_ptr< TbTransmitter< DataType > > TransmitterPtr;
+   typedef std::shared_ptr< TbTransmitter< DataType > > TransmitterPtr;
 public:
    CreateTransmittersHelper();
    void createTransmitters(const Block3DPtr sblock, const Block3DPtr tblock, int dir, IBlock ib,
diff --git a/source/VirtualFluidsCore/Visitors/GenBlocksGridVisitor.cpp b/source/VirtualFluidsCore/Visitors/GenBlocksGridVisitor.cpp
index 20df4e0ba..ecbb8462c 100644
--- a/source/VirtualFluidsCore/Visitors/GenBlocksGridVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/GenBlocksGridVisitor.cpp
@@ -1,89 +1,70 @@
-#include "GenBlocksGridVisitor.h"
-#include "Grid3DSystem.h"
-#include <boost/foreach.hpp>
-
-
-GenBlocksGridVisitor::GenBlocksGridVisitor(GbObject3DPtr boundingBox) :
-   boundingBox(boundingBox)
-{
-
-}
-
-//////////////////////////////////////////////////////////////////////////
-void GenBlocksGridVisitor::visit(const Grid3DPtr grid)
-{
-   double orgX1 = boundingBox->getX1Minimum();
-   double orgX2 = boundingBox->getX2Minimum();
-   double orgX3 = boundingBox->getX3Minimum();
-
-   double dx = grid->getDeltaX(0);
-
-   UbTupleInt3 blockNX = grid->getBlockNX();
-
-   double blockLentghX1 = (double)val<1>(blockNX)*dx;
-   double blockLentghX2 = (double)val<2>(blockNX)*dx;
-   double blockLentghX3 = (double)val<3>(blockNX)*dx;
-
-   CoordinateTransformation3DPtr trafo(new CoordinateTransformation3D(orgX1, orgX2, orgX3, blockLentghX1, blockLentghX2, blockLentghX3));
-   grid->setCoordinateTransformator(trafo);
-
-   genBlocks(grid);
-}
-//////////////////////////////////////////////////////////////////////////
-void GenBlocksGridVisitor::fillExtentWithBlocks(Grid3DPtr grid)
-{
-   for (int x3 = val<3>(minInd); x3 < val<3>(maxInd); x3++)
-   {
-      for (int x2 = val<2>(minInd); x2 < val<2>(maxInd); x2++)
-      {
-         for (int x1 = val<1>(minInd); x1 < val<1>(maxInd); x1++)
-         {
-            Block3DPtr block(new Block3D(x1, x2, x3, 0));
-            grid->addBlock(block);
-         }
-      }
-   }
-
-   //double dx = grid->getDeltaX(0);
-   //UbTupleInt3 blockNX = grid->getBlockNX();
-   //int maxIX1 = ceil(boundingBox->getX1Maximum() / ((double)val<1>(blockNX)*dx));
-   //int maxIX2 = ceil(boundingBox->getX2Maximum() / ((double)val<2>(blockNX)*dx));
-   //int maxIX3 = ceil(boundingBox->getX3Maximum() / ((double)val<3>(blockNX)*dx));
-
-   //for (int x3 = 0; x3 < maxIX1; x3++)
-   //{
-   //   for (int x2 = 0; x2 < maxIX2; x2++)
-   //   {
-   //      for (int x1 = 0; x1 < maxIX3; x1++)
-   //      {
-   //         Block3DPtr block(new Block3D(x1, x2, x3, 0));
-   //         grid->addBlock(block);
-   //      }
-   //   }
-   //}
-}
-//////////////////////////////////////////////////////////////////////////
-void GenBlocksGridVisitor::genBlocks(Grid3DPtr grid)
-{
-   minInd = grid->getBlockIndexes(boundingBox->getX1Minimum(), boundingBox->getX2Minimum(), boundingBox->getX3Minimum());
-   double geoMaxX1 = boundingBox->getX1Maximum();
-   double geoMaxX2 = boundingBox->getX2Maximum();
-   double geoMaxX3 = boundingBox->getX3Maximum();
-   maxInd = grid->getBlockIndexes(geoMaxX1, geoMaxX2, geoMaxX3);
-
-   UbTupleDouble3 blockCoord = grid->getBlockWorldCoordinates(static_cast<int>(val<1>(maxInd)), static_cast<int>(val<2>(maxInd)), static_cast<int>(val<3>(maxInd)), 0);
-   double dx = grid->getDeltaX(0);
-   if (fabs(geoMaxX1-val<1>(blockCoord)) > dx)
-      val<1>(maxInd) += 1;
-   if (fabs(geoMaxX2-val<2>(blockCoord)) > dx)
-      val<2>(maxInd) += 1;
-   if (fabs(geoMaxX3-val<3>(blockCoord)) > dx)
-      val<3>(maxInd) += 1;
-
-   this->fillExtentWithBlocks(grid);
-
-   grid->setNX1(val<1>(maxInd));
-   grid->setNX2(val<2>(maxInd));
-   grid->setNX3(val<3>(maxInd));
-}
-
+#include "GenBlocksGridVisitor.h"
+#include "Grid3DSystem.h"
+#include "CoordinateTransformation3D.h"
+#include "Block3D.h"
+#include "Grid3D.h"
+
+#include <numerics/geometry3d/GbObject3D.h>
+
+GenBlocksGridVisitor::GenBlocksGridVisitor(GbObject3DPtr boundingBox) :
+   boundingBox(boundingBox)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void GenBlocksGridVisitor::visit(const Grid3DPtr grid)
+{
+    double orgX1 = boundingBox->getX1Minimum();
+    double orgX2 = boundingBox->getX2Minimum();
+    double orgX3 = boundingBox->getX3Minimum();
+
+    double dx = grid->getDeltaX(0);
+
+    UbTupleInt3 blockNX = grid->getBlockNX();
+
+    double blockLentghX1 = (double)val<1>(blockNX)*dx;
+    double blockLentghX2 = (double)val<2>(blockNX)*dx;
+    double blockLentghX3 = (double)val<3>(blockNX)*dx;
+
+    CoordinateTransformation3DPtr trafo(new CoordinateTransformation3D(orgX1, orgX2, orgX3, blockLentghX1, blockLentghX2, blockLentghX3));
+    grid->setCoordinateTransformator(trafo);
+
+    genBlocks(grid);
+}
+//////////////////////////////////////////////////////////////////////////
+void GenBlocksGridVisitor::fillExtentWithBlocks( Grid3DPtr grid )
+{
+   for(int x3 =  val<3>(minInd); x3 <  val<3>(maxInd); x3++)
+   {
+      for(int x2 =  val<2>(minInd); x2 <  val<2>(maxInd); x2++)
+      {
+         for(int x1 =  val<1>(minInd); x1 <  val<1>(maxInd); x1++)
+         {
+            Block3DPtr block( new Block3D(x1,x2,x3,0) );
+            grid->addBlock(block);
+         }
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void GenBlocksGridVisitor::genBlocks(Grid3DPtr grid)
+{
+    minInd = grid->getBlockIndexes(boundingBox->getX1Minimum(), boundingBox->getX2Minimum(), boundingBox->getX3Minimum());
+    double geoMaxX1 = boundingBox->getX1Maximum();
+    double geoMaxX2 = boundingBox->getX2Maximum();
+    double geoMaxX3 = boundingBox->getX3Maximum();
+    maxInd = grid->getBlockIndexes(geoMaxX1, geoMaxX2, geoMaxX3);
+    UbTupleDouble3 blockCoord = grid->getBlockWorldCoordinates(static_cast<int>(val<1>(maxInd)), static_cast<int>(val<2>(maxInd)), static_cast<int>(val<3>(maxInd)), 0);
+    if (geoMaxX1 > val<1>(blockCoord))
+        val<1>(maxInd) += 1;
+    if (geoMaxX2 > val<2>(blockCoord))
+        val<2>(maxInd) += 1;
+    if (geoMaxX3 > val<3>(blockCoord))
+        val<3>(maxInd) += 1;
+
+    this->fillExtentWithBlocks(grid);
+
+    grid->setNX1(val<1>(maxInd));
+    grid->setNX2(val<2>(maxInd));
+    grid->setNX3(val<3>(maxInd));
+}
diff --git a/source/VirtualFluidsCore/Visitors/GenBlocksGridVisitor.h b/source/VirtualFluidsCore/Visitors/GenBlocksGridVisitor.h
index 59aeace85..bebfcba6c 100644
--- a/source/VirtualFluidsCore/Visitors/GenBlocksGridVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/GenBlocksGridVisitor.h
@@ -1,22 +1,28 @@
-#ifndef GenBlocksGridVisitor_h
-#define GenBlocksGridVisitor_h
-
-#include "Grid3DVisitor.h" 
-#include <numerics/geometry3d/GbObject3D.h>
-
-class GenBlocksGridVisitor : public Grid3DVisitor
-{
-public:
-   GenBlocksGridVisitor(GbObject3DPtr boundingBox);
-   virtual ~GenBlocksGridVisitor(){}
-
-   void visit(Grid3DPtr grid);
-
-private:
-   UbTupleInt3 minInd, maxInd;
-   GbObject3DPtr boundingBox;
-   void fillExtentWithBlocks(Grid3DPtr grid);
-   void genBlocks(Grid3DPtr grid);
-};
-
-#endif 
+#ifndef GenBlocksGridVisitor_h
+#define GenBlocksGridVisitor_h
+
+#include <memory>
+
+#include <basics/utilities/UbTuple.h>
+
+#include "Grid3DVisitor.h" 
+
+class GbObject3D;
+class Grid3D;
+
+class GenBlocksGridVisitor : public Grid3DVisitor
+{
+public:
+   GenBlocksGridVisitor(std::shared_ptr<GbObject3D> boundingBox);
+   virtual ~GenBlocksGridVisitor(){}
+
+   void visit(std::shared_ptr<Grid3D> grid);
+
+private:
+   UbTupleInt3 minInd, maxInd;
+   std::shared_ptr<GbObject3D> boundingBox;
+   void fillExtentWithBlocks(std::shared_ptr<Grid3D> grid);
+   void genBlocks(std::shared_ptr<Grid3D> grid);
+};
+
+#endif 
diff --git a/source/VirtualFluidsCore/Visitors/Grid3DVisitor.h b/source/VirtualFluidsCore/Visitors/Grid3DVisitor.h
index 7e576074f..8e43bdfa4 100644
--- a/source/VirtualFluidsCore/Visitors/Grid3DVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/Grid3DVisitor.h
@@ -1,11 +1,12 @@
 #ifndef Grid3DVisitor_h
 #define Grid3DVisitor_h
 
-#include <boost/shared_ptr.hpp>
+#include <memory>
+
 class Grid3DVisitor;
-typedef boost::shared_ptr<Grid3DVisitor> Grid3DVisitorPtr;
+typedef std::shared_ptr<Grid3DVisitor> Grid3DVisitorPtr;
 
-#include "Grid3D.h" 
+class Grid3D;
 
 class Grid3DVisitor
 {
@@ -13,7 +14,7 @@ public:
    Grid3DVisitor() {}
    virtual ~Grid3DVisitor() {}
 
-   virtual void visit(Grid3DPtr grid)=0;
+   virtual void visit(std::shared_ptr<Grid3D> grid) = 0;
 };
 
 #endif 
diff --git a/source/VirtualFluidsCore/Visitors/InitDistributionsBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/InitDistributionsBlockVisitor.cpp
index c4d6b47a4..98fbd21c2 100644
--- a/source/VirtualFluidsCore/Visitors/InitDistributionsBlockVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/InitDistributionsBlockVisitor.cpp
@@ -1,311 +1,316 @@
-#include "InitDistributionsBlockVisitor.h"
-#include "LBMKernel.h"
-#include "BCProcessor.h"
-#include "Grid3DSystem.h"
-
-InitDistributionsBlockVisitor::InitDistributionsBlockVisitor() 
-   : Block3DVisitor(0, Grid3DSystem::MAXLEVEL)
-{
-   this->setVx1(0.0);
-   this->setVx2(0.0);
-   this->setVx3(0.0);
-   this->setRho(0.0);
-}
-//////////////////////////////////////////////////////////////////////////
-//D3Q27ETInitDistributionsBlockVisitor::D3Q27ETInitDistributionsBlockVisitor(LBMReal rho, LBMReal vx1, LBMReal vx2, LBMReal vx3)
-//   : Block3DVisitor(0, Grid3DSystem::MAXLEVEL)
-//{
-//   this->setVx1(vx1);
-//   this->setVx2(vx2);
-//   this->setVx3(vx3);
-//   this->setRho(rho);
-//}
-//////////////////////////////////////////////////////////////////////////
-InitDistributionsBlockVisitor::InitDistributionsBlockVisitor( LBMReal nu, LBMReal rho, LBMReal vx1, LBMReal vx2, LBMReal vx3)
-   : Block3DVisitor(0, Grid3DSystem::MAXLEVEL)
-{
-   this->setVx1(vx1);
-   this->setVx2(vx2);
-   this->setVx3(vx3);
-   this->setRho(rho);
-   this->setNu(nu);
-}
-//////////////////////////////////////////////////////////////////////////
-void InitDistributionsBlockVisitor::setVx1( const mu::Parser& parser)  
-{ 
-   this->checkFunction(parser); 
-   this->muVx1 = parser;  
-}
-//////////////////////////////////////////////////////////////////////////
-void InitDistributionsBlockVisitor::setVx2( const mu::Parser& parser)
-{ 
-   this->checkFunction(parser); 
-   this->muVx2 = parser;  
-}
-//////////////////////////////////////////////////////////////////////////
-void InitDistributionsBlockVisitor::setVx3( const mu::Parser& parser)  
-{ 
-   this->checkFunction(parser); 
-   this->muVx3 = parser;  
-}
-//////////////////////////////////////////////////////////////////////////
-void InitDistributionsBlockVisitor::setRho( const mu::Parser& parser)  
-{ 
-   this->checkFunction(parser); 
-   this->muRho = parser;  
-}
-//////////////////////////////////////////////////////////////////////////
-void InitDistributionsBlockVisitor::setVx1( const std::string& muParserString)  
-{ 
-   this->muVx1.SetExpr(muParserString); 
-   this->checkFunction(muVx1); 
-}
-//////////////////////////////////////////////////////////////////////////
-void InitDistributionsBlockVisitor::setVx2( const std::string& muParserString) 
-{ 
-   this->muVx2.SetExpr(muParserString); 
-   this->checkFunction(muVx2); 
-}
-//////////////////////////////////////////////////////////////////////////
-void InitDistributionsBlockVisitor::setVx3( const std::string& muParserString)  
-{ 
-   this->muVx3.SetExpr(muParserString); 
-   this->checkFunction(muVx3); 
-}
-//////////////////////////////////////////////////////////////////////////
-void InitDistributionsBlockVisitor::setRho( const std::string& muParserString)  
-{ 
-   this->muRho.SetExpr(muParserString); 
-   this->checkFunction(muRho); 
-}
-//////////////////////////////////////////////////////////////////////////
-void InitDistributionsBlockVisitor::setVx1( LBMReal vx1 ) 
-{ 
-   this->muVx1.SetExpr( UbSystem::toString(vx1,D3Q27RealLim::digits10) );  
-   this->checkFunction(muVx1); 
-}
-//////////////////////////////////////////////////////////////////////////
-void InitDistributionsBlockVisitor::setVx2( LBMReal vx2 ) 
-{ 
-   this->muVx2.SetExpr( UbSystem::toString(vx2,D3Q27RealLim::digits10) );  
-   this->checkFunction(muVx2); 
-}
-//////////////////////////////////////////////////////////////////////////
-void InitDistributionsBlockVisitor::setVx3( LBMReal vx3 ) 
-{ 
-   this->muVx3.SetExpr( UbSystem::toString(vx3,D3Q27RealLim::digits10) );  
-   this->checkFunction(muVx3); 
-}
-//////////////////////////////////////////////////////////////////////////
-void InitDistributionsBlockVisitor::setRho( LBMReal rho ) 
-{ 
-   this->muRho.SetExpr( UbSystem::toString(rho,D3Q27RealLim::digits10) );  
-   this->checkFunction(muRho); 
-}
-//////////////////////////////////////////////////////////////////////////
-void InitDistributionsBlockVisitor::visit(const Grid3DPtr grid, Block3DPtr block) 
-{
-   using namespace D3Q27System;
-
-   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());
-   
-
-   //define vars for functions
-   mu::value_type x1,x2,x3;
-   this->muVx1.DefineVar("x1",&x1); this->muVx1.DefineVar("x2",&x2); this->muVx1.DefineVar("x3",&x3);
-   this->muVx2.DefineVar("x1",&x1); this->muVx2.DefineVar("x2",&x2); this->muVx2.DefineVar("x3",&x3);
-   this->muVx3.DefineVar("x1",&x1); this->muVx3.DefineVar("x2",&x2); this->muVx3.DefineVar("x3",&x3);
-   this->muRho.DefineVar("x1",&x1); this->muRho.DefineVar("x2",&x2); this->muRho.DefineVar("x3",&x3);
-
-   //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())
-   {
-      LBMKernelPtr 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);
-
-      BCArray3DPtr bcArray = 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();
-
-      for(int ix3=0; ix3<bcArray->getNX3(); ix3++)
-         for(int ix2=0; ix2<bcArray->getNX2(); ix2++)
-            for(int ix1=0; ix1<bcArray->getNX1(); ix1++)
-            {
-               UbTupleDouble3 coords = grid->getNodeCoordinates(block, ix1, ix2, ix3);
-               x1 = val<1>(coords);
-               x2 = val<2>(coords);
-               x3 = val<3>(coords);
-
-               vx1 = muVx1.Eval();
-               vx2 = muVx2.Eval();
-               vx3 = muVx3.Eval();
-               rho = muRho.Eval();
-
-               //x-derivative
-               double deltaX=dx*0.5;
-               x1 = val<1>(coords)+deltaX;
-               double vx1Plusx1 = muVx1.Eval();
-               double vx2Plusx1 = muVx2.Eval();
-               double vx3Plusx1 = muVx3.Eval();
-
-               x1 = val<1>(coords)-deltaX;
-               double vx1Minusx1 = muVx1.Eval();
-               double vx2Minusx1 = muVx2.Eval();
-               double vx3Minusx1 = muVx3.Eval();
-
-               //y-derivative
-               x1 = val<1>(coords);
-               x2 = val<2>(coords)+deltaX;
-               double vx1Plusx2 = muVx1.Eval();
-               double vx2Plusx2 = muVx2.Eval();
-               double vx3Plusx2 = muVx3.Eval();
-
-               x2 = val<2>(coords)-deltaX;
-               double vx1Minusx2 = muVx1.Eval();
-               double vx2Minusx2 = muVx2.Eval();
-               double vx3Minusx2 = muVx3.Eval();
-
-               //z-derivative
-               x2 = val<2>(coords);
-               x3 = val<3>(coords)+deltaX;
-               double vx1Plusx3 = muVx1.Eval();
-               double vx2Plusx3 = muVx2.Eval();
-               double vx3Plusx3 = muVx3.Eval();
-
-               x3 = val<3>(coords)-deltaX;
-               double vx1Minusx3 = muVx1.Eval();
-               double vx2Minusx3 = muVx2.Eval();
-               double vx3Minusx3 = muVx3.Eval();
-
-               double ax=(vx1Plusx1-vx1Minusx1)/(2.0*deltaX)*dx;
-               double bx=(vx2Plusx1-vx2Minusx1)/(2.0*deltaX)*dx;
-               double cx=(vx3Plusx1-vx3Minusx1)/(2.0*deltaX)*dx;
-
-               double ay=(vx1Plusx2-vx1Minusx2)/(2.0*deltaX)*dx;
-               double by=(vx2Plusx2-vx2Minusx2)/(2.0*deltaX)*dx;
-               double cy=(vx3Plusx2-vx3Minusx2)/(2.0*deltaX)*dx;
-
-               double az=(vx1Plusx3-vx1Minusx3)/(2.0*deltaX)*dx;
-               double bz=(vx2Plusx3-vx2Minusx3)/(2.0*deltaX)*dx;
-               double cz=(vx3Plusx3-vx3Minusx3)/(2.0*deltaX)*dx;
-               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];
-
-               //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();
-
-            }
-   }
-
-   //variablen der functions loeschen, da die verwiesenen Objecte nach dem verlassen des scopes ungueltig sind!
-   this->muVx1.ClearVar();
-   this->muVx2.ClearVar();
-   this->muVx3.ClearVar();
-   this->muRho.ClearVar();
-
-}
-//////////////////////////////////////////////////////////////////////////
-void InitDistributionsBlockVisitor::checkFunction(mu::Parser fct)
-{
-   double x1=1.0,x2=1.0,x3=1.0;
-   fct.DefineVar("x1",&x1); 
-   fct.DefineVar("x2",&x2); 
-   fct.DefineVar("x3",&x3);
-
-   try
-   {
-      fct.Eval();
-      fct.ClearVar();
-   }
-   catch(mu::ParserError& e)
-   {
-      throw UbException(UB_EXARGS,"function: "+e.GetExpr() + (std::string)"error: "+e.GetMsg()
-         +(std::string)", only x1,x2,x3 are allowed as variables" );
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void InitDistributionsBlockVisitor::setNu( LBMReal nu )
-{
-   this->nu = nu;
-}
-
+#include "InitDistributionsBlockVisitor.h"
+#include "LBMKernel.h"
+#include "BCProcessor.h"
+#include "Grid3DSystem.h"
+#include "DataSet3D.h"
+#include "EsoTwist3D.h"
+#include "Grid3D.h"
+#include "Block3D.h"
+#include "BCArray3D.h"
+
+InitDistributionsBlockVisitor::InitDistributionsBlockVisitor() 
+   : Block3DVisitor(0, Grid3DSystem::MAXLEVEL)
+{
+   this->setVx1(0.0);
+   this->setVx2(0.0);
+   this->setVx3(0.0);
+   this->setRho(0.0);
+}
+//////////////////////////////////////////////////////////////////////////
+//D3Q27ETInitDistributionsBlockVisitor::D3Q27ETInitDistributionsBlockVisitor(LBMReal rho, LBMReal vx1, LBMReal vx2, LBMReal vx3)
+//   : Block3DVisitor(0, Grid3DSystem::MAXLEVEL)
+//{
+//   this->setVx1(vx1);
+//   this->setVx2(vx2);
+//   this->setVx3(vx3);
+//   this->setRho(rho);
+//}
+//////////////////////////////////////////////////////////////////////////
+InitDistributionsBlockVisitor::InitDistributionsBlockVisitor( LBMReal nu, LBMReal rho, LBMReal vx1, LBMReal vx2, LBMReal vx3)
+   : Block3DVisitor(0, Grid3DSystem::MAXLEVEL)
+{
+   this->setVx1(vx1);
+   this->setVx2(vx2);
+   this->setVx3(vx3);
+   this->setRho(rho);
+   this->setNu(nu);
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setVx1( const mu::Parser& parser)  
+{ 
+   this->checkFunction(parser); 
+   this->muVx1 = parser;  
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setVx2( const mu::Parser& parser)
+{ 
+   this->checkFunction(parser); 
+   this->muVx2 = parser;  
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setVx3( const mu::Parser& parser)  
+{ 
+   this->checkFunction(parser); 
+   this->muVx3 = parser;  
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setRho( const mu::Parser& parser)  
+{ 
+   this->checkFunction(parser); 
+   this->muRho = parser;  
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setVx1( const std::string& muParserString)  
+{ 
+   this->muVx1.SetExpr(muParserString); 
+   this->checkFunction(muVx1); 
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setVx2( const std::string& muParserString) 
+{ 
+   this->muVx2.SetExpr(muParserString); 
+   this->checkFunction(muVx2); 
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setVx3( const std::string& muParserString)  
+{ 
+   this->muVx3.SetExpr(muParserString); 
+   this->checkFunction(muVx3); 
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setRho( const std::string& muParserString)  
+{ 
+   this->muRho.SetExpr(muParserString); 
+   this->checkFunction(muRho); 
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setVx1( LBMReal vx1 ) 
+{ 
+   this->muVx1.SetExpr( UbSystem::toString(vx1,D3Q27RealLim::digits10) );  
+   this->checkFunction(muVx1); 
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setVx2( LBMReal vx2 ) 
+{ 
+   this->muVx2.SetExpr( UbSystem::toString(vx2,D3Q27RealLim::digits10) );  
+   this->checkFunction(muVx2); 
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setVx3( LBMReal vx3 ) 
+{ 
+   this->muVx3.SetExpr( UbSystem::toString(vx3,D3Q27RealLim::digits10) );  
+   this->checkFunction(muVx3); 
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setRho( LBMReal rho ) 
+{ 
+   this->muRho.SetExpr( UbSystem::toString(rho,D3Q27RealLim::digits10) );  
+   this->checkFunction(muRho); 
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::visit(const Grid3DPtr grid, Block3DPtr block) 
+{
+   using namespace D3Q27System;
+
+   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());
+   
+
+   //define vars for functions
+   mu::value_type x1,x2,x3;
+   this->muVx1.DefineVar("x1",&x1); this->muVx1.DefineVar("x2",&x2); this->muVx1.DefineVar("x3",&x3);
+   this->muVx2.DefineVar("x1",&x1); this->muVx2.DefineVar("x2",&x2); this->muVx2.DefineVar("x3",&x3);
+   this->muVx3.DefineVar("x1",&x1); this->muVx3.DefineVar("x2",&x2); this->muVx3.DefineVar("x3",&x3);
+   this->muRho.DefineVar("x1",&x1); this->muRho.DefineVar("x2",&x2); this->muRho.DefineVar("x3",&x3);
+
+   //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())
+   {
+       ILBMKernelPtr 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);
+
+      BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
+      EsoTwist3DPtr distributions = std::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();
+
+      for(int ix3=0; ix3<bcArray->getNX3(); ix3++)
+         for(int ix2=0; ix2<bcArray->getNX2(); ix2++)
+            for(int ix1=0; ix1<bcArray->getNX1(); ix1++)
+            {
+               Vector3D coords = grid->getNodeCoordinates(block, ix1, ix2, ix3);
+               x1 = coords[0];
+               x2 = coords[1];
+               x3 = coords[2];
+
+               vx1 = muVx1.Eval();
+               vx2 = muVx2.Eval();
+               vx3 = muVx3.Eval();
+               rho = muRho.Eval();
+
+               //x-derivative
+               double deltaX=dx*0.5;
+               x1 = coords[0]+deltaX;
+               double vx1Plusx1 = muVx1.Eval();
+               double vx2Plusx1 = muVx2.Eval();
+               double vx3Plusx1 = muVx3.Eval();
+
+               x1 = coords[0]-deltaX;
+               double vx1Minusx1 = muVx1.Eval();
+               double vx2Minusx1 = muVx2.Eval();
+               double vx3Minusx1 = muVx3.Eval();
+
+               //y-derivative
+               x1 = coords[0];
+               x2 = coords[1]+deltaX;
+               double vx1Plusx2 = muVx1.Eval();
+               double vx2Plusx2 = muVx2.Eval();
+               double vx3Plusx2 = muVx3.Eval();
+
+               x2 = coords[1]-deltaX;
+               double vx1Minusx2 = muVx1.Eval();
+               double vx2Minusx2 = muVx2.Eval();
+               double vx3Minusx2 = muVx3.Eval();
+
+               //z-derivative
+               x2 = coords[1];
+               x3 = coords[2]+deltaX;
+               double vx1Plusx3 = muVx1.Eval();
+               double vx2Plusx3 = muVx2.Eval();
+               double vx3Plusx3 = muVx3.Eval();
+
+               x3 = coords[2]-deltaX;
+               double vx1Minusx3 = muVx1.Eval();
+               double vx2Minusx3 = muVx2.Eval();
+               double vx3Minusx3 = muVx3.Eval();
+
+               double ax=(vx1Plusx1-vx1Minusx1)/(2.0*deltaX)*dx;
+               double bx=(vx2Plusx1-vx2Minusx1)/(2.0*deltaX)*dx;
+               double cx=(vx3Plusx1-vx3Minusx1)/(2.0*deltaX)*dx;
+
+               double ay=(vx1Plusx2-vx1Minusx2)/(2.0*deltaX)*dx;
+               double by=(vx2Plusx2-vx2Minusx2)/(2.0*deltaX)*dx;
+               double cy=(vx3Plusx2-vx3Minusx2)/(2.0*deltaX)*dx;
+
+               double az=(vx1Plusx3-vx1Minusx3)/(2.0*deltaX)*dx;
+               double bz=(vx2Plusx3-vx2Minusx3)/(2.0*deltaX)*dx;
+               double cz=(vx3Plusx3-vx3Minusx3)/(2.0*deltaX)*dx;
+               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];
+
+               //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();
+
+            }
+   }
+
+   //variablen der functions loeschen, da die verwiesenen Objecte nach dem verlassen des scopes ungueltig sind!
+   this->muVx1.ClearVar();
+   this->muVx2.ClearVar();
+   this->muVx3.ClearVar();
+   this->muRho.ClearVar();
+
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::checkFunction(mu::Parser fct)
+{
+   double x1=1.0,x2=1.0,x3=1.0;
+   fct.DefineVar("x1",&x1); 
+   fct.DefineVar("x2",&x2); 
+   fct.DefineVar("x3",&x3);
+
+   try
+   {
+      fct.Eval();
+      fct.ClearVar();
+   }
+   catch(mu::ParserError& e)
+   {
+      throw UbException(UB_EXARGS,"function: "+e.GetExpr() + (std::string)"error: "+e.GetMsg()
+         +(std::string)", only x1,x2,x3 are allowed as variables" );
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setNu( LBMReal nu )
+{
+   this->nu = nu;
+}
+
diff --git a/source/VirtualFluidsCore/Visitors/InitDistributionsBlockVisitor.h b/source/VirtualFluidsCore/Visitors/InitDistributionsBlockVisitor.h
index a047cd3d0..6f0868677 100644
--- a/source/VirtualFluidsCore/Visitors/InitDistributionsBlockVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/InitDistributionsBlockVisitor.h
@@ -1,11 +1,10 @@
 #ifndef InitDistributionsBlockVisitor_H
 #define InitDistributionsBlockVisitor_H
 
-#include <boost/foreach.hpp>
+#include <memory>
 
 #include "Block3DVisitor.h"
 #include "D3Q27System.h"
-#include "Block3D.h"
 
 #include <MuParser/include/muParser.h>
 
@@ -32,6 +31,8 @@ if function is invalid an UbException with detailed information is thrown
 //! init.setVx1("0.01*x2^2");<BR>
 //! patch.adaptByPatchCriterion(init);
 
+class Grid3D;
+class Block3D;
 
 
 class InitDistributionsBlockVisitor : public Block3DVisitor
@@ -69,7 +70,7 @@ public:
    void setRho( LBMReal rho );
    void setNu( LBMReal nu );
 
-   void visit(Grid3DPtr grid, Block3DPtr block);
+   void visit(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block) override;
 
 protected:
    void checkFunction(mu::Parser fct);
diff --git a/source/VirtualFluidsCore/Visitors/InitDistributionsFromFileBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/InitDistributionsFromFileBlockVisitor.cpp
index dbea17992..82836988e 100644
--- a/source/VirtualFluidsCore/Visitors/InitDistributionsFromFileBlockVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/InitDistributionsFromFileBlockVisitor.cpp
@@ -1,252 +1,258 @@
-#include "InitDistributionsFromFileBlockVisitor.h"
-#include <basics/utilities/UbFileInputASCII.h>
-#include "LBMKernel.h"
-#include "BCProcessor.h"
-#include "Grid3DSystem.h"
-#include "InitDensityLBMKernel.h"
-
-InitDistributionsFromFileBlockVisitor::InitDistributionsFromFileBlockVisitor(LBMReal nu, LBMReal rho, 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);
-   }
-
-   int nodesX1 = in.readInteger();
-   int nodesX2 = in.readInteger();
-   int nodesX3 = in.readInteger();
-
-   matrix = CbArray4D<LBMReal, IndexerX4X3X2X1>(3, nodesX1, nodesX2, nodesX3, 0);
-
-   for (int x3 = 0; x3<nodesX3; x3++)
-      for (int x2 = 0; x2<nodesX2; x2++)
-         for (int x1 = 0; x1<nodesX1; x1++)
-         {
-   //for (int x1 = 0; x1<nodesX1; x1++)
-   //   for (int x2 = 0; x2<nodesX2; x2++)
-   //      for (int x3 = 0; x3<nodesX3; x3++)
-   //      {
-            matrix(Vx1, x1, x2, x3) = in.readDouble();
-            matrix(Vx2, x1, x2, x3) = in.readDouble();
-            matrix(Vx3, x1, x2, x3) = in.readDouble();
-         }
-}
-//////////////////////////////////////////////////////////////////////////
-InitDistributionsFromFileBlockVisitor::~InitDistributionsFromFileBlockVisitor()
-{
-}
-//////////////////////////////////////////////////////////////////////////
-void InitDistributionsFromFileBlockVisitor::visit(const Grid3DPtr grid, Block3DPtr block)
-{
-   using namespace D3Q27System;
-
-   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;
-
-   int gridRank = grid->getRank();
-   int blockRank = block->getRank();
-
-   if (blockRank==gridRank && block->isActive())
-   {
-      LBMKernelPtr 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);
-
-      BCArray3DPtr bcArray = 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 maxMX1 = (int)matrix.getNX2();
-      int maxMX2 = (int)matrix.getNX3();
-      int maxMX3 = (int)matrix.getNX4();
-
-      int blockix1 = block->getX1();
-      int blockix2 = block->getX2();
-      int blockix3 = block->getX3();
-
-      UbTupleInt3 blockNx = grid->getBlockNX();
-
-      for (int ix3 = minX1; ix3<maxX3; ix3++)
-         for (int ix2 = minX2; ix2<maxX2; ix2++)
-            for (int ix1 = minX1; ix1<maxX1; ix1++)
-            {
-               int x1 = blockix1*val<1>(blockNx)+ix1-1;
-               int x2 = blockix2*val<2>(blockNx)+ix2-1;
-               int x3 = blockix3*val<3>(blockNx)+ix3-1;
-
-               if (x1==-1)
-               {
-                  x1 = maxMX1-1;
-               }
-               if (x2==-1)
-               {
-                  x2 = maxMX2-1;
-               }
-               if (x3==-1)
-               {
-                  x3 = maxMX3-1;
-               }
-
-               if (x1==maxMX1)
-               {
-                  x1 = 1;
-               }
-               if (x2==maxMX2)
-               {
-                  x2 = 1;
-               }
-               if (x3==maxMX3)
-               {
-                  x3 = 1;
-               }
-
-               vx1 = matrix(Vx1, x1, x2, x3);
-               vx2 = matrix(Vx2, x1, x2, x3);
-               vx3 = matrix(Vx3, x1, x2, x3);
-
-               //int x1p, x2p, x3p;
-
-               ////x-derivative
-               //if (x1+1 >= maxMX1) x1p = x1;
-               //else  x1p = x1+1;
-               //double vx1Plusx1 = matrix(Vx1, x1p, x2, x3);
-               //double vx2Plusx1 = matrix(Vx2, x1p, x2, x3);
-               //double vx3Plusx1 = matrix(Vx3, x1p, x2, x3);
-
-               //if (x1-1 < minX1) x1p = x1;
-               //else  x1p = x1-1;
-               //double vx1Minusx1 = matrix(Vx1, x1p, x2, x3);
-               //double vx2Minusx1 = matrix(Vx2, x1p, x2, x3);
-               //double vx3Minusx1 = matrix(Vx3, x1p, x2, x3);
-
-               ////y-derivative
-               //if (x2+1 >= maxMX2) x2p = x2;
-               //else  x2p = x2+1;
-               //double vx1Plusx2 = matrix(Vx1, x1, x2p, x3);
-               //double vx2Plusx2 = matrix(Vx2, x1, x2p, x3);
-               //double vx3Plusx2 = matrix(Vx3, x1, x2p, x3);
-
-               //if (x2-1 < minX2) x2p = x2;
-               //else  x2p = x2-1;
-               //double vx1Minusx2 = matrix(Vx1, x1, x2p, x3);
-               //double vx2Minusx2 = matrix(Vx2, x1, x2p, x3);
-               //double vx3Minusx2 = matrix(Vx3, x1, x2p, x3);
-
-               ////z-derivative
-               //if (x3+1 >= maxMX3) x3p = x3;
-               //else  x3p = x3+1;
-               //double vx1Plusx3 = matrix(Vx1, x1, x2, x3p);
-               //double vx2Plusx3 = matrix(Vx2, x1, x2, x3p);
-               //double vx3Plusx3 = matrix(Vx3, x1, x2, x3p);
-
-               //if (x3-1 < minX3) x3p = x3;
-               //else  x3p = x3-1;
-               //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);
-               //double bx = (vx2Plusx1 - vx2Minusx1) / (2.0);
-               //double cx = (vx3Plusx1 - vx3Minusx1) / (2.0);
-
-               //double ay = (vx1Plusx2 - vx1Minusx2) / (2.0);
-               //double by = (vx2Plusx2 - vx2Minusx2) / (2.0);
-               //double cy = (vx3Plusx2 - vx3Minusx2) / (2.0);
-
-               //double az = (vx1Plusx3 - vx1Minusx3) / (2.0);
-               //double bz = (vx2Plusx3 - vx2Minusx3) / (2.0);
-               //double cz = (vx3Plusx3 - vx3Minusx3) / (2.0);
-               //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];
-
-               calcFeqsFct(f, rho, vx1, vx2, vx3);
-
-               distributions->setDistribution(f, ix1, ix2, ix3);
-               distributions->setDistributionInv(f, ix1, ix2, ix3);
-               boost::dynamic_pointer_cast<InitDensityLBMKernel>(kernel)->setVelocity(ix1, ix2, ix3, vx1, vx2, vx3);
-            }
-      
-   }
-}
-//////////////////////////////////////////////////////////////////////////
+#include "InitDistributionsFromFileBlockVisitor.h"
+#include <basics/utilities/UbFileInputASCII.h>
+#include "LBMKernel.h"
+#include "BCProcessor.h"
+#include "Grid3DSystem.h"
+#include "InitDensityLBMKernel.h"
+#include "DataSet3D.h"
+#include "EsoTwist3D.h"
+#include "Grid3D.h"
+#include "Block3D.h"
+#include "BCArray3D.h"
+
+
+InitDistributionsFromFileBlockVisitor::InitDistributionsFromFileBlockVisitor(LBMReal nu, LBMReal rho, 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);
+   }
+
+   int nodesX1 = in.readInteger();
+   int nodesX2 = in.readInteger();
+   int nodesX3 = in.readInteger();
+
+   matrix = CbArray4D<LBMReal, IndexerX4X3X2X1>(3, nodesX1, nodesX2, nodesX3, 0);
+
+   for (int x3 = 0; x3<nodesX3; x3++)
+      for (int x2 = 0; x2<nodesX2; x2++)
+         for (int x1 = 0; x1<nodesX1; x1++)
+         {
+   //for (int x1 = 0; x1<nodesX1; x1++)
+   //   for (int x2 = 0; x2<nodesX2; x2++)
+   //      for (int x3 = 0; x3<nodesX3; x3++)
+   //      {
+            matrix(Vx1, x1, x2, x3) = in.readDouble();
+            matrix(Vx2, x1, x2, x3) = in.readDouble();
+            matrix(Vx3, x1, x2, x3) = in.readDouble();
+         }
+}
+//////////////////////////////////////////////////////////////////////////
+InitDistributionsFromFileBlockVisitor::~InitDistributionsFromFileBlockVisitor()
+{
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsFromFileBlockVisitor::visit(const Grid3DPtr grid, Block3DPtr block)
+{
+   using namespace D3Q27System;
+
+   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;
+
+   int gridRank = grid->getRank();
+   int blockRank = block->getRank();
+
+   if (blockRank==gridRank && block->isActive())
+   {
+      ILBMKernelPtr 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);
+
+      BCArray3DPtr bcArray = kernel->getBCProcessor()->getBCArray();
+      EsoTwist3DPtr distributions = std::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 maxMX1 = (int)matrix.getNX2();
+      int maxMX2 = (int)matrix.getNX3();
+      int maxMX3 = (int)matrix.getNX4();
+
+      int blockix1 = block->getX1();
+      int blockix2 = block->getX2();
+      int blockix3 = block->getX3();
+
+      UbTupleInt3 blockNx = grid->getBlockNX();
+
+      for (int ix3 = minX1; ix3<maxX3; ix3++)
+         for (int ix2 = minX2; ix2<maxX2; ix2++)
+            for (int ix1 = minX1; ix1<maxX1; ix1++)
+            {
+               int x1 = blockix1*val<1>(blockNx)+ix1-1;
+               int x2 = blockix2*val<2>(blockNx)+ix2-1;
+               int x3 = blockix3*val<3>(blockNx)+ix3-1;
+
+               if (x1==-1)
+               {
+                  x1 = maxMX1-1;
+               }
+               if (x2==-1)
+               {
+                  x2 = maxMX2-1;
+               }
+               if (x3==-1)
+               {
+                  x3 = maxMX3-1;
+               }
+
+               if (x1==maxMX1)
+               {
+                  x1 = 1;
+               }
+               if (x2==maxMX2)
+               {
+                  x2 = 1;
+               }
+               if (x3==maxMX3)
+               {
+                  x3 = 1;
+               }
+
+               vx1 = matrix(Vx1, x1, x2, x3);
+               vx2 = matrix(Vx2, x1, x2, x3);
+               vx3 = matrix(Vx3, x1, x2, x3);
+
+               //int x1p, x2p, x3p;
+
+               ////x-derivative
+               //if (x1+1 >= maxMX1) x1p = x1;
+               //else  x1p = x1+1;
+               //double vx1Plusx1 = matrix(Vx1, x1p, x2, x3);
+               //double vx2Plusx1 = matrix(Vx2, x1p, x2, x3);
+               //double vx3Plusx1 = matrix(Vx3, x1p, x2, x3);
+
+               //if (x1-1 < minX1) x1p = x1;
+               //else  x1p = x1-1;
+               //double vx1Minusx1 = matrix(Vx1, x1p, x2, x3);
+               //double vx2Minusx1 = matrix(Vx2, x1p, x2, x3);
+               //double vx3Minusx1 = matrix(Vx3, x1p, x2, x3);
+
+               ////y-derivative
+               //if (x2+1 >= maxMX2) x2p = x2;
+               //else  x2p = x2+1;
+               //double vx1Plusx2 = matrix(Vx1, x1, x2p, x3);
+               //double vx2Plusx2 = matrix(Vx2, x1, x2p, x3);
+               //double vx3Plusx2 = matrix(Vx3, x1, x2p, x3);
+
+               //if (x2-1 < minX2) x2p = x2;
+               //else  x2p = x2-1;
+               //double vx1Minusx2 = matrix(Vx1, x1, x2p, x3);
+               //double vx2Minusx2 = matrix(Vx2, x1, x2p, x3);
+               //double vx3Minusx2 = matrix(Vx3, x1, x2p, x3);
+
+               ////z-derivative
+               //if (x3+1 >= maxMX3) x3p = x3;
+               //else  x3p = x3+1;
+               //double vx1Plusx3 = matrix(Vx1, x1, x2, x3p);
+               //double vx2Plusx3 = matrix(Vx2, x1, x2, x3p);
+               //double vx3Plusx3 = matrix(Vx3, x1, x2, x3p);
+
+               //if (x3-1 < minX3) x3p = x3;
+               //else  x3p = x3-1;
+               //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);
+               //double bx = (vx2Plusx1 - vx2Minusx1) / (2.0);
+               //double cx = (vx3Plusx1 - vx3Minusx1) / (2.0);
+
+               //double ay = (vx1Plusx2 - vx1Minusx2) / (2.0);
+               //double by = (vx2Plusx2 - vx2Minusx2) / (2.0);
+               //double cy = (vx3Plusx2 - vx3Minusx2) / (2.0);
+
+               //double az = (vx1Plusx3 - vx1Minusx3) / (2.0);
+               //double bz = (vx2Plusx3 - vx2Minusx3) / (2.0);
+               //double cz = (vx3Plusx3 - vx3Minusx3) / (2.0);
+               //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];
+
+               calcFeqsFct(f, rho, vx1, vx2, vx3);
+
+               distributions->setDistribution(f, ix1, ix2, ix3);
+               distributions->setDistributionInv(f, ix1, ix2, ix3);
+               std::dynamic_pointer_cast<InitDensityLBMKernel>(kernel)->setVelocity(ix1, ix2, ix3, vx1, vx2, vx3);
+            }
+      
+   }
+}
+//////////////////////////////////////////////////////////////////////////
diff --git a/source/VirtualFluidsCore/Visitors/InitDistributionsFromFileBlockVisitor.h b/source/VirtualFluidsCore/Visitors/InitDistributionsFromFileBlockVisitor.h
index 100f54977..4e37dae32 100644
--- a/source/VirtualFluidsCore/Visitors/InitDistributionsFromFileBlockVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/InitDistributionsFromFileBlockVisitor.h
@@ -2,13 +2,21 @@
 #define InitDistributionsFromFileBlockVisitor_h__
 
 #include "Block3DVisitor.h"
+#include "LBMSystem.h"
+
+#include "CbArray4D.h"
+
+class Grid3D;
+class Block3D;
 
 class InitDistributionsFromFileBlockVisitor : public Block3DVisitor
 {
 public:
    InitDistributionsFromFileBlockVisitor(LBMReal nu, LBMReal rho, std::string file);
    ~InitDistributionsFromFileBlockVisitor();
-   void visit(Grid3DPtr grid, Block3DPtr block);
+
+   void visit(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block) override;
+
 private:
    CbArray4D<LBMReal, IndexerX4X3X2X1> matrix;
    enum Velocity { Vx1, Vx2, Vx3 };
diff --git a/source/VirtualFluidsCore/Visitors/InitDistributionsWithInterpolationGridVisitor.cpp b/source/VirtualFluidsCore/Visitors/InitDistributionsWithInterpolationGridVisitor.cpp
index 2cd5349f0..809c8d5b5 100644
--- a/source/VirtualFluidsCore/Visitors/InitDistributionsWithInterpolationGridVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/InitDistributionsWithInterpolationGridVisitor.cpp
@@ -1,11 +1,17 @@
 #include "InitDistributionsWithInterpolationGridVisitor.h"
+
+#include "mpi.h"
+
 #include <basics/utilities/UbFileInputASCII.h>
 #include "LBMKernel.h"
 #include "BCProcessor.h"
 #include "Grid3DSystem.h"
 #include <CbArray2D.h>
 #include "D3Q27EsoTwist3DSplittedVector.h"
-
+#include "InterpolationProcessor.h"
+#include "DataSet3D.h"
+#include "Grid3D.h"
+#include "Block3D.h"
 
 using namespace std;
 
@@ -33,7 +39,7 @@ void InitDistributionsWithInterpolationGridVisitor::visit(Grid3DPtr grid)
       newGrid->getBlocks(l, blockVector);
       vector<Block3DPtr> tBlockID;
 
-      BOOST_FOREACH(Block3DPtr newBlock, blockVector)
+      for(Block3DPtr newBlock : blockVector)
       {
          if (!newBlock)
             UB_THROW(UbException(UB_EXARGS, "block is not exist"));
@@ -57,9 +63,9 @@ void InitDistributionsWithInterpolationGridVisitor::visit(Grid3DPtr grid)
          else
          {
             int newlevel = newBlock->getLevel();
-            UbTupleDouble3 coord = newGrid->getNodeCoordinates(newBlock, 1, 1, 1);
+            Vector3D coords = newGrid->getNodeCoordinates(newBlock, 1, 1, 1);
 
-            UbTupleInt3 oldGridBlockIndexes = oldGrid->getBlockIndexes(val<1>(coord), val<2>(coord), val<3>(coord), newlevel-1);
+            UbTupleInt3 oldGridBlockIndexes = oldGrid->getBlockIndexes(coords[0], coords[1], coords[2], newlevel-1);
             Block3DPtr oldBlock = oldGrid->getBlock(val<1>(oldGridBlockIndexes), val<2>(oldGridBlockIndexes), val<3>(oldGridBlockIndexes), newlevel-1);
 
             if (oldBlock)
@@ -78,7 +84,7 @@ void InitDistributionsWithInterpolationGridVisitor::visit(Grid3DPtr grid)
             }
             else
             {
-               UbTupleInt3 oldGridBlockIndexes = oldGrid->getBlockIndexes(val<1>(coord), val<2>(coord), val<3>(coord), newlevel+1);
+               UbTupleInt3 oldGridBlockIndexes = oldGrid->getBlockIndexes(coords[0], coords[1], coords[2], newlevel+1);
                Block3DPtr oldBlock = oldGrid->getBlock(val<1>(oldGridBlockIndexes), val<2>(oldGridBlockIndexes), val<3>(oldGridBlockIndexes), newlevel+1);
                if (oldBlock)
                {
@@ -102,12 +108,12 @@ void InitDistributionsWithInterpolationGridVisitor::visit(Grid3DPtr grid)
 //////////////////////////////////////////////////////////////////////////
 void InitDistributionsWithInterpolationGridVisitor::copyLocalBlock(Block3DPtr oldBlock, Block3DPtr newBlock)
 {
-   LBMKernelPtr oldKernel = oldBlock->getKernel();
+   ILBMKernelPtr 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());
+   EsoTwist3DPtr oldDistributions = std::dynamic_pointer_cast<EsoTwist3D>(oldKernel->getDataSet()->getFdistributions());
 
-   LBMKernelPtr kernel = newBlock->getKernel();
+   ILBMKernelPtr kernel = newBlock->getKernel();
    if (!kernel)
       throw UbException(UB_EXARGS, "The LBM kernel isn't exist in new block: "+newBlock->toString());
    kernel->getDataSet()->setFdistributions(oldDistributions);
@@ -121,14 +127,14 @@ void InitDistributionsWithInterpolationGridVisitor::copyRemoteBlock(Block3DPtr o
 
    if (oldBlockRank == newGridRank && oldBlock->isActive())
    {
-      LBMKernelPtr oldKernel = oldBlock->getKernel();
+       ILBMKernelPtr 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());
+      EsoTwist3DPtr oldDistributions = std::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();
+      CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(oldDistributions)->getLocalDistributions();
+      CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(oldDistributions)->getNonLocalDistributions();
+      CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr   zeroDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(oldDistributions)->getZeroDistributions();
 
       MPI_Send(localDistributions->getStartAdressOfSortedArray(0, 0, 0, 0), (int)localDistributions->getDataVector().size(), MPI_DOUBLE, newBlockRank, 0, MPI_COMM_WORLD);
       MPI_Send(nonLocalDistributions->getStartAdressOfSortedArray(0, 0, 0, 0), (int)nonLocalDistributions->getDataVector().size(), MPI_DOUBLE, newBlockRank, 0, MPI_COMM_WORLD);
@@ -136,15 +142,15 @@ void InitDistributionsWithInterpolationGridVisitor::copyRemoteBlock(Block3DPtr o
    }
    else if (newBlockRank == newGridRank && newBlock->isActive())
    {
-      LBMKernelPtr newKernel = newBlock->getKernel();
+       ILBMKernelPtr 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());
+      EsoTwist3DPtr newDistributions = std::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();
+      CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(newDistributions)->getLocalDistributions();
+      CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(newDistributions)->getNonLocalDistributions();
+      CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr   zeroDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(newDistributions)->getZeroDistributions();
 
       MPI_Recv(localDistributions->getStartAdressOfSortedArray(0, 0, 0, 0), (int)localDistributions->getDataVector().size(), MPI_DOUBLE, oldBlockRank, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
       MPI_Recv(nonLocalDistributions->getStartAdressOfSortedArray(0, 0, 0, 0), (int)nonLocalDistributions->getDataVector().size(), MPI_DOUBLE, oldBlockRank, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
@@ -163,19 +169,19 @@ void InitDistributionsWithInterpolationGridVisitor::interpolateLocalBlockCoarseT
 
    iProcessor->setOmegas(omegaC, omegaF);
 
-   LBMKernelPtr oldKernel = oldBlock->getKernel();
+   ILBMKernelPtr 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());
+   EsoTwist3DPtr oldDistributions = std::dynamic_pointer_cast<EsoTwist3D>(oldKernel->getDataSet()->getFdistributions());
 
    BCArray3DPtr bcArrayOldBlock = oldBlock->getKernel()->getBCProcessor()->getBCArray();
 
-   LBMKernelPtr newKernel = newBlock->getKernel();
+   ILBMKernelPtr 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());
+   EsoTwist3DPtr newDistributions = std::dynamic_pointer_cast<EsoTwist3D>(newKernel->getDataSet()->getFdistributions());
 
    int minX1 = 0;
    int minX2 = 0;
@@ -193,8 +199,8 @@ void InitDistributionsWithInterpolationGridVisitor::interpolateLocalBlockCoarseT
       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));
+             Vector3D coords = newGrid->getNodeCoordinates(newBlock, ix1, ix2, ix3);
+            UbTupleInt3 oldGridIndexMin = oldGrid->getNodeIndexes(oldBlock, coords[0], coords[1], coords[2]);
             int howManySolids= iProcessor->iCellHowManySolids(bcArrayOldBlock, val<1>(oldGridIndexMin), val<2>(oldGridIndexMin), val<3>(oldGridIndexMin));
 
             if (howManySolids == 0 || howManySolids == 8)
@@ -255,14 +261,14 @@ void InitDistributionsWithInterpolationGridVisitor::interpolateRemoteBlockCoarse
 
    if (oldBlockRank == newGridRank)
    {
-      LBMKernelPtr oldKernel = oldBlock->getKernel();
+       ILBMKernelPtr 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());
+      EsoTwist3DPtr oldDistributions = std::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();
+      CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(oldDistributions)->getLocalDistributions();
+      CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(oldDistributions)->getNonLocalDistributions();
+      CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr   zeroDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(oldDistributions)->getZeroDistributions();
 
       MPI_Send(localDistributions->getStartAdressOfSortedArray(0, 0, 0, 0), (int)localDistributions->getDataVector().size(), MPI_DOUBLE, newBlockRank, 0, MPI_COMM_WORLD);
       MPI_Send(nonLocalDistributions->getStartAdressOfSortedArray(0, 0, 0, 0), (int)nonLocalDistributions->getDataVector().size(), MPI_DOUBLE, newBlockRank, 0, MPI_COMM_WORLD);
@@ -283,11 +289,11 @@ void InitDistributionsWithInterpolationGridVisitor::interpolateRemoteBlockCoarse
 
       iProcessor->setOmegas(omegaC, omegaF);
 
-      LBMKernelPtr newKernel = newBlock->getKernel();
+      ILBMKernelPtr 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());
+      EsoTwist3DPtr newDistributions = std::dynamic_pointer_cast<EsoTwist3D>(newKernel->getDataSet()->getFdistributions());
 
       int minX1 = 0;
       int minX2 = 0;
@@ -303,9 +309,9 @@ void InitDistributionsWithInterpolationGridVisitor::interpolateRemoteBlockCoarse
 
       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();
+      CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(oldDistributions)->getLocalDistributions();
+      CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(oldDistributions)->getNonLocalDistributions();
+      CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr   zeroDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(oldDistributions)->getZeroDistributions();
 
       MPI_Recv(localDistributions->getStartAdressOfSortedArray(0, 0, 0, 0), (int)localDistributions->getDataVector().size(), MPI_DOUBLE, oldBlockRank, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
       MPI_Recv(nonLocalDistributions->getStartAdressOfSortedArray(0, 0, 0, 0), (int)nonLocalDistributions->getDataVector().size(), MPI_DOUBLE, oldBlockRank, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
@@ -319,8 +325,8 @@ void InitDistributionsWithInterpolationGridVisitor::interpolateRemoteBlockCoarse
          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));
+                Vector3D coords = newGrid->getNodeCoordinates(newBlock, ix1, ix2, ix3);
+               UbTupleInt3 oldGridIndexMin = oldGrid->getNodeIndexes(oldBlock, coords[0], coords[1], coords[2]);
 
                int howManySolids= iProcessor->iCellHowManySolids(bcArrayOldBlock, val<1>(oldGridIndexMin), val<2>(oldGridIndexMin), val<3>(oldGridIndexMin));
 
@@ -388,19 +394,19 @@ void InitDistributionsWithInterpolationGridVisitor::interpolateLocalBlockFineToC
 
    iProcessor->setOmegas(omegaC, omegaF);
 
-   LBMKernelPtr oldKernel = oldBlock->getKernel();
+   ILBMKernelPtr 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());
+   EsoTwist3DPtr oldDistributions = std::dynamic_pointer_cast<EsoTwist3D>(oldKernel->getDataSet()->getFdistributions());
 
    BCArray3DPtr bcArrayOldBlock = oldBlock->getKernel()->getBCProcessor()->getBCArray();
 
-   LBMKernelPtr newKernel = newBlock->getKernel();
+   ILBMKernelPtr 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());
+   EsoTwist3DPtr newDistributions = std::dynamic_pointer_cast<EsoTwist3D>(newKernel->getDataSet()->getFdistributions());
 
    int minX1 = 0;
    int minX2 = 0;
@@ -418,8 +424,8 @@ void InitDistributionsWithInterpolationGridVisitor::interpolateLocalBlockFineToC
       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));
+             Vector3D coords = newGrid->getNodeCoordinates(newBlock, ix1, ix2, ix3);
+            UbTupleInt3 oldGridIndexMin = oldGrid->getNodeIndexes(oldBlock, coords[0], coords[1], coords[2]);
 
             int howManySolids= iProcessor->iCellHowManySolids(bcArrayOldBlock, val<1>(oldGridIndexMin), val<2>(oldGridIndexMin), val<3>(oldGridIndexMin));
 
@@ -481,14 +487,14 @@ void InitDistributionsWithInterpolationGridVisitor::interpolateRemoteBlockFineTo
 
    if (oldBlockRank == newGridRank)
    {
-      LBMKernelPtr oldKernel = oldBlock->getKernel();
+       ILBMKernelPtr 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());
+      EsoTwist3DPtr oldDistributions = std::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();
+      CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(oldDistributions)->getLocalDistributions();
+      CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(oldDistributions)->getNonLocalDistributions();
+      CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr   zeroDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(oldDistributions)->getZeroDistributions();
 
       MPI_Send(localDistributions->getStartAdressOfSortedArray(0, 0, 0, 0), (int)localDistributions->getDataVector().size(), MPI_DOUBLE, newBlockRank, 0, MPI_COMM_WORLD);
       MPI_Send(nonLocalDistributions->getStartAdressOfSortedArray(0, 0, 0, 0), (int)nonLocalDistributions->getDataVector().size(), MPI_DOUBLE, newBlockRank, 0, MPI_COMM_WORLD);
@@ -509,11 +515,11 @@ void InitDistributionsWithInterpolationGridVisitor::interpolateRemoteBlockFineTo
 
       iProcessor->setOmegas(omegaC, omegaF);
 
-      LBMKernelPtr newKernel = newBlock->getKernel();
+      ILBMKernelPtr 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());
+      EsoTwist3DPtr newDistributions = std::dynamic_pointer_cast<EsoTwist3D>(newKernel->getDataSet()->getFdistributions());
 
       int minX1 = 0;
       int minX2 = 0;
@@ -529,9 +535,9 @@ void InitDistributionsWithInterpolationGridVisitor::interpolateRemoteBlockFineTo
 
       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();
+      CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(oldDistributions)->getLocalDistributions();
+      CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(oldDistributions)->getNonLocalDistributions();
+      CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr   zeroDistributions = std::dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(oldDistributions)->getZeroDistributions();
 
       MPI_Recv(localDistributions->getStartAdressOfSortedArray(0, 0, 0, 0), (int)localDistributions->getDataVector().size(), MPI_DOUBLE, oldBlockRank, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
       MPI_Recv(nonLocalDistributions->getStartAdressOfSortedArray(0, 0, 0, 0), (int)nonLocalDistributions->getDataVector().size(), MPI_DOUBLE, oldBlockRank, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
@@ -545,8 +551,8 @@ void InitDistributionsWithInterpolationGridVisitor::interpolateRemoteBlockFineTo
          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));
+               Vector3D coords = newGrid->getNodeCoordinates(newBlock, ix1, ix2, ix3);
+               UbTupleInt3 oldGridIndexMin = oldGrid->getNodeIndexes(oldBlock, coords[0], coords[1], coords[2]);
 
                int howManySolids= iProcessor->iCellHowManySolids(bcArrayOldBlock, val<1>(oldGridIndexMin), val<2>(oldGridIndexMin), val<3>(oldGridIndexMin));
 
diff --git a/source/VirtualFluidsCore/Visitors/InitDistributionsWithInterpolationGridVisitor.h b/source/VirtualFluidsCore/Visitors/InitDistributionsWithInterpolationGridVisitor.h
index 8227b5d46..6cad16ac1 100644
--- a/source/VirtualFluidsCore/Visitors/InitDistributionsWithInterpolationGridVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/InitDistributionsWithInterpolationGridVisitor.h
@@ -1,28 +1,34 @@
 #ifndef InitDistributionsWithCoarseGridBlockVisitor_h__
 #define InitDistributionsWithCoarseGridBlockVisitor_h__
 
+#include <memory>
+
 #include "Block3DVisitor.h"
-#include <mpi.h>
+#include "LBMSystem.h"
+
+class Grid3D;
+class Block3D;
+class InterpolationProcessor;
 
-class InitDistributionsWithInterpolationGridVisitor : public Grid3DVisitor
+class InitDistributionsWithInterpolationGridVisitor : public Block3DVisitor
 {
 public:
-   InitDistributionsWithInterpolationGridVisitor(Grid3DPtr oldGrid, InterpolationProcessorPtr iProcessor, LBMReal nu);
+   InitDistributionsWithInterpolationGridVisitor(std::shared_ptr<Grid3D> oldGrid, std::shared_ptr<InterpolationProcessor> iProcessor, LBMReal nu);
    ~InitDistributionsWithInterpolationGridVisitor();
-   void visit(Grid3DPtr grid);
+   void visit(std::shared_ptr<Grid3D> grid);
 private:
-   void copyLocalBlock(Block3DPtr oldBlock, Block3DPtr newBlock);
-   void copyRemoteBlock(Block3DPtr oldBlock, Block3DPtr newBlock);
-   void interpolateLocalBlockCoarseToFine(Block3DPtr oldBlock, Block3DPtr newBlock);
-   void interpolateRemoteBlockCoarseToFine(Block3DPtr oldBlock, Block3DPtr newBlock);
-   void interpolateLocalBlockFineToCoarse(Block3DPtr oldBlock, Block3DPtr newBlock);
-   void interpolateRemoteBlockFineToCoarse(Block3DPtr oldBlock, Block3DPtr newBlock);
+   void copyLocalBlock(std::shared_ptr<Block3D> oldBlock, std::shared_ptr<Block3D> newBlock);
+   void copyRemoteBlock(std::shared_ptr<Block3D> oldBlock, std::shared_ptr<Block3D> newBlock);
+   void interpolateLocalBlockCoarseToFine(std::shared_ptr<Block3D> oldBlock, std::shared_ptr<Block3D> newBlock);
+   void interpolateRemoteBlockCoarseToFine(std::shared_ptr<Block3D> oldBlock, std::shared_ptr<Block3D> newBlock);
+   void interpolateLocalBlockFineToCoarse(std::shared_ptr<Block3D> oldBlock, std::shared_ptr<Block3D> newBlock);
+   void interpolateRemoteBlockFineToCoarse(std::shared_ptr<Block3D> oldBlock, std::shared_ptr<Block3D> newBlock);
 
-   Grid3DPtr newGrid;
-   Grid3DPtr oldGrid;
+   std::shared_ptr<Grid3D> newGrid;
+   std::shared_ptr<Grid3D> oldGrid;
    LBMReal nu;
 
-   InterpolationProcessorPtr iProcessor;
+   std::shared_ptr<InterpolationProcessor> iProcessor;
 };
 
 #endif // InitDistributionsWithVelocityProfileBlockVisitor_h__
diff --git a/source/VirtualFluidsCore/Visitors/MetisPartitioningGridVisitor.cpp b/source/VirtualFluidsCore/Visitors/MetisPartitioningGridVisitor.cpp
index e5c5aab95..25357d4ea 100644
--- a/source/VirtualFluidsCore/Visitors/MetisPartitioningGridVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/MetisPartitioningGridVisitor.cpp
@@ -2,7 +2,9 @@
 
 #include "MetisPartitioningGridVisitor.h"
 #include <math.h>
-#include <boost/foreach.hpp>
+#include "Block3D.h"
+#include "Grid3D.h"
+#include "Communicator.h"
 
 using namespace std;
 
@@ -131,7 +133,7 @@ void MetisPartitioningGridVisitor::buildMetisGraphLevelIntersected(Grid3DPtr gri
     const int edgeWeightChildFactor = 8;
     int n = 0;
 
-    BOOST_FOREACH(Grid3D::BlockIDMap::value_type b,  grid->getBlockIDs())
+    for(Grid3D::BlockIDMap::value_type b :  grid->getBlockIDs())
     { 
         Block3DPtr block = b.second;
         if (this->getPartitionCondition(block, level))
@@ -144,7 +146,7 @@ void MetisPartitioningGridVisitor::buildMetisGraphLevelIntersected(Grid3DPtr gri
 
     MetisPartitioner metis;
 
-    BOOST_FOREACH(Grid3D::BlockIDMap::value_type b,  grid->getBlockIDs())
+    for(Grid3D::BlockIDMap::value_type b :  grid->getBlockIDs())
     { 
         const Block3DPtr block = b.second;
         if (this->getPartitionCondition(block, level))
@@ -168,7 +170,7 @@ void MetisPartitioningGridVisitor::buildMetisGraphLevelIntersected(Grid3DPtr gri
             }
             vector<Block3DPtr> subBlocks;
             grid->getSubBlocks(block, 1, subBlocks);
-            BOOST_FOREACH(Block3DPtr subBlock, subBlocks)
+            for(Block3DPtr subBlock : subBlocks)
             {
                 if (subBlock)
                 {
@@ -204,7 +206,7 @@ void MetisPartitioningGridVisitor::buildMetisGraphLevelBased(Grid3DPtr grid, int
         grid->getBlocks(l, blockVector);
         vector<Block3DPtr> tBlockID;
 
-        BOOST_FOREACH(Block3DPtr block, blockVector)
+        for(Block3DPtr block : blockVector)
         { 
             if (this->getPartitionCondition(block, level))
             {
@@ -226,7 +228,7 @@ void MetisPartitioningGridVisitor::buildMetisGraphLevelBased(Grid3DPtr grid, int
         int edges = 0;
         const int edgeWeight= 1;
 
-        BOOST_FOREACH(Block3DPtr block, tBlockID)
+        for(Block3DPtr block : tBlockID)
         {
             metis.xadj.push_back(edges);
             metis.vwgt.push_back(vertexWeight);
@@ -257,7 +259,7 @@ void MetisPartitioningGridVisitor::buildMetisGraphLevelBased(Grid3DPtr grid, int
         }
         metis.partition(tnofSegments, partType);
 
-        BOOST_FOREACH(idx_t p, metis.part)
+        for(idx_t p : metis.part)
         {
             parts.push_back(p);
         }
diff --git a/source/VirtualFluidsCore/Visitors/MetisPartitioningGridVisitor.h b/source/VirtualFluidsCore/Visitors/MetisPartitioningGridVisitor.h
index 4f00c17ca..6ddce666d 100644
--- a/source/VirtualFluidsCore/Visitors/MetisPartitioningGridVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/MetisPartitioningGridVisitor.h
@@ -4,26 +4,31 @@
 #if defined VF_METIS && defined VF_MPI
 
 #include <vector>
+#include <memory>
 
-#include "MetisPartitioner.h"
 #include "Grid3DVisitor.h"
-#include "LBMSystem.h"
-#include "Block3D.h"
-#include "Communicator.h"
+#include "MetisPartitioner.h"
+
+
+class Communicator;
 
-#include <boost/shared_ptr.hpp>
 class MetisPartitioningGridVisitor;
-typedef boost::shared_ptr<MetisPartitioningGridVisitor> PartitionMetisGridVisitorPtr;
+typedef std::shared_ptr<MetisPartitioningGridVisitor> PartitionMetisGridVisitorPtr;
 
 ////////////////////////////////////////////////////////////////////////
 //! \brief The class implements domain decomposition with METIS library
 //! \author Kostyantyn Kucher
 //////////////////////////////////////////////////////////////////////////
+
+class Grid3D;
+class Block3D;
+
 class MetisPartitioningGridVisitor : public Grid3DVisitor
 {                                             
 public:
    //! This describe different types of decomposition   
    enum GraphType{LevelIntersected, LevelBased};
+
 public:
    //! Constructor
    //! \param comm - communicator
@@ -31,23 +36,24 @@ public:
    //! \param numOfDirs - maximum number of neighbors for each process
    //! \param threads - on/off decomposition for threads
    //! \param numberOfThreads - number of threads
-   MetisPartitioningGridVisitor(CommunicatorPtr comm, GraphType graphType, int numOfDirs, MetisPartitioner::PartType partType = MetisPartitioner::KWAY, bool threads = false, int numberOfThreads = 0);
+   MetisPartitioningGridVisitor(std::shared_ptr<Communicator> comm, GraphType graphType, int numOfDirs, MetisPartitioner::PartType partType = MetisPartitioner::KWAY, bool threads = false, int numberOfThreads = 0);
    virtual ~MetisPartitioningGridVisitor();
-   void visit(Grid3DPtr grid);
+   void visit(std::shared_ptr<Grid3D> grid) override;
    void setNumberOfProcesses(int np);
+
 protected:
    enum PartLevel {BUNDLE, PROCESS, THREAD};
-   void collectData(Grid3DPtr grid, int nofSegments, PartLevel level);
-   void buildMetisGraphLevelIntersected(Grid3DPtr grid, int nofSegments, PartLevel level);
-   void buildMetisGraphLevelBased(Grid3DPtr grid, int nofSegments, PartLevel level);
-   bool getPartitionCondition(Block3DPtr block, PartLevel level);
-   void distributePartitionData(Grid3DPtr grid, PartLevel level);
+   void collectData(std::shared_ptr<Grid3D> grid, int nofSegments, PartLevel level);
+   void buildMetisGraphLevelIntersected(std::shared_ptr<Grid3D> grid, int nofSegments, PartLevel level);
+   void buildMetisGraphLevelBased(std::shared_ptr<Grid3D> grid, int nofSegments, PartLevel level);
+   bool getPartitionCondition(std::shared_ptr<Block3D> block, PartLevel level);
+   void distributePartitionData(std::shared_ptr<Grid3D> grid, PartLevel level);
    void clear();
    int  nofSegments;
    int numOfDirs;
    std::vector<int> blockID;
    std::vector<idx_t> parts;
-   CommunicatorPtr comm;
+   std::shared_ptr<Communicator> comm;
    int bundleRoot;
    int processRoot;
    int bundleID;
diff --git a/source/VirtualFluidsCore/Visitors/OverlapBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/OverlapBlockVisitor.cpp
index aa47bcb52..22112fd98 100644
--- a/source/VirtualFluidsCore/Visitors/OverlapBlockVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/OverlapBlockVisitor.cpp
@@ -1,5 +1,7 @@
 #include "OverlapBlockVisitor.h"
 #include "Grid3DSystem.h"
+#include "Block3D.h"
+#include "Grid3D.h"
 
 OverlapBlockVisitor::OverlapBlockVisitor(int levelDepth/*shut be maxGridLevel*/, bool includeNotActiveBlocks)
    :   Block3DVisitor(0, Grid3DSystem::MAXLEVEL)
diff --git a/source/VirtualFluidsCore/Visitors/OverlapBlockVisitor.h b/source/VirtualFluidsCore/Visitors/OverlapBlockVisitor.h
index e3411acc0..6fffdd607 100644
--- a/source/VirtualFluidsCore/Visitors/OverlapBlockVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/OverlapBlockVisitor.h
@@ -1,8 +1,14 @@
 #ifndef OverlapBlockVisitor_H
 #define OverlapBlockVisitor_H
 
+#include <string>
+#include <memory>
+
 #include "Block3DVisitor.h"
 
+class Grid3D;
+class Block3D;
+
 class OverlapBlockVisitor : public Block3DVisitor
 {
 public:
@@ -14,9 +20,8 @@ public:
 
    std::string getSpecificDescription();
 
-   void visit(Grid3DPtr grid, Block3DPtr block);
+   void visit(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block) override;
 
-protected:
 
 private:
    int  levelDepth;
diff --git a/source/VirtualFluidsCore/Visitors/PQueuePartitioningGridVisitor.cpp b/source/VirtualFluidsCore/Visitors/PQueuePartitioningGridVisitor.cpp
index 16c54f2d0..da1d81629 100644
--- a/source/VirtualFluidsCore/Visitors/PQueuePartitioningGridVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/PQueuePartitioningGridVisitor.cpp
@@ -1,9 +1,12 @@
 #include "PQueuePartitioningGridVisitor.h"
-#include "PriorityQueueDecompositor.h"
+
 #include <vector>
-#include <boost/foreach.hpp>
 
-using namespace std;
+#include "PriorityQueueDecompositor.h"
+#include "Grid3D.h"
+#include "Block3D.h"
+#include "UbLogger.h"
+
 
 PQueuePartitioningGridVisitor::PQueuePartitioningGridVisitor(int numOfParts) : numOfParts(numOfParts)
 {
@@ -13,9 +16,9 @@ PQueuePartitioningGridVisitor::PQueuePartitioningGridVisitor(int numOfParts) : n
 void PQueuePartitioningGridVisitor::visit(Grid3DPtr grid)
 {
    UBLOG(logDEBUG5, "PQueuePartitioningGridVisitor::visit() - start");
-   vector<Block3DPtr> blocks;
-   vector<int> weights;
-   vector< vector <Block3DPtr> > parts;
+   std::vector<Block3DPtr> blocks;
+   std::vector<int> weights;
+   std::vector< std::vector <Block3DPtr> > parts;
    int gridRank = grid->getRank();
 
    int minInitLevel = grid->getCoarsestInitializedLevel();
@@ -23,9 +26,9 @@ void PQueuePartitioningGridVisitor::visit(Grid3DPtr grid)
 
    for(int level = minInitLevel; level<=maxInitLevel; level++)
    {
-      vector<Block3DPtr> blockVector;
+       std::vector<Block3DPtr> blockVector;
       grid->getBlocks(level, gridRank, true, blockVector);
-      BOOST_FOREACH(Block3DPtr block, blockVector)
+      for(Block3DPtr block : blockVector)
       {
          if (block)
          {
@@ -38,9 +41,9 @@ void PQueuePartitioningGridVisitor::visit(Grid3DPtr grid)
    dec.getDecomposition(parts);
 
    int i = 0;
-   BOOST_FOREACH(vector<Block3DPtr> p, parts)
+   for(std::vector<Block3DPtr> p : parts)
    {
-      BOOST_FOREACH(Block3DPtr block, p)
+      for(Block3DPtr block : p)
       {
          block->setPart(i);
       }
diff --git a/source/VirtualFluidsCore/Visitors/PQueuePartitioningGridVisitor.h b/source/VirtualFluidsCore/Visitors/PQueuePartitioningGridVisitor.h
index efb0c6eed..91e6260c5 100644
--- a/source/VirtualFluidsCore/Visitors/PQueuePartitioningGridVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/PQueuePartitioningGridVisitor.h
@@ -7,15 +7,19 @@
 #ifndef PQUEUEPARTITIONINGPATCHVISITOR_H 
 #define PQUEUEPARTITIONINGPATCHVISITOR_H
 
+#include <memory>
+
 #include "Grid3DVisitor.h"
 
+class Grid3D;
+
 class PQueuePartitioningGridVisitor : public Grid3DVisitor
 {
 public:
    PQueuePartitioningGridVisitor(int numOfParts);
-   void visit(Grid3DPtr grid);
 
-protected:
+   void visit(std::shared_ptr<Grid3D> grid) override;
+
 private:
    int numOfParts;
 };
diff --git a/source/VirtualFluidsCore/Visitors/RatioBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/RatioBlockVisitor.cpp
index e88520d8b..f4cad9a74 100644
--- a/source/VirtualFluidsCore/Visitors/RatioBlockVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/RatioBlockVisitor.cpp
@@ -1,5 +1,7 @@
 #include "RatioBlockVisitor.h"
 #include "Grid3DSystem.h"
+#include "Grid3D.h"
+#include "Block3D.h"
 
 RatioBlockVisitor::RatioBlockVisitor(int levelDepth, bool includeNotActiveBlocks)
    :   Block3DVisitor(0, Grid3DSystem::MAXLEVEL)
diff --git a/source/VirtualFluidsCore/Visitors/RatioBlockVisitor.h b/source/VirtualFluidsCore/Visitors/RatioBlockVisitor.h
index e25880891..f6627febb 100644
--- a/source/VirtualFluidsCore/Visitors/RatioBlockVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/RatioBlockVisitor.h
@@ -1,8 +1,14 @@
 #ifndef RatioBlockVisitor_H
 #define RatioBlockVisitor_H
 
+#include <string>
+#include <memory>
+
 #include "Block3DVisitor.h"
 
+class Grid3D;
+class Block3D;
+
 class RatioBlockVisitor : public Block3DVisitor
 {
 public:
@@ -27,11 +33,11 @@ public:
 
    std::string getSpecificDescription();
 
-   void visit(Grid3DPtr grid, Block3DPtr block);
+   void visit(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block) override;
 
 protected:
-   bool lookForExpand(Grid3DPtr grid, const int& ix1, const int& ix2, const int& ix3, const int& level);
-   bool lookForCollapse(Grid3DPtr grid, const int& ix1, const int& ix2, const int& ix3, const int& level);
+   bool lookForExpand(std::shared_ptr<Grid3D> grid, const int& ix1, const int& ix2, const int& ix3, const int& level);
+   bool lookForCollapse(std::shared_ptr<Grid3D> grid, const int& ix1, const int& ix2, const int& ix3, const int& level);
 
 private:
    int  maxLevelRatio;
diff --git a/source/VirtualFluidsCore/Visitors/RatioSmoothBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/RatioSmoothBlockVisitor.cpp
index efa836b4a..59c63eecb 100644
--- a/source/VirtualFluidsCore/Visitors/RatioSmoothBlockVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/RatioSmoothBlockVisitor.cpp
@@ -1,5 +1,7 @@
 #include "RatioSmoothBlockVisitor.h"
 #include "Grid3DSystem.h"
+#include "Block3D.h"
+#include "Grid3D.h"
 
 RatioSmoothBlockVisitor::RatioSmoothBlockVisitor(int levelDepth, bool includeNotActiveBlocks)
    :   Block3DVisitor(Grid3DSystem::MAXLEVEL, 0)
diff --git a/source/VirtualFluidsCore/Visitors/RatioSmoothBlockVisitor.h b/source/VirtualFluidsCore/Visitors/RatioSmoothBlockVisitor.h
index 247576414..c77866b80 100644
--- a/source/VirtualFluidsCore/Visitors/RatioSmoothBlockVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/RatioSmoothBlockVisitor.h
@@ -1,8 +1,13 @@
 #ifndef RatioSmoothBlockVisitor_H
 #define RatioSmoothBlockVisitor_H
 
+#include <string>
+
 #include "Block3DVisitor.h"
 
+class Grid3D;
+class Block3D;
+
 class RatioSmoothBlockVisitor : public Block3DVisitor
 {
 public:
@@ -27,11 +32,11 @@ public:
 
    std::string getSpecificDescription();
 
-   void visit(Grid3DPtr grid, Block3DPtr block);
+   void visit(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block) override;
 
 protected:
-   bool lookForExpand(Grid3DPtr grid, const int& ix1, const int& ix2, const int& ix3, const int& level);
-   bool lookForCollapse(Grid3DPtr grid, const int& ix1, const int& ix2, const int& ix3, const int& level);
+   bool lookForExpand(std::shared_ptr<Grid3D> grid, const int& ix1, const int& ix2, const int& ix3, const int& level);
+   bool lookForCollapse(std::shared_ptr<Grid3D> grid, const int& ix1, const int& ix2, const int& ix3, const int& level);
 
 private:
    int  maxLevelRatio;
diff --git a/source/VirtualFluidsCore/Visitors/RefineAroundGbObjectHelper.cpp b/source/VirtualFluidsCore/Visitors/RefineAroundGbObjectHelper.cpp
index c9a0c017e..30a6973f7 100644
--- a/source/VirtualFluidsCore/Visitors/RefineAroundGbObjectHelper.cpp
+++ b/source/VirtualFluidsCore/Visitors/RefineAroundGbObjectHelper.cpp
@@ -4,7 +4,9 @@
 #include "OverlapBlockVisitor.h"
 #include "SetInterpolationDirsBlockVisitor.h"
 #include <D3Q27System.h>
-
+#include <Grid3D.h>
+#include <D3Q27TriFaceMeshInteractor.h>
+#include "Communicator.h"
 
 RefineAroundGbObjectHelper::RefineAroundGbObjectHelper(Grid3DPtr grid, int refineLevel, D3Q27TriFaceMeshInteractorPtr objectIter, double startDistance, double stopDistance, CommunicatorPtr comm) :
    grid(grid),
diff --git a/source/VirtualFluidsCore/Visitors/RefineAroundGbObjectHelper.h b/source/VirtualFluidsCore/Visitors/RefineAroundGbObjectHelper.h
index 0aff400e4..cade52ba3 100644
--- a/source/VirtualFluidsCore/Visitors/RefineAroundGbObjectHelper.h
+++ b/source/VirtualFluidsCore/Visitors/RefineAroundGbObjectHelper.h
@@ -1,10 +1,11 @@
 #ifndef RefineAroundGbObjectHelper_H
 #define RefineAroundGbObjectHelper_H
 
-#include <vector>
+#include <memory>
 
-#include <Grid3D.h>
-#include <D3Q27TriFaceMeshInteractor.h>
+class Grid3D;
+class Communicator;
+class D3Q27TriFaceMeshInteractor;
 
 //! \brief Refine blocks on base of bounding boxes.
 //! \details You need to use <i>addGbObject()</i> to add corresponding bounding boxes. Then call <i>refine()</i>.
@@ -18,16 +19,16 @@ public:
    //! \param objectIter a D3Q27TriFaceMeshInteractor object - represent geometry which should be refinement
    //! \param startDistance start distance from geometry for refinement
    //! \param stopDistance stop distance from geometry for refinement
-   RefineAroundGbObjectHelper(Grid3DPtr grid, int maxRefineLevel, D3Q27TriFaceMeshInteractorPtr objectIter, double startDistance, double stopDistance, CommunicatorPtr comm);
+   RefineAroundGbObjectHelper(std::shared_ptr<Grid3D> grid, int maxRefineLevel, std::shared_ptr<D3Q27TriFaceMeshInteractor> objectIter, double startDistance, double stopDistance, std::shared_ptr<Communicator> comm);
    virtual ~RefineAroundGbObjectHelper(void);
    //! start refinement
    void refine();
 private:
-   Grid3DPtr grid;
-   D3Q27TriFaceMeshInteractorPtr objectIter;
+    std::shared_ptr<Grid3D> grid;
+    std::shared_ptr<D3Q27TriFaceMeshInteractor> objectIter;
    int refineLevel;
    double startDistance, stopDistance;
-   CommunicatorPtr comm;
+   std::shared_ptr<Communicator> comm;
 };
 
 #endif 
diff --git a/source/VirtualFluidsCore/Visitors/RefineCrossAndInsideGbObjectBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/RefineCrossAndInsideGbObjectBlockVisitor.cpp
index ffbeaea0d..e5215764a 100644
--- a/source/VirtualFluidsCore/Visitors/RefineCrossAndInsideGbObjectBlockVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/RefineCrossAndInsideGbObjectBlockVisitor.cpp
@@ -1,5 +1,10 @@
 #include "RefineCrossAndInsideGbObjectBlockVisitor.h"
 
+#include <numerics/geometry3d/GbObject3D.h>
+#include "Grid3D.h"
+#include "Block3D.h"
+
+
 RefineCrossAndInsideGbObjectBlockVisitor::RefineCrossAndInsideGbObjectBlockVisitor()
 :  Block3DVisitor() , notActive(true)
 {
diff --git a/source/VirtualFluidsCore/Visitors/RefineCrossAndInsideGbObjectBlockVisitor.h b/source/VirtualFluidsCore/Visitors/RefineCrossAndInsideGbObjectBlockVisitor.h
index 765c8cbfb..e237ce7ab 100644
--- a/source/VirtualFluidsCore/Visitors/RefineCrossAndInsideGbObjectBlockVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/RefineCrossAndInsideGbObjectBlockVisitor.h
@@ -1,8 +1,14 @@
 #ifndef RefineCrossAndInsideGbObjectBlockVisitor_H
 #define RefineCrossAndInsideGbObjectBlockVisitor_H
 
+#include <vector>
+#include <memory>
+
 #include "Block3DVisitor.h"
-#include <numerics/geometry3d/GbObject3D.h>
+
+class Grid3D;
+class Block3D;
+class GbObject3D;
 
 //! \brief Refine blocks on base of bounding box which is defined with <i>geoObject</i>
 //! \details The class uses a geometry object for define a bounding box. Inside and across this bounding box will be grid on block basis refinement.
@@ -15,12 +21,12 @@ public:
    //! A constructor
    //! \param geoObject a smart pointer to bounding box
    //! \param refineLevel an integer for refine on this level
-   RefineCrossAndInsideGbObjectBlockVisitor(GbObject3DPtr geoObject, int refineLevel);
+   RefineCrossAndInsideGbObjectBlockVisitor(std::shared_ptr<GbObject3D> geoObject, int refineLevel);
    virtual ~RefineCrossAndInsideGbObjectBlockVisitor();
-   void visit(Grid3DPtr grid, Block3DPtr block);
-   //////////////////////////////////////////////////////////////////////////
+
+   void visit(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block) override;
 protected:
-   GbObject3DPtr geoObject;
+    std::shared_ptr<GbObject3D> geoObject;
    bool notActive;
 };
 
diff --git a/source/VirtualFluidsCore/Visitors/RefineCrossAndInsideGbObjectHelper.cpp b/source/VirtualFluidsCore/Visitors/RefineCrossAndInsideGbObjectHelper.cpp
index e5f30bbe7..cc75802b5 100644
--- a/source/VirtualFluidsCore/Visitors/RefineCrossAndInsideGbObjectHelper.cpp
+++ b/source/VirtualFluidsCore/Visitors/RefineCrossAndInsideGbObjectHelper.cpp
@@ -6,6 +6,9 @@
 #include "OverlapBlockVisitor.h"
 #include "SetInterpolationDirsBlockVisitor.h"
 #include <D3Q27System.h>
+#include "Communicator.h"
+#include <Grid3D.h>
+#include <GbObject3D.h>
 
 
 RefineCrossAndInsideGbObjectHelper::RefineCrossAndInsideGbObjectHelper(Grid3DPtr grid, int maxRefineLevel, CommunicatorPtr comm) :
diff --git a/source/VirtualFluidsCore/Visitors/RefineCrossAndInsideGbObjectHelper.h b/source/VirtualFluidsCore/Visitors/RefineCrossAndInsideGbObjectHelper.h
index d63481f79..c34c63639 100644
--- a/source/VirtualFluidsCore/Visitors/RefineCrossAndInsideGbObjectHelper.h
+++ b/source/VirtualFluidsCore/Visitors/RefineCrossAndInsideGbObjectHelper.h
@@ -2,9 +2,11 @@
 #define RefineCrossAndInsideGbObjectHelper_H
 
 #include <vector>
+#include <memory>
 
-#include <Grid3D.h>
-#include <GbObject3D.h>
+class Communicator;
+class Grid3D;
+class GbObject3D;
 
 //! \brief Refine blocks on base of bounding boxes.
 //! \details You need to use <i>addGbObject()</i> to add corresponding bounding boxes. Then call <i>refine()</i>.
@@ -15,20 +17,20 @@ public:
    //! Constructor
    //! \param grid a smart pointer to the grid object
    //! \param maxRefineLevel an integer for maximal refinement level
-   RefineCrossAndInsideGbObjectHelper(Grid3DPtr grid, int maxRefineLevel, CommunicatorPtr comm);
-   virtual ~RefineCrossAndInsideGbObjectHelper(void);
+   RefineCrossAndInsideGbObjectHelper(std::shared_ptr<Grid3D> grid, int maxRefineLevel, std::shared_ptr<Communicator> comm);
+   virtual ~RefineCrossAndInsideGbObjectHelper();
    //! add geometric object
    //! \param object a smart pointer to bounding box
    //! \param refineLevel a value of refinement level for corresponding bounding box
-   void addGbObject(GbObject3DPtr object, int refineLevel);
+   void addGbObject(std::shared_ptr<GbObject3D> object, int refineLevel);
    //! start refinement
    void refine();
 private:
-   Grid3DPtr grid;
-   std::vector<GbObject3DPtr> objects;
+    std::shared_ptr<Grid3D> grid;
+   std::vector<std::shared_ptr<GbObject3D> > objects;
    std::vector<int> levels;
    int maxRefineLevel;
-   CommunicatorPtr comm;
+   std::shared_ptr<Communicator> comm;
 };
 
 #endif 
diff --git a/source/VirtualFluidsCore/Visitors/RefineInterGbObjectsVisitor.cpp b/source/VirtualFluidsCore/Visitors/RefineInterGbObjectsVisitor.cpp
index 0ae9f76ad..4574bdf50 100644
--- a/source/VirtualFluidsCore/Visitors/RefineInterGbObjectsVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/RefineInterGbObjectsVisitor.cpp
@@ -1,5 +1,10 @@
 #include "RefineInterGbObjectsVisitor.h"
 
+#include <numerics/geometry3d/GbObject3D.h>
+#include "Grid3D.h"
+#include "Block3D.h"
+
+
 RefineInterGbObjectsBlockVisitor::RefineInterGbObjectsBlockVisitor() 
    : Block3DVisitor(-1, -1)
 {
diff --git a/source/VirtualFluidsCore/Visitors/RefineInterGbObjectsVisitor.h b/source/VirtualFluidsCore/Visitors/RefineInterGbObjectsVisitor.h
index fa90f34ca..39e20699b 100644
--- a/source/VirtualFluidsCore/Visitors/RefineInterGbObjectsVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/RefineInterGbObjectsVisitor.h
@@ -2,22 +2,26 @@
 #define RefineInterGbObjectsVisirtor_H
 
 #include <vector>
+#include <memory>
 
 #include "Block3DVisitor.h"
-#include <numerics/geometry3d/GbObject3D.h>
+
+class Grid3D;
+class Block3D;
+class GbObject3D;
 
 //////////////////////////////////////////////////////////////////////////
 class RefineInterGbObjectsBlockVisitor : public Block3DVisitor
 {
 public:
    RefineInterGbObjectsBlockVisitor();
-   RefineInterGbObjectsBlockVisitor(GbObject3DPtr includeGbObject3D, GbObject3DPtr excludeGbObject3D, int startlevel, int stoplevel);
-   RefineInterGbObjectsBlockVisitor(std::vector<GbObject3DPtr> includeGbObjects3D, std::vector<GbObject3DPtr> excludeGbObjects3D, int startlevel, int stoplevel);
-   void visit(Grid3DPtr grid, Block3DPtr block);
+   RefineInterGbObjectsBlockVisitor(std::shared_ptr<GbObject3D> includeGbObject3D, std::shared_ptr<GbObject3D> excludeGbObject3D, int startlevel, int stoplevel);
+   RefineInterGbObjectsBlockVisitor(std::vector<std::shared_ptr<GbObject3D> > includeGbObjects3D, std::vector<std::shared_ptr<GbObject3D> > excludeGbObjects3D, int startlevel, int stoplevel);
+   void visit(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block) override;
 
 private:
-   std::vector<GbObject3DPtr> includeGbObjects3D;
-   std::vector<GbObject3DPtr> excludeGbObjects3D;
+   std::vector<std::shared_ptr<GbObject3D> > includeGbObjects3D;
+   std::vector<std::shared_ptr<GbObject3D> > excludeGbObjects3D;
 };
 
 #endif //RefineInterGbObjectsVisirtor_H
diff --git a/source/VirtualFluidsCore/Visitors/RenumberBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/RenumberBlockVisitor.cpp
index 8e6a8e42e..c50a944cf 100644
--- a/source/VirtualFluidsCore/Visitors/RenumberBlockVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/RenumberBlockVisitor.cpp
@@ -1,6 +1,8 @@
 #include "RenumberBlockVisitor.h"
 #include "Grid3DSystem.h"
 #include "LBMSystem.h"
+#include "Grid3D.h"
+#include "Block3D.h"
 
 int RenumberBlockVisitor::counter = 0;
 
diff --git a/source/VirtualFluidsCore/Visitors/RenumberBlockVisitor.h b/source/VirtualFluidsCore/Visitors/RenumberBlockVisitor.h
index ecf37dab7..1d827eee1 100644
--- a/source/VirtualFluidsCore/Visitors/RenumberBlockVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/RenumberBlockVisitor.h
@@ -9,7 +9,9 @@
 #define RenumberBlockVisitor_h
 
 #include "Block3DVisitor.h"
-#include "LBMKernel.h"
+
+class Grid3D;
+class Block3D;
 
 //! \brief  Visitor class which renumber blocks.
 //! \details Visitor class which renumber blocks.            
@@ -21,7 +23,7 @@ public:
 
    virtual ~RenumberBlockVisitor() {}
 
-   virtual void visit(Grid3DPtr grid, Block3DPtr block);
+   void visit(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block) override;
 
 private:
    static int counter;
diff --git a/source/VirtualFluidsCore/Visitors/SetConnectorsBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/SetConnectorsBlockVisitor.cpp
index 4b0453a8a..847672b2f 100644
--- a/source/VirtualFluidsCore/Visitors/SetConnectorsBlockVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/SetConnectorsBlockVisitor.cpp
@@ -6,6 +6,9 @@
 #include "Grid3DSystem.h"
 #include <basics/transmitter/TbTransmitterLocal.h>
 
+#include "Communicator.h"
+#include "InterpolationProcessor.h"
+
 SetConnectorsBlockVisitor::SetConnectorsBlockVisitor(CommunicatorPtr comm, bool fullConnector, int dirs, 
 															   LBMReal nue, InterpolationProcessorPtr iProcessor) :
 Block3DVisitor(0, Grid3DSystem::MAXLEVEL), 
diff --git a/source/VirtualFluidsCore/Visitors/SetConnectorsBlockVisitor.h b/source/VirtualFluidsCore/Visitors/SetConnectorsBlockVisitor.h
index 9cf6b700b..4fd66a83a 100644
--- a/source/VirtualFluidsCore/Visitors/SetConnectorsBlockVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/SetConnectorsBlockVisitor.h
@@ -1,23 +1,29 @@
 #ifndef SETCONNECTORSBLOCKVISITOR_H
 #define SETCONNECTORSBLOCKVISITOR_H
 
+#include <memory>
+
 #include "Block3DVisitor.h"
 #include "D3Q27System.h"
-#include "Communicator.h"
-#include "InterpolationProcessor.h"
+
 #include "CreateTransmittersHelper.h"
 
+class Grid3D;
+class Block3D;
+class Communicator;
+class InterpolationProcessor;
+
 class SetConnectorsBlockVisitor : public Block3DVisitor
 {
 public:
-	SetConnectorsBlockVisitor(CommunicatorPtr comm, bool fullConnector, int dirs, LBMReal nue, InterpolationProcessorPtr iProcessor);
+	SetConnectorsBlockVisitor(std::shared_ptr<Communicator> comm, bool fullConnector, int dirs, LBMReal nue, std::shared_ptr<InterpolationProcessor> iProcessor);
 	virtual ~SetConnectorsBlockVisitor();
-	void visit(Grid3DPtr grid, Block3DPtr block);
+	void visit(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block) override;
 	//////////////////////////////////////////////////////////////////////////
 protected:
-	void setSameLevelConnectors(Grid3DPtr grid, Block3DPtr block);
+	void setSameLevelConnectors(std::shared_ptr<Grid3D> grid, Block3DPtr block);
 	void setRemoteConnectors(Block3DPtr sblock, Block3DPtr tblock, int dir, bool fullConnector);
-	void setInterpolationConnectors(Grid3DPtr grid, Block3DPtr block);
+	void setInterpolationConnectors(std::shared_ptr<Grid3D> grid, Block3DPtr block);
 	void setInterpolationConnectors(Block3DPtr fBlockSW, Block3DPtr fBlockSE, Block3DPtr fBlockNW, Block3DPtr fBlockNE, Block3DPtr cBlock, int dir);
 	void createTransmitters(Block3DPtr cBlock, Block3DPtr fBlock, int dir,
       CreateTransmittersHelper::IBlock ib,
@@ -25,12 +31,12 @@ protected:
 		CreateTransmittersHelper::TransmitterPtr& receiverCF, 
 		CreateTransmittersHelper::TransmitterPtr& senderFC, 
 		CreateTransmittersHelper::TransmitterPtr& receiverFC);
-	CommunicatorPtr comm;
+    std::shared_ptr<Communicator> comm;
 	bool fullConnector;
 	int dirs;
 	int gridRank;
 	LBMReal nue;
-	InterpolationProcessorPtr iProcessor;
+    std::shared_ptr<InterpolationProcessor> iProcessor;
 };
 
 #endif //D3Q27SETCONNECTORSVISITOR_H
diff --git a/source/VirtualFluidsCore/Visitors/SetForcingBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/SetForcingBlockVisitor.cpp
index a83046c5c..91949cf48 100644
--- a/source/VirtualFluidsCore/Visitors/SetForcingBlockVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/SetForcingBlockVisitor.cpp
@@ -1,6 +1,8 @@
 #include "SetForcingBlockVisitor.h"
 #include "Grid3DSystem.h"
 #include "LBMSystem.h"
+#include "Grid3D.h"
+#include "Block3D.h"
 
 SetForcingBlockVisitor::SetForcingBlockVisitor(LBMReal forcingX1, LBMReal forcingX2, LBMReal forcingX3) : 
                         Block3DVisitor(0, Grid3DSystem::MAXLEVEL), forcingX1(forcingX1), 
@@ -30,33 +32,37 @@ SetForcingBlockVisitor::SetForcingBlockVisitor(const std::string& sForcingX1, co
 //////////////////////////////////////////////////////////////////////////
 void SetForcingBlockVisitor::visit(Grid3DPtr grid, Block3DPtr block)
 {
+    LBMKernelPtr kernel = std::dynamic_pointer_cast<LBMKernel>(block->getKernel());
+    if (!kernel)
+        throw std::runtime_error("SetForcingBlockVisitor: Kernel is not a LBMKernel");
+
    if(block->getRank() == grid->getRank())
    {
       switch (ftype)
       {
       case 0:
-         block->getKernel()->setForcingX1(forcingX1);
-         block->getKernel()->setForcingX2(forcingX2);
-         block->getKernel()->setForcingX3(forcingX3);
-         block->getKernel()->setWithForcing(true);
+         kernel->setForcingX1(forcingX1);
+         kernel->setForcingX2(forcingX2);
+         kernel->setForcingX3(forcingX3);
+         kernel->setWithForcing(true);
          break;
       case 1:
-         block->getKernel()->setForcingX1(muForcingX1);
-         block->getKernel()->setForcingX2(muForcingX2);
-         block->getKernel()->setForcingX3(muForcingX3);
-         block->getKernel()->setWithForcing(true);
+         kernel->setForcingX1(muForcingX1);
+         kernel->setForcingX2(muForcingX2);
+         kernel->setForcingX3(muForcingX3);
+         kernel->setWithForcing(true);
          break;
       case 2:
-         block->getKernel()->setForcingX1(sForcingX1);
-         block->getKernel()->setForcingX2(sForcingX2);
-         block->getKernel()->setForcingX3(sForcingX3);
-         block->getKernel()->setWithForcing(true);
+         kernel->setForcingX1(sForcingX1);
+         kernel->setForcingX2(sForcingX2);
+         kernel->setForcingX3(sForcingX3);
+         kernel->setWithForcing(true);
          break;
       default:
-         block->getKernel()->setForcingX1(0.0);
-         block->getKernel()->setForcingX2(0.0);
-         block->getKernel()->setForcingX3(0.0);
-         block->getKernel()->setWithForcing(false);
+         kernel->setForcingX1(0.0);
+         kernel->setForcingX2(0.0);
+         kernel->setForcingX3(0.0);
+         kernel->setWithForcing(false);
          break;
       }
    }
diff --git a/source/VirtualFluidsCore/Visitors/SetForcingBlockVisitor.h b/source/VirtualFluidsCore/Visitors/SetForcingBlockVisitor.h
index b269b7aaf..4426dfedd 100644
--- a/source/VirtualFluidsCore/Visitors/SetForcingBlockVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/SetForcingBlockVisitor.h
@@ -4,6 +4,9 @@
 #include "Block3DVisitor.h"
 #include "LBMKernel.h"
 
+class Block3D;
+class Grid3D;
+
 //! \brief Set forcing for all kernels of grid
 //! \details This visitor is useful if you need to set or reset forcing in kernels (e.g. after restart because forcing is not serializable). 
 //! \author K. Kucher
@@ -18,7 +21,7 @@ public:
 
    virtual ~SetForcingBlockVisitor() {}
 
-   virtual void visit(Grid3DPtr grid, Block3DPtr block);
+   virtual void visit(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block) override;
 
 private:
    int ftype;
diff --git a/source/VirtualFluidsCore/Visitors/SetInterpolationDirsBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/SetInterpolationDirsBlockVisitor.cpp
index 89038d92d..f4f0ccfa2 100644
--- a/source/VirtualFluidsCore/Visitors/SetInterpolationDirsBlockVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/SetInterpolationDirsBlockVisitor.cpp
@@ -1,7 +1,9 @@
 #include "SetInterpolationDirsBlockVisitor.h"
 #include "Grid3DSystem.h"
 #include <D3Q27System.h>
-#include <boost/foreach.hpp>
+#include "Grid3D.h"
+#include "Block3D.h"
+
 
 SetInterpolationDirsBlockVisitor::SetInterpolationDirsBlockVisitor(std::vector<int>& dirs) : 
    Block3DVisitor(0, Grid3DSystem::MAXLEVEL), dirs(dirs)
@@ -22,7 +24,7 @@ void SetInterpolationDirsBlockVisitor::visit(Grid3DPtr grid, Block3DPtr block)
    Block3DPtr parentblock = grid->getSuperBlock(ix1,ix2,ix3,level);
    if(!parentblock) return;
 
-   BOOST_FOREACH(int dir, dirs)
+   for(int dir : dirs)
    {
       Block3DPtr nblock = grid->getNeighborBlock(dir, ix1, ix2, ix3, level);
       if(!nblock)
diff --git a/source/VirtualFluidsCore/Visitors/SetInterpolationDirsBlockVisitor.h b/source/VirtualFluidsCore/Visitors/SetInterpolationDirsBlockVisitor.h
index 820ce1769..39229a98b 100644
--- a/source/VirtualFluidsCore/Visitors/SetInterpolationDirsBlockVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/SetInterpolationDirsBlockVisitor.h
@@ -1,9 +1,13 @@
 #ifndef SetInterpolationDirsBlockVisitor_h
 #define SetInterpolationDirsBlockVisitor_h
 
+#include <vector>
+#include <memory>
+
 #include "Block3DVisitor.h"
-#include "LBMKernel.h"
 
+class Grid3D;
+class Block3D;
 
 class SetInterpolationDirsBlockVisitor : public Block3DVisitor
 {
@@ -12,12 +16,12 @@ public:
 
    virtual ~SetInterpolationDirsBlockVisitor() {}
 
-   virtual void visit(Grid3DPtr grid, Block3DPtr block);
+   void visit(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block) override;
 
 private:
    std::vector<int> dirs;
-   void checkFlagDir(Grid3DPtr grid, int dir1, int dir2, bool &flagDirection, int ix1, int ix2, int ix3, int level);
-   void checkFlagDir(Grid3DPtr grid, int dir1, int dir2, int dir3, bool &flagDirection, int ix1, int ix2, int ix3, int level);
+   void checkFlagDir(std::shared_ptr<Grid3D> grid, int dir1, int dir2, bool &flagDirection, int ix1, int ix2, int ix3, int level);
+   void checkFlagDir(std::shared_ptr<Grid3D> grid, int dir1, int dir2, int dir3, bool &flagDirection, int ix1, int ix2, int ix3, int level);
 };
 
 #endif
diff --git a/source/VirtualFluidsCore/Visitors/SetKernelBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/SetKernelBlockVisitor.cpp
index 598ec67e1..7db7f1699 100644
--- a/source/VirtualFluidsCore/Visitors/SetKernelBlockVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/SetKernelBlockVisitor.cpp
@@ -1,6 +1,11 @@
 #include "SetKernelBlockVisitor.h"
 #include "Grid3DSystem.h"
 #include "LBMSystem.h"
+#include "DataSet3D.h"
+#include "BCProcessor.h"
+#include "Grid3D.h"
+#include "Block3D.h"
+#include "LBMKernel.h"
 
 //SetKernelBlockVisitor::SetKernelBlockVisitor(LBMKernel3DPtr kernel, LBMReal nue) : 
 //                        Block3DVisitor(0, Grid3DSystem::MAXLEVEL), kernel(kernel), nue(nue)
diff --git a/source/VirtualFluidsCore/Visitors/SetKernelBlockVisitor.h b/source/VirtualFluidsCore/Visitors/SetKernelBlockVisitor.h
index cb3921b39..96c427eed 100644
--- a/source/VirtualFluidsCore/Visitors/SetKernelBlockVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/SetKernelBlockVisitor.h
@@ -1,29 +1,33 @@
 #ifndef SetKernelBlockVisitor_h
 #define SetKernelBlockVisitor_h
 
+#include <memory>
+
 #include "Block3DVisitor.h"
-#include "LBMKernel.h"
+#include "LBMSystem.h"
 
+class Grid3D;
+class Block3D;
+class LBMKernel;
 
 class SetKernelBlockVisitor : public Block3DVisitor
 {
 public:
    enum Action { NewKernel, ChangeKernel, ChangeKernelWithData};
-public:
+
    //SetKernelBlockVisitor(LBMKernel3DPtr kernel, LBMReal nue);
    
    //SetKernelBlockVisitor(LBMKernel3DPtr kernel, LBMReal nue, double availMem, double needMem);
 
-   SetKernelBlockVisitor(LBMKernelPtr kernel, LBMReal nue, double availMem, double needMem, SetKernelBlockVisitor::Action action = SetKernelBlockVisitor::NewKernel);
-
+   SetKernelBlockVisitor(std::shared_ptr<LBMKernel> kernel, LBMReal nue, double availMem, double needMem, SetKernelBlockVisitor::Action action = SetKernelBlockVisitor::NewKernel);
    virtual ~SetKernelBlockVisitor() {}
 
-   virtual void visit(Grid3DPtr grid, Block3DPtr block);
+   void visit(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block) override;
 
    void setNoDataSetFlag(bool flag);
 
 private:
-   LBMKernelPtr kernel;
+   std::shared_ptr<LBMKernel> kernel;
    LBMReal nue;
    Action action;
    bool dataSetFlag;
diff --git a/source/VirtualFluidsCore/Visitors/SetSolidBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/SetSolidBlockVisitor.cpp
index b4a155875..82bff0662 100644
--- a/source/VirtualFluidsCore/Visitors/SetSolidBlockVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/SetSolidBlockVisitor.cpp
@@ -1,14 +1,17 @@
 #include "SetSolidBlockVisitor.h"
+
+#include "Interactor3D.h"
 #include "Grid3DSystem.h"
+#include "Grid3D.h"
+#include "Block3D.h"
 
 SetSolidBlockVisitor::SetSolidBlockVisitor(Interactor3DPtr interactor, BlockType type) : 
    Block3DVisitor(0, Grid3DSystem::MAXLEVEL), interactor(interactor),
    type(type)
 {
 
-
 }
-//////////////////////////////////////////////////////////////////////////
+
 void SetSolidBlockVisitor::visit(Grid3DPtr grid, Block3DPtr block)
 {
    if(block->getRank() == grid->getRank())
@@ -17,10 +20,10 @@ void SetSolidBlockVisitor::visit(Grid3DPtr grid, Block3DPtr block)
       {
          switch (type)
          {
-         case SOLID:
+         case BlockType::SOLID:
             interactor->setSolidBlock(block);
             break;
-         case BC:
+         case BlockType::BC:
             interactor->setBCBlock(block);
             break;
          }
diff --git a/source/VirtualFluidsCore/Visitors/SetSolidBlockVisitor.h b/source/VirtualFluidsCore/Visitors/SetSolidBlockVisitor.h
index e0cef4dce..b456446fd 100644
--- a/source/VirtualFluidsCore/Visitors/SetSolidBlockVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/SetSolidBlockVisitor.h
@@ -1,23 +1,26 @@
-#ifndef SetSolidOrTransBlockVisitor_h
-#define SetSolidOrTransBlockVisitor_h
+#ifndef SET_SOLID_OR_TRANS_BLOCK_VISITOR_H
+#define SET_SOLID_OR_TRANS_BLOCK_VISITOR_H
+
+#include <memory>
 
 #include "Block3DVisitor.h"
-#include "Interactor3D.h"
 
+class Grid3D;
+class Block3D;
+class Interactor3D;
+
+enum class BlockType { SOLID, BC };
 
 class SetSolidBlockVisitor : public Block3DVisitor
 {
 public:
-   enum BlockType{SOLID, BC};
-public:
-   SetSolidBlockVisitor(Interactor3DPtr interactor, BlockType type);
-
+   SetSolidBlockVisitor(std::shared_ptr<Interactor3D> interactor, BlockType type);
    virtual ~SetSolidBlockVisitor() {}
 
-   virtual void visit(Grid3DPtr grid, Block3DPtr block);
+   virtual void visit(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block);
 
 private:
-   Interactor3DPtr interactor;
+    std::shared_ptr<Interactor3D> interactor;
    BlockType type;
 };
 
diff --git a/source/VirtualFluidsCore/Visitors/SetSpongeLayerBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/SetSpongeLayerBlockVisitor.cpp
index f85d6d8b6..6ace632a1 100644
--- a/source/VirtualFluidsCore/Visitors/SetSpongeLayerBlockVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/SetSpongeLayerBlockVisitor.cpp
@@ -2,6 +2,10 @@
 #include "Grid3DSystem.h"
 #include "LBMSystem.h"
 
+#include "LBMKernel.h"
+#include "Grid3D.h"
+#include "Block3D.h"
+
 SetSpongeLayerBlockVisitor::SetSpongeLayerBlockVisitor( const mu::Parser& spongeLayer ) : Block3DVisitor(0, Grid3DSystem::MAXLEVEL), spongeLayer(spongeLayer)
 {
 
@@ -16,8 +20,11 @@ void SetSpongeLayerBlockVisitor::visit( Grid3DPtr grid, Block3DPtr block )
 {
    if(block->getRank() == grid->getRank())
    {
-      block->getKernel()->setWithSpongeLayer(true);
-      block->getKernel()->setSpongeLayer(spongeLayer);
+       LBMKernelPtr kernel = std::dynamic_pointer_cast<LBMKernel>(block->getKernel());
+       if (!kernel)
+           throw std::runtime_error("SetSpongeLayerBlockVisitor: Kernel is not a LBMKernel");
+      kernel->setWithSpongeLayer(true);
+      kernel->setSpongeLayer(spongeLayer);
    }
 }
 
diff --git a/source/VirtualFluidsCore/Visitors/SetSpongeLayerBlockVisitor.h b/source/VirtualFluidsCore/Visitors/SetSpongeLayerBlockVisitor.h
index baf3ff782..df0633dac 100644
--- a/source/VirtualFluidsCore/Visitors/SetSpongeLayerBlockVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/SetSpongeLayerBlockVisitor.h
@@ -1,19 +1,25 @@
 #ifndef SetSpongeLayerBlockVisitor_h__
 #define SetSpongeLayerBlockVisitor_h__
 
+#include <memory>
+
+#include <MuParser/include/muParser.h>
+
 #include "Block3DVisitor.h"
-#include "LBMKernel.h"
+
+class Grid3D;
+class Block3D;
 
 //! \brief Set sponge layer for all kernels of grid
 //! \details This visitor is useful if you need to set or reset sponge layer in kernels (e.g. after restart because sponge layer is not serializable). 
 //! \author K. Kucher
-
 class SetSpongeLayerBlockVisitor : public Block3DVisitor
 {
 public:
    SetSpongeLayerBlockVisitor(const mu::Parser& spongeLayer);
    virtual ~SetSpongeLayerBlockVisitor();
-   virtual void visit(Grid3DPtr grid, Block3DPtr block);
+
+   void visit(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block) override;
 protected:
 private:
    mu::Parser spongeLayer;
diff --git a/source/VirtualFluidsCore/Visitors/SetUndefinedNodesBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/SetUndefinedNodesBlockVisitor.cpp
index 2e5ecad3b..b04434787 100644
--- a/source/VirtualFluidsCore/Visitors/SetUndefinedNodesBlockVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/SetUndefinedNodesBlockVisitor.cpp
@@ -4,8 +4,11 @@
 #include "BCProcessor.h"
 #include "Grid3DSystem.h"
 #include "D3Q27System.h"
+#include "BCArray3D.h"
+#include "Grid3D.h"
+#include "Block3D.h"
+#include "ILBMKernel.h"
 
-#include <boost/pointer_cast.hpp>
 
 SetUndefinedNodesBlockVisitor::SetUndefinedNodesBlockVisitor() : 
                                     Block3DVisitor(0, Grid3DSystem::MAXLEVEL) 
@@ -17,7 +20,7 @@ void SetUndefinedNodesBlockVisitor::visit(Grid3DPtr grid, Block3DPtr block)
 {
    if(!block->hasInterpolationFlag()) return;
 
-   LBMKernelPtr kernel = block->getKernel();
+   ILBMKernelPtr kernel = block->getKernel();
 
    if(!kernel && (block->getRank() != grid->getRank())) return;
 
diff --git a/source/VirtualFluidsCore/Visitors/SetUndefinedNodesBlockVisitor.h b/source/VirtualFluidsCore/Visitors/SetUndefinedNodesBlockVisitor.h
index 4e90ab5e2..e2d5fba1e 100644
--- a/source/VirtualFluidsCore/Visitors/SetUndefinedNodesBlockVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/SetUndefinedNodesBlockVisitor.h
@@ -1,11 +1,13 @@
 #ifndef SetUndefinedNodesBlockVisitor_h
 #define SetUndefinedNodesBlockVisitor_h
 
+#include <memory>
+
 #include "Block3DVisitor.h"
-#include "LBMKernel.h"
-#include "BCArray3D.h"
-#include "BoundaryConditions.h"
-#include "BCProcessor.h"
+
+class Grid3D;
+class Block3D;
+class BCArray3D;
 
 class SetUndefinedNodesBlockVisitor : public Block3DVisitor
 {
@@ -14,9 +16,9 @@ public:
 
    virtual ~SetUndefinedNodesBlockVisitor() {}
 
-   void visit(Grid3DPtr grid, Block3DPtr block);
+   void visit(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block) override;
 
 private:
-   void setNodesUndefined( int startix1, int endix1, int startix2, int endix2, int startix3, int endix3, BCArray3DPtr bcMatix );
+   void setNodesUndefined( int startix1, int endix1, int startix2, int endix2, int startix3, int endix3, std::shared_ptr<BCArray3D> bcMatix );
 };
 #endif
diff --git a/source/VirtualFluidsCore/Visitors/SpongeLayerBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/SpongeLayerBlockVisitor.cpp
index 0249f9f64..b1890fefd 100644
--- a/source/VirtualFluidsCore/Visitors/SpongeLayerBlockVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/SpongeLayerBlockVisitor.cpp
@@ -1,39 +1,44 @@
-#include "SpongeLayerBlockVisitor.h"
-#include "Grid3DSystem.h"
-#include "LBMSystem.h"
-
-using namespace std;
-
-SpongeLayerBlockVisitor::SpongeLayerBlockVisitor(GbCuboid3DPtr boundingBox) : Block3DVisitor(0, Grid3DSystem::MAXLEVEL), boundingBox(boundingBox)
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-SpongeLayerBlockVisitor::~SpongeLayerBlockVisitor()
-{
-
-}
-//////////////////////////////////////////////////////////////////////////
-void SpongeLayerBlockVisitor::visit(Grid3DPtr grid, Block3DPtr block)
-{
-   if (block->getRank() == grid->getRank())
-   {
-      UbTupleDouble3 org = grid->getBlockWorldCoordinates(block);
-      UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
-
-      double minX1 = val<1>(org);
-      double minX2 = val<2>(org);
-      double minX3 = val<3>(org);
-      double maxX1 = val<1>(org)+val<1>(blockLengths);
-      double maxX2 = val<2>(org)+val<2>(blockLengths);
-      double maxX3 = val<3>(org)+val<3>(blockLengths);
-
-      if (boundingBox->isCellInsideGbObject3D(minX1, minX2, minX3, maxX1, maxX2, maxX3))
-      {
-         LBMKernelPtr kernel = block->getKernel();
-         kernel->setCollisionFactor(LBMSystem::calcCollisionFactor(0.01, block->getLevel()));
-      }
-   }
-}
-
-
+#include "SpongeLayerBlockVisitor.h"
+
+#include <vector>
+
+#include "Grid3DSystem.h"
+#include "LBMSystem.h"
+#include <numerics/geometry3d/GbCuboid3D.h>
+#include "Grid3D.h"
+#include "Block3D.h"
+#include "ILBMKernel.h"
+
+
+SpongeLayerBlockVisitor::SpongeLayerBlockVisitor(GbCuboid3DPtr boundingBox) : Block3DVisitor(0, Grid3DSystem::MAXLEVEL), boundingBox(boundingBox)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+SpongeLayerBlockVisitor::~SpongeLayerBlockVisitor()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void SpongeLayerBlockVisitor::visit(Grid3DPtr grid, Block3DPtr block)
+{
+    if (block->getRank() == grid->getRank())
+    {
+        UbTupleDouble3 org = grid->getBlockWorldCoordinates(block);
+        UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
+
+        double minX1 = val<1>(org);
+        double minX2 = val<2>(org);
+        double minX3 = val<3>(org);
+        double maxX1 = val<1>(org) + val<1>(blockLengths);
+        double maxX2 = val<2>(org) + val<2>(blockLengths);
+        double maxX3 = val<3>(org) + val<3>(blockLengths);
+
+        if (boundingBox->isCellInsideGbObject3D(minX1, minX2, minX3, maxX1, maxX2, maxX3))
+        {
+            ILBMKernelPtr kernel = block->getKernel();
+            kernel->setCollisionFactor(LBMSystem::calcCollisionFactor(0.01, block->getLevel()));
+        }
+    }
+}
+
diff --git a/source/VirtualFluidsCore/Visitors/SpongeLayerBlockVisitor.h b/source/VirtualFluidsCore/Visitors/SpongeLayerBlockVisitor.h
index fc7c6d328..fa3be7b8c 100644
--- a/source/VirtualFluidsCore/Visitors/SpongeLayerBlockVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/SpongeLayerBlockVisitor.h
@@ -2,22 +2,24 @@
 #define SpongeLayerBlockVisitor_h__
 
 #include "Block3DVisitor.h"
-#include "LBMKernel.h"
-#include <numerics/geometry3d/GbCuboid3D.h>
+
+class Grid3D;
+class Block3D;
+class GbCuboid3D;
 
 //! \brief Set sponge layer for all kernels of grid
 //! \details This visitor is useful if you need to set or reset sponge layer in kernels (e.g. after restart because sponge layer is not serializable). 
 //! \author K. Kutscher
-
 class SpongeLayerBlockVisitor : public Block3DVisitor
 {
 public:
-   SpongeLayerBlockVisitor(GbCuboid3DPtr boundingBox);
+   SpongeLayerBlockVisitor(std::shared_ptr<GbCuboid3D> boundingBox);
    virtual ~SpongeLayerBlockVisitor();
-   virtual void visit(Grid3DPtr grid, Block3DPtr block);
-protected:
+
+   void visit(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block) override;
+
 private:
-   GbCuboid3DPtr boundingBox;
+    std::shared_ptr<GbCuboid3D> boundingBox;
 };
 
 #endif // SetSpongeLayerBlockVisitor_h__
diff --git a/source/VirtualFluidsCore/Visitors/ViscosityBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/ViscosityBlockVisitor.cpp
index 61795457e..b3db42f8d 100644
--- a/source/VirtualFluidsCore/Visitors/ViscosityBlockVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/ViscosityBlockVisitor.cpp
@@ -1,6 +1,9 @@
 #include "ViscosityBlockVisitor.h"
 #include "Grid3DSystem.h"
 #include "LBMSystem.h"
+#include "Block3D.h"
+#include "Grid3D.h"
+#include "ILBMKernel.h"
 
 ViscosityBlockVisitor::ViscosityBlockVisitor(LBMReal nu) :
 Block3DVisitor(0, Grid3DSystem::MAXLEVEL), nu(nu)
diff --git a/source/VirtualFluidsCore/Visitors/ViscosityBlockVisitor.h b/source/VirtualFluidsCore/Visitors/ViscosityBlockVisitor.h
index d5e87fe74..0096b13b4 100644
--- a/source/VirtualFluidsCore/Visitors/ViscosityBlockVisitor.h
+++ b/source/VirtualFluidsCore/Visitors/ViscosityBlockVisitor.h
@@ -1,9 +1,13 @@
 #ifndef ViscosityBlockVisitor_h
 #define ViscosityBlockVisitor_h
 
+#include <memory>
+
 #include "Block3DVisitor.h"
-#include "LBMKernel.h"
+#include "LBMSystem.h"
 
+class Grid3D;
+class Block3D;
 
 class ViscosityBlockVisitor : public Block3DVisitor
 {
@@ -12,7 +16,7 @@ public:
 
    virtual ~ViscosityBlockVisitor() {}
 
-   virtual void visit(Grid3DPtr grid, Block3DPtr block);
+   void visit(std::shared_ptr<Grid3D> grid, std::shared_ptr<Block3D> block) override;
 
 private:
    LBMReal nu;
diff --git a/source/VirtualFluidsCore/Visitors/ZoltanPartitioningGridVisitor.cpp b/source/VirtualFluidsCore/Visitors/ZoltanPartitioningGridVisitor.cpp
index cc354f0e4..fc762d850 100644
--- a/source/VirtualFluidsCore/Visitors/ZoltanPartitioningGridVisitor.cpp
+++ b/source/VirtualFluidsCore/Visitors/ZoltanPartitioningGridVisitor.cpp
@@ -66,7 +66,7 @@ void ZoltanPartitioningGridVisitor::collectData(Grid3DPtr grid)
 
       //Verteilung von Ranks
       int rank = 0;
-      BOOST_FOREACH(Block3DPtr block, blockVector)
+      for(Block3DPtr block : blockVector)
       {
          block->setRank(rank);
          block->setPart(rank);
@@ -77,7 +77,7 @@ void ZoltanPartitioningGridVisitor::collectData(Grid3DPtr grid)
 
       int vertices = 0;
 
-      BOOST_FOREACH(Block3DPtr block, blockVector)
+      for(Block3DPtr block : blockVector)
       {
          if (block->getRank() == myRank)
          {
-- 
GitLab