# Electrical Components¶

The previous section discussed how to create component models in the heat transfer domain. Now let’s turn our attention to how to construct some basic electrical components and then use them to simulate the kinds of systems we saw in our previous electrical example.

In this section we will implement the basic electrical component
models **twice**. The first time through, we will implement each
component without any regard to the others. But the second time
through, we’ll see how we can use the inheritance mechanism in
Modelica to make our lives a little easier.

But in both cases, we’ll use the same connector definitions. In our discussion of Simple Domains, we saw how to construct an electrical connector. As with the previous section on heat transfer, the examples in this section will rely on the connector definitions from the Modelica Standard Library. Those connector definitions look like this:

```
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;
```

## Basic Component Models¶

Given these `connector`

definitions, it is relatively
straightforward to construct a resistor model. The goal of a resistor
model is to encapsulate the relationship between the voltage across
the resistor and the current through the resistor using Ohm’s law.
The following model represents how one might expect such a resistor
model to look:

```
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;
```

In the same way, we might create inductor and capacitor models as follows:

```
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;
```

The important thing to notice about these models is the amount of
common code shared between them. In software development, this kind
of redundancy is frowned upon. In fact, a common software maxim is
“Redundancy is the root of all evil”. The reason this redundancy is a
problem is partly because you are doing the same work multiple times,
but also because this code needs to be *maintained* as well. When you
repeat code and then find a mistake in that code, you have to fix it
everywhere.

## The DRY Principle¶

This issue of redundancy is an important one. So let’s revisit
building models of resistors, inductors and capacitors with the goal
of reducing the amount of repeated code. In software, there is
something called the *DRY principle* where DRY stands for “Don’t
Repeat Yourself”. So our next step is to make our resistor,
capacitor and inductor models DRY.

The key to eliminating redundant code is to identify all the common
code between these models and create a `partial`

model that we can
inherit from. We highlighted the common lines previously. Now we can
capture them in their own model as follows:

```
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;
```

In summary, we’ve extracted the declarations for `p`

, `n`

and
`v`

from the previous models into this model. We’ve also included a
variable, `i`

, to represent the current flowing from pin `p`

to
pin `n`

. Finally, the conservation of charge equation is also
included.

Creating such a model then allows us to create a much more succinct resistor model as follows:

```
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;
```

There are several things to notice about this `Resistor`

model. The
first is how much shorter it is. This is because we inherit the
electrical pins, the conservation of charge equation and the variables
`v`

and `i`

from the `TwoPin`

model. Another thing to notice is
that, by leverage the definitions of `v`

and `i`

, Ohm’s law looks
just like it would if you saw it in a text book.

We can give the same treatment to our inductor and capacitor models:

```
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;
```

Again, we see that the models are much more succinct. Ultimately, factoring out common code in this way means that the component models are easier to write and easier to maintain.

## Circuit Model¶

So far, we’ve only built component models. In order to create a circuit model we first need to define a few more component models. Specifically, we need to create a step voltage source model:

```
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},
```

Note how the `StepVoltage`

model also leverages the `TwoPin`

model. We will also need a ground model which we model as follows:

```
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;
```

The `Ground`

model has only one pin so it cannot inherit from
`TwoPin`

. Recall how we described the AmbientCondition model from
our discussion on Heat Transfer Components an infinite
reservoir. The `Ground`

model serves a very similar purpose. No
matter how much current flows in to or out of an electrical ground,
the voltage remains zero.

Having defined all these components, we can now create a circuit model as follows:

```
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;
```

The schematic diagram for this model is rendered as: