# 不同版本求解表现不一致问题解决方法


本章节主要介绍相同模型在不同版本的 MWORKS 中求解表现不一致问题,模型在不同建模软件中求解表现不一致也可以尝试按照本文档的方式调试。

相同模型在不同版本求解表现不一致问题主要有如下几类:

  • 生成求解器速度差异问题
  • 求解表现不一致

下面就每一种情况分类说明解决方法。

# 生成求解器速度差异问题

不同的机器可能因为性能问题导致生成求解器的速度存在差异,不同的版本之间也可能存在差异,如果遇到生成求解器速度相差较大的问题,有可能是选择的编译器不一致。一般 VC 编译器生成求解器的速度比 GCC 编译器快。

以 Case4_1 示例为例,使用 VC 编译器生成求解器的耗时为 23 s,如下图:

model Case4_1
  parameter Integer n = 500000;
  Real x[n];
equation 
  for i in 1:n loop 
    x[i] = i + 1;
  end for;
end Case4_1;

使用 GCC 编译器的耗时为大约 7 分钟,如下图:

如果遇到不同机器或不同版本同一个模型生成求解器耗时存在较大差异,可以先检查使用的编译器是否一致。

# 求解表现不一致

求解情况不一致包括:求解速度不一致、成功和失败、求解结果不一致。如果在不同机器,不同版本的 MWORKS 中相同模型求解速度或求解结果不一致,可以先从以下几个方面进行检查:

  • 检查仿真设置项是否一致
  • 检查选取的状态变量是否一致
  • 检查选取的非线性迭代变量是否一致
  • 检查状态变量/非线性迭代变量选取的缺省初始条件是否一致

# 仿真设置

主要检查以下仿真配置项:

  • 仿真时间(仿真开始时间和仿真结束时间)
  • 步长(如果设置的是步数则检查步数是否一致)
  • 算法
  • 初始积分步长(使用变步长算法时需要检查)
  • 求解精度
  • “存储事件时刻的变量值”选项设置是否相同
  • 位数(32 位和 64 位)
  • C 编译器
  • “仿真设置->模型翻译->参数估值以便优化模型(改善仿真效率)”选项设置是否一致(这个选项的设置会影响仿真速度)

仿真开始时间、仿真终止时间、步长、算法、初始积分步长、求解精度的设置情况可以在仿真设置 > 常规页面查看,如下图:

可以在仿真设置 > 输出页面查看“存储事件时刻的变量值”选项,如下图:

如果不勾选“存储事件时刻的变量值”选项,那么在事件时刻只会保存事件更新之后的结果;如果勾选了“存储事件时刻的变量值”选项,那么在事件时刻会保存事件更新前和事件更新后的结果。所以这个选项的设置不一样可能会导致仿真结果曲线在事件时刻不一致。

可以在上方工具栏单击主页切换到仿真页面设置 32 位和 64 位或者在仿真设置 > 编译页面设置 32 位和 64 位,如下图:

可以在仿真设置 > 编译页面或者主页 > 选项 > 仿真 > C 编译器页面设置 C 编译器,如下图:


勾选仿真设置 > 模型翻译 > 参数估值以便优化模型改善仿真效率)选项后会对模型中的参数进行估值,可以提升仿真效率,但是模型中的参数在仿真前(翻译后)将不能修改。如果出现在不同机器或不同版本上相同模型的仿真速度存在较大差异,可以检查该选项的设置是否相同,该选项的设置页面如下图:

相关案例可参见历史版本升级到 2024a 版本常见问题及解决方法中参数估值勾选后,编译报错

# 状态变量选取是否一致

由于不同的建模软件或者不同版本的 MWORKS 选取状态变量的策略可能不同,因此如果模型中没有确定选取状态变量,软件自动选取的状态变量可能会不同,选取的状态变量不同,可能导致模型的求解效率,求解结果存在差异,甚至求解失败。勾选仿真设置 > 模型翻译 > 记录所选的连续时间状态变量选项后,翻译模型时就会打印出选取的状态变量。选项设置页面如下图:

例如如下模型 Case4_2 勾选仿真设置 > 模型翻译 > 记录所选的连续时间状态变量选项后,翻译模型时会有如下信息输出。

model Case4_2
  Real a;
  Real b = time;
equation
  der(a) = time;
end Case4_2;

补充说明:模型 Case4_2 翻译过程输出状态变量 a 的信息时,后面有StateSelect.default表示选取状态变量时 a 的优先级,选取状态变量优先级一共有 5 个等级,如下表:

优先级 含义
never 永远不要选为状态变量
avoid 尽量避免选为状态变量
default 根据模型情况,如果适合则选为状态变量
prefer 比 default 级别的变量优先选为状态变量
always 确定选为状态变量

如果没有为变量设置选取为状态变量的优先级,则默认为是 default 级别。

详细的状态变量说明见文档模型分析结果信息解读

# 非线性迭代变量选取是否一致

如果模型中没有确定的选取非线性迭代变量,那么建模软件会自动选取非线性迭代变量,由于不同的建模软件或者不同版本的 MWORKS 选取非线性迭代变量的策略可能不同,会导致模型在分析阶段选取的非线性迭代变量不一致。模型中变量的初值设置会左右 MWORKS 对于非线性迭代变量的选取,例如如下示例,变量 a 和 b 都在非线性方程中,撕裂后,模型中将只有 1 个非线性迭代变量,由于 a 和 b 都没有设置初始值,MWORKS 会从 a 和 b 中任意选取一个变量作为非线性迭代变量,这样模型就会存在随机性可能在不同的建模软件或者不同版本的 MWORKS 中会选取不同的非线性迭代变量。

model Case4_3
  Real a;
  Real b;
equation 
  a * a + b * b = 3.14 * time;
  a + b = sin(time);
end Case4_3;

勾选仿真设置 > 模型翻译 > 输出非线性迭代变量及其初值选项后,翻译模型时会打印出选取的非线性迭代变量及初值信息。选项设置页面如下图:

勾选该选项后,模型 Case4_3 的翻译报表如下图:

如果修改模型 Case4_3 为变量 a 设置 start 值,则会选取变量 a 作为非线性迭代变量,如下:

model Case4_4
  Real a(start = 0);
  Real b;
equation
  a * a + b * b = 3.14 * time;
  a + b = sin(time);
end Case4_4;

上述模型所有变量和方程都是在顶层类中,没有层次化,对于层次的模型,上层的 start 变型会覆盖内层设置的 start 值。例如如下示例,在内层模型中变量 a 和变量 b 都设置了 start 值,并且在外层都没有 start 属性变型,这种情况还是会从变量 a 和变量 b 中任意选一个作为非线性迭代变量。

model Case4_5
  model TestModel
    Real a(start = 1);
    Real b(start = 1);
  equation
    a * a + b * b = 3.14 * time;
    a + b = sin(time);
  end TestModel;

  TestModel tm;
end Case4_5;

如果修改模型在外层为变量 b 设置 start 值,则会选择变量 b 作为非线性迭代变量,如下:

model Case4_6
  model TestModel
    Real a(start = 1);
    Real b(start = 1);
  equation
    a * a + b * b = 3.14 * time;
    a + b = sin(time);
  end TestModel;

  TestModel tm(b(start = 0));
end Case4_6;

如果在外层为变量 a 和变量 b 都设置的 start 值,则还是会从变量 a 和变量 b 中任意选取一个作为非线性迭代变量,因此为避免模型在不同的建模软件中出现不确定性,需要根据模型的实际情况为变量设置合适的初始值使得建模软件能够选取确定准确的非线性迭代变量。

相关案例可参见历史版本升级到 2024a 版本常见问题及解决方法中仿真失败,单步计算失败

# 选取的缺省初始条件是否一致

如果模型中的状态变量或非线性迭代变量没有设置初值,建模软件会自动补充缺省初始值(缺省初始值一般为 0)。不同的建模软件或不同版本的内核补充缺省初始条件的策略可能不同,导致选取的缺省初始条件不一样,可能导致模型求解结果不一致甚至求解失败。

让建模软件自动选取缺省初始条件会存在 2 个弊端:

  • 例如模型中存在 a,b,c 三个状态变量,但是只有一个与 a,b,c 三个变量都有关系的初始条件,此时会从 a,b,c 三个变量中选取两个变量补充缺省初始值,这样模型就会存在随机性(补充缺省初始值的变量可能是 a,b 或者 b,c 或者 a,c);
  • 缺省初始值 0 很多时候并不是一个合适的初始值,状态变量初值设置不合适可能导致模型求解变慢,求解失败,求解结果不正确等问题。

可以通过勾选仿真设置 > 模型翻译 > 记录所选的缺省初始条件选项来查看模型中有没有状态变量是以缺省初始条件作为初始值的。

如下示例 Case4_7:

model Case4_7
  Real a;
  Real b;
  Real c;
equation 
  der(a) = b * b + c * 10 + sin(time);
  b * c + cos(time) = 4 * time;
  b ^ 2 + a ^ 2 + c * 5 = cos(time * 100);
end Case4_7;

模型中有一个状态变量 a 和一个非线性迭代变量 b,都没有设置初始值,勾选“记录所选的缺省初始条件”选项后翻译模型就会有下图所示的信息输出:

关于缺省初始条件的详细描述请参见模型分析结果信息解读文档。

相关案例可参见历史版本升级到 2024a 版本常见问题及解决方法中仿真失败,初始化失败