Added a module for importing water to water source heat pump

This commit is contained in:
Peter Yefi 2021-12-15 09:24:52 +00:00
parent 1ed60762c3
commit 93160912c3

View File

@ -0,0 +1,173 @@
"""
WaterToWaterHPParameters import the heat pump information
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2021 Project Author Peter Yefi peteryefi@gmail.com
"""
import pandas as pd
from typing import Dict
from city_model_structure.energy_systems.water_to_water_hp import WaterToWaterHP
from city_model_structure.energy_system import EnergySystem
from scipy.optimize import curve_fit
import numpy as np
from typing import List
class WaterToWaterHPParameters:
"""
WaterToWaterHPParameters class
"""
def __init__(self, city, base_path):
self._city = city
self._base_path = (base_path / 'heat_pumps/water_to_water.xlsx')
def _read_file(self) -> Dict:
"""
reads xlsx file containing water to water heat pump information
into a dictionary
:return : Dict
"""
xl_file = pd.ExcelFile(self._base_path)
heat_pump_dfs = {sheet_name: xl_file.parse(sheet_name)
for sheet_name in xl_file.sheet_names}
hp_data = {}
flow_rates = {
'156': [2.84, 4.23, 5.68],
'256': [4.73, 7.13, 9.446],
'335': [6.62, 9.97, 12.93],
}
for sheet, dataframe in heat_pump_dfs.items():
df = heat_pump_dfs[sheet].dropna(axis=1, how='all')
df = df.iloc[3:, 6:35]
if '156' in sheet:
hp_data[sheet] = self._extract_required_hp_data(df, [0, 10, 25, 40, 55, 67], flow_rates['156'])
elif '256' in sheet:
hp_data[sheet] = self._extract_required_hp_data(df, [0, 9, 24, 39, 54, 66], flow_rates['256'])
elif '335' in sheet:
hp_data[sheet] = self._extract_required_hp_data(df, [0, 11, 26, 41, 56, 69], flow_rates['335'])
return hp_data
def _extract_required_hp_data(self, dataframe, ranges, flow_rates):
"""
Extracts 156 Kw water to water heat pump data
:param dataframe: dataframe containing all data
:param ranges: the range of values to extract
:param flow_rates: the flow rates of water through pump
:return: Dict
"""
# extract data rows and columns
data = {'tc': self._extract_hp_data(dataframe, [1, 11, 21], ranges),
'pd': self._extract_hp_data(dataframe, [2, 12, 22], ranges),
'lwt': self._extract_hp_data(dataframe, [5, 15, 25], ranges),
'fr': (self._extract_flow_and_ewt(dataframe, ranges, [1, 11, 21], flow_rates))[0],
'ewt': (self._extract_flow_and_ewt(dataframe, ranges, [1, 11, 21], flow_rates))[1]}
# range values for extracting data
return data
def _extract_hp_data(self, df, columns, ranges):
"""
Extract variable specific (LWT, PD or TC) data from water to water hp
:param df: the dataframe
:param columns: the columns to extract data from
:param ranges: the range of values to extract
:return: List
"""
data = df.iloc[ranges[0]:ranges[1], columns[0]].append(df.iloc[ranges[0]:ranges[1], columns[1]])\
.append(df.iloc[ranges[0]:ranges[1], columns[2]])
for i in range(1, 5):
data = data.append(df.iloc[ranges[i]:ranges[i + 1], columns[0]]).append(
df.iloc[ranges[i]:ranges[i + 1], columns[1]]).append(df.iloc[ranges[i]:ranges[i + 1], columns[2]])
return data.dropna().values.tolist()
def _extract_flow_and_ewt(self, df, ranges, columns, flow_rates):
"""
Create the flow and ewt data based on the length of the various
columns for the variables being extracted
:param df: the dataframe
:param ranges: the range of values to extract
:param columns: the columns to extract data from
:param flow_rates: flow rate values
:return:
"""
ewt_values = [-1.111111111, 4.444444444, 10, 15.55555556, 21.11111111]
length = [len(df.iloc[ranges[0]:ranges[1], columns[0]].dropna()),
len(df.iloc[ranges[0]:ranges[1], columns[1]].dropna()),
len(df.iloc[ranges[0]:ranges[1], columns[2]].dropna())]
ewt_data = np.repeat(ewt_values[0], sum(length))
flow_rates_data = np.repeat(flow_rates, length)
for i in range(1, 5):
length = [len(df.iloc[ranges[i]:ranges[i + 1], columns[0]].dropna()),
len(df.iloc[ranges[i]:ranges[i + 1], columns[1]].dropna()),
len(df.iloc[ranges[i]:ranges[i + 1], columns[2]].dropna())]
flow_rates_data = np.append(flow_rates_data, np.repeat(flow_rates, length))
ewt_data = np.append(ewt_data, np.repeat(ewt_values[i], sum(length)))
return flow_rates_data.tolist(), ewt_data.tolist()
def enrich_city(self):
"""
Enriches the city with information from file
"""
heap_pump_data = self._read_file()
for model, data in heap_pump_data.items():
heat_pump = WaterToWaterHP()
heat_pump.model = model.strip()
heat_pump.total_cooling_capacity = data['tc']
heat_pump.power_demand = data['pd']
heat_pump.flow_rate = data['fr']
heat_pump.entering_water_temp = data['ewt']
heat_pump.leaving_water_temp = data['lwt']
heat_pump.power_demand_coff = self._compute_coefficients(data, data_type='power')
heat_pump.total_cooling_capacity_coff = self._compute_coefficients(data)
energy_system = EnergySystem(heat_pump.model, 0, [], None)
energy_system.water_to_water_hp = heat_pump
self._city.add_city_object(energy_system)
return self._city
def _compute_coefficients(self, heat_pump_data: Dict, data_type="heat_output") -> List[float]:
"""
Compute heat output and electrical demand coefficients
from heating performance data
:param heat_pump_data: a dictionary of heat pump data.
:param data_type: string to indicate whether coefficient are power demands
or heat output coefficients. Default is heat output
:return: Tuple[Dict, Dict]
"""
demand = heat_pump_data['tc'] if data_type == "heat_output" else heat_pump_data['pd']
# Compute heat output coefficients
popt, _ = curve_fit(self._objective_function, [heat_pump_data['ewt'], heat_pump_data['lwt'], heat_pump_data['fr']],
demand)
return popt.tolist()
def _objective_function(self, xdata: List, a1: float, a2: float, a3: float, a4: float, a5: float, a6: float,
a7: float, a8: float, a9: float, a10: float, a11: float) -> float:
"""
Objective function for computing coefficients
:param xdata:
:param a1: float
:param a2: float
:param a3: float
:param a4: float
:param a5: float
:param a6: float
:param a7: float
:param a8: float
:param a9: float
:param a10: float
:param a11: float
:return:
"""
x, y, t = xdata
return (a1 * x ** 2) + (a2 * x) + (a3 * y ** 2) + (a4 * y) + (a5 * t ** 2) + (a6 * t) + (a7 * x * y) + (
a8 * x * t) + (a9 * y * t) + (a10 * x * y * t) + a11