45 { volumeModeType::vmAbsolute,
"absolute" },
46 { volumeModeType::vmSpecific,
"specific" },
53void Foam::fv::SemiImplicitSource<Type>::setFieldCoeffs
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);
120 new expressions::volumeExprDriver(mesh_, exprDict)
128 Function1<Type>::New(keyExplicit, subDict, &mesh_)
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);
156 new expressions::volumeExprDriver(mesh_, 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
203 <<
exit(FatalIOError);
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)
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....
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Generic templated field type that is much like a Foam::List except that it is expected to hold numeri...
Generic GeometricField class.
static const this_type & null() noexcept
@ NO_REGISTER
Do not request registration (bool: false).
A List with indirect addressing. Like IndirectList but does not store addressing.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Dimension set for the base types, which can be used to implement rigorous dimension checking for alge...
static bool checking() noexcept
True if dimension checking is enabled (the usual default).
Generic dimensioned Type class.
const Type & value() const noexcept
Return const reference to value.
A special matrix type and solver, designed for finite volume solutions of scalar equations....
const dimensionSet & dimensions() const noexcept
const GeometricField< Type, fvPatchField, volMesh > & psi(const label i=0) const
Return psi.
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 const Enum< volumeModeType > volumeModeTypeNames_
Names for volumeModeType.
virtual bool read(const dictionary &dict)
Read source dictionary.
SemiImplicitSource(const word &name, const word &modelType, const dictionary &dict, const fvMesh &mesh)
Construct from components.
volumeModeType
Options for the volume mode type.
labelList cells_
Set of cells to apply source to.
virtual bool read(const dictionary &dict)
Read source dictionary.
cellSetOption(const word &name, const word &modelType, const dictionary &dict, const fvMesh &mesh)
Construct from components.
scalar V_
Sum of cell volumes.
bool useSubMesh() const noexcept
True if sub-selection should be used.
const word & name() const noexcept
Return const access to the source name.
const fvMesh & mesh_
Reference to the mesh database.
wordList fieldNames_
Field names to apply source to - populated by derived models.
dictionary coeffs_
Dictionary containing source coefficients.
const fvMesh & mesh() const noexcept
Return const access to the mesh database.
const word name_
Source name.
A traits class, which is primarily used for primitives and vector-space.
A class for managing temporary objects.
bool valid() const noexcept
Identical to good(), or bool operator.
T & ref() const
Return non-const reference to the contents of a non-null managed pointer.
A class for handling words, derived from Foam::string.
const volScalarField & psi
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
A special matrix type and solver, designed for finite volume solutions of scalar equations.
Calculate the finiteVolume matrix for implicit and explicit sources.
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Namespace for handling debugging switches.
Namespace for finite-volume.
zeroField SuSp(const Foam::zero, const GeometricField< Type, fvPatchField, volMesh > &)
A no-op source.
GeometricField< scalar, fvPatchField, volMesh > volScalarField
bool equal(const T &a, const T &b)
Compare two values for equality.
messageStream Info
Information stream (stdout output on master, null elsewhere).
Ostream & endl(Ostream &os)
Add newline and flush stream.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
static constexpr const zero Zero
Global zero (0).
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
const dimensionSet dimVolume(pow3(dimLength))
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
bool notNull(const T *ptr) noexcept
True if ptr is not a pointer (of type T) to the nullObject.
errorManipArg< error, int > exit(error &err, const int errNo=1)
constexpr char nl
The newline '\n' character (0x0a).