首页 > 解决方案 > 如何通过同步模型中的函数初始化记录类型(modelica)

问题描述

我写了一个函数,返回值类型为记录。通常我会使用这个函数通过一个初始方程来初始化一个记录类型的实例。但是因为我想在时钟模型中使用这个函数,所以初始方程是不可能的。

对我来说,这似乎是使用属性 start 初始化变量的唯一方法。不幸的是,记录没有这个属性,只有它的组成部分。

这是一个简单的例子,展示了我想做的事情:

model RecordInitializeTest
  record simpleRecord
    Integer arg1;
    Integer arg2;
  end simpleRecord;

  function initFunc
    output simpleRecord sR;
  algorithm 
    sR.arg1 := 1;
    sR.arg2 := 2;
  end initFunc;

  model InitializeTest
    input Boolean u(start=false);
    output simpleRecord sR1;
  equation 
    if u and not previous(u) then
      sR1 =initFunc();
    else
      sR1 = previous(sR1);
    end if;
  end InitializeTest;

  InitializeTest iT;
equation 
  iT.u = sample(time > 0.5,Clock(0.1));
end RecordInitializeTest;

该模型在 dymola 中有效,但当然会有警告,因为 iT.sR1.agr1 和 iT.sR1.arg2 没有起始值,但它们是 previous() 的参数。概念上我想使用

output simpleRecord sR1(start=initFunc());

有没有人知道如何以方便的方式初始化 sR1 而无需分配

output simpleRecord sR1(arg1(start=1),arg2(start=2));

因为这对于大型结构化记录会很不方便。

实际上,我只想在某些时间和初始情况下执行复杂的外部不纯函数(而不是 initFunc),并将结果保持在两者之间。而且我明确不想使用连续时间模型。而且我不想在翻译过程中收到警告。

标签: modelicadymola

解决方案


如果我完全理解您的问题,只需进行一些小的修改即可让您的示例按预期运行:

model RecordInitializeTest
  record simpleRecord
    Integer arg1(start=0);
    Integer arg2(start=0);
  end simpleRecord;

  function impureFunc
    output simpleRecord sR;
  algorithm 
    (sR.arg1, sR.arg2) :=Modelica.Utilities.System.getTime();
  end impureFunc;

  model ImpureTest
    input Boolean u(start=false);
    output simpleRecord sR1;
  equation 
    if firstTick() or u and not previous(u) then
      sR1 = impureFunc();
    else
      sR1 = previous(sR1);
    end if;
  end ImpureTest;

  ImpureTest iT(u=sample(time > 0.5, Clock(0.1)));
end RecordInitializeTest;

在模拟结果中,我们看到新记录值被精确计算了 2 次:在时间 0 和时间 0.5:

模拟结果

这些变化是:

  • initFunc()替换为impureFunc(), 以查看函数在时间 0 和时间 0.5 调用的结果

  • 添加执行初始化firstTick()以在时间 0 调用不纯函数

  • 不再有起始值警告,因为记录中的每个变量都有一个虚拟起始值。实际的起始值无关紧要,因为它们是用firstTick()

注意:我以前从未创建过时钟模型,所以我可能犯了一些愚蠢的初学者错误。


推荐阅读