예제 #1
0
def test_mission_group_without_loop(cleanup):
    input_file_path = pth.join(DATA_FOLDER_PATH, "test_mission.xml")
    vars = VariableIO(input_file_path).read()
    ivc = vars.to_ivc()

    with pytest.raises(FastMissionFileMissingMissionNameError):
        run_system(
            Mission(
                propulsion_id="test.wrapper.propulsion.dummy_engine",
                out_file=pth.join(RESULTS_FOLDER_PATH, "test_unlooped_mission_group.csv"),
                use_initializer_iteration=False,
                mission_file_path=pth.join(DATA_FOLDER_PATH, "test_mission.yml"),
                adjust_fuel=False,
            ),
            ivc,
        )

    problem = run_system(
        Mission(
            propulsion_id="test.wrapper.propulsion.dummy_engine",
            out_file=pth.join(RESULTS_FOLDER_PATH, "test_unlooped_mission_group.csv"),
            use_initializer_iteration=False,
            mission_file_path=pth.join(DATA_FOLDER_PATH, "test_mission.yml"),
            mission_name="operational",
            adjust_fuel=False,
        ),
        ivc,
    )
    assert_allclose(problem["data:mission:operational:needed_block_fuel"], 6589.0, atol=1.0)
    assert_allclose(problem["data:mission:operational:block_fuel"], 15000.0, atol=1.0)
예제 #2
0
def test_loop_compute_oew():
    """
    Tests a weight computation loop matching the max payload criterion.
    """
    # With payload from npax
    reader = VariableIO(
        pth.join(pth.dirname(__file__), "data", "mass_breakdown_inputs.xml"))
    reader.path_separator = ":"
    input_vars = reader.read(ignore=[
        "data:weight:aircraft:MLW",
        "data:weight:aircraft:MZFW",
        "data:weight:aircraft:max_payload",
    ]).to_ivc()
    mass_computation = run_system(MassBreakdown(), input_vars)
    oew = mass_computation["data:weight:aircraft:OWE"]
    assert oew == pytest.approx(41591, abs=1)

    # with payload as input
    reader = VariableIO(
        pth.join(pth.dirname(__file__), "data", "mass_breakdown_inputs.xml"))
    reader.path_separator = ":"
    input_vars = reader.read(ignore=[
        "data:weight:aircraft:MLW",
        "data:weight:aircraft:MZFW",
    ]).to_ivc()
    mass_computation = run_system(MassBreakdown(payload_from_npax=False),
                                  input_vars)
    oew = mass_computation["data:weight:aircraft:OWE"]
    assert oew == pytest.approx(42060, abs=1)
예제 #3
0
def test_breguet_with_rubber_engine():
    ivc = om.IndepVarComp()
    ivc.add_output("data:mission:sizing:main_route:cruise:altitude",
                   35000,
                   units="ft")
    ivc.add_output("data:TLAR:cruise_mach", 0.78)
    ivc.add_output("data:TLAR:range", 500, units="NM")
    ivc.add_output("data:TLAR:NPAX", 150)
    ivc.add_output("data:aerodynamics:aircraft:cruise:L_D_max", 16.0)
    ivc.add_output("data:weight:aircraft:MTOW", 74000, units="kg")

    ivc.add_output("data:propulsion:rubber_engine:bypass_ratio", 5)
    ivc.add_output("data:propulsion:rubber_engine:maximum_mach", 0.95)
    ivc.add_output("data:propulsion:rubber_engine:design_altitude",
                   35000,
                   units="ft")
    ivc.add_output("data:propulsion:MTO_thrust", 100000, units="N")
    ivc.add_output("data:propulsion:rubber_engine:overall_pressure_ratio", 30)
    ivc.add_output("data:propulsion:rubber_engine:turbine_inlet_temperature",
                   1500,
                   units="K")

    # With rubber engine OM component
    group = om.Group()
    group.add_subsystem("breguet", OMBreguet(), promotes=["*"])
    group.add_subsystem("engine", OMRubberEngineComponent(), promotes=["*"])
    group.nonlinear_solver = om.NonlinearBlockGS()
    problem = run_system(group, ivc)

    assert_allclose(problem["data:mission:sizing:ZFW"], 65076.0, atol=1)
    assert_allclose(problem["data:mission:sizing:fuel"], 8924.0, atol=1)
    assert_allclose(problem["data:mission:sizing:fuel:unitary"],
                    0.0642,
                    rtol=1e-3)

    # With direct call to rubber engine
    problem2 = run_system(
        OMBreguet(propulsion_id="fastoad.wrapper.propulsion.rubber_engine"),
        ivc)

    assert_allclose(problem2["data:mission:sizing:ZFW"], 65076.0, atol=1)
    assert_allclose(problem2["data:mission:sizing:fuel"], 8924.0, atol=1)
    assert_allclose(problem2["data:mission:sizing:fuel:unitary"],
                    0.0642,
                    rtol=1e-3)

    engine = RubberEngine(5, 30, 1500, 100000, 0.95, 35000 * foot, -50)
    directly_computed_flight_point = FlightPoint(
        mach=0.78,
        altitude=35000 * foot,
        engine_setting=EngineSetting.CRUISE,
        thrust=problem["data:propulsion:required_thrust"],
    )
    engine.compute_flight_points(directly_computed_flight_point)
    assert_allclose(
        directly_computed_flight_point.sfc,
        problem["data:propulsion:SFC"],
    )
예제 #4
0
def test_breguet():
    # test 1
    ivc = om.IndepVarComp()
    ivc.add_output("data:mission:sizing:main_route:cruise:altitude", 35000, units="ft")
    ivc.add_output("data:TLAR:cruise_mach", 0.78)
    ivc.add_output("data:TLAR:range", 500, units="NM")
    ivc.add_output("data:TLAR:NPAX", 150)
    ivc.add_output("data:aerodynamics:aircraft:cruise:L_D_max", 16.0)
    ivc.add_output("data:propulsion:SFC", 1e-5, units="kg/N/s")
    ivc.add_output("data:weight:aircraft:MTOW", 74000, units="kg")

    problem = run_system(OMBreguet(), ivc)

    assert_allclose(problem["data:mission:sizing:ZFW"], 65617.0, rtol=1e-3)
    assert_allclose(problem["data:mission:sizing:fuel"], 8382.0, rtol=1e-3)
    assert_allclose(problem["data:mission:sizing:fuel:unitary"], 0.0604, rtol=1e-3)
    assert_allclose(problem["data:mission:sizing:fuel:unitary"], 0.0604, rtol=1e-3)
    assert_allclose(
        problem.get_val("data:mission:sizing:main_route:climb:distance", units="km"), 250.0
    )
    assert_allclose(
        problem.get_val("data:mission:sizing:main_route:descent:distance", units="km"), 250.0
    )
    assert_allclose(
        problem.get_val("data:mission:sizing:main_route:cruise:distance", units="km"), 426.0
    )
    # test 2
    ivc = om.IndepVarComp()
    ivc.add_output("data:mission:sizing:main_route:cruise:altitude", 35000, units="ft")
    ivc.add_output("data:TLAR:cruise_mach", 0.78)
    ivc.add_output("data:TLAR:range", 1500, units="NM")
    ivc.add_output("data:TLAR:NPAX", 120)
    ivc.add_output("data:aerodynamics:aircraft:cruise:L_D_max", 16.0)
    ivc.add_output("data:propulsion:SFC", 1e-5, units="kg/N/s")
    ivc.add_output("data:weight:aircraft:MTOW", 74000, units="kg")

    problem = run_system(OMBreguet(), ivc)

    assert_allclose(problem["data:mission:sizing:ZFW"], 62473.0, rtol=1e-3)
    assert_allclose(problem["data:mission:sizing:fuel"], 11526.0, rtol=1e-3)
    assert_allclose(problem["data:mission:sizing:fuel:unitary"], 0.0346, rtol=1e-3)

    # Check consistency of other outputs
    assert_allclose(
        problem["data:mission:sizing:fuel"],
        problem["data:mission:sizing:main_route:fuel"]
        + problem["data:mission:sizing:fuel_reserve"],
        rtol=1e-3,
    )
    assert_allclose(
        problem["data:mission:sizing:main_route:fuel"],
        problem["data:mission:sizing:main_route:climb:fuel"]
        + problem["data:mission:sizing:main_route:cruise:fuel"]
        + problem["data:mission:sizing:main_route:descent:fuel"],
        rtol=1e-3,
    )
예제 #5
0
def test_avl_sizing():
    """
    Test simple AVL computation with sizing option (nz=2.5) and simplified rectangular swept wing
    """
    if pth.exists(AVL_RESULTS):
        shutil.rmtree(AVL_RESULTS)
    input_list = [
        "data:geometry:wing:span",
        "data:geometry:wing:area",
        "data:geometry:wing:sweep_0",
        "data:geometry:wing:MAC:length",
        "data:geometry:wing:MAC:at25percent:x",
        "tuning:aerostructural:aerodynamic:chordwise_spacing:k",
    ]

    # Test with only wing and fuselage -------------------------------------------------------------
    load_case = {
        "weight": 78000,
        "altitude": 30000,
        "mach": 0.84,
        "load_factor": 2.5
    }
    components = ["wing"]
    sections = [12]
    ivc = get_ivc_for_components(components, sections, input_list, load_case)
    avl_comp = AVL(components=components, components_sections=sections)
    problem = run_system(avl_comp, ivc)

    forces_test = np.loadtxt(pth.join(pth.dirname(__file__), "data",
                                      "forces_results_wing_2p5g"),
                             skiprows=1)

    np.testing.assert_allclose(
        problem["data:aerostructural:aerodynamic:wing:forces"],
        forces_test,
        rtol=1e-3)

    # Test for complete aircraft (wing, fuselage, tails) -------------------------------------------
    components = ["wing", "horizontal_tail", "vertical_tail"]
    sections = [12, 11, 5]
    ivc = get_ivc_for_components(components, sections, input_list, load_case)

    avl_comp = AVL(components=components, components_sections=sections)
    problem = run_system(avl_comp, ivc)
    forces_test = np.loadtxt(pth.join(pth.dirname(__file__), "data",
                                      "forces_results_full_2p5g"),
                             skiprows=1)

    forces_fast = np.vstack((
        problem["data:aerostructural:aerodynamic:wing:forces"],
        problem["data:aerostructural:aerodynamic:horizontal_tail:forces"],
        problem["data:aerostructural:aerodynamic:vertical_tail:forces"],
    ))
    np.testing.assert_allclose(forces_fast, forces_test)
예제 #6
0
def test_compute_wing_area():
    # Driven by fuel
    ivc = om.IndepVarComp()
    ivc.add_output("data:geometry:wing:aspect_ratio", 9.48)
    ivc.add_output("data:geometry:wing:root:thickness_ratio", 0.15)
    ivc.add_output("data:geometry:wing:tip:thickness_ratio", 0.11)
    ivc.add_output("data:weight:aircraft:sizing_block_fuel",
                   val=20500,
                   units="kg")
    ivc.add_output("data:TLAR:approach_speed", val=132, units="kn")
    ivc.add_output("data:weight:aircraft:MLW", val=66300, units="kg")

    ivc.add_output("data:weight:aircraft:MFW", val=21000, units="kg")
    ivc.add_output("data:aerodynamics:aircraft:landing:CL_max", val=2.80)

    problem = run_system(ComputeWingArea(), ivc)
    assert_allclose(problem["data:geometry:wing:area"], 133.97, atol=1e-2)
    assert_allclose(
        problem["data:aerodynamics:aircraft:landing:additional_CL_capacity"],
        0.199,
        atol=1e-2)
    assert_allclose(problem["data:weight:aircraft:additional_fuel_capacity"],
                    500.0,
                    atol=1.0)

    # Driven by CL max
    ivc = om.IndepVarComp()
    ivc.add_output("data:geometry:wing:aspect_ratio", 9.48)
    ivc.add_output("data:geometry:wing:root:thickness_ratio", 0.15)
    ivc.add_output("data:geometry:wing:tip:thickness_ratio", 0.11)
    ivc.add_output("data:weight:aircraft:sizing_block_fuel",
                   val=15000,
                   units="kg")
    ivc.add_output("data:TLAR:approach_speed", val=132, units="kn")
    ivc.add_output("data:weight:aircraft:MLW", val=66300, units="kg")

    ivc.add_output("data:weight:aircraft:MFW", val=21000, units="kg")
    ivc.add_output("data:aerodynamics:aircraft:landing:CL_max", val=2.80)

    problem = run_system(ComputeWingArea(), ivc)
    assert_allclose(problem["data:geometry:wing:area"], 124.38, atol=1e-2)
    assert_allclose(
        problem["data:aerodynamics:aircraft:landing:additional_CL_capacity"],
        0.0,
        atol=1e-2)
    assert_allclose(problem["data:weight:aircraft:additional_fuel_capacity"],
                    6000.0,
                    atol=1.0)
예제 #7
0
def test_vtp_props():
    input_list = [
        "data:geometry:vertical_tail:root:chord",
        "data:geometry:vertical_tail:tip:chord",
        "data:geometry:vertical_tail:thickness_ratio",
        "data:geometry:vertical_tail:span",
        "data:geometry:fuselage:maximum_height",
    ]
    ivc = get_indep_var_comp(input_list)
    nodes = np.zeros((6, 3))
    z = np.linspace(2.02994, 8.93118, 3)
    nodes[:, 2] = np.tile(z, 2)
    ivc.add_output("data:aerostructural:structure:vertical_tail:nodes", nodes)
    problem = run_system(VtailBeamProps(number_of_sections=2), ivc)
    a = problem[
        "data:aerostructural:structure:vertical_tail:beam_properties"][:, 0]
    i1 = problem[
        "data:aerostructural:structure:vertical_tail:beam_properties"][:, 1]
    i2 = problem[
        "data:aerostructural:structure:vertical_tail:beam_properties"][:, 2]
    j = problem[
        "data:aerostructural:structure:vertical_tail:beam_properties"][:, 3]
    assert a[:2] == approx(np.array([3.6514e-2, 2.3734e-2]), abs=1e-5)
    assert i1[:2] == approx(np.array([3.0052e-3, 8.253e-4]), abs=1e-6)
    assert i2[:2] == approx(np.array([3.7565e-2, 1.0316e-2]), abs=1e-6)
    assert j[:2] == approx(np.array([9.3913e-3, 2.5791e-3]), abs=1e-6)
예제 #8
0
def test_htp_props():
    input_list = [
        "data:geometry:horizontal_tail:span",
        "data:geometry:horizontal_tail:root:chord",
        "data:geometry:horizontal_tail:tip:chord",
        "data:geometry:horizontal_tail:thickness_ratio",
    ]
    ivc = get_indep_var_comp(input_list)

    nodes = np.zeros((6, 3))
    y = np.linspace(0.0, 6.13961, 3)
    nodes[:, 1] = np.tile(y, 2)
    ivc.add_output("data:aerostructural:structure:horizontal_tail:nodes",
                   nodes)
    problem = run_system(HtailBeamProps(number_of_sections=2), ivc)
    a = problem[
        "data:aerostructural:structure:horizontal_tail:beam_properties"][:, 0]
    i1 = problem[
        "data:aerostructural:structure:horizontal_tail:beam_properties"][:, 1]
    i2 = problem[
        "data:aerostructural:structure:horizontal_tail:beam_properties"][:, 2]
    j = problem[
        "data:aerostructural:structure:horizontal_tail:beam_properties"][:, 3]

    assert a[:2] == approx(np.array([2.6435e-2, 1.7183e-2]), abs=1e-5)
    assert i1[:2] == approx(np.array([1.1403e-3, 3.1315e-4]), abs=1e-6)
    assert i2[:2] == approx(np.array([1.4254e-2, 3.9144e-3]), abs=1e-6)
    assert j[:2] == approx(np.array([3.5634e-3, 9.7860e-4]), abs=1e-6)
def test_geometry_wing_l2_l3(input_xml):
    """ Tests computation of the wing chords (l2 and l3) """

    input_list = [
        "data:geometry:wing:span",
        "data:geometry:fuselage:maximum_width",
        "data:geometry:wing:taper_ratio",
        "data:geometry:wing:sweep_25",
        "data:geometry:wing:root:virtual_chord",
        "data:geometry:wing:tip:chord",
        "data:geometry:wing:root:y",
        "data:geometry:wing:kink:y",
        "data:geometry:wing:tip:y",
    ]

    input_vars = input_xml.read(only=input_list).to_ivc()

    component = ComputeL2AndL3Wing()

    problem = run_system(component, input_vars)

    wing_l2 = problem["data:geometry:wing:root:chord"]
    assert wing_l2 == pytest.approx(6.26, abs=1e-2)
    wing_l3 = problem["data:geometry:wing:kink:chord"]
    assert wing_l3 == pytest.approx(3.985, abs=1e-3)
def test_compute_fuselage_basic(input_xml):
    """ Tests computation of the fuselage with no cabin sizing """

    input_list = [
        "data:geometry:cabin:NPAX1",
        "data:geometry:fuselage:length",
        "data:geometry:fuselage:maximum_width",
        "data:geometry:fuselage:maximum_height",
        "data:geometry:fuselage:front_length",
        "data:geometry:fuselage:rear_length",
        "data:geometry:fuselage:PAX_length",
    ]

    input_vars = input_xml.read(only=input_list).to_ivc()

    problem = run_system(ComputeFuselageGeometryBasic(), input_vars)

    cg_systems_c6 = problem["data:weight:systems:flight_kit:CG:x"]
    assert cg_systems_c6 == pytest.approx(9.19, abs=1e-2)
    cg_furniture_d2 = problem["data:weight:furniture:passenger_seats:CG:x"]
    assert cg_furniture_d2 == pytest.approx(14.91, abs=1e-2)
    fuselage_lcabin = problem["data:geometry:cabin:length"]
    assert fuselage_lcabin == pytest.approx(30.38, abs=1e-2)
    fuselage_wet_area = problem["data:geometry:fuselage:wetted_area"]
    assert fuselage_wet_area == pytest.approx(401.962, abs=1e-3)
    pnc = problem["data:geometry:cabin:crew_count:commercial"]
    assert pnc == pytest.approx(4, abs=1)
예제 #11
0
def test_htail_chords():
    input_list = [
        "data:geometry:wing:MAC:at25percent:x",
        "data:geometry:horizontal_tail:MAC:length",
        "data:geometry:horizontal_tail:MAC:at25percent:x:local",
        "data:geometry:horizontal_tail:MAC:at25percent:x:from_wingMAC25",
        "data:geometry:horizontal_tail:span",
        "data:geometry:horizontal_tail:sweep_0",
        "data:geometry:horizontal_tail:span",
        "data:geometry:horizontal_tail:root:chord",
        "data:geometry:horizontal_tail:tip:chord",
    ]

    ivc = get_indep_var_comp(input_list)
    group = om.Group()
    group.add_subsystem("HtailNodes",
                        AerodynamicNodesHtail(number_of_sections=12),
                        promotes=["*"])
    group.add_subsystem("HtailChords",
                        AerodynamicChordsHtail(number_of_sections=12),
                        promotes=["*"])
    problem = run_system(group, ivc)
    chord = problem["data:aerostructural:aerodynamic:horizontal_tail:chords"]

    assert chord[0] == approx(4.40580, abs=1e-5)  # Check root chord
    assert chord[6] == approx(2.86377, abs=1e-5)  # Check intermediate chord
    assert chord[12] == approx(1.32174, abs=1e-5)  # Check tip chord
    assert chord[19] == approx(2.86377,
                               abs=1e-5)  # Check symmetry intermediate chord
예제 #12
0
def test_vtail_chords():
    input_list = [
        "data:geometry:wing:MAC:at25percent:x",
        "data:geometry:vertical_tail:MAC:at25percent:x:local",
        "data:geometry:vertical_tail:MAC:at25percent:x:from_wingMAC25",
        "data:geometry:vertical_tail:MAC:length",
        "data:geometry:vertical_tail:span",
        "data:geometry:vertical_tail:sweep_0",
        "data:geometry:fuselage:maximum_height",
        "data:geometry:vertical_tail:root:chord",
        "data:geometry:vertical_tail:tip:chord",
    ]

    ivc = get_indep_var_comp(input_list)
    group = om.Group()
    group.add_subsystem("VtailNodes",
                        AerodynamicNodesVtail(number_of_sections=12),
                        promotes=["*"])
    group.add_subsystem("VtailChords",
                        AerodynamicChordsVtail(number_of_sections=12),
                        promotes=["*"])
    problem = run_system(group, ivc)
    chord = problem["data:aerostructural:aerodynamic:vertical_tail:chords"]

    assert chord[0] == approx(6.08571, abs=1e-5)  # Check root chord
    assert chord[6] == approx(3.95571, abs=1e-5)  # Check intermediate chord
    assert chord[12] == approx(1.82571, abs=1e-5)  # Check tip chord
예제 #13
0
    def get_cl_cd(slat_angle, flap_angle, mach, landing_flag):
        ivc = get_indep_var_comp(input_list)
        if landing_flag:
            ivc.add_output("data:mission:sizing:landing:slat_angle",
                           slat_angle,
                           units="deg")
            ivc.add_output("data:mission:sizing:landing:flap_angle",
                           flap_angle,
                           units="deg")
            ivc.add_output("data:aerodynamics:aircraft:landing:mach", mach)
        else:
            ivc.add_output("data:mission:sizing:takeoff:slat_angle",
                           slat_angle,
                           units="deg")
            ivc.add_output("data:mission:sizing:takeoff:flap_angle",
                           flap_angle,
                           units="deg")
            ivc.add_output("data:aerodynamics:aircraft:takeoff:mach", mach)
        component = ComputeDeltaHighLift()
        component.options["landing_flag"] = landing_flag
        problem = run_system(component, ivc)
        if landing_flag:
            return (
                problem["data:aerodynamics:high_lift_devices:landing:CL"],
                problem["data:aerodynamics:high_lift_devices:landing:CD"],
            )

        return (
            problem["data:aerodynamics:high_lift_devices:takeoff:CL"],
            problem["data:aerodynamics:high_lift_devices:takeoff:CD"],
        )
예제 #14
0
def test_transfer_matrices():
    comps = ["wing", "horizontal_tail", "vertical_tail", "fuselage"]
    sects = [5, 5, 5, 4]
    interp = ["linear", "linear", "linear", "rigid"]

    #  Rectangular wing and surfaces geometry from inputs file
    input_list = [
        "data:aerostructural:structure:wing:nodes",
        "data:aerostructural:structure:horizontal_tail:nodes",
        "data:aerostructural:structure:vertical_tail:nodes",
        "data:aerostructural:structure:fuselage:nodes",
        "data:aerostructural:aerodynamic:wing:nodes",
        "data:aerostructural:aerodynamic:horizontal_tail:nodes",
        "data:aerostructural:aerodynamic:vertical_tail:nodes",
        "data:aerostructural:aerodynamic:fuselage:nodes",
    ]
    ivc = get_indep_var_comp(input_list)

    problem = run_system(
        TransferMatrices(components=comps,
                         components_sections=sects,
                         components_interp=interp), ivc)
    t_mat_wing = problem["data:aerostructural:transfer:wing:matrix"]
    t_mat_htp = problem["data:aerostructural:transfer:horizontal_tail:matrix"]
    t_mat_vtp = problem["data:aerostructural:transfer:vertical_tail:matrix"]
    t_mat_fuse = problem["data:aerostructural:transfer:fuselage:matrix"]
    assert t_mat_wing == approx(_test_matrix(12, 2.0), abs=1e-5)
    assert t_mat_htp == approx(_test_matrix(12, 1.0), abs=1e-5)
    assert t_mat_vtp == approx(_test_matrix(6, 1.0), abs=1e-5)
    assert t_mat_fuse == approx(np.zeros((36, 30)), abs=1e-5)
예제 #15
0
def test_aerodynamics_landing_with_xfoil():
    """ Tests AerodynamicsHighSpeed """
    input_list = [
        "data:TLAR:approach_speed",
        "data:mission:sizing:landing:flap_angle",
        "data:mission:sizing:landing:slat_angle",
        "data:geometry:wing:MAC:length",
        "data:geometry:wing:thickness_ratio",
        "data:geometry:wing:sweep_25",
        "data:geometry:wing:sweep_0",
        "data:geometry:wing:sweep_100_outer",
        "data:geometry:flap:chord_ratio",
        "data:geometry:flap:span_ratio",
        "data:geometry:slat:chord_ratio",
        "data:geometry:slat:span_ratio",
        "xfoil:mach",
        "tuning:aerodynamics:aircraft:landing:CL_max:landing_gear_effect:k",
    ]

    ivc = get_indep_var_comp(input_list)
    problem = run_system(AerodynamicsLanding(xfoil_exe_path=xfoil_path), ivc)
    # Reference values are for Windows XFOIL version, but as results can be slightly different on other
    # platforms, tolerance is extended to 1e-2
    assert problem["data:aerodynamics:aircraft:landing:CL_max_clean"] == approx(1.59359, abs=1e-2)
    assert problem["data:aerodynamics:aircraft:landing:CL_max"] == approx(2.82178, abs=1e-2)
예제 #16
0
def test_aerodynamics_landing_without_xfoil():
    """ Tests AerodynamicsHighSpeed """
    input_list = [
        "data:TLAR:approach_speed",
        "data:mission:sizing:landing:flap_angle",
        "data:mission:sizing:landing:slat_angle",
        "data:geometry:wing:MAC:length",
        "data:geometry:wing:thickness_ratio",
        "data:geometry:wing:sweep_25",
        "data:geometry:wing:sweep_0",
        "data:geometry:wing:sweep_100_outer",
        "data:geometry:flap:chord_ratio",
        "data:geometry:flap:span_ratio",
        "data:geometry:slat:chord_ratio",
        "data:geometry:slat:span_ratio",
        "xfoil:mach",
        "tuning:aerodynamics:aircraft:landing:CL_max:landing_gear_effect:k",
        "data:aerodynamics:aircraft:landing:CL_max_clean_2D",
    ]

    ivc = get_indep_var_comp(input_list)
    problem = run_system(AerodynamicsLanding(use_xfoil=False), ivc)
    assert problem[
        "data:aerodynamics:aircraft:landing:CL_max_clean"] == approx(1.54978,
                                                                     abs=1e-5)
    assert problem["data:aerodynamics:aircraft:landing:CL_max"] == approx(
        2.77798, abs=1e-5)
예제 #17
0
def test_mission_group_breguet_with_loop(cleanup):

    input_file_path = pth.join(DATA_FOLDER_PATH, "test_mission.xml")
    vars = VariableIO(input_file_path).read()
    del vars["data:mission:operational:TOW"]
    ivc = vars.to_ivc()

    problem = run_system(
        Mission(
            propulsion_id="test.wrapper.propulsion.dummy_engine",
            out_file=pth.join(RESULTS_FOLDER_PATH, "test_looped_mission_group.csv"),
            use_initializer_iteration=True,
            mission_file_path=pth.join(DATA_FOLDER_PATH, "test_breguet.yml"),
            add_solver=True,
        ),
        ivc,
    )

    # check loop
    assert_allclose(
        problem["data:mission:operational:TOW"],
        problem["data:mission:operational:OWE"]
        + problem["data:mission:operational:payload"]
        + problem["data:mission:operational:block_fuel"],
        atol=1.0,
    )
    assert_allclose(
        problem["data:mission:operational:needed_block_fuel"],
        problem["data:mission:operational:block_fuel"],
        atol=1.0,
    )
    assert_allclose(
        problem["data:mission:operational:needed_block_fuel"], 5640.0, atol=1.0,
    )
예제 #18
0
 def get_cd_trim(cl):
     ivc = IndepVarComp()
     ivc.add_output(
         "data:aerodynamics:aircraft:cruise:CL", 150 * [cl]
     )  # needed because size of input array is fixed
     problem = run_system(CdTrim(), ivc)
     return problem["data:aerodynamics:aircraft:cruise:CD:trim"][0]
예제 #19
0
def test_compute_vt_cg(input_xml):
    """Tests computation of the vertical tail center of gravity"""

    input_list = [
        "data:geometry:vertical_tail:root:chord",
        "data:geometry:vertical_tail:tip:chord",
        "data:geometry:vertical_tail:MAC:at25percent:x:from_wingMAC25",
        "data:geometry:vertical_tail:span",
        "data:geometry:wing:MAC:at25percent:x",
        "data:geometry:vertical_tail:sweep_25",
        "data:geometry:vertical_tail:MAC:length",
    ]

    input_vars = input_xml.read(only=input_list).to_ivc()

    input_vars.add_output(
        "data:geometry:vertical_tail:MAC:at25percent:x:local",
        2.321,
        units="m")

    component = ComputeVTcg()

    problem = run_system(component, input_vars)

    cg_a32 = problem["data:weight:airframe:vertical_tail:CG:x"]
    assert cg_a32 == pytest.approx(34.265, abs=1e-3)
def test_geometry_wing_mac(input_xml):
    """ Tests computation of the wing mean aerodynamic chord """

    input_list = [
        "data:geometry:wing:area",
        "data:geometry:wing:kink:leading_edge:x:local",
        "data:geometry:wing:tip:leading_edge:x:local",
        "data:geometry:wing:root:y",
        "data:geometry:wing:kink:y",
        "data:geometry:wing:tip:y",
        "data:geometry:wing:root:chord",
        "data:geometry:wing:kink:chord",
        "data:geometry:wing:tip:chord",
    ]

    input_vars = input_xml.read(only=input_list).to_ivc()

    component = ComputeMACWing()

    problem = run_system(component, input_vars)

    wing_l0 = problem["data:geometry:wing:MAC:length"]
    assert wing_l0 == pytest.approx(4.457, abs=1e-3)
    wing_x0 = problem["data:geometry:wing:MAC:leading_edge:x:local"]
    assert wing_x0 == pytest.approx(2.361, abs=1e-3)
    wing_y0 = problem["data:geometry:wing:MAC:y"]
    assert wing_y0 == pytest.approx(6.293, abs=1e-3)
def test_geometry_wing_sweep(input_xml):
    """ Tests computation of the wing sweeps """

    input_list = [
        "data:geometry:wing:kink:leading_edge:x:local",
        "data:geometry:wing:tip:leading_edge:x:local",
        "data:geometry:wing:root:y",
        "data:geometry:wing:kink:y",
        "data:geometry:wing:tip:y",
        "data:geometry:wing:root:chord",
        "data:geometry:wing:kink:chord",
        "data:geometry:wing:tip:chord",
    ]

    input_vars = input_xml.read(only=input_list).to_ivc()

    component = ComputeSweepWing()

    problem = run_system(component, input_vars)

    sweep_0 = problem["data:geometry:wing:sweep_0"]
    assert sweep_0 == pytest.approx(27.55, abs=1e-2)
    sweep_100_inner = problem["data:geometry:wing:sweep_100_inner"]
    assert sweep_100_inner == pytest.approx(0.0, abs=1e-1)
    sweep_100_outer = problem["data:geometry:wing:sweep_100_outer"]
    assert sweep_100_outer == pytest.approx(16.7, abs=1e-1)
예제 #22
0
def test_compute_cg_wing(input_xml):
    """ Tests computation of wing center of gravity """

    input_list = [
        "data:geometry:wing:kink:span_ratio",
        "data:geometry:wing:spar_ratio:front:root",
        "data:geometry:wing:spar_ratio:front:kink",
        "data:geometry:wing:spar_ratio:front:tip",
        "data:geometry:wing:spar_ratio:rear:root",
        "data:geometry:wing:spar_ratio:rear:kink",
        "data:geometry:wing:spar_ratio:rear:tip",
        "data:geometry:wing:span",
        "data:geometry:wing:MAC:length",
        "data:geometry:wing:MAC:leading_edge:x:local",
        "data:geometry:wing:root:chord",
        "data:geometry:wing:kink:chord",
        "data:geometry:wing:tip:chord",
        "data:geometry:wing:root:y",
        "data:geometry:wing:kink:leading_edge:x:local",
        "data:geometry:wing:kink:y",
        "data:geometry:wing:tip:y",
        "data:geometry:wing:tip:leading_edge:x:local",
        "data:geometry:wing:MAC:at25percent:x",
    ]

    input_vars = input_xml.read(only=input_list).to_ivc()

    problem = run_system(ComputeWingCG(), input_vars)

    x_cg_wing = problem["data:weight:airframe:wing:CG:x"]
    assert x_cg_wing == pytest.approx(16.67, abs=1e-2)
예제 #23
0
def test_compute_power_systems_weight():
    """ Tests power systems weight computation from sample XML data """
    input_list = [
        "data:weight:aircraft:MTOW",
        "tuning:weight:systems:power:auxiliary_power_unit:mass:k",
        "tuning:weight:systems:power:auxiliary_power_unit:mass:offset",
        "tuning:weight:systems:power:electric_systems:mass:k",
        "tuning:weight:systems:power:electric_systems:mass:offset",
        "tuning:weight:systems:power:hydraulic_systems:mass:k",
        "tuning:weight:systems:power:hydraulic_systems:mass:offset",
        "settings:weight:systems:power:mass:k_elec",
    ]
    ivc = get_indep_var_comp(input_list)
    ivc.add_output("data:geometry:cabin:NPAX1", 150)
    ivc.add_output("data:weight:airframe:flight_controls:mass",
                   700,
                   units="kg")
    problem = run_system(PowerSystemsWeight(), ivc)

    val1 = problem["data:weight:systems:power:auxiliary_power_unit:mass"]
    val2 = problem["data:weight:systems:power:electric_systems:mass"]
    val3 = problem["data:weight:systems:power:hydraulic_systems:mass"]
    assert val1 == pytest.approx(279, abs=1)
    assert val2 == pytest.approx(1297, abs=1)
    assert val3 == pytest.approx(747, abs=1)
예제 #24
0
def test_compute_vt_area(input_xml):
    """Tests computation of the vertical tail area"""

    input_list = [
        "data:TLAR:cruise_mach",
        "data:geometry:wing:MAC:length",
        "data:geometry:wing:MAC:length",
        "data:geometry:wing:area",
        "data:geometry:wing:span",
        "data:geometry:vertical_tail:MAC:at25percent:x:from_wingMAC25",
        "data:aerodynamics:vertical_tail:cruise:CL_alpha",
    ]

    input_vars = input_xml.read(only=input_list).to_ivc()

    input_vars.add_output("data:weight:aircraft:CG:aft:MAC_position", 0.364924)
    input_vars.add_output("data:aerodynamics:fuselage:cruise:CnBeta",
                          -0.117901)

    component = ComputeVTArea()

    problem = run_system(component, input_vars)

    cn_beta_vt = problem["data:aerodynamics:vertical_tail:cruise:CnBeta"]
    assert cn_beta_vt == pytest.approx(0.258348, abs=1e-6)
    wet_area = problem["data:geometry:vertical_tail:wetted_area"]
    assert wet_area == pytest.approx(52.34, abs=1e-2)
    vt_area = problem["data:geometry:vertical_tail:area"]
    assert vt_area == pytest.approx(24.92, abs=1e-2)
예제 #25
0
def test_compute_cg_tanks(input_xml):
    """ Tests computation of tanks center of gravity """

    input_list = [
        "data:geometry:wing:spar_ratio:front:root",
        "data:geometry:wing:spar_ratio:front:kink",
        "data:geometry:wing:spar_ratio:front:tip",
        "data:geometry:wing:spar_ratio:rear:root",
        "data:geometry:wing:spar_ratio:rear:kink",
        "data:geometry:wing:spar_ratio:rear:tip",
        "data:geometry:wing:MAC:length",
        "data:geometry:wing:MAC:leading_edge:x:local",
        "data:geometry:wing:root:chord",
        "data:geometry:wing:kink:chord",
        "data:geometry:wing:tip:chord",
        "data:geometry:wing:root:y",
        "data:geometry:wing:kink:leading_edge:x:local",
        "data:geometry:wing:kink:y",
        "data:geometry:wing:tip:y",
        "data:geometry:wing:tip:leading_edge:x:local",
        "data:geometry:wing:MAC:at25percent:x",
        "data:geometry:fuselage:maximum_width",
    ]

    input_vars = input_xml.read(only=input_list).to_ivc()

    problem = run_system(ComputeTanksCG(), input_vars)

    x_cg_tank = problem["data:weight:fuel_tank:CG:x"]
    assert x_cg_tank == pytest.approx(16.12, abs=1e-2)
예제 #26
0
def test_compute_ht_area(input_xml):
    """Tests computation of the horizontal tail area"""

    input_list = [
        "data:geometry:has_T_tail",
        "data:geometry:fuselage:length",
        "data:geometry:wing:MAC:at25percent:x",
        "data:geometry:wing:MAC:length",
        "data:geometry:wing:area",
        "data:weight:airframe:landing_gear:main:CG:x",
        "data:weight:airframe:landing_gear:front:CG:x",
        "data:weight:aircraft:MTOW",
        "settings:weight:aircraft:CG:range",
    ]

    input_vars = input_xml.read(only=input_list).to_ivc()
    problem = run_system(ComputeHTArea(), input_vars)

    ht_lp = problem[
        "data:geometry:horizontal_tail:MAC:at25percent:x:from_wingMAC25"]
    assert ht_lp == pytest.approx(17.68, abs=1e-2)
    wet_area = problem["data:geometry:horizontal_tail:wetted_area"]
    assert wet_area == pytest.approx(70.31, abs=1e-2)
    ht_area = problem["data:geometry:horizontal_tail:area"]
    assert ht_area == pytest.approx(35.15, abs=1e-2)
예제 #27
0
def test_wing_nodes():
    """ Test Aerodynamic wing nodes mesh generation """
    input_list = [
        "data:geometry:wing:MAC:length",
        "data:geometry:wing:MAC:leading_edge:x:local",
        "data:geometry:wing:MAC:at25percent:x",
        "data:geometry:wing:root:y",
        "data:geometry:wing:root:z",
        "data:geometry:wing:kink:leading_edge:x:local",
        "data:geometry:wing:kink:y",
        "data:geometry:wing:kink:z",
        "data:geometry:wing:tip:leading_edge:x:local",
        "data:geometry:wing:tip:y",
        "data:geometry:wing:tip:z",
    ]

    ivc = get_indep_var_comp(input_list)
    component = AerodynamicNodesWing(number_of_sections=12)
    problem = run_system(component, ivc)
    nodes = problem["data:aerostructural:aerodynamic:wing:nodes"]

    assert nodes[0, 0] == approx(12.83803, abs=1e-5)
    assert nodes[12, 0] == approx(20.81736, abs=1e-5)
    assert (nodes[1, 1] - nodes[0, 1]) == approx(1.95994, abs=1e-5)
    assert (nodes[5, 1] - nodes[4, 1]) == approx(1.31764, abs=1e-5)
예제 #28
0
def test_structure_htail_nodes():
    input_list = [
        "data:geometry:wing:MAC:at25percent:x",
        "data:geometry:horizontal_tail:MAC:at25percent:x:local",
        "data:geometry:horizontal_tail:MAC:at25percent:x:from_wingMAC25",
        "data:geometry:horizontal_tail:MAC:length",
        "data:geometry:horizontal_tail:span",
        "data:geometry:horizontal_tail:sweep_0",
        "data:geometry:horizontal_tail:root:z",
        "data:geometry:horizontal_tail:tip:z",
        "data:geometry:horizontal_tail:root:chord",
        "data:geometry:horizontal_tail:tip:chord",
    ]
    ivc = get_indep_var_comp(input_list)
    problem = run_system(StructureNodesHtail(number_of_sections=4), ivc)
    assert problem[
        "data:aerostructural:structure:horizontal_tail:nodes"][:5,
                                                               1] == approx(
                                                                   np.array([
                                                                       0.0,
                                                                       1.5349,
                                                                       3.06980,
                                                                       4.6047,
                                                                       6.1396
                                                                   ]),
                                                                   abs=1e-5)
    assert problem["data:aerostructural:structure:horizontal_tail:nodes"][
        5:, 1] == approx(np.array([-0.0, -1.5349, -3.06980, -4.6047, -6.1396]),
                         abs=1e-5)
    assert problem[
        "data:aerostructural:structure:horizontal_tail:nodes"][:5, 0] == approx(
            np.array([34.59222, 35.21558, 35.83895, 36.46232, 37.08568]),
            abs=1e-5)
예제 #29
0
def test_compute_cg_loadcases(input_xml):
    """Tests computation of center of gravity for load case 2"""

    input_list = [
        "data:geometry:wing:MAC:length",
        "data:geometry:wing:MAC:at25percent:x",
        "data:weight:payload:PAX:CG:x",
        "data:weight:payload:rear_fret:CG:x",
        "data:weight:payload:front_fret:CG:x",
        "data:TLAR:NPAX",
        "data:weight:aircraft:MFW",
        "data:weight:fuel_tank:CG:x",
    ]

    input_vars = input_xml.read(only=input_list).to_ivc()

    input_vars.add_output("data:weight:aircraft_empty:CG:x",
                          699570.01 / 40979.11)
    input_vars.add_output("data:weight:aircraft_empty:mass", 40979.11)

    # Testing each load case independently -------------
    classes = [
        ComputeCGLoadCase1, ComputeCGLoadCase2, ComputeCGLoadCase3,
        ComputeCGLoadCase4
    ]
    cg_ratio_lc = [
        0.0
    ]  # dummy first item to ensure cg_ratio_lc[i] is for load case i
    for i, cg_class in enumerate(classes):
        problem = run_system(cg_class(), input_vars)
        cg_ratio_lc.append(
            problem[f"data:weight:aircraft:load_case_{i+1}:CG:MAC_position"])

    assert cg_ratio_lc[1] == pytest.approx(0.364907, abs=1e-6)
    assert cg_ratio_lc[2] == pytest.approx(0.285139, abs=1e-6)
    assert cg_ratio_lc[3] == pytest.approx(0.386260, abs=1e-6)
    assert cg_ratio_lc[4] == pytest.approx(0.388971, abs=1e-6)

    # Testing the aggregated load cases -------------
    problem = run_system(CGRatiosForLoadCases(), input_vars)
    cg_ratios = problem["data:weight:aircraft:load_cases:CG:MAC_position"]
    max_cg_ratios = problem[
        "data:weight:aircraft:load_cases:CG:MAC_position:maximum"]

    assert cg_ratios == pytest.approx([0.364907, 0.285139, 0.386260, 0.388971],
                                      abs=1e-6)
    assert max_cg_ratios == pytest.approx(0.388971, abs=1e-6)
예제 #30
0
def test_polar_low_speed():
    """Tests ComputePolar"""

    # Need to plug Cd modules, Reynolds and Oswald

    input_list = [
        "data:aerodynamics:aircraft:takeoff:mach",
        "data:geometry:wing:area",
        "data:geometry:wing:span",
        "data:geometry:fuselage:maximum_height",
        "data:geometry:fuselage:maximum_width",
        "data:geometry:wing:root:chord",
        "data:geometry:wing:tip:chord",
        "data:geometry:wing:sweep_25",
        "data:geometry:wing:thickness_ratio",
        "data:geometry:wing:wetted_area",
        "data:geometry:wing:MAC:length",
        "data:geometry:fuselage:length",
        "data:geometry:fuselage:wetted_area",
        "data:geometry:horizontal_tail:MAC:length",
        "data:geometry:horizontal_tail:thickness_ratio",
        "data:geometry:horizontal_tail:sweep_25",
        "data:geometry:horizontal_tail:wetted_area",
        "data:geometry:vertical_tail:MAC:length",
        "data:geometry:vertical_tail:thickness_ratio",
        "data:geometry:vertical_tail:sweep_25",
        "data:geometry:vertical_tail:wetted_area",
        "data:geometry:propulsion:pylon:length",
        "data:geometry:propulsion:nacelle:length",
        "data:geometry:propulsion:pylon:wetted_area",
        "data:geometry:propulsion:nacelle:wetted_area",
        "data:geometry:propulsion:engine:count",
        "data:geometry:propulsion:fan:length",
        "data:geometry:aircraft:wetted_area",
        "tuning:aerodynamics:aircraft:cruise:CD:k",
        "tuning:aerodynamics:aircraft:cruise:CD:offset",
        "tuning:aerodynamics:aircraft:cruise:CD:winglet_effect:k",
        "tuning:aerodynamics:aircraft:cruise:CD:winglet_effect:offset",
    ]
    group = Group()
    group.add_subsystem("reynolds", ComputeReynolds(low_speed_aero=True), promotes=["*"])
    group.add_subsystem("oswald", OswaldCoefficient(low_speed_aero=True), promotes=["*"])
    group.add_subsystem(
        "induced_drag_coeff", InducedDragCoefficient(low_speed_aero=True), promotes=["*"]
    )
    group.add_subsystem("cd0", CD0(low_speed_aero=True), promotes=["*"])
    group.add_subsystem("cd_trim", CdTrim(low_speed_aero=True), promotes=["*"])
    group.add_subsystem("polar", ComputePolar(polar_type=PolarType.LOW_SPEED), promotes=["*"])

    ivc = get_indep_var_comp(input_list)
    ivc.add_output("data:aerodynamics:aircraft:low_speed:CL", np.arange(0.0, 1.5, 0.01))

    problem = run_system(group, ivc)

    cd = problem["data:aerodynamics:aircraft:low_speed:CD"]
    cl = problem["data:aerodynamics:aircraft:low_speed:CL"]

    assert cd[cl == 0.5] == approx(0.033441, abs=1e-5)
    assert cd[cl == 1.0] == approx(0.077523, abs=1e-5)