Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# Drag divergence exponent
div_exp = 32
### Declare Geometric Programming constraints. ###
constraints = [
# Piecewise c_dp vs. mach model
c_dp >= _c_dp0,
c_dp >= _c_dp0 * (mach_perp / _mach_d)**div_exp,
# Pressure drag vs. lift fit
# This fit was manually tuned to qualitatively match the
# left-hand plot in Drela's [1] figure 8.34.
# There first two terms are a quadratic fit. The third term
# has c_l raised to a high exponent to cause a rapid
# increase in drag above c_l = 0.9.
Tight([_c_dp0 >= 20.5e-4 * c_l**2 + 14.9e-4 + 1e-4 * (c_l/0.9)**25], reltol=1e-3),
# Drag divergence Mach number vs. lift linear fit
# Note: If the 2nd piece of the c_dp constraint is not tight,
# i.e. at low mach, this constraint will not become tight and
# _mach_d will take on some arbitrary value.
_mach_d + 0.0667 * c_l <= 0.783,
# Mach number limit of model
Loose([mach_perp <= _mach_model_max]),
# c_l limit of model
Loose([c_l <= _c_l_model_max]),
# Lift slope vs. Mach number from Prandtl-Glauert
# TODO should this beta be based on mach or mach_perp?
c_la_2d == 0.95 * 2 * pi / flight_state['beta_pg'],
xcglg = Variable('x_{CG_{lg}}', 'm', 'Landing gear CG')
y_m = Variable('y_m', 'm', 'y-location of main gear (symmetric)')
z_CG_0 = Variable('z_{CG}', 'm',
'CG height relative to bottom of fuselage')
zwing = Variable('z_{wing}', 'm',
'Height of wing relative to base of fuselage')
d_nac = Variable('d_{nacelle}', 'm', 'Nacelle diameter')
with SignomialsEnabled():
objective = W_lg
constraints = [
# Track and Base geometry definitions
TCS([l_n+zwing+y_m*tan_gam>=l_m], reltol=1E-3), #[SP]
T == 2*y_m,
TCS([x_n + B <= x_m]),
x_n >= 5*units.m, # nose gear after nose
# Longitudinal tip over (static)
tan_phi == tan_15,
# Lateral tip over in turn (dynamic)
# www.dept.aoe.vt.edu/~mason/Mason_f/M96SC03.pdf
# stricter constraint uses forward CG
# cos(arctan(y/x))) = x/sqrt(x^2 + y^2)
1 >= (z_CG_0 + l_m)**2 * (y_m**2 + B**2) /
(dxn * y_m * tan_psi)**2,
tan_psi <= tan_63,
# Tail strike: Longitudinal ground clearance in
TCS([climb['W_{start}'] >= climb['W_{end}'] + climb['W_{burn}']]),
# similar constraint 2
TCS([cruise['W_{start}'] >= cruise['W_{end}'] + cruise['W_{burn}']]),
climb['W_{start}'][1:] == climb['W_{end}'][:-1],
cruise['W_{start}'][1:] == cruise['W_{end}'][:-1],
TCS([ac['W_{e}'] + ac['W_{payload}'] + ac['numeng'] * ac['W_{engine}'] + ac['W_{wing}'] <= cruise['W_{end}'][-1]]),
TCS([W_ftotal >= W_fclimb + W_fcruise]),
TCS([W_fclimb >= sum(climb['W_{burn}'])]),
TCS([W_fcruise >= sum(cruise['W_{burn}'])]),
#altitude constraints
hftCruise == CruiseAlt,
TCS([hftClimb[1:Ncruise] >= hftClimb[:Ncruise-1] + dhft]),
TCS([hftClimb[0] >= dhft[0]]),
hftClimb[-1] <= hftCruise,
#compute the dh
dhft == hftCruise/Nclimb,
#constrain the thrust
climb['thrust'] <= 2 * max(cruise['thrust']),
#set the range for each cruise segment, doesn't take credit for climb
#down range disatnce covered
cruise.cruiseP['Rng'] == ReqRng/(Ncruise),
#set the TSFC
climb['TSFC'] == .7*units('1/hr'),
cruise['TSFC'] == .5*units('1/hr'),
# Machining constraint # p89 Mason
# www.dept.aoe.vt.edu/~mason/Mason_f/M96SC08.pdf
2*r_m/t_m <= 40,
2*r_m/t_n <= 40,
# Retraction constraint on strut diameter
2*wtm + 2*r_m <= hhold,
2*wtn + 2*r_n <= 0.8*units.m, #TODO improve this
# Weight accounting
W_mg >= n_mg*(W_ms + W_mw*(1 + faddm)),# Currey p264
W_ng >= W_ns + W_nw*(1 + faddn),
W_lg >= Clg * (W_mg + W_ng),
#LG CG accounting
TCS([W_lg*xcglg >= W_ng*x_n + W_mg*x_m], reltol=1E-2,
raiseerror=False),
x_m >= xcglg,
]
return constraints
def setup(self):
exec parse_variables(WVL.__doc__)
with SignomialsEnabled():
constraints = [
TCS([CDi >= 2*np.dot(G, np.dot(B, G))/S]),
TCS([CL <= sum(2*G*deta/S)])
]
return constraints
ac.empenage.ht['L_{{max}_h}'] == 0.5*ac.empenage.ht['\\rho_0']*ac.wing['V_{ne}']**2*ac.empenage.ht['S_h']*ac.empenage.ht['C_{L_{hmax}}'],
#compute mrat, is a signomial equality
SignomialEquality(ac.empenage.ht['m_{ratio}']*(1+2/ac.wing['AR']), 1 + 2/ac.empenage.ht['AR_h']),
#tail volume coefficient
ac.empenage.ht['V_{h}'] == ac.empenage.ht['S_h']*ac.empenage.ht['x_{CG_{ht}}']/(ac.wing['S']*ac.wing['\\bar{c}_w']),
#enforce max tail location is the end of the fuselage
ac.empenage.ht['x_{CG_{ht}}'] <= ac.fuse['l_{fuse}'],
#Stability constraint, is a signomial
#NEED TO RECONSIDER THIS ONCE WE HAVE A BETTER WING MOMENT MODEL
TCS([ac.empenage.ht['SM_{min}'] + ac.empenage.ht['\\Delta x_{CG}']/ac.wing['\\bar{c}_w'] <= ac.empenage.ht['V_{h}']*ac.empenage.ht['m_{ratio}'] + cruise['c_{m_{w}}']/ac.wing['C_{L_{wmax}}'] + ac.empenage.ht['V_{h}']*ac.empenage.ht['C_{L_{hmax}}']/ac.wing['C_{L_{wmax}}']]),
ac.empenage.ht['l_{ht}'] >= ac.empenage.ht['x_{CG_{ht}}'] - xcg,
TCS([ac.wing['x_w'] >= xcg + cruise['\\Delta x_w']]),
TCS([xcg + cruise['\\Delta x_{{trail}_h}'] <= ac.fuse['l_{fuse}']], reltol=0.002),
TCS([ac.empenage.ht['x_{CG_{ht}}'] >= xcg+(cruise['\\Delta x_{{lead}_h}']+cruise['\\Delta x_{{trail}_h}'])/2]),
climb['C_{L_h}'] <= 1.1*climb['C_{L_{ah}}']*climb['\\alpha_w'],
climb['C_{L_h}'] >= 0.9*climb['C_{L_{ah}}']*climb['\\alpha_w'],
# Trim condidtion for each flight segment
TCS([climb['x_{ac}']/ac.wing['\\bar{c}_w'] <= climb['c_{m_{w}}']/climb['C_{L}'] + xcg/ac.wing['\\bar{c}_w'] + ac.empenage.ht['V_{h}']*(climb['C_{L_h}']/climb['C_{L}'])]),
z_CG_0 = Variable('z_{CG}', 'm',
'CG height relative to bottom of fuselage')
zwing = Variable('z_{wing}', 'm',
'Height of wing relative to base of fuselage')
d_nac = Variable('d_{nacelle}', 'm', 'Nacelle diameter')
with SignomialsEnabled():
objective = W_lg
constraints = [
# Track and Base geometry definitions
TCS([l_n+zwing+y_m*tan_gam>=l_m], reltol=1E-3), #[SP]
T == 2*y_m,
TCS([x_n + B <= x_m]),
x_n >= 5*units.m, # nose gear after nose
# Longitudinal tip over (static)
tan_phi == tan_15,
# Lateral tip over in turn (dynamic)
# www.dept.aoe.vt.edu/~mason/Mason_f/M96SC03.pdf
# stricter constraint uses forward CG
# cos(arctan(y/x))) = x/sqrt(x^2 + y^2)
1 >= (z_CG_0 + l_m)**2 * (y_m**2 + B**2) /
(dxn * y_m * tan_psi)**2,
tan_psi <= tan_63,
# Tail strike: Longitudinal ground clearance in
# takeoff, landing (Raymer says 10-15 degrees)
# TODO?: 2 cases:(i) upsweep angle > rotation angle,
"""Simple commercial aircraft flight profile and aircraft model
Integrates Wing, VerticalTail, HorizontalTail , Fuselage, and Landing Gear models """
from __future__ import absolute_import
from builtins import range
import numpy as np
from gpkit import Variable, Model, units, SignomialsEnabled, SignomialEquality, Vectorize
from gpkit.constraints.tight import Tight as TCS
from gpkit.constraints.bounded import Bounded as BCS
from numpy import pi
TCS.reltol = 1e-3
# importing from D8_integration
from stand_alone_simple_profile import FlightState
from vertical_tail import VerticalTail
from horizontal_tail import HorizontalTail
from wing import Wing
from turbofan.engine_validation import Engine
from fuselage import Fuselage
from landing_gear import LandingGear
# for ESP
from collections import OrderedDict
"""
Models required to minimize the aircraft total fuel weight.
"Example Tight ConstraintSet usage"
from gpkit import Variable, Model
from gpkit.constraints.tight import Tight
Tight.reltol = 1e-2 # set the global tolerance of Tight
x = Variable('x')
x_min = Variable('x_{min}', 2)
m = Model(x, [Tight([x >= 1], reltol=1e-3), # set the specific tolerance
x >= x_min])
m.solve(verbosity=0) # prints warning
u6 >= state['V'],
u8 >= state['V'],
#constrain the new BPR
alpha == mFan / mCore,
hold == alphap1,
SignomialEquality(hold, alpha + 1),
alpha <= self.thrust['\\alpha_{max}'],
#overall thrust values
TCS([F8/(alpha * mCore) + state['V'] <= u8]), #B.188
TCS([F6/(mCore) + state['V'] <= u6]), #B.188, unneeded
#SIGNOMIAL
TCS([F <= F6 + F8]),
Fsp == F/((alphap1)*mCore*state['a']), #B.191
#TSFC
TSFC == 1/Isp,
])
return constraints