I want to use MSL CombiTimeTable and be able to scale the parameters here from a scaling factor provided by another block or model. (The idea is to give flexibility for the user to express switching time points in sort of different units, eg. either as 60 seconds or as the liquid volume 120 mL that takes 120/2 seconds to pass by if the flow rate is 2 mL/s). The scaling is the same throughout a simulation. I hesitate whether to see scaling as a signal or a parameter but chose it to be a signal. Then I embed CombiTimeTable in a block with an interface of a scaling-signal and two parameter, see below.
model Test
import Modelica.Blocks.Sources;
import Modelica.Blocks.Types;
import Modelica.Blocks.Interfaces.RealInput;
import Modelica.Blocks.Interfaces.RealOutput;
block ControlStep
output RealOutput out;
input RealInput scaling;
parameter Real start;
parameter Real stop;
Sources.CombiTimeTable loading(
smoothness=Types.Smoothness.ConstantSegments,
extrapolation=Types.Extrapolation.HoldLastPoint,
table=[0, 0; start/scaling, 1; stop/scaling, 0]);
equation
out = loading.y[1];
end ControlStep;
model System
ControlStep control_sample(start=0, stop=120);
parameter Boolean scale_volume = true;
Real F, Y, scaling;
equation
F = 2;
scaling = if scale_volume then F else 1;
control_sample.scaling = scaling;
Y = control_sample.out;
end System;
end Test;
Before I start a simulation I give values to parameters start and stop and also a parameter for if they should be given in terms of time or in terms of a scaled number. The code works for JModelica, but I am not very confident that the code have a sound structure. Here is some "initial" work to be done at start of simulation and I think of the concepts "initial algorithm" or "initial equation". The initial work is in my example spread out in two places as you see and consists of (expressed in a procedural way):
Would appreciate some comments, corrections, or suggestions of improvements even though the code do work in JModelica but actually not in OpenModelica.
If scaling
is no parameter you have a variability problem. I am surprised that JMoedlica accepts that.
In the assignment
loading(
...
table=[0, 0; start/scaling, 1; stop/scaling, 0]);
you compute the parameter table
from scaling. Hence, scaling must be a constant or a parameter.
If we change scaling
and all related variables to parameters or final parameters, the code runs in OpenModelica v1.18.1 and in Dymola 2022x.
model Test
import Modelica.Blocks.Sources;
import Modelica.Blocks.Types;
import Modelica.Units.SI.Time;
block ControlStep
parameter Real scaling;
parameter Time start;
parameter Time stop;
Sources.CombiTimeTable loading(
smoothness=Types.Smoothness.ConstantSegments,
extrapolation=Types.Extrapolation.HoldLastPoint,
table=[0, 0; start/scaling, 1; stop/scaling, 0]);
end ControlStep;
model System
ControlStep control_sample(start=0, stop=120, scaling=scaling);
parameter Boolean scale_volume = true;
final parameter Real scaling = if scale_volume then F else 1;
parameter Real F = 2;
Real Y;
equation
Y = control_sample.loading.y[1];
annotation (experiment(StopTime=200));
end System;
end Test;
Regarding your statement:
The scaling is the same throughout a simulation. I hesitate whether to see scaling as a signal or a parameter but chose it to be a signal.
Definitely use a parameter for that. This allows the Modelica translator to optimize your equations accordingly and in general should result in a faster model (at least a little).
The CombiTimeTable also has a parameter which performs scaling: timeScale
For your minimal example using timeScale=1/scaling
will give the same result as your approach.
model Test
import Modelica.Blocks.Sources;
import Modelica.Blocks.Types;
import Modelica.Units.SI.Time;
block ControlStep
parameter Real scaling;
parameter Time start;
parameter Time stop;
Sources.CombiTimeTable loading(
timeScale=1/scaling,
smoothness=Types.Smoothness.ConstantSegments,
extrapolation=Types.Extrapolation.HoldLastPoint,
table=[0, 0; start, 1; stop, 0]);
end ControlStep;
model System
ControlStep control_sample(start=0, stop=120, scaling=scaling);
parameter Boolean scale_volume = true;
final parameter Real scaling = if scale_volume then F else 1;
parameter Real F = 2;
Real Y;
equation
Y = control_sample.loading.y[1];
annotation (experiment(StopTime=200));
end System;
end Test;