如何将参数缩放引入 MSL CombiTimeTable?

How to introduce scaling of parameters to MSL CombiTimeTable?

我想使用 MSL CombiTimeTable 并能够根据另一个模块或模型提供的缩放因子缩放此处的参数。 (这个想法是为了让用户能够灵活地以不同的单位表示切换时间点,例如 60 秒或液体体积 120 mL,如果流速为 2 [,则需要 120/2 秒通过 mL/s).在整个模拟过程中,缩放比例是相同的。我犹豫是否将缩放视为信号或参数,但选择它作为信号。然后我将 CombiTimeTable 嵌入到一个块中,该块具有一个缩放信号和两个参数的接口,请参见下文。

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;

在我开始模拟之前,我给参数 start 和 stop 赋值,还有一个参数,用于决定它们是按时间还是按比例给出。该代码适用于 JModelica,但我不太相信该代码具有合理的结构。这是在模拟开始时要完成的一些“初始”工作,我想到了“初始算法”或“初始方程”的概念。如您所见,在我的示例中,初始工作分布在两个地方,包括(以程序方式表达):

  1. 评估参数值scale_volume
  2. 获取F的值(这里只是等于2,但一般是根据其他几个参数定义的)
  3. 获取变量缩放的值,即F或1
  4. 计算 CombiTimeTable
  5. 的 table 中的值

即使代码在 JModelica 中有效但实际上在 OpenModelica 中无效,也会收到一些评论、更正或改进建议。

如果 scaling 没有参数,则说明存在可变性问题。我很惊讶 JMoedlica 接受了这一点。

作业中

loading(
  ...
            table=[0, 0; start/scaling, 1; stop/scaling, 0]);

您通过缩放计算参数 table。因此,缩放必须是常数或参数。

如果我们将 scaling 和所有相关变量更改为参数或最终参数,代码将在 OpenModelica v1.18.1 和 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;

关于您的声明:

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.

肯定会为此使用一个参数。这允许 Modelica 翻译器相应地优化您的方程式,并且通常会产生更快的模型(至少一点点)。

备选方案:使用时间刻度参数

CombiTimeTable 还有一个执行缩放的参数:timeScale

对于您使用 timeScale=1/scaling 的最小示例,将给出与您的方法相同的结果。

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;