45 { volumeModeType::vmAbsolute,
"absolute" },
46 { volumeModeType::vmSpecific,
"specific" },
55 const dictionary&
dict,
56 const word& keyExplicit,
57 const word& keyImplicit
62 fieldNames_.resize_nocopy(
count);
71 driverSu_.reserve(
count);
72 driverSp_.reserve(
count);
76 valueExprSu_.reserve(
count);
77 valueExprSp_.reserve(
count);
79 fv::option::resetApplied();
82 Tuple2<Type, scalar> sourceRates;
86 for (
const entry& dEntry :
dict)
88 const word& fieldName = dEntry.keyword();
99 (eptr = subDict.findEntry(keyExplicit, keyType::LITERAL))
108 && eptr->dict().readEntry(
"type", modelType, keyType::LITERAL)
109 && (modelType ==
"exprField")
114 valueExprSu_.emplace_set(fieldName);
115 valueExprSu_[fieldName].readEntry(
"expression", exprDict);
135 (eptr = subDict.findEntry(keyImplicit, keyType::LITERAL))
144 && eptr->dict().readEntry(
"type", modelType, keyType::LITERAL)
145 && (modelType ==
"exprField")
150 valueExprSp_.emplace_set(fieldName);
151 valueExprSp_[fieldName].readEntry(
"expression", exprDict);
164 Function1<scalar>::New(keyImplicit, subDict, &mesh_)
173 dEntry.readEntry(sourceRates);
180 new Function1Types::Constant<Type>
189 new Function1Types::Constant<scalar>
200 <<
"Require at least one of " 201 << keyExplicit <<
'/' << keyImplicit <<
" entries for " 202 <<
"field: " << fieldName <<
endl 206 fieldNames_[
count] = fieldName;
218 const word& modelType,
224 volumeMode_(vmAbsolute),
255 <<
">::addSup for source " << name_ <<
endl;
261 const word& fieldName = fieldNames_[fieldi];
263 const scalar tmVal = mesh_.time().timeOutputValue();
270 const auto iter1 = valueExprSu_.cfind(fieldName);
271 const auto iter2 = Su_.cfind(fieldName);
277 const auto& valueExpr = iter1.val();
285 Info<<
"Explicit expression source:" <<
nl 287 << valueExpr.c_str() <<
nl 291 auto& driver = *(driverSu_[fieldName]);
293 driver.clearVariables();
297 driver.addContextObject(
"rho", &
rho);
303 driver.parse(valueExpr);
308 const ExprResultType* ptr =
309 driver.template isResultType<ExprResultType>();
314 <<
"Expression for Su " << fieldName
315 <<
" evaluated to <" << driver.resultType()
316 <<
"> but expected <" << ExprResultType::typeName
320 else if (ptr->size() != mesh_.nCells())
323 <<
"Expression for Su " << fieldName
324 <<
" evaluated to " << ptr->size()
325 <<
" instead of " << mesh_.nCells() <<
" values" <<
endl 331 driver.removeContextObject(&
rho);
334 const Field<Type>& exprFld = ptr->primitiveField();
338 name_ + fieldName +
"Su",
341 dimensioned<Type>(SuDims,
Zero)
344 if (this->useSubMesh())
346 for (
const label celli : cells_)
348 tsu.
ref()[celli] = exprFld[celli]/VDash_;
353 tsu.
ref().field() = exprFld;
355 if (!
equal(VDash_, 1))
357 tsu.
ref().field() /= VDash_;
361 else if (iter2.good() && iter2.val()->good())
363 const dimensioned<Type> SuValue
367 iter2.val()->value(tmVal)/VDash_
370 if (
mag(SuValue.value()) <= ROOTVSMALL)
374 else if (this->useSubMesh())
378 name_ + fieldName +
"Su",
381 dimensioned<Type>(SuDims,
Zero)
383 UIndirectList<Type>(tsu.
ref(), cells_) = SuValue.value();
400 const auto iter1 = valueExprSp_.cfind(fieldName);
401 const auto iter2 = Sp_.cfind(fieldName);
403 tmp<DimensionedField<scalar, volMesh>> tsp;
407 const auto& valueExpr = iter1.val();
413 Info<<
"Implicit expression source:" <<
nl 415 << valueExpr.c_str() <<
nl 419 auto& driver = *(driverSp_[fieldName]);
421 driver.clearVariables();
425 driver.addContextObject(
"rho", &
rho);
431 driver.parse(valueExpr);
436 const ExprResultType* ptr =
437 driver.template isResultType<ExprResultType>();
442 <<
"Expression for Sp " << fieldName
443 <<
" evaluated to <" << driver.resultType()
444 <<
"> but expected <" << ExprResultType::typeName
448 else if (ptr->size() != mesh_.nCells())
451 <<
"Expression for Sp " << fieldName
452 <<
" evaluated to " << ptr->size()
453 <<
" instead of " << mesh_.nCells() <<
" values" <<
endl 459 driver.removeContextObject(&
rho);
462 const Field<scalar>& exprFld = ptr->primitiveField();
466 name_ + fieldName +
"Sp",
469 dimensioned<scalar>(SpDims,
Zero)
472 if (this->useSubMesh())
474 for (
const label celli : cells_)
476 tsp.ref()[celli] = exprFld[celli]/VDash_;
481 tsp.ref().field() = exprFld;
483 if (!
equal(VDash_, 1))
485 tsp.ref().field() /= VDash_;
489 else if (iter2.good() && iter2.val()->good())
491 const dimensioned<scalar> SpValue
495 iter2.val()->value(tmVal)/VDash_
498 if (
mag(SpValue.value()) <= ROOTVSMALL)
502 else if (this->useSubMesh())
506 name_ + fieldName +
"Sp",
509 dimensioned<scalar>(SpDims,
Zero)
511 UIndirectList<scalar>(tsp.ref(), cells_) = SpValue.value();
534 volumeMode_ = volumeModeTypeNames_.get(
"volumeMode", coeffs_);
537 if (volumeMode_ == vmAbsolute)
bool valid() const noexcept
Identical to good(), or bool operator.
errorManipArg< error, int > exit(error &err, const int errNo=1)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
bool equal(const T &a, const T &b)
Compare two values for equality.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
T & ref() const
Return non-const reference to the contents of a non-null managed pointer.
constexpr char nl
The newline '\n' character (0x0a)
Ostream & endl(Ostream &os)
Add newline and flush stream.
A traits class, which is primarily used for primitives and vector-space.
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
virtual bool read(const dictionary &dict)
Read source dictionary.
virtual bool read(const dictionary &dict)
Read source dictionary.
GeometricField< scalar, fvPatchField, volMesh > volScalarField
const dimensionSet dimVolume(pow3(dimLength))
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Dimension set for the base types, which can be used to implement rigorous dimension checking for alge...
const GeometricField< Type, fvPatchField, volMesh > & psi(const label i=0) const
Return psi.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
volumeExpr::parseDriver volumeExprDriver
Typedef for volumeExpr parseDriver.
static const Enum< volumeModeType > volumeModeTypeNames_
Names for volumeModeType.
A class for handling words, derived from Foam::string.
static const GeometricField< scalar, fvPatchField, volMesh > & null() noexcept
Return a null GeometricField (reference to a nullObject).
A special matrix type and solver, designed for finite volume solutions of scalar equations. Face addressing is used to make all matrix assembly and solution loops vectorise.
zeroField SuSp(const Foam::zero, const GeometricField< Type, fvPatchField, volMesh > &)
A no-op source.
int debug
Static debugging option.
static bool checking() noexcept
True if dimension checking is enabled (the usual default)
const dimensionSet & dimensions() const noexcept
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
volumeModeType
Options for the volume mode type.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
bool notNull(const T *ptr) noexcept
True if ptr is not a pointer (of type T) to the nullObject.
Mesh data needed to do the Finite Volume discretisation.
virtual void addSup(fvMatrix< Type > &eqn, const label fieldi)
Add explicit contribution to incompressible equation.
static tmp< DimensionedField< Type, GeoMesh > > New(const word &name, IOobjectOption::registerOption regOpt, const Mesh &mesh, const dimensionSet &dims, const Field< Type > &iField)
Return tmp field (NO_READ, NO_WRITE) from name, mesh, dimensions, copy of internal field...
A special matrix type and solver, designed for finite volume solutions of scalar equations.
messageStream Info
Information stream (stdout output on master, null elsewhere)
Intermediate abstract class for handling cell-set options for the derived fvOptions.
const volScalarField & psi
Applies semi-implicit source within a specified region for Type, where <Type>=Scalar/Vector/Spherical...
A class for managing temporary objects.
SemiImplicitSource(const word &name, const word &modelType, const dictionary &dict, const fvMesh &mesh)
Construct from components.
Do not request registration (bool: false)
Calculate the finiteVolume matrix for implicit and explicit sources.
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
static constexpr const zero Zero
Global zero (0)