From 7ec17dfd796c00de484c96e57872f79ff2482e7c Mon Sep 17 00:00:00 2001
From: Henry <Henry>
Date: Tue, 3 Feb 2015 12:01:55 +0000
Subject: [PATCH] blockMesh: Add support for multi/sectional grading in a block

Consider a block describing a channel with two opposite walls.
Currently in order to grade the mesh towards the walls and have a
uniform region in the centre the channel would need to be spit into 3
blocks.  With the new multi/sectional grading this can be achieved in a
single block e.g.

blocks
(
    hex (0 1 2 3 4 5 6 7) (20 60 20)
    simpleGrading
    (
        1
        ((0.2 0.3 4) (0.6 0.4 1) (0.2 0.3 0.25))
        1
    )
);

In this example the block is divided uniformly in the x and z -directions
and split into three grading sections in the y-direction described by
three triples:  ((0.2 0.3 4) (0.6 0.4 1) (0.2 0.3 0.25)).  Each of the
grading sections is described by a triple consisting of the fraction of
the block, the fraction of the divisions and the grading ratio (size of
first division/size of last division).  Both the fraction of the block
and the fraction of the divisions are normalized automatically so they
can be specified scaled in anyway, e.g. as percentages:

blocks
(
    hex (0 1 2 3 4 5 6 7) (20 60 20)
    simpleGrading
    (
        1
        ((2 3 4) (6 4 1) (2 3 0.25))
        1
    )
);

and they need not sum to 1 or 100.

This is very new functionality and not well tested but backward
compatibility has been well tested so all existing blockMeshDicts should
parse correctly.
---
 src/mesh/blockMesh/Make/files                 |   3 +
 .../blockDescriptor/blockDescriptor.C         |  12 +-
 .../blockDescriptor/blockDescriptor.H         |   8 +-
 .../blockDescriptor/blockDescriptorEdges.C    |  58 ++-----
 src/mesh/blockMesh/curvedEdges/lineDivide.C   |  82 +++++++--
 src/mesh/blockMesh/curvedEdges/lineDivide.H   |   7 +-
 .../gradingDescriptor/gradingDescriptor.C     | 151 +++++++++++++++++
 .../gradingDescriptor/gradingDescriptor.H     | 157 ++++++++++++++++++
 .../gradingDescriptor/gradingDescriptors.C    | 101 +++++++++++
 .../gradingDescriptor/gradingDescriptors.H    |  94 +++++++++++
 10 files changed, 606 insertions(+), 67 deletions(-)
 create mode 100644 src/mesh/blockMesh/gradingDescriptor/gradingDescriptor.C
 create mode 100644 src/mesh/blockMesh/gradingDescriptor/gradingDescriptor.H
 create mode 100644 src/mesh/blockMesh/gradingDescriptor/gradingDescriptors.C
 create mode 100644 src/mesh/blockMesh/gradingDescriptor/gradingDescriptors.H

diff --git a/src/mesh/blockMesh/Make/files b/src/mesh/blockMesh/Make/files
index 28410a11415..123b6510bf4 100644
--- a/src/mesh/blockMesh/Make/files
+++ b/src/mesh/blockMesh/Make/files
@@ -10,6 +10,9 @@ curvedEdges/lineDivide.C
 curvedEdges/BSplineEdge.C
 curvedEdges/splineEdge.C
 
+gradingDescriptor/gradingDescriptor.C
+gradingDescriptor/gradingDescriptors.C
+
 blockDescriptor/blockDescriptor.C
 blockDescriptor/blockDescriptorEdges.C
 
diff --git a/src/mesh/blockMesh/blockDescriptor/blockDescriptor.C b/src/mesh/blockMesh/blockDescriptor/blockDescriptor.C
index 7fd7ad315b4..458015af3a4 100644
--- a/src/mesh/blockMesh/blockDescriptor/blockDescriptor.C
+++ b/src/mesh/blockMesh/blockDescriptor/blockDescriptor.C
@@ -34,7 +34,7 @@ Foam::blockDescriptor::blockDescriptor
     const pointField& blockPointField,
     const curvedEdgeList& edges,
     const Vector<label>& meshDensity,
-    const UList<scalar>& expand,
+    const UList<gradingDescriptors>& expand,
     const word& zoneName
 )
 :
@@ -77,7 +77,11 @@ Foam::blockDescriptor::blockDescriptor
     meshDensity_(),
     edgePoints_(12),
     edgeWeights_(12),
-    expand_(12, 1.0),
+    expand_
+    (
+        12,
+        gradingDescriptors()
+    ),
     zoneName_()
 {
     // Examine next token
@@ -126,7 +130,7 @@ Foam::blockDescriptor::blockDescriptor
         is.putBack(t);
     }
 
-    scalarList expRatios(is);
+    List<gradingDescriptors> expRatios(is);
 
     if (expRatios.size() == 1)
     {
@@ -273,7 +277,7 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const blockDescriptor& bd)
         << " simpleGrading (";
 
 
-    const scalarList& expand = bd.expand_;
+    const List<gradingDescriptors>& expand = bd.expand_;
 
     // can we use a compact notation?
     if
diff --git a/src/mesh/blockMesh/blockDescriptor/blockDescriptor.H b/src/mesh/blockMesh/blockDescriptor/blockDescriptor.H
index b99d6786f4a..9d77b5f7006 100644
--- a/src/mesh/blockMesh/blockDescriptor/blockDescriptor.H
+++ b/src/mesh/blockMesh/blockDescriptor/blockDescriptor.H
@@ -41,6 +41,7 @@ SourceFiles
 #include "pointField.H"
 #include "scalarList.H"
 #include "curvedEdgeList.H"
+#include "gradingDescriptors.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -51,7 +52,6 @@ class Istream;
 class Ostream;
 
 // Forward declaration of friend functions and operators
-class blockMesh;
 class blockDescriptor;
 Ostream& operator<<(Ostream&, const blockDescriptor&);
 
@@ -82,11 +82,12 @@ class blockDescriptor
         scalarListList edgeWeights_;
 
         //- Expansion ratios in all directions
-        scalarList expand_;
+        List<gradingDescriptors> expand_;
 
         //- Name of the zone (empty string if none)
         word zoneName_;
 
+
     // Private Member Functions
 
         //- Set the points/weights for all edges
@@ -113,7 +114,7 @@ public:
             const pointField& blockPointField,
             const curvedEdgeList&,
             const Vector<label>& meshDensity,
-            const UList<scalar>& expand,
+            const UList<gradingDescriptors>& expand,
             const word& zoneName = ""
         );
 
@@ -159,7 +160,6 @@ public:
         //- Return the (optional) zone name
         const word& zoneName() const;
 
-
         //- Return the number of points
         label nPoints() const;
 
diff --git a/src/mesh/blockMesh/blockDescriptor/blockDescriptorEdges.C b/src/mesh/blockMesh/blockDescriptor/blockDescriptorEdges.C
index 30fc5dfe3e5..e35e9ee7645 100644
--- a/src/mesh/blockMesh/blockDescriptor/blockDescriptorEdges.C
+++ b/src/mesh/blockMesh/blockDescriptor/blockDescriptorEdges.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -23,27 +23,10 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "error.H"
 #include "blockDescriptor.H"
-
 #include "lineEdge.H"
 #include "lineDivide.H"
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-    //! \cond fileScope
-    //  Calculate the geometric expension factor from the expansion ratio
-    inline scalar calcGexp(const scalar expRatio, const label dim)
-    {
-        return dim > 1 ? pow(expRatio, 1.0/(dim - 1)) : 0.0;
-    }
-    //! \endcond
-
-} // End namespace Foam
-
-
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
 void Foam::blockDescriptor::makeBlockEdges()
@@ -52,21 +35,21 @@ void Foam::blockDescriptor::makeBlockEdges()
     const label nj = meshDensity_.y();
     const label nk = meshDensity_.z();
 
-    // these edges correspond to the "hex" cellModel
+    // These edges correspond to the "hex" cellModel
 
-    // x-direction
+    // X-direction
     setEdge(0,  0, 1, ni);
     setEdge(1,  3, 2, ni);
     setEdge(2,  7, 6, ni);
     setEdge(3,  4, 5, ni);
 
-    // y-direction
+    // Y-direction
     setEdge(4,  0, 3, nj);
     setEdge(5,  1, 2, nj);
     setEdge(6,  5, 6, nj);
     setEdge(7,  4, 7, nj);
 
-    // z-direction
+    // Z-direction
     setEdge(8,  0, 4, nk);
     setEdge(9,  1, 5, nk);
     setEdge(10, 2, 6, nk);
@@ -79,21 +62,18 @@ void Foam::blockDescriptor::setEdge
     label edgeI,
     label start,
     label end,
-    label dim
+    label nDiv
 )
 {
-    // set reference to the list of labels defining the block
+    // Set reference to the list of labels defining the block
     const labelList& blockLabels = blockShape_;
 
-    // set reference to global list of points
+    // Set reference to global list of points
     const pointField blockPoints = blockShape_.points(blockPointField_);
 
     // Set the edge points/weights
     // The edge is a straight-line if it is not in the list of curvedEdges
 
-    // calc geometric expension factor from the expansion ratio
-    const scalar gExp = calcGexp(expand_[edgeI], dim);
-
     forAll(curvedEdges_, cedgeI)
     {
         const curvedEdge& cedge = curvedEdges_[cedgeI];
@@ -104,20 +84,20 @@ void Foam::blockDescriptor::setEdge
         {
             if (cmp > 0)
             {
-                // curve has the same orientation
+                // Curve has the same orientation
 
-                // divide the line
-                lineDivide divEdge(cedge, dim, gExp);
+                // Divide the line
+                lineDivide divEdge(cedge, nDiv, expand_[edgeI]);
 
                 edgePoints_[edgeI]  = divEdge.points();
                 edgeWeights_[edgeI] = divEdge.lambdaDivisions();
             }
             else
             {
-                // curve has the opposite orientation
+                // Curve has the opposite orientation
 
-                // divide the line
-                lineDivide divEdge(cedge, dim, 1.0/(gExp+SMALL));
+                // Divide the line
+                lineDivide divEdge(cedge, nDiv, expand_[edgeI].inv());
 
                 const pointField& p = divEdge.points();
                 const scalarList& d = divEdge.lambdaDivisions();
@@ -131,22 +111,20 @@ void Foam::blockDescriptor::setEdge
                     edgePoints_[edgeI][pI]  = p[pMax - pI];
                     edgeWeights_[edgeI][pI] = 1.0 - d[pMax - pI];
                 }
-
             }
 
-            // found curved-edge: done
+            // Found curved-edge: done
             return;
         }
     }
 
 
-    // not found: divide the edge as a straight line
-
+    // Not curved-edge: divide the edge as a straight line
     lineDivide divEdge
     (
         lineEdge(blockPoints, start, end),
-        dim,
-        gExp
+        nDiv,
+        expand_[edgeI]
     );
 
     edgePoints_[edgeI]  = divEdge.points();
diff --git a/src/mesh/blockMesh/curvedEdges/lineDivide.C b/src/mesh/blockMesh/curvedEdges/lineDivide.C
index 28c9e8c0697..7ac372c47d4 100644
--- a/src/mesh/blockMesh/curvedEdges/lineDivide.C
+++ b/src/mesh/blockMesh/curvedEdges/lineDivide.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -23,45 +23,95 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "error.H"
-
 #include "lineDivide.H"
 #include "curvedEdge.H"
 
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    //- Calculate the geometric expension factor from the expansion ratio
+    inline scalar calcGexp(const scalar expRatio, const label nDiv)
+    {
+        return nDiv > 1 ? pow(expRatio, 1.0/(nDiv - 1)) : 0.0;
+    }
+}
+
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 Foam::lineDivide::lineDivide
 (
     const curvedEdge& cedge,
-    const label ndiv,
-    const scalar xratio
+    const label nDiv,
+    const gradingDescriptors& gd
 )
 :
-    points_(ndiv + 1),
-    divisions_(ndiv + 1)
+    points_(nDiv + 1),
+    divisions_(nDiv + 1)
 {
     divisions_[0]    = 0.0;
-    divisions_[ndiv] = 1.0;
+    divisions_[nDiv] = 1.0;
 
-    // calculate the spacing
-    if (xratio == 1.0)
+    scalar secStart = divisions_[0];
+    label secnStart = 1;
+
+    // Check that there are more divisions than sections
+    if (nDiv >= gd.size())
     {
-        for (label i=1; i < ndiv; i++)
+        forAll(gd, sectioni)
         {
-            divisions_[i] = scalar(i)/ndiv;
+            scalar blockFrac = gd[sectioni].blockFraction();
+            scalar nDivFrac = gd[sectioni].nDivFraction();
+            scalar expRatio = gd[sectioni].expansionRatio();
+
+            label secnDiv = label(nDivFrac*nDiv + 0.5);
+            if (sectioni == gd.size() - 1)
+            {
+                secnDiv = nDiv - secnStart + 1;
+            }
+            label secnEnd = secnStart + secnDiv;
+
+            // Calculate the spacing
+            if (expRatio == 1.0)
+            {
+                for (label i = secnStart; i < secnEnd; i++)
+                {
+                    divisions_[i] =
+                        secStart
+                      + blockFrac*scalar(i - secnStart + 1)/secnDiv;
+                }
+            }
+            else
+            {
+                // Calculate geometric expansion factor from the expansion ratio
+                const scalar expFact = calcGexp(expRatio, secnDiv);
+
+                for (label i = secnStart; i < secnEnd; i++)
+                {
+                    divisions_[i] =
+                        secStart
+                      + blockFrac*(1.0 - pow(expFact, i - secnStart + 1))
+                    /(1.0 - pow(expFact, secnDiv));
+                }
+            }
+
+            secStart = divisions_[secnEnd - 1];
+            secnStart = secnEnd;
         }
     }
+    // Otherwise mesh uniformly
     else
     {
-        for (label i=1; i < ndiv; i++)
+        for (label i=1; i < nDiv; i++)
         {
-            divisions_[i] = (1.0 - pow(xratio, i))/(1.0 - pow(xratio, ndiv));
+            divisions_[i] = scalar(i)/nDiv;
         }
     }
 
-    // calculate the points
-    for (label i=0; i <= ndiv; i++)
+
+    // Calculate the points
+    for (label i = 0; i <= nDiv; i++)
     {
         points_[i] = cedge.position(divisions_[i]);
     }
diff --git a/src/mesh/blockMesh/curvedEdges/lineDivide.H b/src/mesh/blockMesh/curvedEdges/lineDivide.H
index d46ec74bee5..bd642bc617a 100644
--- a/src/mesh/blockMesh/curvedEdges/lineDivide.H
+++ b/src/mesh/blockMesh/curvedEdges/lineDivide.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -37,6 +37,7 @@ SourceFiles
 
 #include "pointField.H"
 #include "scalarList.H"
+#include "gradingDescriptors.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -61,12 +62,12 @@ public:
 
     // Constructors
 
-        //- Construct from components with discretization and expansion ratio
+        //- Construct from components
         lineDivide
         (
             const curvedEdge&,
             const label ndiv,
-            const scalar xratio = 1.0
+            const gradingDescriptors& gd = gradingDescriptors()
         );
 
 
diff --git a/src/mesh/blockMesh/gradingDescriptor/gradingDescriptor.C b/src/mesh/blockMesh/gradingDescriptor/gradingDescriptor.C
new file mode 100644
index 00000000000..a098d9d9aff
--- /dev/null
+++ b/src/mesh/blockMesh/gradingDescriptor/gradingDescriptor.C
@@ -0,0 +1,151 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM 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 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM 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 OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "gradingDescriptor.H"
+#include "IOstream.H"
+#include "token.H"
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::gradingDescriptor::gradingDescriptor()
+:
+    blockFraction_(1),
+    nDivFraction_(1),
+    expansionRatio_(1)
+{}
+
+
+Foam::gradingDescriptor::gradingDescriptor
+(
+    const scalar blockFraction,
+    const scalar nDivFraction,
+    const scalar expansionRatio
+)
+:
+    blockFraction_(blockFraction),
+    nDivFraction_(nDivFraction),
+    expansionRatio_(expansionRatio)
+{}
+
+
+Foam::gradingDescriptor::gradingDescriptor
+(
+    const scalar expansionRatio
+)
+:
+    blockFraction_(1.0),
+    nDivFraction_(1.0),
+    expansionRatio_(expansionRatio)
+{}
+
+
+Foam::gradingDescriptor::gradingDescriptor(Istream& is)
+{
+    is >> *this;
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::gradingDescriptor::~gradingDescriptor()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+Foam::gradingDescriptor Foam::gradingDescriptor::inv() const
+{
+    return gradingDescriptor
+    (
+        blockFraction_,
+        nDivFraction_,
+        1.0/expansionRatio_
+    );
+}
+
+
+// * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
+
+bool Foam::gradingDescriptor::operator==(const gradingDescriptor& gd) const
+{
+    return
+        equal(blockFraction_, gd.blockFraction_)
+     && equal(nDivFraction_, gd.nDivFraction_)
+     && equal(expansionRatio_, gd.expansionRatio_);
+}
+
+
+bool Foam::gradingDescriptor::operator!=(const gradingDescriptor& gd) const
+{
+    return !operator==(gd);
+}
+
+
+// * * * * * * * * * * * * * * * Friend Operators  * * * * * * * * * * * * * //
+
+Foam::Istream& Foam::operator>>(Istream& is, gradingDescriptor& gd)
+{
+    // Examine next token
+    token t(is);
+
+    if (t.isNumber())
+    {
+        gd.blockFraction_ = 1.0;
+        gd.nDivFraction_ = 1.0;
+        gd.expansionRatio_ = t.number();
+    }
+    else if (t.isPunctuation() && t.pToken() == token::BEGIN_LIST)
+    {
+        is >> gd.blockFraction_ >> gd.nDivFraction_ >> gd.expansionRatio_;
+        is.readEnd("gradingDescriptor");
+    }
+
+    // Check state of Istream
+    is.check("operator>>(Istream&, gradingDescriptor&)");
+
+    return is;
+}
+
+
+Foam::Ostream& Foam::operator<<(Ostream& os, const gradingDescriptor& gd)
+{
+    if (equal(gd.blockFraction_, 1.0))
+    {
+        os  << gd.expansionRatio_;
+    }
+    else
+    {
+        os  << token::BEGIN_LIST
+            << gd.blockFraction_ << token::SPACE
+            << gd.nDivFraction_ << token::SPACE
+            << gd.expansionRatio_
+            << token::END_LIST;
+    }
+
+    return os;
+}
+
+
+// ************************************************************************* //
diff --git a/src/mesh/blockMesh/gradingDescriptor/gradingDescriptor.H b/src/mesh/blockMesh/gradingDescriptor/gradingDescriptor.H
new file mode 100644
index 00000000000..e021f63a6eb
--- /dev/null
+++ b/src/mesh/blockMesh/gradingDescriptor/gradingDescriptor.H
@@ -0,0 +1,157 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM 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 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM 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 OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::gradingDescriptor
+
+Description
+    Handles the specification for grading within a section of a block
+
+    blockFraction: the fraction of the block the section occupies
+
+    nDivFraction: the fraction of the divisions of the block allocated to
+        the section
+
+    expansionRatio: the expansions ratio for the grading with the section of
+        block defined as the ratio of the size of the division at either and
+        of the section.
+
+SourceFiles
+    gradingDescriptor.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef gradingDescriptor_H
+#define gradingDescriptor_H
+
+#include "scalar.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+class Istream;
+class Ostream;
+
+// Forward declaration of friend functions and operators
+class gradingDescriptor;
+class gradingDescriptors;
+Istream& operator>>(Istream&, gradingDescriptor&);
+Ostream& operator<<(Ostream&, const gradingDescriptor&);
+
+/*---------------------------------------------------------------------------*\
+                     Class gradingDescriptor Declaration
+\*---------------------------------------------------------------------------*/
+
+class gradingDescriptor
+{
+    // Private data
+
+        scalar blockFraction_;
+        scalar nDivFraction_;
+        scalar expansionRatio_;
+
+
+public:
+
+    friend class gradingDescriptors;
+
+
+    // Constructors
+
+        //- Default constructor
+        gradingDescriptor();
+
+        //- Construct from components
+        gradingDescriptor
+        (
+            const scalar blockFraction,
+            const scalar nDivFraction,
+            const scalar expansionRatio
+        );
+
+        //- Construct from expansionRatio
+        gradingDescriptor
+        (
+            const scalar expansionRatio
+        );
+
+        //- Construct from Istream
+        gradingDescriptor(Istream&);
+
+
+    //- Destructor
+    ~gradingDescriptor();
+
+
+    // Member Functions
+
+        // Access
+
+            scalar blockFraction() const
+            {
+                return blockFraction_;
+            }
+
+            scalar nDivFraction() const
+            {
+                return nDivFraction_;
+            }
+
+            scalar expansionRatio() const
+            {
+                return expansionRatio_;
+            }
+
+
+    // Member functions
+
+        //- Return the inverse gradingDescriptor with 1/expansionRatio
+        gradingDescriptor inv() const;
+
+
+    // Member operators
+
+        bool operator==(const gradingDescriptor&) const;
+        bool operator!=(const gradingDescriptor&) const;
+
+
+    // IOstream Operators
+
+        friend Istream& operator>>(Istream&, gradingDescriptor&);
+        friend Ostream& operator<<(Ostream&, const gradingDescriptor&);
+
+        friend Istream& operator>>(Istream&, gradingDescriptors&);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/mesh/blockMesh/gradingDescriptor/gradingDescriptors.C b/src/mesh/blockMesh/gradingDescriptor/gradingDescriptors.C
new file mode 100644
index 00000000000..5284deacc0b
--- /dev/null
+++ b/src/mesh/blockMesh/gradingDescriptor/gradingDescriptors.C
@@ -0,0 +1,101 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM 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 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM 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 OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "gradingDescriptors.H"
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::gradingDescriptors::gradingDescriptors()
+:
+    List<gradingDescriptor>(1, gradingDescriptor())
+{}
+
+
+Foam::gradingDescriptors::gradingDescriptors(const gradingDescriptor& gd)
+:
+    List<gradingDescriptor>(1, gd)
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+Foam::gradingDescriptors Foam::gradingDescriptors::inv() const
+{
+    gradingDescriptors ret(*this);
+
+    forAll(ret, i)
+    {
+        ret[i] = operator[](i).inv();
+    }
+
+    return ret;
+}
+
+
+// * * * * * * * * * * * * * * * Friend Operators  * * * * * * * * * * * * * //
+
+Foam::Istream& Foam::operator>>(Istream& is, gradingDescriptors& gds)
+{
+    // Examine next token
+    token t(is);
+
+    if (t.isNumber())
+    {
+        gds = gradingDescriptors(gradingDescriptor(t.number()));
+    }
+    else
+    {
+        is.putBack(t);
+
+        // Read the list for gradingDescriptors
+        is >> static_cast<List<gradingDescriptor>& >(gds);
+
+        // Check state of Istream
+        is.check("operator>>(Istream&, gradingDescriptor&)");
+
+        // Normalize the blockFractions and nDivFractions
+        // of the list of gradingDescriptors
+
+        scalar sumBlockFraction = 0;
+        scalar sumNDivFraction = 0;
+
+        forAll(gds, i)
+        {
+            sumBlockFraction += gds[i].blockFraction_;
+            sumNDivFraction += gds[i].nDivFraction_;
+        }
+
+        forAll(gds, i)
+        {
+            gds[i].blockFraction_ /= sumBlockFraction;
+            gds[i].nDivFraction_ /= sumNDivFraction;
+        }
+    }
+
+    return is;
+}
+
+
+// ************************************************************************* //
diff --git a/src/mesh/blockMesh/gradingDescriptor/gradingDescriptors.H b/src/mesh/blockMesh/gradingDescriptor/gradingDescriptors.H
new file mode 100644
index 00000000000..aa98228bea1
--- /dev/null
+++ b/src/mesh/blockMesh/gradingDescriptor/gradingDescriptors.H
@@ -0,0 +1,94 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM 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 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM 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 OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::gradingDescriptors
+
+Description
+    List of gradingDescriptor for the sections of a block with additional IO
+    functionality
+
+SourceFiles
+    gradingDescriptors.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef gradingDescriptors_H
+#define gradingDescriptors_H
+
+#include "gradingDescriptor.H"
+#include "List.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+class Istream;
+class Ostream;
+
+// Forward declaration of friend functions and operators
+class gradingDescriptors;
+Istream& operator>>(Istream&, gradingDescriptors&);
+
+/*---------------------------------------------------------------------------*\
+                     Class gradingDescriptors Declaration
+\*---------------------------------------------------------------------------*/
+
+class gradingDescriptors
+:
+    public List<gradingDescriptor>
+{
+
+public:
+
+    // Constructors
+
+        //- Default constructor
+        gradingDescriptors();
+
+        //- Construct from a gradingDescriptor
+        gradingDescriptors(const gradingDescriptor& gd);
+
+
+    // Member functions
+
+        //- Return the inverse gradingDescriptors with 1/expansionRatio
+        gradingDescriptors inv() const;
+
+
+    // IOstream Operators
+
+        friend Istream& operator>>(Istream&, gradingDescriptors&);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
-- 
GitLab