Skip to content

Commit

Permalink
Merge pull request #81 from OpenFAST/f/rename
Browse files Browse the repository at this point in the history
Renaming pyFAST to openfast_toolbox  (see #38 and #60)
  • Loading branch information
ebranlard committed Nov 27, 2023
2 parents 5157125 + 0a82bb5 commit 3446a77
Show file tree
Hide file tree
Showing 377 changed files with 10,572 additions and 9,762 deletions.
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()


File renamed without changes.
File renamed without changes.
File renamed without changes.
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

0 comments on commit 3446a77

Please sign in to comment.