Creating EnergyPlus VRV Performance Curves using Python and Scipy

Contents

The long awaited VRV system objects were added to Energyplus in Version 7.0 which adds the ability to simulate this commonly installed HVAC system. The only problem is that there is a distinct lack of performance curves available for common manufacturers. This is especially a problem due to the fact that there are up to a whopping 22 performance curves that can be defined for the system for heating and cooling - and that’s not even counting the terminal units. Not all the curves are required and it depends on the performance data for specific systems.

The Florida Energy Center released a guide entitled “Creating Performance Curves for Variable Refrigerant Flow Heat Pumps in EnergyPlus” which gives an overview of how to convert manufacturer-supplied performance data into the Energyplus objects. I find this guide to be quite short on practical tips of how to do the required regressions. Therefore I thought I would share my workflow that I used which utilized Python and Scipy.

Step 1: Extract and Organize Manufacturer Data

In this example I will be using data from a Daikin VRV system which was sent to me from my local Daikin distributor. The data is provided in a PDF similar and below is an example screenshot from the PDF.

Instead of manually pulling the required information out, I used a free online PDFtoEXCEL converter to create a spreadsheet which is emailed to me with all of the information. I then created a “CellParser.py” processing script which further decomposes the data into a .csv file which can easily be loaded into our next step. The following is a snapshot of what the first ~20 rows of my csv looks like:

"CombPer","Cap","IWB","ODB","TotCap","Power"
130.0,63.7,14.0,10.0,43.0,7.46
130.0,63.7,14.0,12.0,43.0,7.6
130.0,63.7,14.0,14.0,43.0,7.74
130.0,63.7,14.0,16.0,43.0,7.89
130.0,63.7,14.0,18.0,43.0,8.04
130.0,63.7,14.0,20.0,43.0,8.2
130.0,63.7,14.0,21.0,43.0,8.43
130.0,63.7,14.0,23.0,43.0,9.03
130.0,63.7,14.0,25.0,43.0,9.66
130.0,63.7,14.0,27.0,43.0,10.32
130.0,63.7,14.0,29.0,43.0,11.0
130.0,63.7,14.0,31.0,43.0,11.7
130.0,63.7,14.0,33.0,43.0,12.5
130.0,63.7,14.0,35.0,43.0,13.3
130.0,63.7,14.0,37.0,43.0,14.2
130.0,63.7,14.0,39.0,43.0,15.1

Step 2: Generating Coefficients for Performance Curves

Most of the explanation of what each performance curve is and what its used for is in the Florida Energy Center guide so I will just focus on how I used Scipy to estimate the parameters using Least Square Optimization.

The first step is to load the data from the .csv into an array and pass that to a predefined function which will return the parameters. The following example illustrates calculation of the EIRFT and CAPFT performance functions (complete code found in CoolingCurveFitter.py):

#Load TotalData Array from Text file output of CellParser.py
TotalData = []
csvreader = csv.reader(file("RXYQ18Cool.xls.csv"),quoting=csv.QUOTE_NONNUMERIC)
for row in csvreader:
    TotalData.append(row)
for row in TotalData[1:]:
    for item in row[1:]:
        item=float(item)
    for item in row[:0]:
        item=int(item)

#Find Cooling Cooling Capacity Ratio Modifier Function (CAPFT)
#and Energy Input Ratio Modifier Function (EIRFT)
#This script is designed to simplify the process described in:
#https://securedb.fsec.ucf.edu/pub/pub_show_detail?v_pub_id=4588 by neglecting to created a High AND Low
#Performance curves.
RatedCoolingEnergy = 16.2
CAPFT,EIRFT,CAPFTerr,EIRFTerr,IWBmax,IWBmin,ODBmax,ODBmin = FTCurves(TotalData,RatedCoolingEnergy)

The FTCurve function parses the data passed to it, uses the leastsq library from scipy to compute the coefficients, and returns those values:

from scipy.optimize import leastsq

def FTCurves(TotalData,RatEnergy):
#Create the CAPFT and EIRFT Curves
#Start by aggregating the IWB, ODB, and CapRatio
    IWB,ODB,CapRatio,PowerRatio=[],[],[],[]
    for measurement in TotalData:
        if measurement[0]==100.0:
            IWB.append(measurement[2])
            ODB.append(measurement[3])
            CapRatio.append(measurement[4]/measurement[1])
            PowerRatio.append(measurement[5]/RatEnergy)

    npIWB=np.array(IWB)
    IWBmax,IWBmin = max(npIWB),min(npIWB)
    npODB=np.array(ODB)
    ODBmax,ODBmin = max(npODB),min(npODB)
    npCapRatio=np.array(CapRatio)
    npPowerRatio=np.array(PowerRatio)

    p0=[0,0,0,0,0,0] # initial guesses

    #Least Square Optimization to find parameters
    CAPFT,cov,infodict,mesg,ier = leastsq(residualsTwoDimBiquadratic,p0,args=(npCapRatio,npIWB,npODB),full_output=1)
    CAPFTerr = calcerror(infodict,npCapRatio)
    EIRFT,cov,infodict,mesg,ier = leastsq(residualsTwoDimBiquadratic,p0,args=(npPowerRatio,npIWB,npODB),full_output=1)
    EIRFTerr = calcerror(infodict,npPowerRatio)
    return CAPFT,EIRFT,CAPFTerr,EIRFTerr,IWBmax,IWBmin,ODBmax,ODBmin

You may notice that the leastsq function calls another function such as “residualsTwoDimBiQuadratic” - the purpose of this is to define the structure of the expression which the data will be fitted to (found in VRFfunctions.py):

#Defines the Function for two dimensional Biquadratic
def TwoDimBiquadratic(A,B,p):
    return(p[0] + p[1]*A + p[2]*A**2 + p[3]*B + p[4]*B**2 + p[5]*A*B)

#Defines residuals used in BiQuadratic
def residualsTwoDimBiquadratic(p,I,A,B):
    err = (I - TwoDimBiquadratic(A,B,p))
    return err

Step 3: Assemble Coefficients into Energyplus Input Objects

The calculated coefficients are then used to create performance input objects for the energyplus VRV system. I did this through automating the creation of objects using Python’s excellent text manipulation capabilities. The details of this step can be found in a github repository I set up to show an example of this whole process: all of the scripts in this post as well as some example input and output documents can be found in my pynergyplus repository.

(Disclaimer: the repository is a bit chaotic as I created the scripts quickly to get the job done. Any assistance in improving the scripts is greatly appreciated!)