Skip to content
This repository was archived by the owner on Nov 27, 2023. It is now read-only.
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
34 changes: 17 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# pyfast
# openfast_toolbox

[![Build status](https://github.com/openfast/python-toolbox/workflows/Development%20Pipeline/badge.svg)](https://github.com/OpenFAST/python-toolbox/actions?query=workflow%3A%22Development+Pipeline%22)
[![Python: 3.6+](https://img.shields.io/badge/python-3.6%2B-informational)](https://www.python.org/)
Expand All @@ -22,21 +22,21 @@ pytest

The repository contains a set of small packages:

- input\_output: read/write OpenFAST/FAST.Farm/OLAF input and output files (see [README](pyFAST/input_output))
- postpro: postprocess OpenFAST outputs (extract radial data, compute fatigue loads) (see [examples](pyFAST/postpro/examples))
- linearization: tools to deal with OpenFAST linearization, e.g. generate a Campbell diagram (see [examples](pyFAST/linearization/examples/))
- input\_output: read/write OpenFAST/FAST.Farm/OLAF input and output files (see [README](openfast_toolbox/io))
- postpro: postprocess OpenFAST outputs (extract radial data, compute fatigue loads) (see [examples](openfast_toolbox/postpro/examples))
- linearization: tools to deal with OpenFAST linearization, e.g. generate a Campbell diagram (see [examples](openfast_toolbox/linearization/examples/))
- aeroacoustics: tools for aeroacoustics (generate BL files and plot outputs)
- case\_generation: tools to generate and run a set of input of OpenFAST input files (see [examples](pyFAST/case_generation/examples))
- case\_generation: tools to generate and run a set of input of OpenFAST input files (see [examples](openfast_toolbox/case_generation/examples))


## QuickStart and main usage

### Read and write files
Find examples scripts in this [folder](pyFAST/input_output/examples) and the different fileformats [here](pyFAST/input_output).
Find examples scripts in this [folder](openfast_toolbox/io/examples) and the different fileformats [here](openfast_toolbox/io).

Read an AeroDyn file (or any OpenFAST input file), modifies some values and write the modified file:
```python
from pyFAST.input_output import FASTInputFile
from openfast_toolbox.io import FASTInputFile
filename = 'AeroDyn.dat'
f = FASTInputFile(filename)
f['TwrAero'] = True
Expand All @@ -46,15 +46,15 @@ f.write('AeroDyn_Changed.dat')

Read an OpenFAST binary output file and convert it to a pandas DataFrame
```python
from pyFAST.input_output import FASTOutputFile
from openfast_toolbox.io import FASTOutputFile
df = FASTOutputFile('5MW.outb').toDataFrame()
time = df['Time_[s]']
Omega = df['RotSpeed_[rpm]']
```

Read a TurbSim binary file, modify it and write it back
```python
from pyFAST.input_output import TurbSimFile
from openfast_toolbox.io import TurbSimFile
ts = TurbSimFile('Turb.bts')
print(ts.keys())
print(ts['u'].shape)
Expand All @@ -63,27 +63,27 @@ tw.write('NewTurbulenceBox.bts')
```

### Polar/airfoil manipulation
Find examples scripts in this [folder](pyFAST/polar/examples).
Find examples scripts in this [folder](openfast_toolbox/polar/examples).


Read a CSV file with `alpha, Cl, Cd, Cm`, and write it to AeroDyn format (also computes unsteady coefficients)
```python
from pyFAST.airfoils.Polar import Polar
polar = Polar('pyFAST/airfoils/data/DU21_A17.csv', fformat='delimited')
from openfast_toolbox.airfoils.Polar import Polar
polar = Polar('openfast_toolbox/airfoils/data/DU21_A17.csv', fformat='delimited')
ADpol = polar.toAeroDyn('AeroDyn_Polar_DU21_A17.dat')
```

### Write a set of OpenFAST input file for multiple simulations
Find examples scripts in this [folder](pyFAST/case_generation/examples).
Find examples scripts in this [folder](openfast_toolbox/case_generation/examples).

### Postprocessing

Below are different scripts to manipulate OpenFAST outputs:

- [Extract average radial data](pyFAST/postpro/examples/Example_RadialPostPro.py).
- [Interpolate data at different radial positions](pyFAST/postpro/examples/Example_RadialInterp.py).
- [Compute damage equivalent loads](pyFAST/postpro/examples/Example_EquivalentLoad.py).
- [Change column names and units](pyFAST/postpro/examples/Example_Remap.py).
- [Extract average radial data](openfast_toolbox/postpro/examples/Example_RadialPostPro.py).
- [Interpolate data at different radial positions](openfast_toolbox/postpro/examples/Example_RadialInterp.py).
- [Compute damage equivalent loads](openfast_toolbox/postpro/examples/Example_EquivalentLoad.py).
- [Change column names and units](openfast_toolbox/postpro/examples/Example_Remap.py).


## Future work and friend projects
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
Script to postprocess linearization files from OpenFAST for one operating point.

Adapted from:
https://github.com/OpenFAST/python-toolbox/blob/dev/pyFAST/linearization/examples/ex2a_MultiLinFiles_OneOP.py
https://github.com/OpenFAST/python-toolbox/blob/dev/openfast_toolbox/linearization/examples/ex2a_MultiLinFiles_OneOP.py

"""
import os
import glob
import numpy as np
import pyFAST
import pyFAST.linearization as lin
import openfast_toolbox
import openfast_toolbox.linearization as lin

## Script Parameters
fstFile = './Main.fst' # Main .fst file, .lin files will be sought for with same basename
Expand Down
2 changes: 1 addition & 1 deletion data/linearization_outputs/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
The outputs in this directory should match the ones given by the example script:
pyFAST/linearization/runCampbell.
openfast_toolbox/linearization/runCampbell.

Using the 5MW Land turbine, at given operating points.

Expand Down
76 changes: 76 additions & 0 deletions developper_notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Developer Notes



## Release Steps
Typically releases are done for each new version of OpenFAST

1. Create a pull request from main to dev
2. Make sure the input files in the `data` directory are compatible with the new OpenFAST version
3. Change the file VERSION (and/or setup.py) and push to the pull request
4. Merge pull request to main
5. Tag the commit using `git tag -a vX.X.X` and push to remote: `git push --tags``.
6. Upload to pypi and conda (see below)
7. Merge main to dev


## Upload a new version for pip
Detailled steps are provided further below.

### Summary
Remember to change VERSION file and/or setup.py
```bash
python setup.py sdist
twine upload dist/* # upload to pypi
```



### (Step 0 : create an account on pypi)

### Step 1: go to your repo
Go to folder
```bash
cd path/to/python-toolbox
```

### Step 2: change version in setup.py and tag it
change VERSION in setup.py
```
git add setup.py VERSION
git commit "Version X.X.X"
git tag -a
```

### Step 3: Create a source distribution
```bash
python setup.py sdist
```

### Step 4: Install twine
```bash
pip install twine
```

### Step 5: Ubplot to pypi
Run twine to upload to Pypi (will ask for username and password)
```bash
twine upload dist/*
```

### After clone / first time
Add `.gitconfig` to your path, to apply filters on jupyter notebooks
```bash
git config --local include.path ../.gitconfig
```



## Upload a new version to Conda
TODO TODO TODO

conda-forge,
make a pull request there.
- setup build script (https://conda-forge.org/docs/maintainer/adding_pkgs.html).
see e.g. FLORIS (https://github.com/conda-forge/floris-feedstock/blob/master/recipe/meta.yaml).
- make a pull request to https://github.com/conda-forge/staged-recipes/
14 changes: 14 additions & 0 deletions openfast_toolbox/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""Initialize everything"""
import os
from openfast_toolbox.common import *
# Make main io tools available
from .io import read
from .io.fast_input_file import FASTInputFile
from .io.fast_output_file import FASTOutputFile
from .io.fast_input_deck import FASTInputDeck

# Add version to package
with open(os.path.join(os.path.dirname(__file__), "..", "VERSION")) as fid:
__version__ = fid.read().strip()


86 changes: 86 additions & 0 deletions openfast_toolbox/aeroacoustics/examples/_plot_directivity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from parse import *
import re, os, platform
from openfast_toolbox.io.fast_output_file import FASTOutputFile

#########################################################################################################################################
## User inputs
# Save plot and/or data?
save_fig = False
save_data = False
fig_ext = '.png'

# Number of revolutions (n) to average spectra
n = 1

#########################################################################################################################################
## Paths to files
if platform.system() == 'Windows':
FAST_directory = os.path.dirname( os.path.dirname( os.path.dirname( os.path.dirname( os.path.realpath(__file__) ) ) ) ) + os.sep + 'reg_tests' + os.sep + 'r-tests' + os.sep + 'glue-codes' + os.sep + 'openfast' + os.sep + 'IEA_LB_RWT-AeroAcoustics'
else:
FAST_directory = os.path.dirname( os.path.dirname( os.path.dirname( os.path.dirname( os.path.realpath(__file__) ) ) ) ) + os.sep + 'openfast' + os.sep + 'reg_tests' + os.sep + 'r-tests' + os.sep + 'glue-codes' + os.sep + 'openfast' + os.sep + 'IEA_LB_RWT-AeroAcoustics'
AAfilename = FAST_directory + os.sep + 'IEA_LB_RWT-AeroAcoustics_1.out'
OFfilename = FAST_directory + os.sep + 'IEA_LB_RWT-AeroAcoustics.out'
locfilename = FAST_directory + os.sep + 'AA_ObserverLocations_Map.dat'
output_dir = os.path.dirname( os.path.realpath(__file__) )
outputfilename = output_dir + os.sep + "data_output1"

#########################################################################################################################################
## Read in data, manipulate it, and plot it
# reads in file data
AA_1 = FASTOutputFile(AAfilename).toDataFrame()
OF = FASTOutputFile(OFfilename).toDataFrame()
location = pd.read_csv(locfilename,delimiter='\s+',skiprows=[0,1],names=['x','y','z'])

# determine number of observers
num_obs = AA_1.shape[1]-1

# calculate sample time for n revolutions
rpm = OF[["RotSpeed_[rpm]"]].mean()[0]
yaw = OF[["YawPzn_[deg]"]].mean()[0] / 180. * np.pi
time_revs = n*60/rpm
tot_time = AA_1["Time_[s]"].max()
if time_revs < tot_time:
sample_time = tot_time - time_revs
else:
print("Error: Time for number of revolutions exceeds simulation time. Reduce n.")
raise SystemExit('')

# slice AA dataframe for t > sample_time
AA_1 = AA_1[AA_1["Time_[s]"] > sample_time]
AA_1=AA_1.drop("Time_[s]",axis=1)

# average P over rotor revolution
AA_1 = AA_1.mean()

# merge location info with SPL info
AA_1=AA_1.reset_index()
AA_1=AA_1.drop("index",axis=1)
AA_1=pd.merge(location,AA_1,left_index=True,right_index=True)
AA_1=AA_1.rename(index=str,columns={0:"SPL"})

# contour plot of SPL for each location
if num_obs < 3:
print("Error: Need at least 3 observers to generate contour.")
else:
x=AA_1['x'];
y=AA_1['y'];
z=AA_1['SPL'];
fs = 10
fig,ax=plt.subplots()
ax.set_aspect('equal')
ax.set_xlabel('x [m]', fontsize=fs+2, fontweight='bold')
ax.set_ylabel('y [m]', fontsize=fs+2, fontweight='bold')
tcf=ax.tricontourf(x,y,z, range(58, 84, 1))
fig.colorbar(tcf,orientation="vertical").set_label(label = 'Overall SPL [dB]', fontsize=fs+2,weight='bold')
if save_fig == True:
fig_name = 'directivity_map'
fig.savefig(output_dir + os.sep + fig_name + fig_ext)
plt.show()

# export to csv
if save_data == True:
AA_1.to_csv(r'{}-data.csv'.format(outputfilename))

Loading