mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'feature-splitMeshRegions_autoPatch' into 'develop'
Draft: Extend splitMeshRegions to automatically create AMI inter-region patches See merge request Development/openfoam!525
This commit is contained in:
@ -43,8 +43,9 @@ Description
|
|||||||
- volScalarField with regions as different scalars (-detectOnly)
|
- volScalarField with regions as different scalars (-detectOnly)
|
||||||
or
|
or
|
||||||
- mesh with multiple regions and mapped patches. These patches
|
- mesh with multiple regions and mapped patches. These patches
|
||||||
either cover the whole interface between two region (default) or
|
either cover the whole interface between two region (default),
|
||||||
only part according to faceZones (-useFaceZones)
|
only part according to faceZones (-useFaceZones) or be auto-generated
|
||||||
|
according to an AMI method (see below)
|
||||||
or
|
or
|
||||||
- mesh with cells put into cellZones (-makeCellZones)
|
- mesh with cells put into cellZones (-makeCellZones)
|
||||||
|
|
||||||
@ -98,6 +99,14 @@ Description
|
|||||||
- boundaryRegionAddressing : for every patch in this region the
|
- boundaryRegionAddressing : for every patch in this region the
|
||||||
patch in the original mesh (or -1 if added patch)
|
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"
|
#include "argList.H"
|
||||||
@ -115,6 +124,7 @@ Description
|
|||||||
#include "mappedWallPolyPatch.H"
|
#include "mappedWallPolyPatch.H"
|
||||||
#include "fvMeshTools.H"
|
#include "fvMeshTools.H"
|
||||||
#include "processorMeshes.H"
|
#include "processorMeshes.H"
|
||||||
|
#include "faceAreaWeightAMI2D.H"
|
||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
|
|
||||||
@ -296,12 +306,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.
|
// Get region-region interface name and sizes.
|
||||||
// Returns interfaces as straight list for looping in identical order.
|
// Returns interfaces as straight list for looping in identical order.
|
||||||
void getInterfaceSizes
|
void getInterfaceSizes
|
||||||
(
|
(
|
||||||
const polyMesh& mesh,
|
const polyMesh& mesh,
|
||||||
const bool useFaceZones,
|
const bool useFaceZones,
|
||||||
|
const word& AMIMethod,
|
||||||
|
const labelList& matchPatchIDs,
|
||||||
const labelList& cellRegion,
|
const labelList& cellRegion,
|
||||||
const wordList& regionNames,
|
const wordList& regionNames,
|
||||||
|
|
||||||
@ -340,15 +453,16 @@ void getInterfaceSizes
|
|||||||
// Boundary faces
|
// Boundary faces
|
||||||
// ~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~
|
||||||
|
|
||||||
// Neighbour cellRegion.
|
const labelList coupledRegion
|
||||||
labelList coupledRegion(mesh.nBoundaryFaces());
|
(
|
||||||
|
getMinBoundaryValue
|
||||||
forAll(coupledRegion, i)
|
(
|
||||||
{
|
mesh,
|
||||||
label celli = mesh.faceOwner()[i+mesh.nInternalFaces()];
|
AMIMethod,
|
||||||
coupledRegion[i] = cellRegion[celli];
|
matchPatchIDs,
|
||||||
}
|
cellRegion
|
||||||
syncTools::swapBoundaryFaceList(mesh, coupledRegion);
|
)
|
||||||
|
);
|
||||||
|
|
||||||
forAll(coupledRegion, i)
|
forAll(coupledRegion, i)
|
||||||
{
|
{
|
||||||
@ -540,6 +654,8 @@ autoPtr<mapPolyMesh> createRegionMesh
|
|||||||
const labelList& cellRegion,
|
const labelList& cellRegion,
|
||||||
const label regionI,
|
const label regionI,
|
||||||
const word& regionName,
|
const word& regionName,
|
||||||
|
const word& AMIMethod,
|
||||||
|
const labelList& matchPatchIDs,
|
||||||
// Interface info
|
// Interface info
|
||||||
const labelList& interfacePatches,
|
const labelList& interfacePatches,
|
||||||
const labelList& faceToInterface,
|
const labelList& faceToInterface,
|
||||||
@ -551,15 +667,16 @@ autoPtr<mapPolyMesh> createRegionMesh
|
|||||||
fvMeshTools::createDummyFvMeshFiles(mesh, regionName, true);
|
fvMeshTools::createDummyFvMeshFiles(mesh, regionName, true);
|
||||||
|
|
||||||
// Neighbour cellRegion.
|
// Neighbour cellRegion.
|
||||||
labelList coupledRegion(mesh.nBoundaryFaces());
|
const labelList coupledRegion
|
||||||
|
(
|
||||||
forAll(coupledRegion, i)
|
getMinBoundaryValue
|
||||||
{
|
(
|
||||||
label celli = mesh.faceOwner()[i+mesh.nInternalFaces()];
|
mesh,
|
||||||
coupledRegion[i] = cellRegion[celli];
|
AMIMethod,
|
||||||
}
|
matchPatchIDs,
|
||||||
syncTools::swapBoundaryFaceList(mesh, coupledRegion);
|
cellRegion
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// Topology change container. Start off from existing mesh.
|
// Topology change container. Start off from existing mesh.
|
||||||
polyTopoChange meshMod(mesh);
|
polyTopoChange meshMod(mesh);
|
||||||
@ -578,20 +695,16 @@ autoPtr<mapPolyMesh> createRegionMesh
|
|||||||
labelList exposedPatchIDs(exposedFaces.size());
|
labelList exposedPatchIDs(exposedFaces.size());
|
||||||
forAll(exposedFaces, i)
|
forAll(exposedFaces, i)
|
||||||
{
|
{
|
||||||
label facei = exposedFaces[i];
|
const label facei = exposedFaces[i];
|
||||||
label interfacei = faceToInterface[facei];
|
const label interfacei = faceToInterface[facei];
|
||||||
|
|
||||||
label ownRegion = cellRegion[mesh.faceOwner()[facei]];
|
const label ownRegion = cellRegion[mesh.faceOwner()[facei]];
|
||||||
label neiRegion = -1;
|
const label neiRegion
|
||||||
|
(
|
||||||
if (mesh.isInternalFace(facei))
|
mesh.isInternalFace(facei)
|
||||||
{
|
? cellRegion[mesh.faceNeighbour()[facei]]
|
||||||
neiRegion = cellRegion[mesh.faceNeighbour()[facei]];
|
: coupledRegion[facei-mesh.nInternalFaces()]
|
||||||
}
|
);
|
||||||
else
|
|
||||||
{
|
|
||||||
neiRegion = coupledRegion[facei-mesh.nInternalFaces()];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Check which side is being kept - determines which of the two
|
// Check which side is being kept - determines which of the two
|
||||||
@ -638,6 +751,62 @@ autoPtr<mapPolyMesh> createRegionMesh
|
|||||||
meshMod
|
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
|
autoPtr<mapPolyMesh> map = meshMod.makeMesh
|
||||||
(
|
(
|
||||||
newMesh,
|
newMesh,
|
||||||
@ -662,6 +831,8 @@ void createAndWriteRegion
|
|||||||
const labelList& cellRegion,
|
const labelList& cellRegion,
|
||||||
const wordList& regionNames,
|
const wordList& regionNames,
|
||||||
const bool prefixRegion,
|
const bool prefixRegion,
|
||||||
|
const word& AMIMethod,
|
||||||
|
const labelList& matchPatchIDs,
|
||||||
const labelList& faceToInterface,
|
const labelList& faceToInterface,
|
||||||
const labelList& interfacePatches,
|
const labelList& interfacePatches,
|
||||||
const label regionI,
|
const label regionI,
|
||||||
@ -678,6 +849,8 @@ void createAndWriteRegion
|
|||||||
cellRegion,
|
cellRegion,
|
||||||
regionI,
|
regionI,
|
||||||
regionNames[regionI],
|
regionNames[regionI],
|
||||||
|
AMIMethod,
|
||||||
|
matchPatchIDs,
|
||||||
interfacePatches,
|
interfacePatches,
|
||||||
faceToInterface,
|
faceToInterface,
|
||||||
newMesh
|
newMesh
|
||||||
@ -976,6 +1149,7 @@ labelList addRegionPatches
|
|||||||
const wordList& regionNames,
|
const wordList& regionNames,
|
||||||
const edgeList& interfaces,
|
const edgeList& interfaces,
|
||||||
const List<Pair<word>>& interfaceNames
|
const List<Pair<word>>& interfaceNames
|
||||||
|
//const List<mappedPatchBase::sampleMode>& interfaceModes
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Info<< nl << "Adding patches" << nl << endl;
|
Info<< nl << "Adding patches" << nl << endl;
|
||||||
@ -999,7 +1173,7 @@ labelList addRegionPatches
|
|||||||
0, // overridden
|
0, // overridden
|
||||||
0, // overridden
|
0, // overridden
|
||||||
regionNames[e[1]], // sampleRegion
|
regionNames[e[1]], // sampleRegion
|
||||||
mappedPatchBase::NEARESTPATCHFACE,
|
mappedPatchBase::NEARESTPATCHFACE, //interfaceModes[interI]
|
||||||
names[1], // samplePatch
|
names[1], // samplePatch
|
||||||
point::zero, // offset
|
point::zero, // offset
|
||||||
mesh.boundaryMesh()
|
mesh.boundaryMesh()
|
||||||
@ -1021,7 +1195,7 @@ labelList addRegionPatches
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
regionNames[e[0]], // sampleRegion
|
regionNames[e[0]], // sampleRegion
|
||||||
mappedPatchBase::NEARESTPATCHFACE,
|
mappedPatchBase::NEARESTPATCHFACE, //interfaceModes[interI]
|
||||||
names[0],
|
names[0],
|
||||||
point::zero, // offset
|
point::zero, // offset
|
||||||
mesh.boundaryMesh()
|
mesh.boundaryMesh()
|
||||||
@ -1411,6 +1585,7 @@ int main(int argc, char *argv[])
|
|||||||
"Split mesh into multiple regions (detected by walking across faces)"
|
"Split mesh into multiple regions (detected by walking across faces)"
|
||||||
);
|
);
|
||||||
#include "addRegionOption.H"
|
#include "addRegionOption.H"
|
||||||
|
|
||||||
#include "addOverwriteOption.H"
|
#include "addOverwriteOption.H"
|
||||||
argList::addBoolOption
|
argList::addBoolOption
|
||||||
(
|
(
|
||||||
@ -1477,6 +1652,18 @@ int main(int argc, char *argv[])
|
|||||||
"useFaceZones",
|
"useFaceZones",
|
||||||
"Use faceZones to patch inter-region faces instead of single patch"
|
"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
|
argList::addBoolOption
|
||||||
(
|
(
|
||||||
"prefixRegion",
|
"prefixRegion",
|
||||||
@ -1489,6 +1676,12 @@ int main(int argc, char *argv[])
|
|||||||
#include "createTime.H"
|
#include "createTime.H"
|
||||||
#include "createNamedMesh.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();
|
const word oldInstance = mesh.pointsInstance();
|
||||||
|
|
||||||
word blockedFacesName;
|
word blockedFacesName;
|
||||||
@ -1512,6 +1705,14 @@ int main(int argc, char *argv[])
|
|||||||
const bool useFaceZones = args.found("useFaceZones");
|
const bool useFaceZones = args.found("useFaceZones");
|
||||||
const bool prefixRegion = args.found("prefixRegion");
|
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
|
if
|
||||||
(
|
(
|
||||||
@ -1541,6 +1742,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)
|
if (insidePoint && largestOnly)
|
||||||
{
|
{
|
||||||
@ -1608,8 +1816,8 @@ int main(int argc, char *argv[])
|
|||||||
<< " This requires all"
|
<< " This requires all"
|
||||||
<< " cells to be in one and only one cellZone." << nl << endl;
|
<< " cells to be in one and only one cellZone." << nl << endl;
|
||||||
|
|
||||||
// Collect sets of zones into clusters. If no cluster is just an identity
|
// Collect sets of zones into clusters. If no cluster is just an
|
||||||
// list (cluster 0 is cellZone 0 etc.)
|
// identity list (cluster 0 is cellZone 0 etc.)
|
||||||
wordList clusterNames;
|
wordList clusterNames;
|
||||||
labelListList clusterToZones;
|
labelListList clusterToZones;
|
||||||
labelList zoneToCluster;
|
labelList zoneToCluster;
|
||||||
@ -1924,6 +2132,8 @@ int main(int argc, char *argv[])
|
|||||||
(
|
(
|
||||||
mesh,
|
mesh,
|
||||||
useFaceZones,
|
useFaceZones,
|
||||||
|
AMIMethod,
|
||||||
|
matchPatchIDs,
|
||||||
cellRegion,
|
cellRegion,
|
||||||
regionNames,
|
regionNames,
|
||||||
|
|
||||||
@ -2103,6 +2313,7 @@ int main(int argc, char *argv[])
|
|||||||
regionNames,
|
regionNames,
|
||||||
interfaces,
|
interfaces,
|
||||||
interfaceNames
|
interfaceNames
|
||||||
|
//interfaceModes
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -2155,6 +2366,8 @@ int main(int argc, char *argv[])
|
|||||||
cellRegion,
|
cellRegion,
|
||||||
regionNames,
|
regionNames,
|
||||||
prefixRegion,
|
prefixRegion,
|
||||||
|
AMIMethod,
|
||||||
|
matchPatchIDs,
|
||||||
faceToInterface,
|
faceToInterface,
|
||||||
interfacePatches,
|
interfacePatches,
|
||||||
regionI,
|
regionI,
|
||||||
@ -2176,6 +2389,8 @@ int main(int argc, char *argv[])
|
|||||||
cellRegion,
|
cellRegion,
|
||||||
regionNames,
|
regionNames,
|
||||||
prefixRegion,
|
prefixRegion,
|
||||||
|
AMIMethod,
|
||||||
|
matchPatchIDs,
|
||||||
faceToInterface,
|
faceToInterface,
|
||||||
interfacePatches,
|
interfacePatches,
|
||||||
regionI,
|
regionI,
|
||||||
@ -2197,6 +2412,8 @@ int main(int argc, char *argv[])
|
|||||||
cellRegion,
|
cellRegion,
|
||||||
regionNames,
|
regionNames,
|
||||||
prefixRegion,
|
prefixRegion,
|
||||||
|
AMIMethod,
|
||||||
|
matchPatchIDs,
|
||||||
faceToInterface,
|
faceToInterface,
|
||||||
interfacePatches,
|
interfacePatches,
|
||||||
regionI,
|
regionI,
|
||||||
|
|||||||
Reference in New Issue
Block a user