From 4107eeefcd50b0e8df1aabfd799c34ef336fb643 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Thu, 19 Dec 2019 21:04:15 +0100 Subject: [PATCH] ENH: added foamCalc (applications/tools) Many possibilities: - use as a simple calculator with vectors, tensors etc. - test validity of expression syntax As a calculator: foamCalc '(vector(1,2,3) ^ vector(4,5,6)) * sqrt(34)' The same, but with debugging: foamCalc -debug-switch fieldExpr=6 \ 'mag((vector(1,2,3) ^ vector(4,5,6))) * sqrt(34)' --- applications/tools/foamCalc/Make/files | 3 + applications/tools/foamCalc/Make/options | 2 + applications/tools/foamCalc/foamCalc.C | 164 +++++++++++++++++++++++ 3 files changed, 169 insertions(+) create mode 100644 applications/tools/foamCalc/Make/files create mode 100644 applications/tools/foamCalc/Make/options create mode 100644 applications/tools/foamCalc/foamCalc.C diff --git a/applications/tools/foamCalc/Make/files b/applications/tools/foamCalc/Make/files new file mode 100644 index 0000000000..a2d961e851 --- /dev/null +++ b/applications/tools/foamCalc/Make/files @@ -0,0 +1,3 @@ +foamCalc.C + +EXE = $(FOAM_APPBIN)/foamCalc diff --git a/applications/tools/foamCalc/Make/options b/applications/tools/foamCalc/Make/options new file mode 100644 index 0000000000..18e6fe47af --- /dev/null +++ b/applications/tools/foamCalc/Make/options @@ -0,0 +1,2 @@ +/* EXE_INC = */ +/* EXE_LIBS = */ diff --git a/applications/tools/foamCalc/foamCalc.C b/applications/tools/foamCalc/foamCalc.C new file mode 100644 index 0000000000..f16886188f --- /dev/null +++ b/applications/tools/foamCalc/foamCalc.C @@ -0,0 +1,164 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +Application + foamCalc + +Group + grpTools + +Description + A simple expression calculator using OpenFOAM string evaluation. + Multiple arguments will be concatenated together. + +Usage + \b foamCalc [OPTION] + + Options: + - \par -precision int + Output with specified precision + + - \par -rules + Print parser rules and exit + + - \par -tokens + Print token names and exit + +\*---------------------------------------------------------------------------*/ + +#include "argList.H" +#include "IOstreams.H" +#include "exprString.H" +#include "stringOps.H" +#include "fieldExprParser.H" + +using namespace Foam; + +template +void printInformation +( + Ostream& os, + const word& name, + const bool printNames, + const bool printRules +) +{ + if (printNames) + { + os << nl << "# Tokens for " << name << nl; + Parser::printTokenNames(os); + } + + if (printRules) + { + os << nl << "# Rules for " << name << nl; + Parser::printRules(os); + } +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Main program: + +int main(int argc, char *argv[]) +{ + argList::noBanner(); + argList::noParallel(); + argList::setAdvanced("case"); // Hide -case : has no meaning here + + argList::addNote + ( + "A simple expression calculator using OpenFOAM string evaluation.\n" + "Multiple arguments will be concatenated together." + ); + + argList::addBoolOption("rules", "Print parser rules and exit"); + argList::addBoolOption("tokens", "Print token names and exit"); + argList::addOption("precision", "int", "Output with specified precision"); + + // Flag arguments as optional so that -rules and -tokens works + argList::noMandatoryArgs(); + argList::addArgument + ( + "expression", + "The expression to evaluate" + ); + + argList args(argc, argv); + + const bool printRules = args.found("rules"); + const bool printNames = args.found("tokens"); + + if (printNames || printRules) + { + printInformation + ( + Info, + "field", + printNames, + printRules + ); + + return 0; + } + + { + const int prec = args.lookupOrDefault("precision", 0u); + if (prec > 0) + { + IOstream::defaultPrecision(prec); + Sout.precision(prec); + } + } + + std::string expr; + + for (int argi=1; argi < args.size(); ++argi) + { + if (argi > 1) expr += ' '; + expr += args[argi]; + } + + // Don't bother stripping C/C++, but do allow empty variables + stringOps::inplaceExpand(expr, true); + stringOps::inplaceTrim(expr); + + if (expr.empty()) + { + InfoErr + << "Error: no expression specified." << nl + << "See '" << args.executable() << " -help' for usage" << nl + << nl; + + return 1; + } + + Info<< stringOps::evaluate(expr).c_str() << nl; + + return 0; +} + + +// ************************************************************************* //