Calibrate heat pump model from performance dataΒΆ

This example demonstrates the use of the calibrate module to obtain parameters of the heat pump model. Data is loaded from a performance file generated in the performance data generation example. Once heat pump parameters are identified, the results are verified by running the model in Dymola.

The following script can be found in Buildings/Resources/src/fluid/heatpumps/calibration/Examples/example_calibration.py:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# -*- coding: utf-8 -*-
""" Example calibration of the heat pump model.

This script demonstrates the use of the calibration module to obtain parameters
of the heat pump model. Data is loaded from a performance file generated in
dummy_performance_data.py. Once heat pump parameters are identified, the
results are verified by running the model in Dymola. A modelica record of the
heat pump parameters is generated.

"""
from __future__ import division, print_function, absolute_import

import numpy as np
import os
import sys
import datetime


def main():
    # Add parent directory to system path
    parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.insert(1, parent_dir)
    # Import Heat pump and calibration module
    import PythonModel as hp
    # Change working directory to current directory
    os.chdir(os.path.dirname(__file__))
    # Author info for record generation
    author = 'Mr Modeler'
    # Make and model of the heat pump
    manufacturer = 'SomeManufacturer'
    model = 'ABC060'
    # Set to True if calibrating for cooling mode
    CoolingMode = False
    # File name and table name for manufacturer data in modelica
    tableFileName = 'manufacturerData.txt'
    tableName = 'ManufacturerData'
    # File name for performance data
    performanceData = 'somePerformanceData.txt'

    # Load manufacturer data
    data = hp.calibrate.ManufacturerData(manufacturer, model, CoolingMode)
    with open(performanceData, 'r') as f:
        for line in f:
            dataPoint = line[0:-2].split('\t')
            EWT_Source = float(dataPoint[0])    # Entering water temperature evaporator (K)
            EWT_Load = float(dataPoint[1])      # Entering water temperature condenser (K)
            flowSource = float(dataPoint[2])    # Entering water flow rate evaporator (kg/s)
            flowLoad = float(dataPoint[3])      # Entering water flow rate condenser (kg/s)
            Capacity = float(dataPoint[4])      # Heat transfer rate on the load side (kW).
            HR = float(dataPoint[5])            # Heat transfer rate on the source side (kW).
            Power = float(dataPoint[6])         # Electrical power input to heat pump (kW)
            # Add data point to Data object
            data.add_data_point(EWT_Source, EWT_Load, flowSource,
                                flowLoad, Capacity, HR, Power)

    # Data points used in calibration
    calData = data.calibration_data_16_points()

    # Initialize the heat pump model
    P_nominal = 17.5e3
    COP_nominal = 4.0
    Q_nominal = P_nominal*COP_nominal

    # -------------------------------------------------------------------------
    # Initialize all models using a value of 0. for all parameters. Parameters
    # will be replaced by guess values at the start of the calibration process.
    # -------------------------------------------------------------------------
    # Compressor model (Scroll)
    com = hp.compressors.ScrollCompressor([0., 0., 0., 0., 0., 0.])
    # Condenser model
    con = hp.heatexchangers.EvaporatorCondenser([0.])
    # Evaporator model
    eva = hp.heatexchangers.EvaporatorCondenser([0.])
    # Refrigerant model
    ref = hp.refrigerants.R410A()
    # Fluid model on condenser side
    fluCon = hp.fluids.ConstantPropertyWater()
    # Fluid model on evaporator side
    fluEva = hp.fluids.ConstantPropertyWater()
    # Heat pump model
    heaPum = hp.heatpumps.SingleStageHeatPump(com, con, eva, ref, fluCon,
                                              fluEva, Q_nominal, P_nominal,
                                              CoolingMode)

    # Lauch the calibration of the heat pump model.
    optPar, optRes, gueRes = hp.calibrate.calibrate_model(heaPum, calData,
                                                          data, plot=True)

    # Write the results into a record for use in Modelica
    write_record_scroll(author, manufacturer, model, CoolingMode,
                        'R410A', Q_nominal, COP_nominal,
                        optPar)

    # -------------------------------------------------------------------------
    # Calculate heat pump performance for full dataset in Dymola using the
    # calibrated parameters.
    # -------------------------------------------------------------------------
    dymRes = hp.calibrate.simulate_in_dymola(heaPum, data, tableName,
                                             tableFileName)
    SSE = hp.calibrate.compare_data_sets(dymRes, data, plot=True,
                                         fname=data.name + '_dymola')
    print('----------------------------------------------------------------\n')
    print('Sum of square errors (dymola) : ' + str(SSE) + ' \n')
    print('----------------------------------------------------------------\n')

    # Compare the results of the Python code with the results from Dymola.
    SSE = hp.calibrate.compare_data_sets(dymRes, optRes, plot=True,
                                         fname='modelVerification')
    return optRes, dymRes


def write_record_scroll(author, manufacturer, model, CoolingMode,
                        refrigerant, Q_nominal, COP_nominal,
                        optPar):
    # Evaluate current date
    date = str(datetime.date.today())

    # Extract heat pump parameters from optimized results
    volRat = optPar[0]     # Built-in volume ratio (-)
    v_flow = optPar[1]     # Volume flow rate at suction (m3/s)
    leaCoe = optPar[2]     # Leakage coefficient (kg/s)
    etaEle = optPar[3]     # Electro-mechanical efficiency (-)
    PLos = optPar[4]       # Constant part of the power losses (W)
    dTSup = optPar[5]      # Amplitude of superheating (K)
    UACon = optPar[6]      # Thermal conductance of the condenser (W/K)
    UAEva = optPar[7]      # Thermal conductance of the evaporator (W/K)

    # Operation mode
    if CoolingMode:
        mode = 'Cooling'
    else:
        mode = 'Heating'

    # Build string for nominal capacity. If less than 10kW, the nominal
    # capacity is printed with the first decimal (ex. 9.1kW -> 9_1kW)
    # otherwise the capacity is rounded (ex. 10.6kW - > 11kW).
    if Q_nominal < 10.0e3:
        Q_str = (str(int(Q_nominal/1.0e3)) +
                 '_' +
                 str(int(round(10.*(Q_nominal-np.floor(Q_nominal))/1.0e3))))
    else:
        Q_str = str(int(Q_nominal/1.0e3))

    # Build the full name of the record, including the manufacturer, model,
    # nominal capacity, nominal COP (keeping 2 decimals) and refrigerant type.
    name = '_'.join([manufacturer,
                     model,
                     Q_str + 'kW',
                     str(int(COP_nominal)),
                     str(int(round(100.*(COP_nominal
                                         -np.floor(COP_nominal))))) + 'COP',
                     refrigerant])
    path = name + '.mo'

    # Print the record in Modelica format.
    with open(path, 'w') as f:
        f.write('within Buildings.Fluid.HeatPumps.Data.ScrollWaterToWater.'
                + mode + ';\n')
        f.write('record ' + name + ' =\n')
        f.write('  Buildings.Fluid.HeatPumps.Data.ScrollWaterToWater.Generic ('
                + '\n')
        f.write('    volRat = ' + str(volRat) + ',\n')
        f.write('    V_flow_nominal = ' + str(v_flow) + ',\n')
        f.write('    leaCoe = ' + str(leaCoe) + ',\n')
        f.write('    etaEle = ' + str(etaEle) + ',\n')
        f.write('    PLos = ' + str(PLos) + ',\n')
        f.write('    dTSup = ' + str(dTSup) + ',\n')
        f.write('    UACon = ' + str(UACon) + ',\n')
        f.write('    UAEva = ' + str(UAEva) + ')\n\n')

        f.write('  annotation (\n')
        f.write('    defaultComponentPrefixes = "parameter",\n')
        f.write('    defaultComponentName="datHeaPum",\n')
        f.write('    preferredView="info",\n')
        f.write('  Documentation(info="<html>\n')
        f.write('<p>\n')
        f.write('Generated by ' + author + ' on ' + date + '.\n')
        f.write('</p>\n')
        f.write('</html>"));')
    return

# Main function
if __name__ == "__main__":
    main()

The scripts generates the following figures:

_images/calibration_guess_parameters.png

Fig. 1 Comparison between the performance data and the model predicted (from Python) heating capacities and power input using the initial guess parameters.

_images/calibration_final_parameters.png

Fig. 2 Comparison between the performance data and the model predicted (from Dymola) heating capacities and power input using the calibrated parameters.

The following record is generated for use in Modelica:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
within Buildings.Fluid.HeatPumps.Data.ScrollWaterToWater.Heating;
record SomeManufacturer_ABC060_70kW_4_0COP_R410A =
  Buildings.Fluid.HeatPumps.Data.ScrollWaterToWater.Generic (
    volRat = 2.36185869323,
    V_flow_nominal = 0.00287086738316,
    leaCoe = 0.00408074950474,
    etaEle = 0.922319423243,
    PLos = 398.665383784,
    dTSup = 6.49606895698,
    UACon = 7014.54967992,
    UAEva = 49135.9514647)

  annotation (
    defaultComponentPrefixes = "parameter",
    defaultComponentName="datHeaPum",
    preferredView="info",
  Documentation(info="<html>
<p>
Generated by Mr Modeler on 2017-01-26.
</p>
</html>"));