# 历史版本升级到 2024a 版本常见问题及解决方法
Sysplorer 2024a 相较于 2023b 在内核进行了较大升级,在 2023b 中模型检查翻译较为宽松,2024a 之后更加严格,导致一些在 2023b 搭建的模型无法在 2024a 中正常运行。
经过分析发现其主要原因是模型本身建模不符合规范、系统非线性(状态量)选取不一致。因此,为了帮助用户快速升级模型,并提升模型鲁棒性,本文记录了一些在软件升级过程中旧版模型出现的常见问题与解决办法。
# 连接形式不合法,检查时报错
# 问题描述
在 Sysplore r2023b 中,采用 Modelica 标准库中的三相电压源Modelica.Electrical.Polyphase.Sources.ConstantVoltage和单相电阻Modelica.Electrical.Analog.Basic.Resistor搭建的系统模型(备注:三相电压源与单相电阻在进行接口连接时,由于无法实现之间连接,只能选择三相接口其中一个分量与单相接口连接),检查时无报错,在 Sysplorer 2024a 版本检查相同系统模型会出现以下报错。
# 问题原因
Sysplorer 2024a 相较于 2023b 进行了内核升级,严格按照 Modelica 规范进行连接检查,对于连接中的层级大于等于 3(c1.c2.c3),要求每一级都是连接器,如上系统模型中连接器constantVoltage.plug_p.pin[1]有 3 级,且第一级constantVoltage是 model 类型,不满足当连接中的连接器大于等于 3 级时每一级都为连接器的要求,因此在 2023b 中未按照严格规范搭建的模型在检查时会报连接不合法错误。
Modelica相关规范说明如下图所示:
# 解决办法
方式 1:修改模型,使用三相电阻与三相电源相连,单相电阻与单相电源相连;
方式 2:修改模型,使用Modelica.Electrical.Polyphase.Basic.PlugToPin_p转接器组件,先将单相电阻与转接器相连,然后在将转接器与三相电源相连:
方式 3:去掉仿真设置 > 模型翻译页面中的严格连接检查选项,如下图:
# 使用非法类型转换函数 realString,integerString
# 问题描述
Sysplorer 2023b 中采用 realString(实型转字符串)、IntegerString(整型转字符串)进行类型转换可以实现正常运行,在 2024a 中使用这些类型转换,在翻译时模型错误如下图所示:
# 问题原因
Sysplorer 2023b 版本前,为了兼容 Dymola 中构建的模型,软件内核支持 realString(实型转字符串)、IntegerString(整型转字符串)进行类型转换,而 2024a 之后,内核进行了较大升级,realString、IntegerString 不满足 Modelica 建模规范的语法,因此进行了规范化处理。
# 解决办法
将 realString、IntegerString 类型转换,修改为标准的 String 类型转换,如下例所示:
示例:旧版中可以正常仿真,新版中生成求解器失败。
model E4
constant Real a = 1;
Integer b = 2;
String s1 = realString(a);
String s2 = integerString(b);
end E4;
修改方法:使用标准的 String 函数。
model E4
constant Real a = 1;
Integer b = 2;
String s1 = String(a);
String s2 = String(b);
end E4;
# 在算法中使用 reinit
# 问题描述
Sysplorer 2023b 中,在算法中当 When 语句中使用到 reinit 操作符时可以实现正常运行,但在 2024a 中如此使用则会在检查时报错,如下图所示:
# 问题原因
Sysplorer 2024a 相较于 2023b 进行了内核升级,严格按照 Modelica 规范进行语法检查,对于 reinit 操作符在算法中使用是不被允许的,因此在 2024a 中未按照严格语法规范创建的模型在检查时会报不合法错误。
相关规范说明如下图所示:
# 解决办法
将 reinit 操作符,由在算法中使用修改为在方程中使用,如下例所示:
示例:旧版中不会报错。
model Use_reinit "reinit用法"
Real a(start = 0);
equation
der(a) = time;
algorithm
when time >= 0.5 then
reinit(a, 0);
end when;
end Use_reinit;
修改方法:将算法改成方程即可。
model Use_reinit "reinit用法"
Real a(start = 0);
equation
der(a) = time;
when time >= 0.5 then
reinit(a, 0);
end when;
end Use_reinit;
修改后检查结果如下:
# 模型中记录名未在外部函数中定义
# 问题描述
在 Sysplorer 2023a 中,当模型中的外部函数用到了记录(record)类型的数据时,需要将记录当作参数传入到外部函数,具体案例如下所示。此案例可实现将test_record中的两个实数相加并返回为输出值。

此案例在 Sysplorer 2023a 中可正常运行,但是在 2024a 中翻译时报错误,2024a 报错为:
# 问题原因
Sysplorer 2024a 相较于 2023a 进行了内核升级,严格按照 Modelica 规范进行语法检查,对于模型中记录名未在外部函数中定义是不被允许的,因此在 2024a 中未按照严格语法规范创建的模型在检查时会报不合法错误。
根据 Modelica 规范 12.9.1.3 小节的说明,当外部函数中使用了记录(record)类型时,需要在外部函数中提供与模型中的记录名称一致的结构体(struct)定义,相关规范说明如下图所示:
# 解决办法
当模型中外部函数用到了记录(record)类型时,需要用户提供与模型中记录名同名且成员相同的结构体定义。解决办法为:用户提供具有与 Modelica 模型中 record 名称相同的结构体定义的 C 文件或头文件。针对上述案例,将结构体定义的名称test_record_different修改为test_record,具体如下:

修改后的模型在 2024a 中能正常运行。
# 重声明变型值无法传递
# 问题描述
在S ysplorer 2023b 中,分别定义 Number(定义数目)、Polygon(定义边数和边长)、Cal_Perimeter(计算周长)和 Test(测试)模型。
在 2023b 版本中检查 Test 模型无报错,在 Sysplorer 2024a 版本检查相同模型会出现以下报错。
# 问题原因
Sysplorer 2024a 相较于 2023b 进行了内核升级,严格按照 Modelica 规范进行语法检查。对于 replaceable 组件,若没有显式定义约束子句,则其组件定义中的变型会在组件后续的重声明中生效。反之,若显式定义了约束子句,则组件定义中的变型不向后传递,而是约束子句中的变型向后传递。因此在 2023b 中旧版内核未能正确按照规范处理重声明变型的传递,故不报错。
相关规范说明如下图所示:
# 解决办法
在 Cal_Perimeter 进行文本修改,在定义 replaceable 组件时,将变型(n=4)定义在约束子句中,便可将该变型向后进行传递,在 Test 中 a 的维度与该处的变型保持一致。
# 仿真失败,初始化失败
# 问题描述
GCMRSys 库案例GCMRSys.GCMRSys_Case.GRDT.ExamplePCU.PCU_test在 Sysplorer 2023b 上可以正常运行,同样的模型加载到 Sysplorer 2024a 上出现仿真失败。初始化失败的报错。显示如下:
# 问题原因
该问题本质上是模型问题,在两个软件版本上可以看到,状态变量的选择一致,但状态变量的初值有区别,这是导致模型仿真失败的原因。按照规范,初值是根据 start 给定的,start 有层级,越接近外层的 start 值越优先。
在 2023b 求解器没有这么处理,碰巧选择了建模者想要的 start 值作为初值。2024b 按照规范处理导致有一个更接近外层的 start 值作为了某个变量的初值导致了初始化失败。初值的选择对比如下(部分):
# 解决办法
将实际想要给进去的初值在管道模型对应代码行设置,以确定状态变量的初值。如下图所示,给管道的 mediums 的压力 p 赋初值。
修改后的模型编译信息可见,已把管道的 mediums 的压力 p 初值成功给定为 ps_start 值,且仿真运行成功。

以上例子仅仅展示了状态变量初值设置不同导致的问题,但实际出现该问题存在多种原因,为了更好帮助大家解决此类常见问题,以下补充导致该问题的其他常见问题情况和解决办法:
2023b 与 2024a 状态变量、非线性迭代量选取不一致,导致报错。
a) 状态变量不一致的解决办法
针对状态变量选取不一致,可通过改变变量的 stateSelect 属性值实现状态变量选取,未设置时变量的 stateSelect 属性值默认为 default,可将其设置为如下五种等级以调整变量是否选为状态变量。
StateSelect 变量优先级 StateSelect.always 变量必须选取为状态变量 StateSelect.prefer 变量会优先选取为状态变量 StateSelect.default 该等级值为 stateSelect 属性的缺省值,允许被选取为状态变量 StateSelect.avoid 变量应尽量避免被选取为状态变量 StateSelect.never 变量无论如何也不能被选取为状态变量 b) 非线性迭代变量不一致的解决办法
针对非线性迭代量选取不一致,内核会优先将在模型顶层给定了 start 值的变量选为非线性迭代变量,但不一定就会选为非线性迭代变量。若用户希望将某个变量作为求解变量,可以尝试在模型顶层为其给定 start 值。或者可以通过在顶层的 annotation 中添加如下案例的语句:
__MWORKS(Translation(MNonLinearVariables={x}))(变量 x 选为非线性迭代变量),来优先选择想要的非线性迭代量,该案例在模型翻译中可以看到非线性系统迭代变量从原来不加该语句的 y 变成了 x。model Model1 annotation(__MWORKS(Translation(MNonLinearVariables={x}))); Real x; Real y; equation x^3 + y ^5 = 10; x + y = 1; end Model1;2023b 与 2024a 状态变量、非线性迭代量选取一致,仍导致报错。
这种情况首先看报错信息找思路,是否是由于组件代码改变导致的计算报错,也可以尝试在仿真设置界面中修改仿真步长或换其他算法或改仿真精度去解决仿真报错问题。

# 仿真失败,单步计算失败
# 问题描述
车辆热管理库模型案例TAThermalSystem.Examples.System.HtrLoop在 Sysplorer 2023b 上可以正常运行,同样的模型加载到 Sysplorer 2024a 上出现仿真失败。单步计算失败的报错。显示如下:
# 问题原因
Sysplorer 2024a 与 Sysplorer 2023b 相比,内核做了许多优化处理,加快编译速度。两个版本软件对状态变量、非线性迭代量、初值的选择和求解规则上会有所区别。编译信息对比如下:


# 解决办法
方式 1:修改模型精度
根据报错信息可知,是由于非线性系统残差大于允许值导致的计算失败(Warning:The nonlinear system failed for stucking into local extremum while the residual > tolerance)。尝试把仿真设置 > 常规 > 精度的 0.0001 改成 0.001,仿真成功!


方式 2:修改模型算法
模型仿真失败也可能和选择的求解算法有关,可以尝试用仿真设置中其他求解算法仿真。如下,将 Dassl 算法改成 Lsodar,仿真成功(或者 Lsode/Mebdf/Radau5 都可以仿真成功该案例)。

方法 3:修改状态变量和非线性迭代量的选择
若两个版本上模型翻译时显示的状态变量的选取不同或非线性迭代变量的选择不同,可以尝试修改使两个版本尽量保持一致。
状态变量通过变量的 stateSelect 属性值实现状态变量选取,如下 Case1 将 x 变量优先选为状态变量,而 y 未给定 stateSelect 属性值(取默认值 StateSelect.default),故在模型翻译过程中会选取 stateSelect 属性值较高者作为状态变量,即变量 x 被选取为状态变量。
model Case1
Real x(stateSelect=StateSelect.prefer);
Real y;
equation
der(x)+der(y)=1;
x=y+0.5+sin(time);
end Case1;
stateSelect 属性值的以在上方的仿真失败,初始化失败中有详细介绍。
非线性迭代变量的选择也会影响模型求解,内核会优先将在模型顶层给定了 start 值的变量选为非线性迭代变量,但不一定就会选为非线性迭代变量。若用户希望将某个变量作为求解变量,可以尝试在模型顶层为其给定 start 值。此外,对于状态变量、非线性迭代变量的给出的初值也需要关注是否合理,如在一串联回路中保持每个组件给出的流量初值一致,温度初值一致,且建议初值的选择和系统稳定时的结果偏差不太远,更易于求解。
# 参数估值勾选后,编译报错
# 问题描述
案例一:
模型路径TYFlexBody.Examples.SliderCrankMechanism,案例在不勾选仿真设置 > 模型翻译 > 参数估值以便优化模型时,在 2024a 仿真失败,勾选参数估值以便优化模型后仿真成功。参数估值前和参数估值后仿真结果信息如下:


案例二:
路径TYThermalHydraulics.Examples.PressureRegulator的模型在不勾选仿真设置 > 模型翻译 > 参数估值以便优化模型时,在 2024a 仿真成功。当勾选参数估值后,模型翻译出现如下报错:
# 问题原因
参数估值勾选后,会将模型中所有自由参量替换为数值常数,降低模型中的复杂度。对参数进行处理过程中改变了参数和变量数量,导致模型方程数和求解性与未勾选有区别。
# 解决办法
由于勾选参数估值后可以减小线性和非线性方程撕裂后的环路大小,多数情况可以加快模型仿真求解速度,所以建议勾选上。但如果勾选后出现模型翻译方程出错,那么一是要检查模型方程是否存在问题,若找不到方程问题,则选择不勾选,使模型能仿真。