mappedExtrudedPatchBase: Support patchToPatch coupling

This completes commit 381e0921 and permits patches on the "top" of
extruded regions to determine the point locations opposite as well as
the face centres and areas. This means that patches with dissimilar
meshes can now be coupled via the patchToPatch interpolation engine.

A few fixes have also been applied to extrudeToRegionMesh to make the
intrude option compatibile with extrusion into internal faces and
between opposing zones/sets/patches. The 'shadow' entries used for
extrusion inbetween opposing zones/sets/patches have also been renamed
to 'opposite' for consistency with the patch names and patch types
entries; e.g.,

    faceZones           (fz1 fz3);
    oppositeFaceZones   (fz2 fz4); // <-- was 'faceZonesShadow'

    faceSets            (fs1 fs3);
    oppositeFaceSets    (fs2 fs4); // <-- was 'faceSetsShadow'

    patches             (p1 p3);
    oppositePatches     (p2 p4); // <-- was 'patchesShadow'
This commit is contained in:
Will Bainbridge
2023-05-05 11:30:21 +01:00
parent e5aa8ab63c
commit 74a63a08e4
23 changed files with 1349 additions and 550 deletions

View File

@ -74,7 +74,7 @@ Foam::mappedFilmSurfacePolyPatch::mappedFilmSurfacePolyPatch
const label index,
const word& neighbourRegion,
const word& neighbourPatch,
const word& bottomPatch,
const bool isExtrudedRegion,
const polyBoundaryMesh& bm
)
:
@ -84,7 +84,7 @@ Foam::mappedFilmSurfacePolyPatch::mappedFilmSurfacePolyPatch
*this,
neighbourRegion,
neighbourPatch,
bottomPatch,
isExtrudedRegion,
cyclicTransform(true)
)
{}

View File

@ -98,7 +98,7 @@ public:
const label index,
const word& neighbourRegion,
const word& neighbourPatch,
const word& bottomPatch,
const bool isExtrudedRegion,
const polyBoundaryMesh& bm
);

View File

@ -540,7 +540,7 @@ void addCouplingPatches
const word& regionName,
const word& nbrRegionName,
const wordList& zoneNames,
const wordList& zoneShadowNames,
const wordList& oppositeZoneNames,
const boolList& zoneIsInternal,
const dictionary& dict,
DynamicList<polyPatch*>& newPatches,
@ -557,12 +557,10 @@ void addCouplingPatches
(
dict.lookupOrDefault("patchNames", wordList())
);
wordList regionPatchNames
(
dict.lookupOrDefault("regionPatchNames", wordList())
);
if (isShellMesh)
{
patchNames.swap(regionPatchNames);
@ -571,28 +569,29 @@ void addCouplingPatches
const wordList patchTypes
(
isShellMesh
? dict.lookupOrDefault
(
"regionPatchTypes",
wordList(zoneNames.size(), mappedWallPolyPatch::typeName)
)
: dict.lookupOrDefault
(
"patchTypes",
wordList(zoneNames.size(), mappedWallPolyPatch::typeName)
)
? dict.lookupOrDefault("regionPatchTypes", wordList())
: dict.lookupOrDefault("patchTypes", wordList())
);
const wordList regionOppositePatchTypes
wordList oppositePatchNames
(
dict.lookupOrDefault("regionOppositePatchTypes", wordList())
dict.lookupOrDefault("oppositePatchNames", wordList())
);
const wordList regionOppositePatchNames
wordList regionOppositePatchNames
(
dict.lookupOrDefault("regionOppositePatchNames", wordList())
);
if (isShellMesh)
{
oppositePatchNames.swap(regionOppositePatchNames);
}
const wordList oppositePatchTypes
(
isShellMesh
? dict.lookupOrDefault("regionOppositePatchTypes", wordList())
: dict.lookupOrDefault("oppositePatchType", wordList())
);
zoneTopPatch.setSize(zoneNames.size(), -1);
zoneBottomPatch.setSize(zoneNames.size(), -1);
@ -616,58 +615,80 @@ void addCouplingPatches
if (zoneIsInternal[zonei])
{
bottomPatchName = patchNamePrefix + zoneNames[zonei] + "_bottom";
bottomPatchName =
patchNamePrefix + zoneNames[zonei] + "_bottom";
bottomNbrPatchName =
nbrPatchNamePrefix + zoneNames[zonei] + "_bottom";
topPatchName = patchNamePrefix + zoneNames[zonei] + "_top";
topNbrPatchName = nbrPatchNamePrefix + zoneNames[zonei] + "_top";
topPatchName =
patchNamePrefix + zoneNames[zonei] + "_top";
topNbrPatchName =
nbrPatchNamePrefix + zoneNames[zonei] + "_top";
}
else if (!zoneShadowNames[zonei].empty())
else if (!oppositeZoneNames[zonei].empty())
{
bottomPatchName = patchNamePrefix + zoneNames[zonei];
bottomNbrPatchName = nbrPatchNamePrefix + zoneNames[zonei];
topPatchName = patchNamePrefix + zoneShadowNames[zonei];
topNbrPatchName = nbrPatchNamePrefix + zoneShadowNames[zonei];
topPatchName = patchNamePrefix + oppositeZoneNames[zonei];
topNbrPatchName = nbrPatchNamePrefix + oppositeZoneNames[zonei];
}
else
{
if (patchNames.size())
{
bottomPatchName = patchNames[zonei];
}
else
{
bottomPatchName = patchNamePrefix + zoneNames[zonei];
}
if (regionPatchNames.size())
{
bottomNbrPatchName = regionPatchNames[zonei];
}
else
{
bottomNbrPatchName = nbrPatchNamePrefix + zoneNames[zonei];
}
topPatchName =
regionOppositePatchNames.size()
? regionOppositePatchNames[zonei]
: word(zoneNames[zonei] + "_top");
bottomPatchName = patchNamePrefix + zoneNames[zonei];
bottomNbrPatchName = nbrPatchNamePrefix + zoneNames[zonei];
topPatchName = zoneNames[zonei] + "_top";
topNbrPatchName = word::null;
}
dictionary bottomPatchDict;
if (patchNames.size())
{
bottomPatchName = patchNames[zonei];
}
if (regionPatchNames.size())
{
bottomNbrPatchName = regionPatchNames[zonei];
}
if (oppositePatchNames.size())
{
topPatchName = oppositePatchNames[zonei];
}
if (regionOppositePatchNames.size())
{
topNbrPatchName = regionOppositePatchNames[zonei];
}
if (!intrude)
const bool bothMapped =
zoneIsInternal[zonei] || !oppositeZoneNames[zonei].empty();
const bool bottomMapped = bothMapped || !(intrude && isShellMesh);
const bool topMapped = bothMapped || intrude;
const bool bottomExtruded = !isShellMesh && intrude;
const bool topExtruded = !bottomExtruded;
dictionary bottomPatchDict;
if (bottomMapped)
{
bottomPatchDict = patchDict;
bottomPatchDict.add("neighbourPatch", bottomNbrPatchName);
bottomPatchDict.add
(
"neighbourPatch",
!intrude ? bottomNbrPatchName : topNbrPatchName
);
if (bottomExtruded)
{
bottomPatchDict.add("isExtrudedRegion", isShellMesh);
}
}
zoneBottomPatch[zonei] = addPatch
(
mesh.boundaryMesh(),
bottomPatchName,
patchTypes[zonei],
patchTypes.size() ? patchTypes[zonei]
: !bottomMapped ? polyPatch::typeName
: !bottomExtruded
? mappedWallPolyPatch::typeName
: mappedExtrudedWallPolyPatch::typeName,
bottomPatchDict,
newPatches
);
@ -677,51 +698,36 @@ void addCouplingPatches
<< '\t' << newPatches[zoneBottomPatch[zonei]]->type()
<< nl;
if (zoneIsInternal[zonei] || !zoneShadowNames[zonei].empty())
if (!isShellMesh && !bothMapped) continue;
dictionary topPatchDict;
if (topMapped)
{
dictionary topPatchDict(patchDict);
topPatchDict.add("neighbourPatch", topNbrPatchName);
if (isShellMesh)
{
topPatchDict.add("oppositePatch", bottomPatchName);
}
zoneTopPatch[zonei] = addPatch
topPatchDict = patchDict;
topPatchDict.add
(
mesh.boundaryMesh(),
topPatchName,
mappedExtrudedWallPolyPatch::typeName,
topPatchDict,
newPatches
"neighbourPatch",
!intrude ? topNbrPatchName : bottomNbrPatchName
);
}
else
{
dictionary oppositePatchDict;
if (intrude)
if (topExtruded)
{
oppositePatchDict = patchDict;
oppositePatchDict.add("neighbourPatch", bottomNbrPatchName);
if (isShellMesh)
{
oppositePatchDict.add("oppositePatch", bottomPatchName);
}
topPatchDict.add("isExtrudedRegion", isShellMesh);
}
zoneTopPatch[zonei] = addPatch
(
mesh.boundaryMesh(),
topPatchName,
regionOppositePatchTypes.size()
? regionOppositePatchTypes[zonei]
: polyPatch::typeName,
oppositePatchDict,
newPatches
);
}
zoneTopPatch[zonei] = addPatch
(
mesh.boundaryMesh(),
topPatchName,
oppositePatchTypes.size() ? oppositePatchTypes[zonei]
: !topMapped ? polyPatch::typeName
: !topExtruded
? mappedWallPolyPatch::typeName
: mappedExtrudedWallPolyPatch::typeName,
topPatchDict,
newPatches
);
Pout<< zoneTopPatch[zonei]
<< '\t' << newPatches[zoneTopPatch[zonei]]->name()
<< '\t' << newPatches[zoneTopPatch[zonei]]->type()
@ -1087,7 +1093,7 @@ int main(int argc, char *argv[])
};
wordList zoneNames;
wordList zoneShadowNames;
wordList oppositeZoneNames;
List<zoneSourceType> zoneSourceTypes;
auto lookupZones = [&](const zoneSourceType& type)
@ -1098,14 +1104,17 @@ int main(int argc, char *argv[])
{
zoneNames.append(dict.lookup<wordList>(keyword));
zoneShadowNames.append
oppositeZoneNames.append
(
dict.lookupOrDefault
dict.lookupOrDefaultBackwardsCompatible
(
keyword + "Shadow",
{
"opposite" + keyword.capitalise(),
keyword + "Shadow"
},
wordList
(
zoneNames.size() - zoneShadowNames.size(),
zoneNames.size() - oppositeZoneNames.size(),
word::null
)
)
@ -1123,7 +1132,7 @@ int main(int argc, char *argv[])
{
const unsigned typei = unsigned(zoneSourceTypes[zonei]);
if (zoneShadowNames[zonei].empty())
if (oppositeZoneNames[zonei].empty())
{
Info<< indent << "From " << zoneSourceTypeNames[typei] << " \""
<< zoneNames[zonei] << "\"" << nl;
@ -1131,7 +1140,7 @@ int main(int argc, char *argv[])
else
{
Info<< indent << "Between " << zoneSourcesTypeNames[typei] << " \""
<< zoneNames[zonei] << "\" and \"" << zoneShadowNames[zonei]
<< zoneNames[zonei] << "\" and \"" << oppositeZoneNames[zonei]
<< "\"" << nl;
}
}
@ -1188,7 +1197,7 @@ int main(int argc, char *argv[])
// Map from extrude zone to mesh zone, or -1 if not a mesh zone
labelList zoneMeshZoneID(zoneNames.size(), -1);
labelList shadowZoneMeshZoneID(zoneNames.size(), -1);
labelList oppositeZoneMeshZoneID(zoneNames.size(), -1);
forAll(zoneNames, zonei)
{
if (zoneSourceTypes[zonei] != zoneSourceType::zone) continue;
@ -1204,15 +1213,15 @@ int main(int argc, char *argv[])
<< exit(FatalIOError);
}
if (!zoneShadowNames[zonei].empty())
if (!oppositeZoneNames[zonei].empty())
{
shadowZoneMeshZoneID[zonei] =
mesh.faceZones().findZoneID(zoneShadowNames[zonei]);
oppositeZoneMeshZoneID[zonei] =
mesh.faceZones().findZoneID(oppositeZoneNames[zonei]);
if (shadowZoneMeshZoneID[zonei] == -1)
if (oppositeZoneMeshZoneID[zonei] == -1)
{
FatalIOErrorIn(args.executable().c_str(), dict)
<< "Cannot find shadow zone " << zoneShadowNames[zonei]
<< "Cannot find opposite zone " << oppositeZoneNames[zonei]
<< endl << "Valid zones are " << mesh.faceZones().names()
<< exit(FatalIOError);
}
@ -1221,33 +1230,33 @@ int main(int argc, char *argv[])
// Extract faces to extrude
labelList extrudeFaces, shadowExtrudeFaces;
labelList extrudeFaceZoneIDs, shadowExtrudeFaceZoneIDs;
boolList extrudeFaceFlips, shadowExtrudeFaceFlips;
labelList extrudeFaces, oppositeExtrudeFaces;
labelList extrudeFaceZoneIDs, oppositeExtrudeFaceZoneIDs;
boolList extrudeFaceFlips, oppositeExtrudeFaceFlips;
{
// Load any faceSets that we need
PtrList<faceSet> zoneSets(zoneNames.size());
PtrList<faceSet> zoneShadowSets(zoneNames.size());
PtrList<faceSet> oppositeZoneSets(zoneNames.size());
forAll(zoneNames, zonei)
{
if (zoneSourceTypes[zonei] == zoneSourceType::set)
{
zoneSets.set(zonei, new faceSet(mesh, zoneNames[zonei]));
if (!zoneShadowNames.empty())
if (!oppositeZoneNames.empty())
{
zoneShadowSets.set
oppositeZoneSets.set
(
zonei,
new faceSet(mesh, zoneShadowNames[zonei])
new faceSet(mesh, oppositeZoneNames[zonei])
);
}
}
}
// Create dynamic face lists
DynamicList<label> facesDyn, sdwFacesDyn;
DynamicList<label> zoneIDsDyn, sdwZoneIDsDyn;
DynamicList<bool> flipsDyn, sdwFlipsDyn;
DynamicList<label> facesDyn, oppositeFacesDyn;
DynamicList<label> zoneIDsDyn, oppositeZoneIDsDyn;
DynamicList<bool> flipsDyn, oppositeFlipsDyn;
forAll(zoneNames, zonei)
{
switch (zoneSourceTypes[zonei])
@ -1260,27 +1269,27 @@ int main(int argc, char *argv[])
zoneIDsDyn.append(labelList(fz.size(), zonei));
flipsDyn.append(fz.flipMap());
if (!zoneShadowNames[zonei].empty())
if (!oppositeZoneNames[zonei].empty())
{
const faceZone& sfz =
mesh.faceZones()[shadowZoneMeshZoneID[zonei]];
mesh.faceZones()[oppositeZoneMeshZoneID[zonei]];
if (sfz.size() != fz.size())
{
FatalIOErrorIn(args.executable().c_str(), dict)
<< "Shadow zone " << zoneShadowNames[zonei]
<< "Opposite zone " << oppositeZoneNames[zonei]
<< "is a different size from it's "
<< "corresponding zone " << zoneNames[zonei]
<< exit(FatalIOError);
}
sdwFacesDyn.append(sfz);
sdwZoneIDsDyn.append(labelList(sfz.size(), zonei));
sdwFlipsDyn.append(sfz.flipMap());
oppositeFacesDyn.append(sfz);
oppositeZoneIDsDyn.append(labelList(sfz.size(), zonei));
oppositeFlipsDyn.append(sfz.flipMap());
}
else
{
sdwFacesDyn.append(labelList(fz.size(), -1));
sdwZoneIDsDyn.append(labelList(fz.size(), -1));
sdwFlipsDyn.append(boolList(fz.size(), false));
oppositeFacesDyn.append(labelList(fz.size(), -1));
oppositeZoneIDsDyn.append(labelList(fz.size(), -1));
oppositeFlipsDyn.append(boolList(fz.size(), false));
}
break;
}
@ -1291,26 +1300,26 @@ int main(int argc, char *argv[])
zoneIDsDyn.append(labelList(fs.size(), zonei));
flipsDyn.append(boolList(fs.size(), false));
if (!zoneShadowNames[zonei].empty())
if (!oppositeZoneNames[zonei].empty())
{
const faceSet& sfs = zoneShadowSets[zonei];
const faceSet& sfs = oppositeZoneSets[zonei];
if (sfs.size() != fs.size())
{
FatalIOErrorIn(args.executable().c_str(), dict)
<< "Shadow set " << zoneShadowNames[zonei]
<< "Opposite set " << oppositeZoneNames[zonei]
<< "is a different size from it's "
<< "corresponding zone " << zoneNames[zonei]
<< exit(FatalIOError);
}
sdwFacesDyn.append(sfs.toc());
sdwZoneIDsDyn.append(labelList(sfs.size(), zonei));
sdwFlipsDyn.append(boolList(sfs.size(), false));
oppositeFacesDyn.append(sfs.toc());
oppositeZoneIDsDyn.append(labelList(sfs.size(), zonei));
oppositeFlipsDyn.append(boolList(sfs.size(), false));
}
else
{
sdwFacesDyn.append(labelList(fs.size(), -1));
sdwZoneIDsDyn.append(labelList(fs.size(), -1));
sdwFlipsDyn.append(boolList(fs.size(), false));
oppositeFacesDyn.append(labelList(fs.size(), -1));
oppositeZoneIDsDyn.append(labelList(fs.size(), -1));
oppositeFlipsDyn.append(boolList(fs.size(), false));
}
break;
}
@ -1322,30 +1331,30 @@ int main(int argc, char *argv[])
zoneIDsDyn.append(labelList(pp.size(), zonei));
flipsDyn.append(boolList(pp.size(), false));
if (!zoneShadowNames[zonei].empty())
if (!oppositeZoneNames[zonei].empty())
{
const polyPatch& spp =
mesh.boundaryMesh()[zoneShadowNames[zonei]];
mesh.boundaryMesh()[oppositeZoneNames[zonei]];
if (spp.size() != pp.size())
{
FatalIOErrorIn(args.executable().c_str(), dict)
<< "Shadow patch " << zoneShadowNames[zonei]
<< "Opposite patch " << oppositeZoneNames[zonei]
<< "is a different size from it's "
<< "corresponding zone " << zoneNames[zonei]
<< exit(FatalIOError);
}
sdwFacesDyn.append
oppositeFacesDyn.append
(
spp.start() + identityMap(spp.size())
);
sdwZoneIDsDyn.append(labelList(spp.size(), zonei));
sdwFlipsDyn.append(boolList(spp.size(), false));
oppositeZoneIDsDyn.append(labelList(spp.size(), zonei));
oppositeFlipsDyn.append(boolList(spp.size(), false));
}
else
{
sdwFacesDyn.append(labelList(pp.size(), -1));
sdwZoneIDsDyn.append(labelList(pp.size(), -1));
sdwFlipsDyn.append(boolList(pp.size(), false));
oppositeFacesDyn.append(labelList(pp.size(), -1));
oppositeZoneIDsDyn.append(labelList(pp.size(), -1));
oppositeFlipsDyn.append(boolList(pp.size(), false));
}
break;
}
@ -1356,16 +1365,16 @@ int main(int argc, char *argv[])
extrudeFaces.transfer(facesDyn);
extrudeFaceZoneIDs.transfer(zoneIDsDyn);
extrudeFaceFlips.transfer(flipsDyn);
shadowExtrudeFaces.transfer(sdwFacesDyn);
shadowExtrudeFaceZoneIDs.transfer(sdwZoneIDsDyn);
shadowExtrudeFaceFlips.transfer(sdwFlipsDyn);
oppositeExtrudeFaces.transfer(oppositeFacesDyn);
oppositeExtrudeFaceZoneIDs.transfer(oppositeZoneIDsDyn);
oppositeExtrudeFaceFlips.transfer(oppositeFlipsDyn);
}
faceList extrudeFaceList(UIndirectList<face>(mesh.faces(), extrudeFaces));
if (intrude)
forAll(extrudeFaceList, facei)
{
forAll(extrudeFaceList, facei)
if (intrude != extrudeFaceFlips[facei])
{
extrudeFaceList[facei].flip();
}
@ -1461,7 +1470,7 @@ int main(int argc, char *argv[])
shellRegionName,
regionName,
zoneNames,
zoneShadowNames,
oppositeZoneNames,
zoneIsInternal,
dict,
regionPatches,
@ -1495,7 +1504,7 @@ int main(int argc, char *argv[])
regionName,
shellRegionName,
zoneNames,
zoneShadowNames,
oppositeZoneNames,
zoneIsInternal,
dict,
newPatches,
@ -1889,7 +1898,7 @@ int main(int argc, char *argv[])
false, // face flip
interMeshBottomPatch[zonei],// patch for face
zoneMeshZoneID[zonei], // zone for face
flip // face flip in zone
false // face flip in zone
);
}
else if (mesh.isInternalFace(meshFacei))
@ -1903,18 +1912,18 @@ int main(int argc, char *argv[])
true, // face flip
interMeshBottomPatch[zonei], // patch for face
zoneMeshZoneID[zonei], // zone for face
!flip // face flip in zone
true // face flip in zone
);
}
}
forAll(extrudeFaces, facei)
{
if (shadowExtrudeFaces[facei] != -1)
if (oppositeExtrudeFaces[facei] != -1)
{
const label meshFacei = shadowExtrudeFaces[facei];
const label zonei = shadowExtrudeFaceZoneIDs[facei];
bool flip = shadowExtrudeFaceFlips[facei];
const label meshFacei = oppositeExtrudeFaces[facei];
const label zonei = oppositeExtrudeFaceZoneIDs[facei];
const bool flip = oppositeExtrudeFaceFlips[facei];
const face& f = mesh.faces()[meshFacei];
if (!flip)
@ -1928,7 +1937,7 @@ int main(int argc, char *argv[])
false, // face flip
interMeshTopPatch[zonei], // patch for face
zoneMeshZoneID[zonei], // zone for face
flip // face flip in zone
false // face flip in zone
);
}
else if (mesh.isInternalFace(meshFacei))
@ -1942,7 +1951,7 @@ int main(int argc, char *argv[])
true, // face flip
interMeshTopPatch[zonei], // patch for face
zoneMeshZoneID[zonei], // zone for face
!flip // face flip in zone
true // face flip in zone
);
}
}

View File

@ -0,0 +1,192 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::PointEdgeLayerInfoData
Description
Class to be used with PointEdgeWave which enumerates layers of points
SourceFiles
PointEdgeLayerInfoDataI.H
\*---------------------------------------------------------------------------*/
#ifndef PointEdgeLayerInfoData_H
#define PointEdgeLayerInfoData_H
#include "pointEdgeLayerInfo.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class polyPatch;
class polyMesh;
class transformer;
// Forward declaration of friend functions and operators
template<class Type>
class PointEdgeLayerInfoData;
template<class Type>
inline Ostream& operator<<(Ostream&, const PointEdgeLayerInfoData<Type>&);
template<class Type>
inline Istream& operator>>(Istream&, PointEdgeLayerInfoData<Type>&);
/*---------------------------------------------------------------------------*\
Class PointEdgeLayerInfoData Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class PointEdgeLayerInfoData
:
public pointEdgeLayerInfo
{
// Private Data
//- Data
Type data_;
public:
// Constructors
//- Construct null
inline PointEdgeLayerInfoData();
//- Construct given the point layer index
inline PointEdgeLayerInfoData(const label pointLayer, const Type& data);
// Member Functions
// Access
//- Return the data
inline const Type& data() const;
// Needed by PointEdgeWave
//- Transform across an interface
template<class TrackingData>
inline void transform
(
const polyPatch& patch,
const label patchPointi,
const transformer& transform,
TrackingData& td
);
//- Influence of edge on point
template<class TrackingData>
inline bool updatePoint
(
const polyMesh& mesh,
const label pointi,
const label edgei,
const PointEdgeLayerInfoData<Type>& edgeInfo,
const scalar tol,
TrackingData& td
);
//- Influence of different value on same point.
// Merge new and old info.
template<class TrackingData>
inline bool updatePoint
(
const polyMesh& mesh,
const label pointi,
const PointEdgeLayerInfoData<Type>& newPointInfo,
const scalar tol,
TrackingData& td
);
//- Influence of different value on same point.
// No old information.
template<class TrackingData>
inline bool updatePoint
(
const PointEdgeLayerInfoData<Type>& newPointInfo,
const scalar tol,
TrackingData& td
);
//- Influence of point on edge
template<class TrackingData>
inline bool updateEdge
(
const polyMesh& mesh,
const label edgei,
const label pointi,
const PointEdgeLayerInfoData<Type>& pointInfo,
const scalar tol,
TrackingData& td
);
//- Same (like operator==)
template<class TrackingData>
inline bool equal
(
const PointEdgeLayerInfoData<Type>&,
TrackingData& td
) const;
// Member Operators
inline bool operator==(const PointEdgeLayerInfoData<Type>&) const;
inline bool operator!=(const PointEdgeLayerInfoData<Type>&) const;
// IOstream Operators
friend Ostream& operator<< <Type>
(
Ostream&,
const PointEdgeLayerInfoData<Type>&
);
friend Istream& operator>> <Type>
(
Istream&,
PointEdgeLayerInfoData<Type>&
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "PointEdgeLayerInfoDataI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,233 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "PointEdgeLayerInfoData.H"
#include "polyMesh.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
inline Foam::PointEdgeLayerInfoData<Type>::PointEdgeLayerInfoData()
:
pointEdgeLayerInfo(),
data_()
{}
template<class Type>
inline Foam::PointEdgeLayerInfoData<Type>::PointEdgeLayerInfoData
(
const label pointLayer,
const Type& data
)
:
pointEdgeLayerInfo(pointLayer),
data_(data)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
inline const Type& Foam::PointEdgeLayerInfoData<Type>::data() const
{
return data_;
}
template<class Type>
template<class TrackingData>
inline void Foam::PointEdgeLayerInfoData<Type>::transform
(
const polyPatch& patch,
const label patchFacei,
const transformer& transform,
TrackingData& td
)
{
if (transform.transformsPosition())
{
FatalErrorInFunction
<< "Cannot have a transform within a set of mesh layers"
<< exit(FatalError);
}
}
template<class Type>
template<class TrackingData>
inline bool Foam::PointEdgeLayerInfoData<Type>::updatePoint
(
const polyMesh& mesh,
const label pointi,
const label edgei,
const PointEdgeLayerInfoData<Type>& edgeInfo,
const scalar tol,
TrackingData& td
)
{
if (pointEdgeLayerInfo::updatePoint(mesh, pointi, edgei, edgeInfo, tol, td))
{
data_ = edgeInfo.data_;
return true;
}
else
{
return false;
}
}
template<class Type>
template<class TrackingData>
inline bool Foam::PointEdgeLayerInfoData<Type>::updatePoint
(
const polyMesh& mesh,
const label pointi,
const PointEdgeLayerInfoData<Type>& newPointInfo,
const scalar tol,
TrackingData& td
)
{
if (pointEdgeLayerInfo::updatePoint(mesh, pointi, newPointInfo, tol, td))
{
data_ = newPointInfo.data_;
return true;
}
else
{
return false;
}
}
template<class Type>
template<class TrackingData>
inline bool Foam::PointEdgeLayerInfoData<Type>::updatePoint
(
const PointEdgeLayerInfoData<Type>& newPointInfo,
const scalar tol,
TrackingData& td
)
{
if (pointEdgeLayerInfo::updatePoint(newPointInfo, tol, td))
{
data_ = newPointInfo.data_;
return true;
}
else
{
return false;
}
}
template<class Type>
template<class TrackingData>
inline bool Foam::PointEdgeLayerInfoData<Type>::updateEdge
(
const polyMesh& mesh,
const label edgei,
const label pointi,
const PointEdgeLayerInfoData<Type>& pointInfo,
const scalar tol,
TrackingData& td
)
{
if (pointEdgeLayerInfo::updateEdge(mesh, edgei, pointi, pointInfo, tol, td))
{
data_ = pointInfo.data_;
return true;
}
else
{
return false;
}
}
template<class Type>
template<class TrackingData>
inline bool Foam::PointEdgeLayerInfoData<Type>::equal
(
const PointEdgeLayerInfoData<Type>& rhs,
TrackingData& td
) const
{
return operator==(rhs);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class Type>
inline bool Foam::PointEdgeLayerInfoData<Type>::operator==
(
const Foam::PointEdgeLayerInfoData<Type>& rhs
) const
{
return pointEdgeLayerInfo::operator==(rhs) && data_ == rhs.data_;
}
template<class Type>
inline bool Foam::PointEdgeLayerInfoData<Type>::operator!=
(
const Foam::PointEdgeLayerInfoData<Type>& rhs
) const
{
return !(*this == rhs);
}
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
template<class Type>
inline Foam::Ostream& Foam::operator<<
(
Ostream& os,
const PointEdgeLayerInfoData<Type>& l
)
{
return
os
<< static_cast<const pointEdgeLayerInfo&>(l)
<< token::SPACE
<< l.data_;
}
template<class Type>
inline Foam::Istream& Foam::operator>>
(
Istream& is,
PointEdgeLayerInfoData<Type>& l
)
{
return is >> static_cast<pointEdgeLayerInfo&>(l) >> l.data_;
}
// ************************************************************************* //

View File

@ -97,7 +97,7 @@ public:
//- Return the face layer index
inline label faceLayer() const;
//- Return the face layer index
//- Return the cell layer index
inline label cellLayer() const;

View File

@ -60,7 +60,7 @@ inline Foam::layerInfo::layerInfo(const label faceLayer, const label direction)
inline Foam::label Foam::layerInfo::faceLayer() const
{
if (layer_ % 2 != 1)
if ((layer_ + 1) % 2 != 0)
{
FatalError
<< "Face layer index requested from cell layer info"

View File

@ -0,0 +1,205 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::pointEdgeLayerInfo
Description
Class to be used with PointEdgeWave which enumerates layers of points
SourceFiles
pointEdgeLayerInfoI.H
\*---------------------------------------------------------------------------*/
#ifndef pointEdgeLayerInfo_H
#define pointEdgeLayerInfo_H
#include "contiguous.H"
#include "label.H"
#include "scalar.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class polyPatch;
class polyMesh;
class transformer;
// Forward declaration of friend functions and operators
class pointEdgeLayerInfo;
inline Ostream& operator<<(Ostream&, const pointEdgeLayerInfo&);
inline Istream& operator>>(Istream&, pointEdgeLayerInfo&);
/*---------------------------------------------------------------------------*\
Class pointEdgeLayerInfo Declaration
\*---------------------------------------------------------------------------*/
class pointEdgeLayerInfo
{
// Private Data
//- Layer index
label layer_;
public:
// Constructors
//- Construct null
inline pointEdgeLayerInfo();
//- Construct given the point layer index
inline pointEdgeLayerInfo(const label pointLayer);
// Member Functions
// Access
//- Return the point layer index
inline label pointLayer() const;
//- Return the edge layer index
inline label edgeLayer() const;
// Needed by PointEdgeWave
//- Check whether info has been changed at all or
// still contains original (invalid) value
template<class TrackingData>
inline bool valid(TrackingData& td) const;
//- Check for identical geometrical data. Used for cyclics checking.
template<class TrackingData>
inline bool sameGeometry
(
const pointEdgeLayerInfo&,
const scalar tol,
TrackingData& td
) const;
//- Transform across an interface
template<class TrackingData>
inline void transform
(
const polyPatch& patch,
const label patchPointi,
const transformer& transform,
TrackingData& td
);
//- Influence of edge on point
template<class TrackingData>
inline bool updatePoint
(
const polyMesh& mesh,
const label pointi,
const label edgei,
const pointEdgeLayerInfo& edgeInfo,
const scalar tol,
TrackingData& td
);
//- Influence of different value on same point.
// Merge new and old info.
template<class TrackingData>
inline bool updatePoint
(
const polyMesh& mesh,
const label pointi,
const pointEdgeLayerInfo& newPointInfo,
const scalar tol,
TrackingData& td
);
//- Influence of different value on same point.
// No old information.
template<class TrackingData>
inline bool updatePoint
(
const pointEdgeLayerInfo& newPointInfo,
const scalar tol,
TrackingData& td
);
//- Influence of point on edge
template<class TrackingData>
inline bool updateEdge
(
const polyMesh& mesh,
const label edgei,
const label pointi,
const pointEdgeLayerInfo& pointInfo,
const scalar tol,
TrackingData& td
);
//- Same (like operator==)
template<class TrackingData>
inline bool equal
(
const pointEdgeLayerInfo&,
TrackingData& td
) const;
// Member Operators
inline bool operator==(const pointEdgeLayerInfo&) const;
inline bool operator!=(const pointEdgeLayerInfo&) const;
// IOstream Operators
inline friend Ostream& operator<<(Ostream&, const pointEdgeLayerInfo&);
inline friend Istream& operator>>(Istream&, pointEdgeLayerInfo&);
};
//- Data associated with pointEdgeLayerInfo type are contiguous
template<>
inline bool contiguous<pointEdgeLayerInfo>()
{
return true;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "pointEdgeLayerInfoI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,235 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "pointEdgeLayerInfo.H"
#include "polyMesh.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
inline Foam::pointEdgeLayerInfo::pointEdgeLayerInfo()
:
layer_(-labelMax)
{}
inline Foam::pointEdgeLayerInfo::pointEdgeLayerInfo(const label pointLayer)
:
layer_(2*pointLayer - 1)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline Foam::label Foam::pointEdgeLayerInfo::pointLayer() const
{
if ((layer_ + 1) % 2 != 0)
{
FatalError
<< "Point layer index requested from edge layer info"
<< exit(FatalError);
}
return (layer_ + 1)/2;
}
inline Foam::label Foam::pointEdgeLayerInfo::edgeLayer() const
{
if (layer_ % 2 != 0)
{
FatalError
<< "Edge layer index requested from point layer info"
<< exit(FatalError);
}
return layer_/2;
}
template<class TrackingData>
inline bool Foam::pointEdgeLayerInfo::valid(TrackingData& td) const
{
return layer_ != -labelMax;
}
template<class TrackingData>
inline bool Foam::pointEdgeLayerInfo::sameGeometry
(
const pointEdgeLayerInfo& l,
const scalar tol,
TrackingData& td
) const
{
return true;
}
template<class TrackingData>
inline void Foam::pointEdgeLayerInfo::transform
(
const polyPatch& patch,
const label patchFacei,
const transformer& transform,
TrackingData& td
)
{}
template<class TrackingData>
inline bool Foam::pointEdgeLayerInfo::updatePoint
(
const polyMesh& mesh,
const label pointi,
const label edgei,
const pointEdgeLayerInfo& edgeInfo,
const scalar tol,
TrackingData& td
)
{
if (!valid(td))
{
layer_ = edgeInfo.layer_ + 1;
return true;
}
if (!edgeInfo.valid(td) || layer_ < edgeInfo.layer_)
{
return false;
}
FatalErrorInFunction
<< "Layer information collided. This is not a layered mesh"
<< exit(FatalError);
return false;
}
template<class TrackingData>
inline bool Foam::pointEdgeLayerInfo::updatePoint
(
const polyMesh& mesh,
const label pointi,
const pointEdgeLayerInfo& newPointInfo,
const scalar tol,
TrackingData& td
)
{
if (!valid(td))
{
layer_ = newPointInfo.layer_;
return true;
}
FatalErrorInFunction
<< "Layer information collided. This is not a layered mesh"
<< exit(FatalError);
return false;
}
template<class TrackingData>
inline bool Foam::pointEdgeLayerInfo::updatePoint
(
const pointEdgeLayerInfo& newPointInfo,
const scalar tol,
TrackingData& td
)
{
layer_ = newPointInfo.layer_;
return true;
}
template<class TrackingData>
inline bool Foam::pointEdgeLayerInfo::updateEdge
(
const polyMesh& mesh,
const label edgei,
const label pointi,
const pointEdgeLayerInfo& pointInfo,
const scalar tol,
TrackingData& td
)
{
if (!valid(td))
{
layer_ = pointInfo.layer_ + 1;
return true;
}
layer_ = -labelMax;
return false;
}
template<class TrackingData>
inline bool Foam::pointEdgeLayerInfo::equal
(
const pointEdgeLayerInfo& rhs,
TrackingData& td
) const
{
return operator==(rhs);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline bool Foam::pointEdgeLayerInfo::operator==
(
const Foam::pointEdgeLayerInfo& rhs
) const
{
return layer_ == rhs.layer_;
}
inline bool Foam::pointEdgeLayerInfo::operator!=
(
const Foam::pointEdgeLayerInfo& rhs
) const
{
return !(*this == rhs);
}
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
inline Foam::Ostream& Foam::operator<<(Ostream& os, const pointEdgeLayerInfo& l)
{
return os << l.layer_;
}
inline Foam::Istream& Foam::operator>>(Istream& is, pointEdgeLayerInfo& l)
{
return is >> l.layer_;
}
// ************************************************************************* //

View File

@ -25,7 +25,9 @@ License
#include "mappedExtrudedPatchBase.H"
#include "LayerInfoData.H"
#include "PointEdgeLayerInfoData.H"
#include "FaceCellWave.H"
#include "PointEdgeWave.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -40,60 +42,108 @@ namespace Foam
Foam::tmp<Foam::vectorField>
Foam::mappedExtrudedPatchBase::patchFaceAreas() const
{
if (!bottomFaceAreasPtr_.valid())
if (isExtrudedRegion_)
{
const bool isExtrudedRegion = oppositePatch_ != word::null;
if (isExtrudedRegion)
if (!bottomFaceAreasPtr_.valid())
{
const polyMesh& mesh = patch_.boundaryMesh().mesh();
const polyPatch& pp = patch_;
// If this is the extruded region we need to work out what the
// corresponding areas and centres are on the bottom patch. We do
// this by waving these values across the layers.
const polyMesh& mesh = patch_.boundaryMesh().mesh();
const polyPatch& pp = patch_;
const polyPatch& bottomPp = patch_.boundaryMesh()[oppositePatch_];
// Initialise faces on the bottom patch to wave from
labelList initialFaces(bottomPp.size());
List<LayerInfoData<Pair<vector>>> initialFaceInfo(bottomPp.size());
forAll(bottomPp, bottomPpFacei)
// Initialise layer data on the patch faces
labelList initialFaces1(pp.size());
List<layerInfo> initialFaceInfo1(pp.size());
forAll(pp, ppFacei)
{
initialFaces[bottomPpFacei] =
bottomPp.start() + bottomPpFacei;
initialFaceInfo[bottomPpFacei] =
LayerInfoData<Pair<vector>>
(
0,
-1,
Pair<vector>
(
bottomPp.faceAreas()[bottomPpFacei],
bottomPp.faceCentres()[bottomPpFacei]
)
);
initialFaces1[ppFacei] = pp.start() + ppFacei;
initialFaceInfo1[ppFacei] = layerInfo(0, -1);
}
// Wave across the mesh layers
List<LayerInfoData<Pair<vector>>> faceInfo(mesh.nFaces());
List<LayerInfoData<Pair<vector>>> cellInfo(mesh.nCells());
FaceCellWave<LayerInfoData<Pair<vector>>>
List<layerInfo> faceInfo1(mesh.nFaces());
List<layerInfo> cellInfo1(mesh.nCells());
FaceCellWave<layerInfo> wave1(mesh, faceInfo1, cellInfo1);
wave1.setFaceInfo(initialFaces1, initialFaceInfo1);
const label nIterations1 =
wave1.iterate(mesh.globalData().nTotalCells() + 1);
// Count how many opposite faces the wave ended on
label nInitialFaces2 = 0;
for
(
label facei = mesh.nInternalFaces();
facei < mesh.nFaces();
++ facei
)
{
if
(
faceInfo1[facei].valid(wave1.data())
&& faceInfo1[facei].faceLayer() == nIterations1
)
{
nInitialFaces2 ++;
}
}
// Initialise data on the opposite faces. Store the area and centre.
labelList initialFaces2(nInitialFaces2);
List<LayerInfoData<Pair<vector>>> initialFaceInfo2(nInitialFaces2);
label initialFace2i = 0;
for
(
label facei = mesh.nInternalFaces();
facei < mesh.nFaces();
++ facei
)
{
if
(
faceInfo1[facei].valid(wave1.data())
&& faceInfo1[facei].faceLayer() != 0
)
{
initialFaces2[initialFace2i] = facei;
initialFaceInfo2[initialFace2i] =
LayerInfoData<Pair<vector>>
(
0,
-1,
Pair<vector>
(
mesh.faceAreas()[facei],
mesh.faceCentres()[facei]
)
);
initialFace2i ++;
}
}
// Wave back across the mesh layers
List<LayerInfoData<Pair<vector>>> faceInfo2(mesh.nFaces());
List<LayerInfoData<Pair<vector>>> cellInfo2(mesh.nCells());
FaceCellWave<LayerInfoData<Pair<vector>>> wave2
(
mesh,
initialFaces,
initialFaceInfo,
faceInfo,
cellInfo,
initialFaces2,
initialFaceInfo2,
faceInfo2,
cellInfo2,
mesh.globalData().nTotalCells() + 1
);
// Unpack into this patch's bottom face areas and centres
// Unpack into this patch's bottom face areas and centres. Note
// that the face area needs flipping as it relates to a patch on
// the other side of the extruded region.
bottomFaceAreasPtr_.set(new vectorField(pp.size()));
bottomFaceCentresPtr_.set(new pointField(pp.size()));
forAll(pp, ppFacei)
{
const LayerInfoData<Pair<vector>>& info =
faceInfo[pp.start() + ppFacei];
faceInfo2[pp.start() + ppFacei];
static nil td;
@ -101,62 +151,188 @@ Foam::mappedExtrudedPatchBase::patchFaceAreas() const
{
FatalErrorInFunction
<< "Mesh \"" << mesh.name()
<< "\" is not layered between the extruded patch "
<< "\"" << pp.name() << "\" and the bottom patch \""
<< bottomPp.name() << "\"" << exit(FatalError);
<< "\" is not layered from the extruded patch "
<< "\"" << pp.name() << "\"" << exit(FatalError);
}
bottomFaceAreasPtr_()[ppFacei] = info.data().first();
bottomFaceAreasPtr_()[ppFacei] = - info.data().first();
bottomFaceCentresPtr_()[ppFacei] = info.data().second();
}
}
else
{
// If this is not the extruded region then we trigger construction
// of mapping on the extruded region and then reverse map the
// extruded region's data so it is available here
const mappedExtrudedPatchBase& nbrPp =
refCast<const mappedExtrudedPatchBase>(nbrPolyPatch());
bottomFaceAreasPtr_.set
(
nbrPp.toNeighbour
(
nbrPp.patch_.primitivePatch::faceAreas()
).ptr()
);
bottomFaceCentresPtr_.set
(
nbrPp.toNeighbour
(
nbrPp.patch_.primitivePatch::faceCentres()
).ptr()
);
}
return bottomFaceAreasPtr_();
}
return bottomFaceAreasPtr_();
return mappedPatchBase::patchFaceAreas();
}
Foam::tmp<Foam::pointField>
Foam::mappedExtrudedPatchBase::patchFaceCentres() const
{
if (!bottomFaceCentresPtr_.valid())
if (isExtrudedRegion_)
{
patchFaceAreas();
if (!bottomFaceCentresPtr_.valid())
{
patchFaceAreas();
}
return bottomFaceCentresPtr_();
}
return bottomFaceCentresPtr_();
return mappedPatchBase::patchFaceCentres();
}
Foam::tmp<Foam::pointField>
Foam::mappedExtrudedPatchBase::patchLocalPoints() const
{
NotImplemented;
return tmp<pointField>(nullptr);
if (isExtrudedRegion_)
{
if (!bottomLocalPointsPtr_.valid())
{
const polyMesh& mesh = patch_.boundaryMesh().mesh();
const polyPatch& pp = patch_;
// If this is the extruded region we need to work out what the
// corresponding points are on the bottom patch. We do this by
// waving these location across the layers.
// Initialise layer data on the patch points
labelList initialPoints1(pp.nPoints());
List<pointEdgeLayerInfo> initialPointInfo1(pp.nPoints());
forAll(pp.meshPoints(), ppPointi)
{
initialPoints1[ppPointi] = pp.meshPoints()[ppPointi];
initialPointInfo1[ppPointi] = pointEdgeLayerInfo(0);
}
// Wave across the mesh layers
List<pointEdgeLayerInfo> pointInfo1(mesh.nPoints());
List<pointEdgeLayerInfo> edgeInfo1(mesh.nEdges());
PointEdgeWave<pointEdgeLayerInfo> wave1
(
mesh,
pointInfo1,
edgeInfo1
);
wave1.setPointInfo(initialPoints1, initialPointInfo1);
const label nIterations1 =
wave1.iterate(mesh.globalData().nTotalPoints() + 1);
if (debug)
{
pointScalarField pointLayer
(
pointScalarField::New
(
typedName("pointLayer"),
pointMesh::New(mesh),
dimensionedScalar(dimless, 0)
)
);
forAll(pointInfo1, pointi)
{
pointLayer[pointi] =
pointInfo1[pointi].valid(wave1.data())
? pointInfo1[pointi].pointLayer()
: -1;
}
pointLayer.write();
}
// Count how many opposite points the wave ended on
label nInitialPoints2 = 0;
forAll(pointInfo1, pointi)
{
if
(
pointInfo1[pointi].valid(wave1.data())
&& pointInfo1[pointi].pointLayer() == nIterations1
)
{
nInitialPoints2 ++;
}
}
// Initialise data on the opposite points. Store the position.
labelList initialPoints2(nInitialPoints2);
List<PointEdgeLayerInfoData<point>>
initialPointInfo2(nInitialPoints2);
label initialPoint2i = 0;
forAll(pointInfo1, pointi)
{
if
(
pointInfo1[pointi].valid(wave1.data())
&& pointInfo1[pointi].pointLayer() == nIterations1
)
{
initialPoints2[initialPoint2i] = pointi;
initialPointInfo2[initialPoint2i] =
PointEdgeLayerInfoData<point>(0, mesh.points()[pointi]);
initialPoint2i ++;
}
}
// Wave back across the mesh layers
List<PointEdgeLayerInfoData<point>> pointInfo2(mesh.nPoints());
List<PointEdgeLayerInfoData<point>> edgeInfo2(mesh.nEdges());
PointEdgeWave<PointEdgeLayerInfoData<point>> wave2
(
mesh,
initialPoints2,
initialPointInfo2,
pointInfo2,
edgeInfo2,
mesh.globalData().nTotalCells() + 1
);
// Unpack into this patch's bottom local points
bottomLocalPointsPtr_.set(new pointField(pp.nPoints()));
forAll(pp.meshPoints(), ppPointi)
{
const PointEdgeLayerInfoData<point>& info =
pointInfo2[pp.meshPoints()[ppPointi]];
static nil td;
if (!info.valid(td))
{
FatalErrorInFunction
<< "Mesh \"" << mesh.name()
<< "\" is not layered from the extruded patch "
<< "\"" << pp.name() << "\"" << exit(FatalError);
}
bottomLocalPointsPtr_()[ppPointi] = info.data();
}
if (debug)
{
pointVectorField pointOffset
(
pointVectorField::New
(
typedName("pointOffset"),
pointMesh::New(mesh),
dimensionedVector(dimLength, Zero)
)
);
forAll(pp.meshPoints(), ppPointi)
{
pointOffset[pp.meshPoints()[ppPointi]] =
bottomLocalPointsPtr_()[ppPointi]
- pp.localPoints()[ppPointi];
}
pointOffset.write();
}
}
return bottomLocalPointsPtr_();
}
return mappedPatchBase::patchLocalPoints();
}
@ -165,7 +341,7 @@ Foam::mappedExtrudedPatchBase::patchLocalPoints() const
Foam::mappedExtrudedPatchBase::mappedExtrudedPatchBase(const polyPatch& pp)
:
mappedPatchBase(pp),
oppositePatch_(word::null)
isExtrudedRegion_(false)
{}
@ -174,12 +350,12 @@ Foam::mappedExtrudedPatchBase::mappedExtrudedPatchBase
const polyPatch& pp,
const word& nbrRegionName,
const word& nbrPatchName,
const word& oppositePatch,
const bool isExtrudedRegion,
const cyclicTransform& transform
)
:
mappedPatchBase(pp, nbrRegionName, nbrPatchName, transform),
oppositePatch_(oppositePatch)
isExtrudedRegion_(isExtrudedRegion)
{}
@ -191,7 +367,7 @@ Foam::mappedExtrudedPatchBase::mappedExtrudedPatchBase
)
:
mappedPatchBase(pp, dict, transformIsNone),
oppositePatch_(dict.lookupOrDefault<word>("oppositePatch", word::null))
isExtrudedRegion_(dict.lookup<bool>("isExtrudedRegion"))
{}
@ -202,7 +378,7 @@ Foam::mappedExtrudedPatchBase::mappedExtrudedPatchBase
)
:
mappedPatchBase(pp, mepb),
oppositePatch_(mepb.oppositePatch_)
isExtrudedRegion_(mepb.isExtrudedRegion_)
{}
@ -227,7 +403,7 @@ void Foam::mappedExtrudedPatchBase::clearOut()
void Foam::mappedExtrudedPatchBase::write(Ostream& os) const
{
mappedPatchBase::write(os);
writeEntryIfDifferent(os, "oppositePatch", word::null, oppositePatch_);
writeEntry(os, "isExtrudedRegion", isExtrudedRegion_);
}

View File

@ -53,9 +53,8 @@ class mappedExtrudedPatchBase
{
// Private Member Data
//- The patch on the opposite side of the extruded region.
// Empty if this is not the extruded region.
mutable word oppositePatch_;
//- Is this the in the extruded region?
mutable bool isExtrudedRegion_;
//- The face areas on the bottom patch
mutable autoPtr<vectorField> bottomFaceAreasPtr_;
@ -98,7 +97,7 @@ public:
const polyPatch& pp,
const word& nbrRegionName,
const word& nbrPatchName,
const word& oppositePatch,
const bool isExtrudedRegion,
const cyclicTransform& transform
);

View File

@ -100,7 +100,7 @@ Foam::mappedExtrudedWallPolyPatch::mappedExtrudedWallPolyPatch
const label index,
const word& neighbourRegion,
const word& neighbourPatch,
const word& bottomPatch,
const bool isExtrudedRegion,
const polyBoundaryMesh& bm
)
:
@ -110,7 +110,7 @@ Foam::mappedExtrudedWallPolyPatch::mappedExtrudedWallPolyPatch
*this,
neighbourRegion,
neighbourPatch,
bottomPatch,
isExtrudedRegion,
cyclicTransform(true)
)
{}

View File

@ -95,7 +95,7 @@ public:
const label index,
const word& neighbourRegion,
const word& neighbourPatch,
const word& bottomPatch,
const bool isExtrudedRegion,
const polyBoundaryMesh& bm
);

View File

@ -27,7 +27,7 @@ License
#include "SubField.H"
#include "Time.H"
#include "triPointRef.H"
#include "treeDataFace.H"
#include "treeDataPoint.H"
#include "indexedOctree.H"
#include "globalIndex.H"
#include "RemoteData.H"
@ -62,6 +62,33 @@ Foam::tmp<Foam::pointField> Foam::mappedPatchBase::patchLocalPoints() const
}
Foam::tmp<Foam::vectorField> Foam::mappedPatchBase::nbrPatchFaceAreas() const
{
return
nbrPatchIsMapped()
? nbrMappedPatch().patchFaceAreas()
: tmp<vectorField>(nbrPolyPatch().primitivePatch::faceAreas());
}
Foam::tmp<Foam::pointField> Foam::mappedPatchBase::nbrPatchFaceCentres() const
{
return
nbrPatchIsMapped()
? nbrMappedPatch().patchFaceCentres()
: tmp<vectorField>(nbrPolyPatch().primitivePatch::faceCentres());
}
Foam::tmp<Foam::pointField> Foam::mappedPatchBase::nbrPatchLocalPoints() const
{
return
nbrPatchIsMapped()
? nbrMappedPatch().patchLocalPoints()
: tmp<vectorField>(nbrPolyPatch().localPoints());
}
void Foam::mappedPatchBase::calcMapping() const
{
if (treeMapPtr_.valid())
@ -87,8 +114,8 @@ void Foam::mappedPatchBase::calcMapping() const
patchFaceAreas(),
transform_,
nbrPolyPatch().name(),
nbrPolyPatch().faceCentres(),
nbrPolyPatch().faceAreas(),
nbrPatchFaceCentres(),
nbrPatchFaceAreas(),
nbrPatchIsMapped()
? nbrMappedPatch().transform_
: cyclicTransform(false),
@ -104,9 +131,6 @@ void Foam::mappedPatchBase::calcMapping() const
// Find processor and cell/face indices of samples
labelList sampleGlobalPatchFaces, sampleIndices;
{
// Lookup the correct region
const polyMesh& mesh = nbrMesh();
// Gather the sample points into a single globally indexed list
List<point> allPoints(patchGlobalIndex.size());
{
@ -146,24 +170,17 @@ void Foam::mappedPatchBase::calcMapping() const
}
else
{
const polyPatch& pp = nbrPolyPatch();
const pointField nbrPoints(nbrPatchFaceCentres());
const labelList patchFaces(identityMap(pp.size()) + pp.start());
const treeBoundBox patchBb
const treeBoundBox nbrPointsBb
(
treeBoundBox(pp.points(), pp.meshPoints()).extend(1e-4)
treeBoundBox(nbrPoints).extend(1e-4)
);
const indexedOctree<treeDataFace> boundaryTree
const indexedOctree<treeDataPoint> tree
(
treeDataFace // all information needed to search faces
(
false, // do not cache bb
mesh,
patchFaces // boundary faces only
),
patchBb, // overall search domain
treeDataPoint(nbrPoints),
nbrPointsBb, // overall search domain
8, // maxLevel
10, // leafsize
3.0 // duplicity
@ -174,15 +191,14 @@ void Foam::mappedPatchBase::calcMapping() const
const point& p = allPoints[alli];
const pointIndexHit pih =
boundaryTree.findNearest(p, magSqr(patchBb.span()));
tree.findNearest(p, magSqr(nbrPointsBb.span()));
if (pih.hit())
{
const point fc = pp[pih.index()].centre(pp.points());
allNearest[alli].proci = Pstream::myProcNo();
allNearest[alli].elementi = pih.index();
allNearest[alli].data = magSqr(fc - p);
allNearest[alli].data =
magSqr(nbrPoints[pih.index()] - p);
}
}
}
@ -276,18 +292,24 @@ void Foam::mappedPatchBase::calcMapping() const
}
const pointField patchLocalPoints(this->patchLocalPoints());
const pointField nbrPatchLocalPoints(this->nbrPatchLocalPoints());
const primitivePatch patch
(
SubList<face>(patch_.localFaces(), patch_.size()),
patchLocalPoints
);
const primitivePatch nbrPatch
(
SubList<face>(nbrPolyPatch().localFaces(), nbrPolyPatch().size()),
nbrPatchLocalPoints
);
patchToPatchPtr_->update
(
patch,
patch.pointNormals(),
nbrPolyPatch(),
nbrPatch,
transform_.transform()
);

View File

@ -135,6 +135,15 @@ protected:
//- Get the local points for this patch
virtual tmp<pointField> patchLocalPoints() const;
//- Get the face-areas for the neighbour patch
tmp<vectorField> nbrPatchFaceAreas() const;
//- Get the face-centres for the neighbour patch
tmp<pointField> nbrPatchFaceCentres() const;
//- Get the local points for the neighbour patch
tmp<pointField> nbrPatchLocalPoints() const;
//- Calculate mapping
void calcMapping() const;

View File

@ -16,7 +16,7 @@ FoamFile
region baffle3D;
patches (baffle3D0);
patchesShadow (baffle3D1);
oppositePatches (baffle3D1);
extrudeModel linearNormal;

View File

@ -55,6 +55,7 @@ boundary
type mappedExtrudedWall;
neighbourRegion film;
neighbourPatch surface;
isExtrudedRegion no;
faces
(

View File

@ -1,143 +0,0 @@
/*--------------------------------*- 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;
object blockMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
convertToMeters 1;
vertices
(
(0.5 0 -0.5)
(1 0 -0.5)
(2 0 -0.5)
(2 0.707107 -0.5)
(0.707107 0.707107 -0.5)
(0.353553 0.353553 -0.5)
(2 2 -0.5)
(0.707107 2 -0.5)
(0 2 -0.5)
(0 1 -0.5)
(0 0.5 -0.5)
(-0.5 0 -0.5)
(-1 0 -0.5)
(-2 0 -0.5)
(-2 0.707107 -0.5)
(-0.707107 0.707107 -0.5)
(-0.353553 0.353553 -0.5)
(-2 2 -0.5)
(-0.707107 2 -0.5)
(0.5 0 0.5)
(1 0 0.5)
(2 0 0.5)
(2 0.707107 0.5)
(0.707107 0.707107 0.5)
(0.353553 0.353553 0.5)
(2 2 0.5)
(0.707107 2 0.5)
(0 2 0.5)
(0 1 0.5)
(0 0.5 0.5)
(-0.5 0 0.5)
(-1 0 0.5)
(-2 0 0.5)
(-2 0.707107 0.5)
(-0.707107 0.707107 0.5)
(-0.353553 0.353553 0.5)
(-2 2 0.5)
(-0.707107 2 0.5)
);
blocks
(
hex (5 4 9 10 24 23 28 29) (10 10 11) simpleGrading (1 1 1)
hex (0 1 4 5 19 20 23 24) (10 10 11) simpleGrading (1 1 1)
hex (1 2 3 4 20 21 22 23) (20 10 11) simpleGrading (1 1 1)
hex (4 3 6 7 23 22 25 26) (20 20 11) simpleGrading (1 1 1)
hex (9 4 7 8 28 23 26 27) (10 20 11) simpleGrading (1 1 1)
hex (15 16 10 9 34 35 29 28) (10 10 11) simpleGrading (1 1 1)
hex (12 11 16 15 31 30 35 34) (10 10 11) simpleGrading (1 1 1)
hex (13 12 15 14 32 31 34 33) (20 10 11) simpleGrading (1 1 1)
hex (14 15 18 17 33 34 37 36) (20 20 11) simpleGrading (1 1 1)
hex (15 9 8 18 34 28 27 37) (10 20 11) simpleGrading (1 1 1)
);
edges
(
arc 0 5 (0.469846 0.17101 -0.5)
arc 5 10 (0.17101 0.469846 -0.5)
arc 1 4 (0.939693 0.34202 -0.5)
arc 4 9 (0.34202 0.939693 -0.5)
arc 19 24 (0.469846 0.17101 0.5)
arc 24 29 (0.17101 0.469846 0.5)
arc 20 23 (0.939693 0.34202 0.5)
arc 23 28 (0.34202 0.939693 0.5)
arc 11 16 (-0.469846 0.17101 -0.5)
arc 16 10 (-0.17101 0.469846 -0.5)
arc 12 15 (-0.939693 0.34202 -0.5)
arc 15 9 (-0.34202 0.939693 -0.5)
arc 30 35 (-0.469846 0.17101 0.5)
arc 35 29 (-0.17101 0.469846 0.5)
arc 31 34 (-0.939693 0.34202 0.5)
arc 34 28 (-0.34202 0.939693 0.5)
);
defaultPatch
{
name frontAndBack;
type patch;
}
boundary
(
surface
{
type patch;
faces
(
(0 1 20 19)
(1 2 21 20)
(12 11 30 31)
(13 12 31 32)
(5 0 19 24)
(10 5 24 29)
(16 10 29 35)
(11 16 35 30)
);
}
sides
{
type patch;
faces
(
(2 3 22 21)
(3 6 25 22)
(14 13 32 33)
(17 14 33 36)
);
}
wall
{
type filmWall;
faces
(
(6 7 26 25)
(7 8 27 26)
(8 18 37 27)
(18 17 36 37)
);
}
);
// ************************************************************************* //

View File

@ -104,6 +104,7 @@ boundary
type mappedExtrudedWall;
neighbourRegion film;
neighbourPatch surface;
isExtrudedRegion no;
faces
(

View File

@ -104,6 +104,7 @@ boundary
type mappedExtrudedWall;
neighbourRegion film;
neighbourPatch surface;
isExtrudedRegion no;
faces
(

View File

@ -1,143 +0,0 @@
/*--------------------------------*- 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;
object blockMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
convertToMeters 1;
vertices
(
(0.5 0 -0.5)
(1 0 -0.5)
(2 0 -0.5)
(2 0.707107 -0.5)
(0.707107 0.707107 -0.5)
(0.353553 0.353553 -0.5)
(2 2 -0.5)
(0.707107 2 -0.5)
(0 2 -0.5)
(0 1 -0.5)
(0 0.5 -0.5)
(-0.5 0 -0.5)
(-1 0 -0.5)
(-2 0 -0.5)
(-2 0.707107 -0.5)
(-0.707107 0.707107 -0.5)
(-0.353553 0.353553 -0.5)
(-2 2 -0.5)
(-0.707107 2 -0.5)
(0.5 0 0.5)
(1 0 0.5)
(2 0 0.5)
(2 0.707107 0.5)
(0.707107 0.707107 0.5)
(0.353553 0.353553 0.5)
(2 2 0.5)
(0.707107 2 0.5)
(0 2 0.5)
(0 1 0.5)
(0 0.5 0.5)
(-0.5 0 0.5)
(-1 0 0.5)
(-2 0 0.5)
(-2 0.707107 0.5)
(-0.707107 0.707107 0.5)
(-0.353553 0.353553 0.5)
(-2 2 0.5)
(-0.707107 2 0.5)
);
blocks
(
hex (5 4 9 10 24 23 28 29) (10 10 11) simpleGrading (1 1 1)
hex (0 1 4 5 19 20 23 24) (10 10 11) simpleGrading (1 1 1)
hex (1 2 3 4 20 21 22 23) (20 10 11) simpleGrading (1 1 1)
hex (4 3 6 7 23 22 25 26) (20 20 11) simpleGrading (1 1 1)
hex (9 4 7 8 28 23 26 27) (10 20 11) simpleGrading (1 1 1)
hex (15 16 10 9 34 35 29 28) (10 10 11) simpleGrading (1 1 1)
hex (12 11 16 15 31 30 35 34) (10 10 11) simpleGrading (1 1 1)
hex (13 12 15 14 32 31 34 33) (20 10 11) simpleGrading (1 1 1)
hex (14 15 18 17 33 34 37 36) (20 20 11) simpleGrading (1 1 1)
hex (15 9 8 18 34 28 27 37) (10 20 11) simpleGrading (1 1 1)
);
edges
(
arc 0 5 (0.469846 0.17101 -0.5)
arc 5 10 (0.17101 0.469846 -0.5)
arc 1 4 (0.939693 0.34202 -0.5)
arc 4 9 (0.34202 0.939693 -0.5)
arc 19 24 (0.469846 0.17101 0.5)
arc 24 29 (0.17101 0.469846 0.5)
arc 20 23 (0.939693 0.34202 0.5)
arc 23 28 (0.34202 0.939693 0.5)
arc 11 16 (-0.469846 0.17101 -0.5)
arc 16 10 (-0.17101 0.469846 -0.5)
arc 12 15 (-0.939693 0.34202 -0.5)
arc 15 9 (-0.34202 0.939693 -0.5)
arc 30 35 (-0.469846 0.17101 0.5)
arc 35 29 (-0.17101 0.469846 0.5)
arc 31 34 (-0.939693 0.34202 0.5)
arc 34 28 (-0.34202 0.939693 0.5)
);
defaultPatch
{
name frontAndBack;
type patch;
}
boundary
(
surface
{
type patch;
faces
(
(0 1 20 19)
(1 2 21 20)
(12 11 30 31)
(13 12 31 32)
(5 0 19 24)
(10 5 24 29)
(16 10 29 35)
(11 16 35 30)
);
}
sides
{
type patch;
faces
(
(2 3 22 21)
(3 6 25 22)
(14 13 32 33)
(17 14 33 36)
);
}
wall
{
type filmWall;
faces
(
(6 7 26 25)
(7 8 27 26)
(8 18 37 27)
(18 17 36 37)
);
}
);
// ************************************************************************* //

View File

@ -20,14 +20,15 @@ runApplication -s film extrudeToRegionMesh \
runApplication -s box foamDictionary -set \
"entry0/film/type=mappedExtrudedWall, \
entry0/film/neighbourRegion=film, \
entry0/film/neighbourPatch=surface" \
entry0/film/neighbourPatch=surface, \
entry0/film/isExtrudedRegion=no" \
constant/box/polyMesh/boundary
runApplication -s film foamDictionary -set \
"entry0/surface/type=mappedFilmSurface, \
entry0/surface/neighbourRegion=box, \
entry0/surface/neighbourPatch=film, \
entry0/surface/oppositePatch=wall" \
entry0/surface/isExtrudedRegion=yes" \
constant/film/polyMesh/boundary
printf "\n%s\n" "Creating files for paraview post-processing"

View File

@ -61,6 +61,7 @@ boundary
type mappedExtrudedWall;
neighbourRegion film;
neighbourPatch surface;
isExtrudedRegion no;
faces
(