Example #1
0
def energy_network():
    # ------------------------------------------------------------------
    #   Evaluation Conditions
    # ------------------------------------------------------------------

    # Setup Conditions
    ones_1col = np.ones([1, 1])
    conditions = SUAVE.Analyses.Mission.Segments.Conditions.Aerodynamics()

    # Freestream conditions
    conditions.freestream.mach_number = ones_1col * 0.4
    conditions.freestream.pressure = ones_1col * 20000.0
    conditions.freestream.temperature = ones_1col * 215.0
    conditions.freestream.density = ones_1col * 0.8
    conditions.freestream.dynamic_viscosity = ones_1col * 0.000001475
    conditions.freestream.altitude = ones_1col * 10.0
    conditions.freestream.gravity = ones_1col * 9.81
    conditions.freestream.isentropic_expansion_factor = ones_1col * 1.4
    conditions.freestream.Cp = 1.4 * 287.87 / (1.4 - 1)
    conditions.freestream.R = 287.87
    conditions.M = conditions.freestream.mach_number
    conditions.T = conditions.freestream.temperature
    conditions.p = conditions.freestream.pressure
    conditions.freestream.speed_of_sound = ones_1col * np.sqrt(
        conditions.freestream.Cp /
        (conditions.freestream.Cp - conditions.freestream.R) *
        conditions.freestream.R * conditions.freestream.temperature)  #300.
    conditions.freestream.velocity = conditions.M * conditions.freestream.speed_of_sound
    conditions.velocity = conditions.M * conditions.freestream.speed_of_sound
    conditions.q = 0.5 * conditions.freestream.density * conditions.velocity**2
    conditions.g0 = conditions.freestream.gravity

    # propulsion conditions
    conditions.propulsion.throttle = ones_1col * 1.0

    # ------------------------------------------------------------------
    #   Design/sizing conditions
    # ------------------------------------------------------------------

    # Setup Conditions
    ones_1col = np.ones([1, 1])
    conditions_sizing = SUAVE.Analyses.Mission.Segments.Conditions.Aerodynamics(
    )

    # freestream conditions
    conditions_sizing.freestream.mach_number = ones_1col * 0.5
    conditions_sizing.freestream.pressure = ones_1col * 26499.73156529
    conditions_sizing.freestream.temperature = ones_1col * 223.25186491
    conditions_sizing.freestream.density = ones_1col * 0.41350854
    conditions_sizing.freestream.dynamic_viscosity = ones_1col * 1.45766126e-05
    conditions_sizing.freestream.altitude = ones_1col * 10000.0
    conditions_sizing.freestream.gravity = ones_1col * 9.81
    conditions_sizing.freestream.isentropic_expansion_factor = ones_1col * 1.4
    conditions_sizing.freestream.Cp = 1.4 * 287.87 / (1.4 - 1)
    conditions_sizing.freestream.R = 287.87
    conditions_sizing.freestream.speed_of_sound = 299.53150968
    conditions_sizing.freestream.velocity = conditions_sizing.freestream.mach_number * conditions_sizing.freestream.speed_of_sound

    # propulsion conditions
    conditions_sizing.propulsion.throttle = ones_1col * 1.0

    # Setup Sizing
    state_sizing = Data()
    state_sizing.numerics = Data()
    state_sizing.conditions = conditions_sizing
    state_off_design = Data()
    state_off_design.numerics = Data()
    state_off_design.conditions = conditions

    # ------------------------------------------------------------------
    #   Ducted Fan Network
    # ------------------------------------------------------------------

    #instantiate the ducted fan network
    ductedfan = SUAVE.Components.Energy.Networks.Ducted_Fan()
    ductedfan.tag = 'ductedfan'

    # setup
    ductedfan.bypass_ratio = 0.0
    ductedfan.number_of_engines = 2.0
    ductedfan.engine_length = 0.15
    ductedfan.nacelle_diameter = 0.5

    # working fluid
    ductedfan.working_fluid = SUAVE.Attributes.Gases.Air()

    # ------------------------------------------------------------------
    #   Component 1 - Ram
    # to convert freestream static to stagnation quantities

    # instantiate
    ram = SUAVE.Components.Energy.Converters.Ram()
    ram.tag = 'ram'

    # add to the network
    ductedfan.append(ram)

    # ------------------------------------------------------------------
    #  Component 2 - Inlet Nozzle

    # instantiate
    inlet_nozzle = SUAVE.Components.Energy.Converters.Compression_Nozzle()
    inlet_nozzle.tag = 'inlet_nozzle'

    # setup
    inlet_nozzle.polytropic_efficiency = 1.0
    inlet_nozzle.pressure_ratio = 1.0

    # add to network
    ductedfan.append(inlet_nozzle)

    # ------------------------------------------------------------------
    #  Component 3 - Fan

    # instantiate
    fan = SUAVE.Components.Energy.Converters.Fan()
    fan.tag = 'fan'

    # setup
    fan.polytropic_efficiency = 1.0
    fan.pressure_ratio = 1.3

    # add to network
    ductedfan.append(fan)

    # ------------------------------------------------------------------
    #  Component 4 - outlet_nozzle

    # instantiate
    fan_nozzle = SUAVE.Components.Energy.Converters.Expansion_Nozzle()
    fan_nozzle.tag = 'fan_nozzle'

    # setup
    fan_nozzle.polytropic_efficiency = 1.0
    fan_nozzle.pressure_ratio = 1.0

    # add to network
    ductedfan.append(fan_nozzle)

    # ------------------------------------------------------------------
    #  Component 5 - Thrust
    # to compute thrust

    # instantiate
    thrust = SUAVE.Components.Energy.Processes.Thrust()
    thrust.tag = 'thrust'

    # setup
    thrust.total_design = 21191.50900196

    # add to network
    ductedfan.thrust = thrust

    #size the turbofan
    ducted_fan_sizing(ductedfan, 0.5, 10000.0)

    print("Design thrust ", ductedfan.design_thrust)
    print("Sealevel static thrust ", ductedfan.sealevel_static_thrust)

    results_design = ductedfan(state_sizing)
    results_off_design = ductedfan(state_off_design)
    F = results_design.thrust_force_vector
    F_off_design = results_off_design.thrust_force_vector

    # Test the model
    # Specify the expected values
    expected = Data()
    expected.thrust = 21191.509001558181

    #error data function
    error = Data()
    error.thrust_error = (F[0][0] - expected.thrust) / expected.thrust
    print(error)

    for k, v in list(error.items()):
        assert (np.abs(v) < 1e-6)

    return
Example #2
0
def energy_network():
    # ------------------------------------------------------------------
    #   Battery Ducted Fan Network
    # ------------------------------------------------------------------    
    
    #instantiate the ducted fan network
    ducted_fan = SUAVE.Components.Energy.Networks.Ducted_Fan()
    ducted_fan.tag = 'ducted fan'
    
    # setup
    ducted_fan.number_of_engines = 2
    ducted_fan.engine_length     = 1.038 * Units.meter
    ducted_fan.nacelle_diameter  = 1.064 * Units.meter
    ducted_fan.origin            = [[8.95, 1.48, 0.50],[8.95, -1.48, 0.50]] # meters

    
    #compute engine areas
    ducted_fan.areas.wetted      = 1.1*np.pi*ducted_fan.nacelle_diameter*ducted_fan.engine_length
    
    # working fluid
    ducted_fan.working_fluid = SUAVE.Attributes.Gases.Air()

    # ------------------------------------------------------------------
    #   Component 1 - Ram
    
    # to convert freestream static to stagnation quantities
    # instantiate
    ram         = SUAVE.Components.Energy.Converters.Ram()
    ram.tag     = 'ram'
    
    # add to the network
    ducted_fan.append(ram)

    # ------------------------------------------------------------------
    #  Component 2 - Inlet Nozzle
    
    # instantiate
    inlet_nozzle        = SUAVE.Components.Energy.Converters.Compression_Nozzle()
    inlet_nozzle.tag    = 'inlet_nozzle'
    
    # setup
    inlet_nozzle.polytropic_efficiency = 0.98
    inlet_nozzle.pressure_ratio        = 0.98
    
    # add to network
    ducted_fan.append(inlet_nozzle)

    # ------------------------------------------------------------------
    #  Component 3 - Fan
    
    # instantiate
    fan = SUAVE.Components.Energy.Converters.Fan()   
    fan.tag                   = 'fan'

    # setup
    fan.polytropic_efficiency = 0.93
    fan.pressure_ratio        = 1.7    
    
    # add to network
    ducted_fan.append(fan)

    # ------------------------------------------------------------------
    #  Component 4 - Fan Nozzle
    
    # instantiate
    nozzle = SUAVE.Components.Energy.Converters.Expansion_Nozzle()   
    nozzle.tag = 'fan_nozzle'

    # setup
    nozzle.polytropic_efficiency    = 0.95
    nozzle.pressure_ratio           = 0.99  

    # add to network
    ducted_fan.append(nozzle)

    # ------------------------------------------------------------------
    #Component 5 : thrust (to compute the thrust)
    thrust = SUAVE.Components.Energy.Processes.Thrust()       
    thrust.tag                 ='thrust'
 
    #total design thrust (includes all the engines)
    thrust.total_design        = 2*700. * Units.lbf 
    
    
    # add to network
    ducted_fan.thrust          = thrust   
      
    #design sizing conditions
    altitude      = 0.0 * Units.km
    mach_number   = 0.01
    isa_deviation = 0.
    
    #size the ducted fan
    ducted_fan_sizing(ducted_fan,mach_number,altitude)

    # Created Serial Hybrid Ducted Fan network and set defaults
    hybrid_ducted_fan                      = SUAVE.Components.Energy.Networks.Serial_Hybrid_Ducted_Fan()
    hybrid_ducted_fan.tag                  = 'serial_hybrid_ducted_fan'
    hybrid_ducted_fan.nacelle_diameter     = ducted_fan.nacelle_diameter
    hybrid_ducted_fan.areas                = Data()
    hybrid_ducted_fan.areas.wetted         = ducted_fan.areas.wetted
    hybrid_ducted_fan.engine_length        = ducted_fan.engine_length
    hybrid_ducted_fan.origin               = ducted_fan.origin
    hybrid_ducted_fan.voltage              = 400.

    # add  gas turbine network turbofan to the network 
    hybrid_ducted_fan.propulsor            = ducted_fan

    # Create ESC and add to the network
    esc = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller()
    esc.efficiency                  = 0.97
    hybrid_ducted_fan.esc          = esc

    # Create payload and add to the network
    payload = SUAVE.Components.Energy.Peripherals.Avionics()
    payload.power_draw              = 0.
    payload.mass_properties.mass    = 0. * Units.kg 
    hybrid_ducted_fan.payload      = payload

    # Create avionics and add to the network
    avionics = SUAVE.Components.Energy.Peripherals.Avionics()
    avionics.power_draw             = 200. * Units.watts 
    hybrid_ducted_fan.avionics     = avionics

    # Create the battery and add to the network
    bat = SUAVE.Components.Energy.Storages.Batteries.Constant_Mass.Lithium_Ion()
    bat.specific_energy             = 300. * Units.Wh/Units.kg
    bat.resistance                  = 0.006
    bat.max_voltage                 = 400.
    bat.mass_properties.mass        = 1000. * Units.kg 
    initialize_from_mass(bat, bat.mass_properties.mass)
    hybrid_ducted_fan.battery      = bat
    
    # Create the generator and add to the network
    generator = SUAVE.Components.Energy.Converters.Generator_Zero_Fid()
    generator.max_power = 500000 * Units.watt
    generator.sfc = 300 * Units['g/kW/h']
    
    hybrid_ducted_fan.generator = generator
    
    # ------------------------------------------------------------------
    #   Evaluation Conditions
    # ------------------------------------------------------------------    
    
    # Conditions        
    ones_1col                        = np.array([[1.0],[1.0]])       
    alt                              = 5.0 * Units.km
    
    # Setup the conditions to run the network
    state               = Data()
    state.numerics      = SUAVE.Analyses.Mission.Segments.Conditions.Numerics()
    state.conditions    = SUAVE.Analyses.Mission.Segments.Conditions.Aerodynamics()
    
    conditions          = state.conditions
    numerics            = state.numerics
    
    planet              = SUAVE.Attributes.Planets.Earth()   
    working_fluid       = SUAVE.Attributes.Gases.Air()    
    
     # Calculate atmospheric properties
    atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976()
    atmosphere_conditions =  atmosphere.compute_values(alt)
    rho = atmosphere_conditions.density[0,:]
    a   = atmosphere_conditions.speed_of_sound[0,:]
    mu  = atmosphere_conditions.dynamic_viscosity[0,:]
    T   = atmosphere_conditions.temperature[0,:]
    mach = 0.7

    # aerodynamic conditions
    conditions.expand_rows(2)
    conditions.freestream.mach_number                  = mach * ones_1col
    conditions.freestream.pressure                     = atmosphere_conditions.pressure * ones_1col
    conditions.freestream.temperature                  = T * ones_1col
    conditions.freestream.density                      = rho * ones_1col
    conditions.freestream.dynamic_viscosity            = mu * ones_1col
    conditions.freestream.speed_of_sound               = a * ones_1col
    conditions.freestream.velocity                     = conditions.freestream.mach_number * conditions.freestream.speed_of_sound
    conditions.freestream.altitude                     = alt * ones_1col
    conditions.freestream.gravity                      = planet.compute_gravity(alt) * ones_1col
    conditions.propulsion.battery_energy               = bat.max_energy * ones_1col
    conditions.frames.inertial.time                    = np.array([[0.0],[1.0]])
    conditions.freestream.isentropic_expansion_factor  = ones_1col*working_fluid.compute_gamma(atmosphere_conditions.temperature,atmosphere_conditions.pressure)                                                                                             
    conditions.freestream.Cp                           = ones_1col*working_fluid.compute_cp(atmosphere_conditions.temperature,atmosphere_conditions.pressure)
    conditions.freestream.R                            = ones_1col*working_fluid.gas_specific_constant    
    conditions.q                                       = 0.5 * conditions.freestream.density * conditions.freestream.velocity**2
    # numerics conditions
    numerics.time.integrate                            = np.array([[0, 0],[0, 1]])
    numerics.time.differentiate                        = np.array([[0, 0],[0, 1]])
  
    
    # propulsion conditions
    conditions.propulsion.throttle                     = np.array([[1.0],[1.0]])
    conditions.propulsion.battery_energy               = bat.max_energy*np.ones_like(ones_1col)
    
    print("Design thrust ", hybrid_ducted_fan.propulsor.design_thrust 
          * hybrid_ducted_fan.number_of_engines)
    print("Sealevel static thrust ", hybrid_ducted_fan.propulsor.sealevel_static_thrust
          * hybrid_ducted_fan.number_of_engines)
    
    
    results_off_design  = hybrid_ducted_fan(state)
    F                   = results_off_design.thrust_force_vector
    mdot                = results_off_design.vehicle_mass_rate
    power               = results_off_design.power
    

    
    #Specify the expected values
    expected        = Data()
    expected.thrust = 3053.50858719
    expected.power  = 849362.83002354
    expected.mdot   = 0.041666667
    
    #error data function
    error              =  Data()
    error.thrust_error = (F[0][0] -  expected.thrust)/expected.thrust
    error.power_error  = (power[0] - expected.power)/expected.power
    error.mdot_error   = (mdot[0][0] - expected.mdot)/expected.mdot 
    print(error)
    
    for k,v in list(error.items()):
        assert(np.abs(v)<1e-6)    
    
    return
Example #3
0
def energy_network():
    # ------------------------------------------------------------------
    #   Evaluation Conditions
    # ------------------------------------------------------------------    
    
    # Setup Conditions        
    ones_1col  = np.ones([1,1])    
    conditions = SUAVE.Analyses.Mission.Segments.Conditions.Aerodynamics()
       
    # Freestream conditions
    conditions.freestream.mach_number                 = ones_1col*0.4
    conditions.freestream.pressure                    = ones_1col*20000.0
    conditions.freestream.temperature                 = ones_1col*215.0
    conditions.freestream.density                     = ones_1col*0.8
    conditions.freestream.dynamic_viscosity           = ones_1col*0.000001475
    conditions.freestream.altitude                    = ones_1col*10.0
    conditions.freestream.gravity                     = ones_1col*9.81
    conditions.freestream.isentropic_expansion_factor = ones_1col*1.4
    conditions.freestream.Cp                          = 1.4*287.87/(1.4-1)
    conditions.freestream.R                           = 287.87
    conditions.M                                      = conditions.freestream.mach_number 
    conditions.T                                      = conditions.freestream.temperature
    conditions.p                                      = conditions.freestream.pressure
    conditions.freestream.speed_of_sound              = ones_1col* np.sqrt(conditions.freestream.Cp/(conditions.freestream.Cp-conditions.freestream.R)*conditions.freestream.R*conditions.freestream.temperature) #300.
    conditions.freestream.velocity                    = conditions.M * conditions.freestream.speed_of_sound
    conditions.velocity                               = conditions.M * conditions.freestream.speed_of_sound
    conditions.q                                      = 0.5*conditions.freestream.density*conditions.velocity**2
    conditions.g0                                     = conditions.freestream.gravity
    
    # propulsion conditions
    conditions.propulsion.throttle                    =  ones_1col*1.0

    # ------------------------------------------------------------------
    #   Design/sizing conditions 
    # ------------------------------------------------------------------    
        
    # Setup Conditions        
    ones_1col = np.ones([1,1])       
    conditions_sizing = SUAVE.Analyses.Mission.Segments.Conditions.Aerodynamics()
 
    # freestream conditions
    conditions_sizing.freestream.mach_number                 = ones_1col*0.5
    conditions_sizing.freestream.pressure                    = ones_1col*26499.73156529
    conditions_sizing.freestream.temperature                 = ones_1col*223.25186491
    conditions_sizing.freestream.density                     = ones_1col*0.41350854
    conditions_sizing.freestream.dynamic_viscosity           = ones_1col* 1.45766126e-05
    conditions_sizing.freestream.altitude                    = ones_1col* 10000.0
    conditions_sizing.freestream.gravity                     = ones_1col*9.81
    conditions_sizing.freestream.isentropic_expansion_factor = ones_1col*1.4
    conditions_sizing.freestream.Cp                          = 1.4*287.87/(1.4-1)
    conditions_sizing.freestream.R                           = 287.87
    conditions_sizing.freestream.speed_of_sound              = 299.53150968
    conditions_sizing.freestream.velocity                    = conditions_sizing.freestream.mach_number*conditions_sizing.freestream.speed_of_sound
    
    # propulsion conditions
    conditions_sizing.propulsion.throttle                    =  ones_1col*1.0

    # Setup Sizing
    state_sizing = Data()
    state_sizing.numerics = Data()
    state_sizing.conditions = conditions_sizing
    state_off_design=Data()
    state_off_design.numerics=Data()
    state_off_design.conditions=conditions


    # ------------------------------------------------------------------
    #   Ducted Fan Network
    # ------------------------------------------------------------------    

    #instantiate the ducted fan network
    ductedfan = SUAVE.Components.Energy.Networks.Ducted_Fan()
    ductedfan.tag = 'ductedfan'
    
    # setup
    ductedfan.bypass_ratio      = 0.0
    ductedfan.number_of_engines = 2.0
    ductedfan.engine_length     = 0.15
    ductedfan.nacelle_diameter  = 0.5
    
    # working fluid
    ductedfan.working_fluid = SUAVE.Attributes.Gases.Air()
    
    # ------------------------------------------------------------------
    #   Component 1 - Ram
    # to convert freestream static to stagnation quantities
    
    # instantiate
    ram = SUAVE.Components.Energy.Converters.Ram()
    ram.tag = 'ram'
    
    # add to the network
    ductedfan.append(ram)

    # ------------------------------------------------------------------
    #  Component 2 - Inlet Nozzle   

    # instantiate
    inlet_nozzle = SUAVE.Components.Energy.Converters.Compression_Nozzle()
    inlet_nozzle.tag = 'inlet_nozzle'
    
    # setup
    inlet_nozzle.polytropic_efficiency = 1.0
    inlet_nozzle.pressure_ratio        = 1.0
    
    # add to network
    ductedfan.append(inlet_nozzle)
    
    # ------------------------------------------------------------------
    #  Component 3 - Fan
    
    # instantiate 
    fan = SUAVE.Components.Energy.Converters.Fan()    
    fan.tag = 'fan'

    # setup
    fan.polytropic_efficiency = 1.0
    fan.pressure_ratio        = 1.3    
    
    # add to network
    ductedfan.append(fan)

    # ------------------------------------------------------------------
    #  Component 4 - outlet_nozzle

    # instantiate
    fan_nozzle = SUAVE.Components.Energy.Converters.Expansion_Nozzle()    
    fan_nozzle.tag = 'fan_nozzle'
    
    # setup
    fan_nozzle.polytropic_efficiency = 1.0
    fan_nozzle.pressure_ratio        = 1.0    
    
    # add to network
    ductedfan.append(fan_nozzle)

    # ------------------------------------------------------------------
    #  Component 5 - Thrust
    # to compute thrust
    
    # instantiate
    thrust = SUAVE.Components.Energy.Processes.Thrust()       
    thrust.tag ='thrust'
    
    # setup
    thrust.total_design = 21191.50900196
    
    # add to network
    ductedfan.thrust    = thrust    

    #size the turbofan
    ducted_fan_sizing(ductedfan,0.5,10000.0)
    
    print("Design thrust ",ductedfan.design_thrust)
    print("Sealevel static thrust ",ductedfan.sealevel_static_thrust)
    
    results_design     = ductedfan(state_sizing)
    results_off_design = ductedfan(state_off_design)
    F                  = results_design.thrust_force_vector
    F_off_design       = results_off_design.thrust_force_vector
    
    # Test the model 
    # Specify the expected values
    expected = Data()
    expected.thrust = 21191.509001558181
    
    #error data function
    error =  Data()
    error.thrust_error = (F[0][0] -  expected.thrust)/expected.thrust
    print(error)
    
    for k,v in list(error.items()):
        assert(np.abs(v)<1e-6)    
        
    return
Example #4
0
def vehicle_setup(cruise_altitude):

    # ------------------------------------------------------------------
    #   Initialize the Vehicle
    # ------------------------------------------------------------------

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

    # ------------------------------------------------------------------
    #   Vehicle-level Properties
    # ------------------------------------------------------------------
    '''
    # mass properties
    vehicle.mass_properties.max_takeoff               = 92110. #use landing mass as 
    vehicle.mass_properties.operating_empty           = 34551. 
    vehicle.mass_properties.takeoff                   = 80721. 
    vehicle.mass_properties.max_zero_fuel             = 92110. #equivalent landing mass
    vehicle.mass_properties.cargo                     = 0.0 
    vehicle.mass_properties.max_payload               = 0.0 
    vehicle.mass_properties.max_fuel                  = 0.0
    '''
    
    # envelope properties
    vehicle.envelope.ultimate_load = 3.5
    vehicle.envelope.limit_load    = 1.5
    
    # basic parameters
    vehicle.reference_area         = 100.0
    vehicle.passengers             = 114
    vehicle.systems.control        = "partially powered"
    vehicle.systems.accessories    = "medium range"
    vehicle.w2h                    = 16.     * Units.meters    # Length from the mean aerodynamic center of wing to mean aerodynamic center of the horizontal tail
    vehicle.w2v                    = 20.     * Units.meters    # Length from the mean aerodynamic center of wing to mean aerodynamic center of the vertical tail
    # ------------------------------------------------------------------
    #   Main Wing
    # ------------------------------------------------------------------

    wing = SUAVE.Components.Wings.Wing()
    wing.tag = 'main_wing'

    wing.aspect_ratio            = 8.3
    wing.sweeps.quarter_chord    = 0.002 * Units.deg
    wing.thickness_to_chord      = 0.105
    wing.taper                   = 0.28
    wing.span_efficiency         = 1.0

    wing.spans.projected         = 28.81

    wing.chords.root             = 5.4
    wing.chords.tip              = 1.5185
    wing.chords.mean_aerodynamic = 3.8371

    wing.areas.reference         = 100.0
    wing.areas.wetted            = 2.0 * wing.areas.reference
    wing.areas.exposed           = 150.0
    wing.areas.affected          = 60.0

    wing.twists.root             = -0.311 * Units.degrees
    wing.twists.tip              = -0.315 * Units.degrees

    wing.origin                  = [00,0,0]
    wing.aerodynamic_center      = [0.914,0,0]

    wing.vertical                = False
    wing.symmetric               = True

    wing.dynamic_pressure_ratio  = 1.0

    # add to vehicle
    vehicle.append_component(wing)

    # ------------------------------------------------------------------
    #  Horizontal Stabilizer
    # ------------------------------------------------------------------

    wing = SUAVE.Components.Wings.Wing()
    wing.tag = 'horizontal_stabilizer'

    wing.aspect_ratio            = 5.5
    wing.sweeps.quarter_chord    = 0.002 * Units.deg
    wing.thickness_to_chord      = 0.11
    wing.taper                   = 0.11
    wing.span_efficiency         = 0.9

    wing.spans.projected         = 11.213

    wing.chords.root             = 3.6733
    wing.chords.tip              = 0.4040
    wing.chords.mean_aerodynamic = 2.4755

    wing.areas.reference         = 22.85
    wing.areas.wetted            = 45.71
    wing.areas.exposed           = 34.28
    wing.areas.affected          = 13.71

    wing.twists.root             = 0.0 * Units.degrees
    wing.twists.tip              = 0.0 * Units.degrees

    wing.origin                  = [50,0,0]
    wing.aerodynamic_center      = [16.9144, 0.0, 0.0]

    wing.vertical                = False
    wing.symmetric               = True

    wing.dynamic_pressure_ratio  = 0.9

    # add to vehicle
    vehicle.append_component(wing)

    # ------------------------------------------------------------------
    #   Vertical Stabilizer
    # ------------------------------------------------------------------

    wing = SUAVE.Components.Wings.Wing()
    wing.tag = 'vertical_stabilizer'

    wing.aspect_ratio            = 1.7      #
    wing.sweeps.quarter_chord    = 0.001 * Units.deg
    wing.thickness_to_chord      = 0.12
    wing.taper                   = 0.10
    wing.span_efficiency         = 0.9

    wing.spans.projected         = 4.6945     #

    wing.chords.root             = 5.0209
    wing.chords.tip              = 0.5020
    wing.chords.mean_aerodynamic = 3.3777

    wing.areas.reference         = 12.96
    wing.areas.wetted            = 25.92
    wing.areas.exposed           = 19.44
    wing.areas.affected          = 7.778

    wing.twists.root             = 0.0 * Units.degrees
    wing.twists.tip              = 0.0 * Units.degrees

    wing.origin                  = [0,0,0]
    wing.aerodynamic_center      = [0,0,0]

    wing.vertical                = True
    wing.symmetric               = False

    wing.dynamic_pressure_ratio  = 1.0

    # 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         = 1.5
    fuselage.fineness.tail         = 1.8

    fuselage.lengths.nose          = 4.5
    fuselage.lengths.tail          = 5.4
    fuselage.lengths.cabin         = 21.24675
    fuselage.lengths.total         = 31.14675
    fuselage.lengths.fore_space    = 0.
    fuselage.lengths.aft_space     = 0.

    fuselage.width                 = 3.0

    fuselage.heights.maximum       = 3.4    #
    fuselage.heights.at_quarter_length          = 3.4
    fuselage.heights.at_three_quarters_length   = 3.4
    fuselage.heights.at_wing_root_quarter_chord = 3.4

    fuselage.areas.side_projected  = 79.462
    fuselage.areas.wetted          = 288.521422366
    fuselage.areas.front_projected = 8.011

    fuselage.effective_diameter    = 3.2

    fuselage.differential_pressure = 10**5 * Units.pascal 

    # add to vehicle
    vehicle.append_component(fuselage)

    # ------------------------------------------------------------------
    #  Propulsion
    # ------------------------------------------------------------------
    
    atm = SUAVE.Analyses.Atmospheric.US_Standard_1976()
    
    conditions1 = atm.compute_values(0.)
    conditions2 = atm.compute_values(cruise_altitude)
    p1   = conditions1.pressure
    p2   = conditions2.pressure
    T1   = conditions1.temperature
    T2   = conditions2.temperature
    rho1 = conditions1.density
    rho2 = conditions2.density
    a1   = conditions1.speed_of_sound
    a2   = conditions2.speed_of_sound
    mu1  = conditions1.dynamic_viscosity
    mu2  = conditions2.dynamic_viscosity
    
    mach_number           = .729
    #Create Energy Network
    #create battery
    battery = SUAVE.Components.Energy.Storages.Batteries.Variable_Mass.Lithium_Air()
    battery.tag = 'battery'
   
    ducted_fan      = SUAVE.Components.Energy.Networks.Ducted_Fan()
    network         = SUAVE.Components.Energy.Networks.Battery_Ducted_Fan()
    working_fluid   = SUAVE.Attributes.Gases.Air

    #add working fluid to the network
    ducted_fan.working_fluid    = working_fluid
    
   
    #Component 1 : ram,  to convert freestream static to stagnation quantities
    ram = SUAVE.Components.Energy.Converters.Ram()
    ram.tag = 'ram'

    #add ram to the network
    ducted_fan.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 #	turbofan.fan_nozzle_pressure_ratio     = 0.98     #0.98

    #add inlet nozzle to the network
    ducted_fan.inlet_nozzle = inlet_nozzle


    #Component 8 :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.99

    #add the fan nozzle to the network
    ducted_fan.fan_nozzle = fan_nozzle



    #Component 9 : fan   
    fan = SUAVE.Components.Energy.Converters.Fan()   
    fan.tag = 'fan'

    fan.polytropic_efficiency = 0.93
    fan.pressure_ratio        = 1.5    

    #add the fan to the network
    ducted_fan.fan = fan    

    #Component 10 : thrust (to compute the thrust)
    thrust                               = SUAVE.Components.Energy.Processes.Thrust()  
    thrust.tag                           ='compute_thrust'
    thrust.total_design                  = 121979.18 # Preq*1.5/V_cruise 
    ducted_fan.thrust                    = thrust
    ducted_fan.tag                       ='ducted_fan'
    ducted_fan.number_of_engines         = 2.0    
    
    
    #compute conditions for engine
    conditions = SUAVE.Analyses.Mission.Segments.Conditions.Aerodynamics()            
    conditions.freestream.altitude           = np.atleast_1d(cruise_altitude)
    conditions.freestream.mach_number        = np.atleast_1d(mach_number)
    conditions.freestream.pressure           = np.atleast_1d(p2)
    conditions.freestream.temperature        = np.atleast_1d(T2)
    conditions.freestream.density            = np.atleast_1d(rho2)
    conditions.freestream.dynamic_viscosity  = np.atleast_1d(mu2)
    conditions.freestream.gravity            = np.atleast_1d(9.81)
    conditions.freestream.gamma              = np.atleast_1d(1.4)
    conditions.freestream.Cp                 = 1.4*287.87/(1.4-1)
    conditions.freestream.R                  = 287.87
    conditions.freestream.speed_of_sound     = np.atleast_1d(a2)
    conditions.freestream.velocity           = conditions.freestream.mach_number * conditions.freestream.speed_of_sound
            
    #size mass flow
    ducted_fan_sizing(ducted_fan, mach_number, cruise_altitude)
    #now size geometry
    compute_ducted_fan_geometry(ducted_fan, conditions)
    
    # ------------------------------------------------------------------
    #  Energy Network
    # ------------------------------------------------------------------ 
    
    #define the energy network
    net     = SUAVE.Components.Energy.Networks.Battery_Ducted_Fan()
    net.tag = 'network'
    
    net.propulsor = ducted_fan
    net.append(ducted_fan)
    net.battery = battery
    
    net.nacelle_diameter  = ducted_fan.nacelle_diameter
    net.engine_length     = ducted_fan.engine_length    
    net.number_of_engines = ducted_fan.number_of_engines
    net.motor_efficiency  =.95
    vehicle.propulsors.append(ducted_fan)
    vehicle.energy_network = net
    
    
    # ------------------------------------------------------------------
    #   Vehicle Definition Complete
    # ------------------------------------------------------------------
    

    return vehicle
Example #5
0
def vehicle_setup():
    """This is the full physical definition of the vehicle, and is designed to be independent of the
    analyses that are selected."""

    # ------------------------------------------------------------------
    #   Initialize the Vehicle
    # ------------------------------------------------------------------

    vehicle = SUAVE.Vehicle()
    vehicle.tag = 'Boeing_737-800'

    # ------------------------------------------------------------------
    #   Vehicle-level Properties
    # ------------------------------------------------------------------

    # Vehicle level mass properties
    # The maximum takeoff gross weight is used by a number of methods, most notably the weight
    # method. However, it does not directly inform mission analysis.
    vehicle.mass_properties.max_takeoff = 79015.8 * Units.kilogram
    # The takeoff weight is used to determine the weight of the vehicle at the start of the mission
    vehicle.mass_properties.takeoff = 79015.8 * Units.kilogram
    # Operating empty may be used by various weight methods or other methods. Importantly, it does
    # not constrain the mission analysis directly, meaning that the vehicle weight in a mission
    # can drop below this value if more fuel is needed than is available.
    vehicle.mass_properties.operating_empty = 62746.4 * Units.kilogram
    # The maximum zero fuel weight is also used by methods such as weights
    vehicle.mass_properties.max_zero_fuel = 62732.0 * Units.kilogram
    # Cargo weight typically feeds directly into weights output and does not affect the mission
    vehicle.mass_properties.cargo = 10000. * Units.kilogram

    # Envelope properties
    # These values are typical FAR values for a transport of this type
    vehicle.envelope.ultimate_load = 3.75
    vehicle.envelope.limit_load = 2.5

    # Vehicle level parameters
    # The vehicle reference area typically matches the main wing reference area
    vehicle.reference_area = 124.862 * Units['meters**2']

    # Number of passengers, control settings, and accessories settings are used by the weights
    # methods
    vehicle.passengers = 170
    vehicle.systems.control = "fully powered"
    vehicle.systems.accessories = "medium range"

    # ------------------------------------------------------------------
    #  Landing Gear
    # ------------------------------------------------------------------

    # The settings here can be used for noise analysis, but are not used in this tutorial
    landing_gear = SUAVE.Components.Landing_Gear.Landing_Gear()
    landing_gear.tag = "main_landing_gear"

    landing_gear.main_tire_diameter = 1.12000 * Units.m
    landing_gear.nose_tire_diameter = 0.6858 * Units.m
    landing_gear.main_strut_length = 1.8 * Units.m
    landing_gear.nose_strut_length = 1.3 * Units.m
    landing_gear.main_units = 2  # Number of main landing gear
    landing_gear.nose_units = 1  # Number of nose landing gear
    landing_gear.main_wheels = 2  # Number of wheels on the main landing gear
    landing_gear.nose_wheels = 2  # Number of wheels on the nose landing gear
    vehicle.landing_gear = landing_gear

    # ------------------------------------------------------------------
    #   Main Wing
    # ------------------------------------------------------------------

    # This main wing is approximated as a simple trapezoid. A segmented wing can also be created if
    # desired. Segmented wings appear in later tutorials, and a version of the 737 with segmented
    # wings can be found in the SUAVE testing scripts.

    # SUAVE allows conflicting geometric values to be set in terms of items such as aspect ratio
    # when compared with span and reference area. Sizing scripts may be used to enforce
    # consistency if desired.

    wing = SUAVE.Components.Wings.Main_Wing()
    wing.tag = 'main_wing'

    wing.aspect_ratio = 10.18
    # Quarter chord sweep is used as the driving sweep in most of the low fidelity analysis methods.
    # If a different known value (such as leading edge sweep) is given, it should be converted to
    # quarter chord sweep and added here. In some cases leading edge sweep will be used directly as
    # well, and can be entered here too.

    wing.sweeps.quarter_chord = 25 * Units.deg
    wing.thickness_to_chord = 0.1
    wing.taper = 0.1
    wing.spans.projected = 34.32 * Units.meter
    wing.chords.root = 7.760 * Units.meter
    wing.chords.tip = 0.782 * Units.meter
    wing.chords.mean_aerodynamic = 4.235 * Units.meter
    wing.areas.reference = 124.862 * Units['meters**2']
    wing.twists.root = 4.0 * Units.degrees
    wing.twists.tip = 0.0 * Units.degrees
    wing.origin = [[13.61, 0, -1.27]] * Units.meter
    wing.vertical = False
    wing.symmetric = True

    # The high lift flag controls aspects of maximum lift coefficient calculations
    wing.high_lift = True
    # The dynamic pressure ratio is used in stability calculations
    wing.dynamic_pressure_ratio = 1.0

    # ------------------------------------------------------------------
    #   Main Wing Control Surfaces
    # ------------------------------------------------------------------

    # Information in this section is used for high lift calculations and when conversion to AVL
    # is desired.

    # Deflections will typically be specified separately in individual vehicle configurations.

    flap = SUAVE.Components.Wings.Control_Surfaces.Flap()
    flap.tag = 'flap'
    flap.span_fraction_start = 0.20
    flap.span_fraction_end = 0.70
    flap.deflection = 0.0 * Units.degrees
    # Flap configuration types are used in computing maximum CL and noise
    flap.configuration_type = 'double_slotted'
    flap.chord_fraction = 0.30
    wing.append_control_surface(flap)

    slat = SUAVE.Components.Wings.Control_Surfaces.Slat()
    slat.tag = 'slat'
    slat.span_fraction_start = 0.324
    slat.span_fraction_end = 0.963
    slat.deflection = 0.0 * Units.degrees
    slat.chord_fraction = 0.1
    wing.append_control_surface(slat)

    aileron = SUAVE.Components.Wings.Control_Surfaces.Aileron()
    aileron.tag = 'aileron'
    aileron.span_fraction_start = 0.7
    aileron.span_fraction_end = 0.963
    aileron.deflection = 0.0 * Units.degrees
    aileron.chord_fraction = 0.16
    wing.append_control_surface(aileron)

    # Add to vehicle
    vehicle.append_component(wing)

    # ------------------------------------------------------------------
    #  Horizontal Stabilizer
    # ------------------------------------------------------------------

    wing = SUAVE.Components.Wings.Horizontal_Tail()
    wing.tag = 'horizontal_stabilizer'

    wing.aspect_ratio = 6.16
    wing.sweeps.quarter_chord = 40.0 * Units.deg
    wing.thickness_to_chord = 0.08
    wing.taper = 0.2
    wing.spans.projected = 14.2 * Units.meter
    wing.chords.root = 4.7 * Units.meter
    wing.chords.tip = 0.955 * Units.meter
    wing.chords.mean_aerodynamic = 3.0 * Units.meter
    wing.areas.reference = 32.488 * Units['meters**2']
    wing.twists.root = 3.0 * Units.degrees
    wing.twists.tip = 3.0 * Units.degrees
    wing.origin = [[32.83 * Units.meter, 0, 1.14 * Units.meter]]
    wing.vertical = False
    wing.symmetric = True
    wing.dynamic_pressure_ratio = 0.9

    # Add to vehicle
    vehicle.append_component(wing)

    # ------------------------------------------------------------------
    #   Vertical Stabilizer
    # ------------------------------------------------------------------

    wing = SUAVE.Components.Wings.Vertical_Tail()
    wing.tag = 'vertical_stabilizer'

    wing.aspect_ratio = 1.91
    wing.sweeps.quarter_chord = 25. * Units.deg
    wing.thickness_to_chord = 0.08
    wing.taper = 0.25
    wing.spans.projected = 7.777 * Units.meter
    wing.chords.root = 8.19 * Units.meter
    wing.chords.tip = 0.95 * Units.meter
    wing.chords.mean_aerodynamic = 4.0 * Units.meter
    wing.areas.reference = 27.316 * Units['meters**2']
    wing.twists.root = 0.0 * Units.degrees
    wing.twists.tip = 0.0 * Units.degrees
    wing.origin = [[28.79 * Units.meter, 0, 1.54 * Units.meter]]  # meters
    wing.vertical = True
    wing.symmetric = False
    # The t tail flag is used in weights calculations
    wing.t_tail = False
    wing.dynamic_pressure_ratio = 1.0

    # Add to vehicle
    vehicle.append_component(wing)

    # ------------------------------------------------------------------
    #  Fuselage
    # ------------------------------------------------------------------

    fuselage = SUAVE.Components.Fuselages.Fuselage()
    fuselage.tag = 'fuselage'

    # Number of coach seats is used in some weights methods
    fuselage.number_coach_seats = vehicle.passengers
    # The seats abreast can be used along with seat pitch and the number of coach seats to
    # determine the length of the cabin if desired.
    fuselage.seats_abreast = 6
    fuselage.seat_pitch = 1 * Units.meter
    # Fineness ratios are used to determine VLM fuselage shape and sections to use in OpenVSP
    # output
    fuselage.fineness.nose = 1.6
    fuselage.fineness.tail = 2.
    # Nose and tail lengths are used in the VLM setup
    fuselage.lengths.nose = 6.4 * Units.meter
    fuselage.lengths.tail = 8.0 * Units.meter
    fuselage.lengths.total = 38.02 * Units.meter
    # Fore and aft space are added to the cabin length if the fuselage is sized based on
    # number of seats
    fuselage.lengths.fore_space = 6. * Units.meter
    fuselage.lengths.aft_space = 5. * Units.meter
    fuselage.width = 3.74 * Units.meter
    fuselage.heights.maximum = 3.74 * Units.meter
    fuselage.effective_diameter = 3.74 * Units.meter
    fuselage.areas.side_projected = 142.1948 * Units['meters**2']
    fuselage.areas.wetted = 446.718 * Units['meters**2']
    fuselage.areas.front_projected = 12.57 * Units['meters**2']
    # Maximum differential pressure between the cabin and the atmosphere
    fuselage.differential_pressure = 5.0e4 * Units.pascal

    # Heights at different longitudinal locations are used in stability calculations and
    # in output to OpenVSP
    fuselage.heights.at_quarter_length = 3.74 * Units.meter
    fuselage.heights.at_three_quarters_length = 3.65 * Units.meter
    fuselage.heights.at_wing_root_quarter_chord = 3.74 * Units.meter

    # add to vehicle
    vehicle.append_component(fuselage)

    # ------------------------------------------------------------------
    #   Nacelles
    # ------------------------------------------------------------------
    nacelle = SUAVE.Components.Nacelles.Nacelle()
    nacelle.tag = 'nacelle_1'
    nacelle.length = 2.71
    nacelle.inlet_diameter = 1.90
    nacelle.diameter = 2.05
    nacelle.areas.wetted = 1.1 * np.pi * nacelle.diameter * nacelle.length
    nacelle.origin = [[13.72, -4.86, -1.9]]
    nacelle.flow_through = True
    nacelle_airfoil = SUAVE.Components.Airfoils.Airfoil()
    nacelle_airfoil.naca_4_series_airfoil = '2410'
    nacelle.append_airfoil(nacelle_airfoil)

    nacelle_2 = deepcopy(nacelle)
    nacelle_2.tag = 'nacelle_2'
    nacelle_2.origin = [[13.72, 4.86, -1.9]]

    vehicle.append_component(nacelle)
    vehicle.append_component(nacelle_2)

    # ------------------------------------------------------------------
    #   Turboelectric HTS Ducted Fan Network
    # ------------------------------------------------------------------

    # Instantiate the Turboelectric HTS Ducted Fan Network
    # This also instantiates the component parts of the efan network, then below each part has its properties modified so they are no longer the default properties as created here at instantiation.
    efan = Turboelectric_HTS_Ducted_Fan()
    efan.tag = 'turbo_fan'

    # Outline of Turboelectric drivetrain components. These are populated below.
    # 1. Propulsor     Ducted_fan
    #   1.1 Ram
    #   1.2 Inlet Nozzle
    #   1.3 Fan Nozzle
    #   1.4 Fan
    #   1.5 Thrust
    # 2. Motor
    # 3. Powersupply
    # 4. ESC
    # 5. Rotor
    # 6. Lead
    # 7. CCS
    # 8. Cryocooler
    # 9. Heat Exchanger
    # The components are then sized

    # ------------------------------------------------------------------
    #Component 1 - Ducted Fan

    efan.ducted_fan = SUAVE.Components.Energy.Networks.Ducted_Fan()
    efan.ducted_fan.tag = 'ducted_fan'
    efan.ducted_fan.number_of_engines = 12.
    efan.number_of_engines = efan.ducted_fan.number_of_engines
    efan.ducted_fan.engine_length = 1.1 * Units.meter

    # Positioning variables for the propulsor locations -
    xStart = 15.0
    xSpace = 1.0
    yStart = 3.0
    ySpace = 1.8
    efan.ducted_fan.origin = [
        [xStart + xSpace * 5, -(yStart + ySpace * 5), -2.0],
        [xStart + xSpace * 4, -(yStart + ySpace * 4), -2.0],
        [xStart + xSpace * 3, -(yStart + ySpace * 3), -2.0],
        [xStart + xSpace * 2, -(yStart + ySpace * 2), -2.0],
        [xStart + xSpace * 1, -(yStart + ySpace * 1), -2.0],
        [xStart + xSpace * 0, -(yStart + ySpace * 0), -2.0],
        [xStart + xSpace * 5, (yStart + ySpace * 5), -2.0],
        [xStart + xSpace * 4, (yStart + ySpace * 4), -2.0],
        [xStart + xSpace * 3, (yStart + ySpace * 3), -2.0],
        [xStart + xSpace * 2, (yStart + ySpace * 2), -2.0],
        [xStart + xSpace * 1, (yStart + ySpace * 1), -2.0],
        [xStart + xSpace * 0, (yStart + ySpace * 0), -2.0]
    ]  # meters

    # copy the ducted fan details to the turboelectric ducted fan network to enable drag calculations
    efan.engine_length = efan.ducted_fan.engine_length
    efan.origin = efan.ducted_fan.origin

    # working fluid
    efan.ducted_fan.working_fluid = SUAVE.Attributes.Gases.Air()

    # ------------------------------------------------------------------
    #   Component 1.1 - Ram

    # to convert freestream static to stagnation quantities
    # instantiate
    ram = SUAVE.Components.Energy.Converters.Ram()
    ram.tag = 'ram'

    # add to the network
    efan.ducted_fan.append(ram)

    # ------------------------------------------------------------------
    #  Component 1.2 - Inlet Nozzle

    # instantiate
    inlet_nozzle = SUAVE.Components.Energy.Converters.Compression_Nozzle()
    inlet_nozzle.tag = 'inlet_nozzle'

    # setup
    inlet_nozzle.polytropic_efficiency = 0.98
    inlet_nozzle.pressure_ratio = 0.98

    # add to network
    efan.ducted_fan.append(inlet_nozzle)

    # ------------------------------------------------------------------
    #  Component 1.3 - Fan Nozzle

    # instantiate
    fan_nozzle = SUAVE.Components.Energy.Converters.Expansion_Nozzle()
    fan_nozzle.tag = 'fan_nozzle'

    # setup
    fan_nozzle.polytropic_efficiency = 0.95
    fan_nozzle.pressure_ratio = 0.99

    # add to network
    efan.ducted_fan.append(fan_nozzle)

    # ------------------------------------------------------------------
    #  Component 1.4 - Fan

    # instantiate
    fan = SUAVE.Components.Energy.Converters.Fan()
    fan.tag = 'fan'

    # setup
    fan.polytropic_efficiency = 0.93
    fan.pressure_ratio = 1.7

    # add to network
    efan.ducted_fan.append(fan)

    # ------------------------------------------------------------------
    # Component 1.5 : thrust

    # To compute the thrust
    thrust = SUAVE.Components.Energy.Processes.Thrust()
    thrust.tag = 'compute_thrust'

    # total design thrust (includes all the propulsors)
    thrust.total_design = 2. * 24000. * Units.N  #Newtons

    # design sizing conditions
    altitude = 35000.0 * Units.ft
    mach_number = 0.78
    isa_deviation = 0.

    # add to network
    efan.ducted_fan.thrust = thrust
    # ------------------------------------------------------------------
    # Component 2 : HTS motor

    efan.motor = SUAVE.Components.Energy.Converters.Motor_Lo_Fid()
    efan.motor.tag = 'motor'
    # number_of_motors is not used as the motor count is assumed to match the engine count

    # Set the origin of each motor to match its ducted fan
    efan.motor.origin = efan.ducted_fan.origin
    efan.motor.gear_ratio = 1.0
    efan.motor.gearbox_efficiency = 1.0
    efan.motor.motor_efficiency = 0.96

    # ------------------------------------------------------------------
    #  Component 3 - Powersupply

    efan.powersupply = SUAVE.Components.Energy.Converters.Turboelectric()
    efan.powersupply.tag = 'powersupply'

    efan.number_of_powersupplies = 2.
    efan.powersupply.propellant = SUAVE.Attributes.Propellants.Jet_A()
    efan.powersupply.oxidizer = Air()
    efan.powersupply.number_of_engines = 2.0  # number of turboelectric machines, not propulsors
    efan.powersupply.efficiency = .37  # Approximate average gross efficiency across the product range.
    efan.powersupply.volume = 2.36 * Units.m**3.  # 3m long from RB211 datasheet. 1m estimated radius.
    efan.powersupply.rated_power = 37400.0 * Units.kW
    efan.powersupply.mass_properties.mass = 2500.0 * Units.kg  # 2.5 tonnes from Rolls Royce RB211 datasheet 2013.
    efan.powersupply.specific_power = efan.powersupply.rated_power / efan.powersupply.mass_properties.mass
    efan.powersupply.mass_density = efan.powersupply.mass_properties.mass / efan.powersupply.volume

    # ------------------------------------------------------------------
    #  Component 4 - Electronic Speed Controller (ESC)

    efan.esc = SUAVE.Components.Energy.Distributors.HTS_DC_Supply(
    )  # Could make this where the ESC is defined as a Siemens SD104
    efan.esc.tag = 'esc'

    efan.esc.efficiency = 0.95  # Siemens SD104 SiC Power Electronicss reported to be this efficient

    # ------------------------------------------------------------------
    #  Component 5 - HTS rotor (part of the propulsor motor)

    efan.rotor = SUAVE.Components.Energy.Converters.Motor_HTS_Rotor()
    efan.rotor.tag = 'rotor'

    efan.rotor.temperature = 50.0  # [K]
    efan.rotor.skin_temp = 300.0  # [K]       Temp of rotor outer surface is not ambient
    efan.rotor.current = 1000.0  # [A]       Most of the cryoload will scale with this number if not using HTS Dynamo
    efan.rotor.resistance = 0.0001  # [ohm]     20 x 100 nOhm joints should be possible (2uOhm total) so 1mOhm is an overestimation.
    efan.rotor.number_of_engines = efan.ducted_fan.number_of_engines
    efan.rotor.length = 0.573 * Units.meter  # From paper: DOI:10.2514/6.2019-4517 Would be good to estimate this from power instead.
    efan.rotor.diameter = 0.310 * Units.meter  # From paper: DOI:10.2514/6.2019-4517 Would be good to estimate this from power instead.
    rotor_end_area = np.pi * (efan.rotor.diameter / 2.0)**2.0
    rotor_end_circumference = np.pi * efan.rotor.diameter
    efan.rotor.surface_area = 2.0 * rotor_end_area + efan.rotor.length * rotor_end_circumference
    efan.rotor.R_value = 125.0  # [K.m2/W]  2.0 W/m2 based on experience at Robinson Research

    # ------------------------------------------------------------------
    #  Component 6 - Copper Supply Leads of propulsion motor rotors

    efan.lead = SUAVE.Components.Energy.Distributors.Cryogenic_Lead()
    efan.lead.tag = 'lead'

    copper = Copper()
    efan.lead.cold_temp = efan.rotor.temperature  # [K]
    efan.lead.hot_temp = efan.rotor.skin_temp  # [K]
    efan.lead.current = efan.rotor.current  # [A]
    efan.lead.length = 0.3  # [m]
    efan.lead.material = copper
    efan.leads = efan.ducted_fan.number_of_engines * 2.0  # Each motor has two leads to make a complete circuit

    # ------------------------------------------------------------------
    #  Component 7 - Rotor Constant Current Supply (CCS)

    efan.ccs = SUAVE.Components.Energy.Distributors.HTS_DC_Supply()
    efan.ccs.tag = 'ccs'

    efan.ccs.efficiency = 0.95  # Siemens SD104 SiC Power Electronics reported to be this efficient
    # ------------------------------------------------------------------
    #  Component 8 - Cryocooler, to cool the HTS Rotor

    efan.cryocooler = SUAVE.Components.Energy.Cooling.Cryocooler()
    efan.cryocooler.tag = 'cryocooler'

    efan.cryocooler.cooler_type = 'GM'
    efan.cryocooler.min_cryo_temp = efan.rotor.temperature  # [K]
    efan.cryocooler.ambient_temp = 300.0  # [K]

    # ------------------------------------------------------------------
    #  Component 9 - Cryogenic Heat Exchanger, to cool the HTS Rotor
    efan.heat_exchanger = SUAVE.Components.Energy.Cooling.Cryogenic_Heat_Exchanger(
    )
    efan.heat_exchanger.tag = 'heat_exchanger'

    efan.heat_exchanger.cryogen = SUAVE.Attributes.Cryogens.Liquid_H2()
    efan.heat_exchanger.cryogen_inlet_temperature = 20.0  # [K]
    efan.heat_exchanger.cryogen_outlet_temperature = efan.rotor.temperature  # [K]
    efan.heat_exchanger.cryogen_pressure = 100000.0  # [Pa]
    efan.heat_exchanger.cryogen_is_fuel = 0.0

    # Sizing Conditions. The cryocooler may have greater power requirement at low altitude as the cooling requirement may be static during the flight but the ambient temperature may change.
    cryo_temp = 50.0  # [K]
    amb_temp = 300.0  # [K]

    # ------------------------------------------------------------------
    # Powertrain Sizing

    ducted_fan_sizing(efan.ducted_fan, mach_number, altitude)

    serial_HTS_turboelectric_sizing(efan,
                                    mach_number,
                                    altitude,
                                    cryo_cold_temp=cryo_temp,
                                    cryo_amb_temp=amb_temp)

    # add turboelectric network to the vehicle
    vehicle.append_component(efan)

    # ------------------------------------------------------------------
    #   Vehicle Definition Complete
    # ------------------------------------------------------------------

    return vehicle