diff --git a/configure.ac b/configure.ac
index 10f0a7672db3e0365bdef068fda32dd013480701..0a331b511cc1f56e0638aecdda36958971a1ae47 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,7 +20,8 @@ AC_CONFIG_FILES([dumux.pc
     dumux/boxmodels/2p/Makefile 
     dumux/boxmodels/2p2c/Makefile 
     dumux/boxmodels/2p2cni/Makefile 
-    dumux/boxmodels/2pni/Makefile 
+    dumux/boxmodels/2pni/Makefile
+    dumux/boxmodels/2pdfm/Makefile 
     dumux/boxmodels/3p3c/Makefile 
     dumux/boxmodels/3p3cni/Makefile 
     dumux/boxmodels/common/Makefile 
diff --git a/dumux/boxmodels/2pdfm/2pdfmfluxvariables.hh b/dumux/boxmodels/2pdfm/2pdfmfluxvariables.hh
new file mode 100644
index 0000000000000000000000000000000000000000..93ca3137d6bba43107bc859f0656bdde8596549c
--- /dev/null
+++ b/dumux/boxmodels/2pdfm/2pdfmfluxvariables.hh
@@ -0,0 +1,234 @@
+/*****************************************************************************
+ *   See the file COPYING for full copying permissions.                      *
+ *                                                                           *
+ *   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 This file contains the data which is required to calculate
+ *        all fluxes of fluid phases over a face of a finite volume in the
+ *        two phase discrete fracture-matrix model.
+ */
+#ifndef DUMUX_BOXMODELS_2PDFM_FLUX_VARIABLES_HH
+#define DUMUX_BOXMODELS_2PDFM_FLUX_VARIABLES_HH
+
+#include <dumux/common/math.hh>
+#include <dumux/common/parameters.hh>
+#include <dumux/common/valgrind.hh>
+#include <dumux/boxmodels/common/boxdarcyfluxvariables.hh>
+
+#include "2pdfmproperties.hh"
+
+namespace Dumux
+{
+
+/*!
+ * \ingroup TwoPDFMBoxModel
+ * \ingroup BoxDFMFluxVariables
+ * \brief Contains the data which is required to calculate the fluxes of 
+ *        the fluid phases over a face of a finite volume for the two-phase
+ *        discrete fracture-matrix model.
+ *
+ * This means pressure and concentration gradients, phase densities at
+ * the intergration point, etc.
+ */
+template <class TypeTag>
+class TwoPDFMFluxVariables : public BoxDarcyFluxVariables<TypeTag>
+{
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
+
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+    typedef typename GridView::template Codim<0>::Entity Element;
+    enum {
+        dim = GridView::dimension,
+        dimWorld = GridView::dimensionworld,
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases)
+    };
+
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef Dune::FieldVector<Scalar, dimWorld> Vector;
+
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+    typedef typename FVElementGeometry::SubControlVolumeFace SCVFace;
+    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
+    typedef Dune::FieldVector<Scalar, dim> LocalPosition;
+    typedef Dune::FieldVector<Scalar, numPhases> PhasesVector;
+
+public:
+    /*!
+     * \brief The constructor
+     *
+     * \param problem The problem
+     * \param element The finite element
+     * \param fvGeometry The finite-volume geometry in the box scheme
+     * \param faceIdx The local index of the SCV (sub-control-volume) face
+     * \param elemVolVars The volume variables of the current element
+     * \param onBoundary A boolean variable to specify whether the flux variables
+     * are calculated for interior SCV faces or boundary faces, default=false
+     */
+    TwoPDFMFluxVariables(const Problem &problem,
+                 const Element &element,
+                 const FVElementGeometry &fvGeometry,
+                 int faceIdx,
+                 const ElementVolumeVariables &elemVolVars,
+                 const bool onBoundary = false)
+        : BoxDarcyFluxVariables<TypeTag>(problem, element, fvGeometry, faceIdx, elemVolVars, onBoundary), 
+          fvGeometry_(fvGeometry), faceIdx_(faceIdx), onBoundary_(onBoundary)
+    {
+        faceSCV_ = &this->face();
+
+        for (int phase = 0; phase < numPhases; ++phase)
+        {
+            potentialGradFracture_[phase] = 0.0;
+        }
+
+        calculateGradientsInFractures_(problem, element, elemVolVars, faceIdx);
+        calculateVelocitiesFracture_(problem, element, elemVolVars, faceIdx);
+    };
+
+public:
+    /*!
+     * \brief Calculates the velocities in the lower-dimenstional fracture.
+     * 
+     * \param problem The problem
+     * \param element The finite element
+     * \param elemVolVars The volume variables of the current element
+     * \param faceIdx The local index of the SCV (sub-control-volume) face
+     */
+    void calculateVelocitiesFracture_(const Problem &problem,
+                                      const Element &element,
+                                      const ElementVolumeVariables &elemVolVars,
+                                      int faceIdx)
+    {
+        isFracture_ = problem.spatialParams().isEdgeFracture(element, faceIdx);
+        fractureWidth_ = problem.spatialParams().fractureWidth(element, faceIdx);
+
+        Scalar KFracture, KFi, KFj; //permeabilities of the fracture
+        if (isFracture_)
+        {
+            KFi = problem.spatialParams().
+                intrinsicPermeabilityFracture(element, this->fvGeometry_, this->face().i);
+            KFj = problem.spatialParams().
+                intrinsicPermeabilityFracture(element, this->fvGeometry_, this->face().j);
+        }
+        else
+        {
+            KFi = 0;
+            KFj = 0;
+        }
+
+        KFracture = Dumux::harmonicMean(KFi, KFj);
+
+        // temporary vector for the Darcy velocity
+        Scalar vDarcyFracture = 0;
+        for (int phase=0; phase < numPhases; phase++)
+        {
+            vDarcyFracture = - (KFracture * potentialGradFracture_[phase]);
+
+            Valgrind::CheckDefined(KFracture);
+            Valgrind::CheckDefined(fractureWidth_);
+            vDarcyFracture_[phase] = (vDarcyFracture * fractureWidth_);
+            Valgrind::CheckDefined(vDarcyFracture_[phase]);
+        }
+
+        // set the upstream and downstream vertices
+        for (int phase = 0; phase < numPhases; ++phase)
+        {
+            upstreamFractureIdx[phase] = faceSCV_->i;
+            downstreamFractureIdx[phase] = faceSCV_->j;
+
+            if (vDarcyFracture_[phase] < 0)
+            {
+                std::swap(upstreamFractureIdx[phase],
+                          downstreamFractureIdx[phase]);
+            }
+        }
+    }
+
+    /*!
+     * \brief Return the pressure potential gradient in the lower dimensional fracture.
+     *
+     * \param phaseIdx The index of the fluid phase
+     */
+    const Scalar &potentialGradFracture(int phaseIdx) const
+    {
+        return potentialGradFracture_[phaseIdx];
+    }
+
+
+    PhasesVector vDarcyFracture_;
+
+    int upstreamFractureIdx[numPhases];
+    int downstreamFractureIdx[numPhases];
+protected:
+    // gradients
+    Scalar potentialGradFracture_[numPhases];
+    const FVElementGeometry &fvGeometry_;
+    int faceIdx_;
+    const bool onBoundary_;
+    bool isFracture_;
+    Scalar fractureWidth_;
+    const SCVFace *faceSCV_;
+
+private:
+    /*!
+     * \brief Calculates the gradients in the lower-dimenstional fracture.
+     * 
+     * \param problem The problem
+     * \param element The finite element
+     * \param elemVolVars The volume variables of the current element
+     * \param faceIdx The local index of the SCV (sub-control-volume) face
+     */
+    void calculateGradientsInFractures_(const Problem &problem,
+                                        const Element &element,
+                                        const ElementVolumeVariables &elemVolVars,
+                                        int faceIdx)
+    {
+        // calculate gradients, loop over adjacent vertices
+        for (int idx = 0; idx < this->fvGeometry_.numFAP; idx++)
+        {
+            int i = this->face().i;
+            int j = this->face().j;
+
+            // compute sum of pressure gradients for each phaseGlobalPosition
+            for (int phase = 0; phase < numPhases; phase++)
+            {
+                const GlobalPosition localIdx_i = element.geometry().corner(i);
+                const GlobalPosition localIdx_j = element.geometry().corner(j);
+
+                isFracture_ = problem.spatialParams().isEdgeFracture(element, faceIdx);
+
+                if (isFracture_)
+                {
+                    GlobalPosition diff_ij = localIdx_j;
+                    diff_ij -= localIdx_i;
+                    potentialGradFracture_[phase] =
+                        (elemVolVars[j].pressure(phase) - elemVolVars[i].pressure(phase))
+                        / diff_ij.two_norm();
+                }
+                else
+                {
+                    potentialGradFracture_[phase] = 0;
+                }
+            }
+        }
+    }
+};
+
+} // end namepace
+
+#endif // DUMUX_BOXMODELS_2PDFM_FLUX_VARIABLES_HH
diff --git a/dumux/boxmodels/2pdfm/2pdfmindices.hh b/dumux/boxmodels/2pdfm/2pdfmindices.hh
new file mode 100644
index 0000000000000000000000000000000000000000..6326b0508fa69ac17ec754eea8b63dffd54481a6
--- /dev/null
+++ b/dumux/boxmodels/2pdfm/2pdfmindices.hh
@@ -0,0 +1,64 @@
+/*****************************************************************************
+ *   See the file COPYING for full copying permissions.                      *
+ *                                                                           *
+ *   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 Defines the indices required for the finite volume in the
+ *        two phase discrete fracture-matrix model.
+ */
+#ifndef DUMUX_BOXMODELS_2PDFM_INDICES_HH
+#define DUMUX_BOXMODELS_2PDFM_INDICES_HH
+
+#include<dumux/boxmodels/2p/2pindices.hh>
+
+namespace Dumux
+{
+// \{
+
+/*!
+ * \ingroup TwoPDFMBoxModel
+ * \ingroup BoxIndices
+ * \brief The common indices for the \f$p_w-S_n\f$ formulation of the
+ *        isothermal two-phase discrete fracture-matrix model.
+ *
+ * \tparam TypeTag The problem type tag
+ * \tparam formulation The formulation, either pwSn or pnSw
+ * \tparam PVOffset The first index in a primary variable vector.
+ */
+template <class TypeTag, 
+          int formulation = TwoPFormulation::pwSn, 
+          int PVOffset = 0>
+struct TwoPDFMIndices : public TwoPIndices <TypeTag, formulation, PVOffset>
+{
+    // Primary variable indices
+    static const int pressureIdx = PVOffset + 0; //!< Index for wetting/non-wetting phase pressure (depending on formulation) in a solution vector
+    static const int saturationIdx = PVOffset + 1; //!< Index of the saturation of the non-wetting/wetting phase
+
+    // indices of the primary variables
+    static const int pwIdx = PVOffset + 0; //!< Pressure index of the wetting phase
+    static const int SnIdx = PVOffset + 1; //!< Saturation index of the wetting phase
+
+    // indices of the equations
+    static const int contiWEqIdx = PVOffset + 0; //!< Index of the continuity equation of the wetting phase
+    static const int contiNEqIdx = PVOffset + 1; //!< Index of the continuity equation of the non-wetting phase
+};
+
+// \}
+} // namespace Dumux
+
+#endif // DUMUX_BOXMODELS_2PDFM_INDICES_HH
diff --git a/dumux/boxmodels/2pdfm/2pdfmlocalresidual.hh b/dumux/boxmodels/2pdfm/2pdfmlocalresidual.hh
new file mode 100644
index 0000000000000000000000000000000000000000..3ab534a7b2bbc2b7514cd1fbf283f2c04f45fa04
--- /dev/null
+++ b/dumux/boxmodels/2pdfm/2pdfmlocalresidual.hh
@@ -0,0 +1,335 @@
+/*****************************************************************************
+ *   See the file COPYING for full copying permissions.                      *
+ *                                                                           *
+ *   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 Element-wise calculation of the residual for the finite volume in the
+ *        two phase discrete fracture-matrix model.
+ */
+#ifndef DUMUX_BOXMODELS_2PDFM_LOCAL_RESIDUAL_HH
+#define DUMUX_BOXMODELS_2PDFM_LOCAL_RESIDUAL_HH
+
+#include <dumux/boxmodels/2p/2plocalresidual.hh>
+#include "2pdfmproperties.hh"
+
+namespace Dumux
+{
+/*!
+ * \ingroup TwoPDFMBoxModel
+ * \ingroup BoxLocalResidual
+ * \brief Element-wise calculation of the Jacobian matrix for problems
+ *        using the two-phase discrete fracture box model.
+ */
+template<class TypeTag>
+class TwoPDFMLocalResidual : public TwoPLocalResidual<TypeTag>
+{
+protected:
+    typedef TwoPLocalResidual<TypeTag> ParentType;
+    typedef typename GET_PROP_TYPE(TypeTag, LocalResidual) Implementation;
+    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+    enum
+    {
+        contiWEqIdx = Indices::contiWEqIdx,
+        contiNEqIdx = Indices::contiNEqIdx,
+        wPhaseIdx = Indices::wPhaseIdx,
+        nPhaseIdx = Indices::nPhaseIdx,
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases)
+    };
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+    typedef Dune::UGGrid<2> GridType;
+    typedef typename GridType::ctype DT;
+    enum {
+        dim = GridView::dimension,
+        dimWorld = GridView::dimensionworld
+    };
+    typedef typename GridView::template Codim<0>::Entity Element;
+    typedef typename GridView::template Codim<0>::Iterator ElementIterator;
+    typedef typename GridView::template Codim<dim>::Entity Vertex;
+    typedef typename GridView::template Codim<dim>::Iterator VertexIterator;
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+    typedef typename FVElementGeometry::SubControlVolumeFace SCVFace;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef Dune::FieldVector<Scalar, dimWorld> Vector;
+
+    typedef Dune::FieldVector<Scalar, dim> LocalPosition;
+    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
+
+public:
+    /*!
+     * \brief Constructor. Sets the upwind weight.
+     */
+    TwoPDFMLocalResidual()
+    {
+        // retrieve the upwind weight for the mass conservation equations. Use the value
+        // specified via the property system as default, and overwrite
+        // it by the run-time parameter from the Dune::ParameterTree
+        massUpwindWeight_ = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MassUpwindWeight);
+    };
+
+    /*!
+     * \brief Evaluate the amount all conservation quantities
+     *        (e.g. phase mass) within a finite sub-control volume.
+     *
+     *  \param storage The phase mass within the sub-control volume
+     *  \param scvIdx The SCV (sub-control-volume) index
+     *  \param usePrevSol Evaluate function with solution of current or previous time step
+     */
+    void computeStorage(PrimaryVariables &storage, int scvIdx, bool usePrevSol) const
+    {
+        // if flag usePrevSol is set, the solution from the previous
+        // time step is used, otherwise the current solution is
+        // used. The secondary variables are used accordingly.  This
+        // is required to compute the derivative of the storage term
+        // using the implicit Euler method.
+        ParentType::computeStorage(storage,scvIdx,usePrevSol);
+        computeStorageFracture(storage,scvIdx,usePrevSol);
+    }
+
+    /*!
+     * \brief Evaluate the storage term of the current solution in a
+     *        lower-dimensional fracture.
+     *
+     *  \param storage The phase mass within the sub-control volume
+     *  \param scvIdx The SCV (sub-control-volume) index
+     *  \param usePrevSol Evaluate function with solution of current or previous time step
+     */
+    void computeStorageFracture(PrimaryVariables &storage, int scvIdx, bool usePrevSol) const
+    {
+        const ElementVolumeVariables &elemDat = usePrevSol ? this->prevVolVars_()
+                        : this->curVolVars_();
+        const VolumeVariables &vertDat = elemDat[scvIdx];
+        const Element &elem = this->element_();
+        bool isFracture = this->problem_().spatialParams().isVertexFracture(elem, scvIdx);
+        /*
+         * Sn = w_F * SnF + w_M * SnM
+         * First simple case before determining the real w_F is to assume that it is 0
+         * and w_M = 1
+         *
+         */
+        ///////////////////////////////////////////////////////////////////////
+        Scalar w_F, w_M; //volumetric fractions of fracture and matrix;
+        Scalar fractureVolume = 0.0;
+        w_F = 0.0;
+        /*
+         * Calculate the fracture volume fraction w_F = 0.5 * Fwidth * 0.5 * Length
+         */
+        Dune::GeometryType gt = elem.geometry().type();
+        const typename Dune::GenericReferenceElementContainer<DT,dim>::value_type&
+            refElem = Dune::GenericReferenceElements<DT,dim>::general(gt);
+
+        Scalar vol; //subcontrol volume
+        FVElementGeometry fvelem = this->fvGeometry_();
+        vol = fvelem.subContVol[scvIdx].volume;
+        for (int faceIdx=0; faceIdx<refElem.size(1); faceIdx++)
+        {
+            SCVFace face = fvelem.subContVolFace[faceIdx];
+            int i=face.i;
+            int j=face.j;
+
+            if (this->problem_().spatialParams().isEdgeFracture(elem, faceIdx)
+                    && (i == scvIdx || j == scvIdx))
+            {
+                Scalar fracture_width = this->problem_().spatialParams().fractureWidth(elem, faceIdx);
+
+                const GlobalPosition global_i = elem.geometry().corner(i);
+                const GlobalPosition global_j = elem.geometry().corner(j);
+                GlobalPosition diff_ij = global_j;
+                diff_ij -=global_i;
+                Scalar fracture_length = 0.5*diff_ij.two_norm();
+                //half is taken from the other element
+                fractureVolume += 0.5 * fracture_length * fracture_width;
+            }
+        }
+        w_F = fractureVolume/vol;
+        w_M = 1-w_F;
+        ///////////////////////////////////////////////////////////////////////
+        Scalar storageFracture[numPhases];
+        Scalar storageMatrix [numPhases];
+        storageFracture[wPhaseIdx]    = 0.0;
+        storageFracture[nPhaseIdx]    = 0.0;
+        storageMatrix[wPhaseIdx]    = 0.0;
+        storageMatrix[nPhaseIdx]    = 0.0;
+        //        const GlobalPosition &globalPos = elem.geometry().corner(scvIdx);
+
+        Scalar dSM_dSF = vertDat.dSM_dSF();
+        if (!this->problem_().useInterfaceCondition())
+        {
+            dSM_dSF = 1.0;
+        }
+
+        if (isFracture)
+        {
+            for (int phaseIdx = 0; phaseIdx<2; phaseIdx++)
+            {
+                storageFracture[phaseIdx] = vertDat.density(phaseIdx)
+                                        * vertDat.porosityFracture()
+                                        * w_F
+                                        * vertDat.saturationFracture(phaseIdx);
+                storageMatrix[phaseIdx] = vertDat.density(phaseIdx)
+                                        * vertDat.porosity()
+                                        * w_M
+                                        * dSM_dSF
+                                        * vertDat.saturationMatrix(phaseIdx);
+            }
+        }
+        else
+        {
+            for (int phaseIdx = 0; phaseIdx < 2; phaseIdx++)
+            {
+                storageFracture[phaseIdx] = 0.0;
+                storageMatrix[phaseIdx] = vertDat.density(phaseIdx)
+                                        * vertDat.porosity()
+                                        * vertDat.saturation(phaseIdx);
+            }
+
+        }
+        // wetting phase mass
+        storage[contiWEqIdx] =  storageFracture[wPhaseIdx]
+                            + storageMatrix[wPhaseIdx];
+
+        // non-wetting phase mass
+        storage[contiNEqIdx] =  storageFracture[nPhaseIdx]
+                            + storageMatrix[nPhaseIdx];
+    }
+
+    /*!
+     * \brief Evaluates the mass flux over a face of a sub-control
+     *        volume.
+     *
+     * \param flux The flux over the SCV (sub-control-volume) face for each phase
+     * \param faceIdx The index of the SCV face
+     * \param onBoundary A boolean variable to specify whether the flux variables
+     *        are calculated for interior SCV faces or boundary faces, default=false
+     */
+    void computeFlux(PrimaryVariables &flux, int faceIdx, const bool onBoundary=false) const
+    {
+        FluxVariables fluxVars(this->problem_(),
+                           this->element_(),
+                           this->fvGeometry_(),
+                           faceIdx,
+                           this->curVolVars_(),
+                           onBoundary);
+        flux = 0;
+        asImp_()->computeAdvectiveFlux(flux, fluxVars);
+        asImp_()->computeAdvectiveFluxFracture(flux, fluxVars);
+        asImp_()->computeDiffusiveFlux(flux, fluxVars);
+        asImp_()->computeDiffusiveFluxFracture(flux, fluxVars);
+    }
+
+    /*!
+     * \brief Adds the flux vector in the lower dimensional fracture to the
+     *        flux vector over the face of a sub-control volume.
+     *
+     * This method is called by compute flux and is mainly there for
+     * derived models to ease adding equations selectively.
+     *
+     * \param flux The advective flux over the sub-control-volume face for each phase
+     * \param fluxVars The flux variables at the current SCV
+     */
+    void computeAdvectiveFluxFracture(PrimaryVariables &flux, const FluxVariables &fluxVars) const
+    {
+        ////////
+        // advective fluxes of all components in all phases
+        ////////
+        Vector tmpVec;
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+        {
+            // calculate the flux in direction of the
+            // current fracture
+            //
+            // v = - (K grad p) * n
+            //
+            // (the minus comes from the Darcy law which states that
+            // the flux is from high to low pressure potentials.)
+
+            // data attached to upstream and the downstream vertices
+            // of the current phase
+            const VolumeVariables &upFracture =
+                    this->curVolVars_(fluxVars.upstreamFractureIdx[phaseIdx]);
+            const VolumeVariables &dnFracture =
+                    this->curVolVars_(fluxVars.downstreamFractureIdx[phaseIdx]);
+
+            Scalar fractureFlux =
+                          0.5 * fluxVars.vDarcyFracture_[phaseIdx]
+                              * ( massUpwindWeight_ // upstream vertex
+                                 *  (upFracture.density(phaseIdx)
+                                    * upFracture.mobilityFracture(phaseIdx))
+                                 + (1 - massUpwindWeight_) // downstream vertex
+                                    * (dnFracture.density(phaseIdx)
+                                      * dnFracture.mobilityFracture(phaseIdx)));
+
+            flux[phaseIdx] += fractureFlux;
+        }
+    }
+
+    /*!
+     * \brief Adds the diffusive flux of the fracture to the flux vector over
+     *        the face of a sub-control volume.
+     *
+     * \param flux The diffusive flux over the sub-control-volume face for each phase
+     * \param fluxData The flux variables at the current SCV
+     *
+     * It doesn't do anything in two-phase model but is used by the
+     * non-isothermal two-phase models to calculate diffusive heat
+     * fluxes
+     */
+    void computeDiffusiveFluxFracture(PrimaryVariables &flux, const FluxVariables &fluxData) const
+    {
+        // diffusive fluxes
+        flux += 0.0;
+    }
+
+    /*!
+     * \brief Calculate the source term of the equation
+     *
+     * \param source The source/sink in the SCV for each phase
+     * \param scvIdx The index of the SCV
+     *
+     */
+    void computeSource(PrimaryVariables &source, int scvIdx) const
+    {
+        // retrieve the source term intrinsic to the problem
+        this->problem_().boxSDSource(source,
+                                     this->element_(),
+                                     this->fvGeometry_(),
+                                     scvIdx,
+                                     this->curVolVars_());
+    }
+
+protected:
+    Implementation *asImp_()
+    {
+        return static_cast<Implementation *> (this);
+    }
+    const Implementation *asImp_() const
+    {
+        return static_cast<const Implementation *> (this);
+    }
+
+private:
+    Scalar massUpwindWeight_;
+};
+
+} // end namespace
+
+#endif // DUMUX_BOXMODELS_2PDFM_LOCAL_RESIDUAL_HH
diff --git a/dumux/boxmodels/2pdfm/2pdfmmodel.hh b/dumux/boxmodels/2pdfm/2pdfmmodel.hh
new file mode 100644
index 0000000000000000000000000000000000000000..07b9c92fd06861973664b4a72c5781f91a712098
--- /dev/null
+++ b/dumux/boxmodels/2pdfm/2pdfmmodel.hh
@@ -0,0 +1,390 @@
+/*****************************************************************************
+ *   See the file COPYING for full copying permissions.                      *
+ *                                                                           *
+ *   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 Adaption of the box scheme to the two-phase flow in discrete fracture-matrix 
+*        model.
+*/
+
+#ifndef DUMUX_BOXMODELS_2PDFM_MODEL_HH
+#define DUMUX_BOXMODELS_2PDFM_MODEL_HH
+
+#include <dumux/boxmodels/2p/2pmodel.hh>
+
+#include "2pdfmproperties.hh"
+#include "2pdfmlocalresidual.hh"
+#include "2pdfmproblem.hh"
+
+namespace Dumux
+{
+
+/*!
+ * \ingroup TwoPDFMBoxModel
+ * \brief A two-phase, isothermal flow model using the box scheme.
+ *
+ * This model implements two-phase flow of two immiscible fluids
+ * \f$\alpha \in \{ w, n \}\f$ using a standard multiphase Darcy
+ * approach as the equation for the conservation of momentum, i.e.
+ \f[
+ v_\alpha = - \frac{k_{r\alpha}}{\mu_\alpha} \textbf{K}
+ \left(\textbf{grad}\, p_\alpha - \varrho_{\alpha} {\textbf g} \right)
+ \f]
+ *
+ * By inserting this into the equation for the conservation of the
+ * phase mass, one gets
+ \f[
+ \phi \frac{\partial \varrho_\alpha S_\alpha}{\partial t}
+ -
+ \text{div} \left\{
+ \varrho_\alpha \frac{k_{r\alpha}}{\mu_\alpha} \mbox{\bf K} \left(\textbf{grad}\, p_\alpha - \varrho_{\alpha} \mbox{\bf g} \right)
+ \right\} - q_\alpha = 0 \;,
+ \f]
+ *
+ * These equations are discretized by a fully-coupled vertex centered finite volume
+ * (box) scheme as spatial and the implicit Euler method as time
+ * discretization.
+ *
+ * By using constitutive relations for the capillary pressure \f$p_c =
+ * p_n - p_w\f$ and relative permeability \f$k_{r\alpha}\f$ and taking
+ * advantage of the fact that \f$S_w + S_n = 1\f$, the number of
+ * unknowns can be reduced to two. Currently the model supports
+ * choosing either \f$p_w\f$ and \f$S_n\f$ or \f$p_n\f$ and \f$S_w\f$
+ * as primary variables. The formulation which ought to be used can be
+ * specified by setting the <tt>Formulation</tt> property to either
+ * <tt>TwoPCommonIndices::pWsN</tt> or <tt>TwoPCommonIndices::pNsW</tt>. By
+ * default, the model uses \f$p_w\f$ and \f$S_n\f$.
+ */
+template<class TypeTag >
+class TwoPDFMModel : public TwoPModel<TypeTag>
+{
+    typedef TwoPModel<TypeTag> ParentType;
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
+    typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+    enum {
+        nPhaseIdx = Indices::nPhaseIdx,
+        wPhaseIdx = Indices::wPhaseIdx,
+        pressureIdx = Indices::pressureIdx,
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases)
+    };
+
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+    typedef typename GridView::template Codim<0>::Entity Element;
+    typedef typename GridView::template Codim<0>::Iterator ElementIterator;
+    typedef typename GridView::ctype CoordScalar;
+    enum {
+        dim = GridView::dimension,
+        dimWorld = GridView::dimensionworld
+    };
+
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef Dune::FieldVector<Scalar, numPhases> PhasesVector;
+    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
+
+public:
+    /*!
+     * \brief Returns the relative weight of a primary variable for
+     *        calculating relative errors.
+     *
+     * \param globalIdx The global index of the vertex
+     * \param pvIdx The index of the primary variable
+     */
+    DUNE_DEPRECATED
+    Scalar primaryVarWeight(int globalIdx, int pvIdx) const
+    {
+        if (pressureIdx == pvIdx)
+        {
+            return std::min(10.0 / this->prevSol()[globalIdx][pvIdx], 1.0);
+        }
+        
+        return 1.0;
+    }
+
+    /*!
+     * \brief Append all quantities of interest which can be derived
+     *        from the solution of the current time step to the VTK
+     *        writer.
+     *
+     * \param sol The global solution vector
+     * \param writer The writer for multi-file VTK datasets
+     */
+    template<class MultiWriter>
+    void addOutputVtkFields(const SolutionVector &sol, MultiWriter &writer)
+    {
+        bool velocityOutput = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddVelocity);
+        typedef Dune::BlockVector<Dune::FieldVector<double, 1> > ScalarField;
+        typedef Dune::BlockVector<Dune::FieldVector<double, dim> > VectorField;
+
+        // get the number of degrees of freedom and the number of vertices
+        unsigned numDofs = this->numDofs();
+        unsigned numVertices = this->problem_().gridView().size(dim);
+    
+        // velocity output currently only works for vertex data
+        if (numDofs != numVertices)
+        {
+            velocityOutput = false;
+        }
+    
+        // create the required scalar fields
+        ScalarField *pW = writer.allocateManagedBuffer(numDofs);
+        ScalarField *pN = writer.allocateManagedBuffer(numDofs);
+        ScalarField *pC = writer.allocateManagedBuffer(numDofs);
+        ScalarField *Sw = writer.allocateManagedBuffer(numDofs);
+        ScalarField *Sn = writer.allocateManagedBuffer(numDofs);
+        ScalarField *rhoW = writer.allocateManagedBuffer(numDofs);
+        ScalarField *rhoN = writer.allocateManagedBuffer(numDofs);
+        ScalarField *mobW = writer.allocateManagedBuffer(numDofs);
+        ScalarField *mobN = writer.allocateManagedBuffer(numDofs);
+        ScalarField *poro = writer.allocateManagedBuffer(numDofs);
+        ScalarField *Te = writer.allocateManagedBuffer(numDofs);
+        ScalarField *cellNum =writer.allocateManagedBuffer (numDofs);
+        VectorField *velocityN = writer.template allocateManagedBuffer<double, dim>(numDofs);
+        VectorField *velocityW = writer.template allocateManagedBuffer<double, dim>(numDofs);
+
+        if(velocityOutput) // check if velocity output is demanded
+        {
+            // initialize velocity fields
+            for (unsigned int i = 0; i < numVertices; ++i)
+            {
+                (*velocityN)[i] = Scalar(0);
+                (*velocityW)[i] = Scalar(0);
+                (*cellNum)[i] = Scalar(0.0);
+            }
+        }
+        unsigned numElements = this->gridView_().size(0);
+        ScalarField *rank = writer.allocateManagedBuffer(numElements);
+
+        FVElementGeometry fvGeometry;
+        VolumeVariables volVars;
+        ElementVolumeVariables elemVolVars;
+
+        ElementIterator elemIt = this->gridView_().template begin<0>();
+        ElementIterator elemEndIt = this->gridView_().template end<0>();
+        for (; elemIt != elemEndIt; ++elemIt)
+        {
+            if(velocityOutput && !elemIt->geometry().type().isCube()){
+                DUNE_THROW(Dune::InvalidStateException,
+                           "Currently, velocity output only works for cubes. "
+                           "Please set the EnableVelocityOutput property to false!");
+            }
+            int idx = this->elementMapper().map(*elemIt);
+            (*rank)[idx] = this->gridView_().comm().rank();
+
+            fvGeometry.update(this->gridView_(), *elemIt);
+
+            if (numDofs == numElements) // element data
+            {
+                volVars.update(sol[idx],
+                               this->problem_(),
+                               *elemIt,
+                               fvGeometry,
+                               /*scvIdx=*/0,
+                               false);
+
+                (*pW)[idx] = volVars.pressure(wPhaseIdx);
+                (*pN)[idx] = volVars.pressure(nPhaseIdx);
+                (*pC)[idx] = volVars.capillaryPressure();
+                (*Sw)[idx] = volVars.saturation(wPhaseIdx);
+                (*Sn)[idx] = volVars.saturation(nPhaseIdx);
+                (*rhoW)[idx] = volVars.density(wPhaseIdx);
+                (*rhoN)[idx] = volVars.density(nPhaseIdx);
+                (*mobW)[idx] = volVars.mobility(wPhaseIdx);
+                (*mobN)[idx] = volVars.mobility(nPhaseIdx);
+                (*poro)[idx] = volVars.porosity();
+                (*Te)[idx] = volVars.temperature();
+            }
+            else // vertex data
+            {
+                int numVerts = elemIt->template count<dim> ();
+                for (int scvIdx = 0; scvIdx < numVerts; ++scvIdx)
+                {
+                    int globalIdx = this->vertexMapper().map(*elemIt, scvIdx, dim);
+                    volVars.update(sol[globalIdx],
+                                   this->problem_(),
+                                   *elemIt,
+                                   fvGeometry,
+                                   scvIdx,
+                                   false);
+
+                    (*pW)[globalIdx] = volVars.pressure(wPhaseIdx);
+                    (*pN)[globalIdx] = volVars.pressure(nPhaseIdx);
+                    (*pC)[globalIdx] = volVars.capillaryPressure();
+                    (*Sw)[globalIdx] = volVars.saturation(wPhaseIdx);
+                    (*Sn)[globalIdx] = volVars.saturation(nPhaseIdx);
+                    (*rhoW)[globalIdx] = volVars.density(wPhaseIdx);
+                    (*rhoN)[globalIdx] = volVars.density(nPhaseIdx);
+                    (*mobW)[globalIdx] = volVars.mobility(wPhaseIdx);
+                    (*mobN)[globalIdx] = volVars.mobility(nPhaseIdx);
+                    (*poro)[globalIdx] = volVars.porosity();
+                    (*Te)[globalIdx] = volVars.temperature();
+                    if(velocityOutput)
+                    {
+                        (*cellNum)[globalIdx] += 1;
+                    }
+                }
+
+                if(velocityOutput)
+                {
+                    // calculate vertex velocities
+                    GlobalPosition tmpVelocity[numPhases];
+
+                    for(int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+                    {
+                        tmpVelocity[phaseIdx]  = Scalar(0.0);
+                    }
+
+                    typedef Dune::BlockVector<Dune::FieldVector<Scalar, dim> > SCVVelocities;
+                    SCVVelocities scvVelocityW(8), scvVelocityN(8);
+
+                    scvVelocityW = 0;
+                    scvVelocityN = 0;
+
+                    ElementVolumeVariables elemVolVars;
+
+                    elemVolVars.update(this->problem_(),
+                                       *elemIt,
+                                       fvGeometry,
+                                       false /* oldSol? */);
+
+                    for (int faceIdx = 0; faceIdx < fvGeometry.numEdges; faceIdx++)
+                    {
+                        FluxVariables fluxVars(this->problem_(),
+                                             *elemIt,
+                                             fvGeometry,
+                                             faceIdx,
+                                             elemVolVars);
+
+                        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+                        {
+                            // local position of integration point
+                            const Dune::FieldVector<Scalar, dim>& localPosIP = fvGeometry.subContVolFace[faceIdx].ipLocal;
+
+                            // Transformation of the global normal vector to normal vector in the reference element
+                            const typename Element::Geometry::JacobianTransposed& jacobianT1 = 
+                                elemIt->geometry().jacobianTransposed(localPosIP);
+
+                            const GlobalPosition globalNormal = fluxVars.face().normal;
+                            GlobalPosition localNormal;
+                            jacobianT1.mv(globalNormal, localNormal);
+                            // note only works for cubes
+                            const Scalar localArea = pow(2,-(dim-1));
+
+                            localNormal /= localNormal.two_norm();
+
+                            // Get the Darcy velocities. The Darcy velocities are divided by the area of the subcontrolvolumeface
+                            // in the reference element.
+                            PhasesVector q;
+                            q[phaseIdx] = fluxVars.volumeFlux(phaseIdx) / localArea;
+
+                            // transform the normal Darcy velocity into a vector
+                            tmpVelocity[phaseIdx] = localNormal;
+                            tmpVelocity[phaseIdx] *= q[phaseIdx];
+
+                            if(phaseIdx == wPhaseIdx)
+                            {
+                                scvVelocityW[fluxVars.face().i] += tmpVelocity[phaseIdx];
+                                scvVelocityW[fluxVars.face().j] += tmpVelocity[phaseIdx];
+                            }
+                            else if(phaseIdx == nPhaseIdx)
+                            {
+                                scvVelocityN[fluxVars.face().i] += tmpVelocity[phaseIdx];
+                                scvVelocityN[fluxVars.face().j] += tmpVelocity[phaseIdx];
+                            }
+                        }
+                    }
+                    typedef Dune::GenericReferenceElements<Scalar, dim> ReferenceElements;
+                    const Dune::FieldVector<Scalar, dim> &localPos
+                        = ReferenceElements::general(elemIt->geometry().type()).position(0, 0);
+
+                    // get the transposed Jacobian of the element mapping
+                    const typename Element::Geometry::JacobianTransposed& jacobianT2
+                        = elemIt->geometry().jacobianTransposed(localPos);
+
+                    // transform vertex velocities from local to global coordinates
+                    for (int i = 0; i < numVerts; ++i)
+                    {
+                        int globalIdx = this->vertexMapper().map(*elemIt, i, dim);
+                        // calculate the subcontrolvolume velocity by the Piola transformation
+                        Dune::FieldVector<CoordScalar, dim> scvVelocity(0);
+
+                        jacobianT2.mtv(scvVelocityW[i], scvVelocity);
+                        scvVelocity /= elemIt->geometry().integrationElement(localPos);
+                        // add up the wetting phase subcontrolvolume velocities for each vertex
+                        (*velocityW)[globalIdx] += scvVelocity;
+
+                        jacobianT2.mtv(scvVelocityN[i], scvVelocity);
+                        scvVelocity /= elemIt->geometry().integrationElement(localPos);
+                        // add up the nonwetting phase subcontrolvolume velocities for each vertex
+                        (*velocityN)[globalIdx] += scvVelocity;
+                    }
+                }
+            }
+        }
+
+        if (numDofs == numElements) // element data
+        {
+            writer.attachCellData(*Sn, "Sn");
+            writer.attachCellData(*Sw, "Sw");
+            writer.attachCellData(*pN, "pn");
+            writer.attachCellData(*pW, "pw");
+            writer.attachCellData(*pC, "pc");
+            writer.attachCellData(*rhoW, "rhoW");
+            writer.attachCellData(*rhoN, "rhoN");
+            writer.attachCellData(*mobW, "mobW");
+            writer.attachCellData(*mobN, "mobN");
+            writer.attachCellData(*poro, "porosity");
+            writer.attachCellData(*Te, "temperature");
+        }
+        else // vertex data
+        {
+            writer.attachVertexData(*Sn, "Sn");
+            writer.attachVertexData(*Sw, "Sw");
+            writer.attachVertexData(*pN, "pn");
+            writer.attachVertexData(*pW, "pw");
+            writer.attachVertexData(*pC, "pc");
+            writer.attachVertexData(*rhoW, "rhoW");
+            writer.attachVertexData(*rhoN, "rhoN");
+            writer.attachVertexData(*mobW, "mobW");
+            writer.attachVertexData(*mobN, "mobN");
+            writer.attachVertexData(*poro, "porosity");
+            writer.attachVertexData(*Te, "temperature");
+            if(velocityOutput) // check if velocity output is demanded
+            {
+                // divide the vertex velocities by the number of adjacent scvs i.e. cells
+                for(unsigned int globalIdx = 0; globalIdx < numVertices; ++globalIdx)
+                {
+                    (*velocityW)[globalIdx] /= (*cellNum)[globalIdx];
+                    (*velocityN)[globalIdx] /= (*cellNum)[globalIdx];
+                }
+                writer.attachVertexData(*velocityW,  "velocityW", dim);
+                writer.attachVertexData(*velocityN,  "velocityN", dim);
+            }
+        }
+        writer.attachCellData(*rank, "process rank");
+    }
+};
+} // end namespace
+
+#include "2pdfmpropertydefaults.hh"
+
+#endif // DUMUX_BOXMODELS_2PDFM_MODEL_HH
diff --git a/dumux/boxmodels/2pdfm/2pdfmproblem.hh b/dumux/boxmodels/2pdfm/2pdfmproblem.hh
new file mode 100644
index 0000000000000000000000000000000000000000..fd65e2b68dd2fc9909b991d4f7b4631367888dc1
--- /dev/null
+++ b/dumux/boxmodels/2pdfm/2pdfmproblem.hh
@@ -0,0 +1,79 @@
+/*****************************************************************************
+ *   See the file COPYING for full copying permissions.                      *
+ *                                                                           *
+ *   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 Base class for all problems which use the two-phase DFM box model
+ */
+#ifndef DUMUX_BOXMODELS_2PDFM_PROBLEM_HH
+#define DUMUX_BOXMODELS_2PDFM_PROBLEM_HH
+
+#include <dumux/boxmodels/common/porousmediaboxproblem.hh>
+#include "2pdfmproperties.hh"
+
+namespace Dumux
+{
+/*!
+ * \ingroup BoxBaseProblems
+ * \ingroup TwoPBoxModel
+ * \brief Base class for all problems which use the two-phase box model
+ */
+template<class TypeTag>
+class TwoPDFMProblem : public PorousMediaBoxProblem<TypeTag>
+{
+    typedef PorousMediaBoxProblem<TypeTag> ParentType;
+
+    typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager;
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+    typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams;
+
+public:
+    /*!
+     * \brief The constructor
+     *
+     * \param timeManager The time manager
+     * \param gridView The grid view
+     * \param verbose Turn verbosity on or off
+     */
+    DUNE_DEPRECATED_MSG("use PorousMediaBoxProblem instead")
+    TwoPDFMProblem(TimeManager &timeManager,
+                const GridView &gridView,
+                bool verbose = true)
+        : ParentType(timeManager, gridView)
+    {}
+
+    /*!
+     * \brief The constructor
+     *
+     * \param timeManager The time manager
+     * \param gridView The grid view
+     * \param spatialParams The spatial parameters object
+     * \param verbose Turn verbosity on or off
+     */
+    TwoPDFMProblem(TimeManager &timeManager,
+                const GridView &gridView,
+                SpatialParams &spatialParams,
+                bool verbose = true)
+        : ParentType(timeManager, gridView)
+    {
+        this->newSpatialParams_ = false;
+    delete this->spatialParams_;
+    this->spatialParams_ = &spatialParams;
+    }
+};
+} // end namespace
+
+#endif // DUMUX_BOXMODELS_2PDFM_PROBLEM_HH
diff --git a/dumux/boxmodels/2pdfm/2pdfmproperties.hh b/dumux/boxmodels/2pdfm/2pdfmproperties.hh
new file mode 100644
index 0000000000000000000000000000000000000000..7d0d2631e056a07bd93b21f6ee3b1d5c4637b3be
--- /dev/null
+++ b/dumux/boxmodels/2pdfm/2pdfmproperties.hh
@@ -0,0 +1,69 @@
+/*****************************************************************************
+ *   See the file COPYING for full copying permissions.                      *
+ *                                                                           *
+ *   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 Defines the properties required for the two phase DFM BOX model.
+ * 
+ * \ingroup Properties
+ * \ingroup BoxProperties
+ * \ingroup TwoPDFMBoxModel
+ */
+
+#ifndef DUMUX_BOXMODELS_2PDFM_PROPERTIES_HH
+#define DUMUX_BOXMODELS_2PDFM_PROPERTIES_HH
+
+#include <dumux/boxmodels/common/boxproperties.hh>
+
+namespace Dumux
+{
+
+////////////////////////////////
+// properties
+////////////////////////////////
+namespace Properties
+{
+
+//////////////////////////////////////////////////////////////////
+// Type tags
+//////////////////////////////////////////////////////////////////
+
+//! The type tag for 2pDFM problems
+NEW_TYPE_TAG(BoxTwoPDFM, INHERITS_FROM(BoxModel));
+
+//////////////////////////////////////////////////////////////////
+// Property tags
+//////////////////////////////////////////////////////////////////
+
+NEW_PROP_TAG(NumPhases);   //!< Number of fluid phases in the system
+NEW_PROP_TAG(ProblemEnableGravity); //!< Returns whether gravity is considered in the problem
+NEW_PROP_TAG(ImplicitMassUpwindWeight); //!< The value of the weight of the upwind direction in the mass conservation equations
+NEW_PROP_TAG(ImplicitMobilityUpwindWeight); //!< Weight for the upwind mobility in the velocity calculation
+NEW_PROP_TAG(Formulation);   //!< The formulation of the model
+NEW_PROP_TAG(TwoPDFMIndices); //!< Enumerations for the 2pDFM models
+NEW_PROP_TAG(SpatialParams); //!< The type of the spatial parameters
+NEW_PROP_TAG(MaterialLaw);   //!< The material law which ought to be used (extracted from the spatial parameters)
+NEW_PROP_TAG(MaterialLawParams); //!< The context material law (extracted from the spatial parameters)
+NEW_PROP_TAG(WettingPhase); //!< The wetting phase for two-phase models
+NEW_PROP_TAG(NonwettingPhase); //!< The non-wetting phase for two-phase models
+NEW_PROP_TAG(FluidSystem); //!<The fluid systems including the information about the phases
+NEW_PROP_TAG(FluidState); //!<The phases state
+NEW_PROP_TAG(VtkAddVelocity); //!< Returns whether velocity vectors are written into the vtk output
+} // end namespace Properties
+} // end namespace Dumux
+
+#endif // DUMUX_BOXMODELS_2PDFM_PROPERTIES_HH
diff --git a/dumux/boxmodels/2pdfm/2pdfmpropertydefaults.hh b/dumux/boxmodels/2pdfm/2pdfmpropertydefaults.hh
new file mode 100644
index 0000000000000000000000000000000000000000..84121c23b0f4ed368d4a5e8b78a18fde2697976c
--- /dev/null
+++ b/dumux/boxmodels/2pdfm/2pdfmpropertydefaults.hh
@@ -0,0 +1,144 @@
+/*****************************************************************************
+ *   See the file COPYING for full copying permissions.                      *
+ *                                                                           *
+ *   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 Defines default values for the properties required by the
+ *        2pDFM box model.
+ * 
+ * \ingroup Properties
+ * \ingroup TwoPDFMBoxModel
+ * \ingroup BoxProperties
+ */
+#ifndef DUMUX_BOXMODELS_2PDFM_PROPERTY_DEFAULTS_HH
+#define DUMUX_BOXMODELS_2PDFM_PROPERTY_DEFAULTS_HH
+
+#include <dumux/boxmodels/common/boxdarcyfluxvariables.hh>
+#include <dumux/material/components/nullcomponent.hh>
+#include <dumux/material/fluidstates/immisciblefluidstate.hh>
+#include <dumux/material/fluidsystems/2pimmisciblefluidsystem.hh>
+#include <dumux/material/fluidsystems/gasphase.hh>
+#include <dumux/material/fluidsystems/liquidphase.hh>
+#include <dumux/material/spatialparams/boxspatialparams.hh>
+
+#include "2pdfmmodel.hh"
+#include "2pdfmproblem.hh"
+#include "2pdfmindices.hh"
+#include "2pdfmfluxvariables.hh"
+#include "2pdfmvolumevariables.hh"
+#include "2pdfmproperties.hh"
+
+namespace Dumux
+{
+namespace Properties
+{
+//////////////////////////////////////////////////////////////////
+// Property defaults
+//////////////////////////////////////////////////////////////////
+SET_INT_PROP(BoxTwoPDFM, NumEq, 2); //!< set the number of equations to 2
+SET_INT_PROP(BoxTwoPDFM, NumPhases, 2); //!< The number of phases in the 2p model is 2
+
+//! Set the default formulation to pWsN
+SET_INT_PROP(BoxTwoPDFM,
+             Formulation,
+             TwoPFormulation::pwSn);
+
+//! Use the 2p local jacobian operator for the 2p model
+SET_TYPE_PROP(BoxTwoPDFM,
+              LocalResidual,
+              TwoPDFMLocalResidual<TypeTag>);
+
+//! the Model property
+SET_TYPE_PROP(BoxTwoPDFM, Model, TwoPDFMModel<TypeTag>);
+
+//! the VolumeVariables property
+SET_TYPE_PROP(BoxTwoPDFM, VolumeVariables, TwoPDFMVolumeVariables<TypeTag>);
+
+//! the FluxVariables property
+SET_TYPE_PROP(BoxTwoPDFM, FluxVariables, TwoPDFMFluxVariables<TypeTag>);
+
+//! the upwind weight for the mass conservation equations.
+SET_SCALAR_PROP(BoxTwoPDFM, ImplicitMassUpwindWeight, 1.0);
+
+//! weight for the upwind mobility in the velocity calculation
+SET_SCALAR_PROP(BoxTwoPDFM, ImplicitMobilityUpwindWeight, 1.0);
+
+//! The indices required by the isothermal 2pDFM model
+SET_PROP(BoxTwoPDFM, Indices)
+{ private:
+    enum { Formulation = GET_PROP_VALUE(TypeTag, Formulation) };
+ public:
+    typedef TwoPDFMIndices<TypeTag, Formulation, 0> type;
+};
+
+
+//! The spatial parameters to be employed.
+//! Use BoxSpatialParams by default.
+SET_TYPE_PROP(BoxTwoPDFM, SpatialParams, BoxSpatialParams<TypeTag>);
+
+/*!
+ * \brief Set the property for the material parameters by extracting
+ *        it from the material law.
+ */
+SET_TYPE_PROP(BoxTwoPDFM,
+              MaterialLawParams,
+              typename GET_PROP_TYPE(TypeTag, MaterialLaw)::Params);
+
+SET_PROP(BoxTwoPDFM, WettingPhase)
+{ private:
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+public:
+    typedef Dumux::LiquidPhase<Scalar, Dumux::NullComponent<Scalar> > type;
+};
+
+SET_PROP(BoxTwoPDFM, NonwettingPhase)
+{ private:
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+public:
+    typedef Dumux::LiquidPhase<Scalar, Dumux::NullComponent<Scalar> > type;
+};
+
+SET_PROP(BoxTwoPDFM, FluidSystem)
+{ private:
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, WettingPhase) WettingPhase;
+    typedef typename GET_PROP_TYPE(TypeTag, NonwettingPhase) NonwettingPhase;
+
+public:
+    typedef Dumux::FluidSystems::TwoPImmiscible<Scalar,
+                                                WettingPhase,
+                                                NonwettingPhase> type;
+};
+
+SET_PROP(BoxTwoPDFM, FluidState)
+{
+private:
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+public:
+    typedef ImmiscibleFluidState<Scalar, FluidSystem> type;
+};
+
+// disable velocity output by default
+SET_BOOL_PROP(BoxTwoPDFM, VtkAddVelocity, false);
+
+// enable gravity by default
+SET_BOOL_PROP(BoxTwoPDFM, ProblemEnableGravity, true);
+} // end namespace Properties
+} // end namespace Dumux
+
+#endif // DUMUX_BOXMODELS_2PDFM_PROPERTY_DEFAULTS_HH
diff --git a/dumux/boxmodels/2pdfm/2pdfmvolumevariables.hh b/dumux/boxmodels/2pdfm/2pdfmvolumevariables.hh
new file mode 100644
index 0000000000000000000000000000000000000000..c49cce37b57b620697c56ae13bcdf399bce212ef
--- /dev/null
+++ b/dumux/boxmodels/2pdfm/2pdfmvolumevariables.hh
@@ -0,0 +1,385 @@
+/*****************************************************************************
+ *   See the file COPYING for full copying permissions.                      *
+ *                                                                           *
+ *   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 Contains the quantities which are constant within a
+ *        finite volume in the two-phase discrete fracture-matrix model.
+ */
+#ifndef DUMUX_BOXMODELS_2PDFM_VOLUME_VARIABLES_HH
+#define DUMUX_BOXMODELS_2PDFM_VOLUME_VARIABLES_HH
+
+#include <dune/common/fvector.hh>
+
+#include <dumux/boxmodels/2p/2pvolumevariables.hh>
+
+#include "2pdfmproperties.hh"
+
+namespace Dumux
+{
+/*!
+ * \ingroup TwoPDFMBoxModel
+ * \ingroup BoxVolumeVariables
+ * \brief Contains the quantities which are are constant within a
+ *        finite volume in the two-phase discrete fracture-matrix model.
+ */
+template <class TypeTag>
+class TwoPDFMVolumeVariables : public TwoPVolumeVariables<TypeTag>
+{
+    typedef TwoPVolumeVariables<TypeTag> ParentType;
+
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) Implementation;
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState;
+    typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw;
+    typedef typename GET_PROP_TYPE(TypeTag, MaterialLawParams) MaterialLawParams;
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
+    typedef typename FVElementGeometry::SubControlVolumeFace SCVFace;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+    enum {
+        pwSn = Indices::pwSn,
+        pnSw = Indices::pnSw,
+        pressureIdx = Indices::pressureIdx,
+        saturationIdx = Indices::saturationIdx,
+        wPhaseIdx = Indices::wPhaseIdx,
+        nPhaseIdx = Indices::nPhaseIdx,
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
+        formulation = GET_PROP_VALUE(TypeTag, Formulation)
+    };
+
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+    typedef typename GridView::template Codim<0>::Entity Element;
+    typedef Dune::UGGrid<2> GridType;
+    typedef typename GridType::ctype DT;
+    enum {
+            dim = GridView::dimension,
+            dimWorld = GridView::dimensionworld
+    };
+    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
+    typedef Dune::FieldVector<Scalar, dim> LocalPosition;
+
+public:
+    /*!
+     * \copydoc BoxVolumeVariables::update
+     */
+    void update(const PrimaryVariables &priVars,
+                const Problem &problem,
+                const Element &element,
+                const FVElementGeometry &fvGeometry,
+                int scvIdx,
+                bool oldSol)
+    {
+        ParentType::update(priVars,
+                           problem,
+                           element,
+                           fvGeometry,
+                           scvIdx,
+                           oldSol);
+
+        this->completeFluidState(priVars, problem, element, fvGeometry, scvIdx, fluidState_);
+
+        const MaterialLawParams &materialParams =
+            problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx);
+
+        mobilityMatrix_[wPhaseIdx] =
+            MaterialLaw::krw(materialParams, fluidState_.saturation(wPhaseIdx))
+            / fluidState_.viscosity(wPhaseIdx);
+
+        mobilityMatrix_[nPhaseIdx] =
+            MaterialLaw::krn(materialParams, fluidState_.saturation(wPhaseIdx))
+            / fluidState_.viscosity(nPhaseIdx);
+
+        // porosity
+        porosityMatrix_ = problem.spatialParams().porosity(element, fvGeometry, scvIdx);
+
+        // energy related quantities not belonging to the fluid state
+        asImp_().updateEnergy_(priVars, problem, element, fvGeometry, scvIdx, oldSol);
+        asImp_().updateFracture(priVars, problem, element, fvGeometry, scvIdx, oldSol);
+    }
+
+    /*!
+     * \brief Construct the volume variables for all fracture vertices.
+     *
+     * \param priVars Primary variables.
+     * \param problem The problem which needs to be simulated.
+     * \param element The DUNE Codim<0> entity for which the volume variables ought to be calculated
+     * \param fvGeometry The finite volume geometry of the element
+     * \param oldSol Tells whether the model's previous or current solution should be used.
+     */
+    void updateFracture(const PrimaryVariables &priVars,
+                        const Problem &problem,
+                        const Element &element,
+                        const FVElementGeometry &fvGeometry,
+                        int scvIdx,
+                        bool oldSol)
+    {
+        PrimaryVariables varsFracture;
+        const MaterialLawParams &materialParamsMatrix =
+                    problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx);
+        Scalar pressure[numPhases];
+        Scalar pMatrix[numPhases];
+        Scalar pFract[numPhases];
+
+        satNMatrix_  = priVars[saturationIdx];
+        satWMatrix_  = 1.0 - satNMatrix_;
+        satN_ = satNMatrix_;
+        satW_ = satWMatrix_;
+
+        pCMatrix_ = MaterialLaw::pC(materialParamsMatrix, satWMatrix_);
+        pC_ = pCMatrix_;
+        //pressures
+        pMatrix[wPhaseIdx] = priVars[pressureIdx];
+        pMatrix[nPhaseIdx] = pMatrix[wPhaseIdx] + pCMatrix_;
+        //Initialize pFract with the same values as the ones in the matrix
+        pFract[wPhaseIdx] = pMatrix[wPhaseIdx];
+        pFract[nPhaseIdx] = satNMatrix_;
+
+        varsFracture[pressureIdx] = pFract[wPhaseIdx];
+        varsFracture[saturationIdx] = pFract[wPhaseIdx];
+
+        this->completeFluidState(priVars, problem, element, fvGeometry, scvIdx, fluidStateFracture_);
+
+        //Checks if the node is on a fracture
+        isNodeOnFracture_ = problem.spatialParams().isVertexFracture(element, scvIdx);
+
+        ///////////////////////////////////////////////////////////////////////////////
+        if (isNodeOnFracture_)
+        {
+            const MaterialLawParams &materialParamsFracture =
+                    problem.spatialParams().materialLawParamsFracture(element, fvGeometry, scvIdx);
+
+            satNFracture_ = priVars[saturationIdx];
+            satWFracture_ = 1 - satNFracture_;
+            pCFracture_ = MaterialLaw::pC(materialParamsFracture, satWFracture_);
+            pFract[wPhaseIdx] = priVars[pressureIdx];
+            pFract[nPhaseIdx] = pFract[wPhaseIdx] + pCFracture_;
+            pEntryMatrix_ = MaterialLaw::pC(materialParamsMatrix, 1);
+
+            //use interface condition - extended capillary pressure inteface condition
+            if (problem.useInterfaceCondition())
+            {
+                interfaceCondition(materialParamsMatrix);
+            }
+            pC_ = pCFracture_;
+            satW_ = satWFracture_; //for plotting we are interested in the saturations of the fracture
+            satN_ = satNFracture_;
+            mobilityFracture_[wPhaseIdx] =
+                    MaterialLaw::krw(materialParamsFracture, fluidStateFracture_.saturation(wPhaseIdx))
+                    / fluidStateFracture_.viscosity(wPhaseIdx);
+
+            mobilityFracture_[nPhaseIdx] =
+                    MaterialLaw::krn(materialParamsFracture, fluidStateFracture_.saturation(wPhaseIdx))
+                        / fluidStateFracture_.viscosity(nPhaseIdx);
+
+            // derivative resulted from BrooksCorey pc_Sw formulation
+            dSM_dSF_ = (1 - problem.spatialParams().SwrM_) / (1 - problem.spatialParams().SwrF_)
+                    * pow((problem.spatialParams().pdM_/ problem.spatialParams().pdF_),problem.spatialParams().lambdaM_)
+                    * (problem.spatialParams().lambdaM_ / problem.spatialParams().lambdaF_)
+                    * pow((satWFracture_ - problem.spatialParams().SwrF_ ) / (1 - problem.spatialParams().SwrF_),
+                            (problem.spatialParams().lambdaM_ / problem.spatialParams().lambdaF_) - 1);
+        }// end if (node)
+        ///////////////////////////////////////////////////////////////////////////////
+        else
+        {
+            /* the values of pressure and saturation of the fractures in the volumes where
+                there are no fracture are set unphysical*/
+            satNFracture_ = -1;
+            satWFracture_ = -1;
+            pCFracture_ = -1e100;
+            pFract[wPhaseIdx] = -1e100;
+            pFract[nPhaseIdx] = -1e100;
+            pEntryMatrix_ = -1e100;
+            mobilityFracture_[wPhaseIdx] = 0.0;
+            mobilityFracture_[nPhaseIdx] = 0.0;
+        }
+        ///////////////////////////////////////////////////////////////////////////////
+        pressure[wPhaseIdx] = priVars[pressureIdx];
+        pressure[nPhaseIdx] = pressure[wPhaseIdx] + pC_;
+
+        porosityFracture_ = problem.spatialParams().porosityFracture(element,
+                                                                  fvGeometry,
+                                                                  scvIdx);
+    }
+
+    /*!
+     * \brief Extended capillary pressure saturation interface condition
+     *
+     * \param materialParamsMatrix the material law o calculate the Sw as inverse of capillary pressure function
+     *
+     * This method is called by updateFracture
+     */
+    void interfaceCondition(const MaterialLawParams &materialParamsMatrix)
+    {
+        /*2nd condition Niessner, J., R. Helmig, H. Jakobs, and J.E. Roberts. 2005, eq.10
+        * if the capillary pressure in the fracture is smaller than the entry pressure
+        * in the matrix than in the matrix
+        * */
+        if (pCFracture_ <= pEntryMatrix_)
+        {
+            satWMatrix_ = 1.0;
+            satNMatrix_ = 1 - satWMatrix_;
+        }
+        //3rd condition Niessner, J., R. Helmig, H. Jakobs, and J.E. Roberts. 2005, eq.10
+        else
+        {
+            /*
+             * Inverse capillary pressure function SwM = pcM^(-1)(pcF(SwF))
+             */
+            satWMatrix_ = MaterialLaw::Sw(materialParamsMatrix, pCFracture_);
+            satNMatrix_ = 1 - satWMatrix_;
+        }
+    }
+
+    /*!
+     * \brief Calculates the volume of the fracture inside the SCV
+     */
+    Scalar calculateSCVFractureVolume ( const Problem &problem,
+                                        const Element &element,
+                                        const FVElementGeometry &fvGeometry,
+                                        int scvIdx)
+    {
+        Scalar volSCVFracture;
+        Dune::GeometryType gt = element.geometry().type();
+        const typename Dune::GenericReferenceElementContainer<DT,dim>::value_type&
+            refElem = Dune::GenericReferenceElements<DT,dim>::general(gt);
+
+        for (int faceIdx=0; faceIdx<refElem.size(1); faceIdx++)
+        {
+            SCVFace face = fvGeometry.subContVolFace[faceIdx];
+            int i=face.i;
+            int j=face.j;
+
+            if (problem.spatialParams().isEdgeFracture(element, faceIdx)
+                && (i == scvIdx || j == scvIdx))
+            {
+                Scalar fracture_width = problem.spatialParams().fractureWidth();
+
+                const GlobalPosition global_i = element.geometry().corner(i);
+                const GlobalPosition global_j = element.geometry().corner(j);
+                GlobalPosition diff_ij = global_j;
+                diff_ij -=global_i;
+                //fracture length in the subcontrol volume is half d_ij
+                Scalar fracture_length = 0.5*diff_ij.two_norm();
+
+                volSCVFracture += 0.5 * fracture_length * fracture_width;
+            }
+        }
+        return volSCVFracture;
+    }
+
+    /*!
+     * \brief Returns the effective saturation fracture of a given phase within
+     *        the control volume.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar saturationFracture(int phaseIdx) const
+    {
+        if (phaseIdx == wPhaseIdx)
+            return satWFracture_;
+        else
+            return satNFracture_;
+    }
+    Scalar saturationMatrix(int phaseIdx) const
+    {
+         if (phaseIdx == wPhaseIdx)
+             return satWMatrix_;
+         else
+             return satNMatrix_;
+    }
+
+    /*!
+     * \brief Returns the effective mobility of a given phase within
+     *        the control volume.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar mobility(int phaseIdx) const
+    { return mobilityMatrix_[phaseIdx]; }
+
+    /*!
+     * \brief Returns the effective mobility of a given phase within
+     *        the control volume.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar mobilityFracture(int phaseIdx) const
+    { return mobilityFracture_[phaseIdx]; }
+
+    /*!
+     * \brief Returns the average porosity within the matrix control volume.
+     */
+    Scalar porosity() const
+    { return porosityMatrix_; }
+
+    /*!
+     * \brief Returns the average porosity within the fracture.
+     */
+    Scalar porosityFracture() const
+    { return porosityFracture_; }
+
+    /*!
+     * \brief Returns the average permeability within the fracture.
+     */
+    Scalar permeabilityFracture() const
+    { return permeabilityFracture_; }
+
+    /*!
+     * \brief Returns the derivative dSM/dSF
+     */
+    Scalar dSM_dSF() const
+    { return dSM_dSF_;}
+
+protected:
+    FluidState fluidState_;
+    FluidState fluidStateFracture_;
+    Scalar porosityMatrix_;
+    Scalar porosityFracture_;
+    Scalar permeability_;
+    Scalar permeabilityFracture_;
+    Scalar mobilityMatrix_[numPhases];
+    Scalar mobilityFracture_[numPhases];
+
+    Scalar satW_;
+    Scalar satWFracture_;
+    Scalar satWMatrix_;
+    Scalar satN_;
+    Scalar satNFracture_;
+    Scalar satNMatrix_;
+
+    Scalar pC_;
+    Scalar pCFracture_;
+    Scalar pCMatrix_;
+    Scalar pEntryMatrix_;
+    Scalar dSM_dSF_;
+
+    bool isNodeOnFracture_;
+
+private:
+    Implementation &asImp_()
+    { return *static_cast<Implementation*>(this); }
+
+    const Implementation &asImp_() const
+    { return *static_cast<const Implementation*>(this); }
+};
+} // end namespace
+
+#endif // DUMUX_BOXMODELS_2PDFM_VOLUME_VARIABLES_HH
diff --git a/dumux/boxmodels/2pdfm/Makefile.am b/dumux/boxmodels/2pdfm/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..117f16d6c2746e5d5f135c87626218ceadc23ba3
--- /dev/null
+++ b/dumux/boxmodels/2pdfm/Makefile.am
@@ -0,0 +1,4 @@
+2pdfmdir = $(includedir)/dumux/boxmodels/2pdfm
+2pdfm_HEADERS = *.hh
+
+include $(top_srcdir)/am/global-rules
diff --git a/dumux/boxmodels/Makefile.am b/dumux/boxmodels/Makefile.am
index eff7632454eb4a45a3797935a710d2ffefac5e94..0c3d2aaeab649b08a9cec100892c48f7fc0b7b5f 100644
--- a/dumux/boxmodels/Makefile.am
+++ b/dumux/boxmodels/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = common co2 co2ni 1p 1p2c 2p 2p2c 2p2cni 2pni 3p3c 3p3cni mpnc richards
+SUBDIRS = common co2 co2ni 1p 1p2c 2p 2p2c 2p2cni 2pni 2pdfm 3p3c 3p3cni mpnc richards
 
 boxmodelsdir = $(includedir)/dumux/boxmodels