# 常见问题及解决方法
为方便建模人员对遇到的问题进行自查,本文档对收到的外部反馈的问题以及解决方法进行分类说明。
# 连接不合法问题
由于旧版中未按照规范严格检查连接,因此有一些在旧版中创建但是不规范的模型在旧版中不报错,在新版中会报连接不合法的错误。
规范中的相关说明如下图所示:
如果连接中的层级大于等于 3(c1.c2.c3),要求每一级都是连接器。
如下例,在新版中会报连接形式不合法的错误:
model Case3_1
connector C1
connector C2
Real a;
end C2;
C2 c2;
end C1;
model M
C1 c1;
end M;
M m1;
M m2;
equation
connect(m1.c1.c2, m2.c1.c2); // m1.c1.c2形式不合法
end Case3_1;
修改方法:共有 2 种方法可以使得模型不报错。
- 修改模型,将底层连接器引到上层,而不是直接进行跨层连接,修改后如下:
model Case3_2
connector C1
connector C2
Real a;
end C2;
C2 c2;
end C1;
model M
C1 c1;
C1.C2 c12;
equation
connect(c1.c2, c12); // 将c1.c2引到上层
end M;
M m1;
M m2;
equation
connect(m1.c12, m2.c12); // 等同于connect(m1.c1.c2, m2.c1.c2)
end Case3_2;
取消勾选仿真设置 > 模型翻译页面中的“严格检查连接”选项,如下图:

鉴于部分同事/用户是使用拖拽的方式建模,下面以标准库中的组件为例,用拖拽的方式创建连接不规范的模型进行说明。
新建一个模型,从标准库中拖拽一个Modelica.Electrical.Analog.Basic.Resistor组件(单相电阻)和一个Modelica.Electrical.Polyphase.Sources.ConstantVoltage组件(三相电源)到模型中,将这两个组件连接(这两个组件无论是在新版还是在旧版中均不能直接连接,需要选择组件Modelica.Electrical.Polyphase.Sources.ConstantVoltage中的一个分量相连),此时生成的模型文本如下图:
此时连接器constantVoltage.plug_p.pin[1]有 3 级,且第一级 constantVoltage 是 model 类型,不满足当连接中的连接器大于等于 3 级时每一级都为连接器的要求。
本例中将单相电阻与三相电源相连本来是不合理的,这样的连线方式应该被禁止,对其他建模软件也进行了调研,都不允许进行这样的连接。有两种解决方案:
1)修改模型,使用三相电阻与三相电源相连,单相电阻与单相电源相连;
2)修改模型,使用Modelica.Electrical.Polyphase.Basic.PlugToPin_p转接器组件,先将单相电阻与转接器相连,然后在将转接器与三相电源相连。
# 翻译模型慢问题
目前所遇到的模型翻译慢的问题主要有两类:
模型中读取了大量的外部数据(几十万)
模型中方程数量很多(几十万)
# 模型读取大量外部数据
如果模型中使用外部函数读取大量的外部数据(几十万量级),这种情况分析器处理起来负担会比较重,可以将模型中的数据读取放在外部对象中,模型中需要访问外部数据时可以通过外部对象进行访问。关于外部对象的使用,见“外部对象”文档。
# 模型中算法区方程数量很多
如果模型中方程数量较大(方程数量在几十万以上),有可能是使用算法不当导致翻译模型慢。例如下面的示例:
model Case3_3
parameter Integer n = 500000;
Real x[n];
equation
for i in 1:n loop
x[i] = i + 1;
end for;
end Case3_3;
翻译模型耗时 6.2 s,如下图:
如果将模型中的方程修改为算法,如下:
model Case3_4
parameter Integer n = 500000;
Real x[n];
algorithm
for i in 1:n loop
x[i] := i + 1;
end for;
end Case3_4;
翻译模型耗时大约 1 个小时,如下图:
# 不同机器/版本运行情况不一致问题
不同机器/版本运行情况不一样的问题主要有以下几个方面:
生成求解器速度差异
求解速度差异
求解成功/失败差异
求解结果不一致
具体解决方法见不同版本求解表现不一致问题解决方法文档
# 生成求解器失败问题
生成求解器失败一般会生成build.log文件,可以根据build.log文件中的报错信息定位失败原因。如果生成求解器失败报未知错误或者创建 C 代码进程失败则没有build.log文件生成。下面对生成求解器失败的每一种报错以及原因进行说明。
# 未知错误
到目前为止这种错误出现原因为 Simulator/Bin(64) 下的build_gcc.bat/build_vc.bat/build_gcc.sh文件没有可执行权限。要确保 Simulator/Bin(64) 下的所有.bat/.sh文件都有可执行权限。Windows 下没有可执行权限的原因可能是杀毒软件阻止了bat脚本的运行,需要退出杀毒软件或者设为信任项。Linux 下没有可执行权限,需要使用命令设置为有运行权限。
# 创建 C 代码进程失败
可能是缺少 Simulator,检查安装目录下是否有 Simulator。也可能是本地环境问题导致 C 进程失败,本地环境问题目前还没有确定的解决方案,可以尝试重装 MWORKS。
# 不能覆盖模型目标文件(.o 或 .obj 文件)
生成求解器时编译生成的 C 代码前如果仿真结果目录文件夹下有编译生成的目标文件(上次编译时生成的临时文件,Linux 下为.o文件,Windows 下为.obj文件),则会先删除上次编译生成的目标文件。如果已有文件无法删除,会报不能覆盖模型目标文件(.o或.obj文件)错误。
出现这个错误请检查临时文件是否被占用,对临时文件夹是否具有写权限。
# 不能覆盖 MWSolver.dll 文件
生成求解器时会将MWSolver.exe文件从 Simulator/Bin64(如果是 32 位就是 Simulator/Bin)目录下拷贝到仿真结果目录下,如果 Simulator/Bin64(如果是 32 位就是 Simulator/Bin)目录下没有MWSolver.exe文件则会报不能覆盖MWSolver.dll文件的错误。出现这个错误需要检查 Simulator/Bin 或者 Simulator/Bin64 路径下是否有MWsolver.exe文件。
# 生成目标文件(.o 或 .obj)未能成功
代码生成完成后会将生成 C 代码和外部函数代码(如果有)编译成当前平台的库文件。如果编译失败则会报“生成目标文件(.o或.obj)未能成功”的错误。出现此错误先查看仿真结果目录下的build.log文件,从文件内容查看编译时的报错信息,此错误信息为 C 编译器报出,一般是生成的 C 代码或者外部函数代码中有错误导致编译失败,根据报错信息检查代码。如果是外部函数代码报错,根据报错修改外部函数代码,如果是 MWORKS 生成的 C 代码报错,则将问题反馈到内核。
# 生成 MWSolver.dll 文件未能成功
所有 C 代码(MWORKS 生成的 C 代码和外部 C 代码)编译成动态库后, 会将这些编译好的库链接生成MWSolver.dll文件,供求解阶段使用。如果链接过程出错,会报“生成MWSolve.dll文件未能成功错误”,出现此错误是因为链接的库有问题。如果模型中使用了外部函数需要优先检查模型中依赖的外部库是否有问题。主要从以下几个点检查:
在 MWORKS 中选择的位数与外部库位数是否一致,如:MWORKS 中选择 64 位,实际只有 32 位外部库;
如果使用的外部库是静态库,需要保证编译静态库的编译器版本与 MWORKS 中选择的编译器版本完全一致,如:外部静态库是使用 VS2017 编译出来的,那么 MWORKS 中的编译器也必须选择 VS2017,否则可能出现因编译器版本不兼容导致的链接失败的错误;
提示
如果使用动态库则不会有编译器版本不兼容的问题,因此建议将外部函数代码编译成动态库在 MWORKS 中使用。
使用的外部库本身有错误,可以自己写一个程序调用外部库中的函数,看是否能够正确调用;
MWORKS 生成的代码编译出的库有错误,需要将问题反馈到内核定位。
如果是外部函数问题,可以参照“外部函数调试方法”文档对外部函数进行调试。
出现该错误,在仿真结果目录下会生成build.log文件,可以根据build.log文件中的内容判断是外部函数库有问题,还是 MWORKS 生成的代码编译器出的库有错误。
# 找不到有效的 C 编译器
出现这个错误是 MWORKS 中的编译 C 代码脚本在编译之前通过编译器命令验证编译器有效性时失败。一般是 C 编译器路径设置错误或者 C 编译器安装有问题。可以检查以下几点:
检查 MWORKS 中设置的 C 编译器路径是否有错误;
在 MWORKS 中设置 C 编译器页面点击校验编译器,检查编译器是否能够校验通过;
本地通过运行编译器自带的校验脚本或者自己写命令检查编译器是否能够正常使用。
编译器校验失败问题解决方法见下个章节。
# 编译器校验失败
编译器校验失败一般是本地环境有问题,可能原因有:
- 环境变量问题
- VC 编译器安装有问题
- 杀毒软件阻止 bat 脚本运行
- MWORKS 安装路径下的 Simulator 文件夹中有文件缺失
可以按照如下步骤排查本地环境问题:
检查系统环境变量中是否有
C:\Windows\system32\cmd.exe,如下图:
检查系统环境变量中是否有
C:\Program Files\Microsoft SQL Server\100\Tools\Binn\,如下图:
不同版本的 VC,Microsoft SQL Server 后面的数字可能不同,可能是 80,100,130,150 等。
检查本地是否安装杀毒软件,如果安装了,将杀毒软件退出后重启电脑重试;
运行 VC 自带的验证脚本
vcvars64.bat或vcvars32.bat或vcvarsall.bat,检查本地 VC 是否可以正常使用。如果运行脚本后可以看到如下几张图中的信息,说明本地 VC 环境正常,否则说明本地 VC 环境可能有问题,需要尝试重装 VC。
VC 2019 版本中运行
Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build路径下的vcvars32.bat脚本应有上图中的信息输出。
VC 2019 版本中运行
Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build路径下的vcvars64.bat脚本应有上图中的信息输出。由于我本地未安装其他版本的 VC,因此没有将每一个版本的 VC 验证脚本运行正常输出信息截图。
说明:本章节中只列举了目前遇到过的问题,使用上述方法不一定能解决所有编译器校验失败问题,本文档也会根据遇到的问题不断更新。
# FMU 导出/导入问题
# FMU 导出
FMU 导出过程也会对模型进行检查翻译,如果 FMU 导出失败并且有报错信息,先查看直接检查/翻译模型是否会报错,如果检查/翻译模型报错信息与导出 FMU 失败报错相同那么需要先检查是否是模型本身有问题导致检查/翻译失败。如果直接对模型进行翻译不报错,导出 FMU 报错,则需要将问题反馈到内核。
# FMU 导入
如果是其他平台导出的 FMU 在 MWORKS 中导入失败,先使用 FMU 官方提供的 FMU 校验工具 FMU Checker 验证一下 FMU 是否符合 FMI 规范。如果使用 FMU Checker 可以成功求解,则需要将问题反馈到内核,如果使用 FMU Checker 也无法成功求解,则可能是其他平台导出的 FMU 存在问题。如果是 MWORKS 导出的 FMU 在 MWORKS 中导入失败,则需要将问题反馈到内核。
# FMU 求解
FMU 求解问题主要分为两类:
- FMU 求解失败
- FMU 求解结果不正确
FMU 求解失败
FMU 求解失败先检查 FMU 的位数与 MWORKS 中设置的位数是否相同,如果 FMU 是 32 位,则在 MWORKS 中求解时需要选择 32 位,如果 FMU 是 64 位,在 MWORKS 中求解时需要选择 64 位。如果位数选择没有问题,FMU 求解失败,需要将问题反馈到内核。MWORKS 中位数设置页面如下图:
如果 FMU 位数与求解时选择的位数不一致,会出现如下图所示报错:

FMU 求解结果不正确
FMU 求解结果不正确一般是模型问题或者是 bug,这类问题目前还没有比较通用的解决方法,如果遇到此类问题需要反馈到内核。
更多 FMU 导入导出问题相关解答见 FMU 使用常见问题文档。
# Veristand 导出问题
目前遇到的 Veristand 导出问题主要是 MWORKS 中导出的 Veristand 在 NI Veristand 校验工具中校验失败,目前遇到的校验失败原因都是位数不匹配,例如 MWORKS 中导出的 Veristand 是 64 位,安装的 NI Veristand 校验工具是 32 位。位数不匹配时 NI Veristand 校验工具报错如下图:
