Skip to content

Commit 758cbf0

Browse files
authored
Merge pull request #21 from suavecode/feature-2point3
Feature 2point3
2 parents dbc8e40 + 14127a3 commit 758cbf0

File tree

11 files changed

+69
-134
lines changed

11 files changed

+69
-134
lines changed

Regional_Jet_Optimization/Analyses.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
# ----------------------------------------------------------------------
99

1010
import SUAVE
11+
from SUAVE.Core import Units
12+
13+
import numpy as np
1114

1215
# ----------------------------------------------------------------------
1316
# Setup Analyses
@@ -55,6 +58,10 @@ def base(vehicle):
5558
# Aerodynamics Analysis
5659
aerodynamics = SUAVE.Analyses.Aerodynamics.Fidelity_Zero()
5760
aerodynamics.geometry = vehicle
61+
aerodynamics.settings.number_spanwise_vortices = 5
62+
aerodynamics.settings.number_chordwise_vortices = 1
63+
aerodynamics.process.compute.lift.inviscid_wings.training.angle_of_attack = np.array([[-5., 0.0, 5.0, 10.0, 75.]]).T * Units.deg
64+
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
5865
analyses.append(aerodynamics)
5966

6067
# ------------------------------------------------------------------

Regional_Jet_Optimization/Optimize.py

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,19 @@
2323
# Run the whole thing
2424
# ----------------------------------------------------------------------
2525
def main():
26+
2627
problem = setup()
2728

2829
## Base Input Values
29-
#output = problem.objective()
30+
output = problem.objective()
3031

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

34-
## Uncomment for the first optimization
35+
# Uncomment for the first optimization
3536
output = scipy_setup.SciPy_Solve(problem,solver='SLSQP')
3637
print (output)
37-
38-
## Uncomment these lines when you want to start an optimization problem from a different initial guess
39-
#inputs = [1.28, 1.38]
40-
#scaling = problem.optimization_problem.inputs[:,3] #have to rescale inputs to start problem from here
41-
#scaled_inputs = np.multiply(inputs,scaling)
42-
#problem.optimization_problem.inputs[:,1] = scaled_inputs
43-
#output = scipy_setup.SciPy_Solve(problem,solver='SLSQP')
44-
#print output
45-
38+
4639
print('fuel burn = ', problem.summary.base_mission_fuelburn)
4740
print('fuel margin = ', problem.all_constraints())
4841

@@ -64,17 +57,16 @@ def setup():
6457
# Inputs
6558
# -------------------------------------------------------------------
6659

67-
# [ tag , initial, (lb,ub) , scaling , units ]
60+
# [ tag , initial, (lb , ub) , scaling , units ]
6861
problem.inputs = np.array([
69-
[ 'wing_area' , 100 , ( 90. , 130. ) , 100. , Units.meter**2],
70-
[ 'cruise_altitude' , 11 , ( 9 , 14. ) , 10. , Units.km],
62+
[ 'wing_area' , 92 , ( 50. , 130. ) , 100. , Units.meter**2],
63+
[ 'cruise_altitude' , 8 , ( 6. , 12. ) , 10. , Units.km],
7164
])
7265

7366
# -------------------------------------------------------------------
7467
# Objective
7568
# -------------------------------------------------------------------
7669

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

143135
cbar.ax.set_ylabel('fuel burn (kg)')
144-
CS_const = plt.contour(inputs[0,:],inputs[1,:], constraints[0,:,:])
136+
CS_const = plt.contour(inputs[0,:],inputs[1,:], constraints[0,:,:],cmap='jet')
145137
plt.clabel(CS_const, inline=1, fontsize=10)
146138
cbar = plt.colorbar(CS_const)
147139
cbar.ax.set_ylabel('fuel margin')
148140

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

152-
plt.legend(loc='upper left')
153144
plt.show(block=True)
154145

155146
return

Regional_Jet_Optimization/Procedure.py

Lines changed: 10 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ def setup():
5454
def find_target_range(nexus,mission):
5555

5656
segments = mission.segments
57-
cruise_altitude = mission.segments['climb_5'].altitude_end
5857
climb_1 = segments['climb_1']
5958
climb_2 = segments['climb_2']
6059
climb_3 = segments['climb_3']
@@ -139,55 +138,6 @@ def simple_sizing(nexus):
139138
turbofan_sizing(config.propulsors['turbofan'], mach_number = mach_number, altitude = altitude)
140139
compute_turbofan_geometry(config.propulsors['turbofan'], conditions)
141140

142-
143-
# ------------------------------------------------------------------
144-
# Landing Configuration
145-
# ------------------------------------------------------------------
146-
landing = nexus.vehicle_configurations.landing
147-
state = Data()
148-
state.conditions = Data()
149-
state.conditions.freestream = Data()
150-
151-
# landing weight
152-
landing.mass_properties.landing = 0.85 * config.mass_properties.takeoff
153-
154-
# Landing CL_max
155-
altitude = nexus.missions.base.segments[-1].altitude_end
156-
atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976()
157-
p, T, rho, a, mu = atmosphere.compute_values(altitude)
158-
state.conditions.freestream.velocity = nexus.missions.base.segments['descent_3'].air_speed
159-
state.conditions.freestream.density = rho
160-
state.conditions.freestream.dynamic_viscosity = mu/rho
161-
settings = Data()
162-
settings.maximum_lift_coefficient_factor = 1.0
163-
CL_max_landing, CDi = compute_max_lift_coeff(state,settings,landing)
164-
landing.maximum_lift_coefficient = CL_max_landing
165-
166-
167-
#Takeoff CL_max
168-
takeoff = nexus.vehicle_configurations.takeoff
169-
altitude = nexus.missions.base.airport.altitude
170-
atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976()
171-
p, T, rho, a, mu = atmosphere.compute_values(altitude)
172-
state.conditions.freestream.velocity = nexus.missions.base.segments.climb_1.air_speed
173-
state.conditions.freestream.density = rho
174-
state.conditions.freestream.dynamic_viscosity = mu/rho
175-
settings.maximum_lift_coefficient_factor = 1.0
176-
max_CL_takeoff,CDi = compute_max_lift_coeff(state,settings,takeoff)
177-
takeoff.maximum_lift_coefficient = max_CL_takeoff
178-
179-
#Base config CL_max
180-
base = nexus.vehicle_configurations.base
181-
altitude = nexus.missions.base.airport.altitude
182-
atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976()
183-
p, T, rho, a, mu = atmosphere.compute_values(altitude)
184-
state.conditions.freestream.velocity = nexus.missions.base.segments.climb_1.air_speed
185-
state.conditions.freestream.density = rho
186-
state.conditions.freestream.dynamic_viscosity = mu/rho
187-
settings.maximum_lift_coefficient_factor = 1.0
188-
max_CL_base,CDi = compute_max_lift_coeff(state,settings,landing)
189-
base.maximum_lift_coefficient = max_CL_base
190-
191141
return nexus
192142

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

200150
# weight analysis
201-
weights = nexus.analyses.base.weights.evaluate()
202-
weights = nexus.analyses.cruise.weights.evaluate()
151+
weights = nexus.analyses.base.weights.evaluate(method="SUAVE")
152+
weights = nexus.analyses.cruise.weights.evaluate(method="SUAVE")
203153
vehicle.mass_properties.breakdown = weights
204-
weights = nexus.analyses.landing.weights.evaluate()
205-
weights = nexus.analyses.takeoff.weights.evaluate()
206-
weights = nexus.analyses.short_field_takeoff.weights.evaluate()
207-
208-
for config in nexus.vehicle_configurations:
209-
config.mass_properties.zero_fuel_center_of_gravity = vehicle.mass_properties.zero_fuel_center_of_gravity
210-
config.fuel = vehicle.fuel
211-
154+
weights = nexus.analyses.landing.weights.evaluate(method="SUAVE")
155+
weights = nexus.analyses.takeoff.weights.evaluate(method="SUAVE")
156+
weights = nexus.analyses.short_field_takeoff.weights.evaluate(method="SUAVE")
157+
212158
return nexus
213159

214160
# ----------------------------------------------------------------------
@@ -231,16 +177,7 @@ def post_process(nexus):
231177
vehicle = nexus.vehicle_configurations.base
232178
results = nexus.results
233179
summary = nexus.summary
234-
missions = nexus.missions
235180
nexus.total_number_of_iterations +=1
236-
# Static stability calculations
237-
CMA = -10.
238-
for segment in results.base.segments.values():
239-
max_CMA = np.max(segment.conditions.stability.static.Cm_alpha[:,0])
240-
if max_CMA > CMA:
241-
CMA = max_CMA
242-
243-
summary.static_stability = CMA
244181

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

254191
# Fuel margin and base fuel calculations
255-
operating_empty = vehicle.mass_properties.operating_empty
256-
payload = vehicle.mass_properties.breakdown.payload
257192
design_landing_weight = results.base.segments[-1].conditions.weights.total_mass[-1]
258193
design_takeoff_weight = vehicle.mass_properties.takeoff
259-
max_takeoff_weight = nexus.vehicle_configurations.takeoff.mass_properties.max_takeoff
260-
zero_fuel_weight = payload+operating_empty
194+
zero_fuel_weight = vehicle.mass_properties.breakdown.zero_fuel_weight
261195

262-
summary.max_zero_fuel_margin = (design_landing_weight - zero_fuel_weight)/zero_fuel_weight
263-
summary.base_mission_fuelburn = design_takeoff_weight - results.base.segments['descent_3'].conditions.weights.total_mass[-1]
196+
summary.max_zero_fuel_margin = (design_landing_weight - zero_fuel_weight)/zero_fuel_weight
197+
summary.base_mission_fuelburn = design_takeoff_weight - results.base.segments['descent_3'].conditions.weights.total_mass[-1]
264198

265199
#when you run want to output results to a file
266200
filename = 'results.txt'
267201
write_optimization_outputs(nexus, filename)
268-
202+
269203
return nexus

Regional_Jet_Optimization/Vehicles.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ def base_setup():
3838
# Vehicle-level Properties
3939
# ------------------------------------------------------------------
4040

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

50-
vehicle.mass_properties.center_of_gravity = [[16.8, 0, 1.6]]
51-
vehicle.mass_properties.moments_of_inertia.tensor = [[10 ** 5, 0, 0],[0, 10 ** 6, 0,],[0,0, 10 ** 7]]
52-
5349
# envelope properties
5450
vehicle.envelope.ultimate_load = 3.5
5551
vehicle.envelope.limit_load = 1.5
@@ -217,10 +213,11 @@ def base_setup():
217213
gt_engine.inlet_diameter = 2.0
218214

219215
#compute engine areas)
220-
Amax = (np.pi/4.)*gt_engine.nacelle_diameter**2.
221216
Awet = 1.1*np.pi*gt_engine.nacelle_diameter*gt_engine.engine_length # 1.1 is simple coefficient
217+
222218
#Assign engine area
223219
gt_engine.areas.wetted = Awet
220+
224221
#set the working fluid for the network
225222
working_fluid = SUAVE.Attributes.Gases.Air()
226223

@@ -320,7 +317,7 @@ def base_setup():
320317
#design sizing conditions
321318
altitude = 35000.0*Units.ft
322319
mach_number = 0.78
323-
isa_deviation = 0.
320+
324321
# add thrust to the network
325322
gt_engine.thrust = thrust
326323

Solar_UAV_Optimization/Analyses.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
# ----------------------------------------------------------------------
99

1010
import SUAVE
11+
from SUAVE.Core import Units
12+
import numpy as np
1113

1214
# ----------------------------------------------------------------------
1315
# Setup Analyses
@@ -54,6 +56,10 @@ def base(vehicle):
5456
# ------------------------------------------------------------------
5557
aerodynamics = SUAVE.Analyses.Aerodynamics.Fidelity_Zero()
5658
aerodynamics.geometry = vehicle
59+
aerodynamics.settings.number_spanwise_vortices = 10
60+
aerodynamics.settings.number_chordwise_vortices = 2
61+
aerodynamics.process.compute.lift.inviscid_wings.training.angle_of_attack = np.array([[-5., 0.0, 5.0, 10.0, 75.]]).T * Units.deg
62+
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
5763
analyses.append(aerodynamics)
5864

5965
# ------------------------------------------------------------------

Solar_UAV_Optimization/Missions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def mission(analyses,vehicle):
5454
# connect vehicle configuration
5555
segment.analyses.extend(analyses.base)
5656

57-
# segment attributes
57+
# segment attributes
5858
segment.state.numerics.number_control_points = 50
5959
segment.dynamic_pressure = 115.0 * Units.pascals
6060
segment.start_time = time.strptime("Tue, Jun 21 11:00:00 2020", "%a, %b %d %H:%M:%S %Y",)

Solar_UAV_Optimization/Optimize.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
import SUAVE.Optimization.Package_Setups.scipy_setup as scipy_setup
1818
import SUAVE.Optimization.Package_Setups.pyopt_setup as pyopt_setup
1919
from SUAVE.Optimization.Nexus import Nexus
20+
import pylab as plt
21+
2022

2123
# ----------------------------------------------------------------------
2224
# Run the whole thing
@@ -48,11 +50,11 @@ def setup():
4850

4951
# [ tag , initial, [lb,ub], scaling, units ]
5052
problem.inputs = np.array([
51-
[ 'wing_area' , 0.62, ( 0.1, 1.5 ), 0.5, Units.meter ],
52-
[ 'aspect_ratio' , 13.5, ( 5.0, 20.0 ), 10.0, Units.less ],
53-
[ 'dynamic_pressure', 115.0, ( 1.0, 2000.0 ), 125.0, Units.pascals ],
54-
[ 'solar_ratio' , 0.0, ( 0.0, 0.97), 1.0, Units.less ],
55-
[ 'kv' , 900.0, ( 10.0, 1500.0 ), 800.0, Units['rpm/volt']],
53+
[ 'wing_area' , 0.5, ( 0.1, 1.5 ), 0.5, Units.meter ],
54+
[ 'aspect_ratio' , 10.0, ( 5.0, 20.0 ), 10.0, Units.less ],
55+
[ 'dynamic_pressure', 125.0, ( 1.0, 2000.0 ), 125.0, Units.pascals ],
56+
[ 'solar_ratio' , 0.0, ( 0.0, 0.97), 1.0, Units.less ],
57+
[ 'kv' , 800.0, ( 10.0, 10000.0 ), 800.0, Units['rpm/volt']],
5658
])
5759

5860
# -------------------------------------------------------------------
@@ -120,4 +122,5 @@ def setup():
120122
return nexus
121123

122124
if __name__ == '__main__':
123-
main()
125+
main()
126+
plt.show()

Solar_UAV_Optimization/Vehicles.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ def base_setup():
3838
# Vehicle-level Properties
3939
# ------------------------------------------------------------------
4040
# mass properties
41-
vehicle.mass_properties.takeoff = 6.75 * Units.kg
42-
vehicle.mass_properties.operating_empty = 6.75 * Units.kg
43-
vehicle.mass_properties.max_takeoff = 6.75 * Units.kg
41+
vehicle.mass_properties.takeoff = 4.00 * Units.kg
42+
vehicle.mass_properties.operating_empty = 4.00 * Units.kg
43+
vehicle.mass_properties.max_takeoff = 4.00 * Units.kg
4444

4545
# basic parameters
4646
vehicle.reference_area = 1.0
@@ -171,24 +171,24 @@ def base_setup():
171171
esc.efficiency = 0.95 # Gundlach for brushless motors
172172
net.esc = esc
173173

174-
# Component 5 the Propeller
174+
# Component 4 the Propeller
175175
prop = SUAVE.Components.Energy.Converters.Propeller_Lo_Fid()
176176
prop.propulsive_efficiency = 0.825
177177
net.propeller = prop
178178

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

188188
# Component 6 the Payload
189189
payload = SUAVE.Components.Energy.Peripherals.Payload()
190190
payload.power_draw = 0. #Watts
191-
payload.mass_properties.mass = 0.0 * Units.kg
191+
payload.mass_properties.mass = 1.0 * Units.kg
192192
net.payload = payload
193193

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

199199
# Component 8 the Battery
200200
bat = SUAVE.Components.Energy.Storages.Batteries.Constant_Mass.Lithium_Ion()
201-
bat.mass_properties.mass = 5.0 * Units.kg
202-
bat.specific_energy = 250. *Units.Wh/Units.kg
201+
bat.mass_properties.mass = 3.0 * Units.kg
202+
bat.specific_energy = 200. *Units.Wh/Units.kg
203203
bat.resistance = 0.003
204204
initialize_from_mass(bat,bat.mass_properties.mass)
205205
net.battery = bat

0 commit comments

Comments
 (0)