def test_brachistochrone_vector_boundary_constraints_radau_full_indices( self): p = Problem(model=Group()) p.driver = ScipyOptimizeDriver() p.driver.options['dynamic_simul_derivs'] = True phase = Phase(ode_class=BrachistochroneVectorStatesODE, transcription=Radau(num_segments=20, order=3)) p.model.add_subsystem('phase0', phase) phase.set_time_options(fix_initial=True, duration_bounds=(.5, 10)) phase.set_state_options('pos', fix_initial=True, fix_final=False) phase.set_state_options('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_design_parameter('g', units='m/s**2', opt=False, val=9.80665) phase.add_boundary_constraint('pos', loc='final', equals=[10, 5], indices=[0, 1]) # Minimize time at the end of the phase phase.add_objective('time', loc='final', scaler=10) p.model.linear_solver = DirectSolver() p.setup(check=True, force_alloc_complex=True) p['phase0.t_initial'] = 0.0 p['phase0.t_duration'] = 2.0 pos0 = [0, 10] posf = [10, 5] p['phase0.states:pos'] = phase.interpolate(ys=[pos0, posf], nodes='state_input') p['phase0.states:v'] = phase.interpolate(ys=[0, 9.9], nodes='state_input') p['phase0.controls:theta'] = phase.interpolate(ys=[5, 100], nodes='control_input') p['phase0.design_parameters:g'] = 9.80665 p.run_driver() assert_rel_error(self, p.get_val('phase0.time')[-1], 1.8016, tolerance=1.0E-3) # Plot results if SHOW_PLOTS: p.run_driver() exp_out = phase.simulate(times_per_seg=10) fig, ax = plt.subplots() fig.suptitle('Brachistochrone Solution') x_imp = p.get_val('phase0.timeseries.states:pos')[:, 0] y_imp = p.get_val('phase0.timeseries.states:pos')[:, 1] x_exp = exp_out.get_val('phase0.timeseries.states:pos')[:, 0] y_exp = exp_out.get_val('phase0.timeseries.states:pos')[:, 1] ax.plot(x_imp, y_imp, 'ro', label='implicit') ax.plot(x_exp, y_exp, 'b-', label='explicit') ax.set_xlabel('x (m)') ax.set_ylabel('y (m)') ax.grid(True) ax.legend(loc='upper right') fig, ax = plt.subplots() fig.suptitle('Brachistochrone Solution') x_imp = p.get_val('phase0.timeseries.time') y_imp = p.get_val('phase0.timeseries.control_rates:theta_rate2') x_exp = exp_out.get_val('phase0.timeseries.time') y_exp = exp_out.get_val( 'phase0.timeseries.control_rates:theta_rate2') ax.plot(x_imp, y_imp, 'ro', label='implicit') ax.plot(x_exp, y_exp, 'b-', label='explicit') ax.set_xlabel('time (s)') ax.set_ylabel('theta rate2 (rad/s**2)') ax.grid(True) ax.legend(loc='lower right') plt.show() return p
def min_time_climb(optimizer='SLSQP', num_seg=3, transcription='gauss-lobatto', transcription_order=3, top_level_jacobian='csc', simul_derivs=True, force_alloc_complex=False): p = Problem(model=Group()) p.driver = pyOptSparseDriver() p.driver.options['optimizer'] = optimizer if simul_derivs: p.driver.options['dynamic_simul_derivs'] = True if optimizer == 'SNOPT': p.driver.opt_settings['Major iterations limit'] = 1000 p.driver.opt_settings['iSumm'] = 6 p.driver.opt_settings['Major feasibility tolerance'] = 1.0E-6 p.driver.opt_settings['Major optimality tolerance'] = 1.0E-6 p.driver.opt_settings['Function precision'] = 1.0E-6 p.driver.opt_settings['Linesearch tolerance'] = 0.10 p.driver.opt_settings['Major step limit'] = 0.5 # p.driver.opt_settings['Verify level'] = 3 phase = Phase(transcription, ode_class=MinTimeClimbODE, num_segments=num_seg, compressed=True, transcription_order=transcription_order) p.model.add_subsystem('phase0', phase) phase.set_time_options(fix_initial=True, duration_bounds=(50, 400), duration_ref=100.0) phase.set_state_options('r', fix_initial=True, lower=0, upper=1.0E6, scaler=1.0E-3, defect_scaler=1.0E-2, units='m') phase.set_state_options('h', fix_initial=True, lower=0, upper=20000.0, scaler=1.0E-3, defect_scaler=1.0E-3, units='m') phase.set_state_options('v', fix_initial=True, lower=10.0, scaler=1.0E-2, defect_scaler=1.0E-2, units='m/s') phase.set_state_options('gam', fix_initial=True, lower=-1.5, upper=1.5, ref=1.0, defect_scaler=1.0, units='rad') phase.set_state_options('m', fix_initial=True, lower=10.0, upper=1.0E5, scaler=1.0E-3, defect_scaler=1.0E-3) phase.add_control('alpha', units='deg', lower=-8.0, upper=8.0, scaler=1.0, continuity=True, rate_continuity=True, rate2_continuity=False) phase.add_design_parameter('S', val=49.2386, units='m**2', opt=False) phase.add_design_parameter('Isp', val=1600.0, units='s', opt=False) phase.add_design_parameter('throttle', val=1.0, opt=False) phase.add_boundary_constraint('h', loc='final', equals=20000, scaler=1.0E-3, units='m') phase.add_boundary_constraint('aero.mach', loc='final', equals=1.0, units=None) phase.add_boundary_constraint('gam', loc='final', equals=0.0, units='rad') phase.add_path_constraint(name='h', lower=100.0, upper=20000, ref=20000) phase.add_path_constraint(name='aero.mach', lower=0.1, upper=1.8) phase.add_path_constraint(name='alpha', lower=-8, upper=8) # Minimize time at the end of the phase phase.add_objective('time', loc='final') p.model.options['assembled_jac_type'] = top_level_jacobian.lower() p.model.linear_solver = DirectSolver(assemble_jac=True) p.setup(check=True, force_alloc_complex=force_alloc_complex) p['phase0.t_initial'] = 0.0 p['phase0.t_duration'] = 298.46902 p['phase0.states:r'] = phase.interpolate(ys=[0.0, 111319.54], nodes='state_input') p['phase0.states:h'] = phase.interpolate(ys=[100.0, 20000.0], nodes='state_input') p['phase0.states:v'] = phase.interpolate(ys=[135.964, 283.159], nodes='state_input') p['phase0.states:gam'] = phase.interpolate(ys=[0.0, 0.0], nodes='state_input') p['phase0.states:m'] = phase.interpolate(ys=[19030.468, 16841.431], nodes='state_input') p['phase0.controls:alpha'] = phase.interpolate(ys=[0.0, 0.0], nodes='control_input') p.run_driver() if SHOW_PLOTS: exp_out = phase.simulate(times=np.linspace(0, p['phase0.t_duration'], 100)) import matplotlib.pyplot as plt plt.plot(phase.get_values('time'), phase.get_values('h'), 'ro') plt.plot(exp_out.get_values('time'), exp_out.get_values('h'), 'b-') plt.xlabel('time (s)') plt.ylabel('altitude (m)') plt.figure() plt.plot(phase.get_values('v'), phase.get_values('h'), 'ro') plt.plot(exp_out.get_values('v'), exp_out.get_values('h'), 'b-') plt.xlabel('airspeed (m/s)') plt.ylabel('altitude (m)') plt.figure() plt.plot(phase.get_values('time'), phase.get_values('alpha'), 'ro') plt.plot(exp_out.get_values('time'), exp_out.get_values('alpha'), 'b-') plt.xlabel('time (s)') plt.ylabel('alpha (rad)') plt.figure() plt.plot(phase.get_values('time'), phase.get_values('prop.thrust', units='lbf'), 'ro') plt.plot(exp_out.get_values('time'), exp_out.get_values('prop.thrust', units='lbf'), 'b-') plt.xlabel('time (s)') plt.ylabel('thrust (lbf)') plt.show() return p
def test_brachistochrone_forward_shooting_boundary_constrained_design_parameter(self): from openmdao.api import Problem, Group, ScipyOptimizeDriver, DirectSolver from openmdao.utils.assert_utils import assert_rel_error from dymos import Phase, RungeKutta from dymos.examples.brachistochrone.brachistochrone_ode import BrachistochroneODE p = Problem(model=Group()) p.driver = ScipyOptimizeDriver() p.driver.options['dynamic_simul_derivs'] = True phase = Phase(ode_class=BrachistochroneODE, transcription=RungeKutta(num_segments=20)) p.model.add_subsystem('phase0', phase) phase.set_time_options(initial_bounds=(0, 0), duration_bounds=(0.5, 2.0)) 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_polynomial_control('theta', order=2, units='deg', lower=0.01, upper=179.9) phase.add_design_parameter('g', units='m/s**2', opt=False, val=9.80665) # Final state values can't be controlled with simple bounds in RungeKuttaPhase, # so use nonlinear boundary constraints instead. phase.add_boundary_constraint('x', loc='final', equals=10) phase.add_boundary_constraint('y', loc='final', equals=5) phase.add_boundary_constraint('theta_rate2', loc='final', equals=0) # Minimize time at the end of the phase phase.add_objective('time_phase', loc='final', scaler=1) p.model.linear_solver = DirectSolver() p.setup(check=True) p['phase0.t_initial'] = 0.0 p['phase0.t_duration'] = 2.0 p['phase0.states:x'] = 0 p['phase0.states:y'] = 10 p['phase0.states:v'] = 0 p['phase0.polynomial_controls:theta'][:, 0] = [0.01, 50, 100] # Solve for the optimal trajectory p.run_driver() # Test the results assert_rel_error(self, p['phase0.time'][-1], 1.8016, tolerance=1.0E-3) assert_rel_error(self, p.get_val('phase0.timeseries.polynomial_control_rates:theta_rate2')[-1, 0], 0.0, tolerance=1.0E-9) # Generate the explicitly simulated trajectory exp_out = phase.simulate() assert_rel_error(self, exp_out.get_val('phase0.timeseries.states:x')[-1, 0], 10, tolerance=1.0E-3) assert_rel_error(self, exp_out.get_val('phase0.timeseries.states:y')[-1, 0], 5, tolerance=1.0E-3)
def test_brachistochrone_for_docs_gauss_lobatto(self): import numpy as np import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt from openmdao.api import Problem, Group, ScipyOptimizeDriver, DirectSolver from openmdao.utils.assert_utils import assert_rel_error from dymos import Phase from dymos.examples.brachistochrone.brachistochrone_ode import BrachistochroneODE p = Problem(model=Group()) p.driver = ScipyOptimizeDriver() phase = Phase('gauss-lobatto', ode_class=BrachistochroneODE, num_segments=10) p.model.add_subsystem('phase0', phase) phase.set_time_options(initial_bounds=(0, 0), duration_bounds=(.5, 10)) phase.set_state_options('x', fix_initial=True, fix_final=True) phase.set_state_options('y', fix_initial=True, fix_final=True) phase.set_state_options('v', fix_initial=True) phase.add_control('theta', units='deg', rate_continuity=False, lower=0.01, upper=179.9) phase.add_design_parameter('g', units='m/s**2', opt=False, val=9.80665) # Minimize time at the end of the phase phase.add_objective('time', loc='final', scaler=10) p.model.linear_solver = DirectSolver(assemble_jac=True) p.model.options['assembled_jac_type'] = 'csc' p.setup() p['phase0.t_initial'] = 0.0 p['phase0.t_duration'] = 2.0 p['phase0.states:x'] = phase.interpolate(ys=[0, 10], nodes='state_input') p['phase0.states:y'] = phase.interpolate(ys=[10, 5], nodes='state_input') p['phase0.states:v'] = phase.interpolate(ys=[0, 9.9], nodes='state_input') p['phase0.controls:theta'] = phase.interpolate(ys=[5, 100.5], nodes='control_input') # Solve for the optimal trajectory p.run_driver() # Test the results assert_rel_error(self, phase.get_values('time')[-1], 1.8016, tolerance=1.0E-3) # Generate the explicitly simulated trajectory t0 = p['phase0.t_initial'] tf = t0 + p['phase0.t_duration'] exp_out = phase.simulate(times=np.linspace(t0, tf, 50)) fig, ax = plt.subplots() fig.suptitle('Brachistochrone Solution') x_imp = phase.get_values('x', nodes='all') y_imp = phase.get_values('y', nodes='all') x_exp = exp_out.get_values('x') y_exp = exp_out.get_values('y') ax.plot(x_imp, y_imp, 'ro', label='solution') ax.plot(x_exp, y_exp, 'b-', label='simulated') ax.set_xlabel('x (m)') ax.set_ylabel('y (m)') ax.grid(True) ax.legend(loc='upper right') plt.show()
def test_steady_aircraft_for_docs(self): import numpy as np import matplotlib.pyplot as plt from openmdao.api import Problem, Group, pyOptSparseDriver, DirectSolver, IndepVarComp from openmdao.utils.assert_utils import assert_rel_error from dymos import Phase from dymos.examples.aircraft_steady_flight.aircraft_ode import AircraftODE from dymos.utils.lgl import lgl p = Problem(model=Group()) p.driver = pyOptSparseDriver() p.driver.options['optimizer'] = 'SLSQP' p.driver.options['dynamic_simul_derivs'] = True num_seg = 15 seg_ends, _ = lgl(num_seg + 1) phase = Phase('gauss-lobatto', ode_class=AircraftODE, num_segments=num_seg, segment_ends=seg_ends, transcription_order=5, compressed=False) # Pass design parameters in externally from an external source assumptions = p.model.add_subsystem('assumptions', IndepVarComp()) assumptions.add_output('mach', val=0.8, units=None) assumptions.add_output('S', val=427.8, units='m**2') assumptions.add_output('mass_empty', val=1.0, units='kg') assumptions.add_output('mass_payload', val=1.0, units='kg') p.model.add_subsystem('phase0', phase) phase.set_time_options(fix_initial=True, duration_bounds=(300, 10000), duration_ref=3600) phase.set_state_options('range', units='NM', fix_initial=True, fix_final=False, scaler=0.001, defect_scaler=1.0E-2) phase.set_state_options('mass_fuel', units='lbm', fix_initial=True, fix_final=True, upper=1.5E5, lower=0.0, scaler=1.0E-5, defect_scaler=1.0E-1) phase.add_control('alt', units='kft', opt=True, lower=0.0, upper=50.0, rate_param='climb_rate', rate_continuity=True, rate_continuity_scaler=1.0, rate2_continuity=True, rate2_continuity_scaler=1.0, ref=1.0, fix_initial=True, fix_final=True) phase.add_input_parameter('mach', units=None) phase.add_input_parameter('S', units='m**2') phase.add_input_parameter('mass_empty', units='kg') phase.add_input_parameter('mass_payload', units='kg') phase.add_path_constraint('propulsion.tau', lower=0.01, upper=1.0) phase.add_path_constraint('alt_rate', units='ft/min', lower=-3000, upper=3000, ref=3000) p.model.connect('assumptions.mach', 'phase0.input_parameters:mach') p.model.connect('assumptions.S', 'phase0.input_parameters:S') p.model.connect('assumptions.mass_empty', 'phase0.input_parameters:mass_empty') p.model.connect('assumptions.mass_payload', 'phase0.input_parameters:mass_payload') phase.add_objective('range', loc='final', ref=-1.0) p.model.linear_solver = DirectSolver(assemble_jac=True) p.setup() p['phase0.t_initial'] = 0.0 p['phase0.t_duration'] = 3600.0 p['phase0.states:range'] = phase.interpolate(ys=(0, 1000.0), nodes='state_input') p['phase0.states:mass_fuel'] = phase.interpolate(ys=(30000, 0), nodes='state_input') p['phase0.controls:alt'][:] = 10.0 p['assumptions.mach'][:] = 0.8 p['assumptions.S'] = 427.8 p['assumptions.mass_empty'] = 0.15E6 p['assumptions.mass_payload'] = 84.02869 * 400 p.run_driver() exp_out = phase.simulate(times=np.linspace(0, p['phase0.t_duration'], 500), record=True, record_file='test_doc_aircraft_steady_flight_rec.db') assert_rel_error(self, phase.get_values('range', units='NM')[-1], 726.7, tolerance=1.0E-2) plt.figure() plt.plot(phase.get_values('time', nodes='all'), phase.get_values('alt', nodes='all', units='ft'), 'ro') plt.plot(exp_out.get_values('time'), exp_out.get_values('alt', units='ft'), 'b-') plt.suptitle('Altitude vs Time') plt.xlabel('Time (s)') plt.ylabel('Altitude (ft)') plt.figure() plt.plot(phase.get_values('time', nodes='all'), phase.get_values('alt_rate', nodes='all', units='ft/min'), 'ro') plt.plot(exp_out.get_values('time'), exp_out.get_values('alt_rate', units='ft/min'), 'b-') plt.suptitle('Climb Rate vs Time') plt.xlabel('Time (s)') plt.ylabel('Climb Rate (ft/min)') plt.figure() plt.plot(phase.get_values('time', nodes='all'), phase.get_values('mass_fuel', nodes='all', units='lbm'), 'ro') plt.plot(exp_out.get_values('time'), exp_out.get_values('mass_fuel', units='lbm'), 'b-') plt.suptitle('Fuel Mass vs Time') plt.xlabel('Time (s)') plt.ylabel('Fuel Mass (lbm)') plt.show()