def test_api_eval(cleanup):
    results_folder_path = pth.join(RESULTS_FOLDER_PATH, "api_eval")
    configuration_file_path = pth.join(results_folder_path, "oad_process.toml")

    # Generation of configuration file ----------------------------------------
    api.generate_configuration_file(configuration_file_path, True)

    # Generation of inputs ----------------------------------------------------
    # We get the same inputs as in tutorial notebook
    source_xml = pth.join(root_folder_path, "src", "fastoad", "notebooks",
                          "tutorial", "data", "CeRAS01_baseline.xml")
    api.generate_inputs(configuration_file_path, source_xml, overwrite=True)

    # Run model ---------------------------------------------------------------
    problem = api.evaluate_problem(configuration_file_path, True)

    # Check that weight-performances loop correctly converged
    assert_allclose(
        problem["data:weight:aircraft:OWE"],
        problem["data:weight:airframe:mass"] +
        problem["data:weight:propulsion:mass"] +
        problem["data:weight:systems:mass"] +
        problem["data:weight:furniture:mass"] +
        problem["data:weight:crew:mass"],
        atol=1,
    )
    assert_allclose(
        problem["data:weight:aircraft:MZFW"],
        problem["data:weight:aircraft:OWE"] +
        problem["data:weight:aircraft:max_payload"],
        atol=1,
    )
    assert_allclose(
        problem["data:weight:aircraft:MTOW"],
        problem["data:weight:aircraft:OWE"] +
        problem["data:weight:aircraft:payload"] +
        problem["data:mission:sizing:needed_block_fuel"],
        atol=1,
    )

    assert_allclose(problem["data:handling_qualities:static_margin"],
                    -0.071146,
                    atol=1e-3)
    assert_allclose(problem["data:geometry:wing:MAC:at25percent:x"],
                    16.0,
                    atol=1e-2)
    assert_allclose(problem["data:weight:aircraft:MTOW"], 76796, atol=1)
    assert_allclose(problem["data:geometry:wing:area"], 131.26, atol=1e-2)
    assert_allclose(problem["data:geometry:vertical_tail:area"],
                    27.49,
                    atol=1e-2)
    assert_allclose(problem["data:geometry:horizontal_tail:area"],
                    33.99,
                    atol=1e-2)
    assert_allclose(problem["data:mission:sizing:needed_block_fuel"],
                    20708,
                    atol=1)
def test_api_optim(cleanup):
    results_folder_path = pth.join(RESULTS_FOLDER_PATH, "api_optim")
    configuration_file_path = pth.join(results_folder_path, "oad_process.toml")

    # Generation of configuration file ----------------------------------------
    api.generate_configuration_file(configuration_file_path, True)

    # Generation of inputs ----------------------------------------------------
    # We get the same inputs as in tutorial notebook
    source_xml = pth.join(root_folder_path, "src", "fastoad", "notebooks",
                          "tutorial", "data", "CeRAS01_baseline.xml")
    api.generate_inputs(configuration_file_path, source_xml, overwrite=True)

    # Run optim ---------------------------------------------------------------
    problem = api.optimize_problem(configuration_file_path, True)
    assert not problem.optim_failed

    # Check that weight-performances loop correctly converged
    assert_allclose(
        problem["data:weight:aircraft:OWE"],
        problem["data:weight:airframe:mass"] +
        problem["data:weight:propulsion:mass"] +
        problem["data:weight:systems:mass"] +
        problem["data:weight:furniture:mass"] +
        problem["data:weight:crew:mass"],
        atol=1,
    )
    assert_allclose(
        problem["data:weight:aircraft:MZFW"],
        problem["data:weight:aircraft:OWE"] +
        problem["data:weight:aircraft:max_payload"],
        atol=1,
    )
    assert_allclose(
        problem["data:weight:aircraft:MTOW"],
        problem["data:weight:aircraft:OWE"] +
        problem["data:weight:aircraft:payload"] +
        problem["data:mission:sizing:needed_block_fuel"],
        atol=1,
    )

    # Design Variable
    assert_allclose(problem["data:geometry:wing:MAC:at25percent:x"],
                    17.076,
                    atol=1e-3)

    # Constraint
    assert_allclose(problem["data:handling_qualities:static_margin"],
                    0.05,
                    rtol=1e-5)

    # Objective
    assert_allclose(problem["data:mission:sizing:needed_block_fuel"],
                    20837,
                    atol=1)
Exemple #3
0
class GenerateFiles:
    """
    Generate the configuration file
    """

    DATA_FOLDER_PATH = "data"

    WORK_FOLDER_PATH = "workdir"

    CONFIGURATION_FILE = pth.join(WORK_FOLDER_PATH, "oad_process.yml")
    SOURCE_FILE = pth.join(DATA_FOLDER_PATH, "CeRAS01_baseline.xml")

    # For having log messages on screen
    logging.basicConfig(level=logging.INFO, format="%(levelname)-8s: %(message)s")

    # For using all screen width
    from IPython.core.display import display, HTML

    display(HTML("<style>.container { width:95% !important; }</style>"))

    oad.generate_configuration_file(CONFIGURATION_FILE, overwrite=True)
Exemple #4
0
def run_non_regression_test(
    conf_file,
    legacy_result_file,
    result_dir,
    use_xfoil=False,
    vars_to_check=None,
    tolerance=5.0e-3,
    check_weight_perfo_loop=True,
):
    results_folder_path = pth.join(RESULTS_FOLDER_PATH, result_dir)
    configuration_file_path = pth.join(results_folder_path, conf_file)

    # Copy of configuration file and generation of problem instance ------------------
    api.generate_configuration_file(configuration_file_path)  # just ensure folders are created...
    shutil.copy(pth.join(DATA_FOLDER_PATH, conf_file), configuration_file_path)
    problem = FASTOADProblemConfigurator(configuration_file_path).get_problem()

    # Next trick is needed for overloading option setting from TOML file
    if use_xfoil and (system() == "Windows" or xfoil_path):
        problem.model.aerodynamics_landing._OPTIONS["use_xfoil"] = True
        if system() != "Windows":
            problem.model.aerodynamics_landing._OPTIONS["xfoil_exe_path"] = xfoil_path
        # BTW we narrow computed alpha range for sake of CPU time
        problem.model.aerodynamics_landing._OPTIONS["xfoil_alpha_min"] = 18.0
        problem.model.aerodynamics_landing._OPTIONS["xfoil_alpha_max"] = 22.0

    # Generation and reading of inputs ----------------------------------------
    ref_inputs = pth.join(DATA_FOLDER_PATH, legacy_result_file)
    get_problem_after_setup(problem).write_needed_inputs(ref_inputs, VariableLegacy1XmlFormatter())
    problem.read_inputs()
    problem.setup()

    # Run model ---------------------------------------------------------------
    problem.run_model()
    problem.write_outputs()

    om.view_connections(
        problem, outfile=pth.join(results_folder_path, "connections.html"), show_browser=False
    )

    if check_weight_perfo_loop:
        # Check that weight-performances loop correctly converged
        assert_allclose(
            problem["data:weight:aircraft:OWE"],
            problem["data:weight:airframe:mass"]
            + problem["data:weight:propulsion:mass"]
            + problem["data:weight:systems:mass"]
            + problem["data:weight:furniture:mass"]
            + problem["data:weight:crew:mass"],
            atol=1,
        )
        assert_allclose(
            problem["data:weight:aircraft:MZFW"],
            problem["data:weight:aircraft:OWE"] + problem["data:weight:aircraft:max_payload"],
            atol=1,
        )
        assert_allclose(
            problem["data:weight:aircraft:MTOW"],
            problem["data:weight:aircraft:OWE"]
            + problem["data:weight:aircraft:payload"]
            + problem["data:mission:sizing:fuel"],
            atol=1,
        )

    ref_var_list = VariableIO(
        pth.join(DATA_FOLDER_PATH, legacy_result_file), formatter=VariableLegacy1XmlFormatter(),
    ).read()

    row_list = []
    for ref_var in ref_var_list:
        try:
            value = problem.get_val(ref_var.name, units=ref_var.units)[0]
        except KeyError:
            continue
        row_list.append(
            {
                "name": ref_var.name,
                "units": ref_var.units,
                "ref_value": ref_var.value[0],
                "value": value,
            }
        )

    df = pd.DataFrame(row_list)
    df["rel_delta"] = (df.value - df.ref_value) / df.ref_value
    df["rel_delta"][(df.ref_value == 0) & (abs(df.value) <= 1e-10)] = 0.0
    df["abs_rel_delta"] = np.abs(df.rel_delta)

    pd.set_option("display.max_rows", None)
    pd.set_option("display.max_columns", None)
    pd.set_option("display.width", 1000)
    pd.set_option("display.max_colwidth", 120)
    print(df.sort_values(by=["abs_rel_delta"]))

    if vars_to_check is not None:
        for name in vars_to_check:
            row = df.loc[df.name == name]
            assert_allclose(row.ref_value, row.value, rtol=tolerance)
            # assert np.all(df.abs_rel_delta.loc[df.name == name] < tolerance)
    else:
        assert np.all(df.abs_rel_delta < tolerance)
def run_non_regression_test(
    conf_file,
    legacy_result_file,
    result_dir,
    use_xfoil=False,
    vars_to_check=None,
    tolerance=5.0e-3,
    check_weight_perfo_loop=True,
):
    results_folder_path = pth.join(RESULTS_FOLDER_PATH, result_dir)
    configuration_file_path = pth.join(results_folder_path, conf_file)

    # Copy of configuration file and generation of problem instance ------------------
    api.generate_configuration_file(
        configuration_file_path)  # just ensure folders are created...
    shutil.copy(pth.join(DATA_FOLDER_PATH, conf_file), configuration_file_path)
    configurator = FASTOADProblemConfigurator(configuration_file_path)
    configurator._set_configuration_modifier(XFOILConfigurator(use_xfoil))

    # Generation of inputs ----------------------------------------
    ref_inputs = pth.join(DATA_FOLDER_PATH, legacy_result_file)
    configurator.write_needed_inputs(ref_inputs)

    # Get problem with inputs -------------------------------------
    problem = configurator.get_problem(read_inputs=True)
    problem.setup()

    # Run model ---------------------------------------------------------------
    problem.run_model()
    problem.write_outputs()

    om.view_connections(problem,
                        outfile=pth.join(results_folder_path,
                                         "connections.html"),
                        show_browser=False)

    if check_weight_perfo_loop:
        # Check that weight-performances loop correctly converged
        assert_allclose(
            problem["data:weight:aircraft:OWE"],
            problem["data:weight:airframe:mass"] +
            problem["data:weight:propulsion:mass"] +
            problem["data:weight:systems:mass"] +
            problem["data:weight:furniture:mass"] +
            problem["data:weight:crew:mass"],
            atol=1,
        )
        assert_allclose(
            problem["data:weight:aircraft:MZFW"],
            problem["data:weight:aircraft:OWE"] +
            problem["data:weight:aircraft:max_payload"],
            atol=1,
        )
        assert_allclose(
            problem["data:weight:aircraft:MTOW"],
            problem["data:weight:aircraft:OWE"] +
            problem["data:weight:aircraft:payload"] +
            problem["data:mission:sizing:needed_block_fuel"],
            atol=1,
        )

    ref_var_list = VariableIO(pth.join(DATA_FOLDER_PATH,
                                       legacy_result_file), ).read()

    row_list = []
    for ref_var in ref_var_list:
        try:
            value = problem.get_val(ref_var.name, units=ref_var.units)[0]
        except KeyError:
            continue
        row_list.append({
            "name": ref_var.name,
            "units": ref_var.units,
            "ref_value": ref_var.value[0],
            "value": value,
        })

    df = pd.DataFrame(row_list)
    df["rel_delta"] = (df.value - df.ref_value) / df.ref_value
    df["rel_delta"][(df.ref_value == 0) & (abs(df.value) <= 1e-10)] = 0.0
    df["abs_rel_delta"] = np.abs(df.rel_delta)

    pd.set_option("display.max_rows", None)
    pd.set_option("display.max_columns", None)
    pd.set_option("display.width", 1000)
    pd.set_option("display.max_colwidth", 120)
    print(df.sort_values(by=["abs_rel_delta"]))

    if vars_to_check is not None:
        for name in vars_to_check:
            row = df.loc[df.name == name]
            assert_allclose(row.ref_value, row.value, rtol=tolerance)
            # assert np.all(df.abs_rel_delta.loc[df.name == name] < tolerance)
    else:
        assert np.all(df.abs_rel_delta < tolerance)