Skip to content

march_edges gives each station the previous station's leading-edge step, so a cut near a closing tip grazes the surface and reports an 80%-thick section #361

Description

@1-Bort-1

Summary

march_edges (src/obj_adapter/obj_slice.jl:284) stores with each station the tangent it entered that step with, so row i carries normalize(le[i-1] .- le[i-2]) — one station stale. build_section hands that tangent to airfoil_frame, which builds the cutting plane from it. Near a closing tip the leading edge turns aft and upward, so the plane swings back towards vertical while the tip itself curls down, and the cut grazes the surface instead of crossing it.

On data/ram_air_kite/ram_air_kite_body.obj with the default n_bins=60, station 79 is such a cut. t/c below is the sliced section's depth over its chord, straight out of build_section:

station | y_le   | chord  | t/c (recorded tangent) | t/c (central difference)
     77 | 1.5807 | 0.7273 |                 0.2194 |                  0.2089
     78 | 1.5944 | 0.7074 |                 0.1946 |                  0.2081
     79 | 1.6254 | 0.5055 |                 0.8040 |                  0.1776
     80 | 1.6440 | 0.1683 |                 0.1738 |                  0.1816

Station 79's recorded tangent is [0.811, 0.564, 0.154] — the only one in the tip region pointing up; its neighbours are [0.305, 0.25, -0.919] and [0.695, 0.337, -0.636]. In absolute terms the section it reports is 0.407 m deep where 78 and 80 give 0.138 m and 0.029 m.

What it costs

A section placed on station 79 fits to a blob. NeuralFoil then clamps its whole table:

alpha,delta,Cl,Cd,Cm
-1.0000,-1.0000,0.6374,1.0000,-0.1099
 0.0000,-1.0000,0.6277,1.0000,-0.1074

and its deflected shapes come back empty — Skipping the delta=1.0° overlay ... for airfoils/4_d1.dat: no finite coordinates.

obj_to_yaml's degeneracy guard is built for exactly this and does catch it at a realistic section count: at n_sections=10 the blob fits to thickness=0.428 against a median of 0.122, so it trips 2 × median and the section reuses its neighbour's airfoil (Reused the nearest valid airfoil for: section 1 → airfoil 2, Cd back to 0.0094). At n_sections=4 it does not: two of the four sections are blobs, the median is 0.27 and the limit 0.54 clears 0.43. The guard is only as good as the fraction of sections that are sane.

What I would do

Give each station a tangent from its neighbours rather than from the step that reached it — a central difference over le, taken after the march, leaving the marching itself alone:

le = [r.le for r in rows]
tangent = [normalize(le[min(i + 1, end)] .- le[max(i - 1, 1)]) for i in eachindex(le)]

Measured with that in place, every station from 71 to 80 comes back between 0.177 and 0.21 — the outlier is gone and the rest move by at most 0.035.

I have not committed it anywhere. It moves every station's frame, so every mesh re-slices and every generated geometry shifts; that is a decision of its own rather than a line inside another change.

Where it came from

#350 places sections by spanwise position instead of leading-edge arc length. On this mesh with wingtip_distance=0.05 that puts the outermost section on station 79, where arc-length placement landed on station 80 and walked past the problem. The defect is older than that change and reachable without it — any n_sections/wingtip_distance whose target lands near station 79 hits it.

Related: #272 (the panel normal built from the leading-edge step rather than the quarter-chord step).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions