def simple_sizing(nexus): configs = nexus.vehicle_configurations HT_volume = 1.15948 * Units.less # ATR-72 VT_volume = 0.094316 * Units.less # ATR-72 lht = 13.8654 * Units.m lvt = 10.5724 * Units.m for config in configs: wing_planform(config.wings.main_wing) config.wings.horizontal_stabilizer.areas.reference = ( HT_volume / lht) * (config.wings.main_wing.areas.reference * config.wings.main_wing.chords.mean_aerodynamic) config.wings.vertical_stabilizer.areas.reference = ( VT_volume / lvt) * (config.wings.main_wing.areas.reference * config.wings.main_wing.spans.projected) SUAVE.Methods.Geometry.Two_Dimensional.Planform.wing_fuel_volume( config.wings.main_wing) nexus.summary.available_fuel = config.wings.main_wing.fuel_volume * 803.0 - 3200.03305635 for wing in config.wings: wing_planform(wing) wing.areas.wetted = 2.0 * wing.areas.reference wing.areas.exposed = 0.8 * wing.areas.wetted wing.areas.affected = 0.6 * wing.areas.wetted return nexus
def main_wing_planform(Wing): """ err = SUAVE.Methods.Geometry.main_wing_planform(Wing) main wing planform Assumptions: cranked wing with leading and trailing edge extensions Inputs: Wing.sref Wing.ar Wing.taper Wing.sweep Wing.span Wing.lex Wing.tex Wing.span_chordext Outputs: Wing.chord_root Wing.chord_tip Wing.chord_mid Wing.chord_mac Wing.area_wetted Wing.span """ # unpack span = Wing.span lex = Wing.lex tex = Wing.tex span_chordext = Wing.span_chordext # run basic wing planform # mac assumed on trapezoidal reference wing err = wing_planform(Wing) # unpack more chord_root = Wing.chord_root chord_tip = Wing.chord_tip # calculate chord_mid = chord_root + span_chordext * (chord_tip - chord_root) swet = 2 * span / 2 * (span_chordext * (chord_root + lex + tex + chord_mid) + (1 - span_chordext) * (chord_mid + chord_tip)) # update Wing.chord_mid = chord_mid Wing.swet = swet return 0
def main_wing_planform(Wing): """ err = SUAVE.Methods.Geometry.main_wing_planform(Wing) main wing planform Assumptions: cranked wing with leading and trailing edge extensions Inputs: Wing.sref Wing.ar Wing.taper Wing.sweep Wing.span Wing.lex Wing.tex Wing.span_chordext Outputs: Wing.chord_root Wing.chord_tip Wing.chord_mid Wing.chord_mac Wing.area_wetted Wing.span """ # unpack span = Wing.span lex = Wing.lex tex = Wing.tex span_chordext = Wing.span_chordext # run basic wing planform # mac assumed on trapezoidal reference wing err = wing_planform(Wing) # unpack more chord_root = Wing.chord_root chord_tip = Wing.chord_tip # calculate chord_mid = chord_root + span_chordext*(chord_tip-chord_root) swet = 2*span/2*(span_chordext*(chord_root+lex+tex + chord_mid) + (1-span_chordext)*(chord_mid+chord_tip)) # update Wing.chord_mid = chord_mid Wing.swet = swet return 0
def simple_sizing(nexus): configs = nexus.vehicle_configurations #find conditions air_speed = nexus.missions.base.segments['cruise'].air_speed altitude = nexus.missions.base.segments['climb_5'].altitude_end atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976() freestream = atmosphere.compute_values(altitude) #now size engine mach_number = air_speed/freestream.speed_of_sound #now add to freestream data object freestream.velocity = air_speed freestream.mach_number = mach_number freestream.gravity = 9.81 conditions = SUAVE.Analyses.Mission.Segments.Conditions.Aerodynamics() #assign conditions in form for propulsor sizing conditions.freestream = freestream HT_volume = 1.42542 * Units.less # E170 VT_volume = 0.11458 * Units.less # E170 lht = 14.24 * Units.m lvt = 13.54 * Units.m for config in configs: wing_planform(config.wings.main_wing) config.wings.horizontal_stabilizer.areas.reference = (HT_volume/lht)*(config.wings.main_wing.areas.reference * 3.194) config.wings.vertical_stabilizer.areas.reference = (VT_volume/lvt)*(config.wings.main_wing.areas.reference * 26.0) SUAVE.Methods.Geometry.Two_Dimensional.Planform.wing_fuel_volume(config.wings.main_wing) nexus.summary.available_fuel = config.wings.main_wing.fuel_volume * 803.0 * 1.0197 for wing in config.wings: wing_planform(wing) wing.areas.wetted = 2.0 * wing.areas.reference wing.areas.exposed = 0.8 * wing.areas.wetted wing.areas.affected = 0.6 * wing.areas.wetted turbofan_sizing(config.propulsors['turbofan'], mach_number=mach_number, altitude=altitude) compute_turbofan_geometry(config.propulsors['turbofan'], conditions) config.propulsors['turbofan'].nacelle_diameter = config.propulsors['turbofan'].nacelle_diameter * 1.1462135 config.propulsors['turbofan'].engine_length = config.propulsors['turbofan'].engine_length * 1.24868 config.propulsors['turbofan'].areas.wetted = 1.1*np.pi * (config.propulsors['turbofan'].engine_length * config.propulsors['turbofan'].nacelle_diameter) # ------------------------------------------------------------------ # Landing Configuration # ------------------------------------------------------------------ landing = nexus.vehicle_configurations.landing landing_conditions = Data() landing_conditions.freestream = Data() # landing weight landing.mass_properties.landing = 0.863 * config.mass_properties.takeoff # Landing CL_max altitude = nexus.missions.base.segments[-1].altitude_end atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976() freestream_landing = atmosphere.compute_values(altitude) landing_conditions.freestream.velocity = nexus.missions.base.segments['descent_3'].air_speed landing_conditions.freestream.density = freestream_landing.density landing_conditions.freestream.dynamic_viscosity = freestream_landing.dynamic_viscosity CL_max_landing,CDi = compute_max_lift_coeff(landing, landing_conditions) landing.maximum_lift_coefficient = CL_max_landing #Takeoff CL_max takeoff = nexus.vehicle_configurations.takeoff takeoff_conditions = Data() takeoff_conditions.freestream = Data() altitude = nexus.missions.base.airport.altitude freestream_takeoff = atmosphere.compute_values(altitude) takeoff_conditions.freestream.velocity = nexus.missions.base.segments.climb_1.air_speed takeoff_conditions.freestream.density = freestream_takeoff.density takeoff_conditions.freestream.dynamic_viscosity = freestream_takeoff.dynamic_viscosity max_CL_takeoff, CDi = compute_max_lift_coeff(takeoff, takeoff_conditions) takeoff.maximum_lift_coefficient = max_CL_takeoff #Base config CL_max base = nexus.vehicle_configurations.base base_conditions = Data() base_conditions.freestream = takeoff_conditions.freestream max_CL_base, CDi = compute_max_lift_coeff(base, base_conditions) base.maximum_lift_coefficient = max_CL_base return nexus
def vehicle_setup(): # ------------------------------------------------------------------ # Initialize the Vehicle # ------------------------------------------------------------------ vehicle = SUAVE.Vehicle() vehicle.tag = 'ATR72' # ------------------------------------------------------------------ # Vehicle-level Properties # ------------------------------------------------------------------ # mass properties vehicle.mass_properties.max_takeoff = 23000. * Units.kg vehicle.mass_properties.operating_empty = 13500. * Units.kg vehicle.mass_properties.takeoff = 23000. * Units.kg # 21700 vehicle.mass_properties.max_zero_fuel = 20800. * Units.kg vehicle.mass_properties.cargo = 0.0 * Units.kg vehicle.mass_properties.max_payload = 7500.0 * Units.kg vehicle.mass_properties.max_fuel = 5000.0 * Units.kg vehicle.mass_properties.center_of_gravity = [11.760, 0., 0.] # envelope properties vehicle.envelope.ultimate_load = 2.5 * 1.5 vehicle.envelope.limit_load = 2.5 vehicle.maximum_mach_operational = 0.55 # basic parameters vehicle.reference_area = 61 * Units['meters**2'] vehicle.passengers = 70 vehicle.systems.control = "aerodynamic powered" vehicle.systems.accessories = "short-range" # ------------------------------------------------------------------ # Main Wing # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Main_Wing() wing.tag = 'main_wing' wing.aspect_ratio = 12 wing.sweeps.quarter_chord = 3.00 * Units.deg wing.thickness_to_chord = 0.15 wing.taper = 0.53 wing.span_efficiency = 0.907 wing.calibration_factor = 1.1 wing.spans.projected = 27.05 * Units.meter wing.chords.root = 2.942 * Units.meter wing.chords.tip = 1.568 * Units.meter wing.chords.mean_aerodynamic = 2.325 * Units.meter wing.areas.reference = 61.00 * Units['meters**2'] wing.areas.wetted = 2.0 * wing.areas.reference wing.areas.exposed = 0.8 * wing.areas.wetted wing.twists.root = 2.0 * Units.degrees wing.twists.tip = 0.0 * Units.degrees wing.origin = [11.0946, 0, 0] wing.vertical = False wing.symmetric = True wing.high_lift = True wing.flaps.type = "single_slotted" wing.flaps.chord = 0.250 wing.dynamic_pressure_ratio = 1.0 wing.flaps.span_start = 0.11 wing.flaps.span_end = 0.73 wing_planform(wing) # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------------------ # Horizontal Stabilizer # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'horizontal_stabilizer' wing.aspect_ratio = 4.54 wing.sweeps.quarter_chord = 4.75 * Units.deg wing.thickness_to_chord = 0.12 wing.taper = 0.65 wing.span_efficiency = 0.9 wing.spans.projected = 7.3347 * Units.meter wing.chords.root = 1.960 * Units.meter wing.chords.tip = 1.273 * Units.meter wing.chords.mean_aerodynamic = 1.6413 * Units.meter wing.areas.reference = 11.86 * Units['meters**2'] wing.areas.wetted = 2.0 * wing.areas.reference wing.twists.root = 2.0 * Units.degrees wing.twists.tip = 2.0 * Units.degrees wing.origin = [24.96, 0, 0] wing.vertical = False wing.symmetric = True wing.dynamic_pressure_ratio = 0.9 wing_planform(wing) # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------------------ # Vertical Stabilizer # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'vertical_stabilizer' # equal to E190 data wing.aspect_ratio = 1.6 wing.sweeps.quarter_chord = 30 * Units.deg wing.thickness_to_chord = 0.12 wing.taper = 0.52 wing.span_efficiency = 0.90 wing.spans.projected = 4.8502 * Units.meter wing.chords.root = 3.9845 * Units.meter wing.chords.tip = 2.0840 * Units.meter wing.chords.mean_aerodynamic = 3.1289 * Units.meter wing.areas.reference = 14.72 * Units['meters**2'] wing.areas.wetted = 2.0 * wing.areas.reference wing.twists.root = 0.0 * Units.degrees wing.twists.tip = 0.0 * Units.degrees wing.origin = [21.667, 0, 0] wing.vertical = True wing.symmetric = False wing.dynamic_pressure_ratio = 1.0 wing_planform(wing) # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------------------ # Fuselage # ------------------------------------------------------------------ fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.number_coach_seats = vehicle.passengers fuselage.seats_abreast = 4 fuselage.seat_pitch = 0.762 fuselage.fineness.nose = 2.0 fuselage.fineness.tail = 3.0 fuselage.lengths.nose = 3.00 * Units.meter fuselage.lengths.tail = 4.26 * Units.meter fuselage.lengths.cabin = 19.91 * Units.meter fuselage.lengths.total = 27.17 * Units.meter fuselage.lengths.fore_space = 0. * Units.meter fuselage.lengths.aft_space = 0. * Units.meter fuselage.width = 2.865 * Units.meter fuselage.heights.maximum = 3.020 * Units.meter fuselage.areas.side_projected = 70.000 * Units['meters**2'] fuselage.areas.wetted = 200.00 * Units['meters**2'] fuselage.areas.front_projected = 7.5000 * Units['meters**2'] fuselage.effective_diameter = 3.02 fuselage.differential_pressure = 6.00 * Units.psi fuselage.heights.at_quarter_length = 3.02 * Units.meter fuselage.heights.at_three_quarters_length = 3.02 * Units.meter fuselage.heights.at_wing_root_quarter_chord = 3.02 * Units.meter # add to vehicle vehicle.append_component(fuselage) # ------------------------------------------------------------------ # turboprop Network # ------------------------------------------------------------------ #instantiate the gas turbine network turboprop = SUAVE.Components.Energy.Networks.Turboprop() turboprop.__defaults__() turboprop.tag = 'turboprop' # setup turboprop.number_of_engines = 2 turboprop.origin = [[8.483, 4.05, 0], [8.483, -4.05, 0]] * Units.meter turboprop.nacelle_diameter = 0.95 * Units.meter turboprop.engine_length = 2.25 * Units.meter turboprop.thrust_angle = 0.0 * Units.deg turboprop.installed_power = 2750. * Units.hp #compute engine areas turboprop.areas = Data() turboprop.areas.wetted = 2.0 * np.pi * turboprop.nacelle_diameter * turboprop.engine_length # working fluid turboprop.working_fluid = SUAVE.Attributes.Gases.Air() # ------------------------------------------------------------------ # Component 1 - Gas Turbine # to convert freestream static to stagnation quantities # instantiate gas_turbine = SUAVE.Components.Energy.Converters.Gas_Turbine() gas_turbine.tag = 'gas_turbine' gas_turbine.datum_sea_level_power = 2750. * Units.hp gas_turbine.power_scaling_factor = [0.622, 0.696, 0.74] # NTO, MCL, MCR gas_turbine.sfc_scaling_factor = [1.135, 1.135, 1.11] # NTO, MCL, MCR gas_turbine.power_extraction = 'bleed_ECS' gas_turbine.load_data('engine.out') gas_turbine.bucket = Data() # gas_turbine.bucket.RMTR = [0.600, 0.680, 0.760, 0.840, 0.920, 1.000] gas_turbine.bucket.RMTR = [0.600, 0.680, 0.760, 0.840, 0.900, 1.000] # gas_turbine.bucket.RSFC = [1.126, 1.086, 1.056, 1.033, 1.014, 1.000] gas_turbine.bucket.RSFC = [1.136, 1.096, 1.066, 1.043, 1.03, 1.000] # add to the network turboprop.gas_turbine = gas_turbine # ------------------------------------------------------------------ # Component 2 - Propeller # instantiate propeller = SUAVE.Components.Energy.Converters.Propeller() propeller.tag = 'propeller' # setup prop_attributes = Data() prop_attributes.number_blades = 6.0 prop_attributes.tip_radius = 1.980 * Units.meter prop_attributes.hub_radius = 0.285 * Units.meter prop_attributes.angular_velocity = 1200. * (2. * np.pi / 60.0 ) # Rotation Rate in rad/s prop_attributes.freestream_velocity = 140.0 # Freestream Velocity prop_attributes.design_Cl = 0.43 # Design Lift Coefficient prop_attributes.design_altitude = 21000.0 * Units.ft prop_attributes.design_thrust = 0.00 * Units.N prop_attributes.design_power = 1007.0 * 1e3 * Units.N * Units['m/s'] prop_attributes = propeller_design(prop_attributes) propeller.prop_attributes = prop_attributes # add to network turboprop.propeller = propeller # ------------------------------------------------------------------ # Component 3 - Gear Box # instantiate gearbox = SUAVE.Components.Energy.Converters.Gearbox() gearbox.tag = 'gear_box' gearbox.efficiency = 0.985 # setup turboprop.gearbox = gearbox turboprop.weight() # add gas turbine network turboprop to the vehicle vehicle.append_component(turboprop) # ------------------------------------------------------------------ # Vehicle Definition Complete # ------------------------------------------------------------------ return vehicle
def base_setup(): # ------------------------------------------------------------------ # Initialize the Vehicle # ------------------------------------------------------------------ vehicle = SUAVE.Vehicle() vehicle.tag = 'E170' # ------------------------------------------------------------------ # Vehicle-level Properties # ------------------------------------------------------------------ # mass properties vehicle.mass_properties.max_takeoff = 37200. * Units.kg vehicle.mass_properties.operating_empty = 20736. * Units.kg vehicle.mass_properties.takeoff = 37200. * Units.kg vehicle.mass_properties.max_zero_fuel = 30140. * Units.kg vehicle.mass_properties.cargo = 0.0 * Units.kg vehicle.mass_properties.max_payload = 9404.0 * Units.kg vehicle.mass_properties.max_fuel = 9428.0 * Units.kg # vehicle.mass_properties.center_of_gravity = [11., 0., 0.] vehicle.mass_properties.center_of_gravity = [12.925 + 0.15 * 3.194, 0., 0.] # envelope properties vehicle.envelope.ultimate_load = 2.5 * 1.5 vehicle.envelope.limit_load = 2.5 # basic parameters vehicle.reference_area = 72.72 * Units['meters**2'] vehicle.passengers = 72 vehicle.systems.control = "fully powered" vehicle.systems.accessories = "medium range" # ------------------------------------------------------------------ # Main Wing # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Main_Wing() wing.tag = 'main_wing' wing.aspect_ratio = 8.6 wing.sweeps.quarter_chord = 23.0 * Units.deg # 22.5 wing.thickness_to_chord = 0.11 wing.taper = 0.3275 #0.28 wing.span_efficiency = 0.96 wing.spans.projected = 26.0 * Units.meter wing.chords.root = 4.2138 * Units.meter #5.428 * Units.meter wing.chords.tip = 1.380 * Units.meter wing.chords.mean_aerodynamic = 3.194 * Units.meter # 3.806 wing.areas.reference = 72.72 * Units['meters**2'] wing.areas.wetted = 2.0 * wing.areas.reference wing.areas.exposed = 0.8 * wing.areas.wetted wing.twists.root = 2.0 * Units.degrees wing.twists.tip = 0.0 * Units.degrees wing.origin = [10.36122, 0, 0] wing.vertical = False wing.symmetric = True wing.high_lift = True wing.flaps.type = "double_slotted" wing.flaps.chord = 0.280 wing.dynamic_pressure_ratio = 1.0 wing.flaps.span_start = 0.13 wing.flaps.span_end = 0.75 wing_planform(wing) # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------------------ # Horizontal Stabilizer # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'horizontal_stabilizer' wing.aspect_ratio = 4.3 wing.sweeps.quarter_chord = 30.0 * Units.deg wing.thickness_to_chord = 0.11 wing.taper = 0.3707 wing.span_efficiency = 0.9 wing.spans.projected = 10.000 * Units.meter wing.chords.root = 3.394 * Units.meter wing.chords.tip = 1.258 * Units.meter wing.chords.mean_aerodynamic = 2.4895 * Units.meter wing.areas.reference = 23.25 * Units['meters**2'] wing.areas.wetted = 2.0 * wing.areas.reference wing.areas.exposed = 0.8 * wing.areas.wetted wing.twists.root = 2.0 * Units.degrees wing.twists.tip = 2.0 * Units.degrees wing.origin = [24.6, 0, 0] wing.vertical = False wing.symmetric = True wing.dynamic_pressure_ratio = 0.9 wing_planform(wing) # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------------------ # Vertical Stabilizer # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'vertical_stabilizer' # equal to E190 data wing.aspect_ratio = 1.7 wing.sweeps.quarter_chord = 35 * Units.deg wing.thickness_to_chord = 0.12 wing.taper = 0.26 wing.span_efficiency = 0.90 wing.spans.projected = 5.2153 * Units.meter wing.chords.root = 5.5779 * Units.meter wing.chords.tip = 1.4547 * Units.meter wing.chords.mean_aerodynamic = 3.9192 * Units.meter wing.areas.reference = 16.0 * Units['meters**2'] wing.areas.wetted = 2.0 * wing.areas.reference wing.areas.exposed = 0.8 * wing.areas.wetted wing.twists.root = 0.0 * Units.degrees wing.twists.tip = 0.0 * Units.degrees wing.origin = [23.9, 0, 0] wing.vertical = True wing.symmetric = False wing.dynamic_pressure_ratio = 1.0 wing_planform(wing) # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------------------ # Fuselage # ------------------------------------------------------------------ fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.number_coach_seats = vehicle.passengers fuselage.seats_abreast = 4 fuselage.seat_pitch = 0.7455 # fuselage.fineness.nose = 2.0 # fuselage.fineness.tail = 3.0 # fuselage.lengths.nose = 6.00 * Units.meter fuselage.lengths.tail = 9.00 * Units.meter fuselage.lengths.cabin = 14.90 * Units.meter fuselage.lengths.total = 29.90 * Units.meter fuselage.lengths.fore_space = 0. * Units.meter fuselage.lengths.aft_space = 0. * Units.meter fuselage.width = 3.000 * Units.meter fuselage.heights.maximum = 3.400 * Units.meter fuselage.areas.side_projected = 80.000 * Units[ 'meters**2'] # 197.35 * Units['meters**2'] fuselage.areas.wetted = 280.00 * Units['meters**2'] # 269.80 fuselage.areas.front_projected = 8.0110 * Units['meters**2'] # 8.0110 fuselage.effective_diameter = 3.2 fuselage.differential_pressure = 8.965 * Units.psi fuselage.heights.at_quarter_length = 3.4 * Units.meter fuselage.heights.at_three_quarters_length = 3.4 * Units.meter fuselage.heights.at_wing_root_quarter_chord = 3.4 * Units.meter # add to vehicle vehicle.append_component(fuselage) # ------------------------------------------------------------------ # Turbofan Network # ------------------------------------------------------------------ #initialize the gas turbine network gt_engine = SUAVE.Components.Energy.Networks.Turbofan() gt_engine.tag = 'turbofan' gt_engine.number_of_engines = 2.0 gt_engine.bypass_ratio = 5.0 gt_engine.engine_length = 3.1 * Units.meter gt_engine.nacelle_diameter = 1.64 * Units.meter gt_engine.origin = [[9.721, 3.984, -1], [9.721, -3.984, -1]] # meters # compute engine areas gt_engine.areas.wetted = 1.1 * 3.14159265359 * gt_engine.nacelle_diameter * gt_engine.engine_length #set the working fluid for the network gt_engine.working_fluid = SUAVE.Attributes.Gases.Air() # ------------------------------------------------------------------ # Component 1 - Ram # to convert freestream static to stagnation quantities ram = SUAVE.Components.Energy.Converters.Ram() ram.tag = 'ram' #add ram to the network gt_engine.ram = ram # ------------------------------------------------------------------ # Component 2 - Inlet Nozzle inlet_nozzle = SUAVE.Components.Energy.Converters.Compression_Nozzle() inlet_nozzle.tag = 'inlet nozzle' inlet_nozzle.polytropic_efficiency = 0.98 inlet_nozzle.pressure_ratio = 0.98 # add inlet nozzle to the network gt_engine.inlet_nozzle = inlet_nozzle # ------------------------------------------------------------------ # Component 3 - Low Pressure Compressor low_pressure_compressor = SUAVE.Components.Energy.Converters.Compressor() low_pressure_compressor.tag = 'lpc' low_pressure_compressor.polytropic_efficiency = 0.91 low_pressure_compressor.pressure_ratio = 1.90 # add low pressure compressor to the network gt_engine.low_pressure_compressor = low_pressure_compressor # ------------------------------------------------------------------ # Component 4 - High Pressure Compressor high_pressure_compressor = SUAVE.Components.Energy.Converters.Compressor() high_pressure_compressor.tag = 'hpc' high_pressure_compressor.polytropic_efficiency = 0.91 high_pressure_compressor.pressure_ratio = 7.50 # add the high pressure compressor to the network gt_engine.high_pressure_compressor = high_pressure_compressor # ------------------------------------------------------------------ # Component 5 - Low Pressure Turbine low_pressure_turbine = SUAVE.Components.Energy.Converters.Turbine() low_pressure_turbine.tag = 'lpt' low_pressure_turbine.mechanical_efficiency = 0.99 low_pressure_turbine.polytropic_efficiency = 0.93 # add low pressure turbine to the network gt_engine.low_pressure_turbine = low_pressure_turbine # ------------------------------------------------------------------ # Component 6 - High Pressure Turbine high_pressure_turbine = SUAVE.Components.Energy.Converters.Turbine() high_pressure_turbine.tag = 'hpt' high_pressure_turbine.mechanical_efficiency = 0.99 high_pressure_turbine.polytropic_efficiency = 0.93 # add the high pressure turbine to the network gt_engine.high_pressure_turbine = high_pressure_turbine # ------------------------------------------------------------------ # Component 7 - Combustor combustor = SUAVE.Components.Energy.Converters.Combustor() combustor.tag = 'Comb' combustor.efficiency = 0.99 combustor.alphac = 1.0 combustor.turbine_inlet_temperature = 1500 combustor.pressure_ratio = 0.95 combustor.fuel_data = SUAVE.Attributes.Propellants.Jet_A() # add the combustor to the network gt_engine.combustor = combustor # ------------------------------------------------------------------ # Component 8 - Core Nozzle core_nozzle = SUAVE.Components.Energy.Converters.Expansion_Nozzle() core_nozzle.tag = 'core nozzle' core_nozzle.polytropic_efficiency = 0.95 core_nozzle.pressure_ratio = 0.98 #add the core nozzle to the network gt_engine.core_nozzle = core_nozzle # ------------------------------------------------------------------ # Component 9 - Fan Nozzle fan_nozzle = SUAVE.Components.Energy.Converters.Expansion_Nozzle() fan_nozzle.tag = 'fan nozzle' fan_nozzle.polytropic_efficiency = 0.95 fan_nozzle.pressure_ratio = 0.98 # add the fan nozzle to the network gt_engine.fan_nozzle = fan_nozzle # ------------------------------------------------------------------ # Component 10 - Fan fan = SUAVE.Components.Energy.Converters.Fan() fan.tag = 'fan' fan.polytropic_efficiency = 0.93 fan.pressure_ratio = 1.625 # add the fan to the network gt_engine.fan = fan # ------------------------------------------------------------------ # Component 11 : thrust (to compute the thrust) thrust = SUAVE.Components.Energy.Processes.Thrust() thrust.tag = 'compute_thrust' #total design thrust (includes all the engines) thrust.total_design = 27550.0 * Units.N #Newtons #design sizing conditions altitude = 35000.0 * Units.ft mach_number = 0.78 isa_deviation = 0. # add thrust to the network gt_engine.thrust = thrust #size the turbofan turbofan_sizing(gt_engine, mach_number, altitude) # add gas turbine network gt_engine to the vehicle vehicle.append_component(gt_engine) # ------------------------------------------------------------------ # now add weights objects vehicle.landing_gear = SUAVE.Components.Landing_Gear.Landing_Gear() vehicle.control_systems = SUAVE.Components.Physical_Component() vehicle.electrical_systems = SUAVE.Components.Physical_Component() vehicle.avionics = SUAVE.Components.Energy.Peripherals.Avionics() vehicle.passenger_weights = SUAVE.Components.Physical_Component() vehicle.furnishings = SUAVE.Components.Physical_Component() vehicle.air_conditioner = SUAVE.Components.Physical_Component() vehicle.fuel = SUAVE.Components.Physical_Component() vehicle.apu = SUAVE.Components.Physical_Component() vehicle.hydraulics = SUAVE.Components.Physical_Component() vehicle.optionals = SUAVE.Components.Physical_Component() vehicle.wings[ 'vertical_stabilizer'].rudder = SUAVE.Components.Physical_Component() # ------------------------------------------------------------------ # Vehicle Definition Complete # ------------------------------------------------------------------ return vehicle
def populate_wing_sections(avl_wing, suave_wing): """ Creates sections of wing geometry and populates the AVL wing data structure Assumptions: None Source: None Inputs: avl_wing.symmetric [boolean] suave_wing.spans.projected [meters] suave_wing.origin [meters] suave_wing.dihedral [radians] suave_wing.Segments.sweeps.leading_edge [radians] suave_wing.Segments.root_chord_percent [-] suave_wing.Segments.percent_span_location [-] suave_wing.Segments.sweeps.quarter_chord [radians] suave_wing.Segment.twist [radians] Outputs: avl_wing - aircraft wing in AVL format [data stucture] Properties Used: N/A """ if len(suave_wing.Segments.keys()) > 0: # obtain the geometry for each segment in a loop symm = avl_wing.symmetric semispan = suave_wing.spans.projected * 0.5 * (2 - symm) avl_wing.semispan = semispan root_chord = suave_wing.chords.root segment_percent_span = 0 segments = suave_wing.Segments n_segments = len(segments.keys()) segment_sweeps = [] origin = [] origin.append(suave_wing.origin) for i_segs in range(n_segments): if (i_segs == n_segments - 1): segment_sweeps.append(0) else: # this converts all sweeps defined by the quarter chord to leading edge sweep since AVL needs the start of each wing section #from the leading edge coordinate and not the quarter chord coordinate if segments[i_segs].sweeps.leading_edge is not None: # if leading edge sweep is defined segment_sweep = segments[i_segs].sweeps.leading_edge else: # if quarter chord sweep is defined, convert it to leading edge sweep sweep_quarter_chord = segments[i_segs].sweeps.quarter_chord chord_fraction = 0.25 segment_root_chord = root_chord * segments[ i_segs].root_chord_percent segment_tip_chord = root_chord * segments[ i_segs + 1].root_chord_percent segment_span = semispan * ( segments[i_segs + 1].percent_span_location - segments[i_segs].percent_span_location) segment_sweep = np.arctan( ((segment_root_chord * chord_fraction) + (np.tan(sweep_quarter_chord) * segment_span - chord_fraction * segment_tip_chord)) / segment_span) segment_sweeps.append(segment_sweep) dihedral = segments[i_segs].dihedral_outboard ctrl_surf_at_seg = False # condition for the presence of control surfaces in segment if segments[i_segs].control_surfaces: dihedral_ob = segments[i_segs - 1].dihedral_outboard section_spans = [] for cs in segments[i_segs].control_surfaces: # create a vector if all the section breaks in a segment. sections include beginning and end of control surfaces and end of segment control_surface_start = semispan * cs.span_fraction_start control_surface_end = semispan * cs.span_fraction_end section_spans.append(control_surface_start) section_spans.append(control_surface_end) ordered_section_spans = sorted( list(set(section_spans)) ) # sort the section_spans in order to create sections in spanwise order num_sections = len( ordered_section_spans ) # count the number of sections breaks that the segment will contain \ for section_count in range(num_sections): # create and append sections onto avl wing structure if ordered_section_spans[ section_count] == semispan * segments[ i_segs - 1].percent_span_location: # if control surface begins at beginning of segment, redundant section is removed section_tags = list(avl_wing.sections.keys()) del avl_wing.sections[section_tags[-1]] # create section for each break in the wing section = Section() section.tag = segments[i_segs].tag + '_section_' + str( ordered_section_spans[section_count]) + 'm' root_section_chord = root_chord * segments[ i_segs - 1].root_chord_percent tip_section_chord = root_chord * segments[ i_segs].root_chord_percent semispan_section_fraction = ( ordered_section_spans[section_count] - semispan * segments[i_segs - 1].percent_span_location ) / (semispan * (segments[i_segs].percent_span_location - segments[i_segs - 1].percent_span_location)) section.chord = np.interp( semispan_section_fraction, [0., 1.], [root_section_chord, tip_section_chord]) root_section_twist = segments[i_segs - 1].twist / Units.degrees tip_section_twist = root_chord * segments[ i_segs].twist / Units.degrees section.twist = np.interp( semispan_section_fraction, [0., 1.], [root_section_twist, tip_section_twist]) # if wing is a vertical wing, the y and z coordinates are swapped if avl_wing.vertical: dz = ordered_section_spans[ section_count] - semispan * segments[ i_segs - 1].percent_span_location dy = dz * np.tan(dihedral_ob) l = dz / np.cos(dihedral_ob) dx = l * np.tan(segment_sweeps[i_segs - 1]) else: dy = ordered_section_spans[ section_count] - semispan * segments[ i_segs - 1].percent_span_location dz = dy * np.tan(dihedral_ob) l = dy / np.cos(dihedral_ob) dx = l * np.tan(segment_sweeps[i_segs - 1]) section.origin = [[ origin[i_segs - 1][0][0] + dx, origin[i_segs - 1][0][1] + dy, origin[i_segs - 1][0][2] + dz ]] # this loop appends all the control surfaces within a particular wing section for index, ctrl_surf in enumerate( segments[i_segs].control_surfaces): if (semispan*ctrl_surf.span_fraction_start == ordered_section_spans[section_count]) or \ (ordered_section_spans[section_count] == semispan*ctrl_surf.span_fraction_end): c = Control_Surface() c.tag = ctrl_surf.tag # name of control surface c.sign_duplicate = '+1' # this float indicates control surface deflection symmetry c.x_hinge = 1 - ctrl_surf.chord_fraction # this float is the % location of the control surface hinge on the wing c.deflection = ctrl_surf.deflection / Units.degrees c.order = index # if control surface is an aileron, the deflection is asymmetric. This is standard convention from AVL if (type(ctrl_surf) == Aileron): c.sign_duplicate = '-1' c.function = 'aileron' c.gain = -1.0 # if control surface is a slat, the hinge is taken from the leading edge elif (type(ctrl_surf) == Slat): c.x_hinge = -ctrl_surf.chord_fraction c.function = 'slat' c.gain = -1.0 elif (type(ctrl_surf) == Flap): c.function = 'flap' c.gain = 1.0 elif (type(ctrl_surf) == Elevator): c.function = 'elevator' c.gain = 1.0 elif (type(ctrl_surf) == Rudder): c.function = 'rudder' c.gain = 1.0 else: raise AttributeError( "Define control surface function as 'slat', 'flap', 'elevator' , 'aileron' or 'rudder'" ) section.append_control_surface(c) elif (semispan*ctrl_surf.span_fraction_start < ordered_section_spans[section_count]) and \ (ordered_section_spans[section_count] < semispan*ctrl_surf.span_fraction_end): c = Control_Surface() c.tag = ctrl_surf.tag # name of control surface c.sign_duplicate = '+1' # this float indicates control surface deflection symmetry c.x_hinge = 1 - ctrl_surf.chord_fraction # this float is the % location of the control surface hinge on the wing c.deflection = ctrl_surf.deflection / Units.degrees c.order = index # if control surface is an aileron, the deflection is asymmetric. This is standard convention from AVL if (type(ctrl_surf) == Aileron): c.sign_duplicate = '-1' c.function = 'aileron' c.gain = -1.0 # if control surface is a slat, the hinge is taken from the leading edge elif (type(ctrl_surf) == Slat): c.x_hinge = -ctrl_surf.chord_fraction c.function = 'slat' c.gain = -1.0 elif (type(ctrl_surf) == Flap): c.function = 'flap' c.gain = 1.0 elif (type(ctrl_surf) == Elevator): c.function = 'elevator' c.gain = 1.0 elif (type(ctrl_surf) == Rudder): c.function = 'rudder' c.gain = 1.0 else: raise AttributeError( "Define control surface function as 'slat', 'flap', 'elevator' , 'aileron' or 'rudder'" ) section.append_control_surface(c) if segments[i_segs].Airfoil: if segments[ i_segs].Airfoil.airfoil.coordinate_file is not None: section.airfoil_coord_file = write_avl_airfoil_file( segments[i_segs].Airfoil.airfoil. coordinate_file) elif segments[ i_segs].Airfoil.airfoil.naca_airfoil is not None: section.naca_airfoil = segments[ i_segs].Airfoil.airfoil.naca_airfoil avl_wing.append_section(section) # check if control surface ends at end of segment if ordered_section_spans[section_count] == semispan * segments[ i_segs].percent_span_location: ctrl_surf_at_seg = True if ctrl_surf_at_seg: # if a control surface ends at the end of the segment, there is not need to append another segment pass else: # if there is no control surface break at the end of the segment, this block appends a segment section = Section() section.tag = segments[i_segs].tag section.chord = root_chord * segments[i_segs].root_chord_percent section.twist = segments[i_segs].twist / Units.degrees section.origin = origin[i_segs] if segments[i_segs].Airfoil: if segments[ i_segs].Airfoil.airfoil.coordinate_file is not None: section.airfoil_coord_file = write_avl_airfoil_file( segments[i_segs].Airfoil.airfoil.coordinate_file) elif segments[ i_segs].Airfoil.airfoil.naca_airfoil is not None: section.naca_airfoil = segments[ i_segs].Airfoil.airfoil.naca_airfoil # append section to wing avl_wing.append_section(section) # update origin for next segment if (i_segs == n_segments - 1): return avl_wing segment_percent_span = segments[ i_segs + 1].percent_span_location - segments[ i_segs].percent_span_location if avl_wing.vertical: dz = semispan * segment_percent_span dy = dz * np.tan(dihedral) l = dz / np.cos(dihedral) dx = l * np.tan(segment_sweep) else: dy = semispan * segment_percent_span dz = dy * np.tan(dihedral) l = dy / np.cos(dihedral) dx = l * np.tan(segment_sweep) origin.append([[ origin[i_segs][0][0] + dx, origin[i_segs][0][1] + dy, origin[i_segs][0][2] + dz ]]) else: symm = avl_wing.symmetric dihedral = suave_wing.dihedral span = suave_wing.spans.projected semispan = suave_wing.spans.projected * 0.5 * (2 - symm) if suave_wing.sweeps.leading_edge is not None: sweep = suave_wing.sweeps.leading_edge else: suave_wing = wing_planform(suave_wing) sweep = suave_wing.sweeps.leading_edge avl_wing.semispan = semispan origin = suave_wing.origin[0] # define root section root_section = Section() root_section.tag = 'root_section' root_section.origin = [origin] root_section.chord = suave_wing.chords.root root_section.twist = suave_wing.twists.root / Units.degrees root_section.semispan = semispan # define tip section tip_section = Section() tip_section.tag = 'tip_section' tip_section.chord = suave_wing.chords.tip tip_section.twist = suave_wing.twists.tip / Units.degrees tip_section.semispan = 0 # assign location of wing tip if avl_wing.vertical: tip_section.origin = [[ origin[0] + semispan * np.tan(sweep), origin[1] + semispan * np.tan(dihedral), origin[2] + semispan ]] else: tip_section.origin = [[ origin[0] + semispan * np.tan(sweep), origin[1] + semispan, origin[2] + semispan * np.tan(dihedral) ]] # assign wing airfoil if suave_wing.Airfoil: root_section.airfoil_coord_file = suave_wing.Airfoil.airfoil.coordinate_file tip_section.airfoil_coord_file = suave_wing.Airfoil.airfoil.coordinate_file avl_wing.append_section(root_section) avl_wing.append_section(tip_section) return avl_wing