DC shunt motor
A DC motor has a fixed outer part, called stator, and a rotating inner part, called rotor. Both parts contain a coil of wire through which current flows. In the case of a shunt motor, these two inductors are connected in parallel to a source of electric energy.
First, we model the stator and then the rotor. Finally, we combine them into the motor model.
Stator
First and foremost, the stator has a coil, which generates a magnetic field. We use the methods linear_inductor
and thermal_capacity
from the ComponentLibrary
to define storage components that model its inductance and thermal capacity:
coil = linear_inductor(1.0)
tc = thermal_capacity(1.0, 2.0);
To define the stator model, we further use the reversible component emc
that models the coupling between the electric and the magnetic energy domain, and we use the method magnetic_resistor
to define an irreversible component that models the resistance of the coil.
stator = CompositeSystem(
Dtry(
:b => Dtry(Junction(magnetic_flux, Position(2, 3), exposed=true, power=false)),
:q => Dtry(Junction(charge, Position(2, 1), exposed=true)),
:s => Dtry(Junction(entropy, Position(2, 5))),
),
Dtry(
:emc => Dtry(
InnerBox(
Dtry(
:q => Dtry(InnerPort(■.q)),
:b => Dtry(InnerPort(■.b)),
),
emc,
Position(2, 2)
),
),
:coil => Dtry(
InnerBox(
Dtry(
:b => Dtry(InnerPort(■.b)),
),
coil,
Position(1, 3)
),
),
:res => Dtry(
InnerBox(
Dtry(
:b => Dtry(InnerPort(■.b)),
:s => Dtry(InnerPort(■.s))
),
magnetic_resistor(0.01),
Position(2, 4)
),
),
:tc => Dtry(
InnerBox(
Dtry(
:s => Dtry(InnerPort(■.s))
),
tc,
Position(1, 5)
),
),
)
)
Rotor
For simplicity, we reuse the primitive subsystems coil
and tc
of the stator model, although the parameters probably need to be updated. Further, we use the method angular_mass
from the library to define a component that models storage of kinetic energy:
mass = angular_mass(1.0);
As the centerpiece of the model, we define a reversible component that describes the coupling of the magnetic energy domain and the kinetic energy domain, which depends on the magnetic flux generated by the stator:
mkc = let
bₛ₊x = XVar(:bₛ)
b₊e = EVar(:b)
p₊e = EVar(:p)
b₊f = bₛ₊x * p₊e
p₊f = -(bₛ₊x * b₊e)
ReversibleComponent(
Dtry(
:b => Dtry(ReversiblePort(FlowPort(magnetic_flux, b₊f))),
:p => Dtry(ReversiblePort(FlowPort(angular_momentum, p₊f))),
:bₛ => Dtry(ReversiblePort(StatePort(magnetic_flux)))
)
)
end;
To define the rotor model, we additionally use the library method rotational_friction
to describe the mechanical friction of the rotor.
rotor = CompositeSystem(
Dtry(
:q => Dtry(Junction(charge, Position(2, 1), exposed=true)),
:b => Dtry(Junction(magnetic_flux, Position(2, 3))),
:bₛ => Dtry(Junction(magnetic_flux, Position(1, 4), exposed=true, power=false)),
:p => Dtry(Junction(angular_momentum, Position(2, 5), exposed=true)),
:s => Dtry(Junction(entropy, Position(3, 4))),
),
Dtry(
:emc => Dtry(
InnerBox(
Dtry(
:q => Dtry(InnerPort(■.q)),
:b => Dtry(InnerPort(■.b)),
),
emc,
Position(2, 2)
),
),
:coil => Dtry(
InnerBox(
Dtry(
:b => Dtry(InnerPort(■.b)),
),
coil,
Position(1, 3)
),
),
:mkc => Dtry(
InnerBox(
Dtry(
:b => Dtry(InnerPort(■.b)),
:p => Dtry(InnerPort(■.p)),
:bₛ => Dtry(InnerPort(■.bₛ, power=false)),
),
mkc,
Position(2, 4)
),
),
:mass => Dtry(
InnerBox(
Dtry(
:p => Dtry(InnerPort(■.p)),
),
mass,
Position(1, 5)
),
),
:res => Dtry(
InnerBox(
Dtry(
:b => Dtry(InnerPort(■.b)),
:s => Dtry(InnerPort(■.s))
),
magnetic_resistor(0.01),
Position(3, 3)
),
),
:mf => Dtry(
InnerBox(
Dtry(
:p => Dtry(InnerPort(■.p)),
:s => Dtry(InnerPort(■.s))
),
rotational_friction(0.01),
Position(3, 5)
),
),
:tc => Dtry(
InnerBox(
Dtry(
:s => Dtry(InnerPort(■.s))
),
tc,
Position(4, 4)
),
),
)
)
Motor
Now we interconnect the stator and rotor:
motor = CompositeSystem(
Dtry(
:q => Dtry(Junction(charge, Position(2, 1), exposed=true)),
:bₛ => Dtry(Junction(magnetic_flux, Position(2, 2), power=false)),
:p => Dtry(Junction(angular_momentum, Position(3, 3), exposed=true)),
),
Dtry(
:stator => Dtry(
InnerBox(
Dtry(
:q => Dtry(InnerPort(■.q)),
:b => Dtry(InnerPort(■.bₛ, power=false)),
),
stator,
Position(1, 2)
),
),
:rotor => Dtry(
InnerBox(
Dtry(
:q => Dtry(InnerPort(■.q)),
:bₛ => Dtry(InnerPort(■.bₛ, power=false)),
:p => Dtry(InnerPort(■.p)),
),
rotor,
Position(3, 2)
),
),
)
)
Evolution equations
As the implementation does not yet support the simulation of open systems with 'boundary conditions', we can merely assemble the equations:
assemble(motor)
Flows:
rotor.coil.b.f = q.e + -1.0 * stator.coil.b.x * rotor.mass.p.e + -1.0 * rotor.res.r * rotor.coil.b.e
rotor.mass.p.f = -1.0 * rotor.mf.d * rotor.mass.p.e + stator.coil.b.x * rotor.coil.b.e + p.f
rotor.tc.s.f = rotor.mf.d * (rotor.mass.p.e^2.0) * ((ENV.θ + rotor.tc.s.e)^-1.0) + rotor.res.r * (rotor.coil.b.e^2.0) * ((ENV.θ + rotor.tc.s.e)^-1.0)
stator.coil.b.f = q.e + -1.0 * stator.res.r * stator.coil.b.e
stator.tc.s.f = stator.res.r * (stator.coil.b.e^2.0) * ((ENV.θ + stator.tc.s.e)^-1.0)
Efforts:
rotor.coil.b.e = rotor.coil.b.x * (rotor.coil.l^-1.0)
rotor.mass.p.e = rotor.mass.p.x * (rotor.mass.m^-1.0)
rotor.tc.s.e = rotor.tc.c₁ * (exp(rotor.tc.s.x * (rotor.tc.c₂^-1.0))) * (rotor.tc.c₂^-1.0) + -1.0 * ENV.θ
stator.coil.b.e = stator.coil.b.x * (stator.coil.l^-1.0)
stator.tc.s.e = stator.tc.c₁ * (exp(stator.tc.s.x * (stator.tc.c₂^-1.0))) * (stator.tc.c₂^-1.0) + -1.0 * ENV.θ