ENH: robuster handling of mapMethod naming (#2535)

- align timeVaryingMappedFixedValuePointPatchField keywords with
  MappedFile

STYLE: minor cleanup of pointToPointPlanarInterpolation

BUG: incorrect keyword for timeVaryingMappedFixedValuePointPatchField

- lookup should be "fieldTable" (not "fieldTableName") for consistency
  with the output and other BCs. (Bug introduced by a623ab42a3)
This commit is contained in:
Mark Olesen 2022-07-11 18:48:13 +02:00
parent dfdbe7efd0
commit 5630db5493
8 changed files with 551 additions and 552 deletions

View File

@ -37,7 +37,7 @@ Description
- points : pointField of locations
- \<time\>/\<field\> : field of values at time \<time\>
The default mode of operation (mapMethod planarInterpolation) is to project
The default mode of operation (mapMethod = planar) is to project
the points onto a plane (constructed from the first three points) and
construct a 2D triangulation and finds for the face centres the triangle it
is in and the weights to the 3 vertices.
@ -50,12 +50,12 @@ Description
Usage
\table
Property | Description | Required | Default
setAverage | Use average value | no | false
setAverage | Use average value | no | false
perturb | Perturb points for regular geometries | no | 1e-5
points | Name of points file | no | points
points | Name of points file | no | points
fieldTable | Alternative field name to sample | no | this field name
mapMethod | Type of mapping | no | planarInterpolation
offset | Offset to mapped values | no | Zero
mapMethod | Type of mapping | no | planar
offset | Offset to mapped values | no | Zero
\endtable
\verbatim
@ -74,8 +74,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef timeVaryingMappedFixedValueFvPatchField_H
#define timeVaryingMappedFixedValueFvPatchField_H
#ifndef Foam_timeVaryingMappedFixedValueFvPatchField_H
#define Foam_timeVaryingMappedFixedValueFvPatchField_H
#include "fixedValueFvPatchFields.H"
#include "MappedFile.H"
@ -94,7 +94,7 @@ class timeVaryingMappedFixedValueFvPatchField
:
public fixedValueFvPatchField<Type>
{
// Private data
// Private Data
autoPtr<PatchFunction1Types::MappedFile<Type>> uniformValue_;

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-2017 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
Copyright (C) 2020-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -41,18 +41,20 @@ timeVaryingMappedFixedValuePointPatchField
)
:
fixedValuePointPatchField<Type>(p, iF),
fieldTableName_(iF.name()),
setAverage_(false),
perturb_(0),
fieldTableName_(iF.name()),
pointsName_("points"),
mapMethod_(),
mapperPtr_(nullptr),
sampleTimes_(0),
startSampleTime_(-1),
startSampledValues_(0),
startAverage_(Zero),
endSampleTime_(-1),
endSampledValues_(0),
sampleTimes_(),
begSampleIndex_(-1),
endSampleIndex_(-1),
begAverage_(Zero),
endAverage_(Zero),
offset_()
begSampledValues_(),
endSampledValues_(),
offset_(nullptr)
{}
@ -66,25 +68,19 @@ timeVaryingMappedFixedValuePointPatchField
)
:
fixedValuePointPatchField<Type>(p, iF, dict, false),
fieldTableName_(iF.name()),
setAverage_(dict.getOrDefault("setAverage", false)),
perturb_(dict.getOrDefault("perturb", 1e-5)),
mapMethod_
(
dict.getOrDefault<word>
(
"mapMethod",
"planarInterpolation"
)
),
fieldTableName_(iF.name()),
pointsName_(dict.getOrDefault<word>("points", "points")),
mapMethod_(),
mapperPtr_(nullptr),
sampleTimes_(0),
startSampleTime_(-1),
startSampledValues_(0),
startAverage_(Zero),
endSampleTime_(-1),
endSampledValues_(0),
sampleTimes_(),
begSampleIndex_(-1),
endSampleIndex_(-1),
begAverage_(Zero),
endAverage_(Zero),
begSampledValues_(),
endSampledValues_(),
offset_
(
Function1<Type>::NewIfPresent("offset", dict, word::null, &this->db())
@ -92,16 +88,24 @@ timeVaryingMappedFixedValuePointPatchField
{
if
(
mapMethod_ != "planarInterpolation"
dict.readIfPresent("mapMethod", mapMethod_)
&& !mapMethod_.empty()
&& mapMethod_ != "nearest"
&& !mapMethod_.starts_with("planar")
)
{
FatalIOErrorInFunction(dict)
<< "mapMethod should be one of 'planarInterpolation'"
<< ", 'nearest'" << exit(FatalIOError);
<< "Unknown mapMethod type " << mapMethod_
<< "\n\nValid mapMethod types :\n"
<< "(nearest planar)" << nl
<< exit(FatalIOError);
}
dict.readIfPresent("fieldTableName", fieldTableName_);
dict.readIfPresentCompat
(
"fieldTable", {{"fieldTableName", 2206}},
fieldTableName_
);
if (dict.found("value"))
{
@ -132,18 +136,19 @@ timeVaryingMappedFixedValuePointPatchField
)
:
fixedValuePointPatchField<Type>(ptf, p, iF, mapper),
fieldTableName_(ptf.fieldTableName_),
setAverage_(ptf.setAverage_),
perturb_(ptf.perturb_),
fieldTableName_(ptf.fieldTableName_),
pointsName_(ptf.pointsName_),
mapMethod_(ptf.mapMethod_),
mapperPtr_(nullptr),
sampleTimes_(0),
startSampleTime_(-1),
startSampledValues_(0),
startAverage_(Zero),
endSampleTime_(-1),
endSampledValues_(0),
sampleTimes_(),
begSampleIndex_(-1),
endSampleIndex_(-1),
begAverage_(Zero),
endAverage_(Zero),
begSampledValues_(),
endSampledValues_(),
offset_(ptf.offset_.clone())
{}
@ -156,18 +161,19 @@ timeVaryingMappedFixedValuePointPatchField
)
:
fixedValuePointPatchField<Type>(ptf),
fieldTableName_(ptf.fieldTableName_),
setAverage_(ptf.setAverage_),
perturb_(ptf.perturb_),
fieldTableName_(ptf.fieldTableName_),
pointsName_(ptf.pointsName_),
mapMethod_(ptf.mapMethod_),
mapperPtr_(ptf.mapperPtr_),
sampleTimes_(ptf.sampleTimes_),
startSampleTime_(ptf.startSampleTime_),
startSampledValues_(ptf.startSampledValues_),
startAverage_(ptf.startAverage_),
endSampleTime_(ptf.endSampleTime_),
endSampledValues_(ptf.endSampledValues_),
begSampleIndex_(ptf.begSampleIndex_),
endSampleIndex_(ptf.endSampleIndex_),
begAverage_(ptf.begAverage_),
endAverage_(ptf.endAverage_),
begSampledValues_(ptf.begSampledValues_),
endSampledValues_(ptf.endSampledValues_),
offset_(ptf.offset_.clone())
{}
@ -181,18 +187,19 @@ timeVaryingMappedFixedValuePointPatchField
)
:
fixedValuePointPatchField<Type>(ptf, iF),
fieldTableName_(ptf.fieldTableName_),
setAverage_(ptf.setAverage_),
perturb_(ptf.perturb_),
fieldTableName_(ptf.fieldTableName_),
pointsName_(ptf.pointsName_),
mapMethod_(ptf.mapMethod_),
mapperPtr_(ptf.mapperPtr_),
sampleTimes_(ptf.sampleTimes_),
startSampleTime_(ptf.startSampleTime_),
startSampledValues_(ptf.startSampledValues_),
startAverage_(ptf.startAverage_),
endSampleTime_(ptf.endSampleTime_),
endSampledValues_(ptf.endSampledValues_),
begSampleIndex_(ptf.begSampleIndex_),
endSampleIndex_(ptf.endSampleIndex_),
begAverage_(ptf.begAverage_),
endAverage_(ptf.endAverage_),
begSampledValues_(ptf.begSampledValues_),
endSampledValues_(ptf.endSampledValues_),
offset_(ptf.offset_.clone())
{}
@ -206,15 +213,21 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::autoMap
)
{
fixedValuePointPatchField<Type>::autoMap(m);
if (startSampledValues_.size())
if (begSampledValues_.size())
{
begSampledValues_.autoMap(m);
}
if (endSampledValues_.size())
{
startSampledValues_.autoMap(m);
endSampledValues_.autoMap(m);
}
// Clear interpolator
mapperPtr_.clear();
startSampleTime_ = -1;
endSampleTime_ = -1;
mapperPtr_.reset(nullptr);
begSampleIndex_ = -1;
endSampleIndex_ = -1;
}
@ -230,23 +243,100 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::rmap
const timeVaryingMappedFixedValuePointPatchField<Type>& tiptf =
refCast<const timeVaryingMappedFixedValuePointPatchField<Type>>(ptf);
startSampledValues_.rmap(tiptf.startSampledValues_, addr);
begSampledValues_.rmap(tiptf.begSampledValues_, addr);
endSampledValues_.rmap(tiptf.endSampledValues_, addr);
// Clear interpolator
mapperPtr_.clear();
startSampleTime_ = -1;
endSampleTime_ = -1;
mapperPtr_.reset(nullptr);
begSampleIndex_ = -1;
endSampleIndex_ = -1;
}
template<class Type>
void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::updateSampledValues
(
const int whichEnd // (0|1)
)
{
// Update sampled data fields
const Time& time = this->db().time();
const word& sampleTimeName =
sampleTimes_[(whichEnd ? endSampleIndex_ : begSampleIndex_)].name();
if (debug)
{
Pout<< "checkTable : Reading values from "
<<
(
"boundaryData"
/ this->patch().name()
/ sampleTimeName
/ fieldTableName_
) << endl;
}
// Reread values and interpolate
const fileName valsFile
(
time.caseConstant()
/"boundaryData"
/this->patch().name()
/sampleTimeName
/fieldTableName_
);
IOobject io
(
valsFile, // absolute path
time,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false, // no need to register
true // is global object (currently not used)
);
const rawIOField<Type> vals(io, setAverage_);
if (vals.size() != mapperPtr_().sourceSize())
{
FatalErrorInFunction
<< "Number of values (" << vals.size()
<< ") differs from the number of points ("
<< mapperPtr_().sourceSize()
<< ") in file " << valsFile << exit(FatalError);
}
if (whichEnd)
{
if (setAverage_) // or vals.hasAverage()
{
endAverage_ = vals.average();
}
endSampledValues_ = mapperPtr_().interpolate(vals);
}
else
{
if (setAverage_) // or vals.hasAverage()
{
begAverage_ = vals.average();
}
begSampledValues_ = mapperPtr_().interpolate(vals);
}
}
template<class Type>
void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable
(
const scalar t
)
{
const Time& time = this->db().time();
// Initialise
if (startSampleTime_ == -1 && endSampleTime_ == -1)
if (begSampleIndex_ == -1 && endSampleIndex_ == -1)
{
const polyMesh& pMesh = this->patch().boundaryMesh().mesh()();
@ -288,7 +378,7 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
time.caseConstant()
/"boundaryData"
/this->patch().name()
/"points"
/pointsName_
);
IOobject io
@ -301,14 +391,13 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
true // is global object (currently not used)
);
// Read data
// Read data (no average value!)
const rawIOField<point> samplePoints(io, false);
// tbd: run-time selection
bool nearestOnly =
const bool nearestOnly =
(
!mapMethod_.empty()
&& mapMethod_ != "planarInterpolation"
!mapMethod_.empty() && !mapMethod_.starts_with("planar")
);
// Allocate the interpolator
@ -323,26 +412,24 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
)
);
// Read the times for which data is available
// Read the times for which data is available
const fileName samplePointsDir = samplePointsFile.path();
sampleTimes_ = Time::findTimes(samplePointsDir);
if (debug)
{
Info<< "timeVaryingMappedFixedValuePointPatchField : In directory "
<< samplePointsDir << " found times "
<< pointToPointPlanarInterpolation::timeNames(sampleTimes_)
<< endl;
}
DebugInfo
<< "timeVaryingMappedFixedValuePointPatchField : In directory "
<< samplePointsDir << " found times "
<< pointToPointPlanarInterpolation::timeNames(sampleTimes_)
<< endl;
}
// Find range of current time indices in sampleTimes
Pair<label> timeIndices = instant::findRange
(
sampleTimes_,
time.value(),
startSampleTime_
t, // time.value(),
begSampleIndex_
);
if (timeIndices.first() < 0)
@ -362,11 +449,11 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
// Update sampled data fields.
if (startSampleTime_ != timeIndices.first())
if (begSampleIndex_ != timeIndices.first())
{
startSampleTime_ = timeIndices.first();
begSampleIndex_ = timeIndices.first();
if (startSampleTime_ == endSampleTime_)
if (begSampleIndex_ == endSampleIndex_)
{
// No need to reread since are end values
if (debug)
@ -374,69 +461,24 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
Pout<< "checkTable : Setting startValues to (already read) "
<< "boundaryData"
/this->patch().name()
/sampleTimes_[startSampleTime_].name()
/sampleTimes_[begSampleIndex_].name()
<< endl;
}
startSampledValues_ = endSampledValues_;
startAverage_ = endAverage_;
begAverage_ = endAverage_;
begSampledValues_ = endSampledValues_;
}
else
{
const word& sampleTimeName = sampleTimes_[startSampleTime_].name();
if (debug)
{
Pout<< "checkTable : Reading startValues from "
<< "boundaryData"
/this->patch().name()
/sampleTimeName
<< endl;
}
// Reread values and interpolate
const fileName valsFile
(
time.caseConstant()
/"boundaryData"
/this->patch().name()
/sampleTimeName
/fieldTableName_
);
IOobject io
(
valsFile, // absolute path
time,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false, // no need to register
true // is global object (currently not used)
);
const rawIOField<Type> vals(io, setAverage_);
if (setAverage_)
{
startAverage_ = vals.average();
}
if (vals.size() != mapperPtr_().sourceSize())
{
FatalErrorInFunction
<< "Number of values (" << vals.size()
<< ") differs from the number of points ("
<< mapperPtr_().sourceSize()
<< ") in file " << valsFile << exit(FatalError);
}
startSampledValues_ = mapperPtr_().interpolate(vals);
// Update begin values
this->updateSampledValues(0);
}
}
if (endSampleTime_ != timeIndices.second())
if (endSampleIndex_ != timeIndices.second())
{
endSampleTime_ = timeIndices.second();
endSampleIndex_ = timeIndices.second();
if (endSampleTime_ == -1)
if (endSampleIndex_ == -1)
{
// endTime no longer valid. Might as well clear endValues.
if (debug)
@ -447,54 +489,8 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
}
else
{
const word& sampleTimeName = sampleTimes_[endSampleTime_].name();
if (debug)
{
Pout<< "checkTable : Reading endValues from "
<< "boundaryData"
/this->patch().name()
/sampleTimeName
<< endl;
}
// Reread values and interpolate
const fileName valsFile
(
time.caseConstant()
/"boundaryData"
/this->patch().name()
/sampleTimeName
/fieldTableName_
);
IOobject io
(
valsFile, // absolute path
time,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false, // no need to register
true // is global object (currently not used)
);
const rawIOField<Type> vals(io, setAverage_);
if (setAverage_)
{
endAverage_ = vals.average();
}
if (vals.size() != mapperPtr_().sourceSize())
{
FatalErrorInFunction
<< "Number of values (" << vals.size()
<< ") differs from the number of points ("
<< mapperPtr_().sourceSize()
<< ") in file " << valsFile << exit(FatalError);
}
endSampledValues_ = mapperPtr_().interpolate(vals);
// Update end values
this->updateSampledValues(1);
}
}
}
@ -508,51 +504,51 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::updateCoeffs()
return;
}
checkTable();
// Current time value
const scalar x = this->db().time().value();
checkTable(x);
// Interpolate between the sampled data
auto& fld = static_cast<Field<Type>&>(*this);
Type wantedAverage;
if (endSampleTime_ == -1)
if (endSampleIndex_ == -1)
{
// only start value
// Only start value
if (debug)
{
Pout<< "updateCoeffs : Sampled, non-interpolated values"
<< " from start time:"
<< sampleTimes_[startSampleTime_].name() << nl;
<< sampleTimes_[begSampleIndex_].name() << nl;
}
this->operator==(startSampledValues_);
wantedAverage = startAverage_;
fld = begSampledValues_;
wantedAverage = begAverage_;
}
else
{
scalar start = sampleTimes_[startSampleTime_].value();
scalar end = sampleTimes_[endSampleTime_].value();
scalar s = (this->db().time().value()-start)/(end-start);
const scalar beg = sampleTimes_[begSampleIndex_].value();
const scalar end = sampleTimes_[endSampleIndex_].value();
const scalar s = (x - beg)/(end - beg);
if (debug)
{
Pout<< "updateCoeffs : Sampled, interpolated values"
<< " between start time:"
<< sampleTimes_[startSampleTime_].name()
<< " and end time:" << sampleTimes_[endSampleTime_].name()
<< sampleTimes_[begSampleIndex_].name()
<< " and end time:" << sampleTimes_[endSampleIndex_].name()
<< " with weight:" << s << endl;
}
this->operator==((1-s)*startSampledValues_ + s*endSampledValues_);
wantedAverage = (1-s)*startAverage_ + s*endAverage_;
fld = ((1 - s)*begSampledValues_ + s*endSampledValues_);
wantedAverage = (1 - s)*begAverage_ + s*endAverage_;
}
// Enforce average. Either by scaling (if scaling factor > 0.5) or by
// offsetting.
if (setAverage_)
{
const Field<Type>& fld = *this;
Type averagePsi = gAverage(fld);
if (debug)
@ -572,7 +568,7 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::updateCoeffs()
Pout<< "updateCoeffs :"
<< " offsetting with:" << offset << endl;
}
this->operator==(fld+offset);
fld += offset;
}
else
{
@ -583,7 +579,7 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::updateCoeffs()
Pout<< "updateCoeffs :"
<< " scaling with:" << scale << endl;
}
this->operator==(scale*fld);
fld *= scale;
}
}
@ -591,7 +587,7 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::updateCoeffs()
if (offset_)
{
const scalar t = this->db().time().timeOutputValue();
this->operator==(*this + offset_->value(t));
fld += offset_->value(t);
}
if (debug)
@ -613,9 +609,6 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::write
{
fixedValuePointPatchField<Type>::write(os);
os.writeEntryIfDifferent("setAverage", Switch(false), setAverage_);
os.writeEntryIfDifferent<scalar>("perturb", 1e-5, perturb_);
os.writeEntryIfDifferent
(
"fieldTable",
@ -623,12 +616,22 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::write
fieldTableName_
);
os.writeEntryIfDifferent<word>
(
"mapMethod",
"planarInterpolation",
mapMethod_
);
if (!pointsName_.empty())
{
os.writeEntryIfDifferent<word>("points", "points", pointsName_);
}
if (!mapMethod_.empty() && !mapMethod_.starts_with("planar"))
{
os.writeEntry("mapMethod", mapMethod_);
}
if (setAverage_)
{
os.writeEntry("setAverage", setAverage_);
}
os.writeEntryIfDifferent<scalar>("perturb", 1e-5, perturb_);
if (offset_)
{

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-2016 OpenFOAM Foundation
Copyright (C) 2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -29,6 +30,17 @@ Class
Description
A time-varying form of a mapped fixed value boundary condition.
Usage
\table
Property | Description | Required | Default
setAverage | Use average value | no | false
perturb | Perturb points for regular geometries | no | 1e-5
points | Name of points file | no | points
fieldTable | Alternative field name to sample | no | this field name
mapMethod | Type of mapping | no | planar
offset | Offset to mapped values | no | Zero
\endtable
See also
Foam::timeVaryingMappedFixedValueFvPatchField
@ -37,8 +49,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef timeVaryingMappedFixedValuePointPatchField_H
#define timeVaryingMappedFixedValuePointPatchField_H
#ifndef Foam_timeVaryingMappedFixedValuePointPatchField_H
#define Foam_timeVaryingMappedFixedValuePointPatchField_H
#include "fixedValuePointPatchField.H"
#include "instantList.H"
@ -59,48 +71,60 @@ class timeVaryingMappedFixedValuePointPatchField
:
public fixedValuePointPatchField<Type>
{
// Private data
//- Name of the field data table, defaults to the name of the field
word fieldTableName_;
// Private Data
//- If true adjust the mapped field to maintain average value
Switch setAverage_;
bool setAverage_;
//- Fraction of perturbation (fraction of bounding box) to add
scalar perturb_;
//- Interpolation scheme to use
//- Name of the field data table, defaults to the name of the field
word fieldTableName_;
//- Name of points file (default: "points")
word pointsName_;
//- Interpolation scheme to use (default is empty == "planar")
word mapMethod_;
//- 2D interpolation (for 'planarInterpolation' mapMethod)
//- 2D interpolation (for 'planar' mapMethod)
autoPtr<pointToPointPlanarInterpolation> mapperPtr_;
//- List of boundaryData time directories
instantList sampleTimes_;
//- Current starting index in sampleTimes
label startSampleTime_;
//- Interpolated values from startSampleTime
Field<Type> startSampledValues_;
//- If setAverage: starting average value
Type startAverage_;
//- Current start index in sampleTimes
label begSampleIndex_;
//- Current end index in sampleTimes
label endSampleTime_;
label endSampleIndex_;
//- Interpolated values from endSampleTime
Field<Type> endSampledValues_;
//- Current average value at begSampleIndex (if setAverage)
Type begAverage_;
//- If setAverage: end average value
//- Current average value at endSampleIndex (if setAverage)
Type endAverage_;
//- Current interpolated values at begSampleIndex
Field<Type> begSampledValues_;
//- Current interpolated values at endSampleIndex
Field<Type> endSampledValues_;
//- Time varying offset values to interpolated data
autoPtr<Function1<Type>> offset_;
// Private Member Functions
//- Update start (0) or end (1) interpolated data
void updateSampledValues(const int whichEnd);
//- Find boundary data between time 't' and interpolate
void checkTable(const scalar t);
public:
//- Runtime type information
@ -168,13 +192,7 @@ public:
}
// Member functions
// Utility functions
//- Find boundary data inbetween current time and interpolate
void checkTable();
// Member Functions
// Mapping functions

View File

@ -43,36 +43,33 @@ Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
PatchFunction1<Type>(pp, entryName, dict, faceValues),
dictConstructed_(true),
setAverage_(dict.getOrDefault("setAverage", false)),
fieldTableName_(dict.getOrDefault<word>("fieldTable", entryName)),
perturb_(dict.getOrDefault<scalar>("perturb", 1e-5)),
fieldTableName_(dict.getOrDefault<word>("fieldTable", entryName)),
pointsName_(dict.getOrDefault<word>("points", "points")),
mapMethod_
(
dict.getOrDefault<word>
(
"mapMethod",
"planarInterpolation"
)
),
mapMethod_(),
mapperPtr_(nullptr),
sampleTimes_(0),
startSampleTime_(-1),
startSampledValues_(0),
startAverage_(Zero),
endSampleTime_(-1),
endSampledValues_(0),
sampleTimes_(),
begSampleIndex_(-1),
endSampleIndex_(-1),
begAverage_(Zero),
endAverage_(Zero),
begSampledValues_(),
endSampledValues_(),
offset_(Function1<Type>::NewIfPresent("offset", dict))
{
if
(
mapMethod_ != "planarInterpolation"
dict.readIfPresent("mapMethod", mapMethod_)
&& !mapMethod_.empty()
&& mapMethod_ != "nearest"
&& !mapMethod_.starts_with("planar")
)
{
FatalIOErrorInFunction(dict)
<< "mapMethod should be one of 'planarInterpolation'"
<< ", 'nearest'" << exit(FatalIOError);
<< "Unknown mapMethod type " << mapMethod_
<< "\n\nValid mapMethod types :\n"
<< "(nearest planar)" << nl
<< exit(FatalIOError);
}
}
@ -90,36 +87,33 @@ Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
PatchFunction1<Type>(pp, entryName, dict, faceValues),
dictConstructed_(false),
setAverage_(dict.getOrDefault("setAverage", false)),
fieldTableName_(fieldTableName),
perturb_(dict.getOrDefault<scalar>("perturb", 1e-5)),
fieldTableName_(fieldTableName),
pointsName_(dict.getOrDefault<word>("points", "points")),
mapMethod_
(
dict.getOrDefault<word>
(
"mapMethod",
"planarInterpolation"
)
),
mapMethod_(),
mapperPtr_(nullptr),
sampleTimes_(0),
startSampleTime_(-1),
startSampledValues_(0),
startAverage_(Zero),
endSampleTime_(-1),
endSampledValues_(0),
sampleTimes_(),
begSampleIndex_(-1),
endSampleIndex_(-1),
begAverage_(Zero),
endAverage_(Zero),
begSampledValues_(),
endSampledValues_(),
offset_(Function1<Type>::NewIfPresent("offset", dict))
{
if
(
mapMethod_ != "planarInterpolation"
dict.readIfPresent("mapMethod", mapMethod_)
&& !mapMethod_.empty()
&& mapMethod_ != "nearest"
&& !mapMethod_.starts_with("planar")
)
{
FatalIOErrorInFunction(dict)
<< "mapMethod should be one of 'planarInterpolation'"
<< ", 'nearest'" << exit(FatalIOError);
<< "Unknown mapMethod type " << mapMethod_
<< "\n\nValid mapMethod types :\n"
<< "(nearest planar)" << nl
<< exit(FatalIOError);
}
}
@ -144,18 +138,18 @@ Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
PatchFunction1<Type>(rhs, pp),
dictConstructed_(rhs.dictConstructed_),
setAverage_(rhs.setAverage_),
fieldTableName_(rhs.fieldTableName_),
perturb_(rhs.perturb_),
fieldTableName_(rhs.fieldTableName_),
pointsName_(rhs.pointsName_),
mapMethod_(rhs.mapMethod_),
mapperPtr_(rhs.mapperPtr_.clone()),
sampleTimes_(rhs.sampleTimes_),
startSampleTime_(rhs.startSampleTime_),
startSampledValues_(rhs.startSampledValues_),
startAverage_(rhs.startAverage_),
endSampleTime_(rhs.endSampleTime_),
endSampledValues_(rhs.endSampledValues_),
begSampleIndex_(rhs.begSampleIndex_),
endSampleIndex_(rhs.endSampleIndex_),
begAverage_(rhs.begAverage_),
endAverage_(rhs.endAverage_),
begSampledValues_(rhs.begSampledValues_),
endSampledValues_(rhs.endSampledValues_),
offset_(rhs.offset_.clone())
{}
@ -170,20 +164,19 @@ void Foam::PatchFunction1Types::MappedFile<Type>::autoMap
{
PatchFunction1<Type>::autoMap(mapper);
if (startSampledValues_.size())
if (begSampledValues_.size())
{
startSampledValues_.autoMap(mapper);
begSampledValues_.autoMap(mapper);
}
if (endSampledValues_.size())
{
endSampledValues_.autoMap(mapper);
}
// Clear interpolator
mapperPtr_.clear();
startSampleTime_ = -1;
endSampleTime_ = -1;
mapperPtr_.reset(nullptr);
begSampleIndex_ = -1;
endSampleIndex_ = -1;
}
@ -199,22 +192,100 @@ void Foam::PatchFunction1Types::MappedFile<Type>::rmap
const PatchFunction1Types::MappedFile<Type>& tiptf =
refCast<const PatchFunction1Types::MappedFile<Type>>(pf1);
if (tiptf.startSampledValues_.size())
if (tiptf.begSampledValues_.size())
{
startSampledValues_.setSize(this->size());
startSampledValues_.rmap(tiptf.startSampledValues_, addr);
begSampledValues_.resize(this->size());
begSampledValues_.rmap(tiptf.begSampledValues_, addr);
}
if (tiptf.endSampledValues_.size())
{
endSampledValues_.setSize(this->size());
endSampledValues_.resize(this->size());
endSampledValues_.rmap(tiptf.endSampledValues_, addr);
}
// Clear interpolator
mapperPtr_.clear();
startSampleTime_ = -1;
endSampleTime_ = -1;
mapperPtr_.reset(nullptr);
begSampleIndex_ = -1;
endSampleIndex_ = -1;
}
template<class Type>
void Foam::PatchFunction1Types::MappedFile<Type>::updateSampledValues
(
const int whichEnd // (0|1)
) const
{
// Update sampled data fields
const polyMesh& mesh = this->patch_.boundaryMesh().mesh();
const Time& time = mesh.time();
const word& sampleTimeName =
sampleTimes_[(whichEnd ? endSampleIndex_ : begSampleIndex_)].name();
if (debug)
{
Pout<< "checkTable : Reading values from "
<<
(
"boundaryData"
/ this->patch_.name()
/ sampleTimeName
/ fieldTableName_
) << endl;
}
// Reread values and interpolate
const fileName valsFile
(
time.globalPath()
/time.constant()
/mesh.dbDir() // region
/"boundaryData"
/this->patch_.name()
/sampleTimeName
/fieldTableName_
);
IOobject io
(
valsFile, // absolute path
time,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false, // no need to register
true // is global object (currently not used)
);
const rawIOField<Type> vals(io, setAverage_);
if (vals.size() != mapperPtr_().sourceSize())
{
FatalErrorInFunction
<< "Number of values (" << vals.size()
<< ") differs from the number of points ("
<< mapperPtr_().sourceSize()
<< ") in file " << valsFile
<< exit(FatalError);
}
if (whichEnd)
{
if (setAverage_) // or vals.hasAverage()
{
endAverage_ = vals.average();
}
endSampledValues_ = mapperPtr_().interpolate(vals);
}
else
{
if (setAverage_) // or vals.hasAverage()
{
begAverage_ = vals.average();
}
begSampledValues_ = mapperPtr_().interpolate(vals);
}
}
@ -251,21 +322,19 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
true // is global object (currently not used)
);
// Read data
// Read data (no average value!)
const rawIOField<point> samplePoints(io, false);
// tbd: run-time selection
const bool nearestOnly =
(
!mapMethod_.empty() && !mapMethod_.starts_with("planar")
);
DebugInfo
<< "Read " << samplePoints.size() << " sample points from "
<< samplePointsFile << endl;
// tbd: run-time selection
bool nearestOnly =
(
!mapMethod_.empty()
&& mapMethod_ != "planarInterpolation"
);
// Allocate the interpolator
if (this->faceValues())
{
@ -312,7 +381,7 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
(
sampleTimes_,
t, //mesh.time().value(),
startSampleTime_
begSampleIndex_
);
if (timeIndices.first() < 0)
@ -332,11 +401,11 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
// Update sampled data fields.
if (startSampleTime_ != timeIndices.first())
if (begSampleIndex_ != timeIndices.first())
{
startSampleTime_ = timeIndices.first();
begSampleIndex_ = timeIndices.first();
if (startSampleTime_ == endSampleTime_)
if (begSampleIndex_ == endSampleIndex_)
{
// No need to reread since are end values
if (debug)
@ -344,72 +413,24 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
Pout<< "checkTable : Setting startValues to (already read) "
<< "boundaryData"
/this->patch_.name()
/sampleTimes_[startSampleTime_].name()
/sampleTimes_[begSampleIndex_].name()
<< endl;
}
startSampledValues_ = endSampledValues_;
startAverage_ = endAverage_;
begAverage_ = endAverage_;
begSampledValues_ = endSampledValues_;
}
else
{
const word& sampleTimeName = sampleTimes_[startSampleTime_].name();
if (debug)
{
Pout<< "checkTable : Reading startValues from "
<< "boundaryData"
/this->patch_.name()
/sampleTimeName
/fieldTableName_
<< endl;
}
// Reread values and interpolate
const fileName valsFile
(
time.globalPath()
/time.constant()
/mesh.dbDir() // region
/"boundaryData"
/this->patch_.name()
/sampleTimeName
/fieldTableName_
);
IOobject io
(
valsFile, // absolute path
time,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false, // no need to register
true // is global object (currently not used)
);
const rawIOField<Type> vals(io, setAverage_);
if (setAverage_)
{
startAverage_ = vals.average();
}
if (vals.size() != mapperPtr_().sourceSize())
{
FatalErrorInFunction
<< "Number of values (" << vals.size()
<< ") differs from the number of points ("
<< mapperPtr_().sourceSize()
<< ") in file " << valsFile << exit(FatalError);
}
startSampledValues_ = mapperPtr_().interpolate(vals);
// Update begin values
this->updateSampledValues(0);
}
}
if (endSampleTime_ != timeIndices.second())
if (endSampleIndex_ != timeIndices.second())
{
endSampleTime_ = timeIndices.second();
endSampleIndex_ = timeIndices.second();
if (endSampleTime_ == -1)
if (endSampleIndex_ == -1)
{
// endTime no longer valid. Might as well clear endValues.
if (debug)
@ -420,55 +441,8 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
}
else
{
const word& sampleTimeName = sampleTimes_[endSampleTime_].name();
if (debug)
{
Pout<< "checkTable : Reading endValues from "
<< "boundaryData"
/this->patch_.name()
/sampleTimeName
<< endl;
}
// Reread values and interpolate
fileName valsFile
(
time.globalPath()
/time.constant()
/mesh.dbDir() // region
/"boundaryData"
/this->patch_.name()
/sampleTimeName
/fieldTableName_
);
IOobject io
(
valsFile, // absolute path
time,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false, // no need to register
true // is global object (currently not used)
);
const rawIOField<Type> vals(io, setAverage_);
if (setAverage_)
{
endAverage_ = vals.average();
}
if (vals.size() != mapperPtr_().sourceSize())
{
FatalErrorInFunction
<< "Number of values (" << vals.size()
<< ") differs from the number of points ("
<< mapperPtr_().sourceSize()
<< ") in file " << valsFile << exit(FatalError);
}
endSampledValues_ = mapperPtr_().interpolate(vals);
// Update end values
this->updateSampledValues(1);
}
}
}
@ -483,41 +457,40 @@ Foam::PatchFunction1Types::MappedFile<Type>::value
{
checkTable(x);
auto tfld = tmp<Field<Type>>::New(startSampledValues_.size());
auto tfld = tmp<Field<Type>>::New(begSampledValues_.size());
auto& fld = tfld.ref();
Type wantedAverage;
if (endSampleTime_ == -1)
if (endSampleIndex_ == -1)
{
// Only start value
if (debug)
{
Pout<< "MappedFile<Type>::value : Sampled, non-interpolated values"
<< " from start time:"
<< sampleTimes_[startSampleTime_].name() << nl;
<< sampleTimes_[begSampleIndex_].name() << nl;
}
fld = startSampledValues_;
wantedAverage = startAverage_;
fld = begSampledValues_;
wantedAverage = begAverage_;
}
else
{
scalar start = sampleTimes_[startSampleTime_].value();
scalar end = sampleTimes_[endSampleTime_].value();
scalar s = (x - start)/(end - start);
const scalar beg = sampleTimes_[begSampleIndex_].value();
const scalar end = sampleTimes_[endSampleIndex_].value();
const scalar s = (x - beg)/(end - beg);
if (debug)
{
Pout<< "MappedFile<Type>::value : Sampled, interpolated values"
<< " between start time:"
<< sampleTimes_[startSampleTime_].name()
<< " and end time:" << sampleTimes_[endSampleTime_].name()
<< sampleTimes_[begSampleIndex_].name()
<< " and end time:" << sampleTimes_[endSampleIndex_].name()
<< " with weight:" << s << endl;
}
fld = ((1 - s)*startSampledValues_ + s*endSampledValues_);
wantedAverage = (1 - s)*startAverage_ + s*endAverage_;
fld = ((1 - s)*begSampledValues_ + s*endSampledValues_);
wantedAverage = (1 - s)*begAverage_ + s*endAverage_;
}
// Enforce average. Either by scaling (if scaling factor > 0.5) or by
@ -610,6 +583,16 @@ void Foam::PatchFunction1Types::MappedFile<Type>::writeEntries
fieldTableName_
);
if (!pointsName_.empty())
{
os.writeEntryIfDifferent<word>("points", "points", pointsName_);
}
if (!mapMethod_.empty() && !mapMethod_.starts_with("planar"))
{
os.writeEntry("mapMethod", mapMethod_);
}
if (setAverage_)
{
os.writeEntry("setAverage", setAverage_);
@ -617,15 +600,6 @@ void Foam::PatchFunction1Types::MappedFile<Type>::writeEntries
os.writeEntryIfDifferent<scalar>("perturb", 1e-5, perturb_);
os.writeEntryIfDifferent<word>("points", "points", pointsName_);
os.writeEntryIfDifferent<word>
(
"mapMethod",
"planarInterpolation",
mapMethod_
);
if (offset_)
{
offset_->writeData(os);

View File

@ -38,8 +38,7 @@ Description
Options:
\table
Property | Description | Type | Reqd | Deflt
mapMethod | Mapping method | word | no <!--
--> | planarInterpolation
mapMethod | Mapping method | word | no | planar
offset | Time-varying offset values to interpolated data <!--
--> | Function1\<Type\> | no | -
fieldTable | Name of field data table | word | no | field-name
@ -51,8 +50,8 @@ Description
Options for the \c mapMethod entry:
\verbatim
nearest | Use nearest points only (avoids triangulation)
planarInterpolation | Interpolation using 2D Delaunay triangulation
nearest | Use nearest points only (avoids triangulation)
planar | Interpolation using 2D Delaunay triangulation
\endverbatim
SourceFiles
@ -60,8 +59,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef PatchFunction1Types_MappedFile_H
#define PatchFunction1Types_MappedFile_H
#ifndef Foam_PatchFunction1Types_MappedFile_H
#define Foam_PatchFunction1Types_MappedFile_H
#include "PatchFunction1.H"
#include "Function1.H"
@ -91,48 +90,52 @@ class MappedFile
//- If true adjust the mapped field to maintain average value
bool setAverage_;
//- Name of the field data table, defaults to the name of the field
word fieldTableName_;
//- Fraction of perturbation (fraction of bounding box) to add
scalar perturb_;
//- Name of points file; default = "points"
//- Name of the field data table, defaults to the name of the field
word fieldTableName_;
//- Name of points file (default: "points")
word pointsName_;
//- Interpolation scheme to use
//- Interpolation scheme to use (default is empty == "planar")
word mapMethod_;
//- 2D interpolation (for 'planarInterpolation' mapMethod)
//- 2D interpolation (for 'planar' mapMethod)
mutable autoPtr<pointToPointPlanarInterpolation> mapperPtr_;
//- List of boundaryData time directories
mutable instantList sampleTimes_;
//- Current starting index in sampleTimes
mutable label startSampleTime_;
//- Interpolated values from startSampleTime
mutable Field<Type> startSampledValues_;
//- If setAverage: starting average value
mutable Type startAverage_;
//- Current start index in sampleTimes
mutable label begSampleIndex_;
//- Current end index in sampleTimes
mutable label endSampleTime_;
mutable label endSampleIndex_;
//- Interpolated values from endSampleTime
mutable Field<Type> endSampledValues_;
//- Current average value at begSampleIndex (if setAverage)
mutable Type begAverage_;
//- If setAverage: end average value
//- Current average value at endSampleIndex (if setAverage)
mutable Type endAverage_;
//- Current interpolated values at begSampleIndex
mutable Field<Type> begSampledValues_;
//- Current interpolated values at endSampleIndex
mutable Field<Type> endSampledValues_;
//- Time varying offset values to interpolated data
autoPtr<Function1<Type>> offset_;
// Private Member Functions
//- Update start (0) or end (1) interpolated data
void updateSampledValues(const int whichEnd) const;
//- Find boundary data between time 't' and interpolate
void checkTable(const scalar t) const;
public:

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-2016 OpenFOAM Foundation
Copyright (C) 2019-2020 OpenCFD Ltd.
Copyright (C) 2019-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -44,43 +44,38 @@ namespace Foam
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::coordSystem::cartesian
Foam::pointToPointPlanarInterpolation::calcCoordinateSystem
(
const pointField& points
) const
)
{
if (points.size() < 3)
{
FatalErrorInFunction
<< "Only " << points.size() << " provided." << nl
<< "Need at least three non-colinear points"
<< " to be able to interpolate."
<< "Need at least 3 non-collinear points for planar interpolation,"
<< " but only had " << points.size() << " points" << nl
<< exit(FatalError);
}
const point& p0 = points[0];
// Find furthest away point
vector e1;
label index1 = -1;
scalar maxDist = ROOTVSMALL;
scalar maxDistSqr = ROOTVSMALL;
for (label i = 1; i < points.size(); i++)
for (label i = 1; i < points.size(); ++i)
{
const vector d = points[i] - p0;
scalar magD = mag(d);
const scalar mag2 = magSqr(points[i] - p0);
if (magD > maxDist)
if (maxDistSqr < mag2)
{
e1 = d/magD;
maxDistSqr = mag2;
index1 = i;
maxDist = magD;
}
}
if (index1 == -1)
{
FatalErrorInFunction
@ -89,26 +84,24 @@ Foam::pointToPointPlanarInterpolation::calcCoordinateSystem
<< exit(FatalError);
}
const vector e1(normalised(points[index1] - p0));
// Find point that is furthest away from line p0-p1
const point& p1 = points[index1];
// Find point that is furthest perpendicular distance from the p0-p1 line
label index2 = -1;
maxDist = ROOTVSMALL;
maxDistSqr = ROOTVSMALL;
for (label i = 1; i < points.size(); i++)
{
if (i != index1)
{
const point& p2 = points[i];
vector e2(p2 - p0);
vector e2(points[i] - p0);
e2.removeCollinear(e1);
scalar magE2 = mag(e2);
const scalar mag2 = magSqr(e2);
if (magE2 > maxDist)
if (maxDistSqr < mag2)
{
maxDistSqr = mag2;
index2 = i;
maxDist = magE2;
}
}
}
@ -116,7 +109,7 @@ Foam::pointToPointPlanarInterpolation::calcCoordinateSystem
{
FatalErrorInFunction
<< "Cannot find points that define a plane with a valid normal."
<< nl << "Have so far points " << p0 << " and " << p1
<< nl << "Have so far points " << p0 << " and " << points[index1]
<< ". Are all your points on a single line instead of a plane?"
<< exit(FatalError);
}
@ -124,8 +117,8 @@ Foam::pointToPointPlanarInterpolation::calcCoordinateSystem
const vector n = normalised(e1 ^ (points[index2]-p0));
DebugInFunction
<< " Used points " << p0 << ' ' << points[index1]
<< ' ' << points[index2]
<< " Used points "
<< p0 << ' ' << points[index1] << ' ' << points[index2]
<< " to define coordinate system with normal " << n << endl;
return coordSystem::cartesian
@ -137,6 +130,8 @@ Foam::pointToPointPlanarInterpolation::calcCoordinateSystem
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::pointToPointPlanarInterpolation::calcWeights
(
const pointField& sourcePoints,
@ -162,8 +157,8 @@ void Foam::pointToPointPlanarInterpolation::calcWeights
<< " centre" << exit(FatalError);
}
nearestVertex_.setSize(destPoints.size());
nearestVertexWeight_.setSize(destPoints.size());
nearestVertex_.resize(destPoints.size());
nearestVertexWeight_.resize(destPoints.size());
forAll(nearestVertex_, i)
{
nearestVertex_[i][0] = destToSource[i];
@ -353,35 +348,20 @@ Foam::pointToPointPlanarInterpolation::pointToPointPlanarInterpolation
const bool nearestOnly,
const coordinateSystem& referenceCS,
const label sourceSize,
const List<FixedList<label, 3>>& nearestVertex,
const List<FixedList<scalar, 3>>& nearestVertexWeight
List<FixedList<label, 3>>&& nearestVertex,
List<FixedList<scalar, 3>>&& nearestVertexWeight
)
:
perturb_(perturb),
nearestOnly_(nearestOnly),
referenceCS_(referenceCS),
nPoints_(sourceSize),
nearestVertex_(nearestVertex),
nearestVertexWeight_(nearestVertexWeight)
nearestVertex_(std::move(nearestVertex)),
nearestVertexWeight_(std::move(nearestVertexWeight))
{}
Foam::autoPtr<Foam::pointToPointPlanarInterpolation>
Foam::pointToPointPlanarInterpolation::clone() const
{
return autoPtr<pointToPointPlanarInterpolation>::New
(
perturb_,
nearestOnly_,
referenceCS_,
nPoints_,
nearestVertex_,
nearestVertexWeight_
);
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::wordList Foam::pointToPointPlanarInterpolation::timeNames
(

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-2016 OpenFOAM Foundation
Copyright (C) 2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -35,11 +36,12 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef pointToPointPlanarInterpolation_H
#define pointToPointPlanarInterpolation_H
#ifndef Foam_pointToPointPlanarInterpolation_H
#define Foam_pointToPointPlanarInterpolation_H
#include "FixedList.H"
#include "instantList.H"
#include "Pair.H"
#include "cartesianCS.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -53,13 +55,13 @@ namespace Foam
class pointToPointPlanarInterpolation
{
// Private data
// Private Data
//- Perturbation factor
const scalar perturb_;
scalar perturb_;
//- Whether to use nearest point only (avoids triangulation, projection)
const bool nearestOnly_;
//- Use nearest point only (avoids triangulation, projection)
bool nearestOnly_;
//- Cartesian reference coordinate system
coordSystem::cartesian referenceCS_;
@ -67,19 +69,17 @@ class pointToPointPlanarInterpolation
//- Number of source points (for checking)
label nPoints_;
//- Current interpolation addressing to face centres of underlying
// patch
//- Interpolation addressing to face centres of underlying patch
List<FixedList<label, 3>> nearestVertex_;
//- Current interpolation factors to face centres of underlying
// patch
//- Interpolation factors to face centres of underlying patch
List<FixedList<scalar, 3>> nearestVertexWeight_;
// Private Member Functions
//- Calculate a local coordinate system from set of points
coordSystem::cartesian calcCoordinateSystem(const pointField&) const;
static coordSystem::cartesian calcCoordinateSystem(const pointField&);
//- Calculate addressing and weights
void calcWeights
@ -95,9 +95,25 @@ public:
ClassName("pointToPointPlanarInterpolation");
// Generated Methods
//- Copy construct
pointToPointPlanarInterpolation
(
const pointToPointPlanarInterpolation&
) = default;
//- Copy assignment
pointToPointPlanarInterpolation& operator=
(
const pointToPointPlanarInterpolation&
) = default;
// Constructors
//- Construct from 3D locations. Determines local coordinate system
//- Construct from 3D locations.
// Determines local coordinate system
// from sourcePoints and maps onto that. If nearestOnly skips any
// local coordinate system and triangulation and uses nearest vertex
// only
@ -125,55 +141,57 @@ public:
const bool nearestOnly,
const coordinateSystem& referenceCS,
const label sourceSize,
const List<FixedList<label, 3>>& nearestVertex,
const List<FixedList<scalar, 3>>& nearestVertexWeight
List<FixedList<label, 3>>&& nearestVertex,
List<FixedList<scalar, 3>>&& nearestVertexWeight
);
//- Construct and return a clone
autoPtr<pointToPointPlanarInterpolation> clone() const;
autoPtr<pointToPointPlanarInterpolation> clone() const
{
return autoPtr<pointToPointPlanarInterpolation>::New(*this);
}
// Member Functions
//- Perturbation factor (for triangulation)
scalar perturb() const
scalar perturb() const noexcept
{
return perturb_;
}
//- Whether to use nearest point only (avoids triangulation, projection)
bool nearestOnly() const
bool nearestOnly() const noexcept
{
return nearestOnly_;
}
//- Return the Cartesian reference coordinate system
const coordSystem::cartesian& referenceCS() const
const coordSystem::cartesian& referenceCS() const noexcept
{
return referenceCS_;
}
//- Number of source points
label sourceSize() const
label sourceSize() const noexcept
{
return nPoints_;
}
// patch
const List<FixedList<label, 3>>& nearestVertex() const
//- Interpolation addressing to face centres of underlying patch
const List<FixedList<label, 3>>& nearestVertex() const noexcept
{
return nearestVertex_;
}
//- Current interpolation factors to face centres of underlying
// patch
const List<FixedList<scalar, 3>>& nearestVertexWeight() const
//- Interpolation factors to face centres of underlying patch
const List<FixedList<scalar, 3>>& nearestVertexWeight() const noexcept
{
return nearestVertexWeight_;
}
//- Helper: extract words of times
static wordList timeNames(const instantList&);
static wordList timeNames(const instantList& times);
//- Interpolate from field on source points to dest points
template<class Type>

View File

@ -30,7 +30,8 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::pointToPointPlanarInterpolation::interpolate
Foam::tmp<Foam::Field<Type>>
Foam::pointToPointPlanarInterpolation::interpolate
(
const Field<Type>& sourceFld
) const
@ -43,35 +44,37 @@ Foam::tmp<Foam::Field<Type>> Foam::pointToPointPlanarInterpolation::interpolate
<< exit(FatalError);
}
tmp<Field<Type>> tfld(new Field<Type>(nearestVertex_.size()));
Field<Type>& fld = tfld.ref();
auto tfld = tmp<Field<Type>>::New(nearestVertex_.size());
auto& fld = tfld.ref();
forAll(fld, i)
{
const FixedList<label, 3>& verts = nearestVertex_[i];
const FixedList<scalar, 3>& w = nearestVertexWeight_[i];
if (verts[2] == -1)
if (verts[1] == -1)
{
if (verts[1] == -1)
{
// Use vertex0 only
fld[i] = sourceFld[verts[0]];
}
else
{
// Use vertex 0,1
fld[i] =
w[0]*sourceFld[verts[0]]
+ w[1]*sourceFld[verts[1]];
}
// Use vertex (0) only
fld[i] = sourceFld[verts[0]];
}
else if (verts[2] == -1)
{
// Use vertex (0,1)
fld[i] =
(
w[0]*sourceFld[verts[0]]
+ w[1]*sourceFld[verts[1]]
);
}
else
{
// Use vertex (0,1,2)
fld[i] =
(
w[0]*sourceFld[verts[0]]
+ w[1]*sourceFld[verts[1]]
+ w[2]*sourceFld[verts[2]];
+ w[2]*sourceFld[verts[2]]
);
}
}
return tfld;