51#include "readFields.H"
72struct setExprFieldsControl
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();
162 mesh.thisDb().time().timeName(),
172 auto& output = toutput.
ref();
174 label numValuesChanged = 0;
177 if (fieldMask.
empty())
180 numValuesChanged = output.size();
182 output.primitiveFieldRef() = evaluated;
186 auto&
internal = output.primitiveFieldRef();
199 forAll(evaluated.boundaryField(), patchi)
201 auto& pf = output.boundaryFieldRef()[patchi];
203 if (pf.patch().coupled())
205 pf == evaluated.boundaryField()[patchi];
214 if (numValuesChanged == numTotal)
220 Info<<
"Set " << numValuesChanged <<
" of ";
222 Info<< numTotal <<
" values" <<
endl;
224 if (ctrl.hasDimensions)
226 Info<<
"Setting dimensions to " << dims <<
endl;
227 output.dimensions().reset(dims);
232 Info<<
"(dry-run): Writing to " << output.name() <<
nl;
236 Info<<
"Writing to " << output.name() <<
nl;
237 output.writeObject(ctrl.streamOpt,
true);
247 const word& fieldName,
254 const setExprFieldsControl& ctrl
261 Info<<
"Set new field: " << fieldName;
268 mesh.thisDb().time().timeName(),
275 oldFieldType =
io.headerClassName();
277 if (oldFieldType == IOobject::typeName)
280 <<
"Field " << fieldName <<
"(type: " << oldFieldType
281 <<
") seems to be missing. Use 'create'" <<
nl
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();
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>(); \
485 <<
"Expression evaluates to an unsupported type: "
486 << driver.resultType() <<
nl <<
nl
487 <<
"Expression " << valueExpr_ <<
nl <<
endl
495int main(
int argc,
char *argv[])
497 argList::noFunctionObjects(
true);
500 timeSelector::addOptions(
false);
502 argList::addBoolOption
505 "Write in ASCII format instead of the controlDict setting"
511 "Alternative dictionary for setExprFieldsDict"
513 argList::addDryRunOption
515 "Evaluate but do not write"
517 argList::addVerboseOption
519 "Additional verbosity",
526 "Specify field or fields to preload. Eg, 'T' or '(p T U)'",
533 "The field to create/overwrite"
534 " (command-line operation)",
541 "The expression to evaluate"
542 " (command-line operation)",
549 "The field mask (logical condition) when to apply the expression"
550 " (command-line operation)",
553 argList::addOptionCompat(
"field-mask", {
"condition", 2106});
558 "The dimensions for created fields"
559 " (command-line operation)",
562 argList::addOptionCompat(
"dimensions", {
"dimension", 2012});
564 argList::addBoolOption
567 "Additional debugging information",
570 argList::addBoolOption
573 "Disable caching of expression variables",
576 argList::addBoolOption
580 " (command-line operation)",
583 argList::addBoolOption
586 "Leave patches unaltered"
587 " (command-line operation)",
594 "A list of patches that receive a fixed value"
595 " (command-line operation)",
598 argList::addBoolOption
601 "Provide a zero phi field"
602 " (command-line operation)",
608 argList::addBoolOption
613 argList::addBoolOption
615 "correctResultBoundaryFields",
633 <<
"No times selected." <<
nl
638 dimensionSet::checking(
false);
648 const bool useCommandArgs =
args.
found(
"field");
652 bool fatalCombination =
false;
656 fatalCombination =
true;
658 <<
"Cannot specify both dictionary and command-line arguments"
664 fatalCombination =
true;
666 <<
"Cannot specify both 'create' and 'keepPatches'" <<
nl
672 fatalCombination =
true;
674 <<
"Missing mandatory 'expression' option'" <<
nl
677 if (fatalCombination)
689 "create",
"keepPatches",
"value-patches",
690 "field-mask",
"expression",
"dimensions"
694 if (!badOptions.empty())
698 <<
"Using a dictionary. Cannot specify these options:" <<
nl
709 runTime.setTime(times[timei], timei);
723 if (
args.
found(
"dummy-phi") && !dummyPhi)
725 Info<<
"Adding a dummy phi" <<
endl;
733 mesh.thisDb().time().constant(),
746 runTime.functionObjects().start();
753 Info<<
"Using command-line options for "
754 << fieldName <<
nl <<
endl;
756 setExprFieldsControl ctrl;
759 ctrl.debugParsing =
args.
found(
"debug-parser");
760 ctrl.cacheVariables = !
args.
found(
"no-variable-caching");
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());
770 ctrl.streamOpt.format(IOstream::ASCII);
783 if (ctrl.hasDimensions)
802 else if (exprDictPtr)
816 for (
const entry& dEntry : actions)
818 if (!dEntry.isDict())
820 Info<<
"Ignore non-dictionary entry: "
821 << dEntry.keyword() <<
nl;
827 setExprFieldsControl ctrl;
830 ctrl.debugParsing =
args.
found(
"debug-parser");
831 ctrl.cacheVariables = !
args.
found(
"no-variable-caching");
833 ctrl.createNew =
dict.getOrDefault(
"create",
false);
834 ctrl.keepPatches =
dict.getOrDefault(
"keepPatches",
false);
836 ctrl.correctPatches = !
args.
found(
"noCorrectPatches");
837 ctrl.correctBCs =
args.
found(
"correctResultBoundaryFields");
838 ctrl.streamOpt.format(
runTime.writeFormat());
841 ctrl.streamOpt.format(IOstream::ASCII);
844 if (ctrl.createNew && ctrl.keepPatches)
847 <<
"Cannot specify both 'create' and 'keepPatches'"
849 <<
exit(FatalIOError);
855 "correctResultBoundaryFields",
864 expressions::exprString::getEntry
875 "fieldMask", {{
"condition", 2106}},
890 "dimensions", {{
"dimension", 2012}},
897 ctrl.hasDimensions =
bool(dimPtr);
923 <<
"No command-line or dictionary??" <<
nl <<
endl
reduce(hasMovingMesh, orOp< bool >())
Generic GeometricField class.
label retain(const HashTable< AnyType, Key, AnyHash > &other)
Retain table entries given by keys of the other hash-table.
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Defines the attributes of an object for which implicit objectRegistry management is supported,...
The IOstreamOption is a simple container for options an IOstream can normally have.
An input stream of tokens.
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
bool empty() const noexcept
True if the UList is empty (ie, size() is zero)
T get(const label index) const
Get a value from the argument at index.
int dryRun() const noexcept
Return the dry-run flag.
const HashTable< string > & options() const noexcept
Return options.
int verbose() const noexcept
Return the verbose flag.
bool readListIfPresent(const word &optName, List< T > &list) const
bool found(const word &optName) const
Return true if the named option is found.
bool readIfPresent(const word &optName, T &val) const
Read a value from the named option if present.
ITstream lookup(const word &optName) const
Return an input stream from the named option.
List< T > getList(const label index) const
Get a List of values from the argument at index.
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
void reset(autoPtr< T > &&other) 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
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Dimension set for the base types, which can be used to implement rigorous dimension checking for alge...
Generic dimensioned Type class.
A keyword and a list of tokens is an 'entry'.
virtual ITstream & stream() const =0
Return token stream, if entry is a primitive entry.
const keyType & keyword() const noexcept
Return keyword.
The field association for mesh (patch/volume) values.
void trim()
Inplace trim leading and trailing whitespace.
bool readEntry(const word &keyword, const dictionary &dict, bool mandatory=true, const bool stripComments=true)
Driver for volume, surface, point field expressions.
Mesh data needed to do the Finite Volume discretisation.
A traits class, which is primarily used for primitives.
A simple field-loader, as per the readFields function object.
bool execute(const UList< word > &fieldNames)
A class for managing temporary objects.
@ POINT_DATA
Inside PointData.
A class for handling words, derived from Foam::string.
#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")
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, false)
@ VOLUME_DATA
Volume data.
const wordList internal
Standard dimensioned 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.
messageStream Info
Information stream (stdout output on master, null elsewhere)
void doCorrectBoundaryConditions(bool correctBCs, PointField< Type > &field)
Ostream & endl(Ostream &os)
Add newline and flush stream.
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
word fieldGeoType(const expressions::FieldAssociation geoType)
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)
surfacesMesh setField(triSurfaceToAgglom)
Foam::argList args(argc, argv)
#define forAll(list, i)
Loop across all elements in list.
#define doLocalCode(GeoField)