示例#1
0
文件: test.py 项目: www2000/OpenVSP
vsp.SetXSecPnts(file_xsec_id, pnt_vec)

geoms = vsp.FindGeoms()

print("End of second use case, all geoms in Vehicle.")
print(geoms)

vsp.WriteVSPFile("apitest2.vsp3")

# ==== Use Case 3 ==== #

print("Start of third use case, read in first-case file.")

# ==== Read Geometry From File ==== #
vsp.VSPRenew()
errorMgr.PopErrorAndPrint(stdout)

vsp.ReadVSPFile(fname)

geoms = vsp.FindGeoms()

print("All geoms in Vehicle.")
print(geoms)

# Check for errors

num_err = errorMgr.GetNumTotalErrors()
for i in range(0, num_err):
    err = errorMgr.PopLastError()
    print("error = ", err.m_ErrorString)
示例#2
0
def write_vsp_mesh(geometry, tag, half_mesh_flag, growth_ratio,
                   growth_limiting_flag):
    """This create an .stl surface mesh based on a vehicle stored in a .vsp3 file.
    
    Assumptions:
    None

    Source:
    N/A

    Inputs:
    geometry.                                 - Also passed to set_sources
      wings.main_wing.chords.mean_aerodynamic [m]
    half_mesh_flag                            <boolean>  determines if a symmetry plane is created
    growth_ratio                              [-]        growth ratio for the mesh
    growth_limiting_flag                      <boolean>  determines if 3D growth limiting is used

    Outputs:
    <tag>.stl                               

    Properties Used:
    N/A
    """

    # Reset OpenVSP to avoid including a previous vehicle
    vsp.ClearVSPModel()

    # Turn on symmetry plane splitting to improve robustness of meshing process
    if half_mesh_flag == True:
        f = fileinput.input(tag + '.vsp3', inplace=1)
        for line in f:
            if 'SymmetrySplitting' in line:
                print line[0:34] + '1' + line[35:-1]
            else:
                print line

    vsp.ReadVSPFile(tag + '.vsp3')

    # Set output file types and what will be meshed
    file_type = vsp.CFD_STL_TYPE + vsp.CFD_KEY_TYPE
    set_int = vsp.SET_ALL

    vsp.SetComputationFileName(vsp.CFD_STL_TYPE, tag + '.stl')
    vsp.SetComputationFileName(vsp.CFD_KEY_TYPE, tag + '.key')

    # Set to create a tagged STL mesh file
    vehicle_cont = vsp.FindContainer('Vehicle', 0)
    STL_multi = vsp.FindParm(vehicle_cont, 'MultiSolid', 'STLSettings')
    vsp.SetParmVal(STL_multi, 1.0)

    vsp.SetCFDMeshVal(vsp.CFD_FAR_FIELD_FLAG, 1)
    if half_mesh_flag == True:
        vsp.SetCFDMeshVal(vsp.CFD_HALF_MESH_FLAG, 1)

    # Figure out the size of the bounding box
    vehicle_id = vsp.FindContainersWithName('Vehicle')[0]
    xlen = vsp.GetParmVal(vsp.FindParm(vehicle_id, "X_Len", "BBox"))
    ylen = vsp.GetParmVal(vsp.FindParm(vehicle_id, "Y_Len", "BBox"))
    zlen = vsp.GetParmVal(vsp.FindParm(vehicle_id, "Z_Len", "BBox"))

    # Max length
    max_len = np.max([xlen, ylen, zlen])
    far_length = 10. * max_len

    vsp.SetCFDMeshVal(vsp.CFD_FAR_SIZE_ABS_FLAG, 1)
    vsp.SetCFDMeshVal(vsp.CFD_FAR_LENGTH, far_length)
    vsp.SetCFDMeshVal(vsp.CFD_FAR_WIDTH, far_length)
    vsp.SetCFDMeshVal(vsp.CFD_FAR_HEIGHT, far_length)
    vsp.SetCFDMeshVal(vsp.CFD_FAR_MAX_EDGE_LEN, max_len)
    vsp.SetCFDMeshVal(vsp.CFD_GROWTH_RATIO, growth_ratio)
    if growth_limiting_flag == True:
        vsp.SetCFDMeshVal(vsp.CFD_LIMIT_GROWTH_FLAG, 1.0)

    # Set the max edge length so we have on average 50 elements per chord length
    MAC = geometry.wings.main_wing.chords.mean_aerodynamic
    min_len = MAC / 50.
    vsp.SetCFDMeshVal(vsp.CFD_MAX_EDGE_LEN, min_len)

    # vsp.AddDefaultSources()
    set_sources(geometry)

    vsp.Update()

    vsp.WriteVSPFile(tag + '_premesh.vsp3')

    print 'Starting mesh for ' + tag + ' (This may take several minutes)'
    ti = time.time()
    vsp.ComputeCFDMesh(set_int, file_type)
    tf = time.time()
    dt = tf - ti
    print 'VSP meshing for ' + tag + ' completed in ' + str(dt) + ' s'
def get_fuel_tank_properties(vehicle,
                             tag,
                             fuel_tank_set_index=3,
                             slices_for_calculation=100):
    """This function computes the center of gravity, total possible fuel mass,
    the available volume of each fuel tank in the vehicle through a mass
    properties computation in OpenVSP.
    
    Assumptions:
    Fuel tanks exists in the fuselage and wings only
    All fuel tanks have unique names

    Source:
    N/A

    Inputs:
    vehicle.fuselages.*.Fuel_Tanks.*.tag     [-]
    vehicle.wings.*.Fuel_Tanks.*.tag         [-]

    Outputs:    
    vehicle.fuselages.*.Fuel_Tanks.*.mass_properties.
      center_of_gravity                      [m]
      fuel_mass_when_full                    [kg]
      fuel_volume_when_full                  [m^3]
    vehicle.wings.*.Fuel_Tanks.*.mass_properties.
      center_of_gravity                      [m]
      fuel_mass_when_full                    [kg]
      fuel_volume_when_full                  [m^3]
      

    Properties Used:
    N/A
    """

    # Reset OpenVSP to avoid including a previous vehicle
    vsp.ClearVSPModel()
    vsp.ReadVSPFile(tag + '.vsp3')

    # Extract fuel tanks from vehicle
    fuel_tanks = get_fuel_tanks(vehicle)

    num_slices = slices_for_calculation  # Slices used to estimate mass distribution from areas in OpenVSP
    mass_props_output_file = tag + '_mass_props.txt'
    vsp.SetComputationFileName(vsp.MASS_PROP_TXT_TYPE, mass_props_output_file)
    print('Computing Fuel Tank Mass Properties... ')
    vsp.ComputeMassProps(fuel_tank_set_index, num_slices)
    print('Done')

    # Extract full tank mass properties from OpenVSP output file
    fo = open(mass_props_output_file)
    for line in fo:
        prop_list = line.split()
        try:
            if prop_list[0] in fuel_tanks:
                # Indices based on position in OpenVSP output (may change in the future)
                cg_x = float(prop_list[2])
                cg_y = float(prop_list[3])
                cg_z = float(prop_list[4])
                mass = float(prop_list[1])
                vol = float(prop_list[-1])
                if 'center_of_gravity' not in fuel_tanks[prop_list[
                        0]]:  # assumes at most two identical tank names
                    fuel_tanks[prop_list[0]].center_of_gravity = np.array(
                        [cg_x, cg_y, cg_z])
                    fuel_tanks[prop_list[0]].fuel_mass_when_full = mass
                    fuel_tanks[prop_list[0]].volume = vol
                else:
                    fuel_tanks[prop_list[0]].center_of_gravity = \
                        (fuel_tanks[prop_list[0]].center_of_gravity+np.array([cg_x,cg_y,cg_z]))/2.
                    fuel_tanks[prop_list[0]].fuel_mass_when_full += mass
                    fuel_tanks[prop_list[0]].volume += vol

        except IndexError:  # in case line is empty
            pass

    # Apply fuel tank properties to the vehicle
    vehicle = apply_properties(vehicle, fuel_tanks)

    return vehicle
示例#4
0
def vsp_read(tag, units_type='SI'): 	
	"""This reads an OpenVSP vehicle geometry and writes it into a SUAVE vehicle format.
	Includes wings, fuselages, and propellers.

	Assumptions:
	1. OpenVSP vehicle is composed of conventionally shaped fuselages, wings, and propellers. 
	1a. OpenVSP fuselage: generally narrow at nose and tail, wider in center). 
	1b. Fuselage is designed in VSP as it appears in real life. That is, the VSP model does not rely on
	   superficial elements such as canopies, stacks, or additional fuselages to cover up internal lofting oddities.
	1c. This program will NOT account for multiple geometries comprising the fuselage. For example: a wingbox mounted beneath
	   is a separate geometry and will NOT be processed.
	2. Fuselage origin is located at nose. VSP file origin can be located anywhere, preferably at the forward tip
	   of the vehicle or in front (to make all X-coordinates of vehicle positive).
	3. Written for OpenVSP 3.16.1
	
	Source:
	N/A

	Inputs:
	1. A tag for an XML file in format .vsp3.
	2. Units_type set to 'SI' (default) or 'Imperial'

	Outputs:
	Writes SUAVE vehicle with these geometries from VSP:    (All values default to SI. Any other 2nd argument outputs Imperial.)
		Wings.Wing.    (* is all keys)
			origin                                  [m] in all three dimensions
			spans.projected                         [m]
			chords.root                             [m]
			chords.tip                              [m]
			aspect_ratio                            [-]
			sweeps.quarter_chord                    [radians]
			twists.root                             [radians]
			twists.tip                              [radians]
			thickness_to_chord                      [-]
			dihedral                                [radians]
			symmetric                               <boolean>
			tag                                     <string>
			areas.exposed                           [m^2]
			areas.reference                         [m^2]
			areas.wetted                            [m^2]
			Segments.
			  tag                                   <string>
			  twist                                 [radians]
			  percent_span_location                 [-]  .1 is 10%
			  root_chord_percent                    [-]  .1 is 10%
			  dihedral_outboard                     [radians]
			  sweeps.quarter_chord                  [radians]
			  thickness_to_chord                    [-]
			  airfoil                               <NACA 4-series, 6 series, or airfoil file>
			
		Fuselages.Fuselage.			
			origin                                  [m] in all three dimensions
			width                                   [m]
			lengths.
			  total                                 [m]
			  nose                                  [m]
			  tail                                  [m]
			heights.
			  maximum                               [m]
			  at_quarter_length                     [m]
			  at_three_quarters_length              [m]
			effective_diameter                      [m]
			fineness.nose                           [-] ratio of nose section length to fuselage effective diameter
			fineness.tail                           [-] ratio of tail section length to fuselage effective diameter
			areas.wetted                            [m^2]
			tag                                     <string>
			segment[].   (segments are in ordered container and callable by number)
			  vsp.shape                               [point,circle,round_rect,general_fuse,fuse_file]
			  vsp.xsec_id                             <10 digit string>
			  percent_x_location
			  percent_z_location
			  height
			  width
			  length
			  effective_diameter
			  tag
			vsp.xsec_num                              <integer of fuselage segment quantity>
			vsp.xsec_surf_id                          <10 digit string>
	
		Propellers.Propeller.
			location[X,Y,Z]                            [radians]
			rotation[X,Y,Z]                            [radians]
			prop_attributes.tip_radius                 [m]
		        prop_attributes.hub_radius                 [m]
			thrust_angle                               [radians]
	
	Properties Used:
	N/A
	"""  	
	
	vsp.ClearVSPModel() 
	vsp.ReadVSPFile(tag)	
	
	vsp_fuselages = []
	vsp_wings     = []	
	vsp_props     = []
	
	vsp_geoms     = vsp.FindGeoms()
	geom_names    = []

	vehicle     = SUAVE.Vehicle()
	vehicle.tag = tag

	if units_type == 'SI':
		units_type = 'SI' 
	else:
		units_type = 'Imperial' 

	# The two for-loops below are in anticipation of an OpenVSP API update with a call for GETGEOMTYPE.
	# This print function allows user to enter VSP GeomID manually as first argument in vsp_read functions.
	
	print("VSP geometry IDs: ")	
	
	# Label each geom type by storing its VSP geom ID. (The API call for GETGEOMTYPE was not released as of 8/9/18, v 3.16.1)
	
	for geom in vsp_geoms: 
		geom_name = vsp.GetGeomName(geom)
		geom_names.append(geom_name)
		print(str(geom_name) + ': ' + geom)
	
	# -----------------------------
	# MANUAL VSP ENTRY & PROCESSING
	# -----------------------------		
	
	#fuselage = read_vsp_fuselage(fuselage_id, units_type=units_type) # Replace fuselage_id manually.
	#vehicle.append_component(fuselage)
	
	#wing = read_vsp_wing(wing_id, units_type=units_type)		# Replace wing_id manually.
	#vehicle.append_component(wing)		
	
	#prop = read_vsp_prop(prop_id, units_type=units_type)		# Replace prop_id manually.	
	#vehicle.append_component(prop)
	

	# --------------------------------
	# AUTOMATIC VSP ENTRY & PROCESSING
	# --------------------------------		
		
	#for geom in vsp_geoms:
		#if vsp.GETGEOMTYPE(str(geom)) == 'FUSELAGE':
			#vsp_fuselages.append(geom)
		#if vsp.GETGEOMTYPE(str(geom)) == 'WING':
			#vsp_wings.append(geom)
		#if vsp.GETGEOMTYPE(str(geom)) == 'PROP':
			#vsp_props.append(geom)
	
	# Read VSP geoms and store in SUAVE components.
	
	#for vsp_fuselage in vsp_fuselages:
		#fuselage_id = vsp_fuselages[vsp_fuselage]
		#fuselage = read_vsp_fuselage(fuselage_id, units_type)
		#vehicle.append_component(fuselage)
	
	#for vsp_wing in vsp_wings:
		#wing_id = vsp_wings[vsp_wing]
		#wing = read_vsp_wing(wing_id, units_type)
		#vehicle.append_component(wing)		
	
	#for vsp_prop in vsp_props:
		#prop_id = vsp_props[vsp_prop]
		#prop = read_vsp_prop(prop_id, units_type)		
		#vehicle.append_component(prop)
	
	return vehicle