def test_oad_process(cleanup): """ Test for the overall aircraft design process. """ configurator = FASTOADProblemConfigurator(pth.join(DATA_FOLDER_PATH, "oad_process.yml")) # Create inputs ref_inputs = pth.join(DATA_FOLDER_PATH, "CeRAS01_legacy.xml") configurator.write_needed_inputs(ref_inputs) # Create problems with inputs problem = configurator.get_problem(read_inputs=True) problem.setup() problem.run_model() problem.write_outputs() if not pth.exists(RESULTS_FOLDER_PATH): os.mkdir(RESULTS_FOLDER_PATH) om.view_connections( problem, outfile=pth.join(RESULTS_FOLDER_PATH, "connections.html"), show_browser=False ) om.n2(problem, outfile=pth.join(RESULTS_FOLDER_PATH, "n2.html"), show_browser=False) # Check that weight-performances loop correctly converged _check_weight_performance_loop(problem)
def test_oad_process(cleanup): """ Test for the overall aircraft design process. """ problem = FASTOADProblemConfigurator(pth.join(INPUT_FOLDER_PATH, "oad_process.toml")).get_problem() problem.model.aicraft.set_input_defaults('data:geometry:horizontal_tail:sweep_25', val=10., units='deg') ref_inputs = pth.join(INPUT_FOLDER_PATH, XML_NAME) get_problem_after_setup(problem).write_needed_inputs(ref_inputs, VariableXmlStandardFormatter()) problem.read_inputs() print('\n') problem.setup(check=True) problem.set_solver_print(level=2) with Timer(name="Mass-performance loop:"): problem.run_model() problem.write_outputs() if not pth.exists(RESULTS_FOLDER_PATH): os.mkdir(RESULTS_FOLDER_PATH) om.view_connections( problem, outfile=pth.join(RESULTS_FOLDER_PATH, "connections.html"), show_browser=False ) om.n2(problem, outfile=pth.join(RESULTS_FOLDER_PATH, "n2.html"), show_browser=False) # 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"], rtol=5e-2, ) assert_allclose( problem["data:weight:aircraft:MZFW"], problem["data:weight:aircraft:OWE"] + problem["data:weight:aircraft:max_payload"], rtol=5e-2, ) assert_allclose( problem["data:weight:aircraft:MTOW"], problem["data:weight:aircraft:OWE"] + problem["data:weight:aircraft:max_payload"] + problem["data:mission:sizing:fuel"], rtol=5e-2, ) assert_allclose(problem.get_val("data:mission:sizing:fuel", units="kg"), 203.65, atol=1) # noinspection PyTypeChecker assert_allclose(problem.get_val("data:weight:aircraft:max_payload", units="kg"), 400.0, atol=1) # noinspection PyTypeChecker assert_allclose(problem["data:handling_qualities:static_margin"], 0.08515, atol=1e-2) # noinspection PyTypeChecker assert_allclose(problem.get_val("data:weight:aircraft:MTOW", units="kg"), 1650.24, atol=1) # noinspection PyTypeChecker assert_allclose(problem.get_val("data:weight:aircraft:payload", units="kg"), 360., atol=1) # noinspection PyTypeChecker assert_allclose(problem.get_val("data:weight:aircraft:OWE", units="kg"), 1046.61, atol=1) # noinspection PyTypeChecker assert_allclose(problem.get_val("data:mission:sizing:main_route:cruise:fuel", units="kg"), 166.405, atol=1)
def test_feature_sellar(self): prob = om.Problem() prob.model = SellarNoDerivatives() prob.setup() prob.final_setup() om.view_connections(prob, outfile= "sellar_connections.html", show_browser=False)
def test_sellar(self): # Just tests Newton on Sellar with FD derivs. prob = Problem() prob.model = SellarNoDerivatives() prob.setup(check=False) prob.final_setup() # no output checking, just make sure no exceptions raised view_connections(prob, show_browser=False)
def test_discrete(self): p = om.Problem() ivc = p.model.add_subsystem('ivc', om.IndepVarComp(), promotes=['*']) ivc.add_discrete_output('foo', val='3') p.model.add_subsystem('test_comp', TestComp(), promotes=['*']) p.setup() om.view_connections(p, show_browser=False)
def test_no_setup_warning(self): prob = om.Problem() prob.model = SellarNoDerivatives() prob.setup() msg = "<model> <class SellarNoDerivatives>: Values will not be shown because final_setup has not been called yet." with assert_warning(om.OpenMDAOWarning, msg): om.view_connections(prob, outfile= "sellar_connections.html", show_values=True, show_browser=False)
def test_feature_sellar(self): import openmdao.api as om from openmdao.test_suite.components.sellar import SellarNoDerivatives prob = om.Problem() prob.model = SellarNoDerivatives() prob.setup() prob.final_setup() om.view_connections(prob, outfile="sellar_connections.html", show_browser=False)
def test_oad_process(cleanup): """ Test for the overall aircraft design process. """ configurator = FASTOADProblemConfigurator( pth.join(DATA_FOLDER_PATH, "oad_process.toml")) # Create inputs ref_inputs = pth.join(DATA_FOLDER_PATH, "CeRAS01_legacy.xml") configurator.write_needed_inputs(ref_inputs) # Create problems with inputs problem = configurator.get_problem(read_inputs=True) problem.setup() problem.run_model() problem.write_outputs() if not pth.exists(RESULTS_FOLDER_PATH): os.mkdir(RESULTS_FOLDER_PATH) om.view_connections(problem, outfile=pth.join(RESULTS_FOLDER_PATH, "connections.html"), show_browser=False) om.n2(problem, outfile=pth.join(RESULTS_FOLDER_PATH, "n2.html"), show_browser=False) # 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, )
def test_oad_process(cleanup): """ Test for the overall aircraft design process. """ problem = FASTOADProblemConfigurator( pth.join(DATA_FOLDER_PATH, "oad_process.toml")).get_problem() ref_inputs = pth.join(DATA_FOLDER_PATH, "beechcraft_76.xml") get_problem_after_setup(problem).write_needed_inputs( ref_inputs, VariableXmlStandardFormatter()) problem.read_inputs() print('\n') problem.setup(check=True) problem.set_solver_print(level=2) problem.run_model() problem.write_outputs() if not pth.exists(RESULTS_FOLDER_PATH): os.mkdir(RESULTS_FOLDER_PATH) om.view_connections(problem, outfile=pth.join(RESULTS_FOLDER_PATH, "connections.html"), show_browser=False) om.n2(problem, outfile=pth.join(RESULTS_FOLDER_PATH, "n2.html"), show_browser=False) # 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"], rtol=5e-2, ) assert_allclose( problem["data:weight:aircraft:MZFW"], problem["data:weight:aircraft:OWE"] + problem["data:weight:aircraft:max_payload"], rtol=5e-2, ) assert_allclose( problem["data:weight:aircraft:MTOW"], problem["data:weight:aircraft:OWE"] + problem["data:weight:aircraft:max_payload"] + problem["data:mission:sizing:fuel"], rtol=5e-2, )
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)
p['phase.t_initial'] = 0.0 p['phase.t_duration'] = 10. for cell in np.arange(cells): p['phase.states:T_cell_{}'.format(cell)] = phase.interpolate( ys=[293.15, 333.15], nodes='state_input') p['phase.states:T_cell_1'] = phase.interpolate(ys=[373.15, 333.15], nodes='state_input') p.run_driver() p.model.list_inputs(prom_name=True) p.model.list_outputs(prom_name=True) time_opt = p.get_val('phase.timeseries.time', units='s') om.view_connections(p) om.n2(p) for j in np.arange(cells): T_cell = p.get_val('phase.timeseries.states:T_cell_{}'.format(j), units='K') plt.plot(time_opt, T_cell, label='cell {}'.format(j)) plt.xlabel('time, s') plt.ylabel('T_cell, K') plt.legend() plt.show()
def test_oad_process(cleanup): """ Test the overall aircraft design process without and with optimization. """ test = FASTOADProblemConfigurator( pth.join(INPUT_FOLDER_PATH, "oad_process.toml")) problem = FASTOADProblemConfigurator( pth.join(INPUT_FOLDER_PATH, "oad_process.toml")).get_problem() recorder = om.SqliteRecorder("cases.sql") ref_inputs = pth.join(INPUT_FOLDER_PATH, XML_NAME) get_problem_after_setup(problem).write_needed_inputs( ref_inputs, VariableXmlStandardFormatter()) problem.read_inputs() print('\n') problem.setup(check=True) solver = problem.model.nonlinear_solver solver.add_recorder(recorder) problem.run_model() problem.write_outputs() if not pth.exists(RESULTS_FOLDER_PATH): os.mkdir(RESULTS_FOLDER_PATH) om.view_connections(problem, outfile=pth.join(RESULTS_FOLDER_PATH, "connections.html"), show_browser=False) om.n2(problem, outfile=pth.join(RESULTS_FOLDER_PATH, "n2.html"), show_browser=False) # 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"], rtol=5e-2, ) assert_allclose( problem["data:weight:aircraft:MZFW"], problem["data:weight:aircraft:OWE"] + problem["data:weight:aircraft:max_payload"], rtol=5e-2, ) assert_allclose( problem["data:weight:aircraft:MTOW"], problem["data:weight:aircraft:OWE"] + problem["data:weight:aircraft:payload"] + problem["data:mission:sizing:fuel"], rtol=5e-2, ) if XML_NAME == "cirrus_sr22.xml": assert_allclose(problem.get_val("data:mission:sizing:fuel", units="kg"), 258.831, atol=1) # noinspection PyTypeChecker assert_allclose( problem["data:handling_qualities:stick_fixed_static_margin"], 0.0728, atol=1e-2) # noinspection PyTypeChecker assert_allclose(problem.get_val("data:weight:aircraft:MTOW", units="kg"), 1629.7406025, atol=1) # noinspection PyTypeChecker assert_allclose(problem.get_val("data:weight:aircraft:OWE", units="kg"), 1030.9167, atol=1) else: assert_allclose(problem.get_val("data:mission:sizing:fuel", units="kg"), 228.624, atol=1) # noinspection PyTypeChecker assert_allclose( problem["data:handling_qualities:stick_fixed_static_margin"], 0.0252, atol=1e-2) # noinspection PyTypeChecker assert_allclose(problem.get_val("data:weight:aircraft:MTOW", units="kg"), 1678.863295, atol=1) # noinspection PyTypeChecker assert_allclose(problem.get_val("data:weight:aircraft:OWE", units="kg"), 1090.2524, atol=1)
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)
def run_non_regression_test( conf_file, legacy_result_file, result_dir, use_xfoil=False, global_tolerance=1e-2, vars_to_check=None, specific_tolerance=5.0e-3, check_weight_perfo_loop=True, ): """ Convenience function for non regression tests :param conf_file: FAST-OAD configuration file :param legacy_result_file: reference data for inputs and outputs :param result_dir: relative name, folder will be in RESULTS_FOLDER_PATH :param use_xfoil: if True, XFOIL computation will be activated :param vars_to_check: variables that will be concerned by specific_tolerance :param specific_tolerance: test will fail if absolute relative error between computed and reference values is beyond this value for variables in vars_to_check :param global_tolerance: test will fail if absolute relative error between computed and reference values is beyond this value for ANY variable :param check_weight_perfo_loop: if True, consistency of weights will be checked """ 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_weight_performance_loop(problem) ref_data = DataFile(pth.join(DATA_FOLDER_PATH, legacy_result_file)) row_list = [] for ref_var in ref_data: 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: assert_allclose(df.ref_value, df.value, rtol=global_tolerance) row = df.loc[df.name == name] assert_allclose(row.ref_value, row.value, rtol=specific_tolerance) else: assert np.all(df.abs_rel_delta < specific_tolerance)