Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added more options for homotopy-based initialization of limiters #2561

Merged
merged 12 commits into from
Jun 13, 2018
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 25 additions & 11 deletions Modelica/Blocks/Continuous.mo
Original file line number Diff line number Diff line change
Expand Up @@ -920,9 +920,9 @@ to compute u by an algebraic equation.
"Type of initialization (1: no init, 2: steady state, 3: initial state, 4: initial output)"
annotation(Evaluate=true,
Dialog(group="Initialization"));
parameter Boolean limitsAtInit = true
"= false, if limits are ignored during initialization"
annotation(Evaluate=true, Dialog(group="Initialization"));
parameter Boolean limitsAtInit=true
"Has no longer an effect and is only kept for backwards compatibility (the implementation uses now the homotopy operator)"
annotation (Dialog(tab="Dummy"),Evaluate=true, choices(checkBox=true));
parameter Real xi_start=0
"Initial or guess value for integrator output (= integrator state)"
annotation (Dialog(group="Initialization",
Expand All @@ -938,6 +938,9 @@ to compute u by an algebraic equation.
"Initialization"));
parameter Boolean strict=false "= true, if strict limits with noEvent(..)"
annotation (Evaluate=true, choices(checkBox=true), Dialog(tab="Advanced"));
parameter Modelica.Blocks.Types.LimiterHomotopy homotopyType = Modelica.Blocks.Types.LimiterHomotopy.Linear
"Simplified model for homotopy-based initialization"
annotation (Evaluate=true, Dialog(group="Initialization"));
constant Modelica.SIunits.Time unitTime=1 annotation (HideResult=true);
Modelica.Blocks.Interfaces.RealInput u_ff if withFeedForward
"Optional connector of feed-forward input signal"
Expand Down Expand Up @@ -984,7 +987,8 @@ to compute u by an algebraic equation.
uMax=yMax,
uMin=yMin,
strict=strict,
limitsAtInit=limitsAtInit)
limitsAtInit=limitsAtInit,
homotopyType=homotopyType)
annotation (Placement(transformation(extent={{70,-10},{90,10}})));
protected
parameter Boolean with_I = controllerType==SimpleController.PI or
Expand Down Expand Up @@ -1242,13 +1246,23 @@ to compute u_m by an algebraic equation.
</p>

<p>
If parameter <strong>limitAtInit</strong> = <strong>false</strong>, the limits at the
output of this controller block are removed from the initialization problem which
leads to a much simpler equation system. After initialization has been
performed, it is checked via an assert whether the output is in the
defined limits. For backward compatibility reasons
<strong>limitAtInit</strong> = <strong>true</strong>. In most cases it is best
to use <strong>limitAtInit</strong> = <strong>false</strong>.
When initializing in steady-state, homotopy-based initialization can help the convergence of the solver,
by using a simplified model a the beginning of the solution process. Different options are available.
<ul>
<li><strong>homotopyType=Linear</strong> (default): the limitations are removed from the simplified model,
making it linear. Use this if you know that the controller will not be saturated at steady state.</li>
<li><strong>homotopyType=UpperLimit</strong>: if it is known a priori the controller will be stuck at the upper
limit yMax, this option assumes y = yMax as a simplified model.</li>
<li><strong>homotopyType=LowerLimit</strong>: if it is known a priori the controller will be stuck at the lower
limit yMin, this option assumes y = yMin as a simplified model.</li>
<li><strong>homotopyType=NoHomotopy</strong>: this option does not apply any simplification and keeps the
limiter active throughout the homotopy transformation. Use this if it is unknown whether the controller
is saturated or not at initialization and if the limitations on the output must be enforced throughout
the entire homotopy transformation.</li>
</ul>
</p>
<p>
The parameter <strong>limitAtInit</strong> is obsolete since MSL 3.2.2 and only kept for backwards compatibility.
</p>
</html>"));
end LimPID;
Expand Down
73 changes: 68 additions & 5 deletions Modelica/Blocks/Nonlinear.mo
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,36 @@ package Nonlinear
parameter Boolean strict=false
"= true, if strict limits with noEvent(..)"
annotation (Evaluate=true, choices(checkBox=true), Dialog(tab="Advanced"));
parameter Types.LimiterHomotopy homotopyType = Modelica.Blocks.Types.LimiterHomotopy.Linear "Simplified model for homotopy-based initialization"
annotation (Evaluate=true, Dialog(tab="Advanced"));
parameter Boolean limitsAtInit=true
"Has no longer an effect and is only kept for backwards compatibility (the implementation uses now the homotopy operator)"
annotation (Dialog(tab="Dummy"),Evaluate=true, choices(checkBox=true));
extends Interfaces.SISO;
protected
Real simplifiedExpr "Simplified expression for homotopy-based initialization";

equation
assert(uMax >= uMin, "Limiter: Limits must be consistent. However, uMax (=" + String(uMax) +
") < uMin (=" + String(uMin) + ")");
simplifiedExpr = (if homotopyType == Types.LimiterHomotopy.Linear then u
else if homotopyType == Types.LimiterHomotopy.UpperLimit then uMax
else if homotopyType == Types.LimiterHomotopy.LowerLimit then uMin
else 0);
if strict then
y = homotopy(actual = smooth(0, noEvent(if u > uMax then uMax else if u < uMin then uMin else u)), simplified=u);
if homotopyType == Types.LimiterHomotopy.NoHomotopy then
y = smooth(0, noEvent(if u > uMax then uMax else if u < uMin then uMin else u));
else
y = homotopy(actual = smooth(0, noEvent(if u > uMax then uMax else if u < uMin then uMin else u)),
simplified=simplifiedExpr);
end if;
else
y = homotopy(actual = smooth(0,if u > uMax then uMax else if u < uMin then uMin else u), simplified=u);
if homotopyType == Types.LimiterHomotopy.NoHomotopy then
y = smooth(0,if u > uMax then uMax else if u < uMin then uMin else u);
else
y = homotopy(actual = smooth(0,if u > uMax then uMax else if u < uMin then uMin else u),
simplified=simplifiedExpr);
end if;
end if;
annotation (
Documentation(info="<html>
Expand All @@ -31,6 +49,20 @@ as long as the input is within the specified upper and lower
limits. If this is not the case, the corresponding limits are passed
as output.
</p>
<p>
The parameter <code>homotopyType</code> in the Advanced tab specifies the
simplified behaviour if homotopy-based initialization is used:
<ul>
<li><code>NoHomotopy</code>: the actual expression with limits is used</li>
<li><code>Linear</code>: a linear behaviour y = u is assumed (default option)</li>
<li><code>UpperLimit</code>: it is assumed that the output is stuck at the upper limit u = uMax</li>
<li><code>LowerLimit</code>: it is assumed that the output is stuck at the lower limit u = uMin</li>
</ul>
</p>
<p>
If it is known a priori in which region the input signal will be located, this option can help
a lot by removing one strong nonlinearity from the initialization problem.
</p>
</html>"), Icon(coordinateSystem(
preserveAspectRatio=true,
extent={{-100,-100},{100,100}}), graphics={
Expand Down Expand Up @@ -100,6 +132,10 @@ as output.
extends Interfaces.SISO;
parameter Boolean strict=false "= true, if strict limits with noEvent(..)"
annotation (Evaluate=true, choices(checkBox=true));
parameter Types.VariableLimiterHomotopy homotopyType = Modelica.Blocks.Types.VariableLimiterHomotopy.Linear "Simplified model for homotopy-based initialization"
annotation (Evaluate=true, Dialog(tab="Advanced"));
parameter Real ySimplified = 0 "Fixed value of output in simplified model"
annotation (Dialog(tab="Advanced"));
parameter Boolean limitsAtInit=true
"Has no longer an effect and is only kept for backwards compatibility (the implementation uses now the homotopy operator)"
annotation (Dialog(tab="Dummy"),Evaluate=true, choices(checkBox=true));
Expand All @@ -109,13 +145,27 @@ as output.
Interfaces.RealInput limit2
"Connector of Real input signal used as minimum of input u"
annotation (Placement(transformation(extent={{-140,-100},{-100,-60}})));
protected
Real simplifiedExpr "Simplified expression for homotopy-based initialization";
equation
assert(limit1 >= limit2, "Input signals are not consistent: limit1 < limit2");

simplifiedExpr = (if homotopyType == Types.VariableLimiterHomotopy.Linear then u
else if homotopyType == Types.VariableLimiterHomotopy.Fixed then ySimplified
else 0);
if strict then
y = homotopy(actual = smooth(0, noEvent(if u > limit1 then limit1 else if u < limit2 then limit2 else u)), simplified=u);
if homotopyType == Types.VariableLimiterHomotopy.NoHomotopy then
y = smooth(0, noEvent(if u > limit1 then limit1 else if u < limit2 then limit2 else u));
else
y = homotopy(actual = smooth(0, noEvent(if u > limit1 then limit1 else if u < limit2 then limit2 else u)),
simplified=simplifiedExpr);
end if;
else
y = homotopy(actual = smooth(0,if u > limit1 then limit1 else if u < limit2 then limit2 else u), simplified=u);
if homotopyType == Types.VariableLimiterHomotopy.NoHomotopy then
y = smooth(0,if u > limit1 then limit1 else if u < limit2 then limit2 else u);
else
y = homotopy(actual = smooth(0,if u > limit1 then limit1 else if u < limit2 then limit2 else u),
simplified=simplifiedExpr);
end if;
end if;

annotation (
Expand All @@ -127,6 +177,19 @@ limits specified by the two additional inputs limit1 and
limit2. If this is not the case, the corresponding limit
is passed as output.
</p>
<p>
The parameter <code>homotopyType</code> in the Advanced tab specifies the
simplified behaviour if homotopy-based initialization is used:
<ul>
<li><code>NoHomotopy</code>: the actual expression with limits is used</li>
<li><code>Linear</code>: a linear behaviour y = u is assumed (default option)</li>
<li><code>Fixed</code>: it is assumed that the output is fixed at the value <code>ySimplified</code></li>
</ul>
</p>
<p>
If it is known a priori in which region the input signal will be located, this option can help
a lot by removing one strong nonlinearity from the initialization problem.
</p>
</html>"), Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{100,
100}}), graphics={
Line(points={{0,-90},{0,68}}, color={192,192,192}),
Expand Down
23 changes: 18 additions & 5 deletions Modelica/Blocks/Types.mo
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ package Types
"Table points are interpolated (by Steffen splines) such that the monotonicity is preserved and the first derivative is continuous")
"Enumeration defining the smoothness of table interpolation";

type Extrapolation = enumeration(
type Extrapolation = enumeration(
HoldLastPoint
"Hold the first/last table point outside of the table scope",
LastTwoPoints
Expand All @@ -24,13 +24,13 @@ package Types
NoExtrapolation "Extrapolation triggers an error")
"Enumeration defining the extrapolation of table interpolation";

type TimeEvents = enumeration(
type TimeEvents = enumeration(
Always "Always generate time events at interval boundaries",
AtDiscontinuities "Generate time events at discontinuities (defined by duplicated sample points)",
NoTimeEvents "No time events at interval boundaries")
"Enumeration defining the time event handling of time table interpolation";

type Init = enumeration(
type Init = enumeration(
NoInit
"No initialization (start values are used as guess values with fixed=false)",
SteadyState
Expand All @@ -53,7 +53,7 @@ package Types
</dl>
</html>"));

type InitPID = enumeration(
type InitPID = enumeration(
NoInit
"No initialization (start values are used as guess values with fixed=false)",
SteadyState
Expand Down Expand Up @@ -91,7 +91,7 @@ initialization definition.
</dl>
</html>"));

type SimpleController = enumeration(
type SimpleController = enumeration(
P "P controller",
PI "PI controller",
PD "PD controller",
Expand Down Expand Up @@ -121,6 +121,19 @@ initialization definition.
Cosine "Cosine regularization")
"Enumeration defining the regularization around zero";

type LimiterHomotopy = enumeration(
NoHomotopy "Homotopy is not used",
Linear "Simplified model without limits",
UpperLimit "Simplified model fixed at upper limit",
LowerLimit "Simplified model fixed at lower limit")
"Enumeration defining use of homotopy in limiter components" annotation (Evaluate=true);

type VariableLimiterHomotopy = enumeration(
NoHomotopy "Simplified model = actual model",
Linear "Simplified model: y = u",
Fixed "Simplified model: y = ySimplified")
"Enumeration defining use of homotopy in variable limiter components" annotation (Evaluate=true);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these enumeration alternatives start with a capital letter?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, will do

class ExternalCombiTimeTable
"External object of 1-dim. table where first column is time"
extends ExternalObject;
Expand Down
Loading