Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AVL/OpenVSP Matching #189

Merged
merged 7 commits into from Jul 31, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
51 changes: 43 additions & 8 deletions trunk/SUAVE/Input_Output/OpenVSP/vsp_write.py
Expand Up @@ -2,6 +2,7 @@
#
# Created: Jul 2016, T. MacDonald
# Modified: Jun 2017, T. MacDonald
# Jul 2017, T. MacDonald

# ----------------------------------------------------------------------
# Imports
Expand Down Expand Up @@ -93,9 +94,20 @@ def write(vehicle,tag):
vsp.SetParmVal( wing_id,'Sweep_Location',x_secs[1],sweep_loc)

# Twists
vsp.SetParmVal( wing_id,'Twist',x_secs[0],tip_twist) # tip
vsp.SetParmVal( wing_id,'Twist',x_secs[0],root_twist) # root

if n_segments != 0:
if wing.Segments[0].percent_span_location == 0.:
vsp.SetParmVal( wing_id,'Twist',x_secs[0],wing.Segments[0].twist / Units.deg) # root
else:
vsp.SetParmVal( wing_id,'Twist',x_secs[0],root_twist) # root
if wing.Segments[-1].percent_span_location == 1.:
vsp.SetParmVal( wing_id,'Twist',x_secs[-2],wing.Segments[0].twist / Units.deg) # root
else:
vsp.SetParmVal( wing_id,'Twist',x_secs[-2],tip_twist) # root
else:
vsp.SetParmVal( wing_id,'Twist',x_secs[0],root_twist) # root
vsp.SetParmVal( wing_id,'Twist',x_secs[0],tip_twist) # tip


# Figure out if there is an airfoil provided

# Airfoils should be in Lednicer format
Expand Down Expand Up @@ -174,15 +186,24 @@ def write(vehicle,tag):
adjust = 1
else:
adjust = 1


# Loop for the number of segments left over
for i_segs in xrange(1,n_segments+1):
for i_segs in xrange(1,n_segments+1):

if (wing.Segments[i_segs-1] == wing.Segments[-1]) and (wing.Segments[-1].percent_span_location == 1.):
break

# Unpack
dihedral_i = wing.Segments[i_segs-1].dihedral_outboard / Units.deg
chord_i = root_chord*wing.Segments[i_segs-1].root_chord_percent
twist_i = wing.Segments[i_segs-1].twist / Units.deg
try:
twist_i = wing.Segments[i_segs].twist / Units.deg
no_twist_flag = False
except:
no_twist_flag = True
sweep_i = wing.Segments[i_segs-1].sweeps.quarter_chord / Units.deg
tc_i = wing.Segments[i_segs-1].thickness_to_chord

# Calculate the local span
if i_segs == n_segments:
Expand All @@ -205,12 +226,26 @@ def write(vehicle,tag):
vsp.SetParmVal( wing_id,'Sweep',x_secs[i_segs+adjust],sweep_i)
vsp.SetParmVal( wing_id,'Sweep_Location',x_secs[i_segs+adjust],sweep_loc)
vsp.SetParmVal( wing_id,'Root_Chord',x_secs[i_segs+adjust],chord_i)
vsp.SetParmVal( wing_id,'Twist',x_secs[i_segs+adjust],twist_i)
vsp.SetParmVal( wing_id,'ThickChord',x_sec_curves[i_segs+adjust],tip_tc)
if not no_twist_flag:
vsp.SetParmVal( wing_id,'Twist',x_secs[i_segs+adjust],twist_i)
vsp.SetParmVal( wing_id,'ThickChord',x_sec_curves[i_segs+adjust],tc_i)

if adjust and (i_segs == 1):
vsp.Update()
vsp.SetParmVal( wing_id,'Twist',x_secs[1],wing.Segments[i_segs-1].twist / Units.deg)

vsp.Update()

vsp.SetParmVal( wing_id,'Tip_Chord',x_secs[-1-(1-adjust)],tip_chord)
if (n_segments != 0) and (wing.Segments[-1].percent_span_location == 1.):
tip_chord = root_chord*wing.Segments[-1].root_chord_percent
vsp.SetParmVal( wing_id,'Tip_Chord',x_secs[n_segments-1+adjust],tip_chord)
vsp.SetParmVal( wing_id,'ThickChord',x_secs[n_segments-1+adjust],wing.Segments[-1].thickness_to_chord)
# twist is set in the normal loop
else:
vsp.SetParmVal( wing_id,'Tip_Chord',x_secs[-1-(1-adjust)],tip_chord)
vsp.SetParmVal( wing_id,'Twist',x_secs[-1-(1-adjust)],tip_twist)
# a single trapezoidal wing is assumed to have constant thickness to chord
vsp.Update()
vsp.SetParmVal(wing_id,'CapUMaxOption','EndCap',2.)
vsp.SetParmVal(wing_id,'CapUMaxStrength','EndCap',1.)

Expand Down
38 changes: 25 additions & 13 deletions trunk/SUAVE/Methods/Aerodynamics/AVL/create_avl_datastructure.py
Expand Up @@ -3,6 +3,7 @@
# Created: Oct 2014, T. Momose
# Modified: Jan 2016, E. Botero
# Apr 2017, M. Clarke
# Jul 2017, T. MacDonald

# ----------------------------------------------------------------------
# Imports
Expand Down Expand Up @@ -92,19 +93,25 @@ def populate_wing_sections(avl_wing,suave_wing):
# obtain the geometry for each segment in a loop
for i_segs in xrange(n_segments):
# convert quarter chord sweeps to leading edge sweeps
dihedral = suave_wing.Segments[i_segs].dihedral_outboard
if (i_segs == n_segments-1):
sweep = 0
else:
if suave_wing.Segments[i_segs].sweeps.leading_edge > 0:
sweep = suave_wing.Segments[i_segs].sweeps.leading_edge
segment_span = semispan*(suave_wing.Segments[i_segs+1].percent_span_location - suave_wing.Segments[i_segs].percent_span_location )
span_no_dihedral = segment_span/np.cos(dihedral)
else:
sweep_quarter_chord = suave_wing.Segments[i_segs].sweeps.quarter_chord
chord_fraction = 0.25 # quarter chord
segment_root_chord = root_chord*suave_wing.Segments[i_segs].root_chord_percent
segment_tip_chord = root_chord*suave_wing.Segments[i_segs+1].root_chord_percent
segment_span = semispan*(suave_wing.Segments[i_segs+1].percent_span_location - suave_wing.Segments[i_segs].percent_span_location )
sweep = np.arctan(((segment_root_chord*chord_fraction) + (np.tan(sweep_quarter_chord )*segment_span - chord_fraction*segment_tip_chord)) /segment_span)
dihedral = suave_wing.Segments[i_segs].dihedral_outboard
span_no_dihedral = segment_span/np.cos(dihedral)
dx_quarter = span_no_dihedral*np.tan(sweep_quarter_chord) + segment_root_chord/4.
dx_leading_edge = dx_quarter - segment_tip_chord/4.
sweep = np.arctan(dx_leading_edge/span_no_dihedral)

section = Section()
section.tag = suave_wing.Segments[i_segs].tag
section.chord = root_chord*suave_wing.Segments[i_segs].root_chord_percent
Expand All @@ -125,23 +132,21 @@ def populate_wing_sections(avl_wing,suave_wing):

dz = semispan*segment_percent_span
dy = dz*np.tan(dihedral)
l = dz/np.cos(dihedral)
dx = l*np.tan(sweep)
dx = span_no_dihedral*np.tan(sweep)
origin.append( [origin[i_segs][0] + dx , origin[i_segs][1] + dy, origin[i_segs][2] + dz])
else:

dy = semispan*segment_percent_span
dz = dy*np.tan(dihedral)
l = dy/np.cos(dihedral)
dx = l*np.tan(sweep)
dx = span_no_dihedral*np.tan(sweep)
origin.append( [origin[i_segs][0] + dx , origin[i_segs][1] + dy, origin[i_segs][2] + dz])
else:
symm = avl_wing.symmetric
sweep = suave_wing.sweeps.quarter_chord
dihedral = suave_wing.dihedral
span = suave_wing.spans.projected
semispan = suave_wing.spans.projected * 0.5 * (2 - symm)
origin = suave_wing.origin
symm = avl_wing.symmetric
sweep_quarter_chord = suave_wing.sweeps.quarter_chord
dihedral = suave_wing.dihedral
span = suave_wing.spans.projected
semispan = suave_wing.spans.projected * 0.5 * (2 - symm)
origin = suave_wing.origin

root_section = Section()
root_section.tag = 'root_section'
Expand All @@ -153,7 +158,14 @@ def populate_wing_sections(avl_wing,suave_wing):
tip_section.tag = 'tip_section'
tip_section.chord = suave_wing.chords.tip
tip_section.twist = suave_wing.twists.tip
tip_section.origin = [origin[0]+semispan*np.tan(sweep),origin[1]+semispan,origin[2]+semispan*np.tan(dihedral)]

semispan_no_dihedral = semispan/np.cos(dihedral)
dx_quarter = semispan_no_dihedral*np.tan(sweep_quarter_chord) + root_section.chord/4.
dx_leading_edge = dx_quarter - tip_section.chord/4.
sweep = np.arctan(dx_leading_edge/semispan_no_dihedral)
dx = semispan_no_dihedral*np.tan(sweep)

tip_section.origin = [origin[0]+dx, origin[1]+semispan, origin[2]+semispan*np.tan(dihedral)]

if avl_wing.vertical:
temp = tip_section.origin[2]
Expand Down