diff --git a/dune/phasefield/base_parameters.hh b/dune/phasefield/base_parameters.hh
index 33d0dbe9b5e16d160fee706482d5792e555f2f8e..ed136822072a542abe33e8043b1ef2f1c5b0b316 100644
--- a/dune/phasefield/base_parameters.hh
+++ b/dune/phasefield/base_parameters.hh
@@ -54,13 +54,46 @@ public:
   }
 };
 
+template<typename Number>
+class Mobility_pf2p
+{
+public:
+  Number mobility;
+  Number mobilityPressureSaturation;
+  Mobility_pf2p(const Dune::ParameterTree & param) :
+    mobility(param.get("Mobility",(Number)0.1)),
+    mobilityPressureSaturation(param.get("MobilityPressureSaturation",(Number)0.1))
+  {
+  }
+
+  Number eval( const Number& pf) const
+  {
+    return mobility;
+  }
+
+  Number eval( const Number& pf1, const Number& pf2, const Number& pf3) const
+  {
+    return mobility;
+  }
+
+  Number evalPressureSaturation( const Number& pf) const
+  {
+    return mobilityPressureSaturation;
+  }
+
+  Number evalPressureSaturation( const Number& pf1, const Number& pf2, const Number& pf3) const
+  {
+    return mobilityPressureSaturation;
+  }
+};
+
 //______________________________________________________________________________________________________
 
 template<typename Number>
 class Reaction_Const
 {
 public:
-  const Number reactionRate;
+  Number reactionRate;
   Reaction_Const(const Dune::ParameterTree & param) :
     reactionRate(param.get("ReactionRate",(Number)1))
   {
@@ -397,6 +430,34 @@ public:
   {
   }
 };
+
+
+template <typename Number, typename TW, typename HTW, typename Mobility, typename Reaction, typename VelDissipation>
+class Params_pn_2pflow : public Params_base<Number, Mobility>
+{
+public:
+  Number delta;
+
+  TW tw;
+  HTW htw;
+  Reaction reaction;
+  VelDissipation vDis;
+
+  Number SurfaceTensionScaling;
+
+
+  Params_pn_2pflow(const Dune::ParameterTree& ptree) :
+    Params_base<Number, Mobility>(ptree),
+    delta(ptree.get("Phasefield.delta",this->eps)),
+    tw(ptree.sub("Phasefield")),
+    htw(ptree.sub("Phasefield")),
+    reaction(ptree.sub("Physics")),
+    vDis(ptree.sub("Physics")),
+    SurfaceTensionScaling(ptree.get("Physics.SurfaceTensionScaling",(Number)1))
+  {
+  }
+};
+
 //
 // template<typename Number>
 // class Problem
diff --git a/dune/phasefield/base_potentials.hh b/dune/phasefield/base_potentials.hh
index dd199383184392109f798e20d70a8f0a4647ed20..b9f7d8667500c2759ed070473ec25a579e658225 100644
--- a/dune/phasefield/base_potentials.hh
+++ b/dune/phasefield/base_potentials.hh
@@ -364,3 +364,69 @@ public:
     return dw.eval_q(pf1/(1-pf2))*(1-pf2)*(1-pf2);  //A function being q on the 13 interface and 0 on the others
   }
 };
+
+template<typename Number>
+class TPPentalty_6thOrder
+{
+public:
+  TPPentalty_6thOrder(const Dune::ParameterTree & ptree)
+  {
+  }
+
+  Number eval(const Number& pf1, const Number& pf2, const Number& pf3) const
+  {
+    return pf1*pf1*pf2*pf2*pf3*pf3;
+  }
+
+  Number eval_dpf1(const Number& pf1, const Number& pf2, const Number& pf3) const
+  {
+    return 2*pf1*pf2*pf2*pf3*pf3;
+  }
+
+  Number eval_dpf2(const Number& pf1, const Number& pf2, const Number& pf3) const
+  {
+    return 2*pf1*pf1*pf2*pf3*pf3;
+  }
+
+  Number eval_dpf3(const Number& pf1, const Number& pf2, const Number& pf3) const
+  {
+    return 2*pf1*pf1*pf2*pf2*pf3;
+  }
+};
+
+template<typename Number, typename DW, typename TPPenalty>
+class TripleWellHierarchicalV1
+{
+public:
+  const Number Sigma1;
+  const Number Sigma2;
+  const Number Sigma3;
+  const Number SigmaT;
+  const Number Lambda;
+
+  DW dw;
+  TPPenalty tppen;
+
+  TripleWellHierarchicalV1(const Dune::ParameterTree & param) :
+    Sigma1(param.get("Sigma1",(Number)1)),
+    Sigma2(param.get("Sigma2",(Number)1)),
+    Sigma3(param.get("Sigma3",(Number)1)),
+    SigmaT(1/(1/Sigma1 + 1/Sigma2)),
+    Lambda(param.get("Lambda",(Number)1)),
+    dw(param),
+    tppen(param)
+  {
+  }
+
+  Number eval_dpf1 (const Number& pf1, const Number& pf2, const Number& pf3) const
+  {
+    return (1 - SigmaT/Sigma1)*(Sigma1*dw.eval_d(pf1) + Lambda*tppen.eval_dpf1(pf1,pf2,pf3))
+                -SigmaT/Sigma2*(Sigma2*dw.eval_d(pf2) + Lambda*tppen.eval_dpf2(pf1,pf2,pf3));
+  }
+
+  Number eval_dpf2 (const Number& pf1, const Number& pf2, const Number& pf3) const
+  {
+    return (1 - SigmaT/Sigma2)*(Sigma2*dw.eval_d(pf2) + Lambda*tppen.eval_dpf2(pf1,pf2,pf3))
+                -SigmaT/Sigma1*(Sigma1*dw.eval_d(pf1) + Lambda*tppen.eval_dpf1(pf1,pf2,pf3));
+  }
+};
diff --git a/dune/phasefield/boundary_rectangular.hh b/dune/phasefield/boundary_rectangular.hh
index 3a7728ce8b2b4250298bba0f0da40143afa17ec5..4c6fa95528f00f8d3dba3bdc30f4f6dcd0233e28 100644
--- a/dune/phasefield/boundary_rectangular.hh
+++ b/dune/phasefield/boundary_rectangular.hh
@@ -146,3 +146,50 @@ public:
     return false;
   }
 };
+
+
+template<typename DomainSize>
+class TopRightCorner : public Dune::PDELab::DirichletConstraintsParameters
+{
+private:
+  const DomainSize ds;
+public:
+  TopRightCorner(const DomainSize d) : ds(d)
+  {
+  }
+
+  template<typename I>
+  bool isDirichlet(const I & intersection, const Dune::FieldVector<typename I::ctype, I::mydimension> & coord) const
+  {
+    Dune::FieldVector<typename I::ctype, I::coorddimension>
+      xg = intersection.geometry().global( coord );
+    if (( xg[0] > ds.right - (ds.right-ds.left)/20) && ( xg[1]>ds.top - ds.domainEps))
+    {
+      return true;
+    }
+    return false;
+  }
+};
+
+template<typename DomainSize>
+class LeftBottomCorner : public Dune::PDELab::DirichletConstraintsParameters
+{
+private:
+  const DomainSize ds;
+public:
+  LeftBottomCorner(const DomainSize d) : ds(d)
+  {
+  }
+
+  template<typename I>
+  bool isDirichlet(const I & intersection, const Dune::FieldVector<typename I::ctype, I::mydimension> & coord) const
+  {
+    Dune::FieldVector<typename I::ctype, I::coorddimension>
+      xg = intersection.geometry().global( coord );
+    if (( xg[0] < ds.left + (ds.right-ds.left)/20) && ( xg[1]<ds.bottom + ds.domainEps))
+    {
+      return true;
+    }
+    return false;
+  }
+};
diff --git a/dune/phasefield/fff_chns.hh b/dune/phasefield/fff_chns.hh
index 332ff5d979ad3bd17bdc944fc9b3a1970455fb9a..9ab1c30a1ac915bd66fa17ae9e4d28e220030591 100644
--- a/dune/phasefield/fff_chns.hh
+++ b/dune/phasefield/fff_chns.hh
@@ -214,3 +214,38 @@ public:
   {
   }
 };
+
+template<typename BdryV1, typename BdryV2, typename BdryP,
+          typename BdryPhi, typename BdryMu, typename BdryPhi2, typename BdryMu2>
+class Bdry_fff_chns_compositeV_2d_Explicit_Domain
+{
+public:
+  BdryV1 bdryV1;
+  BdryV2 bdryV2;
+  BdryP bdryP;
+  BdryPhi bdryPhi;
+  BdryMu bdryMu;
+  BdryPhi2 bdryPhi2;
+  BdryMu2 bdryMu2;
+  typedef Dune::PDELab::CompositeConstraintsParameters<BdryV1,BdryV2>    BdryV;
+  typedef Dune::PDELab::CompositeConstraintsParameters<BdryV, BdryP> BdryNS;
+  typedef Dune::PDELab::CompositeConstraintsParameters<BdryPhi, BdryMu, BdryPhi2, BdryMu2> BdryCH;
+  BdryV bdryV;
+  BdryNS bdryNS;
+  BdryCH bdryCH;
+
+  template<typename DomainSize>
+  Bdry_fff_chns_compositeV_2d_Explicit_Domain(DomainSize ds) :
+      bdryV1(ds),
+      bdryV2(ds),
+      bdryP(ds),
+      bdryPhi(ds),
+      bdryMu(ds),
+      bdryPhi2(ds),
+      bdryMu2(ds),
+      bdryV(bdryV1,bdryV2),
+      bdryNS(bdryV,bdryP),
+      bdryCH(bdryPhi,bdryMu,bdryPhi2,bdryMu2)
+  {
+  }
+};
diff --git a/dune/phasefield/initial_fn.hh b/dune/phasefield/initial_fn.hh
index 8b98df41364bf4f2a4fb045d6f3e651003977690..e9df86c4f249d4f8730bf77becc4fccc3e2f43c6 100644
--- a/dune/phasefield/initial_fn.hh
+++ b/dune/phasefield/initial_fn.hh
@@ -657,6 +657,86 @@ public:
 };
 
 
+template<typename GV, typename RF, typename Params, const int Phase>
+class PhiInitial_Bubble_Spinodal :
+  public Dune::PDELab::AnalyticGridFunctionBase<
+    Dune::PDELab::AnalyticGridFunctionTraits<GV,RF,1>, PhiInitial_Bubble_Spinodal<GV,RF,Params,Phase> >
+{
+  RF eps;
+  RF r;
+  RF mean;
+  RF deviation;
+  int seed;
+
+public:
+  typedef Dune::PDELab::AnalyticGridFunctionTraits<GV,RF,1> Traits;
+
+  PhiInitial_Bubble_Spinodal(const GV & gv, const Params & params) :
+     Dune::PDELab::AnalyticGridFunctionBase<Traits,PhiInitial_Bubble_Spinodal<GV,RF,Params,Phase> > (gv)
+     {
+       mean = params.initial.ptree.get("Mean",0.5);
+       deviation = params.initial.ptree.get("Deviation",0.1);
+       seed = params.initial.ptree.get("Seed",1);
+       eps = params.eps;
+       r = params.initial.ptree.get("Radius",0.2);
+     }
+
+  inline void evaluateGlobal(const  typename Traits::DomainType & x, typename Traits::RangeType & y) const
+  {
+    RF dist = std::sqrt((x[0]-0.5)*(x[0]-0.5)+(x[1]-0.5)*(x[1]-0.5));
+    RF rf = 0.5*(1+tanh(1/eps/sqrt(2)*(dist-r)));
+
+    int xint = (int) (x[0]*10000);
+    int yint = (int) (x[1]*10000);
+    std::srand(xint + yint*10061 + seed);
+    RF noise = mean + deviation*(((RF)std::rand())/RAND_MAX);
+    if(Phase == 0)
+    {
+      y[0] = (1-rf)*noise;
+    }
+    else
+    {
+      y[0] = (1-rf)*(1-noise);
+    }
+  }
+};
+
+
+template<typename GV, typename RF, typename Params, const int Phase>
+class PhiInitial_Bubble_Interior :
+  public Dune::PDELab::AnalyticGridFunctionBase<
+    Dune::PDELab::AnalyticGridFunctionTraits<GV,RF,1>, PhiInitial_Bubble_Interior<GV,RF,Params,Phase> >
+{
+  RF eps;
+  RF r;
+
+public:
+  typedef Dune::PDELab::AnalyticGridFunctionTraits<GV,RF,1> Traits;
+
+  PhiInitial_Bubble_Interior(const GV & gv, const Params & params) :
+     Dune::PDELab::AnalyticGridFunctionBase<Traits,PhiInitial_Bubble_Interior<GV,RF,Params,Phase> > (gv)
+     {
+       eps = params.eps;
+       r = params.initial.ptree.get("Radius",0.2);
+     }
+
+  inline void evaluateGlobal(const  typename Traits::DomainType & x, typename Traits::RangeType & y) const
+  {
+    RF dist = std::sqrt((x[0]-0.5)*(x[0]-0.5)+(x[1]-0.5)*(x[1]-0.5));
+    RF rf = 0.5*(1+tanh(1/eps/sqrt(2)*(dist-r)));
+    RF fluid = 0.5*(1+tanh(1/eps/sqrt(2)*(x[1]-0.5)));
+
+    if(Phase == 0)
+    {
+      y[0] = (1-rf)*fluid;
+    }
+    else
+    {
+      y[0] = (1-rf)*(1-fluid);
+    }
+  }
+};
+
 //______________________________________________________________________________________________________________________
 
 #include <dune/phasefield/boundary_fn.hh>
diff --git a/dune/phasefield/localoperator/fem_3p_cahnhilliard_hierarchical_top.hh b/dune/phasefield/localoperator/fem_3p_cahnhilliard_hierarchical_top.hh
new file mode 100644
index 0000000000000000000000000000000000000000..ff4e1944f06ec25c3480d56dc41a66df3158daa2
--- /dev/null
+++ b/dune/phasefield/localoperator/fem_3p_cahnhilliard_hierarchical_top.hh
@@ -0,0 +1,97 @@
+#pragma once
+
+#include<dune/pdelab/common/quadraturerules.hh>
+#include<dune/pdelab/finiteelement/localbasiscache.hh>
+#include<dune/pdelab/localoperator/defaultimp.hh>
+#include<dune/pdelab/localoperator/pattern.hh>
+#include<dune/pdelab/localoperator/flags.hh>
+#include<dune/pdelab/localoperator/variablefactories.hh>
+#include<dune/pdelab/gridfunctionspace/gridfunctionspace.hh>
+
+#include<dune/phasefield/localoperator/fem_base_chns.hh>
+
+
+//Parameter class (for functions), FEM space and RangeField
+template<typename Param, typename CHGFS, typename CHContainer>
+class FEM_3P_CahnHilliard_HierarchicalTop :
+  public Dune::PDELab::FullVolumePattern,
+  public Dune::PDELab::LocalOperatorDefaultFlags,
+  public Dune::PDELab::NumericalJacobianVolume<FEM_3P_CahnHilliard_HierarchicalTop<Param, CHGFS, CHContainer> >,
+  public Dune::PDELab::NumericalJacobianApplyVolume<FEM_3P_CahnHilliard_HierarchicalTop<Param, CHGFS, CHContainer> >
+{
+private:
+  typedef typename CHContainer::field_type RF;
+  typedef typename CHGFS::Traits::GridViewType::template Codim<0>::Entity   ENTITY;
+
+  CHLocalBasisCache<CHGFS> chCache;
+
+  typedef GFS_LocalViewer<CHGFS, CHContainer, ENTITY, RF> CHLView;
+  mutable CHLView chOldLocal;
+
+  Param& param; // parameter functions
+
+public:
+  enum {doPatternVolume=true};
+  enum {doAlphaVolume=true};
+
+  //constructor
+  FEM_3P_CahnHilliard_HierarchicalTop(Param& param_, CHGFS& chGfs_, CHContainer& chVOld_) :
+    chOldLocal(chGfs_,chVOld_),
+    param(param_)
+  {
+  }
+
+
+  template<typename EG, typename LFSU, typename X, typename LFSV, typename R>
+  void alpha_volume (const EG& eg, const LFSU& lfsu, const X& x, const LFSV& lfsv, R& r) const
+  {
+    //Quadrature Rule
+    const int dim = EG::Entity::dimension;
+    const int order = 4; //TODO: Choose more educated
+    auto rule = Dune::PDELab::quadratureRule(eg.geometry(), order);
+
+    chOldLocal.DoEvaluation(eg);
+
+    for(const auto& ip : rule)
+    {
+      const auto S = eg.geometry().jacobianInverseTransposed(ip.position());
+      auto factor = ip.weight()*eg.geometry().integrationElement(ip.position());
+
+      CHVariables_Threephase_PFOld_Extension<RF,dim,LFSV> ch(chCache, ip.position(), lfsv, x.base(), chOldLocal.lv, S);
+
+      RF pf3 = 1-ch.pf-ch.pf2;
+
+      for (size_t i=0; i<ch.pfspace.size(); i++)
+      {
+        RF gradxi3TimesGradphi = ch.gradxi*ch.basis.gradphi[i][0];
+        RF J3 = param.mobility.eval(ch.pf,ch.pf2,pf3) * param.eps/param.tw.Sigma3 * gradxi3TimesGradphi;
+        RF J1 = (-(ch.pf +param.delta/2)/(ch.pf+ch.pf2+param.delta))* J3 ;
+        RF J2 = (-(ch.pf2+param.delta/2)/(ch.pf+ch.pf2+param.delta))* J3;
+      // integrate: (pf-pfold)*phi_i/delta_t + gradpf * grad phi_i + ...
+        r.accumulate(ch.pfspace,i,factor*(
+          (ch.pf-ch.pfOld)*ch.basis.phi[i]/param.time.dt
+          +J1
+        ));
+
+        r.accumulate(ch.pf2space,i,factor*(
+          (ch.pf2-ch.pf2Old)*ch.basis.phi[i]/param.time.dt
+          +J2
+        ));
+
+        r.accumulate(ch.xispace,i,factor*(
+          ch.xi*ch.basis.phi[i]
+          - 1/param.eps* param.tw.dw.eval_d(pf3) *ch.basis.phi[i]
+          + param.eps * param.tw.Sigma3* (ch.gradpf*ch.basis.gradphi[i][0])
+          + param.eps * param.tw.Sigma3* (ch.gradpf2*ch.basis.gradphi[i][0])
+        ));
+
+        r.accumulate(ch.xi2space,i,factor*(
+          ch.xi2*ch.basis.phi[i]
+          //- 1/param.eps* param.tw.eval_dpf2(ch.pf,ch.pf2,pf3) *ch.basis.phi[i]
+          //- param.eps * param.tw.Sigma2* (ch.gradpf2*ch.basis.gradphi[i][0])
+        ));
+      }
+    }
+  }
+
+};
diff --git a/dune/phasefield/localoperator/fem_3p_cahnhilliard_hierarchicalv1.hh b/dune/phasefield/localoperator/fem_3p_cahnhilliard_hierarchicalv1.hh
new file mode 100644
index 0000000000000000000000000000000000000000..3d8c92fc8e2de010dd82237d15f6b27b9adb2972
--- /dev/null
+++ b/dune/phasefield/localoperator/fem_3p_cahnhilliard_hierarchicalv1.hh
@@ -0,0 +1,98 @@
+#pragma once
+
+#include<dune/pdelab/common/quadraturerules.hh>
+#include<dune/pdelab/finiteelement/localbasiscache.hh>
+#include<dune/pdelab/localoperator/defaultimp.hh>
+#include<dune/pdelab/localoperator/pattern.hh>
+#include<dune/pdelab/localoperator/flags.hh>
+#include<dune/pdelab/localoperator/variablefactories.hh>
+#include<dune/pdelab/gridfunctionspace/gridfunctionspace.hh>
+
+#include<dune/phasefield/localoperator/fem_base_chns.hh>
+
+
+//Parameter class (for functions), FEM space and RangeField
+template<typename Param, typename CHGFS, typename CHContainer>
+class FEM_3P_CahnHilliard_HierarchicalV1 :
+  public Dune::PDELab::FullVolumePattern,
+  public Dune::PDELab::LocalOperatorDefaultFlags,
+  public Dune::PDELab::NumericalJacobianVolume<FEM_3P_CahnHilliard_HierarchicalV1<Param, CHGFS, CHContainer> >,
+  public Dune::PDELab::NumericalJacobianApplyVolume<FEM_3P_CahnHilliard_HierarchicalV1<Param, CHGFS, CHContainer> >
+{
+private:
+  typedef typename CHContainer::field_type RF;
+  typedef typename CHGFS::Traits::GridViewType::template Codim<0>::Entity   ENTITY;
+
+  CHLocalBasisCache<CHGFS> chCache;
+
+  typedef GFS_LocalViewer<CHGFS, CHContainer, ENTITY, RF> CHLView;
+  mutable CHLView chOldLocal;
+
+  Param& param; // parameter functions
+
+public:
+  enum {doPatternVolume=true};
+  enum {doAlphaVolume=true};
+
+  //constructor
+  FEM_3P_CahnHilliard_HierarchicalV1(Param& param_, CHGFS& chGfs_, CHContainer& chVOld_) :
+    chOldLocal(chGfs_,chVOld_),
+    param(param_)
+  {
+  }
+
+
+  template<typename EG, typename LFSU, typename X, typename LFSV, typename R>
+  void alpha_volume (const EG& eg, const LFSU& lfsu, const X& x, const LFSV& lfsv, R& r) const
+  {
+    //Quadrature Rule
+    const int dim = EG::Entity::dimension;
+    const int order = 4; //TODO: Choose more educated
+    auto rule = Dune::PDELab::quadratureRule(eg.geometry(), order);
+
+    chOldLocal.DoEvaluation(eg);
+
+    for(const auto& ip : rule)
+    {
+      const auto S = eg.geometry().jacobianInverseTransposed(ip.position());
+      auto factor = ip.weight()*eg.geometry().integrationElement(ip.position());
+
+      CHVariables_Threephase_PFOld_Extension<RF,dim,LFSV> ch(chCache, ip.position(), lfsv, x.base(), chOldLocal.lv, S);
+
+      RF pf3 = 1-ch.pf-ch.pf2;
+
+      for (size_t i=0; i<ch.pfspace.size(); i++)
+      {
+        RF J1 = param.mobility.eval(ch.pf,ch.pf2,pf3)*param.eps/param.htw.Sigma1 * (ch.gradxi*ch.basis.gradphi[i][0]);
+
+      // integrate: (pf-pfold)*phi_i/delta_t + gradpf * grad phi_i + ...
+        r.accumulate(ch.pfspace,i,factor*(
+          (ch.pf-ch.pfOld)*ch.basis.phi[i]/param.time.dt
+          +J1
+        ));
+
+        r.accumulate(ch.pf2space,i,factor*(
+          (ch.pf2-ch.pf2Old)*ch.basis.phi[i]/param.time.dt
+          +param.mobility.eval(ch.pf,ch.pf2,pf3)*param.eps/param.htw.Sigma2 * (ch.gradxi2*ch.basis.gradphi[i][0])
+        ));
+
+        r.accumulate(ch.xispace,i,factor*(
+          ch.xi*ch.basis.phi[i]
+          - 1/param.eps* param.htw.eval_dpf1(ch.pf,ch.pf2,pf3) *ch.basis.phi[i]
+          - param.eps * param.htw.Sigma1* (ch.gradpf*ch.basis.gradphi[i][0])
+          + param.eps * param.htw.SigmaT* (ch.gradpf*ch.basis.gradphi[i][0])
+          + param.eps * param.htw.SigmaT* (ch.gradpf2*ch.basis.gradphi[i][0])
+        ));
+
+        r.accumulate(ch.xi2space,i,factor*(
+          ch.xi2*ch.basis.phi[i]
+          - 1/param.eps* param.htw.eval_dpf2(ch.pf,ch.pf2,pf3) *ch.basis.phi[i]
+          - param.eps * param.htw.Sigma2* (ch.gradpf2*ch.basis.gradphi[i][0])
+          + param.eps * param.htw.SigmaT* (ch.gradpf*ch.basis.gradphi[i][0])
+          + param.eps * param.htw.SigmaT* (ch.gradpf2*ch.basis.gradphi[i][0])
+        ));
+      }
+    }
+  }
+
+};
diff --git a/dune/phasefield/porenetwork/fem_2p_cahnhilliard_precipitation.hh b/dune/phasefield/porenetwork/fem_2p_cahnhilliard_precipitation.hh
new file mode 100644
index 0000000000000000000000000000000000000000..54e23701d036e91e7840f0c1c72d917b5a2b608d
--- /dev/null
+++ b/dune/phasefield/porenetwork/fem_2p_cahnhilliard_precipitation.hh
@@ -0,0 +1,102 @@
+#pragma once
+
+#include<dune/pdelab/common/quadraturerules.hh>
+#include<dune/pdelab/finiteelement/localbasiscache.hh>
+#include<dune/pdelab/localoperator/defaultimp.hh>
+#include<dune/pdelab/localoperator/pattern.hh>
+#include<dune/pdelab/localoperator/flags.hh>
+#include<dune/pdelab/localoperator/variablefactories.hh>
+#include<dune/pdelab/gridfunctionspace/gridfunctionspace.hh>
+
+#include<dune/phasefield/localoperator/fem_base_chns.hh>
+
+
+//Parameter class (for functions), FEM space and RangeField
+template<typename Param, typename CHGFS, typename CHContainer>
+class FEM_2P_CahnHilliard_Precipitation :
+  public Dune::PDELab::FullVolumePattern,
+  public Dune::PDELab::LocalOperatorDefaultFlags,
+  public Dune::PDELab::NumericalJacobianVolume<FEM_2P_CahnHilliard_Precipitation<Param, CHGFS, CHContainer> >,
+  public Dune::PDELab::NumericalJacobianApplyVolume<FEM_2P_CahnHilliard_Precipitation<Param, CHGFS, CHContainer> >
+{
+private:
+  typedef typename CHContainer::field_type RF;
+  typedef typename CHGFS::Traits::GridViewType::template Codim<0>::Entity   ENTITY;
+
+  CHLocalBasisCache<CHGFS> chCache;
+
+  typedef GFS_LocalViewer<CHGFS, CHContainer, ENTITY, RF> CHLView;
+  mutable CHLView chOldLocal;
+
+  Param& param; // parameter functions
+
+public:
+  enum {doPatternVolume=true};
+  enum {doAlphaVolume=true};
+
+  //constructor
+  FEM_2P_CahnHilliard_Precipitation(Param& param_, CHGFS& chGfs_, CHContainer& chVOld_) :
+    chOldLocal(chGfs_,chVOld_),
+    param(param_)
+  {
+  }
+
+
+  template<typename EG, typename LFSU, typename X, typename LFSV, typename R>
+  void alpha_volume (const EG& eg, const LFSU& lfsu, const X& x, const LFSV& lfsv, R& r) const
+  {
+    //Quadrature Rule
+    const int dim = EG::Entity::dimension;
+    const int order = 4; //TODO: Choose more educated
+    auto rule = Dune::PDELab::quadratureRule(eg.geometry(), order);
+
+    chOldLocal.DoEvaluation(eg);
+
+    for(const auto& ip : rule)
+    {
+      const auto S = eg.geometry().jacobianInverseTransposed(ip.position());
+      auto factor = ip.weight()*eg.geometry().integrationElement(ip.position());
+
+      CHVariables_Threephase_PFOld_Extension<RF,dim,LFSV> ch(chCache, ip.position(), lfsv, x.base(), chOldLocal.lv, S);
+
+      RF pf3 = 1-ch.pf-ch.pf2;
+      RF pf3Old = 1-ch.pfOld-ch.pf2Old;
+
+      for (size_t i=0; i<ch.pfspace.size(); i++)
+      {
+
+        RF Rspeed = ch.pfOld < 0.95 ? param.tw.eval_q(ch.pfOld,ch.pf2Old,pf3Old) : 0.0f;
+        RF R1 = -Rspeed/param.eps*param.reaction.eval(1)*ch.basis.phi[i];
+
+        RF gradxi3TimesGradphi = ch.gradxi*ch.basis.gradphi[i][0];
+        RF J3 = param.mobility.eval(ch.pf,ch.pf2,pf3) * param.eps/param.tw.Sigma3 * gradxi3TimesGradphi;
+        RF J1 = (-(ch.pf +param.delta/2)/(ch.pf+ch.pf2+param.delta))* J3 ;
+        RF J2 = (-(ch.pf2+param.delta/2)/(ch.pf+ch.pf2+param.delta))* J3;
+      // integrate: (pf-pfold)*phi_i/delta_t + gradpf * grad phi_i + ...
+        r.accumulate(ch.pfspace,i,factor*(
+          (ch.pf-ch.pfOld)*ch.basis.phi[i]/param.time.dt
+          +J1-R1
+        ));
+
+        r.accumulate(ch.pf2space,i,factor*(
+          (ch.pf2-ch.pf2Old)*ch.basis.phi[i]/param.time.dt
+          +J2
+        ));
+
+        r.accumulate(ch.xispace,i,factor*(
+          ch.xi*ch.basis.phi[i]
+          - 1/param.eps* param.tw.dw.eval_d(pf3) *ch.basis.phi[i]
+          + param.eps * param.tw.Sigma3* (ch.gradpf*ch.basis.gradphi[i][0])
+          + param.eps * param.tw.Sigma3* (ch.gradpf2*ch.basis.gradphi[i][0])
+        ));
+
+        r.accumulate(ch.xi2space,i,factor*(
+          ch.xi2*ch.basis.phi[i]
+          //- 1/param.eps* param.tw.eval_dpf2(ch.pf,ch.pf2,pf3) *ch.basis.phi[i]
+          //- param.eps * param.tw.Sigma2* (ch.gradpf2*ch.basis.gradphi[i][0])
+        ));
+      }
+    }
+  }
+
+};
diff --git a/dune/phasefield/porenetwork/fem_2p_cahnhilliard_pressuresaturation.hh b/dune/phasefield/porenetwork/fem_2p_cahnhilliard_pressuresaturation.hh
new file mode 100644
index 0000000000000000000000000000000000000000..d36cd10feb59412775ba3c174097131067d106f9
--- /dev/null
+++ b/dune/phasefield/porenetwork/fem_2p_cahnhilliard_pressuresaturation.hh
@@ -0,0 +1,121 @@
+#pragma once
+
+#include<dune/pdelab/common/quadraturerules.hh>
+#include<dune/pdelab/finiteelement/localbasiscache.hh>
+#include<dune/pdelab/localoperator/defaultimp.hh>
+#include<dune/pdelab/localoperator/pattern.hh>
+#include<dune/pdelab/localoperator/flags.hh>
+#include<dune/pdelab/localoperator/variablefactories.hh>
+#include<dune/pdelab/gridfunctionspace/gridfunctionspace.hh>
+
+#include<dune/phasefield/localoperator/fem_base_chns.hh>
+
+//Parameter class (for functions), FEM space and RangeField
+template<typename Param, typename CHGFS, typename CHContainer, typename NSGFS, typename NSContainer>
+class FEM_2P_CahnHilliard_PressureSaturation :
+  public Dune::PDELab::FullVolumePattern,
+  public Dune::PDELab::LocalOperatorDefaultFlags,
+  public Dune::PDELab::NumericalJacobianVolume<FEM_2P_CahnHilliard_PressureSaturation<Param, CHGFS, CHContainer, NSGFS, NSContainer> >,
+  public Dune::PDELab::NumericalJacobianApplyVolume<FEM_2P_CahnHilliard_PressureSaturation<Param, CHGFS, CHContainer, NSGFS, NSContainer> >
+{
+private:
+  typedef typename CHContainer::field_type RF;
+  typedef typename CHGFS::Traits::GridViewType::template Codim<0>::Entity   ENTITY;
+
+  CHLocalBasisCache<CHGFS> chCache;
+  VLocalBasisCache<NSGFS> vCache;
+
+  typedef GFS_LocalViewer<CHGFS, CHContainer, ENTITY, RF> CHLView;
+  mutable CHLView chOldLocal;
+
+  typedef GFS_LocalViewer<NSGFS, NSContainer, ENTITY, RF> NSLView;
+  mutable NSLView nsLocal;
+
+
+  Param& param; // parameter functions
+
+public:
+  enum {doPatternVolume=true};
+  //enum {doLambdaVolume=true};
+  enum {doAlphaVolume=true};
+
+  //constructor
+  FEM_2P_CahnHilliard_PressureSaturation(Param& param_, CHGFS& chGfs_, CHContainer& chVOld_, NSGFS& nsGfs_, NSContainer& nsV) :
+    chOldLocal(chGfs_,chVOld_),
+    nsLocal(nsGfs_,nsV),
+    param(param_)
+  {
+  }
+
+
+  template<typename EG, typename LFSU, typename X, typename LFSV, typename R>
+  void alpha_volume (const EG& eg, const LFSU& lfsu, const X& x, const LFSV& lfsv, R& r) const
+  {
+    //Quadrature Rule
+    const int dim = EG::Entity::dimension;
+    const int order = 4; //TODO: Choose more educated
+    auto rule = Dune::PDELab::quadratureRule(eg.geometry(), order);
+
+    chOldLocal.DoEvaluation(eg);
+    //chOldLocal.DoEvaluation(eg);
+    nsLocal.DoSubEvaluation(eg,child(nsLocal.lfs,Dune::Indices::_0));
+
+    for(const auto& ip : rule)
+    {
+      const auto S = eg.geometry().jacobianInverseTransposed(ip.position());
+      auto factor = ip.weight()*eg.geometry().integrationElement(ip.position());
+      CHVariables_Threephase_PFOld_Extension<RF,dim,LFSV> ch(chCache, ip.position(), lfsv, x.base(),chOldLocal.lv, S);
+      NSVariables<RF,dim,decltype(nsLocal.lfs)> ns(vCache, ip.position(), nsLocal.lfs, nsLocal.lv, S);
+
+      RF pf3 = 1-ch.pf-ch.pf2;
+      RF pf3Old = 1-ch.pfOld-ch.pf2Old;
+      //RF xi3 = -param.tw.Sigma3*(ch.xi/param.tw.Sigma1 + ch.xi2/param.tw.Sigma2);
+
+
+      for (size_t i=0; i<ch.pfspace.size(); i++)
+      {
+
+        RF Rspeed = ch.pfOld < 0.95 ? param.tw.eval_q(ch.pfOld,pf3Old,ch.pf2Old) : 0.0f;
+        RF R1 = -Rspeed/param.eps*param.reaction.eval(1)*ch.basis.phi[i];
+        RF J1 = param.mobility.evalPressureSaturation(ch.pf,ch.pf2,pf3)*param.eps/param.htw.Sigma1 * (ch.gradxi*ch.basis.gradphi[i][0]);
+        RF J2 = param.mobility.evalPressureSaturation(ch.pf,ch.pf2,pf3)*param.eps/param.htw.Sigma2 * (ch.gradxi2*ch.basis.gradphi[i][0]);
+
+      // integrate: (pf-pfold)*phi_i/delta_t + gradpf * grad phi_i + ...
+        r.accumulate(ch.pfspace,i,factor*(
+          (ch.pf-ch.pfOld)*ch.basis.phi[i]/param.time.dt
+          +J1
+          //+(ch.pf*ns.div_v + (ch.gradpf*ns.v))*ch.basis.phi[i]
+          -ch.pf*(ns.v*ch.basis.gradphi[i][0])   //weak transport
+          +R1
+        ));
+
+        r.accumulate(ch.pf2space,i,factor*(
+          (ch.pf2-ch.pf2Old)*ch.basis.phi[i]/param.time.dt
+          +J2
+          //+(ch.pf2*ns.div_v + (ch.gradpf2*ns.v))*ch.basis.phi[i]
+          -ch.pf2*(ns.v*ch.basis.gradphi[i][0])
+          -R1
+        ));
+
+        r.accumulate(ch.xispace,i,factor*(
+          ch.xi*ch.basis.phi[i]
+          - 1/param.eps* param.htw.eval_dpf1(ch.pf,ch.pf2,pf3) *ch.basis.phi[i]
+          - param.eps * param.htw.Sigma1* (ch.gradpf*ch.basis.gradphi[i][0])
+          + param.eps * param.htw.SigmaT* (ch.gradpf*ch.basis.gradphi[i][0])
+          + param.eps * param.htw.SigmaT* (ch.gradpf2*ch.basis.gradphi[i][0])
+        ));
+
+        r.accumulate(ch.xi2space,i,factor*(
+          ch.xi2*ch.basis.phi[i]
+          - 1/param.eps* param.htw.eval_dpf2(ch.pf,ch.pf2,pf3) *ch.basis.phi[i]
+          - param.eps * param.htw.Sigma2* (ch.gradpf2*ch.basis.gradphi[i][0])
+          + param.eps * param.htw.SigmaT* (ch.gradpf*ch.basis.gradphi[i][0])
+          + param.eps * param.htw.SigmaT* (ch.gradpf2*ch.basis.gradphi[i][0])
+        ));
+
+
+      }
+    }
+  }
+
+};
diff --git a/dune/phasefield/porenetwork/fem_2p_navierstokes_pressuresaturation.hh b/dune/phasefield/porenetwork/fem_2p_navierstokes_pressuresaturation.hh
new file mode 100644
index 0000000000000000000000000000000000000000..7dda41197e79436c1a7b596fa0b05d10ade646fa
--- /dev/null
+++ b/dune/phasefield/porenetwork/fem_2p_navierstokes_pressuresaturation.hh
@@ -0,0 +1,143 @@
+#pragma once
+
+#include<dune/pdelab/common/quadraturerules.hh>
+#include<dune/pdelab/finiteelement/localbasiscache.hh>
+#include<dune/pdelab/localoperator/defaultimp.hh>
+#include<dune/pdelab/localoperator/pattern.hh>
+#include<dune/pdelab/localoperator/flags.hh>
+#include<dune/pdelab/localoperator/variablefactories.hh>
+#include<dune/pdelab/gridfunctionspace/gridfunctionspace.hh>
+
+#include<dune/phasefield/localoperator/fem_base_chns.hh>
+
+
+
+
+template<typename Param, typename CHGFS, typename CHContainer, typename NSGFS, typename NSContainer>
+    class FEM_2P_NavierStokes_PressureSaturation :
+      public Dune::PDELab::FullVolumePattern,
+      public Dune::PDELab::LocalOperatorDefaultFlags,
+      public Dune::PDELab::NumericalJacobianVolume<FEM_2P_NavierStokes_PressureSaturation<Param, CHGFS, CHContainer, NSGFS, NSContainer> >,
+      public Dune::PDELab::NumericalJacobianApplyVolume<FEM_2P_NavierStokes_PressureSaturation<Param, CHGFS, CHContainer, NSGFS, NSContainer> >
+    {
+    private:
+      typedef typename CHContainer::field_type RF;
+      typedef typename NSGFS::Traits::GridViewType::template Codim<0>::Entity   ENTITY;
+
+      CHLocalBasisCache<CHGFS> chCache;
+      VLocalBasisCache<NSGFS> vCache;
+      PLocalBasisCache<NSGFS> pCache;
+
+      typedef GFS_LocalViewer<CHGFS, CHContainer, ENTITY, RF> CHLView;
+      mutable CHLView chLocal;
+      //mutable CHLView chOldLocal;
+
+      typedef GFS_LocalViewer<NSGFS, NSContainer, ENTITY, RF> NSLView;
+      mutable NSLView nsOldLocal;
+
+      Param& param; // parameter functions
+
+      //FOR DETECTING ENTITY changes
+      typedef typename NSGFS::Traits::GridViewType::template Codim<0>::Entity   ENT;
+      mutable ENT OldEnt;
+
+    public:
+
+
+      // pattern assembly flags
+      enum { doPatternVolume = true };
+
+      // residual assembly flags
+      enum { doAlphaVolume = true };
+      //enum { doLambdaVolume = true };
+
+
+
+      FEM_2P_NavierStokes_PressureSaturation (Param& param_, CHGFS& chGfs_, CHContainer& chV_, CHContainer& chVOld_,
+                         NSGFS& nsGfs_, NSContainer& nsVOld_) :
+        chLocal(chGfs_,chV_),
+        //chOldLocal(chGfs_,chVOld_),
+        nsOldLocal(nsGfs_,nsVOld_),
+        param(param_)
+      {
+      }
+
+
+      template<typename EG, typename LFSU, typename X, typename LFSV, typename R>
+      void alpha_volume (const EG& eg, const LFSU& lfsu, const X& x, const LFSV& lfsv, R& r) const
+      {
+
+        //Quadrature Rule
+        const int dim = EG::Entity::dimension;
+        const int order = 5; //TODO: Choose more educated
+        auto rule = Dune::PDELab::quadratureRule(eg.geometry(), order);
+
+        chLocal.DoEvaluation(eg);
+        //chOldLocal.DoEvaluation(eg);
+        nsOldLocal.DoSubEvaluation(eg,child(nsOldLocal.lfs,Dune::Indices::_0));
+
+        for(const auto& ip : rule)
+        {
+          const auto S = eg.geometry().jacobianInverseTransposed(ip.position());
+          auto factor = ip.weight()*eg.geometry().integrationElement(ip.position());
+
+          CHVariables_Threephase_Extension<RF,dim,decltype(chLocal.lfs)> ch(chCache, ip.position(), chLocal.lfs, chLocal.lv, S);
+          NSVariables_P_VOld_Extension<RF,dim,LFSV> ns(vCache, pCache, ip.position(), lfsv, x.base(), nsOldLocal.lv, S);
+
+
+          RF pf3=1-ch.pf-ch.pf2;
+          RF pf_f=ch.pf+ch.pf2+2*param.delta*pf3;
+          Dune::FieldVector<RF,dim> gradpf_f(0.0);
+          gradpf_f.axpy((1-2*param.delta),ch.gradpf+ch.gradpf2);
+
+          RF rho_f=param.phys.rho_f(ch.pf,ch.pf2);
+          //RF rho_f_reg = rho_f + (param.phys.rho_1+param.phys.rho_2)*param.delta;
+
+          for (size_t i=0; i<ns.pspace.size(); i++)
+          {
+            for(int k=0; k<dim; k++)
+            {
+              // integrate: (div v)*phi
+              //r.accumulate(ns.pspace,i, -1.0* pf_f*(v*gradphi[i][0])*factor);            Weak form
+              r.accumulate(ns.pspace,i, -1.0 * (pf_f*ns.div_v  + (gradpf_f*ns.v) )* ns.pbasis.phi[i] * factor);
+            }
+          }
+          for (size_t i=0; i<ns.vfemspace.size(); i++)
+          {
+            for(int k=0; k<dim; k++)
+            {
+              // integrate: ( (rho+rhoOld)/2 * v_n+1 - rhoOld * v_n)/dt * phi   + nu * Dv_n+1 : D phi - p_n+1 div phi
+
+              //std::cout << (param.nu * (jacv[k]*gradvphi[i][0]) - p * gradvphi[i][0][k]
+              //- param.rho*g[k]*vphi[i] )*factor << std::endl;
+
+              //RF lambda = 3;
+              //const auto v_nabla_v = v * jacv[k];
+              RF gradxi3k = -param.tw.Sigma3*(ch.gradxi[k]/param.tw.Sigma1 + ch.gradxi2[k]/param.tw.Sigma2);
+              RF S = 0;
+              S += - ch.xi2*(ch.gradpf[k]*pf_f  - ch.pf  * gradpf_f[k])/(pf_f*pf_f); //TODO!!!!!!! Other pf_f scaling!!!!!
+              S += - ch.xi *(ch.gradpf2[k]*pf_f - ch.pf2 * gradpf_f[k])/(pf_f*pf_f);
+              S += - 2*param.delta*pf3*(gradxi3k-ch.gradxi2[k]-ch.gradxi[k]);
+
+              //Stronger form - flow in interfaces possible
+              //S += -ch.pf*ch.gradxi[k] - ch.pf2*ch.gradxi2[k] - 2*param.delta*pf3*gradxi3k;
+
+              //Works but is not the one in the theory (same as above, w/o regularization)
+              //S += -ch.pf*ch.gradxi[k] - ch.pf2*ch.gradxi2[k];
+
+              S = S*param.SurfaceTensionScaling*ns.vbasis.phi[i];
+
+              r.accumulate(child(ns.vspace,k),i, (//   rho_f_reg*(ns.v[k]-ns.vOld[k])*ns.vbasis.phi[i]/param.time.dt          //TimeEvolution
+                                                //- ns.p * (pf_f*ns.vbasis.gradphi[i][0][k] + ns.vbasis.phi[i]*gradpf_f[k])            //Pressure in weak form
+                                                + pf_f * (ns.gradp[k] * ns.vbasis.phi[i]) //Pressure in strong form
+                                                + param.phys.eval_mu(pf_f) * (ns.jacv[k]*ns.vbasis.gradphi[i][0]) //+vphi[i]*(jacv[k]*gradpf)   )  //Viscosity
+                                                + param.vDis.eval(pf_f)*ns.v[k]*ns.vbasis.phi[i]              //Velocity Dissipation in Solid
+                                                //- rho*g[k]*vphi[i]                //Gravitation
+                                                - S                                //Surface Tension
+                                              )*factor);
+            } //for k
+          } // for i
+        } // for ip
+      } //alpha volume
+
+    };
diff --git a/dune/phasefield/porenetwork/fem_2p_navierstokes_transmissibility.hh b/dune/phasefield/porenetwork/fem_2p_navierstokes_transmissibility.hh
new file mode 100644
index 0000000000000000000000000000000000000000..eaa3364d03d74a11cf1b5f9c6a765464f5d6150f
--- /dev/null
+++ b/dune/phasefield/porenetwork/fem_2p_navierstokes_transmissibility.hh
@@ -0,0 +1,148 @@
+#pragma once
+
+#include<dune/pdelab/common/quadraturerules.hh>
+#include<dune/pdelab/finiteelement/localbasiscache.hh>
+#include<dune/pdelab/localoperator/defaultimp.hh>
+#include<dune/pdelab/localoperator/pattern.hh>
+#include<dune/pdelab/localoperator/flags.hh>
+#include<dune/pdelab/localoperator/variablefactories.hh>
+#include<dune/pdelab/gridfunctionspace/gridfunctionspace.hh>
+
+#include<dune/phasefield/localoperator/fem_base_chns.hh>
+
+
+
+
+template<typename Param, typename CHGFS, typename CHContainer, typename NSGFS, typename NSContainer>
+    class FEM_2P_NavierStokes_Transmissibility :
+      public Dune::PDELab::FullVolumePattern,
+      public Dune::PDELab::LocalOperatorDefaultFlags,
+      public Dune::PDELab::NumericalJacobianVolume<FEM_2P_NavierStokes_Transmissibility<Param, CHGFS, CHContainer, NSGFS, NSContainer> >,
+      public Dune::PDELab::NumericalJacobianApplyVolume<FEM_2P_NavierStokes_Transmissibility<Param, CHGFS, CHContainer, NSGFS, NSContainer> >
+    {
+    private:
+      typedef typename CHContainer::field_type RF;
+      typedef typename NSGFS::Traits::GridViewType::template Codim<0>::Entity   ENTITY;
+
+      CHLocalBasisCache<CHGFS> chCache;
+      VLocalBasisCache<NSGFS> vCache;
+      PLocalBasisCache<NSGFS> pCache;
+
+      typedef GFS_LocalViewer<CHGFS, CHContainer, ENTITY, RF> CHLView;
+      mutable CHLView chLocal;
+      //mutable CHLView chOldLocal;
+
+      typedef GFS_LocalViewer<NSGFS, NSContainer, ENTITY, RF> NSLView;
+      mutable NSLView nsOldLocal;
+
+      Param& param; // parameter functions
+
+      //FOR DETECTING ENTITY changes
+      typedef typename NSGFS::Traits::GridViewType::template Codim<0>::Entity   ENT;
+      mutable ENT OldEnt;
+
+    public:
+
+
+      // pattern assembly flags
+      enum { doPatternVolume = true };
+
+      // residual assembly flags
+      enum { doAlphaVolume = true };
+      //enum { doLambdaVolume = true };
+
+
+
+      FEM_2P_NavierStokes_Transmissibility (Param& param_, CHGFS& chGfs_, CHContainer& chV_, CHContainer& chVOld_,
+                         NSGFS& nsGfs_, NSContainer& nsVOld_) :
+        chLocal(chGfs_,chV_),
+        //chOldLocal(chGfs_,chVOld_),
+        nsOldLocal(nsGfs_,nsVOld_),
+        param(param_)
+      {
+      }
+
+
+      template<typename EG, typename LFSU, typename X, typename LFSV, typename R>
+      void alpha_volume (const EG& eg, const LFSU& lfsu, const X& x, const LFSV& lfsv, R& r) const
+      {
+
+        //Quadrature Rule
+        const int dim = EG::Entity::dimension;
+        const int order = 5; //TODO: Choose more educated
+        auto rule = Dune::PDELab::quadratureRule(eg.geometry(), order);
+
+        chLocal.DoEvaluation(eg);
+        //chOldLocal.DoEvaluation(eg);
+        nsOldLocal.DoSubEvaluation(eg,child(nsOldLocal.lfs,Dune::Indices::_0));
+
+        for(const auto& ip : rule)
+        {
+          const auto S = eg.geometry().jacobianInverseTransposed(ip.position());
+          auto factor = ip.weight()*eg.geometry().integrationElement(ip.position());
+
+          CHVariables_Threephase_Extension<RF,dim,decltype(chLocal.lfs)> ch(chCache, ip.position(), chLocal.lfs, chLocal.lv, S);
+          NSVariables_P_VOld_Extension<RF,dim,LFSV> ns(vCache, pCache, ip.position(), lfsv, x.base(), nsOldLocal.lv, S);
+
+
+          RF pf3=1-ch.pf-ch.pf2;
+          RF pf_f=ch.pf+ch.pf2+2*param.delta*pf3;
+          Dune::FieldVector<RF,dim> gradpf_f(0.0);
+          gradpf_f.axpy((1-2*param.delta),ch.gradpf+ch.gradpf2);
+
+          RF rho_f=param.phys.rho_f(ch.pf,ch.pf2);
+          RF rho_f_reg = rho_f + (param.phys.rho_1+param.phys.rho_2)*param.delta;
+
+          for (size_t i=0; i<ns.pspace.size(); i++)
+          {
+            for(int k=0; k<dim; k++)
+            {
+              // integrate: (div v)*phi
+              //r.accumulate(ns.pspace,i, -1.0* pf_f*(v*gradphi[i][0])*factor);            Weak form
+              r.accumulate(ns.pspace,i, -1.0 * (pf_f*ns.div_v  + (gradpf_f*ns.v) )* ns.pbasis.phi[i] * factor);
+            }
+          }
+          for (size_t i=0; i<ns.vfemspace.size(); i++)
+          {
+            for(int k=0; k<dim; k++)
+            {
+              // integrate: ( (rho+rhoOld)/2 * v_n+1 - rhoOld * v_n)/dt * phi   + nu * Dv_n+1 : D phi - p_n+1 div phi
+
+              //std::cout << (param.nu * (jacv[k]*gradvphi[i][0]) - p * gradvphi[i][0][k]
+              //- param.rho*g[k]*vphi[i] )*factor << std::endl;
+
+              //RF lambda = 3;
+              //const auto v_nabla_v = v * jacv[k];
+              RF gradxi3k = -param.tw.Sigma3*(ch.gradxi[k]/param.tw.Sigma1 + ch.gradxi2[k]/param.tw.Sigma2);
+              RF S = 0;
+              S += - ch.xi2*(ch.gradpf[k]*pf_f  - ch.pf  * gradpf_f[k])/(pf_f*pf_f); //TODO!!!!!!! Other pf_f scaling!!!!!
+              S += - ch.xi *(ch.gradpf2[k]*pf_f - ch.pf2 * gradpf_f[k])/(pf_f*pf_f);
+              S += - 2*param.delta*pf3*(gradxi3k-ch.gradxi2[k]-ch.gradxi[k]);
+
+              //Stronger form - flow in interfaces possible
+              //S += -ch.pf*ch.gradxi[k] - ch.pf2*ch.gradxi2[k] - 2*param.delta*pf3*gradxi3k;
+
+              //Works but is not the one in the theory (same as above, w/o regularization)
+              //S += -ch.pf*ch.gradxi[k] - ch.pf2*ch.gradxi2[k];
+
+              S = S*param.SurfaceTensionScaling*ns.vbasis.phi[i];
+
+              r.accumulate(child(ns.vspace,k),i, (   rho_f_reg*(ns.v[k]-ns.vOld[k])*ns.vbasis.phi[i]/param.time.dt          //TimeEvolution
+                                                //- ns.p * (pf_f*ns.vbasis.gradphi[i][0][k] + ns.vbasis.phi[i]*gradpf_f[k])            //Pressure in weak form
+                                                + pf_f * (ns.gradp[k] * ns.vbasis.phi[i]) //Pressure in strong form
+                                                + param.phys.eval_mu(pf_f) * (ns.jacv[k]*ns.vbasis.gradphi[i][0]) //+vphi[i]*(jacv[k]*gradpf)   )  //Viscosity
+                                                + param.vDis.eval(pf_f)*ns.v[k]*ns.vbasis.phi[i]              //Velocity Dissipation in Solid
+                                                //- rho*g[k]*vphi[i]                //Gravitation
+                                                - S                                //Surface Tension
+                                              )*factor);
+              if(k==0)
+              {
+                r.accumulate(child(ns.vspace,k),i, ( pf_f * (param.phys.outerMomentumXForce * ns.vbasis.phi[i])   // Momentum Forcing Term
+                                              )*factor);
+              }
+            } //for k
+          } // for i
+        } // for ip
+      } //alpha volume
+
+    };
diff --git a/dune/phasefield/porenetwork/pn_2pflow.hh b/dune/phasefield/porenetwork/pn_2pflow.hh
new file mode 100644
index 0000000000000000000000000000000000000000..02fc246a89ff3b6e3765a994fea8f22d00634680
--- /dev/null
+++ b/dune/phasefield/porenetwork/pn_2pflow.hh
@@ -0,0 +1,449 @@
+#pragma once
+
+// C includes
+#include<sys/stat.h>
+// C++ includes
+#include<iostream>
+#include<vector>
+// Dune includes
+#include<dune/grid/io/file/vtk.hh>
+#include<dune/pdelab/newton/newton.hh>
+#include<dune/pdelab/common/functionutilities.hh>
+#include<dune/pdelab/finiteelementmap/pkfem.hh>
+#include<dune/pdelab/function/callableadapter.hh>
+
+#include <dune/phasefield/porenetwork/fem_2p_navierstokes_pressuresaturation.hh>
+#include <dune/phasefield/porenetwork/fem_2p_cahnhilliard_pressuresaturation.hh>
+#include <dune/phasefield/porenetwork/fem_2p_cahnhilliard_precipitation.hh>
+#include <dune/phasefield/porenetwork/fem_2p_navierstokes_transmissibility.hh>
+#include <dune/phasefield/localoperator/pf_3p_diff_estimator.hh>
+
+#include <dune/phasefield/utility/ISTLBackend_NOVLP_BASE_PREC_FOR_GMRES.hh>
+
+#include <dune/phasefield/boundary_rectangular.hh>
+#include <dune/phasefield/porenetwork/pn_initial.hh>
+#include <dune/phasefield/chns_base.hh>
+#include <dune/phasefield/fff_chns.hh>
+#include <dune/phasefield/initial_fn.hh>
+#include <dune/phasefield/debug/vector_debug.hh>
+
+template< typename Grid>
+std::shared_ptr<Grid> initPnGrid(std::string filename)
+{
+  Dune::GridFactory<Grid> factory;
+  Dune::GmshReader<Grid>::read(factory,filename,true,true);
+  return std::shared_ptr<Grid>(factory.createGrid());
+}
+
+
+template<typename Parameters>
+class Pn_2PFlow{
+private:
+
+  typedef double RF;
+  static const int dim = 2;
+
+  typedef Dune::ALUGrid<2,2,Dune::simplex,Dune::conforming> Grid;
+  typedef Grid::ctype DF;
+  typedef Grid::LeafGridView GV;
+  typedef Dune::PDELab::AllEntitySet<GV> ES;
+  typedef Dune::PDELab::PkLocalFiniteElementMap<ES,DF,double,2> V_FEM;
+  typedef Dune::PDELab::PkLocalFiniteElementMap<ES,DF,double,1> P_FEM;
+  typedef Dune::PDELab::PkLocalFiniteElementMap<ES,DF,double,1> PHI_FEM;
+
+  typedef GFS_fff_chns<RF, ES, V_FEM, P_FEM, PHI_FEM> GFS;
+
+  typedef typename GFS::NS NS_GFS;
+  typedef typename GFS::CH CH_GFS;
+  typedef Dune::PDELab::Backend::Vector<CH_GFS, RF> CH_V;
+  typedef Dune::PDELab::Backend::Vector<NS_GFS, RF> NS_V;
+
+  typedef Ini_fff_chns< ZeroInitialVector<GV,RF, dim, Parameters>, //V
+                    ZeroInitial<GV,RF,Parameters>,                 //P
+                    PhiInitial_2p_Quartersquare<GV,RF,Parameters,0>,
+                    ZeroInitial<GV,RF,Parameters>,
+                    PhiInitial_2p_Quartersquare<GV,RF,Parameters,1>,
+                    ZeroInitial<GV,RF,Parameters>>  Initial;
+  typedef DomainSize<RF> DS;
+  typedef Bdry_fff_chns_compositeV_2d_Explicit_Domain<AllBoundary<DS>, //V
+                    AllBoundary<DS>, //V
+                    TopRightCorner<DS>,  //P
+                    NoBoundary<DS>,
+                    NoBoundary<DS>,
+                    NoBoundary<DS>,
+                    NoBoundary<DS>> Bdry;
+
+  typedef FEM_2P_NavierStokes_PressureSaturation<Parameters, CH_GFS, CH_V, NS_GFS, NS_V> NS_PS_LOP;
+  typedef FEM_2P_CahnHilliard_PressureSaturation<Parameters, CH_GFS, CH_V, NS_GFS, NS_V> CH_PS_LOP;
+  typedef FEM_2P_CahnHilliard_Precipitation<Parameters, CH_GFS, CH_V> CH_R_LOP;
+  typedef FEM_2P_NavierStokes_Transmissibility<Parameters, CH_GFS, CH_V, NS_GFS, NS_V> NS_T_LOP;
+
+  typedef Dune::PDELab::ISTL::BCRSMatrixBackend<> MBE;
+
+  typedef DGF_fff_chns<GFS, NS_V, CH_V> DGF;
+
+  typedef Dune::PDELab::GridOperator<NS_GFS,NS_GFS,NS_PS_LOP,MBE,RF,RF,RF,typename GFS::NS_CC,typename GFS::NS_CC> NS_PS_GO;
+  typedef Dune::PDELab::GridOperator<CH_GFS,CH_GFS,CH_PS_LOP,MBE,RF,RF,RF,typename GFS::CH_CC,typename GFS::CH_CC> CH_PS_GO;
+  typedef Dune::PDELab::GridOperator<CH_GFS,CH_GFS,CH_R_LOP, MBE,RF,RF,RF,typename GFS::CH_CC,typename GFS::CH_CC> CH_R_GO;
+  typedef Dune::PDELab::GridOperator<NS_GFS,NS_GFS,NS_T_LOP, MBE,RF,RF,RF,typename GFS::NS_CC,typename GFS::NS_CC> NS_T_GO;
+
+  typedef ISTLBackend_NOVLP_BASE_PREC_FOR_GMRES<NS_PS_GO, Dune::SeqILU0, Dune::RestartedGMResSolver> NS_PS_LS;
+  typedef ISTLBackend_NOVLP_BASE_PREC_FOR_GMRES<CH_PS_GO, Dune::SeqILU0, Dune::RestartedGMResSolver> CH_PS_LS;
+  typedef ISTLBackend_NOVLP_BASE_PREC_FOR_GMRES<CH_R_GO,  Dune::SeqILU0, Dune::RestartedGMResSolver> CH_R_LS;
+  typedef ISTLBackend_NOVLP_BASE_PREC_FOR_GMRES<NS_T_GO,  Dune::SeqILU0, Dune::RestartedGMResSolver> NS_T_LS;
+
+  typedef Dune::PDELab::Newton<NS_PS_GO,NS_PS_LS,NS_V> NS_PS_Newton;
+  typedef Dune::PDELab::Newton<CH_PS_GO,CH_PS_LS,CH_V> CH_PS_Newton;
+  typedef Dune::PDELab::Newton<CH_R_GO,CH_R_LS,CH_V> CH_R_Newton;
+  typedef Dune::PDELab::Newton<NS_T_GO,NS_T_LS,NS_V> NS_T_Newton;
+
+  Parameters param;
+  std::shared_ptr<Grid> gridp;
+  GV gv;
+  ES es;
+  V_FEM vFem;
+  P_FEM pFem;
+  PHI_FEM phiFem;
+
+  GFS gfs;
+
+  CH_V chV, chVOld;
+  NS_V nsV, nsVOld;
+  Initial initial;
+  DS ds;
+  Bdry bdry;
+
+  MBE mbe;
+
+  RF kf = 0;
+  RF phiSolid = 0;
+
+  RF PoreReferenceLength;
+  RF initialPhiSolid = 0;
+
+  std::unique_ptr<NS_PS_LOP> nspsLop;
+  std::unique_ptr<CH_PS_LOP> chpsLop;
+  std::unique_ptr<CH_R_LOP>  chrLop;
+  std::unique_ptr<NS_T_LOP>  nstLop;
+  std::unique_ptr<DGF> dgf;
+  std::unique_ptr<NS_PS_GO> nspsGo;
+  std::unique_ptr<CH_PS_GO> chpsGo;
+  std::unique_ptr<CH_R_GO>  chrGo;
+  std::unique_ptr<NS_T_GO>  nstGo;
+
+  std::unique_ptr<NS_PS_LS> nspsLs;
+  std::unique_ptr<CH_PS_LS> chpsLs;
+  std::unique_ptr<CH_R_LS>  chrLs;
+  std::unique_ptr<NS_T_LS>  nstLs;
+
+  std::unique_ptr<NS_PS_Newton>  nspsNewton;
+  std::unique_ptr<CH_PS_Newton>  chpsNewton;
+  std::unique_ptr<CH_R_Newton>   chrNewton;
+  std::unique_ptr<NS_T_Newton>   nstNewton;
+  std::unique_ptr<Dune::VTKSequenceWriter<GV>> vtkwriter;
+
+  //------------------------------------------------------------------------------------
+
+
+  void initializeGridOperators()
+  {
+    //Grid Operator
+    nspsGo = std::make_unique<NS_PS_GO>(gfs.ns,gfs.nsCC,gfs.ns,gfs.nsCC,*nspsLop,mbe);
+    chpsGo = std::make_unique<CH_PS_GO>(gfs.ch,gfs.chCC,gfs.ch,gfs.chCC,*chpsLop,mbe);
+    chrGo  = std::make_unique<CH_R_GO> (gfs.ch,gfs.chCC,gfs.ch,gfs.chCC,*chrLop,mbe);
+    nstGo  = std::make_unique<NS_T_GO> (gfs.ns,gfs.nsCC,gfs.ns,gfs.nsCC,*nstLop,mbe);
+    // Linear solver
+    nspsLs = std::make_unique<NS_PS_LS>(*nspsGo,1000,200,3,0);
+    chpsLs = std::make_unique<CH_PS_LS>(*chpsGo,500,100,3,0);
+    chrLs  = std::make_unique<CH_R_LS>(*chrGo,500,100,3,0);
+    nstLs  = std::make_unique<NS_T_LS>(*nstGo,1000,200,3,0);
+    // Nonlinear solver
+    nspsNewton = std::make_unique<NS_PS_Newton>(*nspsGo,nsV,*nspsLs);
+    nspsNewton->setParameters(param.nsNewtonTree);
+
+    chpsNewton = std::make_unique<CH_PS_Newton>(*chpsGo,chV,*chpsLs);
+    chpsNewton->setParameters(param.chNewtonTree);
+
+    chrNewton = std::make_unique<CH_R_Newton>(*chrGo,chV,*chrLs);
+    chrNewton->setParameters(param.chNewtonTree);
+
+    nstNewton = std::make_unique<NS_T_Newton>(*nstGo,nsV,*nstLs);
+    nstNewton->setParameters(param.nsNewtonTree);
+
+    //printVector(chV,10,"chV");
+    //printVector(nsV,10,"nsV");
+  }
+
+  void remesh()
+  {
+    // mark elements for refinement
+    typedef RefinementIndicator<GV,RF,PF_3P_DIFF_ESTIMATOR<CH_GFS>,CH_GFS> RIND;
+    RIND rInd(gv,gfs.ch,param.pTree.sub("Refinement"));
+    rInd.calculateIndicator(gv,chV,false);
+    rInd.markGrid(*gridp,2);
+    rInd.refineGrid(*gridp,chV,nsV,gfs.ch,gfs.ns,0);
+    // recompute constraints
+    gfs.updateConstraintsContainer(bdry);
+    interpolateToBdry(gfs,initial.iniNS,initial.iniCH,nsV,chV);
+    initializeGridOperators();
+  }
+
+  void applyNsPressureSaturation (int verbosity = 0)
+  {
+    nsVOld = nsV;
+    if (verbosity > 0)   std::cout << "= Begin newtonapply NS_PS:" << std::endl;
+    nspsNewton->apply();
+  }
+
+  void applyChPressureSaturation(int verbosity = 0)
+  {
+    chVOld = chV;
+    if (verbosity > 0)   std::cout << "= Begin newtonapply CH_PS:" << std::endl;
+    chpsNewton->apply();
+    //chVOld = chV;
+    remesh();
+  }
+
+  void applyNsTransmissibility(int verbosity = 0)
+  {
+    if (verbosity > 0)   std::cout << "= Begin newtonapply NS_T:" << std::endl;
+    nstNewton->apply();
+  }
+
+  void applyChReaction(int verbosity = 0)
+  {
+    chVOld = chV;
+    if (verbosity > 0)   std::cout << "= Begin newtonapply CH_R:" << std::endl;
+    chrNewton->apply();
+    //chVOld = chV;
+    remesh();
+  }
+
+/*  void updateKf()
+  {
+    auto productFunction = Dune::PDELab::makeGridFunctionFromCallable (gv, [&](const auto& element, const auto& xlocal){
+        Dune::FieldVector<double,1> w;
+        dgf->vxDgf.evaluate(element, xlocal, w);
+        Dune::FieldVector<double,1> phi1;
+        dgf->phiDgf.evaluate(element, xlocal, phi1);
+        return Dune::FieldVector<double,1>(phi1*w);
+        //Dune::FieldVector<double,1> phi2;
+        //dgf->phi2Dgf.evaluate(element, xlocal, phi2);
+        //return Dune::FieldVector<double,1>((phi1+phi2)*w);
+    });
+    Dune::FieldVector<double,1> integral;
+    Dune::PDELab::integrateGridFunction(productFunction,integral,2);
+    // Calculation of kf: 4* because of Quarter-Circle,
+    // Scaling with x_ref^4
+    kf = 4 * integral[0] * PoreReferenceLength*PoreReferenceLength*PoreReferenceLength*PoreReferenceLength;
+  }
+
+  void updatePhiSolid()
+  {
+    auto productFunction = Dune::PDELab::makeGridFunctionFromCallable (gv, [&](const auto& element, const auto& xlocal){
+      Dune::FieldVector<double,1> phi1;
+      dgf->phiDgf.evaluate(element, xlocal, phi1);
+      return Dune::FieldVector<double,1>(1-phi1);
+      //Dune::FieldVector<double,1> phi2;
+      //dgf->phi2Dgf.evaluate(element, xlocal, phi2);
+      //return Dune::FieldVector<double,1>(1-phi1-phi2);
+    });
+    Dune::FieldVector<double,1> integral;
+    Dune::PDELab::integrateGridFunction(productFunction,integral,2);
+    phiSolid = integral[0];
+  }
+
+  RF calculateGrowthSpeed()
+  {
+    auto productFunction = Dune::PDELab::makeGridFunctionFromCallable (gv, [&](const auto& element, const auto& xlocal){
+      Dune::FieldVector<double,1> phi1;
+      dgf->phiDgf.evaluate(element, xlocal, phi1);
+
+      RF Rspeed = phi1[0] < 0.95 ? param.dw.eval_q(phi1[0]) : 0.0f;
+      RF R1 = -Rspeed/param.eps*param.reaction.eval(1);
+      return Dune::FieldVector<double,1>(-R1);
+    });
+    Dune::FieldVector<double,1> integral;
+    Dune::PDELab::integrateGridFunction(productFunction,integral,2);
+    return integral[0];
+  }
+
+*/
+
+//------------------------------------------------------------------------------------
+
+public:
+
+  //Constructor
+  Pn_2PFlow(std::string GridFilename, std::string OutputFilename, Parameters param_, RF PoreBaseRadius_ = 10e-6) :
+  param(param_),
+  gridp(initPnGrid<Grid>(GridFilename)),
+  gv(gridp->leafGridView()),
+  es(gv),
+  vFem(es), pFem(es), phiFem(es),
+  gfs(es,vFem,pFem,phiFem),
+  chV(gfs.ch), nsV(gfs.ns), chVOld(gfs.ch), nsVOld(gfs.ns),
+  initial(gv,param), ds(0,1,0,1,1e-6), bdry(ds), mbe(10),
+  PoreReferenceLength(PoreBaseRadius_ / (1-param.initial.ptree.get("Radius",0.2) ) )
+  {
+    Dune::PDELab::interpolate(initial.iniCH , gfs.ch, chV);
+    Dune::PDELab::interpolate(initial.iniNS , gfs.ns, nsV);
+
+    // Refine Intial Values
+    for(int i=0; i<param.pTree.get("Refinement.maxRefineLevel",2); i++)
+    {
+      // mark elements for refinement
+      typedef RefinementIndicator<GV,RF,PF_3P_DIFF_ESTIMATOR<CH_GFS>,CH_GFS> RIND0;
+      RIND0 rInd0(gv,gfs.ch,param.pTree.sub("Refinement"));
+      rInd0.calculateIndicator(gv,chV,false);
+      rInd0.markGrid(*gridp,2);
+      rInd0.refineGrid(*gridp,chV,nsV,gfs.ch,gfs.ns,1);
+      //rInd0.myRefineGrid(grid,gv,chV,nsV,gfs.ch,gfs.ns,1);
+      Dune::PDELab::interpolate(initial.iniCH , gfs.ch, chV);
+      Dune::PDELab::interpolate(initial.iniNS , gfs.ns, nsV);
+    }
+
+    gfs.updateConstraintsContainer(bdry);
+    interpolateToBdry(gfs,initial.iniNS,initial.iniCH,nsV,chV);
+
+    //chVOld = chV;
+
+    //Local Operator
+    nspsLop = std::make_unique<NS_PS_LOP>(param, gfs.ch, chV, chVOld, gfs.ns, nsVOld);
+    chpsLop = std::make_unique<CH_PS_LOP>(param, gfs.ch, chVOld, gfs.ns, nsV);
+    chrLop =  std::make_unique<CH_R_LOP> (param, gfs.ch, chVOld);
+    nstLop = std::make_unique<NS_T_LOP> (param, gfs.ch, chV, chVOld, gfs.ns, nsVOld);
+
+    dgf = std::make_unique<DGF>(gfs,nsV,chV);
+
+    struct stat st;
+    if( stat( OutputFilename.c_str(), &st ) != 0 )
+    {
+      int stat = 0;
+      stat = mkdir(OutputFilename.c_str(),S_IRWXU|S_IRWXG|S_IRWXO);
+      if( stat != 0 && stat != -1)
+        std::cout << "Error: Cannot create directory "  << OutputFilename << std::endl;
+    }
+    auto stationaryvtkwriter = std::make_shared<Dune::SubsamplingVTKWriter<GV> >(gv,0);
+    vtkwriter = std::make_unique<Dune::VTKSequenceWriter<GV> >(stationaryvtkwriter,OutputFilename.c_str(),OutputFilename.c_str(),"");
+    dgf->addToVTKWriter(*vtkwriter);
+
+
+    initializeGridOperators();
+
+/*    applyNs();
+    updatePhiSolid();
+    initialPhiSolid = phiSolid;
+    updateKf();
+*/
+
+    RF dtmax = param.pTree.get("Time.dtMax",0.01);
+    param.time.dt = dtmax;
+    for(int i=0; i<1000; i++)
+    {
+      writeVTK(i);
+      if(i < 10)
+      {
+        applyChPressureSaturation(1);
+      }
+      else if(i<40)
+      {
+        param.reaction.reactionRate = 0;
+        applyChPressureSaturation(1);
+        applyNsPressureSaturation(1);
+      }
+      else
+      {
+        param.reaction.reactionRate = 1;
+        applyChReaction(1);
+      }
+    }
+  }
+
+  void writeVTK(RF time)
+  {
+    vtkwriter->write(time,Dune::VTK::ascii);
+  }
+
+/*
+
+  void grow(RF length)  // How much the the solid-fluid interface should grow in normal direction (in m)
+  {
+    length = length/PoreReferenceLength;
+    if(length <= 0)
+    {
+      std::cout << "Need positive length (dissolution not yet implemented)" << std::endl;
+      return;
+    }
+    RF dtmax = param.pTree.get("Time.dtMax",0.01);
+    while(length > dtmax)
+    {
+      //writeVTK(1-length);
+      length -= dtmax;
+      param.time.dt = dtmax;
+      applyCh(0);
+    }
+    param.time.dt = length;
+    applyCh(0);
+    applyNs(0);
+    updateKf();
+    updatePhiSolid();
+  }
+
+  void growArea(RF area)  // How much Area the solid phase should grow (in m^2)
+  {
+    RF phiSolid_beforeGrowth = phiSolid;
+    area = area/(PoreReferenceLength*PoreReferenceLength*4);  //4 because of Symmetry
+    if(area <= 0)
+    {
+      std::cout << "Need positive area (dissolution not yet implemented)" << std::endl;
+      return;
+    }
+    RF dtmax = param.pTree.get("Time.dtMax",0.01);
+
+    while(area - (phiSolid - phiSolid_beforeGrowth) > dtmax*calculateGrowthSpeed())
+    {
+      //writeVTK(1-length);
+      param.time.dt = dtmax;
+      applyCh(0);
+      updatePhiSolid();
+    }
+    param.time.dt = (area - (phiSolid - phiSolid_beforeGrowth)) / calculateGrowthSpeed();
+    applyCh(0);
+    applyNs(0);
+    updateKf();
+    updatePhiSolid();
+  }
+
+  RF getKf()
+  {
+    return kf;
+  }
+
+  RF getPhiSolid()
+  {
+    return phiSolid;
+  }
+
+  RF getPoreArea()
+  {
+    return 4*PoreReferenceLength*PoreReferenceLength*(1-phiSolid);  //4 because of Symmetry
+  }
+
+  RF getPoreAreaFraction()
+  {
+    return (1-phiSolid)/(1-initialPhiSolid);
+  }
+
+  void setPoreBaseRadius(RF PoreBaseRadius_)
+  {
+    PoreReferenceLength = PoreBaseRadius_ / (1-param.initial.ptree.get("Radius",0.2) );
+  }
+
+  RF getPoreReferenceLength()
+  {
+    return PoreReferenceLength;
+  }
+
+*/
+};
diff --git a/dune/phasefield/porenetwork/pn_initial.hh b/dune/phasefield/porenetwork/pn_initial.hh
index 2f8c77d89249944a0fa5a93bf23abbd09f960eb1..be66d9ed1dfeeb6afb767b9205ef84dede559ede 100644
--- a/dune/phasefield/porenetwork/pn_initial.hh
+++ b/dune/phasefield/porenetwork/pn_initial.hh
@@ -47,3 +47,61 @@ public:
     }
   }
 };
+
+
+template<typename GV, typename RF, typename Params, const int Phase>
+class PhiInitial_2p_Quartersquare :
+  public Dune::PDELab::AnalyticGridFunctionBase<
+    Dune::PDELab::AnalyticGridFunctionTraits<GV,RF,1>, PhiInitial_2p_Quartersquare<GV,RF,Params,Phase> >
+{
+  const Params& param;
+  RF eps;
+  RF r;
+  int myshape;
+
+public:
+  typedef Dune::PDELab::AnalyticGridFunctionTraits<GV,RF,1> Traits;
+
+  PhiInitial_2p_Quartersquare(const GV & gv, const Params & params) :
+     Dune::PDELab::AnalyticGridFunctionBase<Traits,PhiInitial_2p_Quartersquare<GV,RF,Params,Phase> > (gv),
+     param(params)
+     {
+       eps = params.eps;
+       r = params.initial.ptree.get("Radius",0.2);
+       std::cout << "EPS" << eps;
+       myshape = params.initial.shape;
+     }
+
+  inline void evaluateGlobal(const  typename Traits::DomainType & x, typename Traits::RangeType & y) const
+  {
+    RF Pore = 0;
+    if(myshape == INITIAL_SHAPE_SQUARE)
+    {
+      RF rf1 = param.tw.dw.eval_shape((x[0]-r)*1/eps);
+      RF rf2 = param.tw.dw.eval_shape((x[1]-r)*1/eps);
+      //RF rf1 = 0.5*(1+tanh(1/eps/sqrt(2)*(x[0]-r)));
+      //RF rf2 = 0.5*(1+tanh(1/eps/sqrt(2)*(x[1]-r)));
+      Pore=rf1*rf2;
+    }
+    else if(myshape == INITIAL_SHAPE_CIRCLE)
+    {
+      RF rad = sqrt((x[0]-1)*(x[0]-1) + (x[1]-1)*(x[1]-1));
+      Pore = param.tw.dw.eval_shape(((1-r)-rad)*1/eps);
+    }
+    else
+    {
+      std::cout << "WARNING: pn_initial.hh cannot find shape" << myshape << std::endl;
+    }
+
+    RF Cornerflow = param.tw.dw.eval_shape((x[0]+x[1]-4*r)*1/eps);
+
+    if(Phase == 0)
+    {
+      y = Pore*(1-Cornerflow);
+    }
+    if(Phase == 1)
+    {
+      y = Pore*Cornerflow;
+    }
+  }
+};
diff --git a/src/pntest/CMakeLists.txt b/src/pntest/CMakeLists.txt
index baf654051d9d06d2d04855eca95213b15748abd1..05b01592c924f23d1f16e2d14b31b887687cc08b 100644
--- a/src/pntest/CMakeLists.txt
+++ b/src/pntest/CMakeLists.txt
@@ -1,2 +1,3 @@
-add_executable(pntest pntest.cc)
-dune_symlink_to_source_files(FILES grids pn1p.ini)
+#add_executable(pntest pntest.cc)
+add_executable(pn2ptest pn2ptest.cc)
+dune_symlink_to_source_files(FILES grids pn1p.ini pn2p.ini)
diff --git a/src/pntest/pn2p.ini b/src/pntest/pn2p.ini
new file mode 100644
index 0000000000000000000000000000000000000000..4a774f424c8c7972d56f99ff4346dd6a7200b230
--- /dev/null
+++ b/src/pntest/pn2p.ini
@@ -0,0 +1,58 @@
+[Physics]
+uAst = 1
+D = 0.02
+rho1 = 1.0
+rho2 = 1.0
+mu=0.05
+ReactionRate=1#1.5
+#ReactionLimiter = 1000
+SurfaceTensionScaling=1
+VelDissipationRate = 4000
+CurvatureAlpha=0#0.001
+
+[domain]
+filename = grids/square_periodic.msh
+
+[output]
+filename = outp3
+
+[Phasefield]
+eps=0.02
+delta=0.01#0.03
+DoubleWellDelta=0.05
+Mobility=0.0005
+MobilityPressureSaturation=0.5
+Sigma1=1
+Sigma2=20
+Sigma3=20
+Lambda=0
+
+[Time]
+dtMax = 0.002
+
+[Initial]
+shape = 1
+# FlowVyy= 10# pConst/(Domain_width * mu)
+#pConst=0.1
+#uConst=0.5
+#uInflow=0.3
+
+[Refinement]
+etaRefine  = 0.2
+etaCoarsen = 0.1
+maxRefineLevel = 6
+minRefineLevel = -1
+
+[NS_Newton]
+ReassembleThreshold = 0.0
+LineSearchMaxIterations = 30
+MaxIterations = 30
+AbsoluteLimit = 1e-9
+Reduction = 1e-7
+VerbosityLevel = 0
+
+[Phasefield_Newton]
+ReassembleThreshold = 0.0
+LineSearchMaxIterations = 30
+MaxIterations = 30
+VerbosityLevel = 0
diff --git a/src/pntest/pn2ptest.cc b/src/pntest/pn2ptest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f37a01d0b5f9194488930ed6eb62852484d76444
--- /dev/null
+++ b/src/pntest/pn2ptest.cc
@@ -0,0 +1,94 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include<iostream>
+// dune includes
+#include<dune/common/parallel/mpihelper.hh>
+#include<dune/common/parametertreeparser.hh>
+#include<dune/common/timer.hh>
+#if HAVE_DUNE_ALUGRID
+#include<dune/alugrid/grid.hh>
+#endif
+// phasefield includes
+#include<dune/phasefield/porenetwork/pn_2pflow.hh>
+
+//===============================================================
+// Main program
+//===============================================================
+
+
+int main(int argc, char** argv)
+{
+  try{
+    // Maybe initialize Mpi
+    Dune::MPIHelper&
+      helper = Dune::MPIHelper::instance(argc, argv);
+    if(Dune::MPIHelper::isFake)
+      std::cout<< "This is a sequential program." << std::endl;
+    else
+      std::cout << "Parallel code run on "
+                << helper.size() << " process(es)" << std::endl;
+
+    // open ini file
+    Dune::ParameterTree ptree;
+    Dune::ParameterTreeParser ptreeparser;
+    ptreeparser.readINITree("pn2p.ini",ptree);
+    ptreeparser.readOptions(argc,argv,ptree);
+
+    // Define Template Options
+    typedef double RF;
+    typedef Params_pn_2pflow< RF,
+                          TripleWell<RF,
+                              DoubleWell_limited< RF, DoubleWell_poly<RF>, Limiter_FakeDiverging<RF> >
+                          >,
+                          TripleWellHierarchicalV1<RF,
+                              DoubleWell_limited< RF, DoubleWell_poly<RF>, Limiter_FakeDiverging<RF> >,
+                              TPPentalty_6thOrder<RF>
+                          >,
+                          Mobility_pf2p<RF>,
+                          Reaction_Const<RF>,
+                          VelDissipation_Quadratic<RF>
+                          //VelDissipation_Quadratic_Shifted<RF>
+                          > Parameters;
+    Parameters param(ptree);
+
+
+    //Set input/output filenamens
+    std::string GridFilename = ptree.get("domain.filename","square.msh");
+    std::string OutputFilename = ptree.get("output.filename","output");
+
+    //Set initial Shape
+    param.initial.shape = INITIAL_SHAPE_SQUARE;
+    //param.initial.shape = INITIAL_SHAPE_CIRCLE;
+
+    //Create Simulation
+    Pn_2PFlow<Parameters> pn_2pFlow(GridFilename,OutputFilename,param, 10e-6); //Last Parameter is initial pore Radius in m
+
+/*
+    //Example of usecase for Pn_1PFlow
+    std::cout << "Kf = " << pn_1pFlow.getKf() << " phiSolid = " << pn_1pFlow.getPhiSolid() << std::endl;
+    std::cout << "Pore Area = " << pn_1pFlow.getPoreArea() << " m^2" << std::endl;
+    std::cout << "Pore Area Fraction (compared to inital values) = " << pn_1pFlow.getPoreAreaFraction() << std::endl;
+
+    pn_1pFlow.writeVTK(0.0);
+    //pn_1pFlow.grow(2e-6);  //Growth is measured in m
+    pn_1pFlow.growArea((10e-6)*(10e-6)*0.1);   // Growth of Area in m^2
+    pn_1pFlow.writeVTK(1.0);
+    std::cout << "Kf = " << pn_1pFlow.getKf() << " phiSolid = " << pn_1pFlow.getPhiSolid() << std::endl;
+    std::cout << "Total Flux = - Kf/viscosity * gradient p" << std::endl;
+    std::cout << "Kf has unit m^4" << std::endl;
+
+    std::cout << "Pore Area = " << pn_1pFlow.getPoreArea()  << " m^2" << std::endl;
+    std::cout << "Pore Area Fraction (compared to inital values) = " << pn_1pFlow.getPoreAreaFraction() << std::endl;
+*/
+  }
+  catch (Dune::Exception &e){
+    std::cerr << "Dune reported error: " << e << std::endl;
+    return 1;
+  }
+  catch (...){
+    std::cerr << "Unknown exception thrown!" << std::endl;
+    return 1;
+  }
+}