Variables

Variable definition synopsis

There are eight types of user defined variables:

Each of these are stored in arb using the same general data structure (fortran funk_type in general_module.f90). Any of these variables can be defined by a user-written expression which is read by and interpreted by setup_equations.pl and maxima, as per

centring_variable <name> [units] "expression" ON <region> options # comments

where centring is one of CELL, FACE, NODE or NONE, and variable is one of the above eight variables, both typed in uppercase.

Variables that have CELL, FACE or NODE centrings have one value associated with each element of the associated CELL, FACE or NODE centred <region> (respectively). Variables that have NONE centring are not associated with a region, and have only one value. If centring is omitted then NONE centring is assumed for CONSTANT variables, while CELL centring is assumed for all other variables.

If a variable centring and type has already been defined within an arb file, the variable may be redefined without re-specifying the centring and type again using the VARIABLE keyword. Also, if a variable is redefined, you can use the variable name in the new expression to refer to the variable expression as previously defined. This combination of features is useful for incrementing or modifying a previously defined variable. Note that if there is a self-reference to a variable in its expression but the variable has not yet been defined, then a zero value is substituted for this self-reference. Also note that it is good practice to place braces around self-references as they are substituted in place, and omitting these braces can lead to order of mathematical operations (BODMAS) errors (definitely a common gotcha bug!).

The following are some examples of variable definition statements:

CELL_UNKNOWN <u[l=1]> [m/s] "4.d0" ON <allcells> # this specifies an unknown vector variable (actually the 1st (i.e. x) direction component), defined over the region <allcells>, with an initial value of 4 m/s
CELL_EQUATION <equation[l=1]> "<u[l=1]>-<cellx[l=1]>" ON <allcells> # this specifies an equation variable, defined over the region <allcells>.  The equation has the solution <u[l=]> = <cellx[l=1]>, where <cellx[l=1]> is the location of the cell in the 1st (i.e. x) direction
NONE_CONSTANT <c_total> [M] 45.d+3 convertunits # this is a none-centred (i.e., no spatial dependence) constant, which has a numerical value (no quotes), and will be converted from M (molar) to standard units (mol/m^3) after being read in
CONSTANT <c_free> "<c_total>/2" # this is also a none-centred constant, but the value is defined in terms of another constant so is defined using an expression
VARIABLE <c_free> "(<c_free>) + 1.d0" # redefinition of <c_free>, but using the previous definition as a starting point
FACE_TRANSIENT <f_t> [1] "0.d0" "faceif(facedelta(<boundaries>),2.d0,0.d0)" ON <allfaces> # a dimensionless transient variable that is initially 0.d0 on <allfaces>, but during timestep updates becomes 2 only on the boundary faces (<boundaries>) of the domain

Along with the user defined variables, there are also system defined variables which can be used in user-written expressions and are known as SYSTEM variables, however these cannot be set within the arb file.

All variables have an associated compound variable type (scalar, vector or tensor). These compounds are mainly used for input/output in the *.msh files.

The rest of this chapter covers these variable definition statements in more detail.

Variable names

Each variable must have a unique name, delimited by the < and >characters. Besides these characters, the variable may contain spaces and any other non-alphanumeric characters except for the hash character # (which indicates that a comment follows), the apersand & (which indicates line continuation) and the character doubles {{ and }} (which indicate the start and end of embedded perl code, respectively). Also, certain variable names are reserved for system variables as detailed below in [system variables].

Every variable is defined as a component of either a scalar, vector or tensor. The parent scalar, vector or tensor is known as the variable’s compound variable. If the name ends with a direction index contained within square braces [], as in <a vector[l=1]> or <another vector[l=3]>, then the variable is considered to be a component of a three dimensional vector compound. The vector compound is written without the directional index, as in <a vector> or <another vector>. Similarly, if the name ends with a double direction index, as in <a tensor[l=2,1]>, then the variable is considered to be a component of a three by three tensor compound, and its compound is again written without the directional index as in <a tensor>. If the variable has no direction index contained within square braces then the variable is a scalar and its compound has only one component (that is, the scalar) and its compound is written identically to its component or variable. All defined components that are members of the same compound must have the same centring and be defined over the same region, but they may be of different types.

By default arb problems are three dimensional, however the number of dimensions that are active can be altered by redefining the general string variable <<dimensions>> which lists the number of active dimensions — by default this variable has the value of 1,2,3 implying that all three dimensions are active. Components of compounds that are not explicitly defined within the arb file are given a zero value (when used in dot dot and double dot ddot colon operators for example).

Example scalar, vector and tensor variable definitions include:

CONSTANT <S> 1.d0 # a scalar variable
CONSTANT <V[l=1]> 2.d0 # the first component of the compound vector <V> is 2
CONSTANT <V[l=3]> 1.d0 # the third component of the compound vector <V> is 1
CONSTANT <V_mag^2> "<V[l=1]>^2+<V[l=2]>^2+<V[l=3]>^2" # this will evaluate as 2^2+0^2+1^2=5 as <V[l=2]> is not been defined so will evaluate as zero
CONSTANT <VV_dot> "dot(<V[l=:]>,<V[l=:]>)" # the dot colon operator calculates the dot product of two vectors by expanding the : to include all dimensions in <<dimensions>>, so <VV_dot> evaluates to be exactly the same as <V_mag^2>
CONSTANT <V_mag> "mag(<V[l=:]>)" # the colon operator mag is equivalent to sqrt(dot(<V[l=:]>,<V[l=:]>)), which is the magnitude of the vector <V>
CONSTANT <T[l=1,1]> 1.d0 # component 1,1 of tensor T
CONSTANT <T[l=2,2]> 2.d0 # component 2,2 of tensor T
CONSTANT <T_mag> "mag(<T[l=:,:]>)" # evaluates to second invariant of T, noting that only components 1,1 and 2,2 are non-zero here
CONSTANT <T:vv> "ddot(<T[l=:,:]>,<V[l=:]>*<V[l=:]>)" # calculates the double dot product of T:VV
BLOCK
  REPLACEMENTS R "<<dimensions>>" W "1,2" # within this code block the problem dimensions are changed to ignore the 3rd dimension
  CONSTANT <VV_dot> "dot(<V[l=:]>,<V[l=:]>)" # now <VV_dot> = 2^2+0^2 = 4 as the dimensions of the problem have been redefined within this code block
END_BLOCK

As well as specifying the cell compound rank (ie scalar, vector or tensor), the [] contained at the end of a variable name can also be used to specify what relative timestep (or relstep) a variable corresponds to. Relative timesteps are used (primarily) in transient problems to signify which timestep a variable corresponds to. Noting that in transient simulations typically time is continuously advancing, then [r=0] implies that the variable corresponds to the latest timestep, [r=1] implies that the variable corresponds to the preceeding timestep, [r=2] implies that the variable corresponds to the timestep before the preceeding timestep, etc. TRANSIENT variables are updated in decreasing relstep index when a new timestep is started (…, r=2, r=1, r=0), so that typically within a transient simulation [r=2] variable values will be updated (ie, overwritten) by [r=1] values, and [r=0] values by [r=1] values, etc, such that the variable values progress forwards in time. If unspecified, any variable defaults to the the current timestep, or equivalently [r=0]. Hence the names <a[r=0]> and <a> are equivalent.

Example relative timestep specifications include:

CONSTANT <dt> [s] 1.d0
NONE_TRANSIENT <t[r=0]> "0.d0" "<t[r=1]>+<dt>" # this transient has an initial value of 0, and upon update is <t[r=1]>+<dt>, noting that during a timestep update variables are evaluated in increasing `r` order
NONE_TRANSIENT <t[r=1]> "<t[r=0]>-<dt>" "<t[r=0]>" # initially this variable will be 0-1=-1s, and on timestep update will adopt the latest <t[r=0]> value
NONE_OUTPUT <a[r=0]> "<t[r=0]>+2"
NONE_OUTPUT <a> "<t>+2" # exactly the same as the above
CONSTANT <V2[l=1,r=0]> 3.d0 # the order of the l direction indicies and r relstep indicies doesn't matter, although they are standardised to alphabetical order internally
CONSTANT <V2[r=0,l=1]> 3.d0 # same as the above

Note that while the arb transient simulation notation has been designed for solving transient problems, in reality the notation may be used more generally. For example the transient simulations functionality can be used to perform multiple steady-state simulations with input parameters changing in a user defined way as a function of the <timestep>. As an example, in the following the material diffusivity <D> increases as a function of the <timestep>:

CELL_UNKNOWN <A> "1.d0" ON <domain> # an unknown is defined on all cells in the domain
CELL_EQUATION <A transport> "celldiv(<D>*facegrad(<A>))" ON <domain> # a steady state diffusion equation is solved on each cell
NONE_TRANSIENT <D> "" "<timestep>*1.d-10" # the diffusivity changes from 1.d-10 t 1.d-9 over the 10 'timesteps'
GENERAL_OPTIONS timestepmax=10 # setting the maximum timesteps in the simulation
# in reality this problem would also require boundary conditions to be set on <boundaries> for additional unknown variables

Variable definition modifiers

Along with the standard variable definition statements, variable statements can also be used to cancel, append or apply a default value for a variable using a definition modifier. The modifiers trail the variable definition keyword and are:

Example uses of definition modifiers are:

CONSTANT <A> 1.d0
CONSTANT- <A> # cancels <A> = 1.d0 definition
CONSTANT <A> "<a variable>" # now <A> = <a variable>
CONSTANT+ <A> "<b variable>" # now <A> = <a variable> + <b variable>
CONSTANT* <A> 3.d0 # statement is ignored as <A> has already been defined
CONSTANT <A> "<A>*4" # careful, as <A> = <a variable> + <b variable>*4, which is most likely a bug
CONSTANT <A> "(<A>)*4" # probably what was wanted, as now <A> = (<a variable> + <b variable>*4)*4
CONSTANT <A> CANCEL # legacy equivalent to CONSTANT- <A> that cancels <A>
FACE_DERIVED <A> "<facex[l=1]>" ON <allfaces> # completely new definition for <A>

Variable units

Units are defined using the [] brackets that follow the variable name. The units definition is optional, defaulting to ‘1’ (implying non-dimensional) if not defined. Units are generally just strings that are passed through the code to the output files, however the code has some capability of converting between different unit types using the convertunits string as detailed below. To use the convertunits script the units must be specified using fairly simple mathematical forms. Example units specifications that are compatible with convertunits include:

CONSTANT <A> [m^3/s] 2.d0
CONSTANT <B> [m3 s-1] 4.d0
CONSTANT <C> [nM/s] 5.d0 convertunits # convertunits will convert the number to standard basis on read
CONSTANT <D> [pJ K /kg] 3.d0 convertunits
CONSTANT <E> [A/(m s)] 0.1d0 # ERROR! use of brackets in units is not allowed

Variable expression or numerical value

Following the units definition an expression can be specified, or as an alternative for CONSTANT variables only, a numerical value can be specified instead. All user variables require either an expression or numerical value.

Expressions must be quoted in either single (') or double (") quotes, and will contain a combination of mathematical operations (+-*/() etc), maxima functions (log, sin, etc), arb operators (celldiv, facesum, etc) and arb variables and regions (<a variable>, <allcells>, etc). Variable expressions are interpreted using the setup_equations.pl script (and in turn maxima) and are hard coded into the fortran exectuable, with the implication that every time an expression is altered the setup script will need to be rerun and the code recompiled.

Unlike variable expressions numerical values may only be specified for CONSTANT variables (any centring) and are distinguished from variable expression by NOT being quoted. Numerical values are read directly by the fortran exectuable (as opposed to the setup script setup_equations.pl), meaning that if a numerical constant value is changed then the fortran code does not have to be recompiled - this is the advantage of using numerical values. It is good practice to use the character ‘d’ to specify the exponent in any numerical value, as these values are read by fortran and within fortran this notation means that a full double precision float value (roughly 16 significant figures) will be specified as opposed to only a real float specification (roughly only 8 significant figures, although actually any ‘e’ exponents are converted to ‘d’ exponents before being read anyway).

The following gives some examples of variable expressions and numerical values

CELL_DERIVED <A> "<cellx[l=1]>^2" ON <allcells> # double quotes specify an expression
FACE_CONSTANT <C> '<facex[l=2]>+<facex[l=3]>' ON <allfaces> # single quotes also specify an expression
CELL_OUTPUT <B> "(6!)*log(<cellvol>)" ON <boundarycells> # here we use the maxima factorial expression (only works with integers) and the natural log function
CONSTANT <diameter> [mm] 4.d0 convertunits # a numerical value is specified for <diameter>
CONSTANT <diameter_mm> [mm] "4.d0" # this is also a constant value, but as it is contained in an expression changing this value will result in code recompilation - bad practice
CONSTANT <diameter_m> [m] "noneconvertunits(<diameter_mm>)" # this ends up having the same value as <diameter>
CELL_CONSTANT <silly rho> [kg/m^3] 0.123e23 ON <allcells> # all <silly rho> variables are assigned a constant value

A special case of constant variables can be specified using the REGION_LIST and REGION_CONSTANT keyword combinations. The purpose of these keywords is to allow a constant to be read in (directly by the fortran exectuable) that has different constant values for different regions. This definition can be used in the file to assign different numerical values to either a cell/face/node centred constant in specific regions. Two statements are required for this type of constant definition: The first defines the list of regions where the next constant will be set (REGION_LIST) and the second defines the constant and sets/lists the corresponding numerical values (REGION_CONSTANT). The region names in the statement must have the same centring as the following statement. Furthermore, the regions over which the constant is defined must include all of the regions listed within the previous statement.

REGION_LIST <region1> <region2> ... <regionN> # comments
CELL_REGION_CONSTANT <name> [units] value1 value2 ... valueN ON <region> options # comments
FACE_REGION_CONSTANT <name> [units] value1 value2 ... valueN ON <region> options # comments

In the following example the two regions <subset A> and <subset B> are cell regions that are subsets of <allcells>. The following commands define two property constant variables over these regions:

CELL_REGION <subset A> "withinbox(0,1,0,1,0,1)" ON <allcells> # defines a region that is a subset of <allcells>
CELL_REGION <subset B> "compound(<domain>-<subset A>)" ON <domain> # this is any cell that is within <domain> (itself a subset of <allcells>) but not within <subset A>
REGION_LIST <subset A> <subset B> # this is the list of regions that is applied to every following constant list command until another region list command is specified
CELL_REGION_CONSTANT <rho> [kg/m^3] 500.d0 300.d0 ON <allcells> # defines <rho> to be 500 within <subset A>, 300 within <subset B> and 0 elsewhere within <allcells>
CELL_REGION_CONSTANT <mu> [Pa s] 1.d0 0.5d0 ON <allcells>

REGION_LIST/REGION_CONSTANT keywords are useful for specifying constant material properties that vary with position.

Variable centring and region

All variables must have a centring. If not defined then NONE centring is assumed.

Additionally, all variables that are CELL, FACE or NODE centred must be defined on a region that has the same centring as the variable. The associated region is defined using the ON <region> notation. Variables may be defined on regions that are either static or dynamic (noting that dynamic regions change as the simulation progresses), however if a variable is defined on a dynamic region then it will actually be assigned values on all elements within the parent static region that houses the dynamic region. For example, in the following

CELL_DERIVED <dynamic variable> "<phi>" ON <dynamic region> # variable is defined on a dynamic region
CELL_DERIVED_REGION <dynamic region> "variable(<a changing variable>)" ON <allcells>

the DERIVED variable <dynamic variable> will adopt of the value of <phi> for every cell element within <dynamic region>. Noting that <dynamic region> is a dynamic region that is a subset of the static (system) region <allcells>, <dynamic variable> will actually be defined for all cells within <allcells>, but be zero if the cell is contained within <allcells> but not within the current <dynamic region>.

Note that referring to a variable value outside its (static parent) region of definition will produce a memory error when the fortran executable is running.

If not specified by default a CELL centred variable will be defined over <domain> if it is an equation, or <allcells> otherwise. Similarly if not specified a FACE variable will be defined over <boundaries> if it is an equation, or <allfaces> otherwise. A NODE variable will be defined over <allnodes> if it is not specified. If in doubt, specify!

Variable types

The eight user variable types are now defined in more detail:

CONSTANT

Constant variables are evaluated once at the start of a simulation. They may be defined either by expression language (if quoted in single or double quotes) or just as a numerical constant (if not quoted) read directly by the fortran executable. The advantage of the latter method is that setup_equations.pl doesn’t have to be run again, so simulation setup is faster.

Defining statements:

CELL_CONSTANT <name> [units] "expression" ON <region> options # comments
FACE_CONSTANT <name> [units] "expression" ON <region> options # comments
NODE_CONSTANT <name> [units] "expression" options # comments
NONE_CONSTANT <name> [units] "expression" options # comments
CELL_CONSTANT <name> [units] numerical_constant ON <region> options # comments
FACE_CONSTANT <name> [units] numerical_constant ON <region> options # comments
NODE_CONSTANT <name> [units] numerical_constant options # comments
NONE_CONSTANT <name> [units] numerical_constant options # comments

Examples:

CELL_CONSTANT <test constant> "<cellx[l=1]>^2" ON <boundarycells>
FACE_CONSTANT <test constant 2> [m] "<facex[l=2]>" # default region of <allfaces> will be implied
CONSTANT <mu> [Pa s] 1.0d-3 # fluid viscosity
NONE_CONSTANT <rho> [kg/m^3] 997 # fluid density

As discussed above, constants may also be defined using the REGION_LIST and REGION_CONSTANT keyword combination, defined by

REGION_LIST <region1> <region2> ... <regionN> # comments
CELL_REGION_CONSTANT <name> [units] value1 value2 ... valueN ON <region> options # comments
FACE_REGION_CONSTANT <name> [units] value1 value2 ... valueN ON <region> options # comments

An example of this type of specification is

REGION_LIST <inlet> <outlet> # some face regions
FACE_REGION_CONSTANT <electric field> [V/m] 10 20. ON <boundaries> 

TRANSIENT

Transient variables are used only in transient simulations, and are evaluated at the start of each timestep. Transient variables are typically used to store previous timestep values, or to provide constant data to a simulation that depends explicitly on the time. Transient variables are defined using two expressions, with the first representing the initial value for the variable and the second used to update the variable at the start of each timestep:

CELL_TRANSIENT <name> [units] "initial expression" "update expression" ON <region> options # comments
FACE_TRANSIENT <name> [units] "initial expression" "update expression" ON <region> options # comments
NONE_TRANSIENT <name> [units] "initial expression" "update expression" options # comments
NONE_TRANSIENT <name> [units] "" "update expression" options # this will use the update expression as the initial expression
NONE_TRANSIENT <name> [units] "update expression" options # the initial expression here depends on rstep

Along with the rules detailed for other variables, transient variables are associated with particular relative timesteps (or relsteps). Relative timesteps indicate how many timesteps previous to the current one the variable refers to. The value of a variable is defined in a similar manner to the direction of a variable, using an index in square brackets at the end of the variable name: For example <t[r=0]> would represent the time at the end of the current timestep, <t[r=1]> would be time at the end of the previous timestep, <t[r=2]> the time at the end of (earlier) timestep before that one and so on. If an index is omitted from a definition, then r=0 is assumed. Actually, any type of variable can be associated with any particular relative timestep, but it is rare to do this with anything other than a transient variable.

Along with the usual (in this case second) expression definition, the optional first expression is applied once (only) at the start of a simulation, and represents the variable’s initial condition. If an initial expression is not given at all (no quotation marks present for this field), then the value of zero is assumed if the variable has r=0, or the update expression otherwise. If the initial expression is not specified but quotation marks are present for this field, then the update expression is substituted for the initial expression - ie, a shorthand way of repeating the update expression.

The second expression for the transient variable is the update expression that is applied once at the start of each timestep. These expressions are applied in the order of decreasing relstep (relative timestep), meaning that the earliest time value is calculated first, followed by the next timestep value, until the current time (r=0) is reached. Circular references are not allowed in the expression — in practice this is not limiting by carefully considering the relstep update order of variables.

Examples:

NONE_TRANSIENT <t[r=0]> "0.d0" "<t[r=1]>+<dt>" # current end-of-timestep time (r=0)
NONE_TRANSIENT <t[r=1]> "<t>-<dt>" "<t>" # time at last step (r=1)
NONE_TRANSIENT <t[r=2]> "<t[r=1]>-<dt>" "<t[r=1]>" # time at step before last step (r=2, assuming a constant dt)
NONE_TRANSIENT <z[r=1]> [m] "<z>-<w_0>*<dt>" "<z_real>" # position of ball at last step (r=1)
NONE_TRANSIENT <w[r=1]> [m/s] "<w>" "<w_real>" # velocity of ball at last step (r=1)

DERIVED

Derived variables can depend on any other variables and are updated as the UNKNOWN variables are updated within the main Newton iteration loop. These variables are the main workhorse variables used to setup systems of equations to be solved.

The defining statements are:

CELL_DERIVED <name> [units] "expression" ON <region> options # comments
FACE_DERIVED <name> [units] "expression" ON <region> options # comments
NODE_DERIVED <name> [units] "expression" ON <region> options # comments
NONE_DERIVED <name> [units] "expression" options # comments

Examples:

FACE_DERIVED <tau[l=1,1]> "<p> - <mu>*2.d0*facegrad[l=1](<u[l=1]>)" output
CELL_DERIVED <graddivp[l=1]> "celldivgrad[l=1](<p>)" # divergence based pressure gradient

UNKNOWN

Unknown variables are those upon which the EQUATION variables ultimately depend. The objective of the Newton iteration loop is to choose appropriate UNKNOWN values such that all equations are satisfied (that is, equal zero). The expression for an UNKNOWN variable is the initial value used at the start of the first Newton iteration loop in a simulation. Choosing initial values that are as close as possible to the final solution gives the best chance of a simulation converging. In transient simulations the initial value for the variable usually has the physical meaning of the variables value at the zeroth timestep. In subsequent timesteps the UNKNOWN variables maintain the values from the end of the converged previous timestep when commencing each new Newton iteration loop. Usually when restarting a simulation (by default) input is specified for these variables so that they start the Newton loop with the values from the stored msh file.

Defining statements:

CELL_UNKNOWN <name> [units] magnitude "expression" ON <region> options # comments
FACE_UNKNOWN <name> [units] magnitude "expression" ON <region> options # comments
NODE_UNKNOWN <name> [units] magnitude "expression" ON <region> options # comments
NONE_UNKNOWN <name> [units] magnitude "expression" options # comments

Note that all UNKNOWN variables require a single scalar magnitude value that is used to normalise (or non-dimensionalise) their values when computing the Newton residual. By default this magnitude is calculated by examining the magnitude of the initial expression, however in some situations (such as a concentration that is initially zero) this process cannot determine this magnitude and instead it must be specified explicitly via the magnitude option (detailed in variable options list).

Examples:

CELL_UNKNOWN <u[l=1]> 1.d0 "<u_av>" # a velocity component
CELL_UNKNOWN <p> [] 1.d0 "1.d0-<cellx[l=1]>" # pressure
NONE_UNKNOWN <p_in> [Pa] 1.d0 "1.d0" # the pressure at the inlet

EQUATION

Equation variables represent the equations to be satisfied. The equation expressions should be formulated so that when the equation is satisfied, the expression equals zero. The number of EQUATION variables (in a per-element sense) must equal the number of UNKNOWN variables (again in a per-element sense). Furthermore, for the system to be well posed the equations must be functionally independent, meaning that no single equation can be made from a combination of the other equations.

Defining statements:

CELL_EQUATION <name> [units] "expression" ON <region> options # comments
FACE_EQUATION <name> [units] "expression" ON <region> options # comments
NODE_EQUATION <name> [units] "expression" options # comments
NONE_EQUATION <name> [units] "expression" options # comments

As for the UNKNOWN variables, EQUATION variables require a single scalar magnitude value which is used normalise their value when calculating the Newton loop residual. By default these are calculated from a combination of the initial unconverged EQUATION variable values, and from the product of the derivatives of the EQUATION variables with respect to the UNKNOWN variables, multiplied by each UNKNOWN magnitude. Generally this works as satisfactorily, however the magnitude can be set independently using various magnitude options as listed in the variable options list.

Examples:

CELL_EQUATION <continuity> "celldiv(<u_f>)" ON <domain> # continuity
FACE_EQUATION <outlet noslip> "dot(<u[l=:]>,<facetang1[l=:]>)" ON <outlet> # no component tangential to outlet
NONE_EQUATION <p_in for flowrate> "<u_av_calc>-<u_av>" # set flowrate through inlet to give required average velocity

OUTPUT

Output variables are evaluated once convergence of the solution has been reached. While designed for output purposes, they do not have to be output (by specifying the option nooutput) and can instead also be regarded as variables that are only evaluated once the Newton loop has converged. This can be handy in transient simulations if you want a variable to be calculated at the end of a timestep that will be carried over to the next timestep, but that is not involved in the actual iteration procedure.

Defining statements:

CELL_OUTPUT <name> [units] "expression" ON <region> options # comments
FACE_OUTPUT <name> [units] "expression" ON <region> options # comments
NODE_OUTPUT <name> [units] "expression" options # comments
NONE_OUTPUT <name> [units] "expression" options # comments

Examples:

NONE_OUTPUT <F_drag> [N] "facesum(<facearea>*dot(<facenorm[l=:]>,<tau[l=:,1]>),<cylinder>)" # force on object in axial direction

CONDITION

CONDITION variables control the running of the simulation. They can initiate the following actions: output, stop, convergence, indicate an error, cause timestep or newtstep rewinding and a bell. CONDITION variables are evaluated (tested) at various stages in the running of the code, depending on the particular action being tested.

Defining statements:

CELL_CONDITION <name> [units] "expression" ON <region> options # comments
FACE_CONDITION <name> [units] "expression" ON <region> options # comments
NODE_CONDITION <name> [units] "expression" options # comments
NONE_CONDITION <name> [units] "expression" options # comments

For a CONDITION variable, if the evaluated expression is positive (>0) then the condition is satisfied and the corresponding action will take place. Note that an action will take place if any of the condition variables that correspond to it are positive (in fact, after one positive value is found the remainder are not even evaluated). More than one action can be specified for each CONDITION variable. If a CONDITION variable is either CELL, FACE or NODE centred then it is evaluated for every element in its associated region, and the relevant actions are performed if the variable value is positive for any the associated elements. Note also that as CONDITION variables are evaluated in the order they are defined, they are only evaluated if the relevant condition has not already become true. Hence, a CONDITION variable value may not become positive in a simulation (ie, in the output) if another CONDITION variable of the same type (eg, outputcondition) is evaluated as true before hand.

What action is performed when the CONDITION variable becomes positive is specified via options, with the alternatives being outputcondition, stopcondition, convergencecondition, errorcondition, timesteprewindcondition, newtsteprewindcondition (not fully implemented) and bellcondition. More details are listed below in variable options list.

Examples:

NONE_CONDITION <time based stop condition> "<t>-<tend>" stopcondition # when this becomes true (>0.) the simulation stops
NONE_CONDITION <bouncing bell> "noneif(<z>,-1.d0,1.d0)" bellcondition # is positive when <z> is negative at the end of a timestep
NONE_CONDITION <output test> "<t>-<tout>-<dtout>" outputcondition # this will be true (>0.) whenever we are <dtout> from last output

LOCAL

LOCAL variables are like DERIVED (or OUTPUT or really any other) variables, except that they are not stored, but rather evaluated only when required. LOCAL variables may be used instead of DERIVED variables to save memory. This strategy makes sense if the variable is only going to be used only once or twice at each location. LOCAL variables may also be used to split up an otherwise long expression into smaller (and possibly common) sub-statements, dependent on the local conditions. For example, in the examples given below, LOCAL variables are used to calculate the second derivative of the normal velocity to a wall, in the normal direction to a wall.

Defining statements:

CELL_LOCAL <name> [units] "expression" ON <region> options # comments
FACE_LOCAL <name> [units] "expression" ON <region> options # comments
NODE_LOCAL <name> [units] "expression" options # comments
NONE_LOCAL <name> [units] "expression" options # comments

When referred to in other variable expressions, LOCAL statements can either be inlined, or evaluated independently depending on the option inline. By default inline is on for all LOCAL variables as this tends to result in the most efficient code. However if a LOCAL variable is referred to many times in the expression of another variable then it is possible that using noinline may result in slightly more efficient code. Note that the output option can also be specified for a LOCAL, which is a good strategy to (slightly) lower memory usage if the variable being output is not used for anything else. The region over which a LOCAL is defined is only really relevant if the output option is on.

Note also that a LOCAL variable may depend on the locale of the calling statement: For example for the evaluation of <u_n> in the following examples we refer to the <facenorm> of the face on which the local variable is calculated. For this type of LOCAL variable it would not make sense to output this separately over <allcells>, as the <facenorm> would be undefined and an error would result.

Examples:

CELL_LOCAL <u_n> "dot(<u[l=:]>,cellave[lastface](<facenorm[l=:]>))"
CELL_LOCAL <d u_n d x[l=1]> "cellgrad[l=1](<u_n>)"
CELL_LOCAL <d u_n d x[l=2]> "cellgrad[l=2](<u_n>)"
CELL_LOCAL <d u_n d x_n> "dot(<d u_n d x[l=:]>,cellave[lastface](<facenorm[l=:]>))"
FACE_LOCAL <d^2 u_n d x_n^2> "facegrad(<d u_n d x_n>)" ON <boundaries> output

SYSTEM

In addition to the user variables there are a number of system defined variables. See ref: system variables in VariableRegion.pm.

Variable options

Variable options synopsis

Following the region specification a comma separated list of options may be given for each variable. Options are used to specify additional information about variables, including how variables are output or input, how they are updated during convergence iterations, or how they are changed during timestep rewinds.

Variable options are generally specified using lowercase keywords, written without spaces or ’_’ characters separating words. Options statements such as output that can be either true or false can be specified using two formats: In the first a true value is implied by simply stating the option name, as in output, while a false value is specified by preceding the option with a no, as in nooutput; In the second format the true or false strings are written explicitly using fortran syntax, as in output=.true. or output=.false.. Other types of options accept a value, set using the option=value syntax. Setting an option that normally accepts a value to an empty string clears its definition, as in option=. Values can be quoted via either single of double quotes. If the value is a variable name, (as in magnitude=<a variable>) the variable name need not be quoted. Additionally, while most options are specific to the (component) variable being defined, some options such as output are actually specific to the compound variable that the current variable being defined is a component of. Not all options apply to all variable types.

Internally each option may be read by either the setup_equations.pl script (indicated by ‘p’ for perl in the following table) or by the fortran executable (indicated by ‘f’ for fortran in the table) — whether the option is read by the setup script or the fortran executable determines whether the simulation has to be recompiled when the option changes, with ‘p’ requiring recompilation and ‘f’ not.

Following the general philosophy of the arb syntax, options that are read last take precedence over options that are read first. Hence, options that are assigned to a variable lower down an input file take precedence over those that are assigned higher up in the file, and on a single variable definition line options that are written further to the right take precedence over options that are to the left. A special clearoptions keyword can be used to remove any options that have been assigned to a variable previously. For example, in the following:

CELL_DERIVED <A> "<facex[l=1]>" output # <A> now has output defined
VARIABLE <A> nooutput # but this is now superseded by nooutput
VARIABLE <A> output,nooutput,clearoptions,nooutput,output # clearoptions removes all previous options, but then output is finally read

the variable <A> eventually ends up with only the two options nooutput and output, however output was read last so takes precedence.

The keywords DEFAULT_OPTIONS and OVERRIDE_OPTIONS can also be specified to either set default options or override the options, respectively, for certain groups of variables or regions being read in. In their most basic form:

If either of these keywords is given without any trailing options, as in the example definition of

DEFAULT OPTIONS

then the (in this case) DEFAULT_OPTIONS are cleared and are no longer applied to the following variables and regions.

Actually the DEFAULT_OPTIONS and OVERRIDE_OPTIONS have many more specific varieties that apply to classes of variables and/or regions. In the above two basic forms, the options are applied to all following variables and regions until cancelled again by an empty definition. In there more complex form however they can be applied to individual groups of centrings, variable/region types and variable/regions. The more general format of these commands is defined via

DEFAULT_centring_type_entity_OPTIONS list,of,comma,separated,options
OVERRIDE_centring_type_entity_OPTIONS list,of,comma,separated,options

where centring=CELL|FACE|NODE|NONE, type=UNKNOWN|DERIVED|EQUATION|OUTPUT|TRANSIENT|NEWTIENT|CONDITION|LOCAL and entity=VARIABLE|REGION. If any of centring, type or entity are left out then the command is assumed to apply to all relevant following definition statements (until cancelled again by the same command, but now with no trailing options). As examples

DEFAULT_CELL_VARIABLE_OPTIONS output # sets the output option to be on by default for <a> and <c>, but not <d> and <e>
OVERRIDE_DERIVED_OPTIONS nooutput # sets the output option to be off (override) for <d> only
CELL_UNKNOWN <a>
FACE_DERIVED <d>
CELL_LOCAL <c>
DEFAULT_CELL_VARIABLE_OPTIONS # cancels the default options again for the cell centred variables
CELL_LOCAL <e>
OVERRIDE_DERIVED_OPTIONS # clears the particular override option again

Variable options list

The various options are now listed. In the following the ‘|’ notation implies ‘or’:

derivative|noderivative
For DERIVED|EQUATION|LOCAL (p): Do or do not calculate Jacobian derivatives for this variable. If this derivative is not calculated then convergence will be slowed, however in rare instances where derivatives could be ill-defined, not able to be calculated or undergo step changes (not-continuous) then setting the derivative of a function to zero may allow a simulation to converge. Default is derivative for all DERIVED|EQUATION|LOCAL variables (and makes no sense for any other type of variable).
positive|negative|nocheck
For DERIVED|UNKNOWN|EQUATION|LOCAL (p): Check at each iteration that variable is positive or negative, or do not check.
derivative|noderivative
For DERIVED|EQUATION|LOCAL (p): Do or do not calculate Jacobian derivatives for this variable. If this derivative is not calculated then convergence will be slowed, however in rare instances where derivatives could be ill-defined and the residual is not heavily dependent on the variable then ignoring its derivative may allow a simulation to converge.
positive|negative|nocheck
For DERIVED|UNKNOWN|EQUATION|LOCAL (p): Check at each iteration that variable is positive or negative, or do not check. Including one of these positive|negative options causes the code to check the sign of the relevant variable. In theory this could be used for quantities like concentrations that are only physically meaningful when positive. By using an expression such as 1-<concentration> and including the positive option an upper limit for a variable can also be enforced. In practice using these types of limiting conditions to prevent equation singularities slows convergence to an unfeasibly slow rate. It is usually better to choose the form of the equations so that they are stable even for small unphysical excursions, and then check once convergence has been achieved that the results are physical.
output|nooutput
For all user variables (f): Output compound to msh files. For example, if output is specified for the vector <v[l=1]>, then all components of this vector (including any empty components) will be written to the msh file. A vector such as <v> (in compound notation) will appear as a vector in gmsh. The default is output for all UNKNOWN and OUTPUT variables, as well as CELL centred DERIVED variables and any TRANSIENT variables that do not correspond to the oldest stored relstep (that is, output is on for relstep < max(relstepmax,1), noting that the relstepmax data is not required for a simulation restart). All other variables have nooutput by default.
compoundoutput|nocompoundoutput
For all user variables (f): These are synonyms for output|nooutput.
componentoutput|nocomponentoutput
For all user variables (f): Output just this component to the msh files. For example, if output is specified for the vector <v[l=1]> then this specific component will be output to the msh file as <v[l=1]> and will appear as a scalar. The output (or equivalently compoundoutput) and componentoutput variables may be set independently. The default is nocomponentoutput for all variables.
stepoutput|nostepoutputupdate|stepoutputnoupdate|nostepoutput
For all user variables (f): Output compound to the step file, which typically is written to more regularly that the msh files and contains data used to monitor simulation convergence or process conditions. The nosetpoutputupdate option does not write the variable to the step file, but does update its value when the step file is written. This is useful if you want an OUTPUT variable updated during the step file output as another variable depends upon it, but you don’t want the variable output. The stepoutputnoupdate alternative does the opposite, in that the variable is not updated when the step file is written but its value is still written. This is useful for recording when (eg) the msh file was last written. Finally the nostepoutput option neither updates or writes the value to the step file. The default is stepoutput for all UNKNOWN, DERIVED, OUTPUT and TRANSIENT NONE centred variables that correspond to the current timestep (relstep=0).
compoundstepoutput|nocompoundstepoutputupdate|compoundstepoutputnoupdate|nocompoundstepoutput
For all user variables (f): Synonyms of stepoutput|nostepoutputupdate|stepoutputnoupdate|nostepoutput as above
componentstepoutput|nocomponentstepoutputupdate|componentstepoutputnoupdate|nocomponentstepoutput
For all user variables (f): As per stepoutput|nostepoutputupdate|stepoutputnoupdate|nostepoutput, but applied to the component variable rather than its compound.
input|noinput
For all stored user variables (ie, not LOCAL) (f): Read in compound from msh files when starting the simulation, overwriting any initial data set from expressions. It probably doesn’t make much sense to read in CONDITION and EQUATION variables, but you can… Default is input for all UNKNOWN and TRANSIENT variables and noinput for everything else.
componentinput|nocomponentinput
For all stored user variables (ie, not LOCAL) (f): as for input|noinput, but for the individual component rather than the compound.
elementdata|elementnodedata|elementnodelimiteddata
For CELL centred user varables (f): These options control how CELL centred data is written to msh files for compound variables. If the elementdata option is chosen then only one compound variable value per cell is written to the msh file, corresponding to the average or centroid value of that variable for the cell. When gmsh displays elementdata using a contour plot the colour within each cell will be uniform (and the field will appear ‘blocky’). If instead elementnodedata is chosen instead then a value will be written to the msh file for every node that surrounds every cell. The average of these values will still equal the average (or centroid) value for the cell, however now gmsh will display a contour plot of this variable using a gradient of colours within each cell. This is preferable for data visualisation (the plots don’t appear ‘blocky’ anymore) but there are more values written to the msh file with the result that the msh file is larger. The final option, elementnodelimiteddata is the same as elementnodedata, however the gradient chosen to calculate the node values within each cell is limited such that no node value within a particular cell lies outside the bounds of the average (or centroid) values of the surrounding cells. This option is a sensible choice if data visualisation is required for a variable that should be bounded between strict limits - for example, concentrations that should not range below zero. elementnodedata and elementnodelimiteddata have no effect on FACE, NODE and NONE centred variables. Default is elementnodelimiteddata for all CELL centred scalar variables, and elementdata for everything else.
compoundelementdata|compoundelementnodedata|compoundelementnodelimiteddata
For all CELL centred user variables (f): synonyms for elementdata|elementnodedata|elementnodelimiteddata.
componentelementdata|componentelementnodedata|componentelementnodelimiteddata
For all CELL centred user variables (f): as per elementdata|elementnodedata|elementnodelimiteddata, but applied just to components. Default is componentelementdata for all variables.
#p  outputcondition,stopcondition,convergencecondition,bellcondition - for CONDITION, type of condition, can have multiple conditions for the one variable
#f  magnitude=value - for EQUATION, UNKNOWN specifies the initial variable magnitude to be used (rather than being based on the initial variable values) - a negative number will cause the magnitude to be set based upon the initial values (which is the default)
#f  dynamicmagnitude/staticmagnitude - for EQUATION, UNKNOWN, adjust magnitude of variable dynamically as the simulation progresses, or keep it constant at the initial magnitude
#f  dynamicmagnitudemultiplier=value - for EQUATION, UNKNOWN, multiplier to use when adjusting magnitude of variable dynamically (=>1.d0, with 1.d0 equivalent to static magnitudes, and large values placing no restriction on the change in magnitude from one newton iteration to the next)
#   clearoptions - remove all previously (to the left and above the clearoptions word) user-specified options for this variable
#f  timesteprewind - this variable gets rewound if a timestep rewind is performed
#f  timesteprewindmultiplier=value - and further that it is multiplied by this amount on rewind, either a number or a reference to a none-centred variable (can be a local)
#f  newtsteprewind - this variable gets rewound if a newtstep rewind is performed
#p  inline|noinline - where possible substitute this equation in other equations rather than evaluating as a separate variable (inline default for locals, noinline default for others)
#p  convertunits(|=finalunits) - for (NUMERICAL_)CONSTANT, convert variable magnitude when read into fortran from originalunits specified in arb file to finalunits.  If finalunits is left out then convert to standard SI units

magnitude - (required): An order of magnitude estimate (postive and greater than zero real or double precision value) must be specified for all unknown variables. This magnitude is used when checking on the convergence of the solution.

conditions - : For transient and steady-state simulations, indicates when the Newton loop has converged. Is evaluated at the start of each Newton loop.

-   : For a transient simulation, indicates when the simulation
    should finish. Is evaluated at the end of each
    successful timestep.

-   : For a transient simulation, indicates when the output files
    should be written. Is evaluated at the end of each
    successful timestep.

-   : For a transient simulation, indicates when a noise should be
    made (this one’s a bit silly). Is evaluated at the end of each
    successful timestep.

Expression Language Overview

The expression language refers to the psuedo-mathematical language that is used to represent each variable’s expression. arb uses the symbolic algebra program ‘maxima’ to parse this language and convert these expressions into executable (fortran), so any mathematical operators supported by ‘maxima’ are able to be used in this language. In addition to maxima’s features, the expression language also supports a number of arb specific discretisation operators that allow spatially varying problems to be expressed in scalar arithmetic. The discretisation operators are particularly suited to solving transport problems using the Finite Volume Method and are detailed in this section.

Discretisation Operators

Syntax

Discretisation operators produce a single result from the arguments that are contained within their parentheses (). They also accept options, contained within square brackets [], and placed between the operator name and any parentheses. Operators are (by convention) typed lowercase (although should parse in uppercase) and contain no underscores, as per

operator[option1,option2,...](<argument1>,<argument2>,...)

Example facegrad and celldiv operators contained within variable definitions:

FACE_OUTPUT <phigrad> "facegrad[adjacentcells](<phi>)" ON <allfaces> # operator is facegrad, argument is <phi> and a single option of adjacentcells is specified
CELL_EQUATION <continuity> "celldiv(<u_f>)" ON <domain> # operator is celldiv acting on single argument of <u_f>

Operator Centring

The centring of an operator refers to the centring of the result it produces. This centring must match or be consistent with the centring of the context in which the operator is placed. The centring of most operators corresponds to the first syllable of the operator name, however there are some exceptions. For the exceptions the centring of the operator is none, and the first syllable of the operator name corresponds to the centring of the first argument passed to the operator.

To illustrate, following the centring rule is celldiv which generates the cell centred divergence of a face centred quantity. This operator is cell centred and hence must be used in a cell centred context. Note that the content expression passed into this operator (actually its first argument) is face centred however. Similarly, facegrad is the gradient of a cell centred quantity evaluated at a face, so this operator is face centred and must be used in a face centred context, but its argument (content) has cell centring.

"celldiv(<u_f>)" # cell context centring, face argument centring
"facegrad(<phi>)" # face context centring, cell argument centring

Exceptions to the centring rule include the loop-type operators, max, min, and sum. For example, cellmax loops through a region of cells finding the maximum value of an expression within those cells. Hence, this operator produces a result which has no centring (none centred) so can be used in any centring context, but its first argument has cell centring. facesum loops through a region of faces summing the values of its first argument, hence producing a none centred result that can be used in any centring context.

"cellmax(<phi>,0.d0)" # none context centring, cell centring of the first argument <phi>
"facesum(<phi_f>,0.d0,<allfaces>)" # none context centring, face centring of the first argument <phi_f>

The centring of specific operators is detailed in the reference section.

Operator Arguments

Implicit Operator Arguments

Each operator accepts a certain number of arguments, however if an argument is not specified then a default value may be used. For example, cellmax uses three arguments:

  1. an expression that is to evaluated in each cell (<expression>), here denoted by a single variable, but more usually an expression of variables;
  2. an initial, default expression for the operator (<default>), which again could be an expression of variables; and
  3. the cell centred content region over which the maximum will be calculated and within which <expression> must be defined (<region>).

Using implicit argument notation, operators expect the arguments in a specific order, so cellmax expects these three arguments in the manner

"cellmax(<expression>,<default>,<region>)"

If less than the required number of arguments are passed to an operator, then a default value for the omitted arguments will be assumed (or if no defaults are available or are sensible, an error will be flagged). For example, using

"cellmax(<expression>)"

sets <default> to -<huge> (the largest negative double precision number that the processor can store) and <region> to <noloop> if (for example) the expression was being used in a cell centred context. If in doubt about what the default value for an argument is, specify it!

Explicit Operator Arguments

The alternative to the implicit argument notation is to specify the arguments explicitly (similar to argument passing in f90). Using explicit notation the order of the arguments that are passed explicitly is irrelevant, however the order of any arguments that are not explicitly named (and hence specified implicitly) still is. For example, the following will all produce the same result

"cellmax(expression=<expression>,default=<default>,region=<region>)"
"cellmax(<expression>,<default>,<region>)"
"cellmax(region=<region>,default=<default>,expression=<expression>)"
"cellmax(<expression>,region=<region>,<default>)"
"cellmax(region=<region>,<expression>,<default>)"

Note in the last case that although <expression> was the second argument in the operator, it was the first implicitly named operator, so would be read correctly. Using a combination of the implicit and explicit passing is often convenient. For example, for the cellmax operator, the following form that uses a default value of -<huge> but performs the maximum comparison over a specified region is handy

"cellmax(<expression>,region=<region>)" # as default is omitted, the last (third) argument must be explicitly named

Operator options are similar to variable options. Some operators require a dimension, and this dimension (direction) is specified via the options. For example, celldivgrad calculates a gradient in a certain direction dimension using the divergence of a face centred scalar. To find this gradient in the second dimension you use the option [l=2]:

"celldivgrad[l=2](<face centred expression>)"

Some options are quite generic (eg, noderivative), however most are specific to the operator. There is no restriction on the order that options are specified.

Details of individual discretisation operators follows. However ultimate details of each operator (including argument order, options etc) can be found in the code file VariableRegion.pm which shows how they are expanded into working code. Use search strings such as ref: celldiv within this perl file to find the specific code.

Discretisation Operators Listing

celldiv : Divergence

Summary:

Uses Gauss’ theorem to calculate the divergence of a face centred vector component around a cell.

Statement:

"celldiv[options](expression=<expression>)"

Centring:

Operator is (context) cell centred, and expression is face centred.

Details:

Using Gauss’ theorem to evaluate divergences around cells is probably the defining characteristic of Finite Volume methods. celldiv performs this operation.

Specifically, to discretise the divergence of a face centred vector \(\vect[j]{u}\) over a cell \(i\) that sits within the domain, Gauss’ theorem gives

\[\begin{aligned} \frac{1}{\scali[i]{V}} \int_{\scali[i]{V}} \vect{\nabla} \cdot \vect{u} dV & \Rightarrow \frac{1}{\scali[i]{V}} \sum_{j \in \scali[\text{nobcellfaces},i]{\mathbb{J}}} \frac{1}{\scali[j]{S}} \int_{\scali[j]{S}} \vecti[i,j]{N} \cdot \vecti[j]{u} \, dS \\ & = \explain{\sum_{j \in \scali[\text{nobcellfaces},i]{\mathbb{J}}} \frac{\vecti[i,j]{N} \cdot \vecti[j]{n} }{\scali[i]{V}}}{\normalsize\code{celldiv}} \frac{1}{\scali[j]{S}} \int_{\scali[j]{S}} \vecti[j]{n} \cdot \vecti[j]{u} \, dS \nonumber \\ %= \frac{1}{\scal[cell]{V}} \int_{\scal[cell]{S}} \vect[cell]{n} \cdot \vect{u} dS = \frac{1}{\scal[cell]{V}} \sum_j (\vect[cell]{n} \cdot \vecti[j]{n}) (\vect{u} \cdot \vecti[j]{n}) \scali[j]{S} \nonumber \\ & \Rightarrow `celldiv(dot(<u[l=:]>,<facenorm[l=:]>))` \end{aligned}\]

where \(\scali[i]{V}\) and \(\scali[j]{S}\) are the volume and total surface area of the cell \(i\) and face \(j\), respectively, \(\vecti[i,j]{N}\) is a unit normal pointing outward from cell \(i\) but located at face \(j\), \(\vecti[j]{n}\) is a normal associated with face \(j\), and the sum is conducted over the set of all face elements that surround cell \(i\), denoted by \(\scali[\text{nobcellfaces},i]{\mathbb{J}}\). In the equivalent coding the face centred vector \(\vecti[j]{u}\) is represented by the three component variables , and , and the unit normal associated with the face \(j\), \(\vecti[j]{n}\), is given by the system component variables , and . Note that as the divergence of a vector results in a scalar, the above operation produces a scalar for each cell it is performed in.

The region used by arb in performing the above sum as represented by \(\scali[\text{nobcellfaces},i]{\mathbb{J}}\) is (‘no-boundary-cell-faces’). This relative region specifies all faces that surround a given cell, unless that cell is a boundary cell. As boundary cells are not fully surrounded by faces Gauss’ theorem can not be applied. Hence, if the operator is used at a boundary cell then the region is taken relative (moved) to the closest domain cell that is adjacent the boundary cell, so this is where becomes evaluated. Physically it is inadvisable to use an equation that involves a divergence at a boundary cell anyway.

Options:

[noderivative] : No derivatives with respect to the unknown variables for the Newton-Raphson Jacobian are calculated for this operator (and its contents).

Examples:

CELL_EQUATION <continuity> "celldiv(<u_f>)" ON <domain> # continuity equation
CELL_EQUATION <momentum[l=1]> "celldiv(<J_f[l=1]>)" ON <domain> # momentum conservation in direction l=1
CELL_EQUATION <momentum[l=2]> "celldiv(<J_f[l=2]>)" ON <domain> # momentum conservation in direction l=2

cellgrad, facegrad or nodegrad: Gradient

Summary:

Calculates a scalar component of a gradient from surrounding cell values at the location of a cell, face or node.

Statement:


Centring:

is context cell centred and is context face centred. In both cases is cell centred.

Details:

To calculate the gradient of a cell centred scalar \(\scali[i]{\phi}\) in coodinate direction \(2\) in cell \(i\), \[\frac{1}{\scali[i]{V}} \int_{\scali[i]{V}} \vecti[2]{e} \cdot \vect{\nabla} \phi dV \Rightarrow \sum_{i' \in \scali[\text{cellcells},i]{\mathbb{I}}} \scali[i,i']{\cellcentred{k}^{(2)}} \scali[i']{\phi} \Rightarrow \code{cellgrad[l=2](phi)} \nonumber\] where \(\vecti[2]{e}\) is a unit vector in coordinate direction \(2\), \(\scali[i,i']{\cellcentred{k}^{(2)}}\) is a predetermined kernel for this operation, and \(\scali[\text{cellcells},i]{\mathbb{I}}\) is the set of all cells in the vicinity of cell \(i\) that are used by this kernel. Kernels to calculate the cell gradient in the other coordinate directions, that is \(\scali[i,i']{\cellcentred{k}^{(1)}}\) and \(\scali[i,i']{\cellcentred{k}^{(3)}}\) also exist.

A gradient of a cell centred quantity evaluated at a face can be calculated similarly, for example \[\frac{1}{\scali[j]{S}} \int_{\scali[j]{S}} \vecti[3]{e} \cdot \vect{\nabla} \phi dS \Rightarrow \sum_{i \in \scali[\text{facecells},j]{\mathbb{I}}} \scali[j,i]{\facecentred{k}^{(3)}} \scali[i]{\phi} \Rightarrow \code{facegrad[l=3](phi)} \nonumber\] Gradients taken in directions relative to the face orientation are also available using the operator. Index \(4\) gives the gradient relative to the face’s normal, that is \[\frac{1}{\scali[j]{S}} \int_{\scali[j]{S}} \vecti[j]{n} \cdot \vect{\nabla} \phi dS \Rightarrow \sum_{i \in \scali[\text{facecells},j]{\mathbb{I}}} \scali[j,i]{\facecentred{k}^{(4)}} \scali[i]{\phi} \Rightarrow \code{facegrad[l=4](phi)} \nonumber\] In computational terms the face normal is represented by (,, ). Indices \(5\) and \(6\) give gradients in the directions of the first and second tangents for each face, respectively, that is \[\frac{1}{\scali[j]{S}} \int_{\scali[j]{S}} \vecti[j]{t}^{(1)} \cdot \vect{\nabla} \phi dS \Rightarrow \sum_{i \in \scali[\text{facecells},j]{\mathbb{I}}} \scali[j,i]{\facecentred{k}^{(5)}} \scali[i]{\phi} \Rightarrow \code{facegrad[l=5](phi)} \nonumber\] and \[\frac{1}{\scali[j]{S}} \int_{\scali[j]{S}} \vecti[j]{t}^{(2)} \cdot \vect{\nabla} \phi dS \Rightarrow \sum_{i \in \scali[\text{facecells},j]{\mathbb{I}}} \scali[j,i]{\facecentred{k}^{(6)}} \scali[i]{\phi} \Rightarrow \code{facegrad[l=6](phi)} \nonumber\] Computationally \(\vecti[j]{t}^{(1)}\) is represented by (,, ) and \(\vecti[j]{t}^{(2)}\) by (,, ), respectively. If the face has one dimension then \(\vecti[j]{t}^{(1)}\) will be directed along the face, and \(\vecti[j]{t}^{(2)}\) will be normal to both \(\vecti[j]{t}^{(1)}\) and \(vecti[j]{n}\). If the face has no or two dimensions (a point or a plane) then there are no preferential directions for these tangents. If no index is specified on the operator then is assumed.

Options:

Examples:

FACE_DERIVED <T flux> "-<D>*facegrad(<T>)" ON <all faces> # some type of heat flux occuring across each face
CELL_DERIVED <dpdx[l=1]> "cellgrad[l=1](<p>)" # gradient of pressure in first dimension

: Interpolation to cell centring

Summary: Interpolates or averages an expression from (mainly) face centring to cell centring.

Statement:


Centring:

is context cell centred and generally takes a face centred expression (see option however).

Details:

Without any options, predefined kernels are used to interpolate the face centred expression from the faces that surround a cell to the centroid of that cell.

Options:

: Interpolation

Summary: Interpolates or averages an expression from cell to face centring.

Statement:

Centring:

has face context centring. is cell centred. is face centred. is cell centred.

Details:

TODO

Options:

or : Sum

Summary: Performs a sum over a region of either cell or face elements.

Statement:




Centring:

Operators may be cell, face or none centred. Contents of is cell centred, contents of is face centred.

Details:

This operator sums the contained expression over a region of cell or face elements. If no region is specified, then default regions are applied, defined by:

Operator centring Expression centring Default region ——————- ——————— —————-

Options:

: Gradient evaluated at a cell calculated via a divergence

: Gradient limiter for ensuring advection stability

, or : If conditional statement

or : Product performed over a region of elements

, or : Picks the minimum/maximum from a region of elements

or : A delta function to identify specific regions

arb

v0.70

manual

contents