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.
245 lines
7.4 KiB
C++
245 lines
7.4 KiB
C++
/*---------------------------------------------------------------------------*\
|
|
========= |
|
|
\\ / 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
|
|
mergeOrSplitBaffles
|
|
|
|
Description
|
|
Detects faces that share points (baffles) and merge them into internal
|
|
faces.
|
|
|
|
\*---------------------------------------------------------------------------*/
|
|
|
|
#include "argList.H"
|
|
#include "Time.H"
|
|
#include "syncTools.H"
|
|
#include "faceSet.H"
|
|
#include "pointSet.H"
|
|
#include "meshTools.H"
|
|
#include "polyTopoChange.H"
|
|
#include "polyRemoveFace.H"
|
|
#include "polyModifyFace.H"
|
|
#include "indirectPrimitivePatch.H"
|
|
#include "processorPolyPatch.H"
|
|
#include "localPointRegion.H"
|
|
#include "duplicatePoints.H"
|
|
#include "ReadFields.H"
|
|
#include "volFields.H"
|
|
#include "surfaceFields.H"
|
|
#include "pointFields.H"
|
|
|
|
using namespace Foam;
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
|
|
void mergeDuplicateBoundaryFaces
|
|
(
|
|
const polyMesh& mesh,
|
|
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();
|
|
|
|
forAll(duplicates, bFacei)
|
|
{
|
|
label otherFacei = duplicates[bFacei];
|
|
|
|
if (otherFacei != -1 && otherFacei > bFacei)
|
|
{
|
|
// Two duplicate faces. Merge.
|
|
|
|
label face0 = mesh.nInternalFaces() + bFacei;
|
|
label face1 = mesh.nInternalFaces() + otherFacei;
|
|
|
|
label own0 = faceOwner[face0];
|
|
label own1 = faceOwner[face1];
|
|
|
|
if (own0 < own1)
|
|
{
|
|
// Use face0 as the new internal face.
|
|
label zoneID = faceZones.whichZone(face0);
|
|
bool zoneFlip = false;
|
|
|
|
if (zoneID >= 0)
|
|
{
|
|
const faceZone& fZone = faceZones[zoneID];
|
|
zoneFlip = fZone.flipMap()[fZone.whichFace(face0)];
|
|
}
|
|
|
|
meshMod.setAction(polyRemoveFace(face1));
|
|
meshMod.setAction
|
|
(
|
|
polyModifyFace
|
|
(
|
|
faces[face0], // modified face
|
|
face0, // label of face being modified
|
|
own0, // owner
|
|
own1, // neighbour
|
|
false, // face flip
|
|
-1, // patch for face
|
|
false, // remove from zone
|
|
zoneID, // zone for face
|
|
zoneFlip // face flip in zone
|
|
)
|
|
);
|
|
}
|
|
else
|
|
{
|
|
// Use face1 as the new internal face.
|
|
label zoneID = faceZones.whichZone(face1);
|
|
bool zoneFlip = false;
|
|
|
|
if (zoneID >= 0)
|
|
{
|
|
const faceZone& fZone = faceZones[zoneID];
|
|
zoneFlip = fZone.flipMap()[fZone.whichFace(face1)];
|
|
}
|
|
|
|
meshMod.setAction(polyRemoveFace(face0));
|
|
meshMod.setAction
|
|
(
|
|
polyModifyFace
|
|
(
|
|
faces[face1], // modified face
|
|
face1, // label of face being modified
|
|
own1, // owner
|
|
own0, // neighbour
|
|
false, // face flip
|
|
-1, // patch for face
|
|
false, // remove from zone
|
|
zoneID, // zone for face
|
|
zoneFlip // face flip in zone
|
|
)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
argList::addNote
|
|
(
|
|
"Detect faces that share points (baffles)\n"
|
|
"and merge them into internal faces."
|
|
);
|
|
|
|
#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);
|
|
|
|
// Merge duplicate boundary faces into internal faces.
|
|
mergeDuplicateBoundaryFaces(mesh, 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;
|
|
}
|
|
|
|
|
|
// ************************************************************************* //
|