From 40210f6e2e1605b54b2a2153cf43fef4e5e2ff99 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Tue, 29 May 2018 17:22:42 +0200 Subject: [PATCH 01/12] Added more options for homotopy-based initialization of limiters --- Modelica/Blocks/Nonlinear.mo | 73 +++++++++++++++++++++++++++++++++--- Modelica/Blocks/Types.mo | 13 +++++++ 2 files changed, 81 insertions(+), 5 deletions(-) diff --git a/Modelica/Blocks/Nonlinear.mo b/Modelica/Blocks/Nonlinear.mo index 0ea2c12f14..be1efc36db 100644 --- a/Modelica/Blocks/Nonlinear.mo +++ b/Modelica/Blocks/Nonlinear.mo @@ -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.uMax then uMax + else if homotopyType == Types.LimiterHomotopy.uMin 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=" @@ -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.

+

+The parameter homotopyType in the Advanced tab specifies the +simplified behaviour if homotopy-based initialization is used: +

+

+

+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. +

"), Icon(coordinateSystem( preserveAspectRatio=true, extent={{-100,-100},{100,100}}), graphics={ @@ -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)); @@ -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 ( @@ -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.

+

+The parameter homotopyType in the Advanced tab specifies the +simplified behaviour if homotopy-based initialization is used: +

+

+

+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. +

"), Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{100, 100}}), graphics={ Line(points={{0,-90},{0,68}}, color={192,192,192}), diff --git a/Modelica/Blocks/Types.mo b/Modelica/Blocks/Types.mo index f5e85c04d0..e84cb16e83 100644 --- a/Modelica/Blocks/Types.mo +++ b/Modelica/Blocks/Types.mo @@ -121,6 +121,19 @@ initialization definition. Cosine "Cosine regularization") "Enumeration defining the regularization around zero"; + type LimiterHomotopy = enumeration( + noHomotopy "Simplified model = actual model", + linear "Simplified model: y = u", + uMax "Simplified model: y = uMax", + uMin "Simplified model: y = uMin") + "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); + class ExternalCombiTimeTable "External object of 1-dim. table where first column is time" extends ExternalObject; From d23dee4b1e137fd9db9f1bd17650efdcbc9ce67a Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Wed, 30 May 2018 15:50:44 +0200 Subject: [PATCH 02/12] Changed enumeration values to start with capital letters; updated and corrected documentation --- Modelica/Blocks/Nonlinear.mo | 36 ++++++++++++++++++------------------ Modelica/Blocks/Types.mo | 14 +++++++------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/Modelica/Blocks/Nonlinear.mo b/Modelica/Blocks/Nonlinear.mo index be1efc36db..5f62a30331 100644 --- a/Modelica/Blocks/Nonlinear.mo +++ b/Modelica/Blocks/Nonlinear.mo @@ -10,7 +10,7 @@ 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" + 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)" @@ -22,19 +22,19 @@ package Nonlinear 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.uMax then uMax - else if homotopyType == Types.LimiterHomotopy.uMin then uMin + simplifiedExpr = (if homotopyType == Types.LimiterHomotopy.Linear then u + else if homotopyType == Types.LimiterHomotopy.UMax then uMax + else if homotopyType == Types.LimiterHomotopy.UMin then uMin else 0); if strict then - if homotopyType == Types.LimiterHomotopy.noHomotopy then + 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 - if homotopyType == Types.LimiterHomotopy.noHomotopy then + 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), @@ -53,10 +53,10 @@ as output. The parameter homotopyType in the Advanced tab specifies the simplified behaviour if homotopy-based initialization is used:

@@ -132,7 +132,7 @@ a lot by removing one strong nonlinearity from the initialization problem. 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" + 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")); @@ -149,18 +149,18 @@ a lot by removing one strong nonlinearity from the initialization problem. 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 + simplifiedExpr = (if homotopyType == Types.VariableLimiterHomotopy.Linear then u + else if homotopyType == Types.VariableLimiterHomotopy.Fixed then ySimplified else 0); if strict then - if homotopyType == Types.VariableLimiterHomotopy.noHomotopy then + 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 - if homotopyType == Types.VariableLimiterHomotopy.noHomotopy then + 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), @@ -181,9 +181,9 @@ is passed as output. The parameter homotopyType in the Advanced tab specifies the simplified behaviour if homotopy-based initialization is used:

diff --git a/Modelica/Blocks/Types.mo b/Modelica/Blocks/Types.mo index e84cb16e83..eb73de7316 100644 --- a/Modelica/Blocks/Types.mo +++ b/Modelica/Blocks/Types.mo @@ -122,16 +122,16 @@ initialization definition. "Enumeration defining the regularization around zero"; type LimiterHomotopy = enumeration( - noHomotopy "Simplified model = actual model", - linear "Simplified model: y = u", - uMax "Simplified model: y = uMax", - uMin "Simplified model: y = uMin") + NoHomotopy "Simplified model = actual model", + Linear "Simplified model: y = u", + UMax "Simplified model: y = uMax", + UMin "Simplified model: y = uMin") "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") + 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); class ExternalCombiTimeTable From 13b0c0cc7bf3fa16cc8fc89f1d499d0613b82eb1 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Mon, 4 Jun 2018 19:36:37 +0200 Subject: [PATCH 03/12] Added test cases for advanced homotopy options of Limiter and VariableLimiter blocks --- ModelicaTest/Blocks.mo | 315 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 312 insertions(+), 3 deletions(-) diff --git a/ModelicaTest/Blocks.mo b/ModelicaTest/Blocks.mo index 7fd295ad00..5d87aa6347 100644 --- a/ModelicaTest/Blocks.mo +++ b/ModelicaTest/Blocks.mo @@ -187,7 +187,7 @@ package Blocks "Test models for Modelica.Blocks" use_reset=true) annotation(Placement(transformation(extent={{-20,60},{0,80}}))); Modelica.Blocks.Sources.Constant const(k=1.0) annotation(Placement(transformation(extent={{-60,60},{-40,80}}))); Modelica.Blocks.Logical.GreaterEqualThreshold greaterEqualThreshold(threshold=1.0) annotation(Placement(transformation(extent={{20,60},{40,80}}))); - equation + equation connect(const.y, integrator.u) annotation(Line( points={{-39,70},{-34,70},{-27,70},{-22,70}}, color={0,0,127})); @@ -211,7 +211,7 @@ package Blocks "Test models for Modelica.Blocks" Modelica.Blocks.Sources.BooleanPulse booleanPulse( period=1.0) annotation(Placement(transformation(extent={{-80,20},{-60,40}}))); Modelica.Blocks.Logical.FallingEdge fallingEdge annotation(Placement(transformation(extent={{0,-20},{20,0}}))); - equation + equation connect(switch.y, integrator.u) annotation(Line( points={{21,30},{38,30}}, color={0,0,127})); @@ -245,7 +245,7 @@ package Blocks "Test models for Modelica.Blocks" Modelica.Blocks.Sources.BooleanPulse booleanPulse( period=1.0) annotation(Placement(transformation(extent={{-80,20},{-60,40}}))); Modelica.Blocks.Logical.Change change annotation(Placement(transformation(extent={{0,-20},{20,0}}))); - equation + equation connect(switch.y, integrator.u) annotation(Line( points={{21,30},{38,30}}, color={0,0,127})); @@ -401,6 +401,315 @@ package Blocks "Test models for Modelica.Blocks" annotation (experiment(StopTime=1.1)); end StrictLimiters; + model LimitersHomotopy + "Tests the homotopy-based initialization options of the limiter blocks" + extends Modelica.Icons.Example; + + encapsulated model MustUseHomotopy "Only works with homotopy-based initialization" + Real x(start = 0); + equation + 0 = homotopy(sin(x)*(x - 100), + x - 100); + assert(abs(x - 100) < 1e-6, "Wrong solution selected"); + end MustUseHomotopy; + + + MustUseHomotopy mustUseHomotopy + annotation (Placement(transformation(extent={{320,180},{340,200}}))); + Modelica.Blocks.Continuous.FirstOrder controllerFeedbackPart1( + T=1, + initType=Modelica.Blocks.Types.Init.SteadyState, + k=-1) annotation (Placement(transformation(extent={{-140,100},{-160,120}}))); + Modelica.Blocks.Nonlinear.Limiter limiter1( + uMax=0.99, uMin=-0.99, + homotopyType=Modelica.Blocks.Types.LimiterHomotopy.UMax) + annotation (Placement(transformation(extent={{-160,140},{-140,160}}))); + Modelica.Blocks.Math.Feedback internalFeedback1 + annotation (Placement(transformation(extent={{-200,140},{-180,160}}))); + Modelica.Blocks.Math.Asin asin1 + annotation (Placement(transformation(extent={{-100,140},{-80,160}}))); + Modelica.Blocks.Sources.Ramp ramp1( + duration=100, + startTime=1, + height=-9.5, + offset=10) + annotation (Placement(transformation(extent={{-280,140},{-260,160}}))); + Modelica.Blocks.Continuous.FirstOrder firstOrder1( + T=1, + initType=Modelica.Blocks.Types.Init.SteadyState, + k=2/Modelica.Constants.pi) + annotation (Placement(transformation(extent={{-60,140},{-40,160}}))); + Modelica.Blocks.Math.Feedback feedback1 + annotation (Placement(transformation(extent={{-240,140},{-220,160}}))); + Modelica.Blocks.Continuous.FirstOrder controllerFeedbackPart2( + T=1, + initType=Modelica.Blocks.Types.Init.SteadyState, + k=-1) annotation (Placement(transformation(extent={{-140,-50},{-160,-30}}))); + Modelica.Blocks.Nonlinear.Limiter limiter2( + uMax=0.99, uMin=-0.99, + homotopyType=Modelica.Blocks.Types.LimiterHomotopy.UMin) + annotation (Placement(transformation(extent={{-160,-10},{-140,10}}))); + Modelica.Blocks.Math.Feedback internalFeedback2 + annotation (Placement(transformation(extent={{-200,-10},{-180,10}}))); + Modelica.Blocks.Math.Asin asin2 + annotation (Placement(transformation(extent={{-100,-10},{-80,10}}))); + Modelica.Blocks.Sources.Ramp ramp2( + duration=100, + startTime=1, + height=9.5, + offset=-10) + annotation (Placement(transformation(extent={{-280,-10},{-260,10}}))); + Modelica.Blocks.Continuous.FirstOrder firstOrder2( + T=1, + initType=Modelica.Blocks.Types.Init.SteadyState, + k=2/Modelica.Constants.pi) + annotation (Placement(transformation(extent={{-60,-10},{-40,10}}))); + Modelica.Blocks.Math.Feedback feedback2 + annotation (Placement(transformation(extent={{-240,-10},{-220,10}}))); + Modelica.Blocks.Continuous.FirstOrder controllerFeedbackPart3( + T=1, + initType=Modelica.Blocks.Types.Init.SteadyState, + k=-1) annotation (Placement(transformation(extent={{-140,-160},{-160,-140}}))); + Modelica.Blocks.Nonlinear.Limiter limiter3( + uMax=0.99, uMin=-0.99, + homotopyType=Modelica.Blocks.Types.LimiterHomotopy.NoHomotopy) + annotation (Placement(transformation(extent={{-160,-120},{-140,-100}}))); + Modelica.Blocks.Math.Feedback internalFeedback3 + annotation (Placement(transformation(extent={{-200,-120},{-180,-100}}))); + Modelica.Blocks.Math.Asin asin3 + annotation (Placement(transformation(extent={{-100,-120},{-80,-100}}))); + Modelica.Blocks.Sources.Ramp ramp3( + duration=100, + startTime=1, + height=-9.5, + offset=10) + annotation (Placement(transformation(extent={{-280,-120},{-260,-100}}))); + Modelica.Blocks.Continuous.FirstOrder firstOrder3( + T=1, + initType=Modelica.Blocks.Types.Init.SteadyState, + k=2/Modelica.Constants.pi) + annotation (Placement(transformation(extent={{-60,-120},{-40,-100}}))); + Modelica.Blocks.Math.Feedback feedback3 + annotation (Placement(transformation(extent={{-240,-120},{-220,-100}}))); + Modelica.Blocks.Continuous.FirstOrder controllerFeedbackPart4( + T=1, + initType=Modelica.Blocks.Types.Init.SteadyState, + k=-1) annotation (Placement(transformation(extent={{160,100},{140,120}}))); + Modelica.Blocks.Nonlinear.VariableLimiter + limiter4(homotopyType=Modelica.Blocks.Types.VariableLimiterHomotopy.Fixed, + ySimplified=0.99) + annotation (Placement(transformation(extent={{180,140},{200,160}}))); + Modelica.Blocks.Math.Feedback internalFeedback4 + annotation (Placement(transformation(extent={{100,140},{120,160}}))); + Modelica.Blocks.Math.Asin asin4 + annotation (Placement(transformation(extent={{240,140},{260,160}}))); + Modelica.Blocks.Sources.Ramp ramp4( + duration=100, + startTime=1, + height=-9.5, + offset=10) + annotation (Placement(transformation(extent={{20,140},{40,160}}))); + Modelica.Blocks.Continuous.FirstOrder firstOrder4( + T=1, + initType=Modelica.Blocks.Types.Init.SteadyState, + k=2/Modelica.Constants.pi) + annotation (Placement(transformation(extent={{280,140},{300,160}}))); + Modelica.Blocks.Math.Feedback feedback4 + annotation (Placement(transformation(extent={{60,140},{80,160}}))); + Modelica.Blocks.Continuous.FirstOrder controllerFeedbackPart5( + T=1, + initType=Modelica.Blocks.Types.Init.SteadyState, + k=-1) annotation (Placement(transformation(extent={{160,-50},{140,-30}}))); + Modelica.Blocks.Nonlinear.VariableLimiter + limiter5(homotopyType=Modelica.Blocks.Types.VariableLimiterHomotopy.Fixed, + ySimplified=-0.99) + annotation (Placement(transformation(extent={{180,-10},{200,10}}))); + Modelica.Blocks.Math.Feedback internalFeedback5 + annotation (Placement(transformation(extent={{100,-10},{120,10}}))); + Modelica.Blocks.Math.Asin asin5 + annotation (Placement(transformation(extent={{240,-10},{260,10}}))); + Modelica.Blocks.Sources.Ramp ramp5( + duration=100, + startTime=1, + height=9.5, + offset=-10) + annotation (Placement(transformation(extent={{20,-10},{40,10}}))); + Modelica.Blocks.Continuous.FirstOrder firstOrder5( + T=1, + initType=Modelica.Blocks.Types.Init.SteadyState, + k=2/Modelica.Constants.pi) + annotation (Placement(transformation(extent={{280,-10},{300,10}}))); + Modelica.Blocks.Math.Feedback feedback5 + annotation (Placement(transformation(extent={{60,-10},{80,10}}))); + Modelica.Blocks.Continuous.FirstOrder controllerFeedbackPart6( + T=1, + initType=Modelica.Blocks.Types.Init.SteadyState, + k=-1) annotation (Placement(transformation(extent={{160,-160},{140,-140}}))); + Modelica.Blocks.Nonlinear.VariableLimiter + limiter6(homotopyType=Modelica.Blocks.Types.VariableLimiterHomotopy.NoHomotopy) + annotation (Placement(transformation(extent={{180,-120},{200,-100}}))); + Modelica.Blocks.Math.Feedback internalFeedback6 + annotation (Placement(transformation(extent={{100,-120},{120,-100}}))); + Modelica.Blocks.Math.Asin asin6 + annotation (Placement(transformation(extent={{240,-120},{260,-100}}))); + Modelica.Blocks.Sources.Ramp ramp6( + duration=100, + startTime=1, + height=-9.5, + offset=10) + annotation (Placement(transformation(extent={{20,-120},{40,-100}}))); + Modelica.Blocks.Continuous.FirstOrder firstOrder6( + T=1, + initType=Modelica.Blocks.Types.Init.SteadyState, + k=2/Modelica.Constants.pi) + annotation (Placement(transformation(extent={{280,-120},{300,-100}}))); + Modelica.Blocks.Math.Feedback feedback6 + annotation (Placement(transformation(extent={{60,-120},{80,-100}}))); + Modelica.Blocks.Sources.RealExpression uMax1(y=0.99) + annotation (Placement(transformation(extent={{146,148},{166,168}}))); + Modelica.Blocks.Sources.RealExpression uMax2(y=0.99) + annotation (Placement(transformation(extent={{148,-2},{168,18}}))); + Modelica.Blocks.Sources.RealExpression uMax3(y=0.99) + annotation (Placement(transformation(extent={{146,-112},{166,-92}}))); + Modelica.Blocks.Sources.RealExpression uMin1(y=-0.99) + annotation (Placement(transformation(extent={{146,130},{166,150}}))); + Modelica.Blocks.Sources.RealExpression uMin2(y=-0.99) + annotation (Placement(transformation(extent={{148,-22},{168,-2}}))); + Modelica.Blocks.Sources.RealExpression uMin3(y=-0.99) + annotation (Placement(transformation(extent={{146,-134},{166,-114}}))); + equation + connect(limiter1.u, internalFeedback1.y) + annotation (Line(points={{-162,150},{-181,150}}, color={0,0,127})); + connect(controllerFeedbackPart1.y, internalFeedback1.u2) annotation (Line( + points={{-161,110},{-190,110},{-190,142}}, color={0,0,127})); + connect(limiter1.y, asin1.u) + annotation (Line(points={{-139,150},{-102,150}}, color={0,0,127})); + connect(asin1.y, firstOrder1.u) + annotation (Line(points={{-79,150},{-62,150}}, color={0,0,127})); + connect(limiter1.y, controllerFeedbackPart1.u) annotation (Line(points={{-139, + 150},{-120,150},{-120,110},{-138,110}}, color={0,0,127})); + connect(feedback1.y, internalFeedback1.u1) + annotation (Line(points={{-221,150},{-198,150}}, color={0,0,127})); + connect(ramp1.y, feedback1.u1) + annotation (Line(points={{-259,150},{-238,150}}, color={0,0,127})); + connect(firstOrder1.y, feedback1.u2) annotation (Line(points={{-39,150},{-20,150}, + {-20,90},{-230,90},{-230,142}}, color={0,0,127})); + connect(limiter2.u, internalFeedback2.y) + annotation (Line(points={{-162,0},{-181,0}}, color={0,0,127})); + connect(controllerFeedbackPart2.y, internalFeedback2.u2) annotation (Line( + points={{-161,-40},{-190,-40},{-190,-8}}, color={0,0,127})); + connect(limiter2.y, asin2.u) + annotation (Line(points={{-139,0},{-102,0}}, color={0,0,127})); + connect(asin2.y, firstOrder2.u) + annotation (Line(points={{-79,0},{-62,0}}, color={0,0,127})); + connect(limiter2.y, controllerFeedbackPart2.u) annotation (Line(points={{-139, + 0},{-120,0},{-120,-40},{-138,-40}}, color={0,0,127})); + connect(feedback2.y, internalFeedback2.u1) + annotation (Line(points={{-221,0},{-198,0}}, color={0,0,127})); + connect(ramp2.y, feedback2.u1) + annotation (Line(points={{-259,0},{-238,0}}, color={0,0,127})); + connect(firstOrder2.y, feedback2.u2) annotation (Line(points={{-39,0},{-16,0}, + {-16,-60},{-230,-60},{-230,-8}}, color={0,0,127})); + connect(limiter3.u, internalFeedback3.y) + annotation (Line(points={{-162,-110},{-181,-110}}, color={0,0,127})); + connect(controllerFeedbackPart3.y, internalFeedback3.u2) annotation (Line( + points={{-161,-150},{-190,-150},{-190,-118}}, color={0,0,127})); + connect(limiter3.y, asin3.u) + annotation (Line(points={{-139,-110},{-102,-110}}, color={0,0,127})); + connect(asin3.y, firstOrder3.u) + annotation (Line(points={{-79,-110},{-62,-110}}, color={0,0,127})); + connect(limiter3.y, controllerFeedbackPart3.u) annotation (Line(points={{-139, + -110},{-120,-110},{-120,-150},{-138,-150}}, color={0,0,127})); + connect(feedback3.y, internalFeedback3.u1) + annotation (Line(points={{-221,-110},{-198,-110}}, color={0,0,127})); + connect(ramp3.y, feedback3.u1) + annotation (Line(points={{-259,-110},{-238,-110}}, color={0,0,127})); + connect(firstOrder3.y, feedback3.u2) annotation (Line(points={{-39,-110},{-20, + -110},{-20,-170},{-230,-170},{-230,-118}}, color={0,0,127})); + connect(limiter4.u, internalFeedback4.y) + annotation (Line(points={{178,150},{119,150}}, color={0,0,127})); + connect(controllerFeedbackPart4.y, internalFeedback4.u2) + annotation (Line(points={{139,110},{110,110},{110,142}}, color={0,0,127})); + connect(limiter4.y, asin4.u) + annotation (Line(points={{201,150},{238,150}}, color={0,0,127})); + connect(asin4.y, firstOrder4.u) + annotation (Line(points={{261,150},{278,150}}, color={0,0,127})); + connect(limiter4.y, controllerFeedbackPart4.u) annotation (Line(points={{201,150}, + {220,150},{220,110},{162,110}}, color={0,0,127})); + connect(feedback4.y, internalFeedback4.u1) + annotation (Line(points={{79,150},{102,150}}, color={0,0,127})); + connect(ramp4.y, feedback4.u1) annotation (Line(points={{41,150},{54,150},{54, + 150},{54,150},{54,150},{62,150}}, color={0,0,127})); + connect(firstOrder4.y, feedback4.u2) annotation (Line(points={{301,150},{320,150}, + {320,90},{70,90},{70,142}}, color={0,0,127})); + connect(limiter5.u, internalFeedback5.y) + annotation (Line(points={{178,0},{119,0}}, color={0,0,127})); + connect(controllerFeedbackPart5.y, internalFeedback5.u2) + annotation (Line(points={{139,-40},{110,-40},{110,-8}}, color={0,0,127})); + connect(limiter5.y, asin5.u) + annotation (Line(points={{201,0},{238,0}}, color={0,0,127})); + connect(asin5.y, firstOrder5.u) + annotation (Line(points={{261,0},{278,0}}, color={0,0,127})); + connect(limiter5.y, controllerFeedbackPart5.u) annotation (Line(points={{201,0}, + {220,0},{220,-40},{162,-40}}, color={0,0,127})); + connect(feedback5.y, internalFeedback5.u1) + annotation (Line(points={{79,0},{102,0}}, color={0,0,127})); + connect(ramp5.y, feedback5.u1) + annotation (Line(points={{41,0},{62,0}}, color={0,0,127})); + connect(firstOrder5.y, feedback5.u2) annotation (Line(points={{301,0},{320,0}, + {320,-60},{70,-60},{70,-8}}, color={0,0,127})); + connect(limiter6.u, internalFeedback6.y) + annotation (Line(points={{178,-110},{119,-110}}, color={0,0,127})); + connect(controllerFeedbackPart6.y, internalFeedback6.u2) annotation (Line( + points={{139,-150},{110,-150},{110,-118}}, color={0,0,127})); + connect(limiter6.y, asin6.u) + annotation (Line(points={{201,-110},{238,-110}}, color={0,0,127})); + connect(asin6.y, firstOrder6.u) + annotation (Line(points={{261,-110},{278,-110}}, color={0,0,127})); + connect(limiter6.y, controllerFeedbackPart6.u) annotation (Line(points={{201,-110}, + {220,-110},{220,-150},{162,-150}}, color={0,0,127})); + connect(feedback6.y, internalFeedback6.u1) + annotation (Line(points={{79,-110},{102,-110}}, color={0,0,127})); + connect(ramp6.y, feedback6.u1) + annotation (Line(points={{41,-110},{62,-110}}, color={0,0,127})); + connect(firstOrder6.y, feedback6.u2) annotation (Line(points={{301,-110},{320, + -110},{320,-170},{70,-170},{70,-118}}, color={0,0,127})); + connect(uMax1.y, limiter4.limit1) + annotation (Line(points={{167,158},{178,158}}, color={0,0,127})); + connect(uMin1.y, limiter4.limit2) annotation (Line(points={{167,140},{172,140}, + {172,142},{178,142}}, color={0,0,127})); + connect(uMax2.y, limiter5.limit1) + annotation (Line(points={{169,8},{178,8}}, color={0,0,127})); + connect(uMin2.y, limiter5.limit2) annotation (Line(points={{169,-12},{172,-12}, + {172,-8},{178,-8}}, color={0,0,127})); + connect(uMax3.y, limiter6.limit1) + annotation (Line(points={{167,-102},{178,-102}}, color={0,0,127})); + connect(uMin3.y, limiter6.limit2) annotation (Line(points={{167,-124},{172,-124}, + {172,-118},{178,-118}}, color={0,0,127})); + annotation ( + Icon(coordinateSystem(preserveAspectRatio=false, + extent={{-100,-100},{100,100}}, + initialScale=0.1)), + Diagram(coordinateSystem(preserveAspectRatio=false, + extent={{-300,-200},{340,200}}, + initialScale=0.1)), + experiment(StopTime=100), + Documentation(info=" +

These test models demonstrate the use of the advanced homotopy options homotopyType +of the Limiter and VariableLimiter blocks.

+

The models represent a basic control system using a PI with anti-windup in three different configurations: +

    +
  1. The loop is initialized in steady-state with the upper saturation active and homotopyType=UMax
  2. +
  3. The loop is initialized in steady-state with the lower saturation active and homotopyType=UMin
  4. +
  5. The loop is initialized in steady-state with the upper saturation active and homotopyType=NoHomotopy
  6. +
+

+

The mustUseHomotopyblock forces the tool to use homotopy-based initialization; in order to do so, +a system with two solutions x = 0 and x = 100 is provided. The start value leads to the convergence to x = 0; only +if homotopy is active, the solution accepted by the assert statement (x = 100) is obtained.

+")); + end LimitersHomotopy; + model KinematicPTP extends Modelica.Icons.Example; Modelica.Blocks.Sources.KinematicPTP kinematicPTP1a( From d27eca1cdad3d7768bcc97aaa041163cb85c6df8 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Tue, 5 Jun 2018 17:08:23 +0200 Subject: [PATCH 04/12] Updated the implementation of LimPID with homotopyType. Marked obsolete parameter in LimPID. Added test cases to ModelicaTest. --- Modelica/Blocks/Continuous.mo | 41 +++++++++---- Modelica/Blocks/Types.mo | 18 ++++-- ModelicaTest/Blocks.mo | 105 ++++++++++++++++++++++++++++++++++ 3 files changed, 148 insertions(+), 16 deletions(-) diff --git a/Modelica/Blocks/Continuous.mo b/Modelica/Blocks/Continuous.mo index 47c28ac063..ff505c5a1f 100644 --- a/Modelica/Blocks/Continuous.mo +++ b/Modelica/Blocks/Continuous.mo @@ -882,6 +882,8 @@ to compute u by an algebraic equation. "P, PI, PD, and PID controller with limited output, anti-windup compensation, setpoint weighting and optional feed-forward" import Modelica.Blocks.Types.InitPID; import Modelica.Blocks.Types.Init; + import Modelica.Blocks.Types.InitPIDHomotopy; + import Modelica.Blocks.Types.LimiterHomotopy; import Modelica.Blocks.Types.SimpleController; extends Modelica.Blocks.Interfaces.SVcontrol; output Real controlError = u_s - u_m @@ -920,9 +922,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", @@ -938,6 +940,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.InitPIDHomotopy homotopyType = Modelica.Blocks.Types.InitPIDHomotopy.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" @@ -984,7 +989,11 @@ to compute u by an algebraic equation. uMax=yMax, uMin=yMin, strict=strict, - limitsAtInit=limitsAtInit) + limitsAtInit=limitsAtInit, + homotopyType = (if homotopyType==InitPIDHomotopy.NoHomotopy then LimiterHomotopy.NoHomotopy + else if homotopyType==InitPIDHomotopy.YMax then LimiterHomotopy.UMax + else if homotopyType==InitPIDHomotopy.YMin then LimiterHomotopy.UMin + else LimiterHomotopy.Linear)) annotation (Placement(transformation(extent={{70,-10},{90,10}}))); protected parameter Boolean with_I = controllerType==SimpleController.PI or @@ -1242,13 +1251,23 @@ to compute u_m by an algebraic equation.

-If parameter limitAtInit = false, 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 -limitAtInit = true. In most cases it is best -to use limitAtInit = false. +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. +

    +
  • homotopyType=Linear (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.
  • +
  • homotopyType=YMax: 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.
  • +
  • homotopyType=YMin: 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.
  • +
  • homotopyType=NoHomotopy: this option does not apply any simplification and keeps the +limiter active throughout the homotopy transformation. Use this if it it 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.
  • +
+

+

+The parameter limitAtInit is obsolete since MSL 3.2.2 and only kept for backwards compatibility.

")); end LimPID; diff --git a/Modelica/Blocks/Types.mo b/Modelica/Blocks/Types.mo index eb73de7316..0099bc2edc 100644 --- a/Modelica/Blocks/Types.mo +++ b/Modelica/Blocks/Types.mo @@ -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 @@ -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 @@ -53,7 +53,7 @@ package Types ")); - type InitPID = enumeration( + type InitPID = enumeration( NoInit "No initialization (start values are used as guess values with fixed=false)", SteadyState @@ -91,7 +91,15 @@ initialization definition. ")); - type SimpleController = enumeration( + type InitPIDHomotopy = enumeration( + NoHomotopy "Full model used for initialization", + Linear "No output limitations during simplified initialization", + YMax "y = yMax during simplified initialization", + YMin "y = yMin during simplified initialization") + "Enumeration defining type of homotopy-based initialization for LimPID model" annotation ( + Evaluate = true); + + type SimpleController = enumeration( P "P controller", PI "PI controller", PD "PD controller", diff --git a/ModelicaTest/Blocks.mo b/ModelicaTest/Blocks.mo index 5d87aa6347..19b09f8593 100644 --- a/ModelicaTest/Blocks.mo +++ b/ModelicaTest/Blocks.mo @@ -1926,4 +1926,109 @@ This shows the improvements in the numerics when balance=true is set. color={0,0,127})); annotation (experiment(StopTime=2)); end MuxDemux; + + model LimPID "Test cases for the LimPID block" + extends Modelica.Icons.Example; + Modelica.Blocks.Continuous.LimPID PID1( + Ti=1, + yMax=1, + yMin=0, + initType=Modelica.Blocks.Types.InitPID.SteadyState, + controllerType=Modelica.Blocks.Types.SimpleController.PI) + annotation (Placement(transformation(extent={{-40,80},{-20,100}}))); + Modelica.Blocks.Sources.Step step1( + height=0.4, + offset=0.5, + startTime=1) + annotation (Placement(transformation(extent={{-80,80},{-60,100}}))); + Modelica.Blocks.Continuous.FirstOrder firstOrder1(T=1, initType=Modelica.Blocks.Types.Init.SteadyState) + annotation (Placement(transformation(extent={{0,80},{20,100}}))); + Modelica.Blocks.Continuous.LimPID PID2( + Ti=1, + yMax=1, + yMin=0, + initType=Modelica.Blocks.Types.InitPID.SteadyState, + controllerType=Modelica.Blocks.Types.SimpleController.PI, + homotopyType=Modelica.Blocks.Types.InitPIDHomotopy.YMax) + annotation (Placement(transformation(extent={{-40,20},{-20,40}}))); + Modelica.Blocks.Sources.Step step2( + startTime=1, + height=-1.5, + offset=2) + annotation (Placement(transformation(extent={{-80,20},{-60,40}}))); + Modelica.Blocks.Continuous.FirstOrder firstOrder2(T=1, initType=Modelica.Blocks.Types.Init.SteadyState) + annotation (Placement(transformation(extent={{0,20},{20,40}}))); + Modelica.Blocks.Continuous.LimPID PID3( + Ti=1, + yMax=1, + yMin=0, + initType=Modelica.Blocks.Types.InitPID.SteadyState, + controllerType=Modelica.Blocks.Types.SimpleController.PI, + homotopyType=Modelica.Blocks.Types.InitPIDHomotopy.YMin) + annotation (Placement(transformation(extent={{-40,-40},{-20,-20}}))); + Modelica.Blocks.Sources.Step step3( + startTime=1, + height=1.5, + offset=-1) + annotation (Placement(transformation(extent={{-80,-40},{-60,-20}}))); + Modelica.Blocks.Continuous.FirstOrder firstOrder3(T=1, initType=Modelica.Blocks.Types.Init.SteadyState) + annotation (Placement(transformation(extent={{0,-40},{20,-20}}))); + Modelica.Blocks.Continuous.LimPID PID4( + Ti=1, + yMax=1, + yMin=0, + initType=Modelica.Blocks.Types.InitPID.SteadyState, + controllerType=Modelica.Blocks.Types.SimpleController.PI, + homotopyType=Modelica.Blocks.Types.InitPIDHomotopy.NoHomotopy) + annotation (Placement(transformation(extent={{-40,-100},{-20,-80}}))); + Modelica.Blocks.Sources.Step step4( + startTime=1, + height=0.4, + offset=0.5) + annotation (Placement(transformation(extent={{-80,-100},{-60,-80}}))); + Modelica.Blocks.Continuous.FirstOrder firstOrder4(T=1, initType=Modelica.Blocks.Types.Init.SteadyState) + annotation (Placement(transformation(extent={{0,-100},{20,-80}}))); + equation + connect(firstOrder1.y, PID1.u_m) annotation (Line(points={{21,90},{40,90},{ + 40,60},{-30,60},{-30,78}}, color={0,0,127})); + connect(PID1.y, firstOrder1.u) + annotation (Line(points={{-19,90},{-2,90}}, color={0,0,127})); + connect(step1.y, PID1.u_s) + annotation (Line(points={{-59,90},{-42,90}}, color={0,0,127})); + connect(firstOrder2.y, PID2.u_m) annotation (Line(points={{21,30},{40,30},{ + 40,0},{-30,0},{-30,18}}, color={0,0,127})); + connect(PID2.y, firstOrder2.u) + annotation (Line(points={{-19,30},{-2,30}}, color={0,0,127})); + connect(step2.y, PID2.u_s) + annotation (Line(points={{-59,30},{-42,30}}, color={0,0,127})); + connect(firstOrder3.y, PID3.u_m) annotation (Line(points={{21,-30},{40,-30}, + {40,-60},{-30,-60},{-30,-42}}, color={0,0,127})); + connect(PID3.y, firstOrder3.u) + annotation (Line(points={{-19,-30},{-2,-30}}, color={0,0,127})); + connect(step3.y, PID3.u_s) + annotation (Line(points={{-59,-30},{-42,-30}}, color={0,0,127})); + connect(firstOrder4.y, PID4.u_m) annotation (Line(points={{21,-90},{40,-90}, + {40,-120},{-30,-120},{-30,-102}}, color={0,0,127})); + connect(PID4.y, firstOrder4.u) + annotation (Line(points={{-19,-90},{-2,-90}}, color={0,0,127})); + connect(step4.y, PID4.u_s) annotation (Line(points={{-59,-90},{-52,-90},{ + -52,-90},{-48,-90},{-48,-90},{-42,-90}}, color={0,0,127})); + annotation (Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100, + -140},{100,120}})), Diagram( + coordinateSystem(preserveAspectRatio=false, extent={{-100,-140},{100, + 120}})), + experiment(StopTime=10), + Documentation(info=" +

This test models demonstrates the use of the homotopyType parameter of the LimPID model in different situations.

+

The first control loop is initialized in steady state with a value of the set point which is compatible with the control variable limitations. +In this case, the default option can be used, which removes the limitations in the simplified model, making it linear and thus easier to solve

+

The second control loop is initialized in steady state with a value of the set point that causes the control output to hit +the upper saturation limit. If this is known a priori, then by setting homotopyType = YMax the simplified model just +assumes the PID output to be yMax, thus making the simplified initialization problem linear.

+

The third control looop is similar to the second, except that the lower saturation limit is now engaged.

+

The fourth loop does not use any simplified model of the limiter during homotopy - this can be used when it is not +known a priori if the controller is saturated or not, and it is important to enforce the PID output limitations throughout +the whole homotopy transformation.

+")); + end LimPID; end Blocks; From adcb754018b40a6cd3ac3ee3813237748342c967 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Wed, 6 Jun 2018 11:51:19 +0200 Subject: [PATCH 05/12] Removed InitPIDHomotopy enumeration; generalized LimiterHomotopy enumeration and also used it in LimPID model. Updated tests and documentation. --- Modelica/Blocks/Continuous.mo | 13 ++++--------- Modelica/Blocks/Nonlinear.mo | 8 ++++---- Modelica/Blocks/Types.mo | 16 ++++------------ ModelicaTest/Blocks.mo | 16 ++++++++-------- 4 files changed, 20 insertions(+), 33 deletions(-) diff --git a/Modelica/Blocks/Continuous.mo b/Modelica/Blocks/Continuous.mo index ff505c5a1f..8b943348cb 100644 --- a/Modelica/Blocks/Continuous.mo +++ b/Modelica/Blocks/Continuous.mo @@ -882,8 +882,6 @@ to compute u by an algebraic equation. "P, PI, PD, and PID controller with limited output, anti-windup compensation, setpoint weighting and optional feed-forward" import Modelica.Blocks.Types.InitPID; import Modelica.Blocks.Types.Init; - import Modelica.Blocks.Types.InitPIDHomotopy; - import Modelica.Blocks.Types.LimiterHomotopy; import Modelica.Blocks.Types.SimpleController; extends Modelica.Blocks.Interfaces.SVcontrol; output Real controlError = u_s - u_m @@ -940,7 +938,7 @@ 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.InitPIDHomotopy homotopyType = Modelica.Blocks.Types.InitPIDHomotopy.Linear + 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); @@ -990,10 +988,7 @@ to compute u by an algebraic equation. uMin=yMin, strict=strict, limitsAtInit=limitsAtInit, - homotopyType = (if homotopyType==InitPIDHomotopy.NoHomotopy then LimiterHomotopy.NoHomotopy - else if homotopyType==InitPIDHomotopy.YMax then LimiterHomotopy.UMax - else if homotopyType==InitPIDHomotopy.YMin then LimiterHomotopy.UMin - else LimiterHomotopy.Linear)) + homotopyType=homotopyType) annotation (Placement(transformation(extent={{70,-10},{90,10}}))); protected parameter Boolean with_I = controllerType==SimpleController.PI or @@ -1256,9 +1251,9 @@ by using a simplified model a the beginning of the solution process. Different o
  • homotopyType=Linear (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.
  • -
  • homotopyType=YMax: if it is known a priori the controller will be stuck at the upper +
  • homotopyType=UpperLimit: 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.
  • -
  • homotopyType=YMin: if it is known a priori the controller will be stuck at the lower +
  • homotopyType=LowerLimit: 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.
  • homotopyType=NoHomotopy: this option does not apply any simplification and keeps the limiter active throughout the homotopy transformation. Use this if it it unknown whether the controller diff --git a/Modelica/Blocks/Nonlinear.mo b/Modelica/Blocks/Nonlinear.mo index 5f62a30331..df26077c80 100644 --- a/Modelica/Blocks/Nonlinear.mo +++ b/Modelica/Blocks/Nonlinear.mo @@ -23,8 +23,8 @@ package Nonlinear 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.UMax then uMax - else if homotopyType == Types.LimiterHomotopy.UMin then uMin + else if homotopyType == Types.LimiterHomotopy.UpperLimit then uMax + else if homotopyType == Types.LimiterHomotopy.LowerLimit then uMin else 0); if strict then if homotopyType == Types.LimiterHomotopy.NoHomotopy then @@ -55,8 +55,8 @@ simplified behaviour if homotopy-based initialization is used:
    • NoHomotopy: the actual expression with limits is used
    • Linear: a linear behaviour y = u is assumed (default option)
    • -
    • UMax: it is assumed that the output is stuck at the upper limit u = uMax
    • -
    • UMin: it is assumed that the output is stuck at the lower limit u = uMin
    • +
    • UpperLimit: it is assumed that the output is stuck at the upper limit u = uMax
    • +
    • LowerLimit: it is assumed that the output is stuck at the lower limit u = uMin

    diff --git a/Modelica/Blocks/Types.mo b/Modelica/Blocks/Types.mo index 0099bc2edc..da33296aba 100644 --- a/Modelica/Blocks/Types.mo +++ b/Modelica/Blocks/Types.mo @@ -91,14 +91,6 @@ initialization definition. ")); - type InitPIDHomotopy = enumeration( - NoHomotopy "Full model used for initialization", - Linear "No output limitations during simplified initialization", - YMax "y = yMax during simplified initialization", - YMin "y = yMin during simplified initialization") - "Enumeration defining type of homotopy-based initialization for LimPID model" annotation ( - Evaluate = true); - type SimpleController = enumeration( P "P controller", PI "PI controller", @@ -130,10 +122,10 @@ initialization definition. "Enumeration defining the regularization around zero"; type LimiterHomotopy = enumeration( - NoHomotopy "Simplified model = actual model", - Linear "Simplified model: y = u", - UMax "Simplified model: y = uMax", - UMin "Simplified model: y = uMin") + 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( diff --git a/ModelicaTest/Blocks.mo b/ModelicaTest/Blocks.mo index 19b09f8593..22fa6470f0 100644 --- a/ModelicaTest/Blocks.mo +++ b/ModelicaTest/Blocks.mo @@ -422,7 +422,7 @@ package Blocks "Test models for Modelica.Blocks" k=-1) annotation (Placement(transformation(extent={{-140,100},{-160,120}}))); Modelica.Blocks.Nonlinear.Limiter limiter1( uMax=0.99, uMin=-0.99, - homotopyType=Modelica.Blocks.Types.LimiterHomotopy.UMax) + homotopyType=Modelica.Blocks.Types.LimiterHomotopy.UpperLimit) annotation (Placement(transformation(extent={{-160,140},{-140,160}}))); Modelica.Blocks.Math.Feedback internalFeedback1 annotation (Placement(transformation(extent={{-200,140},{-180,160}}))); @@ -447,7 +447,7 @@ package Blocks "Test models for Modelica.Blocks" k=-1) annotation (Placement(transformation(extent={{-140,-50},{-160,-30}}))); Modelica.Blocks.Nonlinear.Limiter limiter2( uMax=0.99, uMin=-0.99, - homotopyType=Modelica.Blocks.Types.LimiterHomotopy.UMin) + homotopyType=Modelica.Blocks.Types.LimiterHomotopy.LowerLimit) annotation (Placement(transformation(extent={{-160,-10},{-140,10}}))); Modelica.Blocks.Math.Feedback internalFeedback2 annotation (Placement(transformation(extent={{-200,-10},{-180,10}}))); @@ -699,8 +699,8 @@ package Blocks "Test models for Modelica.Blocks" of the Limiter and VariableLimiter blocks.

    The models represent a basic control system using a PI with anti-windup in three different configurations:

      -
    1. The loop is initialized in steady-state with the upper saturation active and homotopyType=UMax
    2. -
    3. The loop is initialized in steady-state with the lower saturation active and homotopyType=UMin
    4. +
    5. The loop is initialized in steady-state with the upper saturation active and homotopyType=UpperLimit
    6. +
    7. The loop is initialized in steady-state with the lower saturation active and homotopyType=LowerLimit
    8. The loop is initialized in steady-state with the upper saturation active and homotopyType=NoHomotopy

    @@ -1949,7 +1949,7 @@ This shows the improvements in the numerics when balance=true is set. yMin=0, initType=Modelica.Blocks.Types.InitPID.SteadyState, controllerType=Modelica.Blocks.Types.SimpleController.PI, - homotopyType=Modelica.Blocks.Types.InitPIDHomotopy.YMax) + homotopyType=Modelica.Blocks.Types.LimiterHomotopy.UpperLimit) annotation (Placement(transformation(extent={{-40,20},{-20,40}}))); Modelica.Blocks.Sources.Step step2( startTime=1, @@ -1964,7 +1964,7 @@ This shows the improvements in the numerics when balance=true is set. yMin=0, initType=Modelica.Blocks.Types.InitPID.SteadyState, controllerType=Modelica.Blocks.Types.SimpleController.PI, - homotopyType=Modelica.Blocks.Types.InitPIDHomotopy.YMin) + homotopyType=Modelica.Blocks.Types.LimiterHomotopy.LowerLimit) annotation (Placement(transformation(extent={{-40,-40},{-20,-20}}))); Modelica.Blocks.Sources.Step step3( startTime=1, @@ -1979,7 +1979,7 @@ This shows the improvements in the numerics when balance=true is set. yMin=0, initType=Modelica.Blocks.Types.InitPID.SteadyState, controllerType=Modelica.Blocks.Types.SimpleController.PI, - homotopyType=Modelica.Blocks.Types.InitPIDHomotopy.NoHomotopy) + homotopyType=Modelica.Blocks.Types.LimiterHomotopy.NoHomotopy) annotation (Placement(transformation(extent={{-40,-100},{-20,-80}}))); Modelica.Blocks.Sources.Step step4( startTime=1, @@ -2023,7 +2023,7 @@ This shows the improvements in the numerics when balance=true is set.

    The first control loop is initialized in steady state with a value of the set point which is compatible with the control variable limitations. In this case, the default option can be used, which removes the limitations in the simplified model, making it linear and thus easier to solve

    The second control loop is initialized in steady state with a value of the set point that causes the control output to hit -the upper saturation limit. If this is known a priori, then by setting homotopyType = YMax the simplified model just +the upper saturation limit. If this is known a priori, then by setting homotopyType = UpperLimit the simplified model just assumes the PID output to be yMax, thus making the simplified initialization problem linear.

    The third control looop is similar to the second, except that the lower saturation limit is now engaged.

    The fourth loop does not use any simplified model of the limiter during homotopy - this can be used when it is not From b28a2f407d85512b028a13aabbb12d8b92fedfcb Mon Sep 17 00:00:00 2001 From: Thomas Beutlich Date: Tue, 5 Jun 2018 20:53:20 +0200 Subject: [PATCH 06/12] Fix typo --- Modelica/Blocks/Continuous.mo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modelica/Blocks/Continuous.mo b/Modelica/Blocks/Continuous.mo index 8b943348cb..b2bd7b6751 100644 --- a/Modelica/Blocks/Continuous.mo +++ b/Modelica/Blocks/Continuous.mo @@ -1256,7 +1256,7 @@ limit yMax, this option assumes y = yMax as a simplified model.

  • homotopyType=LowerLimit: 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.
  • homotopyType=NoHomotopy: this option does not apply any simplification and keeps the -limiter active throughout the homotopy transformation. Use this if it it unknown whether the controller +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.
From d8654dbacd8841209b27bda5d2e8560dbc4165a9 Mon Sep 17 00:00:00 2001 From: Thomas Beutlich Date: Wed, 6 Jun 2018 13:31:09 +0200 Subject: [PATCH 07/12] Always group parameter homotopyType to Initialization group of dialog --- Modelica/Blocks/Continuous.mo | 13 ++++++------- Modelica/Blocks/Nonlinear.mo | 4 ++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Modelica/Blocks/Continuous.mo b/Modelica/Blocks/Continuous.mo index b2bd7b6751..d6d6a9eaa2 100644 --- a/Modelica/Blocks/Continuous.mo +++ b/Modelica/Blocks/Continuous.mo @@ -918,11 +918,7 @@ to compute u by an algebraic equation. annotation(Dialog(enable=withFeedForward)); parameter .Modelica.Blocks.Types.InitPID initType= .Modelica.Blocks.Types.InitPID.DoNotUse_InitialIntegratorState "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 - "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)); + annotation(Evaluate=true, Dialog(group="Initialization")); parameter Real xi_start=0 "Initial or guess value for integrator output (= integrator state)" annotation (Dialog(group="Initialization", @@ -936,11 +932,14 @@ to compute u by an algebraic equation. parameter Real y_start=0 "Initial value of output" annotation(Dialog(enable=initType == .Modelica.Blocks.Types.InitPID.InitialOutput, group= "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")); + parameter Boolean strict=false "= true, if strict limits with noEvent(..)" + annotation (Evaluate=true, choices(checkBox=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)); constant Modelica.SIunits.Time unitTime=1 annotation (HideResult=true); Modelica.Blocks.Interfaces.RealInput u_ff if withFeedForward "Optional connector of feed-forward input signal" diff --git a/Modelica/Blocks/Nonlinear.mo b/Modelica/Blocks/Nonlinear.mo index df26077c80..933aae493e 100644 --- a/Modelica/Blocks/Nonlinear.mo +++ b/Modelica/Blocks/Nonlinear.mo @@ -11,7 +11,7 @@ package Nonlinear "= 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")); + 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)); @@ -133,7 +133,7 @@ a lot by removing one strong nonlinearity from the initialization problem. 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")); + annotation (Evaluate=true, Dialog(group="Initialization")); parameter Real ySimplified = 0 "Fixed value of output in simplified model" annotation (Dialog(tab="Advanced")); parameter Boolean limitsAtInit=true From ef3225baa7d4df7f61a0387784600c244718397a Mon Sep 17 00:00:00 2001 From: Thomas Beutlich Date: Mon, 11 Jun 2018 21:16:25 +0200 Subject: [PATCH 08/12] Enable/disable parameter ySimplified --- Modelica/Blocks/Nonlinear.mo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modelica/Blocks/Nonlinear.mo b/Modelica/Blocks/Nonlinear.mo index 933aae493e..89c84abdad 100644 --- a/Modelica/Blocks/Nonlinear.mo +++ b/Modelica/Blocks/Nonlinear.mo @@ -135,7 +135,7 @@ a lot by removing one strong nonlinearity from the initialization problem. parameter Types.VariableLimiterHomotopy homotopyType = Modelica.Blocks.Types.VariableLimiterHomotopy.Linear "Simplified model for homotopy-based initialization" annotation (Evaluate=true, Dialog(group="Initialization")); parameter Real ySimplified = 0 "Fixed value of output in simplified model" - annotation (Dialog(tab="Advanced")); + annotation (Dialog(tab="Advanced", enable=homotopyType == Modelica.Blocks.Types.VariableLimiterHomotopy.Fixed)); 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)); From d3a7c13d04c9e51ea6b10c64b5fced17bf4b9261 Mon Sep 17 00:00:00 2001 From: Thomas Beutlich Date: Mon, 11 Jun 2018 21:19:17 +0200 Subject: [PATCH 09/12] Consistently have strict parameter in Advanced tab --- Modelica/Blocks/Nonlinear.mo | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Modelica/Blocks/Nonlinear.mo b/Modelica/Blocks/Nonlinear.mo index 89c84abdad..db9a3f9b4d 100644 --- a/Modelica/Blocks/Nonlinear.mo +++ b/Modelica/Blocks/Nonlinear.mo @@ -7,13 +7,12 @@ package Nonlinear block Limiter "Limit the range of a signal" parameter Real uMax(start=1) "Upper limits of input signals"; parameter Real uMin= -uMax "Lower limits of input signals"; - parameter Boolean strict=false - "= true, if strict limits with noEvent(..)" + 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(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)" + "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 @@ -131,7 +130,7 @@ a lot by removing one strong nonlinearity from the initialization problem. block VariableLimiter "Limit the range of a signal with variable limits" extends Interfaces.SISO; parameter Boolean strict=false "= true, if strict limits with noEvent(..)" - annotation (Evaluate=true, choices(checkBox=true)); + annotation (Evaluate=true, choices(checkBox=true), Dialog(tab="Advanced")); parameter Types.VariableLimiterHomotopy homotopyType = Modelica.Blocks.Types.VariableLimiterHomotopy.Linear "Simplified model for homotopy-based initialization" annotation (Evaluate=true, Dialog(group="Initialization")); parameter Real ySimplified = 0 "Fixed value of output in simplified model" From 9d7df7b4fe18e5141bcb6d7809de9a09a8f40485 Mon Sep 17 00:00:00 2001 From: Thomas Beutlich Date: Mon, 11 Jun 2018 22:48:59 +0200 Subject: [PATCH 10/12] Add homotopy-based initialization for IdealizedOpAmpLimted --- Modelica/Electrical/Analog/Ideal.mo | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/Modelica/Electrical/Analog/Ideal.mo b/Modelica/Electrical/Analog/Ideal.mo index a94fa52102..f8fee1beba 100644 --- a/Modelica/Electrical/Analog/Ideal.mo +++ b/Modelica/Electrical/Analog/Ideal.mo @@ -675,6 +675,10 @@ If the input voltage is vin larger than 0, the output voltage is out.v = VMax. annotation (Dialog(enable=not useSupply)); parameter SI.Voltage Vns=-15 "Negative supply voltage" annotation (Dialog(enable=not useSupply)); + 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")); SI.Voltage vps "Positive supply voltage"; SI.Voltage vns "Negative supply voltage"; SI.Voltage v_in=in_p.v - in_n.v "Input voltage difference"; @@ -700,6 +704,8 @@ If the input voltage is vin larger than 0, the output voltage is out.v = VMax. Modelica.Electrical.Analog.Interfaces.NegativePin s_n(final i=-i_s, final v= vns) if useSupply "Optional negative supply pin" annotation (Placement( transformation(extent={{-10,-110},{10,-90}}))); + protected + SI.Voltage simplifiedExpr "Simplified expression for homotopy-based initialization"; equation if not useSupply then vps = Vps; @@ -707,7 +713,25 @@ If the input voltage is vin larger than 0, the output voltage is out.v = VMax. end if; in_p.i = 0; in_n.i = 0; - v_out = homotopy(actual = smooth(0, if V0*v_invps then vps else V0*v_in), simplified=V0*v_in); + simplifiedExpr = (if homotopyType == Modelica.Blocks.Types.LimiterHomotopy.Linear then V0*v_in + else if homotopyType == Modelica.Blocks.Types.LimiterHomotopy.UpperLimit then vps + else if homotopyType == Modelica.Blocks.Types.LimiterHomotopy.LowerLimit then vns + else 0); + if strict then + if homotopyType == Modelica.Blocks.Types.LimiterHomotopy.NoHomotopy then + v_out = smooth(0, noEvent(if V0*v_in>vps then vps else if V0*v_invps then vps else if V0*v_invps then vps else if V0*v_invps then vps else if V0*v_in Date: Mon, 11 Jun 2018 22:49:14 +0200 Subject: [PATCH 11/12] Update examples utilizing IdealizedOpAmpLimted --- Modelica/Electrical/Analog/Examples/OpAmps.mo | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/Modelica/Electrical/Analog/Examples/OpAmps.mo b/Modelica/Electrical/Analog/Examples/OpAmps.mo index c09f6f83e6..4ac2823a15 100644 --- a/Modelica/Electrical/Analog/Examples/OpAmps.mo +++ b/Modelica/Electrical/Analog/Examples/OpAmps.mo @@ -566,7 +566,8 @@ package OpAmps "Examples with operational amplifiers" Modelica.Electrical.Analog.Ideal.IdealizedOpAmpLimted opAmp( Vps=Vps, Vns=Vns, - out(i(start=0))) + out(i(start=0)), + homotopyType=Modelica.Blocks.Types.LimiterHomotopy.LowerLimit) annotation (Placement(transformation(extent={{0,-10},{20,10}}))); Modelica.Electrical.Analog.Basic.Ground ground annotation (Placement(transformation(extent={{-20,-100},{0,-80}}))); @@ -639,7 +640,8 @@ package OpAmps "Examples with operational amplifiers" Modelica.Electrical.Analog.Ideal.IdealizedOpAmpLimted opAmp( Vps=Vps, Vns=Vns, - out(i(start=0))) + out(i(start=0)), + homotopyType=Modelica.Blocks.Types.LimiterHomotopy.UpperLimit) annotation (Placement(transformation(extent={{0,10},{20,-10}}))); Modelica.Electrical.Analog.Basic.Ground ground annotation (Placement(transformation(extent={{-20,-100},{0,-80}}))); @@ -707,8 +709,10 @@ package OpAmps "Examples with operational amplifiers" parameter SI.Resistance R2=1000 "Resistance 2 for adjusting the Schmitt trigger voltage level"; parameter SI.Resistance R=1000 "Arbitrary resistance"; parameter SI.Capacitance C=1/f/(2*R*log(1 + 2*R1/R2)) "Calculated capacitance to reach the desired frequency f"; - Modelica.Electrical.Analog.Ideal.IdealizedOpAmpLimted opAmp(Vps=Vps, Vns= - Vns) annotation (Placement(transformation(extent={{0,-10},{20,10}}))); + Modelica.Electrical.Analog.Ideal.IdealizedOpAmpLimted opAmp( + Vps=Vps, + Vns=Vns, + strict=true) annotation (Placement(transformation(extent={{0,-10},{20,10}}))); Modelica.Electrical.Analog.Basic.Ground ground annotation (Placement(transformation(extent={{-20,-80},{0,-60}}))); Modelica.Electrical.Analog.Sensors.VoltageSensor vOut annotation (Placement( @@ -776,8 +780,10 @@ package OpAmps "Examples with operational amplifiers" parameter SI.Frequency f=10 "Desired frequency"; parameter SI.Resistance R=1000 "Arbitrary resistance of integrator part"; parameter SI.Capacitance C=Vps/VAmp/(4*f*R) "Calculated capacitance of integrator part to reach f"; - Modelica.Electrical.Analog.Ideal.IdealizedOpAmpLimted opAmp1(Vps=Vps, Vns= - Vns) + Modelica.Electrical.Analog.Ideal.IdealizedOpAmpLimted opAmp1( + Vps=Vps, + Vns=Vns, + homotopyType=Modelica.Blocks.Types.LimiterHomotopy.UpperLimit) annotation (Placement(transformation(extent={{-60,10},{-40,-10}}))); Modelica.Electrical.Analog.Basic.Resistor r2(R=R2, i(start=Vps/R2)) annotation (Placement(transformation( From a4083f2be666494fb0e3c5b4a6fb58bb730a4007 Mon Sep 17 00:00:00 2001 From: Thomas Beutlich Date: Wed, 13 Jun 2018 13:45:55 +0200 Subject: [PATCH 12/12] Set IdealizedOpAmpLimted.strict to true as default * Restore MSL 3.2.2 behaviour, i.e., without events * Force events for SignalGenerator example model --- Modelica/Electrical/Analog/Examples/OpAmps.mo | 7 ++++--- Modelica/Electrical/Analog/Ideal.mo | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Modelica/Electrical/Analog/Examples/OpAmps.mo b/Modelica/Electrical/Analog/Examples/OpAmps.mo index 4ac2823a15..98f415c024 100644 --- a/Modelica/Electrical/Analog/Examples/OpAmps.mo +++ b/Modelica/Electrical/Analog/Examples/OpAmps.mo @@ -711,8 +711,7 @@ package OpAmps "Examples with operational amplifiers" parameter SI.Capacitance C=1/f/(2*R*log(1 + 2*R1/R2)) "Calculated capacitance to reach the desired frequency f"; Modelica.Electrical.Analog.Ideal.IdealizedOpAmpLimted opAmp( Vps=Vps, - Vns=Vns, - strict=true) annotation (Placement(transformation(extent={{0,-10},{20,10}}))); + Vns=Vns) annotation (Placement(transformation(extent={{0,-10},{20,10}}))); Modelica.Electrical.Analog.Basic.Ground ground annotation (Placement(transformation(extent={{-20,-80},{0,-60}}))); Modelica.Electrical.Analog.Sensors.VoltageSensor vOut annotation (Placement( @@ -783,6 +782,7 @@ package OpAmps "Examples with operational amplifiers" Modelica.Electrical.Analog.Ideal.IdealizedOpAmpLimted opAmp1( Vps=Vps, Vns=Vns, + strict=false, homotopyType=Modelica.Blocks.Types.LimiterHomotopy.UpperLimit) annotation (Placement(transformation(extent={{-60,10},{-40,-10}}))); Modelica.Electrical.Analog.Basic.Resistor r2(R=R2, i(start=Vps/R2)) @@ -799,7 +799,8 @@ package OpAmps "Examples with operational amplifiers" Modelica.Electrical.Analog.Ideal.IdealizedOpAmpLimted opAmp2( Vps=Vps, Vns=Vns, - v_in(start=0)) + v_in(start=0), + strict=false) annotation (Placement(transformation(extent={{30,-10},{50,10}}))); Modelica.Electrical.Analog.Basic.Capacitor c(C=C, v(fixed=true, start=0)) annotation (Placement(transformation(extent={{50,10},{30,30}}))); diff --git a/Modelica/Electrical/Analog/Ideal.mo b/Modelica/Electrical/Analog/Ideal.mo index f8fee1beba..d6441db1bc 100644 --- a/Modelica/Electrical/Analog/Ideal.mo +++ b/Modelica/Electrical/Analog/Ideal.mo @@ -675,7 +675,7 @@ If the input voltage is vin larger than 0, the output voltage is out.v = VMax. annotation (Dialog(enable=not useSupply)); parameter SI.Voltage Vns=-15 "Negative supply voltage" annotation (Dialog(enable=not useSupply)); - parameter Boolean strict=false "= true, if strict limits with noEvent(..)" + parameter Boolean strict=true "= 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"));