miile7
miile7

Reputation: 2403

How to implement a constant power load (CPL)

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?

Constant power load circuit

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 ifs and whens 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

Answers (1)

marco
marco

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.

The problems

A power source model might not have a solution at all. In other cases there are two solutions.

No solution

You can easily get into a situation where it is impossible to draw the requested power. Your example demonstrates two troublesome cases very nicely:

  1. 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)

  2. 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)

Multiple solutions

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 resistor
  • P = v*i = 1.12V*8.87A = 10W at the load and consequently 8.87V at the resistor

Both 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).

Available models

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 power

Solution for this specific case

In your specific example we could make use of some facts and build a power source for limited range of applications:

  • We know the inner resistance of the voltage source. With this information available in the power sink we can compute the maximum power.
  • We compute the current from the voltage at the terminals
  • We have to avoid a division by zero when the voltage is zero. See the code below how to do that. To understand what is going on, I suggest to read about events and preventing events and the operator 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:

Dymola simulation result

Upvotes: 2

Related Questions