Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .stickler.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
linters:
flake8:
python: 3
max-line-length: 79
select: C,E,F,W,B,B950
ignore: E203, E501, W503
black:
config: ./pyproject.toml
fixer: true

fixers:
enable: true
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ matrix:
- python: 3.5
- python: 3.6
- python: 3.7
dist: xenial
sudo: true
- python: 3.8

# command to install dependencies
#before_install:
Expand Down
81 changes: 46 additions & 35 deletions example/modelchain_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,19 +64,24 @@ def get_weather_data(filename='weather.csv', **kwargs):

"""

if 'datapath' not in kwargs:
kwargs['datapath'] = os.path.join(os.path.split(
os.path.dirname(__file__))[0], 'example')
file = os.path.join(kwargs['datapath'], filename)
if "datapath" not in kwargs:
kwargs["datapath"] = os.path.join(
os.path.split(os.path.dirname(__file__))[0], "example"
)
file = os.path.join(kwargs["datapath"], filename)

# read csv file
weather_df = pd.read_csv(
file, index_col=0, header=[0, 1],
date_parser=lambda idx: pd.to_datetime(idx, utc=True))
file,
index_col=0,
header=[0, 1],
date_parser=lambda idx: pd.to_datetime(idx, utc=True),
)

# change type of index to datetime and set time zone
weather_df.index = pd.to_datetime(weather_df.index).tz_convert(
'Europe/Berlin')
"Europe/Berlin"
)

# change type of height from str to int by resetting columns
l0 = [_[0] for _ in weather_df.columns]
Expand Down Expand Up @@ -112,33 +117,38 @@ def initialize_wind_turbines():
# specification of wind turbine where data is provided in the oedb
# turbine library
enercon_e126 = {
'turbine_type': 'E-126/4200', # turbine type as in register
'hub_height': 135 # in m
"turbine_type": "E-126/4200", # turbine type as in register
"hub_height": 135, # in m
}
# initialize WindTurbine object
e126 = WindTurbine(**enercon_e126)

# specification of own wind turbine (Note: power values and nominal power
# have to be in Watt)
my_turbine = {
'nominal_power': 3e6, # in W
'hub_height': 105, # in m
'power_curve': pd.DataFrame(
data={'value': [p * 1000 for p in [
0.0, 26.0, 180.0, 1500.0, 3000.0, 3000.0]], # in W
'wind_speed': [0.0, 3.0, 5.0, 10.0, 15.0, 25.0]}) # in m/s
"nominal_power": 3e6, # in W
"hub_height": 105, # in m
"power_curve": pd.DataFrame(
data={
"value": [
p * 1000
for p in [0.0, 26.0, 180.0, 1500.0, 3000.0, 3000.0]
], # in W
"wind_speed": [0.0, 3.0, 5.0, 10.0, 15.0, 25.0],
}
), # in m/s
}
# initialize WindTurbine object
my_turbine = WindTurbine(**my_turbine)

# specification of wind turbine where power coefficient curve and nominal
# power is provided in an own csv file
csv_path = os.path.join(os.path.dirname(__file__), 'data')
csv_path = os.path.join(os.path.dirname(__file__), "data")
dummy_turbine = {
'turbine_type': "DUMMY 1",
'hub_height': 100, # in m
'rotor_diameter': 70, # in m
'path': csv_path
"turbine_type": "DUMMY 1",
"hub_height": 100, # in m
"rotor_diameter": 70, # in m
"path": csv_path,
}
# initialize WindTurbine object
dummy_turbine = WindTurbine(**dummy_turbine)
Expand Down Expand Up @@ -182,18 +192,19 @@ def calculate_power_output(weather, my_turbine, e126, dummy_turbine):
# power output calculation for e126
# own specifications for ModelChain setup
modelchain_data = {
'wind_speed_model': 'logarithmic', # 'logarithmic' (default),
# 'hellman' or
# 'interpolation_extrapolation'
'density_model': 'ideal_gas', # 'barometric' (default), 'ideal_gas' or
# 'interpolation_extrapolation'
'temperature_model': 'linear_gradient', # 'linear_gradient' (def.) or
# 'interpolation_extrapolation'
'power_output_model': 'power_curve', # 'power_curve' (default) or
# 'power_coefficient_curve'
'density_correction': True, # False (default) or True
'obstacle_height': 0, # default: 0
'hellman_exp': None} # None (default) or None
"wind_speed_model": "logarithmic", # 'logarithmic' (default),
# 'hellman' or
# 'interpolation_extrapolation'
"density_model": "ideal_gas", # 'barometric' (default), 'ideal_gas' or
# 'interpolation_extrapolation'
"temperature_model": "linear_gradient", # 'linear_gradient' (def.) or
# 'interpolation_extrapolation'
"power_output_model": "power_curve", # 'power_curve' (default) or
# 'power_coefficient_curve'
"density_correction": True, # False (default) or True
"obstacle_height": 0, # default: 0
"hellman_exp": None,
} # None (default) or None
# initialize ModelChain with own specifications and use run_model method
# to calculate power output
mc_e126 = ModelChain(e126, **modelchain_data).run_model(weather)
Expand All @@ -203,8 +214,8 @@ def calculate_power_output(weather, my_turbine, e126, dummy_turbine):
# power output calculation for example_turbine
# own specification for 'power_output_model'
mc_example_turbine = ModelChain(
dummy_turbine,
power_output_model='power_coefficient_curve').run_model(weather)
dummy_turbine, power_output_model="power_coefficient_curve"
).run_model(weather)
dummy_turbine.power_output = mc_example_turbine.power_output

return
Expand Down Expand Up @@ -272,7 +283,7 @@ def run_example():
Runs the basic example.

"""
weather = get_weather_data('weather.csv')
weather = get_weather_data("weather.csv")
my_turbine, e126, dummy_turbine = initialize_wind_turbines()
calculate_power_output(weather, my_turbine, e126, dummy_turbine)
plot_or_print(my_turbine, e126, dummy_turbine)
Expand Down
70 changes: 49 additions & 21 deletions example/test_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,45 @@


class TestExamples:

def test_modelchain_example_flh(self):
# tests full load hours
weather = mc_e.get_weather_data('weather.csv')
weather = mc_e.get_weather_data("weather.csv")
my_turbine, e126, dummy_turbine = mc_e.initialize_wind_turbines()
mc_e.calculate_power_output(weather, my_turbine, e126, dummy_turbine)

assert_allclose(2764.194772, (e126.power_output.sum() /
e126.nominal_power), 0.01)
assert_allclose(1882.7567, (my_turbine.power_output.sum() /
my_turbine.nominal_power), 0.01)
assert_allclose(
2764.194772, (e126.power_output.sum() / e126.nominal_power), 0.01
)
assert_allclose(
1882.7567,
(my_turbine.power_output.sum() / my_turbine.nominal_power),
0.01,
)

def test_turbine_cluster_modelchain_example_flh(self):
# tests full load hours
weather = mc_e.get_weather_data('weather.csv')
weather = mc_e.get_weather_data("weather.csv")
my_turbine, e126, dummy_turbine = mc_e.initialize_wind_turbines()
example_farm, example_farm_2 = tc_mc_e.initialize_wind_farms(
my_turbine, e126)
my_turbine, e126
)
example_cluster = tc_mc_e.initialize_wind_turbine_cluster(
example_farm, example_farm_2)
example_farm, example_farm_2
)
tc_mc_e.calculate_power_output(weather, example_farm, example_cluster)
assert_allclose(1956.164053, (example_farm.power_output.sum() /
example_farm.nominal_power), 0.01)
assert_allclose(2156.794154, (example_cluster.power_output.sum() /
example_cluster.nominal_power), 0.01)
assert_allclose(
1956.164053,
(example_farm.power_output.sum() / example_farm.nominal_power),
0.01,
)
assert_allclose(
2156.794154,
(
example_cluster.power_output.sum()
/ example_cluster.nominal_power
),
0.01,
)

def _notebook_run(self, path):
"""
Expand All @@ -49,30 +63,44 @@ def _notebook_run(self, path):
dirname, __ = os.path.split(path)
os.chdir(dirname)
with tempfile.NamedTemporaryFile(suffix=".ipynb") as fout:
args = ["jupyter", "nbconvert", "--to", "notebook", "--execute",
"--ExecutePreprocessor.timeout=60",
"--output", fout.name, path]
args = [
"jupyter",
"nbconvert",
"--to",
"notebook",
"--execute",
"--ExecutePreprocessor.timeout=60",
"--output",
fout.name,
path,
]
subprocess.check_call(args)

fout.seek(0)
nb = nbformat.read(fout, nbformat.current_nbformat)

errors = [output for cell in nb.cells if "outputs" in cell
for output in cell["outputs"]
if output.output_type == "error"]
errors = [
output
for cell in nb.cells
if "outputs" in cell
for output in cell["outputs"]
if output.output_type == "error"
]

return nb, errors

@pytest.mark.skipif(sys.version_info < (3, 6), reason="requires python3.6")
def test_modelchain_example_ipynb(self):
dir_path = os.path.dirname(os.path.realpath(__file__))
nb, errors = self._notebook_run(
os.path.join(dir_path, 'modelchain_example.ipynb'))
os.path.join(dir_path, "modelchain_example.ipynb")
)
assert errors == []

@pytest.mark.skipif(sys.version_info < (3, 6), reason="requires python3.6")
def test_turbine_cluster_modelchain_example_ipynb(self):
dir_path = os.path.dirname(os.path.realpath(__file__))
nb, errors = self._notebook_run(
os.path.join(dir_path, 'turbine_cluster_modelchain_example.ipynb'))
os.path.join(dir_path, "turbine_cluster_modelchain_example.ipynb")
)
assert errors == []
89 changes: 49 additions & 40 deletions example/turbine_cluster_modelchain_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,21 +59,27 @@ def initialize_wind_farms(my_turbine, e126):
# that type in the wind farm (float values are possible as well) or the
# total installed capacity of that turbine type in W
wind_turbine_fleet = pd.DataFrame(
{'wind_turbine': [my_turbine, e126], # as windpowerlib.WindTurbine
'number_of_turbines': [6, None],
'total_capacity': [None, 12.6e6]}
{
"wind_turbine": [my_turbine, e126], # as windpowerlib.WindTurbine
"number_of_turbines": [6, None],
"total_capacity": [None, 12.6e6],
}
)
# initialize WindFarm object
example_farm = WindFarm(name='example_farm',
wind_turbine_fleet=wind_turbine_fleet)
example_farm = WindFarm(
name="example_farm", wind_turbine_fleet=wind_turbine_fleet
)

# specification of wind farm data (2) containing a wind farm efficiency
# wind turbine fleet is provided using the to_group function
example_farm_2_data = {
'name': 'example_farm_2',
'wind_turbine_fleet': [my_turbine.to_group(6),
e126.to_group(total_capacity=12.6e6)],
'efficiency': 0.9}
"name": "example_farm_2",
"wind_turbine_fleet": [
my_turbine.to_group(6),
e126.to_group(total_capacity=12.6e6),
],
"efficiency": 0.9,
}
# initialize WindFarm object
example_farm_2 = WindFarm(**example_farm_2_data)

Expand Down Expand Up @@ -104,8 +110,9 @@ def initialize_wind_turbine_cluster(example_farm, example_farm_2):

# specification of cluster data
example_cluster_data = {
'name': 'example_cluster',
'wind_farms': [example_farm, example_farm_2]}
"name": "example_cluster",
"wind_farms": [example_farm, example_farm_2],
}
# initialize WindTurbineCluster object
example_cluster = WindTurbineCluster(**example_cluster_data)

Expand Down Expand Up @@ -144,35 +151,36 @@ class that provides all necessary steps to calculate the power output of a
# power output calculation for turbine_cluster
# own specifications for TurbineClusterModelChain setup
modelchain_data = {
'wake_losses_model':
'wind_farm_efficiency', # 'dena_mean' (default), None,
# 'wind_farm_efficiency' or name
# of another wind efficiency curve
# see :py:func:`~.wake_losses.get_wind_efficiency_curve`
'smoothing': True, # False (default) or True
'block_width': 0.5, # default: 0.5
'standard_deviation_method': 'Staffell_Pfenninger', #
# 'turbulence_intensity' (default)
# or 'Staffell_Pfenninger'
'smoothing_order': 'wind_farm_power_curves', #
# 'wind_farm_power_curves' (default) or
# 'turbine_power_curves'
'wind_speed_model': 'logarithmic', # 'logarithmic' (default),
# 'hellman' or
# 'interpolation_extrapolation'
'density_model': 'ideal_gas', # 'barometric' (default), 'ideal_gas' or
# 'interpolation_extrapolation'
'temperature_model': 'linear_gradient', # 'linear_gradient' (def.) or
# 'interpolation_extrapolation'
'power_output_model': 'power_curve', # 'power_curve' (default) or
# 'power_coefficient_curve'
'density_correction': True, # False (default) or True
'obstacle_height': 0, # default: 0
'hellman_exp': None} # None (default) or None
"wake_losses_model": "wind_farm_efficiency", # 'dena_mean' (default), None,
# 'wind_farm_efficiency' or name
# of another wind efficiency curve
# see :py:func:`~.wake_losses.get_wind_efficiency_curve`
"smoothing": True, # False (default) or True
"block_width": 0.5, # default: 0.5
"standard_deviation_method": "Staffell_Pfenninger", #
# 'turbulence_intensity' (default)
# or 'Staffell_Pfenninger'
"smoothing_order": "wind_farm_power_curves", #
# 'wind_farm_power_curves' (default) or
# 'turbine_power_curves'
"wind_speed_model": "logarithmic", # 'logarithmic' (default),
# 'hellman' or
# 'interpolation_extrapolation'
"density_model": "ideal_gas", # 'barometric' (default), 'ideal_gas' or
# 'interpolation_extrapolation'
"temperature_model": "linear_gradient", # 'linear_gradient' (def.) or
# 'interpolation_extrapolation'
"power_output_model": "power_curve", # 'power_curve' (default) or
# 'power_coefficient_curve'
"density_correction": True, # False (default) or True
"obstacle_height": 0, # default: 0
"hellman_exp": None,
} # None (default) or None
# initialize TurbineClusterModelChain with own specifications and use
# run_model method to calculate power output
mc_example_cluster = TurbineClusterModelChain(
example_cluster, **modelchain_data).run_model(weather)
example_cluster, **modelchain_data
).run_model(weather)
# write power output time series to WindTurbineCluster object
example_cluster.power_output = mc_example_cluster.power_output

Expand Down Expand Up @@ -209,11 +217,12 @@ def run_example():
Runs the example.

"""
weather = mc_e.get_weather_data('weather.csv')
weather = mc_e.get_weather_data("weather.csv")
my_turbine, e126, dummy_turbine = mc_e.initialize_wind_turbines()
example_farm, example_farm_2 = initialize_wind_farms(my_turbine, e126)
example_cluster = initialize_wind_turbine_cluster(example_farm,
example_farm_2)
example_cluster = initialize_wind_turbine_cluster(
example_farm, example_farm_2
)
calculate_power_output(weather, example_farm, example_cluster)
plot_or_print(example_farm, example_cluster)

Expand Down
Loading