From 7694ad7e814587748a39e1506fcfa964fe97067d Mon Sep 17 00:00:00 2001
From: andy <andy>
Date: Tue, 30 Jul 2013 16:02:50 +0100
Subject: [PATCH] ENH: fieldAverage - extended to include surface fields

---
 .../fieldAverage/fieldAverage/fieldAverage.C  | 166 ++-----
 .../fieldAverage/fieldAverage/fieldAverage.H  |  90 ++--
 .../fieldAverage/fieldAverageTemplates.C      | 458 ++++++++++--------
 .../fieldAverageItem/fieldAverageItem.C       |  12 +
 .../fieldAverageItem/fieldAverageItem.H       |  55 +++
 .../fieldAverageItem/fieldAverageItemIO.C     |  24 +
 6 files changed, 435 insertions(+), 370 deletions(-)

diff --git a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.C b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.C
index e8f58c370e6..b541295c550 100644
--- a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.C
+++ b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.C
@@ -34,114 +34,62 @@ License
 namespace Foam
 {
 defineTypeNameAndDebug(fieldAverage, 0);
-
-const word fieldAverage::EXT_MEAN = "Mean";
-const word fieldAverage::EXT_PRIME2MEAN = "Prime2Mean";
 }
 
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-void Foam::fieldAverage::resetFields(wordList& names)
+void Foam::fieldAverage::resetFields()
 {
-    forAll(names, fieldI)
+    forAll(faItems_, i)
     {
-        if (names[fieldI].size())
+        if (faItems_[i].mean())
         {
-            obr_.checkOut(*obr_[names[fieldI]]);
+            if (obr_.found(faItems_[i].meanFieldName()))
+            {
+                obr_.checkOut(*obr_[faItems_[i].meanFieldName()]);
+            }
+        }
+        if (faItems_[i].prime2Mean())
+        {
+            if (obr_.found(faItems_[i].prime2MeanFieldName()))
+            {
+                obr_.checkOut(*obr_[faItems_[i].prime2MeanFieldName()]);
+            }
         }
     }
-
-    names.clear();
-    names.setSize(faItems_.size());
 }
 
 
 void Foam::fieldAverage::initialize()
 {
-    resetFields(meanScalarFields_);
-    resetFields(meanVectorFields_);
-    resetFields(meanSphericalTensorFields_);
-    resetFields(meanSymmTensorFields_);
-    resetFields(meanTensorFields_);
-
-    resetFields(prime2MeanScalarFields_);
-    resetFields(prime2MeanSymmTensorFields_);
+    resetFields();
 
 
     // Add mean fields to the field lists
     forAll(faItems_, fieldI)
     {
-        const word& fieldName = faItems_[fieldI].fieldName();
-        if (obr_.foundObject<volScalarField>(fieldName))
-        {
-            addMeanField<scalar>(fieldI, meanScalarFields_);
-        }
-        else if (obr_.foundObject<volVectorField>(fieldName))
-        {
-            addMeanField<vector>(fieldI, meanVectorFields_);
-        }
-        else if (obr_.foundObject<volSphericalTensorField>(fieldName))
-        {
-            addMeanField<sphericalTensor>(fieldI, meanSphericalTensorFields_);
-        }
-        else if (obr_.foundObject<volSymmTensorField>(fieldName))
-        {
-            addMeanField<symmTensor>(fieldI, meanSymmTensorFields_);
-        }
-        else if (obr_.foundObject<volTensorField>(fieldName))
-        {
-            addMeanField<tensor>(fieldI, meanTensorFields_);
-        }
-        else
-        {
-            FatalErrorIn("Foam::fieldAverage::initialize()")
-                << "Requested field " << faItems_[fieldI].fieldName()
-                << " does not exist in the database" << nl
-                << exit(FatalError);
-        }
+        addMeanField<scalar>(fieldI);
+        addMeanField<vector>(fieldI);
+        addMeanField<sphericalTensor>(fieldI);
+        addMeanField<symmTensor>(fieldI);
+        addMeanField<tensor>(fieldI);
     }
 
     // Add prime-squared mean fields to the field lists
     forAll(faItems_, fieldI)
     {
-        if (faItems_[fieldI].prime2Mean())
-        {
-            const word& fieldName = faItems_[fieldI].fieldName();
-            if (!faItems_[fieldI].mean())
-            {
-                FatalErrorIn("Foam::fieldAverage::initialize()")
-                    << "To calculate the prime-squared average, the "
-                    << "mean average must also be selected for field "
-                    << fieldName << nl << exit(FatalError);
-            }
+        addPrime2MeanField<scalar, scalar>(fieldI);
+        addPrime2MeanField<vector, symmTensor>(fieldI);
+    }
 
-            if (obr_.foundObject<volScalarField>(fieldName))
-            {
-                addPrime2MeanField<scalar, scalar>
-                (
-                    fieldI,
-                    meanScalarFields_,
-                    prime2MeanScalarFields_
-                );
-            }
-            else if (obr_.foundObject<volVectorField>(fieldName))
-            {
-                addPrime2MeanField<vector, symmTensor>
-                (
-                    fieldI,
-                    meanVectorFields_,
-                    prime2MeanSymmTensorFields_
-                );
-            }
-            else
-            {
-                FatalErrorIn("Foam::fieldAverage::initialize()")
-                    << "prime2Mean average can only be applied to "
-                    << "volScalarFields and volVectorFields"
-                    << nl << "    Field: " << fieldName << nl
-                    << exit(FatalError);
-            }
+    forAll(faItems_, fieldI)
+    {
+        if (!faItems_[fieldI].active())
+        {
+            WarningIn("void Foam::fieldAverage::initialize()")
+                << "Field " << faItems_[fieldI].fieldName()
+                << " not found in database for averaging";
         }
     }
 
@@ -173,33 +121,17 @@ void Foam::fieldAverage::calcAverages()
 
     Info<< "Calculating averages" << nl << endl;
 
-    addMeanSqrToPrime2Mean<scalar, scalar>
-    (
-        meanScalarFields_,
-        prime2MeanScalarFields_
-    );
-    addMeanSqrToPrime2Mean<vector, symmTensor>
-    (
-        meanVectorFields_,
-        prime2MeanSymmTensorFields_
-    );
+    addMeanSqrToPrime2Mean<scalar, scalar>();
+    addMeanSqrToPrime2Mean<vector, symmTensor>();
 
-    calculateMeanFields<scalar>(meanScalarFields_);
-    calculateMeanFields<vector>(meanVectorFields_);
-    calculateMeanFields<sphericalTensor>(meanSphericalTensorFields_);
-    calculateMeanFields<symmTensor>(meanSymmTensorFields_);
-    calculateMeanFields<tensor>(meanTensorFields_);
+    calculateMeanFields<scalar>();
+    calculateMeanFields<vector>();
+    calculateMeanFields<sphericalTensor>();
+    calculateMeanFields<symmTensor>();
+    calculateMeanFields<tensor>();
 
-    calculatePrime2MeanFields<scalar, scalar>
-    (
-        meanScalarFields_,
-        prime2MeanScalarFields_
-    );
-    calculatePrime2MeanFields<vector, symmTensor>
-    (
-        meanVectorFields_,
-        prime2MeanSymmTensorFields_
-    );
+    calculatePrime2MeanFields<scalar, scalar>();
+    calculatePrime2MeanFields<vector, symmTensor>();
 
     forAll(faItems_, fieldI)
     {
@@ -211,14 +143,11 @@ void Foam::fieldAverage::calcAverages()
 
 void Foam::fieldAverage::writeAverages() const
 {
-    writeFieldList<scalar>(meanScalarFields_);
-    writeFieldList<vector>(meanVectorFields_);
-    writeFieldList<sphericalTensor>(meanSphericalTensorFields_);
-    writeFieldList<symmTensor>(meanSymmTensorFields_);
-    writeFieldList<tensor>(meanTensorFields_);
-
-    writeFieldList<scalar>(prime2MeanScalarFields_);
-    writeFieldList<symmTensor>(prime2MeanSymmTensorFields_);
+    writeFields<scalar>();
+    writeFields<vector>();
+    writeFields<sphericalTensor>();
+    writeFields<symmTensor>();
+    writeFields<tensor>();
 }
 
 
@@ -324,13 +253,6 @@ Foam::fieldAverage::fieldAverage
     resetOnOutput_(false),
     initialised_(false),
     faItems_(),
-    meanScalarFields_(),
-    meanVectorFields_(),
-    meanSphericalTensorFields_(),
-    meanSymmTensorFields_(),
-    meanTensorFields_(),
-    prime2MeanScalarFields_(),
-    prime2MeanSymmTensorFields_(),
     totalIter_(),
     totalTime_()
 {
diff --git a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.H b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.H
index 12cea88cd76..01b25580104 100644
--- a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.H
+++ b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.H
@@ -29,9 +29,9 @@ Group
 
 Description
     This function object calculates average quantities for a user-specified
-    selection of fields.  Fields are entered as a list of sub-dictionaries,
-    which indicate the type of averages to perform, and can be updated during
-    the calculation.  The current options include:
+    selection of volumetric and surface fields.  Fields are entered as a list
+    of sub-dictionaries, which indicate the type of averages to perform, and
+    can be updated during the calculation.  The current options include:
     - \c mean: arithmetic mean:
         \f[
             \overline{x} = \frac{1}{N}\displaystyle\sum\limits_{i=0}^N x_i
@@ -142,16 +142,7 @@ class fieldAverage
 {
 protected:
 
-    // File and field name extensions
-
-        //- Mean average
-        static const word EXT_MEAN;
-
-        //- Prime-squared average
-        static const word EXT_PRIME2MEAN;
-
-
-    // Private data
+    // Protected data
 
         //- Name of this set of field averages.
         word name_;
@@ -178,22 +169,6 @@ protected:
         //  calculated and output
         List<fieldAverageItem> faItems_;
 
-
-        // Lists of averages
-
-            // Arithmetic mean fields
-            wordList meanScalarFields_;
-            wordList meanVectorFields_;
-            wordList meanSphericalTensorFields_;
-            wordList meanSymmTensorFields_;
-            wordList meanTensorFields_;
-
-            // Prime-squared fields
-            // Only applicable to volScalarFields / volVectorFields
-            wordList prime2MeanScalarFields_;
-            wordList prime2MeanSymmTensorFields_;
-
-
         // Counters
 
             //- Iteration steps counter
@@ -209,24 +184,27 @@ protected:
 
             //- Checkout fields (causes deletion) from the database
             //  and reset lists
-            void resetFields(wordList&);
+            void resetFields();
 
             //- Reset lists (clear existing values) and initialize averaging.
             //  Check requested field averages are valid, populate field lists
             void initialize();
 
-            //- Add mean average field to list
+            //- Add mean average field to database
+            template<class Type>
+            void addMeanFieldType(const label fieldI);
+
+            //- Add mean average field to database
             template<class Type>
-            void addMeanField(const label, wordList&) const;
+            void addMeanField(const label fieldI);
 
-            //- Add prime-squared average field to list
+            //- Add prime-squared average field to database
             template<class Type1, class Type2>
-            void addPrime2MeanField
-            (
-                const label,
-                const wordList&,
-                wordList&
-            ) const;
+            void addPrime2MeanFieldType(const label fieldI);
+
+            //- Add prime-squared average field to database
+            template<class Type1, class Type2>
+            void addPrime2MeanField(const label fieldI);
 
 
         // Calculation functions
@@ -236,23 +214,27 @@ protected:
 
             //- Calculate mean average fields
             template<class Type>
-            void calculateMeanFields(const wordList&) const;
+            void calculateMeanFieldType(const label fieldI) const;
 
-            //- Add mean-squared field value to prime-squared mean field
+            //- Calculate mean average fields
+            template<class Type>
+            void calculateMeanFields() const;
+
+            //- Calculate prime-squared average fields
             template<class Type1, class Type2>
-            void addMeanSqrToPrime2Mean
-            (
-                const wordList&,
-                const wordList&
-            ) const;
+            void calculatePrime2MeanFieldType(const label fieldI) const;
 
             //- Calculate prime-squared average fields
             template<class Type1, class Type2>
-            void calculatePrime2MeanFields
-            (
-                const wordList&,
-                const wordList&
-            ) const;
+            void calculatePrime2MeanFields() const;
+
+            //- Add mean-squared field value to prime-squared mean field
+            template<class Type1, class Type2>
+            void addMeanSqrToPrime2MeanType(const label fieldI) const;
+
+            //- Add mean-squared field value to prime-squared mean field
+            template<class Type1, class Type2>
+            void addMeanSqrToPrime2Mean() const;
 
 
         // I-O
@@ -262,7 +244,11 @@ protected:
 
             //- Write fields
             template<class Type>
-            void writeFieldList(const wordList&) const;
+            void writeFieldType(const word& fieldName) const;
+
+            //- Write fields
+            template<class Type>
+            void writeFields() const;
 
             //- Write averaging properties - steps and time
             void writeAveragingProperties() const;
diff --git a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverageTemplates.C b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverageTemplates.C
index 184df72a9c9..996d0073e77 100644
--- a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverageTemplates.C
+++ b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverageTemplates.C
@@ -25,290 +25,356 @@ License
 
 #include "fieldAverageItem.H"
 #include "volFields.H"
+#include "surfaceFields.H"
 #include "OFstream.H"
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
 template<class Type>
-void Foam::fieldAverage::addMeanField
-(
-    const label fieldI,
-    wordList& meanFieldList
-) const
+void Foam::fieldAverage::addMeanFieldType(const label fieldI)
 {
-    if (faItems_[fieldI].mean())
+    faItems_[fieldI].active() = true;
+
+    const word& fieldName = faItems_[fieldI].fieldName();
+    const word& meanFieldName = faItems_[fieldI].meanFieldName();
+
+    Info<< "Reading/calculating field " << meanFieldName << nl << endl;
+
+    if (obr_.foundObject<Type>(meanFieldName))
     {
-        typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
+       // do nothing
+    }
+    else if (obr_.found(meanFieldName))
+    {
+        Info<< "Cannot allocate average field " << meanFieldName
+            << " since an object with that name already exists."
+            << " Disabling averaging." << nl << endl;
 
-        const word& fieldName = faItems_[fieldI].fieldName();
+        faItems_[fieldI].mean() = false;
+    }
+    else
+    {
+        const Type& baseField = obr_.lookupObject<Type>(fieldName);
 
-        word meanFieldName = fieldName + EXT_MEAN;
-        if
+        // Store on registry
+        obr_.store
         (
-            (faItems_[fieldI].window() > 0)
-         && (faItems_[fieldI].windowName() != "")
-        )
-        {
-            meanFieldName = meanFieldName + "_" + faItems_[fieldI].windowName();
-        }
+            new Type
+            (
+                IOobject
+                (
+                    meanFieldName,
+                    obr_.time().timeName(obr_.time().startTime().value()),
+                    obr_,
+                    IOobject::READ_IF_PRESENT,
+                    IOobject::NO_WRITE
+                ),
+                1*baseField
+            )
+        );
+    }
+}
 
-        Info<< "Reading/calculating field " << meanFieldName << nl << endl;
 
-        if (obr_.foundObject<fieldType>(meanFieldName))
+template<class Type>
+void Foam::fieldAverage::addMeanField(const label fieldI)
+{
+    if (faItems_[fieldI].mean())
+    {
+        typedef GeometricField<Type, fvPatchField, volMesh> volFieldType;
+        typedef GeometricField<Type, fvsPatchField, surfaceMesh> surfFieldType;
+
+        const word& fieldName = faItems_[fieldI].fieldName();
+
+        if (obr_.foundObject<volFieldType>(fieldName))
         {
-            meanFieldList[fieldI] = meanFieldName;
+            addMeanFieldType<volFieldType>(fieldI);
         }
-        else if (obr_.found(meanFieldName))
+        else if (obr_.foundObject<surfFieldType>(fieldName))
         {
-            Info<< "Cannot allocate average field " << meanFieldName
-                << " since an object with that name already exists."
-                << " Disabling averaging." << nl << endl;
-            meanFieldList[fieldI] = word::null;
+            addMeanFieldType<surfFieldType>(fieldI);
         }
-        else
-        {
-            const fieldType& baseField =
-                obr_.lookupObject<fieldType>(fieldName);
+    }
+}
+
+
+template<class Type1, class Type2>
+void Foam::fieldAverage::addPrime2MeanFieldType(const label fieldI)
+{
+    const word& fieldName = faItems_[fieldI].fieldName();
+    const word& meanFieldName = faItems_[fieldI].meanFieldName();
+    const word& prime2MeanFieldName = faItems_[fieldI].prime2MeanFieldName();
+
+    Info<< "Reading/calculating field " << prime2MeanFieldName << nl << endl;
 
-            // Store on registry
-            obr_.store
+    if (obr_.foundObject<Type2>(prime2MeanFieldName))
+    {
+        // do nothing
+    }
+    else if (obr_.found(prime2MeanFieldName))
+    {
+        Info<< "Cannot allocate average field " << prime2MeanFieldName
+            << " since an object with that name already exists."
+            << " Disabling averaging." << nl << endl;
+
+        faItems_[fieldI].prime2Mean() = false;
+    }
+    else
+    {
+        const Type1& baseField = obr_.lookupObject<Type1>(fieldName);
+        const Type1& meanField = obr_.lookupObject<Type1>(meanFieldName);
+
+        obr_.store
+        (
+            new Type2
             (
-                new fieldType
+                IOobject
                 (
-                    IOobject
-                    (
-                        meanFieldName,
-                        obr_.time().timeName(obr_.time().startTime().value()),
-                        obr_,
-                        IOobject::READ_IF_PRESENT,
-                        IOobject::NO_WRITE
-                    ),
-                    1*baseField
-                )
-            );
-
-            meanFieldList[fieldI] = meanFieldName;
-        }
+                    prime2MeanFieldName,
+                    obr_.time().timeName(obr_.time().startTime().value()),
+                    obr_,
+                    IOobject::READ_IF_PRESENT,
+                    IOobject::NO_WRITE
+                ),
+                sqr(baseField) - sqr(meanField)
+            )
+        );
     }
 }
 
 
 template<class Type1, class Type2>
-void Foam::fieldAverage::addPrime2MeanField
-(
-    const label fieldI,
-    const wordList& meanFieldList,
-    wordList& prime2MeanFieldList
-) const
+void Foam::fieldAverage::addPrime2MeanField(const label fieldI)
 {
-    if (faItems_[fieldI].mean() && meanFieldList[fieldI].size())
-    {
-        typedef GeometricField<Type1, fvPatchField, volMesh> fieldType1;
-        typedef GeometricField<Type2, fvPatchField, volMesh> fieldType2;
+    typedef GeometricField<Type1, fvPatchField, volMesh> volFieldType1;
+    typedef GeometricField<Type1, fvsPatchField, surfaceMesh> surfFieldType1;
 
+    typedef GeometricField<Type2, fvPatchField, volMesh> volFieldType2;
+    typedef GeometricField<Type2, fvsPatchField, surfaceMesh> surfFieldType2;
+
+    if (faItems_[fieldI].prime2Mean())
+    {
         const word& fieldName = faItems_[fieldI].fieldName();
 
-        word meanFieldName = fieldName + EXT_PRIME2MEAN;
-        if
-        (
-            (faItems_[fieldI].window() > 0)
-         && (faItems_[fieldI].windowName() != "")
-        )
+        if (!faItems_[fieldI].mean())
         {
-            meanFieldName = meanFieldName + "_" + faItems_[fieldI].windowName();
+            FatalErrorIn
+            (
+                "void Foam::fieldAverage::addPrime2MeanField(const label) const"
+            )
+                << "To calculate the prime-squared average, the "
+                << "mean average must also be selected for field "
+                << fieldName << nl << exit(FatalError);
         }
 
-        Info<< "Reading/calculating field " << meanFieldName << nl << endl;
-
-        if (obr_.foundObject<fieldType2>(meanFieldName))
+        if (obr_.foundObject<volFieldType1>(fieldName))
         {
-            prime2MeanFieldList[fieldI] = meanFieldName;
+            addPrime2MeanFieldType<volFieldType1, volFieldType2>(fieldI);
         }
-        else if (obr_.found(meanFieldName))
+        else if (obr_.foundObject<surfFieldType1>(fieldName))
         {
-            Info<< "Cannot allocate average field " << meanFieldName
-                << " since an object with that name already exists."
-                << " Disabling averaging." << nl << endl;
-            prime2MeanFieldList[fieldI] = word::null;
-        }
-        else
-        {
-            const fieldType1& baseField =
-                obr_.lookupObject<fieldType1>(fieldName);
-            const fieldType1& meanField =
-                obr_.lookupObject<fieldType1>(meanFieldList[fieldI]);
-
-            obr_.store
-            (
-                new fieldType2
-                (
-                    IOobject
-                    (
-                        meanFieldName,
-                        obr_.time().timeName(obr_.time().startTime().value()),
-                        obr_,
-                        IOobject::READ_IF_PRESENT,
-                        IOobject::NO_WRITE
-                    ),
-                    sqr(baseField) - sqr(meanField)
-                )
-            );
-
-            prime2MeanFieldList[fieldI] = meanFieldName;
+            addPrime2MeanFieldType<surfFieldType1, surfFieldType2>(fieldI);
         }
     }
 }
 
 
 template<class Type>
-void Foam::fieldAverage::calculateMeanFields(const wordList& meanFieldList)
-const
+void Foam::fieldAverage::calculateMeanFieldType(const label fieldI) const
 {
-    typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
-
-    scalar dt = obr_.time().deltaTValue();
+    const word& fieldName = faItems_[fieldI].fieldName();
 
-    forAll(faItems_, i)
+    if (obr_.foundObject<Type>(fieldName))
     {
-        if (faItems_[i].mean() && meanFieldList[i].size())
+        const Type& baseField = obr_.lookupObject<Type>(fieldName);
+
+        Type& meanField = const_cast<Type&>
+        (
+            obr_.lookupObject<Type>(faItems_[fieldI].meanFieldName())
+        );
+
+        scalar dt = obr_.time().deltaTValue();
+        scalar Dt = totalTime_[fieldI];
+
+        if (faItems_[fieldI].iterBase())
         {
-            const word& fieldName = faItems_[i].fieldName();
-            const fieldType& baseField =
-                obr_.lookupObject<fieldType>(fieldName);
-            fieldType& meanField = const_cast<fieldType&>
-            (
-                obr_.lookupObject<fieldType>(meanFieldList[i])
-            );
+            dt = 1.0;
+            Dt = scalar(totalIter_[fieldI]);
+        }
+
+        scalar alpha = (Dt - dt)/Dt;
+        scalar beta = dt/Dt;
 
-            scalar Dt = totalTime_[i];
-            if (faItems_[i].iterBase())
+        if (faItems_[fieldI].window() > 0)
+        {
+            const scalar w = faItems_[fieldI].window();
+
+            if (Dt - dt >= w)
             {
-                dt = 1.0;
-                Dt = scalar(totalIter_[i]);
+                alpha = (w - dt)/w;
+                beta = dt/w;
             }
+        }
 
-            scalar alpha = (Dt - dt)/Dt;
-            scalar beta = dt/Dt;
-            if (faItems_[i].window() > 0)
-            {
-                const scalar w = faItems_[i].window();
+        meanField = alpha*meanField + beta*baseField;
+    }
+}
 
-                if (Dt - dt >= w)
-                {
-                    alpha = (w - dt)/w;
-                    beta = dt/w;
-                }
-            }
 
-            meanField = alpha*meanField + beta*baseField;
+template<class Type>
+void Foam::fieldAverage::calculateMeanFields() const
+{
+    typedef GeometricField<Type, fvPatchField, volMesh> volFieldType;
+    typedef GeometricField<Type, fvsPatchField, surfaceMesh> surfFieldType;
+
+    forAll(faItems_, i)
+    {
+        if (faItems_[i].mean())
+        {
+            calculateMeanFieldType<volFieldType>(i);
+            calculateMeanFieldType<surfFieldType>(i);
         }
     }
 }
 
 
 template<class Type1, class Type2>
-void Foam::fieldAverage::calculatePrime2MeanFields
-(
-    const wordList& meanFieldList,
-    const wordList& prime2MeanFieldList
-) const
+void Foam::fieldAverage::calculatePrime2MeanFieldType(const label fieldI) const
 {
-    typedef GeometricField<Type1, fvPatchField, volMesh> fieldType1;
-    typedef GeometricField<Type2, fvPatchField, volMesh> fieldType2;
+    const word& fieldName = faItems_[fieldI].fieldName();
 
-    scalar dt = obr_.time().deltaTValue();
-
-    forAll(faItems_, i)
+    if (obr_.foundObject<Type1>(fieldName))
     {
-        if
+        const Type1& baseField = obr_.lookupObject<Type1>(fieldName);
+        const Type1& meanField =
+            obr_.lookupObject<Type1>(faItems_[fieldI].meanFieldName());
+
+        Type2& prime2MeanField = const_cast<Type2&>
         (
-            faItems_[i].prime2Mean()
-         && meanFieldList[i].size()
-         && prime2MeanFieldList[i].size()
-        )
+            obr_.lookupObject<Type2>(faItems_[fieldI].prime2MeanFieldName())
+        );
+
+        scalar dt = obr_.time().deltaTValue();
+        scalar Dt = totalTime_[fieldI];
+
+        if (faItems_[fieldI].iterBase())
         {
-            const word& fieldName = faItems_[i].fieldName();
-            const fieldType1& baseField =
-                obr_.lookupObject<fieldType1>(fieldName);
-            const fieldType1& meanField =
-                obr_.lookupObject<fieldType1>(meanFieldList[i]);
-            fieldType2& prime2MeanField = const_cast<fieldType2&>
-            (
-                obr_.lookupObject<fieldType2>(prime2MeanFieldList[i])
-            );
+            dt = 1.0;
+            Dt = scalar(totalIter_[fieldI]);
+        }
 
-            scalar Dt = totalTime_[i];
-            if (faItems_[i].iterBase())
+        scalar alpha = (Dt - dt)/Dt;
+        scalar beta = dt/Dt;
+
+        if (faItems_[fieldI].window() > 0)
+        {
+            const scalar w = faItems_[fieldI].window();
+
+            if (Dt - dt >= w)
             {
-                dt = 1.0;
-                Dt = scalar(totalIter_[i]);
+                alpha = (w - dt)/w;
+                beta = dt/w;
             }
+        }
 
-            scalar alpha = (Dt - dt)/Dt;
-            scalar beta = dt/Dt;
-            if (faItems_[i].window() > 0)
-            {
-                const scalar w = faItems_[i].window();
+        prime2MeanField =
+            alpha*prime2MeanField
+          + beta*sqr(baseField)
+          - sqr(meanField);
+    }
+}
 
-                if (Dt - dt >= w)
-                {
-                    alpha = (w - dt)/w;
-                    beta = dt/w;
-                }
-            }
 
-            prime2MeanField =
-                alpha*prime2MeanField
-              + beta*sqr(baseField)
-              - sqr(meanField);
+template<class Type1, class Type2>
+void Foam::fieldAverage::calculatePrime2MeanFields() const
+{
+    typedef GeometricField<Type1, fvPatchField, volMesh> volFieldType1;
+    typedef GeometricField<Type1, fvsPatchField, surfaceMesh> surfFieldType1;
+
+    typedef GeometricField<Type2, fvPatchField, volMesh> volFieldType2;
+    typedef GeometricField<Type2, fvsPatchField, surfaceMesh> surfFieldType2;
+
+    forAll(faItems_, i)
+    {
+        if (faItems_[i].prime2Mean())
+        {
+            calculatePrime2MeanFieldType<volFieldType1, volFieldType2>(i);
+            calculatePrime2MeanFieldType<surfFieldType1, surfFieldType2>(i);
         }
     }
 }
 
 
 template<class Type1, class Type2>
-void Foam::fieldAverage::addMeanSqrToPrime2Mean
-(
-    const wordList& meanFieldList,
-    const wordList& prime2MeanFieldList
-) const
+void Foam::fieldAverage::addMeanSqrToPrime2MeanType(const label fieldI) const
 {
-    typedef GeometricField<Type1, fvPatchField, volMesh> fieldType1;
-    typedef GeometricField<Type2, fvPatchField, volMesh> fieldType2;
+    const word& fieldName = faItems_[fieldI].fieldName();
 
-    forAll(faItems_, i)
+    if (obr_.foundObject<Type1>(fieldName))
     {
-        if
+        const Type1& meanField =
+            obr_.lookupObject<Type1>(faItems_[fieldI].meanFieldName());
+
+        Type2& prime2MeanField = const_cast<Type2&>
         (
-            faItems_[i].prime2Mean()
-         && meanFieldList[i].size()
-         && prime2MeanFieldList[i].size()
-        )
-        {
-            const fieldType1& meanField =
-                obr_.lookupObject<fieldType1>(meanFieldList[i]);
-            fieldType2& prime2MeanField = const_cast<fieldType2&>
-            (
-                obr_.lookupObject<fieldType2>(prime2MeanFieldList[i])
-            );
+            obr_.lookupObject<Type2>(faItems_[fieldI].prime2MeanFieldName())
+        );
+
+        prime2MeanField += sqr(meanField);
+    }
+}
+
+
+template<class Type1, class Type2>
+void Foam::fieldAverage::addMeanSqrToPrime2Mean() const
+{
+    typedef GeometricField<Type1, fvPatchField, volMesh> volFieldType1;
+    typedef GeometricField<Type1, fvsPatchField, surfaceMesh> surfFieldType1;
 
-            prime2MeanField += sqr(meanField);
+    typedef GeometricField<Type2, fvPatchField, volMesh> volFieldType2;
+    typedef GeometricField<Type2, fvsPatchField, surfaceMesh> surfFieldType2;
+
+    forAll(faItems_, i)
+    {
+        if (faItems_[i].prime2Mean())
+        {
+            addMeanSqrToPrime2MeanType<volFieldType1, volFieldType2>(i);
+            addMeanSqrToPrime2MeanType<surfFieldType1, surfFieldType2>(i);
         }
     }
 }
 
 
 template<class Type>
-void Foam::fieldAverage::writeFieldList(const wordList& fieldList) const
+void Foam::fieldAverage::writeFieldType(const word& fieldName) const
+{
+    if (obr_.foundObject<Type>(fieldName))
+    {
+        const Type& f = obr_.lookupObject<Type>(fieldName);
+        f.write();
+    }
+}
+
+
+template<class Type>
+void Foam::fieldAverage::writeFields() const
 {
-    typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
+    typedef GeometricField<Type, fvPatchField, volMesh> volFieldType;
+    typedef GeometricField<Type, fvsPatchField, surfaceMesh> surfFieldType;
 
-    forAll(fieldList, i)
+    forAll(faItems_, i)
     {
-        if (fieldList[i].size())
+        if (faItems_[i].mean())
+        {
+            const word& fieldName = faItems_[i].meanFieldName();
+            writeFieldType<volFieldType>(fieldName);
+            writeFieldType<surfFieldType>(fieldName);
+        }
+        if (faItems_[i].prime2Mean())
         {
-            const fieldType& f = obr_.lookupObject<fieldType>(fieldList[i]);
-            f.write();
+            const word& fieldName = faItems_[i].prime2MeanFieldName();
+            writeFieldType<volFieldType>(fieldName);
+            writeFieldType<surfFieldType>(fieldName);
         }
     }
 }
diff --git a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItem.C b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItem.C
index 3b01b215949..9f5334c03a4 100644
--- a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItem.C
+++ b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItem.C
@@ -29,6 +29,9 @@ License
 
 namespace Foam
 {
+    const word fieldAverageItem::EXT_MEAN = "Mean";
+    const word fieldAverageItem::EXT_PRIME2MEAN = "Prime2Mean";
+
     template<>
     const char* Foam::NamedEnum
     <
@@ -50,9 +53,12 @@ const Foam::NamedEnum<Foam::fieldAverageItem::baseType, 2>
 
 Foam::fieldAverageItem::fieldAverageItem()
 :
+    active_(false),
     fieldName_("unknown"),
     mean_(0),
+    meanFieldName_("unknown"),
     prime2Mean_(0),
+    prime2MeanFieldName_("unknown"),
     base_(ITER),
     window_(-1.0),
     windowName_("")
@@ -61,9 +67,12 @@ Foam::fieldAverageItem::fieldAverageItem()
 
 Foam::fieldAverageItem::fieldAverageItem(const fieldAverageItem& faItem)
 :
+    active_(faItem.active_),
     fieldName_(faItem.fieldName_),
     mean_(faItem.mean_),
+    meanFieldName_(faItem.meanFieldName_),
     prime2Mean_(faItem.prime2Mean_),
+    prime2MeanFieldName_(faItem.prime2MeanFieldName_),
     base_(faItem.base_),
     window_(faItem.window_),
     windowName_(faItem.windowName_)
@@ -91,9 +100,12 @@ void Foam::fieldAverageItem::operator=(const fieldAverageItem& rhs)
     }
 
     // Set updated values
+    active_ = rhs.active_;
     fieldName_ = rhs.fieldName_;
     mean_ = rhs.mean_;
+    meanFieldName_ = rhs.meanFieldName_;
     prime2Mean_ = rhs.prime2Mean_;
+    prime2MeanFieldName_ = rhs.prime2MeanFieldName_;
     base_ = rhs.base_;
     window_ = rhs.window_;
     windowName_ = rhs.windowName_;
diff --git a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItem.H b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItem.H
index 7fe21a9aef2..0c40bac95ad 100644
--- a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItem.H
+++ b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItem.H
@@ -78,6 +78,14 @@ public:
 
     // Public data
 
+        // File and field name extensions
+
+            //- Mean average
+            static const word EXT_MEAN;
+
+            //- Prime-squared average
+            static const word EXT_PRIME2MEAN;
+
         //- Enumeration defining the averaging base type
         enum baseType
         {
@@ -90,15 +98,24 @@ private:
 
     // Private data
 
+        //- Active flag
+        Switch active_;
+
         //- Field name
         word fieldName_;
 
         //- Compute mean flag
         Switch mean_;
 
+        //- Name of mean field
+        word meanFieldName_;
+
         //- Compute prime-squared mean flag
         Switch prime2Mean_;
 
+        //- Name of prime-squared mean field
+        word prime2MeanFieldName_;
+
         //- Averaging base type names
         static const NamedEnum<baseType, 2> baseTypeNames_;
 
@@ -134,6 +151,18 @@ public:
 
         // Access
 
+            //- Return const access to the active flag
+            const Switch& active() const
+            {
+                return active_;
+            }
+
+            //- Return non-const access to the active flag
+            Switch& active()
+            {
+                return active_;
+            }
+
             //- Return const access to the field name
             const word& fieldName() const
             {
@@ -146,12 +175,36 @@ public:
                 return mean_;
             }
 
+            //- Return non-const access to the mean flag
+            Switch& mean()
+            {
+                return mean_;
+            }
+
+            //- Return const access to the mean field name
+            const word& meanFieldName() const
+            {
+                return meanFieldName_;
+            }
+
             //- Return const access to the prime-squared mean flag
             const Switch& prime2Mean() const
             {
                 return prime2Mean_;
             }
 
+            //- Return non-const access to the prime-squared mean flag
+            Switch& prime2Mean()
+            {
+                return prime2Mean_;
+            }
+
+            //- Return const access to the prime-squared mean field name
+            const word& prime2MeanFieldName() const
+            {
+                return prime2MeanFieldName_;
+            }
+
             //- Return averaging base type name
             const word base() const
             {
@@ -197,7 +250,9 @@ public:
             return
                 a.fieldName_ == b.fieldName_
              && a.mean_ == b.mean_
+             && a.meanFieldName_ == b.meanFieldName_
              && a.prime2Mean_ == b.prime2Mean_
+             && a.prime2MeanFieldName_ == b.prime2MeanFieldName_
              && a.base_ == b.base_
              && a.window_ == b.window_
              && a.windowName_ == b.windowName_;
diff --git a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItemIO.C b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItemIO.C
index af293ff989b..7dfee8646d0 100644
--- a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItemIO.C
+++ b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItemIO.C
@@ -31,9 +31,12 @@ License
 
 Foam::fieldAverageItem::fieldAverageItem(Istream& is)
 :
+    active_(false),
     fieldName_("unknown"),
     mean_(0),
+    meanFieldName_("unknown"),
     prime2Mean_(0),
+    prime2MeanFieldName_("unknown"),
     base_(ITER),
     window_(-1.0)
 {
@@ -47,6 +50,14 @@ Foam::fieldAverageItem::fieldAverageItem(Istream& is)
     base_ = baseTypeNames_[entry.lookup("base")];
     window_ = entry.lookupOrDefault<scalar>("window", -1.0);
     windowName_ = entry.lookupOrDefault<word>("windowName", "");
+
+    meanFieldName_ = fieldName_ + EXT_MEAN;
+    prime2MeanFieldName_ = fieldName_ + EXT_PRIME2MEAN;
+    if ((window_ > 0) && (windowName_ != ""))
+    {
+        meanFieldName_ = meanFieldName_ + "_" + windowName_;
+        prime2MeanFieldName_ = prime2MeanFieldName_ + "_" + windowName_;
+    }
 }
 
 
@@ -62,6 +73,7 @@ Foam::Istream& Foam::operator>>(Istream& is, fieldAverageItem& faItem)
 
     const dictionaryEntry entry(dictionary::null, is);
 
+    faItem.active_ = false;
     faItem.fieldName_ = entry.keyword();
     entry.lookup("mean") >> faItem.mean_;
     entry.lookup("prime2Mean") >> faItem.prime2Mean_;
@@ -69,6 +81,18 @@ Foam::Istream& Foam::operator>>(Istream& is, fieldAverageItem& faItem)
     faItem.window_ = entry.lookupOrDefault<scalar>("window", -1.0);
     faItem.windowName_ = entry.lookupOrDefault<word>("windowName", "");
 
+    faItem.meanFieldName_ = faItem.fieldName_ + fieldAverageItem::EXT_MEAN;
+    faItem.prime2MeanFieldName_ =
+        faItem.fieldName_ + fieldAverageItem::EXT_PRIME2MEAN;
+
+    if ((faItem.window_ > 0) && (faItem.windowName_ != ""))
+    {
+        faItem.meanFieldName_ =
+            faItem.meanFieldName_ + "_" + faItem.windowName_;
+
+        faItem.prime2MeanFieldName_ =
+            faItem.prime2MeanFieldName_ + "_" + faItem.windowName_;
+    }
     return is;
 }
 
-- 
GitLab