From 0581a9d8842943f5a7447619ea019882b630ccc5 Mon Sep 17 00:00:00 2001 From: kuti Date: Sun, 26 May 2019 21:38:00 +0100 Subject: [PATCH] ENH: new forceCoeffs functionObject output - additional coefficients: - Side force coefficient: direction in curl(lift,drag), - Yaw moment coefficient: rotation axis in dir(lift) - Roll moment coefficient: rotation axis in dir(drag) Order of output - forces(drag,side,lift) - moments(roll,pitch,yaw) Note - For force coeffs, front and rear axles' contributions are computed --- .../forces/forceCoeffs/forceCoeffs.C | 215 +++++++++++++----- .../forces/forceCoeffs/forceCoeffs.H | 99 +++++--- 2 files changed, 219 insertions(+), 95 deletions(-) diff --git a/src/functionObjects/forces/forceCoeffs/forceCoeffs.C b/src/functionObjects/forces/forceCoeffs/forceCoeffs.C index be744320a7..71c142e3b8 100644 --- a/src/functionObjects/forces/forceCoeffs/forceCoeffs.C +++ b/src/functionObjects/forces/forceCoeffs/forceCoeffs.C @@ -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,12 +42,37 @@ namespace Foam namespace functionObjects { defineTypeNameAndDebug(forceCoeffs, 0); - addToRunTimeSelectionTable(functionObject, forceCoeffs, dictionary); } } +// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // + +namespace Foam +{ + // Read vector and normalise if present, or set default + inline vector readVectorOrDefault + ( + const dictionary& dict, + const word& key, + const vector::components axis + ) + { + vector vec(Zero); // Zero initialise! + + if (dict.readIfPresent(key, vec)) + { + return normalised(vec); + } + + vec[axis] = 1; + return vec; + } + +} // End namespace Foam + + // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // void Foam::functionObjects::forceCoeffs::createFiles() @@ -61,12 +86,18 @@ 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 +110,28 @@ void Foam::functionObjects::forceCoeffs::writeIntegratedHeader ) const { writeHeader(os, "Force coefficients"); - writeHeaderValue(os, "liftDir", liftDir_); writeHeaderValue(os, "dragDir", dragDir_); + writeHeaderValue(os, "sideDir", sideDir_); + writeHeaderValue(os, "liftDir", liftDir_); + writeHeaderValue(os, "rollAxis", rollAxis_); writeHeaderValue(os, "pitchAxis", pitchAxis_); + writeHeaderValue(os, "yawAxis", yawAxis_); 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 +155,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 +204,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 +219,7 @@ void Foam::functionObjects::forceCoeffs::writeIntegratedData Info<< token::TAB << "porous: " << porous; } - Info<< ")" << endl; + Info<< ')' << endl; } @@ -190,7 +231,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 +257,49 @@ Foam::functionObjects::forceCoeffs::forceCoeffs ) : forces(name, runTime, dict), - liftDir_(Zero), dragDir_(Zero), + sideDir_(Zero), + liftDir_(Zero), + rollAxis_(Zero), pitchAxis_(Zero), - magUInf_(0.0), - lRef_(0.0), - Aref_(0.0), + yawAxis_(Zero), + magUInf_(Zero), + lRef_(Zero), + Aref_(Zero), coeffFilePtr_(), - CmBinFilePtr_(), CdBinFilePtr_(), - ClBinFilePtr_() + CsBinFilePtr_(), + ClBinFilePtr_(), + CmRollBinFilePtr_(), + CmPitchBinFilePtr_(), + CmYawBinFilePtr_() { read(dict); 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_); + // Standard (default) definitions + dragDir_ = readVectorOrDefault(dict, "dragDir", vector::X); + sideDir_ = readVectorOrDefault(dict, "sideDir", vector::Y); + liftDir_ = readVectorOrDefault(dict, "liftDir", vector::Z); + rollAxis_ = readVectorOrDefault(dict, "rollAxis", vector::X); + pitchAxis_ = readVectorOrDefault(dict, "pitchAxis", vector::Y); + yawAxis_ = readVectorOrDefault(dict, "yawAxis", vector::Z); + // 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 +360,90 @@ bool Foam::functionObjects::forceCoeffs::execute() createFiles(); - scalar pDyn = 0.5*rhoRef_*magUInf_*magUInf_; - // Storage for pressure, viscous and porous contributions to coeffs - List> momentCoeffs(3); List> dragCoeffs(3); + List> sideCoeffs(3); List> liftCoeffs(3); + List> rollMomentCoeffs(3); + List> pitchMomentCoeffs(3); + List> 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); + dragCoeffs[i] = forceScaling*(force_[i] & dragDir_); + sideCoeffs[i] = forceScaling*(force_[i] & sideDir_); + liftCoeffs[i] = forceScaling*(force_[i] & liftDir_); + rollMomentCoeffs[i] = momentScaling*(moment_[i] & rollAxis_); + pitchMomentCoeffs[i] = momentScaling*(moment_[i] & pitchAxis_); + yawMomentCoeffs[i] = momentScaling*(moment_[i] & yawAxis_); - 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 axles + 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 +451,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); } diff --git a/src/functionObjects/forces/forceCoeffs/forceCoeffs.H b/src/functionObjects/forces/forceCoeffs/forceCoeffs.H index d68b47f185..c82002f908 100644 --- a/src/functionObjects/forces/forceCoeffs/forceCoeffs.H +++ b/src/functionObjects/forces/forceCoeffs/forceCoeffs.H @@ -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,10 @@ 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 forces functionObject by providing coefficients for: + - drag, side and lift forces + - roll, pitch and yaw moments + 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 +44,12 @@ Description Data is written into multiple files in the postProcessing/\ 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,9 +62,12 @@ Usage log yes; writeFields yes; patches (walls); - liftDir (0 1 0); - dragDir (-1 0 0); - pitchAxis (0 0 1); + dragDir (1 0 0); + sideDir (0 1 0); + liftDir (0 0 1); + rollAxis (1 0 0); + pitchAxis (0 1 0); + yawAxis (0 0 1); magUInf 100; lRef 3.5; Aref 2.2; @@ -76,26 +83,29 @@ 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 | + dragDir | Drag direction | no | (1 0 0) + sideDir | Side force direction | no | (0 1 0) + liftDir | Lift direction | no | (0 0 1) + rollAxis | Roll axis | no | (1 0 0) + pitchAxis | Pitch axis | no | (0 1 0) + yawAxis | Yaw axis | no | (0 0 1) + 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 See also @@ -130,30 +140,39 @@ class forceCoeffs { // Private data - // Force coefficient geometry + // Force coefficient geometry in global Cartesian coordinate system - //- Lift + //- Drag force direction + vector dragDir_; + + //- Side force direction + vector sideDir_; + + //- Lift force direction vector liftDir_; - //- Drag - vector dragDir_; + //- Roll axis direction + vector rollAxis_; - //- Pitch + //- Pitch axis direction vector pitchAxis_; + //- Yaw axis direction + vector yawAxis_; + // 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 +181,24 @@ class forceCoeffs //- Integrated coefficients autoPtr coeffFilePtr_; - //- Moment coefficient - autoPtr CmBinFilePtr_; - //- Drag coefficient autoPtr CdBinFilePtr_; + //- Side coefficient + autoPtr CsBinFilePtr_; + //- Lift coefficient autoPtr ClBinFilePtr_; + //- Roll moment coefficient + autoPtr CmRollBinFilePtr_; + + //- Pitch moment coefficient + autoPtr CmPitchBinFilePtr_; + + //- Yaw moment coefficient + autoPtr CmYawBinFilePtr_; + // Private Member Functions @@ -223,7 +251,7 @@ public: //- Destructor - virtual ~forceCoeffs(); + virtual ~forceCoeffs() = default; // Member Functions @@ -231,7 +259,7 @@ public: //- Read the forces data virtual bool read(const dictionary&); - //- Execute, currently does nothing + //- Execute virtual bool execute(); //- Write the forces @@ -249,3 +277,4 @@ public: #endif // ************************************************************************* // +