diff --git a/src/functionObjects/field/Curle/Curle.C b/src/functionObjects/field/Curle/Curle.C new file mode 100644 index 0000000000..200568ef75 --- /dev/null +++ b/src/functionObjects/field/Curle/Curle.C @@ -0,0 +1,186 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\/ 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 . + +\*---------------------------------------------------------------------------*/ + +#include "Curle.H" +#include "fvcDdt.H" +#include "mathematicalConstants.H" +#include "addToRunTimeSelectionTable.H" + +using namespace Foam::constant; + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace functionObjects +{ + defineTypeNameAndDebug(Curle, 0); + + addToRunTimeSelectionTable + ( + functionObject, + Curle, + dictionary + ); +} +} + + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +bool Foam::functionObjects::Curle::calc() +{ + if (foundObject(fieldName_)) + { + // Evaluate pressure force time derivative + + const volScalarField& p = lookupObject(fieldName_); + const volScalarField dpdt(scopedName("dpdt"), fvc::ddt(p)); + const volScalarField::Boundary& dpdtBf = dpdt.boundaryField(); + const surfaceVectorField::Boundary& SfBf = mesh_.Sf().boundaryField(); + + dimensionedVector dfdt + ( + "0", + p.dimensions()*dimArea/dimTime, + vector::zero + ); + + for (auto patchi : patchSet_) + { + dfdt.value() += sum(dpdtBf[patchi]*SfBf[patchi]); + } + + reduce(dfdt.value(), sumOp()); + + + // Construct and store Curle acoustic pressure + + const volVectorField& C = mesh_.C(); + + tmp tpDash + ( + new volScalarField + ( + IOobject + ( + resultName_, + mesh_.time().timeName(), + mesh_, + IOobject::NO_READ, + IOobject::NO_WRITE + ), + mesh_, + dimensionedScalar("0", p.dimensions(), 0) + ) + ); + + volScalarField& pDash = tpDash.ref(); + const volVectorField d(scopedName("d"), C - x0_); + pDash = 4*mathematical::pi/c0_*(d/magSqr(d) & dfdt); + + return store(resultName_, tpDash); + } + else + { + return false; + } +} + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::functionObjects::Curle::Curle +( + const word& name, + const Time& runTime, + const dictionary& dict +) +: + fieldExpression(name, runTime, dict, "p"), + patchSet_(), + x0_("x0", dimLength, vector::zero), + c0_("c0", dimVelocity, 0) +{ + read(dict); + + setResultName(typeName, fieldName_); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::functionObjects::Curle::~Curle() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::functionObjects::Curle::read(const dictionary& dict) +{ + if (fieldExpression::read(dict)) + { + patchSet_ = + mesh_.boundaryMesh().patchSet(wordReList(dict.lookup("patches"))); + + if (patchSet_.empty()) + { + WarningInFunction + << "No patches defined" + << endl; + + return false; + } + + // Read the reference speed of sound + dict.lookup("c0") >> c0_; + + + // Set the location of the effective point source to the area-average + // of the patch face centres + const volVectorField::Boundary& Cbf = mesh_.C().boundaryField(); + const surfaceScalarField::Boundary& magSfBf = + mesh_.magSf().boundaryField(); + + x0_.value() = vector::zero; + scalar sumMagSf = 0; + for (auto patchi : patchSet_) + { + x0_.value() += sum(Cbf[patchi]*magSfBf[patchi]); + sumMagSf += sum(magSfBf[patchi]); + } + + reduce(x0_.value(), sumOp()); + reduce(sumMagSf, sumOp()); + + x0_.value() /= sumMagSf + ROOTVSMALL; + + return true; + } + + return false; +} + + +// ************************************************************************* // diff --git a/src/functionObjects/field/Curle/Curle.H b/src/functionObjects/field/Curle/Curle.H new file mode 100644 index 0000000000..050970a05b --- /dev/null +++ b/src/functionObjects/field/Curle/Curle.H @@ -0,0 +1,173 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\/ 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 . + +Class + Foam::functionObjects::Curle + +Group + grpFieldFunctionObjects + +Description + Calculates the acoustic pressure based on Curle's analogy. + + Curle's analogy is implemented as: + + \f[ + p' = 4 \frac{\pi}{c_0}\frac{\vec d}{|\vec d|^2}\frac{d(F)}{d(t)} + \f] + + + where + \vartable + p' | Curle's acoustic pressure [Pa] or [Pa (m3/rho)] + c_0 | Reference speed of sound [m/s] + \vec d | Distance vector to observer locations [m] + F | Force [N] or [N (m3/rho)] + \endvartable + +Note + Only the normal-pressure force is included in the force calculation + + +Usage + Example of function object specification: + \verbatim + Curle1 + { + type Curle; + libs ("libfieldFunctionObjects.so"); + ... + patches (surface1 surface2); + c0 330; + } + \endverbatim + + Where the entries comprise: + \table + Property | Description | Required | Default value + type | Type name: Curle | yes | + field | Pressure field name | no | p + result | Acoustic pressure field name | no | Curle + patches | Sound generation patch names | yes | + c0 | Reference speed of sound | yes | + \endtable + + +See also + - Foam::functionObjects::fieldExpression + - Foam::functionObjects::fvMeshFunctionObject + +SourceFiles + Curle.C + +\*---------------------------------------------------------------------------*/ + +#ifndef functionObjects_Curle_H +#define functionObjects_Curle_H + +#include "fieldExpression.H" +#include "dimensionedScalar.H" +#include "dimensionedVector.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace functionObjects +{ + +/*---------------------------------------------------------------------------*\ + Class Curle Declaration +\*---------------------------------------------------------------------------*/ + +class Curle +: + public fieldExpression +{ + // Private data + + // Read from dictionary + + //- Patches to integrate forces over + labelHashSet patchSet_; + + //- Area-averaged centre of patch faces + dimensionedVector x0_; + + //- Reference speed of souund + dimensionedScalar c0_; + + + // Private Member Functions + + //- Disallow default bitwise copy construct + Curle(const Curle&) = delete; + + //- Disallow default bitwise assignment + void operator=(const Curle&) = delete; + + +protected: + + //- Calculate the acoustic pressure field and return true if successful + virtual bool calc(); + + +public: + + //- Runtime type information + TypeName("Curle"); + + + // Constructors + + //- Construct from Time and dictionary + Curle + ( + const word& name, + const Time& runTime, + const dictionary& dict + ); + + + //- Destructor + virtual ~Curle(); + + + // Member Functions + + //- Read the Curle data + virtual bool read(const dictionary&); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace functionObjects +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/functionObjects/field/Make/files b/src/functionObjects/field/Make/files index 27a5790b3b..b44dc3819f 100644 --- a/src/functionObjects/field/Make/files +++ b/src/functionObjects/field/Make/files @@ -52,6 +52,7 @@ PecletNo/PecletNo.C blendingFactor/blendingFactor.C pressure/pressure.C MachNo/MachNo.C +Curle/Curle.C fieldsExpression/fieldsExpression.C add/add.C