ENH: add instance searching routines

- find start index
- find index range spanning a time
This commit is contained in:
Mark Olesen
2022-07-15 14:43:31 +02:00
parent b4612b4c04
commit dfdbe7efd0
11 changed files with 166 additions and 151 deletions

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
Copyright (C) 2018-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -30,11 +30,31 @@ Description
#include "argList.H"
#include "instant.H"
#include "Pair.H"
#include "fileNameInstant.H"
#include "DynamicList.H"
using namespace Foam;
template<class T>
Ostream& printInstant(const UList<T>& times, const label i)
{
if (i >= 0 && i < times.size())
{
Info<< " (" << times[i] << ")";
}
return Info;
}
template<class T>
Ostream& printInstant(const UList<T>& times, const Pair<label>& range)
{
printInstant(times, range.first());
printInstant(times, range.second());
return Info;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
@ -48,6 +68,7 @@ int main(int argc, char *argv[])
times.append({300.456, "def"});
times.append({454.456, "xyz"});
times.append({10, "ten"});
times.append({15, "fifteen"});
{
word timeName("twenty");
@ -61,6 +82,19 @@ int main(int argc, char *argv[])
sort(times);
Info<< "Sorted:" << times << nl;
for (const scalar val : { -0.5, 5.0, 18.0, 25.0, 450.0, 480.0 })
{
label start = instant::findStart(times, val);
Pair<label> range = instant::findRange(times, val);
Info<< nl
<< "time:" << val << nl;
Info<< " start:" << start;
printInstant(times, start) << nl;
Info<< " range:" << range;
printInstant(times, range) << nl;
}
DynamicList<fileNameInstant> files;
files.append(fileNameInstant{});

View File

@ -116,28 +116,17 @@ public:
// Member Functions
//- The value (const access)
scalar value() const noexcept
{
return val_;
}
scalar value() const noexcept { return val_; }
//- The value (non-const access)
scalar& value() noexcept
{
return val_;
}
scalar& value() noexcept { return val_; }
//- The name/key (const access)
const T& name() const noexcept
{
return key_;
}
const T& name() const noexcept { return key_; }
//- The name/key (non-const access)
T& name() noexcept
{
return key_;
}
T& name() noexcept { return key_; }
//- True if values are equal (includes SMALL for rounding)
bool equal(scalar val) const noexcept

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2018-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
@ -28,6 +28,8 @@ License
#include "instant.H"
#include "Time.H"
#include "Pair.H"
#include "UList.H"
#include <cstdlib> // std::atof
#include <utility> // std::move
@ -36,6 +38,62 @@ License
const char* const Foam::instant::typeName = "instant";
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::label Foam::instant::findStart
(
const UList<instant>& times,
const scalar timeVal
)
{
for (label i = 0; i < times.size(); ++i)
{
if (timeVal <= times[i].value())
{
return i;
}
}
return 0;
}
Foam::Pair<Foam::label> Foam::instant::findRange
(
const UList<instant>& times,
const scalar timeVal,
const label start
)
{
Pair<label> range(start, -1); // lower/upper
for (label i = start+1; i < times.size(); ++i)
{
if (timeVal < times[i].value())
{
break;
}
else
{
range.first() = i;
}
}
if (range.first() < 0 || range.first() >= times.size())
{
// Invalid
return Pair<label>(-1, -1);
}
if (range.first() < times.size()-1)
{
// Upper part of range within bounds
range.second() = range.first()+1;
}
return range;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::instant::instant(scalar timeValue)

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2018-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
@ -32,7 +32,7 @@ Description
Uses Foam::Time when formatting the name.
SourceFiles
instants.C
instant.C
\*---------------------------------------------------------------------------*/
@ -47,6 +47,10 @@ SourceFiles
namespace Foam
{
// Forward Declarations
template<class T> class Pair;
template<class T> class UList;
/*---------------------------------------------------------------------------*\
Class instant Declaration
\*---------------------------------------------------------------------------*/
@ -94,6 +98,26 @@ public:
//- Move construct from timeName, parsing timeName for a value
explicit instant(word&& timeName);
// Helper Functions (for searching)
//- Find and return index of given start time (linear search)
static label findStart
(
const UList<instant>& times,
const scalar timeVal
);
//- Find lower/upper indices for given time value in list of instances
//- (linear search) continuing \em after the given start index.
// \returns the range indices or (-1,-1) if unsuccessful.
static Pair<label> findRange
(
const UList<instant>& times,
const scalar timeVal,
const label start = -1
);
};

View File

@ -337,20 +337,15 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
}
}
// Find current time in sampleTimes
label lo = -1;
label hi = -1;
bool foundTime = mapperPtr_().findTime
// Find range of current time indices in sampleTimes
Pair<label> timeIndices = instant::findRange
(
sampleTimes_,
startSampleTime_,
time.value(),
lo,
hi
startSampleTime_
);
if (!foundTime)
if (timeIndices.first() < 0)
{
FatalErrorInFunction
<< "Cannot find starting sampling values for current time "
@ -367,9 +362,9 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
// Update sampled data fields.
if (lo != startSampleTime_)
if (startSampleTime_ != timeIndices.first())
{
startSampleTime_ = lo;
startSampleTime_ = timeIndices.first();
if (startSampleTime_ == endSampleTime_)
{
@ -387,12 +382,14 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
}
else
{
const word& sampleTimeName = sampleTimes_[startSampleTime_].name();
if (debug)
{
Pout<< "checkTable : Reading startValues from "
<< "boundaryData"
/this->patch().name()
/sampleTimes_[lo].name()
/sampleTimeName
<< endl;
}
@ -402,7 +399,7 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
time.caseConstant()
/"boundaryData"
/this->patch().name()
/sampleTimes_[startSampleTime_].name()
/sampleTimeName
/fieldTableName_
);
@ -435,9 +432,9 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
}
}
if (hi != endSampleTime_)
if (endSampleTime_ != timeIndices.second())
{
endSampleTime_ = hi;
endSampleTime_ = timeIndices.second();
if (endSampleTime_ == -1)
{
@ -450,12 +447,14 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
}
else
{
const word& sampleTimeName = sampleTimes_[endSampleTime_].name();
if (debug)
{
Pout<< "checkTable : Reading endValues from "
<< "boundaryData"
/this->patch().name()
/sampleTimes_[endSampleTime_].name()
/sampleTimeName
<< endl;
}
@ -465,7 +464,7 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
time.caseConstant()
/"boundaryData"
/this->patch().name()
/sampleTimes_[endSampleTime_].name()
/sampleTimeName
/fieldTableName_
);

View File

@ -307,20 +307,15 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
}
// Find current time in sampleTimes
label lo = -1;
label hi = -1;
bool foundTime = mapperPtr_().findTime
// Find range of current time indices in sampleTimes
Pair<label> timeIndices = instant::findRange
(
sampleTimes_,
startSampleTime_,
t, //mesh.time().value(),
lo,
hi
startSampleTime_
);
if (!foundTime)
if (timeIndices.first() < 0)
{
FatalErrorInFunction
<< "Cannot find starting sampling values for index "
@ -337,9 +332,9 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
// Update sampled data fields.
if (lo != startSampleTime_)
if (startSampleTime_ != timeIndices.first())
{
startSampleTime_ = lo;
startSampleTime_ = timeIndices.first();
if (startSampleTime_ == endSampleTime_)
{
@ -357,12 +352,14 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
}
else
{
const word& sampleTimeName = sampleTimes_[startSampleTime_].name();
if (debug)
{
Pout<< "checkTable : Reading startValues from "
<< "boundaryData"
/this->patch_.name()
/sampleTimes_[lo].name()
/sampleTimeName
/fieldTableName_
<< endl;
}
@ -375,7 +372,7 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
/mesh.dbDir() // region
/"boundaryData"
/this->patch_.name()
/sampleTimes_[startSampleTime_].name()
/sampleTimeName
/fieldTableName_
);
@ -408,9 +405,9 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
}
}
if (hi != endSampleTime_)
if (endSampleTime_ != timeIndices.second())
{
endSampleTime_ = hi;
endSampleTime_ = timeIndices.second();
if (endSampleTime_ == -1)
{
@ -423,12 +420,14 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
}
else
{
const word& sampleTimeName = sampleTimes_[endSampleTime_].name();
if (debug)
{
Pout<< "checkTable : Reading endValues from "
<< "boundaryData"
/this->patch_.name()
/sampleTimes_[endSampleTime_].name()
/sampleTimeName
<< endl;
}
@ -440,7 +439,7 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
/mesh.dbDir() // region
/"boundaryData"
/this->patch_.name()
/sampleTimes_[endSampleTime_].name()
/sampleTimeName
/fieldTableName_
);

View File

@ -398,65 +398,4 @@ Foam::wordList Foam::pointToPointPlanarInterpolation::timeNames
}
bool Foam::pointToPointPlanarInterpolation::findTime
(
const instantList& times,
const label startSampleTime,
const scalar timeVal,
label& lo,
label& hi
)
{
lo = startSampleTime;
hi = -1;
for (label i = startSampleTime+1; i < times.size(); i++)
{
if (times[i].value() > timeVal)
{
break;
}
else
{
lo = i;
}
}
if (lo == -1)
{
//FatalErrorInFunction
// << "Cannot find starting sampling values for current time "
// << timeVal << nl
// << "Have sampling values for times "
// << timeNames(times) << nl
// << exit(FatalError);
return false;
}
if (lo < times.size()-1)
{
hi = lo+1;
}
if (debug)
{
if (hi == -1)
{
Pout<< "findTime : Found time " << timeVal << " after"
<< " index:" << lo << " time:" << times[lo].value()
<< endl;
}
else
{
Pout<< "findTime : Found time " << timeVal << " inbetween"
<< " index:" << lo << " time:" << times[lo].value()
<< " and index:" << hi << " time:" << times[hi].value()
<< endl;
}
}
return true;
}
// ************************************************************************* //

View File

@ -175,16 +175,6 @@ public:
//- Helper: extract words of times
static wordList timeNames(const instantList&);
//- Helper: find time. Return true if successful.
static bool findTime
(
const instantList& times,
const label startSampleTime,
const scalar timeVal,
label& lo,
label& hi
);
//- Interpolate from field on source points to dest points
template<class Type>
tmp<Field<Type>> interpolate(const Field<Type>& sourceFld) const;

View File

@ -239,26 +239,6 @@ bool Foam::noiseModel::validateBounds(const scalarList& p) const
}
Foam::label Foam::noiseModel::findStartTimeIndex
(
const instantList& allTimes,
const scalar startTime
) const
{
forAll(allTimes, timeI)
{
const instant& i = allTimes[timeI];
if (i.value() >= startTime)
{
return timeI;
}
}
return 0;
}
Foam::fileName Foam::noiseModel::baseFileDir(const label dataseti) const
{
return

View File

@ -239,11 +239,15 @@ protected:
bool validateBounds(const scalarList& p) const;
//- Find and return start time index
label findStartTimeIndex
FOAM_DEPRECATED_FOR(2022-07, "instant::findStart() static method")
static label findStartTimeIndex
(
const instantList& allTimes,
const scalar startTime
) const;
)
{
return instant::findStart(allTimes, startTime);
}
//- Return the base output directory
fileName baseFileDir(const label dataseti) const;

View File

@ -50,6 +50,7 @@ void surfaceNoise::initialise(const fileName& fName)
{
Info<< "Reading data file " << fName << endl;
instantList allTimes;
label nAvailableTimes = 0;
// All reading performed on the master processor only
@ -75,8 +76,8 @@ void surfaceNoise::initialise(const fileName& fName)
// the heavy lifting
// Set the time range
const instantList allTimes = readerPtr_->times();
startTimeIndex_ = findStartTimeIndex(allTimes, startTime_);
allTimes = readerPtr_->times();
startTimeIndex_ = instant::findStart(allTimes, startTime_);
// Determine the windowing
nAvailableTimes = allTimes.size() - startTimeIndex_;
@ -97,8 +98,6 @@ void surfaceNoise::initialise(const fileName& fName)
if (Pstream::master())
{
// Restrict times
const instantList allTimes = readerPtr_->times();
times_.setSize(nRequiredTimes);
forAll(times_, timeI)
{