# Airfoil Learning Tutorial
In this tutorial you will learn how to run the code provided to setup the code for training.
Data Processing
1. Downloading the Dataset
2. Normalization
3. Creating the Graph Network Database (This can take time)
4. Creating Multilayer Perception Database (Done with step 3)

Training
1. Data fractionalizing - The entire dataset is large and can take a long time to train. This step takes a fraction of the data and uses it for training
2. Train Graph Network
3. Train Multilayer Perception

**Outcome of this tutorial**
When you look through the code, you'll be more familar with how it works. What file does what. This tutorial is a walk through of the code cited in the readme.md inside of `generate_xfoil` and `pytorch` folders.

# Background
The section below describes some of the theory behind Lift, Drag, Moment, and Pressure. You don't need to understand everything in detail but if you wanted to, there's good references.

**To the students**: feel free to file a github issue with documentation if something is unclear or you have questions.

**To the instructors**: if something is unclear, please help make this documentation better by making changes and doing a pull request.

The image below is a airfoil. Airfoils are a 2D cross section of an airplane wing. These are some of the parameters used to characterize an airfoil.

## Performance Characterization
Airfoil performance are characterized by normalized Lift, Drag, and Moment coefficients. Think of Lift as a force pushing the airfoil up in the presence of air flow. In order to have Lift, you need to have Drag; however, not all airfoils have the same efficiency, some produce more lift with less drag than others at certain conditions.

### Lift
To understand what Lift is, you need to understand pressure forces. These are upward and downward forces distributed along the airfoil. When you integrate the **vertical** component of the pressure force $p(x)$ there's a certain location where everything equals to 0, this is called the center of pressure. In a freebody diagram, this is the balancing point where lift is acting on.

\begin{align}
x_{cp} = \int_{x_{LE}}^{x_{TE}} \frac{x p(x)}{p(x)}
\end{align}

The coefficient of lift is simply the total lift force (L) normalized by the dynamic pressure $q=0.5 \rho V^2$

\begin{align}
C_L = \frac{L}{q}
\end{align}

### Moment

Moment coefficient or pitching moment coefficient affects how the airfoil want to pitch based on airflow and angle of attack of which the air is impacting the airfoil. Moment acts on the aerodytnamic center $x_{ac}$. This is the point where all moment forces are 0.

The equation is the moment which is equal to $M=L*d$ where $d$ is the distance from the center of pressure to the aerodynamic center (Point at which moment forces are 0)

\begin{align}
C_{M} = \frac{M}{Sc 0.5\rho V^2}
\end{align}

To compute the aerodynamic center $x_{ac}$ you need to know how the coefficient of moment changes with angle of attack $\frac{dCm}{d\alpha}$ and how the coefficient of lift changes with angle of attack $\frac{dCl}{d\alpha}$. These comes from simulations with [XFOIL](https://web.mit.edu/drela/Public/web/xfoil/) (Note: XFLR is running xfoil in the background) or a Computational Fluid Dynamics (CFD) Tool. Xfoil uses $0.25*c$ or 25% of the chord as a reference x-value in computing the coefficient of moment.

What we are computing below is the aerodynamic center of the wing. This is where the moment is 0. For airfoil stability, the aerodynamic center should be in front of the center of gravity - the airfoil will want to pitch upwards as opposed to downwards toward the earth.

\begin{align}
x_{ac} = -\frac{ \frac{dC_M}{d\alpha} }{ \frac{dCl}{d\alpha} }+ 0.25
\end{align}

> Good reference for Lift-Drag-Moment Coefficient https://aerotoolbox.com/lift-drag-moment-coefficient/

> XFoil Documentation
> See: http://web.mit.edu/aeroutil_v1.0/xfoil_doc.txt

### Drag

Airfoil drag is a combination of **viscous drag forces** and **pressure drag forces**.

#### Viscous Drag
Viscous drag is due to shear forces boundary layer. A fluid particle at the surface of a body has 0 velocity, but as you go further from the surface, the velocity is equal to the free stream. This region is the boundary layer. The boundary layer can be laminar, transitional, or turbulent. In simple airfoil theory, e^N transition model is used to determine the state of the boundary layer

> Laminar boundary layer
> https://en.wikipedia.org/wiki/Blasius_boundary_layer

> $e^N$ Transition Criteria
> https://arc.aiaa.org/doi/10.2514/6.2003-4066

Understanding the state of the boundary layer is important for the next step which is to compute the height of the boundary layer. The height is used to compute momentum thickness which is then used to compute the drag.

> Emperical correlations for boundary layer thickness https://en.wikipedia.org/wiki/Boundary_layer_thickness

Using equation 19.19 from http://www.ase.uc.edu/class/AEEM456/Section_3_Notes.pdf and correlations, it's possible to estimate the shear stress which is the viscous stress.

#### Pressure Drag
Pressure drag is caused by the pressure forces acting **axially** $P\hat{x}$ on the airfoil. Pressure is alway normal to the surface so if the surface is at an inclination you can break down pressure into two components a vertical component $P\hat{y}$ and a horizontal/axial component $P\hat{x}$. $P\hat{y}$ is used for calculating lift and $P\hat{x}$ for drag. This is the simple explaination. This is what panel code uses to compute pressure drag.

## Cloning the Project
This section shows how to create a dataset for training purposes

```python
!git clone https://github.com/nasa/airfoil-learning.git
!cp -r airfoil-learning/generate_xfoil/* .
```

    Cloning into 'airfoil-learning'...
    remote: Enumerating objects: 71, done.
    remote: Counting objects: 100% (71/71), done.
    remote: Compressing objects: 100% (60/60), done.
    remote: Total 71 (delta 13), reused 59 (delta 6), pack-reused 0
    Unpacking objects: 100% (71/71), done.

# Data Processing
To begin data processing, the notebook structure needs to be reorganized. This is not needed when dealing with the actual code on your computer. Jupyter notebook does not allow you to change root directories so we have to copy everything to the root and process it then move it back.

## Downloading the Dataset
Download the dataset by running the code below. Contents of airfoil-learning/generate_xfoil are copied to root path. This is because you cannot change your working directory from within a jupyter notebook

```python
!rm -rf json/
!wget https://nasa-public-data.s3.amazonaws.com/plot3d_utilities/airfoil-learning-dataset.zip
!unzip airfoil-learning-dataset.zip
!rm airfoil-learning-dataset.zip

```

    --2022-03-23 14:40:18--  https://nasa-public-data.s3.amazonaws.com/plot3d_utilities/airfoil-learning-dataset.zip
    Resolving nasa-public-data.s3.amazonaws.com (nasa-public-data.s3.amazonaws.com)... 52.216.204.163
    Connecting to nasa-public-data.s3.amazonaws.com (nasa-public-data.s3.amazonaws.com)|52.216.204.163|:443... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 1569105133 (1.5G) [application/zip]
    Saving to: ‘airfoil-learning-dataset.zip’

    airfoil-learning-da 100%[===================>]   1.46G  54.5MB/s    in 29s

    2022-03-23 14:40:47 (52.0 MB/s) - ‘airfoil-learning-dataset.zip’ saved [1569105133/1569105133]

    Archive:  airfoil-learning-dataset.zip
      inflating: json/2032c-il - 20-32C AIRFOIL.json
      inflating: json/a18-il - A18 (original).json
      inflating: json/a63a108c-il - NASA_AMES 63A108 MOD C AIRFOIL.json
      inflating: json/ag04-il - AG04.json
      inflating: json/ag09-il - AG09.json
      inflating: json/ag11-il - AG11.json
      inflating: json/ag13-il - AG13.json
      inflating: json/ag16-il - AG16.json
      inflating: json/ag18-il - AG18.json
      inflating: json/ag24-il - AG24 Bubble Dancer DLG by Mark Drela.json
      inflating: json/ag26-il - AG26 Bubble Dancer DLG by Mark Drela.json
      inflating: json/ag35-il - AG35.json
      inflating: json/ag37-il - AG37.json
      inflating: json/ag44ct02r-il - AG44ct -02f.json
      inflating: json/ag45c03-il - AG45c -03f.json
      inflating: json/ag46c03-il - AG46c -03f.json
      inflating: json/ag47c03-il - AG47c -03f.json
      inflating: json/ah21-7-il - AH21 7% version (Andrew Hollom).json
      inflating: json/ah63k127-il - AH 63-K-127_24.json
      inflating: json/ah7476-il - AH-7-47-6 AIRFOIL.json
      inflating: json/ah79100b-il - AH 79-100 B AIRFOIL.json
      inflating: json/ah79k132-il - AH 79-K-132_20.json
      inflating: json/ah79k143-il - AH 79-K-143_18.json
      inflating: json/ah80136-il - AH 80-136.json
      inflating: json/ah81131-il - AH 81-131.json
      inflating: json/ah81k144wfklappe-il - AH 81-K-144 W-F KLAPPE.json
      inflating: json/ah82150f-il - AH 82-150 F.json
      inflating: json/ah83159-il - AH 83-159.json
      inflating: json/ah88k130-il - AH 88-K-130_20.json
      inflating: json/ah93156-il - AH 93-156.json
      inflating: json/ah93k130-il - AH 93-K-130_15.json
      inflating: json/ah93k132-il - AH 93-K-132_15.json
      inflating: json/ah93w174-il - AH 93-W-174.json
      inflating: json/ah93w257-il - AH 93-W-257.json
      inflating: json/ah93w480b-il - AH 93-W-480B.json
      inflating: json/ah94156-il - AH 94-156.json
      inflating: json/ah95160-il - AH 95-160.json
      inflating: json/ames02-il - NASA_AMES A-02 AIRFOIL.json
      inflating: json/amsoil1-il - RUTAN CANARD AIRFOIL.json
      inflating: json/apex16-il - Apex 16 (normalized using XFOIL date021206).json
      inflating: json/arad10-il - ARA-D 10% AIRFOIL.json
      inflating: json/arad20-il - ARA-D 20% AIRFOIL.json
      inflating: json/as5045-il - AS5045 (15%).json
      inflating: json/as5048-il - AS5048 (18%).json
      inflating: json/august160-il - AUGUST 160.json
      inflating: json/b29root-il - B-29 ROOT AIRFOIL.json
      inflating: json/b540ols-il - BELL 540 AIRFOIL (MODIFIED NACA 0012).json
      inflating: json/b707b-il - BOEING 707 .19 SPAN AIRFOIL.json
      inflating: json/b707d-il - BOEING 707 .54 SPAN AIRFOIL.json
      inflating: json/b737a-il - BOEING 737 ROOT AIRFOIL.json
      inflating: json/b737c-il - BOEING 737 MIDSPAN AIRFOIL.json
      inflating: json/bacj-il - BOEING AIRFOIL J (no closed TE).json
      inflating: json/bacxxx-il - BOEING BACXXX AIRFOIL.json
      inflating: json/be50-il - BE50 (original).json
      inflating: json/boe103-il - BOEING 103 AIRFOIL.json
      inflating: json/bqm34-il - RYAN BQM-34 FIREBEE WING AIRFOIL.json
      inflating: json/c141a-il - LOCKHEED C-141 BL0 AIRFOIL.json
      inflating: json/c141c-il - LOCKHEED C-141 BL426.57 AIRFOIL.json
      inflating: json/c141e-il - LOCKHEED C-141 BL761.11 AIRFOIL.json
      inflating: json/c5a-il - LOCKHEED C-5A BL0 AIRFOIL.json
      inflating: json/c5c-il - LOCKHEED C-5A BL576 AIRFOIL.json
      inflating: json/c5e-il - LOCKHEED C-5A BL1256 AIRFOIL.json
      inflating: json/cast102-il - CAST 10-2_DOA 2 AIRFOIL.json
      inflating: json/chen-il - CHEN AIRFOIL.json
      inflating: json/clarkv-il - CLARK V AIRFOIL.json
      inflating: json/clarkx-il - CLARK X AIRFOIL.json
      inflating: json/clarkyh-il - CLARK YH AIRFOIL.json
      inflating: json/clarkysm-il - CLARK-Y 11.7% smoothed.json
      inflating: json/clarym15-il - CLARK YM-15 AIRFOIL.json
      inflating: json/coanda1-il - Coanda 1.json
      inflating: json/coanda3-il - Coanda 3.json
      inflating: json/cp-060-050-gn - Cambered plate C=6% T=5% R=2.11.json
      inflating: json/cp-100-050-gn - Cambered plate C=10% T=5% R=1.3.json
      inflating: json/cp-140-050-gn - Cambered plate C=14% T=5% R=0.96.json
      inflating: json/cp-180-050-gn - Cambered plate C=18% T=5% R=0.78.json
      inflating: json/cr1-il - CURTISS CR-1 AIRFOIL.json
      inflating: json/dae11-il - DAE-11 AIRFOIL.json
      inflating: json/dae31-il - DAE-31 AIRFOIL.json
      inflating: json/davis-corrected-il - DAVIS BASIC B-24 WING AIRFOIL.json
      inflating: json/davissm-il - davissm.json
      inflating: json/daytonwrightt1-il - Dayton-Wright T-1.json
      inflating: json/defcnd1-il - DEFIANT CANARD BL20 AIRFOIL.json
      inflating: json/defcnd3-il - DEFIANT CANARD BL145 AIRFOIL.json
      inflating: json/df102-il - DF102.json
      inflating: json/dga1138-il - D.G.A. 1138.json
      inflating: json/dh4009sm-il - dh4009sm.json
      inflating: json/dormoy-il - Dormoy.json
      inflating: json/dsma523a-il - DSMA-523A AIRFOIL.json
      inflating: json/du06-w-200-dt - DU 06-W-200  VAWT airfoil.json
      inflating: json/du8608418-il - DU86-084_18 8.44%.json
      inflating: json/e1098-il - EPPLER 1098 AIRFOIL.json
      inflating: json/e1210-il - EPPLER 1210 AIRFOIL.json
      inflating: json/e1212-il - EPPLER E1212 AIRFOIL.json
      inflating: json/e1213-il - EPPLER 1213 AIRFOIL.json
      inflating: json/e1230-il - EPPLER 1230 AIRFOIL.json
      inflating: json/e168-il - E168  (12.45%).json
      inflating: json/e171-il - (Dicke 12.28%).json
      inflating: json/e176-il - E176  (8.83%).json
      inflating: json/e180-il - E180  (8.59%).json
      inflating: json/e184-il - E184  (8.33%).json
      inflating: json/e193-il - E193  (10.22%).json
      inflating: json/e197-il - E197  (13.49%).json
      inflating: json/e203-il - E203  (13.64%).json
      inflating: json/e207-il - E207  (12.04%).json
      inflating: json/e210-il - E210  (13.64%).json
      inflating: json/e212-il - E212  (10.55%).json
      inflating: json/e216-il - E216  (10.4%).json
      inflating: json/e221-il - E221  (9.39%).json
      inflating: json/e224-il - E224  (10.17%).json
      inflating: json/e228-il - E10(08%).json
      inflating: json/e231-il - E231.json
      inflating: json/e297-il - EPPLER 297 AIRFOIL.json
      inflating: json/e326-il - EPPLER 326 AIRFOIL.json
      inflating: json/e328-il - EPPLER 328 AIRFOIL.json
      inflating: json/e330-il - EPPLER 330 AIRFOIL.json
      inflating: json/e332-il - EPPLER 332 AIRFOIL.json
      inflating: json/e334-il - EPPLER 334 AIRFOIL.json
      inflating: json/e336-il - EPPLER 336 AIRFOIL.json
      inflating: json/e338-il - EPPLER 338 AIRFOIL.json
      inflating: json/e340-il - EPPLER 340 AIRFOIL.json
      inflating: json/e342-il - EPPLER 342 AIRFOIL.json
      inflating: json/e344-il - EPPLER 344 AIRFOIL.json
      inflating: json/e361-il - EPPLER 361 AIRFOIL.json
      inflating: json/e376-il - EPPLER 376 AIRFOIL.json
      inflating: json/e377m-il - EPPLER 377 (MODIFIED) AIRFOIL.json
      inflating: json/e379-il - EPPLER 379 AIRFOIL.json
      inflating: json/e387-il - E387.json
      inflating: json/e393-il - EPPLER 393 AIRFOIL.json
      inflating: json/e396-il - EPPLER 396 AIRFOIL.json
      inflating: json/e398-il - EPPLER 398 AIRFOIL.json
      inflating: json/e403-il - EPPLER 403 AIRFOIL.json
      inflating: json/e417-il - EPPLER 417 AIRFOIL.json
      inflating: json/e421-il - EPPLER 421 AIRFOIL.json
      inflating: json/e423-il - E423.json
      inflating: json/e428-il - EPPLER 428 AIRFOIL.json
      inflating: json/e432-il - EPPLER 432 AIRFOIL.json
      inflating: json/e434-il - EPPLER 434 AIRFOIL.json
      inflating: json/e471-il - E471  (6.25%).json
      inflating: json/e473-il - EPPLER 473 AIRFOIL.json
      inflating: json/e475-il - E475  (15.01%).json
      inflating: json/e485-il - EPPLER 485 AIRFOIL.json
      inflating: json/e502-il - EPPLER 502 AIRFOIL.json
      inflating: json/e521-il - EPPLER 521 AIRFOIL.json
      inflating: json/e541-il - EPPLER 541 AIRFOIL.json
      inflating: json/e543-il - EPPLER 543 AIRFOIL.json
      inflating: json/e545-il - EPPLER 545 AIRFOIL.json
      inflating: json/e547-il - EPPLER 547 AIRFOIL.json
      inflating: json/e549-il - EPPLER 549 AIRFOIL.json
      inflating: json/e551-il - EPPLER 551 AIRFOIL.json
      inflating: json/e553-il - EPPLER 553 AIRFOIL.json
      inflating: json/e555-il - EPPLER 555 AIRFOIL.json
      inflating: json/e557-il - EPPLER 557 AIRFOIL.json
      inflating: json/e559-il - EPPLER 559 AIRFOIL.json
      inflating: json/e561-il - EPPLER 561 AIRFOIL.json
      inflating: json/e582-il - EPPLER 582 AIRFOIL.json
      inflating: json/e584-il - EPPLER 584 AIRFOIL.json
      inflating: json/e587-il - EPPLER 587 AIRFOIL.json
      inflating: json/e58-il - EPPLER 58 AIRFOIL.json
      inflating: json/e591-il - E591.json
      inflating: json/e598-il - EPPLER 598 AIRFOIL.json
      inflating: json/e604-il - EPPLER 604 AIRFOIL.json
      inflating: json/e62-il - E62  (5.62%).json
      inflating: json/e636-il - EPPLER 636 AIRFOIL.json
      inflating: json/e638-il - EPPLER 638 AIRFOIL.json
      inflating: json/e63-il - E63  (4.25%).json
      inflating: json/e64-il - E64  (8.45%).json
      inflating: json/e654-il - EPPLER 654 AIRFOIL.json
      inflating: json/e656-il - EPPLER 656 AIRFOIL.json
      inflating: json/e664-il - EPPLER 664 AIRFOIL.json
      inflating: json/e66-il - EPPLER 66 AIRFOIL.json
      inflating: json/e67-il - EPPLER 67 AIRFOIL.json
      inflating: json/e68-il - EPPLER 68 AIRFOIL.json
      inflating: json/e694-il - EPPLER 694 AIRFOIL.json
      inflating: json/e715-il - EPPLER 715 AIRFOIL.json
      inflating: json/e793-il - EPPLER 793 AIRFOIL.json
      inflating: json/e818-il - EPPLER 818 HYDROFOIL AIRFOIL.json
      inflating: json/e837-il - EPPLER E837 HYDROFOIL AIRFOIL.json
      inflating: json/e850-il - EPPLER E850 AIRFOIL.json
      inflating: json/e852-il - EPPLER E852 AIRFOIL.json
      inflating: json/e854-il - EPPLER E854 AIRFOIL.json
      inflating: json/e856-il - EPPLER 856 AIRFOIL.json
      inflating: json/e858-il - EPPLER 858 AIRFOIL.json
      inflating: json/e863-il - EPPLER 863 STRUT AIRFOIL.json
      inflating: json/e874-il - EPPLER 874 HYDROFOIL AIRFOIL.json
      inflating: json/e908-il - EPPLER 908 AIRFOIL.json
      inflating: json/ea61012-il - EPPLER EA 6(-1)-012 AIRFOIL.json
      inflating: json/ebambino7-il - E. Bambino.json
      inflating: json/eh0009-il - EH 0.0_9.0.json
      inflating: json/eh1090-il - EH 1.0_9.0.json
      inflating: json/eh2010-il - EH 2.0_10.json
      inflating: json/eh2070-il - EH 2.0_7.0.json
      inflating: json/eh3012-il - EH 3.0_12.json
      inflating: json/eiffel371-il - Eiffel 371 (Monge).json
      inflating: json/eiffel428-il - Eiffel 428 (Bleriot).json
      inflating: json/esa40-il - ESA40.json
      inflating: json/falcon-il - Falcon.json
      inflating: json/fg1-il - Fage & Collins 1.json
      inflating: json/fg3-il - Fage & Collins 3.json
      inflating: json/fx049915-il - WORTMANN FX 049-915 AIRFOIL.json
      inflating: json/fx05191-il - WORTMANN FX 05-191 AIRFOIL.json
      inflating: json/fx05h126-il - WORTMANN FX 05-H-126 AIRFOIL.json
      inflating: json/fx08s176-il - WORTMANN FX 08-S-176 AIRFOIL.json
      inflating: json/fx3-il - WORTMANN FX 3 AIRFOIL.json
      inflating: json/fx60100-il - FX 60-100 AIRFOIL.json
      inflating: json/fx60100sm-il - FX60-100 10.0% smoothed.json
      inflating: json/fx601261-il - WORTMANN FX 60-126_1 AIRFOIL.json
      inflating: json/fx60160-il - FX 60-160 AIRFOIL.json
      inflating: json/fx61140-il - FX 61-140 AIRFOIL.json
      inflating: json/fx61163-il - FX 61-163 AIRFOIL.json
      inflating: json/fx61184-il - FX 61-184 AIRFOIL.json
      inflating: json/fx62k153-il - FX 62-K-153_20 AIRFOIL.json
      inflating: json/fx63110-il - FX 63-110 AIRFOIL.json
      inflating: json/fx63137-il - WORTMANN FX 63-137 AIRFOIL.json
      inflating: json/fx63143-il - FX 63-143 AIRFOIL.json
      inflating: json/fx63147-il - FX 63-147 AIRFOIL.json
      inflating: json/fx6617a2-il - FX 66-17AII-182 AIRFOIL.json
      inflating: json/fx66182-il - FX 66-182 AIRFOIL.json
      inflating: json/fx66a175-il - WORTMANN FX 66-17A-175 AIRFOIL.json
      inflating: json/fx66h80-il - FX 66-H-80.json
      inflating: json/fx66s171-il - FX 66-S-171 AIRFOIL.json
      inflating: json/fx67k150-il - FX 67-K-150_17 AIRFOIL.json
      inflating: json/fx68h120-il - FX 68-H-120.json
      inflating: json/fx69h083-il - BELL_WORTMANN FX 69-H-083 AIRFOIL.json
      inflating: json/fx69pr281-il - FX 69-PR-281.json
      inflating: json/fx71120-il - WORTMANN FX 71-120 AIRFOIL.json
      inflating: json/fx711525-il - FX 71-L-150_25 AIRFOIL.json
      inflating: json/fx71l150-il - FX 71-L-150_30 AIRFOIL.json
      inflating: json/fx72150b-il - WORTMANN FX 72-MS-150B AIRFOIL.json
      inflating: json/fx73170-il - WORTMANN FX 73-170.json
      inflating: json/fx73cl1152-il - FX 73-CL1-152.json
      inflating: json/fx73cl3152-il - FX 73-CL3-152.json
      inflating: json/fx74080-il - WORTMANN FX 74-080.json
      inflating: json/fx74130wp2-il - 74-130 WP2.json
      inflating: json/fx74cl5140-il - FX74_CL5_140.json
      inflating: json/fx74modsm-il - FX 74-Cl5-140 MOD  (smoothed).json
      inflating: json/fx75193-il - WORTMANN FX 75-193.json
      inflating: json/fx76100-il - WORTMANN FX 76-100.json
      inflating: json/fx76mp120-il - FX 76-MP-120.json
      inflating: json/fx76mp160-il - FX 76-MP-160.json
      inflating: json/fx77w121-il - FX 77-W-121.json
      inflating: json/fx77w258-il - WORTMANN FX 77-W-258 AIRFOIL.json
      inflating: json/fx77w270s-il - FX 77-W-270S.json
      inflating: json/fx78k140-il - FX 78-K-140_20.json
      inflating: json/fx78k150-il - FX 78-K-150_20.json
      inflating: json/fx78pk188-il - FX 78-PK-188_20.json
      inflating: json/fx79l100-il - FX 79-L-100.json
      inflating: json/fx79w151a-il - FX 79-W-151 A.json
      inflating: json/fx79w660a-il - FX 79-W-660A.json
      inflating: json/fx83w108-il - FX 83-W-108.json
      inflating: json/fx83w227-il - FX 83-W-227.json
      inflating: json/fx84w127-il - FX 84-W-127.json
      inflating: json/fx84w150-il - FX 84-W-150.json
      inflating: json/fx84w218-il - FX 84-W-218.json
      inflating: json/fxlv152-il - WORTMANN FX L V-152 AIRFOIL.json
      inflating: json/fxs02196-il - FX S 02-196 AIRFOIL.json
      inflating: json/fxs21158-il - FX S 02_1-158 AIRFOIL.json
      inflating: json/geminism-il - GEMINI (smoothed).json
      inflating: json/giiib-il - GIII BL45 AIRFOIL.json
      inflating: json/giiid-il - GIII BL86 AIRFOIL (modified line 31).json
      inflating: json/giiif-il - GIII BL145 AIRFOIL.json
      inflating: json/giiih-il - GIII BL207 AIRFOIL.json
      inflating: json/giiij-il - GIII BL332 AIRFOIL.json
      inflating: json/giiil-il - GIII BL387 AIRFOIL.json
      inflating: json/giiin-il - GIII BL450 AIRFOIL.json
      inflating: json/glennmartin3-il - Glenn Martin 3.json
      inflating: json/gm15sm-il - GM15 (smoothed).json
      inflating: json/goe06k-il - GOE 6K AIRFOIL.json
      inflating: json/goe08k-il - GOE 8K AIRFOIL.json
      inflating: json/goe100-il - GOE 100 (SOPWITH) AIRFOIL.json
      inflating: json/goe10k-il - GOE 10K AIRFOIL.json
      inflating: json/goe114-il - GOE 114 (MVA MK.1) AIRFOIL.json
      inflating: json/goe116-il - GOE 116 (MVA MK.3) AIRFOIL.json
      inflating: json/goe118-il - GOE 118 (MVA MK.7) AIRFOIL.json
      inflating: json/goe121-il - GOE 121 (MVA H.1) AIRFOIL.json
      inflating: json/goe123-il - GOE 123 AIRFOIL.json
      inflating: json/goe12k-il - GOE 12K AIRFOIL.json
      inflating: json/goe134-il - GOE 134 (MVA H.12) AIRFOIL.json
      inflating: json/goe13k-il - GOE 13K AIRFOIL.json
      inflating: json/goe140-il - GOE 140 (MVA H.17) AIRFOIL.json
      inflating: json/goe143-il - GOE 143 (MVA H.20) AIRFOIL.json
      inflating: json/goe147-il - GOE 147 (MVA H.6) AIRFOIL.json
      inflating: json/goe15-il - GOE 15 AIRFOIL.json
      inflating: json/goe15k-il - GOE 15K AIRFOIL.json
      inflating: json/goe165-il - GOE 165 (MVA MK.11) AIRFOIL.json
      inflating: json/goe16k-il - GOE 16K AIRFOIL.json
      inflating: json/goe174-il - GOE 174 (ALBATROS 5020) AIRFOIL.json
      inflating: json/goe177-il - GOE 177 AIRFOIL.json
      inflating: json/goe180-il - GOE 180 (MVA H.26) AIRFOIL.json
      inflating: json/goe184-il - GOE 184 (MVA H.29) AIRFOIL.json
      inflating: json/goe188-il - GOE 188 (SCHTTE-LANZ 3U10) AIRFOIL.json
      inflating: json/goe195-il - GOE 195 AIRFOIL.json
      inflating: json/goe199-il - GOE 199 (L.F.G. 5406) AIRFOIL.json
      inflating: json/goe210-il - GOE 210 (DAIMLER) AIRFOIL.json
      inflating: json/goe222-il - GOE 222 (MVA H.33) AIRFOIL.json
      inflating: json/goe225-il - GOE 225 (MVA H.35) AIRFOIL.json
      inflating: json/goe227-il - GOE 227 (MVA H.37) AIRFOIL.json
      inflating: json/goe229-il - GOE 229 (MVA H.39) AIRFOIL.json
      inflating: json/goe234-il - GOE 234 (MVA CA5) AIRFOIL.json
      inflating: json/goe238-il - GOE 238 (HANSA-BRANDENBURG) AIRFOIL.json
      inflating: json/goe240-il - GOE 240 (KOLLER) AIRFOIL.json
      inflating: json/goe242-il - GOE 242 (MVA PR.2) AIRFOIL.json
      inflating: json/goe244-il - GOE 244 (MVA PR.4) AIRFOIL.json
      inflating: json/goe256-il - GOE 256 (JUNKERS E) AIRFOIL.json
      inflating: json/goe264-il - GOE 264 AIRFOIL.json
      inflating: json/goe269-il - GOE 269 AIRFOIL.json
      inflating: json/goe275-il - GOE 275 (DAIMLER VI) AIRFOIL.json
      inflating: json/goe277-il - GOE 277 (DAIMLER VIII) AIRFOIL.json
      inflating: json/goe279-il - GOE 279 (DAIMLER X) AIRFOIL.json
      inflating: json/goe281-il - GOE 281 (DAIMLER XII) AIRFOIL.json
      inflating: json/goe284-il - GOE 284 AIRFOIL.json
      inflating: json/goe286-il - GOE 286 AIRFOIL.json
      inflating: json/goe288-il - GOE 288 AIRFOIL.json
      inflating: json/goe290-il - GOE 290 (MVA 290) AIRFOIL.json
      inflating: json/goe29b-il - GOE 29B AIRFOIL.json
      inflating: json/goe301-il - GOE 301 (FRIEDRICHSHAFEN G 13) AIRFOIL.json
      inflating: json/goe304-il - GOE 304 (FRIEDRICHSHAFEN G02) AIRFOIL.json
      inflating: json/goe309-il - GOE 309 (MVA H.41) AIRFOIL.json
      inflating: json/goe311-il - GOE 311 (MVA H.43) AIRFOIL.json
      inflating: json/goe315-il - GOE 315 (HANSA-BRANDENBURG III.5) AIRFOIL.json
      inflating: json/goe318-il - GOE 318 (HANSA-BRANDENBURG VI.5) AIRFOIL.json
      inflating: json/goe320-il - GOE 320 (HANSA-BRANDENBURG II.1) AIRFOIL.json
      inflating: json/goe322-il - GOE 322 (HANSA-BRANDENBURG IV.1) AIRFOIL.json
      inflating: json/goe324-il - GOE 324 (HANSA-BRANDENBURG) AIRFOIL.json
      inflating: json/goe326-il - GOE 326 (PFALZ 55) AIRFOIL.json
      inflating: json/goe329-il - GOE 329 (PFALZ 58) AIRFOIL.json
      inflating: json/goe331-il - GOE 331 (PFALZ 60) AIRFOIL.json
      inflating: json/goe335-il - GOE 335 (D.F.W.) AIRFOIL.json
      inflating: json/goe342-il - GOE 342 AIRFOIL.json
      inflating: json/goe346-il - GOE 346 (FRIEDRICHSHAFEN-STAAKEN) AIRFOIL.json
      inflating: json/goe359-il - GOE 359 AIRFOIL.json
      inflating: json/goe361-il - GOE 361 AIRFOIL.json
      inflating: json/goe363-il - GOE 363 AIRFOIL.json
      inflating: json/goe365-il - GOE 365 AIRFOIL.json
      inflating: json/goe367-il - GOE 367 AIRFOIL.json
      inflating: json/goe369-il - GOE 369 AIRFOIL.json
      inflating: json/goe371-il - GOE 371 AIRFOIL.json
      inflating: json/goe373-il - GOE 373 AIRFOIL.json
      inflating: json/goe375-il - GOE 375 AIRFOIL.json
      inflating: json/goe377-il - GOE 377 AIRFOIL.json
      inflating: json/goe380-il - GOE 380 AIRFOIL.json
      inflating: json/goe382-il - GOE 382 AIRFOIL.json
      inflating: json/goe384-il - GOE 384 AIRFOIL.json
      inflating: json/goe386-il - GOE 386 AIRFOIL.json
      inflating: json/goe388-il - GOE 388 AIRFOIL.json
      inflating: json/goe390-il - GOE 390 AIRFOIL.json
      inflating: json/goe392-il - GOE 392 AIRFOIL.json
      inflating: json/goe394-il - GOE 394 AIRFOIL.json
      inflating: json/goe396-il - GOE 396 AIRFOIL.json
      inflating: json/goe398-il - GOE 398 AIRFOIL.json
      inflating: json/goe400-il - GOE 400 AIRFOIL.json
      inflating: json/goe402-il - GOE 402 AIRFOIL.json
      inflating: json/goe404-il - GOE 404 AIRFOIL.json
      inflating: json/goe406-il - GOE 406 AIRFOIL.json
      inflating: json/goe408-il - GOE 408 AIRFOIL.json
      inflating: json/goe410-il - GOE 410 AIRFOIL.json
      inflating: json/goe412-il - GOE 412 AIRFOIL.json
      inflating: json/goe414-il - GOE 414 AIRFOIL.json
      inflating: json/goe416a-il - GOE 416A AIRFOIL.json
      inflating: json/goe417a-il - GOE 417A (GEW. PLATTE) AIRFOIL.json
      inflating: json/goe419-il - GOE 419 AIRFOIL.json
      inflating: json/goe421-il - GOE 421 AIRFOIL.json
      inflating: json/goe423-il - GOE 423 AIRFOIL.json
      inflating: json/goe425-il - GOE 425 AIRFOIL.json
      inflating: json/goe427-il - GOE 427 AIRFOIL.json
      inflating: json/goe429-il - GOE 429 AIRFOIL.json
      inflating: json/goe431-il - GOE 431 AIRFOIL.json
      inflating: json/goe433-il - GOE 433 AIRFOIL.json
      inflating: json/goe435-il - GOE 435 AIRFOIL.json
      inflating: json/goe437-il - GOE 437 AIRFOIL.json
      inflating: json/goe439-il - GOE 439 AIRFOIL.json
      inflating: json/goe441-il - GOE 441 AIRFOIL.json
      inflating: json/goe443-il - GOE 443 AIRFOIL.json
      inflating: json/goe445-il - GOE 445 AIRFOIL.json
      inflating: json/goe447-il - GOE 447 AIRFOIL.json
      inflating: json/goe449-il - GOE 449 AIRFOIL.json
      inflating: json/goe451-il - GOE 451 AIRFOIL (modified line 6).json
      inflating: json/goe457-il - GOE 457 AIRFOIL.json
      inflating: json/goe459-il - GOE 459 AIRFOIL.json
      inflating: json/goe462-il - GOE 462 AIRFOIL.json
      inflating: json/goe474-il - GOE 474 AIRFOIL.json
      inflating: json/goe477-il - GOE 477 AIRFOIL.json
      inflating: json/goe479-il - GOE 479 AIRFOIL.json
      inflating: json/goe481-il - GOE 481 AIRFOIL.json
      inflating: json/goe482-il - GOE 482 AIRFOIL.json
      inflating: json/goe484-il - GOE 484 AIRFOIL.json
      inflating: json/goe490-il - GOE 490 AIRFOIL.json
      inflating: json/goe492-il - GOE 492 AIRFOIL.json
      inflating: json/goe494-il - GOE 494 AIRFOIL.json
      inflating: json/goe496-il - GOE 496 AIRFOIL.json
      inflating: json/goe498-il - GOE 498 AIRFOIL.json
      inflating: json/goe500-il - GOE 500 AIRFOIL.json
      inflating: json/goe502-il - GOE 502 AIRFOIL.json
      inflating: json/goe504-il - GOE 504 AIRFOIL.json
      inflating: json/goe506-il - GOE 506 AIRFOIL.json
      inflating: json/goe508-il - GOE 508 AIRFOIL.json
      inflating: json/goe510-il - GOE 510 AIRFOIL.json
      inflating: json/goe512-il - GOE 512 AIRFOIL.json
      inflating: json/goe514-il - GOE 514 AIRFOIL.json
      inflating: json/goe517-il - GOE 517 AIRFOIL.json
      inflating: json/goe522-il - GOE 522 AIRFOIL.json
      inflating: json/goe525-il - GOE 525 AIRFOIL.json
      inflating: json/goe527-il - GOE 527 AIRFOIL.json
      inflating: json/goe529-il - GOE 529 AIRFOIL.json
      inflating: json/goe531-il - GOE 531 AIRFOIL.json
      inflating: json/goe533-il - GOE 533 AIRFOIL.json
      inflating: json/goe535-il - GOE 535 AIRFOIL.json
      inflating: json/goe546-il - GOE 546 AIRFOIL.json
      inflating: json/goe548-il - GOE 548 AIRFOIL.json
      inflating: json/goe553-il - GOE 553 AIRFOIL.json
      inflating: json/goe55-il - GOE 55 AIRFOIL.json
      inflating: json/goe561-il - GOE 561 AIRFOIL.json
      inflating: json/goe563-il - GOE 563 AIRFOIL.json
      inflating: json/goe565-il - GOE 565 AIRFOIL.json
      inflating: json/goe567-il - GOE 567 AIRFOIL.json
      inflating: json/goe570-il - GOE 570 AIRFOIL.json
      inflating: json/goe572-il - GOE 572 AIRFOIL.json
      inflating: json/goe574-il - GOE 574 AIRFOIL.json
      inflating: json/goe584-il - GOE 584 AIRFOIL.json
      inflating: json/goe587-il - GOE 587 AIRFOIL.json
      inflating: json/goe591-il - GOE 591 AIRFOIL.json
      inflating: json/goe593-il - GOE 593 AIRFOIL.json
      inflating: json/goe596-il - GOE 596 AIRFOIL.json
      inflating: json/goe599-il - GOE 599 AIRFOIL.json
      inflating: json/goe601-il - GOE 601 AIRFOIL.json
      inflating: json/goe602m-il - GOE 602 MOD. AIRFOIL.json
      inflating: json/goe610b-il - GOE 610 B AIRFOIL.json
      inflating: json/goe611-il - GOE 611 AIRFOIL.json
      inflating: json/goe613-il - GOE 613 AIRFOIL.json
      inflating: json/goe615-il - GOE 615 AIRFOIL.json
      inflating: json/goe619-il - GOE 619 AIRFOIL.json
      inflating: json/goe621-il - GOE 621 AIRFOIL.json
      inflating: json/goe623-il - GOE 623 AIRFOIL.json
      inflating: json/goe625-il - GOE 625 AIRFOIL.json
      inflating: json/goe627-il - GOE 627 AIRFOIL.json
      inflating: json/goe629-il - GOE 629 AIRFOIL.json
      inflating: json/goe630-il - GOE 630 AIRFOIL.json
      inflating: json/goe633-il - GOE 633 AIRFOIL.json
      inflating: json/goe646-il - GOE 646 AIRFOIL.json
      inflating: json/goe648-il - GOE 648 AIRFOIL.json
      inflating: json/goe652-il - GOE 652 AIRFOIL.json
      inflating: json/goe655-il - GOE 655 AIRFOIL.json
      inflating: json/goe673-il - GOE 673 AIRFOIL.json
      inflating: json/goe676-il - GOE 676 (= M 12) AIRFOIL.json
      inflating: json/goe679-il - GOE 679 AIRFOIL.json
      inflating: json/goe682-il - GOE 682 AIRFOIL.json
      inflating: json/goe685-il - GOE 685 AIRFOIL.json
      inflating: json/goe693-il - GOE 693 AIRFOIL.json
      inflating: json/goe702-il - GOE 702 AIRFOIL.json
      inflating: json/goe704-il - GOE 704 AIRFOIL.json
      inflating: json/goe723-il - GOE 723 AIRFOIL.json
      inflating: json/goe738-il - GOE 738 AIRFOIL.json
      inflating: json/goe744-il - GOE 744 AIRFOIL.json
      inflating: json/goe758-il - GOE 758 AIRFOIL.json
      inflating: json/goe766-il - GOE 766 AIRFOIL.json
      inflating: json/goe769-il - GOE 769 AIRFOIL.json
      inflating: json/goe775-il - GOE 775 AIRFOIL.json
      inflating: json/goe777-il - GOE 777 AIRFOIL.json
      inflating: json/goe795sm-il - GOE 795 smoothed.json
      inflating: json/goe797-il - GOE 797 AIRFOIL.json
      inflating: json/goe79-il - GOE 79 (PFALZ 11) AIRFOIL.json
      inflating: json/goe801-il - GOE 801 (MVA 301) AIRFOIL.json
      inflating: json/goe802a-il - GOE 802 A AIRFOIL.json
      inflating: json/goe803h-il - GOE 803 (HACKLINGER) AIRFOIL.json
      inflating: json/goe81-il - GOE 81 AIRFOIL.json
      inflating: json/griffith30symsuction-il - Griffith 30% Suction Airfoil.json
      inflating: json/gu255118-il - UNIVERSITY OF GLASGOW GU25-5(11)8 AIRFOIL.json
      inflating: json/hh02-il - HUGHES HELICOPTERS HH-02 AIRFOIL.json
      inflating: json/hobiesm-il - HOBIESMO1.DAT.json
      inflating: json/hor07-il - ONERA HOR07 AIRFOIL.json
      inflating: json/hor20-il - ONERA HOR20 AIRFOIL.json
      inflating: json/hq07-il - HQ 0_7 AIRFOIL.json
      inflating: json/hq1010-il - HQ 1.0_10 AIRFOIL.json
      inflating: json/hq108-il - HQ 1.0_8 AIRFOIL.json
      inflating: json/hq1510-il - HQ 1.5_10 AIRFOIL.json
      inflating: json/hq1512-il - HQ 1.5_12 AIRFOIL.json
      inflating: json/hq1585-il - HQ 1.5_8.5 AIRFOIL.json
      inflating: json/hq159b-il - HQ 1.5_9 B AIRFOIL.json
      inflating: json/hq2010-il - HQ 2.0_10 AIRFOIL.json
      inflating: json/hq208-il - HQ 2.0_8 AIRFOIL.json
      inflating: json/hq2090sm-il - HQ-2.0_9  9.0%   smoothed.json
      inflating: json/hq2510-il - HQ 2.5_10 AIRFOIL.json
      inflating: json/hq2512-il - HQ 2.5_12 AIRFOIL.json
      inflating: json/hq259b-il - HQ 2.5_9 B AIRFOIL.json
      inflating: json/hq259-il - HQ 2.5_9 AIRFOIL.json
      inflating: json/hq3010-il - HQ 3.0_10 AIRFOIL.json
      inflating: json/hq3012-il - HQ 3.0_12 AIRFOIL.json
      inflating: json/hq3014-il - HQ 3.0_14 AIRFOIL.json
      inflating: json/hq308-il - HQ 3.0_8 AIRFOIL.json
      inflating: json/hq3510-il - HQ 3.5_10 AIRFOIL.json
      inflating: json/hq3513-il - HQ 3.5_13 AIRFOIL.json
      inflating: json/hq3518-il - HQ 3.5_18 AIRFOIL.json
      inflating: json/hq359-il - HQ 3.5_9 AIRFOIL.json
      inflating: json/hs1430-il - HAM-STD HS1-430 AIRFOIL.json
      inflating: json/hs1620-il - HAM-STD HS1-620 AIRFOIL.json
      inflating: json/hs1712-il - HAM-STD HS1-712 AIRFOIL.json
      inflating: json/ht05-il - HT05.json
      inflating: json/ht12-il - HT12.json
      inflating: json/ht23-il - HT23.json
      inflating: json/isa571-il - I.S.A. 571.json
      inflating: json/isa961-il - I.S.A. 961.json
      inflating: json/j5012-il - J5012   12%.json
      inflating: json/joukowsk0015-jf - Joukovsky f=0% t=15%.json
      inflating: json/joukowsk0021-jf - Joukovsky f=0% t=21%.json
      inflating: json/joukowsk-il - 12% JOUKOWSKI AIRFOIL.json
      inflating: json/k1-il - NYU_GRUMMAN K-1 AIRFOIL.json
      inflating: json/k3311sm-il - K3311 (smoothed).json
      inflating: json/k3-il - GRUMMAN K-3 AIRFOIL.json
      inflating: json/kc135b-il - KC-135 BL124.32 AIRFOIL.json
      inflating: json/kc135d-il - KC-135 BL351.6 AIRFOIL.json
      inflating: json/kenmar-il - KENNEDY AND MARSDEN AIRFOIL.json
      inflating: json/l1003-il - LIEBECK L1003 AIRFOIL.json
      inflating: json/l188tip-il - LOCKHEED L-188 TIP AIRFOIL.json
      inflating: json/la203a-il - DOUGLAS LA203A AIRFOIL.json
      inflating: json/la5055-il - LIEBECK LA5055 AIRFOIL.json
      inflating: json/lg10sc-il - LOCKHEED-GEORGIA SUPERCRITICAL AIRFOIL.json
      inflating: json/lrn1007-il - lrn1007.json
      inflating: json/ls013-il - NASA_LANGLEY LS(1)-0013 AIRFOIL.json
      inflating: json/ls413mod-il - NASA_LANGLEY LS(1)-0413MOD AIRFOIL.json
      inflating: json/ls417mod-il - NASA_LANGLEY LS(1)-0417MOD AIRFOIL.json
      inflating: json/ls421mod-il - NASA_LANGLEY LS(1)-0421MOD AIRFOIL.json
      inflating: json/lwk80080-il - LWK 80-080.json
      inflating: json/lwk80120k25-il - LWK 80-120_K25.json
      inflating: json/m11-il - NACA M11 AIRFOIL.json
      inflating: json/m13-il - NACA M13 AIRFOIL.json
      inflating: json/m15-il - NACA M15 AIRFOIL.json
      inflating: json/m17-il - NACA M17 AIRFOIL.json
      inflating: json/m19-il - NACA M19 AIRFOIL.json
      inflating: json/m1-il - NACA-M1 AIRFOIL.json
      inflating: json/m20-il - NACA M20 AIRFOIL.json
      inflating: json/m22-il - NACA M22 AIRFOIL.json
      inflating: json/m24-il - NACA M24 AIRFOIL.json
      inflating: json/m26-il - NACA M26 AIRFOIL.json
      inflating: json/m3-il - NACA M3 AIRFOIL.json
      inflating: json/m5-il - NACA M5 AIRFOIL.json
      inflating: json/m665-il - M6 (65%).json
      inflating: json/m7-il - NACA M7 AIRFOIL.json
      inflating: json/m9-il - NACA M9 AIRFOIL.json
      inflating: json/ma409sm-il - MA409 (smoothed).json
      inflating: json/marske1-il - MARSKE XM-1D AIRFOIL (F14-3.0).json
      inflating: json/marske3-il - MARSKE PIONEER IID ROOT AIRFOIL (NACA 431012A_24112 HYBRID).json
      inflating: json/marske5-il - MARSKE MONARCH AIRFOIL (NACA 43012A).json
      inflating: json/mb253515sm-il - MB253515 15.0% smoothed.json
      inflating: json/mh104-il - MH 104  15.28%.json
      inflating: json/mh108-il - MH 108  11.98%.json
      inflating: json/mh112-il - MH 112  Airfoil.json
      inflating: json/mh114-il - MH 114  13.02%.json
      inflating: json/mh116-il - MH 116  9.84%.json
      inflating: json/mh120-il - MH 120  11.57%.json
      inflating: json/mh122-il - MH 122  9.32%.json
      inflating: json/mh18-il - MH 18  11.16%.json
      inflating: json/mh200-il - MH 200  12.97%.json
      inflating: json/mh22-il - MH 22  7.2%.json
      inflating: json/mh24-il - MH 24  9.01%.json
      inflating: json/mh26-il - MH 26  10.99%.json
      inflating: json/mh30-il - MH 30  7.84%.json
      inflating: json/mh33-il - MH33.json
      inflating: json/mh42-il - MH 42  8.94%.json
      inflating: json/mh44-il - MH 44  9.66%.json
      inflating: json/mh46-il - MH 46  9.1%.json
      inflating: json/mh61-il - MH 61  10.26%.json
      inflating: json/mh64-il - MH 64  8.59%.json
      inflating: json/mh78-il - MH 78  14.47%.json
      inflating: json/mh81-il - MH 81  13%.json
      inflating: json/mh83-il - MH 83  13.29%.json
      inflating: json/mh91-il - MH 91  14.98%.json
      inflating: json/mh93-il - MH 93  15.98%.json
      inflating: json/mh95-il - MH 95  15.86%.json
      inflating: json/mrc-16-il - MRC-16.json
      inflating: json/ms313-il - NASA_LANGLEY MS(1)-0313 AIRFOIL.json
      inflating: json/mue139-il - MUE 139.json
      inflating: json/n0009sm-il - NACA-0009 9.0% smoothed.json
      inflating: json/n0012-il - NACA 0012 AIRFOILS.json
      inflating: json/n11-il - N-11.json
      inflating: json/n12-il - N-12.json
      inflating: json/n14-il - N-14.json
      inflating: json/n22-il - N-22.json
      inflating: json/n2414-il - NACA 2414.json
      inflating: json/n2h15-il - NACA 2-H-15 AIRFOIL.json
      inflating: json/n5h15-il - NACA 5-H-15 AIRFOIL.json
      inflating: json/n63010a-il - NACA 63A010 AIRFOIL.json
      inflating: json/n63015a-il - NACA 63-015A AIRFOIL.json
      inflating: json/n63212-il - NACA 63-212 AIRFOIL.json
      inflating: json/n63215b-il - NACA 63(2)-215 MOD B.json
      inflating: json/n63415-il - NACA 63-415 AIRFOIL.json
      inflating: json/n64012-il - NASA_LANGLEY 64-012 AIRFOIL.json
      inflating: json/n64015-il - NACA 642-015 AIRFOIL.json
      inflating: json/n6409-il - NACA6409 9%.json
      inflating: json/n64110-il - NACA 64-110 AIRFOIL.json
      inflating: json/n64212ma-il - NACA 64(1)-212 MOD A.json
      inflating: json/n64215-il - NACA 64-215 AIRFOIL.json
      inflating: json/n6h10-il - NACA 6-H-10 AIRFOIL.json
      inflating: json/n6h20-il - NACA 6-H-20 AIRFOIL.json
      inflating: json/n9-il - N-9.json
      inflating: json/naca0008-il - NACA 0008.json
      inflating: json/naca001034a08cli02-il - NACA 0010-34 a=0.8 c(li)=0.2.json
      inflating: json/naca001064-il - NACA 0010-64.json
      inflating: json/naca001066-il - NACA 0010-66.json
      inflating: json/naca0010-il - NACA 0010.json
      inflating: json/naca001264-il - NACA 0012-64.json
      inflating: json/naca0012h-sa - NACA0012H for VAWT from Sandia report SAND80-2114.json
      inflating: json/naca0018-il - NACA 0018.json
      inflating: json/naca0024-il - NACA 0024.json
      inflating: json/naca1410-il - NACA 1410.json
      inflating: json/naca16006-il - NACA 16-006.json
      inflating: json/naca16012-il - NACA 16-012.json
      inflating: json/naca16018-il - NACA 16-018.json
      inflating: json/naca22112-jf - NACA 22112.json
      inflating: json/naca23015-il - NACA 23015.json
      inflating: json/naca23021-il - NACA 23021.json
      inflating: json/naca23112-jf - NACA 23112.json
      inflating: json/naca2410-il - NACA 2410.json
      inflating: json/naca24112-jf - NACA 24112.json
      inflating: json/naca2415-il - NACA 2415.json
      inflating: json/naca2421-il - NACA 2421.json
      inflating: json/naca25112-jf - NACA 25112.json
      inflating: json/naca4415-il - NACA 4415.json
      inflating: json/naca4421-il - NACA 4421.json
      inflating: json/naca63206-il - NACA 63-206.json
      inflating: json/naca632615-il - NACA 63(2)-615.json
      inflating: json/naca633018-il - NACA 63(3)-018.json
      inflating: json/naca633418-il - NACA 63.json
      inflating: json/naca634221-il - NACA 63(4)-221.json
      inflating: json/naca63a210-il - NACA 63A210.json
      inflating: json/naca6412-il - NACA 6412.json
      inflating: json/naca64208-il - NACA 64-208.json
      inflating: json/naca64210-il - NACA 64-210.json
      inflating: json/naca642415-il - NACA 64(2)-415.json
      inflating: json/naca643418-il - NACA 64(3)-418.json
      inflating: json/naca644221-il - NACA 64(4)-221.json
      inflating: json/naca64a010-il - NACA 64A-010 10.0%.json
      inflating: json/naca64a410-il - NACA 64A410.json
      inflating: json/naca651212a06-il - NACA 65(1)-212 a=0.6.json
      inflating: json/naca65206-il - NACA 65-206.json
      inflating: json/naca65210-il - NACA 65-210.json
      inflating: json/naca652415-il - NACA 65(2)-415.json
      inflating: json/naca653218-il - NACA 65(3)-218.json
      inflating: json/naca65410-il - NACA 65-410.json
      inflating: json/naca654421-il - NACA 65(4)-421.json
      inflating: json/naca66-018-il - NACA 66-018.json
      inflating: json/naca66206-il - NACA 66-206.json
      inflating: json/naca66210-il - NACA 66-210.json
      inflating: json/naca662415-il - NACA 66(2)-415.json
      inflating: json/naca663418-il - NACA 66(3)-418.json
      inflating: json/naca671215-il - NACA 67.json
      inflating: json/naca747a415-il - NACA 747A415.json
      inflating: json/nacam12-il - NACA M12.json
      inflating: json/nacam2-il - NACA M2.json
      inflating: json/nacam6-il - NACA M6.json
      inflating: json/ncambre-il - ONERA NACA CAMBRE AIRFOIL.json
      inflating: json/nl722362-il - NLR-7223-62 AIRFOIL.json
      inflating: json/nlf0215f-il - NASA_LANGLEY NLF(1)-0215F AIRFOIL.json
      inflating: json/nlf414f-il - NASA_LANGLEY NLF 0414F AIRFOIL.json
      inflating: json/nlf416-il - NASA_LANGLEY NLF(1)-0416 AIRFOIL.json
      inflating: json/nlr7301-il - NLR-7301 AIRFOIL.json
      inflating: json/npl9510-il - NPL 9510 AIRFOIL.json
      inflating: json/npl9626-il - NPL 9626 AIRFOIL.json
      inflating: json/npl9660-il - NPL 9660 AIRFOIL.json
      inflating: json/oa206-il - ONERA OA206 AIRFOIL.json
      inflating: json/oa212-il - ONERA OA212 AIRFOIL.json
      inflating: json/oaf095-il - OAF095 AIRFOIL.json
      inflating: json/oaf117-il - OAF117 AIRFOIL.json
      inflating: json/oaf139-il - OAF139 AIRFOIL.json
      inflating: json/p51droot-il - P-51D ROOT (BL17.5) AIRFOIL.json
      inflating: json/p51hroot-il - NACA 66.json
      inflating: json/pfcm-il - PROPFAN CRUISE MISSILE WING AIRFOIL.json
      inflating: json/prandtl-d-root-ns - Prandtl-D root - NASA Preliminary Research Aerodynamic Design To Lower Drag.json
      inflating: json/psu-90-125wl-il - PSU-90-125WL.json
      inflating: json/pt40-il - PT40.json
      inflating: json/pw1211-pw - PW1211.json
      inflating: json/pw75-pw - PW75.json
      inflating: json/r1046-il - RONCZ 1046 VOYAGER CANARD AIRFOIL.json
      inflating: json/r1082-il - RONCZ 1082 VOYAGER ROOT OUTER AFT WING AIRFOIL.json
      inflating: json/r140-il - R140 (original).json
      inflating: json/rae100-il - RAE 100 AIRFOIL.json
      inflating: json/rae102-il - RAE 102 AIRFOIL.json
      inflating: json/rae104-il - RAE 104 AIRFOIL.json
      inflating: json/rae5212-il - RAE(NPL) 5212 AIRFOIL.json
      inflating: json/rae5214-il - RAE 5214 AIRFOIL.json
      inflating: json/rae69ck-il - RAE6-9CK AIRFOIL.json
      inflating: json/raf19-il - RAF 19 AIRFOIL.json
      inflating: json/raf26-il - RAF 26 AIRFOIL.json
      inflating: json/raf28-il - RAF 28 AIRFOIL.json
      inflating: json/raf30md-il - RAF 30 MOD AIRFOIL.json
      inflating: json/raf32-il - RAF 32 AIRFOIL.json
      inflating: json/raf33-il - RAF 33 AIRFOIL.json
      inflating: json/raf38-il - RAF 38 AIRFOIL.json
      inflating: json/raf6-il - RAF 6 AIRFOIL.json
      inflating: json/raf89-il - RAF 89 AIRFOIL.json
      inflating: json/rc08b3-il - NASA_LANGLEY RC-08(B)3 AIRFOIL.json
      inflating: json/rc1064c-il - NASA_LANGLEY RC10-64C AIRFOIL.json
      inflating: json/rc10n1-il - NASA_LANGLEY RC-10(N)1 AIRFOIL.json
      inflating: json/rc12b3-il - NASA_LANGLEY RC-12(B)3 AIRFOIL.json
      inflating: json/rc410-il - NASA RC(4)-10 AIRFOIL.json
      inflating: json/rcsc2-il - NASA_LANGLEY RC-SC2 AIRFOIL.json
      inflating: json/rg12a-il - AIRFOIL PROFILE12A 9.00%.json
      inflating: json/rg149-il - RG 14 9% AIRFOIL.json
      inflating: json/rg14a147-il - RG 14A-1.4_7.0 AIRFOIL.json
      inflating: json/rg14-il - RG 14 AIRFOIL.json
      inflating: json/rg15a111-il - RG 15A-1.8_11.0 AIRFOIL.json
      inflating: json/rg8-il - RG 8 AIRFOIL.json
      inflating: json/rhodesg32-il - Rhode St. Genese 32.json
      inflating: json/rhodesg36-il - Rhode St. Genese 36.json
      inflating: json/s1010-il - S1010 HPV airfoil.json
      inflating: json/s1014-il - S1014.json
      inflating: json/s1020-il - Ornithopter airfoil..json
      inflating: json/s102s-il - SOMERS S102 AIRFOIL (SHARP).json
      inflating: json/s1048-il - S1048 14% (Danny Howell).json
      inflating: json/s1210-il - S1210 12%.json
      inflating: json/s1221-il - S1221  w_o flap.json
      inflating: json/s1223rtl-il - S1223 RTL.json
      inflating: json/s2046-il - S2046.json
      inflating: json/s2050-il - S2050 8.93%.json
      inflating: json/s2060-il - S2060 8%.json
      inflating: json/s2091-il - S2091-101-83.json
      inflating: json/s3002-il - SELIG 3002-099-83.json
      inflating: json/s3014-il - S3014-095-85.json
      inflating: json/s3021-il - S3021-095-84.json
      inflating: json/s3025-il - S3025 9.38%.json
      inflating: json/s4053-il - S4053.json
      inflating: json/s4062-il - S4062-095-87.json
      inflating: json/s4094-il - S4094 (root airfoil designed for and used on the E-flite UMX ASK-21 scale RC sailplane).json
      inflating: json/s4096-il - S4096 (designed for the E-flite UMX ASK-21 scale RC sailplane).json
      inflating: json/s4158-il - S4158.json
      inflating: json/s4233-il - S4233-136-84.json
      inflating: json/s4320-il - S4320.json
      inflating: json/s5020-il - S5020.json
      inflating: json/s6062-il - S6062 8%.json
      inflating: json/s7012-il - S7012 8.75%.json
      inflating: json/s7075-il - S7075 (9%).json
      inflating: json/s802-nr - NREL's S802 Airfoil.json
      inflating: json/s8036-il - S8036 (16%).json
      inflating: json/s8038-il - S8038 (13%).json
      inflating: json/s803-nr - NREL's S803 Airfoil.json
      inflating: json/s8052-il - S8052 (11.88%).json
      inflating: json/s805a-nr - NREL's S805A Airfoil.json
      inflating: json/s8065-il - S8065 (11% version of S8064).json
      inflating: json/s806a-nr - NREL's S806A Airfoil (modified line 35).json
      inflating: json/s808-nr - NREL's S808 Airfoil.json
      inflating: json/s810-nr - NREL's S810 Airfoil.json
      inflating: json/s812-nr - NREL's S812 Airfoil.json
      inflating: json/s814-nr - NREL's S814 Airfoil.json
      inflating: json/s816-nr - NREL's S816 Airfoil.json
      inflating: json/s818-nr - NREL's S818 Airfoil.json
      inflating: json/s820-nr - NREL's S820 Airfoil.json
      inflating: json/s822-nr - NREL's S822 Airfoil.json
      inflating: json/s825-nr - NREL's S825 Airfoil.json
      inflating: json/s827-nr - NREL's S827 Airfoil.json
      inflating: json/s829-nr - NREL's S829 Airfoil.json
      inflating: json/s831-nr - NREL's S831 Airfoil.json
      inflating: json/s833-nr - NREL's S833 Airfoil.json
      inflating: json/s835-nr - NREL's S835 Airfoil.json
      inflating: json/s9026-il - S9026 (9.5%).json
      inflating: json/s9032-il - S9032 (9%).json
      inflating: json/s9037-il - S9037 (9%).json
      inflating: json/sa7025-il - SA7025.json
      inflating: json/sa7035-il - SA7035.json
      inflating: json/sa7038-il - SA7038.json
      inflating: json/sc1012r8-il - SIKORSKY SC1012R8 AIRFOIL.json
      inflating: json/sc1095-il - SIKORSKY SC1095 AIRFOIL.json
      inflating: json/sc20010-il - NASA SC(2)-0010 AIRFOIL.json
      inflating: json/sc20402-il - NASA SC(2)-0402 AIRFOIL.json
      inflating: json/sc20404-il - NASA SC(2)-0404 AIRFOIL.json
      inflating: json/sc20410-il - NASA SC(2)-0410 AIRFOIL.json
      inflating: json/sc20414-il - NASA SC(2)-0414 AIRFOIL.json
      inflating: json/sc20518-il - NASA SC(2)-0518 AIRFOIL.json
      inflating: json/sc20610-il - NASA SC(2)-0610 AIRFOIL.json
      inflating: json/sc20614-il - NASA SC(2)-0614 AIRFOIL.json
      inflating: json/sc20710-il - NASA SC(2)-0710 AIRFOIL.json
      inflating: json/sc20714-il - NASA SC(2)-0714 AIRFOIL.json
      inflating: json/sc21010-il - NASA SC(2)-1010 AIRFOIL.json
      inflating: json/sd2030-il - SD2030-086-88.json
      inflating: json/sd5060-il - SD5060 (9.5%).json
      inflating: json/sd6080-il - SD6080 (9.2%).json
      inflating: json/sd7032-il - SD7032-099-88.json
      inflating: json/sd7037-il - SD7037-092-88.json
      inflating: json/sd7062-il - SD7062 (14%).json
      inflating: json/sd7084-il - SD7084 (9.6%).json
      inflating: json/sd8000-il - SD8000-089-88.json
      inflating: json/sd8040-il - SD8040 (10%).json
      inflating: json/sg6041-il - SG6041.json
      inflating: json/sg6043-il - SG6043.json
      inflating: json/sg6051-il - SG6051.json
      inflating: json/sokolov-il - SOKOLOV AIRFOIL.json
      inflating: json/sp4721la-po - SP4721LA.json
      inflating: json/ssca07-il - SIKORSKY SSC-A07 AIRFOIL.json
      inflating: json/stcyr171-il - St. CYR 171 (Royer).json
      inflating: json/stcyr234-il - St. CYR 234 (Bartel 17-IC).json
      inflating: json/ste87151-il - EPPLER STE 871-514 AIRFOIL.json
      inflating: json/stf86361-il - EPPLER STF 863-615 AIRFOIL.json
      inflating: json/supermarine371i-il - Supermarine 371-I (root).json
      inflating: json/tempest1-il - HAWKER TEMPEST 37.5% SEMISPAN AIRFOIL.json
      inflating: json/tempest3-il - HAWKER TEMPEST 96.77% SEMISPAN AIRFOIL.json
      inflating: json/trainer60-il - TRAINER60.json
      inflating: json/tsagi12-il - TSAGI 12% AIRFOIL.json
      inflating: json/ua2-180-il - UA(2)-180 (University of Alberta_Marsden).json
      inflating: json/ua79sf18-il - UNIVERSITY OF ALBERTA UA 79-SF-187 AIRFOIL.json
      inflating: json/ua79sfm-il - UNIVERSITY OF ALBERTA UA 79-SF-187 AIRFOIL MAIN ELEMENT.json
      inflating: json/ui1720-il - UNIVERSITY OF ILLINOIS UI-1720 AIRFOIL.json
      inflating: json/us1000root-il - US1000ROOT.json
      inflating: json/usa25-il - USA 25 AIRFOIL.json
      inflating: json/usa27-il - USA 27 AIRFOIL.json
      inflating: json/usa28-il - USA 28 AIRFOIL.json
      inflating: json/usa31-il - USA 31 AIRFOIL.json
      inflating: json/usa33-il - USA 33 AIRFOIL.json
      inflating: json/usa35b-il - USA-35B AIRFOIL.json
      inflating: json/usa35-il - USA 35 AIRFOIL.json
      inflating: json/usa40b-il - USA 40 B AIRFOIL.json
      inflating: json/usa45-il - USA 45 AIRFOIL.json
      inflating: json/usa46-il - USA 46 AIRFOIL.json
      inflating: json/usa49-il - USA 49 AIRFOIL.json
      inflating: json/usa50-il - USA 50 AIRFOIL.json
      inflating: json/usa98-il - USA 98 AIRFOIL.json
      inflating: json/v13006-il - BOEING VERTOL V13006-.7 AIRFOIL.json
      inflating: json/v23010-il - BOEING-VERTOL V23010-1.58 AIRFOIL.json
      inflating: json/v43015-il - BOEING VERTOL V43015-2.48 AIRFOIL.json
      inflating: json/vr11x-il - BOEING-VERTOL VR-11X AIRFOIL.json
      inflating: json/vr13-il - BOEING-VERTOL VR-13 AIRFOIL.json
      inflating: json/vr15-il - BOEING-VERTOL VR-15 AIRFOIL.json
      inflating: json/vr7-il - BOEING-VERTOL VR-7 AIRFOIL.json
      inflating: json/vr8-il - BOEING-VERTOL VR-8 AIRFOIL.json
      inflating: json/vr9-il - BOEING-VERTOL VR-9 AIRFOIL.json
      inflating: json/waspsm-il - WASP (smoothed).json
      inflating: json/wb140-il - WB-140_35_FB 14%.json
      inflating: json/ys900-il - YS-900.json
      inflating: json/ys930-il - YS-930.json

### Install pytorch geometric

```python
!pip install torch-scatter torch-sparse torch-cluster torch-spline-conv torch-geometric -f https://data.pyg.org/whl/torch-1.11.0+cu115.html
!pip3 install torch==1.11.0+cu113 torchvision==0.12.0+cu113 torchaudio==0.11.0+cu113 -f https://download.pytorch.org/whl/cu113/torch_stable.html

```

    Looking in links: https://data.pyg.org/whl/torch-1.11.0+cu115.html
    Requirement already satisfied: torch-scatter in /usr/local/lib/python3.7/dist-packages (2.0.9)
    Requirement already satisfied: torch-sparse in /usr/local/lib/python3.7/dist-packages (0.6.13)
    Requirement already satisfied: torch-cluster in /usr/local/lib/python3.7/dist-packages (1.6.0)
    Requirement already satisfied: torch-spline-conv in /usr/local/lib/python3.7/dist-packages (1.2.1)
    Requirement already satisfied: torch-geometric in /usr/local/lib/python3.7/dist-packages (2.0.4)
    Requirement already satisfied: scipy in /usr/local/lib/python3.7/dist-packages (from torch-sparse) (1.4.1)
    Requirement already satisfied: pandas in /usr/local/lib/python3.7/dist-packages (from torch-geometric) (1.3.5)
    Requirement already satisfied: tqdm in /usr/local/lib/python3.7/dist-packages (from torch-geometric) (4.63.0)
    Requirement already satisfied: requests in /usr/local/lib/python3.7/dist-packages (from torch-geometric) (2.23.0)
    Requirement already satisfied: pyparsing in /usr/local/lib/python3.7/dist-packages (from torch-geometric) (3.0.7)
    Requirement already satisfied: scikit-learn in /usr/local/lib/python3.7/dist-packages (from torch-geometric) (1.0.2)
    Requirement already satisfied: numpy in /usr/local/lib/python3.7/dist-packages (from torch-geometric) (1.21.5)
    Requirement already satisfied: jinja2 in /usr/local/lib/python3.7/dist-packages (from torch-geometric) (2.11.3)
    Requirement already satisfied: MarkupSafe>=0.23 in /usr/local/lib/python3.7/dist-packages (from jinja2->torch-geometric) (2.0.1)
    Requirement already satisfied: pytz>=2017.3 in /usr/local/lib/python3.7/dist-packages (from pandas->torch-geometric) (2018.9)
    Requirement already satisfied: python-dateutil>=2.7.3 in /usr/local/lib/python3.7/dist-packages (from pandas->torch-geometric) (2.8.2)
    Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.7/dist-packages (from python-dateutil>=2.7.3->pandas->torch-geometric) (1.15.0)
    Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests->torch-geometric) (1.24.3)
    Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests->torch-geometric) (2021.10.8)
    Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests->torch-geometric) (3.0.4)
    Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests->torch-geometric) (2.10)
    Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from scikit-learn->torch-geometric) (3.1.0)
    Requirement already satisfied: joblib>=0.11 in /usr/local/lib/python3.7/dist-packages (from scikit-learn->torch-geometric) (1.1.0)
    Looking in links: https://download.pytorch.org/whl/cu113/torch_stable.html
    Requirement already satisfied: torch==1.11.0+cu113 in /usr/local/lib/python3.7/dist-packages (1.11.0+cu113)
    Requirement already satisfied: torchvision==0.12.0+cu113 in /usr/local/lib/python3.7/dist-packages (0.12.0+cu113)
    Requirement already satisfied: torchaudio==0.11.0+cu113 in /usr/local/lib/python3.7/dist-packages (0.11.0+cu113)
    Requirement already satisfied: typing-extensions in /usr/local/lib/python3.7/dist-packages (from torch==1.11.0+cu113) (3.10.0.2)
    Requirement already satisfied: pillow!=8.3.*,>=5.3.0 in /usr/local/lib/python3.7/dist-packages (from torchvision==0.12.0+cu113) (7.1.2)
    Requirement already satisfied: requests in /usr/local/lib/python3.7/dist-packages (from torchvision==0.12.0+cu113) (2.23.0)
    Requirement already satisfied: numpy in /usr/local/lib/python3.7/dist-packages (from torchvision==0.12.0+cu113) (1.21.5)
    Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests->torchvision==0.12.0+cu113) (3.0.4)
    Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests->torchvision==0.12.0+cu113) (2021.10.8)
    Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests->torchvision==0.12.0+cu113) (1.24.3)
    Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests->torchvision==0.12.0+cu113) (2.10)

## Normalization

Normalization brings all the data to the same scale. Without this, the weight matrix may be illconditioned and you'll have extremely high gradients.

ResizeCp.py - this file takes all the json data and resizes the Cp to 50 points on pressure side and 50 points on suction side - the JSON contains about 100 points on both sides describing Cp.

Step3_NormalizeData.py takes into account the entire dataset and normalizes each of the fields. So if airfoil has 50 points in the x and y direction to define the pressure side. Point 1 y-value for all airfoils taken as a vector and normalized between 0 and 1 or mean and standard deviation same with point 2 all the way to the last point. This is an example of local normalization. You can select to normalize by the locally or by the global value. Results can vary and consistency is important when comparing graph and multilayer perception/deep neural networks.

The output for all this is a file called `scalers.pickle`

```python
!python ResizeCp.py
!python Step3_NormalizeData.py
```

    Processing: 100% 825/825 [13:50<00:00,  1.01s/it]
    reading json data: 100% 825/825 [00:09<00:00, 85.45it/s]

## Creating the Processed Dataset for Graph and Multilayer Perception Networks
Next step is to iterate through the JSON files, normalize, and create pytorch geometric dataset for the training step.

Option 1: Run the code below to generate test and train dataset. **This may take a while ...**

```python
!python Step4_CreateDataset.py
```

    Processing:  28% 234/825 [24:16<2:51:46, 17.44s/it]^C

Option 2: Download the processed dataset. This extracts to a `datasets` folder. There's the `datasets/minmax` this is the data scaled using minmax scaler. `datasets/standard` is the data scaled using standard scaler.

> Note: This may not work for newer versions of pytorch or pytorch geometric .

```python
!wget https://nasa-public-data.s3.amazonaws.com/plot3d_utilities/dataset-processed.zip
!unzip dataset-processed.zip

```

    --2022-03-23 15:15:44--  https://nasa-public-data.s3.amazonaws.com/plot3d_utilities/dataset-processed.zip
    Resolving nasa-public-data.s3.amazonaws.com (nasa-public-data.s3.amazonaws.com)... 52.216.77.4
    Connecting to nasa-public-data.s3.amazonaws.com (nasa-public-data.s3.amazonaws.com)|52.216.77.4|:443... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 9188863364 (8.6G) [application/zip]
    Saving to: ‘dataset-processed.zip’

    dataset-processed.z 100%[===================>]   8.56G  55.4MB/s    in 2m 58s

    2022-03-23 15:18:42 (49.3 MB/s) - ‘dataset-processed.zip’ saved [9188863364/9188863364]

    Archive:  dataset-processed.zip
       creating: datasets/
       creating: datasets/minmax/
      inflating: datasets/minmax/dnn_scaled_data_cp_test.pt
      inflating: datasets/minmax/dnn_scaled_data_cp_train.pt
      inflating: datasets/minmax/dnn_scaled_data_test.pt
      inflating: datasets/minmax/dnn_scaled_data_train.pt
      inflating: datasets/minmax/graph_scaled_data_cp_test.pt
      inflating: datasets/minmax/graph_scaled_data_cp_train.pt
      inflating: datasets/minmax/graph_scaled_data_test.pt
      inflating: datasets/minmax/graph_scaled_data_train.pt
       creating: datasets/standard/
      inflating: datasets/standard/dnn_scaled_data_cp_test.pt
      inflating: datasets/standard/dnn_scaled_data_cp_train.pt
      inflating: datasets/standard/dnn_scaled_data_test.pt
      inflating: datasets/standard/dnn_scaled_data_train.pt
      inflating: datasets/standard/graph_scaled_data_cp_test.pt
      inflating: datasets/standard/graph_scaled_data_cp_train.pt
      inflating: datasets/standard/graph_scaled_data_test.pt
      inflating: datasets/standard/graph_scaled_data_train.pt

```python
# Reorganize
!mv datasets airfoil-learning/generate_xfoil/
!mv json* airfoil-learning/generate_xfoil/
!mv libs* airfoil-learning/generate_xfoil/
!mv old* airfoil-learning/generate_xfoil/
!mv xfoil* airfoil-learning/generate_xfoil/
!mv *.py airfoil-learning/generate_xfoil/
!mv *.pickle airfoil-learning/generate_xfoil/

!rm *.zip
!rm -r libs old sample_data xfoil
```

    mv: cannot stat 'datasets': No such file or directory
    mv: cannot stat 'json*': No such file or directory
    mv: cannot stat 'libs*': No such file or directory
    mv: cannot stat 'old*': No such file or directory
    mv: cannot stat 'xfoil*': No such file or directory
    mv: cannot stat '*.py': No such file or directory
    mv: cannot move 'scalers.pickle' to 'airfoil-learning/generate_xfoil/': Not a directory
    rm: cannot remove '*.zip': No such file or directory
    rm: cannot remove 'libs': No such file or directory
    rm: cannot remove 'old': No such file or directory
    rm: cannot remove 'sample_data': No such file or directory
    rm: cannot remove 'xfoil': No such file or directory

# Training

To begin training, the notebook structure needs to be reorganized. This is not needed when dealing with the actual code on your computer. Jupyter notebook does not allow you to change root directories so we copy everything to the root and process it then move it back.

To begin training, we need to setup or proportion the dataset. The full processed and normalized dataset is located in `../generate_xfoil`. For training we can either train on the entire thing or on a small fraction of the data.

```python
!mv airfoil-learning/generate_xfoil .
!mv airfoil-learning/pytorch .
!rm *.png
```

```python
# Changes the directory to pytorch and executes setup_dataset.py
# What you would do in vscode is open `pytorch` as your working directory
#    and then execute setup_dataset.py from there
!(cd pytorch && python setup_dataset.py > setup_dataset.out)

# Note: Depending on the speed and if you paid for colab pro, this command may die unexpectedly.
```

If the above block of code doesn't work then run the code below. This is a modified version of setup_dataset.py.

```python
from pathlib import Path
from typing import List
import torch
import json
from sklearn.model_selection import train_test_split
import json
import os.path as osp

def setup_dataset(train_filename:str,test_filename:str,percent_dataset:float=1,train_percentage:float=0.8,train_indices:List[int]=None, test_indices:List[int]=None,scaler_type:str="minmax"):
    """Setup the Train and Validation datasets

    Args:
        train_filename (str): [description]
        test_filename (str): [description]
        percent_dataset (float, optional): percentage of dataset to use 0 to 1. Defaults to 1.
        train_indices (List[int], optional): array indices to use for training. Defaults to None.
        test_indices (List[int], optional): array indices to use for test. Defaults to None.
        scaler_type (str, optional): string to describe the type of scaler to use. This determines where the dataset is saved. Defaults to "minmax".

    Returns:
        (tuple): tuple containing:

            - **train_dataset** (torch.utils.data.TensorDataset): pitch distribution
            - **val_dataset** (torch.utils.data.TensorDataset): pitch to chord distribution

    """

    train_dataset = torch.load(train_filename)
    test_dataset = torch.load(test_filename)

    # Combined train and test
    train_dataset.extend(test_dataset)

    if (not train_indices):
        all_data = range(len(train_dataset))
        # Shuffle the dataset and select a percent from it
        new_dataset,_ = train_test_split(all_data, test_size=1-percent_dataset, train_size=percent_dataset)
        train_indices, test_indices = train_test_split(new_dataset, test_size=1-train_percentage, train_size=train_percentage)

    test_dataset = [train_dataset[t] for t in test_indices]
    train_dataset = [train_dataset[t] for t in train_indices]

    Path(osp.join('local_dataset',scaler_type)).mkdir(parents=True, exist_ok=True)
    Path(osp.join('local_dataset',scaler_type)).mkdir(parents=True, exist_ok=True)
    if 'graph' in train_filename:
        data_params = {'input_size':train_dataset[0].x.shape[0],'output_size':len(train_dataset[0].y),'node_labels':train_dataset[0].node_labels.shape[0]}
        with open(osp.join('local_dataset',scaler_type,'gnn_dataset_properties.json'), 'w') as outfile:
            json.dump(data_params, outfile)
        torch.save(train_dataset,osp.join('local_dataset',scaler_type,'train_gnn.pt'))
        torch.save(test_dataset,osp.join('local_dataset',scaler_type,'test_gnn.pt'))
    else:
        features = train_dataset[0][0]
        labels = train_dataset[0][1]
        data_params = {'input_size':len(features),'output_size':len(labels)}
        with open(osp.join('local_dataset',scaler_type,'dnn_dataset_properties.json'), 'w') as outfile:
            json.dump(data_params, outfile)
        torch.save(train_dataset,osp.join('local_dataset',scaler_type,'train_dnn.pt'))
        torch.save(test_dataset,osp.join('local_dataset',scaler_type,'test_dnn.pt'))

    return train_indices, test_indices

if __name__ == '__main__':
    with open('settings.json', 'r') as infile:    # Loads the settings for all networks
        settings = json.load(infile)

    percent_train = -1
    for args in settings['data']:
        if percent_train == args["percent_train"]:
            train_indices, test_indices = setup_dataset(args['train_filename'].replace("../",""), args['test_filename'].replace("../",""), args['percent_dataset'], args["percent_train"],train_indices,test_indices,args['scaler_type'])
        else:
            train_indices, test_indices = setup_dataset(args['train_filename'].replace("../",""), args['test_filename'].replace("../",""), args['percent_dataset'], args["percent_train"],None,None,args['scaler_type'])
        percent_train = args["percent_train"]
    print('local_dataset created')
```

If the above 2 codes do not work and you notice session crashing because of not enough ram or disk then you need to pay for colab pro or build/find a better computer. I ran this on a machine with 64GB ram and had no issues.

## Multilayer Perception Networks

 A multilayer perception network is a network that is made up of fully connected linear layers (pytorch) or dense layers (tensorflow).

Here is an example of how to code up a multilayer linear network from the file `MultiLayerLinear.py`. The way to initialize is it:

```python
model = MultiLayerLinear(3,4,[16,16,16,256,560,5])
```
The array indicates the sizes of the hidden layers. 3 is the number of inputs and 4 is number of outputs.

```python
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.nn import Linear, Module, Dropout
from typing import List
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

class MultiLayerLinear(Module):
    """
    Model aims to predict both cp and y with spatial convolutions (MFConv).
    """
    # Multi-layer Perceptron
    # https://discuss.pytorch.org/t/how-to-create-mlp-model-with-arbitrary-number-of-hidden-layers/13124/2

    # https://github.com/FrancescoSaverioZuppichini/Pytorch-how-and-when-to-use-Module-Sequential-ModuleList-and-ModuleDict

    def __init__(self,in_channels:int,out_channels:int,h_sizes:List[int]=None):
        """This class joins a bunch of linear layers together to predict the output size

        Args:
            in_channels (int): number of inputs channels
            out_channels (int): number of output channels
            h_sizes (List[int], optional): Any additional internal linear layers. Defaults to None.
        """
        super(MultiLayerLinear, self).__init__()
        self.in_channels = in_channels
        self.out_channels = out_channels
        self.layers = nn.ModuleList()
        if (h_sizes!=None):
            self.layers.append(nn.Linear(in_channels,h_sizes[0],bias=True))
            self.layer_sizes = h_sizes
            for k in range(len(h_sizes)-1):
                self.layers.append(nn.Linear(h_sizes[k], h_sizes[k+1],bias=True))
            self.layers.append(nn.Linear(h_sizes[len(h_sizes)-1], out_channels,bias=True))
        else:
            self.layers.append(nn.Linear(in_channels,out_channels))
            self.layer_sizes = None

    def forward(self,x):
        out = x
        for i in range(len(self.layers)-1):
            out = F.relu6(self.layers[i](out))
        return self.layers[-1](out) # dont activate the last laye

    def __str__(self):
        n_layers = len(self.layers)
        if (self.layer_sizes):
            layer_sizes = '-'.join([str(x) for x in self.layer_sizes])
            return f"MLL_IN-{self.in_channels}_OUT-{self.out_channels}_{layer_sizes}"
        else:
            return f"MLL_IN-{self.in_channels}_OUT-{self.out_channels}"

    def __repr__(self):
        return self.__str__()

```

```python
!(cd pytorch && python train_dnn.py)
```

# Graph Neural Network
The graph network used was [spline convolution](https://pytorch-geometric.readthedocs.io/en/latest/_modules/torch_geometric/nn/conv/spline_conv.html). This type of graph convolution was used in an encoder-decoder style network to learn features.

In an encoder-decoder network each feature encoded is saved and passed directly into the decoder. Here's the example from `pytorch/gnn_model.py`

In the initialization `__init__`, I had to initialize the size of the decoder to take into account the size of the features coming out of the encoder as well as the features entering in the decoder from past decoders.

Example:
```python
  for n in range(len(neurons)-1,0,-1):
      out_channels = self.encoder[n_encoder-i].out_channels
      self.decoder.append(SplineConv(out_channels+neurons[n], neurons[n], dim=2,degree=2,kernel_size=3))
      self.decoder_bn.append(BatchNorm(neurons[n]))
      i+=1
```

```python
import torch
from typing import List
import torch.nn.functional as F
from torch.nn import Linear, Module, Dropout, ModuleList
from torch_geometric.data import Data
from torch_geometric.nn import BatchNorm
# from torch_geometric.nn import SplineConv
from SplineConv import SplineConv
from MultiLayerLinear import MultiLayerLinear

class GnnModel(Module):
    """Defines the graph neural network structure for prediction
        Example of encoder decoder with cnn and batchnorms https://medium.com/dataseries/convolutional-autoencoder-in-pytorch-on-mnist-dataset-d65145c132ac
    """
    def __init__(self,linear_input_size:int, neurons:List[int]=[16,32,64],linear_layers:MultiLayerLinear = None,batch_norm_encoder=False, batch_norm_decoder=False):
        """Constructor for GnnModel. User passes the number of neurons they would like the graph network to use. The graph network then constructs and encoder with those neurons and corresponding decoder.

        Args:
            linear_input_size (int):
            neurons (List[int], optional): Number of neurons to use for each graph neural network. Defaults to [16,32,64].
            use_batch_norm (bool, optional): Whether to use batch norm in between encoder networks. Defaults to False.
            dropout (float, optional): [description]. Defaults to 0.
            linear_layers (MultiLayerLinear, optional): [description]. Defaults to None.
        """
        super(GnnModel, self).__init__()
        self.linear_input_size = linear_input_size
        self.batch_norm_encoder = batch_norm_encoder
        self.batch_norm_decoder = batch_norm_decoder
        self.encoder = ModuleList()
        self.encoder_bn = ModuleList()
        self.neurons = neurons
        # Encoder
        for n in range(1,len(neurons)):
            self.encoder.append(SplineConv(neurons[n-1], neurons[n], dim=2,degree=2,kernel_size=3))
            self.encoder_bn.append(BatchNorm(neurons[n]))
        self.encoder.append(SplineConv(neurons[n], neurons[n], dim=2,degree=2,kernel_size=3))
        self.encoder_bn.append(BatchNorm(neurons[n]))

        # Decoder
        self.decoder = ModuleList()
        self.decoder_bn = ModuleList()
        i = 0
        n_encoder = len(self.encoder)-1
        for n in range(len(neurons)-1,0,-1):
            out_channels = self.encoder[n_encoder-i].out_channels
            self.decoder.append(SplineConv(out_channels+neurons[n], neurons[n], dim=2,degree=2,kernel_size=3))
            self.decoder_bn.append(BatchNorm(neurons[n]))
            i+=1
        self.linear_layers = linear_layers

    def forward(self,data:Data):
        """Sends torch geometric data through the neural network.

        Args:
            data (torch_geometric.data.Data): https://pytorch-geometric.readthedocs.io/en/latest/modules/data.html

        Returns:
            (torch.tensor): tensor describing the results of the network. This depends on what is predicted by MultiLayerLinear
        """
        x, edge_index, edge_attr, batch, pos = data.x,data.edge_index, data.edge_attr, data.batch, data.pos
        batch_size = max(batch)+1
        # Run through encoder and store results
        out = list()
        out.append(x)
        for encoder in self.encoder:
            out.append(F.relu6(encoder(out[-1],edge_index,edge_attr=pos)))
        # Run through decoder and apply results from encoder
        n = len(out)-3
        dout_out = torch.cat([out[-1], out[-2]],dim=1)
        for decoder in self.decoder:
            dout = F.relu6(decoder(dout_out, edge_index, edge_attr=pos))     # https://arxiv.org/pdf/1711.08920.pdf From SplineConv Paper G = (V, E, U) where U is the position and also edge attributes
            dout_out = torch.cat([dout, out[n]],dim=1)                            # data = spline_basis(edge_attr, self.kernel_size, self.is_open_spline, self.degree) Spline basis
            n -= 1

        # conditions = conditions.reshape((batch_size,3))
        out = dout.reshape((batch_size,self.linear_input_size*dout.shape[1]))
        # out8 = torch.cat((out7,conditions),dim=1)
        return self.linear_layers(out)

    def __str__(self):
        n_encoders = len(self.encoder)
        n_decoders = len(self.decoder)
        neurons = '-'.join([str(n) for n in self.neurons])
        linear = str(self.linear_layers)
        return f"GnnModel_{neurons}_{n_encoders}_{n_decoders}_{str(self.batch_norm_encoder)}_{str(self.batch_norm_decoder)}_MLinear_{linear}"
```

To train the network you can run the code below

> Note: Training will certainly not work on colab without lots of $$ thrown at google.

```python
!(cd pytorch && python train_gnn.py)     # Trains the network to predict only Cl,Cd,Cdp,Cm
!(cd pytorch && python train_gnn_cp.py)  # Trains the network to predict Cl,Cd,Cdp,Cm, and Cp all together
```

# Plotting and Visualizing the Results

Once training is complete, you'll have a bunch of model weights in the checkpoints folder. Keeping all this information is useful for going back and evaluating each model.

To plot a randomly selected design, simply run

```python
!(cd pytorch python plot_random_airfoil_results.py)
```

IF you want to visualize the training results. You can run

```python
!(cd pytorch python plot_train_history.py)
```

The training saves the loss for train and test inside of the checkpoints. It's important to keep everything including the model weights.

I was not able to run this in google colab. I reccomend running all the code locally or within some kind of super computer.