ENH: Updates to rotor momentum source

This commit is contained in:
andy
2012-05-23 15:11:55 +01:00
parent 114b4d9474
commit 5a80198bef
6 changed files with 100 additions and 119 deletions

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -47,33 +47,34 @@ void Foam::bladeModel::interpolateWeights
scalar& ddx scalar& ddx
) const ) const
{ {
scalar x = -GREAT; i2 = 0;
label nElem = values.size(); label nElem = values.size();
i2 = 0; if (nElem == 1)
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; i1 = i2;
ddx = 0.0; ddx = 0.0;
return; return;
} }
else else
{ {
i1 = i2 - 1; while ((values[i2] < xIn) && (i2 < nElem))
ddx = (xIn - values[i1])/(values[i2] - values[i1]); {
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 else
{ {
FatalErrorIn FatalErrorIn("Foam::bladeModel::bladeModel(const dictionary&)")
( << "No blade data specified" << exit(FatalError);
"Foam::bladeModel::bladeModel"
"("
"const dictionary&, "
"const word&"
")"
) << "No blade data specified" << exit(FatalError);
} }
} }

View File

@ -49,33 +49,34 @@ void Foam::lookupProfile::interpolateWeights
scalar& ddx scalar& ddx
) const ) const
{ {
scalar x = -GREAT; i2 = 0;
label nElem = values.size(); label nElem = values.size();
i2 = 0; if (nElem == 1)
while ((x < xIn) && (i2 < nElem))
{ {
x = values[i2];
i2++;
}
if (i2 == 0)
{
i1 = i2;
ddx = 0.0;
return;
}
else if (i2 == nElem)
{
i2 = nElem - 1;
i1 = i2; i1 = i2;
ddx = 0.0; ddx = 0.0;
return; return;
} }
else else
{ {
i1 = i2 - 1; while ((values[i2] < xIn) && (i2 < nElem))
ddx = (xIn - values[i1])/(values[i2] - values[i1]); {
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]);
}
} }
} }

View File

@ -67,6 +67,7 @@ namespace Foam
void Foam::rotorDiskSource::checkData() void Foam::rotorDiskSource::checkData()
{ {
// set inflow type
switch (selectionMode()) switch (selectionMode())
{ {
case smCellSet: case smCellSet:
@ -129,11 +130,10 @@ void Foam::rotorDiskSource::setFaceArea(vector& axis, const bool correct)
const label nInternalFaces = mesh_.nInternalFaces(); const label nInternalFaces = mesh_.nInternalFaces();
const polyBoundaryMesh& pbm = mesh_.boundaryMesh(); const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
const vectorField& Sf = mesh_.Sf().internalField(); const vectorField& Sf = mesh_.Sf();
const scalarField& magSf = mesh_.magSf().internalField(); const scalarField& magSf = mesh_.magSf();
vector n = vector::zero; vector n = vector::zero;
label nFace = 0;
// calculate cell addressing for selected cells // calculate cell addressing for selected cells
labelList cellAddr(mesh_.nCells(), -1); labelList cellAddr(mesh_.nCells(), -1);
@ -158,7 +158,6 @@ void Foam::rotorDiskSource::setFaceArea(vector& axis, const bool correct)
// correct for parallel running // correct for parallel running
syncTools::swapBoundaryFaceList(mesh_, nbrFaceCellAddr); syncTools::swapBoundaryFaceList(mesh_, nbrFaceCellAddr);
// add internal field contributions // add internal field contributions
for (label faceI = 0; faceI < nInternalFaces; faceI++) for (label faceI = 0; faceI < nInternalFaces; faceI++)
{ {
@ -173,7 +172,6 @@ void Foam::rotorDiskSource::setFaceArea(vector& axis, const bool correct)
{ {
area_[own] += magSf[faceI]; area_[own] += magSf[faceI];
n += Sf[faceI]; n += Sf[faceI];
nFace++;
} }
} }
else if ((own == -1) && (nbr != -1)) else if ((own == -1) && (nbr != -1))
@ -184,7 +182,6 @@ void Foam::rotorDiskSource::setFaceArea(vector& axis, const bool correct)
{ {
area_[nbr] += magSf[faceI]; area_[nbr] += magSf[faceI];
n -= Sf[faceI]; n -= Sf[faceI];
nFace++;
} }
} }
} }
@ -210,7 +207,6 @@ void Foam::rotorDiskSource::setFaceArea(vector& axis, const bool correct)
{ {
area_[own] += magSfp[j]; area_[own] += magSfp[j];
n += Sfp[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 label own = cellAddr[mesh_.faceOwner()[faceI]];
const vector nf = Sfp[j]/magSfp[j]; const vector nf = Sfp[j]/magSfp[j];
if ((own != -1) && ((nf & axis) > 0.8)) if ((own != -1) && ((nf & axis) > tol))
{ {
area_[own] += magSfp[j]; area_[own] += magSfp[j];
n += Sfp[j]; n += Sfp[j];
nFace++;
} }
} }
} }
@ -359,32 +354,30 @@ void Foam::rotorDiskSource::constructGeometry()
forAll(cells_, i) forAll(cells_, i)
{ {
const label cellI = cells_[i]; if (area_[i] > ROOTVSMALL)
// position in (planar) rotor co-ordinate system
x_[i] = coordSys_.localPosition(C[cellI]);
// 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; const label cellI = cells_[i];
// position in (planar) rotor co-ordinate system
x_[i] = coordSys_.localPosition(C[cellI]);
// 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();
// 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();
} }
// 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);
} }
} }
@ -440,6 +433,7 @@ Foam::rotorDiskSource::rotorDiskSource
: :
basicSource(name, modelType, dict, mesh), basicSource(name, modelType, dict, mesh),
rhoName_("none"), rhoName_("none"),
rhoRef_(1.0),
omega_(0.0), omega_(0.0),
nBlades_(0), nBlades_(0),
inletFlow_(ifLocal), inletFlow_(ifLocal),
@ -477,13 +471,15 @@ void Foam::rotorDiskSource::calculate
const bool output const bool output
) const ) const
{ {
tmp<volScalarField> trho;
if (rhoName_ != "none")
{
trho = mesh_.lookupObject<volScalarField>(rhoName_);
}
const scalarField& V = mesh_.V(); const scalarField& V = mesh_.V();
const bool compressible = rhoName_ != "none";
tmp<volScalarField> trho
(
compressible
? mesh_.lookupObject<volScalarField>(rhoName_)
: volScalarField::null()
);
// logging info // logging info
@ -503,17 +499,17 @@ void Foam::rotorDiskSource::calculate
// velocity in local cylindrical reference frame // velocity in local cylindrical reference frame
vector Uc = coordSys_.localVector(U[cellI]); 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; Uc = R_[i] & Uc;
// set radial component of velocity to zero // set radial component of velocity to zero
Uc.x() = 0.0; Uc.x() = 0.0;
// remove blade linear velocity from blade normal component // set blade normal component of velocity
Uc.y() -= radius*omega_; Uc.y() = radius*omega_ - Uc.y();
// determine blade data for this radius // 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 twist = 0.0;
scalar chord = 0.0; scalar chord = 0.0;
label i1 = -1; label i1 = -1;
@ -529,17 +525,7 @@ void Foam::rotorDiskSource::calculate
} }
// effective angle of attack // effective angle of attack
scalar alphaEff = scalar alphaEff = alphaGeom - atan2(-Uc.z(), Uc.y());
mathematical::pi + atan2(Uc.z(), Uc.y()) - alphaGeom;
if (alphaEff > mathematical::pi)
{
alphaEff -= mathematical::twoPi;
}
if (alphaEff < -mathematical::pi)
{
alphaEff += mathematical::twoPi;
}
AOAmin = min(AOAmin, alphaEff); AOAmin = min(AOAmin, alphaEff);
AOAmax = max(AOAmax, alphaEff); AOAmax = max(AOAmax, alphaEff);
@ -564,21 +550,21 @@ void Foam::rotorDiskSource::calculate
// calculate forces perpendicular to blade // calculate forces perpendicular to blade
scalar pDyn = 0.5*magSqr(Uc); scalar pDyn = 0.5*magSqr(Uc);
if (trho.valid()) if (compressible)
{ {
pDyn *= trho()[cellI]; pDyn *= trho()[cellI];
} }
scalar f = pDyn*chord*nBlades_*area_[i]/mathematical::twoPi; scalar f = pDyn*chord*nBlades_*area_[i]/radius/mathematical::twoPi;
vector localForce = vector(0.0, f*Cd, tipFactor*f*Cl); 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 // convert force from local coning system into rotor cylindrical
localForce = invR_[i] & localForce; localForce = invR_[i] & localForce;
// accumulate forces
dragEff += localForce.y();
liftEff += localForce.z();
// convert force to global cartesian co-ordinate system // convert force to global cartesian co-ordinate system
force[cellI] = coordSys_.globalVector(localForce); force[cellI] = coordSys_.globalVector(localForce);
@ -616,6 +602,7 @@ void Foam::rotorDiskSource::addSup(fvMatrix<vector>& eqn, const label fieldI)
} }
else else
{ {
coeffs_.lookup("rhoRef") >> rhoRef_;
dims.reset(dimForce/dimVolume/dimDensity); dims.reset(dimForce/dimVolume/dimDensity);
} }
@ -666,6 +653,8 @@ bool Foam::rotorDiskSource::read(const dictionary& dict)
coeffs_.lookup("fieldNames") >> fieldNames_; coeffs_.lookup("fieldNames") >> fieldNames_;
applied_.setSize(fieldNames_.size(), false); applied_.setSize(fieldNames_.size(), false);
// read co-ordinate system/geometry invariant properties
scalar rpm(readScalar(coeffs_.lookup("rpm"))); scalar rpm(readScalar(coeffs_.lookup("rpm")));
omega_ = rpm/60.0*mathematical::twoPi; omega_ = rpm/60.0*mathematical::twoPi;
@ -683,14 +672,17 @@ bool Foam::rotorDiskSource::read(const dictionary& dict)
flap_.beta1 = degToRad(flap_.beta1); flap_.beta1 = degToRad(flap_.beta1);
flap_.beta2 = degToRad(flap_.beta2); flap_.beta2 = degToRad(flap_.beta2);
trim_->read(coeffs_);
checkData();
// create co-ordinate system
createCoordinateSystem(); createCoordinateSystem();
// read co-odinate system dependent properties
checkData();
constructGeometry(); constructGeometry();
trim_->read(coeffs_);
if (debug) if (debug)
{ {
writeField("alphag", trim_->thetag()(), true); writeField("alphag", trim_->thetag()(), true);

View File

@ -148,6 +148,9 @@ protected:
//- Name of density field //- Name of density field
word rhoName_; word rhoName_;
//- Reference density if rhoName = 'none'
scalar rhoRef_;
//- Rotational speed [rad/s] //- Rotational speed [rad/s]
// Positive anti-clockwise when looking along -ve lift direction // Positive anti-clockwise when looking along -ve lift direction
scalar omega_; scalar omega_;

View File

@ -71,11 +71,6 @@ void Foam::fixedTrim::read(const dictionary& dict)
forAll(thetag_, i) forAll(thetag_, i)
{ {
scalar psi = x[i].y(); scalar psi = x[i].y();
if (psi < 0)
{
psi += mathematical::twoPi;
}
thetag_[i] = theta0 + theta1c*cos(psi) + theta1s*sin(psi); thetag_[i] = theta0 + theta1c*cos(psi) + theta1s*sin(psi);
} }
} }

View File

@ -142,11 +142,6 @@ Foam::tmp<Foam::scalarField> Foam::targetForceTrim::thetag() const
forAll(t, i) forAll(t, i)
{ {
scalar psi = x[i].y(); scalar psi = x[i].y();
if (psi < 0)
{
psi += mathematical::twoPi;
}
t[i] = theta_[0] + theta_[1]*cos(psi) + theta_[2]*sin(psi); t[i] = theta_[0] + theta_[1]*cos(psi) + theta_[2]*sin(psi);
} }