@@ -297,16 +297,15 @@ Calculate Aerodynamic Influence Coefficient matrices.
297297
298298See also: [BodyAerodynamics](@ref), [Model](@ref)
299299
300- Returns:
301- Tuple of (`AIC_x`, `AIC_y`, `AIC_z`) matrices
300+ Returns: nothing
302301"""
303- function calculate_AIC_matrices! (body_aero:: BodyAerodynamics , model:: Model ,
302+ @inline function calculate_AIC_matrices! (body_aero:: BodyAerodynamics , model:: Model ,
304303 core_radius_fraction:: Float64 ,
305304 va_norm_array:: Vector{Float64} ,
306305 va_unit_array:: Matrix{Float64} )
307306 # Determine evaluation point based on model
308- evaluation_point = model === VSM ? :control_point : :aero_center
309- evaluation_point_on_bound = model === LLT
307+ evaluation_point = model == VSM ? :control_point : :aero_center
308+ evaluation_point_on_bound = model == LLT
310309
311310 # Initialize AIC matrices
312311 velocity_induced, tempvel, va_unit, U_2D = zeros (MVec3), zeros (MVec3), zeros (MVec3), zeros (MVec3)
@@ -330,13 +329,13 @@ function calculate_AIC_matrices!(body_aero::BodyAerodynamics, model::Model,
330329 core_radius_fraction,
331330 body_aero. work_vectors
332331 )
333- body_aero. AIC[:, icp, jring] .= velocity_induced
334-
332+
335333 # Subtract 2D induced velocity for VSM
336- if icp == jring && model === VSM
334+ if icp == jring && model == VSM
337335 calculate_velocity_induced_bound_2D! (U_2D, body_aero. panels[jring], ep, body_aero. work_vectors)
338- body_aero . AIC[:, icp, jring] .- = U_2D
336+ velocity_induced .- = U_2D
339337 end
338+ body_aero. AIC[:, icp, jring] .= velocity_induced
340339 end
341340 end
342341 return nothing
@@ -347,24 +346,23 @@ end
347346
348347Calculate circulation distribution for an elliptical wing.
349348
350- Returns:
351- Vector{Float64}: Circulation distribution along the wing
349+ Returns: nothing
352350"""
353- function calculate_circulation_distribution_elliptical_wing (body_aero:: BodyAerodynamics , gamma_0:: Float64 = 1.0 )
351+ function calculate_circulation_distribution_elliptical_wing (gamma_i, body_aero:: BodyAerodynamics , gamma_0:: Float64 = 1.0 )
354352 length (body_aero. wings) == 1 || throw (ArgumentError (" Multiple wings not yet implemented" ))
355353
356354 wing_span = body_aero. wings[1 ]. span
357355 @debug " Wing span: $wing_span "
358356
359357 # Calculate y-coordinates of control points
358+ # TODO : pre-allocate y
360359 y = [panel. control_point[2 ] for panel in body_aero. panels]
361360
362361 # Calculate elliptical distribution
363- gamma_i = gamma_0 * sqrt .(1 .- (2 .* y ./ wing_span). ^ 2 )
362+ gamma_i . = gamma_0 * sqrt .(1 .- (2 .* y ./ wing_span). ^ 2 )
364363
365364 @debug " Calculated circulation distribution: $gamma_i "
366-
367- return gamma_i
365+ nothing
368366end
369367
370368"""
@@ -413,6 +411,8 @@ function calculate_stall_angle_list(panels::Vector{Panel};
413411 return stall_angles
414412end
415413
414+ const cache_body = [LazyBufferCache () for _ in 1 : 5 ]
415+
416416"""
417417 update_effective_angle_of_attack_if_VSM(body_aero::BodyAerodynamics, gamma::Vector{Float64},
418418 core_radius_fraction::Float64,
@@ -427,7 +427,8 @@ Update angle of attack at aerodynamic center for VSM method.
427427Returns:
428428 Vector{Float64}: Updated angles of attack
429429"""
430- function update_effective_angle_of_attack_if_VSM (body_aero:: BodyAerodynamics ,
430+ function update_effective_angle_of_attack! (alpha_corrected,
431+ body_aero:: BodyAerodynamics ,
431432 gamma:: Vector{Float64} ,
432433 core_radius_fraction:: Float64 ,
433434 z_airf_array:: Matrix{Float64} ,
@@ -436,26 +437,53 @@ function update_effective_angle_of_attack_if_VSM(body_aero::BodyAerodynamics,
436437 va_norm_array:: Vector{Float64} ,
437438 va_unit_array:: Matrix{Float64} )
438439
439- # Calculate AIC matrices at aerodynamic center using LLT method
440- calculate_AIC_matrices! (
441- body_aero, LLT, core_radius_fraction, va_norm_array, va_unit_array
442- )
443- AIC_x, AIC_y, AIC_z = @views body_aero. AIC[1 , :, :], body_aero. AIC[2 , :, :], body_aero. AIC[3 , :, :]
444-
445- # Calculate induced velocities
446- induced_velocity = [
447- AIC_x * gamma,
448- AIC_y * gamma,
449- AIC_z * gamma
450- ]
451- induced_velocity = hcat (induced_velocity... )
440+ # Calculate AIC matrices (keep existing optimized view)
441+ calculate_AIC_matrices! (body_aero, LLT, core_radius_fraction, va_norm_array, va_unit_array)
442+
443+ # Get dimensions from existing data
444+ n_rows = size (body_aero. AIC, 2 )
445+ n_cols = size (body_aero. AIC, 3 )
446+
447+ # Preallocate induced velocity array
448+ induced_velocity = cache_body[1 ][va_array]
449+
450+ # Calculate each component with explicit loops
451+ for j in 1 : 3 # For each x/y/z component
452+ for i in 1 : n_rows
453+ acc = zero (eltype (induced_velocity)) # Type-stable accumulator
454+ for k in 1 : n_cols
455+ acc += body_aero. AIC[j, i, k] * gamma[k]
456+ end
457+ induced_velocity[i, j] = acc
458+ end
459+ end
460+
461+ # In-place relative velocity calculation
462+ relative_velocity = cache_body[2 ][va_array]
463+ relative_velocity .= va_array .+ induced_velocity
464+
465+ # Preallocate and compute dot products manually
466+ n = size (relative_velocity, 1 )
467+ v_normal = cache_body[3 ][relative_velocity]
468+ v_tangential = cache_body[4 ][relative_velocity]
452469
453- # Calculate relative velocities and angles
454- relative_velocity = va_array + induced_velocity
455- v_normal = sum (z_airf_array .* relative_velocity, dims= 2 )
456- v_tangential = sum (x_airf_array .* relative_velocity, dims= 2 )
457- alpha_array = atan .(v_normal ./ v_tangential)
458- return alpha_array
470+ @inbounds for i in 1 : n
471+ vn = 0.0
472+ vt = 0.0
473+ for j in 1 : 3
474+ vn += z_airf_array[i, j] * relative_velocity[i, j]
475+ vt += x_airf_array[i, j] * relative_velocity[i, j]
476+ end
477+ v_normal[i] = vn
478+ v_tangential[i] = vt
479+ end
480+
481+ # Direct angle calculation without temporary arrays
482+ @inbounds for i in 1 : n
483+ alpha_corrected[i] = atan (v_normal[i], v_tangential[i])
484+ end
485+
486+ nothing
459487end
460488
461489"""
@@ -501,6 +529,7 @@ function calculate_results(
501529 cd_array = zeros (n_panels)
502530 cm_array = zeros (n_panels)
503531 panel_width_array = zeros (n_panels)
532+ alpha_corrected = zeros (n_panels)
504533
505534 # Calculate coefficients for each panel
506535 for (i, panel) in enumerate (panels)
@@ -515,8 +544,9 @@ function calculate_results(
515544 moment = reshape ((cm_array .* 0.5 .* density .* v_a_array.^ 2 .* chord_array), :, 1 )
516545
517546 # Calculate alpha corrections based on model type
518- alpha_corrected = if aerodynamic_model_type === VSM
519- update_effective_angle_of_attack_if_VSM (
547+ if aerodynamic_model_type === VSM
548+ update_effective_angle_of_attack! (
549+ alpha_corrected,
520550 body_aero,
521551 gamma_new,
522552 core_radius_fraction,
@@ -526,10 +556,8 @@ function calculate_results(
526556 va_norm_array,
527557 va_unit_array
528558 )
529- elseif aerodynamic_model_type === LLT
530- alpha_array
531- else
532- throw (ArgumentError (" Unknown aerodynamic model type, should be LLT or VSM" ))
559+ elseif aerodynamic_model_type == LLT
560+ alpha_corrected .= alpha_array
533561 end
534562
535563 # Verify va is not distributed
0 commit comments