Now faceZones are handled directly by the applications and the new
faceZone::topoChange function so that any face can now be in any number of
zones, significantly increasing the flexibility and usefulness of faceZones.
This completes the generalisation of cellZone, faceZone and pointZone to support
multiple zones for each cell, face or point respectively. Next step will be to
make zones polymorphic and run-time selectable so that they can alter during the
run and adapt to moving meshes for example.
Now cellZones are handled directly by the applications and the new
cellZone::topoChange function so that any cell can now be in any number of
zones, significantly increasing the flexibility and usefulness of cellZones.
The same rationalisation and generalisation will be applied to faceZones in the
future.
Now pointZones are handled directly by the applications and the new
pointZone::topoChange function so that any point can now be in any number of
zones, significantly increasing the flexibility and usefulness of pointZones.
The same rationalisation and generalisation will be applied to cellZones and
faceZones in the future.
This utility is superseded by the much more general transformPoints. A
rotation between vectors (0 1 0) and (0.707107 0.707107 0), and a
corresponding transformation of all vector and tensor fields, can be
achieved with the following call to transformPoints:
transformPoints "rotate=((0 1 0) (0.707107 0.707107 0))" -rotateFields
The concept of cell and face inflation proved unworkable in general and has been
replaced by the more flexible and robust cell-splitting combined with
conservative interpolative mapping and mesh morphing as appropriate.
The concept of cell inflation from faces or points proved unworkable in general
and has been replaced by the more flexible and robust cell-splitting combined
with conservative interpolative mapping and mesh morphing as appropriate.
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.
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.
to set the time and other case controls. This is possible and reliable now that
the functionObject specifications are in a separate functions file which is not
read.
Description
Merges meshes without stitching.
Usage
\b mergeMeshes [OPTION]
Options:
- \par -doc
Display the documentation in browser
- \par -srcDoc
Display the source documentation in browser
- \par -help
Print the usage
- \par -case \<dir\>
Select a case directory instead of the current working directory
- \par -region \<name\>
Specify an alternative mesh region.
- \par -addRegions "'(region1 region2 ... regionN)'"
Specify list of region meshes to merge.
- \par -addCases "'(\"casePath1\" \"casePath2\" ... \"casePathN\")'"
Specify list of case meshes to merge.
- \par -addCaseRegions "'((\"casePath1\" region1) (\"casePath2\" region2)"
Specify list of case region meshes to merge.
The mergePatchPairs functionality in blockMesh also now uses patchIntersection.
The new mergePatchPairs and patchIntersection replaces the old, fragile and
practically unusable polyTopoChanger::slidingInterface functionality the removal
of which has allowed the deletion of a lot of other ancient and otherwise unused
clutter including polyTopoChanger, polyMeshModifier, polyTopoChange::setAction
and associated addObject/*, modifyObject/* and removeObject/*. This
rationalisation paves the way for the completion of the update of zone handling
allowing mesh points, faces and cells to exist in multiple zones which is
currently not supported with mesh topology change.
Application
stitchMesh
Description
Utility to stitch or conform pairs of patches,
converting the patch faces either into internal faces
or conformal faces or another patch.
Usage
\b stitchMesh (\<list of patch pairs\>)
E.g. to stitch patches \c top1 to \c top2 and \c bottom1 to \c bottom2
stitchMesh "((top1 top2) (bottom1 bottom2))"
Options:
- \par -overwrite \n
Replace the old mesh with the new one, rather than writing the new one
into a separate time directory
- \par -region \<name\>
Specify an alternative mesh region.
- \par -fields
Update vol and point fields
- \par -tol
Merge tolerance relative to local edge length (default 1e-4)
See also
Foam::mergePatchPairs
The legacy fvMeshTopoChangersMovingCone removed, replaced by the more general
mesh mapping approach, see tutorials incompressibleFluid/movingCone and
shockFluid/movingCone.
A number of fixes have been made in order to make non-conformal cyclic
patches compatible with run-time distribution.
A tutorial case, incompressibleVoF/rotatingCube, has been added which
demonstrates simultaneous usage of motion, non-conformal couplings,
adaptive refinement and load-balancing.
Now both the checkMesh utility and functionObject operate in the same manner
with the same controls, executing the same checkGeometry and checkTopology
functions from the new meshCheck library. The controls have been updated and
made more consistent and flexible, in particular by the addition of optional
user specification for the non-orthogonality and skewness error thresholds:
Application
checkMesh
Description
Checks validity of a mesh.
Usage
\b checkMesh [OPTION]
Options:
- \par noTopology
Skip checking the mesh topology
- \par -allTopology
Check all (including non finite-volume specific) addressing
- \par -allGeometry
Check all (including non finite-volume specific) geometry
- \par -meshQuality
Check against user defined (in \a system/meshQualityDict) quality
settings
- \par -region \<name\>
Specify an alternative mesh region.
- \par -writeSurfaces
Reconstruct cellSets and faceSets of problem faces and write to
postProcessing directory.
- \par -surfaceFormat <format>
Format used to write the cellSets and faceSets surfaces
e.g. vtk or ensight.
- \par -writeSets
Reconstruct pointSets of problem points nd write to
postProcessing directory.
- \par -setFormat <format>
Format used to write the pointSets
e.g. vtk or ensight.
- \par -nonOrthThreshold <threshold value in degrees>
Threshold in degrees for reporting non-orthogonality errors,
default: 70"
- \par -skewThreshold <threshold value>
Threshold for reporting skewness errors, default: 4.
Class
Foam::functionObjects::checkMesh
Description
Executes primitiveMesh::checkMesh(true) every execute time for which the
mesh changed, i.e. moved or changed topology.
Useful to check the correctness of changing and morphing meshes.
Usage
\table
Property | Description | Required | Default value
type | type name: checkMesh | yes |
noTopology | Skip checking the mesh topology | no | false
allTopology | Check all addressing | no | false
allGeometry | Check all geometry | no | false
writeSurfaces | Reconstruct and write problem faces | no | false
surfaceFormat | Format for problem faceSets | no | vtk
writeSets | Reconstruct and write problem points | no | false
setFormat | Format used to write the problem pointSets | no | vtk
nonOrthThreshold | Threshold for non-orthogonality errors | no | 70 deg
skewThreshold | Threshold for reporting skewness errors | no | 4
\endtable
Example of checkMesh specification:
\verbatim
checkMesh
{
type checkMesh;
libs ("libutilityFunctionObjects.so");
executeControl timeStep;
executeInterval 10;
allGeometry true;
allTopology true;
writeSurfaces true;
surfaceFormat vtk;
writeSets true;
setFormat vtk;
}
\endverbatim
or using the standard configuration file:
\verbatim
#includeFunc checkMesh(executeInterval=10, allGeometry=true)
\endverbatim
This avoids potential hidden run-time errors caused by solvers running with
boundary conditions which are not fully specified. Note that "null-constructor"
here means the constructor from patch and internal field only, no data is
provided.
Constraint and simple BCs such as 'calculated', 'zeroGradient' and others which
do not require user input to fully specify their operation remain on the
null-constructor table for the construction of fields with for example all
'calculated' or all 'zeroGradient' BCs.
A special version of the 'inletOutlet' fvPatchField named 'zeroInletOutlet' has
been added in which the inlet value is hard-coded to zero which allows this BC
to be included on the null-constructor table. This is useful for the 'age'
functionObject to avoid the need to provide the 'age' volScalarField at time 0
unless special inlet or outlet BCs are required. Also for isothermalFilm in
which the 'alpha' field is created automatically from the 'delta' field if it is
not present and can inherit 'zeroInletOutlet' from 'delta' if appropriate. If a
specific 'inletValue' is require or other more complex BCs then the 'alpha'
field file must be provided to specify these BCs as before.
Following this improvement it will now be possible to remove the
null-constructors from all fvPatchFields not added to the null-constructor
table, which is most of them, thus reducing the amount of code and maintenance
overhead and making easier and more obvious to write new fvPatchField types.
genericPatches is linked into mesh generation and manipulation utilities but not
solvers so that the solvers now check for the availability of the specified
patch types. Bugs in the tutorials exposed by this check have been corrected.