Mission analysis

Mission analysis#

Once more details are available for the airplane, it is important to perform a refined mission analysis to access whether the airplane can still complete the design mission. Accordingly, this section performs mission analysis for the example airplane. Similar to initial sizing, the mission profile is divided into various segments and the weight fraction (or fuel weight) is estimated for each segment. However, the methods used in this section are more refined as compared to the methods used in intial sizing. The additional information about the airplane is incorporated which is computed in various preceding sections.

For this demonstration, only the cruise and loiter estimation is refined. Other segments of the mission are assumed to be same as initial sizing. However, if refined models are available for other segments, then those should be used for computing fuel and weight fraction. As described in initial sizing, following table summarizes the weight fraction for each segment, except for cruise and loiter.

Mission segment

Weight fraction

Value

Warmup, taxi, takeoff

\(W_1/W_0\)

0.984

Climb

\(W_2/W_1\)

0.990

Descent

\(W_4/W_3\)

0.992

Climb

\(W_5/W_4\)

0.990

Descent

\(W_7/W_6\)

0.992

Land, taxi, shutdown

\(W_8/W_7\)

0.992

Note that above table does not specify a value for \(W_3/W_2\) and \(W_6/W_5\). Following table summarizes various fixed values used in this analysis.

Parameter

Value

Source

Aspect ratio, \(A\)

8

Assumed

Zero-lift drag coeff, \(C_{D_0}\)

0.033

Calculated

Cruise propeller efficiency, \(\eta_{p_{cr}}\)

0.82

Roskam Part 1, Table 2.2

Cruise brake specific fuel consumption, \(C_{{bhp}_{cr}}\)

0.4 lb/hr/bhp

Raymer, Table 3.4

Loiter propeller efficiency, \(\eta_{p_{lo}}\)

0.72

Roskam Part 1, Table 2.2

Loiter brake specific fuel consumption, \(C_{{bhp}_{lo}}\)

0.4 lb/hr/bhp

Raymer, Table 3.4

Below code block imports requried packages and defines some variables:

import numpy as np

A = 8
e = 0.81
K = 1/np.pi/A/e
S = 134 # sq ft
CD0 = 0.03363 # clean configuration
prop_eff_cruise = 0.82
prop_eff_loiter = 0.72
Cbhp = 0.4 # lbs/hp-hr
rho_sea_level = 0.0023769 # slugs/ft^3
rho_4000 = 0.00211114 # slugs/ft^3
rho_8000 = 0.00186850 # slugs/ft^3
MTOW = 5374 # lbs

# Weight fractions
W1_W0 = 0.985
W2_W1 = 0.99
W4_W3 = 0.992
W5_W4 = 0.99
W7_W6 = 0.992
W8_W7 = 0.992

Below sub-sections describe cruise and loiter analysis, and computes corresponding weight fractions.

Cruise#

Similar to the initial sizing analysis, the cruise performance is evaluated using the Breguet range equation, but with a few key differences. In the initial sizing phase, the lift coefficient, \(C_L\), was chosen to maximize the lift-to-drag ratio (L/D), thereby maximizing range. However, that approach does not account for the specified cruise speed requirement of 200 knots.

In this cruise analysis, \(C_L\) is instead determined from the aircraft’s weight and the required cruise speed. Once \(C_L\) is known, the corresponding \(L/D\) ratio is computed using the simplified drag model described in the aerodynamics section.

Because the aircraft’s weight decreases during cruise due to fuel burn, \(C_L\) must be updated continuously to maintain a constant cruise speed. To capture this effect, the cruise segment is divided into smaller subsegments, with the weight assumed constant within each subsegment. The overall cruise weight fraction is simply the weight fraction across all subsegments multiplied together and is written as

\[ \frac{W_3}{W_2} = \prod_{j=1}^{k} \frac{w_{j}}{w_{j-1}}, \]

where \(w_j/w_{j-1}\) is the weight fraction for subsegment \(j\), \(k\) is the total number of subsegments, and \(w_0 = W_2\). The weight fraction for each subsegment is computed using the Breguet range equation as

\[ \frac{w_{j}}{w_{j-1}} = \exp \Bigg[ - \frac{ RC_{{bhp}_{cr}} }{ 375\eta_{p_{cr}} (L/D)_j } \Bigg], \]

where lift to drag ratio for subsegment \(j\) is given by

\[ (L/D)_j = \frac{C_{L_j}}{C_{D_0} + KC_{L_j}^2}. \]

Note that the range should be in miles in the above weight fraction equation. The lift coefficient for subsegment \(j\) is computed as

\[ C_{L_j} = \frac{w_{j-1}}{0.5\rho V^2S} \]

For this analysis, MTOW is set to 5374 lbs (value found from initial sizing and refined empty weight estimation). Below code block defines function to compute cruise weight fraction. Note that it also computes the average power requried for cruise. This is used for verifying whether the engine can provide sufficient power for cruise.

def compute_cruise_weight_fraction(weight, R=1200, V=200, num_segements=10):
    """
        Compute the weight fraction for cruise segment.

        Parameters
        ----------
        weight : float
            Initial weight at the beginning of cruise (lbs)
        R : float
            Range of cruise (nm)
        V : float
            Velocity during cruise (knots)
        num_segements : int
            Number of segments to divide the cruise into
        
        Returns
        -------
        weight_fraction: float
            Total weight fraction for the cruise segment
        avg_power_req: float
            Average power required during cruise (hp)
        avg_CL_cruise: float
            Average lift coefficient during cruise
    """

    segment_range = R / num_segements * 1.15077945 # miles
    V = V * 1.68781  # Convert to ft/s
    q = 0.5 * rho_8000 * V**2 # lbs/sq ft

    # initialize empty lists
    weight_fractions = []
    power_req = []
    CL_req = []

    for i in range(num_segements):

        CL = weight / q / S
        CL_req.append(CL)
        CD = CD0 + K * CL**2
        LbyD = CL/CD

        weight_fraction = np.exp( - segment_range * Cbhp / 375 / prop_eff_cruise / LbyD ) # weight fraction per segment
        weight_fractions.append(weight_fraction)
        weight = weight * weight_fraction

        # Power required for the segment
        T = CD * q * S / 0.92 # lbs, 0.92 for installation losses
        P_req = T * V / prop_eff_cruise / 550 # hp

        power_req.append(P_req)

    total_weight_fraction = np.prod(weight_fractions)
    avg_power_req = np.mean(power_req)
    avg_CL_cruise = np.mean(CL_req)

    return total_weight_fraction, avg_power_req, avg_CL_cruise

Below code block computes the cruise weight fraction and average power required for cruise. Note that the value of power required is at cruising altitude of 8000 ft.

W2 = W2_W1 * W1_W0 * MTOW

W3_W2, avg_power_cruise, avg_CL_cruise = compute_cruise_weight_fraction(W2, R=1200, V=200, num_segements=10)

print(f"Cruise weight fraction: {W3_W2:.3f}")
print(f"Average power required during cruise (hp): {avg_power_cruise:.0f}")
print(f"Average CL during cruise: {avg_CL_cruise:.3f}")
Cruise weight fraction: 0.810
Average power required during cruise (hp): 455
Average CL during cruise: 0.336

Based on the above values, the cruise weight fraction is lower than initial sizing estimate of 0.88. This can be attributed to the fact that airplane is not flying at maximum L/D during cruise, but rather at a lift coefficient required to maintain 200 knots. Also, note the value of average \(C_L\) during cruise. This value can be easily achieved at low angle of attack based on the lift curve in clean onfiguration.

Below code block computes maximum available power from engine at cruising altitude:

Pmax_sea_level = 2*298 # hp
sigma = rho_8000 / rho_sea_level
Pmax_8000 = Pmax_sea_level * (sigma - (1-sigma)/7.75)

print(f"Maximum available power at 8000 ft (hp): {Pmax_8000:.0f}")
Maximum available power at 8000 ft (hp): 452

Based on the maximum available power, this propulsion system cannot achieve the cruise speed of 200 knots. This implies that the design needs to be refined to ensure that enough power available. Note that the maximum poqer available at cruising altitude should be much higher than the required power since engine will not be operating at max power during cruise.

Loiter#

A similar process is followed for loiter analysis with some differences. Since there is no speed requirement for loiter, \(C_L\) computed such that the endurance is maximized. Because the aircraft’s weight decreases during loiter due to fuel burn, the airplane speed must be updated continuously to maintain the \(C_L\). To capture this effect, the loiter segment is divided into smaller subsegments, with the weight assumed constant within each subsegment. The overall loiter weight fraction is simply the weight fraction across all subsegments multiplied together (similar to cruise section).

Below code block defines function to compute loiter weight fraction. Note that it also computes the average power requried for loiter. This is used for verifying whether the engine can provide sufficient power for loiter.

def compute_loiter_weight_fraction(weight, E=45, num_segements=10):
    """
        Compute the weight fraction for loiter segment.

        Parameters
        ----------
        weight : float
            Initial weight at the beginning of loiter (lbs)
        E : float
            loiter time (min)
        num_segements : int
            Number of segments to divide the loiter into

        Returns
        -------
        weight_fraction: float
            Total weight fraction for the loiter segment
        avg_power_req: float
            Average power required during loiter (hp)
        avg_speed_loiter: float
            Average speed during loiter
    """

    segment_E = E / num_segements / 60 # hr

    # initialize empty lists
    weight_fractions = []
    power_req = []
    avg_V = []

    CL = (3*CD0/K)**0.5 # for max endurance for prop airplane
    CD = CD0 + K * CL**2
    LbyD = CL/CD

    for i in range(num_segements):

        V = ( weight/S * 2/rho_4000 * 1/CL )**0.5 # ft/s
        avg_V.append(V)
        q = 0.5 * rho_4000 * V**2 # lbs/sq ft

        # weight fraction per segment
        weight_fraction = np.exp( - segment_E * V * Cbhp / 375 / prop_eff_loiter / LbyD )
        weight_fractions.append(weight_fraction)
        weight = weight * weight_fraction

        # Power required for the segment
        T = CD * q * S / 0.92 # lbs, 0.92 for installation losses
        P_req = T * V / prop_eff_cruise / 550 # hp
        power_req.append(P_req)

    total_weight_fraction = np.prod(weight_fractions)
    avg_power_req = np.mean(power_req)
    avg_V = np.mean(avg_V)

    return total_weight_fraction, avg_power_req, avg_V

Below code block computes the loiter weight fraction and average power required for loiter. Note that the value of power required is at loiter altitude of 4000 ft.

W5 = W5_W4 * W4_W3 * W3_W2 * W2_W1 * W1_W0 * MTOW

W6_W5, avg_power_loiter, avg_V_loiter = compute_loiter_weight_fraction(W5, E=45, num_segements=10)

print(f"Loiter weight fraction: {W6_W5:.3f}")
print(f"Average power required during loiter (hp): {avg_power_loiter:.0f}")
print(f"Average speed during loiter: {avg_V_loiter:.0f} ft/s")
Loiter weight fraction: 0.985
Average power required during loiter (hp): 134
Average speed during loiter: 143 ft/s

Below code block computes maximum available power from engine at loiter altitude:

sigma = rho_4000 / rho_sea_level
Pmax_4000 = Pmax_sea_level * (sigma - (1-sigma)/7.75)

print(f"Maximum available power at 4000 ft (hp): {Pmax_4000:.0f}")
Maximum available power at 4000 ft (hp): 521

Based on the above calculation, there is sufficient power available for loiter segment.

Fuel fraction#

Once cruise and loiter weight fractions are computed, final weight fraction and fuel fraction can be computed. Below code block computes the final fuel fraction for the example airplane. Note that 6% extra fuel is assumed to be trapped, not usable fuel.

W8_W0 = W8_W7 * W7_W6 * W6_W5 * W5_W4 * W4_W3 * W3_W2 * W2_W1 * W1_W0 # weight fraction

Wf_W0 = 1.06 * (1 - W8_W0) # 6% is for trapped unusable fuel

print(f"Fuel fraction: {Wf_W0:.3f}")
Fuel fraction: 0.262

The computed fraction is higher than the fuel fraction of 0.198, computed in initial sizing. This implies that the maximum takeoff weight needs to be comptued again using the iterative process described in initial weight estimation, but with refined methods. This concludes the mission analysis.