Spaces:
Sleeping
Sleeping
init
Browse files- .gitignore +53 -0
- README.md +97 -0
- app.py +218 -0
- examples/clarky.dat +36 -0
- examples/naca4412.dat +44 -0
- examples/rae2822.dat +48 -0
- requirements.txt +5 -0
- run.sh +33 -0
.gitignore
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Python
|
| 2 |
+
__pycache__/
|
| 3 |
+
*.py[cod]
|
| 4 |
+
*$py.class
|
| 5 |
+
*.so
|
| 6 |
+
.Python
|
| 7 |
+
build/
|
| 8 |
+
develop-eggs/
|
| 9 |
+
dist/
|
| 10 |
+
downloads/
|
| 11 |
+
eggs/
|
| 12 |
+
.eggs/
|
| 13 |
+
lib/
|
| 14 |
+
lib64/
|
| 15 |
+
parts/
|
| 16 |
+
sdist/
|
| 17 |
+
var/
|
| 18 |
+
wheels/
|
| 19 |
+
pip-wheel-metadata/
|
| 20 |
+
share/python-wheels/
|
| 21 |
+
*.egg-info/
|
| 22 |
+
.installed.cfg
|
| 23 |
+
*.egg
|
| 24 |
+
|
| 25 |
+
# Virtual Environment
|
| 26 |
+
venv/
|
| 27 |
+
.venv/
|
| 28 |
+
env/
|
| 29 |
+
ENV/
|
| 30 |
+
env.bak/
|
| 31 |
+
venv.bak/
|
| 32 |
+
|
| 33 |
+
# IDE
|
| 34 |
+
.vscode/
|
| 35 |
+
.idea/
|
| 36 |
+
*.swp
|
| 37 |
+
*.swo
|
| 38 |
+
*~
|
| 39 |
+
.DS_Store
|
| 40 |
+
|
| 41 |
+
# Logs
|
| 42 |
+
*.log
|
| 43 |
+
nohup.out
|
| 44 |
+
app.log
|
| 45 |
+
|
| 46 |
+
# Gradio
|
| 47 |
+
flagged/
|
| 48 |
+
gradio_cached_examples/
|
| 49 |
+
|
| 50 |
+
# Model cache
|
| 51 |
+
.cache/
|
| 52 |
+
*.pkl
|
| 53 |
+
*.pth
|
README.md
CHANGED
|
@@ -12,3 +12,100 @@ short_description: Web-app and APIs to get NeuralFoil predictions
|
|
| 12 |
---
|
| 13 |
|
| 14 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
---
|
| 13 |
|
| 14 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
| 15 |
+
|
| 16 |
+
# NeuralFoil Airfoil Predictor (Hugging Face Space)
|
| 17 |
+
|
| 18 |
+
This Space wraps [NeuralFoil](https://github.com/peterdsharpe/NeuralFoil) in a Gradio UI.
|
| 19 |
+
|
| 20 |
+
It runs a NeuralFoil surrogate model to estimate airfoil aerodynamics (CL, CD, CM, transition locations, and an analysis confidence metric) for a single operating point.
|
| 21 |
+
|
| 22 |
+
NeuralFoil is a neural-network-based surrogate for XFoil.
|
| 23 |
+
Given an airfoil and operating conditions, it predicts aerodynamic coefficients and related quantities much faster than traditional CFD or XFoil.
|
| 24 |
+
|
| 25 |
+
This Space only wraps that functionality and does **not** train any models itself.
|
| 26 |
+
|
| 27 |
+
## Features
|
| 28 |
+
|
| 29 |
+
- **Airfoil definition**
|
| 30 |
+
- By **name** via AeroSandbox (UIUC / NACA-style names, e.g. `naca4412`, `rae2822`, `clarky`)
|
| 31 |
+
- By **`.dat` file upload** (XFoil-style coordinate file)
|
| 32 |
+
- numpy coordinates
|
| 33 |
+
|
| 34 |
+
- **Operating point inputs**
|
| 35 |
+
- Angle of attack **Ξ± [deg]**
|
| 36 |
+
- Reynolds number **Re [-]**
|
| 37 |
+
- NeuralFoil **model size** (`xxsmall` β¦ `xxxlarge`)
|
| 38 |
+
|
| 39 |
+
- **Outputs**
|
| 40 |
+
- Lift coefficient **CL**
|
| 41 |
+
- Drag coefficient **CD**
|
| 42 |
+
- Moment coefficient **CM**
|
| 43 |
+
- Transition locations: **Top_Xtr**, **Bot_Xtr** (if available)
|
| 44 |
+
- **analysis_confidence** + a crude textual interpretation
|
| 45 |
+
- Full raw NeuralFoil output JSON (for power users / debugging)
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
## Running locally
|
| 49 |
+
|
| 50 |
+
### Quick Start (if already set up)
|
| 51 |
+
|
| 52 |
+
```bash
|
| 53 |
+
./run.sh
|
| 54 |
+
# or
|
| 55 |
+
source venv/bin/activate && python app.py
|
| 56 |
+
```
|
| 57 |
+
|
| 58 |
+
### First Time Setup
|
| 59 |
+
|
| 60 |
+
```bash
|
| 61 |
+
# 1. Create virtual environment
|
| 62 |
+
python3 -m venv venv
|
| 63 |
+
|
| 64 |
+
# 2. Activate virtual environment
|
| 65 |
+
source venv/bin/activate # macOS/Linux
|
| 66 |
+
# or
|
| 67 |
+
venv\Scripts\activate # Windows
|
| 68 |
+
|
| 69 |
+
# 3. Install dependencies
|
| 70 |
+
pip install --upgrade pip
|
| 71 |
+
pip install -r requirements.txt
|
| 72 |
+
|
| 73 |
+
# 4. Run the app
|
| 74 |
+
python app.py
|
| 75 |
+
```
|
| 76 |
+
|
| 77 |
+
The app will start on `http://127.0.0.1:7860` (or next available port).
|
| 78 |
+
|
| 79 |
+
See [SETUP.md](SETUP.md) for detailed setup instructions and troubleshooting.
|
| 80 |
+
|
| 81 |
+
## License
|
| 82 |
+
|
| 83 |
+
- NeuralFoil itself is MIT-licensed (see its own repository for details).
|
| 84 |
+
- This Space is just a thin wrapper around NeuralFoil and AeroSandbox.
|
| 85 |
+
|
| 86 |
+
## Citation
|
| 87 |
+
|
| 88 |
+
If you use NeuralFoil in your research, please cite:
|
| 89 |
+
Both the tool itself (this repository), which includes the pre-print publication:
|
| 90 |
+
|
| 91 |
+
```bibtex
|
| 92 |
+
@misc{neuralfoil,
|
| 93 |
+
author = {Peter Sharpe},
|
| 94 |
+
title = {{NeuralFoil}: An airfoil aerodynamics analysis tool using physics-informed machine learning},
|
| 95 |
+
year = {2023},
|
| 96 |
+
publisher = {GitHub},
|
| 97 |
+
journal = {GitHub repository},
|
| 98 |
+
howpublished = {\url{https://github.com/peterdsharpe/NeuralFoil}},
|
| 99 |
+
}
|
| 100 |
+
```
|
| 101 |
+
|
| 102 |
+
And the author's PhD thesis, which has an extended chapter that serves as the primary long-form documentation for the tool:
|
| 103 |
+
|
| 104 |
+
```bibtex
|
| 105 |
+
@phdthesis{aerosandbox_phd_thesis,
|
| 106 |
+
title = {Accelerating Practical Engineering Design Optimization with Computational Graph Transformations},
|
| 107 |
+
author = {Sharpe, Peter D.},
|
| 108 |
+
school = {Massachusetts Institute of Technology},
|
| 109 |
+
year = {2024},
|
| 110 |
+
}
|
| 111 |
+
```
|
app.py
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import neuralfoil as nf
|
| 3 |
+
import numpy as np
|
| 4 |
+
import json
|
| 5 |
+
from pathlib import Path
|
| 6 |
+
|
| 7 |
+
def load_airfoil_from_dat(filepath):
|
| 8 |
+
"""Load airfoil coordinates from a .dat file"""
|
| 9 |
+
with open(filepath, 'r') as f:
|
| 10 |
+
lines = f.readlines()
|
| 11 |
+
|
| 12 |
+
# Skip the first line (airfoil name)
|
| 13 |
+
coords = []
|
| 14 |
+
for line in lines[1:]:
|
| 15 |
+
line = line.strip()
|
| 16 |
+
if line:
|
| 17 |
+
parts = line.split()
|
| 18 |
+
if len(parts) >= 2:
|
| 19 |
+
try:
|
| 20 |
+
x, y = float(parts[0]), float(parts[1])
|
| 21 |
+
coords.append([x, y])
|
| 22 |
+
except ValueError:
|
| 23 |
+
continue
|
| 24 |
+
|
| 25 |
+
return np.array(coords)
|
| 26 |
+
|
| 27 |
+
def format_coordinates(coords_array):
|
| 28 |
+
"""Format coordinates array as a string for display"""
|
| 29 |
+
if coords_array is None or len(coords_array) == 0:
|
| 30 |
+
return ""
|
| 31 |
+
|
| 32 |
+
lines = []
|
| 33 |
+
for x, y in coords_array:
|
| 34 |
+
lines.append(f"{x:.6f} {y:.6f}")
|
| 35 |
+
return "\n".join(lines)
|
| 36 |
+
|
| 37 |
+
def parse_coordinates(coords_text):
|
| 38 |
+
"""Parse coordinates from text input"""
|
| 39 |
+
lines = coords_text.strip().split('\n')
|
| 40 |
+
coords = []
|
| 41 |
+
|
| 42 |
+
for line in lines:
|
| 43 |
+
line = line.strip()
|
| 44 |
+
if line:
|
| 45 |
+
parts = line.split()
|
| 46 |
+
if len(parts) >= 2:
|
| 47 |
+
try:
|
| 48 |
+
x, y = float(parts[0]), float(parts[1])
|
| 49 |
+
coords.append([x, y])
|
| 50 |
+
except ValueError:
|
| 51 |
+
continue
|
| 52 |
+
|
| 53 |
+
return np.array(coords)
|
| 54 |
+
|
| 55 |
+
def run_neuralfoil_prediction(coords_text, alpha, reynolds, model_size):
|
| 56 |
+
"""Run NeuralFoil prediction and return full JSON output"""
|
| 57 |
+
try:
|
| 58 |
+
# Parse coordinates
|
| 59 |
+
coords = parse_coordinates(coords_text)
|
| 60 |
+
|
| 61 |
+
if len(coords) < 3:
|
| 62 |
+
return json.dumps({"error": "Invalid coordinates. Please provide at least 3 coordinate pairs."}, indent=2)
|
| 63 |
+
|
| 64 |
+
# Run NeuralFoil analysis directly from coordinates
|
| 65 |
+
result = nf.get_aero_from_coordinates(
|
| 66 |
+
coordinates=coords,
|
| 67 |
+
alpha=alpha,
|
| 68 |
+
Re=reynolds,
|
| 69 |
+
model_size=model_size
|
| 70 |
+
)
|
| 71 |
+
print(result)
|
| 72 |
+
|
| 73 |
+
# Convert result to a serializable dictionary
|
| 74 |
+
output = {}
|
| 75 |
+
|
| 76 |
+
# Standard outputs
|
| 77 |
+
if hasattr(result, 'CL'):
|
| 78 |
+
output['CL'] = float(result.CL) if not np.isnan(result.CL) else None
|
| 79 |
+
if hasattr(result, 'CD'):
|
| 80 |
+
output['CD'] = float(result.CD) if not np.isnan(result.CD) else None
|
| 81 |
+
if hasattr(result, 'CM'):
|
| 82 |
+
output['CM'] = float(result.CM) if not np.isnan(result.CM) else None
|
| 83 |
+
|
| 84 |
+
# Transition locations (if available)
|
| 85 |
+
if hasattr(result, 'Top_Xtr'):
|
| 86 |
+
output['Top_Xtr'] = float(result.Top_Xtr) if not np.isnan(result.Top_Xtr) else None
|
| 87 |
+
if hasattr(result, 'Bot_Xtr'):
|
| 88 |
+
output['Bot_Xtr'] = float(result.Bot_Xtr) if not np.isnan(result.Bot_Xtr) else None
|
| 89 |
+
|
| 90 |
+
# Confidence metric
|
| 91 |
+
if hasattr(result, 'analysis_confidence'):
|
| 92 |
+
output['analysis_confidence'] = float(result.analysis_confidence) if not np.isnan(result.analysis_confidence) else None
|
| 93 |
+
|
| 94 |
+
# Include all other attributes
|
| 95 |
+
for attr in dir(result):
|
| 96 |
+
if not attr.startswith('_') and attr not in output:
|
| 97 |
+
val = getattr(result, attr)
|
| 98 |
+
if isinstance(val, (int, float, str, bool)):
|
| 99 |
+
output[attr] = val
|
| 100 |
+
elif isinstance(val, np.ndarray):
|
| 101 |
+
output[attr] = val.tolist()
|
| 102 |
+
|
| 103 |
+
# Add input parameters for reference
|
| 104 |
+
output['input_parameters'] = {
|
| 105 |
+
'alpha_deg': alpha,
|
| 106 |
+
'reynolds_number': reynolds,
|
| 107 |
+
'model_size': model_size,
|
| 108 |
+
'num_coordinates': len(coords)
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
return json.dumps(output, indent=2)
|
| 112 |
+
|
| 113 |
+
except Exception as e:
|
| 114 |
+
return json.dumps({"error": str(e)}, indent=2)
|
| 115 |
+
|
| 116 |
+
def load_example(example_name):
|
| 117 |
+
"""Load an example airfoil"""
|
| 118 |
+
example_files = {
|
| 119 |
+
"NACA 4412": "examples/naca4412.dat",
|
| 120 |
+
"Clark Y": "examples/clarky.dat",
|
| 121 |
+
"RAE 2822": "examples/rae2822.dat"
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
filepath = example_files.get(example_name)
|
| 125 |
+
if filepath and Path(filepath).exists():
|
| 126 |
+
coords = load_airfoil_from_dat(filepath)
|
| 127 |
+
return format_coordinates(coords)
|
| 128 |
+
return ""
|
| 129 |
+
|
| 130 |
+
# Load default airfoil (NACA 4412)
|
| 131 |
+
default_coords = format_coordinates(load_airfoil_from_dat("examples/naca4412.dat"))
|
| 132 |
+
|
| 133 |
+
# Create Gradio interface
|
| 134 |
+
with gr.Blocks(title="NeuralFoil Airfoil Predictor") as demo:
|
| 135 |
+
gr.Markdown("# NeuralFoil Airfoil Predictor")
|
| 136 |
+
gr.Markdown("""
|
| 137 |
+
This app uses [NeuralFoil](https://github.com/peterdsharpe/NeuralFoil) to predict airfoil aerodynamics.
|
| 138 |
+
|
| 139 |
+
Provide airfoil coordinates (x, y pairs, one per line) and operating conditions to get predictions for CL, CD, CM, and more.
|
| 140 |
+
""")
|
| 141 |
+
|
| 142 |
+
with gr.Row():
|
| 143 |
+
with gr.Column():
|
| 144 |
+
gr.Markdown("### Airfoil Coordinates")
|
| 145 |
+
gr.Markdown("Enter x,y coordinate pairs (one per line). Coordinates should trace the airfoil from trailing edge, over the top, to leading edge, then back along the bottom.")
|
| 146 |
+
|
| 147 |
+
coords_input = gr.Textbox(
|
| 148 |
+
label="Airfoil Coordinates",
|
| 149 |
+
value=default_coords,
|
| 150 |
+
lines=15,
|
| 151 |
+
max_lines=30,
|
| 152 |
+
placeholder="x y\n1.0 0.0\n0.95 0.01\n..."
|
| 153 |
+
)
|
| 154 |
+
|
| 155 |
+
gr.Markdown("### Load Example")
|
| 156 |
+
example_buttons = gr.Radio(
|
| 157 |
+
choices=["NACA 4412", "Clark Y", "RAE 2822"],
|
| 158 |
+
label="Example Airfoils",
|
| 159 |
+
value="NACA 4412"
|
| 160 |
+
)
|
| 161 |
+
|
| 162 |
+
load_btn = gr.Button("Load Example")
|
| 163 |
+
|
| 164 |
+
gr.Markdown("### Operating Conditions")
|
| 165 |
+
alpha_input = gr.Slider(
|
| 166 |
+
minimum=-10,
|
| 167 |
+
maximum=20,
|
| 168 |
+
value=5.0,
|
| 169 |
+
step=0.5,
|
| 170 |
+
label="Angle of Attack Ξ± [deg]"
|
| 171 |
+
)
|
| 172 |
+
|
| 173 |
+
reynolds_input = gr.Number(
|
| 174 |
+
value=1e6,
|
| 175 |
+
label="Reynolds Number Re [-]"
|
| 176 |
+
)
|
| 177 |
+
|
| 178 |
+
model_size_input = gr.Dropdown(
|
| 179 |
+
choices=["xxsmall", "xsmall", "small", "medium", "large", "xlarge", "xxlarge", "xxxlarge"],
|
| 180 |
+
value="large",
|
| 181 |
+
label="Model Size"
|
| 182 |
+
)
|
| 183 |
+
|
| 184 |
+
predict_btn = gr.Button("Run Prediction", variant="primary")
|
| 185 |
+
|
| 186 |
+
with gr.Column():
|
| 187 |
+
gr.Markdown("### Full NeuralFoil Output (JSON)")
|
| 188 |
+
output_json = gr.Textbox(
|
| 189 |
+
label="Prediction Results",
|
| 190 |
+
lines=25,
|
| 191 |
+
max_lines=40,
|
| 192 |
+
placeholder="Results will appear here..."
|
| 193 |
+
)
|
| 194 |
+
|
| 195 |
+
# Event handlers
|
| 196 |
+
load_btn.click(
|
| 197 |
+
fn=load_example,
|
| 198 |
+
inputs=[example_buttons],
|
| 199 |
+
outputs=[coords_input]
|
| 200 |
+
)
|
| 201 |
+
|
| 202 |
+
predict_btn.click(
|
| 203 |
+
fn=run_neuralfoil_prediction,
|
| 204 |
+
inputs=[coords_input, alpha_input, reynolds_input, model_size_input],
|
| 205 |
+
outputs=[output_json]
|
| 206 |
+
)
|
| 207 |
+
|
| 208 |
+
gr.Markdown("""
|
| 209 |
+
---
|
| 210 |
+
### About
|
| 211 |
+
|
| 212 |
+
**NeuralFoil** is a neural-network-based surrogate for XFoil that predicts airfoil aerodynamics much faster than traditional CFD.
|
| 213 |
+
|
| 214 |
+
**Citation**: If you use NeuralFoil, please cite the [GitHub repository](https://github.com/peterdsharpe/NeuralFoil) and Peter Sharpe's PhD thesis.
|
| 215 |
+
""")
|
| 216 |
+
|
| 217 |
+
if __name__ == "__main__":
|
| 218 |
+
demo.launch()
|
examples/clarky.dat
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
CLARK Y
|
| 2 |
+
1.000000 0.000000
|
| 3 |
+
0.950000 0.009300
|
| 4 |
+
0.900000 0.017800
|
| 5 |
+
0.800000 0.032500
|
| 6 |
+
0.700000 0.044500
|
| 7 |
+
0.600000 0.053500
|
| 8 |
+
0.500000 0.059500
|
| 9 |
+
0.400000 0.061500
|
| 10 |
+
0.300000 0.059000
|
| 11 |
+
0.250000 0.056000
|
| 12 |
+
0.200000 0.051500
|
| 13 |
+
0.150000 0.045500
|
| 14 |
+
0.100000 0.037000
|
| 15 |
+
0.075000 0.031000
|
| 16 |
+
0.050000 0.024000
|
| 17 |
+
0.025000 0.015500
|
| 18 |
+
0.012500 0.010500
|
| 19 |
+
0.000000 0.000000
|
| 20 |
+
0.012500 -0.010500
|
| 21 |
+
0.025000 -0.015000
|
| 22 |
+
0.050000 -0.020000
|
| 23 |
+
0.075000 -0.023000
|
| 24 |
+
0.100000 -0.025000
|
| 25 |
+
0.150000 -0.026000
|
| 26 |
+
0.200000 -0.025500
|
| 27 |
+
0.250000 -0.024000
|
| 28 |
+
0.300000 -0.022000
|
| 29 |
+
0.400000 -0.017500
|
| 30 |
+
0.500000 -0.012500
|
| 31 |
+
0.600000 -0.008000
|
| 32 |
+
0.700000 -0.004500
|
| 33 |
+
0.800000 -0.002000
|
| 34 |
+
0.900000 -0.000500
|
| 35 |
+
0.950000 -0.000250
|
| 36 |
+
1.000000 0.000000
|
examples/naca4412.dat
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
NACA 4412
|
| 2 |
+
1.000000 0.001260
|
| 3 |
+
0.950070 0.010760
|
| 4 |
+
0.900190 0.019440
|
| 5 |
+
0.850360 0.027380
|
| 6 |
+
0.800580 0.034640
|
| 7 |
+
0.750860 0.041260
|
| 8 |
+
0.701190 0.047300
|
| 9 |
+
0.651580 0.052790
|
| 10 |
+
0.602030 0.057770
|
| 11 |
+
0.552550 0.062270
|
| 12 |
+
0.503140 0.066310
|
| 13 |
+
0.453810 0.069910
|
| 14 |
+
0.404580 0.073080
|
| 15 |
+
0.355450 0.075820
|
| 16 |
+
0.306440 0.078120
|
| 17 |
+
0.257570 0.079970
|
| 18 |
+
0.208840 0.081330
|
| 19 |
+
0.160280 0.082160
|
| 20 |
+
0.111900 0.082400
|
| 21 |
+
0.063730 0.081950
|
| 22 |
+
0.015810 0.080630
|
| 23 |
+
0.000000 0.000000
|
| 24 |
+
0.034190 -0.059780
|
| 25 |
+
0.082600 -0.056500
|
| 26 |
+
0.131100 -0.052370
|
| 27 |
+
0.179720 -0.047770
|
| 28 |
+
0.228460 -0.042960
|
| 29 |
+
0.277320 -0.038070
|
| 30 |
+
0.326290 -0.033180
|
| 31 |
+
0.375360 -0.028360
|
| 32 |
+
0.424540 -0.023640
|
| 33 |
+
0.473810 -0.019070
|
| 34 |
+
0.523190 -0.014680
|
| 35 |
+
0.572640 -0.010500
|
| 36 |
+
0.622170 -0.006560
|
| 37 |
+
0.671770 -0.002890
|
| 38 |
+
0.721440 0.000510
|
| 39 |
+
0.771170 0.003630
|
| 40 |
+
0.820960 0.006480
|
| 41 |
+
0.870790 0.009060
|
| 42 |
+
0.920660 0.011360
|
| 43 |
+
0.970570 0.013400
|
| 44 |
+
1.000000 0.001260
|
examples/rae2822.dat
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
RAE 2822
|
| 2 |
+
1.000000 0.000000
|
| 3 |
+
0.950000 0.005800
|
| 4 |
+
0.900000 0.011200
|
| 5 |
+
0.850000 0.016100
|
| 6 |
+
0.800000 0.020700
|
| 7 |
+
0.750000 0.024900
|
| 8 |
+
0.700000 0.028800
|
| 9 |
+
0.650000 0.032300
|
| 10 |
+
0.600000 0.035500
|
| 11 |
+
0.550000 0.038400
|
| 12 |
+
0.500000 0.040900
|
| 13 |
+
0.450000 0.043000
|
| 14 |
+
0.400000 0.044700
|
| 15 |
+
0.350000 0.045900
|
| 16 |
+
0.300000 0.046500
|
| 17 |
+
0.250000 0.046400
|
| 18 |
+
0.200000 0.045300
|
| 19 |
+
0.150000 0.042700
|
| 20 |
+
0.100000 0.037800
|
| 21 |
+
0.075000 0.034200
|
| 22 |
+
0.050000 0.029200
|
| 23 |
+
0.025000 0.021500
|
| 24 |
+
0.012500 0.015500
|
| 25 |
+
0.000000 0.000000
|
| 26 |
+
0.012500 -0.015500
|
| 27 |
+
0.025000 -0.021000
|
| 28 |
+
0.050000 -0.026500
|
| 29 |
+
0.075000 -0.029500
|
| 30 |
+
0.100000 -0.031500
|
| 31 |
+
0.150000 -0.033500
|
| 32 |
+
0.200000 -0.033500
|
| 33 |
+
0.250000 -0.032000
|
| 34 |
+
0.300000 -0.029500
|
| 35 |
+
0.350000 -0.026500
|
| 36 |
+
0.400000 -0.023000
|
| 37 |
+
0.450000 -0.019500
|
| 38 |
+
0.500000 -0.016000
|
| 39 |
+
0.550000 -0.012500
|
| 40 |
+
0.600000 -0.009500
|
| 41 |
+
0.650000 -0.006800
|
| 42 |
+
0.700000 -0.004500
|
| 43 |
+
0.750000 -0.002700
|
| 44 |
+
0.800000 -0.001300
|
| 45 |
+
0.850000 -0.000500
|
| 46 |
+
0.900000 -0.000100
|
| 47 |
+
0.950000 0.000000
|
| 48 |
+
1.000000 0.000000
|
requirements.txt
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
gradio>=4.0.0,<4.45.0
|
| 2 |
+
# huggingface-hub<1.0.0
|
| 3 |
+
neuralfoil>=0.2.0
|
| 4 |
+
aerosandbox>=4.0.0
|
| 5 |
+
numpy>=1.24.0
|
run.sh
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
# Simple script to run the NeuralFoil Gradio app
|
| 3 |
+
|
| 4 |
+
echo "π Starting NeuralFoil Airfoil Predictor..."
|
| 5 |
+
echo ""
|
| 6 |
+
|
| 7 |
+
# Check if virtual environment exists
|
| 8 |
+
if [ ! -d "venv" ]; then
|
| 9 |
+
echo "β Virtual environment not found!"
|
| 10 |
+
echo "Please run: python3 -m venv venv && source venv/bin/activate && pip install -r requirements.txt"
|
| 11 |
+
exit 1
|
| 12 |
+
fi
|
| 13 |
+
|
| 14 |
+
# Activate virtual environment
|
| 15 |
+
source venv/bin/activate
|
| 16 |
+
|
| 17 |
+
# Check if dependencies are installed
|
| 18 |
+
python -c "import gradio, neuralfoil" 2>/dev/null
|
| 19 |
+
if [ $? -ne 0 ]; then
|
| 20 |
+
echo "β Dependencies not installed!"
|
| 21 |
+
echo "Please run: pip install -r requirements.txt"
|
| 22 |
+
exit 1
|
| 23 |
+
fi
|
| 24 |
+
|
| 25 |
+
echo "β
Virtual environment activated"
|
| 26 |
+
echo "β
Dependencies found"
|
| 27 |
+
echo ""
|
| 28 |
+
echo "π Launching Gradio app..."
|
| 29 |
+
echo "β³ First startup may take 30-60 seconds..."
|
| 30 |
+
echo ""
|
| 31 |
+
|
| 32 |
+
# Run the app
|
| 33 |
+
python app.py
|