within ;
package LAES "Simulation components for an LAES plant"
package Connectors "Connectors for LAES"
connector Flange "Flange connector for water/steam flows"
replaceable package Medium = ThermoPower.Water.StandardWater constrainedby
Modelica.Media.Interfaces.PartialMedium "Medium model";
flow Medium.MassFlowRate m_flow
"Mass flow rate from the connection point into the component";
Medium.AbsolutePressure p "Thermodynamic pressure in the connection point";
stream Medium.SpecificEnthalpy T_outflow
"Temperature close to the connection point if m_flow < 0";
stream Medium.MassFraction Xi_outflow[Medium.nXi]
"Independent mixture mass fractions m_i/m close to the connection point if m_flow < 0";
stream Medium.ExtraProperty C_outflow[Medium.nC]
"Properties c_i/m close to the connection point if m_flow < 0";
annotation (
Documentation(info=".
", revisions="
"),
Diagram(graphics),
Icon(graphics));
end Flange;
model HT_DHTNodes "HT to DHT adaptor"
parameter Integer N=1 "Number of nodes on DHT side";
parameter Modelica.SIunits.Area exchangeSurface
"Area of heat transfer surface";
ThermoPower.Thermal.HT HT_port annotation (Placement(transformation(extent={{-140,
-16},{-100,24}}, rotation=0)));
ThermoPower.Thermal.DHTNodes DHT_port(N=N) annotation (Placement(transformation(
extent={{100,-40},{120,40}}, rotation=0)));
equation
for i in 1:N loop
DHT_port.T[i] = HT_port.T "Uniform temperature distribution on DHT side";
end for;
if N == 1 then
// Uniform flow distribution
DHT_port.phi[1]*exchangeSurface + HT_port.Q_flow = 0 "Energy balance";
else
// Piecewise linear flow distribution
sum(DHT_port.phi[1:N - 1] + DHT_port.phi[2:N])/2*exchangeSurface/(N - 1)
+ HT_port.Q_flow = 0 "Energy balance";
end if;
annotation (Icon(graphics={
Polygon(
points={{-100,100},{-100,-100},{100,100},{-100,100}},
lineColor={185,0,0},
fillColor={185,0,0},
fillPattern=FillPattern.Solid),
Polygon(
points={{100,100},{100,-100},{-100,-100},{100,100}},
lineColor={255,128,0},
fillColor={255,128,0},
fillPattern=FillPattern.Solid),
Text(
extent={{-74,10},{24,88}},
lineColor={255,255,255},
lineThickness=1,
textString="HT"),
Text(
extent={{-16,-84},{82,-6}},
lineColor={255,255,255},
lineThickness=1,
textString="DHT"),
Rectangle(
extent={{-100,100},{100,-100}},
lineColor={0,0,0},
pattern=LinePattern.None)}));
end HT_DHTNodes;
model ConvHT "1D Convective heat transfer"
extends ThermoPower.Icons.HeatFlow;
parameter Integer N=2 "Number of Nodes";
parameter Modelica.SIunits.CoefficientOfHeatTransfer gamma
"Constant heat transfer coefficient";
ThermoPower.Thermal.DHTNodes side1(N=N) annotation (Placement(transformation(
extent={{-40,20},{40,40}}, rotation=0)));
ThermoPower.Thermal.DHTNodes side2(N=N) annotation (Placement(transformation(
extent={{-40,-42},{40,-20}}, rotation=0)));
equation
side1.phi = gamma*(side1.T - side2.T) "Convective heat transfer";
side1.phi = -side2.phi "Energy balance";
annotation (Icon(graphics={Text(
extent={{-100,-44},{100,-68}},
lineColor={191,95,0},
textString="%name")}), Documentation(info="
Model of a simple convective heat transfer mechanism between two 1D objects, with a constant heat transfer coefficient.
Node j on side 1 interacts with node j on side 2.
", revisions="
1 Oct 2003
by Francesco Casella:
First release.
"));
end ConvHT;
model HT_DHTVolumes "HT to DHT adaptor"
parameter Integer N=1 "Number of nodes on DHT side";
parameter Modelica.SIunits.Area exchangeSurface
"Area of heat transfer surface";
ThermoPower.Thermal.HT HT_port annotation (Placement(transformation(extent={{-140,
-16},{-100,24}}, rotation=0)));
ThermoPower.Thermal.DHTVolumes DHT_port(N=N) annotation (Placement(transformation(
extent={{100,-40},{120,40}}, rotation=0)));
equation
for i in 1:N loop
DHT_port.T[i] = HT_port.T "Uniform temperature distribution on DHT side";
end for;
if N == 1 then
// Uniform flow distribution
DHT_port.phi[1]*exchangeSurface + HT_port.Q_flow = 0 "Energy balance";
else
// Piecewise linear flow distribution
sum(DHT_port.phi[1:N - 1] + DHT_port.phi[2:N])/2*exchangeSurface/(N - 1)
+ HT_port.Q_flow = 0 "Energy balance";
end if;
annotation (Icon(graphics={
Polygon(
points={{-100,100},{-100,-100},{100,100},{-100,100}},
lineColor={185,0,0},
fillColor={185,0,0},
fillPattern=FillPattern.Solid),
Polygon(
points={{100,100},{100,-100},{-100,-100},{100,100}},
lineColor={255,128,0},
fillColor={255,128,0},
fillPattern=FillPattern.Solid),
Text(
extent={{-74,10},{24,88}},
lineColor={255,255,255},
lineThickness=1,
textString="HT"),
Text(
extent={{-16,-84},{82,-6}},
lineColor={255,255,255},
lineThickness=1,
textString="DHT"),
Rectangle(
extent={{-100,100},{100,-100}},
lineColor={0,0,0},
pattern=LinePattern.None)}), Diagram(graphics));
end HT_DHTVolumes;
model Flow1DFEM_New
"1-dimensional fluid flow model for water/steam (finite elements) with new nodal distributed heat terminal"
extends ThermoPower.Water.BaseClasses.Flow1DBase;
replaceable ThermoPower.Thermal.DHTNodes wall(N=N) annotation (Dialog(enable=
false), Placement(transformation(extent={{-40,40},{40,60}},
rotation=0)));
import Modelica.Math.*;
import ThermoPower.Choices.Flow1D.FFtypes;
import ThermoPower.Choices.Flow1D.HCtypes;
Medium.ThermodynamicState fluidState[N]
"Thermodynamic state of the fluid at the nodes";
parameter Real alpha(
min=0,
max=1) = 1 "Numerical stabilization coefficient";
parameter Real ML(
min=0,
max=1) = 0 "Mass Lumping Coefficient";
parameter Real wnf_bc=0.01
"Fraction of the nominal total mass flow rate for FEM regularization";
constant Real g=Modelica.Constants.g_n;
final parameter Boolean evenN=(div(N, 2)*2 == N)
"The number of nodes is even";
Modelica.SIunits.Length omega_hyd "Hydraulic perimeter (single tube)";
Real Kf[N] "Friction coefficients";
Real Cf[N] "Fanning friction factors";
Real dwdt "Dynamic momentum term";
Medium.AbsolutePressure p(start=pstart) "Fluid pressure";
Modelica.SIunits.Pressure Dpfric "Pressure drop due to friction (total)";
Modelica.SIunits.Pressure Dpfric1
"Pressure drop due to friction (from inlet to capacitance)";
Modelica.SIunits.Pressure Dpfric2
"Pressure drop due to friction (from capacitance to outlet)";
Modelica.SIunits.Pressure Dpstat "Pressure drop due to static head";
Modelica.SIunits.MassFlowRate w[N](each start=wnom/Nt)
"Mass flowrate (single tube)";
Modelica.SIunits.Velocity u[N] "Fluid velocity";
Modelica.SIunits.HeatFlux phi[N] "External heat flux";
Medium.Temperature T[N] "Fluid temperature";
Medium.SpecificEnthalpy h[N](start=hstart) "Fluid specific enthalpy";
Medium.Density rho[N] "Fluid density";
Modelica.SIunits.SpecificVolume v[N] "Fluid specific volume";
Modelica.SIunits.Mass Mtot "Total mass of fluid";
protected
Modelica.SIunits.DerDensityByEnthalpy drdh[N]
"Derivative of density by enthalpy";
Modelica.SIunits.DerDensityByPressure drdp[N]
"Derivative of density by pressure";
Real Y[N, N];
Real M[N, N];
Real D[N];
Real D1[N];
Real D2[N];
Real G[N];
Real B[N, N];
Real C[N, N];
Real K[N, N];
Real alpha_sgn;
Real YY[N, N];
equation
//All equations are referred to a single tube
// Selection of representative pressure variable
if HydraulicCapacitance == HCtypes.Middle then
p = infl.p - Dpfric1 - Dpstat/2;
elseif HydraulicCapacitance == HCtypes.Upstream then
p = infl.p;
elseif HydraulicCapacitance == HCtypes.Downstream then
p = outfl.p;
else
assert(false, "Unsupported HydraulicCapacitance option");
end if;
//Friction factor selection
omega_hyd = 4*A/Dhyd;
for i in 1:N loop
if FFtype == FFtypes.Kfnom then
Kf[i] = Kfnom*Kfc;
elseif FFtype == FFtypes.OpPoint then
Kf[i] = dpnom*rhonom/(wnom/Nt)^2*Kfc;
elseif FFtype == FFtypes.Cfnom then
Cf[i] = Cfnom*Kfc;
elseif FFtype == FFtypes.Colebrook then
Cf[i] = ThermoPower.Water.f_colebrook(
w[i],
Dhyd/A,
e,
Medium.dynamicViscosity(fluidState[i]))*Kfc;
elseif FFtype == FFtypes.NoFriction then
Cf[i] = 0;
end if;
assert(Kf[i] >= 0, "Negative friction coefficient");
Kf[i] = Cf[i]*omega_hyd*L/(2*A^3)
"Relationship between friction coefficient and Fanning friction factor";
end for;
//Dynamic Momentum [not] accounted for
if DynamicMomentum then
if HydraulicCapacitance == HCtypes.Upstream then
dwdt = der(w[N]);
elseif HydraulicCapacitance == HCtypes.Downstream then
dwdt = der(w[1]);
else
assert(false,
"DynamicMomentum == true requires either Upstream or Downstream capacitance");
end if;
else
dwdt = 0;
end if;
L/A*dwdt + (outfl.p - infl.p) + Dpstat + Dpfric = 0
"Momentum balance equation";
w[1] = infl.m_flow/Nt "Inlet flow rate - single tube";
w[N] = -outfl.m_flow/Nt "Outlet flow rate - single tube";
Dpfric = Dpfric1 + Dpfric2 "Total pressure drop due to friction";
if FFtype == FFtypes.NoFriction then
Dpfric1 = 0;
Dpfric2 = 0;
else
Dpfric1 = homotopy(sum(Kf[i]/L*squareReg(w[i], wnom/Nt*wnf)*D1[i]/rho[i]
for i in 1:N), dpnom/2/(wnom/Nt)*w[1])
"Pressure drop from inlet to capacitance";
Dpfric2 = homotopy(sum(Kf[i]/L*squareReg(w[i], wnom/Nt*wnf)*D2[i]/rho[i]
for i in 1:N), dpnom/2/(wnom/Nt)*w[N])
"Pressure drop from capacitance to outlet";
end if "Pressure drop due to friction";
Dpstat = if abs(dzdx) < 1e-6 then 0 else g*dzdx*rho*D
"Pressure drop due to static head";
((1 - ML)*Y + ML*YY)*der(h) + B/A*h + C*h/A = der(p)*G + M*(omega/A)*phi +
K*w/A "Energy balance equation";
// Fluid property calculations
for j in 1:N loop
fluidState[j] = Medium.setState_ph(p, h[j]);
T[j] = Medium.temperature(fluidState[j]);
rho[j] = Medium.density(fluidState[j]);
drdp[j] = if Medium.singleState then 0 else Medium.density_derp_h(
fluidState[j]);
drdh[j] = Medium.density_derh_p(fluidState[j]);
v[j] = 1/rho[j];
u[j] = w[j]/(rho[j]*A);
end for;
//Wall energy flux and temperature
T = wall.T;
phi = wall.phi;
//Boundary Values of outflowing fluid enthalpies
h[1] = infl.h_outflow;
h[N] = outfl.h_outflow;
alpha_sgn = alpha*sign(infl.m_flow - outfl.m_flow);
for i in 1:N - 1 loop
(w[i + 1] - w[i]) = -A*l*(der(p)*1/2*(drdp[i + 1] + drdp[i]) + 1/6*(der(h[
i])*(2*drdh[i] + drdh[i + 1]) + der(h[i + 1])*(drdh[i] + 2*drdh[i + 1])))
"Mass balance equations";
end for;
// Energy equation FEM matrices
Y[1, 1] = rho[1]*((-l/12)*(2*alpha_sgn - 3)) + rho[2]*((-l/12)*(alpha_sgn
- 1));
Y[1, 2] = rho[1]*((-l/12)*(alpha_sgn - 1)) + rho[2]*((-l/12)*(2*alpha_sgn
- 1));
Y[N, N] = rho[N - 1]*((l/12)*(alpha_sgn + 1)) + rho[N]*((l/12)*(2*alpha_sgn
+ 3));
Y[N, N - 1] = rho[N - 1]*((l/12)*(2*alpha_sgn + 1)) + rho[N]*((l/12)*(
alpha_sgn + 1));
if N > 2 then
for i in 2:N - 1 loop
Y[i, i - 1] = rho[i - 1]*((l/12)*(2*alpha_sgn + 1)) + rho[i]*((l/12)*(
alpha_sgn + 1));
Y[i, i] = rho[i - 1]*((l/12)*(alpha_sgn + 1)) + rho[i]*(l/2) + rho[i +
1]*(-(l/12)*(alpha_sgn - 1));
Y[i, i + 1] = rho[i]*((-l/12)*(alpha_sgn - 1)) + rho[i + 1]*((-l/12)*(2
*alpha_sgn - 1));
Y[1, i + 1] = 0;
Y[N, i - 1] = 0;
for j in 1:(i - 2) loop
Y[i, j] = 0;
end for;
for j in (i + 2):N loop
Y[i, j] = 0;
end for;
end for;
end if;
for i in 1:N loop
for j in 1:N loop
YY[i, j] = if (i <> j) then 0 else sum(Y[:, j]);
end for;
end for;
M[1, 1] = l/3 - l*alpha_sgn/4;
M[N, N] = l/3 + l*alpha_sgn/4;
M[1, 2] = l/6 - l*alpha_sgn/4;
M[N, (N - 1)] = l/6 + l*alpha_sgn/4;
if N > 2 then
for i in 2:N - 1 loop
M[i, i - 1] = l/6 + l*alpha_sgn/4;
M[i, i] = 2*l/3;
M[i, i + 1] = l/6 - l*alpha_sgn/4;
M[1, i + 1] = 0;
M[N, i - 1] = 0;
for j in 1:(i - 2) loop
M[i, j] = 0;
end for;
for j in (i + 2):N loop
M[i, j] = 0;
end for;
end for;
end if;
B[1, 1] = (-1/3 + alpha_sgn/4)*w[1] + (-1/6 + alpha_sgn/4)*w[2];
B[1, 2] = (1/3 - alpha_sgn/4)*w[1] + (1/6 - alpha_sgn/4)*w[2];
B[N, N] = (1/6 + alpha_sgn/4)*w[N - 1] + (1/3 + alpha_sgn/4)*w[N];
B[N, N - 1] = (-1/(6) - alpha_sgn/4)*w[N - 1] + (-1/3 - alpha_sgn/4)*w[N];
if N > 2 then
for i in 2:N - 1 loop
B[i, i - 1] = (-1/6 - alpha_sgn/4)*w[i - 1] + (-1/3 - alpha_sgn/4)*w[i];
B[i, i] = (1/6 + alpha_sgn/4)*w[i - 1] + (alpha_sgn/2)*w[i] + (-1/6 +
alpha_sgn/4)*w[i + 1];
B[i, i + 1] = (1/3 - alpha_sgn/4)*w[i] + (1/6 - alpha_sgn/4)*w[i + 1];
B[1, i + 1] = 0;
B[N, i - 1] = 0;
for j in 1:(i - 2) loop
B[i, j] = 0;
end for;
for j in (i + 2):N loop
B[i, j] = 0;
end for;
end for;
end if;
if Medium.singleState then
G = zeros(N) "No influence of pressure";
else
G[1] = l/2*(1 - alpha_sgn);
G[N] = l/2*(1 + alpha_sgn);
if N > 2 then
for i in 2:N - 1 loop
G[i] = l;
end for;
end if;
end if;
// boundary condition matrices
// step change is regularized, no negative undershoot
C[1, 1] = ThermoPower.Functions.stepReg(
infl.m_flow - wnom*wnf_bc,
(1 - alpha_sgn/2)*w[1],
0,
wnom*wnf_bc);
C[N, N] = ThermoPower.Functions.stepReg(
outfl.m_flow - wnom*wnf_bc,
-(1 + alpha_sgn/2)*w[N],
0,
wnom*wnf_bc);
// C[1, 1] = if infl.m_flow >= 0 then (1 - alpha_sgn/2)*w[1] else 0;
// C[N, N] = if outfl.m_flow >= 0 then -(1 + alpha_sgn/2)*w[N] else 0;
C[N, 1] = 0;
C[1, N] = 0;
if (N > 2) then
for i in 2:(N - 1) loop
C[1, i] = 0;
C[N, i] = 0;
for j in 1:N loop
C[i, j] = 0;
end for;
end for;
end if;
K[1, 1] = ThermoPower.Functions.stepReg(
infl.m_flow - wnom*wnf_bc,
(1 - alpha_sgn/2)*inStream(infl.h_outflow),
0,
wnom*wnf_bc);
K[N, N] = ThermoPower.Functions.stepReg(
outfl.m_flow - wnom*wnf_bc,
-(1 + alpha_sgn/2)*inStream(outfl.h_outflow),
0,
wnom*wnf_bc);
// K[1, 1] = if infl.m_flow >= 0 then (1 - alpha_sgn/2)*inStream(infl.h_outflow) else 0;
// K[N, N] = if outfl.m_flow >= 0 then -(1 + alpha_sgn/2)*inStream(outfl.h_outflow) else 0;
K[N, 1] = 0;
K[1, N] = 0;
if (N > 2) then
for i in 2:(N - 1) loop
K[1, i] = 0;
K[N, i] = 0;
for j in 1:N loop
K[i, j] = 0;
end for;
end for;
end if;
// Momentum and Mass balance equation matrices
D[1] = l/2;
D[N] = l/2;
for i in 2:N - 1 loop
D[i] = l;
end for;
if HydraulicCapacitance == HCtypes.Middle then
D1 = l*(if N == 2 then {3/8,1/8} else if evenN then cat(
1,
{1/2},
ones(max(0, div(N, 2) - 2)),
{7/8,1/8},
zeros(div(N, 2) - 1)) else cat(
1,
{1/2},
ones(div(N, 2) - 1),
{1/2},
zeros(div(N, 2))));
D2 = l*(if N == 2 then {1/8,3/8} else if evenN then cat(
1,
zeros(div(N, 2) - 1),
{1/8,7/8},
ones(max(div(N, 2) - 2, 0)),
{1/2}) else cat(
1,
zeros(div(N, 2)),
{1/2},
ones(div(N, 2) - 1),
{1/2}));
elseif HydraulicCapacitance == HCtypes.Upstream then
D1 = zeros(N);
D2 = D;
elseif HydraulicCapacitance == HCtypes.Downstream then
D1 = D;
D2 = zeros(N);
else
assert(false, "Unsupported HydraulicCapacitance option");
end if;
Q = Nt*omega*D*phi "Total heat flow through lateral boundary";
Mtot = Nt*D*rho*A "Total mass of fluid";
Tr = noEvent(Mtot/max(abs(infl.m_flow), Modelica.Constants.eps))
"Residence time";
initial equation
if initOpt == ThermoPower.Choices.Init.Options.noInit then
// do nothing
elseif initOpt == ThermoPower.Choices.Init.Options.steadyState then
der(h) = zeros(N);
if (not Medium.singleState) then
der(p) = 0;
end if;
elseif initOpt == ThermoPower.Choices.Init.Options.steadyStateNoP then
der(h) = zeros(N);
elseif initOpt == ThermoPower.Choices.Init.Options.steadyStateNoT and not
Medium.singleState then
der(p) = 0;
else
assert(false, "Unsupported initialisation option");
end if;
annotation (
Diagram(graphics),
Icon(graphics={Text(extent={{-100,-40},{100,-80}}, textString="%name")}),
Documentation(info="
This model describes the flow of water or steam in a rigid tube. The basic modelling assumptions are:
- The fluid state is always one-phase (i.e. subcooled liquid or superheated steam).
- Uniform velocity is assumed on the cross section, leading to a 1-D distributed parameter model.
- Turbulent friction is always assumed; a small linear term is added to avoid numerical singularities at zero flowrate. The friction effects are not accurately computed in the laminar and transitional flow regimes, which however should not be an issue in most applications using water or steam as a working fluid.
- The model is based on dynamic mass, momentum, and energy balances. The dynamic momentum term can be switched off, to avoid the fast oscillations that can arise from its coupling with the mass balance (sound wave dynamics).
- The longitudinal heat diffusion term is neglected.
- The energy balance equation is written by assuming a uniform pressure distribution; the pressure drop is lumped either at the inlet or at the outlet.
- The fluid flow can exchange thermal power through the lateral surface, which is represented by the wall connector. The actual heat flux must be computed by a connected component (heat transfer computation module).
The mass, momentum, and energy balance equation are discretised with the finite element method. The state variables are one pressure, one flowrate (optional) and N specific enthalpies.
The turbulent friction factor can be either assumed as a constant, or computed by Colebrook's equation. In the former case, the friction factor can be supplied directly, or given implicitly by a specified operating point. In any case, the multiplicative correction coefficient Kfc can be used to modify the friction coefficient, e.g. to fit experimental data.
A small linear pressure drop is added to avoid numerical singularities at low or zero flowrate. The wnom parameter must be always specified: the additional linear pressure drop is such that it is equal to the turbulent pressure drop when the flowrate is equal to wnf*wnom (the default value is 1% of the nominal flowrate). Increase wnf if numerical instabilities occur in tubes with very low pressure drops.
Flow reversal is fully supported.
Modelling options
Thermal variables (enthalpy, temperature, density) are computed in N equally spaced nodes, including the inlet (node 1) and the outlet (node N); N must be greater or equal than 2.
The dynamic momentum term is included or neglected depending on the DynamicMomentum parameter.
Two parameters are available to tune the numerical method. The stabilisation coefficient alpha varies from 0.0 to 1.0; alpha=0.0 corresponds to a non-stabilised method, which gives rise to non-physical oscillations; the default value of 1.0 corresponds to a stabilised method, with well-damped oscillations. The mass lumping coefficient (ML) allows to use a hybrid finite-element/finite-volume discretisation method for the dynamic matrix; the default value ML=0.0 corresponds to a standard FEM model, ML=1.0 corresponds to a full finite-volume method, with the associated numerical diffusion effects. Intermediate values can be used.
The following options are available to specify the friction coefficient:
- FFtype = FFtypes.Kfnom: the hydraulic friction coefficient Kf is set directly to Kfnom.
- FFtype = FFtypes.OpPoint: the hydraulic friction coefficient is specified by a nominal operating point (wnom,dpnom, rhonom).
- FFtype = FFtypes.Cfnom: the friction coefficient is computed by giving the (constant) value of the Fanning friction factor Cfnom.
- FFtype = FFtypes.Colebrook: the Fanning friction factor is computed by Colebrook's equation (assuming Re > 2100, e.g. turbulent flow).
- FFtype = FFtypes.NoFriction: no friction is assumed across the pipe.
If HydraulicCapacitance = 2 (default option) then the mass buildup term depending on the pressure is lumped at the outlet, while the optional momentum buildup term depending on the flowrate is lumped at the inlet. If HydraulicCapacitance = 1 the reverse takes place.
Start values for pressure and flowrate are specified by pstart, wstart. The start values for the node enthalpies are linearly distributed from hstartin at the inlet to hstartout at the outlet.
A bank of Nt identical tubes working in parallel can be modelled by setting Nt > 1. The geometric parameters always refer to a single tube.
This models makes the temperature and external heat flow distributions visible through the wall connector. If other variables (e.g. the heat transfer coefficient) are needed by external components to compute the actual heat flow, the wall connector can be replaced by an extended version of the DHT connector.
", revisions="
"));
end Flow1DFEM_New;
connector TwoPhaseFlangeA "A-type flange connector for two-phase medium flows"
extends ThermoPower.Water.Flange;
annotation (Icon(graphics={Ellipse(
extent={{-100,100},{100,-100}},
lineColor={57,150,0},
fillColor={57,150,0},
fillPattern=FillPattern.Solid)}));
end TwoPhaseFlangeA;
connector TwoPhaseFlangeB "B-type flange connector for water/steam flows"
extends ThermoPower.Water.Flange;
annotation (Icon(graphics={Ellipse(
extent={{-100,100},{100,-100}},
lineColor={57,150,0},
fillColor={57,150,0},
fillPattern=FillPattern.Solid), Ellipse(
extent={{-40,40},{40,-40}},
lineColor={57,150,0},
fillColor={255,255,255},
fillPattern=FillPattern.Solid)}));
end TwoPhaseFlangeB;
connector RealInput_control =
input Real "'input Real' as connector" annotation (
defaultComponentName="u",
Icon(graphics={
Polygon(
fillColor={255,0,0},
fillPattern=FillPattern.Solid,
points={{-100.0,100.0},{100.0,0.0},{-100.0,-100.0}},
pattern=LinePattern.None,
lineColor={255,0,0})},
coordinateSystem(extent={{-100.0,-100.0},{100.0,100.0}},
preserveAspectRatio=true,
initialScale=0.2)),
Diagram(
coordinateSystem(preserveAspectRatio=true,
initialScale=0.2,
extent={{-100.0,-100.0},{100.0,100.0}}),
graphics={
Polygon(
lineColor={255,0,0},
fillColor={255,0,0},
fillPattern=FillPattern.Solid,
points={{0.0,50.0},{100.0,0.0},{0.0,-50.0},{0.0,50.0}}),
Text(
lineColor={255,0,0},
extent={{-10.0,60.0},{-10.0,85.0}},
textString="%name",
fillColor={255,0,0},
fillPattern=FillPattern.Solid)}),
Documentation(info="
Connector with one input signal of type Real.
"));
connector RealOutput_control =
output Real "'output Real' as connector" annotation (
defaultComponentName="y",
Icon(
coordinateSystem(preserveAspectRatio=true,
extent={{-100.0,-100.0},{100.0,100.0}}),
graphics={
Polygon(
lineColor={255,0,0},
fillColor={255,255,255},
fillPattern=FillPattern.Solid,
points={{-100.0,100.0},{100.0,0.0},{-100.0,-100.0}})}),
Diagram(
coordinateSystem(preserveAspectRatio=true,
extent={{-100.0,-100.0},{100.0,100.0}}),
graphics={
Polygon(
lineColor={255,0,0},
fillColor={255,255,255},
fillPattern=FillPattern.Solid,
points={{-100.0,50.0},{0.0,0.0},{-100.0,-50.0}}),
Text(
extent={{30.0,60.0},{30.0,110.0}},
textString="%name",
pattern=LinePattern.None,
lineColor={255,0,0})}),
Documentation(info="
Connector with one output signal of type Real.
"));
end Connectors;
package Components "Component set for LAES"
package Icons "Icons package for nuclear power plant components"
partial model SourcePTwoPhase
annotation (Icon(graphics={
Ellipse(
extent={{-80,80},{80,-80}},
lineColor={57,150,0},
fillColor={57,150,0},
fillPattern=FillPattern.Solid),
Text(
extent={{-20,34},{28,-26}},
lineColor={255,255,255},
textString="P"),
Text(extent={{-100,-78},{100,-106}}, textString="%name")}));
end SourcePTwoPhase;
partial model SourceWTwoPhase
annotation (Icon(graphics={
Rectangle(
extent={{-80,40},{80,-40}},
lineColor={57,150,0},
fillColor={57,150,0},
fillPattern=FillPattern.Solid),
Polygon(
points={{-12,-20},{66,0},{-12,20},{34,0},{-12,-20}},
lineColor={255,255,255},
fillColor={255,255,255},
fillPattern=FillPattern.Solid),
Text(extent={{-100,-52},{100,-80}}, textString="%name")}));
end SourceWTwoPhase;
partial model Tank
annotation (Icon(graphics={
Rectangle(
extent={{-60,58},{60,-82}},
lineColor={0,0,0},
fillColor={57,150,0},
fillPattern=FillPattern.Solid),
Rectangle(
extent={{-54,60},{54,12}},
lineColor={255,255,255},
fillColor={255,255,255},
fillPattern=FillPattern.Solid),
Rectangle(extent={{-54,12},{54,-72}}, lineColor={57,150,0},
fillColor={57,150,0},
fillPattern=FillPattern.Solid)}));
end Tank;
partial model PressDrop
annotation (Icon(graphics={Rectangle(
extent={{-80,40},{80,-40}},
lineColor={0,0,0},
fillPattern=FillPattern.HorizontalCylinder), Polygon(
points={{-80,40},{-42,40},{-20,12},{20,12},{40,40},{80,40},{80,-40},
{40,-40},{20,-12},{-20,-12},{-40,-40},{-80,-40},{-80,40}},
lineColor={0,0,0},
fillPattern=FillPattern.HorizontalCylinder,
fillColor={77,150,0})}),Diagram(graphics));
end PressDrop;
partial model GravelBed
annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
Rectangle(
extent={{-100,100},{100,-100}},
lineColor={0,0,0},
lineThickness=1),
Ellipse(
extent={{-20,80},{0,60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-40,80},{-20,60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-40,100},{-20,80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-60,100},{-40,80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-80,100},{-60,80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-100,100},{-80,80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-80,60},{-60,40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-20,60},{0,40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-100,80},{-80,60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-60,80},{-40,60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-40,60},{-20,40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-60,60},{-40,40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-100,60},{-80,40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-80,80},{-60,60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-20,20},{0,0}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-40,20},{-20,0}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-40,40},{-20,20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-60,40},{-40,20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-80,40},{-60,20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-100,40},{-80,20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-80,0},{-60,-20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-20,0},{0,-20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-100,20},{-80,0}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-60,20},{-40,0}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-40,0},{-20,-20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-60,0},{-40,-20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-100,0},{-80,-20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-80,20},{-60,0}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-20,-40},{0,-60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-40,-40},{-20,-60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-40,-20},{-20,-40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-60,-20},{-40,-40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-80,-20},{-60,-40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-100,-20},{-80,-40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-80,-60},{-60,-80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-20,-60},{0,-80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-100,-40},{-80,-60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-60,-40},{-40,-60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-40,-60},{-20,-80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-60,-60},{-40,-80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-100,-60},{-80,-80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-80,-40},{-60,-60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-20,40},{0,20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-20,-20},{0,-40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-40,-80},{-20,-100}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-60,-80},{-40,-100}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-80,-80},{-60,-100}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-100,-100},{-80,-80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{80,80},{100,60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{60,80},{80,60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{60,100},{80,80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{40,100},{60,80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{20,100},{40,80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{80,100},{100,80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{20,60},{40,40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{80,60},{100,40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{0,80},{20,60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{40,80},{60,60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{60,60},{80,40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{40,60},{60,40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{0,60},{20,40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{20,80},{40,60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{80,20},{100,0}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{60,20},{80,0}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{60,40},{80,20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{40,40},{60,20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{20,40},{40,20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{0,40},{20,20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{20,0},{40,-20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{80,0},{100,-20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{0,20},{20,0}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{40,20},{60,0}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{60,0},{80,-20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{40,0},{60,-20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{0,0},{20,-20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{20,20},{40,0}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{80,-40},{100,-60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{60,-40},{80,-60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{60,-20},{80,-40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{40,-20},{60,-40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{20,-20},{40,-40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{0,-20},{20,-40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{20,-60},{40,-80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{80,-60},{100,-80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{0,-40},{20,-60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{40,-40},{60,-60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{60,-60},{80,-80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{40,-60},{60,-80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{0,-60},{20,-80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{20,-40},{40,-60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{80,40},{100,20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{80,-20},{100,-40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{60,-80},{80,-100}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{40,-80},{60,-100}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{20,-80},{40,-100}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{80,-100},{100,-80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid)}), Diagram(coordinateSystem(
preserveAspectRatio=false)));
end GravelBed;
model FlowJoin
annotation (Diagram(graphics), Icon(graphics={Polygon(
points={{-40,60},{0,20},{40,20},{40,-20},{0,-20},{-40,-60},{-40,-20},
{-20,0},{-40,20},{-40,60}},
lineColor={0,0,0},
fillPattern=FillPattern.Solid,
fillColor={57,150,0})}));
end FlowJoin;
model FlowSplit
annotation (Diagram(graphics), Icon(graphics={Polygon(
points={{40,60},{0,20},{-40,20},{-40,-20},{0,-20},{40,-60},{40,-20},
{22,0},{40,20},{40,60}},
lineColor={0,0,0},
fillPattern=FillPattern.Solid,
fillColor={57,150,0})}));
end FlowSplit;
partial model VapourLiquidSeparator
annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
Rectangle(
extent={{-100,0},{100,-100}},
lineThickness=0.5,
pattern=LinePattern.None,
lineColor={0,0,0},
fillColor={57,150,0},
fillPattern=FillPattern.Solid),
Rectangle(
extent={{-100,100},{100,-100}},
lineColor={0,0,0},
lineThickness=0.5),
Ellipse(
extent={{-82,44},{-74,52}},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid,
pattern=LinePattern.None),
Ellipse(
extent={{-30,68},{-22,76}},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid,
pattern=LinePattern.None),
Ellipse(
extent={{-38,24},{-30,32}},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid,
pattern=LinePattern.None),
Ellipse(
extent={{16,52},{24,60}},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid,
pattern=LinePattern.None),
Ellipse(
extent={{-62,66},{-54,74}},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid,
pattern=LinePattern.None),
Ellipse(
extent={{-52,44},{-44,52}},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid,
pattern=LinePattern.None),
Ellipse(
extent={{-68,12},{-60,20}},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid,
pattern=LinePattern.None),
Ellipse(
extent={{-8,36},{0,44}},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid,
pattern=LinePattern.None),
Ellipse(
extent={{-86,82},{-78,90}},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid,
pattern=LinePattern.None),
Ellipse(
extent={{-2,70},{6,78}},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid,
pattern=LinePattern.None),
Ellipse(
extent={{-10,10},{-2,18}},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid,
pattern=LinePattern.None),
Ellipse(
extent={{32,82},{40,90}},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid,
pattern=LinePattern.None),
Ellipse(
extent={{26,8},{34,16}},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid,
pattern=LinePattern.None),
Ellipse(
extent={{38,30},{46,38}},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid,
pattern=LinePattern.None),
Ellipse(
extent={{64,8},{72,16}},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid,
pattern=LinePattern.None),
Ellipse(
extent={{80,28},{88,36}},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid,
pattern=LinePattern.None),
Ellipse(
extent={{60,48},{68,56}},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid,
pattern=LinePattern.None),
Ellipse(
extent={{76,74},{84,82}},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid,
pattern=LinePattern.None),
Ellipse(
extent={{44,60},{52,68}},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid,
pattern=LinePattern.None)}), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end VapourLiquidSeparator;
partial model SteamTurbine
annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
Polygon(
points={{-28,76},{-28,28},{-22,28},{-22,82},{-60,82},{-60,76},{-28,76}},
lineColor={0,0,0},
lineThickness=0.5,
fillColor={0,0,255},
fillPattern=FillPattern.Solid),
Polygon(
points={{26,56},{32,56},{32,76},{60,76},{60,82},{26,82},{26,56}},
lineColor={0,0,0},
lineThickness=0.5,
fillColor={0,0,255},
fillPattern=FillPattern.Solid),
Polygon(
points={{-28,28},{-28,-26},{32,-60},{32,60},{-28,28}},
lineColor={0,0,0},
lineThickness=0.5,
fillColor={0,0,255},
fillPattern=FillPattern.Solid)}), Diagram(coordinateSystem(
preserveAspectRatio=false)));
end SteamTurbine;
partial model Pump
annotation (Icon(graphics={
Polygon(
points={{-40,-24},{-60,-60},{60,-60},{40,-24},{-40,-24}},
lineColor={0,0,255},
pattern=LinePattern.None,
fillColor={135,135,135},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-60,80},{60,-40}},
lineColor={0,0,0},
fillPattern=FillPattern.Sphere),
Polygon(
points={{-30,52},{-30,-8},{48,20},{-30,52}},
lineColor={0,0,0},
pattern=LinePattern.None,
fillPattern=FillPattern.HorizontalCylinder,
fillColor={255,255,255}),
Text(extent={{-100,-64},{100,-90}}, textString="%name")}));
end Pump;
partial model CompressorTwoPhase
annotation (Icon(graphics={
Polygon(
points={{24,26},{30,26},{30,76},{60,76},{60,82},{24,82},{24,26}},
lineColor={128,128,128},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid),
Polygon(
points={{-30,76},{-30,56},{-24,56},{-24,82},{-60,82},{-60,76},{-30,
76}},
lineColor={128,128,128},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid),
Polygon(
points={{-30,60},{-30,-60},{30,-26},{30,26},{-30,60}},
lineColor={128,128,128},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid)}), Diagram(graphics));
end CompressorTwoPhase;
partial model TurbineTwoPhase
annotation (Icon(graphics={
Polygon(
points={{-28,76},{-28,28},{-22,28},{-22,82},{-60,82},{-60,76},{-28,
76}},
lineColor={128,128,128},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid),
Polygon(
points={{26,56},{32,56},{32,76},{60,76},{60,82},{26,82},{26,56}},
lineColor={128,128,128},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid),
Polygon(
points={{-28,28},{-28,-26},{32,-60},{32,60},{-28,28}},
lineColor={128,128,128},
lineThickness=0.5,
fillColor={57,150,0},
fillPattern=FillPattern.Solid)}), Diagram(graphics));
end TurbineTwoPhase;
partial model GravelBed_multiflow
annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
Rectangle(
extent={{-100,100},{100,-100}},
lineColor={0,0,0},
lineThickness=1),
Ellipse(
extent={{-20,80},{0,60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-40,80},{-20,60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-40,100},{-20,80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{0,100},{20,80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-20,100},{0,80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-100,100},{-80,80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-80,60},{-60,40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-20,60},{0,40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-100,80},{-80,60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-60,80},{-40,60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-40,60},{-20,40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-60,60},{-40,40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-100,60},{-80,40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-80,80},{-60,60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-20,20},{0,0}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-40,20},{-20,0}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-40,40},{-20,20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-60,40},{-40,20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-80,40},{-60,20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-100,40},{-80,20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-80,0},{-60,-20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-20,0},{0,-20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-100,20},{-80,0}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-60,20},{-40,0}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-40,0},{-20,-20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-60,0},{-40,-20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-100,0},{-80,-20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-80,20},{-60,0}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-20,-40},{0,-60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-40,-40},{-20,-60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-40,-20},{-20,-40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-60,-20},{-40,-40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-80,-20},{-60,-40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-100,-20},{-80,-40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-80,-60},{-60,-80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-20,-60},{0,-80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-100,-40},{-80,-60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-60,-40},{-40,-60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-40,-60},{-20,-80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-60,-60},{-40,-80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-100,-60},{-80,-80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-80,-40},{-60,-60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-20,40},{0,20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-20,-20},{0,-40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-40,-80},{-20,-100}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{0,-80},{20,-100}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-20,-80},{0,-100}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{-100,-100},{-80,-80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{80,80},{100,60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{60,80},{80,60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{20,100},{40,80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{80,100},{100,80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{20,60},{40,40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{80,60},{100,40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{0,80},{20,60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{40,80},{60,60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{60,60},{80,40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{40,60},{60,40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{0,60},{20,40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{20,80},{40,60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{80,20},{100,0}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{60,20},{80,0}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{60,40},{80,20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{40,40},{60,20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{20,40},{40,20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{0,40},{20,20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{20,0},{40,-20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{80,0},{100,-20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{0,20},{20,0}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{40,20},{60,0}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{60,0},{80,-20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{40,0},{60,-20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{0,0},{20,-20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{20,20},{40,0}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{80,-40},{100,-60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{60,-40},{80,-60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{60,-20},{80,-40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{40,-20},{60,-40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{20,-20},{40,-40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{0,-20},{20,-40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{20,-60},{40,-80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{80,-60},{100,-80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{0,-40},{20,-60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{40,-40},{60,-60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{60,-60},{80,-80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{40,-60},{60,-80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{0,-60},{20,-80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{20,-40},{40,-60}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{80,40},{100,20}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{80,-20},{100,-40}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{20,-80},{40,-100}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),
Ellipse(
extent={{80,-100},{100,-80}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid)}), Diagram(coordinateSystem(
preserveAspectRatio=false)));
end GravelBed_multiflow;
partial model ColdBox_metal "Metal heat exchanger for the cold box"
annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
Rectangle(
extent={{-100,100},{100,-100}},
lineColor={0,0,0},
lineThickness=1,
fillColor={131,131,131},
fillPattern=FillPattern.Solid)}), Diagram(coordinateSystem(
preserveAspectRatio=false)));
end ColdBox_metal;
end Icons;
package BaseClasses "Base class package for NPP"
partial model WaterFlow1DBase_dpProp
"Basic interface for 1-dimensional water/steam fluid flow models"
replaceable package Medium = ThermoPower.Water.StandardWater constrainedby
Modelica.Media.Interfaces.PartialMedium "Medium model"
annotation(choicesAllMatching = true);
extends ThermoPower.Icons.Water.Tube;
constant Real pi = Modelica.Constants.pi;
parameter Integer N(min=2) = 2 "Number of nodes for thermal variables";
parameter Integer Nw = N - 1 "Number of volumes on the wall interface";
parameter Integer Nt = 1 "Number of tubes in parallel";
parameter Modelica.SIunits.Distance L "Tube length" annotation (Evaluate=true);
parameter Modelica.SIunits.Position H=0 "Elevation of outlet over inlet";
parameter Modelica.SIunits.Area A "Cross-sectional area (single tube)";
parameter Modelica.SIunits.Length omega
"Perimeter of heat transfer surface (single tube)";
parameter Modelica.SIunits.Length Dhyd=omega/pi
"Hydraulic Diameter (single tube)";
parameter Modelica.SIunits.MassFlowRate wnom "Nominal mass flowrate (total)";
parameter Real PressureDrop=0.01
"Pressure drop as a function of inlet pressure";
parameter Boolean DynamicMomentum=false
"Inertial phenomena accounted for"
annotation (Evaluate=true);
parameter ThermoPower.Choices.Flow1D.HCtypes HydraulicCapacitance=ThermoPower.Choices.Flow1D.HCtypes.Downstream
"Location of the hydraulic capacitance";
parameter Boolean avoidInletEnthalpyDerivative=true
"Avoid inlet enthalpy derivative";
parameter Boolean allowFlowReversal=system.allowFlowReversal
"= true to allow flow reversal, false restricts to design direction";
outer ThermoPower.System system "System wide properties";
parameter ThermoPower.Choices.FluidPhase.FluidPhases FluidPhaseStart=
ThermoPower.Choices.FluidPhase.FluidPhases.Liquid
"Fluid phase (only for initialization!)"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.Pressure pstart=1e5 "Pressure start value"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.SpecificEnthalpy hstartin=if FluidPhaseStart ==
ThermoPower.Choices.FluidPhase.FluidPhases.Liquid then 1e5 else if
FluidPhaseStart == ThermoPower.Choices.FluidPhase.FluidPhases.Steam then 3e6
else 1e6 "Inlet enthalpy start value"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.SpecificEnthalpy hstartout=if FluidPhaseStart ==
ThermoPower.Choices.FluidPhase.FluidPhases.Liquid then 1e5 else if
FluidPhaseStart == ThermoPower.Choices.FluidPhase.FluidPhases.Steam then 3e6
else 1e6 "Outlet enthalpy start value"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.SpecificEnthalpy hstart[N]=linspace(
hstartin,
hstartout,
N) "Start value of enthalpy vector (initialized by default)"
annotation (Dialog(tab="Initialisation"));
parameter Real wnf=0.02
"Fraction of nominal flow rate at which linear friction equals turbulent friction";
parameter ThermoPower.Choices.Init.Options initOpt=ThermoPower.Choices.Init.Options.noInit
"Initialisation option" annotation (Dialog(tab="Initialisation"));
constant Real g=Modelica.Constants.g_n;
function squareReg = ThermoPower.Functions.squareReg;
ThermoPower.Water.FlangeA infl(
h_outflow(start=hstartin),
redeclare package Medium = Medium,
m_flow(start=wnom, min=if allowFlowReversal then -Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{-120,-20},{-80,
20}}, rotation=0)));
ThermoPower.Water.FlangeB outfl(
h_outflow(start=hstartout),
redeclare package Medium = Medium,
m_flow(start=-wnom, max=if allowFlowReversal then +Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{80,-20},{120,20}},
rotation=0)));
// replaceable ThermoPower.Thermal.DHT wall(N=N) annotation (Dialog(enable=
// false), Placement(transformation(extent={{-40,40},{40,60}},
// rotation=0)));
Modelica.SIunits.Power Q
"Total heat flow through the lateral boundary (all Nt tubes)";
Modelica.SIunits.Time Tr "Residence time";
final parameter Real dzdx=H/L "Slope" annotation (Evaluate=true);
final parameter Modelica.SIunits.Length l=L/(N - 1)
"Length of a single volume" annotation (Evaluate=true);
annotation (
Documentation(info="
Basic interface of the Flow1D models, containing the common parameters and connectors.
", revisions=
"
"),Diagram(graphics),
Icon(graphics));
end WaterFlow1DBase_dpProp;
partial model TwoPhaseFlow1DBase
"Basic interface for 1-dimensional two phase medium flow models"
replaceable package Medium = ThermoPower.Water.StandardWater constrainedby
Modelica.Media.Interfaces.PartialMedium "Medium model"
annotation(choicesAllMatching = true);
extends ThermoPower.Icons.Water.Tube;
constant Real pi = Modelica.Constants.pi;
parameter Integer N(min=2) = 2 "Number of nodes for thermal variables";
parameter Integer Nw = N - 1 "Number of volumes on the wall interface";
parameter Integer Nt = 1 "Number of tubes in parallel";
parameter Modelica.SIunits.Distance L "Tube length" annotation (Evaluate=true);
parameter Modelica.SIunits.Position H=0 "Elevation of outlet over inlet";
parameter Modelica.SIunits.Area A "Cross-sectional area (single tube)";
parameter Modelica.SIunits.Length omega
"Perimeter of heat transfer surface (single tube)";
parameter Modelica.SIunits.Length Dhyd=omega/pi
"Hydraulic Diameter (single tube)";
parameter Modelica.SIunits.MassFlowRate wnom "Nominal mass flowrate (total)";
parameter ThermoPower.Choices.Flow1D.FFtypes FFtype=ThermoPower.Choices.Flow1D.FFtypes.NoFriction
"Friction Factor Type"
annotation (Evaluate=true);
parameter Modelica.SIunits.Pressure dpnom=0
"Nominal pressure drop (friction term only!)";
parameter Real Kfnom = 0
"Nominal hydraulic resistance coefficient (DP = Kfnom*w^2/rho)"
annotation(Dialog(enable = (FFtype == ThermoPower.Choices.Flow1D.FFtypes.Kfnom)));
parameter ThermoPower.Density rhonom=0 "Nominal inlet density" annotation (
Dialog(enable=(FFtype == ThermoPower.Choices.Flow1D.FFtypes.OpPoint)));
parameter Real Cfnom=0 "Nominal Fanning friction factor"
annotation(Dialog(enable = (FFtype == ThermoPower.Choices.Flow1D.FFtypes.Cfnom)));
parameter Real e=0 "Relative roughness (ratio roughness/diameter)"
annotation(Dialog(enable = (FFtype == ThermoPower.Choices.Flow1D.FFtypes.Colebrook)));
parameter Real Kfc=1 "Friction factor correction coefficient";
parameter Boolean DynamicMomentum=false
"Inertial phenomena accounted for"
annotation (Evaluate=true);
parameter ThermoPower.Choices.Flow1D.HCtypes HydraulicCapacitance=ThermoPower.Choices.Flow1D.HCtypes.Downstream
"Location of the hydraulic capacitance";
parameter Boolean avoidInletEnthalpyDerivative=true
"Avoid inlet enthalpy derivative";
parameter Boolean allowFlowReversal=system.allowFlowReversal
"= true to allow flow reversal, false restricts to design direction";
outer ThermoPower.System system "System wide properties";
parameter ThermoPower.Choices.FluidPhase.FluidPhases FluidPhaseStart=
ThermoPower.Choices.FluidPhase.FluidPhases.Liquid
"Fluid phase (only for initialization!)"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.Pressure pstart=1e5 "Pressure start value"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.SpecificEnthalpy hstartin=if FluidPhaseStart ==
ThermoPower.Choices.FluidPhase.FluidPhases.Liquid then 1e5 else if
FluidPhaseStart == ThermoPower.Choices.FluidPhase.FluidPhases.Steam then 3e6
else 1e6 "Inlet enthalpy start value"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.SpecificEnthalpy hstartout=if FluidPhaseStart ==
ThermoPower.Choices.FluidPhase.FluidPhases.Liquid then 1e5 else if
FluidPhaseStart == ThermoPower.Choices.FluidPhase.FluidPhases.Steam then 3e6
else 1e6 "Outlet enthalpy start value"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.SpecificEnthalpy hstart[N]=linspace(
hstartin,
hstartout,
N) "Start value of enthalpy vector (initialized by default)"
annotation (Dialog(tab="Initialisation"));
parameter Real wnf=0.02
"Fraction of nominal flow rate at which linear friction equals turbulent friction";
parameter ThermoPower.Choices.Init.Options initOpt=ThermoPower.Choices.Init.Options.noInit
"Initialisation option" annotation (Dialog(tab="Initialisation"));
constant Real g=Modelica.Constants.g_n;
function squareReg = ThermoPower.Functions.squareReg;
NuclearPowerPlant.Connectors.TwoPhaseFlangeA infl(
h_outflow(start=hstartin),
redeclare package Medium = Medium,
m_flow(start=wnom, min=if allowFlowReversal then -Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{-120,-20},{-80,
20}}, rotation=0)));
NuclearPowerPlant.Connectors.TwoPhaseFlangeB outfl(
h_outflow(start=hstartout),
redeclare package Medium = Medium,
m_flow(start=-wnom, max=if allowFlowReversal then +Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{80,-20},{120,20}},
rotation=0)));
// replaceable ThermoPower.Thermal.DHT wall(N=N) annotation (Dialog(enable=
// false), Placement(transformation(extent={{-40,40},{40,60}},
// rotation=0)));
Modelica.SIunits.Power Q
"Total heat flow through the lateral boundary (all Nt tubes)";
Modelica.SIunits.Time Tr "Residence time";
final parameter Real dzdx=H/L "Slope" annotation (Evaluate=true);
final parameter Modelica.SIunits.Length l=L/(N - 1)
"Length of a single volume" annotation (Evaluate=true);
equation
assert(FFtype == ThermoPower.Choices.Flow1D.FFtypes.NoFriction or dpnom > 0,
"dpnom=0 not valid, it is also used in the homotopy trasformation during the inizialization");
annotation (
Documentation(info="
Basic interface of the Flow1D models, containing the common parameters and connectors.
", revisions=
"
"),Diagram(graphics),
Icon(graphics));
end TwoPhaseFlow1DBase;
partial model TwoPhaseFlow1DBase_dpProp
"Basic interface for 1-dimensional two phase medium flow models with pressure drop proportional to inlet pressure"
replaceable package Medium = ThermoPower.Water.StandardWater constrainedby
Modelica.Media.Interfaces.PartialMedium "Medium model"
annotation(choicesAllMatching = true);
extends ThermoPower.Icons.Water.Tube;
constant Real pi = Modelica.Constants.pi;
parameter Integer N(min=2) = 2 "Number of nodes for thermal variables";
parameter Integer Nw = N - 1 "Number of volumes on the wall interface";
parameter Integer Nt = 1 "Number of tubes in parallel";
parameter Modelica.SIunits.Distance L "Tube length" annotation (Evaluate=true);
parameter Modelica.SIunits.Position H=0 "Elevation of outlet over inlet";
parameter Modelica.SIunits.Area A "Cross-sectional area (single tube)";
parameter Modelica.SIunits.Length omega
"Perimeter of heat transfer surface (single tube)";
parameter Modelica.SIunits.Length Dhyd=omega/pi
"Hydraulic Diameter (single tube)";
parameter Modelica.SIunits.MassFlowRate wnom "Nominal mass flowrate (total)";
parameter Real PressureDrop=0.01
"Pressure drop as a function of inlet pressure";
parameter Boolean DynamicMomentum=false
"Inertial phenomena accounted for"
annotation (Evaluate=true);
parameter ThermoPower.Choices.Flow1D.HCtypes HydraulicCapacitance=ThermoPower.Choices.Flow1D.HCtypes.Downstream
"Location of the hydraulic capacitance";
parameter Boolean avoidInletEnthalpyDerivative=true
"Avoid inlet enthalpy derivative";
parameter Boolean allowFlowReversal=system.allowFlowReversal
"= true to allow flow reversal, false restricts to design direction";
outer ThermoPower.System system "System wide properties";
parameter ThermoPower.Choices.FluidPhase.FluidPhases FluidPhaseStart=
ThermoPower.Choices.FluidPhase.FluidPhases.Liquid
"Fluid phase (only for initialization!)"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.Pressure pstart=1e5 "Pressure start value"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.SpecificEnthalpy hstartin=if FluidPhaseStart ==
ThermoPower.Choices.FluidPhase.FluidPhases.Liquid then 1e5 else if
FluidPhaseStart == ThermoPower.Choices.FluidPhase.FluidPhases.Steam then 3e6
else 1e6 "Inlet enthalpy start value"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.SpecificEnthalpy hstartout=if FluidPhaseStart ==
ThermoPower.Choices.FluidPhase.FluidPhases.Liquid then 1e5 else if
FluidPhaseStart == ThermoPower.Choices.FluidPhase.FluidPhases.Steam then 3e6
else 1e6 "Outlet enthalpy start value"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.SpecificEnthalpy hstart[N]=linspace(
hstartin,
hstartout,
N) "Start value of enthalpy vector (initialized by default)"
annotation (Dialog(tab="Initialisation"));
parameter ThermoPower.Choices.Init.Options initOpt=ThermoPower.Choices.Init.Options.noInit
"Initialisation option" annotation (Dialog(tab="Initialisation"));
constant Real g=Modelica.Constants.g_n;
function squareReg = ThermoPower.Functions.squareReg;
NuclearPowerPlant.Connectors.TwoPhaseFlangeA infl(
h_outflow(start=hstartin),
redeclare package Medium = Medium,
m_flow(start=wnom, min=if allowFlowReversal then -Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{-120,-20},{-80,
20}}, rotation=0)));
NuclearPowerPlant.Connectors.TwoPhaseFlangeB outfl(
h_outflow(start=hstartout),
redeclare package Medium = Medium,
m_flow(start=-wnom, max=if allowFlowReversal then +Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{80,-20},{120,20}},
rotation=0)));
// replaceable ThermoPower.Thermal.DHT wall(N=N) annotation (Dialog(enable=
// false), Placement(transformation(extent={{-40,40},{40,60}},
// rotation=0)));
Modelica.SIunits.Power Q
"Total heat flow through the lateral boundary (all Nt tubes)";
Modelica.SIunits.Time Tr "Residence time";
final parameter Real dzdx=H/L "Slope" annotation (Evaluate=true);
final parameter Modelica.SIunits.Length l=L/(N - 1)
"Length of a single volume" annotation (Evaluate=true);
annotation (
Documentation(info="
Basic interface of the Flow1D models, containing the common parameters and connectors.
", revisions=
"
"),Diagram(graphics),
Icon(graphics));
end TwoPhaseFlow1DBase_dpProp;
partial model PumpBase "Base model for centrifugal pumps"
extends ThermoPower.Icons.Water.Pump;
import Modelica.SIunits.Conversions.NonSIunits.*;
replaceable package Medium = ThermoPower.Water.StandardWater constrainedby
Modelica.Media.Interfaces.PartialMedium "Medium model"
annotation(choicesAllMatching = true);
Medium.ThermodynamicState inletFluidState
"Thermodynamic state of the fluid at the inlet";
replaceable function flowCharacteristic =
ThermoPower.Functions.PumpCharacteristics.quadraticFlow
constrainedby ThermoPower.Functions.PumpCharacteristics.baseFlow
"Head vs. q_flow characteristic at nominal speed and density"
annotation (Dialog(group="Characteristics"),choicesAllMatching=true);
parameter Boolean usePowerCharacteristic=false
"Use powerCharacteristic (vs. efficiencyCharacteristic)"
annotation (Dialog(group="Characteristics"));
replaceable function powerCharacteristic =
ThermoPower.Functions.PumpCharacteristics.constantPower constrainedby
ThermoPower.Functions.PumpCharacteristics.basePower
"Power consumption vs. q_flow at nominal speed and density" annotation (
Dialog(group="Characteristics", enable=usePowerCharacteristic),
choicesAllMatching=true);
replaceable function efficiencyCharacteristic =
ThermoPower.Functions.PumpCharacteristics.constantEfficiency (eta_nom=0.8)
constrainedby
ThermoPower.Functions.PumpCharacteristics.baseEfficiency
"Efficiency vs. q_flow at nominal speed and density" annotation (Dialog(
group="Characteristics", enable=not usePowerCharacteristic),
choicesAllMatching=true);
parameter Integer Np0(min=1) = 1 "Nominal number of pumps in parallel";
parameter ThermoPower.Density rho0=1000 "Nominal Liquid Density"
annotation (Dialog(group="Characteristics"));
parameter AngularVelocity_rpm n0 "Nominal rotational speed"
annotation (Dialog(group="Characteristics"));
parameter Modelica.SIunits.Volume V=0 "Pump Internal Volume"
annotation (Evaluate=true);
parameter Boolean CheckValve=false "Reverse flow stopped";
parameter Boolean allowFlowReversal=system.allowFlowReversal
"= true to allow flow reversal, false restricts to design direction";
outer ThermoPower.System system "System wide properties";
parameter Modelica.SIunits.MassFlowRate wstart=w0
"Mass Flow Rate Start Value" annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.SpecificEnthalpy hstart=1e5
"Specific Enthalpy Start Value" annotation (Dialog(tab="Initialisation"));
parameter ThermoPower.Choices.Init.Options initOpt=ThermoPower.Choices.Init.Options.noInit
"Initialisation option" annotation (Dialog(tab="Initialisation"));
constant Modelica.SIunits.Acceleration g=Modelica.Constants.g_n;
parameter Modelica.SIunits.MassFlowRate w0 "Nominal mass flow rate"
annotation (Dialog(group="Characteristics"));
parameter Modelica.SIunits.Pressure dp0 "Nominal pressure increase"
annotation (Dialog(group="Characteristics"));
final parameter Modelica.SIunits.VolumeFlowRate q_single0=w0/(Np0*rho0)
"Nominal volume flow rate (single pump)"
annotation(Evaluate = true);
final parameter Modelica.SIunits.Height head0=dp0/(rho0*g)
"Nominal pump head"
annotation(Evaluate = true);
final parameter Real d_head_dq_0=
(flowCharacteristic(q_single0*1.05) - flowCharacteristic(q_single0*0.95))/
(q_single0*0.1)
"Approximate derivative of flow characteristic w.r.t. volume flow"
annotation(Evaluate = true);
final parameter Real d_head_dn_0 = 2/n0*head0 - q_single0/n0*d_head_dq_0
"Approximate derivative of the flow characteristic w.r.t. rotational speed"
annotation(Evaluate = true);
Modelica.SIunits.MassFlowRate w_single(start=wstart/Np0)
"Mass flow rate (single pump)";
Modelica.SIunits.MassFlowRate w=Np*w_single "Mass flow rate (total)";
Modelica.SIunits.VolumeFlowRate q_single(start=wstart/(Np0*rho0))
"Volume flow rate (single pump)";
Modelica.SIunits.VolumeFlowRate q=Np*q_single "Volume flow rate (total)";
Modelica.SIunits.Pressure dp "Outlet pressure minus inlet pressure";
Modelica.SIunits.Height head "Pump head";
Medium.SpecificEnthalpy h(start=hstart) "Fluid specific enthalpy";
Medium.SpecificEnthalpy hin "Enthalpy of entering fluid";
Medium.SpecificEnthalpy hout "Enthalpy of outgoing fluid";
ThermoPower.LiquidDensity rho "Liquid density";
Medium.Temperature Tin "Liquid inlet temperature";
AngularVelocity_rpm n "Shaft r.p.m.";
Integer Np(min=1) "Number of pumps in parallel";
Modelica.SIunits.Power W_single "Power Consumption (single pump)";
Modelica.SIunits.Power W=Np*W_single "Power Consumption (total)";
constant Modelica.SIunits.Power W_eps=1e-8
"Small coefficient to avoid numerical singularities";
constant AngularVelocity_rpm n_eps=1e-6;
Real eta "Pump efficiency";
Real s(start = 1, final unit = "1") "Auxiliary non-dimensional variable";
ThermoPower.Water.FlangeA infl(redeclare package Medium = Medium, m_flow(min=
if allowFlowReversal then -Modelica.Constants.inf else 0))
annotation (Placement(transformation(extent={{-100,0},{-60,40}}, rotation=0)));
ThermoPower.Water.FlangeB outfl(redeclare package Medium = Medium, m_flow(max=
if allowFlowReversal then +Modelica.Constants.inf else 0)) annotation (
Placement(transformation(extent={{40,50},{80,90}}, rotation=0)));
Modelica.Blocks.Interfaces.IntegerInput in_Np "Number of parallel pumps"
annotation (Placement(transformation(
origin={28,80},
extent={{-10,-10},{10,10}},
rotation=270)));
equation
// Number of pumps in parallel
Np = in_Np;
if cardinality(in_Np) == 0 then
in_Np = Np0 "Number of pumps selected by parameter";
end if;
// Flow equations
q_single = w_single/homotopy(rho, rho0);
head = dp/(homotopy(rho, rho0)*g);
if noEvent(s > 0 or (not CheckValve)) then
// Flow characteristics when check valve is open
q_single = s*q_single0;
head = homotopy((n/n0)^2*flowCharacteristic(q_single*n0/(n + n_eps)),
head0 + d_head_dq_0*(q_single - q_single0) +
d_head_dn_0*(n - n0));
else
// Flow characteristics when check valve is closed
head = homotopy((n/n0)^2*flowCharacteristic(0) - s*head0,
head0 + d_head_dq_0*(q_single - q_single0) +
d_head_dn_0*(n - n0));
q_single = 0;
end if;
// Power consumption
if usePowerCharacteristic then
W_single = (n/n0)^3*(rho/rho0)*
powerCharacteristic(q_single*n0/(n + n_eps))
"Power consumption (single pump)";
eta = (dp*q_single)/(W_single + W_eps) "Hydraulic efficiency";
else
eta = efficiencyCharacteristic(q_single*n0/(n + n_eps));
W_single = dp*q_single/eta;
end if;
// Fluid properties
inletFluidState = Medium.setState_ph(infl.p, hin);
rho = Medium.density(inletFluidState);
Tin = Medium.temperature(inletFluidState);
// Boundary conditions
dp = outfl.p - infl.p;
w = infl.m_flow "Pump total flow rate";
hin = homotopy(if not allowFlowReversal then inStream(infl.h_outflow)
else if w >= 0 then inStream(infl.h_outflow)
else inStream(outfl.h_outflow),
inStream(infl.h_outflow));
infl.h_outflow = hout;
outfl.h_outflow = hout;
h = hout;
// Mass and energy balances
infl.m_flow + outfl.m_flow = 0 "Mass balance";
if V > 0 then
(rho*V*der(h)) = (outfl.m_flow/Np)*hout + (infl.m_flow/Np)*hin +
W_single "Energy balance";
else
0 = (outfl.m_flow/Np)*hout + (infl.m_flow/Np)*hin + W_single
"Energy balance";
end if;
initial equation
if initOpt == ThermoPower.Choices.Init.Options.noInit then
// do nothing
elseif initOpt == ThermoPower.Choices.Init.Options.steadyState then
if V > 0 then
der(h) = 0;
end if;
else
assert(false, "Unsupported initialisation option");
end if;
annotation (
Icon(graphics),
Diagram(graphics),
Documentation(info="
This is the base model for the Pump and
PumpMech pump models.
The model describes a centrifugal pump, or a group of Np identical pumps in parallel. The pump model is based on the theory of kinematic similarity: the pump characteristics are given for nominal operating conditions (rotational speed and fluid density), and then adapted to actual operating condition, according to the similarity equations.
In order to avoid singularities in the computation of the outlet enthalpy at zero flowrate, the thermal capacity of the fluid inside the pump body can be taken into account.
The model can either support reverse flow conditions or include a built-in check valve to avoid flow reversal.
Modelling options
The nominal hydraulic characteristic (head vs. volume flow rate) is given by the the replaceable function flowCharacteristic.
The pump energy balance can be specified in two alternative ways:
- usePowerCharacteristic = false (default option): the replaceable function efficiencyCharacteristic (efficiency vs. volume flow rate in nominal conditions) is used to determine the efficiency, and then the power consumption. The default is a constant efficiency of 0.8.
- usePowerCharacteristic = true: the replaceable function powerCharacteristic (power consumption vs. volume flow rate in nominal conditions) is used to determine the power consumption, and then the efficiency.
Several functions are provided in the package Functions.PumpCharacteristics to specify the characteristics as a function of some operating points at nominal conditions.
Depending on the value of the checkValve parameter, the model either supports reverse flow conditions, or includes a built-in check valve to avoid flow reversal.
If the in_Np input connector is wired, it provides the number of pumps in parallel; otherwise, Np0 parallel pumps are assumed.
It is possible to take into account the heat capacity of the fluid inside the pump by specifying its volume V at nominal conditions; this is necessary to avoid singularities in the computation of the outlet enthalpy in case of zero flow rate. If zero flow rate conditions are always avoided, this dynamic effect can be neglected by leaving the default value V = 0, thus avoiding a fast state variable in the model.
The CheckValve parameter determines whether the pump has a built-in check valve or not.
If computeNPSHa = true, the available net positive suction head is also computed; this requires a two-phase medium model to provide the fluid saturation pressure.
", revisions="
"));
end PumpBase;
partial model SteamTurbineBase "Steam turbine"
replaceable package Medium = ThermoPower.Water.StandardWater
constrainedby Modelica.Media.Interfaces.PartialMedium "Medium model"
annotation(choicesAllMatching = true);
parameter Boolean explicitIsentropicEnthalpy=true
"Outlet enthalpy computed by isentropicEnthalpy function";
parameter Modelica.SIunits.MassFlowRate wstart=wnom
"Mass flow rate start value" annotation (Dialog(tab="Initialisation"));
parameter Real PRstart "Pressure ratio start value"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.MassFlowRate wnom "Inlet nominal flowrate";
parameter Modelica.SIunits.Pressure pnom "Nominal inlet pressure";
parameter Real eta_mech=0.98 "Mechanical efficiency";
parameter Boolean allowFlowReversal=system.allowFlowReversal
"= true to allow flow reversal, false restricts to design direction";
outer ThermoPower.System system "System wide properties";
Medium.ThermodynamicState steamState_in;
Medium.ThermodynamicState steamState_iso;
Modelica.SIunits.Angle phi "shaft rotation angle";
Modelica.SIunits.Torque tau "net torque acting on the turbine";
Modelica.SIunits.AngularVelocity omega "shaft angular velocity";
Modelica.SIunits.MassFlowRate w(start=wstart) "Mass flow rate";
Medium.SpecificEnthalpy hin "Inlet enthalpy";
Medium.SpecificEnthalpy hout "Outlet enthalpy";
Medium.SpecificEnthalpy hiso "Isentropic outlet enthalpy";
Medium.SpecificEntropy sin "Inlet entropy";
Medium.AbsolutePressure pin(start=pnom) "Outlet pressure";
Medium.AbsolutePressure pout(start=pnom/PRstart) "Outlet pressure";
Real PR "pressure ratio";
Modelica.SIunits.Power Pm "Mechanical power input";
Real eta_iso "Isentropic efficiency";
Modelica.Blocks.Interfaces.RealInput partialArc annotation (Placement(
transformation(extent={{-60,-50},{-40,-30}}, rotation=0)));
Modelica.Mechanics.Rotational.Interfaces.Flange_a shaft_a annotation (
Placement(transformation(extent={{-76,-10},{-56,10}}, rotation=0)));
Modelica.Mechanics.Rotational.Interfaces.Flange_b shaft_b annotation (
Placement(transformation(extent={{54,-10},{74,10}}, rotation=0)));
ThermoPower.Water.FlangeA inlet(redeclare package Medium = Medium, m_flow(min=
if allowFlowReversal then -Modelica.Constants.inf else 0)) annotation (
Placement(transformation(extent={{-100,60},{-60,100}}, rotation=0)));
ThermoPower.Water.FlangeB outlet(redeclare package Medium = Medium, m_flow(
max=if allowFlowReversal then +Modelica.Constants.inf else 0))
annotation (Placement(transformation(extent={{60,60},{100,100}}, rotation=0)));
equation
PR = pin/pout "Pressure ratio";
if cardinality(partialArc) == 0 then
partialArc = 1 "Default value if not connected";
end if;
if explicitIsentropicEnthalpy then
hiso = Medium.isentropicEnthalpy(pout, steamState_in)
"Isentropic enthalpy";
//dummy assignments
sin = 0;
steamState_iso = Medium.setState_ph(1e5, 1e5);
else
sin = Medium.specificEntropy(steamState_in);
steamState_iso = Medium.setState_ps(pout, sin);
hiso = Medium.specificEnthalpy(steamState_iso);
end if;
hin - hout = eta_iso*(hin - hiso) "Computation of outlet enthalpy";
Pm = eta_mech*w*(hin - hout) "Mechanical power from the steam";
Pm = -tau*omega "Mechanical power balance";
inlet.m_flow + outlet.m_flow = 0 "Mass balance";
// assert(w >= -wnom/100, "The turbine model does not support flow reversal");
// Mechanical boundary conditions
shaft_a.phi = phi;
shaft_b.phi = phi;
shaft_a.tau + shaft_b.tau = tau;
der(phi) = omega;
// steam boundary conditions and inlet steam properties
steamState_in = Medium.setState_ph(pin, inStream(inlet.h_outflow));
hin = inStream(inlet.h_outflow);
hout = outlet.h_outflow;
pin = inlet.p;
pout = outlet.p;
w = inlet.m_flow;
// The next equation is provided to close the balance but never actually used
inlet.h_outflow = outlet.h_outflow;
annotation (
Icon(graphics={
Polygon(
points={{-28,76},{-28,28},{-22,28},{-22,82},{-60,82},{-60,76},{-28,
76}},
lineColor={0,0,0},
lineThickness=0.5,
fillColor={0,0,255},
fillPattern=FillPattern.Solid),
Polygon(
points={{26,56},{32,56},{32,76},{60,76},{60,82},{26,82},{26,56}},
lineColor={0,0,0},
lineThickness=0.5,
fillColor={0,0,255},
fillPattern=FillPattern.Solid),
Rectangle(
extent={{-60,8},{60,-8}},
lineColor={0,0,0},
fillPattern=FillPattern.Sphere,
fillColor={160,160,164}),
Polygon(
points={{-28,28},{-28,-26},{32,-60},{32,60},{-28,28}},
lineColor={0,0,0},
lineThickness=0.5,
fillColor={0,0,255},
fillPattern=FillPattern.Solid),
Text(extent={{-130,-60},{128,-100}}, textString="%name")}),
Diagram(graphics),
Documentation(info="
This base model contains the basic interface, parameters and definitions for steam turbine models. It lacks the actual performance characteristics, i.e. two more equations to determine the flow rate and the efficiency.
This model does not include any shaft inertia by itself; if that is needed, connect a Modelica.Mechanics.Rotational.Inertia model to one of the shaft connectors.
Modelling options
The following options are available to calculate the enthalpy of the outgoing steam:
- explicitIsentropicEnthalpy = true: the isentropic enthalpy hout_iso is calculated by the Medium.isentropicEnthalpy function.
- explicitIsentropicEnthalpy = false: the isentropic enthalpy is given equating the specific entropy of the inlet steam steam_in and of a fictional steam state steam_iso, which has the same pressure of the outgoing steam, both computed with the function Medium.specificEntropy.
", revisions="
"));
end SteamTurbineBase;
model BaseReader_twophase
"Base reader for the visualization of the state in the simulation (water)"
replaceable package Medium = ThermoPower.Water.StandardWater constrainedby
Modelica.Media.Interfaces.PartialPureSubstance "Medium model";
parameter Boolean allowFlowReversal=system.allowFlowReversal
"= true to allow flow reversal, false restricts to design direction";
outer ThermoPower.System system "System wide properties";
NuclearPowerPlant.Connectors.TwoPhaseFlangeA inlet(redeclare package
Medium = Medium, m_flow(min=if allowFlowReversal then -Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{-80,-20},
{-40,20}}, rotation=0)));
NuclearPowerPlant.Connectors.TwoPhaseFlangeB outlet(redeclare package
Medium = Medium, m_flow(max=if allowFlowReversal then +Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{40,-20},
{80,20}}, rotation=0)));
equation
inlet.m_flow + outlet.m_flow = 0 "Mass balance";
inlet.p = outlet.p "No pressure drop";
// Boundary conditions
inlet.h_outflow = inStream(outlet.h_outflow);
inStream(inlet.h_outflow) = outlet.h_outflow;
annotation (
Icon(graphics={Polygon(
points={{-80,0},{0,32},{80,0},{0,-32},{-80,0}},
lineColor={77,150,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid),Text(
extent={{-80,20},{80,-20}},
lineColor={255,255,255},
fillColor={0,0,255},
fillPattern=FillPattern.Solid,
textString="S")}),
Documentation(info="
This component can be inserted in a hydraulic circuit to measure the temperature of the fluid flowing through it.
Flow reversal is supported.
", revisions="
"));
end BaseReader_twophase;
model BaseReader_water
"Base reader for the visualization of the state in the simulation (water)"
replaceable package Medium = ThermoPower.Water.StandardWater constrainedby
Modelica.Media.Interfaces.PartialPureSubstance "Medium model";
parameter Boolean allowFlowReversal=system.allowFlowReversal
"= true to allow flow reversal, false restricts to design direction";
outer ThermoPower.System system "System wide properties";
ThermoPower.Water.FlangeA inlet(redeclare package Medium = Medium, m_flow(
min=if allowFlowReversal then -Modelica.Constants.inf else 0))
annotation (Placement(transformation(extent={{-80,-20},{-40,20}}, rotation=
0)));
ThermoPower.Water.FlangeB outlet(redeclare package Medium = Medium, m_flow(
max=if allowFlowReversal then +Modelica.Constants.inf else 0))
annotation (Placement(transformation(extent={{40,-20},{80,20}}, rotation=0)));
equation
inlet.m_flow + outlet.m_flow = 0 "Mass balance";
inlet.p = outlet.p "No pressure drop";
// Boundary conditions
inlet.h_outflow = inStream(outlet.h_outflow);
inStream(inlet.h_outflow) = outlet.h_outflow;
annotation (
Icon(graphics={Polygon(
points={{-80,0},{0,32},{80,0},{0,-32},{-80,0}},
lineColor={0,0,255},
fillColor={0,0,255},
fillPattern=FillPattern.Solid),Text(
extent={{-80,20},{80,-20}},
lineColor={255,255,255},
fillColor={0,0,255},
fillPattern=FillPattern.Solid,
textString="S")}),
Documentation(info="
This component can be inserted in a hydraulic circuit to measure the temperature of the fluid flowing through it.
Flow reversal is supported.
", revisions="
"));
end BaseReader_water;
model GravelBed_base
"Gravel bed heat store for high grade cold storage"
extends LAES.Components.Icons.GravelBed;
parameter Integer Nw=1 "Number of volumes on the wall ports";
parameter Modelica.SIunits.Mass M "Total mass of gravel material";
parameter Modelica.SIunits.SpecificHeatCapacity cm "Heat capacity of the gravel";
parameter Modelica.SIunits.Temperature Tvolstart[Nw] annotation (Dialog(tab="Initialisation"));
parameter ThermoPower.Choices.Init.Options initOpt=ThermoPower.Choices.Init.Options.noInit
"Initialisation option" annotation (Dialog(tab="Initialisation"));
constant Real pi=Modelica.Constants.pi;
Modelica.SIunits.Temperature Tvol[Nw](start=Tvolstart) "Volume temperatures";
ThermoPower.Thermal.DHTVolumes port(final N=Nw, T(start=Tvolstart))
annotation (Placement(transformation(extent={{-20,80},{20,100}})));
equation
(M/Nw)*cm*der(Tvol) = port.Q "Energy balance";
port.T = Tvol "surface temperature to port";
annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
Ellipse(
extent={{-20,-80},{0,-100}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid), Ellipse(
extent={{0,-80},{20,-100}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid)}), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end GravelBed_base;
model GravelBed_base_conduction
"Gravel bed heat store for high grade cold storage"
extends LAES.Components.Icons.GravelBed;
parameter Integer Nw=4 "Number of volumes on the wall ports";
parameter Modelica.SIunits.Mass M "Total mass of gravel material";
parameter Modelica.SIunits.SpecificHeatCapacity cm "Heat capacity of the gravel";
parameter Modelica.SIunits.Temperature Tvolstart[Nw]
annotation (Dialog(tab="Initialisation"));
parameter ThermoPower.Choices.Init.Options initOpt=ThermoPower.Choices.Init.Options.noInit
"Initialisation option" annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.ThermalConductivity k "Therml conductivity of the gravel";
parameter Modelica.SIunits.Area A_eff "effective area for conduction";
parameter Modelica.SIunits.Length VolDist "length between volume centres";
constant Real pi=Modelica.Constants.pi;
Modelica.SIunits.Temperature Tvol[Nw](start=Tvolstart) "Volume temperatures";
Modelica.SIunits.Power Q_Cond[Nw-1] "Heat transfer rates by conduction";
ThermoPower.Thermal.DHTVolumes port(final N=Nw, T(start=Tvolstart))
annotation (Placement(transformation(extent={{-20,80},{20,100}})));
equation
//Conduction calculations
for i in 1:Nw-1 loop
Q_Cond[i]=(k*A_eff*(Tvol[i+1]-Tvol[i]))/VolDist;
end for;
//Energy balance calculations
(M/Nw)*cm*der(Tvol[1]) = port.Q[1] + Q_Cond[1] "Conduction into volume 1 from volume 2 only";
(M/Nw)*cm*der(Tvol[Nw]) = port.Q[Nw] - Q_Cond[Nw-1] "Conduction into volume Nw from volume Nw-1 only";
for j in 2:Nw-1 loop
(M/Nw)*cm*der(Tvol[j]) = port.Q[j] + Q_Cond[j] - Q_Cond [j-1] "Energy balance";
end for;
port.T = Tvol "surface temperature to port";
annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
Ellipse(
extent={{-20,-80},{0,-100}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid), Ellipse(
extent={{0,-80},{20,-100}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid)}), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end GravelBed_base_conduction;
model GravelBed_base2 "Gravel bed heat store for high grade cold storage"
extends LAES.Components.Icons.GravelBed;
parameter Integer Nw=1 "Number of volumes on the wall ports";
parameter Modelica.SIunits.Mass M "Total mass of gravel material";
parameter Modelica.SIunits.SpecificHeatCapacity cm "Heat capacity of the gravel";
parameter Modelica.SIunits.Temperature Tstart1
"Temperature start value - first volume"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.Temperature TstartN
"Temperature start value - last volume"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.Temperature Tvolstart[Nw]=
ThermoPower.Functions.linspaceExt(Tstart1, TstartN, Nw)
annotation (Dialog(tab="Initialisation"));
parameter ThermoPower.Choices.Init.Options initOpt=ThermoPower.Choices.Init.Options.noInit
"Initialisation option" annotation (Dialog(tab="Initialisation"));
constant Real pi=Modelica.Constants.pi;
Modelica.SIunits.Temperature Tvol[Nw](start=Tvolstart) "Volume temperatures";
ThermoPower.Thermal.DHTVolumes port(final N=Nw, T(start=Tvolstart))
annotation (Placement(transformation(extent={{-20,80},{20,100}})));
equation
for j in 1:Nw loop
(M/Nw)*cm*der(Tvol[j]) = port.Q[j] "Energy balance";
end for;
port.T = Tvol "surface temperature to port";
annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
Ellipse(
extent={{-20,-80},{0,-100}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid), Ellipse(
extent={{0,-80},{20,-100}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid)}), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end GravelBed_base2;
partial block SO "Single Output continuous control block"
extends Modelica.Blocks.Icons.Block;
NuclearPowerPlant.Connectors.RealOutput_control y
"Connector of Real output signal"
annotation (Placement(transformation(extent={{100,-10},{120,10}})));
annotation (Documentation(info="
Block has one continuous Real output signal.
"));
end SO;
model GravelBed_base_conduction_multiport "Gravel bed heat store for high grade cold storage including multiple flows"
extends LAES.Components.Icons.GravelBed;
parameter Integer Nw=4 "Number of volumes on the wall ports";
parameter Modelica.SIunits.Mass M "Total mass of gravel material";
parameter Modelica.SIunits.SpecificHeatCapacity cm "Heat capacity of the gravel";
parameter Modelica.SIunits.Temperature Tstart1
"Temperature start value - first volume"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.Temperature TstartN
"Temperature start value - last volume"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.Temperature Tvolstart[Nw]=
ThermoPower.Functions.linspaceExt(Tstart1, TstartN, Nw)
annotation (Dialog(tab="Initialisation"));
parameter ThermoPower.Choices.Init.Options initOpt=ThermoPower.Choices.Init.Options.noInit
"Initialisation option" annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.ThermalConductivity k "Therml conductivity of the gravel";
parameter Modelica.SIunits.Area A_eff "effective area for conduction";
parameter Modelica.SIunits.Length VolDist "length between volume centres";
constant Real pi=Modelica.Constants.pi;
Modelica.SIunits.Temperature Tvol[Nw](start=Tvolstart) "Volume temperatures";
Modelica.SIunits.Power Q_Cond[Nw-1] "Heat transfer rates by conduction";
ThermoPower.Thermal.DHTVolumes dischargePort(final N=Nw, T(start=Tvolstart)) annotation (Placement(transformation(extent={{-20,80},{20,100}})));
ThermoPower.Thermal.DHTVolumes chargePort(final N=Nw, T(start=Tvolstart)) annotation (Placement(transformation(extent={{-20,-100},{20,-80}})));
equation
//Conduction calculations
for i in 1:Nw-1 loop
Q_Cond[i]=(k*A_eff*(Tvol[i+1]-Tvol[i]))/VolDist;
end for;
//Energy balance calculations
(M/Nw)*cm*der(Tvol[1]) =chargePort.Q[1] + dischargePort.Q[1] + Q_Cond[1]
"Conduction into volume 1 from volume 2 only";
(M/Nw)*cm*der(Tvol[Nw]) =chargePort.Q[Nw-1] + dischargePort.Q[Nw-1] - Q_Cond[Nw - 1]
"Conduction into volume Nw from volume Nw-1 only";
for j in 2:Nw-1 loop
(M/Nw)*cm*der(Tvol[j]) =chargePort.Q[Nw-1] + dischargePort.Q[Nw-1] + Q_Cond[j] - Q_Cond[j - 1]
"Energy balance";
end for;
//Define temperature equations
chargePort.T = Tvol;
dischargePort.T = Tvol;
//Connect internal connectors
annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
Ellipse(
extent={{-20,-80},{0,-100}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid), Ellipse(
extent={{0,-80},{20,-100}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid)}), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end GravelBed_base_conduction_multiport;
model Coldbox_metal "Metal core for multistream cold box heat exchanger model"
extends LAES.Components.Icons.ColdBox_metal;
parameter Integer Nw=4 "Number of volumes on the wall ports";
parameter Modelica.SIunits.Mass M "Total mass of metal";
parameter Modelica.SIunits.SpecificHeatCapacity cm "Heat capacity of the metal";
parameter Modelica.SIunits.Temperature Tstart1
"Temperature start value - first volume"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.Temperature TstartN
"Temperature start value - last volume"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.Temperature Tvolstart[Nw]=
ThermoPower.Functions.linspaceExt(Tstart1, TstartN, Nw)
annotation (Dialog(tab="Initialisation"));
parameter ThermoPower.Choices.Init.Options initOpt=ThermoPower.Choices.Init.Options.noInit
"Initialisation option" annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.ThermalConductivity k "Therml conductivity of the metal";
parameter Modelica.SIunits.Area A_eff "effective area for conduction";
parameter Modelica.SIunits.Length VolDist "length between volume centres";
constant Real pi=Modelica.Constants.pi;
Modelica.SIunits.Temperature Tvol[Nw](start=Tvolstart) "Volume temperatures";
Modelica.SIunits.Power Q_Cond[Nw-1] "Heat transfer rates by conduction";
ThermoPower.Thermal.DHTVolumes feedPort(final N=Nw, T(start=Tvolstart)) annotation (Placement(transformation(
extent={{-20,-10},{20,10}},
rotation=-90,
origin={-90,0})));
ThermoPower.Thermal.DHTVolumes returnPort(final N=Nw, T(start=Tvolstart)) annotation (Placement(transformation(extent={{-20,-10},{20,10}},
rotation=90,
origin={90,0}), iconTransformation(extent={{-20,-10},{20,10}},
rotation=90,
origin={90,0})));
ThermoPower.Thermal.DHTVolumes coldstorePort(final N=Nw, T(start=Tvolstart)) annotation (Placement(transformation(
extent={{-20,-10},{20,10}},
rotation=0,
origin={0,-90})));
equation
//Conduction calculations
for i in 1:Nw-1 loop
Q_Cond[i]=(k*A_eff*(Tvol[i+1]-Tvol[i]))/VolDist;
end for;
//Energy balance calculations
(M/Nw)*cm*der(Tvol[1]) =feedPort.Q[1] + returnPort.Q[1] + coldstorePort.Q[1] + Q_Cond[1]
"Conduction into volume 1 from volume 2 only";
(M/Nw)*cm*der(Tvol[Nw]) =feedPort.Q[Nw] + returnPort.Q[Nw] + coldstorePort.Q[Nw] - Q_Cond[Nw - 1]
"Conduction into volume Nw from volume Nw-1 only";
for j in 2:Nw-1 loop
(M/Nw)*cm*der(Tvol[j]) =feedPort.Q[j] + returnPort.Q[j] + Q_Cond[j] + coldstorePort.Q[j] - Q_Cond[j - 1]
"Energy balance";
end for;
//Define temperature equations
returnPort.T = Tvol;
feedPort.T = Tvol;
coldstorePort.T = Tvol;
annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end Coldbox_metal;
partial model TwoPhaseFlow1DBase_ultra
"Basic interface for 1-dimensional two phase medium flow models"
replaceable package Medium = ThermoPower.Water.StandardWater constrainedby
Modelica.Media.Interfaces.PartialMedium "Medium model"
annotation(choicesAllMatching = true);
extends ThermoPower.Icons.Water.Tube;
constant Real pi = Modelica.Constants.pi;
parameter Integer N(min=2) = 2 "Number of nodes for thermal variables";
parameter Integer Nw = N - 1 "Number of volumes on the wall interface";
parameter Integer Nt = 1 "Number of tubes in parallel";
parameter Modelica.SIunits.Distance L "Tube length" annotation (Evaluate=true);
parameter Modelica.SIunits.Position H=0 "Elevation of outlet over inlet";
parameter Modelica.SIunits.Area A "Cross-sectional area (single tube)";
parameter Modelica.SIunits.Length omega
"Perimeter of heat transfer surface (single tube)";
parameter Modelica.SIunits.Length Dhyd=omega/pi
"Hydraulic Diameter (single tube)";
parameter Modelica.SIunits.MassFlowRate wnom "Nominal mass flowrate (total)";
parameter ThermoPower.Choices.Flow1D.FFtypes FFtype=ThermoPower.Choices.Flow1D.FFtypes.NoFriction
"Friction Factor Type"
annotation (Evaluate=true);
parameter Modelica.SIunits.Pressure dpnom=0
"Nominal pressure drop (friction term only!)";
parameter Real Kfnom = 0
"Nominal hydraulic resistance coefficient (DP = Kfnom*w^2/rho)"
annotation(Dialog(enable = (FFtype == ThermoPower.Choices.Flow1D.FFtypes.Kfnom)));
parameter ThermoPower.Density rhonom=0 "Nominal inlet density" annotation (
Dialog(enable=(FFtype == ThermoPower.Choices.Flow1D.FFtypes.OpPoint)));
parameter Real Cfnom=0 "Nominal Fanning friction factor"
annotation(Dialog(enable = (FFtype == ThermoPower.Choices.Flow1D.FFtypes.Cfnom)));
parameter Real e=0 "Relative roughness (ratio roughness/diameter)"
annotation(Dialog(enable = (FFtype == ThermoPower.Choices.Flow1D.FFtypes.Colebrook)));
parameter Real Kfc=1 "Friction factor correction coefficient";
parameter Boolean DynamicMomentum=false
"Inertial phenomena accounted for"
annotation (Evaluate=true);
parameter ThermoPower.Choices.Flow1D.HCtypes HydraulicCapacitance=ThermoPower.Choices.Flow1D.HCtypes.Downstream
"Location of the hydraulic capacitance";
parameter Boolean avoidInletEnthalpyDerivative=true
"Avoid inlet enthalpy derivative";
parameter Boolean allowFlowReversal=system.allowFlowReversal
"= true to allow flow reversal, false restricts to design direction";
outer ThermoPower.System system "System wide properties";
parameter ThermoPower.Choices.FluidPhase.FluidPhases FluidPhaseStart=
ThermoPower.Choices.FluidPhase.FluidPhases.Liquid
"Fluid phase (only for initialization!)"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.Pressure pstart=1e5 "Pressure start value"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.SpecificEnthalpy hstartin=if FluidPhaseStart ==
ThermoPower.Choices.FluidPhase.FluidPhases.Liquid then 1e5 else if
FluidPhaseStart == ThermoPower.Choices.FluidPhase.FluidPhases.Steam then 3e6
else 1e6 "Inlet enthalpy start value"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.SpecificEnthalpy hstartout=if FluidPhaseStart ==
ThermoPower.Choices.FluidPhase.FluidPhases.Liquid then 1e5 else if
FluidPhaseStart == ThermoPower.Choices.FluidPhase.FluidPhases.Steam then 3e6
else 1e6 "Outlet enthalpy start value"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.SpecificEnthalpy hstart[N]=linspace(
hstartin,
hstartout,
N) "Start value of enthalpy vector (initialized by default)"
annotation (Dialog(tab="Initialisation"));
parameter Real wnf=0.02
"Fraction of nominal flow rate at which linear friction equals turbulent friction";
parameter ThermoPower.Choices.Init.Options initOpt=ThermoPower.Choices.Init.Options.noInit
"Initialisation option" annotation (Dialog(tab="Initialisation"));
constant Real g=Modelica.Constants.g_n;
function squareReg = ThermoPower.Functions.squareReg;
NuclearPowerPlant.Connectors.TwoPhaseFlangeA infl(
h_outflow(start=hstartin),
redeclare package Medium = Medium,
m_flow(start=wnom, min=if allowFlowReversal then -Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{-120,-20},{-80,
20}}, rotation=0)));
NuclearPowerPlant.Connectors.TwoPhaseFlangeB outfl(
h_outflow(start=hstartout),
redeclare package Medium = Medium,
m_flow(start=-wnom, max=if allowFlowReversal then +Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{80,-20},{120,20}},
rotation=0)));
// replaceable ThermoPower.Thermal.DHT wall(N=N) annotation (Dialog(enable=
// false), Placement(transformation(extent={{-40,40},{40,60}},
// rotation=0)));
Modelica.SIunits.Power Q
"Total heat flow through the lateral boundary (all Nt tubes)";
Modelica.SIunits.Time Tr "Residence time";
final parameter Real dzdx=H/L "Slope" annotation (Evaluate=true);
final parameter Modelica.SIunits.Length l=L/(N - 1)
"Length of a single volume" annotation (Evaluate=true);
equation
assert(FFtype == ThermoPower.Choices.Flow1D.FFtypes.NoFriction or dpnom > 0,
"dpnom=0 not valid, it is also used in the homotopy trasformation during the inizialization");
annotation (
Documentation(info="
Basic interface of the Flow1D models, containing the common parameters and connectors.
", revisions=
"
"),Diagram(graphics),
Icon(graphics));
end TwoPhaseFlow1DBase_ultra;
partial model TwoPhaseFlow1DBase_dpPara_ultra
"Basic interface for 1-dimensional two phase medium flow models with parameter pressure drop"
replaceable package Medium = ThermoPower.Water.StandardWater constrainedby
Modelica.Media.Interfaces.PartialMedium "Medium model"
annotation(choicesAllMatching = true);
extends ThermoPower.Icons.Water.Tube;
constant Real pi = Modelica.Constants.pi;
parameter Integer N(min=2) = 2 "Number of nodes for thermal variables";
parameter Integer Nw = N - 1 "Number of volumes on the wall interface";
parameter Integer Nt = 1 "Number of tubes in parallel";
parameter Modelica.SIunits.Distance L "Tube length" annotation (Evaluate=true);
parameter Modelica.SIunits.Position H=0 "Elevation of outlet over inlet";
parameter Modelica.SIunits.Area A "Cross-sectional area (single tube)";
parameter Modelica.SIunits.Length omega
"Perimeter of heat transfer surface (single tube)";
parameter Modelica.SIunits.Length Dhyd=omega/pi
"Hydraulic Diameter (single tube)";
parameter Modelica.SIunits.MassFlowRate wnom "Nominal mass flowrate (total)";
parameter Boolean DynamicMomentum=false
"Inertial phenomena accounted for"
annotation (Evaluate=true);
parameter ThermoPower.Choices.Flow1D.HCtypes HydraulicCapacitance=ThermoPower.Choices.Flow1D.HCtypes.Downstream
"Location of the hydraulic capacitance";
parameter Boolean avoidInletEnthalpyDerivative=true
"Avoid inlet enthalpy derivative";
parameter Boolean allowFlowReversal=system.allowFlowReversal
"= true to allow flow reversal, false restricts to design direction";
outer ThermoPower.System system "System wide properties";
parameter ThermoPower.Choices.FluidPhase.FluidPhases FluidPhaseStart=
ThermoPower.Choices.FluidPhase.FluidPhases.Liquid
"Fluid phase (only for initialization!)"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.Pressure pstart=1e5 "Pressure start value"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.SpecificEnthalpy hstartin=if FluidPhaseStart ==
ThermoPower.Choices.FluidPhase.FluidPhases.Liquid then 1e5 else if
FluidPhaseStart == ThermoPower.Choices.FluidPhase.FluidPhases.Steam then 3e6
else 1e6 "Inlet enthalpy start value"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.SpecificEnthalpy hstartout=if FluidPhaseStart ==
ThermoPower.Choices.FluidPhase.FluidPhases.Liquid then 1e5 else if
FluidPhaseStart == ThermoPower.Choices.FluidPhase.FluidPhases.Steam then 3e6
else 1e6 "Outlet enthalpy start value"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.SpecificEnthalpy hstart[N]=linspace(
hstartin,
hstartout,
N) "Start value of enthalpy vector (initialized by default)"
annotation (Dialog(tab="Initialisation"));
parameter ThermoPower.Choices.Init.Options initOpt=ThermoPower.Choices.Init.Options.noInit
"Initialisation option" annotation (Dialog(tab="Initialisation"));
constant Real g=Modelica.Constants.g_n;
function squareReg = ThermoPower.Functions.squareReg;
NuclearPowerPlant.Connectors.TwoPhaseFlangeA infl(
h_outflow(start=hstartin),
redeclare package Medium = Medium,
m_flow(start=wnom, min=if allowFlowReversal then -Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{-120,-20},{-80,
20}}, rotation=0)));
NuclearPowerPlant.Connectors.TwoPhaseFlangeB outfl(
h_outflow(start=hstartout),
redeclare package Medium = Medium,
m_flow(start=-wnom, max=if allowFlowReversal then +Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{80,-20},{120,20}},
rotation=0)));
// replaceable ThermoPower.Thermal.DHT wall(N=N) annotation (Dialog(enable=
// false), Placement(transformation(extent={{-40,40},{40,60}},
// rotation=0)));
Modelica.SIunits.Power Q
"Total heat flow through the lateral boundary (all Nt tubes)";
Modelica.SIunits.Time Tr "Residence time";
final parameter Real dzdx=H/L "Slope" annotation (Evaluate=true);
final parameter Modelica.SIunits.Length l=L/(N - 1)
"Length of a single volume" annotation (Evaluate=true);
annotation (
Documentation(info="
Basic interface of the Flow1D models, containing the common parameters and connectors.
", revisions=
"
"),Diagram(graphics),
Icon(graphics));
end TwoPhaseFlow1DBase_dpPara_ultra;
model GravelBed_base_new
"Gravel bed heat store for high grade cold storage"
extends LAES.Components.Icons.GravelBed;
parameter Integer Nw=1 "Number of volumes on the wall ports";
parameter Modelica.SIunits.Mass M "Total mass of gravel material";
parameter Modelica.SIunits.SpecificHeatCapacity cm "Heat capacity of the gravel";
parameter Modelica.SIunits.Temperature Tstart1
"Temperature start value - first volume"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.Temperature TstartN
"Temperature start value - last volume"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.Temperature Tvolstart[Nw]=
ThermoPower.Functions.linspaceExt(Tstart1, TstartN, Nw)
annotation (Dialog(tab="Initialisation"));
parameter Boolean InitTemp = true
"Initialisation option" annotation (Dialog(tab="Initialisation"));
constant Real pi=Modelica.Constants.pi;
Modelica.SIunits.Temperature Tvol[Nw] "Volume temperatures";
ThermoPower.Thermal.DHTVolumes port(final N=Nw, T(start=Tvolstart))
annotation (Placement(transformation(extent={{-20,80},{20,100}})));
equation
(M/Nw)*cm*der(Tvol) = port.Q "Energy balance";
port.T = Tvol "surface temperature to port";
initial equation
if InitTemp then Tvol[Nw]=Tvolstart[Nw];
else
end if;
annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
Ellipse(
extent={{-20,-80},{0,-100}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid), Ellipse(
extent={{0,-80},{20,-100}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid)}), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end GravelBed_base_new;
model GravelBed_base_reverse
"Gravel bed heat store for high grade cold storage"
extends LAES.Components.Icons.GravelBed;
parameter Integer Nw=1 "Number of volumes on the wall ports";
parameter Modelica.SIunits.Mass M "Total mass of gravel material";
parameter Modelica.SIunits.SpecificHeatCapacity cm "Heat capacity of the gravel";
parameter Modelica.SIunits.Temperature Tvolstart[Nw] annotation (Dialog(tab="Initialisation"));
parameter ThermoPower.Choices.Init.Options initOpt=ThermoPower.Choices.Init.Options.noInit
"Initialisation option" annotation (Dialog(tab="Initialisation"));
constant Real pi=Modelica.Constants.pi;
parameter Modelica.SIunits.Temperature Tvolstartrev[Nw];
Modelica.SIunits.Temperature Tvol[Nw] "Volume temperatures";
ThermoPower.Thermal.DHTVolumes port(final N=Nw, T(start=Tvolstart))
annotation (Placement(transformation(extent={{-20,80},{20,100}})));
equation
(M/Nw)*cm*der(Tvol) = port.Q "Energy balance";
port.T = Tvol "surface temperature to port";
initial equation
for i in 1:1:Nw loop
Tvol[i]=Tvolstart[Nw-(i-1)];
end for;
annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
Ellipse(
extent={{-20,-80},{0,-100}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid), Ellipse(
extent={{0,-80},{20,-100}},
lineColor={0,0,0},
fillColor={77,150,0},
fillPattern=FillPattern.Solid)}), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end GravelBed_base_reverse;
end BaseClasses;
package Flow "Flows, sources and sinks"
package TwoPhaseSources "Sinks and sources for two-phase media"
model SourcePressureTwoPhase "Pressure source for water/steam flows"
extends LAES.Components.Icons.SourcePTwoPhase;
replaceable package Medium = ThermoPower.Water.StandardWater constrainedby
Modelica.Media.Interfaces.PartialMedium "Medium model"
annotation(choicesAllMatching = true);
parameter Modelica.SIunits.Pressure p0=1.01325e5 "Nominal pressure";
parameter ThermoPower.HydraulicResistance R=0 "Hydraulic resistance";
parameter Modelica.SIunits.SpecificEnthalpy h=1e5 "Nominal specific enthalpy";
parameter Boolean allowFlowReversal=system.allowFlowReversal
"= true to allow flow reversal, false restricts to design direction";
parameter Boolean use_in_p0 = false "Use connector input for the pressure" annotation(Dialog(group="External inputs"), choices(checkBox=true));
parameter Boolean use_in_h = false
"Use connector input for the specific enthalpy" annotation(Dialog(group="External inputs"), choices(checkBox=true));
outer ThermoPower.System system "System wide properties";
Modelica.SIunits.Pressure p "Actual pressure";
NuclearPowerPlant.Connectors.TwoPhaseFlangeB flange(redeclare package
Medium = Medium, m_flow(max=if allowFlowReversal then +Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{80,-20},
{120,20}}, rotation=0)));
NuclearPowerPlant.Connectors.RealInput_control in_p0 if use_in_p0
annotation (Placement(transformation(
origin={-40,92},
extent={{-20,-20},{20,20}},
rotation=270)));
NuclearPowerPlant.Connectors.RealInput_control in_h if use_in_h
annotation (Placement(transformation(
origin={40,90},
extent={{-20,-20},{20,20}},
rotation=270)));
protected
Modelica.Blocks.Interfaces.RealInput in_p0_internal;
Modelica.Blocks.Interfaces.RealInput in_h_internal;
equation
if R == 0 then
flange.p = p;
else
flange.p = p + flange.m_flow*R;
end if;
p = in_p0_internal;
if not use_in_p0 then
in_p0_internal = p0 "Pressure set by parameter";
end if;
flange.h_outflow = in_h_internal;
if not use_in_h then
in_h_internal = h "Enthalpy set by parameter";
end if;
// Connect protected connectors to public conditional connectors
connect(in_p0, in_p0_internal);
connect(in_h, in_h_internal);
annotation (
Icon(graphics={Text(extent={{-106,90},{-52,50}}, textString="p0"), Text(
extent={{66,90},{98,52}}, textString="h")}),
Documentation(info="
Modelling options
If R is set to zero, the pressure source is ideal; otherwise, the outlet pressure decreases proportionally to the outgoing flowrate.
If the in_p0 connector is wired, then the source pressure is given by the corresponding signal, otherwise it is fixed to p0.
If the in_h connector is wired, then the source pressure is given by the corresponding signal, otherwise it is fixed to h.
", revisions="
- 16 Dec 2004
by Francesco Casella:
Medium model and standard medium definition added.
- 18 Jun 2004
by Francesco Casella:
Removed p0_fix and hfix; the connection of external signals is now detected automatically.
- 1 Oct 2003
by Francesco Casella:
First release.
"));
end SourcePressureTwoPhase;
model TwoPhaseSinkMassFlow "Flowrate sink for two phase flows"
extends LAES.Components.Icons.SourceWTwoPhase;
replaceable package Medium = ThermoPower.Water.StandardWater constrainedby
Modelica.Media.Interfaces.PartialMedium "Medium model"
annotation(choicesAllMatching = true);
parameter Modelica.SIunits.MassFlowRate w0=0 "Nominal mass flowrate";
parameter Modelica.SIunits.Pressure p0=1e5 "Nominal pressure";
parameter ThermoPower.HydraulicConductance G=0 "Hydraulic conductance";
parameter Modelica.SIunits.SpecificEnthalpy h=1e5 "Nominal specific enthalpy";
parameter Boolean allowFlowReversal=system.allowFlowReversal
"= true to allow flow reversal, false restricts to design direction";
parameter Boolean use_in_w0 = false "Use connector input for the mass flow" annotation(Dialog(group="External inputs"), choices(checkBox=true));
parameter Boolean use_in_h = false
"Use connector input for the specific enthalpy" annotation(Dialog(group="External inputs"), choices(checkBox=true));
outer ThermoPower.System system "System wide properties";
Modelica.SIunits.MassFlowRate w "Mass flowrate";
NuclearPowerPlant.Connectors.TwoPhaseFlangeA flange(redeclare package
Medium = Medium, m_flow(min=if allowFlowReversal then -Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{-120,
-20},{-80,20}}, rotation=0)));
NuclearPowerPlant.Connectors.RealInput_control in_w0 if use_in_w0
annotation (Placement(transformation(
origin={-40,60},
extent={{-20,-20},{20,20}},
rotation=270)));
NuclearPowerPlant.Connectors.RealInput_control in_h if use_in_h
annotation (Placement(transformation(
origin={40,60},
extent={{-20,-20},{20,20}},
rotation=270)));
protected
Modelica.Blocks.Interfaces.RealInput in_w0_internal;
Modelica.Blocks.Interfaces.RealInput in_h_internal;
equation
if G == 0 then
flange.m_flow = w;
else
flange.m_flow = w + (flange.p - p0)*G;
end if;
w = in_w0_internal;
if not use_in_w0 then
in_w0_internal = w0 "Flow rate set by parameter";
end if;
flange.h_outflow = in_h_internal;
if not use_in_h then
in_h_internal = h "Enthalpy set by parameter";
end if;
// Connect protected connectors to public conditional connectors
connect(in_w0, in_w0_internal);
connect(in_h, in_h_internal);
annotation (
Icon(graphics={Text(extent={{-98,72},{-48,40}}, textString="w0"), Text(
extent={{48,72},{98,40}}, textString="h")}),
Documentation(info="
Modelling options
If G is set to zero, the flowrate source is ideal; otherwise, the incoming flowrate increases proportionally to the inlet pressure.
If w0Fix is set to true, the incoming flowrate is given by the parameter w0; otherwise, the in_w0 connector must be wired, providing the (possibly varying) source flowrate.
If hFix is set to true, the source enthalpy is given by the parameter h; otherwise, the in_h connector must be wired, providing the (possibly varying) source enthalpy.
", revisions="
- 16 Dec 2004
by Francesco Casella:
Medium model and standard medium definition added.
- 18 Jun 2004
by Francesco Casella:
Removed p0_fix and hfix; the connection of external signals is now detected automatically.
- 1 Oct 2003
by Francesco Casella:
First release.
"));
end TwoPhaseSinkMassFlow;
model SourceMassFlowTwoPhase
"Flowrate source for two-phase fluid flows"
extends LAES.Components.Icons.SourceWTwoPhase;
replaceable package Medium = ThermoPower.Water.StandardWater constrainedby
Modelica.Media.Interfaces.PartialMedium "Medium model"
annotation(choicesAllMatching = true);
parameter Modelica.SIunits.MassFlowRate w0=0 "Nominal mass flowrate";
parameter Modelica.SIunits.AbsolutePressure p0=1e5 "Nominal pressure";
parameter ThermoPower.HydraulicConductance G=0 "Hydraulic conductance";
parameter Modelica.SIunits.SpecificEnthalpy h=1e5 "Nominal specific enthalpy";
parameter Boolean allowFlowReversal=system.allowFlowReversal
"= true to allow flow reversal, false restricts to design direction";
parameter Boolean use_in_w0 = false "Use connector input for the mass flow" annotation(Dialog(group="External inputs"), choices(checkBox=true));
parameter Boolean use_in_h = false
"Use connector input for the specific enthalpy" annotation(Dialog(group="External inputs"), choices(checkBox=true));
parameter Boolean use_in_p0 = false "Use connnector input for the pressure";
outer ThermoPower.System system "System wide properties";
Modelica.SIunits.MassFlowRate w "Mass flowrate";
NuclearPowerPlant.Connectors.TwoPhaseFlangeB flange(redeclare package
Medium = Medium, m_flow(max=if allowFlowReversal then +Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{80,-20},{
120,20}}, rotation=0)));
NuclearPowerPlant.Connectors.RealInput_control in_w0 if use_in_w0
annotation (Placement(transformation(
origin={-40,60},
extent={{-20,-20},{20,20}},
rotation=270), iconTransformation(
extent={{-20,-20},{20,20}},
rotation=270,
origin={-40,60})));
NuclearPowerPlant.Connectors.RealInput_control in_h if use_in_h
annotation (Placement(transformation(
origin={40,60},
extent={{-20,-20},{20,20}},
rotation=270), iconTransformation(
extent={{-20,-20},{20,20}},
rotation=270,
origin={40,60})));
protected
Modelica.Blocks.Interfaces.RealInput in_w0_internal;
Modelica.Blocks.Interfaces.RealInput in_h_internal;
equation
if G == 0 then
flange.m_flow = -w;
else
flange.m_flow = -w + (flange.p - p0)*G;
end if;
w = in_w0_internal;
if not use_in_w0 then
in_w0_internal = w0 "Flow rate set by parameter";
end if;
flange.h_outflow = in_h_internal "Enthalpy set by connector";
if not use_in_h then
in_h_internal = h "Enthalpy set by parameter";
end if;
// Connect protected connectors to public conditional connectors
connect(in_w0, in_w0_internal);
connect(in_h, in_h_internal);
annotation (
Icon(graphics={Text(extent={{-94,70},{-44,38}}, textString="w0"), Text(
extent={{44,70},{94,38}}, textString="h")}),
Documentation(info="
Modelling options
If G is set to zero, the flowrate source is ideal; otherwise, the outgoing flowrate decreases proportionally to the outlet pressure.
If the in_w0 connector is wired, then the source pressure is given by the corresponding signal, otherwise it is fixed to p0.
If the in_h connector is wired, then the source pressure is given by the corresponding signal, otherwise it is fixed to h.
", revisions="
- 16 Dec 2004
by Francesco Casella:
Medium model and standard medium definition added.
- 18 Jun 2004
by Francesco Casella:
Removed p0_fix and hfix; the connection of external signals is now detected automatically.
- 1 Oct 2003
by Francesco Casella:
First release.
"));
end SourceMassFlowTwoPhase;
model SinkPressureTwoPhase "Pressure sink for two-phase fluid flows"
extends LAES.Components.Icons.SourcePTwoPhase;
replaceable package Medium = NuclearPowerPlant.Media.AirRefProp
constrainedby Modelica.Media.Interfaces.PartialPureSubstance
"Fluid model" annotation(choicesAllMatching = true);
parameter Modelica.SIunits.AbsolutePressure p0=1.01325e5 "Nominal pressure";
parameter ThermoPower.HydraulicResistance R=0 "Hydraulic resistance"
annotation (Evaluate=true);
parameter Modelica.SIunits.SpecificEnthalpy h=1e5 "Nominal specific enthalpy";
parameter Boolean allowFlowReversal=system.allowFlowReversal
"= true to allow flow reversal, false restricts to design direction";
parameter Boolean use_in_p0 = false "Use connector input for the pressure" annotation(Dialog(group="External inputs"), choices(checkBox=true));
parameter Boolean use_in_h = false
"Use connector input for the specific enthalpy" annotation(Dialog(group="External inputs"), choices(checkBox=true));
outer ThermoPower.System system "System wide properties";
Modelica.SIunits.AbsolutePressure p "Actual pressure";
NuclearPowerPlant.Connectors.TwoPhaseFlangeA flange(redeclare package
Medium = Medium, m_flow(min=if allowFlowReversal then -Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{-120,-20},
{-80,20}}, rotation=0)));
NuclearPowerPlant.Connectors.RealInput_control in_p0 if use_in_p0
annotation (Placement(transformation(
origin={-40,88},
extent={{-20,-20},{20,20}},
rotation=270)));
NuclearPowerPlant.Connectors.RealInput_control in_h if use_in_h
annotation (Placement(transformation(
origin={40,88},
extent={{-20,-20},{20,20}},
rotation=270)));
protected
Modelica.Blocks.Interfaces.RealInput in_p0_internal;
Modelica.Blocks.Interfaces.RealInput in_h_internal;
equation
if R == 0 then
flange.p = p;
else
flange.p = p + flange.m_flow*R;
end if;
p = in_p0_internal;
if not use_in_p0 then
in_p0_internal = p0 "Pressure set by parameter";
end if;
flange.h_outflow = in_h_internal;
if not use_in_h then
in_h_internal = h "Enthalpy set by parameter";
end if;
// Connect protected connectors to public conditional connectors
connect(in_p0, in_p0_internal);
connect(in_h, in_h_internal);
annotation (
Icon(graphics={Text(extent={{-106,92},{-56,50}}, textString="p0"), Text(
extent={{54,94},{112,52}}, textString="h")}),
Documentation(info="
Modelling options
If R is set to zero, the pressure sink is ideal; otherwise, the inlet pressure increases proportionally to the incoming flowrate.
If the in_p0 connector is wired, then the source pressure is given by the corresponding signal, otherwise it is fixed to p0.
If the in_h connector is wired, then the source pressure is given by the corresponding signal, otherwise it is fixed to h.
", revisions="
- 16 Dec 2004
by Francesco Casella:
Medium model and standard medium definition added.
- 18 Jun 2004
by Francesco Casella:
Removed p0_fix and hfix; the connection of external signals is now detected automatically.
- 1 Oct 2003
by Francesco Casella:
First release.
"));
end SinkPressureTwoPhase;
model AirTank "Air storage tank"
extends LAES.Components.Icons.Tank;
replaceable package Medium = ThermoPower.Water.StandardWater constrainedby
Modelica.Media.Interfaces.PartialMedium "Medium model"
annotation(choicesAllMatching = true);
parameter Modelica.SIunits.AbsolutePressure p=1.01325e5 "Tank pressure";
parameter Boolean allowFlowReversal=system.allowFlowReversal
"= true to allow flow reversal, false restricts to design direction";
outer ThermoPower.System system "System wide properties";
parameter Modelica.SIunits.Mass Mstart "Start mass"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.SpecificEnthalpy hstart=1e5
annotation (Dialog(tab="Initialisation"));
Modelica.SIunits.Volume V "Liquid volume";
Modelica.SIunits.Mass M(start=Mstart) "Liquid mass";
Modelica.SIunits.Enthalpy H "Liquid (total) enthalpy";
Medium.SpecificEnthalpy h(start=hstart, stateSelect=StateSelect.prefer)
"Liquid specific enthalpy";
Medium.SpecificEnthalpy hin "Inlet specific enthalpy";
Medium.SpecificEnthalpy hout "Outlet specific enthalpy";
NuclearPowerPlant.Connectors.TwoPhaseFlangeA inlet(redeclare package
Medium = Medium, m_flow(min=if allowFlowReversal then -Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{-100,-80},
{-60,-40}}, rotation=0)));
NuclearPowerPlant.Connectors.TwoPhaseFlangeB outlet(redeclare package
Medium = Medium, m_flow(max=if allowFlowReversal then +Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{60,-80},{
100,-40}}, rotation=0)));
parameter ThermoPower.Choices.Init.Options initOpt=ThermoPower.Choices.Init.Options.noInit
"Initialisation option" annotation (Dialog(tab="Initialisation"));
equation
V = M/Medium.density_ph(p,h);
H = M*h "Liquid enthalpy";
der(M) = inlet.m_flow + outlet.m_flow "Mass balance";
der(H) = inlet.m_flow*hin + outlet.m_flow*hout "Energy balance";
// Boundary conditions
hin = homotopy(if not allowFlowReversal then inStream(inlet.h_outflow)
else actualStream(inlet.h_outflow), inStream(inlet.h_outflow));
hout = homotopy(if not allowFlowReversal then h else actualStream(outlet.h_outflow),
h);
inlet.h_outflow = h;
outlet.h_outflow = h;
inlet.p = p;
outlet.p = p;
initial equation
if initOpt == ThermoPower.Choices.Init.Options.noInit then
// do nothing
elseif initOpt == ThermoPower.Choices.Init.Options.steadyState then
der(h) = 0;
der(M) = 0;
else
assert(false, "Unsupported initialisation option");
end if;
annotation (
Icon(graphics={Text(extent={{-100,90},{100,64}}, textString="%name")}),
Documentation(info="
This model describes a simple free-surface cylindrical water tank. The model is based on mass and energy balances, assuming that no heat transfer takes place except through the inlet and outlet flows.
", revisions="
"), Diagram(graphics));
end AirTank;
end TwoPhaseSources;
package TwoPhaseFlows "Flows for two phase media"
model TwoPhaseFlow1DFV
"1-dimensional fluid flow model for water/steam (finite volumes, 2-phase)"
//Mass balance is continuous - there is no accumulation in finite volumes
extends LAES.Components.BaseClasses.TwoPhaseFlow1DBase_dpProp(redeclare
replaceable package Medium =
NuclearPowerPlant.Media.PropaneRefProp
constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
"Medium model", FluidPhaseStart=ThermoPower.Choices.FluidPhase.FluidPhases.TwoPhases);
replaceable ThermoPower.Thermal.HeatTransfer.IdealHeatTransfer heatTransfer constrainedby
ThermoPower.Thermal.BaseClasses.DistributedHeatTransferFV(
redeclare package Medium = Medium,
final Nf=N, final Nw = Nw, final Nt = Nt,
final L = L, final A = A, final Dhyd = Dhyd,
final omega = omega, final wnom = wnom/Nt,
final w=w*ones(N), final fluidState=fluidState) "Heat transfer model"
annotation(choicesAllMatching = true);
ThermoPower.Thermal.DHTVolumes wall(final N=Nw) annotation (Dialog(enable=
false), Placement(transformation(extent={{-40,40},{40,60}},
rotation=0)));
import ThermoPower.Choices.Flow1D.FFtypes;
import ThermoPower.Choices.Flow1D.HCtypes;
// package SmoothMedium = Medium (final smoothModel=true);
constant Modelica.SIunits.Pressure pzero=10 "Small deltap for calculations";
constant Modelica.SIunits.Pressure pc=Medium.fluidConstants[1].criticalPressure;
constant Modelica.SIunits.SpecificEnthalpy hzero=1e-3 "Small value for deltah";
constant Real pi=Modelica.Constants.pi;
// SmoothMedium.ThermodynamicState fluidState[N]
// "Thermodynamic state of the fluid at the nodes";
Medium.ThermodynamicState fluidState[N]
"Thermodynamic state of the fluid at the nodes";
Medium.SaturationProperties sat "Properties of saturated fluid";
Modelica.SIunits.Length omega_hyd "Wet perimeter (single tube)";
Modelica.SIunits.Pressure Dpfric "Pressure drop due to friction";
Modelica.SIunits.Pressure Dpstat "Pressure drop due to static head";
Real dwdt "Dynamic momentum term";
Medium.AbsolutePressure p(start=pstart)
"Fluid pressure for property calculations";
/*, stateSelect=StateSelect.prefer*/
Modelica.SIunits.Pressure dpf[N - 1] "Pressure drop due to friction between two nodes";
Modelica.SIunits.MassFlowRate w(start=wnom/Nt) "Mass flowrate (single tube)";
Modelica.SIunits.MassFlowRate wbar[N - 1](each start=wnom/Nt);
Modelica.SIunits.Power Q_single[Nw]
"Heat flows entering the volumes from the lateral boundary (single tube)";
Modelica.SIunits.Velocity u[N] "Fluid velocity";
Medium.Temperature T[N] "Fluid temperature";
Medium.Temperature Ts "Saturated water temperature";
Medium.SpecificEnthalpy h[N](start=hstart) "Fluid specific enthalpy";
Medium.SpecificEnthalpy htilde[N - 1](start=hstart[2:N])
"Enthalpy state variables"; /*,each stateSelect=StateSelect.prefer*/
Medium.SpecificEnthalpy hl "Saturated liquid temperature";
Medium.SpecificEnthalpy hv "Saturated vapour temperature";
Real x[N] "Steam quality";
Medium.Density rho[N] "Fluid density";
ThermoPower.LiquidDensity rhol "Saturated liquid density";
ThermoPower.GasDensity rhov "Saturated vapour density";
Modelica.SIunits.Mass M "Fluid mass";
protected
Modelica.SIunits.DerEnthalpyByPressure dhldp
"Derivative of saturated liquid enthalpy by pressure";
Modelica.SIunits.DerEnthalpyByPressure dhvdp
"Derivative of saturated vapour enthalpy by pressure";
Modelica.SIunits.Density rhobar[N - 1] "Fluid average density";
Modelica.SIunits.DerDensityByPressure drldp
"Derivative of saturated liquid density by pressure";
Modelica.SIunits.DerDensityByPressure drvdp
"Derivative of saturated vapour density by pressure";
Modelica.SIunits.SpecificVolume vbar[N - 1] "Average specific volume";
Real AA;
Real AA1;
Real dMdt[N - 1] "Derivative of fluid mass in each volume";
equation
//All equations are referred to a single tube
omega_hyd = 4*A/Dhyd;
// Dynamic momentum term
if DynamicMomentum then
dwdt = der(w);
else
dwdt = 0;
end if;
sum(dMdt) = (infl.m_flow/Nt + outfl.m_flow/Nt) "Mass balance";
sum(dpf) = Dpfric "Total pressure drop due to friction";
Dpstat = if abs(dzdx) < 1e-6 then 0 else g*l*dzdx*sum(rhobar)
"Pressure drop due to static head";
L/A*dwdt + (outfl.p - infl.p) + Dpstat + Dpfric = 0 "Momentum balance";
for j in 1:(N - 1) loop
A*l*rhobar[j]*der(htilde[j]) + wbar[j]*(h[j + 1] - h[j]) - A*l*der(p) = Q_single[j]
"Energy balance";
dMdt[j] = 0 "Mass balance for each volume";
// Average volume quantities
vbar[j] = 1/rhobar[j] "Average specific volume";
wbar[j] = infl.m_flow/Nt;
dpf[j] = (infl.p*PressureDrop)/(N-1);
if avoidInletEnthalpyDerivative and j == 1 then
// first volume properties computed by the outlet properties
rhobar[j] = rho[j + 1];
elseif noEvent((h[j] < hl and h[j + 1] < hl) or (h[j] > hv and h[j + 1]
> hv) or p >= (pc - pzero) or abs(h[j + 1] - h[j]) < hzero) then
// 1-phase or almost uniform properties
rhobar[j] = (rho[j] + rho[j + 1])/2;
elseif noEvent(h[j] >= hl and h[j] <= hv and h[j + 1] >= hl and h[j + 1]
<= hv) then
// 2-phase
rhobar[j] = AA*log(rho[j]/rho[j + 1])/(h[j + 1] - h[j]);
elseif noEvent(h[j] < hl and h[j + 1] >= hl and h[j + 1] <= hv) then
// liquid/2-phase
rhobar[j] = ((rho[j] + rhol)*(hl - h[j])/2 + AA*log(rhol/rho[j + 1]))/(
h[j + 1] - h[j]);
elseif noEvent(h[j] >= hl and h[j] <= hv and h[j + 1] > hv) then
// 2-phase/vapour
rhobar[j] = (AA*log(rho[j]/rhov) + (rhov + rho[j + 1])*(h[j + 1] - hv)/
2)/(h[j + 1] - h[j]);
elseif noEvent(h[j] < hl and h[j + 1] > hv) then
// liquid/2-phase/vapour
rhobar[j] = ((rho[j] + rhol)*(hl - h[j])/2 + AA*log(rhol/rhov) + (rhov
+ rho[j + 1])*(h[j + 1] - hv)/2)/(h[j + 1] - h[j]);
elseif noEvent(h[j] >= hl and h[j] <= hv and h[j + 1] < hl) then
// 2-phase/liquid
rhobar[j] = (AA*log(rho[j]/rhol) + (rhol + rho[j + 1])*(h[j + 1] - hl)/
2)/(h[j + 1] - h[j]);
elseif noEvent(h[j] > hv and h[j + 1] < hl) then
// vapour/2-phase/liquid
rhobar[j] = ((rho[j] + rhov)*(hv - h[j])/2 + AA*log(rhov/rhol) + (rhol
+ rho[j + 1])*(h[j + 1] - hl)/2)/(h[j + 1] - h[j]);
else
// vapour/2-phase
rhobar[j] = ((rho[j] + rhov)*(hv - h[j])/2 + AA*log(rhov/rho[j + 1]))/(
h[j + 1] - h[j]);
end if;
end for;
// Saturated fluid property calculations
sat = Medium.setSat_p(p);
Ts = sat.Tsat;
rhol = Medium.bubbleDensity(sat);
rhov = Medium.dewDensity(sat);
hl = Medium.bubbleEnthalpy(sat);
hv = Medium.dewEnthalpy(sat);
drldp = Medium.dBubbleDensity_dPressure(sat);
drvdp = Medium.dDewDensity_dPressure(sat);
dhldp = Medium.dBubbleEnthalpy_dPressure(sat);
dhvdp = Medium.dDewEnthalpy_dPressure(sat);
AA = (hv - hl)/(1/rhov - 1/rhol);
AA1 = ((dhvdp - dhldp)*(rhol - rhov)*rhol*rhov - (hv - hl)*(rhov^2*drldp -
rhol^2*drvdp))/(rhol - rhov)^2;
// Fluid property calculations
for j in 1:N loop
fluidState[j] = Medium.setState_ph(p, h[j]);
T[j] = Medium.temperature(fluidState[j]);
rho[j] = Medium.density(fluidState[j]);
u[j] = w/(rho[j]*A);
x[j] = noEvent(if h[j] <= hl then 0 else if h[j] >= hv then 1 else (h[j]
- hl)/(hv - hl));
end for;
// Selection of representative pressure and flow rate variables
if HydraulicCapacitance == HCtypes.Upstream then
p = infl.p;
w = -outfl.m_flow/Nt;
else
p = outfl.p;
w = infl.m_flow/Nt;
end if;
// Boundary conditions
Q_single = wall.Q/Nt;
infl.h_outflow = htilde[1];
outfl.h_outflow = htilde[N - 1];
h[1] = inStream(infl.h_outflow);
h[2:N] = htilde;
connect(wall,heatTransfer.wall);
Q = sum(heatTransfer.wall.Q) "Total heat flow through lateral boundary";
M = sum(rhobar)*A*l "Fluid mass (single tube)";
Tr = noEvent(M/max(infl.m_flow/Nt, Modelica.Constants.eps))
"Residence time";
initial equation
if initOpt == ThermoPower.Choices.Init.Options.noInit then
// do nothing
elseif initOpt == ThermoPower.Choices.Init.Options.steadyState then
der(htilde) = zeros(N - 1);
if (not Medium.singleState) then
der(p) = 0;
end if;
elseif initOpt == ThermoPower.Choices.Init.Options.steadyStateNoP then
der(htilde) = zeros(N - 1);
elseif initOpt == ThermoPower.Choices.Init.Options.steadyStateNoT and not Medium.singleState then
der(p) = 0;
else
assert(false, "Unsupported initialisation option");
end if;
annotation (
Icon(graphics={Text(extent={{-100,-40},{100,-80}}, textString="%name")}),
Documentation(info="
This model describes the flow of water or steam in a rigid tube. The basic modelling assumptions are:
- The fluid state is either one-phase, or a two-phase mixture.
- In case of two-phase flow, the same velocity is assumed for both phases (homogeneous model).
- Uniform velocity is assumed on the cross section, leading to a 1-D distributed parameter model.
- Turbulent friction is always assumed; a small linear term is added to avoid numerical singularities at zero flowrate. The friction effects are not accurately computed in the laminar and transitional flow regimes, which however should not be an issue in most applications using water or steam as a working fluid.
- The model is based on dynamic mass, momentum, and energy balances. The dynamic momentum term can be switched off, to avoid the fast oscillations that can arise from its coupling with the mass balance (sound wave dynamics).
- The longitudinal heat diffusion term is neglected.
- The energy balance equation is written by assuming a uniform pressure distribution; the pressure drop is lumped either at the inlet or at the outlet.
- The fluid flow can exchange thermal power through the lateral surface, which is represented by the wall connector. The actual heat flux must be computed by a connected component (heat transfer computation module).
The mass, momentum, and energy balance equation are discretised with the finite volume method. The state variables are one pressure, one flowrate (optional) and N-1 specific enthalpies.
The turbulent friction factor can be either assumed as a constant, or computed by Colebrook's equation. In the former case, the friction factor can be supplied directly, or given implicitly by a specified operating point. In any case, the multiplicative correction coefficient Kfc can be used to modify the friction coefficient, e.g. to fit experimental data.
A small linear pressure drop is added to avoid numerical singularities at low or zero flowrate. The wnom parameter must be always specified: the additional linear pressure drop is such that it is equal to the turbulent pressure drop when the flowrate is equal to wnf*wnom (the default value is 1% of the nominal flowrate). Increase wnf if numerical instabilities occur in tubes with very low pressure drops.
The model assumes that the mass flow rate is always from the inlet to the outlet. Small reverse flow is allowed (e.g. when closing a valve at the outlet), but the model will not account for it explicitly.
Modelling options
Thermal variables (enthalpy, temperature, density) are computed in N equally spaced nodes, including the inlet (node 1) and the outlet (node N); N must be greater than or equal to 2.
The dynamic momentum term is included or neglected depending on the DynamicMomentum parameter.
The density is computed assuming a linear distribution of the specific
enthalpy between the nodes; this requires the availability of the time derivative of the inlet enthalpy. If this is not available, it is possible to set avoidInletEnthalpyDerivative to true, which will cause the mean density of the first volume to be approximated as its outlet density, thus avoiding the need of the inlet enthalpy derivative.
The following options are available to specify the friction coefficient:
- FFtype = FFtypes.Kfnom: the hydraulic friction coefficient Kf is set directly to Kfnom.
- FFtype = FFtypes.OpPoint: the hydraulic friction coefficient is specified by a nominal operating point (wnom,dpnom, rhonom).
- FFtype = FFtypes.Cfnom: the friction coefficient is computed by giving the (constant) value of the Fanning friction factor Cfnom.
- FFtype = FFtypes.Colebrook: the Fanning friction factor is computed by Colebrook's equation (assuming Re > 2100, e.g. turbulent flow).
- FFtype = FFtypes.NoFriction: no friction is assumed across the pipe.
If HydraulicCapacitance = 2 (default option) then the mass storage term depending on the pressure is lumped at the outlet, while the optional momentum storage term depending on the flowrate is lumped at the inlet. If HydraulicCapacitance = 1 the reverse takes place.
Start values for pressure and flowrate are specified by pstart, wstart. The start values for the node enthalpies are linearly distributed from hstartin at the inlet to hstartout at the outlet.
A bank of Nt identical tubes working in parallel can be modelled by setting Nt > 1. The geometric parameters always refer to a single tube.
This models makes the temperature and external heat flow distributions visible through the wall connector. If other variables (e.g. the heat transfer coefficient) are needed by external components to compute the actual heat flow, the wall connector can be replaced by an extended version of the DHT connector.
", revisions="
"));
end TwoPhaseFlow1DFV;
model VapourLiquidSeparator
"Splits the liquid and vapour streams from a Joule-Thomson valve"
extends LAES.Components.Icons.VapourLiquidSeparator;
replaceable package Medium = NuclearPowerPlant.Media.AirCoolProp constrainedby
Modelica.Media.Interfaces.PartialMedium "Medium model";
Modelica.SIunits.MassFraction x "Vapour quality";
Modelica.SIunits.EnthalpyFlowRate HMixIn "Enthalpy flow rate at inlet";
Modelica.SIunits.EnthalpyFlowRate HVapourOut "Enthalpy flow rate at vapour outlet";
Modelica.SIunits.EnthalpyFlowRate HLiquidOut "Enthalpy flow rate at liquid outlet";
Medium.ThermodynamicState InletState "Thermodynamic state of the fluid at inlet";
Medium.SaturationProperties InletSat "Saturation properties of the fluid at inlet";
Modelica.SIunits.AbsolutePressure p "System pressure";
NuclearPowerPlant.Connectors.TwoPhaseFlangeA MixIn(redeclare package
Medium = Medium) "Mixed stream in" annotation (Placement(
transformation(extent={{-120,0},{-80,40}}), iconTransformation(
extent={{-120,0},{-80,40}})));
NuclearPowerPlant.Connectors.TwoPhaseFlangeB VapourOut(redeclare
package Medium =
Medium) "Vapour stream out"
annotation (Placement(transformation(extent={{80,40},{120,80}})));
NuclearPowerPlant.Connectors.TwoPhaseFlangeB LiquidOut(redeclare
package Medium =
Medium) "Liquid stream out"
annotation (Placement(transformation(extent={{80,-80},{120,-40}})));
equation
assert(MixIn.m_flow >= 0, "Reverse flow not allowed in separator");
//Set fluid thermodynamic state and saturation properties
InletState = Medium.setState_ph(MixIn.p, inStream(MixIn.h_outflow));
x = Medium.vapourQuality(InletState);
InletSat = Medium.setSat_p(p);
//Mass balance
LiquidOut.m_flow = -MixIn.m_flow * (1 - x) "Mass flow rate of liquid out defined by vapour quality";
VapourOut.m_flow = -MixIn.m_flow * x "Mass flow rate of vapour out defined by vapour quality";
//Equal pressure throughout
MixIn.p = p;
LiquidOut.p = p;
//Enthalpy flow rate calculations
HMixIn = inStream(MixIn.h_outflow) * MixIn.m_flow;
HVapourOut = VapourOut.h_outflow * (-VapourOut.m_flow);
HLiquidOut = LiquidOut.h_outflow * (-LiquidOut.m_flow);
//Energy balance from quality calculations
LiquidOut.h_outflow = Medium.bubbleEnthalpy(InletSat);
HMixIn = HVapourOut + HLiquidOut;
//Unused equations to complete the balance
(LiquidOut.m_flow*inStream(LiquidOut.h_outflow)) + (VapourOut.m_flow*inStream(VapourOut.h_outflow)) + (MixIn.m_flow*MixIn.h_outflow) = 0
annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end VapourLiquidSeparator;
model TwoPhaseFlowJoin "Joins two two-phase fluid flows"
extends LAES.Components.Icons.FlowJoin;
replaceable package Medium = NuclearPowerPlant.Media.AirCoolProp constrainedby
Modelica.Media.Interfaces.PartialMedium "Medium model"
annotation(choicesAllMatching = true);
NuclearPowerPlant.Connectors.TwoPhaseFlangeB out(redeclare package
Medium =
Medium) annotation (Placement(transformation(extent={{40,-20},{80,
20}}, rotation=0)));
NuclearPowerPlant.Connectors.TwoPhaseFlangeA in1(redeclare package
Medium =
Medium) annotation (Placement(transformation(extent={{-80,20},{-40,
60}}, rotation=0)));
NuclearPowerPlant.Connectors.TwoPhaseFlangeA in2(redeclare package
Medium =
Medium) annotation (Placement(transformation(extent={{-80,-60},{-40,
-20}}, rotation=0)));
equation
in1.m_flow + in2.m_flow + out.m_flow = 0 "Mass balance";
in1.p = out.p;
in2.p = out.p;
assert(in1.m_flow>=0,"Reverse flow not supported in flow joiner");
assert(in2.m_flow>=0,"Reverse flow not supported in flow joiner");
// Energy balance
out.h_outflow*out.m_flow + inStream(in1.h_outflow)*in1.m_flow + inStream(in2.h_outflow)*in2.m_flow = 0;
//Unused balancing equations
in1.h_outflow = inStream(out.h_outflow);
in2.h_outflow = inStream(out.h_outflow);
annotation (
Documentation(info="
This component allows to join two separate flows into one. The model is based on mass and energy balance equations, without any mass or energy buildup, and without any pressure drop between the inlet and the outlets.
Modelling options
If rev_in1, rev_in2 or rev_out is true, the respective flows reversal is allowed. If at least ona among these parameters is false, it is possible to set checkFlowDirection.
If checkFlowDirection is true, when the flow reversal happen where it is not allowed, the error message is showed.
", revisions="
"), Diagram(graphics));
end TwoPhaseFlowJoin;
model TwoPhaseFlowSplit "Splits a two-phase flow in two"
extends LAES.Components.Icons.FlowSplit;
replaceable package Medium = NuclearPowerPlant.Media.AirCoolProp constrainedby
Modelica.Media.Interfaces.PartialMedium "Medium model"
annotation(choicesAllMatching = true);
parameter Real SplitRatio=0.5 "Proportion of inlet flow sent to outlet 1";
NuclearPowerPlant.Connectors.TwoPhaseFlangeA in1(redeclare package
Medium =
Medium) annotation (Placement(transformation(extent={{-80,-20},{-40,
20}}, rotation=0)));
NuclearPowerPlant.Connectors.TwoPhaseFlangeB out1(redeclare package
Medium = Medium) annotation (Placement(transformation(extent={{40,20},
{80,60}}, rotation=0), iconTransformation(extent={{40,20},{80,
60}})));
NuclearPowerPlant.Connectors.TwoPhaseFlangeB out2(redeclare package
Medium = Medium) annotation (Placement(transformation(extent={{40,-60},
{80,-20}}, rotation=0)));
equation
out2.m_flow = -in1.m_flow * (1-SplitRatio) "Mass balance";
out1.m_flow = -in1.m_flow * SplitRatio "Definition of outlet 1 flow rate";
out1.p = in1.p;
assert(in1.m_flow>=0,"Flow reversal not supported in the flow splitter");
// Energy balance
out1.h_outflow = inStream(in1.h_outflow);
out2.h_outflow = inStream(in1.h_outflow);
//Unused balancing equation
in1.h_outflow = inStream(out1.h_outflow);
annotation (
Documentation(info="
This component allows to split a single flow in two ones. The model is based on mass and energy balance equations, without any mass or energy buildup, and without any pressure drop between the inlet and the outlets.
Modelling options
If rev_in1, rev_out1 or rev_out2 is true, the respective flows reversal is allowed. If at least ona among these parameters is false, it is possible to set checkFlowDirection.
If checkFlowDirection is true, when the flow reversal happen where it is not allowed, the error message is showed.
", revisions="
"));
end TwoPhaseFlowSplit;
model JTValve
"Joule-Thomson valve that provides the temperature drop for an isothermal pressure drop"
extends LAES.Components.Icons.PressDrop;
replaceable package Medium = NuclearPowerPlant.Media.WaterRefProp constrainedby
Modelica.Media.Interfaces.PartialMedium "Medium model"
annotation(choicesAllMatching = true);
parameter Modelica.SIunits.AbsolutePressure dp "Pressure drop";
parameter Boolean allowFlowReversal=system.allowFlowReversal
"= true to allow flow reversal, false restricts to design direction";
outer ThermoPower.System system "System wide properties";
NuclearPowerPlant.Connectors.TwoPhaseFlangeA inlet(redeclare package
Medium = Medium, m_flow(min=if allowFlowReversal then -Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{-120,-20},
{-80,20}}, rotation=0)));
NuclearPowerPlant.Connectors.TwoPhaseFlangeB outlet(redeclare package
Medium = Medium, m_flow(max=if allowFlowReversal then +Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{80,-20},{
120,20}}, rotation=0)));
equation
inlet.m_flow + outlet.m_flow = 0;
inlet.p - outlet.p = dp "pressure drop";
// Energy balance
inlet.h_outflow = inStream(outlet.h_outflow);
inStream(inlet.h_outflow) = outlet.h_outflow;
annotation (
Icon(graphics={Text(extent={{-100,-44},{100,-76}}, textString="%name")}),
Documentation(info="
This very simple model provides a pressure drop which is proportional to the flowrate, without computing any fluid property.
", revisions="
"));
end JTValve;
model StateReader_TwoPhase
"State reader for the visualization of the state in the simulation (two-phase media)"
extends LAES.Components.BaseClasses.BaseReader_twophase;
Modelica.SIunits.Temperature T "Temperature";
Modelica.SIunits.Pressure p "Pressure";
Modelica.SIunits.SpecificEnthalpy h "Specific enthalpy";
Modelica.SIunits.MassFlowRate w "Mass flow rate";
Modelica.SIunits.MassFraction x "Vapour quality";
Modelica.SIunits.Density rho "Density";
Medium.ThermodynamicState fluidState "Thermodynamic state of the fluid";
equation
// Set fluid state
p = inlet.p;
h = homotopy(if not allowFlowReversal then inStream(inlet.h_outflow)
else actualStream(inlet.h_outflow), inStream(inlet.h_outflow));
fluidState = Medium.setState_ph(p, h);
T = Medium.temperature(fluidState);
w = inlet.m_flow;
x = Medium.vapourQuality(fluidState);
rho = Medium.density(fluidState);
end StateReader_TwoPhase;
end TwoPhaseFlows;
package WaterSources "Sinks and sources for water"
end WaterSources;
end Flow;
package Heat_Exchange "Heat exchangers"
package TwoPhaseHX "Heat exchangers for two-phase media"
model ColdStore_conduction
"Gravel bed cold store flow model with proportional pressure drop in fluid flow and longitudinal conduction"
extends LAES.Components.Icons.GravelBed;
replaceable package Medium = NuclearPowerPlant.Media.AirCoolProp constrainedby
Modelica.Media.Interfaces.PartialMedium "Medium model"
annotation(choicesAllMatching = true);
//System parameters
parameter Integer Nodes=101 "Number of nodes for the flows";
constant Real pi=Modelica.Constants.pi;
parameter Boolean SSInit=true "Steady-state initialisation";
//Flow geometry parameters
parameter Modelica.SIunits.Length FlowDiameter "Internal diameter of the packed bed";
parameter Modelica.SIunits.Length FlowLength "Length of the packed bed";
//Packed bed parameters
parameter Modelica.SIunits.Density ParticleDensity "Density of the packed bed material";
parameter Modelica.SIunits.Length ParticleDiameter "Diameter of the particles used in the packed bed";
parameter Modelica.SIunits.SpecificHeatCapacity ParticleSpecificHeatCapacity "Heat capacity of the gravel";
parameter Modelica.SIunits.ThermalConductivity ParticleThermalConductivity "Therml conductivity of the gravel";
parameter Modelica.SIunits.Temperature TVolStart[Nodes-1]={85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344};
//Flow hydraulic and thermal parameters
parameter Modelica.SIunits.MassFlowRate NomMassFlowRate "Nominal mass flow rate of flow";
parameter Modelica.SIunits.AbsolutePressure NomPressure "Nominal pressure of flow";
parameter Real PressureDrop=0.02 "Pressure drop relative to inlet pressure";
//Initialisation parameters
parameter Modelica.SIunits.Temperature TempIn
"Temperature of flow at source"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.Temperature TempOut
"Temperature of flow at sink"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.Temperature Tstart1
"Temperature start value - first volume"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.Temperature TstartN
"Temperature start value - last volume"
annotation (Dialog(tab="Initialisation"));
output Modelica.SIunits.Power HeatStoreRate "Heat storage rate in the gravel bed";
output Modelica.SIunits.Temperature AverageTemperature "Average temperature of the gravel bed";
output Modelica.SIunits.Energy HeatStored "Heat stored in the gravel bed";
//Useful equations
//Cross sectional area of flow = ((pi/4)*(FlowDiameter^2))
//Volume of flow = (((pi/4)*(FlowDiameter^2))*FlowLength)
//Epsilon, void fraction = (0.375 + (0.17*(ParticleDiameter/FlowDiameter)) + (0.39*((ParticleDiameter/FlowDiameter)^2)))
//Surface area per unit volume = ((6 * (1 - (0.375 + (0.17*(ParticleDiameter/FlowDiameter)) + (0.39*((ParticleDiameter/FlowDiameter)^2)))))/ParticleDiameter)
//Convective heat transfer Gamma = (700/(6 * (1 - (0.375 + (0.17*(ParticleDiameter/FlowDiameter)) + (0.39*((ParticleDiameter/FlowDiameter)^2))))))*((NomMassFlowRate/((pi/4)*(FlowDiameter^2)))^0.76)*(ParticleDiameter^0.24)
Flow.TwoPhaseFlows.TwoPhaseFlow1DFV twoPhaseFlow1DFV(
redeclare package Medium = Medium,
N=Nodes,
L=FlowLength,
A=((pi/4)*(FlowDiameter^2)),
omega=((((pi/4)*(FlowDiameter^2))*FlowLength)*((6*(1 - (0.375 + (
0.17*((ParticleDiameter)/FlowDiameter)) + (0.39*(((
ParticleDiameter)/FlowDiameter)^2)))))/ParticleDiameter))/
FlowLength,
wnom=NomMassFlowRate,
pstart=NomPressure,
hstartin=Medium.specificEnthalpy_pT(NomPressure, TempIn),
hstartout=Medium.specificEnthalpy_pT(NomPressure, TempOut),
initOpt=if SSInit then ThermoPower.Choices.Init.Options.steadyState
else ThermoPower.Choices.Init.Options.noInit,
redeclare
ThermoPower.Thermal.HeatTransfer.FlowDependentHeatTransferCoefficient
heatTransfer(
gamma_nom=(700/(6*(1 - (0.375 + (0.17*((ParticleDiameter)/
FlowDiameter)) + (0.39*(((ParticleDiameter)/FlowDiameter)^2))))))
*((NomMassFlowRate/((pi/4)*(FlowDiameter^2)))^0.76)*((
ParticleDiameter)^0.24),
alpha=0.76,
beta=0),
PressureDrop=PressureDrop) annotation (Placement(transformation(
extent={{-20,-20},{20,20}},
rotation=-90,
origin={-40,0})));
BaseClasses.GravelBed_base_conduction
gravelBed_base(
Nw = Nodes - 1,
M = (1-(0.375 + (0.17*((ParticleDiameter)/FlowDiameter)) + (0.39*(((ParticleDiameter)/FlowDiameter)^2))))*(((pi/4)*(FlowDiameter^2))*FlowLength)*ParticleDensity,
cm = ParticleSpecificHeatCapacity,
k=ParticleThermalConductivity,
VolDist=FlowLength/(Nodes-1),
A_eff=((pi/4)*(FlowDiameter^2))*FlowLength*(1-(0.375 + (0.17*(ParticleDiameter/FlowDiameter)) + (0.39*((ParticleDiameter/FlowDiameter)^2)))),
Tvolstart=TVolStart) annotation (Placement(
transformation(
extent={{-20,-20},{20,20}},
rotation=90,
origin={60,0})));
NuclearPowerPlant.Connectors.TwoPhaseFlangeA twoPhaseFlangeA(
redeclare package Medium = Medium)
annotation (Placement(transformation(extent={{-20,80},{20,120}})));
NuclearPowerPlant.Connectors.TwoPhaseFlangeB twoPhaseFlangeB(
redeclare package Medium = Medium) annotation (Placement(
transformation(extent={{-20,-120},{20,-80}})));
equation
connect(twoPhaseFlow1DFV.infl, twoPhaseFlangeA) annotation (Line(points={{-40,
20},{-40,20},{-40,50},{0,50},{0,100}}, color={57,150,0}));
connect(twoPhaseFlow1DFV.outfl, twoPhaseFlangeB) annotation (Line(points={{-40,-20},
{-40,-20},{-40,-60},{0,-60},{0,-100}}, color={57,
150,0}));
connect(twoPhaseFlow1DFV.wall, gravelBed_base.port)
annotation (Line(points={{-30,0},{42,0}}, color={255,127,0}));
HeatStoreRate = twoPhaseFlow1DFV.Q;
der(HeatStored) = HeatStoreRate;
AverageTemperature = sum([gravelBed_base.Tvol]) / (Nodes);
end ColdStore_conduction;
model GravelBed_dpProp_rev
"Gravel bed cold store flow model with pressure drop in fluid flow estimated by Ergun's correlation"
extends LAES.Components.Icons.GravelBed;
replaceable package Medium = NuclearPowerPlant.Media.AirCoolProp constrainedby
Modelica.Media.Interfaces.PartialMedium "Medium model"
annotation(choicesAllMatching = true);
//System parameters
parameter Integer Nodes=101 "Number of nodes for the flows";
constant Real pi=Modelica.Constants.pi;
parameter Boolean SSInit=true "Steady-state initialisation";
parameter Boolean InitTemp = true
"Initialisation option" annotation (Dialog(tab="Initialisation"));
//Flow geometry parameters
parameter Modelica.SIunits.Length FlowDiameter "Internal diameter of the packed bed";
parameter Modelica.SIunits.Length FlowLength "Length of the packed bed";
//Packed bed parameters
parameter Modelica.SIunits.Density ParticleDensity "Density of the packed bed material";
parameter Modelica.SIunits.Length ParticleDiameter "Diameter of the particles used in the packed bed";
parameter Modelica.SIunits.SpecificHeatCapacity ParticleSpecificHeatCapacity "Heat capacity of the gravel";
parameter Modelica.SIunits.Temperature TVolStart[Nodes-1]={85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344,85.540000915527344};
//Flow hydraulic and thermal parameters
parameter Modelica.SIunits.MassFlowRate NomMassFlowRate "Nominal mass flow rate of flow";
parameter Modelica.SIunits.AbsolutePressure NomPressure "Nominal pressure of flow";
parameter Real PressureDrop=0.02 "Pressure drop relative to inlet pressure";
//Initialisation parameters
parameter Modelica.SIunits.Temperature TempIn
"Temperature of flow at source"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.Temperature TempOut
"Temperature of flow at sink"
annotation (Dialog(tab="Initialisation"));
output Modelica.SIunits.Power HeatStoreRate "Heat storage rate in the gravel bed";
output Modelica.SIunits.Temperature AverageTemperature "Average temperature of the gravel bed";
output Modelica.SIunits.Energy HeatStored "Heat stored in the gravel bed";
output Modelica.SIunits.Temperature GBedT[Nodes-1] "Gravel bed temperatures";
//Useful equations
//Cross sectional area of flow = ((pi/4)*(FlowDiameter^2))
//Volume of flow = (((pi/4)*(FlowDiameter^2))*FlowLength)
//Epsilon, void fraction = (0.375 + (0.17*(ParticleDiameter/FlowDiameter)) + (0.39*((ParticleDiameter/FlowDiameter)^2)))
//Surface area per unit volume = ((6 * (1 - (0.375 + (0.17*(ParticleDiameter/FlowDiameter)) + (0.39*((ParticleDiameter/FlowDiameter)^2)))))/ParticleDiameter)
//Convective heat transfer Gamma = (700/(6 * (1 - (0.375 + (0.17*(ParticleDiameter/FlowDiameter)) + (0.39*((ParticleDiameter/FlowDiameter)^2))))))*((NomMassFlowRate/((pi/4)*(FlowDiameter^2)))^0.76)*(ParticleDiameter^0.24)
Flow.TwoPhaseFlows.TwoPhaseFlow1DFV twoPhaseFlow1DFV(
redeclare package Medium = Medium,
N=Nodes,
L=FlowLength,
A=((pi/4)*(FlowDiameter^2)),
omega=((((pi/4)*(FlowDiameter^2))*FlowLength)*((6*(1 - (0.375 + (
0.17*((ParticleDiameter)/FlowDiameter)) + (0.39*(((
ParticleDiameter)/FlowDiameter)^2)))))/ParticleDiameter))/
FlowLength,
wnom=NomMassFlowRate,
pstart=NomPressure,
hstartin=Medium.specificEnthalpy_pT(NomPressure, TempIn),
hstartout=Medium.specificEnthalpy_pT(NomPressure, TempOut),
initOpt=if SSInit then ThermoPower.Choices.Init.Options.steadyState
else ThermoPower.Choices.Init.Options.noInit,
redeclare
ThermoPower.Thermal.HeatTransfer.FlowDependentHeatTransferCoefficient
heatTransfer(gamma_nom=(700/(6*(1 - (0.375 + (0.17*((
ParticleDiameter)/FlowDiameter)) + (0.39*(((ParticleDiameter)
/FlowDiameter)^2))))))*((NomMassFlowRate/((pi/4)*(
FlowDiameter^2)))^0.76)*((ParticleDiameter)^0.24), alpha=0.76),
PressureDrop=PressureDrop) annotation (Placement(transformation(
extent={{-20,-20},{20,20}},
rotation=-90,
origin={-40,0})));
BaseClasses.GravelBed_base_reverse
gravelBed_base(
Nw = Nodes - 1,
M = (1-(0.375 + (0.17*((ParticleDiameter)/FlowDiameter)) + (0.39*(((ParticleDiameter)/FlowDiameter)^2))))*(((pi/4)*(FlowDiameter^2))*FlowLength)*ParticleDensity,
cm = ParticleSpecificHeatCapacity,
Tvolstart=TVolStart)
annotation (Placement(
transformation(
extent={{-20,-20},{20,20}},
rotation=90,
origin={60,0})));
NuclearPowerPlant.Connectors.TwoPhaseFlangeA twoPhaseFlangeA(
redeclare package Medium = Medium)
annotation (Placement(transformation(extent={{-20,80},{20,120}})));
NuclearPowerPlant.Connectors.TwoPhaseFlangeB twoPhaseFlangeB(
redeclare package Medium = Medium) annotation (Placement(
transformation(extent={{-20,-120},{20,-80}})));
equation
connect(twoPhaseFlow1DFV.infl, twoPhaseFlangeA) annotation (Line(points={{-40,
20},{-40,20},{-40,50},{0,50},{0,100}}, color={57,150,0}));
connect(twoPhaseFlow1DFV.outfl, twoPhaseFlangeB) annotation (Line(points={{-40,-20},
{-40,-20},{-40,-60},{0,-60},{0,-100}}, color={57,
150,0}));
connect(twoPhaseFlow1DFV.wall, gravelBed_base.port)
annotation (Line(points={{-30,0},{42,0}}, color={255,127,0}));
HeatStoreRate = twoPhaseFlow1DFV.Q;
der(HeatStored) = HeatStoreRate;
AverageTemperature = sum([gravelBed_base.Tvol]) / (Nodes - 1);
for j in 1:1:Nodes-1 loop
GBedT[j]=gravelBed_base.Tvol[(Nodes-1)-(j-1)];
end for;
end GravelBed_dpProp_rev;
model TwoPhaseSteamAirHX_rev
"Water/steam-air heat exchanger for heat exchange between steam and multi-phase air cycles"
replaceable package WaterMedium =
NuclearPowerPlant.Media.WaterRefProp
constrainedby Modelica.Media.Interfaces.PartialMedium
"Water medium";
replaceable package AirMedium = NuclearPowerPlant.Media.AirCoolProp
constrainedby Modelica.Media.Interfaces.PartialMedium
"Air medium";
parameter Integer Nodes=6 "Number of nodes flows";
//Flow geometry parameters
parameter Modelica.SIunits.Area WaterExchSurf
"Exchange surface between the water flow and the metal tube";
parameter Modelica.SIunits.Volume WaterVol "Water flow volume";
parameter Boolean RoundAirFlow=true
"True for circular cross section - false for rectangular";
parameter Modelica.SIunits.Length AirSectionLength
"Cross-sectional length of air flow for rectangular flow - diameter of circular flow";
parameter Modelica.SIunits.Length AirSectionWidth = 0
"Cross-sectional width of air flow (rectangular flow only)";
parameter Modelica.SIunits.Length TubeThickness
"Thickness of metal tube";
//Flow hydraulic and thermal parameters
parameter Modelica.SIunits.MassFlowRate WaterNomFlowRate
"Nominal flow rate of water";
parameter ThermoPower.Choices.FluidPhase.FluidPhases WaterPhaseStart=ThermoPower.Choices.FluidPhase.FluidPhases.Steam
"Starting phase of primary loop fluid";
parameter Modelica.SIunits.AbsolutePressure WaterNomPressure
"Nominal pressure of water";
parameter Modelica.SIunits.Temperature WaterTIn
"Average water starting temperature";
parameter Modelica.SIunits.Temperature WaterTOut
"Average water starting temperature";
parameter Modelica.SIunits.MassFlowRate AirNomFlowRate
"Nominal flow rate of air";
parameter Modelica.SIunits.AbsolutePressure AirNomPressure
"Nominal pressure of air";
parameter Modelica.SIunits.Temperature AirTIn
"Average air starting temperature";
parameter Modelica.SIunits.Temperature AirTOut
"Average air starting temperature";
parameter Boolean SSInit=false "Steady-state initialisation";
parameter Modelica.SIunits.CoefficientOfHeatTransfer Gamma
"Constant heat transfer coefficient, maximum";
//Metal tube thermal parameters
parameter Real TubeHeatCap "Volumetric heat capacity in the metal [J/m^3.K]";
parameter Modelica.SIunits.ThermalConductivity TubeThermConductivity
"Thermal conductivity of the metal";
//Flow characteristics
parameter ThermoPower.Choices.Flow1D.FFtypes WaterFFType=ThermoPower.Choices.Flow1D.FFtypes.NoFriction
"Friction factor type, water flow";
parameter Modelica.SIunits.AbsolutePressure WaterDeltaPNom=0
"Nominal pressure drop, water flow";
parameter Real WaterKfnom=0
"Nominal hydraulic resistance coefficient, water flow";
parameter Modelica.SIunits.Density WaterRhoNom=0
"Nominal inlet density, water flow";
parameter Real WaterCfnom=0 "Fanning friction factor, water flow";
parameter ThermoPower.Choices.Flow1D.HCtypes WaterHCtype=ThermoPower.Choices.Flow1D.HCtypes.Downstream
"Location of hydraulic capacitance, water flow";
parameter ThermoPower.Choices.Flow1D.FFtypes AirFFType=ThermoPower.Choices.Flow1D.FFtypes.NoFriction
"Friction factor type, air flow";
parameter Modelica.SIunits.AbsolutePressure AirDeltaPNom=0
"Nominal pressure drop, air flow";
parameter Real AirKfnom=0
"Nominal hydraulic resistance coefficient, air flow";
parameter Modelica.SIunits.Density AirRhoNom=0
"Nominal inlet density, air flow";
parameter Real AirCfnom=0 "Fanning friction factor, air flow";
parameter ThermoPower.Choices.Flow1D.HCtypes AirHCtype=ThermoPower.Choices.Flow1D.HCtypes.Downstream
"Location of hydraulic capacitance, air flow";
parameter Boolean counterCurrent=true "Counter-current flow";
constant Real pi=Modelica.Constants.pi;
ThermoPower.Water.FlangeA WaterIn(redeclare package Medium =
WaterMedium)
annotation (Placement(transformation(extent={{-20,80},{20,120}})));
NuclearPowerPlant.Connectors.TwoPhaseFlangeA AirIn(redeclare package
Medium = AirMedium)
annotation (Placement(transformation(extent={{-120,-20},{-80,20}})));
ThermoPower.Water.FlangeB WaterOut(redeclare package Medium =
WaterMedium)
annotation (Placement(transformation(extent={{-20,-120},{20,-80}})));
NuclearPowerPlant.Connectors.TwoPhaseFlangeB AirOut(redeclare package
Medium = AirMedium)
annotation (Placement(transformation(extent={{80,-20},{120,20}})));
ThermoPower.Water.Flow1DFV WaterFlow(
redeclare package Medium = WaterMedium,
N=Nodes,
L=WaterExchSurf^2/(WaterVol*pi*4),
A=(((WaterVol*4/WaterExchSurf)^2)/4)*pi,
omega=(WaterVol*4/WaterExchSurf)*pi,
Dhyd=(WaterVol*4/WaterExchSurf),
wnom=WaterNomFlowRate,
FFtype=WaterFFType,
dpnom=WaterDeltaPNom,
Kfnom=WaterKfnom,
rhonom=WaterRhoNom,
Cfnom=WaterCfnom,
HydraulicCapacitance=WaterHCtype,
FluidPhaseStart=WaterPhaseStart,
pstart=WaterNomPressure,
hstartin=WaterMedium.specificEnthalpy_pT(WaterNomPressure,WaterTIn),
hstartout=WaterMedium.specificEnthalpy_pT(WaterNomPressure,WaterTOut),
initOpt=if SSInit then ThermoPower.Choices.Init.Options.steadyState else
ThermoPower.Choices.Init.Options.noInit,
redeclare ThermoPower.Thermal.HeatTransfer.ConstantHeatTransferCoefficient
heatTransfer(gamma=Gamma)) "Primary loop single-phase fluid flow"
annotation (Placement(transformation(extent={{-20,-72},{20,-32}})));
ThermoPower.Thermal.MetalTubeFV metalTube(
Nw=Nodes-1,
L=WaterExchSurf^2/(WaterVol*pi*4),
rint=(WaterVol*2)/WaterExchSurf,
rext=((WaterVol*2)/WaterExchSurf)+TubeThickness,
rhomcm=TubeHeatCap,
lambda=TubeThermConductivity,
WallRes=false,
Tstartbar=(WaterTIn+WaterTOut)/2,
Tstart1=WaterTIn,
TstartN=WaterTOut,
initOpt=if SSInit then ThermoPower.Choices.Init.Options.steadyState
else ThermoPower.Choices.Init.Options.noInit)
"Metal tube of steam generator"
annotation (Placement(transformation(extent={{-20,0},{20,-40}})));
ThermoPower.Thermal.CounterCurrentFV
counterCurrentFV(Nw=Nodes-1)
annotation (Placement(transformation(extent={{-20,0},{20,40}})));
Flow.TwoPhaseFlows.TwoPhaseFlow1DFV AirFlow(
redeclare package Medium = AirMedium,
N=Nodes,
L=WaterExchSurf^2/(WaterVol*pi*4),
A=if RoundAirFlow then (pi*(AirSectionLength^2)/4) - ((((WaterVol*4
/WaterExchSurf)^2)/4)*pi) else (AirSectionLength*
AirSectionWidth) - ((((WaterVol*4/WaterExchSurf)^2)/4)*pi),
omega=WaterVol*4/WaterExchSurf*pi,
Dhyd=if RoundAirFlow then (AirSectionLength - (WaterVol*4/
WaterExchSurf)) else ((4*AirSectionLength*AirSectionWidth) - (
pi*(((WaterVol*4/WaterExchSurf) + (2*TubeThickness))^2)))/((2*(
AirSectionLength + AirSectionWidth)) - (pi*((WaterVol*4/
WaterExchSurf) + (2*TubeThickness)))),
wnom=AirNomFlowRate,
FFtype=AirFFType,
dpnom=AirDeltaPNom,
Kfnom=AirKfnom,
Cfnom=AirCfnom,
pstart=AirNomPressure,
hstartin=AirMedium.specificEnthalpy_pT(AirNomPressure, AirTIn),
hstartout=AirMedium.specificEnthalpy_pT(AirNomPressure, AirTOut),
initOpt=if SSInit then ThermoPower.Choices.Init.Options.steadyState
else ThermoPower.Choices.Init.Options.noInit,
redeclare
ThermoPower.Thermal.HeatTransfer.ConstantHeatTransferCoefficient
heatTransfer(gamma=Gamma)) annotation (Placement(transformation(
extent={{-20,-20},{20,20}},
rotation=180,
origin={0,60})));
equation
connect(counterCurrentFV.side2, metalTube.ext) annotation (Line(points={{0,13.8},
{0,-13.8},{0,-13.8}}, color={255,127,0}));
connect(metalTube.int, WaterFlow.wall)
annotation (Line(points={{0,-26},{0,-34},{0,-42}}, color={255,127,0}));
connect(WaterIn, WaterFlow.infl) annotation (Line(points={{0,100},{-30,100},{-60,
100},{-60,-52},{-20,-52}}, color={0,0,255}));
connect(WaterFlow.outfl, WaterOut) annotation (Line(points={{20,-52},{30,-52},
{40,-52},{40,-100},{0,-100}}, color={0,0,255}));
connect(AirFlow.wall, counterCurrentFV.side1) annotation (Line(points={{-1.33227e-015,
50},{0,50},{0,26}}, color={255,127,0}));
connect(AirIn, AirFlow.outfl) annotation (Line(points={{-100,0},{-100,0},{
-100,60},{-20,60},{-20,60}}, color={57,150,0}));
connect(AirFlow.infl, AirOut) annotation (Line(points={{20,60},{60,60},{100,
60},{100,0}}, color={57,150,0}));
annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
Rectangle(
extent={{-100,100},{100,-100}},
lineColor={0,0,255},
fillColor={230,230,230},
fillPattern=FillPattern.Solid),
Line(
points={{0,-80},{0,-40},{40,-20},{-40,20},{0,40},{0,80}},
color={0,0,255},
thickness=0.5),
Text(
extent={{-102,46},{-78,16}},
lineColor={28,108,200},
textString="A"),
Text(
extent={{78,46},{102,16}},
lineColor={28,108,200},
textString="A"),
Text(
extent={{-40,100},{-16,70}},
lineColor={28,108,200},
textString="S"),
Text(
extent={{-40,-74},{-16,-104}},
lineColor={28,108,200},
textString="S")}), Diagram(
coordinateSystem(preserveAspectRatio=false)),
Documentation(info="
This is a heat exchanger designed for primary (reactor coolant) to secondary (steam power cycle) loop heat exchange in a nuclear reactor - essentially a steam generator. This is largely based on Thermopower's gas-liquid heat exchanger ThermoPower.Examples.RankineCycle.HE modified to allow heat exchange between two water flows. Only pressurised water reactors have this form of heat exchanger and the flow on the water flow is single phase to reflect this. The flow on the air flow is two phase to allow steam generation. P and S at icon layer denote primary and secondary for ease of connection.
"));
end TwoPhaseSteamAirHX_rev;
model TwoPhaseAirAirHX_NA
"Air-air heat exchanger for air power cycle using two phase flows without accumulation in the flow"
replaceable package AirFlow1Medium =
NuclearPowerPlant.Media.AirRefProp
constrainedby Modelica.Media.Interfaces.PartialPureSubstance
"Fluid model";
replaceable package AirFlow2Medium =
NuclearPowerPlant.Media.AirRefProp
constrainedby Modelica.Media.Interfaces.PartialPureSubstance
"Fluid model";
parameter Integer Nodes=6 "Number of nodes for the flows";
parameter Boolean counterCurrent=true "Counter-current flow";
constant Real pi=Modelica.Constants.pi;
//Flow parameters
parameter Modelica.SIunits.Area AirFlow1ExchSurf
"Exchange surface area of the air flow 1";
parameter Modelica.SIunits.Volume AirFlow1Vol
"Volume of the air flow 1";
parameter Boolean RoundAirFlow2=true
"True for circular air flow 2; false for rectangular";
parameter Modelica.SIunits.Length AirFlow2SectionLength
"Cross-sectional length or diameter of air flow 2";
parameter Modelica.SIunits.Length AirFlow2SectionWidth=0
"Cross-sectional width of air flow 2";
parameter Modelica.SIunits.Length TubeThickness
"Thickness of metal tube";
//Flow hydraulic and thermal parameters
parameter Modelica.SIunits.MassFlowRate AirFlow1NomFlowRate
"Nominal flow rate through the air flow 1 side";
parameter ThermoPower.Choices.FluidPhase.FluidPhases AirFlow1FluidPhaseStart=
ThermoPower.Choices.FluidPhase.FluidPhases.Liquid
"Initialization phase of air flow 1" annotation (Dialog(tab="Initialization"));
parameter Modelica.SIunits.AbsolutePressure AirFlow1NomPressure
"Nominal pressure in the air flow 1";
parameter Modelica.SIunits.Temperature AirFlow1TIn
"Start inlet temperature of the air flow 1";
parameter Modelica.SIunits.Temperature AirFlow1TOut
"Start outlet temperature of the air flow 1";
parameter Modelica.SIunits.MassFlowRate AirFlow2NomFlowRate
"Nominal flow rate through the air flow 2 side";
parameter ThermoPower.Choices.FluidPhase.FluidPhases AirFlow2FluidPhaseStart=
ThermoPower.Choices.FluidPhase.FluidPhases.Steam
"Initialization phase of air flow 2" annotation (Dialog(tab="Initialization"));
parameter Modelica.SIunits.AbsolutePressure AirFlow2NomPressure
"Nominal pressure in the air flow 2";
parameter Modelica.SIunits.Temperature AirFlow2TIn
"Start inlet temperature of the air flow 2";
parameter Modelica.SIunits.Temperature AirFlow2TOut
"Start outlet temperature of the air flow 2";
parameter Boolean SSInit=true "Steady-state initialisation";
parameter Modelica.SIunits.CoefficientOfHeatTransfer Gamma
"Constant heat transfer coefficient, maximum";
//Metal tube thermal parameters
parameter Real TubeHeatCap "Metal tube heat capacity per unit volume [J/m^3.K]";
parameter Modelica.SIunits.ThermalConductivity TubeThermConductivity
"Thermal conductivity of the metal tube (density by specific heat capacity)";
//Flow characteristics
parameter ThermoPower.Choices.Flow1D.FFtypes AirFlow1FFtype=ThermoPower.Choices.Flow1D.FFtypes.NoFriction
"Friction factor type, air flow 1";
parameter Modelica.SIunits.AbsolutePressure AirFlow1dpnom=0
"Nominal pressure drop, air flow 1";
parameter Real AirFlow1Kfnom=0
"Nominal hydraulic resistance coefficient, air flow 1";
parameter Modelica.SIunits.Density AirFlow1rhonom=0
"Nominal inlet density, air flow 1";
parameter Real AirFlow1Cfnom=0 "Fanning friction factor, air flow 1";
parameter ThermoPower.Choices.Flow1D.FFtypes AirFlow2FFtype=ThermoPower.Choices.Flow1D.FFtypes.NoFriction
"Friction factor type, air flow 2";
parameter Modelica.SIunits.AbsolutePressure AirFlow2dpnom=0
"Nominal pressure drop, air flow 2";
parameter Real AirFlow2Kfnom=0
"Nominal hydraulic resistance coefficient, air flow 2";
parameter Modelica.SIunits.Density AirFlow2rhonom=0
"Nominal inlet density, air flow 2";
parameter Real AirFlow2Cfnom=0 "Fanning friction factor, air flow 2";
NuclearPowerPlant.Connectors.TwoPhaseFlangeA AirFlow1In(redeclare
package Medium =
AirFlow1Medium) annotation (Placement(transformation(extent=
{{-120,-20},{-80,20}}, rotation=0)));
NuclearPowerPlant.Connectors.TwoPhaseFlangeB AirFlow1Out(redeclare
package Medium = AirFlow1Medium) annotation (Placement(transformation(
extent={{80,-20},{120,20}}, rotation=0)));
NuclearPowerPlant.Connectors.TwoPhaseFlangeA AirFlow2In(redeclare
package Medium =
AirFlow2Medium) annotation (Placement(transformation(extent=
{{-20,80},{20,120}}, rotation=0)));
NuclearPowerPlant.Connectors.TwoPhaseFlangeB AirFlow2Out(redeclare
package Medium = AirFlow2Medium) annotation (Placement(transformation(
extent={{-20,-120},{20,-80}}, rotation=0)));
Flow.TwoPhaseFlows.TwoPhaseFlow1DFV AirFlow2(
redeclare package Medium = AirFlow2Medium,
N=Nodes,
L=AirFlow1ExchSurf^2/(AirFlow1Vol*pi*4),
A=if RoundAirFlow2 then (pi*(AirFlow2SectionLength^2)/4) - ((((
AirFlow1Vol*4/AirFlow1ExchSurf)^2)/4)*pi) else (
AirFlow2SectionLength*AirFlow2SectionWidth) - ((((AirFlow1Vol*4
/AirFlow1ExchSurf)^2)/4)*pi),
omega=AirFlow1Vol*4/AirFlow1ExchSurf*pi,
Dhyd=if RoundAirFlow2 then (AirFlow2SectionLength - (AirFlow1Vol*4/
AirFlow1ExchSurf)) else ((4*AirFlow2SectionLength*
AirFlow2SectionWidth) - (pi*(((AirFlow1Vol*4/AirFlow1ExchSurf)
+ (2*TubeThickness))^2)))/((2*(AirFlow2SectionLength +
AirFlow2SectionWidth)) - (pi*((AirFlow1Vol*4/AirFlow1ExchSurf)
+ (2*TubeThickness)))),
wnom=AirFlow2NomFlowRate,
FFtype=AirFlow2FFtype,
dpnom=AirFlow2dpnom,
Kfnom=AirFlow2Kfnom,
rhonom=AirFlow2rhonom,
Cfnom=AirFlow2Cfnom,
FluidPhaseStart=AirFlow2FluidPhaseStart,
pstart=AirFlow2NomPressure,
hstartin=AirFlow2Medium.specificEnthalpy_pT(AirFlow2NomPressure,
AirFlow2TIn),
hstartout=AirFlow2Medium.specificEnthalpy_pT(AirFlow2NomPressure,
AirFlow2TOut),
initOpt=if SSInit then ThermoPower.Choices.Init.Options.steadyState
else ThermoPower.Choices.Init.Options.noInit,
redeclare
ThermoPower.Thermal.HeatTransfer.ConstantHeatTransferCoefficient
heatTransfer(gamma=Gamma)) "Flow model for the air flow 2 loop"
annotation (Placement(transformation(extent={{-20,-76},{20,-36}},
rotation=0)));
ThermoPower.Thermal.MetalTubeFV metalTube(
Nw=Nodes-1,
L=AirFlow1ExchSurf^2/(AirFlow1Vol*pi*4),
rint=(AirFlow1Vol*2)/AirFlow1ExchSurf,
rext=((AirFlow1Vol*2)/AirFlow1ExchSurf)+TubeThickness,
rhomcm=TubeHeatCap,
lambda=TubeThermConductivity,
WallRes=false,
Tstartbar=(AirFlow1TIn+AirFlow1TOut)/2,
Tstart1=AirFlow1TIn,
TstartN=AirFlow1TOut,
initOpt=if SSInit then ThermoPower.Choices.Init.Options.steadyState
else ThermoPower.Choices.Init.Options.noInit)
annotation (Placement(transformation(extent={{-20,-40},{20,0}},
rotation=0)));
Flow.TwoPhaseFlows.TwoPhaseFlow1DFV AirFlow1(
redeclare package Medium = AirFlow1Medium,
N=Nodes,
L=AirFlow1ExchSurf^2/(AirFlow1Vol*pi*4),
A=(((AirFlow1Vol*4/AirFlow1ExchSurf)^2)/4)*pi,
omega=(AirFlow1Vol*4/AirFlow1ExchSurf)*pi,
Dhyd=(AirFlow1Vol*4/AirFlow1ExchSurf),
wnom=AirFlow1NomFlowRate,
FFtype=AirFlow1FFtype,
dpnom=AirFlow1dpnom,
Kfnom=AirFlow1Kfnom,
rhonom=AirFlow1rhonom,
Cfnom=AirFlow1Cfnom,
FluidPhaseStart=AirFlow1FluidPhaseStart,
pstart=AirFlow1NomPressure,
hstartin=AirFlow1Medium.specificEnthalpy_pT(AirFlow1NomPressure,
AirFlow1TIn),
hstartout=AirFlow1Medium.specificEnthalpy_pT(AirFlow1NomPressure,
AirFlow1TOut),
initOpt=if SSInit then ThermoPower.Choices.Init.Options.steadyState
else ThermoPower.Choices.Init.Options.noInit,
redeclare
ThermoPower.Thermal.HeatTransfer.ConstantHeatTransferCoefficient
heatTransfer(gamma=Gamma)) "Flow model for the air flow 1 loop"
annotation (Placement(transformation(extent={{-20,60},{20,20}},
rotation=0)));
ThermoPower.Thermal.CounterCurrentFV cC(Nw=Nodes-1) annotation (Placement(
transformation(extent={{-20,-8},{20,32}}, rotation=0)));
equation
connect(AirFlow1.wall, cC.side1) annotation (Line(
points={{0,30},{0,18}},
color={255,127,0},
smooth=Smooth.None));
connect(cC.side2, metalTube.int)
annotation (Line(points={{0,5.8},{0,-4.1},{0,-14}}, color={255,127,0}));
connect(metalTube.ext, AirFlow2.wall)
annotation (Line(points={{0,-26.2},{0,-46}}, color={255,127,0}));
connect(AirFlow1In, AirFlow1.infl)
annotation (Line(points={{-100,0},{-100,40},{-20,40}}, color={57,150,0}));
connect(AirFlow1.outfl, AirFlow1Out) annotation (Line(points={{20,40},{60,40},{
100,40},{100,0}}, color={57,150,0}));
connect(AirFlow2In, AirFlow2.infl) annotation (Line(points={{0,100},{-20,100},
{-40,100},{-40,-56},{-20,-56}}, color={57,150,0}));
connect(AirFlow2.outfl, AirFlow2Out) annotation (Line(points={{20,-56},{32,-56},
{40,-56},{40,-100},{0,-100}}, color={57,150,0}));
annotation (
Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,
-100},{100,100}})),
Icon(graphics={
Rectangle(
extent={{-100,100},{100,-100}},
lineColor={0,0,255},
fillColor={230,230,230},
fillPattern=FillPattern.Solid),
Line(
points={{0,-80},{0,-40},{40,-20},{-40,20},{0,40},{0,80}},
color={57,150,0},
thickness=0.5,
origin={0,0},
rotation=-90),
Text(
extent={{-100,-115},{100,-145}},
lineColor={85,170,255},
textString="%name"),
Text(
extent={{-40,92},{-16,62}},
lineColor={57,150,0},
textString="A2"),
Text(
extent={{-42,-64},{-18,-94}},
lineColor={57,150,0},
textString="A2"),
Text(
extent={{-92,-20},{-68,-50}},
lineColor={57,150,0},
textString="A1"),
Text(
extent={{70,-20},{94,-50}},
lineColor={57,150,0},
textString="A1")}),
Documentation(revisions="
- 10 Dec 2008 by Luca Savoldelli:
First release.
- 17 October by Andy Wilson: Amended for suitability for fluid-fluid HX in a nuclear power plant - still requires additional amendments for 2-phase on fluid side
", info="
"));
end TwoPhaseAirAirHX_NA;
end TwoPhaseHX;
end Heat_Exchange;
package Machinery "Pumps and turbines"
package Water "Pumps and turbines for water"
model PumpControl "Centrifugal pump deigned for flow control"
extends LAES.Components.Icons.Pump;
replaceable package Medium = NuclearPowerPlant.Media.WaterRefProp constrainedby
Modelica.Media.Interfaces.PartialMedium "Medium model"
annotation(choicesAllMatching = true);
Medium.ThermodynamicState inletFluidState
"Thermodynamic state of the fluid at the inlet";
parameter Real eta "Pump efficiency";
parameter ThermoPower.Density rho0=1000 "Nominal Liquid Density"
annotation (Dialog(group="Characteristics"));
parameter Modelica.SIunits.MassFlowRate wstart "Starting mass flow rate";
parameter Modelica.SIunits.AbsolutePressure poutlet "Pressure at outlet";
parameter Modelica.SIunits.Temperature Tstart "Starting temperature at outlet";
outer ThermoPower.System system "System wide properties";
Modelica.SIunits.MassFlowRate w(start=wstart,fixed=true) "Mass flow rate";
Modelica.SIunits.VolumeFlowRate q "Volume flow rate";
Modelica.SIunits.Pressure dp "Outlet pressure minus inlet pressure";
Medium.SpecificEnthalpy hin "Enthalpy of entering fluid";
Medium.SpecificEnthalpy hout(start = Medium.specificEnthalpy_pT(poutlet,Tstart)) "Enthalpy of outgoing fluid";
ThermoPower.LiquidDensity rho "Liquid density";
Modelica.SIunits.Power Power "Power Consumption (total)";
ThermoPower.Water.FlangeA infl(redeclare package Medium = Medium, m_flow(min=0))
annotation (Placement(transformation(extent={{-100,0},{-60,40}}, rotation=0)));
ThermoPower.Water.FlangeB outfl(redeclare package Medium = Medium, m_flow(max=0),
p(start = poutlet)) annotation (
Placement(transformation(extent={{40,40},{80,80}}, rotation=0)));
equation
assert(infl.m_flow>=0,"Reverse flow not allowed in pump");
assert(infl.m_flow+outfl.m_flow>=0,"Fluid lost in loop",level=AssertionLevel.warning);
assert(infl.m_flow+outfl.m_flow<=0,"Fluid gained in loop",level=AssertionLevel.warning);
// Flow equations
q = w/homotopy(rho, rho0);
// Power consumption
Power = dp*q/eta;
// Fluid properties
inletFluidState = Medium.setState_ph(infl.p, hin);
rho = Medium.density(inletFluidState);
// Boundary conditions
dp = outfl.p - infl.p;
outfl.p = poutlet;
w = -outfl.m_flow "Pump total flow rate";
hin = inStream(infl.h_outflow);
outfl.h_outflow = hout;
infl.h_outflow = hout "Unused balancing equation for reverse flow";
// Mass and energy balances
outfl.m_flow+infl.m_flow=0;
0 = (outfl.m_flow)*hout + (infl.m_flow)*hin + Power
"Energy balance";
initial equation
der(rho)=0;
annotation (
Documentation(info="
This is the base model for the Pump and
PumpMech pump models.
The model describes a centrifugal pump, or a group of Np identical pumps in parallel. The pump model is based on the theory of kinematic similarity: the pump characteristics are given for nominal operating conditions (rotational speed and fluid density), and then adapted to actual operating condition, according to the similarity equations.
In order to avoid singularities in the computation of the outlet enthalpy at zero flowrate, the thermal capacity of the fluid inside the pump body can be taken into account.
The model can either support reverse flow conditions or include a built-in check valve to avoid flow reversal.
Modelling options
The nominal hydraulic characteristic (head vs. volume flow rate) is given by the the replaceable function flowCharacteristic.
The pump energy balance can be specified in two alternative ways:
- usePowerCharacteristic = false (default option): the replaceable function efficiencyCharacteristic (efficiency vs. volume flow rate in nominal conditions) is used to determine the efficiency, and then the power consumption. The default is a constant efficiency of 0.8.
- usePowerCharacteristic = true: the replaceable function powerCharacteristic (power consumption vs. volume flow rate in nominal conditions) is used to determine the power consumption, and then the efficiency.
Several functions are provided in the package Functions.PumpCharacteristics to specify the characteristics as a function of some operating points at nominal conditions.
Depending on the value of the checkValve parameter, the model either supports reverse flow conditions, or includes a built-in check valve to avoid flow reversal.
If the in_Np input connector is wired, it provides the number of pumps in parallel; otherwise, Np0 parallel pumps are assumed.
It is possible to take into account the heat capacity of the fluid inside the pump by specifying its volume V at nominal conditions; this is necessary to avoid singularities in the computation of the outlet enthalpy in case of zero flow rate. If zero flow rate conditions are always avoided, this dynamic effect can be neglected by leaving the default value V = 0, thus avoiding a fast state variable in the model.
The CheckValve parameter determines whether the pump has a built-in check valve or not.
If computeNPSHa = true, the available net positive suction head is also computed; this requires a two-phase medium model to provide the fluid saturation pressure.
", revisions="
"), Icon(graphics={Polygon(
points={{-30,52},{48,20},{-30,-8},{-30,52}},
lineColor={0,0,255},
fillColor={0,0,255},
fillPattern=FillPattern.Solid)}));
end PumpControl;
end Water;
package TwoPhase "Pumps and turbines for two phase media"
model TurbineSimpleTwoPhase
"Simple turbine model with lookup table for isentropic efficiency based on flow rate - capable of handling 2-phase flows"
extends LAES.Components.Icons.TurbineTwoPhase;
replaceable package Medium = NuclearPowerPlant.Media.AirCoolProp
annotation(choicesAllMatching = true);
parameter Boolean explicitIsentropicEnthalpy=true
"isentropicEnthalpy function used";
parameter Real eta_mech=0.98 "mechanical efficiency";
parameter Modelica.SIunits.MassFlowRate m_flow_des "design mass flow rate";
parameter Boolean allowFlowReversal=system.allowFlowReversal
"= true to allow flow reversal, false restricts to design direction";
outer ThermoPower.System system "System wide properties";
parameter Modelica.SIunits.Pressure pstart_in "inlet start pressure"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.Pressure pstart_out "outlet start pressure"
annotation (Dialog(tab="Initialisation"));
parameter ThermoPower.AbsoluteTemperature Tstart_in
"inlet start temperature" annotation (Dialog(tab="Initialisation"));
parameter ThermoPower.AbsoluteTemperature Tstart_out
"outlet start temperature" annotation (Dialog(tab="Initialisation"));
parameter Real PR "pressure ratio";
parameter Real tableEta[5, 2]=[0.5, 0.6; 0.70, 0.7; 0.80, 0.75; 0.90, 0.77; 1.0, 0.79] "Table for eta(m_flow_factor)";
Medium.BaseProperties gas_in(
p(start=pstart_in),
T(start=Tstart_in));
Medium.BaseProperties gas_iso(
p(start=pstart_out),
T(start=Tstart_out));
Modelica.SIunits.MassFlowRate w "Gas flow rate";
Medium.SpecificEntropy s_in "Inlet specific entropy";
Medium.SpecificEnthalpy hout_iso "Outlet isentropic enthalpy";
Medium.SpecificEnthalpy hout "Outlet enthalpy";
Medium.AbsolutePressure pout(start=pstart_out) "Outlet pressure";
Modelica.SIunits.Power Power "Compressor power input";
Real eta "isoentropic efficiency";
Real m_flow_factor "fraction of design mass flow rate";
NuclearPowerPlant.Connectors.TwoPhaseFlangeA inlet(redeclare package
Medium = Medium, m_flow(min=if allowFlowReversal then -Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{-100,
60},{-60,100}}, rotation=0)));
NuclearPowerPlant.Connectors.TwoPhaseFlangeB outlet(redeclare package
Medium = Medium, m_flow(max=if allowFlowReversal then +Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{60,60},
{100,100}}, rotation=0)));
Modelica.Blocks.Tables.CombiTable1Ds Eta(
tableOnFile=false,
table=tableEta)
annotation (Placement(transformation(extent={{-10,-10},{10,10}},
rotation=0)));
equation
w = inlet.m_flow;
assert(w >= 0, "The turbine model does not support flow reversal");
inlet.m_flow + outlet.m_flow = 0 "Mass balance";
m_flow_factor=w/m_flow_des "calculation of fraction of design mass flow rate";
// Set inlet gas properties
gas_in.p = inlet.p;
gas_in.h = inStream(inlet.h_outflow);
// Set outlet gas properties
outlet.p = pout;
outlet.h_outflow = hout;
// Equations for reverse flow (not used)
inlet.h_outflow = inStream(outlet.h_outflow);
if explicitIsentropicEnthalpy then
hout_iso = Medium.isentropicEnthalpy(outlet.p, gas_in.state)
"Approximated isentropic enthalpy";
hout - gas_in.h = eta*(hout_iso - gas_in.h) "Enthalpy change";
//dummy assignments
s_in = 0;
gas_iso.p = 1e5;
gas_iso.T = 300;
else
// Properties of the gas after isentropic transformation
gas_iso.p = pout;
s_in = Medium.specificEntropy(gas_in.state);
s_in = Medium.specificEntropy(gas_iso.state);
hout - gas_in.h = eta*(gas_iso.h - gas_in.h) "Enthalpy change";
//dummy assignment
hout_iso = 0;
end if;
w*(gas_in.h - hout)*eta_mech = Power "Energy balance";
PR = gas_in.p/pout "Pressure ratio";
// eta = Eta(m_flow_factor)
Eta.u = m_flow_factor;
eta = Eta.y[1];
annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end TurbineSimpleTwoPhase;
model TwoPhasePumpControl "Centrifugal pump deigned for flow control of two phase flows"
extends LAES.Components.Icons.Pump;
replaceable package Medium = NuclearPowerPlant.Media.AirCoolProp constrainedby
Modelica.Media.Interfaces.PartialMedium "Medium model"
annotation(choicesAllMatching = true);
Medium.ThermodynamicState inletFluidState
"Thermodynamic state of the fluid at the inlet";
parameter Real eta "Pump efficiency";
parameter ThermoPower.Density rho0=1000 "Nominal Liquid Density"
annotation (Dialog(group="Characteristics"));
parameter Modelica.SIunits.MassFlowRate wstart "Starting mass flow rate";
parameter Modelica.SIunits.AbsolutePressure poutlet "Pressure at outlet";
parameter Modelica.SIunits.Temperature TstartIn "Starting temperature at inlet";
parameter Modelica.SIunits.Temperature TstartOut "Starting temperature at outlet";
parameter Modelica.SIunits.Pressure pstartIn "Starting pressure at inlet";
parameter Boolean use_in_w0 = false "Use connector input for the mass flow" annotation(Dialog(group="External inputs"), choices(checkBox=true));
outer ThermoPower.System system "System wide properties";
Modelica.SIunits.MassFlowRate w "Mass flow rate";
Modelica.SIunits.VolumeFlowRate q "Volume flow rate";
Modelica.SIunits.Pressure dp "Outlet pressure minus inlet pressure";
Medium.SpecificEnthalpy hin(start = Medium.specificEnthalpy_pT(pstartIn,TstartIn)) "Enthalpy of entering fluid";
Medium.SpecificEnthalpy hout(start = Medium.specificEnthalpy_pT(poutlet,TstartOut)) "Enthalpy of outgoing fluid";
ThermoPower.LiquidDensity rho "Liquid density";
Modelica.SIunits.Power Power "Power Consumption (total)";
NuclearPowerPlant.Connectors.TwoPhaseFlangeA infl(redeclare package
Medium = Medium, m_flow(min=0)) annotation (Placement(
transformation(extent={{-100,0},{-60,40}}, rotation=0)));
NuclearPowerPlant.Connectors.TwoPhaseFlangeB outfl(
redeclare package Medium = Medium,
m_flow(max=0),
p(start=poutlet)) annotation (Placement(transformation(extent={{40,
40},{80,80}}, rotation=0)));
NuclearPowerPlant.Connectors.RealInput_control in_w0 if use_in_w0
annotation (Placement(transformation(
origin={-40,80},
extent={{-20,-20},{20,20}},
rotation=270)));
protected
Modelica.Blocks.Interfaces.RealInput in_w0_internal;
equation
assert(infl.m_flow>=0,"Reverse flow not allowed in pump");
assert(infl.m_flow+outfl.m_flow>=0,"Fluid lost in loop",level=AssertionLevel.warning);
assert(infl.m_flow+outfl.m_flow<=0,"Fluid gained in loop",level=AssertionLevel.warning);
// Flow equations
q = w/homotopy(rho, rho0);
// Power consumption
Power = dp*q/eta;
// Fluid properties
inletFluidState = Medium.setState_ph(infl.p, hin);
rho = Medium.density(inletFluidState);
//Flow rate control
w = in_w0_internal;
if not use_in_w0 then
in_w0_internal = wstart "Flow rate set by parameter";
end if;
// Boundary conditions
dp = outfl.p - infl.p;
outfl.p = poutlet;
w = -outfl.m_flow "Pump total flow rate";
hin = inStream(infl.h_outflow);
outfl.h_outflow = hout;
infl.h_outflow = hout "Unused balancing equation for reverse flow";
// Mass and energy balances
0 = (outfl.m_flow)*hout + (infl.m_flow)*hin + Power
"Energy balance";
connect(in_w0, in_w0_internal);
annotation (
Documentation(info="
This is the base model for the Pump and
PumpMech pump models.
The model describes a centrifugal pump, or a group of Np identical pumps in parallel. The pump model is based on the theory of kinematic similarity: the pump characteristics are given for nominal operating conditions (rotational speed and fluid density), and then adapted to actual operating condition, according to the similarity equations.
In order to avoid singularities in the computation of the outlet enthalpy at zero flowrate, the thermal capacity of the fluid inside the pump body can be taken into account.
The model can either support reverse flow conditions or include a built-in check valve to avoid flow reversal.
Modelling options
The nominal hydraulic characteristic (head vs. volume flow rate) is given by the the replaceable function flowCharacteristic.
The pump energy balance can be specified in two alternative ways:
- usePowerCharacteristic = false (default option): the replaceable function efficiencyCharacteristic (efficiency vs. volume flow rate in nominal conditions) is used to determine the efficiency, and then the power consumption. The default is a constant efficiency of 0.8.
- usePowerCharacteristic = true: the replaceable function powerCharacteristic (power consumption vs. volume flow rate in nominal conditions) is used to determine the power consumption, and then the efficiency.
Several functions are provided in the package Functions.PumpCharacteristics to specify the characteristics as a function of some operating points at nominal conditions.
Depending on the value of the checkValve parameter, the model either supports reverse flow conditions, or includes a built-in check valve to avoid flow reversal.
If the in_Np input connector is wired, it provides the number of pumps in parallel; otherwise, Np0 parallel pumps are assumed.
It is possible to take into account the heat capacity of the fluid inside the pump by specifying its volume V at nominal conditions; this is necessary to avoid singularities in the computation of the outlet enthalpy in case of zero flow rate. If zero flow rate conditions are always avoided, this dynamic effect can be neglected by leaving the default value V = 0, thus avoiding a fast state variable in the model.
The CheckValve parameter determines whether the pump has a built-in check valve or not.
If computeNPSHa = true, the available net positive suction head is also computed; this requires a two-phase medium model to provide the fluid saturation pressure.
", revisions="
"), Icon(graphics={Polygon(
points={{-30,52},{48,20},{-30,-8},{-30,52}},
lineColor={57,150,0},
fillColor={57,150,0},
fillPattern=FillPattern.Solid)}));
end TwoPhasePumpControl;
model AirPumpSimple "Simple centrifugal pump for air"
extends LAES.Components.Icons.Pump;
replaceable package Medium = NuclearPowerPlant.Media.AirCoolProp constrainedby
Modelica.Media.Interfaces.PartialMedium "Medium model"
annotation(choicesAllMatching = true);
Medium.ThermodynamicState inletFluidState
"Thermodynamic state of the fluid at the inlet";
parameter Real eta "Pump efficiency";
parameter ThermoPower.Density rho0=1000 "Nominal Liquid Density"
annotation (Dialog(group="Characteristics"));
parameter Boolean allowFlowReversal=system.allowFlowReversal
"= true to allow flow reversal, false restricts to design direction";
parameter Modelica.SIunits.Pressure dp "Outlet pressure minus inlet pressure";
outer ThermoPower.System system "System wide properties";
Modelica.SIunits.MassFlowRate w "Mass flow rate";
Modelica.SIunits.VolumeFlowRate q "Volume flow rate";
Medium.SpecificEnthalpy h "Fluid specific enthalpy";
Medium.SpecificEnthalpy hin "Enthalpy of entering fluid";
Medium.SpecificEnthalpy hout "Enthalpy of outgoing fluid";
ThermoPower.LiquidDensity rho "Liquid density";
Modelica.SIunits.Power W "Power Consumption (total)";
NuclearPowerPlant.Connectors.TwoPhaseFlangeA infl(redeclare package
Medium = Medium, m_flow(min=if allowFlowReversal then -Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{-100,0},{
-60,40}}, rotation=0)));
NuclearPowerPlant.Connectors.TwoPhaseFlangeB outfl(redeclare package
Medium = Medium, m_flow(max=if allowFlowReversal then +Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{40,50},{
80,90}}, rotation=0)));
equation
// Flow equations
q = w/homotopy(rho, rho0);
// Power consumption
W = dp*q/eta;
// Fluid properties
inletFluidState = Medium.setState_ph(infl.p, hin);
rho = Medium.density(inletFluidState);
// Boundary conditions
dp = outfl.p - infl.p;
w = infl.m_flow "Pump total flow rate";
hin = homotopy(if not allowFlowReversal then inStream(infl.h_outflow)
else if w >= 0 then inStream(infl.h_outflow)
else inStream(outfl.h_outflow),
inStream(infl.h_outflow));
infl.h_outflow = hout;
outfl.h_outflow = hout;
h = hout;
// Mass and energy balances
infl.m_flow + outfl.m_flow = 0 "Mass balance";
0 = (outfl.m_flow)*hout + (infl.m_flow)*hin + W
"Energy balance";
annotation (
Diagram(graphics),
Documentation(info="
This is the base model for the Pump and
PumpMech pump models.
The model describes a centrifugal pump, or a group of Np identical pumps in parallel. The pump model is based on the theory of kinematic similarity: the pump characteristics are given for nominal operating conditions (rotational speed and fluid density), and then adapted to actual operating condition, according to the similarity equations.
In order to avoid singularities in the computation of the outlet enthalpy at zero flowrate, the thermal capacity of the fluid inside the pump body can be taken into account.
The model can either support reverse flow conditions or include a built-in check valve to avoid flow reversal.
Modelling options
The nominal hydraulic characteristic (head vs. volume flow rate) is given by the the replaceable function flowCharacteristic.
The pump energy balance can be specified in two alternative ways:
- usePowerCharacteristic = false (default option): the replaceable function efficiencyCharacteristic (efficiency vs. volume flow rate in nominal conditions) is used to determine the efficiency, and then the power consumption. The default is a constant efficiency of 0.8.
- usePowerCharacteristic = true: the replaceable function powerCharacteristic (power consumption vs. volume flow rate in nominal conditions) is used to determine the power consumption, and then the efficiency.
Several functions are provided in the package Functions.PumpCharacteristics to specify the characteristics as a function of some operating points at nominal conditions.
Depending on the value of the checkValve parameter, the model either supports reverse flow conditions, or includes a built-in check valve to avoid flow reversal.
If the in_Np input connector is wired, it provides the number of pumps in parallel; otherwise, Np0 parallel pumps are assumed.
It is possible to take into account the heat capacity of the fluid inside the pump by specifying its volume V at nominal conditions; this is necessary to avoid singularities in the computation of the outlet enthalpy in case of zero flow rate. If zero flow rate conditions are always avoided, this dynamic effect can be neglected by leaving the default value V = 0, thus avoiding a fast state variable in the model.
The CheckValve parameter determines whether the pump has a built-in check valve or not.
If computeNPSHa = true, the available net positive suction head is also computed; this requires a two-phase medium model to provide the fluid saturation pressure.
", revisions="
"), Icon(graphics={Polygon(
points={{-30,52},{48,20},{-30,-8},{-30,52}},
lineColor={57,150,0},
fillColor={57,150,0},
fillPattern=FillPattern.Solid)}));
end AirPumpSimple;
model CompressorSimpleTwoPhase
"Simple compressor model with lookup table for isentropic efficiency based on flow rate"
extends LAES.Components.Icons.CompressorTwoPhase;
replaceable package Medium = NuclearPowerPlant.Media.AirCoolProp
annotation(choicesAllMatching = true);
parameter Boolean explicitIsentropicEnthalpy=true
"isentropicEnthalpy function used";
parameter Real eta_mech=0.98 "mechanical efficiency";
parameter Modelica.SIunits.AbsolutePressure pstart_in "inlet start pressure"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.AbsolutePressure pstart_out "outlet start pressure"
annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.MassFlowRate m_flow_des "design mass flow rate";
parameter Boolean allowFlowReversal=system.allowFlowReversal
"= true to allow flow reversal, false restricts to design direction";
outer ThermoPower.System system "System wide properties";
parameter ThermoPower.AbsoluteTemperature Tstart_in
"inlet start temperature" annotation (Dialog(tab="Initialisation"));
parameter ThermoPower.AbsoluteTemperature Tstart_out
"outlet start temperature" annotation (Dialog(tab="Initialisation"));
parameter Modelica.SIunits.MassFlowRate wstart
"starting mass flow rate" annotation (Dialog(tab="Initialisation"));
parameter Real PR "pressure ratio";
parameter Real tableEta[5, 2]=[0.5, 0.6; 0.70, 0.7; 0.80, 0.75; 0.90, 0.77; 1.0, 0.79] "Table for eta(m_flow_factor)";
Medium.BaseProperties gas_in(
p(start=pstart_in),
T(start=Tstart_in));
Medium.BaseProperties gas_iso(
p(start=pstart_out),
T(start=Tstart_out));
Medium.SpecificEnthalpy hout_iso "Outlet isentropic enthalpy";
Medium.SpecificEnthalpy hout "Outlet enthaply";
Medium.SpecificEntropy s_in "Inlet specific entropy";
Medium.AbsolutePressure pout(start=pstart_out) "Outlet pressure";
Modelica.SIunits.MassFlowRate w(start=wstart) "Gas flow rate";
Modelica.SIunits.Power Power "Compressor power input";
Real eta "isentropic efficiency";
Real m_flow_factor "fraction of design mass flow rate";
NuclearPowerPlant.Connectors.TwoPhaseFlangeA inlet(redeclare package
Medium = Medium, m_flow(min=if allowFlowReversal then -Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{-100,60},
{-60,100}}, rotation=0)));
NuclearPowerPlant.Connectors.TwoPhaseFlangeB outlet(redeclare package
Medium = Medium, m_flow(max=if allowFlowReversal then +Modelica.Constants.inf
else 0)) annotation (Placement(transformation(extent={{60,60},{
100,100}}, rotation=0)));
Modelica.Blocks.Tables.CombiTable1Ds Eta(
tableOnFile=false,
table=tableEta)
annotation (Placement(transformation(extent={{-10,-10},{10,10}},
rotation=0)));
equation
w = inlet.m_flow;
assert(w >= 0, "The compressor model does not support flow reversal");
inlet.m_flow + outlet.m_flow = 0 "Mass balance";
m_flow_factor=w/m_flow_des "calculation of fraction of design mass flow rate";
// Set inlet gas properties
gas_in.p = inlet.p;
gas_in.h = inStream(inlet.h_outflow);
// Set outlet gas properties
outlet.p = pout;
outlet.h_outflow = hout;
// Equations for reverse flow (not used)
inlet.h_outflow = inStream(outlet.h_outflow);
if explicitIsentropicEnthalpy then
hout_iso = Medium.isentropicEnthalpy(outlet.p, gas_in.state)
"Approximated isentropic enthalpy";
hout - gas_in.h = 1/eta*(hout_iso - gas_in.h) "Enthalpy change";
// dummy assignments
s_in = 0;
gas_iso.p = 1e5;
gas_iso.T = 300;
else
// Properties of the gas after isentropic transformation
gas_iso.p = pout;
s_in = Medium.specificEntropy(gas_in.state);
s_in = Medium.specificEntropy(gas_iso.state);
hout - gas_in.h = 1/eta*(gas_iso.h - gas_in.h);
// dummy assignment
hout_iso = 0;
end if;
w*(hout - gas_in.h) = Power*eta_mech "Energy balance";
PR = pout/gas_in.p "Pressure ratio";
// eta = Eta(m_flow_factor)
Eta.u = m_flow_factor;
eta = Eta.y[1];
annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end CompressorSimpleTwoPhase;
end TwoPhase;
end Machinery;
package Controllers "Control signal generators"
block Pulse_Control "Generate pulse signal of type Real"
parameter Real amplitude=1 "Amplitude of pulse";
parameter Real width(
final min=Modelica.Constants.small,
final max=100) = 50 "Width of pulse in % of period";
parameter Modelica.SIunits.Time period(final min=Modelica.Constants.small,
start=1) "Time for one period";
parameter Integer nperiod=-1
"Number of periods (< 0 means infinite number of periods)";
parameter Real offset=0 "Offset of output signals";
parameter Modelica.SIunits.Time startTime=0
"Output = offset for time < startTime";
extends LAES.Components.BaseClasses.SO;
protected
Modelica.SIunits.Time T_width=period*width/100;
Modelica.SIunits.Time T_start "Start time of current period";
Integer count "Period count";
initial algorithm
count := integer((time - startTime)/period);
T_start := startTime + count*period;
equation
when integer((time - startTime)/period) > pre(count) then
count = pre(count) + 1;
T_start = time;
end when;
y = offset + (if (time < startTime or nperiod == 0 or (nperiod > 0 and
count >= nperiod)) then 0 else if time < T_start + T_width then amplitude
else 0);
connect(y, y) annotation (Line(points={{110,0},{110,0},{110,0}}, color={0,0,127}));
annotation (
Icon(coordinateSystem(
preserveAspectRatio=true,
extent={{-100,-100},{100,100}}), graphics={
Line(points={{-80,68},{-80,-80}}, color={192,192,192}),
Polygon(
points={{-80,90},{-88,68},{-72,68},{-80,90}},
lineColor={192,192,192},
fillColor={192,192,192},
fillPattern=FillPattern.Solid),
Line(points={{-90,-70},{82,-70}}, color={192,192,192}),
Polygon(
points={{90,-70},{68,-62},{68,-78},{90,-70}},
lineColor={192,192,192},
fillColor={192,192,192},
fillPattern=FillPattern.Solid),
Line(points={{-80,-70},{-40,-70},{-40,44},{0,44},{0,-70},{40,-70},{40,
44},{79,44}}),
Text(
extent={{-147,-152},{153,-112}},
lineColor={0,0,0},
textString="period=%period")}),
Diagram(coordinateSystem(
preserveAspectRatio=true,
extent={{-100,-100},{100,100}}), graphics={
Polygon(
points={{-80,90},{-85,68},{-75,68},{-80,90}},
lineColor={95,95,95},
fillColor={95,95,95},
fillPattern=FillPattern.Solid),
Line(points={{-80,68},{-80,-80}}, color={95,95,95}),
Line(points={{-90,-70},{82,-70}}, color={95,95,95}),
Polygon(
points={{90,-70},{68,-65},{68,-75},{90,-70}},
lineColor={95,95,95},
fillColor={95,95,95},
fillPattern=FillPattern.Solid),
Polygon(
points={{-34,0},{-37,-13},{-31,-13},{-34,0}},
lineColor={95,95,95},
fillColor={95,95,95},
fillPattern=FillPattern.Solid),
Line(points={{-34,0},{-34,-70}}, color={95,95,95}),
Polygon(
points={{-34,-70},{-37,-57},{-31,-57},{-34,-70},{-34,-70}},
lineColor={95,95,95},
fillColor={95,95,95},
fillPattern=FillPattern.Solid),
Text(
extent={{-78,-24},{-35,-36}},
lineColor={0,0,0},
textString="offset"),
Text(
extent={{-30,-72},{16,-81}},
lineColor={0,0,0},
textString="startTime"),
Text(
extent={{-82,96},{-49,79}},
lineColor={0,0,0},
textString="y"),
Text(
extent={{66,-80},{87,-90}},
lineColor={0,0,0},
textString="time"),
Line(points={{-10,0},{-10,-70}}, color={95,95,95}),
Line(
points={{-80,0},{-10,0},{-10,50},{30,50},{30,0},{50,0},{50,50},{90,
50}},
color={255,0,0},
thickness=0.5),
Line(points={{-10,88},{-10,50}}, color={95,95,95}),
Line(points={{30,74},{30,50}}, color={95,95,95}),
Line(points={{50,88},{50,50}}, color={95,95,95}),
Line(points={{-10,83},{50,83}}, color={95,95,95}),
Line(points={{-10,69},{30,69}}, color={95,95,95}),
Text(
extent={{-3,93},{39,84}},
lineColor={0,0,0},
textString="period"),
Text(
extent={{-7,78},{30,69}},
lineColor={0,0,0},
textString="width"),
Line(points={{-43,50},{-10,50}}, color={95,95,95}),
Line(points={{-34,50},{-34,0}}, color={95,95,95}),
Text(
extent={{-77,30},{-37,21}},
lineColor={0,0,0},
textString="amplitude"),
Polygon(
points={{-34,50},{-37,37},{-31,37},{-34,50}},
lineColor={95,95,95},
fillColor={95,95,95},
fillPattern=FillPattern.Solid),
Polygon(
points={{-34,0},{-37,13},{-31,13},{-34,0},{-34,0}},
lineColor={95,95,95},
fillColor={95,95,95},
fillPattern=FillPattern.Solid),
Line(
points={{90,50},{90,0},{100,0}},
color={255,0,0},
thickness=0.5),
Polygon(
points={{-10,69},{-1,71},{-1,67},{-10,69}},
lineColor={95,95,95},
fillColor={95,95,95},
fillPattern=FillPattern.Solid),
Polygon(
points={{30,69},{22,71},{22,67},{30,69}},
lineColor={95,95,95},
fillColor={95,95,95},
fillPattern=FillPattern.Solid),
Polygon(
points={{-10,83},{-1,85},{-1,81},{-10,83}},
lineColor={95,95,95},
fillColor={95,95,95},
fillPattern=FillPattern.Solid),
Polygon(
points={{50,83},{42,85},{42,81},{50,83}},
lineColor={95,95,95},
fillColor={95,95,95},
fillPattern=FillPattern.Solid)}),
Documentation(info="
The Real output y is a pulse signal:
"));
end Pulse_Control;
block Trapezoid_control "Generate trapezoidal signal of type Real"
parameter Real amplitude=1 "Amplitude of trapezoid";
parameter Modelica.SIunits.Time rising(final min=0)=0 "Rising duration of trapezoid";
parameter Modelica.SIunits.Time width(final min=0)=0.5 "Width duration of trapezoid";
parameter Modelica.SIunits.Time falling(final min=0)=0 "Falling duration of trapezoid";
parameter Modelica.SIunits.Time period(final min=Modelica.Constants.small, start=1) "Time for one period";
parameter Integer nperiod=-1
"Number of periods (< 0 means infinite number of periods)";
parameter Real offset=0 "Offset of output signal";
parameter Modelica.SIunits.Time startTime=0 "Output = offset for time < startTime";
extends LAES.Components.BaseClasses.SO;
protected
parameter Modelica.SIunits.Time T_rising=rising "End time of rising phase within one period";
parameter Modelica.SIunits.Time T_width=T_rising + width "End time of width phase within one period";
parameter Modelica.SIunits.Time T_falling=T_width + falling "End time of falling phase within one period";
Modelica.SIunits.Time T_start "Start time of current period";
Integer count "Period count";
initial algorithm
count := integer((time - startTime)/period);
T_start := startTime + count*period;
equation
when integer((time - startTime)/period) > pre(count) then
count = pre(count) + 1;
T_start = time;
end when;
y = offset + (if (time < startTime or nperiod == 0 or (nperiod > 0 and
count >= nperiod)) then 0 else if (time < T_start + T_rising) then
amplitude*(time - T_start)/rising else if (time < T_start + T_width)
then amplitude else if (time < T_start + T_falling) then amplitude*(
T_start + T_falling - time)/falling else 0);
annotation (
Icon(coordinateSystem(
preserveAspectRatio=true,
extent={{-100,-100},{100,100}}), graphics={
Line(points={{-80,68},{-80,-80}}, color={192,192,192}),
Polygon(
points={{-80,90},{-88,68},{-72,68},{-80,90}},
lineColor={192,192,192},
fillColor={192,192,192},
fillPattern=FillPattern.Solid),
Line(points={{-90,-70},{82,-70}}, color={192,192,192}),
Polygon(
points={{90,-70},{68,-62},{68,-78},{90,-70}},
lineColor={192,192,192},
fillColor={192,192,192},
fillPattern=FillPattern.Solid),
Text(
extent={{-147,-152},{153,-112}},
lineColor={0,0,0},
textString="period=%period"),
Line(points={{-81,-70},{-60,-70},{-30,40},{9,40},{39,-70},{61,-70},{
90,40}})}),
Diagram(coordinateSystem(
preserveAspectRatio=true,
extent={{-100,-100},{100,100}}), graphics={
Polygon(
points={{-81,90},{-87,68},{-75,68},{-81,90}},
lineColor={95,95,95},
fillColor={95,95,95},
fillPattern=FillPattern.Solid),
Line(points={{-81,68},{-81,-80}}, color={95,95,95}),
Line(points={{-91,-70},{81,-70}}, color={95,95,95}),
Polygon(
points={{89,-70},{67,-65},{67,-76},{89,-70}},
lineColor={95,95,95},
fillColor={95,95,95},
fillPattern=FillPattern.Solid),
Polygon(
points={{-46,-30},{-48,-41},{-44,-41},{-46,-30}},
lineColor={95,95,95},
fillColor={95,95,95},
fillPattern=FillPattern.Solid),
Line(
points={{-46,-30},{-46,-70}},
color={95,95,95}),
Polygon(
points={{-46,-70},{-48,-60},{-44,-60},{-46,-70},{-46,-70}},
lineColor={95,95,95},
fillColor={95,95,95},
fillPattern=FillPattern.Solid),
Text(
extent={{-80,-46},{-42,-55}},
lineColor={0,0,0},
textString="offset"),
Text(
extent={{-49,-71},{-6,-81}},
lineColor={0,0,0},
textString="startTime"),
Text(
extent={{-80,95},{-47,80}},
lineColor={0,0,0},
textString="y"),
Text(
extent={{66,-78},{89,-89}},
lineColor={0,0,0},
textString="time"),
Line(
points={{-31,82},{-31,-70}},
color={95,95,95},
pattern=LinePattern.Dash),
Line(
points={{-11,59},{-11,40}},
color={95,95,95},
pattern=LinePattern.Dash),
Line(
points={{19,59},{19,40}},
color={95,95,95},
pattern=LinePattern.Dash),
Line(
points={{39,59},{39,-30}},
color={95,95,95},
pattern=LinePattern.Dash),
Line(points={{-31,76},{59,76}}, color={95,95,95}),
Line(points={{-31,56},{39,56}}, color={95,95,95}),
Text(
extent={{-3,86},{24,77}},
lineColor={0,0,0},
textString="period"),
Text(
extent={{-11,68},{18,59}},
lineColor={0,0,0},
textString="width"),
Line(
points={{-43,40},{-11,40}},
color={95,95,95},
pattern=LinePattern.Dash),
Line(
points={{-40,40},{-40,-30}},
color={95,95,95}),
Text(
extent={{-77,11},{-44,1}},
lineColor={0,0,0},
textString="amplitude"),
Polygon(
points={{-31,56},{-24,58},{-24,54},{-31,56}},
lineColor={95,95,95},
fillColor={95,95,95},
fillPattern=FillPattern.Solid),
Polygon(
points={{-11,56},{-18,58},{-18,54},{-11,56}},
lineColor={95,95,95},
fillColor={95,95,95},
fillPattern=FillPattern.Solid),
Polygon(
points={{-31,76},{-22,78},{-22,74},{-31,76}},
lineColor={95,95,95},
fillColor={95,95,95},
fillPattern=FillPattern.Solid),
Polygon(
points={{59,76},{51,78},{51,74},{59,76}},
lineColor={95,95,95},
fillColor={95,95,95},
fillPattern=FillPattern.Solid),
Line(
points={{-81,-30},{-31,-30},{-11,40},{19,40},{39,-30},{59,-30},{79,
40},{99,40}},
color={0,0,255},
thickness=0.5),
Polygon(
points={{-40,40},{-42,29},{-38,29},{-40,40}},
lineColor={95,95,95},
fillColor={95,95,95},
fillPattern=FillPattern.Solid),
Polygon(
points={{-40,-30},{-42,-20},{-38,-20},{-40,-30},{-40,-30}},
lineColor={95,95,95},
fillColor={95,95,95},
fillPattern=FillPattern.Solid),
Line(
points={{59,84},{59,-30}},
color={95,95,95},
pattern=LinePattern.Dash),
Polygon(
points={{39,56},{32,58},{32,54},{39,56}},
lineColor={95,95,95},
fillColor={95,95,95},
fillPattern=FillPattern.Solid),
Polygon(
points={{19,56},{26,58},{26,54},{19,56}},
lineColor={95,95,95},
fillColor={95,95,95},
fillPattern=FillPattern.Solid),
Polygon(
points={{19,56},{12,58},{12,54},{19,56}},
lineColor={95,95,95},
fillColor={95,95,95},
fillPattern=FillPattern.Solid),
Polygon(
points={{-11,56},{-4,58},{-4,54},{-11,56}},
lineColor={95,95,95},
fillColor={95,95,95},
fillPattern=FillPattern.Solid),
Text(
extent={{-35,68},{-6,60}},
lineColor={0,0,0},
textString="rising"),
Text(
extent={{16,68},{44,60}},
lineColor={0,0,0},
textString="falling")}),
Documentation(info="
The Real output y is a trapezoid signal:
"));
end Trapezoid_control;
end Controllers;
end Components;
package Media "Medium models for NPP model"
package PropaneRefProp "Medium model for propane using RefProp"
import ExternalMedia;
extends ExternalMedia.Media.FluidPropMedium(
mediumName="Propane",
libraryName="FluidProp.RefProp",
substanceNames={"C3H8"},
ThermoStates=Modelica.Media.Interfaces.Choices.IndependentVariables.ph);
annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end PropaneRefProp;
package MethanolRefProp "Medium model for methanol using RefProp"
import ExternalMedia;
extends ExternalMedia.Media.FluidPropMedium(
mediumName="Methanol",
libraryName="FluidProp.RefProp",
substanceNames={"CH4O"},
ThermoStates=Modelica.Media.Interfaces.Choices.IndependentVariables.ph);
annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end MethanolRefProp;
package WaterRefProp "Medium model for water using RefProp"
import ExternalMedia;
extends ExternalMedia.Media.FluidPropMedium(
mediumName="Water",
libraryName="FluidProp.RefProp",
substanceNames={"H2O"},
ThermoStates=Modelica.Media.Interfaces.Choices.IndependentVariables.ph);
annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end WaterRefProp;
package AirRefProp "Medium model for air using RefProp"
import ExternalMedia;
extends ExternalMedia.Media.FluidPropMedium(
mediumName="air",
libraryName="FluidProp.RefProp",
substanceNames={"AIR"},
ThermoStates=Modelica.Media.Interfaces.Choices.IndependentVariables.ph);
annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end AirRefProp;
package NitrogenRefProp "Medium model for nitrogen using RefProp"
import ExternalMedia;
extends ExternalMedia.Media.FluidPropMedium(
mediumName="nitrogen",
libraryName="FluidProp.RefProp",
substanceNames={"nitrogen"},
ThermoStates=Modelica.Media.Interfaces.Choices.IndependentVariables.ph);
annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end NitrogenRefProp;
package AirCoolProp "CoolProp model of air"
extends ExternalMedia.Media.CoolPropMedium(
mediumName = "Air",
substanceNames = {"air"},
ThermoStates = Modelica.Media.Interfaces.Choices.IndependentVariables.ph,
AbsolutePressure(start=10e5),
SpecificEnthalpy(start=2e5));
end AirCoolProp;
package WaterCoolProp "CoolProp model of water"
extends ExternalMedia.Media.CoolPropMedium(
mediumName = "Water",
substanceNames = {"water"},
ThermoStates = Modelica.Media.Interfaces.Choices.IndependentVariables.ph,
AbsolutePressure(start=10e5),
SpecificEnthalpy(start=2e5));
end WaterCoolProp;
end Media;
annotation (Documentation(info="
A plant process simulation model for a liquid air energy storage system was developed as part of a PhD project by Andy Wilson.
The bulk of the work associated with this model was published as a working paper in 2020: https://www.eprg.group.cam.ac.uk/eprg-working-paper-2001/. My PhD thesis and any further developments to this work will be added to the package information as an when I get the oppotunity. This package remains very much a work in progress. Coding is something new to me and I'm sure others will be able to develop improved versions of many of these components.
This package contains the components usede in the simulation model. As the opportunity to do so arises, this package will be updated with example plant models utilising these components.
Three additional packages are required for the models in this set to work:
- The Modelica standard library v3.2.2 or higher.
- The Thermopower library v3.1 or higher (https://github.com/casella/ThermoPower) upon which many of these components are based.
- The ExternalMedia library v3.2.1 or higher (https://github.com/modelica-3rdparty/ExternalMedia) if reference to external thermofluid property databases is required. It should be noted that neither the Thermopower nor the Modelica standard library have air packages that operate in the cryogenic range. By default, this library uses CoolProp's pseudo-pure model of air.
"), uses(ThermoPower(version="3.1"), Modelica(version="3.2.2")));
end LAES;