modelicaopenmodelicadymola

Modelica MoSDH-Library HeatPump has supplyPortSource.m_flow but no equivalent returnPortSource.m_flow. Why could that be?


I expanded a model with a second heatPump. For this HeatPump I used fluidSourceHot as a supplySource and fluidSourceCold as returnSource.

The HeatPump in Question is the one on the left side

When simulating the model, I receive unrealistic values for my return temperatures. Upon further investigation i figured out that the HeatPump.supplyPortSource.m_flow is constantly around 50kg/s while the HeatPump.returnPortSource.m_flow is constantly around zero, thus acumulating enthalpy in the HeatPump and returning shyrocketing temperatures.

Has anyone ever experienced something like this?

The HeatPumps are both defined equally, and only one has this error.

The program I use is Dymola 2023.

I already tried adding another shunt between the fluidSources and the HeatPump, without any changes.

You can find the MoSDH Library on GitHub, here: https://github.com/MoSDH/MoSDH

model Modell_13_02 "Geothermal supported heating system example"
 import modes = MoSDH.Utilities.Types.OperationModes;
 import buoyancy = MoSDH.Components.Storage.StratifiedTank.BaseClasses.BuoyancyModels;
 parameter Modelica.Units.SI.Power BHE_PthermalSpec=30;
 parameter Modelica.Units.SI.Temperature TsupplyRef=323.15;
 parameter Modelica.Units.SI.Temperature TregenerationRef=278.15;
 parameter Modelica.Units.SI.Temperature TreturnRef=298.15;
 parameter Modelica.Units.SI.Temperature TboreholeMin=273.15 "Minimum allowed entrance temperature of boreholes";
 parameter Modelica.Units.SI.VolumeFlowRate BHE_volFlowSpec=0.0005 "Specific flow rate through BHEs";
 modes heatPumpMode "Heat pump operation mode";
 modes boilerMode "Supply from buffer mode";
 modes regenerationHeatPumpMode "regeneration Heat Pump mode";
 Modelica.Units.SI.Power HP_PthermalRef(displayUnit="MW") "Reference thermal power of heat pump";
 Modelica.Units.SI.Power regHP_PthermalRef(displayUnit="MW") "Reference thermal power of regeneration heat pump";
 Modelica.Units.SI.VolumeFlowRate EB_volFlowRef "Boiler flow rate";
 Modelica.Units.SI.Temperature EB_Tref "Boiler supply temperature";
 MoSDH.Components.Storage.StratifiedTank.TTES buffer(
    storageVolume=0.01*boreholes.nBHEs*boreholes.BHElength,
    storageHeight=10,
    buoyancyMode=Components.Storage.StratifiedTank.BaseClasses.BuoyancyModels.buildings,
    nLayers=10,
    Tinitial=linspace(
        TreturnRef,
        TsupplyRef,
        buffer.nLayers))                                     annotation(Placement(transformation(extent={{-15,-1},{15,59}})));
 MoSDH.Components.Weather.WeatherData weather(weatherData=Modelica.Utilities.Files.loadResource("modelica://MoSDH/Data/Weather/DWD/TRY2017_Darmstadt.txt")) annotation(Placement(transformation(extent={{-20,-66},{20,-26}})));
 MoSDH.Components.Loads.HeatDemand load(
    Qthermal(displayUnit="J"),
    tau=3600,
    medium=buffer.medium,
    loadData=Modelica.Utilities.Files.loadResource("modelica://MoSDH/Data/HeatDemand/Darmstadt_TRY2015_5GWh.txt"),
    powerUnitData(displayUnit="W") = 1000,
    TreturnGrid=TreturnRef)
                          annotation(Placement(transformation(extent={{85,9},{125,49}})));
  Components.Sources.Electric.ElectricHeatingRod elBoiler(
    tau=3600,
    PelMax=2000000,
    mode=MoSDH.Utilities.Types.ControlTypes.RefFlowRefTemp,
    on=true,
    Tref(displayUnit="degC") = EB_Tref,
    volFlowRef=EB_volFlowRef) annotation (Placement(transformation(extent={{25,9},{65,49}})));
 MoSDH.Components.Storage.BoreholeStorage.BTES boreholes(
    nBHEs=200,
    BHElength=100,
    nBHEsInSeries=2,
    redeclare replaceable parameter Modelica.Thermal.FluidHeatFlow.Media.Gylcol20_20degC medium,
    BHEstart=2,
    BHEspacing=8,
    dZminMax(displayUnit=""),
    relativeModelDepth=1.3,
    nAdditionalElementsR=5,
    volFlowRef=-heatPump.volFlowSource)
                                      annotation(Placement(transformation(
  origin={-134,-29},
  extent={{-20,-20},{20,20}})));
 MoSDH.Components.Sources.Electric.HeatPump heatPump(
    tau=3600,
    redeclare replaceable parameter Modelica.Thermal.FluidHeatFlow.Media.Gylcol20_20degC mediumSource,
    setAbsoluteSourcePressure=true,
    redeclare replaceable parameter Modelica.Thermal.FluidHeatFlow.Media.Water mediumLoad,
    setAbsoluteLoadPressure=false,
    TminLoad=323.15,
    MiminumShift=20,
    mode=MoSDH.Utilities.Types.ControlTypesHeatPump.SourceFlowRate,
    on=heatPumpMode == modes.FullLoad,
    Pref=HP_PthermalRef,
    Tref=TsupplyRef + 3,
    volFlowRef=boreholes.nBHEs*BHE_volFlowSpec/boreholes.nBHEsInSeries,
    DeltaTref=5)
               annotation(Placement(transformation(
  origin={-60,29},
  extent={{-20,-20},{20,20}})));
 MoSDH.Components.Distribution.HydraulicShunt hydraulicShunt(
    redeclare replaceable parameter Modelica.Thermal.FluidHeatFlow.Media.Gylcol20_20degC medium,
    setAbsolutePressure=false,
    tau=3600)
            annotation(Placement(transformation(
  origin={-95,29},
  extent={{-10,-10},{10,10}})));
 MoSDH.Components.Distribution.threeWayValveMix valve(tau=3600) annotation(Placement(transformation(extent={{70,29},{80,39}})));
 MoSDH.Components.Distribution.threeWayValveMix valve1(tau=3600) annotation(Placement(transformation(extent={{70,29},{80,19}})));
 MoSDH.Components.Distribution.threeWayValveMix valve5(tau=3600) annotation(Placement(transformation(extent={{-30,49},{-20,59}})));
 MoSDH.Components.Distribution.threeWayValveMix valve6(tau=3600) annotation(Placement(transformation(extent={{-30,9},{-20,-1}})));
 MoSDH.Components.Distribution.threeWayValveMix valve2(tau=3600) annotation(Placement(transformation(extent={{20,9},{30,-1}})));
 MoSDH.Components.Distribution.threeWayValveMix valve3(tau=3600) annotation(Placement(transformation(extent={{20,49},{30,59}})));
  MoSDH.Components.Distribution.Pump pump(volFlowRef=min(heatPump.volFlowLoad, load.volFlow - elBoiler.volFlow)) annotation (Placement(transformation(origin={0,64}, extent={{-5,-5},{5,5}})));
  MoSDH.Components.Distribution.Pump pump1(volFlowRef=min(heatPump.volFlowLoad, load.volFlow - elBoiler.volFlow)) annotation (Placement(transformation(origin={0,-11}, extent={{5,-5},{-5,5}})));
  Components.Sources.Electric.HeatPump regenerationHeatPump(
    tau=3600,
    redeclare Modelica.Thermal.FluidHeatFlow.Media.Water mediumSource,
    setAbsoluteSourcePressure=true,
    mediumLoad=boreholes.medium,
    TminSource=243.15,
    TminLoad=273.15,
    constrainPower=false,
    mode=MoSDH.Utilities.Types.ControlTypesHeatPump.SourceFlowRate,
    on=regenerationHeatPumpMode == modes.FullLoad,
    Pref=regHP_PthermalRef,
    setAbsoluteLoadPressure=false,
    Tref=TsupplyRef + 3,
    volFlowRef=boreholes.nBHEs*BHE_volFlowSpec/boreholes.nBHEsInSeries,
    DeltaTref=5) annotation (Placement(transformation(extent={{-226,-8},{-186,32}})));
  Components.Utilities.FluidHeatFlow.fluidSourceHot fluidSourceHot(medium=regenerationHeatPump.mediumSource,
                                                                   Tsource=weather.Tambient) annotation (Placement(transformation(extent={{-236,12},{-246,22}})));
  Components.Distribution.HydraulicShunt shunt(medium=boreholes.medium, setAbsolutePressure=false,
    tau=3600)                                                                                      annotation (Placement(transformation(extent={{-170,2},{-150,22}})));
  Components.Utilities.FluidHeatFlow.fluidSourceCold fluidSourceCold(medium=regenerationHeatPump.mediumSource, Tsource=weather.Tambient - 5)
                                                                     annotation (Placement(transformation(extent={{-236,-12},{-246,-2}})));
initial algorithm 
  // determine the initial heat pump operation mode
    if max(buffer.Tlayers) < TsupplyRef and time>3600 then
      heatPumpMode := modes.FullLoad;
    else
      heatPumpMode := modes.Idle;
    end if;
  // determine the initial gas boiler operation mode
    if min(buffer.Tlayers[buffer.nLayers - 1:buffer.nLayers]) > TsupplyRef + 1 then
      boilerMode := modes.Idle;
    elseif min(buffer.Tlayers[buffer.nLayers - 1:buffer.nLayers]) > TsupplyRef - 8 then
      heatPumpMode := modes.PartLoad;
    else
      heatPumpMode := modes.FullLoad;
    end if;
  // determine the initial regeneration heat pump operation mode
    if weather.Tambient < TregenerationRef and time>3600 then
      regenerationHeatPumpMode := modes.FullLoad;
    else
      regenerationHeatPumpMode := modes.FullLoad;
    end if;
equation 
  //Switch heat pump on/off
algorithm 
    when min(buffer.Tlayers) > TsupplyRef - 5 or min(boreholes.TboreholeWall) < TboreholeMin then
      heatPumpMode := modes.Idle;
    elsewhen max(buffer.Tlayers) < TsupplyRef and time>3600 and min(boreholes.TboreholeWall) > TboreholeMin + 2 then
      heatPumpMode := modes.FullLoad;
    end when;
  //siwtch between boiler full load, part load and idle model
    when min(buffer.Tlayers[buffer.nLayers - 1:buffer.nLayers]) > TsupplyRef + 1 then
      boilerMode := modes.Idle;
    elsewhen min(buffer.Tlayers[buffer.nLayers - 1:buffer.nLayers]) < TsupplyRef - 3 then
      boilerMode := modes.PartLoad;
    elsewhen min(buffer.Tlayers[buffer.nLayers - 1:buffer.nLayers]) < TsupplyRef - 16 then
      boilerMode := modes.FullLoad;
    elsewhen min(buffer.Tlayers[buffer.nLayers - 1:buffer.nLayers]) > TsupplyRef - 8 then
      boilerMode := modes.PartLoad;
    end when;
  //switch regeneration on/off
    when weather.Tambient>TregenerationRef and time>3600 then
      regenerationHeatPumpMode := modes.FullLoad;
    elsewhen weather.Tambient<TregenerationRef and time>3600 then
      regenerationHeatPumpMode := modes.FullLoad;
    end when;

equation 
  // Component behaviour
  HP_PthermalRef = boreholes.nBHEs * boreholes.BHElength * BHE_PthermalSpec * min(1, max(0.25, (min(boreholes.TboreholeWall) - TboreholeMin) / 2));
  regHP_PthermalRef = 0.01 * boreholes.nBHEs * boreholes.BHElength * BHE_PthermalSpec * min(1, max(0.25, (min(boreholes.TboreholeWall) - TboreholeMin) / 2));
  if boilerMode == modes.FullLoad then
    EB_volFlowRef = load.volFlow;
    EB_Tref = TsupplyRef;
  elseif boilerMode == modes.PartLoad then
    EB_volFlowRef = load.volFlow * (TsupplyRef - buffer.Tlayers[10]) / (363.15 - TsupplyRef);
    EB_Tref = 363.15;
  else
    EB_volFlowRef = 0;
    EB_Tref = 363.15;
  end if;
  connect(hydraulicShunt.loadSupply,heatPump.supplyPortSource) annotation(Line(
   points={{-85,34},{-80,34}},
   color={255,0,0},
   thickness=1));
  connect(heatPump.returnPortSource,hydraulicShunt.loadReturn) annotation(Line(
   points={{-80,24},{-85.33,24}},
   color={0,0,255},
   thickness=1));
  connect(elBoiler.supplyPort, valve.flowPort_b) annotation (Line(
      points={{64.67,34},{70,34}},
      color={255,0,0},
      thickness=1));
  connect(elBoiler.returnPort, valve1.flowPort_b) annotation (Line(
      points={{64.67,24},{70,24}},
      color={0,0,255},
      thickness=1));
  connect(load.supplyPort,valve.flowPort_a) annotation(Line(
   points={{85,34},{79.67,34}},
   color={255,0,0},
   thickness=1));
  connect(load.returnPort,valve1.flowPort_a) annotation(Line(
   points={{85,24},{79.67,24}},
   color={0,0,255},
   thickness=1));
  connect(load.weatherPort,weather.weatherPort) annotation(Line(
   points={{105,9.33},{104,9.33},{104,-20},{0,-20},{0,-26}},
   color={0,176,80}));
  connect(weather.weatherPort,buffer.weatherPort) annotation(Line(
   points={{0,-26},{0,-0.67}},
   color={0,176,80}));
  connect(pump1.flowPort_b,valve6.flowPort_c) annotation(Line(
   points={{-4.67,-11},{-25,-11},{-25,-1}},
   color={0,0,255},
   thickness=1));
  connect(pump.flowPort_a,valve5.flowPort_c) annotation(Line(
   points={{-5,64},{-25,64},{-25,59}},
   color={255,0,0},
   thickness=1));
  connect(pump.flowPort_b,valve3.flowPort_c) annotation(Line(
   points={{4.67,64},{25,64},{25,59}},
   color={255,0,0},
   thickness=1));
  connect(buffer.sourceIn,valve5.flowPort_a) annotation(Line(
   points={{-15,54},{-20.33,54}},
   color={255,0,0},
   thickness=1));
  connect(buffer.sourceOut,valve6.flowPort_a) annotation(Line(
   points={{-15,4},{-20.33,4}},
   color={0,0,255},
   thickness=1));
  connect(buffer.loadOut,valve3.flowPort_b) annotation(Line(
   points={{14.67,54},{20,54}},
   color={255,0,0},
   thickness=1));
  connect(buffer.loadIn,valve2.flowPort_b) annotation(Line(
   points={{14.67,4},{20,4}},
   color={0,0,255},
   thickness=1));
  connect(valve2.flowPort_a,valve1.flowPort_c) annotation(Line(
   points={{29.67,4},{75,4},{75,19}},
   color={0,0,255},
   thickness=1));
  connect(valve3.flowPort_a,valve.flowPort_c) annotation(Line(
   points={{29.67,54},{75,54},{75,39}},
   color={255,0,0},
   thickness=1));
  connect(pump1.flowPort_a,valve2.flowPort_c) annotation(Line(
   points={{5,-11},{25,-11},{25,-1}},
   color={0,0,255},
   thickness=1));
  connect(valve6.flowPort_b,heatPump.returnPortLoad) annotation(Line(
   points={{-30,4},{-35,4},{-35,24},{-40.33,24}},
   color={0,0,255},
   thickness=1));
  connect(valve5.flowPort_b,heatPump.supplyPortLoad) annotation(Line(
   points={{-30,54},{-35,54},{-35,34},{-40.33,34}},
   color={255,0,0},
   thickness=1));
  connect(weather.weatherPort, boreholes.weatherPort) annotation (Line(points={{0,-26},{0,-20},{-52,-20},{-52,-54},{-134,-54},{-134,-48.67}},      color={0,176,80}));
  connect(regenerationHeatPump.supplyPortLoad, shunt.sourceSupply) annotation (Line(
      points={{-186.33,17},{-170,17}},
      color={255,0,0},
      thickness=1));
  connect(regenerationHeatPump.returnPortLoad, shunt.sourceReturn) annotation (Line(
      points={{-186.33,7},{-170,7}},
      color={0,0,255},
      thickness=1));
  connect(shunt.loadReturn, hydraulicShunt.sourceReturn) annotation (Line(
      points={{-150.33,7},{-150.33,6},{-110,6},{-110,24},{-105,24}},
      color={0,0,255},
      thickness=1));
  connect(regenerationHeatPump.supplyPortSource, fluidSourceHot.fluidPort) annotation (Line(
      points={{-226,17},{-236,17}},
      color={255,0,0},
      thickness=1));
  connect(regenerationHeatPump.returnPortSource, fluidSourceCold.fluidPort) annotation (Line(
      points={{-226,7},{-226,6},{-236,6},{-236,-7}},
      color={0,0,255},
      thickness=1));
  connect(boreholes.supplyPort, hydraulicShunt.sourceSupply) annotation (Line(
      points={{-144,-9},{-144,34},{-105,34}},
      color={255,0,0},
      thickness=1));
  connect(shunt.loadSupply, boreholes.returnPort) annotation (Line(
      points={{-150,17},{-150,16},{-124,16},{-124,-9}},
      color={255,0,0},
      thickness=1));
 annotation (
  __OpenModelica_commandLineOptions="--matchingAlgorithm=PFPlusExt --indexReductionMethod=dynamicStateSelection -d=initialization,evaluateAllParameters,NLSanalyticJacobian -d=nonewInst -d=nonewInst",
  __OpenModelica_simulationFlags(
   lv="LOG_STATS",
   s="cvode"),
  __esi_viewinfo={
     ModelInfo(
      defaultViewSettings=ViewSettings(showGrid=2))},
  Diagram(coordinateSystem(extent={{-260,-80},{140,80}})),
  Documentation(info= "<html><head></head><body><h3 style=\"font-family: 'MS Shell Dlg 2';\">Example model for a geothermal heating system:</h3><h2><ul><li style=\"font-family: 'MS Shell Dlg 2'; font-size: 12px; font-weight: normal;\">A&nbsp;<a href=\"modelica://MoSDH.Components.Storage.BoreholeStorage.BTES\">borehole heat exchanger array</a>&nbsp;supplies heat to the&nbsp;<a href=\"modelica://MoSDH.Components.Storage.StratifiedTank.TTES\">buffer storage</a>&nbsp;via a&nbsp;<a href=\"modelica://MoSDH.Components.Sources.Electric.HeatPump\">heat pump</a>.&nbsp;</li><li style=\"font-family: 'MS Shell Dlg 2'; font-size: 12px; font-weight: normal;\">A <a href=\"modelica://MoSDH.Components.Distribution.HydraulicShunt\">shunt</a> is used for hydraulic decoupling of the BHEs and the heat pumps, since both have a circulation pump integrated into the same hydraulic circuit.</li><li style=\"font-family: 'MS Shell Dlg 2'; font-size: 12px; font-weight: normal;\">The&nbsp;<a href=\"modelica://MoSDH.Components.Loads.HeatDemand\">heat load</a>&nbsp;is suplied from the buffer storage and a&nbsp;<a href=\"modelica://MoSDH.Components.Sources.Fossil,BasBoiler\">gas boiler</a>&nbsp;is used as additional heat source.&nbsp;</li><li style=\"font-family: 'MS Shell Dlg 2'; font-size: 12px; font-weight: normal;\">The&nbsp;<a href=\"modelica://MoSDH.Components.Weather.WeatherData\">weather</a>&nbsp;component is required to giv the ambient temperature for calculation of the buffer's thermal losses and the day of the year for the heat load table.</li><li style=\"font-family: 'MS Shell Dlg 2'; font-size: 12px; font-weight: normal;\">Pumps are used to bypass the buffer, if heat can be supplied directly from the heat pump to the load.</li><li style=\"font-family: 'MS Shell Dlg 2'; font-size: 12px; font-weight: normal;\">The system control strategy is defined on the top level of the model.</li><li style=\"font-family: 'MS Shell Dlg 2'; font-size: 12px; font-weight: normal;\">Parameters&nbsp;<b>TsupplyRef</b>&nbsp;and&nbsp;<b>TreturnRef</b>&nbsp;are used to define the operating temperatures of the system.</li><li style=\"font-family: 'MS Shell Dlg 2'; font-size: 12px; font-weight: normal;\">The gas boiler is operated in mode&nbsp;<b>RefTempFefFlow</b>, for which the supply temperture is deined by the control variable&nbsp;<b>boiler.Tref</b>&nbsp;and the volume flow rate by the variable&nbsp;<b>boiler.volFlowRef</b>.&nbsp;</li><li style=\"font-family: 'MS Shell Dlg 2'; font-size: 12px; font-weight: normal;\">The variable&nbsp;<b>boilerMode</b>&nbsp;of type&nbsp;<a href=\"modelica://MoSDH.Utilities.Types.OperationModes\">OperationModes</a>&nbsp;is used &nbsp;to define the behavior of the gas boiler. Three modes are implemented:</li><ul style=\"font-family: 'MS Shell Dlg 2'; font-size: 12px;\"><li><span style=\"font-weight: normal;\">Idle: If the buffer has the required temperature, the boiler is turned off (</span>boiler.<b>volFlowRef</b><span style=\"font-weight: normal;\">=0)</span></li><li style=\"font-weight: normal;\">PartLoad: If the buffer temperature falls below the required temperature, the gas boiler is used to shift the temperature of the stored heat by mixing.</li><li style=\"font-weight: normal;\">FullLoad: If the buffer temperature falls below the deinfed maximum, all of the heat demand is covered by the boiler.</li></ul><li style=\"font-family: 'MS Shell Dlg 2'; font-size: 12px;\"><span style=\"font-weight: normal;\">The heat pump is operated in </span>mode<span style=\"font-weight: normal;\"> SourceFlowRate, fow which the source side volume flow rate (</span>heatPump.volFlowRef<span style=\"font-weight: normal;\">), the load side supply temperature (</span>heatPump.Tref<span style=\"font-weight: normal;\">) and the load thermal power (</span>heatPump.Tref<span style=\"font-weight: normal;\">) have to be defined.</span></li><li style=\"font-family: 'MS Shell Dlg 2'; font-size: 12px;\"><span style=\"font-weight: normal;\">The variable heatPumpMode is used to turn the heat pump off, if the buffer storage is filled or the borehole wall temperature falls below parameter </span>TboreholeMin.</li><li style=\"font-family: 'MS Shell Dlg 2'; font-size: 12px;\"><span style=\"font-weight: normal;\">The heating power of the heat pump is defined in relation to the total borehole length by parameter </span>BHE_PthermalSpec<span style=\"font-weight: normal;\">&nbsp;and modulated to a minimum of 25 % if the borehole temperatures gets close to </span>TboreholeMin<span style=\"font-weight: normal;\">.</span></li><li style=\"font-family: 'MS Shell Dlg 2'; font-size: 12px;\"><span style=\"font-weight: normal;\">The borehole field volume flow rate </span>boreholes.volFlowRef<span style=\"font-weight: normal;\"> is set equal to the source side volume flow rate of the heat pump </span>hp.volFlowSource <span style=\"font-weight: normal;\">(negative -&gt; see pump on the icon of the borehole field).</span></li></ul>
<table border=\"0\" cellspacing=\"0\" cellpadding=\"2\">
  <caption align=\"bottom\"><strong>Fig. 1: </strong>Thermal powers</caption>
  <tbody><tr>
    <td>
      <img src=\"modelica://MoSDH/Utilities/Images/ExampleGeothermalHeating.png\" width=\"700\">
    </td>
  </tr>
</tbody></table>
<table border=\"0\" cellspacing=\"0\" cellpadding=\"2\">
  <caption align=\"bottom\"><strong>Fig. 2: </strong>BHE inlet and outlet temperatures </caption>
  <tbody><tr>
    <td>
      <img src=\"modelica://MoSDH/Utilities/Images/ExampleGeothermalHeatingB.png\" width=\"700\">
    </td>
  </tr>
</tbody></table>
</h2>

</body></html>"),
  experiment(
      StopTime=31536000,
      Interval=3600,
      Tolerance=0.1,
      __Dymola_Algorithm="Dassl"),
    Icon(coordinateSystem(extent={{-260,-80},{140,80}})));
end Modell_13_02;

Solution

  • I didn't fully understand the issue, but to give any help: There is no flow out of regenerationHeatPump as the parameter setAbsoluteSourcePressure is set to true. Therefore, the volume flow is "consumed" internally. Changing this I get an error caused by a division by zero - which I currently don't understand...

    As this was posted in the comments, it actually solved the problem for me, although i don't know what else i changed.