mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: add instance searching routines
- find start index - find index range spanning a time
This commit is contained in:
@ -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{});
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -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_
|
||||
);
|
||||
|
||||
|
||||
@ -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_
|
||||
);
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user