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 \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -30,11 +30,31 @@ Description
#include "argList.H" #include "argList.H"
#include "instant.H" #include "instant.H"
#include "Pair.H"
#include "fileNameInstant.H" #include "fileNameInstant.H"
#include "DynamicList.H" #include "DynamicList.H"
using namespace Foam; 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: // Main program:
@ -48,6 +68,7 @@ int main(int argc, char *argv[])
times.append({300.456, "def"}); times.append({300.456, "def"});
times.append({454.456, "xyz"}); times.append({454.456, "xyz"});
times.append({10, "ten"}); times.append({10, "ten"});
times.append({15, "fifteen"});
{ {
word timeName("twenty"); word timeName("twenty");
@ -61,6 +82,19 @@ int main(int argc, char *argv[])
sort(times); sort(times);
Info<< "Sorted:" << times << nl; 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; DynamicList<fileNameInstant> files;
files.append(fileNameInstant{}); files.append(fileNameInstant{});

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2018-2022 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -28,6 +28,8 @@ License
#include "instant.H" #include "instant.H"
#include "Time.H" #include "Time.H"
#include "Pair.H"
#include "UList.H"
#include <cstdlib> // std::atof #include <cstdlib> // std::atof
#include <utility> // std::move #include <utility> // std::move
@ -36,6 +38,62 @@ License
const char* const Foam::instant::typeName = "instant"; 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 * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::instant::instant(scalar timeValue) Foam::instant::instant(scalar timeValue)

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2018-2022 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -32,7 +32,7 @@ Description
Uses Foam::Time when formatting the name. Uses Foam::Time when formatting the name.
SourceFiles SourceFiles
instants.C instant.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -47,6 +47,10 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward Declarations
template<class T> class Pair;
template<class T> class UList;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class instant Declaration Class instant Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -94,6 +98,26 @@ public:
//- Move construct from timeName, parsing timeName for a value //- Move construct from timeName, parsing timeName for a value
explicit instant(word&& timeName); 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 // Find range of current time indices in sampleTimes
label lo = -1; Pair<label> timeIndices = instant::findRange
label hi = -1;
bool foundTime = mapperPtr_().findTime
( (
sampleTimes_, sampleTimes_,
startSampleTime_,
time.value(), time.value(),
lo, startSampleTime_
hi
); );
if (!foundTime) if (timeIndices.first() < 0)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Cannot find starting sampling values for current time " << "Cannot find starting sampling values for current time "
@ -367,9 +362,9 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
// Update sampled data fields. // Update sampled data fields.
if (lo != startSampleTime_) if (startSampleTime_ != timeIndices.first())
{ {
startSampleTime_ = lo; startSampleTime_ = timeIndices.first();
if (startSampleTime_ == endSampleTime_) if (startSampleTime_ == endSampleTime_)
{ {
@ -387,12 +382,14 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
} }
else else
{ {
const word& sampleTimeName = sampleTimes_[startSampleTime_].name();
if (debug) if (debug)
{ {
Pout<< "checkTable : Reading startValues from " Pout<< "checkTable : Reading startValues from "
<< "boundaryData" << "boundaryData"
/this->patch().name() /this->patch().name()
/sampleTimes_[lo].name() /sampleTimeName
<< endl; << endl;
} }
@ -402,7 +399,7 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
time.caseConstant() time.caseConstant()
/"boundaryData" /"boundaryData"
/this->patch().name() /this->patch().name()
/sampleTimes_[startSampleTime_].name() /sampleTimeName
/fieldTableName_ /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) if (endSampleTime_ == -1)
{ {
@ -450,12 +447,14 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
} }
else else
{ {
const word& sampleTimeName = sampleTimes_[endSampleTime_].name();
if (debug) if (debug)
{ {
Pout<< "checkTable : Reading endValues from " Pout<< "checkTable : Reading endValues from "
<< "boundaryData" << "boundaryData"
/this->patch().name() /this->patch().name()
/sampleTimes_[endSampleTime_].name() /sampleTimeName
<< endl; << endl;
} }
@ -465,7 +464,7 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
time.caseConstant() time.caseConstant()
/"boundaryData" /"boundaryData"
/this->patch().name() /this->patch().name()
/sampleTimes_[endSampleTime_].name() /sampleTimeName
/fieldTableName_ /fieldTableName_
); );

View File

@ -307,20 +307,15 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
} }
// Find current time in sampleTimes // Find range of current time indices in sampleTimes
label lo = -1; Pair<label> timeIndices = instant::findRange
label hi = -1;
bool foundTime = mapperPtr_().findTime
( (
sampleTimes_, sampleTimes_,
startSampleTime_,
t, //mesh.time().value(), t, //mesh.time().value(),
lo, startSampleTime_
hi
); );
if (!foundTime) if (timeIndices.first() < 0)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Cannot find starting sampling values for index " << "Cannot find starting sampling values for index "
@ -337,9 +332,9 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
// Update sampled data fields. // Update sampled data fields.
if (lo != startSampleTime_) if (startSampleTime_ != timeIndices.first())
{ {
startSampleTime_ = lo; startSampleTime_ = timeIndices.first();
if (startSampleTime_ == endSampleTime_) if (startSampleTime_ == endSampleTime_)
{ {
@ -357,12 +352,14 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
} }
else else
{ {
const word& sampleTimeName = sampleTimes_[startSampleTime_].name();
if (debug) if (debug)
{ {
Pout<< "checkTable : Reading startValues from " Pout<< "checkTable : Reading startValues from "
<< "boundaryData" << "boundaryData"
/this->patch_.name() /this->patch_.name()
/sampleTimes_[lo].name() /sampleTimeName
/fieldTableName_ /fieldTableName_
<< endl; << endl;
} }
@ -375,7 +372,7 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
/mesh.dbDir() // region /mesh.dbDir() // region
/"boundaryData" /"boundaryData"
/this->patch_.name() /this->patch_.name()
/sampleTimes_[startSampleTime_].name() /sampleTimeName
/fieldTableName_ /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) if (endSampleTime_ == -1)
{ {
@ -423,12 +420,14 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
} }
else else
{ {
const word& sampleTimeName = sampleTimes_[endSampleTime_].name();
if (debug) if (debug)
{ {
Pout<< "checkTable : Reading endValues from " Pout<< "checkTable : Reading endValues from "
<< "boundaryData" << "boundaryData"
/this->patch_.name() /this->patch_.name()
/sampleTimes_[endSampleTime_].name() /sampleTimeName
<< endl; << endl;
} }
@ -440,7 +439,7 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
/mesh.dbDir() // region /mesh.dbDir() // region
/"boundaryData" /"boundaryData"
/this->patch_.name() /this->patch_.name()
/sampleTimes_[endSampleTime_].name() /sampleTimeName
/fieldTableName_ /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 //- Helper: extract words of times
static wordList timeNames(const instantList&); 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 //- Interpolate from field on source points to dest points
template<class Type> template<class Type>
tmp<Field<Type>> interpolate(const Field<Type>& sourceFld) const; 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 Foam::fileName Foam::noiseModel::baseFileDir(const label dataseti) const
{ {
return return

View File

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

View File

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