-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit c88636a
Showing
50 changed files
with
6,259 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
# Byte-compiled / optimized / DLL files | ||
__pycache__/ | ||
*.py[cod] | ||
*$py.class | ||
|
||
# C extensions | ||
*.so | ||
uiuc*.csv | ||
|
||
# Distribution / packaging | ||
.Python | ||
build/ | ||
develop-eggs/ | ||
dist/ | ||
downloads/ | ||
eggs/ | ||
.eggs/ | ||
lib/ | ||
lib64/ | ||
parts/ | ||
sdist/ | ||
var/ | ||
wheels/ | ||
.vscode/ | ||
pip-wheel-metadata/ | ||
share/python-wheels/ | ||
*.egg-info/ | ||
.installed.cfg | ||
*.egg | ||
MANIFEST | ||
|
||
# PyInstaller | ||
# Usually these files are written by a python script from a template | ||
# before PyInstaller builds the exe, so as to inject date/other infos into it. | ||
*.manifest | ||
*.spec | ||
|
||
# Installer logs | ||
pip-log.txt | ||
pip-delete-this-directory.txt | ||
|
||
# Unit test / coverage reports | ||
htmlcov/ | ||
.tox/ | ||
.nox/ | ||
.coverage | ||
.coverage.* | ||
.cache | ||
nosetests.xml | ||
coverage.xml | ||
*.cover | ||
*.py,cover | ||
.hypothesis/ | ||
.pytest_cache/ | ||
|
||
# Translations | ||
*.mo | ||
*.pot | ||
|
||
# Django stuff: | ||
*.log | ||
local_settings.py | ||
db.sqlite3 | ||
db.sqlite3-journal | ||
|
||
# Flask stuff: | ||
instance/ | ||
.webassets-cache | ||
|
||
# Scrapy stuff: | ||
.scrapy | ||
|
||
# Sphinx documentation | ||
docs/_build/ | ||
|
||
# PyBuilder | ||
target/ | ||
|
||
# Jupyter Notebook | ||
.ipynb_checkpoints | ||
|
||
# IPython | ||
profile_default/ | ||
ipython_config.py | ||
|
||
# pyenv | ||
.python-version | ||
|
||
# pipenv | ||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. | ||
# However, in case of collaboration, if having platform-specific dependencies or dependencies | ||
# having no cross-platform support, pipenv may install dependencies that don't work, or not | ||
# install all needed dependencies. | ||
#Pipfile.lock | ||
|
||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow | ||
__pypackages__/ | ||
|
||
# Celery stuff | ||
celerybeat-schedule | ||
celerybeat.pid | ||
|
||
# SageMath parsed files | ||
*.sage.py | ||
|
||
# Environments | ||
.env | ||
.venv | ||
env/ | ||
venv/ | ||
ENV/ | ||
env.bak/ | ||
venv.bak/ | ||
|
||
# Spyder project settings | ||
.spyderproject | ||
.spyproject | ||
|
||
# Rope project settings | ||
.ropeproject | ||
|
||
# mkdocs documentation | ||
/site | ||
|
||
# mypy | ||
.mypy_cache/ | ||
.dmypy.json | ||
dmypy.json | ||
|
||
# Pyre type checker | ||
.pyre/ | ||
|
||
# Large files | ||
test*.pt | ||
train*.pt | ||
*.off | ||
*.tar.gz | ||
*.DS_Store | ||
*.npz | ||
*.csv | ||
*.pt.tar | ||
|
||
|
||
.vscode/ | ||
*.gz | ||
*.cp | ||
*.tar | ||
*.pth | ||
*.h5 | ||
*.tmp | ||
*$* | ||
*.pickle | ||
*.txt | ||
*.pt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# Airfoil Learning | ||
The goal of this repository is to outline a method of using graph neural networks and deep neural networks to predict the Lift and Drag of 2D Airfoils. Graph Neural Networks investigate the relationship between nodes through edges and edge attributes. Graph relationships are all around us, our social networks on Facebook, the products we purchase or are interested in on Amazon, molecular interactions. This project investigates using the connectivity of points that describe a 2D airfoil to predict performance. | ||
|
||
## Data Structure | ||
|
||
* (Feature) Vertices (x,y,z) | ||
* (Feature) Edge_Connectivity (edge_index1,edge_index2) | ||
* (Feature) Reynolds - flow velocity | ||
* (Feature) Ncrit - turbulence parameter | ||
* (Feature) Alpha - angle of attack | ||
* (Label) Cl - Coefficient of Lift | ||
* (Label) Cd - Coefficient of Drag | ||
* (Label) Cm - Coefficient of Moment | ||
* (Label) Cp - Pressure coefficient | ||
|
||
Useful documentation on torch data object | ||
* [Data Class](https://pytorch-geometric.readthedocs.io/en/latest/_modules/torch_geometric/data/data.html#Data) | ||
* [In-Memory Datasets](https://pytorch-geometric.readthedocs.io/en/latest/notes/create_dataset.html#creating-in-memory-datasets) | ||
* [Datasets](https://pytorch-geometric.readthedocs.io/en/latest/notes/create_dataset.html#creating-larger-datasets) | ||
|
||
|
||
# Wiki links | ||
[Getting Started with your Environment](https://gitlab.grc.nasa.gov/machine-learning/graph-networks/airfoil-learning/-/wikis/1.0-Getting-Started) | ||
|
||
# Link to Dataset | ||
Dataset can be found at https://nasa-public-data.s3.amazonaws.com/plot3d_utilities/airfoil-learning-dataset.zip | ||
|
||
# Reporting Bugs | ||
To report bugs, add a github issue. Instructions for adding github issues: https://www.youtube.com/watch?v=TKJ4RdhyB5Y | ||
|
||
# License | ||
[NASA Open Source Agreement](https://opensource.org/licenses/NASA-1.3) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import torch | ||
import matplotlib.pyplot as plt | ||
import glob | ||
import os.path as osp | ||
import numpy as np | ||
import pandas as pd | ||
from utils import csapi | ||
|
||
# Folders | ||
data = pd.read_pickle('scraped_airfoils_cp_clean.gz') | ||
airfoil_names = data['name'].unique() | ||
name = airfoil_names[np.random.randint(0,len(airfoil_names))] | ||
print(name) | ||
|
||
airfoil = data[data.name==name] | ||
xss = np.array(airfoil['xss'])[0]; yss = np.array(airfoil['yss'])[0]; xps = np.array(airfoil['xps'])[0]; yps = np.array(airfoil['yps'])[0] | ||
|
||
xv = np.linspace(0,1,20) # ! This fixes the number of points | ||
|
||
yss_v = csapi(xss,yss,xv) | ||
yps_v = csapi(xps,yps,xv) | ||
|
||
x = np.concatenate( (xss, np.flip(xps[1:-1])) ) | ||
y = np.concatenate( (yss, np.flip(yps[1:-1])) ) | ||
|
||
polars = airfoil['polars'].iloc[0] | ||
polars = polars[polars.Reynolds==100000] | ||
polars = polars[polars.Ncrit==5] | ||
alpha = polars.alpha | ||
Cl = polars.Cl | ||
Cp = np.concatenate(( polars.iloc[50].Cp_ss, np.flip( polars.iloc[50].Cp_ps[1:-1]) )) | ||
|
||
|
||
# # Plot the Airfoil | ||
# fig,ax = plt.subplots(1,1) | ||
# x = np.concatenate((xss,np.flip(xps[1:-1]))) | ||
# y = np.concatenate((yss,np.flip(yps[1:-1]))) | ||
|
||
# x2 = np.concatenate((xv,np.flip(xv[1:-1]))) | ||
# y2 = np.concatenate((yss_v,np.flip(yps_v[1:-1]))) | ||
# # ax.plot(x,y, color='black', linestyle='solid', linewidth=2,marker='o', label='{0} points'.format(len(x))) | ||
# ax.plot(x2,y2, color='red', linestyle='dashed', linewidth=4,marker='^', markersize=12,label='{0} points'.format(len(x2))) | ||
# ax.set(xlim=(-0.05,1.05), ylim=(-0.15, 0.15)) | ||
# ax.legend(loc='lower right') | ||
# ax.set_xlabel('x') | ||
# ax.set_ylabel('y') | ||
# ax.set_aspect('equal') | ||
# fig.canvas.draw() | ||
# fig.canvas.flush_events() | ||
# plt.show() | ||
|
||
# fig,ax = plt.subplots(1,1) | ||
# # Plot Cl vs Alpha for a given Reynolds, Ncrit | ||
# ax.plot(alpha,Cl, color='black', linestyle='solid', linewidth=2, label=name) | ||
# ax.legend(loc='lower right') | ||
# ax.set_xlabel('alpha [deg]') | ||
# ax.set_ylabel('Cl') | ||
|
||
# fig.canvas.draw() | ||
# fig.canvas.flush_events() | ||
# plt.show() | ||
|
||
fig,ax = plt.subplots(1,1) | ||
# Plot Cl vs Alpha for a given Reynolds, Ncrit | ||
ax.plot(x,Cp, color='blue', linestyle='None', linewidth=2,marker='^', markersize=5, label=name) | ||
ax.invert_yaxis() | ||
ax.legend(loc='lower right') | ||
ax.set_xlabel('x/c') | ||
ax.set_ylabel('Cp') | ||
|
||
fig.canvas.draw() | ||
fig.canvas.flush_events() | ||
plt.show() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# Generate XFOIL | ||
This folder has files needed to mine the airfoils and data from airfoil-tools.com. | ||
|
||
# Installation | ||
pip install -r requirements.txt | ||
|
||
## Pytorch and Pytorch Geometric | ||
These are the versions used at the time of testing. It may work with newer versions, if not please fix and submit a pull request or file a github issue. | ||
|
||
- **CPU**: pip3 install torch==1.10.1+cu113 torchvision==0.11.2+cu113 torchaudio===0.10.1+cu113 -f https://download.pytorch.org/whl/cu113/torch_stable.html | ||
- **GPU**: pip3 install torch torchvision torchaudio | ||
- **Cpu version of PyTorch Geometric**: `pip install torch-scatter torch-sparse torch-cluster torch-spline-conv torch-geometric -f https://data.pyg.org/whl/torch-1.10.0+cpu.html` | ||
- **GPU version of PyTorch Geometric**: `pip install torch-scatter torch-sparse torch-cluster torch-spline-conv torch-geometric -f https://data.pyg.org/whl/torch-1.10.0+cu113.html` | ||
|
||
# Summary of the files and what they do | ||
## Step1_GatherData.py | ||
This file mines the website airfoil-tools.com and downloads each airfoil to data/scrape folder. | ||
|
||
### Requirements | ||
- bs4: Beautiful soup | ||
|
||
--- | ||
**NOTE** | ||
|
||
This may not work if airfoil-tools changes their website. | ||
|
||
--- | ||
|
||
## Step2_XfoilScrapedData.py | ||
This file processes the airfoils in data/scrape folder. **This code is intended to be run on ubuntu.** It will loop through each of the files and run the xfoil simulation gathering data on Cl, Cd, Cdp, Cm, and Cp distribution for each angle of attack. The results are then interpolated such that every airfoil has the same number of points for the geometry as well as for the Cp distribution. The `pchip` method is used to interpolate the data. | ||
|
||
The results from Step2_XfoilScrapedData.py are saved to json/ folder. | ||
|
||
## Step3_NormalizeData.py | ||
After processing all the scraped airfoils into json. The data needs to be normalized so that each of the values `alpha`, `Re`, `NCrit` are of the same scale from 0 to 1 for example. Normalizing is done in 2 ways. First method uses `StandardScaler` which normalizes the data with mean and standard deviation. This is probably the most ideal if you think there maybe some extremes such as `Cp` is very high for a particular airfoil at a certain point. The second method is called `minmax` this normalizes all the data between 0 and 1. This method is ideal if you truely know all your data is of a certain range and there are no extremes. | ||
|
||
This file creates a scalers.pickle file with all the normization parameters to do either the `StandardScaler` or `minmax` | ||
|
||
## Step4_CreateDataset.py | ||
This takes the normalization file `scalers.pickle` and normalizes all the jsons then saves the results to `datasets/` folder. | ||
|
||
### What is inside the datasets folder? | ||
Inside you will see the following | ||
- dnn_scaled_cp_test.pt : Deep Neural Network data format with Cp values for test | ||
- dnn_scaled_cp_train.pt : Deep Neural Network data format with Cp values for train | ||
- dnn_scaled_test.pt : Deep Neural Network data format with only Cl, Cd, Cdp, Cm for test | ||
- dnn_scaled_train.pt : Deep Neural Network data format with only Cl, Cd, Cdp, Cm for train | ||
- graph_scaled_cp_test.pt : Graph Neural Network data format with Cp values for test | ||
- graph_scaled_cp_train.pt : Graph Neural Network data format with Cp values for train | ||
- graph_scaled_test.pt : Graph Neural Network data format with only Cl, Cd, Cdp, Cm for test | ||
- graph_scaled_train.pt : Graph Neural Network data format with only Cl, Cd, Cdp, Cm for train | ||
|
||
## view_data.py | ||
This file does 2 things. | ||
1. It reads a all json generated by Step2 and plots is used to plot the max bounds of y/c | ||
 | ||
|
||
|
||
2. It picks a random airfoil and plots the results | ||
 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
'''' | ||
Reads through all the Json files and resizes the Cp. Writes the data back to a separate json_cp_resize folder | ||
''' | ||
import os, glob | ||
import os.path as osp | ||
from libs.utils import pchip | ||
import json | ||
from tqdm import trange | ||
import numpy as np | ||
import copy | ||
|
||
new_save_dir = 'json_cp_resize' | ||
os.makedirs(new_save_dir,exist_ok=True) | ||
|
||
cp_points = 50 | ||
|
||
x_cp = np.linspace(0,1,cp_points) | ||
data_files = glob.glob(osp.join('json','*.json')) | ||
pbar = trange(len(data_files),desc='Processing') | ||
for i in pbar: | ||
filename = data_files[i] | ||
with open(filename,'r') as f: | ||
airfoil = json.load(f) | ||
new_airfoil = copy.deepcopy(airfoil) | ||
|
||
xss = airfoil['xss'] | ||
yss = airfoil['yss'] | ||
|
||
xps = airfoil['xps'] | ||
yps = airfoil['yps'] | ||
|
||
for p in range(len(airfoil['polars'])): | ||
polar = airfoil['polars'][p] | ||
|
||
Cp_ss = np.array(polar['Cp_ss']) | ||
Cp_ps = np.array(polar['Cp_ps']) | ||
|
||
# Resize cp | ||
Cp_ss = pchip(xss,Cp_ss,x_cp) # from 0 to 1 | ||
Cp_ps = pchip(xps,Cp_ps,x_cp) # use xss here because we need same length for cp | ||
|
||
new_airfoil['polars'][p]['Cp_ss'] = Cp_ss.tolist() | ||
new_airfoil['polars'][p]['Cp_ps'] = Cp_ps.tolist() | ||
|
||
with open(osp.join(new_save_dir,osp.basename(filename)),'w') as f2: | ||
json.dump(new_airfoil,f2) |
Oops, something went wrong.