diff --git a/dumux/decoupled/2p2c/2p2cfluidstate.hh b/dumux/decoupled/2p2c/2p2cfluidstate.hh
index 125641d02b9309c682ad2ad2f710e1c2ed5c3beb..60bef96508b3232136c2ee5365b7805e646fdc64 100644
--- a/dumux/decoupled/2p2c/2p2cfluidstate.hh
+++ b/dumux/decoupled/2p2c/2p2cfluidstate.hh
@@ -63,168 +63,6 @@ public:
             numComponents = GET_PROP_VALUE(TypeTag, NumComponents)};
 
 public:
-    /*!
-     * \name flash calculation routines
-     * Routines to determine the phase composition after the transport step.
-     */
-    //@{
-
-    //! the update routine equals the 2p2c - concentration flash for constant p & t.
-    /*!
-     * Routine goes as follows:
-     * - determination of the equilibrium constants from the fluid system
-     * - determination of maximum solubilities (mole fractions) according to phase pressures
-     * - comparison with Z1 to determine phase presence => phase mass fractions
-     * - round off fluid properties
-     * \param Z1 Feed mass fraction: Mass of comp1 per total mass \f$\mathrm{[-]}\f$
-     * \param phasePressure Vector holding the pressure \f$\mathrm{[Pa]}\f$
-     * \param poro Porosity \f$\mathrm{[-]}\f$
-     * \param temperature Temperature \f$\mathrm{[K]}\f$
-     */
-    void update(Scalar Z1, Dune::FieldVector<Scalar, numPhases> phasePressure, Scalar poro, Scalar temperature)
-    {
-        if (pressureType == Indices::pressureGlobal)
-        {
-            DUNE_THROW(Dune::NotImplemented, "Pressure type not supported in fluidState!");
-        }
-        else
-        phasePressure_[wPhaseIdx] = phasePressure[wPhaseIdx];
-        phasePressure_[nPhaseIdx] = phasePressure[nPhaseIdx];
-        temperature_=temperature;
-
-
-        //mole equilibrium ratios K for in case wPhase is reference phase
-        double k1 = FluidSystem::fugacityCoefficient(*this, wPhaseIdx, wCompIdx);    // = p^wComp_vap / p
-        double k2 = FluidSystem::fugacityCoefficient(*this, wPhaseIdx, nCompIdx);    // = H^nComp_w / p
-
-        // get mole fraction from equilibrium konstants
-        moleFraction_[wPhaseIdx][wCompIdx] = (1. - k2) / (k1 -k2);
-        moleFraction_[nPhaseIdx][wCompIdx] = moleFraction_[wPhaseIdx][wCompIdx] * k1;
-
-
-        // transform mole to mass fractions
-        massFraction_[wPhaseIdx][wCompIdx] = moleFraction_[wPhaseIdx][wCompIdx] * FluidSystem::molarMass(wCompIdx)
-            / ( moleFraction_[wPhaseIdx][wCompIdx] * FluidSystem::molarMass(wCompIdx) + (1.-moleFraction_[wPhaseIdx][wCompIdx]) * FluidSystem::molarMass(nCompIdx) );
-        massFraction_[nPhaseIdx][wCompIdx] = moleFraction_[nPhaseIdx][wCompIdx] * FluidSystem::molarMass(wCompIdx)
-            / ( moleFraction_[nPhaseIdx][wCompIdx] * FluidSystem::molarMass(wCompIdx) + (1.-moleFraction_[nPhaseIdx][wCompIdx]) * FluidSystem::molarMass(nCompIdx) );
-
-
-        //mass equilibrium ratios
-        equilRatio_[nPhaseIdx][wCompIdx] = massFraction_[nPhaseIdx][wCompIdx] / massFraction_[wPhaseIdx][wCompIdx];     // = Xn1 / Xw1 = K1
-        equilRatio_[nPhaseIdx][nCompIdx] = (1.-massFraction_[nPhaseIdx][wCompIdx])/ (1.-massFraction_[wPhaseIdx][wCompIdx]); // =(1.-Xn1) / (1.-Xw1)     = K2
-        equilRatio_[wPhaseIdx][nCompIdx] = equilRatio_[wPhaseIdx][wCompIdx] = 1.;
-
-        // phase fraction of nPhase [mass/totalmass]
-        nu_[nPhaseIdx] = 0;
-
-        // check if there is enough of component 1 to form a phase
-        if (Z1 > massFraction_[nPhaseIdx][wCompIdx] && Z1 < massFraction_[wPhaseIdx][wCompIdx])
-            nu_[nPhaseIdx] = -((equilRatio_[nPhaseIdx][wCompIdx]-1)*Z1 + (equilRatio_[nPhaseIdx][nCompIdx]-1)*(1-Z1))
-            / (equilRatio_[nPhaseIdx][wCompIdx]-1) / (equilRatio_[nPhaseIdx][nCompIdx] -1);
-        else if (Z1 <= massFraction_[nPhaseIdx][wCompIdx]) // too little wComp to form a phase
-        {
-            nu_[nPhaseIdx] = 1; // only nPhase
-            massFraction_[nPhaseIdx][wCompIdx] = Z1; // hence, assign complete mass soluted into nPhase
-            massFraction_[nPhaseIdx][nCompIdx] = 1. - massFraction_[nPhaseIdx][wCompIdx];
-            // store as moleFractions
-            moleFraction_[nPhaseIdx][wCompIdx] = ( massFraction_[nPhaseIdx][wCompIdx] / FluidSystem::molarMass(wCompIdx) );  // = moles of compIdx
-            moleFraction_[nPhaseIdx][wCompIdx] /= ( massFraction_[nPhaseIdx][wCompIdx] / FluidSystem::molarMass(wCompIdx)
-                           + massFraction_[nPhaseIdx][nCompIdx] / FluidSystem::molarMass(nCompIdx) );    // /= total moles in phase
-
-            // w phase is already set to equilibrium mass fraction
-        }
-        else    // (Z1 >= Xw1) => no nPhase
-        {
-            nu_[nPhaseIdx] = 0; // no second phase
-            massFraction_[wPhaseIdx][wCompIdx] = Z1;
-            massFraction_[wPhaseIdx][nCompIdx] = 1. - massFraction_[wPhaseIdx][wCompIdx];
-            // store as moleFractions
-            moleFraction_[wPhaseIdx][wCompIdx] = ( massFraction_[wPhaseIdx][wCompIdx] / FluidSystem::molarMass(wCompIdx) );  // = moles of compIdx
-            moleFraction_[wPhaseIdx][wCompIdx] /= ( massFraction_[wPhaseIdx][wCompIdx] / FluidSystem::molarMass(wCompIdx)
-                           + massFraction_[wPhaseIdx][nCompIdx] / FluidSystem::molarMass(nCompIdx) );    // /= total moles in phase
-
-            // n phase is already set to equilibrium mass fraction
-        }
-
-        // complete array of mass fractions
-        massFraction_[wPhaseIdx][nCompIdx] = 1. - massFraction_[wPhaseIdx][wCompIdx];
-        massFraction_[nPhaseIdx][nCompIdx] = 1. - massFraction_[nPhaseIdx][wCompIdx];
-        // complete array of mole fractions
-        moleFraction_[wPhaseIdx][nCompIdx] = 1. - moleFraction_[wPhaseIdx][wCompIdx];
-        moleFraction_[nPhaseIdx][nCompIdx] = 1. - moleFraction_[nPhaseIdx][wCompIdx];
-
-        // complete phase mass fractions
-        nu_[wPhaseIdx] = 1. - nu_[nPhaseIdx];
-
-        // get densities with correct composition
-        density_[wPhaseIdx] = FluidSystem::density(*this, wPhaseIdx);
-        density_[nPhaseIdx] = FluidSystem::density(*this, nPhaseIdx);
-
-        Sw_ = (nu_[wPhaseIdx]) / density_[wPhaseIdx];
-        Sw_ /= (nu_[wPhaseIdx]/density_[wPhaseIdx] + nu_[nPhaseIdx]/density_[nPhaseIdx]);
-    }
-
-    //! a flash routine for 2p2c if the saturation instead of total concentration is known.
-    /*!
-     * Routine goes as follows:
-     * - determination of the equilibrium constants from the fluid system
-     * - determination of maximum solubilities (mole fractions) according to phase pressures
-     * - round off fluid properties
-     * \param sat Saturation of phase 1 \f$\mathrm{[-]}\f$
-     * \param phasePressure Vector holding the pressure \f$\mathrm{[Pa]}\f$
-     * \param poro Porosity \f$\mathrm{[-]}\f$
-     * \param temperature Temperature \f$\mathrm{[K]}\f$
-     */
-    void satFlash(Scalar sat, Dune::FieldVector<Scalar, numPhases> phasePressure, Scalar poro, Scalar temperature)
-    {
-        if (pressureType == Indices::pressureGlobal)
-        {
-            DUNE_THROW(Dune::NotImplemented, "Pressure type not supported in fluidState!");
-        }
-        else  if (sat <= 0. || sat >= 1.)
-            Dune::dinfo << "saturation initial and boundary conditions set to zero or one!"
-                << " assuming fully saturated compositional conditions" << std::endl;
-
-        // assign values
-        Sw_ = sat;
-        phasePressure_[wPhaseIdx] = phasePressure[wPhaseIdx];
-        phasePressure_[nPhaseIdx] = phasePressure[nPhaseIdx];
-        temperature_=temperature;
-        nu_[nPhaseIdx] = nu_[wPhaseIdx] = NAN;  //in contrast to the standard update() method, satflash() does not calculate nu.
-
-
-        //mole equilibrium ratios K for in case wPhase is reference phase
-        double k1 = FluidSystem::fugacityCoefficient(*this, wPhaseIdx, wCompIdx);    // = p^wComp_vap / p
-        double k2 = FluidSystem::fugacityCoefficient(*this, wPhaseIdx, nCompIdx);    // = H^nComp_w / p
-
-        // get mole fraction from equilibrium konstants
-        moleFraction_[wPhaseIdx][wCompIdx] = (1. - k2) / (k1 -k2);
-        moleFraction_[nPhaseIdx][wCompIdx] = moleFraction_[wPhaseIdx][wCompIdx] * k1;
-
-
-        // transform mole to mass fractions
-        massFraction_[wPhaseIdx][wCompIdx] = moleFraction_[wPhaseIdx][wCompIdx] * FluidSystem::molarMass(wCompIdx)
-            / ( moleFraction_[wPhaseIdx][wCompIdx] * FluidSystem::molarMass(wCompIdx) + (1.-moleFraction_[wPhaseIdx][wCompIdx]) * FluidSystem::molarMass(nCompIdx) );
-        massFraction_[nPhaseIdx][wCompIdx] = moleFraction_[nPhaseIdx][wCompIdx] * FluidSystem::molarMass(wCompIdx)
-            / ( moleFraction_[nPhaseIdx][wCompIdx] * FluidSystem::molarMass(wCompIdx) + (1.-moleFraction_[nPhaseIdx][wCompIdx]) * FluidSystem::molarMass(nCompIdx) );
-
-        // complete array of mass fractions
-        massFraction_[wPhaseIdx][nCompIdx] = 1. - massFraction_[wPhaseIdx][wCompIdx];
-        massFraction_[nPhaseIdx][nCompIdx] = 1. - massFraction_[nPhaseIdx][wCompIdx];
-        // complete array of mole fractions
-        moleFraction_[wPhaseIdx][nCompIdx] = 1. - moleFraction_[wPhaseIdx][wCompIdx];
-        moleFraction_[nPhaseIdx][nCompIdx] = 1. - moleFraction_[nPhaseIdx][wCompIdx];
-
-        //mass equilibrium ratios
-        equilRatio_[nPhaseIdx][wCompIdx] = massFraction_[nPhaseIdx][wCompIdx] / massFraction_[wPhaseIdx][wCompIdx];     // = Xn1 / Xw1 = K1
-        equilRatio_[nPhaseIdx][nCompIdx] = (1.-massFraction_[nPhaseIdx][wCompIdx])/ (1.-massFraction_[wPhaseIdx][wCompIdx]); // =(1.-Xn1) / (1.-Xw1)     = K2
-        equilRatio_[wPhaseIdx][nCompIdx] = equilRatio_[wPhaseIdx][wCompIdx] = 1.;
-
-        // get densities with correct composition
-        density_[wPhaseIdx] = FluidSystem::density(*this, wPhaseIdx);
-        density_[nPhaseIdx] = FluidSystem::density(*this, nPhaseIdx);
-    }
-    //@}
     /*!
      * \name acess functions
      */
@@ -296,6 +134,7 @@ public:
             return phasePressure_[nPhaseIdx]*moleFrac(nPhaseIdx, wCompIdx);
         else
             DUNE_THROW(Dune::NotImplemented, "component not found in fluidState!");
+        return 0.;
     }
 
     /*!
@@ -355,6 +194,16 @@ public:
         else
             return nu_[phaseIdx];
     }
+    /*!
+     * \brief Returns the phase mass fraction \f$ \nu \f$:
+     *  phase mass per total mass \f$\mathrm{[kg/kg]}\f$.
+     *
+     * \param phaseIdx the index of the phase
+     */
+    Scalar&  nu(int phaseIdx) const
+    {
+        return phaseMassFraction(phaseIdx);
+    }
 
     /*!
      * \name Functions to set Data
diff --git a/dumux/decoupled/2p2c/2p2cproblem.hh b/dumux/decoupled/2p2c/2p2cproblem.hh
index f20e1582ae6a894924f3caf3da892d1f110496aa..fc24a59f527c06058edf560227ff887f9ea4138d 100644
--- a/dumux/decoupled/2p2c/2p2cproblem.hh
+++ b/dumux/decoupled/2p2c/2p2cproblem.hh
@@ -112,7 +112,9 @@ public:
         if (this->adaptiveGrid)
         {
             this->gridAdapt().adaptGrid();
-            asImp_().pressureModel().updateMaterialLaws(false);
+
+            if(this->gridAdapt().wasAdapted())
+                asImp_().pressureModel().updateMaterialLaws(false);
         }
     }
     /*!
@@ -203,9 +205,9 @@ protected:
         }
         else if (equation == -1)
         {
-            values[Indices::pressureEqIdx] = 0.;
-            values[Indices::contiNEqIdx] =0.;
-            values[Indices::contiWEqIdx] =0.;
+            // set everything to zero
+            for (int i = 0; i < values.size(); i++)
+                values[i] = 0.;
         }
         else
             DUNE_THROW(Dune::InvalidStateException, "vector of primary variables can not be set properly");
diff --git a/dumux/decoupled/2p2c/2p2cproperties.hh b/dumux/decoupled/2p2c/2p2cproperties.hh
index 14dcd5e3a27cd8f06a65a34eed806f99d8f364f3..afbeb76cd3bc94acd504341ea1819672ab096949 100644
--- a/dumux/decoupled/2p2c/2p2cproperties.hh
+++ b/dumux/decoupled/2p2c/2p2cproperties.hh
@@ -89,9 +89,10 @@ NEW_PROP_TAG( FluidSystem ); //!< The fluid system
 NEW_PROP_TAG( FluidState ); //!< The fluid state
 NEW_PROP_TAG( ImpetEnableVolumeIntegral ); //!< Enables volume integral in the pressure equation (volume balance formulation)
 NEW_PROP_TAG( EnableVolumeIntegral ); //!< DEPRECATED Enables volume integral in the pressure equation (volume balance formulation)
-NEW_PROP_TAG( EnableMultiPointFluxApproximationOnAdaptiveGrids ); //!< Two-point flux approximation (false) or mpfa (true)
+NEW_PROP_TAG( GridAdaptEnableMultiPointFluxApproximation); //!< HangingNode: Two-point flux approximation (false) or mpfa (true)
+NEW_PROP_TAG( EnableMultiPointFluxApproximationOnAdaptiveGrids ); //Deprecated
 NEW_PROP_TAG( EnableSecondHalfEdge ); //!< Uses second interaction volume for second half-edge in 2D
-
+NEW_PROP_TAG( GridAdaptEnableSecondHalfEdge ); //!< Uses second interaction volume for second half-edge in 2D
 }}
 
 //DUMUX includes
@@ -155,8 +156,8 @@ SET_PROP(DecoupledTwoPTwoC, TransportSolutionType)
 SET_BOOL_PROP(DecoupledTwoPTwoC, EnableCompressibility, true); //!< Compositional models are very likely compressible
 SET_BOOL_PROP(DecoupledTwoPTwoC, VisitFacesOnlyOnce, false); //!< Faces are regarded from both sides
 SET_BOOL_PROP(DecoupledTwoPTwoC, EnableCapillarity, false); //!< Capillarity is enabled
-SET_BOOL_PROP(DecoupledTwoPTwoC, ImpetRestrictFluxInTransport, GET_PROP_VALUE(TypeTag, RestrictFluxInTransport)); //!< Restrict (no upwind) flux in transport step if direction reverses after pressure equation
-SET_BOOL_PROP(DecoupledTwoPTwoC, RestrictFluxInTransport, false); //!< DEPRECATED Restrict (no upwind) flux in transport step if direction reverses after pressure equation
+SET_INT_PROP(DecoupledTwoPTwoC, ImpetRestrictFluxInTransport, GET_PROP_VALUE(TypeTag, RestrictFluxInTransport)); //!< Restrict (no upwind) flux in transport step if direction reverses after pressure equation
+SET_INT_PROP(DecoupledTwoPTwoC, RestrictFluxInTransport, 0); //!< DEPRECATED Restrict (no upwind) flux in transport step if direction reverses after pressure equation
 
 SET_PROP(DecoupledTwoPTwoC, BoundaryMobility) //!< Saturation scales flux on Dirichlet B.C.
 {    static const int value = DecoupledTwoPTwoCIndices<TypeTag>::satDependent;};
@@ -168,7 +169,9 @@ SET_TYPE_PROP(DecoupledTwoPTwoC, FluidState, TwoPTwoCFluidState<TypeTag>);
 
 SET_TYPE_PROP(DecoupledTwoPTwoC, SpatialParameters, typename GET_PROP_TYPE(TypeTag, SpatialParams));//!< DEPRECATED SpatialParameters property
 
-SET_BOOL_PROP(DecoupledTwoPTwoC, EnableMultiPointFluxApproximationOnAdaptiveGrids, false); //!< MPFA disabled on adaptive grids
+SET_BOOL_PROP(DecoupledTwoPTwoC, GridAdaptEnableMultiPointFluxApproximation,
+        GET_PROP_VALUE(TypeTag,EnableMultiPointFluxApproximationOnAdaptiveGrids)); //!< MPFA disabled on adaptive grids
+SET_BOOL_PROP(DecoupledTwoPTwoC, EnableMultiPointFluxApproximationOnAdaptiveGrids, false); //!<  DEPRECATED MPFA disabled on adaptive grids
 SET_BOOL_PROP(DecoupledTwoPTwoC, ImpetEnableVolumeIntegral, GET_PROP_VALUE(TypeTag,EnableVolumeIntegral)); //!< Regard volume integral in pressure equation
 SET_BOOL_PROP(DecoupledTwoPTwoC, EnableVolumeIntegral, true); //!< DEPRECATED Regard volume integral in pressure equation
 
diff --git a/dumux/decoupled/2p2c/cellData2p2c.hh b/dumux/decoupled/2p2c/cellData2p2c.hh
index 28be1a2f56727ed1d6b7e1970711a81b05bd27ea..d248437103bbfa290137417fb60166bfb1b78bf2 100644
--- a/dumux/decoupled/2p2c/cellData2p2c.hh
+++ b/dumux/decoupled/2p2c/cellData2p2c.hh
@@ -83,6 +83,7 @@ protected:
     Scalar dv_dp_;
     Scalar dv_[numComponents];
     bool volumeDerivativesAvailable_;
+    bool wasRefined_;
 
     int globalIdx_;
     Scalar perimeter_;
@@ -104,6 +105,7 @@ public:
         errorCorrection_= 0.;
         dv_dp_ = 0.;
         volumeDerivativesAvailable_ = false;
+        wasRefined_ = false;
         globalIdx_ = 0;
         perimeter_ = 0.;
     }
@@ -118,7 +120,6 @@ public:
         return fluxData_;
     }
 
-
     /*! \name Acess to primary variables */
     //@{
     /*! Acess to the phase pressure
@@ -351,8 +352,7 @@ public:
     //@}
 
     //! Deprecated set function, use manipulateFluidState() instead
-    void setFluidState(FluidState& fluidState)
-    DUNE_DEPRECATED
+    void setFluidState(FluidState& fluidState) DUNE_DEPRECATED
     {
         fluidState_ = &fluidState;
     }
@@ -389,9 +389,15 @@ public:
     //! Resets the cell data after a timestep was completed: No volume derivatives yet available
     void reset()
     {
+        wasRefined_ = false;
         volumeDerivativesAvailable_ = false;
     }
-
+    //! Indicates if current cell was refined at this time step
+    bool& wasRefined()
+    {   return wasRefined_;}
+    //!\copydoc wasRefined()
+    const bool& wasRefined() const
+    {   return wasRefined_;}
     //! Indicates if current cell is the upwind cell for a given interface
     /* @param indexInInside Local face index seen from current cell
      * @param phaseIdx The index of the phase
diff --git a/dumux/decoupled/2p2c/fluxData2p2c.hh b/dumux/decoupled/2p2c/fluxData2p2c.hh
index e36450b8c541379171a0c77050bf27b2a9bf8627..cd0346ece0bc7e4d11989d8a9b771fc56361acee 100644
--- a/dumux/decoupled/2p2c/fluxData2p2c.hh
+++ b/dumux/decoupled/2p2c/fluxData2p2c.hh
@@ -86,6 +86,11 @@ public:
     {
         isUpwindCell_.resize(size);
     }
+    //! returns the size of the upwind vector which equals number of faces
+    int size()
+    {
+        return isUpwindCell_.size();
+    }
     //! functions returning upwind information
     /* @param indexInInside The local inside index of the intersection
      * @param equationIdx The equation index
diff --git a/dumux/decoupled/2p2c/fvpressure2p2c.hh b/dumux/decoupled/2p2c/fvpressure2p2c.hh
index 8c03597f90c8dfff63e6b7afe4f905c53adbd0f4..dc84219b050dc2ad3b68027857ed809c37835b5c 100644
--- a/dumux/decoupled/2p2c/fvpressure2p2c.hh
+++ b/dumux/decoupled/2p2c/fvpressure2p2c.hh
@@ -300,7 +300,6 @@ void FVPressure2P2C<TypeTag>::getStorage(Dune::FieldVector<Scalar, 2>& storageEn
     // error reduction routine: volumetric error is damped and inserted to right hand side
     // if damping is not done, the solution method gets unstable!
     problem().variables().cellData(globalIdxI).volumeError() /= timestep_;
-    Scalar maxError = maxError_;
     Scalar erri = fabs(cellDataI.volumeError());
     Scalar x_lo = ErrorTermLowerBound_;
     Scalar x_mi = ErrorTermUpperBound_;
@@ -310,17 +309,17 @@ void FVPressure2P2C<TypeTag>::getStorage(Dune::FieldVector<Scalar, 2>& storageEn
     Scalar lofac = 0.;
     Scalar hifac = 0.;
 
-    if ((erri*timestep_ > 5e-5) && (erri > x_lo * maxError))
+    if ((erri*timestep_ > 5e-5) && (erri > x_lo * maxError_))
     {
-        if (erri <= x_mi * maxError)
+        if (erri <= x_mi * maxError_)
             storageEntry[rhs] +=
                     problem().variables().cellData(globalIdxI).errorCorrection() =
-                            fac* (1-x_mi*(lofac-1)/(x_lo-x_mi) + (lofac-1)/(x_lo-x_mi)*erri/maxError)
+                            fac* (1-x_mi*(lofac-1)/(x_lo-x_mi) + (lofac-1)/(x_lo-x_mi)*erri/maxError_)
                                 * cellDataI.volumeError() * volume;
         else
             storageEntry[rhs] +=
                     problem().variables().cellData(globalIdxI).errorCorrection() =
-                            fac * (1 + x_mi - hifac*x_mi/(1-x_mi) + (hifac/(1-x_mi)-1)*erri/maxError)
+                            fac * (1 + x_mi - hifac*x_mi/(1-x_mi) + (hifac/(1-x_mi)-1)*erri/maxError_)
                                 * cellDataI.volumeError() * volume;
     }
     else
@@ -510,28 +509,29 @@ void FVPressure2P2C<TypeTag>::getFlux(Dune::FieldVector<Scalar, 2>& entries,
         }
 
         //perform upwinding if desired
-        if(!upwindWCellData)
+        if(!upwindWCellData or (cellDataI.wasRefined() && cellDataJ.wasRefined() && elementPtrI->father() == neighborPtr->father()))
         {
-            // compute values for both cells
-            Scalar dV_wI = (dv_dC1 * cellDataI.massFraction(wPhaseIdx, wCompIdx)
-                    + dv_dC2 * cellDataI.massFraction(wPhaseIdx, nCompIdx));
-            Scalar gV_wI = (graddv_dC1 * cellDataI.massFraction(wPhaseIdx, wCompIdx)
-                    + graddv_dC2 * cellDataI.massFraction(wPhaseIdx, nCompIdx));
-            dV_wI *= cellDataI.density(wPhaseIdx);
-            gV_wI *= cellDataI.density(wPhaseIdx);
-            Scalar dV_wJ = (dv_dC1 * cellDataJ.massFraction(wPhaseIdx, wCompIdx)
-                    + dv_dC2 * cellDataJ.massFraction(wPhaseIdx, nCompIdx));
-            Scalar gV_wJ = (graddv_dC1 * cellDataJ.massFraction(wPhaseIdx, wCompIdx)
-                    + graddv_dC2 * cellDataJ.massFraction(wPhaseIdx, nCompIdx));
-            dV_wJ *= cellDataJ.density(wPhaseIdx);
-            gV_wJ *= cellDataJ.density(wPhaseIdx);
+            if (cellDataI.wasRefined() && cellDataJ.wasRefined())
+            {
+                problem().variables().cellData(problem().variables().index(*elementPtrI)).setUpwindCell(intersection.indexInInside(), contiWEqIdx, false);
+                cellDataJ.setUpwindCell(intersection.indexInOutside(), contiWEqIdx, false);
+            }
+
+            Scalar averagedMassFraction[2];
+            averagedMassFraction[wCompIdx]
+               = harmonicMean(cellDataI.massFraction(wPhaseIdx, wCompIdx), cellDataJ.massFraction(wPhaseIdx, wCompIdx));
+            averagedMassFraction[nCompIdx]
+               = harmonicMean(cellDataI.massFraction(wPhaseIdx, nCompIdx), cellDataJ.massFraction(wPhaseIdx, nCompIdx));
+            Scalar averageDensity = harmonicMean(cellDataI.density(wPhaseIdx), cellDataJ.density(wPhaseIdx));
 
             //compute means
-            dV_w = harmonicMean(dV_wI, dV_wJ);
-            gV_w = harmonicMean(gV_wI, gV_wJ);
+            dV_w = dv_dC1 * averagedMassFraction[wCompIdx] + dv_dC2 * averagedMassFraction[nCompIdx];
+            dV_w *= averageDensity;
+            gV_w = graddv_dC1 * averagedMassFraction[wCompIdx] + graddv_dC2 * averagedMassFraction[nCompIdx];
+            gV_w *= averageDensity;
             lambdaW = harmonicMean(cellDataI.mobility(wPhaseIdx), cellDataJ.mobility(wPhaseIdx));
         }
-        else
+        else //perform upwinding
         {
             dV_w = (dv_dC1 * upwindWCellData->massFraction(wPhaseIdx, wCompIdx)
                     + dv_dC2 * upwindWCellData->massFraction(wPhaseIdx, nCompIdx));
@@ -542,28 +542,29 @@ void FVPressure2P2C<TypeTag>::getFlux(Dune::FieldVector<Scalar, 2>& entries,
             gV_w *= upwindWCellData->density(wPhaseIdx);
         }
 
-        if(!upwindNCellData)
+        if(!upwindNCellData or (cellDataI.wasRefined() && cellDataJ.wasRefined()))
         {
-            Scalar dV_nI = (dv_dC1 * cellDataI.massFraction(nPhaseIdx, wCompIdx)
-                    + dv_dC2 * cellDataI.massFraction(nPhaseIdx, nCompIdx));
-            Scalar gV_nI = (graddv_dC1 * cellDataI.massFraction(nPhaseIdx, wCompIdx)
-                    + graddv_dC2 * cellDataI.massFraction(nPhaseIdx, nCompIdx));
-            dV_nI *= cellDataI.density(nPhaseIdx);
-            gV_nI *= cellDataI.density(nPhaseIdx);
-            Scalar dV_nJ = (dv_dC1 * cellDataJ.massFraction(nPhaseIdx, wCompIdx)
-                    + dv_dC2 * cellDataJ.massFraction(nPhaseIdx, nCompIdx));
-            Scalar gV_nJ = (graddv_dC1 * cellDataJ.massFraction(nPhaseIdx, wCompIdx)
-                    + graddv_dC2 * cellDataJ.massFraction(nPhaseIdx, nCompIdx));
-            dV_nJ *= cellDataJ.density(nPhaseIdx);
-            gV_nJ *= cellDataJ.density(nPhaseIdx);
+            if (cellDataI.wasRefined() && cellDataJ.wasRefined())
+            {
+                problem().variables().cellData(problem().variables().index(*elementPtrI)).setUpwindCell(intersection.indexInInside(), contiNEqIdx, false);
+                cellDataJ.setUpwindCell(intersection.indexInOutside(), contiNEqIdx, false);
+            }
+            Scalar averagedMassFraction[2];
+            averagedMassFraction[wCompIdx]
+               = harmonicMean(cellDataI.massFraction(nPhaseIdx, wCompIdx), cellDataJ.massFraction(nPhaseIdx, wCompIdx));
+            averagedMassFraction[nCompIdx]
+               = harmonicMean(cellDataI.massFraction(nPhaseIdx, nCompIdx), cellDataJ.massFraction(nPhaseIdx, nCompIdx));
+            Scalar averageDensity = harmonicMean(cellDataI.density(nPhaseIdx), cellDataJ.density(nPhaseIdx));
 
             //compute means
-            dV_n = harmonicMean(dV_nI, dV_nJ);
-            gV_n = harmonicMean(gV_nI, gV_nJ);
+            dV_n = dv_dC1 * averagedMassFraction[wCompIdx] + dv_dC2 * averagedMassFraction[nCompIdx];
+            dV_n *= averageDensity;
+            gV_n = graddv_dC1 * averagedMassFraction[wCompIdx] + graddv_dC2 * averagedMassFraction[nCompIdx];
+            gV_n *= averageDensity;
             lambdaN = harmonicMean(cellDataI.mobility(nPhaseIdx), cellDataJ.mobility(nPhaseIdx));
         }
         else
-        {
+       {
             dV_n = (dv_dC1 * upwindNCellData->massFraction(nPhaseIdx, wCompIdx)
                     + dv_dC2 * upwindNCellData->massFraction(nPhaseIdx, nCompIdx));
             lambdaN = upwindNCellData->mobility(nPhaseIdx);
@@ -573,8 +574,6 @@ void FVPressure2P2C<TypeTag>::getFlux(Dune::FieldVector<Scalar, 2>& entries,
             gV_n *= upwindNCellData->density(nPhaseIdx);
         }
 
-
-
         //calculate current matrix entry
         entries[matrix] = faceArea * (lambdaW * dV_w + lambdaN * dV_n)* (unitOuterNormal * unitDistVec);
         if(enableVolumeIntegral)
@@ -983,7 +982,8 @@ void FVPressure2P2C<TypeTag>::updateMaterialLawsInElement(const Element& element
     }
 
     //complete fluid state
-    fluidState.update(Z1, pressure, problem().spatialParams().porosity(elementI), temperature_);
+    CompositionalFlash<TypeTag> flashSolver;
+    flashSolver.concentrationFlash2p2c(fluidState,  Z1, pressure, problem().spatialParams().porosity(elementI), temperature_);
 
     // iterations part in case of enabled capillary pressure
     Scalar pc(0.), oldPc(0.);
@@ -1015,8 +1015,8 @@ void FVPressure2P2C<TypeTag>::updateMaterialLawsInElement(const Element& element
             //store old pc
             oldPc = pc;
             //update with better pressures
-            fluidState.update(Z1, pressure, problem().spatialParams().porosity(elementI),
-                                problem().temperatureAtPos(globalPos));
+            flashSolver.concentrationFlash2p2c(fluidState, Z1, pressure,
+                    problem().spatialParams().porosity(elementI), problem().temperatureAtPos(globalPos));
             pc = MaterialLaw::pC(problem().spatialParams().materialLawParams(elementI),
                                 fluidState.saturation(wPhaseIdx));
             // TODO: get right criterion, do output for evaluation
diff --git a/dumux/decoupled/2p2c/fvpressure2p2cmultiphysics.hh b/dumux/decoupled/2p2c/fvpressure2p2cmultiphysics.hh
index d70d7cd5719b658946a2089cb73f464ffde30653..77ce4fb3adfc947c5920ecb5080083f0ffb95483 100644
--- a/dumux/decoupled/2p2c/fvpressure2p2cmultiphysics.hh
+++ b/dumux/decoupled/2p2c/fvpressure2p2cmultiphysics.hh
@@ -208,7 +208,7 @@ protected:
 };
 
 //! function which assembles the system of equations to be solved
-/** for first == true, this function assembles the matrix and right hand side for
+/*! for first == true, this function assembles the matrix and right hand side for
  * the solution of the pressure field in the same way as in the class FVPressure2P.
  * for first == false, the approach is changed to \f[-\frac{\partial V}{\partial p}
  * \frac{\partial p}{\partial t}+\sum_{\kappa}\frac{\partial V}{\partial m^{\kappa}}\nabla\cdot
@@ -350,10 +350,11 @@ void FVPressure2P2CMultiPhysics<TypeTag>::get1pStorage(Dune::FieldVector<Scalar,
         Scalar Z1 = cellDataI.massConcentration(wCompIdx) / sumC;
         // initialize simple fluidstate object
         PseudoOnePTwoCFluidState<TypeTag> pseudoFluidState;
-        pseudoFluidState.update(Z1, p_, cellDataI.subdomain(),
+        CompositionalFlash<TypeTag> flashSolver;
+        flashSolver.concentrationFlash1p2c(pseudoFluidState, Z1, p_, cellDataI.subdomain(),
                 problem().temperatureAtPos(elementI.geometry().center()));
 
-        Scalar v_ = 1. / FluidSystem::density(pseudoFluidState, presentPhaseIdx);
+        Scalar v_ = 1. / pseudoFluidState.density(presentPhaseIdx);
         cellDataI.dv_dp() = (sumC * ( v_ - (1. /cellDataI.density(presentPhaseIdx)))) /incp;
 
         if (cellDataI.dv_dp()>0)
@@ -362,9 +363,9 @@ void FVPressure2P2CMultiPhysics<TypeTag>::get1pStorage(Dune::FieldVector<Scalar,
             Dune::dinfo << "dv_dp larger 0 at Idx " << globalIdxI << " , try and invert secant"<< std::endl;
 
             p_ -= 2*incp;
-            pseudoFluidState.update(Z1, p_, cellDataI.subdomain(),
+            flashSolver.concentrationFlash1p2c(pseudoFluidState, Z1, p_, cellDataI.subdomain(),
                     problem().temperatureAtPos(elementI.geometry().center()));
-            v_ = 1. / FluidSystem::density(pseudoFluidState, presentPhaseIdx);
+            v_ = 1. / pseudoFluidState.density(presentPhaseIdx);
             cellDataI.dv_dp() = (sumC * ( v_ - (1. /cellDataI.density(presentPhaseIdx)))) /incp;
             // dV_dp > 0 is unphysical: Try inverse increment for secant
             if (cellDataI.dv_dp()>0)
@@ -479,6 +480,8 @@ void FVPressure2P2CMultiPhysics<TypeTag>::get1pFlux(Dune::FieldVector<Scalar, 2>
         // due to "safety cell" around subdomain, both cells I and J
         // have single-phase conditions, although one is in 2p domain.
         int phaseIdx = std::min(cellDataI.subdomain(), cellDataJ.subdomain());
+        // determine respective equation Idx
+        int contiEqIdx = (phaseIdx == wPhaseIdx) ? contiWEqIdx : contiNEqIdx;
 
         Scalar rhoMean = 0.5 * (cellDataI.density(phaseIdx) + cellDataJ.density(phaseIdx));
         //Scalar density = 0;
@@ -490,14 +493,22 @@ void FVPressure2P2CMultiPhysics<TypeTag>::get1pFlux(Dune::FieldVector<Scalar, 2>
 
         Scalar lambda;
 
-        if (potential >= 0.)
+        if (potential > 0.)
         {
             lambda = cellDataI.mobility(phaseIdx);
+            cellDataJ.setUpwindCell(intersection.indexInOutside(), contiEqIdx, false);  // store in cellJ since cellI is const
             //density = cellDataI.density(phaseIdx);
         }
-        else
+        else if (potential < 0.)
         {
             lambda = cellDataJ.mobility(phaseIdx);
+            cellDataJ.setUpwindCell(intersection.indexInOutside(), contiEqIdx, true);
+            //density = cellDataJ.density(phaseIdx);
+        }
+        else
+        {
+            lambda = harmonicMean(cellDataI.mobility(phaseIdx) , cellDataJ.mobility(phaseIdx));
+            cellDataJ.setUpwindCell(intersection.indexInOutside(), contiEqIdx, false);
             //density = cellDataJ.density(phaseIdx);
         }
 
@@ -732,23 +743,16 @@ void FVPressure2P2CMultiPhysics<TypeTag>::updateMaterialLaws(bool postTimeStep)
         if(oldSubdomainI != 2
                     && nextSubdomain[globalIdx] == 2)
         {
-            // assure correct PV if subdomain used to be simple
-            if(cellData.fluidStateType() != 0) // i.e. it was simple
-            {
-              timer_.stop();
-            }
+            // use complex update of the fluidstate
+            timer_.stop();
             this->updateMaterialLawsInElement(*eIt, postTimeStep);
             timer_.start();
         }
         else if(oldSubdomainI != 2
                     && nextSubdomain[globalIdx] != 2)    // will be simple and was simple
         {
-//            // determine which phase should be present
-//            int presentPhaseIdx = cellData.subdomain(); // this is already =nextSubomainIdx
-
-            // perform simple update
+			// perform simple update
             this->update1pMaterialLawsInElement(*eIt, cellData, postTimeStep);
-            timer_.stop();
         }
         //else
         // a) will remain complex -> everything already done in loop A
@@ -760,7 +764,9 @@ void FVPressure2P2CMultiPhysics<TypeTag>::updateMaterialLaws(bool postTimeStep)
     this->maxError_ = maxError/problem().timeManager().timeStepSize();
 
     timer_.stop();
-    Dune::dinfo << "Subdomain routines took " << timer_.elapsed() << " seconds" << std::endl;
+    
+    if(problem().timeManager().willBeFinished() or problem().timeManager().episodeWillBeOver())
+    	Dune::dinfo << "Subdomain routines took " << timer_.elapsed() << " seconds" << std::endl;
 
     return;
 }
@@ -799,18 +805,13 @@ void FVPressure2P2CMultiPhysics<TypeTag>::update1pMaterialLawsInElement(const El
         pressure[nPhaseIdx] = this->pressure(globalIdx);
     }
 
-//            // make shure total concentrations from solution vector are exact in fluidstate
-//            pseudoFluidState.setMassConcentration(wCompIdx,
-//                    problem().transportModel().totalConcentration(wCompIdx,globalIdx));
-//            pseudoFluidState.setMassConcentration(nCompIdx,
-//                    problem().transportModel().totalConcentration(nCompIdx,globalIdx));
-
     // get the overall mass of component 1:  Z1 = C^k / (C^1+C^2) [-]
     Scalar sumConc = cellData.massConcentration(wCompIdx)
             + cellData.massConcentration(nCompIdx);
     Scalar Z1 = cellData.massConcentration(wCompIdx)/ sumConc;
 
-    pseudoFluidState.update(Z1, pressure, presentPhaseIdx, problem().temperatureAtPos(globalPos));
+    CompositionalFlash<TypeTag> flashSolver;
+    flashSolver.concentrationFlash1p2c(pseudoFluidState, Z1, pressure, presentPhaseIdx, problem().temperatureAtPos(globalPos));
 
     // write stuff in fluidstate
     assert(presentPhaseIdx == pseudoFluidState.presentPhaseIdx());
diff --git a/dumux/decoupled/2p2c/fvpressurecompositional.hh b/dumux/decoupled/2p2c/fvpressurecompositional.hh
index bb0826849ad6cf052b2bca333ad690d3027886b7..24c11c4082c83a12122e6163378f89d2b99b5f1b 100644
--- a/dumux/decoupled/2p2c/fvpressurecompositional.hh
+++ b/dumux/decoupled/2p2c/fvpressurecompositional.hh
@@ -27,6 +27,7 @@
 // dumux environment
 #include "dumux/common/math.hh"
 #include <dumux/decoupled/common/fv/fvpressure.hh>
+#include <dumux/material/constraintsolvers/compositionalflash.hh>
 #include <dumux/decoupled/2p2c/2p2cproperties.hh>
 #include <dumux/io/vtkmultiwriter.hh>
 
@@ -235,6 +236,10 @@ public:
         ScalarSolutionType *totalConcentration2 = writer.allocateManagedBuffer (size);
         ScalarSolutionType *viscosityWetting = writer.allocateManagedBuffer(size);
         ScalarSolutionType *viscosityNonwetting = writer.allocateManagedBuffer(size);
+//        ScalarSolutionType *nun = writer.allocateManagedBuffer(size);
+//        ScalarSolutionType *nuw = writer.allocateManagedBuffer(size);
+        ScalarSolutionType *faceUpwindW = writer.allocateManagedBuffer(size);
+        ScalarSolutionType *faceUpwindN = writer.allocateManagedBuffer(size);
         for (int i = 0; i < size; i++)
         {
             CellData& cellData = problem_.variables().cellData(i);
@@ -242,8 +247,25 @@ public:
             (*totalConcentration2)[i] = cellData.massConcentration(nCompIdx);
             (*viscosityWetting)[i] = cellData.viscosity(wPhaseIdx);
             (*viscosityNonwetting)[i] = cellData.viscosity(nPhaseIdx);
+//            (*nun)[i] = cellData.phaseMassFraction(nPhaseIdx);
+//            (*nuw)[i] = cellData.phaseMassFraction(wPhaseIdx);
+            (*faceUpwindW)[i] = 0;
+            (*faceUpwindN)[i] = 0;
+            // run thorugh all local face idx and collect upwind information
+            for(int faceIdx = 0; faceIdx<cellData.fluxData().size(); faceIdx++)
+            {
+                if(cellData.isUpwindCell(faceIdx, contiWEqIdx))
+                    (*faceUpwindW)[i] += pow(10,static_cast<double>(1-faceIdx));
+                if(cellData.isUpwindCell(faceIdx, contiNEqIdx))
+                    (*faceUpwindN)[i] += pow(10,static_cast<double>(1-faceIdx));
+            }
         }
+//        writer.attachCellData(*nun, "phase mass fraction n-phase");
+//        writer.attachCellData(*nuw, "phase mass fraction w-phase");
         *pressurePV = this->pressure();
+
+        writer.attachCellData(*faceUpwindW, "isUpwind w-phase");
+        writer.attachCellData(*faceUpwindN, "isUpwind n-phase");
         writer.attachCellData(*pressurePV, "pressure (Primary Variable");
         writer.attachCellData(*totalConcentration1, "C^w from cellData");
         writer.attachCellData(*totalConcentration2, "C^n from cellData");
@@ -454,6 +476,7 @@ void FVPressureCompositional<TypeTag>::initialMaterialLaws(bool compositional)
         CellData& cellData = problem_.variables().cellData(globalIdx);
         // acess the fluid state and prepare for manipulation
         FluidState& fluidState = cellData.manipulateFluidState();
+        CompositionalFlash<TypeTag> flashSolver;
 
         // initial conditions
         PhaseVector pressure(0.);
@@ -470,12 +493,13 @@ void FVPressureCompositional<TypeTag>::initialMaterialLaws(bool compositional)
             if (icFormulation == Indices::saturation)  // saturation initial condition
             {
                 sat_0 = problem_.initSat(*eIt);
-                fluidState.satFlash(sat_0, pressure, problem_.spatialParams().porosity(*eIt), temperature_);
+                flashSolver.saturationFlash2p2c(fluidState, sat_0, pressure, problem_.spatialParams().porosity(*eIt), temperature_);
             }
             else if (icFormulation == Indices::concentration) // concentration initial condition
             {
                 Scalar Z1_0 = problem_.initConcentration(*eIt);
-                fluidState.update(Z1_0, pressure, problem_.spatialParams().porosity(*eIt), temperature_);
+                flashSolver.concentrationFlash2p2c(fluidState, Z1_0, pressure,
+                        problem_.spatialParams().porosity(*eIt), temperature_);
             }
         }
         else if(compositional)    //means we regard compositional effects since we know an estimate pressure field
@@ -509,8 +533,8 @@ void FVPressureCompositional<TypeTag>::initialMaterialLaws(bool compositional)
                         break;
                     }
                 }
-
-                fluidState.satFlash(sat_0, pressure, problem_.spatialParams().porosity(*eIt), temperature_);
+                flashSolver.saturationFlash2p2c(fluidState, sat_0, pressure,
+                        problem_.spatialParams().porosity(*eIt), temperature_);
             }
             else if (icFormulation == Indices::concentration) // concentration initial condition
             {
@@ -548,8 +572,8 @@ void FVPressureCompositional<TypeTag>::initialMaterialLaws(bool compositional)
                         //store old pc
                         Scalar oldPc = pc;
                         //update with better pressures
-                        fluidState.update(Z1_0, pressure, problem_.spatialParams().porosity(*eIt),
-                                            problem_.temperatureAtPos(globalPos));
+                        flashSolver.concentrationFlash2p2c(fluidState, Z1_0, pressure,
+                                problem_.spatialParams().porosity(*eIt), problem_.temperatureAtPos(globalPos));
                         pc = MaterialLaw::pC(problem_.spatialParams().materialLawParams(*eIt),
                                             fluidState.saturation(wPhaseIdx));
                         // TODO: get right criterion, do output for evaluation
@@ -565,7 +589,8 @@ void FVPressureCompositional<TypeTag>::initialMaterialLaws(bool compositional)
                 {
                     pressure[wPhaseIdx] = pressure[nPhaseIdx]
                         = this->pressure()[globalIdx];
-                    fluidState.update(Z1_0, pressure, problem_.spatialParams().porosity(*eIt), temperature_);
+                    flashSolver.concentrationFlash2p2c(fluidState, Z1_0,
+                            pressure, problem_.spatialParams().porosity(*eIt), temperature_);
                 }
             } //end conc initial condition
             cellData.calculateMassConcentration(problem_.spatialParams().porosity(*eIt));
@@ -629,8 +654,9 @@ void FVPressureCompositional<TypeTag>::volumeDerivatives(const GlobalPosition& g
     // get cell temperature
     Scalar temperature_ = problem_.temperatureAtPos(globalPos);
 
-    // initialize an Fluid state for the update
+    // initialize an Fluid state and a flash solver
     FluidState updFluidState;
+    CompositionalFlash<TypeTag> flashSolver;
 
     /**********************************
      * a) get necessary variables
@@ -667,7 +693,6 @@ void FVPressureCompositional<TypeTag>::volumeDerivatives(const GlobalPosition& g
     }
     Scalar incp = 1e-2;
 
-
     /**********************************
      * c) Secant method for derivatives
      **********************************/
@@ -676,7 +701,7 @@ void FVPressureCompositional<TypeTag>::volumeDerivatives(const GlobalPosition& g
     PhaseVector p_(incp);
     p_ += pressure;
     Scalar Z1 = mass[0] / mass.one_norm();
-    updFluidState.update(Z1,
+    flashSolver.concentrationFlash2p2c(updFluidState, Z1,
             p_, problem_.spatialParams().porosity(element), temperature_);
 
     specificVolume=0.; // = \sum_{\alpha} \nu_{\alpha} / \rho_{\alpha}
@@ -691,7 +716,7 @@ void FVPressureCompositional<TypeTag>::volumeDerivatives(const GlobalPosition& g
         Dune::dinfo << "dv_dp larger 0 at Idx " << globalIdx << " , try and invert secant"<< std::endl;
 
         p_ -= 2*incp;
-        updFluidState.update(Z1,
+        flashSolver.concentrationFlash2p2c(updFluidState, Z1,
                     p_, problem_.spatialParams().porosity(element), temperature_);
 
         specificVolume=0.; // = \sum_{\alpha} \nu_{\alpha} / \rho_{\alpha}
@@ -711,7 +736,9 @@ void FVPressureCompositional<TypeTag>::volumeDerivatives(const GlobalPosition& g
     {
         mass[compIdx] +=  massIncrement[compIdx];
         Z1 = mass[0] / mass.one_norm();
-        updFluidState.update(Z1, pressure, problem_.spatialParams().porosity(element), temperature_);
+
+        flashSolver.concentrationFlash2p2c(updFluidState, Z1,
+                pressure, problem_.spatialParams().porosity(element), temperature_);
 
         specificVolume=0.; // = \sum_{\alpha} \nu_{\alpha} / \rho_{\alpha}
         for(int phaseIdx = 0; phaseIdx< numPhases; phaseIdx++)
diff --git a/dumux/decoupled/2p2c/fvtransport2p2c.hh b/dumux/decoupled/2p2c/fvtransport2p2c.hh
index b97ed8d9b63a34b8d46d57cf248200f5dac7f497..2e3158b60bd27bf5602176d5f1227d5c099d97eb 100644
--- a/dumux/decoupled/2p2c/fvtransport2p2c.hh
+++ b/dumux/decoupled/2p2c/fvtransport2p2c.hh
@@ -73,7 +73,7 @@ class FVTransport2P2C
 
     enum
     {
-        dim = GridView::dimension, dimWorld = GridView::dimensionworld
+        dim = GridView::dimension, dimWorld = GridView::dimensionworld,
     };
     enum
     {
@@ -86,7 +86,8 @@ class FVTransport2P2C
     {
         wPhaseIdx = Indices::wPhaseIdx, nPhaseIdx = Indices::nPhaseIdx,
         wCompIdx = Indices::wPhaseIdx, nCompIdx = Indices::nPhaseIdx,
-        contiWEqIdx=Indices::contiWEqIdx, contiNEqIdx=Indices::contiNEqIdx
+        contiWEqIdx=Indices::contiWEqIdx, contiNEqIdx=Indices::contiNEqIdx,
+        NumPhases = GET_PROP_VALUE(TypeTag, NumPhases)
     };
 
     typedef typename GridView::Traits::template Codim<0>::Entity Element;
@@ -98,7 +99,7 @@ class FVTransport2P2C
 
     typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
     typedef Dune::FieldMatrix<Scalar,dim,dim> DimMatrix;
-    typedef Dune::FieldVector<Scalar, GET_PROP_VALUE(TypeTag, NumPhases)> PhaseVector;
+    typedef Dune::FieldVector<Scalar, NumPhases> PhaseVector;
     typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
 
     //! Acess function for the current problem
@@ -173,6 +174,11 @@ public:
     //! \copydoc transportedQuantity()
     void getTransportedQuantity(TransportSolutionType& transportedQuantity)
     {
+        // resize update vector and set to zero
+        transportedQuantity.resize(GET_PROP_VALUE(TypeTag, NumComponents));
+        transportedQuantity[wCompIdx].resize(problem_.gridView().size(0));
+        transportedQuantity[nCompIdx].resize(problem_.gridView().size(0));
+
         transportedQuantity = totalConcentration_;
     }
     //! \copydoc transportedQuantity()
@@ -195,7 +201,7 @@ public:
         totalConcentration_[wCompIdx].resize(problem.gridView().size(0));
         totalConcentration_[nCompIdx].resize(problem.gridView().size(0));
 
-        restrictFluxInTransport_ = GET_PARAM_FROM_GROUP(TypeTag,bool, Impet, RestrictFluxInTransport);
+        restrictFluxInTransport_ = GET_PARAM_FROM_GROUP(TypeTag,int, Impet, RestrictFluxInTransport);
     }
 
     virtual ~FVTransport2P2C()
@@ -206,9 +212,10 @@ protected:
     TransportSolutionType totalConcentration_;
     Problem& problem_;
     bool impet_;
+    int averagedFaces_;
 
     static const int pressureType = GET_PROP_VALUE(TypeTag, PressureFormulation); //!< gives kind of pressure used (\f$ 0 = p_w \f$, \f$ 1 = p_n \f$, \f$ 2 = p_{global} \f$)
-    bool restrictFluxInTransport_;
+    int restrictFluxInTransport_;
     bool switchNormals;
 };
 
@@ -238,6 +245,7 @@ void FVTransport2P2C<TypeTag>::update(const Scalar t, Scalar& dt,
     dt = 1E100;
     // store if we do update Estimate for flux functions
     impet_ = impet;
+    averagedFaces_ = 0;
 
     // resize update vector and set to zero
     updateVec.resize(GET_PROP_VALUE(TypeTag, NumComponents));
@@ -302,7 +310,12 @@ void FVTransport2P2C<TypeTag>::update(const Scalar t, Scalar& dt,
         }
     } // end grid traversal
     if(impet)
-        Dune::dinfo << "Timestep restricted by CellIdx " << restrictingCell << " leads to dt = "<<dt * GET_PARAM_FROM_GROUP(TypeTag, Scalar, Impet, CFLFactor)<< std::endl;
+    {
+        Dune::dinfo << "Timestep restricted by CellIdx " << restrictingCell << " leads to dt = "
+                <<dt * GET_PARAM_FROM_GROUP(TypeTag, Scalar, Impet, CFLFactor)<< std::endl;
+    	if(averagedFaces_ != 0)
+            Dune::dinfo  << " Averageing done for " << averagedFaces_ << " faces. "<< std::endl;
+    }
     return;
 }
 /*	Updates the transported quantity once an update is calculated.
@@ -363,10 +376,11 @@ void FVTransport2P2C<TypeTag>::getFlux(Dune::FieldVector<Scalar, 2>& fluxEntries
     Scalar pcI = cellDataI.capillaryPressure();
     DimMatrix K_I(problem().spatialParams().intrinsicPermeability(*elementPtrI));
 
-    Scalar SwmobI = std::max((cellDataI.saturation(wPhaseIdx)
+    PhaseVector SmobI(0.);
+    SmobI[wPhaseIdx] = std::max((cellDataI.saturation(wPhaseIdx)
                             - problem().spatialParams().materialLawParams(*elementPtrI).Swr())
                             , 1e-2);
-    Scalar SnmobI = std::max((cellDataI.saturation(nPhaseIdx)
+    SmobI[nPhaseIdx] = std::max((cellDataI.saturation(nPhaseIdx)
                                 - problem().spatialParams().materialLawParams(*elementPtrI).Snr())
                             , 1e-2);
 
@@ -380,6 +394,10 @@ void FVTransport2P2C<TypeTag>::getFlux(Dune::FieldVector<Scalar, 2>& fluxEntries
         unitOuterNormal *= -1.0;
     Scalar faceArea = intersection.geometry().volume();
 
+//    // local interface index
+//    const int indexInInside = intersection.indexInInside();
+//    const int indexInOutside = intersection.indexInOutside();
+
     // create vector for timestep and for update
     Dune::FieldVector<Scalar, 2> factor (0.);
     Dune::FieldVector<Scalar, 2> updFactor (0.);
@@ -443,128 +461,101 @@ void FVTransport2P2C<TypeTag>::getFlux(Dune::FieldVector<Scalar, 2>& fluxEntries
     potential[wPhaseIdx] +=  (K * gravity_)  * (unitOuterNormal * unitDistVec) * densityW_mean;
 
     // determine upwinding direction, perform upwinding if possible
-    Dune::FieldVector<bool, GET_PROP_VALUE(TypeTag, NumPhases)> doUpwinding(true);
+    Dune::FieldVector<bool, NumPhases> doUpwinding(true);
     PhaseVector lambda(0.);
-    if(!impet_ or !restrictFluxInTransport_) // perform a simple uwpind scheme
+    for(int phaseIdx = 0; phaseIdx < NumPhases; phaseIdx++)
     {
-        if (potential[wPhaseIdx] > 0.)
-        {
-            lambda[wPhaseIdx] = cellDataI.mobility(wPhaseIdx);
-            cellDataI.setUpwindCell(intersection.indexInInside(), contiWEqIdx, true);
-
-        }
-        else if(potential[wPhaseIdx] < 0.)
-        {
-            lambda[wPhaseIdx] = cellDataJ.mobility(wPhaseIdx);
-            cellDataI.setUpwindCell(intersection.indexInInside(), contiWEqIdx, false);
-        }
+        int contiEqIdx = 0;
+        if(phaseIdx == wPhaseIdx)
+            contiEqIdx = contiWEqIdx;
         else
-        {
-            doUpwinding[wPhaseIdx] = false;
-            cellDataI.setUpwindCell(intersection.indexInInside(), contiWEqIdx, false);
-            cellDataJ.setUpwindCell(intersection.indexInOutside(), contiWEqIdx, false);
-        }
+            contiEqIdx = contiNEqIdx;
 
-        if (potential[nPhaseIdx] > 0.)
-        {
-            lambda[nPhaseIdx] = cellDataI.mobility(nPhaseIdx);
-            cellDataI.setUpwindCell(intersection.indexInInside(), contiNEqIdx, true);
-        }
-        else if (potential[nPhaseIdx] < 0.)
-        {
-            lambda[nPhaseIdx] = cellDataJ.mobility(nPhaseIdx);
-            cellDataI.setUpwindCell(intersection.indexInInside(), contiNEqIdx, false);
-        }
-        else
+        if(!impet_ or restrictFluxInTransport_==0) // perform a strict uwpind scheme
         {
-            doUpwinding[nPhaseIdx] = false;
-            cellDataI.setUpwindCell(intersection.indexInInside(), contiNEqIdx, false);
-            cellDataJ.setUpwindCell(intersection.indexInOutside(), contiNEqIdx, false);
+            if (potential[phaseIdx] > 0.)
+            {
+                lambda[phaseIdx] = cellDataI.mobility(phaseIdx);
+                cellDataI.setUpwindCell(intersection.indexInInside(), contiEqIdx, true);
+
+            }
+            else if(potential[phaseIdx] < 0.)
+            {
+                lambda[phaseIdx] = cellDataJ.mobility(phaseIdx);
+                cellDataI.setUpwindCell(intersection.indexInInside(), contiEqIdx, false);
+            }
+            else
+            {
+                doUpwinding[phaseIdx] = false;
+                cellDataI.setUpwindCell(intersection.indexInInside(), contiEqIdx, false);
+                cellDataJ.setUpwindCell(intersection.indexInOutside(), contiEqIdx, false);
+            }
         }
-    }
-    else // if new potentials indicate same flow direction as in P.E., perform upwind
-    {
-        if (potential[wPhaseIdx] >= 0. && cellDataI.isUpwindCell(intersection.indexInInside(), contiWEqIdx))
-            lambda[wPhaseIdx] = cellDataI.mobility(wPhaseIdx);
-        else if (potential[wPhaseIdx] < 0. && !cellDataI.isUpwindCell(intersection.indexInInside(), contiWEqIdx))
-            lambda[wPhaseIdx] = cellDataJ.mobility(wPhaseIdx);
-        else    // potential of w-phase does not coincide with that of P.E.
+        else // Transport after PE with check on flow direction
         {
-            bool isUpwindCell = cellDataI.isUpwindCell(intersection.indexInInside(), contiWEqIdx);
-            //check if harmonic weithing is necessary
-            if (!isUpwindCell && !(cellDataI.mobility(wPhaseIdx) != 0. && cellDataJ.mobility(wPhaseIdx) == 0.)) // check if outflow induce neglected phase flux
-                lambda[wPhaseIdx] = cellDataI.mobility(wPhaseIdx);
-            else if (isUpwindCell && !(cellDataJ.mobility(wPhaseIdx) != 0. && cellDataI.mobility(wPhaseIdx) == 0.)) // check if inflow induce neglected phase flux
-                lambda[wPhaseIdx] = cellDataJ.mobility(wPhaseIdx);
-            else
-                doUpwinding[wPhaseIdx] = false;
+            bool wasUpwindCell = cellDataI.isUpwindCell(intersection.indexInInside(), contiEqIdx);
+
+            if (potential[phaseIdx] > 0. && wasUpwindCell)
+                lambda[phaseIdx] = cellDataI.mobility(phaseIdx);
+            else if (potential[phaseIdx] < 0. && !wasUpwindCell)
+                lambda[phaseIdx] = cellDataJ.mobility(phaseIdx);
+            // potential direction does not coincide with that of P.E.
+            else if(restrictFluxInTransport_ == 2)   // perform central averageing for all direction changes
+                doUpwinding[phaseIdx] = false;
+            else    // i.e. restrictFluxInTransport == 1
+            {
+               //check if harmonic weithing is necessary
+                if (!wasUpwindCell && (cellDataJ.mobility(phaseIdx) != 0.   // check if outflow induce neglected (i.e. mob=0) phase flux
+                       or (cellDataI.wasRefined() && cellDataJ.wasRefined() && elementPtrI->father() == neighborPtr->father())))
+                    lambda[phaseIdx] = cellDataI.mobility(phaseIdx);
+                else if (wasUpwindCell && (cellDataI.mobility(phaseIdx) != 0. // check if inflow induce neglected phase flux
+                        or (cellDataI.wasRefined() && cellDataJ.wasRefined() && elementPtrI->father() == neighborPtr->father())))
+                    lambda[phaseIdx] = cellDataJ.mobility(phaseIdx);
+                else
+                    doUpwinding[phaseIdx] = false;
+            }
+
         }
 
-        if (potential[nPhaseIdx] >= 0. && cellDataI.isUpwindCell(intersection.indexInInside(), contiNEqIdx))
-            lambda[nPhaseIdx] = cellDataI.mobility(nPhaseIdx);
-        else if (potential[nPhaseIdx] < 0. && !cellDataI.isUpwindCell(intersection.indexInInside(), contiNEqIdx))
-            lambda[nPhaseIdx] = cellDataJ.mobility(nPhaseIdx);
-        else    // potential of n-phase does not coincide with that of P.E.
+        // do not perform upwinding if so desired
+        if(!doUpwinding[phaseIdx])
         {
-            bool isUpwindCell = cellDataI.isUpwindCell(intersection.indexInInside(), contiNEqIdx);
-            //check if harmonic weithing is necessary
-            if (!isUpwindCell && !(cellDataI.mobility(nPhaseIdx) != 0. && cellDataJ.mobility(nPhaseIdx) == 0.)) // check if outflow induce neglected phase flux
-                lambda[nPhaseIdx] = cellDataI.mobility(nPhaseIdx);
-            else if (isUpwindCell && !(cellDataJ.mobility(nPhaseIdx) != 0. && cellDataI.mobility(nPhaseIdx) == 0.)) // check if inflow induce neglected phase flux
-                lambda[nPhaseIdx] = cellDataJ.mobility(nPhaseIdx);
-            else
-                doUpwinding[nPhaseIdx] = false;
-        }
-    }
+            //a) no flux if there wont be any flux regardless how to average/upwind
+            if(cellDataI.mobility(phaseIdx)+cellDataJ.mobility(phaseIdx)==0.)
+            {
+                potential[phaseIdx] = 0;
+                continue;
+            }
 
-    // do not perform upwinding if so desired
-    if(!doUpwinding[wPhaseIdx])
-    {
-        //a) perform harmonic averageing
-        fluxEntries[wCompIdx] -= potential[wPhaseIdx] * faceArea / volume
-                * harmonicMean(cellDataI.massFraction(wPhaseIdx, wCompIdx) * cellDataI.mobility(wPhaseIdx) * cellDataI.density(wPhaseIdx),
-                        cellDataJ.massFraction(wPhaseIdx, wCompIdx) * cellDataJ.mobility(wPhaseIdx) * cellDataJ.density(wPhaseIdx));
-        fluxEntries[nCompIdx] -= potential[wPhaseIdx] * faceArea / volume
-                * harmonicMean(cellDataI.massFraction(wPhaseIdx, nCompIdx) * cellDataI.mobility(wPhaseIdx) * cellDataI.density(wPhaseIdx),
-                        cellDataJ.massFraction(wPhaseIdx, nCompIdx) * cellDataJ.mobility(wPhaseIdx) * cellDataJ.density(wPhaseIdx));
-        // b) timestep control
-        // for timestep control : influx
-        timestepFlux[0] += std::max(0.,
-                - potential[wPhaseIdx] * faceArea / volume * harmonicMean(cellDataI.density(wPhaseIdx),cellDataJ.density(wPhaseIdx)));
-        // outflux
-        timestepFlux[1] += std::max(0.,
-                potential[wPhaseIdx] * faceArea / volume * harmonicMean(cellDataI.density(wPhaseIdx),cellDataJ.density(wPhaseIdx)));
-
-        //c) stop further standard calculations
-        potential[wPhaseIdx] = 0;
-
-        //d) output (only for one side)
-        if(globalIdxI > globalIdxJ)
-            Dune::dinfo << "harmonicMean flux of phase w used from cell" << globalIdxI<< " into " << globalIdxJ <<"\n";
-    }
-    if(!doUpwinding[nPhaseIdx])
-    {
-        //a) perform harmonic averageing
-        fluxEntries[wCompIdx] -= potential[nPhaseIdx] * faceArea / volume
-                * harmonicMean(cellDataI.massFraction(nPhaseIdx, wCompIdx) * cellDataI.mobility(nPhaseIdx) * cellDataI.density(nPhaseIdx),
-                        cellDataJ.massFraction(nPhaseIdx, wCompIdx) * cellDataJ.mobility(nPhaseIdx) * cellDataJ.density(nPhaseIdx));
-        fluxEntries[nCompIdx] -= potential[nPhaseIdx] * faceArea / volume
-                * harmonicMean(cellDataI.massFraction(nPhaseIdx, nCompIdx) * cellDataI.mobility(nPhaseIdx) * cellDataI.density(nPhaseIdx),
-                        cellDataJ.massFraction(nPhaseIdx, nCompIdx) * cellDataJ.mobility(nPhaseIdx) * cellDataJ.density(nPhaseIdx));
-        // b) timestep control
-        // for timestep control : influx
-        timestepFlux[0] += std::max(0.,
-                - potential[nPhaseIdx] * faceArea / volume * harmonicMean(cellDataI.density(nPhaseIdx),cellDataJ.density(nPhaseIdx)));
-        // outflux
-        timestepFlux[1] += std::max(0.,
-                potential[nPhaseIdx] * faceArea / volume * harmonicMean(cellDataI.density(nPhaseIdx),cellDataJ.density(nPhaseIdx)));
-
-        //c) stop further standard calculations
-        potential[nPhaseIdx] = 0;
-
-        //d) output (only for one side)
-        if(globalIdxI > globalIdxJ)
-            Dune::dinfo << "harmonicMean flux of phase n used from cell" << globalIdxI<< " into " << globalIdxJ <<"\n";
+            //b) perform harmonic averageing
+            fluxEntries[wCompIdx] -= potential[phaseIdx] * faceArea / volume
+                    * harmonicMean(cellDataI.massFraction(phaseIdx, wCompIdx) * cellDataI.mobility(phaseIdx) * cellDataI.density(phaseIdx),
+                            cellDataJ.massFraction(phaseIdx, wCompIdx) * cellDataJ.mobility(phaseIdx) * cellDataJ.density(phaseIdx));
+            fluxEntries[nCompIdx] -= potential[phaseIdx] * faceArea / volume
+                    * harmonicMean(cellDataI.massFraction(phaseIdx, nCompIdx) * cellDataI.mobility(phaseIdx) * cellDataI.density(phaseIdx),
+                            cellDataJ.massFraction(phaseIdx, nCompIdx) * cellDataJ.mobility(phaseIdx) * cellDataJ.density(phaseIdx));
+            // c) timestep control
+            // for timestep control : influx
+            timestepFlux[0] += std::max(0.,
+                    - potential[phaseIdx] * faceArea / volume
+                      * harmonicMean(cellDataI.mobility(phaseIdx),cellDataJ.mobility(phaseIdx)));
+            // outflux
+            timestepFlux[1] += std::max(0.,
+                    potential[phaseIdx] * faceArea / volume
+                    * harmonicMean(cellDataI.mobility(phaseIdx),cellDataJ.mobility(phaseIdx))/SmobI[phaseIdx]);
+
+            //d) output (only for one side)
+            averagedFaces_++;
+            #if DUNE_MINIMAL_DEBUG_LEVEL < 3
+            // verbose (only for one side)
+            if(globalIdxI > globalIdxJ)
+                Dune::dinfo << "harmonicMean flux of phase" << phaseIdx <<" used from cell" << globalIdxI<< " into " << globalIdxJ
+                << " ; TE upwind I = "<< cellDataI.isUpwindCell(intersection.indexInInside(), contiEqIdx) << " but pot = "<< potential[phaseIdx] <<  " \n";
+            #endif
+
+            //e) stop further standard calculations
+            potential[phaseIdx] = 0;
+        }
     }
 
     // calculate and standardized velocity
@@ -576,8 +567,8 @@ void FVTransport2P2C<TypeTag>::getFlux(Dune::FieldVector<Scalar, 2>& fluxEntries
     // for timestep control : influx
     timestepFlux[0] += velocityJIw + velocityJIn;
 
-    double foutw = velocityIJw/SwmobI;
-    double foutn = velocityIJn/SnmobI;
+    double foutw = velocityIJw/SmobI[wPhaseIdx];
+    double foutn = velocityIJn/SmobI[nPhaseIdx];
     if (std::isnan(foutw) || std::isinf(foutw) || foutw < 0) foutw = 0;
     if (std::isnan(foutn) || std::isinf(foutn) || foutn < 0) foutn = 0;
     timestepFlux[1] += foutw + foutn;
@@ -825,6 +816,9 @@ void FVTransport2P2C<TypeTag>::evalBoundary(GlobalPosition globalPosFace,
                                             FluidState &BCfluidState,
                                             PhaseVector &pressBound)
 {
+    // prepare a flash solver
+    CompositionalFlash<TypeTag> flashSolver;
+
     const ElementPointer eIt= intersection.inside();
     // read boundary values
     PrimaryVariables primaryVariablesOnBoundary(0.);
@@ -859,18 +853,16 @@ void FVTransport2P2C<TypeTag>::evalBoundary(GlobalPosition globalPosFace,
         else // capillarity neglected
             pressBound[wPhaseIdx] = pressBound[nPhaseIdx] = primaryVariablesOnBoundary[Indices::pressureEqIdx];
 
-
-        BCfluidState.satFlash(satBound, pressBound, problem().spatialParams().porosity(*eIt),
-                            problem().temperatureAtPos(globalPosFace));
-
+        flashSolver.saturationFlash2p2c(BCfluidState, satBound, pressBound,
+                problem().spatialParams().porosity(*eIt), problem().temperatureAtPos(globalPosFace));
     }
     else if (bcType == Indices::concentration)
     {
         // saturation and hence pc and hence corresponding pressure unknown
         pressBound[wPhaseIdx] = pressBound[nPhaseIdx] = primaryVariablesOnBoundary[Indices::pressureEqIdx];
         Scalar Z1Bound = primaryVariablesOnBoundary[contiWEqIdx];
-        BCfluidState.update(Z1Bound, pressBound, problem().spatialParams().porosity(*eIt),
-                            problem().temperatureAtPos(globalPosFace));
+        flashSolver.concentrationFlash2p2c(BCfluidState, Z1Bound, pressBound,
+        	problem().spatialParams().porosity(*eIt), problem().temperatureAtPos(globalPosFace));
 
         if(GET_PROP_VALUE(TypeTag, EnableCapillarity))
         {
@@ -902,8 +894,8 @@ void FVTransport2P2C<TypeTag>::evalBoundary(GlobalPosition globalPosFace,
                 //store old pc
                 Scalar oldPc = pcBound;
                 //update with better pressures
-                BCfluidState.update(Z1Bound, pressBound, problem().spatialParams().porosity(*eIt),
-                                    problem().temperatureAtPos(globalPosFace));
+                flashSolver.concentrationFlash2p2c(BCfluidState, Z1Bound, pressBound,
+                        problem().spatialParams().porosity(*eIt), problem().temperatureAtPos(globalPosFace));
                 pcBound = MaterialLaw::pC(problem().spatialParams().materialLawParams(*eIt),
                         BCfluidState.saturation(wPhaseIdx));
                 // TODO: get right criterion, do output for evaluation
diff --git a/dumux/decoupled/2p2c/fvtransport2p2cmultiphysics.hh b/dumux/decoupled/2p2c/fvtransport2p2cmultiphysics.hh
index 83f1eab9be22061c4b2ad356d43e96e0fd6bbc0f..9248c32150e42093d54ec10169629fe3fb07acf5 100644
--- a/dumux/decoupled/2p2c/fvtransport2p2cmultiphysics.hh
+++ b/dumux/decoupled/2p2c/fvtransport2p2cmultiphysics.hh
@@ -135,7 +135,8 @@ void FVTransport2P2CMultiPhysics<TypeTag>::update(const Scalar t, Scalar& dt, Tr
     // initialize dt very large
     dt = 1E100;
     // store if we do update Estimate for flux functions
-    this->impet_ = impet;    
+    this->impet_ = impet;
+    this->averagedFaces_ = 0.;
     
     // resize update vector and set to zero
     updateVec.resize(GET_PROP_VALUE(TypeTag, NumComponents));
@@ -203,7 +204,11 @@ void FVTransport2P2CMultiPhysics<TypeTag>::update(const Scalar t, Scalar& dt, Tr
         }
     } // end grid traversal
     if(impet)
+    {
         Dune::dinfo << "Timestep restricted by CellIdx " << restrictingCell << " leads to dt = "<<dt * GET_PARAM_FROM_GROUP(TypeTag, Scalar, Impet, CFLFactor)<< std::endl;
+        if(this->averagedFaces_ != 0)
+            Dune::dinfo  << " Averageing done for " << this->averagedFaces_ << " faces. "<< std::endl;
+    }
     return;
 }
 }
diff --git a/dumux/decoupled/2p2c/pseudo1p2cfluidstate.hh b/dumux/decoupled/2p2c/pseudo1p2cfluidstate.hh
index 8d050b2c8d2e360eccfb53efad481418b23f6e5f..7652d6e5af7203d607f0ef167cd11498d5da7ede 100644
--- a/dumux/decoupled/2p2c/pseudo1p2cfluidstate.hh
+++ b/dumux/decoupled/2p2c/pseudo1p2cfluidstate.hh
@@ -74,49 +74,6 @@ public:
      * \param presentPhaseIdx Subdomain Index = Indication which phase is present
      * \param temperature Temperature \f$\mathrm{[K]}\f$
      */
-    void update(const Scalar& Z1,const Dune::FieldVector<Scalar, numPhases> phasePressure,const int presentPhaseIdx, const Scalar& temperature)
-    {
-        pressure_[wPhaseIdx] = phasePressure[wPhaseIdx];
-        pressure_[nPhaseIdx] = phasePressure[nPhaseIdx];
-        temperature_ = temperature;
-
-        if (presentPhaseIdx == wPhaseIdx)
-        {
-            massFractionWater_[wPhaseIdx] = Z1;
-            massFractionWater_[nPhaseIdx] = 0.;
-
-            moleFractionWater_[wPhaseIdx] = Z1 / FluidSystem::molarMass(0);
-            moleFractionWater_[wPhaseIdx] /= ( Z1 / FluidSystem::molarMass(0)
-                           + (1.-Z1) / FluidSystem::molarMass(1));
-            moleFractionWater_[nPhaseIdx] = 0.;
-
-            presentPhaseIdx_ = wPhaseIdx;
-        }
-        else if (presentPhaseIdx == nPhaseIdx)
-        {
-            massFractionWater_[wPhaseIdx] = 0.;
-            massFractionWater_[nPhaseIdx] = Z1;
-
-            // interested in nComp => 1-X1
-            moleFractionWater_[nPhaseIdx] = ( Z1 / FluidSystem::molarMass(0) );   // = moles of compIdx
-            moleFractionWater_[nPhaseIdx] /= (Z1/ FluidSystem::molarMass(0)
-                           + (1.-Z1) / FluidSystem::molarMass(1) );    // /= total moles in phase
-            moleFractionWater_[nPhaseIdx] = 0.;
-
-            presentPhaseIdx_ = nPhaseIdx;
-        }
-        else
-            Dune::dgrave << __FILE__ <<": Twophase conditions in single-phase flash!"
-                << " Z1 is "<<Z1<< std::endl;
-
-        density_ = FluidSystem::density(*this, presentPhaseIdx);
-
-        aveMoMass_ =  moleFractionWater_[presentPhaseIdx]*FluidSystem::molarMass(wCompIdx)
-        +   (1.-moleFractionWater_[presentPhaseIdx])*FluidSystem::molarMass(nCompIdx);
-
-        return;
-    }
-    //@}
     /*! \name Acess functions */
     //@{
     /*! \brief Returns the saturation of a phase.
@@ -134,10 +91,6 @@ public:
     {
         return presentPhaseIdx_;
     }
-    void setPresentPhaseIdx(int index)
-    {
-        presentPhaseIdx_ = index;
-    };
 
     /*! \brief Returns the pressure of a fluid phase \f$\mathrm{[Pa]}\f$.
      *  \param phaseIdx Index of the phase
@@ -150,7 +103,7 @@ public:
         if(phaseIdx == presentPhaseIdx_)
             return density_;
         else
-            return FluidSystem::density(*this, phaseIdx);
+            return 0.; // only required for output if phase is not present anyhow
     }
 
     /*!
@@ -160,6 +113,10 @@ public:
      */
     Scalar massFraction(int phaseIdx, int compIdx) const
     {
+        if(phaseIdx != presentPhaseIdx_)
+            return 0.;
+
+
         if (compIdx == wPhaseIdx)
             return massFractionWater_[phaseIdx];
         else
@@ -174,6 +131,8 @@ public:
      */
     Scalar moleFraction(int phaseIdx, int compIdx) const
     {
+        if(phaseIdx != presentPhaseIdx_)
+            return 0.;
         if (compIdx == wPhaseIdx)
             return moleFractionWater_[phaseIdx];
         else
@@ -190,11 +149,6 @@ public:
         assert(phaseIdx == presentPhaseIdx_);
         return viscosity_;
     }
-    void setViscosity(int phaseIdx, Scalar value)
-    {
-        assert(phaseIdx == presentPhaseIdx_);
-        viscosity_ = value;
-    }
 
     Scalar averageMolarMass(int phaseIdx) const
     {
@@ -209,7 +163,86 @@ public:
      */
     Scalar temperature(int phaseIdx) const
     { return temperature_; };
+    //@}
 
+    /*!
+     * \name Functions to set Data
+     */
+    //@{
+    /*!
+     * \brief Sets the viscosity of a phase \f$\mathrm{[Pa*s]}\f$.
+     *
+     * \param phaseIdx the index of the phase
+     * @param value Value to be stored
+     */
+    void setViscosity(int phaseIdx, Scalar value)
+    {
+        assert(phaseIdx == presentPhaseIdx_);
+        viscosity_ = value;
+    }
+    /*!
+     * \brief Sets the mass fraction of a component in a phase.
+     *
+     * \param phaseIdx the index of the phase
+     * \param compIdx the index of the component
+     * @param value Value to be stored
+     */
+    void setMassFraction(int phaseIdx, int compIdx, Scalar value)
+    {
+        if (compIdx == wCompIdx)
+            massFractionWater_[phaseIdx] = value;
+        else
+            massFractionWater_[phaseIdx] = 1- value;
+    }
+
+    /*!
+     * \brief Sets the molar fraction of a component in a fluid phase.
+     *
+     * \param phaseIdx the index of the phase
+     * \param compIdx the index of the component
+     * @param value Value to be stored
+     */
+    void setMoleFraction(int phaseIdx, int compIdx, Scalar value)
+    {
+        if (compIdx == wCompIdx)
+            moleFractionWater_[phaseIdx] = value;
+        else
+            moleFractionWater_[phaseIdx] = 1-value;
+    }
+    /*!
+     * \brief Sets the density of a phase \f$\mathrm{[kg/m^3]}\f$.
+     *
+     * \param phaseIdx the index of the phase
+     * @param value Value to be stored
+     */
+    void setDensity(int phaseIdx, Scalar value)
+    {
+        assert(phaseIdx == presentPhaseIdx_);
+        density_ = value;
+    }
+    /*!
+     * \brief Sets the phase Index that is present in this fluidState.
+     * @param phaseIdx the index of the phase
+     */
+    void setPresentPhaseIdx(int phaseIdx)
+    {
+        presentPhaseIdx_ = phaseIdx;
+    }
+
+    /*!
+     * \brief Sets the temperature
+     *
+     * @param value Value to be stored
+     */
+    void setTemperature(Scalar value)
+    {
+        temperature_ = value;
+    }
+    //TODO: doc me
+    void setAverageMolarMass(int phaseIdx, Scalar value)
+    {
+        aveMoMass_ = value;
+    }
     /*!
      * \brief Sets the phase pressure \f$\mathrm{[Pa]}\f$.
      */
diff --git a/dumux/material/constraintsolvers/compositionalflash.hh b/dumux/material/constraintsolvers/compositionalflash.hh
new file mode 100644
index 0000000000000000000000000000000000000000..dc7e6eb43b630a5253920d22476dcf0463a15cea
--- /dev/null
+++ b/dumux/material/constraintsolvers/compositionalflash.hh
@@ -0,0 +1,322 @@
+// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+// vi: set et ts=4 sw=4 sts=4:
+/*****************************************************************************
+ *   Copyright (C) 2011 by Benjamin Faigle                                   *
+ *   Institute for Modelling Hydraulic and Environmental Systems             *
+ *   University of Stuttgart, Germany                                        *
+ *   email: <givenname>.<name>@iws.uni-stuttgart.de                          *
+ *                                                                           *
+ *   This program is free software: you can redistribute it and/or modify    *
+ *   it under the terms of the GNU General Public License as published by    *
+ *   the Free Software Foundation, either version 2 of the License, or       *
+ *   (at your option) any later version.                                     *
+ *                                                                           *
+ *   This program is distributed in the hope that it will be useful,         *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
+ *   GNU General Public License for more details.                            *
+ *                                                                           *
+ *   You should have received a copy of the GNU General Public License       *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ *
+ * \brief Determines the pressures and saturations of all fluid phases
+ *        given the total mass of all components.
+ */
+#ifndef DUMUX_COMPOSITIONAL_FLASH_HH
+#define DUMUX_COMPOSITIONAL_FLASH_HH
+
+#include <dune/common/fvector.hh>
+#include <dune/common/fmatrix.hh>
+
+#include <dumux/common/exceptions.hh>
+#include <dumux/common/valgrind.hh>
+#include <dumux/decoupled/2p2c/2p2cproperties.hh>
+#include <dumux/decoupled/2p2c/2p2cfluidstate.hh>
+#include <dumux/decoupled/2p2c/pseudo1p2cfluidstate.hh>
+
+namespace Dumux
+{
+/*!
+ * \brief Flash calculation routines for compositional decoupled models
+ *
+ *        Routines for isothermal and isobaric 2p2c and 1p2c flash.
+ *  \tparam TypeTag The property Type Tag
+ */
+template <class TypeTag>
+class CompositionalFlash
+{
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar)      Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState;
+    typedef PseudoOnePTwoCFluidState<TypeTag> FluidState1p2c;
+
+    enum {  numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
+            numComponents = GET_PROP_VALUE(TypeTag, NumComponents)};
+
+    enum{
+        wPhaseIdx = FluidSystem::wPhaseIdx,
+        nPhaseIdx = FluidSystem::nPhaseIdx,
+        wCompIdx = FluidSystem::wCompIdx,
+        nCompIdx = FluidSystem::nCompIdx
+    };
+
+public:
+    typedef Dune::FieldVector<Scalar, numComponents> ComponentVector;
+    typedef Dune::FieldVector<Scalar, numPhases> PhaseVector;
+/*!
+ * \name Concentration flash for a given feed fraction
+ */
+//@{
+    //! 2p2c Flash for constant p & t if concentrations (feed mass fraction) is given.
+    /*!
+     * Routine goes as follows:
+     * - determination of the equilibrium constants from the fluid system
+     * - determination of maximum solubilities (mole fractions) according to phase pressures
+     * - comparison with Z1 to determine phase presence => phase mass fractions
+     * - round off fluid properties
+     * \param fluidState The decoupled fluid State
+     * \param Z1 Feed mass fraction: Mass of comp1 per total mass \f$\mathrm{[-]}\f$
+     * \param phasePressure Vector holding the pressure \f$\mathrm{[Pa]}\f$
+     * \param poro Porosity \f$\mathrm{[-]}\f$
+     * \param temperature Temperature \f$\mathrm{[K]}\f$
+     */
+    static void concentrationFlash2p2c(FluidState &fluidState,
+                             const Scalar &Z1,
+                             const PhaseVector &phasePressure,
+                             const Scalar &porosity,
+                             const Scalar &temperature)
+    {
+        // set the temperature, pressure
+        fluidState.setTemperature(temperature);
+        fluidState.setPressure(wPhaseIdx, phasePressure[wPhaseIdx]);
+        fluidState.setPressure(nPhaseIdx, phasePressure[nPhaseIdx]);
+
+        //mole equilibrium ratios K for in case wPhase is reference phase
+        double k1 = FluidSystem::fugacityCoefficient(fluidState, wPhaseIdx, wCompIdx);    // = p^wComp_vap
+        double k2 = FluidSystem::fugacityCoefficient(fluidState, wPhaseIdx, nCompIdx);    // = H^nComp_w
+
+        // get mole fraction from equilibrium konstants
+        fluidState.setMoleFraction(wPhaseIdx,wCompIdx, ((1. - k2) / (k1 -k2)));
+        fluidState.setMoleFraction(nPhaseIdx,wCompIdx, (fluidState.moleFraction(wPhaseIdx,wCompIdx) * k1));
+
+        // transform mole to mass fractions
+        fluidState.setMassFraction(wPhaseIdx, wCompIdx,
+                (fluidState.moleFraction(wPhaseIdx,wCompIdx) * FluidSystem::molarMass(wCompIdx)
+                / ( fluidState.moleFraction(wPhaseIdx,wCompIdx) * FluidSystem::molarMass(wCompIdx)
+                    + (1.-fluidState.moleFraction(wPhaseIdx,wCompIdx)) * FluidSystem::molarMass(nCompIdx) )));
+        fluidState.setMassFraction(nPhaseIdx,wCompIdx,
+                (fluidState.moleFraction(nPhaseIdx,wCompIdx) * FluidSystem::molarMass(wCompIdx)
+                / ( fluidState.moleFraction(nPhaseIdx,wCompIdx) * FluidSystem::molarMass(wCompIdx)
+                    + (1.-fluidState.moleFraction(nPhaseIdx,wCompIdx)) * FluidSystem::molarMass(nCompIdx) )));
+
+        //mass equilibrium ratios
+        Scalar equilRatio_[numPhases][numComponents];
+        equilRatio_[nPhaseIdx][wCompIdx] = fluidState.massFraction(nPhaseIdx,wCompIdx)
+                / fluidState.massFraction(wPhaseIdx, wCompIdx);     // = Xn1 / Xw1 = K1
+        equilRatio_[nPhaseIdx][nCompIdx] = (1.-fluidState.massFraction(nPhaseIdx, wCompIdx))
+                / (1.-fluidState.massFraction(wPhaseIdx, wCompIdx)); // =(1.-Xn1) / (1.-Xw1)     = K2
+        equilRatio_[wPhaseIdx][nCompIdx] = equilRatio_[wPhaseIdx][wCompIdx] = 1.;
+
+        // phase fraction of nPhase [mass/totalmass]
+        fluidState.setNu(nPhaseIdx, 0.);
+
+        // check if there is enough of component 1 to form a phase
+        if (Z1 > fluidState.massFraction(nPhaseIdx,wCompIdx)
+                             && Z1 < fluidState.massFraction(wPhaseIdx,wCompIdx))
+            fluidState.setNu(nPhaseIdx, -((equilRatio_[nPhaseIdx][wCompIdx]-1)*Z1 + (equilRatio_[nPhaseIdx][nCompIdx]-1)*(1-Z1))
+                                / (equilRatio_[nPhaseIdx][wCompIdx]-1) / (equilRatio_[nPhaseIdx][nCompIdx] -1));
+        else if (Z1 <= fluidState.massFraction(nPhaseIdx,wCompIdx)) // too little wComp to form a phase
+        {
+            fluidState.setNu(nPhaseIdx, 1.); // only nPhase
+            fluidState.setMassFraction(nPhaseIdx,wCompIdx, Z1); // hence, assign complete mass dissolved into nPhase
+
+            // store as moleFractions
+            Scalar xw_n = Z1 /*=Xw_n*/ / FluidSystem::molarMass(wCompIdx);  // = moles of compIdx
+            xw_n /= ( Z1 /*=Xw_n*/ / FluidSystem::molarMass(wCompIdx)
+                    +(1- Z1 /*=Xn_n*/) / FluidSystem::molarMass(nCompIdx) ); // /= total moles in phase
+
+            fluidState.setMoleFraction(nPhaseIdx,wCompIdx, xw_n);
+
+//            // opposing non-present phase is already set to equilibrium mass fraction
+//            fluidState.setMassFraction(wPhaseIdx,wCompIdx, 1.); // non present phase is set to be pure
+//            fluidState.setMoleFraction(wPhaseIdx,wCompIdx, 1.); // non present phase is set to be pure
+        }
+        else    // (Z1 >= Xw1) => no nPhase
+        {
+            fluidState.setNu(nPhaseIdx, 0.); // no second phase
+            fluidState.setMassFraction(wPhaseIdx, wCompIdx, Z1);
+
+            // store as moleFractions
+            Scalar xw_w = Z1 /*=Xw_w*/ / FluidSystem::molarMass(wCompIdx);  // = moles of compIdx
+            xw_w /= ( Z1 /*=Xw_w*/ / FluidSystem::molarMass(wCompIdx)
+                    +(1- Z1 /*=Xn_w*/) / FluidSystem::molarMass(nCompIdx) ); // /= total moles in phase
+            fluidState.setMoleFraction(wPhaseIdx, wCompIdx, xw_w);
+
+//            // opposing non-present phase is already set to equilibrium mass fraction
+//            fluidState.setMassFraction(nPhaseIdx,wCompIdx, 0.); // non present phase is set to be pure
+//            fluidState.setMoleFraction(nPhaseIdx,wCompIdx, 0.); // non present phase is set to be pure
+        }
+
+        // complete array of mass fractions
+        fluidState.setMassFraction(wPhaseIdx, nCompIdx, 1. - fluidState.massFraction(wPhaseIdx,wCompIdx));
+        fluidState.setMassFraction(nPhaseIdx, nCompIdx, 1. - fluidState.massFraction(nPhaseIdx,wCompIdx));
+        // complete array of mole fractions
+        fluidState.setMoleFraction(wPhaseIdx, nCompIdx, 1. - fluidState.moleFraction(wPhaseIdx,wCompIdx));
+        fluidState.setMoleFraction(nPhaseIdx, nCompIdx, 1. - fluidState.moleFraction(nPhaseIdx,wCompIdx));
+
+        // complete phase mass fractions
+        fluidState.setNu(wPhaseIdx, 1. - fluidState.phaseMassFraction(nPhaseIdx));
+
+        // get densities with correct composition
+        fluidState.setDensity(wPhaseIdx, FluidSystem::density(fluidState, wPhaseIdx));
+        fluidState.setDensity(nPhaseIdx, FluidSystem::density(fluidState, nPhaseIdx));
+
+        Scalar Sw = fluidState.phaseMassFraction(wPhaseIdx) / fluidState.density(wPhaseIdx);
+        Sw /= (fluidState.phaseMassFraction(wPhaseIdx)/fluidState.density(wPhaseIdx)
+                    + fluidState.phaseMassFraction(nPhaseIdx)/fluidState.density(nPhaseIdx));
+        fluidState.setSaturation(wPhaseIdx, Sw);
+    };
+
+    //! The simplest possible update routine for 1p2c "flash" calculations
+    /*!
+     * Routine goes as follows:
+     * - Check if we are in single phase condition
+     * - Assign total concentration to the present phase
+     *
+     * \param Z1 Feed mass fraction \f$\mathrm{[-]}\f$
+     * \param phasePressure Vector holding the pressure \f$\mathrm{[Pa]}\f$
+     * \param presentPhaseIdx Subdomain Index = Indication which phase is present
+     * \param temperature Temperature \f$\mathrm{[K]}\f$
+     */
+    static void concentrationFlash1p2c(FluidState1p2c& fluidState, const Scalar& Z1,const Dune::FieldVector<Scalar, numPhases> phasePressure,const int presentPhaseIdx, const Scalar& temperature)
+    {
+        // set the temperature, pressure
+        fluidState.setTemperature(temperature);
+        fluidState.setPressure(wPhaseIdx, phasePressure[wPhaseIdx]);
+        fluidState.setPressure(nPhaseIdx, phasePressure[nPhaseIdx]);
+
+        fluidState.setPresentPhaseIdx(presentPhaseIdx);
+        fluidState.setMassFraction(presentPhaseIdx,wCompIdx, Z1);
+
+        // calculate mole fraction and average molar mass
+        Scalar xw_alpha= Z1 / FluidSystem::molarMass(wCompIdx);
+        xw_alpha /= ( Z1 / FluidSystem::molarMass(wCompIdx)
+                + (1.-Z1) / FluidSystem::molarMass(nCompIdx));
+        fluidState.setMoleFraction(presentPhaseIdx, wCompIdx, xw_alpha);
+
+//        if (presentPhaseIdx == wPhaseIdx)
+//        {
+//
+////            fluidState.setMassFraction(wPhaseIdx,wCompIdx, 0.;
+//
+//
+//
+//
+//
+////            fluidState.moleFractionWater_[nPhaseIdx] = 0.;
+//
+//            fluidState.setPresentPhaseIdx(presentPhaseIdx);
+//        }
+//        else if (presentPhaseIdx == nPhaseIdx)
+//        {
+//            fluidState.setMassFraction[wPhaseIdx] = 0.;
+//            fluidState.setMassFraction[nPhaseIdx] = Z1;
+//
+//            // interested in nComp => 1-X1
+//            fluidState.moleFractionWater_[nPhaseIdx] = ( Z1 / FluidSystem::molarMass(0) );   // = moles of compIdx
+//            fluidState.moleFractionWater_[nPhaseIdx] /= (Z1/ FluidSystem::molarMass(0)
+//                           + (1.-Z1) / FluidSystem::molarMass(1) );    // /= total moles in phase
+//            fluidState.moleFractionWater_[nPhaseIdx] = 0.;
+//
+//            fluidState.presentPhaseIdx_ = nPhaseIdx;
+//        }
+//        else
+//            Dune::dgrave << __FILE__ <<": Twophase conditions in single-phase flash!"
+//                << " Z1 is "<<Z1<< std::endl;
+
+        fluidState.setAverageMolarMass(presentPhaseIdx,
+                fluidState.massFraction(presentPhaseIdx, wCompIdx)*FluidSystem::molarMass(wCompIdx)
+                +fluidState.massFraction(presentPhaseIdx, nCompIdx)*FluidSystem::molarMass(nCompIdx));
+
+        fluidState.setDensity(presentPhaseIdx, FluidSystem::density(fluidState, presentPhaseIdx));
+
+        return;
+    }
+//@}
+
+/*!
+ * \name Saturation flash for a given saturation (e.g. at boundary)
+ */
+//@{
+    //! a flash routine for 2p2c systems if the saturation instead of total concentration is known.
+    /*!
+     * Routine goes as follows:
+     * - determination of the equilibrium constants from the fluid system
+     * - determination of maximum solubilities (mole fractions) according to phase pressures
+     * - round off fluid properties
+     * \param fluidState The decoupled fluid state
+     * \param sat Saturation of phase 1 \f$\mathrm{[-]}\f$
+     * \param phasePressure Vector holding the pressure \f$\mathrm{[Pa]}\f$
+     * \param poro Porosity \f$\mathrm{[-]}\f$
+     * \param temperature Temperature \f$\mathrm{[K]}\f$
+     */
+    static void saturationFlash2p2c(FluidState &fluidState,
+            const Scalar &saturation,
+            const PhaseVector &phasePressure,
+            const Scalar &porosity,
+            const Scalar &temperature)
+    {
+        if (saturation == 0. || saturation == 1.)
+                    Dune::dinfo << "saturation initial and boundary conditions set to zero or one!"
+                        << " assuming fully saturated compositional conditions" << std::endl;
+
+        // set the temperature, pressure
+        fluidState.setTemperature(temperature);
+        fluidState.setPressure(wPhaseIdx, phasePressure[wPhaseIdx]);
+        fluidState.setPressure(nPhaseIdx, phasePressure[nPhaseIdx]);
+
+        //in contrast to the standard update() method, satflash() does not calculate nu.
+        fluidState.setNu(wPhaseIdx, NAN);
+        fluidState.setNu(nPhaseIdx, NAN);
+
+        //mole equilibrium ratios K for in case wPhase is reference phase
+        double k1 = FluidSystem::fugacityCoefficient(fluidState, wPhaseIdx, wCompIdx);    // = p^wComp_vap
+        double k2 = FluidSystem::fugacityCoefficient(fluidState, wPhaseIdx, nCompIdx);    // = H^nComp_w
+
+        // get mole fraction from equilibrium konstants
+        fluidState.setMoleFraction(wPhaseIdx,wCompIdx, ((1. - k2) / (k1 -k2)));
+        fluidState.setMoleFraction(nPhaseIdx,wCompIdx, (fluidState.moleFraction(wPhaseIdx,wCompIdx) * k1));
+
+        // transform mole to mass fractions
+        fluidState.setMassFraction(wPhaseIdx, wCompIdx,
+                (fluidState.moleFraction(wPhaseIdx,wCompIdx) * FluidSystem::molarMass(wCompIdx)
+                / ( fluidState.moleFraction(wPhaseIdx,wCompIdx) * FluidSystem::molarMass(wCompIdx)
+                    + (1.-fluidState.moleFraction(wPhaseIdx,wCompIdx)) * FluidSystem::molarMass(nCompIdx) )));
+        fluidState.setMassFraction(nPhaseIdx,wCompIdx,
+                (fluidState.moleFraction(nPhaseIdx,wCompIdx) * FluidSystem::molarMass(wCompIdx)
+                / ( fluidState.moleFraction(nPhaseIdx,wCompIdx) * FluidSystem::molarMass(wCompIdx)
+                    + (1.-fluidState.moleFraction(nPhaseIdx,wCompIdx)) * FluidSystem::molarMass(nCompIdx) )));
+
+        // complete array of mass fractions
+        fluidState.setMassFraction(wPhaseIdx, nCompIdx, 1. - fluidState.massFraction(wPhaseIdx,wCompIdx));
+        fluidState.setMassFraction(nPhaseIdx, nCompIdx, 1. - fluidState.massFraction(nPhaseIdx,wCompIdx));
+        // complete array of mole fractions
+        fluidState.setMoleFraction(wPhaseIdx, nCompIdx, 1. - fluidState.moleFraction(wPhaseIdx,wCompIdx));
+        fluidState.setMoleFraction(nPhaseIdx, nCompIdx, 1. - fluidState.moleFraction(nPhaseIdx,wCompIdx));
+
+        // get densities with correct composition
+        fluidState.setDensity(wPhaseIdx, FluidSystem::density(fluidState, wPhaseIdx));
+        fluidState.setDensity(nPhaseIdx, FluidSystem::density(fluidState, nPhaseIdx));
+
+        // set saturation
+        fluidState.setSaturation(wPhaseIdx, saturation);
+    }
+//@}
+};
+
+} // end namespace Dumux
+
+#endif