From 2f3f9fffc322a56c826e03936f06663fa373450a Mon Sep 17 00:00:00 2001 From: Kaushik Ponnapalli Date: Thu, 11 Aug 2022 10:28:43 -0500 Subject: [PATCH 1/4] added a warning if load case is called while fix_final is set to True --- dymos/load_case.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dymos/load_case.py b/dymos/load_case.py index 7db6f4ed6..c5df05bd2 100644 --- a/dymos/load_case.py +++ b/dymos/load_case.py @@ -2,6 +2,7 @@ from openmdao.recorders.case import Case from .phase.phase import Phase from .trajectory import Trajectory +from warnings import warn def find_phases(sys): @@ -149,6 +150,11 @@ def load_case(problem, previous_solution): if init_val_path: problem.set_val(init_val_path[0], prev_state_val[0, ...], units=prev_state_units) + if options['fix_final']: + warning_message = f"{state_name} specifies 'fix_final = True'. If the given restart file has a" \ + f" different final value this will overwrite the user-specified value" + warn(warning_message) + # Interpolate the timeseries control outputs from the previous solution onto the new grid. for control_name, options in phase.control_options.items(): control_path = [s for s in phase_vars if s.endswith(f'{phase_name}.controls:{control_name}')][0] From c509d05656045046e78057e70a1b4b6fd37911e8 Mon Sep 17 00:00:00 2001 From: Kaushik Ponnapalli Date: Thu, 11 Aug 2022 10:41:28 -0500 Subject: [PATCH 2/4] added test case --- dymos/test/test_load_case.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/dymos/test/test_load_case.py b/dymos/test/test_load_case.py index 53bb782da..4fe3cfbda 100644 --- a/dymos/test/test_load_case.py +++ b/dymos/test/test_load_case.py @@ -186,6 +186,32 @@ def test_load_case_radau_to_lgl(self): q.model.phase0.interp(xs=time_val, ys=theta_val, nodes='all'), tolerance=1.0E-2) + def test_load_case_warn_fix_final(self): + import openmdao.api as om + from openmdao.utils.assert_utils import assert_warnings + import dymos as dm + + p = setup_problem(dm.Radau(num_segments=20)) + + # Solve for the optimal trajectory + dm.run_problem(p) + + # Load the solution + case = om.CaseReader('dymos_solution.db').get_case('final') + + # create a problem with a different transcription with a different number of variables + q = setup_problem(dm.GaussLobatto(num_segments=50)) + + msgs = [] + + # Load the values from the previous solution + for state_name in ['x', 'y']: + msgs.append((UserWarning, f"{state_name} specifies 'fix_final = True'. If the given restart file has a" + f" different final value this will overwrite the user-specified value")) + print(msgs) + with assert_warnings(msgs): + dm.load_case(q, case) + if __name__ == '__main__': # pragma: no cover unittest.main() From 4d5811dab4ac74c2ef869ec8f7f29c53205fda2e Mon Sep 17 00:00:00 2001 From: Kaushik Ponnapalli Date: Thu, 11 Aug 2022 11:23:15 -0500 Subject: [PATCH 3/4] added similar warnings for controls and polynomial controls --- dymos/load_case.py | 13 +++++++- dymos/test/test_load_case.py | 65 +++++++++++++++++++++++++++++++----- 2 files changed, 68 insertions(+), 10 deletions(-) diff --git a/dymos/load_case.py b/dymos/load_case.py index c5df05bd2..f66521a19 100644 --- a/dymos/load_case.py +++ b/dymos/load_case.py @@ -151,7 +151,8 @@ def load_case(problem, previous_solution): problem.set_val(init_val_path[0], prev_state_val[0, ...], units=prev_state_units) if options['fix_final']: - warning_message = f"{state_name} specifies 'fix_final = True'. If the given restart file has a" \ + warning_message = f"{phase_name}.states:{state_name} specifies 'fix_final=True'. " \ + f"If the given restart file has a" \ f" different final value this will overwrite the user-specified value" warn(warning_message) @@ -166,6 +167,11 @@ def load_case(problem, previous_solution): phase.interp(xs=prev_time_val, ys=prev_control_val, nodes='control_input', kind='slinear'), units=prev_control_units) + if options['fix_final']: + warning_message = f"{phase_name}.controls:{control_name} specifies 'fix_final=True'. " \ + f"If the given restart file has a" \ + f" different final value this will overwrite the user-specified value" + warn(warning_message) # Set the output polynomial control outputs from the previous solution as the value for pc_name, options in phase.polynomial_control_options.items(): @@ -175,6 +181,11 @@ def load_case(problem, previous_solution): prev_pc_val = prev_vars[prev_pc_path]['val'] prev_pc_units = prev_vars[prev_pc_path]['units'] problem.set_val(pc_path, prev_pc_val, units=prev_pc_units) + if options['fix_final']: + warning_message = f"{phase_name}.polynomial_controls:{pc_name} specifies 'fix_final=True'. " \ + f"If the given restart file has a" \ + f" different final value this will overwrite the user-specified value" + warn(warning_message) # Set the timeseries parameter outputs from the previous solution as the parameter value for param_name, options in phase.parameter_options.items(): diff --git a/dymos/test/test_load_case.py b/dymos/test/test_load_case.py index 4fe3cfbda..c86dd3b45 100644 --- a/dymos/test/test_load_case.py +++ b/dymos/test/test_load_case.py @@ -8,7 +8,8 @@ om_version = tuple([int(s) for s in openmdao.__version__.split('-')[0].split('.')]) -def setup_problem(trans=dm.GaussLobatto(num_segments=10), polynomial_control=False): +def setup_problem(trans=dm.GaussLobatto(num_segments=10), polynomial_control=False, + fix_final_state=True, fix_final_control=False): from dymos.examples.brachistochrone.brachistochrone_ode import BrachistochroneODE p = om.Problem(model=om.Group()) @@ -20,15 +21,16 @@ def setup_problem(trans=dm.GaussLobatto(num_segments=10), polynomial_control=Fal phase.set_time_options(fix_initial=True, duration_bounds=(.5, 10)) - phase.add_state('x', fix_initial=True, fix_final=True) - phase.add_state('y', fix_initial=True, fix_final=True) + phase.add_state('x', fix_initial=True, fix_final=fix_final_state) + phase.add_state('y', fix_initial=True, fix_final=fix_final_state) phase.add_state('v', fix_initial=True) if not polynomial_control: phase.add_control('theta', units='deg', - rate_continuity=False, lower=0.01, upper=179.9) + rate_continuity=False, lower=0.01, upper=179.9, fix_final=fix_final_control) else: - phase.add_polynomial_control('theta', order=1, units='deg', lower=0.01, upper=179.9) + phase.add_polynomial_control('theta', order=1, units='deg', lower=0.01, upper=179.9, + fix_final=fix_final_control) phase.add_parameter('g', units='m/s**2', opt=False, val=9.80665) @@ -186,7 +188,7 @@ def test_load_case_radau_to_lgl(self): q.model.phase0.interp(xs=time_val, ys=theta_val, nodes='all'), tolerance=1.0E-2) - def test_load_case_warn_fix_final(self): + def test_load_case_warn_fix_final_states(self): import openmdao.api as om from openmdao.utils.assert_utils import assert_warnings import dymos as dm @@ -206,12 +208,57 @@ def test_load_case_warn_fix_final(self): # Load the values from the previous solution for state_name in ['x', 'y']: - msgs.append((UserWarning, f"{state_name} specifies 'fix_final = True'. If the given restart file has a" - f" different final value this will overwrite the user-specified value")) - print(msgs) + msgs.append((UserWarning, f"phase0.states:{state_name} specifies 'fix_final=True'." + f" If the given restart file has a different final value" + f" this will overwrite the user-specified value")) + with assert_warnings(msgs): dm.load_case(q, case) + def test_load_case_warn_fix_final_control(self): + import openmdao.api as om + from openmdao.utils.assert_utils import assert_warning + import dymos as dm + p = setup_problem(dm.Radau(num_segments=10)) + + # Solve for the optimal trajectory + dm.run_problem(p) + + # Load the solution + case = om.CaseReader('dymos_solution.db').get_case('final') + + # create a problem with a different transcription with a different number of variables + q = setup_problem(dm.Radau(num_segments=10), fix_final_state=False, fix_final_control=True) + + msg = f"phase0.controls:theta specifies 'fix_final=True'. If the given restart file has a" \ + f" different final value this will overwrite the user-specified value" + + with assert_warning(UserWarning, msg): + dm.load_case(q, case) + + def test_load_case_warn_fix_final_polynomial_control(self): + import openmdao.api as om + from openmdao.utils.assert_utils import assert_warning + import dymos as dm + p = setup_problem(dm.Radau(num_segments=10), polynomial_control=True,) + + # Solve for the optimal trajectory + dm.run_problem(p) + + # Load the solution + case = om.CaseReader('dymos_solution.db').get_case('final') + + # create a problem with a different transcription with a different number of variables + q = setup_problem(dm.Radau(num_segments=10), polynomial_control=True, + fix_final_state=False, fix_final_control=True) + + # Load the values from the previous solution + msg = f"phase0.polynomial_controls:theta specifies 'fix_final=True'. If the given restart file has a" \ + f" different final value this will overwrite the user-specified value" + + with assert_warning(UserWarning, msg): + dm.load_case(q, case) + if __name__ == '__main__': # pragma: no cover unittest.main() From 85c3eb758a39d4cdcf87fcf1e1eac15d7fe16d80 Mon Sep 17 00:00:00 2001 From: Kaushik Ponnapalli Date: Thu, 18 Aug 2022 07:58:52 -0500 Subject: [PATCH 4/4] switched warning to issue_warning --- dymos/load_case.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dymos/load_case.py b/dymos/load_case.py index f66521a19..14a7a2be8 100644 --- a/dymos/load_case.py +++ b/dymos/load_case.py @@ -2,7 +2,7 @@ from openmdao.recorders.case import Case from .phase.phase import Phase from .trajectory import Trajectory -from warnings import warn +from openmdao.utils.om_warnings import issue_warning def find_phases(sys): @@ -154,7 +154,7 @@ def load_case(problem, previous_solution): warning_message = f"{phase_name}.states:{state_name} specifies 'fix_final=True'. " \ f"If the given restart file has a" \ f" different final value this will overwrite the user-specified value" - warn(warning_message) + issue_warning(warning_message) # Interpolate the timeseries control outputs from the previous solution onto the new grid. for control_name, options in phase.control_options.items(): @@ -171,7 +171,7 @@ def load_case(problem, previous_solution): warning_message = f"{phase_name}.controls:{control_name} specifies 'fix_final=True'. " \ f"If the given restart file has a" \ f" different final value this will overwrite the user-specified value" - warn(warning_message) + issue_warning(warning_message) # Set the output polynomial control outputs from the previous solution as the value for pc_name, options in phase.polynomial_control_options.items(): @@ -185,7 +185,7 @@ def load_case(problem, previous_solution): warning_message = f"{phase_name}.polynomial_controls:{pc_name} specifies 'fix_final=True'. " \ f"If the given restart file has a" \ f" different final value this will overwrite the user-specified value" - warn(warning_message) + issue_warning(warning_message) # Set the timeseries parameter outputs from the previous solution as the parameter value for param_name, options in phase.parameter_options.items():