diff --git a/conf/elasticity/benchmarks/LandBenchmark.conf b/conf/elasticity/benchmarks/LandBenchmark.conf
index 92164b58cae47c59a894bbe466e47f8465b73a73..6efcfcc6fc4dd03062d4c4e8daf430f5948df646 100644
--- a/conf/elasticity/benchmarks/LandBenchmark.conf
+++ b/conf/elasticity/benchmarks/LandBenchmark.conf
@@ -2,28 +2,44 @@
 ClearData = true
 # ========================================================
 # = Location of .geo files ===============================
-GeoPath = ../geo/
+#GeoPath = ../geo/
 # ========================================================
 h0=1e-4
 h_min=1e-6
+
 #logfile = AS_T4_1_deg1_gamma07
 
-activeDeformation = Quarteroni2
-g = 0.75 #gamma for updateStretch
-scale_gamma = -1.7
+# CAUTION: right now there is no possibility to use homotopy for different meshes and/or different degrees
+# enables the possibility to start homotopy for different discretizations or to test penalty choices
+multiDiscs  = 0
+# CAUTION: if useDifferentMeshes = 0, it will use the entry in Mesh!!!
+useDifferentMeshes = 0 # possibility to change meshes isn't implemented right now
+MechDiscretizationList =  Conforming,DG  # chosing different discs for homotopy
+MechPolynomialDegreeList = 1 #if there is only one entry, it usess the same degree for all discs
+MeshList = OrientedEllipsoid_2 #if there is only one entry, it usess the same mesh for all discs
+# If |DGPenaltyList| != |MechDiscretizationList| DGPenalty = 0 für fehlende Einträge
+DGPenaltyList= 0,1000,2000
+
+
+#activeDeformation = Quarteroni2
+#g = 0.75 #gamma for updateStretch
+#scale_gamma = -1.7
 #StretchFactorNormal =1
-activeStress = 0#60
+activeStress = 60 #kPa
 Model = ActiveStrainElasticity
 MechRuntype = Default
 MechDynamics = Static
-MechDiscretization = Conforming
+MechDiscretization =  Conforming#DG
+
+DGSign=-1.0
+DGPenalty= 1000# Penalty for EG=200
 
 CalculateReference = 0
-ReferenceLevel = 3
-InterpolateStartVector = true
+ReferenceLevel = 5
+InterpolateStartVector = false #true
 
 #Mesh=FullEllipsoid
-Mesh = OrientedEllipsoid_4
+Mesh = OrientedEllipsoid_2
 MechProblem = LandEllipsoid
 MechMeshPart = leftventricle
 
@@ -56,14 +72,14 @@ TractionC = 0
 #------------------------
 Incompressible = false
 QuasiCompressiblePenalty = Ciarlet
-VolumetricPenalty = 1000
+VolumetricPenalty = 1000 # 1 MPa
 
 
 ######################
 # Pressure Parameters#
 ######################
 #ConstantPressure = -10
-LVPressure = 15
+LVPressure = 15 #kPa
 RVPressure = 0
 RAPressure = 0
 LAPressure = 0
@@ -78,17 +94,17 @@ PlotCellPotential = 0
 
 # === Mechanics Solver ============================================
 MechSolver = gmres
-MechPreconditioner = SuperLU;
-MechEpsilon = 1e-8;
-MechReduction = 1e-12;
+MechPreconditioner = GaussSeidel;
+MechEpsilon = 1e-8#1e-8;
+MechReduction = 1e-5;
 MechSteps = 10000;
 
 # === Newton Method === #
-NewtonEpsilon = 1e-6
-NewtonReduction = 1e-12;
+NewtonEpsilon = 1e-4
+NewtonReduction = 1e-5;
 NewtonSteps = 200
 NewtonLineSearchSteps = 10;
-NewtonLinearizationReduction = 1e-12
+NewtonLinearizationReduction = 1e-3
 #NewtonJacobiUpdate = 8
 #NewtonDamping = 0.75
 
@@ -137,21 +153,21 @@ DynamicSolverVerbose = -1
 CoupledSolverVerbose = 2
 CellModelVerbose = -10
 
-MechVTK = 1
+MechVTK = 0
 # = Main Verbose =
 ElphyVerbose = -1
 MechVerbose = 1
 
 # = Plot Verbose =
-PlotVTK  = 1
+PlotVTK  = 0
 PlottingSteps = 1
 
 ElphySolverVTK = -1
-PressureSolverVTK = 1
+PressureSolverVTK = 0
 DynamicSolverVTK = -1
 CoupledSolverVTK = -1
 
 PrestressPlotVerbose = 0
-PressurePlotVerbose = 1
+PressurePlotVerbose = 0
 DynamicPlotVerbose = -1
 
diff --git a/conf/elasticity/benchmarks/beam.conf b/conf/elasticity/benchmarks/beam.conf
index a606258f2e41815a832b0d77b554ba5444b16c55..56fdc2c578a929be0e321a21f64486476a43d185 100644
--- a/conf/elasticity/benchmarks/beam.conf
+++ b/conf/elasticity/benchmarks/beam.conf
@@ -7,10 +7,9 @@ h_min=1e-6
 Model = ActiveStrainElasticity
 MechRuntype = Default
 MechDynamics = Static
-#MechDiscretization = DG
-MechDiscretization = Conforming
+MechDiscretization = DG #EG#Conforming
 
-CalculateReference = 1
+CalculateReference = 0
 ReferenceLevel = 1
 InterpolateStartVector = false
 
@@ -23,13 +22,13 @@ ProblemDimension = 3
 ProblemGeometry = Tet
 
 # Amount of pressure steps per iteration
-PressureSteps = 1
+PressureSteps = 10
 PressureIterations = 10
 PressureDepth = 0
 
 DebugPressure = 1
 
-MechLevel = 0
+MechLevel = 1
 MechPolynomialDegree = 1
 
 WithPrestress=false
@@ -181,14 +180,16 @@ ElphyVerbose = -1
 MechVerbose = -1
 
 # = Plot Verbose =
-MechPlot=-1
+MechPlot=1
 ElphySolverVTK = -1
-PressureSolverVTK = -1
+PressureSolverVTK = 1
 DynamicSolverVTK = -1
 CoupledSolverVTK = -1
 
 PrestressPlotVerbose = -1
-PressurePlotVerbose = -1
+PressurePlotVerbose = 1
 DynamicPlotVerbose = -1
-PlotVTK = -1
+PlotVTK = 1
+
+ParallelPlotting = 0
 
diff --git a/conf/elasticity/m++.conf b/conf/elasticity/m++.conf
index 97de08d7c08eb6a75a601a12443d6bf4b5d55e86..c100113caf546b637bda1b47e8eea51b50feddbe 100644
--- a/conf/elasticity/m++.conf
+++ b/conf/elasticity/m++.conf
@@ -11,8 +11,8 @@ ClearData = true
 #loadconf = elasticity/benchmarks/dg_beam.conf
 #loadconf = elasticity/benchmarks/eg_beam.conf
 #loadconf = elasticity/benchmarks/ellipsoid.conf
-#loadconf = elasticity/benchmarks/LandBenchmark.conf
-loadconf = elasticity/benchmarks/LandBenchmarkDG.conf
+loadconf = elasticity/benchmarks/LandBenchmark.conf
+#loadconf = elasticity/benchmarks/LandBenchmarkDG.conf
 #loadconf = elasticity/benchmarks/LandBenchmarkBiVentricle.conf
 #loadconf = elasticity/elasticity.conf
 # ======================================
diff --git a/pipeline/.cardmech-benchmark-on-horeka.yml b/pipeline/.cardmech-benchmark-on-horeka.yml
index 94f45f5c82b68a2ed738d25a2c98fc85cb05051e..8182cb668a9f7aea0f450cb4d456896fc3c0b71f 100644
--- a/pipeline/.cardmech-benchmark-on-horeka.yml
+++ b/pipeline/.cardmech-benchmark-on-horeka.yml
@@ -26,3 +26,61 @@ ellipsoid-test:
     CMAKE_ARGS: '-DMPP_BUILD_TYPE=MppRelease'
   script:
     - salloc -p cpuonly -t 00:01:00 -n 4 mpirun Elphy-M++ electrophysiology/TetraTest/start
+
+.land-benchmark_on_horeka:
+  extends: .benchmark_on_horeka
+  only:
+    variables:
+      - $BENCHMARK == $CI_JOB_NAME || $BENCHMARK == 'all' || $BENCHMARK == 'on-horeka' || $BENCHMARK == 'land-on-horeka'
+  variables:
+    CMAKE_ARGS: '-DMPP_BUILD_TYPE=MppRelease'
+
+
+
+#  extends: .land-benchmark_on_horeka
+ # script:
+#    - salloc -p cpuonly -t 00:05:00 -n 256 mpirun M++ elasticity/benchmarks/LandBenchmark MechLevel=0 MechPolynomialDegree=1 CalculateReference=0
+#    - salloc -p cpuonly -t 00:15:00 -n 256 mpirun M++ elasticity/benchmarks/LandBenchmark MechLevel=1 MechPolynomialDegree=1 CalculateReference=0
+#    - salloc -p cpuonly -t 01:00:00 -n 256 mpirun M++ elasticity/benchmarks/LandBenchmark MechLevel=2 MechPolynomialDegree=1 CalculateReference=0
+#    - salloc -p cpuonly -t 15:00:00 -n 256 mpirun M++ elasticity/benchmarks/LandBenchmark MechLevel=3 MechPolynomialDegree=1 CalculateReference=0
+  #  - salloc -p cpuonly -t 72:00:00 -n 512 -N 16 mpirun M++ elasticity/benchmarks/LandBenchmark MechLevel=4 MechPolynomialDegree=1 CalculateReference=0
+#    - salloc -p cpuonly -t 100:00:00 -n 256 mpirun M++ elasticity/benchmarks/LandBenchmark MechLevel=5 MechPolynomialDegree=1 CalculateReference=0
+
+# alle auf mehr Kernen testen
+
+#landbenchmark-deg1_ref:
+#  extends: .land-benchmark_on_horeka
+#  script:
+#    - salloc -p cpuonly -t 72:00:00 -n 256  mpirun M++ elasticity/benchmarks/LandBenchmark MechLevel=0 MechPolynomialDegree=1 CalculateReference=1 ReferenceLevel=4
+#    - salloc -p cpuonly -t 72:00:00 -n 1024 -N 16  mpirun M++ elasticity/benchmarks/LandBenchmark MechLevel=0 MechPolynomialDegree=1 CalculateReference=1 ReferenceLevel=4
+#    - salloc -p cpuonly -t 72:00:00 -n 512 -N 8 mpirun M++ elasticity/benchmarks/LandBenchmark MechLevel=0 MechPolynomialDegree=1 CalculateReference=1 ReferenceLevel=4
+#    - salloc -p cpuonly -t 72:00:00 -n 512 mpirun M++ elasticity/benchmarks/LandBenchmark MechLevel=0 MechPolynomialDegree=1 CalculateReference=1 ReferenceLevel=4
+#    - salloc -p cpuonly -t 72:00:00 -n 1024 mpirun M++ elasticity/benchmarks/LandBenchmark MechLevel=0 MechPolynomialDegree=1 CalculateReference=1 ReferenceLevel=4
+#    - salloc -p cpuonly -t 72:00:00 -n 1024 mpirun M++ elasticity/benchmarks/LandBenchmark MechLevel=0 MechPolynomialDegree=1 CalculateReference=1 ReferenceLevel=5
+
+#TODO: Zeiten anpassen
+landbenchmark-deg2:
+  extends: .land-benchmark_on_horeka
+  script:
+#    - salloc -p cpuonly -t 00:05:00 -n 256 mpirun M++ elasticity/benchmarks/LandBenchmark MechLevel=0 MechPolynomialDegree=2 CalculateReference=0
+#    - salloc -p cpuonly -t 00:15:00 -n 256 mpirun M++ elasticity/benchmarks/LandBenchmark MechLevel=1 MechPolynomialDegree=2 CalculateReference=0
+#    - salloc -p cpuonly -t 01:00:00 -n 256 mpirun M++ elasticity/benchmarks/LandBenchmark MechLevel=2 MechPolynomialDegree=2 CalculateReference=0
+#    - salloc -p cpuonly -t 72:00:00 -n 256 mpirun M++ elasticity/benchmarks/LandBenchmark MechLevel=3 MechPolynomialDegree=2 CalculateReference=0
+    - salloc -p cpuonly -t 72:00:00 -n 1024 -N 40 mpirun M++ elasticity/benchmarks/LandBenchmark MechLevel=4 MechPolynomialDegree=2 CalculateReference=0 PressureSteps=10
+#    - salloc -p cpuonly -t 72:00:00 -n 256 mpirun M++ elasticity/benchmarks/LandBenchmark MechLevel=5 MechPolynomialDegree=2 CalculateReference=0
+
+#TODO: Zeiten anpassen
+#landbenchmark-deg2_ref:
+#   extends: .land-benchmark_on_horeka
+#   script:
+#         - salloc -p cpuonly -t 72:00:00 -n 1024 -N 20 mpirun M++ elasticity/benchmarks/LandBenchmark MechLevel=0 MechPolynomialDegree=2 CalculateReference=1 ReferenceLevel=4
+#    - salloc -p cpuonly -t 72:00:00 -n 512 mpirun M++ elasticity/benchmarks/LandBenchmark MechLevel=0 MechPolynomialDegree=2 CalculateReference=1 ReferenceLevel=4
+#    - salloc -p cpuonly -t 72:00:00 -n 1024 mpirun M++ elasticity/benchmarks/LandBenchmark MechLevel=0 MechPolynomialDegree=2 CalculateReference=1 ReferenceLevel=4
+#    - salloc -p cpuonly -t 72:00:00 -n 1024 mpirun M++ elasticity/benchmarks/LandBenchmark MechLevel=0 MechPolynomialDegree=2 CalculateReference=1 ReferenceLevel=5
+
+
+EG_landbenchmark-deg1_ref:
+  extends: .land-benchmark_on_horeka
+  script:
+   # - salloc -p cpuonly -t 72:00:00 -n 1024 -N 30 mpirun M++ elasticity/benchmarks/LandBenchmark Mesh=OrientedEllipsoid_3 MechLevel=0 MechPolynomialDegree=1 CalculateReference=1 ReferenceLevel=5
+        - salloc -p cpuonly -t 72:00:00 -n 1024 -N 30 mpirun M++ elasticity/benchmarks/LandBenchmark Mesh=OrientedEllipsoid_3 MechLevel=3 MechPolynomialDegree=1 CalculateReference=0
diff --git a/src/CardMechIProblem.hpp b/src/CardMechIProblem.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1a53c04f484b9478c0291b98f86703201e63297f
--- /dev/null
+++ b/src/CardMechIProblem.hpp
@@ -0,0 +1,64 @@
+#ifndef CARDMECH_CARDMECHIPROBLEM_H
+#define CARDMECH_CARDMECHIPROBLEM_H
+
+#include "Config.hpp"
+#include "Meshes.hpp"
+#include "MeshesCreator.hpp"
+#include <memory>
+
+class CardMechIProblem {
+protected:
+  int verbose = 1;
+
+  std::string meshesName = "";
+
+  std::shared_ptr<Meshes> meshes = nullptr;
+
+  std::shared_ptr<CoarseGeometry> cGeo = nullptr;
+
+public:
+  explicit CardMechIProblem(std::string meshName = "") : meshesName(meshName) {
+    if (meshesName.empty())
+      Config::Get("Mesh", meshesName);
+    if (!meshesName.empty()) {
+      CreateMeshes(MeshesCreator(meshesName));
+    }
+    Config::Get("ProblemVerbose", verbose);
+  }
+
+  explicit CardMechIProblem(std::shared_ptr<Meshes> meshes)
+      : meshes(std::move(meshes)) {
+    Config::Get("ProblemVerbose", verbose);
+  }
+
+  explicit CardMechIProblem(CardMechIProblem &otherProblem)
+      : meshes(otherProblem.meshes), verbose(otherProblem.verbose) {}
+
+  virtual ~CardMechIProblem() = default;
+
+  virtual bool HasExactSolution() const { return false; }
+
+  void CreateMeshes(MeshesCreator meshesCreator) {
+    std::string injectedMeshName = meshesCreator.GetMeshName();
+    cGeo = CreateCoarseGeometryShared(
+        injectedMeshName.empty() ? meshesName : injectedMeshName);
+    meshes = meshesCreator.WithCoarseGeometry(cGeo).CreateShared();
+  }
+
+  const CoarseGeometry &Domain() const { return *cGeo; };
+
+  const Meshes &GetMeshes() const {
+    if (meshes == nullptr)
+      Exit("Meshes not initialized") return *meshes;
+  }
+
+  bool IsMeshInitialized() const { return meshes != nullptr; }
+
+  const Mesh &GetMesh(int level) const { return (*meshes)[level]; }
+
+  const Mesh &GetMesh(LevelPair level) const { return (*meshes)[level]; }
+
+  virtual std::string Name() const = 0;
+};
+
+#endif // CARDMECH_CARDMECHIPROBLEM_H
diff --git a/src/CardiacData.cpp b/src/CardiacData.cpp
index 6fe36143278bace00cf176bf0f210fb870d4b432..7bfc2a845a9fe6bb7a979f5b620d34e1b3e6e842 100644
--- a/src/CardiacData.cpp
+++ b/src/CardiacData.cpp
@@ -99,7 +99,7 @@ std::vector<int> getIncludedChambers(const string &chamberName) {
 #include "LagrangeDiscretization.hpp"
 
 void PlotFibreOrientation(const Vector &U, VtuPlot& plot) {
-  LagrangeDiscretization fibreDisc(U.GetDisc().GetMeshes(), 0, SpaceDimension);
+  auto fibreDisc = std::make_shared<LagrangeDiscretization>(U.GetDisc().GetMeshes(), 0, SpaceDimension);
   Vector f(0.0, fibreDisc);
   Vector s(0.0, fibreDisc);
   Vector n(0.0, fibreDisc);
diff --git a/src/CardiacInterpolation.cpp b/src/CardiacInterpolation.cpp
index 1dc9d17ed4cd675fa5c9467981d208a43728958f..c1f89bed82a00173c0f470ae6537b55912d529a4 100644
--- a/src/CardiacInterpolation.cpp
+++ b/src/CardiacInterpolation.cpp
@@ -1,6 +1,5 @@
 #include <DGDiscretization.hpp>
 #include "LagrangeDiscretization.hpp"
-#include "EGDiscretization.hpp"
 #include "MixedEGDiscretization.hpp"
 #include "MultiPartDiscretization.hpp"
 #include "CardiacInterpolation.hpp"
@@ -411,7 +410,7 @@ void smoothMeshData(const Mesh &mesh, Vector &vec) {
 
 
 void interpolateLagrangeCellData(const Meshes &meshes, Vector &vec) {
-  const auto &coarse = meshes.coarseMesh();
+  const auto &coarse = meshes.coarse();
 
   for (cell c = coarse.cells(); c != coarse.cells_end(); ++c) {
     // Fetch coarse cell corners and data
@@ -446,13 +445,13 @@ void interpolateLagrangeData(Vector &vec, int degree) {
   std::string interpolation{};
   Config::Get("ExternalCurrentSmoothingInSpace", interpolation);
   if (interpolation != "discrete" && meshes[0].Name() != "BiVentricle_smoothed" && meshes[0].Name() != "KovachevaBiventricle"&& meshes[0].Name() != "BiventricleDirichlet" && meshes[0].Name()!="KovacheveBiventricleSimpleExcitation_smooth") {
-    smoothMeshData(meshes.coarseMesh(), vec);
+    smoothMeshData(meshes.coarse(), vec);
   }
 
     InterpolateCellData(meshes);
 
   if (degree > 0) {
-    interpolateLagrangeVertexData(meshes.coarseMesh(), vec, pow(2, meshes.Level()) * degree);
+    interpolateLagrangeVertexData(meshes.coarse(), vec, pow(2, meshes.Level()) * degree);
   } else {
     interpolateLagrangeCellData(meshes, vec);
   }
@@ -464,22 +463,24 @@ void InterpolateCellData(const Meshes &meshes) {
   }
 }
 
-Vector InterpolateMeshData(const IDiscretization& disc){
+Vector InterpolateMeshData(std::shared_ptr<const IDiscretization> disc){
   Vector interpolated(0.0, disc);
-  const auto &mesh = disc.GetMeshes().coarseMesh();
+  const auto &mesh = disc->GetMeshes().coarse();
 
-  if (typeid(disc) == typeid(LagrangeDiscretization)) {
-    int d = ((const LagrangeDiscretization &) disc).Degree();
+  if (typeid(*disc) == typeid(LagrangeDiscretization)) {
+    const auto &lagrangeDisc = std::dynamic_pointer_cast<const LagrangeDiscretization>(disc);
+    int d = lagrangeDisc->Degree();
     interpolated = -100.0;
     interpolateLagrangeData(interpolated, d);
-  } else if (typeid(disc) == typeid(MultiPartDiscretization)) {
-    int d = ((const MultiPartDiscretization &) disc).Degree();
+  } else if (typeid(*disc) == typeid(MultiPartDiscretization)) {
+    const auto &multiPartDisc = std::dynamic_pointer_cast<const MultiPartDiscretization>(disc);
+    int d = multiPartDisc->Degree();
     interpolated = -100.0;
     interpolateLagrangeData(interpolated, d);
-  } else if(typeid(disc) == typeid(DGDiscretization)) {
+  } else if(typeid(*disc) == typeid(DGDiscretization)) {
     interpolated = -100.0;
     interpolateLagrangeData(interpolated, 0);
-  } else if(typeid(disc) == typeid(MixedEGDiscretization)) {
+  } else if(typeid(*disc) == typeid(MixedEGDiscretization)) {
     interpolated = -100.0;
     interpolateLagrangeData(interpolated, 0);
   } else {
@@ -487,4 +488,4 @@ Vector InterpolateMeshData(const IDiscretization& disc){
   }
 
   return interpolated;
-}
\ No newline at end of file
+}
diff --git a/src/CardiacInterpolation.hpp b/src/CardiacInterpolation.hpp
index adf837f7e1c70f66a4e8f5d6998d1c9e0ea7ef0d..3f19fb1d36a3c14f718485be0dec389e1370f85f 100644
--- a/src/CardiacInterpolation.hpp
+++ b/src/CardiacInterpolation.hpp
@@ -11,7 +11,7 @@ void InterpolateCellData(const Meshes &meshes);
  * @param disc Discretization which is used by the assemble requesting the data
  * @return A vector containing interpolated vertex data
  */
-Vector InterpolateMeshData(const IDiscretization &disc);
+Vector InterpolateMeshData(std::shared_ptr<const IDiscretization> disc);
 
 
 #endif //CARDIACINTERPOLATION_HPP
diff --git a/src/MainCardMech.cpp b/src/MainCardMech.cpp
index abb0d20f039a7c61cf29d1e4ab81ce7ef2789a2c..c37015aaa1f4fbf65a58f621619fe3d3d4325428 100644
--- a/src/MainCardMech.cpp
+++ b/src/MainCardMech.cpp
@@ -2,6 +2,7 @@
 
 #include "electrophysiology/MainMonodomain.hpp"
 #include "elasticity/MultiElasticity.hpp"
+#include "elasticity/MultiDiscElasticity.hpp"
 #include "coupled/MainCoupled.hpp"
 
 
@@ -10,10 +11,7 @@ int main(int argc, char **argv) {
   Config::SetConfPath(std::string(ProjectSourceDir) + "/conf/");
   Config::SetConfigFileName("m++.conf");
   Mpp::initialize(&argc, argv);
-
-
   Config::PrintInfo();
-
   bool clear = false;
   Config::Get("ClearData", clear);
   if (clear && PPM->master()) {
@@ -26,7 +24,9 @@ int main(int argc, char **argv) {
   Config::Get("Model", model);
 
   bool reference{false};
+  bool multiDiscs{false};
   Config::Get("CalculateReference", reference);
+  Config::Get("multiDiscs", multiDiscs);
 
   MainCardMech *cmMain;
   if (model == "Monodomain") {
@@ -36,6 +36,8 @@ int main(int argc, char **argv) {
     mout << "Starting Elasticity Suite of M++." << endl;
     if (reference)
       cmMain = new MultiElasticity();
+    else if(multiDiscs)
+      cmMain = new MultiDiscElasticity();
     else
       cmMain = new MainElasticity();
   } else if (model.find("Coupled") != std::string::npos) {
diff --git a/src/coupled/MainCoupled.cpp b/src/coupled/MainCoupled.cpp
index a72ea2195d4514e7cbda6d08516f1002e112ccc0..8215a43c44eea7e85dc13e811ce45ab70d7cd243 100644
--- a/src/coupled/MainCoupled.cpp
+++ b/src/coupled/MainCoupled.cpp
@@ -65,9 +65,9 @@ Vector &MainCoupled::Run() {
 }
 
 void MainCoupled::generateStartVectors() {
-  potential = std::make_unique<Vector>(elphyA->GetDisc());
-  stretch = std::make_unique<Vector>(elphyA->GetDisc());
-  displacement = std::make_unique<Vector>(0.0, mechA->GetDisc());
+  potential = std::make_unique<Vector>(elphyA->GetSharedDisc());
+  stretch = std::make_unique<Vector>(elphyA->GetSharedDisc());
+  displacement = std::make_unique<Vector>(0.0, mechA->GetSharedDisc());
 
   // Gets initial value of cellmodel at src/cellmodesl/*.cpp
   *potential = tensionModel->InitialValue(ELPHY);
diff --git a/src/coupled/problem/CoupledProblem.cpp b/src/coupled/problem/CoupledProblem.cpp
index e75f9677371465062e4052466ac0b6c6ac69fc17..9657a51485abc3eb68c52d34161f37fba724e435 100644
--- a/src/coupled/problem/CoupledProblem.cpp
+++ b/src/coupled/problem/CoupledProblem.cpp
@@ -66,16 +66,14 @@ const std::string &CoupledProblem::MechMeshName() const {
 void CoupledProblem::CreateElphyMesh(MeshesCreator &creator) {
   {
     elphyGeo = CreateCoarseGeometryShared(elphyMeshName);
-    elphyMeshes = creator.WithCoarseGeometry(elphyGeo).
-        WithCommSplit(ElphyProblem::commSplit).CreateShared();
+    elphyMeshes = creator.WithCoarseGeometry(elphyGeo).CreateShared();
   }
 }
 
 void CoupledProblem::CreateMechMesh(MeshesCreator &creator) {
   {
     mechGeo = CreateCoarseGeometryShared(mechMeshName);
-    mechMeshes = creator.WithCoarseGeometry(mechGeo).
-        WithCommSplit(ElasticityProblem::commSplit).CreateShared();
+    mechMeshes = creator.WithCoarseGeometry(mechGeo).CreateShared();
     InterpolateCellData(*mechMeshes);
   }
 }
diff --git a/src/coupled/problem/DeformedProblem.hpp b/src/coupled/problem/DeformedProblem.hpp
index edcaa009a10b7c26230e80fcb6c4691597507901..f08c98e0090c21e7f1a920ec121ed9df462b2bd7 100644
--- a/src/coupled/problem/DeformedProblem.hpp
+++ b/src/coupled/problem/DeformedProblem.hpp
@@ -8,7 +8,7 @@
 class DeformedCoupledProblem : public CoupledProblem {
   std::unique_ptr<CoupledProblem> originalProblem{nullptr};
   std::unique_ptr<MultiPartDeformationTransfer> transfer;
-  std::unique_ptr<IDiscretization> defDisc;
+  std::shared_ptr<IDiscretization> defDisc;
   Vector* displacement; //TODO: has to be more efficient
   Vector* displacement_old;
   std::unique_ptr<Vector> velocity;
@@ -156,11 +156,11 @@ public:
     if (!transfer) {
       if (contains(v.GetDisc().DiscName(), "MultiPart")) {
         const auto &elphyDisc = (const MultiPartDiscretization &) v.GetDisc();
-        defDisc = std::make_unique<MultiPartDiscretization>(elphyDisc, u.GetMesh().dim());
+        defDisc = std::make_shared<MultiPartDiscretization>(elphyDisc, u.GetMesh().dim());
       }
-      displacement = new Vector(0.0, *defDisc);
-      displacement_old = new Vector(0.0, *defDisc);
-      velocity = std::make_unique<Vector>(0.0, *defDisc);
+      displacement = new Vector(0.0, defDisc);
+      displacement_old = new Vector(0.0, defDisc);
+      velocity = std::make_unique<Vector>(0.0, defDisc);
       transfer = GetCardiacTransfer(u, *displacement);
       transfer->Prolongate(u, *displacement);
     }
diff --git a/src/coupled/solvers/SegregatedSolver.cpp b/src/coupled/solvers/SegregatedSolver.cpp
index 06053ab6dbb8bfd5e0dd091139b026a337d189ba..ea9fd8f3bd286f302714406220c0c02b8873d193 100644
--- a/src/coupled/solvers/SegregatedSolver.cpp
+++ b/src/coupled/solvers/SegregatedSolver.cpp
@@ -186,8 +186,6 @@ bool SegregatedSolver::Method(IElphyAssemble &elphyAssemble, IElasticity &mechAs
   return true;
 }
 
-
-
 bool SegregatedSolver::Step(IElphyAssemble &elphyAssemble, IElasticity &mechAssemble,
                             Vectors &elphyValues,
                             Vectors &mechValues) {
@@ -319,7 +317,7 @@ bool adaptiveSegregatedSolver::Step(IElphyAssemble &elphyAssemble, IElasticity &
  // Projects stretch from elphy to mech
   cardiacTransfer->Project(u_stretch(mechValues), v_stretch(elphyValues));
   mechAssemble.UpdateStretch(u_stretch(mechValues));
-  
+
 
   vout(2) << "Solving MechStep from " << mechAssemble.Time() << " to "
           << mechAssemble.NextTimeStep(false) << endl;
diff --git a/src/coupled/transfers/MultiPartTransfer.cpp b/src/coupled/transfers/MultiPartTransfer.cpp
index 3b3b680fba390b28b95d07c20b381bf34e9b470b..3f5345816fb60f04436969707299dfc1645be79b 100644
--- a/src/coupled/transfers/MultiPartTransfer.cpp
+++ b/src/coupled/transfers/MultiPartTransfer.cpp
@@ -81,9 +81,9 @@ MultiPartLagrangeTransfer::MultiPartLagrangeTransfer(const Vector &coarse, const
   mechDim = mechDisc.Size();
   elphyDim = elphyDisc.Size();
 
-  discs = std::pair<std::unique_ptr<LagrangeDiscretization>, std::unique_ptr<MultiPartDiscretization>>{
-      std::make_unique<LagrangeDiscretization>(mechDisc, mechDisc.Degree(), mechDisc.Size()),
-      std::make_unique<MultiPartDiscretization>(elphyDisc, mechDisc.Size()),
+  discs = std::pair<std::shared_ptr<LagrangeDiscretization>, std::shared_ptr<MultiPartDiscretization>>{
+      std::make_shared<LagrangeDiscretization>(mechDisc, mechDisc.Degree(), mechDisc.Size()),
+      std::make_shared<MultiPartDiscretization>(elphyDisc, mechDisc.Size()),
   };
 
   constructRowList(coarse, fine);
@@ -252,7 +252,7 @@ RMatrix MultiPartLagrangeTransfer::AsMatrix() const {
 }
 
 std::unique_ptr<Vector> MultiPartLagrangeTransfer::CreateFineDeformation() const {
-  return std::make_unique<Vector>(0.0, *discs.second);
+  return std::make_unique<Vector>(0.0, discs.second);
 }
 
 std::unique_ptr<MultiPartDeformationTransfer>
diff --git a/src/coupled/transfers/MultiPartTransfer.hpp b/src/coupled/transfers/MultiPartTransfer.hpp
index 973176d2e028dbdc1f32ad5d66140da16f1a73b6..51b253a3d5fbcdc0e6837b70a652a0dc352dcafb 100644
--- a/src/coupled/transfers/MultiPartTransfer.hpp
+++ b/src/coupled/transfers/MultiPartTransfer.hpp
@@ -47,7 +47,7 @@ class MultiPartLagrangeTransfer : public MultiPartDeformationTransfer {
   int mechDim{1};
   int elphyDim{1};
 
-  std::pair<std::unique_ptr<LagrangeDiscretization>, std::unique_ptr<MultiPartDiscretization>> discs{};
+  std::pair<std::shared_ptr<LagrangeDiscretization>, std::shared_ptr<MultiPartDiscretization>> discs{};
   RowList rowList;
 
   void constructRowList(const Vector &coarse, const Vector &fine);
diff --git a/src/elasticity/CMakeLists.txt b/src/elasticity/CMakeLists.txt
index 9b14dc9f38f745320cc4ab26e7b2e90445eb979f..c6c299770570e1530d879036c2a61a2f806cea8a 100644
--- a/src/elasticity/CMakeLists.txt
+++ b/src/elasticity/CMakeLists.txt
@@ -6,7 +6,9 @@ add_subdirectory(solvers)
 
 add_library(ELASTICITY
         MainElasticity.cpp
-        MultiElasticity.cpp)
+        MultiElasticity.cpp
+        MultiDiscElasticity.cpp
+)
 
 
 set(CM_LOG data_processing/VectorLogger.cpp
diff --git a/src/elasticity/MainElasticity.cpp b/src/elasticity/MainElasticity.cpp
index 249207644ba2a31e4812af9adbf019fb53deb45a..920d99f6836e12eec2d612130749be713bd4d549 100644
--- a/src/elasticity/MainElasticity.cpp
+++ b/src/elasticity/MainElasticity.cpp
@@ -25,13 +25,28 @@ void MainElasticity::Initialize() {
 
   generateMesh(elasticityModel);
   initAssemble();
+  generateStartVectors();
+}
 
+void MainElasticity::Initialize(std::unique_ptr<ElasticityProblem> problem) {
+  elasticityProblem = std::move(problem);
+  generateMesh(elasticityProblem->Model());
+  initAssemble();
   generateStartVectors();
 }
 
 Vector &MainElasticity::Run(const Vector &start) {
-  // load Interpolation from used discretization model from src/elasticity/assemble/IElasticity.hpp
-  *displacement = mechA->Interpolation(start, *displacement);
+  if (start.GetDisc().DiscName() == (*displacement).GetDisc().DiscName() && start.Level() < (*displacement).Level()){
+    // load Interpolation from used discretization model from src/elasticity/assemble/IElasticity.hpp
+    *displacement = mechA->Interpolation(start, *displacement);
+  }
+  else {
+    if(start.GetDisc().DiscName()==(*displacement).GetDisc().DiscName())
+      *displacement = start;
+    else {
+      *displacement = mechA->UseLagrangeAsStartVector(start, *displacement);
+    }
+  }
   return Run();
 }
 
@@ -55,10 +70,12 @@ Vector &MainElasticity::Run() {
                  PrintInfoEntry("Poisson's Ratio",
                                 material::poissonInvariant(elasticityProblem->GetMaterials().first),
                                 1),
+                 PrintInfoEntry("MechPolynomialDegree:", discDegree, 1),
                  PrintInfoEntry("Degrees of Freedom:", displacement->pSize(), 1)/*,
                    PrintInfoEntry("Matrix Entries", solution.pMatrixSize(), 2)*/);
   mout << "===========================================================" << endl << endl;
-
+//  displacement->GetMatrixGraph().PrintMatrixMemoryInfo();
+//  displacement->GetMatrixGraph().PrintVectorMemoryInfo();
   displacement->GetMesh().PrintInfo();
 
   mout << endl << "===========================================================" << endl << endl;
@@ -100,11 +117,6 @@ void MainElasticity::generateMesh(const string &model) const {
       WithMeshName(elasticityProblem->GetMeshName()).
       WithIncludeVector(chambers).
       WithLevel(mlevel);
-  if (model.find("DG") != std::string::npos) {
-    mCreator = mCreator.WithOverlap("dG1");
-  } else if (model.find("EG") != std::string::npos) {
-    mCreator.WithOverlap("EG");
-  } else mCreator.WithoutOverlap();
 
   elasticityProblem->CreateMeshes(mCreator);
   InterpolateCellData(elasticityProblem->GetMeshes());
@@ -115,7 +127,7 @@ void MainElasticity::generateStartVectors() {
   vectorDisc = mechA->CreateDisc(3);
   scalarDisc = mechA->CreateDisc(1);
 
-  displacement = std::make_unique<Vector>(*vectorDisc);
+  displacement = std::make_unique<Vector>(vectorDisc);
   *displacement = 0.0;
   //displacement->Clear();
 }
@@ -138,11 +150,9 @@ Vector &MainElasticity::GetDisplacement() const {
 }
 
 void MainElasticity::initAssemble() {
-  int degree = 1;
   bool isStatic = false;
-  Config::Get("MechPolynomialDegree", degree);
   // Create assemble for used discretization in src/elasticity/assemble/IElasticity.cpp
-  mechA = CreateFiniteElasticityAssemble(*elasticityProblem, degree, isStatic);
+  mechA = CreateFiniteElasticityAssemble(*elasticityProblem, discDegree, isStatic);
   auto times = ReadTimeFromConfig();
   mechA->ResetTime(times[0], times[1], times[2]);
 }
@@ -221,6 +231,11 @@ void MainElasticity::ResetLevel(int newLevel) {
   mlevel = newLevel;
 }
 
+
+void MainElasticity::SetDegree(int degree){
+  discDegree = degree;
+}
+
 void MainElasticity::EvaluateReferece(const Vector &solution, const Vector &reference) {
   mout << "============== Comparing grid level " << solution.GetMesh().Level() << " with "
        << reference.GetMesh().Level() << " =========" << endl << endl;
diff --git a/src/elasticity/MainElasticity.hpp b/src/elasticity/MainElasticity.hpp
index 889eb56e81261ccdfcb39fa1516de8a9d04b576e..32d8f189bc37e8e87291290cdafd6425208a2f38 100644
--- a/src/elasticity/MainElasticity.hpp
+++ b/src/elasticity/MainElasticity.hpp
@@ -9,7 +9,7 @@
 /// Is used to move ElasticityProblem, Discretization and displacement in MoveVector() function.
 struct VectorStruct {
   std::unique_ptr<ElasticityProblem> problem{nullptr};
-  std::unique_ptr<IDiscretization> disc{nullptr};
+  std::shared_ptr<IDiscretization> disc{nullptr};
   std::unique_ptr<Vector> vec{nullptr};
 
   Vector &operator()() {
@@ -26,6 +26,7 @@ struct VectorStruct {
  */
 class MainElasticity : public MainCardMech {
   friend class MultiElasticity;
+  friend class MultiDiscElasticity;
 
   void generateMesh(const string &model) const;
 
@@ -34,8 +35,8 @@ class MainElasticity : public MainCardMech {
 
   std::unique_ptr<ElasticityProblem> elasticityProblem = nullptr;
 
-  std::unique_ptr<IDiscretization> vectorDisc = nullptr;
-  std::unique_ptr<IDiscretization> scalarDisc = nullptr;
+  std::shared_ptr<IDiscretization> vectorDisc = nullptr;
+  std::shared_ptr<IDiscretization> scalarDisc = nullptr;
 
   std::unique_ptr<IElasticity> mechA = nullptr;
   std::unique_ptr<IElasticity> prestressedEla = nullptr;
@@ -65,10 +66,14 @@ public:
 
   void Initialize() override;
 
+  void Initialize(std::unique_ptr<ElasticityProblem> problem);
+
   void ResetTime(double start, double end, int steps) override;
 
   void ResetLevel(int newLevel);
 
+  void SetDegree(int degree);
+
   Vector &Run() override;
 
   std::vector<double> Evaluate(const Vector &solution) override;
diff --git a/src/elasticity/MultiDiscElasticity.cpp b/src/elasticity/MultiDiscElasticity.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..24603cbfca46754cdf2857fb2a7cd39711651e89
--- /dev/null
+++ b/src/elasticity/MultiDiscElasticity.cpp
@@ -0,0 +1,93 @@
+#include "MultiDiscElasticity.hpp"
+
+
+
+MultiDiscElasticity::MultiDiscElasticity() : main() {
+  Config::Get("multiDiscs", multiDiscs);
+  Config::Get("useDifferentMeshes", useDifferentMeshes);
+  Config::Get("useDifferentDegs", useDifferentDegs);
+  Config::Get("MechDiscretizationList", discs);
+  solutions.resize(discs.size());
+  meshes.resize(discs.size());
+  degrees.resize(discs.size());
+  DGPenalties.resize(discs.size());
+
+  Config::Get("MechPolynomialDegreeList", degreeList);
+  Config::Get("MeshList", meshesList);
+  Config::Get("DGPenaltyList", DGPenaltyList);
+}
+
+
+void MultiDiscElasticity::Initialize() {
+
+  if (degreeList.size() == 1){
+    for(int i = 0; i <= discs.size()-1; ++i) {
+      degrees[i] = degreeList[0];
+    }
+  } else {
+    if (degreeList.size() != degrees.size()) THROW("List of MechPolynomialDegrees is not matching!")
+    degrees = degreeList;
+  }
+
+
+  if (meshesList.size() == 1){
+    for(int i = 0; i <= discs.size()-1; ++i) {
+      meshes[i] = meshesList[0];
+    }
+  } else {
+    if (meshesList.size() != meshes.size()) THROW("List of MechPolynomialDegrees is not matching!")
+    meshes = meshesList;
+  }
+
+  DGPenalties = DGPenaltyList;
+
+  for (int j = 0; j < degrees.size(); ++j){
+    if (degrees[j] == degrees[j+1]){
+      useDifferentDegs = false;
+    }
+  }
+  auto elasticityProblemLocal = GetElasticityProblem();
+  elasticityProblemLocal->SetModel(discs[0]); // sets disc
+  elasticityProblemLocal->SetDGPenalty(DGPenalties[0]);
+  if (useDifferentMeshes) {
+    elasticityProblemLocal->SetMeshName(meshes[0]);
+  }
+  main.SetDegree(degrees[0]);
+  main.Initialize(std::move(elasticityProblemLocal));
+}
+
+Vector &MultiDiscElasticity::Run() {
+  for (int i = 0; i <= discs.size()-1; ++i) {
+    mout << "\n=================== Running discretization " << discs[i] << " ================ " << endl;
+    auto elasticityProblemLocal = GetElasticityProblem();
+    elasticityProblemLocal->SetModel(discs[i]);
+
+    elasticityProblemLocal->SetDGPenalty(DGPenalties[i]);
+
+    if (useDifferentMeshes) {
+      elasticityProblemLocal->SetMeshName(meshes[i]);
+    }
+    main.SetDegree(degrees[i]);
+    main.Initialize(std::move(elasticityProblemLocal));
+
+    bool usePrevDisc =  (multiDiscs && i > 0 && !useDifferentMeshes && !useDifferentDegs);
+
+    if ((usePrevDisc && useDifferentMeshes) || (usePrevDisc && useDifferentDegs)){
+      THROW("Not implemented right now!")
+    }
+
+    main.pressureSteps = 1;
+    const auto &solution = usePrevDisc ? main.Run(solutions[i - 1]()) : main.Run();
+
+    main.Evaluate(solution);
+    solutions[i] = main.MoveVector();
+  }
+
+  return solutions[discs.size() - 1]();
+}
+
+vector<double> MultiDiscElasticity::Evaluate(const Vector &solution) {
+  mout << endl << "=============================================================" << endl << endl;
+  return {};
+}
+
diff --git a/src/elasticity/MultiDiscElasticity.hpp b/src/elasticity/MultiDiscElasticity.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b12cc4ecfcb2955a125f92e667e942c1e032f70c
--- /dev/null
+++ b/src/elasticity/MultiDiscElasticity.hpp
@@ -0,0 +1,46 @@
+//
+// Created by laura on 30.01.24.
+//
+
+#ifndef CARDMECH_MULTIDISCELASTICITY_HPP
+#define CARDMECH_MULTIDISCELASTICITY_HPP
+
+#endif //CARDMECH_MULTIDISCELASTICITY_HPP
+
+#include "MainCardMech.hpp"
+#include "MainElasticity.hpp"
+
+/**
+ * Running different discretizations one after the other.
+ * Homotopy (for different discs or e.g. to test different penalty parameters for DG/EG faster).
+ * Possibilty to choose different meshes and degrees is not implemented yet!
+ * "meshesList" and "degreeList": if there is only one entry in the config, it uses the same entries
+ * for all discretizations in "discs"
+ * homotopy possibilities: CG -> DG, CG -> EG, DG -> DG, EG -> EG
+ */
+class MultiDiscElasticity : public MainCardMech {
+  MainElasticity main;
+
+  bool multiDiscs{false};
+  bool useDifferentMeshes{false};
+  bool useDifferentDegs{false};
+  std::vector<VectorStruct> solutions{};
+  std::vector<string>  discs{};
+  std::vector<string>  meshes;
+  std::vector<string>  meshesList;
+  std::vector<int>  degrees;
+  std::vector<int>  degreeList;
+  std::vector<int>  DGPenalties;
+  std::vector<int>  DGPenaltyList;
+
+public:
+  MultiDiscElasticity();
+
+  void Initialize() override;
+
+  Vector &Run() override;
+
+  vector<double> Evaluate(const Vector &solution) override;
+
+};
+
diff --git a/src/elasticity/assemble/DGElasticity.cpp b/src/elasticity/assemble/DGElasticity.cpp
index 5261b199ddeccdcaf764c9ba0bef7278ebebdd22..ab9428a22cb218db3ce73129999623e2629a7cd7 100644
--- a/src/elasticity/assemble/DGElasticity.cpp
+++ b/src/elasticity/assemble/DGElasticity.cpp
@@ -2,11 +2,15 @@
 #include "DGDoF.hpp"
 #include "DGVectorFieldElement.hpp"
 #include "VectorAccess.hpp"
+#include "VectorFieldElement.hpp"
 
 DGElasticity::DGElasticity(ElasticityProblem &eP, int degree, bool isStatic)
-    : IElasticity(eP), disc(eP.GetMeshes(), degree, dim()) {
+    : IElasticity(eP), disc(std::make_shared<const DGDiscretization>(eP.GetMeshes(), degree, dim())) {
   Config::Get("DGSign", sign);
-  Config::Get("DGPenalty", penalty);
+
+  penalty = eP.GetDGPenalty();
+  if (penalty == 0)   Config::Get("DGPenalty", penalty);
+
   this->degree = degree;
 }
 
@@ -193,9 +197,9 @@ void DGElasticity::Residual(const cell &c, const Vector &U, Vector &r) const {
       }
 
     } else if (E.Bnd(f) == -1) {
-      cell cf = r.GetMesh().find_neighbour_cell(c, f);
+      cell cf = r.find_neighbour_cell(c, f);
       if (cf() < c()) continue;
-      int f1 = r.GetMesh().find_neighbour_face_id(c.Face(f), cf);
+      int f1 = r.find_neighbour_face_id(c.Face(f), cf);
       DGVectorFieldElement E_nghbr(U, *cf);
       DGVectorFieldFaceElement FE_nghbr(r, *cf, f1);
       DGSizedRowBndValues r_cf(r, *cf, E_nghbr.shape_size());
@@ -481,14 +485,14 @@ void DGElasticity::Jacobi(const cell &c, const Vector &U, Matrix &A) const {
       }
     }
     if (E.Bnd(face) == -1) {
-      cell cf = U.GetMesh().find_neighbour_cell(c, face);
+      cell cf = U.find_neighbour_cell(c, face);
       if (cf() < c()) continue;
       DGVectorFieldElement E_nghbr(U, *cf);
       DGSizedRowEntries A_cf(A, *c, E.shape_size(), *cf, E_nghbr.shape_size());
 
       DGSizedRowEntries A_fc(A, *cf, E_nghbr.shape_size(), *c, E.shape_size());
       DGSizedRowEntries A_ff(A, *cf, E_nghbr.shape_size(), *cf, E_nghbr.shape_size());
-      int f1 = U.GetMesh().find_neighbour_face_id(c.Face(face), cf);
+      int f1 = U.find_neighbour_face_id(c.Face(face), cf);
       DGVectorFieldFaceElement FE_nghbr(U, *cf, f1);
 
       for (int q = 0; q < FE.nQ(); ++q) {
@@ -654,6 +658,24 @@ void DGElasticity::Interpolate(const Vector &coarse, Vector &u) const {
   u.Accumulate();
 }
 
+void DGElasticity::UseLagrangeValuesAsStartVector(const Vector &u_conforming, Vector &u) const {
+  for (cell c = u.cells(); c != u.cells_end(); ++c) {
+    DGVectorFieldElement E(u, *c);
+    VectorFieldElement EC(u_conforming, *c);
+    for (int i = 0; i < E.shape_size(); ++i) {
+      Point x = E.NodalPoint(i);
+      row r = u_conforming.find_row(x);
+      if (r == u_conforming.rows_end()) continue;
+      for (int k = 0; k < E.Dim(); ++k)
+        u(c(), k * E.shape_size() + i) = u_conforming(r,k);
+    }
+    auto x = c.GlobalToLocal(c());
+    VectorField val = E.VectorValue(x, u);
+    VectorField valC = EC.VectorValue(x, u_conforming);
+  }
+  u.MakeAdditive();
+  u.Accumulate();
+}
 
 double DGElasticity::StrainEnergyError(const Vector &u) const {
   double err = 0.0;
@@ -1070,7 +1092,7 @@ double DGElasticity::DeformedVolume(const Vector &U) const {
 
 void DGElasticity::PlotBoundary(const Vector &U, const Vector &scal) const {
   if (vtkplot < 1) return;
-  Vector bnd(0.0, U.GetDisc());
+  Vector bnd(0.0, U.GetSharedDisc());
 
   auto &plot = mpp::plot("Boundary");
   for (cell c = U.cells(); c != U.cells_end(); c++) {
@@ -1081,17 +1103,36 @@ void DGElasticity::PlotBoundary(const Vector &U, const Vector &scal) const {
     for (int face = 0; face < c.Faces(); ++face) {
       DGVectorFieldFaceElement FE(U, *c, face);
       int bc = u_c.bc(face);
-
-      for (int i = 0; i < FE.shape_size(); ++i) {
-        bnd(c(), i) = max(bnd(c(), i), (double) bc);
-      }
-
+      bnd(c(), 0) = max(bnd(c(), 0), (double) bc);
+      bnd(c(), 1) = max(bnd(c(), 1), bc == 199 ? 1.0 : 0.0); // Fixation Boundary bc == 199
     }
   }
-  plot.AddData("Boundary", bnd);
+  plot.AddData("Boundary", bnd, 0);
+  plot.AddData("Fixation", bnd, 1);
   plot.PlotFile("Boundary");
 }
 
+Vector makePlottableDGVector(const Vector &U) {
+  Vector plotU(0.0, U);
+  for (cell c = U.cells(); c != U.cells_end(); c++) {
+    row r = plotU.find_row(c());
+    DGVectorFieldElement elem(U, *c);
+    VectorField disp = elem.VectorValue(c.LocalCenter(), U);
+    plotU(r, 0) = disp[0];
+    plotU(r, 1) = disp[1];
+    plotU(r, 2) = disp[2];
+  }
+  return plotU;
+}
+
+
+void DGElasticity::PlotDisplacement(const Vector &U, int step,
+                                    const string &varname) const {
+  // Plotting the deformation in src/CardiacAssemble.hpp
+  PlotDeformed(U, {{"Displacement", makePlottableDGVector(U)}}, step, varname);
+
+}
+
 void DGElasticity::SetDisplacement(Vector &U) const {
   for (cell c = U.cells(); c != U.cells_end(); ++c) {
     auto index = U.find_row(c());
@@ -1206,8 +1247,6 @@ void DGElasticity::ProblemEvaluation(const Vector &u) const {
 }
 
 
-
-
 void DGElasticity::MassMatrix(Matrix &massMatrix) const {
   THROW("MassMatrix is not implemented for DG")
 }
@@ -1218,4 +1257,24 @@ void DGElasticity::SystemMatrix(Matrix &systemMatrix) const {
 
 void DGElasticity::Initialize(Vectors &vecs) const {
   THROW("Initialize is not implemented for DG")
-}
\ No newline at end of file
+}
+
+
+std::pair<double, double> DGElasticity::detF(const Vector &u) const {
+  double Jmax = 1.0;
+  double Jmin = 1.0;
+
+  for (cell c = u.cells(); c != u.cells_end(); ++c) {
+    DGVectorFieldElement E(u, *c);
+    for (int q = 0; q < E.nQ(); ++q) {
+      Tensor DU = E.VectorGradient(q, u);
+      double J = det(One + DU);
+      Jmin = min(Jmin, J);
+      Jmax = max(Jmax, J);
+    }
+  }
+  Jmin = PPM->Min(Jmin);
+  Jmax = PPM->Max(Jmax);
+
+  return {Jmin, Jmax};
+}
diff --git a/src/elasticity/assemble/DGElasticity.hpp b/src/elasticity/assemble/DGElasticity.hpp
index 751565d87754f5fdbb7b72c1a78b364b38dec973..010a62e350c6efea650988639a5979707aef3445 100644
--- a/src/elasticity/assemble/DGElasticity.hpp
+++ b/src/elasticity/assemble/DGElasticity.hpp
@@ -10,18 +10,20 @@ class DGElasticity : public IElasticity {
   double penalty{1};
   int size{3};
 
-  const DGDiscretization disc;
+  std::shared_ptr<const DGDiscretization> disc;
 
 protected:
   void prestress(const Vector &u, Vector &pStress) override;
 public:
   DGElasticity(ElasticityProblem &eP, int degree, bool isStatic = false);
 
-  std::unique_ptr<IDiscretization> CreateDisc(int sizes) const override {
-    return std::make_unique<DGDiscretization>(disc.GetMeshes(), degree, sizes);
+  std::shared_ptr<IDiscretization> CreateDisc(int sizes) const override {
+    return std::make_shared<DGDiscretization>(disc->GetMeshes(), degree, sizes);
   }
 
-  const IDiscretization &GetDisc() const override { return disc; }
+  const IDiscretization &GetDisc() const override { return *disc; }
+
+  std::shared_ptr<const IDiscretization> GetSharedDisc() const override {return disc; }
 
   void Initialize(Vector &u) const override {};
 
@@ -52,7 +54,9 @@ public:
 
   void Interpolate(const Vector &coarse, Vector &u) const override;
 
-  //void Project(Vector &coarse, const Vector &fine) const;
+  void UseLagrangeValuesAsStartVector(const Vector &u_conforming, Vector &u) const override;
+
+    //void Project(Vector &coarse, const Vector &fine) const;
 
   double L2Error(const Vector &u) const override;
 
@@ -86,6 +90,8 @@ public:
 
   void PlotBoundary(const Vector &U, const Vector &scal) const override;
 
+  void PlotDisplacement(const Vector &u, int step, const string &varname) const override;
+
   //std::array<double, 4> ChamberVolume(const Vector &U) const override;
   void FixationBoundary(const cell &c, int face, int bc, const Vector &U, Vector &r) const;
 
@@ -118,8 +124,10 @@ public:
 
   void Scale (double s) const {
     Material &cellMat = eProblem.GetMaterial();
-    cellMat.ScalePenalty(s*s);
+//    cellMat.ScalePenalty(s*s);
   }
+
+  std::pair<double, double> detF(const Vector &u) const override;
 };
 
 #endif //DGELASTICITY_HPP
diff --git a/src/elasticity/assemble/EGElasticity.cpp b/src/elasticity/assemble/EGElasticity.cpp
index d50a0c6c789251dab64eab59889c3b539c496a2f..7b835427f0d6bd76535268443522fd2de1f12ac1 100644
--- a/src/elasticity/assemble/EGElasticity.cpp
+++ b/src/elasticity/assemble/EGElasticity.cpp
@@ -1,9 +1,12 @@
 #include "EGElasticity.hpp"
 
 EGElasticity::EGElasticity(ElasticityProblem &eP, int degree, bool isStatic)
-    : IElasticity(eP), disc(eP.GetMeshes(), degree, dim()){
+    : IElasticity(eP), disc(std::make_shared<const MixedEGDiscretization>(eP.GetMeshes(), degree, dim())){
   Config::Get("DGSign", sign);
-  Config::Get("DGPenalty", penalty);
+
+  penalty = eP.GetDGPenalty();
+  if (penalty == 0)   Config::Get("DGPenalty", penalty);
+
   this->degree = degree;
 }
 
@@ -26,13 +29,23 @@ void EGElasticity::Energy(const cell &c, const Vector &U, double &energy) const
     double w = E.QWeight(q);
 
     Tensor F = DeformationGradient(E, q, U);
-
+    Tensor FT = transpose(F);
+    Tensor E = 0.5 * (FT * F - One);
 
 //    VectorField v = timeScheme->Velocity<MixedEGVectorFieldElement>(U, E, q); // noch überlegen
 //    energy += w * rho * (v * v);
-    energy += w * cellMat.TotalEnergy(F, Q);
+    // energy += w * cellMat.TotalEnergy(F, Q);
+
+    
+    //energy = min(energy,det(F));
+
+    energy = max(energy,cellMat.q(E, Q[0]));
+    
   }
 
+  return;
+
+  
   BFParts bnd(U.GetMesh(), *c);
   if (!bnd.onBnd()) return;
 
@@ -197,9 +210,9 @@ void EGElasticity::Residual(const cell &c, const Vector &U, Vector &r) const {
 
       }
     } else if (E.Bnd(f) == -1) {
-      cell cf = r.GetMesh().find_neighbour_cell(c, f);
+      cell cf = r.find_neighbour_cell(c, f);
       if (cf() < c()) continue;
-      int f1 = r.GetMesh().find_neighbour_face_id(c.Face(f), cf);
+      int f1 = r.find_neighbour_face_id(c.Face(f), cf);
       MixedEGVectorFieldElement E_nghbr(U, *cf);
       MixedEGVectorFieldFaceElement FE_nghbr(r, *cf, f1);
       MixedRowValues r_cf(r, *cf);
@@ -444,9 +457,9 @@ void EGElasticity::Jacobi(const cell &c, const Vector &U, Matrix &A) const {
             w * (localPressure) * (Cross(F, Dtheta) * N) * theta;
       }
     } else if (E.Bnd(face) == -1) {
-      cell cf = U.GetMesh().find_neighbour_cell(c, face);
+      cell cf = U.find_neighbour_cell(c, face);
       if (cf() < c()) continue;
-      int f1 = U.GetMesh().find_neighbour_face_id(c.Face(face), cf);
+      int f1 = U.find_neighbour_face_id(c.Face(face), cf);
       MixedEGVectorFieldElement E_nghbr(U, *cf);
       MixedEGVectorFieldFaceElement FE_nghbr(U, *cf, f1);
       MixedRowEntries A_cf(A, *c, *cf);
@@ -927,30 +940,54 @@ void EGElasticity::GetInvariant(const Vector &displacement, Vector &iota4) const
   iota4.Collect();
 }
 
-/*void EGElasticity::PlotBoundary(const Vector &U, const Vector &scal) const {
-    if (vtkplot < 1) return;
-    Vector bnd(0.0, U.GetDisc());
-
-    auto &plot = mpp::plot("Boundary");
-    for (cell c = U.cells(); c != U.cells_end(); c++) {
-        MixedEGVectorFieldElement E(U, *c);
-        RowBndValues u_c(bnd, *c);
-        if (!u_c.onBnd()) continue;
-
-        for (int face = 0; face < c.Faces(); ++face) {
-            MixedEGVectorFieldFaceElement FE(U, *c, face);
-            int shape_size = FE.dimension()-1;
-            int bc = u_c.bc(face);
+void EGElasticity::PlotBoundary(const Vector &U, const Vector &scal) const {
+  if (vtkplot < 1) return;  
+  Vector bnd(scal);
+  bnd.Clear();
+  Vector count(bnd);
+  count.Clear();
+  auto &plot = mpp::plot("Boundary");
+  for (cell c = U.cells(); c != U.cells_end(); c++) {
+    RowBndValues u_c(bnd, *c);
+    RowBndValues u_count(count, *c);
+
+    if (!u_c.onBnd()) continue;
+
+    for (int i = 0; i < c.Faces(); ++i) {
+      for (int j = 0; j < U.NumberOfNodalPointsOnFace(*c, i); ++j) {
+        int id = U.IdOfNodalPointOnFace(*c, i, j);
+        if (u_c.bc(i) > u_c(id, 0)) {
+          u_c(id, 0) = (double) u_c.bc(i);
+          u_count(id, 0) = 1;
+        }
+      }
+    }
+  }
+  bnd.Accumulate();
+  count.Accumulate();
+  for (size_t i = 0; i < count.size(); i++) {
+    if (count[i] > 0) {
+      bnd[i] /= count[i];
+    }
+  }
+  plot.AddData("Boundary", bnd, 0);
 
-            for (int i = 0; i < shape_size; ++i) {
-                bnd(c(), i) = max(bnd(c(), i), (double) bc);
-            }
+  bnd = 0;
+  for (cell c = U.cells(); c != U.cells_end(); c++) {
+    RowBndValues u_c(bnd, *c);
+    if (!u_c.onBnd()) continue;
 
-        }
+    for (int i = 0; i < c.Faces(); ++i) {
+      for (int j = 0; j < U.NumberOfNodalPointsOnFace(*c, i); ++j) {
+        int id = U.IdOfNodalPointOnFace(*c, i, j);
+        u_c(id, 0) = max(u_c(id, 0), u_c.bc(i) == 199 ? 1.0 : 0.0);
+      }
     }
-    plot.AddData("Boundary", bnd);
-    plot.PlotFile("Boundary");
-}*/
+  }
+  plot.AddData("Fixation", bnd);
+
+  plot.PlotFile("Boundary");
+}
 
 void EGElasticity::SetDisplacement(Vector &U) const {
   for (row r = U.rows(); r != U.rows_end(); ++r) {
@@ -1036,6 +1073,22 @@ void EGElasticity::Interpolate(const Vector &coarse, Vector &u) const {
 }
 
 
+void EGElasticity::UseLagrangeValuesAsStartVector(const Vector &u_conforming, Vector &u) const{
+  for (row r = u.rows(); r != u.rows_end(); ++r){
+    row r2 = u_conforming.find_row(r());
+    if (r2 == u_conforming.rows_end()) continue;
+    int n = r.NumberOfDofs();
+    if (n == 1) continue;
+    for (int j = 0; j < n ; ++j){
+      u(r,j) = u_conforming(r2, j);
+    }
+  }
+  u.MakeAdditive();
+  u.Accumulate();
+}
+
+
+
 void EGElasticity::MassMatrix(Matrix &massMatrix) const {
   THROW("MassMatrix is not implemented for DG")
 }
@@ -1170,4 +1223,24 @@ void EGElasticity::Initialize(const cell &c, Vector &U) const {
         break;
     }
   }
-}
\ No newline at end of file
+}
+
+std::pair<double, double> EGElasticity::detF(const Vector &u) const {
+  double Jmax = 1.0;
+  double Jmin = 1.0;
+
+  for (cell c = u.cells(); c != u.cells_end(); ++c) {
+    MixedEGVectorFieldElement E(u, *c);
+    for (int q = 0; q < E.nQ(); ++q) {
+      Tensor DU = E.VectorGradient(q, u);
+      double J = det(One + DU);
+      Jmin = min(Jmin, J);
+      Jmax = max(Jmax, J);
+    }
+  }
+  Jmin = PPM->Min(Jmin);
+  Jmax = PPM->Max(Jmax);
+
+  return {Jmin, Jmax};
+}
+
diff --git a/src/elasticity/assemble/EGElasticity.hpp b/src/elasticity/assemble/EGElasticity.hpp
index e3c5fb6b56ef255b67c53554e8d839b09042f026..24f70cd21d9c7be64f6518fc1baf29feae70a826 100644
--- a/src/elasticity/assemble/EGElasticity.hpp
+++ b/src/elasticity/assemble/EGElasticity.hpp
@@ -14,7 +14,7 @@ class EGElasticity : public IElasticity {
   double penalty{1};
   int size{3};
 
-  const MixedEGDiscretization disc;
+  std::shared_ptr<const MixedEGDiscretization> disc;
 
   void fixationBnd(const cell &c, const Vector &U, RowBndValues &u_c, int face) const;
 
@@ -26,11 +26,13 @@ protected:
 public:
   EGElasticity(ElasticityProblem &eP, int degree, bool isStatic = false);
 
-  std::unique_ptr<IDiscretization> CreateDisc(int sizes) const override {
-    return std::make_unique<MixedEGDiscretization>(disc.GetMeshes(), degree, sizes);
+  std::shared_ptr<IDiscretization> CreateDisc(int sizes) const override {
+    return std::make_shared<MixedEGDiscretization>(disc->GetMeshes(), degree, sizes);
   }
 
-  const IDiscretization &GetDisc() const override { return disc; }
+  const IDiscretization &GetDisc() const override { return *disc; }
+
+  std::shared_ptr<const IDiscretization> GetSharedDisc() const override {return disc; }
 
   //void Initialize(Vector &u) const override {};
 
@@ -92,7 +94,7 @@ public:
 
   double NormPrestress();
 
-  /*void PlotBoundary(const Vector &U, const Vector &scal) const override;*/
+  void PlotBoundary(const Vector &U, const Vector &scal) const override;
 
   /*std::array<double, 4> CalculateVolume(const Vector &U) const override;*/
 
@@ -106,8 +108,12 @@ public:
 
   void Interpolate(const Vector &coarse, Vector &u) const override;
 
+  void UseLagrangeValuesAsStartVector(const Vector &u_conforming, Vector &u) const override;
+
   std::array<double, 4> ChamberVolume(const Vector &u) const override;
 
+  std::pair<double, double> detF(const Vector &u) const override; 
+  
 };
 
 
diff --git a/src/elasticity/assemble/IElasticity.cpp b/src/elasticity/assemble/IElasticity.cpp
index 5d7242a134e5ebfd59c5ba5d2d7e402c25521abe..6e4ed0dcd9fc478d09ebe11051de6e28535d0347 100644
--- a/src/elasticity/assemble/IElasticity.cpp
+++ b/src/elasticity/assemble/IElasticity.cpp
@@ -24,24 +24,13 @@ void IElasticity::SetInitialValue(Vector &u) {
   // Initialize ElasticityProblem in src/elasticity/problem/ElasticityProblem.hpp
   eProblem.Initialize(StepSize(), Time(), ChamberVolume(u));
   const Meshes &M = u.GetMeshes();
-  disc03 = new LagrangeDiscretization(M, 0, 3);
+  auto disc03 = std::make_shared<LagrangeDiscretization>(M, 0, 3);
   gamma_c= !Prestress ? std::make_unique<Vector>(*disc03,prestressLevel) : std::make_unique<Vector>(*disc03);
 
   if (!Prestress) {
     Prestress = std::make_unique<Vector>(0.0, u);
   }
   gamma = std::make_unique<Vector>(0.0, u);
-
-
-  /*int cellcounterGamma=0;
-  int cellcounterU=0;
-  for(cell c = (*gamma_c).cells(); c != (*gamma_c).cells_end(); ++c)
-    cellcounterGamma+=1;
-  for(cell c = (u).cells(); c != (u).cells_end(); ++c)
-    cellcounterU+=1;
-  std::cout<<"gamma cells "<<cellcounterGamma<<" u cells "<<cellcounterU<<endl;
-*/
-
 }
 
 void IElasticity::SetInitialValue(Vectors &values) {
@@ -182,6 +171,9 @@ void IElasticity::PrintPressureIteration(const Vector &u) const {
 }
 
 void IElasticity::PlotIteration(const Vectors &mechValues, int step) const {
+  if (mechValues[0].GetDisc().DiscName().find("DG") != std::string::npos) {
+    THROW("TODO: Override in DGElasticity as in PlotDisplacement!")
+  }
   step = step < 0 ? Step() : step;
 
   if (step == 0) PlotBoundary(mechValues[0], mechValues[0]);
diff --git a/src/elasticity/assemble/IElasticity.hpp b/src/elasticity/assemble/IElasticity.hpp
index dcc38cdd194408f2e6245798a7e6daa21f74809f..789f74d4d82ff315a5e2db674964253ed5f50d62 100644
--- a/src/elasticity/assemble/IElasticity.hpp
+++ b/src/elasticity/assemble/IElasticity.hpp
@@ -50,8 +50,10 @@ public:
   /// Gets the corresponding discretization.
   virtual const IDiscretization &GetDisc() const = 0;
 
+  virtual std::shared_ptr<const IDiscretization> GetSharedDisc() const = 0;
+
   /// Creates a new discretization with a different size.
-  virtual std::unique_ptr<IDiscretization> CreateDisc(int size) const = 0;
+  virtual std::shared_ptr<IDiscretization> CreateDisc(int size) const = 0;
 
   const char *Name() const override { return "Cardiac Elasticity"; }
 
@@ -143,7 +145,7 @@ public:
 
   virtual void GetInvariant(const Vector &u, Vector &iota4, Vector &iota) const { return GetInvariant(u,iota4); }
 
-  void PlotDisplacement(const Vector &u, int step, const string &varname) const;
+  virtual void PlotDisplacement(const Vector &u, int step, const string &varname) const;
 
   /**
    *   Creates a new vector with the discretization of target (coarse vector) and projects fine
@@ -175,6 +177,17 @@ public:
     Warning("No Interpolation implemented")
   }
 
+  Vector UseLagrangeAsStartVector(const Vector &u_conforming, const Vector &target) const {
+    Vector v(target);
+    UseLagrangeValuesAsStartVector(u_conforming, v);
+    return v;
+  }
+
+
+  virtual void UseLagrangeValuesAsStartVector(const Vector &u_conforming, Vector &u) const  {
+    Warning("Not implemented for this discretization")
+  }
+
 
   virtual double L2Norm(const Vector &u) const { return 0.0; };
 
diff --git a/src/elasticity/assemble/LagrangeElasticity.cpp b/src/elasticity/assemble/LagrangeElasticity.cpp
index f8d72b3be2248b72c0cad929e6cfae7367f477d4..9c262f1e462d5fa821972d231c981bfe55a0e252 100644
--- a/src/elasticity/assemble/LagrangeElasticity.cpp
+++ b/src/elasticity/assemble/LagrangeElasticity.cpp
@@ -4,7 +4,7 @@
 #include "VectorFieldElement.hpp"
 
 LagrangeElasticity::LagrangeElasticity(ElasticityProblem &eP, int degree, bool isStatic)
-    : IElasticity(eP), disc(eP.GetMeshes(), degree, dim()) {
+    : IElasticity(eP), disc(std::make_shared<LagrangeDiscretization>(eP.GetMeshes(), degree, dim())) {
   this->degree = degree;
 
   Config::Get("withPressure", withPressure);
@@ -1222,7 +1222,7 @@ void LagrangeElasticity::SetInitialValue(Vector &u) {
 
 void LagrangeElasticity::Initialize(const cell &c, Vector &U) const {
   RowBndValues u_c(U, *c);
-  if (!U.GetMesh().OnBoundary(*c)) return;
+  if (!U.OnBoundary(*c)) return;
   for (int face = 0; face < c.Faces(); ++face) {
     switch (u_c.bc(face)) {
       case 1:
@@ -1290,7 +1290,7 @@ void LagrangeElasticity::TractionStiffness(Matrix &matrix) const {
 
     for (int f = 0; f < c.Faces(); ++f) {
       VectorFieldFaceElement faceElem(matrix, *c, f);
-      if (matrix.GetMesh().OnBoundary(*c, f)) {
+      if (matrix.OnBoundary(*c, f)) {
         int bc = matrix.GetMesh().BoundaryFacePart(c.Face(f));
 
         if ((bc >= ROBIN_BC_EPI) && (bc <= ROBIN_BC_BASE)) {
@@ -1329,7 +1329,7 @@ void LagrangeElasticity::EvaluateTractionStiffness(Vector &u) const {
 
     for (int f = 0; f < c.Faces(); ++f) {
       VectorFieldFaceElement faceElem(u, *c, f);
-      if (u.GetMesh().OnBoundary(*c, f)) {
+      if (u.OnBoundary(*c, f)) {
         for (int face = 0; face < c.Faces(); ++face) {
           int bc = u.GetMesh().BoundaryFacePart(c.Face(f));
 
@@ -1356,7 +1356,7 @@ void LagrangeElasticity::TractionViscosity(Matrix &matrix) const {
 
     for (int f = 0; f < c.Faces(); ++f) {
       VectorFieldFaceElement faceElem(matrix, *c, f);
-      if (matrix.GetMesh().OnBoundary(*c, f)) {
+      if (matrix.OnBoundary(*c, f)) {
         int bc = matrix.GetMesh().BoundaryFacePart(c.Face(f));
 
         if ((bc >= ROBIN_BC_EPI) && (bc <= ROBIN_BC_BASE)) {
diff --git a/src/elasticity/assemble/LagrangeElasticity.hpp b/src/elasticity/assemble/LagrangeElasticity.hpp
index 84645ad83247d454b7d8e20f8bebd065b8733dd6..71e2589c17250a78ab6be577a402a74c100ff527 100644
--- a/src/elasticity/assemble/LagrangeElasticity.hpp
+++ b/src/elasticity/assemble/LagrangeElasticity.hpp
@@ -6,7 +6,7 @@
 
 class LagrangeElasticity : public IElasticity {
     int size{3};
-    const LagrangeDiscretization disc;
+    std::shared_ptr<const LagrangeDiscretization> disc;
     bool withPressure = true;
 
 
@@ -23,9 +23,13 @@ protected:
 public:
   LagrangeElasticity(ElasticityProblem &eP, int degree, bool isStatic = false);
 
-  const IDiscretization &GetDisc() const override { return disc; }
+  const IDiscretization &GetDisc() const override { return *disc; }
 
-  std::unique_ptr<IDiscretization> CreateDisc(int sizes) const override {return std::make_unique<LagrangeDiscretization>(disc, degree,sizes);}
+  std::shared_ptr<IDiscretization> CreateDisc(int sizes) const override {
+    return std::make_shared<LagrangeDiscretization>(*disc, degree, sizes);
+  }
+
+  std::shared_ptr<const IDiscretization> GetSharedDisc() const override {return disc; }
 
   void Initialize(Vectors &vecs) const override;
 
@@ -138,8 +142,9 @@ public:
   std::pair<double, double> detF(const Vector &u) const override;
 
   void Scale (double s) const {
+    //TODO warum konvergiert der LandBenchmark mit mehreren PressureSteps nicht, wenn einkommentiert?
     Material &cellMat = eProblem.GetMaterial();
-    cellMat.ScalePenalty(s*s);
+// cellMat.ScalePenalty(s*s);
   }
       
 };
diff --git a/src/elasticity/materials/GuccioneMaterial.cpp b/src/elasticity/materials/GuccioneMaterial.cpp
index 1eff5ec2ebfdaa42e32e87b5ca93d017dc4e948d..bb7c6127277e5a2cf4ad19a5e80e235d3898fb94 100644
--- a/src/elasticity/materials/GuccioneMaterial.cpp
+++ b/src/elasticity/materials/GuccioneMaterial.cpp
@@ -140,22 +140,20 @@ Tensor GuccioneBonetMaterial::ddq(const Tensor &E, const VectorField &f, const T
   return 2*QE;
 }
 
-
 double GuccioneBonetMaterial::energy(const Tensor &E, const VectorField &f) const {
-  return 0.5 * C() * (mat::cutexp(q(E, f)) - 1);
+  return 0.5 * C() * (mat::cutexp(q(E, f),exp_max) - 1);
 }
 
 
 Tensor GuccioneBonetMaterial::firstPK(const Tensor &E, const VectorField &f) const {
-  Tensor DPsi = 0.5 * C() * mat::cutexp(q(E, f)) * dq(E, f) + activeStress * Product(f,f);
+  Tensor DPsi = 0.5 * C() * mat::cutexp(q(E, f),exp_max) * dq(E, f) + activeStress * Product(f,f);
   return DPsi;
 }
 
 Tensor
 GuccioneBonetMaterial::constitutiveMatrix(const Tensor &E, const VectorField &f,
                                           const Tensor &H) const {
-  double expQ = mat::cutexp(q(E, f));
-
+  double expQ = mat::cutexp(q(E, f),exp_max);
   Tensor DDPsi = Frobenius(dq(E, f), H) * dq(E, f);
   DDPsi += ddq(E, f, H);
   return 0.5 * C() * expQ * DDPsi;
diff --git a/src/elasticity/materials/GuccioneMaterial.hpp b/src/elasticity/materials/GuccioneMaterial.hpp
index 174b82bc8aba1e01f56411054344a6e87f12a61a..626b2bbb82191cb37c86c2219aad9b9f25fa9c33 100644
--- a/src/elasticity/materials/GuccioneMaterial.hpp
+++ b/src/elasticity/materials/GuccioneMaterial.hpp
@@ -90,7 +90,8 @@ class GuccioneBonetMaterial : public HyperelasticMaterial {
   double b{1.0};
   double c{1.0};
   double activeStress{0.0};
-
+  double exp_max = 10;
+  
   void calculateParams() {
     a = 0.25 * (bf() - 2.0 * bfs() + bs());
     b = 0.5 * (bfs() - bs());
@@ -130,18 +131,21 @@ public:
     Config::Get("GuccioneMat_bf", parameters[1]);
     Config::Get("GuccioneMat_bs", parameters[2]);
     Config::Get("GuccioneMat_bfs", parameters[3]);
+    Config::Get("exp_max", exp_max);
     calculateParams();
     Config::Get("activeStress", activeStress);
   }
 
   explicit GuccioneBonetMaterial(const std::vector<double> &params) : HyperelasticMaterial("Bonet",
                                                                                            params) {
+    Config::Get("exp_max", exp_max);
     calculateParams();
     Config::Get("activeStress", activeStress);
   };
 
   explicit GuccioneBonetMaterial(std::vector<double> &&params) : HyperelasticMaterial("Bonet",
                                                                                       std::move(params)) {
+    Config::Get("exp_max", exp_max);
     calculateParams();
     Config::Get("activeStress", activeStress);
   };
diff --git a/src/elasticity/materials/HolzapfelMaterial.cpp b/src/elasticity/materials/HolzapfelMaterial.cpp
index 2cdfcad1df8c7f5c5bf18c725c526cc3e6b28d8a..79374d162dd5c90b474492d4a7ceef8fcbcd87df 100644
--- a/src/elasticity/materials/HolzapfelMaterial.cpp
+++ b/src/elasticity/materials/HolzapfelMaterial.cpp
@@ -2,44 +2,44 @@
 
 double HolzapfelMaterial::energyIso(const Tensor &C) const {
   double I_1 = trace(C);
-  return 0.5 * a() / b() * (mat::cutexp(b() * (I_1 - 3)) - 1);
+  return 0.5 * a() / b() * (mat::cutexp(b() * (I_1 - 3),exp_max) - 1);
 }
 
 Tensor HolzapfelMaterial::firstPKIso(const Tensor &C) const {
   double I_1 = trace(C);
-  Tensor Psi = 0.5 * a() * (mat::cutexp(b() * (I_1 - 3))) * One;
+  Tensor Psi = 0.5 * a() * (mat::cutexp(b() * (I_1 - 3),exp_max)) * One;
   return Psi;
 }
 
 Tensor
 HolzapfelMaterial::constitutiveMatrixIso(const Tensor &C, const Tensor &H) const {
   double I_1 = trace(C);
-  Tensor Psi = 0.5 * a() * b()* (mat::cutexp(b() * (I_1 - 3))) * trace(H) * One;
+  Tensor Psi = 0.5 * a() * b()* (mat::cutexp(b() * (I_1 - 3),exp_max)) * trace(H) * One;
   return Psi;
 }
 
 double HolzapfelMaterial::energyAniso(const Tensor &C, const Tensor &Q) const {
   double I_4f = macaulay(Q[0] * (C * Q[0]) - 1.0);
-  double energy = af() / (2.0 * bf()) * (mat::cutexp(bf() * I_4f * I_4f) - 1);
+  double energy = af() / (2.0 * bf()) * (mat::cutexp(bf() * I_4f * I_4f,exp_max) - 1);
 
   double I_4s = macaulay(Q[1] * (C * Q[1]) - 1.0);
-  energy += as() / (2.0 * bs()) * (mat::cutexp(bs() * I_4s * I_4s) - 1);
+  energy += as() / (2.0 * bs()) * (mat::cutexp(bs() * I_4s * I_4s,exp_max) - 1);
 
   double I_8fs = Q[0] * (C * Q[1]);
-  energy += afs() / (2.0 * bfs()) * (mat::cutexp(bfs() * I_8fs * I_8fs) - 1);
+  energy += afs() / (2.0 * bfs()) * (mat::cutexp(bfs() * I_8fs * I_8fs,exp_max) - 1);
 
   return energy;
 }
 
 Tensor HolzapfelMaterial::firstPKAniso(const Tensor &C, const Tensor &Q) const {
   double I_4f = macaulay(Q[0] * (C * Q[0]) - 1.0);
-  Tensor Psi = af() * mat::cutexp(bf() * I_4f * I_4f) * I_4f * Product(Q[0], Q[0]);
+  Tensor Psi = af() * mat::cutexp(bf() * I_4f * I_4f,exp_max) * I_4f * Product(Q[0], Q[0]);
 
   double I_4s = macaulay(Q[1] * (C * Q[1]) - 1.0);
-  Psi += as() * mat::cutexp(bs() * I_4s * I_4s) * I_4s * Product(Q[1], Q[1]);
+  Psi += as() * mat::cutexp(bs() * I_4s * I_4s,exp_max) * I_4s * Product(Q[1], Q[1]);
 
   double I_8fs = Q[0] * (C * Q[1]);
-  Psi += afs() * mat::cutexp(bfs() * I_8fs * I_8fs) * I_8fs * sym(Product(Q[0], Q[1]));
+  Psi += afs() * mat::cutexp(bfs() * I_8fs * I_8fs,exp_max) * I_8fs * sym(Product(Q[0], Q[1]));
 
   return Psi;
 }
@@ -48,15 +48,15 @@ Tensor
 HolzapfelMaterial::constitutiveMatrixAniso(const Tensor &C, const Tensor &Q, const Tensor &H) const {
   double I_4f = macaulay(Q[0] * (C * Q[0]) - 1.0);
   double Hf = Q[0] * (H * Q[0]);
-  Tensor Psi = af() * mat::cutexp(bf() * I_4f * I_4f) * Hf * (2 * bf() * I_4f * I_4f + 1) * Product(Q[0], Q[0]);
+  Tensor Psi = af() * mat::cutexp(bf() * I_4f * I_4f,exp_max) * Hf * (2 * bf() * I_4f * I_4f + 1) * Product(Q[0], Q[0]);
 
   double I_4s = macaulay(Q[1] * (C * Q[1]) - 1.0);
   double Hs = Q[1] * (H * Q[1]);
-  Psi += as() * mat::cutexp(bs() * I_4s * I_4s) * Hs * (2 * bs() * I_4s * I_4s + 1) * Product(Q[1], Q[1]);
+  Psi += as() * mat::cutexp(bs() * I_4s * I_4s,exp_max) * Hs * (2 * bs() * I_4s * I_4s + 1) * Product(Q[1], Q[1]);
 
   double I_8fs = Q[0] * (C * Q[1]);
   double Hfs = 0.5 * (Q[0] * (H * Q[1]) + Q[1] * (H * Q[0]));
-  Psi += afs() * mat::cutexp(bfs() * I_8fs * I_8fs) * Hfs * (2 * bfs() * I_8fs * I_8fs + 1) * sym(Product(Q[0], Q[1]));
+  Psi += afs() * mat::cutexp(bfs() * I_8fs * I_8fs,exp_max) * Hfs * (2 * bfs() * I_8fs * I_8fs + 1) * sym(Product(Q[0], Q[1]));
 
   return Psi;
 }
diff --git a/src/elasticity/materials/HolzapfelMaterial.hpp b/src/elasticity/materials/HolzapfelMaterial.hpp
index 77117a8349863375e51c942d95a573124882b7bf..f46d801815ff9234d27eeb160e2d77c934e3325b 100644
--- a/src/elasticity/materials/HolzapfelMaterial.hpp
+++ b/src/elasticity/materials/HolzapfelMaterial.hpp
@@ -10,6 +10,8 @@
  * See i.e. doi:10.1016/j.ijnonlinmec.2006.02.001
  */
 class HolzapfelMaterial : public HyperelasticMaterial {
+  double exp_max = 10;
+
   double a() const { return GetParameter(0); }
 
   double af() const { return GetParameter(1); }
@@ -57,12 +59,17 @@ public:
     Config::Get("HolzapfelMat_bf", parameters[5]);
     Config::Get("HolzapfelMat_bs", parameters[6]);
     Config::Get("HolzapfelMat_bfs", parameters[7]);
+    Config::Get("exp_max", exp_max);
   }
 
-  explicit HolzapfelMaterial(const std::vector<double> &params) : HyperelasticMaterial("Holzapfel", params) {};
+  explicit HolzapfelMaterial(const std::vector<double> &params) : HyperelasticMaterial("Holzapfel", params) {
+    Config::Get("exp_max", exp_max);
+  };
 
   explicit HolzapfelMaterial(std::vector<double> &&params) : HyperelasticMaterial("Holzapfel",
-                                                                                  std::move(params)) {};
+                                                                                  std::move(params)) {
+    Config::Get("exp_max", exp_max);
+  };
 
 
   Tensor FirstPiolaKirchhoff(const Tensor &F, const Tensor &Fiso, const Tensor &Q) const override;
diff --git a/src/elasticity/materials/Material.hpp b/src/elasticity/materials/Material.hpp
index ba618cbf11407d70bdfd672e63a4a7f9b9a16b21..cdb1f6a517a7b73da6841af0fab689c505981423 100644
--- a/src/elasticity/materials/Material.hpp
+++ b/src/elasticity/materials/Material.hpp
@@ -24,6 +24,9 @@ public:
   HyperelasticMaterial(std::string &&name, std::vector<double> &&params) noexcept: name(std::move(name)), parameters(
       std::move(params)) {}
 
+  virtual double q(const Tensor &E, const VectorField &f) const { return 0; }
+
+  
   /**
    * Returns the strain energy of the material given the deformation Gradient F
    * @param F = (Du + One) for the derivative Du of a given displacement u.
@@ -165,7 +168,10 @@ public:
   IsoSecondDerivative(const Tensor &F, const T &H, const T &G) const {
     return hyperelMat->IsotropicSecondDerivative(F, H, G);
   }
-
+  
+  double q(const Tensor &E, const VectorField &f) const { 
+    return hyperelMat->q(E,f);
+  }
 
   double AnisoEnergy(const Tensor &F, const Tensor &Q) const {
     return hyperelMat->AnisotropicEnergy(F, Q);
diff --git a/src/elasticity/materials/VolumetricPenalty.hpp b/src/elasticity/materials/VolumetricPenalty.hpp
index 57bf5699757fb1a1f6cf1fb64bd699be4e9f6e67..fa70c96b14cbe7fb032a076698f01496ebc5426c 100644
--- a/src/elasticity/materials/VolumetricPenalty.hpp
+++ b/src/elasticity/materials/VolumetricPenalty.hpp
@@ -45,14 +45,22 @@ public:
 
   CiarletPenalty(double p) : VolumetricPenalty(p) {}
 
-  CiarletPenalty(double p, double m) : VolumetricPenalty(p), mu(p > 0.0 ? m / p : 1.0) {
-  }
+  CiarletPenalty(double p, double m) : VolumetricPenalty(p), mu(p > 0.0 ? m / p : 1.0) {}
 
-  double Functional(double J) const override { return 0.5 * (J - 1.0) * (J - 1.0) - mu * log(J); };
+  double Functional(double J) const override {
+    if (J <= 0) {
+      return 0;
+    }
+    return 0.5 * (J - 1.0) * (J - 1.0) - mu * log(J);
+  }
 
-  double Derivative(double J) const override {return (J - 1.0) - mu / J; };
+  double Derivative(double J) const override {
+    return (J - 1.0) - mu / J;
+  }
 
-  double SecondDerivative(double J) const override { return 1.0 + mu / (J * J); };
+  double SecondDerivative(double J) const override {
+    return 1.0 + mu / (J * J);
+  }
 };
 
 class LogarithmicCompressiblePenalty : public VolumetricPenalty {
@@ -61,7 +69,8 @@ public:
 
   LogarithmicCompressiblePenalty(double p) : VolumetricPenalty(p) {}
 
-  double Functional(double J) const override { return 0.5 * (J - 1.0) * log(J); };
+  double Functional(double J) const override { return 0.5 * (J - 1.0) * log(J);
+  }
 
   double Derivative(double J) const override { return 0.5 * (log(J) + (J - 1.0) / J); };
 
diff --git a/src/elasticity/materials/materials.hpp b/src/elasticity/materials/materials.hpp
index 3db20c3e59ec52809c3b6d173b057e5c67eec095..00611e6bd923cb0cd50861ed81f22d46ac04678c 100644
--- a/src/elasticity/materials/materials.hpp
+++ b/src/elasticity/materials/materials.hpp
@@ -1,12 +1,12 @@
 #ifndef MATERIALS_HPP
 #define MATERIALS_HPP
 
-
 #include "Tensor.hpp"
 
 namespace mat {
-  constexpr double cutexp(double argument, double max = 35.0) {
-    return exp(min(argument, max));
+  constexpr double cutexp(double argument, double max = 35) {
+    if (argument<max) return exp(argument);
+    return exp(max) * (1 + argument-max);
   }
 
   static Tensor cofactor(const Tensor &F) {
diff --git a/src/elasticity/problem/ElasticityProblem.cpp b/src/elasticity/problem/ElasticityProblem.cpp
index e812f9aa13d33b93ced7d7e6c738fe82b6cd09d4..9be4e99f3be0888b2dcfb51f1eb90fa351875533 100644
--- a/src/elasticity/problem/ElasticityProblem.cpp
+++ b/src/elasticity/problem/ElasticityProblem.cpp
@@ -8,9 +8,8 @@
 
 std::vector<double> findDisplacements(const Vector &u, const vector<Point> &points, int index) {
   std::vector<double> displacements(points.size());
-  std::string disc = "";
-  Config::Get("MechDiscretization",disc);
-  if (contains(disc,"Conforming") || contains(disc,"EG")) {
+
+  if (!contains(u.GetDisc().DiscName(),"DG")) {
     for (row r = u.rows(); r != u.rows_end(); ++r) {
       auto [i, isNear] = isIn(r(), points);
       if (isNear) {
@@ -26,7 +25,7 @@ std::vector<double> findDisplacements(const Vector &u, const vector<Point> &poin
       displacements[i] = PPM->Sum(displacements[i]);
     }
   }
-  else if (contains(disc,"DG")) {
+  else {
     std::vector<VectorField> disp(points.size());
     disp = findDisplacements(u,points);
     for (int l = 0; l < displacements.size(); ++l) {
@@ -38,9 +37,7 @@ std::vector<double> findDisplacements(const Vector &u, const vector<Point> &poin
 
 std::vector<VectorField> findDisplacements(const Vector &u, const vector<Point> &points) {
   std::vector<VectorField> displacements(points.size());
-  std::string disc = "";
-  Config::Get("MechDiscretization",disc);
-  if (contains(disc,"Conforming") || contains(disc,"EG")) {
+  if (!contains(u.GetDisc().DiscName(),"DG")) {
     for (row r = u.rows(); r != u.rows_end(); ++r) {
       auto [i, isNear] = isIn(r(), points);
       if (isNear) {
@@ -58,7 +55,7 @@ std::vector<VectorField> findDisplacements(const Vector &u, const vector<Point>
       displacements[i] = PPM->Sum(displacements[i]);
     }
   }
-  else if (contains(disc,"DG")) {
+  else {
     std::vector<int> cellCount(points.size());
 
     for (cell c = u.cells(); c != u.cells_end(); ++c) {
@@ -84,7 +81,7 @@ std::vector<VectorField> findDisplacements(const Vector &u, const vector<Point>
 }
 
 
-ElasticityProblem::ElasticityProblem() : IProblem(), IElasticityProblem(), IPressureProblem() {
+ElasticityProblem::ElasticityProblem() : CardMechIProblem(), IElasticityProblem(), IPressureProblem() {
   Config::Get("MechProblemVerbose", verbose);
 
   std::string aMatName{"Linear"};
@@ -98,7 +95,7 @@ ElasticityProblem::ElasticityProblem() : IProblem(), IElasticityProblem(), IPres
 
 ElasticityProblem::ElasticityProblem(const std::string &matName,
                                      const std::vector<double> &matParameters)
-    : IProblem(), IElasticityProblem(), IPressureProblem() {
+    : CardMechIProblem(), IElasticityProblem(), IPressureProblem() {
   Config::Get("MechProblemVerbose", verbose);
   activeMaterial = Material(matName, matParameters);
   passiveMaterial = Material(matName, matParameters);
diff --git a/src/elasticity/problem/ElasticityProblem.hpp b/src/elasticity/problem/ElasticityProblem.hpp
index 21b0351f702fe094d887148099090206dbf06f1f..14e32b3ad53d3eb047a69982b5b8d9095e79c055 100644
--- a/src/elasticity/problem/ElasticityProblem.hpp
+++ b/src/elasticity/problem/ElasticityProblem.hpp
@@ -1,22 +1,22 @@
 #ifndef ELASTICITYPROBLEM_HPP
 #define ELASTICITYPROBLEM_HPP
 
-#include "IProblem.hpp"
+#include "CardMechIProblem.hpp"
 #include "Vector.hpp"
 
 #include "CardiacProblem.hpp"
 #include "materials/Material.hpp"
 
 namespace mpp {
-  template<class T, class Alloc, class Pred>
-  constexpr typename std::vector<T, Alloc>::size_type
-  erase_if(std::vector<T, Alloc> &c, Pred pred) {
-    auto it = std::remove_if(c.begin(), c.end(), pred);
-    auto r = std::distance(it, c.end());
-    c.erase(it, c.end());
-    return r;
-  }
+template <class T, class Alloc, class Pred>
+constexpr typename std::vector<T, Alloc>::size_type
+erase_if(std::vector<T, Alloc> &c, Pred pred) {
+  auto it = std::remove_if(c.begin(), c.end(), pred);
+  auto r = std::distance(it, c.end());
+  c.erase(it, c.end());
+  return r;
 }
+} // namespace mpp
 
 std::array<double, 4> pressureFromConfig();
 double pressureFromConfig(short chamber);
@@ -24,14 +24,15 @@ double pressureFromConfig(short chamber);
 std::vector<double>
 findDisplacements(const Vector &u, const std::vector<Point> &points, int index);
 
-std::vector<VectorField>
-findDisplacements(const Vector &u, const std::vector<Point> &points);
+std::vector<VectorField> findDisplacements(const Vector &u,
+                                           const std::vector<Point> &points);
 
 class IElasticityProblem {
   bool useFlorySplit{false};
   bool isStatic{false};
 
   std::string elasticityModel{"Conforming"};
+
 public:
   IElasticityProblem() {
     Config::Get("MechDiscretization", elasticityModel);
@@ -40,121 +41,176 @@ public:
     Config::Get("VolumetricSplit", useFlorySplit);
   }
 
-  [[nodiscard]] virtual const std::string &Model() const { return elasticityModel; }
+  [[nodiscard]] virtual const std::string &Model() const {
+    return elasticityModel;
+  }
+
+  virtual const void SetModel(std::string modelName) {
+    elasticityModel = modelName;
+  }
 
   [[nodiscard]] virtual bool IsStatic() const { return isStatic; }
 
-  [[nodiscard]] virtual VectorField
-  Load(double t, const Point &x, const Cell &c) const { return zero; };
+  [[nodiscard]] virtual VectorField Load(double t, const Point &x,
+                                         const Cell &c) const {
+    return zero;
+  };
 
-  [[nodiscard]] virtual double ActiveStress(double t, const Point &x) const { return 0.0; };
+  [[nodiscard]] virtual double ActiveStress(double t, const Point &x) const {
+    return 0.0;
+  };
 
-  [[nodiscard]] virtual double ActiveStretch(double t, const Point &x) const { return 0.0; };
+  [[nodiscard]] virtual double ActiveStretch(double t, const Point &x) const {
+    return 0.0;
+  };
 
-  [[nodiscard]] virtual double
-  TractionStiffness(double t, const Point &x, int sd) const { return 0.0; };
+  [[nodiscard]] virtual double TractionStiffness(double t, const Point &x,
+                                                 int sd) const {
+    return 0.0;
+  };
 
-  [[nodiscard]] virtual double
-  TractionViscosity(double t, const Point &x, int sd) const { return 0.0; };
+  [[nodiscard]] virtual double TractionViscosity(double t, const Point &x,
+                                                 int sd) const {
+    return 0.0;
+  };
 
   [[nodiscard]] Tensor IsochoricPart(const Tensor &F) const {
     return useFlorySplit ? pow(det(F), -1.0 / 3.0) * F : F;
   }
 
-  [[nodiscard]] virtual VectorField Deformation(double time, const Point &x) const { return zero; };
+  [[nodiscard]] virtual VectorField Deformation(double time,
+                                                const Point &x) const {
+    return zero;
+  };
 
-  [[nodiscard]] virtual VectorField Velocity(double time, const Point &x) const { return zero; };
+  [[nodiscard]] virtual VectorField Velocity(double time,
+                                             const Point &x) const {
+    return zero;
+  };
 
-  [[nodiscard]] virtual VectorField
-  Acceleration(double time, const Point &x) const { return zero; };
+  [[nodiscard]] virtual VectorField Acceleration(double time,
+                                                 const Point &x) const {
+    return zero;
+  };
 
-  [[nodiscard]] virtual Tensor
-  DeformationGradient(double time, const Point &x) const { return Zero; };
+  [[nodiscard]] virtual Tensor DeformationGradient(double time,
+                                                   const Point &x) const {
+    return Zero;
+  };
 };
 
 class IPressureProblem {
   mutable double pressureScale{1.0};
+
 protected:
-  virtual double pressure(double t, const Point &x, int bndCondition) const { return 0.0; }
+  virtual double pressure(double t, const Point &x, int bndCondition) const {
+    return 0.0;
+  }
+
 public:
   IPressureProblem() = default;
 
-  [[nodiscard]] virtual double Scale() const{
-    return pressureScale;
-  }
+  [[nodiscard]] virtual double Scale() const { return pressureScale; }
 
   virtual void Scale(double s) const {
-    pressureScale = ((s>1.0) + (0.0<s<=1.0) * s);
+    pressureScale = ((s > 1.0) + (0.0 < s <= 1.0) * s);
   }
 
   virtual double Pressure(double t, const Point &x, int bndCondition) const {
     return Scale() * pressure(t, x, bndCondition);
   }
 
-  virtual double InitialPressure(const Point &x, int bndCondition) const { return 0.0; }
+  virtual double InitialPressure(const Point &x, int bndCondition) const {
+    return 0.0;
+  }
 
-  virtual void Initialize(double dt, double t, const std::array<double, 4> &mechVolumes) {}
+  virtual void Initialize(double dt, double t,
+                          const std::array<double, 4> &mechVolumes) {}
 
-  virtual void Update(double dt, double t, const std::array<double, 4> &mechVolumes) {}
+  virtual void Update(double dt, double t,
+                      const std::array<double, 4> &mechVolumes) {}
 
-  virtual void Finalize(double dt, double t, const std::array<double, 4> &mechVolumes) {}
+  virtual void Finalize(double dt, double t,
+                        const std::array<double, 4> &mechVolumes) {}
 
-  virtual void Iterate(double dt, double t, const std::array<double, 4> &mechVolumes) {}
+  virtual void Iterate(double dt, double t,
+                       const std::array<double, 4> &mechVolumes) {}
 
-  virtual bool Converged(const std::array<double, 4> &mechVolumes) { return true; }
+  virtual bool Converged(const std::array<double, 4> &mechVolumes) {
+    return true;
+  }
 };
 
-
-class ElasticityProblem : public IProblem, public IElasticityProblem, public IPressureProblem {
+class ElasticityProblem : public CardMechIProblem,
+                          public IElasticityProblem,
+                          public IPressureProblem {
 protected:
   std::string elasticityModel{"Conforming"};
 
   Material activeMaterial;
   Material passiveMaterial;
 
+  double DGpenalty = 0;
+
   bool meshFromConfig() const { return meshesName != ""; }
+
 public:
   ElasticityProblem();
 
-  ElasticityProblem(const std::string& matName, const std::vector<double>& matParameters);
+  ElasticityProblem(const std::string &matName,
+                    const std::vector<double> &matParameters);
 
   [[nodiscard]] const string &GetMeshName() const { return meshesName; }
 
+  virtual const void SetMeshName(std::string meshName) {
+    meshesName = meshName;
+  }
 
   [[nodiscard]] const string &GetMaterialName(bool active) const {
     return (active ? activeMaterial.Name() : passiveMaterial.Name());
   };
 
   [[nodiscard]] const Material &GetMaterial(const cell &c) const {
-    //TODO: enable different materials
+    // TODO: enable different materials
     bool isActive = true;
     return (isActive ? activeMaterial : passiveMaterial);
   }
 
-  [[nodiscard]] Material &GetMaterial() {
-    return activeMaterial;
-  }
+  [[nodiscard]] Material &GetMaterial() { return activeMaterial; }
 
-  [[nodiscard]] std::pair<const Material &, const Material &> GetMaterials() const {
-    return std::pair<const Material &, const Material &>{activeMaterial, passiveMaterial};
+  [[nodiscard]] std::pair<const Material &, const Material &>
+  GetMaterials() const {
+    return std::pair<const Material &, const Material &>{activeMaterial,
+                                                         passiveMaterial};
   }
 
-  [[nodiscard]] virtual std::string Evaluate(const Vector &solution) const { return ""; };
+  [[nodiscard]] virtual std::string Evaluate(const Vector &solution) const {
+    return "";
+  };
 
-  [[nodiscard]] virtual std::vector<std::string> EvaluationMetrics() const { return {}; }
+  [[nodiscard]] virtual std::vector<std::string> EvaluationMetrics() const {
+    return {};
+  }
 
   [[nodiscard]] virtual std::vector<double>
-  EvaluationResults(const Vector &solution) const { return std::vector<double>{}; }
+  EvaluationResults(const Vector &solution) const {
+    return std::vector<double>{};
+  }
 
-};
+  [[nodiscard]] virtual const double &GetDGPenalty() const { return DGpenalty; }
 
+  virtual const void SetDGPenalty(double p) { DGpenalty = p; }
+};
 
 class DefaultElasticityProblem : public ElasticityProblem {
   std::array<double, 4> chamberPressure{0.0, 0.0, 0.0, 0.0};
+
 protected:
-  [[nodiscard]] double pressure(double t, const Point &x, int bndCondition) const override {
+  [[nodiscard]] double pressure(double t, const Point &x,
+                                int bndCondition) const override {
     return chamberPressure[bndCondition % 230];
   }
+
 public:
   DefaultElasticityProblem()
       : ElasticityProblem(), chamberPressure(pressureFromConfig()) {}
@@ -165,25 +221,26 @@ public:
   explicit DefaultElasticityProblem(std::array<double, 4> pressure)
       : ElasticityProblem(), chamberPressure(pressure) {}
 
-
   [[nodiscard]] std::string Name() const override {
     return "Default Elasticity Problem";
   }
 };
 
-
 class InitialPrestressProblem : public ElasticityProblem {
   const ElasticityProblem &refProblem;
+
 protected:
-  [[nodiscard]] double pressure(double t, const Point &x, int bndCondition) const override {
+  [[nodiscard]] double pressure(double t, const Point &x,
+                                int bndCondition) const override {
     return refProblem.Pressure(0.0, x, bndCondition);
   }
-public:
-  InitialPrestressProblem(const ElasticityProblem &reference) : refProblem(reference) {
 
-  }
+public:
+  InitialPrestressProblem(const ElasticityProblem &reference)
+      : refProblem(reference) {}
 
-  [[nodiscard]] VectorField Load(double t, const Point &x, const Cell &c) const override {
+  [[nodiscard]] VectorField Load(double t, const Point &x,
+                                 const Cell &c) const override {
     return refProblem.Load(0.0, x, c);
   }
 
@@ -191,27 +248,33 @@ public:
     return refProblem.ActiveStretch(0.0, x);
   }
 
-  [[nodiscard]] double TractionStiffness(double t, const Point &x, int sd) const override {
+  [[nodiscard]] double TractionStiffness(double t, const Point &x,
+                                         int sd) const override {
     return refProblem.TractionStiffness(t, x, sd);
   }
 
-  [[nodiscard]] double TractionViscosity(double t, const Point &x, int sd) const override {
+  [[nodiscard]] double TractionViscosity(double t, const Point &x,
+                                         int sd) const override {
     return refProblem.TractionViscosity(t, x, sd);
   }
 
-  [[nodiscard]] VectorField Deformation(double time, const Point &x) const override {
+  [[nodiscard]] VectorField Deformation(double time,
+                                        const Point &x) const override {
     return refProblem.Deformation(0.0, x);
   }
 
-  [[nodiscard]] VectorField Velocity(double time, const Point &x) const override {
+  [[nodiscard]] VectorField Velocity(double time,
+                                     const Point &x) const override {
     return refProblem.Velocity(0.0, x);
   }
 
-  [[nodiscard]] VectorField Acceleration(double time, const Point &x) const override {
+  [[nodiscard]] VectorField Acceleration(double time,
+                                         const Point &x) const override {
     return refProblem.Acceleration(0.0, x);
   }
 
-  [[nodiscard]] Tensor DeformationGradient(double time, const Point &x) const override {
+  [[nodiscard]] Tensor DeformationGradient(double time,
+                                           const Point &x) const override {
     return refProblem.DeformationGradient(0.0, x);
   }
 
@@ -219,10 +282,7 @@ public:
     return refProblem.Model();
   }
 
-  [[nodiscard]] bool IsStatic() const override {
-    return refProblem.IsStatic();
-  }
-
+  [[nodiscard]] bool IsStatic() const override { return refProblem.IsStatic(); }
 
   [[nodiscard]] string Name() const override {
     return "Initial Prestress Problem";
@@ -231,6 +291,7 @@ public:
 
 std::unique_ptr<ElasticityProblem> GetElasticityProblem();
 
-std::unique_ptr<ElasticityProblem> GetElasticityProblem(const std::string &problemName);
+std::unique_ptr<ElasticityProblem>
+GetElasticityProblem(const std::string &problemName);
 
-#endif //ELASTICITYPROBLEM_HPP
+#endif // ELASTICITYPROBLEM_HPP
diff --git a/src/elasticity/solvers/IterativePressureSolver.cpp b/src/elasticity/solvers/IterativePressureSolver.cpp
index a7c2514129367e6b908e19212e7f52af2654bca9..5b0cd9d576314c00f19a222a802dab2b55b77a3a 100644
--- a/src/elasticity/solvers/IterativePressureSolver.cpp
+++ b/src/elasticity/solvers/IterativePressureSolver.cpp
@@ -4,7 +4,6 @@
 #include <chrono>
 #include "LagrangeTransfer.hpp"
 
-
 void IterativePressureSolver::Initialize(IElasticity &assemble, Vector &u) {
   problem.Scale(0.0);
   assemble.SetInitialValue(u);
@@ -24,11 +23,8 @@ bool IterativePressureSolver::Method(IElasticity &assemble, Vector &u) {
   Vector uNew(u);
 
   Initialize(assemble, uNew);
-
   while (!iteration.IsFinished()) {
-    //for loop overlevels:
-    //{ u0 u1,....
-        bool converged = Step(assemble, uNew);
+    bool converged = Step(assemble, uNew);
 
     if(converged) {
       //mapping von corse to finer
@@ -46,7 +42,6 @@ bool IterativePressureSolver::Method(IElasticity &assemble, Vector &u) {
         return Method(assemble, u);
       return false;
     }
-    //}
   }
   mout.EndBlock();
   return true;
diff --git a/src/electrophysiology/MainMonodomain.cpp b/src/electrophysiology/MainMonodomain.cpp
index 402509dfc6369aecd1edb969345768709329593b..3213cc0e07b241ece5bd1032d57afd59980ff6cd 100644
--- a/src/electrophysiology/MainMonodomain.cpp
+++ b/src/electrophysiology/MainMonodomain.cpp
@@ -41,7 +41,7 @@ void MainMonodomain::Initialize() {
   elphyA->ResetTime(times[0], times[1], times[2]);
 
   // Initialize Vectors
-  potential = std::make_unique<Vector>(0.0, elphyA->GetDisc());
+  potential = std::make_unique<Vector>(0.0, elphyA->GetSharedDisc());
   problem->SetEvaluationCells(*potential);
 
   bool printMeshOnly = false;
diff --git a/src/electrophysiology/MainOneCell.cpp b/src/electrophysiology/MainOneCell.cpp
index 58a5811d80c0a55c9fe6238d3dc37152e31d9158..700ede9d1265dcf2017eb67a7c7f6a5865970617 100644
--- a/src/electrophysiology/MainOneCell.cpp
+++ b/src/electrophysiology/MainOneCell.cpp
@@ -23,7 +23,7 @@ Vector &MainOneCell::Run() {
     auto cellModel = GetElphyModel();
     elphyA = CreateElphyAssemble(*problem, *cellModel, 0);
     elphyA->ResetTime(times[0], times[1], times[2]);
-    potential = std::make_unique<Vector>(cellModel->InitialValue(ELPHY), elphyA->GetDisc());
+    potential = std::make_unique<Vector>(cellModel->InitialValue(ELPHY), elphyA->GetSharedDisc());
     if (problem->Name() == "EigenvalueProblem") {
       MElphySolver solver(*cellModel, elphyA->ExcitationData(), "Eigenvalue");
       solver.SetVerbose(15);
diff --git a/src/electrophysiology/assemble/IElphyAssemble.cpp b/src/electrophysiology/assemble/IElphyAssemble.cpp
index aee71d85046bfd963898d17e77065432b5238403..e49e36a2affa8b38edb70610c43dee5ff2ea8758 100644
--- a/src/electrophysiology/assemble/IElphyAssemble.cpp
+++ b/src/electrophysiology/assemble/IElphyAssemble.cpp
@@ -13,9 +13,9 @@
 
 IElphyAssemble::IElphyAssemble(ElphyProblem &elphyProblem, int degree, int exactUpTo)
     : INonLinearTimeAssemble(), ICardiacAssemble("ElphyVTK"), problem(elphyProblem), degree(degree),
-      disc(elphyProblem.GetMeshes(), degree, exactUpTo < 0 ? 2 * degree : exactUpTo, DomainPart, 1),
-      dataDisc(elphyProblem.GetMeshes(), degree, exactUpTo < 0 ? 2 * degree : exactUpTo, DomainPart,
-               3),
+      disc(std::make_shared<const MultiPartDiscretization>(elphyProblem.GetMeshes(), degree, exactUpTo < 0 ? 2 * degree : exactUpTo, DomainPart, 1)),
+      dataDisc(std::make_shared<const MultiPartDiscretization>(elphyProblem.GetMeshes(), degree, exactUpTo < 0 ? 2 * degree : exactUpTo, DomainPart,
+               3)),
       excData(std::move(InterpolateMeshData(dataDisc))) {
   Config::Get("ElphyVerbose", verbose);
   Config::Get("IsExternalCurrentSmooth", iextContinuous);
diff --git a/src/electrophysiology/assemble/IElphyAssemble.hpp b/src/electrophysiology/assemble/IElphyAssemble.hpp
index b2862a77f0dee1eb3825ac5ea6e0ec0624f2a45d..68425c47874c1211e3444705e46afc2b3cce66eb 100644
--- a/src/electrophysiology/assemble/IElphyAssemble.hpp
+++ b/src/electrophysiology/assemble/IElphyAssemble.hpp
@@ -25,8 +25,8 @@ protected:
 
   //Discretization
   int degree{1};
-  const MultiPartDiscretization disc;
-  const MultiPartDiscretization dataDisc;
+  std::shared_ptr<const MultiPartDiscretization> disc;
+  std::shared_ptr<const MultiPartDiscretization> dataDisc;
   Vector excData;
 
   int printVSteps{1};
@@ -36,12 +36,10 @@ public:
   IElphyAssemble(ElphyProblem &elphyProblem, int degree, int exactUpTo = -1);
 
   const IDiscretization &GetDisc() const {
-    return disc;
+    return *disc;
   }
 
-  std::unique_ptr<IDiscretization> CreateDisc(int size) const {
-    return std::make_unique<MultiPartDiscretization>(disc, size);
-  }
+  std::shared_ptr<const IDiscretization> GetSharedDisc() const { return disc; }
 
   virtual void Initialize(Vector &u) const {};
 
diff --git a/src/electrophysiology/assemble/Monodomain.cpp b/src/electrophysiology/assemble/Monodomain.cpp
index 948244a0600e799faa0c05645866200f32baf17e..3c2bb6a1a71e0005685175fbf69c5f26484f938a 100644
--- a/src/electrophysiology/assemble/Monodomain.cpp
+++ b/src/electrophysiology/assemble/Monodomain.cpp
@@ -196,8 +196,8 @@ void Monodomain::RHS(const cell &c, const Vectors &VCW, Vector &r) const {
 MonodomainLINodes::MonodomainLINodes(ElphyProblem &elphyProblem, MCellModel &cellModel,
                                      int degree, int exactUpTo) : Monodomain(elphyProblem, cellModel,
                                                                          degree, exactUpTo) {
-  IionVEC = std::make_unique<Vector>(0.0, GetDisc());
-  DVIionVEC = std::make_unique<Vector>(0.0, GetDisc());
+  IionVEC = std::make_unique<Vector>(0.0, GetSharedDisc());
+  DVIionVEC = std::make_unique<Vector>(0.0, GetSharedDisc());
 }
 
 void MonodomainLINodes::updateIionVecs(const Vectors &VCW) {
@@ -340,8 +340,8 @@ MonodomainQuadrature::MonodomainQuadrature(ElphyProblem &elphyProblem, MCellMode
       nJ = E.size();
     }
 
-    CWdisc = std::make_unique<DoFDiscretization<CellDoF>>(u.GetDisc().GetMeshes(), nQ * nJ);
-    CWcells = std::make_unique<Vector>(*CWdisc);
+    CWdisc = std::make_shared<DoFDiscretization<CellDoF>>(u.GetDisc().GetMeshes(), nQ * nJ);
+    CWcells = std::make_unique<Vector>(CWdisc);
     VCWQuadrature = std::make_unique<Vectors>(elphyModel.ElphySize(), *CWcells);
     elphyModel.Initialize(*VCWQuadrature);
   }
@@ -420,7 +420,7 @@ void MonodomainQuadrature::RHS(const cell &c, const Vectors &VCW, Vector &r) con
 MonodomainFullNewton::MonodomainFullNewton(ElphyProblem &elphyProblem, MCellModel &cellModel,
                                            int degree, int exactUpTo)
     : Monodomain(elphyProblem, cellModel, degree, exactUpTo) {
-  VACAW = std::make_unique<Vectors>(elphyModel.ElphySize(), GetDisc());
+  VACAW = std::make_unique<Vectors>(elphyModel.ElphySize(), GetSharedDisc());
   elphyModel.Initialize(*VACAW);
 
   /*if(MK==nullptr){
diff --git a/src/electrophysiology/assemble/Monodomain.hpp b/src/electrophysiology/assemble/Monodomain.hpp
index 561ac224ce00ce38dc1c3e28f3a59393f429da2d..3cd2c453b7e8bccc0ed8798e85ce0c52387a53d3 100644
--- a/src/electrophysiology/assemble/Monodomain.hpp
+++ b/src/electrophysiology/assemble/Monodomain.hpp
@@ -137,7 +137,7 @@ public:
 class MonodomainQuadrature : public Monodomain {
   std::unique_ptr<Vectors> VCWQuadrature;
   std::unique_ptr<Vector> CWcells;
-  std::unique_ptr<DoFDiscretization<CellDoF>> CWdisc;
+  std::shared_ptr<DoFDiscretization<CellDoF>> CWdisc;
 public:
   MonodomainQuadrature(ElphyProblem &elphyProblem, MCellModel &cellModel, const Vector &u,
                        int degree, int exactUpTo = -1);
@@ -199,7 +199,7 @@ public:
   MonodomainSemiImplicitNodes(ElphyProblem &elphyProblem, MCellModel &cellModel, int degree,
                               int exactUpTo = -1)
       : Monodomain(elphyProblem, cellModel, degree, exactUpTo) {
-    IionVEC = std::make_unique<Vector>(0.0, GetDisc());
+    IionVEC = std::make_unique<Vector>(0.0, GetSharedDisc());
 
   };
 
@@ -210,17 +210,15 @@ public:
 };
 class MonodomainSemiImplicitCells : public Monodomain {
 protected:
-  std::unique_ptr<LagrangeDiscretization> disc0;
+  std::shared_ptr<LagrangeDiscretization> disc0;
   std::unique_ptr<Vector> IionCell;
-
 public:
   MonodomainSemiImplicitCells(ElphyProblem &elphyProblem, MCellModel &cellModel, int degree,
                               int exactUpTo = -1)
       : Monodomain(elphyProblem, cellModel, degree, exactUpTo) {
     const Meshes &mesh = GetDisc().GetMeshes();
-    disc0=std::make_unique<LagrangeDiscretization >(mesh, 0, 1);
-    IionCell = std::make_unique<Vector>(0.0,*disc0);
-
+    disc0 = std::make_shared<LagrangeDiscretization >(mesh, 0, 1);
+    IionCell = std::make_unique<Vector>(0.0, disc0);;
 
   };
 
@@ -230,7 +228,6 @@ public:
   virtual void RHS(const cell &c, const Vector &u, Vector &r) const override;
   void updateIionVecs(const Vectors &VCW) override;
 
-
 };
 class MonodomainSemiImplicitCellsIextPerCell : public MonodomainSemiImplicitCells {
   std::unique_ptr<Vectors> externalCurrentOnCells;;
@@ -239,7 +236,7 @@ public:
   MonodomainSemiImplicitCellsIextPerCell(ElphyProblem &elphyProblem, MCellModel &cellModel, int degree,
                                  int exactUpTo = -1)
       : MonodomainSemiImplicitCells(elphyProblem, cellModel, degree, exactUpTo) {
-    
+
   };
 
   void RHS(const cell &c, const Vector &u, Vector &r) const override;
diff --git a/src/electrophysiology/problem/ElphyProblem.hpp b/src/electrophysiology/problem/ElphyProblem.hpp
index 3d85d757de0f639f94aea6adcc447f69bf5a069b..0c4bc23c4b28292a16c79d59ab13654a8bfa2a04 100644
--- a/src/electrophysiology/problem/ElphyProblem.hpp
+++ b/src/electrophysiology/problem/ElphyProblem.hpp
@@ -3,7 +3,7 @@
 
 #include "utility/Config.hpp"
 
-#include "IProblem.hpp"
+#include "CardMechIProblem.hpp"
 #include "CardiacProblem.hpp"
 
 #include "CardiacData.hpp"
@@ -154,17 +154,17 @@ public:
   const EvaluationPointData &getCellAt(int i) const { return cellsBesideMeshPoints.at(i); };
 };
 
-class ElphyProblem : public IElphyProblem, public IProblem {
+class ElphyProblem : public IElphyProblem, public CardMechIProblem {
 protected:
   bool meshFromConfig() const { return meshesName != ""; }
 
 public:
-  ElphyProblem() : IProblem(), IElphyProblem() {}
+  ElphyProblem() : CardMechIProblem(), IElphyProblem() {}
 
-  explicit ElphyProblem(bool at) : IProblem(), IElphyProblem(at) {}
+  explicit ElphyProblem(bool at) : CardMechIProblem(), IElphyProblem(at) {}
 
   ElphyProblem(bool at, std::array<double, 4> sigmaParams)
-      : IProblem(), IElphyProblem(at, sigmaParams) {}
+      : CardMechIProblem(), IElphyProblem(at, sigmaParams) {}
 
   [[nodiscard]] const string &GetMeshName() const { return meshesName; }
 
diff --git a/src/electrophysiology/solvers/LinearImplicitSolver.cpp b/src/electrophysiology/solvers/LinearImplicitSolver.cpp
index 6bfb193378799b3c18db2aa4c314a08008aa98dd..da62aad48f23645769864528160fb94a35d9a78c 100644
--- a/src/electrophysiology/solvers/LinearImplicitSolver.cpp
+++ b/src/electrophysiology/solvers/LinearImplicitSolver.cpp
@@ -31,8 +31,8 @@ void LinearImplicitSolver::Initialize(IElphyAssemble &A, Vector &V) {
   if ((vcw_c) == nullptr)
   {
     const Meshes &mesh = (*potential).GetMeshes();
-    disc0=std::make_unique<LagrangeDiscretization >(mesh, 0, 1);
-    cellSizeV=std::make_unique<Vector>(*disc0);
+    disc0=std::make_shared<LagrangeDiscretization >(mesh, 0, 1);
+    cellSizeV=std::make_unique<Vector>(disc0);
   }
   vcw_c = std::make_unique<Vectors>(M.Size(), *cellSizeV);
   //gating_c = std::make_unique<Vectors>(M.Size(), gamma_f_c);
@@ -401,7 +401,7 @@ void SemiImplicitSolverOnCells:: Initialize(IElphyAssemble &A, Vector &V){
   {
     const Meshes &mesh = (*potential).GetMeshes();
     disc0=std::make_unique<LagrangeDiscretization >(mesh, 0, 1);
-    cellSizeV=std::make_unique<Vector>(*disc0);
+    cellSizeV=std::make_unique<Vector>(disc0);
   }
   vcw_c = std::make_unique<Vectors>(M.Size(), *cellSizeV);
 
diff --git a/src/electrophysiology/solvers/LinearImplicitSolver.hpp b/src/electrophysiology/solvers/LinearImplicitSolver.hpp
index 966d86250409e45d463e7d26181b8705cef6049b..02557a89f824e9eb624caaf1959fe9ba2c1f4e5b 100644
--- a/src/electrophysiology/solvers/LinearImplicitSolver.hpp
+++ b/src/electrophysiology/solvers/LinearImplicitSolver.hpp
@@ -8,7 +8,6 @@
 #include <MCellModel.hpp>
 #include "Newton.hpp"
 
-
 void QuadraticIonStep(MCellModel &cellModel, double t, double dt, std::vector<double> &VW,
                       std::vector<std::vector<double>> &g);
 
@@ -49,7 +48,7 @@ protected:
   int ionSteps{1};
   bool plotCa{false};
   std::unique_ptr<Vector> cellSizeV;
-  std::unique_ptr<LagrangeDiscretization> disc0;
+  std::shared_ptr<LagrangeDiscretization> disc0;
   std::unique_ptr<Vectors> externalCurrentOnCells;
 
   void selectIonScheme(const string &solvingIonScheme);
@@ -123,7 +122,6 @@ public:
   virtual void updateValues(Vectors &values, Vector &gamma_f_c){Exit("only defined for semi-implicit solver");};
 
   void GatingVectorAti( Vector &values, int i) const override;
-
 };
 
 /*class LiniearImplicitSolverQuad: public LinearImplicitSolver{
@@ -159,11 +157,8 @@ public:
 };
 
 class SemiImplicitSolverOnCells : public LinearImplicitSolver {
-  //std::unique_ptr<LagrangeDiscretization> disc0;
+
 public:
-  //SemiImplicitSolverOnCells(MCellModel &cellModel,const Vector &cSV) : LinearImplicitSolver(cellModel) {
-   // cellSizeV=std::make_unique<Vector>(cSV);
-  //};
   SemiImplicitSolverOnCells(MCellModel &cellModel) : LinearImplicitSolver(cellModel){};
 
 
diff --git a/test/cellmodels/TestElphyModels.cpp b/test/cellmodels/TestElphyModels.cpp
index 163adbe37f6e1d682b0a30e10c90dc7ca697d1d7..89276b673dc0a55e4b905a0e9b24b43d8e315d5c 100644
--- a/test/cellmodels/TestElphyModels.cpp
+++ b/test/cellmodels/TestElphyModels.cpp
@@ -82,7 +82,7 @@ public:
         WithCellData(DataContainer({1, 0, 0, 0, 1, 0, 0, 0, 1})).
         WithVertexData(DataContainer({0.0, 0.002, 1.0})).
         CreateUnique();
-    auto disc = LagrangeDiscretization(*meshes, 1);
+    auto disc = std::make_shared<const LagrangeDiscretization>(*meshes, 1);
     dummyData = std::make_unique<Vector>(0.0, disc);
   }
 
diff --git a/test/cellmodels/TestSolvers.cpp b/test/cellmodels/TestSolvers.cpp
index a9ace41ce27507c5b3743037dae49769ae92964a..6da3b67415ad46f732ad68fc60959d7577f75d9c 100644
--- a/test/cellmodels/TestSolvers.cpp
+++ b/test/cellmodels/TestSolvers.cpp
@@ -39,7 +39,7 @@ public:
         WithCellData(DataContainer({1, 0, 0, 0, 1, 0, 0, 0, 1})).
         WithVertexData(DataContainer({0.0, 0.002, 1.0})).
         CreateUnique();
-    auto disc = LagrangeDiscretization(*meshes, 0);
+    auto disc = std::make_shared<const LagrangeDiscretization>(*meshes, 0);
     dummyData = std::make_unique<Vector>(0.0, disc);
   }
 
diff --git a/test/cellmodels/TestTensionModel.cpp b/test/cellmodels/TestTensionModel.cpp
index eba0ad96bdc3d6b3b55b6ee6ec2261e6e11bc5e0..1152c7e165f1ebb0c4a1ae53b474bb7df395235b 100644
--- a/test/cellmodels/TestTensionModel.cpp
+++ b/test/cellmodels/TestTensionModel.cpp
@@ -26,7 +26,7 @@ public:
         WithCellData(DataContainer({1, 0, 0, 0, 1, 0, 0, 0, 1})).
         WithVertexData(DataContainer({0.0, 0.002, 1.0})).
         CreateUnique();
-    auto disc = LagrangeDiscretization(*meshes, 1);
+    auto disc = std::make_shared<const LagrangeDiscretization>(*meshes, 1);
     dummyData = std::make_unique<Vector>(0.0, disc);
   }
 
diff --git a/test/coupled/CMakeLists.txt b/test/coupled/CMakeLists.txt
index fd7ca81cf58b0eb21762883687a89c87839c88e4..b1121a9e04d8bda8a4e301bc4b0429a75072ab94 100644
--- a/test/coupled/CMakeLists.txt
+++ b/test/coupled/CMakeLists.txt
@@ -1,5 +1,3 @@
-add_mpp_test(TestCardiacTransfers COUPLED)
-add_mpp_test(TestDeformedDiffusion COUPLED)
-
 add_mpi_test(TestCardiacTransfers COUPLED)
-add_mpi_test(TestCoupledConsistency COUPLED)
\ No newline at end of file
+add_mpi_test(TestCoupledConsistency COUPLED)
+add_mpi_test(TestDeformedDiffusion COUPLED)
diff --git a/test/coupled/TestCardiacTransfers.cpp b/test/coupled/TestCardiacTransfers.cpp
index 06312517bd07081438b147e8596d696267e61dfe..9ebcc6d54965528162d23d6fd32a30cdf2b90696 100644
--- a/test/coupled/TestCardiacTransfers.cpp
+++ b/test/coupled/TestCardiacTransfers.cpp
@@ -20,8 +20,8 @@ class TestCardiacTransfer : public TestWithParam<CTransferParam> {
 protected:
   std::unique_ptr<Meshes> coarseMeshes;
   std::unique_ptr<Meshes> fineMeshes;
-  std::unique_ptr<LagrangeDiscretization> coarseDisc;
-  std::unique_ptr<MultiPartDiscretization> fineDisc;
+  std::shared_ptr<LagrangeDiscretization> coarseDisc;
+  std::shared_ptr<MultiPartDiscretization> fineDisc;
   std::unique_ptr<Vector> coarse;
   std::unique_ptr<Vector> fine;
 
@@ -37,12 +37,12 @@ protected:
         WithIncludeVector(getIncludedChambers(GetParam().coarseChambers)).CreateUnique();
 
 
-    coarseDisc = std::make_unique<LagrangeDiscretization>(*coarseMeshes, GetParam().coarseDegree,
+    coarseDisc = std::make_shared<LagrangeDiscretization>(*coarseMeshes, GetParam().coarseDegree,
                                                           GetParam().dim);
-    coarse = std::make_unique<Vector>(*coarseDisc, GetParam().coarseLevel);
-    fineDisc = std::make_unique<MultiPartDiscretization>(*fineMeshes, GetParam().fineDegree,
+    coarse = std::make_unique<Vector>(coarseDisc, GetParam().coarseLevel);
+    fineDisc = std::make_shared<MultiPartDiscretization>(*fineMeshes, GetParam().fineDegree,
                                                          DomainPart, GetParam().dim);
-    fine = std::make_unique<Vector>(*fineDisc, GetParam().fineLevel);
+    fine = std::make_unique<Vector>(fineDisc, GetParam().fineLevel);
   }
 
   void SetUp() override {
diff --git a/test/coupled/TestCoupledConsistency.cpp b/test/coupled/TestCoupledConsistency.cpp
index 2e388f0af1e55b64fe20758f742be9866044df10..ccef0111663b9c83c60bb48eedf05af9d211d4ad 100644
--- a/test/coupled/TestCoupledConsistency.cpp
+++ b/test/coupled/TestCoupledConsistency.cpp
@@ -97,8 +97,8 @@ protected:
 
 
 TEST_P(CoupledConsistencyTest, CompareCellModels) {
-  Vector elphyPot(elphyA->GetDisc());
-  Vector tensionPot(coupledA->GetDisc());
+  Vector elphyPot(elphyA->GetSharedDisc());
+  Vector tensionPot(coupledA->GetSharedDisc());
 
 
   auto elphySolver = GetElphySolver(GetParam().ElphyModel, cellModel->ElphyModel(),
@@ -130,9 +130,9 @@ TEST_P(CoupledConsistencyTest, CompareCellModels) {
 
 
 TEST_P(CoupledConsistencyTest, CompareSolvers) {
-  Vector elphyPot(0.0, elphyA->GetDisc());
-  Vector coupledPot(0.0, coupledA->GetDisc());
-  Vector displacement(0.0, mechA->GetDisc());
+  Vector elphyPot(0.0, elphyA->GetSharedDisc());
+  Vector coupledPot(0.0, coupledA->GetSharedDisc());
+  Vector displacement(0.0, mechA->GetSharedDisc());
 
 
   auto elphySolver = GetElphySolver(GetParam().ElphyModel, *cellModel,
diff --git a/test/coupled/TestDeformedDiffusion.cpp b/test/coupled/TestDeformedDiffusion.cpp
index 5f20982be8f5410add4bad1be20ad03493cec4fc..4438690203eff62073675778445e5ec8cd3544d7 100644
--- a/test/coupled/TestDeformedDiffusion.cpp
+++ b/test/coupled/TestDeformedDiffusion.cpp
@@ -78,9 +78,9 @@ protected:
 };
 
 TEST_F(DeformedDiffusionTest, CheckReference) {
-  Vector elphyVec(0.0, elphyA->GetDisc());
-  Vector mechVec(1.0, mechA->GetDisc());
-  Vector vel(0.0, mechA->GetDisc());
+  Vector elphyVec(0.0, elphyA->GetSharedDisc());
+  Vector mechVec(1.0, mechA->GetSharedDisc());
+  Vector vel(0.0, mechA->GetSharedDisc());
 
   std::unordered_map<Point, Tensor> conductivities{};
   for (cell c = elphyVec.cells(); c != elphyVec.cells_end(); ++c) {
@@ -94,9 +94,9 @@ TEST_F(DeformedDiffusionTest, CheckReference) {
 }
 
 TEST_F(DeformedDiffusionTest, NoDeformation) {
-  Vector elphyVec(0.0, elphyA->GetDisc());
-  Vector mechVec(0.0, mechA->GetDisc());
-  Vector vel(0.0, mechA->GetDisc());
+  Vector elphyVec(0.0, elphyA->GetSharedDisc());
+  Vector mechVec(0.0, mechA->GetSharedDisc());
+  Vector vel(0.0, mechA->GetSharedDisc());
 
   deformedProblem->UpdateDeformation(mechVec, vel, elphyVec);
 
@@ -109,9 +109,9 @@ TEST_F(DeformedDiffusionTest, NoDeformation) {
 }
 
 TEST_F(DeformedDiffusionTest, WithDeformation) {
-  Vector elphyVec(0.0, elphyA->GetDisc());
-  Vector mechVec(0.0, mechA->GetDisc());
-  Vector vel(0.0, mechA->GetDisc());
+  Vector elphyVec(0.0, elphyA->GetSharedDisc());
+  Vector mechVec(0.0, mechA->GetSharedDisc());
+  Vector vel(0.0, mechA->GetSharedDisc());
   for (row r = mechVec.rows(); r != mechVec.rows_end(); ++r) {
     auto x = r();
     mechVec(r, 0) = 2.0 * x[0];
@@ -129,9 +129,9 @@ TEST_F(DeformedDiffusionTest, WithDeformation) {
 
 
 TEST_F(DeformedDiffusionTest, StretchAlongFiber) {
-  Vector elphyVec(0.0, elphyA->GetDisc());
-  Vector mechVec(0.0, mechA->GetDisc());
-  Vector vel(0.0, mechA->GetDisc());
+  Vector elphyVec(0.0, elphyA->GetSharedDisc());
+  Vector mechVec(0.0, mechA->GetSharedDisc());
+  Vector vel(0.0, mechA->GetSharedDisc());
   for (row r = mechVec.rows(); r != mechVec.rows_end(); ++r) {
     mechVec(r, 0) = 2.0 * r()[0];
   }
diff --git a/test/elasticity/TestAssembleConsistency.cpp b/test/elasticity/TestAssembleConsistency.cpp
index f0d78609262bcae47d557ba42dc3110fcd949c92..5555b877dbe61587500bdf495cb1409cf2064dc8 100644
--- a/test/elasticity/TestAssembleConsistency.cpp
+++ b/test/elasticity/TestAssembleConsistency.cpp
@@ -62,11 +62,11 @@ protected:
     Config::PrintInfo();
 
     elastProblem = GetElasticityProblem();//CardiacBeam
-    elastProblem->CreateMeshes();
+    elastProblem->CreateMeshes(MeshesCreator());
 
     assemble = CreateFiniteElasticityAssemble(*elastProblem, model,
                                               GetParam().degree, false);
-    u = std::make_unique<Vector>(0.0, assemble->GetDisc());
+    u = std::make_unique<Vector>(0.0, assemble->GetSharedDisc());
 
     assemble->SetInitialValue(*u);
     assemble->Initialize(*u);