Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Ordered nuclear examples into subpackages called with power plant system names, [PR#219](https://github.com/Metroscope-dev/metroscope-modeling-library/pull/219)

### Added <!--Make sure to add a link to the PR and issues related to your change-->
- Added `LMTDHeatExchange`function, `LMTDfuelHeater`component and reverse unit test. [PR #266](https://github.com/Metroscope-dev/metroscope-modeling-library/pull/266)
- Added`HXmoistAirWater` component and reverse unit test, [PR #250](https://github.com/Metroscope-dev/metroscope-modeling-library/pull/250)
- Added flue gases enthalpy start value to `hrsg_monophasic_HX`, [PR #264](https://github.com/Metroscope-dev/metroscope-modeling-library/pull/264)
- Added `mass_flow_rate_bias` fault in `BaseSensor`, to be able to declare faulty `FlowSensor` [PR #245](https://github.com/Metroscope-dev/metroscope-modeling-library/pull/245)
Expand Down
9 changes: 9 additions & 0 deletions MetroscopeModelingLibrary/FlueGases/Pipes/HeatLoss.mo
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
within MetroscopeModelingLibrary.FlueGases.Pipes;
model HeatLoss
package FlueGasesMedium = MetroscopeModelingLibrary.Media.FlueGasesMedium;
extends Partial.Pipes.HeatLoss(
redeclare MetroscopeModelingLibrary.FlueGases.Connectors.Inlet C_in,
redeclare MetroscopeModelingLibrary.FlueGases.Connectors.Outlet C_out,
redeclare package Medium = FlueGasesMedium)
annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(coordinateSystem(preserveAspectRatio=false)));
end HeatLoss;
1 change: 1 addition & 0 deletions MetroscopeModelingLibrary/FlueGases/Pipes/package.order
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
Pipe
Filter
HeatLoss
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ model FuelHeater
// Initialization parameters
parameter Units.MassFlowRate Q_cold_0 = 500;
parameter Units.MassFlowRate Q_hot_0 = 50;
parameter Units.Temperature T_cold_in_0 = 76 + 273.15;
parameter Units.Pressure P_cold_in_0 = 18 *1e5;
parameter Units.Temperature T_hot_in_0 = 76 + 273.15;
parameter Units.Pressure P_hot_in_0 = 18 *1e5;

Fuel.Connectors.Inlet C_cold_in annotation (Placement(transformation(extent={{-80,-10},{-60,10}}), iconTransformation(extent={{-80,-10},{-60,10}})));
Fuel.Connectors.Outlet C_cold_out annotation (Placement(transformation(extent={{60,-10},{80,10}}), iconTransformation(extent={{60,-10},{80,10}})));
Expand All @@ -39,18 +39,18 @@ model FuelHeater
Power.HeatExchange.NTUHeatExchange HX(
config=HX_config,
QCp_max_side=QCp_max_side,
T_cold_in_0=T_cold_in_0) annotation (Placement(transformation(
T_hot_in_0=T_hot_in_0) annotation (Placement(transformation(
extent={{-10,10},{10,-10}},
rotation=0,
origin={10,14})));
WaterSteam.BaseClasses.IsoPFlowModel hot_side(
Q_0=Q_cold_0,
T_in_0=T_cold_in_0,
P_in_0=P_cold_in_0) annotation (Placement(transformation(
Q_0=Q_hot_0,
T_in_0=T_hot_in_0,
P_in_0=P_hot_in_0) annotation (Placement(transformation(
extent={{10,10},{-10,-10}},
rotation=0,
origin={10,28})));
WaterSteam.Pipes.Pipe hot_side_pipe(Q_0=Q_cold_0, T_in_0=T_cold_in_0) annotation (Placement(transformation(
WaterSteam.Pipes.Pipe hot_side_pipe(Q_0=Q_hot_0, T_in_0=T_hot_in_0) annotation (Placement(transformation(
extent={{10,-10},{-10,10}},
rotation=90,
origin={-14,-24})));
Expand Down
106 changes: 106 additions & 0 deletions MetroscopeModelingLibrary/MultiFluid/HeatExchangers/LMTDFuelHeater.mo
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
within MetroscopeModelingLibrary.MultiFluid.HeatExchangers;
model LMTDFuelHeater

extends MetroscopeModelingLibrary.Icons.KeepingScaleIcon;
package WaterSteamMedium = MetroscopeModelingLibrary.Media.WaterSteamMedium;
package FuelMedium = MetroscopeModelingLibrary.Media.FuelMedium;
import MetroscopeModelingLibrary.Units;
import MetroscopeModelingLibrary.Units.Inputs;

// Pressure Losses
Inputs.InputFrictionCoefficient Kfr_cold;
Inputs.InputFrictionCoefficient Kfr_hot;

// Heating
Inputs.InputArea S;
Inputs.InputHeatExchangeCoefficient Kth;
Units.Power W;

// Definitions
Units.MassFlowRate Q_cold;
Units.MassFlowRate Q_hot;
Units.Temperature T_cold_in;
Units.Temperature T_cold_out;
Units.Temperature T_hot_in;
Units.Temperature T_hot_out;

// Initialization parameters
parameter Units.MassFlowRate Q_cold_0 = 12;
parameter Units.MassFlowRate Q_hot_0 = 8.6;
parameter Units.Temperature T_cold_in_0 = 29.5 + 273.15;
parameter Units.Temperature T_hot_in_0 = 230 +273.15;
parameter Units.Pressure P_cold_in_0 = 29.7 *1e5;
parameter Units.Pressure P_hot_in_0 = 47 *1e5;
parameter Real h_hot_in_0 = 2e4;
parameter Real h_hot_out_0 = 1e4;
parameter Real h_cold_in_0 = 6e5;
parameter Real h_cold_out_0 = 1e6;

Power.HeatExchange.LMTDHeatExchange HX(
T_cold_in_0=T_cold_in_0) annotation (Placement(transformation(
extent={{-10,10},{10,-10}},
rotation=0,
origin={10,14})));
WaterSteam.BaseClasses.IsoPFlowModel hot_side(
Q_0=Q_hot_0,
T_in_0=T_hot_in_0,
P_in_0=P_hot_in_0,
h_in_0 = h_hot_in_0) annotation (Placement(transformation(
extent={{10,10},{-10,-10}},
rotation=0,
origin={10,28})));
WaterSteam.Pipes.Pipe hot_side_pipe(Q_0=Q_hot_0, T_in_0=T_hot_in_0,h_0=h_hot_in_0) annotation (Placement(transformation(
extent={{10,-10},{-10,10}},
rotation=90,
origin={-14,-24})));
Fuel.Pipes.Pipe cold_side_pipe(h_0=h_cold_in_0) annotation (Placement(transformation(extent={{-52,-10},{-32,10}})));
Fuel.BaseClasses.IsoPFlowModel cold_side(h_in_0 = h_cold_in_0) annotation (Placement(transformation(extent={{0,-10},{20,10}})));
Fuel.Connectors.Inlet C_cold_in annotation (Placement(transformation(extent={{-80,-10},{-60,10}}), iconTransformation(extent={{-80,-10},{-60,10}})));
Fuel.Connectors.Outlet C_cold_out(h_outflow(start=h_cold_out_0)) annotation (Placement(transformation(extent={{60,-10},{80,10}}), iconTransformation(extent={{60,-10},{80,10}})));
WaterSteam.Connectors.Inlet C_hot_in annotation (Placement(transformation(extent={{30,60},{50,80}}), iconTransformation(extent={{30,60},{50,80}})));
WaterSteam.Connectors.Outlet C_hot_out(h_outflow(start=h_hot_out_0)) annotation (Placement(transformation(extent={{-50,-80},{-30,-60}}),
iconTransformation(extent={{-50,-80},{-30,-60}})));
equation
// Definitions
Q_cold = cold_side.Q;
Q_hot = hot_side.Q;
T_cold_in = cold_side.T_in;
T_cold_out = cold_side.T_out;
T_hot_in = hot_side.T_in;
T_hot_out = hot_side.T_out;
cold_side.W = W;

// Energy balance
hot_side.W + cold_side.W = 0;

// Pressure losses
cold_side_pipe.delta_z = 0;
cold_side_pipe.Kfr = Kfr_cold;
hot_side_pipe.delta_z = 0;
hot_side_pipe.Kfr = Kfr_hot;

// Power Exchange
HX.W = W;
HX.S = S;
HX.Kth = Kth;
HX.T_cold_in = T_cold_in;
HX.T_hot_in = T_hot_in;
HX.T_cold_out = T_cold_out;
HX.T_hot_out = T_hot_out;
connect(hot_side_pipe.C_out,C_hot_out) annotation (Line(points={{-14,-34},{-14,-70},{-40,-70}}, color={28,108,200}));
connect(hot_side_pipe.C_in,hot_side. C_out) annotation (Line(points={{-14,-14},{-14,28},{0,28}},color={28,108,200}));
connect(hot_side.C_in,C_hot_in) annotation (Line(points={{20,28},{40,28},{40,70}}, color={28,108,200}));
connect(cold_side_pipe.C_in,C_cold_in) annotation (Line(points={{-52,0},{-70,0}}, color={213,213,0}));
connect(cold_side_pipe.C_out,cold_side. C_in) annotation (Line(points={{-32,0},{0,0}}, color={213,213,0}));
connect(cold_side.C_out,C_cold_out) annotation (Line(points={{20,0},{70,0}}, color={213,213,0}));
annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
Rectangle(
extent={{-70,50},{70,-50}},
lineColor={0,0,0},
fillColor={226,230,140},
fillPattern=FillPattern.Solid), Line(
points={{40,66},{40,-60},{20,-60},{20,64},{0,64},{0,-60},{-20,-60},{-20,65.6309},{-40,66},{-40,-66}},
color={28,108,200},
thickness=1,
smooth=Smooth.Bezier)}), Diagram(coordinateSystem(preserveAspectRatio=false)));
end LMTDFuelHeater;
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ Economiser
Superheater
Evaporator
FuelHeater
LMTDFuelHeater
HXmoistAirWater
LMTDFuelHeater
54 changes: 54 additions & 0 deletions MetroscopeModelingLibrary/Power/HeatExchange/LMTDHeatExchange.mo
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
within MetroscopeModelingLibrary.Power.HeatExchange;
model LMTDHeatExchange
import MetroscopeModelingLibrary.Units.Inputs;
import MetroscopeModelingLibrary.Units;

// Initialization parameters
parameter Units.Temperature T_hot_in_0 = 273.15 + 200 "Init parameter for Hot mass flow rate at the inlet";
parameter Units.Temperature T_cold_in_0 = 273.15 + 100 "Init parameter for Cold mass flow rate at the inlet";
parameter Units.Temperature T_hot_out_0 = 273.15 + 200 "Init parameter for Hot mass flow rate at the outlet";
parameter Units.Temperature T_cold_out_0 = 273.15 + 100 "Init parameter for Cold mass flow rate at the outlet";

/* Exchanger configuration and parameters */
//parameter String config = "LMTD_monophasic_counter_current"; No need for parameter as long as there is only one configuration !!
Inputs.InputArea S(start=100) "Heat exchange surface";
Inputs.InputHeatExchangeCoefficient Kth(start=1900) "Heat exchange coefficient";

/* Exchanger output */
Units.Power W(start=1e4);

/* Exchanger boundary conditions */
Inputs.InputTemperature T_hot_in(start=T_hot_in_0) "Temperature, hot side, at the inlet";
Inputs.InputTemperature T_cold_in(start=T_cold_in_0) "Temperature, cold side, at the inlet";
Inputs.InputTemperature T_hot_out(start=T_hot_out_0) "Temperature, hot side, at the outlet";
Inputs.InputTemperature T_cold_out(start=T_cold_out_0) "Temperature, cold side, at the outlet";

// intermediate variables
Units.DifferentialTemperature dT_a(start = 15);
Units.DifferentialTemperature dT_b(start=1);
equation

dT_a = T_hot_in - T_cold_out;
dT_b = T_hot_out - T_cold_in;

// Log mean equation written in an exponential way
0 = - dT_a + dT_b * exp(Kth*S*(dT_a - dT_b)/W);


annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
Polygon(
points={{-66,-72},{-48,-72},{-48,-66},{-50,-54},{-54,-44},{-58,-34},{-60,-28},{-60,-16},{-60,-8},{-54,8},{-52,12},{-50,20},{-48,30},{-48,36},{-32,36},{-56,68},{-56,68},{-80,36},{-64,36},{-64,30},{-66,24},{-68,16},{-72,8},{-74,2},{-76,-6},{-76,-16},{-76,-28},{-74,-36},{-70,-48},{-66,-58},{-66,-72}},
lineColor={255,170,255},
fillColor={255,170,255},
fillPattern=FillPattern.Solid),
Polygon(
points={{-10,-72},{8,-72},{8,-66},{6,-54},{2,-44},{-2,-34},{-4,-28},{-4,-16},{-4,-8},{2,8},{4,12},{6,20},{8,30},{8,36},{24,36},{0,68},{0,68},{-24,36},{-8,36},{-8,30},{-10,24},{-12,16},{-16,8},{-18,2},{-20,-6},{-20,-16},{-20,-28},{-18,-36},{-14,-48},{-10,-58},{-10,-72}},
lineColor={255,170,255},
fillColor={255,170,255},
fillPattern=FillPattern.Solid),
Polygon(
points={{48,-72},{66,-72},{66,-66},{64,-54},{60,-44},{56,-34},{54,-28},{54,-16},{54,-8},{60,8},{62,12},{64,20},{66,30},{66,36},{82,36},{58,68},{58,68},{34,36},{50,36},{50,30},{48,24},{46,16},{42,8},{40,2},{38,-6},{38,-16},{38,-28},{40,-36},{44,-48},{48,-58},{48,-72}},
lineColor={255,170,255},
fillColor={255,170,255},
fillPattern=FillPattern.Solid)}), Diagram(coordinateSystem(preserveAspectRatio=false)));
end LMTDHeatExchange;
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,13 @@ equation
/* QCpMAX is associated to the mixed fluid, shell side, considered as hot side */
QCpMAX = Q_hot*Cp_hot;
QCpMIN = Q_cold*Cp_cold;
assert(QCpMIN < QCpMAX, "QCPMIN is higher than QCpMAX", AssertionLevel.error);
assert(QCpMIN < QCpMAX, "QCPMIN is higher than QCpMAX", AssertionLevel.warning);
epsilon = (1 - exp(-Cr*(1 - exp(-NTU))))/Cr;
else
/* QCpMAX is associated to the unmixed fluid, tube side, considered as cold side */
QCpMIN = Q_hot*Cp_hot;
QCpMAX = Q_cold*Cp_cold;
assert(QCpMIN < QCpMAX, "QCPMIN is higher than QCpMAX", AssertionLevel.error);
assert(QCpMIN < QCpMAX, "QCPMIN is higher than QCpMAX", AssertionLevel.warning);
epsilon = 1 - exp(-(1 - exp(-Cr*NTU))/Cr);
end if;

Expand Down
1 change: 1 addition & 0 deletions MetroscopeModelingLibrary/Power/HeatExchange/package.order
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
NTUHeatExchange
LMTDHeatExchange
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ within MetroscopeModelingLibrary.Tests.Multifluid.HeatExchangers;
model FuelHeater_reverse
extends MetroscopeModelingLibrary.Icons.Tests.MultifluidTestIcon;
// Boundary conditions
input Real P_hot_source(start=20, min=0, nominal=10) "barA";
input Units.MassFlowRate Q_hot_source(start=50) "kg/s";
input Real T_hot_source(start=50) "J/kg";
input Real P_hot_source(start=47, min=0, nominal=10) "barA";
input Units.MassFlowRate Q_hot_source(start=8) "kg/s";
input Real T_hot_source(start=230) "J/kg";

input Real P_cold_source(start=20, min=0, nominal=10) "barA";
input Units.MassFlowRate Q_cold_source(start=100) "kg/s";
//input Real T_cold_source(start = 50, min = 0, nominal = 50) "degC";
input Units.SpecificEnthalpy h_cold_source(start=1e6) "J/kg";
input Real P_cold_source(start=30, min=0, nominal=10) "barA";
input Units.MassFlowRate Q_cold_source(start=12) "kg/s";
input Real T_cold_source(start = 30, min = 0, nominal = 50) "degC";
//input Units.SpecificEnthalpy h_cold_source(start=1e6) "J/kg";
// Parameters
parameter String QCp_max_side = "hot";
parameter Units.Area S = 100;
Expand All @@ -20,38 +20,39 @@ model FuelHeater_reverse
output Units.FrictionCoefficient Kfr_cold;

// Calibration inputs
input Real P_cold_out(start = 19, min= 0, nominal = 10) "barA"; // Outlet pressure on cold side, to calibrate Kfr cold
input Real P_hot_out(start = 50, min = 0, nominal = 10) "barA"; // Outlet pressure on hot side, to calibrate Kfr hot
input Real T_hot_out(start = 55, min = 0, nominal = 100) "degC"; // Outlet temperature on cold side, to calibrate Kth
input Real P_cold_out(start = 30, min= 0, nominal = 10) "barA"; // Outlet pressure on cold side, to calibrate Kfr cold
input Real P_hot_out(start = 47, min = 0, nominal = 10) "barA"; // Outlet pressure on hot side, to calibrate Kfr hot
input Real T_hot_out(start = 80, min = 0, nominal = 100) "degC"; // Outlet temperature on cold side, to calibrate Kth
//input Real T_cold_out(start = 200, nominal = 200)"degC";

MultiFluid.HeatExchangers.FuelHeater fuelHeater(QCp_max_side = QCp_max_side) annotation (Placement(transformation(extent={{-38,-34},{38,34}})));
MetroscopeModelingLibrary.WaterSteam.BoundaryConditions.Source hot_source annotation (Placement(transformation(
extent={{-10,-10},{10,10}},
rotation=270,
origin={12,50})));
origin={14,50})));
MetroscopeModelingLibrary.WaterSteam.BoundaryConditions.Sink hot_sink annotation (Placement(transformation(
extent={{-10,-10},{10,10}},
rotation=90,
origin={-12,90})));
rotation=270,
origin={-16,-88})));
MetroscopeModelingLibrary.Fuel.BoundaryConditions.Source cold_source annotation (Placement(transformation(extent={{-66,-10},{-46,10}})));
MetroscopeModelingLibrary.Fuel.BoundaryConditions.Sink cold_sink annotation (Placement(transformation(extent={{74,-10},{94,10}})));
MetroscopeModelingLibrary.Sensors.Fuel.PressureSensor P_cold_out_sensor annotation (Placement(transformation(extent={{46,-10},{66,10}})));
MetroscopeModelingLibrary.Sensors.WaterSteam.TemperatureSensor T_hot_out_sensor annotation (Placement(transformation(
extent={{-10,-10},{10,10}},
rotation=90,
origin={-12,42})));
rotation=270,
origin={-16,-40})));
MetroscopeModelingLibrary.Sensors.WaterSteam.PressureSensor P_hot_out_sensor annotation (Placement(transformation(
extent={{-10,-10},{10,10}},
rotation=90,
origin={-12,68})));
rotation=270,
origin={-16,-66})));
equation
// Boundary conditions
hot_source.P_out = P_hot_source * 1e5;
hot_source.T_out = T_hot_source;
hot_source.T_out = T_hot_source+273.15;
hot_source.Q_out = - Q_hot_source;
cold_source.P_out = P_cold_source *1e5;
//cold_source.T_out = 273.15 + T_cold_source;
cold_source.h_out = h_cold_source;
cold_source.T_out = 273.15 + T_cold_source;
//cold_source.h_out = h_cold_source;
cold_source.Q_out = - Q_cold_source;
cold_source.Xi_out = {0.92,0.048,0.005,0.002,0.015,0.01};

Expand All @@ -60,6 +61,7 @@ equation

// Inputs for calibration
T_hot_out_sensor.T_degC = T_hot_out;
//cold_sink.T_in = T_cold_out +273.15;
P_cold_out_sensor.P_barA = P_cold_out;
P_hot_out_sensor.P_barA = P_hot_out;

Expand All @@ -68,12 +70,15 @@ equation
fuelHeater.Kfr_hot = Kfr_hot;
fuelHeater.Kfr_cold = Kfr_cold;

connect(fuelHeater.C_hot_in, hot_source.C_out) annotation (Line(points={{15.2,23.8},{12,23.8},{12,45}}, color={28,108,200}));
connect(fuelHeater.C_hot_in, hot_source.C_out) annotation (Line(points={{15.2,23.8},{14,23.8},{14,45}}, color={28,108,200}));
connect(fuelHeater.C_cold_in, cold_source.C_out) annotation (Line(points={{-26.6,0},{-51,0}}, color={213,213,0}));
connect(fuelHeater.C_cold_out, P_cold_out_sensor.C_in) annotation (Line(points={{26.6,0},{46,0}}, color={213,213,0}));
connect(cold_sink.C_in, P_cold_out_sensor.C_out) annotation (Line(points={{79,0},{66,0}}, color={213,213,0}));
connect(fuelHeater.C_hot_out, T_hot_out_sensor.C_in) annotation (Line(points={{-15.2,-23.8},{-15.2,27.9},{-12,27.9},{-12,32}},color={28,108,200}));
connect(T_hot_out_sensor.C_out, P_hot_out_sensor.C_in) annotation (Line(points={{-12,52},{-12,58}}, color={28,108,200}));
connect(hot_sink.C_in, P_hot_out_sensor.C_out) annotation (Line(points={{-12,85},{-12,78}}, color={28,108,200}));
connect(fuelHeater.C_hot_out, T_hot_out_sensor.C_in) annotation (Line(points={{-15.2,-23.8},{-15.2,-26.9},{-16,-26.9},{-16,-30}},
color={28,108,200}));
connect(T_hot_out_sensor.C_out, P_hot_out_sensor.C_in) annotation (Line(points={{-16,-50},{-16,-53},{-16,-53},{-16,-56}},
color={28,108,200}));
connect(hot_sink.C_in, P_hot_out_sensor.C_out) annotation (Line(points={{-16,-83},{-16,-76}},
color={28,108,200}));
annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(coordinateSystem(preserveAspectRatio=false)));
end FuelHeater_reverse;
Loading