Example
This example shows how to use DLM.jl to solve for the lift coefficient slope of a rectangular wing with an aspect ratio of 20 pitching about its midchord.
using DLM
Defining the geometry
Surfaces are defined in DLM.jl by creating rectangular grids with shape (3, ni, nj)
. The first dimension is used for the x, y, and z coordinates, respectively. The second dimension is used for the grid index in the chordwise direction. The third dimension is used for the grid index in the spanwise direction.
Here we will create the AR 20 wing with 10 panels in the chordwise direction and 40 panels in the spanwise direction.
AR = 20
nchord = 10
nspan = 40
b = 10
semispan = b/2
chord = b/AR
symmetric = true
xyz = zeros(3, nchord+1, nspan+1)
for i = 1:nchord+1
for j = 1:nspan+1
xyz[1, i, j] = chord*(i-1)/nchord
xyz[2, i, j] = semispan*(j-1)/nspan
end
end
Using this convention, the geometry can be easily visualized using WriteVTK.
using WriteVTK
# add extra dimension for WriteVTK
xyz_vtk = reshape(xyz, size(xyz)..., 1)
# initialize vtk file
vtkfile = vtk_grid("example", xyz_vtk)
# save the vtk file
vtk_save(vtkfile)
Setting the flow conditions
For this example we will use the following flow properties:
- Velocity: 10 m/s
- Mach Number: 0 (Incompressible)
- Reduced Frequency (based on chord): [0, 0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
U = 10
M = 0.0
kr = [0, 0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Solving for the lift slope
To solve for the lift slope we perform the following steps:
- Construct the AIC matrix
- Find the downwash on each panel's control point
- Solve the system to find the pressure coefficients
- Integrate to find the lift coefficient
AIC = zeros(Complex{Float64}, nchord, nspan, nchord, nspan)
w = zeros(Complex{Float64}, nchord, nspan)
CL = zeros(Complex{Float64}, length(kr))
for k = 1:length(kr)
# compute circular frequency
ω = U*kr[k]/(chord)
# calculate AIC
influence_matrix!(AIC, ω, U, M, xyz, true)
# calculate downwash
for i = 1:nchord
for j = 1:nspan
# get control point x-location
x1 = (1/2)*xyz[1,i,j] + (1/2)*xyz[1,i,j+1]
x2 = (1/2)*xyz[1,i+1,j] + (1/2)*xyz[1,i+1,j+1]
x = (1/4)*x1 + (3/4)*x2
# compute downwash
# -1/U*(dh/dt + U*dh/dx), where h = (x - 0.5c)*e^{j*omega*t}
w[i,j] = -1.0 - 1im*(ω/U)*(x-0.5*chord)
end
end
# solve the system to get the pressure coefficients
Cp = pressure_coefficients(AIC, w)
# integrate to find the lift slope
CL[k] = sum(Cp)/(nspan*nchord)
end
println(CL)
Complex{Float64}[5.469951193063653 + 0.0im, 4.290939951467311 + 0.3166473189485307im, 3.811308954684494 + 1.623745292882406im, 3.4297214864062022 + 4.106557503770894im, 3.173824870397947 + 6.327687027471004im, 2.9114292317363 + 8.29013753929997im, 2.6262943633142957 + 9.975798091612491im, 2.323877065478717 + 11.36817650214414im, 2.014750520973105 + 12.461220208818865im, 1.7097578786561909 + 13.260874668344076im, 1.4181499074018102 + 13.78370390825787im, 1.1468807841505873 + 14.05432585659564im]
Examine the Results
This exact analysis was performed by van Zyl in "Robustness of the subsonic doublet lattice method". Here's a comparison of our results to van Zyl's results:
As you can see, the results match exactly. This is actually not surprising, since the doublet lattice method implementation in DLM.jl is based on the same theory as the doublet lattice method used by van Zyl.
Evaluating the Accuracy of the Results
Even though our results matched those of van Zyl, that doesn't mean that they are accurate. Here we show an excerpt from van Zyl's paper which shows just how accurate our analysis is:
The extrapolated solution shown in the figure is effectively the grid-converged solution, which is pretty close to the analytical solution for an infinite aspect-ratio wing. The doublet lattice results for the 10x10 and 10x40 grids, however, fail to be accurate past a reduced frequency of 2 due to the coarseness of the grid in the chordwise direction.
While doing a grid-independent study is the only sure way of knowing whether your discretization has converged to the correct pressure distribution, previous studies have suggested specified numbers of panels per wavelength in order to resolve the pressure distribution.
Rodden, Taylor, and McIntosh suggested that 50 panels per wavelength may be sufficient to resolve the pressure distribution, with an absolute minimum number of panels of 4.
# use standard definition of reduced frequency based on semi-chord
kr = [0, 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
# minimum number of chordwise panels to resolve pressure distribution
nchord = max.(4, ceil.(Int, 50 .* kr./pi))
println("Number of chordwise panels: ", nchord)
# minimum number of spanwise panels for parabolic kernel (maximum panel aspect ratio of 3)
nspan_parabolic = ceil.(Int, nchord*(AR/2)*1/3)
println("Minimum number of spanwise panels for parabolic kernel: ", nspan_parabolic)
# minimum number of spanwise panels for quartic kernel (maximum panel aspect ratio of 6-10)
nspan_quartic = ceil.(Int, nchord*(AR/2)*1/10)
println("Minimum number of spanwise panels for quartic kernel: ", nspan_quartic)
Number of chordwise panels: [4, 16, 32, 64, 96, 128, 160, 191, 223, 255, 287, 319]
Minimum number of spanwise panels for parabolic kernel: [14, 54, 107, 214, 320, 427, 534, 637, 744, 850, 957, 1064]
Minimum number of spanwise panels for quartic kernel: [4, 16, 32, 64, 96, 128, 160, 191, 223, 255, 287, 319]
Others, however, have suggested as few as 12 panels per wavelength is sufficient. Ultimately the appropriate number of panels depends on how accurate the solution need to be.