62 case FieldAssociation::POINT_DATA :
return "points";
break;
63 case FieldAssociation::FACE_DATA :
return "faces";
break;
64 case FieldAssociation::VOLUME_DATA :
return "cells";
break;
72struct setExprFieldsControl
82 IOstreamOption streamOpt;
95 Info<<
"Correcting boundary conditions: " <<
field.name() <<
nl;
96 field.correctBoundaryConditions();
110 Info<<
"Correcting boundary conditions: " <<
field.name() <<
nl;
111 field.correctBoundaryConditions();
125template<
class GeoField>
128 const word& fieldName,
129 const GeoField& evaluated,
134 const setExprFieldsControl& ctrl
137 Info<<
"setField(" << fieldName <<
"): "
140 const auto&
mesh = evaluated.mesh();
147 toutput = GeoField::New
163 mesh.thisDb().time().timeName(),
173 auto& output = toutput.
ref();
175 label numValuesChanged = 0;
178 if (fieldMask.
empty())
181 numValuesChanged = output.size();
183 output.primitiveFieldRef() = evaluated;
187 auto&
internal = output.primitiveFieldRef();
200 forAll(evaluated.boundaryField(), patchi)
202 auto& pf = output.boundaryFieldRef()[patchi];
204 if (pf.patch().coupled())
206 pf == evaluated.boundaryField()[patchi];
215 if (numValuesChanged == numTotal)
221 Info<<
"Set " << numValuesChanged <<
" of ";
223 Info<< numTotal <<
" values" <<
endl;
225 if (ctrl.hasDimensions)
227 Info<<
"Setting dimensions to " << dims <<
endl;
228 output.dimensions().reset(dims);
233 Info<<
"(dry-run): Writing to " << output.name() <<
nl;
237 Info<<
"Writing to " << output.name() <<
nl;
238 output.writeObject(ctrl.streamOpt,
true);
248 const word& fieldName,
255 const setExprFieldsControl& ctrl
262 Info<<
"Set new field: " << fieldName;
269 mesh.thisDb().time().timeName(),
278 <<
"Field '" << fieldName
279 <<
"' seems to be missing. Use 'create'" <<
nl
283 oldFieldType =
io.headerClassName();
285 Info<<
"Modify field: " << fieldName
286 <<
" (type: " << oldFieldType <<
')';
290 Info<<
" time=" <<
mesh.thisDb().time().timeName() <<
nl
291 <<
"Expression:" <<
nl
293 << valueExpr_.c_str() <<
nl
297 (maskExpr_.size() && maskExpr_ !=
"true" && maskExpr_ !=
"1");
301 Info<<
"field-mask:" <<
nl
303 << maskExpr_.c_str() <<
nl
307 if (ctrl.keepPatches)
309 Info<<
"Keeping patches unaltered" <<
endl;
311 else if (!valuePatches.
empty())
314 <<
" to fixed value" <<
endl;
321 driver.setCaching(ctrl.cacheVariables);
323 driver.readDict(
dict);
325 if (ctrl.debugParsing)
327 Info<<
"Parsing expression: " << valueExpr_ <<
"\nand field-mask "
328 << maskExpr_ <<
nl <<
endl;
329 driver.setDebugging(
true,
true);
333 driver.clearVariables();
343 if (ctrl.debugParsing)
345 Info<<
"Parsing field-mask:" << maskExpr_ <<
endl;
348 driver.parse(maskExpr_);
349 if (ctrl.debugParsing)
354 if (driver.isLogical())
356 auto& result = driver.result();
357 if (result.is_bool())
359 fieldMask = result.getResult<
bool>();
360 maskFieldAssoc = driver.fieldAssociation();
366 driver.clearResult();
368 evalFieldMask = (maskFieldAssoc != FieldAssociation::NO_DATA);
373 <<
" mask: " << maskExpr_
374 <<
" does not evaluate to a logical expression: "
375 << driver.resultType() <<
nl
377 <<
"contents: " << fieldMask
382 if (ctrl.debugParsing)
384 Info<<
"Field-mask evaluates to "
389 if (ctrl.debugParsing)
391 Info<<
"Parsing expression:" << valueExpr_ <<
endl;
394 driver.parse(valueExpr_);
396 if (ctrl.debugParsing)
401 if (evalFieldMask && maskFieldAssoc != driver.fieldAssociation())
404 <<
"Mismatch between field-mask geometric type ("
406 <<
"expression geometric type ("
409 <<
"expression: " << valueExpr_ <<
nl
410 <<
"field-mask: " << maskExpr_ <<
nl
415 if (!oldFieldType.empty() && driver.resultType() != oldFieldType)
418 <<
"Inconsistent types: " << fieldName <<
" is "
420 <<
" but the expression evaluates to "
421 << driver.resultType()
425 Info<<
"Dispatch ... " << driver.resultType() <<
nl;
428 bool applied =
false;
429 switch (driver.fieldAssociation())
432 #define doLocalCode(GeoField) \
434 const auto* ptr = driver.isResultType<GeoField>(); \
450 case FieldAssociation::VOLUME_DATA:
459 case FieldAssociation::FACE_DATA:
468 case FieldAssociation::POINT_DATA:
485 <<
"Expression evaluates to an unsupported type: "
486 << driver.resultType() <<
nl <<
nl
487 <<
"Expression " << valueExpr_ <<
nl <<
endl
495int main(
int argc,
char *argv[])
506 "Write in ASCII format instead of the controlDict setting"
512 "Alternative dictionary for setExprFieldsDict"
516 "Evaluate but do not write"
520 "Additional verbosity",
527 "Specify field or fields to preload. Eg, 'T' or '(p T U)'",
534 "The field to create/overwrite"
535 " (command-line operation)",
542 "The expression to evaluate"
543 " (command-line operation)",
550 "The field mask (logical condition) when to apply the expression"
551 " (command-line operation)",
559 "The dimensions for created fields"
560 " (command-line operation)",
567 "Additional debugging information",
573 "Disable caching of expression variables",
580 " (command-line operation)",
586 "Leave patches unaltered"
587 " (command-line operation)",
594 "A list of patches that receive a fixed value"
595 " (command-line operation)",
601 "Provide a zero phi field"
602 " (command-line operation)",
615 "correctResultBoundaryFields",
633 <<
"No times selected." <<
nl
648 const bool useCommandArgs =
args.found(
"field");
652 bool fatalCombination =
false;
654 if (
args.found(
"dict"))
656 fatalCombination =
true;
658 <<
"Cannot specify both dictionary and command-line arguments"
662 if (
args.found(
"create") &&
args.found(
"keepPatches"))
664 fatalCombination =
true;
666 <<
"Cannot specify both 'create' and 'keepPatches'" <<
nl
670 if (!
args.found(
"expression"))
672 fatalCombination =
true;
674 <<
"Missing mandatory 'expression' option'" <<
nl
677 if (fatalCombination)
689 "create",
"keepPatches",
"value-patches",
690 "field-mask",
"expression",
"dimensions"
692 badOptions.retain(
args.options());
694 if (!badOptions.empty())
698 <<
"Using a dictionary. Cannot specify these options:" <<
nl
709 runTime.setTime(times[timei], timei);
719 args.readListIfPresent(
"load-fields", preloadFields);
723 if (
args.found(
"dummy-phi") && !dummyPhi)
725 Info<<
"Adding a dummy phi" <<
endl;
733 mesh.thisDb().time().constant(),
744 if (
args.allowFunctionObjects())
746 runTime.functionObjects().start();
753 Info<<
"Using command-line options for "
754 << fieldName <<
nl <<
endl;
756 setExprFieldsControl ctrl;
758 ctrl.dryRun =
args.dryRun();
759 ctrl.debugParsing =
args.found(
"debug-parser");
760 ctrl.cacheVariables = !
args.found(
"no-variable-caching");
762 ctrl.createNew =
args.found(
"create");
763 ctrl.keepPatches =
args.found(
"keepPatches");
764 ctrl.correctPatches = !
args.found(
"noCorrectPatches");
765 ctrl.correctBCs =
args.found(
"correctResultBoundaryFields");
766 ctrl.hasDimensions =
args.found(
"dimensions");
767 ctrl.streamOpt.format(
runTime.writeFormat());
768 if (
args.found(
"ascii"))
776 args.readIfPresent(
"field-mask", maskExpr_);
779 if (ctrl.hasDimensions)
793 args.getList<
word>(
"value-patches",
false),
798 else if (exprDictPtr)
812 for (
const entry& dEntry : actions)
814 if (!dEntry.isDict())
816 Info<<
"Ignore non-dictionary entry: "
817 << dEntry.keyword() <<
nl;
823 setExprFieldsControl ctrl;
825 ctrl.dryRun =
args.dryRun();
826 ctrl.debugParsing =
args.found(
"debug-parser");
827 ctrl.cacheVariables = !
args.found(
"no-variable-caching");
829 ctrl.createNew =
dict.getOrDefault(
"create",
false);
830 ctrl.keepPatches =
dict.getOrDefault(
"keepPatches",
false);
832 ctrl.correctPatches = !
args.found(
"noCorrectPatches");
833 ctrl.correctBCs =
args.found(
"correctResultBoundaryFields");
834 ctrl.streamOpt.format(
runTime.writeFormat());
835 if (
args.found(
"ascii"))
840 if (ctrl.createNew && ctrl.keepPatches)
843 <<
"Cannot specify both 'create' and 'keepPatches'"
851 "correctResultBoundaryFields",
864 "fieldMask", {{
"condition", 2106}},
879 if (
args.verbose() && !timei)
902 <<
"No command-line or dictionary??" <<
nl <<
endl
Generic GeometricField class.
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
@ NO_REGISTER
Do not request registration (bool: false).
@ NO_READ
Nothing to be read.
@ MUST_READ
Reading required.
@ NO_WRITE
Ignore writing from objectRegistry::writeObject().
Defines the attributes of an object for which implicit objectRegistry management is supported,...
@ ASCII
"ascii" (normal default)
An input stream of tokens.
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
bool empty() const noexcept
True if List is empty (ie, size() is zero).
static void noFunctionObjects(bool addWithOption=false)
Remove '-noFunctionObjects' option and ignore any occurrences.
static void addVerboseOption(const string &usage="", bool advanced=false)
Enable a 'verbose' bool option, with usage information.
static void addDryRunOption(const string &usage, bool advanced=false)
Enable a 'dry-run' bool option, with usage information.
static void addBoolOption(const word &optName, const string &usage="", bool advanced=false)
Add a bool option to validOptions with usage information.
static void addOption(const word &optName, const string ¶m="", const string &usage="", bool advanced=false)
Add an option to validOptions with usage information.
static void addOptionCompat(const word &optName, std::pair< const char *, int > compat)
Specify an alias for the option name.
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
void reset(T *p=nullptr) noexcept
Delete managed object and set to new given pointer.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
ITstream & lookup(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return an entry data stream. FatalIOError if not found, or not a stream.
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry if present, and assign to T val. FatalIOError if it is found and the number of tokens i...
static const dictionary null
An empty dictionary, which is also the parent for all dictionaries.
Dimension set for the base types, which can be used to implement rigorous dimension checking for alge...
static bool checking(bool on) noexcept
Turn dimension checking on/off.
bool readIfPresent(const word &entryName, const dictionary &dict)
Update the dimensions from dictionary entry. FatalIOError if it is found and the number of tokens is ...
A keyword and a list of tokens is an 'entry'.
const keyType & keyword() const noexcept
Return keyword.
The field association for mesh (patch/volume) values.
A variant of Foam::string with expansion of dictionary variables into a comma-separated form.
void trim()
Inplace trim leading and trailing whitespace.
bool readEntry(const word &keyword, const dictionary &dict, IOobjectOption::readOption readOpt=IOobjectOption::MUST_READ)
Read/expand entry with dictionary variables, and strip any embedded C/C++ comments from the input.
Mesh data needed to do the Finite Volume discretisation.
A traits class, which is primarily used for primitives and vector-space.
A simple field-loader, as per the readFields function object.
bool execute(const UList< word > &fieldNames)
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
static void addOptions(const bool constant=true, const bool withZero=false)
Add timeSelector options to argList::validOptions.
static instantList select0(Time &runTime, const argList &args)
Return the set of times selected based on the argList options and also set the runTime to the first i...
A class for managing temporary objects.
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
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.
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Operations involving expressions.
const word dictName("faMeshDefinition")
#define doLocalCode(FieldType, Variable)
return returnReduce(nRefine-oldNRefine, sumOp< label >())
volumeExpr::parseDriver volumeExprDriver
Typedef for volumeExpr parseDriver.
const wordList internal
Standard volume internal field types (scalar, vector, tensor, etc).
string evaluate(label fieldWidth, const std::string &s, size_t pos=0, size_t len=std::string::npos)
String evaluation with specified (positive, non-zero) field width.
GeometricField< vector, fvsPatchField, surfaceMesh > surfaceVectorField
List< word > wordList
List of word.
GeometricField< vector, fvPatchField, volMesh > volVectorField
HashSet< word, Hash< word > > wordHashSet
A HashSet of words, uses string hasher.
GeometricField< tensor, pointPatchField, pointMesh > pointTensorField
GeometricField< scalar, pointPatchField, pointMesh > pointScalarField
GeometricField< sphericalTensor, pointPatchField, pointMesh > pointSphericalTensorField
GeometricField< scalar, fvPatchField, volMesh > volScalarField
Field< bool > boolField
Specialisation of Field<T> for bool.
messageStream Info
Information stream (stdout output on master, null elsewhere).
GeometricField< vector, pointPatchField, pointMesh > pointVectorField
List< instant > instantList
List of instants.
GeometricField< scalar, fvsPatchField, surfaceMesh > surfaceScalarField
GeometricField< symmTensor, pointPatchField, pointMesh > pointSymmTensorField
Ostream & endl(Ostream &os)
Add newline and flush stream.
GeometricField< tensor, fvPatchField, volMesh > volTensorField
GeometricField< tensor, fvsPatchField, surfaceMesh > surfaceTensorField
GeometricField< sphericalTensor, fvPatchField, volMesh > volSphericalTensorField
void reduce(T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce).
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
GeometricField< sphericalTensor, fvsPatchField, surfaceMesh > surfaceSphericalTensorField
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
GeometricField< symmTensor, fvPatchField, volMesh > volSymmTensorField
static void doCorrectBoundaryConditions(bool correctBCs, VolumeField< Type > &field)
static constexpr const zero Zero
Global zero (0).
word fieldGeoType(const expressions::FieldAssociation geoType)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
errorManipArg< error, int > exit(error &err, const int errNo=1)
GeometricField< symmTensor, fvsPatchField, surfaceMesh > surfaceSymmTensorField
constexpr char nl
The newline '\n' character (0x0a).
surfacesMesh setField(triSurfaceToAgglom)
Foam::argList args(argc, argv)
#define forAll(list, i)
Loop across all elements in list.