From 5a80198bef39013b51b600c4a0c836d04230992f Mon Sep 17 00:00:00 2001
From: andy <andy>
Date: Wed, 23 May 2012 15:11:55 +0100
Subject: [PATCH] ENH: Updates to rotor momentum source

---
 .../rotorDiskSource/bladeModel/bladeModel.C   |  49 ++++----
 .../profileModel/lookup/lookupProfile.C       |  37 +++---
 .../rotorDiskSource/rotorDiskSource.C         | 116 ++++++++----------
 .../rotorDiskSource/rotorDiskSource.H         |   3 +
 .../trimModel/fixed/fixedTrim.C               |   5 -
 .../trimModel/targetForce/targetForceTrim.C   |   5 -
 6 files changed, 98 insertions(+), 117 deletions(-)

diff --git a/src/fieldSources/basicSource/rotorDiskSource/bladeModel/bladeModel.C b/src/fieldSources/basicSource/rotorDiskSource/bladeModel/bladeModel.C
index a1f76d3e993..af12f6b0ce2 100644
--- a/src/fieldSources/basicSource/rotorDiskSource/bladeModel/bladeModel.C
+++ b/src/fieldSources/basicSource/rotorDiskSource/bladeModel/bladeModel.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -47,33 +47,34 @@ void Foam::bladeModel::interpolateWeights
     scalar& ddx
 ) const
 {
-    scalar x = -GREAT;
-    label nElem = values.size();
-
     i2 = 0;
-    while ((x < xIn) && (i2 < nElem))
-    {
-        x = values[i2];
-        i2++;
-    }
+    label nElem = values.size();
 
-    if (i2 == 0)
+    if (nElem == 1)
     {
         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]);
+        while ((values[i2] < xIn) && (i2 < nElem))
+        {
+            i2++;
+        }
+
+        if (i2 == nElem)
+        {
+            i2 = nElem - 1;
+            i1 = i2;
+            ddx = 0.0;
+            return;
+        }
+        else
+        {
+            i1 = i2 - 1;
+            ddx = (xIn - values[i1])/(values[i2] - values[i1]);
+        }
     }
 }
 
@@ -120,14 +121,8 @@ Foam::bladeModel::bladeModel(const dictionary& dict)
     }
     else
     {
-        FatalErrorIn
-        (
-            "Foam::bladeModel::bladeModel"
-            "("
-                "const dictionary&, "
-                "const word&"
-            ")"
-        )   << "No blade data specified" << exit(FatalError);
+        FatalErrorIn("Foam::bladeModel::bladeModel(const dictionary&)")
+            << "No blade data specified" << exit(FatalError);
     }
 }
 
diff --git a/src/fieldSources/basicSource/rotorDiskSource/profileModel/lookup/lookupProfile.C b/src/fieldSources/basicSource/rotorDiskSource/profileModel/lookup/lookupProfile.C
index 1dda6b403b3..93e54bc8efe 100644
--- a/src/fieldSources/basicSource/rotorDiskSource/profileModel/lookup/lookupProfile.C
+++ b/src/fieldSources/basicSource/rotorDiskSource/profileModel/lookup/lookupProfile.C
@@ -49,33 +49,34 @@ void Foam::lookupProfile::interpolateWeights
     scalar& ddx
 ) const
 {
-    scalar x = -GREAT;
-    label nElem = values.size();
-
     i2 = 0;
-    while ((x < xIn) && (i2 < nElem))
-    {
-        x = values[i2];
-        i2++;
-    }
+    label nElem = values.size();
 
-    if (i2 == 0)
+    if (nElem == 1)
     {
         i1 = i2;
         ddx = 0.0;
         return;
     }
-    else if (i2 == nElem)
-    {
-        i2 = nElem - 1;
-        i1 = i2;
-        ddx = 0.0;
-        return;
-    }
     else
     {
-        i1 = i2 - 1;
-        ddx = (xIn - values[i1])/(values[i2] - values[i1]);
+        while ((values[i2] < xIn) && (i2 < nElem))
+        {
+            i2++;
+        }
+
+        if (i2 == nElem)
+        {
+            i2 = nElem - 1;
+            i1 = i2;
+            ddx = 0.0;
+            return;
+        }
+        else
+        {
+            i1 = i2 - 1;
+            ddx = (xIn - values[i1])/(values[i2] - values[i1]);
+        }
     }
 }
 
diff --git a/src/fieldSources/basicSource/rotorDiskSource/rotorDiskSource.C b/src/fieldSources/basicSource/rotorDiskSource/rotorDiskSource.C
index 20161147df0..6014b623fb9 100644
--- a/src/fieldSources/basicSource/rotorDiskSource/rotorDiskSource.C
+++ b/src/fieldSources/basicSource/rotorDiskSource/rotorDiskSource.C
@@ -67,6 +67,7 @@ namespace Foam
 
 void Foam::rotorDiskSource::checkData()
 {
+    // set inflow type
     switch (selectionMode())
     {
         case smCellSet:
@@ -129,11 +130,10 @@ void Foam::rotorDiskSource::setFaceArea(vector& axis, const bool correct)
 
     const label nInternalFaces = mesh_.nInternalFaces();
     const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
-    const vectorField& Sf = mesh_.Sf().internalField();
-    const scalarField& magSf = mesh_.magSf().internalField();
+    const vectorField& Sf = mesh_.Sf();
+    const scalarField& magSf = mesh_.magSf();
 
     vector n = vector::zero;
-    label nFace = 0;
 
     // calculate cell addressing for selected cells
     labelList cellAddr(mesh_.nCells(), -1);
@@ -158,7 +158,6 @@ void Foam::rotorDiskSource::setFaceArea(vector& axis, const bool correct)
     // correct for parallel running
     syncTools::swapBoundaryFaceList(mesh_, nbrFaceCellAddr);
 
-
     // add internal field contributions
     for (label faceI = 0; faceI < nInternalFaces; faceI++)
     {
@@ -173,7 +172,6 @@ void Foam::rotorDiskSource::setFaceArea(vector& axis, const bool correct)
             {
                 area_[own] += magSf[faceI];
                 n += Sf[faceI];
-                nFace++;
             }
         }
         else if ((own == -1) && (nbr != -1))
@@ -184,7 +182,6 @@ void Foam::rotorDiskSource::setFaceArea(vector& axis, const bool correct)
             {
                 area_[nbr] += magSf[faceI];
                 n -= Sf[faceI];
-                nFace++;
             }
         }
     }
@@ -210,7 +207,6 @@ void Foam::rotorDiskSource::setFaceArea(vector& axis, const bool correct)
                 {
                     area_[own] += magSfp[j];
                     n += Sfp[j];
-                    nFace++;
                 }
             }
         }
@@ -222,11 +218,10 @@ void Foam::rotorDiskSource::setFaceArea(vector& axis, const bool correct)
                 const label own = cellAddr[mesh_.faceOwner()[faceI]];
                 const vector nf = Sfp[j]/magSfp[j];
 
-                if ((own != -1) && ((nf & axis) > 0.8))
+                if ((own != -1) && ((nf & axis) > tol))
                 {
                     area_[own] += magSfp[j];
                     n += Sfp[j];
-                    nFace++;
                 }
             }
         }
@@ -359,32 +354,30 @@ void Foam::rotorDiskSource::constructGeometry()
 
     forAll(cells_, i)
     {
-        const label cellI = cells_[i];
+        if (area_[i] > ROOTVSMALL)
+        {
+            const label cellI = cells_[i];
 
-        // position in (planar) rotor co-ordinate system
-        x_[i] = coordSys_.localPosition(C[cellI]);
+            // position in (planar) rotor co-ordinate system
+            x_[i] = coordSys_.localPosition(C[cellI]);
 
-        // cache max radius
-        rMax_ = max(rMax_, x_[i].x());
+            // cache max radius
+            rMax_ = max(rMax_, x_[i].x());
 
-        // swept angle relative to rDir axis [radians] in range 0 -> 2*pi
-        scalar psi = x_[i].y();
-        if (psi < 0)
-        {
-            psi += mathematical::twoPi;
-        }
+            // swept angle relative to rDir axis [radians] in range 0 -> 2*pi
+            scalar psi = x_[i].y();
 
-        // blade flap angle [radians]
-        scalar beta = flap_.beta0 - flap_.beta1*cos(psi) - flap_.beta2*sin(psi);
-
-        // determine rotation tensor to convert from planar system into the
-        // rotor cone system
-        scalar cNeg = cos(-beta);
-        scalar sNeg = sin(-beta);
-        R_[i] = tensor(cNeg, 0.0, -sNeg, 0.0, 1.0, 0.0, sNeg, 0.0, cNeg);
-        scalar cPos = cos(beta);
-        scalar sPos = sin(beta);
-        invR_[i] = tensor(cPos, 0.0, -sPos, 0.0, 1.0, 0.0, sPos, 0.0, cPos);
+            // blade flap angle [radians]
+            scalar beta =
+                flap_.beta0 - flap_.beta1*cos(psi) - flap_.beta2*sin(psi);
+
+            // determine rotation tensor to convert from planar system into the
+            // rotor cone system
+            scalar c = cos(beta);
+            scalar s = sin(beta);
+            R_[i] = tensor(c, 0, -s, 0, 1, 0, s, 0, c);
+            invR_[i] = R_[i].T();
+        }
     }
 }
 
@@ -440,6 +433,7 @@ Foam::rotorDiskSource::rotorDiskSource
 :
     basicSource(name, modelType, dict, mesh),
     rhoName_("none"),
+    rhoRef_(1.0),
     omega_(0.0),
     nBlades_(0),
     inletFlow_(ifLocal),
@@ -477,13 +471,15 @@ void Foam::rotorDiskSource::calculate
     const bool output
 ) const
 {
-    tmp<volScalarField> trho;
-    if (rhoName_ != "none")
-    {
-        trho = mesh_.lookupObject<volScalarField>(rhoName_);
-    }
-
     const scalarField& V = mesh_.V();
+    const bool compressible = rhoName_ != "none";
+
+    tmp<volScalarField> trho
+    (
+        compressible
+      ? mesh_.lookupObject<volScalarField>(rhoName_)
+      : volScalarField::null()
+    );
 
 
     // logging info
@@ -503,17 +499,17 @@ void Foam::rotorDiskSource::calculate
             // velocity in local cylindrical reference frame
             vector Uc = coordSys_.localVector(U[cellI]);
 
-            // apply correction in local system due to coning
+            // transform from rotor cylindrical into local coning system
             Uc = R_[i] & Uc;
 
             // set radial component of velocity to zero
             Uc.x() = 0.0;
 
-            // remove blade linear velocity from blade normal component
-            Uc.y() -= radius*omega_;
+            // set blade normal component of velocity
+            Uc.y() = radius*omega_ - Uc.y();
 
             // determine blade data for this radius
-            // i1 = index of upper bound data point in blade list
+            // i2 = index of upper radius bound data point in blade list
             scalar twist = 0.0;
             scalar chord = 0.0;
             label i1 = -1;
@@ -529,17 +525,7 @@ void Foam::rotorDiskSource::calculate
             }
 
             // effective angle of attack
-            scalar alphaEff =
-                mathematical::pi + atan2(Uc.z(), Uc.y()) - alphaGeom;
-
-            if (alphaEff > mathematical::pi)
-            {
-                alphaEff -= mathematical::twoPi;
-            }
-            if (alphaEff < -mathematical::pi)
-            {
-                alphaEff += mathematical::twoPi;
-            }
+            scalar alphaEff = alphaGeom - atan2(-Uc.z(), Uc.y());
 
             AOAmin = min(AOAmin, alphaEff);
             AOAmax = max(AOAmax, alphaEff);
@@ -564,21 +550,21 @@ void Foam::rotorDiskSource::calculate
 
             // calculate forces perpendicular to blade
             scalar pDyn = 0.5*magSqr(Uc);
-            if (trho.valid())
+            if (compressible)
             {
                 pDyn *= trho()[cellI];
             }
 
-            scalar f = pDyn*chord*nBlades_*area_[i]/mathematical::twoPi;
-            vector localForce = vector(0.0, f*Cd, tipFactor*f*Cl);
+            scalar f = pDyn*chord*nBlades_*area_[i]/radius/mathematical::twoPi;
+            vector localForce = vector(0.0, -f*Cd, tipFactor*f*Cl);
+
+            // accumulate forces
+            dragEff += rhoRef_*localForce.y();
+            liftEff += rhoRef_*localForce.z();
 
             // convert force from local coning system into rotor cylindrical
             localForce = invR_[i] & localForce;
 
-            // accumulate forces
-            dragEff += localForce.y();
-            liftEff += localForce.z();
-
             // convert force to global cartesian co-ordinate system
             force[cellI] = coordSys_.globalVector(localForce);
 
@@ -616,6 +602,7 @@ void Foam::rotorDiskSource::addSup(fvMatrix<vector>& eqn, const label fieldI)
     }
     else
     {
+        coeffs_.lookup("rhoRef") >> rhoRef_;
         dims.reset(dimForce/dimVolume/dimDensity);
     }
 
@@ -666,6 +653,8 @@ bool Foam::rotorDiskSource::read(const dictionary& dict)
         coeffs_.lookup("fieldNames") >> fieldNames_;
         applied_.setSize(fieldNames_.size(), false);
 
+
+        // read co-ordinate system/geometry invariant properties
         scalar rpm(readScalar(coeffs_.lookup("rpm")));
         omega_ = rpm/60.0*mathematical::twoPi;
 
@@ -683,14 +672,17 @@ bool Foam::rotorDiskSource::read(const dictionary& dict)
         flap_.beta1 = degToRad(flap_.beta1);
         flap_.beta2 = degToRad(flap_.beta2);
 
-        trim_->read(coeffs_);        
-
-        checkData();
 
+        // create co-ordinate system
         createCoordinateSystem();
 
+        // read co-odinate system dependent properties
+        checkData();
+
         constructGeometry();
 
+        trim_->read(coeffs_);
+
         if (debug)
         {
             writeField("alphag", trim_->thetag()(), true);
diff --git a/src/fieldSources/basicSource/rotorDiskSource/rotorDiskSource.H b/src/fieldSources/basicSource/rotorDiskSource/rotorDiskSource.H
index 8e26425e107..a2f856988da 100644
--- a/src/fieldSources/basicSource/rotorDiskSource/rotorDiskSource.H
+++ b/src/fieldSources/basicSource/rotorDiskSource/rotorDiskSource.H
@@ -148,6 +148,9 @@ protected:
         //- Name of density field
         word rhoName_;
 
+        //- Reference density if rhoName = 'none'
+        scalar rhoRef_;
+
         //- Rotational speed [rad/s]
         //  Positive anti-clockwise when looking along -ve lift direction
         scalar omega_;
diff --git a/src/fieldSources/basicSource/rotorDiskSource/trimModel/fixed/fixedTrim.C b/src/fieldSources/basicSource/rotorDiskSource/trimModel/fixed/fixedTrim.C
index d5f4843d587..28b208c7c94 100644
--- a/src/fieldSources/basicSource/rotorDiskSource/trimModel/fixed/fixedTrim.C
+++ b/src/fieldSources/basicSource/rotorDiskSource/trimModel/fixed/fixedTrim.C
@@ -71,11 +71,6 @@ void Foam::fixedTrim::read(const dictionary& dict)
     forAll(thetag_, i)
     {
         scalar psi = x[i].y();
-        if (psi < 0)
-        {
-            psi += mathematical::twoPi;
-        }
-
         thetag_[i] = theta0 + theta1c*cos(psi) + theta1s*sin(psi);
     }
 }
diff --git a/src/fieldSources/basicSource/rotorDiskSource/trimModel/targetForce/targetForceTrim.C b/src/fieldSources/basicSource/rotorDiskSource/trimModel/targetForce/targetForceTrim.C
index 409015d885f..f22226f84c1 100644
--- a/src/fieldSources/basicSource/rotorDiskSource/trimModel/targetForce/targetForceTrim.C
+++ b/src/fieldSources/basicSource/rotorDiskSource/trimModel/targetForce/targetForceTrim.C
@@ -142,11 +142,6 @@ Foam::tmp<Foam::scalarField> Foam::targetForceTrim::thetag() const
     forAll(t, i)
     {
         scalar psi = x[i].y();
-        if (psi < 0)
-        {
-            psi += mathematical::twoPi;
-        }
-
         t[i] = theta_[0] + theta_[1]*cos(psi) + theta_[2]*sin(psi);
     }
 
-- 
GitLab