Completed
Push — master ( 3b218c...f838a5 )
by
unknown
02:59
created

calculate_dynamic_COP()   A

Complexity

Conditions 2

Size

Total Lines 36
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 15
dl 0
loc 36
rs 9.65
c 0
b 0
f 0
cc 2
nop 3
1
import os
2
import oemof.thermal.compression_heatpumps_and_chillers as cmpr_hp_chiller
3
import pandas as pd
4
import numpy as np
5
from disaggregator import data
6
from reegis import coastdat
7
from reegis import config as cfg
8
9
10
def flow_temperature_dependent_on_ambient(t_max, t_min, t_amb):
11
    """
12
    Parameters
13
    ----------
14
    t_max : int
15
        Maximum flow temperature of heating system
16
    t_min : int
17
        Minimum flow temperature of heating system
18
    t_amb : pd.Series
19
        Ambient temperature
20
21
    Returns: list
22
        List containing flow temperature depending on heatload/ambient temperature
23
    -------
24
    """
25
26
    delta_t_flow = t_max - t_min
27
    delta_t_amb = 30
28
    T_flow = [t_max - (delta_t_flow/delta_t_amb) * i for i in range(31)]
29
    T_round = np.round(t_amb)
30
31
    t_ind = np.zeros(shape=(len(t_amb)))
32
    tvl = np.zeros(shape=(len(t_amb)))  # Vorlauftemperatur
33
    for i in range(len(t_amb)):
34
        if T_round[i] < -14:
35
            t_ind[i] = 1
36
        elif T_round[i] >= -14 and T_round[i] < 0:
37
            t_ind[i] = abs(15 + T_round[i])  # nimm erste 15 Stellen bei -10 bis 0°C
38
        elif T_round[i] >= 0:
39
            t_ind[i] = min(31, 16 + T_round[i])
40
        tvl[i] = int(max(t_min, T_flow[int(t_ind[i] - 1)]))
41
42
    tvl = list(tvl)
43
44
    return tvl
45
46
47
def calculate_COP(t_flow, t_low, quality_grade):
48
    """
49
    Parameters
50
    ----------
51
    t_flow : int
52
        Maximum flow temperature of heating system
53
    t_low : Series
54
        Minimum flow temperature of heating system
55
    quality_grade : float
56
        Ambient temperature
57
58
    Returns: list
59
        List containing flow temperature depending on heatload/ambient temperature
60
    -------
61
    """
62
63
    cops = cmpr_hp_chiller.calc_cops(
64
        temp_high=list([t_flow]),
65
        temp_low=t_low,
66
        quality_grade=quality_grade,
67
        mode='heat_pump',
68
        temp_threshold_icing=2,
69
        factor_icing=0.8)
70
71
    return cops
72
73
74
def calculate_dynamic_COP(t_flow, t_low, quality_grade):
75
    r"""
76
    This function calculates COPs of a heatpump. Both, the flow temperature and the heat source must be given
77
    as a timeseries and can very for each timestep.
78
79
    Parameters
80
    ----------
81
    t_flow : Series
82
        Flow temperature series
83
    t_low : Series
84
        Heat source of heatpump
85
    quality_grade : float
86
        Carnot efficiency factor of heat pump
87
88
    Returns: Series
89
        Series containing COPs
90
    -------
91
    """
92
    cops = []
93
    for i in range(0, len(t_flow)):
94
        tmp_high = list([t_flow[i]])
95
        tmp_low = list([t_low[i]])
96
97
        cop = cmpr_hp_chiller.calc_cops(
98
            temp_high=tmp_high,
99
            temp_low=tmp_low,
100
            quality_grade=quality_grade,
101
            mode='heat_pump',
102
            temp_threshold_icing=2,
103
            factor_icing=0.8)
104
105
        cops.append(cop[0])
106
107
    cops = pd.Series(cops)
108
109
    return cops
110
111
112
def calculate_mixed_COPS_per_region(t_amb, t_ground, quality_grade, share_ashp=0.7, share_gshp=0.3):
113
    """
114
    Parameters
115
    ----------
116
    t_amb : Series
117
        Ambient temperature
118
    t_ground : Series
119
        Ground temperature for GSHP
120
    quality_grade : float
121
        Ambient temperature
122
    share_ashp: Float
123
        Share of air sourced heat pumps
124
    share_gshp: Float
125
        Share of ground sourced heat pumps
126
127
    Returns: DataFrame
128
        DataFrame containing some COP series
129
    -------
130
    """
131
132
    t_flow = dict(high = 75, medium=55, low = 40)
133
134
    # Calculate flow temperature for different temperature levels
135
    tvl75 = flow_temperature_dependent_on_ambient(t_flow['high'], 50, t_amb)
136
    tvl50 = flow_temperature_dependent_on_ambient(t_flow['medium'], 30 , t_amb)
137
    tvl35 = flow_temperature_dependent_on_ambient(t_flow['low'], 30 , t_amb)
138
139
    # Calculate COPs for air sourced heat pump
140
    cop75_ASHP = calculate_dynamic_COP(tvl75, t_amb, quality_grade)
141
    cop50_ASHP = calculate_dynamic_COP(tvl50, t_amb, quality_grade)
142
    cop35_ASHP = calculate_dynamic_COP(tvl35, t_amb, quality_grade)
143
    copwater_ASHP = calculate_dynamic_COP(np.ones(shape=8760)*50, t_amb, quality_grade)
144
145
    # Calculate COPs for ground sourced heat pump
146
    cop75_GSHP = calculate_dynamic_COP(tvl75, t_ground, quality_grade)
147
    cop50_GSHP = calculate_dynamic_COP(tvl50, t_ground, quality_grade)
148
    cop35_GSHP = calculate_dynamic_COP(tvl35, t_ground, quality_grade)
149
    copwater_GSHP = calculate_dynamic_COP(np.ones(shape=8760)*50, t_ground, quality_grade)
150
151
    cops_aggregated = pd.DataFrame(columns=['COP35_air', 'COP50_air', 'COP75_air', 'COP35_ground', 'COP50_ground',
152
                                            'COP75_ground', 'COPwater_air', 'COPwater_ground','COP_mean' ])
153
154
    # Write COP-Series to DataFrame
155
    cops_aggregated['COP35_air'] = cop35_ASHP
156
    cops_aggregated['COP50_air'] = cop50_ASHP
157
    cops_aggregated['COP75_air'] = cop75_ASHP
158
    cops_aggregated['COP35_ground'] = cop35_GSHP
159
    cops_aggregated['COP50_ground'] = cop50_GSHP
160
    cops_aggregated['COP75_ground'] = cop75_GSHP
161
    cops_aggregated['COPwater_air'] = copwater_ASHP
162
    cops_aggregated['COPwater_ground'] = copwater_GSHP
163
164
    # Calculate mean COP and add it to DataFrame
165
    cop_air_mean = (cop35_ASHP + cop50_ASHP + cop75_ASHP) / 3
166
    cop_ground_mean = (cop35_GSHP + cop50_GSHP + cop75_GSHP) / 3
167
    cop_mean = share_ashp * cop_air_mean + share_gshp * cop_ground_mean
168
    cops_aggregated['COP_mean'] = cop_mean
169
170
    # Limit COP to 7
171
    limit = cops_aggregated >= 7
172
    cops_aggregated[limit] = 7
173
174
    return cops_aggregated
175
176
177
def calculate_mixed_cops_by_nuts3(year, name, share_ashp=0.7, share_gshp=0.3, quality_grade=0.4):
178
    """
179
    Parameters
180
    ----------
181
    year: int
182
        Year of interest
183
    name: string
184
        Name of the analysed set
185
    share_ashp: Float
186
        Share of air sourced heat pumps
187
    share_gshp: Float
188
        Share of ground sourced heat pumps
189
    quality_grade : float
190
        Ambient temperature
191
192
    Returns: 2 DataFrames
193
        DataFrames containing mean COP series for each German NUTS3 region
194
    -------
195
    """
196
197
    fn_pattern = "mixed_cops_by_nuts3_{name}_{year}.csv".format(name=name, year=year)
198
    fn_pattern_water = "cops_by_nuts3_{name}_{year}_water.csv".format(name=name, year=year)
199
    fn = os.path.join(cfg.get("paths", "cop_precalc"), fn_pattern)
200
    fn_water = os.path.join(cfg.get("paths", "cop_precalc"), fn_pattern_water)
201
202
    if not os.path.isfile(fn):
203
        share_ashp = share_ashp
204
        share_gshp = share_gshp
205
        quality_grade = quality_grade
206
        t_ground = pd.Series(np.ones(8760)*10)
207
208
        outfile = os.path.join(cfg.get("paths", "cop_precalc"), "average_temp_by_nuts3_{year}.csv".format(year=year))
209
210
        if not os.path.isfile(outfile):
211
212
            # Load NUTS3-geometries
213
            nuts3 = data.database_shapes()
214
            nuts3 = nuts3.to_crs(crs=4326)
215
216
            # Get average temperature per NUTS3, coastdat only available until 2014
217
            coastdat.spatial_average_weather(year, nuts3, 'temp_air', 'deTemp', outfile=outfile)
218
            NUTS3_temp = pd.read_csv(outfile)
219
            NUTS3_temp.drop('Unnamed: 0', axis='columns', inplace=True)
220
221
        else:
222
            NUTS3_temp = pd.read_csv(outfile)
223
            NUTS3_temp.drop('Unnamed: 0', axis='columns', inplace=True)
224
225
        # Create empty DataFrames
226
        COP_NUTS3 = pd.DataFrame(index=pd.date_range('1/1/'+str(year), periods=8760, freq='H'),
227
                                 columns=NUTS3_temp.columns)
228
        COP_NUTS3_water = pd.DataFrame(index=pd.date_range('1/1/'+str(year), periods=8760, freq='H'),
229
                                       columns=NUTS3_temp.columns)
230
231
        # Loop through NUTS3-regions and calculate mixed COP for each region
232
        for r in COP_NUTS3.columns:
233
            tmp_cop = calculate_mixed_COPS_per_region(NUTS3_temp[r]-273.15, t_ground, quality_grade=quality_grade,
234
                                                      share_ashp=share_ashp, share_gshp=share_gshp)
235
            tmp_cop.set_index(COP_NUTS3.index, inplace=True)
236
            COP_NUTS3[r] = tmp_cop['COP_mean']
237
            COP_NUTS3_water[r] = tmp_cop['COPwater_air']* share_ashp + tmp_cop['COPwater_ground'] * share_gshp
238
239
        COP_NUTS3.to_csv(fn)
240
        COP_NUTS3_water.to_csv(fn_water)
241
242
    else:
243
        COP_NUTS3 = pd.read_csv(fn)
244
        COP_NUTS3_water = pd.read_csv(fn_water)
245
246
    return COP_NUTS3, COP_NUTS3_water
247