Needed to support overlapping faceZones with topology change
//- Return the list of flips for the facei
// for each of the face zones in faceiZones
boolList zonesFlipFace
(
const label facei,
const labelList& faceiZones
);
//- Given a global object index, return the list of zones it is in
labelList whichZones(const label objectIndex) const;
which will replace the original whichZone function
//- Given a global object index, return the zone it is in.
// If object does not belong to any zones, return -1
// *** This will be replaced by whichZones
label whichZone(const label objectIndex) const;
so that cells, faces and points can exist in any number of zones.
This is an alternative, approximate parameterisation of the JONSWAP
spectrum, in which the significant wave height and period are specified
instead of the wind speed and fetch.
Example specification, in constant/waveProperties:
waves
(
irregular
{
spectrum GodaJONSWAP;
Hs 2; // <- significant wave height [m]
Ts 6; // <- significant wave period [s]
n 12; // <- number of samples []
angle 0;
}
);
Constructing the fields in patch order is logical, and preferable to
using the potentially arbitrary order in which the fields are specified
in the field dictionary. It also resolves the issue that the
construction of jump cyclics can fail if the patch fields are not
specified in the same order as the patches.
for example it is now possible to freeze the cylinder head points with respect
to the piston motion but still move with respect to the valve motion by
specifying the cylinderHead pointZone only in the piston specification, e.g.:
piston
{
patches (piston);
axis (0 0 1);
motion
{
type crankConnectingRodMotion;
conRodLength 0.147;
stroke 0.08423;
}
// Move the points in the piston bowl with the piston
movingZones (pistonBowl);
// Freeze the points in the cylinder head
frozenZones (cylinderHead);
// There is no need to update the motion weights
fractionalTravelInterval 1;
}
The FV patches don't hold any data that requires updating. If they did,
then they would require a full set of mesh change hooks (i.e.,
topoChange, distribute, and mesh mapping, as well as move). The poly
patches currently hold all of this sort of data, and have a complete
system of methods to handle mesh changes.
to calculate and write the forces and moments on moving rigid bodies with
specified or calculated centre of rotation using Foam::RBD::rigidBodyMotion
respectively. The current moving centre of rotation is used in the evaluation
of the moments but does not affect the evaluation of the forces.
Class
Foam::functionObjects::movingForces
Description
Calculates the forces and moments by integrating the pressure and
skin-friction forces over a given list of patches of a moving object.
The centre of rotation (CofR) of the moving object is specified as a
Foam::Function1<vector> of time.
Member function movingForces::write() calculates the forces/moments and
writes the forces/moments into the file \<timeDir\>/movingForces.dat and bin
data (if selected) to the file \<timeDir\>/movingForces_bin.dat
Example of function object specification:
\verbatim
movingForces1
{
type movingForces;
libs ("libforces.so");
log yes;
patches (walls);
CofR
{
type sine;
amplitude (0 0.025 0);
frequency 1;
start 0;
level (0 0 0);
}
}
\endverbatim
Usage
\table
Property | Description | Required | Default value
type | Type name: movingForces | yes |
log | Write force data to standard output | no | no
patches | Patches included in the forces calculation | yes |
p | Pressure field name | no | p
U | Velocity field name | no | U
rho | Density field name (see below) | no | rho
phase | Phase name for phase-fraction | no |
CofR | Centre of rotation Foam::Function1<vector> | yes |
directForceDensity | Force density supplied directly (see below)|no|no
fD | Name of force density field (see below) | no | fD
\endtable
Bin data is optional, but if the dictionary is present, the entries must
be defined according o
\table
nBin | number of data bins | yes |
direction | direction along which bins are defined | yes |
cumulative | bin data accumulated with increasing distance | yes |
\endtable
Note
- For incompressible cases, set \c rho to \c rhoInf and provide
a \c rhoInf value corresponding to the free-stream constant density.
- If the \c phase name is specified the corresponding phase-fraction field
\c alpha.<phase> is used to filter the surface force field
before integration.
- If the force density is supplied directly, set the \c directForceDensity
flag to 'yes', and supply the force density field using the \c
fDName entry
See also
Foam::functionObject
Foam::functionObjects::forcesBase
Foam::functionObjects::fvMeshFunctionObject
Foam::functionObjects::logFiles
Foam::functionObjects::timeControl
Foam::Function1
SourceFiles
movingForces.C
Class
Foam::functionObjects::rigidBodyForces
Description
Calculates the forces and moments by integrating the pressure and
skin-friction forces over a given list of patches of a moving rigid body.
The centre of rotation (CofR) of the moving rigid object is obtained
directly from the corresponding Foam::RBD::rigidBodyMotion of the
specified body.
Member function rigidBodyForces::write() calculates the forces/moments and
writes the forces/moments into the file \<timeDir\>/rigidBodyForces.dat
and bin data (if selected) to the file \<timeDir\>/rigidBodyForces_bin.dat
Example of function object specification:
\verbatim
rigidBodyForces1
{
type rigidBodyForces;
libs ("librigidBodyForces.so");
body (hull);
patches (walls);
log yes;
}
\endverbatim
Usage
\table
Property | Description | Required | Default value
type | Type name: rigidBodyForces | yes |
log | Write force data to standard output | no | no
body | Name of the rigid body | yes |
patches | Patches included in the forces calculation | yes |
p | Pressure field name | no | p
U | Velocity field name | no | U
rho | Density field name (see below) | no | rho
phase | Phase name for phase-fraction | no |
directForceDensity | Force density supplied directly (see below)|no|no
fD | Name of force density field (see below) | no | fD
\endtable
Bin data is optional, but if the dictionary is present, the entries must
be defined according o
\table
nBin | number of data bins | yes |
direction | direction along which bins are defined | yes |
cumulative | bin data accumulated with increasing distance | yes |
\endtable
Note
- For incompressible cases, set \c rho to \c rhoInf and provide
a \c rhoInf value corresponding to the free-stream constant density.
- If the \c phase name is specified the corresponding phase-fraction field
\c alpha.<phase> is used to filter the surface force field
before integration.
- If the force density is supplied directly, set the \c directForceDensity
flag to 'yes', and supply the force density field using the \c
fDName entry
See also
Foam::functionObject
Foam::functionObjects::forcesBase
Foam::functionObjects::fvMeshFunctionObject
Foam::functionObjects::logFiles
Foam::functionObjects::timeControl
Foam::RBD::rigidBodyMotion
SourceFiles
rigidBodyForces.C
foamMonitor has new options to select columns of data, plot the data on
x-axis and the independent variable on y-axis, and to display a single
graph without refreshing periodically. It also now terminates cleanly,
removing the gnuplot processes behind it.
New options:
-columns | -c <cols> display specfied columns, comma-separated, e.g. 2,4
-flip | -f plot data on x-axis, independent variable on y-axis
-once | -o print a graph one time without refreshing
for the multiValveEngine fvMeshMover. This replaced the hard-coded messages
printed by the multiValveEngine class, providing automatic logging of the piston
and valve speed and position and easy user extension or replacement to provide
additional case-specific diagnostics without having to hack the core
multiValveEngine code. A functionObject configuration file is provided so that
the simple line
can be added to the system/functions file to enable this functionObject.
This utility is used as a pre-processing step for the multiValveEngine
fvMeshMover and provides two options:
-cylinderHead to generate the pointZone within the cylinder head
-pistonBowl to generate the pointZone within the piston bowl
The updated tutorials/XiFluid/kivaTest case demonstrates the application of this
utility.
This mesh mover facilitates explicit node translation based on scaled distance
functions for the providing smooth deformation of the mesh to accommodate the
motion piston and multiple valves present in IC engines. and run-time mesh-to-mesh mapping used to avoid
extreme mesh distortion and support the necessary topology changes that occur at
valve closure.
Highlighted features include:
* Piston motion based on user-defined functions, with options for standard crank
and connecting rod motion.
* Valve motion based on user-provided lift data or table.
* Support for linerPatches, slidingPatches, and frozenZones.
* Non-conformal coupled (NCC) interfaces can be used to provide better control
of the mesh-motion around valves
* Run-time mesh-to-mesh mapping used to avoid extreme mesh distortion and
support the necessary topology changes that occur at valve closure
* Control over mesh motion per moving object including motion parameters and layer
thickness.
Description from the multiValveEngine.H file:
A mesh mover using explicit node translation based on scaled distance
functions per moving object. The mover supports any number of valves
together with piston motion and following features:
- Piston motion: Function1 of user-time, may be set to
crankConnectingRodMotion for standard crank and connecting rod motion.
- Valve motion: Function1, may be set to table if the valve lift date is
provided in the form of a table.
- Smooth mesh motion between a moving object and other patches.
- linerPatches: the set of patches corresponding to the cylinder liner
Used by createEngineZones
- slidingPatches: a set of patches along which mesh is allowed
to deform. For example, on the cylinder liner, it is desired to
slide mesh nodes while piston is moving.
- frozenZones: list of pointZones the points of which are frozen,
i.e. do not move.
- Run-time clearance estimation based on patch-to-patch distances printed.
- Supports cellSet and cellZone definitions to restrict mesh motion.
- Supports domains with nonConformalCoupling (NCC) interfaces,
enabling e.g. nodes to slide along with the interface.
- Closing the valve can be achieved by meshToMesh mapping onto a new
grid with closed valve geometry at user given time.
- Mesh motion can be controlled per moving object by setting:
- patches: list of patches defining the object.
- motion: a Function1 which returns the object position
as a function of time.
- movingZones: list of pointZones the points of which move with the
object.
- maxMotionDistance: a distance away from the moving object
after nodes are not allowed to move. (Default inf.)
- movingFrozenLayerThickness: thickness of layer in which points move
with the moving object. (Default 0)
- staticFrozenLayerThickness: thickness of layer in which points
are fixed with respect to static patches (e.g. walls). (Default 0)
- cosineScaling: a switch whether nodal translation is weighted by
its distance from the moving object. The objective is to yield less
deformation near the moving object and sustain e.g. boundary layer.
(Default no, i.e. linear weighting)
- fractionalTravelInterval: fraction of the stroke travelled after
which the cached motion scaling weights are recalculated
For valve object only:
- minLift: a minimum valve lift value after considered closed.
Some of the above parameters are highlighted in a given schematic
piston-valve configuration w.r.t entries used to control piston motion.
Furthermore, an example dictionary entries are provided below.
| | | |
| | | |
| | S | |
| | T | |
| | E | |
| | M | |
/ | | \
/ | | \
/ | | \
_____________/ | | \_____________
| : | | : |
| : /``````````````` ```````````````\ : |
| : / VALVE HEAD \ : |
| L : /_____________________________________________\ : |
| I : /\ : |
| N : || staticFrozenLayerThickness : |
| E : NCC (optional) \/ (w.r.t. piston motion) : |
| R : `````````` : |
| : : |
| : : |
|........:.......................................................:........|
| : /\ : |
| : || movingFrozenLayerThickness : |
|________:_________________________\/____________________________:________|
PISTON
\verbatim
mover
{
type multiValveEngine;
libs ("libfvMeshMoversMultiValveEngine.so");
frozenZones (frozenZone1 frozenZone2);
slidingPatches
(
liner
valveStem
"nonCouple.*"
);
linerPatches (liner);
piston
{
patches (piston);
axis (0 0 1);
motion
{
type crankConnectingRodMotion;
conRodLength 1e3;
stroke 1.0;
}
// Move the points in the piston bowl with the piston
movingZones (pistonBowl);
// Optional
maxMotionDistance 1e30;
movingFrozenLayerThickness 0;
staticFrozenLayerThickness 0;
fractionalTravelInterval 0.1;
cosineScaling yes;
}
valves
{
iv
{
patches (valveHead);
axis (0 0 1);
// Optional
maxMotionDistance 1e30;
movingFrozenLayerThickness 0;
staticFrozenLayerThickness 0;
fractionalTravelInterval 0.1;
cosineScaling yes;
minLift 0.001;
motion
{
type table;
values
(
(0 0)
(480 0.1)
(720 0)
);
// For multi-cycle simulations, use repeat
outOfBounds repeat;
interpolationScheme linear;
}
}
}
}
\endverbatim
Note:
The implementation utilises pointDist objects for distance computation,
resulting distance fields do not propagate through NCC interfaces. Hence,
there should be no horizontal NCC interface separating piston from
cylinder head as it would result in potentially ill defined mesh
deformation. Due to same feature, in a schematic case setup above, valve
motion affects only cells between NCC patches even though no cellSet is
explicitly defined.
SourceFiles
multiValveEngine.C
Patch contributed by:
* Heikki Kahila, Wärtsilä Finland: Original implementation
* Bulut Tekgül, Wärtsilä Finland: Testing, cleanup, help with refactoring
* Henry Weller, CFD Direct: Refactoring, generalisation, optimisation and
merging into OpenFOAM
Either single entries renamed using the -entry option with -rename:
-entry <entryName> -rename <newName>
or a list of entries can be renamed using the -rename <newNames> option:
-rename "<entryName0>=<newName0>, <entryName1>=<newName1>..."
These models represent a phase nucleating directly out of a
multi-component mixture into isolated particles (i.e., homogeneous),
rather than onto an existing surface or impurity (heterogeneous).
The homogeneousCondensation model can represent the initial stages of a
gas condensing into a liquid. Example usage, in constant/fvModels:
homogeneousCondensation
{
type homogeneousCondensation;
libs ("libmultiphaseEulerFvModels.so");
// Phases between which the transfer occurs. The first phase is the
// gas, and the second is the condensed liquid.
phases (gas water);
// The specie that is condensing
specie H2O;
// Linearise the latent heat contribution into the energy equation?
energySemiImplicit no;
// Saturation curve for the specie in the gaseous phase
pSat ArdenBuck;
}
The homogeneousLiquidPhaseSeparation model can represent the initial
stages of a liquid solution precipitating out a solid or separating into
two immiscible liquid phases: Example usage, in constant/fvModels:
homogeneousLiquidPhaseSeparation
{
type homogeneousLiquidPhaseSeparation;
libs ("libmultiphaseEulerFvModels.so");
// Phases between which the transfer occurs. The first phase is the
// solution, and the second is the precipitate.
phases (liquid sugar);
// The specie that is condensing
specie C2H12O6;
// Linearise the latent heat contribution into the energy equation?
energySemiImplicit no;
// Solubility given in mass of solute per mass of solvent
solubility constant 0.9;
}
If population balance is being used, then both of these models require a
source term to be applied to the size-group equations. This is achieved
by means of a new nucleationSizeGroup field source. Example usage, in
0/fDefault.water:
sources
{
homogeneousCondensation
{
type nucleationSizeGroup;
libs ("libmultiphaseEulerFvModels.so");
}
}
Functions have been added to populationBalance to generate the
volumetric allocation coefficient etaV. This is needed if a volume or
mass source is to be conveniently distributed into the size groups. The
number-based allocation coefficient, eta, is still available and is
still used in all cases within populationBalance.
The allocation bounds handling has been removed. This, as it turns out,
was just an incomplete subset of having both number- and volume-based
allocation coefficients implemented.
This thermal wall function now asks the corresponding nut wall function
for yPlus, rather than calculating it itself from the turbulent kinetic
energy. This simplifies the implementation and should improve
consistency between the near-wall modelling of the heat and momentum
transfers.
The heat-flux dependent terms in this boundary condition have also been
removed. The origin of these terms is unclear, and their value increases
without limit as the thermal boundary condition tends towards the case
of an adiabatic wall. These terms, or something eqivalent, could be
reinstated in a separate boundary condition if a clear reference was
provided and a case found for which tangible benefit could be
demonstrated.
Zones are now completely dynamic, i.e. the number of zones of each type can
change during the run, e.g. by run-time mesh-to-mesh mapping onto meshes with
different zones used to control mesh motion. This means that the index of each
zone may change during the run and so it better that the zones do not cache
their own index but it is looked-up from the zone list using findIndex when
required.
A new nonConformalMappedWall patch type has been added which can couple
between different regions of a multi-region simulation. This patch type
uses the same intersection algorithm as the nonConformalCyclic patch,
which is used for coupling sections of a mesh within the same region.
The nonConformalMappedWall provides some advantages over the existing
mappedWall patches:
- The connection it creates is not interpolative. It creates a pair of
coupled finite-volume faces wherever two opposing faces overlap.
There is therefore no interpolation error associated with mapping
values across the coupling.
- Faces (or parts of faces) which do not overlap are not normalised
away by an interpolation or averaging process. Instead, they are
assigned an alternative boundary condition; e.g., an external
constraint, or even another non-conformal cyclic or mapped wall.
This makes the system able to construct partially-overlapping
couplings.
- The direct non-interpolative transfer of values between the patches
makes the method equivalent to a conformal coupling. Properties of
the solution algorithm, such as conservation and boundedness, are
retained regardless of the non-conformance of the boundary meshes.
- All constructed finite volume faces have accurate centre points.
This makes the method second order accurate in space.
Usage:
Non-conformal mapped wall couplings are constructed as the last stage of
a multi-region meshing process. First, a multi-region mesh is
constructed in one of the usual ways, but with the boundaries specified
as standard non-coupled walls instead of a special mapped type. Then,
createNonConformalCouples is called to construct non-conformal mapped
patches that couple overlapping parts of these non-coupled walls. This
process is very similar to the construction of non-conformal cyclics.
createNonConformalCouples requires a
system/createNonConformalCouplesDict in order to construct non-conformal
mapped walls. Each coupling is specified in its own sub-dictionary, and
a "regions" entry is used to specify the pair of regions that the
non-conformal mapped wall will couple. Non-conformal cyclics can also be
created using the same dictionary, and will be assumed if the two
specified regions are the same, or if a single "region" entry is
specified. For example:
// Do not modify the fields
fields no;
// List of non-conformal couplings
nonConformalCouples
{
// Non-conformal cyclic interface. Only one region is specified.
fluidFluid
{
region fluid;
originalPatches (nonCoupleRotating nonCoupleStationary);
}
// Non-conformal mapped wall interface. Two different regions
// have been specified.
fluidSolid
{
regions (fluid solid);
originalPatches (nonCoupleRotating nonCoupleStationary);
}
}
After this step, a case should execute with foamMultiRun and decompose
and reconstruct and post-process normally.
One additional restriction for parallelised workflows is that
decomposition and reconstruction must be done with the -allRegions
option, so that the both sides of the coupling are available to the
decomposition/reconstruction algorithm.
Tutorials:
Two tutorials have been added to demonstrate use of this new
functionality:
- The multiRegion/CHT/misalignedDuct case provides a simple visual
confirmation that the patches are working (the exposed corners of
the solid will be hot if the non-conformal mapped walls are active),
and it demonstrates createNonConformalCouples's ability to add
boundary conditions to existing fields.
- The multiRegion/CHT/notchedRoller case demonstrates use of
non-conformal mapped walls with a moving mesh, and also provides an
example of parallelised usage.
Notes for Developers:
A coupled boundary condition now uses a new class,
mappedFvPatchBaseBase, in order to perform a transfer of values to or
from the neighbouring patch. For example:
// Cast the patch type to it's underlying mapping engine
const mappedFvPatchBaseBase& mapper =
mappedFvPatchBaseBase::getMap(patch());
// Lookup a field on the neighbouring patch
const fvPatchScalarField& nbrTn =
mapper.nbrFvPatch().lookupPatchField<volScalarField, scalar>("T");
// Map the values to this patch
const scalarField Tn(mapper.fromNeighbour(nbrTn));
For this to work, the fvPatch should be of an appropriate mapped type
which derives from mappedFvPatchBaseBase. This mappedFvPatchBaseBase
class provides an interface to to both conformal/interpolative and
non-conformal mapping procedures. This means that a coupled boundary
condition implemented in the manner above will work with either
conformal/interpolative or non-conformal mapped patch types.
Previously, coupled boundary conditions would access a mappedPatchBase
base class of the associated polyPatch, and use that to transfer values
between the patches. This direct dependence on the polyPatch's mapping
engine meant that only conformal/interpolative fvPatch fields that
corresponded to the polyPatch's geometry could be mapped.
This boundary condition provides a no-slip velocity condition for mapped
walls. The wall velocity is taken to be the mesh velocity of the
neighbouring region.
This will typically be used in CHT simulations in order to apply the
mesh motion of a solid region to the boundary of the adjacent fluid
region.
Example of the boundary condition specification:
<patchName>
{
type movingMappedWallVelocity;
value uniform (0 0 0); // Initial value
}
This provides finer control as to when the changes get constructed and
initial stitching is performed. These is needed by certain processes,
notably decomposition and reconstruction.
By default, the mesh still performs all these operations on a "normal"
read-construction. A flag has to be passed explicitly to the constructor
in order to prevent the post-construction steps.
A number of boundary conditions' mapping constructors and methods have
been modified so as to specify what value gets applied to a new or
unmapped face. This allows them to be maintained throughout mesh changes
in which faces are created without reference to a parent or master face.
For example, the coupled temperature condition now creates values
representative of an adiabatic wall on new faces. If the faces didn't
exist prior to mapping, then there was previously no heat flux at these
locations, so an adiabatic constraint is a sensible initialisation.