Merge branch 'feature-Function1-fvSolution' into 'develop'

ENH: fvSolution: allow Function1 for all scalars

See merge request Development/openfoam!497
This commit is contained in:
Mark Olesen
2021-11-10 19:06:49 +00:00
6 changed files with 219 additions and 34 deletions

View File

@ -27,6 +27,8 @@ License
\*---------------------------------------------------------------------------*/
#include "solution.H"
#include "HashPtrTable.H"
#include "Function1.H"
#include "Time.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -55,23 +57,27 @@ void Foam::solution::read(const dictionary& dict)
if (dict.found("relaxationFactors"))
{
const dictionary& relaxDict(dict.subDict("relaxationFactors"));
const dictionary& relaxDict = dict.subDict("relaxationFactors");
if (relaxDict.found("fields") || relaxDict.found("equations"))
{
if (relaxDict.found("fields"))
{
fieldRelaxDict_ = relaxDict.subDict("fields");
fieldRelaxCache_.clear();
}
if (relaxDict.found("equations"))
{
eqnRelaxDict_ = relaxDict.subDict("equations");
eqnRelaxCache_.clear();
}
}
else
{
// backwards compatibility
fieldRelaxDict_.clear();
fieldRelaxCache_.clear();
for (const word& e : relaxDict.toc())
{
@ -85,17 +91,38 @@ void Foam::solution::read(const dictionary& dict)
{
fieldRelaxDict_.add(e, value);
}
}
eqnRelaxDict_ = relaxDict;
eqnRelaxCache_.clear();
}
fieldRelaxDefault_ =
fieldRelaxDict_.getOrDefault<scalar>("default", 0);
eqnRelaxDefault_ =
eqnRelaxDict_.getOrDefault<scalar>("default", 0);
fieldRelaxDefault_ = Function1<scalar>::NewIfPresent
(
"default",
fieldRelaxDict_
);
if (!fieldRelaxDefault_)
{
fieldRelaxDefault_.reset
(
new Function1Types::Constant<scalar>("default", 0)
);
}
eqnRelaxDefault_ = Function1<scalar>::NewIfPresent
(
"default",
eqnRelaxDict_
);
if (!eqnRelaxDefault_)
{
eqnRelaxDefault_.reset
(
new Function1Types::Constant<scalar>("default", 0)
);
}
DebugInfo
<< "Relaxation factors:" << nl
@ -141,8 +168,6 @@ Foam::solution::solution
caching_(false),
fieldRelaxDict_(),
eqnRelaxDict_(),
fieldRelaxDefault_(0),
eqnRelaxDefault_(0),
solvers_()
{
if
@ -157,6 +182,13 @@ Foam::solution::solution
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
// A non-default destructor since we had incomplete types in the header
Foam::solution::~solution()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::label Foam::solution::upgradeSolverDict
@ -257,11 +289,17 @@ Foam::scalar Foam::solution::fieldRelaxationFactor(const word& name) const
if (fieldRelaxDict_.found(name))
{
return fieldRelaxDict_.get<scalar>(name);
return Function1<scalar>::New
(
fieldRelaxCache_, // cache
name,
fieldRelaxDict_,
keyType::REGEX
)().value(time().timeOutputValue());
}
else if (fieldRelaxDefault_ > SMALL)
else if (fieldRelaxDefault_)
{
return fieldRelaxDefault_;
return fieldRelaxDefault_().value(time().timeOutputValue());
}
FatalIOErrorInFunction(fieldRelaxDict_)
@ -279,11 +317,17 @@ Foam::scalar Foam::solution::equationRelaxationFactor(const word& name) const
if (eqnRelaxDict_.found(name))
{
return eqnRelaxDict_.get<scalar>(name);
return Function1<scalar>::New
(
eqnRelaxCache_, // cache
name,
eqnRelaxDict_,
keyType::REGEX
)().value(time().timeOutputValue());
}
else if (eqnRelaxDefault_ > SMALL)
else if (eqnRelaxDefault_)
{
return eqnRelaxDefault_;
return eqnRelaxDefault_().value(time().timeOutputValue());
}
FatalIOErrorInFunction(eqnRelaxDict_)

View File

@ -39,12 +39,16 @@ SourceFiles
#define solution_H
#include "IOdictionary.H"
#include "HashPtrTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward Declarations
template<class Type> class Function1;
/*---------------------------------------------------------------------------*\
Class solution Declaration
\*---------------------------------------------------------------------------*/
@ -64,14 +68,20 @@ class solution
//- Dictionary of relaxation factors for all the fields
dictionary fieldRelaxDict_;
//- Cache of Function1s in above dictionary
mutable HashPtrTable<Function1<scalar>> fieldRelaxCache_;
//- Dictionary of relaxation factors for all the equations
dictionary eqnRelaxDict_;
//- Cache of Function1s in above dictionary
mutable HashPtrTable<Function1<scalar>> eqnRelaxCache_;
//- Optional default relaxation factor for all the fields
scalar fieldRelaxDefault_;
autoPtr<Function1<scalar>> fieldRelaxDefault_;
//- Optional default relaxation factor for all the equations
scalar eqnRelaxDefault_;
autoPtr<Function1<scalar>> eqnRelaxDefault_;
//- Dictionary of solver parameters for all the fields
dictionary solvers_;
@ -125,6 +135,10 @@ public:
{}
//- Destructor
virtual ~solution();
// Member Functions
// Access
@ -132,15 +146,6 @@ public:
//- Return true if the given field should be cached
bool cache(const word& name) const;
//- Helper for printing cache message
template<class FieldType>
static void cachePrintMessage
(
const char* message,
const word& name,
const FieldType& vf
);
//- Return true if the relaxation factor is given for the field
bool relaxField(const word& name) const;
@ -168,6 +173,18 @@ public:
//- Read the solution dictionary
bool read();
// Other
//- Helper for printing cache message
template<class FieldType>
static void cachePrintMessage
(
const char* message,
const word& name,
const FieldType& vf
);
};

View File

@ -27,8 +27,7 @@ License
#include "solution.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class FieldType>
void Foam::solution::cachePrintMessage
@ -48,7 +47,4 @@ void Foam::solution::cachePrintMessage
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2018-2020 OpenCFD Ltd.
Copyright (C) 2018-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -76,6 +76,7 @@ SourceFiles
#include "function1Base.H"
#include "Field.H"
#include "HashPtrTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -191,6 +192,32 @@ public:
);
// Caching Selectors - accept wildcards in dictionary
//- Selector with external storage of Function1.
//- This also allows wildcard matches in a dictionary
static refPtr<Function1<Type>> New
(
HashPtrTable<Function1<Type>>& cache,
const word& entryName,
const dictionary& dict,
enum keyType::option matchOpt = keyType::LITERAL,
const bool mandatory = true
);
/// //- Selector with external storage of Function1.
/// //- This also allows wildcard matches in a dictionary.
/// // If the default value is used, stores an entry as "default"
/// static refPtr<Function1<Type>> NewOrDefault
/// (
/// HashPtrTable<Function1<Type>>& cache,
/// const word& entryName,
/// const dictionary& dict,
/// const Type& deflt,
/// enum keyType::option matchOpt = keyType::LITERAL
/// );
//- Destructor
virtual ~Function1() = default;

View File

@ -209,4 +209,104 @@ Foam::Function1<Type>::NewIfPresent
}
template<class Type>
Foam::refPtr<Foam::Function1<Type>>
Foam::Function1<Type>::New
(
HashPtrTable<Function1<Type>>& cache,
const word& entryName,
const dictionary& dict,
enum keyType::option matchOpt,
const bool mandatory
)
{
// Use the dictionary to find the keyword (allowing wildcards).
// Alternative would be to have
// a HashTable where the key type uses a wildcard match
refPtr<Function1<Type>> fref; // return value
// Try for direct cache hit
fref.cref(cache.get(entryName));
if (fref)
{
return fref;
}
// Lookup from dictionary
const entry* eptr = dict.findEntry(entryName, matchOpt);
if (eptr)
{
// Use keyword (potentially a wildcard) instead of entry name
const auto& kw = eptr->keyword();
// Try for a cache hit
fref.cref(cache.get(kw));
if (!fref)
{
// Create new entry
auto fauto
(
Function1<Type>::New
(
kw,
eptr, // Already resolved
dict,
word::null,
mandatory
)
);
if (fauto)
{
// Cache the newly created function
fref.cref(fauto.get());
cache.set(kw, fauto);
}
}
}
if (mandatory && !fref)
{
FatalIOErrorInFunction(dict)
<< "No match for " << entryName << nl
<< exit(FatalIOError);
}
return fref;
}
/// template<class Type>
/// Foam::refPtr<Foam::Function1<Type>>
/// Foam::Function1<Type>::NewOrDefault
/// (
/// HashPtrTable<Function1<Type>>& cache,
///
/// const word& entryName,
/// const dictionary& dict,
/// const Type& deflt,
/// enum keyType::option matchOpt
/// )
/// {
/// auto fref
/// (
/// Function1<Type>::New(entryName, dict, cache, matchOpt, false)
/// );
///
/// if (!fref)
/// {
/// fref.reset(new Function1Types::Constant<Type>("default", deflt));
/// }
///
/// return fref;
/// }
// ************************************************************************* //

View File

@ -79,9 +79,10 @@ relaxationFactors
}
equations
{
"U.*" 0.7;
"e.*" 0.7;
"(k|epsilon).*" 0.7;
// "(U|e|k|epsilon).*" 0.7;
// Demonstrate some ramping
"(U|e|k|epsilon).*" table ((0 0.4) (0.5 0.7));
}
}