Esempio n. 1
0
 def test_te_exp_minus1(self):
     """Test Taylor expansion of e^x - 1"""
     x = Variable('x')
     self.assertEqual(te_exp_minus1(x, 1), x)
     self.assertEqual(te_exp_minus1(x, 3), x + x**2/2. + x**3/6.)
     self.assertRaises(ValueError, te_exp_minus1, x, 0)
     # make sure x was not modified
     self.assertEqual(x, Variable('x'))
     # try for VectorVariable too
     y = VectorVariable(3, 'y')
     self.assertEqual(te_exp_minus1(y, 1), y)
     self.assertEqual(te_exp_minus1(y, 3), y + y**2/2. + y**3/6.)
     self.assertRaises(ValueError, te_exp_minus1, y, 0)
     # make sure y was not modified
     self.assertEqual(y, VectorVariable(3, 'y'))
Esempio n. 2
0
 def test_te_exp_minus1(self):
     """Test Taylor expansion of e^x - 1"""
     x = Variable('x')
     self.assertEqual(te_exp_minus1(x, 1), x)
     self.assertEqual(te_exp_minus1(x, 3), x + x**2 / 2. + x**3 / 6.)
     self.assertRaises(ValueError, te_exp_minus1, x, 0)
     # make sure x was not modified
     self.assertEqual(x, Variable('x'))
     # try for VectorVariable too
     y = VectorVariable(3, 'y')
     self.assertEqual(te_exp_minus1(y, 1), y)
     self.assertEqual(te_exp_minus1(y, 3), y + y**2 / 2. + y**3 / 6.)
     self.assertRaises(ValueError, te_exp_minus1, y, 0)
     # make sure y was not modified
     self.assertEqual(y, VectorVariable(3, 'y'))
Esempio n. 3
0
    def setup(self, aircraft, state, **kwargs):
        self.aircraft = aircraft
        self.aircraftP = aircraft.dynamic(state)
        self.wingP = self.aircraftP.wingP
        self.fuseP = self.aircraftP.fuseP
        self.engineP = self.aircraftP.engineP
                        
        #variable definitions
        z_bre = Variable('z_{bre}', '-', 'Breguet Parameter')
        Rng = Variable('Rng', 'nautical_miles', 'Cruise Segment Range')

        constraints = []

        constraints.extend([
             #steady level flight constraint on D 
             self.aircraftP['D'] == aircraft['numeng'] * self.engineP['F'],

             #taylor series expansion to get the weight term
             TCS([self.aircraftP['W_{burn}']/self.aircraftP['W_{end}'] >=
                  te_exp_minus1(z_bre, nterm=3)]),

             #breguet range eqn
             TCS([z_bre >= (self.engineP['TSFC'] * self.aircraftP['thr']*
                            self.aircraftP['D']) / self.aircraftP['W_{avg}']]),

             #time
             self.aircraftP['thr'] * state['V'] == Rng,
             ])

        return constraints, self.aircraftP
Esempio n. 4
0
    def setup(self, goods=None, bads=None, taylor_order=6):
        goods = goods if goods else {}
        goods.update({1 / k: 1 / v for k, v in bads.items()})
        N = check_values_length(goods)

        exp_S = VectorVariable(N, "e^{S}")
        VectorVariable(N, "S")

        self.cost = 1
        constraints = [[exp_S >= 1, exp_S.prod() == np.e]]
        for monomial, options in goods.items():
            m_nd = Variable("|%s|" %
                            monomial.latex(excluded=["models", "units"]))
            exp_m = Variable("e^{%s}" % m_nd.latex(excluded=["models"]))
            self.cost /= monomial
            if hasattr(options, "units"):
                monomial = monomial / (1 * options.units)
                options = options.magnitude
            options_scale = options.mean()
            options /= options_scale
            constraints.append([
                m_nd == monomial / options_scale,
                (exp_S**options).prod() == exp_m,
                exp_m >= 1 + te_exp_minus1(m_nd, taylor_order),
            ])

        return constraints
Esempio n. 5
0
    def setup(self, aircraft, state, **kwargs):
        self.aircraft = aircraft
        self.aircraftP = AircraftP(aircraft, state)
        self.wingP = self.aircraftP.wingP
        self.fuseP = self.aircraftP.fuseP

        #variable definitions
        z_bre = Variable('z_{bre}', '-', 'Breguet Parameter')
        Rng = Variable('Rng', 'nautical_miles', 'Cruise Segment Range')

        constraints = []

        constraints.extend([
            #taylor series expansion to get the weight term
            TCS([
                self.aircraftP['W_{burn}'] / self.aircraftP['W_{end}'] >=
                te_exp_minus1(z_bre, nterm=3)
            ]),

            #time
            self.aircraftP['thr'] * state['V'] == Rng,
            self.aircraftP['W_{burn}'] == self.aircraft.engine['TSFC'][2:] *
            self.aircraft.engine['F'][:2:] * self.aircraftP['thr']
        ])

        return constraints, self.aircraftP
Esempio n. 6
0
    def setup(self, perf):
        z_bre = Variable("z_{bre}", "-", "Breguet coefficient")
        t = Variable("t", "days", "Time per flight segment")
        f_fueloil = Variable("f_{(fuel/oil)}", 0.98, "-", "Fuel-oil fraction")
        Wfuel = Variable("W_{fuel}", "lbf", "Segment-fuel weight")
        g = Variable("g", 9.81, "m/s^2", "gravitational acceleration")

        constraints = [
            TCS([
                z_bre >= (perf["P_{total}"] * t * perf["BSFC"] * g /
                          (perf["W_{end}"] * perf["W_{start}"])**0.5)
            ]), f_fueloil * Wfuel / perf["W_{end}"] >= te_exp_minus1(z_bre, 3),
            perf["W_{start}"] >= perf["W_{end}"] + Wfuel
        ]

        return constraints
Esempio n. 7
0
    def setup(self, Wstart, Wend, perf):
        z_bre = Variable("z_{bre}", "-", "Breguet coefficient")
        Wfuel = Variable("W_{fuel}", "lbf", "segment-fuel weight")
        g = Variable("g", 9.81, "m/s^2", "gravitational acceleration")
        R = Variable("R", "nautical_miles", "range")
        rhofuel = Variable("\\rho_{JetA}", 6.75, "lb/gallon",
                           "Jet A fuel density")

        constraints = [
            TCS([
                z_bre >= (R * perf["\\dot{m}"] * rhofuel * g / perf["V"] /
                          (Wend * Wstart)**0.5)
            ]), Wfuel / Wend >= te_exp_minus1(z_bre, 3), Wstart >= Wend + Wfuel
        ]

        return constraints
    def setup(self, aircraft, state, **kwargs):
        self.aircraft = aircraft
        self.aircraftP = AircraftP(aircraft, state)
        self.wingP = self.aircraftP.wingP
        self.fuseP = self.aircraftP.fuseP
        self.engineP = self.aircraftP.engineP

        #variable definitions
        z_bre = Variable('z_{bre}', '-', 'Breguet Parameter')
        Rng = Variable('Rng', 'nautical_miles', 'Cruise Segment Range')

        constraints = []

        constraints.extend([
            #steady level flight constraint on D
            self.aircraftP['D'] == aircraft['numeng'] * self.engineP['thrust'],

            #taylor series expansion to get the weight term
            TCS([
                self.aircraftP['W_{burn}'] / self.aircraftP['W_{end}'] >=
                te_exp_minus1(z_bre, nterm=3)
            ]),

            #breguet range eqn
            # old version -- possibly unneeded numeng
            #            TCS([z_bre >= (self.aircraft['numeng'] * self.engineP['TSFC'] * self.aircraftP['thr']*
            #                           self.aircraftP['D']) / self.aircraftP['W_{avg}']]),

            # new version -- needs to be thought through carefully
            # seems correct to me - I switched T to D below (steady level flight) but fogot
            #about the Negn term
            TCS([
                z_bre >= (self.engineP['TSFC'] * self.aircraftP['thr'] *
                          self.aircraftP['D']) / self.aircraftP['W_{avg}']
            ]),

            #time
            self.aircraftP['thr'] * state['V'] == Rng,
        ])

        return constraints, self.aircraftP
Esempio n. 9
0
    def setup(self):

        # Fixed Parameters
        LD_max = Variable('\\left(\\frac{L}{D}\\right)_{max}', 15, '-',
                          'Maximum lift-to-drag ratio')
        MTOW   = Variable('MTOW', 10000, 'lbf', 'Max takeoff weight')
        TSFC   = Variable('TSFC', 0.307, 'lb/lbf/hr',
                          'Thrust specific fuel consumption')
        V_max  = Variable('V_{max}', 420, 'knots', 'Maximum velocity')
        W_e    = Variable('W_{e}', 7000, 'lbf', 'Operating empty weight')

        # Constants
        g      = Variable('g', 9.81, 'm/s^2', 'Gravitational acceleration')

        # Free Variables
        LD     = Variable('\\frac{L}{D}', '-', 'Lift-to-drag ratio')
        R      = Variable('R', 'nautical_miles', 'Range')
        V      = Variable('V', 'knots', 'Velocity')
        W_fuel = Variable('W_{fuel}', 'lbf', 'Fuel weight')
        W_init = Variable('W_{init}', 'lbf', 'Initial gross weight')
        z_bre  = Variable('z_{bre}', '-', 'Breguet parameter')

        # Model
        objective = 1/R  # Maximize range

        constraints = [# Aircraft and fuel weight
                       W_init >= W_e + W_fuel,
                       
                       # Performance constraints
                       W_init <= MTOW,
                       LD <= LD_max,
                       V <= V_max,

                       # Breguet range
                       R <= z_bre*LD*V/(TSFC*g),
                       # Taylor series expansion of exp(z_bre) - 1
                       W_fuel/W_e >= te_exp_minus1(z_bre, nterm=3)
                      ]
        return objective, constraints
Esempio n. 10
0
    def __init__(self, **kwargs):
        T_tp = 216.65
        k = GRAVITATIONAL_ACCEL/(GAS_CONSTANT*T_tp)

        p11 = Variable('p_{11}', 22630, 'Pa', 'Pressure at 11 km')

        objective = 1/rho  # maximize density
        constraints = [h >= 11*units.km,
                       h <= 20*units.km,

                       # Temperature is constant in the tropopause
                       T == T_tp,

                       # Pressure-altitude relation, using taylor series exp
                       TCS([np.exp(k*11000)*p11/p >=
                            1 + te_exp_minus1(g/(R*T)*h, 15)], reltol=1E-4),

                       # Ideal gas law
                       rho == p/(R*T),
                       ]
        su = Sutherland()
        lc = su.link(constraints)

        Model.__init__(self, objective, lc, **kwargs)
Esempio n. 11
0
    def __init__(self):

        CL     = Variable('C_L', '-', 'Lift coefficient')
        CLmax  = Variable('C_{L_{max}}', '-', 'Max lift coefficient')
        CD     = Variable('C_D', '-', 'Drag coefficient')
        D      = Variable('D', 'N', 'Total aircraft drag (cruise)')
        Dfuse  = Variable('D_{fuse}', 'N', 'Fuselage drag')
        Dht    = Variable('D_{ht}', 'N', 'Horizontal tail drag')
        Dvt    = Variable('D_{vt}', 'N', 'Vertical tail drag')
        Dwing  = Variable('D_{wing}', 'N', 'Wing drag')
        LD     = Variable('\\frac{L}{D}', '-', 'Lift/drag ratio')
        Lh     = Variable('L_h', 'N', 'Horizontal tail downforce')
        Lw     = Variable('L_w', 'N', 'Wing lift')
        M      = Variable('M', '-', 'Cruise Mach number')
        R      = Variable('Range', 'nautical_miles', 'Range')
        Sw     = Variable('S_w', 'm**2', 'Wing reference area')
        Te     = Variable('T_e', 'N', 'Engine thrust at takeoff')
        TSFC   = Variable('c_T', 'lb/lbf/hr',
                          'Thrust specific fuel consumption')
        V      = Variable('V_{\\infty}', 'm/s', 'Cruise velocity')
        VTO    = Variable('V_{TO}', 'm/s', 'Takeoff speed')
        W      = Variable('W', 'N', 'Total aircraft weight')
        Weng   = Variable('W_{eng}', 'N', 'Engine weight')
        Wfuel  = Variable('W_{fuel}', 'N', 'Fuel weight')
        Wfuse  = Variable('W_{fuse}', 'N', 'Fuselage weight')
        Wht    = Variable('W_{ht}', 'N', 'Horizontal tail weight')
        Wlg    = Variable('W_{lg}', 'N', 'Landing gear weight')
        Wpay   = Variable('W_{pay}', 'N', 'Payload weight')
        Wvt    = Variable('W_{vt}', 'N', 'Vertical tail weight')
        Wwing  = Variable('W_{wing}', 'N', 'Wing weight')
        Wzf    = Variable('W_{zf}', 'N', 'Zero fuel weight')
        a      = Variable('a', 'm/s', 'Speed of sound (35,000 ft)')
        g      = Variable('g', 9.81, 'm/s^2', 'Gravitational acceleration')
        lr     = Variable('l_r', 5000, 'ft', 'Runway length')
        rho    = Variable('\\rho', 'kg/m^3', 'Air density (cruise)')
        rho0   = Variable('\\rho_0', 'kg/m^3', 'Air density (sea level)')
        xCG    = Variable('x_{CG}', 'm', 'x-location of CG')
        xCGeng = Variable('x_{CG_{eng}}', 'm', 'x-location of engine CG')
        xCGfu  = Variable('x_{CG_{fu}}', 'm', 'x-location of fuselage CG')
        xCGht  = Variable('x_{CG_{ht}}', 'm', 'x-location of htail CG')
        xCGlg  = Variable('x_{CG_{lg}}', 'm', 'x-location of landing gear CG')
        xCGvt  = Variable('x_{CG_{vt}}', 'm', 'x-location of vtail CG') 
        xCGwing = Variable('x_{CG_{wing}}', 'm', 'x-location of wing CG')
        xTO    = Variable('x_{TO}', 'm', 'Takeoff distance')
        xi     = Variable('\\xi', '-', 'Takeoff parameter')
        xw     = Variable('x_w', 'm', 'x-location of wing aerodynamic center')
        y      = Variable('y', '-', 'Takeoff parameter')
        z_bre  = Variable('z_{bre}', '-', 'Breguet parameter')

        with SignomialsEnabled():

            objective = Wfuel

            # High level constraints
            hlc = [
                   # Drag and weight buildup
                   D >= Dvt + Dfuse       + Dwing + Dht,
                   Wzf >= Wvt + Wfuse + Wlg + Wwing + Wht + Weng + Wpay,
                   W >= Wzf + Wfuel,

                   # Range equation for a jet
                   V == M*a,
                   D == 0.5*rho*V**2*Sw*CD,
                   W == 0.5*rho*V**2*Sw*CL,
                   LD == CL/CD,
                   Lw >= W, # TODO: add Lh
                   R <= z_bre*LD*V/(TSFC*g),
                   Wfuel/Wzf >= te_exp_minus1(z_bre, nterm=3),

                   # CG relationships
                   TCS([xCG*W >= Wvt*xCGvt + Wfuse*xCGfu + Wlg*xCGlg
                               + Wwing*xCGwing + Wht*xCGht + Weng*xCGeng
                               + Wfuel*xCGwing + Wpay*xCGfu],
                       reltol=1E-2, raiseerror=False),
                   xw == xCGwing,
                   xCGeng == xCGwing,

                   #Takeoff relationships
                   xi >= 0.5*rho0*VTO**2*Sw*CD/Te,
                   4*g*xTO*Te/(W*VTO**2) >= 1 + y,
                   1 >= 0.0464*xi**2.73/y**2.88 + 1.044*xi**0.296/y**0.049,
                   VTO == 1.2*(2*W/(rho0*Sw*CLmax))**0.5,
                   xTO <= lr,
                  ]

            # Subsystem models
            vt = VerticalTail.coupled737()
            fu = Fuselage.coupled737()
            lg = LandingGear.coupled737()
            ht = HorizontalTail.coupled737()
            wi = Wing.coupled737()
            wb = WingBox()

        substitutions = {
                         'C_{L_{max}}': 2.5,
                         'M': 0.78,
                         'Range': 3000,
                         'c_T': 0.3,
                         'W_{eng}': 10000,
                         'a': 297,
                        }

        lc = LinkedConstraintSet([hlc, vt, fu, lg, ht, wi],
                                 exclude=[vk.name for vk in wb.varkeys
                                          if not vk.value])
        Model.__init__(self, objective,
                             lc,
                             substitutions)
# Constants
g = Variable('g', 9.81, 'm/s^2', 'Gravitational acceleration')
rho = Variable('\\rho', 0.4, 'kg/m^3', 'Air density at 33,000 ft')
rho_sl = Variable('\\rho_{SL}', 1.225, 'kg/m^3', 'Air density at sea level')

# Model
objective = 1 / R  # Maximize range

constraints = [  # Weight buildup
    W >= W_e + W_pay + W_fuel,
    W_e >= f_str * W,

    # Breguet range
    R <= z_bre * CL / CD * V / (TSFC * g),
    # Taylor series expansion of exp(z_bre) - 1
    W_fuel / W_e >= te_exp_minus1(z_bre, nterm=3),

    # Wing geometry
    AR == b**2 / S,
    b <= bmax,

    # Steady level flight
    W == 0.5 * rho * V**2 * S * CL,
    T == 0.5 * rho * V**2 * S * CD,
    T <= T_max,

    # Drag buildup
    CD >= CD0 + CL**2 / (np.pi * e * AR),

    # Speed limited by compressible drag rise
    M == V / a,
Esempio n. 13
0
                                    + W_electrical
                                    + W_avionics
                                    + W_furnishings
                                    + W_air_conditioning
                                    + W_handling_gear
                                    + W_anti_ice
                                    + W_military_cargo_handling_system
                                    + Nen * Wen
                                      ) 
                    ]

# Weights
constraints += [
                W_maximum_gross >= W_operating_empty + Wc + W_fuel,
                zbre >= R * (SFC/V) * (D/L),
                W_fuel >= W_operating_empty*te_exp_minus1(zbre,4),
                W_landing_gross >= .7 * W_maximum_gross
               ]

# # Performance Model
constraints += [
               L == 1./2 * rho * V**2 * CL * S,
               L == W_maximum_gross,
               D == 1./2 * rho * V**2 * CD * S,
               S >= Saft + Scab + Sw ,
               ]

# Aerodynamic Model
constraints += [
                Re == rho*V*chord/mu,
                M == V/a,
Esempio n. 14
0
    def setup(self):
        constraints = []

        # Steady level flight relations
        CD = Variable('C_D', '-', 'Drag coefficient')
        CL = Variable('C_L', '-', 'Lift coefficient')
        P_shaft = Variable('P_{shaft}', 'W', 'Shaft power')
        S = Variable('S', 'm^2', 'Wing reference area')
        V = Variable('V', 'm/s', 'Cruise velocity')
        W = Variable('W', 'lbf', 'Aircraft weight')

        eta_prop = Variable(r'\eta_{prop}', 0.7, '-', 'Propulsive efficiency')
        rho = Variable(r'\rho', 'kg/m^3')

        constraints.extend([P_shaft == V*W*CD/CL/eta_prop,   # eta*P = D*V
                            W == 0.5*rho*V**2*CL*S])

        # Aerodynamics model
        Cd0 = Variable('C_{d0}', 0.01, '-', "non-wing drag coefficient")
        CLmax = Variable('C_{L-max}', 1.5, '-', 'maximum lift coefficient')
        e = Variable('e', 0.9, '-', "spanwise efficiency")
        A = Variable('A', 20, '-', "aspect ratio")
        b = Variable('b', 'ft', 'span')
        mu = Variable(r'\mu', 1.5e-5, 'N*s/m^2', "dynamic viscosity")
        Re = Variable("Re", '-', "Reynolds number")
        Cf = Variable("C_f", "-", "wing skin friction coefficient")
        Kwing = Variable("K_{wing}", 1.3, "-", "wing form factor")
        cl_16 = Variable("cl_{16}", 0.0001, "-", "profile stall coefficient")
        constraints.extend([CD >= Cd0 + 2*Cf*Kwing + CL**2/(pi*e*A) + cl_16*CL**16,
                            b**2 == S*A,
                            CL <= CLmax,
                            Re == rho*V/mu*(S/A)**0.5,
                            Cf >= 0.074/Re**0.2])


        # Engine Weight Model
        W_eng = Variable('W_{eng}', 'lbf', 'Engine weight')
        W_engmin = Variable('W_{min}', 1.3, 'lbf', 'min engine weight')
        W_engmax = Variable('W_{max}', 275, 'lbf', 'max engine weight')
        eta_t = Variable('\\eta_t', 0.75, '-', 'percent throttle')
        eng_cnst = Variable('eng_{cnst}', 0.0011, '-',
                            'engine constant based off of power weight model')
        constraints.extend([W_eng >= W_engmin,
                            W_eng <= W_engmax,
                            W_eng >= P_shaft*eng_cnst/eta_t * units('lbf/watt')])

        # Weight model
        W_airframe = Variable('W_{airframe}', 'lbf', 'Airframe weight')
        W_pay = Variable(r'W_{pay}', 4, 'lbf', 'Payload weight')
        W_fuel = Variable('W_{fuel}', 'lbf', 'Fuel Weight')
        W_zfw = Variable('W_{zfw}', 'lbf', 'Zero fuel weight')
        wl = Variable('wl', 'lbf/ft^2', 'wing loading')

        f_airframe = Variable('f_{airframe}', 0.3, '-',
                              'Airframe weight fraction')
        g = Variable('g', 9.81, 'm/s^2', 'Gravitational acceleration')

        constraints.extend([W_airframe >= W*f_airframe,
                            W_zfw >= W_airframe + W_eng + W_pay,
                            wl == W/S,
                            W >= W_pay + W_eng + W_airframe + W_fuel])

        # Breguet Range
        z_bre = Variable("z_bre", "-", "breguet coefficient")
        h_fuel = Variable("h_{fuel}", 42e6, "J/kg", "heat of combustion")
        eta_0 = Variable("\\eta_0", 0.2, "-", "overall efficiency")
        t = Variable('t', 7, 'days', 'time on station')

        constraints.extend([z_bre >= g*t*V*CD/(h_fuel*eta_0*CL),
                            W_fuel/W_zfw >= te_exp_minus1(z_bre, 3)])

        # Atmosphere model
        h = Variable("h", "ft", "Altitude")
        p_sl = Variable("p_{sl}", 101325, "Pa", "Pressure at sea level")
        T_sl = Variable("T_{sl}", 288.15, "K", "Temperature at sea level")
        L_atm = Variable("L_{atm}", 0.0065, "K/m", "Temperature lapse rate")
        T_atm = Variable("T_{atm}", "K", "air temperature")
        M_atm = Variable("M_{atm}", 0.0289644, "kg/mol",
                         "Molar mass of dry air")
        R_atm = Variable("R_{atm}", 8.31447, "J/mol/K")
        TH = (g*M_atm/R_atm/L_atm).value.magnitude  # dimensionless
        constraints.extend([h <= 20000*units.m,  # Model valid to top of troposphere
                            T_sl >= T_atm + L_atm*h,     # Temp decreases w/ altitude
                            rho <= p_sl*T_atm**(TH-1)*M_atm/R_atm/(T_sl**TH)])
            # http://en.wikipedia.org/wiki/Density_of_air#Altitude

        # station keeping requirement
        footprint = Variable("d_{footprint}", 100, 'km',
                             "station keeping footprint diameter")
        lu = Variable(r"\theta_{look-up}", 5, '-', "look up angle")
        R_earth = Variable("R_{earth}", 6371, "km", "Radius of earth")
        tan_lu = lu*pi/180. + (lu*pi/180.)**3/3.  # Taylor series expansion
        # approximate earth curvature penalty as distance^2/(2*Re)
        constraints.extend([
            h >= tan_lu*0.5*footprint + footprint**2/8./R_earth])

        # wind speed model
        V_wind = Variable('V_{wind}', 'm/s', 'wind speed')
        wd_cnst = Variable('wd_{cnst}', [0.002, 0.0015], 'm/s/ft',
                           'wind speed constant predited by model')
        wd_ln = Variable('wd_{ln}', [13.009, 8.845], 'm/s',
                         'linear wind speed variable')
        h_min = Variable('h_{min}', 11800, 'ft', 'minimum height')
        h_max = Variable('h_{max}', 20800, 'ft', 'maximum height')
        constraints.extend([V_wind >= wd_cnst*h + wd_ln, # model predicting worse case scenario at 45 deg latitude
                            V >= V_wind,
                            h >= h_min,
                            h <= h_max])

        objective = W

        return objective, constraints
Esempio n. 15
0
m_structures = VectorVariable(n_stages,"m_structures","kg")
m_dot = VectorVariable(n_stages,"m_dot","kg/s")
v_exhaust_effective = VectorVariable(n_stages,"v_exhaust_effective","m/s")
F_thrust = VectorVariable(n_stages,"F_thrust","N")
total_mass = VectorVariable(n_stages,"total_mass","kg")
m_total = Variable("m_total","kg")

g = Variable("g",9.8,"m/s/s")

constraints = []
for stage in range(n_stages):
	constraints += [
		Isp[stage] == v_exhaust_effective[stage]/g,
		m_dot[stage] == F_thrust[stage]/(g*Isp[stage]),
		z[stage] >= (dV[stage]+g*(m_fuel[stage]/m_dot[stage]))/v_exhaust_effective[stage],
		theta_fuel[stage] >= te_exp_minus1(z[stage],5)
	]

	if stage == 0:
		constraints+=[F_thrust[stage]/g >= total_mass[stage],
					  total_mass[stage] >= m_fuel[stage]+m_fuel[stage+1]+m_structures[stage]+m_structures[stage+1]+m_payload,
					  m_structures[stage] == 0.02*m_fuel[stage],
					  theta_fuel[stage] == m_fuel[stage]/total_mass[stage]]
	if stage == 1:
		constraints+=[F_thrust[stage]/g >= total_mass[stage],
					total_mass[stage] >= m_fuel[stage]+m_structures[stage] + m_payload,
					m_structures[stage] == 0.02*m_fuel[stage],
					theta_fuel[stage] == m_fuel[stage]/total_mass[stage]]

constraints+=[
			m_total >= m_structures[0] + m_fuel[0] + m_structures[1] + m_fuel[1] + m_payload]
constraints += [
    W_operating_empty >=
    (W_centerbody + W_afterbody + W_wing + W_vertical_tail +
     W_main_landing_gear + W_nose_landing_gear + W_engine_contents +
     W_nacelle_group + W_engine_controls + W_starter_penumatic +
     W_fuel_system + W_flight_controls + W_APU_installed + W_instruments +
     W_hydraulics + W_electrical + W_avionics + W_furnishings +
     W_air_conditioning + W_handling_gear + W_anti_ice +
     W_military_cargo_handling_system + Nen * Wen)
]

# Weights
constraints += [
    W_maximum_gross >= W_operating_empty + Wc + W_fuel,
    zbre >= R * (SFC / V) * (D / L),
    W_fuel >= W_operating_empty * te_exp_minus1(zbre, 4),
    W_landing_gross >= .7 * W_maximum_gross
]

# # Performance Model
constraints += [
    L == 1. / 2 * rho * V**2 * CL * S,
    L == W_maximum_gross,
    D == 1. / 2 * rho * V**2 * CD * S,
    S >= Saft + Scab + Sw,
]

# Aerodynamic Model
constraints += [
    Re == rho * V * chord / mu,
    M == V / a,
Esempio n. 17
0
# Constants
g      = Variable('g', 9.81, 'm/s^2', 'Gravitational acceleration')
rho    = Variable('\\rho', 0.4, 'kg/m^3', 'Air density at 33,000 ft')
rho_sl = Variable('\\rho_{SL}', 1.225, 'kg/m^3', 'Air density at sea level')

# Model
objective = 1/R  # Maximize range

constraints = [# Weight buildup
               W >= W_e + W_pay + W_fuel,
               W_e >= f_str*W,

               # Breguet range
               R <= z_bre*CL/CD*V/(TSFC*g),
               # Taylor series expansion of exp(z_bre) - 1
               W_fuel/W_e >= te_exp_minus1(z_bre, nterm=3),

               # Wing geometry
               AR == b**2/S,
               b <= bmax,

               # Steady level flight
               W == 0.5*rho*V**2*S*CL,
               T == 0.5*rho*V**2*S*CD,
               T <= T_max,

               # Drag buildup
               CD >= CD0 + CL**2/(np.pi*e*AR),

               # Speed limited by compressible drag rise
               M == V/a,
Esempio n. 18
0
    def setup(self):
        constraints = []

        # Steady level flight relations
        CD = Variable('C_D', '-', 'Drag coefficient')
        CL = Variable('C_L', '-', 'Lift coefficient')
        P_shaft = Variable('P_{shaft}', 'W', 'Shaft power')
        S = Variable('S', 'm^2', 'Wing reference area')
        V = Variable('V', 'm/s', 'Cruise velocity')
        W = Variable('W', 'lbf', 'Aircraft weight')

        eta_prop = Variable(r'\eta_{prop}', 0.7, '-', 'Propulsive efficiency')
        rho = Variable(r'\rho', 'kg/m^3')

        constraints.extend([
            P_shaft == V * W * CD / CL / eta_prop,  # eta*P = D*V
            W == 0.5 * rho * V**2 * CL * S
        ])

        # Aerodynamics model
        Cd0 = Variable('C_{d0}', 0.01, '-', "non-wing drag coefficient")
        CLmax = Variable('C_{L-max}', 1.5, '-', 'maximum lift coefficient')
        e = Variable('e', 0.9, '-', "spanwise efficiency")
        A = Variable('A', 20, '-', "aspect ratio")
        b = Variable('b', 'ft', 'span')
        mu = Variable(r'\mu', 1.5e-5, 'N*s/m^2', "dynamic viscosity")
        Re = Variable("Re", '-', "Reynolds number")
        Cf = Variable("C_f", "-", "wing skin friction coefficient")
        Kwing = Variable("K_{wing}", 1.3, "-", "wing form factor")
        cl_16 = Variable("cl_{16}", 0.0001, "-", "profile stall coefficient")
        constraints.extend([
            CD >= Cd0 + 2 * Cf * Kwing + CL**2 / (pi * e * A) + cl_16 * CL**16,
            b**2 == S * A, CL <= CLmax, Re == rho * V / mu * (S / A)**0.5,
            Cf >= 0.074 / Re**0.2
        ])

        # Engine Weight Model
        W_eng = Variable('W_{eng}', 'lbf', 'Engine weight')
        W_engmin = Variable('W_{min}', 1.3, 'lbf', 'min engine weight')
        W_engmax = Variable('W_{max}', 275, 'lbf', 'max engine weight')
        eta_t = Variable('\\eta_t', 0.75, '-', 'percent throttle')
        eng_cnst = Variable('eng_{cnst}', 0.0011, '-',
                            'engine constant based off of power weight model')
        constraints.extend([
            W_eng >= W_engmin, W_eng <= W_engmax,
            W_eng >= P_shaft * eng_cnst / eta_t * units('lbf/watt')
        ])

        # Weight model
        W_airframe = Variable('W_{airframe}', 'lbf', 'Airframe weight')
        W_pay = Variable(r'W_{pay}', 4, 'lbf', 'Payload weight')
        W_fuel = Variable('W_{fuel}', 'lbf', 'Fuel Weight')
        W_zfw = Variable('W_{zfw}', 'lbf', 'Zero fuel weight')
        wl = Variable('wl', 'lbf/ft^2', 'wing loading')

        f_airframe = Variable('f_{airframe}', 0.3, '-',
                              'Airframe weight fraction')
        g = Variable('g', 9.81, 'm/s^2', 'Gravitational acceleration')

        constraints.extend([
            W_airframe >= W * f_airframe, W_zfw >= W_airframe + W_eng + W_pay,
            wl == W / S, W >= W_pay + W_eng + W_airframe + W_fuel
        ])

        # Breguet Range
        z_bre = Variable("z_bre", "-", "breguet coefficient")
        h_fuel = Variable("h_{fuel}", 42e6, "J/kg", "heat of combustion")
        eta_0 = Variable("\\eta_0", 0.2, "-", "overall efficiency")
        t = Variable('t', 7, 'days', 'time on station')

        constraints.extend([
            z_bre >= g * t * V * CD / (h_fuel * eta_0 * CL),
            W_fuel / W_zfw >= te_exp_minus1(z_bre, 3)
        ])

        # Atmosphere model
        h = Variable("h", "ft", "Altitude")
        p_sl = Variable("p_{sl}", 101325, "Pa", "Pressure at sea level")
        T_sl = Variable("T_{sl}", 288.15, "K", "Temperature at sea level")
        L_atm = Variable("L_{atm}", 0.0065, "K/m", "Temperature lapse rate")
        T_atm = Variable("T_{atm}", "K", "air temperature")
        M_atm = Variable("M_{atm}", 0.0289644, "kg/mol",
                         "Molar mass of dry air")
        R_atm = Variable("R_{atm}", 8.31447, "J/mol/K")
        TH = (g * M_atm / R_atm / L_atm).value.magnitude  # dimensionless
        constraints.extend([
            h <= 20000 * units.m,  # Model valid to top of troposphere
            T_sl >= T_atm + L_atm * h,  # Temp decreases w/ altitude
            rho <= p_sl * T_atm**(TH - 1) * M_atm / R_atm / (T_sl**TH)
        ])
        # http://en.wikipedia.org/wiki/Density_of_air#Altitude

        # station keeping requirement
        footprint = Variable("d_{footprint}", 100, 'km',
                             "station keeping footprint diameter")
        lu = Variable(r"\theta_{look-up}", 5, '-', "look up angle")
        R_earth = Variable("R_{earth}", 6371, "km", "Radius of earth")
        tan_lu = lu * pi / 180. + (lu * pi /
                                   180.)**3 / 3.  # Taylor series expansion
        # approximate earth curvature penalty as distance^2/(2*Re)
        constraints.extend(
            [h >= tan_lu * 0.5 * footprint + footprint**2 / 8. / R_earth])

        # wind speed model
        V_wind = Variable('V_{wind}', 'm/s', 'wind speed')
        wd_cnst = Variable('wd_{cnst}', [0.002, 0.0015], 'm/s/ft',
                           'wind speed constant predited by model')
        wd_ln = Variable('wd_{ln}', [13.009, 8.845], 'm/s',
                         'linear wind speed variable')
        h_min = Variable('h_{min}', 11800, 'ft', 'minimum height')
        h_max = Variable('h_{max}', 20800, 'ft', 'maximum height')
        constraints.extend([
            V_wind >= wd_cnst * h +
            wd_ln,  # model predicting worse case scenario at 45 deg latitude
            V >= V_wind,
            h >= h_min,
            h <= h_max
        ])

        objective = W

        return objective, constraints