You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenModelica自定义布尔振荡器仿真错误求助

可变频率布尔振荡器仿真错误排查与解决

问题场景

实现一个带可变周期输入u的布尔振荡器模型,模型语法检查通过,但仿真时触发大量内部翻译错误。

原模型代码

class VarBoolPulse
  extends Modelica.Blocks.Interfaces.partialBooleanSource;
  
  Modelica.Blocks.Interfaces.BooleanOutput y;
  Modelica.Blocks.Interfaces.RealInput u;

protected
  Modelica.SIunits.Time start "Start time of current period";
  
initial algorithm
  start := time;
  
equation
  when sample(start, u) then
    start = time;
  end when;
  y = not(time >= start and time < start + u * 0.5);

end VarBoolPulse;

仿真错误信息

Translation Error
[/var/lib/jenkins3/ws/LINUX_BUILDS/tmp.build/openmodelica-1.21.0~2-g0bc3d29/OMCompiler/Compiler/BackEnd/BackendDAETransform.mo: 332:7-332:48]: Internal error BackendDAETransform.analyseStrongComponentBlock failed (Purely discrete algebraic loops cannot be solved by iterative processes. Try to break them open using the delay() operator.)
$whenCondition1
start
when $whenCondition1 then
  start := time;
end when;
$whenCondition1 = sample(1, start, u)

[9] 15:56:07 Translation Error
[/var/lib/jenkins3/ws/LINUX_BUILDS/tmp.build/openmodelica-1.21.0~2-g0bc3d29/OMCompiler/Compiler/BackEnd/BackendDAETransform.mo: 342:7-342:48]: Internal error BackendDAETransform.analyseStrongComponentBlock failed
variables:
  $whenCondition1
  start
equations:
  when $whenCondition1 then
  start := time;
end when;
  $whenCondition1 = sample(1, start, u)

[10] 15:56:07 Translation Error
[/var/lib/jenkins3/ws/LINUX_BUILDS/tmp.build/openmodelica-1.21.0~2-g0bc3d29/OMCompiler/Compiler/BackEnd/BackendDAETransform.mo: 346:7-346:90]: Internal error function analyseStrongComponentBlock failed

[11] 15:56:07 Translation Error
[/var/lib/jenkins3/ws/LINUX_BUILDS/tmp.build/openmodelica-1.21.0~2-g0bc3d29/OMCompiler/Compiler/BackEnd/BackendDAETransform.mo: 196:5-196:89]: Internal error function analyseStrongComponentScalar failed

[12] 15:56:07 Translation Error
[/var/lib/jenkins3/ws/LINUX_BUILDS/tmp.build/openmodelica-1.21.0~2-g0bc3d29/OMCompiler/Compiler/BackEnd/BackendDAETransform.mo: 107:7-107:113]: Internal error function strongComponentsScalar failed (sorting strong components)

[13] 15:56:07 Translation Error
[/var/lib/jenkins3/ws/LINUX_BUILDS/tmp.build/openmodelica-1.21.0~2-g0bc3d29/OMCompiler/Compiler/BackEnd/BackendDAEUtil.mo: 7953:5-7953:89]: Internal error Transformation module sort components failed

问题原因

核心问题是纯离散代数环:sample(start, u)的触发时刻依赖start变量,而start又在when sample(...)的事件中被重新赋值,形成循环依赖。OpenModelica的翻译器无法处理这种无延迟的离散环,导致编译阶段失败。

修正方案

使用pre()运算符打破循环依赖,pre(start)会取start变量的前一个时间步值,避免当前时刻的循环引用。以下提供两种可行的修正版本:

版本1:严格对齐初始时刻

class VarBoolPulse
  extends Modelica.Blocks.Interfaces.partialBooleanSource;
  
  Modelica.Blocks.Interfaces.BooleanOutput y;
  Modelica.Blocks.Interfaces.RealInput u;

protected
  Modelica.SIunits.Time start "Start time of current period";
  Boolean firstTrigger = true; // 标记首次触发
  
initial algorithm
  start := time;
  
equation
  // 首次触发用初始start值,后续用前一时刻的start值
  when sample(if firstTrigger then start else pre(start), u) then
    start := time;
    firstTrigger := false;
  end when;
  
  y = not(time >= start and time < start + u * 0.5);

end VarBoolPulse;

版本2:简洁通用写法

如果不需要严格对齐初始时刻,可直接使用pre(start),初始时刻pre(start)会自动取初始赋值的start值:

class VarBoolPulse
  extends Modelica.Blocks.Interfaces.partialBooleanSource;
  
  Modelica.Blocks.Interfaces.BooleanOutput y;
  Modelica.Blocks.Interfaces.RealInput u;

protected
  Modelica.SIunits.Time start "Start time of current period";
  
initial algorithm
  start := time;
  
equation
  when sample(pre(start), u) then
    start := time;
  end when;
  
  y = not(time >= start and time < start + u * 0.5);

end VarBoolPulse;

关键修改说明

  • pre()运算符的作用:获取变量的历史值,切断当前时刻start与触发条件的循环依赖,让求解器能按时间步迭代计算。
  • 两种版本均能有效打破离散代数环,解决仿真翻译错误。

内容的提问来源于stack exchange,提问作者Peter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 00:37:48