2. Modelica语言核心语法与方程建模思想

Modelica 与多数过程式仿真语言最根本的差别在于:它描述的是“系统由哪些守恒关系约束”,而不是“按什么顺序计算”。理解这一点,才能写出可被 Dymola 正确编译、可跨物理域复用的组件。本节围绕类、模型、连接器、方程与算法、参数与变量、初始方程、因果与非因果建模这几组核心概念展开,并最终落地为一个可运行的多物理组件。

类与模型:复用的基本单位

Modelica 中一切皆类(class)。类通过 extends 继承,通过 replaceable/redeclare 实现可替换设计。model 是最常用的类限制符,表示一个可实例化的完整模型;此外还有 connector(连接器)、record(数据记录)、block(因果块)、function(函数)、package(包)等。限制符决定了该类能否被实例化、能否被连接、内部方程是否允许被外部求解器处理。

一个典型组件的骨架如下:

model Resistor "理想电阻"
  extends Modelica.Electrical.Analog.Interfaces.OnePort;
  parameter Modelica.Units.SI.Resistance R = 100 "电阻值";
equation
  v = R * i;
end Resistor;

这里 OnePort 提供了两个引脚 p、n 以及端口电压 v、电流 i 的定义,extends 让新组件自动获得这些接口,只需补充本构方程 v = R*i。这就是 Modelica 组件复用的核心机制。

连接器:跨物理域的统一接口

连接器是组件之间交换能量的“插头”。它内部只允许声明变量和方程,不允许算法。连接器中的变量分为两类:势变量(potential,如电压、温度、压力、位移)和流变量(flow,如电流、热流、质量流量、力)。

当两个连接器用 connect(a, b) 相连时,Modelica 自动生成两类方程:所有势变量相等(等势),所有流变量之和为零(守恒)。这正是基尔霍夫定律、能量守恒在语言层面的统一表达。例如电气连接器:

connector Pin
  Modelica.Units.SI.Voltage v "势变量";
  flow Modelica.Units.SI.Current i "流变量";
end Pin;

把 connect(p1, p2) 展开,就得到 p1.v = p2.v 与 p1.i + p2.i = 0。同一套机制用于机械平动(位移/力)、转动(角度/力矩)、热(温度/热流)、流体(压力/质量流量),因此多物理耦合只需把不同域的连接器接到对应组件上即可。

参数与变量、方程与算法

parameter 是仿真开始前确定的常量,不参与求解;constant 是编译期常量;普通变量则随仿真演化。给参数赋默认值可提高复用性,例如 parameter Real R = 100。

方程区(equation)声明的是等式约束,而非赋值语句。方程的顺序无关紧要,求解器会统一处理。算法区(algorithm)则是过程式代码,按顺序执行,通常用于查表、条件分支、迭代等难以用纯方程表达的逻辑。一个组件中方程数与未知量数必须相等,否则模型欠定或过定,Dymola 会在编译期报错。

经验法则:能用方程表达的关系优先用 equation,因为它保留非因果性,便于求解器优化;只有确实需要顺序逻辑时才用 algorithm。

初始方程与因果、非因果建模

动态模型需要初始条件。Modelica 用 initial equation 声明仿真开始时刻的约束,例如电容电压初值、质量块初始位置。若未显式给出,Dymola 会尝试用 start 属性作为初值猜测,但猜测不保证收敛,因此关键状态量应显式写初始方程。

因果与非因果是 Modelica 的灵魂。因果建模(如 Simulink 的 block)必须事先指定输入与输出,信号单向流动;非因果建模只写物理关系,输入输出由求解器根据连接关系自动确定。例如 v = R*i 既可解出 v,也可解出 i,取决于外部电路。这种特性让组件可以双向使用,也让多物理耦合变得自然。

编写第一个多物理组件:RC 低通滤波器

下面把上述概念整合为一个可运行示例——RC 低通滤波器,它同时涉及电气域与信号观测。

model RCLowPass "RC低通滤波器"
  import Modelica.Units.SI.*;
  parameter Resistance R = 1000 "电阻";
  parameter Capacitance C = 1e-6 "电容";
  Modelica.Electrical.Analog.Basic.Resistor res(R = R);
  Modelica.Electrical.Analog.Basic.Capacitor cap(C = C);
  Modelica.Electrical.Analog.Basic.Ground gnd;
  Modelica.Electrical.Analog.Sources.SineVoltage src(V = 5, f = 1000);
  Real vOut "输出电压";
equation
  connect(src.p, res.p);
  connect(res.n, cap.p);
  connect(cap.n, gnd.p);
  connect(src.n, gnd.p);
  vOut = cap.v;
  initial equation
    cap.v = 0;
end RCLowPass;

该模型包含四个组件:正弦电压源、电阻、电容、地。连接关系构成回路,vOut 观测电容电压。初始方程设定电容初始电压为零。截止频率 f_c = 1/(2πRC) ≈ 159 Hz,输入 1 kHz 正弦时输出幅值应显著衰减,相位滞后约 81°。在 Dymola 中仿真 5 ms,观察 vOut 波形即可验证低通特性。

RC 低通滤波器:连接器与方程关系图 SineVoltage V=5, f=1kHz Pin p / Pin n Resistor R=1000 Ω v = R·i Capacitor C=1 μF i = C·dv/dt Ground v = 0 connect connect connect vOut = cap.v 连接器展开:势变量相等(v_p = v_n),流变量守恒(i_p + i_n = 0) 初始方程:cap.v = 0 | 截止频率 f_c = 1/(2πRC) ≈ 159 Hz

从图中可以看到,四个组件通过 connect 语句形成回路,连接器自动展开为等势与守恒方程,观测点 vOut 直接取自电容电压。整个模型没有指定任何计算顺序,求解器会根据方程系统自动确定因果方向。这正是 Modelica 非因果建模的价值:组件只描述自身物理规律,系统行为由连接关系自然涌现。

常见错误:忘记给电容或电感写初始方程,Dymola 可能报“初始化失败”或给出非物理的起始值;连接器变量误用 flow 前缀会导致守恒方程错误,表现为能量不守恒或求解发散。