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 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:

    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:

    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:

    ", 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=" ")); 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=" ")); 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=" ")); 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=" ")); 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 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:

    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=" ", 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:

    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:

    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:

    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:

    \"Pulse.png\"

    ")); 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:

    \"Trapezoid\"

    ")); 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:

    "), uses(ThermoPower(version="3.1"), Modelica(version="3.2.2"))); end LAES;