Completed
Pull Request — master (#1)
by Uwe
04:23 queued 03:18
created

scenario_builder.cop_precalc.calculate_COP()   A

Complexity

Conditions 1

Size

Total Lines 25
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 9
dl 0
loc 25
rs 9.95
c 0
b 0
f 0
cc 1
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
    artifact = cops_aggregated < 0
173
    cops_aggregated[limit] = 7
174
    cops_aggregated[artifact] = 7
175
176
    return cops_aggregated
177
178
179
def calculate_mixed_cops_by_nuts3(year, name, share_ashp=0.7, share_gshp=0.3, quality_grade=0.4):
180
    """
181
    Parameters
182
    ----------
183
    year: int
184
        Year of interest
185
    name: string
186
        Name of the analysed set
187
    share_ashp: Float
188
        Share of air sourced heat pumps
189
    share_gshp: Float
190
        Share of ground sourced heat pumps
191
    quality_grade : float
192
        Ambient temperature
193
194
    Returns: 2 DataFrames
195
        DataFrames containing mean COP series for each German NUTS3 region
196
    -------
197
    """
198
199
    fn_pattern = "mixed_cops_by_nuts3_{name}_{year}.csv".format(name=name, year=year)
200
    fn_pattern_water = "cops_by_nuts3_{name}_{year}_water.csv".format(name=name, year=year)
201
    fn = os.path.join(cfg.get("paths", "cop_precalc"), fn_pattern)
202
    fn_water = os.path.join(cfg.get("paths", "cop_precalc"), fn_pattern_water)
203
204
    if not os.path.isfile(fn):
205
        share_ashp = share_ashp
206
        share_gshp = share_gshp
207
        quality_grade = quality_grade
208
        t_ground = pd.Series(np.ones(8760)*10)
209
210
        outfile = os.path.join(cfg.get("paths", "cop_precalc"), "average_temp_by_nuts3_{year}.csv".format(year=year))
211
212
        if not os.path.isfile(outfile):
213
214
            # Load NUTS3-geometries
215
            nuts3 = data.database_shapes()
216
            nuts3 = nuts3.to_crs(crs=4326)
217
218
            # Get average temperature per NUTS3, coastdat only available until 2014
219
            coastdat.spatial_average_weather(year, nuts3, 'temp_air', 'deTemp', outfile=outfile)
220
            NUTS3_temp = pd.read_csv(outfile)
221
            NUTS3_temp.drop('Unnamed: 0', axis='columns', inplace=True)
222
223
        else:
224
            NUTS3_temp = pd.read_csv(outfile)
225
            NUTS3_temp.drop('Unnamed: 0', axis='columns', inplace=True)
226
227
        # Create empty DataFrames
228
        COP_NUTS3 = pd.DataFrame(index=pd.date_range('1/1/'+str(year), periods=8760, freq='H'),
229
                                 columns=NUTS3_temp.columns)
230
        COP_NUTS3_water = pd.DataFrame(index=pd.date_range('1/1/'+str(year), periods=8760, freq='H'),
231
                                       columns=NUTS3_temp.columns)
232
233
        # Loop through NUTS3-regions and calculate mixed COP for each region
234
        for r in COP_NUTS3.columns:
235
            tmp_cop = calculate_mixed_COPS_per_region(NUTS3_temp[r]-273.15, t_ground, quality_grade=quality_grade,
236
                                                      share_ashp=share_ashp, share_gshp=share_gshp)
237
            tmp_cop.set_index(COP_NUTS3.index, inplace=True)
238
            COP_NUTS3[r] = tmp_cop['COP_mean']
239
            COP_NUTS3_water[r] = tmp_cop['COPwater_air']* share_ashp + tmp_cop['COPwater_ground'] * share_gshp
240
241
        COP_NUTS3.to_csv(fn)
242
        COP_NUTS3_water.to_csv(fn_water)
243
244
    else:
245
        COP_NUTS3 = pd.read_csv(fn)
246
        COP_NUTS3_water = pd.read_csv(fn_water)
247
248
    return COP_NUTS3, COP_NUTS3_water
249
250
251
def aggregate_COP_by_region(regions, COP):
252
    mean_COP = pd.DataFrame(columns=regions.index)
253
    #mean_COP_water = pd.DataFrame(columns=regions.index)
254
255
    nuts3_list = demand_disaggregator.get_nutslist_for_regions(regions)
256
257
    for zone in regions.index:
258
        idx = nuts3_list.loc[zone]["nuts"]
259
        mean_COP[zone] = COP[idx].mean(axis=1)
260
        #mean_COP_water[zone] = COP_water[idx].mean(axis=1)
261
262
    return mean_COP
263
264
265
def get_hp_timeseries(heat_profile, cop, E_el):
266
    cop.index = heat_profile.index
267
268
    for Q_rated in range(0,10000000,1000):
269
        heat_hp = Q_rated * cop * heat_profile
270
        elc_hp = heat_hp / cop
271
272
        if elc_hp.sum() > E_el:
273
            break
274
275
    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 268 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 268 is not entered. Are you sure this can never be the case?
Loading history...
276