Skip to content
Snippets Groups Projects
Commit 7c94789a authored by ENRI's avatar ENRI
Browse files

Merge branch 'dev'

parents 46950753 3270be81
No related branches found
No related tags found
No related merge requests found
#HP_Model
"""
Interpolated Power Calculator
Interpolated Calculator
This class processes data from a CSV file containing power-related information. It performs the following steps:
1. Data Preparation:
- Reads the CSV file into a pandas DataFrame.
- Sorts the DataFrame by 'PowerPercentage', 'sourceTemp', and 'condensationTemperature'.
- Converts relevant columns into a numpy 3D array, with (PowerPercentage, sourceTemp, condensationTemp) as coordinates.
- Assigns two values to each point in the array: 'heatingPower' and 'electricalPower'.
- Sorts the DataFrame by 'T_source_in', 'T_sink_out', and 'Q_dot_H'.
- Converts relevant columns into a numpy 3D array, with (T_source_in, T_sink_out, Q_dot_H) as coordinates.
- Assigns two values to each point in the array: 'n_comp_perc' and 'P_comp'.
2. KD-Tree Creation:
- Constructs a KD-Tree for the entire 3D array.
- Saves the KD-Tree within the class.
3. User Queries:
- Users can request power information for a specific point (given 'powerPercentage', 'sourceTemp', and 'condensationTemp').
- Choose either 'heatingPower' or 'electricalPower'.
- Users can request information for a specific point (given 'T_source_in', 'T_sink_out', and 'Q_dot_H').
- Choose either 'n_comp_perc', 'P_comp', 'COP' or 'eta_II'.
- If the requested point does not exist in the 3D array, the KD-Tree identifies the closest points.
- Interpolates values from these nearby points to estimate the requested power value.
- Interpolates values from these nearby points to estimate the requested value.
4. Interpolation Method:
- Utilizes a normalized inverse distance weighting (IDW) technique.
"""
import enum
import pandas as pd
from scipy.spatial import cKDTree
class PowerTypes(enum.Enum):
N_COMP_PERC = enum.auto()
ELECTRICAL = enum.auto()
class HeatPump:
# ====================================================================================================
def __init__(self, csvFile: str, mul100: bool = False, verbose: bool = False) -> None:
def __init__(self, csvFile: str, mul1000: bool = False, verbose: bool = False) -> None:
"""
Initializes the class by reading a CSV file and creating a KD-Tree.
Args:
csvFile (str): Path to the CSV file containing the data points. The CSV file should have the following headers (in order):
- PowerPercentage
- SourceTemp
- CondensationTemp
- HeatingPower
- ElectricalPower
mul100 (bool, optional): When True, the PowerPercentage values are multiplied by 100. Defaults to False.
- n_comp_perc
- T_source_in
- T_sink_out
- Q_dot_H
- P_comp
mul1000 (bool, optional): When True, the Q_dot_H values are converted from kW to W. Defaults to False.
verbose (bool, optional): If True, feedback messages are printed during initialization. Defaults to False.
Returns:
None
"""
self.__readCSV(csvFile, mul100, verbose)
self.__readCSV(csvFile, mul1000, verbose)
self.__createKDTree(verbose)
# ====================================================================================================
def __readCSV(self, csvFile: str, mul100: bool = False, verbose: bool = False) -> None:
def __readCSV(self, csvFile: str, mul1000: bool = False, verbose: bool = False) -> None:
"""
Reads and sorts the CSV file into a pandas DataFrame. The DataFrame is then extracted into NumPy n-dimensional arrays.
Args:
csvFile (str): Path to the CSV file containing the data points. The CSV file should have the following headers (in order):
- PowerPercentage
- SourceTemp
- CondensationTemp
- HeatingPower
- ElectricalPower
mul100 (bool, optional): When True, the PowerPercentage values are multiplied by 100. Defaults to False.
- n_comp_perc
- T_source_in
- T_sink_out
- Q_dot_H
- P_comp
mul1000 (bool, optional): When True, the Q_dot_H values are converted from kW to W. Defaults to False.
verbose (bool, optional): If True, feedback messages are printed during initialization. Defaults to False.
Returns:
......@@ -78,15 +83,15 @@ def __readCSV(self, csvFile: str, mul100: bool = False, verbose: bool = False) -
self.dataframe = pd.read_csv(csvFile, sep=';')
# Sort the DataFrame by specified columns and reset the index
self.dataframe = self.dataframe.sort_values(by=['PowerPercentage', 'SourceTemp', 'CondensationTemp']).reset_index(drop=True)
self.dataframe = self.dataframe.sort_values(by=['T_source_in', 'T_sink_out', 'Q_dot_H']).reset_index(drop=True)
if mul100:
self.dataframe['PowerPercentage'] *= 100
if mul1000:
self.dataframe['Q_dot_H'] *= 1000
# Extract relevant columns
self.coords = self.dataframe[['PowerPercentage', 'SourceTemp', 'CondensationTemp']].values
self.heatingPower = self.dataframe["HeatingPower"].values
self.electricalPower = self.dataframe["ElectricalPower"].values
self.coords = self.dataframe[['T_source_in', 'T_sink_out', 'Q_dot_H']].values
self.powerPercentage = self.dataframe["n_comp_perc"].values
self.electricalPower = self.dataframe["P_comp"].values
if verbose:
print(f"The CSV file '{csvFile}' has been read.")
......@@ -113,26 +118,26 @@ def __createKDTree(self, verbose: bool = False) -> None:
# ====================================================================================================
def __getPower(self, powerPercentage: float, sourceTemp: float, condensationTemp: float, K: int = 3, type: str = "heating") -> float:
def __getPowerValue(self, T_source_in: float, T_sink_out: float, Q_dot_H: float, K: int = 3, type: PowerTypes = PowerTypes.ELECTRICAL) -> float:
"""
Calculates the interpolated power value at the specified coordinate point.
Calculates the interpolated power or power related value at the specified coordinate point.
Args:
powerPercentage (float): Power percentage value.
sourceTemp (float): Source temperature.
condensationTemp (float): Condensation temperature.
T_source_in (float): Source temerature (in).
T_sink_out (float): Sink temperature (out).
Q_dot_H (float): Heating power.
K (int, optional): Number of neighbors to consider. Defaults to 3.
type (str, optional): Type of power ('heating' or 'electrical'). Defaults to 'heating'.
type (PowerTypes, optional): Type of power value. Defaults to ELECTRICAL.
Returns:
float: Interpolated power value.
"""
if type not in ["heating", "electrical"]:
print(f"Invalid type '{type}' selected. Please choose 'heating' or 'electrical'.")
if type not in PowerTypes:
print("Invalid type selected.")
return 0
point = (powerPercentage, sourceTemp, condensationTemp)
point = (T_source_in, T_sink_out, Q_dot_H)
distances, indices = self.kdTree.query(point, k=K)
totalDistance = sum(distances)
......@@ -145,46 +150,85 @@ def __getPower(self, powerPercentage: float, sourceTemp: float, condensationTemp
weights = [(totalDistance - d) / (totalDistance * (K - 1)) for d in distances]
# Interpolate values
interpolatedPower = 0
interpolatedPowerValue = 0
for index in range(K):
nearbyPower = self.heatingPower[indices[index]] if type == "heating" else self.electricalPower[indices[index]]
interpolatedPower += weights[index] * nearbyPower # Assuming each point has a 'value' attribute
nearbyPowerValue = self.powerPercentage[indices[index]] if type == PowerTypes.N_COMP_PERC else self.electricalPower[indices[index]]
interpolatedPowerValue += weights[index] * nearbyPowerValue # Assuming each point has a 'value' attribute
return interpolatedPower
return interpolatedPowerValue
# ====================================================================================================
# ====================================================================================================
def getHeatingPower(self, powerPercentage: float, sourceTemp: float, condensationTemp: float, K: int = 3) -> float:
def getN_comp_perc(self, T_source_in: float, T_sink_out: float, Q_dot_H: float, K: int = 3) -> float:
"""
Calculates the interpolated heating power value at the specified coordinate point.
Calculates the interpolated compressor rpm-percentage at the specified coordinate point.
Args:
powerPercentage (float): Power percentage value.
sourceTemp (float): Source temperature.
condensationTemp (float): Condensation temperature.
T_source_in (float): Source temerature (in).
T_sink_out (float): Sink temperature (out).
Q_dot_H (float): Heating power.
K (int, optional): Number of neighbors to consider. Defaults to 3.
Returns:
float: Interpolated heating power value.
float: Interpolated compressor rpm-percentage value.
"""
return self.__getPower(powerPercentage, sourceTemp, condensationTemp, K, "heating")
return self.__getPowerValue(T_source_in, T_sink_out, Q_dot_H, K, PowerTypes.N_COMP_PERC)
# ====================================================================================================
def getElectricalPower(self, powerPercentage: float, sourceTemp: float, condensationTemp: float, K: int = 3) -> float:
def getElectricalPower(self, T_source_in: float, T_sink_out: float, Q_dot_H: float, K: int = 3) -> float:
"""
Calculates the interpolated electrical power value at the specified coordinate point.
Args:
powerPercentage (float): Power percentage value.
sourceTemp (float): Source temperature.
condensationTemp (float): Condensation temperature.
T_source_in (float): Source temerature (in).
T_sink_out (float): Sink temperature (out).
Q_dot_H (float): Heating power.
K (int, optional): Number of neighbors to consider. Defaults to 3.
Returns:
float: Interpolated electrical power value.
"""
return self.__getPower(powerPercentage, sourceTemp, condensationTemp, K, "electrical")
return self.__getPowerValue(T_source_in, T_sink_out, Q_dot_H, K)
# ====================================================================================================
def getCOP(self, T_source_in: float, T_sink_out: float, Q_dot_H: float, K: int = 3) -> float:
"""
Calculates the interpolated COP value at the specified coordinate point.
Args:
T_source_in (float): Source temerature (in).
T_sink_out (float): Sink temperature (out).
Q_dot_H (float): Heating power.
K (int, optional): Number of neighbors to consider. Defaults to 3.
Returns:
float: Interpolated COP value.
"""
return (Q_dot_H / self.getElectricalPower(T_source_in, T_sink_out, Q_dot_H, K))
# ====================================================================================================
def getEta_II(self, T_source_in: float, T_sink_out: float, Q_dot_H: float, K: int = 3) -> float:
"""
Calculates the interpolated second law efficiency value at the specified coordinate point.
Args:
T_source_in (float): Source temerature (in).
T_sink_out (float): Sink temperature (out).
Q_dot_H (float): Heating power.
K (int, optional): Number of neighbors to consider. Defaults to 3.
Returns:
float: Interpolated second law efficiency value.
"""
COP = self.getCOP(T_source_in, T_sink_out, Q_dot_H, K)
COP_Carnot = (T_sink_out + 273.15) / (T_sink_out - T_source_in) # in Kelvin!
return (COP / COP_Carnot)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment