Ejemplo n.º 1
0
def test_EngineSet():
    """Tests behaviour of FuelEngineSet"""
    engine = DummyEngine(1.2e5, 1.0e-5)

    # input = thrust rate
    thrust_rate = np.linspace(0.0, 1.0, 20)
    for engine_count in [1, 2, 3, 4]:
        engine_set = FuelEngineSet(engine, engine_count)
        flight_point = FlightPoint(mach=0.0,
                                   altitude=0.0,
                                   engine_setting=1,
                                   thrust_rate=thrust_rate)
        engine_set.compute_flight_points(flight_point)
        assert_allclose(flight_point.sfc, engine.max_sfc * thrust_rate)
        assert_allclose(flight_point.thrust,
                        engine.max_thrust * engine_count * thrust_rate)

    # input = thrust
    thrust = np.linspace(0.0, engine.max_thrust, 30)
    for engine_count in [1, 2, 3, 4]:
        engine_set = FuelEngineSet(engine, engine_count)
        flight_point = FlightPoint(mach=0.0,
                                   altitude=0.0,
                                   engine_setting=1,
                                   thrust=thrust)
        engine_set.compute_flight_points(flight_point)
        assert_allclose(flight_point.thrust_rate,
                        thrust / engine_count / engine.max_thrust)
        assert_allclose(flight_point.sfc,
                        engine.max_sfc * flight_point.thrust_rate)
Ejemplo n.º 2
0
def test_breguet_cruise(polar):
    propulsion = FuelEngineSet(DummyEngine(0.5e5, 1.0e-5), 2)

    segment = BreguetCruiseSegment(
        target=FlightPoint(ground_distance=5.0e5),
        propulsion=propulsion,
        reference_area=120.0,
        polar=polar,
        engine_setting=EngineSetting.
        CRUISE,  # The engine model does not use this setting
    )
    flight_points = segment.compute_from(
        FlightPoint(time=10000.0, mass=70000.0, altitude=10000.0, mach=0.78))

    print_dataframe(flight_points)

    first_point = flight_points.iloc[0]
    last_point = flight_points.iloc[-1]
    # Note: reference values are obtained by running the process with CruiseSegment and 0.05s as
    # time step
    assert_allclose(first_point.altitude, 10000.0)
    assert_allclose(first_point.true_airspeed, 233.6, atol=0.1)
    assert first_point.engine_setting == EngineSetting.CRUISE

    assert_allclose(last_point.ground_distance, 500000.0)
    assert_allclose(last_point.altitude, 10000.0)
    assert_allclose(last_point.time, 12141.0, rtol=1e-2)
    assert_allclose(last_point.true_airspeed, 233.6, atol=0.1)
    assert_allclose(last_point.mass, 69568.0, rtol=1e-4)
    assert last_point.engine_setting == EngineSetting.CRUISE
Ejemplo n.º 3
0
def test_optimal_cruise(polar):
    propulsion = FuelEngineSet(DummyEngine(0.5e5, 1.0e-5), 2)

    segment = OptimalCruiseSegment(
        target=FlightPoint(ground_distance=5.0e5),
        propulsion=propulsion,
        reference_area=120.0,
        polar=polar,
        engine_setting=EngineSetting.CRUISE,
    )
    flight_points = segment.compute_from(
        FlightPoint(mass=70000.0, time=1000.0, ground_distance=1e5, mach=0.78))
    print_dataframe(flight_points)

    first_point = flight_points.iloc[0]
    last_point = flight_points.iloc[-1]
    # Note: reference values are obtained by running the process with 0.05s as time step
    assert_allclose(first_point.altitude, 9156.0, atol=1.0)
    assert_allclose(first_point.true_airspeed, 236.4, atol=0.1)
    assert_allclose(first_point.CL, polar.optimal_cl)
    assert_allclose(first_point.CL, polar.optimal_cl)
    assert first_point.engine_setting == EngineSetting.CRUISE

    assert_allclose(last_point.ground_distance, 600000.0)
    assert_allclose(last_point.CL, polar.optimal_cl)
    assert_allclose(last_point.altitude, 9196.0, atol=1.0)
    assert_allclose(last_point.time, 3115.0, rtol=1e-2)
    assert_allclose(last_point.true_airspeed, 236.3, atol=0.1)
    assert_allclose(last_point.mass, 69577.0, rtol=1e-4)
    assert last_point.engine_setting == EngineSetting.CRUISE
Ejemplo n.º 4
0
    def _compute_breguet(self, inputs, outputs):
        """
        Computes mission using simple Breguet formula at altitude==100m and Mach 0.1
        (but max L/D ratio is assumed anyway)

        Useful only for initiating the computation.

        :param inputs: OpenMDAO input vector
        :param outputs: OpenMDAO output vector
        """
        propulsion_model = FuelEngineSet(
            self._engine_wrapper.get_model(inputs), inputs["data:geometry:propulsion:engine:count"]
        )

        high_speed_polar = self._get_initial_polar(inputs)
        distance = np.asscalar(
            np.sum(self._mission_wrapper.get_route_ranges(inputs, self.options["mission_name"]))
        )

        altitude = 100.0
        cruise_mach = 0.1

        breguet = BreguetCruiseSegment(
            FlightPoint(ground_distance=distance),
            propulsion=propulsion_model,
            polar=high_speed_polar,
            use_max_lift_drag_ratio=True,
        )
        start_point = FlightPoint(
            mass=inputs[self._mission_vars.TOW.value], altitude=altitude, mach=cruise_mach
        )
        flight_points = breguet.compute_from(start_point)
        end_point = FlightPoint.create(flight_points.iloc[-1])
        outputs[self._mission_vars.NEEDED_BLOCK_FUEL.value] = start_point.mass - end_point.mass
Ejemplo n.º 5
0
def test_climb_fixed_altitude_at_constant_TAS(polar):
    propulsion = FuelEngineSet(DummyEngine(1.0e5, 1.0e-5), 2)

    # initialisation then change instance attributes
    segment = AltitudeChangeSegment(
        target=FlightPoint(altitude=10000.0),
        propulsion=propulsion,
        reference_area=120.0,
        polar=polar,
        engine_setting=EngineSetting.CLIMB,
    )  # not constant TAS order, as it is the default
    segment.thrust_rate = 1.0
    segment.time_step = 2.0
    flight_points = segment.compute_from(
        FlightPoint(altitude=5000.0, mass=70000.0,
                    true_airspeed=150.0))  # Test with dict

    last_point = flight_points.iloc[-1]
    # Note: reference values are obtained by running the process with 0.01s as time step
    assert_allclose(last_point.altitude, 10000.0)
    assert_allclose(last_point.true_airspeed, 150.0)
    assert_allclose(last_point.time, 143.5, rtol=1e-2)
    assert_allclose(last_point.mass, 69713.0, rtol=1e-4)
    assert_allclose(last_point.ground_distance, 20943.0, rtol=1e-3)
    assert last_point.engine_setting == EngineSetting.CLIMB
Ejemplo n.º 6
0
def test_climb_fixed_altitude_at_constant_EAS(polar):
    propulsion = FuelEngineSet(DummyEngine(1.0e5, 1.0e-5), 2)

    flight_points = AltitudeChangeSegment(
        target=FlightPoint(altitude=10000.0, equivalent_airspeed="constant"),
        propulsion=propulsion,
        reference_area=120.0,
        polar=polar,
        thrust_rate=1.0,
        time_step=2.0,
        engine_setting=EngineSetting.
        CRUISE,  # The engine model does not use this setting
    ).compute_from(
        FlightPoint(altitude=5000.0, mass=70000.0, equivalent_airspeed=100.0))

    first_point = flight_points.iloc[0]
    last_point = flight_points.iloc[-1]
    # Note: reference values are obtained by running the process with 0.01s as time step
    assert_allclose(last_point.altitude, 10000.0)
    assert_allclose(last_point.equivalent_airspeed, 100.0)
    assert_allclose(last_point.time, 145.2, rtol=1e-2)
    assert_allclose(first_point.true_airspeed, 129.0, atol=0.1)
    assert_allclose(last_point.true_airspeed, 172.3, atol=0.1)
    assert_allclose(last_point.mass, 69710.0, rtol=1e-4)
    assert_allclose(last_point.ground_distance, 20915.0, rtol=1e-3)
    assert last_point.engine_setting == EngineSetting.CRUISE
Ejemplo n.º 7
0
 def get_model(self, inputs) -> IPropulsion:
     return FuelEngineSet(
         DummyEngine(
             inputs["data:propulsion:dummy_engine:max_thrust"],
             inputs["data:propulsion:dummy_engine:max_sfc"],
         ),
         inputs["data:geometry:propulsion:engine_count"],
     )
Ejemplo n.º 8
0
def test_ranged_route(low_speed_polar, high_speed_polar, cleanup):

    engine = DummyEngine(1e5, 2.0e-5)
    propulsion = FuelEngineSet(engine, 2)

    total_distance = 2.0e6

    kwargs = dict(propulsion=propulsion, reference_area=120.0)
    initial_climb = InitialClimbPhase(**kwargs,
                                      polar=low_speed_polar,
                                      thrust_rate=1.0,
                                      name="initial_climb",
                                      time_step=0.2)
    climb = ClimbPhase(
        **kwargs,
        polar=high_speed_polar,
        thrust_rate=0.8,
        target_altitude="mach",
        maximum_mach=0.78,
        name="climb",
        time_step=5.0,
    )
    cruise = CruiseSegment(
        **kwargs,
        target=FlightPoint(ground_distance=0.0),
        polar=high_speed_polar,
        engine_setting=EngineSetting.CRUISE,
        name=FlightPhase.CRUISE.value,
    )
    descent = DescentPhase(
        **kwargs,
        polar=high_speed_polar,
        thrust_rate=0.05,
        target_altitude=1500.0 * foot,
        name=FlightPhase.DESCENT.value,
        time_step=5.0,
    )

    flight_calculator = RangedRoute([initial_climb, climb], cruise, [descent],
                                    total_distance)
    assert flight_calculator.cruise_speed == ("mach", 0.78)

    start = FlightPoint(true_airspeed=150.0 * knot,
                        altitude=100.0 * foot,
                        mass=70000.0,
                        ground_distance=100000.0)
    flight_points = flight_calculator.compute_from(start)

    # plot_flight(flight_points, "test_ranged_flight.png")

    assert_allclose(
        flight_points.iloc[-1].ground_distance,
        total_distance + start.ground_distance,
        atol=flight_calculator.distance_accuracy,
    )
Ejemplo n.º 9
0
def test_acceleration_not_enough_thrust(polar):
    propulsion = FuelEngineSet(DummyEngine(0.5e5, 1.0e-5), 2)

    segment = SpeedChangeSegment(
        target=FlightPoint(true_airspeed=250.0),
        propulsion=propulsion,
        reference_area=120.0,
        polar=polar,
        thrust_rate=0.1,
    )
    assert len(
        segment.compute_from(
            FlightPoint(altitude=5000.0, true_airspeed=150.0, mass=70000.0)))
Ejemplo n.º 10
0
def test_climb_not_enough_thrust(polar):
    propulsion = FuelEngineSet(DummyEngine(1.0e5, 1.0e-5), 2)

    segment = AltitudeChangeSegment(
        target=FlightPoint(altitude=10000.0, true_airspeed="constant"),
        propulsion=propulsion,
        reference_area=120.0,
        polar=polar,
        thrust_rate=0.1,
    )
    assert (len(
        segment.compute_from(
            FlightPoint(altitude=5000.0, true_airspeed=150.0,
                        mass=70000.0))) == 1)
Ejemplo n.º 11
0
    def _compute_mission(self, inputs, outputs):
        """
        Computes mission using time-step integration.

        :param inputs: OpenMDAO input vector
        :param outputs: OpenMDAO output vector
        """
        propulsion_model = FuelEngineSet(
            self._engine_wrapper.get_model(inputs),
            inputs["data:geometry:propulsion:engine:count"])

        reference_area = inputs["data:geometry:wing:area"]

        self._mission_wrapper.propulsion = propulsion_model
        self._mission_wrapper.reference_area = reference_area

        end_of_takeoff = FlightPoint(
            time=0.0,
            mass=inputs[self._mission_vars.TOW.value],
            true_airspeed=inputs[self._mission_vars.TAKEOFF_V2.value],
            altitude=inputs[self._mission_vars.TAKEOFF_ALTITUDE.value] +
            35 * foot,
            ground_distance=0.0,
        )

        self.flight_points = self._mission_wrapper.compute(
            inputs, outputs, end_of_takeoff)

        # Final ================================================================
        end_of_mission = FlightPoint.create(self.flight_points.iloc[-1])
        zfw = end_of_mission.mass - self._mission_wrapper.get_reserve(
            self.flight_points, self.options["mission_name"])
        outputs[self._mission_vars.BLOCK_FUEL.value] = (
            inputs[self._mission_vars.TOW.value] +
            inputs[self._mission_vars.TAKEOFF_FUEL.value] +
            inputs[self._mission_vars.TAXI_OUT_FUEL.value] - zfw)
        if self.options["is_sizing"]:
            outputs["data:weight:aircraft:sizing_block_fuel"] = outputs[
                self._mission_vars.BLOCK_FUEL.value]

        def as_scalar(value):
            if isinstance(value, np.ndarray):
                return np.asscalar(value)
            return value

        self.flight_points = self.flight_points.applymap(as_scalar)
        if self.options["out_file"]:
            self.flight_points.to_csv(self.options["out_file"])
Ejemplo n.º 12
0
def test_hold(polar):
    propulsion = FuelEngineSet(DummyEngine(0.5e5, 2.0e-5), 2)

    segment = HoldSegment(target=FlightPoint(time=3000.0),
                          propulsion=propulsion,
                          reference_area=120.0,
                          polar=polar)
    flight_points = segment.compute_from(
        FlightPoint(altitude=500.0, equivalent_airspeed=250.0, mass=60000.0), )

    last_point = flight_points.iloc[-1]
    assert_allclose(last_point.time, 3000.0)
    assert_allclose(last_point.altitude, 500.0)
    assert_allclose(last_point.equivalent_airspeed, 250.0, atol=0.1)
    assert_allclose(last_point.mass, 57776.0, rtol=1e-4)
    assert_allclose(last_point.ground_distance, 768323.0, rtol=1.0e-3)
Ejemplo n.º 13
0
def test_taxi():
    propulsion = FuelEngineSet(DummyEngine(0.5e5, 1.0e-5), 2)

    segment = TaxiSegment(target=FlightPoint(time=500.0),
                          propulsion=propulsion,
                          thrust_rate=0.1)
    flight_points = segment.compute_from(
        FlightPoint(altitude=10.0,
                    true_airspeed=10.0,
                    mass=50000.0,
                    time=10000.0), )

    last_point = flight_points.iloc[-1]
    assert_allclose(last_point.altitude, 10.0, atol=1.0)
    assert_allclose(last_point.time, 10500.0, rtol=1e-2)
    assert_allclose(last_point.true_airspeed, 10.0, atol=0.1)
    assert_allclose(last_point.mass, 49973.0, rtol=1e-4)
    assert_allclose(last_point.ground_distance, 5000.0)
Ejemplo n.º 14
0
def test_climb_and_cruise_at_optimal_flight_level(polar):
    propulsion = FuelEngineSet(DummyEngine(0.5e5, 3.0e-5), 2)
    reference_area = 120.0

    segment = ClimbAndCruiseSegment(
        target=FlightPoint(
            ground_distance=10.0e6,
            altitude=AltitudeChangeSegment.OPTIMAL_FLIGHT_LEVEL),
        propulsion=propulsion,
        reference_area=reference_area,
        polar=polar,
        engine_setting=EngineSetting.CRUISE,
        climb_segment=AltitudeChangeSegment(
            target=FlightPoint(),
            propulsion=propulsion,
            reference_area=reference_area,
            polar=polar,
            thrust_rate=0.9,
            engine_setting=EngineSetting.CLIMB,
        ),
    )

    flight_points = segment.compute_from(
        FlightPoint(mass=70000.0,
                    altitude=8000.0,
                    mach=0.78,
                    ground_distance=1.0e6))

    first_point = flight_points.iloc[0]
    last_point = flight_points.iloc[-1]
    # Note: reference values are obtained by running the process with 1.0s as time step

    assert_allclose(first_point.altitude, 8000.0)
    assert_allclose(first_point.thrust_rate, 0.9)
    assert_allclose(first_point.true_airspeed, 240.3, atol=0.1)
    assert first_point.engine_setting == EngineSetting.CLIMB

    assert_allclose(flight_points.mach, 0.78)
    assert_allclose(last_point.altitude, 9753.6)
    assert_allclose(last_point.ground_distance, 11.0e6)
    assert_allclose(last_point.time, 42659.0, rtol=1e-3)
    assert_allclose(last_point.true_airspeed, 234.4, atol=0.1)
    assert_allclose(last_point.mass, 48874.0, rtol=1e-4)
    assert last_point.engine_setting == EngineSetting.CRUISE
def test_descent_to_fixed_altitude_at_constant_EAS(polar):
    propulsion = FuelEngineSet(DummyEngine(1.0e5, 1.0e-5), 2)

    flight_points = AltitudeChangeSegment(
        target=FlightPoint(altitude=5000.0, equivalent_airspeed="constant"),
        propulsion=propulsion,
        reference_area=100.0,
        polar=polar,
        thrust_rate=0.1,
        time_step=2.0,
    ).compute_from(FlightPoint(altitude=10000.0, equivalent_airspeed=200.0, mass=70000.0))

    last_point = flight_points.iloc[-1]
    # Note: reference values are obtained by running the process with 0.01s as time step
    assert_allclose(last_point.altitude, 5000.0)
    assert_allclose(last_point.equivalent_airspeed, 200.0)
    assert_allclose(last_point.time, 821.4, rtol=1e-2)
    assert_allclose(last_point.mass, 69910.0, rtol=1e-4)
    assert_allclose(last_point.ground_distance, 243155.0, rtol=1e-3)
Ejemplo n.º 16
0
def test_acceleration_to_mach(polar):
    propulsion = FuelEngineSet(DummyEngine(0.5e5, 1.0e-5), 2)

    flight_points = SpeedChangeSegment(
        target=FlightPoint(mach=0.8),
        propulsion=propulsion,
        reference_area=120.0,
        polar=polar,
        thrust_rate=1.0,
        time_step=0.2,
    ).compute_from(
        FlightPoint(altitude=1000.0, true_airspeed=150.0, mass=70000.0))

    last_point = flight_points.iloc[-1]
    # Note: reference values are obtained by running the process with 0.01s as time step
    assert_allclose(last_point.time, 138.0, rtol=1e-2)
    assert_allclose(last_point.altitude, 1000.0)
    assert_allclose(last_point.mach, 0.8, atol=1e-5)
    assert_allclose(last_point.mass, 69862.0, rtol=1e-4)
    assert_allclose(last_point.ground_distance, 29470.0, rtol=1e-3)
def test_climb_optimal_flight_level_at_fixed_mach(polar):
    propulsion = FuelEngineSet(DummyEngine(1.0e5, 1.0e-5), 2)

    flight_points = AltitudeChangeSegment(
        target=FlightPoint(altitude=AltitudeChangeSegment.OPTIMAL_FLIGHT_LEVEL, mach="constant"),
        propulsion=propulsion,
        reference_area=120.0,
        polar=polar,
        thrust_rate=1.0,
        time_step=2.0,
    ).compute_from(FlightPoint(altitude=5000.0, mach=0.82, mass=70000.0))

    last_point = flight_points.iloc[-1]
    # Note: reference values are obtained by running the process with 0.01s as time step
    assert_allclose(flight_points.mach, 0.82)
    assert_allclose(last_point.altitude / foot, 32000.0, atol=0.1)
    assert_allclose(last_point.time, 77.5, rtol=1e-2)
    assert_allclose(last_point.true_airspeed, 246.44, rtol=1e-4)
    assert_allclose(last_point.mass, 69843.0, rtol=1e-4)
    assert_allclose(last_point.ground_distance, 19179.0, rtol=1e-3)
Ejemplo n.º 18
0
def test_descent_to_fixed_EAS_at_constant_mach(polar):
    propulsion = FuelEngineSet(DummyEngine(1.0e5, 1.0e-5), 2)

    flight_points = AltitudeChangeSegment(
        target=FlightPoint(equivalent_airspeed=150.0, mach="constant"),
        propulsion=propulsion,
        reference_area=100.0,
        polar=polar,
        thrust_rate=0.1,
        # time_step=5.0, # we use default time step
    ).compute_from(FlightPoint(altitude=10000.0, mass=70000.0, mach=0.78))

    last_point = flight_points.iloc[-1]
    # Note: reference values are obtained by running the process with 0.01s as time step
    assert_allclose(last_point.equivalent_airspeed, 150.0)
    assert_allclose(last_point.mach, 0.78)
    assert_allclose(last_point.time, 343.6, rtol=1e-2)
    assert_allclose(last_point.altitude, 8654.0, atol=1.0)
    assert_allclose(last_point.true_airspeed, 238.1, atol=0.1)
    assert_allclose(last_point.mass, 69962.0, rtol=1e-4)
    assert_allclose(last_point.ground_distance, 81042.0, rtol=1e-3)
Ejemplo n.º 19
0
def test_climb_optimal_altitude_at_fixed_TAS(polar):
    propulsion = FuelEngineSet(DummyEngine(1.0e5, 1.0e-5), 2)

    flight_points = AltitudeChangeSegment(
        target=FlightPoint(altitude=AltitudeChangeSegment.OPTIMAL_ALTITUDE,
                           true_airspeed="constant"),
        propulsion=propulsion,
        reference_area=120.0,
        polar=polar,
        thrust_rate=1.0,
        time_step=2.0,
    ).compute_from(
        FlightPoint(altitude=5000.0, true_airspeed=250.0, mass=70000.0))

    last_point = flight_points.iloc[-1]
    # Note: reference values are obtained by running the process with 0.01s as time step
    assert_allclose(last_point.altitude, 10085.0, atol=0.1)
    assert_allclose(last_point.true_airspeed, 250.0)
    assert_allclose(last_point.time, 84.1, rtol=1e-2)
    assert_allclose(last_point.mach, 0.8359, rtol=1e-4)
    assert_allclose(last_point.mass, 69832.0, rtol=1e-4)
    assert_allclose(last_point.ground_distance, 20401.0, rtol=1e-3)
Ejemplo n.º 20
0
def test_deceleration_not_enough_thrust(polar):
    propulsion = FuelEngineSet(DummyEngine(0.5e5, 1.0e-5), 2)

    segment = SpeedChangeSegment(
        target=FlightPoint(true_airspeed=150.0),
        propulsion=propulsion,
        reference_area=120.0,
        polar=polar,
        thrust_rate=0.1,
        time_step=1.0,
    )
    segment.time_step = 1.0
    flight_points = segment.compute_from(
        FlightPoint(altitude=5000.0, true_airspeed=250.0, mass=70000.0))

    last_point = flight_points.iloc[-1]
    # Note: reference values are obtained by running the process with 0.01s as time step
    assert_allclose(last_point.time, 315.8, rtol=1e-2)
    assert_allclose(last_point.altitude, 5000.0)
    assert_allclose(last_point.true_airspeed, 150.0)
    assert_allclose(last_point.mass, 69982.0, rtol=1e-4)
    assert_allclose(last_point.ground_distance, 62804.0, rtol=1e-3)
Ejemplo n.º 21
0
def test_cruise_at_constant_altitude(polar):
    propulsion = FuelEngineSet(DummyEngine(0.5e5, 1.0e-5), 2)

    segment = CruiseSegment(
        target=FlightPoint(ground_distance=5.0e5),
        propulsion=propulsion,
        reference_area=120.0,
        polar=polar,
    )
    flight_points = segment.compute_from(
        FlightPoint(mass=70000.0, altitude=10000.0, mach=0.78))

    first_point = flight_points.iloc[0]
    last_point = flight_points.iloc[-1]
    # Note: reference values are obtained by running the process with 0.05s as time step
    assert_allclose(first_point.altitude, 10000.0)
    assert_allclose(first_point.true_airspeed, 233.6, atol=0.1)

    assert_allclose(last_point.ground_distance, 500000.0)
    assert_allclose(last_point.altitude, 10000.0)
    assert_allclose(last_point.time, 2141.0, rtol=1e-2)
    assert_allclose(last_point.true_airspeed, 233.6, atol=0.1)
    assert_allclose(last_point.mass, 69568.0, rtol=1e-4)
Ejemplo n.º 22
0
def test_acceleration_to_EAS(polar):
    propulsion = FuelEngineSet(DummyEngine(0.5e5, 1.0e-5), 2)

    flight_points = SpeedChangeSegment(
        target=FlightPoint(equivalent_airspeed=250.0),
        propulsion=propulsion,
        reference_area=120.0,
        polar=polar,
        thrust_rate=1.0,
        time_step=0.2,
        engine_setting=EngineSetting.
        CRUISE,  # The engine model does not use this setting
    ).compute_from(
        FlightPoint(altitude=1000.0, true_airspeed=150.0, mass=70000.0))

    last_point = flight_points.iloc[-1]
    # Note: reference values are obtained by running the process with 0.01s as time step
    assert_allclose(last_point.time, 128.2, rtol=1e-2)
    assert_allclose(last_point.altitude, 1000.0)
    assert_allclose(last_point.true_airspeed, 262.4, atol=1e-1)
    assert_allclose(last_point.mass, 69872.0, rtol=1e-4)
    assert_allclose(last_point.ground_distance, 26868.0, rtol=1e-3)
    assert last_point.engine_setting == EngineSetting.CRUISE
Ejemplo n.º 23
0
    def _compute_mission(self, inputs, outputs):
        """
        Computes mission using time-step integration.

        :param inputs: OpenMDAO input vector
        :param outputs: OpenMDAO output vector
        """
        propulsion_model = FuelEngineSet(
            self._engine_wrapper.get_model(inputs),
            inputs["data:geometry:propulsion:engine:count"])

        reference_area = inputs["data:geometry:wing:area"]

        self._mission_wrapper.propulsion = propulsion_model
        self._mission_wrapper.reference_area = reference_area

        self._compute_taxi_out(inputs, outputs, propulsion_model)
        end_of_takeoff = FlightPoint(
            time=0.0,
            mass=inputs[self._mission_vars.TOW],
            true_airspeed=inputs[self._mission_vars.TAKEOFF_V2],
            altitude=inputs[self._mission_vars.TAKEOFF_ALTITUDE] + 35 * foot,
            ground_distance=0.0,
        )

        self.flight_points = self._mission_wrapper.compute(
            inputs, outputs, end_of_takeoff)

        # Final ================================================================
        end_of_mission = FlightPoint.create(self.flight_points.iloc[-1])
        reserve = self._mission_wrapper.get_reserve(
            self.flight_points, self.options["mission_name"])
        zfw = end_of_mission.mass - reserve
        reserve_name = self._mission_wrapper.get_reserve_variable_name()
        if reserve_name in outputs:
            outputs[reserve_name] = reserve
        outputs[self._mission_vars.NEEDED_BLOCK_FUEL] = (
            inputs[self._mission_vars.TOW] +
            inputs[self._mission_vars.TAKEOFF_FUEL] +
            outputs[self._mission_vars.TAXI_OUT_FUEL] - zfw)
        outputs[self._mission_vars.NEEDED_FUEL_AT_TAKEOFF] = (
            outputs[self._mission_vars.NEEDED_BLOCK_FUEL] -
            inputs[self._mission_vars.TAKEOFF_FUEL] -
            outputs[self._mission_vars.TAXI_OUT_FUEL])
        if self.options["is_sizing"]:
            outputs["data:weight:aircraft:sizing_block_fuel"] = outputs[
                self._mission_vars.NEEDED_BLOCK_FUEL]
            outputs[
                "data:weight:aircraft:sizing_onboard_fuel_at_takeoff"] = outputs[
                    self._mission_vars.NEEDED_FUEL_AT_TAKEOFF]

        def as_scalar(value):
            if isinstance(value, np.ndarray):
                return np.asscalar(value)
            return value

        self.flight_points = self.flight_points.applymap(as_scalar)
        rename_dict = {
            field_name: "%s [%s]" % (field_name, unit)
            for field_name, unit in FlightPoint.get_units().items()
        }
        self.flight_points.rename(columns=rename_dict, inplace=True)

        if self.options["out_file"]:
            self.flight_points.to_csv(self.options["out_file"])