Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
35c62b4808
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -2,3 +2,5 @@
|
||||||
/venv/
|
/venv/
|
||||||
.idea/
|
.idea/
|
||||||
/development_tests/
|
/development_tests/
|
||||||
|
/data/energy_systems/heat_pumps/*.csv
|
||||||
|
/data/energy_systems/heat_pumps/*.insel
|
||||||
|
|
|
@ -4,7 +4,6 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import math
|
import math
|
||||||
import sys
|
import sys
|
||||||
|
@ -72,11 +71,11 @@ class Polygon:
|
||||||
"""
|
"""
|
||||||
if self._edges is None:
|
if self._edges is None:
|
||||||
self._edges = []
|
self._edges = []
|
||||||
for i in range(0, len(self.points)-1):
|
for i in range(0, len(self.points) - 1):
|
||||||
point_1 = self.points[i]
|
point_1 = self.points[i]
|
||||||
point_2 = self.points[i+1]
|
point_2 = self.points[i + 1]
|
||||||
self._edges.append([point_1, point_2])
|
self._edges.append([point_1, point_2])
|
||||||
self._edges.append([self.points[len(self.points)-1], self.points[0]])
|
self._edges.append([self.points[len(self.points) - 1], self.points[0]])
|
||||||
return self._edges
|
return self._edges
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -100,12 +99,12 @@ class Polygon:
|
||||||
return 0
|
return 0
|
||||||
horizontal_points = self._points_rotated_to_horizontal
|
horizontal_points = self._points_rotated_to_horizontal
|
||||||
area = 0
|
area = 0
|
||||||
for i in range(0, len(horizontal_points)-1):
|
for i in range(0, len(horizontal_points) - 1):
|
||||||
point = horizontal_points[i]
|
point = horizontal_points[i]
|
||||||
next_point = horizontal_points[i+1]
|
next_point = horizontal_points[i + 1]
|
||||||
area += (next_point[1] + point[1]) / 2 * (next_point[0] - point[0])
|
area += (next_point[1] + point[1]) / 2 * (next_point[0] - point[0])
|
||||||
next_point = horizontal_points[0]
|
next_point = horizontal_points[0]
|
||||||
point = horizontal_points[len(horizontal_points)-1]
|
point = horizontal_points[len(horizontal_points) - 1]
|
||||||
area += (next_point[1] + point[1]) / 2 * (next_point[0] - point[0])
|
area += (next_point[1] + point[1]) / 2 * (next_point[0] - point[0])
|
||||||
self._area = abs(area)
|
self._area = abs(area)
|
||||||
return self._area
|
return self._area
|
||||||
|
@ -157,8 +156,8 @@ class Polygon:
|
||||||
if self._normal is None:
|
if self._normal is None:
|
||||||
points = self.coordinates
|
points = self.coordinates
|
||||||
# todo: IF THE FIRST ONE IS 0, START WITH THE NEXT
|
# todo: IF THE FIRST ONE IS 0, START WITH THE NEXT
|
||||||
point_origin = points[len(points)-2]
|
point_origin = points[len(points) - 2]
|
||||||
vector_1 = points[len(points)-1] - point_origin
|
vector_1 = points[len(points) - 1] - point_origin
|
||||||
vector_2 = points[0] - point_origin
|
vector_2 = points[0] - point_origin
|
||||||
vector_3 = points[1] - point_origin
|
vector_3 = points[1] - point_origin
|
||||||
cross_product = np.cross(vector_1, vector_2)
|
cross_product = np.cross(vector_1, vector_2)
|
||||||
|
@ -173,9 +172,9 @@ class Polygon:
|
||||||
if np.linalg.norm(cross_product) == 0:
|
if np.linalg.norm(cross_product) == 0:
|
||||||
return cross_product
|
return cross_product
|
||||||
alpha += self._angle(vector_2, vector_3, cross_product)
|
alpha += self._angle(vector_2, vector_3, cross_product)
|
||||||
for i in range(0, len(points)-4):
|
for i in range(0, len(points) - 4):
|
||||||
vector_1 = points[i+1] - point_origin
|
vector_1 = points[i + 1] - point_origin
|
||||||
vector_2 = points[i+2] - point_origin
|
vector_2 = points[i + 2] - point_origin
|
||||||
alpha += self._angle(vector_1, vector_2, cross_product)
|
alpha += self._angle(vector_1, vector_2, cross_product)
|
||||||
vector_1 = points[len(points) - 1] - point_origin
|
vector_1 = points[len(points) - 1] - point_origin
|
||||||
vector_2 = points[0] - point_origin
|
vector_2 = points[0] - point_origin
|
||||||
|
@ -242,25 +241,30 @@ class Polygon:
|
||||||
if self._is_ear(ear, rest_points):
|
if self._is_ear(ear, rest_points):
|
||||||
ears.append(ear)
|
ears.append(ear)
|
||||||
point_to_remove = concave_points[i]
|
point_to_remove = concave_points[i]
|
||||||
previous_point_in_list, next_point_in_list = self._enveloping_points(point_to_remove, total_points_list)
|
previous_point_in_list, next_point_in_list = self._enveloping_points(point_to_remove,
|
||||||
|
total_points_list)
|
||||||
total_points_list.remove(point_to_remove)
|
total_points_list.remove(point_to_remove)
|
||||||
concave_points.remove(point_to_remove)
|
concave_points.remove(point_to_remove)
|
||||||
# Was any of the adjacent points convex? -> check if changed status to concave
|
# Was any of the adjacent points convex? -> check if changed status to concave
|
||||||
for convex_point in convex_points:
|
for convex_point in convex_points:
|
||||||
if convex_point == previous_point_in_list:
|
if convex_point == previous_point_in_list:
|
||||||
concave_points, convex_points, end_loop = self._if_concave_change_status(normal, points_list,
|
concave_points, convex_points, end_loop = self._if_concave_change_status(normal,
|
||||||
|
points_list,
|
||||||
convex_point,
|
convex_point,
|
||||||
total_points_list,
|
total_points_list,
|
||||||
concave_points, convex_points,
|
concave_points,
|
||||||
|
convex_points,
|
||||||
previous_point_in_list)
|
previous_point_in_list)
|
||||||
if end_loop:
|
if end_loop:
|
||||||
break
|
break
|
||||||
continue
|
continue
|
||||||
if convex_point == next_point_in_list:
|
if convex_point == next_point_in_list:
|
||||||
concave_points, convex_points, end_loop = self._if_concave_change_status(normal, points_list,
|
concave_points, convex_points, end_loop = self._if_concave_change_status(normal,
|
||||||
|
points_list,
|
||||||
convex_point,
|
convex_point,
|
||||||
total_points_list,
|
total_points_list,
|
||||||
concave_points, convex_points,
|
concave_points,
|
||||||
|
convex_points,
|
||||||
next_point_in_list)
|
next_point_in_list)
|
||||||
if end_loop:
|
if end_loop:
|
||||||
break
|
break
|
||||||
|
@ -300,11 +304,11 @@ class Polygon:
|
||||||
else:
|
else:
|
||||||
convex_points.append(index)
|
convex_points.append(index)
|
||||||
# case 2: all points except first and last
|
# case 2: all points except first and last
|
||||||
for i in range(0, int((len(points_list)-6)/3)):
|
for i in range(0, int((len(points_list) - 6) / 3)):
|
||||||
point = points_list[(i+1)*3:(i+2)*3]
|
point = points_list[(i + 1) * 3:(i + 2) * 3]
|
||||||
previous_point = points_list[i*3:(i+1)*3]
|
previous_point = points_list[i * 3:(i + 1) * 3]
|
||||||
next_point = points_list[(i+2)*3:(i+3)*3]
|
next_point = points_list[(i + 2) * 3:(i + 3) * 3]
|
||||||
index = i+1
|
index = i + 1
|
||||||
total_points_list.append(index)
|
total_points_list.append(index)
|
||||||
if Polygon._point_is_concave(normal, point, previous_point, next_point):
|
if Polygon._point_is_concave(normal, point, previous_point, next_point):
|
||||||
concave_points.append(index)
|
concave_points.append(index)
|
||||||
|
@ -314,7 +318,7 @@ class Polygon:
|
||||||
point = points_list[len(points_list) - 3:]
|
point = points_list[len(points_list) - 3:]
|
||||||
previous_point = points_list[len(points_list) - 6:len(points_list) - 3]
|
previous_point = points_list[len(points_list) - 6:len(points_list) - 3]
|
||||||
next_point = points_list[0:3]
|
next_point = points_list[0:3]
|
||||||
index = int(len(points_list)/3) - 1
|
index = int(len(points_list) / 3) - 1
|
||||||
total_points_list.append(index)
|
total_points_list.append(index)
|
||||||
if Polygon._point_is_concave(normal, point, previous_point, next_point):
|
if Polygon._point_is_concave(normal, point, previous_point, next_point):
|
||||||
concave_points.append(index)
|
concave_points.append(index)
|
||||||
|
@ -358,7 +362,7 @@ class Polygon:
|
||||||
if point_position == total_points_list[len(total_points_list) - 1]:
|
if point_position == total_points_list[len(total_points_list) - 1]:
|
||||||
previous_point_index = total_points_list[len(total_points_list) - 2] * 3
|
previous_point_index = total_points_list[len(total_points_list) - 2] * 3
|
||||||
next_point_index = total_points_list[0] * 3
|
next_point_index = total_points_list[0] * 3
|
||||||
for i in range(1, len(total_points_list)-1):
|
for i in range(1, len(total_points_list) - 1):
|
||||||
if point_position == total_points_list[i]:
|
if point_position == total_points_list[i]:
|
||||||
previous_point_index = total_points_list[i - 1] * 3
|
previous_point_index = total_points_list[i - 1] * 3
|
||||||
next_point_index = total_points_list[i + 1] * 3
|
next_point_index = total_points_list[i + 1] * 3
|
||||||
|
@ -495,9 +499,9 @@ class Polygon:
|
||||||
sys.stderr.write("Warning: impossible to calculate angle between planes' normal. Return 0\n")
|
sys.stderr.write("Warning: impossible to calculate angle between planes' normal. Return 0\n")
|
||||||
return 0
|
return 0
|
||||||
cosine = np.dot(vec_1, vec_2) / np.linalg.norm(vec_1) / np.linalg.norm(vec_2)
|
cosine = np.dot(vec_1, vec_2) / np.linalg.norm(vec_1) / np.linalg.norm(vec_2)
|
||||||
if cosine > 1 and cosine-1 < 1e-5:
|
if cosine > 1 and cosine - 1 < 1e-5:
|
||||||
cosine = 1
|
cosine = 1
|
||||||
elif cosine < -1 and cosine+1 > -1e-5:
|
elif cosine < -1 and cosine + 1 > -1e-5:
|
||||||
cosine = -1
|
cosine = -1
|
||||||
alpha = math.acos(cosine)
|
alpha = math.acos(cosine)
|
||||||
return alpha
|
return alpha
|
||||||
|
@ -546,8 +550,9 @@ class Polygon:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _edge_in_edges_list(edge, edges_list):
|
def _edge_in_edges_list(edge, edges_list):
|
||||||
for edge_element in edges_list:
|
for edge_element in edges_list:
|
||||||
if (edge_element[0].distance_to_point(edge[0]) == 0 and edge_element[1].distance_to_point(edge[1]) == 0) or\
|
if (edge_element[0].distance_to_point(edge[0]) == 0 and edge_element[1].distance_to_point(edge[1]) == 0) or \
|
||||||
(edge_element[1].distance_to_point(edge[0]) == 0 and edge_element[0].distance_to_point(edge[1]) == 0):
|
(edge_element[1].distance_to_point(edge[0]) == 0 and edge_element[0].distance_to_point(
|
||||||
|
edge[1]) == 0):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -558,10 +563,10 @@ class Polygon:
|
||||||
for _ in range(0, len(points)):
|
for _ in range(0, len(points)):
|
||||||
for i in range(1, len(edges_list)):
|
for i in range(1, len(edges_list)):
|
||||||
point_1 = edges_list[i][0]
|
point_1 = edges_list[i][0]
|
||||||
point_2 = points[len(points)-1]
|
point_2 = points[len(points) - 1]
|
||||||
if point_1.distance_to_point(point_2) == 0:
|
if point_1.distance_to_point(point_2) == 0:
|
||||||
points.append(edges_list[i][1])
|
points.append(edges_list[i][1])
|
||||||
points.remove(points[len(points)-1])
|
points.remove(points[len(points) - 1])
|
||||||
array_points = []
|
array_points = []
|
||||||
for point in points:
|
for point in points:
|
||||||
array_points.append(point.coordinates)
|
array_points.append(point.coordinates)
|
||||||
|
@ -571,8 +576,10 @@ class Polygon:
|
||||||
def _remove_from_list(edge, edges_list):
|
def _remove_from_list(edge, edges_list):
|
||||||
new_list = []
|
new_list = []
|
||||||
for edge_element in edges_list:
|
for edge_element in edges_list:
|
||||||
if not((edge_element[0].distance_to_point(edge[0]) == 0 and edge_element[1].distance_to_point(edge[1]) == 0) or
|
if not ((edge_element[0].distance_to_point(edge[0]) == 0 and edge_element[1].distance_to_point(
|
||||||
(edge_element[1].distance_to_point(edge[0]) == 0 and edge_element[0].distance_to_point(edge[1]) == 0)):
|
edge[1]) == 0) or
|
||||||
|
(edge_element[1].distance_to_point(edge[0]) == 0 and edge_element[0].distance_to_point(
|
||||||
|
edge[1]) == 0)):
|
||||||
new_list.append(edge_element)
|
new_list.append(edge_element)
|
||||||
return new_list
|
return new_list
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ class Schedule:
|
||||||
"""
|
"""
|
||||||
Schedule class
|
Schedule class
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._id = None
|
self._id = None
|
||||||
self._type = None
|
self._type = None
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
City module
|
City module
|
||||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||||
|
Contributor Peter Yefi peteryefi@gmail.com
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import sys
|
import sys
|
||||||
|
@ -21,6 +22,7 @@ from city_model_structure.subway_entrance import SubwayEntrance
|
||||||
from city_model_structure.fuel import Fuel
|
from city_model_structure.fuel import Fuel
|
||||||
from helpers.geometry_helper import GeometryHelper
|
from helpers.geometry_helper import GeometryHelper
|
||||||
from helpers.location import Location
|
from helpers.location import Location
|
||||||
|
from city_model_structure.energy_system import EnergySystem
|
||||||
|
|
||||||
|
|
||||||
class City:
|
class City:
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
"""
|
"""
|
||||||
EnergySystem module
|
EnergySystem module
|
||||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
Copyright © 2021 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||||
|
Contributor Peter Yefi peteryefi@gmail.com
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from city_model_structure.city_object import CityObject
|
from city_model_structure.city_object import CityObject
|
||||||
|
@ -12,11 +13,33 @@ class EnergySystem(CityObject):
|
||||||
"""
|
"""
|
||||||
EnergySystem(CityObject) class
|
EnergySystem(CityObject) class
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, name, lod, surfaces, city_lower_corner):
|
def __init__(self, name, lod, surfaces, city_lower_corner):
|
||||||
super().__init__(name, lod, surfaces, city_lower_corner)
|
super().__init__(name, lod, surfaces, city_lower_corner)
|
||||||
self._heat_pump = None
|
self._heat_pump = None
|
||||||
|
self._type = 'energy_system'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def heat_pump(self) -> HeatPump:
|
def heat_pump(self) -> HeatPump:
|
||||||
|
"""
|
||||||
|
Heat pump energy system
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
return self._heat_pump
|
return self._heat_pump
|
||||||
|
|
||||||
|
@heat_pump.setter
|
||||||
|
def heat_pump(self, value):
|
||||||
|
"""
|
||||||
|
Set heat pumm for energy system
|
||||||
|
:param value: HeatPump
|
||||||
|
"""
|
||||||
|
if self._heat_pump is None:
|
||||||
|
self._heat_pump = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def type(self) -> str:
|
||||||
|
"""
|
||||||
|
Type of city object
|
||||||
|
:return: str
|
||||||
|
"""
|
||||||
|
return self._type
|
||||||
|
|
|
@ -2,45 +2,189 @@
|
||||||
heat_pump module defines a heat pump
|
heat_pump module defines a heat pump
|
||||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||||
|
Contributor Peter Yefi peteryefi@gmail.com
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from typing import Union
|
from typing import List
|
||||||
|
from typing import Dict
|
||||||
|
|
||||||
|
|
||||||
class HeatPump:
|
class HeatPump:
|
||||||
"""
|
"""
|
||||||
HeatPump class
|
HeatPump class
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._model = None
|
self._model = None
|
||||||
self._cooling_pf = None
|
self._cooling_capacity = None
|
||||||
self._cooling_pa = None
|
self._cooling_comp_power = None
|
||||||
self._cooling_qw = None
|
self._cooling_capacity_coff = None
|
||||||
self._heating_pf = None
|
self._cooling_comp_power_coff = None
|
||||||
self._heating_pa = None
|
self._heating_capacity = None
|
||||||
self._heating_qw = None
|
self._heating_comp_power = None
|
||||||
|
self._heating_capacity_coff = None
|
||||||
|
self._heating_comp_power_coff = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def model(self):
|
def model(self) -> str:
|
||||||
"""
|
"""
|
||||||
Get model name
|
Get model name
|
||||||
:return: str
|
:return: str
|
||||||
"""
|
"""
|
||||||
return self._model
|
return self._model
|
||||||
|
|
||||||
|
@model.setter
|
||||||
|
def model(self, value):
|
||||||
|
"""
|
||||||
|
Set model (name, indicated in capacity)
|
||||||
|
:param value: str
|
||||||
|
"""
|
||||||
|
if self._model is None:
|
||||||
|
self._model = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def cooling_pf(self):
|
def cooling_capacity(self) -> List[float]:
|
||||||
"""
|
"""
|
||||||
Get cooling capacity in kW
|
Get cooling capacity in kW
|
||||||
:return: [[float]]
|
:return: [[float]]
|
||||||
"""
|
"""
|
||||||
return self._cooling_pf
|
return self._cooling_capacity
|
||||||
|
|
||||||
@cooling_pf.setter
|
@cooling_capacity.setter
|
||||||
def cooling_pf(self, value):
|
def cooling_capacity(self, value):
|
||||||
"""
|
"""
|
||||||
Set cooling capacity in kW
|
Set cooling capacity in kW
|
||||||
:param value: [[float]]
|
:param value: [[float]]
|
||||||
"""
|
"""
|
||||||
if self._cooling_pf is None:
|
if self._cooling_capacity is None:
|
||||||
self._cooling_pf = value
|
self._cooling_capacity = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cooling_comp_power(self) -> List[float]:
|
||||||
|
"""
|
||||||
|
Get cooling compressor power input in kW
|
||||||
|
:return: [[float]]
|
||||||
|
"""
|
||||||
|
return self._cooling_comp_power
|
||||||
|
|
||||||
|
@cooling_comp_power.setter
|
||||||
|
def cooling_comp_power(self, value):
|
||||||
|
"""
|
||||||
|
Set the cooling compressor in kW
|
||||||
|
:param value: [[float]]
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
if self._cooling_comp_power is None:
|
||||||
|
self._cooling_comp_power = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cooling_capacity_coff(self) -> List[float]:
|
||||||
|
"""
|
||||||
|
Get cooling capacity coefficients
|
||||||
|
:return: [float]
|
||||||
|
"""
|
||||||
|
return self._cooling_capacity_coff
|
||||||
|
|
||||||
|
@cooling_capacity_coff.setter
|
||||||
|
def cooling_capacity_coff(self, value):
|
||||||
|
"""
|
||||||
|
Set the value for cooling capacity coefficients
|
||||||
|
:param value: [float]
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
if self._cooling_capacity_coff is None:
|
||||||
|
self._cooling_capacity_coff = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cooling_comp_power_coff(self) -> List[float]:
|
||||||
|
"""
|
||||||
|
Get cooling compressor power coefficients
|
||||||
|
:return: [float]
|
||||||
|
"""
|
||||||
|
return self._cooling_comp_power_coff
|
||||||
|
|
||||||
|
@cooling_comp_power_coff.setter
|
||||||
|
def cooling_comp_power_coff(self, value):
|
||||||
|
"""
|
||||||
|
Set the value for cooling compressor power coefficients
|
||||||
|
:param value: [float]
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
if self._cooling_comp_power_coff is None:
|
||||||
|
self._cooling_comp_power_coff = value
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@property
|
||||||
|
def heating_capacity(self) -> List[float]:
|
||||||
|
"""
|
||||||
|
Get heating capacity kW
|
||||||
|
:return: [[float]]
|
||||||
|
"""
|
||||||
|
return self._heating_capacity
|
||||||
|
|
||||||
|
@heating_capacity.setter
|
||||||
|
def heating_capacity(self, value):
|
||||||
|
"""
|
||||||
|
Set the heating capacity in kW
|
||||||
|
:param value: [[float]]
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
if self._heating_capacity is None:
|
||||||
|
self._heating_capacity = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def heating_comp_power(self) -> List[float]:
|
||||||
|
"""
|
||||||
|
Get heating compressor power kW
|
||||||
|
:return: [[float]]
|
||||||
|
"""
|
||||||
|
return self._heating_comp_power
|
||||||
|
|
||||||
|
@heating_comp_power.setter
|
||||||
|
def heating_comp_power(self, value):
|
||||||
|
"""
|
||||||
|
Set the heating compressor power in kW
|
||||||
|
:param value: [[float]]
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
if self._heating_comp_power is None:
|
||||||
|
self._heating_comp_power = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def heating_comp_power_coff(self) -> List[float]:
|
||||||
|
"""
|
||||||
|
Get heating compressor power coefficients
|
||||||
|
:return: [float]
|
||||||
|
"""
|
||||||
|
return self._heating_comp_power_coff
|
||||||
|
|
||||||
|
@heating_comp_power_coff.setter
|
||||||
|
def heating_comp_power_coff(self, value):
|
||||||
|
"""
|
||||||
|
Set the value for heating compressor power coefficients
|
||||||
|
:param value: [float]
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
if self._heating_comp_power_coff is None:
|
||||||
|
self._heating_comp_power_coff = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def heating_capacity_coff(self) -> List[float]:
|
||||||
|
"""
|
||||||
|
Get heating capacity coefficients
|
||||||
|
:return: [float]
|
||||||
|
"""
|
||||||
|
return self._heating_capacity_coff
|
||||||
|
|
||||||
|
@heating_capacity_coff.setter
|
||||||
|
def heating_capacity_coff(self, value):
|
||||||
|
"""
|
||||||
|
Set the value for heating capacity coefficients
|
||||||
|
:param value: [float]
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
if self._heating_capacity_coff is None:
|
||||||
|
self._heating_capacity_coff = value
|
||||||
|
|
||||||
|
|
||||||
|
|
20
data/energy_systems/heat_pumps/constants.yaml
Normal file
20
data/energy_systems/heat_pumps/constants.yaml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# Heat pump performance constants
|
||||||
|
StartMonth: 1
|
||||||
|
StartDay: 1
|
||||||
|
StartHour: 0
|
||||||
|
StartMinute: 0
|
||||||
|
StartSecond: 0
|
||||||
|
EndMonth: 1
|
||||||
|
EndDay: 1
|
||||||
|
EndHour: 0
|
||||||
|
EndMinute: 0
|
||||||
|
EndSecond: 0
|
||||||
|
Cp: 4190
|
||||||
|
Rhow: 1000
|
||||||
|
TESDiameter: 5
|
||||||
|
AuxHeaterEfficiency: 0.9
|
||||||
|
|
||||||
|
# These come from the data model according to other student's work
|
||||||
|
ElecGridEF: 0.5
|
||||||
|
ElectricityPrice: 0.073
|
||||||
|
|
105120
data/energy_systems/heat_pumps/demand.txt
Normal file
105120
data/energy_systems/heat_pumps/demand.txt
Normal file
File diff suppressed because it is too large
Load Diff
816
data/energy_systems/heat_pumps/template.txt
Normal file
816
data/energy_systems/heat_pumps/template.txt
Normal file
|
@ -0,0 +1,816 @@
|
||||||
|
|
||||||
|
B 10 MUL
|
||||||
|
64.1
|
||||||
|
183.1
|
||||||
|
|
||||||
|
B 11 MUL
|
||||||
|
198.1
|
||||||
|
167.1
|
||||||
|
163.1
|
||||||
|
162.1
|
||||||
|
|
||||||
|
B 12 MUL
|
||||||
|
201.1
|
||||||
|
24.1
|
||||||
|
|
||||||
|
B 13 MUL
|
||||||
|
70.1
|
||||||
|
180.1
|
||||||
|
|
||||||
|
B 14 MUL
|
||||||
|
184.1
|
||||||
|
34.1
|
||||||
|
|
||||||
|
B 15 MUL
|
||||||
|
198.1
|
||||||
|
165.1
|
||||||
|
163.1
|
||||||
|
162.1
|
||||||
|
|
||||||
|
B 16 MUL
|
||||||
|
186.1
|
||||||
|
40.1
|
||||||
|
|
||||||
|
B 17 MUL
|
||||||
|
79.1
|
||||||
|
56.1
|
||||||
|
69.1
|
||||||
|
|
||||||
|
B 18 MUL
|
||||||
|
188.1
|
||||||
|
49.1
|
||||||
|
|
||||||
|
B 19 MUL
|
||||||
|
46.1
|
||||||
|
158.1
|
||||||
|
|
||||||
|
B 20 MUL
|
||||||
|
72.1
|
||||||
|
66.1
|
||||||
|
|
||||||
|
B 21 MUL
|
||||||
|
57.1
|
||||||
|
182.1
|
||||||
|
|
||||||
|
B 22 MUL
|
||||||
|
203.2
|
||||||
|
43.1
|
||||||
|
|
||||||
|
B 23 MUL
|
||||||
|
78.1
|
||||||
|
50.1
|
||||||
|
47.1
|
||||||
|
|
||||||
|
B 24 MUL
|
||||||
|
201.1
|
||||||
|
193.1
|
||||||
|
196.1
|
||||||
|
|
||||||
|
B 25 MUL
|
||||||
|
203.2
|
||||||
|
76.1
|
||||||
|
|
||||||
|
B 26 MUL
|
||||||
|
58.1
|
||||||
|
68.1
|
||||||
|
|
||||||
|
B 27 MUL
|
||||||
|
160.1
|
||||||
|
63.1
|
||||||
|
168.1
|
||||||
|
136.1
|
||||||
|
|
||||||
|
B 28 MUL
|
||||||
|
58.1
|
||||||
|
60.1
|
||||||
|
|
||||||
|
B 29 MUL
|
||||||
|
65.1
|
||||||
|
181.1
|
||||||
|
|
||||||
|
B 30 MUL
|
||||||
|
203.2
|
||||||
|
58.1
|
||||||
|
36.1
|
||||||
|
|
||||||
|
B 31 MUL
|
||||||
|
159.1
|
||||||
|
195.1
|
||||||
|
|
||||||
|
B 32 MUL
|
||||||
|
203.2
|
||||||
|
58.1
|
||||||
|
77.1
|
||||||
|
|
||||||
|
B 33 MUL
|
||||||
|
202.1
|
||||||
|
74.1
|
||||||
|
|
||||||
|
B 34 CONST
|
||||||
|
P 34
|
||||||
|
$ElecGridEF % Constant value
|
||||||
|
|
||||||
|
B 35 CONST
|
||||||
|
P 35
|
||||||
|
5 % Constant value
|
||||||
|
|
||||||
|
B 36 CONST
|
||||||
|
P 36
|
||||||
|
$a3 % Constant value
|
||||||
|
|
||||||
|
B 37 CONST
|
||||||
|
P 37
|
||||||
|
$TemperatureDifference % Constant value
|
||||||
|
|
||||||
|
B 38 CONST
|
||||||
|
P 38
|
||||||
|
42 % Constant value
|
||||||
|
|
||||||
|
B 39 CONST
|
||||||
|
P 39
|
||||||
|
40 % Constant value
|
||||||
|
|
||||||
|
B 40 CONST
|
||||||
|
P 40
|
||||||
|
$ElectricityPrice % Constant value
|
||||||
|
|
||||||
|
B 41 CONST
|
||||||
|
P 41
|
||||||
|
9 % Constant value
|
||||||
|
|
||||||
|
B 42 CONST
|
||||||
|
P 42
|
||||||
|
12 % Constant value
|
||||||
|
|
||||||
|
B 43 CONST
|
||||||
|
P 43
|
||||||
|
$b2 % Constant value
|
||||||
|
|
||||||
|
B 44 CONST
|
||||||
|
P 44
|
||||||
|
$a6 % Constant value
|
||||||
|
|
||||||
|
B 45 CONST
|
||||||
|
P 45
|
||||||
|
55 % Constant value
|
||||||
|
|
||||||
|
B 46 CONST
|
||||||
|
P 46
|
||||||
|
$Cp % Constant value
|
||||||
|
|
||||||
|
B 47 CONST
|
||||||
|
P 47
|
||||||
|
$FuelEF % Constant value
|
||||||
|
|
||||||
|
B 48 CONST
|
||||||
|
P 48
|
||||||
|
2 % Constant value
|
||||||
|
|
||||||
|
B 49 CONST
|
||||||
|
P 49
|
||||||
|
1 % Constant value
|
||||||
|
|
||||||
|
B 50 CONST
|
||||||
|
P 50
|
||||||
|
300 % Constant value
|
||||||
|
|
||||||
|
B 51 CONST
|
||||||
|
P 51
|
||||||
|
10 % Constant value
|
||||||
|
|
||||||
|
B 52 CONST
|
||||||
|
P 52
|
||||||
|
0 % Constant value
|
||||||
|
|
||||||
|
B 53 CONST
|
||||||
|
P 53
|
||||||
|
12 % Constant value
|
||||||
|
|
||||||
|
B 54 CONST
|
||||||
|
P 54
|
||||||
|
$FuelLHV % Constant value
|
||||||
|
|
||||||
|
B 55 CONST
|
||||||
|
P 55
|
||||||
|
2 % Constant value
|
||||||
|
|
||||||
|
B 56 CONST
|
||||||
|
P 56
|
||||||
|
300 % Constant value
|
||||||
|
|
||||||
|
B 57 CONST
|
||||||
|
P 57
|
||||||
|
$b5 % Constant value
|
||||||
|
|
||||||
|
B 58 CONST
|
||||||
|
P 58
|
||||||
|
$HPSupTemp % Constant value
|
||||||
|
|
||||||
|
B 59 CONST
|
||||||
|
P 59
|
||||||
|
40 % Constant value
|
||||||
|
|
||||||
|
B 60 CONST
|
||||||
|
P 60
|
||||||
|
$a4 % Constant value
|
||||||
|
|
||||||
|
B 61 CONST
|
||||||
|
P 61
|
||||||
|
$b6 % Constant value
|
||||||
|
|
||||||
|
B 62 CONST
|
||||||
|
P 62
|
||||||
|
2 % Constant value
|
||||||
|
|
||||||
|
B 63 CONST
|
||||||
|
P 63
|
||||||
|
$Cp % Constant value
|
||||||
|
|
||||||
|
B 64 CONST
|
||||||
|
P 64
|
||||||
|
$b1 % Constant value
|
||||||
|
|
||||||
|
B 65 CONST
|
||||||
|
P 65
|
||||||
|
$a1 % Constant value
|
||||||
|
|
||||||
|
B 66 CONST
|
||||||
|
P 66
|
||||||
|
$TemperatureDifference % Constant value
|
||||||
|
|
||||||
|
B 67 CONST
|
||||||
|
P 67
|
||||||
|
$MaximumHPEnergyInput % Constant value
|
||||||
|
|
||||||
|
B 68 CONST
|
||||||
|
P 68
|
||||||
|
$b4 % Constant value
|
||||||
|
|
||||||
|
B 69 CONST
|
||||||
|
P 69
|
||||||
|
$FuelPrice % Constant value
|
||||||
|
|
||||||
|
B 70 CONST
|
||||||
|
P 70
|
||||||
|
$a5 % Constant value
|
||||||
|
|
||||||
|
B 71 CONST
|
||||||
|
P 71
|
||||||
|
2 % Constant value
|
||||||
|
|
||||||
|
B 72 CONST
|
||||||
|
P 72
|
||||||
|
$Cp % Constant value
|
||||||
|
|
||||||
|
B 73 CONST
|
||||||
|
P 73
|
||||||
|
$BuildingSuppTemp % Constant value
|
||||||
|
|
||||||
|
B 74 CONST
|
||||||
|
P 74
|
||||||
|
25 % Constant value
|
||||||
|
|
||||||
|
B 75 CONST
|
||||||
|
P 75
|
||||||
|
0 % Constant value
|
||||||
|
|
||||||
|
B 76 CONST
|
||||||
|
P 76
|
||||||
|
$a2 % Constant value
|
||||||
|
|
||||||
|
B 77 CONST
|
||||||
|
P 77
|
||||||
|
$b3 % Constant value
|
||||||
|
|
||||||
|
B 78 ATT
|
||||||
|
191.1
|
||||||
|
P 78
|
||||||
|
$FuelDensity % Attenuation factor a
|
||||||
|
|
||||||
|
B 79 ATT
|
||||||
|
191.1
|
||||||
|
P 79
|
||||||
|
$FuelDensity % Attenuation factor a
|
||||||
|
|
||||||
|
B 80 ATT
|
||||||
|
27.1
|
||||||
|
P 80
|
||||||
|
$AuxHeaterEfficiency % Attenuation factor a
|
||||||
|
|
||||||
|
B 81 ATT
|
||||||
|
191.1
|
||||||
|
P 81
|
||||||
|
$FuelDensity % Attenuation factor a
|
||||||
|
|
||||||
|
B 82 ATT
|
||||||
|
11.1
|
||||||
|
P 82
|
||||||
|
12 % Attenuation factor a
|
||||||
|
|
||||||
|
B 83 ATT
|
||||||
|
210.5
|
||||||
|
P 83
|
||||||
|
3600000 % Attenuation factor a
|
||||||
|
|
||||||
|
B 84 ATT
|
||||||
|
161.1
|
||||||
|
P 84
|
||||||
|
3600000 % Attenuation factor a
|
||||||
|
|
||||||
|
B 85 ATT
|
||||||
|
27.1
|
||||||
|
P 85
|
||||||
|
1000 % Attenuation factor a
|
||||||
|
|
||||||
|
|
||||||
|
B 125 WRITE
|
||||||
|
156.1
|
||||||
|
156.2
|
||||||
|
156.3
|
||||||
|
P 125
|
||||||
|
2 % Mode
|
||||||
|
0 % Suppress FNQ inputs
|
||||||
|
$fileOut7 % File name
|
||||||
|
'*' % Fortran format
|
||||||
|
|
||||||
|
B 126 WRITE
|
||||||
|
151.1
|
||||||
|
151.2
|
||||||
|
151.3
|
||||||
|
P 126
|
||||||
|
2 % Mode
|
||||||
|
0 % Suppress FNQ inputs
|
||||||
|
$fileOut2 % File name
|
||||||
|
'*' % Fortran format
|
||||||
|
|
||||||
|
B 127 WRITE
|
||||||
|
154.1
|
||||||
|
154.2
|
||||||
|
154.3
|
||||||
|
P 127
|
||||||
|
2 % Mode
|
||||||
|
0 % Suppress FNQ inputs
|
||||||
|
$fileOut3 % File name
|
||||||
|
'*' % Fortran format
|
||||||
|
|
||||||
|
B 128 WRITE
|
||||||
|
153.1
|
||||||
|
153.2
|
||||||
|
153.3
|
||||||
|
P 128
|
||||||
|
2 % Mode
|
||||||
|
0 % Suppress FNQ inputs
|
||||||
|
$fileOut5 % File name
|
||||||
|
'*' % Fortran format
|
||||||
|
|
||||||
|
B 129 WRITE
|
||||||
|
204.1
|
||||||
|
204.2
|
||||||
|
204.3
|
||||||
|
204.4
|
||||||
|
204.5
|
||||||
|
15.1
|
||||||
|
11.1
|
||||||
|
190.1
|
||||||
|
187.1
|
||||||
|
160.1
|
||||||
|
210.1
|
||||||
|
210.2
|
||||||
|
210.3
|
||||||
|
210.4
|
||||||
|
210.5
|
||||||
|
83.1
|
||||||
|
84.1
|
||||||
|
191.1
|
||||||
|
85.1
|
||||||
|
16.1
|
||||||
|
17.1
|
||||||
|
14.1
|
||||||
|
23.1
|
||||||
|
164.1
|
||||||
|
145.1
|
||||||
|
P 129
|
||||||
|
2 % Mode
|
||||||
|
0 % Suppress FNQ inputs
|
||||||
|
$fileOut1 % File name
|
||||||
|
'*' % Fortran format
|
||||||
|
|
||||||
|
B 130 WRITE
|
||||||
|
204.1
|
||||||
|
204.2
|
||||||
|
204.3
|
||||||
|
152.1
|
||||||
|
152.2
|
||||||
|
P 130
|
||||||
|
2 % Mode
|
||||||
|
0 % Suppress FNQ inputs
|
||||||
|
$fileOut10 % File name
|
||||||
|
'*' % Fortran format
|
||||||
|
|
||||||
|
B 131 WRITE
|
||||||
|
149.1
|
||||||
|
149.2
|
||||||
|
P 131
|
||||||
|
2 % Mode
|
||||||
|
0 % Suppress FNQ inputs
|
||||||
|
$fileOut9 % File name
|
||||||
|
'*' % Fortran format
|
||||||
|
|
||||||
|
B 132 WRITE
|
||||||
|
157.1
|
||||||
|
157.2
|
||||||
|
P 132
|
||||||
|
2 % Mode
|
||||||
|
0 % Suppress FNQ inputs
|
||||||
|
$fileOut8 % File name
|
||||||
|
'*' % Fortran format
|
||||||
|
|
||||||
|
B 133 WRITE
|
||||||
|
150.1
|
||||||
|
150.2
|
||||||
|
P 133
|
||||||
|
2 % Mode
|
||||||
|
0 % Suppress FNQ inputs
|
||||||
|
$fileOut4 % File name
|
||||||
|
'*' % Fortran format
|
||||||
|
|
||||||
|
B 134 WRITE
|
||||||
|
155.1
|
||||||
|
155.2
|
||||||
|
P 134
|
||||||
|
2 % Mode
|
||||||
|
0 % Suppress FNQ inputs
|
||||||
|
$fileOut6 % File name
|
||||||
|
'*' % Fortran format
|
||||||
|
|
||||||
|
B 135 LT
|
||||||
|
204.2
|
||||||
|
35.1
|
||||||
|
|
||||||
|
B 136 LT
|
||||||
|
210.1
|
||||||
|
39.1
|
||||||
|
|
||||||
|
%B 137 SCREEN
|
||||||
|
%176.1
|
||||||
|
%P 137
|
||||||
|
%'*' % Format
|
||||||
|
%'Total CO2 Emissions from Electricity Grid (g)' % Headline
|
||||||
|
|
||||||
|
%B 138 SCREEN
|
||||||
|
%178.1
|
||||||
|
%P 138
|
||||||
|
%'*' % Format
|
||||||
|
%'Total Electricity Cost in a Year (CAD)' % Headline
|
||||||
|
|
||||||
|
%B 139 SCREEN
|
||||||
|
%173.1
|
||||||
|
%P 139
|
||||||
|
%'*' % Format
|
||||||
|
%'Total Cost of the Auxiliary Heater Fuel in a Year (CAD)' % Headline
|
||||||
|
|
||||||
|
%B 140 SCREEN
|
||||||
|
%177.1
|
||||||
|
%P 140
|
||||||
|
%'*' % Format
|
||||||
|
%'Total CO2 Emissions from Auxiliary Heater (g)' % Headline
|
||||||
|
|
||||||
|
%B 141 SCREEN
|
||||||
|
%189.1
|
||||||
|
%P 141
|
||||||
|
%'*' % Format
|
||||||
|
%'HP Seasonal COP' % Headline
|
||||||
|
|
||||||
|
%B 142 SCREEN
|
||||||
|
%148.1
|
||||||
|
%P 142
|
||||||
|
%'*' % Format
|
||||||
|
%'Maximum Number of HPs in Operation' % Headline
|
||||||
|
|
||||||
|
%B 143 SCREEN
|
||||||
|
%174.1
|
||||||
|
%P 143
|
||||||
|
%'*' % Format
|
||||||
|
%'Total Electricuty Demand of Heat Pumps in a year (kWh)' % Headline
|
||||||
|
|
||||||
|
%B 144 SCREEN
|
||||||
|
%179.1
|
||||||
|
%P 144
|
||||||
|
%'*' % Format
|
||||||
|
%'Total Fossil Fuel consumption in a Year (m3)' % Headline
|
||||||
|
|
||||||
|
B 145 READ
|
||||||
|
P 145
|
||||||
|
1 % Number of values to be read per record
|
||||||
|
0 % Number of records to be skipped on the first call
|
||||||
|
$HeatingDemand % File name
|
||||||
|
'*' % Fortran format
|
||||||
|
|
||||||
|
B 146 DELAY
|
||||||
|
15.1
|
||||||
|
P 146
|
||||||
|
0 % Initial value
|
||||||
|
|
||||||
|
B 147 DELAY
|
||||||
|
210.5
|
||||||
|
P 147
|
||||||
|
0 % Initial value
|
||||||
|
|
||||||
|
B 148 MAXX
|
||||||
|
198.1
|
||||||
|
|
||||||
|
B 149 CUMC
|
||||||
|
204.3
|
||||||
|
205.1
|
||||||
|
|
||||||
|
B 150 CUMC
|
||||||
|
204.2
|
||||||
|
205.1
|
||||||
|
|
||||||
|
B 151 CUMC
|
||||||
|
204.3
|
||||||
|
14.1
|
||||||
|
23.1
|
||||||
|
|
||||||
|
B 152 CUMC
|
||||||
|
204.4
|
||||||
|
82.1
|
||||||
|
|
||||||
|
B 153 CUMC
|
||||||
|
204.2
|
||||||
|
14.1
|
||||||
|
23.1
|
||||||
|
|
||||||
|
B 154 CUMC
|
||||||
|
204.2
|
||||||
|
16.1
|
||||||
|
17.1
|
||||||
|
|
||||||
|
B 155 CUMC
|
||||||
|
204.3
|
||||||
|
82.1
|
||||||
|
|
||||||
|
B 156 CUMC
|
||||||
|
204.3
|
||||||
|
16.1
|
||||||
|
17.1
|
||||||
|
|
||||||
|
B 157 CUMC
|
||||||
|
204.2
|
||||||
|
82.1
|
||||||
|
|
||||||
|
B 158 SUM
|
||||||
|
58.1
|
||||||
|
169.1
|
||||||
|
|
||||||
|
B 159 SUM
|
||||||
|
170.1
|
||||||
|
210.1
|
||||||
|
|
||||||
|
B 160 SUM
|
||||||
|
18.1
|
||||||
|
75.1
|
||||||
|
|
||||||
|
B 161 SUM
|
||||||
|
210.5
|
||||||
|
172.1
|
||||||
|
|
||||||
|
B 162 SUM
|
||||||
|
12.1
|
||||||
|
200.1
|
||||||
|
|
||||||
|
B 163 SUM
|
||||||
|
135.1
|
||||||
|
197.1
|
||||||
|
|
||||||
|
B 164 SUM
|
||||||
|
31.1
|
||||||
|
33.1
|
||||||
|
|
||||||
|
B 165 SUM
|
||||||
|
29.1
|
||||||
|
25.1
|
||||||
|
30.1
|
||||||
|
28.1
|
||||||
|
13.1
|
||||||
|
44.1
|
||||||
|
|
||||||
|
B 166 SUM
|
||||||
|
51.1
|
||||||
|
203.2
|
||||||
|
|
||||||
|
B 167 SUM
|
||||||
|
10.1
|
||||||
|
22.1
|
||||||
|
32.1
|
||||||
|
26.1
|
||||||
|
21.1
|
||||||
|
61.1
|
||||||
|
|
||||||
|
B 168 SUM
|
||||||
|
73.1
|
||||||
|
171.1
|
||||||
|
|
||||||
|
B 169 CHS
|
||||||
|
210.4
|
||||||
|
|
||||||
|
B 170 CHS
|
||||||
|
37.1
|
||||||
|
|
||||||
|
B 171 CHS
|
||||||
|
210.1
|
||||||
|
|
||||||
|
B 172 CHS
|
||||||
|
147.1
|
||||||
|
|
||||||
|
B 173 CUM
|
||||||
|
17.1
|
||||||
|
|
||||||
|
B 174 CUM
|
||||||
|
82.1
|
||||||
|
|
||||||
|
B 175 CUM
|
||||||
|
15.1
|
||||||
|
11.1
|
||||||
|
|
||||||
|
B 176 CUM
|
||||||
|
14.1
|
||||||
|
|
||||||
|
B 177 CUM
|
||||||
|
23.1
|
||||||
|
|
||||||
|
B 178 CUM
|
||||||
|
16.1
|
||||||
|
|
||||||
|
B 179 CUM
|
||||||
|
205.1
|
||||||
|
|
||||||
|
B 180 EXPG
|
||||||
|
58.1
|
||||||
|
55.1
|
||||||
|
|
||||||
|
B 181 EXPG
|
||||||
|
203.2
|
||||||
|
71.1
|
||||||
|
|
||||||
|
B 182 EXPG
|
||||||
|
58.1
|
||||||
|
48.1
|
||||||
|
|
||||||
|
B 183 EXPG
|
||||||
|
203.2
|
||||||
|
62.1
|
||||||
|
|
||||||
|
B 184 DIV
|
||||||
|
11.1
|
||||||
|
53.1
|
||||||
|
|
||||||
|
B 185 DIV
|
||||||
|
67.1
|
||||||
|
165.1
|
||||||
|
|
||||||
|
B 186 DIV
|
||||||
|
11.1
|
||||||
|
42.1
|
||||||
|
|
||||||
|
B 187 DIV
|
||||||
|
206.1
|
||||||
|
19.1
|
||||||
|
|
||||||
|
B 188 DIV
|
||||||
|
207.1
|
||||||
|
20.1
|
||||||
|
|
||||||
|
B 189 DIV
|
||||||
|
175.1
|
||||||
|
175.2
|
||||||
|
|
||||||
|
B 190 DIV
|
||||||
|
15.1
|
||||||
|
11.1
|
||||||
|
|
||||||
|
B 191 DIV
|
||||||
|
80.1
|
||||||
|
54.1
|
||||||
|
|
||||||
|
B 192 GE
|
||||||
|
210.1
|
||||||
|
45.1
|
||||||
|
P 192
|
||||||
|
0 % Error tolerance
|
||||||
|
|
||||||
|
B 193 GE
|
||||||
|
210.1
|
||||||
|
38.1
|
||||||
|
P 193
|
||||||
|
0 % Error tolerance
|
||||||
|
|
||||||
|
B 194 SOY
|
||||||
|
204.1
|
||||||
|
204.2
|
||||||
|
204.3
|
||||||
|
204.4
|
||||||
|
204.5
|
||||||
|
204.6
|
||||||
|
|
||||||
|
B 195 GT
|
||||||
|
210.1
|
||||||
|
59.1
|
||||||
|
|
||||||
|
B 196 GT
|
||||||
|
146.1
|
||||||
|
52.1
|
||||||
|
|
||||||
|
B 197 GT
|
||||||
|
204.2
|
||||||
|
41.1
|
||||||
|
|
||||||
|
B 198 INT
|
||||||
|
185.1
|
||||||
|
|
||||||
|
B 199 MTM
|
||||||
|
204.2
|
||||||
|
P 199
|
||||||
|
'Montreal' % Location
|
||||||
|
|
||||||
|
B 200 INV
|
||||||
|
193.1
|
||||||
|
|
||||||
|
B 201 INV
|
||||||
|
192.1
|
||||||
|
|
||||||
|
B 202 INV
|
||||||
|
195.1
|
||||||
|
|
||||||
|
B 203 GENGT
|
||||||
|
199.1
|
||||||
|
199.3
|
||||||
|
199.4
|
||||||
|
199.5
|
||||||
|
199.7
|
||||||
|
199.8
|
||||||
|
204.1
|
||||||
|
204.2
|
||||||
|
204.3
|
||||||
|
204.4
|
||||||
|
P 203
|
||||||
|
45.5 % Latitude
|
||||||
|
73.62 % Longitude
|
||||||
|
5 % Time zone
|
||||||
|
1 % Variance factor of the Gordon Reddy correlation
|
||||||
|
0 % Year-to-year variability
|
||||||
|
0.3 % Autocorrelation coefficient lag one
|
||||||
|
0.171 % Autocorrelation coefficient lag two
|
||||||
|
4711 % Initialisation of random number generator
|
||||||
|
2 % Maximum allowed mean temperature deviation
|
||||||
|
100 % Maximum number of iterations
|
||||||
|
|
||||||
|
B 204 CLOCK
|
||||||
|
P 204
|
||||||
|
$StartYear % Start year
|
||||||
|
$StartMonth % Start month
|
||||||
|
$StartDay % Start day
|
||||||
|
$StartHour % Start hour
|
||||||
|
$StartMinute % Start minute
|
||||||
|
$StartSecond % Start second
|
||||||
|
$EndYear % End year
|
||||||
|
$EndMonth % End month
|
||||||
|
$EndDay % End day
|
||||||
|
$EndHour % End hour
|
||||||
|
$EndMinute % End minute
|
||||||
|
$EndSecond % End second
|
||||||
|
5 % Increment
|
||||||
|
'm' % Unit
|
||||||
|
|
||||||
|
B 205 GAIN
|
||||||
|
81.1
|
||||||
|
P 205
|
||||||
|
300 % Gain factor g
|
||||||
|
|
||||||
|
B 206 GAIN
|
||||||
|
15.1
|
||||||
|
P 206
|
||||||
|
1000 % Gain factor g
|
||||||
|
|
||||||
|
B 207 GAIN
|
||||||
|
145.1
|
||||||
|
P 207
|
||||||
|
1000 % Gain factor g
|
||||||
|
|
||||||
|
B 210 TANKST
|
||||||
|
58.1
|
||||||
|
187.1
|
||||||
|
164.1
|
||||||
|
160.1
|
||||||
|
166.1
|
||||||
|
194.1
|
||||||
|
P 210
|
||||||
|
$TESCapacity % Tank volume
|
||||||
|
4 % Number of temperature nodes
|
||||||
|
$TESDiameter % Tank diameter
|
||||||
|
$Cp % Specfic heat of fluid
|
||||||
|
$Rhow % Fluid density
|
||||||
|
0 % Overall heat-loss coefficient
|
||||||
|
1 % Effective heat conductivity
|
||||||
|
30 % Initial tank temperature
|
||||||
|
|
0
exports/energy_systems/__init__.py
Normal file
0
exports/energy_systems/__init__.py
Normal file
216
exports/energy_systems/heat_pump_export.py
Normal file
216
exports/energy_systems/heat_pump_export.py
Normal file
|
@ -0,0 +1,216 @@
|
||||||
|
"""
|
||||||
|
HeatPumpExport exports heatpump coefficient into several formats
|
||||||
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
|
Copyright © 2021 Project Author Peter Yefi peteryefi@gmail.com
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
from typing import List, Tuple, Union, Dict
|
||||||
|
import yaml
|
||||||
|
from string import Template
|
||||||
|
import pandas as pd
|
||||||
|
|
||||||
|
|
||||||
|
class HeatPumpExport:
|
||||||
|
"""
|
||||||
|
Exports heat pump values as coefficients
|
||||||
|
of some defined function
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, base_path, city, output_path):
|
||||||
|
self._template_path = (base_path / 'heat_pumps/template.txt')
|
||||||
|
self._constants_path = (base_path / 'heat_pumps/constants.yaml')
|
||||||
|
# needed to compute max demand.
|
||||||
|
self._demand_path = (base_path / 'heat_pumps/demand.txt')
|
||||||
|
self._city = city
|
||||||
|
self._input_data = None
|
||||||
|
self._base_path = base_path
|
||||||
|
self._output_path = output_path
|
||||||
|
|
||||||
|
def run_insel(self, user_input: Dict, hp_model: str, data_type: str) -> None:
|
||||||
|
"""
|
||||||
|
Runs insel and write the necessary files
|
||||||
|
:param user_input: a dictionary containing the user
|
||||||
|
values necessary to run insel
|
||||||
|
:param hp_model: a string that indicates the heat
|
||||||
|
pump model to be used e.g. 012, 015
|
||||||
|
:param data_type: a string that indicates whether
|
||||||
|
insel should run for heat or cooling performance
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
self._input_data = user_input
|
||||||
|
# update input data with other data necessary to run insel
|
||||||
|
capacity_coff, comp_power_coff = self._extract_model_coff(hp_model, data_type)
|
||||||
|
self._update_input_data_with_coff(capacity_coff, comp_power_coff)
|
||||||
|
# update input data with constants
|
||||||
|
self._update_input_data_with_constants()
|
||||||
|
# update input data with input and output files for insel
|
||||||
|
self._update_input_data_with_files()
|
||||||
|
insel_file_handler = None
|
||||||
|
insel_template_handler = None
|
||||||
|
try:
|
||||||
|
# run insel
|
||||||
|
insel_template_handler = open(self._template_path, "r")
|
||||||
|
insel_template_content = insel_template_handler.read()
|
||||||
|
insel_template = Template(insel_template_content).substitute(self._input_data)
|
||||||
|
# create the insel file and write the template with substituted values into it
|
||||||
|
insel_file = (self._base_path / 'heat_pumps/dompark_heat_pump.insel')
|
||||||
|
insel_file_handler = open(insel_file, "w")
|
||||||
|
insel_file_handler.write(insel_template)
|
||||||
|
# Now run insel
|
||||||
|
self._delete_existing_output_files()
|
||||||
|
os.system('insel {}'.format(insel_file))
|
||||||
|
# Writer headers to csv output files generated by insel
|
||||||
|
self._write_insel_output_headers()
|
||||||
|
# User output
|
||||||
|
self._get_user_out_put()
|
||||||
|
except IOError as err:
|
||||||
|
print("I/O exception: {}".format(err))
|
||||||
|
finally:
|
||||||
|
insel_file_handler.close()
|
||||||
|
insel_template_handler.close()
|
||||||
|
|
||||||
|
def _write_insel_output_headers(self):
|
||||||
|
"""
|
||||||
|
Write headers to the various csv file generated by insel
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
header_data = {
|
||||||
|
self._input_data['fileOut1']: ['Year', ' Month', ' Day', 'Hour', 'Minute', 'HP Heat Output (kW)',
|
||||||
|
'HP Electricity Consumption (kW)', 'HP COP', 'TES Charging Rate (kg/s)',
|
||||||
|
'TES Discharging Rate (kg/s)', 'TES Node 1 Temperature', 'TES Node 2 Temperature',
|
||||||
|
'TES Node 3 Temperature', 'TES Node 4 Temperature', 'TES Energy Content (J)',
|
||||||
|
'TES Energy Content (kWh)', 'TES Energy Content Variation (kWh)',
|
||||||
|
'Auxiliary Heater Fuel Flow Rate (kg/s)', 'Auxiliary Heater Energy Input (kW)',
|
||||||
|
'HP Operational Cost (CAD)', 'Auxiliary Heater Operational Cost (CAD)',
|
||||||
|
'Operational CO2 Emissions of HP (g)',
|
||||||
|
'Operational CO2 Emissions of Auxiliary Heater (g)',
|
||||||
|
'Return Temperature', 'Demand (kW)'],
|
||||||
|
self._input_data['fileOut2']: ['Day', 'Operational Daily Emissions from Heat Pumps (g)',
|
||||||
|
'Operational Daily Emissions from Auxiliary Heater (g)'],
|
||||||
|
self._input_data['fileOut3']: ['Month', 'Monthly Operational Costs of Heat Pumps (CAD)',
|
||||||
|
'Monthly Operational Costs of Auxiliary Heater (CAD)'],
|
||||||
|
self._input_data['fileOut4']: ['Month', 'Monthly Fuel Consumption of Auxiliary Heater (m3)'],
|
||||||
|
self._input_data['fileOut5']: ['Month', 'Operational Monthly Emissions from Heat Pumps (g)',
|
||||||
|
'Operational Monthly Emissions from Auxiliary Heater (g)'],
|
||||||
|
self._input_data['fileOut6']: ['Day', 'Daily HP Electricity Demand (kWh)'],
|
||||||
|
self._input_data['fileOut7']: ['Day', 'Daily Operational Costs of Heat Pumps (CAD)',
|
||||||
|
'Daily Operational Costs of Auxiliary Heater (CAD)'],
|
||||||
|
self._input_data['fileOut8']: ['Month', 'Monthly HP Electricity Demand (kWh)'],
|
||||||
|
self._input_data['fileOut9']: ['Day', 'Daily Fuel Consumption of Auxiliary Heater (m3)'],
|
||||||
|
self._input_data['fileOut10']: ['Year', 'Month', 'Day', 'Hour', 'HP Electricity Demand (kWh)']
|
||||||
|
}
|
||||||
|
for file_path, header in header_data.items():
|
||||||
|
file_path = file_path.strip("'")
|
||||||
|
df = pd.read_csv(file_path, header=None, sep='\s+')
|
||||||
|
df.to_csv(file_path, header=header)
|
||||||
|
|
||||||
|
def _update_input_data_with_files(self):
|
||||||
|
"""
|
||||||
|
Updates input data for insel with some files that will
|
||||||
|
be written to after insel runs. Also specifies and input file
|
||||||
|
which is the Heating Demand (demand.txt) file
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
self._input_data["HeatingDemand"] = f"'{str(self._demand_path)}'"
|
||||||
|
self._input_data["fileOut1"] = f"'{str((self._base_path / 'heat_pumps/technical_performance.csv'))}'"
|
||||||
|
self._input_data["fileOut2"] = f"'{str((self._base_path / 'heat_pumps/system_daily_emissions.csv'))}'"
|
||||||
|
self._input_data["fileOut3"] = f"'{str((self._base_path / 'heat_pumps/monthly_operational_costs.csv'))}'"
|
||||||
|
self._input_data["fileOut4"] = f"'{str((self._base_path / 'heat_pumps/monthly_fossil_fuel_consumptions.csv'))}'"
|
||||||
|
self._input_data["fileOut5"] = f"'{str((self._base_path / 'heat_pumps/system_monthly_emissions.csv'))}'"
|
||||||
|
self._input_data["fileOut6"] = f"'{str((self._base_path / 'heat_pumps/daily_hp_electricity_demand.csv'))}'"
|
||||||
|
self._input_data["fileOut7"] = f"'{str((self._base_path / 'heat_pumps/daily_operational_costs.csv'))}'"
|
||||||
|
self._input_data["fileOut8"] = f"'{str((self._base_path / 'heat_pumps/monthly_hp_electricity_demand.csv'))}'"
|
||||||
|
self._input_data["fileOut9"] = f"'{str((self._base_path / 'heat_pumps/daily_fossil_fuel_consumption.csv'))}'"
|
||||||
|
self._input_data["fileOut10"] = f"'{str((self._base_path / 'heat_pumps/hp_hourly_electricity_demand.csv'))}'"
|
||||||
|
|
||||||
|
def _delete_existing_output_files(self):
|
||||||
|
"""
|
||||||
|
Remove existing out files generated by insel before
|
||||||
|
running insel
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
for key, file_path in self._input_data.items():
|
||||||
|
if 'fileOut' in key:
|
||||||
|
file_path = file_path.strip("'")
|
||||||
|
try:
|
||||||
|
os.remove(file_path)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _compute_max_demand(self):
|
||||||
|
"""
|
||||||
|
Retrieves the maximum demand value from
|
||||||
|
the demands text file
|
||||||
|
:return: float
|
||||||
|
"""
|
||||||
|
max_demand = -1
|
||||||
|
with open(self._demand_path) as file_handler:
|
||||||
|
for demand in file_handler.readlines():
|
||||||
|
if float(demand) > max_demand:
|
||||||
|
max_demand = float(demand)
|
||||||
|
return max_demand
|
||||||
|
|
||||||
|
def _update_input_data_with_constants(self):
|
||||||
|
with open(self._constants_path) as file:
|
||||||
|
constants_dict = yaml.load(file, Loader=yaml.FullLoader)
|
||||||
|
for key, value in constants_dict.items():
|
||||||
|
self._input_data[key] = value
|
||||||
|
# compute maximum demand. TODO: This should come from catalog in the future
|
||||||
|
max_demand = self._compute_max_demand()
|
||||||
|
# compute TESCapacity
|
||||||
|
self._input_data["TESCapacity"] = self._input_data["HoursOfStorageAtMaxDemand"] * (max_demand * 3.6) / (
|
||||||
|
(self._input_data["Cp"] / 1000) * self._input_data["TemperatureDifference"])
|
||||||
|
|
||||||
|
def _update_input_data_with_coff(self, capacity_coff: List, comp_power_coff: List):
|
||||||
|
"""
|
||||||
|
Updates the user data with coefficients derived from imports
|
||||||
|
:param capacity_coff: heat or cooling capacity coefficients
|
||||||
|
:param comp_power_coff: heat or cooling comppressor power coefficients
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
self._input_data["a1"] = capacity_coff[0]
|
||||||
|
self._input_data["a2"] = capacity_coff[1]
|
||||||
|
self._input_data["a3"] = capacity_coff[2]
|
||||||
|
self._input_data["a4"] = capacity_coff[3]
|
||||||
|
self._input_data["a5"] = capacity_coff[4]
|
||||||
|
self._input_data["a6"] = capacity_coff[5]
|
||||||
|
self._input_data["b1"] = comp_power_coff[0]
|
||||||
|
self._input_data["b2"] = comp_power_coff[1]
|
||||||
|
self._input_data["b3"] = comp_power_coff[2]
|
||||||
|
self._input_data["b4"] = comp_power_coff[3]
|
||||||
|
self._input_data["b5"] = comp_power_coff[4]
|
||||||
|
self._input_data["b6"] = comp_power_coff[5]
|
||||||
|
|
||||||
|
def _extract_model_coff(self, hp_model: str, data_type='heat') -> Union[Tuple[List, List], None]:
|
||||||
|
"""
|
||||||
|
Extracts heat pump coefficient data for a specific
|
||||||
|
model. e.g 012, 140
|
||||||
|
:param hp_model: the model type
|
||||||
|
:param data_type: indicates whether we're extracting cooling
|
||||||
|
or heating perfarmcn coefficients
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
for energy_system in self._city.energy_systems:
|
||||||
|
if energy_system.heat_pump.model == hp_model:
|
||||||
|
if data_type == 'heat':
|
||||||
|
return energy_system.heat_pump.heating_capacity_coff, energy_system.heat_pump.heating_comp_power_coff
|
||||||
|
return energy_system.heat_pump.cooling_capacity_coff, energy_system.heat_pump.cooling_comp_power_coff
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _get_user_out_put(self):
|
||||||
|
"""
|
||||||
|
Extracts monthly electricity demand and fossil fuel consumption
|
||||||
|
from output files generated by insel
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
|
||||||
|
electricity_df = pd.read_csv(self._input_data['fileOut8'].strip("'")).iloc[:, 2]
|
||||||
|
fossil_df = pd.read_csv(self._input_data['fileOut4'].strip("'")).iloc[:, 2]
|
||||||
|
|
||||||
|
data = [electricity_df, fossil_df]
|
||||||
|
df = pd.concat(data, axis=1)
|
||||||
|
df = df.append(df.agg(['sum']))
|
||||||
|
s = pd.Series(["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "Total"])
|
||||||
|
df = df.set_index([s])
|
||||||
|
df.to_csv(self._output_path)
|
||||||
|
|
40
exports/energy_systems_factory.py
Normal file
40
exports/energy_systems_factory.py
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
"""
|
||||||
|
EnergySystemsFactory exports energy systems into several formats
|
||||||
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
|
Copyright © 2020 Project Author Peter Yefi peteryefi@gmail.com
|
||||||
|
"""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
from exports.energy_systems.heat_pump_export import HeatPumpExport
|
||||||
|
|
||||||
|
|
||||||
|
class EnergySystemsExportFactory:
|
||||||
|
"""
|
||||||
|
Exports factory class for energy systems
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, city, user_input, hp_model, output_path, data_type='heat', base_path=None):
|
||||||
|
self._city = city
|
||||||
|
if base_path is None:
|
||||||
|
base_path = base_path = Path(Path(__file__).parent.parent / 'data/energy_systems')
|
||||||
|
self._base_path = base_path
|
||||||
|
self._user_input = user_input
|
||||||
|
self._hp_model = hp_model
|
||||||
|
self._data_type = data_type
|
||||||
|
self._output_path = output_path
|
||||||
|
|
||||||
|
def _export_heat_pump(self):
|
||||||
|
"""
|
||||||
|
Exports heat pump performance data as coefficients
|
||||||
|
of some objective function
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
HeatPumpExport(self._base_path, self._city, self._output_path)\
|
||||||
|
.run_insel(self._user_input, self._hp_model, self._data_type)
|
||||||
|
|
||||||
|
def export(self):
|
||||||
|
"""
|
||||||
|
Export the city given to the class using the given export type handler
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
return getattr(self, '_export_heat_pump', lambda: None)()
|
|
@ -1,26 +1,143 @@
|
||||||
"""
|
"""
|
||||||
XlsxHeatPumpParameters import the heat pump information
|
XlsxHeatPumpParameters import the heat pump information
|
||||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
Copyright © 2020 Project Author
|
Copyright © 2020 Project Author Peter Yefi peteryefi@gmail.com
|
||||||
Contributor Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
Contributor Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import pandas as pd
|
||||||
|
from typing import Dict
|
||||||
|
from city_model_structure.energy_systems.heat_pump import HeatPump
|
||||||
|
from city_model_structure.energy_system import EnergySystem
|
||||||
|
from scipy.optimize import curve_fit
|
||||||
|
import numpy as np
|
||||||
|
from typing import List
|
||||||
|
import itertools
|
||||||
|
|
||||||
|
|
||||||
class XlsxHeatPumpParameters:
|
class XlsxHeatPumpParameters:
|
||||||
"""
|
"""
|
||||||
XlsxHeatPumpParameters class
|
XlsxHeatPumpParameters class
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, city, base_path):
|
def __init__(self, city, base_path):
|
||||||
self._city = city
|
self._city = city
|
||||||
self._base_path = (base_path / 'heat_pumps/Air source.xlsx')
|
self._base_path = (base_path / 'heat_pumps/Air Source.xlsx')
|
||||||
|
|
||||||
def _read_file(self):
|
def _read_file(self) -> Dict:
|
||||||
"""
|
"""
|
||||||
reads xlsx file containing the heat pump information
|
reads xlsx file containing the 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}
|
||||||
|
|
||||||
|
cooling_data = {}
|
||||||
|
heating_data = {}
|
||||||
|
|
||||||
|
for sheet, dataframe in heat_pump_dfs.items():
|
||||||
|
if sheet == "Summary":
|
||||||
|
continue
|
||||||
|
# Remove nan rows and columns and extract cooling and heating data
|
||||||
|
# for each sheet
|
||||||
|
df = heat_pump_dfs[sheet].dropna(axis=1, how='all')
|
||||||
|
cooling_df = df.iloc[4:34, 0:8]
|
||||||
|
heating_df = df.iloc[4:29, 8:20]
|
||||||
|
|
||||||
|
# extract the data into dictionaries each sheet is a key entry in the
|
||||||
|
# dictionary
|
||||||
|
cooling_data[sheet] = {}
|
||||||
|
heating_data[sheet] = {}
|
||||||
|
i = 0
|
||||||
|
# for each sheet extract data for twout/Ta.RU temperatures. Thus, the twout
|
||||||
|
# temp is the key for the values of pf,pa,qw data
|
||||||
|
while i < 25:
|
||||||
|
cooling_data[sheet][cooling_df.iloc[i][0]] = cooling_df.iloc[i + 1:i + 4, 2:8].values.tolist()
|
||||||
|
heating_data[sheet][heating_df.iloc[i][0]] = heating_df.iloc[i + 1:i + 4, 2:8].values.tolist()
|
||||||
|
i = i + 5
|
||||||
|
# extract the last cooling data
|
||||||
|
cooling_data[sheet][cooling_df.iloc[i][0]] = cooling_df.iloc[i + 1:i + 4, 2:8].values.tolist()
|
||||||
|
return {"cooling": cooling_data, "heating": heating_data}
|
||||||
|
|
||||||
def enrich_city(self):
|
def enrich_city(self):
|
||||||
"""
|
"""
|
||||||
Enriches the city with information from file
|
Enriches the city with information from file
|
||||||
"""
|
"""
|
||||||
|
heap_pump_data = self._read_file()
|
||||||
|
for (k_cool, v_cool), (k_heat, v_heat) in \
|
||||||
|
zip(heap_pump_data["cooling"].items(), heap_pump_data["heating"].items()):
|
||||||
|
heat_pump = HeatPump()
|
||||||
|
heat_pump.model = k_cool
|
||||||
|
h_data = self._extract_heat_pump_data(v_heat)
|
||||||
|
c_data = self._extract_heat_pump_data(v_cool)
|
||||||
|
heat_pump.cooling_capacity = c_data[0]
|
||||||
|
heat_pump.cooling_comp_power = c_data[1]
|
||||||
|
heat_pump.cooling_capacity_coff = self._compute_coefficients(c_data[0], "cool")
|
||||||
|
heat_pump.cooling_comp_power_coff = self._compute_coefficients(c_data[1], "cool")
|
||||||
|
heat_pump.heating_capacity = h_data[0]
|
||||||
|
heat_pump.heating_comp_power = h_data[1]
|
||||||
|
heat_pump.heating_capacity_coff = self._compute_coefficients(h_data[0])
|
||||||
|
heat_pump.heating_comp_power_coff = self._compute_coefficients(h_data[1])
|
||||||
|
|
||||||
|
energy_system = EnergySystem('{} capacity heat pump'.format(heat_pump.model), 0, [], None)
|
||||||
|
energy_system.heat_pump = heat_pump
|
||||||
|
self._city.add_city_object(energy_system)
|
||||||
return self._city
|
return self._city
|
||||||
|
|
||||||
|
def _extract_heat_pump_data(self, heat_pump_capacity_data: Dict) -> [List, List]:
|
||||||
|
"""
|
||||||
|
Fetches a list of metric based data for heat pump for various temperature,
|
||||||
|
eg. cooling capacity data for 12 capacity heat pump
|
||||||
|
for 6,7,8,9,10 and 11 degree celsius
|
||||||
|
:param heat_pump_capacity_data: the heat pump capacity data from the
|
||||||
|
which the metric specific data is fetched: {List}
|
||||||
|
:return: List
|
||||||
|
"""
|
||||||
|
cooling_heating_capacity_data = []
|
||||||
|
compressor_power_data = []
|
||||||
|
for _, metric_data in heat_pump_capacity_data.items():
|
||||||
|
cooling_heating_capacity_data.append(metric_data[0])
|
||||||
|
compressor_power_data.append(metric_data[1])
|
||||||
|
return [cooling_heating_capacity_data, compressor_power_data]
|
||||||
|
|
||||||
|
def _compute_coefficients(self, heat_pump_data: List, data_type="heat") -> List[float]:
|
||||||
|
"""
|
||||||
|
Compute heat output and electrical demand coefficients
|
||||||
|
from heating and cooling performance data
|
||||||
|
:param heat_pump_data: a list of heat pump data. eg. cooling capacity
|
||||||
|
:param data_type: string to indicate if data is cooling performance data
|
||||||
|
or heating performance data
|
||||||
|
:return: Tuple[Dict, Dict]
|
||||||
|
"""
|
||||||
|
# Determine the recurrence of temperature values. 6 repetitions for
|
||||||
|
# cooling performance and 5 repetition for heating performance
|
||||||
|
temp_multiplier = 5 if data_type == "heat" else 6
|
||||||
|
out_temp = [25, 30, 32, 35, 40, 45] * temp_multiplier
|
||||||
|
|
||||||
|
heat_x_values = np.repeat([-5, 0, 7, 10, 15], 6)
|
||||||
|
cool_x_values = np.repeat([6, 7, 8, 9, 10, 11], 6)
|
||||||
|
x_values = heat_x_values if data_type == "heat" else cool_x_values
|
||||||
|
x_values = x_values.tolist()
|
||||||
|
# convert list of lists to one list
|
||||||
|
heat_pump_data = list(itertools.chain.from_iterable(heat_pump_data))
|
||||||
|
|
||||||
|
# Compute heat output coefficients
|
||||||
|
popt, _ = curve_fit(self._objective_function, [x_values, out_temp], heat_pump_data)
|
||||||
|
return popt.tolist()
|
||||||
|
|
||||||
|
def _objective_function(self, xdata: List, a1: float, a2: float, a3: float, a4: float, a5: float, a6: 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
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
x, y = xdata
|
||||||
|
return (a1 * x ** 2) + (a2 * x) + (a3 * x * y) + (a4 * y) + (a5 * y ** 2) + a6
|
||||||
|
|
|
@ -11,6 +11,7 @@ class EnergySystemsFactory:
|
||||||
"""
|
"""
|
||||||
EnergySystemsFactory class
|
EnergySystemsFactory class
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, handler, city, base_path=None):
|
def __init__(self, handler, city, base_path=None):
|
||||||
if base_path is None:
|
if base_path is None:
|
||||||
base_path = Path(Path(__file__).parent.parent / 'data/energy_systems')
|
base_path = Path(Path(__file__).parent.parent / 'data/energy_systems')
|
||||||
|
@ -18,7 +19,7 @@ class EnergySystemsFactory:
|
||||||
self._city = city
|
self._city = city
|
||||||
self._base_path = base_path
|
self._base_path = base_path
|
||||||
|
|
||||||
def _xlsxheatpump(self):
|
def _xlsx_heat_pump(self):
|
||||||
"""
|
"""
|
||||||
Enrich the city by using xlsx heat pump information
|
Enrich the city by using xlsx heat pump information
|
||||||
"""
|
"""
|
||||||
|
@ -30,4 +31,3 @@ class EnergySystemsFactory:
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
getattr(self, self._handler, lambda: None)()
|
getattr(self, self._handler, lambda: None)()
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,10 @@ geomeppy~=0.11.8
|
||||||
pathlib~=1.0.1
|
pathlib~=1.0.1
|
||||||
PyWavefront~=1.3.3
|
PyWavefront~=1.3.3
|
||||||
xlrd~=2.0.1
|
xlrd~=2.0.1
|
||||||
|
openpyxl~=3.0.7
|
||||||
networkx~=2.5.1
|
networkx~=2.5.1
|
||||||
parseidf~=1.0.0
|
parseidf~=1.0.0
|
||||||
ply~=3.11
|
ply~=3.11
|
||||||
rhino3dm~=7.7.0
|
rhino3dm~=7.7.0
|
||||||
|
scipy==1.7.1
|
||||||
|
PyYAML==6.0
|
61
unittests/test_energy_systems_factory.py
Normal file
61
unittests/test_energy_systems_factory.py
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
"""
|
||||||
|
Test EnergySystemsFactory and various heatpump models
|
||||||
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
|
Copyright © 2021 Project Author Peter Yefi peteryefi@gmail.com
|
||||||
|
"""
|
||||||
|
import pandas as pd
|
||||||
|
from unittest import TestCase
|
||||||
|
from imports.geometry_factory import GeometryFactory
|
||||||
|
from imports.energy_systems_factory import EnergySystemsFactory
|
||||||
|
from city_model_structure.energy_systems.heat_pump import HeatPump
|
||||||
|
from exports.energy_systems_factory import EnergySystemsExportFactory
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
class TestEnergySystemsFactory(TestCase):
|
||||||
|
"""
|
||||||
|
TestBuilding TestCase 1
|
||||||
|
"""
|
||||||
|
|
||||||
|
def setUp(self) -> None:
|
||||||
|
"""
|
||||||
|
Test setup
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
city_file = "../unittests/tests_data/C40_Final.gml"
|
||||||
|
self._output_path = "../unittests/tests_data/user_output.csv"
|
||||||
|
self._city = GeometryFactory('citygml', city_file).city
|
||||||
|
EnergySystemsFactory('xlsx heat pump', self._city).enrich()
|
||||||
|
|
||||||
|
def test_heat_pump_import(self):
|
||||||
|
self.assertIsNotNone(self._city.energy_systems, 'City has energy systems')
|
||||||
|
self.assertIsInstance(self._city.energy_systems[0].heat_pump, HeatPump)
|
||||||
|
self.assertEqual(self._city.energy_systems[0].heat_pump.model, '012')
|
||||||
|
self.assertEqual(self._city.energy_systems[len(self._city.energy_systems) - 1].heat_pump.model, '140')
|
||||||
|
|
||||||
|
def test_heat_pump_export(self):
|
||||||
|
# User defined paramenters
|
||||||
|
user_input = {
|
||||||
|
'StartYear': 2020,
|
||||||
|
'EndYear': 2021,
|
||||||
|
'MaximumHPEnergyInput': 8000,
|
||||||
|
'HoursOfStorageAtMaxDemand': 1,
|
||||||
|
'BuildingSuppTemp': 40,
|
||||||
|
'TemperatureDifference': 15,
|
||||||
|
'FuelLHV': 47100,
|
||||||
|
'FuelPrice': 0.12,
|
||||||
|
'FuelEF': 1887,
|
||||||
|
'FuelDensity': 0.717,
|
||||||
|
'HPSupTemp': 60
|
||||||
|
}
|
||||||
|
|
||||||
|
EnergySystemsExportFactory(self._city, user_input, '012', self._output_path).export()
|
||||||
|
df = pd.read_csv(self._output_path)
|
||||||
|
self.assertEqual(df.shape, (13, 3))
|
||||||
|
self.assertEqual(df.iloc[0, 1], 3045398.0)
|
||||||
|
|
||||||
|
def tearDown(self) -> None:
|
||||||
|
try:
|
||||||
|
os.remove(self._output_path)
|
||||||
|
except OSError:
|
||||||
|
pass
|
Loading…
Reference in New Issue
Block a user