mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: directMapped: allow offset specification; allow fieldName specification; allow non-constant interpolation
This commit is contained in:
@ -26,6 +26,7 @@ License
|
|||||||
#include "directMappedFixedValueFvPatchField.H"
|
#include "directMappedFixedValueFvPatchField.H"
|
||||||
#include "directMappedPatchBase.H"
|
#include "directMappedPatchBase.H"
|
||||||
#include "volFields.H"
|
#include "volFields.H"
|
||||||
|
#include "interpolationCell.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -42,8 +43,10 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
|
|||||||
)
|
)
|
||||||
:
|
:
|
||||||
fixedValueFvPatchField<Type>(p, iF),
|
fixedValueFvPatchField<Type>(p, iF),
|
||||||
|
fieldName_(iF.name()),
|
||||||
setAverage_(false),
|
setAverage_(false),
|
||||||
average_(pTraits<Type>::zero)
|
average_(pTraits<Type>::zero),
|
||||||
|
interpolationScheme_(interpolationCell<Type>::typeName)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -57,8 +60,10 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
|
|||||||
)
|
)
|
||||||
:
|
:
|
||||||
fixedValueFvPatchField<Type>(ptf, p, iF, mapper),
|
fixedValueFvPatchField<Type>(ptf, p, iF, mapper),
|
||||||
|
fieldName_(ptf.fieldName_),
|
||||||
setAverage_(ptf.setAverage_),
|
setAverage_(ptf.setAverage_),
|
||||||
average_(ptf.average_)
|
average_(ptf.average_),
|
||||||
|
interpolationScheme_(ptf.interpolationScheme_)
|
||||||
{
|
{
|
||||||
if (!isA<directMappedPatchBase>(this->patch().patch()))
|
if (!isA<directMappedPatchBase>(this->patch().patch()))
|
||||||
{
|
{
|
||||||
@ -91,8 +96,10 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
|
|||||||
)
|
)
|
||||||
:
|
:
|
||||||
fixedValueFvPatchField<Type>(p, iF, dict),
|
fixedValueFvPatchField<Type>(p, iF, dict),
|
||||||
|
fieldName_(dict.lookupOrDefault<word>("fieldName", iF.name())),
|
||||||
setAverage_(readBool(dict.lookup("setAverage"))),
|
setAverage_(readBool(dict.lookup("setAverage"))),
|
||||||
average_(pTraits<Type>(dict.lookup("average")))
|
average_(pTraits<Type>(dict.lookup("average"))),
|
||||||
|
interpolationScheme_(interpolationCell<Type>::typeName)
|
||||||
{
|
{
|
||||||
if (!isA<directMappedPatchBase>(this->patch().patch()))
|
if (!isA<directMappedPatchBase>(this->patch().patch()))
|
||||||
{
|
{
|
||||||
@ -112,6 +119,15 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
|
|||||||
<< " in file " << this->dimensionedInternalField().objectPath()
|
<< " in file " << this->dimensionedInternalField().objectPath()
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const directMappedPatchBase& mpp = refCast<const directMappedPatchBase>
|
||||||
|
(
|
||||||
|
directMappedFixedValueFvPatchField<Type>::patch().patch()
|
||||||
|
);
|
||||||
|
if (mpp.mode() == directMappedPatchBase::NEARESTCELL)
|
||||||
|
{
|
||||||
|
dict.lookup("interpolationScheme") >> interpolationScheme_;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -122,8 +138,10 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
|
|||||||
)
|
)
|
||||||
:
|
:
|
||||||
fixedValueFvPatchField<Type>(ptf),
|
fixedValueFvPatchField<Type>(ptf),
|
||||||
|
fieldName_(ptf.fieldName_),
|
||||||
setAverage_(ptf.setAverage_),
|
setAverage_(ptf.setAverage_),
|
||||||
average_(ptf.average_)
|
average_(ptf.average_),
|
||||||
|
interpolationScheme_(ptf.interpolationScheme_)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -135,13 +153,67 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
|
|||||||
)
|
)
|
||||||
:
|
:
|
||||||
fixedValueFvPatchField<Type>(ptf, iF),
|
fixedValueFvPatchField<Type>(ptf, iF),
|
||||||
|
fieldName_(ptf.fieldName_),
|
||||||
setAverage_(ptf.setAverage_),
|
setAverage_(ptf.setAverage_),
|
||||||
average_(ptf.average_)
|
average_(ptf.average_),
|
||||||
|
interpolationScheme_(ptf.interpolationScheme_)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>&
|
||||||
|
directMappedFixedValueFvPatchField<Type>::sampleField() const
|
||||||
|
{
|
||||||
|
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
|
||||||
|
|
||||||
|
const directMappedPatchBase& mpp = refCast<const directMappedPatchBase>
|
||||||
|
(
|
||||||
|
directMappedFixedValueFvPatchField<Type>::patch().patch()
|
||||||
|
);
|
||||||
|
const fvMesh& nbrMesh = refCast<const fvMesh>(mpp.sampleMesh());
|
||||||
|
|
||||||
|
if (mpp.sameRegion())
|
||||||
|
{
|
||||||
|
if (fieldName_ == this->dimensionedInternalField().name())
|
||||||
|
{
|
||||||
|
// Optimisation: bypass field lookup
|
||||||
|
return
|
||||||
|
dynamic_cast<const fieldType&>
|
||||||
|
(
|
||||||
|
this->dimensionedInternalField()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const fvMesh& thisMesh = this->patch().boundaryMesh().mesh();
|
||||||
|
return thisMesh.lookupObject<fieldType>(fieldName_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return nbrMesh.lookupObject<fieldType>(fieldName_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
const interpolation<Type>&
|
||||||
|
directMappedFixedValueFvPatchField<Type>::interpolator() const
|
||||||
|
{
|
||||||
|
if (!interpolator_.valid())
|
||||||
|
{
|
||||||
|
interpolator_ = interpolation<Type>::New
|
||||||
|
(
|
||||||
|
interpolationScheme_,
|
||||||
|
sampleField()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return interpolator_();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void directMappedFixedValueFvPatchField<Type>::updateCoeffs()
|
void directMappedFixedValueFvPatchField<Type>::updateCoeffs()
|
||||||
{
|
{
|
||||||
@ -159,11 +231,8 @@ void directMappedFixedValueFvPatchField<Type>::updateCoeffs()
|
|||||||
);
|
);
|
||||||
const mapDistribute& distMap = mpp.map();
|
const mapDistribute& distMap = mpp.map();
|
||||||
|
|
||||||
// Force recalculation of schedule
|
const fvMesh& thisMesh = this->patch().boundaryMesh().mesh();
|
||||||
(void)distMap.schedule();
|
|
||||||
|
|
||||||
const fvMesh& nbrMesh = refCast<const fvMesh>(mpp.sampleMesh());
|
const fvMesh& nbrMesh = refCast<const fvMesh>(mpp.sampleMesh());
|
||||||
const word& fldName = this->dimensionedInternalField().name();
|
|
||||||
|
|
||||||
// Result of obtaining remote values
|
// Result of obtaining remote values
|
||||||
Field<Type> newValues;
|
Field<Type> newValues;
|
||||||
@ -172,17 +241,37 @@ void directMappedFixedValueFvPatchField<Type>::updateCoeffs()
|
|||||||
{
|
{
|
||||||
case directMappedPatchBase::NEARESTCELL:
|
case directMappedPatchBase::NEARESTCELL:
|
||||||
{
|
{
|
||||||
if (mpp.sameRegion())
|
if (interpolationScheme_ != interpolationCell<Type>::typeName)
|
||||||
{
|
{
|
||||||
newValues = this->internalField();
|
// Send back sample points to the processor that holds the cell
|
||||||
|
vectorField samples(mpp.samplePoints());
|
||||||
|
distMap.reverseDistribute
|
||||||
|
(
|
||||||
|
(mpp.sameRegion() ? thisMesh.nCells() : nbrMesh.nCells()),
|
||||||
|
point::max,
|
||||||
|
samples
|
||||||
|
);
|
||||||
|
|
||||||
|
const interpolation<Type>& interp = interpolator();
|
||||||
|
|
||||||
|
newValues.setSize(samples.size(), pTraits<Type>::max);
|
||||||
|
forAll(samples, cellI)
|
||||||
|
{
|
||||||
|
if (samples[cellI] != point::max)
|
||||||
|
{
|
||||||
|
newValues[cellI] = interp.interpolate
|
||||||
|
(
|
||||||
|
samples[cellI],
|
||||||
|
cellI
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
newValues = nbrMesh.lookupObject<fieldType>
|
newValues = sampleField();
|
||||||
(
|
|
||||||
fldName
|
|
||||||
).internalField();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mapDistribute::distribute
|
mapDistribute::distribute
|
||||||
(
|
(
|
||||||
Pstream::defaultCommsType,
|
Pstream::defaultCommsType,
|
||||||
@ -213,10 +302,8 @@ void directMappedFixedValueFvPatchField<Type>::updateCoeffs()
|
|||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
const fieldType& nbrField = nbrMesh.lookupObject<fieldType>
|
const fieldType& nbrField = sampleField();
|
||||||
(
|
|
||||||
fldName
|
|
||||||
);
|
|
||||||
newValues = nbrField.boundaryField()[nbrPatchID];
|
newValues = nbrField.boundaryField()[nbrPatchID];
|
||||||
mapDistribute::distribute
|
mapDistribute::distribute
|
||||||
(
|
(
|
||||||
@ -234,10 +321,8 @@ void directMappedFixedValueFvPatchField<Type>::updateCoeffs()
|
|||||||
{
|
{
|
||||||
Field<Type> allValues(nbrMesh.nFaces(), pTraits<Type>::zero);
|
Field<Type> allValues(nbrMesh.nFaces(), pTraits<Type>::zero);
|
||||||
|
|
||||||
const fieldType& nbrField = nbrMesh.lookupObject<fieldType>
|
const fieldType& nbrField = sampleField();
|
||||||
(
|
|
||||||
fldName
|
|
||||||
);
|
|
||||||
forAll(nbrField.boundaryField(), patchI)
|
forAll(nbrField.boundaryField(), patchI)
|
||||||
{
|
{
|
||||||
const fvPatchField<Type>& pf =
|
const fvPatchField<Type>& pf =
|
||||||
@ -294,7 +379,8 @@ void directMappedFixedValueFvPatchField<Type>::updateCoeffs()
|
|||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Info<< "directMapped on field:" << fldName
|
Info<< "directMapped on field:"
|
||||||
|
<< this->dimensionedInternalField().name()
|
||||||
<< " patch:" << this->patch().name()
|
<< " patch:" << this->patch().name()
|
||||||
<< " avg:" << gAverage(*this)
|
<< " avg:" << gAverage(*this)
|
||||||
<< " min:" << gMin(*this)
|
<< " min:" << gMin(*this)
|
||||||
@ -310,8 +396,11 @@ template<class Type>
|
|||||||
void directMappedFixedValueFvPatchField<Type>::write(Ostream& os) const
|
void directMappedFixedValueFvPatchField<Type>::write(Ostream& os) const
|
||||||
{
|
{
|
||||||
fvPatchField<Type>::write(os);
|
fvPatchField<Type>::write(os);
|
||||||
|
os.writeKeyword("fieldName") << fieldName_ << token::END_STATEMENT << nl;
|
||||||
os.writeKeyword("setAverage") << setAverage_ << token::END_STATEMENT << nl;
|
os.writeKeyword("setAverage") << setAverage_ << token::END_STATEMENT << nl;
|
||||||
os.writeKeyword("average") << average_ << token::END_STATEMENT << nl;
|
os.writeKeyword("average") << average_ << token::END_STATEMENT << nl;
|
||||||
|
os.writeKeyword("interpolationScheme") << interpolationScheme_
|
||||||
|
<< token::END_STATEMENT << nl;
|
||||||
this->writeEntry("value", os);
|
this->writeEntry("value", os);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -33,6 +33,17 @@ Description
|
|||||||
mode = NEARESTFACE : sample nearest face on any patch. Note: does not
|
mode = NEARESTFACE : sample nearest face on any patch. Note: does not
|
||||||
warn if nearest actually is on internal face!
|
warn if nearest actually is on internal face!
|
||||||
|
|
||||||
|
For NEARESTCELL you have to provide an 'interpolationScheme' entry
|
||||||
|
which can be any one of the interpolation schemes (cell, cellPoint, etc.)
|
||||||
|
In case of interpolation (so scheme != cell) the limitation is that
|
||||||
|
there is only one value per cell. So e.g. if you have a cell with two
|
||||||
|
boundary faces and both faces sample into the cell both faces will get
|
||||||
|
the same value.
|
||||||
|
|
||||||
|
See directMappedPatchBase for options on sampling.
|
||||||
|
|
||||||
|
Optional 'fieldName' entry to supply a different filename
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
directMappedFixedValueFvPatchField.C
|
directMappedFixedValueFvPatchField.C
|
||||||
|
|
||||||
@ -43,6 +54,7 @@ SourceFiles
|
|||||||
|
|
||||||
#include "fixedValueFvPatchFields.H"
|
#include "fixedValueFvPatchFields.H"
|
||||||
#include "directMappedFvPatch.H"
|
#include "directMappedFvPatch.H"
|
||||||
|
#include "interpolation.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -60,12 +72,29 @@ class directMappedFixedValueFvPatchField
|
|||||||
{
|
{
|
||||||
// Private data
|
// Private data
|
||||||
|
|
||||||
|
//- Name of field to sample - defaults to field associated with this
|
||||||
|
// patchField if not specified
|
||||||
|
word fieldName_;
|
||||||
|
|
||||||
//- If true adjust the mapped field to maintain average value average_
|
//- If true adjust the mapped field to maintain average value average_
|
||||||
bool setAverage_;
|
const bool setAverage_;
|
||||||
|
|
||||||
//- Average value the mapped field is adjusted to maintain if
|
//- Average value the mapped field is adjusted to maintain if
|
||||||
// setAverage_ is set true
|
// setAverage_ is set true
|
||||||
Type average_;
|
const Type average_;
|
||||||
|
|
||||||
|
//- Interpolation scheme to use for nearestcell mode
|
||||||
|
word interpolationScheme_;
|
||||||
|
|
||||||
|
mutable autoPtr<interpolation<Type> > interpolator_;
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Field to sample. Either on my or nbr mesh
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& sampleField() const;
|
||||||
|
|
||||||
|
//- Access the interpolation method
|
||||||
|
const interpolation<Type>& interpolator() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|||||||
@ -112,6 +112,29 @@ directMappedVelocityFluxFixedValueFvPatchField
|
|||||||
<< " in file " << dimensionedInternalField().objectPath()
|
<< " in file " << dimensionedInternalField().objectPath()
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const directMappedPatchBase& mpp = refCast<const directMappedPatchBase>
|
||||||
|
(
|
||||||
|
this->patch().patch()
|
||||||
|
);
|
||||||
|
if (mpp.mode() == directMappedPolyPatch::NEARESTCELL)
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"directMappedVelocityFluxFixedValueFvPatchField::"
|
||||||
|
"directMappedVelocityFluxFixedValueFvPatchField"
|
||||||
|
"("
|
||||||
|
"const fvPatch&, "
|
||||||
|
"const DimensionedField<vector, volMesh>&, "
|
||||||
|
"const dictionary&"
|
||||||
|
")"
|
||||||
|
) << "Patch " << p.name()
|
||||||
|
<< " of type '" << p.type()
|
||||||
|
<< "' can not be used in 'nearestCell' mode"
|
||||||
|
<< " of field " << dimensionedInternalField().name()
|
||||||
|
<< " in file " << dimensionedInternalField().objectPath()
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -54,6 +54,18 @@ namespace Foam
|
|||||||
directMappedPatchBase::sampleModeNames_;
|
directMappedPatchBase::sampleModeNames_;
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
const char* NamedEnum<directMappedPatchBase::offsetMode, 3>::names[] =
|
||||||
|
{
|
||||||
|
"uniform",
|
||||||
|
"nonuniform",
|
||||||
|
"normal"
|
||||||
|
};
|
||||||
|
|
||||||
|
const NamedEnum<directMappedPatchBase::offsetMode, 3>
|
||||||
|
directMappedPatchBase::offsetModeNames_;
|
||||||
|
|
||||||
|
|
||||||
//- Private class for finding nearest
|
//- Private class for finding nearest
|
||||||
// - point+local index
|
// - point+local index
|
||||||
// - sqr(distance)
|
// - sqr(distance)
|
||||||
@ -100,7 +112,7 @@ void Foam::directMappedPatchBase::collectSamples
|
|||||||
labelListList globalFaces(Pstream::nProcs());
|
labelListList globalFaces(Pstream::nProcs());
|
||||||
|
|
||||||
globalFc[Pstream::myProcNo()] = patch_.faceCentres();
|
globalFc[Pstream::myProcNo()] = patch_.faceCentres();
|
||||||
globalSamples[Pstream::myProcNo()] = globalFc[Pstream::myProcNo()]+offsets_;
|
globalSamples[Pstream::myProcNo()] = samplePoints();
|
||||||
globalFaces[Pstream::myProcNo()] = identity(patch_.size());
|
globalFaces[Pstream::myProcNo()] = identity(patch_.size());
|
||||||
|
|
||||||
// Distribute to all processors
|
// Distribute to all processors
|
||||||
@ -393,19 +405,34 @@ void Foam::directMappedPatchBase::calcMapping() const
|
|||||||
<< "Mapping already calculated" << exit(FatalError);
|
<< "Mapping already calculated" << exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if
|
// Do a sanity check
|
||||||
|
// Am I sampling my own patch? This only makes sense for a non-zero
|
||||||
|
// offset.
|
||||||
|
bool sampleMyself =
|
||||||
(
|
(
|
||||||
gAverage(mag(offsets_)) <= ROOTVSMALL
|
mode_ == NEARESTPATCHFACE
|
||||||
&& mode_ == NEARESTPATCHFACE
|
|
||||||
&& sampleRegion_ == patch_.boundaryMesh().mesh().name()
|
&& sampleRegion_ == patch_.boundaryMesh().mesh().name()
|
||||||
&& samplePatch_ == patch_.name()
|
&& samplePatch_ == patch_.name()
|
||||||
)
|
);
|
||||||
|
|
||||||
|
// Check offset
|
||||||
|
vectorField d(samplePoints()-patch_.faceCentres());
|
||||||
|
if (sampleMyself && gAverage(mag(d)) <= ROOTVSMALL)
|
||||||
{
|
{
|
||||||
WarningIn("directMappedPatchBase::calcMapping() const")
|
WarningIn
|
||||||
<< "Invalid offset " << offsets_ << endl
|
(
|
||||||
|
"directMappedPatchBase::directMappedPatchBase\n"
|
||||||
|
"(\n"
|
||||||
|
" const polyPatch& pp,\n"
|
||||||
|
" const word& sampleRegion,\n"
|
||||||
|
" const sampleMode mode,\n"
|
||||||
|
" const word& samplePatch,\n"
|
||||||
|
" const vector& offset\n"
|
||||||
|
")\n"
|
||||||
|
) << "Invalid offset " << d << endl
|
||||||
<< "Offset is the vector added to the patch face centres to"
|
<< "Offset is the vector added to the patch face centres to"
|
||||||
<< " find the patch face supplying the data." << endl
|
<< " find the patch face supplying the data." << endl
|
||||||
<< "Setting it to " << offsets_
|
<< "Setting it to " << d
|
||||||
<< " on the same patch, on the same region"
|
<< " on the same patch, on the same region"
|
||||||
<< " will find the faces themselves which does not make sense"
|
<< " will find the faces themselves which does not make sense"
|
||||||
<< " for anything but testing." << endl
|
<< " for anything but testing." << endl
|
||||||
@ -413,10 +440,11 @@ void Foam::directMappedPatchBase::calcMapping() const
|
|||||||
<< "sampleRegion_:" << sampleRegion_ << endl
|
<< "sampleRegion_:" << sampleRegion_ << endl
|
||||||
<< "mode_:" << sampleModeNames_[mode_] << endl
|
<< "mode_:" << sampleModeNames_[mode_] << endl
|
||||||
<< "samplePatch_:" << samplePatch_ << endl
|
<< "samplePatch_:" << samplePatch_ << endl
|
||||||
<< "offsets_:" << offsets_ << endl;
|
<< "offsetMode_:" << offsetModeNames_[offsetMode_] << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Get global list of all samples and the processor and face they come from.
|
// Get global list of all samples and the processor and face they come from.
|
||||||
pointField samples;
|
pointField samples;
|
||||||
labelList patchFaceProcs;
|
labelList patchFaceProcs;
|
||||||
@ -477,40 +505,6 @@ void Foam::directMappedPatchBase::calcMapping() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//// Check that actual offset vector (sampleLocations - patchFc) is more or
|
|
||||||
//// less constant.
|
|
||||||
//if (Pstream::master())
|
|
||||||
//{
|
|
||||||
// const scalarField magOffset(mag(sampleLocations - patchFc));
|
|
||||||
// const scalar avgOffset(average(magOffset));
|
|
||||||
//
|
|
||||||
// forAll(magOffset, sampleI)
|
|
||||||
// {
|
|
||||||
// if
|
|
||||||
// (
|
|
||||||
// mag(magOffset[sampleI]-avgOffset)
|
|
||||||
// > max(SMALL, 0.001*avgOffset)
|
|
||||||
// )
|
|
||||||
// {
|
|
||||||
// WarningIn("directMappedPatchBase::calcMapping() const")
|
|
||||||
// << "The actual cell/face centres picked up using offset "
|
|
||||||
// << offsets_ << " are not" << endl
|
|
||||||
// << " on a single plane."
|
|
||||||
// << " This might give numerical problems." << endl
|
|
||||||
// << " At patchface " << patchFc[sampleI]
|
|
||||||
// << " the sampled cell/face " << sampleLocations[sampleI]
|
|
||||||
// << endl
|
|
||||||
// << " is not on a plane " << avgOffset
|
|
||||||
// << " offset from the patch." << endl
|
|
||||||
// << " You might want to shift your plane offset."
|
|
||||||
// << " Set the debug flag to get a dump of sampled cells."
|
|
||||||
// << endl;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
// Determine schedule.
|
// Determine schedule.
|
||||||
mapPtr_.reset(new mapDistribute(sampleProcs, patchFaceProcs));
|
mapPtr_.reset(new mapDistribute(sampleProcs, patchFaceProcs));
|
||||||
|
|
||||||
@ -597,9 +591,10 @@ Foam::directMappedPatchBase::directMappedPatchBase
|
|||||||
sampleRegion_(patch_.boundaryMesh().mesh().name()),
|
sampleRegion_(patch_.boundaryMesh().mesh().name()),
|
||||||
mode_(NEARESTPATCHFACE),
|
mode_(NEARESTPATCHFACE),
|
||||||
samplePatch_("none"),
|
samplePatch_("none"),
|
||||||
uniformOffset_(true),
|
offsetMode_(UNIFORM),
|
||||||
offset_(vector::zero),
|
offset_(vector::zero),
|
||||||
offsets_(pp.size(), offset_),
|
offsets_(pp.size(), offset_),
|
||||||
|
distance_(0),
|
||||||
sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
|
sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
|
||||||
mapPtr_(NULL)
|
mapPtr_(NULL)
|
||||||
{}
|
{}
|
||||||
@ -618,8 +613,10 @@ Foam::directMappedPatchBase::directMappedPatchBase
|
|||||||
sampleRegion_(sampleRegion),
|
sampleRegion_(sampleRegion),
|
||||||
mode_(mode),
|
mode_(mode),
|
||||||
samplePatch_(samplePatch),
|
samplePatch_(samplePatch),
|
||||||
uniformOffset_(false),
|
offsetMode_(NONUNIFORM),
|
||||||
|
offset_(vector::zero),
|
||||||
offsets_(offsets),
|
offsets_(offsets),
|
||||||
|
distance_(0),
|
||||||
sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
|
sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
|
||||||
mapPtr_(NULL)
|
mapPtr_(NULL)
|
||||||
{}
|
{}
|
||||||
@ -638,9 +635,10 @@ Foam::directMappedPatchBase::directMappedPatchBase
|
|||||||
sampleRegion_(sampleRegion),
|
sampleRegion_(sampleRegion),
|
||||||
mode_(mode),
|
mode_(mode),
|
||||||
samplePatch_(samplePatch),
|
samplePatch_(samplePatch),
|
||||||
uniformOffset_(true),
|
offsetMode_(UNIFORM),
|
||||||
offset_(offset),
|
offset_(offset),
|
||||||
offsets_(pp.size(), offset_),
|
offsets_(0),
|
||||||
|
distance_(0),
|
||||||
sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
|
sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
|
||||||
mapPtr_(NULL)
|
mapPtr_(NULL)
|
||||||
{}
|
{}
|
||||||
@ -663,22 +661,62 @@ Foam::directMappedPatchBase::directMappedPatchBase
|
|||||||
),
|
),
|
||||||
mode_(sampleModeNames_.read(dict.lookup("sampleMode"))),
|
mode_(sampleModeNames_.read(dict.lookup("sampleMode"))),
|
||||||
samplePatch_(dict.lookup("samplePatch")),
|
samplePatch_(dict.lookup("samplePatch")),
|
||||||
uniformOffset_(dict.found("offset")),
|
offsetMode_(UNIFORM),
|
||||||
offset_
|
offset_(vector::zero),
|
||||||
(
|
offsets_(0),
|
||||||
uniformOffset_
|
distance_(0.0),
|
||||||
? point(dict.lookup("offset"))
|
|
||||||
: vector::zero
|
|
||||||
),
|
|
||||||
offsets_
|
|
||||||
(
|
|
||||||
uniformOffset_
|
|
||||||
? pointField(pp.size(), offset_)
|
|
||||||
: dict.lookup("offsets")
|
|
||||||
),
|
|
||||||
sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
|
sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
|
||||||
mapPtr_(NULL)
|
mapPtr_(NULL)
|
||||||
{}
|
{
|
||||||
|
if (dict.found("offsetMode"))
|
||||||
|
{
|
||||||
|
offsetMode_ = offsetModeNames_.read(dict.lookup("offsetMode"));
|
||||||
|
|
||||||
|
switch(offsetMode_)
|
||||||
|
{
|
||||||
|
case UNIFORM:
|
||||||
|
{
|
||||||
|
offset_ = point(dict.lookup("offset"));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NONUNIFORM:
|
||||||
|
{
|
||||||
|
offsets_ = pointField(dict.lookup("offsets"));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NORMAL:
|
||||||
|
{
|
||||||
|
distance_ = readScalar(dict.lookup("distance"));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (dict.found("offset"))
|
||||||
|
{
|
||||||
|
offsetMode_ = UNIFORM;
|
||||||
|
offset_ = point(dict.lookup("offset"));
|
||||||
|
}
|
||||||
|
else if (dict.found("offsets"))
|
||||||
|
{
|
||||||
|
offsetMode_ = NONUNIFORM;
|
||||||
|
offsets_ = pointField(dict.lookup("offsets"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"directMappedPatchBase::directMappedPatchBase\n"
|
||||||
|
"(\n"
|
||||||
|
" const polyPatch& pp,\n"
|
||||||
|
" const dictionary& dict\n"
|
||||||
|
")\n"
|
||||||
|
) << "Please supply the offsetMode as one of "
|
||||||
|
<< NamedEnum<offsetMode, 3>::words()
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::directMappedPatchBase::directMappedPatchBase
|
Foam::directMappedPatchBase::directMappedPatchBase
|
||||||
@ -691,9 +729,10 @@ Foam::directMappedPatchBase::directMappedPatchBase
|
|||||||
sampleRegion_(dmp.sampleRegion_),
|
sampleRegion_(dmp.sampleRegion_),
|
||||||
mode_(dmp.mode_),
|
mode_(dmp.mode_),
|
||||||
samplePatch_(dmp.samplePatch_),
|
samplePatch_(dmp.samplePatch_),
|
||||||
uniformOffset_(dmp.uniformOffset_),
|
offsetMode_(dmp.offsetMode_),
|
||||||
offset_(dmp.offset_),
|
offset_(dmp.offset_),
|
||||||
offsets_(dmp.offsets_),
|
offsets_(dmp.offsets_),
|
||||||
|
distance_(dmp.distance_),
|
||||||
sameRegion_(dmp.sameRegion_),
|
sameRegion_(dmp.sameRegion_),
|
||||||
mapPtr_(NULL)
|
mapPtr_(NULL)
|
||||||
{}
|
{}
|
||||||
@ -710,9 +749,10 @@ Foam::directMappedPatchBase::directMappedPatchBase
|
|||||||
sampleRegion_(dmp.sampleRegion_),
|
sampleRegion_(dmp.sampleRegion_),
|
||||||
mode_(dmp.mode_),
|
mode_(dmp.mode_),
|
||||||
samplePatch_(dmp.samplePatch_),
|
samplePatch_(dmp.samplePatch_),
|
||||||
uniformOffset_(dmp.uniformOffset_),
|
offsetMode_(dmp.offsetMode_),
|
||||||
offset_(dmp.offset_),
|
offset_(dmp.offset_),
|
||||||
offsets_(dmp.offsets_, mapAddressing),
|
offsets_(dmp.offsets_, mapAddressing),
|
||||||
|
distance_(dmp.distance_),
|
||||||
sameRegion_(dmp.sameRegion_),
|
sameRegion_(dmp.sameRegion_),
|
||||||
mapPtr_(NULL)
|
mapPtr_(NULL)
|
||||||
{}
|
{}
|
||||||
@ -762,6 +802,40 @@ const Foam::polyPatch& Foam::directMappedPatchBase::samplePolyPatch() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::pointField> Foam::directMappedPatchBase::samplePoints() const
|
||||||
|
{
|
||||||
|
tmp<pointField> tfld(new pointField(patch_.faceCentres()));
|
||||||
|
pointField& fld = tfld();
|
||||||
|
|
||||||
|
switch(offsetMode_)
|
||||||
|
{
|
||||||
|
case UNIFORM:
|
||||||
|
{
|
||||||
|
fld += offset_;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NONUNIFORM:
|
||||||
|
{
|
||||||
|
fld += offsets_;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NORMAL:
|
||||||
|
{
|
||||||
|
// Get outwards pointing normal
|
||||||
|
vectorField n(patch_.faceAreas());
|
||||||
|
n /= mag(n);
|
||||||
|
|
||||||
|
fld += distance_*n;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tfld;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::directMappedPatchBase::write(Ostream& os) const
|
void Foam::directMappedPatchBase::write(Ostream& os) const
|
||||||
{
|
{
|
||||||
os.writeKeyword("sampleMode") << sampleModeNames_[mode_]
|
os.writeKeyword("sampleMode") << sampleModeNames_[mode_]
|
||||||
@ -770,13 +844,31 @@ void Foam::directMappedPatchBase::write(Ostream& os) const
|
|||||||
<< token::END_STATEMENT << nl;
|
<< token::END_STATEMENT << nl;
|
||||||
os.writeKeyword("samplePatch") << samplePatch_
|
os.writeKeyword("samplePatch") << samplePatch_
|
||||||
<< token::END_STATEMENT << nl;
|
<< token::END_STATEMENT << nl;
|
||||||
if (uniformOffset_)
|
|
||||||
|
os.writeKeyword("offsetMode") << offsetModeNames_[offsetMode_]
|
||||||
|
<< token::END_STATEMENT << nl;
|
||||||
|
|
||||||
|
switch(offsetMode_)
|
||||||
{
|
{
|
||||||
os.writeKeyword("offset") << offset_ << token::END_STATEMENT << nl;
|
case UNIFORM:
|
||||||
}
|
{
|
||||||
else
|
os.writeKeyword("offset") << offset_ << token::END_STATEMENT << nl;
|
||||||
{
|
}
|
||||||
os.writeKeyword("offsets") << offsets_ << token::END_STATEMENT << nl;
|
break;
|
||||||
|
|
||||||
|
case NONUNIFORM:
|
||||||
|
{
|
||||||
|
os.writeKeyword("offsets") << offsets_ << token::END_STATEMENT
|
||||||
|
<< nl;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NORMAL:
|
||||||
|
{
|
||||||
|
os.writeKeyword("distance") << distance_ << token::END_STATEMENT
|
||||||
|
<< nl;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -28,6 +28,33 @@ Description
|
|||||||
Determines a mapping between patch face centres and mesh cell or face
|
Determines a mapping between patch face centres and mesh cell or face
|
||||||
centres and processors they're on.
|
centres and processors they're on.
|
||||||
|
|
||||||
|
If constructed from dictionary:
|
||||||
|
// Region to sample (default is region0)
|
||||||
|
sampleRegion region0;
|
||||||
|
|
||||||
|
// What to sample:
|
||||||
|
// - nearestCell : sample nearest cell
|
||||||
|
// - nearestPatchFace : nearest face on selected patch
|
||||||
|
// - nearestFace : nearest boundary face on any patch
|
||||||
|
sampleMode nearestCell;
|
||||||
|
|
||||||
|
// If sampleMod is nearestPatchFace : patch to find faces of
|
||||||
|
samplePatch movingWall;
|
||||||
|
|
||||||
|
// How to supply offset (w.r.t. my patch face centres):
|
||||||
|
// - uniform : single offset vector
|
||||||
|
// - nonuniform : per-face offset vector
|
||||||
|
// - normal : using supplied distance and face normal
|
||||||
|
offsetMode uniform;
|
||||||
|
|
||||||
|
// According to offsetMode (see above) supply one of
|
||||||
|
// offset, offsets or distance
|
||||||
|
offset (1 0 0);
|
||||||
|
|
||||||
|
Note: if offsetMode is 'normal' it uses outwards pointing normals. So
|
||||||
|
supply a negative distance if sampling inside the domain.
|
||||||
|
|
||||||
|
|
||||||
Note
|
Note
|
||||||
Storage is not optimal. It temporary collects all (patch)face centres
|
Storage is not optimal. It temporary collects all (patch)face centres
|
||||||
on all processors to keep the addressing calculation simple.
|
on all processors to keep the addressing calculation simple.
|
||||||
@ -71,12 +98,22 @@ public:
|
|||||||
NEARESTFACE // nearest face
|
NEARESTFACE // nearest face
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//- How to project face centres
|
||||||
|
enum offsetMode
|
||||||
|
{
|
||||||
|
UNIFORM, // single offset vector
|
||||||
|
NONUNIFORM, // per-face offset vector
|
||||||
|
NORMAL // use face normal + distance
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Private data
|
// Private data
|
||||||
|
|
||||||
static const NamedEnum<sampleMode, 3> sampleModeNames_;
|
static const NamedEnum<sampleMode, 3> sampleModeNames_;
|
||||||
|
|
||||||
|
static const NamedEnum<offsetMode, 3> offsetModeNames_;
|
||||||
|
|
||||||
//- Patch to sample
|
//- Patch to sample
|
||||||
const polyPatch& patch_;
|
const polyPatch& patch_;
|
||||||
|
|
||||||
@ -89,14 +126,17 @@ private:
|
|||||||
//- Patch (only if NEARESTPATCHFACE)
|
//- Patch (only if NEARESTPATCHFACE)
|
||||||
const word samplePatch_;
|
const word samplePatch_;
|
||||||
|
|
||||||
//- For backwards compatibility : reading/writing of uniform offset.
|
//- How to obtain samples
|
||||||
const bool uniformOffset_;
|
offsetMode offsetMode_;
|
||||||
|
|
||||||
//- Offset vector (uniform)
|
//- Offset vector (uniform)
|
||||||
const vector offset_;
|
vector offset_;
|
||||||
|
|
||||||
//- Offset vector
|
//- Offset vector (nonuniform)
|
||||||
const vectorField offsets_;
|
vectorField offsets_;
|
||||||
|
|
||||||
|
//- Offset distance (normal)
|
||||||
|
scalar distance_;
|
||||||
|
|
||||||
//- Same region
|
//- Same region
|
||||||
const bool sameRegion_;
|
const bool sameRegion_;
|
||||||
@ -146,17 +186,17 @@ public:
|
|||||||
//- Construct from patch
|
//- Construct from patch
|
||||||
directMappedPatchBase(const polyPatch&);
|
directMappedPatchBase(const polyPatch&);
|
||||||
|
|
||||||
//- Construct from components
|
//- Construct with offsetMode=non-uniform
|
||||||
directMappedPatchBase
|
directMappedPatchBase
|
||||||
(
|
(
|
||||||
const polyPatch& pp,
|
const polyPatch& pp,
|
||||||
const word& sampleRegion,
|
const word& sampleRegion,
|
||||||
const sampleMode sampleMode,
|
const sampleMode sampleMode,
|
||||||
const word& samplePatch,
|
const word& samplePatch,
|
||||||
const vectorField& offset
|
const vectorField& offsets
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Construct from components
|
//- Construct from offsetMode=uniform
|
||||||
directMappedPatchBase
|
directMappedPatchBase
|
||||||
(
|
(
|
||||||
const polyPatch& pp,
|
const polyPatch& pp,
|
||||||
@ -166,6 +206,16 @@ public:
|
|||||||
const vector& offset
|
const vector& offset
|
||||||
);
|
);
|
||||||
|
|
||||||
|
////- Construct from normal and distance
|
||||||
|
//directMappedPatchBase
|
||||||
|
//(
|
||||||
|
// const polyPatch& pp,
|
||||||
|
// const word& sampleRegion,
|
||||||
|
// const word& samplePatch,
|
||||||
|
// const sampleMode sampleMode,
|
||||||
|
// const vector& offset
|
||||||
|
//);
|
||||||
|
|
||||||
//- Construct from dictionary
|
//- Construct from dictionary
|
||||||
directMappedPatchBase(const polyPatch&, const dictionary&);
|
directMappedPatchBase(const polyPatch&, const dictionary&);
|
||||||
|
|
||||||
@ -241,6 +291,9 @@ public:
|
|||||||
//- Get the patch on the region
|
//- Get the patch on the region
|
||||||
const polyPatch& samplePolyPatch() const;
|
const polyPatch& samplePolyPatch() const;
|
||||||
|
|
||||||
|
//- Get the sample points
|
||||||
|
tmp<pointField> samplePoints() const;
|
||||||
|
|
||||||
//- Write as a dictionary
|
//- Write as a dictionary
|
||||||
virtual void write(Ostream&) const;
|
virtual void write(Ostream&) const;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user