1 Protocol

The COE protocol is based on a JSON over HTTP protocol using a similar approach as REST. However, unlike REST, the COE keeps state. The format used to describe each command is: URL and any arguments, prefixed with a colon, e.g. :section”.

1.1 COE Information

Information about the COE is available at:

http://localhost:8082/

1.2 The API Command

The command is available at:

http://localhost:8082/api

or the following for a PDF version:

http://localhost:8082/api/pdf

If successful, the command returns one of two types of content:

Content-Type: application/pdf
A PDF version of this document.
Content-Type: text/plain
The LaTeX source file of this document.

1.3 The Status Command

The command is available at:

http://localhost:8082/status/:session

The command takes the following arguments:

:session
Optional session id filtering the returned data array to the single instance with the given session id.

If no session is provided, then the command returns an array of all sessions status similar to the example below.

 
1    [   
2    { 
3        "status":"idle", 
4        "sessionid": "-1" 
5    }, 
6    { 
7        "status":"idle", 
8        "sessionid": "0" 
9    } 
10    ]  
11

If a session ID is given, then a single session is returned

 
1    { 
2        "status":"idle", 
3        "sessionid": "-1" 
4    }  
5

1.4 The Create Session Command

The command is available at:

http://localhost:8082/createSession

The command takes no argument and returns a JSON string containing the session id. An example is presented below, where the sessionId is 12345:

 
1    {"sessionId":"12345"}  
2

1.5 The Attach Session Command

The command is available at:

ws://localhost:8082/attachSession/:session

The command takes no arguments and opens a WebSocket (https://tools.ietf.org/html/rfc6455). Output data from connected outputs will be live streamed according to the following format:

 
1    { 
2        "{fmuName}":{ 
3            "instanceName":{ 
4                "variableName": variableValue 
5            } 
6        } 
7    }  
8

1.6 The Initialize Command

The command is available at:

http://localhost:8082/initialize/:session

The command takes the following argument and requires a JSON payload, Content-Type: application/json:

:session
The session ID.

The Data payload:

 
1    { 
2        "fmus":{ 
3            "{controllerFmu}":"file://controller.fmu", 
4            "{tankFmu}":"file://tank.fmu" 
5        }, 
6        "connections":{ 
7            "{controllerFmu}.crtlIns.valve":["{tankFmu}.tankIns.valve"], 
8            "{tankFmu}.tankIns.level":["{controllerFmu}.crtlIns.level"] 
9        }, 
10        "parameters":{ 
11            "{controllerFmu}.crtlIns.maxLevel":8, 
12            "{controllerFmu}.crtlIns.minLevel":2 
13        }, 
14        "algorithm":{ 
15            FIXED-STEP-SIZE-CONFIG or VARIABLE-STEP-SIZE-CONFIG 
16        }, 
17        "livestream":{ 
18            "{controllerFmu}.crtlIns":["local","local2"], 
19            "{tankFmu}.tankIns":["level"] 
20        }, 
21        "logVariables":{ 
22            "{tankFmu}.tankIns":["local"] 
23        }, 
24        "parallelSimulation": false, 
25        "stabalizationEnabled":false, 
26        "global_absolute_tolerance": 0.0, 
27        "global_relative_tolerance":0.01 
28 
29    }  
30

FIXED-STEP-SIZE-CONFIG
The fixed step size configuration contains the following:
 
1        "type":"fixed-step", 
2        "size":0.1  
3
VARIABLE-STEP-SIZE-CONFIG
The variable step size configuration contains the following:
 
1        "type":"var-step", 
2        "size":[1E-6, 1.0], 
3        "initsize":1E-4, 
4        "constraints":{ 
5            STEPSIZE-CONSTRAINT* 
6        }  
7

Where the properties are defined as:

type:"var-step"
selects the variable stepsize calculator (each algorithm has a type).
size:[<minimal stepsize> , <maximal step size>]
defines the stepsize interval as an array of double values.
initsize:<initial stepsize>
defines the initial stepsize as double value.
constraints:
defines the stepsize constraints as follows:
 
1            "id":{ 
2                type:"[zerocrossing|boundeddifference|samplingrate|fmumaxstepsize]", 
3                ... 
4            }  
5

The id is a string that is used to identify the constraint e.g. in the log. All constraints have a single common name-value pair with name type. The value of type specifies the type of the constraint; the other name-value pairs of the constraint depend on the value of type. The zerocrossing is described in Section 1.6.1, boundeddifference in Section 1.6.2, and samplingrate in Section 1.6.3 fmumaxstepsize in Section 1.6.4.

The JSON payload contains the following entries:

fmus
A list of the location of the FMUs.
connections
A map of connections, output to input.
parameters
A map from parameter to value.
algorithm
Step size algorithm configuration:
fixed-step
A fixed step size algorithm is available requiring a step size to be specified.
livestream
These scalar variables will be livestreamed via websockets. They must have a causality of either local or output.
logVariables
These scalar variables will be logged. They must have a causality of either local or output.
parallelSimulation
Optional boolean condition specifying if the COE should parallelize certain parts of the simulation. This condition is or’ed together with all simulation.parallelise.* properties.
stabalizationEnabled
This enabled stabilization mode in the COE. Currently it makes use of successive substitution retrying a maximum of 5 steps. It uses the global_absolute_tolerance and global_relative_tolerance to decide if the signals are stable or another stabilization step is needed. The implementation uses the Numpy.isclose function. When this option is enabled the cyclic check is disabled and a warning is for any FMU that is in a cycle that does not support get and set state from FMI.
global_absolute_tolerance
The global absolute tolerance used for stabilization.
global_relative_tolerance
The global relative tolerance used for stabilization.

The command returns the following response on success:

 
1    { 
2        "status":"initialized", 
3        "sessionid": "1234", 
4        "avaliableLogLevels":{ 
5            "{8c4e810f-3df3-4a00-8276-176fa3c9f001}.tank":[ 
6            { 
7                "name":"logAll", 
8                "description":"Description of this loggin level" 
9            }, 
10            { 
11                "name":"logError", 
12                "description":null 
13            }], 
14            "{8c4e810f-3df3-4a00-8276-176fa3c9f000}.controller":[ 
15            { 
16                "name":"logAll", 
17            }] 
18        } 
19    }  
20

The avaliableLogLevels value will be specific to the FMUs given in the initial payload. The sessionid is the ID that must be supplied in any subsequent calls.

1.6.1 Definition of a Zero Crossing Constraint

A constraint of "type":"zerocrossing" is defined by

 
1    "id":{ 
2        "type":"zerocrossing", 
3        "ports":[ 
4        "<guid>.<instance>.<outport>", 
5        "<guid>.<instance>.<outport>" 
6        ], 
7        "order":[1|2], 
8        "abstol":<double>, 
9        "safety":<double> 
10    }  
11

where the second entry in the ports list and the attributes order, abstol and safety are optional. The name-value pairs have the following meaning.

1.6.2 Definition of a Bounded Difference Constraint

A constraint of "type":"boundeddifference" is defined by

 
1        "id":{ 
2            "type":"boundeddifference", 
3            "ports":[ 
4            "<guid>.<instance>.<outport>" 
5            ,"<guid>.<instance>.<outport>" 
6            ,"<guid>.<instance>.<outport>" 
7            ... 
8            ] 
9            ,"abstol":<double> 
10            ,"reltol":<double> 
11            ,"safety":<double> 
12            ,"skipDiscrete":<boolean> 
13        }  
14

where entries after the first in the ports list and the attributes abstol, reltol, safety and skipDiscrete are optional. The name-value pairs have the following meaning.

1.6.3 Definition of a Sampling Rate Constraint

A constraint of "type":"samplingrate" is defined by

 
1        "id":{ 
2            "type":"samplingrate", 
3            "base":<integer>, 
4            "rate":<integer>, 
5            "startTime":<integer> 
6        }  
7

with the following name-value pairs.

1.6.4 Definition of a FMU Max Step Size Constraint

A constraint of "type":"fmumaxstepsize" is defined by

 
1        "id":{ 
2            "type":"fmumaxstepsize" 
3        }  
4

The constraint limits the step size to the minimum of the step size returned by getMaxStepSize from all instances that support the function.

1.7 The Simulate Command

The command is available at:

http://localhost:8082/simulate/:session

The command takes the following arguments and requires a JSON payload, Content-Type: application/json:

:session
The session ID.

The Data payload:

 
1        { 
2            "startTime":0.0, 
3            "endTime":10.1, 
4            "logLevels": { 
5                "{8c4e810f-3df3-4a00-8276-176fa3c9f001}.tank": 
6                ["logAll", "logError"], 
7                "{8c4e810f-3df3-4a00-8276-176fa3c9f000}.tank": 
8                ["logError"] 
9            } 
10        }  
11

The payload contains the start and end time interval plus the log levels.

The command returns the following response on success:

 
1        [ 
2        { 
3            "status":"Finished", 
4            "sessionid": "1234" 
5        } 
6        ]  
7

1.8 The Stop Simulation Command

This command sets a flag such that the simulation related to a given sessionID is stopped on completion of its current step.

The command is available at:

http://localhost:8082/stopsimulation/:session

The command takes the following arguments:

:session
The session ID.

1.9 The Result Command

The command is available at:

http://localhost:8082/result/:session/:type

The command takes the following arguments:

:session
The session ID.
:type
Optional parameter. Possible parameters are: plain/zip and default is plain.

The command returns the following response on success. A response supports two return formats selected by the :type argument and indicated using the content type:

Content-Type: application/zip
Returns a zip file containing the initialization data + start data + the result obtained during the simulation
Content-Type: text/plain
Returns the result obtained during the simulation as text. The result is a CSV formatted string with: time, stepsize, and all outputs at that time

1.10 The Destroy Command

The command is available at:

http://localhost:8082/destroy/:session

The command takes the following arguments:

:session
The session ID.

The command destroys a session and releases all resources bound to the session on success full termination.

1.11 Example

This sections exemplifies how to use the COE in terms of creating a configuration file and invoking the COE. Two FMUs are used in the example below: A sine FMU generating a sine wave and an integrate FMU that integrates the sine wave.

First the configuration file will be presented and described in section 1.11.1. Afterwards the HTTP requests required to run a simulation will be demonstrated and explained in section 1.11.2.

1.11.1 Configuration file

The configuration file is in JSON format, and the full file is shown below:

 
1    { 
2        "fmus":{ 
3            "{integrate}":"./integrate", 
4            "{sine}":"./sine" 
5        }, 
6        "connections":{ 
7            "{sine}.sine.output":["{integrate}.inst1.input","{integrate}.inst2.input"], 
8            "{integrate}.inst2.output":["{integrate}.inst3.input"] 
9        }, 
10        "parameters":{ 
11            "{sine}.sine.amplitude":1 
12        }, 
13        "algorithm":{ 
14            "type":"fixed-step", 
15            "size":0.1 
16        }, 
17        "livestream":{ 
18            "{sine}.sine":["output"], 
19            "{integrate}.inst2":["output"] 
20        }, 
21        "logVariables":{ 
22            "{integrate}.inst3":["output"] 
23        } 
24    }  
25

FMUs JSON object
The "fmus" JSON object contains two name/value pairs: "{integrate}":"./integrate" and "{sine}":"./sine". Note the , separating the pairs. {integrate} and {sine} are user-defined identifiers for the respective FMUs, they must not contain additional “{}”, and they must be consistent throughout the configuration file, when referring to the respective FMUs. The COE accepts two different kind of paths: a path to a directory as in this example, or path to a zip-file with the extension “.fmu”. If the integrate FMU was packaged in a zip-file with the extension “.fmu”, the path would be "./integrate.fmu" instead of "./integrate". The paths must be relative to the “COE.jar” file, which means the directories in this example are in the same directory as the “COE.jar” file.

Connections JSON object
The "connections" json object defines the relations between the FMUs. In this case there a two name/value pairs:

 
1"{sine}.sine.output":["{integrate}.inst1.input","{integrate}.inst2.input"], 
2"{integrate}.inst2.output":["{integrate}.inst3.input"]  
3

Once again, note the , separating the pairs. To address the FMU variables, the following format is used: fmuReference.instancename.variablename. This introduces the concept of “instances”. Some FMUs can be used to create multiple instances. In the example above the integrate FMU is used to instantiate three instances called: inst1, inst2, and inst3. Therefore "{integrate}.inst2.output" means: The variable output of instance inst2 in the FMU {integrate}.

1.11.2 Requests

2 Variable Stepsize Calculation

Three of the four constraint types (Zero Crossing, Bounded Difference, and Sampling Rate) are defined in a JSON file that is posted to the COE with the initialize command (see Section 1.6), and one (FMU-requested) is requested by the simulated FMUs.

After initialization, the variable stepsize calculator holds a set of constraint handlers. Each handler is responsible for one constraint. When asked for the next stepsize by the COE, the variable stepsize calculator asks each handler for the next stepsize and returns the minimum of these values.

2.1 Interface with the Master Algorithm

The variable stepsize calculator is called by the master algorithm before each doStep. It is given by the master algorithm the current time, the previous stepsize, the current output values, and the (estimated) output derivatives of the FMUs. The variable stepsize calculator returns to the master algorithm the next stepsize.

After a doStep, the master algorithm asks the variable stepsize calculator to validate the taken step, i.e. to check whether any constraints have been violated. If that is the case, a warning is issued. If all FMUs support rollback, a rollback is initiated and the master algorithm asks the variable stepsize calculator for a new, reduced stepsize.

The algorithm for derivative estimation, see Section 2.3.2, has been moved from the variable stepsize calculator to the COE. This is done so that the master algorithm may estimate derivatives and supply these to FMUs that have the capability canInterpolateInputs. To be clear, if the FMU that supplies these signals also provides derivatives, these are used, but if that FMU has maxOutputDerivativeOrder=0 (or <=1 in the case of second order input derivatives]), the estimated values are used.

2.2 Constraint Types

There are four constraint types:

The constraints are defined in the JSON file (see Section 1.6). The fourth constraint, FMU Max Step Size, was enabled by default until COE version 0.2.14. See Section 2.6 for more info on the FMU Max Step Size Constraint.

2.3 Zero Crossing Constraints

A zero crossing constraint is a continuous constraint. A zero crossing occurs at the point where a function changes its sign. In simulation, it can be important to adjust the stepsize such that a zero crossing is hit (more or less) exactly. For instance, a ball should rebound from a wall exactly when the distance between the ball and the wall hits zero and not before or after that.

A solver in a tool such as Simulink can adjust the stepsize using iterative approaches, but in a co-simulation a rollback of the participating models’ internal states is in general not possible or efficient. Hence, the variable stepsize calculator bases its stepsize adjustments on the prediction of a future zero crossing.

2.3.1 Extrapolation

To predict a future zero crossing, the zero crossing function f must be extrapolated.

For first order extrapolation, the following calculation is used:

f(t + Δt) = f(t) + (tt

For second order extrapolation, the following calculation is used:

f(t + Δt) = f(t) + (tt + 0.5f¨ (t)(Δt )2

2.3.2 Derivative Estimation

The derivatives (t) and ¨f (t) are either provided by the FMUs (if the capability maxOutputDerivativeOrder is high enough), or estimated. For first order extrapolation, the last two data points are used to estimate the first derivative. For second order extrapolation, either the last three data points are used to estimate the first and second derivate, or, if the FMU provides the first but not the second derivative, the last two data points and their first derivatives are used to estimate the second derivative.

2.3.3 Extrapolation Error Estimation

Extrapolation will generally incur an extrapolation error; the variable stepsize calculator estimates that error based on past extrapolation errors. After completion of a time step, the variable stepsize calculator compares the actual value x of the zero crossing function f with the value ˆx that was predicted one time step earlier. The estimated extrapolation error ˆϵ follows:

    {                                  }
      α ˆε+ (1-  α)|x- ˆx | if ˆε > |x - ˆx|
ϵ ←   |x-  ˆx|             otherwise
(1)

For example, it decreases slowly (α = 0.7) with a first order IIR-filter rule when the extrapolation error becomes smaller, and rises abruptly to the actual value when the extrapolation error becomes larger.

2.3.4 Estimation of the number of timesteps to a zero crossing

The variable stepsize calculator (conservatively) estimates the number of timesteps n to hit the predicted zero crossing f(tZC) = 0 at time tZC, when starting from the current time t (with t tZC) and when keeping the current stepsize Δt constant, to:

n =  tZC---t-⋅----1----
       Δt    1 + ˆε+ σ
(2)

where ˆε is the estimated extrapolation error and σ the (additional) level of conservatism optionally specified by the attribute safety in the JSON config file.

The rationale of this equation is that the left term predicts the zero crossing exactly when the zero crossing function f is, in the case of first order extrapolation, a straight line, or, in the case of second order extrapolation, a straight line or second order parabola. An extrapolation error generally occurs for all other functions f, with the danger of overestimating n and thus potentially choosing a too large stepsize (that steps over the zero crossing with the consequence that the tolerance of the zero crossing may be violated). Therefore, n is conservatively underestimated. The degree of this conservatism is defined by the second term and depends on both the (time-varying) estimated extrapolation error ˆε and the (constant) value of the safety attribute σ.

2.3.5 Detection of unstable oscillations

Unstable oscillations around the zero crossing are detected by monitoring the last three data points and checking whether these lie on alternating sides of the zero crossing and increase in absolute value.

2.3.6 Stepsize adjustment strategy

The chosen stepsize Δt is in most cases determined by a factor ρ that is multiplied with the previous stepsize Δtprev (and saturated to lie within the specified stepsize interval). The stepsize is said to be adjusted to hit the zero crossing when ρ = n (for n 1). The stepsize is said to be tightened when ρ = TIGHTENING_FACTOR. The stepsize is held constant, when ρ = 1. The stepsize is said to be relaxed when ρ = RELAXATION_FACTOR. The stepsize is said to be strongly relaxed when ρ = STRONG_RELAXATION_FACTOR. The default values for these factors are listed in Table 1.



Table 1: Default values for the stepsize adjustment factors.


TIGHTENING_FACTOR 0.5
RELAXATION FACTOR 1.2
STRONG_RELAXATION_FACTOR3.0



By inspecting the last two data points, the direction of the simulated trajectory with respect to the zero crossing can be either:

When distancing a zero crossing, the stepsize is strongly relaxed.

When approaching a zero crossing, the current value of the zero crossing function, f(t), is compared to the value of the absolute tolerance, abstol.

If:

|f(t)| ≤ abstol ⋅TOLERAN    CE -SAF  ET Y F ACT  OR
(3)

where TOLERANCE_SAFETY _FACTOR 1.0 and a default value of 0.5, then f(t) is said to be well within tolerance, and the stepsize is relaxed (the zero crossing has not yet occurred but is already precisely resolved).

If

|f(t)| ≤ abstol
(4)

then f(t) is said to be within tolerance, and the stepsize is held constant (the zero crossing has not yet occurred but is already resolved).

If

|f(t)| > abstol
(5)

then f(t) is said to be outside tolerance, and the (conservatively) estimated value for the number of timesteps to hit the predicted zero crossing, n, is considered.

The default values of the parameters δi are listed in Table 2.



Table 2: Default values of the distance bin separators for the number of timesteps to hit a predicted zero crossing.


δtighten 1.8 (= 1.5 RELAXATION_FACTOR)
δrelax 3.0 (= STRONG_RELAXATION_FACTOR)
δstronglyrelax30.0 (= 10.0 δrelax)



When the simulated trajectory crossed zero in the previous time step, it is checked whether or not unstable oscillations around the zero crossing are building up.

The final three reactions (when unstable oscillations do not occur) are somewhat conservative, with the intention of discouraging possible oscillations around the zero crossing from developing. Therefore, the stepsize immediately after the zero crossing is kept small. Altogether, these are the 14 possible reactions of the variable step size calculator to exhaustively handle a zero crossing constraint.

2.4 Bounded Difference Constraints

A bounded difference constraint is a continuous constraint. A bounded difference ensures that the minimal and maximal value of a set of values do not differ by more than a specified amount (the underlying assumption is that this difference becomes smaller when the stepsize is reduced). For the definition of a bounded difference constraint in the JSON file, see Section 1.6.2.

The capability to impose a bounded difference can be useful in co-simulation, for instance, in the calculation of the heat exchange between model A of temperature TA and model B of temperature TB. Here, at least one of the models must calculate the heat flow, which is a function of both TA and TB. The model that calculates the heat flow, say model A, knows its own temperature TA but only has a view, TB,view, on model B’s true temperature TB. To bound the error of the calculated heat flow, a bounded difference between TB and TB,view is imposed.

The bounded difference problem is distinct from the zero crossing problem in that there is not a specific time instant (the zero crossing) to hit, but rather a specific time difference (the stepsize that keeps the difference bounded).

To choose the next stepsize, the current absolute and relative differences between the minimal and maximal values, δA and δR, are calculated and compared to the absolute and relative tolerances, εA and εR, respectively. Based on this comparison, the absolute and relative differences are each assigned to one of five distance bins. The bins are determined with the safety factor:

σ = ----1-----,
    1+ saf ety
(6)

where i = A,R, and with the default values of the parameters

αSAF E ≤ αT ARGET ≤  αRISKY  ≤ 1
(7)

listed in Table 3.



Table 3: Default values of the parameters used in the distance bin assignment of the bounded difference algorithm.


αRISKY 0.6
αTARGET 0.4
αSAFE 0.2



If:

Of the two assigned distance bins, the less safe one (the one ranking higher in the bullet list above) is chosen. If this distance bin is the

A strongly tightened stepsize means that δ = STRONG_TIGHTENING_FACTOR with default value 0.01 is multiplied with the previous stepsize (Δt)prev to obtain the next stepsize Δt. The meaning of the other stepsize adjustments is analogous to the implementation of the zero crossing algorithm (see Section 2.3.6). The chosen stepsize is saturated to the stepsize interval.

This algorithm for the bounded difference handler tries to adjust the stepsize such that it is kept within the TARGET bin throughout the simulation. Because a variable stepsize calculator in a co-simulation cannot (efficiently) obtain the stepsize through an iterative approach, it needs to make fairly sure that the stepsize it selects does not lead to a tolerance violation. The stepsize calculation must therefore be somewhat conservative, which is essentially manifested in the RISKY bin as a buffer between the TARGET and VIOLATION bins.

On the safe side of the TARGET bin, two bins must exist. The SAFE bin has an associated relaxation factor that is small enough so that a stepsize relaxation should not lead to an overshoot of the bound difference beyond the TARGET bin in the next time step. The SAFEST bin has an associated strong relaxation factor that is equal to the strong relaxation factor used by all other continuous constraints to prevent interference between continuous constraints (see Section 2.7.1).

Note that the above described algorithm of the Bound Difference handler is extended below to prevent interference by discrete events (see Section 2.7.3).

2.5 Sampling Rate Constraints

A sampling rate constraint is a discrete constraint. It constrains the stepsize such that repetitive, predefined time instants are exactly hit. This can be useful in co-simulation, for instance, when a modeled control unit reads a sensor value every x milliseconds. For the definition of a sampling rate constraint in the JSON file, see Section 1.6.3.

The chosen stepsize is either the time difference between the current time and the time instant of the next sampling, or the maximal stepsize, whichever is smaller. Note that the minimal stepsize may be violated to hit a sampling event.

2.6 FMU Max Step Size Constraints

The FMU Max Step Size constraint limits the step size to the value returned from an FMU if the function is supported by the FMU. A proposal is underway to extend the FMI standard with the procedure:

fmi2Status fmi2GetMaxStepSize(fmi2Component c, fmi2Real *maxStepSize);

This means that an FMU can report in advance the maximal stepsize that it will accept in the next time step. The variable stepsize calculator queries all FMUs for these stepsizes and uses the minimum of the reported values as upper bound for the next stepsize. The implementation in the COE is based on the principle presented in [??] for Master-Step With Predictable Step Sizes. To the authors knowledge, this feature is implemented in FMUs exported from the tools: 20-sim, OpenModelica and Overture.

2.7 Interference between constraint handlers

When multiple constraints are present, their handlers may interfere with each other in the sense that one constraint may become active only because another one has been active in the previous step. Measures are taken to counter such interference.

2.7.1 Interference between continuous constraints handlers

Interference between continuous constraint handlers occurs when:

  1. In one time step, Constraint A is active (i.e. constrains the stepsize);
  2. In the next time step, the handler for Constraint A relaxes the stepsize by a factor ρA > 1, and
  3. Constraint B becomes active – not because its handler protects against a potential violation, but only because it cannot relax the stepsize by more than a factor ρB < ρA.

To prevent such interference, all continous contraints must have the same value for their respective maximal relaxation factors. Therefore, in the implementation of the variable stepsize calculator, STRONG_RELAXATION_FACTOR is the maximal relaxation factor for both Zero Crossing and Bounded Difference constraints and defined in the scope of the whole calculator – not in the scope of individual constraints (as other factors are). When constraints relax strongly, STRONG_RELAXATION_FACTOR is used1 .

2.7.2 Interference between discrete constraints handlers

Discrete constraints handlers base their stepsize requirements on independent time instants and therefore do not interfere with each other.

2.7.3 Interference between discrete and continuous constraint handlers

When a discrete constraint handler has limited the stepsize in the previous step, the question arises how a continuous constraint handlers shall proceed with its calculation of the next stepsize. The situation that shall be avoided is this: all continuous constraint handlers would allow a large stepsize, but a discrete constraint handler enforces a sudden, strong reduction of the stepsize. In the steps that follow, there are no discrete events, but the continuous constraint handlers require potentially many steps to repeatedly strongly relax the stepsize until it becomes large again.

The solution to this problem is different for Zero Crossing and Bounded Difference constraint handlers.

Extension of the Zero Crossing handler To prevent the above described undesired situation, Zero Crossing handlers calculate the next stepsize based on the last stepsize that was not limited by a discrete constraint.

To be precise, a Zero Crossing handler uses the previous data points irrespective of the previously active constraints to calculate the extrapolation. But when it calculates the next stepsize, it discards all previous stepsizes that were limited by a discrete constraint and chooses the last stepsize that was limited by a continuous constraint. With the thus chosen previous stepsize (and the result of the extrapolation), the handler calculates the factor ρ that is multiplied to the chosen previous stepsize in order to obtain the next stepsize. With this approach, introduced discrete events do not markedly affect the tightening and relaxation of the stepsize selected by a Zero Crossing handler.

This approach is safe, in the sense that a zero crossing should not be crossed prematurely, for two reasons. First, introduced discrete events always shorten the stepsize when approaching the zero crossing, which is conservative. Second, the assumed previous stepsize may be larger than the true previous stepsize (that was limited by a discrete constraint handler), but this does no harm: The calculation of the next stepsize is based on the number of timesteps to the predicted zero crossing, n, with the assumption that the (assumed) previous stepsize is held constant. When the previous stepsize is larger, n becomes smaller, favoring a stronger tightening of the next stepsize in particular close to the zero crossing, where the stepsize is adjusted to hit.

Essentially, the Zero Crossing handler can safely ignore previous stepsizes that were limited by discrete constraints because it needs to hit a time instant (i.e. the zero crossing) and that time instant does not depend on the previous stepsizes (time differences). The situation is different for the Bounded Difference handler.

Extension of the Bounded Difference handler Whereas the Zero Crossing handler needs to hit a time instant (i.e. the zero crossing) that does not depend on the previous stepsizes (time differences), the Bounded Difference handler needs to limit a value difference that does depend on the stepsize. When the Bounded Difference handler notices that the previous stepsize was limited by a discrete constraint, it may proceed in either of two ways.

First, the Bounded Difference handler could simply go forward as usual (i.e. it calculates the next stepsize by scaling the previous stepsize by the factor that is associated with the determined diffe-rence bin). Because the previous stepsize was limited by a discrete event and was therefore shorter than the stepsize that the Bounded Difference handler would have chosen, this strategy will frequently lead to the stepsize being relaxed or strongly relaxed.

Second, the Bounded Difference handler could take the last stepsize that was limited by a continuous constraint and repeat the decision it made then on that stepsize. To prevent that a repeated decision overly relaxes the stepsize, the repeated decision will hold the stepsize constant whenever the past decision was to relax or strongly relax it. To prevent that a repeated decision overly tightens the step-size, the chosen next stepsize may never be smaller than the one obtained with the above (usual) strategy.

By default, the second strategy is enabled. However, in rare cases that strategy may lead to a tolerance violation (a chain of discrete events could carry a past decision to hold the stepsize constant through time; when the chain of discrete events stops, the stepsize will be held constant in the next step but it might have needed to be tightened instead). Therefore, it is possible to disable the second strategy by setting the optional attribute "skipDiscrete" to false in the definition of the Bounded Difference constraint in the JSON configuration file (see Section 1.6.2).

When the second strategy is disabled, an active discrete constraint will likely reduce the next stepsize(s) proposed by the Bounded Difference constraint handler, potentially reducing efficiency.

2.8 Logging

The variable stepsize calculator writes to the same log as the COE.

When a step is taken with maximal stepsize, the variable stepsize calculator produces no log output.

When a step is taken with a less than maximal stepsize, the variable stepsize calculator logs the identifiers of the active constraints and the action of their handlers. For instance, a log entry would read

Time 0.9499999999999998, stepsize 0.09, limited by constraint 
"bd" with decision to hold the stepsize constant 
(absolute difference within target range)

When all continuous constraints relax strongly, the log entry does not list all constraints but is shortened to:

Time 5.000458745644138, stepsize 9.536808544011453E-4, 
all continuous constraint handlers allow strong relaxation}

When a Zero Crossing constraint handler detects a zero crossing, it produces a log entry which would read:

A zerocrossing of constraint "zc" occurred in the time interval 
[ 14.999971188014648 ; 15.000117672389647 ] and was hit 
with a distance of 0.18103104302103257

When the variable stepsize calculator detects that a constraint has been violated in the previous step, it logs a warning. For instance, such a warning would read:

Absolute tolerance violated! 
        | A zerocrossing of constraint "zc" 
        | occurred in the time interval [ 4.998123597131701 ; 5.008123597131701 ] 
        | and could only be resolved with a distance of 11.789784201164633 
        | which is greather than the absolute tolerance of 1.0 
        | The stepsize equals the minimal stepsize of 0.01 ! 
        | Decrease the minimal stepsize 
        or increase this constraints  tolerance}

A Variable stepsize

A.1 Variable step size configuration example

The variable stepsize calculator is selected and configured in a JSON config file. This file is posted to the COE with the initialize command (see Section 1.6). An example JSON config file follows.

 
1{ 
2    "fmus":[ 
3        "{MassAFMU}":"src/test/resources/varsteptest/VarStepSolverTest_FMUs_MassA", 
4        "{MassBFMU}":"src/test/resources/varsteptest/VarStepSolverTest_FMUs_MassB", 
5        "{SineFMU}":"src/test/resources/varsteptest/VarStepSolverTest_FMUs_Sine", 
6        "{SinkFMU}":"src/test/resources/varsteptest/VarStepSolverTest_FMUs_Sink" 
7    ], 
8    "connections":{ 
9        "{MassAFMU}.massA.QA":[ 
10            "{MassBFMU}.massB.QA", 
11            "{SinkFMU}.sink.QA" 
12        ], 
13        "{SineFMU}.sine.EXTSIG":[ 
14            "{MassBFMU}.massB.EXTSIG", 
15            "{SinkFMU}.sink.EXTSIG" 
16        ], 
17        "{MassBFMU}.massB.TB":[ 
18            "{MassAFMU}.massA.TB", 
19            "{SinkFMU}.sink.TB" 
20        ], 
21        "{MassAFMU}.massA.TB_used":[ 
22            "{SinkFMU}.sink.TB_used" 
23        ] 
24    }, 
25    "parameters":{ 
26        "{MassBFMU}.massB.B.C":15000.0, 
27        "{MassAFMU}.massA.A.C":120000.0 
28    }, 
29    "algorithm":{ 
30        "type":"var-step", 
31        "size":[ 
32            1E-6, 
33            1.0 
34        ], 
35        "initsize":1E-4, 
36        "constraints":{ 
37            "zc":{ 
38                "type":"zerocrossing", 
39                "ports":[ 
40                    "{SineFMU}.sine.EXTSIG" 
41                ], 
42                "order":2, 
43                "abstol":1.0, 
44                "safety":0.0, 
45            }, 
46            "bd":{ 
47                "type":"boundeddifference", 
48                "ports":[ 
49                    "{MassBFMU}.massB.TB", 
50                    "{MassAFMU}.massA.TB_used" 
51                ], 
52                "abstol":1.0, 
53                "reltol":1.0, 
54                "safety":0.0, 
55            }, 
56            "sr":{ 
57                "type":"samplingrate", 
58                "base":-1, 
59                "rate":10, 
60                "startTime":15 
61            } 
62        } 
63    } 
64}  
65

B Program properties

The COE program flow can be changed using the following Java properties which can be set on program launch using -D followed by the property and a value can be specified after an equal sign:

simulation.program.delay.enable
If this property is set to true then the COE will interpret the time step size in seconds and make sure that the steps are at least separated by a program delay of that time step size. It only introduces a delay if the execution of doStep on all FMU instances are faster than the requested time step size.
fmi.instantiate.with.empty.authority
This inserts an empty authority into the URI sent to the FMU in instantiate. E.g. file:/ will become file:///. This can be necessary for faulty FMU implementations.
coe.fmu.custom.factory
This must be given a fully qualified name to a class which implements org.intocps.orchestration.coe.IFmuFactory if set this class will be instantiated and ask to handle FMU creation before the internal factory. This can thus be used to override the default behaviour.
coe.livestream.filter
Limits the time resolution on the values send using live logging. The values will only be send at the given interval or greater.
simulation.parallelise.resolveinputs
Run all per instance input actions in parallel.
simulation.parallelise.setinputs
Run all per instance set inputs in parallel.
simulation.parallelise.dostep
Run all per instance doSte calls in parallel.
simulation.parallelise.obtainstate
Run all per instance calls to obtain a global state in parallel.
simulation.profile.executiontime
Log execution time for the main calls involved in performing a global step.

Note that enabling parallel execution may not give faster simulations it is highly dependent on the number of instances, the amount of inputs/outputs and the actual execution to of the doStep call per instance.