@@ -1120,8 +1120,9 @@ end
11201120
11211121Refine mesh by splitting provided sections into desired number of panels.
11221122
1123- When `billowing_percentage > 0`, applies catenary TE displacement to intermediate
1124- sections within each rib pair (simulating fabric billowing between ribs).
1123+ When `billowing_percentage > 0`, applies sinusoidal TE displacement to
1124+ intermediate sections within each rib pair (simulating fabric billowing
1125+ between ribs).
11251126"""
11261127function refine_mesh_by_splitting_provided_sections! (
11271128 wing:: AbstractWing ;
@@ -1136,13 +1137,33 @@ function refine_mesh_by_splitting_provided_sections!(
11361137
11371138 # Check if refinement is needed
11381139 if n_panels_provided == n_panels_desired
1139- for (refined_section, section) in zip (wing. refined_sections, wing. unrefined_sections)
1140+ for (refined_section, section) in zip (
1141+ wing. refined_sections, wing. unrefined_sections)
11401142 if reuse_aero_data
1141- reinit! (refined_section, section. LE_point, section. TE_point, section. aero_model)
1143+ reinit! (refined_section, section. LE_point,
1144+ section. TE_point, section. aero_model)
11421145 else
11431146 reinit! (refined_section, section)
11441147 end
11451148 end
1149+ if billowing_percentage > 0
1150+ LE = [s. LE_point for s in wing. unrefined_sections]
1151+ TE = [s. TE_point for s in wing. unrefined_sections]
1152+ for i in 1 : (n_panels_provided - 1 )
1153+ y_hat = normalize (LE[i] - LE[i + 1 ])
1154+ span_len = norm (LE[i] - LE[i + 1 ])
1155+ start_si = i + 1
1156+ end_si = i + 1
1157+ if start_si <= end_si
1158+ apply_billowing_to_pair! (
1159+ wing. refined_sections,
1160+ start_si, end_si,
1161+ y_hat, span_len,
1162+ LE[i + 1 ], TE[i], TE[i + 1 ],
1163+ billowing_percentage)
1164+ end
1165+ end
1166+ end
11461167 return nothing
11471168 end
11481169
@@ -1249,13 +1270,25 @@ function refine_mesh_by_splitting_provided_sections!(
12491270
12501271 # Validate result
12511272 if length (wing. refined_sections) != wing. n_panels + 1
1252- @warn " Number of panels ($(length (new_sections )- 1 ) ) differs from desired ($(wing. n_panels) )"
1273+ @warn " Number of panels ($(length (wing . refined_sections )- 1 ) ) differs from desired ($(wing. n_panels) )"
12531274 end
12541275
12551276 return nothing
12561277end
12571278
12581279
1280+ """
1281+ rodrigues_rotate(vec, axis, θ)
1282+
1283+ Rotate `vec` around unit `axis` by angle `θ` (radians) using the
1284+ Rodrigues rotation formula. Non-allocating with MVec3 inputs.
1285+ """
1286+ @inline function rodrigues_rotate (vec, axis, θ)
1287+ ct = cos (θ); st = sin (θ)
1288+ d = dot (vec, axis)
1289+ return ct * vec + st * cross (axis, vec) + (1 - ct) * d * axis
1290+ end
1291+
12591292"""
12601293 billowing_arc_length(sections, start_si, end_si, y_hat,
12611294 span_len, le_ref, te_left, te_right,
@@ -1279,11 +1312,7 @@ function billowing_arc_length(
12791312 t = dot (sec. LE_point - le_ref, y_hat) / span_len
12801313 θ = - angle_max * sin (π * t)
12811314 chord_vec = sec. TE_point - sec. LE_point
1282- ct = cos (θ); st = sin (θ)
1283- d_y = dot (chord_vec, y_hat)
1284- rotated = ct * chord_vec +
1285- st * cross (y_hat, chord_vec) +
1286- (1 - ct) * d_y * y_hat
1315+ rotated = rodrigues_rotate (chord_vec, y_hat, θ)
12871316 current_te = sec. LE_point + rotated
12881317 arc += norm (current_te - prev_te)
12891318 prev_te = current_te
@@ -1314,6 +1343,10 @@ function apply_billowing_to_pair!(
13141343 te_left, te_right, percentage
13151344)
13161345 percentage <= 0 && return nothing
1346+ if percentage >= 100
1347+ throw (ArgumentError (
1348+ " billowing_percentage must be < 100, got $percentage " ))
1349+ end
13171350 straight = norm (te_right - te_left)
13181351 straight < 1e-12 && return nothing
13191352 target_arc = straight / (1 - percentage / 100 )
@@ -1335,7 +1368,7 @@ function apply_billowing_to_pair!(
13351368 te_left, te_right, angle_max + δ)
13361369 df = (arc_p - arc) / δ
13371370 abs (df) < 1e-30 && break
1338- angle_max -= f / df
1371+ angle_max = max ( 0.0 , angle_max - f / df)
13391372 end
13401373
13411374 # Apply converged rotations in-place
@@ -1344,11 +1377,7 @@ function apply_billowing_to_pair!(
13441377 t = dot (sec. LE_point - le_ref, y_hat) / span_len
13451378 θ = - angle_max * sin (π * t)
13461379 chord_vec = sec. TE_point - sec. LE_point
1347- ct = cos (θ); st = sin (θ)
1348- d_y = dot (chord_vec, y_hat)
1349- rotated = ct * chord_vec +
1350- st * cross (y_hat, chord_vec) +
1351- (1 - ct) * d_y * y_hat
1380+ rotated = rodrigues_rotate (chord_vec, y_hat, θ)
13521381 sec. TE_point .= sec. LE_point + rotated
13531382 end
13541383 return nothing
0 commit comments