Skip to content

Commit

Permalink
Merge pull request #21 from suavecode/feature-2point3
Browse files Browse the repository at this point in the history
Feature 2point3
  • Loading branch information
planes authored Dec 26, 2020
2 parents dbc8e40 + 14127a3 commit 758cbf0
Show file tree
Hide file tree
Showing 11 changed files with 69 additions and 134 deletions.
7 changes: 7 additions & 0 deletions Regional_Jet_Optimization/Analyses.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
# ----------------------------------------------------------------------

import SUAVE
from SUAVE.Core import Units

import numpy as np

# ----------------------------------------------------------------------
# Setup Analyses
Expand Down Expand Up @@ -55,6 +58,10 @@ def base(vehicle):
# Aerodynamics Analysis
aerodynamics = SUAVE.Analyses.Aerodynamics.Fidelity_Zero()
aerodynamics.geometry = vehicle
aerodynamics.settings.number_spanwise_vortices = 5
aerodynamics.settings.number_chordwise_vortices = 1
aerodynamics.process.compute.lift.inviscid_wings.training.angle_of_attack = np.array([[-5., 0.0, 5.0, 10.0, 75.]]).T * Units.deg
aerodynamics.process.compute.lift.inviscid_wings.training.Mach = np.array([[0.0, 0.2, 0.5, 0.70, 0.80, 0.9, 1.3, 1.35, 1.5, 2.0]]).T
analyses.append(aerodynamics)

# ------------------------------------------------------------------
Expand Down
27 changes: 9 additions & 18 deletions Regional_Jet_Optimization/Optimize.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,19 @@
# Run the whole thing
# ----------------------------------------------------------------------
def main():

problem = setup()

## Base Input Values
#output = problem.objective()
output = problem.objective()

## Uncomment to view contours of the design space
#variable_sweep(problem)

## Uncomment for the first optimization
# Uncomment for the first optimization
output = scipy_setup.SciPy_Solve(problem,solver='SLSQP')
print (output)

## Uncomment these lines when you want to start an optimization problem from a different initial guess
#inputs = [1.28, 1.38]
#scaling = problem.optimization_problem.inputs[:,3] #have to rescale inputs to start problem from here
#scaled_inputs = np.multiply(inputs,scaling)
#problem.optimization_problem.inputs[:,1] = scaled_inputs
#output = scipy_setup.SciPy_Solve(problem,solver='SLSQP')
#print output


print('fuel burn = ', problem.summary.base_mission_fuelburn)
print('fuel margin = ', problem.all_constraints())

Expand All @@ -64,17 +57,16 @@ def setup():
# Inputs
# -------------------------------------------------------------------

# [ tag , initial, (lb,ub) , scaling , units ]
# [ tag , initial, (lb , ub) , scaling , units ]
problem.inputs = np.array([
[ 'wing_area' , 100 , ( 90. , 130. ) , 100. , Units.meter**2],
[ 'cruise_altitude' , 11 , ( 9 , 14. ) , 10. , Units.km],
[ 'wing_area' , 92 , ( 50. , 130. ) , 100. , Units.meter**2],
[ 'cruise_altitude' , 8 , ( 6. , 12. ) , 10. , Units.km],
])

# -------------------------------------------------------------------
# Objective
# -------------------------------------------------------------------

# throw an error if the user isn't specific about wildcards
# [ tag, scaling, units ]
problem.objective = np.array([
[ 'fuel_burn', 10000, Units.kg ]
Expand Down Expand Up @@ -137,19 +129,18 @@ def variable_sweep(problem):
objective = outputs.objective
constraints = outputs.constraint_val
plt.figure(0)
CS = plt.contourf(inputs[0,:],inputs[1,:], objective, 20, linewidths=2)
CS = plt.contourf(inputs[0,:],inputs[1,:], objective, 20, linewidths=2,cmap='jet')
cbar = plt.colorbar(CS)

cbar.ax.set_ylabel('fuel burn (kg)')
CS_const = plt.contour(inputs[0,:],inputs[1,:], constraints[0,:,:])
CS_const = plt.contour(inputs[0,:],inputs[1,:], constraints[0,:,:],cmap='jet')
plt.clabel(CS_const, inline=1, fontsize=10)
cbar = plt.colorbar(CS_const)
cbar.ax.set_ylabel('fuel margin')

plt.xlabel('Wing Area (m^2)')
plt.ylabel('Cruise Altitude (km)')

plt.legend(loc='upper left')
plt.show(block=True)

return
Expand Down
86 changes: 10 additions & 76 deletions Regional_Jet_Optimization/Procedure.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ def setup():
def find_target_range(nexus,mission):

segments = mission.segments
cruise_altitude = mission.segments['climb_5'].altitude_end
climb_1 = segments['climb_1']
climb_2 = segments['climb_2']
climb_3 = segments['climb_3']
Expand Down Expand Up @@ -139,55 +138,6 @@ def simple_sizing(nexus):
turbofan_sizing(config.propulsors['turbofan'], mach_number = mach_number, altitude = altitude)
compute_turbofan_geometry(config.propulsors['turbofan'], conditions)


# ------------------------------------------------------------------
# Landing Configuration
# ------------------------------------------------------------------
landing = nexus.vehicle_configurations.landing
state = Data()
state.conditions = Data()
state.conditions.freestream = Data()

# landing weight
landing.mass_properties.landing = 0.85 * config.mass_properties.takeoff

# Landing CL_max
altitude = nexus.missions.base.segments[-1].altitude_end
atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976()
p, T, rho, a, mu = atmosphere.compute_values(altitude)
state.conditions.freestream.velocity = nexus.missions.base.segments['descent_3'].air_speed
state.conditions.freestream.density = rho
state.conditions.freestream.dynamic_viscosity = mu/rho
settings = Data()
settings.maximum_lift_coefficient_factor = 1.0
CL_max_landing, CDi = compute_max_lift_coeff(state,settings,landing)
landing.maximum_lift_coefficient = CL_max_landing


#Takeoff CL_max
takeoff = nexus.vehicle_configurations.takeoff
altitude = nexus.missions.base.airport.altitude
atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976()
p, T, rho, a, mu = atmosphere.compute_values(altitude)
state.conditions.freestream.velocity = nexus.missions.base.segments.climb_1.air_speed
state.conditions.freestream.density = rho
state.conditions.freestream.dynamic_viscosity = mu/rho
settings.maximum_lift_coefficient_factor = 1.0
max_CL_takeoff,CDi = compute_max_lift_coeff(state,settings,takeoff)
takeoff.maximum_lift_coefficient = max_CL_takeoff

#Base config CL_max
base = nexus.vehicle_configurations.base
altitude = nexus.missions.base.airport.altitude
atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976()
p, T, rho, a, mu = atmosphere.compute_values(altitude)
state.conditions.freestream.velocity = nexus.missions.base.segments.climb_1.air_speed
state.conditions.freestream.density = rho
state.conditions.freestream.dynamic_viscosity = mu/rho
settings.maximum_lift_coefficient_factor = 1.0
max_CL_base,CDi = compute_max_lift_coeff(state,settings,landing)
base.maximum_lift_coefficient = max_CL_base

return nexus

# ----------------------------------------------------------------------
Expand All @@ -198,17 +148,13 @@ def weight(nexus):
vehicle=nexus.vehicle_configurations.base

# weight analysis
weights = nexus.analyses.base.weights.evaluate()
weights = nexus.analyses.cruise.weights.evaluate()
weights = nexus.analyses.base.weights.evaluate(method="SUAVE")
weights = nexus.analyses.cruise.weights.evaluate(method="SUAVE")
vehicle.mass_properties.breakdown = weights
weights = nexus.analyses.landing.weights.evaluate()
weights = nexus.analyses.takeoff.weights.evaluate()
weights = nexus.analyses.short_field_takeoff.weights.evaluate()

for config in nexus.vehicle_configurations:
config.mass_properties.zero_fuel_center_of_gravity = vehicle.mass_properties.zero_fuel_center_of_gravity
config.fuel = vehicle.fuel

weights = nexus.analyses.landing.weights.evaluate(method="SUAVE")
weights = nexus.analyses.takeoff.weights.evaluate(method="SUAVE")
weights = nexus.analyses.short_field_takeoff.weights.evaluate(method="SUAVE")

return nexus

# ----------------------------------------------------------------------
Expand All @@ -231,16 +177,7 @@ def post_process(nexus):
vehicle = nexus.vehicle_configurations.base
results = nexus.results
summary = nexus.summary
missions = nexus.missions
nexus.total_number_of_iterations +=1
# Static stability calculations
CMA = -10.
for segment in results.base.segments.values():
max_CMA = np.max(segment.conditions.stability.static.Cm_alpha[:,0])
if max_CMA > CMA:
CMA = max_CMA

summary.static_stability = CMA

#throttle in design mission
max_throttle = 0
Expand All @@ -252,18 +189,15 @@ def post_process(nexus):
summary.max_throttle = max_throttle

# Fuel margin and base fuel calculations
operating_empty = vehicle.mass_properties.operating_empty
payload = vehicle.mass_properties.breakdown.payload
design_landing_weight = results.base.segments[-1].conditions.weights.total_mass[-1]
design_takeoff_weight = vehicle.mass_properties.takeoff
max_takeoff_weight = nexus.vehicle_configurations.takeoff.mass_properties.max_takeoff
zero_fuel_weight = payload+operating_empty
zero_fuel_weight = vehicle.mass_properties.breakdown.zero_fuel_weight

summary.max_zero_fuel_margin = (design_landing_weight - zero_fuel_weight)/zero_fuel_weight
summary.base_mission_fuelburn = design_takeoff_weight - results.base.segments['descent_3'].conditions.weights.total_mass[-1]
summary.max_zero_fuel_margin = (design_landing_weight - zero_fuel_weight)/zero_fuel_weight
summary.base_mission_fuelburn = design_takeoff_weight - results.base.segments['descent_3'].conditions.weights.total_mass[-1]

#when you run want to output results to a file
filename = 'results.txt'
write_optimization_outputs(nexus, filename)

return nexus
9 changes: 3 additions & 6 deletions Regional_Jet_Optimization/Vehicles.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ def base_setup():
# Vehicle-level Properties
# ------------------------------------------------------------------

# mass properties (http://www.embraercommercialaviation.com/AircraftPDF/E190_Weights.pdf)
vehicle.mass_properties.max_takeoff = 51800. # kg
vehicle.mass_properties.operating_empty = 27837. # kg
vehicle.mass_properties.takeoff = 51800. # kg
Expand All @@ -47,9 +46,6 @@ def base_setup():
vehicle.mass_properties.max_fuel = 12971. # kg
vehicle.mass_properties.cargo = 0.0 # kg

vehicle.mass_properties.center_of_gravity = [[16.8, 0, 1.6]]
vehicle.mass_properties.moments_of_inertia.tensor = [[10 ** 5, 0, 0],[0, 10 ** 6, 0,],[0,0, 10 ** 7]]

# envelope properties
vehicle.envelope.ultimate_load = 3.5
vehicle.envelope.limit_load = 1.5
Expand Down Expand Up @@ -217,10 +213,11 @@ def base_setup():
gt_engine.inlet_diameter = 2.0

#compute engine areas)
Amax = (np.pi/4.)*gt_engine.nacelle_diameter**2.
Awet = 1.1*np.pi*gt_engine.nacelle_diameter*gt_engine.engine_length # 1.1 is simple coefficient

#Assign engine area
gt_engine.areas.wetted = Awet

#set the working fluid for the network
working_fluid = SUAVE.Attributes.Gases.Air()

Expand Down Expand Up @@ -320,7 +317,7 @@ def base_setup():
#design sizing conditions
altitude = 35000.0*Units.ft
mach_number = 0.78
isa_deviation = 0.

# add thrust to the network
gt_engine.thrust = thrust

Expand Down
6 changes: 6 additions & 0 deletions Solar_UAV_Optimization/Analyses.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
# ----------------------------------------------------------------------

import SUAVE
from SUAVE.Core import Units
import numpy as np

# ----------------------------------------------------------------------
# Setup Analyses
Expand Down Expand Up @@ -54,6 +56,10 @@ def base(vehicle):
# ------------------------------------------------------------------
aerodynamics = SUAVE.Analyses.Aerodynamics.Fidelity_Zero()
aerodynamics.geometry = vehicle
aerodynamics.settings.number_spanwise_vortices = 10
aerodynamics.settings.number_chordwise_vortices = 2
aerodynamics.process.compute.lift.inviscid_wings.training.angle_of_attack = np.array([[-5., 0.0, 5.0, 10.0, 75.]]).T * Units.deg
aerodynamics.process.compute.lift.inviscid_wings.training.Mach = np.array([[0.0, 0.2, 0.3, 0.9, 1.3, 1.35, 1.5, 2.0]]).T
analyses.append(aerodynamics)

# ------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion Solar_UAV_Optimization/Missions.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def mission(analyses,vehicle):
# connect vehicle configuration
segment.analyses.extend(analyses.base)

# segment attributes
# segment attributes
segment.state.numerics.number_control_points = 50
segment.dynamic_pressure = 115.0 * Units.pascals
segment.start_time = time.strptime("Tue, Jun 21 11:00:00 2020", "%a, %b %d %H:%M:%S %Y",)
Expand Down
15 changes: 9 additions & 6 deletions Solar_UAV_Optimization/Optimize.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import SUAVE.Optimization.Package_Setups.scipy_setup as scipy_setup
import SUAVE.Optimization.Package_Setups.pyopt_setup as pyopt_setup
from SUAVE.Optimization.Nexus import Nexus
import pylab as plt


# ----------------------------------------------------------------------
# Run the whole thing
Expand Down Expand Up @@ -48,11 +50,11 @@ def setup():

# [ tag , initial, [lb,ub], scaling, units ]
problem.inputs = np.array([
[ 'wing_area' , 0.62, ( 0.1, 1.5 ), 0.5, Units.meter ],
[ 'aspect_ratio' , 13.5, ( 5.0, 20.0 ), 10.0, Units.less ],
[ 'dynamic_pressure', 115.0, ( 1.0, 2000.0 ), 125.0, Units.pascals ],
[ 'solar_ratio' , 0.0, ( 0.0, 0.97), 1.0, Units.less ],
[ 'kv' , 900.0, ( 10.0, 1500.0 ), 800.0, Units['rpm/volt']],
[ 'wing_area' , 0.5, ( 0.1, 1.5 ), 0.5, Units.meter ],
[ 'aspect_ratio' , 10.0, ( 5.0, 20.0 ), 10.0, Units.less ],
[ 'dynamic_pressure', 125.0, ( 1.0, 2000.0 ), 125.0, Units.pascals ],
[ 'solar_ratio' , 0.0, ( 0.0, 0.97), 1.0, Units.less ],
[ 'kv' , 800.0, ( 10.0, 10000.0 ), 800.0, Units['rpm/volt']],
])

# -------------------------------------------------------------------
Expand Down Expand Up @@ -120,4 +122,5 @@ def setup():
return nexus

if __name__ == '__main__':
main()
main()
plt.show()
20 changes: 10 additions & 10 deletions Solar_UAV_Optimization/Vehicles.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ def base_setup():
# Vehicle-level Properties
# ------------------------------------------------------------------
# mass properties
vehicle.mass_properties.takeoff = 6.75 * Units.kg
vehicle.mass_properties.operating_empty = 6.75 * Units.kg
vehicle.mass_properties.max_takeoff = 6.75 * Units.kg
vehicle.mass_properties.takeoff = 4.00 * Units.kg
vehicle.mass_properties.operating_empty = 4.00 * Units.kg
vehicle.mass_properties.max_takeoff = 4.00 * Units.kg

# basic parameters
vehicle.reference_area = 1.0
Expand Down Expand Up @@ -171,24 +171,24 @@ def base_setup():
esc.efficiency = 0.95 # Gundlach for brushless motors
net.esc = esc

# Component 5 the Propeller
# Component 4 the Propeller
prop = SUAVE.Components.Energy.Converters.Propeller_Lo_Fid()
prop.propulsive_efficiency = 0.825
net.propeller = prop

# Component 4 the Motor
# Component 5 the Motor
motor = SUAVE.Components.Energy.Converters.Motor_Lo_Fid()
motor.speed_constant = 800. * Units['rpm/volt'] # RPM/volt is standard
motor.speed_constant = 900. * Units['rpm/volt'] # RPM/volt is standard
motor = size_from_kv(motor)
motor.gear_ratio = 1. # Gear ratio, no gearbox
motor.gearbox_efficiency = 1. # Gear box efficiency, no gearbox
motor.motor_efficiency = 0.825;
motor.motor_efficiency = 0.8;
net.motor = motor

# Component 6 the Payload
payload = SUAVE.Components.Energy.Peripherals.Payload()
payload.power_draw = 0. #Watts
payload.mass_properties.mass = 0.0 * Units.kg
payload.mass_properties.mass = 1.0 * Units.kg
net.payload = payload

# Component 7 the Avionics
Expand All @@ -198,8 +198,8 @@ def base_setup():

# Component 8 the Battery
bat = SUAVE.Components.Energy.Storages.Batteries.Constant_Mass.Lithium_Ion()
bat.mass_properties.mass = 5.0 * Units.kg
bat.specific_energy = 250. *Units.Wh/Units.kg
bat.mass_properties.mass = 3.0 * Units.kg
bat.specific_energy = 200. *Units.Wh/Units.kg
bat.resistance = 0.003
initialize_from_mass(bat,bat.mass_properties.mass)
net.battery = bat
Expand Down
Loading

0 comments on commit 758cbf0

Please sign in to comment.