.ModelicaReference.Classes.'function'

Information

Define specialized class function

Examples

function si
  input Real x;
  output Real y;
algorithm
  y = if abs(x) < Modelica.Constants.eps then 1 else Modelica.Math.sin(x)/x;
end si;
Simulation result

Syntax

   [ encapsulated ][ partial ] function
   IDENT class_specifier

class_specifier :
   string_comment composition end IDENT
   | "=" base_prefix name [ array_subscripts ] [ class_modification ] comment
   | "=" enumeration "(" ( [enum_list] | ":" ) ")" comment

See Modelica Language Specification for further details.

Description

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:

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

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:

function quadrature "Integrate function y=integrand(x) from x1 to x2"
  input  Real x1;
  input  Real x2;
  input  Integrand integrand;   // Integrand is a partial function, see below
  // With default: input Integrand integrand := Modelica.Math.sin;
  output Real integral;
algorithm
  integral :=(x2-x1)*(integrand(x1) + integrand(x2))/2;
end quadrature;

partial function Integrand
  input  Real x;
  output Real y;
end Integrand;

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):

  1. as a function name,
  2. as a function partial application,
  3. as a function that is a component,
  4. 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)
function Parabola
   extends Integrand;
algorithm
   y = x*x;
end Parabola;

area = quadrature(0, 1, Parabola);

// The quadrature2 example below uses a function integrand that
// is a component as input argument according to case (c):
function quadrature2 "Integrate function y=integrand(x) from x1 to x2"
  input  Real x1;
  input  Real x2;
  input  Integrand integrand;   // Integrand is a partial function type
  output Real integral;
algorithm
   integral := quadrature(x1,       (x1+x2)/2, integrand)+
               quadrature((x1+x2)/2, x2,       integrand);
end quadrature2;

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.:

function func_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:

model Test
   parameter Integer N;
   Real area;
algorithm
   area := 0;
   for i in 1:N loop
     area  := area + quadrature(0, 1, function Sine(A=2, w=i*time));
   end for;
end Test;

function Sine  "y = Sine(x,A,w)"
  extends Integrand;
  input Real A;
  input Real w;
algorithm
  y:=A*Modelica.Math.sin(w*x);
end Sine;

//Call with function partial application as named input argument:
area  := area + quadrature(0, 1, integrand = function Sine(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:

function Sine2  "y = Sine2(A,w,x)"
  input Real A;
  input Real w;
  input Real x; // Note: x is now last in argument list.
  output Real y;
algorithm
  y:=A*Modelica.Math.sin(w*x);
end Sine2;

// The partially evaluated Sine2 has only one argument:
// x - and is thus type compatible with Integrand.
area = quadrature(0, 1, integrand = function Sine2(A=2, w=3));

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

partial function SurfaceIntegrand
   input Real x;
   input Real y;
   output Real z;
end SurfaceIntegrand;

function quadratureOnce
  input Real x;
  input Real y1;
  input Real y2;
  input SurfaceIntegrand integrand;
  output Real z;
algorithm
  // This is according to case (d) and needs to bind the 2nd argument
  z := quadrature(y1, y2, function integrand(y=x));
end quadratureOnce;

function surfaceQuadrature
  input Real x1;
  input Real x2;
  input Real y1;
  input Real y2;
  input SurfaceIntegrand integrand;
  output Real integral;
algorithm
   // Case (b) and (c)
   integral := quadrature(x1, x2,
     function quadratureOnce(y1=y1, y2=y2, integrand=integrand);
end surfaceQuadrature;

Generated at 2020-06-05T07:38:22Z by OpenModelica 1.16.0~dev-420-gc007a39