Skip to content

Commit

Permalink
Merge pull request #561 from suavecode/fix-vtk_updates
Browse files Browse the repository at this point in the history
Fix plot updates
  • Loading branch information
rachealerhard authored Mar 8, 2022
2 parents 363aafe + 4e96d51 commit 901edf3
Show file tree
Hide file tree
Showing 9 changed files with 371 additions and 510 deletions.
20 changes: 10 additions & 10 deletions regression/scripts/slipstream/slipstream_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,13 @@ def regress_1a(results, configs):
sectional_lift_coeff = results.segments.cruise.conditions.aerodynamics.lift_breakdown.inviscid_wings_sectional[0]

# lift coefficient and sectional lift coefficient check
lift_coefficient_true = 0.43768245404117523
lift_coefficient_true = 0.4376824540411817
sectional_lift_coeff_true = np.array([ 4.41918141e-01, 3.93826079e-01, 3.57544475e-01, 3.00916953e-01,
5.79957579e-02, 4.41918156e-01, 3.93826087e-01, 3.57544519e-01,
3.00917150e-01, 5.79957818e-02, -7.86775230e-02, -7.55998225e-02,
-6.69811421e-02, -5.08736530e-02, -3.04987429e-02, -7.86775380e-02,
-7.55998465e-02, -6.69811824e-02, -5.08737077e-02, -3.04987532e-02,
-1.97703006e-15, -7.67234643e-16, -5.67115098e-16, -4.37274420e-16,
-1.97703006e-15, -7.67234643e-16, -5.67115097e-16, -4.37274419e-16,
-2.80981158e-16])

diff_CL = np.abs(lift_coefficient - lift_coefficient_true)
Expand All @@ -117,14 +117,14 @@ def regress_1b(results, configs):
sectional_lift_coeff = results.segments.cruise.conditions.aerodynamics.lift_breakdown.inviscid_wings_sectional[0]

# lift coefficient and sectional lift coefficient check
lift_coefficient_true = 0.4375681814886325
sectional_lift_coeff_true = np.array([ 4.39186743e-01, 3.55022830e-01, 3.51363002e-01, 3.03463863e-01,
5.83427225e-02, 4.49490617e-01, 4.03740726e-01, 3.68481887e-01,
3.11492900e-01, 6.01164743e-02, -6.61621250e-02, -6.28443495e-02,
-5.56118594e-02, -4.13996846e-02, -2.44318893e-02, -7.41588710e-02,
-7.19859998e-02, -6.32091207e-02, -4.77136327e-02, -2.85404276e-02,
5.13437911e-07, 2.71732702e-09, 2.85037078e-09, 6.96361700e-09,
4.19821840e-09])
lift_coefficient_true = 0.4375488183038649
sectional_lift_coeff_true = np.array([ 4.40783757e-01, 3.58418562e-01, 3.53731760e-01, 3.05377937e-01,
5.87221694e-02, 4.49249431e-01, 3.95108678e-01, 3.67248531e-01,
3.11383276e-01, 5.98984459e-02, -6.58338027e-02, -6.26213368e-02,
-5.53134061e-02, -4.11543787e-02, -2.42887821e-02, -7.24163428e-02,
-7.02015173e-02, -6.15927784e-02, -4.62903782e-02, -2.76006293e-02,
3.50584012e-07, 1.98446996e-09, 1.57066442e-09, 4.03406510e-09,
2.45046628e-09])

diff_CL = np.abs(lift_coefficient - lift_coefficient_true)
print('CL difference')
Expand Down
210 changes: 105 additions & 105 deletions trunk/SUAVE/Input_Output/OpenVSP/vsp_wing.py

Large diffs are not rendered by default.

89 changes: 2 additions & 87 deletions trunk/SUAVE/Input_Output/VTK/save_nacelle_vtk.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
from SUAVE.Input_Output.VTK.write_azimuthal_cell_values import write_azimuthal_cell_values
import numpy as np

from SUAVE.Plots.Geometry.plot_vehicle import generate_nacelle_points


#------------------------------
# Nacelle VTK generation
Expand Down Expand Up @@ -49,93 +51,6 @@ def save_nacelle_vtk(nacelle, filename, Results):

return

## @ingroup Input_Output-VTK
def generate_nacelle_points(nac,tessellation = 24):
""" This generates the coordinate points on the surface of the nacelle
Assumptions:
None
Source:
None
Inputs:
nac - nacelle
Properties Used:
N/A
"""


num_nac_segs = len(nac.Segments.keys())
theta = np.linspace(0,2*np.pi,tessellation)
n_points = 20

if num_nac_segs == 0:
num_nac_segs = int(n_points/2)
nac_pts = np.zeros((num_nac_segs,tessellation,3))
naf = nac.Airfoil

if naf.naca_4_series_airfoil != None:
# use mean camber surface of airfoil
camber = float(naf.naca_4_series_airfoil[0])/100
camber_loc = float(naf.naca_4_series_airfoil[1])/10
thickness = float(naf.naca_4_series_airfoil[2:])/100
airfoil_data = compute_naca_4series(camber, camber_loc, thickness,(n_points - 2))
xpts = np.repeat(np.atleast_2d(airfoil_data.x_lower_surface).T,tessellation,axis = 1)*nac.length
zpts = np.repeat(np.atleast_2d(airfoil_data.camber_coordinates[0]).T,tessellation,axis = 1)*nac.length

elif naf.coordinate_file != None:
a_sec = naf.coordinate_file
a_secl = [0]
airfoil_data = import_airfoil_geometry(a_sec,npoints=num_nac_segs)
xpts = np.repeat(np.atleast_2d(np.take(airfoil_data.x_coordinates,a_secl,axis=0)).T,tessellation,axis = 1)*nac.length
zpts = np.repeat(np.atleast_2d(np.take(airfoil_data.y_coordinates,a_secl,axis=0)).T,tessellation,axis = 1)*nac.length

else:
# if no airfoil defined, use super ellipse as default
a = nac.length/2
b = (nac.diameter - nac.inlet_diameter)/2
b = np.maximum(b,1E-3) # ensure
xpts = np.repeat(np.atleast_2d(np.linspace(-a,a,num_nac_segs)).T,tessellation,axis = 1)
zpts = (np.sqrt((b**2)*(1 - (xpts**2)/(a**2) )))*nac.length
xpts = (xpts+a)*nac.length

if nac.flow_through:
zpts = zpts + nac.inlet_diameter/2

# create geometry
theta_2d = np.repeat(np.atleast_2d(theta),num_nac_segs,axis =0)
nac_pts[:,:,0] = xpts
nac_pts[:,:,1] = zpts*np.cos(theta_2d)
nac_pts[:,:,2] = zpts*np.sin(theta_2d)

else:
nac_pts = np.zeros((num_nac_segs,tessellation,3))
for i_seg in range(num_nac_segs):
a = nac.Segments[i_seg].width/2
b = nac.Segments[i_seg].height/2
r = np.sqrt((b*np.sin(theta))**2 + (a*np.cos(theta))**2)
nac_ypts = r*np.cos(theta)
nac_zpts = r*np.sin(theta)
nac_pts[i_seg,:,0] = nac.Segments[i_seg].percent_x_location*nac.length
nac_pts[i_seg,:,1] = nac_ypts + nac.Segments[i_seg].percent_y_location*nac.length
nac_pts[i_seg,:,2] = nac_zpts + nac.Segments[i_seg].percent_z_location*nac.length

# rotation about y to orient propeller/rotor to thrust angle
rot_trans = nac.nac_vel_to_body()
rot_trans = np.repeat( np.repeat(rot_trans[ np.newaxis,:,: ],tessellation,axis=0)[ np.newaxis,:,:,: ],num_nac_segs,axis=0)

NAC_PTS = np.matmul(rot_trans,nac_pts[...,None]).squeeze()

# translate to body
NAC_PTS[:,:,0] = NAC_PTS[:,:,0] + nac.origin[0][0]
NAC_PTS[:,:,1] = NAC_PTS[:,:,1] + nac.origin[0][1]
NAC_PTS[:,:,2] = NAC_PTS[:,:,2] + nac.origin[0][2]
return NAC_PTS




#------------------------------
# Writing nacelle data
Expand Down
124 changes: 12 additions & 112 deletions trunk/SUAVE/Input_Output/VTK/save_prop_vtk.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
#----------------------------------
# Imports
#----------------------------------
from SUAVE.Methods.Geometry.Two_Dimensional.Cross_Section.Airfoil.import_airfoil_geometry import import_airfoil_geometry
from SUAVE.Methods.Geometry.Two_Dimensional.Cross_Section.Airfoil.compute_naca_4series import compute_naca_4series
from SUAVE.Input_Output.VTK.write_azimuthal_cell_values import write_azimuthal_cell_values
from SUAVE.Core import Data
import numpy as np
import copy

from SUAVE.Plots.Geometry.plot_vehicle import get_blade_coordinates

## @ingroup Input_Output-VTK
def save_prop_vtk(prop, filename, Results, time_step):
"""
Expand Down Expand Up @@ -66,8 +66,8 @@ def save_prop_vtk(prop, filename, Results, time_step):
except:
# No lofted geometry has been saved yet, create it
Gprops = generate_lofted_propeller_points(prop)
n_af = Gprops.n_af
wake=False
n_af = prop.vtk_airfoil_points
wake = False


for B_idx in range(n_blades):
Expand Down Expand Up @@ -317,120 +317,20 @@ def generate_lofted_propeller_points(prop):
None
"""
num_B = prop.number_of_blades
a_sec = prop.airfoil_geometry
a_secl = prop.airfoil_polar_stations
beta = prop.twist_distribution
b = prop.chord_distribution
r = prop.radius_distribution
t = prop.max_thickness_distribution
origin = prop.origin
# unpack
num_B = prop.number_of_blades
n_points = prop.vtk_airfoil_points
dim = len(prop.radius_distribution)

# Initialize data structure for propellers
Gprops = Data()

if prop.rotation==1:
# negative chord and twist to give opposite rotation direction
b = -b
beta = -beta

try:
a_o = prop.start_angle[0]
except:
a_o = prop.start_angle

n_r = len(b) # number radial points
n_a_loft = prop.vtk_airfoil_points # number points around airfoil
theta = np.linspace(0,2*np.pi,num_B+1)[:-1] # azimuthal stations

# create empty data structure for storing propeller geometries
G = Data()
Gprops = Data()
Gprops.n_af = n_a_loft

flip_1 = (np.pi/2)
flip_2 = (np.pi/2)

b_2d = np.repeat(np.atleast_2d(b).T ,n_a_loft,axis=1)
t_2d = np.repeat(np.atleast_2d(t).T ,n_a_loft,axis=1)
r_2d = np.repeat(np.atleast_2d(r).T ,n_a_loft,axis=1)

for i in range(num_B):
Gprops[i] = Data()
# get airfoil coordinate geometry
if a_sec != None:
airfoil_data = import_airfoil_geometry(a_sec,npoints=n_a_loft)

xpts = np.take(airfoil_data.x_coordinates,a_secl,axis=0)
zpts = np.take(airfoil_data.y_coordinates,a_secl,axis=0)
max_t = np.take(airfoil_data.thickness_to_chord,a_secl,axis=0)

else:
camber = 0.02
camber_loc = 0.4
thickness = 0.10
airfoil_data = compute_naca_4series(camber, camber_loc, thickness,(n_a_loft - 2))
xpts = np.repeat(np.atleast_2d(airfoil_data.x_coordinates) ,n_r,axis=0)
zpts = np.repeat(np.atleast_2d(airfoil_data.y_coordinates) ,n_r,axis=0)
max_t = np.repeat(airfoil_data.thickness_to_chord,n_r,axis=0)

# store points of airfoil in similar format as Vortex Points (i.e. in vertices)
max_t2d = np.repeat(np.atleast_2d(max_t).T ,n_a_loft,axis=1)

airfoil_le_offset = ( - np.repeat(b[:,None], n_a_loft, axis=1)/2 ) # no sweep
xp = (xpts*b_2d + airfoil_le_offset) # x coord of airfoil
yp = r_2d*np.ones_like(xp) # radial location
zp = zpts*(t_2d/max_t2d) # former airfoil y coord

matrix = np.zeros((n_r,n_a_loft,3)) # radial location, airfoil pts (same y)
matrix[:,:,0] = xp
matrix[:,:,1] = yp
matrix[:,:,2] = zp


# ROTATION MATRICES FOR INNER SECTION
# rotation about y axis to create twist and position blade upright
trans_1 = np.zeros((n_r,3,3))
trans_1[:,0,0] = np.cos(flip_1 - beta)
trans_1[:,0,2] = -np.sin(flip_1 - beta)
trans_1[:,1,1] = 1
trans_1[:,2,0] = np.sin(flip_1 - beta)
trans_1[:,2,2] = np.cos(flip_1 - beta)

# rotation about x axis to create azimuth locations
trans_2 = np.array([[1 , 0 , 0],
[0 , np.cos(theta[i] + a_o + flip_2 ), -np.sin(theta[i] + a_o + flip_2)],
[0,np.sin(theta[i] + a_o + flip_2), np.cos(theta[i] + a_o + flip_2)] ])
trans_2 = np.repeat(trans_2[ np.newaxis,:,: ],n_r,axis=0)


trans = np.matmul(trans_2,trans_1)
rot_mat = np.repeat(trans[:, np.newaxis,:,:],n_a_loft,axis=1)

# ---------------------------------------------------------------------------------------------
# ROTATE POINTS
mat = np.matmul(rot_mat,matrix[...,None]).squeeze()

# ---------------------------------------------------------------------------------------------
# store node points
G.X = mat[:,:,0] + origin[0][0]
G.Y = mat[:,:,1] + origin[0][1]
G.Z = mat[:,:,2] + origin[0][2]

# store cell points
G.XA1 = mat[:-1,:-1,0] + origin[0][0]
G.YA1 = mat[:-1,:-1,1] + origin[0][1]
G.ZA1 = mat[:-1,:-1,2] + origin[0][2]
G.XA2 = mat[:-1,1:,0] + origin[0][0]
G.YA2 = mat[:-1,1:,1] + origin[0][1]
G.ZA2 = mat[:-1,1:,2] + origin[0][2]

G.XB1 = mat[1:,:-1,0] + origin[0][0]
G.YB1 = mat[1:,:-1,1] + origin[0][1]
G.ZB1 = mat[1:,:-1,2] + origin[0][2]
G.XB2 = mat[1:,1:,0] + origin[0][0]
G.YB2 = mat[1:,1:,1] + origin[0][1]
G.ZB2 = mat[1:,1:,2] + origin[0][2]
G = get_blade_coordinates(prop,n_points,dim,i)

# Store G for this blade:
Gprops[i] = copy.deepcopy(G)


return Gprops
5 changes: 5 additions & 0 deletions trunk/SUAVE/Input_Output/VTK/save_vehicle_vtk.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

from SUAVE.Core import Data
import numpy as np
import os

## @ingroup Input_Output-VTK
def save_vehicle_vtks(vehicle, conditions=None, Results=Data(), time_step=0,VLM_settings=None, prop_filename="propeller.vtk", rot_filename="rotor.vtk",
Expand Down Expand Up @@ -53,6 +54,10 @@ def save_vehicle_vtks(vehicle, conditions=None, Results=Data(), time_step=0,VLM_
None
"""
if (save_loc is not None) and (not os.path.exists(save_loc)):
os.makedirs(save_loc)
print("Directory "+save_loc+" created.")

if VLM_settings == None:
VLM_settings = Vortex_Lattice().settings
VLM_settings.number_spanwise_vortices = 25
Expand Down
Loading

0 comments on commit 901edf3

Please sign in to comment.