From 1a1247273af9d147b9b2624a2732f966656e415b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bjarne=20B=C3=B8rresen?= Date: Wed, 11 Feb 2026 09:35:00 +0100 Subject: [PATCH 1/9] Added partial base class TorqueEquation for use with turbine models --- OpenHPL/ElectroMech/BaseClasses/package.order | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenHPL/ElectroMech/BaseClasses/package.order b/OpenHPL/ElectroMech/BaseClasses/package.order index ba4a2d0f..49c67585 100644 --- a/OpenHPL/ElectroMech/BaseClasses/package.order +++ b/OpenHPL/ElectroMech/BaseClasses/package.order @@ -1,2 +1,3 @@ Power2Torque BaseValve +TorqueEquation From 8795bfcb4fe0a7fd834aebd11b95ec0ddb3d566b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bjarne=20B=C3=B8rresen?= Date: Wed, 11 Feb 2026 12:28:06 +0100 Subject: [PATCH 2/9] Merged feat/torqueEquation into master --- .../ElectroMech/BaseClasses/TorqueEquation.mo | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo diff --git a/OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo b/OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo new file mode 100644 index 00000000..7ee1307d --- /dev/null +++ b/OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo @@ -0,0 +1,110 @@ +within OpenHPL.ElectroMech.BaseClasses; + +partial model TorqueEquation + outer OpenHPL.Data data "Using standard class with global parameters"; + // + parameter Boolean useH = false "If checked, calculate the inertia from a given H value" annotation( + Dialog(group = "Mechanical"), + choices(checkBox = true)); + parameter SI.Power Pmax = 100e6 "Maximum rated power (for torque limiting and H calculation)" annotation( + Dialog(group = "Mechanical")); + parameter SI.Time H = 2.75 "Inertia constant H, typical 2s (high-head hydro) to 6s (gas or low-head hydro) production units" annotation( + Dialog(group = "Mechanical", enable = useH)); + parameter SI.MomentOfInertia J = 2e5 "Moment of inertia of the unit (GD2/4)" annotation( + Dialog(group = "Mechanical", enable = not useH)); + parameter Integer p(min = 2) = 12 "Number of poles for mechanical speed calculation (Not pole pairs!)" annotation( + Dialog(group = "Mechanical"), + choices(choice = 2 "2,[3000|3600] rpm", choice = 4 "4,[1500|1800] rpm", choice = 6 "6,[1000|1200] rpm", choice = 8 "8,[750|900] rpm", choice = 10 "10,[600|720] rpm", choice = 12 "12,[500|600] rpm", choice = 14 "14,[429|514] rpm", choice = 16 "16,[375|450] rpm", choice = 18 "18,[333|400] rpm", choice = 20 "20,[300|360] rpm", choice = 22 "22,[273|327] rpm", choice = 24 "24,[250|300] rpm", choice = 26 "26,[231|277] rpm", choice = 28 "28,[214|257] rpm", choice = 30 "30,[200|240] rpm", choice = 28 "32,[187.5|225] rpm")); + parameter SI.Power Ploss = 0 "Friction losses of the unit at nominal speed" annotation( + Dialog(group = "Mechanical")); + parameter SI.PerUnit f_0 = 1 "Initial speed of the unit" annotation( + Dialog(group = "Initialization")); + parameter Boolean enable_nomSpeed = false "If checked, unit runs at fixed speed f_0" annotation( + choices(checkBox = true), + Dialog(group = "Initialization", enable = not fixed_iniSpeed and not enable_f_in)); + parameter Boolean fixed_iniSpeed = false "If checked, unit initialises with fixed speed. + When connecting several units mechanically only one can be fixed." annotation( + choices(checkBox = true), + Dialog(group = "Initialization", enable = not enable_nomSpeed and not enable_f_in)); + parameter Boolean enable_f_in = false "If checked, get a connector for speed input" annotation( + choices(checkBox = true), + Dialog(group = "Inputs", tab = "I/O", enable = not fixed_iniSpeed and not enable_nomSpeed)); + parameter Boolean enable_w = false "If checked, get a connector for angular velocity output" annotation( + choices(checkBox = true), + Dialog(group = "Outputs", tab = "I/O")); + parameter Boolean enable_f = false "If checked, get a connector for speed output" annotation( + choices(checkBox = true), + Dialog(group = "Outputs", tab = "I/O")); + + Modelica.Mechanics.Rotational.Sensors.SpeedSensor speedSensor annotation( + Placement(transformation(origin = {10, -28}, extent = {{10, -10}, {-10, 10}}, rotation = 90))); + Modelica.Mechanics.Rotational.Components.Inertia inertia(J = if useH then 2*H*Pmax/f_0^2 else J, w(start = f_0*2*Modelica.Constants.pi*data.f_0/(p/2), fixed = not enable_nomSpeed and not enable_f_in and fixed_iniSpeed)) annotation( + Placement(transformation(extent = {{-20, -10}, {0, 10}}))); + Modelica.Electrical.Machines.Losses.Friction friction(frictionParameters(PRef = Ploss, wRef = data.f_0*4*C.pi/p)) annotation( + Placement(transformation(extent = {{0, 60}, {20, 40}}))); + Modelica.Mechanics.Rotational.Components.Fixed fixed annotation( + Placement(transformation(extent = {{20, 50}, {40, 70}}))); + Modelica.Blocks.Math.Gain w_m2pu(k = (p/2)/(2*Modelica.Constants.pi*data.f_0)) annotation( + Placement(transformation(extent = {{66, -46}, {78, -34}}))); + Modelica.Blocks.Interfaces.RealOutput f if enable_f "Speed output of the unit [pu]" annotation( + Placement(transformation(extent = {{100, -50}, {120, -30}}), iconTransformation(extent = {{100, -50}, {120, -30}}))); + Modelica.Blocks.Interfaces.RealOutput w(unit = "rad/s") if enable_w "Mechanical angular velocity output of the unit [rad/s]" annotation( + Placement(transformation(extent = {{100, 30}, {120, 50}}), iconTransformation(extent = {{100, 30}, {120, 50}}))); + Modelica.Mechanics.Rotational.Interfaces.Flange_b flange "Flange of right shaft" annotation( + Placement(transformation(extent = {{40, -10}, {60, 10}}), iconTransformation(extent = {{-10, -10}, {10, 10}}))); + Modelica.Blocks.Sources.RealExpression torque annotation( + Placement(transformation(extent = {{-60, 20}, {-80, 40}}))); + Modelica.Mechanics.Rotational.Sensors.PowerSensor frictionLoss annotation( + Placement(transformation(extent = {{10, -10}, {-10, 10}}, rotation = 270, origin = {10, 20}))); + Modelica.Mechanics.Rotational.Sources.Speed setSpeed if enable_nomSpeed or enable_f_in annotation( + Placement(transformation(extent = {{76, -6}, {64, 6}}))); + Modelica.Mechanics.Rotational.Components.IdealGear toSysSpeed(ratio = 2/p) "Converts to system speed based on p = 2" annotation( + Placement(transformation(extent = {{24, -6}, {36, 6}}))); + Modelica.Blocks.Sources.RealExpression nominalSpeed(y = f_0) if enable_nomSpeed annotation( + Placement(transformation(extent = {{-10, -80}, {10, -60}}))); + Modelica.Blocks.Interfaces.RealInput f_in if enable_f_in and not enable_nomSpeed "Speed input of the unit [pu]" annotation( + Placement(transformation(extent = {{-20, -20}, {20, 20}}, rotation = 90, origin = {-80, -120}))); + Modelica.Blocks.Math.Gain pu2w_s(k = 2*Modelica.Constants.pi*data.f_0) if enable_f_in or enable_nomSpeed annotation( + Placement(transformation(extent = {{40, -90}, {60, -70}}))); + protected + Modelica.Mechanics.Rotational.Sources.Torque torque_transfer annotation( + Placement(transformation(extent = {{-36, -6}, {-24, 6}}))); + +equation + connect(w, speedSensor.w) annotation( + Line(points = {{110, 40}, {40, 40}, {40, -42}, {10, -42}, {10, -39}}, color = {0, 0, 127}, pattern = LinePattern.Dash)); + connect(w_m2pu.u, speedSensor.w) annotation( + Line(points = {{64.8, -40}, {64.8, -42}, {10, -42}, {10, -39}}, color = {0, 0, 127})); + connect(f, w_m2pu.y) annotation( + Line(points = {{110, -40}, {78.6, -40}}, color = {0, 0, 127}, pattern = LinePattern.Dash)); + connect(inertia.flange_b, speedSensor.flange) annotation( + Line(points = {{0, 0}, {0, -2}, {10, -2}, {10, -18}})); + connect(friction.support, fixed.flange) annotation( + Line(points = {{10, 60}, {10, 70}, {30, 70}, {30, 60}}, color = {0, 0, 0})); + connect(torque_transfer.flange, inertia.flange_a) annotation( + Line(points = {{-24, 0}, {-20, 0}}, color = {0, 0, 0})); + connect(w, w) annotation( + Line(points = {{110, 40}, {105, 40}, {105, 40}, {110, 40}}, color = {0, 0, 127})); + connect(frictionLoss.flange_a, inertia.flange_b) annotation( + Line(points = {{10, 10}, {10, 0}, {0, 0}}, color = {0, 0, 0})); + connect(frictionLoss.flange_b, friction.flange) annotation( + Line(points = {{10, 30}, {10, 40}}, color = {0, 0, 0})); + connect(setSpeed.flange, flange) annotation( + Line(points = {{64, 0}, {50, 0}}, color = {0, 0, 0}, pattern = LinePattern.Dash)); + connect(flange, toSysSpeed.flange_b) annotation( + Line(points = {{50, 0}, {36, 0}}, color = {0, 0, 0})); + connect(toSysSpeed.flange_a, inertia.flange_b) annotation( + Line(points = {{24, 0}, {0, 0}}, color = {0, 0, 0})); + connect(setSpeed.w_ref, pu2w_s.y) annotation( + Line(points = {{77.2, 0}, {88, 0}, {88, -80}, {61, -80}}, color = {0, 0, 127}, pattern = LinePattern.Dash)); + connect(pu2w_s.u, f_in) annotation( + Line(points = {{38, -80}, {28, -80}, {28, -90}, {-80, -90}, {-80, -120}}, color = {0, 0, 127}, pattern = LinePattern.Dash)); + connect(nominalSpeed.y, pu2w_s.u) annotation( + Line(points = {{11, -70}, {28, -70}, {28, -80}, {38, -80}}, color = {0, 0, 127}, pattern = LinePattern.Dash)); + connect(torque.y, torque_transfer.tau) annotation( + Line(points = {{-80, 30}, {-94, 30}, {-94, 0}, {-38, 0}}, color = {0, 0, 127})); + annotation( + Icon(graphics = {Text(visible = enable_w, extent = {{80, 50}, {100, 30}}, textColor = {0, 0, 0}, textString = "w"), Text(visible = enable_f, extent = {{80, -30}, {100, -50}}, textColor = {0, 0, 0}, textString = "f"), Text(visible = enable_f_in, extent = {{-100, -70}, {-60, -90}}, textColor = {0, 0, 0}, textString = "f_in")}), +Documentation(info = "

Abstract (partial) base class for including the torque equation:
$$ J\frac{d\omega}{dt}=T $$
In the future this base class can replace Power2Torque in the turbine models to avoid the issue at zero speed. This class is also better suited for fundamental or mechanistic turbine models.

")); + +end TorqueEquation; From 6da4f316bfc897e2e37476cb4e83c50e2abd78ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bjarne=20B=C3=B8rresen?= Date: Wed, 11 Feb 2026 14:37:17 +0100 Subject: [PATCH 3/9] Added base class TorqueEquation --- OpenHPLTest/TorqueEquation.mo | 5 +++++ OpenHPLTest/package.order | 2 ++ 2 files changed, 7 insertions(+) create mode 100644 OpenHPLTest/TorqueEquation.mo diff --git a/OpenHPLTest/TorqueEquation.mo b/OpenHPLTest/TorqueEquation.mo new file mode 100644 index 00000000..dec90663 --- /dev/null +++ b/OpenHPLTest/TorqueEquation.mo @@ -0,0 +1,5 @@ +within OpenHPLTest; + +package TorqueEquation + extends Modelica.Icons.ExamplesPackage; +end TorqueEquation; diff --git a/OpenHPLTest/package.order b/OpenHPLTest/package.order index 33105008..6883ceb3 100644 --- a/OpenHPLTest/package.order +++ b/OpenHPLTest/package.order @@ -71,3 +71,5 @@ HPSTSimple HPSTAirCushion HPSTSharpOrifice HPSTThrottleValve +TestPipe +TorqueEquation From 8b354965856fee7fdf070507b1c3a101764724aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bjarne=20B=C3=B8rresen?= Date: Tue, 17 Feb 2026 12:46:59 +0100 Subject: [PATCH 4/9] Added f_grid - grid frequency to Data, corrected reference speed for normalization of speed (to p.u.) in Power2Torque and TorqueEquation. Added test case for TorqueEquation in OpenHPLTest --- OpenHPL/Data.mo | 1 + .../ElectroMech/BaseClasses/Power2Torque.mo | 4 +-- .../ElectroMech/BaseClasses/TorqueEquation.mo | 8 ++--- OpenHPLTest/TorqueEquation.mo | 32 +++++++++++++++++++ 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/OpenHPL/Data.mo b/OpenHPL/Data.mo index 416ec54d..f3b30a4a 100644 --- a/OpenHPL/Data.mo +++ b/OpenHPL/Data.mo @@ -19,6 +19,7 @@ record Data "Provides a data set of most common used settings" annotation (Dialog(group = "Waterway properties")); parameter SI.Compressibility beta_total = 1 / (rho*1000^2) "Total compressibility" annotation (Dialog(group = "Waterway properties")); + parameter SI.Frequency f_grid=50 "Grid frequency" annotation (Dialog(group = "System properties")); parameter Boolean SteadyState=false "If checked, simulation starts in steady state" annotation (choices(checkBox = true), Dialog(group="Initialization")); parameter SI.VolumeFlowRate Vdot_0 = 0 "Initial volume flow rate through the system" diff --git a/OpenHPL/ElectroMech/BaseClasses/Power2Torque.mo b/OpenHPL/ElectroMech/BaseClasses/Power2Torque.mo index 979fad93..7eb0ce6e 100644 --- a/OpenHPL/ElectroMech/BaseClasses/Power2Torque.mo +++ b/OpenHPL/ElectroMech/BaseClasses/Power2Torque.mo @@ -67,7 +67,7 @@ partial model Power2Torque "Converts a power signal to a torque in the rotationa extent={{-6,-6},{6,6}}, rotation=180, origin={-50,-40}))); - Modelica.Blocks.Math.Gain w_m2pu(k=(p/2)/(2*C.pi*data.f_0)) + Modelica.Blocks.Math.Gain w_m2pu(k=(p/2)/(2*C.pi*data.f_grid)) annotation (Placement(transformation(extent={{66,-46},{78,-34}}))); Modelica.Blocks.Nonlinear.Limiter torqueLimit(uMax=Pmax/f_0) annotation (Placement(transformation( @@ -101,7 +101,7 @@ partial model Power2Torque "Converts a power signal to a torque in the rotationa Modelica.Blocks.Interfaces.RealInput f_in if enable_f_in and not enable_nomSpeed "Speed input of the unit [pu]" annotation (Placement(transformation(extent={{-20,-20},{20,20}},rotation=90,origin={-80,-120}))); - Modelica.Blocks.Math.Gain pu2w_s(k=2*C.pi*data.f_0) if enable_f_in or enable_nomSpeed + Modelica.Blocks.Math.Gain pu2w_s(k=2*C.pi*data.f_grid) if enable_f_in or enable_nomSpeed annotation (Placement(transformation(extent={{40,-90},{60,-70}}))); equation diff --git a/OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo b/OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo index 7ee1307d..c22654c8 100644 --- a/OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo +++ b/OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo @@ -44,7 +44,7 @@ partial model TorqueEquation Placement(transformation(extent = {{0, 60}, {20, 40}}))); Modelica.Mechanics.Rotational.Components.Fixed fixed annotation( Placement(transformation(extent = {{20, 50}, {40, 70}}))); - Modelica.Blocks.Math.Gain w_m2pu(k = (p/2)/(2*Modelica.Constants.pi*data.f_0)) annotation( + Modelica.Blocks.Math.Gain w_m2pu(k = (p/2)/(data.f_grid*2*Modelica.Constants.pi)) "Convert from rad/s to pu" annotation( Placement(transformation(extent = {{66, -46}, {78, -34}}))); Modelica.Blocks.Interfaces.RealOutput f if enable_f "Speed output of the unit [pu]" annotation( Placement(transformation(extent = {{100, -50}, {120, -30}}), iconTransformation(extent = {{100, -50}, {120, -30}}))); @@ -64,12 +64,12 @@ partial model TorqueEquation Placement(transformation(extent = {{-10, -80}, {10, -60}}))); Modelica.Blocks.Interfaces.RealInput f_in if enable_f_in and not enable_nomSpeed "Speed input of the unit [pu]" annotation( Placement(transformation(extent = {{-20, -20}, {20, 20}}, rotation = 90, origin = {-80, -120}))); - Modelica.Blocks.Math.Gain pu2w_s(k = 2*Modelica.Constants.pi*data.f_0) if enable_f_in or enable_nomSpeed annotation( + Modelica.Blocks.Math.Gain pu2w_s(k = 2*Modelica.Constants.pi*data.f_grid) if enable_f_in or enable_nomSpeed annotation( Placement(transformation(extent = {{40, -90}, {60, -70}}))); protected Modelica.Mechanics.Rotational.Sources.Torque torque_transfer annotation( Placement(transformation(extent = {{-36, -6}, {-24, 6}}))); - + equation connect(w, speedSensor.w) annotation( Line(points = {{110, 40}, {40, 40}, {40, -42}, {10, -42}, {10, -39}}, color = {0, 0, 127}, pattern = LinePattern.Dash)); @@ -105,6 +105,6 @@ equation Line(points = {{-80, 30}, {-94, 30}, {-94, 0}, {-38, 0}}, color = {0, 0, 127})); annotation( Icon(graphics = {Text(visible = enable_w, extent = {{80, 50}, {100, 30}}, textColor = {0, 0, 0}, textString = "w"), Text(visible = enable_f, extent = {{80, -30}, {100, -50}}, textColor = {0, 0, 0}, textString = "f"), Text(visible = enable_f_in, extent = {{-100, -70}, {-60, -90}}, textColor = {0, 0, 0}, textString = "f_in")}), -Documentation(info = "

Abstract (partial) base class for including the torque equation:
$$ J\frac{d\omega}{dt}=T $$
In the future this base class can replace Power2Torque in the turbine models to avoid the issue at zero speed. This class is also better suited for fundamental or mechanistic turbine models.

")); +Documentation(info = "

Abstract (partial) base class for including the torque equation:
$$ J\\f rac{d\\omega}{dt}=T $$
In the future this base class can replace Power2Torque in the turbine models to avoid the issue at zero speed. This class is also better suited for fundamental or mechanistic turbine models.

")); end TorqueEquation; diff --git a/OpenHPLTest/TorqueEquation.mo b/OpenHPLTest/TorqueEquation.mo index dec90663..ed03c8b1 100644 --- a/OpenHPLTest/TorqueEquation.mo +++ b/OpenHPLTest/TorqueEquation.mo @@ -2,4 +2,36 @@ within OpenHPLTest; package TorqueEquation extends Modelica.Icons.ExamplesPackage; + import SI = Modelica.Units.SI; + // + + model TorqueElement + extends OpenHPL.Icons.ElectroMech; + extends OpenHPL.ElectroMech.BaseClasses.TorqueEquation; + equation + + end TorqueElement; + + model TorqueTest + extends Modelica.Icons.Example; + // + parameter SI.Torque shaftTorque0 = 1.e+03; + SI.Torque shaftTorque; + inner OpenHPL.Data data annotation( + Placement(transformation(origin = {-52, 74}, extent = {{-10, -10}, {10, 10}}))); + TorqueElement te1(J = 10, f_0 = 0, torque(y = shaftTorque), enable_f = true, p = 10) annotation( + Placement(transformation(origin = {-30, 52}, extent = {{-10, -10}, {10, 10}}))); + TorqueElement te2(J = 10, f_0 = 0, torque(y = shaftTorque), enable_f = true, p = 22) annotation( + Placement(transformation(origin = {-30, 24}, extent = {{-10, -10}, {10, 10}}))); + equation + if (time > 0.1 and time < 0.4) then + shaftTorque = shaftTorque0; + elseif (time > 0.5 and time < 0.8) then + shaftTorque = -shaftTorque0; + else + shaftTorque = 0.0; + end if; + annotation( + Diagram(coordinateSystem(extent = {{-80, 80}, {-20, 0}}))); +end TorqueTest; end TorqueEquation; From 1b7da4ffbce763b0372a9c3ee436fb5afecf3a7d Mon Sep 17 00:00:00 2001 From: Dietmar Winkler Date: Mon, 23 Feb 2026 13:23:43 +0100 Subject: [PATCH 5/9] Fix package order. --- OpenHPLTest/package.order | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/OpenHPLTest/package.order b/OpenHPLTest/package.order index 6883ceb3..e2e7c76f 100644 --- a/OpenHPLTest/package.order +++ b/OpenHPLTest/package.order @@ -1,4 +1,5 @@ TestPipe +TorqueEquation OpenChannel Reservoir TestMCB @@ -71,5 +72,3 @@ HPSTSimple HPSTAirCushion HPSTSharpOrifice HPSTThrottleValve -TestPipe -TorqueEquation From 6c46ffafa93508761e0aa17e8fed52dd5a485485 Mon Sep 17 00:00:00 2001 From: Dietmar Winkler Date: Mon, 23 Feb 2026 13:42:09 +0100 Subject: [PATCH 6/9] Fix the documentation --- .../ElectroMech/BaseClasses/TorqueEquation.mo | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo b/OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo index c22654c8..d8cb7fc3 100644 --- a/OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo +++ b/OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo @@ -37,7 +37,7 @@ partial model TorqueEquation Dialog(group = "Outputs", tab = "I/O")); Modelica.Mechanics.Rotational.Sensors.SpeedSensor speedSensor annotation( - Placement(transformation(origin = {10, -28}, extent = {{10, -10}, {-10, 10}}, rotation = 90))); + Placement(transformation(origin = {10, -20}, extent = {{10, -10}, {-10, 10}}, rotation = 90))); Modelica.Mechanics.Rotational.Components.Inertia inertia(J = if useH then 2*H*Pmax/f_0^2 else J, w(start = f_0*2*Modelica.Constants.pi*data.f_0/(p/2), fixed = not enable_nomSpeed and not enable_f_in and fixed_iniSpeed)) annotation( Placement(transformation(extent = {{-20, -10}, {0, 10}}))); Modelica.Electrical.Machines.Losses.Friction friction(frictionParameters(PRef = Ploss, wRef = data.f_0*4*C.pi/p)) annotation( @@ -69,16 +69,15 @@ partial model TorqueEquation protected Modelica.Mechanics.Rotational.Sources.Torque torque_transfer annotation( Placement(transformation(extent = {{-36, -6}, {-24, 6}}))); - equation connect(w, speedSensor.w) annotation( - Line(points = {{110, 40}, {40, 40}, {40, -42}, {10, -42}, {10, -39}}, color = {0, 0, 127}, pattern = LinePattern.Dash)); + Line(points = {{110, 40}, {40, 40}, {40, -40}, {10, -40}, {10, -31}}, color = {0, 0, 127}, pattern = LinePattern.Dash)); connect(w_m2pu.u, speedSensor.w) annotation( - Line(points = {{64.8, -40}, {64.8, -42}, {10, -42}, {10, -39}}, color = {0, 0, 127})); + Line(points = {{64.8, -40}, {10, -40}, {10, -31}}, color = {0, 0, 127})); connect(f, w_m2pu.y) annotation( Line(points = {{110, -40}, {78.6, -40}}, color = {0, 0, 127}, pattern = LinePattern.Dash)); connect(inertia.flange_b, speedSensor.flange) annotation( - Line(points = {{0, 0}, {0, -2}, {10, -2}, {10, -18}})); + Line(points = {{0, 0}, {10, 0}, {10, -10}})); connect(friction.support, fixed.flange) annotation( Line(points = {{10, 60}, {10, 70}, {30, 70}, {30, 60}}, color = {0, 0, 0})); connect(torque_transfer.flange, inertia.flange_a) annotation( @@ -105,6 +104,16 @@ equation Line(points = {{-80, 30}, {-94, 30}, {-94, 0}, {-38, 0}}, color = {0, 0, 127})); annotation( Icon(graphics = {Text(visible = enable_w, extent = {{80, 50}, {100, 30}}, textColor = {0, 0, 0}, textString = "w"), Text(visible = enable_f, extent = {{80, -30}, {100, -50}}, textColor = {0, 0, 0}, textString = "f"), Text(visible = enable_f_in, extent = {{-100, -70}, {-60, -90}}, textColor = {0, 0, 0}, textString = "f_in")}), -Documentation(info = "

Abstract (partial) base class for including the torque equation:
$$ J\\f rac{d\\omega}{dt}=T $$
In the future this base class can replace Power2Torque in the turbine models to avoid the issue at zero speed. This class is also better suited for fundamental or mechanistic turbine models.

")); +Documentation(info = " +

+Abstract (partial) base class for including the torque equation: +

+

+$$ J \\frac{\\mathrm{d}\\omega}{\\mathrm{d}t} = T $$ +

+

+In the future this base class can replace Power2Torque in the turbine models to avoid the issue at zero speed. This class is also better suited for fundamental or mechanistic turbine models. +

+")); -end TorqueEquation; +end TorqueEquation; \ No newline at end of file From f6326eb9fa96fd39720fca11aa1659bc83f7a35d Mon Sep 17 00:00:00 2001 From: Dietmar Winkler Date: Mon, 23 Feb 2026 14:03:28 +0100 Subject: [PATCH 7/9] Make Power2Torque to extend from TorqueEquation --- .../ElectroMech/BaseClasses/Power2Torque.mo | 214 +++++------------- .../ElectroMech/BaseClasses/TorqueEquation.mo | 8 +- OpenHPL/ElectroMech/BaseClasses/package.order | 2 +- 3 files changed, 56 insertions(+), 168 deletions(-) diff --git a/OpenHPL/ElectroMech/BaseClasses/Power2Torque.mo b/OpenHPL/ElectroMech/BaseClasses/Power2Torque.mo index 7eb0ce6e..5c084fa3 100644 --- a/OpenHPL/ElectroMech/BaseClasses/Power2Torque.mo +++ b/OpenHPL/ElectroMech/BaseClasses/Power2Torque.mo @@ -1,166 +1,58 @@ within OpenHPL.ElectroMech.BaseClasses; partial model Power2Torque "Converts a power signal to a torque in the rotational domain" + extends TorqueEquation; outer Data data "Using standard class with global parameters"; - - parameter Boolean useH= false "If checked, calculate the inertia from a given H value" - annotation (Dialog(group = "Mechanical"), choices(checkBox=true)); - parameter SI.Power Pmax = 100e6 "Maximum rated power (for torque limiting and H calculation)" - annotation (Dialog(group = "Mechanical")); - parameter SI.Time H = 2.75 "Inertia constant H, typical 2s (high-head hydro) to 6s (gas or low-head hydro) production units" - annotation (Dialog(group = "Mechanical", enable=useH)); - parameter SI.MomentOfInertia J = 2e5 "Moment of inertia of the unit" - annotation (Dialog(group = "Mechanical", enable=not useH)); - parameter Integer p(min=2) = 12 "Number of poles for mechanical speed calculation" - annotation (Dialog(group = "Mechanical"), - choices( choice = 2 "2,[3000|3600] rpm", - choice = 4 "4,[1500|1800] rpm", - choice = 6 "6,[1000|1200] rpm", - choice = 8 "8,[750|900] rpm", - choice = 10 "10,[600|720] rpm", - choice = 12 "12,[500|600] rpm", - choice = 14 "14,[429|514] rpm", - choice = 16 "16,[375|450] rpm", - choice = 18 "18,[333|400] rpm", - choice = 20 "20,[300|360] rpm", - choice = 22 "22,[273|327] rpm", - choice = 24 "24,[250|300] rpm", - choice = 26 "26,[231|277] rpm", - choice = 28 "28,[214|257] rpm", - choice = 30 "30,[200|240] rpm", - choice = 28 "32,[187.5|225] rpm")); - parameter SI.Power Ploss = 0 "Friction losses of the unit at nominal speed" - annotation (Dialog(group = "Mechanical")); - parameter SI.PerUnit f_0=1 "Initial speed of the unit" - annotation (Dialog(group="Initialization")); - parameter Boolean enable_nomSpeed = false "If checked, unit runs at fixed speed f_0" - annotation (choices(checkBox = true), - Dialog(group = "Initialization", enable=not fixed_iniSpeed and not enable_f_in)); + parameter Boolean useH = false "If checked, calculate the inertia from a given H value" annotation( + Dialog(group = "Mechanical"), + choices(checkBox = true)); + parameter Modelica.Units.SI.Power Pmax = 100e6 "Maximum rated power (for torque limiting and H calculation)" annotation( + Dialog(group = "Mechanical")); + parameter Modelica.Units.SI.Time H = 2.75 "Inertia constant H, typical 2s (high-head hydro) to 6s (gas or low-head hydro) production units" annotation( + Dialog(group = "Mechanical", enable = useH)); + parameter Modelica.Units.SI.MomentOfInertia J = 2e5 "Moment of inertia of the unit" annotation( + Dialog(group = "Mechanical", enable = not useH)); + parameter Integer p(min = 2) = 12 "Number of poles for mechanical speed calculation" annotation( + Dialog(group = "Mechanical"), + choices(choice = 2 "2,[3000|3600] rpm", choice = 4 "4,[1500|1800] rpm", choice = 6 "6,[1000|1200] rpm", choice = 8 "8,[750|900] rpm", choice = 10 "10,[600|720] rpm", choice = 12 "12,[500|600] rpm", choice = 14 "14,[429|514] rpm", choice = 16 "16,[375|450] rpm", choice = 18 "18,[333|400] rpm", choice = 20 "20,[300|360] rpm", choice = 22 "22,[273|327] rpm", choice = 24 "24,[250|300] rpm", choice = 26 "26,[231|277] rpm", choice = 28 "28,[214|257] rpm", choice = 30 "30,[200|240] rpm", choice = 28 "32,[187.5|225] rpm")); + parameter Modelica.Units.SI.Power Ploss = 0 "Friction losses of the unit at nominal speed" annotation( + Dialog(group = "Mechanical")); + parameter Modelica.Units.SI.PerUnit f_0 = 1 "Initial speed of the unit" annotation( + Dialog(group = "Initialization")); + parameter Boolean enable_nomSpeed = false "If checked, unit runs at fixed speed f_0" annotation( + choices(checkBox = true), + Dialog(group = "Initialization", enable = not fixed_iniSpeed and not enable_f_in)); parameter Boolean fixed_iniSpeed = false "If checked, unit initialises with fixed speed. - When connecting several units mechanically only one can be fixed." - annotation (choices(checkBox = true), - Dialog(group = "Initialization", enable=not enable_nomSpeed and not enable_f_in)); - parameter Boolean enable_f_in=false "If checked, get a connector for speed input" - annotation (choices(checkBox = true), - Dialog(group="Inputs", tab="I/O", enable=not fixed_iniSpeed and not enable_nomSpeed)); - parameter Boolean enable_w = false "If checked, get a connector for angular velocity output" - annotation (choices(checkBox = true), Dialog(group = "Outputs", tab="I/O")); - parameter Boolean enable_f = false "If checked, get a connector for speed output" - annotation (choices(checkBox = true), Dialog(group = "Outputs", tab="I/O")); - - Modelica.Blocks.Math.Division power2torque - annotation (Placement(transformation(extent={{-76,-6},{-64,6}}))); - Modelica.Mechanics.Rotational.Sensors.SpeedSensor speedSensor - annotation (Placement(transformation( - extent={{10,-10},{-10,10}}, - rotation=90, - origin={10,-20}))); - Modelica.Mechanics.Rotational.Components.Inertia inertia(J=if useH then 2*H*Pmax/f_0^2 else J, w(start=f_0*2*C.pi*data.f_0/(p/2), fixed=not enable_nomSpeed and not enable_f_in and fixed_iniSpeed)) - annotation (Placement(transformation(extent={{-20,-10},{0,10}}))); - Modelica.Electrical.Machines.Losses.Friction friction(frictionParameters(PRef=Ploss, wRef=data.f_0*4*C.pi/p)) - annotation (Placement(transformation(extent={{0,60},{20,40}}))); - Modelica.Mechanics.Rotational.Components.Fixed fixed - annotation (Placement(transformation(extent={{20,50},{40,70}}))); - Modelica.Mechanics.Rotational.Sources.Torque torque - annotation (Placement(transformation(extent={{-36,-6},{-24,6}}))); - Modelica.Blocks.Nonlinear.Limiter div0protect(uMax=Modelica.Constants.inf, uMin=Modelica.Constants.small) - annotation (Placement(transformation( - extent={{-6,-6},{6,6}}, - rotation=180, - origin={-50,-40}))); - Modelica.Blocks.Math.Gain w_m2pu(k=(p/2)/(2*C.pi*data.f_grid)) - annotation (Placement(transformation(extent={{66,-46},{78,-34}}))); - Modelica.Blocks.Nonlinear.Limiter torqueLimit(uMax=Pmax/f_0) - annotation (Placement(transformation( - extent={{6,6},{-6,-6}}, - rotation=180, - origin={-50,0}))); - Modelica.Blocks.Interfaces.RealOutput f if enable_f - "Speed output of the unit [pu]" - annotation (Placement(transformation(extent={{100,-50},{120,-30}}), - iconTransformation(extent={{100,-50},{120,-30}}))); - Modelica.Blocks.Interfaces.RealOutput w(unit="rad/s") if enable_w - "Mechanical angular velocity output of the unit [rad/s]" - annotation (Placement(transformation(extent={{100,30},{120,50}}), - iconTransformation(extent={{100,30},{120,50}}))); - - Modelica.Mechanics.Rotational.Interfaces.Flange_b flange "Flange of right shaft" - annotation (Placement(transformation(extent={{40,-10},{60,10}}), iconTransformation(extent={{-10,-10},{10,10}}))); - Modelica.Blocks.Sources.RealExpression power - annotation (Placement(transformation(extent={{-60,20},{-80,40}}))); - Modelica.Mechanics.Rotational.Sensors.PowerSensor frictionLoss - annotation (Placement(transformation( - extent={{10,-10},{-10,10}}, - rotation=270, - origin={10,20}))); - Modelica.Mechanics.Rotational.Sources.Speed setSpeed if enable_nomSpeed or enable_f_in - annotation (Placement(transformation(extent={{76,-6},{64,6}}))); - Modelica.Mechanics.Rotational.Components.IdealGear toSysSpeed(ratio=2/p) "Converts to system speed based on p = 2" - annotation (Placement(transformation(extent={{24,-6},{36,6}}))); - Modelica.Blocks.Sources.RealExpression nominalSpeed(y=f_0) if enable_nomSpeed - annotation (Placement(transformation(extent={{-10,-80},{10,-60}}))); - Modelica.Blocks.Interfaces.RealInput f_in if enable_f_in and not enable_nomSpeed - "Speed input of the unit [pu]" - annotation (Placement(transformation(extent={{-20,-20},{20,20}},rotation=90,origin={-80,-120}))); - Modelica.Blocks.Math.Gain pu2w_s(k=2*C.pi*data.f_grid) if enable_f_in or enable_nomSpeed - annotation (Placement(transformation(extent={{40,-90},{60,-70}}))); - + When connecting several units mechanically only one can be fixed." annotation( + choices(checkBox = true), + Dialog(group = "Initialization", enable = not enable_nomSpeed and not enable_f_in)); + parameter Boolean enable_f_in = false "If checked, get a connector for speed input" annotation( + choices(checkBox = true), + Dialog(group = "Inputs", tab = "I/O", enable = not fixed_iniSpeed and not enable_nomSpeed)); + parameter Boolean enable_w = false "If checked, get a connector for angular velocity output" annotation( + choices(checkBox = true), + Dialog(group = "Outputs", tab = "I/O")); + parameter Boolean enable_f = false "If checked, get a connector for speed output" annotation( + choices(checkBox = true), + Dialog(group = "Outputs", tab = "I/O")); + Modelica.Blocks.Math.Division power2torque annotation( + Placement(transformation(extent = {{-76, -6}, {-64, 6}}))); + Modelica.Blocks.Nonlinear.Limiter div0protect(uMax = Modelica.Constants.inf, uMin = Modelica.Constants.small) annotation( + Placement(transformation(extent = {{-6, -6}, {6, 6}}, rotation = 180, origin = {-50, -40}))); + Modelica.Blocks.Nonlinear.Limiter torqueLimit(uMax = Pmax/f_0) annotation( + Placement(transformation(extent = {{6, 6}, {-6, -6}}, rotation = 180, origin = {-50, 0}))); + Modelica.Blocks.Sources.RealExpression power annotation( + Placement(transformation(extent = {{-60, 20}, {-80, 40}}))); equation - connect(w, speedSensor.w) annotation (Line( - points={{110,40},{40,40},{40,-40},{10,-40},{10,-31}}, - color={0,0,127}, - pattern=LinePattern.Dash)); - connect(w_m2pu.u, speedSensor.w) annotation (Line(points={{64.8,-40},{10,-40},{10,-31}}, color={0,0,127})); - connect(div0protect.y, power2torque.u2) annotation (Line(points={{-56.6,-40},{-88,-40},{-88,-3.6},{-77.2,-3.6}}, - color={0,0,127})); - connect(f, w_m2pu.y) annotation (Line( - points={{110,-40},{78.6,-40}}, - color={0,0,127}, - pattern=LinePattern.Dash)); - connect(power2torque.y, torqueLimit.u) annotation (Line(points={{-63.4,0},{-64,0},{-64,8.88178e-16},{-57.2,8.88178e-16}}, - color={0,0,127})); - connect(torqueLimit.y, torque.tau) annotation (Line(points={{-43.4,-6.66134e-16},{-42,-6.66134e-16},{-42,0},{-37.2,0}}, - color={0,0,127})); - connect(speedSensor.w,div0protect. u) annotation (Line(points={{10,-31},{10,-40},{-42.8,-40}}, - color={0,0,127})); - connect(inertia.flange_b, speedSensor.flange) annotation (Line(points={{0,0},{10,0},{10,-10}}, color={0,0,0})); - connect(friction.support, fixed.flange) annotation (Line(points={{10,60},{10,70},{30,70},{30,60}}, color={0,0,0})); - connect(torque.flange, inertia.flange_a) annotation (Line(points={{-24,0},{-20,0}}, - color={0,0,0})); - connect(w, w) annotation (Line(points={{110,40},{105,40},{105,40},{110,40}}, color={0,0,127})); - connect(power.y, power2torque.u1) annotation (Line(points={{-81,30},{-88,30},{-88,3.6},{-77.2,3.6}}, - color={0,0,127})); - connect(frictionLoss.flange_a, inertia.flange_b) annotation (Line(points={{10,10},{10,0},{0,0}}, color={0,0,0})); - connect(frictionLoss.flange_b, friction.flange) annotation (Line(points={{10,30},{10,40}}, color={0,0,0})); - connect(setSpeed.flange, flange) annotation (Line(points={{64,0},{50,0}}, color={0,0,0}, - pattern=LinePattern.Dash)); - connect(flange, toSysSpeed.flange_b) annotation (Line(points={{50,0},{36,0}}, color={0,0,0})); - connect(toSysSpeed.flange_a, inertia.flange_b) annotation (Line(points={{24,0},{0,0}}, color={0,0,0})); - connect(setSpeed.w_ref, pu2w_s.y) annotation (Line( - points={{77.2,0},{88,0},{88,-80},{61,-80}}, - color={0,0,127}, - pattern=LinePattern.Dash)); - connect(pu2w_s.u, f_in) annotation (Line( - points={{38,-80},{28,-80},{28,-90},{-80,-90},{-80,-120}}, - color={0,0,127}, - pattern=LinePattern.Dash)); - connect(nominalSpeed.y, pu2w_s.u) annotation (Line( - points={{11,-70},{28,-70},{28,-80},{38,-80}}, - color={0,0,127}, - pattern=LinePattern.Dash)); - annotation (Icon(graphics={ - Text( - visible=enable_w, - extent={{80,50},{100,30}}, - textColor={0,0,0}, - textString="w"), - Text( - visible=enable_f, - extent={{80,-30},{100,-50}}, - textColor={0,0,0}, - textString="f"), - Text( - visible=enable_f_in, - extent={{-100,-70},{-60,-90}}, - textColor={0,0,0}, - textString="f_in")})); -end Power2Torque; + connect(div0protect.y, power2torque.u2) annotation( + Line(points = {{-56.6, -40}, {-88, -40}, {-88, -3.6}, {-77.2, -3.6}}, color = {0, 0, 127})); + connect(power2torque.y, torqueLimit.u) annotation( + Line(points = {{-63.4, 0}, {-64, 0}, {-64, 8.88178e-16}, {-57.2, 8.88178e-16}}, color = {0, 0, 127})); + connect(power.y, power2torque.u1) annotation( + Line(points = {{-81, 30}, {-88, 30}, {-88, 3.6}, {-77.2, 3.6}}, color = {0, 0, 127})); + connect(torqueLimit.y, torque.tau) annotation( + Line(points = {{-44, 0}, {-38, 0}}, color = {0, 0, 127})); + connect(div0protect.u, speedSensor.w) annotation( + Line(points = {{-42, -40}, {10, -40}, {10, -30}}, color = {0, 0, 127})); + annotation( + Icon(graphics = {Text(visible = enable_w, extent = {{80, 50}, {100, 30}}, textColor = {0, 0, 0}, textString = "w"), Text(visible = enable_f, extent = {{80, -30}, {100, -50}}, textColor = {0, 0, 0}, textString = "f"), Text(visible = enable_f_in, extent = {{-100, -70}, {-60, -90}}, textColor = {0, 0, 0}, textString = "f_in")})); +end Power2Torque; \ No newline at end of file diff --git a/OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo b/OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo index d8cb7fc3..4c5f78de 100644 --- a/OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo +++ b/OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo @@ -52,8 +52,6 @@ partial model TorqueEquation Placement(transformation(extent = {{100, 30}, {120, 50}}), iconTransformation(extent = {{100, 30}, {120, 50}}))); Modelica.Mechanics.Rotational.Interfaces.Flange_b flange "Flange of right shaft" annotation( Placement(transformation(extent = {{40, -10}, {60, 10}}), iconTransformation(extent = {{-10, -10}, {10, 10}}))); - Modelica.Blocks.Sources.RealExpression torque annotation( - Placement(transformation(extent = {{-60, 20}, {-80, 40}}))); Modelica.Mechanics.Rotational.Sensors.PowerSensor frictionLoss annotation( Placement(transformation(extent = {{10, -10}, {-10, 10}}, rotation = 270, origin = {10, 20}))); Modelica.Mechanics.Rotational.Sources.Speed setSpeed if enable_nomSpeed or enable_f_in annotation( @@ -67,7 +65,7 @@ partial model TorqueEquation Modelica.Blocks.Math.Gain pu2w_s(k = 2*Modelica.Constants.pi*data.f_grid) if enable_f_in or enable_nomSpeed annotation( Placement(transformation(extent = {{40, -90}, {60, -70}}))); protected - Modelica.Mechanics.Rotational.Sources.Torque torque_transfer annotation( + Modelica.Mechanics.Rotational.Sources.Torque torque annotation( Placement(transformation(extent = {{-36, -6}, {-24, 6}}))); equation connect(w, speedSensor.w) annotation( @@ -80,7 +78,7 @@ equation Line(points = {{0, 0}, {10, 0}, {10, -10}})); connect(friction.support, fixed.flange) annotation( Line(points = {{10, 60}, {10, 70}, {30, 70}, {30, 60}}, color = {0, 0, 0})); - connect(torque_transfer.flange, inertia.flange_a) annotation( + connect(torque.flange, inertia.flange_a) annotation( Line(points = {{-24, 0}, {-20, 0}}, color = {0, 0, 0})); connect(w, w) annotation( Line(points = {{110, 40}, {105, 40}, {105, 40}, {110, 40}}, color = {0, 0, 127})); @@ -100,8 +98,6 @@ equation Line(points = {{38, -80}, {28, -80}, {28, -90}, {-80, -90}, {-80, -120}}, color = {0, 0, 127}, pattern = LinePattern.Dash)); connect(nominalSpeed.y, pu2w_s.u) annotation( Line(points = {{11, -70}, {28, -70}, {28, -80}, {38, -80}}, color = {0, 0, 127}, pattern = LinePattern.Dash)); - connect(torque.y, torque_transfer.tau) annotation( - Line(points = {{-80, 30}, {-94, 30}, {-94, 0}, {-38, 0}}, color = {0, 0, 127})); annotation( Icon(graphics = {Text(visible = enable_w, extent = {{80, 50}, {100, 30}}, textColor = {0, 0, 0}, textString = "w"), Text(visible = enable_f, extent = {{80, -30}, {100, -50}}, textColor = {0, 0, 0}, textString = "f"), Text(visible = enable_f_in, extent = {{-100, -70}, {-60, -90}}, textColor = {0, 0, 0}, textString = "f_in")}), Documentation(info = " diff --git a/OpenHPL/ElectroMech/BaseClasses/package.order b/OpenHPL/ElectroMech/BaseClasses/package.order index 49c67585..cf8edc46 100644 --- a/OpenHPL/ElectroMech/BaseClasses/package.order +++ b/OpenHPL/ElectroMech/BaseClasses/package.order @@ -1,3 +1,3 @@ -Power2Torque BaseValve +Power2Torque TorqueEquation From 2667cde4e0b90c362bae2f2f1ca1d543a153a2b9 Mon Sep 17 00:00:00 2001 From: Dietmar Winkler Date: Mon, 23 Feb 2026 14:13:23 +0100 Subject: [PATCH 8/9] Make use of library imports --- OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo b/OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo index 4c5f78de..802a5ed4 100644 --- a/OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo +++ b/OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo @@ -2,7 +2,7 @@ within OpenHPL.ElectroMech.BaseClasses; partial model TorqueEquation outer OpenHPL.Data data "Using standard class with global parameters"; - // + parameter Boolean useH = false "If checked, calculate the inertia from a given H value" annotation( Dialog(group = "Mechanical"), choices(checkBox = true)); @@ -38,13 +38,13 @@ partial model TorqueEquation Modelica.Mechanics.Rotational.Sensors.SpeedSensor speedSensor annotation( Placement(transformation(origin = {10, -20}, extent = {{10, -10}, {-10, 10}}, rotation = 90))); - Modelica.Mechanics.Rotational.Components.Inertia inertia(J = if useH then 2*H*Pmax/f_0^2 else J, w(start = f_0*2*Modelica.Constants.pi*data.f_0/(p/2), fixed = not enable_nomSpeed and not enable_f_in and fixed_iniSpeed)) annotation( + Modelica.Mechanics.Rotational.Components.Inertia inertia(J = if useH then 2*H*Pmax/f_0^2 else J, w(start = f_0*2*C.pi*data.f_0/(p/2), fixed = not enable_nomSpeed and not enable_f_in and fixed_iniSpeed)) annotation( Placement(transformation(extent = {{-20, -10}, {0, 10}}))); Modelica.Electrical.Machines.Losses.Friction friction(frictionParameters(PRef = Ploss, wRef = data.f_0*4*C.pi/p)) annotation( Placement(transformation(extent = {{0, 60}, {20, 40}}))); Modelica.Mechanics.Rotational.Components.Fixed fixed annotation( Placement(transformation(extent = {{20, 50}, {40, 70}}))); - Modelica.Blocks.Math.Gain w_m2pu(k = (p/2)/(data.f_grid*2*Modelica.Constants.pi)) "Convert from rad/s to pu" annotation( + Modelica.Blocks.Math.Gain w_m2pu(k = (p/2)/(data.f_grid*2*C.pi)) "Convert from rad/s to pu" annotation( Placement(transformation(extent = {{66, -46}, {78, -34}}))); Modelica.Blocks.Interfaces.RealOutput f if enable_f "Speed output of the unit [pu]" annotation( Placement(transformation(extent = {{100, -50}, {120, -30}}), iconTransformation(extent = {{100, -50}, {120, -30}}))); @@ -62,7 +62,7 @@ partial model TorqueEquation Placement(transformation(extent = {{-10, -80}, {10, -60}}))); Modelica.Blocks.Interfaces.RealInput f_in if enable_f_in and not enable_nomSpeed "Speed input of the unit [pu]" annotation( Placement(transformation(extent = {{-20, -20}, {20, 20}}, rotation = 90, origin = {-80, -120}))); - Modelica.Blocks.Math.Gain pu2w_s(k = 2*Modelica.Constants.pi*data.f_grid) if enable_f_in or enable_nomSpeed annotation( + Modelica.Blocks.Math.Gain pu2w_s(k = 2*C.pi*data.f_grid) if enable_f_in or enable_nomSpeed annotation( Placement(transformation(extent = {{40, -90}, {60, -70}}))); protected Modelica.Mechanics.Rotational.Sources.Torque torque annotation( From 96282696f5180bdf8210ae00f577946c920d8b08 Mon Sep 17 00:00:00 2001 From: Dietmar Winkler Date: Tue, 24 Feb 2026 10:26:32 +0100 Subject: [PATCH 9/9] Make use of f_nom helper parameter --- .../ElectroMech/BaseClasses/Power2Torque.mo | 5 +++-- .../ElectroMech/BaseClasses/TorqueEquation.mo | 18 +++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/OpenHPL/ElectroMech/BaseClasses/Power2Torque.mo b/OpenHPL/ElectroMech/BaseClasses/Power2Torque.mo index 5c084fa3..cbcb5ac3 100644 --- a/OpenHPL/ElectroMech/BaseClasses/Power2Torque.mo +++ b/OpenHPL/ElectroMech/BaseClasses/Power2Torque.mo @@ -38,7 +38,8 @@ partial model Power2Torque "Converts a power signal to a torque in the rotationa Placement(transformation(extent = {{-76, -6}, {-64, 6}}))); Modelica.Blocks.Nonlinear.Limiter div0protect(uMax = Modelica.Constants.inf, uMin = Modelica.Constants.small) annotation( Placement(transformation(extent = {{-6, -6}, {6, 6}}, rotation = 180, origin = {-50, -40}))); - Modelica.Blocks.Nonlinear.Limiter torqueLimit(uMax = Pmax/f_0) annotation( + Modelica.Blocks.Nonlinear.Limiter torqueLimit(uMax=Pmax/(2*C.pi*f_nom)) + annotation ( Placement(transformation(extent = {{6, 6}, {-6, -6}}, rotation = 180, origin = {-50, 0}))); Modelica.Blocks.Sources.RealExpression power annotation( Placement(transformation(extent = {{-60, 20}, {-80, 40}}))); @@ -55,4 +56,4 @@ equation Line(points = {{-42, -40}, {10, -40}, {10, -30}}, color = {0, 0, 127})); annotation( Icon(graphics = {Text(visible = enable_w, extent = {{80, 50}, {100, 30}}, textColor = {0, 0, 0}, textString = "w"), Text(visible = enable_f, extent = {{80, -30}, {100, -50}}, textColor = {0, 0, 0}, textString = "f"), Text(visible = enable_f_in, extent = {{-100, -70}, {-60, -90}}, textColor = {0, 0, 0}, textString = "f_in")})); -end Power2Torque; \ No newline at end of file +end Power2Torque; diff --git a/OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo b/OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo index 802a5ed4..87002d29 100644 --- a/OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo +++ b/OpenHPL/ElectroMech/BaseClasses/TorqueEquation.mo @@ -35,16 +35,17 @@ partial model TorqueEquation parameter Boolean enable_f = false "If checked, get a connector for speed output" annotation( choices(checkBox = true), Dialog(group = "Outputs", tab = "I/O")); - + final parameter SI.Frequency f_nom = data.f_grid / (p/2) "Nominal mechanical rotational frequency"; + Modelica.Mechanics.Rotational.Sensors.SpeedSensor speedSensor annotation( Placement(transformation(origin = {10, -20}, extent = {{10, -10}, {-10, 10}}, rotation = 90))); - Modelica.Mechanics.Rotational.Components.Inertia inertia(J = if useH then 2*H*Pmax/f_0^2 else J, w(start = f_0*2*C.pi*data.f_0/(p/2), fixed = not enable_nomSpeed and not enable_f_in and fixed_iniSpeed)) annotation( + Modelica.Mechanics.Rotational.Components.Inertia inertia(J=if useH then 2*H*Pmax/f_nom^2 else J, w(start=f_0*2*C.pi*f_nom, fixed=not enable_nomSpeed and not enable_f_in and fixed_iniSpeed)) annotation ( Placement(transformation(extent = {{-20, -10}, {0, 10}}))); - Modelica.Electrical.Machines.Losses.Friction friction(frictionParameters(PRef = Ploss, wRef = data.f_0*4*C.pi/p)) annotation( + Modelica.Electrical.Machines.Losses.Friction friction(frictionParameters(PRef=Ploss, wRef=2*C.pi*f_nom)) annotation ( Placement(transformation(extent = {{0, 60}, {20, 40}}))); Modelica.Mechanics.Rotational.Components.Fixed fixed annotation( Placement(transformation(extent = {{20, 50}, {40, 70}}))); - Modelica.Blocks.Math.Gain w_m2pu(k = (p/2)/(data.f_grid*2*C.pi)) "Convert from rad/s to pu" annotation( + Modelica.Blocks.Math.Gain w_m2pu(k=1/(2*C.pi*f_nom)) "Convert from rad/s to pu" annotation ( Placement(transformation(extent = {{66, -46}, {78, -34}}))); Modelica.Blocks.Interfaces.RealOutput f if enable_f "Speed output of the unit [pu]" annotation( Placement(transformation(extent = {{100, -50}, {120, -30}}), iconTransformation(extent = {{100, -50}, {120, -30}}))); @@ -62,10 +63,9 @@ partial model TorqueEquation Placement(transformation(extent = {{-10, -80}, {10, -60}}))); Modelica.Blocks.Interfaces.RealInput f_in if enable_f_in and not enable_nomSpeed "Speed input of the unit [pu]" annotation( Placement(transformation(extent = {{-20, -20}, {20, 20}}, rotation = 90, origin = {-80, -120}))); - Modelica.Blocks.Math.Gain pu2w_s(k = 2*C.pi*data.f_grid) if enable_f_in or enable_nomSpeed annotation( + Modelica.Blocks.Math.Gain pu2w_s(k=2*C.pi*f_nom*(p/2)) if enable_f_in or enable_nomSpeed annotation ( Placement(transformation(extent = {{40, -90}, {60, -70}}))); - protected - Modelica.Mechanics.Rotational.Sources.Torque torque annotation( + Modelica.Mechanics.Rotational.Sources.Torque torque annotation ( Placement(transformation(extent = {{-36, -6}, {-24, 6}}))); equation connect(w, speedSensor.w) annotation( @@ -103,7 +103,7 @@ equation Documentation(info = "

Abstract (partial) base class for including the torque equation: -

+

$$ J \\frac{\\mathrm{d}\\omega}{\\mathrm{d}t} = T $$

@@ -112,4 +112,4 @@ In the future this base class can replace Power2Torque in the turbi

")); -end TorqueEquation; \ No newline at end of file +end TorqueEquation;