Difference between revisions of "Contrib/equationReader"

From OpenFOAMWiki
m (Forgot to add 1.7.x, which is very likelly to be acceptable.)
Line 1: Line 1:
An equation reader for your dictionary files.<BR>
+
Known to work with:<BR>
Latest updates:
+
{{VersionInfo}}{{Version1.6-ext}}{{Version1.7.0}}{{Version1.7.1}}{{Version1.7.x}}
* significant efficiency improvement using ''function pointers'' behind the scenes;
+
* numbers are okay in variable names now; and
+
* <tt>fieldEvaluate</tt> function makes working with fields easier.
+
{{VersionInfo}}{{Version1.5}}{{Version1.6}}{{Version1.7.0}}{{Version1.7.1}}{{Version1.7.x}}{{Version1.5-dev}}{{Version1.6-ext}}
+
 
<BR>
 
<BR>
 +
May also work with the latest version.  Be the first to find out, and let me know.
 +
<br>
 +
<small>Subpage contents (alphabetical)<BR>
 +
> [[Contrib_equationReader/Installation|Installation]]<BR>
 +
> [[Contrib_equationReader/Installation|Programming]]<BR>
 +
> [[Contrib_equationReader/Uninstallation|Uninstallation]]<BR>
 +
> [[Contrib_equationReader/Using_equationReader|Using equationReader]]<BR></small>
 +
<BR>
 +
 
== What is it? ==
 
== What is it? ==
'''equationReader''' is an extension to [[OpenFOAM]] that allows you to read equations from a dictionary file, and have them evaluated at every timestep.  It works for <tt>scalars</tt> and <tt>dimensionedScalars</tt>.  For example:
+
'''equationReader''' is an extension to [[OpenFOAM]] that allows you to work with user-entered equations.  For example:
 
+
nu          nu [0 2 -1 0 0 0 0] "1.2 + 3 * alpha^sin(pi_/6)";
+
aScalar    "nu / max(5, alpha)";
+
alpha      1.3;
+
  
 +
U.x        "sin(pi_ * t / 4)";
 +
U.y        "rho * nut / L";
 +
U.z        0;
 +
nu        nu [0 2 -1 0 0 0 0] "1.2 + 3 * alpha^sin(pi_/6)";
 +
aScalar    "nu / max(5, alpha)";
 +
alpha      1.3;
 +
 
== Features ==
 
== Features ==
 +
* '''Works with most fields''' - Now works with ''single elements'', ''fields'', and ''GeometricFields'';
 +
* '''Works with most Types''' - Now works with ''scalars'', ''vectors'', and all kinds of ''tensors'';
 +
* '''Flexible data sources''' - In addition to these types, equations can also lookup values from ''dictionaries'', and you can create an ''activeVariable'' that derives its value on-the-fly.
 
* '''Order of operations''' - it is fully compliant with the conventional order of operations to an arbitrary parenthesis depth;
 
* '''Order of operations''' - it is fully compliant with the conventional order of operations to an arbitrary parenthesis depth;
* '''Automatic output''' - '''equationReader''' is now an <tt>IOobject</tt>, '''IOEquationReader''', supporting automatic output;
 
* '''Flexible data sources''' - equations can use data from any <tt>dictionary</tt>, <tt>scalar</tt>, <tt>dimensionedScalar</tt>, and any derivative of <tt>scalarList</tt>, which includes <tt>scalarField</tt>, <tt>volScalarField</tt>, and <tt>surfaceScalarField</tt>;
 
 
* '''Equation dependency tracking''' - equations can depend on one another to an arbitrary hierarchy depth;
 
* '''Equation dependency tracking''' - equations can depend on one another to an arbitrary hierarchy depth;
 
* '''Circular-reference detection''' - it will halt computations when a circular reference is detected;
 
* '''Circular-reference detection''' - it will halt computations when a circular reference is detected;
* '''On-the-fly equation mapping''' - it will automatically perform substitution on other equations when they are needed, even if they aren't specifically called for in the solver;
+
* '''On-the-fly equation mapping''' - it will automatically perform substitution on other equations when they are needed, even if they aren't specifically called for in the solver; and
* '''Dimension-checking''' - fully utilizes [[OpenFOAM]]'s built-in dimension-checking, or you can force the outcome to a specific dimension-set to quickly disable it (if you are lazy);
+
* '''Dimension-checking''' - fully utilizes [[OpenFOAM]]'s built-in dimension-checking, or you can force the outcome to a specific dimension-set to quickly disable it (if you are lazy).
* '''Three modes of operation''' - you can choose from three different modes of operation to suit your needs:
+
:# '''stand-alone''' - this one works "out of the box" with all OpenFOAM applications.  You can only use literal constants in your equations;
+
:# '''passive mode''' - if you create an <tt>equationReader</tt> object, you can give it data sources.  This allows you to use variables, and equation substitution; and
+
:# '''active mode''' - if you also give <tt>equationReader</tt> pointers to your output variables, it can automatically update the values at every timestep.
+
  
== How do you use it? ==
+
'''Limitations:''' Although '''equationReader''' works with all Types, at its core, it is just a ''scalar'' calculator with ''dimensions''.  Therefore, you can't use vector operators, let alone tensor operators.  Each equation must be expressed in scalar components.
  
First [[#Installation|install it]].  Out of the box, it will work with all existing solvers.
+
== Why would you need this? ==
 +
Let the user define their own equations - this makes your application '''more user-friendly''', and '''more flexible'''.  But don't reinvent the wheel - if you are only working with ''boundary conditions'' or ''initial conditions'', Bernhard's [[Contrib/swak4Foam|swak4Foam]] would probably be more suitable.
  
=== Syntax ===
+
== Learn more ==
The general syntax is:
+
  
==== <tt>scalar</tt> or regular equation ====
+
* ''I'm sold, let me install it!'' - Check out the [[Contrib_equationReader/Installation|installation sub-page]].
An equation using this format has dimension-checking enabled (unless you turn off set dimensionSet::debug).
+
* ''I'm a user, how do I format my equations?'' - Check out the [[Contrib_equationReader/Using_equationReader|user's guide sub-page]].
keyword    "''equation''";
+
* ''I'm a developer, how do I use '''equationReader'''?'' - Check out the [[Contrib_equationReader/Programming|programmer's guide sub-page]].
e.g.:
+
* ''I've had enough, how do I uninstall it?'' - Check out the [[Contrib_equationReader/Uninstallation|Uninstallation sub-page]].
endTime    "2*pi_/360*60";
+
 
+
==== <tt>dimensionedScalar</tt> or dimensioned equation ====
+
If you specify dimensions, it will disable the dimension-checking and force the outcome to the given dimensionSet.
+
keyword    name [''dimensionSet''] "''equation''";
+
e.g.:
+
nu    nu [0 2 -1 0 0 0 0] "1 / (1e-5 + 2.3/4000 + SMALL_)";
+
'''NOTE:''' A dimensioned equation will ignore the 'name' field;
+
==== Abbreviated dimensioned equation ====
+
Since a dimensioned equation does not need the <tt>name</tt> field, an abbreviated format is acceptable:
+
keyword    [''dimensionSet''] "''equation''";
+
e.g.:
+
nu    [0 2 -1 0 0 0 0] "1 / (1e-5 + 2.3/4000 + SMALL_)";
+
This format will not work in '''stand-alone''' mode.
+
 
+
==== Equation syntax ====
+
'''equationReader''' uses the conventional order of operations '''BEDMAS''', then left to right:
+
 
+
* '''B'''rackets (and functions);
+
* '''E'''xponents;
+
* '''DM''' - division and multiplication; and
+
* '''AS''' - addition and subtraction.
+
 
+
Basically, if you can enter equations into Excel<ref>Excel is copyright Microsoft</ref>, you already know how to do this.
+
 
+
* you can use any amount of whitespace you want;
+
* exponents are <tt>^</tt>, for example <tt>2^3</tt> is <tt>8</tt>;
+
* multiplication is <tt>*</tt>, for example <tt>2*3</tt> is <tt>6</tt>;
+
* there is no implied multiplication - you must explicitly use <tt>*</tt>.  For example:
+
::<tt>2 sin(theta)</tt> <span style="color:#ff0000">'''INCORRECT'''</span>
+
::<tt>2 * sin(theta)</tt> '''CORRECT'''
+
:and
+
::<tt>2(3 + 4)</tt> <span style="color:#ff0000">'''INCORRECT'''</span>
+
::<tt>2 * (3 + 4)</tt> '''CORRECT'''
+
 
+
<strike>NOTE: You cannot have numbers in your variable names.</strike>  Now you can.
+
 
+
==== Mathematical constants ====
+
'''equationReader''' recognizes all the mathematical constants I could find in the [[OpenFOAM]] library.  To specify a mathematical constant, append the regular [[OpenFOAM]] format with an underscore '_'.  The available constants are:
+
 
+
* <tt>e_</tt> (Euler's number);
+
* <tt>pi_</tt>;
+
* <tt>twoPi_</tt>;
+
* <tt>piByTwo_</tt>;
+
* <tt>GREAT_</tt>;
+
* <tt>VGREAT_</tt>;
+
* <tt>ROOTVGREAT_</tt>;
+
* <tt>SMALL_</tt>;
+
* <tt>VSMALL_</tt>; and
+
* <tt>ROOTSMALL_</tt>.
+
 
+
==== Functions ====
+
[[Contrib_equationReader/functions|Click here for a complete list of functions.]]
+
 
+
All the <tt>scalar</tt> and <tt>dimensionedScalar</tt> functions I could find in the [[OpenFOAM]] library have been implemented. 
+
 
+
=== Stand-alone mode ===
+
'''equationReader''' changes [[OpenFOAM]]'s <tt>readScalar</tt> function, and therefore all existing applications can use equation input for <tt>scalar</tt>s and <tt>dimensionedScalar</tt>s read from dictionary.  Using '''stand-alone mode:'''
+
 
+
* you do not have to recompile the solver or application;
+
* you can use <tt>[[#scalar or regular equation|scalar]]</tt> and <tt>[[#dimensionedScalar or dimensioned equation|dimensionedScalar]]</tt> formats (above);
+
* you can use [[#Mathematical constants|mathematical constants]]; and
+
* you can use [[TestMarupio/functions|functions]]; but
+
* '''you cannot use any variables.'''
+
 
+
Since you cannot use variables, there is no equation substitution available in '''stand-alone mode'''.
+
 
+
=== Passive and active mode ===
+
To use '''passive mode''' and '''active mode''' your solver or application has to be specifically written to use '''equationReader'''.  See [[#Programming with equationReader|Programming with equationReader]].
+
 
+
=== Debugging your equations ===
+
If you enter an incorrect equation '''equationReader''' should throw an error that explains exactly what is wrong with it.  If you encounter a floating point exception, try using a debug flag.  Add <tt>equationReader</tt> to the debug flag list in <tt>[OpenFOAM root folder]/etc/controlDict</tt>.  There are two debug levels:
+
# Show when equations are read, parsed, and evaluated; and
+
# Show every operation as it is calculated.
+
 
+
== Programming with '''equationReader''' ==
+
Have a look at the demo application that '''equationReader''' comes with.
+
 
+
To enable the use of variables, you have to create an <tt>equationReader</tt> object, and tell it where to find its data.
+
<cpp>#include "IOequationReader.H"
+
// ...
+
    IOEquationReader eqns
+
    (
+
        IOobject
+
        (
+
            "eqns",
+
            runTime.timeName(),
+
            runTime,
+
            IOobject::READ_IF_PRESENT,
+
            IOobject::AUTO_WRITE // Set to NO_WRITE to suppress output
+
        ),
+
        false // set to true to show data sources in output file
+
    );
+
</cpp>
+
 
+
To give it data, use the <tt>addDataSource</tt> functions.  There are five data sources '''equationReader''' will accept:
+
 
+
* <tt>dictionaries</tt>;
+
* <tt>scalars</tt>;
+
* <tt>dimensionedScalars</tt>;
+
* <tt>scalarLists</tt>; and
+
* <tt>dimensioned scalarLists</tt> (these include <tt>scalarFields, volScalarField</tt>, etc...).
+
 
+
'''NOTE:''' I've provided access methods directly to the data storage members, so if you know what you are doing, you can direclty modify everything this way.
+
 
+
=== Working with scalarLists / fields ===
+
'''equationReader''' was not originally intended for use with fields - OpenFOAM has plenty of functionality for that.  '''equationReader''' only operates on scalars and dimensioned scalars.  To get it working with full fields, there are now two options:
+
 
+
* manually cycling through all the indices in the field using <tt>setListIndex</tt>, as shown here:
+
 
+
<cpp>// p_g is a volScalarField
+
forAll(p_g, i)
+
{
+
    eqns.setListIndex(i);
+
    p_g[i] = eqns.evaluate("p_g");
+
}
+
</cpp>
+
 
+
<cpp>// S_su is a geometricField
+
forAll(S_su.internalField(), i)
+
{
+
    eqns.setListIndex(i);
+
    S_su.internalField()[i] = eqns.evaluate("S_su");
+
}
+
</cpp>
+
 
+
* or, use the new <tt>evaluateField</tt> function:
+
<cpp>S_su = eqns.evaluateField("S_su");</cpp>
+
 
+
=== Data source and output warnings ===
+
'''WARNING - DATA SOURCES AND OUTPUTS MUST NOT GO OUT-OF-SCOPE'''<br>
+
Ensure that anytime '''equationReader''' is in use, all of its data is available to it.  There is no way of telling when the object at the end of a pointer has been deleted.  However, it ''is'' safe to let the '''equationReader''' go out-of-scope without impacting the data.
+
 
+
'''Suggested practice''' - An easy way to give access to the '''equationReader''' to everyone, and prevent it from going out of scope is to override <tt>Time</tt>, and give it an '''IOEquationReader''', as well as access functions.
+
 
+
=== Reading equations ===
+
One you've defined the data sources, you can use the <tt>readEquation</tt> method to read and parse the equations in the dictionary.  This does not immediately evaluate them... use the <tt>evaluate</tt> or <tt>update</tt> methods for that.
+
 
+
==== On-the-fly equation reading ====
+
If you have a <tt>dictionary</tt> source, '''equationReader''' will search the dictionary recursively for any unknown variables.  If the variable happens to be an equation, '''equationReader''' will automatically read this equation as well.  This can continue to an indefinite equation substitution depth.
+
 
+
=== Passive mode ===
+
To use an equation in '''passive mode''', when you read the equation with <tt>readEquation</tt>, you do not have to specify an output variable.  To get output from and equation in this manner, use <tt>evaluate</tt>.  This returns a <tt>dimensionedScalar</tt> that you can assign to whatever variable you want.
+
 
+
Passive mode requires an <tt>evaluate</tt> command for each equation you're using.
+
 
+
=== Active mode ===
+
To use an equation in '''active mode''', when you read the equation with <tt>readEquation</tt>, you must specify an output variable.  Again, '''use the freestore''', and give a pointer.  When you you <tt>update</tt>, '''equationReader''' will cycle through all your equations, and evaluate those with output pointers, changing the output variables in the process.  If you only want to <tt>update</tt> one equation, that is also available.
+
 
+
'''NOTE:''' You can still use this equation passively with <tt>evaluate</tt>.
+
 
+
== Installation ==
+
To install '''equationReader''':
+
 
+
0. If you are running precompiled binaries, first ensure that you can compile your copy of OpenFOAM.
+
 
+
1. Download the code for [http://openfoam-extend.svn.sourceforge.net/viewvc/openfoam-extend/trunk/Breeder_1.5/libraries/equationReaderExtension/?view=tar OpenFOAM-1.5.x including 1.5-dev], or for [http://openfoam-extend.svn.sourceforge.net/viewvc/openfoam-extend/trunk/Breeder_1.6/libraries/equationReaderExtension/?view=tar OpenFOAM-1.6.x and higher]
+
 
+
For OpenFOAM 1.5.x and 1.5-dev:<BR>
+
http://openfoam-extend.svn.sourceforge.net/viewvc/openfoam-extend/trunk/Breeder_1.5/libraries/equationReaderExtension/?view=tar
+
 
+
For OpenFOAM 1.6, 1.6-ext, 1.7, 1.7.1 and higher:<BR>
+
http://openfoam-extend.svn.sourceforge.net/viewvc/openfoam-extend/trunk/Breeder_1.6/libraries/equationReaderExtension/?view=tar
+
 
+
2. In your own OpenFOAM source directory, find the <tt>src/OpenFOAM/Make/files</tt> file and edit it.
+
 
+
3. Somewhere in the middle (''1.5-dev'' - line 139, ''1.6'' - line 137, ''1.6-ext'' - line 151, ''1.7.1'' - line 137), you will find <tt>"$(functionEntries)/removeEntry/removeEntry.C"</tt>.  After this line, add the lines:
+
 
+
equation = $(dictionary)/equation
+
$(equation)/equationReader/equationReader.C
+
$(equation)/equationReader/equationReaderIO.C
+
$(equation)/equation/equation.C
+
$(equation)/equation/equationIO.C
+
$(equation)/equationOperation/equationOperation.C
+
+
IOEquationReader = db/IOobjects/IOEquationReader
+
$(IOEquationReader)/IOEquationReader.C
+
$(IOEquationReader)/IOEquationReaderIO.C
+
 
+
4. Save and close the file.
+
 
+
5. Open a terminal window, and browse to the directory with your download.
+
 
+
6. Execute the following commands.  You should be able to copy and paste all 10 lines at once into you terminal window.
+
 
+
tar --transform='s,equationReaderExtension,'$WM_PROJECT_DIR',' \
+
-x -v -z -P -f openfoam-extend-equationReaderExtension.tar.gz
+
cd $WM_PROJECT_DIR/src/OpenFOAM
+
rmdepall
+
wmakeLnInclude -f .
+
wmake libso
+
cd $FOAM_APP/solvers/equationReader/equationReaderDemo
+
wmake
+
cd $FOAM_APP/solvers/equationReader/equationReaderTester
+
wmake
+
 
+
Equation reader should now be installed.
+
 
+
=== Testing the installation ===
+
The code comes with two applications: a simple demo, and a more complex test program.  Once '''equationReader''' is installed, there should be a new folder: <tt>$WM_PROJECT_DIR/tutorials/equationReader</tt>.  Copy this into your <tt>run</tt> directory:
+
 
+
cp -rf $WM_PROJECT_DIR/tutorials/equationReader $FOAM_RUN/tutorials
+
 
+
'''To run the demo:'''
+
 
+
cd $FOAM_RUN/tutorials/equationReaderDemo
+
equationReaderDemo
+
 
+
You can compare the output with the <tt>expectedOutput</tt> file.
+
 
+
'''To run the tester:'''
+
 
+
cd $FOAM_RUN/tutorials/equationReaderTester
+
blockMesh
+
equationReaderTester
+
 
+
The tester runs '''equationReader''' in an environment that might be expected in a regular simulation.  It shouldn't throw any errors here, but as it is beta code, please me know: [[User:Marupio|Marupio]].
+
 
+
== Notes ==
+
'''No plans for vector or label implementation'''
+
:There are no plans to implement vectors, labels, or any other data type.  You can get around this limitation if you must, albeit in a cumbersome manner: you can break the vectors down and reassemble them; you can cast to label, etc..
+
  
 
== Update info ==
 
== Update info ==
Line 273: Line 57:
 
** Added a fieldEvaluate function for active equations whose output is to a scalar field.
 
** Added a fieldEvaluate function for active equations whose output is to a scalar field.
 
** Bug fix to get it working with 1.6-ext and higher.
 
** Bug fix to get it working with 1.6-ext and higher.
== Foot notes ==
+
*''2011-09-13:'' Major upgrade
<references/>
+
** ''''Now a stand-alone library''''.
 +
** Now works with ''''vectors and tensors'''':
 +
*** scalar;
 +
*** vector;
 +
*** tensor;
 +
*** diagTensor;
 +
*** symmTensor; and
 +
*** sphericalTensor.
 +
** ''''Now works with GeometricFields'''
 +
** Dimension checking is now performed separately, improving efficiency of field and GeometricField calculations.
 +
* Interface changes:
 +
** Add data functions reorganized / changed.
 +
** Evaluate functions reorganized / changed.
 +
** Update functions removed.
 +
 
 +
--[[User:Marupio|Marupio]] 21:42, 14 September 2011 (CEST)

Revision as of 19:42, 14 September 2011

Known to work with:
Valid versions: OF Version 16ext.png OF Version 170.png OF Version 171.png OF Version 17x.png
May also work with the latest version. Be the first to find out, and let me know.
Subpage contents (alphabetical)
> Installation
> Programming
> Uninstallation
> Using equationReader

1 What is it?

equationReader is an extension to OpenFOAM that allows you to work with user-entered equations. For example:

U.x        "sin(pi_ * t / 4)";
U.y        "rho * nut / L";
U.z        0;
nu         nu [0 2 -1 0 0 0 0] "1.2 + 3 * alpha^sin(pi_/6)";
aScalar    "nu / max(5, alpha)";
alpha      1.3;

2 Features

  • Works with most fields - Now works with single elements, fields, and GeometricFields;
  • Works with most Types - Now works with scalars, vectors, and all kinds of tensors;
  • Flexible data sources - In addition to these types, equations can also lookup values from dictionaries, and you can create an activeVariable that derives its value on-the-fly.
  • Order of operations - it is fully compliant with the conventional order of operations to an arbitrary parenthesis depth;
  • Equation dependency tracking - equations can depend on one another to an arbitrary hierarchy depth;
  • Circular-reference detection - it will halt computations when a circular reference is detected;
  • On-the-fly equation mapping - it will automatically perform substitution on other equations when they are needed, even if they aren't specifically called for in the solver; and
  • Dimension-checking - fully utilizes OpenFOAM's built-in dimension-checking, or you can force the outcome to a specific dimension-set to quickly disable it (if you are lazy).

Limitations: Although equationReader works with all Types, at its core, it is just a scalar calculator with dimensions. Therefore, you can't use vector operators, let alone tensor operators. Each equation must be expressed in scalar components.

3 Why would you need this?

Let the user define their own equations - this makes your application more user-friendly, and more flexible. But don't reinvent the wheel - if you are only working with boundary conditions or initial conditions, Bernhard's swak4Foam would probably be more suitable.

4 Learn more

5 Update info

  • 2010-07-21: Initial release
  • 2010-08-05: Bug-fix - differentiated versions for OpenFOAM-1.5.x/1.5-dev and OpenFOAM-1.6.x+
  • 2010-08-12: Major upgrade
    • Introducing IOEquationReader - EquationReader is now an IOobject<tt>. This enables automatic output
    • Added support for <tt>scalarList data sources - including scalarField<tt>, <tt>volScalarField, etc.
    • Removed the need for pointers for data sources
    • Cleaned up available functions
  • 2010-10-16: Bug fixes and added full support for fields
  • 2011-04-06: Major upgrade
    • Efficiency improvement - pointer functions have been implemented to increase computation speed by an order of magnitude (at least).
    • Improved dimension-checking on all functions.
    • Added a fieldEvaluate function for active equations whose output is to a scalar field.
    • Bug fix to get it working with 1.6-ext and higher.
  • 2011-09-13: Major upgrade
    • 'Now a stand-alone library'.
    • Now works with 'vectors and tensors':
      • scalar;
      • vector;
      • tensor;
      • diagTensor;
      • symmTensor; and
      • sphericalTensor.
    • 'Now works with GeometricFields
    • Dimension checking is now performed separately, improving efficiency of field and GeometricField calculations.
  • Interface changes:
    • Add data functions reorganized / changed.
    • Evaluate functions reorganized / changed.
    • Update functions removed.

--Marupio 21:42, 14 September 2011 (CEST)