-
Notifications
You must be signed in to change notification settings - Fork 45
/
Copy pathProcedure.py
203 lines (150 loc) · 8.2 KB
/
Procedure.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# Procedure.py
#
# Created: Mar 2016, M. Vegh
# Modified: Aug 2017, E. Botero
# ----------------------------------------------------------------------
# Imports
# ----------------------------------------------------------------------
import numpy as np
import SUAVE
from SUAVE.Core import Units, Data
from SUAVE.Analyses.Process import Process
from SUAVE.Methods.Propulsion.turbofan_sizing import turbofan_sizing
from SUAVE.Methods.Geometry.Two_Dimensional.Cross_Section.Propulsion.compute_turbofan_geometry import compute_turbofan_geometry
#from SUAVE.Methods.Center_of_Gravity.compute_component_centers_of_gravity import compute_component_centers_of_gravity
#from SUAVE.Methods.Center_of_Gravity.compute_aircraft_center_of_gravity import compute_aircraft_center_of_gravity
from SUAVE.Methods.Aerodynamics.Fidelity_Zero.Lift.compute_max_lift_coeff import compute_max_lift_coeff
from SUAVE.Optimization.write_optimization_outputs import write_optimization_outputs
# ----------------------------------------------------------------------
# Setup
# ----------------------------------------------------------------------
def setup():
# ------------------------------------------------------------------
# Analysis Procedure
# ------------------------------------------------------------------
# size the base config
procedure = Process()
procedure.simple_sizing = simple_sizing
# find the weights
procedure.weights = weight
# finalizes the data dependencies
procedure.finalize = finalize
# performance studies
procedure.missions = Process()
procedure.missions.design_mission = design_mission
# post process the results
procedure.post_process = post_process
return procedure
# ----------------------------------------------------------------------
# Target Range Function
# ----------------------------------------------------------------------
def find_target_range(nexus,mission):
segments = mission.segments
climb_1 = segments['climb_1']
climb_2 = segments['climb_2']
climb_3 = segments['climb_3']
climb_4 = segments['climb_4']
climb_5 = segments['climb_5']
descent_1 = segments['descent_1']
descent_2 = segments['descent_2']
descent_3 = segments['descent_3']
x_climb_1 = climb_1.altitude_end/np.tan(np.arcsin(climb_1.climb_rate/climb_1.air_speed))
x_climb_2 = (climb_2.altitude_end-climb_1.altitude_end)/np.tan(np.arcsin(climb_2.climb_rate/climb_2.air_speed))
x_climb_3 = (climb_3.altitude_end-climb_2.altitude_end)/np.tan(np.arcsin(climb_3.climb_rate/climb_3.air_speed))
x_climb_4 = (climb_4.altitude_end-climb_3.altitude_end)/np.tan(np.arcsin(climb_4.climb_rate/climb_4.air_speed))
x_climb_5 = (climb_5.altitude_end-climb_4.altitude_end)/np.tan(np.arcsin(climb_5.climb_rate/climb_5.air_speed))
x_descent_1 = (climb_5.altitude_end-descent_1.altitude_end)/np.tan(np.arcsin(descent_1.descent_rate/descent_1.air_speed))
x_descent_2 = (descent_1.altitude_end-descent_2.altitude_end)/np.tan(np.arcsin(descent_2.descent_rate/descent_2.air_speed))
x_descent_3 = (descent_2.altitude_end-descent_3.altitude_end)/np.tan(np.arcsin(descent_3.descent_rate/descent_3.air_speed))
cruise_range = mission.design_range-(x_climb_1+x_climb_2+x_climb_3+x_climb_4+x_climb_5+x_descent_1+x_descent_2+x_descent_3)
segments['cruise'].distance = cruise_range
return nexus
# ----------------------------------------------------------------------
# Design Mission
# ----------------------------------------------------------------------
def design_mission(nexus):
mission = nexus.missions.base
mission.design_range = 1500.*Units.nautical_miles
find_target_range(nexus,mission)
results = nexus.results
results.base = mission.evaluate()
return nexus
# ----------------------------------------------------------------------
# Sizing
# ----------------------------------------------------------------------
def simple_sizing(nexus):
configs=nexus.vehicle_configurations
base=configs.base
#find conditions
air_speed = nexus.missions.base.segments['cruise'].air_speed
altitude = nexus.missions.base.segments['climb_5'].altitude_end
atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976()
freestream = atmosphere.compute_values(altitude)
freestream0 = atmosphere.compute_values(6000.*Units.ft) #cabin altitude
diff_pressure = np.max(freestream0.pressure-freestream.pressure,0)
fuselage = base.fuselages['fuselage']
fuselage.differential_pressure = diff_pressure
#now size engine
mach_number = air_speed/freestream.speed_of_sound
#now add to freestream data object
freestream.velocity = air_speed
freestream.mach_number = mach_number
freestream.gravity = 9.81
conditions = SUAVE.Analyses.Mission.Segments.Conditions.Aerodynamics() #assign conditions in form for propulsor sizing
conditions.freestream = freestream
for config in configs:
config.wings.horizontal_stabilizer.areas.reference = (26.0/92.0)*config.wings.main_wing.areas.reference
for wing in config.wings:
wing = SUAVE.Methods.Geometry.Two_Dimensional.Planform.wing_planform(wing)
wing.areas.exposed = 0.8 * wing.areas.wetted
wing.areas.affected = 0.6 * wing.areas.reference
fuselage = config.fuselages['fuselage']
fuselage.differential_pressure = diff_pressure
turbofan_sizing(config.networks['turbofan'], mach_number = mach_number, altitude = altitude)
compute_turbofan_geometry(config.networks['turbofan'], config.nacelles.nacelle_1)
return nexus
# ----------------------------------------------------------------------
# Weights
# ----------------------------------------------------------------------
def weight(nexus):
vehicle=nexus.vehicle_configurations.base
# weight analysis
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(method="SUAVE")
weights = nexus.analyses.takeoff.weights.evaluate(method="SUAVE")
weights = nexus.analyses.short_field_takeoff.weights.evaluate(method="SUAVE")
return nexus
# ----------------------------------------------------------------------
# Finalizing Function
# ----------------------------------------------------------------------
def finalize(nexus):
nexus.analyses.finalize()
return nexus
# ----------------------------------------------------------------------
# Post Process Results to give back to the optimizer
# ----------------------------------------------------------------------
def post_process(nexus):
# Unpack data
vehicle = nexus.vehicle_configurations.base
results = nexus.results
summary = nexus.summary
nexus.total_number_of_iterations +=1
#throttle in design mission
max_throttle = 0
for segment in results.base.segments.values():
max_segment_throttle = np.max(segment.conditions.propulsion.throttle[:,0])
if max_segment_throttle > max_throttle:
max_throttle = max_segment_throttle
summary.max_throttle = max_throttle
# Fuel margin and base fuel calculations
design_landing_weight = results.base.segments[-1].conditions.weights.total_mass[-1]
design_takeoff_weight = vehicle.mass_properties.takeoff
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]
#when you run want to output results to a file
filename = 'results.txt'
write_optimization_outputs(nexus, filename)
return nexus