@@ -412,8 +412,10 @@ Calculate final aerodynamic results.
412412Returns:
413413 Dict: Results including forces, coefficients and distributions
414414"""
415- function calculate_results (body_aero:: BodyAerodynamics ,
415+ function calculate_results (
416+ body_aero:: BodyAerodynamics ,
416417 gamma_new:: Vector{Float64} ,
418+ reference_point:: AbstractVector ,
417419 density:: Float64 ,
418420 aerodynamic_model_type:: Symbol ,
419421 core_radius_fraction:: Float64 ,
@@ -428,7 +430,8 @@ function calculate_results(body_aero::BodyAerodynamics,
428430 va_norm_array:: Vector{Float64} ,
429431 va_unit_array:: Matrix{Float64} ,
430432 panels:: Vector{Panel} ,
431- is_only_f_and_gamma_output:: Bool )
433+ is_only_f_and_gamma_output:: Bool ,
434+ )
432435
433436 # Initialize arrays
434437 n_panels = length (panels)
@@ -477,6 +480,7 @@ function calculate_results(body_aero::BodyAerodynamics,
477480 cd_prescribed_va = Float64[]
478481 cs_prescribed_va = Float64[]
479482 f_global_3D = zeros (3 , n_panels)
483+ m_global_3D = zeros (3 , n_panels)
480484 area_all_panels = 0.0
481485
482486 # Initialize force sums
@@ -493,6 +497,7 @@ function calculate_results(body_aero::BodyAerodynamics,
493497
494498 # Main calculation loop
495499 for (i, panel) in enumerate (panels)
500+ # ## Lift and Drag ###
496501 # Panel geometry
497502 z_airf_span = panel. z_airf
498503 y_airf_chord = panel. y_airf
@@ -545,6 +550,27 @@ function calculate_results(body_aero::BodyAerodynamics,
545550 push! (cl_prescribed_va, lift_prescribed_va / (q_inf * panel. chord))
546551 push! (cd_prescribed_va, drag_prescribed_va / (q_inf * panel. chord))
547552 push! (cs_prescribed_va, side_prescribed_va / (q_inf * panel. chord))
553+
554+ # ## Moment ###
555+ # (1) Panel aerodynamic center in global frame:
556+ panel_ac_global = panel. aero_center # 3D [x, y, z]
557+
558+ # (2) Convert local (2D) pitching moment to a 3D vector in global coords.
559+ # Use the axis around which the moment is defined,
560+ # which is the z-axis pointing "spanwise"
561+ moment_axis_global = panel. z_airf
562+
563+ # Scale by panel width if your 'moment[i]' is 2D moment-per-unit-span:
564+ M_local_3D = moment[i] * moment_axis_global * panel. width
565+
566+ # Vector from panel AC to the chosen reference point:
567+ r_vector = panel_ac_global - reference_point # e.g. CG, wing root, etc.
568+
569+ # Cross product to shift the force from panel AC to ref. point:
570+ M_shift = cross (r_vector, f_global_3D[:,i])
571+
572+ # Total panel moment about the reference point:
573+ m_global_3D[:,i] = M_local_3D + M_shift
548574 end
549575
550576 if is_only_f_and_gamma_output
@@ -572,14 +598,20 @@ function calculate_results(body_aero::BodyAerodynamics,
572598 # Create results dictionary
573599 results = Dict {String,Any} (
574600 " Fx" => sum (f_global_3D[1 ,:]),
575- " Fy" => sum (f_global_3D[1 ,:]),
576- " Fz" => sum (f_global_3D[1 ,:]),
601+ " Fy" => sum (f_global_3D[2 ,:]),
602+ " Fz" => sum (f_global_3D[3 ,:]),
603+ " Mx" => sum (m_global_3D[1 ,:]),
604+ " My" => sum (m_global_3D[2 ,:]),
605+ " Mz" => sum (m_global_3D[3 ,:]),
577606 " lift" => lift_wing_3D_sum,
578607 " drag" => drag_wing_3D_sum,
579608 " side" => side_wing_3D_sum,
580609 " cl" => lift_wing_3D_sum / (q_inf * projected_area),
581610 " cd" => drag_wing_3D_sum / (q_inf * projected_area),
582611 " cs" => side_wing_3D_sum / (q_inf * projected_area),
612+ " cmx" => sum (m_global_3D[1 ,:]) / (q_inf * projected_area * max_chord),
613+ " cmy" => sum (m_global_3D[2 ,:]) / (q_inf * projected_area * max_chord),
614+ " cmz" => sum (m_global_3D[3 ,:]) / (q_inf * projected_area * max_chord),
583615 " cl_distribution" => cl_prescribed_va,
584616 " cd_distribution" => cd_prescribed_va,
585617 " cs_distribution" => cs_prescribed_va,
0 commit comments