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.