TUT: example of user access for Function1

This commit is contained in:
Mark Olesen 2020-12-11 16:08:07 +01:00
parent b59ae32d68
commit c2692e7c99
3 changed files with 201 additions and 9 deletions

View File

@ -51,4 +51,9 @@ maxCo 1;
maxDeltaT 1;
functions
{
#include "relVelocity"
}
// ************************************************************************* //

View File

@ -0,0 +1,118 @@
// --------------------------------*- C++ -*-------------------------------- //
//
// File
// OpenFOAM coded function object
//
// Description
// Write relative rotational speed
//
// ------------------------------------------------------------------------- //
relVelocity
{
type coded;
name relVelocity;
libs ( utilityFunctionObjects );
coeffs
{
// User input (duplicate of constant/dynamicMeshDict)
// origin (-3 2 2.6);
// axis (0 0 1);
// omega 10;
// zones ( rotatingZone );
#sinclude "<constant>/dynamicMeshDict"
}
// Additional context for code execute/write
codeContext
{
verbose true;
}
codeData
#{
vector origin;
vector omega;
wordRes zoneNames;
#};
codeRead
#{
const dictionary& coeffs = dict.optionalSubDict("coeffs");
const dictionary& context = this->codeContext();
origin = coeffs.get<vector>("origin");
omega =
(
// speed
(
coeffs.found("rpm")
? degToRad(coeffs.get<scalar>("rpm") / 60.0)
: coeffs.get<scalar>("omega")
)
// axis
* normalised(coeffs.getOrDefault<vector>("axis", vector(0,0,1)))
);
if (!coeffs.readIfPresent("zones", zoneNames))
{
if (coeffs.found("cellZone"))
{
zoneNames.resize(1);
coeffs.readEntry("cellZone", zoneNames[0]);
}
}
if (context.getOrDefault<bool>("verbose", false))
{
Log<< "Relative velocity at origin " << origin << "\n";
}
#};
codeExecute // codeWrite
#{
const dictionary& context = this->codeContext();
if (context.getOrDefault<bool>("verbose", false))
{
Log<< "Calculate relative velocity\n";
}
const auto& cc = mesh().C();
const auto& U = mesh().lookupObject<volVectorField>("U");
auto trelVel = volVectorField::New
(
"relVelocity",
mesh(),
dimensionedVector(dimVelocity, Zero),
"zeroGradient"
);
auto& relVel = trelVel.ref();
auto& relVelField = relVel.primitiveFieldRef();
if (zoneNames.empty())
{
for (label celli = 0; celli < mesh().nCells(); ++celli)
{
relVelField[celli] = U[celli] - (omega ^ (cc[celli] - origin));
}
}
else
{
for (const label celli : mesh().cellZones().selection(zoneNames))
{
relVelField[celli] = U[celli] - (omega ^ (cc[celli] - origin));
}
}
relVel.correctBoundaryConditions();
relVel.write();
#};
}
// ************************************************************************* //

View File

@ -1,14 +1,14 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2012 |
| \\ / O peration | Version: v2106 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format binary;
format ascii;
class volVectorField;
object U;
}
@ -25,13 +25,82 @@ boundaryField
type uniformFixedValue;
value $internalField;
uniformValue table
(
(0 (0 0 0.1))
(1 (0 0 0.1))
(4 (0 0 0.3))
(14 (0 0 0.5))
);
uniformValue
{
type coded;
name examplePatchFunction1;
// Example code to combine/adapt Function1 to PatchFunction1
// User inputs
/// verbose true;
timeFunction
{
type table;
values
(
(0 0.1)
(1 0.1)
(4 0.3)
(14 0.5)
);
}
// ... or a function of time
directionFunction (0 0 1);
// Code implementation.
code
#{
// Persistent (Member) Data
static autoPtr<Function1<scalar>> baseVel;
static autoPtr<Function1<vector>> baseDir;
// Base settings
const dictionary& dict = this->dictionaryContent::dict();
const polyPatch& pp = this->patch();
vector velDir(0, 0, 1);
if (!baseVel)
{
baseVel = Function1<scalar>::New("timeFunction", dict);
}
const bool verbose = dict.getOrDefault<bool>("verbose", false);
if (!baseDir && dict.found("directionFunction"))
{
// ie, NewIfPresent
baseDir = Function1<vector>::New("directionFunction", dict);
InfoErr
<< "Function1 for direction" << nl;
}
if (baseDir)
{
velDir = normalised(baseDir->value(x));
}
if (verbose)
{
InfoErr
<< "vel: " << baseVel->value(x)
<< " dir:" << velDir << nl;
}
return tmp<vectorField>::New
(
pp.size(),
baseVel->value(x) * velDir
);
#};
}
}
outlet