Skip to content

Commit

Permalink
Squashed 'ROSCO_toolbox/' changes from 9b123f1..381ae28
Browse files Browse the repository at this point in the history
381ae28 CI Testing (WISDEM#41)
da6b56c Merge pull request WISDEM#40 from nikhar-abbas/b/interp
67d5d36 Write example_07 (min pitch) output to new figure
3750beb Remove double instance of rated wind speed in controller.v
9e89ef8 Make interpolation function monotonic
65c4020 linear interpolation
53343d1 Delete history file
07b46b6 Update version to 2.2.0
REVERT: 9b123f1 Update examples to test in weis environment, working
REVERT: 15976f5 Merge branch 'develop' into weis
REVERT: 7d28a6f Get rid of annoying spectral warning
REVERT: 25ef7a7 Update ROSCO install dir, other setup fun stuff
REVERT: 52465fe Merge remote-tracking branch 'upstream/develop' into weis
REVERT: 3454fc0 Merge remote-tracking branch 'upstream/develop' into weis
REVERT: b730428 Merge pull request WISDEM#28 from nikhar-abbas/weis
REVERT: 71565e1 Revert "fix minpitch saturation bug"
REVERT: 34b427c Update submodule to track develop branch
REVERT: f504b34 remove 0.7 from flpwise damping conversion
REVERT: bc8c9c3 write kappa to self
REVERT: 38e956e Merge branch 'weis' of https://github.com/NREL/ROSCO_toolbox into weis
REVERT: 096f1e9 Merge branch 'develop' into weis
REVERT: cf5b43b Fix another ofTools import
REVERT: 67731f8 Fix ofTools import
REVERT: 2256b0c Move ofTools into ROSCO_toolbox
REVERT: e4a1c7f Revert setup.py to exclude ROSCO build, etc.
REVERT: 0e53372 Use weis.aeroelasticse for file reading
REVERT: c8e9954 Make tuning yaml relative to main directory
REVERT: f62653b Update InflowWind.dat templates in TuneCases/
REVERT: 3afe143 typo
REVERT: 92d6410 fix minpitch saturation bug
REVERT: a7be52a Separate below and above rated windspeeds by 30 points each

git-subtree-dir: ROSCO_toolbox
git-subtree-split: 381ae28
  • Loading branch information
ewquon committed Apr 8, 2021
1 parent 331b1af commit 198964d
Show file tree
Hide file tree
Showing 25 changed files with 249 additions and 181 deletions.
19 changes: 19 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
## Description and Purpose

## Type of change
What types of change is it?
_Select the appropriate type(s) that describe this PR_

- [ ] Bugfix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (non-backwards-compatible fix or feature)
- [ ] Code style update (formatting, renaming)
- [ ] Refactoring (no functional changes, no API changes)
- [ ] Documentation update
- [ ] Maintenance update
- [ ] Other (please describe)

## Github issues addressed, if one exists

## Examples/Testing, if applicable

106 changes: 106 additions & 0 deletions .github/workflows/CI_rosco-toolbox.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
name: CI_rosco-toolbox

# We run CI on push commits on all branches
on: [push, pull_request]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
build:
name: Build (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
os: ["ubuntu-latest", "macOS-latest", "windows-latest"]
python-version: ["3.8"]
defaults:
run:
shell: bash -l {0}

steps:
- name: Checkout repository and submodules
uses: actions/checkout@v2
with:
submodules: recursive

- name: Setup environment
uses: conda-incubator/setup-miniconda@v2
with:
miniconda-version: "latest"
channels: conda-forge, general
auto-update-conda: true
python-version: 3.8
environment-file: environment.yml


# Install dependencies of ROSCO toolbox
- name: Add dependencies ubuntu specific
if: false == contains( matrix.os, 'windows')
run: |
conda install -y compilers
conda install -y wisdem
- name: Add dependencies windows specific
if: true == contains( matrix.os, 'windows')
run: |
conda install -y m2w64-toolchain libpython
conda install -y wisdem
# Install ROSCO toolbox
- name: Install ROSCO toolbox
run: |
python setup.py develop --compile-rosco
run_examples:
name: Run Examples
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
os: ["ubuntu-latest"] #, "macOS-latest"]
python-version: ["3.8"]
defaults:
run:
shell: bash -l {0}

steps:
- name: Checkout repository and submodules
uses: actions/checkout@v2
with:
submodules: recursive

- name: Setup environment
uses: conda-incubator/setup-miniconda@v2
with:
miniconda-version: "latest"
channels: conda-forge, general
auto-update-conda: true
python-version: 3.8
environment-file: environment.yml


# Install dependencies of ROSCO toolbox
- name: Add dependencies ubuntu specific
if: false == contains( matrix.os, 'windows')
run: |
conda install -y compilers
conda install -y wisdem
# Install ROSCO toolbox
- name: Install ROSCO toolbox
run: |
python setup.py develop --compile-rosco
# Install OpenFAST
- name: Install OpenFAST
run: |
conda install openfast
# Run examples
- name: Run examples
run: |
cd Examples
python run_examples.py
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[submodule "ROSCO"]
path = ROSCO
url = https://github.com/NREL/ROSCO
branch = main
branch = main
17 changes: 5 additions & 12 deletions Examples/example_06.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@
from ROSCO_toolbox import turbine as ROSCO_turbine
from ROSCO_toolbox.utilities import write_DISCON, run_openfast
from ROSCO_toolbox import sim as ROSCO_sim
from ROSCO_toolbox.ofTools.fast_io import output_processing

this_dir = os.path.dirname(os.path.abspath(__file__))
rt_dir = os.path.dirname(this_dir)

# Load yaml file
parameter_filename = os.path.join(os.path.dirname(this_dir), 'Tune_Cases', 'IEA15MW.yaml')
Expand All @@ -36,26 +34,21 @@

# Load turbine data from OpenFAST and rotor performance text file
turbine.load_from_fast(path_params['FAST_InputFile'], \
os.path.join(rt_dir,path_params['FAST_directory']), \
os.path.join(this_dir,path_params['FAST_directory']), \
dev_branch=True,rot_source='txt',\
txt_filename=os.path.join(rt_dir,path_params['FAST_directory'],path_params['rotor_performance_filename']))
txt_filename=os.path.join(this_dir,path_params['FAST_directory'],path_params['rotor_performance_filename']))

# Tune controller
controller.tune_controller(turbine)

# Write parameter input file
param_file = os.path.join(rt_dir,'Test_Cases/IEA-15-240-RWT-UMaineSemi/ServoData/DISCON-UMaineSemi.IN') # This must be named DISCON.IN to be seen by the compiled controller binary.
param_file = os.path.join(this_dir,'DISCON.IN') # This must be named DISCON.IN to be seen by the compiled controller binary.
write_DISCON(turbine,controller,param_file=param_file, txt_filename=path_params['rotor_performance_filename'])

# Run OpenFAST
# --- May need to change fastcall if you use a non-standard command to call openfast
fastcall = '/Users/dzalkind/Tools/WEIS-1/build/temp.macosx-10.9-x86_64-3.8_rosco_openfast/glue-codes/openfast/openfast'
run_openfast(
os.path.join(rt_dir,path_params['FAST_directory']),
fastcall=fastcall,
fastfile=path_params['FAST_InputFile'],
chdir=True
)
fastcall = 'openfast'
run_openfast(path_params['FAST_directory'], fastcall=fastcall, fastfile=path_params['FAST_InputFile'], chdir=True)



Expand Down
11 changes: 6 additions & 5 deletions Examples/example_07.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,12 @@
controller.tune_controller(turbine)

# Plot minimum pitch schedule
plt.plot(controller.v, controller.pitch_op,label='Steady State Operation')
plt.plot(controller.v, controller.ps_min_bld_pitch, label='Minimum Pitch Schedule')
plt.legend()
plt.xlabel('Wind speed (m/s)')
plt.ylabel('Blade pitch (rad)')
fig, ax = plt.subplots(1,1)
ax.plot(controller.v, controller.pitch_op,label='Steady State Operation')
ax.plot(controller.v, controller.ps_min_bld_pitch, label='Minimum Pitch Schedule')
ax.legend()
ax.set_xlabel('Wind speed (m/s)')
ax.set_ylabel('Blade pitch (rad)')

if False:
plt.show()
Expand Down
9 changes: 3 additions & 6 deletions Examples/example_09.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@
wind_directory = os.path.join(this_dir,'../Test_Cases/Wind/')
turbsim_infile = '90m_12mps_twr.inp'

run_openfast(
wind_directory,
fastcall='/Users/dzalkind/Tools/WEIS-1/build/temp.macosx-10.9-x86_64-3.8_rosco_openfast/modules/turbsim/turbsim',
fastfile=turbsim_infile,
chdir=False
)
run_openfast(wind_directory, fastcall='turbsim',
fastfile=os.path.join(wind_directory, turbsim_infile), chdir=False)

print('test')
8 changes: 1 addition & 7 deletions Examples/example_11.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@

import numpy as np

this_dir = os.path.dirname(os.path.abspath(__file__))
rt_dir = os.path.dirname(this_dir)

# Load yaml file
parameter_filename = os.path.join( os.path.dirname( os.path.dirname( os.path.realpath(__file__) )),
'Tune_Cases', 'IEA15MW.yaml')
Expand All @@ -43,10 +40,7 @@
controller = ROSCO_controller.Controller(controller_params)

# Load turbine data from OpenFAST and rotor performance text file
turbine.load_from_fast(path_params['FAST_InputFile'], \
os.path.join(rt_dir,path_params['FAST_directory']), \
dev_branch=True,rot_source='txt',\
txt_filename=os.path.join(rt_dir,path_params['FAST_directory'],path_params['rotor_performance_filename']))
turbine.load_from_fast(path_params['FAST_InputFile'],path_params['FAST_directory'],dev_branch=True,rot_source=None,txt_filename=path_params['rotor_performance_filename'])

# Tune controller
controller.tune_controller(turbine)
Expand Down
4 changes: 3 additions & 1 deletion Examples/run_examples.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import unittest
import sys
from time import time
import importlib

Expand Down Expand Up @@ -100,4 +101,5 @@ def suite():


if __name__ == "__main__":
unittest.TextTestRunner().run(suite())
result = unittest.TextTestRunner().run(suite())
sys.exit(not result.wasSuccessful())
54 changes: 0 additions & 54 deletions HISTORY.md

This file was deleted.

13 changes: 7 additions & 6 deletions ROSCO_toolbox/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@ def tune_controller(self, turbine):
TSR_rated = rated_rotor_speed*R/turbine.v_rated # TSR at rated

# separate wind speeds by operation regions
v_below_rated = np.linspace(turbine.v_min,turbine.v_rated, num=30) # below rated
v_above_rated = np.linspace(turbine.v_rated,turbine.v_max, num=30)[1:] # above rated
v_below_rated = np.linspace(turbine.v_min,turbine.v_rated, num=30)[:-1] # below rated
v_above_rated = np.linspace(turbine.v_rated,turbine.v_max, num=30) # above rated
v = np.concatenate((v_below_rated, v_above_rated))

# separate TSRs by operations regions
Expand Down Expand Up @@ -189,7 +189,8 @@ def tune_controller(self, turbine):
# Find pitch angle as a function of expected operating CP for each TSR
Cp_TSR = np.ndarray.flatten(turbine.Cp.interp_surface(turbine.pitch_initial_rad, TSR_op[i])) # all Cp values for a given tsr
Cp_op[i] = np.clip(Cp_op[i], np.min(Cp_TSR), np.max(Cp_TSR)) # saturate Cp values to be on Cp surface
f_cp_pitch = interpolate.interp1d(Cp_TSR,pitch_initial_rad) # interpolate function for Cp(tsr) values
Cp_maxidx = Cp_TSR.argmax() # Find maximum Cp value for this TSR
f_cp_pitch = interpolate.interp1d(Cp_TSR[Cp_maxidx:],pitch_initial_rad[Cp_maxidx:]) # interpolate function for Cp(tsr) values
# expected operation blade pitch values
if v[i] <= turbine.v_rated and isinstance(self.min_pitch, float): # Below rated & defined min_pitch
pitch_op[i] = min(self.min_pitch, f_cp_pitch(Cp_op[i]))
Expand Down Expand Up @@ -479,7 +480,7 @@ def peak_shaving(self,controller, turbine):
else:
Ct_max[i] = np.minimum( np.max(Ct_tsr), Ct_max[i])
# Define minimum pitch angle
f_pitch_min = interpolate.interp1d(Ct_tsr, turbine.pitch_initial_rad, kind='cubic', bounds_error=False, fill_value=(turbine.pitch_initial_rad[0],turbine.pitch_initial_rad[-1]))
f_pitch_min = interpolate.interp1d(Ct_tsr, turbine.pitch_initial_rad, kind='linear', bounds_error=False, fill_value=(turbine.pitch_initial_rad[0],turbine.pitch_initial_rad[-1]))
pitch_min[i] = max(controller.min_pitch, f_pitch_min(Ct_max[i]))

controller.ps_min_bld_pitch = pitch_min
Expand All @@ -495,9 +496,9 @@ def peak_shaving(self,controller, turbine):
def min_pitch_saturation(self, controller, turbine):

# Find TSR associated with minimum rotor speed
TSR_at_minspeed = (controller.vs_minspd/turbine.Ng) * turbine.rotor_radius / controller.v_below_rated
TSR_at_minspeed = (controller.pc_minspd/turbine.Ng) * turbine.rotor_radius / controller.v_below_rated
for i in range(len(TSR_at_minspeed)):
if TSR_at_minspeed[i] > turbine.Cp.TSR_opt:
if TSR_at_minspeed[i] > controller.TSR_op[i]:
controller.TSR_op[i] = TSR_at_minspeed[i]

# Initialize some arrays
Expand Down
2 changes: 1 addition & 1 deletion ROSCO_toolbox/ofTools/util/spectral.py
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ def fnextpow2(x):
if nperseg is None:
if noverlap is None:
overlap_frac=0.5
elif noverlap == 0:
elif noverlap is 0:
overlap_frac=0
else:
raise NotImplementedError('TODO noverlap set but not nperseg')
Expand Down
Loading

0 comments on commit 198964d

Please sign in to comment.