AMIInterpolation, cyclicAMI: Removed

AMIInterpolation and cyclicAMI have been superseded by patchToPatch and
nonConformalCoupled, respectively.

The motivation behind this change is explained in the following article:

    https://cfd.direct/openfoam/free-software/non-conformal-coupling/

Information about how to convert a case which uses cyclicAMI to
nonConformalCoupled can be found here:

    https://cfd.direct/openfoam/free-software/using-non-conformal-coupling/
This commit is contained in:
Will Bainbridge
2022-09-22 10:05:41 +01:00
parent aa25763e14
commit f4ac5f8748
139 changed files with 42 additions and 14745 deletions

View File

@ -1082,11 +1082,7 @@ Foam::MomentumTransferPhaseSystem<BasePhaseSystem>::ddtCorrByAs
forAll(this->mesh_.boundary(), patchi)
{
// Set ddtPhiCorr to 0 on non-coupled boundaries
if
(
!this->mesh_.boundary()[patchi].coupled()
|| isA<cyclicAMIFvPatch>(this->mesh_.boundary()[patchi])
)
if (!this->mesh_.boundary()[patchi].coupled())
{
phiCorrCoeffBf[patchi] = 0;
}

View File

@ -300,19 +300,6 @@ void Foam::MovingPhaseModel<BasePhaseModel>::correctUf()
/mesh.magSf()
- (n & Uf_())
);
surfaceVectorField::Boundary& UfBf = Uf_.ref().boundaryFieldRef();
const volVectorField::Boundary& UBf = U_.boundaryField();
forAll(mesh.boundary(), patchi)
{
// Remove the flux correction on AMI patches to compensate for
// AMI non-conservation error
if (isA<cyclicAMIFvPatch>(mesh.boundary()[patchi]))
{
UfBf[patchi] = UBf[patchi];
}
}
}
}

View File

@ -24,7 +24,6 @@ License
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "AMIInterpolation.H"
#include "cpuTime.H"
#include "patchToPatch.H"
#include "polyMesh.H"
@ -51,13 +50,6 @@ int main(int argc, char *argv[])
cpuTime time;
/*
AMIInterpolation(srcPatch, tgtPatch, faceAreaIntersect::tmMesh);
Info<< nl << "AMI" << ": Completed in "
<< time.cpuTimeIncrement() << " s" << nl << endl;
*/
patchToPatch::New(method, false)->update
(
srcPatch,

View File

@ -84,13 +84,10 @@ void Foam::conformalVoronoiMesh::selectSeparatedCoupledFaces
forAll(patches, patchi)
{
// Check all coupled. Avoid using .coupled() so we also pick up AMI.
if (isA<coupledPolyPatch>(patches[patchi]))
{
const coupledPolyPatch& cpp = refCast<const coupledPolyPatch>
(
patches[patchi]
);
const coupledPolyPatch& cpp =
refCast<const coupledPolyPatch>(patches[patchi]);
if (cpp.transform().transformsPosition())
{

View File

@ -13,7 +13,6 @@
#include "setWriter.H"
#include "checkTools.H"
#include "cyclicAMIPolyPatch.H"
#include "Time.H"
// Find wedge with opposite orientation. Note: does not actually check that
@ -479,107 +478,6 @@ bool Foam::checkCoupledPoints
}
void Foam::writeAMIWeightsSum
(
const polyMesh& mesh,
const primitivePatch& patch,
const scalarField& wghtSum,
const fileName& file
)
{
// Collect geometry
labelList pointToGlobal;
labelList uniqueMeshPointLabels;
autoPtr<globalIndex> globalPoints;
autoPtr<globalIndex> globalFaces;
faceList mergedFaces;
pointField mergedPoints;
Foam::PatchTools::gatherAndMerge
(
mesh,
patch.localFaces(),
patch.meshPoints(),
patch.meshPointMap(),
pointToGlobal,
uniqueMeshPointLabels,
globalPoints,
globalFaces,
mergedFaces,
mergedPoints
);
// Collect field
scalarField mergedWeights;
globalFaces().gather
(
UPstream::worldComm,
labelList(UPstream::procID(UPstream::worldComm)),
wghtSum,
mergedWeights
);
// Write the surface
if (Pstream::master())
{
vtkSurfaceWriter
(
mesh.time().writeFormat(),
mesh.time().writeCompression()
).write
(
file.path(),
"weightsSum_" + file.name(),
mergedPoints,
mergedFaces,
false,
"weightsSum",
mergedWeights
);
}
}
void Foam::writeAMIWeightsSums(const polyMesh& mesh)
{
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
const word tmName(mesh.time().timeName());
forAll(pbm, patchi)
{
if (isA<cyclicAMIPolyPatch>(pbm[patchi]))
{
const cyclicAMIPolyPatch& cpp =
refCast<const cyclicAMIPolyPatch>(pbm[patchi]);
if (cpp.owner())
{
Info<< "Calculating AMI weights between owner patch: "
<< cpp.name() << " and neighbour patch: "
<< cpp.nbrPatch().name() << endl;
writeAMIWeightsSum
(
mesh,
cpp,
cpp.weightsSum(),
fileName("postProcessing") / "src_" + tmName
);
writeAMIWeightsSum
(
mesh,
cpp.nbrPatch(),
cpp.nbrWeightsSum(),
fileName("postProcessing") / "tgt_" + tmName
);
}
}
}
}
Foam::label Foam::checkGeometry
(
const polyMesh& mesh,
@ -1044,10 +942,5 @@ Foam::label Foam::checkGeometry
}
}
if (allGeometry)
{
writeAMIWeightsSums(mesh);
}
return noFailedChecks;
}

View File

@ -23,18 +23,6 @@ namespace Foam
//- Check 0th vertex on coupled faces
bool checkCoupledPoints(const polyMesh&, const bool report, labelHashSet*);
//- Write out the weights-sums on all the AMI patches
void writeAMIWeightsSums(const polyMesh&);
//- Write out the weights-sum on the given AMI patch
void writeAMIWeightsSum
(
const polyMesh&,
const primitivePatch&,
const scalarField&,
const fileName&
);
label checkGeometry
(
const polyMesh& mesh,

View File

@ -37,7 +37,6 @@ Description
#include "fvMesh.H"
#include "pimpleControl.H"
#include "vtkSurfaceWriter.H"
#include "cyclicAMIPolyPatch.H"
#include "PatchTools.H"
#include "checkGeometry.H"
@ -48,12 +47,6 @@ using namespace Foam;
int main(int argc, char *argv[])
{
#include "addRegionOption.H"
argList::addBoolOption
(
"checkAMI",
"check AMI weights"
);
#include "setRootCase.H"
#include "createTime.H"
@ -84,13 +77,6 @@ int main(int argc, char *argv[])
)
);
const bool checkAMI = args.optionFound("checkAMI");
if (checkAMI)
{
Info<< "Writing VTK files with weights of AMI patches." << nl << endl;
}
pimpleControl pimple(mesh);
while (runTime.run())
@ -113,11 +99,6 @@ int main(int argc, char *argv[])
mesh.checkMesh(true);
if (checkAMI)
{
writeAMIWeightsSums(mesh);
}
runTime.write();
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"

View File

@ -26,6 +26,7 @@ License
#include "MapLagrangianFields.H"
#include "passiveParticleCloud.H"
#include "meshSearch.H"
#include "OSspecific.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -26,6 +26,7 @@ License
#include "MapLagrangianFields.H"
#include "passiveParticleCloud.H"
#include "meshSearch.H"
#include "OSspecific.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -27,12 +27,7 @@ labelHashSet includePatches;
forAll(patches, patchi)
{
const polyPatch& pp = patches[patchi];
if
(
!pp.coupled()
&& !isA<cyclicAMIPolyPatch>(pp)
&& !isA<emptyPolyPatch>(pp)
)
if (!pp.coupled() && !isA<emptyPolyPatch>(pp))
{
includePatches.insert(patchi);
}

View File

@ -44,7 +44,6 @@ Description
#include "surfaceFields.H"
#include "fixedValueFvPatchFields.H"
#include "distributedTriSurfaceMesh.H"
#include "cyclicAMIPolyPatch.H"
#include "symmetryPolyPatch.H"
#include "symmetryPlanePolyPatch.H"
#include "wedgePolyPatch.H"

View File

@ -51,6 +51,3 @@ epsAvg/bounding epsilon,/average:
#- gamma bounding
alpha1Min/Min\(alpha1\) =/Min(alpha1) =
alpha1Max/Max\(alpha1\) =/Max(alpha1) =
# AMI
AMIMin/AMI: Patch source sum/average =

View File

@ -11,11 +11,6 @@ cyclic
type cyclic;
}
cyclicAMI
{
type cyclicAMI;
}
cyclicSlip
{
type cyclicSlip;
@ -32,12 +27,6 @@ nonConformalError
type nonConformalError;
}
nonConformalProcessorCyclic
{
type nonConformalProcessorCyclic;
value $internalField;
}
empty
{
type empty;
@ -55,6 +44,12 @@ processorCyclic
value $internalField;
}
nonConformalProcessorCyclic
{
type nonConformalProcessorCyclic;
value $internalField;
}
symmetryPlane
{
type symmetryPlane;

View File

@ -2231,7 +2231,7 @@ _moveMesh_ ()
local line=${COMP_LINE}
local used=$(echo "$line" | grep -oE "\-[a-zA-Z]+ ")
opts="-case -checkAMI -doc -fileHandler -help -hostRoots -libs -noFunctionObjects -parallel -region -roots -srcDoc"
opts="-case -doc -fileHandler -help -hostRoots -libs -noFunctionObjects -parallel -region -roots -srcDoc"
for o in $used ; do opts="${opts/$o/}" ; done
extra=""

View File

@ -1,7 +1,7 @@
Overview
========
+ Template case for rotating geometry flow for a closed geometry
+ Can be used for MRF or NCC simulations. Also supports AMI.
+ Can be used for MRF or NCC simulations.
+ Setup to run the incompressibleFluid solver module for MRF or NCC
+ The case is designed to be meshed with snappyHexMesh
+ snappyHexMesh is setup to use 3 trisurface files
@ -74,7 +74,3 @@ NCC Simulation
+ createNonConformalCouples must then be run to generate the couple patches
required by NCC, e.g. by
createNonConformalCouples -overwrite
+ To use AMI instead of NCC, the patches must be generated by createBaffles
using a suitable configuration file, provided by createBafflesDict-AMI
createBaffles -overwrite -dict system/createBafflesDict-AMI
The interface is completed by running splitBaffles, see above

View File

@ -1,45 +0,0 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
format ascii;
class dictionary;
object createBafflesDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
internalFacesOnly true;
fields true;
baffles
{
baffleFaces
{
type faceZone;
zoneName rotatingZone;
patches
{
master
{
name AMI1;
type cyclicAMI;
neighbourPatch AMI2;
}
slave
{
name AMI2;
type cyclicAMI;
neighbourPatch AMI1;
}
}
}
}
// ************************************************************************* //

View File

@ -1,7 +1,7 @@
Overview
========
+ Template case for rotating geometry flow with single inlet and outlet
+ Can be used for MRF or NCC simulations. Also supports AMI.
+ Can be used for MRF or NCC simulations.
+ Setup to run the incompressibleFluid solver module for MRF or NCC
+ The case is designed to be meshed with snappyHexMesh
+ snappyHexMesh is setup to use 3 trisurface files
@ -80,7 +80,3 @@ NCC Simulation
+ createNonConformalCouples must then be run to generate the couple patches
required by NCC, e.g. by
createNonConformalCouples -overwrite
+ To use AMI instead of NCC, the patches must be generated by createBaffles
using a suitable configuration file, provided by createBafflesDict-AMI
createBaffles -overwrite -dict system/createBafflesDict-AMI
The interface is completed by running splitBaffles, see above

View File

@ -1,45 +0,0 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
format ascii;
class dictionary;
object createBafflesDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
internalFacesOnly true;
fields true;
baffles
{
baffleFaces
{
type faceZone;
zoneName rotatingZone;
patches
{
master
{
name AMI1;
type cyclicAMI;
neighbourPatch AMI2;
}
slave
{
name AMI2;
type cyclicAMI;
neighbourPatch AMI1;
}
}
}
}
// ************************************************************************* //

View File

@ -20,7 +20,6 @@ $(basicFvPatches)/generic/genericFvPatch.C
constraintFvPatches = $(fvPatches)/constraint
$(constraintFvPatches)/cyclic/cyclicFvPatch.C
$(constraintFvPatches)/cyclicAMI/cyclicAMIFvPatch.C
$(constraintFvPatches)/cyclicSlip/cyclicSlipFvPatch.C
$(constraintFvPatches)/empty/emptyFvPatch.C
$(constraintFvPatches)/processor/processorFvPatch.C
@ -149,11 +148,9 @@ $(basicFvPatchFields)/zeroGradient/zeroGradientFvPatchFields.C
constraintFvPatchFields = $(fvPatchFields)/constraint
$(constraintFvPatchFields)/cyclic/cyclicFvPatchFields.C
$(constraintFvPatchFields)/cyclicAMI/cyclicAMIFvPatchFields.C
$(constraintFvPatchFields)/cyclicSlip/cyclicSlipFvPatchFields.C
$(constraintFvPatchFields)/empty/emptyFvPatchFields.C
$(constraintFvPatchFields)/jumpCyclic/jumpCyclicFvPatchFields.C
$(constraintFvPatchFields)/jumpCyclicAMI/jumpCyclicAMIFvPatchFields.C
$(constraintFvPatchFields)/processor/processorFvPatchFields.C
$(constraintFvPatchFields)/processor/processorFvPatchScalarField.C
$(constraintFvPatchFields)/processorCyclic/processorCyclicFvPatchFields.C
@ -181,7 +178,6 @@ $(derivedFvPatchFields)/fixedFluxPressure/fixedFluxPressureFvPatchScalarField.C
$(derivedFvPatchFields)/fixedFluxExtrapolatedPressure/fixedFluxExtrapolatedPressureFvPatchScalarField.C
$(derivedFvPatchFields)/fixedInternalValue/fixedInternalValueFvPatchFields.C
$(derivedFvPatchFields)/fixedJump/fixedJumpFvPatchFields.C
$(derivedFvPatchFields)/fixedJumpAMI/fixedJumpAMIFvPatchFields.C
$(derivedFvPatchFields)/fixedMean/fixedMeanFvPatchFields.C
$(derivedFvPatchFields)/fixedNormalSlip/fixedNormalSlipFvPatchFields.C
$(derivedFvPatchFields)/fixedPressureCompressibleDensity/fixedPressureCompressibleDensityFvPatchScalarField.C
@ -241,7 +237,6 @@ $(derivedFvPatchFields)/uniformFixedGradient/uniformFixedGradientFvPatchFields.C
$(derivedFvPatchFields)/uniformFixedValue/uniformFixedValueFvPatchFields.C
$(derivedFvPatchFields)/uniformInletOutlet/uniformInletOutletFvPatchFields.C
$(derivedFvPatchFields)/uniformJump/uniformJumpFvPatchFields.C
$(derivedFvPatchFields)/uniformJumpAMI/uniformJumpAMIFvPatchFields.C
$(derivedFvPatchFields)/uniformTotalPressure/uniformTotalPressureFvPatchScalarField.C
$(derivedFvPatchFields)/variableHeightFlowRate/variableHeightFlowRateFvPatchField.C
$(derivedFvPatchFields)/variableHeightFlowRateInletVelocity/variableHeightFlowRateInletVelocityFvPatchVectorField.C
@ -270,7 +265,6 @@ $(basicFvsPatchFields)/sliced/slicedFvsPatchFields.C
constraintFvsPatchFields = $(fvsPatchFields)/constraint
$(constraintFvsPatchFields)/cyclic/cyclicFvsPatchFields.C
$(constraintFvsPatchFields)/cyclicAMI/cyclicAMIFvsPatchFields.C
$(constraintFvsPatchFields)/cyclicSlip/cyclicSlipFvsPatchFields.C
$(constraintFvsPatchFields)/empty/emptyFvsPatchFields.C
$(constraintFvsPatchFields)/processor/processorFvsPatchFields.C

View File

@ -26,7 +26,6 @@ License
#include "FvFaceCellWave.H"
#include "processorFvPatch.H"
#include "cyclicFvPatch.H"
#include "cyclicAMIFvPatch.H"
#include "CompactListList.H"
#include "OPstream.H"
#include "IPstream.H"
@ -528,194 +527,6 @@ Foam::FvFaceCellWave<Type, TrackingData>::handleCyclicPatches()
}
template<class Type, class TrackingData>
void
Foam::FvFaceCellWave<Type, TrackingData>::handleCyclicAMIPatches()
{
// Define combine operator for AMIInterpolation
class combine
{
FvFaceCellWave<Type, TrackingData>& solver_;
const cyclicAMIFvPatch& patch_;
public:
combine
(
FvFaceCellWave<Type, TrackingData>& solver,
const cyclicAMIFvPatch& patch
)
:
solver_(solver),
patch_(patch)
{}
void operator()
(
Type& x,
const label patchFacei,
const Type& y,
const scalar weight
) const
{
if (y.valid(solver_.data()))
{
x.updateFace
(
solver_.mesh(),
{patch_.index(), patchFacei},
y,
solver_.propagationTol(),
solver_.data()
);
}
}
};
// Transfer information across cyclicAMI halves.
forAll(mesh_.boundaryMesh(), patchi)
{
const fvPatch& patch = mesh_.boundary()[patchi];
if (isA<cyclicAMIFvPatch>(patch))
{
const cyclicAMIFvPatch& cycPatch =
refCast<const cyclicAMIFvPatch>(patch);
const cyclicAMIFvPatch& nbrPatch = cycPatch.nbrPatch();
// Create a combine operator to transfer sendInfo from nbrPatch
// to cycPatch
combine cmb(*this, cycPatch);
// Get nbrPatch data (so not just changed faces)
List<Type> sendInfo(patchFaceInfo_[nbrPatch.index()]);
// Construct default values, if necessary
List<Type> defVals;
if (cycPatch.applyLowWeightCorrection())
{
defVals = cycPatch.patch().patchInternalList(cellInfo_);
}
// Interpolate from nbrPatch to cycPatch, applying AMI
// transforms as necessary
List<Type> receiveInfo;
if (cycPatch.owner())
{
forAll(cycPatch.AMIs(), i)
{
if (cycPatch.AMITransforms()[i].transformsPosition())
{
List<Type> sendInfoT(sendInfo);
transform
(
nbrPatch,
nbrPatch.size(),
identity(nbrPatch.size()),
cycPatch.AMITransforms()[i],
sendInfo
);
cycPatch.AMIs()[i].interpolateToSource
(
sendInfoT,
cmb,
receiveInfo,
defVals
);
}
else
{
cycPatch.AMIs()[i].interpolateToSource
(
sendInfo,
cmb,
receiveInfo,
defVals
);
}
}
}
else
{
forAll(nbrPatch.AMIs(), i)
{
if (nbrPatch.AMITransforms()[i].transformsPosition())
{
List<Type> sendInfoT(sendInfo);
transform
(
nbrPatch,
nbrPatch.size(),
identity(nbrPatch.size()),
nbrPatch.AMITransforms()[i],
sendInfo
);
cycPatch.nbrPatch().AMIs()[i].interpolateToTarget
(
sendInfoT,
cmb,
receiveInfo,
defVals
);
}
else
{
cycPatch.nbrPatch().AMIs()[i].interpolateToTarget
(
sendInfo,
cmb,
receiveInfo,
defVals
);
}
}
}
// Shuffle up to remove invalid info
DynamicList<label> receiveFaces(cycPatch.size());
forAll(receiveInfo, patchFacei)
{
if (receiveInfo[patchFacei].valid(td_))
{
if (receiveFaces.size() != patchFacei)
{
receiveInfo[receiveFaces.size()] =
receiveInfo[patchFacei];
}
receiveFaces.append(patchFacei);
}
}
// Transform info across the interface
if (cycPatch.transform().transformsPosition())
{
transform
(
cycPatch,
receiveFaces.size(),
receiveFaces,
cycPatch.transform(),
receiveInfo
);
}
// Merge into global storage
mergeFaceInfo
(
cycPatch,
receiveFaces.size(),
receiveFaces,
receiveInfo
);
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type, class TrackingData>
@ -753,8 +564,7 @@ Foam::FvFaceCellWave<Type, TrackingData>::FvFaceCellWave
),
changedPatchAndFaces_(mesh_.nInternalFaces()),
changedCells_(mesh_.nCells()),
hasCyclicPatches_(hasPatch<cyclicFvPatch>()),
hasCyclicAMIPatches_(hasPatch<cyclicAMIFvPatch>())
hasCyclicPatches_(hasPatch<cyclicFvPatch>())
{
if
(
@ -996,12 +806,6 @@ Foam::label Foam::FvFaceCellWave<Type, TrackingData>::cellToFace()
handleCyclicPatches();
}
if (hasCyclicAMIPatches_)
{
// Transfer changed faces across cyclicAMIs
handleCyclicAMIPatches();
}
if (Pstream::parRun())
{
// Transfer changed faces from neighbouring processors.
@ -1030,12 +834,6 @@ Foam::label Foam::FvFaceCellWave<Type, TrackingData>::iterate
handleCyclicPatches();
}
if (hasCyclicAMIPatches_)
{
// Transfer changed faces across cyclicAMIs
handleCyclicAMIPatches();
}
if (Pstream::parRun())
{
// Transfer changed faces from neighbouring processors.

View File

@ -122,9 +122,6 @@ protected:
//- Contains cyclics
const bool hasCyclicPatches_;
//- Contains cyclicAMI
const bool hasCyclicAMIPatches_;
// Protected member functions
@ -215,9 +212,6 @@ protected:
//- Merge data from across cyclics
void handleCyclicPatches();
//- Merge data from across AMI cyclics
void handleCyclicAMIPatches();
public:

View File

@ -1,256 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 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/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::cyclicAMIFvPatchField<Type>::cyclicAMIFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
:
coupledFvPatchField<Type>(p, iF),
cyclicAMILduInterfaceField(),
cyclicAMIPatch_(refCast<const cyclicAMIFvPatch>(p))
{}
template<class Type>
Foam::cyclicAMIFvPatchField<Type>::cyclicAMIFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
coupledFvPatchField<Type>(p, iF, dict, dict.found("value")),
cyclicAMILduInterfaceField(),
cyclicAMIPatch_(refCast<const cyclicAMIFvPatch>(p))
{
if (!isA<cyclicAMIFvPatch>(p))
{
FatalIOErrorInFunction
(
dict
) << " patch type '" << p.type()
<< "' not constraint type '" << typeName << "'"
<< "\n for patch " << p.name()
<< " of field " << this->internalField().name()
<< " in file " << this->internalField().objectPath()
<< exit(FatalIOError);
}
if (!dict.found("value"))
{
if (this->coupled())
{
this->evaluate(Pstream::commsTypes::blocking);
}
else
{
fvPatchField<Type>::operator=(this->patchInternalField());
}
}
}
template<class Type>
Foam::cyclicAMIFvPatchField<Type>::cyclicAMIFvPatchField
(
const cyclicAMIFvPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
coupledFvPatchField<Type>(ptf, p, iF, mapper),
cyclicAMILduInterfaceField(),
cyclicAMIPatch_(refCast<const cyclicAMIFvPatch>(p))
{
if (!isA<cyclicAMIFvPatch>(this->patch()))
{
FatalErrorInFunction
<< "' not constraint type '" << typeName << "'"
<< "\n for patch " << p.name()
<< " of field " << this->internalField().name()
<< " in file " << this->internalField().objectPath()
<< exit(FatalIOError);
}
}
template<class Type>
Foam::cyclicAMIFvPatchField<Type>::cyclicAMIFvPatchField
(
const cyclicAMIFvPatchField<Type>& ptf,
const DimensionedField<Type, volMesh>& iF
)
:
coupledFvPatchField<Type>(ptf, iF),
cyclicAMILduInterfaceField(),
cyclicAMIPatch_(ptf.cyclicAMIPatch_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
bool Foam::cyclicAMIFvPatchField<Type>::coupled() const
{
return cyclicAMIPatch_.coupled();
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::cyclicAMIFvPatchField<Type>::patchNeighbourField
(
const Pstream::commsTypes
) const
{
const Field<Type>& iField = this->primitiveField();
const labelUList& nbrFaceCells =
cyclicAMIPatch_.cyclicAMIPatch().nbrPatch().faceCells();
Field<Type> pnf(iField, nbrFaceCells);
tmp<Field<Type>> tpnf;
if (cyclicAMIPatch_.applyLowWeightCorrection())
{
tpnf = cyclicAMIPatch_.interpolate(pnf, this->patchInternalField()());
}
else
{
tpnf = cyclicAMIPatch_.interpolate(pnf);
}
transform().transform(tpnf.ref(), tpnf());
return tpnf;
}
template<class Type>
const Foam::cyclicAMIFvPatchField<Type>&
Foam::cyclicAMIFvPatchField<Type>::nbrPatchField() const
{
const GeometricField<Type, fvPatchField, volMesh>& fld =
static_cast<const GeometricField<Type, fvPatchField, volMesh>&>
(
this->primitiveField()
);
return refCast<const cyclicAMIFvPatchField<Type>>
(
fld.boundaryField()[cyclicAMIPatch_.nbrPatchID()]
);
}
template<class Type>
void Foam::cyclicAMIFvPatchField<Type>::updateInterfaceMatrix
(
scalarField& result,
const scalarField& psiInternal,
const scalarField& coeffs,
const direction cmpt,
const Pstream::commsTypes
) const
{
const labelUList& nbrFaceCells =
cyclicAMIPatch_.cyclicAMIPatch().nbrPatch().faceCells();
scalarField pnf(psiInternal, nbrFaceCells);
// Transform according to the transformation tensors
transformCoupleField(pnf, cmpt);
if (cyclicAMIPatch_.applyLowWeightCorrection())
{
scalarField pif(psiInternal, cyclicAMIPatch_.faceCells());
pnf = cyclicAMIPatch_.interpolate(pnf, pif);
}
else
{
pnf = cyclicAMIPatch_.interpolate(pnf);
}
// Multiply the field by coefficients and add into the result
const labelUList& faceCells = cyclicAMIPatch_.faceCells();
forAll(faceCells, elemI)
{
result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
}
}
template<class Type>
void Foam::cyclicAMIFvPatchField<Type>::updateInterfaceMatrix
(
Field<Type>& result,
const Field<Type>& psiInternal,
const scalarField& coeffs,
const Pstream::commsTypes
) const
{
const labelUList& nbrFaceCells =
cyclicAMIPatch_.cyclicAMIPatch().nbrPatch().faceCells();
Field<Type> pnf(psiInternal, nbrFaceCells);
// Transform according to the transformation tensors
transformCoupleField(pnf);
if (cyclicAMIPatch_.applyLowWeightCorrection())
{
Field<Type> pif(psiInternal, cyclicAMIPatch_.faceCells());
pnf = cyclicAMIPatch_.interpolate(pnf, pif);
}
else
{
pnf = cyclicAMIPatch_.interpolate(pnf);
}
// Multiply the field by coefficients and add into the result
const labelUList& faceCells = cyclicAMIPatch_.faceCells();
forAll(faceCells, elemI)
{
result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
}
}
template<class Type>
void Foam::cyclicAMIFvPatchField<Type>::write(Ostream& os) const
{
fvPatchField<Type>::write(os);
writeEntry(os, "value", *this);
}
// ************************************************************************* //

View File

@ -1,219 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 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/>.
Class
Foam::cyclicAMIFvPatchField
Description
This boundary condition enforces a cyclic condition between a pair of
boundaries, whereby communication between the patches is performed using
an arbitrary mesh interface (AMI) interpolation.
Usage
Example of the boundary condition specification:
\verbatim
<patchName>
{
type cyclicAMI;
}
\endverbatim
Note:
The outer boundary of the patch pairs must be similar, i.e. if the owner
patch is transformed to the neighbour patch, the outer perimeter of each
patch should be identical (or very similar).
See also
Foam::AMIInterpolation
SourceFiles
cyclicAMIFvPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef cyclicAMIFvPatchField_H
#define cyclicAMIFvPatchField_H
#include "coupledFvPatchField.H"
#include "cyclicAMILduInterfaceField.H"
#include "cyclicAMIFvPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cyclicAMIFvPatchField Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class cyclicAMIFvPatchField
:
public coupledFvPatchField<Type>,
public cyclicAMILduInterfaceField
{
// Private Data
//- Local reference cast into the cyclic patch
const cyclicAMIFvPatch& cyclicAMIPatch_;
public:
//- Runtime type information
TypeName(cyclicAMIFvPatch::typeName_());
// Constructors
//- Construct from patch and internal field
cyclicAMIFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&
);
//- Construct from patch, internal field and dictionary
cyclicAMIFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const dictionary&
);
//- Construct by mapping given cyclicAMIFvPatchField onto a new patch
cyclicAMIFvPatchField
(
const cyclicAMIFvPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const fvPatchFieldMapper&
);
//- Disallow copy without setting internal field reference
cyclicAMIFvPatchField(const cyclicAMIFvPatchField<Type>&) = delete;
//- Copy constructor setting internal field reference
cyclicAMIFvPatchField
(
const cyclicAMIFvPatchField<Type>&,
const DimensionedField<Type, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchField<Type>> clone
(
const DimensionedField<Type, volMesh>& iF
) const
{
return tmp<fvPatchField<Type>>
(
new cyclicAMIFvPatchField<Type>(*this, iF)
);
}
// Member Functions
// Access
//- Return local reference cast into the cyclic AMI patch
const cyclicAMIFvPatch& cyclicAMIPatch() const
{
return cyclicAMIPatch_;
}
// Evaluation functions
//- Return true if coupled. Note that the underlying patch
// is not coupled() - the points don't align.
virtual bool coupled() const;
//- Return neighbour coupled internal cell data
virtual tmp<Field<Type>> patchNeighbourField
(
const Pstream::commsTypes
) const;
//- Return reference to neighbour patchField
const cyclicAMIFvPatchField<Type>& nbrPatchField() const;
//- Update result field based on interface functionality
virtual void updateInterfaceMatrix
(
scalarField& result,
const scalarField& psiInternal,
const scalarField& coeffs,
const direction cmpt,
const Pstream::commsTypes commsType
) const;
//- Update result field based on interface functionality
virtual void updateInterfaceMatrix
(
Field<Type>&,
const Field<Type>&,
const scalarField&,
const Pstream::commsTypes commsType
) const;
// Cyclic AMI coupled interface functions
//- Return transformation between the coupled patches
virtual const transformer& transform() const
{
return cyclicAMIPatch_.transform();
}
//- Return rank of component for transform
virtual int rank() const
{
return pTraits<Type>::rank;
}
// I-O
//- Write
virtual void write(Ostream& os) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "cyclicAMIFvPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,43 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 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/>.
\*---------------------------------------------------------------------------*/
#include "cyclicAMIFvPatchFields.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makePatchFields(cyclicAMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -1,49 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 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/>.
\*---------------------------------------------------------------------------*/
#ifndef cyclicAMIFvPatchFields_H
#define cyclicAMIFvPatchFields_H
#include "cyclicAMIFvPatchField.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeFieldTypedefs(cyclicAMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,50 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 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/>.
\*---------------------------------------------------------------------------*/
#ifndef cyclicAMIFvPatchFieldsFwd_H
#define cyclicAMIFvPatchFieldsFwd_H
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type> class cyclicAMIFvPatchField;
makePatchTypeFieldTypedefs(cyclicAMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,190 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2022 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/>.
\*---------------------------------------------------------------------------*/
#include "jumpCyclicAMIFvPatchField.H"
#include "transformField.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::jumpCyclicAMIFvPatchField<Type>::jumpCyclicAMIFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
:
cyclicAMIFvPatchField<Type>(p, iF)
{}
template<class Type>
Foam::jumpCyclicAMIFvPatchField<Type>::jumpCyclicAMIFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
cyclicAMIFvPatchField<Type>(p, iF, dict)
{
// Call this evaluation in derived classes
// this->evaluate(Pstream::commsTypes::blocking);
}
template<class Type>
Foam::jumpCyclicAMIFvPatchField<Type>::jumpCyclicAMIFvPatchField
(
const jumpCyclicAMIFvPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
cyclicAMIFvPatchField<Type>(ptf, p, iF, mapper)
{}
template<class Type>
Foam::jumpCyclicAMIFvPatchField<Type>::jumpCyclicAMIFvPatchField
(
const jumpCyclicAMIFvPatchField<Type>& ptf,
const DimensionedField<Type, volMesh>& iF
)
:
cyclicAMIFvPatchField<Type>(ptf, iF)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::jumpCyclicAMIFvPatchField<Type>::patchNeighbourField
(
const Pstream::commsTypes
) const
{
const Field<Type>& iField = this->primitiveField();
const labelUList& nbrFaceCells =
this->cyclicAMIPatch().cyclicAMIPatch().nbrPatch().faceCells();
Field<Type> pnf(iField, nbrFaceCells);
tmp<Field<Type>> tpnf;
if (this->cyclicAMIPatch().applyLowWeightCorrection())
{
tpnf =
this->cyclicAMIPatch().interpolate
(
pnf,
this->patchInternalField()()
);
}
else
{
tpnf = this->cyclicAMIPatch().interpolate(pnf);
}
this->transform().transform(tpnf.ref(), tpnf());
tmp<Field<Type>> tjf = jump();
if (!this->cyclicAMIPatch().owner())
{
tjf = -tjf;
}
return tpnf - tjf;
}
template<class Type>
void Foam::jumpCyclicAMIFvPatchField<Type>::updateInterfaceMatrix
(
scalarField& result,
const scalarField& psiInternal,
const scalarField& coeffs,
const direction cmpt,
const Pstream::commsTypes
) const
{
NotImplemented;
}
template<class Type>
void Foam::jumpCyclicAMIFvPatchField<Type>::updateInterfaceMatrix
(
Field<Type>& result,
const Field<Type>& psiInternal,
const scalarField& coeffs,
const Pstream::commsTypes
) const
{
const labelUList& nbrFaceCells =
this->cyclicAMIPatch().cyclicAMIPatch().nbrPatch().faceCells();
Field<Type> pnf(psiInternal, nbrFaceCells);
if (this->cyclicAMIPatch().applyLowWeightCorrection())
{
pnf =
this->cyclicAMIPatch().interpolate
(
pnf,
this->patchInternalField()()
);
}
else
{
pnf = this->cyclicAMIPatch().interpolate(pnf);
}
// only apply jump to original field
if (&psiInternal == &this->primitiveField())
{
Field<Type> jf(this->jump());
if (!this->cyclicAMIPatch().owner())
{
jf *= -1.0;
}
pnf -= jf;
}
// Transform according to the transformation tensors
this->transformCoupleField(pnf);
// Multiply the field by coefficients and add into the result
const labelUList& faceCells = this->cyclicAMIPatch().faceCells();
forAll(faceCells, elemI)
{
result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
}
}
// ************************************************************************* //

View File

@ -1,177 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2022 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/>.
Class
Foam::jumpCyclicAMIFvPatchField
Description
This boundary condition provides a base class that enforces a cyclic
condition with a specified 'jump' (or offset) between a pair of boundaries,
whereby communication between the patches is performed using an arbitrary
mesh interface (AMI) interpolation.
See also
Foam::cyclicAMIFvPatchField
SourceFiles
jumpCyclicAMIFvPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef jumpCyclicAMIFvPatchField_H
#define jumpCyclicAMIFvPatchField_H
#include "cyclicAMIFvPatchField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class jumpCyclicAMIFvPatchField Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class jumpCyclicAMIFvPatchField
:
public cyclicAMIFvPatchField<Type>
{
public:
//- Runtime type information
TypeName("jumpCyclicAMI");
// Constructors
//- Construct from patch and internal field
jumpCyclicAMIFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&
);
//- Construct from patch, internal field and dictionary
jumpCyclicAMIFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const dictionary&
);
//- Construct by mapping given jumpCyclicAMIFvPatchField onto a
// new patch
jumpCyclicAMIFvPatchField
(
const jumpCyclicAMIFvPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const fvPatchFieldMapper&
);
//- Disallow copy without setting internal field reference
jumpCyclicAMIFvPatchField
(
const jumpCyclicAMIFvPatchField<Type>&
) = delete;
//- Copy constructor setting internal field reference
jumpCyclicAMIFvPatchField
(
const jumpCyclicAMIFvPatchField<Type>&,
const DimensionedField<Type, volMesh>&
);
// Member Functions
// Access
//- Return the interface type
virtual const word& interfaceFieldType() const
{
return cyclicAMIFvPatchField<Type>::type();
}
//- Return the "jump" across the patch as a "half" field
virtual tmp<Field<Type>> jump() const = 0;
// Evaluation functions
//- Return neighbour coupled given internal cell data
virtual tmp<Field<Type>> patchNeighbourField
(
const Pstream::commsTypes
) const;
//- Update result field based on interface functionality
virtual void updateInterfaceMatrix
(
scalarField& result,
const scalarField& psiInternal,
const scalarField& coeffs,
const direction cmpt,
const Pstream::commsTypes commsType
) const;
//- Update result field based on interface functionality
virtual void updateInterfaceMatrix
(
Field<Type>&,
const Field<Type>&,
const scalarField&,
const Pstream::commsTypes commsType
) const;
};
//- Update result field based on interface functionality
template<>
void jumpCyclicAMIFvPatchField<scalar>::updateInterfaceMatrix
(
scalarField& result,
const scalarField& psiInternal,
const scalarField& coeffs,
const direction cmpt,
const Pstream::commsTypes commsType
) const;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "jumpCyclicAMIFvPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,87 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2020 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/>.
\*---------------------------------------------------------------------------*/
#include "jumpCyclicAMIFvPatchFields.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makePatchFieldTypeNames(jumpCyclicAMI);
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<>
void Foam::jumpCyclicAMIFvPatchField<scalar>::updateInterfaceMatrix
(
scalarField& result,
const scalarField& psiInternal,
const scalarField& coeffs,
const direction cmpt,
const Pstream::commsTypes
) const
{
const labelUList& nbrFaceCells =
this->cyclicAMIPatch().cyclicAMIPatch().nbrPatch().faceCells();
scalarField pnf(psiInternal, nbrFaceCells);
pnf = this->cyclicAMIPatch().interpolate(pnf);
// only apply jump to original field
if (&psiInternal == &this->primitiveField())
{
Field<scalar> jf(this->jump());
if (!this->cyclicAMIPatch().owner())
{
jf *= -1.0;
}
pnf -= jf;
}
// Transform according to the transformation tensors
this->transformCoupleField(pnf, cmpt);
// Multiply the field by coefficients and add into the result
const labelUList& faceCells = this->cyclicAMIPatch().faceCells();
forAll(faceCells, elemI)
{
result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -1,49 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2018 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/>.
\*---------------------------------------------------------------------------*/
#ifndef jumpCyclicAMIFvPatchFields_H
#define jumpCyclicAMIFvPatchFields_H
#include "jumpCyclicAMIFvPatchField.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeFieldTypedefs(jumpCyclicAMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,50 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2018 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/>.
\*---------------------------------------------------------------------------*/
#ifndef jumpCyclicAMIFvPatchFieldsFwd_H
#define jumpCyclicAMIFvPatchFieldsFwd_H
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type> class jumpCyclicAMIFvPatchField;
makePatchTypeFieldTypedefs(jumpCyclicAMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,186 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2022 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/>.
\*---------------------------------------------------------------------------*/
#include "fixedJumpAMIFvPatchField.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::fixedJumpAMIFvPatchField<Type>::fixedJumpAMIFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
:
jumpCyclicAMIFvPatchField<Type>(p, iF),
jump_(this->size(), Zero)
{}
template<class Type>
Foam::fixedJumpAMIFvPatchField<Type>::fixedJumpAMIFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
jumpCyclicAMIFvPatchField<Type>(p, iF),
jump_(p.size(), Zero)
{
if (this->cyclicAMIPatch().owner())
{
jump_ = Field<Type>("jump", dict, p.size());
}
if (dict.found("value"))
{
fvPatchField<Type>::operator=
(
Field<Type>("value", dict, p.size())
);
}
else
{
this->evaluate(Pstream::commsTypes::blocking);
}
}
template<class Type>
Foam::fixedJumpAMIFvPatchField<Type>::fixedJumpAMIFvPatchField
(
const fixedJumpAMIFvPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
jumpCyclicAMIFvPatchField<Type>(ptf, p, iF, mapper),
jump_(mapper(ptf.jump_))
{}
template<class Type>
Foam::fixedJumpAMIFvPatchField<Type>::fixedJumpAMIFvPatchField
(
const fixedJumpAMIFvPatchField<Type>& ptf,
const DimensionedField<Type, volMesh>& iF
)
:
jumpCyclicAMIFvPatchField<Type>(ptf, iF),
jump_(ptf.jump_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::fixedJumpAMIFvPatchField<Type>::jump() const
{
if (this->cyclicAMIPatch().owner())
{
return jump_;
}
else
{
const fixedJumpAMIFvPatchField& nbrPatch =
refCast<const fixedJumpAMIFvPatchField<Type>>
(
this->nbrPatchField()
);
if (this->cyclicAMIPatch().applyLowWeightCorrection())
{
return this->cyclicAMIPatch().interpolate
(
nbrPatch.jump(),
Field<Type>(this->size(), Zero)
);
}
else
{
return this->cyclicAMIPatch().interpolate(nbrPatch.jump());
}
}
}
template<class Type>
void Foam::fixedJumpAMIFvPatchField<Type>::autoMap
(
const fvPatchFieldMapper& m
)
{
jumpCyclicAMIFvPatchField<Type>::autoMap(m);
m(jump_, jump_);
}
template<class Type>
void Foam::fixedJumpAMIFvPatchField<Type>::rmap
(
const fvPatchField<Type>& ptf,
const labelList& addr
)
{
jumpCyclicAMIFvPatchField<Type>::rmap(ptf, addr);
const fixedJumpAMIFvPatchField<Type>& tiptf =
refCast<const fixedJumpAMIFvPatchField<Type>>(ptf);
jump_.rmap(tiptf.jump_, addr);
}
template<class Type>
void Foam::fixedJumpAMIFvPatchField<Type>::reset
(
const fvPatchField<Type>& ptf
)
{
jumpCyclicAMIFvPatchField<Type>::reset(ptf);
const fixedJumpAMIFvPatchField<Type>& tiptf =
refCast<const fixedJumpAMIFvPatchField<Type>>(ptf);
jump_.reset(tiptf.jump_);
}
template<class Type>
void Foam::fixedJumpAMIFvPatchField<Type>::write(Ostream& os) const
{
fvPatchField<Type>::write(os);
writeEntry(os, "patchType", this->interfaceFieldType());
if (this->cyclicAMIPatch().owner())
{
writeEntry(os, "jump", jump_);
}
writeEntry(os, "value", *this);
}
// ************************************************************************* //

View File

@ -1,191 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2022 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/>.
Class
Foam::fixedJumpAMIFvPatchField
Description
This boundary condition provides a jump condition, across non-conformal
cyclic path-pairs, employing an arbitraryMeshInterface (AMI).
The jump is specified as a fixed value field, applied as an offset to the
'owner' patch.
Usage
\table
Property | Description | Required | Default value
patchType | underlying patch type should be \c cyclic| yes |
jump | current jump value | yes |
\endtable
Example of the boundary condition specification:
\verbatim
<patchName>
{
type fixedJumpAMI;
patchType cyclic;
jump uniform 10;
}
\endverbatim
The above example shows the use of a fixed jump of '10'.
Note:
The underlying \c patchType should be set to \c cyclicAMI
See also
Foam::jumpCyclicAMIFvPatchField
SourceFiles
fixedJumpAMIFvPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef fixedJumpAMIFvPatchField_H
#define fixedJumpAMIFvPatchField_H
#include "jumpCyclicAMIFvPatchField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class fixedJumpAMIFvPatchField Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class fixedJumpAMIFvPatchField
:
public jumpCyclicAMIFvPatchField<Type>
{
protected:
// Protected data
//- "jump" field
Field<Type> jump_;
public:
//- Runtime type information
TypeName("fixedJumpAMI");
// Constructors
//- Construct from patch and internal field
fixedJumpAMIFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&
);
//- Construct from patch, internal field and dictionary
fixedJumpAMIFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const dictionary&
);
//- Construct by mapping given fixedJumpAMIFvPatchField onto a
// new patch
fixedJumpAMIFvPatchField
(
const fixedJumpAMIFvPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const fvPatchFieldMapper&
);
//- Disallow copy without setting internal field reference
fixedJumpAMIFvPatchField
(
const fixedJumpAMIFvPatchField<Type>&
) = delete;
//- Copy constructor setting internal field reference
fixedJumpAMIFvPatchField
(
const fixedJumpAMIFvPatchField<Type>&,
const DimensionedField<Type, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchField<Type>> clone
(
const DimensionedField<Type, volMesh>& iF
) const
{
return tmp<fvPatchField<Type>>
(
new fixedJumpAMIFvPatchField<Type>(*this, iF)
);
}
// Member Functions
// Access
//- Return the "jump" across the patch
virtual tmp<Field<Type>> jump() const;
// Mapping functions
//- Map (and resize as needed) from self given a mapping object
virtual void autoMap(const fvPatchFieldMapper&);
//- Reverse map the given fvPatchField onto this fvPatchField
virtual void rmap(const fvPatchField<Type>&, const labelList&);
//- Reset the fvPatchField to the given fvPatchField
// Used for mesh to mesh mapping
virtual void reset(const fvPatchField<Type>&);
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "fixedJumpAMIFvPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,43 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2018 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/>.
\*---------------------------------------------------------------------------*/
#include "fixedJumpAMIFvPatchFields.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makePatchFields(fixedJumpAMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -1,49 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2018 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/>.
\*---------------------------------------------------------------------------*/
#ifndef fixedJumpAMIFvPatchFields_H
#define fixedJumpAMIFvPatchFields_H
#include "fixedJumpAMIFvPatchField.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeFieldTypedefs(fixedJumpAMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,50 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2018 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/>.
\*---------------------------------------------------------------------------*/
#ifndef fixedJumpAMIFvPatchFieldsFwd_H
#define fixedJumpAMIFvPatchFieldsFwd_H
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type> class fixedJumpAMIFvPatchField;
makePatchTypeFieldTypedefs(fixedJumpAMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,125 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2022 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/>.
\*---------------------------------------------------------------------------*/
#include "uniformJumpAMIFvPatchField.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::uniformJumpAMIFvPatchField<Type>::uniformJumpAMIFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
:
fixedJumpAMIFvPatchField<Type>(p, iF),
jumpTable_()
{}
template<class Type>
Foam::uniformJumpAMIFvPatchField<Type>::uniformJumpAMIFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
fixedJumpAMIFvPatchField<Type>(p, iF),
jumpTable_()
{
if (this->cyclicAMIPatch().owner())
{
jumpTable_ = Function1<Type>::New("jumpTable", dict);
}
if (dict.found("value"))
{
fvPatchField<Type>::operator=(Field<Type>("value", dict, p.size()));
}
else
{
this->evaluate(Pstream::commsTypes::blocking);
}
}
template<class Type>
Foam::uniformJumpAMIFvPatchField<Type>::uniformJumpAMIFvPatchField
(
const uniformJumpAMIFvPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedJumpAMIFvPatchField<Type>(ptf, p, iF, mapper),
jumpTable_(ptf.jumpTable_, false)
{}
template<class Type>
Foam::uniformJumpAMIFvPatchField<Type>::uniformJumpAMIFvPatchField
(
const uniformJumpAMIFvPatchField<Type>& ptf,
const DimensionedField<Type, volMesh>& iF
)
:
fixedJumpAMIFvPatchField<Type>(ptf, iF),
jumpTable_(ptf.jumpTable_, false)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::uniformJumpAMIFvPatchField<Type>::updateCoeffs()
{
if (this->updated())
{
return;
}
if (this->cyclicAMIPatch().owner())
{
this->jump_ = jumpTable_->value(this->db().time().userTimeValue());
}
fixedJumpAMIFvPatchField<Type>::updateCoeffs();
}
template<class Type>
void Foam::uniformJumpAMIFvPatchField<Type>::write(Ostream& os) const
{
fixedJumpAMIFvPatchField<Type>::write(os);
if (this->cyclicAMIPatch().owner())
{
writeEntry(os, jumpTable_());
}
}
// ************************************************************************* //

View File

@ -1,178 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2022 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/>.
Class
Foam::uniformJumpAMIFvPatchField
Description
This boundary condition provides a jump condition, using the \c cyclicAMI
condition as a base. The jump is specified as a time-varying uniform
value across the patch.
Usage
\table
Property | Description | Required | Default value
patchType | underlying patch type should be \c cyclicAMI| yes |
jumpTable | jump value | yes |
\endtable
Example of the boundary condition specification:
\verbatim
<patchName>
{
type uniformJumpAMI;
patchType cyclicAMI;
jumpTable constant 10;
}
\endverbatim
The above example shows the use of a fixed jump of '10'.
Note:
The uniformValue entry is a Function1 type, able to describe time
varying functions. The example above gives the usage for supplying a
constant value.
The underlying \c patchType should be set to \c cyclic
See also
Foam::jumpCyclicAMIFvPatchField
Foam::Function1s
SourceFiles
uniformJumpAMIFvPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef uniformJumpAMIFvPatchField_H
#define uniformJumpAMIFvPatchField_H
#include "fixedJumpAMIFvPatchField.H"
#include "Function1.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class uniformJumpAMIFvPatchField Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class uniformJumpAMIFvPatchField
:
public fixedJumpAMIFvPatchField<Type>
{
protected:
// Protected data
//- "jump" table
autoPtr<Function1<Type>> jumpTable_;
public:
//- Runtime type information
TypeName("uniformJumpAMI");
// Constructors
//- Construct from patch and internal field
uniformJumpAMIFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&
);
//- Construct from patch, internal field and dictionary
uniformJumpAMIFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const dictionary&
);
//- Construct by mapping given uniformJumpAMIFvPatchField onto a
// new patch
uniformJumpAMIFvPatchField
(
const uniformJumpAMIFvPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const fvPatchFieldMapper&
);
//- Disallow copy without setting internal field reference
uniformJumpAMIFvPatchField
(
const uniformJumpAMIFvPatchField<Type>&
) = delete;
//- Copy constructor setting internal field reference
uniformJumpAMIFvPatchField
(
const uniformJumpAMIFvPatchField<Type>&,
const DimensionedField<Type, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchField<Type>> clone
(
const DimensionedField<Type, volMesh>& iF
) const
{
return tmp<fvPatchField<Type>>
(
new uniformJumpAMIFvPatchField<Type>(*this, iF)
);
}
// Member Functions
//- Update the coefficients
virtual void updateCoeffs();
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "uniformJumpAMIFvPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,43 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2018 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/>.
\*---------------------------------------------------------------------------*/
#include "uniformJumpAMIFvPatchFields.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makePatchFields(uniformJumpAMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -1,49 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2018 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/>.
\*---------------------------------------------------------------------------*/
#ifndef uniformJumpAMIFvPatchFields_H
#define uniformJumpAMIFvPatchFields_H
#include "uniformJumpAMIFvPatchField.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeFieldTypedefs(uniformJumpAMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,50 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2018 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/>.
\*---------------------------------------------------------------------------*/
#ifndef uniformJumpAMIFvPatchFieldsFwd_H
#define uniformJumpAMIFvPatchFieldsFwd_H
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type> class uniformJumpAMIFvPatchField;
makePatchTypeFieldTypedefs(uniformJumpAMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,142 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
\*---------------------------------------------------------------------------*/
#include "cyclicAMIFvsPatchField.H"
#include "GeometricField.H"
#include "surfaceMesh.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::cyclicAMIFvsPatchField<Type>::cyclicAMIFvsPatchField
(
const fvPatch& p,
const DimensionedField<Type, surfaceMesh>& iF
)
:
coupledFvsPatchField<Type>(p, iF),
cyclicAMIPatch_(refCast<const cyclicAMIFvPatch>(p))
{}
template<class Type>
Foam::cyclicAMIFvsPatchField<Type>::cyclicAMIFvsPatchField
(
const cyclicAMIFvsPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, surfaceMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
coupledFvsPatchField<Type>(ptf, p, iF, mapper),
cyclicAMIPatch_(refCast<const cyclicAMIFvPatch>(p))
{
if (!isA<cyclicAMIFvPatch>(this->patch()))
{
FatalErrorInFunction
<< "Field type does not correspond to patch type for patch "
<< this->patch().index() << "." << endl
<< "Field type: " << typeName << endl
<< "Patch type: " << this->patch().type()
<< exit(FatalError);
}
}
template<class Type>
Foam::cyclicAMIFvsPatchField<Type>::cyclicAMIFvsPatchField
(
const fvPatch& p,
const DimensionedField<Type, surfaceMesh>& iF,
const dictionary& dict
)
:
coupledFvsPatchField<Type>(p, iF, dict),
cyclicAMIPatch_(refCast<const cyclicAMIFvPatch>(p))
{
if (!isA<cyclicAMIFvPatch>(p))
{
FatalIOErrorInFunction
(
dict
) << "patch " << this->patch().index() << " not cyclicAMI type. "
<< "Patch type = " << p.type()
<< exit(FatalIOError);
}
}
template<class Type>
Foam::cyclicAMIFvsPatchField<Type>::cyclicAMIFvsPatchField
(
const cyclicAMIFvsPatchField<Type>& ptf,
const DimensionedField<Type, surfaceMesh>& iF
)
:
coupledFvsPatchField<Type>(ptf, iF),
cyclicAMIPatch_(ptf.cyclicAMIPatch_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
bool Foam::cyclicAMIFvsPatchField<Type>::coupled() const
{
return cyclicAMIPatch_.coupled();
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::cyclicAMIFvsPatchField<Type>::patchNeighbourField
(
const Pstream::commsTypes commsType
) const
{
typedef GeometricField<Type, fvsPatchField, surfaceMesh> geoField;
const geoField& gf = refCast<const geoField>(this->internalField());
const cyclicAMIFvPatch& cp = refCast<const cyclicAMIFvPatch>(this->patch());
const Field<Type>& pnf = gf.boundaryField()[cp.nbrPatchID()];
tmp<Field<Type>> tpnf;
if (cp.applyLowWeightCorrection())
{
tpnf = cyclicAMIPatch_.interpolate(pnf, *this);
}
else
{
tpnf = cyclicAMIPatch_.interpolate(pnf);
}
cp.transform().transform(tpnf.ref(), tpnf());
return tpnf;
}
// ************************************************************************* //

View File

@ -1,147 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
Class
Foam::cyclicAMIFvsPatchField
Description
Foam::cyclicAMIFvsPatchField
SourceFiles
cyclicAMIFvsPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef cyclicAMIFvsPatchField_H
#define cyclicAMIFvsPatchField_H
#include "coupledFvsPatchField.H"
#include "cyclicAMIFvPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cyclicAMIFvsPatchField Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class cyclicAMIFvsPatchField
:
public coupledFvsPatchField<Type>
{
// Private Data
//- Local reference cast into the cyclic patch
const cyclicAMIFvPatch& cyclicAMIPatch_;
public:
//- Runtime type information
TypeName(cyclicAMIFvPatch::typeName_());
// Constructors
//- Construct from patch and internal field
cyclicAMIFvsPatchField
(
const fvPatch&,
const DimensionedField<Type, surfaceMesh>&
);
//- Construct from patch, internal field and dictionary
cyclicAMIFvsPatchField
(
const fvPatch&,
const DimensionedField<Type, surfaceMesh>&,
const dictionary&
);
//- Construct by mapping given cyclicAMIFvsPatchField onto a new patch
cyclicAMIFvsPatchField
(
const cyclicAMIFvsPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, surfaceMesh>&,
const fvPatchFieldMapper&
);
//- Disallow copy without setting internal field reference
cyclicAMIFvsPatchField(const cyclicAMIFvsPatchField<Type>&) = delete;
//- Copy constructor setting internal field reference
cyclicAMIFvsPatchField
(
const cyclicAMIFvsPatchField<Type>&,
const DimensionedField<Type, surfaceMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvsPatchField<Type>> clone
(
const DimensionedField<Type, surfaceMesh>& iF
) const
{
return tmp<fvsPatchField<Type>>
(
new cyclicAMIFvsPatchField<Type>(*this, iF)
);
}
// Member Functions
// Access
//- Return true if running parallel
virtual bool coupled() const;
// Evaluation functions
//- Return patchField on the opposite patch of a coupled patch
virtual tmp<Field<Type>> patchNeighbourField
(
const Pstream::commsTypes commsType
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "cyclicAMIFvsPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,43 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 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/>.
\*---------------------------------------------------------------------------*/
#include "cyclicAMIFvsPatchFields.H"
#include "fvsPatchFields.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makeFvsPatchFields(cyclicAMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -1,49 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 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/>.
\*---------------------------------------------------------------------------*/
#ifndef cyclicAMIFvsPatchFields_H
#define cyclicAMIFvsPatchFields_H
#include "cyclicAMIFvsPatchField.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makeFvsPatchTypeFieldTypedefs(cyclicAMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,50 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 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/>.
\*---------------------------------------------------------------------------*/
#ifndef cyclicAMIFvsPatchFieldsFwd_H
#define cyclicAMIFvsPatchFieldsFwd_H
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type> class cyclicAMIFvsPatchField;
makeFvsPatchTypeFieldTypedefs(cyclicAMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

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-2021 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -27,7 +27,6 @@ License
#include "HashTable.H"
#include "surfaceInterpolate.H"
#include "fvMatrix.H"
#include "cyclicAMIFvPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -182,13 +181,9 @@ tmp<surfaceScalarField> ddtScheme<Type>::fvcDdtPhiCoeff
forAll(U.boundaryField(), patchi)
{
if
(
!U.boundaryField()[patchi].coupled()
|| isA<cyclicAMIFvPatch>(mesh().boundary()[patchi])
)
if (!U.boundaryField()[patchi].coupled())
{
ccbf[patchi] = 0.0;
ccbf[patchi] = 0;
}
}

View File

@ -339,13 +339,9 @@ tmp<surfaceScalarField> localEulerDdtScheme<Type>::fvcDdtPhiCoeff
forAll(U.boundaryField(), patchi)
{
if
(
U.boundaryField()[patchi].fixesValue()
|| isA<cyclicAMIFvPatch>(mesh().boundary()[patchi])
)
if (U.boundaryField()[patchi].fixesValue())
{
ccbf[patchi] = 0.0;
ccbf[patchi] = 0;
}
}

View File

@ -31,7 +31,6 @@ License
#include "slicedSurfaceFields.H"
#include "SubField.H"
#include "cyclicFvPatchFields.H"
#include "cyclicAMIFvPatchFields.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //

View File

@ -1,191 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 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/>.
\*---------------------------------------------------------------------------*/
#include "cyclicAMIFvPatch.H"
#include "addToRunTimeSelectionTable.H"
#include "fvMesh.H"
#include "Time.H"
#include "transform.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cyclicAMIFvPatch, 0);
addToRunTimeSelectionTable(fvPatch, cyclicAMIFvPatch, polyPatch);
}
// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
Foam::tmp<Foam::scalarField> Foam::cyclicAMIFvPatch::deltan() const
{
return nf() & coupledFvPatch::delta();
}
Foam::tmp<Foam::scalarField> Foam::cyclicAMIFvPatch::nbrDeltan() const
{
if (coupled())
{
const cyclicAMIFvPatch& nbrPatch = neighbFvPatch();
tmp<scalarField> tnbrDeltan;
if (applyLowWeightCorrection())
{
tnbrDeltan =
interpolate
(
nbrPatch.nf() & nbrPatch.coupledFvPatch::delta(),
scalarField(this->size(), 1.0)
);
}
else
{
tnbrDeltan =
interpolate(nbrPatch.nf() & nbrPatch.coupledFvPatch::delta());
}
return tnbrDeltan;
}
else
{
return tmp<scalarField>();
}
}
void Foam::cyclicAMIFvPatch::makeWeights(scalarField& w) const
{
if (coupled())
{
const scalarField deltan(this->deltan());
const scalarField nbrDeltan(this->nbrDeltan());
forAll(deltan, facei)
{
scalar di = deltan[facei];
scalar dni = nbrDeltan[facei];
w[facei] = dni/(di + dni);
}
}
else
{
// Behave as uncoupled patch
fvPatch::makeWeights(w);
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::cyclicAMIFvPatch::coupled() const
{
return
Pstream::parRun()
|| !this->boundaryMesh().mesh().time().processorCase();
}
Foam::tmp<Foam::vectorField> Foam::cyclicAMIFvPatch::delta() const
{
const cyclicAMIFvPatch& nbrPatch = neighbFvPatch();
if (coupled())
{
const vectorField patchD(coupledFvPatch::delta());
tmp<vectorField> tnbrPatchD;
if (applyLowWeightCorrection())
{
tnbrPatchD =
interpolate
(
nbrPatch.coupledFvPatch::delta(),
vectorField(this->size(), Zero)
);
}
else
{
tnbrPatchD = interpolate(nbrPatch.coupledFvPatch::delta());
}
const vectorField& nbrPatchD = tnbrPatchD();
tmp<vectorField> tpdv(new vectorField(patchD.size()));
vectorField& pdv = tpdv.ref();
// do the transformation if necessary
if (transform().transforms())
{
forAll(patchD, facei)
{
const vector& ddi = patchD[facei];
const vector& dni = nbrPatchD[facei];
pdv[facei] = ddi - transform().transform(dni);
}
}
else
{
forAll(patchD, facei)
{
const vector& ddi = patchD[facei];
const vector& dni = nbrPatchD[facei];
pdv[facei] = ddi - dni;
}
}
return tpdv;
}
else
{
return coupledFvPatch::delta();
}
}
Foam::tmp<Foam::labelField> Foam::cyclicAMIFvPatch::interfaceInternalField
(
const labelUList& internalData
) const
{
return patchInternalField(internalData);
}
Foam::tmp<Foam::labelField> Foam::cyclicAMIFvPatch::internalFieldTransfer
(
const Pstream::commsTypes commsType,
const labelUList& iF
) const
{
return neighbFvPatch().patchInternalField(iF);
}
// ************************************************************************* //

View File

@ -1,211 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 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/>.
Class
Foam::cyclicAMIFvPatch
Description
Cyclic patch for Arbitrary Mesh Interface (AMI)
SourceFiles
cyclicAMIFvPatch.C
\*---------------------------------------------------------------------------*/
#ifndef cyclicAMIFvPatch_H
#define cyclicAMIFvPatch_H
#include "coupledFvPatch.H"
#include "cyclicAMILduInterface.H"
#include "cyclicAMIPolyPatch.H"
#include "fvBoundaryMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cyclicAMIFvPatch Declaration
\*---------------------------------------------------------------------------*/
class cyclicAMIFvPatch
:
public coupledFvPatch,
public cyclicAMILduInterface
{
// Private Data
const cyclicAMIPolyPatch& cyclicAMIPolyPatch_;
protected:
// Protected Member functions
//- Return the patch-normal component of the deltas
tmp<scalarField> deltan() const;
//- Return the neighbour patch-normal component of the deltas
tmp<scalarField> nbrDeltan() const;
//- Make patch weighting factors
virtual void makeWeights(scalarField&) const;
public:
//- Runtime type information
TypeName(cyclicAMIPolyPatch::typeName_());
// Constructors
//- Construct from polyPatch
cyclicAMIFvPatch(const polyPatch& patch, const fvBoundaryMesh& bm)
:
coupledFvPatch(patch, bm),
cyclicAMILduInterface(),
cyclicAMIPolyPatch_(refCast<const cyclicAMIPolyPatch>(patch))
{}
// Member Functions
// Access
//- Return local reference cast into the cyclic patch
const cyclicAMIPolyPatch& cyclicAMIPatch() const
{
return cyclicAMIPolyPatch_;
}
//- Return the neighbour patch ID
virtual label nbrPatchID() const
{
return cyclicAMIPolyPatch_.nbrPatchID();
}
//- Is this side the owner?
virtual bool owner() const
{
return cyclicAMIPolyPatch_.owner();
}
//- Return the neighbour patch
virtual const cyclicAMIFvPatch& nbrPatch() const
{
return refCast<const cyclicAMIFvPatch>
(
this->boundaryMesh()[cyclicAMIPolyPatch_.nbrPatchID()]
);
}
//- Return a reference to the AMI interpolators
virtual const PtrList<AMIInterpolation>& AMIs() const
{
return cyclicAMIPolyPatch_.AMIs();
}
//- Return a reference to the AMI transforms
virtual const List<transformer>& AMITransforms() const
{
return cyclicAMIPolyPatch_.AMITransforms();
}
//- Return true if applying the low weight correction
virtual bool applyLowWeightCorrection() const
{
return cyclicAMIPolyPatch_.applyLowWeightCorrection();
}
//- Return transformation between the coupled patches
virtual const transformer& transform() const
{
return cyclicAMIPolyPatch_.transform();
}
const cyclicAMIFvPatch& neighbFvPatch() const
{
return refCast<const cyclicAMIFvPatch>
(
this->boundaryMesh()[cyclicAMIPolyPatch_.nbrPatchID()]
);
}
//- Return true if this patch is coupled. This is equivalent
// to the coupledPolyPatch::coupled() if parallel running or
// both sides present, false otherwise
virtual bool coupled() const;
//- Return delta (P to N) vectors across coupled patch
virtual tmp<vectorField> delta() const;
template<class Type>
tmp<Field<Type>> interpolate
(
const Field<Type>& fld,
const UList<Type>& defaultValues = UList<Type>()
) const
{
return cyclicAMIPolyPatch_.interpolate(fld, defaultValues);
}
template<class Type>
tmp<Field<Type>> interpolate
(
const tmp<Field<Type>>& tFld,
const UList<Type>& defaultValues = UList<Type>()
) const
{
return cyclicAMIPolyPatch_.interpolate(tFld, defaultValues);
}
// Interface transfer functions
//- Return the values of the given internal data adjacent to
// the interface as a field
virtual tmp<labelField> interfaceInternalField
(
const labelUList& internalData
) const;
//- Return neighbour field
virtual tmp<labelField> internalFieldTransfer
(
const Pstream::commsTypes commsType,
const labelUList& internalData
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2020 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2020-2022 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -65,7 +65,7 @@ Description
}
\endverbatim
This is particularly useful for cases with rotating regions, e.g. mixer
vessels with AMI.
vessels with NCC.
See also
Foam::functionObjects::fieldExpression

View File

@ -163,19 +163,6 @@ void Foam::findCellParticle::hitCyclicPatch
}
void Foam::findCellParticle::hitCyclicAMIPatch
(
const vector&,
const scalar,
Cloud<findCellParticle>&,
trackingData& td
)
{
// Remove particle
td.keepParticle = false;
}
void Foam::findCellParticle::hitProcessorPatch
(
Cloud<findCellParticle>& cloud,

View File

@ -201,15 +201,6 @@ public:
//- Overridable function to handle the particle hitting a cyclic
void hitCyclicPatch(Cloud<findCellParticle>&, trackingData&);
//- Overridable function to handle the particle hitting a cyclicAMI
void hitCyclicAMIPatch
(
const vector&,
const scalar,
Cloud<findCellParticle>&,
trackingData&
);
//- Overridable function to handle the particle hitting a
//- processorPatch
void hitProcessorPatch(Cloud<findCellParticle>&, trackingData&);

View File

@ -27,6 +27,7 @@ License
#include "wordReList.H"
#include "findCellParticle.H"
#include "OBJstream.H"
#include "globalIndex.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //

View File

@ -38,6 +38,7 @@ License
#include "polyTopoChangeMap.H"
#include "polyMeshMap.H"
#include "polyDistributionMap.H"
#include "OSspecific.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -373,22 +373,6 @@ void Foam::streamlinesParticle::hitCyclicPatch
}
void Foam::streamlinesParticle::hitCyclicAMIPatch
(
const vector& displacement,
const scalar fraction,
streamlinesCloud& cloud,
trackingData& td
)
{
// End this track
endTrack(td);
// Move across the cyclic
particle::hitCyclicAMIPatch(displacement, fraction, cloud, td);
}
bool Foam::streamlinesParticle::hitNonConformalCyclicPatch
(
const vector& displacement,

View File

@ -252,16 +252,6 @@ public:
//- Overridable function to handle the particle hitting a cyclic
void hitCyclicPatch(streamlinesCloud&, trackingData&);
//- Overridable function to handle the particle hitting a
// cyclicAMIPatch
void hitCyclicAMIPatch
(
const vector&,
const scalar,
streamlinesCloud&,
trackingData&
);
//- Overridable function to handle the particle hitting an
// nonConformalCyclicPolyPatch
bool hitNonConformalCyclicPatch

View File

@ -33,7 +33,6 @@ License
#include "Time.H"
#include "OFstream.H"
#include "wallPolyPatch.H"
#include "cyclicAMIPolyPatch.H"
#include "nonConformalCyclicPolyPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -61,32 +60,6 @@ struct IDLListAppendEqOp
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
template<class ParticleType>
void Foam::Cloud<ParticleType>::checkPatches() const
{
const polyBoundaryMesh& pbm = pMesh_.boundaryMesh();
bool ok = true;
forAll(pbm, patchi)
{
if (isA<cyclicAMIPolyPatch>(pbm[patchi]))
{
const cyclicAMIPolyPatch& cami =
refCast<const cyclicAMIPolyPatch>(pbm[patchi]);
ok = ok && cami.singlePatchProc() != -1;
}
}
if (!ok)
{
FatalErrorInFunction
<< "Particle tracking across AMI patches is only currently "
<< "supported for cases where the AMI patches reside on a "
<< "single processor" << abort(FatalError);
}
}
template<class ParticleType>
Foam::labelList Foam::Cloud<ParticleType>::patchNbrProc
(
@ -224,8 +197,6 @@ Foam::Cloud<ParticleType>::Cloud
patchNonConformalCyclicPatches_(patchNonConformalCyclicPatches(pMesh)),
globalPositionsPtr_()
{
checkPatches();
// Ask for the tetBasePtIs and oldCellCentres to trigger all processors to
// build them, otherwise, if some processors have no particles then there
// is a comms mismatch.

View File

@ -94,9 +94,6 @@ class Cloud
// Private Member Functions
//- Check patches
void checkPatches() const;
//- Initialise cloud on IO constructor
void initCloud(const bool checkClass);

View File

@ -154,8 +154,6 @@ Foam::Cloud<ParticleType>::Cloud
patchNonConformalCyclicPatches_(patchNonConformalCyclicPatches(pMesh)),
globalPositionsPtr_()
{
checkPatches();
pMesh_.tetBasePtIs();
pMesh_.oldCellCentres();

View File

@ -27,6 +27,7 @@ License
#include "polyTopoChangeMap.H"
#include "transform.H"
#include "treeDataCell.H"
#include "indexedOctree.H"
#include "cubicEqn.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //

View File

@ -56,7 +56,6 @@ class particle;
class polyPatch;
class cyclicPolyPatch;
class cyclicAMIPolyPatch;
class processorPolyPatch;
class symmetryPlanePolyPatch;
class symmetryPolyPatch;
@ -338,16 +337,6 @@ protected:
template<class TrackCloudType>
void hitCyclicPatch(TrackCloudType&, trackingData&);
//- Overridable function to handle the particle hitting a cyclicAMIPatch
template<class TrackCloudType>
void hitCyclicAMIPatch
(
const vector& displacement,
const scalar fraction,
TrackCloudType& cloud,
trackingData& td
);
//- Overridable function to handle the particle hitting an
// nonConformalCyclicPolyPatch
template<class TrackCloudType>

View File

@ -27,7 +27,6 @@ License
#include "IOPosition.H"
#include "cyclicPolyPatch.H"
#include "cyclicAMIPolyPatch.H"
#include "nonConformalCyclicPolyPatch.H"
#include "processorPolyPatch.H"
#include "symmetryPlanePolyPatch.H"
@ -170,10 +169,6 @@ void Foam::particle::hitFace
{
p.hitCyclicPatch(cloud, ttd);
}
else if (isA<cyclicAMIPolyPatch>(patch))
{
p.hitCyclicAMIPatch(displacement, fraction, cloud, ttd);
}
else if (isA<processorPolyPatch>(patch))
{
p.hitProcessorPatch(cloud, ttd);
@ -278,122 +273,6 @@ void Foam::particle::hitCyclicPatch(TrackCloudType&, trackingData& td)
}
template<class TrackCloudType>
void Foam::particle::hitCyclicAMIPatch
(
const vector& displacement,
const scalar fraction,
TrackCloudType& cloud,
trackingData& td
)
{
const cyclicAMIPolyPatch& cpp =
static_cast<const cyclicAMIPolyPatch&>
(
td.mesh.boundaryMesh()[patch(td.mesh)]
);
const cyclicAMIPolyPatch& receiveCpp = cpp.nbrPatch();
if (debug)
{
Info<< "Particle " << origId() << " crossing AMI from " << cpp.name()
<< " to " << receiveCpp.name() << endl << endl;
}
// Get the send patch data
vector sendNormal, sendDisplacement;
patchData(td.mesh, sendNormal, sendDisplacement);
vector pos = position(td.mesh);
const labelPair receiveIs =
cpp.pointAMIAndFace
(
cpp.whichFace(facei_),
displacement - fraction*sendDisplacement,
pos
);
const label receiveAMIi = receiveIs.first();
const label receiveFacei = receiveIs.second();
// If the receiving face could not be found then issue a warning and remove
// the particle
if (receiveFacei < 0)
{
td.keepParticle = false;
WarningInFunction
<< "Particle transfer from " << cyclicAMIPolyPatch::typeName
<< " patches " << cpp.name() << " to " << receiveCpp.name()
<< " failed at position " << pos << " and with displacement "
<< (displacement - fraction*sendDisplacement) << nl
<< " A receiving face could not be found" << nl
<< " The particle has been removed" << nl << endl;
return;
}
// Set the topology
facei_ = tetFacei_ = receiveFacei + receiveCpp.start();
// Locate the particle on the receiving side
locate
(
td.mesh,
pos,
td.mesh.faceOwner()[facei_],
false,
"Particle crossed between " + cyclicAMIPolyPatch::typeName +
" patches " + cpp.name() + " and " + receiveCpp.name() +
" to a location outside of the mesh."
);
// The particle must remain associated with a face for the tracking to
// register as incomplete
facei_ = tetFacei_;
// Transform the properties
vector displacementT = displacement;
const transformer AMITransform =
receiveCpp.owner()
? receiveCpp.AMITransforms()[receiveAMIi]
: inv(cpp.AMITransforms()[receiveAMIi]);
if (AMITransform.transformsPosition())
{
transformProperties(AMITransform);
displacementT = AMITransform.transform(displacementT);
}
if (receiveCpp.transform().transformsPosition())
{
transformProperties(receiveCpp.transform());
displacementT = receiveCpp.transform().transform(displacementT);
}
// If on a boundary and the displacement points into the receiving face
// then issue a warning and remove the particle
if (onBoundaryFace(td.mesh))
{
vector receiveNormal, receiveDisplacement;
patchData(td.mesh, receiveNormal, receiveDisplacement);
if (((displacementT - fraction*receiveDisplacement)&receiveNormal) > 0)
{
td.keepParticle = false;
WarningInFunction
<< "Particle transfer from " << cyclicAMIPolyPatch::typeName
<< " patches " << cpp.name() << " to " << receiveCpp.name()
<< " failed at position " << pos << " and with displacement "
<< (displacementT - fraction*receiveDisplacement) << nl
<< " The displacement points into both the source and "
<< "receiving faces, so the tracking cannot proceed" << nl
<< " The particle has been removed" << nl << endl;
return;
}
}
}
template<class TrackCloudType>
bool Foam::particle::hitNonConformalCyclicPatch
(

View File

@ -41,6 +41,7 @@ Description
#include "dimensionedTypes.H"
#include "fvMesh.H"
#include "fluidThermo.H"
#include "globalIndex.H"
#include "Cloud.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

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-2021 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -28,6 +28,7 @@ License
#include "ListListOps.H"
#include "surfaceWriter.H"
#include "globalIndex.H"
#include "OSspecific.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //

View File

@ -31,6 +31,7 @@ License
#include "triangle.H"
#include "cloud.H"
#include "axesRotation.H"
#include "OSspecific.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //

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-2022 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -28,6 +28,7 @@ License
#include "stringListOps.H"
#include "ListOps.H"
#include "ListListOps.H"
#include "OSspecific.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //

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-2022 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -26,7 +26,6 @@ License
#include "patchInteractionDataList.H"
#include "stringListOps.H"
#include "emptyPolyPatch.H"
#include "cyclicAMIPolyPatch.H"
// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //

View File

@ -2077,13 +2077,10 @@ void Foam::meshRefinement::selectSeparatedCoupledFaces(boolList& selected) const
forAll(patches, patchi)
{
// Check all coupled. Avoid using .coupled() so we also pick up AMI.
if (isA<coupledPolyPatch>(patches[patchi]))
{
const coupledPolyPatch& cpp = refCast<const coupledPolyPatch>
(
patches[patchi]
);
const coupledPolyPatch& cpp =
refCast<const coupledPolyPatch>(patches[patchi]);
if (cpp.transform().transformsPosition())
{

View File

@ -191,19 +191,6 @@ void Foam::trackedParticle::hitCyclicPatch
}
void Foam::trackedParticle::hitCyclicAMIPatch
(
const vector&,
const scalar,
Cloud<trackedParticle>&,
trackingData& td
)
{
// Remove particle
td.keepParticle = false;
}
void Foam::trackedParticle::hitWallPatch
(
Cloud<trackedParticle>&,

View File

@ -233,15 +233,6 @@ public:
//- Overridable function to handle the particle hitting a cyclic
void hitCyclicPatch(Cloud<trackedParticle>&, trackingData&);
//- Overridable function to handle the particle hitting a cyclicAMI
void hitCyclicAMIPatch
(
const vector&,
const scalar,
Cloud<trackedParticle>&,
trackingData&
);
//- Overridable function to handle the particle hitting a wallPatch
void hitWallPatch(Cloud<trackedParticle>&, trackingData&);

View File

@ -1,574 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 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/>.
Class
Foam::AMIInterpolation
Description
Interpolation class dealing with transfer of data between two
primitive patches with an arbitrary mesh interface (AMI).
Based on the algorithm given in:
Conservative interpolation between volume meshes by local Galerkin
projection, Farrell PE and Maddison JR, 2011, Comput. Methods Appl.
Mech Engrg, Volume 200, Issues 1-4, pp 89-100
Interpolation requires that the two patches should have opposite
orientations (opposite normals). The 'reverseTarget' flag can be used to
reverse the orientation of the target patch.
SourceFiles
AMIInterpolation.C
AMIInterpolationParallelOps.C
AMIInterpolationTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef AMIInterpolation_H
#define AMIInterpolation_H
#include "className.H"
#include "searchableSurface.H"
#include "treeBoundBoxList.H"
#include "boolList.H"
#include "primitivePatch.H"
#include "faceAreaIntersect.H"
#include "faceAreaWeightAMI.H"
#include "globalIndex.H"
#include "ops.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class AMIInterpolation Declaration
\*---------------------------------------------------------------------------*/
class AMIInterpolation
{
// Private Data
//- Interpolation method
const word methodName_;
//- Flag to indicate that the two patches are co-directional and
// that the orientation of the target patch should be reversed
const bool reverseTarget_;
//- Flag to indicate that the two patches must be matched/an overlap
// exists between them
const bool requireMatch_;
//- Index of processor that holds all of both sides. -1 in all other
// cases
label singlePatchProc_;
//- Threshold weight below which interpolation is deactivated
scalar lowWeightCorrection_;
// Source patch
//- Source face areas
scalarField srcMagSf_;
//- Addresses of target faces per source face
labelListList srcAddress_;
//- Weights of target faces per source face
scalarListList srcWeights_;
//- Sum of weights of target faces per source face
scalarField srcWeightsSum_;
// Target patch
//- Target face areas
scalarField tgtMagSf_;
//- Addresses of source faces per target face
labelListList tgtAddress_;
//- Weights of source faces per target face
scalarListList tgtWeights_;
//- Sum of weights of source faces per target face
scalarField tgtWeightsSum_;
//- Face triangulation mode
const faceAreaIntersect::triangulationMode triMode_;
//- Source map pointer - parallel running only
autoPtr<distributionMap> srcMapPtr_;
//- Target map pointer - parallel running only
autoPtr<distributionMap> tgtMapPtr_;
// Parallel functionality
//- Calculate if patches are on multiple processors
label calcDistribution
(
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch
) const;
label calcOverlappingProcs
(
const List<treeBoundBoxList>& procBb,
const treeBoundBox& bb,
boolList& overlaps
) const;
void distributePatches
(
const distributionMap& map,
const primitivePatch& pp,
const globalIndex& gi,
List<faceList>& faces,
List<pointField>& points,
List<labelList>& tgtFaceIDs
) const;
void distributeAndMergePatches
(
const distributionMap& map,
const primitivePatch& tgtPatch,
const globalIndex& gi,
faceList& tgtFaces,
pointField& tgtPoints,
labelList& tgtFaceIDs
) const;
autoPtr<distributionMap> calcProcMap
(
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch
) const;
// Initialisation
//- Project points to surface
void projectPointsToSurface
(
const searchableSurface& surf,
pointField& pts
) const;
// Manipulation
//- Sum the weights for each face
static void sumWeights
(
const scalarListList& wght,
scalarField& wghtSum
);
//- As above, but for multiple sets of weights
static void sumWeights
(
const UPtrList<scalarListList>& wghts,
scalarField& wghtSum
);
//- Print out information relating to the weights sum. Values close
// to one are ideal. This information acts as a measure of the
// quality of the AMI.
static void reportSumWeights
(
const scalarField& patchAreas,
const word& patchName,
const scalarField& wghtSum,
const scalar lowWeightTol
);
//- Normalise the weights so that they sum to one for each face.
// This may stabilise the solution at the expense of accuracy.
static void normaliseWeights
(
scalarListList& wght,
const scalarField& wghtSum
);
//- As above but for multiple sets of weights
static void normaliseWeights
(
UPtrList<scalarListList>& wghts,
const scalarField& wghtSum
);
// Constructor helpers
static void agglomerate
(
const autoPtr<distributionMap>& targetMap,
const scalarField& fineSrcMagSf,
const labelListList& fineSrcAddress,
const scalarListList& fineSrcWeights,
const labelList& sourceRestrictAddressing,
const labelList& targetRestrictAddressing,
scalarField& srcMagSf,
labelListList& srcAddress,
scalarListList& srcWeights,
scalarField& srcWeightsSum,
autoPtr<distributionMap>& tgtMap
);
void constructFromSurface
(
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch,
const autoPtr<searchableSurface>& surfPtr,
const bool report
);
public:
//- Runtime type information
TypeName("cyclicAMI");
// Constructors
//- Construct from components
AMIInterpolation
(
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch,
const faceAreaIntersect::triangulationMode& triMode,
const bool requireMatch = true,
const word& methodName = faceAreaWeightAMI::typeName,
const scalar lowWeightCorrection = -1,
const bool reverseTarget = false,
const bool report = true
);
//- Construct from components, with projection surface
AMIInterpolation
(
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch,
const autoPtr<searchableSurface>& surf,
const faceAreaIntersect::triangulationMode& triMode,
const bool requireMatch = true,
const word& methodName = faceAreaWeightAMI::typeName,
const scalar lowWeightCorrection = -1,
const bool reverseTarget = false,
const bool report = true
);
//- Construct from agglomeration of AMIInterpolation.
// Agglomeration passed in as new coarse size and addressing from fine
// from coarse
AMIInterpolation
(
const AMIInterpolation& fineAMI,
const labelList& sourceRestrictAddressing,
const labelList& neighbourRestrictAddressing,
const bool report = false
);
//- Disallow default bitwise copy construction
AMIInterpolation(const AMIInterpolation&) = delete;
//- Destructor
virtual ~AMIInterpolation();
// Member Functions
// Access
//- Set to -1, or the processor holding all faces (both sides) of
// the AMI
inline label singlePatchProc() const;
//- Threshold weight below which interpolation is deactivated
inline scalar lowWeightCorrection() const;
//- Return true if employing a 'lowWeightCorrection'
inline bool applyLowWeightCorrection() const;
// Source patch
//- Return const access to source patch face areas
inline const scalarField& srcMagSf() const;
//- Return const access to source patch addressing
inline const labelListList& srcAddress() const;
//- Return const access to source patch weights
inline const scalarListList& srcWeights() const;
//- Return access to source patch weights
inline scalarListList& srcWeights();
//- Return const access to normalisation factor of source
// patch weights (i.e. the sum before normalisation)
inline const scalarField& srcWeightsSum() const;
//- Return access to normalisation factor of source
// patch weights (i.e. the sum before normalisation)
inline scalarField& srcWeightsSum();
//- Source map pointer - valid only if singlePatchProc = -1
// This gets source data into a form to be consumed by
// tgtAddress, tgtWeights
inline const distributionMap& srcMap() const;
// Target patch
//- Return const access to target patch face areas
inline const scalarField& tgtMagSf() const;
//- Return const access to target patch addressing
inline const labelListList& tgtAddress() const;
//- Return const access to target patch weights
inline const scalarListList& tgtWeights() const;
//- Return access to target patch weights
inline scalarListList& tgtWeights();
//- Return const access to normalisation factor of target
// patch weights (i.e. the sum before normalisation)
inline const scalarField& tgtWeightsSum() const;
//- Return access to normalisation factor of target
// patch weights (i.e. the sum before normalisation)
inline scalarField& tgtWeightsSum();
//- Target map pointer - valid only if singlePatchProc=-1.
// This gets target data into a form to be consumed by
// srcAddress, srcWeights
inline const distributionMap& tgtMap() const;
// Manipulation
//- Update addressing and weights
void update
(
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch,
const bool report
);
//- Sum the weights on both sides of an AMI
static void sumWeights(AMIInterpolation& AMI);
//- As above, but for multiple AMI-s
static void sumWeights(PtrList<AMIInterpolation>& AMIs);
//- Print out information relating to the weights sum. Values close
// to one are ideal. This information acts as a measure of the
// quality of the AMI.
static void reportSumWeights(AMIInterpolation& AMI);
//- Normalise the weights on both sides of an AMI
static void normaliseWeights(AMIInterpolation& AMI);
//- As above, but for multiple AMI-s
static void normaliseWeights(UPtrList<AMIInterpolation>& AMIs);
// Evaluation
// Low-level
//- Interpolate from target to source with supplied op
// to combine existing value with remote value and weight
template<class Type, class CombineOp>
void interpolateToSource
(
const UList<Type>& fld,
const CombineOp& cop,
List<Type>& result,
const UList<Type>& defaultValues = UList<Type>::null()
) const;
//- Interpolate from source to target with supplied op
// to combine existing value with remote value and weight
template<class Type, class CombineOp>
void interpolateToTarget
(
const UList<Type>& fld,
const CombineOp& cop,
List<Type>& result,
const UList<Type>& defaultValues = UList<Type>::null()
) const;
//- Interpolate from target to source with supplied op
template<class Type, class CombineOp>
tmp<Field<Type>> interpolateToSource
(
const Field<Type>& fld,
const CombineOp& cop,
const UList<Type>& defaultValues = UList<Type>::null()
) const;
//- Interpolate from target tmp field to source with supplied op
template<class Type, class CombineOp>
tmp<Field<Type>> interpolateToSource
(
const tmp<Field<Type>>& tFld,
const CombineOp& cop,
const UList<Type>& defaultValues = UList<Type>::null()
) const;
//- Interpolate from source to target with supplied op
template<class Type, class CombineOp>
tmp<Field<Type>> interpolateToTarget
(
const Field<Type>& fld,
const CombineOp& cop,
const UList<Type>& defaultValues = UList<Type>::null()
) const;
//- Interpolate from source tmp field to target with supplied op
template<class Type, class CombineOp>
tmp<Field<Type>> interpolateToTarget
(
const tmp<Field<Type>>& tFld,
const CombineOp& cop,
const UList<Type>& defaultValues = UList<Type>::null()
) const;
//- Interpolate from target to source
template<class Type>
tmp<Field<Type>> interpolateToSource
(
const Field<Type>& fld,
const UList<Type>& defaultValues = UList<Type>::null()
) const;
//- Interpolate from target tmp field
template<class Type>
tmp<Field<Type>> interpolateToSource
(
const tmp<Field<Type>>& tFld,
const UList<Type>& defaultValues = UList<Type>::null()
) const;
//- Interpolate from source to target
template<class Type>
tmp<Field<Type>> interpolateToTarget
(
const Field<Type>& fld,
const UList<Type>& defaultValues = UList<Type>::null()
) const;
//- Interpolate from source tmp field
template<class Type>
tmp<Field<Type>> interpolateToTarget
(
const tmp<Field<Type>>& tFld,
const UList<Type>& defaultValues = UList<Type>::null()
) const;
// Point intersections
//- Return source patch face index of point on target patch face
label srcPointFace
(
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch,
const vector& n,
const label tgtFacei,
point& tgtPoint
)
const;
//- Return target patch face index of point on source patch face
label tgtPointFace
(
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch,
const vector& n,
const label srcFacei,
point& srcPoint
)
const;
//- Calculate the patch face magnitudes for the given tri-mode
static tmp<scalarField> patchMagSf
(
const primitivePatch& patch,
const faceAreaIntersect::triangulationMode triMode
);
// Checks
//- Write face connectivity as OBJ file
void writeFaceConnectivity
(
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch,
const labelListList& srcAddress
) const;
// Member Operators
//- Disallow default bitwise assignment
void operator=(const AMIInterpolation&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "AMIInterpolationI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "AMIInterpolationTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,128 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 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/>.
\*---------------------------------------------------------------------------*/
inline Foam::label Foam::AMIInterpolation::singlePatchProc() const
{
return singlePatchProc_;
}
inline Foam::scalar Foam::AMIInterpolation::lowWeightCorrection() const
{
return lowWeightCorrection_;
}
inline bool Foam::AMIInterpolation::applyLowWeightCorrection() const
{
return lowWeightCorrection_ > 0;
}
inline const Foam::scalarField& Foam::AMIInterpolation::srcMagSf() const
{
return srcMagSf_;
}
inline const Foam::labelListList& Foam::AMIInterpolation::srcAddress() const
{
return srcAddress_;
}
inline const Foam::scalarListList& Foam::AMIInterpolation::srcWeights() const
{
return srcWeights_;
}
inline Foam::scalarListList& Foam::AMIInterpolation::srcWeights()
{
return srcWeights_;
}
inline const Foam::scalarField& Foam::AMIInterpolation::srcWeightsSum() const
{
return srcWeightsSum_;
}
inline Foam::scalarField& Foam::AMIInterpolation::srcWeightsSum()
{
return srcWeightsSum_;
}
inline const Foam::distributionMap& Foam::AMIInterpolation::srcMap() const
{
return srcMapPtr_();
}
inline const Foam::scalarField& Foam::AMIInterpolation::tgtMagSf() const
{
return tgtMagSf_;
}
inline const Foam::labelListList& Foam::AMIInterpolation::tgtAddress() const
{
return tgtAddress_;
}
inline const Foam::scalarListList& Foam::AMIInterpolation::tgtWeights() const
{
return tgtWeights_;
}
inline Foam::scalarListList& Foam::AMIInterpolation::tgtWeights()
{
return tgtWeights_;
}
inline const Foam::scalarField& Foam::AMIInterpolation::tgtWeightsSum() const
{
return tgtWeightsSum_;
}
inline Foam::scalarField& Foam::AMIInterpolation::tgtWeightsSum()
{
return tgtWeightsSum_;
}
inline const Foam::distributionMap& Foam::AMIInterpolation::tgtMap() const
{
return tgtMapPtr_();
}
// ************************************************************************* //

View File

@ -1,474 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 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/>.
\*---------------------------------------------------------------------------*/
#include "AMIInterpolation.H"
#include "mergePoints.H"
#include "distributionMap.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::label Foam::AMIInterpolation::calcDistribution
(
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch
) const
{
label proci = 0;
if (Pstream::parRun())
{
List<label> facesPresentOnProc(Pstream::nProcs(), 0);
if ((srcPatch.size() > 0) || (tgtPatch.size() > 0))
{
facesPresentOnProc[Pstream::myProcNo()] = 1;
}
else
{
facesPresentOnProc[Pstream::myProcNo()] = 0;
}
Pstream::gatherList(facesPresentOnProc);
Pstream::scatterList(facesPresentOnProc);
label nHaveFaces = sum(facesPresentOnProc);
if (nHaveFaces > 1)
{
proci = -1;
if (debug)
{
InfoInFunction
<< "AMI split across multiple processors" << endl;
}
}
else if (nHaveFaces == 1)
{
proci = findIndex(facesPresentOnProc, 1);
if (debug)
{
InfoInFunction
<< "AMI local to processor" << proci << endl;
}
}
}
// Either not parallel or no faces on any processor
return proci;
}
Foam::label Foam::AMIInterpolation::calcOverlappingProcs
(
const List<treeBoundBoxList>& procBb,
const treeBoundBox& bb,
boolList& overlaps
) const
{
overlaps.setSize(procBb.size());
overlaps = false;
label nOverlaps = 0;
forAll(procBb, proci)
{
const treeBoundBoxList& bbs = procBb[proci];
forAll(bbs, bbI)
{
if (bbs[bbI].overlaps(bb))
{
overlaps[proci] = true;
nOverlaps++;
break;
}
}
}
return nOverlaps;
}
void Foam::AMIInterpolation::distributePatches
(
const distributionMap& map,
const primitivePatch& pp,
const globalIndex& gi,
List<faceList>& faces,
List<pointField>& points,
List<labelList>& faceIDs
) const
{
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
for (label domain = 0; domain < Pstream::nProcs(); domain++)
{
const labelList& sendElems = map.subMap()[domain];
if (domain != Pstream::myProcNo() && sendElems.size())
{
labelList globalElems(sendElems.size());
forAll(sendElems, i)
{
globalElems[i] = gi.toGlobal(sendElems[i]);
}
faceList subFaces(UIndirectList<face>(pp, sendElems));
primitivePatch subPatch
(
SubList<face>(subFaces, subFaces.size()),
pp.points()
);
if (debug & 2)
{
Pout<< "distributePatches: to processor " << domain
<< " sending faces " << subPatch.faceCentres() << endl;
}
UOPstream toDomain(domain, pBufs);
toDomain
<< subPatch.localFaces() << subPatch.localPoints()
<< globalElems;
}
}
// Start receiving
pBufs.finishedSends();
faces.setSize(Pstream::nProcs());
points.setSize(Pstream::nProcs());
faceIDs.setSize(Pstream::nProcs());
{
// Set up 'send' to myself
const labelList& sendElems = map.subMap()[Pstream::myProcNo()];
faceList subFaces(UIndirectList<face>(pp, sendElems));
primitivePatch subPatch
(
SubList<face>(subFaces, subFaces.size()),
pp.points()
);
// Receive
if (debug & 2)
{
Pout<< "distributePatches: to processor " << Pstream::myProcNo()
<< " sending faces " << subPatch.faceCentres() << endl;
}
faces[Pstream::myProcNo()] = subPatch.localFaces();
points[Pstream::myProcNo()] = subPatch.localPoints();
faceIDs[Pstream::myProcNo()].setSize(sendElems.size());
forAll(sendElems, i)
{
faceIDs[Pstream::myProcNo()][i] = gi.toGlobal(sendElems[i]);
}
}
// Consume
for (label domain = 0; domain < Pstream::nProcs(); domain++)
{
const labelList& recvElems = map.constructMap()[domain];
if (domain != Pstream::myProcNo() && recvElems.size())
{
UIPstream str(domain, pBufs);
str >> faces[domain]
>> points[domain]
>> faceIDs[domain];
}
}
}
void Foam::AMIInterpolation::distributeAndMergePatches
(
const distributionMap& map,
const primitivePatch& tgtPatch,
const globalIndex& gi,
faceList& tgtFaces,
pointField& tgtPoints,
labelList& tgtFaceIDs
) const
{
// Exchange per-processor data
List<faceList> allFaces;
List<pointField> allPoints;
List<labelList> allTgtFaceIDs;
distributePatches(map, tgtPatch, gi, allFaces, allPoints, allTgtFaceIDs);
// Renumber and flatten
label nFaces = 0;
label nPoints = 0;
forAll(allFaces, proci)
{
nFaces += allFaces[proci].size();
nPoints += allPoints[proci].size();
}
tgtFaces.setSize(nFaces);
tgtPoints.setSize(nPoints);
tgtFaceIDs.setSize(nFaces);
nFaces = 0;
nPoints = 0;
// My own data first
{
const labelList& faceIDs = allTgtFaceIDs[Pstream::myProcNo()];
SubList<label>(tgtFaceIDs, faceIDs.size()) = faceIDs;
const faceList& fcs = allFaces[Pstream::myProcNo()];
forAll(fcs, i)
{
const face& f = fcs[i];
face& newF = tgtFaces[nFaces++];
newF.setSize(f.size());
forAll(f, fp)
{
newF[fp] = f[fp] + nPoints;
}
}
const pointField& pts = allPoints[Pstream::myProcNo()];
forAll(pts, i)
{
tgtPoints[nPoints++] = pts[i];
}
}
// Other proc data follows
forAll(allFaces, proci)
{
if (proci != Pstream::myProcNo())
{
const labelList& faceIDs = allTgtFaceIDs[proci];
SubList<label>(tgtFaceIDs, faceIDs.size(), nFaces) = faceIDs;
const faceList& fcs = allFaces[proci];
forAll(fcs, i)
{
const face& f = fcs[i];
face& newF = tgtFaces[nFaces++];
newF.setSize(f.size());
forAll(f, fp)
{
newF[fp] = f[fp] + nPoints;
}
}
const pointField& pts = allPoints[proci];
forAll(pts, i)
{
tgtPoints[nPoints++] = pts[i];
}
}
}
// Merge
labelList oldToNew;
pointField newTgtPoints;
bool hasMerged = mergePoints
(
tgtPoints,
small,
false,
oldToNew,
newTgtPoints
);
if (hasMerged)
{
if (debug)
{
Pout<< "Merged from " << tgtPoints.size()
<< " down to " << newTgtPoints.size() << " points" << endl;
}
tgtPoints.transfer(newTgtPoints);
forAll(tgtFaces, i)
{
inplaceRenumber(oldToNew, tgtFaces[i]);
}
}
}
Foam::autoPtr<Foam::distributionMap>
Foam::AMIInterpolation::calcProcMap
(
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch
) const
{
// Get decomposition of patch
List<treeBoundBoxList> procBb(Pstream::nProcs());
if (srcPatch.size())
{
procBb[Pstream::myProcNo()] = treeBoundBoxList
(
1, // For now single bounding box per proc
treeBoundBox
(
srcPatch.points(),
srcPatch.meshPoints()
)
);
}
else
{
procBb[Pstream::myProcNo()] = treeBoundBoxList();
}
// slightly increase size of bounding boxes to allow for cases where
// bounding boxes are perfectly aligned
forAll(procBb[Pstream::myProcNo()], bbI)
{
treeBoundBox& bb = procBb[Pstream::myProcNo()][bbI];
bb.inflate(0.01);
}
Pstream::gatherList(procBb);
Pstream::scatterList(procBb);
if (debug)
{
Info<< "Determining extent of srcPatch per processor:" << nl
<< "\tproc\tbb" << endl;
forAll(procBb, proci)
{
Info<< '\t' << proci << '\t' << procBb[proci] << endl;
}
}
// Determine which faces of tgtPatch overlaps srcPatch per proc
const faceList& faces = tgtPatch.localFaces();
const pointField& points = tgtPatch.localPoints();
labelListList sendMap;
{
// Per processor indices into all segments to send
List<DynamicList<label>> dynSendMap(Pstream::nProcs());
// Work array - whether processor bb overlaps the face bounds
boolList procBbOverlaps(Pstream::nProcs());
forAll(faces, facei)
{
if (faces[facei].size())
{
treeBoundBox faceBb(points, faces[facei]);
// Find the processor this face overlaps
calcOverlappingProcs(procBb, faceBb, procBbOverlaps);
forAll(procBbOverlaps, proci)
{
if (procBbOverlaps[proci])
{
dynSendMap[proci].append(facei);
}
}
}
}
// Convert dynamicList to labelList
sendMap.setSize(Pstream::nProcs());
forAll(sendMap, proci)
{
sendMap[proci].transfer(dynSendMap[proci]);
}
}
// Debug printing
if (debug)
{
Pout<< "Of my " << faces.size() << " I need to send to:" << nl
<< "\tproc\tfaces" << endl;
forAll(sendMap, proci)
{
Pout<< '\t' << proci << '\t' << sendMap[proci].size() << endl;
}
}
// Send over how many faces I need to receive
labelListList sendSizes(Pstream::nProcs());
sendSizes[Pstream::myProcNo()].setSize(Pstream::nProcs());
forAll(sendMap, proci)
{
sendSizes[Pstream::myProcNo()][proci] = sendMap[proci].size();
}
Pstream::gatherList(sendSizes);
Pstream::scatterList(sendSizes);
// Determine order of receiving
labelListList constructMap(Pstream::nProcs());
// My local segment first
constructMap[Pstream::myProcNo()] = identity
(
sendMap[Pstream::myProcNo()].size()
);
label segmentI = constructMap[Pstream::myProcNo()].size();
forAll(constructMap, proci)
{
if (proci != Pstream::myProcNo())
{
// What I need to receive is what other processor is sending to me
label nRecv = sendSizes[proci][Pstream::myProcNo()];
constructMap[proci].setSize(nRecv);
for (label i = 0; i < nRecv; i++)
{
constructMap[proci][i] = segmentI++;
}
}
}
autoPtr<distributionMap> mapPtr
(
new distributionMap
(
segmentI, // size after construction
move(sendMap),
move(constructMap)
)
);
return mapPtr;
}
// ************************************************************************* //

View File

@ -1,336 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 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/>.
\*---------------------------------------------------------------------------*/
#include "AMIInterpolation.H"
#include "AMIMethod.H"
#include "meshTools.H"
#include "distributionMap.H"
#include "flipOp.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type, class CombineOp>
void Foam::AMIInterpolation::interpolateToTarget
(
const UList<Type>& fld,
const CombineOp& cop,
List<Type>& result,
const UList<Type>& defaultValues
) const
{
if (fld.size() != srcAddress_.size())
{
FatalErrorInFunction
<< "Supplied field size is not equal to source patch size" << nl
<< " source patch = " << srcAddress_.size() << nl
<< " target patch = " << tgtAddress_.size() << nl
<< " supplied field = " << fld.size()
<< abort(FatalError);
}
if (lowWeightCorrection_ > 0)
{
if (defaultValues.size() != tgtAddress_.size())
{
FatalErrorInFunction
<< "Employing default values when sum of weights falls below "
<< lowWeightCorrection_
<< " but supplied default field size is not equal to target "
<< "patch size" << nl
<< " default values = " << defaultValues.size() << nl
<< " target patch = " << tgtAddress_.size() << nl
<< abort(FatalError);
}
}
result.setSize(tgtAddress_.size());
if (singlePatchProc_ == -1)
{
const distributionMap& map = srcMapPtr_();
List<Type> work(fld);
map.distribute(work);
forAll(result, facei)
{
if (tgtWeightsSum_[facei] < lowWeightCorrection_)
{
result[facei] = defaultValues[facei];
}
else
{
const labelList& faces = tgtAddress_[facei];
const scalarList& weights = tgtWeights_[facei];
forAll(faces, i)
{
cop(result[facei], facei, work[faces[i]], weights[i]);
}
}
}
}
else
{
forAll(result, facei)
{
if (tgtWeightsSum_[facei] < lowWeightCorrection_)
{
result[facei] = defaultValues[facei];
}
else
{
const labelList& faces = tgtAddress_[facei];
const scalarList& weights = tgtWeights_[facei];
forAll(faces, i)
{
cop(result[facei], facei, fld[faces[i]], weights[i]);
}
}
}
}
}
template<class Type, class CombineOp>
void Foam::AMIInterpolation::interpolateToSource
(
const UList<Type>& fld,
const CombineOp& cop,
List<Type>& result,
const UList<Type>& defaultValues
) const
{
if (fld.size() != tgtAddress_.size())
{
FatalErrorInFunction
<< "Supplied field size is not equal to target patch size" << nl
<< " source patch = " << srcAddress_.size() << nl
<< " target patch = " << tgtAddress_.size() << nl
<< " supplied field = " << fld.size()
<< abort(FatalError);
}
if (lowWeightCorrection_ > 0)
{
if (defaultValues.size() != srcAddress_.size())
{
FatalErrorInFunction
<< "Employing default values when sum of weights falls below "
<< lowWeightCorrection_
<< " but supplied default field size is not equal to target "
<< "patch size" << nl
<< " default values = " << defaultValues.size() << nl
<< " source patch = " << srcAddress_.size() << nl
<< abort(FatalError);
}
}
result.setSize(srcAddress_.size());
if (singlePatchProc_ == -1)
{
const distributionMap& map = tgtMapPtr_();
List<Type> work(fld);
map.distribute(work);
forAll(result, facei)
{
if (srcWeightsSum_[facei] < lowWeightCorrection_)
{
result[facei] = defaultValues[facei];
}
else
{
const labelList& faces = srcAddress_[facei];
const scalarList& weights = srcWeights_[facei];
forAll(faces, i)
{
cop(result[facei], facei, work[faces[i]], weights[i]);
}
}
}
}
else
{
forAll(result, facei)
{
if (srcWeightsSum_[facei] < lowWeightCorrection_)
{
result[facei] = defaultValues[facei];
}
else
{
const labelList& faces = srcAddress_[facei];
const scalarList& weights = srcWeights_[facei];
forAll(faces, i)
{
cop(result[facei], facei, fld[faces[i]], weights[i]);
}
}
}
}
}
template<class Type, class CombineOp>
Foam::tmp<Foam::Field<Type>>
Foam::AMIInterpolation::interpolateToSource
(
const Field<Type>& fld,
const CombineOp& cop,
const UList<Type>& defaultValues
) const
{
tmp<Field<Type>> tresult
(
new Field<Type>
(
srcAddress_.size(),
Zero
)
);
interpolateToSource
(
fld,
multiplyWeightedOp<Type, CombineOp>(cop),
tresult.ref(),
defaultValues
);
return tresult;
}
template<class Type, class CombineOp>
Foam::tmp<Foam::Field<Type>>
Foam::AMIInterpolation::interpolateToSource
(
const tmp<Field<Type>>& tFld,
const CombineOp& cop,
const UList<Type>& defaultValues
) const
{
return interpolateToSource(tFld(), cop, defaultValues);
}
template<class Type, class CombineOp>
Foam::tmp<Foam::Field<Type>>
Foam::AMIInterpolation::interpolateToTarget
(
const Field<Type>& fld,
const CombineOp& cop,
const UList<Type>& defaultValues
) const
{
tmp<Field<Type>> tresult
(
new Field<Type>
(
tgtAddress_.size(),
Zero
)
);
interpolateToTarget
(
fld,
multiplyWeightedOp<Type, CombineOp>(cop),
tresult.ref(),
defaultValues
);
return tresult;
}
template<class Type, class CombineOp>
Foam::tmp<Foam::Field<Type>>
Foam::AMIInterpolation::interpolateToTarget
(
const tmp<Field<Type>>& tFld,
const CombineOp& cop,
const UList<Type>& defaultValues
) const
{
return interpolateToTarget(tFld(), cop, defaultValues);
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::AMIInterpolation::interpolateToSource
(
const Field<Type>& fld,
const UList<Type>& defaultValues
) const
{
return interpolateToSource(fld, plusEqOp<Type>(), defaultValues);
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::AMIInterpolation::interpolateToSource
(
const tmp<Field<Type>>& tFld,
const UList<Type>& defaultValues
) const
{
return interpolateToSource(tFld(), plusEqOp<Type>(), defaultValues);
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::AMIInterpolation::interpolateToTarget
(
const Field<Type>& fld,
const UList<Type>& defaultValues
) const
{
return interpolateToTarget(fld, plusEqOp<Type>(), defaultValues);
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::AMIInterpolation::interpolateToTarget
(
const tmp<Field<Type>>& tFld,
const UList<Type>& defaultValues
) const
{
return interpolateToTarget(tFld(), plusEqOp<Type>(), defaultValues);
}
// ************************************************************************* //

View File

@ -1,360 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2022 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/>.
\*---------------------------------------------------------------------------*/
#include "AMIMethod.H"
#include "meshTools.H"
#include "distributionMap.H"
#include "unitConversion.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(AMIMethod, 0);
defineRunTimeSelectionTable(AMIMethod, components);
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::AMIMethod::checkPatches() const
{
if (debug && (!srcPatch_.size() || !tgtPatch_.size()))
{
Pout<< "AMI: Patches not on processor: Source faces = "
<< srcPatch_.size() << ", target faces = " << tgtPatch_.size()
<< endl;
}
if (conformal())
{
const scalar maxBoundsError = 0.05;
// check bounds of source and target
boundBox bbSrc(srcPatch_.points(), srcPatch_.meshPoints(), true);
boundBox bbTgt(tgtPatch_.points(), tgtPatch_.meshPoints(), true);
boundBox bbTgtInf(bbTgt);
bbTgtInf.inflate(maxBoundsError);
if (!bbTgtInf.contains(bbSrc))
{
WarningInFunction
<< "Source and target patch bounding boxes are not similar"
<< nl
<< " source box span : " << bbSrc.span() << nl
<< " target box span : " << bbTgt.span() << nl
<< " source box : " << bbSrc << nl
<< " target box : " << bbTgt << nl
<< " inflated target box : " << bbTgtInf << endl;
}
}
}
bool Foam::AMIMethod::initialise
(
labelListList& srcAddress,
scalarListList& srcWeights,
labelListList& tgtAddress,
scalarListList& tgtWeights,
label& srcFacei,
label& tgtFacei
)
{
checkPatches();
// set initial sizes for weights and addressing - must be done even if
// returns false below
srcAddress.setSize(srcPatch_.size());
srcWeights.setSize(srcPatch_.size());
tgtAddress.setSize(tgtPatch_.size());
tgtWeights.setSize(tgtPatch_.size());
// check that patch sizes are valid
if (!srcPatch_.size())
{
return false;
}
else if (!tgtPatch_.size())
{
WarningInFunction
<< srcPatch_.size() << " source faces but no target faces" << endl;
return false;
}
// reset the octree
resetTree();
// find initial face match using brute force/octree search
if ((srcFacei == -1) || (tgtFacei == -1))
{
srcFacei = 0;
tgtFacei = 0;
bool foundFace = false;
forAll(srcPatch_, facei)
{
tgtFacei = findTargetFace(facei);
if (tgtFacei >= 0)
{
srcFacei = facei;
foundFace = true;
break;
}
}
if (!foundFace)
{
if (requireMatch_)
{
FatalErrorInFunction
<< "Unable to find initial target face"
<< abort(FatalError);
}
return false;
}
}
if (debug)
{
Pout<< "AMI: initial target face = " << tgtFacei << endl;
}
return true;
}
void Foam::AMIMethod::writeIntersectionOBJ
(
const scalar area,
const face& f1,
const face& f2,
const pointField& f1Points,
const pointField& f2Points
) const
{
static label count = 1;
const pointField f1pts = f1.points(f1Points);
const pointField f2pts = f2.points(f2Points);
Pout<< "Face intersection area (" << count << "):" << nl
<< " f1 face = " << f1 << nl
<< " f1 pts = " << f1pts << nl
<< " f2 face = " << f2 << nl
<< " f2 pts = " << f2pts << nl
<< " area = " << area
<< endl;
OFstream os("areas" + name(count) + ".obj");
forAll(f1pts, i)
{
meshTools::writeOBJ(os, f1pts[i]);
}
os<< "l";
forAll(f1pts, i)
{
os<< " " << i + 1;
}
os<< " 1" << endl;
forAll(f2pts, i)
{
meshTools::writeOBJ(os, f2pts[i]);
}
os<< "l";
forAll(f2pts, i)
{
os<< " " << f1pts.size() + i + 1;
}
os<< " " << f1pts.size() + 1 << endl;
count++;
}
void Foam::AMIMethod::resetTree()
{
// Clear the old octree
treePtr_.clear();
treeBoundBox bb(tgtPatch_.points(), tgtPatch_.meshPoints());
bb.inflate(0.01);
if (!treePtr_.valid())
{
treePtr_.reset
(
new indexedOctree<treeType>
(
treeType
(
false,
tgtPatch_,
indexedOctree<treeType>::perturbTol()
),
bb, // overall search domain
8, // maxLevel
10, // leaf size
3.0 // duplicity
)
);
}
}
Foam::label Foam::AMIMethod::findTargetFace
(
const label srcFacei
) const
{
label targetFacei = -1;
const pointField& srcPts = srcPatch_.points();
const face& srcFace = srcPatch_[srcFacei];
const point srcPt = srcFace.centre(srcPts);
const scalar srcFaceArea = srcMagSf_[srcFacei];
pointIndexHit sample = treePtr_->findNearest(srcPt, 10.0*srcFaceArea);
if (sample.hit())
{
targetFacei = sample.index();
if (debug)
{
Pout<< "Source point = " << srcPt << ", Sample point = "
<< sample.hitPoint() << ", Sample index = " << sample.index()
<< endl;
}
}
return targetFacei;
}
void Foam::AMIMethod::appendNbrFaces
(
const label facei,
const primitivePatch& patch,
const DynamicList<label>& visitedFaces,
DynamicList<label>& faceIDs
) const
{
const labelList& nbrFaces = patch.faceFaces()[facei];
// filter out faces already visited from face neighbours
forAll(nbrFaces, i)
{
label nbrFacei = nbrFaces[i];
bool valid = true;
forAll(visitedFaces, j)
{
if (nbrFacei == visitedFaces[j])
{
valid = false;
break;
}
}
if (valid)
{
forAll(faceIDs, j)
{
if (nbrFacei == faceIDs[j])
{
valid = false;
break;
}
}
}
// prevent addition of face if it is not on the same plane-ish
if (valid)
{
const vector& n1 = patch.faceNormals()[facei];
const vector& n2 = patch.faceNormals()[nbrFacei];
scalar cosI = n1 & n2;
if (cosI > cos(maxWalkAngle()))
{
faceIDs.append(nbrFacei);
}
}
}
}
Foam::scalar Foam::AMIMethod::maxWalkAngle() const
{
return degToRad(89);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::AMIMethod::AMIMethod
(
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch,
const scalarField& srcMagSf,
const scalarField& tgtMagSf,
const faceAreaIntersect::triangulationMode& triMode,
const bool reverseTarget,
const bool requireMatch
)
:
srcPatch_(srcPatch),
tgtPatch_(tgtPatch),
reverseTarget_(reverseTarget),
requireMatch_(requireMatch),
srcMagSf_(srcMagSf),
tgtMagSf_(tgtMagSf),
srcNonOverlap_(),
triMode_(triMode)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::AMIMethod::~AMIMethod()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::AMIMethod::conformal() const
{
return true;
}
// ************************************************************************* //

View File

@ -1,261 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2019 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/>.
Class
Foam::AMIMethod
Description
Base class for Arbitrary Mesh Interface (AMI) methods
SourceFiles
AMIMethod.C
\*---------------------------------------------------------------------------*/
#ifndef AMIMethod_H
#define AMIMethod_H
#include "className.H"
#include "DynamicList.H"
#include "faceAreaIntersect.H"
#include "indexedOctree.H"
#include "treeDataPrimitivePatch.H"
#include "treeBoundBoxList.H"
#include "primitivePatch.H"
#include "runTimeSelectionTables.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class AMIMethod Declaration
\*---------------------------------------------------------------------------*/
class AMIMethod
{
protected:
//- Local typedef to octree tree-type
typedef treeDataPrimitivePatch<primitivePatch> treeType;
// Protected data
//- Reference to source patch
const primitivePatch& srcPatch_;
//- Reference to target patch
const primitivePatch& tgtPatch_;
//- Flag to indicate that the two patches are co-directional and
// that the orientation of the target patch should be reversed
const bool reverseTarget_;
//- Flag to indicate that the two patches must be matched/an overlap
// exists between them
const bool requireMatch_;
//- Source face areas
const scalarField& srcMagSf_;
//- Target face areas
const scalarField& tgtMagSf_;
//- Labels of faces that are not overlapped by any target faces
// (should be empty for correct functioning)
labelList srcNonOverlap_;
//- Octree used to find face seeds
autoPtr<indexedOctree<treeType>> treePtr_;
//- Face triangulation mode
const faceAreaIntersect::triangulationMode triMode_;
// Protected Member Functions
// Helper functions
//- Check AMI patch coupling
void checkPatches() const;
//- Initialise and return true if all ok
bool initialise
(
labelListList& srcAddress,
scalarListList& srcWeights,
labelListList& tgtAddress,
scalarListList& tgtWeights,
label& srcFacei,
label& tgtFacei
);
//- Write triangle intersection to OBJ file
void writeIntersectionOBJ
(
const scalar area,
const face& f1,
const face& f2,
const pointField& f1Points,
const pointField& f2Points
) const;
// Common AMI method functions
//- Reset the octree for the target patch face search
void resetTree();
//- Find face on target patch that overlaps source face
label findTargetFace(const label srcFacei) const;
//- Add faces neighbouring facei to the ID list
void appendNbrFaces
(
const label facei,
const primitivePatch& patch,
const DynamicList<label>& visitedFaces,
DynamicList<label>& faceIDs
) const;
//- The maximum edge angle that the walk will cross
virtual scalar maxWalkAngle() const;
public:
//- Runtime type information
TypeName("AMIMethod");
//- Declare runtime constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
AMIMethod,
components,
(
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch,
const scalarField& srcMagSf,
const scalarField& tgtMagSf,
const faceAreaIntersect::triangulationMode& triMode,
const bool reverseTarget,
const bool requireMatch
),
(
srcPatch,
tgtPatch,
srcMagSf,
tgtMagSf,
triMode,
reverseTarget,
requireMatch
)
);
// Constructors
//- Construct from components
AMIMethod
(
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch,
const scalarField& srcMagSf,
const scalarField& tgtMagSf,
const faceAreaIntersect::triangulationMode& triMode,
const bool reverseTarget,
const bool requireMatch
);
//- Disallow default bitwise copy construction
AMIMethod(const AMIMethod&) = delete;
//- Selector
static autoPtr<AMIMethod> New
(
const word& methodName,
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch,
const scalarField& srcMagSf,
const scalarField& tgtMagSf,
const faceAreaIntersect::triangulationMode& triMode,
const bool reverseTarget,
const bool requireMatch
);
//- Destructor
virtual ~AMIMethod();
// Member Functions
// Access
//- Labels of faces that are not overlapped by any target faces
// Note: this should be empty for correct functioning
inline const labelList& srcNonOverlap() const;
//- Flag to indicate that interpolation patches are conformal
virtual bool conformal() const;
// Manipulation
//- Update addressing and weights
virtual void calculate
(
labelListList& srcAddress,
scalarListList& srcWeights,
labelListList& tgtAddress,
scalarListList& tgtWeights,
label srcFacei = -1,
label tgtFacei = -1
) = 0;
// Member Operators
//- Disallow default bitwise assignment
void operator=(const AMIMethod&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "AMIMethodI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,32 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2018 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/>.
\*---------------------------------------------------------------------------*/
inline const Foam::labelList& Foam::AMIMethod::srcNonOverlap() const
{
return srcNonOverlap_;
}
// ************************************************************************* //

View File

@ -1,75 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2018 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/>.
\*---------------------------------------------------------------------------*/
#include "AMIMethod.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::autoPtr<Foam::AMIMethod> Foam::AMIMethod::New
(
const word& methodName,
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch,
const scalarField& srcMagSf,
const scalarField& tgtMagSf,
const faceAreaIntersect::triangulationMode& triMode,
const bool reverseTarget,
const bool requireMatch
)
{
if (debug)
{
Info<< "Selecting AMIMethod " << methodName << endl;
}
typename componentsConstructorTable::iterator cstrIter =
componentsConstructorTablePtr_->find(methodName);
if (cstrIter == componentsConstructorTablePtr_->end())
{
FatalErrorInFunction
<< "Unknown AMIMethod type "
<< methodName << nl << nl
<< "Valid AMIMethod types are:" << nl
<< componentsConstructorTablePtr_->sortedToc() << exit(FatalError);
}
return autoPtr<AMIMethod>
(
cstrIter()
(
srcPatch,
tgtPatch,
srcMagSf,
tgtMagSf,
triMode,
reverseTarget,
requireMatch
)
);
}
// ************************************************************************* //

View File

@ -1,328 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2018 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/>.
\*---------------------------------------------------------------------------*/
#include "directAMI.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(directAMI, 0);
addToRunTimeSelectionTable(AMIMethod, directAMI, components);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::directAMI::appendToDirectSeeds
(
labelList& mapFlag,
labelList& srcTgtSeed,
DynamicList<label>& srcSeeds,
DynamicList<label>& nonOverlapFaces,
label& srcFacei,
label& tgtFacei
) const
{
const labelList& srcNbr = this->srcPatch_.faceFaces()[srcFacei];
const labelList& tgtNbr = this->tgtPatch_.faceFaces()[tgtFacei];
const pointField& srcPoints = this->srcPatch_.points();
const pointField& tgtPoints = this->tgtPatch_.points();
const vectorField& srcCf = this->srcPatch_.faceCentres();
forAll(srcNbr, i)
{
label srcI = srcNbr[i];
if ((mapFlag[srcI] == 0) && (srcTgtSeed[srcI] == -1))
{
// first attempt: match by comparing face centres
const face& srcF = this->srcPatch_[srcI];
const point& srcC = srcCf[srcI];
scalar tol = great;
forAll(srcF, fpI)
{
const point& p = srcPoints[srcF[fpI]];
scalar d2 = magSqr(p - srcC);
if (d2 < tol)
{
tol = d2;
}
}
tol = max(small, 0.0001*sqrt(tol));
bool found = false;
forAll(tgtNbr, j)
{
label tgtI = tgtNbr[j];
const face& tgtF = this->tgtPatch_[tgtI];
const point tgtC = tgtF.centre(tgtPoints);
if (mag(srcC - tgtC) < tol)
{
// new match - append to lists
found = true;
srcTgtSeed[srcI] = tgtI;
srcSeeds.append(srcI);
break;
}
}
// second attempt: match by shooting a ray into the tgt face
if (!found)
{
const vector srcN = srcF.area(srcPoints);
forAll(tgtNbr, j)
{
label tgtI = tgtNbr[j];
const face& tgtF = this->tgtPatch_[tgtI];
pointHit ray = tgtF.ray(srcCf[srcI], srcN, tgtPoints);
if (ray.hit())
{
// new match - append to lists
found = true;
srcTgtSeed[srcI] = tgtI;
srcSeeds.append(srcI);
break;
}
}
}
// no match available for source face srcI
if (!found)
{
mapFlag[srcI] = -1;
nonOverlapFaces.append(srcI);
if (debug)
{
Pout<< "source face not found: id=" << srcI
<< " centre=" << srcCf[srcI]
<< " area=" << srcF.area(srcPoints)
<< " points=" << srcF.points(srcPoints)
<< endl;
Pout<< "target neighbours:" << nl;
forAll(tgtNbr, j)
{
label tgtI = tgtNbr[j];
const face& tgtF = this->tgtPatch_[tgtI];
Pout<< "face id: " << tgtI
<< " centre=" << tgtF.centre(tgtPoints)
<< " area=" << tgtF.area(tgtPoints)
<< " points=" << tgtF.points(tgtPoints)
<< endl;
}
}
}
}
}
if (srcSeeds.size())
{
srcFacei = srcSeeds.remove();
tgtFacei = srcTgtSeed[srcFacei];
}
else
{
srcFacei = -1;
tgtFacei = -1;
}
}
void Foam::directAMI::restartAdvancingFront
(
labelList& mapFlag,
DynamicList<label>& nonOverlapFaces,
label& srcFacei,
label& tgtFacei
) const
{
forAll(mapFlag, facei)
{
if (mapFlag[facei] == 0)
{
tgtFacei = this->findTargetFace(facei);
if (tgtFacei < 0)
{
mapFlag[facei] = -1;
nonOverlapFaces.append(facei);
}
else
{
srcFacei = facei;
break;
}
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::directAMI::directAMI
(
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch,
const scalarField& srcMagSf,
const scalarField& tgtMagSf,
const faceAreaIntersect::triangulationMode& triMode,
const bool reverseTarget,
const bool requireMatch
)
:
AMIMethod
(
srcPatch,
tgtPatch,
srcMagSf,
tgtMagSf,
triMode,
reverseTarget,
requireMatch
)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::directAMI::~directAMI()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::directAMI::calculate
(
labelListList& srcAddress,
scalarListList& srcWeights,
labelListList& tgtAddress,
scalarListList& tgtWeights,
label srcFacei,
label tgtFacei
)
{
bool ok =
this->initialise
(
srcAddress,
srcWeights,
tgtAddress,
tgtWeights,
srcFacei,
tgtFacei
);
if (!ok)
{
return;
}
// temporary storage for addressing and weights
List<DynamicList<label>> srcAddr(this->srcPatch_.size());
List<DynamicList<label>> tgtAddr(this->tgtPatch_.size());
// construct weights and addressing
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// list of faces currently visited for srcFacei to avoid multiple hits
DynamicList<label> srcSeeds(10);
// list to keep track of tgt faces used to seed src faces
labelList srcTgtSeed(srcAddr.size(), -1);
srcTgtSeed[srcFacei] = tgtFacei;
// list to keep track of whether src face can be mapped
// 1 = mapped, 0 = untested, -1 = cannot map
labelList mapFlag(srcAddr.size(), 0);
label nTested = 0;
DynamicList<label> nonOverlapFaces;
do
{
srcAddr[srcFacei].append(tgtFacei);
tgtAddr[tgtFacei].append(srcFacei);
mapFlag[srcFacei] = 1;
nTested++;
// Do advancing front starting from srcFacei, tgtFacei
appendToDirectSeeds
(
mapFlag,
srcTgtSeed,
srcSeeds,
nonOverlapFaces,
srcFacei,
tgtFacei
);
if (srcFacei < 0 && nTested < this->srcPatch_.size())
{
restartAdvancingFront(mapFlag, nonOverlapFaces, srcFacei, tgtFacei);
}
} while (srcFacei >= 0);
if (nonOverlapFaces.size() != 0)
{
Pout<< " AMI: " << nonOverlapFaces.size()
<< " non-overlap faces identified"
<< endl;
this->srcNonOverlap_.transfer(nonOverlapFaces);
}
// transfer data to persistent storage
forAll(srcAddr, i)
{
srcAddress[i].transfer(srcAddr[i]);
srcWeights[i] = scalarList(1, 1.0);
}
forAll(tgtAddr, i)
{
tgtAddress[i].transfer(tgtAddr[i]);
tgtWeights[i] = scalarList(1, 1.0);
}
}
// ************************************************************************* //

View File

@ -1,148 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2019 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/>.
Class
Foam::directAMI
Description
Direct mapped Arbitrary Mesh Interface (AMI) method
SourceFiles
directAMI.C
\*---------------------------------------------------------------------------*/
#ifndef directAMI_H
#define directAMI_H
#include "AMIMethod.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class directAMI Declaration
\*---------------------------------------------------------------------------*/
class directAMI
:
public AMIMethod
{
// Private Member Functions
// Marching front
//- Append to list of src face seed indices
void appendToDirectSeeds
(
labelList& mapFlag,
labelList& srcTgtSeed,
DynamicList<label>& srcSeeds,
DynamicList<label>& nonOverlapFaces,
label& srcFacei,
label& tgtFacei
) const;
//- Restart the advancing front - typically happens for
// disconnected regions
void restartAdvancingFront
(
labelList& mapFlag,
DynamicList<label>& nonOverlapFaces,
label& srcFacei,
label& tgtFacei
) const;
// Evaluation
//- Area of intersection between source and target faces
scalar interArea
(
const label srcFacei,
const label tgtFacei
) const;
public:
//- Runtime type information
TypeName("directAMI");
// Constructors
//- Construct from components
directAMI
(
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch,
const scalarField& srcMagSf,
const scalarField& tgtMagSf,
const faceAreaIntersect::triangulationMode& triMode,
const bool reverseTarget = false,
const bool requireMatch = true
);
//- Disallow default bitwise copy construction
directAMI(const directAMI&) = delete;
//- Destructor
virtual ~directAMI();
// Member Functions
// Manipulation
//- Update addressing and weights
virtual void calculate
(
labelListList& srcAddress,
scalarListList& srcWeights,
labelListList& tgtAddress,
scalarListList& tgtWeights,
label srcFacei = -1,
label tgtFacei = -1
);
// Member Operators
//- Disallow default bitwise assignment
void operator=(const directAMI&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,583 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2018 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/>.
\*---------------------------------------------------------------------------*/
#include "faceAreaWeightAMI.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(faceAreaWeightAMI, 0);
addToRunTimeSelectionTable(AMIMethod, faceAreaWeightAMI, components);
}
// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
void Foam::faceAreaWeightAMI::calcAddressing
(
List<DynamicList<label>>& srcAddr,
List<DynamicList<scalar>>& srcWght,
List<DynamicList<label>>& tgtAddr,
List<DynamicList<scalar>>& tgtWght,
label srcFacei,
label tgtFacei
)
{
// construct weights and addressing
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
label nFacesRemaining = srcAddr.size();
// list of tgt face neighbour faces
DynamicList<label> nbrFaces(10);
// list of faces currently visited for srcFacei to avoid multiple hits
DynamicList<label> visitedFaces(10);
// list to keep track of tgt faces used to seed src faces
labelList seedFaces(nFacesRemaining, -1);
seedFaces[srcFacei] = tgtFacei;
// list to keep track of whether src face can be mapped
boolList mapFlag(nFacesRemaining, true);
// reset starting seed
label startSeedI = 0;
DynamicList<label> nonOverlapFaces;
do
{
// Do advancing front starting from srcFacei,tgtFacei
bool faceProcessed = processSourceFace
(
srcFacei,
tgtFacei,
nbrFaces,
visitedFaces,
srcAddr,
srcWght,
tgtAddr,
tgtWght
);
mapFlag[srcFacei] = false;
nFacesRemaining--;
if (!faceProcessed)
{
nonOverlapFaces.append(srcFacei);
}
// choose new src face from current src face neighbour
if (nFacesRemaining > 0)
{
setNextFaces
(
startSeedI,
srcFacei,
tgtFacei,
mapFlag,
seedFaces,
visitedFaces
);
}
} while (nFacesRemaining > 0);
this->srcNonOverlap_.transfer(nonOverlapFaces);
}
bool Foam::faceAreaWeightAMI::processSourceFace
(
const label srcFacei,
const label tgtStartFacei,
// list of tgt face neighbour faces
DynamicList<label>& nbrFaces,
// list of faces currently visited for srcFacei to avoid multiple hits
DynamicList<label>& visitedFaces,
// temporary storage for addressing and weights
List<DynamicList<label>>& srcAddr,
List<DynamicList<scalar>>& srcWght,
List<DynamicList<label>>& tgtAddr,
List<DynamicList<scalar>>& tgtWght
)
{
if (tgtStartFacei == -1)
{
return false;
}
nbrFaces.clear();
visitedFaces.clear();
// append initial target face and neighbours
nbrFaces.append(tgtStartFacei);
this->appendNbrFaces
(
tgtStartFacei,
this->tgtPatch_,
visitedFaces,
nbrFaces
);
const scalar srcArea = this->srcMagSf_[srcFacei];
bool faceProcessed = false;
do
{
// process new target face
const label tgtFacei = nbrFaces.remove();
visitedFaces.append(tgtFacei);
const scalar tgtArea = this->tgtMagSf_[tgtFacei];
// calculate the intersection area
const scalar area = interArea(srcFacei, tgtFacei);
// store when intersection fractional area > min weight
if (area/srcArea > minWeight())
{
srcAddr[srcFacei].append(tgtFacei);
srcWght[srcFacei].append(area/srcArea);
tgtAddr[tgtFacei].append(srcFacei);
tgtWght[tgtFacei].append(area/tgtArea);
this->appendNbrFaces
(
tgtFacei,
this->tgtPatch_,
visitedFaces,
nbrFaces
);
faceProcessed = true;
}
} while (nbrFaces.size() > 0);
return faceProcessed;
}
void Foam::faceAreaWeightAMI::setNextFaces
(
label& startSeedI,
label& srcFacei,
label& tgtFacei,
const boolList& mapFlag,
labelList& seedFaces,
const DynamicList<label>& visitedFaces,
bool errorOnNotFound
) const
{
const labelList& srcNbrFaces = this->srcPatch_.faceFaces()[srcFacei];
// initialise tgtFacei
tgtFacei = -1;
// set possible seeds for later use
bool valuesSet = false;
forAll(srcNbrFaces, i)
{
label faceS = srcNbrFaces[i];
if (mapFlag[faceS] && seedFaces[faceS] == -1)
{
forAll(visitedFaces, j)
{
label faceT = visitedFaces[j];
scalar area = interArea(faceS, faceT);
scalar areaTotal = this->srcMagSf_[srcFacei];
// Check that faces have enough overlap for robust walking
if (area/areaTotal > minWeight())
{
// TODO - throwing area away - re-use in next iteration?
seedFaces[faceS] = faceT;
if (!valuesSet)
{
srcFacei = faceS;
tgtFacei = faceT;
valuesSet = true;
}
}
}
}
}
// set next src and tgt faces if not set above
if (valuesSet)
{
return;
}
else
{
// try to use existing seed
bool foundNextSeed = false;
for (label facei = startSeedI; facei < mapFlag.size(); facei++)
{
if (mapFlag[facei])
{
if (!foundNextSeed)
{
startSeedI = facei;
foundNextSeed = true;
}
if (seedFaces[facei] != -1)
{
srcFacei = facei;
tgtFacei = seedFaces[facei];
return;
}
}
}
// perform new search to find match
if (debug)
{
Pout<< "Advancing front stalled: searching for new "
<< "target face" << endl;
}
foundNextSeed = false;
for (label facei = startSeedI; facei < mapFlag.size(); facei++)
{
if (mapFlag[facei])
{
if (!foundNextSeed)
{
startSeedI = facei + 1;
foundNextSeed = true;
}
srcFacei = facei;
tgtFacei = this->findTargetFace(srcFacei);
if (tgtFacei >= 0)
{
return;
}
}
}
if (errorOnNotFound)
{
FatalErrorInFunction
<< "Unable to set source and target faces" << abort(FatalError);
}
}
}
Foam::scalar Foam::faceAreaWeightAMI::interArea
(
const label srcFacei,
const label tgtFacei
) const
{
scalar area = 0;
const pointField& srcPoints = this->srcPatch_.points();
const pointField& tgtPoints = this->tgtPatch_.points();
// references to candidate faces
const face& src = this->srcPatch_[srcFacei];
const face& tgt = this->tgtPatch_[tgtFacei];
// quick reject if either face has zero area
// Note: do not use stored face areas for target patch
const scalar tgtMag = tgt.mag(tgtPoints);
if ((this->srcMagSf_[srcFacei] < rootVSmall) || (tgtMag < rootVSmall))
{
return area;
}
// create intersection object
faceAreaIntersect inter(srcPoints, tgtPoints, this->reverseTarget_);
// crude resultant norm
vector n(-this->srcPatch_.faceNormals()[srcFacei]);
if (this->reverseTarget_)
{
n -= this->tgtPatch_.faceNormals()[tgtFacei];
}
else
{
n += this->tgtPatch_.faceNormals()[tgtFacei];
}
scalar magN = mag(n);
if (magN > rootVSmall)
{
area = inter.calc(src, tgt, n/magN, this->triMode_);
}
else
{
WarningInFunction
<< "Invalid normal for source face " << srcFacei
<< " points " << UIndirectList<point>(srcPoints, src)
<< " target face " << tgtFacei
<< " points " << UIndirectList<point>(tgtPoints, tgt)
<< endl;
}
if ((debug > 1) && (area > 0))
{
this->writeIntersectionOBJ(area, src, tgt, srcPoints, tgtPoints);
}
return area;
}
void Foam::faceAreaWeightAMI::restartUncoveredSourceFace
(
List<DynamicList<label>>& srcAddr,
List<DynamicList<scalar>>& srcWght,
List<DynamicList<label>>& tgtAddr,
List<DynamicList<scalar>>& tgtWght
)
{
// Collect all src faces with a low weight
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
labelHashSet lowWeightFaces(100);
forAll(srcWght, srcFacei)
{
const scalar s = sum(srcWght[srcFacei]);
if (s < 0.5)
{
lowWeightFaces.insert(srcFacei);
}
}
if (debug)
{
Pout<< "faceAreaWeightAMI: restarting search on "
<< lowWeightFaces.size() << " faces since sum of weights < 0.5"
<< endl;
}
if (lowWeightFaces.size() > 0)
{
// Erase all the lowWeight source faces from the target
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DynamicList<label> okSrcFaces(10);
DynamicList<scalar> okSrcWeights(10);
forAll(tgtAddr, tgtFacei)
{
okSrcFaces.clear();
okSrcWeights.clear();
DynamicList<label>& srcFaces = tgtAddr[tgtFacei];
DynamicList<scalar>& srcWeights = tgtWght[tgtFacei];
forAll(srcFaces, i)
{
if (!lowWeightFaces.found(srcFaces[i]))
{
okSrcFaces.append(srcFaces[i]);
okSrcWeights.append(srcWeights[i]);
}
}
if (okSrcFaces.size() < srcFaces.size())
{
srcFaces.transfer(okSrcFaces);
srcWeights.transfer(okSrcWeights);
}
}
// Restart search from best hit
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// list of tgt face neighbour faces
DynamicList<label> nbrFaces(10);
// list of faces currently visited for srcFacei to avoid multiple hits
DynamicList<label> visitedFaces(10);
forAllConstIter(labelHashSet, lowWeightFaces, iter)
{
label srcFacei = iter.key();
label tgtFacei = this->findTargetFace(srcFacei);
if (tgtFacei != -1)
{
// bool faceProcessed =
processSourceFace
(
srcFacei,
tgtFacei,
nbrFaces,
visitedFaces,
srcAddr,
srcWght,
tgtAddr,
tgtWght
);
// ? Check faceProcessed to see if restarting has worked.
}
}
}
}
Foam::scalar
Foam::faceAreaWeightAMI::minWeight() const
{
return faceAreaIntersect::tolerance();
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::faceAreaWeightAMI::faceAreaWeightAMI
(
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch,
const scalarField& srcMagSf,
const scalarField& tgtMagSf,
const faceAreaIntersect::triangulationMode& triMode,
const bool reverseTarget,
const bool requireMatch,
const bool restartUncoveredSourceFace
)
:
AMIMethod
(
srcPatch,
tgtPatch,
srcMagSf,
tgtMagSf,
triMode,
reverseTarget,
requireMatch
),
restartUncoveredSourceFace_(restartUncoveredSourceFace)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::faceAreaWeightAMI::~faceAreaWeightAMI()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::faceAreaWeightAMI::calculate
(
labelListList& srcAddress,
scalarListList& srcWeights,
labelListList& tgtAddress,
scalarListList& tgtWeights,
label srcFacei,
label tgtFacei
)
{
bool ok =
this->initialise
(
srcAddress,
srcWeights,
tgtAddress,
tgtWeights,
srcFacei,
tgtFacei
);
if (!ok)
{
return;
}
// temporary storage for addressing and weights
List<DynamicList<label>> srcAddr(this->srcPatch_.size());
List<DynamicList<scalar>> srcWght(srcAddr.size());
List<DynamicList<label>> tgtAddr(this->tgtPatch_.size());
List<DynamicList<scalar>> tgtWght(tgtAddr.size());
calcAddressing
(
srcAddr,
srcWght,
tgtAddr,
tgtWght,
srcFacei,
tgtFacei
);
if (debug && !this->srcNonOverlap_.empty())
{
Pout<< " AMI: " << this->srcNonOverlap_.size()
<< " non-overlap faces identified"
<< endl;
}
// Check for badly covered faces
if (restartUncoveredSourceFace_)
{
restartUncoveredSourceFace
(
srcAddr,
srcWght,
tgtAddr,
tgtWght
);
}
// transfer data to persistent storage
forAll(srcAddr, i)
{
srcAddress[i].transfer(srcAddr[i]);
srcWeights[i].transfer(srcWght[i]);
}
forAll(tgtAddr, i)
{
tgtAddress[i].transfer(tgtAddr[i]);
tgtWeights[i].transfer(tgtWght[i]);
}
}
// ************************************************************************* //

View File

@ -1,184 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2019 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/>.
Class
Foam::faceAreaWeightAMI
Description
Face area weighted Arbitrary Mesh Interface (AMI) method
SourceFiles
faceAreaWeightAMI.C
\*---------------------------------------------------------------------------*/
#ifndef faceAreaWeightAMI_H
#define faceAreaWeightAMI_H
#include "AMIMethod.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class faceAreaWeightAMI Declaration
\*---------------------------------------------------------------------------*/
class faceAreaWeightAMI
:
public AMIMethod
{
// Private Data
//- Flag to restart uncovered source faces
const bool restartUncoveredSourceFace_;
protected:
// Protected Member Functions
// Marching front
//- Calculate addressing and weights using temporary storage
virtual void calcAddressing
(
List<DynamicList<label>>& srcAddress,
List<DynamicList<scalar>>& srcWeights,
List<DynamicList<label>>& tgtAddress,
List<DynamicList<scalar>>& tgtWeights,
label srcFacei,
label tgtFacei
);
//- Determine overlap contributions for source face srcFacei
virtual bool processSourceFace
(
const label srcFacei,
const label tgtStartFacei,
DynamicList<label>& nbrFaces,
DynamicList<label>& visitedFaces,
List<DynamicList<label>>& srcAddr,
List<DynamicList<scalar>>& srcWght,
List<DynamicList<label>>& tgtAddr,
List<DynamicList<scalar>>& tgtWght
);
//- Attempt to re-evaluate source faces that have not been included
virtual void restartUncoveredSourceFace
(
List<DynamicList<label>>& srcAddr,
List<DynamicList<scalar>>& srcWght,
List<DynamicList<label>>& tgtAddr,
List<DynamicList<scalar>>& tgtWght
);
//- Set the source and target seed faces
virtual void setNextFaces
(
label& startSeedI,
label& srcFacei,
label& tgtFacei,
const boolList& mapFlag,
labelList& seedFaces,
const DynamicList<label>& visitedFaces,
bool errorOnNotFound = true
) const;
// Evaluation
//- The minimum weight below which connections are discarded
virtual scalar minWeight() const;
//- Area of intersection between source and target faces
virtual scalar interArea
(
const label srcFacei,
const label tgtFacei
) const;
public:
//- Runtime type information
TypeName("faceAreaWeightAMI");
// Constructors
//- Construct from components
faceAreaWeightAMI
(
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch,
const scalarField& srcMagSf,
const scalarField& tgtMagSf,
const faceAreaIntersect::triangulationMode& triMode,
const bool reverseTarget = false,
const bool requireMatch = true,
const bool restartUncoveredSourceFace = true
);
//- Disallow default bitwise copy construction
faceAreaWeightAMI(const faceAreaWeightAMI&) = delete;
//- Destructor
virtual ~faceAreaWeightAMI();
// Member Functions
// Manipulation
//- Update addressing and weights
virtual void calculate
(
labelListList& srcAddress,
scalarListList& srcWeights,
labelListList& tgtAddress,
scalarListList& tgtWeights,
label srcFacei = -1,
label tgtFacei = -1
);
// Member Operators
//- Disallow default bitwise assignment
void operator=(const faceAreaWeightAMI&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,342 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2018 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/>.
\*---------------------------------------------------------------------------*/
#include "mapNearestAMI.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(mapNearestAMI, 0);
addToRunTimeSelectionTable(AMIMethod, mapNearestAMI, components);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::mapNearestAMI::findNearestFace
(
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch,
const label& srcFacei,
label& tgtFacei
) const
{
const vectorField& srcCf = srcPatch.faceCentres();
const vectorField& tgtCf = tgtPatch.faceCentres();
const vector srcP = srcCf[srcFacei];
DynamicList<label> tgtFaces(10);
tgtFaces.append(tgtFacei);
DynamicList<label> visitedFaces(10);
scalar d = great;
do
{
label tgtI = tgtFaces.remove();
visitedFaces.append(tgtI);
scalar dTest = magSqr(tgtCf[tgtI] - srcP);
if (dTest < d)
{
tgtFacei = tgtI;
d = dTest;
this->appendNbrFaces
(
tgtFacei,
tgtPatch,
visitedFaces,
tgtFaces
);
}
} while (tgtFaces.size() > 0);
}
void Foam::mapNearestAMI::setNextNearestFaces
(
boolList& mapFlag,
label& startSeedI,
label& srcFacei,
label& tgtFacei
) const
{
const labelList& srcNbr = this->srcPatch_.faceFaces()[srcFacei];
srcFacei = -1;
forAll(srcNbr, i)
{
label facei = srcNbr[i];
if (mapFlag[facei])
{
srcFacei = facei;
startSeedI = facei + 1;
return;
}
}
forAll(mapFlag, facei)
{
if (mapFlag[facei])
{
srcFacei = facei;
tgtFacei = this->findTargetFace(facei);
if (tgtFacei == -1)
{
const vectorField& srcCf = this->srcPatch_.faceCentres();
FatalErrorInFunction
<< "Unable to find target face for source face "
<< srcFacei << " with face centre " << srcCf[srcFacei]
<< abort(FatalError);
}
break;
}
}
}
Foam::label Foam::mapNearestAMI::findMappedSrcFace
(
const label tgtFacei,
const List<DynamicList<label>>& tgtToSrc
) const
{
DynamicList<label> testFaces(10);
DynamicList<label> visitedFaces(10);
testFaces.append(tgtFacei);
do
{
// search target tgtFacei neighbours for match with source face
label tgtI = testFaces.remove();
if (findIndex(visitedFaces, tgtI) == -1)
{
visitedFaces.append(tgtI);
if (tgtToSrc[tgtI].size())
{
return tgtToSrc[tgtI][0];
}
else
{
const labelList& nbrFaces = this->tgtPatch_.faceFaces()[tgtI];
forAll(nbrFaces, i)
{
if (findIndex(visitedFaces, nbrFaces[i]) == -1)
{
testFaces.append(nbrFaces[i]);
}
}
}
}
} while (testFaces.size());
// did not find any match - should not be possible to get here!
return -1;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::mapNearestAMI::mapNearestAMI
(
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch,
const scalarField& srcMagSf,
const scalarField& tgtMagSf,
const faceAreaIntersect::triangulationMode& triMode,
const bool reverseTarget,
const bool requireMatch
)
:
AMIMethod
(
srcPatch,
tgtPatch,
srcMagSf,
tgtMagSf,
triMode,
reverseTarget,
requireMatch
)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::mapNearestAMI::~mapNearestAMI()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::mapNearestAMI::calculate
(
labelListList& srcAddress,
scalarListList& srcWeights,
labelListList& tgtAddress,
scalarListList& tgtWeights,
label srcFacei,
label tgtFacei
)
{
bool ok =
this->initialise
(
srcAddress,
srcWeights,
tgtAddress,
tgtWeights,
srcFacei,
tgtFacei
);
if (!ok)
{
return;
}
// temporary storage for addressing and weights
List<DynamicList<label>> srcAddr(this->srcPatch_.size());
List<DynamicList<label>> tgtAddr(this->tgtPatch_.size());
// construct weights and addressing
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// list to keep track of whether src face can be mapped
boolList mapFlag(srcAddr.size(), true);
// reset starting seed
label startSeedI = 0;
DynamicList<label> nonOverlapFaces;
do
{
findNearestFace(this->srcPatch_, this->tgtPatch_, srcFacei, tgtFacei);
srcAddr[srcFacei].append(tgtFacei);
tgtAddr[tgtFacei].append(srcFacei);
mapFlag[srcFacei] = false;
// Do advancing front starting from srcFacei, tgtFacei
setNextNearestFaces
(
mapFlag,
startSeedI,
srcFacei,
tgtFacei
);
} while (srcFacei >= 0);
// for the case of multiple source faces per target face, select the
// nearest source face only and discard the others
const vectorField& srcCf = this->srcPatch_.faceCentres();
const vectorField& tgtCf = this->tgtPatch_.faceCentres();
forAll(tgtAddr, targetFacei)
{
if (tgtAddr[targetFacei].size() > 1)
{
const vector& tgtC = tgtCf[tgtFacei];
DynamicList<label>& srcFaces = tgtAddr[targetFacei];
label srcFacei = srcFaces[0];
scalar d = magSqr(tgtC - srcCf[srcFacei]);
for (label i = 1; i < srcFaces.size(); i++)
{
label srcI = srcFaces[i];
scalar dNew = magSqr(tgtC - srcCf[srcI]);
if (dNew < d)
{
d = dNew;
srcFacei = srcI;
}
}
srcFaces.clear();
srcFaces.append(srcFacei);
}
}
// If there are more target faces than source faces, some target faces
// might not yet be mapped
forAll(tgtAddr, tgtFacei)
{
if (tgtAddr[tgtFacei].empty())
{
label srcFacei = findMappedSrcFace(tgtFacei, tgtAddr);
if (srcFacei >= 0)
{
// note - reversed search from src->tgt to tgt->src
findNearestFace
(
this->tgtPatch_,
this->srcPatch_,
tgtFacei,
srcFacei
);
tgtAddr[tgtFacei].append(srcFacei);
}
}
}
// transfer data to persistent storage
forAll(srcAddr, i)
{
srcAddress[i].transfer(srcAddr[i]);
srcWeights[i] = scalarList(1, 1.0);
}
forAll(tgtAddr, i)
{
tgtAddress[i].transfer(tgtAddr[i]);
tgtWeights[i] = scalarList(1, 1.0);
}
}
// ************************************************************************* //

View File

@ -1,152 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2019 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/>.
Class
Foam::mapNearestAMI
Description
Nearest-mapping Arbitrary Mesh Interface (AMI) method
SourceFiles
mapNearestAMI.C
\*---------------------------------------------------------------------------*/
#ifndef mapNearestAMI_H
#define mapNearestAMI_H
#include "AMIMethod.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class mapNearestAMI Declaration
\*---------------------------------------------------------------------------*/
class mapNearestAMI
:
public AMIMethod
{
// Private Member Functions
// Marching front
//- Find nearest target face for source face srcFacei
void findNearestFace
(
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch,
const label& srcFacei,
label& tgtFacei
) const;
//- Determine next source-target face pair
void setNextNearestFaces
(
boolList& mapFlag,
label& startSeedI,
label& srcFacei,
label& tgtFacei
) const;
//- Find mapped source face
label findMappedSrcFace
(
const label tgtFacei,
const List<DynamicList<label>>& tgtToSrc
) const;
// Evaluation
//- Area of intersection between source and target faces
scalar interArea
(
const label srcFacei,
const label tgtFacei
) const;
public:
//- Runtime type information
TypeName("mapNearestAMI");
// Constructors
//- Construct from components
mapNearestAMI
(
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch,
const scalarField& srcMagSf,
const scalarField& tgtMagSf,
const faceAreaIntersect::triangulationMode& triMode,
const bool reverseTarget = false,
const bool requireMatch = true
);
//- Disallow default bitwise copy construction
mapNearestAMI(const mapNearestAMI&) = delete;
//- Destructor
virtual ~mapNearestAMI();
// Member Functions
// Manipulation
//- Update addressing and weights
virtual void calculate
(
labelListList& srcAddress,
scalarListList& srcWeights,
labelListList& tgtAddress,
scalarListList& tgtWeights,
label srcFacei = -1,
label tgtFacei = -1
);
// Member Operators
//- Disallow default bitwise assignment
void operator=(const mapNearestAMI&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,160 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2018 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/>.
\*---------------------------------------------------------------------------*/
#include "partialFaceAreaWeightAMI.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(partialFaceAreaWeightAMI, 0);
addToRunTimeSelectionTable(AMIMethod, partialFaceAreaWeightAMI, components);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::partialFaceAreaWeightAMI::setNextFaces
(
label& startSeedI,
label& srcFacei,
label& tgtFacei,
const boolList& mapFlag,
labelList& seedFaces,
const DynamicList<label>& visitedFaces,
const bool errorOnNotFound
) const
{
faceAreaWeightAMI::setNextFaces
(
startSeedI,
srcFacei,
tgtFacei,
mapFlag,
seedFaces,
visitedFaces,
false // no error on not found
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::partialFaceAreaWeightAMI::partialFaceAreaWeightAMI
(
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch,
const scalarField& srcMagSf,
const scalarField& tgtMagSf,
const faceAreaIntersect::triangulationMode& triMode,
const bool reverseTarget,
const bool requireMatch
)
:
faceAreaWeightAMI
(
srcPatch,
tgtPatch,
srcMagSf,
tgtMagSf,
triMode,
reverseTarget,
requireMatch
)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::partialFaceAreaWeightAMI::~partialFaceAreaWeightAMI()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::partialFaceAreaWeightAMI::conformal() const
{
return false;
}
void Foam::partialFaceAreaWeightAMI::calculate
(
labelListList& srcAddress,
scalarListList& srcWeights,
labelListList& tgtAddress,
scalarListList& tgtWeights,
label srcFacei,
label tgtFacei
)
{
bool ok =
this->initialise
(
srcAddress,
srcWeights,
tgtAddress,
tgtWeights,
srcFacei,
tgtFacei
);
if (!ok)
{
return;
}
// temporary storage for addressing and weights
List<DynamicList<label>> srcAddr(this->srcPatch_.size());
List<DynamicList<scalar>> srcWght(srcAddr.size());
List<DynamicList<label>> tgtAddr(this->tgtPatch_.size());
List<DynamicList<scalar>> tgtWght(tgtAddr.size());
faceAreaWeightAMI::calcAddressing
(
srcAddr,
srcWght,
tgtAddr,
tgtWght,
srcFacei,
tgtFacei
);
// transfer data to persistent storage
forAll(srcAddr, i)
{
srcAddress[i].transfer(srcAddr[i]);
srcWeights[i].transfer(srcWght[i]);
}
forAll(tgtAddr, i)
{
tgtAddress[i].transfer(tgtAddr[i]);
tgtWeights[i].transfer(tgtWght[i]);
}
}
// ************************************************************************* //

View File

@ -1,135 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2019 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/>.
Class
Foam::partialFaceAreaWeightAMI
Description
Partial face area weighted Arbitrary Mesh Interface (AMI) method
SourceFiles
partialFaceAreaWeightAMI.C
\*---------------------------------------------------------------------------*/
#ifndef partialFaceAreaWeightAMI_H
#define partialFaceAreaWeightAMI_H
#include "faceAreaWeightAMI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class partialFaceAreaWeightAMI Declaration
\*---------------------------------------------------------------------------*/
class partialFaceAreaWeightAMI
:
public faceAreaWeightAMI
{
// Private Member Functions
// Marching front
//- Set the source and target seed faces
virtual void setNextFaces
(
label& startSeedI,
label& srcFacei,
label& tgtFacei,
const boolList& mapFlag,
labelList& seedFaces,
const DynamicList<label>& visitedFaces,
bool errorOnNotFound = true
) const;
public:
//- Runtime type information
TypeName("partialFaceAreaWeightAMI");
// Constructors
//- Construct from components
partialFaceAreaWeightAMI
(
const primitivePatch& srcPatch,
const primitivePatch& tgtPatch,
const scalarField& srcMagSf,
const scalarField& tgtMagSf,
const faceAreaIntersect::triangulationMode& triMode,
const bool reverseTarget = false,
const bool requireMatch = true
);
//- Disallow default bitwise copy construction
partialFaceAreaWeightAMI(const partialFaceAreaWeightAMI&) = delete;
//- Destructor
virtual ~partialFaceAreaWeightAMI();
// Member Functions
// Access
//- Flag to indicate that interpolation patches are conformal
virtual bool conformal() const;
// Manipulation
//- Update addressing and weights
virtual void calculate
(
labelListList& srcAddress,
scalarListList& srcWeights,
labelListList& tgtAddress,
scalarListList& tgtWeights,
label srcFacei = -1,
label tgtFacei = -1
);
// Member Operators
//- Disallow default bitwise assignment
void operator=(const partialFaceAreaWeightAMI&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,596 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2017-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/>.
\*---------------------------------------------------------------------------*/
#include "sweptFaceAreaWeightAMI.H"
#include "cut.H"
#include "linearEqn.H"
#include "quadraticEqn.H"
#include "unitConversion.H"
#include "triSurface.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(sweptFaceAreaWeightAMI, 0);
addToRunTimeSelectionTable(AMIMethod, sweptFaceAreaWeightAMI, components);
}
const Foam::scalar Foam::sweptFaceAreaWeightAMI::minCutRatio_ = 10*small;
const Foam::scalar Foam::sweptFaceAreaWeightAMI::maxDot_ =
- cos(degToRad(89.9));
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<unsigned Size>
void Foam::sweptFaceAreaWeightAMI::writeCutTrisVTK
(
const cutTriList<Size>& tris,
const word& name
) const
{
OFstream obj(typeName + "_" + name + ".vtk");
obj << "# vtk DataFile Version 2.0" << endl
<< triSurface::typeName << endl
<< "ASCII" << endl
<< "DATASET POLYDATA" << endl
<< "POINTS " << 3*tris.size() << " float" << endl;
for (label i = 0; i < tris.size(); ++ i)
{
for (label j = 0; j < 3; ++ j)
{
const vector& x = tris[i][j];
obj << x.x() << ' ' << x.y() << ' ' << x.z() << endl;
}
}
obj << "POLYGONS " << tris.size() << ' ' << 4*tris.size() << endl;
for (label i = 0; i < tris.size(); ++ i)
{
obj << 3 << ' ' << 3*i << ' ' << 3*i + 1 << ' ' << 3*i + 2 << endl;
}
}
void Foam::sweptFaceAreaWeightAMI::writeFaceOBJ
(
const face& f,
const pointField& ps,
const string& name
) const
{
OFstream obj(typeName + "_" + name + ".obj");
for (label i = 0; i < f.size(); ++ i)
{
const vector& x = ps[f[i]];
obj << "v " << x.x() << ' ' << x.y() << ' ' << x.z() << endl;
}
obj << 'f';
for (label i = 0; i < f.size(); ++ i)
{
obj << ' ' << i + 1;
}
obj << endl;
}
void Foam::sweptFaceAreaWeightAMI::writeProjectionOBJ
(
const label srcN,
const FixedList<point, 4>& srcTri,
const FixedList<point, 4>& srcNrm
) const
{
scalar l = 0;
for (label i = 0; i < srcN - 1; ++ i)
{
l = max(l, mag(srcTri[i] - srcTri[i + 1]));
}
const label nu = 20, nv = 20;
const scalar u0 = 0, u1 = 1, v0 = -l, v1 = l;
OFstream obj(typeName + "_projection.obj");
for (label i = 0; i < srcN; ++ i)
{
const point& p0 = srcTri[i], p1 = srcTri[(i + 1) % srcN];
const vector& n0 = srcNrm[i], n1 = srcNrm[(i + 1) % srcN];
for (label iu = 0; iu <= nu; ++ iu)
{
const scalar u = u0 + (u1 - u0)*scalar(iu)/nu;
for (label iv = 0; iv <= nv; ++ iv)
{
const scalar v = v0 + (v1 - v0)*scalar(iv)/nv;
const vector x = p0 + (p1 - p0)*u + (n0 + (n1 - n0)*u)*v;
obj << "v " << x.x() << ' ' << x.y() << ' ' << x.z() << endl;
}
}
}
for (label i = 0; i < srcN; ++ i)
{
for (label iu = 0; iu < nu; ++ iu)
{
for (label iv = 0; iv < nv; ++ iv)
{
obj << "f "
<< i*(nu + 1)*(nv + 1) + (nv + 1)*iu + iv + 1 << ' '
<< i*(nu + 1)*(nv + 1) + (nv + 1)*iu + iv + 2 << ' '
<< i*(nu + 1)*(nv + 1) + (nv + 1)*(iu + 1) + iv + 2 << ' '
<< i*(nu + 1)*(nv + 1) + (nv + 1)*(iu + 1) + iv + 1<< endl;
}
}
}
}
Foam::label Foam::sweptFaceAreaWeightAMI::getSourceProjection
(
FixedList<point, 4>& srcTri,
FixedList<point, 4>& srcNrm,
const FixedList<point, 3>& tgtTri
) const
{
// The target normal
const vector np = plane(tgtTri[0], tgtTri[1], tgtTri[2]).normal();
// Dot products between the projection normals and the target plane
FixedList<scalar, 4> dots;
for (label i = 0; i < 3; ++ i)
{
dots[i] = srcNrm[i] & np;
}
dots[3] = 0;
// Search though for the number of reversed directions and an index for
// both a reverse and a forward direction
label nR = 0, iR = -1, iF = -1;
for (label i = 0; i < 3; ++ i)
{
if (dots[i] > maxDot_)
{
++ nR;
iR = i;
}
else
{
iF = i;
}
}
// If all the normals hit in the forward or reverse direction then return
// the existing projection or no projection respectively
if (nR == 0 || nR == 3)
{
return 3 - nR;
}
// One normal hits in the reverse direction
if (nR == 1)
{
/*
o j1
/ \
/ \
/ \
/ o jR
/ / .
/ / .
/ / .
o - > - o . . . . (old iR)
i0 iR
*/
// Make a gap by duplicating the reverse the point
for (label j = 2; j >= iR; -- j)
{
srcTri[j + 1] = srcTri[j];
srcNrm[j + 1] = srcNrm[j];
dots[j + 1] = dots[j];
}
const label jR = iR + 1;
const label i0 = (iR + 3) % 4, j1 = (jR + 1) % 4;
const scalar wi = (dots[iR] - maxDot_)/(dots[iR] - dots[i0]);
const scalar wj = (dots[jR] - maxDot_)/(dots[jR] - dots[j1]);
srcTri[iR] = srcTri[iR] + (srcTri[i0] - srcTri[iR])*wi;
srcTri[jR] = srcTri[jR] + (srcTri[j1] - srcTri[jR])*wj;
srcNrm[iR] = srcNrm[iR] + (srcNrm[i0] - srcNrm[iR])*wi;
srcNrm[jR] = srcNrm[jR] + (srcNrm[j1] - srcNrm[jR])*wj;
return 4;
}
// Two normals hit in the reverse direction
if (nR == 2)
{
/*
. (old jR)
. .
jR o .
/ \ .
/ \ .
/ \ .
/ \ .
/ \ .
o - - > - - o . . (old iR)
iF iR
*/
const label iR = (iF + 1) % 3, jR = (iF + 2) % 3;
const label i0 = (iR + 2) % 3, j1 = (jR + 1) % 3;
const scalar wi = (dots[iR] - maxDot_)/(dots[iR] - dots[i0]);
const scalar wj = (dots[jR] - maxDot_)/(dots[jR] - dots[j1]);
srcTri[iR] = srcTri[iR] + (srcTri[i0] - srcTri[iR])*wi;
srcTri[jR] = srcTri[jR] + (srcTri[j1] - srcTri[jR])*wj;
srcNrm[iR] = srcNrm[iR] + (srcNrm[i0] - srcNrm[iR])*wi;
srcNrm[jR] = srcNrm[jR] + (srcNrm[j1] - srcNrm[jR])*wj;
return 3;
}
// This cannot happen
return -1;
}
Foam::plane Foam::sweptFaceAreaWeightAMI::getCutPlane
(
const point& p0,
const point& p1,
const vector& n0,
const vector& n1,
const FixedList<point, 3>& tgtTri
) const
{
// The target plane
const plane tgtPln(tgtTri[0], tgtTri[1], tgtTri[2]);
const point& pp = tgtPln.refPoint();
const vector& np = tgtPln.normal();
// Calculate the bounding intersection points. These are the locations at
// which the bounding lines of the projected surface intersect with the
// target plane.
const scalar v0 = ((pp - p0) & np)/(n0 & np);
const scalar v1 = ((pp - p1) & np)/(n1 & np);
Pair<point> cutPnts(p0 + v0*n0, p1 + v1*n1);
Pair<vector> cutNrms((p1 - p0 + n1*v0) ^ n0, (p1 - p0 - n0*v1) ^ n1);
// Calculate edge intersections with the surface
for (label i = 0; i < 3; ++ i)
{
// The current target edge
const point& l0 = tgtTri[i], l1 = tgtTri[(i + 1)%3];
// Form the quadratic in the surface parameter u
const vector k = l0 - p0;
const vector a = l0 - l1, b = p1 - p0, c = n0, d = n1 - n0;
const vector ka = k ^ a, ba = b ^ a, ca = c ^ a, da = d ^ a;
const scalar A = d & ba;
const scalar B = (c & ba) - (d & ka);
const scalar C = - c & ka;
// Solve and extract the other parameters
const Roots<2> us = quadraticEqn(A, B, C).roots();
Pair<scalar> vs, ws;
Pair<vector> ns;
Pair<bool> cuts(false, false);
for (label j = 0; j < 2; ++ j)
{
if (us.type(j) == rootType::real)
{
const vector den = ca + da*us[j];
if (magSqr(den) > vSmall)
{
const vector vNum = ka - ba*us[j];
const vector wNum = (- k + b*us[j]) ^ (c + d*us[j]);
vs[j] = (vNum & den)/magSqr(den);
ws[j] = (wNum & den)/magSqr(den);
ns[j] = (b ^ (c + d*us[j])) + (n1 ^ n0)*vs[j];
const bool cutu = 0 < us[j] && us[j] < 1;
const bool cutw = 0 < ws[j] && ws[j] < 1;
cuts[j] = cutu && cutw;
}
}
}
// If we have just one intersection in bounds then store it in the
// result list based on its direction
if (cuts[0] != cuts[1])
{
const label j = cuts[0] ? 0 : 1;
const scalar na = ns[j] & a;
cutPnts[na < 0] = l0 + (l1 - l0)*ws[j];
cutNrms[na < 0] = ns[j];
}
}
// Generate and return the cut plane. If the cut points are not coincident
// then form a plane normal by crossing the displacement between the points
// by the target plane normal. If the points are coincident then use the
// projected surface normal evaluated at the first cut point.
const vector cutDelta = cutPnts[1] - cutPnts[0];
const bool coincident = mag(cutDelta) < minCutRatio_*mag(p1 - p0);
return plane(cutPnts[0], coincident ? cutNrms[0] : np ^ cutDelta);
};
// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
Foam::scalar Foam::sweptFaceAreaWeightAMI::interArea
(
const label srcFacei,
const label tgtFacei
) const
{
const label debugTgtFace =
(- 1 - debug) % this->tgtPatch_.size() == tgtFacei
? (- 1 - debug) / this->tgtPatch_.size() + 1 : 0;
const bool debugPrint = debug > 0 || debugTgtFace > 0;
const bool debugWrite = debug > 1 || debugTgtFace > 1;
if (debugPrint)
{
Info<< "Inter area between source face #" << srcFacei
<< " and target face #" << tgtFacei << (debugWrite ? "\n" : ": ");
}
// Patch data
const pointField& srcPoints = this->srcPatch_.localPoints();
const pointField& tgtPoints = this->tgtPatch_.localPoints();
const vectorField& srcPointNormals = this->srcPatch_.pointNormals();
// Faces
const face& srcFace = this->srcPatch_.localFaces()[srcFacei];
const face& tgtFace = this->tgtPatch_.localFaces()[tgtFacei];
// Write out the faces
if (debugWrite)
{
writeFaceOBJ(srcFace, srcPoints, "source");
writeFaceOBJ(tgtFace, tgtPoints, "target");
}
if (debugTgtFace)
{
writeFaceOBJ(tgtFace, tgtPoints, "target" + name(tgtFacei));
}
// Triangulate the faces
const faceAreaIntersect::triangulationMode triMode = this->triMode_;
triFaceList srcFaceTris, tgtFaceTris;
faceAreaIntersect::triangulate(srcFace, srcPoints, triMode, srcFaceTris);
faceAreaIntersect::triangulate(tgtFace, tgtPoints, triMode, tgtFaceTris);
// Area sum
scalar areaMag = Zero;
// Loop the target triangles
forAllConstIter(triFaceList, tgtFaceTris, tgtIter)
{
const FixedList<point, 3>
tgtTri =
{
tgtPoints[(*tgtIter)[0]],
tgtPoints[(*tgtIter)[this->reverseTarget_ ? 2 : 1]],
tgtPoints[(*tgtIter)[this->reverseTarget_ ? 1 : 2]]
};
// Loop the source triangles
forAllConstIter(triFaceList, srcFaceTris, srcIter)
{
FixedList<point, 4>
srcTri =
{
srcPoints[(*srcIter)[0]],
srcPoints[(*srcIter)[1]],
srcPoints[(*srcIter)[2]],
vector::zero
};
FixedList<point, 4>
srcNrm =
{
srcPointNormals[(*srcIter)[0]],
srcPointNormals[(*srcIter)[1]],
srcPointNormals[(*srcIter)[2]],
vector::zero
};
// Get the source projection modified for any reverse intersections
const label srcN = getSourceProjection(srcTri, srcNrm, tgtTri);
if (srcN <= 0)
{
continue;
}
// Write the source projection
if (debugWrite)
{
writeProjectionOBJ(srcN, srcTri, srcNrm);
}
// Create the initial cut triangle list
cutTriList<8> cutTris;
cutTris.append(tgtTri);
// Write the initial triangle
if (debugWrite)
{
writeCutTrisVTK(cutTris, "tris0");
}
// Do all but one of the cuts
for
(
label i = 0;
i < srcN - 1 && (debugWrite || cutTris.size());
++ i
)
{
// Do the cut
const plane cutPlane =
getCutPlane
(
srcTri[i],
srcTri[i+1],
srcNrm[i],
srcNrm[i+1],
tgtTri
);
cutTriList<8> cutTrisTmp;
for (label j = 0; j < cutTris.size(); ++j)
{
triCut
(
cutTris[j],
cutPlane,
cut::noOp(),
cut::appendOp<cutTriList<8>>(cutTrisTmp)
);
}
Swap(cutTris, cutTrisTmp);
// Write the triangles resulting from the cut
if (debugWrite)
{
writeCutTrisVTK(cutTris, "tris" + name(i + 1));
}
}
// Do the last cut
const plane cutPlane =
getCutPlane
(
srcTri[srcN - 1],
srcTri[0],
srcNrm[srcN - 1],
srcNrm[0],
tgtTri
);
cutTriList<8> cutTrisTmp;
for (label i = 0; i < cutTris.size(); ++ i)
{
// Sum the area of the cut triangle
areaMag +=
mag
(
triCut
(
cutTris[i],
cutPlane,
cut::noOp(),
cut::areaOp()
)
);
// Store the cut triangle if it is needed for output
if (debugWrite || debugTgtFace)
{
triCut
(
cutTris[i],
cutPlane,
cut::noOp(),
cut::appendOp<cutTriList<8>>(cutTrisTmp)
);
}
}
Swap(cutTris, cutTrisTmp);
// Write the triangles resulting from the cuts
if (debugTgtFace && cutTris.size())
{
static label writeCutTrisVTKIndex = 0;
writeCutTrisVTK
(
cutTris,
"target" + name(tgtFacei) + "_"
+ "tris" + name(writeCutTrisVTKIndex ++)
);
}
if (debugWrite)
{
writeCutTrisVTK(cutTris, "tris" + name(srcN));
Info << "view triangles then press ENTER to continue ...";
getchar();
}
}
}
// Print the difference between this inter-area and that obtained by the
// standard algorithm built around faceAreaIntersect
if (debugPrint)
{
const scalar standardAreaMag =
faceAreaWeightAMI::interArea
(
srcFacei,
tgtFacei
);
Info<<"standard=" << standardAreaMag << ", swept=" << areaMag
<< endl;
}
return areaMag;
}
Foam::scalar Foam::sweptFaceAreaWeightAMI::minWeight() const
{
return small;
}
Foam::scalar Foam::sweptFaceAreaWeightAMI::maxWalkAngle() const
{
return degToRad(180);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::sweptFaceAreaWeightAMI::~sweptFaceAreaWeightAMI()
{}
// ************************************************************************* //

View File

@ -1,264 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2017-2020 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/>.
Class
Foam::sweptFaceAreaWeightAMI
Description
Swept face area weighted Arbitrary Mesh Interface (AMI) method
This method uses the point normals of the source patch to sweep the source
faces over the target patches. This creates a projection which fills space,
and which therefore generates overlap areas which are consistent between
neighbouring faces. The projection of a source edge is shown below:
\verbatim
/
/
n_1 ^
/
/
p_1 o
\\
\\ ^ u
\\ \
\\ + - > v
\\
o - - - > - - -
p_0 n_0
\endverbatim
The surface is, in general, not flat. Any deviation between the two end
normals generates expansion, contraction, and twist in the surface. The
surface connects with surfaces emanating from connected edges along the end
normals. This is what makes the projection fill space and generate
consistent overlaps between neighbouring faces.
The projected surface is parameterised by the local coordinates, \f$u\f$
and \f$v\f$, and a position on this plane is calculated from \f$u\f$ and
\f$v\f$ as follows:
\f[
x(u, v) = p_0 + (p_1 - p_0) u + [ q_0 + (q_1 - q_0) u ] v
\f]
To calculate an intersection with a line between points \f$l_0\f$ to
\f$l_1\f$, we define a local coordinate, \f$w\f$, along the line, and
subtract it's equation from that of the surface:
\f[
0 = (p_0 - l_0) - (l_1 - l_0) w + (p_1 - p_0) u +
[ q_0 + (q_1 - q_0) u ] v
\f]
This is a system of three equations in three unknowns. It is non-linear,
courtesy of the \f$u v\f$ term at the end. It can be reduced to a single
quadratic in any of the three variables. We choose to solve for \f$u\f$ by
taking the dot product of the above equation with the following vector:
\f[
(l_1 - l_0) \times [ q_0 + (q_1 - q_0) u ]
\f]
The sign of the intersection (i.e., whether the line crosses from below the
surface to above or vice versa) can be determined by taking the dot product
of the line vector with the surface normal at the intersection. The surface
normal is as follows:
\f[
n(u, v) = (p_1 - p_0) \times [q_0 + (q_1 - q_0) u] + (q_1 \times q_0) v
\f]
SourceFiles
sweptFaceAreaWeightAMI.C
\*---------------------------------------------------------------------------*/
#ifndef sweptFaceAreaWeightAMI_H
#define sweptFaceAreaWeightAMI_H
#include "faceAreaWeightAMI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class sweptFaceAreaWeightAMI Declaration
\*---------------------------------------------------------------------------*/
class sweptFaceAreaWeightAMI
:
public faceAreaWeightAMI
{
// Private static data
//- Minimum length of a cut as a ratio of the overall projected edge
// length
static const scalar minCutRatio_;
//- Maximum allowable dot product between a source point normal and a
// target triangle
static const scalar maxDot_;
// Private classes
//- A fixed list of tris which simulates a dynamic list by incrementing
// a counter whenever its append method is called. This is used as an
// optimisation so that the tri cutting does not allocate memory.
template<unsigned Size>
class cutTriList
:
public FixedList<FixedList<point, 3>, Size>
{
private:
//- The number of stored elements
label n_;
public:
//- Construct null
cutTriList()
:
n_(0)
{}
//- Clear the array
void clear()
{
n_ = 0;
}
//- Get the current size
label size() const
{
return n_;
}
//- Add a new tet to the end of the array
void append(const FixedList<point, 3>& t)
{
this->operator[](n_) = t;
++ n_;
}
};
// Private Member Functions
// Debugging
//- Write a VTK file of cut triangles
template<unsigned Size>
void writeCutTrisVTK
(
const cutTriList<Size>& tris,
const word& name
) const;
//- Write an OBJ file of a face
void writeFaceOBJ
(
const face& f,
const pointField& ps,
const string& name
) const;
//- Write an OBJ file of the source projection
void writeProjectionOBJ
(
const label srcN,
const FixedList<point, 4>& srcTri,
const FixedList<point, 4>& srcPrj
) const;
//- Convert the source tris and normals to a projection. Most of the
// time this does nothing, but if some of the normals point in the
// reverse direction the projection will be reduced to span only the
// region in which the projection points forward through the target
// plane. Returns the number of edges in the projection (0, 3 or 4).
label getSourceProjection
(
FixedList<point, 4>& srcTri,
FixedList<point, 4>& srcNrm,
const FixedList<point, 3>& tgtTri
) const;
//- Get the cutting plane, for an edge of the source projection.
plane getCutPlane
(
const point& p0,
const point& p1,
const vector& n0,
const vector& n1,
const FixedList<point, 3>& tgtTri
) const;
//- The minimum weight below which connections are discarded
virtual scalar minWeight() const;
//- The maximum edge angle that the walk will cross
virtual scalar maxWalkAngle() const;
protected:
// Protected Member Functions
// Evaluation
//- Area of intersection between source and target faces
virtual scalar interArea
(
const label srcFacei,
const label tgtFacei
) const;
public:
//- Runtime type information
TypeName("sweptFaceAreaWeightAMI");
// Constructors
//- Use parent constructors
using faceAreaWeightAMI::faceAreaWeightAMI;
//- Destructor
virtual ~sweptFaceAreaWeightAMI();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,147 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 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/>.
\*---------------------------------------------------------------------------*/
#include "cyclicAMIGAMGInterfaceField.H"
#include "addToRunTimeSelectionTable.H"
#include "lduMatrix.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cyclicAMIGAMGInterfaceField, 0);
addToRunTimeSelectionTable
(
GAMGInterfaceField,
cyclicAMIGAMGInterfaceField,
lduInterface
);
addToRunTimeSelectionTable
(
GAMGInterfaceField,
cyclicAMIGAMGInterfaceField,
lduInterfaceField
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cyclicAMIGAMGInterfaceField::cyclicAMIGAMGInterfaceField
(
const GAMGInterface& GAMGCp,
const lduInterfaceField& fineInterface
)
:
GAMGInterfaceField(GAMGCp, fineInterface),
cyclicAMIInterface_(refCast<const cyclicAMIGAMGInterface>(GAMGCp)),
rank_(0)
{
const cyclicAMILduInterfaceField& p =
refCast<const cyclicAMILduInterfaceField>(fineInterface);
rank_ = p.rank();
}
Foam::cyclicAMIGAMGInterfaceField::cyclicAMIGAMGInterfaceField
(
const GAMGInterface& GAMGCp,
const int rank
)
:
GAMGInterfaceField(GAMGCp, rank),
cyclicAMIInterface_(refCast<const cyclicAMIGAMGInterface>(GAMGCp)),
rank_(rank)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cyclicAMIGAMGInterfaceField::~cyclicAMIGAMGInterfaceField()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::cyclicAMIGAMGInterfaceField::updateInterfaceMatrix
(
scalarField& result,
const scalarField& psiInternal,
const scalarField& coeffs,
const direction cmpt,
const Pstream::commsTypes
) const
{
const cyclicAMIGAMGInterface& thisInterface = cyclicAMIInterface_;
const cyclicAMIGAMGInterface& neiInterface = thisInterface.nbrPatch();
// Get neighbouring field
scalarField pnf(neiInterface.interfaceInternalField(psiInternal));
// Transform according to the transformation tensors
transformCoupleField(pnf, cmpt);
// Transform and interpolate
scalarField pf(size(), Zero);
if (thisInterface.owner())
{
forAll(thisInterface.AMIs(), i)
{
const scalar r =
pow
(
inv(thisInterface.AMITransforms()[i]).T()(cmpt, cmpt),
rank()
);
pf += thisInterface.AMIs()[i].interpolateToSource(r*pnf);
}
}
else
{
forAll(neiInterface.AMIs(), i)
{
const scalar r =
pow
(
neiInterface.AMITransforms()[i].T()(cmpt, cmpt),
rank()
);
pf += neiInterface.AMIs()[i].interpolateToTarget(r*pnf);
}
}
// Multiply the field by coefficients and add into the result
const labelUList& faceCells = cyclicAMIInterface_.faceCells();
forAll(faceCells, elemI)
{
result[faceCells[elemI]] -= coeffs[elemI]*pf[elemI];
}
}
// ************************************************************************* //

View File

@ -1,152 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 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/>.
Class
Foam::cyclicAMIGAMGInterfaceField
Description
GAMG agglomerated cyclic interface field.
SourceFiles
cyclicAMIGAMGInterfaceField.C
\*---------------------------------------------------------------------------*/
#ifndef cyclicAMIGAMGInterfaceField_H
#define cyclicAMIGAMGInterfaceField_H
#include "GAMGInterfaceField.H"
#include "cyclicAMIGAMGInterface.H"
#include "cyclicAMILduInterfaceField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cyclicAMIGAMGInterfaceField Declaration
\*---------------------------------------------------------------------------*/
class cyclicAMIGAMGInterfaceField
:
public GAMGInterfaceField,
public cyclicAMILduInterfaceField
{
// Private Data
//- Local reference cast into the cyclic interface
const cyclicAMIGAMGInterface& cyclicAMIInterface_;
//- Rank of component for transformation
int rank_;
public:
//- Runtime type information
TypeName("cyclicAMI");
// Constructors
//- Construct from GAMG interface and fine level interface field
cyclicAMIGAMGInterfaceField
(
const GAMGInterface& GAMGCp,
const lduInterfaceField& fineInterfaceField
);
//- Construct from GAMG interface and fine level interface field
cyclicAMIGAMGInterfaceField
(
const GAMGInterface& GAMGCp,
const int rank
);
//- Disallow default bitwise copy construction
cyclicAMIGAMGInterfaceField
(
const cyclicAMIGAMGInterfaceField&
) = delete;
//- Destructor
virtual ~cyclicAMIGAMGInterfaceField();
// Member Functions
// Access
//- Return size
label size() const
{
return cyclicAMIInterface_.size();
}
// Interface matrix update
//- Update result field based on interface functionality
virtual void updateInterfaceMatrix
(
scalarField& result,
const scalarField& psiInternal,
const scalarField& coeffs,
const direction cmpt,
const Pstream::commsTypes commsType
) const;
//- Cyclic interface functions
//- Return transformation between the coupled patches
virtual const transformer& transform() const
{
return cyclicAMIInterface_.transform();
}
//- Return rank of component for transform
virtual int rank() const
{
return rank_;
}
// Member Operators
//- Disallow default bitwise assignment
void operator=(const cyclicAMIGAMGInterfaceField&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,209 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 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/>.
\*---------------------------------------------------------------------------*/
#include "AMIInterpolation.H"
#include "cyclicAMIGAMGInterface.H"
#include "addToRunTimeSelectionTable.H"
#include "Map.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cyclicAMIGAMGInterface, 0);
addToRunTimeSelectionTable
(
GAMGInterface,
cyclicAMIGAMGInterface,
lduInterface
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cyclicAMIGAMGInterface::cyclicAMIGAMGInterface
(
const label index,
const lduInterfacePtrsList& coarseInterfaces,
const lduInterface& fineInterface,
const labelField& localRestrictAddressing,
const labelField& neighbourRestrictAddressing,
const label fineLevelIndex,
const label coarseComm
)
:
GAMGInterface
(
index,
coarseInterfaces
),
fineCyclicAMIInterface_
(
refCast<const cyclicAMILduInterface>(fineInterface)
),
AMIs_(),
AMITransforms_()
{
// Construct face agglomeration from cell agglomeration
{
// From coarse face to cell
DynamicList<label> dynFaceCells(localRestrictAddressing.size());
// From face to coarse face
DynamicList<label> dynFaceRestrictAddressing
(
localRestrictAddressing.size()
);
Map<label> masterToCoarseFace(localRestrictAddressing.size());
forAll(localRestrictAddressing, ffi)
{
label curMaster = localRestrictAddressing[ffi];
Map<label>::const_iterator fnd = masterToCoarseFace.find
(
curMaster
);
if (fnd == masterToCoarseFace.end())
{
// New coarse face
label coarseI = dynFaceCells.size();
dynFaceRestrictAddressing.append(coarseI);
dynFaceCells.append(curMaster);
masterToCoarseFace.insert(curMaster, coarseI);
}
else
{
// Already have coarse face
dynFaceRestrictAddressing.append(fnd());
}
}
faceCells_.transfer(dynFaceCells);
faceRestrictAddressing_.transfer(dynFaceRestrictAddressing);
}
// On the owner side construct the AMI
if (fineCyclicAMIInterface_.owner())
{
// Construct the neighbour side agglomeration (as the neighbour would
// do it so it the exact loop above using neighbourRestrictAddressing
// instead of localRestrictAddressing)
labelList nbrFaceRestrictAddressing;
{
// From face to coarse face
DynamicList<label> dynNbrFaceRestrictAddressing
(
neighbourRestrictAddressing.size()
);
Map<label> masterToCoarseFace(neighbourRestrictAddressing.size());
forAll(neighbourRestrictAddressing, ffi)
{
label curMaster = neighbourRestrictAddressing[ffi];
Map<label>::const_iterator fnd = masterToCoarseFace.find
(
curMaster
);
if (fnd == masterToCoarseFace.end())
{
// New coarse face
label coarseI = masterToCoarseFace.size();
dynNbrFaceRestrictAddressing.append(coarseI);
masterToCoarseFace.insert(curMaster, coarseI);
}
else
{
// Already have coarse face
dynNbrFaceRestrictAddressing.append(fnd());
}
}
nbrFaceRestrictAddressing.transfer(dynNbrFaceRestrictAddressing);
}
AMIs_.resize(fineCyclicAMIInterface_.AMIs().size());
AMITransforms_.resize(fineCyclicAMIInterface_.AMITransforms().size());
forAll(AMIs(), i)
{
AMIs_.set
(
i,
new AMIInterpolation
(
fineCyclicAMIInterface_.AMIs()[i],
faceRestrictAddressing_,
nbrFaceRestrictAddressing
)
);
AMITransforms_[i] = fineCyclicAMIInterface_.AMITransforms()[i];
}
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cyclicAMIGAMGInterface::~cyclicAMIGAMGInterface()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::labelField> Foam::cyclicAMIGAMGInterface::internalFieldTransfer
(
const Pstream::commsTypes,
const labelUList& iF
) const
{
const cyclicAMIGAMGInterface& nbr =
dynamic_cast<const cyclicAMIGAMGInterface&>(nbrPatch());
const labelUList& nbrFaceCells = nbr.faceCells();
tmp<labelField> tpnf(new labelField(nbrFaceCells.size()));
labelField& pnf = tpnf.ref();
forAll(pnf, facei)
{
pnf[facei] = iF[nbrFaceCells[facei]];
}
return tpnf;
}
// ************************************************************************* //

View File

@ -1,177 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 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/>.
Class
Foam::cyclicAMIGAMGInterface
Description
GAMG agglomerated cyclic AMI interface.
SourceFiles
cyclicAMIGAMGInterface.C
\*---------------------------------------------------------------------------*/
#ifndef cyclicAMIGAMGInterface_H
#define cyclicAMIGAMGInterface_H
#include "GAMGInterface.H"
#include "cyclicAMILduInterface.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cyclicAMIGAMGInterface Declaration
\*---------------------------------------------------------------------------*/
class cyclicAMIGAMGInterface
:
public GAMGInterface,
public cyclicAMILduInterface
{
// Private Data
//- Reference for the cyclicLduInterface from which this is
// agglomerated
const cyclicAMILduInterface& fineCyclicAMIInterface_;
//- AMI interfaces
PtrList<AMIInterpolation> AMIs_;
//- AMI transformations
List<transformer> AMITransforms_;
public:
//- Runtime type information
TypeName("cyclicAMI");
// Constructors
//- Construct from fine level interface,
// local and neighbour restrict addressing
cyclicAMIGAMGInterface
(
const label index,
const lduInterfacePtrsList& coarseInterfaces,
const lduInterface& fineInterface,
const labelField& restrictAddressing,
const labelField& neighbourRestrictAddressing,
const label fineLevelIndex,
const label coarseComm
);
//- Disallow default bitwise copy construction
cyclicAMIGAMGInterface(const cyclicAMIGAMGInterface&) = delete;
//- Destructor
virtual ~cyclicAMIGAMGInterface();
// Member Functions
// Interface transfer functions
//- Transfer and return internal field adjacent to the interface
virtual tmp<labelField> internalFieldTransfer
(
const Pstream::commsTypes commsType,
const labelUList& iF
) const;
//- Cyclic interface functions
//- Return neighbour processor number
virtual label nbrPatchID() const
{
return fineCyclicAMIInterface_.nbrPatchID();
}
//- Does this side own the interface?
virtual bool owner() const
{
return fineCyclicAMIInterface_.owner();
}
//- Return neighbour patch
virtual const cyclicAMIGAMGInterface& nbrPatch() const
{
return dynamic_cast<const cyclicAMIGAMGInterface&>
(
coarseInterfaces_[nbrPatchID()]
);
}
//- Return a reference to the AMI interpolators
virtual const PtrList<AMIInterpolation>& AMIs() const
{
return AMIs_;
}
// Return a reference to the AMI transformations
virtual const List<transformer>& AMITransforms() const
{
return AMITransforms_;
}
//- Return transformation between the coupled patches
virtual const transformer& transform() const
{
return fineCyclicAMIInterface_.transform();
}
// I/O
//- Write to stream
virtual void write(Ostream&) const
{
// TBD. How to serialise the AMI such that we can stream
// cyclicAMIGAMGInterface.
NotImplemented;
}
// Member Operators
//- Disallow default bitwise assignment
void operator=(const cyclicAMIGAMGInterface&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,399 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
\*---------------------------------------------------------------------------*/
#include "faceAreaIntersect.H"
#include "polygonTriangulate.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
template<>
const char* NamedEnum<faceAreaIntersect::triangulationMode, 2>::names[] =
{
"fan",
"mesh"
};
}
const Foam::NamedEnum<Foam::faceAreaIntersect::triangulationMode, 2>
Foam::faceAreaIntersect::triangulationModeNames_;
Foam::scalar Foam::faceAreaIntersect::tol = 1e-6;
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
void Foam::faceAreaIntersect::triSliceWithPlane
(
const triPoints& tri,
const plane& p,
FixedList<triPoints, 10>& tris,
label& nTris,
const scalar len
)
{
// distance to cutting plane
FixedList<scalar, 3> d;
// determine how many of the points are above the cutting plane
label nCoPlanar = 0;
label nPos = 0;
label posI = -1;
label negI = -1;
label copI = -1;
forAll(tri, i)
{
d[i] = ((tri[i] - p.refPoint()) & p.normal());
if (mag(d[i]) < tol*len)
{
nCoPlanar++;
copI = i;
d[i] = 0.0;
}
else
{
if (d[i] > 0)
{
nPos++;
posI = i;
}
else
{
negI = i;
}
}
}
// Determine triangle area contribution
if
(
(nPos == 3)
|| ((nPos == 2) && (nCoPlanar == 1))
|| ((nPos == 1) && (nCoPlanar == 2))
)
{
/*
/\ _____
/ \ \ / /\
/____\ \ / / \
__________ ____v____ __/____\__
all points above cutting plane
- add complete triangle to list
*/
tris[nTris++] = tri;
}
else if ((nPos == 2) && (nCoPlanar == 0))
{
/*
i1________i2
\ /
--\----/--
\ /
\/
i0
2 points above plane, 1 below
- resulting quad above plane split into 2 triangles
- forget triangle below plane
*/
// point under the plane
label i0 = negI;
// indices of remaining points
label i1 = d.fcIndex(i0);
label i2 = d.fcIndex(i1);
// determine the two intersection points
point p01 = planeIntersection(d, tri, i0, i1);
point p02 = planeIntersection(d, tri, i0, i2);
// forget triangle below plane
// - decompose quad above plane into 2 triangles and add to list
setTriPoints(tri[i1], tri[i2], p02, nTris, tris);
setTriPoints(tri[i1], p02, p01, nTris, tris);
}
else if (nPos == 1)
{
// point above the plane
label i0 = posI;
if (nCoPlanar == 0)
{
/*
i0
/\
/ \
--/----\--
/______\
i2 i1
1 point above plane, 2 below
- keep triangle above intersection plane
- forget quad below plane
*/
// indices of remaining points
label i1 = d.fcIndex(i0);
label i2 = d.fcIndex(i1);
// determine the two intersection points
point p01 = planeIntersection(d, tri, i1, i0);
point p02 = planeIntersection(d, tri, i2, i0);
// add triangle above plane to list
setTriPoints(tri[i0], p01, p02, nTris, tris);
}
else
{
/*
i0
|\
| \
__|__\_i2_
| /
| /
|/
i1
1 point above plane, 1 on plane, 1 below
- keep triangle above intersection plane
*/
// point indices
label i1 = negI;
label i2 = copI;
// determine the intersection point
point p01 = planeIntersection(d, tri, i1, i0);
// add triangle above plane to list - clockwise points
if (d.fcIndex(i0) == i1)
{
setTriPoints(tri[i0], p01, tri[i2], nTris, tris);
}
else
{
setTriPoints(tri[i0], tri[i2], p01, nTris, tris);
}
}
}
else
{
/*
_________ __________ ___________
/\ \ /
/\ / \ \ /
/ \ /____\ \/
/____\
all points below cutting plane - forget
*/
}
}
Foam::scalar Foam::faceAreaIntersect::triangleIntersect
(
const triPoints& src,
const triPoints& tgt,
const vector& n
)
{
// Work storage
FixedList<triPoints, 10> workTris1;
label nWorkTris1 = 0;
FixedList<triPoints, 10> workTris2;
label nWorkTris2 = 0;
// cut source triangle with all inwards pointing faces of target triangle
// - triangles in workTris1 are inside target triangle
scalar t = sqrt(triArea(src));
// edge 0
{
// cut triangle src with plane and put resulting sub-triangles in
// workTris1 list
scalar s = mag(tgt[1] - tgt[0]);
plane pl0(tgt[0], tgt[1], tgt[1] + s*n);
triSliceWithPlane(src, pl0, workTris1, nWorkTris1, t);
}
if (nWorkTris1 == 0)
{
return 0.0;
}
// edge1
{
// cut workTris1 with plane and put resulting sub-triangles in
// workTris2 list (re-use tris storage)
scalar s = mag(tgt[2] - tgt[1]);
plane pl1(tgt[1], tgt[2], tgt[2] + s*n);
nWorkTris2 = 0;
for (label i = 0; i < nWorkTris1; i++)
{
triSliceWithPlane(workTris1[i], pl1, workTris2, nWorkTris2, t);
}
if (nWorkTris2 == 0)
{
return 0.0;
}
}
// edge2
{
// cut workTris2 with plane and put resulting sub-triangles in
// workTris1 list (re-use workTris1 storage)
scalar s = mag(tgt[2] - tgt[0]);
plane pl2(tgt[2], tgt[0], tgt[0] + s*n);
nWorkTris1 = 0;
for (label i = 0; i < nWorkTris2; i++)
{
triSliceWithPlane(workTris2[i], pl2, workTris1, nWorkTris1, t);
}
if (nWorkTris1 == 0)
{
return 0.0;
}
else
{
// calculate area of sub-triangles
scalar area = 0.0;
for (label i = 0; i < nWorkTris1; i++)
{
area += triArea(workTris1[i]);
}
return area;
}
}
}
// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
Foam::faceAreaIntersect::faceAreaIntersect
(
const pointField& pointsA,
const pointField& pointsB,
const bool reverseB
)
:
pointsA_(pointsA),
pointsB_(pointsB),
reverseB_(reverseB)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::faceAreaIntersect::triangulate
(
const face& f,
const pointField& points,
const triangulationMode& triMode,
triFaceList& faceTris
)
{
faceTris.resize(f.nTriangles());
switch (triMode)
{
case tmFan:
{
for (label i = 0; i < f.nTriangles(); ++ i)
{
faceTris[i][0] = f[0];
faceTris[i][1] = f[i + 1];
faceTris[i][2] = f[i + 2];
}
break;
}
case tmMesh:
{
polygonTriangulate triEngine;
triEngine.triangulate(UIndirectList<point>(points, f));
faceTris = triEngine.triPoints(f);
}
}
}
Foam::scalar Foam::faceAreaIntersect::calc
(
const face& faceA,
const face& faceB,
const vector& n,
const triangulationMode& triMode
)
{
// split faces into triangles
triFaceList trisA, trisB;
triangulate(faceA, pointsA_, triMode, trisA);
triangulate(faceB, pointsB_, triMode, trisB);
// intersect triangles
scalar totalArea = 0.0;
forAll(trisA, tA)
{
triPoints tpA = getTriPoints(pointsA_, trisA[tA], false);
// if (triArea(tpA) > rootVSmall)
{
forAll(trisB, tB)
{
triPoints tpB = getTriPoints(pointsB_, trisB[tB], !reverseB_);
// if (triArea(tpB) > rootVSmall)
{
totalArea += triangleIntersect(tpA, tpB, n);
}
}
}
}
return totalArea;
}
// ************************************************************************* //

View File

@ -1,192 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
Class
Foam::faceAreaIntersect
Description
Face intersection class
- calculates intersection area by sub-dividing face into triangles
and cutting
SourceFiles
faceAreaIntersect.C
\*---------------------------------------------------------------------------*/
#ifndef faceAreaIntersect_H
#define faceAreaIntersect_H
#include "pointField.H"
#include "FixedList.H"
#include "plane.H"
#include "face.H"
#include "NamedEnum.H"
#include "triFaceList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class faceAreaIntersect Declaration
\*---------------------------------------------------------------------------*/
class faceAreaIntersect
{
public:
typedef FixedList<point, 3> triPoints;
enum triangulationMode
{
tmFan,
tmMesh
};
static const NamedEnum<triangulationMode, 2> triangulationModeNames_;
private:
// Private Data
//- Reference to the points of sideA
const pointField& pointsA_;
//- Reference to the points of sideB
const pointField& pointsB_;
//- Flag to reverse B faces
const bool reverseB_;
// Static Data Members
static scalar tol;
// Private Member Functions
//- Get triPoints from face
inline triPoints getTriPoints
(
const pointField& points,
const triFace& f,
const bool reverse
) const;
//- Set triPoints into tri list
inline void setTriPoints
(
const point& a,
const point& b,
const point& c,
label& count,
FixedList<triPoints, 10>& tris
) const;
//- Return point of intersection between plane and triangle edge
inline point planeIntersection
(
const FixedList<scalar, 3>& d,
const triPoints& t,
const label negI,
const label posI
) const;
//- Return triangle area
inline scalar triArea(const triPoints& t) const;
//- Slice triangle with plane and generate new cut sub-triangles
void triSliceWithPlane
(
const triPoints& tri,
const plane& p,
FixedList<triPoints, 10>& tris,
label& nTris,
const scalar len
);
//- Return area of intersection of triangles src and tgt
scalar triangleIntersect
(
const triPoints& src,
const triPoints& tgt,
const vector& n
);
public:
// Constructors
//- Construct from components
faceAreaIntersect
(
const pointField& pointsA,
const pointField& pointsB,
const bool reverseB = false
);
// Public Member Functions
//- Fraction of local length scale to use as intersection tolerance
inline static scalar& tolerance();
//- Triangulate a face using the given triangulation mode
static void triangulate
(
const face& f,
const pointField& points,
const triangulationMode& triMode,
triFaceList& faceTris
);
//- Return area of intersection of faceA with faceB
scalar calc
(
const face& faceA,
const face& faceB,
const vector& n,
const triangulationMode& triMode
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "faceAreaIntersectI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,96 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
inline void Foam::faceAreaIntersect::setTriPoints
(
const point& a,
const point& b,
const point& c,
label& count,
FixedList<triPoints, 10>& tris
) const
{
triPoints& tp = tris[count++];
tp[0] = a;
tp[1] = b;
tp[2] = c;
}
inline Foam::faceAreaIntersect::triPoints Foam::faceAreaIntersect::getTriPoints
(
const pointField& points,
const triFace& f,
const bool reverse
) const
{
triPoints result;
if (reverse)
{
result[2] = points[f[0]];
result[1] = points[f[1]];
result[0] = points[f[2]];
}
else
{
result[0] = points[f[0]];
result[1] = points[f[1]];
result[2] = points[f[2]];
}
return result;
}
inline Foam::point Foam::faceAreaIntersect::planeIntersection
(
const FixedList<scalar, 3>& d,
const triPoints& t,
const label negI,
const label posI
) const
{
return (d[posI]*t[negI] - d[negI]*t[posI])/(-d[negI] + d[posI]);
}
inline Foam::scalar Foam::faceAreaIntersect::triArea(const triPoints& t) const
{
return mag(0.5*((t[1] - t[0])^(t[2] - t[0])));
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::scalar& Foam::faceAreaIntersect::tolerance()
{
return tol;
}
// ************************************************************************* //

View File

@ -1,42 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 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/>.
\*---------------------------------------------------------------------------*/
#include "cyclicAMILduInterface.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cyclicAMILduInterface, 0);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cyclicAMILduInterface::~cyclicAMILduInterface()
{}
// ************************************************************************* //

View File

@ -1,103 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 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/>.
Class
Foam::cyclicAMILduInterface
Description
An abstract base class for cyclic AMI coupled interfaces
SourceFiles
cyclicAMILduInterface.C
\*---------------------------------------------------------------------------*/
#ifndef cyclicAMILduInterface_H
#define cyclicAMILduInterface_H
#include "primitiveFieldsFwd.H"
#include "AMIInterpolation.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cyclicAMILduInterface Declaration
\*---------------------------------------------------------------------------*/
class cyclicAMILduInterface
{
public:
//- Runtime type information
TypeName("cyclicAMILduInterface");
// Constructors
//- Construct null
cyclicAMILduInterface()
{}
//- Destructor
virtual ~cyclicAMILduInterface();
// Member Functions
// Access
//- Return neighbour
virtual label nbrPatchID() const = 0;
//- Does this side own the interface?
virtual bool owner() const = 0;
//- Return processor number
virtual const cyclicAMILduInterface& nbrPatch() const = 0;
//- Return a reference to the AMI interpolators
virtual const PtrList<AMIInterpolation>& AMIs() const = 0;
// Return a reference to the AMI transformations
virtual const List<transformer>&
AMITransforms() const = 0;
//- Return transformation between the coupled patches
virtual const transformer& transform() const = 0;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

Some files were not shown because too many files have changed in this diff Show More