From 1a52758c413dd0bcf47cce8085d622062d6dac1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Henrotte?= <francois.henrotte@uclouvain.be> Date: Fri, 14 Dec 2018 15:14:26 +0100 Subject: [PATCH] tuto to interactively show how to management variables in Onelab models --- Managevariables/ManageVariables.geo | 233 ++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 Managevariables/ManageVariables.geo diff --git a/Managevariables/ManageVariables.geo b/Managevariables/ManageVariables.geo new file mode 100644 index 0000000..a2589e9 --- /dev/null +++ b/Managevariables/ManageVariables.geo @@ -0,0 +1,233 @@ +/* ------------------------------------------------------------------- + Tutorial: Managing variables in Onelab models + + Features: + - Gmsh and GetDP namespaces vs. Onelab database + - DefineNumber vs. DefineConstant + - line argument '-setnumber name value' + - SetNumber, ReadOnly + - Macro + + See also + gitlab.onelab.info/doc/tutorials/wikis/ONELAB-syntax-for-Gmsh-and-GetDP + + To run the tutorial, open the 'OnelabVar.geo' file with Gmsh, + and click on the bottom bar below the graphic window of the GUI + in order to disclose the message window. + Switch from example to the next with the drop-down menu "Example number" + The 'Run' button is here useless. + + Alternatively, run the tutorial in the console with the command + + $ gmsh ManageVariables.geo - -setnumber ex n + + with n = 1,2,3 successively. + + ------------------------------------------------------------------- */ + +/* + There are differents ways of defining variables in Onelab models, + with specificities that can exploited for building + flexible interactive or, on the contrary, automized models. + This tutorial intends to demonstrate and explain these differences. + It is organized as a series of three commented examples. + + Open this file with Gmsh and click immediately on the bottom bar + below the graphic window of the GUI to disclose the message window. + The file 'OnelabVars' has already been parsed and you see there + the output corresponding to Example 1. + Each time you select a new 'Example' in the drop-down menu, + the file is reparsed and the output is displayed in the message window. + The 'Run' button is ineffective in this tutorial. + + Variable handling is identical in Gmsh and GetDP. + All what is said below about Gmsh variables + applies without change to GetDP variables. + Scalar and string variables are also handled similarly, + under obvious changes: GetNumber -> GetString, etc... + + To start with, it is insisted on this, + that there are no local variables in Gmsh or GetDP. + Both programs have one own global namespacet. + Macros are kind of functions, but without scope nor arguments, + and working only with the variables present in the global namespace. + The Onelab database, on the other hand, is and even more global structure, + as it is unique and shared by several solvers. +*/ + +Solver.AutoCheck = 1; + +Macro PrintVars + Printf(" "); + If( StrLen(str)) + Printf(StrCat["After: ", str]); + EndIf + Printf("Gmsh variable: nb = %g Onelab variable: Number = %g", nb, GetNumber("Number")); + Return + +DefineConstant[ + ex = DefineNumber(1, Name "Example number", + Choices {1="1", 2="2", 3="3"}) +]; + +If( ex==1 ) + Printf(" "); + Printf("Example 1"); + /* + The statement: + + nb = DefineNumber(1, Name "Number"); + + makes the following operations: + - The function 'DefineNumber' searches for a variable named "Number" + in the Onelab database. + - If not found, + -> the Onelab variable 'Number' is added to the database + with the default value given in argument (here, 1) + -> the function returns the database value '1', + which is affected to the Gmsh variable 'nb' + - If it is found, + -> the function returns the database value of 'Number' + and affects it to the Gmsh variable 'nb'. + + The main purpose of the Onelab interface is to synchonize + variable values across different solvers and programmes. + Invoking DefineNumbers() in different files + is the natural way to share variable values across different solvers + and build consistent multifile/multisolver Onelab models. + + The purpose of the above statement is to have a variable 'nb' + available in the Gmsh namespace whose value is always identical + with the value of the Onelab variable "Number". + + Example 1 however shows how a reaffectation breaks this identity + and is (most probably) the clue of an inconsistent model. + + You can also edit the database values of "Number" + in the left panel of the GUI and check that what you observe + can be explained on basis of the same principles. + */ + nb = 0; + + nb = DefineNumber(5, Name "Number"); + str = 'nb = DefineNumber(5, Name "Number");'; + Call PrintVars; + Printf("==> DefineNumber() creates the Onelab variable with given default value"); + Printf(" and affects the returned value to the Gmsh variable."); + + nb = DefineNumber(6, Name "Number"); + str = 'nb = DefineNumber(7, Name "Number");'; + Call PrintVars; + Printf("==> Repeated DefineNumber() with another default value has no effect."); + + nb = 8; // re-affectation of the Gmsh variable + str = 'nb = 8'; + Call PrintVars; + Printf("==> A re-affectation desynchronizes the Gmsh and Onelab variables"); + Printf(" This is (probably) an inconsistency in the model."); + Printf(" If_you edit the value of 'Number' in the left panel (do it now),"); + Printf(" the entered value is also overwritten by this re-affectation."); + Printf(" "); + Printf(" Go to example 2."); + +ElseIf( ex==2 ) + Printf("Example 2"); + /* + In a Onelab model, some variables are edited by the user + whereas others are modified by the model itself. + The latter are called 'ReadOnly' Onelab variable. + Read-only Onleab variables are displayed in the GUI, + but they are not editable. + A readonly Onelab variable is reverted to editable at any time + by a further DefineNubmer() without the 'ReadOnly 1' clause. + + The modification of the database value of a Onelab variable + can be done in two ways: + - If the Onelab variable must be synchronized with a Gmsh variable, + a DefineNumber(..., ReadOnly 1) is used. + When the 'ReadOnly 1' clause is present, DefineNumber() overwrites + the database value with the value given in argument. + - The function SetNumber() can be used otherwise. + */ + Call PrintVars; + Printf("==> An error is issued because the Gmsh namespace is initialized"); + Printf(" each time the '.geo' file is parsed."); + Printf(" The Gmsh variable 'nb' of Example 1 is thus no longer defined."); + Printf(" The Onelab database, which is attached to the Gmsh GUI,"); + Printf(" is, on the other hand, still active."); + + nb = DefineNumber(1, Name "Number"); + str = 'nb = DefineNumber(1, Name "Number");'; + Call PrintVars; + Printf("==> DefineNumber() synchronizes 'nb' with the Onelab variable 'Number'."); + Printf(" As the Onelab variable already exists, the given default value is ignored."); + + SetNumber("Number", 2); + str = 'SetNumber("Number", 2);'; + Call PrintVars; + Printf("==> SetNumber() modifies the database value of 'Number', but not 'nb'."); + Printf(" They are thus no longer synchronized."); + Printf(" SetNumber() should not be used for Onelab variables that have"); + Printf(" an associated variable in the Gmsh namespace, except if you know what you do."); + + nb = DefineNumber(3, Name "Number", ReadOnly 1); + str = 'nb = DefineNumber(3, Name "Number", ReadOnly 1);'; + Call PrintVars; + Printf("==> DefineNumber() with the 'Read-only 1' clause also modifies the database value,"); + Printf(" but keeps 'nb' synchronized with 'Number'."); + Printf(" Check that the value of 'Number' is no longer editable in the GUI"); + Printf(" "); + Printf(" Go to example 3."); + +ElseIf( ex==3 ) + Printf("Example 3"); +/* + The mechanism described above is that of synchronizing Onelab variables + with a Gmsh variables, or more generally speaking, + with variables in the namespaces of various solvers. + Another important, and rather different mechanism is that of precedence. + Indeed, in a model, information available at a higher level, + where, e.g., the user or a calling optimisation loop acts, + should often be given the priority over equivalent information + declared at a lower level. + As plain affectations statement like + + left-value = right-value; + + are unconditionally executed, they naturally give precedence + to the lower level information, + which is treated after the high level information when parsing model files. + One thus needs a mechanism to revert this behaviour. + This is the purpose of the 'DefineConstant[]' statement. + + An affectation done within a 'DefineConstant[]' statement + is ignored if the left-value is already defined in the Gmsh namespace. + It can have been defined + - by a previous affectation at a higher level, e.g., in an including file + - or by a '-setnumber' commandline option. + + If the ignored affectation contains Onelab arguments ("Name", etc...), + the definition of the Onelab variable is also skipped. +*/ + + nb = 0; + str='nb = 0;'; + Call PrintVars; + Printf("==> 'nb' set to zero in the Gmsh namespace"); + Printf(" with no effect in the Onelab variable 'Number'."); + + DefineConstant[ + nb = 1 // ignored + nb = {2, Name "Number", ReadOnly 1} // ignored + ]; + str = 'DefineConstant[ ... ];'; + Call PrintVars; + Printf("==> Further affectations ignored because enclosed in DefineConstant[]"); + + nb = 2; + str='nb = 2;'; + Call PrintVars; + Printf("==> Subsequent affectation executed because not enclosed in DefineConstant[]."); + Printf(" The high level information 'nb=0' is superseeded by the low level information 'nb = 2'."); +EndIf + -- GitLab