Extending the performance map

To complete the performance map, Costa relies on correction curves, following the methodology described by [Strugala]. Here’s a TLDR:

  1. Select the performance map entries for each quantity to add.

  2. Multiply the original performance map by a correction factor that depends on the entry value, for each selected entry.

Thus before filling the performance map, new entries and the corrections to use have to be specified, along with some other things. The following sections explain how to do so, and the last one shows how to finally fill the performance map.

Specify the operating mode

The corrections and the variables involved in the performance map depend on the operating mode (heating or cooling), which must therefore be specified before filling. (Not doing so will raise an exception.)

This can be done simply by assigning the string 'heating' or 'cooling' to the attribute mode.

Warning

When using Permap attributes or methods, don’t forget to use the pm prefix !

Set the performance map entries

The entries are stored in the entries attribute, in the form of a dict with input quantities as keys and entries as values. Valid keys for referencing input quantities are found in the index names tables, and the selected entries must be specified in the form of a list or a NumPy ndarray. For example, to set frequency entries 0.1, 0.5 and 0.9 for a performance map permap, you would do

>>> permap.pm.entries['freq'] = [0.1, 0.5, 0.9]

Manage the correction functions

Correction functions are the backbone of this performance map completion methodology. Some default corrections are available for you to use, but you can also use your own. Correction functions are stored in a dictionary like the entries, in the corrections attribute. However since corrections depends both on the input and output quantities of the performance map, the dictionary is more nested; it has the following form:

{
   'AFR': {
      'power': <function>,
      'capacity': <function>,
      'COP': <function>,
   },
   'freq': {
      'power': <function>,
      'capacity': <function>,
      'COP': <function>,
   },
   ...
}

For example, to get the power correction as a function of frequency, you could use permap.pm.corrections[‘freq’][‘power’] (see examples in the Permap docstring). There is also a dedicated getter method, get_correction, that would return the same correction with permap.pm.get_correction(‘freq’, ‘power’). It also allows to get all corrections associated with a specific input by omitting the second argument.

Use default corrections

Everything related to the default corrections is contained in the defaults module. For getting a specific correction, there is the function default_correction. As with the Permap.get_correction method, it returns a callable that can easily be visualized:

import numpy as np
import matplotlib.pyplot as plt
from costa.defaults import default_correction

corr = default_correction('heating', 'freq', 'power')
freq = np.linspace(0, 2, 100)
plt.plot(freq, corr(freq))
plt.xlabel("Normalized compressor frequency")
plt.ylabel("Heat pump power correction")
../_images/extend-1.png

You can also get all the corrections associated with a certain mode arranged in a dict structure as shown above, using the function build_default_corrections.

Note

As of today, there are no regressions for the air flow rate (AFR) or the indoor wet-bulb temperature (Twbr); all corrections associated with these quantities are equal to 1.

Add custom corrections

Corrections can easily be edited or added through the corrections attribute, but you may want to use the set_correction method instead. Indeed, it performs some security checks before updating the corrections dictionary, and it can also return a new instance instead of modifying the performance table in-place (see inplace argument.).

There is also the set_corrections method, which allows you to specify all corrections associated with an input quantity. In addition, it automatically adds correction functions that can be deduced from the others. Indeed, since the output quantities are not independent (\(\text{COP} = \dot{Q} / P\)) you can give only two corrections out of the three and the last one will be automatically added. For example, if you have a COP and a power correction named respectively cop and power, you can do

new_corrections = {'COP': cop, 'power': power}
new_permap = permap.pm.set_corrections('freq', new_corrections)

and new_permap.pm.corrections[‘freq’] should have an entry 'capacity'.

Adjust the initial normalized values

By normalizing everything w.r.t. rated values, the correction functions must take the value 1 when the normalized input is 1 (i.e. for any correction function \(\varphi\), \(\varphi(1) = 1\)). But performance tables are not always provided at rated values. For example, it may happen that a spec sheet provide performance values at the maximum frequency \(f_\text{max}\), while the rated frequency \(f_\text{r}\) is only half of \(f_\text{max}\). In that case, the normalized frequency \(\nu = f / f_\text{r}\) would range from 0 to 2, and the initial performance data would be given at \(\nu = 2\). Since \(\varphi(2) \neq 1\), one cannot just multiply the performance map by \(\varphi(\nu)\) to extend it; we have to make sure that values are preserved at \(\nu = 2\). Thus, we must adjust the correction and instead multiply by \(\varphi(\nu) / \varphi(2)\).

More generally, if the performance data is provided at a certain condition \(v^*\) different from the rated value \(v_\text{r}\), the correction \(\varphi(v)\) must be adjusted by dividing it by \(\varphi(v^*/v_\text{r})\). Therefore the ratio \(v^*/v_\text{r}\), called the initial normalized value, must be explicitly specified for each normalized quantity to extend the performance map correctly. This can be done using the attribute initial_norm_values, where values are once again stored in a dictionary whose keys are the normalized quantities in question. So for example, if performance is provided at a frequency of 120 Hz but the rated frequency is 75 Hz, you would have to set

>>> permap.pm.initial_norm_values['freq'] = 120 / 75

Note

By default, i.e. if you don’t make any dict assignment, all those values are set to 1. This means that, unless specified otherwise, it is assumed that initial performance data is provided at rated values.

Fill the performance map

Once you have set the operating mode, the performance map entries, the correction functions and the initial normalized values, you can fill the performance map. To do so, simply

>>> permap_full = permap.pm.fill()

Note that you can combine the fill operation with the normalize operation (see normalizing data), by providing rated values to the fill method.

References

Strugala

Strugala, G. (2020). Experimental testing and modelling of variable capacity air-to-air heat pumps (Master’s thesis, Polytechnique Montréal). Retrieved from https://publications.polymtl.ca/5285/