diff --git a/applications/solvers/combustion/chemFoam/createFields.H b/applications/solvers/combustion/chemFoam/createFields.H
index 4a971492c9c38395f0128bc193cef93582da1a2e..b37a8818e311f56d8576e44188aabe7866026f3d 100644
--- a/applications/solvers/combustion/chemFoam/createFields.H
+++ b/applications/solvers/combustion/chemFoam/createFields.H
@@ -45,9 +45,29 @@
         ),
         thermo.rho()
     );
+
     volScalarField& p = thermo.p();
     volScalarField& hs = thermo.hs();
 
+    volScalarField Rspecific
+    (
+        IOobject
+        (
+            "Rspecific",
+            runTime.timeName(),
+            runTime,
+            IOobject::NO_READ,
+            IOobject::AUTO_WRITE
+        ),
+        mesh,
+        dimensionedScalar
+        (
+            "zero",
+            dimensionSet(dimEnergy/dimMass/dimTemperature),
+            0.0
+        )
+    );
+
     volVectorField U
     (
         IOobject
diff --git a/applications/solvers/combustion/chemFoam/pEqn.H b/applications/solvers/combustion/chemFoam/pEqn.H
index 28d240940b6805c6ce5124bd2924e6c36c80a3fc..13f3d603ae7375fe6719e3fd0131f3fdad117270 100644
--- a/applications/solvers/combustion/chemFoam/pEqn.H
+++ b/applications/solvers/combustion/chemFoam/pEqn.H
@@ -3,7 +3,15 @@
     rho = thermo.rho();
     if (constProp == "volume")
     {
-        p[0] = rho0*R0*thermo.T()[0];
+        scalar invW = 0.0;
+        forAll(Y, i)
+        {
+            invW += Y[i][0]/specieData[i].W();
+        }
+
+        Rspecific[0] = 1000.0*constant::physicoChemical::R.value()*invW;
+
+        p[0] = rho0*Rspecific[0]*thermo.T()[0];
         rho[0] = rho0;
     }
-}
\ No newline at end of file
+}
diff --git a/applications/solvers/combustion/chemFoam/readInitialConditions.H b/applications/solvers/combustion/chemFoam/readInitialConditions.H
index 6b26e5fc37e1f8083600d9d01804c08df12b4c47..817ed264f9a18224280ddd54f24becd72472ff51 100644
--- a/applications/solvers/combustion/chemFoam/readInitialConditions.H
+++ b/applications/solvers/combustion/chemFoam/readInitialConditions.H
@@ -106,6 +106,7 @@
     scalar rho0 = rho[0];
     scalar u0 = hs0 - p0/rho0;
     scalar R0 = p0/(rho0*T0);
-
+    Rspecific[0] = R0;
+ 
     scalar integratedHeat = 0.0;
 
diff --git a/src/finiteVolume/Make/files b/src/finiteVolume/Make/files
index 3bcd7b80d55dfec16641962a6dbf6ff0e12c12fd..cc2f3e4225a0e329c88e772acb0748631e5042a7 100644
--- a/src/finiteVolume/Make/files
+++ b/src/finiteVolume/Make/files
@@ -390,6 +390,12 @@ $(basicSource)/actuationDiskSource/actuationDiskSource.C
 $(basicSource)/radialActuationDiskSource/radialActuationDiskSource.C
 $(basicSource)/explicitSource/explicitSource.C
 $(basicSource)/explicitSetValue/explicitSetValue.C
+$(basicSource)/rotorDiskSource/rotorDiskSource.C
+$(basicSource)/rotorDiskSource/bladeModel/bladeModel.C
+$(basicSource)/rotorDiskSource/profileModel/profileModel.C
+$(basicSource)/rotorDiskSource/profileModel/profileModelList.C
+$(basicSource)/rotorDiskSource/profileModel/lookup/lookupProfile.C
+$(basicSource)/rotorDiskSource/profileModel/series/seriesProfile.C
 
 
 LIB = $(FOAM_LIBBIN)/libfiniteVolume
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/actuationDiskSource/actuationDiskSource.C b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/actuationDiskSource/actuationDiskSource.C
index 32a025d993bd4010f8c5a3e4aee8656ce9d04b80..e7e996d1db9784c8a07821fdf425c03c25cca17f 100644
--- a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/actuationDiskSource/actuationDiskSource.C
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/actuationDiskSource/actuationDiskSource.C
@@ -75,11 +75,11 @@ Foam::actuationDiskSource::actuationDiskSource
 )
 :
     basicSource(name, modelType, dict, mesh),
-    dict_(dict.subDict(modelType + "Coeffs")),
-    diskDir_(dict_.lookup("diskDir")),
-    Cp_(readScalar(dict_.lookup("Cp"))),
-    Ct_(readScalar(dict_.lookup("Ct"))),
-    diskArea_(readScalar(dict_.lookup("diskArea")))
+    coeffs_(dict.subDict(modelType + "Coeffs")),
+    diskDir_(coeffs_.lookup("diskDir")),
+    Cp_(readScalar(coeffs_.lookup("Cp"))),
+    Ct_(readScalar(coeffs_.lookup("Ct"))),
+    diskArea_(readScalar(coeffs_.lookup("diskArea")))
 {
     Info<< "    - creating actuation disk zone: "
         << this->name() << endl;
@@ -132,20 +132,8 @@ void Foam::actuationDiskSource::addSu(fvMatrix<vector>& UEqn)
 
 void Foam::actuationDiskSource::writeData(Ostream& os) const
 {
-    os  << indent << token::BEGIN_BLOCK << incrIndent << nl;
-    os.writeKeyword("name") << this->name() << token::END_STATEMENT << nl;
-
-    if (dict_.found("note"))
-    {
-        os.writeKeyword("note") << string(dict_.lookup("note"))
-            << token::END_STATEMENT << nl;
-    }
-
-    os << indent << "actuationDisk";
-
+    os  << indent << name_ << endl;
     dict_.write(os);
-
-    os << decrIndent << indent << token::END_BLOCK << endl;
 }
 
 
@@ -153,13 +141,11 @@ bool Foam::actuationDiskSource::read(const dictionary& dict)
 {
     if (basicSource::read(dict))
     {
-        const dictionary& sourceDict = dict.subDict(name());
-        const dictionary& subDictCoeffs =
-            sourceDict.subDict(typeName + "Coeffs");
-        subDictCoeffs.readIfPresent("diskDir", diskDir_);
-        subDictCoeffs.readIfPresent("Cp", Cp_);
-        subDictCoeffs.readIfPresent("Ct", Ct_);
-        subDictCoeffs.readIfPresent("diskArea", diskArea_);
+        coeffs_ = dict.subDict(typeName + "Coeffs");
+        coeffs_.readIfPresent("diskDir", diskDir_);
+        coeffs_.readIfPresent("Cp", Cp_);
+        coeffs_.readIfPresent("Ct", Ct_);
+        coeffs_.readIfPresent("diskArea", diskArea_);
 
         checkData();
 
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/actuationDiskSource/actuationDiskSource.H b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/actuationDiskSource/actuationDiskSource.H
index 8b54ac08710686b5f43e3555abbd07685f62ddb7..cbe98ea4c8d24e2489a9691c24931256bbe11138 100644
--- a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/actuationDiskSource/actuationDiskSource.H
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/actuationDiskSource/actuationDiskSource.H
@@ -74,8 +74,8 @@ protected:
 
     // Protected data
 
-        //- Sub dictionary with actuationDisk information
-        const dictionary& dict_;
+        //- Coefficients dictionary
+        dictionary coeffs_;
 
         //- Disk area normal
         vector diskDir_;
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/basicSource/basicSource.C b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/basicSource/basicSource.C
index 114e6e58cbe692549e742f4d515bf2cbbe962c74..cd7394a173bc9029c9517e2e411b32113868b262 100644
--- a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/basicSource/basicSource.C
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/basicSource/basicSource.C
@@ -277,28 +277,20 @@ bool Foam::basicSource::isActive()
 
 void Foam::basicSource::addSu(Foam::fvMatrix<vector>& Eqn)
 {
-    notImplemented
-    (
-        "Foam::basicSource addSu(Foam::fvMatrix<vector>& Eqn)"
-    );
+    notImplemented("Foam::basicSource addSu(Foam::fvMatrix<vector>& Eqn)");
 }
 
 
 void Foam::basicSource::addSu(Foam::fvMatrix<scalar>& Eqn)
 {
-    notImplemented
-    (
-        "Foam::basicSource addSu(Foam::fvMatrix<scalar>& Eqn)"
-    );
+    notImplemented("Foam::basicSource addSu(Foam::fvMatrix<scalar>& Eqn)");
 }
 
 
 void Foam::basicSource::setValue(Foam::fvMatrix<scalar>& Eqn)
 {
-    notImplemented
-    (
-        "Foam::basicSource setValue(Foam::fvMatrix<scalar>& Eqn)"
-    );
+    notImplemented("Foam::basicSource setValue(Foam::fvMatrix<scalar>& Eqn)");
 }
 
+
 // ************************************************************************* //
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/basicSource/basicSource.H b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/basicSource/basicSource.H
index 43c9e8bd47028e8fa32b05774ffdb1946d0be1f7..9862282479b3c0db10e3c4857353c9335f003540 100644
--- a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/basicSource/basicSource.H
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/basicSource/basicSource.H
@@ -202,10 +202,7 @@ public:
         //- Return clone
         autoPtr<basicSource> clone() const
         {
-            notImplemented
-            (
-                "autoPtr<basicSource> clone() const"
-            );
+            notImplemented("autoPtr<basicSource> clone() const");
             return autoPtr<basicSource>(NULL);
         }
 
@@ -273,7 +270,7 @@ public:
             //- Return const access to the mesh database
             inline const fvMesh& mesh() const;
 
-            //- Return dictionay
+            //- Return dictionary
             inline const dictionary& dictCoeffs() const;
 
             //- Return const access to the source active flag
@@ -340,7 +337,6 @@ public:
 
             //- Read source dictionary
             virtual bool read(const dictionary& dict) = 0;
-
 };
 
 
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/basicSource/basicSourceIO.C b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/basicSource/basicSourceIO.C
index 8b425cf91c184669cdc76cc2791c2de33b21e25c..caec8b58cf78769260e7f08816fe352a2f77826c 100644
--- a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/basicSource/basicSourceIO.C
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/basicSource/basicSourceIO.C
@@ -77,10 +77,9 @@ void Foam::basicSource::writeData(Ostream& os) const
 
 bool Foam::basicSource::read(const dictionary& dict)
 {
-    const dictionary& sourceDict = dict.subDict(name_);
-    active_ = readBool(sourceDict.lookup("active"));
-    timeStart_ = readScalar(sourceDict.lookup("timeStart"));
-    duration_  = readScalar(sourceDict.lookup("duration"));
+    active_ = readBool(dict.lookup("active"));
+    timeStart_ = readScalar(dict.lookup("timeStart"));
+    duration_  = readScalar(dict.lookup("duration"));
     return true;
 }
 
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/basicSource/basicSourceList.C b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/basicSource/basicSourceList.C
index e9827409c5aef81c4de1449e5ae03aa1cddbb58e..79af0251430efbafbb62641764fff90a7e7fdec3 100644
--- a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/basicSource/basicSourceList.C
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/basicSource/basicSourceList.C
@@ -51,12 +51,12 @@ Foam::basicSourceList::basicSourceList
     forAllConstIter(dictionary, dict, iter)
     {
         const word& name = iter().keyword();
-        const dictionary& dict = iter().dict();
+        const dictionary& sourceDict = iter().dict();
 
         this->set
         (
             i++,
-            basicSource::New(name, dict, mesh)
+            basicSource::New(name, sourceDict, mesh)
         );
     }
 }
@@ -108,7 +108,8 @@ bool Foam::basicSourceList::read(const dictionary& dict)
     bool allOk = true;
     forAll(*this, i)
     {
-        bool ok = this->operator[](i).read(dict);
+        basicSource& bs = this->operator[](i);
+        bool ok = bs.read(dict.subDict(bs.name()));
         allOk = (allOk && ok);
     }
     return allOk;
@@ -117,12 +118,6 @@ bool Foam::basicSourceList::read(const dictionary& dict)
 
 bool Foam::basicSourceList::writeData(Ostream& os) const
 {
-    // Write size of list
-    os << nl << this->size();
-
-    // Write beginning of contents
-    os << nl << token::BEGIN_LIST;
-
     // Write list contents
     forAll(*this, i)
     {
@@ -130,9 +125,6 @@ bool Foam::basicSourceList::writeData(Ostream& os) const
         this->operator[](i).writeData(os);
     }
 
-    // Write end of contents
-    os << token::END_LIST << token::END_STATEMENT << nl;
-
     // Check state of IOstream
     return os.good();
 }
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/explicitSetValue/explicitSetValue.C b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/explicitSetValue/explicitSetValue.C
index 2a14b793a8de3db75521adcff5d0a1ec05704b6b..898f2c41c3728ee47628edec240626365212f172 100644
--- a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/explicitSetValue/explicitSetValue.C
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/explicitSetValue/explicitSetValue.C
@@ -72,11 +72,9 @@ void Foam::explicitSetValue::setFieldData(const dictionary& dict)
         }
         else
         {
-            FatalErrorIn
-            (
-                "explicitSetValue::setFieldData"
-            )   << "header not OK " << io.name()
-                << exit(FatalError);
+            FatalErrorIn("explicitSetValue::setFieldData")
+                << "header not OK for field " << io.name()
+                << abort(FatalError);
         }
     }
 
@@ -96,9 +94,9 @@ Foam::explicitSetValue::explicitSetValue
 )
 :
     basicSource(name, modelType, dict, mesh),
-    dict_(dict.subDict(modelType + "Coeffs"))
+    coeffs_(dict.subDict(modelType + "Coeffs"))
 {
-    setFieldData(dict_.subDict("fieldData"));
+    setFieldData(coeffs_.subDict("fieldData"));
 }
 
 
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/explicitSetValue/explicitSetValue.H b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/explicitSetValue/explicitSetValue.H
index 643e6b618243d40c4bb7401e13c7bdcc4e7a1352..df3d404f1ac373cdc1c584b6fcec73d08fbd2649 100644
--- a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/explicitSetValue/explicitSetValue.H
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/explicitSetValue/explicitSetValue.H
@@ -89,8 +89,8 @@ protected:
 
     // Protected data
 
-         //- Sub dictionary for time activated explicit sources
-        const dictionary& dict_;
+        //- Coefficients dictionary
+        dictionary coeffs_;
 
 
     // Protected functions
@@ -119,10 +119,7 @@ public:
         //- Return clone
         autoPtr<explicitSetValue> clone() const
         {
-            notImplemented
-            (
-                "autoPtr<explicitSetValue> clone() const"
-            );
+            notImplemented("autoPtr<explicitSetValue> clone() const");
             return autoPtr<explicitSetValue>(NULL);
         }
 
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/explicitSetValue/explicitSetValueIO.C b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/explicitSetValue/explicitSetValueIO.C
index dce0a53ddf69a4776aba28b21bc040ab76824773..24e9205606db82c5af9e1cebfe659628e7b2b6a6 100644
--- a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/explicitSetValue/explicitSetValueIO.C
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/explicitSetValue/explicitSetValueIO.C
@@ -29,22 +29,8 @@ License
 
 void Foam::explicitSetValue::writeData(Ostream& os) const
 {
-    os  << indent << name_ << nl
-        << indent << token::BEGIN_BLOCK << incrIndent << nl;
-
-    if (scalarFields_.size() > 0)
-    {
-        os.writeKeyword("scalarFields") << scalarFields_
-            << token::END_STATEMENT << nl;
-    }
-
-    if (vectorFields_.size() > 0)
-    {
-        os.writeKeyword("vectorFields") << vectorFields_
-            << token::END_STATEMENT << nl;
-    }
-
-    os << decrIndent << indent << token::END_BLOCK << endl;
+    os  << indent << name_ << endl;
+    dict_.write(os);
 }
 
 
@@ -52,12 +38,8 @@ bool Foam::explicitSetValue::read(const dictionary& dict)
 {
     if (basicSource::read(dict))
     {
-        const dictionary& sourceDict = dict.subDict(name());
-        const dictionary& subDictCoeffs = sourceDict.subDict
-        (
-            typeName + "Coeffs"
-        );
-        setFieldData(subDictCoeffs.subDict("fieldData"));
+        coeffs_ = dict.subDict(typeName + "Coeffs");
+        setFieldData(coeffs_.subDict("fieldData"));
         return true;
     }
     else
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/explicitSource/explicitSource.C b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/explicitSource/explicitSource.C
index de01ebb5309c7e2bd4975a1ac4013ae3a6336350..af5555f3fb09af2f0c73a427a8930c8c4c10ff00 100644
--- a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/explicitSource/explicitSource.C
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/explicitSource/explicitSource.C
@@ -112,8 +112,8 @@ Foam::explicitSource::explicitSource
 )
 :
     basicSource(name, modelType, dict, mesh),
-    dict_(dict.subDict(modelType + "Coeffs")),
-    volumeMode_(volumeModeTypeNames_.read(dict_.lookup("volumeMode")))
+    coeffs_(dict.subDict(modelType + "Coeffs")),
+    volumeMode_(volumeModeTypeNames_.read(coeffs_.lookup("volumeMode")))
 {
     setFieldData(dict_.subDict("fieldData"));
 }
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/explicitSource/explicitSource.H b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/explicitSource/explicitSource.H
index 9b88fac753e69c088d0b920d2d2928eb9681e772..05c3782254769ad49c32318e781dd132ab7c19b7 100644
--- a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/explicitSource/explicitSource.H
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/explicitSource/explicitSource.H
@@ -110,8 +110,8 @@ protected:
 
     // Protected data
 
-         //- Sub dictionary for time activated explicit sources
-        const dictionary& dict_;
+        //- Coefficients dictionary
+        dictionary coeffs_;
 
         //- Volume mode
         volumeModeType volumeMode_;
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/explicitSource/explicitSourceIO.C b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/explicitSource/explicitSourceIO.C
index 3b7b1b7c3521017e990f6fa591e59969cc27e507..f97ad329067091f0ba063410bc818d8e06e37e9c 100644
--- a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/explicitSource/explicitSourceIO.C
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/explicitSource/explicitSourceIO.C
@@ -29,25 +29,8 @@ License
 
 void Foam::explicitSource::writeData(Ostream& os) const
 {
-    os  << indent << name_ << nl
-        << indent << token::BEGIN_BLOCK << incrIndent << nl;
-
-    os.writeKeyword("volumeMode") << volumeModeTypeNames_[volumeMode_]
-        << token::END_STATEMENT << nl;
-
-    if (scalarFields_.size() > 0)
-    {
-        os.writeKeyword("scalarFields") << scalarFields_
-            << token::END_STATEMENT << nl;
-    }
-
-    if (vectorFields_.size() > 0)
-    {
-        os.writeKeyword("vectorFields") << vectorFields_
-            << token::END_STATEMENT << nl;
-    }
-
-    os << decrIndent << indent << token::END_BLOCK << endl;
+    os  << indent << name_ << endl;
+    dict_.write(os);
 }
 
 
@@ -55,12 +38,8 @@ bool Foam::explicitSource::read(const dictionary& dict)
 {
     if (basicSource::read(dict))
     {
-        const dictionary& sourceDict = dict.subDict(name());
-        const dictionary& subDictCoeffs = sourceDict.subDict
-        (
-            typeName + "Coeffs"
-        );
-        setFieldData(subDictCoeffs.subDict("fieldData"));
+        coeffs_ = dict.subDict(typeName + "Coeffs");
+        setFieldData(coeffs_.subDict("fieldData"));
         return true;
     }
     else
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/radialActuationDiskSource/radialActuationDiskSource.C b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/radialActuationDiskSource/radialActuationDiskSource.C
index e01a2a57361dbe299df301675f59953669972323..0444a9408b3dc3e81896634da6e641dbff45dfae 100644
--- a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/radialActuationDiskSource/radialActuationDiskSource.C
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/radialActuationDiskSource/radialActuationDiskSource.C
@@ -53,10 +53,10 @@ Foam::radialActuationDiskSource::radialActuationDiskSource
 )
 :
     actuationDiskSource(name, modelType, dict, mesh),
-    dict_(dict.subDict(modelType + "Coeffs")),
+    coeffsDict_(dict.subDict(modelType + "Coeffs")),
     coeffs_()
 {
-    dict_.lookup("coeffs") >> coeffs_;
+    coeffsDict_.lookup("coeffs") >> coeffs_;
     Info<< "    - creating radial actuation disk zone: "
         << this->name() << endl;
 }
@@ -114,14 +114,12 @@ bool Foam::radialActuationDiskSource::read(const dictionary& dict)
 {
     if (basicSource::read(dict))
     {
-        const dictionary& sourceDict = dict.subDict(name());
-        const dictionary& subDictCoeffs =
-            sourceDict.subDict(typeName + "Coeffs");
-        subDictCoeffs.readIfPresent("diskDir", diskDir_);
-        subDictCoeffs.readIfPresent("Cp", Cp_);
-        subDictCoeffs.readIfPresent("Ct", Ct_);
-        subDictCoeffs.readIfPresent("diskArea", diskArea_);
-        subDictCoeffs.lookup("coeffs") >> coeffs_;
+        const dictionary& coeffsDict_ = dict.subDict(typeName + "Coeffs");
+        coeffsDict_.readIfPresent("diskDir", diskDir_);
+        coeffsDict_.readIfPresent("Cp", Cp_);
+        coeffsDict_.readIfPresent("Ct", Ct_);
+        coeffsDict_.readIfPresent("diskArea", diskArea_);
+        coeffsDict_.lookup("coeffs") >> coeffs_;
         return true;
     }
     else
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/radialActuationDiskSource/radialActuationDiskSource.H b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/radialActuationDiskSource/radialActuationDiskSource.H
index 701e752ff400ccb1650a70c5547cff7c05c75da0..245f002fa51446d0035f74c58987764ec3640783 100644
--- a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/radialActuationDiskSource/radialActuationDiskSource.H
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/radialActuationDiskSource/radialActuationDiskSource.H
@@ -62,7 +62,7 @@ namespace Foam
 {
 
 /*---------------------------------------------------------------------------*\
-                     Class radialActuationDiskSource Declaration
+                  Class radialActuationDiskSource Declaration
 \*---------------------------------------------------------------------------*/
 
 class radialActuationDiskSource
@@ -71,8 +71,8 @@ class radialActuationDiskSource
 {
     // Private data
 
-        //- Sub dictionary with model information
-        const dictionary& dict_;
+        //- Coefficients dictionary
+        dictionary coeffsDict_;
 
         //- Coeffcients for the radial distribution
         FixedList<scalar, 3> coeffs_;
@@ -123,7 +123,7 @@ public:
 
         // Public Functions
 
-            //-Source term to fvMatrix<vector>
+            //- Source term to fvMatrix<vector>
             virtual void addSu(fvMatrix<vector>& UEqn);
 
 
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/bladeModel/bladeModel.C b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/bladeModel/bladeModel.C
new file mode 100644
index 0000000000000000000000000000000000000000..a1f76d3e99344fb74acddb2f4e84d235b8449424
--- /dev/null
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/bladeModel/bladeModel.C
@@ -0,0 +1,195 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 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 "bladeModel.H"
+#include "unitConversion.H"
+#include "Tuple2.H"
+#include "vector.H"
+#include "IFstream.H"
+
+
+// * * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * //
+
+bool Foam::bladeModel::readFromFile() const
+{
+    return fName_ != fileName::null;
+}
+
+
+void Foam::bladeModel::interpolateWeights
+(
+    const scalar& xIn,
+    const List<scalar>& values,
+    label& i1,
+    label& i2,
+    scalar& ddx
+) const
+{
+    scalar x = -GREAT;
+    label nElem = values.size();
+
+    i2 = 0;
+    while ((x < xIn) && (i2 < nElem))
+    {
+        x = values[i2];
+        i2++;
+    }
+
+    if (i2 == 0)
+    {
+        i1 = i2;
+        ddx = 0.0;
+        return;
+    }
+    else if (i2 == values.size())
+    {
+        i2 = values.size() - 1;
+        i1 = i2;
+        ddx = 0.0;
+        return;
+    }
+    else
+    {
+        i1 = i2 - 1;
+        ddx = (xIn - values[i1])/(values[i2] - values[i1]);
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::bladeModel::bladeModel(const dictionary& dict)
+:
+    profileName_(),
+    profileID_(),
+    radius_(),
+    twist_(),
+    chord_(),
+    fName_(fileName::null)
+{
+    List<Tuple2<word, vector> > data;
+    if (readFromFile())
+    {
+        IFstream is(fName_);
+        is  >> data;
+    }
+    else
+    {
+        dict.lookup("data") >> data;
+    }
+
+
+    if (data.size() > 0)
+    {
+        profileName_.setSize(data.size());
+        profileID_.setSize(data.size());
+        radius_.setSize(data.size());
+        twist_.setSize(data.size());
+        chord_.setSize(data.size());
+
+        forAll(data, i)
+        {
+            profileName_[i] = data[i].first();
+            profileID_[i] = -1;
+            radius_[i] = data[i].second()[0];
+            twist_[i] = degToRad(data[i].second()[1]);
+            chord_[i] = data[i].second()[2];
+        }
+    }
+    else
+    {
+        FatalErrorIn
+        (
+            "Foam::bladeModel::bladeModel"
+            "("
+                "const dictionary&, "
+                "const word&"
+            ")"
+        )   << "No blade data specified" << exit(FatalError);
+    }
+}
+
+// * * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * //
+
+Foam::bladeModel::~bladeModel()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+const Foam::List<Foam::word>& Foam::bladeModel::profileName() const
+{
+    return profileName_;
+}
+
+
+const Foam::List<Foam::label>& Foam::bladeModel::profileID() const
+{
+    return profileID_;
+}
+
+
+const Foam::List<Foam::scalar>& Foam::bladeModel::radius() const
+{
+    return radius_;
+}
+
+
+const Foam::List<Foam::scalar>& Foam::bladeModel::twist() const
+{
+    return twist_;
+}
+
+
+const Foam::List<Foam::scalar>& Foam::bladeModel::chord() const
+{
+    return chord_;
+}
+
+
+Foam::List<Foam::label>& Foam::bladeModel::profileID()
+{
+    return profileID_;
+}
+
+
+void Foam::bladeModel::interpolate
+(
+    const scalar radius,
+    scalar& twist,
+    scalar& chord,
+    label& i1,
+    label& i2,
+    scalar& invDr
+) const
+{
+    interpolateWeights(radius, radius_, i1, i2, invDr);
+
+    twist = invDr*(twist_[i2] - twist_[i1]) + twist_[i1];
+    chord = invDr*(chord_[i2] - chord_[i1]) + chord_[i1];
+}
+
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/bladeModel/bladeModel.H b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/bladeModel/bladeModel.H
new file mode 100644
index 0000000000000000000000000000000000000000..df26e7bd401a5b1bdf617ec0620dc25ccac1ba4c
--- /dev/null
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/bladeModel/bladeModel.H
@@ -0,0 +1,151 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 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::bladeModel
+
+Description
+    Blade model class
+
+SourceFiles
+    bladeModel.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef bladeModel_H
+#define bladeModel_H
+
+#include "List.H"
+#include "dictionary.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                         Class bladeModel Declaration
+\*---------------------------------------------------------------------------*/
+
+class bladeModel
+{
+
+protected:
+
+    // Protected data
+
+        //- Corresponding profile name per section
+        List<word> profileName_;
+
+        //- Corresponding profile ID per section
+        List<label> profileID_;
+
+        //- Radius [m]
+        List<scalar> radius_;
+
+        //- Twist [deg] on input, converted to [rad]
+        List<scalar> twist_;
+
+        //- Chord [m]
+        List<scalar> chord_;
+
+        //- File name (optional)
+        fileName fName_;
+
+
+    // Protected Member Functions
+
+        //- Return ture if file name is set
+        bool readFromFile() const;
+
+        //- Return the interpolation indices and gradient
+        void interpolateWeights
+        (
+            const scalar& xIn,
+            const List<scalar>& values,
+            label& i1,
+            label& i2,
+            scalar& ddx
+        ) const;
+
+
+public:
+
+    //- Constructor
+    bladeModel(const dictionary& dict);
+
+
+    //- Destructor
+    virtual ~bladeModel();
+
+
+    // Member functions
+
+        // Access
+
+            //- Return const access to the profile name list
+            const List<word>& profileName() const;
+
+            //- Return const access to the profile ID list
+            const List<label>& profileID() const;
+
+            //- Return const access to the radius list
+            const List<scalar>& radius() const;
+
+            //- Return const access to the twist list
+            const List<scalar>& twist() const;
+
+            //- Return const access to the chord list
+            const List<scalar>& chord() const;
+
+
+        // Edit
+
+            //- Return non-const access to the profile ID list
+            List<label>& profileID();
+
+
+        // Evaluation
+
+            //- Return the twist and chord for a given radius
+            virtual void interpolate
+            (
+                const scalar radius,
+                scalar& twist,
+                scalar& chord,
+                label& i1,
+                label& i2,
+                scalar& invDr
+            ) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/profileModel/lookup/lookupProfile.C b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/profileModel/lookup/lookupProfile.C
new file mode 100644
index 0000000000000000000000000000000000000000..ae80d03995d4e11bd5bd17043650240e70f31876
--- /dev/null
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/profileModel/lookup/lookupProfile.C
@@ -0,0 +1,148 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 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 "lookupProfile.H"
+#include "addToRunTimeSelectionTable.H"
+#include "vector.H"
+#include "unitConversion.H"
+#include "IFstream.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(lookupProfile, 0);
+    addToRunTimeSelectionTable(profileModel, lookupProfile, dictionary);
+}
+
+
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+void Foam::lookupProfile::interpolateWeights
+(
+    const scalar& xIn,
+    const List<scalar>& values,
+    label& i1,
+    label& i2,
+    scalar& ddx
+) const
+{
+    scalar x = -GREAT;
+    label nElem = values.size();
+
+    i2 = 0;
+    while ((x < xIn) && (i2 < nElem))
+    {
+        x = values[i2];
+        i2++;
+    }
+
+    if (i2 == 0)
+    {
+        i1 = i2;
+        ddx = 0.0;
+        return;
+    }
+    else if (i2 == values.size())
+    {
+        i2 = values.size() - 1;
+        i1 = i2;
+        ddx = 0.0;
+        return;
+    }
+    else
+    {
+        i1 = i2 - 1;
+        ddx = (xIn - values[i1])/(values[i2] - values[i1]);
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::lookupProfile::lookupProfile
+(
+    const dictionary& dict,
+    const word& modelName
+)
+:
+    profileModel(dict, modelName),
+    AOA_(),
+    Cd_(),
+    Cl_()
+{
+    List<vector> data;
+    if (readFromFile())
+    {
+        IFstream is(fName_);
+        is  >> data;
+    }
+    else
+    {
+        dict.lookup("data") >> data;
+    }
+
+    if (data.size() > 0)
+    {
+        AOA_.setSize(data.size());
+        Cd_.setSize(data.size());
+        Cl_.setSize(data.size());
+
+        forAll(data, i)
+        {
+            AOA_[i] = degToRad(data[i][0]);
+            Cd_[i] = data[i][1];
+            Cl_[i] = data[i][2];
+        }
+    }
+    else
+    {
+        FatalErrorIn
+        (
+            "Foam::lookupProfile::lookupProfile"
+            "("
+                "const dictionary&, "
+                "const word&"
+            ")"
+        )   << "No profile data specified" << exit(FatalError);
+    }
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::lookupProfile::Cdl(const scalar alpha, scalar& Cd, scalar& Cl) const
+{
+    label i1 = -1;
+    label i2 = -1;
+    scalar invAlpha = -1.0;
+    interpolateWeights(alpha, AOA_, i1, i2, invAlpha);
+
+    Cd = invAlpha*(Cd_[i2] - Cd_[i1]) + Cd_[i1];
+    Cl = invAlpha*(Cl_[i2] - Cl_[i1]) + Cl_[i1];
+}
+
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/profileModel/lookup/lookupProfile.H b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/profileModel/lookup/lookupProfile.H
new file mode 100644
index 0000000000000000000000000000000000000000..deb5c1f725ab8096c9a0471e09d8784fba7e6061
--- /dev/null
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/profileModel/lookup/lookupProfile.H
@@ -0,0 +1,124 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 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::lookupProfile
+
+Description
+    Look-up based profile data - drag and lift coefficients are lineraly
+    interpolated based on the supplied angle of attack
+
+    Input in list format:
+
+        data
+        (
+            (AOA1 Cd1 Cl2)
+            (AOA2 Cd2 Cl2)
+            ...
+            (AOAN CdN CdN)
+        );
+
+    where:
+        AOA = angle of attack [deg] converted to [rad] internally
+        Cd  = drag coefficient
+        Cl  = lift coefficient
+
+SourceFiles
+    lookupProfile.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef lookupProfile_H
+#define lookupProfile_H
+
+#include "profileModel.H"
+#include "List.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                        Class lookupProfile Declaration
+\*---------------------------------------------------------------------------*/
+
+class lookupProfile
+:
+    public profileModel
+{
+
+protected:
+
+    // Protected data
+
+        //- List of angle-of-attack values [deg] on input, converted to [rad]
+        List<scalar> AOA_;
+
+        //- List of drag coefficient values
+        List<scalar> Cd_;
+
+        //- List of lift coefficient values
+        List<scalar> Cl_;
+
+
+    // Protected Member Functions
+
+        //- Return the interpolation indices and gradient
+        void interpolateWeights
+        (
+            const scalar& xIn,
+            const List<scalar>& values,
+            label& i1,
+            label& i2,
+            scalar& ddx
+        ) const;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("lookup");
+
+    //- Constructor
+    lookupProfile(const dictionary& dict, const word& modelName);
+
+
+    // Member functions
+
+        // Evaluation
+
+            //- Return the Cd and Cl for a given angle-of-attack
+            virtual void Cdl(const scalar alpha, scalar& Cd, scalar& Cl) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/profileModel/profileModel.C b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/profileModel/profileModel.C
new file mode 100644
index 0000000000000000000000000000000000000000..c9008d276c644533d6a446f453eb20b3d709fafe
--- /dev/null
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/profileModel/profileModel.C
@@ -0,0 +1,99 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 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 "profileModel.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(profileModel, 0);
+    defineRunTimeSelectionTable(profileModel, dictionary);
+}
+
+
+// * * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * //
+
+bool Foam::profileModel::readFromFile() const
+{
+    return fName_ != fileName::null;
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::profileModel::profileModel(const dictionary& dict, const word& name)
+:
+    dict_(dict),
+    name_(name),
+    fName_(fileName::null)
+{
+    dict.readIfPresent("fileName", fName_);
+}
+
+// * * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * //
+
+Foam::profileModel::~profileModel()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+const Foam::word& Foam::profileModel::name() const
+{
+    return name_;
+}
+
+
+Foam::autoPtr<Foam::profileModel> Foam::profileModel::New
+(
+    const dictionary& dict
+)
+{
+    const word& modelName(dict.dictName());
+
+    const word modelType(dict.lookup("type"));
+
+    Info<< "    - creating " << modelType << " profile " << modelName << endl;
+
+    dictionaryConstructorTable::iterator cstrIter =
+        dictionaryConstructorTablePtr_->find(modelType);
+
+    if (cstrIter == dictionaryConstructorTablePtr_->end())
+    {
+        FatalErrorIn("profileModel::New(const dictionary&)")
+            << "Unknown profile model type " << modelType
+            << nl << nl
+            << "Valid model types are :" << nl
+            << dictionaryConstructorTablePtr_->sortedToc()
+            << exit(FatalError);
+    }
+
+    return autoPtr<profileModel>(cstrIter()(dict, modelName));
+}
+
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/profileModel/profileModel.H b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/profileModel/profileModel.H
new file mode 100644
index 0000000000000000000000000000000000000000..5c850ec1bb30a214b71b35586e0c09b8af57039f
--- /dev/null
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/profileModel/profileModel.H
@@ -0,0 +1,136 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 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::profileModel
+
+Description
+    Base class for profile models
+
+SourceFiles
+    profileModel.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef profileModel_H
+#define profileModel_H
+
+#include "autoPtr.H"
+#include "runTimeSelectionTables.H"
+#include "dictionary.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                        Class profileModel Declaration
+\*---------------------------------------------------------------------------*/
+
+class profileModel
+{
+
+protected:
+
+    // Protected data
+
+        //- Coefficients dictionary
+        const dictionary dict_;
+
+        //- Name of profile model
+        const word name_;
+
+        //- File name (optional)
+        fileName fName_;
+
+
+    // Protected Member Functions
+
+        //- Return ture if file name is set
+        bool readFromFile() const;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("profileModel");
+
+
+        // Declare run-time constructor selection table
+        declareRunTimeSelectionTable
+        (
+            autoPtr,
+            profileModel,
+            dictionary,
+            (
+                const dictionary& dict,
+                const word& modelName
+            ),
+            (dict, modelName)
+        );
+
+
+    // Selectors
+
+        //- Return a reference to the selected basicSource model
+        static autoPtr<profileModel> New(const dictionary& dict);
+
+
+    //- Constructor
+    profileModel(const dictionary& dict, const word& modelName);
+
+
+    //- Destructor
+    virtual ~profileModel();
+
+
+    // Member functions
+
+        // Access
+
+            //- Return const access to the source name
+            const word& name() const;
+
+
+        // Evaluation
+
+            //- Return the Cd and Cl for a given angle-of-attack
+            virtual void Cdl
+            (
+                const scalar alpha,
+                scalar& Cd,
+                scalar& Cl
+            ) const = 0;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/profileModel/profileModelList.C b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/profileModel/profileModelList.C
new file mode 100644
index 0000000000000000000000000000000000000000..904b01372b540aadf146c3e345744ba0d41298ad
--- /dev/null
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/profileModel/profileModelList.C
@@ -0,0 +1,121 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 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 "profileModelList.H"
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::profileModelList::profileModelList
+(
+    const dictionary& dict,
+    const bool readFields
+)
+:
+    PtrList<profileModel>(),
+    dict_(dict)
+{
+    if (readFields)
+    {
+        wordList modelNames(dict.toc());
+
+        Info<< "    Constructing blade profiles:" << endl;
+
+        if (modelNames.size() > 0)
+        {
+            this->setSize(modelNames.size());
+
+            forAll(modelNames, i)
+            {
+                const word& modelName = modelNames[i];
+
+                this->set
+                (
+                    i,
+                    profileModel::New(dict.subDict(modelName))
+                );
+            }
+        }
+        else
+        {
+            Info<< "        none" << endl;
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * //
+
+Foam::profileModelList::~profileModelList()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::profileModelList::connectBlades
+(
+    const List<word>& names,
+    List<label>& addr
+) const
+{
+    // construct the addressing between blade sections and profiles
+    forAll(names, bI)
+    {
+        label index = -1;
+        const word& profileName = names[bI];
+
+        forAll(*this, pI)
+        {
+            const profileModel& pm = this->operator[](pI);
+
+            if (pm.name() == profileName)
+            {
+                index = pI;
+                break;
+            }
+        }
+
+        if (index == -1)
+        {
+            List<word> profileNames(size());
+            forAll(*this, i)
+            {
+                const profileModel& pm = this->operator[](i);
+                profileNames[i] = pm.name();
+            }
+
+            FatalErrorIn("void Foam::connectBlades(List<word>& names) const")
+                << "Profile " << profileName << " could not be found "
+                << "in profile list.  Available profiles are"
+                << profileNames << exit(FatalError);
+        }
+        else
+        {
+            addr[bI] = index;
+        }
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/profileModel/profileModelList.H b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/profileModel/profileModelList.H
new file mode 100644
index 0000000000000000000000000000000000000000..74326dced4b74ed907493363c2f066c831c212cc
--- /dev/null
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/profileModel/profileModelList.H
@@ -0,0 +1,91 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 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::profileModelList
+
+Description
+    Base class for profile models
+
+SourceFiles
+    profileModel.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef profileModelList_H
+#define profileModelList_H
+
+#include "PtrList.H"
+#include "profileModel.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                    Class profileModelList Declaration
+\*---------------------------------------------------------------------------*/
+
+class profileModelList
+:
+    public PtrList<profileModel>
+{
+
+protected:
+
+    // Protected data
+
+        //- Dictionary
+        const dictionary dict_;
+
+
+public:
+
+    //- Constructor
+    profileModelList(const dictionary& dict, const bool readFields = true);
+
+    //- Destructor
+    ~profileModelList();
+
+
+    // Member Functions
+
+        //- Set blade->profile addressing
+        void connectBlades
+        (
+            const List<word>& names,
+            List<label>& addr
+        ) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/profileModel/series/seriesProfile.C b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/profileModel/series/seriesProfile.C
new file mode 100644
index 0000000000000000000000000000000000000000..865ed3ab62ec7459c76ad59b6e7bb1d417c233f1
--- /dev/null
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/profileModel/series/seriesProfile.C
@@ -0,0 +1,116 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 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 "seriesProfile.H"
+#include "addToRunTimeSelectionTable.H"
+#include "IFstream.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(seriesProfile, 0);
+    addToRunTimeSelectionTable(profileModel, seriesProfile, dictionary);
+}
+
+
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+Foam::scalar Foam::seriesProfile::evaluate
+(
+    const scalar& xIn,
+    const List<scalar>& values
+) const
+{
+    scalar result = 0.0;
+
+    forAll(values, i)
+    {
+        result += values[i]*cos((i+1)*xIn);
+    }
+
+    return result;
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::seriesProfile::seriesProfile
+(
+    const dictionary& dict,
+    const word& modelName
+)
+:
+    profileModel(dict, modelName),
+    CdCoeffs_(),
+    ClCoeffs_()
+{
+    if (readFromFile())
+    {
+        IFstream is(fName_);
+        is  >> CdCoeffs_ >> ClCoeffs_;
+    }
+    else
+    {
+        dict.lookup("CdCoeffs") >> CdCoeffs_;
+        dict.lookup("ClCoeffs") >> ClCoeffs_;
+    }
+
+
+    if (CdCoeffs_.empty())
+    {
+        FatalErrorIn
+        (
+            "Foam::seriesProfile::seriesProfile"
+            "("
+                "const dictionary&, "
+                "const word&"
+            ")"
+        )   << "CdCoeffs must be specified" << exit(FatalError);
+    }
+    if (ClCoeffs_.empty())
+    {
+        FatalErrorIn
+        (
+            "Foam::seriesProfile::seriesProfile"
+            "("
+                "const dictionary&, "
+                "const word&"
+            ")"
+        )   << "ClCoeffs must be specified" << exit(FatalError);
+    }
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::seriesProfile::Cdl(const scalar alpha, scalar& Cd, scalar& Cl) const
+{
+    Cd = evaluate(alpha, CdCoeffs_);
+    Cl = evaluate(alpha, ClCoeffs_);
+}
+
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/profileModel/series/seriesProfile.H b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/profileModel/series/seriesProfile.H
new file mode 100644
index 0000000000000000000000000000000000000000..73b474aae1f3bb22bbdbacc1b29ea35a914051fb
--- /dev/null
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/profileModel/series/seriesProfile.H
@@ -0,0 +1,116 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 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::seriesProfile
+
+Description
+    Series-up based profile data - drag and lift coefficients computed as
+    sum of cosine series
+
+        Cd = sum_i(CdCoeff)*cos(i*AOA)
+        Cl = sum_i(ClCoeff)*cos(i*AOA)
+
+    where:
+        AOA = angle of attack [deg] converted to [rad] internally
+        Cd = drag coefficent
+        Cl = lift coefficent
+
+    Input in two (arbitrary length) lists:
+
+        CdCoeffs (coeff1 coeff2 ... coeffN);
+        ClCoeffs (coeff1 coeff2 ... coeffN);
+
+SourceFiles
+    seriesProfile.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef seriesProfile_H
+#define seriesProfile_H
+
+#include "profileModel.H"
+#include "List.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                        Class seriesProfile Declaration
+\*---------------------------------------------------------------------------*/
+
+class seriesProfile
+:
+    public profileModel
+{
+
+protected:
+
+    // Protected data
+
+        //- List of drag coefficient values
+        List<scalar> CdCoeffs_;
+
+        //- List of lift coefficient values
+        List<scalar> ClCoeffs_;
+
+
+    // Protected Member Functions
+
+        //- Evaluate
+        scalar evaluate
+        (
+            const scalar& xIn,
+            const List<scalar>& values
+        ) const;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("series");
+
+    //- Constructor
+    seriesProfile(const dictionary& dict, const word& modelName);
+
+
+    // Member functions
+
+        // Evaluation
+
+            //- Return the Cd and Cl for a given angle-of-attack
+            virtual void Cdl(const scalar alpha, scalar& Cd, scalar& Cl) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/rotorDiskSource.C b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/rotorDiskSource.C
new file mode 100644
index 0000000000000000000000000000000000000000..db4fd5d80336bb3c72f418c02e1b18bd0169c32c
--- /dev/null
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/rotorDiskSource.C
@@ -0,0 +1,495 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 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 "rotorDiskSource.H"
+#include "addToRunTimeSelectionTable.H"
+#include "mathematicalConstants.H"
+#include "unitConversion.H"
+#include "geometricOneField.H"
+
+using namespace Foam::constant;
+
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(rotorDiskSource, 0);
+    addToRunTimeSelectionTable(basicSource, rotorDiskSource, dictionary);
+
+    template<> const char* NamedEnum<rotorDiskSource::geometryModeType, 2>::
+        names[] =
+    {
+        "auto",
+        "specified"
+    };
+
+    const NamedEnum<rotorDiskSource::geometryModeType, 2>
+        rotorDiskSource::geometryModeTypeNames_;
+
+    template<> const char* NamedEnum<rotorDiskSource::inletFlowType, 3>::
+        names[] =
+    {
+        "fixed",
+        "surfaceNormal",
+        "local"
+    };
+
+    const NamedEnum<rotorDiskSource::inletFlowType, 3>
+        rotorDiskSource::inletFlowTypeNames_;
+}
+
+
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+void Foam::rotorDiskSource::checkData()
+{
+    switch (selectionMode())
+    {
+        case smCellSet:
+        case smCellZone:
+        case smAll:
+        {
+            // set the profile ID for each blade section
+            profiles_.connectBlades(blade_.profileName(), blade_.profileID());
+            switch (inletFlow_)
+            {
+                case ifFixed:
+                {
+                    coeffs_.lookup("inletVelocity") >> inletVelocity_;
+                    break;
+                }
+                case ifSurfaceNormal:
+                {
+                    scalar UIn
+                    (
+                        readScalar(coeffs_.lookup("inletNormalVelocity"))
+                    );
+                    inletVelocity_ = -coordSys_.e3()*UIn;
+                    break;
+                }
+                case ifLocal:
+                {
+                    // do nothing
+                    break;
+                }
+                default:
+                {
+                    FatalErrorIn("void rotorDiskSource::checkData()")
+                        << "Unknown inlet velocity type" << abort(FatalError);
+                }
+            }
+
+
+            break;
+        }
+        default:
+        {
+            FatalErrorIn("void rotorDiskSource::checkData()")
+                << "Source cannot be used with '"
+                << selectionModeTypeNames_[selectionMode()]
+                << "' mode.  Please use one of: " << nl
+                << selectionModeTypeNames_[smCellSet] << nl
+                << selectionModeTypeNames_[smCellZone] << nl
+                << selectionModeTypeNames_[smAll]
+                << exit(FatalError);
+        }
+    }
+}
+
+
+void Foam::rotorDiskSource::setFaceArea(vector& axis, const bool correct)
+{
+    // calculate rotor face areas
+    const vectorField& Sf = mesh_.Sf();
+    const scalarField& magSf = mesh_.magSf();
+
+    boolList selectedCells(mesh_.nCells(), false);
+    boolList processedFaces(mesh_.nFaces(), false);
+    UIndirectList<bool>(selectedCells, cells_) = boolList(cells_.size(), true);
+
+    vector n = vector::zero;
+
+    label nFace = 0;
+    area_ = 0.0;
+    forAll(cells_, i)
+    {
+        const label cellI = cells_[i];
+        const cell& cFaces = mesh_.cells()[cellI];
+        forAll(cFaces, j)
+        {
+            const label faceI = cFaces[j];
+            label own = mesh_.owner()[faceI];
+            label nbr = mesh_.neighbour()[faceI];
+            if
+            (
+                !processedFaces[faceI]
+             && (selectedCells[own] != selectedCells[nbr])
+            )
+            {
+                if (selectedCells[own])
+                {
+                    if (((Sf[faceI]/magSf[faceI]) & axis) > 0.8)
+                    {
+                        area_[i] += magSf[faceI];
+                        n += Sf[faceI];
+                        nFace++;
+                    }
+                }
+                else if (selectedCells[nbr])
+                {
+                    if (((-Sf[faceI]/magSf[faceI]) & axis) > 0.8)
+                    {
+                        area_[i] += magSf[faceI];
+                        n -= Sf[faceI];
+                        nFace++;
+                    }
+                }
+                processedFaces[faceI] = true;
+            }
+        }
+    }
+
+    if (correct && (nFace > 0))
+    {
+        axis = n/mag(n);
+    }
+}
+
+
+void Foam::rotorDiskSource::createCoordinateSystem()
+{
+    // construct the local rotor co-prdinate system
+    vector origin(vector::zero);
+    vector axis(vector::zero);
+    vector refDir(vector::zero);
+
+    geometryModeType gm =
+        geometryModeTypeNames_.read(coeffs_.lookup("geometryMode"));
+
+    switch (gm)
+    {
+        case gmAuto:
+        {
+            // determine rotation origin
+            scalar sumV = 0.0;
+            const scalarField& V = mesh_.V();
+            const vectorField& C = mesh_.C();
+            forAll(cells_, i)
+            {
+                const label cellI = cells_[i];
+                sumV += V[cellI];
+                origin += V[cellI]*C[cellI];
+            }
+            origin /= sumV;
+
+            // determine first radial vector
+            vector dx1(vector::zero);
+            scalar magR = -GREAT;
+            forAll(cells_, i)
+            {
+                const label cellI = cells_[i];
+                vector test = C[cellI] - origin;
+                if (mag(test) > magR)
+                {
+                    dx1 = test;
+                    magR = mag(test);
+                }
+            }
+
+            // determine second radial vector and cross to determine axis
+            forAll(cells_, i)
+            {
+                const label cellI = cells_[i];
+                vector dx2 = C[cellI] - origin;
+                if (mag(dx2) > 0.5*magR)
+                {
+                    axis = dx1 ^ dx2;
+                    if (mag(axis) > SMALL)
+                    {
+                        break;
+                    }
+                }
+            }
+            axis /= mag(axis);
+
+            // axis direction is somewhat arbitrary - check if user needs
+            // needs to reverse
+            bool reverse(readBool(coeffs_.lookup("reverseAxis")));
+            if (reverse)
+            {
+                axis *= -1.0;
+            }
+
+            coeffs_.lookup("refDirection") >> refDir;
+
+            // set the face areas and apply correction to calculated axis
+            // e.g. if cellZone is more than a single layer in thickness
+            setFaceArea(axis, true);
+
+            break;
+        }
+        case gmSpecified:
+        {
+            coeffs_.lookup("origin") >> origin;
+            coeffs_.lookup("axis") >> axis;
+            coeffs_.lookup("refDirection") >> refDir;
+
+            setFaceArea(axis, false);
+
+            break;
+        }
+        default:
+        {
+            FatalErrorIn
+            (
+                "rotorDiskSource::createCoordinateSystem(const geometryMode&);"
+            )   << "Unknown geometryMode " << geometryModeTypeNames_[gm]
+                << ". Available geometry modes include "
+                << geometryModeTypeNames_ << exit(FatalError);
+        }
+    }
+
+    coordSys_ = cylindricalCS("rotorCoordSys", origin, axis, refDir, false);
+
+    const scalar sumArea = gSum(area_);
+    const scalar diameter = Foam::sqrt(4.0*sumArea/mathematical::pi);
+    Info<< "    Rotor gometry:" << nl
+        << "    - disk diameter = " << diameter << nl
+        << "    - disk area     = " << sumArea << nl
+        << "    - origin        = " << coordSys_.origin() << nl
+        << "    - r-axis        = " << coordSys_.e1() << nl
+        << "    - psi-axis      = " << coordSys_.e2() << nl
+        << "    - z-axis        = " << coordSys_.e3() << endl;
+}
+
+
+void Foam::rotorDiskSource::constructGeometry()
+{
+    const vectorField& C = mesh_.C();
+
+    const vector rDir = coordSys_.e1();
+    const vector zDir = coordSys_.e3();
+
+    forAll(cells_, i)
+    {
+        const label cellI = cells_[i];
+
+        // position in rotor co-ordinate system
+        x_[i] = coordSys_.localPosition(C[cellI]);
+
+        // cache max radius
+        rMax_ = max(rMax_, x_[i].x());
+
+        // determine swept angle relative to rDir axis
+        scalar psi = x_[i].y() - rDir.y();
+
+        // blade flap angle
+        scalar beta = flap_.beta0 - flap_.beta1*cos(psi) - flap_.beta2*sin(psi);
+
+        // determine rotation tensor to convert into the rotor cone plane
+        scalar c = cos(-beta);
+        scalar s = sin(-beta);
+        R_[i] = tensor(1, 0, 0, 0, c, s, 0, -s, c);
+
+        // geometric angle of attack - not including twist
+        alphag_[i] = trim_.alphaC - trim_.A*cos(psi) - trim_.B*sin(psi);
+    }
+}
+
+
+Foam::tmp<Foam::vectorField> Foam::rotorDiskSource::inflowVelocity
+(
+    const volVectorField& U
+) const
+{
+    switch (inletFlow_)
+    {
+        case ifFixed:
+        case ifSurfaceNormal:
+        {
+            return tmp<vectorField>
+            (
+                new vectorField(mesh_.nCells(), inletVelocity_)
+            );
+
+            break;
+        }
+        case ifLocal:
+        {
+            return U.internalField();
+
+            break;
+        }
+        default:
+        {
+            FatalErrorIn
+            (
+                "Foam::tmp<Foam::vectorField> "
+                "Foam::rotorDiskSource::inflowVelocity"
+                "(const volVectorField&) const"
+            )   << "Unknown inlet flow specification" << abort(FatalError);
+        }
+    }
+
+    return tmp<vectorField>(new vectorField(mesh_.nCells(), vector::zero));
+}
+
+
+// * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * * //
+
+Foam::rotorDiskSource::rotorDiskSource
+(
+    const word& name,
+    const word& modelType,
+    const dictionary& dict,
+    const fvMesh& mesh
+
+)
+:
+    basicSource(name, modelType, dict, mesh),
+    coeffs_(dict_.subDict(type() + "Coeffs")),
+    rhoName_("none"),
+    omega_(0.0),
+    nBlades_(0),
+    inletFlow_(ifLocal),
+    inletVelocity_(vector::zero),
+    tipEffect_(1.0),
+    flap_(),
+    trim_(),
+    blade_(coeffs_.subDict("blade")),
+    profiles_(coeffs_.subDict("profiles")),
+    x_(cells_.size(), vector::zero),
+    R_(cells_.size(), I),
+    alphag_(cells_.size(), 0.0),
+    area_(cells_.size(), 0.0),
+    coordSys_(false),
+    rMax_(0.0)
+{
+    read(dict);
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::rotorDiskSource::~rotorDiskSource()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::rotorDiskSource::addSu(fvMatrix<vector>& UEqn)
+{
+    // add source to lhs of eqn
+
+    const volVectorField& U = UEqn.psi();
+
+    if (UEqn.dimensions() == dimForce)
+    {
+        coeffs_.lookup("rhoName") >> rhoName_;
+
+        const volScalarField& rho =
+            mesh_.lookupObject<volScalarField>(rhoName_);
+
+        UEqn += calculateForces
+            (
+                rho.internalField(),
+                inflowVelocity(U),
+                dimForce/dimVolume
+            );
+    }
+    else
+    {
+        UEqn += calculateForces
+            (
+                oneField(),
+                inflowVelocity(U),
+                dimForce/dimVolume/dimDensity
+            );
+    }
+}
+
+
+void Foam::rotorDiskSource::addSu(fvMatrix<scalar>& UEqn)
+{
+    // do nothing
+}
+
+
+void Foam::rotorDiskSource::writeData(Ostream& os) const
+{
+    os  << indent << name_ << endl;
+    dict_.write(os);
+}
+
+
+bool Foam::rotorDiskSource::read(const dictionary& dict)
+{
+    if (basicSource::read(dict))
+    {
+        coeffs_ = dict.subDict(type() + "Coeffs");
+
+        scalar rpm(readScalar(coeffs_.lookup("rpm")));
+        omega_ = rpm/60.0*mathematical::twoPi;
+
+        coeffs_.lookup("nBlades") >> nBlades_;
+
+        inletFlow_ = inletFlowTypeNames_.read(coeffs_.lookup("inletFlowType"));
+
+        coeffs_.lookup("tipEffect") >> tipEffect_;
+
+        const dictionary& flapCoeffs(coeffs_.subDict("flapCoeffs"));
+        flapCoeffs.lookup("beta0") >> flap_.beta0;
+        flapCoeffs.lookup("beta1") >> flap_.beta1;
+        flapCoeffs.lookup("beta2") >> flap_.beta2;
+        flap_.beta0 = degToRad(flap_.beta0);
+
+        const dictionary& trimCoeffs(coeffs_.subDict("trimCoeffs"));
+        trimCoeffs.lookup("alphaC") >> trim_.alphaC;
+        trimCoeffs.lookup("A") >> trim_.A;
+        trimCoeffs.lookup("B") >> trim_.B;
+        trim_.alphaC = degToRad(trim_.alphaC);
+
+        checkData();
+
+        createCoordinateSystem();
+
+        constructGeometry();
+
+        if (debug)
+        {
+            writeField("alphag", alphag_, true);
+            writeField("faceArea", area_, true);
+        }
+
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/rotorDiskSource.H b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/rotorDiskSource.H
new file mode 100644
index 0000000000000000000000000000000000000000..0d646b98996b3174b4693da90e37346620adec46
--- /dev/null
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/rotorDiskSource.H
@@ -0,0 +1,249 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 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::rotorDiskSource
+
+Description
+    Cell-zone based momemtum source
+
+    Source approximates the mean effects of rotor forces on a cylindrical
+    region within the domain
+
+SourceFiles
+    rotorDiskSource.C
+    rotorDiskSourceTemplates.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef rotorDiskSource_H
+#define rotorDiskSource_H
+
+#include "basicSource.H"
+#include "cylindricalCS.H"
+#include "NamedEnum.H"
+#include "bladeModel.H"
+#include "profileModelList.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                      Class rotorDiskSource Declaration
+\*---------------------------------------------------------------------------*/
+
+class rotorDiskSource
+:
+    public basicSource
+{
+public:
+
+    enum geometryModeType
+    {
+        gmAuto,
+        gmSpecified
+    };
+    static const NamedEnum<geometryModeType, 2> geometryModeTypeNames_;
+
+    enum inletFlowType
+    {
+        ifFixed,
+        ifSurfaceNormal,
+        ifLocal
+    };
+    static const NamedEnum<inletFlowType, 3> inletFlowTypeNames_;
+
+
+protected:
+
+    // Helper structures to encapsulate flap and trim data
+
+        struct flapData
+        {
+            scalar beta0;   // coning angle [deg]
+            scalar beta1;   // lateral flapping coeff
+            scalar beta2;   // longitudinal flapping coeff
+        };
+
+        struct trimData
+        {
+            scalar alphaC;  // collective pitch angle [deg]
+            scalar A;       // lateral cyclic coeff
+            scalar B;       // longitudinal cyclic coeff
+        };
+
+
+    // Protected data
+
+        //- Coefficients dictionary
+        dictionary coeffs_;
+
+        //- Name of density field
+        word rhoName_;
+
+        //- Rotational speed [rad/s]
+        scalar omega_;
+
+        //- Number of blades
+        label nBlades_;
+
+        //- Inlet flow type
+        inletFlowType inletFlow_;
+
+        //- Inlet velocity for specified iinflow
+        vector inletVelocity_;
+
+        //- Tip effect [0-1]
+        //  Ratio of blade radius beyond which lift=0
+        scalar tipEffect_;
+
+        //- Blade flap coefficients [rad/s]
+        flapData flap_;
+
+        //- Blad trim coefficients
+        trimData trim_;
+
+        //- Blade data
+        bladeModel blade_;
+
+        //- Profile data
+        profileModelList profiles_;
+
+        //- Cell centre positions in local rotor frame (Cartesian x, y, z)
+        List<point> x_;
+
+        //- Rotation tensor for flap angle
+        List<tensor> R_;
+
+        //- Geometric angle of attack [deg]
+        List<scalar> alphag_;
+
+        //- Area [m2]
+        List<scalar> area_;
+
+        //- Rotor co-ordinate system (r, theta, z)
+        cylindricalCS coordSys_;
+
+        //- Maximum radius
+        scalar rMax_;
+
+        
+    // Protected Member Functions
+
+        //- Check data
+        void checkData();
+
+        //- Set the face areas per cell, and optionally correct the rotor axis
+        void setFaceArea(vector& axis, const bool correct);
+
+        //- Create the co-ordinate system
+        void createCoordinateSystem();
+
+        //- Construct geometry
+        void constructGeometry();
+
+        //- Return the inlet flow field
+        tmp<vectorField> inflowVelocity(const volVectorField& U) const;
+
+        //- Calculate forces
+        template<class RhoType>
+        tmp<volVectorField> calculateForces
+        (
+            const RhoType& rho,
+            const vectorField& U,
+            const dimensionSet& dims
+        );
+
+        //- Helper function to write rotor values
+        template<class Type>
+        void writeField
+        (
+            const word& name,
+            const List<Type>& values,
+            const bool writeNow = false
+        ) const;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("rotorDisk");
+
+
+    // Constructors
+
+        
+        //- Construct from components
+        rotorDiskSource
+        (
+            const word& name,
+            const word& modelType,
+            const dictionary& dict,
+            const fvMesh& mesh
+        );
+
+
+    //- Destructor
+    virtual ~rotorDiskSource();
+
+
+    // Member Functions
+
+
+        // Source term addition
+
+            //- Source term to fvMatrix<vector>
+            virtual void addSu(fvMatrix<vector>& UEqn);
+
+            //- Source term to fvMatrix<scalar>
+            virtual void addSu(fvMatrix<scalar>& UEqn);
+
+
+        // I-O
+
+            //- Write the source properties
+            virtual void writeData(Ostream&) const;
+
+            //- Read source dictionary
+            virtual bool read(const dictionary& dict);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+    #include "rotorDiskSourceTemplates.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
+
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/rotorDiskSourceTemplates.C b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/rotorDiskSourceTemplates.C
new file mode 100644
index 0000000000000000000000000000000000000000..5bc97c703f99f4ab4e4b316b0c1c9213a31c2fc5
--- /dev/null
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/rotorDiskSource/rotorDiskSourceTemplates.C
@@ -0,0 +1,205 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 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 "rotorDiskSource.H"
+#include "addToRunTimeSelectionTable.H"
+#include "mathematicalConstants.H"
+#include "unitConversion.H"
+
+using namespace Foam::constant;
+
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+template<class Type>
+void Foam::rotorDiskSource::writeField
+(
+    const word& name,
+    const List<Type>& values,
+    const bool writeNow
+) const
+{
+    typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
+
+    if (mesh_.time().outputTime() || writeNow)
+    {
+        tmp<fieldType> tfld
+        (
+            new fieldType
+            (
+                IOobject
+                (
+                    name,
+                    mesh_.time().timeName(),
+                    mesh_,
+                    IOobject::NO_READ,
+                    IOobject::NO_WRITE
+                ),
+                mesh_,
+                dimensioned<Type>("zero", dimless, pTraits<Type>::zero)
+            )
+        );
+
+        Field<Type>& fld = tfld().internalField();
+
+        if (cells_.size() != values.size())
+        {
+            FatalErrorIn("") << "cells_.size() != values_.size()"
+                << abort(FatalError);
+        }
+
+        forAll(cells_, i)
+        {
+            const label cellI = cells_[i];
+            fld[cellI] = values[i];
+        }
+
+        tfld().write();
+    }
+}
+
+
+template<class RhoType>
+Foam::tmp<Foam::volVectorField> Foam::rotorDiskSource::calculateForces
+(
+    const RhoType& rho,
+    const vectorField& U,
+    const dimensionSet& dims
+)
+{
+    tmp<volVectorField> tForce
+    (
+        new volVectorField
+        (
+            IOobject
+            (
+                "rotorForce",
+                mesh_.time().timeName(),
+                mesh_,
+                IOobject::NO_READ,
+                IOobject::NO_WRITE
+            ),
+            mesh_,
+            dimensionedVector("zero", dims, vector::zero)
+        )
+    );
+
+    vectorField& force = tForce().internalField();
+    const scalarField& V = mesh_.V();
+
+
+    // logging info
+    scalar dragEff = 0.0;
+    scalar liftEff = 0.0;
+    scalar AOAmin = GREAT;
+    scalar AOAmax = -GREAT;
+
+    forAll(cells_, i)
+    {
+        if (area_[i] > ROOTVSMALL)
+        {
+            const label cellI = cells_[i];
+
+            const scalar radius = x_[i].x();
+
+            // apply correction due to flap in cartesian frame
+            vector Uc = R_[i] & U[cellI];
+
+            // velocity in local reference frame
+            Uc = coordSys_.localVector(Uc);
+
+            // set radial component of velocity to zero
+            Uc.x() = 0.0;
+
+            // remove blade linear velocity from blade normal component
+            Uc.y() -= radius*omega_;
+
+            // velocity magnitude
+            scalar magUc = mag(Uc);
+
+            // determine blade data for this radius
+            // i1 = index of upper bound data point in blade list
+            scalar twist = 0.0;
+            scalar chord = 0.0;
+            label i1 = -1;
+            label i2 = -1;
+            scalar invDr = 0.0;
+            blade_.interpolate(radius, twist, chord, i1, i2, invDr);
+
+            // effective angle of attack
+            scalar alphaEff = alphag_[i] + twist - atan(Uc.z()/Uc.y());
+            AOAmin = min(AOAmin, alphaEff);
+            AOAmax = max(AOAmax, alphaEff);
+
+            // determine profile data for this radius and angle of attack
+            const label profile1 = blade_.profileID()[i1];
+            const label profile2 = blade_.profileID()[i2];
+
+            scalar Cd1 = 0.0;
+            scalar Cl1 = 0.0;
+            profiles_[profile1].Cdl(alphaEff, Cd1, Cl1);
+
+            scalar Cd2 = 0.0;
+            scalar Cl2 = 0.0;
+            profiles_[profile2].Cdl(alphaEff, Cd2, Cl2);
+
+            scalar Cd = invDr*(Cd2 - Cd1) + Cd1;
+            scalar Cl = invDr*(Cl2 - Cl1) + Cl1;
+
+            // apply tip effect for blade lift
+            scalar tipFactor = 1.0;
+            if (radius/rMax_ > tipEffect_)
+            {
+                tipFactor = 0.0;
+            }
+
+            // calculate forces
+            scalar pDyn = 0.5*rho[cellI]*sqr(magUc);
+            scalar f = pDyn*chord*nBlades_*area_[i]/(mathematical::twoPi);
+            vector localForce = vector(0.0, f*Cd, tipFactor*f*Cl);
+
+            // accumulate forces
+            dragEff += localForce.y();
+            liftEff += localForce.z();
+
+            // convert force to global cartesian co-ordinate system
+            force[cellI] = coordSys_.globalVector(localForce);
+
+            force[cellI] /= V[cellI];
+        }
+    }
+
+
+    Info<< type() << " output:" << nl
+        << "    min/max(AOA)   = " << radToDeg(AOAmin) << ", "
+        << radToDeg(AOAmax) << nl
+        << "    Effective drag = " << dragEff << nl
+        << "    Effective lift = " << liftEff << endl;
+
+
+    return tForce;
+}
+
+
+// ************************************************************************* //
diff --git a/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.C b/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.C
index d080a624a2f68ca809fbcac43d5bdeaa1716ab1b..af83ca14295550c13f6540812abd0dd43daf5b78 100644
--- a/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.C
+++ b/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.C
@@ -239,7 +239,7 @@ void Foam::SurfaceFilmModel<CloudType>::cacheFilmFields
 
     diameterParcelPatch_ =
         filmModel.cloudDiameterTrans().boundaryField()[filmPatchI];
-    filmModel.toPrimary(filmPatchI, diameterParcelPatch_);
+    filmModel.toPrimary(filmPatchI, diameterParcelPatch_, maxOp<scalar>());
 
     UFilmPatch_ = filmModel.Us().boundaryField()[filmPatchI];
     filmModel.toPrimary(filmPatchI, UFilmPatch_);
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C
index 535583a9e13578de3a750ce3804e15122273fc17..2e6a4b4384da5fab4fd8602aa60c85a1295dd619 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C
@@ -1333,11 +1333,12 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
 
 
 template<class SourcePatch, class TargetPatch>
-template<class Type>
+template<class Type, class BinaryOp>
 Foam::tmp<Foam::Field<Type> >
 Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToSource
 (
-    const Field<Type>& fld
+    const Field<Type>& fld,
+    const BinaryOp& bop
 ) const
 {
     if (fld.size() != tgtAddress_.size())
@@ -1377,7 +1378,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToSource
 
             forAll(faces, i)
             {
-                result[faceI] += work[faces[i]]*weights[i];
+                result[faceI] = bop(result[faceI], work[faces[i]]*weights[i]);
             }
         }
     }
@@ -1390,7 +1391,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToSource
 
             forAll(faces, i)
             {
-                result[faceI] += fld[faces[i]]*weights[i];
+                result[faceI] = bop(result[faceI], fld[faces[i]]*weights[i]);
             }
         }
     }
@@ -1400,24 +1401,26 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToSource
 
 
 template<class SourcePatch, class TargetPatch>
-template<class Type>
+template<class Type, class BinaryOp>
 Foam::tmp<Foam::Field<Type> >
 Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToSource
 (
-    const tmp<Field<Type> >& tFld
+    const tmp<Field<Type> >& tFld,
+    const BinaryOp& bop
 ) const
 {
-    return interpolateToSource(tFld());
+    return interpolateToSource(tFld(), bop);
 }
 
 
 
 template<class SourcePatch, class TargetPatch>
-template<class Type>
+template<class Type, class BinaryOp>
 Foam::tmp<Foam::Field<Type> >
 Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToTarget
 (
-    const Field<Type>& fld
+    const Field<Type>& fld,
+    const BinaryOp& bop
 ) const
 {
     if (fld.size() != srcAddress_.size())
@@ -1457,7 +1460,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToTarget
 
             forAll(faces, i)
             {
-                result[faceI] += work[faces[i]]*weights[i];
+                result[faceI] = bop(result[faceI], work[faces[i]]*weights[i]);
             }
         }
     }
@@ -1470,7 +1473,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToTarget
 
             forAll(faces, i)
             {
-                result[faceI] += fld[faces[i]]*weights[i];
+                result[faceI] = bop(result[faceI], fld[faces[i]]*weights[i]);
             }
         }
     }
@@ -1479,6 +1482,55 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToTarget
 }
 
 
+template<class SourcePatch, class TargetPatch>
+template<class Type, class BinaryOp>
+Foam::tmp<Foam::Field<Type> >
+Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToTarget
+(
+    const tmp<Field<Type> >& tFld,
+    const BinaryOp& bop
+) const
+{
+    return interpolateToTarget(tFld(), bop);
+}
+
+
+template<class SourcePatch, class TargetPatch>
+template<class Type>
+Foam::tmp<Foam::Field<Type> >
+Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToSource
+(
+    const Field<Type>& fld
+) const
+{
+    return interpolateToSource(fld, sumOp<Type>());
+}
+
+
+template<class SourcePatch, class TargetPatch>
+template<class Type>
+Foam::tmp<Foam::Field<Type> >
+Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToSource
+(
+    const tmp<Field<Type> >& tFld
+) const
+{
+    return interpolateToSource(tFld, sumOp<Type>());
+}
+
+
+template<class SourcePatch, class TargetPatch>
+template<class Type>
+Foam::tmp<Foam::Field<Type> >
+Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToTarget
+(
+    const Field<Type>& fld
+) const
+{
+    return interpolateToSource(fld, sumOp<Type>());
+}
+
+
 template<class SourcePatch, class TargetPatch>
 template<class Type>
 Foam::tmp<Foam::Field<Type> >
@@ -1487,7 +1539,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToTarget
     const tmp<Field<Type> >& tFld
 ) const
 {
-    return interpolateToTarget(tFld());
+    return interpolateToSource(tFld, sumOp<Type>());
 }
 
 
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H
index b9d73f24ee3446bae541fea490636b7d0a56df8d..8df0d6fb4abaa105efca9f31ce858ecef62a1bcc 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H
@@ -53,6 +53,7 @@ SourceFiles
 #include "treeBoundBox.H"
 #include "treeBoundBoxList.H"
 #include "globalIndex.H"
+#include "ops.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -345,11 +346,46 @@ public:
 
         // Evaluation
 
+            //- Interpolate from target to source with supplied op
+            template<class Type, class BinaryOp>
+            tmp<Field<Type> > interpolateToSource
+            (
+                const Field<Type>& fld,
+                const BinaryOp& bop
+            ) const;
+
+            //- Interpolate from target tmp field to source with supplied op
+            template<class Type, class BinaryOp>
+            tmp<Field<Type> > interpolateToSource
+            (
+                const tmp<Field<Type> >& tFld,
+                const BinaryOp& bop
+            ) const;
+
+            //- Interpolate from source to target with supplied op
+            template<class Type, class BinaryOp>
+            tmp<Field<Type> > interpolateToTarget
+            (
+                const Field<Type>& fld,
+                const BinaryOp& bop
+            ) const;
+
+            //- Interpolate from source tmp field to target with supplied op
+            template<class Type, class BinaryOp>
+            tmp<Field<Type> > interpolateToTarget
+            (
+                const tmp<Field<Type> >& tFld,
+                const BinaryOp& bop
+            ) const;
+
             //- Interpolate from target to source
             template<class Type>
-            tmp<Field<Type> > interpolateToSource(const Field<Type>& fld) const;
+            tmp<Field<Type> > interpolateToSource
+            (
+                const Field<Type>& fld
+            ) const;
 
-            //- Interpolate from target tmp field to source
+            //- Interpolate from target tmp field
             template<class Type>
             tmp<Field<Type> > interpolateToSource
             (
@@ -358,9 +394,12 @@ public:
 
             //- Interpolate from source to target
             template<class Type>
-            tmp<Field<Type> > interpolateToTarget(const Field<Type>& fld) const;
+            tmp<Field<Type> > interpolateToTarget
+            (
+                const Field<Type>& fld
+            ) const;
 
-            //- Interpolate from source tmp field to target
+            //- Interpolate from source tmp field
             template<class Type>
             tmp<Field<Type> > interpolateToTarget
             (
diff --git a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.H b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.H
index 68c432e97aadc3be08e4cdfea6b34cabe048b8ff..b2f0f4eb92e1764521eacfb57897a184411d9bdd 100644
--- a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.H
+++ b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.H
@@ -339,6 +339,39 @@ public:
         }
 
 
+        //- Wrapper around map/interpolate data distribution with supplied op
+        template<class Type, class BinaryOp>
+        void distribute(List<Type>& lst, const BinaryOp& bop) const
+        {
+            switch (mode_)
+            {
+                case NEARESTPATCHFACEAMI:
+                {
+                    lst = AMI().interpolateToSource
+                        (
+                            Field<Type>(lst.xfer()),
+                            bop
+                        );
+                    break;
+                }
+                default:
+                {
+                    map().distribute
+                    (
+                        Pstream::defaultCommsType,
+                        map().schedule(),
+                        map().constructSize(),
+                        map().subMap(),
+                        map().constructMap(),
+                        lst,
+                        bop,
+                        pTraits<Type>::zero
+                    );
+                }
+            }
+        }
+
+
         //- Wrapper around map/interpolate data distribution
         template<class Type>
         void reverseDistribute(List<Type>& lst) const
@@ -359,6 +392,40 @@ public:
         }
 
 
+        //- Wrapper around map/interpolate data distribution with supplied op
+        template<class Type, class BinaryOp>
+        void reverseDistribute(List<Type>& lst, const BinaryOp& bop) const
+        {
+            switch (mode_)
+            {
+                case NEARESTPATCHFACEAMI:
+                {
+                    lst = AMI().interpolateToTarget
+                        (
+                            Field<Type>(lst.xfer()),
+                            bop
+                        );
+                    break;
+                }
+                default:
+                {
+                    label cSize = patch_.size();
+                    map().distribute
+                    (
+                        Pstream::defaultCommsType,
+                        map().schedule(),
+                        cSize,
+                        map().constructMap(),
+                        map().subMap(),
+                        lst,
+                        bop,
+                        pTraits<Type>::zero
+                    );
+                }
+            }
+        }
+
+
         //- Return reference to the parallel distribution map
         const mapDistribute& map() const
         {
diff --git a/src/postProcessing/functionObjects/field/Make/files b/src/postProcessing/functionObjects/field/Make/files
index c1497c5e5484b0fa8ac62e29f7afdbdd0fbe4e05..9d465d2663337a86c4472089e6cd2ad239373e38 100644
--- a/src/postProcessing/functionObjects/field/Make/files
+++ b/src/postProcessing/functionObjects/field/Make/files
@@ -3,6 +3,9 @@ fieldAverage/fieldAverageItem/fieldAverageItem.C
 fieldAverage/fieldAverageItem/fieldAverageItemIO.C
 fieldAverage/fieldAverageFunctionObject/fieldAverageFunctionObject.C
 
+fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.C
+fieldCoordinateSystemTransform/fieldCoordinateSystemTransformFunctionObject.C
+
 fieldMinMax/fieldMinMax.C
 fieldMinMax/fieldMinMaxFunctionObject.C
 
diff --git a/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/IOfieldCoordinateSystemTransform.H b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/IOfieldCoordinateSystemTransform.H
new file mode 100644
index 0000000000000000000000000000000000000000..36216f399bf18258482528045045a7a11f340afb
--- /dev/null
+++ b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/IOfieldCoordinateSystemTransform.H
@@ -0,0 +1,50 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 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/>.
+
+Typedef
+    Foam::IOfieldCoordinateSystemTransform
+
+Description
+    Instance of the generic IOOutputFilter for fieldCoordinateSystemTransform.
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef IOfieldCoordinateSystemTransform_H
+#define IOfieldCoordinateSystemTransform_H
+
+#include "fieldCoordinateSystemTransform.H"
+#include "IOOutputFilter.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    typedef IOOutputFilter<fieldCoordinateSystemTransform>
+        IOfieldCoordinateSystemTransform;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.C b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.C
new file mode 100644
index 0000000000000000000000000000000000000000..afb592bc78dab27c912d39f5fdab4a760b072e87
--- /dev/null
+++ b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.C
@@ -0,0 +1,118 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 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 "fieldCoordinateSystemTransform.H"
+#include "dictionary.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+defineTypeNameAndDebug(Foam::fieldCoordinateSystemTransform, 0);
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::fieldCoordinateSystemTransform::fieldCoordinateSystemTransform
+(
+    const word& name,
+    const objectRegistry& obr,
+    const dictionary& dict,
+    const bool loadFromFiles
+)
+:
+    name_(name),
+    obr_(obr),
+    active_(true),
+    fieldSet_(),
+    coordSys_(dict, obr)
+{
+    // Check if the available mesh is an fvMesh otherise deactivate
+    if (!isA<fvMesh>(obr_))
+    {
+        active_ = false;
+        WarningIn
+        (
+            "fieldCoordinateSystemTransform::fieldCoordinateSystemTransform"
+            "("
+                "const word&, "
+                "const objectRegistry&, "
+                "const dictionary&, "
+                "const bool"
+            ")"
+        )   << "No fvMesh available, deactivating."
+            << endl;
+    }
+
+    read(dict);
+
+    Info<< type() << ":" << nl
+        << "   Applying transformation from global Cartesian to local "
+        << coordSys_ << nl << endl;
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::fieldCoordinateSystemTransform::~fieldCoordinateSystemTransform()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::fieldCoordinateSystemTransform::read(const dictionary& dict)
+{
+    if (active_)
+    {
+        dict.lookup("fields") >> fieldSet_;
+    }
+}
+
+
+void Foam::fieldCoordinateSystemTransform::execute()
+{
+    // Do nothing
+}
+
+
+void Foam::fieldCoordinateSystemTransform::end()
+{
+    // Do nothing
+}
+
+
+void Foam::fieldCoordinateSystemTransform::write()
+{
+    forAll(fieldSet_, fieldI)
+    {
+        // If necessary load field
+        transform<scalar>(fieldSet_[fieldI]);
+        transform<vector>(fieldSet_[fieldI]);
+        transform<sphericalTensor>(fieldSet_[fieldI]);
+        transform<symmTensor>(fieldSet_[fieldI]);
+        transform<tensor>(fieldSet_[fieldI]);
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.H b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.H
new file mode 100644
index 0000000000000000000000000000000000000000..138d2d09d5fbe65cc6b424de9aa5337b441ff6df
--- /dev/null
+++ b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.H
@@ -0,0 +1,163 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 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::fieldCoordinateSystemTransform
+
+Description
+    Transforms fields from global cartesian co-ordinates to local co-ordinate
+    system
+
+SourceFiles
+    fieldCoordinateSystemTransform.C
+    IOfieldCoordinateSystemTransform.H
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef fieldCoordinateSystemTransform_H
+#define fieldCoordinateSystemTransform_H
+
+#include "OFstream.H"
+#include "pointFieldFwd.H"
+#include "volFields.H"
+#include "surfaceFields.H"
+#include "coordinateSystem.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declaration of classes
+class objectRegistry;
+class dictionary;
+class mapPolyMesh;
+
+/*---------------------------------------------------------------------------*\
+               Class fieldCoordinateSystemTransform Declaration
+\*---------------------------------------------------------------------------*/
+
+class fieldCoordinateSystemTransform
+{
+protected:
+
+    // Protected data
+
+        //- Name
+        word name_;
+
+        const objectRegistry& obr_;
+
+        //- on/off switch
+        bool active_;
+
+        //- Fields to transform
+        wordList fieldSet_;
+
+        //- Co-ordinate system to transform to
+        coordinateSystem coordSys_;
+
+
+    // Protected Member Functions
+
+        //- Disallow default bitwise copy construct
+        fieldCoordinateSystemTransform(const fieldCoordinateSystemTransform&);
+
+        //- Disallow default bitwise assignment
+        void operator=(const fieldCoordinateSystemTransform&);
+
+        template<class Type>
+        void transform(const word& fieldName) const;
+
+        template<class Type>
+        void transformField(const Type& field) const;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("fieldCoordinateSystemTransform");
+
+
+    // Constructors
+
+        //- Construct for given objectRegistry and dictionary.
+        //  Allow the possibility to load fields from files
+        fieldCoordinateSystemTransform
+        (
+            const word& name,
+            const objectRegistry&,
+            const dictionary&,
+            const bool loadFromFiles = false
+        );
+
+
+    //- Destructor
+    virtual ~fieldCoordinateSystemTransform();
+
+
+    // Member Functions
+
+        //- Return name of the fieldCoordinateSystemTransform object
+        virtual const word& name() const
+        {
+            return name_;
+        }
+
+        //- Read the input data
+        virtual void read(const dictionary&);
+
+        //- Execute, currently does nothing
+        virtual void execute();
+
+        //- Execute at the final time-loop, currently does nothing
+        virtual void end();
+
+        //- Write
+        virtual void write();
+
+        //- Update for changes of mesh
+        virtual void updateMesh(const mapPolyMesh&)
+        {}
+
+        //- Update for changes of mesh
+        virtual void movePoints(const pointField&)
+        {}
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+#   include "fieldCoordinateSystemTransformTemplates.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransformFunctionObject.C b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransformFunctionObject.C
new file mode 100644
index 0000000000000000000000000000000000000000..be3f5624b474da841e9ddb374c0aed611ecf4a16
--- /dev/null
+++ b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransformFunctionObject.C
@@ -0,0 +1,45 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 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 "fieldCoordinateSystemTransformFunctionObject.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineNamedTemplateTypeNameAndDebug
+    (
+        fieldCoordinateSystemTransformFunctionObject, 0
+    );
+
+    addToRunTimeSelectionTable
+    (
+        functionObject,
+        fieldCoordinateSystemTransformFunctionObject,
+        dictionary
+    );
+}
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransformFunctionObject.H b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransformFunctionObject.H
new file mode 100644
index 0000000000000000000000000000000000000000..20cf0fccbf9b73b590cfe41b5d61af920162c6ab
--- /dev/null
+++ b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransformFunctionObject.H
@@ -0,0 +1,54 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 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/>.
+
+Typedef
+    Foam::fieldCoordinateSystemTransformFunctionObject
+
+Description
+    FunctionObject wrapper around fieldCoordinateSystemTransform to allow
+    them to be created via the functions entry within controlDict.
+
+SourceFiles
+    fieldCoordinateSystemTransformFunctionObject.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef fieldCoordinateSystemTransformFunctionObject_H
+#define fieldCoordinateSystemTransformFunctionObject_H
+
+#include "fieldCoordinateSystemTransform.H"
+#include "OutputFilterFunctionObject.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    typedef OutputFilterFunctionObject<fieldCoordinateSystemTransform>
+        fieldCoordinateSystemTransformFunctionObject;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransformTemplates.C b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransformTemplates.C
new file mode 100644
index 0000000000000000000000000000000000000000..c1ecc72707bce985a0705929006be29edaf1a993
--- /dev/null
+++ b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransformTemplates.C
@@ -0,0 +1,158 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 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 "fieldCoordinateSystemTransform.H"
+#include "volFields.H"
+#include "surfaceFields.H"
+#include "Time.H"
+#include "transformGeometricField.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template<class Type>
+void Foam::fieldCoordinateSystemTransform::transformField
+(
+    const Type& field
+) const
+{
+    const word& fieldName = field.name() + "Transformed";
+
+    dimensionedTensor R("R", field.dimensions(), coordSys_.R());
+
+    if (obr_.foundObject<Type>(fieldName))
+    {
+        Type& transField =
+            const_cast<Type&>(obr_.lookupObject<Type>(fieldName));
+
+        transField == field;
+
+        forAll(field, i)
+        {
+            Foam::transform(transField, R, transField);
+        }
+
+        transField.write();
+    }
+    else
+    {
+        Type& transField = obr_.store
+        (
+            new Type
+            (
+                IOobject
+                (
+                    fieldName,
+                    obr_.time().timeName(),
+                    obr_,
+                    IOobject::READ_IF_PRESENT,
+                    IOobject::NO_WRITE
+                ),
+                field
+            )
+        );
+
+        forAll(field, i)
+        {
+            Foam::transform(transField, R, transField);
+        }
+
+        transField.write();
+    }
+}
+
+
+template<class Type>
+void Foam::fieldCoordinateSystemTransform::transform
+(
+    const word& fieldName
+) const
+{
+    typedef GeometricField<Type, fvPatchField, volMesh> vfType;
+    typedef GeometricField<Type, fvsPatchField, surfaceMesh> sfType;
+
+    if (obr_.foundObject<vfType>(fieldName))
+    {
+        if (debug)
+        {
+            Info<< type() << ": Field " << fieldName << " already in database"
+                << endl;
+        }
+
+        transformField<vfType>(obr_.lookupObject<vfType>(fieldName));
+    }
+    else if (obr_.foundObject<sfType>(fieldName))
+    {
+        if (debug)
+        {
+            Info<< type() << ": Field " << fieldName << " already in database"
+                << endl;
+        }
+
+        transformField<sfType>(obr_.lookupObject<sfType>(fieldName));
+    }
+    else
+    {
+        IOobject fieldHeader
+        (
+            fieldName,
+            obr_.time().timeName(),
+            obr_,
+            IOobject::MUST_READ,
+            IOobject::NO_WRITE
+        );
+
+        if
+        (
+            fieldHeader.headerOk()
+         && fieldHeader.headerClassName() == vfType::typeName
+        )
+        {
+            if (debug)
+            {
+                Info<< type() << ": Field " << fieldName << " read from file"
+                    << endl;
+            }
+
+            transformField<vfType>(obr_.lookupObject<vfType>(fieldName));
+        }
+        else if
+        (
+            fieldHeader.headerOk()
+         && fieldHeader.headerClassName() == sfType::typeName
+        )
+        {
+            if (debug)
+            {
+                Info<< type() << ": Field " << fieldName << " read from file"
+                    << endl;
+            }
+
+            transformField<sfType>(obr_.lookupObject<sfType>(fieldName));
+        }
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/postProcessingDict b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/postProcessingDict
new file mode 100644
index 0000000000000000000000000000000000000000..e0d17f6271ab7d9e767ffe454713e2c917eaae7e
--- /dev/null
+++ b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/postProcessingDict
@@ -0,0 +1,50 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      postProcessingDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+functions
+{
+    fieldCoordinateSystemTransform1
+    {
+        // Type of functionObject
+        type            fieldCoordinateSystemTransform;
+
+        // Where to load it from (if not already in solver)
+        functionObjectLibs ("libfieldCoordinateSystemTransform.so");
+
+        // Function object enabled flag
+        enabled         true;
+
+        // When to output the average fields
+        outputControl   outputTime;
+
+        // Fields to be transformed - runTime modifiable
+        fields
+        (
+            U
+            UMean
+            UPrime2Mean
+        );
+
+        coordinateSystem
+        {
+            origin  (0.001  0       0);
+            e1      (1      0.15    0);
+            e3      (0      0      -1);
+        }
+    }
+}
+
+// ************************************************************************* //
diff --git a/src/regionModels/regionModel/regionModel/regionModel.H b/src/regionModels/regionModel/regionModel/regionModel.H
index 2af98421d108216d76b5606f0ff7d3bf4abc28cc..49f708bcd81e38562234da286387e11e3e5f0dfe 100644
--- a/src/regionModels/regionModel/regionModel/regionModel.H
+++ b/src/regionModels/regionModel/regionModel/regionModel.H
@@ -231,6 +231,24 @@ public:
                 List<Type>& primaryFieldField
             ) const;
 
+            //- Convert a local region field to the primary region with op
+            template<class Type, class BinaryOp>
+            void toPrimary
+            (
+                const label regionPatchI,
+                List<Type>& regionField,
+                const BinaryOp& bop
+            ) const;
+
+            //- Convert a primary region field to the local region with op
+            template<class Type, class BinaryOp>
+            void toRegion
+            (
+                const label regionPatchI,
+                List<Type>& primaryFieldField,
+                const BinaryOp& bop
+            ) const;
+
 
         // Evolution
 
diff --git a/src/regionModels/regionModel/regionModel/regionModelTemplates.C b/src/regionModels/regionModel/regionModel/regionModelTemplates.C
index 977da7dd8167df5a3b5acf703cc09f434602c5b6..ab013ad8e08f09cff6df2b8142805c7605813b5f 100644
--- a/src/regionModels/regionModel/regionModel/regionModelTemplates.C
+++ b/src/regionModels/regionModel/regionModel/regionModelTemplates.C
@@ -77,4 +77,69 @@ void Foam::regionModels::regionModel::toRegion
 }
 
 
+template<class Type, class BinaryOp>
+void Foam::regionModels::regionModel::toPrimary
+(
+    const label regionPatchI,
+    List<Type>& regionField,
+    const BinaryOp& bop
+) const
+{
+    forAll(intCoupledPatchIDs_, i)
+    {
+        if (intCoupledPatchIDs_[i] == regionPatchI)
+        {
+            const mappedPatchBase& mpb =
+                refCast<const mappedPatchBase>
+                (
+                    regionMesh().boundaryMesh()[regionPatchI]
+                );
+            mpb.reverseDistribute(regionField, bop);
+            return;
+        }
+    }
+
+    FatalErrorIn
+    (
+        "const void toPrimary"
+        "("
+            "const label, "
+            "List<Type>&, "
+            "const BinaryOp&"
+        ") const"
+    )   << "Region patch ID " << regionPatchI << " not found in region mesh"
+        << abort(FatalError);
+}
+
+
+template<class Type, class BinaryOp>
+void Foam::regionModels::regionModel::toRegion
+(
+    const label regionPatchI,
+    List<Type>& primaryField,
+    const BinaryOp& bop
+) const
+{
+    forAll(intCoupledPatchIDs_, i)
+    {
+        if (intCoupledPatchIDs_[i] == regionPatchI)
+        {
+            const mappedPatchBase& mpb =
+                refCast<const mappedPatchBase>
+                (
+                    regionMesh().boundaryMesh()[regionPatchI]
+                );
+            mpb.distribute(primaryField, bop);
+            return;
+        }
+    }
+
+    FatalErrorIn
+    (
+        "const void toRegion(const label, List<Type>&, const BinaryOp&) const"
+    )   << "Region patch ID " << regionPatchI << " not found in region mesh"
+        << abort(FatalError);
+}
+
+
 // ************************************************************************* //
diff --git a/src/turbulenceModels/compressible/turbulenceModel/derivedFvPatchFields/externalWallHeatFluxTemperature/externalWallHeatFluxTemperatureFvPatchScalarField.C b/src/turbulenceModels/compressible/turbulenceModel/derivedFvPatchFields/externalWallHeatFluxTemperature/externalWallHeatFluxTemperatureFvPatchScalarField.C
index 4fede11db6d5d5ea981b29856360fda57d7f15be..2a396388c816392b2a30f7f06b01bd9787bcf0b5 100644
--- a/src/turbulenceModels/compressible/turbulenceModel/derivedFvPatchFields/externalWallHeatFluxTemperature/externalWallHeatFluxTemperatureFvPatchScalarField.C
+++ b/src/turbulenceModels/compressible/turbulenceModel/derivedFvPatchFields/externalWallHeatFluxTemperature/externalWallHeatFluxTemperatureFvPatchScalarField.C
@@ -54,10 +54,6 @@ externalWallHeatFluxTemperatureFvPatchScalarField::operationModeNames;
 
 } // End namespace Foam
 
-
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
-
-
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 Foam::externalWallHeatFluxTemperatureFvPatchScalarField::
@@ -118,7 +114,7 @@ externalWallHeatFluxTemperatureFvPatchScalarField
         oldMode_ = fixedHeatFlux;
         q_ = scalarField("q", dict, p.size());
     }
-    else if(dict.found("h") && dict.found("Ta") && !dict.found("q"))
+    else if (dict.found("h") && dict.found("Ta") && !dict.found("q"))
     {
         oldMode_ = fixedHeatTransferCoeff;
         h_ = scalarField("h", dict, p.size());
@@ -209,7 +205,7 @@ void Foam::externalWallHeatFluxTemperatureFvPatchScalarField::updateCoeffs()
     {
         q = q_;
     }
-    else if(oldMode_ == fixedHeatTransferCoeff)
+    else if (oldMode_ == fixedHeatTransferCoeff)
     {
         q = (Ta_ - *this)*h_;
     }