电气部件

前一节中讨论了如何在传热领域中创建组件模型。现在让我们将注意力转移到如何构建一些基本的电气元件。然后,我们会用这些模型来建立所看到的电气系统

在这一节中,我们将两次实现基本电气组件的模型。第一次时,我们将独立地实现每个组件,不考虑组件间的关系。但在第二次过程中,我们将看到怎样通过使用Modelica的继承机制去减轻我们的工作量。

但在两种情况下,我们都将使用相同的接口定义。在对简单领域的讨论里,我们看到了如何构建一个电连接器。与上一节传热一样,本节中的例子将依赖于Modelica标准库的连接器定义。这些接口的定义如下:

connector PositivePin "Positive pin of an electric component"
  Modelica.SIunits.Voltage v "Potential at the pin";
  flow Modelica.SIunits.Current i "Current flowing into the pin";
end PositivePin;

connector NegativePin "Negative pin of an electric component"
  Modelica.SIunits.Voltage v "Potential at the pin";
  flow Modelica.SIunits.Current i "Current flowing into the pin";
end NegativePin;

基本组件模型

有了这些connector定义,构建电阻模型就相对简单了。电阻模型的目标是使用欧姆定律去封装电阻两端电压与电阻器内电流之间的关系。下面的模型表示上述电阻模型的一种可能形式:

within ModelicaByExample.Components.Electrical.VerboseApproach;
model Resistor "A resistor model"
  parameter Modelica.SIunits.Resistance R;
  Modelica.Electrical.Analog.Interfaces.PositivePin p
    annotation (Placement(transformation(extent={{-110,-10},{-90,10}})));
  Modelica.Electrical.Analog.Interfaces.NegativePin n
    annotation (Placement(transformation(extent={{90,-10},{110,10}})));
protected
  Modelica.SIunits.Voltage v = p.v-n.v;
equation
  p.i + n.i = 0 "Conservation of charge";
  v = p.i*R "Ohm's law";
end Resistor;

以同样的方式,我们可以创建电感和电容的模型,如下:

within ModelicaByExample.Components.Electrical.VerboseApproach;
model Inductor "An inductor model"
  parameter Modelica.SIunits.Inductance L;
  Modelica.Electrical.Analog.Interfaces.PositivePin p
    annotation (Placement(transformation(extent={{-110,-10},{-90,10}})));
  Modelica.Electrical.Analog.Interfaces.NegativePin n
    annotation (Placement(transformation(extent={{90,-10},{110,10}})));
protected
  Modelica.SIunits.Voltage v = p.v-n.v;
equation
  p.i + n.i = 0 "Conservation of charge";
  L*der(p.i) = p.v;
end Inductor;
within ModelicaByExample.Components.Electrical.VerboseApproach;
model Capacitor "A capacitor model"
  parameter Modelica.SIunits.Capacitance C;
  Modelica.Electrical.Analog.Interfaces.PositivePin p
    annotation (Placement(transformation(extent={{-110,-10},{-90,10}})));
  Modelica.Electrical.Analog.Interfaces.NegativePin n
    annotation (Placement(transformation(extent={{90,-10},{110,10}})));
protected
  Modelica.SIunits.Voltage v = p.v-n.v;
equation
  p.i + n.i = 0 "Conservation of charge";
  C*der(v) = p.i;
end Capacitor;

要注意的这些模型之间共同代码。在软件开发中,这种程度的冗余时常会被人鄙视。事实上,有条常用的软件工程格言说:“冗余是万恶根源”。这种冗余之所以是一个问题,一方面是由于你将同样的工作重复了多次,另一方面也因为代码也是需要维护的。若你在重复代码内找到错误,你就要在每一处进行修复。

DRY原则

冗余是一个重要的问题。因此,为减少重复的代码,让我们再观察了电阻、电感和电容的模型。在软件工程里有所谓的DRY原则。其中DRY表示“不要重复”。因此,我们的下一步任务就是使电阻、电容和电感模型让变得DRY。

要消除冗余代码的关键在于,要确定这些模型内所有的公共代码,并创建一个我们可以从之继承的partial模型。我们在前面已经高亮了公共代码行。现在,我们可以将这些代码放到一个如下的单独模型内:

within ModelicaByExample.Components.Electrical.DryApproach;
partial model TwoPin "Common elements of two pin electrical components"
  Modelica.Electrical.Analog.Interfaces.PositivePin p
    annotation (Placement(transformation(extent={{-110,-10},{-90,10}})));
  Modelica.Electrical.Analog.Interfaces.NegativePin n
    annotation (Placement(transformation(extent={{90,-10},{110,10}})));
protected
  Modelica.SIunits.Voltage v = p.v-n.v;
  Modelica.SIunits.Current i = p.i;
equation
  p.i + n.i = 0 "Conservation of charge";
end TwoPin;

简而言之,我们将pnv的声明从旧模型提取这个模型里。我们还引入了一个变量i,以代表从引脚p到引脚n的电流。最后,电荷守恒方程也包括在内。

创建这样的模型后,我们就可以创建一个更简洁的电阻模型,如下:

within ModelicaByExample.Components.Electrical.DryApproach;
model Resistor "A DRY resistor model"
  parameter Modelica.SIunits.Resistance R;
  extends TwoPin;
equation
  v = i*R "Ohm's law";
end Resistor;

这个Resistor模型有几点事情需要注意。首先是模型变得有多短。这是因为我们从TwoPin模型继承了电引脚、电荷守恒方程和变量v以及i。另一个要注意的点是,通过使用vi的定义,欧姆定律看起来一本教科书里的一模一样。

我们可以用相同方法处理电感和电容的模型:

within ModelicaByExample.Components.Electrical.DryApproach;
model Capacitor "A DRY capacitor model"
  parameter Modelica.SIunits.Capacitance C;
  extends TwoPin;
equation
  C*der(v) = i;
end Capacitor;
within ModelicaByExample.Components.Electrical.DryApproach;
model Inductor "A DRY inductor model"
  parameter Modelica.SIunits.Inductance L;
  extends TwoPin;
equation
  L*der(i) = v;
end Inductor;

我们再一次看到的模型编得更为简洁。基本上,以这种方式抽出公共代码意味着,组件模型编得更容易编写以及更方便维护。

电路模型

到目前为止,我们只创建了组件模型。为了创建电路模型,我们首先还需要多定义几个组件模型。具体来说,我们需要创建一个阶跃电压源模型:

within ModelicaByExample.Components.Electrical.DryApproach;
model StepVoltage "A DRY step voltage source"
  parameter Modelica.SIunits.Voltage V0;
  parameter Modelica.SIunits.Voltage Vf;
  parameter Modelica.SIunits.Time stepTime;
  extends TwoPin;
          color={0,0,255},

请注意StepVoltage模型也利用了TwoPin模型。我们还需要如下的接地模型:

within ModelicaByExample.Components.Electrical.DryApproach;
model Ground "Electrical ground"
  Modelica.Electrical.Analog.Interfaces.PositivePin ground "Ground pin"
    annotation (Placement(transformation(extent={{-10,70},{10,90}})));
equation
  ground.v = 0;
end Ground;

Ground模型只有一个引脚,因此不能继承TwoPin。回想一下在讨论传热组件环境条件模型时,我们是如何描述无限大容器的。Ground模型提供了非常类似的功用。不管多少电流流入或流出电接地,电压保持为零。

定义了所有这些组件后,现在我们可以创建电路模型如下:

within ModelicaByExample.Components.Electrical.Examples;
model SwitchedRLC "Recreation of the switched RLC circuit"
  DryApproach.StepVoltage Vs(V0=0, Vf=24, stepTime=0.5)
    annotation (Placement(transformation(
        extent={{-10,-10},{10,10}},
        rotation=270,
        origin={-40,0})));
  DryApproach.Inductor inductor(L=1)
    annotation (Placement(transformation(extent={{-10,10},{10,30}})));
  DryApproach.Capacitor capacitor(C=1e-3) annotation (Placement(transformation(
        extent={{-10,-10},{10,10}},
        rotation=90,
        origin={30,0})));
  DryApproach.Resistor resistor(R=100) annotation (Placement(transformation(
        extent={{-10,-10},{10,10}},
        rotation=90,
        origin={60,2})));
  DryApproach.Ground ground
    annotation (Placement(transformation(extent={{-10,-38},{10,-18}})));
equation
  connect(inductor.n, resistor.n) annotation (Line(
      points={{10,20},{60,20},{60,12}},
      color={0,0,255},
      smooth=Smooth.None));
  connect(capacitor.n, inductor.n) annotation (Line(
      points={{30,10},{30,20},{10,20}},
      color={0,0,255},
      smooth=Smooth.None));
  connect(inductor.p, Vs.p) annotation (Line(
      points={{-10,20},{-40,20},{-40,10}},
      color={0,0,255},
      smooth=Smooth.None));
  connect(capacitor.p, ground.ground) annotation (Line(
      points={{30,-10},{30,-20},{0,-20}},
      color={0,0,255},
      smooth=Smooth.None));
  connect(resistor.p, ground.ground) annotation (Line(
      points={{60,-8},{60,-20},{0,-20}},
      color={0,0,255},
      smooth=Smooth.None));
  connect(Vs.n, ground.ground) annotation (Line(
      points={{-40,-10},{-40,-20},{0,-20}},
      color={0,0,255},
      smooth=Smooth.None));
end SwitchedRLC;

该模型的示意图显示如下:

Modeling the step response of an RLC circuit