Пример #1
0
    def setup(self):
        self.HTns = HorizontalTailNoStruct()
        self.wb = WingBox(self.HTns, "horizontal_tail")

        #HT system weight variable
        Wht = Variable('W_{ht}', 'N', 'HT System Weight')
        fht = Variable('f_{ht}' ,'-', 'Rudder etc. fractional weight')

        #margin and sensitivity
        Cht = Variable('C_{ht}', 1, '-', 'HT Weight Margin and Sensitivity Factor')

        #variables only used for the TASOPT tail drag formulation
        cdfh = Variable('c_{d_{fh}}', '-', 'VT friction drag coefficient')
        cdph = Variable('c_{d_{ph}}', '-', 'VT pressure drag coefficient')
        coslamcube = Variable('\\cos(\\Lambda_{ht})^3', '-', 'Cosine of tail sweep cubed')

        constraints = []
        with SignomialsEnabled():
            constraints.append([
                self.wb['L_{ht_{rect}}'] >= self.HTns['L_{ht_{max}}']/2.*self.HTns['c_{tip_{ht}}']*self.HTns['b_{ht}']/self.HTns['S_{ht}'],
                self.wb['L_{ht_{tri}}'] >= self.HTns['L_{ht_{max}}']/4.*(1-self.wb['taper'])*self.HTns['c_{root_{ht}}']*self.HTns['b_{ht}']/self.HTns['S_{ht}'], #[SP]
                Wht >= Cht*(self.wb['W_{struct}'] + self.wb['W_{struct}']  * fht),
            ])

        return self.HTns, self.wb, constraints
Пример #2
0
    def setup(self, **kwargs):
        self.wns = WingNoStruct()
        self.wb = WingBox(self.wns, "wing")

        Wwing = Variable('W_{wing}', 'N', 'Wing System Weight')

        Cwing = Variable('C_{wing}', 1, '-', 'Wing Weight Margin and Sensitivity Factor')

        # w.r.t. the quarter chord of the root of the wing.
        dxACwing = Variable('\\Delta x_{AC_{wing}}','m','Wing Aerodynamic Center Shift')

        #wing induced drag reduction due to wing tip devices
        TipReduct = Variable('TipReduct', '-', 'Induced Drag Reduction Factor from Wing Tip Devices')

        constraints = []
        with SignomialsEnabled():
            constraints.extend([
            self.wns['\\lambda'] == self.wb['taper'],

            TCS([Wwing >= Cwing * self.wb['W_{struct}'] + self.wb['W_{struct}']*(self.wns['f_{flap}'] + \
                    self.wns['f_{slat}'] + self.wns['f_{aileron}'] + self.wns['f_{lete}'] + self.wns['f_{ribs}'] + \
                    self.wns['f_{spoiler}'] + self.wns['f_{watt}'])]),
            TCS([dxACwing <= 1./24.*(self.wns['c_{root}'] + 5.*self.wns['c_{tip}'])/self.wns['S'] \
                            *self.wns['b']**2*self.wns['\\tan(\\Lambda)']]),
            ])

        return self.wns, self.wb, constraints
Пример #3
0
    def setup(self, **kwargs):
        self.vtns = VerticalTailNoStruct()
        self.wb = WingBox(self.vtns, "vertical_tail")

        #total weight variables
        Wvt = Variable('W_{vt}', 'N', 'Total VT System Weight')
        fVT = Variable('f_{VT}', '-', 'VT Fractional Weight')

        #Margin and Sensitivity
        CVT = Variable('C_{VT}', 1, '-', 'VT Weight Margin and Sensitivity')

        #variables only used for the TASOPT tail drag formulation
        cdfv = Variable('c_{d_{fv}}', '-', 'VT friction drag coefficient')
        cdpv = Variable('c_{d_{pv}}', '-', 'VT pressure drag coefficient')
        coslamcube = Variable('\\cos(\\Lambda_{vt})^3', '-',
                              'Cosine of tail sweep cubed')

        numspar = Variable(
            'N_{spar}', '-',
            'Number of Spars in Each VT Carrying Stress in 1 in 20 Case')

        constraints = [
            self.vtns['\\lambda_{vt}'] == self.wb['taper'],
            Wvt >= numspar * CVT *
            (self.wb['W_{struct}'] + self.wb['W_{struct}'] * fVT),
        ]

        return self.vtns, self.wb, constraints
Пример #4
0
    def __init__(self, **kwargs):
        ARh     = Variable('AR_h', '-', 'Horizontal tail aspect ratio')
        ARw     = Variable('AR_w', '-', 'Wing aspect ratio')
        CD0h    = Variable('C_{D_{0_h}}', '-',
                           'Horizontal tail parasitic drag coefficient')
        CDh     = Variable('C_{D_h}', '-', 'Horizontal tail drag coefficient')
        CLah    = Variable('C_{L_{ah}}', '-', 'Lift curve slope (htail)')
        CLah0   = Variable('C_{L_{ah_0}}', '-',
                           'Isolated lift curve slope (htail)')
        CLaw    = Variable('C_{L_{aw}}', '-', 'Lift curve slope (wing)')
        CLh     = Variable('C_{L_h}', '-', 'Lift coefficient (htail)')
        CLhmax  = Variable('C_{L_{hmax}}', '-', 'Max lift coefficient')
        CLw     = Variable('C_{L_w}', '-', 'Lift coefficient (wing)')
        Cmac    = Variable('|C_{m_{ac}}|', '-', # Absolute value of CMwing
                           'Moment coefficient about aerodynamic centre (wing)')
        Cmfu    = Variable('C_{m_{fuse}}', '-', 'Moment coefficient (fuselage)')
        D       = Variable('D_{ht}', 'N', 'Horizontal tail drag')
        Kf      = Variable('K_f', '-',
                           'Empirical factor for fuselage-wing interference')
        Lh      = Variable('L_h', 'N', 'Horizontal tail downforce')
        Lmax    = Variable('L_{{max}_h}', 'N', 'Maximum load')
        M       = Variable('M', '-', 'Cruise Mach number')
        Rec     = Variable('Re_{c_h}', '-',
                           'Cruise Reynolds number (Horizontal tail)')
        SM      = Variable('S.M.', '-', 'Stability margin')
        SMmin   = Variable('S.M._{min}', '-', 'Minimum stability margin')
        Sh      = Variable('S_h', 'm^2', 'Horizontal tail area')
        Sw      = Variable('S_w', 'm^2', 'Wing area')
        Vinf    = Variable('V_{\\infty}', 'm/s', 'Freestream velocity')
        Vne     = Variable('V_{ne}', 'm/s', 'Never exceed velocity')
        W       = Variable('W_{ht}', 'N', 'Horizontal tail weight')
        a       = Variable('a', 'm/s', 'Speed of sound (35,000 ft)')
        alpha   = Variable('\\alpha', '-', 'Horizontal tail angle of attack')
        amax    = Variable('\\alpha_{max,h}', '-', 'Max angle of attack, htail')
        bht     = Variable('b_{ht}', 'm', 'Horizontal tail span')
        chma    = Variable('\\bar{c}_{ht}', 'm', 'Mean aerodynamic chord (ht)')
        croot   = Variable('c_{root_h}', 'm', 'Horizontal tail root chord')
        ctip    = Variable('c_{tip_h}', 'm', 'Horizontal tail tip chord')
        cwma    = Variable('\\bar{c}_w', 'm',
                           'Mean aerodynamic chord (wing)')
        dxlead  = Variable('\\Delta x_{{lead}_h}', 'm',
                           'Distance from CG to horizontal tail leading edge')
        dxtrail = Variable('\\Delta x_{{trail}_h}', 'm',
                           'Distance from CG to horizontal tail trailing edge')
        dxw     = Variable('\\Delta x_w', 'm',
                           'Distance from aerodynamic centre to CG')
        e       = Variable('e_h', '-', 'Oswald efficiency factor')
        eta     = Variable('\\eta_h', '-',
                           ("Lift efficiency (diff between sectional and "
                            "actual lift)"))
        etaht   = Variable('\\eta_{ht}', '-', 'Tail efficiency')
        fl      = Variable(r"f(\lambda_h)", '-',
                           'Empirical efficiency function of taper')
        lfuse   = Variable('l_{fuse}', 'm', 'Fuselage length')
        lht     = Variable('l_{ht}', 'm', 'Horizontal tail moment arm')
        mu      = Variable(r'\mu', 'N*s/m^2', 'Dynamic viscosity (35,000 ft)')
        p       = Variable('p_{ht}', '-', 'Substituted variable = 1 + 2*taper')
        q       = Variable('q_{ht}', '-', 'Substituted variable = 1 + taper')
        rho     = Variable(r'\rho', 'kg/m^3', 'Air density (cruise)')
        rho0    = Variable(r'\rho_0', 'kg/m^3', 'Air density (0 ft)')
        tanLh   = Variable(r'\tan(\Lambda_{ht})', '-',
                           'tangent of horizontal tail sweep')
        taper   = Variable(r'\lambda_h', '-', 'Horizontal tail taper ratio')
        tau     = Variable(r'\tau_h', '-',
                           'Horizontal tail thickness/chord ratio')
        wf      = Variable('w_{fuse}', 'm', 'Fuselage width')
        xcg     = Variable('x_{CG}', 'm', 'CG location')
        xcght   = Variable('x_{CG_{ht}}', 'm', 'Horizontal tail CG location')
        xw      = Variable('x_w', 'm', 'Position of wing aerodynamic center')
        ymac    = Variable('y_{\\bar{c}_{ht}}', 'm',
                           'Spanwise location of mean aerodynamic chord')

        objective = D + 0.1*W

        with SignomialsEnabled():
                           # Stability from UMich AE-481 course notes
            constraints = [TCS([SM + dxw/cwma + Kf*wf**2*lfuse/(CLaw*Sw*cwma)
                                <= CLah*Sh*lht/(CLaw*Sw*cwma)]),
                           SM >= SMmin,

                           # Trim from UMich AE-481 course notes
                           TCS([CLh*Sh*lht/(Sw*cwma) + Cmac >=
                                CLw*dxw/cwma + Cmfu], reltol=0.02),
                           Lh == 0.5*rho*Vinf**2*Sh*CLh,

                           # Moment arm and geometry -- same as for vtail
                           TCS([dxlead + croot <= dxtrail]),
                           TCS([xcg + dxtrail <= lfuse], reltol=0.002),
                           TCS([dxlead + ymac*tanLh + 0.25*chma >= lht],
                               reltol=1e-2), # [SP]
                           p >= 1 + 2*taper,
                           2*q >= 1 + p,
                           ymac == (bht/3)*q/p,
                           TCS([(2./3)*(1 + taper + taper**2)*croot/q >=
                                chma]), # [SP]
                           taper == ctip/croot,
                           TCS([Sh <= bht*(croot + ctip)/2]), # [SP]

                           # DATCOM formula (Mach number makes it SP)
                           TCS([(ARh/eta)**2*(1+tanLh**2-M**2) + 8*pi*ARh/CLah0
                                <= (2*pi*ARh/CLah0)**2]),
                           # Loss of tail effectiveness due to wing downwash
                           CLah + (2*CLaw/(pi*ARw))*etaht*CLah0 <= CLah0*etaht,
                           CLh == CLah*alpha,
                           alpha <= amax,

                           # K_f as f(wing position) -- (fitted posynomial)
                           # from from UMich AE-481 course notes Table 9.1
                           Kf >= (1.5012*(xw/lfuse)**2 +
                                  0.538*(xw/lfuse) +
                                  0.0331),
                           TCS([xw >= xcg + dxw]),

                           # Drag
                           D == 0.5*rho*Vinf**2*Sh*CDh,
                           CDh >= CD0h + CLh**2/(pi*e*ARh),
                           # same drag model as vtail
                           CD0h**0.125 >= 0.19*(tau)**0.0075 *(Rec)**0.0017
                                        + 1.83e+04*(tau)**3.54*(Rec)**-0.494
                                        + 0.118*(tau)**0.0082 *(Rec)**0.00165
                                        + 0.198*(tau)**0.00774*(Rec)**0.00168,
                           Rec == rho*Vinf*chma/mu,

                           # Oswald efficiency
                           # Nita, Scholz,
                           # "Estimating the Oswald factor from basic
                           # aircraft geometrical parameters"
                           TCS([fl >= (0.0524*taper**4 - 0.15*taper**3
                                       + 0.1659*taper**2
                                       - 0.0706*taper + 0.0119)], reltol=0.2),
                           # NOTE: slightly slack
                           TCS([e*(1 + fl*ARh) <= 1]),
                           taper >= 0.2, # TODO: make less arbitrary

                           Lmax == 0.5*rho0*Vne**2*Sh*CLhmax,
                          ]

        standalone_constraints = [M == Vinf/a,
                                 ]

        CG_constraint = [TCS([xcght >= xcg+(dxlead+dxtrail)/2]),
                         xcght <= lfuse
                        ]

        self.standalone_constraints = standalone_constraints
        self.CG_constraint = CG_constraint

        wb = WingBox()
        wb.subinplace({'A': ARh,
                       'b': bht,
                       'L_{max}': Lmax,
                       'p': p,
                       'q': q,
                       'S': Sh,
                       'taper': taper,
                       r'\tau': tau,
                       'W_{struct}': W})

        lc = LinkedConstraintSet([constraints, wb])

        CostedConstraintSet.__init__(self, objective, lc, **kwargs)
Пример #5
0
    def __init__(self, **kwargs):
        Afuel   = Variable('\\bar{A}_{fuel, max}', '-', 'Non-dim. fuel area')
        AR      = Variable('AR_w', '-', 'Wing aspect ratio')
        CDp     = Variable('C_{D_{p_w}}', '-',
                           'Wing parasitic drag coefficient')
        CDw     = Variable('C_{D_w}', '-', 'Drag coefficient, wing')
        CLaw    = Variable('C_{L_{aw}}', '-', 'Lift curve slope, wing')
        CLw     = Variable('C_{L_w}', '-', 'Lift coefficient, wing')
        CLwmax  = Variable('C_{L_{wmax}}', '-', 'Max lift coefficient, wing')
        D       = Variable('D_{wing}', 'N', 'Wing drag')
        Lmax    = Variable('L_{max_{w}}', 'N', 'Maximum load')
        Lw      = Variable('L_w', 'N', 'Wing lift')
        M       = Variable('M', '-', 'Cruise Mach number')
        Re      = Variable('Re_w', '-', 'Cruise Reynolds number (wing)')
        Sw      = Variable('S_w', 'm^2', 'Wing area')
        Vinf    = Variable('V_{\\infty}', 'm/s', 'Freestream velocity')
        Vfuel   = Variable('V_{fuel, max}', 'm^3', 'Available fuel volume')
        Vne     = Variable('V_{ne}', 'm/s', 'Never exceed velocity')
        W       = Variable('W', 'N', 'Aircraft weight')
        W0      = Variable('W_0', 'N', 'Weight excluding wing')
        Wfuel   = Variable('W_{fuel}', 'N', 'Fuel weight')
        Wfuelmax= Variable('W_{fuel,max}', 'N', 'Max fuel weight')
        Ww      = Variable('W_{wing}', 'N', 'Wing weight')
        a       = Variable('a', 'm/s', 'Speed of sound (35,000 ft)')
        alpha   = Variable('\\alpha_w', '-', 'Wing angle of attack')
        amax    = Variable('\\alpha_{max,w}', '-', 'Max angle of attack')
        b       = Variable('b_w', 'm', 'Wing span')
        cosL    = Variable('\\cos(\\Lambda)', '-',
                           'Cosine of quarter-chord sweep angle')
        croot   = Variable('c_{root}', 'm', 'Wing root chord')
        ctip    = Variable('c_{tip}', 'm', 'Wing tip chord')
        cwma    = Variable('\\bar{c}_w', 'm',
                           'Mean aerodynamic chord (wing)')
        e       = Variable('e', '-', 'Oswald efficiency factor')
        eta     = Variable('\\eta_w', '-',
                           'Lift efficiency (diff b/w sectional, actual lift)')
        fl      = Variable('f(\\lambda_w)', '-',
                           'Empirical efficiency function of taper')
        g       = Variable('g', 'm/s^2', 'Gravitational acceleration')
        mu      = Variable('\\mu', 'N*s/m^2', 'Dynamic viscosity (35,000 ft)')
        p       = Variable('p_w', '-', 'Substituted variable = 1 + 2*taper')
        q       = Variable('q_w', '-', 'Substituted variable = 1 + taper')
        rho     = Variable('\\rho', 'kg/m^3', 'Air density (cruise)')
        rho0    = Variable('\\rho_0', 'kg/m^3', 'Air density (0 ft)')
        rhofuel = Variable('\\rho_{fuel}', 'kg/m^3', 'Density of fuel')
        tanL    = Variable('\\tan(\\Lambda)', '-',
                           'Tangent of quarter-chord sweep angle')
        taper   = Variable('\\lambda', '-', 'Wing taper ratio')
        tau     = Variable('\\tau_w', '-', 'Wing thickness/chord ratio')
        tcap    = Variable('t_{cap}' ,'-', 'Non-dim. spar cap thickness')
        tweb    = Variable('t_{web}', '-', 'Non-dim. shear web thickness')
        w       = Variable('w', 0.5, '-', 'Wingbox-width-to-chord ratio')
        #xw     = Variable('x_w', 'm', 'Position of wing aerodynamic center')
        ymac    = Variable('y_{\\bar{c}_w}', 'm',
                           'Spanwise location of mean aerodynamic chord')


        objective = D

        with SignomialsEnabled():
            constraints = [
                           Lw == 0.5*rho*Vinf**2*Sw*CLw,

                           p >= 1 + 2*taper,
                           2*q >= 1 + p,
                           ymac == (b/3)*q/p,
                           TCS([(2./3)*(1+taper+taper**2)*croot/q <= cwma],
                               reltol=1E-2),
                           taper == ctip/croot,
                           TCS([Sw <= b*(croot + ctip)/2], reltol=1E-2), # [SP]

                           # DATCOM formula (Mach number makes it SP)
                           TCS([(AR/eta)**2*(1 + tanL**2 - M**2) + 8*pi*AR/CLaw
                                <= (2*pi*AR/CLaw)**2]),
                           CLw == CLaw*alpha,
                           alpha <= amax,

                           # Drag
                           D == 0.5*rho*Vinf**2*Sw*CDw,
                           CDw >= CDp + CLw**2/(pi*e*AR),
                           Re == rho*Vinf*cwma/mu,
                           1 >= (2.56*CLw**5.88/(Re**1.54*tau**3.32*CDp**2.62)
                              + 3.8e-9*tau**6.23/(CLw**0.92*Re**1.38*CDp**9.57)
                              + 2.2e-3*Re**0.14*tau**0.033/(CLw**0.01*CDp**0.73)
                              + 6.14e-6*CLw**6.53/(Re**0.99*tau**0.52*CDp**5.19)
                              + 1.19e4*CLw**9.78*tau**1.76/(Re*CDp**0.91)),

                           # Oswald efficiency
                           # Nita, Scholz, "Estimating the Oswald factor from
                           # basic aircraft geometrical parameters"
                           TCS([fl >= 0.0524*taper**4 - 0.15*taper**3
                                    + 0.1659*taper**2 - 0.0706*taper + 0.0119],
                               reltol=1E-2),
                           TCS([e*(1 + fl*AR) <= 1]),
                           taper >= 0.2, # TODO

                           Lmax == 0.5*rho0*Vne**2*Sw*CLwmax,

                           # Fuel volume [TASOPT doc]
                           Afuel <= w*0.92*tau,
                           # GP approx of the signomial constraint:
                           # Afuel <= (w - 2*tweb)*(0.92*tau - 2*tcap),
                           Vfuel <= croot**2 * (b/6) * (1+taper+taper**2)*cosL,
                           Wfuel <= rhofuel*Afuel*Vfuel*g,
                          ]

            standalone_constraints = [W >= W0 + Ww + Wfuel,
                                      Lw == W,
                                      M == Vinf/a,
                                      ]

            self.standalone_constraints = standalone_constraints

        wb = WingBox()
        wb.subinplace({'A': AR,
                       'b': b,
                       'L_{max}': Lmax,
                       'p': p,
                       'q': q,
                       'S': Sw,
                       'taper': taper,
                       '\\tau': tau,
                       'W_{struct}': Ww})

        lc = LinkedConstraintSet([constraints, wb])

        CostedConstraintSet.__init__(self, objective, lc, **kwargs)
Пример #6
0
    def __init__(self, **kwargs):

        Afan   = Variable('A_{fan}', 'm^2', 'Engine reference area')
        Avt    = Variable('A_{vt}', '-', 'Vertical tail aspect ratio')
        CDvis  = Variable('C_{D_{vis}}', '-', 'Viscous drag coefficient')
        CDwm   = Variable('C_{D_{wm}}', '-', 'Windmill drag coefficient')
        CLvmax = Variable('C_{L_{vmax}}', '-', 'Max lift coefficient')
        CLvt   = Variable('C_{L_{vt}}', '-', 'Vertical tail lift coefficient')
        Dvt    = Variable('D_{vt}', 'N', 'Vertical tail viscous drag, cruise')
        Dwm    = Variable('D_{wm}', 'N', 'Engine out windmill drag')
        Lmax   = Variable('L_{max_{vt}}', 'N',
                          'Maximum load for structural sizing') # fuselage
        Lvmax  = Variable('L_{v_{max}}', 'N',
                          'Maximum load for structural sizing')
        Lvt    = Variable('L_{vt}', 'N', 'Vertical tail lift in engine out')
        Rec    = Variable('Re_{vt}', '-', 'Vertical tail reynolds number, cruise')
        S      = Variable('S', 'm^2', 'Vertical tail reference area (full)')
        Svt    = Variable('S_{vt}', 'm^2', 'Vertical tail reference area (half)')
        Te     = Variable('T_e', 'N', 'Thrust per engine at takeoff')
        V1     = Variable('V_1', 'm/s', 'Minimum takeoff velocity')
        Vinf   = Variable('V_{\\infty}', 'm/s', 'Cruise velocity')
        Vne    = Variable('V_{ne}', 'm/s', 'Never exceed velocity')
        Wstruct= Variable('W_{struct}', 'N', 'Full span weight')
        Wvt    = Variable('W_{vt}', 'N', 'Vertical tail weight')
        b      = Variable('b', 'm', 'Vertical tail full span')
        bvt    = Variable('b_{vt}', 'm', 'Vertical tail half span')
        clvt   = Variable('c_{l_{vt}}', '-',
                          'Sectional lift force coefficient (engine out)')
        cma    = Variable('\\bar{c}_{vt}', 'm', 'Vertical tail mean aero chord')
        croot  = Variable('c_{root_{vt}}', 'm', 'Vertical tail root chord')
        ctip   = Variable('c_{tip_{vt}}', 'm', 'Vertical tail tip chord')
        cvt    = Variable('c_{vt}', 'm', 'Vertical tail root chord') # fuselage
        dfan   = Variable('d_{fan}', 'm', 'Fan diameter')
        dxlead = Variable('\\Delta x_{lead_v}', 'm',
                          'Distance from CG to vertical tail leading edge')
        dxtrail= Variable('\\Delta x_{trail_v}', 'm',
                          'Distance from CG to vertical tail trailing edge')
        e      = Variable('e_v', '-', 'Span efficiency of vertical tail')
        lfuse  = Variable('l_{fuse}', 'm', 'Length of fuselage')
        lvt    = Variable('l_{vt}', 'm', 'Vertical tail moment arm')
        mu     = Variable('\\mu', 'N*s/m^2', 'Dynamic viscosity (35,000 ft)')
        mu0    = Variable('\\mu_0', 1.8E-5, 'N*s/m^2', 'Dynamic viscosity (SL)')
        p      = Variable('p_{vt}', '-', 'Substituted variable = 1 + 2*taper')
        plamv  = Variable('p_{\\lambda_v}', '-',
                          'Dummy variable = 1 + 2\\lambda') # fuselage
        q      = Variable('q_{vt}', '-', 'Substituted variable = 1 + taper')
        rho0   = Variable('\\rho_{TO}', 'kg/m^3', 'Air density (SL))')
        rho    = Variable('\\rho', 'kg/m^3', 'Air density (cruise)')
        tanL   = Variable('\\tan(\\Lambda_{vt})', '-',
                          'Tangent of leading edge sweep (40 deg)')
        taper  = Variable('\\lambda_{vt}', '-', 'Vertical tail taper ratio')
        tau    = Variable('\\tau_{vt}', '-', 'Vertical tail thickness/chord ratio')
        xCG    = Variable('x_{CG}', 'm', 'x-location of CG')
        xCGvt  = Variable('x_{CG_{vt}}', 'm', 'x-location of tail CG')
        y_eng  = Variable('y_{eng}', 'm', 'Engine moment arm')
        zmac   = Variable('z_{\\bar{c}_{vt}}', 'm',
                          'Vertical location of mean aerodynamic chord')


        with SignomialsEnabled():
            objective = Dvt + 0.05*Wvt
            constraints = [
                           Lvt*lvt >= Te*y_eng + Dwm*y_eng,
                           # Force moment balance for one engine out condition
                           # TASOPT 2.0 p45

                           TCS([dxlead + zmac*tanL + 0.25*cma >= lvt]), # [SP]
                           # Tail moment arm

                           Lvt == 0.5*rho0*V1**2*Svt*CLvt,
                           # Vertical tail force (y-direction) for engine out 

                           Avt == bvt**2/Svt,
                           TCS([CLvt*(1 + clvt/(np.pi*e*Avt)) <= clvt]),
                           # Finite wing theory
                           # people.clarkson.edu/~pmarzocc/AE429/AE-429-4.pdf
                           # Valid because tail is untwisted and uncambered
                           # (lift curve slope passes through origin)

                           Dwm >= 0.5*rho0*V1**2*Afan*CDwm,
                           Afan >= np.pi*(dfan/2)**2,
                           # Drag of a windmilling engine

                           Svt <= bvt*(croot + ctip)/2, # [SP]
                           # Tail geometry relationship

                           TCS([dxtrail >= croot + dxlead]),
                           # Tail geometry constraint

                           lfuse >= dxtrail + xCG,
                           # Fuselage length constrains the tail trailing edge

                           p >= 1 + 2*taper,
                           2*q >= 1 + p,
                           zmac == (bvt/3)*q/p,
                           TCS([(2./3)*(1 + taper + taper**2)*croot/q >= cma]), # [SP]
                           taper == ctip/croot,
                           # Define vertical tail geometry

                           taper >= 0.27,
                           # TODO: Constrain taper by tip Reynolds number
                           # source: b737.org.uk

                           Dvt >= 0.5*rho*Vinf**2*Svt*CDvis,
                           CDvis**0.125 >= 0.19*(tau)**0.0075 *(Rec)**0.0017
                                        + 1.83e+04*(tau)**3.54*(Rec)**-0.494
                                        + 0.118*(tau)**0.0082 *(Rec)**0.00165
                                        + 0.198*(tau)**0.00774*(Rec)**0.00168,
                           # Vertical tail viscous drag in cruise
                           # Data fit from Xfoil

                           Rec == rho*Vinf*cma/mu,
                           # Cruise Reynolds number

                           S == Svt*2,
                           b == bvt*2,
                           Wvt == Wstruct/2,
                           Lmax == 2*Lvmax,
                           # Relate vertical tail geometry/weight to generic
                           # wing used in structural model

                           Lvmax == 0.5*rho0*Vne**2*Svt*CLvmax,
                           # Max load for structural sizing
                          ]

            # For linking to other models
            linking_constraints = [plamv == p,
                                   cvt == croot]

            CG_constraint = [TCS([xCGvt >= xCG+(dxlead+dxtrail)/2],
                                 raiseerror=False),
                             xCGvt <= lfuse]

            self.linking_constraints = linking_constraints
            self.CG_constraint = CG_constraint


        # Incorporate the structural model
        wb = WingBox()
        wb.subinplace({'b': b,
                       'L_{max}': Lmax,
                       'p': p,
                       'q': q,
                       'S': S,
                       'taper': taper,
                       '\\tau': tau})
        lc = LinkedConstraintSet([constraints, wb])

        CostedConstraintSet.__init__(self, objective, lc)