Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature 2point3 #21

Merged
merged 9 commits into from
Dec 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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