-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0cf4fbf
commit 748dd80
Showing
9 changed files
with
665 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
name: Dash example workflow | ||
|
||
on: | ||
push: | ||
paths: | ||
- "examples/dash/**" | ||
workflow_dispatch: | ||
inputs: | ||
logLevel: | ||
description: 'Log level' | ||
required: true | ||
default: 'warning' | ||
type: choice | ||
options: | ||
- info | ||
- warning | ||
- debug | ||
tags: | ||
description: 'Manual run' | ||
required: false | ||
type: boolean | ||
|
||
|
||
jobs: | ||
push: | ||
if: | | ||
github.ref == 'refs/heads/main' && | ||
github.repository == 'scilifelabdatacentre/serve-images' | ||
runs-on: ubuntu-latest | ||
concurrency: | ||
group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}' | ||
cancel-in-progress: true | ||
permissions: | ||
contents: read | ||
packages: write | ||
|
||
steps: | ||
- name: 'Checkout github action' | ||
uses: actions/checkout@main | ||
|
||
- name: Docker meta | ||
id: meta | ||
uses: docker/metadata-action@v4 | ||
with: | ||
images: ghcr.io/scilifelabdatacentre/example-dash | ||
tags: | | ||
type=raw,value={{date 'YYMMDD-HHmm' tz='Europe/Stockholm'}} | ||
- name: 'Login to GHCR' | ||
uses: docker/login-action@v1 | ||
with: | ||
registry: ghcr.io | ||
username: ${{github.actor}} | ||
password: ${{secrets.GITHUB_TOKEN}} | ||
|
||
- name: Publish image to GHCR | ||
uses: docker/build-push-action@v3 | ||
with: | ||
file: ./examples/dash/Dockerfile | ||
context: ./examples/dash | ||
push: true | ||
build-args: version=${{ github.ref_name }} | ||
tags: | | ||
${{ steps.meta.outputs.tags }} | ||
ghcr.io/scilifelabdatacentre/example-dash:latest | ||
labels: ${{ steps.meta.outputs.labels }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
FROM python:3.8-slim | ||
|
||
ENV USER=serve | ||
ENV HOME=/home/$USER | ||
|
||
RUN apt-get update -yq \ | ||
&& useradd -m $USER \ | ||
&& pip install --upgrade --no-cache-dir pip \ | ||
&& rm -rf /var/lib/apt/lists/* | ||
|
||
COPY . $HOME/ | ||
|
||
RUN pip install --no-cache-dir --upgrade pip \ | ||
&& pip install --no-cache-dir -r $HOME/requirements.txt | ||
|
||
USER $USER | ||
EXPOSE 8000 | ||
WORKDIR $HOME | ||
|
||
ENTRYPOINT ["gunicorn", "app:server", "-b", "0.0.0.0:8000"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
web: gunicorn app:server --workers 4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# AeroSandbox-Interactive-Demo | ||
by Peter Sharpe | ||
|
||
## Description | ||
An interactive demo of AeroSandbox, powered by Dash! Work in progress. | ||
|
||
## Installation and Usage | ||
1. Install all dependencies listed in `requirements.txt` - all packages are pip-installable. In particular, be sure to get a recent version of AeroSandbox (`pip install --upgrade aerosandbox`). | ||
2. Run `app.py` to launch a local Dash server to host the Dash app. A link will appear in your console; click this to use the Dash app. | ||
|
||
## Illustration |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,260 @@ | ||
import aerosandbox as asb | ||
from aerosandbox.library.airfoils import e216 | ||
import numpy as np | ||
import casadi as cas | ||
import copy | ||
|
||
naca0008 = asb.Airfoil("naca0008") | ||
|
||
|
||
def make_airplane( | ||
n_booms, wing_span, | ||
): | ||
# n_booms = 3 | ||
|
||
# wing | ||
# wing_span = 37.126 | ||
wing_root_chord = 2.316 | ||
wing_x_quarter_chord = -0.1 | ||
|
||
# hstab | ||
hstab_span = 2.867 | ||
hstab_chord = 1.085 | ||
hstab_twist_angle = -7 | ||
|
||
# vstab | ||
vstab_span = 2.397 | ||
vstab_chord = 1.134 | ||
|
||
# fuselage | ||
boom_length = 6.181 | ||
nose_length = 1.5 | ||
fuse_diameter = 0.6 | ||
boom_diameter = 0.2 | ||
|
||
wing = asb.Wing( | ||
name="Main Wing", | ||
# x_le=-0.05 * wing_root_chord, # Coordinates of the wing's leading edge # TODO make this a free parameter? | ||
x_le=wing_x_quarter_chord, # Coordinates of the wing's leading edge # TODO make this a free parameter? | ||
y_le=0, # Coordinates of the wing's leading edge | ||
z_le=0, # Coordinates of the wing's leading edge | ||
symmetric=True, | ||
xsecs=[ # The wing's cross ("X") sections | ||
asb.WingXSec( # Root | ||
x_le=-wing_root_chord / 4, | ||
# Coordinates of the XSec's leading edge, relative to the wing's leading edge. | ||
y_le=0, # Coordinates of the XSec's leading edge, relative to the wing's leading edge. | ||
z_le=0, # Coordinates of the XSec's leading edge, relative to the wing's leading edge. | ||
chord=wing_root_chord, | ||
twist=0, # degrees | ||
airfoil=e216, # Airfoils are blended between a given XSec and the next one. | ||
control_surface_type="symmetric", | ||
# Flap # Control surfaces are applied between a given XSec and the next one. | ||
control_surface_deflection=0, # degrees | ||
spanwise_panels=30, | ||
), | ||
asb.WingXSec( # Tip | ||
x_le=-wing_root_chord * 0.5 / 4, | ||
y_le=wing_span / 2, | ||
z_le=0, # wing_span / 2 * cas.pi / 180 * 5, | ||
chord=wing_root_chord * 0.5, | ||
twist=0, | ||
airfoil=e216, | ||
), | ||
], | ||
) | ||
hstab = asb.Wing( | ||
name="Horizontal Stabilizer", | ||
x_le=boom_length | ||
- vstab_chord * 0.75 | ||
- hstab_chord, # Coordinates of the wing's leading edge | ||
y_le=0, # Coordinates of the wing's leading edge | ||
z_le=0.1, # Coordinates of the wing's leading edge | ||
symmetric=True, | ||
xsecs=[ # The wing's cross ("X") sections | ||
asb.WingXSec( # Root | ||
x_le=0, # Coordinates of the XSec's leading edge, relative to the wing's leading edge. | ||
y_le=0, # Coordinates of the XSec's leading edge, relative to the wing's leading edge. | ||
z_le=0, # Coordinates of the XSec's leading edge, relative to the wing's leading edge. | ||
chord=hstab_chord, | ||
twist=-3, # degrees # TODO fix | ||
airfoil=naca0008, # Airfoils are blended between a given XSec and the next one. | ||
control_surface_type="symmetric", | ||
# Flap # Control surfaces are applied between a given XSec and the next one. | ||
control_surface_deflection=0, # degrees | ||
spanwise_panels=8, | ||
), | ||
asb.WingXSec( # Tip | ||
x_le=0, | ||
y_le=hstab_span / 2, | ||
z_le=0, | ||
chord=hstab_chord, | ||
twist=-3, # TODO fix | ||
airfoil=naca0008, | ||
), | ||
], | ||
) | ||
vstab = asb.Wing( | ||
name="Vertical Stabilizer", | ||
x_le=boom_length - vstab_chord * 0.75, # Coordinates of the wing's leading edge | ||
y_le=0, # Coordinates of the wing's leading edge | ||
z_le=-vstab_span / 2 | ||
+ vstab_span * 0.15, # Coordinates of the wing's leading edge | ||
symmetric=False, | ||
xsecs=[ # The wing's cross ("X") sections | ||
asb.WingXSec( # Root | ||
x_le=0, # Coordinates of the XSec's leading edge, relative to the wing's leading edge. | ||
y_le=0, # Coordinates of the XSec's leading edge, relative to the wing's leading edge. | ||
z_le=0, # Coordinates of the XSec's leading edge, relative to the wing's leading edge. | ||
chord=vstab_chord, | ||
twist=0, # degrees | ||
airfoil=naca0008, # Airfoils are blended between a given XSec and the next one. | ||
control_surface_type="symmetric", | ||
# Flap # Control surfaces are applied between a given XSec and the next one. | ||
control_surface_deflection=0, # degrees | ||
spanwise_panels=8, | ||
), | ||
asb.WingXSec( # Tip | ||
x_le=0, | ||
y_le=0, | ||
z_le=vstab_span, | ||
chord=vstab_chord, | ||
twist=0, | ||
airfoil=naca0008, | ||
), | ||
], | ||
) | ||
### Build the fuselage geometry | ||
blend = lambda x: (1 - np.cos(np.pi * x)) / 2 | ||
fuse_x_c = [] | ||
fuse_z_c = [] | ||
fuse_radius = [] | ||
fuse_resolution = 10 | ||
# Nose geometry | ||
fuse_nose_theta = np.linspace(0, np.pi / 2, fuse_resolution) | ||
fuse_x_c.extend( | ||
[ | ||
(wing_x_quarter_chord - wing_root_chord / 4) - nose_length * np.cos(theta) | ||
for theta in fuse_nose_theta | ||
] | ||
) | ||
fuse_z_c.extend([-fuse_diameter / 2] * fuse_resolution) | ||
fuse_radius.extend([fuse_diameter / 2 * np.sin(theta) for theta in fuse_nose_theta]) | ||
# Taper | ||
fuse_taper_x_nondim = np.linspace(0, 1, fuse_resolution) | ||
fuse_x_c.extend( | ||
[ | ||
0.0 * boom_length + (0.6 - 0.0) * boom_length * x_nd | ||
for x_nd in fuse_taper_x_nondim | ||
] | ||
) | ||
fuse_z_c.extend( | ||
[ | ||
-fuse_diameter / 2 * blend(1 - x_nd) - boom_diameter / 2 * blend(x_nd) | ||
for x_nd in fuse_taper_x_nondim | ||
] | ||
) | ||
fuse_radius.extend( | ||
[ | ||
fuse_diameter / 2 * blend(1 - x_nd) + boom_diameter / 2 * blend(x_nd) | ||
for x_nd in fuse_taper_x_nondim | ||
] | ||
) | ||
# Tail | ||
# fuse_tail_x_nondim = np.linspace(0, 1, fuse_resolution)[1:] | ||
# fuse_x_c.extend([ | ||
# 0.9 * boom_length + (1 - 0.9) * boom_length * x_nd for x_nd in fuse_taper_x_nondim | ||
# ]) | ||
# fuse_z_c.extend([ | ||
# -boom_diameter / 2 * blend(1 - x_nd) for x_nd in fuse_taper_x_nondim | ||
# ]) | ||
# fuse_radius.extend([ | ||
# boom_diameter / 2 * blend(1 - x_nd) for x_nd in fuse_taper_x_nondim | ||
# ]) | ||
fuse_straight_resolution = 4 | ||
fuse_x_c.extend( | ||
[ | ||
0.6 * boom_length + (1 - 0.6) * boom_length * x_nd | ||
for x_nd in np.linspace(0, 1, fuse_straight_resolution)[1:] | ||
] | ||
) | ||
fuse_z_c.extend([-boom_diameter / 2] * (fuse_straight_resolution - 1)) | ||
fuse_radius.extend([boom_diameter / 2] * (fuse_straight_resolution - 1)) | ||
|
||
fuse = asb.Fuselage( | ||
name="Fuselage", | ||
x_le=0, | ||
y_le=0, | ||
z_le=0, | ||
xsecs=[ | ||
asb.FuselageXSec(x_c=fuse_x_c[i], z_c=fuse_z_c[i], radius=fuse_radius[i]) | ||
for i in range(len(fuse_x_c)) | ||
], | ||
) | ||
|
||
# Assemble the airplane | ||
fuses = [] | ||
hstabs = [] | ||
vstabs = [] | ||
if n_booms == 1: | ||
fuses.append(fuse) | ||
hstabs.append(hstab) | ||
vstabs.append(vstab) | ||
elif n_booms == 2: | ||
boom_location = 0.40 # as a fraction of the half-span | ||
|
||
left_fuse = copy.deepcopy(fuse) | ||
right_fuse = copy.deepcopy(fuse) | ||
left_fuse.xyz_le += cas.vertcat(0, -wing_span / 2 * boom_location, 0) | ||
right_fuse.xyz_le += cas.vertcat(0, wing_span / 2 * boom_location, 0) | ||
fuses.extend([left_fuse, right_fuse]) | ||
|
||
left_hstab = copy.deepcopy(hstab) | ||
right_hstab = copy.deepcopy(hstab) | ||
left_hstab.xyz_le += cas.vertcat(0, -wing_span / 2 * boom_location, 0) | ||
right_hstab.xyz_le += cas.vertcat(0, wing_span / 2 * boom_location, 0) | ||
hstabs.extend([left_hstab, right_hstab]) | ||
|
||
left_vstab = copy.deepcopy(vstab) | ||
right_vstab = copy.deepcopy(vstab) | ||
left_vstab.xyz_le += cas.vertcat(0, -wing_span / 2 * boom_location, 0) | ||
right_vstab.xyz_le += cas.vertcat(0, wing_span / 2 * boom_location, 0) | ||
vstabs.extend([left_vstab, right_vstab]) | ||
|
||
elif n_booms == 3: | ||
boom_location = 0.57 # as a fraction of the half-span | ||
|
||
left_fuse = copy.deepcopy(fuse) | ||
center_fuse = copy.deepcopy(fuse) | ||
right_fuse = copy.deepcopy(fuse) | ||
left_fuse.xyz_le += cas.vertcat(0, -wing_span / 2 * boom_location, 0) | ||
right_fuse.xyz_le += cas.vertcat(0, wing_span / 2 * boom_location, 0) | ||
fuses.extend([left_fuse, center_fuse, right_fuse]) | ||
|
||
left_hstab = copy.deepcopy(hstab) | ||
center_hstab = copy.deepcopy(hstab) | ||
right_hstab = copy.deepcopy(hstab) | ||
left_hstab.xyz_le += cas.vertcat(0, -wing_span / 2 * boom_location, 0) | ||
right_hstab.xyz_le += cas.vertcat(0, wing_span / 2 * boom_location, 0) | ||
hstabs.extend([left_hstab, center_hstab, right_hstab]) | ||
|
||
left_vstab = copy.deepcopy(vstab) | ||
center_vstab = copy.deepcopy(vstab) | ||
right_vstab = copy.deepcopy(vstab) | ||
left_vstab.xyz_le += cas.vertcat(0, -wing_span / 2 * boom_location, 0) | ||
right_vstab.xyz_le += cas.vertcat(0, wing_span / 2 * boom_location, 0) | ||
vstabs.extend([left_vstab, center_vstab, right_vstab]) | ||
|
||
else: | ||
raise ValueError("Bad value of n_booms!") | ||
|
||
airplane = asb.Airplane( | ||
name="Solar1", | ||
x_ref=0, | ||
y_ref=0, | ||
z_ref=0, | ||
wings=[wing] + hstabs + vstabs, | ||
fuselages=fuses, | ||
) | ||
|
||
return airplane |
Oops, something went wrong.