ENH: surfaceCourantNumber: new finite-area function object
Computes the surface Courant number field at finite-area face centres. Note: the calculation is performed at face centers, not edge centers.
This commit is contained in:
parent
4f1e7f6343
commit
1a6f0f997a
@ -42,5 +42,6 @@ liquidFilm/kinematicThinFilm/kinematicThinFilm.C
|
||||
derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.C
|
||||
|
||||
functionObjects/setTimeStep/setTimeStepFaRegionsFunctionObject.C
|
||||
functionObjects/surfaceCourantNumber/surfaceCourantNumber.C
|
||||
|
||||
LIB = $(FOAM_LIBBIN)/libregionFaModels
|
||||
|
@ -0,0 +1,227 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2024 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 "surfaceCourantNumber.H"
|
||||
#include "fvMesh.H"
|
||||
#include "faMesh.H"
|
||||
#include "areaFields.H"
|
||||
#include "edgeFields.H"
|
||||
#include "facEdgeIntegrate.H"
|
||||
#include "zeroGradientFaPatchFields.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace functionObjects
|
||||
{
|
||||
defineTypeNameAndDebug(surfaceCourantNumber, 0);
|
||||
addToRunTimeSelectionTable(functionObject, surfaceCourantNumber, dictionary);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::functionObjects::surfaceCourantNumber::writeFileHeader(Ostream& os)
|
||||
{
|
||||
writeHeader(os, "Surface Courant Number");
|
||||
|
||||
writeCommented(os, "Time");
|
||||
writeTabbed(os, "min");
|
||||
writeTabbed(os, "max");
|
||||
writeTabbed(os, "mean");
|
||||
os << endl;
|
||||
|
||||
writtenHeader_ = true;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::functionObjects::surfaceCourantNumber::surfaceCourantNumber
|
||||
(
|
||||
const word& name,
|
||||
const Time& runTime,
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
fvMeshFunctionObject(name, runTime, dict),
|
||||
writeFile(mesh_, name, typeName, dict),
|
||||
resultName_("surfaceCo"),
|
||||
phisName_("phis"),
|
||||
rhoName_("rho")
|
||||
{
|
||||
read(dict);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::functionObjects::surfaceCourantNumber::read(const dictionary& dict)
|
||||
{
|
||||
if (!fvMeshFunctionObject::read(dict) || !writeFile::read(dict))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
dict.readIfPresent("result", resultName_);
|
||||
dict.readIfPresent("phis", phisName_);
|
||||
dict.readIfPresent("rho", rhoName_);
|
||||
|
||||
// Registry containing all finite-area meshes on the polyMesh
|
||||
const auto* faRegistryPtr = faMesh::registry(mesh_);
|
||||
|
||||
if (!faRegistryPtr)
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "No finite-area object registry is available."
|
||||
<< abort(FatalIOError);
|
||||
}
|
||||
|
||||
word areaName;
|
||||
|
||||
if (!dict.readIfPresent("area", areaName))
|
||||
{
|
||||
wordList available = faRegistryPtr->sortedNames<faMesh>();
|
||||
if (!available.empty())
|
||||
{
|
||||
areaName = available.front();
|
||||
}
|
||||
}
|
||||
|
||||
if (areaName.empty())
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "No name for finite-area mesh is available."
|
||||
<< abort(FatalIOError);
|
||||
}
|
||||
|
||||
faMeshPtr_ = std::shared_ptr<const faMesh>
|
||||
(
|
||||
faRegistryPtr->cfindObject<faMesh>(areaName),
|
||||
[](const faMesh*) { /* no-op deleter to avoid double deletion */ }
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::functionObjects::surfaceCourantNumber::execute()
|
||||
{
|
||||
if (!faMeshPtr_->foundObject<edgeScalarField>(phisName_))
|
||||
{
|
||||
WarningInFunction
|
||||
<< "No edge flux field is available. "
|
||||
<< "Name of provided edge flux field (phi): " << phisName_
|
||||
<< endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& phis = faMeshPtr_->lookupObject<edgeScalarField>(phisName_);
|
||||
|
||||
tmp<areaScalarField::Internal> tCo =
|
||||
(0.5*faMeshPtr_->time().deltaT())
|
||||
*fac::edgeSum(mag(phis))()()
|
||||
/faMeshPtr_->S();
|
||||
|
||||
areaScalarField::Internal Co = tCo.ref();
|
||||
|
||||
if (Co.dimensions() == dimDensity)
|
||||
{
|
||||
Co /= faMeshPtr_->lookupObject<areaScalarField>(rhoName_);
|
||||
}
|
||||
|
||||
auto* resultPtr = faMeshPtr_->getObjectPtr<areaScalarField>(resultName_);
|
||||
|
||||
if (!resultPtr)
|
||||
{
|
||||
resultPtr = new areaScalarField
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
resultName_,
|
||||
faMeshPtr_->time().timeName(),
|
||||
*faMeshPtr_,
|
||||
IOobjectOption()
|
||||
),
|
||||
*faMeshPtr_,
|
||||
dimensionedScalar(dimless, Zero),
|
||||
faPatchFieldBase::zeroGradientType()
|
||||
);
|
||||
regIOobject::store(resultPtr);
|
||||
}
|
||||
auto& result = *resultPtr;
|
||||
|
||||
result.internalFieldRef() = tCo;
|
||||
result.correctBoundaryConditions();
|
||||
|
||||
|
||||
const scalarMinMax limits(gMinMax(result));
|
||||
const scalar mean = gAverage(result);
|
||||
|
||||
Log << "Surface Courant number: "
|
||||
<< "mean: " << mean
|
||||
<< " max: " << limits.max()
|
||||
<< endl;
|
||||
|
||||
if (writeToFile())
|
||||
{
|
||||
if (!writtenHeader_) writeFileHeader(file());
|
||||
|
||||
writeCurrentTime(file());
|
||||
file()
|
||||
<< token::TAB << limits.min()
|
||||
<< token::TAB << limits.max()
|
||||
<< token::TAB << mean
|
||||
<< endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::functionObjects::surfaceCourantNumber::write()
|
||||
{
|
||||
const auto* result = faMeshPtr_->cfindObject<areaScalarField>(resultName_);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Log << type() << " " << name() << " write: " << result->name() << endl;
|
||||
|
||||
result->write();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,175 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2024 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/>.
|
||||
|
||||
Class
|
||||
Foam::functionObjects::surfaceCourantNumber
|
||||
|
||||
Description
|
||||
Computes the surface Courant number field at finite-area face centres.
|
||||
|
||||
Operands:
|
||||
\table
|
||||
Operand | Type | Location
|
||||
input | - | -
|
||||
output file | dat <!--
|
||||
--> | postProcessing/\<FO\>/\<time\>/\<file\>
|
||||
output field | areaScalarField | \<time\>/\<outField\>
|
||||
\endtable
|
||||
|
||||
Usage
|
||||
Minimal example by using \c system/controlDict.functions:
|
||||
\verbatim
|
||||
surfaceCourantNumber1
|
||||
{
|
||||
// Mandatory entries
|
||||
type surfaceCourantNumber;
|
||||
libs (regionFaModels);
|
||||
|
||||
// Optional entries
|
||||
area <word>;
|
||||
result <word>;
|
||||
phis <word>;
|
||||
rho <word>;
|
||||
|
||||
// Inherited entries
|
||||
...
|
||||
}
|
||||
\endverbatim
|
||||
|
||||
where the entries mean:
|
||||
\table
|
||||
Property | Description | Type | Reqd | Deflt
|
||||
type | Type name: surfaceCourantNumber | word | yes | -
|
||||
libs | Library name: regionFaModels | word | yes | -
|
||||
area | Name of finite-area region | word | no | region0
|
||||
result | Name of result field | word | no | surfaceCo
|
||||
phis | Name of edge flux field | word | no | phis
|
||||
rho | Name of density field | word | no | rho
|
||||
\endtable
|
||||
|
||||
The inherited entries are elaborated in:
|
||||
- \link fvMeshFunctionObject.H \endlink
|
||||
- \link writeFile.H \endlink
|
||||
|
||||
Note
|
||||
- The \c surfaceCourantNumber calculates the Courant number at face centers,
|
||||
rather than at edge centers.
|
||||
|
||||
SourceFiles
|
||||
surfaceCourantNumber.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef functionObjects_surfaceCourantNumber_H
|
||||
#define functionObjects_surfaceCourantNumber_H
|
||||
|
||||
#include "fvMeshFunctionObject.H"
|
||||
#include "writeFile.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward Declarations
|
||||
class faMesh;
|
||||
|
||||
namespace functionObjects
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class surfaceCourantNumber Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class surfaceCourantNumber
|
||||
:
|
||||
public fvMeshFunctionObject,
|
||||
public writeFile
|
||||
{
|
||||
// Private Data
|
||||
|
||||
//- Name of result field
|
||||
word resultName_;
|
||||
|
||||
//- Name of edge flux field
|
||||
word phisName_;
|
||||
|
||||
//- Name of density field
|
||||
word rhoName_;
|
||||
|
||||
//- Reference to finite-area object registry
|
||||
std::shared_ptr<const faMesh> faMeshPtr_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Output file header information
|
||||
virtual void writeFileHeader(Ostream& os);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("surfaceCourantNumber");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from Time and dictionary
|
||||
surfaceCourantNumber
|
||||
(
|
||||
const word& name,
|
||||
const Time& runTime,
|
||||
const dictionary& dict
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~surfaceCourantNumber() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Read the surfaceCourantNumber data
|
||||
virtual bool read(const dictionary&);
|
||||
|
||||
//- Calculate the Courant number field and return true if successful
|
||||
virtual bool execute();
|
||||
|
||||
//- Write the result field
|
||||
virtual bool write();
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace functionObjects
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,38 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2406 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
surfaceCourantNumber1
|
||||
{
|
||||
// Mandatory entries
|
||||
type surfaceCourantNumber;
|
||||
libs (regionFaModels);
|
||||
|
||||
// Optional entries
|
||||
area region0;
|
||||
result surfaceCourantNumberField;
|
||||
rho rho;
|
||||
phis phis;
|
||||
|
||||
// Inherited entries
|
||||
writePrecision 6;
|
||||
writeToFile true;
|
||||
useUserTime true;
|
||||
|
||||
region region0;
|
||||
enabled true;
|
||||
log true;
|
||||
timeStart 0;
|
||||
timeEnd 1000;
|
||||
executeControl timeStep;
|
||||
executeInterval 1;
|
||||
writeControl writeTime;
|
||||
writeInterval -1;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -50,5 +50,9 @@ maxCo 5;
|
||||
|
||||
maxDeltaT 0.1;
|
||||
|
||||
functions
|
||||
{
|
||||
#include "FOsurfaceCourantNumber"
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
|
Loading…
Reference in New Issue
Block a user