/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-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 .
\*---------------------------------------------------------------------------*/
#include "cyclicAMIPolyPatch.H"
#include "SubField.H"
#include "vectorList.H"
#include "polyTopoChange.H"
// * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * * //
void Foam::cyclicAMIPolyPatch::restoreScaledGeometry()
{
DebugInFunction << endl;
// Note: only used for topology update (createAMIFaces_ flag)
if (!createAMIFaces_)
{
FatalErrorInFunction
<< "Attempted to perform topology update when createAMIFaces_ "
<< "flag is set to false"
<< abort(FatalError);
}
if (boundaryMesh().mesh().hasCellVolumes())
{
WarningInFunction
<< "Mesh already has volumes set!"
<< endl;
}
vectorField::subField faceAreas = this->faceAreas();
vectorField::subField faceCentres = this->faceCentres();
DebugInfo
<< "Patch:" << name() << " before: sum(mag(faceAreas)):"
<< gSum(mag(faceAreas)) << nl
<< "Patch:" << name() << " before: sum(mag(faceAreas0)):"
<< gSum(mag(faceAreas0_)) << endl;
faceAreas = faceAreas0_;
if (moveFaceCentres_)
{
DebugInfo << "Moving face centres" << endl;
faceCentres = faceCentres0_;
}
faceAreas0_.clear();
faceCentres0_.clear();
DebugInfo
<< "Patch:" << name() << " after: sum(mag(faceAreas)):"
<< gSum(mag(faceAreas)) << nl
<< "Patch:" << name() << " after: sum(mag(faceAreas0)):"
<< gSum(mag(faceAreas0_)) << endl;
}
bool Foam::cyclicAMIPolyPatch::removeAMIFaces(polyTopoChange& topoChange)
{
DebugInFunction << endl;
// Note: only used for topology update (createAMIFaces_ flag)
if (!createAMIFaces_)
{
FatalErrorInFunction
<< "Attempted to perform topology update when createAMIFaces_ "
<< "flag is set to false"
<< abort(FatalError);
}
if (!owner())
{
return false;
}
bool changeRequired = false;
// Remove any faces that we inserted to create the 1-to-1 match...
const cyclicAMIPolyPatch& nbr = neighbPatch();
const label newSrcFaceStart = srcFaceIDs_.size();
if (newSrcFaceStart != 0)
{
for (label facei = newSrcFaceStart; facei < size(); ++facei)
{
changeRequired = true;
label meshFacei = start() + facei;
topoChange.removeFace(meshFacei, -1);
}
}
const label newTgtFaceStart = tgtFaceIDs_.size();
if (newTgtFaceStart != 0)
{
for (label facei = newTgtFaceStart; facei < nbr.size(); ++facei)
{
changeRequired = true;
label meshFacei = nbr.start() + facei;
topoChange.removeFace(meshFacei, -1);
}
}
srcFaceIDs_.clear();
tgtFaceIDs_.clear();
return changeRequired;
}
bool Foam::cyclicAMIPolyPatch::addAMIFaces(polyTopoChange& topoChange)
{
DebugInFunction << endl;
// Note: only used for topology update (createAMIFaces_ flag = true)
if (!createAMIFaces_)
{
FatalErrorInFunction
<< "Attempted to perform topology update when createAMIFaces_ "
<< "flag is set to false"
<< abort(FatalError);
}
bool changedFaces = false;
const cyclicAMIPolyPatch& nbr = neighbPatch();
polyMesh& mesh = const_cast(boundaryMesh().mesh());
const faceZoneMesh& faceZones = mesh.faceZones();
// First face address and weight are used to manipulate the
// original face - all other addresses and weights are used to
// create additional faces
const labelListList& srcToTgtAddr = AMI().srcAddress();
const labelListList& tgtToSrcAddr = AMI().tgtAddress();
const label nSrcFace = srcToTgtAddr.size();
const label nTgtFace = tgtToSrcAddr.size();
srcFaceIDs_.setSize(nSrcFace);
tgtFaceIDs_.setSize(nTgtFace);
label nNewSrcFaces = 0;
forAll(srcToTgtAddr, srcFacei)
{
const labelList& tgtAddr = srcToTgtAddr[srcFacei];
// No tgt faces linked to srcFacei (ACMI)
if (tgtAddr.empty()) continue;
srcFaceIDs_[srcFacei].setSize(tgtAddr.size());
srcFaceIDs_[srcFacei][0] = srcFacei;
const label meshFacei = start() + srcFacei;
for (label addri = 1; addri < tgtAddr.size(); ++addri)
{
changedFaces = true;
// Note: new faces reuse originating face points
// - but areas are scaled by the weights (later)
// New source face for each target face address
srcFaceIDs_[srcFacei][addri] = nNewSrcFaces + nSrcFace;
++nNewSrcFaces;
(void)topoChange.addFace
(
mesh.faces()[meshFacei], // modified face
mesh.faceOwner()[meshFacei], // owner
-1, // neighbour
-1, // master point
-1, // master edge
meshFacei, // master face
false, // face flip
index(), // patch for face
faceZones.whichZone(meshFacei), // zone for original face
false // face flip in zone
);
}
}
label nNewTgtFaces = 0;
forAll(tgtToSrcAddr, tgtFacei)
{
const labelList& srcAddr = tgtToSrcAddr[tgtFacei];
// No src faces linked to tgtFacei (ACMI)
if (srcAddr.empty()) continue;
tgtFaceIDs_[tgtFacei].setSize(srcAddr.size());
tgtFaceIDs_[tgtFacei][0] = tgtFacei;
const label meshFacei = nbr.start() + tgtFacei;
for (label addri = 1; addri < srcAddr.size(); ++addri)
{
changedFaces = true;
// Note: new faces reuse originating face points
// - but areas are scaled by the weights (later)
// New target face for each source face address
tgtFaceIDs_[tgtFacei][addri] = nNewTgtFaces + nTgtFace;
++nNewTgtFaces;
(void)topoChange.addFace
(
mesh.faces()[meshFacei], // modified face
mesh.faceOwner()[meshFacei], // owner
-1, // neighbour
-1, // master point
-1, // master edge
meshFacei, // master face
false, // face flip
nbr.index(), // patch for face
faceZones.whichZone(meshFacei), // zone for original face
false // face flip in zone
);
}
}
Info<< "AMI: Patch " << name() << " additional faces: "
<< returnReduce(nNewSrcFaces, sumOp