From 5d7c3a2fef213cf99aa7441750cc3ebe2e56cdbb Mon Sep 17 00:00:00 2001 From: planes Date: Tue, 29 Mar 2022 08:59:41 -0700 Subject: [PATCH 1/3] correct equations for writing of control surfaces; --- trunk/SUAVE/Input_Output/OpenVSP/vsp_wing.py | 55 ++++++++++++++++++-- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/trunk/SUAVE/Input_Output/OpenVSP/vsp_wing.py b/trunk/SUAVE/Input_Output/OpenVSP/vsp_wing.py index df92dc594e..ab17962c88 100644 --- a/trunk/SUAVE/Input_Output/OpenVSP/vsp_wing.py +++ b/trunk/SUAVE/Input_Output/OpenVSP/vsp_wing.py @@ -655,7 +655,7 @@ def write_vsp_wing(vehicle,wing, area_tags, fuel_tank_set_ind, OML_set_ind): if 'control_surfaces' in wing: for ctrl_surf in wing.control_surfaces: - write_vsp_control_surface(wing_id,ctrl_surf,n_segments) + write_vsp_control_surface(wing,wing_id,ctrl_surf) if 'Fuel_Tanks' in wing: @@ -668,7 +668,7 @@ def write_vsp_wing(vehicle,wing, area_tags, fuel_tank_set_ind, OML_set_ind): ## @ingroup Input_Output-OpenVSP -def write_vsp_control_surface(wing_id,ctrl_surf,n_segments): +def write_vsp_control_surface(wing,wing_id,ctrl_surf): """This writes a control surface in a wing. Assumptions: @@ -688,6 +688,27 @@ def write_vsp_control_surface(wing_id,ctrl_surf,n_segments): Properties Used: N/A """ + + # determine the number of segments and where the breaks are + if len(wing.Segments.keys())>0: + N = len(wing.Segments.keys())-1 + + # Do a for loop to find the location of breaks + breaks = [] + for seg in wing.Segments: + breaks.append(seg.percent_span_location) + + else: + N = 1 + # Location of breaks + breaks = [0.,1.] + + breaks = np.array(breaks) + + span_start = ctrl_surf.span_fraction_start + span_end = ctrl_surf.span_fraction_end + + cs_id = vsp.AddSubSurf( wing_id, vsp.SS_CONTROL) param_names = vsp.GetSubSurfParmIDs(cs_id) for p_idx in range(len(param_names)): @@ -696,10 +717,36 @@ def write_vsp_control_surface(wing_id,ctrl_surf,n_segments): vsp.SetParmVal(param_names[p_idx], 1.0) else: vsp.SetParmVal( param_names[p_idx], 0.0) + + # U values are only linear about the section in which they are defined + + # Identify the segments they start and end with, if there are no segments there is one segment + segment_start = np.where(breaks=span_end)[0][0] -1 + + # Find where in the segment it starts and ends (normalized) + start_span = breaks[segment_start+1] - breaks[segment_start] + end_span = breaks[segment_end+1] - breaks[segment_end] + + start_offset = breaks[segment_start] + end_offset = breaks[segment_end] + + segment_normalized_start = (span_start - start_offset)/start_span + segment_normalized_end = (span_end - end_offset )/end_span + + # Find the scaling for those segments + U_scale = 1/(N + 2) + + # Used the normalized positions and the U_scaling to find the U location + U_start = U_scale*segment_normalized_start + (segment_start + 1) * U_scale + U_end = U_scale*segment_normalized_end + (segment_end + 1) * U_scale + + # Voila! + if 'UStart' == vsp.GetParmName(param_names[p_idx]): - vsp.SetParmVal(param_names[p_idx], (ctrl_surf.span_fraction_start*(n_segments-1)+1)/(n_segments+1)) + vsp.SetParmVal(param_names[p_idx], U_start) if 'UEnd' ==vsp.GetParmName(param_names[p_idx]): - vsp.SetParmVal(param_names[p_idx], (ctrl_surf.span_fraction_end*(n_segments-1)+1)/(n_segments+1)) + vsp.SetParmVal(param_names[p_idx], U_end) if 'Length_C_Start' == vsp.GetParmName(param_names[p_idx]): vsp.SetParmVal(param_names[p_idx], ctrl_surf.chord_fraction) if 'Length_C_End' == vsp.GetParmName(param_names[p_idx]): From 97e9b4d2ddd741ee7f69aafbc37eb549bb534ac5 Mon Sep 17 00:00:00 2001 From: planes Date: Tue, 29 Mar 2022 09:59:12 -0700 Subject: [PATCH 2/3] fixed CS reads --- trunk/SUAVE/Input_Output/OpenVSP/vsp_wing.py | 57 ++++++++++++++++---- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/trunk/SUAVE/Input_Output/OpenVSP/vsp_wing.py b/trunk/SUAVE/Input_Output/OpenVSP/vsp_wing.py index ab17962c88..dabdf0a21a 100644 --- a/trunk/SUAVE/Input_Output/OpenVSP/vsp_wing.py +++ b/trunk/SUAVE/Input_Output/OpenVSP/vsp_wing.py @@ -287,7 +287,7 @@ def read_vsp_wing(wing_id, units_type='SI', write_airfoil_file=True, use_scaling x_sec_1_taper_parm = vsp.GetXSecParm(x_sec_1,'Taper') x_sec_1_rc_parm = vsp.GetXSecParm(x_sec_1,'Root_Chord') x_sec_1_tc_parm = vsp.GetXSecParm(x_sec_1,'Tip_Chord') - x_sec_1_t_parm = vsp.GetXSecParm(x_sec_1,'ThickChord') + x_sec_1_t_parm = vsp.GetXSecParm(x_sec_1,'ThickChord') # Calcs sweep = vsp.GetParmVal(x_sec_1_sweep_parm) * Units.deg @@ -315,9 +315,25 @@ def read_vsp_wing(wing_id, units_type='SI', write_airfoil_file=True, use_scaling # check if control surface (sub surfaces) are defined tags = [] LE_flags = [] - span_fraction_starts = [] - span_fraction_ends = [] + U_starts = [] + U_ends = [] chord_fractions = [] + + # determine the number of segments and where the breaks are + if len(wing.Segments.keys())>0: + N = len(wing.Segments.keys())-1 + + # Do a for loop to find the location of breaks + breaks = [] + for seg in wing.Segments: + breaks.append(seg.percent_span_location) + + else: + N = 1 + # Location of breaks + breaks = [0.,1.] + + num_cs = vsp.GetNumSubSurf(wing_id) @@ -330,9 +346,9 @@ def read_vsp_wing(wing_id, units_type='SI', write_airfoil_file=True, use_scaling if 'LE_Flag' == vsp.GetParmName(param_names[p_idx]): LE_flags.append(vsp.GetParmVal(param_names[p_idx])) if 'UStart' == vsp.GetParmName(param_names[p_idx]): - span_fraction_starts.append(vsp.GetParmVal(param_names[p_idx])) + U_starts.append(vsp.GetParmVal(param_names[p_idx])) if 'UEnd' == vsp.GetParmName(param_names[p_idx]): - span_fraction_ends.append(vsp.GetParmVal(param_names[p_idx])) + U_ends.append(vsp.GetParmVal(param_names[p_idx])) if 'Length_C_Start' == vsp.GetParmName(param_names[p_idx]): chord_fractions.append(vsp.GetParmVal(param_names[p_idx])) @@ -340,7 +356,7 @@ def read_vsp_wing(wing_id, units_type='SI', write_airfoil_file=True, use_scaling for cs_idx in range(num_cs): aileron_present = False if num_cs > 1: - aileron_loc = np.argmax(np.array(span_fraction_starts)) + aileron_loc = np.argmax(np.array(U_starts)) if cs_idx == aileron_loc: aileron_present = True if LE_flags[cs_idx] == 1.0: @@ -354,8 +370,31 @@ def read_vsp_wing(wing_id, units_type='SI', write_airfoil_file=True, use_scaling else: CS = SUAVE.Components.Wings.Control_Surfaces.Flap() CS.tag = tags[cs_idx] - CS.span_fraction_start = np.maximum((span_fraction_starts[cs_idx] * (segment_num + 1) - 1) / (segment_num - 1), 0) - CS.span_fraction_end = np.minimum((span_fraction_ends[cs_idx] * (segment_num + 1) - 1) / (segment_num - 1), 1) + + # Do some math to get U into a span fraction + U_scale = 1/(N+2) # U scaling + + # Determine which segment the control surfaces begin and end, use floor + segment_start = int(np.floor(U_starts[cs_idx]/U_scale)) - 1 + segment_end = int(np.floor(U_ends[cs_idx]/U_scale)) - 1 + + segment_normalized_start = U_starts[cs_idx]/U_scale - (segment_start+1) + segment_normalized_end = U_ends[cs_idx]/U_scale - (segment_end+1) + + # calculate segment spans + start_span = breaks[segment_start+1] - breaks[segment_start] + end_span = breaks[segment_end+1] - breaks[segment_end] + + # Calculate the offsets + start_offset = breaks[segment_start] + end_offset = breaks[segment_end] + + # Calculate the end points + span_start = segment_normalized_start * start_span - start_offset + span_end = segment_normalized_end * end_span - end_offset + + CS.span_fraction_start = np.max([span_start, 0]) + CS.span_fraction_end = np.min([span_end,1]) if CS.span_fraction_start > 1 or CS.span_fraction_end < 0: raise AssertionError("SUAVE import of VSP files does not allow control surfaces defined for the wing caps.") @@ -729,7 +768,7 @@ def write_vsp_control_surface(wing,wing_id,ctrl_surf): end_span = breaks[segment_end+1] - breaks[segment_end] start_offset = breaks[segment_start] - end_offset = breaks[segment_end] + end_offset = breaks[segment_end] segment_normalized_start = (span_start - start_offset)/start_span segment_normalized_end = (span_end - end_offset )/end_span From 8d9ac7a3344c62d2604b70dbdcf8af75425ce604 Mon Sep 17 00:00:00 2001 From: planes Date: Wed, 30 Mar 2022 08:25:41 -0700 Subject: [PATCH 3/3] fliping signs on read --- trunk/SUAVE/Input_Output/OpenVSP/vsp_wing.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/trunk/SUAVE/Input_Output/OpenVSP/vsp_wing.py b/trunk/SUAVE/Input_Output/OpenVSP/vsp_wing.py index dabdf0a21a..1d06af93de 100644 --- a/trunk/SUAVE/Input_Output/OpenVSP/vsp_wing.py +++ b/trunk/SUAVE/Input_Output/OpenVSP/vsp_wing.py @@ -390,8 +390,8 @@ def read_vsp_wing(wing_id, units_type='SI', write_airfoil_file=True, use_scaling end_offset = breaks[segment_end] # Calculate the end points - span_start = segment_normalized_start * start_span - start_offset - span_end = segment_normalized_end * end_span - end_offset + span_start = segment_normalized_start * start_span + start_offset + span_end = segment_normalized_end * end_span + end_offset CS.span_fraction_start = np.max([span_start, 0]) CS.span_fraction_end = np.min([span_end,1])