2. 搭建第一个可运行的Modelica模型

上一节我们理解了Modelica“用方程描述物理系统”的基本思想。本节要把这个思想真正落到工具里:在OpenModelica或Dymola中从零创建一个可运行的模型,定义变量与参数,编写方程,运行仿真,查看结果曲线,并把数据导出。为了让过程具体可复现,我们以一个最经典的物理对象——一阶RC电路——作为教学示例。它足够简单,却完整包含了建模、参数化、求解、观察和导出的全部环节。

一、明确建模对象与物理约定

示例对象是一个由理想电压源、电阻和电容串联组成的RC充电回路。我们关心电容两端电压 vC 随时间的变化。在动手之前,必须先固定参照约定,否则方程和结果都会出错:

  • 电流方向:从电压源正极流出,经电阻流向电容,记为 i,取正。
  • 电压极性:电容电压 vC 定义为电容上端相对下端的电位差,取正。
  • 初始状态:电容初始电压为0,即 vC(0) = 0。

这些约定一旦确定,全文和图示都保持一致。RC电路的时间常数 tau = R*C,理论上电容电压按 vC(t) = V*(1 - exp(-t/tau)) 上升,最终趋于电源电压 V。这个解析解正是我们判断仿真结果是否正确的依据。

二、在工具中创建模型

在OpenModelica中,打开OMEdit,选择“新建Modelica类”,类型选 model,命名为 RCCharge。在Dymola中,通过“File → New → Model”创建同名模型。两者生成的骨架相同:一个以 model RCCharge 开头、以 end RCCharge; 结尾的类。Modelica是面向对象的,模型本身就是一个类,方程写在类体内。

接下来定义参数和变量。参数是仿真前确定、运行中不变的量;变量是随时间求解得到的量。示例参数取电源电压 V = 10 V、电阻 R = 1000 Ω、电容 C = 1e-3 F,则时间常数 tau = 1 s。这些数值属于教学示例,便于观察曲线。

model RCCharge
  parameter Real V = 10 "电源电压, V";
  parameter Real R = 1000 "电阻, Ohm";
  parameter Real C = 1e-3 "电容, F";
  Real i "回路电流, A";
  Real vR "电阻电压, V";
  Real vC(start = 0, fixed = true) "电容电压, V";
equation
  vR = R * i;
  i = C * der(vC);
  V = vR + vC;
end RCCharge;

这里有三点值得强调。parameter 关键字声明参数,可在仿真前修改;start = 0, fixed = true 表示 vC 的初始值固定为0,这是求解初值问题的必要条件;der(vC) 表示 vC 对时间的导数。三个方程分别对应欧姆定律、电容的电流-电压关系和回路的电压平衡,它们都是代数或微分方程,而不是赋值语句——这正是Modelica与普通编程语言的根本区别。

三、方程结构与求解逻辑

把上面三个方程联立,可以消去 i 和 vR,得到 R*C*der(vC) + vC = V,即标准的一阶线性微分方程。求解器并不需要我们手工消元,它会在每个时间步同时处理这三个方程。理解这一点,有助于我们判断模型是否“可解”:方程个数必须与未知变量个数匹配,否则会报“方程数不足”或“过约束”。本例中未知量为 i、vR、vC 三个,方程也是三个,结构平衡。

RC充电模型:方程结构与信号流 参数(仿真前设定) V = 10 V R = 1000 Ω C = 1e-3 F 方程(同时求解) vR = R · i i = C · der(vC) V = vR + vC 待求变量 i(电流) vR(电阻电压) vC(电容电压) 数值求解器 初值 vC(0)=0,步长自适应 结果曲线 vC(t) 与数据导出 tau = R·C = 1 s,稳态趋于 10 V

四、设置仿真并运行

在OMEdit中,点击“仿真设置”,把停止时间设为 5 秒(约5个时间常数,足以看到稳态),求解器保持默认的 dassl,输出步长可设为 0.01 秒。在Dymola中,通过“Simulation → Setup”设置 StopTime = 5、OutputInterval = 0.01。然后点击“仿真”按钮。若模型语法或方程结构有误,工具会在消息窗口给出错误,例如变量未声明、方程数不匹配、单位不一致等。首次运行建议先检查消息窗口是否为零错误。

仿真成功后,工具会自动打开结果浏览器。在变量树中勾选 vC,即可看到一条从0开始、逐渐上升并趋于10 V的曲线。为了验证正确性,可以叠加解析解:在5秒时,vC = 10*(1 - exp(-5)) ≈ 9.93 V;在1秒时,vC = 10*(1 - exp(-1)) ≈ 6.32 V。如果曲线在1秒处明显偏离6.32 V,就要检查参数或方程。

五、查看曲线与导出数据

结果曲线不仅能看,还能量化。在OMEdit的绘图窗口中,可以右键曲线选择“导出为CSV”,或在变量树上选择变量后使用“导出结果”。Dymola中可用“Plot → Export”或直接使用 val(vC, 1.0) 在命令窗口查询特定时刻的值。导出的CSV通常包含两列:时间 time 和变量值 vC,可直接用Excel或Python读取,用于后续分析或报告。

下面给出一个可直接参考的仿真设置与结果核对清单,便于第一次建模时逐项确认:

检查项示例值/要求判断依据
模型名与文件名RCCharge.mo类名与文件名一致,避免加载失败
参数单位V、R、C 均带单位注释单位一致可减少量纲错误
初始条件vC(start=0, fixed=true)缺少 fixed 可能导致初值不确定
方程数 vs 变量数3 个方程,3 个未知量结构平衡,求解器可解
停止时间5 s覆盖约5个时间常数
1 s 处 vC约 6.32 V与解析解对比
5 s 处 vC约 9.93 V接近稳态 10 V
导出格式CSV,含 time 与 vC可被外部工具读取
第一次建模最常见的三类问题:一是忘记给状态变量设置 fixed=true,导致初值报错;二是参数单位混用(如把 mF 当成 F),使时间常数差三个数量级;三是把方程写成赋值语句顺序,误以为 vC = ... 会覆盖前面的方程。Modelica中方程是声明式的,顺序不影响求解。

完成以上步骤后,你已经拥有了一个可运行、可验证、可导出的Modelica模型。它虽然只有三个方程,却完整走通了“建模—参数化—求解—观察—导出”的工程闭环。后续更复杂的多领域模型,本质上都是在这个骨架上增加更多变量、更多方程和更多物理接口。