This package contains models for district heating and cooling substations
that provide heating or cooling using vapor compression engines.
Model for a substation with space heating, space cooling and domestic hot water.
The model takes as parameters
the temperature lift on the primary side and
and then draws the required amount of water.
The load is specified by a file that contains
time series for the load profiles. This file needs to have
the following format:
Values at intermediate times are interpolated using cubic Hermite splines.
The time series data are interpolated using
Fritsch-Butland interpolation. This uses
cubic Hermite splines such that y preserves the monotonicity and
der(y) is continuous, also if extrapolated.
There is a control volume at each of the two fluid ports
that are exposed by this model. These approximate the dynamics
of the substation, and they also generally avoid nonlinear system
of equations if multiple substations are connected to each other.
model HeatingCoolingHotwaterTimeSeries_dT
replaceable package Medium =
Modelica.Media.Interfaces.PartialMedium ;
parameter Real gaiCoo(min=0) = 1 ;
parameter Real gaiHea(min=0) = gaiCoo ;
parameter Real gaiHotWat(min=0) = gaiHea ;
parameter Modelica.SIunits.Temperature TColMin = 273.15+8
;
parameter Modelica.SIunits.Temperature THotMax = 273.15+18
;
parameter Modelica.SIunits.TemperatureDifference dTCooCon_nominal(
min=0.5,
displayUnit="K") = 4
;
parameter Modelica.SIunits.TemperatureDifference dTHeaEva_nominal(
max=-0.5,
displayUnit="K") = -4
;
parameter Modelica.SIunits.TemperatureDifference dTCooEva_nominal=-4
;
parameter String filNam ;
parameter Modelica.SIunits.HeatFlowRate QCoo_flow_nominal(max=-Modelica.Constants.eps)= gaiCoo *
Buildings.Experimental.DistrictHeatingCooling.SubStations.VaporCompression.BaseClasses.getPeakLoad(
string="#Peak space cooling load",
filNam=filNam) ;
parameter Modelica.SIunits.HeatFlowRate QHea_flow_nominal(min=Modelica.Constants.eps)= gaiHea *
Buildings.Experimental.DistrictHeatingCooling.SubStations.VaporCompression.BaseClasses.getPeakLoad(
string="#Peak space heating load",
filNam=filNam) ;
parameter Modelica.SIunits.HeatFlowRate QHotWat_flow_nominal(min=Modelica.Constants.eps)= gaiHotWat *
Buildings.Experimental.DistrictHeatingCooling.SubStations.VaporCompression.BaseClasses.getPeakLoad(
string="#Peak water heating load",
filNam=filNam) ;
parameter Modelica.SIunits.Temperature TChiSup_nominal = 273.15 + 16
;
parameter Modelica.SIunits.Temperature THeaSup_nominal = 273.15+30
;
parameter Modelica.SIunits.Temperature THeaRet_nominal = 273.15+25
;
parameter Modelica.SIunits.Temperature TOut_nominal
;
parameter Modelica.SIunits.TemperatureDifference dTHotWatCon_nominal(min=0)=60-40
;
parameter Modelica.SIunits.Pressure dp_nominal(displayUnit="Pa")=30000
;
final parameter Modelica.SIunits.MassFlowRate mCooCon_flow_nominal(min=0)=
-QCoo_flow_nominal/cp_default/dTCooCon_nominal
;
final parameter Modelica.SIunits.MassFlowRate mHeaEva_flow_nominal(min=0)=
-QHea_flow_nominal/cp_default/dTHeaEva_nominal
;
final parameter Modelica.SIunits.MassFlowRate mHotWatEva_flow_nominal(min=0)=
QHotWat_flow_nominal/cp_default/dTHotWatCon_nominal
;
parameter Boolean show_T = false
;
parameter Modelica.Fluid.Types.Dynamics mixingVolumeEnergyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial
;
Modelica.Blocks.Interfaces.RealOutput PHea(unit="W")
;
Modelica.Blocks.Interfaces.RealOutput PHotWat(unit="W")
;
Modelica.Blocks.Interfaces.RealOutput PCoo(unit="W")
;
Modelica.Blocks.Interfaces.RealOutput QHea_flow(unit="W")
;
Modelica.Blocks.Interfaces.RealOutput QHotWat_flow(unit="W")
;
Modelica.Blocks.Interfaces.RealOutput QCoo_flow(unit="W")
;
BoundaryConditions.WeatherData.Bus weaBus;
Modelica.Fluid.Interfaces.FluidPort_a port_a(
redeclare final package Medium =
Medium,
h_outflow(start=Medium.h_default)) ;
Modelica.Fluid.Interfaces.FluidPort_b port_b(
redeclare final package Medium =
Medium,
h_outflow(start=Medium.h_default)) ;
Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort_a
;
Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort_b
;
Medium.ThermodynamicState staHea_a2=
Medium.setState_phX(heaPum.port_a2.p,
noEvent(
actualStream(heaPum.port_a2.h_outflow)),
noEvent(
actualStream(heaPum.port_a2.Xi_outflow)))
if
show_T ;
Medium.ThermodynamicState staHea_b2=
Medium.setState_phX(heaPum.port_b2.p,
noEvent(
actualStream(heaPum.port_b2.h_outflow)),
noEvent(
actualStream(heaPum.port_b2.Xi_outflow)))
if
show_T ;
Medium.ThermodynamicState staHotWat_a2=
Medium.setState_phX(heaPumHotWat.port_a2.p,
noEvent(
actualStream(heaPumHotWat.port_a2.h_outflow)),
noEvent(
actualStream(heaPumHotWat.port_a2.Xi_outflow)))
if
show_T ;
Medium.ThermodynamicState staHotWat_b2=
Medium.setState_phX(heaPumHotWat.port_b2.p,
noEvent(
actualStream(heaPumHotWat.port_b2.h_outflow)),
noEvent(
actualStream(heaPumHotWat.port_b2.Xi_outflow)))
if
show_T ;
Medium.ThermodynamicState staCoo_a1=
Medium.setState_phX(chi.port_a1.p,
noEvent(
actualStream(chi.port_a1.h_outflow)),
noEvent(
actualStream(chi.port_a1.Xi_outflow)))
if
show_T ;
Medium.ThermodynamicState staCoo_b1=
Medium.setState_phX(chi.port_b1.p,
noEvent(
actualStream(chi.port_b1.h_outflow)),
noEvent(
actualStream(chi.port_b1.Xi_outflow)))
if
show_T ;
constant Modelica.SIunits.SpecificHeatCapacity cp_default=4184
;
Buildings.Fluid.HeatPumps.Carnot_TCon heaPum(
redeclare package Medium1 =
Medium,
redeclare package Medium2 =
Medium,
dTEva_nominal=dTHeaEva_nominal,
dTCon_nominal=THeaSup_nominal-THeaRet_nominal,
allowFlowReversal1=false,
allowFlowReversal2=allowFlowReversal,
use_eta_Carnot_nominal=true,
etaCarnot_nominal=0.3,
QCon_flow_nominal=QHea_flow_nominal,
dp1_nominal=dp_nominal,
dp2_nominal=dp_nominal) ;
Buildings.Fluid.Movers.FlowControlled_m_flow pumHea(
redeclare package Medium =
Medium,
energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState,
allowFlowReversal=allowFlowReversal,
m_flow_nominal=mHeaEva_flow_nominal,
inputType=Buildings.Fluid.Types.InputType.Continuous,
use_inputFilter=false,
addPowerToMedium=false) ;
Buildings.Controls.SetPoints.HotWaterTemperatureReset TSupHeaSet(
TSup_nominal=THeaSup_nominal,
TRet_nominal=THeaRet_nominal,
TOut_nominal=TOut_nominal) ;
Buildings.Fluid.Movers.FlowControlled_m_flow pumHotWat(
redeclare package Medium =
Medium,
energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState,
m_flow_nominal=mHotWatEva_flow_nominal,
allowFlowReversal=allowFlowReversal,
inputType=Buildings.Fluid.Types.InputType.Continuous,
use_inputFilter=false,
addPowerToMedium=false) ;
Buildings.Fluid.HeatPumps.Carnot_TCon heaPumHotWat(
redeclare package Medium1 =
Medium,
redeclare package Medium2 =
Medium,
dTEva_nominal=dTHeaEva_nominal,
allowFlowReversal1=false,
allowFlowReversal2=allowFlowReversal,
use_eta_Carnot_nominal=true,
etaCarnot_nominal=0.3,
dp1_nominal=dp_nominal,
dp2_nominal=dp_nominal,
QCon_flow_nominal=QHotWat_flow_nominal,
dTCon_nominal=dTHotWatCon_nominal) ;
Buildings.Fluid.Chillers.Carnot_TEva chi(
redeclare package Medium1 =
Medium,
redeclare package Medium2 =
Medium,
use_eta_Carnot_nominal=true,
etaCarnot_nominal=0.3,
dp1_nominal=dp_nominal,
dp2_nominal=dp_nominal,
QEva_flow_nominal=QCoo_flow_nominal,
dTEva_nominal=dTCooEva_nominal,
dTCon_nominal=dTCooCon_nominal,
allowFlowReversal1=allowFlowReversal,
allowFlowReversal2=false) ;
Buildings.Fluid.Movers.FlowControlled_m_flow pumChi(
redeclare package Medium =
Medium,
energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState,
allowFlowReversal=allowFlowReversal,
inputType=Buildings.Fluid.Types.InputType.Continuous,
use_inputFilter=false,
m_flow_nominal=mCooCon_flow_nominal,
addPowerToMedium=false) ;
protected
constant Boolean allowFlowReversal = false
;
final parameter Medium.ThermodynamicState sta_default =
Medium.setState_pTX(
T=Medium.T_default,
p=Medium.p_default,
X=Medium.X_default[1:Medium.nXi]) ;
final parameter Modelica.SIunits.SpecificHeatCapacity cp_default_check=
Medium.specificHeatCapacityCp(sta_default)
;
Modelica.Blocks.Sources.CombiTimeTable loa(
tableOnFile=true,
tableName="tab1",
fileName=
Modelica.Utilities.Files.loadResource(filNam),
extrapolation=Modelica.Blocks.Types.Extrapolation.Periodic,
y(
each unit="W"),
offset={0,0,0},
columns={2,3,4},
smoothness=Modelica.Blocks.Types.Smoothness.MonotoneContinuousDerivative1)
;
Modelica.Blocks.Routing.DeMultiplex3 deMul ;
Buildings.Fluid.Sources.MassFlowSource_T sou(
redeclare package Medium =
Medium,
nPorts=1,
use_m_flow_in=true,
use_T_in=true) ;
Buildings.Fluid.Sources.FixedBoundary sin1(
redeclare package Medium =
Medium,
nPorts=1);
Modelica.Blocks.Math.Add dTHeaAct(k2=-1) ;
Modelica.Blocks.Math.Division mConFlow ;
Modelica.Blocks.Math.Gain gainH(k=cp_default) ;
Modelica.Blocks.Math.Add QEva_flow(k1=-1) ;
Modelica.Blocks.Math.Add PHeaAct ;
Modelica.Blocks.Math.Add QEvaHotWat_flow(k1=-1)
;
Modelica.Blocks.Math.Add PHotWatAct ;
Buildings.Fluid.Sources.FixedBoundary sinHotWat(
redeclare package Medium =
Medium,
nPorts=1) ;
Buildings.Fluid.Sources.MassFlowSource_T souHotWat(
redeclare package Medium =
Medium,
nPorts=1,
use_m_flow_in=true,
use_T_in=false,
T=313.15) ;
Modelica.Blocks.Math.Division mConHotWatFlow ;
Modelica.Blocks.Sources.Constant gainHotWat(k=dTHotWatCon_nominal*cp_default)
;
Buildings.Fluid.Sources.FixedBoundary sin2(
redeclare package Medium =
Medium,
nPorts=1);
Buildings.Fluid.Sources.MassFlowSource_T sou1(
redeclare package Medium =
Medium,
nPorts=1,
use_m_flow_in=true,
use_T_in=true) ;
Modelica.Blocks.Math.Gain mPumCoo_flow(k=1/(cp_default*dTCooCon_nominal))
;
Modelica.Blocks.Math.Add QCon_flow(k1=-1) ;
Modelica.Blocks.Math.Add PCooAct ;
Modelica.Blocks.Sources.Constant TChiSup(k=TChiSup_nominal)
;
Buildings.Utilities.Math.SmoothMax smoothMax(
deltaX=(THeaSup_nominal - THeaRet_nominal)*0.005);
Modelica.Blocks.Sources.Constant dTHeaPumConMin(k=4)
;
Modelica.Blocks.Sources.Constant TSetHotWat(k=273.15 + 60)
;
Modelica.Blocks.Math.Add THeaPumSup
;
Modelica.Blocks.Sources.Constant dTChiEvaMin(k=-dTCooEva_nominal)
;
Modelica.Blocks.Math.Add TEvaIn ;
Buildings.Fluid.Delays.DelayFirstOrder del_a(
redeclare final package Medium =
Medium,
nPorts=4,
final m_flow_nominal=(mHeaEva_flow_nominal + mCooCon_flow_nominal + mHotWatEva_flow_nominal)/2,
final allowFlowReversal=true,
tau=600,
final energyDynamics=mixingVolumeEnergyDynamics)
;
Buildings.Fluid.Delays.DelayFirstOrder del_b(
redeclare final package Medium =
Medium,
nPorts=4,
final m_flow_nominal=(mHeaEva_flow_nominal + mCooCon_flow_nominal + mHotWatEva_flow_nominal)/2,
final allowFlowReversal=true,
tau=600,
final energyDynamics=mixingVolumeEnergyDynamics)
;
Modelica.Blocks.Math.Gain gaiLoa[3](
final k={gaiCoo, gaiHea, gaiHotWat})
;
Modelica.Blocks.Math.Gain mPumHotWat_flow(
final k=1/(cp_default*dTHeaEva_nominal))
;
Modelica.Blocks.Math.Gain mPumHea_flow(
final k=1/(cp_default*dTHeaEva_nominal)) ;
Modelica.Blocks.Math.Gain mPumCooEva_flow(
final k=-1/(cp_default*dTCooCon_nominal))
;
initial equation
assert(
abs((cp_default-cp_default_check)/cp_default) < 0.1, "Wrong cp_default value. Check cp_default constant.");
assert(QCoo_flow_nominal < 0,
"Nominal cooling rate must be strictly negative. Obtained QCoo_flow_nominal = "
+
String(QCoo_flow_nominal));
assert(QHea_flow_nominal > 0,
"Nominal heating rate must be strictly positive. Obtained QHea_flow_nominal = "
+
String(QHea_flow_nominal));
assert(QHotWat_flow_nominal > 0,
"Nominal hot water heating rate must be strictly positive. Obtained QHotWat_flow_nominal = "
+
String(QHotWat_flow_nominal));
equation
connect(pumHea.port_b, heaPum.port_a2);
connect(dTHeaAct.u1, TSupHeaSet.TSup);
connect(TSupHeaSet.TRet, dTHeaAct.u2);
connect(mConFlow.u1, deMul.y2[1]);
connect(gainH.y, mConFlow.u2);
connect(mConFlow.y, sou.m_flow_in);
connect(sou.ports[1], heaPum.port_a1);
connect(heaPum.port_b1, sin1.ports[1]);
connect(sou.T_in, TSupHeaSet.TRet);
connect(QEva_flow.u1, deMul.y2[1]);
connect(QEva_flow.u2, heaPum.P);
connect(PHeaAct.y, PHea);
connect(PHeaAct.u1, pumHea.P);
connect(PHeaAct.u2, heaPum.P);
connect(QEvaHotWat_flow.u2, heaPumHotWat.P);
connect(PHotWatAct.u2, heaPumHotWat.P);
connect(PHotWatAct.u1, pumHotWat.P);
connect(heaPumHotWat.port_b1, sinHotWat.ports[1]);
connect(souHotWat.ports[1], heaPumHotWat.port_a1);
connect(mConHotWatFlow.y, souHotWat.m_flow_in);
connect(gainHotWat.y, mConHotWatFlow.u2);
connect(QEvaHotWat_flow.u1, deMul.y3[1]);
connect(PHotWatAct.y, PHotWat);
connect(pumHotWat.port_b, heaPumHotWat.port_a2);
connect(mConHotWatFlow.u1, deMul.y3[1]);
connect(chi.port_b2, sin2.ports[1]);
connect(chi.port_a2, sou1.ports[1]);
connect(mPumCoo_flow.y, pumChi.m_flow_in);
connect(mPumCoo_flow.u, QCon_flow.y);
connect(pumChi.port_b, chi.port_a1);
connect(QCon_flow.u1, deMul.y1[1]);
connect(QCon_flow.u2, chi.P);
connect(PCooAct.y, PCoo);
connect(PCooAct.u1, pumChi.P);
connect(PCooAct.u2, chi.P);
connect(TChiSup.y, chi.TSet);
connect(dTHeaAct.y, smoothMax.u1);
connect(dTHeaPumConMin.y, smoothMax.u2);
connect(TSetHotWat.y, heaPumHotWat.TSet);
connect(gainH.u, smoothMax.y);
connect(THeaPumSup.u1, TSupHeaSet.TRet);
connect(THeaPumSup.u2, smoothMax.y);
connect(THeaPumSup.y, heaPum.TSet);
connect(TChiSup.y, TEvaIn.u1);
connect(dTChiEvaMin.y, TEvaIn.u2);
connect(TEvaIn.y, sou1.T_in);
connect(del_a.ports[1], port_a);
connect(pumHea.port_a, del_a.ports[2]);
connect(pumHotWat.port_a, del_a.ports[3]);
connect(chi.port_b1, del_a.ports[4]);
connect(heaPum.port_b2, del_b.ports[1]);
connect(heaPumHotWat.port_b2, del_b.ports[2]);
connect(pumChi.port_a, del_b.ports[3]);
connect(port_b, del_b.ports[4]);
connect(weaBus.TDryBul, TSupHeaSet.TOut);
connect(deMul.y2[1], QHea_flow);
connect(deMul.y3[1], QHotWat_flow);
connect(deMul.y1[1], QCoo_flow);
connect(loa.y, gaiLoa.u);
connect(gaiLoa.y, deMul.u);
connect(del_a.heatPort, heatPort_a);
connect(del_b.heatPort, heatPort_b);
connect(QEvaHotWat_flow.y, mPumHotWat_flow.u);
connect(mPumHotWat_flow.y, pumHotWat.m_flow_in);
connect(QEva_flow.y, mPumHea_flow.u);
connect(mPumHea_flow.y, pumHea.m_flow_in);
connect(deMul.y1[1], mPumCooEva_flow.u);
connect(mPumCooEva_flow.y, sou1.m_flow_in);
end HeatingCoolingHotwaterTimeSeries_dT;