Exemple #1
0
    def setup(self, static, Wcent):

        Nmax = Variable("N_{max}", 5, "-", "max loading")
        cbar, _ = c_bar(0.5, static.N)
        sigmaai = Variable("\\sigma_{AI}", 207, "MPa", "aluminum max stress")
        kappa = Variable("\\kappa", 0.05, "-", "max tip deflection ratio")

        with Vectorize(static.N - 1):
            Mr = Variable("M_r", "N*m", "wing section root moment")

        with Vectorize(static.N):
            qbar = Variable("\\bar{q}", cbar, "-", "normalized loading")

        beam = Beam(static.N, qbar)

        constraints = [
            # dimensionalize moment of inertia and young's modulus
            beam["\\bar{EI}"] <=
            (8 * static["E"] * static["I"] / Nmax / Wcent / static["b"]**2),
            Mr == (beam["\\bar{M}"][:-1] * Wcent * Nmax * static["b"] / 4),
            sigmaai >= Mr / static["S_y"],
            beam["\\bar{\\delta}"][-1] <= kappa,
        ]

        return beam, constraints
Exemple #2
0
    def setup(self, N, qbar):

        with Vectorize(N - 1):
            EIbar = Variable("\\bar{EI}", "-",
                             "normalized YM and moment of inertia")

        with Vectorize(N):
            Sbar = Variable("\\bar{S}", "-", "normalized shear")
            Mbar = Variable("\\bar{M}", "-", "normalized moment")
            th = Variable("\\theta", "-", "deflection slope")
            dbar = Variable("\\bar{\\delta}", "-", "normalized displacement")

        Sbartip = Variable("\\bar{S}_{tip}", 1e-10, "-", "Tip loading")
        Mbartip = Variable("\\bar{M}_{tip}", 1e-10, "-", "Tip moment")
        throot = Variable("\\theta_{root}", 1e-10, "-", "Base angle")
        dbarroot = Variable("\\bar{\\delta}_{root}", 1e-10, "-",
                            "Base deflection")
        dx = Variable("dx", "-", "normalized length of element")

        constraints = [
            Sbar[:-1] >= Sbar[1:] + 0.5 * dx * (qbar[:-1] + qbar[1:]),
            Sbar[-1] >= Sbartip,
            Mbar[:-1] >= Mbar[1:] + 0.5 * dx * (Sbar[:-1] + Sbar[1:]),
            Mbar[-1] >= Mbartip,
            th[0] >= throot,
            th[1:] >= th[:-1] + 0.5 * dx * (Mbar[1:] + Mbar[:-1]) / EIbar,
            dbar[0] >= dbarroot,
            dbar[1:] >= dbar[:-1] + 0.5 * dx * (th[1:] + th[:-1]),
            1 == (N - 1) * dx,
        ]

        return constraints
Exemple #3
0
    def setup(self, aircraft, N=5, altitude=15000):

        Wfuelfs = Variable("W_{fuel-fs}", "lbf", "flight segment fuel weight")

        self.aircraft = aircraft
        with Vectorize(N):
            W = Variable("W", "lbf", "aircraft weight during flight segment")
            Wstart = Variable("W_{start}", "lbf", "vector-begin weight")
            Wend = Variable("W_{end}", "lbf", "vector-end weight")
            self.fs = FlightState(altitude)
            self.aircraftPerf = self.aircraft.flight_model(self.fs)
            self.slf = SteadyLevelFlight(W, self.fs, self.aircraft,
                                         self.aircraftPerf)
            self.br = BreguetRange(Wstart, Wend, self.aircraftPerf)

        self.submodels = [self.fs, self.aircraftPerf, self.slf, self.br]

        self.constraints = [
            Wfuelfs >= self.br["W_{fuel}"].sum(), W == (Wstart * Wend)**0.5
        ]

        if N > 1:
            self.constraints.extend([Wend[:-1] >= Wstart[1:]])

        return self.aircraft, self.submodels, self.constraints
Exemple #4
0
    def setup(self,
              aircraft,
              N,
              altitude=15000,
              latitude=45,
              percent=90,
              day=355,
              dh=15000):
        fs = FlightSegment(aircraft, N, altitude, latitude, percent, day)

        with Vectorize(N):
            hdot = Variable("\\dot{h}", "ft/min", "Climb rate")

        deltah = Variable("\\Delta_h", dh, "ft", "altitude difference")
        hdotmin = Variable("\\dot{h}_{min}", 100, "ft/min",
                           "minimum climb rate")

        constraints = [
            hdot * fs.be["t"] >= deltah / N,
            hdot >= hdotmin,
            fs.slf["T"] >=
            (0.5 * fs["\\rho"] * fs["V"]**2 * fs["C_D"] * fs.aircraft.wing["S"]
             + fs["W_{start}"] * hdot / fs["V"]),
        ]

        return fs, constraints
Exemple #5
0
    def setup(self, static, state, N=5):
        exec parse_variables(BladeElementProp.__doc__)

        with Vectorize(N):
            blade = BladeElementPerf(static, state)

        constraints = [
            blade.dr == static.R / (N), blade.omega == omega,
            blade.r[0] == static.R / (2. * N)
        ]

        for n in range(1, N):
            constraints += [
                TCS([blade.r[n] >= blade.r[n - 1] + static.R / N]),
                blade.eta_i[n] == blade.eta_i[n - 1],
            ]

        constraints += [
            TCS([Q >= sum(blade.dQ)]), eta == state.V * T / (omega * Q),
            blade.M[-1] <= Mtip, static.T_m >= T, omega <= omega_max
        ]

        with SignomialsEnabled():
            constraints += [TCS([T <= sum(blade.dT)])]

        return constraints, blade
Exemple #6
0
    def setup(self, nt):
        exec parse_variables(Rocket.__doc__)
        self.nt = nt
        self.nozzle = Nozzle()
        with Vectorize(nt):
            self.nozzlePerformance = NozzlePerformance(self.nozzle)
        constraints = []

        return constraints, self.nozzle, self.nozzlePerformance
Exemple #7
0
    def setup(self, N):

        with Vectorize(N - 1):
            EIbar = self.EIbar = Variable(
                "\\bar{EI}", "-", "normalized YM and moment of inertia")
            dx = self.dx = Variable("dx", "-", "normalized length of element")

        with Vectorize(N):
            Sbar = Variable("\\bar{S}", self.SbarFun, "-", "normalized shear")
            Mbar = Variable("\\bar{M}", self.MbarFun, "-", "normalized moment")
            th = Variable("\\theta", "-", "deflection slope")
            dbar = Variable("\\bar{\\delta}", "-", "normalized displacement")
            self.dbar_tip = dbar[-1]

        throot = Variable("\\theta_{root}", 1e-10, "-", "Base angle")
        dbarroot = Variable("\\bar{\\delta}_{root}", 1e-10, "-",
                            "Base deflection")

        constraints = []
        if self.SbarFun is None:
            with Vectorize(N):
                qbar = self.qbar = Variable("\\bar{q}", self.qbarFun, "-",
                                            "normalized loading")
            Sbartip = Variable("\\bar{S}_{tip}", 1e-10, "-", "Tip loading")
            constraints.extend([
                Sbar[:-1] >= Sbar[1:] + 0.5 * dx * (qbar[:-1] + qbar[1:]),
                Sbar[-1] >= Sbartip
            ])

        if self.MbarFun is None:
            Mbartip = Variable("\\bar{M}_{tip}", 1e-10, "-", "Tip moment")
            constraints.extend([
                Mbar[:-1] >= Mbar[1:] + 0.5 * dx * (Sbar[:-1] + Sbar[1:]),
                Mbar[-1] >= Mbartip
            ])

        constraints.extend([
            th[0] >= throot,
            th[1:] >= th[:-1] + 0.5 * dx * (Mbar[1:] + Mbar[:-1]) / EIbar,
            dbar[0] >= dbarroot,
            dbar[1:] >= dbar[:-1] + 0.5 * dx * (th[1:] + th[:-1]),
        ])

        return constraints
Exemple #8
0
    def setup(self, nt, nx):
        exec parse_variables(Rocket.__doc__)
        self.nt = nt
        self.nx = nx
        self.nozzle = Nozzle()
        with Vectorize(nt):
            self.nozzlePerformance = NozzlePerformance(self.nozzle)
            self.section = SRM(nx)
        constraints = [
            # Limiting nozzle size to cross-sectional area
            # self.nozzle.A_e <= np.pi*r**2,
            # Equal time segments
            self.section.dt == t_T/nt,
            # All fuel is consumed
            self.section.A_p_out[:,-1] == 1e-20*np.ones(nx)*np.pi*r**2,
            A_fuel == self.section.A_p_in[:,0],
            T_target == self.nozzlePerformance.T,
            c_T == self.nozzlePerformance.c_T,
            # Fuel parameters
            self.section.k_comb_p == k_comb_p,
            self.section.rho_p == rho_p,
        ]

        for i in range(nt-1):
            constraints += [
                # Decreasing fuel
                self.section.A_p_out[:, i] == self.section.A_p_in[:, i+1],
                # Decreasing sectional area
                self.section.A_in[:,i] <= self.section.A_in[:,i+1],
                self.section.A_out[:,i] <= self.section.A_out[:,i+1],
            ]

        for i in range(nt):
            constraints += [
                # Rocket length is section length,
                self.section.radius[i] == r,
                self.section.l[i] == l,
                # Matching nozzle and section conditions
                self.nozzlePerformance.mdot[i] == self.section.mdot_out[i],
                self.nozzlePerformance.T_t[i] == self.section.T_t_out[i],
                # Maximum chamber pressure
                self.section.P_chamb[:, i] <= P_max,
                self.nozzlePerformance.P_star[i] <= P_max,
            ]
            with SignomialsEnabled():
                constraints += [
                # Matching nozzle stagnation pressure
                Tight([self.nozzlePerformance.P_t[i] <= s[i]*(self.section.P_out[i] +
                                0.5*self.section.rho_out[i]*self.section.u_out[i]**2)], name='PtNozzle', printwarning=True),
                s[i]*self.nozzlePerformance.P_t[i] >= self.section.P_out[i] +
                                0.5*self.section.rho_out[i]*self.section.u_out[i]**2,
                s[i] >= 1
                ]

        return constraints, self.nozzle, self.nozzlePerformance, self.section
    def setup(self, aircraft):
        with Vectorize(4):  # four flight segments
            fs = FlightSegment(aircraft)

        Wburn = fs.aircraftp["W_{burn}"]
        Wfuel = fs.aircraftp["W_{fuel}"]
        self.takeoff_fuel = Wfuel[0]

        return fs, [
            Wfuel[:-1] >= Wfuel[1:] + Wburn[:-1], Wfuel[-1] >= Wburn[-1]
        ]
    def setup(self, aircraft):
        self.aircraft = aircraft

        with Vectorize(4):  # four flight segments
            self.fs = FlightSegment(aircraft)

        Wburn = self.fs.aircraftp.Wburn
        Wfuel = self.fs.aircraftp.Wfuel
        self.takeoff_fuel = Wfuel[0]

        return self.fs, [
            Wfuel[:-1] >= Wfuel[1:] + Wburn[:-1], Wfuel[-1] >= Wburn[-1]
        ]
Exemple #11
0
def return_radii(nPoints, sol, mrocket):
    nt = len(sol('A_avg')[0])
    nx = len(sol('A_avg')[:, 0])
    with Vectorize(nt):
        with Vectorize(nx):
            m = Star(nPoints)
    linkingConstraints = []
    for i in m.variables_byname('r_o'):
        linkingConstraints += [
            i <= sol(mrocket.r), m['r_{ii}'] <= m['r_i'], m['r_i'] <= m['r_o']
        ]
    for j in range(nt - 1):
        linkingConstraints += [
            m['r_i'][:, j] <= m['r_i'][:, j + 1],
            m['r_o'][:, j] <= m['r_o'][:, j + 1],
            m['r_{ii}'][:, j] <= m['r_{ii}'][:, j + 1],
        ]
    cost = np.prod(m['slack']**10) * np.prod(
        m['r_o'] * m['r_i']**-1 * m['h_e']**-1)
    m = Model(cost, [m, linkingConstraints], m.substitutions)
    m.substitutions.update({'A': sol('A_out'), 'C': sol('l_b')})
    r_sol = m.localsolve(verbosity=4)
    return r_sol
    def setup(self, aircraft):
        self.aircraft = aircraft

        with Vectorize(4):  # four flight segments
            self.fs = FlightSegment(aircraft)

        Wburn = self.fs.aircraftp.Wburn
        Wfuel = self.fs.aircraftp.Wfuel
        self.takeoff_fuel = Wfuel[0]

        return {
            "definition of Wburn": Wfuel[:-1] >= Wfuel[1:] + Wburn[:-1],
            "require fuel for the last leg": Wfuel[-1] >= Wburn[-1],
            "flight segment": self.fs
        }
Exemple #13
0
    def setup(self, N, aircraft, alt=15000, wind=False, etap=0.7, dh=15000):
        fs = FlightSegment(N, aircraft, alt, wind, etap)

        with Vectorize(N):
            hdot = Variable("\\dot{h}", "ft/min", "Climb rate")

        deltah = Variable("\\Delta h", dh, "ft", "altitude difference")
        hdotmin = Variable("\\dot{h}_{min}", 100, "ft/min",
                           "minimum climb rate")

        constraints = [
            hdot*fs.be["t"] >= deltah/N,
            hdot >= hdotmin,
            fs.slf["T"] >= (0.5*fs["\\rho"]*fs["V"]**2*fs["C_D"]
                            * fs.aircraft.wing["S"] + fs["W_{start}"]*hdot
                            / fs["V"]),
            ]

        return fs, constraints
Exemple #14
0
    def setup(self, N, aircraft):
        self.N = N

        with Vectorize(self.N):
            self.drag = AircraftDrag(aircraft, self)

        Wtotal = self.Wtotal = aircraft.Wtotal
        CD = self.CD = self.drag.CD
        CL = self.CL = self.drag.CL
        S = self.S = aircraft.wing.planform.S
        E = aircraft.battery.E
        Poper = self.drag.Poper
        T = self.drag.T
        self.rho = rho

        constraints = [
            Wtotal <= 0.5 * rho * V**2 * CL * S,
            T >= 0.5 * rho * V**2 * CD * S + Wtotal * hdot / V,
            hdot >= dh / dt, t >= sum(hstack(dt)), E >= sum(hstack(Poper * dt))
        ]

        return self.drag, constraints
Exemple #15
0
    def setup(self, N, aircraft, alt=15000, wind=False, etap=0.7):

        self.aircraft = aircraft

        with Vectorize(N):
            self.fs = FlightState(alt, wind)
            self.aircraftPerf = self.aircraft.flight_model(self.fs)
            self.slf = SteadyLevelFlight(self.fs, self.aircraft,
                                         self.aircraftPerf, etap)
            self.be = BreguetEndurance(self.aircraftPerf)

        self.submodels = [self.fs, self.aircraftPerf, self.slf, self.be]

        Wfuelfs = Variable("W_{fuel-fs}", "lbf", "flight segment fuel weight")

        self.constraints = [Wfuelfs >= self.be["W_{fuel}"].sum()]

        if N > 1:
            self.constraints.extend([self.aircraftPerf["W_{end}"][:-1] >=
                                     self.aircraftPerf["W_{start}"][1:]])

        return self.aircraft, self.submodels, self.constraints
    def setup(self,aircraft,Nmissions,Nsegments):
        self.aircraft = aircraft
        self.missions = []
        for i in range(0,Nmissions):
            self.missions.append(Mission(self.aircraft,Nsegments))

        # Multimission objective variables
        W_f_mm = Variable('W_{f_{mm}}','N','multimission fuel weight')

        with Vectorize(Nmissions):
            # Mission variables
            hcruise    = Variable('h_{cruise_{mm}}', 'm', 'minimum cruise altitude')
            Range      = Variable("Range_{mm}", "km", "aircraft range")
            W_p        = Variable("W_{p_{mm}}", "N", "payload weight", pr=20.)
            V_min      = Variable("V_{min_{mm}}", 25, "m/s", "takeoff speed", pr=20.)
            cost_index = Variable("C_{mm}", '1/hr','hourly cost index')
            TOfac      = Variable('T/O factor_{mm}', 2.,'-','takeoff thrust factor')

        constraints = []

        # Setting up the missions
        for i in range(0,Nmissions):
            constraints += [
            self.missions[i]['h_{cruise_m}'] == hcruise[i],
            self.missions[i]['Range_m']      == Range[i],
            self.missions[i]['W_{p_m}']        == W_p[i],
            self.missions[i]['V_{min_m}']    == V_min[i],
            self.missions[i]['C_m']          == cost_index[i],
            self.missions[i]['T/O factor_m'] == TOfac[i],
            # Upper bounding relevant variables
            W_f_mm <= 1e11*units('N'),
            ]

        # Multimission constraints
        constraints += [W_f_mm >= sum(self.missions[i]['W_{f_m}'] for i in range(0,Nmissions))]



        return constraints, self.aircraft, self.missions
Exemple #17
0
    def test_init(self):
        """Test VectorVariable initialization"""
        # test 1
        n = 3
        v = VectorVariable(n, 'v', label='dummy variable')
        self.assertTrue(isinstance(v, NomialArray))
        v_mult = 3*v
        for i in range(n):
            self.assertTrue(isinstance(v[i], PlainVariable))
            self.assertTrue(isinstance(v[i], Monomial))
            # test that operations on Variable cast to Monomial
            self.assertTrue(isinstance(v_mult[i], Monomial))
            self.assertFalse(isinstance(v_mult[i], PlainVariable))

        # test 2
        x = VectorVariable(3, 'x', label='dummy variable')
        x_0 = Variable('x', idx=(0,), shape=(3,), label='dummy variable')
        x_1 = Variable('x', idx=(1,), shape=(3,), label='dummy variable')
        x_2 = Variable('x', idx=(2,), shape=(3,), label='dummy variable')
        x2 = NomialArray([x_0, x_1, x_2])
        self.assertEqual(x, x2)

        # test inspired by issue 137
        N = 20
        x_arr = np.arange(0, 5, 5/N) + 1e-6
        x = VectorVariable(N, 'x', x_arr, 'm', "Beam Location")

        with self.assertRaises(ValueError):
            _ = VectorVariable(2, "x", [1, 2, 3])

        with Vectorize(2):
            x = VectorVariable(3, "x", np.array([13, 15, 17]))
            self.assertEqual(x[0, 0].value, 13)
            self.assertEqual(x[1, 0].value, 15)
            self.assertEqual(x[2, 0].value, 17)
            self.assertEqual(x[0, 0].value, x[0, 1].value)
            self.assertEqual(x[1, 0].value, x[1, 1].value)
            self.assertEqual(x[2, 0].value, x[2, 1].value)
Exemple #18
0
    def setup(self, b, cave, tau, N=5):

        self.N = N
        rho_cfrp = Variable("\\rho_{CFRP}", 1.6, "g/cm^3", "density of CFRP")
        E = Variable("E", 2e7, "psi", "Youngs modulus of CF")

        with Vectorize(self.N - 1):
            d = Variable("d", "in", "spar diameter")
            I = Variable("I", "m^4", "spar x moment of inertia")
            Sy = Variable("S_y", "m**3", "section modulous")
            A = Variable("A", "in**2", "spar cross sectional area")
            dm = Variable("dm", "kg", "segment spar mass")

        W = Variable("W", "lbf", "tube spar weight")
        g = Variable("g", 9.81, "m/s**2", "gravitational constant")

        constraints = [
            dm >= rho_cfrp * A * b / (N - 1), W >= 2 * dm.sum() * g,
            cave * tau >= d, 4 * I**2 / A**2 / (d / 2)**2 + A / pi <=
            (d / 2)**2, Sy * (d / 2) <= I, E == E
        ]

        return constraints
Exemple #19
0
    def setup(self, static, state, onDesign=False):
        fd = dirname(abspath(__file__)) + sep + "dai1336a.csv"

        self.wing = static.wing.flight_model(static.wing, state, fitdata=fd)
        self.htail = static.emp.htail.flight_model(static.emp.htail, state)
        self.vtail = static.emp.vtail.flight_model(static.emp.vtail, state)
        self.tailboom = static.emp.tailboom.flight_model(
            static.emp.tailboom, state)
        self.motor = static.motor.flight_model(static.motor, state)
        if static.sp:
            if onDesign:
                static.propeller.flight_model = BladeElementProp

        self.propeller = static.propeller.flight_model(static.propeller, state)

        self.flight_models = [
            self.wing, self.htail, self.vtail, self.tailboom, self.motor,
            self.propeller
        ]

        e = self.e = self.wing.e
        cdht = self.cdht = self.htail.Cd
        cdvt = self.cdvt = self.vtail.Cd
        Sh = self.Sh = static.Sh
        Sv = self.Sv = static.Sv
        Sw = self.Sw = static.Sw
        cftb = self.cftb = self.tailboom.Cf
        Stb = self.Stb = static.emp.tailboom.S
        cdw = self.cdw = self.wing.Cd
        self.CL = self.wing.CL
        Nprop = static.Nprop
        Tprop = self.propeller.T
        Qprop = self.propeller.Q
        RPMprop = self.propeller.omega
        Qmotor = self.motor.Q
        RPMmotor = self.motor.omega
        Pelec = self.motor.Pelec

        self.wing.substitutions[e] = 0.95
        self.wing.substitutions[self.wing.CLstall] = 4

        self.wing.substitutions[e] = 0.95
        dvars = [cdht * Sh / Sw, cdvt * Sv / Sw, cftb * Stb / Sw]

        if static.Npod is not 0:
            with Vectorize(static.Npod):
                self.fuse = static.fuselage.flight_model(
                    static.fuselage, state)
            self.flight_models.extend([self.fuse])
            cdfuse = self.fuse.Cd
            Sfuse = static.fuselage.S
            dvars.extend(cdfuse * Sfuse / Sw)
            self.fuse.substitutions[self.fuse.mfac] = 1.1

        constraints = [
            cda >= sum(dvars),
            Tprop == T / Nprop,
            Qmotor == Qprop,
            RPMmotor == RPMprop,
            CD / mfac >= cda + cdw,
            Poper / mpower >= Pavn + Ppay + (Pelec * Nprop),
        ]

        return self.flight_models, constraints
Exemple #20
0
    def setup(self, Nmissions, **kwargs):
        g = Variable('g', 9.81, 'm*s^-2', 'Acceleration due to gravity')
        dPover = Variable('\\Delta P_{over}', 'psi', 'Cabin overpressure')
        with Vectorize(Nmissions):
            npass = Variable('n_{pass}', '-', 'Number of passengers')
        Nland = Variable('N_{land}', 6.0, '-',
                         'Emergency landing load factor')  # [TAS]
        Nlift = Variable('N_{lift}', '-', 'Wing maximum load factor')
        SPR = Variable('SPR', '-', 'Number of seats per row')
        nrows = Variable('n_{rows}', '-', 'Number of rows')
        nseat = Variable('n_{seat}', '-', 'Number of seats')
        pitch = Variable('p_s', 'cm', 'Seat pitch')

        # Cross-sectional variables
        Adb = Variable('A_{db}', 'm^2', 'Web cross sectional area')
        Afloor = Variable('A_{floor}', 'm^2', 'Floor beam x-sectional area')
        Afuse = Variable('A_{fuse}', 'm^2', 'Fuselage x-sectional area')
        Askin = Variable('A_{skin}', 'm^2', 'Skin cross sectional area')
        hdb = Variable('h_{db}', 'm', 'Web half-height')
        hfloor = Variable('h_{floor}', 'm', 'Floor beam height')
        hfuse = Variable('h_{fuse}', 'm', 'Fuselage height')
        dRfuse = Variable('\\Delta R_{fuse}', 'm', 'Fuselage extension height')
        Rfuse = Variable('R_{fuse}', 'm', 'Fuselage radius')
        tdb = Variable('t_{db}', 'm', 'Web thickness')
        thetadb = Variable('\\theta_{db}', '-', 'DB fuselage joining angle')
        tshell = Variable('t_{shell}', 'm', 'Shell thickness')
        tskin = Variable('t_{skin}', 'm', 'Skin thickness')
        waisle = Variable('w_{aisle}', 'm', 'Aisle width')
        wdb = Variable('w_{db}', 'm', 'DB added half-width')
        wfloor = Variable('w_{floor}', 'm', 'Floor half-width')
        wfuse = Variable('w_{fuse}', 'm', 'Fuselage half-width')
        wseat = Variable('w_{seat}', 'm', 'Seat width')
        wsys = Variable('w_{sys}', 'm',
                        'Width between cabin and skin for systems')

        # Tail cone variables
        lamcone = Variable('\\lambda_{cone}', '-',
                           'Tailcone radius taper ratio')
        lcone = Variable('l_{cone}', 'm', 'Cone length')
        plamv = Variable('p_{\\lambda_{vt}}', 1.6, '-',
                         '1 + 2*Tail taper ratio')
        # tcone = Variable('t_{cone}', 'm', 'Cone thickness') # perhaps to be added later

        # Lengths
        c0 = Variable('c_0', 'm', 'Root chord of the wing')
        lfuse = Variable('l_{fuse}', 'm', 'Fuselage length')
        lnose = Variable('l_{nose}', 'm', 'Nose length')
        lshell = Variable('l_{shell}', 'm', 'Shell length')
        lfloor = Variable('l_{floor}', 'm', 'Floor length')

        # Surface areas
        Sbulk = Variable('S_{bulk}', 'm^2', 'Bulkhead surface area')
        Snose = Variable('S_{nose}', 'm^2', 'Nose surface area')

        # Volumes
        Vbulk = Variable('V_{bulk}', 'm^3', 'Bulkhead skin volume')
        Vcabin = Variable('V_{cabin}', 'm^3', 'Cabin volume')
        Vcone = Variable('V_{cone}', 'm^3', 'Cone skin volume')
        Vcyl = Variable('V_{cyl}', 'm^3', 'Cylinder skin volume')
        Vdb = Variable('V_{db}', 'm^3', 'Web volume')
        Vfloor = Variable('V_{floor}', 'm^3', 'Floor volume')
        Vnose = Variable('V_{nose}', 'm^3', 'Nose skin volume')

        # Loads
        sigskin = Variable('\\sigma_{skin}', 'N/m^2',
                           'Max allowable skin stress')
        sigth = Variable('\\sigma_{\\theta}', 'N/m^2', 'Skin hoop stress')
        sigx = Variable('\\sigma_x', 'N/m^2', 'Axial stress in skin')

        # Floor loads
        Mfloor = Variable('M_{floor}', 'N*m',
                          'Max bending moment in floor beams')
        Pfloor = Variable('P_{floor}', 'N', 'Distributed floor load')
        Sfloor = Variable('S_{floor}', 'N', 'Maximum shear in floor beams')
        sigfloor = Variable('\\sigma_{floor}', 'N/m^2',
                            'Max allowable floor stress')
        taucone = Variable('\\tau_{cone}', 'N/m^2', 'Shear stress in cone')
        taufloor = Variable('\\tau_{floor}', 'N/m^2',
                            'Max allowable shear web stress')

        # Bending inertias (ported from TASOPT)
        # (shell inertia contribution)
        A0h = Variable('A_{0h}', 'm^2', 'Horizontal bending area constant A0h')

        # (tail impact + aero loading)
        A1hLand = Variable(
            'A_{1h_{Land}}', 'm',
            'Horizontal bending area constant A1h (landing case)')
        A1hMLF = Variable(
            'A_{1h_{MLF}}', 'm',
            'Horizontal bending area constant A1h (max aero load case)')

        # (fuselage impact)
        A2hLand = Variable(
            'A_{2h_{Land}}', '-',
            'Horizontal bending area constant A2h (landing case)')
        A2hMLF = Variable(
            'A_{2h_{MLF}}', '-',
            'Horizontal bending area constant A2h (max aero load case)')

        AhbendbLand = Variable(
            'A_{hbendb_{Land}}', 'm^2',
            'Horizontal bending area at rear wingbox (landing case)')
        AhbendbMLF = Variable(
            'A_{hbendb_{MLF}}', 'm^2',
            'Horizontal bending area at rear wingbox (max aero load case)')

        AhbendfLand = Variable(
            'A_{hbendf_{Land}}', 'm^2',
            'Horizontal bending area at front wingbox (landing case)')
        AhbendfMLF = Variable(
            'A_{hbendf_{MLF}}', 'm^2',
            'Horizontal bending area at front wingbox (max aero load case)')

        Avbendb = Variable('A_{vbend_{b}}', 'm^2',
                           'Vertical bending material area at rear wingbox')

        B0v = Variable(
            'B_{0v}', 'm^2',
            'Vertical bending area constant B0')  #(shell inertia contribution)
        B1v = Variable('B_{1v}', 'm', 'Vertical bending area constant B1')
        # #(vertical tail bending load)
        Ihshell = Variable('I_{h_{shell}}', 'm^4',
                           'Shell horizontal bending inertia')
        Ivshell = Variable('I_{v_{shell}}', 'm^4',
                           'Shell vertical bending inertia')
        rMh = Variable('r_{M_h}', .4, '-',
                       'Horizontal inertial relief factor')  # [TAS]
        rMv = Variable('r_{M_v}', .7, '-',
                       'Vertical inertial relief factor')  # [TAS]
        sigbend = Variable('\\sigma_{bend}', 'N/m^2',
                           'Bending material stress')
        sigMh = Variable('\\sigma_{M_h}', 'N/m^2',
                         'Horizontal bending material stress')
        sigMv = Variable('\\sigma_{M_v}', 'N/m^2',
                         'Vertical bending material stress')
        Vhbend = Variable('V_{hbend}', 'm^3',
                          'Horizontal bending material volume')

        Vhbendb = Variable(
            'V_{hbend_{b}}', 'm^3',
            'Horizontal bending material volume b')  # back fuselage
        Vhbendc = Variable(
            'V_{hbend_{c}}', 'm^3',
            'Horizontal bending material volume c')  # center fuselage
        Vhbendf = Variable(
            'V_{hbend_{f}}', 'm^3',
            'Horizontal bending material volume f')  # front fuselage

        Vvbend = Variable('V_{vbend}', 'm^3',
                          'Vertical bending material volume')
        Vvbendb = Variable(
            'V_{vbend_{b}}', 'm^3',
            'Vertical bending material volume b')  #back fuselage
        Vvbendc = Variable(
            'V_{vbend_{c}}', 'm^3',
            'Vertical bending material volume c')  #center fuselage

        Whbend = Variable('W_{hbend}', 'lbf',
                          'Horizontal bending material weight')
        Wvbend = Variable('W_{vbend}', 'lbf',
                          'Vertical bending material weight')

        xhbendLand = Variable(
            'x_{hbend_{Land}}', 'ft',
            'Horizontal zero bending location (landing case)')
        xhbendMLF = Variable(
            'x_{hbend_{MLF}}', 'ft',
            'Horizontal zero bending location (maximum aero load case)')
        xvbend = Variable('x_{vbend}', 'ft', 'Vertical zero bending location')

        # Material properties
        rE = Variable(
            'r_E', 1., '-',
            'Ratio of stringer/skin moduli')  # [TAS] # [b757 freight doc]
        rhocargo = Variable('\\rho_{cargo}', 150, 'kg/m^3', 'Cargo density')
        rhocone = Variable('\\rho_{cone}', 'kg/m^3',
                           'Cone material density')  # [TAS]
        rhobend = Variable('\\rho_{bend}', 'kg/m^3',
                           'Stringer density')  # [TAS]
        rhofloor = Variable('\\rho_{floor}', 'kg/m^3',
                            'Floor material density')  # [TAS]
        rholugg = Variable('\\rho_{lugg}', 100, 'kg/m^3',
                           'Luggage density')  # [Philippe]
        rhoskin = Variable('\\rho_{skin}', 'kg/m^3', 'Skin density')  # [TAS]
        Wppfloor = Variable('W\'\'_{floor}', 'N/m^2',
                            'Floor weight/area density')  # [TAS]
        Wppinsul = Variable(
            'W\'\'_{insul}', 'N/m^2',
            'Weight/area density of insulation material')  # [TAS]
        Wpseat = Variable('W\'_{seat}', 'N', 'Weight per seat')  # [TAS]
        Wpwindow = Variable('W\'_{window}', 'N/m',
                            'Weight/length density of windows')  # [TAS]

        # Weight fractions
        fapu = Variable('f_{apu}', 0.035, '-',
                        'APU weight as fraction of payload weight')  # [TAS]
        ffadd = Variable(
            'f_{fadd}', '-',
            'Fractional added weight of local reinforcements')  # [TAS]
        fframe = Variable('f_{frame}', '-',
                          'Fractional frame weight')  # [Philippe]
        flugg1 = Variable(
            'f_{lugg,1}', '-',
            'Proportion of passengers with one suitcase')  # [Philippe]
        flugg2 = Variable(
            'f_{lugg,2}', '-',
            'Proportion of passengers with two suitcases')  # [Philippe]
        fpadd = Variable('f_{padd}', 0.35, '-',
                         'Other misc weight as fraction of payload weight')
        fseat = Variable('f_{seat}', '-', 'Fractional seat weight')
        fstring = Variable('f_{string}', '-',
                           'Fractional stringer weight')  # [Philippe]

        # Weights
        Wapu = Variable('W_{apu}', 'lbf', 'APU weight')
        Wavgpass = Variable('W_{avg. pass}', 'lbf',
                            'Average passenger weight')  # [Philippe]
        Wavgpasstot = Variable(
            'W_{avg. pass_{total}}', 215., 'lbf',
            'Average passenger weight including payload')  #[TAS]
        Wcargo = Variable('W_{cargo}', 'lbf', 'Cargo weight')  # [Philippe]
        Wcarryon = Variable('W_{carry on}', 'lbf',
                            'Ave. carry-on weight')  # [Philippe]
        Wchecked = Variable('W_{checked}', 'lbf',
                            'Ave. checked bag weight')  # [Philippe]
        Wcone = Variable('W_{cone}', 'lbf', 'Cone weight')
        Wdb = Variable('W_{db}', 'lbf', 'Web weight')
        Wfix = Variable('W_{fix}', 'lbf',
                        'Fixed weights (pilots, cockpit seats, navcom)')
        Wfloor = Variable('W_{floor}', 'lbf', 'Floor weight')
        Wfuse = Variable('W_{fuse}', 'lbf', 'Fuselage weight')
        Winsul = Variable('W_{insul}', 'lbf', 'Insulation material weight')
        Wpadd = Variable('W_{padd}', 'lbf',
                         'Misc weights (galley, toilets, doors etc.)')
        Wseat = Variable('W_{seat}', 'lbf', 'Seating weight')
        Wshell = Variable('W_{shell}', 'lbf', 'Shell weight')
        Wskin = Variable('W_{skin}', 'lbf', 'Skin weight')
        Wtail = Variable('W_{tail}', 'lbf', 'Total tail weight')
        Wwindow = Variable('W_{window}', 'lbf', 'Window weight')

        with Vectorize(Nmissions):
            Wpay = Variable('W_{payload}', 'lbf', 'Payload weight')
            Wlugg = Variable('W_{lugg}', 'lbf', 'Passenger luggage weight')
            Wpass = Variable('W_{pass}', 'lbf', 'Passenger weight')
        Wpaymax = Variable('W_{payload_{max}}', 'lbf',
                           'Maximum payload weight')

        # x-location variables
        xshell1 = Variable('x_{shell1}', 'm', 'Start of cylinder section')
        xshell2 = Variable('x_{shell2}', 'm', 'End of cylinder section')
        xtail = Variable('x_{tail}', 'm', 'x-location of tail')
        xwing = Variable('x_{wing}', 'm', 'x-location of wing c/4')

        # Wingbox variables
        xf = Variable('x_f', 'm', 'x-location of front of wingbox')
        xb = Variable('x_b', 'm', 'x-location of back of wingbox')
        w = Variable('r_{w/c}', 0.5, '-', 'Wingbox width-to-chord ratio')

        #weight margin and sensitivity
        Cfuse = Variable('C_{fuse}', 1, '-',
                         'Fuselage Weight Margin and Sensitivity')

        #fuselage drag reference mach
        MfuseD = Variable('M_{fuseD}', '-', 'Fuselage Drag Reference Mach')

        # Moments
        # alphaMf0 = Variable('\\alpha_{Mf0}','-','AoA at which fuselage moment is zero')

        constraints = []
        with SignomialsEnabled():
            constraints.extend([
                # Passenger constraints
                Wlugg >= flugg2 * npass * 2 * Wchecked + flugg1 * npass * Wchecked + Wcarryon,
                TCS([Wpass >= npass * Wavgpass]),
                Wpay >= Wpass + Wlugg + Wcargo,
                TCS([Wpay >= npass * Wavgpasstot]),
                Wpaymax >= Wpay,
                nseat >= npass,
                nrows == nseat / SPR,
                lshell == nrows * pitch,

                # Fuselage joint angle relations
                thetadb == wdb / Rfuse,  # first order Taylor works...
                hdb >= Rfuse * (1.0 - .5 * thetadb**2),  # [SP]

                # Cross-sectional constraints
                Adb >= (2 * hdb + dRfuse) * tdb,
                Afuse >= (pi + 2 * thetadb + 2 * thetadb * \
                          (1 - thetadb**2 / 2)) * Rfuse**2 + 2*dRfuse*Rfuse,  # [SP]
                Askin >= (2 * pi + 4 * thetadb) * Rfuse * tskin + 2*dRfuse*tskin,
                wfloor == wfuse,
                wfuse <= (Rfuse + wdb),
                SignomialEquality(hfuse, Rfuse + 0.5*dRfuse), #[SP] #[SPEquality]
                TCS([tshell <= tskin * (1. + rE * fstring * rhoskin / rhobend)]), #[SP]

                # Fuselage surface area relations
                Snose >= (2 * pi + 4 * thetadb) * Rfuse**2 * \
                (1 / 3 + 2 / 3 * (lnose / Rfuse)**(8 / 5))**(5 / 8),
                Sbulk >= (2 * pi + 4 * thetadb) * Rfuse**2,

                # Fuselage length relations
                SignomialEquality(lfuse, lnose + lshell + lcone), #[SP] #[SPEquality]
                    # NOTE: it is not clear which direction the pressure is!
                lcone == Rfuse / lamcone,
                xshell1 == lnose,
                TCS([xshell2 >= lnose + lshell]),
                # STRESS RELATIONS
                # Pressure shell loading
                tskin == dPover * Rfuse / sigskin,
                tdb == 2 * dPover * wdb / sigskin,
                sigx == dPover * Rfuse / (2 * tshell),
                sigth == dPover * Rfuse / tskin,

                # Floor loading
                lfloor >= lshell + 2 * Rfuse,
                TCS([Pfloor >= Nland * (Wpaymax + Wseat)]),
                Afloor >= 2. * Mfloor / (sigfloor * hfloor) + 1.5 * Sfloor / taufloor,
                Vfloor == 2 * wfloor * Afloor,
                Wfloor >= rhofloor * g * Vfloor + 2 * wfloor * lfloor * Wppfloor,
                # hfloor <= 0.1 * Rfuse,

                # Tail cone sizing
                taucone == sigskin,
                Wcone >= rhocone * g * Vcone * (1 + fstring + fframe),
                xtail >= lnose + lshell + .5 * lcone,

                # BENDING MODEL
                # Maximum axial stress is the sum of bending and pressurization
                # stresses
                Ihshell <= ((pi + 4 * thetadb) * Rfuse**2 + 8.*(1-thetadb**2/2) * (dRfuse/2.)*Rfuse + \
                            (2*pi + 4 * thetadb)*(dRfuse/2)**2) * Rfuse * tshell + \
                    2 / 3 * (hdb + dRfuse/2.)**3 * tdb,  # [SP]
                Ivshell <= (pi*Rfuse**2 + 8*wdb*Rfuse + (2*pi+4*thetadb)*wdb**2)*Rfuse*tshell, #[SP] #Ivshell
                # approximation needs to be improved

                # Horizontal bending material model
                # Calculating xhbend, the location where additional bending
                # material is required
                xhbendLand >= xwing, xhbendLand <= lfuse,
                xhbendMLF >= xwing, xhbendMLF <= lfuse,

                SignomialEquality(A0h, A2hLand * (xshell2 - xhbendLand) ** 2 + A1hLand * (xtail - xhbendLand)), # [SP] #[SPEquality]
                SignomialEquality(A0h, A2hMLF * (xshell2 - xhbendMLF) ** 2 + A1hMLF * (xtail - xhbendMLF)), # [SP] #[SPEquality]

                A2hLand >= Nland * (Wpaymax + Wpadd + Wshell + Wwindow + Winsul + Wfloor + Wseat) / \
                (2 * lshell * hfuse * sigMh),  # Landing loads constant A2hLand
                A2hMLF >= Nlift * (Wpaymax + Wpadd + Wshell + Wwindow + Winsul + Wfloor + Wseat) / \
                (2 * lshell * hfuse * sigMh),  # Max wing aero loads constant A2hMLF

                # Shell inertia constant A0h
                A0h == (Ihshell / (rE * hfuse**2)), # [SP]

                # Bending area behind wingbox
                AhbendfLand >= A2hLand * (xshell2 - xf)**2 + A1hLand * (xtail - xf) - A0h, # [SP]
                AhbendfMLF >= A2hMLF * (xshell2 - xf)**2 + A1hMLF * (xtail - xf) - A0h, # [SP]

                # Bending area in front of wingbox
                AhbendbLand >= A2hLand * (xshell2 - xb)**2 + A1hLand * (xtail - xb) - A0h, # [SP]
                AhbendbMLF >= A2hMLF * (xshell2 - xb)**2 + A1hMLF * (xtail - xb) - A0h, # [SP]

                # Bending volume forward of wingbox
                Vhbendf >= A2hLand / 3 * ((xshell2 - xf)**3 - (xshell2 - xhbendLand)**3) \
                + A1hLand / 2 * ((xtail - xf)**2 - (xtail - xhbendLand)**2) \
                - A0h * (xhbendLand - xf),  # [SP]
                Vhbendf >= A2hMLF / 3 * ((xshell2 - xf)**3 - (xshell2 - xhbendMLF)**3) \
                + A1hMLF / 2 * ((xtail - xf)**2 - (xtail - xhbendMLF)**2) \
                - A0h * (xhbendMLF - xf),  # [SP]

                # Bending volume behind wingbox
                Vhbendb >= A2hLand / 3 * ((xshell2 - xb)**3 - (xshell2 - xhbendLand)**3) \
                + A1hLand / 2 * ((xtail - xb)**2 - (xtail - xhbendLand)**2) \
                - A0h * (xhbendLand - xb),  # [SP]
                Vhbendb >= A2hMLF / 3 * ((xshell2 - xb)**3 - (xshell2 - xhbendMLF)**3) \
                + A1hMLF / 2 * ((xtail - xb)**2 - (xtail - xhbendMLF)**2) \
                - A0h * (xhbendMLF - xb),  # [SP]

                # Bending volume over wingbox
                Vhbendc >= .5 * (AhbendfLand + AhbendbLand) * c0 * w,
                Vhbendc >= .5 * (AhbendfMLF + AhbendbMLF) * c0 * w,

                # Determining more constraining load case (landing vs. max aero horizontal bending)
                Vhbend >= Vhbendc + Vhbendf + Vhbendb,
                Whbend >= g * rhobend * Vhbend,

                # Vertical bending material model
                # Calculating xvbend, the location where additional bending material is required
                xvbend >= xwing, xvbend <= lfuse,
                SignomialEquality(B0v, B1v * (xtail - xvbend)), # [SP] #[SPEquality]
                #B1v definition in Aircraft()
                B0v == Ivshell/(rE*wfuse**2),
                Avbendb >= B1v * (xtail - xb) - B0v,
                Vvbendb >= 0.5*B1v * ((xtail-xb)**2 - (xtail - xvbend)**2) - B0v * (xvbend - xb),
                Vvbendc >= 0.5*Avbendb*c0*w,
                Vvbend >= Vvbendb + Vvbendc,
                Wvbend >= rhobend*g*Vvbend,

                # Wing variable substitutions
                SignomialEquality(xf,xwing + .5 * c0 * w), # [SP] [SPEquality]
                SignomialEquality(xb,xwing - .5 * c0 * w),  # [SP] [SPEquality]

                sigMh <= sigbend - rE * dPover / 2 * Rfuse / tshell,
                sigMv <= sigbend - rE * dPover / 2 * Rfuse / tshell,

                # Volume relations
                Vcyl == Askin * lshell,
                Vnose == Snose * tskin,
                Vbulk == Sbulk * tskin,
                Vdb == Adb * lshell,
                Vcabin >= Afuse * (lshell + 0.67 * lnose + 0.67 * Rfuse),

                # Weight relations
                Wapu == Wpaymax * fapu,
                Wdb == rhoskin * g * Vdb,
                Winsul >= Wppinsul * ((1.1 * pi + 2 * thetadb) * Rfuse * lshell + 0.55 * (Snose + Sbulk)),
                Wwindow >= Wpwindow * lshell,
                Wpadd == Wpaymax * fpadd,
                # Two methods for determining seat weight (must be inequalities)
                Wseat >= Wpseat * nseat,
                Wseat >= fseat * Wpaymax,

                Wskin >= rhoskin * g * (Vcyl + Vnose + Vbulk),
                Wshell >= Wskin * (1 + fstring + ffadd + fframe) + Wdb,
                Wfuse >= Cfuse*(Wshell + Wfloor + Winsul + \
                    Wapu + Wfix + Wwindow + Wpadd + Wseat + Whbend + Wvbend + Wcone),
            ])

        return constraints
Exemple #21
0
    def setup(self, Nclimb, Ncruise, Nfleet, substitutions=None, **kwargs):
        eng = 0

        #two level vectorization to make a fleet
        with Vectorize(Nfleet):
            # vectorize
            with Vectorize(Nclimb + Ncruise):
                enginestate = FlightState()

        ac = Aircraft(Nclimb, Ncruise, enginestate, eng, Nfleet)

        #two level vectorization to make a fleet
        with Vectorize(Nfleet):
            #Vectorize
            with Vectorize(Nclimb):
                climb = ClimbSegment(ac)

            with Vectorize(Ncruise):
                cruise = CruiseSegment(ac)

        statelinking = StateLinking(climb.state, cruise.state, enginestate,
                                    Nclimb, Ncruise)

        with Vectorize(Nfleet):
            #declare new variables
            W_ftotal = Variable('W_{f_{total}}', 'N', 'Total Fuel Weight')
            W_fclimb = Variable('W_{f_{climb}}', 'N',
                                'Fuel Weight Burned in Climb')
            W_fcruise = Variable('W_{f_{cruise}}', 'N',
                                 'Fuel Weight Burned in Cruise')
            W_total = Variable('W_{total}', 'N', 'Total Aircraft Weight')
            CruiseAlt = Variable('CruiseAlt', 'ft', 'Cruise Altitude [feet]')
            ReqRng = Variable('ReqRng', 'nautical_miles',
                              'Required Cruise Range')
            W_dry = Variable('W_{dry}', 'N', 'Aircraft Dry Weight')

            dhfthold = Variable('dhfthold', 'ft', 'Hold Variable')

        W_ffleet = Variable('W_{f_{fleet}}', 'N', 'Total Fleet Fuel Burn')

        h = climb['h']
        hftClimb = climb['hft']
        dhft = climb['dhft']
        hftCruise = cruise['hft']

        #make overall constraints
        constraints = []

        constraints.extend([
            #weight constraints
            TCS([
                ac['W_{e}'] + ac['W_{payload}'] +
                ac['numeng'] * ac['W_{engine}'] + ac['W_{wing}'] <= W_dry
            ]),
            TCS([W_dry + W_ftotal <= W_total]),
            climb['W_{start}'][0] == W_total,
            climb['W_{end}'][-1] == cruise['W_{start}'][0],

            # similar constraint 1
            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([W_dry <= 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:Nclimb] >= hftClimb[:Nclimb - 1] + dhft[:Nclimb - 1]
            ]),
            TCS([hftClimb[0] >= dhft[0]]),
            hftClimb[-1] <= hftCruise,

            #compute the dh
            dhfthold == hftCruise[0] / Nclimb,
            dhft == dhfthold,

            #set the range for each cruise segment, doesn't take credit for climb
            #down range disatnce covered
            cruise.cruiseP['Rng'] == ReqRng / (Ncruise),

            #compute fuel burn from TSFC
            cruise['W_{burn}'] == ac['numeng'] * ac.engine['TSFC'][Nclimb:] *
            cruise['thr'] * ac.engine['F'][Nclimb:],
            climb['W_{burn}'] == ac['numeng'] * ac.engine['TSFC'][:Nclimb] *
            climb['thr'] * ac.engine['F'][:Nclimb],
            CruiseAlt >= 30000 * units('ft'),

            #min climb rate constraint
            climb['RC'] >= 500 * units('ft/min'),
        ])

        fleetfuel = [
            #compute the fleet fuel burn
            W_ffleet >= .375 * W_ftotal[0] + .375 * W_ftotal[1] +
            .125 * W_ftotal[2] + .125 * W_ftotal[3],
        ]

        M2 = .8
        M25 = .6
        M4a = .1025
        M0 = .8

        engineclimb = [
            ac.engine.engineP['M_2'][:Nclimb] == climb['M'],
            ac.engine.engineP['M_{2.5}'][:Nclimb] == M25,
            ac.engine.engineP['hold_{2}'] == 1 + .5 * (1.398 - 1) * M2**2,
            ac.engine.engineP['hold_{2.5}'] == 1 + .5 * (1.354 - 1) * M25**2,
            ac.engine.engineP['c1'] == 1 + .5 * (.401) * M0**2,

            #constraint on drag and thrust
            ac['numeng'] * ac.engine['F_{spec}'][:Nclimb] >=
            climb['D'] + climb['W_{avg}'] * climb['\\theta'],

            #climb rate constraints
            TCS([
                climb['excessP'] + climb.state['V'] * climb['D'] <=
                climb.state['V'] * ac['numeng'] *
                ac.engine['F_{spec}'][:Nclimb]
            ]),
        ]

        M25 = .6

        enginecruise = [
            ac.engine.engineP['M_2'][Nclimb:] == cruise['M'],
            ac.engine.engineP['M_{2.5}'][Nclimb:] == M25,

            #steady level flight constraint on D
            cruise['D'] == ac['numeng'] * ac.engine['F_{spec}'][Nclimb:],

            #breguet range eqn
            TCS([
                cruise['z_{bre}'] >=
                (ac.engine['TSFC'][Nclimb:] * cruise['thr'] * cruise['D']) /
                cruise['W_{avg}']
            ]),
        ]

        ranges = [
            ReqRng[0] == 500 * units('nautical_miles'),
            ReqRng[1] == 1000 * units('nautical_miles'),
            ReqRng[2] == 1500 * units('nautical_miles'),
            ReqRng[3] == 2000 * units('nautical_miles'),
        ]

        return constraints + ac + climb + cruise + enginecruise + engineclimb + enginestate + statelinking + ranges + fleetfuel
Exemple #22
0
    def setup(self, Ncoldpipes, Nhotpipes):
        self.Ncoldpipes = Ncoldpipes
        self.Nhotpipes = Nhotpipes
        exec parse_variables(Layer.__doc__)

        self.material = self.material_model()
        with Vectorize(Nhotpipes):
            with Vectorize(Ncoldpipes):
                cells = self.cells = HXArea(n_fins, self.material)

        coldfluid = self.coldfluid_model()
        with Vectorize(Ncoldpipes):
            coldpipes = RectangularPipe(Nhotpipes,
                                        n_fins,
                                        coldfluid,
                                        increasingT=True)
        self.coldpipes = coldpipes
        hotfluid = self.hotfluid_model()
        with Vectorize(Nhotpipes):
            hotpipes = RectangularPipe(Ncoldpipes,
                                       n_fins,
                                       hotfluid,
                                       increasingT=False)
        self.hotpipes = hotpipes
        pipes = [
            coldpipes, coldpipes.T_in == T_in_cold,
            coldpipes.v_in == v_in_cold, hotpipes, hotpipes.T_in == T_in_hot,
            hotpipes.v_in == v_in_hot
        ]

        self.design_parameters = OrderedDict([
            # TODO: add T_max_hot, T_min_cold?
            ("gravity", g),
            ("x_width", x_dim),
            ("y_width", y_dim),
            ("z_width", z_dim),
            ("Hot_Channels", self.Nhotpipes),
            ("Cold_Channels", self.Ncoldpipes),
            ("Hot_Drag", D_hot),
            ("Cold_Drag", D_cold),
            ("c_metal", self.material.c),
            ("k_metal", self.material.k),
            ("rho_metal", self.material.rho),
            ("t_min_metal", self.material.t_min),
            ("c_coldfluid", coldfluid.c),
            ("k_coldfluid", coldfluid.k),
            ("rho_coldfluid", coldfluid.rho),
            ("mu_coldfluid", coldfluid.mu),
            ("Ti_coldfluid", T_in_cold),
            ("vi_coldfluid", v_in_cold),
            ("c_hotfluid", hotfluid.c),
            ("k_hotfluid", hotfluid.k),
            ("rho_hotfluid", hotfluid.rho),
            ("mu_hotfluid", hotfluid.mu),
            ("Ti_hotfluid", T_in_hot),
            ("vi_hotfluid", v_in_hot),
            ("max_solidity", max_solidity)
        ])

        geom = [
            V_tot >= hotpipes.V_seg.sum() + coldpipes.V_seg.sum() + V_mtrl,
            cells.x_cell == coldpipes.l_seg.T,
            cells.y_cell == hotpipes.l_seg,
            maxAR >= cells.y_cell / cells.x_cell,
            maxAR >= cells.x_cell / cells.y_cell,
            # Differentiating between flow width and cell width
            cells.x_cell >= n_fins * (cells.t_hot + hotpipes.w_fluid),
            cells.y_cell >= n_fins * (cells.t_cld + coldpipes.w_fluid.T),
            n_fins >= 1.,  # Making sure there is at least 1 fin
            cells.dQ == hotpipes.dQ,
            cells.dQ == coldpipes.dQ.T,
            cells.Tr_hot == hotpipes.Tr_int,
            cells.Tr_cld == coldpipes.Tr_int.T,
            cells.T_hot == hotpipes.T_avg,
            cells.T_cld == coldpipes.T_avg.T,
            cells.h_hot == hotpipes.h,
            cells.h_cld == coldpipes.h.T,
            cells.z_hot == hotpipes.h_seg,
            cells.z_cld == coldpipes.h_seg.T,
            x_dim >= hotpipes.w.sum(),
            y_dim >= coldpipes.w.sum(),
            z_dim >= cells.z_hot + cells.z_cld + cells.t_plate,
            T_max_hot >= cells.T_hot[-1, :],
            T_min_cold <= cells.T_cld[:, -1],
            T_min_cold <= T_max_hot
        ]

        for j in range(Nhotpipes):
            for i in range(Ncoldpipes):
                geom.extend([
                    cells.x_cell[i, j] == hotpipes.w[j],
                    cells.y_cell[i, j] == coldpipes.w[i],
                ])

        with SignomialsEnabled():
            SP_Qsum = Q <= cells.dQ.sum()

        return [
            SP_Qsum,
            cells,
            pipes,
            geom,
            self.material,

            # SOLIDITY
            solidity == V_mtrl / V_tot,
            solidity <= max_solidity,

            # DRAG
            D_hot >= self.hotpipes.D.sum(),
            D_cold >= self.coldpipes.D.sum(),

            # TOTAL VOLUME REQUIREMENT
            V_tot <= x_dim * y_dim * z_dim,

            # MATERIAL VOLUME
            V_mtrl >=
            ((n_fins * cells.z_hot * cells.t_hot * cells.x_cell).sum() +
             (n_fins * cells.z_cld * cells.t_cld * cells.y_cell).sum() +
             (cells.x_cell * cells.y_cell * cells.t_plate).sum()),
        ]
Exemple #23
0
"Example Vectorize usage, from gpkit/tests/t_vars.py"
from gpkit import Variable, Vectorize, VectorVariable

with Vectorize(3):
    with Vectorize(5):
        y = Variable("y")
        x = VectorVariable(2, "x")
    z = VectorVariable(7, "z")

assert (y.shape == (5, 3))
assert (x.shape == (2, 5, 3))
assert (z.shape == (7, 3))
Exemple #24
0
    def setup(self,
              aircraft,
              V_cruise=150 * ureg.mph,
              N_crew=3,
              N_passengers=1,
              reserve_type="FAA_heli",
              mission_type="piloted",
              loiter_type="level_flight",
              tailRotor_power_fraction_hover=0.0001,
              tailRotor_power_fraction_levelFlight=0.0001):

        if not (aircraft.autonomousEnabled) and (mission_type != "piloted"):
            raise ValueError("Autonomy is not enabled for Aircraft() model.")

        W = Variable("W_{mission}", "lbf",
                     "Weight of the aircraft during the mission")

        C_eff = aircraft.battery.topvar("C_{eff}")  #effective battery capacity
        E_mission = Variable("E_{mission}", "kWh",
                             "Electrical energy used during mission")

        self.W = W
        self.E_mission = E_mission
        self.mission_type = mission_type
        self.crew = Crew(mission_type=mission_type,
                         N_crew=N_crew,
                         W_oneCrew=225 * ureg.lbf)
        self.passengers = Passengers(N_passengers=N_passengers,
                                     W_onePassenger=225 * ureg.lbf)
        self.medical_equipment = MedicalEquipment()

        hoverState = FlightState(h=0 * ureg.ft)

        constraints = []

        self.fs0 = Hover(
            self,
            aircraft,
            hoverState,
            tailRotor_power_fraction=tailRotor_power_fraction_hover
        )  #takeoff from base
        self.fs1 = LevelFlight(
            self,
            aircraft,
            V=V_cruise,
            tailRotor_power_fraction=tailRotor_power_fraction_levelFlight
        )  #fly to patient location
        self.fs2 = Hover(
            self,
            aircraft,
            hoverState,
            tailRotor_power_fraction=tailRotor_power_fraction_hover
        )  #Hover/land at patient location
        self.fs3 = Hover(
            self,
            aircraft,
            hoverState,
            tailRotor_power_fraction=tailRotor_power_fraction_hover
        )  #Takeoff from patient location
        self.fs4 = LevelFlight(
            self,
            aircraft,
            V=V_cruise,
            tailRotor_power_fraction=tailRotor_power_fraction_levelFlight
        )  #Fly to hospital
        self.fs5 = Hover(
            self,
            aircraft,
            hoverState,
            tailRotor_power_fraction=tailRotor_power_fraction_hover
        )  #Hover/land at hospital
        self.fs6 = Hover(
            self,
            aircraft,
            hoverState,
            tailRotor_power_fraction=tailRotor_power_fraction_hover
        )  #Takeoff from hospital
        self.fs7 = LevelFlight(
            self,
            aircraft,
            V=V_cruise,
            tailRotor_power_fraction=tailRotor_power_fraction_levelFlight
        )  #Fly to base

        #Reserve segment
        if reserve_type == "FAA_aircraft" or reserve_type == "FAA_heli":
            V_reserve = ((1 / 3.)**(
                1 / 4.)) * V_cruise  #Approximation for max-endurance speed

            if reserve_type == "FAA_aircraft":
                #30-minute loiter time, as per VFR rules for aircraft (daytime only)
                t_loiter = Variable("t_{loiter}", 30, "minutes", "Loiter time")
            elif reserve_type == "FAA_heli":
                #20-minute loiter time, as per VFR rules for helicopters
                t_loiter = Variable("t_{loiter}", 20, "minutes", "Loiter time")

            if loiter_type == "level_flight":  #loiter segment is a level-flight segment
                self.fs8 = LevelFlight(self,
                                       aircraft,
                                       V=V_reserve,
                                       segment_type="loiter",
                                       tailRotor_power_fraction=
                                       tailRotor_power_fraction_levelFlight)
            elif loiter_type == "hover":  #loiter segment is a hover segment
                self.fs8 = Hover(
                    self,
                    aircraft,
                    hoverState,
                    tailRotor_power_fraction=tailRotor_power_fraction_hover)

            constraints += [t_loiter == self.fs8.topvar("t")]

        if reserve_type == "Uber":  #2-nautical-mile diversion distance; used by McDonald & German
            V_reserve = V_cruise
            R_divert = Variable("R_{divert}", 2, "nautical_mile",
                                "Diversion distance")
            self.fs8 = LevelFlight(
                self,
                aircraft,
                V=V_reserve,
                segment_type="cruise",
                tailRotor_power_fraction=tailRotor_power_fraction_levelFlight
            )  #reserve segment
            constraints += [R_divert == self.fs8.topvar("segment_range")]

        self.fs9 = Hover(
            self,
            aircraft,
            hoverState,
            tailRotor_power_fraction=tailRotor_power_fraction_hover
        )  #Land at base
        self.time_on_ground = TimeOnGround(self)  #Charging

        self.flight_segments = [self.fs0, self.fs1, self.fs2, self.fs3, self.fs4,\
         self.fs5, self.fs6, self.fs7, self.fs8, self.fs9]#all segments included
        self.cruise_segments = [self.fs1, self.fs4,
                                self.fs7]  #loiter not included
        self.hover_segments  = [self.fs0, self.fs2, self.fs3, self.fs5, self.fs6,\
         self.fs9]

        #Power and energy consumption by mission segment
        with Vectorize(len(self.flight_segments)):
            P_battery = Variable("P_{battery}", "kW", "Segment power draw")
            E = Variable("E", "kWh", "Segment energy use")

        #Segment range constraints
        with Vectorize(len(self.cruise_segments)):
            segment_range = Variable("segment_range", "nautical_mile",
                                     "Segment range")

        #Data from hover segments
        with Vectorize(len(self.hover_segments)):
            t_hover = Variable("t_{hover}", "s", "Segment hover time")
            CT = Variable("CT", "-", "Thrust coefficient")
            CP = Variable("CP", "-", "Power coefficient")
            Q_perRotor = Variable("Q_perRotor", "lbf*ft",
                                  "Torque per lifting rotor")
            T_perRotor = Variable("T_perRotor", "lbf",
                                  "Thrust per lifting rotor")
            P = Variable("P", "kW",
                         "Total power supplied to all lifting rotors")
            P_perRotor = Variable("P_perRotor", "kW",
                                  "Power per lifting rotor")
            VT = Variable("VT", "ft/s", "Propeller tip speed")
            omega = Variable("\omega", "rpm", "Propeller angular velocity")
            MT = Variable("MT", "-", "Propeller tip Mach number")
            FOM = Variable("FOM", "-", "Figure of merit")
            p_ratio = Variable("p_{ratio}", "-",
                               "Sound pressure ratio in hover")

        constraints += [self.flight_segments, self.time_on_ground]
        constraints += [self.crew, self.passengers]
        constraints += [W >= aircraft.topvar("W_{empty}") + self.passengers.topvar("W") \
         + self.crew.topvar("W") + self.medical_equipment.topvar("W")]
        constraints += [aircraft.topvar("MTOW") >= W]

        #Mission-segment constraints
        constraints += [
            segment_range[i] == segment.topvar("segment_range")
            for i, segment in enumerate(self.cruise_segments)
        ]
        constraints += [
            t_hover[i] == segment.topvar("t")
            for i, segment in enumerate(self.hover_segments)
        ]

        constraints += [hoverState]

        constraints += [
            E_mission >= sum(c.topvar("E") for c in self.flight_segments)
        ]
        constraints += [C_eff >= E_mission]

        constraints += [
            P_battery[i] == segment.topvar("P_{battery}")
            for i, segment in enumerate(self.flight_segments)
        ]
        constraints += [
            E[i] == segment.topvar("E")
            for i, segment in enumerate(self.flight_segments)
        ]

        constraints += [
            CT[i] == segment.rotorPerf.topvar("CT")
            for i, segment in enumerate(self.hover_segments)
        ]
        constraints += [
            CP[i] == segment.rotorPerf.topvar("CP")
            for i, segment in enumerate(self.hover_segments)
        ]
        constraints += [
            Q_perRotor[i] == segment.rotorPerf.topvar("Q_perRotor")
            for i, segment in enumerate(self.hover_segments)
        ]
        constraints += [
            T_perRotor[i] == segment.rotorPerf.topvar("T_perRotor")
            for i, segment in enumerate(self.hover_segments)
        ]
        constraints += [
            P[i] == segment.rotorPerf.topvar("P")
            for i, segment in enumerate(self.hover_segments)
        ]
        constraints += [
            P_perRotor[i] == segment.rotorPerf.topvar("P_perRotor")
            for i, segment in enumerate(self.hover_segments)
        ]
        constraints += [
            VT[i] == segment.rotorPerf.topvar("VT")
            for i, segment in enumerate(self.hover_segments)
        ]
        constraints += [
            omega[i] == segment.rotorPerf.topvar("\omega")
            for i, segment in enumerate(self.hover_segments)
        ]
        constraints += [
            MT[i] == segment.rotorPerf.topvar("MT")
            for i, segment in enumerate(self.hover_segments)
        ]
        constraints += [
            FOM[i] == segment.rotorPerf.topvar("FOM")
            for i, segment in enumerate(self.hover_segments)
        ]
        constraints += [
            p_ratio[i] == segment.rotorPerf.topvar("p_{ratio}")
            for i, segment in enumerate(self.hover_segments)
        ]

        #Mission time
        t_flight = Variable("t_{flight}", "s", "Time in flight")
        t_mission = Variable("t_{mission}", "s",
                             "Mission time (including charging)")

        constraints += [
            t_flight >= sum(c.topvar("t") for c in self.flight_segments)
        ]
        constraints += [
            t_mission >= t_flight + self.time_on_ground.topvar("t")
        ]

        return constraints
Exemple #25
0
    def setup(self, Nclimb1, Nclimb2, Ncruise, substitutions = None, **kwargs):
        eng = 0
        # vectorize
        with Vectorize(Nclimb1  +Nclimb2 + Ncruise):
            enginestate = FlightState()
            
        #build the submodel
        ac = Aircraft(Nclimb1 + Nclimb2, Ncruise, enginestate, eng)

        #Vectorize
        with Vectorize(Nclimb1):
            climb1 = ClimbSegment(ac)

        #Vectorize
        with Vectorize(Nclimb2):
            climb2 = ClimbSegment(ac)

        with Vectorize(Ncruise):
            cruise = CruiseClimbSegment(ac)

        statelinking = StateLinking(climb1.state, climb2.state, cruise.state, enginestate, Nclimb1, Nclimb2, Ncruise)

        #declare new variables
        W_ftotal = Variable('W_{f_{total}}', 'N', 'Total Fuel Weight')
        W_fclimb1 = Variable('W_{f_{climb1}}', 'N', 'Fuel Weight Burned in Climb 1')
        W_fclimb2 = Variable('W_{f_{climb2}}', 'N', 'Fuel Weight Burned in Climb 2')
        W_fcruise = Variable('W_{f_{cruise}}', 'N', 'Fuel Weight Burned in Cruise')
        W_total = Variable('W_{total}', 'N', 'Total Aircraft Weight')
        CruiseAlt = Variable('CruiseAlt', 'ft', 'Cruise Altitude [feet]')
        ReqRng = Variable('ReqRng', 'nautical_miles', 'Required Cruise Range')
        W_dry = Variable('W_{dry}', 'N', 'Aircraft Dry Weight')

        RCmin = Variable('RC_{min}', 'ft/min', 'Minimum allowed climb rate')

        dhftholdcl1 = Variable('dhftholdcl1', 'ft', 'Climb 1 Hold Variable')
        dhftholdcl2 = Variable('dhftholdcl2', 'ft', 'Climb 2 Hold Variable')
        dhftholdcr = Variable('dhftholdcr', 'ft', 'Cruise Hold Variable')

        h1 = climb1['h']
        hftClimb1 = climb1['hft']
        dhftcl1 = climb1['dhft']
        h2 = climb2['h']
        hftClimb2 = climb2['hft']
        dhftcl2 = climb2['dhft']
        dhftcr = cruise['dhft']
        hftCruise = cruise['hft']

        #make overall constraints
        constraints = []

        with SignomialsEnabled():
            constraints.extend([
                #weight constraints
                TCS([ac['W_{e}'] + ac['W_{payload}'] + ac['numeng'] * ac['W_{engine}'] + ac['W_{wing}'] <= W_dry]),
                TCS([W_dry + W_ftotal <= W_total]),

                climb1['W_{start}'][0] == W_total,
                climb1['W_{end}'][-1] == climb2['W_{start}'][0],
                climb2['W_{end}'][-1] == cruise['W_{start}'][0],

                TCS([climb1['W_{start}'] >= climb1['W_{end}'] + climb1['W_{burn}']]),
                TCS([climb2['W_{start}'] >= climb2['W_{end}'] + climb2['W_{burn}']]),
                TCS([cruise['W_{start}'] >= cruise['W_{end}'] + cruise['W_{burn}']]),

                climb1['W_{start}'][1:] == climb1['W_{end}'][:-1],
                climb2['W_{start}'][1:] == climb2['W_{end}'][:-1],
                cruise['W_{start}'][1:] == cruise['W_{end}'][:-1],

                TCS([W_dry <= cruise['W_{end}'][-1]]),

                TCS([W_ftotal >=  W_fclimb1 + W_fclimb2 + W_fcruise]),
                TCS([W_fclimb1 >= sum(climb1['W_{burn}'])]),
                TCS([W_fclimb2 >= sum(climb2['W_{burn}'])]),
                TCS([W_fcruise >= sum(cruise['W_{burn}'])]),

                #altitude constraints
                hftCruise[0] == CruiseAlt,
##                TCS([hftCruise[1:Ncruise] >= hftCruise[:Ncruise-1] + dhftcr]),
                SignomialEquality(hftCruise[1:Ncruise], hftCruise[:Ncruise-1] + dhftholdcr),
                TCS([hftClimb2[1:Nclimb2] <= hftClimb2[:Nclimb2-1] + dhftholdcl2]),
                TCS([hftClimb2[0] <= dhftholdcl2 + 10000*units('ft')]),
                hftClimb2[-1] == hftCruise,
                TCS([hftClimb1[1:Nclimb1] >= hftClimb1[:Nclimb1-1] + dhftholdcl1]),
                TCS([hftClimb1[0] == dhftcl1[0]]),
                hftClimb1[-1] == 10000*units('ft'),

                #compute the dh2
                dhftholdcl2 >= (hftCruise-10000*units('ft'))/Nclimb2,
##                SignomialEquality(dhftholdcl2, (hftCruise-10000*units('ft'))/Nclimb2,),
                dhftholdcl2 == dhftcl2,
                #compute the dh1
                dhftholdcl1 == 10000*units('ft')/Nclimb1,
                dhftholdcl1 == dhftcl1,

                dhftcr == dhftholdcr,
                
                sum(cruise['RngCruise']) + sum(climb2['RngClimb']) + sum(climb1['RngClimb']) >= ReqRng,

                #compute fuel burn from TSFC
                cruise['W_{burn}'] == ac['numeng']*ac.engine['TSFC'][Nclimb1 + Nclimb2:] * cruise['thr'] * ac.engine['F'][Nclimb1 + Nclimb2:],              
                climb1['W_{burn}'] == ac['numeng']*ac.engine['TSFC'][:Nclimb1] * climb1['thr'] * ac.engine['F'][:Nclimb1],
                climb2['W_{burn}'] == ac['numeng']*ac.engine['TSFC'][Nclimb1:Nclimb1 + Nclimb2] * climb2['thr'] * ac.engine['F'][Nclimb1:Nclimb1 + Nclimb2],

                #min climb rate constraint
##                climb1['RC'][0] >= RCmin,

                climb1['V'] <= 250*units('knots'),
                ])

        M2 = .8
        M25 = .6
        M4a = .1025
        Mexit = 1
        M0 = .8

        engineclimb1 = [
            ac.engine.engineP['M_2'][:Nclimb1] == climb1['M'],
            ac.engine.engineP['M_{2.5}'] == M25,
            ac.engine.engineP['hold_{2}'] == 1+.5*(1.398-1)*M2**2,
            ac.engine.engineP['hold_{2.5}'] == 1+.5*(1.354-1)*M25**2,
            ac.engine.engineP['c1'] == 1+.5*(.401)*M0**2,

            #constraint on drag and thrust
            ac['numeng']*ac.engine['F_{spec}'][:Nclimb1] >= climb1['D'] + climb1['W_{avg}'] * climb1['\\theta'],

            #climb rate constraints
            TCS([climb1['excessP'] + climb1.state['V'] * climb1['D'] <=  climb1.state['V'] * ac['numeng'] * ac.engine['F_{spec}'][:Nclimb1]]),
            ]

        M2 = .8
        M25 = .6
        M4a = .1025
        Mexit = 1
        M0 = .8

        engineclimb2 = [
            ac.engine.engineP['M_2'][Nclimb1:Nclimb1 + Nclimb2] == climb2['M'],

            #constraint on drag and thrust
            ac['numeng']*ac.engine['F_{spec}'][Nclimb1:Nclimb1 + Nclimb2] >= climb2['D'] + climb2['W_{avg}'] * climb2['\\theta'],

            #climb rate constraints
            TCS([climb2['excessP'] + climb2.state['V'] * climb2['D'] <=  climb2.state['V'] * ac['numeng'] * ac.engine['F_{spec}'][Nclimb1:Nclimb1 + Nclimb2]]),
            ]

        M2 = .8
        M25 = .6
        M4a = .1025
        Mexit = 1
        M0 = .8

        enginecruise = [
            ac.engine.engineP['M_2'][Nclimb1 + Nclimb2:] == cruise['M'],

##            cruise['M'] >= .7,

           #constraint on drag and thrust
            ac['numeng'] * ac.engine['F_{spec}'][Nclimb1 + Nclimb2:] >= cruise['D'] + cruise['W_{avg}'] * cruise['\\theta'],

            #climb rate constraints
            TCS([cruise['excessP'] + cruise.state['V'] * cruise['D'] <=  cruise.state['V'] * ac['numeng'] * ac.engine['F_{spec}'][Nclimb1 + Nclimb2:]]),
            ]

        return constraints + ac + climb1 + climb2 + cruise + enginecruise + engineclimb1 + engineclimb2 + enginestate + statelinking
    def setup(self, ac, substitutions=None, **kwargs):
        #define the number of each flight segment
        Nclimb = 2
        Ncruise = 2

        #Vectorize
        with Vectorize(Nclimb):
            climb = ClimbSegment(ac)

        with Vectorize(Ncruise):
            cruise = CruiseSegment(ac)

        #declare new variables
        W_ftotal = Variable('W_{f_{total}}', 'N', 'Total Fuel Weight')
        W_fclimb = Variable('W_{f_{climb}}', 'N',
                            'Fuel Weight Burned in Climb')
        W_fcruise = Variable('W_{f_{cruise}}', 'N',
                             'Fuel Weight Burned in Cruise')
        W_total = Variable('W_{total}', 'N', 'Total Aircraft Weight')
        CruiseAlt = Variable('CruiseAlt', 'ft', 'Cruise Altitude [feet]')
        ReqRng = Variable('R_{req}', 'nautical_miles', 'Required Cruise Range')

        h = climb['h']
        hftClimb = climb['hft']
        dhft = climb['dhft']
        hftCruise = cruise['hft']

        #make overall constraints
        constraints = []

        constraints.extend([
            #weight constraints
            TCS([
                ac['W_{e}'] + ac['W_{payload}'] + W_ftotal +
                ac['numeng'] * ac['W_{engine}'] + ac['W_{wing}'] <= W_total
            ]),
            climb['W_{start}'][0] == W_total,
            climb['W_{end}'][-1] == cruise['W_{start}'][0],

            # similar constraint 1
            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'),
        ])

        # Model.setup(self, W_ftotal + s*units('N'), constraints + ac + climb + cruise, subs)
        return constraints + ac + climb + cruise
Exemple #27
0
"Vectorization demonstration"
from gpkit import Model, Variable, Vectorize


class Test(Model):
    """A simple scalar model

    Upper Unbounded
    ---------------
    x
    """
    def setup(self):
        x = self.x = Variable("x")
        return [x >= 1]


print "SCALAR"
m = Test()
m.cost = m["x"]
print m.solve(verbosity=0).summary()

print "__________\n"
print "VECTORIZED"
with Vectorize(3):
    m = Test()
m.cost = m["x"].prod()
m.append(m["x"][1] >= 2)
print m.solve(verbosity=0).summary()
    def setup(self, aircraft, Nsegments):
        self.aircraft = aircraft
        W_f_m = Variable('W_{f_m}', 'N', 'total mission fuel')
        t_m = Variable('t_m', 'hr', 'total mission time')

        with Vectorize(Nsegments):
            Wavg = Variable('W_{avg}', 'N', 'segment average weight')
            Wstart = Variable('W_{start}', 'N',
                              'weight at the beginning of flight segment')
            Wend = Variable('W_{end}', 'N',
                            'weight at the end of flight segment')
            h = Variable('h', 'm', 'final segment flight altitude')
            havg = Variable('h_{avg}', 'm', 'average segment flight altitude')
            dhdt = Variable('\\frac{dh}{dt}', 'm/hr', 'climb rate')
            W_f_s = Variable('W_{f_s}', 'N', 'segment fuel burn')
            t_s = Variable('t_s', 'hr', 'time spent in flight segment')
            R_s = Variable('R_s', 'km', 'range flown in segment')
            state = Atmosphere()
            self.aircraftP = self.aircraft.dynamic(state)

        # Mission variables
        hcruise = Variable('h_{cruise_m}', 'm', 'minimum cruise altitude')
        Range = Variable("Range_m", "km", "aircraft range")
        W_p = Variable("W_{p_m}", "N", "payload weight", pr=20.)
        V_min = Variable("V_{min_m}", "m/s", "takeoff speed", pr=20.)
        TOfac = Variable('T/O factor_m', '-', 'takeoff thrust factor')
        cost_index = Variable("C_m", '1/hr', 'hourly cost index')

        constraints = []

        # Setting up the mission
        with SignomialsEnabled():
            constraints += [
                havg == state['h'],  # Linking states
                h[1:Nsegments - 1] >=
                hcruise,  # Adding minimum cruise altitude

                # Weights at beginning and end of mission
                Wstart[0] >= W_p + self.aircraft.wing['W_w'] +
                self.aircraft.engine['W_e'] + W_f_m,
                Wend[Nsegments - 1] >=
                W_p + self.aircraft.wing['W_w'] + self.aircraft.engine['W_e'],

                # Lift, and linking segment start and end weights
                Wavg <= 0.5 * state['\\rho'] * self.aircraft['S'] *
                self.aircraftP.wingP['C_L'] * self.aircraftP['V']**2,
                Wstart >= Wend + W_f_s,  # Making sure fuel gets burnt!
                Wstart[1:Nsegments] == Wend[:Nsegments - 1],
                Wavg == Wstart**0.5 * Wend**0.5,

                # Altitude changes
                h[0] == t_s[0] * dhdt[0],  # Starting altitude
                dhdt >= 1. * units('m/hr'),
                havg[0] == 0.5 * h[0],
                havg[1:Nsegments] == (h[1:Nsegments] *
                                      h[0:Nsegments - 1])**(0.5),
                SignomialEquality(
                    h[1:Nsegments],
                    h[:Nsegments - 1] + t_s[1:Nsegments] * dhdt[1:Nsegments]),

                # Thrust and fuel burn
                W_f_s >= self.aircraftP.engineP['BSFC'] *
                self.aircraftP.engineP['P_{shaft}'] * t_s,
                self.aircraftP.engineP['T'] * self.aircraftP['V'] >=
                self.aircraftP['D'] * self.aircraftP['V'] + Wavg * dhdt,

                # Max MSL thrust at least 2*climb thrust
                self.aircraft.engine['P_{shaft,max}'] >=
                TOfac * self.aircraftP.engineP['P_{shaft}'][0],
                # Flight time
                t_s == R_s / self.aircraftP['V'],

                # Aggregating segment variables
                self.aircraft['W_f'] >= W_f_m,
                R_s == Range / Nsegments,  # Dividing into equal range segments
                W_f_m >= sum(W_f_s),
                t_m >= sum(t_s)
            ]

        # Maximum takeoff weight
        constraints += [
            self.aircraft['W'] >= W_p + self.aircraft.wing['W_w'] +
            self.aircraft['W_f'] + self.aircraft.engine['W_e']
        ]

        # Stall constraint
        constraints += [
            self.aircraft['W'] <= 0.5 * state['\\rho'] * self.aircraft['S'] *
            self.aircraft['C_{L,max}'] * V_min**2
        ]

        # Wing weight model
        constraints += [
            self.aircraft.wing['W_{w_{strc}}']**2. >=
            self.aircraft.wing['W_{w_{coeff1}}']**2. /
            self.aircraft.wing['\\tau']**2. *
            (self.aircraft.wing['N_{ult}']**2. * self.aircraft.wing['A']**3. *
             ((W_p + self.aircraft.fuse['V_{f_{fuse}}'] * self.aircraft['g'] *
               self.aircraft['\\rho_f']) * self.aircraft['W'] *
              self.aircraft.wing['S']))
        ]

        # Upper bounding variables
        constraints += [
            t_m <= 100000 * units('hr'), W_f_m <= 1e10 * units('N')
        ]

        return constraints, state, self.aircraft, self.aircraftP
Exemple #29
0
    def setup(self, substitutions=None, **kwargs):
        eng = 0
        #define the number of each flight segment
        Ncruise = 2

        # vectorize
        with Vectorize(Ncruise):
            enginestate = FlightState()

        ac = Aircraft(0, Ncruise, enginestate, eng)

        #Vectorize
        with Vectorize(Ncruise):
            cruise = CruiseSegment(ac)

        statelinking = StateLinking(cruise.state, enginestate, Ncruise)

        #declare new variables
        W_ftotal = Variable('W_{f_{total}}', 'N', 'Total Fuel Weight')
        W_fcruise = Variable('W_{f_{cruise}}', 'N',
                             'Fuel Weight Burned in Cruise')
        W_total = Variable('W_{total}', 'N', 'Total Aircraft Weight')
        CruiseAlt = Variable('CruiseAlt', 'ft', 'Cruise Altitude [feet]')
        ReqRng = Variable('ReqRng', 'nautical_miles', 'Required Cruise Range')

        hftCruise = cruise['hft']

        #make overall constraints
        constraints = []

        constraints.extend([
            #weight constraints
            TCS([
                ac['W_{e}'] + ac['W_{payload}'] + W_ftotal +
                ac['numeng'] * ac['W_{engine}'] + ac['W_{wing}'] <= W_total
            ]),
            cruise['W_{start}'][0] == W_total,
            TCS([
                cruise['W_{start}'] >= cruise['W_{end}'] + cruise['W_{burn}']
            ]),
            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_fcruise]),
            TCS([W_fcruise >= sum(cruise['W_{burn}'])]),

            #altitude constraints
            hftCruise == CruiseAlt,
            CruiseAlt >= 30000 * units('ft'),

            #set the range for each cruise segment, doesn't take credit for climb
            #down range disatnce covered
            cruise.cruiseP['Rng'] == ReqRng / (Ncruise),

            #compute fuel burn from TSFC
            cruise['W_{burn}'] == ac['numeng'] * ac.engine['TSFC'] *
            cruise['thr'] * ac.engine['F'],
        ])

        M2 = .8
        M25 = .6
        M4a = .1025
        M0 = .8

        enginecruise = [
            ac.engine.engineP['M_2'][0] == cruise['M'][0],
            ac.engine.engineP['M_2'][1] == cruise['M'][1],
            ac.engine.engineP['M_{2.5}'][1] == M25,
            ac.engine.engineP['M_{2.5}'][0] == M25,
            ac.engine.engineP['hold_{2}'] == 1 + .5 * (1.398 - 1) * M2**2,
            ac.engine.engineP['hold_{2.5}'] == 1 + .5 * (1.354 - 1) * M25**2,
            ac.engine.engineP['c1'] == 1 + .5 * (.401) * M0**2,

            #steady level flight constraint on D
            cruise['D'] == ac['numeng'] * ac.engine['F'],

            #breguet range eqn
            TCS([
                cruise['z_{bre}'] >=
                (ac.engine['TSFC'] * cruise['thr'] * cruise['D']) /
                cruise['W_{avg}']
            ]),
        ]

        # Model.setup(self, W_ftotal + s*units('N'), constraints + ac + climb + cruise, subs)
        return constraints + ac + cruise + enginecruise + enginestate + statelinking
Exemple #30
0
    def setup(self, Npod=0, sp=False):
        self.Npod = Npod
        self.sp = sp

        cfrpud.substitutions.update({
            cfrpud.rho: 1.5,
            cfrpud.E: 200,
            cfrpud.tmin: 0.1,
            cfrpud.sigma: 1500
        })
        cfrpfabric.substitutions.update({
            cfrpfabric.rho: 1.3,
            cfrpfabric.E: 40,
            cfrpfabric.tmin: 0.1,
            cfrpfabric.sigma: 300,
            cfrpfabric.tau: 80
        })
        foamhd.substitutions.update({foamhd.rho: 0.03})
        materials = [cfrpud, cfrpfabric, foamhd]

        HorizontalTail.sparModel = BoxSparGP
        HorizontalTail.fillModel = None
        HorizontalTail.skinModel = WingSecondStruct
        VerticalTail.sparModel = BoxSparGP
        VerticalTail.fillModel = None
        VerticalTail.skinModel = WingSecondStruct
        TailBoom.__bases__ = (BoxSparGP, )
        TailBoom.secondaryWeight = True
        self.emp = Empennage(N=5)
        self.solarcells = SolarCells()
        self.battery = Battery()
        if sp:
            WingSP.sparModel = BoxSparSP
            WingSP.fillModel = None
            WingSP.skinModel = WingSecondStruct
            self.wing = WingSP(N=20)
        else:
            WingGP.sparModel = BoxSparGP
            WingGP.fillModel = None
            WingGP.skinModel = WingSecondStruct
            self.wing = WingGP(N=20)
        self.motor = Motor()
        Propeller.flight_model = ActuatorProp
        self.propeller = Propeller()
        self.components = [self.solarcells, self.wing, self.battery, self.emp]
        self.propulsor = [self.motor, self.propeller]

        Sw = self.Sw = self.wing.planform.S
        cmac = self.cmac = self.wing.planform.cmac
        tau = self.tau = self.wing.planform.tau
        croot = self.croot = self.wing.planform.croot
        b = self.b = self.wing.planform.b
        Vh = self.Vh = self.emp.htail.Vh
        lh = self.lh = self.emp.htail.lh
        Sh = self.Sh = self.emp.htail.planform.S
        Vv = self.Vv = self.emp.vtail.Vv
        Sv = self.Sv = self.emp.vtail.planform.S
        lv = self.lv = self.emp.vtail.lv
        d0 = self.d0 = self.emp.tailboom.d0
        Ssolar = self.Ssolar = self.solarcells.S
        mfsolar = self.mfsolar = self.solarcells.mfac
        Volbatt = self.battery.Volbatt
        vttau = self.emp.vtail.planform.tau
        httau = self.emp.htail.planform.tau

        self.emp.substitutions[Vv] = 0.02
        self.emp.substitutions[self.emp.htail.skin.rhoA] = 0.4
        self.emp.substitutions[self.emp.vtail.skin.rhoA] = 0.4
        self.emp.substitutions[self.emp.tailboom.wlim] = 1.0
        self.wing.substitutions[self.wing.mfac] = 1.0
        if not sp:
            self.emp.substitutions[Vh] = 0.45
            self.emp.substitutions[self.emp.htail.mh] = 0.1

        constraints = [
            Ssolar * mfsolar <= Sw, Vh <= Sh * lh / Sw / cmac,
            Vv <= Sv * lv / Sw / b, d0 <= tau * croot, Wland >= fland * Wtotal,
            vttau >= minvttau, httau >= minhttau, tau <= maxtau
        ]

        if self.Npod is not 0:
            with Vectorize(1):
                with Vectorize(self.Npod):
                    self.fuselage = Fuselage()

            self.k = self.fuselage.k
            Volfuse = self.Volfuse = self.fuselage.Vol[:, 0]
            Wbatt = self.battery.W
            Wfuse = sum(self.fuselage.W)
            self.fuselage.substitutions[self.fuselage.nply] = 5

            constraints.extend([
                Volbatt <= Volfuse, Wwing >= self.wing.W + self.solarcells.W,
                Wcent >= (Wpay + Wavn + self.emp.W + self.motor.W * Nprop +
                          self.fuselage.W[0] + Wbatt / self.Npod),
                Wtotal / mfac >= (Wpay + Wavn + Wland + Wfuse +
                                  sum([c.W for c in self.components]) +
                                  (Nprop) * sum([c.W for c in self.propulsor]))
            ])

            self.components.append(self.fuselage)
        else:
            constraints.extend([
                Wwing >= sum(
                    [c.W for c in [self.wing, self.battery, self.solarcells]]),
                Wcent >= Wpay + Wavn + self.emp.W + self.motor.W * Nprop,
                Volbatt <= cmac**2 * 0.5 * tau * b, Wtotal / mfac >=
                (Wpay + Wavn + Wland + sum([c.W for c in self.components]) +
                 Nprop * sum([c.W for c in self.propulsor]))
            ])

        return constraints, self.components, materials, self.propulsor