cyclicRepeatAMI: New constraint patch type

A new constraint patch has been added which permits AMI coupling in
cyclic geometries. The coupling is repeated with different multiples of
the cyclic transformation in order to achieve a full correspondence.
This allows, for example, a cylindrical AMI interface to be used in a
sector of a rotational geometry.

The patch is used in a similar manner to cyclicAMI, except that it has
an additional entry, "transformPatch". This entry must name a coupled
patch. The transformation used to repeat the AMI coupling is taken from
this patch. For example, in system/blockMeshDict:

boundary
(
    cyclic1
    {
        type cyclic;
        neighbourPatch cyclic2;
        faces ( ... );
    }

    cyclic2
    {
        type cyclic;
        neighbourPatch cyclic1;
        faces ( ... );
    }

    cyclicRepeatAMI1
    {
        type cyclicRepeatAMI;
        neighbourPatch cyclicRepeatAM2;
        transformPatch cyclic1;
        faces ( ... );
    }

    cyclicRepeatAMI2
    {
        type cyclicRepeatAMI;
        neighbourPatch cyclicRepeatAMI1;
        transformPatch cyclic1;
        faces ( ... );
    }

    // other patches ...
);

In this example, the transformation between cyclic1 and cyclic2 is used
to define the repetition used by the two cyclicRepeatAMI patches.
Whether cyclic1 or cyclic2 is listed as the transform patch is not
important.

A tutorial, incompressible/pimpleFoam/RAS/impeller, has been added to
demonstrate the functionality. This contains two repeating AMI pairs;
one cylindrical and one planar.

A significant amount of maintenance has been carried out on the AMI and
ACMI patches as part of this work. The AMI methods now return
dimensionless weights by default, which prevents ambiguity over the
units of the weight field during construction. Large amounts of
duplicate code have also been removed by deriving ACMI classes from
their AMI equivalents. The reporting and writing of AMI weights has also
been unified.

This work was supported by Dr Victoria Suponitsky, at General Fusion
This commit is contained in:
Will Bainbridge
2018-04-09 14:39:42 +01:00
parent c1b380c867
commit 785a7d9e3f
88 changed files with 4017 additions and 1544 deletions

View File

@ -479,6 +479,103 @@ bool Foam::checkCoupledPoints
}
void Foam::writeAMIWeightsSum
(
const polyMesh& mesh,
const primitivePatch& patch,
const scalarField& wghtSum,
const fileName& file
)
{
// Collect geometry
labelList pointToGlobal;
labelList uniqueMeshPointLabels;
autoPtr<globalIndex> globalPoints;
autoPtr<globalIndex> globalFaces;
faceList mergedFaces;
pointField mergedPoints;
Foam::PatchTools::gatherAndMerge
(
mesh,
patch.localFaces(),
patch.meshPoints(),
patch.meshPointMap(),
pointToGlobal,
uniqueMeshPointLabels,
globalPoints,
globalFaces,
mergedFaces,
mergedPoints
);
// Collect field
scalarField mergedWeights;
globalFaces().gather
(
UPstream::worldComm,
labelList(UPstream::procID(UPstream::worldComm)),
wghtSum,
mergedWeights
);
// Write the surface
if (Pstream::master())
{
vtkSurfaceWriter().write
(
file.path(),
file.name(),
mergedPoints,
mergedFaces,
"weightsSum",
mergedWeights,
false
);
}
}
void Foam::writeAMIWeightsSums(const polyMesh& mesh)
{
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
const word tmName(mesh.time().timeName());
forAll(pbm, patchi)
{
if (isA<cyclicAMIPolyPatch>(pbm[patchi]))
{
const cyclicAMIPolyPatch& cpp =
refCast<const cyclicAMIPolyPatch>(pbm[patchi]);
if (cpp.owner())
{
Info<< "Calculating AMI weights between owner patch: "
<< cpp.name() << " and neighbour patch: "
<< cpp.neighbPatch().name() << endl;
writeAMIWeightsSum
(
mesh,
cpp,
cpp.weightsSum(),
fileName("postProcessing") / "src_" + tmName
);
writeAMIWeightsSum
(
mesh,
cpp.neighbPatch(),
cpp.neighbWeightsSum(),
fileName("postProcessing") / "tgt_" + tmName
);
}
}
}
}
Foam::label Foam::checkGeometry
(
const polyMesh& mesh,
@ -945,136 +1042,7 @@ Foam::label Foam::checkGeometry
if (allGeometry)
{
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
const word tmName(mesh.time().timeName());
const word procAndTime(Foam::name(Pstream::myProcNo()) + "_" + tmName);
autoPtr<surfaceWriter> patchWriter;
if (!surfWriter.valid())
{
patchWriter.reset(new vtkSurfaceWriter());
}
const surfaceWriter& wr =
(
surfWriter.valid()
? surfWriter()
: patchWriter()
);
forAll(pbm, patchi)
{
if (isA<cyclicAMIPolyPatch>(pbm[patchi]))
{
const cyclicAMIPolyPatch& cpp =
refCast<const cyclicAMIPolyPatch>(pbm[patchi]);
if (cpp.owner())
{
Info<< "Calculating AMI weights between owner patch: "
<< cpp.name() << " and neighbour patch: "
<< cpp.neighbPatch().name() << endl;
const AMIPatchToPatchInterpolation& ami =
cpp.AMI();
{
// Collect geometry
labelList pointToGlobal;
labelList uniqueMeshPointLabels;
autoPtr<globalIndex> globalPoints;
autoPtr<globalIndex> globalFaces;
faceList mergedFaces;
pointField mergedPoints;
Foam::PatchTools::gatherAndMerge
(
mesh,
cpp.localFaces(),
cpp.meshPoints(),
cpp.meshPointMap(),
pointToGlobal,
uniqueMeshPointLabels,
globalPoints,
globalFaces,
mergedFaces,
mergedPoints
);
// Collect field
scalarField mergedWeights;
globalFaces().gather
(
UPstream::worldComm,
labelList(UPstream::procID(UPstream::worldComm)),
ami.srcWeightsSum(),
mergedWeights
);
if (Pstream::master())
{
wr.write
(
"postProcessing",
"src_" + tmName,
mergedPoints,
mergedFaces,
"weightsSum",
mergedWeights,
false
);
}
}
{
// Collect geometry
labelList pointToGlobal;
labelList uniqueMeshPointLabels;
autoPtr<globalIndex> globalPoints;
autoPtr<globalIndex> globalFaces;
faceList mergedFaces;
pointField mergedPoints;
Foam::PatchTools::gatherAndMerge
(
mesh,
cpp.neighbPatch().localFaces(),
cpp.neighbPatch().meshPoints(),
cpp.neighbPatch().meshPointMap(),
pointToGlobal,
uniqueMeshPointLabels,
globalPoints,
globalFaces,
mergedFaces,
mergedPoints
);
// Collect field
scalarField mergedWeights;
globalFaces().gather
(
UPstream::worldComm,
labelList(UPstream::procID(UPstream::worldComm)),
ami.tgtWeightsSum(),
mergedWeights
);
if (Pstream::master())
{
wr.write
(
"postProcessing",
"tgt_" + tmName,
mergedPoints,
mergedFaces,
"weightsSum",
mergedWeights,
false
);
}
}
}
}
}
writeAMIWeightsSums(mesh);
}
return noFailedChecks;

View File

@ -23,6 +23,18 @@ namespace Foam
//- Check 0th vertex on coupled faces
bool checkCoupledPoints(const polyMesh&, const bool report, labelHashSet*);
//- Write out the weights-sums on all the AMI patches
void writeAMIWeightsSums(const polyMesh&);
//- Write out the weights-sum on the given AMI patch
void writeAMIWeightsSum
(
const polyMesh&,
const primitivePatch&,
const scalarField&,
const fileName&
);
label checkGeometry
(
const polyMesh& mesh,

View File

@ -1,3 +1,5 @@
moveDynamicMesh.C
../checkMesh/checkGeometry.C
../checkMesh/checkTools.C
EXE = $(FOAM_APPBIN)/moveDynamicMesh

View File

@ -1,8 +1,10 @@
EXE_INC = \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I../checkMesh
EXE_LIBS = \
-ldynamicFvMesh \

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -36,119 +36,12 @@ Description
#include "vtkSurfaceWriter.H"
#include "cyclicAMIPolyPatch.H"
#include "PatchTools.H"
#include "checkGeometry.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Dump patch + weights to vtk file
void writeWeights
(
const polyMesh& mesh,
const scalarField& wghtSum,
const primitivePatch& patch,
const fileName& directory,
const fileName& prefix,
const word& timeName
)
{
vtkSurfaceWriter writer;
// Collect geometry
labelList pointToGlobal;
labelList uniqueMeshPointLabels;
autoPtr<globalIndex> globalPoints;
autoPtr<globalIndex> globalFaces;
faceList mergedFaces;
pointField mergedPoints;
Foam::PatchTools::gatherAndMerge
(
mesh,
patch.localFaces(),
patch.meshPoints(),
patch.meshPointMap(),
pointToGlobal,
uniqueMeshPointLabels,
globalPoints,
globalFaces,
mergedFaces,
mergedPoints
);
// Collect field
scalarField mergedWeights;
globalFaces().gather
(
UPstream::worldComm,
labelList(UPstream::procID(UPstream::worldComm)),
wghtSum,
mergedWeights
);
if (Pstream::master())
{
writer.write
(
directory,
prefix + "_" + timeName,
mergedPoints,
mergedFaces,
"weightsSum",
mergedWeights,
false
);
}
}
void writeWeights(const polyMesh& mesh)
{
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
const word tmName(mesh.time().timeName());
forAll(pbm, patchi)
{
if (isA<cyclicAMIPolyPatch>(pbm[patchi]))
{
const cyclicAMIPolyPatch& cpp =
refCast<const cyclicAMIPolyPatch>(pbm[patchi]);
if (cpp.owner())
{
Info<< "Calculating AMI weights between owner patch: "
<< cpp.name() << " and neighbour patch: "
<< cpp.neighbPatch().name() << endl;
const AMIPatchToPatchInterpolation& ami =
cpp.AMI();
writeWeights
(
mesh,
ami.tgtWeightsSum(),
cpp.neighbPatch(),
"postProcessing",
"tgt",
tmName
);
writeWeights
(
mesh,
ami.srcWeightsSum(),
cpp,
"postProcessing",
"src",
tmName
);
}
}
}
}
int main(int argc, char *argv[])
{
#include "addRegionOption.H"
@ -192,7 +85,7 @@ int main(int argc, char *argv[])
if (checkAMI)
{
writeWeights(mesh);
writeAMIWeightsSums(mesh);
}
runTime.write();