41namespace functionObjects
55 { actionType::opNone,
"none" },
56 { actionType::opNew,
"new" },
57 { actionType::opModify,
"modify" },
89 field.correctBoundaryConditions();
92 for (
auto& pf :
field.boundaryFieldRef())
96 pf = pf.patchInternalField();
113 field.correctBoundaryConditions();
131template<
class FieldType>
138 <<
" (" << FieldType::typeName <<
')' <<
endl;
167 for (
const word& fieldName : fieldSet_)
170 const auto* ptr = mesh_.cfindObject<
regIOobject>(fieldName);
177 << ptr->name() <<
" (" << ptr->type()
178 <<
") already in database" <<
endl;
186 mesh_.time().timeName(),
195 &&
io.hasHeaderClass()
198 loadField<scalar>(
io)
199 || loadField<vector>(
io)
200 || loadField<sphericalTensor>(
io)
201 || loadField<symmTensor>(
io)
202 || loadField<tensor>(
io)
213 <<
"readFields : failed to load " << fieldName <<
endl;
221template<
class GeoField>
225 const GeoField& evaluated,
229 label numValuesChanged = 0;
232 if (fieldMask.
empty())
235 numValuesChanged =
output.size();
237 output.primitiveFieldRef() = evaluated;
241 auto& internal =
output.primitiveFieldRef();
247 internal[idx] = evaluated[idx];
254 forAll(evaluated.boundaryField(), patchi)
256 auto& pf =
output.boundaryFieldRef()[patchi];
258 if (pf.patch().coupled())
260 pf == evaluated.boundaryField()[patchi];
266 if (action_ == actionType::opModify &&
log)
272 if (numValuesChanged == numTotal)
278 Info<< numValuesChanged <<
" of ";
280 Info<< numTotal <<
" values (field: "
287 output.dimensions().reset(dimensions_);
301 const bool loadFromFiles
314 hasDimensions_(false),
315 loadFromFiles_(loadFromFiles)
333 case actionType::opNone:
337 case actionType::opNew:
339 return scopedName(fieldName_);
341 case actionType::opModify:
355 action_ = actionNames_.getOrDefault(
"action",
dict, actionType::opNew);
357 fieldName_ =
dict.get<
word>(
"field");
358 const word fldName = fieldName();
361 <<
" action = " << actionNames_[action_] <<
nl
362 <<
" field = " << fldName <<
nl;
367 preloadFields_.clear();
368 dict.readIfPresent(
"readFields", preloadFields_);
372 case actionType::opNone:
377 case actionType::opModify:
380 maskExpr_.readEntry(
"fieldMask",
dict,
false);
383 case actionType::opNew:
386 valueExpr_.readEntry(
"expression",
dict);
391 autowrite_ =
dict.getOrDefault(
"autowrite",
false);
392 store_ =
dict.getOrDefault(
"autowrite",
true);
396 hasDimensions_ = dimensions_.readEntry(
"dimensions",
dict,
false);
398 if (action_ == actionType::opNew)
402 Log <<
" no 'dimensions' : treat '" << fldName
403 <<
"' as dimensionless" <<
endl;
409 hasDimensions_ =
false;
413 if (action_ == actionType::opNone)
415 driver_.reset(
nullptr);
424 driver_->setSearchBehaviour
438 driver_->readDict(dict_);
448 if (!driver_ || action_ == actionType::opNone)
454 const word fldName = fieldName();
458 loadFields(preloadFields_);
461 if (action_ == actionType::opModify && loadFromFiles_)
466 auto& driver = *driver_;
470 auto* regIOobjectPtr = mesh_.getObjectPtr<
regIOobject>(fldName);
472 if (action_ == actionType::opModify && !regIOobjectPtr)
477 <<
" missing-field: " << fldName <<
nl
487 (action_ == actionType::opModify)
488 && maskExpr_.size() && maskExpr_ !=
"true" && maskExpr_ !=
"1"
496 driver.parse(maskExpr_);
498 if (driver.isLogical())
500 auto& result = driver.result();
501 if (result.is_bool())
503 fieldMask = result.getResult<
bool>();
504 maskFieldAssoc = driver.fieldAssociation();
510 driver.clearResult();
512 evalFieldMask = (maskFieldAssoc != FieldAssociation::NO_DATA);
517 <<
"field-mask: " << maskExpr_
518 <<
" does not evaluate to a logical expression: "
519 << driver.resultType() <<
nl
521 <<
"contents: " << fieldMask
530 bool applied =
false;
534 driver.clearVariables();
536 driver.parse(valueExpr_);
538 if (evalFieldMask && maskFieldAssoc != driver.fieldAssociation())
541 <<
"Mismatch between field-mask geometric type ("
543 <<
"expression geometric type ("
546 <<
"Expression: " << valueExpr_ <<
nl
547 <<
"Field-mask: " << maskExpr_ <<
nl
556 toutputField.
reset(driver.dupZeroField());
560 toutputField->rename(fldName);
571 regIOobjectPtr = toutputField.
get();
575 if (toutputField->checkIn() && toutputField->store())
581 regIOobjectPtr = mesh_.getObjectPtr<
regIOobject>(fldName);
593 <<
" missing-field: " << fldName <<
nl
609 switch (driver.fieldAssociation())
612 #define doLocalCode(GeoField) \
615 auto* outPtr = dynamic_cast<GeoField*>(regIOobjectPtr); \
616 const auto* ptr = driver.isResultType<GeoField>(); \
620 applied = setField(*outPtr, *ptr, fieldMask); \
629 case FieldAssociation::VOLUME_DATA:
638 case FieldAssociation::FACE_DATA:
647 case FieldAssociation::POINT_DATA:
664 driver.clearResult();
671 <<
type() <<
' ' << this->
name() <<
": Failed to apply "
672 << actionNames_[action_] <<
" for " << fldName
682 return performAction(
false);
688 return performAction(
true);
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Generic GeometricField class.
Defines the attributes of an object for which implicit objectRegistry management is supported,...
bool isHeaderClass() const
Check if headerClassName() equals Type::typeName.
const word & name() const noexcept
Return the object name.
virtual const fileName & name() const
Return the name of the stream.
virtual bool read()
Re-read model coefficients if they have changed.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
bool empty() const noexcept
True if the UList is empty (ie, size() is zero)
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
T * get() noexcept
Return pointer to managed object without nullptr checking.
T * release() noexcept
Release ownership and return the pointer.
void reset(autoPtr< T > &&other) noexcept
Delete managed object and set to new given pointer.
This boundary condition is not designed to be evaluated; it is assmued that the value is assigned via...
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
The field association for mesh (patch/volume) values.
searchControls
Search/caching controls.
@ SEARCH_REGISTRY
Search registry before disk.
@ SEARCH_FILES
Search disk (eg, standalone app)
Driver for volume, surface, point field expressions.
Abstract base-class for Time/database function objects.
Function object that generates or modifies a field based on expressions.
bool setField(GeoField &output, const GeoField &evaluated, const boolField &cond)
bool performAction(bool doWrite)
virtual ~fvExpressionField()
Destructor.
virtual bool read(const dictionary &dict)
Read the data.
bool loadAndStore(const IOobject &io)
Attempt load from io, store on database if successful.
static const Enum< actionType > actionNames_
Action type names.
actionType
Action type enumeration.
label loadFields(const UList< word > &fieldSet_)
Attempt to load specified fields.
virtual bool execute()
Execute.
virtual word fieldName() const
Qualified/unqualified field name (depends on action)
virtual bool write()
Write.
bool loadField(const IOobject &io)
Forward to loadAndStore for supported types.
Specialization of Foam::functionObject for an Foam::fvMesh, providing a reference to the Foam::fvMesh...
const fvMesh & mesh_
Reference to the fvMesh.
Computes the natural logarithm of an input volScalarField.
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
A class for handling words, derived from Foam::string.
static const word null
An empty word.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, false)
#define DebugInfo
Report an information message using Foam::Info.
#define WarningInFunction
Report a warning using Foam::Warning.
@ VOLUME_DATA
Volume data.
List< word > wordList
A List of words.
const TargetType * isA(const Type &t)
Check if dynamic_cast to TargetType is possible.
messageStream Info
Information stream (stdout output on master, null elsewhere)
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Ostream & endl(Ostream &os)
Add newline and flush stream.
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
static Ostream & output(Ostream &os, const IntRange< T > &range)
static void doCorrectBoundaryConditions(bool correctBCs, VolumeField< Type > &field)
word fieldGeoType(const expressions::FieldAssociation geoType)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce (copy) and return value.
errorManipArg< error, int > exit(error &err, const int errNo=1)
constexpr char nl
The newline '\n' character (0x0a)
#define forAll(list, i)
Loop across all elements in list.
#define doLocalCode(GeoField)