Reputation: 2403
How do I implement a constant power load?
Consider the following circuit. This contains a constant power load which represents power consumer(s) that take (in this example) 10 W more less constantly. How do I create a model
that adjusts itself in a way that it consumes 10 W?
My naive approach was the following:
model ConstantPowerLoad
extends Modelica.Electrical.Analog.Interfaces.OnePin;
parameter Modelica.Units.SI.Power P "The constant power value";
equation
v * p.i = P;
end ConstantPowerLoad;
This did not work and I get the message "Failed to solve nonlinear system using Newton solver". Probably this is because the current i
is zero at the startup causing v * 0 = P
with v, P > 0
. So I tried adding an initial resistance when the current is zero. But still, this does not work. I get the same error.
model ConstantPowerLoad
extends Modelica.Electrical.Analog.Interfaces.OnePin;
parameter Modelica.Units.SI.Power P "The constant power value";
parameter Modelica.Units.SI.Resistance R_internal = 1e-3 "A dummy resistance on startup";
equation
if p.i == 0.0 then
R_internal * p.i = v;
else
v * p.i = P;
end if;
end ConstantPowerLoad;
I played around with a lot of if
s and when
s but I just don't get it running.
I'm very new to modelica and such simulations. Therefore I would really appreciate not only a solution but also what I'm structurally thinking wrong about and, if possible, an explanation of why my code does not work.
Thank you very much in advance!
Upvotes: 0
Views: 745
Reputation: 6655
Building a reliable power load (or source) model is not an easy task, so that' s probably the reason why there is no such a model in the Modelica Standard Library.
A power source model might not have a solution at all. In other cases there are two solutions.
You can easily get into a situation where it is impossible to draw the requested power. Your example demonstrates two troublesome cases very nicely:
With a voltage of zero it is impossible to draw the required power, due to P=v*i
. Voltages close to zero are also troublesome, as the current increases to infinity. Of course similar problems arise with the voltage when we use a current source.
(Note that there is no infinity in Modelica, only a maximum possible value: Modelica.Constants.inf
, which is typically defined as 1e60)
A resistance in series to the power source limits the maximum power due to the Maximum power transfer theorem according to the formula Pmax = v^2 / (4*Ri)
(unfortunately the English wiki article is not that great. See also here or refer to the equivalent wiki article in German)
With a resistance of 1Ohm in series and requesting 10W we can get two solutions:
P = v*i = 8.87V*1.12A = 10W
at the load and consequently 1.12V at the resistorP = v*i = 1.12V*8.87A = 10W
at the load and consequently 8.87V at the resistorBoth solutions are correct. Which one you get depends on how the simulation is initialized.
The start
attribute is needed here. It initializes state variables and sets guess values for non-linear iterations (which is what we have here).
There are various implementations available, each with their respective pros and cons. I can recall these two from my mind, but I guess there are alot more out there:
DC_Power
in the DymolaModels library (free, shipped with Dymola): At its core uses a similar setup as you with P=v*i
. It tries to circumvent the various troubles by limiting the current and the power below a certain voltage level.Loads
package in the SmartElectricDrives library (commercial): Uses a PI controller to draw the requested powerIn your specific example we could make use of some facts and build a power source for limited range of applications:
noEvent
. This link is a good starting point (in fact, the whole book can be recommended to anyone starting with Modelica).This is the code of the load:
model Pload
import Modelica.Units.SI;
extends Modelica.Electrical.Analog.Interfaces.OnePort;
parameter SI.Power Pdes=10 "Desired constant power to draw";
parameter SI.Resistance Ri=1 "Inner resistance of connected circuit";
SI.Power Pload "Maximum power, either limited by Pdes or by maximum power theorem";
equation
Pload = min(Pdes, v^2/(4*Ri));
i = if noEvent(abs(v)>0) then Pload/v else 0;
end Pload;
Note that this model is only a starting point. It is only usable, when we know Ri
and it does not deal with the fact, that two solutions exist.
Applying it to your circuit with a voltage ramp of 10V gives this result:
Upvotes: 2