def test_report_generation_user_defined_report(self): setup_default_reports() # So it sees the OPENMDAO_REPORTS var user_report_filename = 'user_report.txt' # @report_function(user_report_filename) @report_function() def user_defined_report(prob, report_filepath): with open(report_filepath, "w") as f: f.write(f"Do some reporting on the Problem, {prob._name}\n") # register_report("User defined report", user_defined_report, # "user defined report description", # 'Problem', 'setup', 'pre') register_report("User defined report", user_defined_report, "user defined report description", 'Problem', 'setup', 'pre', user_report_filename) prob = self.setup_and_run_simple_problem() problem_reports_dir = pathlib.Path(_reports_dir).joinpath(prob._name) path = pathlib.Path(problem_reports_dir).joinpath(user_report_filename) self.assertTrue( path.is_file(), f'The user defined report file, {str(path)} was not found')
def test_reports_system_mpi_basic( self): # example taken from TestScipyOptimizeDriverMPI setup_default_reports() prob = om.Problem() prob.model = SellarMDA() prob.driver = om.ScipyOptimizeDriver(optimizer='SLSQP', tol=1e-8) prob.model.add_design_var('x', lower=0, upper=10) prob.model.add_design_var('z', lower=0, upper=10) prob.model.add_objective('obj') prob.model.add_constraint('con1', upper=0) prob.model.add_constraint('con2', upper=0) prob.setup() prob.set_solver_print(level=0) prob.run_driver() # get the path to the problem subdirectory problem_reports_dir = pathlib.Path(_reports_dir).joinpath(prob._name) path = pathlib.Path(problem_reports_dir).joinpath(self.n2_filename) self.assertTrue(path.is_file(), f'The N2 report file, {str(path)} was not found') path = pathlib.Path(problem_reports_dir).joinpath( self.scaling_filename) self.assertTrue( path.is_file(), f'The scaling report file, {str(path)}, was not found')
def test_report_generation_multiple_problems(self): setup_default_reports() # So it sees the OPENMDAO_REPORTS var probname, subprobname = self.setup_and_run_model_with_subproblem() # The multiple problem code only runs model so no scaling reports to look for for problem_name in [probname, subprobname]: problem_reports_dir = pathlib.Path(_reports_dir).joinpath( f'{problem_name}') path = pathlib.Path(problem_reports_dir).joinpath(self.n2_filename) self.assertTrue(path.is_file(), f'N2 report file, {str(path)} was not found')
def test_report_generation_basic_problem_reports_argument_n2_and_scaling( self): setup_default_reports() prob = self.setup_and_run_simple_problem(reports='n2,scaling') # get the path to the problem subdirectory problem_reports_dir = pathlib.Path(_reports_dir).joinpath(prob._name) path = pathlib.Path(problem_reports_dir).joinpath(self.n2_filename) self.assertTrue(path.is_file(), f'The N2 report file, {str(path)} was not found') path = pathlib.Path(problem_reports_dir).joinpath( self.scaling_filename) self.assertTrue(path.is_file(), f'The scaling report file, {str(path)} was not found')
def test_report_generation_basic_problem_reports_argument_false(self): setup_default_reports() prob = self.setup_and_run_simple_problem(reports=False) # get the path to the problem subdirectory problem_reports_dir = pathlib.Path(_reports_dir).joinpath(prob._name) path = pathlib.Path(problem_reports_dir).joinpath(self.n2_filename) self.assertFalse( path.is_file(), f'The N2 report file, {str(path)} was found but should not have') path = pathlib.Path(problem_reports_dir).joinpath( self.scaling_filename) self.assertFalse( path.is_file(), f'The scaling report file, {str(path)}, was found but should not have' )
def test_report_generation_basic_pyoptsparse(self): # Just to try a different driver setup_default_reports() prob = self.setup_and_run_simple_problem(driver=pyOptSparseDriver( optimizer='SLSQP')) # get the path to the problem subdirectory problem_reports_dir = pathlib.Path(_reports_dir).joinpath(prob._name) path = pathlib.Path(problem_reports_dir).joinpath(self.n2_filename) self.assertTrue(path.is_file(), f'The N2 report file, {str(path)} was not found') path = pathlib.Path(problem_reports_dir).joinpath( self.scaling_filename) self.assertTrue( path.is_file(), f'The scaling report file, {str(path)}, was not found')
def test_report_generation_list_reports(self): setup_default_reports() # So it sees the OPENMDAO_REPORTS var stdout = sys.stdout strout = StringIO() sys.stdout = strout try: list_reports() finally: sys.stdout = stdout output = strout.getvalue() self.assertTrue( 'N2 diagram' in output, '"N2 diagram" expected in list_reports output but was not found') self.assertTrue( 'Driver scaling report' in output, '"Driver scaling report" expected in list_reports output but was not found' )
def test_report_generation_basic_doedriver(self): # Test a driver that does not generate scaling report setup_default_reports() prob = self.setup_and_run_simple_problem( driver=om.DOEDriver(om.PlackettBurmanGenerator())) problem_reports_dir = pathlib.Path(_reports_dir).joinpath(prob._name) path = pathlib.Path(problem_reports_dir).joinpath(self.n2_filename) self.assertTrue(path.is_file(), f'The N2 report file, {str(path)} was not found') # DOEDriver won't cause the creation of a scaling report path = pathlib.Path(problem_reports_dir).joinpath( self.scaling_filename) self.assertFalse( path.is_file(), f'The scaling report file, {str(path)}, was found but should not have' )
def test_report_generation_set_reports_dir_using_env_var(self): setup_default_reports() # So it sees the OPENMDAO_REPORTS var # test use of setting a custom reports directory other than the default of "." custom_dir = 'custom_reports_dir' os.environ['OPENMDAO_REPORTS_DIR'] = custom_dir prob = self.setup_and_run_simple_problem() # See if the report files exist and if they have the right names reports_dir = custom_dir problem_reports_dir = pathlib.Path(reports_dir).joinpath(prob._name) path = pathlib.Path(problem_reports_dir).joinpath(self.n2_filename) self.assertTrue(path.is_file(), f'The N2 report file, {str(path)} was not found') path = pathlib.Path(problem_reports_dir).joinpath( self.scaling_filename) self.assertTrue( path.is_file(), f'The scaling report file, {str(path)}, was not found')
def test_report_generation_selected_reports_using_env_var(self): # test use of the OPENMDAO_REPORTS variable to turn off selected reports os.environ['OPENMDAO_REPORTS'] = 'n2' clear_reports() setup_default_reports() # So it sees the OPENMDAO_REPORTS var prob = self.setup_and_run_simple_problem() # See if the report files exist and if they have the right names problem_reports_dir = pathlib.Path(_reports_dir).joinpath(prob._name) path = pathlib.Path(problem_reports_dir).joinpath(self.n2_filename) self.assertTrue(path.is_file(), f'The N2 report file, {str(path)} was not found') path = pathlib.Path(problem_reports_dir).joinpath( self.scaling_filename) self.assertFalse( path.is_file(), f'The scaling report file, {str(path)}, was found but should not have' )
def test_report_generation_test_TESTFLO_RUNNING(self): # need to do this here again even though it is done in setup, because otherwise # setup_default_reports won't see environment variable, TESTFLO_RUNNING os.environ['TESTFLO_RUNNING'] = 'true' clear_reports() setup_default_reports() prob = self.setup_and_run_simple_problem() problem_reports_dir = pathlib.Path(_reports_dir).joinpath(prob._name) path = pathlib.Path(problem_reports_dir).joinpath(self.n2_filename) self.assertFalse( path.is_file(), f'The N2 report file, {str(path)} was found but should not have') path = pathlib.Path(problem_reports_dir).joinpath( self.scaling_filename) self.assertFalse( path.is_file(), f'The scaling report file, {str(path)}, was found but should not have' )
def test_report_generation_various_locations(self): # the reports can be generated pre and post for setup, final_setup, and run_driver # check those all work setup_default_reports() # So it sees the OPENMDAO_REPORTS var self.count = 0 # A simple report user_report_filename = 'user_defined_{count}.txt' # @report_function(user_report_filename) @report_function() def user_defined_report(prob, report_filepath): report_filepath = report_filepath.format(count=self.count) with open(report_filepath, "w") as f: f.write(f"Do some reporting on the Problem, {prob._name}\n") self.count += 1 for method in ['setup', 'final_setup', 'run_driver']: for pre_or_post in ['pre', 'post']: register_report(f"User defined report {method} {pre_or_post}", user_defined_report, "user defined report", 'Problem', method, pre_or_post, user_report_filename) prob = self.setup_and_run_simple_problem() problem_reports_dir = pathlib.Path(_reports_dir).joinpath(prob._name) self.count = 0 for _ in ['setup', 'final_setup', 'run_driver']: for _ in ['pre', 'post']: user_report_filename = f"user_defined_{self.count}.txt" path = pathlib.Path(problem_reports_dir).joinpath( user_report_filename) self.assertTrue( path.is_file(), f'The user defined report file, {str(path)} was not found') self.count += 1
def test_report_generation_problem_reports_argument_multiple_problems( self): setup_default_reports() _, _ = self.setup_and_run_model_with_subproblem(prob2_reports=None) # Only problem1 reports should have been generated # The multiple problem code only runs model so no scaling reports to look for problem_name = 'problem1' problem_reports_dir = pathlib.Path(_reports_dir).joinpath( f'{problem_name}') path = pathlib.Path(problem_reports_dir).joinpath(self.n2_filename) self.assertTrue( path.is_file(), f'The problem1 N2 report file, {str(path)} was not found') problem_name = 'problem2' problem_reports_dir = pathlib.Path(_reports_dir).joinpath( f'{problem_name}') path = pathlib.Path(problem_reports_dir).joinpath(self.n2_filename) self.assertFalse( path.is_file(), f'The problem2 n2 report file, {str(path)}, was found but should not have' )
def test_no_sim_reports(self): setup_default_reports() p = om.Problem(model=om.Group()) p.driver = om.ScipyOptimizeDriver() p.driver.declare_coloring(tol=1.0E-12) t = dm.Radau(num_segments=10, order=3) traj = dm.Trajectory() phase = dm.Phase(ode_class=BrachistochroneODE, transcription=t) p.model.add_subsystem('traj0', traj) traj.add_phase('phase0', phase) # p.model.add_subsystem('traj0', traj) phase.set_time_options(fix_initial=True, duration_bounds=(.5, 10)) phase.add_state('x', fix_initial=True, fix_final=False) phase.add_state('y', fix_initial=True, fix_final=False) # Note that by omitting the targets here Dymos will automatically attempt to connect # to a top-level input named 'v' in the ODE, and connect to nothing if it's not found. phase.add_state('v', fix_initial=True, fix_final=False) phase.add_control('theta', continuity=True, rate_continuity=True, units='deg', lower=0.01, upper=179.9) phase.add_parameter('g', targets=['g'], units='m/s**2') phase.add_boundary_constraint('x', loc='final', equals=10) phase.add_boundary_constraint('y', loc='final', equals=5) # Minimize time at the end of the phase phase.add_objective('time_phase', loc='final', scaler=10) p.setup() phase.set_simulate_options(method='RK23') p['traj0.phase0.t_initial'] = 0.0 p['traj0.phase0.t_duration'] = 2.0 p['traj0.phase0.states:x'] = phase.interp('x', [0, 10]) p['traj0.phase0.states:y'] = phase.interp('y', [10, 5]) p['traj0.phase0.states:v'] = phase.interp('v', [0, 9.9]) p['traj0.phase0.controls:theta'] = phase.interp('theta', [5, 100]) p['traj0.phase0.parameters:g'] = 9.80665 dm.run_problem(p, run_driver=True, simulate=True) problem_reports_dir = pathlib.Path(_reports_dir).joinpath(p._name) report_subdirs = [ e for e in pathlib.Path(_reports_dir).iterdir() if e.is_dir() ] # Test that a report subdir was made self.assertEqual(len(report_subdirs), 1) path = pathlib.Path(problem_reports_dir).joinpath(self.n2_filename) self.assertTrue(path.is_file(), f'The N2 report file, {str(path)} was not found') path = pathlib.Path(problem_reports_dir).joinpath( self.scaling_filename) self.assertTrue( path.is_file(), f'The scaling report file, {str(path)}, was not found')
def test_explicitshooting_make_subprob_reports(self): setup_default_reports() prob = om.Problem() prob.driver = om.ScipyOptimizeDriver() prob.driver.declare_coloring(tol=1.0E-12) tx = dm.ExplicitShooting(num_segments=3, grid='gauss-lobatto', method='rk4', order=5, num_steps_per_segment=5, compressed=False, subprob_reports=True) phase = dm.Phase(ode_class=BrachistochroneODE, transcription=tx) phase.set_time_options(units='s', fix_initial=True, duration_bounds=(1.0, 10.0)) # automatically discover states phase.set_state_options('x', fix_initial=True) phase.set_state_options('y', fix_initial=True) phase.set_state_options('v', fix_initial=True) phase.add_parameter('g', val=1.0, units='m/s**2', opt=True, lower=1, upper=9.80665) phase.add_control('theta', val=45.0, units='deg', opt=True, lower=1.0E-6, upper=179.9, ref=90., rate2_continuity=True) phase.add_boundary_constraint('x', loc='final', equals=10.0) phase.add_boundary_constraint('y', loc='final', equals=5.0) prob.model.add_subsystem('phase0', phase) phase.add_objective('time', loc='final') prob.setup(force_alloc_complex=True) prob.set_val('phase0.t_initial', 0.0) prob.set_val('phase0.t_duration', 2) prob.set_val('phase0.states:x', 0.0) prob.set_val('phase0.states:y', 10.0) prob.set_val('phase0.states:v', 1.0E-6) prob.set_val('phase0.parameters:g', 1.0, units='m/s**2') prob.set_val('phase0.controls:theta', phase.interp('theta', ys=[0.01, 90]), units='deg') dm.run_problem(prob, run_driver=True, simulate=False) problem_reports_dir = pathlib.Path(_reports_dir).joinpath(prob._name) report_subdirs = [ e for e in pathlib.Path(_reports_dir).iterdir() if e.is_dir() ] # Test that a report subdir was made # There is the nominal problem, a subproblem for integration, and a subproblem for the derivatives. self.assertEqual(len(report_subdirs), 3) path = pathlib.Path(problem_reports_dir).joinpath(self.n2_filename) self.assertTrue(path.is_file(), f'The N2 report file, {str(path)} was not found') path = pathlib.Path(problem_reports_dir).joinpath( self.scaling_filename) self.assertTrue( path.is_file(), f'The scaling report file, {str(path)}, was not found') for subdir in report_subdirs: path = pathlib.Path(subdir).joinpath(self.n2_filename) self.assertTrue(path.is_file(), f'The N2 report file, {str(path)} was not found')