diff --git a/Applications/ApplicationsLib/ProjectData.cpp b/Applications/ApplicationsLib/ProjectData.cpp
index 34f2d5a6588cee3a23762c7fa58100865f0ed970..d494bdec19bd28494d9f2c071b1cb6c4410c9763 100644
--- a/Applications/ApplicationsLib/ProjectData.cpp
+++ b/Applications/ApplicationsLib/ProjectData.cpp
@@ -42,6 +42,7 @@
 #include "ProcessLib/LIE/HydroMechanics/CreateHydroMechanicsProcess.h"
 #include "ProcessLib/LIE/SmallDeformation/CreateSmallDeformationProcess.h"
 #include "ProcessLib/LiquidFlow/CreateLiquidFlowProcess.h"
+#include "ProcessLib/PhaseField/CreatePhaseFieldProcess.h"
 #include "ProcessLib/RichardsFlow/CreateRichardsFlowProcess.h"
 #include "ProcessLib/SmallDeformation/CreateSmallDeformationProcess.h"
 #include "ProcessLib/TES/CreateTESProcess.h"
@@ -399,6 +400,26 @@ void ProjectData::parseProcesses(BaseLib::ConfigTree const& processes_config,
                     _process_variables, _parameters, integration_order,
                     process_config);
         }
+        else if (type == "PHASE_FIELD")
+        {
+            switch (_mesh_vec[0]->getDimension())
+            {
+                case 2:
+                    process =
+                        ProcessLib::PhaseField::createPhaseFieldProcess<
+                            2>(*_mesh_vec[0], std::move(jacobian_assembler),
+                               _process_variables, _parameters,
+                               integration_order, process_config);
+                    break;
+                case 3:
+                    process =
+                        ProcessLib::PhaseField::createPhaseFieldProcess<
+                            3>(*_mesh_vec[0], std::move(jacobian_assembler),
+                               _process_variables, _parameters,
+                               integration_order, process_config);
+                    break;
+            }
+        }
         else if (type == "SMALL_DEFORMATION")
         {
             switch (_mesh_vec[0]->getDimension())
diff --git a/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/c_PHASE_FIELD.md b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/c_PHASE_FIELD.md
new file mode 100644
index 0000000000000000000000000000000000000000..47f149e88d320fea48a74ea181e7c64b468290be
--- /dev/null
+++ b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/c_PHASE_FIELD.md
@@ -0,0 +1 @@
+Phase-field modelling for brittle fracture. It is implemented monolithically.
\ No newline at end of file
diff --git a/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/constitutive_relation/i_constitutive_relation.md b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/constitutive_relation/i_constitutive_relation.md
new file mode 100644
index 0000000000000000000000000000000000000000..4a2457d3f4c6929e8670842215d3ab145424d306
--- /dev/null
+++ b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/constitutive_relation/i_constitutive_relation.md
@@ -0,0 +1 @@
+The constitutive relation for the brittle fracture.
\ No newline at end of file
diff --git a/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/constitutive_relation/t_type.md b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/constitutive_relation/t_type.md
new file mode 100644
index 0000000000000000000000000000000000000000..c66714fc4af7a6a2e11c293f1bc98e75a4c7c09c
--- /dev/null
+++ b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/constitutive_relation/t_type.md
@@ -0,0 +1,2 @@
+The type of constitutive relation available.
+1. Linear elastic
\ No newline at end of file
diff --git a/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/phasefield_parameters/i_phasefield_parameters.md b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/phasefield_parameters/i_phasefield_parameters.md
new file mode 100644
index 0000000000000000000000000000000000000000..fa401a8b3df36ff3689832b1cc7abf33053f5c53
--- /dev/null
+++ b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/phasefield_parameters/i_phasefield_parameters.md
@@ -0,0 +1 @@
+A tag for phase-field parameters.
diff --git a/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/phasefield_parameters/t_crack_length_scale.md b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/phasefield_parameters/t_crack_length_scale.md
new file mode 100644
index 0000000000000000000000000000000000000000..2d624ad71c95f7e22d0fdda55333d60442394328
--- /dev/null
+++ b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/phasefield_parameters/t_crack_length_scale.md
@@ -0,0 +1 @@
+A length-scale parameter which controls the regularisation.
\ No newline at end of file
diff --git a/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/phasefield_parameters/t_crack_resistance.md b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/phasefield_parameters/t_crack_resistance.md
new file mode 100644
index 0000000000000000000000000000000000000000..29068c95b59e62700e3d5634c3c05e80ecd9717a
--- /dev/null
+++ b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/phasefield_parameters/t_crack_resistance.md
@@ -0,0 +1 @@
+The critical Griffith-type fracture energy.
\ No newline at end of file
diff --git a/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/phasefield_parameters/t_history_field.md b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/phasefield_parameters/t_history_field.md
new file mode 100644
index 0000000000000000000000000000000000000000..f90cb95d6a2d87cafe3c8fab042027fc716ad5eb
--- /dev/null
+++ b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/phasefield_parameters/t_history_field.md
@@ -0,0 +1 @@
+A damage-driving history field which is associated with the maximum local tensile strain energy.
\ No newline at end of file
diff --git a/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/phasefield_parameters/t_kinetic_coefficient.md b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/phasefield_parameters/t_kinetic_coefficient.md
new file mode 100644
index 0000000000000000000000000000000000000000..ad80c785d41859db77470c3594581fd9f8a370bf
--- /dev/null
+++ b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/phasefield_parameters/t_kinetic_coefficient.md
@@ -0,0 +1 @@
+A kinetic coefficient which is defined to address rate-dependent cases.
\ No newline at end of file
diff --git a/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/phasefield_parameters/t_residual_stiffness.md b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/phasefield_parameters/t_residual_stiffness.md
new file mode 100644
index 0000000000000000000000000000000000000000..33a233ac922b2cd95aeed1c9212997e2e63e6ebd
--- /dev/null
+++ b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/phasefield_parameters/t_residual_stiffness.md
@@ -0,0 +1 @@
+A residual stiffness which is used in numerical calculations.
diff --git a/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/process_variables/i_process_variables.md b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/process_variables/i_process_variables.md
new file mode 100644
index 0000000000000000000000000000000000000000..949045cf3b383e6fb962472086e6c261e08383df
--- /dev/null
+++ b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/process_variables/i_process_variables.md
@@ -0,0 +1 @@
+The process variables for displacement and phasefield.
diff --git a/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/process_variables/t_displacement.md b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/process_variables/t_displacement.md
new file mode 100644
index 0000000000000000000000000000000000000000..b6e0f53b6b056cb721efd2ffa7ddfed60a5c5731
--- /dev/null
+++ b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/process_variables/t_displacement.md
@@ -0,0 +1 @@
+Process variable name of displacement.
diff --git a/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/process_variables/t_phasefield.md b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/process_variables/t_phasefield.md
new file mode 100644
index 0000000000000000000000000000000000000000..cc5910921a5d5735b3fba88c729016ec67738aaa
--- /dev/null
+++ b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/process_variables/t_phasefield.md
@@ -0,0 +1 @@
+Process variable name of phasefield.
diff --git a/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/t_solid_density.md b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/t_solid_density.md
new file mode 100644
index 0000000000000000000000000000000000000000..54bbc62fe6cba8cce1195247a1c7339cde00233d
--- /dev/null
+++ b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/t_solid_density.md
@@ -0,0 +1 @@
+Reference solid density.
\ No newline at end of file
diff --git a/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/t_specific_body_force.md b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/t_specific_body_force.md
new file mode 100644
index 0000000000000000000000000000000000000000..dd77e37995b3f3628c82ccd1f99f6315167028f8
--- /dev/null
+++ b/Documentation/ProjectFile/prj/processes/process/PHASE_FIELD/t_specific_body_force.md
@@ -0,0 +1 @@
+Specific body forces that are used to apply gravitational forces. A vector of displacement dimension's length.
diff --git a/MaterialLib/SolidModels/LinearElasticIsotropic.h b/MaterialLib/SolidModels/LinearElasticIsotropic.h
index afa40e8a627d4172b060c6e5d61aa43ced82e16d..23cadbab63990e2c82b3f30ec229a87f1ce891f2 100644
--- a/MaterialLib/SolidModels/LinearElasticIsotropic.h
+++ b/MaterialLib/SolidModels/LinearElasticIsotropic.h
@@ -17,7 +17,7 @@ namespace MaterialLib
 namespace Solids
 {
 template <int DisplacementDim>
-class LinearElasticIsotropic final : public MechanicsBase<DisplacementDim>
+class LinearElasticIsotropic : public MechanicsBase<DisplacementDim>
 {
 public:
     /// Variables specific to the material model
@@ -47,6 +47,13 @@ public:
                    (2 * (1 + _poissons_ratio(t, x)[0]));
         }
 
+        /// the bulk modulus.
+        double bulk_modulus(double const t, X const& x) const
+        {
+            return _youngs_modulus(t, x)[0] /
+                   (3 * (1 - 2 * _poissons_ratio(t, x)[0]));
+        }
+
     private:
         P const& _youngs_modulus;
         P const& _poissons_ratio;
@@ -101,7 +108,9 @@ public:
         typename MechanicsBase<DisplacementDim>::MaterialStateVariables const&
             material_state_variables) override;
 
-private:
+    MaterialProperties getMaterialProperties() {return _mp;}
+
+protected:
     MaterialProperties _mp;
 };
 
diff --git a/MaterialLib/SolidModels/LinearElasticIsotropicPhaseField.cpp b/MaterialLib/SolidModels/LinearElasticIsotropicPhaseField.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e46fa45017a46097940740d8f3040700d73bb44a
--- /dev/null
+++ b/MaterialLib/SolidModels/LinearElasticIsotropicPhaseField.cpp
@@ -0,0 +1,21 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2017, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#include "LinearElasticIsotropicPhaseField.h"
+
+namespace MaterialLib
+{
+namespace Solids
+{
+
+template class LinearElasticIsotropicPhaseField<2>;
+template class LinearElasticIsotropicPhaseField<3>;
+
+}   // namespace Solids
+}   // namespace MaterialLib
diff --git a/MaterialLib/SolidModels/LinearElasticIsotropicPhaseField.h b/MaterialLib/SolidModels/LinearElasticIsotropicPhaseField.h
new file mode 100644
index 0000000000000000000000000000000000000000..1a5eeaf141d53b7c445321b2cfe2abbf6c314a76
--- /dev/null
+++ b/MaterialLib/SolidModels/LinearElasticIsotropicPhaseField.h
@@ -0,0 +1,135 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2017, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#pragma once
+
+#include "PhaseFieldExtension.h"
+#include "LinearElasticIsotropic.h"
+#include "KelvinVector.h"
+
+namespace MaterialLib
+{
+namespace Solids
+{
+template <int DisplacementDim>
+class LinearElasticIsotropicPhaseField final
+    : public LinearElasticIsotropic<DisplacementDim>,
+      public PhaseFieldExtension<DisplacementDim>
+{
+public:
+    static int const KelvinVectorSize =
+        ProcessLib::KelvinVectorDimensions<DisplacementDim>::value;
+    using KelvinVector = ProcessLib::KelvinVectorType<DisplacementDim>;
+    using KelvinMatrix = ProcessLib::KelvinMatrixType<DisplacementDim>;
+
+    explicit LinearElasticIsotropicPhaseField(
+        typename LinearElasticIsotropic<
+            DisplacementDim>::MaterialProperties&& material_properties)
+        : LinearElasticIsotropic<DisplacementDim>(std::move(material_properties))
+    {
+    }
+
+    std::unique_ptr<
+        typename MechanicsBase<DisplacementDim>::MaterialStateVariables>
+    createMaterialStateVariables() override
+    {
+        return LinearElasticIsotropic<
+            DisplacementDim>::createMaterialStateVariables();
+    }
+
+    boost::optional<std::tuple<KelvinVector,
+                               std::unique_ptr<typename MechanicsBase<
+                                   DisplacementDim>::MaterialStateVariables>,
+                               KelvinMatrix>>
+    integrateStress(
+        double const t,
+        ProcessLib::SpatialPosition const& x,
+        double const dt,
+        KelvinVector const& eps_prev,
+        KelvinVector const& eps,
+        KelvinVector const& sigma_prev,
+        typename MechanicsBase<DisplacementDim>::MaterialStateVariables const&
+            material_state_variables) override
+    {
+        return LinearElasticIsotropic<DisplacementDim>::
+                        integrateStress(t,
+                                        x,
+                                        dt,
+                                        eps_prev,
+                                        eps,
+                                        sigma_prev,
+                                        material_state_variables);
+    }
+
+    /** Decompose the stiffness into tensile and compressive part.
+     * Judging by the physical observations, compression perpendicular
+     * to a crack does not cause crack propagation. Thus,
+     * the phase-field parameter is only involved into the tensile part
+     * to degrade the elastic strain energy.
+     */
+    bool calculateDegradedStress(double const t,
+                         ProcessLib::SpatialPosition const& x,
+                         KelvinVector const& eps,
+                         double& strain_energy_tensile,
+                         KelvinVector& sigma_tensile,
+                         KelvinVector& sigma_compressive,
+                         KelvinMatrix& C_tensile,
+                         KelvinMatrix& C_compressive,
+                         KelvinVector& sigma_real,
+                         double const degradation) const override
+    {
+        using Invariants =
+            MaterialLib::SolidModels::Invariants<KelvinVectorSize>;
+        // calculation of deviatoric parts
+        auto const& P_dev = Invariants::deviatoric_projection;
+        KelvinVector const epsd_curr = P_dev * eps;
+
+        // Hydrostatic part for the stress and the tangent.
+        double const eps_curr_trace = Invariants::trace(eps);
+
+        auto const& K =
+            LinearElasticIsotropic<DisplacementDim>::_mp.bulk_modulus(t, x);
+        auto const& mu =
+            LinearElasticIsotropic<DisplacementDim>::_mp.mu(t, x);
+
+        C_tensile = KelvinMatrix::Zero();
+        C_compressive = KelvinMatrix::Zero();
+
+        if (eps_curr_trace >= 0)
+        {
+            strain_energy_tensile =
+                 K / 2 * eps_curr_trace * eps_curr_trace +
+                 mu * epsd_curr.transpose() * epsd_curr;
+            sigma_tensile.noalias() =
+                 K * eps_curr_trace * Invariants::identity2 +
+                 2 * mu * epsd_curr;
+            sigma_compressive.noalias() = KelvinVector::Zero();
+            C_tensile.template topLeftCorner<3, 3>().setConstant(K);
+            C_tensile.noalias() += 2 * mu * P_dev * KelvinMatrix::Identity();
+        }
+        else
+        {
+            strain_energy_tensile = mu * epsd_curr.transpose() * epsd_curr;
+            sigma_tensile.noalias() = 2 * mu * epsd_curr;
+            sigma_compressive.noalias() =
+                 K * eps_curr_trace * Invariants::identity2;
+            C_tensile.noalias() = 2 * mu * P_dev * KelvinMatrix::Identity();
+            C_compressive.template topLeftCorner<3, 3>().setConstant(K);
+        }
+
+        sigma_real.noalias() = degradation * sigma_tensile + sigma_compressive;
+        return true;
+    }
+};
+
+extern template class LinearElasticIsotropicPhaseField<2>;
+extern template class LinearElasticIsotropicPhaseField<3>;
+
+}  // namespace Solids
+}  // namespace MaterialLib
diff --git a/MaterialLib/SolidModels/PhaseFieldExtension.h b/MaterialLib/SolidModels/PhaseFieldExtension.h
new file mode 100644
index 0000000000000000000000000000000000000000..77bb5a40027cce13779cbe2b1d985bf125916288
--- /dev/null
+++ b/MaterialLib/SolidModels/PhaseFieldExtension.h
@@ -0,0 +1,89 @@
+/**
+ * \file
+ * \copyright
+ * Copyright (c) 2012-2017, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#pragma once
+
+#include "ProcessLib/Deformation/BMatrixPolicy.h"
+#include "ProcessLib/Parameter/SpatialPosition.h"
+#include "MechanicsBase.h"
+
+namespace MaterialLib
+{
+namespace Solids
+{
+
+template <int DisplacementDim>
+struct PhaseFieldExtension : public MechanicsBase<DisplacementDim>
+{
+    using KelvinVector = ProcessLib::KelvinVectorType<DisplacementDim>;
+    using KelvinMatrix = ProcessLib::KelvinMatrixType<DisplacementDim>;
+    virtual bool calculateDegradedStress(double const t,
+                                 ProcessLib::SpatialPosition const& x,
+                                 KelvinVector const& eps,
+                                 double& strain_energy_tensile,
+                                 KelvinVector& sigma_tensile,
+                                 KelvinVector& sigma_compressive,
+                                 KelvinMatrix& C_tensile,
+                                 KelvinMatrix& C_compressive,
+                                 KelvinVector& sigma_real,
+                                 double const degradation) const = 0;
+
+    /// Dynamic size Kelvin vector and matrix wrapper for the polymorphic
+    /// constitutive relation compute function.
+    bool calculateDegradedStress(
+        double const t,
+        ProcessLib::SpatialPosition const& x,
+        Eigen::Matrix<double, Eigen::Dynamic, 1> const& eps,
+        double& strain_energy_tensile,
+        Eigen::Matrix<double, Eigen::Dynamic, 1>& sigma_tensile,
+        Eigen::Matrix<double, Eigen::Dynamic, 1>& sigma_compressive,
+        Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>&
+            C_tensile,
+        Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>&
+            C_compressive,
+        Eigen::Matrix<double, Eigen::Dynamic, 1>& sigma_real,
+        double const degradation) const
+    {
+        // TODO Avoid copies of data:
+        // Using MatrixBase<Derived> not possible because template functions
+        // cannot be virtual. Maybe there is a workaround for this.  Using
+        // Map<Matrix<double, ...>> makes the interface (for the material model
+        // implementation) unnecessary difficult.
+        KelvinVector const eps_{eps};
+        KelvinVector sigma_tensile_{sigma_tensile};
+        KelvinVector sigma_compressive_{sigma_compressive};
+        KelvinMatrix C_tensile_{C_tensile};
+        KelvinMatrix C_compressive_{C_compressive};
+        KelvinVector sigma_real_{sigma_real};
+
+        bool const result = calculateDegradedStress(t,
+                                            x,
+                                            eps_,
+                                            strain_energy_tensile,
+                                            sigma_tensile_,
+                                            sigma_compressive_,
+                                            C_tensile_,
+                                            C_compressive_,
+                                            sigma_real_,
+                                            degradation);
+
+        sigma_tensile = sigma_tensile_;
+        sigma_compressive = sigma_compressive_;
+        C_tensile = C_tensile_;
+        C_compressive = C_compressive_;
+        sigma_real = sigma_real_;
+        return result;
+    }
+
+    virtual ~PhaseFieldExtension() = default;
+};
+
+}  // namespace Solids
+}  // namespace MaterialLib
diff --git a/ProcessLib/CMakeLists.txt b/ProcessLib/CMakeLists.txt
index e64cf8f67828ab3664c09f4704f28bfba4935a4d..f73380f5ba850aac7e4c504efe9028c539be0aae 100644
--- a/ProcessLib/CMakeLists.txt
+++ b/ProcessLib/CMakeLists.txt
@@ -17,6 +17,7 @@ APPEND_SOURCE_FILES(SOURCES LIE/SmallDeformation)
 APPEND_SOURCE_FILES(SOURCES LIE/SmallDeformation/LocalAssembler)
 APPEND_SOURCE_FILES(SOURCES LiquidFlow)
 APPEND_SOURCE_FILES(SOURCES Parameter)
+APPEND_SOURCE_FILES(SOURCES PhaseField)
 APPEND_SOURCE_FILES(SOURCES RichardsFlow)
 APPEND_SOURCE_FILES(SOURCES SmallDeformation)
 APPEND_SOURCE_FILES(SOURCES TES)
@@ -58,6 +59,7 @@ include(HydroMechanics/Tests.cmake)
 include(LIE/HydroMechanics/Tests.cmake)
 include(LIE/SmallDeformation/Tests.cmake)
 include(LiquidFlow/Tests.cmake)
+include(PhaseField/Tests.cmake)
 include(RichardsFlow/Tests.cmake)
 include(SmallDeformation/Tests.cmake)
 include(TES/Tests.cmake)
diff --git a/ProcessLib/PhaseField/CreatePhaseFieldProcess.cpp b/ProcessLib/PhaseField/CreatePhaseFieldProcess.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0dcadcb9de6e2bca3a7db6a1a405352e634432c5
--- /dev/null
+++ b/ProcessLib/PhaseField/CreatePhaseFieldProcess.cpp
@@ -0,0 +1,208 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2017, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#include "CreatePhaseFieldProcess.h"
+
+#include <cassert>
+
+#include "MaterialLib/SolidModels/CreateLinearElasticIsotropic.h"
+#include "MaterialLib/SolidModels/LinearElasticIsotropic.h"
+#include "ProcessLib/Utils/ParseSecondaryVariables.h"
+
+#include "PhaseFieldProcess.h"
+#include "PhaseFieldProcessData.h"
+
+namespace ProcessLib
+{
+namespace PhaseField
+{
+template <int DisplacementDim>
+class PhaseFieldProcess;
+
+extern template class PhaseFieldProcess<2>;
+extern template class PhaseFieldProcess<3>;
+
+template <int DisplacementDim>
+std::unique_ptr<Process> createPhaseFieldProcess(
+    MeshLib::Mesh& mesh,
+    std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
+    std::vector<ProcessVariable> const& variables,
+    std::vector<std::unique_ptr<ParameterBase>> const& parameters,
+    unsigned const integration_order,
+    BaseLib::ConfigTree const& config)
+{
+    //! \ogs_file_param{prj__processes__process__type}
+    config.checkConfigParameter("type", "PHASE_FIELD");
+    DBUG("Create PhaseFieldProcess.");
+
+    // Process variable.
+
+    //! \ogs_file_param{prj__processes__process__PHASE_FIELD__process_variables}
+    auto const pv_config = config.getConfigSubtree("process_variables");
+
+    auto process_variables = findProcessVariables(
+        variables, pv_config,
+        {//! \ogs_file_param_special{prj__processes__process__PHASE_FIELD__process_variables__phasefield}
+         "phasefield",
+         //! \ogs_file_param_special{prj__processes__process__PHASE_FIELD__process_variables__displacement}
+         "displacement"});
+
+    DBUG("Associate displacement with process variable \'%s\'.",
+         process_variables[1].get().getName().c_str());
+
+    if (process_variables[1].get().getNumberOfComponents() != DisplacementDim)
+    {
+        OGS_FATAL(
+            "Number of components of the process variable '%s' is different "
+            "from the displacement dimension: got %d, expected %d",
+            process_variables[1].get().getName().c_str(),
+            process_variables[1].get().getNumberOfComponents(),
+            DisplacementDim);
+    }
+
+    DBUG("Associate phase field with process variable \'%s\'.",
+         process_variables[0].get().getName().c_str());
+    if (process_variables[0].get().getNumberOfComponents() != 1)
+    {
+        OGS_FATAL(
+            "Phase field process variable '%s' is not a scalar variable but has "
+            "%d components.",
+            process_variables[0].get().getName().c_str(),
+            process_variables[0].get().getNumberOfComponents(),
+            DisplacementDim);
+    }
+
+    // Constitutive relation.
+    // read type;
+    auto const constitutive_relation_config =
+        //! \ogs_file_param{prj__processes__process__PHASE_FIELD__constitutive_relation}
+        config.getConfigSubtree("constitutive_relation");
+
+    auto const phasefield_parameters_config =
+        //! \ogs_file_param{prj__processes__process__PHASE_FIELD__phasefield_parameters}
+        config.getConfigSubtree("phasefield_parameters");
+
+    auto const type =
+        //! \ogs_file_param{prj__processes__process__PHASE_FIELD__constitutive_relation__type}
+        constitutive_relation_config.peekConfigParameter<std::string>("type");
+
+    std::unique_ptr<MaterialLib::Solids::PhaseFieldExtension<DisplacementDim>>
+        material = nullptr;
+    if (type == "LinearElasticIsotropic")
+    {
+        auto elastic_model = MaterialLib::Solids::createLinearElasticIsotropic<
+                DisplacementDim>(parameters, constitutive_relation_config);
+        material =
+                std::make_unique<MaterialLib::Solids::LinearElasticIsotropicPhaseField<
+                DisplacementDim>>(std::move(elastic_model->getMaterialProperties()));
+    }
+    else
+    {
+        OGS_FATAL(
+            "Cannot construct constitutive relation of given type \'%s\'.",
+            type.c_str());
+    }
+
+    // Residual stiffness
+    auto& residual_stiffness = findParameter<double>(
+        phasefield_parameters_config,
+        //! \ogs_file_param_special{prj__processes__process__PHASE_FIELD__phasefield_parameters__residual_stiffness}
+        "residual_stiffness", parameters, 1);
+    DBUG("Use \'%s\' as residual stiffness.", residual_stiffness.name.c_str());
+
+    // Crack resistance
+    auto& crack_resistance = findParameter<double>(
+        phasefield_parameters_config,
+        //! \ogs_file_param_special{prj__processes__process__PHASE_FIELD__phasefield_parameters__crack_resistance}
+        "crack_resistance", parameters, 1);
+    DBUG("Use \'%s\' as crack resistance.", crack_resistance.name.c_str());
+
+    // Crack length scale
+    auto& crack_length_scale = findParameter<double>(
+        phasefield_parameters_config,
+        //! \ogs_file_param_special{prj__processes__process__PHASE_FIELD__phasefield_parameters__crack_length_scale}
+        "crack_length_scale", parameters, 1);
+    DBUG("Use \'%s\' as crack length scale.", crack_length_scale.name.c_str());
+
+    // Kinetic coefficient
+    auto& kinetic_coefficient = findParameter<double>(
+        phasefield_parameters_config,
+        //! \ogs_file_param_special{prj__processes__process__PHASE_FIELD__phasefield_parameters__kinetic_coefficient}
+        "kinetic_coefficient", parameters, 1);
+    DBUG("Use \'%s\' as kinetic coefficient.",
+         kinetic_coefficient.name.c_str());
+
+    // Solid density
+    auto& solid_density = findParameter<double>(
+        config,
+        //! \ogs_file_param_special{prj__processes__process__PHASE_FIELD__solid_density}
+        "solid_density", parameters, 1);
+    DBUG("Use \'%s\' as solid density parameter.", solid_density.name.c_str());
+
+    // History field
+    auto& history_field = findParameter<double>(
+        phasefield_parameters_config,
+        //! \ogs_file_param_special{prj__processes__process__PHASE_FIELD__phasefield_parameters__history_field}
+        "history_field", parameters, 1);
+    DBUG("Use \'%s\' as history field.", history_field.name.c_str());
+
+    // Specific body force
+    Eigen::Matrix<double, DisplacementDim, 1> specific_body_force;
+    {
+        std::vector<double> const b =
+            //! \ogs_file_param{prj__processes__process__PHASE_FIELD__specific_body_force}
+            config.getConfigParameter<std::vector<double>>(
+                "specific_body_force");
+        if (specific_body_force.size() != DisplacementDim)
+            OGS_FATAL(
+                "The size of the specific body force vector does not match the "
+                "displacement dimension. Vector size is %d, displacement "
+                "dimension is %d",
+                specific_body_force.size(), DisplacementDim);
+
+        std::copy_n(b.data(), b.size(), specific_body_force.data());
+    }
+
+    PhaseFieldProcessData<DisplacementDim> process_data{
+        std::move(material), residual_stiffness,  crack_resistance,
+        crack_length_scale,  kinetic_coefficient, solid_density,
+        history_field,       specific_body_force};
+
+    SecondaryVariableCollection secondary_variables;
+
+    NumLib::NamedFunctionCaller named_function_caller(
+        {"PhaseField_displacement"});
+
+    ProcessLib::parseSecondaryVariables(config, secondary_variables,
+                                        named_function_caller);
+
+    return std::make_unique<PhaseFieldProcess<DisplacementDim>>(
+            mesh, std::move(jacobian_assembler), parameters, integration_order,
+            std::move(process_variables), std::move(process_data),
+            std::move(secondary_variables), std::move(named_function_caller));
+}
+
+template std::unique_ptr<Process> createPhaseFieldProcess<2>(
+    MeshLib::Mesh& mesh,
+    std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
+    std::vector<ProcessVariable> const& variables,
+    std::vector<std::unique_ptr<ParameterBase>> const& parameters,
+    unsigned const integration_order,
+    BaseLib::ConfigTree const& config);
+
+template std::unique_ptr<Process> createPhaseFieldProcess<3>(
+    MeshLib::Mesh& mesh,
+    std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
+    std::vector<ProcessVariable> const& variables,
+    std::vector<std::unique_ptr<ParameterBase>> const& parameters,
+    unsigned const integration_order,
+    BaseLib::ConfigTree const& config);
+
+}  // namespace PhaseField
+}  // namespace ProcessLib
diff --git a/ProcessLib/PhaseField/CreatePhaseFieldProcess.h b/ProcessLib/PhaseField/CreatePhaseFieldProcess.h
new file mode 100644
index 0000000000000000000000000000000000000000..770b8e7bd22f79f938d240c69151347b1d99fb93
--- /dev/null
+++ b/ProcessLib/PhaseField/CreatePhaseFieldProcess.h
@@ -0,0 +1,28 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2017, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#pragma once
+
+#include "ProcessLib/Process.h"
+
+namespace ProcessLib
+{
+namespace PhaseField
+{
+template <int DisplacementDim>
+std::unique_ptr<Process> createPhaseFieldProcess(
+    MeshLib::Mesh& mesh,
+    std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
+    std::vector<ProcessVariable> const& variables,
+    std::vector<std::unique_ptr<ParameterBase>> const& parameters,
+    unsigned const integration_order,
+    BaseLib::ConfigTree const& config);
+
+}  // namespace PhaseField
+}  // namespace ProcessLib
diff --git a/ProcessLib/PhaseField/PhaseFieldFEM.h b/ProcessLib/PhaseField/PhaseFieldFEM.h
new file mode 100644
index 0000000000000000000000000000000000000000..f3be2299be43927ac8a26721c41bad5d6be40f80
--- /dev/null
+++ b/ProcessLib/PhaseField/PhaseFieldFEM.h
@@ -0,0 +1,653 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2017, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#pragma once
+
+#include <memory>
+#include <vector>
+
+#include "MaterialLib/SolidModels/KelvinVector.h"
+#include "MaterialLib/SolidModels/LinearElasticIsotropicPhaseField.h"
+#include "MaterialLib/SolidModels/LinearElasticIsotropic.h"
+#include "MathLib/LinAlg/Eigen/EigenMapTools.h"
+#include "NumLib/Extrapolation/ExtrapolatableElement.h"
+#include "NumLib/Fem/FiniteElement/TemplateIsoparametric.h"
+#include "NumLib/Fem/ShapeMatrixPolicy.h"
+#include "NumLib/Function/Interpolation.h"
+#include "ProcessLib/Deformation/BMatrixPolicy.h"
+#include "ProcessLib/Deformation/LinearBMatrix.h"
+#include "ProcessLib/LocalAssemblerInterface.h"
+#include "ProcessLib/LocalAssemblerTraits.h"
+#include "ProcessLib/Parameter/Parameter.h"
+#include "ProcessLib/Utils/InitShapeMatrices.h"
+
+#include "PhaseFieldProcessData.h"
+
+namespace ProcessLib
+{
+namespace PhaseField
+{
+template <typename BMatricesType, typename ShapeMatrixType, int DisplacementDim>
+struct IntegrationPointData final
+{
+    explicit IntegrationPointData(
+        MaterialLib::Solids::MechanicsBase<DisplacementDim>& solid_material)
+        : solid_material(solid_material),
+          material_state_variables(
+              solid_material.createMaterialStateVariables())
+    {
+    }
+
+    typename ShapeMatrixType::NodalRowVectorType N;
+    typename ShapeMatrixType::GlobalDimNodalMatrixType dNdx;
+
+    typename BMatricesType::KelvinVectorType eps, eps_prev;
+
+    typename BMatricesType::KelvinVectorType sigma_tensile, sigma_compressive,
+        sigma_real_prev, sigma_real;
+    double strain_energy_tensile;
+
+    MaterialLib::Solids::MechanicsBase<DisplacementDim>& solid_material;
+    std::unique_ptr<typename MaterialLib::Solids::MechanicsBase<
+        DisplacementDim>::MaterialStateVariables> material_state_variables;
+
+    typename BMatricesType::KelvinMatrixType C_tensile, C_compressive;
+    double integration_weight;
+    double history_variable;
+    double history_variable_prev;
+
+    void pushBackState()
+    {
+        if (history_variable_prev <
+            history_variable)
+        {
+            history_variable_prev =
+                history_variable;
+        }
+        eps_prev = eps;
+        sigma_real_prev = sigma_real;
+        material_state_variables->pushBackState();
+    }
+
+    template <typename DisplacementVectorType>
+    void updateConstitutiveRelation(
+                                    double const t,
+                                    SpatialPosition const& x_position,
+                                    double const dt,
+                                    DisplacementVectorType const& /*u*/,
+                                    double const degradation)
+    {
+        static_cast<MaterialLib::Solids::PhaseFieldExtension<DisplacementDim>&>(
+            solid_material)
+            .calculateDegradedStress(t, x_position, eps, strain_energy_tensile,
+                             sigma_tensile, sigma_compressive, C_tensile,
+                             C_compressive, sigma_real, degradation);
+    }
+
+};
+
+/// Used by for extrapolation of the integration point values. It is ordered
+/// (and stored) by integration points.
+template <typename ShapeMatrixType>
+struct SecondaryData
+{
+    std::vector<ShapeMatrixType, Eigen::aligned_allocator<ShapeMatrixType>> N;
+};
+
+struct PhaseFieldLocalAssemblerInterface
+    : public ProcessLib::LocalAssemblerInterface,
+      public NumLib::ExtrapolatableElement
+{
+    virtual std::vector<double> const& getIntPtSigmaXX(
+        const double /*t*/,
+        GlobalVector const& /*current_solution*/,
+        NumLib::LocalToGlobalIndexMap const& /*dof_table*/,
+        std::vector<double>& cache) const = 0;
+
+    virtual std::vector<double> const& getIntPtSigmaYY(
+        const double /*t*/,
+        GlobalVector const& /*current_solution*/,
+        NumLib::LocalToGlobalIndexMap const& /*dof_table*/,
+        std::vector<double>& cache) const = 0;
+
+    virtual std::vector<double> const& getIntPtSigmaZZ(
+        const double /*t*/,
+        GlobalVector const& /*current_solution*/,
+        NumLib::LocalToGlobalIndexMap const& /*dof_table*/,
+        std::vector<double>& cache) const = 0;
+
+    virtual std::vector<double> const& getIntPtSigmaXY(
+        const double /*t*/,
+        GlobalVector const& /*current_solution*/,
+        NumLib::LocalToGlobalIndexMap const& /*dof_table*/,
+        std::vector<double>& cache) const = 0;
+
+    virtual std::vector<double> const& getIntPtSigmaXZ(
+        const double /*t*/,
+        GlobalVector const& /*current_solution*/,
+        NumLib::LocalToGlobalIndexMap const& /*dof_table*/,
+        std::vector<double>& cache) const = 0;
+
+    virtual std::vector<double> const& getIntPtSigmaYZ(
+        const double /*t*/,
+        GlobalVector const& /*current_solution*/,
+        NumLib::LocalToGlobalIndexMap const& /*dof_table*/,
+        std::vector<double>& cache) const = 0;
+
+    virtual std::vector<double> const& getIntPtEpsilonXX(
+        const double /*t*/,
+        GlobalVector const& /*current_solution*/,
+        NumLib::LocalToGlobalIndexMap const& /*dof_table*/,
+        std::vector<double>& cache) const = 0;
+
+    virtual std::vector<double> const& getIntPtEpsilonYY(
+        const double /*t*/,
+        GlobalVector const& /*current_solution*/,
+        NumLib::LocalToGlobalIndexMap const& /*dof_table*/,
+        std::vector<double>& cache) const = 0;
+
+    virtual std::vector<double> const& getIntPtEpsilonZZ(
+        const double /*t*/,
+        GlobalVector const& /*current_solution*/,
+        NumLib::LocalToGlobalIndexMap const& /*dof_table*/,
+        std::vector<double>& cache) const = 0;
+
+    virtual std::vector<double> const& getIntPtEpsilonXY(
+        const double /*t*/,
+        GlobalVector const& /*current_solution*/,
+        NumLib::LocalToGlobalIndexMap const& /*dof_table*/,
+        std::vector<double>& cache) const = 0;
+
+    virtual std::vector<double> const& getIntPtEpsilonXZ(
+        const double /*t*/,
+        GlobalVector const& /*current_solution*/,
+        NumLib::LocalToGlobalIndexMap const& /*dof_table*/,
+        std::vector<double>& cache) const = 0;
+
+    virtual std::vector<double> const& getIntPtEpsilonYZ(
+        const double /*t*/,
+        GlobalVector const& /*current_solution*/,
+        NumLib::LocalToGlobalIndexMap const& /*dof_table*/,
+        std::vector<double>& cache) const = 0;
+};
+
+template <typename ShapeFunction, typename IntegrationMethod,
+          int DisplacementDim>
+class PhaseFieldLocalAssembler : public PhaseFieldLocalAssemblerInterface
+{
+public:
+    using ShapeMatricesType =
+        ShapeMatrixPolicyType<ShapeFunction, DisplacementDim>;
+
+    // Types for displacement.
+    // (Higher order elements = ShapeFunction).
+    using ShapeMatrices = typename ShapeMatricesType::ShapeMatrices;
+    using BMatricesType = BMatrixPolicyType<ShapeFunction, DisplacementDim>;
+
+    using NodalForceVectorType = typename BMatricesType::NodalForceVectorType;
+    using RhsVector = typename ShapeMatricesType::template VectorType<
+        ShapeFunction::NPOINTS + ShapeFunction::NPOINTS * DisplacementDim>;
+    using JacobianMatrix = typename ShapeMatricesType::template MatrixType<
+        ShapeFunction::NPOINTS + ShapeFunction::NPOINTS * DisplacementDim,
+        ShapeFunction::NPOINTS + ShapeFunction::NPOINTS * DisplacementDim>;
+
+    PhaseFieldLocalAssembler(PhaseFieldLocalAssembler const&) = delete;
+    PhaseFieldLocalAssembler(PhaseFieldLocalAssembler&&) = delete;
+
+    PhaseFieldLocalAssembler(
+        MeshLib::Element const& e,
+        std::size_t const /*local_matrix_size*/,
+        bool const is_axially_symmetric,
+        unsigned const integration_order,
+        PhaseFieldProcessData<DisplacementDim>& process_data)
+        : _process_data(process_data),
+          _integration_method(integration_order),
+          _element(e),
+         _is_axially_symmetric(is_axially_symmetric)
+    {
+        unsigned const n_integration_points =
+            _integration_method.getNumberOfPoints();
+
+        _ip_data.reserve(n_integration_points);
+        _secondary_data.N.resize(n_integration_points);
+
+        auto const shape_matrices =
+            initShapeMatrices<ShapeFunction, ShapeMatricesType,
+                              IntegrationMethod, DisplacementDim>(
+                e, is_axially_symmetric, _integration_method);
+
+        SpatialPosition x_position;
+        x_position.setElementID(_element.getID());
+
+        for (unsigned ip = 0; ip < n_integration_points; ip++)
+        {
+            // displacement (subscript u)
+            _ip_data.emplace_back(*_process_data.material);
+            auto& ip_data = _ip_data[ip];
+            ip_data.integration_weight =
+                _integration_method.getWeightedPoint(ip).getWeight() *
+                shape_matrices[ip].integralMeasure * shape_matrices[ip].detJ;
+
+            ip_data.eps.setZero(kelvin_vector_size);
+            ip_data.eps_prev.resize(kelvin_vector_size);
+            ip_data.C_tensile.setZero(kelvin_vector_size, kelvin_vector_size);
+            ip_data.C_compressive.setZero(kelvin_vector_size,
+                                         kelvin_vector_size);
+            ip_data.sigma_tensile.setZero(kelvin_vector_size);
+            ip_data.sigma_compressive.setZero(kelvin_vector_size);
+            ip_data.history_variable =
+                process_data.history_field(0, x_position)[0];
+            ip_data.history_variable_prev =
+                process_data.history_field(0, x_position)[0];
+            ip_data.sigma_real.setZero(kelvin_vector_size);
+
+            ip_data.N = shape_matrices[ip].N;
+            ip_data.dNdx = shape_matrices[ip].dNdx;
+
+            _secondary_data.N[ip] = shape_matrices[ip].N;
+        }
+    }
+
+    void assemble(double const /*t*/, std::vector<double> const& /*local_x*/,
+                  std::vector<double>& /*local_M_data*/,
+                  std::vector<double>& /*local_K_data*/,
+                  std::vector<double>& /*local_rhs_data*/) override
+    {
+        OGS_FATAL(
+            "PhaseFieldLocalAssembler: assembly without jacobian is not "
+            "implemented.");
+    }
+
+    void assembleWithJacobian(double const t,
+                              std::vector<double> const& local_x,
+                              std::vector<double> const& local_xdot,
+                              const double /*dxdot_dx*/, const double /*dx_dx*/,
+                              std::vector<double>& /*local_M_data*/,
+                              std::vector<double>& /*local_K_data*/,
+                              std::vector<double>& local_rhs_data,
+                              std::vector<double>& local_Jac_data) override
+    {
+        auto const local_matrix_size = local_x.size();
+        assert(local_matrix_size == phasefield_size + displacement_size);
+
+        auto d = Eigen::Map<typename ShapeMatricesType::template VectorType<
+            phasefield_size> const>(local_x.data() + phasefield_index,
+                                    phasefield_size);
+
+        auto u = Eigen::Map<typename ShapeMatricesType::template VectorType<
+            displacement_size> const>(local_x.data() + displacement_index,
+                                      displacement_size);
+
+        auto d_dot = Eigen::Map<typename ShapeMatricesType::template VectorType<
+            phasefield_size> const>(local_xdot.data() + phasefield_index,
+                                    phasefield_size);
+
+        auto local_Jac = MathLib::createZeroedMatrix<JacobianMatrix>(
+            local_Jac_data, local_matrix_size, local_matrix_size);
+
+        auto local_rhs = MathLib::createZeroedVector<RhsVector>(
+            local_rhs_data, local_matrix_size);
+
+        typename ShapeMatricesType::template MatrixType<displacement_size,
+                                                        phasefield_size> Kud;
+        Kud.setZero(displacement_size, phasefield_size);
+
+        typename ShapeMatricesType::template MatrixType<phasefield_size,
+                                                        displacement_size> Kdu;
+        Kdu.setZero(phasefield_size, displacement_size);
+
+        typename ShapeMatricesType::NodalMatrixType Kdd;
+        Kdd.setZero(phasefield_size, phasefield_size);
+
+        typename ShapeMatricesType::NodalMatrixType Ddd;
+        Ddd.setZero(phasefield_size, phasefield_size);
+
+        double const& dt = _process_data.dt;
+
+        SpatialPosition x_position;
+        x_position.setElementID(_element.getID());
+
+        unsigned const n_integration_points =
+            _integration_method.getNumberOfPoints();
+        for (unsigned ip = 0; ip < n_integration_points; ip++)
+        {
+            x_position.setIntegrationPoint(ip);
+            auto const& w = _ip_data[ip].integration_weight;
+
+            auto const& dNdx = _ip_data[ip].dNdx;
+            auto const& N = _ip_data[ip].N;
+
+            auto const x_coord =
+                interpolateXCoordinate<ShapeFunction, ShapeMatricesType>(
+                    _element, N);
+            auto const& B = LinearBMatrix::computeBMatrix<
+                DisplacementDim, ShapeFunction::NPOINTS,
+                typename BMatricesType::BMatrixType>(dNdx, N, x_coord,
+                                                     _is_axially_symmetric);
+
+            auto const& C_tensile = _ip_data[ip].C_tensile;
+            auto const& C_compressive = _ip_data[ip].C_compressive;
+
+            auto& eps = _ip_data[ip].eps;
+            auto const& strain_energy_tensile =
+                _ip_data[ip].strain_energy_tensile;
+            auto const& sigma_tensile = _ip_data[ip].sigma_tensile;
+
+            auto& history_variable = _ip_data[ip].history_variable;
+            auto& history_variable_prev = _ip_data[ip].history_variable_prev;
+
+            auto const& sigma_real = _ip_data[ip].sigma_real;
+
+            // Kdd_1 defines one term which both used in Kdd and local_rhs for
+            // phase field
+            double const gc = _process_data.crack_resistance(t, x_position)[0];
+            double const ls =
+                _process_data.crack_length_scale(t, x_position)[0];
+            typename ShapeMatricesType::NodalMatrixType const Kdd_1 =
+                dNdx.transpose() * 2 * gc * ls * dNdx;
+
+            //
+            // displacement equation, displacement part
+            //
+            double const k = _process_data.residual_stiffness(t, x_position)[0];
+            double const d_ip = N.dot(d);
+            double const degradation = d_ip * d_ip * (1 - k) + k;
+            eps.noalias() = B * u;
+            _ip_data[ip].updateConstitutiveRelation(t, x_position, dt, u,
+                                                    degradation);
+
+            local_Jac.template block<displacement_size, displacement_size>(
+                         displacement_index, displacement_index)
+                .noalias() += B.transpose() *
+                              (degradation * C_tensile + C_compressive) * B * w;
+
+            typename ShapeMatricesType::template MatrixType<DisplacementDim,
+                                                            displacement_size>
+                N_u = ShapeMatricesType::template MatrixType<
+                    DisplacementDim,
+                    displacement_size>::Zero(DisplacementDim,
+                                             displacement_size);
+
+            for (int i = 0; i < DisplacementDim; ++i)
+                N_u.template block<1, displacement_size / DisplacementDim>(
+                       i, i * displacement_size / DisplacementDim)
+                    .noalias() = N;
+
+            auto const rho_sr = _process_data.solid_density(t, x_position)[0];
+            auto const& b = _process_data.specific_body_force;
+            local_rhs.template block<displacement_size, 1>(displacement_index, 0)
+                .noalias() -=
+                (B.transpose() * sigma_real - N_u.transpose() * rho_sr * b) * w;
+
+            //
+            // displacement equation, phasefield part
+            //
+            Kud.noalias() += B.transpose() * 2 * d_ip * sigma_tensile * N * w;
+
+            double const d_dot_ip = N.dot(d_dot);
+
+            if (history_variable_prev < strain_energy_tensile)
+            {
+                history_variable = strain_energy_tensile;
+                Kdu.noalias() = Kud.transpose();
+            }
+            else
+            {
+                history_variable = history_variable_prev;
+            }
+
+            //
+            // phasefield equation, phasefield part.
+            //
+            Kdd.noalias() += (Kdd_1 + N.transpose() * 2 * history_variable * N +
+                              N.transpose() * 0.5 * gc / ls * N) *
+                             w;
+            double const M =
+                _process_data.kinetic_coefficient(t, x_position)[0];
+            local_rhs.template segment<phasefield_size>(phasefield_index)
+                .noalias() -= (N.transpose() * d_dot_ip / M + Kdd_1 * d +
+                               N.transpose() * d_ip * 2 * history_variable -
+                               N.transpose() * 0.5 * gc / ls * (1 - d_ip)) *
+                              w;
+
+            Ddd.noalias() += N.transpose() / M * N * w;
+        }
+        // displacement equation, phasefield part
+        local_Jac.template block<displacement_size, phasefield_size>(
+                     displacement_index, phasefield_index)
+            .noalias() += Kud;
+
+        // phasefield equation, phasefield part.
+        local_Jac.template block<phasefield_size, phasefield_size>(
+                     phasefield_index, phasefield_index)
+            .noalias() += Kdd + Ddd / dt;
+
+        // phasefield equation, displacement part.
+        local_Jac.template block<phasefield_size, displacement_size>(
+                     phasefield_index, displacement_index)
+            .noalias() += Kdu;
+
+    }
+
+    void preTimestepConcrete(std::vector<double> const& /*local_x*/,
+                             double const /*t*/,
+                             double const /*delta_t*/) override
+    {
+        unsigned const n_integration_points =
+            _integration_method.getNumberOfPoints();
+
+        for (unsigned ip = 0; ip < n_integration_points; ip++)
+        {
+            _ip_data[ip].pushBackState();
+        }
+    }
+
+    Eigen::Map<const Eigen::RowVectorXd> getShapeMatrix(
+        const unsigned integration_point) const override
+    {
+        auto const& N = _secondary_data.N[integration_point];
+
+        // assumes N is stored contiguously in memory
+        return Eigen::Map<const Eigen::RowVectorXd>(N.data(), N.size());
+    }
+
+    std::vector<double> const& getIntPtSigmaXX(
+        const double /*t*/,
+        GlobalVector const& /*current_solution*/,
+        NumLib::LocalToGlobalIndexMap const& /*dof_table*/,
+        std::vector<double>& cache) const override
+    {
+        return getIntPtSigma(cache, 0);
+    }
+
+    std::vector<double> const& getIntPtSigmaYY(
+        const double /*t*/,
+        GlobalVector const& /*current_solution*/,
+        NumLib::LocalToGlobalIndexMap const& /*dof_table*/,
+        std::vector<double>& cache) const override
+    {
+        return getIntPtSigma(cache, 1);
+    }
+
+    std::vector<double> const& getIntPtSigmaZZ(
+        const double /*t*/,
+        GlobalVector const& /*current_solution*/,
+        NumLib::LocalToGlobalIndexMap const& /*dof_table*/,
+        std::vector<double>& cache) const override
+    {
+        return getIntPtSigma(cache, 2);
+    }
+
+    std::vector<double> const& getIntPtSigmaXY(
+        const double /*t*/,
+        GlobalVector const& /*current_solution*/,
+        NumLib::LocalToGlobalIndexMap const& /*dof_table*/,
+        std::vector<double>& cache) const override
+    {
+        return getIntPtSigma(cache, 3);
+    }
+
+    std::vector<double> const& getIntPtSigmaYZ(
+        const double /*t*/,
+        GlobalVector const& /*current_solution*/,
+        NumLib::LocalToGlobalIndexMap const& /*dof_table*/,
+        std::vector<double>& cache) const override
+    {
+        assert(DisplacementDim == 3);
+        return getIntPtSigma(cache, 4);
+    }
+
+    std::vector<double> const& getIntPtSigmaXZ(
+        const double /*t*/,
+        GlobalVector const& /*current_solution*/,
+        NumLib::LocalToGlobalIndexMap const& /*dof_table*/,
+        std::vector<double>& cache) const override
+    {
+        assert(DisplacementDim == 3);
+        return getIntPtSigma(cache, 5);
+    }
+
+    std::vector<double> const& getIntPtEpsilonXX(
+        const double /*t*/,
+        GlobalVector const& /*current_solution*/,
+        NumLib::LocalToGlobalIndexMap const& /*dof_table*/,
+        std::vector<double>& cache) const override
+    {
+        return getIntPtEpsilon(cache, 0);
+    }
+
+    std::vector<double> const& getIntPtEpsilonYY(
+        const double /*t*/,
+        GlobalVector const& /*current_solution*/,
+        NumLib::LocalToGlobalIndexMap const& /*dof_table*/,
+        std::vector<double>& cache) const override
+    {
+        return getIntPtEpsilon(cache, 1);
+    }
+
+    std::vector<double> const& getIntPtEpsilonZZ(
+        const double /*t*/,
+        GlobalVector const& /*current_solution*/,
+        NumLib::LocalToGlobalIndexMap const& /*dof_table*/,
+        std::vector<double>& cache) const override
+    {
+        return getIntPtEpsilon(cache, 2);
+    }
+
+    std::vector<double> const& getIntPtEpsilonXY(
+        const double /*t*/,
+        GlobalVector const& /*current_solution*/,
+        NumLib::LocalToGlobalIndexMap const& /*dof_table*/,
+        std::vector<double>& cache) const override
+    {
+        return getIntPtEpsilon(cache, 3);
+    }
+
+    std::vector<double> const& getIntPtEpsilonYZ(
+        const double /*t*/,
+        GlobalVector const& /*current_solution*/,
+        NumLib::LocalToGlobalIndexMap const& /*dof_table*/,
+        std::vector<double>& cache) const override
+    {
+        assert(DisplacementDim == 3);
+        return getIntPtEpsilon(cache, 4);
+    }
+
+    std::vector<double> const& getIntPtEpsilonXZ(
+        const double /*t*/,
+        GlobalVector const& /*current_solution*/,
+        NumLib::LocalToGlobalIndexMap const& /*dof_table*/,
+        std::vector<double>& cache) const override
+    {
+        assert(DisplacementDim == 3);
+        return getIntPtEpsilon(cache, 5);
+    }
+
+private:
+    std::vector<double> const& getIntPtSigma(std::vector<double>& cache,
+                                             std::size_t const component) const
+    {
+        cache.clear();
+        cache.reserve(_ip_data.size());
+
+        for (auto const& ip_data : _ip_data)
+        {
+            if (component < 3)  // xx, yy, zz components
+                cache.push_back(ip_data.sigma_real[component]);
+            else  // mixed xy, yz, xz components
+                cache.push_back(ip_data.sigma_real[component] / std::sqrt(2));
+        }
+
+        return cache;
+    }
+
+    std::vector<double> const& getIntPtEpsilon(
+        std::vector<double>& cache, std::size_t const component) const
+    {
+        cache.clear();
+        cache.reserve(_ip_data.size());
+
+        for (auto const& ip_data : _ip_data)
+        {
+            if (component < 3)  // xx, yy, zz components
+                cache.push_back(ip_data.eps[component]);
+            else  // mixed xy, yz, xz components
+                cache.push_back(ip_data.eps[component] / std::sqrt(2));
+        }
+
+        return cache;
+    }
+
+    PhaseFieldProcessData<DisplacementDim>& _process_data;
+
+    std::vector<
+        IntegrationPointData<BMatricesType, ShapeMatricesType, DisplacementDim>,
+        Eigen::aligned_allocator<IntegrationPointData<
+            BMatricesType, ShapeMatricesType, DisplacementDim>>>
+        _ip_data;
+
+    IntegrationMethod _integration_method;
+    MeshLib::Element const& _element;
+    bool const _is_axially_symmetric;
+    SecondaryData<typename ShapeMatrices::ShapeType> _secondary_data;
+
+    static const int phasefield_index = 0;
+    static const int phasefield_size = ShapeFunction::NPOINTS;
+    static const int displacement_index = ShapeFunction::NPOINTS;
+    static const int displacement_size =
+        ShapeFunction::NPOINTS * DisplacementDim;
+    static const int kelvin_vector_size =
+        KelvinVectorDimensions<DisplacementDim>::value;
+};
+
+template <typename ShapeFunction, typename IntegrationMethod,
+          unsigned GlobalDim, int DisplacementDim>
+class LocalAssemblerData final
+    : public PhaseFieldLocalAssembler<ShapeFunction, IntegrationMethod,
+                                      DisplacementDim>
+{
+public:
+    LocalAssemblerData(LocalAssemblerData const&) = delete;
+    LocalAssemblerData(LocalAssemblerData&&) = delete;
+
+    LocalAssemblerData(MeshLib::Element const& e,
+                       std::size_t const local_matrix_size,
+                       bool is_axially_symmetric,
+                       unsigned const integration_order,
+                       PhaseFieldProcessData<DisplacementDim>& process_data)
+        : PhaseFieldLocalAssembler<ShapeFunction, IntegrationMethod,
+                                   DisplacementDim>(
+              e, local_matrix_size, is_axially_symmetric, integration_order,
+              process_data)
+    {
+    }
+};
+
+}  // namespace PhaseField
+}  // namespace ProcessLib
diff --git a/ProcessLib/PhaseField/PhaseFieldProcess.cpp b/ProcessLib/PhaseField/PhaseFieldProcess.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6e3243e76ceb7dba633fd6c560456ef52594e8ee
--- /dev/null
+++ b/ProcessLib/PhaseField/PhaseFieldProcess.cpp
@@ -0,0 +1,20 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2017, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#include "PhaseFieldProcess.h"
+
+namespace ProcessLib
+{
+namespace PhaseField
+{
+template class PhaseFieldProcess<2>;
+template class PhaseFieldProcess<3>;
+
+}  // namespace PhaseField
+}  // namespace ProcessLib
diff --git a/ProcessLib/PhaseField/PhaseFieldProcess.h b/ProcessLib/PhaseField/PhaseFieldProcess.h
new file mode 100644
index 0000000000000000000000000000000000000000..df885f24062e0c3bd56f18358dfe47a599ebf675
--- /dev/null
+++ b/ProcessLib/PhaseField/PhaseFieldProcess.h
@@ -0,0 +1,244 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2017, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#pragma once
+
+#include <cassert>
+
+#include "NumLib/DOF/DOFTableUtil.h"
+#include "ProcessLib/Process.h"
+#include "ProcessLib/SmallDeformation/CreateLocalAssemblers.h"
+
+#include "PhaseFieldFEM.h"
+#include "PhaseFieldProcessData.h"
+
+namespace ProcessLib
+{
+namespace PhaseField
+{
+
+/**
+ * \brief A class to simulate mechanical fracturing process
+ * using phase-field approach in solids described by
+ *
+ * \f[
+ *     \mathrm{div} \left[ \left(d^2 + k \right) \boldsymbol{\sigma}_0^+
+ *      + \boldsymbol{\sigma}_0^- \right] +
+ *        \varrho \boldsymbol{b} = \boldsymbol{0}
+ * \f]
+ * \f[
+ *     2d H(\boldsymbol{\epsilon}_\mathrm{el})
+ *      - \frac{1 - d}{2 \varepsilon} g_\mathrm{c}
+ *      - 2 \varepsilon g_\mathrm{c} \mathrm{div}(\mathrm{grad} d) = 0
+ * \f]
+ * where
+ *    \f{eqnarray*}{
+ *       &d:&                    \mbox{order parameter,}\\
+ *       &\varrho:&              \mbox{density,}\\
+ *       &H:&                    \mbox{history field,}\\
+ *       &g_\mathrm{c}:&         \mbox{fracture energy,}\\
+ *       &\varepsilon:&          \mbox{length scale}\\
+ *    \f}
+ *
+ * Detailed model description can refer
+ * <a href="Miao_Biot2017.pdff" target="_blank"><b>Phase field method</b></a>
+ */
+template <int DisplacementDim>
+class PhaseFieldProcess final : public Process
+{
+    using Base = Process;
+
+public:
+    PhaseFieldProcess(
+        MeshLib::Mesh& mesh,
+        std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&&
+            jacobian_assembler,
+        std::vector<std::unique_ptr<ParameterBase>> const& parameters,
+        unsigned const integration_order,
+        std::vector<std::reference_wrapper<ProcessVariable>>&&
+            process_variables,
+        PhaseFieldProcessData<DisplacementDim>&& process_data,
+        SecondaryVariableCollection&& secondary_variables,
+        NumLib::NamedFunctionCaller&& named_function_caller)
+        : Process(mesh, std::move(jacobian_assembler), parameters,
+                  integration_order, std::move(process_variables),
+                  std::move(secondary_variables),
+                  std::move(named_function_caller)),
+          _process_data(std::move(process_data))
+    {
+    }
+
+    //! \name ODESystem interface
+    //! @{
+
+    bool isLinear() const override { return false; }
+    //! @}
+
+private:
+    using LocalAssemblerInterface = PhaseFieldLocalAssemblerInterface;
+
+    void initializeConcreteProcess(
+        NumLib::LocalToGlobalIndexMap const& dof_table,
+        MeshLib::Mesh const& mesh,
+        unsigned const integration_order) override
+    {
+        ProcessLib::SmallDeformation::createLocalAssemblers<
+                DisplacementDim, PhaseFieldLocalAssembler>(
+                mesh.getElements(), dof_table, _local_assemblers,
+                mesh.isAxiallySymmetric(), integration_order, _process_data);
+
+        // TODO move the two data members somewhere else.
+        // for extrapolation of secondary variables
+        std::vector<MeshLib::MeshSubsets> all_mesh_subsets_single_component;
+        all_mesh_subsets_single_component.emplace_back(
+            _mesh_subset_all_nodes.get());
+        _local_to_global_index_map_single_component.reset(
+            new NumLib::LocalToGlobalIndexMap(
+                std::move(all_mesh_subsets_single_component),
+                // by location order is needed for output
+                NumLib::ComponentOrder::BY_LOCATION));
+
+        Base::_secondary_variables.addSecondaryVariable(
+            "sigma_xx",
+            makeExtrapolator(
+                1, getExtrapolator(), _local_assemblers,
+                &PhaseFieldLocalAssemblerInterface::getIntPtSigmaXX));
+
+        Base::_secondary_variables.addSecondaryVariable(
+            "sigma_yy",
+            makeExtrapolator(
+                1, getExtrapolator(), _local_assemblers,
+                &PhaseFieldLocalAssemblerInterface::getIntPtSigmaYY));
+
+        Base::_secondary_variables.addSecondaryVariable(
+            "sigma_zz",
+            makeExtrapolator(
+                1, getExtrapolator(), _local_assemblers,
+                &PhaseFieldLocalAssemblerInterface::getIntPtSigmaZZ));
+
+        Base::_secondary_variables.addSecondaryVariable(
+            "sigma_xy",
+            makeExtrapolator(
+                1, getExtrapolator(), _local_assemblers,
+                &PhaseFieldLocalAssemblerInterface::getIntPtSigmaXY));
+
+        if (DisplacementDim == 3)
+        {
+            Base::_secondary_variables.addSecondaryVariable(
+                "sigma_xz",
+                makeExtrapolator(
+                    1, getExtrapolator(), _local_assemblers,
+                    &PhaseFieldLocalAssemblerInterface::getIntPtSigmaXZ));
+
+            Base::_secondary_variables.addSecondaryVariable(
+                "sigma_yz",
+                makeExtrapolator(
+                    1, getExtrapolator(), _local_assemblers,
+                    &PhaseFieldLocalAssemblerInterface::getIntPtSigmaYZ));
+        }
+        Base::_secondary_variables.addSecondaryVariable(
+            "epsilon_xx",
+            makeExtrapolator(
+                1, getExtrapolator(), _local_assemblers,
+                &PhaseFieldLocalAssemblerInterface::getIntPtEpsilonXX));
+
+        Base::_secondary_variables.addSecondaryVariable(
+            "epsilon_yy",
+            makeExtrapolator(
+                1, getExtrapolator(), _local_assemblers,
+                &PhaseFieldLocalAssemblerInterface::getIntPtEpsilonYY));
+
+        Base::_secondary_variables.addSecondaryVariable(
+            "epsilon_zz",
+            makeExtrapolator(
+                1, getExtrapolator(), _local_assemblers,
+                &PhaseFieldLocalAssemblerInterface::getIntPtEpsilonZZ));
+
+        Base::_secondary_variables.addSecondaryVariable(
+            "epsilon_xy",
+            makeExtrapolator(
+                1, getExtrapolator(), _local_assemblers,
+                &PhaseFieldLocalAssemblerInterface::getIntPtEpsilonXY));
+        if (DisplacementDim == 3)
+        {
+            Base::_secondary_variables.addSecondaryVariable(
+                "epsilon_yz",
+                makeExtrapolator(1, getExtrapolator(), _local_assemblers,
+                                 &PhaseFieldLocalAssemblerInterface::
+                                     getIntPtEpsilonYZ));
+
+            Base::_secondary_variables.addSecondaryVariable(
+                "epsilon_xz",
+                makeExtrapolator(1, getExtrapolator(), _local_assemblers,
+                                 &PhaseFieldLocalAssemblerInterface::
+                                     getIntPtEpsilonXZ));
+        }
+    }
+
+    void assembleConcreteProcess(
+        const double t, GlobalVector const& x, GlobalMatrix& M, GlobalMatrix& K,
+        GlobalVector& b, StaggeredCouplingTerm const& coupling_term) override
+    {
+        DBUG("Assemble PhaseFieldProcess.");
+
+        // Call global assembler for each local assembly item.
+        GlobalExecutor::executeMemberDereferenced(
+            _global_assembler, &VectorMatrixAssembler::assemble,
+            _local_assemblers, *_local_to_global_index_map, t, x, M, K, b,
+            coupling_term);
+    }
+
+    void assembleWithJacobianConcreteProcess(
+        const double t, GlobalVector const& x, GlobalVector const& xdot,
+        const double dxdot_dx, const double dx_dx, GlobalMatrix& M,
+        GlobalMatrix& K, GlobalVector& b, GlobalMatrix& Jac,
+        StaggeredCouplingTerm const& coupling_term) override
+    {
+        // DBUG("AssembleJacobian PhaseFieldProcess.");
+
+        // Call global assembler for each local assembly item.
+        GlobalExecutor::executeMemberDereferenced(
+            _global_assembler, &VectorMatrixAssembler::assembleWithJacobian,
+            _local_assemblers, *_local_to_global_index_map, t, x, xdot,
+            dxdot_dx, dx_dx, M, K, b, Jac, coupling_term);
+    }
+
+    void preTimestepConcreteProcess(GlobalVector const& x, double const t,
+                                    double const dt) override
+    {
+        DBUG("PreTimestep PhaseFieldProcess.");
+
+        _process_data.dt = dt;
+        _process_data.t = t;
+
+        GlobalExecutor::executeMemberOnDereferenced(
+            &PhaseFieldLocalAssemblerInterface::preTimestep, _local_assemblers,
+            *_local_to_global_index_map, x, t, dt);
+    }
+
+    void postTimestepConcreteProcess(GlobalVector const& x) override
+    {
+        DBUG("PostTimestep PhaseFieldProcess.");
+
+        GlobalExecutor::executeMemberOnDereferenced(
+            &PhaseFieldLocalAssemblerInterface::postTimestep, _local_assemblers,
+            *_local_to_global_index_map, x);
+    }
+
+private:
+    PhaseFieldProcessData<DisplacementDim> _process_data;
+
+    std::vector<std::unique_ptr<LocalAssemblerInterface>> _local_assemblers;
+
+    std::unique_ptr<NumLib::LocalToGlobalIndexMap>
+        _local_to_global_index_map_single_component;
+};
+
+}  // namespace PhaseField
+}  // namespace ProcessLib
diff --git a/ProcessLib/PhaseField/PhaseFieldProcessData.h b/ProcessLib/PhaseField/PhaseFieldProcessData.h
new file mode 100644
index 0000000000000000000000000000000000000000..bea1a24b92ecc4cb4677f482043bf87b41a251fc
--- /dev/null
+++ b/ProcessLib/PhaseField/PhaseFieldProcessData.h
@@ -0,0 +1,82 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2017, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#pragma once
+
+namespace MeshLib
+{
+class Element;
+}
+
+namespace ProcessLib
+{
+namespace PhaseField
+{
+template <int DisplacementDim>
+struct PhaseFieldProcessData
+{
+    PhaseFieldProcessData(
+        std::unique_ptr<MaterialLib::Solids::MechanicsBase<DisplacementDim>>&&
+            material_,
+        Parameter<double> const& residual_stiffness_,
+        Parameter<double> const& crack_resistance_,
+        Parameter<double> const& crack_length_scale_,
+        Parameter<double> const& kinetic_coefficient_,
+        Parameter<double> const& solid_density_,
+        Parameter<double>& history_field_,
+        Eigen::Matrix<double, DisplacementDim, 1> const& specific_body_force_)
+        : material{std::move(material_)},
+          residual_stiffness(residual_stiffness_),
+          crack_resistance(crack_resistance_),
+          crack_length_scale(crack_length_scale_),
+          kinetic_coefficient(kinetic_coefficient_),
+          solid_density(solid_density_),
+          history_field(history_field_),
+          specific_body_force(specific_body_force_)
+    {
+    }
+
+    PhaseFieldProcessData(PhaseFieldProcessData&& other)
+        : material{std::move(other.material)},
+          residual_stiffness(other.residual_stiffness),
+          crack_resistance(other.crack_resistance),
+          crack_length_scale(other.crack_length_scale),
+          kinetic_coefficient(other.kinetic_coefficient),
+          solid_density(other.solid_density),
+          history_field(other.history_field),
+          specific_body_force(other.specific_body_force),
+          dt(other.dt),
+          t(other.t)
+    {
+    }
+
+    //! Copies are forbidden.
+    PhaseFieldProcessData(PhaseFieldProcessData const&) = delete;
+
+    //! Assignments are not needed.
+    void operator=(PhaseFieldProcessData const&) = delete;
+
+    //! Assignments are not needed.
+    void operator=(PhaseFieldProcessData&&) = delete;
+
+    std::unique_ptr<MaterialLib::Solids::MechanicsBase<DisplacementDim>>
+        material;
+    Parameter<double> const& residual_stiffness;
+    Parameter<double> const& crack_resistance;
+    Parameter<double> const& crack_length_scale;
+    Parameter<double> const& kinetic_coefficient;
+    Parameter<double> const& solid_density;
+    Parameter<double>& history_field;
+    Eigen::Matrix<double, DisplacementDim, 1> const& specific_body_force;
+    double dt;
+    double t;
+};
+
+}  // namespace PhaseField
+}  // namespace ProcessLib
diff --git a/ProcessLib/PhaseField/Tests.cmake b/ProcessLib/PhaseField/Tests.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..8a267e8658df4503c2a6029e07c0438d47635fc5
--- /dev/null
+++ b/ProcessLib/PhaseField/Tests.cmake
@@ -0,0 +1,13 @@
+AddTest(
+    NAME PhaseField_3D_Unconfined_Compression
+    PATH PhaseField
+    EXECUTABLE ogs
+    EXECUTABLE_ARGS cube_1e0.prj
+    WRAPPER time
+    TESTER vtkdiff
+    REQUIREMENTS NOT (OGS_USE_LIS OR OGS_USE_MPI)
+    ABSTOL 1e-6 RELTOL 1e-6
+    DIFF_DATA
+    expected_cube_1e0_pcs_0_ts_10000_t_1.000000.vtu cube_1e0_pcs_0_ts_10000_t_1.000000.vtu displacement displacement
+    expected_cube_1e0_pcs_0_ts_10000_t_1.000000.vtu cube_1e0_pcs_0_ts_10000_t_1.000000.vtu phasefield phasefield
+   )
diff --git a/web/content/docs/benchmarks/phase-field/Miao_Biot2017.pdf b/web/content/docs/benchmarks/phase-field/Miao_Biot2017.pdf
new file mode 100755
index 0000000000000000000000000000000000000000..053152c7ecbae216aa541594d7b28e48e73454cf
Binary files /dev/null and b/web/content/docs/benchmarks/phase-field/Miao_Biot2017.pdf differ
diff --git a/web/content/docs/benchmarks/phase-field/beam.png b/web/content/docs/benchmarks/phase-field/beam.png
new file mode 100644
index 0000000000000000000000000000000000000000..1a9bf92fef409308ac9bb976eaeff5fb4e268019
Binary files /dev/null and b/web/content/docs/benchmarks/phase-field/beam.png differ
diff --git a/web/content/docs/benchmarks/phase-field/beam_d.png b/web/content/docs/benchmarks/phase-field/beam_d.png
new file mode 100644
index 0000000000000000000000000000000000000000..8a06309b0455bb898b5558b809489b4c7c5b261b
Binary files /dev/null and b/web/content/docs/benchmarks/phase-field/beam_d.png differ
diff --git a/web/content/docs/benchmarks/phase-field/beam_u.png b/web/content/docs/benchmarks/phase-field/beam_u.png
new file mode 100644
index 0000000000000000000000000000000000000000..1fcd4d021010aed55c5c225b8d8aa3c837c0294b
Binary files /dev/null and b/web/content/docs/benchmarks/phase-field/beam_u.png differ
diff --git a/web/content/docs/benchmarks/phase-field/error_u.png b/web/content/docs/benchmarks/phase-field/error_u.png
new file mode 100644
index 0000000000000000000000000000000000000000..edaa0b050dbb798caabb64f1bbb35be39aeaa476
Binary files /dev/null and b/web/content/docs/benchmarks/phase-field/error_u.png differ
diff --git a/web/content/docs/benchmarks/phase-field/phasefield.md b/web/content/docs/benchmarks/phase-field/phasefield.md
new file mode 100644
index 0000000000000000000000000000000000000000..af1d34b6b75c70f58b3b3f1e61d820acd6c4adc9
--- /dev/null
+++ b/web/content/docs/benchmarks/phase-field/phasefield.md
@@ -0,0 +1,50 @@
++++
+project = "https://github.com/ufz/ogs-data/blob/master/PhaseField/beam3d.prj"
+author = "Xing-Yuan Miao"
+date = "2017-05-19T09:10:33+01:00"
+title = "Crack beam under tension"
+weight = 158
+
+[menu]
+  [menu.benchmarks]
+    parent = "phase-field"
+
++++
+
+{{< project-link >}}
+
+## Problem description
+
+We solve a homogeneous beam model under a given displacement loading. The length of the beam is 2\,mm. Detailed model description can refer [this PDF](../Miao_Biot2017.pdf).
+## Results and evaluation
+
+Results show crack phase-field and displacement field distributions through the length of the beam:
+
+{{< img src="../beam.png" >}}
+{{< img src="../beam_d.png" >}}
+{{< img src="../beam_u.png" >}}
+
+For highlighting the deviation between the analytical and numerical solution, we provide the absolute error of the analytical solution and numerical simulation as follows:
+{{< img src="../error_u.png" >}}
+
+The analytical solution is:
+$$
+\begin{equation}
+d (x) = 1 - {\mathrm{e}}^{\frac{- |x|}{2 \varepsilon}}
+\end{equation}
+$$
+$$
+\begin{equation}
+u (x) = \dfrac{\sigma}{E} \int_0^x \dfrac{1}{d (x)^2 + k} \mathrm{d}x
+\end{equation}
+$$
+with
+$$
+\begin{equation}
+\sigma = \dfrac{E u_0}{I (\varepsilon, k)}
+\end{equation}
+$$
+\begin{equation}
+I (\varepsilon, k) =  \int_0^1  \dfrac{1}{d (x)^2 + k} \mathrm{d}x
+\end{equation}
+$$
\ No newline at end of file