Compare commits
5 Commits
feature-AM
...
feature-sp
| Author | SHA1 | Date | |
|---|---|---|---|
| 0503f66c90 | |||
| 25ff1d7d6f | |||
| eb2b9b2823 | |||
| d5644058b2 | |||
| 504f5a8a14 |
@ -1157,6 +1157,34 @@ Foam::label Foam::checkGeometry
|
||||
globalFaces,
|
||||
globalPoints
|
||||
);
|
||||
|
||||
if (cpp.sameWorld())
|
||||
{
|
||||
//- Get the patch on the region
|
||||
const polyPatch& nbrPp = cpp.samplePolyPatch();
|
||||
|
||||
// Collect neighbour geometry
|
||||
faceList mergedFaces;
|
||||
pointField mergedPoints;
|
||||
autoPtr<globalIndex> globalFaces;
|
||||
autoPtr<globalIndex> globalPoints;
|
||||
|
||||
collectAndWriteAMIWeights
|
||||
(
|
||||
cpp.sampleMesh(),
|
||||
wr,
|
||||
outputDir / pName + "-tgt_" + tmName,
|
||||
ami.tgtWeightsSum(),
|
||||
nbrPp.localFaces(),
|
||||
nbrPp.meshPoints(),
|
||||
nbrPp.meshPointMap(),
|
||||
|
||||
mergedFaces,
|
||||
mergedPoints,
|
||||
globalFaces,
|
||||
globalPoints
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,8 +43,9 @@ Description
|
||||
- volScalarField with regions as different scalars (-detectOnly)
|
||||
or
|
||||
- mesh with multiple regions and mapped patches. These patches
|
||||
either cover the whole interface between two region (default) or
|
||||
only part according to faceZones (-useFaceZones)
|
||||
either cover the whole interface between two region (default),
|
||||
only part according to faceZones (-useFaceZones) or be auto-generated
|
||||
according to an AMI method (see below)
|
||||
or
|
||||
- mesh with cells put into cellZones (-makeCellZones)
|
||||
|
||||
@ -57,7 +58,7 @@ Description
|
||||
-combineZones '((zoneA "zoneB.*")(none otherZone))
|
||||
This can be combined with e.g. 'cellZones' or 'cellZonesOnly'. The
|
||||
addZones option supplies the destination region name as first element in
|
||||
the list. The combineZones option synthesises the region name e.g.
|
||||
the list. The combineZones option synthesises the region name e.g.
|
||||
zoneA_zoneB0_zoneB1
|
||||
|
||||
- cellZonesOnly does not do a walk and uses the cellZones only. Use
|
||||
@ -98,6 +99,14 @@ Description
|
||||
- boundaryRegionAddressing : for every patch in this region the
|
||||
patch in the original mesh (or -1 if added patch)
|
||||
|
||||
- auto-generate patches using AMI area-overlap detection. This requires a
|
||||
patchSet to apply it to and an optional AMIMethod (default is
|
||||
faceAreaWeightAMI2D).
|
||||
-autoPatch '("solid*")'
|
||||
-AMIMethod faceAreaWeightAMI2D
|
||||
Any mapped patch thus generated should probably use the
|
||||
nearestPatchFaceAMI sampling method.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
@ -116,6 +125,7 @@ Description
|
||||
#include "fvMeshTools.H"
|
||||
#include "zeroGradientFvPatchFields.H"
|
||||
#include "processorMeshes.H"
|
||||
#include "faceAreaWeightAMI2D.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
@ -317,12 +327,115 @@ void addToInterface
|
||||
}
|
||||
|
||||
|
||||
labelList getMinBoundaryValue
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const word& AMIMethod,
|
||||
const labelList& matchPatchIDs,
|
||||
const labelList& cellRegion
|
||||
)
|
||||
{
|
||||
// Neighbour cellRegion.
|
||||
labelList coupledRegion(mesh.nBoundaryFaces());
|
||||
|
||||
forAll(coupledRegion, i)
|
||||
{
|
||||
label celli = mesh.faceOwner()[i+mesh.nInternalFaces()];
|
||||
coupledRegion[i] = cellRegion[celli];
|
||||
}
|
||||
syncTools::swapBoundaryFaceList(mesh, coupledRegion);
|
||||
|
||||
// Add approximate matches
|
||||
forAll(matchPatchIDs, i)
|
||||
{
|
||||
const label patchi = matchPatchIDs[i];
|
||||
const auto& pp = mesh.boundaryMesh()[patchi];
|
||||
|
||||
for (label j = i+1; j < matchPatchIDs.size(); ++j)
|
||||
{
|
||||
const label nbrPatchi = matchPatchIDs[j];
|
||||
const auto& nbrPp = mesh.boundaryMesh()[nbrPatchi];
|
||||
|
||||
// Use AMI to try and find matches
|
||||
auto AMPtr(AMIInterpolation::New(AMIMethod));
|
||||
|
||||
AMPtr->calculate(pp, nbrPp, nullptr);
|
||||
if
|
||||
(
|
||||
gAverage(AMPtr->tgtWeightsSum()) > SMALL
|
||||
|| gAverage(AMPtr->srcWeightsSum()) > SMALL
|
||||
)
|
||||
{
|
||||
// Pull remote data local
|
||||
labelList thisDecomp(pp.size(), labelMax);
|
||||
AMPtr->interpolateToSource
|
||||
(
|
||||
labelList(cellRegion, nbrPp.faceCells()),
|
||||
[]
|
||||
(
|
||||
label& res,
|
||||
const label facei,
|
||||
const label& fld,
|
||||
const scalar& w
|
||||
)
|
||||
{
|
||||
res = min(res, fld);
|
||||
},
|
||||
thisDecomp,
|
||||
thisDecomp // used in case of low-weight-corr
|
||||
);
|
||||
|
||||
// Put thisDecomp into coupledRegion. Check for unmatched faces.
|
||||
forAll(thisDecomp, i)
|
||||
{
|
||||
if (thisDecomp[i] != labelMax)
|
||||
{
|
||||
coupledRegion[pp.offset()+i] = thisDecomp[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
labelList nbrDecomp(nbrPp.size(), labelMax);
|
||||
AMPtr->interpolateToTarget
|
||||
(
|
||||
labelList(cellRegion, pp.faceCells()), //thisDecomp,
|
||||
[]
|
||||
(
|
||||
label& res,
|
||||
const label facei,
|
||||
const label& fld,
|
||||
const scalar& w
|
||||
)
|
||||
{
|
||||
res = min(res, fld);
|
||||
},
|
||||
nbrDecomp,
|
||||
nbrDecomp // used in case of low-weight-corr
|
||||
);
|
||||
|
||||
// Put nbrDecomp into coupledRegion. Check for unmatched faces/
|
||||
forAll(nbrDecomp, i)
|
||||
{
|
||||
if (nbrDecomp[i] != labelMax)
|
||||
{
|
||||
coupledRegion[nbrPp.offset()+i] = nbrDecomp[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return coupledRegion;
|
||||
}
|
||||
|
||||
|
||||
// Get region-region interface name and sizes.
|
||||
// Returns interfaces as straight list for looping in identical order.
|
||||
void getInterfaceSizes
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const bool useFaceZones,
|
||||
const word& AMIMethod,
|
||||
const labelList& matchPatchIDs,
|
||||
const labelList& cellRegion,
|
||||
const wordList& regionNames,
|
||||
|
||||
@ -361,15 +474,16 @@ void getInterfaceSizes
|
||||
// Boundary faces
|
||||
// ~~~~~~~~~~~~~~
|
||||
|
||||
// Neighbour cellRegion.
|
||||
labelList coupledRegion(mesh.nBoundaryFaces());
|
||||
|
||||
forAll(coupledRegion, i)
|
||||
{
|
||||
label celli = mesh.faceOwner()[i+mesh.nInternalFaces()];
|
||||
coupledRegion[i] = cellRegion[celli];
|
||||
}
|
||||
syncTools::swapBoundaryFaceList(mesh, coupledRegion);
|
||||
const labelList coupledRegion
|
||||
(
|
||||
getMinBoundaryValue
|
||||
(
|
||||
mesh,
|
||||
AMIMethod,
|
||||
matchPatchIDs,
|
||||
cellRegion
|
||||
)
|
||||
);
|
||||
|
||||
forAll(coupledRegion, i)
|
||||
{
|
||||
@ -583,6 +697,8 @@ autoPtr<mapPolyMesh> createRegionMesh
|
||||
const labelList& cellRegion,
|
||||
const label regionI,
|
||||
const word& regionName,
|
||||
const word& AMIMethod,
|
||||
const labelList& matchPatchIDs,
|
||||
// Interface info
|
||||
const labelList& interfacePatches,
|
||||
const labelList& faceToInterface,
|
||||
@ -594,15 +710,16 @@ autoPtr<mapPolyMesh> createRegionMesh
|
||||
fvMeshTools::createDummyFvMeshFiles(mesh, regionName, true);
|
||||
|
||||
// Neighbour cellRegion.
|
||||
labelList coupledRegion(mesh.nBoundaryFaces());
|
||||
|
||||
forAll(coupledRegion, i)
|
||||
{
|
||||
label celli = mesh.faceOwner()[i+mesh.nInternalFaces()];
|
||||
coupledRegion[i] = cellRegion[celli];
|
||||
}
|
||||
syncTools::swapBoundaryFaceList(mesh, coupledRegion);
|
||||
|
||||
const labelList coupledRegion
|
||||
(
|
||||
getMinBoundaryValue
|
||||
(
|
||||
mesh,
|
||||
AMIMethod,
|
||||
matchPatchIDs,
|
||||
cellRegion
|
||||
)
|
||||
);
|
||||
|
||||
// Topology change container. Start off from existing mesh.
|
||||
polyTopoChange meshMod(mesh);
|
||||
@ -621,20 +738,16 @@ autoPtr<mapPolyMesh> createRegionMesh
|
||||
labelList exposedPatchIDs(exposedFaces.size());
|
||||
forAll(exposedFaces, i)
|
||||
{
|
||||
label facei = exposedFaces[i];
|
||||
label interfacei = faceToInterface[facei];
|
||||
const label facei = exposedFaces[i];
|
||||
const label interfacei = faceToInterface[facei];
|
||||
|
||||
label ownRegion = cellRegion[mesh.faceOwner()[facei]];
|
||||
label neiRegion = -1;
|
||||
|
||||
if (mesh.isInternalFace(facei))
|
||||
{
|
||||
neiRegion = cellRegion[mesh.faceNeighbour()[facei]];
|
||||
}
|
||||
else
|
||||
{
|
||||
neiRegion = coupledRegion[facei-mesh.nInternalFaces()];
|
||||
}
|
||||
const label ownRegion = cellRegion[mesh.faceOwner()[facei]];
|
||||
const label neiRegion
|
||||
(
|
||||
mesh.isInternalFace(facei)
|
||||
? cellRegion[mesh.faceNeighbour()[facei]]
|
||||
: coupledRegion[facei-mesh.nInternalFaces()]
|
||||
);
|
||||
|
||||
|
||||
// Check which side is being kept - determines which of the two
|
||||
@ -681,6 +794,62 @@ autoPtr<mapPolyMesh> createRegionMesh
|
||||
meshMod
|
||||
);
|
||||
|
||||
|
||||
// Do re-patching on non-removed cells ourselves. These are not exposed
|
||||
// faces but are boundary faces
|
||||
for (label bFacei = 0; bFacei < mesh.nBoundaryFaces(); bFacei++)
|
||||
{
|
||||
const label facei = mesh.nInternalFaces()+bFacei;
|
||||
|
||||
if (!meshMod.faceRemoved(facei))
|
||||
{
|
||||
const label interfacei = faceToInterface[facei];
|
||||
const label ownRegion = cellRegion[mesh.faceOwner()[facei]];
|
||||
const label neiRegion = coupledRegion[bFacei];
|
||||
|
||||
label exposedPatchID = -1;
|
||||
if (ownRegion == regionI)
|
||||
{
|
||||
if (regionI < neiRegion)
|
||||
{
|
||||
exposedPatchID = interfacePatches[interfacei];
|
||||
}
|
||||
else if (regionI > neiRegion)
|
||||
{
|
||||
exposedPatchID = interfacePatches[interfacei]+1;
|
||||
}
|
||||
}
|
||||
else if (neiRegion == regionI)
|
||||
{
|
||||
if (regionI < ownRegion)
|
||||
{
|
||||
exposedPatchID = interfacePatches[interfacei];
|
||||
}
|
||||
else if (regionI > ownRegion)
|
||||
{
|
||||
exposedPatchID = interfacePatches[interfacei]+1;
|
||||
}
|
||||
}
|
||||
|
||||
if (exposedPatchID != -1)
|
||||
{
|
||||
// In-place modify the patch
|
||||
DynamicList<label>& patchID =
|
||||
const_cast<DynamicList<label>&>(meshMod.region());
|
||||
|
||||
//Pout<< "For face:" << facei
|
||||
// << " on interface:" << interfacei
|
||||
// << " modifying from own:" << meshMod.faceOwner()[facei]
|
||||
// << " nei:" << meshMod.faceNeighbour()[facei]
|
||||
// << " verts:" << meshMod.faces()[facei]
|
||||
// << " patch " << patchID[facei]
|
||||
// << " to " << exposedPatchID << endl;
|
||||
patchID[facei] = exposedPatchID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
autoPtr<mapPolyMesh> map = meshMod.makeMesh
|
||||
(
|
||||
newMesh,
|
||||
@ -705,6 +874,8 @@ void createAndWriteRegion
|
||||
const labelList& cellRegion,
|
||||
const wordList& regionNames,
|
||||
const bool prefixRegion,
|
||||
const word& AMIMethod,
|
||||
const labelList& matchPatchIDs,
|
||||
const labelList& faceToInterface,
|
||||
const labelList& interfacePatches,
|
||||
const label regionI,
|
||||
@ -721,6 +892,8 @@ void createAndWriteRegion
|
||||
cellRegion,
|
||||
regionI,
|
||||
regionNames[regionI],
|
||||
AMIMethod,
|
||||
matchPatchIDs,
|
||||
interfacePatches,
|
||||
faceToInterface,
|
||||
newMesh
|
||||
@ -1019,6 +1192,7 @@ labelList addRegionPatches
|
||||
const wordList& regionNames,
|
||||
const edgeList& interfaces,
|
||||
const List<Pair<word>>& interfaceNames
|
||||
//const List<mappedPatchBase::sampleMode>& interfaceModes
|
||||
)
|
||||
{
|
||||
Info<< nl << "Adding patches" << nl << endl;
|
||||
@ -1042,7 +1216,7 @@ labelList addRegionPatches
|
||||
0, // overridden
|
||||
0, // overridden
|
||||
regionNames[e[1]], // sampleRegion
|
||||
mappedPatchBase::NEARESTPATCHFACE,
|
||||
mappedPatchBase::NEARESTPATCHFACE, //interfaceModes[interI]
|
||||
names[1], // samplePatch
|
||||
point::zero, // offset
|
||||
mesh.boundaryMesh()
|
||||
@ -1064,7 +1238,7 @@ labelList addRegionPatches
|
||||
0,
|
||||
0,
|
||||
regionNames[e[0]], // sampleRegion
|
||||
mappedPatchBase::NEARESTPATCHFACE,
|
||||
mappedPatchBase::NEARESTPATCHFACE, //interfaceModes[interI]
|
||||
names[0],
|
||||
point::zero, // offset
|
||||
mesh.boundaryMesh()
|
||||
@ -1455,6 +1629,7 @@ int main(int argc, char *argv[])
|
||||
"Split mesh into multiple regions (detected by walking across faces)"
|
||||
);
|
||||
#include "addRegionOption.H"
|
||||
|
||||
#include "addOverwriteOption.H"
|
||||
argList::addBoolOption
|
||||
(
|
||||
@ -1521,6 +1696,18 @@ int main(int argc, char *argv[])
|
||||
"useFaceZones",
|
||||
"Use faceZones to patch inter-region faces instead of single patch"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"autoPatch",
|
||||
"lists of patches",
|
||||
"Find overlapping faces to auto-generate interface patches"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"AMIMethod",
|
||||
"word",
|
||||
"type of AMI matching method"
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"prefixRegion",
|
||||
@ -1533,6 +1720,12 @@ int main(int argc, char *argv[])
|
||||
#include "createTime.H"
|
||||
#include "createNamedMesh.H"
|
||||
|
||||
|
||||
// Note: could try to read multiple meshes and merge into one before
|
||||
// operation but this would give problems with unique prefixes:
|
||||
// - patches get renamed. So patchFields would need to be renamed.
|
||||
// - what about e.g. 'samplePatch' in mapped patches?
|
||||
|
||||
const word oldInstance = mesh.pointsInstance();
|
||||
|
||||
word blockedFacesName;
|
||||
@ -1556,6 +1749,14 @@ int main(int argc, char *argv[])
|
||||
const bool useFaceZones = args.found("useFaceZones");
|
||||
const bool prefixRegion = args.found("prefixRegion");
|
||||
|
||||
labelList matchPatchIDs;
|
||||
word AMIMethod(faceAreaWeightAMI2D::typeName);
|
||||
if (args.found("autoPatch"))
|
||||
{
|
||||
const wordRes patchNames(args.getList<wordRe>("autoPatch"));
|
||||
matchPatchIDs = mesh.boundaryMesh().indices(patchNames);
|
||||
args.readIfPresent("AMIMethod", AMIMethod);
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
@ -1585,6 +1786,13 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
|
||||
if (matchPatchIDs.size())
|
||||
{
|
||||
Info<< "Auto-detecting matching faces out of patches "
|
||||
<< UIndirectList<word>(mesh.boundaryMesh().names(), matchPatchIDs)
|
||||
<< nl << endl;
|
||||
}
|
||||
|
||||
|
||||
if (insidePoint && largestOnly)
|
||||
{
|
||||
@ -1652,8 +1860,8 @@ int main(int argc, char *argv[])
|
||||
<< " This requires all"
|
||||
<< " cells to be in one and only one cellZone." << nl << endl;
|
||||
|
||||
// Collect sets of zones into clusters. If no cluster is just an identity
|
||||
// list (cluster 0 is cellZone 0 etc.)
|
||||
// Collect sets of zones into clusters. If no cluster is just an
|
||||
// identity list (cluster 0 is cellZone 0 etc.)
|
||||
wordList clusterNames;
|
||||
labelListList clusterToZones;
|
||||
labelList zoneToCluster;
|
||||
@ -1829,7 +2037,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
label ownCluster = clusterID[mesh.faceOwner()[facei]];
|
||||
label neiCluster = clusterID[mesh.faceNeighbour()[facei]];
|
||||
|
||||
|
||||
if (ownCluster != neiCluster)
|
||||
{
|
||||
blockedFace[facei] = true;
|
||||
@ -1968,6 +2176,8 @@ int main(int argc, char *argv[])
|
||||
(
|
||||
mesh,
|
||||
useFaceZones,
|
||||
AMIMethod,
|
||||
matchPatchIDs,
|
||||
cellRegion,
|
||||
regionNames,
|
||||
|
||||
@ -2147,6 +2357,7 @@ int main(int argc, char *argv[])
|
||||
regionNames,
|
||||
interfaces,
|
||||
interfaceNames
|
||||
//interfaceModes
|
||||
)
|
||||
);
|
||||
|
||||
@ -2199,6 +2410,8 @@ int main(int argc, char *argv[])
|
||||
cellRegion,
|
||||
regionNames,
|
||||
prefixRegion,
|
||||
AMIMethod,
|
||||
matchPatchIDs,
|
||||
faceToInterface,
|
||||
interfacePatches,
|
||||
regionI,
|
||||
@ -2220,6 +2433,8 @@ int main(int argc, char *argv[])
|
||||
cellRegion,
|
||||
regionNames,
|
||||
prefixRegion,
|
||||
AMIMethod,
|
||||
matchPatchIDs,
|
||||
faceToInterface,
|
||||
interfacePatches,
|
||||
regionI,
|
||||
@ -2241,6 +2456,8 @@ int main(int argc, char *argv[])
|
||||
cellRegion,
|
||||
regionNames,
|
||||
prefixRegion,
|
||||
AMIMethod,
|
||||
matchPatchIDs,
|
||||
faceToInterface,
|
||||
interfacePatches,
|
||||
regionI,
|
||||
|
||||
@ -47,6 +47,9 @@ pointSync false;
|
||||
// Patches to create.
|
||||
patches
|
||||
(
|
||||
// Example of creating cyclic patch pair
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
{
|
||||
// Name of new patch
|
||||
name cyc_half0;
|
||||
@ -70,10 +73,17 @@ patches
|
||||
//matchTolerance 1E-2;
|
||||
}
|
||||
|
||||
// How to construct: either from 'patches' or 'set'
|
||||
// How to select the faces:
|
||||
// - set : specify faceSet in 'set'
|
||||
// - patches : specify names in 'patches'
|
||||
// - autoPatch : attempts automatic patching of the specified
|
||||
// candidates in 'patches'.
|
||||
// - single region : match in the region itself
|
||||
// - multi regions : match in between regions only
|
||||
constructFrom patches;
|
||||
|
||||
// If constructFrom = patches : names of patches. Wildcards allowed.
|
||||
// If constructFrom = patches or autoPatch: names of patches.
|
||||
// Wildcards&patchGroups allowed.
|
||||
patches (periodic1);
|
||||
|
||||
// If constructFrom = set : name of faceSet
|
||||
@ -98,15 +108,66 @@ patches
|
||||
// separationVector (1 0 0);
|
||||
}
|
||||
|
||||
// How to construct: either from 'patches' or 'set'
|
||||
// How to select the faces:
|
||||
// - set : specify faceSet in 'set'
|
||||
// - patches : specify names in 'patches'
|
||||
// - autoPatch : attempts automatic patching of the specified
|
||||
// candidates in 'patches'.
|
||||
// - single region : match in the region itself
|
||||
// - multi regions : match in between regions only
|
||||
constructFrom patches;
|
||||
|
||||
// If constructFrom = patches : names of patches. Wildcards allowed.
|
||||
// If constructFrom = patches or autoPatch: names of patches.
|
||||
// Wildcards&patchGroups allowed.
|
||||
patches (periodic2);
|
||||
|
||||
// If constructFrom = set : name of faceSet
|
||||
set f0;
|
||||
}
|
||||
|
||||
|
||||
// Example of creating mapped patches using geometric matching
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
{
|
||||
// Name of new patch
|
||||
name solid;
|
||||
|
||||
// Dictionary to construct new patch from
|
||||
patchInfo
|
||||
{
|
||||
type mappedPatch;
|
||||
sampleMode nearestPatchFaceAMI;
|
||||
AMIMethod faceAreaWeightAMI;
|
||||
|
||||
// Overwritten
|
||||
//sampleRegion otherRegion;
|
||||
//samplePatch otherPatch;
|
||||
|
||||
//- Optional override of added patchfields. If not specified
|
||||
// any added patchfields are of type calculated.
|
||||
patchFields
|
||||
{
|
||||
T
|
||||
{
|
||||
type fixedValue;
|
||||
value uniform 300;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// How to select the faces:
|
||||
// - set : specify faceSet in 'set'
|
||||
// - patches : specify names in 'patches'
|
||||
// - autoPatch : attempts automatic patching of the specified
|
||||
// candidates in 'patches'.
|
||||
// - single region : match in the region itself
|
||||
// - multi regions : match in between regions only
|
||||
constructFrom autoPatch;
|
||||
|
||||
// If constructFrom = patches or autoPatch: names of patches.
|
||||
// Wildcards&patchGroups allowed.
|
||||
patches (coupling_group);
|
||||
}
|
||||
);
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||
Copyright (C) 2015-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -1354,7 +1354,9 @@ void Foam::argList::parse
|
||||
|
||||
// Disable any parallel comms happening inside the fileHandler
|
||||
// since we are on master. This can happen e.g. inside
|
||||
// the masterUncollated/collated handler.
|
||||
// the masterUncollated/collated handler. Note that we
|
||||
// also have to protect the actual dictionary parsing since
|
||||
// it might trigger file access (e.g. #include, #codeStream)
|
||||
const bool oldParRun = Pstream::parRun(false);
|
||||
|
||||
autoPtr<ISstream> dictStream
|
||||
@ -1362,8 +1364,6 @@ void Foam::argList::parse
|
||||
fileHandler().NewIFstream(source)
|
||||
);
|
||||
|
||||
Pstream::parRun(oldParRun); // Restore parallel state
|
||||
|
||||
if (dictStream && dictStream->good())
|
||||
{
|
||||
dictionary decompDict(*dictStream);
|
||||
@ -1412,6 +1412,8 @@ void Foam::argList::parse
|
||||
}
|
||||
}
|
||||
|
||||
Pstream::parRun(oldParRun); // Restore parallel state
|
||||
|
||||
if (Pstream::nProcs() == 1)
|
||||
{
|
||||
Warning
|
||||
|
||||
@ -798,20 +798,6 @@ bool Foam::AMIInterpolation::calculate
|
||||
}
|
||||
|
||||
|
||||
bool Foam::AMIInterpolation::calculate
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const label srcPatchi,
|
||||
const primitivePatch& srcPatch,
|
||||
const label tgtPatchi,
|
||||
const primitivePatch& tgtPatch,
|
||||
const autoPtr<searchableSurface>& surfPtr
|
||||
)
|
||||
{
|
||||
return calculate(srcPatch, tgtPatch, surfPtr);
|
||||
}
|
||||
|
||||
|
||||
void Foam::AMIInterpolation::reset
|
||||
(
|
||||
autoPtr<mapDistribute>&& srcToTgtMap,
|
||||
|
||||
@ -73,8 +73,6 @@ SourceFiles
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
class polyMesh;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class AMIInterpolation Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -200,6 +198,15 @@ protected:
|
||||
) const;
|
||||
|
||||
|
||||
// Access
|
||||
|
||||
//- Return the orginal src patch with optionally updated points
|
||||
inline const primitivePatch& srcPatch0() const;
|
||||
|
||||
//- Return the orginal tgt patch with optionally updated points
|
||||
inline const primitivePatch& tgtPatch0() const;
|
||||
|
||||
|
||||
// Evaluation
|
||||
|
||||
//- Normalise the (area) weights - suppresses numerical error in
|
||||
@ -341,15 +348,6 @@ public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
//- Return the orginal src patch with optionally updated points
|
||||
inline const primitivePatch& srcPatch0() const;
|
||||
|
||||
//- Return the orginal tgt patch with optionally updated points
|
||||
inline const primitivePatch& tgtPatch0() const;
|
||||
|
||||
|
||||
// Access
|
||||
|
||||
//- Access to the up-to-date flag
|
||||
@ -448,12 +446,6 @@ public:
|
||||
//- patch weights (i.e. the sum before normalisation)
|
||||
inline const scalarField& tgtWeightsSum() const;
|
||||
|
||||
//- Return const access to target patch face centroids
|
||||
inline const pointListList& tgtCentroids() const;
|
||||
|
||||
//- Return access to target patch face centroids
|
||||
inline pointListList& tgtCentroids();
|
||||
|
||||
//- Return access to normalisation factor of target
|
||||
//- patch weights (i.e. the sum before normalisation)
|
||||
inline scalarField& tgtWeightsSum();
|
||||
@ -474,17 +466,6 @@ public:
|
||||
const autoPtr<searchableSurface>& surfPtr = nullptr
|
||||
);
|
||||
|
||||
//- Update addressing, weights and (optional) centroids
|
||||
virtual bool calculate
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const label srcPatchi,
|
||||
const primitivePatch& srcPatch,
|
||||
const label tgtPatchi,
|
||||
const primitivePatch& tgtPatch,
|
||||
const autoPtr<searchableSurface>& surfPtr = nullptr
|
||||
);
|
||||
|
||||
//- Set the maps, addresses and weights from an external source
|
||||
void reset
|
||||
(
|
||||
|
||||
@ -222,18 +222,6 @@ inline const Foam::scalarField& Foam::AMIInterpolation::tgtWeightsSum() const
|
||||
}
|
||||
|
||||
|
||||
inline const Foam::pointListList& Foam::AMIInterpolation::tgtCentroids() const
|
||||
{
|
||||
return tgtCentroids_;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::pointListList& Foam::AMIInterpolation::tgtCentroids()
|
||||
{
|
||||
return tgtCentroids_;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::scalarField& Foam::AMIInterpolation::tgtWeightsSum()
|
||||
{
|
||||
return tgtWeightsSum_;
|
||||
|
||||
@ -1,52 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type, class PrimitivePatchType>
|
||||
Foam::Ostream& Foam::operator<<
|
||||
(
|
||||
Foam::Ostream& os,
|
||||
const Foam::edgeTopoDistancesData<Type, PrimitivePatchType>& wDist
|
||||
)
|
||||
{
|
||||
return os << wDist.distance_ << token::SPACE << wDist.data_;
|
||||
}
|
||||
|
||||
|
||||
template<class Type, class PrimitivePatchType>
|
||||
Foam::Istream& Foam::operator>>
|
||||
(
|
||||
Foam::Istream& is,
|
||||
Foam::edgeTopoDistancesData<Type, PrimitivePatchType>& wDist
|
||||
)
|
||||
{
|
||||
return is >> wDist.distance_ >> wDist.data_;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,261 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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::edgeTopoDistancesData
|
||||
|
||||
Description
|
||||
For use with PatchEdgeFaceWave. Determines topological distance to
|
||||
starting edges. Templated on passive transported data.
|
||||
|
||||
SourceFiles
|
||||
edgeTopoDistancesDataI.H
|
||||
edgeTopoDistancesData.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef edgeTopoDistancesData_H
|
||||
#define edgeTopoDistancesData_H
|
||||
|
||||
#include "point.H"
|
||||
#include "tensor.H"
|
||||
#include "indirectPrimitivePatch.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward Declarations
|
||||
class polyPatch;
|
||||
class polyMesh;
|
||||
template<class Type, class PrimitivePatchType>
|
||||
class edgeTopoDistancesData;
|
||||
|
||||
template<class Type, class PrimitivePatchType>
|
||||
Istream& operator>>
|
||||
(
|
||||
Istream&,
|
||||
edgeTopoDistancesData<Type, PrimitivePatchType>&
|
||||
);
|
||||
template<class Type, class PrimitivePatchType>
|
||||
Ostream& operator<<
|
||||
(
|
||||
Ostream&,
|
||||
const edgeTopoDistancesData<Type, PrimitivePatchType>&
|
||||
);
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class edgeTopoDistancesData Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class Type, class PrimitivePatchType = indirectPrimitivePatch>
|
||||
class edgeTopoDistancesData
|
||||
{
|
||||
public:
|
||||
|
||||
//- Class used to pass additional data in
|
||||
struct trackData
|
||||
{
|
||||
//- Max number of entries stored per element
|
||||
label n_;
|
||||
};
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
//- Distance (up to size n_)
|
||||
labelList distance_;
|
||||
|
||||
//- Starting data (up to size n_)
|
||||
List<Type> data_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
typedef Type dataType;
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null with null constructor for distance and data
|
||||
inline edgeTopoDistancesData();
|
||||
|
||||
//- Construct from distance, data
|
||||
inline edgeTopoDistancesData
|
||||
(
|
||||
const labelList& distance,
|
||||
const List<Type>& data
|
||||
);
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
inline const labelList& distance() const
|
||||
{
|
||||
return distance_;
|
||||
}
|
||||
|
||||
inline const List<Type>& data() const
|
||||
{
|
||||
return data_;
|
||||
}
|
||||
|
||||
|
||||
// Needed by PatchEdgeFaceWave
|
||||
|
||||
//- Check whether origin has been changed at all or
|
||||
// still contains original (invalid) value.
|
||||
template<class TrackingData>
|
||||
inline bool valid(TrackingData& td) const;
|
||||
|
||||
//- Apply rotation matrix
|
||||
template<class TrackingData>
|
||||
inline void transform
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const PrimitivePatchType& patch,
|
||||
const tensor& rotTensor,
|
||||
const scalar tol,
|
||||
TrackingData& td
|
||||
);
|
||||
|
||||
//- Influence of face on edge
|
||||
template<class TrackingData>
|
||||
inline bool updateEdge
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const PrimitivePatchType& patch,
|
||||
const label edgeI,
|
||||
const label facei,
|
||||
const edgeTopoDistancesData<Type, PrimitivePatchType>& faceInfo,
|
||||
const scalar tol,
|
||||
TrackingData& td
|
||||
);
|
||||
|
||||
//- New information for edge (from e.g. coupled edge)
|
||||
template<class TrackingData>
|
||||
inline bool updateEdge
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const PrimitivePatchType& patch,
|
||||
const edgeTopoDistancesData<Type, PrimitivePatchType>& edgeInfo,
|
||||
const bool sameOrientation,
|
||||
const scalar tol,
|
||||
TrackingData& td
|
||||
);
|
||||
|
||||
//- Influence of edge on face.
|
||||
template<class TrackingData>
|
||||
inline bool updateFace
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const PrimitivePatchType& patch,
|
||||
const label facei,
|
||||
const label edgeI,
|
||||
const edgeTopoDistancesData<Type, PrimitivePatchType>& edgeInfo,
|
||||
const scalar tol,
|
||||
TrackingData& td
|
||||
);
|
||||
|
||||
//- Same (like operator==)
|
||||
template<class TrackingData>
|
||||
inline bool equal
|
||||
(
|
||||
const edgeTopoDistancesData<Type, PrimitivePatchType>&,
|
||||
TrackingData&
|
||||
) const;
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
// Needed for List IO
|
||||
inline bool operator==
|
||||
(
|
||||
const edgeTopoDistancesData<Type, PrimitivePatchType>&
|
||||
) const;
|
||||
inline bool operator!=
|
||||
(
|
||||
const edgeTopoDistancesData<Type, PrimitivePatchType>&
|
||||
) const;
|
||||
|
||||
|
||||
// IOstream Operators
|
||||
|
||||
friend Ostream& operator<< <Type, PrimitivePatchType>
|
||||
(
|
||||
Ostream&,
|
||||
const edgeTopoDistancesData<Type, PrimitivePatchType>&
|
||||
);
|
||||
friend Istream& operator>> <Type, PrimitivePatchType>
|
||||
(
|
||||
Istream&,
|
||||
edgeTopoDistancesData<Type, PrimitivePatchType>&
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * Traits * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
//- Data are contiguous if data type is contiguous
|
||||
template<class Type, class PrimitivePatchType>
|
||||
struct is_contiguous<edgeTopoDistancesData<Type, PrimitivePatchType>> :
|
||||
std::false_type {};
|
||||
|
||||
//- Data are contiguous label if data type is label
|
||||
template<class Type, class PrimitivePatchType>
|
||||
struct is_contiguous_label<edgeTopoDistancesData<Type, PrimitivePatchType>> :
|
||||
std::false_type {};
|
||||
|
||||
//- Data are contiguous scalar if data type is scalar
|
||||
template<class Type, class PrimitivePatchType>
|
||||
struct is_contiguous_scalar<edgeTopoDistancesData<Type, PrimitivePatchType>> :
|
||||
std::false_type {};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "edgeTopoDistancesData.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "edgeTopoDistancesDataI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,224 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 "polyMesh.H"
|
||||
#include "transform.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type, class PrimitivePatchType>
|
||||
inline
|
||||
Foam::edgeTopoDistancesData<Type, PrimitivePatchType>::edgeTopoDistancesData()
|
||||
:
|
||||
distance_(),
|
||||
data_()
|
||||
{}
|
||||
|
||||
|
||||
template<class Type, class PrimitivePatchType>
|
||||
inline
|
||||
Foam::edgeTopoDistancesData<Type, PrimitivePatchType>::edgeTopoDistancesData
|
||||
(
|
||||
const labelList& distance,
|
||||
const List<Type>& data
|
||||
)
|
||||
:
|
||||
distance_(distance),
|
||||
data_(data)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type, class PrimitivePatchType>
|
||||
template<class TrackingData>
|
||||
inline bool Foam::edgeTopoDistancesData<Type, PrimitivePatchType>::valid
|
||||
(
|
||||
TrackingData& td
|
||||
) const
|
||||
{
|
||||
return distance_.size();
|
||||
}
|
||||
|
||||
|
||||
template<class Type, class PrimitivePatchType>
|
||||
template<class TrackingData>
|
||||
inline void Foam::edgeTopoDistancesData<Type, PrimitivePatchType>::transform
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const PrimitivePatchType& patch,
|
||||
const tensor& rotTensor,
|
||||
const scalar tol,
|
||||
TrackingData& td
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
template<class Type, class PrimitivePatchType>
|
||||
template<class TrackingData>
|
||||
inline bool Foam::edgeTopoDistancesData<Type, PrimitivePatchType>::updateEdge
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const PrimitivePatchType& patch,
|
||||
const label edgeI,
|
||||
const label facei,
|
||||
const edgeTopoDistancesData<Type, PrimitivePatchType>& faceInfo,
|
||||
const scalar tol,
|
||||
TrackingData& td
|
||||
)
|
||||
{
|
||||
// From face to edge
|
||||
|
||||
if (distance_.size() >= td.n_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const label oldSize = data_.size();
|
||||
|
||||
forAll(faceInfo.data_, i)
|
||||
{
|
||||
const auto& d = faceInfo.data_[i];
|
||||
|
||||
if (!data_.found(d))
|
||||
{
|
||||
data_.append(d);
|
||||
distance_.append(faceInfo.distance_[i] + 1);
|
||||
}
|
||||
}
|
||||
return data_.size() > oldSize;
|
||||
}
|
||||
|
||||
|
||||
template<class Type, class PrimitivePatchType>
|
||||
template<class TrackingData>
|
||||
inline bool Foam::edgeTopoDistancesData<Type, PrimitivePatchType>::updateEdge
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const PrimitivePatchType& patch,
|
||||
const edgeTopoDistancesData<Type, PrimitivePatchType>& edgeInfo,
|
||||
const bool sameOrientation,
|
||||
const scalar tol,
|
||||
TrackingData& td
|
||||
)
|
||||
{
|
||||
// From edge to edge (e.g. coupled edges)
|
||||
|
||||
if (distance_.size() >= td.n_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const label oldSize = data_.size();
|
||||
|
||||
forAll(edgeInfo.data_, i)
|
||||
{
|
||||
const auto& d = edgeInfo.data_[i];
|
||||
|
||||
if (!data_.found(d))
|
||||
{
|
||||
data_.append(d);
|
||||
distance_.append(edgeInfo.distance_[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return data_.size() > oldSize;
|
||||
}
|
||||
|
||||
|
||||
template<class Type, class PrimitivePatchType>
|
||||
template<class TrackingData>
|
||||
inline bool Foam::edgeTopoDistancesData<Type, PrimitivePatchType>::updateFace
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const PrimitivePatchType& patch,
|
||||
const label facei,
|
||||
const label edgeI,
|
||||
const edgeTopoDistancesData<Type, PrimitivePatchType>& edgeInfo,
|
||||
const scalar tol,
|
||||
TrackingData& td
|
||||
)
|
||||
{
|
||||
// From edge to edge (e.g. coupled edges)
|
||||
|
||||
if (distance_.size() >= td.n_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const label oldSize = data_.size();
|
||||
|
||||
forAll(edgeInfo.data_, i)
|
||||
{
|
||||
const auto& d = edgeInfo.data_[i];
|
||||
|
||||
if (!data_.found(d))
|
||||
{
|
||||
data_.append(d);
|
||||
distance_.append(edgeInfo.distance_[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return data_.size() > oldSize;
|
||||
}
|
||||
|
||||
|
||||
template<class Type, class PrimitivePatchType>
|
||||
template<class TrackingData>
|
||||
inline bool Foam::edgeTopoDistancesData<Type, PrimitivePatchType>::equal
|
||||
(
|
||||
const edgeTopoDistancesData<Type, PrimitivePatchType>& rhs,
|
||||
TrackingData& td
|
||||
) const
|
||||
{
|
||||
return operator==(rhs);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type, class PrimitivePatchType>
|
||||
inline bool Foam::edgeTopoDistancesData<Type, PrimitivePatchType>::operator==
|
||||
(
|
||||
const Foam::edgeTopoDistancesData<Type, PrimitivePatchType>& rhs
|
||||
) const
|
||||
{
|
||||
return distance() == rhs.distance() && data() == rhs.data();
|
||||
}
|
||||
|
||||
|
||||
template<class Type, class PrimitivePatchType>
|
||||
inline bool Foam::edgeTopoDistancesData<Type, PrimitivePatchType>::operator!=
|
||||
(
|
||||
const Foam::edgeTopoDistancesData<Type, PrimitivePatchType>& rhs
|
||||
) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,578 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 "lowWeightCorrection.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "edgeTopoDistancesData.H"
|
||||
#include "PatchEdgeFaceWave.H"
|
||||
#include "OBJstream.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(lowWeightCorrection, 0);
|
||||
addToRunTimeSelectionTable(AMIInterpolation, lowWeightCorrection, dict);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
AMIInterpolation,
|
||||
lowWeightCorrection,
|
||||
component
|
||||
);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::lowWeightCorrection::findNearest
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const primitivePatch& pp,
|
||||
const globalIndex& globalFaces,
|
||||
const labelList& uncoveredFaces,
|
||||
labelListList& nearestCoveredFaces
|
||||
) const
|
||||
{
|
||||
// Data on all edges and faces
|
||||
typedef edgeTopoDistancesData<label, primitivePatch> Type;
|
||||
|
||||
List<Type> allEdgeInfo(pp.nEdges());
|
||||
List<Type> allFaceInfo(pp.size());
|
||||
|
||||
|
||||
// Seed all covered faces
|
||||
bitSet isUncovered(pp.size(), uncoveredFaces);
|
||||
|
||||
DynamicList<label> changedEdges(pp.nEdges());
|
||||
DynamicList<Type> changedInfo(pp.nEdges());
|
||||
forAll(pp, facei)
|
||||
{
|
||||
if (!isUncovered(facei))
|
||||
{
|
||||
const labelList& fEdges = pp.faceEdges()[facei];
|
||||
|
||||
const Type seed
|
||||
(
|
||||
labelList(1, 0),
|
||||
labelList(1, globalFaces.toGlobal(facei))
|
||||
);
|
||||
|
||||
allFaceInfo[facei] = seed;
|
||||
for (const label edgei : fEdges)
|
||||
{
|
||||
changedEdges.append(edgei);
|
||||
changedInfo.append(seed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Walk
|
||||
Type::trackData td;
|
||||
td.n_ = nDonors_;
|
||||
|
||||
PatchEdgeFaceWave
|
||||
<
|
||||
primitivePatch,
|
||||
Type,
|
||||
Type::trackData
|
||||
> calc
|
||||
(
|
||||
mesh,
|
||||
pp,
|
||||
changedEdges,
|
||||
changedInfo,
|
||||
allEdgeInfo,
|
||||
allFaceInfo,
|
||||
0, //returnReduce(pp.nEdges(), sumOp<label>())
|
||||
td
|
||||
);
|
||||
calc.iterate(nIters_); // should be enough iterations?
|
||||
|
||||
|
||||
nearestCoveredFaces.setSize(uncoveredFaces.size());
|
||||
forAll(uncoveredFaces, i)
|
||||
{
|
||||
const label facei = uncoveredFaces[i];
|
||||
if (allFaceInfo[facei].valid(calc.data()))
|
||||
{
|
||||
// Collect donor faces
|
||||
nearestCoveredFaces[i] = allFaceInfo[facei].data();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::lowWeightCorrection::calculateStencil
|
||||
(
|
||||
const label facei,
|
||||
const point& sample,
|
||||
const labelList& covered,
|
||||
const labelListList& stencilAddressing,
|
||||
|
||||
labelListList& addressing,
|
||||
scalarListList& weights,
|
||||
scalarField& sumWeights,
|
||||
const pointField& faceCentres
|
||||
) const
|
||||
{
|
||||
addressing[facei].clear();
|
||||
weights[facei].clear();
|
||||
sumWeights[facei] = Zero;
|
||||
|
||||
// The (uncovered) facei has local donors
|
||||
|
||||
// Add the donors
|
||||
for (const label coveredSlot : covered)
|
||||
{
|
||||
// Get remote slots for the local covered face
|
||||
const labelList& slots = stencilAddressing[coveredSlot];
|
||||
|
||||
for (const label sloti : slots)
|
||||
{
|
||||
const point& donorPt = faceCentres[sloti];
|
||||
const label index = addressing[facei].find(sloti);
|
||||
if (index == -1)
|
||||
{
|
||||
addressing[facei].append(sloti);
|
||||
weights[facei].append(1.0/mag(sample-donorPt));
|
||||
}
|
||||
else
|
||||
{
|
||||
weights[facei][index] += 1.0/mag(sample-donorPt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scalarList& wghts = weights[facei];
|
||||
const scalar w = sum(wghts);
|
||||
forAll(wghts, i)
|
||||
{
|
||||
wghts[i] /= w;
|
||||
}
|
||||
sumWeights[facei] = 1.0;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::lowWeightCorrection::lowWeightCorrection
|
||||
(
|
||||
const dictionary& dict,
|
||||
const bool reverseTarget
|
||||
)
|
||||
:
|
||||
AMIInterpolation(dict, reverseTarget),
|
||||
lowWeightCorrection_(dict.get<scalar>("lowWeightCorrection")),
|
||||
nDonors_(dict.get<label>("nDonors")),
|
||||
nIters_(dict.get<label>("nIters")),
|
||||
AMIPtr_
|
||||
(
|
||||
AMIInterpolation::New
|
||||
(
|
||||
dict.subDict(type() + "Coeffs").get<word>("AMIMethod"),
|
||||
dict.subDict(type() + "Coeffs"),
|
||||
reverseTarget
|
||||
)
|
||||
)
|
||||
{
|
||||
if (nDonors_ <= 0 || nIters_ <= 0)
|
||||
{
|
||||
WarningInFunction << "Disabled low-weight correction. Using "
|
||||
<< AMIPtr_->type() << " AMI interpolation" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::lowWeightCorrection::lowWeightCorrection
|
||||
(
|
||||
const bool requireMatch,
|
||||
const bool reverseTarget,
|
||||
const scalar lowWeightCorrection
|
||||
)
|
||||
:
|
||||
AMIInterpolation(requireMatch, reverseTarget, lowWeightCorrection),
|
||||
lowWeightCorrection_(-1),
|
||||
nDonors_(0),
|
||||
nIters_(0),
|
||||
AMIPtr_()
|
||||
{}
|
||||
|
||||
|
||||
Foam::lowWeightCorrection::lowWeightCorrection(const lowWeightCorrection& ami)
|
||||
:
|
||||
AMIInterpolation(ami),
|
||||
lowWeightCorrection_(ami.lowWeightCorrection_),
|
||||
nDonors_(ami.nDonors_),
|
||||
nIters_(ami.nIters_),
|
||||
AMIPtr_(ami.AMIPtr_.clone())
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::lowWeightCorrection::calculate
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const label srcPatchi,
|
||||
const primitivePatch& srcPatch,
|
||||
const label tgtPatchi,
|
||||
const primitivePatch& tgtPatch,
|
||||
const autoPtr<searchableSurface>& surfPtr
|
||||
)
|
||||
{
|
||||
if (upToDate_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
AMIInterpolation::calculate(srcPatch, tgtPatch, surfPtr);
|
||||
AMIPtr_->calculate
|
||||
(
|
||||
mesh,
|
||||
srcPatchi,
|
||||
srcPatch,
|
||||
tgtPatchi,
|
||||
tgtPatch,
|
||||
surfPtr
|
||||
);
|
||||
|
||||
// Take over AMI data
|
||||
// ~~~~~~~~~~~~~~~~~~
|
||||
|
||||
upToDate_ = AMIPtr_->upToDate();
|
||||
// distributed / singlePatchProc
|
||||
singlePatchProc_ = AMIPtr_->singlePatchProc();;
|
||||
|
||||
// Source patch
|
||||
srcMagSf_ = AMIPtr_->srcMagSf();
|
||||
srcAddress_ = AMIPtr_->srcAddress();
|
||||
srcWeights_ = AMIPtr_->srcWeights();
|
||||
srcWeightsSum_ = AMIPtr_->srcWeightsSum();
|
||||
srcCentroids_ = AMIPtr_->srcCentroids();
|
||||
//TBD: srcPatchPts_ = AMIPtr_->srcPatchPts();
|
||||
tsrcPatch0_ = AMIPtr_->srcPatch0();
|
||||
if (AMIPtr_->distributed())
|
||||
{
|
||||
srcMapPtr_.reset(new mapDistribute(AMIPtr_->srcMap()));
|
||||
}
|
||||
|
||||
// Target
|
||||
tgtMagSf_ = AMIPtr_->tgtMagSf();
|
||||
tgtAddress_ = AMIPtr_->tgtAddress();
|
||||
tgtWeights_ = AMIPtr_->tgtWeights();
|
||||
tgtWeightsSum_ = AMIPtr_->tgtWeightsSum();
|
||||
tgtCentroids_ = AMIPtr_->tgtCentroids();
|
||||
//TBD: tgtPatchPts_ = AMIPtr_->tgtPatchPts();
|
||||
ttgtPatch0_ = AMIPtr_->tgtPatch0();
|
||||
if (AMIPtr_->distributed())
|
||||
{
|
||||
tgtMapPtr_.reset(new mapDistribute(AMIPtr_->tgtMap()));
|
||||
}
|
||||
|
||||
|
||||
// Walk out valid donors
|
||||
// ~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
if (nDonors_ > 0 && nIters_ > 0)
|
||||
{
|
||||
// Extend source side
|
||||
{
|
||||
// Low weight faces
|
||||
DynamicList<label> uncoveredFaces;
|
||||
forAll(srcWeightsSum(), facei)
|
||||
{
|
||||
if (srcWeightsSum()[facei] < lowWeightCorrection_)
|
||||
{
|
||||
uncoveredFaces.append(facei);
|
||||
}
|
||||
}
|
||||
uncoveredFaces.shrink();
|
||||
|
||||
|
||||
// Global indexing for src faces
|
||||
const globalIndex globalFaces(srcPatch.size());
|
||||
|
||||
|
||||
// Find nearest face with high weight
|
||||
labelListList nearestCoveredFaces;
|
||||
findNearest
|
||||
(
|
||||
mesh,
|
||||
mesh.boundaryMesh()[srcPatchi],
|
||||
globalFaces,
|
||||
uncoveredFaces,
|
||||
nearestCoveredFaces
|
||||
);
|
||||
|
||||
|
||||
// Create map to get remote data into nearestCoveredFaces
|
||||
// order
|
||||
List<Map<label>> compactMap;
|
||||
const mapDistribute uncoveredToPatchMap
|
||||
(
|
||||
globalFaces,
|
||||
nearestCoveredFaces,
|
||||
compactMap
|
||||
);
|
||||
// Get srcPatch faceCentres in stencil ordering
|
||||
pointField stencilFcs(srcPatch.faceCentres());
|
||||
uncoveredToPatchMap.distribute(stencilFcs);
|
||||
// Get addressing (to donors) over in stencil ordering
|
||||
labelListList stencilAddressing(srcAddress());
|
||||
uncoveredToPatchMap.distribute(stencilAddressing);
|
||||
//scalarListList stencilWeights(srcWeights());
|
||||
//uncoveredToPatchMap.distribute(stencilWeights);
|
||||
|
||||
|
||||
// Target side patch centres
|
||||
tmp<pointField> totherFcs;
|
||||
if (AMIPtr_->distributed())
|
||||
{
|
||||
totherFcs = new pointField(tgtPatch.faceCentres());
|
||||
AMIPtr_->tgtMap().distribute(totherFcs.ref());
|
||||
}
|
||||
else
|
||||
{
|
||||
totherFcs = tgtPatch.faceCentres();
|
||||
}
|
||||
const pointField& otherFcs = totherFcs();
|
||||
|
||||
|
||||
//forAll(uncoveredFaces, i)
|
||||
//{
|
||||
// const label facei = uncoveredFaces[i];
|
||||
// const labelList& covered = nearestCoveredFaces[i];
|
||||
// Pout<< "Uncovered face:" << facei
|
||||
// << " low weihgt:" << srcWeightsSum()[facei]
|
||||
// << " at:" << srcPatch.faceCentres()[facei]
|
||||
// << " has local donors:" << endl;
|
||||
// for (const label coveredSlot : covered)
|
||||
// {
|
||||
// Pout<< " fc:" << stencilFcs[coveredSlot] << nl
|
||||
// << " which has remotes:"
|
||||
// << stencilAddressing[coveredSlot] << nl
|
||||
// << " at:"
|
||||
// << UIndirectList<point>
|
||||
// (
|
||||
// otherFcs,
|
||||
// stencilAddressing[coveredSlot]
|
||||
// ) << nl
|
||||
// //<< " with weights:"
|
||||
// //<< stencilWeights[coveredSlot] << nl
|
||||
// << endl;
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
// Re-do interpolation on uncovered faces
|
||||
forAll(uncoveredFaces, i)
|
||||
{
|
||||
const label facei = uncoveredFaces[i];
|
||||
|
||||
calculateStencil
|
||||
(
|
||||
facei,
|
||||
srcPatch.faceCentres()[facei],
|
||||
nearestCoveredFaces[i],
|
||||
stencilAddressing,
|
||||
|
||||
srcAddress_,
|
||||
srcWeights_,
|
||||
srcWeightsSum_,
|
||||
otherFcs
|
||||
);
|
||||
}
|
||||
|
||||
//OBJstream os
|
||||
//(
|
||||
// mesh.time().path()
|
||||
// /mesh.boundaryMesh()[srcPatchi].name()+"_src.obj"
|
||||
//);
|
||||
//forAll(uncoveredFaces, i)
|
||||
//{
|
||||
// const label facei = uncoveredFaces[i];
|
||||
// const point& fc = srcPatch.faceCentres()[facei];
|
||||
// const labelList& slots = srcAddress_[facei];
|
||||
// for (const label sloti : slots)
|
||||
// {
|
||||
// os.write(linePointRef(fc, otherFcs[sloti]));
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
// Extend target side
|
||||
{
|
||||
// Low weight faces
|
||||
DynamicList<label> uncoveredFaces;
|
||||
forAll(tgtWeightsSum(), facei)
|
||||
{
|
||||
if (tgtWeightsSum()[facei] < lowWeightCorrection_)
|
||||
{
|
||||
uncoveredFaces.append(facei);
|
||||
}
|
||||
}
|
||||
uncoveredFaces.shrink();
|
||||
|
||||
|
||||
// Global indexing for tgt faces
|
||||
const globalIndex globalFaces(tgtPatch.size());
|
||||
|
||||
|
||||
// Find nearest face with high weight
|
||||
labelListList nearestCoveredFaces;
|
||||
findNearest
|
||||
(
|
||||
mesh,
|
||||
mesh.boundaryMesh()[tgtPatchi],
|
||||
globalFaces,
|
||||
uncoveredFaces,
|
||||
nearestCoveredFaces
|
||||
);
|
||||
|
||||
|
||||
// Create map to get remote data into nearestCoveredFaces
|
||||
// order
|
||||
List<Map<label>> compactMap;
|
||||
const mapDistribute uncoveredToPatchMap
|
||||
(
|
||||
globalFaces,
|
||||
nearestCoveredFaces,
|
||||
compactMap
|
||||
);
|
||||
// Get tgtPatch faceCentres in stencil ordering
|
||||
pointField stencilFcs(tgtPatch.faceCentres());
|
||||
uncoveredToPatchMap.distribute(stencilFcs);
|
||||
// Get addressing (to donors) over in stencil ordering
|
||||
labelListList stencilAddressing(tgtAddress());
|
||||
uncoveredToPatchMap.distribute(stencilAddressing);
|
||||
scalarListList stencilWeights(tgtWeights());
|
||||
uncoveredToPatchMap.distribute(stencilWeights);
|
||||
|
||||
|
||||
// Target side patch centres
|
||||
tmp<pointField> totherFcs;
|
||||
if (AMIPtr_->distributed())
|
||||
{
|
||||
totherFcs = new pointField(srcPatch.faceCentres());
|
||||
AMIPtr_->srcMap().distribute(totherFcs.ref());
|
||||
}
|
||||
else
|
||||
{
|
||||
totherFcs = srcPatch.faceCentres();
|
||||
}
|
||||
const pointField& otherFcs = totherFcs();
|
||||
|
||||
|
||||
//forAll(uncoveredFaces, i)
|
||||
//{
|
||||
// const label facei = uncoveredFaces[i];
|
||||
// const labelList& covered = nearestCoveredFaces[i];
|
||||
// Pout<< "Uncovered face:" << facei
|
||||
// << " low weihgt:" << tgtWeights()[facei]
|
||||
// << " at:" << tgtPatch.faceCentres()[facei]
|
||||
// << " has local donors:" << endl;
|
||||
// for (const label coveredSlot : covered)
|
||||
// {
|
||||
// Pout<< " fc:" << stencilFcs[coveredSlot] << nl
|
||||
// << " which has remotes:"
|
||||
// << stencilAddressing[coveredSlot] << nl
|
||||
// << " at:"
|
||||
// << UIndirectList<point>
|
||||
// (
|
||||
// otherFcs,
|
||||
// stencilAddressing[coveredSlot]
|
||||
// ) << nl
|
||||
// << " with weights:"
|
||||
// << stencilWeights[coveredSlot] << nl
|
||||
// << endl;
|
||||
// }
|
||||
//}
|
||||
|
||||
// Re-do interpolation on uncovered faces
|
||||
forAll(uncoveredFaces, i)
|
||||
{
|
||||
const label facei = uncoveredFaces[i];
|
||||
|
||||
calculateStencil
|
||||
(
|
||||
facei,
|
||||
tgtPatch.faceCentres()[facei],
|
||||
nearestCoveredFaces[i],
|
||||
stencilAddressing,
|
||||
|
||||
tgtAddress_,
|
||||
tgtWeights_,
|
||||
tgtWeightsSum_,
|
||||
otherFcs
|
||||
);
|
||||
}
|
||||
|
||||
//OBJstream os
|
||||
//(
|
||||
// mesh.time().path()
|
||||
// /mesh.boundaryMesh()[srcPatchi].name()+"_tgt.obj"
|
||||
//);
|
||||
//forAll(uncoveredFaces, i)
|
||||
//{
|
||||
// const label facei = uncoveredFaces[i];
|
||||
// const point& fc = tgtPatch.faceCentres()[facei];
|
||||
// const labelList& slots = tgtAddress_[facei];
|
||||
// for (const label sloti : slots)
|
||||
// {
|
||||
// os.write(linePointRef(fc, otherFcs[sloti]));
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
////- Write face connectivity as OBJ file
|
||||
//writeFaceConnectivity
|
||||
//(
|
||||
// srcPatch,
|
||||
// tgtPatch,
|
||||
// srcAddress_
|
||||
//);
|
||||
}
|
||||
|
||||
return upToDate_;
|
||||
}
|
||||
|
||||
|
||||
void Foam::lowWeightCorrection::write(Ostream& os) const
|
||||
{
|
||||
AMIInterpolation::write(os);
|
||||
os.writeEntry("nDonors", nDonors_);
|
||||
os.writeEntry("nIters", nIters_);
|
||||
os.beginBlock(word(this->type() + "Coeffs"));
|
||||
AMIPtr_->write(os);
|
||||
os.endBlock();
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,216 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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::lowWeightCorrection
|
||||
|
||||
Description
|
||||
Arbitrary Mesh Interface (AMI) method wrapper that extends low-weight
|
||||
faces to use donors of local neighbouring (non-low weight) faces.
|
||||
|
||||
It collects valid nearby faces and uses their stencil instead.
|
||||
|
||||
Example of the boundary specification:
|
||||
\verbatim
|
||||
<patchName>
|
||||
{
|
||||
type cyclicAMI;
|
||||
|
||||
AMIMethod lowWeightCorrection;
|
||||
|
||||
// Low weight value; which faces to override
|
||||
lowWeightCorrection 0.1;
|
||||
// How far to walk out from valid faces. 0 means no change.
|
||||
nIters 2;
|
||||
// Limit amount of valid faces to store.
|
||||
nDonors 2;
|
||||
// Underlying AMI method to use.
|
||||
lowWeightCorrectionCoeffs
|
||||
{
|
||||
AMIMethod faceAreaWeightAMI;
|
||||
}
|
||||
}
|
||||
\endverbatim
|
||||
|
||||
This version walks out the local faces and then collects all their
|
||||
remote donors. Hence even for e.g. 2 local faces (nDonors) the stencil
|
||||
might still include lots of remote faces.
|
||||
|
||||
The number of iterations to walk out might be set to infinite if one
|
||||
wants a value on all faces.
|
||||
|
||||
|
||||
SourceFiles
|
||||
lowWeightCorrection.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lowWeightCorrection_H
|
||||
#define lowWeightCorrection_H
|
||||
|
||||
#include "AMIInterpolation.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class lowWeightCorrection Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class lowWeightCorrection
|
||||
:
|
||||
public AMIInterpolation
|
||||
{
|
||||
private:
|
||||
|
||||
// Private Data
|
||||
|
||||
//- Threshold weight below which interpolation switches to distance
|
||||
// weighted
|
||||
const scalar lowWeightCorrection_;
|
||||
|
||||
//- Number of donors to weigh
|
||||
const label nDonors_;
|
||||
|
||||
//- Number of iterations to walk out to search for donors
|
||||
const label nIters_;
|
||||
|
||||
//- Uncorrected AMI
|
||||
autoPtr<AMIInterpolation> AMIPtr_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Find (local) donor faces for all uncovered faces
|
||||
void findNearest
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const primitivePatch& pp,
|
||||
const globalIndex& globalFaces,
|
||||
const labelList& uncoveredFaces,
|
||||
labelListList& nearestCoveredFaces
|
||||
) const;
|
||||
|
||||
//- Determine stencil for single face. Gets list of (local) faces
|
||||
// whose addressing can be used for calculating the stencil
|
||||
void calculateStencil
|
||||
(
|
||||
const label facei,
|
||||
const point& sample,
|
||||
const labelList& nearestCovered,
|
||||
const labelListList& stencilAddressing,
|
||||
|
||||
labelListList& addressing,
|
||||
scalarListList& weights,
|
||||
scalarField& sumWeights,
|
||||
const pointField& faceCentres
|
||||
) const;
|
||||
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const lowWeightCorrection&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("lowWeightCorrection");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from dictionary
|
||||
lowWeightCorrection
|
||||
(
|
||||
const dictionary& dict,
|
||||
const bool reverseTarget = false
|
||||
);
|
||||
|
||||
//- Construct from components
|
||||
lowWeightCorrection
|
||||
(
|
||||
const bool requireMatch = true,
|
||||
const bool reverseTarget = false,
|
||||
const scalar lowWeightCorrection = -1
|
||||
);
|
||||
|
||||
//- Construct as copy
|
||||
lowWeightCorrection(const lowWeightCorrection& ami);
|
||||
|
||||
//- Construct and return a clone
|
||||
virtual autoPtr<AMIInterpolation> clone() const
|
||||
{
|
||||
return autoPtr<AMIInterpolation>(new lowWeightCorrection(*this));
|
||||
}
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~lowWeightCorrection() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Update addressing and weights
|
||||
virtual bool calculate
|
||||
(
|
||||
const primitivePatch& srcPatch,
|
||||
const primitivePatch& tgtPatch,
|
||||
const autoPtr<searchableSurface>& surfPtr = nullptr
|
||||
)
|
||||
{
|
||||
NotImplemented;
|
||||
return false;
|
||||
}
|
||||
|
||||
//- Update addressing and weights
|
||||
virtual bool calculate
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const label srcPatchi,
|
||||
const primitivePatch& srcPatch,
|
||||
const label tgtPatchi,
|
||||
const primitivePatch& tgtPatch,
|
||||
const autoPtr<searchableSurface>& surfPtr = nullptr
|
||||
);
|
||||
|
||||
|
||||
// I-O
|
||||
|
||||
//- Write
|
||||
virtual void write(Ostream& os) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -435,15 +435,7 @@ void Foam::cyclicAMIPolyPatch::resetAMI(const UList<point>& points) const
|
||||
|
||||
// Construct/apply AMI interpolation to determine addressing and weights
|
||||
AMIPtr_->upToDate() = false;
|
||||
AMIPtr_->calculate
|
||||
(
|
||||
boundaryMesh().mesh(),
|
||||
index(),
|
||||
patch0,
|
||||
nbr.index(),
|
||||
nbrPatch0,
|
||||
surfPtr()
|
||||
);
|
||||
AMIPtr_->calculate(patch0, nbrPatch0, surfPtr());
|
||||
|
||||
if (debug)
|
||||
{
|
||||
|
||||
@ -293,7 +293,6 @@ $(AMI)/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterface
|
||||
|
||||
$(AMI)/triangle2D/triangle2D.C
|
||||
$(AMI)/AMIInterpolation/faceAreaWeightAMI2D/faceAreaWeightAMI2D.C
|
||||
$(AMI)/AMIInterpolation/lowWeightCorrection/lowWeightCorrection.C
|
||||
|
||||
|
||||
AMICycPatches=$(AMI)/patches/cyclicAMI
|
||||
|
||||
Reference in New Issue
Block a user