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.
182 lines
4.9 KiB
C++
182 lines
4.9 KiB
C++
/*--------------------------------*- C++ -*----------------------------------*\
|
|
========= |
|
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
\\ / O peration | Website: https://openfoam.org
|
|
\\ / A nd | Version: dev
|
|
\\/ M anipulation |
|
|
\*---------------------------------------------------------------------------*/
|
|
FoamFile
|
|
{
|
|
format ascii;
|
|
class dictionary;
|
|
location "system";
|
|
object blockMeshDict;
|
|
}
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
|
|
convertToMeters 0.01;
|
|
|
|
R 6;
|
|
RbyRoot2 #calc "$<scalar>{R}/sqrt(scalar(2))";
|
|
C 2.1;
|
|
CbyRoot2 #calc "$<scalar>{C}/sqrt(scalar(2))";
|
|
|
|
vertices
|
|
(
|
|
(-50 -10 -1) (-10 -10 -1) (10 -10 -1) (50 -10 -1)
|
|
(-50 0 -1) (-10 0 -1) (10 0 -1) (50 0 -1)
|
|
(-50 10 -1) (-10 10 -1) (10 10 -1) (50 10 -1)
|
|
(-50 40 -1) (-10 40 -1) (10 40 -1) (50 40 -1)
|
|
|
|
(#neg $R 0 -1)
|
|
(#neg $RbyRoot2 #neg $RbyRoot2 -1)
|
|
($RbyRoot2 #neg $RbyRoot2 -1)
|
|
($R 0 -1)
|
|
($RbyRoot2 $RbyRoot2 -1)
|
|
(#neg $RbyRoot2 $RbyRoot2 -1)
|
|
|
|
(#neg $C 0 -1)
|
|
(#neg $CbyRoot2 #neg $CbyRoot2 -1)
|
|
($CbyRoot2 #neg $CbyRoot2 -1)
|
|
($CbyRoot2 0 -1)
|
|
($CbyRoot2 $CbyRoot2 -1)
|
|
(#neg $CbyRoot2 $CbyRoot2 -1)
|
|
|
|
|
|
(-50 -10 1) (-10 -10 1) (10 -10 1) (50 -10 1)
|
|
(-50 0 1) (-10 0 1) (10 0 1) (50 0 1)
|
|
(-50 10 1) (-10 10 1) (10 10 1) (50 10 1)
|
|
(-50 40 1) (-10 40 1) (10 40 1) (50 40 1)
|
|
|
|
(#neg $R 0 1)
|
|
(#neg $RbyRoot2 #neg $RbyRoot2 1)
|
|
($RbyRoot2 #neg $RbyRoot2 1)
|
|
($R 0 1)
|
|
($RbyRoot2 $RbyRoot2 1)
|
|
(#neg $RbyRoot2 $RbyRoot2 1)
|
|
|
|
(#neg $C 0 1)
|
|
(#neg $CbyRoot2 #neg $CbyRoot2 1)
|
|
($CbyRoot2 #neg $CbyRoot2 1)
|
|
($CbyRoot2 0 1)
|
|
($CbyRoot2 $CbyRoot2 1)
|
|
(#neg $CbyRoot2 $CbyRoot2 1)
|
|
);
|
|
|
|
nCore 16;
|
|
nCoreBy2 #calc "$<label>{nCore}/2";
|
|
nRStatic 8;
|
|
nRRotating 12;
|
|
nAcross 26;
|
|
nAlong 30;
|
|
|
|
gStatic 0.7;
|
|
|
|
blocks
|
|
(
|
|
hex ( 0 1 5 4 28 29 33 32) solid ($nAlong $nCoreBy2 1) simpleGrading (1 1 1)
|
|
hex ( 4 5 9 8 32 33 37 36) fluid ($nAlong $nCoreBy2 1) simpleGrading (1 1 1)
|
|
hex ( 8 9 13 12 36 37 41 40) fluid ($nAlong $nAcross 1) simpleGrading (1 1 1)
|
|
|
|
hex ( 9 10 14 13 37 38 42 41) fluid ($nCore $nAcross 1) simpleGrading (1 1 1)
|
|
|
|
hex ( 2 3 7 6 30 31 35 34) solid ($nAlong $nCoreBy2 1) simpleGrading (1 1 1)
|
|
hex ( 6 7 11 10 34 35 39 38) fluid ($nAlong $nCoreBy2 1) simpleGrading (1 1 1)
|
|
hex (10 11 15 14 38 39 43 42) fluid ($nAlong $nAcross 1) simpleGrading (1 1 1)
|
|
|
|
hex ( 5 1 17 16 33 29 45 44) solid ($nCoreBy2 $nRStatic 1) simpleGrading (1 $gStatic 1)
|
|
hex ( 1 2 18 17 29 30 46 45) solid ($nCore $nRStatic 1) simpleGrading (1 $gStatic 1)
|
|
hex ( 2 6 19 18 30 34 47 46) solid ($nCoreBy2 $nRStatic 1) simpleGrading (1 $gStatic 1)
|
|
hex ( 6 10 20 19 34 38 48 47) fluid ($nCoreBy2 $nRStatic 1) simpleGrading (1 $gStatic 1)
|
|
hex (10 9 21 20 38 37 49 48) fluid ($nCore $nRStatic 1) simpleGrading (1 $gStatic 1)
|
|
hex ( 9 5 16 21 37 33 44 49) fluid ($nCoreBy2 $nRStatic 1) simpleGrading (1 $gStatic 1)
|
|
|
|
hex (16 17 23 22 44 45 51 50) fluid ($nCoreBy2 $nRRotating 1) simpleGrading (1 1 1)
|
|
hex (17 18 24 23 45 46 52 51) roller ($nCore $nRRotating 1) simpleGrading (1 1 1)
|
|
hex (18 19 25 24 46 47 53 52) roller ($nCoreBy2 $nRRotating 1) simpleGrading (1 1 1)
|
|
hex (19 20 26 25 47 48 54 53) roller ($nCoreBy2 $nRRotating 1) simpleGrading (1 1 1)
|
|
hex (20 21 27 26 48 49 55 54) roller ($nCore $nRRotating 1) simpleGrading (1 1 1)
|
|
hex (21 16 22 27 49 44 50 55) fluid ($nCoreBy2 $nRRotating 1) simpleGrading (1 1 1)
|
|
|
|
hex (22 23 24 25 50 51 52 53) roller ($nCoreBy2 $nCore 1) simpleGrading (1 1 1)
|
|
hex (25 26 27 22 53 54 55 50) roller ($nCoreBy2 $nCore 1) simpleGrading (1 1 1)
|
|
);
|
|
|
|
edges
|
|
(
|
|
arc 16 17 45 (0 0 1)
|
|
arc 17 18 90 (0 0 1)
|
|
arc 18 19 45 (0 0 1)
|
|
arc 19 20 45 (0 0 1)
|
|
arc 20 21 90 (0 0 1)
|
|
arc 21 16 45 (0 0 1)
|
|
|
|
arc 44 45 45 (0 0 1)
|
|
arc 45 46 90 (0 0 1)
|
|
arc 46 47 45 (0 0 1)
|
|
arc 47 48 45 (0 0 1)
|
|
arc 48 49 90 (0 0 1)
|
|
arc 49 44 45 (0 0 1)
|
|
|
|
arc 22 23 45 (0 0 1)
|
|
arc 27 22 45 (0 0 1)
|
|
|
|
arc 50 51 45 (0 0 1)
|
|
arc 55 50 45 (0 0 1)
|
|
);
|
|
|
|
defaultPatch
|
|
{
|
|
name frontAndBack;
|
|
type empty;
|
|
}
|
|
|
|
boundary
|
|
(
|
|
atmosphere
|
|
{
|
|
type patch;
|
|
faces
|
|
(
|
|
(12 13 41 40)
|
|
(13 14 42 41)
|
|
(14 15 43 42)
|
|
);
|
|
}
|
|
|
|
inlet
|
|
{
|
|
type patch;
|
|
faces
|
|
(
|
|
(4 8 36 32)
|
|
(8 12 40 36)
|
|
);
|
|
}
|
|
|
|
outlet
|
|
{
|
|
type patch;
|
|
faces
|
|
(
|
|
(7 11 39 35)
|
|
(11 15 43 39)
|
|
);
|
|
}
|
|
|
|
external
|
|
{
|
|
type patch;
|
|
faces
|
|
(
|
|
(0 4 32 28)
|
|
(0 1 29 28)
|
|
(1 2 30 29)
|
|
(2 3 31 30)
|
|
(3 7 35 31)
|
|
);
|
|
}
|
|
);
|
|
|
|
// ************************************************************************* //
|