In chemistryModel "li" is set to the current cell index but for other reacting
systems it should be set to the current index of the element for which the
reaction system is being evaluated.
In the ODESolver "li" is the current index of the element for which the ODE
system is being solved if there is a list of related systems being solved,
otherwise it can be set to 0.
Refactored the function for scaling the size group volume fractions to
better handle situations in which their sum drifts away from unity.
Scaling is now turned on by default, and can be turned off in the
solution dictionary for the population balance.
Additional revision and renaming of *Polydisperse tutorials
Patch contributed by Institute of Fluid Dynamics,
Helmholtz-Zentrum Dresden - Rossendorf (HZDR)
Removed unnecessary clutter in header descriptions for models that are
only required for testing purposes.
Patch contributed by Institute of Fluid Dynamics,
Helmholtz-Zentrum Dresden - Rossendorf (HZDR)
This fix also required a generalization of the corresponding base class,
which allows the user to specify the number of daughter particles per
breakup event separately.
Patch contributed by Institute of Fluid Dynamics,
Helmholtz-Zentrum Dresden - Rossendorf (HZDR)
Following this commit, a coalescence event leading to a size larger than
that of the last size group is not discarded anymore, but leads to an
accumulation of volume fraction in the last size group.
Patch contributed by Institute of Fluid Dynamics,
Helmholtz-Zentrum Dresden - Rossendorf (HZDR)
The various temporary fields used to create the nuTilda equation sources are now
internal fields to avoid unnecessary evaluation of boundary conditions, lowering
storage and reducing CPU time, particularly when running in parallel. These
temporary fields are now named with respect to the model so that they can be
cached conveniently and written as required.
The LESRegion field can now be contructed on demand if it is requested as a
cached temporary field and written out for diagnostics if needed, for example in
the tutorials/incompressible/pisoFoam/LES/motorBike tutorial:
cacheTemporaryObjects
(
SpalartAllmarasDDES:LESRegion
);
functions
{
writeCachedObjects
{
type writeObjects;
libs ("libutilityFunctionObjects.so");
writeControl writeTime;
writeOption anyWrite;
objects
(
SpalartAllmarasDDES:LESRegion
);
}
#include "cuttingPlane"
#include "streamLines"
#include "forceCoeffs"
}
which provides a very convenient mechanism to process and write any temporary
fields created during a time-step, either within models the construction of
equations and matrices or any other intermediate processing step within an
OpenFOAM application. The cached fields can relate to physical properties in
models, e.g. the generation term or other terms in the turbulence models, or
numerical, e.g. the limiters used on convection schemes. This mechanism
provides a new very powerful non-intrusive way of analysing the internals of an
OpenFOAM application for diagnosis and general post-processing which cannot be
easily achieved by any other means without adding specific diagnostics code to
the models or interest and recompiling.
For example to cache the kEpsilon:G field in
tutorials/incompressible/simpleFoam/pitzDaily add the dictionary entry
cacheTemporaryObjects
(
grad(k)
kEpsilon:G
);
to system/controlDict and to write the field add a writeObjects entry to the
functions list:
functions
{
writeCachedObjects
{
type writeObjects;
libs ("libutilityFunctionObjects.so");
writeControl writeTime;
writeOption anyWrite;
objects
(
grad(k)
kEpsilon:G
);
}
#includeFunc streamlines
}
If a name of a field which in never constructed is added to the
cacheTemporaryObjects list a waning message is generated which includes a useful
list of ALL the temporary fields constructed during the time step, e.g. for the
tutorials/incompressible/simpleFoam/pitzDaily case:
--> FOAM Warning : Could not find temporary object dummy in registry region0
Available temporary objects
81
(
(((0.666667*C1)-C3)*div(phi))
div(phi)
(interpolate(nuEff)*magSf)
surfaceIntegrate(phi)
(interpolate(DepsilonEff)*magSf)
((interpolate(((1|((1|(1|A(U)))-H(1)))-(1|A(U))))*snGrad(p))*magSf)
grad(p)
((interpolate(nuEff)*magSf)*snGradCorr(U))
(interpolate((1|((1|(1|A(U)))-H(1))))*magSf)
((1|((1|(1|A(U)))-H(1)))-(1|A(U)))
((Cmu*sqr(k))|epsilon)
interpolate(HbyA)
interpolate(DkEff)
interpolate(U)
phiHbyA
weights
div(((interpolate((1|((1|(1|A(U)))-H(1))))*magSf)*snGradCorr(p)))
(phiHbyA-flux(p))
MRFZoneList:acceleration
average(interpolate(max(epsilon,epsilonMin)))
div(((interpolate(DepsilonEff)*magSf)*snGradCorr(epsilon)))
nuEff
kEpsilon:G
grad(k)
interpolate((1|((1|(1|A(U)))-H(1))))
(nuEff*dev2(T(grad(U))))
grad(U)
interpolate(epsilon)
(phi*linearUpwind::correction(U))
((interpolate(DepsilonEff)*magSf)*snGradCorr(epsilon))
grad(k)Cached
(HbyA-((1|((1|(1|A(U)))-H(1)))*grad(p)))
pos0(phi)
-div((nuEff*dev2(T(grad(U)))))
H(1)
interpolate(k)
((nut|sigmak)+nu)
snGrad(p)
(0.666667*div(phi))
surfaceIntegrate(((interpolate((1|((1|(1|A(U)))-H(1))))*magSf)*snGradCorr(p)))
DepsilonEff
(1|A(U))
surfaceIntegrate(((interpolate(DepsilonEff)*magSf)*snGradCorr(epsilon)))
limitedLinearLimiter(epsilon)
surfaceIntegrate(((interpolate(DkEff)*magSf)*snGradCorr(k)))
grad(epsilon)
(interpolate(DkEff)*magSf)
div(((interpolate(DkEff)*magSf)*snGradCorr(k)))
surfaceSum(magSf)
((1|A(U))-(1|((1|(1|A(U)))-H(1))))
(1|((1|(1|A(U)))-H(1)))
((interpolate((1|((1|(1|A(U)))-H(1))))*magSf)*snGradCorr(p))
mag(div(phi))
surfaceSum((magSf*interpolate(max(epsilon,epsilonMin))))
interpolate(DepsilonEff)
-grad(p)
snGradCorr(p)
interpolate(p)
interpolate(max(epsilon,epsilonMin))
dev(twoSymm(grad(U)))
surfaceIntegrate((phi*linearUpwind::correction(U)))
(magSf*interpolate(max(epsilon,epsilonMin)))
limitedLinearLimiter(k)
(nut+nu)
HbyA
max(epsilon,epsilonMin)
surfaceIntegrate(((interpolate(nuEff)*magSf)*snGradCorr(U)))
surfaceIntegrate(phiHbyA)
DkEff
(((C1*kEpsilon:G)*epsilon)|k)
(mag(S)+2.22507e-308)
(((1|A(U))-(1|((1|(1|A(U)))-H(1))))*grad(p))
((nut|sigmaEps)+nu)
((interpolate(DkEff)*magSf)*snGradCorr(k))
(nut*(dev(twoSymm(grad(U)))&&grad(U)))
interpolate(nuEff)
((C2*epsilon)|k)
interpolate((nuEff*dev2(T(grad(U)))))
(epsilon|k)
div(phiHbyA)
div(((interpolate(nuEff)*magSf)*snGradCorr(U)))
)
Multiple regions are also supported by specifying individual region names in a
cacheTemporaryObjects dictionary, e.g. in the
tutorials/heatTransfer/chtMultiRegionFoam/heatExchanger case
cacheTemporaryObjects
{
air
(
kEpsilon:G
);
porous
(
porosityBlockage:UNbr
);
}
functions
{
writeAirObjects
{
type writeObjects;
libs ("libutilityFunctionObjects.so");
region air;
writeControl writeTime;
writeOption anyWrite;
objects (kEpsilon:G);
}
writePorousObjects
{
type writeObjects;
libs ("libutilityFunctionObjects.so");
region porous;
writeControl writeTime;
writeOption anyWrite;
objects (porosityBlockage:UNbr);
}
}
which constructs the name for a field property associated with the model by
pre-pending the given field name with <modelType>: e.g. the generation term in
the kEpsilon model is named kEpsilon:G
This is useful to visualise sources which are created as
volScalarField::Internal, e.g. the turbulence generation term for models like
kEpsilon in which it is named kEpsilon:G.
To avoid additional clutter in the interface volFields, surfaceFields and
pointFields are now selected from a single fields selection box consistent with
the single directory with guaranteed unique names in which they are stored.
Note that when visualising the "phi" flux fields that these are extensive, the
value depends directly on the face area, so unless the mesh is uniform
interpolated continuous colour plots are not physical or informative.
Based on proposal contributed by Mattijs Janssens
The filtering level for an iso-surface can now be selected. The keyword
is "filtering", and the options are "full", "partial" or "none". The
default is "full". The other options are only retained for debugging and
to provide a fallback if robustness of the full filtering algorithm is
an issue. As of commit 2ee8b7ac, "full" filtering has no known
disadvantages and is recommended in all usage cases.
This setting replaces the "regularise" entry, which switched between
what are now the "full" and "none" settings. "partial" was not
previously an option.
This is a slight rework of commit c81abfef. Instead of adapting tet
base points cell-by-cell, the dangling points are pre-computed and then
the adaptations to the base points are made face-by-face. This correctly
adapts faces which have different dangling points relative to the owner
and neighbour cells.
The corresponding constructor in the base class was removed as part of a
number of related changes to patch field construction in commit
70021b12.
Resolves bug report https://bugs.openfoam.org/view.php?id=3304
For example in the combustion/coldEngineFoam/freePiston/0/p field the
internalField entry may be obtained from the include/caseSettings dictionary
using either a relative path:
internalField uniform $include/caseSettings!internalField/p;
or an absolute path:
internalField uniform ${$FOAM_CASE/0/include/caseSettings!internalField/p};
in which recursive substitution using ${...} is applied to expand the $FOAM_CASE
environment variable.
In order to avoid conflict with the use of ':' in model-specific fields,
e.g. "thermo:rho", in the "slash" syntax the '!' character is now used to refer
to the top-level dictionary.
If there is a part of the keyword before the '!' then this is taken to be the
file name of the dictionary from which the entry will be looked-up using the
part of the keyword after the '!'.
For example, given a dictionary file named testSlashDict2:
internalField 5.6;
active
{
type fixedValue;
value.air $internalField;
}
it is now possible to read entries from it directly in the dictionary file testSlashDict:
external
{
value $testSlashDict2!active/value.air;
}
active2
{
$testSlashDict2!active;
}
which expands to
external
{
value 5.6;
}
active2
{
type fixedValue;
value.air 5.6;
}
Arc-edges can now be specified with a sector angle (in degrees) and an
axis of the circle of which the arc forms a part. The new syntax is as
follows:
edges
(
arc <vertex-0> <vertex-1> <angle> (<axis-x> <axis-y> <axis-z>)
);
This is often more convenient than the alternative specification where a
third third point somewhere in the arc is given; it usually does not
require any additional calculation on the part of the user, and multiple
entries are very likely to be identical.
Which specification is used depends on the form of the entry that comes
after the two vertices. If the entry is a vector then it is assumed to
be a point in the arc; if it is scalar then is is taken to be the angle
and the axis is assumed to follow.
For example, to put a 90 degree arc between the vertices 12 and 13, at
(1 0 0) and (0 1 0) respectively, the following specification can now be
used:
edges
(
arc 12 13 90.0 (0 0 1)
);
This is equivalent to the existing point-in-arc speficiation below:
edges
(
arc 12 13 (0.707107 0.707107 0)
);
An edge's points are ordered on the perimeter of the circle according to
a right-hand screw rule on the given axis. Changing the the side of the
edge on which the arc is defined can therefore be achieved by reversing
either the edge or the direction of the axis.
If the given axis is not perpendicular to the line between the vertices,
then the arc gains some axial length and becomes a helix.
A new optional "slash" scoping syntax is now provided which is more intuitive
than the current "dot" syntax as it corresponds to the common directory/file
access syntax used in UNIX, and avoids limitations of the "dot" (see below)
e.g.
internalField 3.4;
active
{
type fixedValue;
value.air $internalField;
}
inactive
{
type anotherFixedValue;
value $../active/value.air;
anotherValue $:active/value.air;
sub
{
value $../../active/value.air;
anotherValue $:active/value.air;
}
}
"U.*"
{
solver GAMG;
}
e.air
{
// This does expand
$U.air;
}
"#inputSyntax slash;" selects the new "slash" syntax.
"../" refers to the parent directory.
":" refers to the top-level directory.
The corresponding dictionary using the current "dot" syntax is
internalField 3.4;
active
{
type fixedValue;
value.air $internalField;
}
inactive
{
type anotherFixedValue;
value $..active.value.air;
anotherValue $:active.value.air;
sub
{
value $...active.value.air;
anotherValue $:active.value.air;
}
}
"U.*"
{
solver GAMG;
}
e.air
{
// This doesn't expand
$U.air;
}
Note that the "$U.air" expansion does not work in this case due to the
interference between the use of '.' for scoping and phase-name.
This is a fundamental problem which prompted the development of the new more
intuitive and flexible "slash" syntax.
The new syntax also allows a for planned future development to access entries
in directories in other files, e.g.
active
{
type fixedValue;
value.air $FOAM_CASE/internalFieldValues/value.air;
}
or
active
{
type fixedValue;
value.air :../internalFieldValues/value.air;
}