diff --git a/dumux/common/parameters.hh b/dumux/common/parameters.hh
index 12431506d41a4b0648e307a8d5bee8ed8861f809..f06f2d1c2cca33615b7c768387faa18c83042c16 100644
--- a/dumux/common/parameters.hh
+++ b/dumux/common/parameters.hh
@@ -104,7 +104,7 @@
  * \code
  * // -> retrieves global integer value "NumberOfCellsX" which is
  * // located in the parameter group "Grid"
- * GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, int, "Grid.NumberOfCellsX");
+ * GET_RUNTIME_PARAM_CSTRING(TypeTag, int, "Grid.NumberOfCellsX");
  * \endcode
  *
  * Example with a string variable:
@@ -114,7 +114,7 @@
  * // located in the parameter group "Grid"
  * std::string paramName = "Grid";
  * paramName += ".NumberOfCellsX";
- * GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, int, paramName.c_str());
+ * GET_RUNTIME_PARAM_CSTRING(TypeTag, int, paramName.c_str());
  * \endcode
  */
 #define GET_RUNTIME_PARAM_CSTRING(TypeTag, ParamType, ParamName) \
diff --git a/dumux/io/gridcreator.hh b/dumux/io/gridcreator.hh
index 5f42dc44e5c73dafac44793403f9a2fc2c23f316..73ed7c510598b86ce5e1b93b1dcbe04d6e32e2d0 100644
--- a/dumux/io/gridcreator.hh
+++ b/dumux/io/gridcreator.hh
@@ -583,6 +583,255 @@ private:
     }
 };
 
+/*!
+ * \brief Provides a grid creator for YaspGrids with different zones and grading
+ *
+ * All keys are expected to be in group GridParameterGroup.
+ * The following keys are recognized:
+ * - Positions0 : position array for x-coordinate
+ * - Positions1 : position array for y-coordinate
+ * - Positions2 : position array for z-coordinate
+ * - Cells0 : number of cells array for x-coordinate
+ * - Cells1 : number of cells array for y-coordinate
+ * - Cells2 : number of cells array for z-coordinate
+ * - Grading0 : grading factor array for x-coordinate
+ * - Grading1 : grading factor array for y-coordinate
+ * - Grading2 : grading factor array for z-coordinate
+ * - Verbosity : whether the grid construction should output to standard out
+ * - Periodic : true or false for each direction
+ * - Overlap : overlap size in cells
+ * - Partitioning : a non-standard load-balancing, number of processors per direction
+ * - KeepPyhsicalOverlap : whether to keep the physical overlap
+ *     in physical size or in number of cells upon refinement
+ * - Refinement : the number of global refines to apply initially.
+ *
+ * The grading factor \f$ g \f$ specifies the ratio between the next and the current cell size:
+ * \f$ g = \frac{h_{i+1}}{h_i} \f$.
+ * Negative grading factors are converted to
+ * \f$ g = -\frac{1}{g_\textrm{negative}} \f$
+ * to avoid issues with imprecise fraction numbers.
+ */
+template<class TypeTag, class ct, int dim>
+class GridCreatorImpl<TypeTag, Dune::YaspGrid<dim, Dune::TensorProductCoordinates<ct, dim> > >
+          : public GridCreatorBase<TypeTag, Dune::YaspGrid<dim, Dune::TensorProductCoordinates<ct, dim> > >
+{
+public:
+    typedef typename Dune::YaspGrid<dim, Dune::TensorProductCoordinates<ct, dim> > Grid;
+    typedef GridCreatorBase<TypeTag, Grid> ParentType;
+
+    /*!
+     * \brief Make the grid. This is implemented by specializations of this method.
+     */
+    static void makeGrid()
+    {
+        // Only construction from the input file is possible
+        // Look for the necessary keys to construct from the input file
+        try {
+            typedef typename GET_PROP(TypeTag, ParameterTree) Params;
+            auto params = Params::tree();
+            typedef ct Scalar;
+            typedef std::vector<int> IntVector;
+            typedef std::vector<Scalar> ScalarVector;
+
+            // The positions
+            std::array<ScalarVector, dim> positions;
+            for (int i = 0; i < dim; ++i)
+            {
+              std::string paramName = GET_PROP_VALUE(TypeTag, GridParameterGroup);
+              paramName += ".Positions";
+              paramName += std::to_string(i);
+              positions[i] = GET_RUNTIME_PARAM_CSTRING(TypeTag, ScalarVector, paramName.c_str());
+            }
+
+            // the number of cells (has a default)
+            std::array<IntVector, dim> cells;
+            for (int i = 0; i < dim; ++i)
+            {
+              std::string paramName = GET_PROP_VALUE(TypeTag, GridParameterGroup);
+              paramName += ".Cells";
+              paramName += std::to_string(i);
+              try { cells[i] = GET_RUNTIME_PARAM_CSTRING(TypeTag, IntVector, paramName.c_str()); }
+              catch (Dumux::ParameterException &e) { cells[i].resize(positions[i].size()-1, 1.0); }
+            }
+
+            // grading factor (has a default)
+            std::array<ScalarVector, dim> grading;
+            for (int i = 0; i < dim; ++i)
+            {
+              std::string paramName = GET_PROP_VALUE(TypeTag, GridParameterGroup);
+              paramName += ".Grading";
+              paramName += std::to_string(i);
+              try { grading[i] = GET_RUNTIME_PARAM_CSTRING(TypeTag, ScalarVector, paramName.c_str()); }
+              catch (Dumux::ParameterException &e) { grading[i].resize(positions[i].size()-1, 1.0); }
+            }
+
+            // The optional parameters (they have a default)
+            typedef std::bitset<dim> BitSet;
+            BitSet periodic;
+            try { periodic = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, BitSet, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), Periodic);}
+            catch (Dumux::ParameterException &e) { }
+
+            int overlap = 1;
+            try { overlap = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, int, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), Overlap);}
+            catch (Dumux::ParameterException &e) { }
+
+            bool default_lb = false;
+            typedef std::array<int, dim> CellArray;
+            CellArray partitioning;
+            try { partitioning = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, CellArray, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), Partitioning);}
+            catch (Dumux::ParameterException &e) { default_lb = true; }
+
+            //make the grid
+            // sanity check of the input parameters
+            bool verbose = false;
+            try { verbose = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, bool, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), Verbosity);}
+            catch (Dumux::ParameterException &e) {  }
+
+            for (unsigned int dimIdx = 0; dimIdx < dim; ++dimIdx)
+            {
+                if (cells[dimIdx].size() + 1 != positions[dimIdx].size())
+                {
+                    DUNE_THROW(Dune::RangeError, "Make sure to specify correct \"Cells\" and \"Positions\" arrays");
+                }
+                if (grading[dimIdx].size() + 1 != positions[dimIdx].size())
+                {
+                    DUNE_THROW(Dune::RangeError, "Make sure to specify correct \"Grading\" and \"Positions\" arrays");
+                }
+                Scalar temp = std::numeric_limits<Scalar>::lowest();
+                for (unsigned int posIdx = 0; posIdx < positions[dimIdx].size(); ++posIdx)
+                {
+                    if (temp > positions[dimIdx][posIdx])
+                    {
+                        DUNE_THROW(Dune::RangeError, "Make sure to specify a monotone increasing \"Positions\" array");
+                    }
+                    temp = positions[dimIdx][posIdx];
+                }
+            }
+
+            std::array<ScalarVector, dim> globalPositions;
+            for (int dimIdx = 0; dimIdx < dim; dimIdx++)
+            {
+                for (int zoneIdx = 0; zoneIdx < cells[dimIdx].size(); ++zoneIdx)
+                {
+                    Scalar lower = positions[dimIdx][zoneIdx];
+                    Scalar upper = positions[dimIdx][zoneIdx+1];
+                    int numCells = cells[dimIdx][zoneIdx];
+                    Scalar gradingFactor = grading[dimIdx][zoneIdx];
+                    Scalar length = upper - lower;
+                    Scalar height = 1.0;
+                    bool reverse = false;
+
+                    if (verbose)
+                    {
+                        std::cout << "dim " << dimIdx
+                                  << " lower "  << lower
+                                  << " upper "  << upper
+                                  << " numCells "  << numCells
+                                  << " grading "  << gradingFactor;
+                    }
+
+                    if (gradingFactor > 1.0 - 1e-7 && gradingFactor < 1.0 + 1e-7)
+                    {
+                        height = 1.0 / numCells;
+                        if (verbose)
+                        {
+                            std::cout << " -> h "  << height * length << std::endl;
+                        }
+                    }
+                    else
+                    {
+                        if (gradingFactor < -1.0)
+                        {
+                            gradingFactor = -gradingFactor;
+                        }
+                        else if (gradingFactor > 0.0 && gradingFactor < 1.0)
+                        {
+                            gradingFactor = 1.0 / gradingFactor;
+                        }
+                        else if (gradingFactor > 1.0)
+                        {
+                            reverse = true;
+                        }
+                        else
+                        {
+                            DUNE_THROW(Dune::NotImplemented, "This grading factor is not implemented.");
+                        }
+                        height = (1.0 - gradingFactor) / (1.0 - std::pow(gradingFactor, numCells));
+
+                        if (verbose)
+                        {
+                            std::cout << " -> grading_eff "  << gradingFactor
+                                      << " h_min "  << height * std::pow(gradingFactor, 0) * length
+                                      << " h_max "  << height * std::pow(gradingFactor, numCells-1) * length
+                                      << std::endl;
+                        }
+                    }
+
+                    std::vector<Scalar> localPositions;
+                    localPositions.push_back(0);
+                    for (int i = 0; i < numCells-1; i++)
+                    {
+                        Scalar hI = height;
+                        if (!(gradingFactor < 1.0 + 1e-7 && gradingFactor > 1.0 - 1e-7))
+                        {
+                            if (reverse)
+                            {
+                                hI *= std::pow(gradingFactor, i);
+                            }
+                            else
+                            {
+                                hI *= std::pow(gradingFactor, numCells-i-1);
+                            }
+                        }
+                        localPositions.push_back(localPositions[i] + hI);
+                    }
+
+                    for (int i = 0; i < localPositions.size(); i++)
+                    {
+                        localPositions[i] *= length;
+                        localPositions[i] += lower;
+                    }
+
+
+                    for (unsigned int i = 0; i < localPositions.size(); ++i)
+                    {
+                        globalPositions[dimIdx].push_back(localPositions[i]);
+                    }
+                }
+                globalPositions[dimIdx].push_back(positions[dimIdx].back());
+            }
+
+            if (default_lb)
+                ParentType::gridPtr() = std::make_shared<Grid>(globalPositions, periodic, overlap);
+            else
+            {
+                typename Dune::YaspFixedSizePartitioner<dim> lb(partitioning);
+                ParentType::gridPtr() = std::make_shared<Grid>(globalPositions, periodic, overlap, typename Grid::CollectiveCommunicationType(), &lb);
+            }
+            postProcessing_();
+        }
+        catch (Dumux::ParameterException &e) {
+                DUNE_THROW(Dumux::ParameterException, "Please supply the mandatory parameters:" << std::endl
+                                              << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".Positions0, ..." << std::endl);
+        }
+        catch (...) { throw; }
+    }
+
+private:
+    /*!
+     * \brief Postprocessing for YaspGrid
+     */
+    static void postProcessing_()
+    {
+        // Check if should refine the grid
+        bool keepPhysicalOverlap = true;
+        try { keepPhysicalOverlap = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, bool, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), KeepPhysicalOverlap);}
+        catch (Dumux::ParameterException &e) { }
+        ParentType::grid().refineOptions(keepPhysicalOverlap);
+        ParentType::maybeRefineGrid();
+    }
+};
+
 /*!
  * \brief Provides a grid creator for OneDGrids
  *        from information in the input file
@@ -1093,7 +1342,6 @@ public:
 
 #endif // HAVE_ALBERTA
 
-// TODO support Yasp Tensor Product Grid
 // TODO Petrel grids with dune-cornerpoint
 
 } // namespace Dumux