mappedValue: Extended to allow in-patch mapping

It is now possible to map from one field to another within the same
patch, using the mappedValue boundary condition. The restriction is that
the mapping must be from a different field, otherwise field values are
being assigned to themselves, which produces an undefined result.

The mappedValue boundary condition can now be used in place of the
copiedFixedValue condition in the multiphaseEuler module. The
copiedFixedValue condition has therefore been removed.

In addition, the error messages that result from casting a patch to its
mapping engine (mappedPatchBase) have been standardised, and made more
specific to the situation in which the mapping is applied. It may be
inappropriate, for example, to map within the same region or patch.
These cases are now identified and appropriate error messages are
generated.

The error messages have also been made IO errors, so they now provide
context with regards to the dictionary entries that they relate to.
This commit is contained in:
Will Bainbridge
2023-01-05 08:39:46 +00:00
parent 56e87c469f
commit 0a194458f5
22 changed files with 300 additions and 478 deletions

View File

@ -24,7 +24,6 @@ derivedFvPatchFields/alphatPhaseJayatillekeWallFunction/alphatPhaseJayatillekeWa
derivedFvPatchFields/alphatPhaseChangeWallFunction/alphatPhaseChangeWallFunctionFvPatchScalarField.C
derivedFvPatchFields/alphatFixedDmdtfWallBoilingWallFunction/alphatFixedDmdtfWallBoilingWallFunctionFvPatchScalarField.C
derivedFvPatchFields/alphatWallBoilingWallFunction/alphatWallBoilingWallFunctionFvPatchScalarField.C
derivedFvPatchFields/copiedFixedValue/copiedFixedValueFvPatchScalarField.C
derivedFvPatchFields/fixedMultiphaseHeatFlux/fixedMultiphaseHeatFluxFvPatchScalarField.C
derivedFvPatchFields/coupledMultiphaseTemperature/coupledMultiphaseTemperatureFvPatchScalarField.C

View File

@ -1,119 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2015-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 "copiedFixedValueFvPatchScalarField.H"
#include "fvPatchFieldMapper.H"
#include "volFields.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::copiedFixedValueFvPatchScalarField::copiedFixedValueFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF
)
:
fixedValueFvPatchScalarField(p, iF),
sourceFieldName_("default")
{}
Foam::copiedFixedValueFvPatchScalarField::copiedFixedValueFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const dictionary& dict
)
:
fixedValueFvPatchScalarField(p, iF, dict),
sourceFieldName_(dict.lookup("sourceFieldName"))
{}
Foam::copiedFixedValueFvPatchScalarField::copiedFixedValueFvPatchScalarField
(
const copiedFixedValueFvPatchScalarField& ptf,
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedValueFvPatchScalarField(ptf, p, iF, mapper),
sourceFieldName_(ptf.sourceFieldName_)
{}
Foam::copiedFixedValueFvPatchScalarField::copiedFixedValueFvPatchScalarField
(
const copiedFixedValueFvPatchScalarField& awfpsf,
const DimensionedField<scalar, volMesh>& iF
)
:
fixedValueFvPatchScalarField(awfpsf, iF),
sourceFieldName_(awfpsf.sourceFieldName_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::copiedFixedValueFvPatchScalarField::updateCoeffs()
{
if (this->updated())
{
return;
}
operator==
(
patch().lookupPatchField<volScalarField, scalar>(sourceFieldName_)
);
fixedValueFvPatchScalarField::updateCoeffs();
}
void Foam::copiedFixedValueFvPatchScalarField::write(Ostream& os) const
{
fvPatchField<scalar>::write(os);
writeEntry(os, "sourceFieldName", sourceFieldName_);
writeEntry(os, "value", *this);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
makePatchTypeField
(
fvPatchScalarField,
copiedFixedValueFvPatchScalarField
);
}
// ************************************************************************* //

View File

@ -1,145 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2015-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::copiedFixedValueFvPatchScalarField
Description
Copies the boundary values from a user specified field.
See also
Foam::fixedValueFvPatchField
SourceFiles
copiedFixedValueFvPatchScalarField.C
\*---------------------------------------------------------------------------*/
#ifndef copiedFixedValueFvPatchScalarField_H
#define copiedFixedValueFvPatchScalarField_H
#include "fixedValueFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class copiedFixedValueFvPatchScalarField Declaration
\*---------------------------------------------------------------------------*/
class copiedFixedValueFvPatchScalarField
:
public fixedValueFvPatchScalarField
{
protected:
// Protected data
word sourceFieldName_;
public:
//- Runtime type information
TypeName("copiedFixedValue");
// Constructors
//- Construct from patch and internal field
copiedFixedValueFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&
);
//- Construct from patch, internal field and dictionary
copiedFixedValueFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const dictionary&
);
//- Construct by mapping given
// copiedFixedValueFvPatchScalarField
// onto a new patch
copiedFixedValueFvPatchScalarField
(
const copiedFixedValueFvPatchScalarField&,
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const fvPatchFieldMapper&
);
//- Disallow copy without setting internal field reference
copiedFixedValueFvPatchScalarField
(
const copiedFixedValueFvPatchScalarField&
) = delete;
//- Copy constructor setting internal field reference
copiedFixedValueFvPatchScalarField
(
const copiedFixedValueFvPatchScalarField&,
const DimensionedField<scalar, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchScalarField> clone
(
const DimensionedField<scalar, volMesh>& iF
) const
{
return tmp<fvPatchScalarField>
(
new copiedFixedValueFvPatchScalarField(*this, iF)
);
}
// Member Functions
// Evaluation functions
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
// I-O
//- Write
virtual void write(Ostream&) 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-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2020-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -455,7 +455,6 @@ Foam::cyclicTransform::cyclicTransform
);
}
// Calculate the angle
const tensor PerpA = tensor::I - sqr(rotationAxis_);
const vector normalPerpA = normalised(PerpA & normal);
const vector negNbrNormalPerpA = normalised(PerpA & negNbrNormal);
@ -465,6 +464,7 @@ Foam::cyclicTransform::cyclicTransform
- sign((normalPerpA ^ negNbrNormalPerpA) & rotationAxis_)
*radToDeg(theta);
// Calculate the angle
// Calculate the centre of rotation, if necessary
if (transformType_ != oldTransformType)
{

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-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -168,15 +168,12 @@ coupledTemperatureFvPatchScalarField
Qs_(0),
wallKappaByDelta_(0)
{
if (!isA<mappedPatchBase>(this->patch().patch()))
{
FatalErrorInFunction
<< "' not type '" << mappedPatchBase::typeName << "'"
<< "\n for patch " << p.name()
<< " of field " << internalField().name()
<< " in file " << internalField().objectPath()
<< exit(FatalError);
}
mappedPatchBase::validateMapForField
(
*this,
dict,
mappedPatchBase::from::differentPatch
);
if (dict.found("thicknessLayers"))
{
@ -290,8 +287,7 @@ void Foam::coupledTemperatureFvPatchScalarField::updateCoeffs()
UPstream::msgType() = oldTag + 1;
// Get the coupling information from the mappedPatchBase
const mappedPatchBase& mpp =
refCast<const mappedPatchBase>(patch().patch());
const mappedPatchBase& mpp = mappedPatchBase::getMap(patch().patch());
const label patchiNbr = mpp.nbrPolyPatch().index();
const fvPatch& patchNbr =
refCast<const fvMesh>(mpp.nbrMesh()).boundary()[patchiNbr];

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-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -79,15 +79,13 @@ thermalBaffle1DFvPatchScalarField
qrRelaxation_(dict.lookupOrDefault<scalar>("qrRelaxation", 1)),
qrName_(dict.lookupOrDefault<word>("qr", "none"))
{
if (!isA<mappedPatchBase>(this->patch().patch()))
{
FatalErrorInFunction
<< "' not type '" << mappedPatchBase::typeName << "'"
<< "\n for patch " << p.name()
<< " of field " << internalField().name()
<< " in file " << internalField().objectPath()
<< exit(FatalError);
}
mappedPatchBase::validateMapForField
(
*this,
dict,
mappedPatchBase::from::sameRegion
& mappedPatchBase::from::differentPatch
);
fvPatchScalarField::operator=(scalarField("value", dict, p.size()));
@ -176,17 +174,7 @@ thermalBaffle1DFvPatchScalarField
template<class solidType>
bool thermalBaffle1DFvPatchScalarField<solidType>::owner() const
{
const mappedPatchBase& mpp =
refCast<const mappedPatchBase>(patch().patch());
if (!mpp.sameRegion())
{
FatalErrorInFunction
<< "A" << typeName
<< " must map to a patch field in the same region"
<< exit(FatalError);
}
const mappedPatchBase& mpp = mappedPatchBase::getMap(patch().patch());
return patch().patch().index() < mpp.nbrPolyPatch().index();
}
@ -195,8 +183,7 @@ template<class solidType>
const thermalBaffle1DFvPatchScalarField<solidType>&
thermalBaffle1DFvPatchScalarField<solidType>::nbrField() const
{
const mappedPatchBase& mpp =
refCast<const mappedPatchBase>(patch().patch());
const mappedPatchBase& mpp = mappedPatchBase::getMap(patch().patch());
const polyMesh& nbrMesh = mpp.nbrMesh();
const label nbrPatchi = mpp.nbrPolyPatch().index();
const fvPatch& nbrPatch =
@ -250,8 +237,7 @@ baffleThickness() const
}
else
{
const mappedPatchBase& mpp =
refCast<const mappedPatchBase>(patch().patch());
const mappedPatchBase& mpp = mappedPatchBase::getMap(patch().patch());
return mpp.distribute(nbrField().baffleThickness());
}
}
@ -266,8 +252,7 @@ tmp<scalarField> thermalBaffle1DFvPatchScalarField<solidType>::qs() const
}
else
{
const mappedPatchBase& mpp =
refCast<const mappedPatchBase>(patch().patch());
const mappedPatchBase& mpp = mappedPatchBase::getMap(patch().patch());
return mpp.distribute(nbrField().qs());
}
}
@ -341,8 +326,7 @@ void thermalBaffle1DFvPatchScalarField<solidType>::updateCoeffs()
int oldTag = UPstream::msgType();
UPstream::msgType() = oldTag + 1;
const mappedPatchBase& mpp =
refCast<const mappedPatchBase>(patch().patch());
const mappedPatchBase& mpp = mappedPatchBase::getMap(patch().patch());
if (baffleActivated_)
{

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-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -58,7 +58,14 @@ mappedFlowRateVelocityFvPatchVectorField
nbrPhiName_(dict.lookupOrDefault<word>("nbrPhi", "phi")),
phiName_(dict.lookupOrDefault<word>("phi", "phi")),
rhoName_(dict.lookupOrDefault<word>("rho", "rho"))
{}
{
mappedPatchBase::validateMapForField
(
*this,
dict,
mappedPatchBase::from::differentPatch
);
}
Foam::mappedFlowRateVelocityFvPatchVectorField::
@ -105,8 +112,7 @@ void Foam::mappedFlowRateVelocityFvPatchVectorField::updateCoeffs()
int oldTag = UPstream::msgType();
UPstream::msgType() = oldTag+1;
const mappedPatchBase& mapper =
refCast<const mappedPatchBase>(patch().patch());
const mappedPatchBase& mapper = mappedPatchBase::getMap(patch().patch());
const fvMesh& nbrMesh = refCast<const fvMesh>(mapper.nbrMesh());
const label nbrPatchi = mapper.nbrPolyPatch().index();
const fvPatch& nbrPatch = nbrMesh.boundary()[nbrPatchi];

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-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -24,6 +24,7 @@ License
\*---------------------------------------------------------------------------*/
#include "mappedValueFvPatchField.H"
#include "mappedPolyPatch.H"
#include "volFields.H"
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
@ -32,25 +33,10 @@ template<class Type>
const Foam::mappedPatchBase&
Foam::mappedValueFvPatchField<Type>::mapper() const
{
if (mapperPtr_.valid())
{
return mapperPtr_();
}
if (isA<mappedPatchBase>(this->patch().patch()))
{
return refCast<const mappedPatchBase>(this->patch().patch());
}
FatalErrorInFunction
<< "Field " << this->internalField().name() << " on patch "
<< this->patch().name() << " in file "
<< this->internalField().objectPath()
<< " has neither a mapper specified nor is the patch of "
<< mappedPatchBase::typeName << " type"
<< exit(FatalError);
return NullObjectRef<mappedPatchBase>();
return
mapperPtr_.valid()
? mapperPtr_()
: mappedPatchBase::getMap(this->patch().patch());
}
@ -150,7 +136,30 @@ Foam::mappedValueFvPatchField<Type>::mappedValueFvPatchField
? new mappedPatchBase(p.patch(), dict, false)
: nullptr
)
{}
{
if (!mapperPtr_.valid() && !isA<mappedPatchBase>(p.patch()))
{
OStringStream str;
str << "Field " << this->internalField().name() << " of type "
<< type() << " on patch " << this->patch().name() << " does not "
<< "have mapping specified (i.e., neighbourPatch, and/or "
<< "neighbourRegion entries) nor is the patch of "
<< mappedPolyPatch::typeName << " type";
FatalIOErrorInFunction(dict)
<< stringOps::breakIntoIndentedLines(str.str()).c_str()
<< exit(FatalIOError);
}
this->mapper().validateForField
(
*this,
dict,
this->mapper().sameUntransformedPatch()
&& this->fieldName_ == this->internalField().name()
? mappedPatchBase::from::differentPatch
: mappedPatchBase::from::any
);
}
template<class Type>

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-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -53,16 +53,12 @@ Foam::mappedVelocityFluxFvPatchField::mappedVelocityFluxFvPatchField
fixedValueFvPatchVectorField(p, iF, dict),
phiName_(dict.lookupOrDefault<word>("phi", "phi"))
{
if (!isA<mappedPatchBase>(this->patch().patch()))
{
FatalErrorInFunction
<< "Patch type '" << p.type()
<< "' not type '" << mappedPatchBase::typeName << "'"
<< " for patch " << p.name()
<< " of field " << internalField().name()
<< " in file " << internalField().objectPath()
<< exit(FatalError);
}
mappedPatchBase::validateMapForField
(
*this,
dict,
mappedPatchBase::from::differentPatch
);
}
@ -76,18 +72,7 @@ Foam::mappedVelocityFluxFvPatchField::mappedVelocityFluxFvPatchField
:
fixedValueFvPatchVectorField(ptf, p, iF, mapper),
phiName_(ptf.phiName_)
{
if (!isA<mappedPatchBase>(this->patch().patch()))
{
FatalErrorInFunction
<< "Patch type '" << p.type()
<< "' not type '" << mappedPatchBase::typeName << "'"
<< " for patch " << p.name()
<< " of field " << internalField().name()
<< " in file " << internalField().objectPath()
<< exit(FatalError);
}
}
{}
Foam::mappedVelocityFluxFvPatchField::mappedVelocityFluxFvPatchField
@ -115,8 +100,7 @@ void Foam::mappedVelocityFluxFvPatchField::updateCoeffs()
int oldTag = UPstream::msgType();
UPstream::msgType() = oldTag+1;
const mappedPatchBase& mapper =
refCast<const mappedPatchBase>(patch().patch());
const mappedPatchBase& mapper = mappedPatchBase::getMap(patch().patch());
const fvMesh& nbrMesh = refCast<const fvMesh>(mapper.nbrMesh());
const label nbrPatchi = mapper.nbrPolyPatch().index();

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-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -81,6 +81,7 @@ class mappedVelocityFluxFvPatchField
//- Name of flux field
word phiName_;
public:
//- Runtime type information

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-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -72,6 +72,14 @@ void Foam::mappedPatchBase::calcMapping() const
<< "Mapping already calculated" << exit(FatalError);
}
if (sameUntransformedPatch())
{
FatalErrorInFunction
<< "Patch " << patch_.name() << " is mapping itself with no "
<< "transform. Mapping data does not need to be constructed."
<< exit(FatalError);
}
// Calculate the transform as necessary
transform_ =
cyclicTransform
@ -90,22 +98,6 @@ void Foam::mappedPatchBase::calcMapping() const
true
);
// Do a sanity check. Am I sampling my own patch? This only makes sense if
// the position is transformed.
if
(
nbrRegionName() == patch_.boundaryMesh().mesh().name()
&& nbrPatchName() == patch_.name()
&& !transform_.transform().transformsPosition()
)
{
FatalErrorInFunction
<< "Patch " << patch_.name() << " is sampling itself with no "
<< "transform. The patch face values are undefined."
<< exit(FatalError);
}
// Build the mapping...
//
// This octree based solution is deprecated. The "matching" patch-to-patch
@ -313,15 +305,12 @@ void Foam::mappedPatchBase::calcMapping() const
// * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * * * //
Foam::mappedPatchBase::mappedPatchBase
(
const polyPatch& pp
)
Foam::mappedPatchBase::mappedPatchBase(const polyPatch& pp)
:
patch_(pp),
nbrRegionName_(patch_.boundaryMesh().mesh().name()),
nbrPatchName_(word::null),
coupleGroup_(),
nbrRegionName_(patch_.boundaryMesh().mesh().name()),
nbrPatchName_(patch_.name()),
transform_(true),
mapPtr_(nullptr),
nbrPatchFaceIndices_(),
@ -341,9 +330,9 @@ Foam::mappedPatchBase::mappedPatchBase
)
:
patch_(pp),
coupleGroup_(),
nbrRegionName_(nbrRegionName),
nbrPatchName_(nbrPatchName),
coupleGroup_(),
transform_(transform),
mapPtr_(nullptr),
nbrPatchFaceIndices_(),
@ -362,23 +351,25 @@ Foam::mappedPatchBase::mappedPatchBase
)
:
patch_(pp),
coupleGroup_(dict),
nbrRegionName_
(
dict.lookupOrDefaultBackwardsCompatible<word>
(
{"neighbourRegion", "sampleRegion"},
word::null
coupleGroup_.valid() ? word::null : pp.boundaryMesh().mesh().name()
)
),
nbrPatchName_
(
dict.lookupOrDefaultBackwardsCompatible<word>
coupleGroup_.valid()
? dict.lookupOrDefaultBackwardsCompatible<word>
(
{"neighbourPatch", "samplePatch"},
word::null
)
: dict.lookupBackwardsCompatible<word>({"neighbourPatch", "samplePatch"})
),
coupleGroup_(dict),
transform_
(
transformIsNone
@ -401,9 +392,15 @@ Foam::mappedPatchBase::mappedPatchBase
),
matchTol_(dict.lookupOrDefault("matchTolerance", defaultMatchTol_))
{
if (!coupleGroup_.valid() && nbrRegionName_.empty())
if
(
coupleGroup_.valid()
&& (nbrRegionName_ != word::null || nbrPatchName_ != word::null)
)
{
nbrRegionName_ = patch_.boundaryMesh().mesh().name();
FatalIOErrorInFunction(dict)
<< "Either a coupleGroup or a neighbourRegion/Patch should be "
<< "specified, not both" << exit(FatalIOError);
}
}
@ -415,9 +412,9 @@ Foam::mappedPatchBase::mappedPatchBase
)
:
patch_(pp),
coupleGroup_(mpb.coupleGroup_),
nbrRegionName_(mpb.nbrRegionName_),
nbrPatchName_(mpb.nbrPatchName_),
coupleGroup_(mpb.coupleGroup_),
transform_(mpb.transform_),
mapPtr_(nullptr),
nbrPatchFaceIndices_(),
@ -469,6 +466,22 @@ const Foam::polyPatch& Foam::mappedPatchBase::nbrPolyPatch() const
}
const Foam::mappedPatchBase& Foam::mappedPatchBase::getMap
(
const polyPatch& patch
)
{
if (!isA<mappedPatchBase>(patch))
{
FatalErrorInFunction
<< "Patch " << patch.name() << " is not of type "
<< typeName << exit(FatalError);
}
return refCast<const mappedPatchBase>(patch);
}
void Foam::mappedPatchBase::clearOut()
{
mapPtr_.clear();
@ -481,7 +494,9 @@ bool Foam::mappedPatchBase::specified(const dictionary& dict)
{
return
dict.found("neighbourRegion")
|| dict.found("sampleRegion")
|| dict.found("neighbourPatch")
|| dict.found("samplePatch")
|| dict.found("coupleGroup");
}

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-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -77,15 +77,15 @@ protected:
//- Patch to map to
const polyPatch& patch_;
//- Couple group for the region/patch to map from
const coupleGroupIdentifier coupleGroup_;
//- Name of the region to map from
mutable word nbrRegionName_;
//- Name of the patch to map from
mutable word nbrPatchName_;
//- Couple group for the region/patch to map from
const coupleGroupIdentifier coupleGroup_;
//- The transformation between the patches
mutable cyclicTransform transform_;
@ -184,6 +184,12 @@ public:
//- Is the neighbour region the same as for this patch?
inline bool sameRegion() const;
//- Is the neighbour patch the same as this patch?
inline bool samePatch() const;
//- Is the neighbour patch the same as this patch with no transform?
inline bool sameUntransformedPatch() const;
//- Name of the patch to map from
inline const word& nbrPatchName() const;
@ -194,6 +200,41 @@ public:
const polyPatch& nbrPolyPatch() const;
// Casting
//- Cast the given polyPatch to a mappedPatchBase. Handle errors.
static const mappedPatchBase& getMap(const polyPatch& patch);
//- Restrict use of the mapper to certain configurations
struct from
{
static const label any = 0;
static const label sameRegion = 1;
static const label differentRegion = 2;
static const label differentPatch = 4;
};
//- Validate that the map exists and is appropriate for the given
// set of permitted configurations
template<class PatchField>
static void validateMapForField
(
const PatchField& field,
const dictionary& context,
const label froms = from::any
);
//- Validate that the map is appropriate for the given
// set of permitted configurations
template<class PatchField>
void validateForField
(
const PatchField& field,
const dictionary& context,
const label froms = from::any
) const;
// Edit
//- Clear out data on mesh change

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-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -56,18 +56,10 @@ inline bool Foam::mappedPatchBase::symmetric() const
inline const Foam::word& Foam::mappedPatchBase::nbrRegionName() const
{
if (nbrRegionName_.empty())
if (coupleGroup_.valid() && nbrRegionName_.empty())
{
if (!coupleGroup_.valid())
{
FatalErrorInFunction
<< "Supply either a regionName or a coupleGroup"
<< " for patch " << patch_.name()
<< " in region " << patch_.boundaryMesh().mesh().name()
<< exit(FatalError);
}
// Try and use patchGroup to find nbrPatch and nbrRegion
// Try and use the couple group to find nbrPatch and nbrRegion. Note:
// This call sets nbrRegionName_.
const label nbrPatchID =
coupleGroup_.findOtherPatchID(patch_, nbrRegionName_);
@ -95,4 +87,21 @@ inline bool Foam::mappedPatchBase::sameRegion() const
}
inline bool Foam::mappedPatchBase::samePatch() const
{
return sameRegion() && nbrPatchName() == patch_.name();
}
inline bool Foam::mappedPatchBase::sameUntransformedPatch() const
{
return
samePatch()
&& (
!transform_.transformComplete()
|| !transform_.transform().transformsPosition()
);
}
// ************************************************************************* //

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-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -24,13 +24,87 @@ License
\*---------------------------------------------------------------------------*/
#include "mappedPatchBase.H"
#include "stringOps.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class PatchField>
void Foam::mappedPatchBase::validateMapForField
(
const PatchField& field,
const dictionary& context,
const label froms
)
{
const polyPatch& pp = field.patch().patch();
if (!isA<mappedPatchBase>(pp))
{
OStringStream str;
str << "Field " << field.internalField().name() << " of type "
<< field.type() << " cannot apply to patch " << pp.name()
<< " because the patch is not of " << typeName << " type";
FatalIOErrorInFunction(context)
<< stringOps::breakIntoIndentedLines(str.str()).c_str()
<< exit(FatalIOError);
}
refCast<const mappedPatchBase>(pp).validateForField(field, context, froms);
}
template<class PatchField>
void Foam::mappedPatchBase::validateForField
(
const PatchField& field,
const dictionary& context,
const label froms
) const
{
const bool isNotRegion = !sameRegion() && (froms & from::sameRegion);
const bool isRegion = sameRegion() && (froms & from::differentRegion);
const bool isPatch = samePatch() && (froms & from::differentPatch);
OStringStream str;
if (isNotRegion || isRegion || isPatch)
{
str << "Field " << field.internalField().name() << " of type "
<< field.type() << " cannot apply to patch " << patch_.name()
<< " because values are mapped from ";
}
if (isNotRegion)
{
str << "a different region";
}
else if (isRegion)
{
str << "within the same region";
}
else if (isPatch)
{
str << "the same patch";
}
if (isNotRegion || isRegion || isPatch)
{
FatalIOErrorInFunction(context)
<< stringOps::breakIntoIndentedLines(str.str()).c_str()
<< exit(FatalIOError);
}
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::mappedPatchBase::distribute(const Field<Type>& fld) const
{
if (sameUntransformedPatch())
{
return fld;
}
if (!patchToPatchIsUsed_)
{
if (mapPtr_.empty())
@ -83,6 +157,11 @@ template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::mappedPatchBase::reverseDistribute(const Field<Type>& fld) const
{
if (sameUntransformedPatch())
{
return fld;
}
if (!patchToPatchIsUsed_)
{
if (mapPtr_.empty())

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-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -98,38 +98,15 @@ Foam::radiationCoupledBase::radiationCoupledBase
{
case SOLIDRADIATION:
{
if (!isA<mappedPatchBase>(patch_.patch()))
{
FatalIOErrorInFunction
(
dict
) << "\n patch type '" << patch_.type()
<< "' not type '" << mappedPatchBase::typeName << "'"
<< "\n for patch " << patch_.name()
<< exit(FatalIOError);
}
emissivity_ = scalarField(patch_.size(), 0.0);
emissivity_ = scalarField(patch_.size(), scalar(0));
break;
}
break;
case LOOKUP:
{
if (!dict.found("emissivity"))
{
FatalIOErrorInFunction
(
dict
) << "\n emissivity key does not exist for patch "
<< patch_.name()
<< exit(FatalIOError);
}
else
{
emissivity_ = scalarField("emissivity", dict, patch_.size());
}
emissivity_ = scalarField("emissivity", dict, patch_.size());
break;
}
break;
}
}
@ -150,7 +127,7 @@ Foam::tmp<Foam::scalarField> Foam::radiationCoupledBase::emissivity() const
{
// Get the coupling information from the mappedPatchBase
const mappedPatchBase& mpp =
refCast<const mappedPatchBase>(patch_.patch());
mappedPatchBase::getMap(patch_.patch());
const polyMesh& nbrMesh = mpp.nbrMesh();

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2017-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2017-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -55,15 +55,12 @@ semiPermeableBaffleMassFractionFvPatchScalarField
:
specieTransferMassFractionFvPatchScalarField(p, iF, dict)
{
if (!isA<mappedPatchBase>(patch().patch()))
{
FatalErrorInFunction
<< "' not type '" << mappedPatchBase::typeName << "'"
<< "\n for patch " << p.name()
<< " of field " << internalField().name()
<< " in file " << internalField().objectPath()
<< exit(FatalError);
}
mappedPatchBase::validateMapForField
(
*this,
dict,
mappedPatchBase::from::differentPatch
);
}
@ -104,8 +101,7 @@ Foam::semiPermeableBaffleMassFractionFvPatchScalarField::calcPhiYp() const
const word& YName = internalField().name();
// Get the coupling information from the mappedPatchBase
const mappedPatchBase& mpp =
refCast<const mappedPatchBase>(patch().patch());
const mappedPatchBase& mpp = mappedPatchBase::getMap(patch().patch());
const polyMesh& nbrMesh = mpp.nbrMesh();
const label nbrPatchi = mpp.nbrPolyPatch().index();
const fvPatch& nbrPatch =

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-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -37,7 +37,6 @@ namespace Foam
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
bool Foam::surfaceFilm::read()
{
if (regIOobject::read())
@ -69,10 +68,9 @@ Foam::label Foam::surfaceFilm::nbrCoupledPatchID
// region
const fvMesh& nbrRegionMesh = nbrRegion.mesh();
// boundary mesh
const polyBoundaryMesh& nbrPbm = nbrRegionMesh.boundaryMesh();
// boundary meshes
const polyBoundaryMesh& pbm = mesh().boundaryMesh();
const polyBoundaryMesh& nbrPbm = nbrRegionMesh.boundaryMesh();
if (regionPatchi > pbm.size() - 1)
{
@ -83,16 +81,8 @@ Foam::label Foam::surfaceFilm::nbrCoupledPatchID
<< abort(FatalError);
}
const polyPatch& pp = mesh().boundaryMesh()[regionPatchi];
if (!isA<mappedPatchBase>(pp))
{
FatalErrorInFunction
<< "Expected a " << mappedPatchBase::typeName
<< " patch, but found a " << pp.type() << abort(FatalError);
}
const mappedPatchBase& mpb = refCast<const mappedPatchBase>(pp);
const mappedPatchBase& mpb =
mappedPatchBase::getMap(pbm[regionPatchi]);
// sample patch name on the primary region
const word& primaryPatchName = mpb.nbrPatchName();
@ -103,7 +93,7 @@ Foam::label Foam::surfaceFilm::nbrCoupledPatchID
const label nbrRegionPatchi = nbrRegion.intCoupledPatchIDs()[j];
const mappedPatchBase& mpb =
refCast<const mappedPatchBase>(nbrPbm[nbrRegionPatchi]);
mappedPatchBase::getMap(nbrPbm[nbrRegionPatchi]);
if (mpb.nbrPatchName() == primaryPatchName)
{
@ -215,10 +205,6 @@ Foam::surfaceFilm::surfaceFilm
if (isA<mappedPatchBase>(regionPatch))
{
DebugInFunction
<< "found " << mappedWallPolyPatch::typeName
<< " " << regionPatch.name() << endl;
intCoupledPatchIDs.append(patchi);
nBoundaryFaces += regionPatch.faceCells().size();
@ -234,7 +220,6 @@ Foam::surfaceFilm::surfaceFilm
)
)
{
const label primaryPatchi = mapPatch.nbrPolyPatch().index();
primaryPatchIDs.append(primaryPatchi);
}

View File

@ -34,8 +34,9 @@ boundaryField
}
walls
{
type copiedFixedValue;
sourceFieldName T.liquid;
type mappedValue;
neighbourPatch walls;
field T.liquid;
value $internalField;
}
front

View File

@ -34,8 +34,9 @@ boundaryField
}
wall
{
type copiedFixedValue;
sourceFieldName T.liquid;
type mappedValue;
neighbourPatch wall;
field T.liquid;
value $internalField;
}
front

View File

@ -34,8 +34,9 @@ boundaryField
}
wall
{
type copiedFixedValue;
sourceFieldName T.liquid;
type mappedValue;
neighbourPatch wall;
field T.liquid;
value $internalField;
}
front

View File

@ -34,8 +34,9 @@ boundaryField
}
wall
{
type copiedFixedValue;
sourceFieldName T.liquid;
type mappedValue;
neighbourPatch wall;
field T.liquid;
value $internalField;
}
front

View File

@ -34,8 +34,9 @@ boundaryField
}
wall
{
type copiedFixedValue;
sourceFieldName T.liquid;
type mappedValue;
neighbourPatch wall;
field T.liquid;
value $internalField;
}
front