Define specialized class *function*

functionsiinputReal x;outputReal y;algorithmy =if abs(x) < Modelica.Constants.epsthen1elseModelica.Math.sin(x)/x;endsi;

[encapsulated][partial]functionIDENT class_specifier class_specifier : string_comment compositionendIDENT | "=" base_prefix name [ array_subscripts ] [ class_modification ] comment | "="enumeration"(" ( [enum_list] | ":" ) ")" comment

See Modelica Language Specification for further details.

The keyword function is used to define functions as known from programming languages. Each part of a function interface must either have causality equal to input or output. A function may not be used in connections. In functions, no equations or initial algorithm and at most one algorithm clause are allowed. Calling a function requires either an algorithm clause or an external function interface.

The syntax and semantics of a function have many similarities to those of the block specialized class. A function has many of the properties of a general class, e.g., being able to inherit other functions, or to redeclare or modify elements of a function declaration.

Modelica functions have the following restrictions compared to a general Modelica class:

- Each input formal parameter of the function must be prefixed by the keyword input, and each result formal parameter by the keyword output. All public variables are formal parameters.
- Input formal parameters are read-only after being bound to the actual arguments or default values, i.e., they may not be assigned values in the body of the function.
- A function may not be used in connections, may have no equations, may have no initial algorithm, and can have at most one algorithm section, which, if present, is the body of the function.
- A function may have zero or one external function interface, which, if present, is the external definition of the function.
- For a function to be called in a simulation model, it must have either an algorithm section or an external function interface as its body, and it may not be partial.
- A function cannot contain calls to the Modelica built-in operators der, initial, terminal, sample, pre, edge, change, reinit, delay, cardinality, to the operators of the built-in package Connections, and is not allowed to contain when-statements.
- The dimension sizes not declared with (:) of each array result or array local variable [i.e., a non-input components] of a function must be either given by the input formal parameters, or given by constant or parameter expressions, or by expressions containing combinations of those. If an output or a local array dimension is declared with (:), the size of the dimension can be changed in the function. A size change takes place by assigning a full array with the respective sizes to the dynamically sized array on the left hand side of an equal sign.
- The local variables of a function are not automatically initialized to the implicit default values of the data type [(e.g., 0.0 for Real) for performance reasons. It is the responsibility of the user to provide explicit defaults or to define the values of such variables before they are referenced.]
- Components of a function will inside the function behave as though they had discrete-time variability.

Modelica functions have the following enhancements compared to a general Modelica class:

- A function may be called using the conventional positional calling syntax for passing arguments.
- A function can be recursive.
- A formal parameter or local variable may be initialized through an assignment (:=) of a default value in its declaration. Initialization through an equation is not possible.
- A function is dynamically instantiated when it is called rather than being statically instantiated by an instance declaration, which is the case for other kinds of classes.
- A function may have an external function interface specifier as its body.
- A function may have a return statement in its algorithm section body.
- A function allows dimension sizes declared with (:) to be resized for non-input array variables (so the actual dimension need not to be known when the function is translated).

A function may have a function as an input argument. The
declared type of such an input formal parameter in a function can
be the class-name of a partial function that has no replaceable
elements. It cannot be the class-name of a record [i.e., *record
constructor functions are not allowed in this context.*] Such
an input formal parameter of function type can also have an
optional functional default value. Example:

functionquadrature "Integrate function y=integrand(x) from x1 to x2"inputReal x1;inputReal x2;inputIntegrand integrand; // Integrand is a partial function, see below // With default: input Integrand integrand := Modelica.Math.sin;outputReal integral;algorithmintegral :=(x2-x1)*(integrand(x1) + integrand(x2))/2;endquadrature;partial functionIntegrandinputReal x;outputReal y;endIntegrand;

A functional argument can be provided in one of the following forms to be passed to a formal parameter of function type in a function call (see examples below):

- as a function name,
- as a function partial application,
- as a function that is a component,
- as a function partial application of a function that is a component.

In all cases the provided function must be "function type compatible" to the corresponding formal parameter of function type. Example:

// A function as a positional input argument according to case (a)functionParabolaextendsIntegrand;algorithmy = x*x;endParabola; area = quadrature(0, 1, Parabola); // The quadrature2 example below uses a function integrand that // is a component as input argument according to case (c):functionquadrature2 "Integrate function y=integrand(x) from x1 to x2"inputReal x1;inputReal x2;inputIntegrand integrand; // Integrand is a partial function typeoutputReal integral;algorithmintegral := quadrature(x1, (x1+x2)/2, integrand)+ quadrature((x1+x2)/2, x2, integrand);endquadrature2;

A function partial application is a function call with certain formal parameters bound to expressions. A function partial application returns a partially evaluated function that is also a function, with the remaining not bound formal parameters still present in the same order as in the original function declaration. A function partial application is specified by the function keyword followed by a function call to func_name giving named formal parameter associations for the formal parameters to be bound, e.g.:

functionfunc_name(..., formal_parameter_name = expr, ...)

[*Note that the keyword function in a function partial
application differentiates the syntax from a normal function call
where some parameters have been left out, and instead supplied via
default values.*] The function created by the function partial
application acts as the original function but with the bound formal
input parameters(s) removed, i.e., they cannot be supplied
arguments at function call. The binding occurs when the partially
evaluated function is created. A partially evaluated function is
"function compatible" to the same function where all bound
arguments are removed [*thus, for checking function type
compatibility, bound formal parameters are ignored*].

Example of function partial application as argument, positional argument passing, according to case (b) above:

modelTestparameterInteger N; Real area;algorithmarea := 0;foriin1:Nlooparea := area + quadrature(0, 1,functionSine(A=2, w=i*time));end for;endTest;functionSine "y = Sine(x,A,w)"extendsIntegrand;inputReal A;inputReal w;algorithmy:=A*Modelica.Math.sin(w*x);endSine; //Call with function partial application as named input argument: area := area + quadrature(0, 1, integrand =functionSine(A=2, w=i*time));

Example showing that function types are matching after removing the bound arguments A and w in a function partial application:

functionSine2 "y = Sine2(A,w,x)"inputReal A;inputReal w;inputReal x; // Note: x is now last in argument list.outputReal y;algorithmy:=A*Modelica.Math.sin(w*x);endSine2; // The partially evaluated Sine2 has only one argument: // x - and is thus type compatible with Integrand. area = quadrature(0, 1, integrand =functionSine2(A=2, w=3));

Example of a function partial application of a function that is a component, according to case (d) above:

partial functionSurfaceIntegrandinputReal x;inputReal y;outputReal z;endSurfaceIntegrand;functionquadratureOnceinputReal x;inputReal y1;inputReal y2;inputSurfaceIntegrand integrand;outputReal z;algorithm// This is according to case (d) and needs to bind the 2nd argument z := quadrature(y1, y2,functionintegrand(y=x));endquadratureOnce;functionsurfaceQuadratureinputReal x1;inputReal x2;inputReal y1;inputReal y2;inputSurfaceIntegrand integrand;outputReal integral;algorithm// Case (b) and (c) integral := quadrature(x1, x2,functionquadratureOnce(y1=y1, y2=y2, integrand=integrand);endsurfaceQuadrature;

Generated at 2019-12-16T02:39:06Z by OpenModelicaOpenModelica 1.16.0~dev-83-g5b8ff4c using GenerateDoc.mos