Functions and Operators
Function and operators are used in the same way as part of an expression: a function or operator name followed by a list of argument expressions enclosed in parentheses, for example atan2(dx,dy) or comp1.at2(x0,y0,u). The name behaves like a variable name with respect to Namespace Lookup. This means that the same base name may be defined in multiple namespaces. For example root.an1(x) and root.comp1.an1(x) may be different functions where the latter will hide the former if referred to as just an1(x) in an input field in Component comp1.
While they use the same syntax, there are important differences between functions and operators. A function is always a self-contained object that maps argument values to output values. This means that the result of a function evaluation does not depend on anything other than its arguments. When the function is evaluated, its argument expressions are first evaluated to numbers, real or complex, before being passed to the function. This in practice means that all true functions can be used as part of a parameter expression.
An operator may deviate from the strict constraints of a function in a number of ways:
If may be defined differently on different geometric entities. An Expression Operator can for example be set up as a wrapper which evaluates different coupling operators on different domains.
It may act on its argument expressions rather than on their values. This is often referred to as a symbolic operator. Prime examples are the differentiation operator d(<expression>,<variable>) and the summation operator sum(<expression>,<variable>,<lower>,<upper>).
Units in Functions
Functions do not handle units internally. This is natural since the value of a unit expression depends on the unit system context, and function objects are expected to be independent of their evaluation context. Most built-in functions, and in particular the standard mathematical functions, are defined in one of two possible ways:
User-defined functions expect their arguments to be evaluated in a specific set of units and return a value in a specified unit. Both arguments and return value are by default treated as dimensionless with unit 1, which makes the function behave as in the first case above. If other units are specified, a rescaling is automatically performed.
For example, if the interpolation function int1 is created from the stress history of an experiment, it may contain measurements in megapascal taken at times measured in minutes. Therefore, when creating the function, you set the argument unit to min and the function unit to MPa. If the function is used in a physics feature to apply a time-dependent load with expected input unit Pa, you enter the load as int1[t]. When the expression is parsed, the specified function units will be inserted, transforming the expression to int1(t[1/min])[MPa], where the function is now assumed to be dimensionless. Note that multiplying the variable t, with values in the base unit system time unit (seconds in practice), with the inverse of the expected input unit will transform the value to minutes. This symbolic operation takes place at the same time as the Namespace Lookup.