Skip to content

Commit 857721d

Browse files
committed
Merge branch 'features/tools' into features/tests
Conflicts: doc/modules.rst windpowerlib/density.py windpowerlib/modelchain.py
2 parents ee26418 + f15e863 commit 857721d

File tree

4 files changed

+77
-84
lines changed

4 files changed

+77
-84
lines changed

doc/modules.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ Additional functions used in the windpowerlib.
105105
:toctree: temp/
106106

107107
tools.smallest_difference
108+
tools.linear_extra_interpolation
108109

109110

110111
Example

windpowerlib/density.py

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -59,53 +59,6 @@ def temperature_gradient(temp_air, temp_height, hub_height):
5959
return temp_air - 0.0065 * (hub_height - temp_height)
6060

6161

62-
def temperature_interpol(temp_air_1, temp_air_2,
63-
temp_air_height_1, temp_air_height_2, hub_height):
64-
r"""
65-
Calculates the temperature at hub height by inter- or extrapolation.
66-
67-
This function is carried out when the parameter `temperature_model` of an
68-
instance of the :class:`~.modelchain.ModelChain` class
69-
is 'interpolation'.
70-
71-
Parameters
72-
----------
73-
temp_air_1 : pandas.Series or numpy.array
74-
Air temperature.
75-
temp_air_2 : pandas.Series or numpy.array
76-
Second air temperature for interpolation.
77-
temp_air_height_1 : float
78-
Height for which the parameter `temp_air_1` applies.
79-
temp_air_height_2 : float
80-
Height for which the parameter `temp_air_2` applies.
81-
hub_height : float
82-
Hub height of wind turbine in m.
83-
84-
Returns
85-
-------
86-
pandas.Series or numpy.array
87-
Temperature at hub height.
88-
89-
Notes
90-
-----
91-
92-
The following equation is used:
93-
94-
.. math:: T_{hub} = (T_2 - T_1) / (h_2 - h_1) * (h_{hub} - h_1) + T_1
95-
96-
with:
97-
T: temperature, h: height
98-
99-
Assumptions:
100-
101-
* linear temperature gradient
102-
103-
"""
104-
return ((temp_air_2 - temp_air_1) /
105-
(temp_air_height_2 - temp_air_height_1) *
106-
(hub_height - temp_air_height_1) + temp_air_1)
107-
108-
10962
def rho_barometric(pressure, pressure_height, hub_height, temp_hub):
11063
r"""
11164
Calculates the density of air at hub height using the barometric height

windpowerlib/modelchain.py

Lines changed: 6 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,6 @@ class ModelChain(object):
3131
Parameter to define which model to use to calculate the density of air
3232
at hub height. Valid options are 'barometric' and 'ideal_gas'.
3333
Default: 'barometric'.
34-
temperature_model : string
35-
Parameter to define which model to use to calculate the temperature at
36-
hub height. Valid options are 'gradient' and 'interpolation'.
37-
Default: 'gradient'.
3834
power_output_model : string
3935
Parameter to define which model to use to calculate the turbine power
4036
output. Valid options are 'cp_values' and 'p_values'.
@@ -63,10 +59,6 @@ class ModelChain(object):
6359
Parameter to define which model to use to calculate the density of air
6460
at hub height. Valid options are 'barometric' and 'ideal_gas'.
6561
Default: 'barometric'.
66-
temperature_model : string
67-
Parameter to define which model to use to calculate the temperature at
68-
hub height. Valid options are 'gradient' and 'interpolation'.
69-
Default: 'gradient'.
7062
power_output_model : string
7163
Parameter to define which model to use to calculate the turbine power
7264
output. Valid options are 'cp_values' and 'p_values'.
@@ -90,8 +82,7 @@ class ModelChain(object):
9082
... 'd_rotor': 127,
9183
... 'wind_conv_type': 'ENERCON E 126 7500'}
9284
>>> e126 = wind_turbine.WindTurbine(**enerconE126)
93-
>>> modelchain_data = {'rho_model': 'ideal_gas',
94-
... 'temperature_model': 'interpolation'}
85+
>>> modelchain_data = {'rho_model': 'ideal_gas'}
9586
>>> e126_md = modelchain.ModelChain(e126, **modelchain_data)
9687
>>> print(e126.d_rotor)
9788
127
@@ -102,7 +93,6 @@ def __init__(self, wind_turbine,
10293
obstacle_height=0,
10394
wind_model='logarithmic',
10495
rho_model='barometric',
105-
temperature_model='gradient',
10696
power_output_model='p_values',
10797
density_corr=False,
10898
hellman_exp=None):
@@ -111,7 +101,6 @@ def __init__(self, wind_turbine,
111101
self.obstacle_height = obstacle_height
112102
self.wind_model = wind_model
113103
self.rho_model = rho_model
114-
self.temperature_model = temperature_model
115104
self.power_output_model = power_output_model
116105
self.density_corr = density_corr
117106
self.hellman_exp = hellman_exp
@@ -123,16 +112,13 @@ def rho_hub(self, weather, data_height):
123112
124113
The density is calculated using the method specified by the parameter
125114
`rho_model`. Previous to the calculation of density the temperature at
126-
hub height is calculated using the method specified by the parameter
127-
`temperature_model`.
115+
hub height is calculated using a linear temperature gradient.
128116
129117
Parameters
130118
----------
131119
weather : DataFrame or Dictionary
132120
Containing columns or keys with timeseries for temperature
133-
`temp_air` in K and pressure `pressure` in Pa, as well as
134-
optionally the temperature `temp_air_2` in K at a different height
135-
for interpolation.
121+
`temp_air` in K and pressure `pressure` in Pa.
136122
If a Dictionary is used the data inside the dictionary has to be of
137123
the types pandas.Series or numpy.array.
138124
data_height : Dictionary
@@ -161,25 +147,11 @@ def rho_hub(self, weather, data_height):
161147
logging.debug('Using given temperature at hub height.')
162148
temp_hub = temp_air_closest
163149
# Calculation of temperature in K at hub height.
164-
elif self.temperature_model == 'gradient':
150+
else:
165151
logging.debug('Calculating temperature using a temp. gradient.')
166152
temp_hub = density.temperature_gradient(
167153
temp_air_closest, temp_air_height,
168154
self.wind_turbine.hub_height)
169-
elif self.temperature_model == 'interpolation':
170-
try:
171-
logging.debug('Calculating temperature using interpolation.')
172-
temp_hub = density.temperature_interpol(
173-
weather['temp_air'], weather['temp_air_2'],
174-
data_height['temp_air'], data_height['temp_air_2'],
175-
self.wind_turbine.hub_height)
176-
except TypeError:
177-
raise KeyError("No 'temp_air_2' in `weather`, but needed " +
178-
"for interpolation.")
179-
else:
180-
raise ValueError("'{0}' is an invalid value.".format(
181-
self.temperature_model) + "`temperature_model` " +
182-
"must be 'gradient' or 'interpolation'.")
183155
# Calculation of density in kg/m³ at hub height
184156
if self.rho_model == 'barometric':
185157
logging.debug('Calculating density using barometric height eq.')
@@ -333,8 +305,8 @@ def run_model(self, weather, data_height):
333305
Containing columns or keys with the timeseries for wind speed
334306
`v_wind` in m/s, roughness length `z0` in m, temperature
335307
`temp_air` in K and pressure `pressure` in Pa, as well as
336-
optionally wind speed `v_wind_2` in m/s and temperature
337-
`temp_air_2` in K at different height for interpolation.
308+
optionally wind speed `v_wind_2` in m/s in K at different height
309+
for interpolation.
338310
If a Dictionary is used the data inside the dictionary has to be of
339311
the types pandas.Series or numpy.array.
340312
data_height : Dictionary

windpowerlib/tools.py

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
55
"""
66

7+
import numpy as np
8+
9+
710
__copyright__ = "Copyright oemof developer group"
811
__license__ = "GPLv3"
912

@@ -28,14 +31,14 @@ def smallest_difference(value_1, value_2, comp_value, corresp_1, corresp_2):
2831
Second value for comparison.
2932
comp_value : float
3033
Comparative value.
31-
corresp_1 : float
34+
corresp_1 : pd.Series or np.array or float
3235
Corresponding value to `value_1`.
33-
corresp_2 : float
36+
corresp_2 : pd.Series or np.array or float
3437
Corresponding value to `value_2`.
3538
3639
Returns
3740
-------
38-
Tuple(float, float)
41+
Tuple(float, pd.Series or np.array or float)
3942
Value closer to comparing value as float and its corresponding value as
4043
float.
4144
@@ -54,3 +57,67 @@ def smallest_difference(value_1, value_2, comp_value, corresp_1, corresp_2):
5457
else:
5558
corresp_value = corresp_2
5659
return (closest_value, corresp_value)
60+
61+
62+
def linear_extra_interpolation(data_frame, requested_height, column_name):
63+
r"""
64+
Inter- or extrapolates between the values of a data frame.
65+
66+
This function can for example be used for the interpolation of a wind
67+
speed, density or temperature.
68+
69+
Parameters
70+
----------
71+
data_frame : DataFrame
72+
Indices are the values between which will be interpolated or from which
73+
will be extrapolated, the corresponding values are in the column
74+
specified by `column_name` and they can be floats, pd.Series or
75+
np.arrays.
76+
requested_height : float
77+
Height for which the interpolation takes place (e.g. hub height of wind
78+
turbine).
79+
column_name : string
80+
Name of the column in the DataFrame `data_frame` that contains the
81+
correponding values.
82+
83+
Returns
84+
-------
85+
interpolant : pandas.Series, numpy.array or float
86+
Result of the interpolation (e.g. density at hub height).
87+
88+
Notes
89+
-----
90+
91+
For the interpolation np.interp() is used and the following equation is
92+
used for extrapolation:
93+
94+
.. math:: interpolant = (value_2 - value_1) / (height_2 - height_1) *
95+
(height_{requested} - height_1) + value_1
96+
97+
with:
98+
:math:`height_2`: largest/smallest value in data frame,
99+
:math:`height_1`: second largest/smallest value in data frame,
100+
:math:`value_2`: corresponding value to `height_2`,
101+
:math:`value_1`: correponding value to `height_1`,
102+
:math:`height_{requested}` : Height for which the interpolation takes
103+
place
104+
105+
"""
106+
if requested_height > max(data_frame.index):
107+
height_2 = max(data_frame.index)
108+
value_2 = data_frame[column_name][height_2]
109+
height_1 = sorted(data_frame.index)[-2] # Second largest number
110+
value_1 = data_frame[column_name][height_1]
111+
interpolant = ((value_2 - value_1) / (height_2 - height_1) *
112+
(requested_height - height_1) + value_1)
113+
elif requested_height < min(data_frame.index):
114+
height_2 = min(data_frame.index)
115+
value_2 = data_frame[column_name][height_2]
116+
height_1 = sorted(data_frame.index)[1] # Second smallest number
117+
value_1 = data_frame[column_name][height_1]
118+
interpolant = ((value_2 - value_1) / (height_2 - height_1) *
119+
(requested_height - height_1) + value_1)
120+
else:
121+
interpolant = np.interp(requested_height, data_frame.index,
122+
data_frame[column_name])
123+
return interpolant

0 commit comments

Comments
 (0)