Commit c6832767 authored by Andrew Heather's avatar Andrew Heather
Browse files

updated time varying boundary conditions

parent 8d1adca1
......@@ -28,8 +28,6 @@ License
#include "Time.H"
#include "IFstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
......@@ -57,8 +55,7 @@ timeVaryingUniformFixedValuePointPatchField
)
:
fixedValuePointPatchField<Type>(ptf, p, iF, mapper),
timeDataFile_(ptf.timeDataFile_),
timeSeries_(ptf.timeBounding())
timeSeries_(ptf.timeSeries_)
{}
......@@ -73,8 +70,7 @@ timeVaryingUniformFixedValuePointPatchField
)
:
fixedValuePointPatchField<Type>(p, iF),
timeDataFile_(dict.lookup("timeDataFile")),
timeSeries_(word(dict.lookup("timeBounding")))
timeSeries_(this->db(), dict)
{
updateCoeffs();
}
......@@ -89,8 +85,7 @@ timeVaryingUniformFixedValuePointPatchField
)
:
fixedValuePointPatchField<Type>(ptf),
timeDataFile_(ptf.timeDataFile_),
timeSeries_(ptf.timeBounding())
timeSeries_(ptf.timeSeries_)
{}
......@@ -104,67 +99,12 @@ timeVaryingUniformFixedValuePointPatchField
)
:
fixedValuePointPatchField<Type>(ptf, iF),
timeDataFile_(ptf.timeDataFile_),
timeSeries_(ptf.timeBounding())
timeSeries_(ptf.timeSeries_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Type
Foam::timeVaryingUniformFixedValuePointPatchField<Type>::
currentValue()
{
if (timeSeries_.size() == 0)
{
fileName fName(timeDataFile_);
fName.expand();
if (fName.size() == 0)
{
FatalErrorIn
(
"timeVaryingUniformFixedValuePointPatchField"
"::currentValue()"
) << "timeDataFile not specified for Patch "
<< this->patch().name()
<< exit(FatalError);
}
else
{
// relative path
if (fName[0] != '/')
{
fName = this->db().path()/fName;
}
// just in case we change the interface to timeSeries
word boundType = timeBounding();
IFstream(fName)() >> timeSeries_;
timeSeries_.bounding(boundType);
// be a bit paranoid and check that the list is okay
timeSeries_.check();
}
if (timeSeries_.size() == 0)
{
FatalErrorIn
(
"timeVaryingUniformFixedValuePointPatchField"
"::currentValue()"
) << "empty time series for Patch "
<< this->patch().name()
<< exit(FatalError);
}
}
return timeSeries_(this->db().time().timeOutputValue());
}
template<class Type>
void Foam::timeVaryingUniformFixedValuePointPatchField<Type>::updateCoeffs()
{
......@@ -173,7 +113,7 @@ void Foam::timeVaryingUniformFixedValuePointPatchField<Type>::updateCoeffs()
return;
}
this->operator==(currentValue());
this->operator==(timeSeries_(this->db().time().timeOutputValue()));
fixedValuePointPatchField<Type>::updateCoeffs();
}
......@@ -182,13 +122,8 @@ template<class Type>
void Foam::timeVaryingUniformFixedValuePointPatchField<Type>::write(Ostream& os) const
{
fixedValuePointPatchField<Type>::write(os);
os.writeKeyword("timeDataFile")
<< timeDataFile_ << token::END_STATEMENT << nl;
os.writeKeyword("timeBounding")
<< timeBounding() << token::END_STATEMENT << nl;
timeSeries_.write(os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //
......@@ -40,7 +40,7 @@ SourceFiles
#define timeVaryingUniformFixedValuePointPatchField_H
#include "fixedValuePointPatchField.H"
#include "timeSeries.H"
#include "interpolationTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......@@ -58,14 +58,9 @@ class timeVaryingUniformFixedValuePointPatchField
{
// Private data
//- file containing time/uniformFixedValue
fileName timeDataFile_;
//- the time series being used, including the bounding treatment
timeSeries<Type> timeSeries_;
interpolationTable<Type> timeSeries_;
//- interpolate the value at the current time
Type currentValue();
public:
......@@ -138,14 +133,8 @@ public:
// Access
//- Return the out-of-bounds treatment as a word
word timeBounding() const
{
return timeSeries_.bounding();
}
//- Return the time series used
const timeSeries<Type>& timeData() const
const interpolationTable<Type>& timeSeries() const
{
return timeSeries_;
}
......
......@@ -24,151 +24,207 @@ License
\*---------------------------------------------------------------------------*/
#include "timeSeries.H"
#include "Istream.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
#include "interpolationTable.H"
#include "IFstream.H"
#include "objectRegistry.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<typename T>
Foam::timeSeries<T>::timeSeries(const bounds bound)
template<class Type>
Foam::interpolationTable<Type>::interpolationTable()
:
List<Tuple2<scalar, T> >(),
bounding_(bound)
List<Tuple2<scalar, Type> >(),
dict_(dictionary::null),
boundAction_(interpolationTable::WARN),
fileName_("undefined_fileName")
{}
template<typename T>
Foam::timeSeries<T>::timeSeries(const word& bound)
template<class Type>
Foam::interpolationTable<Type>::interpolationTable
(
const objectRegistry& obr,
const dictionary& dict
)
:
List<Tuple2<scalar, T> >(),
bounding_(timeSeries::WARN)
List<Tuple2<scalar, Type> >(),
dict_(dict),
boundAction_(wordToBoundAction(dict.lookup("boundAction"))),
fileName_(dict.lookup("fileName"))
{
bounding(bound);
}
fileName_.expand();
// Correct for relative path
if (fileName_[0] != '/')
{
fileName_ = obr.db().path()/fileName_;
}
template<typename T>
Foam::timeSeries<T>::timeSeries(Istream& is, const bounds bound)
:
List<Tuple2<scalar, T> >(is),
bounding_(bound)
{}
// Read data from file
IFstream(fileName_)() >> *this;
// Check that the data is okay
check();
template<typename T>
Foam::timeSeries<T>::timeSeries(Istream& is, const word& bound)
:
List<Tuple2<scalar, T> >(is),
bounding_(timeSeries::WARN)
{
bounding(bound);
if (this->size() == 0)
{
FatalErrorIn
(
"Foam::interpolationTable<Type>::interpolationTable"
"(const dictionary& dict)"
) << "table is empty" << nl
<< exit(FatalError);
}
}
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
template<class Type>
Foam::interpolationTable<Type>::interpolationTable
(
const interpolationTable& interpTable
)
:
List<Tuple2<scalar, Type> >(interpTable),
dict_(interpTable.dict_),
boundAction_(interpTable.boundAction_),
fileName_(interpTable.fileName_)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<typename T>
Foam::timeSeries<T>::~timeSeries()
template<class Type>
Foam::interpolationTable<Type>::~interpolationTable()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<typename T>
Foam::word Foam::timeSeries<T>::bounding() const
template<class Type>
Foam::word Foam::interpolationTable<Type>::boundActionToWord
(
const boundActions& bound
) const
{
word enumName("warn");
switch (bounding_)
switch (bound)
{
case timeSeries::ERROR:
case interpolationTable::ERROR:
{
enumName = "error";
break;
case timeSeries::WARN:
}
case interpolationTable::WARN:
{
enumName = "warn";
break;
case timeSeries::CLAMP:
}
case interpolationTable::CLAMP:
{
enumName = "clamp";
break;
case timeSeries::REPEAT:
}
case interpolationTable::REPEAT:
{
enumName = "repeat";
break;
}
}
return enumName;
}
template<typename T>
void Foam::timeSeries<T>::bounding(const word& bound)
template<class Type>
typename Foam::interpolationTable<Type>::boundActions
Foam::interpolationTable<Type>::wordToBoundAction
(
const word& bound
) const
{
if (bound == "error")
{
bounding_ = timeSeries::ERROR;
return interpolationTable::ERROR;
}
else if (bound == "warn")
{
bounding_ = timeSeries::WARN;
return interpolationTable::WARN;
}
else if (bound == "clamp")
{
bounding_ = timeSeries::CLAMP;
return interpolationTable::CLAMP;
}
else if (bound == "repeat")
{
bounding_ = timeSeries::REPEAT;
return interpolationTable::REPEAT;
}
else
{
WarningIn("Foam::timeSeries<T>::boundingEnum(const word&)")
<< "bad bounding specifier " << bound << " using 'warn'" << endl;
WarningIn
(
"Foam::interpolationTable<Type>::wordToBoundAction(const word&)"
) << "bad bounding specifier " << bound << " using 'warn'" << endl;
bounding_ = timeSeries::WARN;
return interpolationTable::WARN;
}
}
template<typename T>
void Foam::timeSeries<T>::check() const
template<class Type>
void Foam::interpolationTable<Type>::check() const
{
label n = size();
scalar prevTime = List<Tuple2<scalar, T> >::operator[](0).first();
scalar prevValue = List<Tuple2<scalar, Type> >::operator[](0).first();
for (label i = 1; i < n; ++i)
for (label i=1; i<n; ++i)
{
const scalar currTime = List<Tuple2<scalar, T> >::operator[](i).first();
const scalar currValue =
List<Tuple2<scalar, Type> >::operator[](i).first();
// avoid duplicate times (divide-by-zero error)
if (currTime <= prevTime)
// avoid duplicate values (divide-by-zero error)
if (currValue <= prevValue)
{
FatalErrorIn
(
"Foam::timeSeries<T>::checkOrder() const"
) << "out-of-order time: "
<< currTime << " at index " << i << nl
"Foam::interpolationTable<Type>::checkOrder() const"
) << "out-of-order value: "
<< currValue << " at index " << i << nl
<< exit(FatalError);
}
prevTime = currTime;
prevValue = currValue;
}
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class Type>
typename Foam::interpolationTable<Type>::boundActions
Foam::interpolationTable<Type>::boundAction
(
const boundActions& bound
)
{
boundActions prev = boundAction_;
boundAction_ = bound;
return prev;
}
template<typename T>
const Foam::Tuple2<Foam::scalar, T>&
Foam::timeSeries<T>::operator[](const label i) const
template<class Type>
void Foam::interpolationTable<Type>::write(Ostream& os) const
{
os.writeKeyword("fileName")
<< fileName_ << token::END_STATEMENT << nl;
os.writeKeyword("boundAction")
<< boundActionToWord(boundAction_) << token::END_STATEMENT << nl;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class Type>
const Foam::Tuple2<Foam::scalar, Type>&
Foam::interpolationTable<Type>::operator[](const label i) const
{
label ii = i;
label n = size();
......@@ -179,155 +235,183 @@ Foam::timeSeries<T>::operator[](const label i) const
}
else if (ii < 0)
{
switch (bounding_)
switch (boundAction_)
{
case timeSeries::ERROR:
case interpolationTable::ERROR:
{
FatalErrorIn
(
"Foam::timeSeries<T>::operator[](const label) const"
"Foam::interpolationTable<Type>::operator[]"
"(const label) const"
) << "index (" << ii << ") underflow" << nl
<< exit(FatalError);
break;
case timeSeries::WARN:
}
case interpolationTable::WARN:
{
WarningIn
(
"Foam::timeSeries<T>::operator[](const label) const"
"Foam::interpolationTable<Type>::operator[]"
"(const label) const"
) << "index (" << ii << ") underflow" << nl
<< " Continuing with the first entry"
<< endl;
// fall-through to 'CLAMP'
case timeSeries::CLAMP:
}
case interpolationTable::CLAMP:
{
ii = 0;
break;
case timeSeries::REPEAT:
}
case interpolationTable::REPEAT:
{
while (ii < 0)
{
ii += n;
}
break;
}
}
}
else if (ii >= n)
{
switch (bounding_)
switch (boundAction_)
{
case timeSeries::ERROR:
case interpolationTable::ERROR:
{
FatalErrorIn
(
"Foam::timeSeries<T>::operator[](const label) const"
"Foam::interpolationTable<Type>::operator[]"
"(const label) const"
) << "index (" << ii << ") overflow" << nl
<< exit(FatalError);
break;
case timeSeries::WARN:
}
case interpolationTable::WARN:
{
WarningIn
(
"Foam::timeSeries<T>::operator[](const label) const"
"Foam::interpolationTable<Type>::operator[]"
"(const label) const"
) << "index (" << ii << ") overflow" << nl
<< " Continuing with the last entry"
<< endl;
// fall-through to 'CLAMP'
case timeSeries::CLAMP:
}
case interpolationTable::CLAMP:
{
ii = n - 1;
break;
case timeSeries::REPEAT:
}
case interpolationTable::REPEAT:
{
while (ii >= n)
{
ii -= n;
}
break;
}
}
}
return List<Tuple2<scalar, T> >::operator[](ii);
return List<Tuple2<scalar, Type> >::operator[](ii);
}
template<typename T>
T Foam::timeSeries<T>::operator()(const scalar timeValue) const
template<class Type>
Type Foam::interpolationTable<Type>::operator()(const scalar value) const
{
label n = size();
if (n <= 1)
{
return List<Tuple2<scalar, T> >::operator[](0).second();
return List<Tuple2<scalar, Type> >::operator[](0).second();
}
scalar minTime = List<Tuple2<scalar, T> >::operator[](0).first();
scalar maxTime = List<Tuple2<scalar, T> >::operator[](n-1).first();
scalar lookupTime = timeValue;
scalar minLimit = List<Tuple2<scalar, Type> >::operator[](0).first();
scalar maxLimit = List<Tuple2<scalar, Type> >::operator[](n-1).first();
scalar lookupValue = value;
if (lookupTime < minTime)
if (lookupValue < minLimit)
{
switch (bounding_)
switch (boundAction_)
{
case timeSeries::ERROR:
case interpolationTable::ERROR:
{
FatalErrorIn
(
"Foam::timeSeries<T>::operator[](const scalar) const"
) << "time (" << lookupTime << ") underflow" << nl
"Foam::interpolationTable<Type>::operator[]"