Skip to content
Snippets Groups Projects
Commit a69fe2e4 authored by Mads M. Pedersen's avatar Mads M. Pedersen
Browse files

exercises

parent 10f2c812
No related branches found
Tags v1.0.8
No related merge requests found
Showing
with 938 additions and 11 deletions
%% Cell type:markdown id: tags:
# Exercise: Optimize Hornsrev1 layoutV80 example turbine
%% Cell type:code id: tags:
``` python
import numpy as np
import matplotlib.pyplot as plt
from py_wake.examples.data.hornsrev1 import V80, Hornsrev1Site, wt_x, wt_y
from py_wake.wake_models import Fuga
from py_wake.tests.test_files.fuga import LUT_path_2MW_z0_0_03
from py_wake.aep_calculator import AEPCalculator
site = Hornsrev1Site()
wt = V80()
wake_model = Fuga(LUT_path_2MW_z0_0_03, wt)
aep_calc = AEPCalculator(site, wt, wake_model)
```
%% Cell type:code id: tags:
``` python
site.plot_wd_distribution(n_wd=12)
```
%% Output
%% Cell type:code id: tags:
``` python
# Original layout and AEP
wt.plot(wt_x, wt_y)
aep_ref = aep_calc.calculate_AEP(wt_x,wt_y).sum()
print ("AEP ref", aep_ref)
```
%% Output
AEP ref 692.800850831212
%% Cell type:markdown id: tags:
**Exercise**
Modify the x and y offsets for the rows and columns to increase the AEP.
Note, the turbines positions are limited by a rectangle surrounding the existing layout
%% Cell type:code id: tags:
``` python
def add_offset_plot_and_print(row_offset_x, row_offset_y, col_offset_x, col_offset_y):
x,y = wt_x, wt_y
y = np.reshape(y,(10,8)).astype(np.float)
x = np.reshape(x,(10,8)).astype(np.float)
x+= np.array(row_offset_x)
y+= np.array(row_offset_y)
x+= np.array(col_offset_x)[:,np.newaxis]
y+= np.array(col_offset_y)[:,np.newaxis]
y = np.maximum(min(wt_y), np.minimum(max(wt_y), y.flatten()))
x = np.maximum(min(wt_x), np.minimum(max(wt_x), x.flatten()))
plt.plot()
plt.plot(wt_x, wt_y,'b.')
wt.plot(x, y)
aep = aep_calc.calculate_AEP(x,y).sum()
print ("AEP ref", aep_ref)
print ("AEP", aep)
print ("Increase: %f %%"%((aep-aep_ref)/aep_ref*100))
# =======================================
# Specify offsets
# =======================================
row_offset_x = -np.linspace(0,1,8)* 478
row_offset_y = np.linspace(0,1,8) * 0
col_offset_x = np.linspace(0,1,10) * 478
col_offset_y = np.linspace(0,1,10) * 0
add_offset_plot_and_print(row_offset_x, row_offset_y, col_offset_x, col_offset_y)
```
%% Output
AEP ref 692.800850831212
AEP 696.6038571239302
Increase: 0.548932 %
%% Cell type:code id: tags:
``` python
```
%% Cell type:markdown id: tags:
# Exercise: Validate NOJ
%% Cell type:markdown id: tags:
Validate the down stream wind speed result presented in table 1 in Jensen, Niels Otto. "A note on wind generator interaction." (1983)
%% Cell type:markdown id: tags:
Input
- Nibe turbine:
- radius: 20m
- Wind speed behind the turbine: 1/3U (corresponding to ct=8/9)
- Wake expansion factor, k: 0.1
- wind speed:
- 100m upstream: 8.1 m/s
Results
- 40m down stream: 4.35 m/s
- 100m down stream: 5.7 m/s
Hint:
- Copy the template below into a code cell
- Replace all occurences of "..." with proper values/code
- Take a look at the [refernce guide](https://topfarm.pages.windenergy.dtu.dk/PyWake/reference_guide.html)
%% Cell type:markdown id: tags:
**Template**
```python
import numpy as np
import matplotlib.pyplot as plt
from py_wake.aep_calculator import AEPCalculator
from py_wake.wind_turbines import OneTypeWindTurbines
from py_wake.wake_models import NOJ
from py_wake.site import UniformSite
def p(ws):
# power function for wind turbine
return ...
def ct(ws):
# ct function for wind turbine
return ...
wt = OneTypeWindTurbines(name=...,
diameter=...,
hub_height=...,
ct_func=ct,
power_func=p,
power_unit=...)
wake_model = NOJ(...)
site = UniformSite(p_wd=[1], ti=.1) # Dummy site (flat and uniform)
aep_calc = AEPCalculator(site, wt, wake_model)
X,Y,WS_eff = aep_calc.wake_map(x_j = [...],
y_j=[...],
wt_x=[...],
wt_y=[...],
wd=[...],
ws=[...])
print ( WS_eff)
```
%% Cell type:code id: tags:
``` python
```
%% Cell type:markdown id: tags:
# Exercise: Validate NOJ (solution)
%% Cell type:markdown id: tags:
Validate the down stream wind speed result presented in table 1 in Jensen, Niels Otto. "A note on wind generator interaction." (1983)
%% Cell type:markdown id: tags:
Input
- Nibe turbine:
- radius: 20m
- Wind speed behind the turbine: 1/3U (corresponding to ct=8/9)
- Wake expansion factor, k: 0.1
- wind speed:
- 100m upstream: 8.1 m/s
Results
- 40m down stream: 4.35 m/s
- 100m down stream: 5.7
%% Cell type:code id: tags:
``` python
import numpy as np
import matplotlib.pyplot as plt
from py_wake.aep_calculator import AEPCalculator
from py_wake.wind_turbines import OneTypeWindTurbines
from py_wake.wake_models import NOJ
from py_wake.site import UniformSite
def p(ws):
return 0
def ct(ws):
return 8/9
wt = OneTypeWindTurbines(name="Nibe",
diameter=40,
hub_height=50,
ct_func= ct,
power_func = p,
power_unit='w')
wake_model = NOJ(wt, k=.1)
site = UniformSite(p_wd=[1], ti=.1) # Dummy site (flat and uniform)
aep_calc = AEPCalculator(site, wt, wake_model)
X,Y,WS_eff = aep_calc.wake_map(x_j = [0],
y_j=[100,-40,-100],
wt_x=[0],
wt_y=[0],
wd=[0],
ws=[8.1])
print ( WS_eff)
```
%% Output
[[8.1 ]
[4.35]
[5.7 ]]
%% Cell type:code id: tags:
``` python
```
......@@ -94,5 +94,6 @@ if __name__ == '__main__':
make_doc_notebooks(['V80', 'IEA37Turbine',
'IEA37Site', 'Hornsrev1Site',
'noj', 'fuga', 'IEA37SimpleBastankhahGaussian', 'BastankhahGaussian',
'cmp_wakemodels'])
'cmp_wakemodels',
'noj_validation_exercise_solution', 'noj_validation_exercise', 'hornsrev_layout_optimization_exercise'])
print('Done')
This diff is collapsed.
%% Cell type:markdown id: tags:
# Exercise: Validate NOJ
%% Cell type:markdown id: tags:
[Try this yourself](https://colab.research.google.com/github/DTUWindEnergy/PyWake/blob/master/docs/notebooks/noj_validation_exercise.ipynb) (requires google account)
%% Cell type:code id: tags:
``` python
# Install PyWake if needed
try:
import py_wake
except ModuleNotFoundError:
!pip install py_wake
```
%% Cell type:markdown id: tags:
Validate the down stream wind speed result presented in table 1 in Jensen, Niels Otto. "A note on wind generator interaction." (1983)
%% Cell type:markdown id: tags:
Input
- Nibe turbine:
- radius: 20m
- Wind speed behind the turbine: 1/3U (corresponding to ct=8/9)
- Wake expansion factor, k: 0.1
- wind speed:
- 100m upstream: 8.1 m/s
Results
- 40m down stream: 4.35 m/s
- 100m down stream: 5.7 m/s
Hint:
- Copy the template below into a code cell
- Replace all occurences of "..." with proper values/code
- Take a look at the [refernce guide](https://topfarm.pages.windenergy.dtu.dk/PyWake/reference_guide.html)
%% Cell type:markdown id: tags:
**Template**
```python
import numpy as np
import matplotlib.pyplot as plt
from py_wake.aep_calculator import AEPCalculator
from py_wake.wind_turbines import OneTypeWindTurbines
from py_wake.wake_models import NOJ
from py_wake.site import UniformSite
def p(ws):
# power function for wind turbine
return ...
def ct(ws):
# ct function for wind turbine
return ...
wt = OneTypeWindTurbines(name=...,
diameter=...,
hub_height=...,
ct_func=ct,
power_func=p,
power_unit=...)
wake_model = NOJ(...)
site = UniformSite(p_wd=[1], ti=.1) # Dummy site (flat and uniform)
aep_calc = AEPCalculator(site, wt, wake_model)
X,Y,WS_eff = aep_calc.wake_map(x_j = [...],
y_j=[...],
wt_x=[...],
wt_y=[...],
wd=[...],
ws=[...])
print ( WS_eff)
```
%% Cell type:code id: tags:
``` python
```
%% Cell type:markdown id: tags:
# Exercise: Validate NOJ (solution)
%% Cell type:markdown id: tags:
[Try this yourself](https://colab.research.google.com/github/DTUWindEnergy/PyWake/blob/master/docs/notebooks/noj_validation_exercise_solution.ipynb) (requires google account)
%% Cell type:code id: tags:
``` python
# Install PyWake if needed
try:
import py_wake
except ModuleNotFoundError:
!pip install py_wake
```
%% Cell type:markdown id: tags:
Validate the down stream wind speed result presented in table 1 in Jensen, Niels Otto. "A note on wind generator interaction." (1983)
%% Cell type:markdown id: tags:
Input
- Nibe turbine:
- radius: 20m
- Wind speed behind the turbine: 1/3U (corresponding to ct=8/9)
- Wake expansion factor, k: 0.1
- wind speed:
- 100m upstream: 8.1 m/s
Results
- 40m down stream: 4.35 m/s
- 100m down stream: 5.7
%% Cell type:code id: tags:
``` python
import numpy as np
import matplotlib.pyplot as plt
from py_wake.aep_calculator import AEPCalculator
from py_wake.wind_turbines import OneTypeWindTurbines
from py_wake.wake_models import NOJ
from py_wake.site import UniformSite
def p(ws):
return 0
def ct(ws):
return 8/9
wt = OneTypeWindTurbines(name="Nibe",
diameter=40,
hub_height=50,
ct_func= ct,
power_func = p,
power_unit='w')
wake_model = NOJ(wt, k=.1)
site = UniformSite(p_wd=[1], ti=.1) # Dummy site (flat and uniform)
aep_calc = AEPCalculator(site, wt, wake_model)
X,Y,WS_eff = aep_calc.wake_map(x_j = [0],
y_j=[100,-40,-100],
wt_x=[0],
wt_y=[0],
wd=[0],
ws=[8.1])
print ( WS_eff)
```
%% Output
[[8.1 ]
[4.35]
[5.7 ]]
%% Cell type:code id: tags:
``` python
```
Exercises
===========================
.. toctree::
:caption: Exercises
:maxdepth: 2
exercises/hornsrev_layout_optimization_exercise
exercises/noj_validation_exercise
exercises/noj_validation_exercise_solution
\ No newline at end of file
{
"path": "../../notebooks/hornsrev_layout_optimization_exercise.ipynb"
}
\ No newline at end of file
{
"path": "../../notebooks/noj_validation_exercise.ipynb"
}
\ No newline at end of file
{
"path": "../../notebooks/noj_validation_exercise_solution.ipynb"
}
\ No newline at end of file
......@@ -7,10 +7,12 @@
.. image:: _static/logo.png
:align: center
Welcome to PyWake
===========================================
PyWake is an AEP calculator for wind farms implemented in Python including a collection of wake models
*- an AEP calculator for wind farms implemented in Python including a collection of wake models*
Quick Start::
**Quick Start**::
pip install py_wake
......@@ -30,3 +32,4 @@ Contents:
installation
introduction
reference_guide
exercises
......@@ -2,17 +2,21 @@
import os
from _notebooks.notebook import Notebook
import py_wake
import pytest
def test_notebooks():
def get_notebooks():
path = os.path.dirname(py_wake.__file__) + "/../_notebooks/elements/"
return [Notebook(path + f) for f in [f for f in os.listdir(path) if f.endswith('.ipynb')]]
@pytest.mark.parametrize("notebook", get_notebooks())
def test_notebooks(notebook):
import matplotlib.pyplot as plt
def no_show(*args, **kwargs):
pass
plt.show = no_show # disable plt show that requires the user to close the plot
path = os.path.dirname(py_wake.__file__) + "/../_notebooks/elements/"
for f in [f for f in os.listdir(path) if f.endswith('.ipynb')]:
nb = Notebook(path + f)
nb.check_code()
nb.check_links()
notebook.check_code()
notebook.check_links()
......@@ -13,6 +13,7 @@ class NOJ(SquaredSum, WakeModel):
def calc_deficit(self, WS_lk, D_src_l, D_dst_jl, dw_jl, cw_jl, ct_lk):
# Calculate the wake loss using NOJ
# Jensen, Niels Otto. "A note on wind generator interaction." (1983)
# In NOJensen wake model:
# V_def = v*(1-sqrt(1-Ct))/(1+k*dist_down/R)**2
......
......@@ -136,9 +136,26 @@ class WindTurbines():
class OneTypeWindTurbines(WindTurbines):
def __init__(self, name, diameter, hub_height, ct_func, power_func, power_unit):
"""Initialize OneTypeWindTurbine
Parameters
----------
name : str
Wind turbine name
diameter : int or float
Diameter of wind turbine
hub_height : int or float
Hub height of wind turbine
ct_func : function
Wind turbine ct function; func(ws) -> ct
power_func : function
Wind turbine power function; func(ws) -> power
power_unit : {'W', 'kW', 'MW', 'GW'}
Unit of power_func output (case insensitive)
"""
WindTurbines.__init__(self, [name], [diameter], [hub_height],
[lambda ws, types=0: ct_func(ws)],
[lambda ws, types=0: power_func(ws)],
[lambda ws: ct_func(ws)],
[lambda ws: power_func(ws)],
power_unit)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment