Skip to content

Commit

Permalink
#3168 LimiterAtCurrentValueWithLag created, base block shared with Li…
Browse files Browse the repository at this point in the history
…miterWithLag

Signed-off-by: GUICHARD Erwan Ext <erwan.guichard@rte-france.com>
  • Loading branch information
ErwanGuichard49 committed Mar 18, 2024
1 parent 68a2fde commit 6c3f17c
Show file tree
Hide file tree
Showing 10 changed files with 249 additions and 148 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
within Dynawo.NonElectrical.Blocks.NonLinear.BaseClasses;

/*
* Copyright (c) 2024, RTE (http://www.rte-france.com)
* See AUTHORS.txt
* All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at http://mozilla.org/MPL/2.0/.
* SPDX-License-Identifier: MPL-2.0
*
* This file is part of Dynawo, an hybrid C++/Modelica open source suite
* of simulation tools for power systems.
*/

block BaseLimiterWithLag "Base block of limiter that enforces saturations only after they were violated without interruption during a given amount of time"
import Modelica.Constants;
import Dynawo.NonElectrical.Logs.Timeline;
import Dynawo.NonElectrical.Logs.TimelineKeys;

extends Modelica.Blocks.Icons.Block;

parameter Types.Time LagMax "Time lag before taking action when going above UMax";
parameter Types.Time LagMin "Time lag before taking action when going below UMin";
parameter Real UMax "Maximum allowed u";
parameter Real UMin "Minimum allowed u";

Modelica.Blocks.Interfaces.RealInput u(start = u0) "Input signal connector" annotation(
Placement(transformation(extent={{-140,-20},{-100,20}})));
Modelica.Blocks.Interfaces.RealOutput y(start = y0) "Output signal connector" annotation(
Placement(transformation(extent={{100,-10},{120,10}})));

discrete Types.Time tUMaxReached(start = tUMaxReached0) "Last time when u went above UMax";
discrete Types.Time tUMinReached(start = tUMinReached0) "Last time when u went below UMin";

Boolean initSaturatedMax(start = (tUMaxReached0 == -Constants.inf)) "If true, simulation starts in max saturated mode";
Boolean initSaturatedMin(start = (tUMinReached0 == -Constants.inf)) "If true, simulation starts in min saturated mode";

parameter Types.Time tUMaxReached0 "Initial time when u went above UMax";
parameter Types.Time tUMinReached0 "Initial time when u went below UMin";
parameter Real u0 "Initial input";
parameter Real y0 "Initial output";

equation
when u > UMax then
tUMaxReached = if initSaturatedMax then -Constants.inf else time;
initSaturatedMax = false;
elsewhen u <= UMax then
tUMaxReached = Constants.inf;
initSaturatedMax = false;
end when;

when u < UMin then
tUMinReached = if initSaturatedMin then -Constants.inf else time;
initSaturatedMin = false;
elsewhen u >= UMin then
tUMinReached = Constants.inf;
initSaturatedMin = false;
end when;

annotation(
preferredView = "text",
Icon(coordinateSystem(
preserveAspectRatio=true,
extent={{-100,-100},{100,100}}), graphics={
Line(points={{-80,-56},{-60,-56},{-60,-22},{38,-22},{38,-56},{66,-56}},color={0,0,192}),
Line(points={{-80,32},{18,32},{18,66},{38,66},{38,32},{66,32}},color={0,192,0}),
Line(points={{0,-90},{0,68}}, color={192,192,192}),
Polygon(
points={{0,90},{-8,68},{8,68},{0,90}},
lineColor={192,192,192},
fillColor={192,192,192},
fillPattern=FillPattern.Solid),
Line(points={{-90,0},{68,0}}, color={192,192,192}),
Polygon(
points={{90,0},{68,-8},{68,8},{90,0}},
lineColor={192,192,192},
fillColor={192,192,192},
fillPattern=FillPattern.Solid),
Line(points={{-80,-70},{-50,-70},{50,70},{80,70}}),
Text(
extent={{-150,-150},{150,-110}},
lineColor={0,0,0},
textString="uMax=%uMax"),
Text(
extent={{-150,150},{150,110}},
textString="%name",
lineColor={0,0,255}),
Line(
visible=strict,
points={{50,70},{80,70}},
color={255,0,0}),
Line(
visible=strict,
points={{-80,-70},{-50,-70}},
color={255,0,0})}),
Diagram(coordinateSystem(
preserveAspectRatio=true,
extent={{-100,-100},{100,100}}), graphics={
Line(points={{0,-60},{0,50}}, color={192,192,192}),
Polygon(
points={{0,60},{-5,50},{5,50},{0,60}},
lineColor={192,192,192},
fillColor={192,192,192},
fillPattern=FillPattern.Solid),
Line(points={{-60,0},{50,0}}, color={192,192,192}),
Polygon(
points={{60,0},{50,-5},{50,5},{60,0}},
lineColor={192,192,192},
fillColor={192,192,192},
fillPattern=FillPattern.Solid),
Line(points={{-50,-40},{-30,-40},{30,40},{50,40}}),
Text(
extent={{46,-6},{68,-18}},
lineColor={128,128,128},
textString="u"),
Text(
extent={{-30,70},{-5,50}},
lineColor={128,128,128},
textString="y"),
Text(
extent={{58,-54},{28,-42}},
lineColor={128,128,128},
textString="%delayTimes s"),
Text(
extent={{-58,-54},{-28,-42}},
lineColor={128,128,128},
textString="UMin"),
Text(
extent={{26,40},{66,56}},
lineColor={128,128,128},
textString="UMax")}),
Documentation(info = "<html><head></head><body>There is no lag when switching from saturated to non-saturated mode.<br><br>The Boolean variable&nbsp;<i>initSaturatedMax</i>&nbsp;prevents&nbsp;<i>tUMaxReached</i>&nbsp;from being reset at initial time if the simulation starts in saturated mode. Thus, <i>tUMaxReached</i> is equal to minus infinity i.e. it is assumed that <b>UMax</b> was crossed long before the simulation.<br><br>The Boolean variable initSaturatedMin performs the same function with respect to <i>tUMinReached </i>and <b>UMin</b>.</body></html>"));
end BaseLimiterWithLag;
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
within Dynawo.NonElectrical.Blocks.NonLinear.BaseClasses;

/*
* Copyright (c) 2024, RTE (http://www.rte-france.com)
* See AUTHORS.txt
* All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at http://mozilla.org/MPL/2.0/.
* SPDX-License-Identifier: MPL-2.0
*
* This file is part of Dynawo, an hybrid C++/Modelica open source suite
* of simulation tools for power systems.
*/

model BaseLimiterWithLag_INIT "Base initialization model for LimiterWithLag and LimiterAtCurrentValueWithLag"
import Modelica.Constants;

extends AdditionalIcons.Init;

parameter Real UMax "Maximum allowed u";
parameter Real UMin "Minimum allowed u";

discrete Types.Time tUMaxReached0(start = Constants.inf) "Initial time when u went above UMax";
discrete Types.Time tUMinReached0(start = Constants.inf) "Initial time when u went below UMin";

Real u0 "Initial input";
Real y0 "Initial output, =y0LF if compliant with saturations";
Real y0LF "Initial y from loadflow";

equation
u0 = y0LF;

when u0 > UMax then
tUMaxReached0 = -Constants.inf; // Init in steadystate, UMax has been reached for a long time
elsewhen u0 <= UMax then
tUMaxReached0 = Constants.inf;
end when;

when u0 < UMin then
tUMinReached0 = -Constants.inf;
elsewhen u0 >= UMin then
tUMinReached0 = Constants.inf;
end when;

annotation(
preferredView = "text",
Documentation(info = "<html><head></head><body>The input of this model is <i>y0LF</i>. This value will initialize the limiter input variable, but since it could be out the saturation bounds, the initial value kept for y is <i>y0</i>.<div><br></div><div>If <i>u0</i> exceeds <b>UMax</b>, it is assumed that <b>UMax</b> has been crossed long before the simulation, hence <i>tUMaxReached0</i> is equal to minus infinity.<br><br>The same assumption is made regarding <b>UMin</b> and <i>tUMinReached0</i>.</div></body></html>"));
end BaseLimiterWithLag_INIT;
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
set(MODEL_FILES
package.mo
package.order
BaseLimiterWithLag.mo
BaseLimiterWithLag_INIT.mo
BasePulse.mo
BaseRSFlipFlop.mo
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
BaseLimiterWithLag
BaseLimiterWithLag_INIT
BasePulse
BaseRSFlipFlop
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ set(MODEL_FILES
LimitedFirstOrder.mo
LimitedIntegrator.mo
LimitedLeadLag.mo
LimiterAtCurrentValueWithLag.mo
LimiterAtCurrentValueWithLag_INIT.mo
LimiterWithLag.mo
LimiterWithLag_INIT.mo
LimRateLimFirstOrder.mo
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
within Dynawo.NonElectrical.Blocks.NonLinear;

/*
* Copyright (c) 2024, RTE (http://www.rte-france.com)
* See AUTHORS.txt
* All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at http://mozilla.org/MPL/2.0/.
* SPDX-License-Identifier: MPL-2.0
*
* This file is part of Dynawo, an hybrid C++/Modelica open source suite
* of simulation tools for power systems.
*/

block LimiterAtCurrentValueWithLag "Limiter that enforces saturations only after they were violated without interruption during a given amount of time, the lower saturation value being its current value"
extends Dynawo.NonElectrical.Blocks.NonLinear.BaseClasses.BaseLimiterWithLag;

equation
y = if (time - tUMinReached >= LagMin) then pre(y) elseif (time - tUMaxReached >= LagMax) then UMax else u;

annotation(preferredView = "text");
end LimiterAtCurrentValueWithLag;
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
within Dynawo.NonElectrical.Blocks.NonLinear;

/*
* Copyright (c) 2024, RTE (http://www.rte-france.com)
* See AUTHORS.txt
* All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at http://mozilla.org/MPL/2.0/.
* SPDX-License-Identifier: MPL-2.0
*
* This file is part of Dynawo, an hybrid C++/Modelica open source suite
* of simulation tools for power systems.
*/

model LimiterAtCurrentValueWithLag_INIT "Initialization model of LimiterAtCurrentValueWithLag"
extends Dynawo.NonElectrical.Blocks.NonLinear.BaseClasses.BaseLimiterWithLag_INIT;

equation
y0 = if u0 > UMax then UMax else u0;

annotation(
preferredView = "text",
Documentation(info = "<html><head></head><body>In this model, <i>y0</i> complies only with <b>UMax</b>.</body></html>"));
end LimiterAtCurrentValueWithLag_INIT;
Original file line number Diff line number Diff line change
Expand Up @@ -12,123 +12,11 @@ within Dynawo.NonElectrical.Blocks.NonLinear;
* This file is part of Dynawo, an hybrid C++/Modelica open source time domain simulation tool for power systems.
*/

block LimiterWithLag "Limiter that enforces saturations only after they were violated without interruption during a certain amount of time. No lag when switching from saturated to non saturated mode though"
import Modelica.Constants;
import Dynawo.NonElectrical.Logs.Timeline;
import Dynawo.NonElectrical.Logs.TimelineKeys;

extends Modelica.Blocks.Icons.Block;

parameter Real UMin "Minimum allowed u";
parameter Real UMax "Maximum allowed u";
parameter Types.Time LagMin "Time lag before taking action when going below uMin";
parameter Types.Time LagMax "Time lag before taking action when going above uMax";

Modelica.Blocks.Interfaces.RealInput u(start = u0) "Input signal connector" annotation(Placement(
transformation(extent={{-140,-20},{-100,20}})));
Modelica.Blocks.Interfaces.RealOutput y(start = y0) "Output signal connector" annotation(Placement(
transformation(extent={{100,-10},{120,10}})));

discrete Types.Time tUMinReached(start = tUMinReached0) "Last time when u went below EfdMin";
discrete Types.Time tUMaxReached(start = tUMaxReached0) "Last time when u went above EfdMax";

parameter Real u0 "Initial input";
parameter Real y0 "Initial output";
parameter Types.Time tUMinReached0 "Initial time when u went below UMin";
parameter Types.Time tUMaxReached0 "Initial time when u went above UMax";

Boolean initSaturatedMin(start = (tUMinReached0 == - Constants.inf) ) "Whether we start in min saturated mode. Boolean used to prevent the model from resetting tUMinReached when in saturated mode at the beginning of the simulation";
Boolean initSaturatedMax(start = (tUMaxReached0 == - Constants.inf) ) "Whether we start in max saturated mode. Boolean used to prevent the model from resetting tUMaxReached when in saturated mode at the beginning of the simulation";
block LimiterWithLag "Limiter that enforces saturations only after they were violated without interruption during a given amount of time"
extends Dynawo.NonElectrical.Blocks.NonLinear.BaseClasses.BaseLimiterWithLag;

equation
y = if (time - tUMinReached >= LagMin) then UMin else if (time - tUMaxReached >= LagMax) then UMax else u;

// Assessing that u is within limits
when (u < UMin) then
tUMinReached = if initSaturatedMin then - Constants.inf else time; // If we start in saturated state, tUMinReached should not be reset to time at time = 0 because we assume that u crossed UMin a long time ago
initSaturatedMin = false; // For the next when triggerings, back to classic behaviour
elsewhen (u >= UMin) then
tUMinReached = Constants.inf;
initSaturatedMin = false;
end when;

when (u > UMax) then
tUMaxReached = if initSaturatedMax then - Constants.inf else time; // If we start in saturated state, tUMaxReached should not be reset to time at time = 0 because we assume that u crossed UMax a long time ago
initSaturatedMax = false; // For the next when triggerings, back to classic behaviour
elsewhen (u <= UMax) then
tUMaxReached = Constants.inf;
initSaturatedMax = false;
end when;
y = if (time - tUMinReached >= LagMin) then UMin elseif (time - tUMaxReached >= LagMax) then UMax else u;

annotation(preferredView = "text",
Icon(coordinateSystem(
preserveAspectRatio=true,
extent={{-100,-100},{100,100}}), graphics={
Line(points={{-80,-56},{-60,-56},{-60,-22},{38,-22},{38,-56},{66,-56}},color={0,0,192}),
Line(points={{-80,32},{18,32},{18,66},{38,66},{38,32},{66,32}},color={0,192,0}),
Line(points={{0,-90},{0,68}}, color={192,192,192}),
Polygon(
points={{0,90},{-8,68},{8,68},{0,90}},
lineColor={192,192,192},
fillColor={192,192,192},
fillPattern=FillPattern.Solid),
Line(points={{-90,0},{68,0}}, color={192,192,192}),
Polygon(
points={{90,0},{68,-8},{68,8},{90,0}},
lineColor={192,192,192},
fillColor={192,192,192},
fillPattern=FillPattern.Solid),
Line(points={{-80,-70},{-50,-70},{50,70},{80,70}}),
Text(
extent={{-150,-150},{150,-110}},
lineColor={0,0,0},
textString="uMax=%uMax"),
Text(
extent={{-150,150},{150,110}},
textString="%name",
lineColor={0,0,255}),
Line(
visible=strict,
points={{50,70},{80,70}},
color={255,0,0}),
Line(
visible=strict,
points={{-80,-70},{-50,-70}},
color={255,0,0})}),
Diagram(coordinateSystem(
preserveAspectRatio=true,
extent={{-100,-100},{100,100}}), graphics={
Line(points={{0,-60},{0,50}}, color={192,192,192}),
Polygon(
points={{0,60},{-5,50},{5,50},{0,60}},
lineColor={192,192,192},
fillColor={192,192,192},
fillPattern=FillPattern.Solid),
Line(points={{-60,0},{50,0}}, color={192,192,192}),
Polygon(
points={{60,0},{50,-5},{50,5},{60,0}},
lineColor={192,192,192},
fillColor={192,192,192},
fillPattern=FillPattern.Solid),
Line(points={{-50,-40},{-30,-40},{30,40},{50,40}}),
Text(
extent={{46,-6},{68,-18}},
lineColor={128,128,128},
textString="u"),
Text(
extent={{-30,70},{-5,50}},
lineColor={128,128,128},
textString="y"),
Text(
extent={{58,-54},{28,-42}},
lineColor={128,128,128},
textString="%delayTimes s"),
Text(
extent={{-58,-54},{-28,-42}},
lineColor={128,128,128},
textString="uMin"),
Text(
extent={{26,40},{66,56}},
lineColor={128,128,128},
textString="uMax")}));
annotation(preferredView = "text");
end LimiterWithLag;

0 comments on commit 6c3f17c

Please sign in to comment.