Commit 966ba1db authored by Andrew Heather's avatar Andrew Heather Committed by Andrew Heather
Browse files

Merge branch 'feature-functionObject-forceCoeffExtension' into 'develop'

ENH: functionObject: refactored co-ordinate system usage and new forceCoeffs members

See merge request OpenFOAM-plus!246
parents e716d1c0 a1f92568
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2017 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
......@@ -42,7 +42,6 @@ namespace Foam
namespace functionObjects
{
defineTypeNameAndDebug(forceCoeffs, 0);
addToRunTimeSelectionTable(functionObject, forceCoeffs, dictionary);
}
}
......@@ -61,12 +60,23 @@ void Foam::functionObjects::forceCoeffs::createFiles()
if (nBin_ > 1)
{
CmBinFilePtr_ = createFile("CmBin");
writeBinHeader("Moment coefficient bins", CmBinFilePtr_());
CdBinFilePtr_ = createFile("CdBin");
writeBinHeader("Drag coefficient bins", CdBinFilePtr_());
CsBinFilePtr_ = createFile("CsBin");
writeBinHeader("Side coefficient bins", CsBinFilePtr_());
ClBinFilePtr_ = createFile("ClBin");
writeBinHeader("Lift coefficient bins", ClBinFilePtr_());
CmRollBinFilePtr_ = createFile("CmRollBin");
writeBinHeader("Roll moment coefficient bins", CmRollBinFilePtr_());
CmPitchBinFilePtr_ = createFile("CmPitchBin");
writeBinHeader("Moment coefficient bins", CmPitchBinFilePtr_());
CmYawBinFilePtr_ = createFile("CmYawBin");
writeBinHeader("Yaw moment coefficient bins", CmYawBinFilePtr_());
}
}
}
......@@ -79,18 +89,28 @@ void Foam::functionObjects::forceCoeffs::writeIntegratedHeader
) const
{
writeHeader(os, "Force coefficients");
writeHeaderValue(os, "liftDir", liftDir_);
writeHeaderValue(os, "dragDir", dragDir_);
writeHeaderValue(os, "pitchAxis", pitchAxis_);
writeHeaderValue(os, "dragDir", coordSys_.e1());
writeHeaderValue(os, "sideDir", coordSys_.e2());
writeHeaderValue(os, "liftDir", coordSys_.e3());
writeHeaderValue(os, "rollAxis", coordSys_.e1());
writeHeaderValue(os, "pitchAxis", coordSys_.e2());
writeHeaderValue(os, "yawAxis", coordSys_.e3());
writeHeaderValue(os, "magUInf", magUInf_);
writeHeaderValue(os, "lRef", lRef_);
writeHeaderValue(os, "Aref", Aref_);
writeHeaderValue(os, "CofR", coordSys_.origin());
writeHeader(os, "");
writeCommented(os, "Time");
writeTabbed(os, "Cm");
writeTabbed(os, "Cd");
writeTabbed(os, "Cs");
writeTabbed(os, "Cl");
writeTabbed(os, "CmRoll");
writeTabbed(os, "CmPitch");
writeTabbed(os, "CmYaw");
writeTabbed(os, "Cd(f)");
writeTabbed(os, "Cd(r)");
writeTabbed(os, "Cs(f)");
writeTabbed(os, "Cs(r)");
writeTabbed(os, "Cl(f)");
writeTabbed(os, "Cl(r)");
os << endl;
......@@ -114,30 +134,30 @@ void Foam::functionObjects::forceCoeffs::writeBinHeader
forAll(binPoints, pointi)
{
binPoints[pointi] = (binMin_ + (pointi + 1)*binDx_)*binDir_;
os << tab << binPoints[pointi].x();
os << tab << binPoints[pointi].x();
}
os << nl;
os << nl;
writeCommented(os, "y co-ords :");
forAll(binPoints, pointi)
{
os << tab << binPoints[pointi].y();
os << tab << binPoints[pointi].y();
}
os << nl;
os << nl;
writeCommented(os, "z co-ords :");
forAll(binPoints, pointi)
{
os << tab << binPoints[pointi].z();
os << tab << binPoints[pointi].z();
}
os << nl;
os << nl;
writeHeader(os, "");
writeCommented(os, "Time");
for (label j = 0; j < nBin_; j++)
for (label j = 0; j < nBin_; ++j)
{
word jn(Foam::name(j) + ':');
const word jn(Foam::name(j) + ':');
writeTabbed(os, jn + "total");
writeTabbed(os, jn + "pressure");
writeTabbed(os, jn + "viscous");
......@@ -163,13 +183,13 @@ void Foam::functionObjects::forceCoeffs::writeIntegratedData
return;
}
scalar pressure = sum(coeff[0]);
scalar viscous = sum(coeff[1]);
scalar porous = sum(coeff[2]);
scalar total = pressure + viscous + porous;
const scalar pressure = sum(coeff[0]);
const scalar viscous = sum(coeff[1]);
const scalar porous = sum(coeff[2]);
const scalar total = pressure + viscous + porous;
Info<< " " << title << " : " << total << token::TAB
<< "("
<< '('
<< "pressure: " << pressure << token::TAB
<< "viscous: " << viscous;
......@@ -178,7 +198,7 @@ void Foam::functionObjects::forceCoeffs::writeIntegratedData
Info<< token::TAB << "porous: " << porous;
}
Info<< ")" << endl;
Info<< ')' << endl;
}
......@@ -190,7 +210,7 @@ void Foam::functionObjects::forceCoeffs::writeBinData
{
writeTime(os);
for (label bini = 0; bini < nBin_; bini++)
for (label bini = 0; bini < nBin_; ++bini)
{
scalar total = coeffs[0][bini] + coeffs[1][bini] + coeffs[2][bini];
......@@ -216,45 +236,35 @@ Foam::functionObjects::forceCoeffs::forceCoeffs
)
:
forces(name, runTime, dict),
liftDir_(Zero),
dragDir_(Zero),
pitchAxis_(Zero),
magUInf_(0.0),
lRef_(0.0),
Aref_(0.0),
magUInf_(Zero),
lRef_(Zero),
Aref_(Zero),
coeffFilePtr_(),
CmBinFilePtr_(),
CdBinFilePtr_(),
ClBinFilePtr_()
CsBinFilePtr_(),
ClBinFilePtr_(),
CmRollBinFilePtr_(),
CmPitchBinFilePtr_(),
CmYawBinFilePtr_()
{
read(dict);
setCoordinateSystem(dict, "liftDir", "dragDir");
Info<< endl;
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::functionObjects::forceCoeffs::~forceCoeffs()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::functionObjects::forceCoeffs::read(const dictionary& dict)
{
forces::read(dict);
// Directions for lift and drag forces, and pitch moment
dict.readEntry("liftDir", liftDir_);
dict.readEntry("dragDir", dragDir_);
dict.readEntry("pitchAxis", pitchAxis_);
// Free stream velocity magnitude
dict.readEntry("magUInf", magUInf_);
// If case is compressible we must read rhoInf (store in rhoRef_) to
// calculate the reference dynamic pressure
// - note: for incompressible, rhoRef_ is already initialised
// Note: for incompressible, rhoRef_ is already initialised
if (rhoName_ != "rhoInf")
{
dict.readEntry("rhoInf", rhoRef_);
......@@ -315,55 +325,94 @@ bool Foam::functionObjects::forceCoeffs::execute()
createFiles();
scalar pDyn = 0.5*rhoRef_*magUInf_*magUInf_;
// Storage for pressure, viscous and porous contributions to coeffs
List<Field<scalar>> momentCoeffs(3);
List<Field<scalar>> dragCoeffs(3);
List<Field<scalar>> sideCoeffs(3);
List<Field<scalar>> liftCoeffs(3);
List<Field<scalar>> rollMomentCoeffs(3);
List<Field<scalar>> pitchMomentCoeffs(3);
List<Field<scalar>> yawMomentCoeffs(3);
forAll(liftCoeffs, i)
{
momentCoeffs[i].setSize(nBin_);
dragCoeffs[i].setSize(nBin_);
sideCoeffs[i].setSize(nBin_);
liftCoeffs[i].setSize(nBin_);
rollMomentCoeffs[i].setSize(nBin_);
pitchMomentCoeffs[i].setSize(nBin_);
yawMomentCoeffs[i].setSize(nBin_);
}
// Calculate coefficients
scalar CmTot = 0;
scalar CdTot = 0;
scalar CsTot = 0;
scalar ClTot = 0;
scalar CmRollTot = 0;
scalar CmPitchTot = 0;
scalar CmYawTot = 0;
const scalar pDyn = 0.5*rhoRef_*sqr(magUInf_);
// Avoid divide by zero in 2D cases
const scalar momentScaling = 1.0/(Aref_*pDyn*lRef_ + SMALL);
const scalar forceScaling = 1.0/(Aref_*pDyn + SMALL);
forAll(liftCoeffs, i)
{
momentCoeffs[i] = (moment_[i] & pitchAxis_)/(Aref_*pDyn*lRef_);
dragCoeffs[i] = (force_[i] & dragDir_)/(Aref_*pDyn);
liftCoeffs[i] = (force_[i] & liftDir_)/(Aref_*pDyn);
const Field<vector> localForce(coordSys_.localVector(force_[i]));
const Field<vector> localMoment(coordSys_.localVector(moment_[i]));
dragCoeffs[i] = forceScaling*(localForce.component(0));
sideCoeffs[i] = forceScaling*(localForce.component(1));
liftCoeffs[i] = forceScaling*(localForce.component(2));
rollMomentCoeffs[i] = momentScaling*(localMoment.component(0));
pitchMomentCoeffs[i] = momentScaling*(localMoment.component(1));
yawMomentCoeffs[i] = momentScaling*(localMoment.component(2));
CmTot += sum(momentCoeffs[i]);
CdTot += sum(dragCoeffs[i]);
CsTot += sum(sideCoeffs[i]);
ClTot += sum(liftCoeffs[i]);
CmRollTot += sum(rollMomentCoeffs[i]);
CmPitchTot += sum(pitchMomentCoeffs[i]);
CmYawTot += sum(yawMomentCoeffs[i]);
}
scalar ClfTot = ClTot/2.0 + CmTot;
scalar ClrTot = ClTot/2.0 - CmTot;
// Single contributions to the front and rear
const scalar CdfTot = 0.5*CdTot + CmRollTot;
const scalar CdrTot = 0.5*CdTot - CmRollTot;
const scalar CsfTot = 0.5*CsTot + CmYawTot;
const scalar CsrTot = 0.5*CsTot - CmYawTot;
const scalar ClfTot = 0.5*ClTot + CmPitchTot;
const scalar ClrTot = 0.5*ClTot - CmPitchTot;
Log << type() << " " << name() << " execute:" << nl
<< " Coefficients" << nl;
writeIntegratedData("Cm", momentCoeffs);
writeIntegratedData("Cd", dragCoeffs);
writeIntegratedData("Cs", sideCoeffs);
writeIntegratedData("Cl", liftCoeffs);
writeIntegratedData("CmRoll", rollMomentCoeffs);
writeIntegratedData("CmPitch", pitchMomentCoeffs);
writeIntegratedData("CmYaw", yawMomentCoeffs);
Log << " Cd(f) : " << CdfTot << nl
<< " Cd(r) : " << CdrTot << nl;
Log << " Cs(f) : " << CsfTot << nl
<< " Cs(r) : " << CsrTot << nl;
Log << " Cl(f) : " << ClfTot << nl
<< " Cl(r) : " << ClrTot << nl
<< endl;
<< " Cl(r) : " << ClrTot << nl;
if (writeToFile())
{
writeTime(coeffFilePtr_());
coeffFilePtr_()
<< tab << CmTot << tab << CdTot
<< tab << ClTot << tab << ClfTot << tab << ClrTot << endl;
<< tab << CdTot << tab << CsTot << tab << ClTot
<< tab << CmRollTot << tab << CmPitchTot << tab << CmYawTot
<< tab << CdfTot << tab << CdrTot
<< tab << CsfTot << tab << CsrTot
<< tab << ClfTot << tab << ClrTot << endl;
if (nBin_ > 1)
{
......@@ -371,26 +420,41 @@ bool Foam::functionObjects::forceCoeffs::execute()
{
forAll(liftCoeffs, i)
{
for (label bini = 1; bini < nBin_; bini++)
for (label bini = 1; bini < nBin_; ++bini)
{
liftCoeffs[i][bini] += liftCoeffs[i][bini-1];
dragCoeffs[i][bini] += dragCoeffs[i][bini-1];
momentCoeffs[i][bini] += momentCoeffs[i][bini-1];
sideCoeffs[i][bini] += sideCoeffs[i][bini-1];
liftCoeffs[i][bini] += liftCoeffs[i][bini-1];
rollMomentCoeffs[i][bini] +=
rollMomentCoeffs[i][bini-1];
pitchMomentCoeffs[i][bini] +=
pitchMomentCoeffs[i][bini-1];
yawMomentCoeffs[i][bini] += yawMomentCoeffs[i][bini-1];
}
}
}
writeBinData(dragCoeffs, CdBinFilePtr_());
writeBinData(sideCoeffs, CsBinFilePtr_());
writeBinData(liftCoeffs, ClBinFilePtr_());
writeBinData(momentCoeffs, CmBinFilePtr_());
writeBinData(rollMomentCoeffs, CmRollBinFilePtr_());
writeBinData(pitchMomentCoeffs, CmPitchBinFilePtr_());
writeBinData(yawMomentCoeffs, CmYawBinFilePtr_());
}
}
// Write state/results information
{
setResult("Cm", CmTot);
setResult("Cd", CdTot);
setResult("Cs", CsTot);
setResult("Cl", ClTot);
setResult("CmRoll", CmRollTot);
setResult("CmPitch", CmPitchTot);
setResult("CmYaw", CmYawTot);
setResult("Cd(f)", CdfTot);
setResult("Cd(r)", CdrTot);
setResult("Cs(f)", CsfTot);
setResult("Cs(r)", CsrTot);
setResult("Cl(f)", ClfTot);
setResult("Cl(r)", ClrTot);
}
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
......@@ -30,9 +30,18 @@ Group
grpForcesFunctionObjects
Description
Extends the forces functionObject by providing lift, drag and moment
coefficients. The data can optionally be output into bins, defined in a
given direction.
Extends the \c forces functionObject by providing coefficients for:
- drag, side and lift forces (Cd, Cs, and Cl)
- roll, pitch and yaw moments (CmRoll, CmPitch, and CmYaw)
- front and rear axle force contributions (C(f) and C(r)) wherein
\verbatim
Cd(f/r) = 0.5*Cd \pm CmRoll
Cs(f/r) = 0.5*Cs \pm CmYaw
Cl(f/r) = 0.5*Cl \pm CmPitch
\endverbatim
The data can optionally be output into bins, defined in a given direction.
The binned data provides the total and consitituent components per bin:
- total coefficient
......@@ -43,9 +52,12 @@ Description
Data is written into multiple files in the
postProcessing/\<functionObjectName\> directory:
- coefficient.dat : integrated coefficients over all geometries
- CmBin.dat : moment coefficient bins
- CdBin.dat : drag coefficient bins
- CsBin.dat : side coefficient bins
- ClBin.dat : lift coefficient bins
- CmRollBin.dat : roll moment coefficient bins
- CmPitchBin.dat : pitch moment coefficient bins
- CmYawBin.dat : yaw moment coefficient bins
Usage
Example of function object specification:
......@@ -58,12 +70,14 @@ Usage
log yes;
writeFields yes;
patches (walls);
liftDir (0 1 0);
dragDir (-1 0 0);
pitchAxis (0 0 1);
// input keywords for directions of force/moment coefficients
// refer below for options, and relations
magUInf 100;
lRef 3.5;
Aref 2.2;
porosity no;
binData
{
......@@ -76,26 +90,65 @@ Usage
Where the entries comprise:
\table
Property | Description | Required | Default value
type | Type name: forceCoeffs | yes |
log | Write force data to standard output | no | no
writeFields | Write the force and moment coefficient fields | no | no
Property | Description | Required | Default
type | Type name: forceCoeffs | yes |
log | Write force data to standard output | no | no
writeFields | Write force,moment coefficient fields | no | no
patches | Patches included in the forces calculation | yes |
liftDir | Lift direction | yes |
dragDir | Drag direction | yes |
pitchAxis | Picth axis | yes |
magUInf | Free stream velocity magnitude | yes |
magUInf | Free stream velocity magnitude | yes |
lRef | Reference length scale for moment calculations | yes |
Aref | Reference area | yes |
porosity | Flag to include porosity contributions | no | no
Aref | Reference area | yes |
porosity | Include porosity contributions | no | false
\endtable
Bin data is optional, but if the dictionary is present, the entries must
be defined according o
be defined according to following:
\table
nBin | number of data bins | yes |
direction | direction along which bins are defined | yes |
cumulative | bin data accumulated with incresing distance | yes |
nBin | Number of data bins | yes |
direction | Direction along which bins are defined | yes |
cumulative | Bin data accumulated with incresing distance | yes |
\endtable
Input of force/moment coefficient directions:
- require an origin, and two orthogonal directions; the remaining orthogonal
direction is determined accordingly.
- can be added by the three options below.
\verbatim
CofR (0 0 0); // Centre of rotation
dragDir (1 0 0);
liftDir (0 0 1);
\endverbatim
\verbatim
origin (0 0 0);
e1 (1 0 0);
e3 (0 0 1); // combinations: (e1, e2) or (e2, e3) or (e3, e1)
\endverbatim
\verbatim
coordinateSystem
{
origin (0 0 0);
rotation
{
type axes;
e1 (1 0 0);
e3 (0 0 1); // combinations: (e1, e2) or (e2, e3) or (e3, e1)
}
}
\endverbatim
The default direction relations are shown below:
\table
Property | Description | Alias | Direction
dragDir | Drag direction | e1 | (1 0 0)
sideDir | Side force direction | e2 | (0 1 0)
liftDir | Lift direction | e3 | (0 0 1)
rollAxis | Roll axis | e1 | (1 0 0)
pitchAxis | Pitch axis | e2 | (0 1 0)
yawAxis | Yaw axis | e3 | (0 0 1)
\endtable
See also
......@@ -130,30 +183,18 @@ class forceCoeffs
{
// Private data
// Force coefficient geometry
//- Lift
vector liftDir_;
//- Drag
vector dragDir_;
//- Pitch
vector pitchAxis_;
// Free-stream conditions
//- Velocity magnitude
//- Free-stream velocity magnitude
scalar magUInf_;
// Reference scales
//- Length
//- Reference length [m]
scalar lRef_;
//- Area
//- Reference area [m^2]
scalar Aref_;
......@@ -162,15 +203,24 @@ class forceCoeffs
//- Integrated coefficients
autoPtr<OFstream> coeffFilePtr_;
//- Moment coefficient
autoPtr<OFstream> CmBinFilePtr_;
//- Drag coefficient
autoPtr<OFstream> CdBinFilePtr_;
//- Side coefficient
autoPtr<OFstream> CsBinFilePtr_;
//- Lift coefficient
autoPtr<OFstream> ClBinFilePtr_;
//- Roll moment coefficient
autoPtr<OFstream> CmRollBinFilePtr_;
//- Pitch moment coefficient
autoPtr<OFstream> CmPitchBinFilePtr_;
//- Yaw moment coefficient
autoPtr<OFstream> CmYawBinFilePtr_;
// Private Member Functions
......@@ -223,7 +273,7 @@ public:
//- Destructor
virtual ~forceCoeffs();
virtual ~forceCoeffs() = default;
// Member Functions
......@@ -231,7 +281,7 @@ public:
//- Read the forces data
virtual bool read(const dictionary&);
//- Execute, currently does nothing
//- Execute
virtual bool execute();
//- Write the forces
......@@ -249,3 +299,4 @@ public:
#endif
// ************************************************************************* //
......@@ -71,22 +71,6 @@ void Foam::functionObjects::forces::createFiles()
momentBinFilePtr_ = createFile("momentBin");
writeBinHeader("Moment", momentBinFilePtr_());
}
if (localSystem_)
{
localForceFilePtr_ = createFile("localForce");
writeIntegratedHeader("Force", localForceFilePtr_());
localMomentFilePtr_ = createFile("localMoment");
writeIntegratedHeader("Moment", localMomentFilePtr_());
if (nBin_ > 1)
{
localForceBinFilePtr_ = createFile("localForceBin");
writeBinHeader("Force", localForceBinFilePtr_());
localMomentBinFilePtr_ = createFile("localMomentBin");
writeBinHeader("Moment", localMomentBinFilePtr_());
}
}
}
}
......@@ -169,6 +153,49 @@ void Foam::functionObjects::forces::writeBinHeader