splitBaffles, mergeBaffles: New utilities to replace mergeOrSplitBaffles

splitBaffles identifies baffle faces; i.e., faces on the mesh boundary
which share the exact same set of points as another boundary face. It
then splits the points to convert these faces into completely separate
boundary patches. This functionality was previously provided by calling
mergeOrSplitBaffles with the "-split" option.

mergeBaffles also identifes the duplicate baffle faces, but then merges
them, converting them into a single set of internal faces. This
functionality was previously provided by calling mergeOrSplitBaffles
without the "-split" option.
This commit is contained in:
Will Bainbridge
2021-06-25 08:46:34 +01:00
parent a0f25afd06
commit 45a0059026
17 changed files with 237 additions and 189 deletions

View File

@ -25,8 +25,7 @@ Application
createBaffles
Description
Makes internal faces into boundary faces. Does not duplicate points, unlike
mergeOrSplitBaffles.
Makes internal faces into boundary faces. Does not duplicate points.
Note: if any coupled patch face is selected for baffling the opposite
member has to be selected for baffling as well.

View File

@ -0,0 +1,3 @@
mergeBaffles.C
EXE = $(FOAM_APPBIN)/mergeBaffles

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -25,22 +25,8 @@ Application
mergeOrSplitBaffles
Description
Detects faces that share points (baffles). Either merge them or
duplicate the points.
Notes:
- can only handle pairwise boundary faces. So three faces using
the same points is not handled (is illegal mesh anyway)
- there is no option to only split/merge some baffles.
- surfaces consisting of duplicate faces can be topologically split
if the points on the interior of the surface cannot walk to all the
cells that use them in one go.
- Parallel operation (where duplicate face is perpendicular to a coupled
boundary) is supported but not really tested.
(Note that coupled faces themselves are not seen as duplicate faces)
Detects faces that share points (baffles) and merge them into internal
faces.
\*---------------------------------------------------------------------------*/
@ -66,13 +52,42 @@ using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void insertDuplicateMerge
void mergeDuplicateBoundaryFaces
(
const polyMesh& mesh,
const labelList& duplicates,
polyTopoChange& meshMod
)
{
// Get all duplicate face labels in the boundary
labelList duplicates = localPointRegion::findDuplicateFaces
(
mesh,
identity(mesh.nFaces() - mesh.nInternalFaces())
+ mesh.nInternalFaces()
);
// Check that none are on processor patches
const polyBoundaryMesh& patches = mesh.boundaryMesh();
forAll(duplicates, bFacei)
{
if (duplicates[bFacei] != -1)
{
label facei = mesh.nInternalFaces() + bFacei;
label patchi = patches.whichPatch(facei);
if (isA<processorPolyPatch>(patches[patchi]))
{
FatalErrorInFunction
<< "Duplicate face " << facei
<< " is on a processorPolyPatch."
<< "This is not allowed." << nl
<< "Face:" << facei
<< " is on patch:" << patches[patchi].name()
<< abort(FatalError);
}
}
}
const faceList& faces = mesh.faces();
const labelList& faceOwner = mesh.faceOwner();
const faceZoneMesh& faceZones = mesh.faceZones();
@ -154,93 +169,17 @@ void insertDuplicateMerge
}
labelList findBaffles(const polyMesh& mesh, const labelList& boundaryFaces)
{
// Get all duplicate face labels (in boundaryFaces indices!).
labelList duplicates = localPointRegion::findDuplicateFaces
(
mesh,
boundaryFaces
);
// Check that none are on processor patches
const polyBoundaryMesh& patches = mesh.boundaryMesh();
forAll(duplicates, bFacei)
{
if (duplicates[bFacei] != -1)
{
label facei = mesh.nInternalFaces() + bFacei;
label patchi = patches.whichPatch(facei);
if (isA<processorPolyPatch>(patches[patchi]))
{
FatalErrorInFunction
<< "Duplicate face " << facei
<< " is on a processorPolyPatch."
<< "This is not allowed." << nl
<< "Face:" << facei
<< " is on patch:" << patches[patchi].name()
<< abort(FatalError);
}
}
}
// Write to faceSet for ease of postprocessing.
{
faceSet duplicateSet
(
mesh,
"duplicateFaces",
(mesh.nFaces() - mesh.nInternalFaces())/256
);
forAll(duplicates, bFacei)
{
label otherFacei = duplicates[bFacei];
if (otherFacei != -1 && otherFacei > bFacei)
{
duplicateSet.insert(mesh.nInternalFaces() + bFacei);
duplicateSet.insert(mesh.nInternalFaces() + otherFacei);
}
}
Pout<< "Writing " << duplicateSet.size()
<< " duplicate faces to faceSet " << duplicateSet.localObjectPath()
<< nl << endl;
duplicateSet.write();
}
return duplicates;
}
int main(int argc, char *argv[])
{
argList::addNote
(
"Detect faces that share points (baffles).\n"
"Merge them or duplicate the points."
"Detect faces that share points (baffles)\n"
"and merge them into internal faces."
);
#include "addOverwriteOption.H"
#include "addRegionOption.H"
argList::addBoolOption
(
"detectOnly",
"find baffles only, but do not merge or split them"
);
argList::addBoolOption
(
"split",
"topologically split duplicate surfaces"
);
argList::addBoolOption
(
"fields",
"update fields"
@ -251,28 +190,10 @@ int main(int argc, char *argv[])
runTime.functionObjects().off();
#include "createNamedMesh.H"
const word oldInstance = mesh.pointsInstance();
const bool split = args.optionFound("split");
const bool overwrite = args.optionFound("overwrite");
const bool detectOnly = args.optionFound("detectOnly");
const bool fields = args.optionFound("fields");
// Collect all boundary faces
labelList boundaryFaces(mesh.nFaces() - mesh.nInternalFaces());
forAll(boundaryFaces, i)
{
boundaryFaces[i] = i+mesh.nInternalFaces();
}
if (detectOnly)
{
findBaffles(mesh, boundaryFaces);
return 0;
}
const word oldInstance = mesh.pointsInstance();
// Read objects in time directory
IOobjectList objects(mesh, runTime.timeName());
@ -283,39 +204,11 @@ int main(int argc, char *argv[])
#include "readSurfaceFields.H"
#include "readPointFields.H"
Info<< endl;
// Mesh change engine
polyTopoChange meshMod(mesh);
if (split)
{
Pout<< "Topologically splitting duplicate surfaces"
<< ", i.e. duplicating points internal to duplicate surfaces."
<< nl << endl;
// Analyse which points need to be duplicated
localPointRegion regionSide(mesh);
// Point duplication engine
duplicatePoints pointDuplicator(mesh);
// Insert topo changes
pointDuplicator.setRefinement(regionSide, meshMod);
}
else
{
Pout<< "Merging duplicate faces."
<< nl << endl;
// Get all duplicate face labels (in boundaryFaces indices!).
labelList duplicates(findBaffles(mesh, boundaryFaces));
// Merge into internal faces.
insertDuplicateMerge(mesh, duplicates, meshMod);
}
// Merge duplicate boundary faces into internal faces.
mergeDuplicateBoundaryFaces(mesh, meshMod);
if (!overwrite)
{
@ -338,38 +231,10 @@ int main(int argc, char *argv[])
{
mesh.setInstance(oldInstance);
}
Pout<< "Writing mesh to time " << runTime.timeName() << endl;
Info<< "Writing mesh to time " << runTime.timeName() << endl;
mesh.write();
// Dump duplicated points (if any)
if (split)
{
const labelList& pointMap = map().pointMap();
labelList nDupPerPoint(map().nOldPoints(), 0);
pointSet dupPoints(mesh, "duplicatedPoints", 100);
forAll(pointMap, pointi)
{
label oldPointi = pointMap[pointi];
nDupPerPoint[oldPointi]++;
if (nDupPerPoint[oldPointi] > 1)
{
dupPoints.insert(map().reversePointMap()[oldPointi]);
dupPoints.insert(pointi);
}
}
Pout<< "Writing " << dupPoints.size()
<< " duplicated points to pointSet "
<< dupPoints.localObjectPath() << nl << endl;
dupPoints.write();
}
Info<< "End\n" << endl;
return 0;

View File

@ -1,3 +0,0 @@
mergeOrSplitBaffles.C
EXE = $(FOAM_APPBIN)/mergeOrSplitBaffles

View File

@ -0,0 +1,3 @@
splitBaffles.C
EXE = $(FOAM_APPBIN)/splitBaffles

View File

@ -0,0 +1,9 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lmeshTools \
-ldynamicMesh

View File

@ -0,0 +1,125 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2021 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/>.
Application
splitBaffles
Description
Detects faces that share points (baffles) and duplicates the points to
separate them
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "Time.H"
#include "polyTopoChange.H"
#include "localPointRegion.H"
#include "duplicatePoints.H"
#include "ReadFields.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "pointFields.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::addNote
(
"Detect faces that share points (baffles)\n"
"and duplicate the points to separate them."
);
#include "addOverwriteOption.H"
#include "addRegionOption.H"
argList::addBoolOption
(
"fields",
"update fields"
);
#include "setRootCase.H"
#include "createTime.H"
runTime.functionObjects().off();
#include "createNamedMesh.H"
const bool overwrite = args.optionFound("overwrite");
const bool fields = args.optionFound("fields");
const word oldInstance = mesh.pointsInstance();
// Read objects in time directory
IOobjectList objects(mesh, runTime.timeName());
if (fields) Info<< "Reading geometric fields" << nl << endl;
#include "readVolFields.H"
#include "readSurfaceFields.H"
#include "readPointFields.H"
// Mesh change engine
polyTopoChange meshMod(mesh);
// Analyse which points need to be duplicated
localPointRegion regionSide(mesh);
// Point duplication engine
duplicatePoints pointDuplicator(mesh);
// Insert topo changes
pointDuplicator.setRefinement(regionSide, meshMod);
if (!overwrite)
{
runTime++;
}
// Change the mesh. No inflation.
autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh, false);
// Update fields
mesh.updateMesh(map);
// Move mesh (since morphing does not do this)
if (map().hasMotionPoints())
{
mesh.movePoints(map().preMotionPoints());
}
if (overwrite)
{
mesh.setInstance(oldInstance);
}
Info<< "Writing mesh to time " << runTime.timeName() << endl;
mesh.write();
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

47
bin/mergeOrSplitBaffles Executable file
View File

@ -0,0 +1,47 @@
#!/bin/sh
#------------------------------------------------------------------------------
# ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration | Website: https://openfoam.org
# \\ / A nd | Copyright (C) 2021 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/>.
#
# Script
# mergeOrSplitBaffles
#
# Description
# Script to inform the user that mergeOrSplitBaffles has been replaced
# by separate splitBaffles and mergeBaffles utilities.
#
#------------------------------------------------------------------------------
cat << EOF
The mergeOrSplitBaffles utility has been replaced by the splitBaffles and
mergeBaffles utilities.
If mergeOrSplitBaffles was previously being called with the "-split" option,
then splitBaffles should now be called instead.
If mergeOrSplitBaffles was previously being called without the "-split" option,
then mergeBaffles should now be called instead.
EOF
#------------------------------------------------------------------------------

View File

@ -10,7 +10,7 @@ runApplication blockMesh
runApplication snappyHexMesh -overwrite
runApplication createBaffles -overwrite
runApplication mergeOrSplitBaffles -split -overwrite
runApplication splitBaffles -overwrite
runApplication $(getApplication)

View File

@ -16,7 +16,7 @@ runParallel snappyHexMesh -overwrite
# Convert the face zones into mapped wall baffles and split
runParallel createBaffles -overwrite
runParallel mergeOrSplitBaffles -split -overwrite
runParallel splitBaffles -overwrite
rm -rf processor*/constant/polyMesh/pointLevel
# Run snappy again to create layers

View File

@ -14,7 +14,7 @@ runApplication snappyHexMesh -overwrite
# Create the inlet/outlet and AMI patches
runApplication createBaffles -overwrite
runApplication mergeOrSplitBaffles -split -overwrite
runApplication splitBaffles -overwrite
# Renumbering
runApplication renumberMesh -noFields -overwrite

View File

@ -8,7 +8,7 @@ application=$(getApplication)
runApplication blockMesh -dict $FOAM_TUTORIALS/resources/blockMesh/mixerVessel2D
runApplication createBaffles -overwrite
runApplication mergeOrSplitBaffles -split -overwrite
runApplication splitBaffles -overwrite
runApplication topoSet
#runApplication $application

View File

@ -6,6 +6,6 @@ cd ${0%/*} || exit 1 # Run from this directory
runApplication blockMesh -dict $FOAM_TUTORIALS/resources/blockMesh/mixerVessel2D
runApplication createBaffles -overwrite
runApplication mergeOrSplitBaffles -split -overwrite
runApplication splitBaffles -overwrite
runApplication $(getApplication)

View File

@ -12,6 +12,6 @@ runApplication blockMesh
runApplication surfaceFeatures
runApplication snappyHexMesh -overwrite
runApplication createBaffles -overwrite
runApplication mergeOrSplitBaffles -split -overwrite
runApplication splitBaffles -overwrite
#------------------------------------------------------------------------------

View File

@ -13,7 +13,7 @@ runApplication snappyHexMesh -overwrite
# Create the inlet/outlet and AMI patches
runApplication createBaffles -overwrite
runApplication mergeOrSplitBaffles -split -overwrite
runApplication splitBaffles -overwrite
# Renumbering
runApplication renumberMesh -noFields -overwrite

View File

@ -8,7 +8,7 @@ application=$(getApplication)
runApplication blockMesh -dict $FOAM_TUTORIALS/resources/blockMesh/mixerVessel2D
runApplication createBaffles -overwrite
runApplication mergeOrSplitBaffles -split -overwrite
runApplication splitBaffles -overwrite
runApplication $application