Completed
Push — master ( 783fd3...8a64e3 )
by
unknown
21:20
created

scenario_builder.cop_precalc.get_hp_timeseries()   A

Complexity

Conditions 3

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 11
rs 10
c 0
b 0
f 0
cc 3
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, demand_disaggregator
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
248
249
def aggregate_COP_by_region(regions, COP):
250
    mean_COP = pd.DataFrame(columns=regions.index)
251
    #mean_COP_water = pd.DataFrame(columns=regions.index)
252
253
    nuts3_list = demand_disaggregator.get_nutslist_for_regions(regions)
254
255
    for zone in regions.index:
256
        idx = nuts3_list.loc[zone]["nuts"]
257
        mean_COP[zone] = COP[idx].mean(axis=1)
258
        #mean_COP_water[zone] = COP_water[idx].mean(axis=1)
259
260
    return mean_COP
261
262
263
def get_hp_timeseries(heat_profile, cop, E_el):
264
    cop.index = heat_profile.index
265
266
    for Q_rated in range(0,10000000,1000):
267
        heat_hp = Q_rated * cop * heat_profile
268
        elc_hp = heat_hp / cop
269
270
        if elc_hp.sum() > E_el:
271
            break
272
273
    return elc_hp, heat_hp
0 ignored issues
show
introduced by
The variable heat_hp does not seem to be defined in case the for loop on line 266 is not entered. Are you sure this can never be the case?
Loading history...
introduced by
The variable elc_hp does not seem to be defined in case the for loop on line 266 is not entered. Are you sure this can never be the case?
Loading history...
274