Files
openfoam/src/functionObjects/field/Curle/Curle.C
2021-09-06 16:29:49 +02:00

274 lines
7.5 KiB
C

/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#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);
}
}
const Foam::Enum<Foam::functionObjects::Curle::modeType>
Foam::functionObjects::Curle::modeTypeNames_
({
{ modeType::point, "point" },
{ modeType::surface, "surface" },
});
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::functionObjects::Curle::Curle
(
const word& name,
const Time& runTime,
const dictionary& dict
)
:
fvMeshFunctionObject(name, runTime, dict),
writeFile(mesh_, name),
pName_("p"),
patchSet_(),
observerPositions_(),
c0_(0),
rawFilePtrs_(),
inputSurface_(),
surfaceWriterPtr_(nullptr)
{
read(dict);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::functionObjects::Curle::read(const dictionary& dict)
{
if (!(fvMeshFunctionObject::read(dict) && writeFile::read(dict)))
{
return false;
}
dict.readIfPresent("p", pName_);
patchSet_ = mesh_.boundaryMesh().patchSet(dict.get<wordRes>("patches"));
if (patchSet_.empty())
{
WarningInFunction
<< "No patches defined"
<< endl;
return false;
}
const modeType inputMode = modeTypeNames_.get("input", dict);
switch (inputMode)
{
case modeType::point:
{
observerPositions_ = dict.get<List<point>>("observerPositions");
break;
}
case modeType::surface:
{
const fileName fName = (dict.get<fileName>("surface")).expand();
inputSurface_ = MeshedSurface<face>(fName);
observerPositions_ = inputSurface_.Cf();
}
}
if (observerPositions_.empty())
{
WarningInFunction
<< "No observer positions defined"
<< endl;
return false;
}
const auto outputMode = modeTypeNames_.get("output", dict);
switch (outputMode)
{
case modeType::point:
{
rawFilePtrs_.setSize(observerPositions_.size());
forAll(rawFilePtrs_, filei)
{
rawFilePtrs_.set
(
filei,
createFile("observer" + Foam::name(filei))
);
if (rawFilePtrs_.set(filei))
{
OFstream& os = rawFilePtrs_[filei];
writeHeaderValue(os, "Observer", filei);
writeHeaderValue(os, "Position", observerPositions_[filei]);
writeCommented(os, "Time");
writeTabbed(os, "p(Curle)");
os << endl;
}
}
break;
}
case modeType::surface:
{
if (inputMode != modeType::surface)
{
FatalIOErrorInFunction(dict)
<< "Surface output is only available when input mode is "
<< "type '" << modeTypeNames_[modeType::surface] << "'"
<< abort(FatalIOError);
}
const word surfaceType(dict.get<word>("surfaceType"));
surfaceWriterPtr_ = surfaceWriter::New
(
surfaceType,
dict.subOrEmptyDict("formatOptions").subOrEmptyDict(surfaceType)
);
// Use outputDir/TIME/surface-name
surfaceWriterPtr_->useTimeDir(true);
}
}
// Read the reference speed of sound
dict.readEntry("c0", c0_);
if (c0_ < VSMALL)
{
FatalErrorInFunction
<< "Reference speed of sound = " << c0_
<< " cannot be negative or zero."
<< abort(FatalError);
}
return true;
}
bool Foam::functionObjects::Curle::execute()
{
if (!foundObject<volScalarField>(pName_))
{
return false;
}
const volScalarField& p = lookupObject<volScalarField>(pName_);
const volScalarField::Boundary& pBf = p.boundaryField();
const volScalarField dpdt(scopedName("dpdt"), fvc::ddt(p));
const volScalarField::Boundary& dpdtBf = dpdt.boundaryField();
const surfaceVectorField::Boundary& SfBf = mesh_.Sf().boundaryField();
const surfaceVectorField::Boundary& CfBf = mesh_.Cf().boundaryField();
scalarField pDash(observerPositions_.size(), 0);
for (auto patchi : patchSet_)
{
const scalarField& pp = pBf[patchi];
const scalarField& dpdtp = dpdtBf[patchi];
const vectorField& Sfp = SfBf[patchi];
const vectorField& Cfp = CfBf[patchi];
forAll(observerPositions_, pointi)
{
const vectorField r(observerPositions_[pointi] - Cfp);
const scalarField invMagR(1/(mag(r) + ROOTVSMALL));
pDash[pointi] +=
sum((pp*sqr(invMagR) + invMagR/c0_*dpdtp)*(Sfp & (r*invMagR)));
}
}
pDash /= 4*mathematical::pi;
Pstream::listCombineGather(pDash, plusEqOp<scalar>());
Pstream::listCombineScatter(pDash);
if (surfaceWriterPtr_)
{
if (Pstream::master())
{
// Time-aware, with time spliced into the output path
surfaceWriterPtr_->beginTime(time_);
surfaceWriterPtr_->open
(
inputSurface_.points(),
inputSurface_.surfFaces(),
(baseFileDir()/name()/"surface"),
false // serial - already merged
);
surfaceWriterPtr_->write("p(Curle)", pDash);
surfaceWriterPtr_->endTime();
surfaceWriterPtr_->clear();
}
}
else
{
forAll(observerPositions_, pointi)
{
if (rawFilePtrs_.set(pointi))
{
OFstream& os = rawFilePtrs_[pointi];
writeCurrentTime(os);
os << pDash[pointi] << endl;
}
}
}
return true;
}
bool Foam::functionObjects::Curle::write()
{
return true;
}
// ************************************************************************* //