简单的一阶系统

首先,让我们考虑一个非常简单的微分方程:

\[\dot{x} = (1-x)\]

在这个方程中,只有一个变量\(x\)。此方程可以用Modelica语言表述如下:

model FirstOrder
  Real x;
equation
  der(x) = 1-x;
end FirstOrder;

这段代码以关键词model开始,以表明模型定义的开始。后面紧跟着模型的名字FirstOrder,再后面是我们感兴趣的变量声明部分。

从这个方程中,我们可以确定变量\(x\)是一个连续实数。在Modelica语言中,我们可以用Real x;语句来声明它。Real类型只是众多数据类型的一种(在接下来的变量一节中,将会对数据类型进行更加详细的讨论)。

当所有的变量声明完成后,我们就可以编写描述模型特性的方程了。在这个例子中,我们可以用运算符der来表示变量x的一阶导数。所以:

der(x) = (1-x)

其所描述的含义等同于方程:

\[\dot{x} = (1-x)\]

不同于大多数的编程语言,我们并不像运行“程序”那样将代码解析成逐条执行的指令。相反,我们使用Modelica编译器将代码转换成可以仿真的模型。这种仿真的过程基本上等同于求解方程(通常用数值方法)并获取其解的轨迹的过程。如下图所示:

../../../_images/FO.png

通过上面的例子,让你对使用建模语言描述系统的数学特性有了一个初步的了解。我们并不需要描述如何去求解这个微分方程,我们关注的重点完全放在方程本身的特性上。在我们介绍更复杂的实例时,你将会发现很多涉及求解过程的繁琐工作都是由Modelica编译器自动处理的

添加文档

现在,我们已经完成了这个简单数学方程的求解,让我们把重点转移到如何才能使模型更具可读性。我们考虑如下的模型:

model FirstOrderDocumented "A simple first order differential equation"
  Real x "State variable";
equation
  der(x) = 1-x "Drives value of x toward 1.0";
end FirstOrderDocumented;

注意在这个模型中引号中的文字。

理解这些引号中的文字模块非常重要,它们在计算机科学中被称为“字符串”,而不是注释。这些“描述性字符串”不像注释,不能在任意的地方插入。相反的,它们只能在特定的地方插入,以提供与其关联的模型元素的附加说明。

例如,第一个字符串 “A simple first order differential equation” (一个简单的一阶微分方程)用来描述模型的属性。你可以注意到,它紧跟在模型名字后面。如果你希望对模型做相应的注释,文档语句必须插入在模型名字的后面。

在后面我们将会看到,这种文档可以被很多工具所使用。例如,搜索模型时,搜索工具可以利用这些描述性的字符串进行识别匹配。这些文本也可以与模型的图示相关联。当然,这种文档对阅读模型的任何人都很有帮助。

通过上面的例子,我们可以看到,这些描述性的文本也可以放置在模型的其他位置。比如,在变量声明或方程后面添加相应的文档。

初始化

通过上面的例子可以看到,Modelica语言允许我们使用微分方程去描述模型的特性。但是,设定初始条件和编写方程同样重要。

因此,Modelica语言也提供用于描述方程组初始化的结构。例如,如果我们想给模型中变量x赋初值为2,可以在模型中增加initial equation(初始化方程)区域,如下所示:

model FirstOrderInitial "First order equation with initial value"
  Real x "State variable";
initial equation
  x = 2 "Used before simulation to compute initial values";
equation
  der(x) = 1-x "Drives value of x toward 1.0";
end FirstOrderInitial;

我们可以看到,上述模型和前面添加文档小节所述模型唯一不同的地方在于,这里多了initial equation部分,即包含方程x = 2。在前面的例子中,变量x的初始值在模型仿真开始时是不确定的。通常,这意味着变量x的初始值是它的start属性(其缺省值为零)。然而,每个工具都会使用自己特定的算法对最终的方程组进行表示。因此,我们最好明确的声明方程的初始化条件,就像上述模型声明的那样。通过在initial equation部分添加相应的方程,我们就明确的完成了变量x的初始化声明。

如下图所示,是否对变量进行初始化定义,其方程解的轨迹完全不同:

../../../_images/FOI.png

FirstOrderInitial模型展示了初始化系统的典型方式:为系统状态提供明确的初始值。事实上,没有确定初始条件的微分方程组并不完整。FirstOrderInitial模型可以用数学方程表示如下:

\[\dot{x} = (1-x);\; x(0) = 2\]

当然了,很多情况下,你也许需要更为复杂的初始化条件。initial equation区域不仅仅可以包含显示方程的状态变量初始值。

例如,我们可能希望在仿真开始时,\(x\)的导数为零。稍有点代数知识的就会知道,这可以通过指定初始条件\(x(0)=1\)来实现。但是,对于更复杂的系统,通过这种方式确定初始条件是很困难的。在这些情况下,可以在Modelica中直接添加初始条件 \(\dot{x}(0)=0\) ,如下所示:

model FirstOrderSteady
  "First order equation with steady state initial condition"
  Real x "State variable";
initial equation
  der(x) = 0 "Initialize the system in steady state";
equation
  der(x) = 1-x "Drives value of x toward 1.0";
end FirstOrderSteady;

仿真该系统会得到以下结果:

../../../_images/FOS.png

从这些结果中可以看到,因为没有破坏系统平衡的外部激励,\(x\)的导数在仿真开始以及仿真过程中一直保持为0。

本章节提供了Modelica初始化功能的概述,有关初始化功能更完整的内容将在后面的初始化章节中介绍。

试验条件

当搭建模型时,建模人员可能希望为模型关联特定的试验条件。这可以通过应用annotation(标注)来完成。标注中包含的信息与模型的属性没有直接联系。

例如,试验条件的描述包括仿真开始时间、结束时间以及容差范围等,这些信息并不描述模型的特性,只是提供进行模拟仿真的条件。试验条件通过特定的experiment标注保存在模型中。

可以通过设定4个参数完成试验条件的设置,这4个参数都是可选的。如下所示为包含试验条件的一阶系统模型:

model FirstOrderExperiment "Defining experimental conditions"
  Real x "State variable";
initial equation
  x = 2 "Used before simulation to compute initial values";
equation
  der(x) = 1-x "Drives value of x toward 1.0";
  annotation(experiment(StartTime=0,StopTime=8));
end FirstOrderExperiment;

下图是使用这些试验条件的仿真结果:

../../../_images/FOE.png

从图中可以看到,在8秒时仿真终止,因为求解器通过experiment确定了仿真的运行时间。

标注应用

虽然experiment标注在建立模型时被广泛的应用,但是也要注意到,一般情况下,建模工具是可以忽略任何或者全部标注内容的。