# 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 AixLib/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 AixLib.Fluid.HeatPumps.Data.ScrollWaterToWater.'
                    + mode + ';\n')
            f.write('record ' + name + ' =\n')
            f.write('  AixLib.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:

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

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 AixLib.Fluid.HeatPumps.Data.ScrollWaterToWater.Heating;
    record SomeManufacturer_ABC060_70kW_4_0COP_R410A =
      AixLib.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>"));