From ec1a1e0cfb95be00d598c7d2ed610cb5ca8f0c15 Mon Sep 17 00:00:00 2001 From: Dietmar Winkler Date: Mon, 13 Apr 2026 07:43:15 +0200 Subject: [PATCH 1/2] Fix the initialisation of Pipe volume flow in connection with sources --- OpenHPL/Examples/VolumeFlowSource.mo | 14 +++++++------- OpenHPL/Waterway/Pipe.mo | 12 ++++++++---- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/OpenHPL/Examples/VolumeFlowSource.mo b/OpenHPL/Examples/VolumeFlowSource.mo index a490171..5ae0c71 100644 --- a/OpenHPL/Examples/VolumeFlowSource.mo +++ b/OpenHPL/Examples/VolumeFlowSource.mo @@ -2,19 +2,19 @@ within OpenHPL.Examples; model VolumeFlowSource "Example demonstrating the use of VolumeFlowSource" extends Modelica.Icons.Example; OpenHPL.Waterway.Reservoir tail1 annotation (Placement(transformation(extent={{60,30},{40,50}}))); - inner OpenHPL.Data data(SteadyState = false, Vdot_0 = 1, showElevation = true) annotation (Placement(transformation(extent={{-100,80},{-80,100}}))); + inner OpenHPL.Data data(SteadyState = true) annotation (Placement(transformation(extent={{-100,80},{-80,100}}))); OpenHPL.Waterway.VolumeFlowSource volumeFlowConstant(fixElevation = true) annotation (Placement(transformation(extent={{-50,30},{-30,50}}))); - Waterway.Pipe pipe1(H=0) annotation (Placement(transformation(extent={{-10,30},{10,50}}))); - Waterway.Pipe pipe2(H=0) annotation (Placement(transformation(extent={{-10,-10},{10,10}}))); + Waterway.Pipe pipe1(H=0, useInitialEquation=false) annotation (Placement(transformation(extent={{-10,30},{10,50}}))); + Waterway.Pipe pipe2(H=0, useInitialEquation=false) annotation (Placement(transformation(extent={{-10,-10},{10,10}}))); OpenHPL.Waterway.Reservoir tail2 annotation (Placement(transformation(extent={{60,-10},{40,10}}))); - OpenHPL.Waterway.VolumeFlowSource volumeFlowInput(useInput=true, useFilter= false, fixElevation = true) annotation (Placement(transformation(extent={{-48,-10},{-28,10}}))); + OpenHPL.Waterway.VolumeFlowSource volumeFlowInput(useInput=true, useFilter=false, fixElevation = true) annotation (Placement(transformation(extent={{-48,-10},{-28,10}}))); Modelica.Blocks.Sources.Sine sine(f = 0.01, offset = 1) annotation (Placement(transformation(extent={{-80,-10},{-60,10}}))); - Modelica.Blocks.Sources.CombiTimeTable logdata(table=[1, 1; 2,0.245221436; 3,0.266113698; 4,0.249561667; 5,0.525063097; 6,0.479064316; 7,0.494991362; 8,0.489708632; 9,0.50391084; 10,0.492354929; 11,0.509279788; 12,0.495274216; 13,0.493877858; 14,0.520679474; 15,0.499932915; 16,0.494227827; 17,0.472558141; 18,0.441845328; 19,0.398698032; 20,0.369865984; 21,0.341512531; 22,0.317958236; 23,0.300121665; 24,0.283421665; 25,0.271103382; 26,0.29000932; 27,0.276437521; 28,0.279719085; 29,0.273819894; + Modelica.Blocks.Sources.CombiTimeTable logdata(table=[1,0.256342739; 2,0.245221436; 3,0.266113698; 4,0.249561667; 5,0.525063097; 6,0.479064316; 7,0.494991362; 8,0.489708632; 9,0.50391084; 10,0.492354929; 11,0.509279788; 12,0.495274216; 13,0.493877858; 14,0.520679474; 15,0.499932915; 16,0.494227827; 17,0.472558141; 18,0.441845328; 19,0.398698032; 20,0.369865984; 21,0.341512531; 22,0.317958236; 23,0.300121665; 24,0.283421665; 25,0.271103382; 26,0.29000932; 27,0.276437521; 28,0.279719085; 29,0.273819894; 30,0.530646265; 31,0.494690746; 32,0.668753743; 33,0.748319328; 34,1.156479597; 35,1.622769237; 36,1.455329537; 37,1.440503478; 38,1.388660312; 39,1.321571827; 40,1.428969026; 41,1.335716724; 42,1.240077496; 43,1.147016048; 44,1.046641827; 45,0.957466781; 46,0.877434254; 47,0.760209978; 48,0.685476542; 49,0.611937046; 50,0.5434497; 51,0.486470848; 52,0.437200874; 53,0.387043357; 54,0.346913666; 55,0.321531206; 56,0.3025949; 57,0.289946347; 58,0.76049149; 59,1.301532745; 60,1.66047287; 61, 1.468578339; 62,1.445258141; 63,1.381029367; 64,1.308333635; 65,1.429936647; 66,1.324193954; 67,1.215524554; 68,1.132795691; 69,1.039966226; 70,0.957139969; 71,0.881121516; 72,0.764806509; 73,0.679720461; 74,1.153712869; 75,1.617045045; 76,1.342065096; 77,1.21108222; 78,1.097126365; 79,0.956687152; 80,0.846820831; 81,0.726776063; 82,0.637088716; 83,0.566960931; 84,0; 85,0.081746899; 86,0.287258357; 87,0.440648884; 88,0.623197138; 89,0.745818675; 90,0.877141893; 91,1.14376235; 92,1.091307402; 93,1.166081309; 94,1.204966307; 95,1.155335188; 96,1.090149403; 97,1.023901701; 98,0.955312788; 99,0.895717919; 100,0.781589091; 101,0.711237729; 102,0.642216742; 103,0.592425168; 104,0.53075856; 105,0.470919639; 106,0.424907953; 107,0.379154414; 108,0.341206133; 109,0.313439339; 110,0.291419089; 111,0.282484144], extrapolation=Modelica.Blocks.Types.Extrapolation.HoldLastPoint) annotation (Placement(transformation(extent={{-80,-50},{-60,-30}}))); - Waterway.Pipe pipe3(H=0) annotation (Placement(transformation(extent={{-10,-50},{10,-30}}))); + Waterway.Pipe pipe3(H=0, useInitialEquation=false) annotation (Placement(transformation(extent={{-10,-50},{10,-30}}))); Waterway.Reservoir tail3 annotation (Placement(transformation(extent={{60,-50},{40,-30}}))); Waterway.VolumeFlowSource volumeFlowFiltered(useInput=true, useFilter=true, fixElevation = true) annotation (Placement(transformation(extent={{-48,-50},{-28,-30}}))); equation @@ -27,5 +27,5 @@ equation connect(pipe3.o,tail3. o) annotation (Line(points={{10,-40},{40,-40}}, color={0,128,255})); connect(volumeFlowFiltered.outFlow, logdata.y[1]) annotation (Line(points={{-50,-40},{-59,-40}}, color={0,0,127})); - annotation (experiment(StopTime = 120, StartTime = 0, Tolerance = 1e-06, Interval = 0.24)); + annotation (experiment(StopTime=120)); end VolumeFlowSource; \ No newline at end of file diff --git a/OpenHPL/Waterway/Pipe.mo b/OpenHPL/Waterway/Pipe.mo index 2b6a5d5..69b9881 100644 --- a/OpenHPL/Waterway/Pipe.mo +++ b/OpenHPL/Waterway/Pipe.mo @@ -32,6 +32,8 @@ model Pipe "Model of a pipe" // Steady state: parameter Boolean SteadyState=data.SteadyState "If true, starts in steady state" annotation (Dialog(group="Initialization")); parameter SI.VolumeFlowRate Vdot_0=data.Vdot_0 "Initial flow rate of the pipe" annotation (Dialog(group="Initialization")); + parameter Boolean useInitialEquation=true "If false, skip initial equation for flow (e.g., when flow is imposed by a source)" + annotation (Dialog(group="Initialization"), choices(checkBox=true)); SI.Velocity v "Average Water velocity"; SI.Force F_f "Friction force"; @@ -56,10 +58,12 @@ protected parameter Modelica.Units.NonSI.Angle_deg phi = Modelica.Units.Conversions.to_deg(Modelica.Math.atan((abs(D_i-D_o)/(2*L)))) "Cone half angle"; initial equation - if SteadyState then - der(mdot) = 0; - else - Vdot=Vdot_0; + if useInitialEquation then + if SteadyState then + der(mdot) = 0; + else + Vdot=Vdot_0; + end if; end if; algorithm assert( phi < 1.0, "Change in pipe diameter is too large. (angle= "+String(phi)+" )",AssertionLevel.warning); From 6e658377d1418a254b1ad622eec56be2bdb42e43 Mon Sep 17 00:00:00 2001 From: Dietmar Winkler Date: Mon, 13 Apr 2026 07:49:07 +0200 Subject: [PATCH 2/2] Add documentation and change name. --- OpenHPL/Examples/VolumeFlowSource.mo | 6 +++--- OpenHPL/Waterway/Pipe.mo | 11 +++++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/OpenHPL/Examples/VolumeFlowSource.mo b/OpenHPL/Examples/VolumeFlowSource.mo index 5ae0c71..141c03b 100644 --- a/OpenHPL/Examples/VolumeFlowSource.mo +++ b/OpenHPL/Examples/VolumeFlowSource.mo @@ -4,8 +4,8 @@ model VolumeFlowSource "Example demonstrating the use of VolumeFlowSource" OpenHPL.Waterway.Reservoir tail1 annotation (Placement(transformation(extent={{60,30},{40,50}}))); inner OpenHPL.Data data(SteadyState = true) annotation (Placement(transformation(extent={{-100,80},{-80,100}}))); OpenHPL.Waterway.VolumeFlowSource volumeFlowConstant(fixElevation = true) annotation (Placement(transformation(extent={{-50,30},{-30,50}}))); - Waterway.Pipe pipe1(H=0, useInitialEquation=false) annotation (Placement(transformation(extent={{-10,30},{10,50}}))); - Waterway.Pipe pipe2(H=0, useInitialEquation=false) annotation (Placement(transformation(extent={{-10,-10},{10,10}}))); + Waterway.Pipe pipe1(H=0, useInitialFlow=false) annotation (Placement(transformation(extent={{-10,30},{10,50}}))); + Waterway.Pipe pipe2(H=0, useInitialFlow=false) annotation (Placement(transformation(extent={{-10,-10},{10,10}}))); OpenHPL.Waterway.Reservoir tail2 annotation (Placement(transformation(extent={{60,-10},{40,10}}))); OpenHPL.Waterway.VolumeFlowSource volumeFlowInput(useInput=true, useFilter=false, fixElevation = true) annotation (Placement(transformation(extent={{-48,-10},{-28,10}}))); Modelica.Blocks.Sources.Sine sine(f = 0.01, offset = 1) annotation (Placement(transformation(extent={{-80,-10},{-60,10}}))); @@ -14,7 +14,7 @@ model VolumeFlowSource "Example demonstrating the use of VolumeFlowSource" 1.468578339; 62,1.445258141; 63,1.381029367; 64,1.308333635; 65,1.429936647; 66,1.324193954; 67,1.215524554; 68,1.132795691; 69,1.039966226; 70,0.957139969; 71,0.881121516; 72,0.764806509; 73,0.679720461; 74,1.153712869; 75,1.617045045; 76,1.342065096; 77,1.21108222; 78,1.097126365; 79,0.956687152; 80,0.846820831; 81,0.726776063; 82,0.637088716; 83,0.566960931; 84,0; 85,0.081746899; 86,0.287258357; 87,0.440648884; 88,0.623197138; 89,0.745818675; 90,0.877141893; 91,1.14376235; 92,1.091307402; 93,1.166081309; 94,1.204966307; 95,1.155335188; 96,1.090149403; 97,1.023901701; 98,0.955312788; 99,0.895717919; 100,0.781589091; 101,0.711237729; 102,0.642216742; 103,0.592425168; 104,0.53075856; 105,0.470919639; 106,0.424907953; 107,0.379154414; 108,0.341206133; 109,0.313439339; 110,0.291419089; 111,0.282484144], extrapolation=Modelica.Blocks.Types.Extrapolation.HoldLastPoint) annotation (Placement(transformation(extent={{-80,-50},{-60,-30}}))); - Waterway.Pipe pipe3(H=0, useInitialEquation=false) annotation (Placement(transformation(extent={{-10,-50},{10,-30}}))); + Waterway.Pipe pipe3(H=0, useInitialFlow=false) annotation (Placement(transformation(extent={{-10,-50},{10,-30}}))); Waterway.Reservoir tail3 annotation (Placement(transformation(extent={{60,-50},{40,-30}}))); Waterway.VolumeFlowSource volumeFlowFiltered(useInput=true, useFilter=true, fixElevation = true) annotation (Placement(transformation(extent={{-48,-50},{-28,-30}}))); equation diff --git a/OpenHPL/Waterway/Pipe.mo b/OpenHPL/Waterway/Pipe.mo index 69b9881..3b88d2b 100644 --- a/OpenHPL/Waterway/Pipe.mo +++ b/OpenHPL/Waterway/Pipe.mo @@ -32,7 +32,7 @@ model Pipe "Model of a pipe" // Steady state: parameter Boolean SteadyState=data.SteadyState "If true, starts in steady state" annotation (Dialog(group="Initialization")); parameter SI.VolumeFlowRate Vdot_0=data.Vdot_0 "Initial flow rate of the pipe" annotation (Dialog(group="Initialization")); - parameter Boolean useInitialEquation=true "If false, skip initial equation for flow (e.g., when flow is imposed by a source)" + parameter Boolean useInitialFlow=true "If false, skip initial equation for flow (e.g., when flow is imposed by a source)" annotation (Dialog(group="Initialization"), choices(checkBox=true)); SI.Velocity v "Average Water velocity"; @@ -58,7 +58,7 @@ protected parameter Modelica.Units.NonSI.Angle_deg phi = Modelica.Units.Conversions.to_deg(Modelica.Math.atan((abs(D_i-D_o)/(2*L)))) "Cone half angle"; initial equation - if useInitialEquation then + if useInitialFlow then if SteadyState then der(mdot) = 0; else @@ -138,6 +138,13 @@ These are then converted using: p_eps = D_h·3.097·e(-0.118/n) empir

The conversions are simplified for hydropower applications assuming fully turbulent flow, so they depend only on fixed pipe dimensions and the chosen friction coefficient.

+
Initialization
+

By default, the pipe provides an initial equation for the flow rate: either der(mdot) = 0 +(steady state) or Vdot = Vdot_0. When the pipe is connected to a component that already +imposes the flow (e.g., VolumeFlowSource), these initial equations become redundant and may +cause an over-determined initialization problem in some tools (e.g., Dymola). Set +useInitialFlow = false to disable the initial equation in such cases.

+
More Information

More info about the pipe model can be found in [Vytvytskyi2017]