Skip to content

Commit 71f16bc

Browse files
authored
Merge pull request #24 from byuflowlab/fastmultipole-mvp
Fastmultipole MVP and multipole new features for unstructured grids
2 parents abd62bf + 17437b7 commit 71f16bc

24 files changed

+4430
-108
lines changed

.github/workflows/docs.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
- uses: actions/checkout@v4
2323
- uses: julia-actions/setup-julia@v1
2424
with:
25-
version: '1.10'
25+
version: '1.11'
2626
- uses: julia-actions/cache@v1
2727
- name: Override Conda Python
2828
run: if [ "$RUNNER_OS" = "Linux" ]; then julia -e 'import Pkg; Pkg.add("PyCall"); ENV["PYTHON"]="/usr/bin/python3"; Pkg.build("PyCall")'; fi

.github/workflows/test.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ jobs:
77
runs-on: ${{ matrix.os }}
88
strategy:
99
matrix:
10-
julia-version: ['1.8', '1.10']
10+
julia-version: ['1.8', '1.10', '1.11']
1111
julia-arch: [x64]
1212
os: [ubuntu-latest, macOS-latest]
1313

@@ -24,3 +24,5 @@ jobs:
2424
shell: bash
2525
# - uses: julia-actions/julia-buildpkg@v1
2626
- uses: julia-actions/julia-runtest@v1
27+
with:
28+
test_args: 'remote'

Project.toml

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,38 @@
11
name = "FLOWPanel"
22
uuid = "6be8c882-484d-4309-b349-d23112750151"
33
author = ["Eduardo Alvarez <Edo.AlvarezR@gmail.com>"]
4-
version = "1.1.1"
4+
version = "1.2.1"
55

66
[deps]
77
Dierckx = "39dd38d3-220a-591b-8e3c-4c3a8c710a94"
8-
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
9-
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
10-
Krylov = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7"
8+
# FastMultipole = "ce07d0d3-2b9f-49ba-89eb-12c800257c85"
119
GeometricTools = "83792f5e-c6a1-11e8-2e0a-93511f02ae5f"
1210
ImplicitAD = "e7cbb90b-9b31-4eb2-a8c8-45099c074ee1"
11+
Krylov = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7"
12+
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
13+
LinearOperators = "5c8ed15e-5a4c-59e4-a42b-c7e8811fb125"
14+
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
15+
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
16+
WriteVTK = "64499a7a-5c06-52f2-abe2-ccb03c286192"
17+
18+
# [sources]
19+
# FastMultipole = {url = "https://github.com/byuflowlab/FastMultipole", rev = "d21d242d081ea8c9c19655097d83413b1f783d2d"}
1320

1421
[compat]
15-
julia = "1.6"
1622
Dierckx = "0.5"
1723
GeometricTools = "2.2"
1824
ImplicitAD = "0.3"
1925
Krylov = "0.9"
2026
Requires = "1"
27+
julia = "1.6"
2128

2229
[extras]
23-
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
24-
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
25-
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
26-
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
2730
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
2831
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
32+
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
33+
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
34+
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
35+
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
2936

3037
[targets]
31-
test = ["Pkg", "Test", "Printf",
32-
"ForwardDiff",
33-
"CSV", "DataFrames"]
38+
test = ["Pkg", "Test", "Printf", "ForwardDiff", "CSV", "DataFrames"]

docs/src/examples/cessna-aero.md

Lines changed: 21 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ import Meshes
3737
import GeoIO
3838
import Rotations: RotX, RotY, RotZ
3939

40-
# import CUDA # Uncomment this to use GPU (if available)
41-
4240

4341
run_name = "cessna" # Name of this run
4442

@@ -53,20 +51,20 @@ rho = 0.71461 # (kg/m^3) air density at 17300 ft
5351

5452

5553
# ----------------- GEOMETRY DESCRIPTION ---------------------------------------
56-
meshfile = joinpath(read_path, "cessna.msh") # Gmsh file to read
54+
meshfile = "cessna.msh" # Gmsh file to read
5755

5856
offset = [0, 0, 0] # Offset to center the mesh
5957
rotation = RotX(0*pi/180) * RotY(0*pi/180) * RotX(0*pi/180) # Rotation to align mesh
6058
scaling = 0.3048 # Factor to scale mesh dimensions (ft -> m)
6159

62-
# Gmsh files with trailing edges
63-
trailingedges = [ # ( Gmsh file, span direction )
64-
("cessna-TE-leftwing.msh", [0, 1, 0]),
65-
("cessna-TE-rightwing.msh", [0, 1, 0]),
66-
("cessna-TE-leftelevator.msh", [0, 1, 0]),
67-
("cessna-TE-rightelevator.msh", [0, 1, 0]),
68-
("cessna-TE-rudder.msh", [0, 0, 1]),
69-
]
60+
trailingedges = [ # Gmsh files with trailing edges
61+
# ( Gmsh file, span sorting function, junction criterion, closed )
62+
( "cessna-TE-leftwing.msh", X -> dot(X, [0, 1, 0]), X -> abs(X[2]) - 0.67, false ),
63+
( "cessna-TE-rightwing.msh", X -> dot(X, [0, 1, 0]), X -> abs(X[2]) - 0.67, false ),
64+
( "cessna-TE-leftelevator.msh", X -> dot(X, [0, 1, 0]), X -> abs(X[2]) - 0.23, false ),
65+
( "cessna-TE-rightelevator.msh", X -> dot(X, [0, 1, 0]), X -> abs(X[2]) - 0.23, false ),
66+
( "cessna-TE-rudder.msh", X -> dot(X, [0, 0, 1]), X -> X[3] - 0.65, false ),
67+
]
7068

7169
flip = true # Whether to flip control points against the direction of normals
7270
# NOTE: use `flip=true` if the normals
@@ -78,6 +76,12 @@ Sref = 16.2344 # (m^2) reference area
7876
Xac = [2.815, 0, 0.4142] # (m) aerodynamic center for
7977
# calculation of moments
8078

79+
# Define function used for reading Gmsh files
80+
meshreader(file) = GeoIO.load(file).geometry
81+
82+
# Format input for `generate_multibody(...)`
83+
meshfiles = [ ("Airframe", meshfile, flip) ]
84+
8185
# ----------------- SOLVER SETTINGS -------------------------------------------
8286

8387
# Solver: direct linear solver for open bodies
@@ -88,71 +92,11 @@ bodytype = pnl.RigidWakeBody{pnl.VortexRing, 2}
8892

8993

9094
# ----------------- GENERATE BODY ----------------------------------------------
91-
# Read Gmsh mesh
92-
msh = GeoIO.load(meshfile)
93-
msh = msh.geometry
94-
95-
# Transform the original mesh: Translate, rotate, and scale
96-
msh = msh |> Meshes.Translate(offset...) |> Meshes.Rotate(rotation) |> Meshes.Scale(scaling)
97-
98-
# Wrap Meshes object into a Grid object from GeometricTools
99-
grid = pnl.gt.GridTriangleSurface(msh)
100-
101-
# Read all trailing edges
102-
sheddings = []
103-
104-
for (trailingedgefile, spandir) in trailingedges
105-
106-
# Read Gmsh line of trailing edge
107-
TEmsh = GeoIO.load(joinpath(read_path, trailingedgefile))
108-
TEmsh = TEmsh.geometry
109-
110-
# Apply the same transformations of the mesh to the trailing edge
111-
TEmsh = TEmsh |> Meshes.Translate(offset...) |> Meshes.Rotate(rotation) |> Meshes.Scale(scaling)
112-
113-
# Convert TE Meshes object into a matrix of points used to identify the trailing edge
114-
trailingedge = pnl.gt.vertices2nodes(TEmsh.vertices)
115-
116-
# Sort TE points from "left" to "right" according to span direction
117-
trailingedge = sortslices(trailingedge; dims=2, by = X -> pnl.dot(X, spandir))
118-
119-
# Function for identifying if a point is close to a junction
120-
if trailingedgefile in ["cessna-TE-leftwing.msh", "cessna-TE-rightwing.msh"]
121-
122-
criterion = X -> abs(X[2]) <= 0.67
123-
124-
elseif trailingedgefile in ["cessna-TE-leftelevator.msh", "cessna-TE-rightelevator.msh"]
125-
126-
criterion = X -> abs(X[2]) <= 0.23
127-
128-
elseif trailingedgefile in ["cessna-TE-rudder.msh"]
129-
130-
criterion = X -> X[3] <= 0.65
131-
132-
else
133-
134-
criterion = X -> false
135-
136-
end
137-
138-
# Filter out any points that are close to junctions
139-
tokeep = filter( i -> !criterion(trailingedge[:, i]), 1:size(trailingedge, 2) )
140-
trailingedge = trailingedge[:, tokeep]
141-
142-
# Generate TE shedding matrix
143-
shedding = pnl.calc_shedding(grid, trailingedge; tolerance=0.001*bref)
144-
145-
push!(sheddings, shedding)
146-
147-
end
148-
149-
# Combine all TE shedding matrices into one
150-
shedding = hcat(sheddings...)
151-
152-
# Generate paneled body
153-
body = bodytype(grid, shedding; CPoffset=(-1)^flip * 1e-14)
154-
155-
println("Number of panels:\t$(body.ncells)")
95+
body, elsprescribe = pnl.generate_multibody(bodytype, meshfiles, trailingedges, meshreader;
96+
tolerance=0.001*bref,
97+
read_path=read_path,
98+
offset=offset, rotation=rotation, scaling=scaling,
99+
)
156100

157101

158102
# ----------------- CALL SOLVER ------------------------------------------------
@@ -171,10 +115,7 @@ Dbs = repeat(Vinf/magVinf, 1, body.nsheddings)
171115

172116
# Solve body (panel strengths) giving `Uinfs` as boundary conditions and
173117
# `Das` and `Dbs` as trailing edge rigid wake direction
174-
@time pnl.solve(body, Uinfs, Das, Dbs)
175-
176-
# Uncomment this to use GPU instead (if available)
177-
# @time pnl.solve(body, Uinfs, Das, Dbs; GPUArray=CUDA.CuArray{Float32})
118+
@time pnl.solve(body, Uinfs, Das, Dbs; elprescribe=elsprescribe)
178119

179120
# ----------------- POST PROCESSING ----------------------------------------
180121
println("Post processing...")

docs/src/generate_examples_cessna.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ open(joinpath(output_path, output_name*"-aero.md"), "w") do fout
203203

204204
println(fout, "```julia")
205205

206-
open(joinpath(pnl.examples_path, "cessna.jl"), "r") do fin
206+
open(joinpath(pnl.examples_path, "cessna2.jl"), "r") do fin
207207
for l in eachline(fin)
208208
# if contains(l, "COMPARISON TO EXPERIMENTAL DATA")
209209
# break

0 commit comments

Comments
 (0)