Example #1
0
    def test_control_rate_path_constraint_gl(self):
        from openmdao.api import Problem, Group, ScipyOptimizeDriver, DirectSolver
        from openmdao.utils.assert_utils import assert_rel_error
        from dymos import Phase, GaussLobatto
        from dymos.examples.brachistochrone.brachistochrone_ode import BrachistochroneODE

        p = Problem(model=Group())
        p.driver = ScipyOptimizeDriver()

        phase = Phase(ode_class=BrachistochroneODE,
                      transcription=GaussLobatto(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)

        phase.add_path_constraint('theta_rate',
                                  lower=0,
                                  upper=100,
                                  units='deg/s')

        p.model.linear_solver = DirectSolver()

        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,
                         p.get_val('phase0.timeseries.time')[-1],
                         1.8016,
                         tolerance=1.0E-3)
Example #2
0
    def test_record_specified_file(self, transcription='gauss-lobatto',
                                   top_level_jacobian='csc', optimizer='slsqp'):
        p = Problem(model=Group())

        if optimizer == 'SNOPT':
            p.driver = pyOptSparseDriver()
            p.driver.options['optimizer'] = OPTIMIZER
            p.driver.opt_settings['Major iterations limit'] = 100
            p.driver.opt_settings['iSumm'] = 6
            p.driver.opt_settings['Verify level'] = 3
        else:
            p.driver = ScipyOptimizeDriver()

        phase = Phase(transcription,
                      ode_class=BrachistochroneODE,
                      num_segments=8,
                      transcription_order=3)

        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=True, lower=0.01, upper=179.9)

        # Minimize time at the end of the phase
        phase.add_objective('time', loc='final', scaler=10)

        p.model.options['assembled_jac_type'] = top_level_jacobian.lower()
        p.model.linear_solver = DirectSolver(assemble_jac=True)

        p.setup()

        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')

        p.run_driver()

        exp_out = phase.simulate(times=np.linspace(p['phase0.t_initial'],
                                                   p['phase0.t_initial'] + p['phase0.t_duration'],
                                                   50),
                                 record_file='brachistochrone_sim.db')

        loaded_exp_out = load_simulation_results('brachistochrone_sim.db')

        for var in ['time', 'x', 'y', 'v', 'theta']:
            assert_almost_equal(exp_out.get_values(var).ravel(),
                                loaded_exp_out.get_values(var).ravel())
Example #3
0
    def test_ex_brachistochrone_vs_rungekutta_compressed(self):
        from openmdao.api import Problem, Group, ScipyOptimizeDriver, DirectSolver
        from dymos import Phase, RungeKutta
        from dymos.examples.brachistochrone.brachistochrone_vector_states_ode import \
            BrachistochroneVectorStatesODE

        p = Problem(model=Group())

        p.driver = ScipyOptimizeDriver()

        p.driver.options['dynamic_simul_derivs'] = True

        phase = Phase(ode_class=BrachistochroneVectorStatesODE,
                      transcription=RungeKutta(num_segments=20,
                                               compressed=True))

        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', lower=[10, 5])

        # 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'] = 1.80162174

        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=[0.46, 100.22900215],
                                                       nodes='control_input')
        p['phase0.design_parameters:g'] = 9.80665

        p.run_driver()

        self.assert_results(p)
        self.tearDown()
    def setUpClass(cls):
        import matplotlib
        matplotlib.use('Agg')
        from openmdao.api import Problem, Group, ScipyOptimizeDriver, DirectSolver
        from dymos import Phase, load_simulation_results
        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='rad',
                          rate_continuity=False,
                          lower=0.001,
                          upper=3.14)

        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()

        cls.exp_out = phase.simulate(
            times=100, record_file='phase_simulation_test_sim.db')

        cls.exp_out_loaded = load_simulation_results(
            'phase_simulation_test_sim.db')
Example #5
0
    def test_unbounded_time(self):
        p = Problem(model=Group())

        p.driver = ScipyOptimizeDriver()
        p.driver.options['dynamic_simul_derivs'] = True

        phase = Phase('gauss-lobatto',
                      ode_class=BrachistochroneODE,
                      num_segments=8,
                      transcription_order=3)

        p.model.add_subsystem('phase0', phase)

        phase.set_time_options(fix_initial=False, fix_duration=False)

        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, 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)

        # Minimize time at the end of the phase
        phase.add_objective('time', loc='final', scaler=10)

        phase.add_boundary_constraint('time', loc='initial', equals=0)

        p.model.options['assembled_jac_type'] = 'csc'
        p.model.linear_solver = DirectSolver(assemble_jac=True)
        p.setup(check=True)

        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],
                                                       nodes='control_input')
        p['phase0.design_parameters:g'] = 9.80665

        p.run_driver()

        self.assertTrue(p.driver.result.success,
                        msg='Brachistochrone with outbounded times has failed')
Example #6
0
    def test_objective_design_parameter_radau(self):
        p = Problem(model=Group())

        p.driver = ScipyOptimizeDriver()

        p.driver.options['dynamic_simul_derivs'] = True

        phase = Phase(ode_class=BrachistochroneODE,
                      transcription=Radau(num_segments=20,
                                          order=3,
                                          compressed=True))

        p.model.add_subsystem('phase0', phase)

        phase.set_time_options(fix_initial=True, duration_bounds=(4, 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, 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=True, val=9.80665)

        # Minimize time at the end of the phase
        phase.add_objective('g')

        p.model.options['assembled_jac_type'] = 'csc'
        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'] = 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],
                                                       nodes='control_input')
        p['phase0.design_parameters:g'] = 9.80665

        p.run_driver()

        assert_rel_error(self, p['phase0.t_duration'], 10, tolerance=1.0E-3)
Example #7
0
def double_integrator_direct_collocation(transcription='gauss-lobatto',
                                         top_level_jacobian='csc',
                                         compressed=True):
    p = Problem(model=Group())
    p.driver = ScipyOptimizeDriver()
    p.driver.options['dynamic_simul_derivs'] = True

    phase = Phase(transcription,
                  ode_class=DoubleIntegratorODE,
                  num_segments=20,
                  transcription_order=3,
                  compressed=compressed)

    p.model.add_subsystem('phase0', phase)

    phase.set_time_options(fix_initial=True, fix_duration=True)

    phase.set_state_options('x', fix_initial=True)
    phase.set_state_options('v', fix_initial=True, fix_final=True)

    phase.add_control('u',
                      units='m/s**2',
                      scaler=0.01,
                      continuity=False,
                      rate_continuity=False,
                      rate2_continuity=False,
                      lower=-1.0,
                      upper=1.0)

    # Maximize distance travelled in one second.
    phase.add_objective('x', loc='final', scaler=-1)

    p.model.linear_solver = DirectSolver(assemble_jac=True)
    p.model.options['assembled_jac_type'] = top_level_jacobian.lower()

    p.setup(check=True)

    p['phase0.t_initial'] = 0.0
    p['phase0.t_duration'] = 1.0

    p['phase0.states:x'] = phase.interpolate(ys=[0, 0.25], nodes='state_input')
    p['phase0.states:v'] = phase.interpolate(ys=[0, 0], nodes='state_input')
    p['phase0.controls:u'] = phase.interpolate(ys=[1, -1],
                                               nodes='control_input')

    p.run_driver()

    return p
Example #8
0
    def test_brachistochrone_backward_shooting(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=(-2.0, -0.5))

        phase.set_state_options('x', fix_initial=True)
        phase.set_state_options('y', fix_initial=True)
        phase.set_state_options('v', fix_initial=False)

        phase.add_control('theta', units='deg', lower=0.01, upper=179.9, ref0=0, ref=180.0,
                          rate_continuity=True, rate2_continuity=True)

        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 ExplicitPhase,
        # so use nonlinear boundary constraints instead.
        phase.add_boundary_constraint('x', loc='final', equals=0)
        phase.add_boundary_constraint('y', loc='final', equals=10)
        phase.add_boundary_constraint('v', loc='final', equals=0)

        # Minimize time at the end of the phase
        phase.add_objective('time', loc='final', scaler=-1)

        p.model.linear_solver = DirectSolver()

        p.setup(check=True)

        p['phase0.t_initial'] = 1.8016
        p['phase0.t_duration'] = -1.8016

        p['phase0.states:x'] = 10
        p['phase0.states:y'] = 5
        p['phase0.states:v'] = 10
        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, p['phase0.time'][-1], -1.8016, tolerance=1.0E-3)

        # Generate the explicitly simulated trajectory
        exp_out = phase.simulate()

        assert_rel_error(self, exp_out.get_val('phase0.timeseries.states:x')[-1, 0], 0,
                         tolerance=1.0E-3)
        assert_rel_error(self, exp_out.get_val('phase0.timeseries.states:y')[-1, 0], 10,
                         tolerance=1.0E-3)
Example #9
0
    def _make_problem(self, transcription, num_seg, transcription_order=3):
        p = Problem(model=Group())

        p.driver = ScipyOptimizeDriver()

        # Compute sparsity/coloring when run_driver is called
        p.driver.options['dynamic_simul_derivs'] = True

        t = {'gauss-lobatto': GaussLobatto(num_segments=num_seg, order=transcription_order),
             'radau-ps': Radau(num_segments=num_seg, order=transcription_order),
             'runge-kutta': RungeKutta(num_segments=num_seg)}

        phase = Phase(ode_class=_BrachistochroneTestODE, transcription=t[transcription])

        p.model.add_subsystem('phase0', phase)

        phase.set_time_options(initial_bounds=(1, 1), duration_bounds=(.5, 10))

        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_control('theta', units='deg', rate_continuity=True, lower=0.01, upper=179.9)

        phase.add_design_parameter('g', units='m/s**2', opt=False, val=9.80665)

        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', loc='final', scaler=10)

        p.model.linear_solver = DirectSolver()

        p.setup()

        p['phase0.t_initial'] = 1.0
        p['phase0.t_duration'] = 3.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')

        return p
Example #10
0
    def test_min_time_climb_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, pyOptSparseDriver, DirectSolver
        from openmdao.utils.assert_utils import assert_rel_error

        from dymos import Phase
        from dymos.examples.min_time_climb.min_time_climb_ode import MinTimeClimbODE

        p = Problem(model=Group())

        p.driver = pyOptSparseDriver()
        p.driver.options['optimizer'] = 'SLSQP'

        # Compute sparsity/coloring when run_driver is called
        p.driver.options['dynamic_simul_derivs'] = True

        phase = Phase('gauss-lobatto',
                      ode_class=MinTimeClimbODE,
                      num_segments=12,
                      compressed=True,
                      transcription_order=3)

        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,
                                ref=1.0E3,
                                defect_ref=1000.0,
                                units='m')

        phase.set_state_options('h',
                                fix_initial=True,
                                lower=0,
                                upper=20000.0,
                                ref=1.0E2,
                                defect_ref=100.0,
                                units='m')

        phase.set_state_options('v',
                                fix_initial=True,
                                lower=10.0,
                                ref=1.0E2,
                                defect_ref=0.1,
                                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,
                                ref=1.0E3,
                                defect_ref=0.1)

        rate_continuity = True

        phase.add_control('alpha',
                          units='deg',
                          lower=-8.0,
                          upper=8.0,
                          scaler=1.0,
                          rate_continuity=rate_continuity,
                          rate_continuity_scaler=100.0,
                          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.driver.options['dynamic_simul_derivs'] = True
        p.model.options['assembled_jac_type'] = 'csc'
        p.model.linear_solver = DirectSolver(assemble_jac=True)

        p.setup(check=True)

        p['phase0.t_initial'] = 0.0
        p['phase0.t_duration'] = 500

        p['phase0.states:r'] = phase.interpolate(ys=[0.0, 50000.0],
                                                 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, 10000.],
                                                 nodes='state_input')
        p['phase0.controls:alpha'] = phase.interpolate(ys=[0.0, 0.0],
                                                       nodes='control_input')

        # Solve for the optimal trajectory
        p.run_driver()

        # Test the results
        assert_rel_error(self,
                         p.model.phase0.get_values('time')[-1],
                         321.0,
                         tolerance=2)

        exp_out = phase.simulate(times=50)

        fig, axes = plt.subplots(2, 1, sharex=True)

        axes[0].plot(phase.get_values('time'), phase.get_values('h'), 'ro')
        axes[0].plot(exp_out.get_values('time'), exp_out.get_values('h'), 'b-')
        axes[0].set_xlabel('time (s)')
        axes[0].set_ylabel('altitude (m)')

        axes[1].plot(phase.get_values('time'),
                     phase.get_values('alpha', units='deg'), 'ro')
        axes[1].plot(exp_out.get_values('time'),
                     exp_out.get_values('alpha', units='deg'), 'b-')
        axes[1].set_xlabel('time (s)')
        axes[1].set_ylabel('alpha (deg)')

        plt.show()
    def test_brachistochrone_recording(self):
        import matplotlib
        matplotlib.use('Agg')
        from openmdao.api import Problem, Group, ScipyOptimizeDriver, DirectSolver, \
            SqliteRecorder, CaseReader
        from openmdao.utils.assert_utils import assert_rel_error
        from dymos import Phase, GaussLobatto
        from dymos.examples.brachistochrone.brachistochrone_ode import BrachistochroneODE

        p = Problem(model=Group())
        p.driver = ScipyOptimizeDriver()

        phase = Phase(ode_class=BrachistochroneODE,
                      transcription=GaussLobatto(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()

        # Recording
        rec = SqliteRecorder('brachistochrone_solution.db')

        p.driver.recording_options['record_desvars'] = True
        p.driver.recording_options['record_responses'] = True
        p.driver.recording_options['record_objectives'] = True
        p.driver.recording_options['record_constraints'] = True

        p.model.recording_options['record_metadata'] = True

        p.driver.add_recorder(rec)
        p.model.add_recorder(rec)
        phase.add_recorder(rec)

        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,
                         p.get_val('phase0.timeseries.time')[-1],
                         1.8016,
                         tolerance=1.0E-3)

        cr = CaseReader('brachistochrone_solution.db')
        system_cases = cr.list_cases('root')
        case = cr.get_case(system_cases[-1])

        outputs = dict([
            (o[0], o[1])
            for o in case.list_outputs(units=True, shape=True, out_stream=None)
        ])

        assert_rel_error(
            self, p['phase0.controls:theta'],
            outputs['phase0.control_group.indep_controls.controls:theta']
            ['value'])
Example #12
0
def ex_aircraft_steady_flight(optimizer='SLSQP',
                              transcription='gauss-lobatto'):
    p = Problem(model=Group())
    p.driver = pyOptSparseDriver()
    p.driver.options['optimizer'] = optimizer
    p.driver.options['dynamic_simul_derivs'] = True
    if optimizer == 'SNOPT':
        p.driver.opt_settings['Major iterations limit'] = 1000
        p.driver.opt_settings['Major feasibility tolerance'] = 1.0E-6
        p.driver.opt_settings['Major optimality tolerance'] = 1.0E-6
        p.driver.opt_settings["Linesearch tolerance"] = 0.10
        p.driver.opt_settings['iSumm'] = 6

    num_seg = 15
    seg_ends, _ = lgl(num_seg + 1)

    phase = Phase(transcription,
                  ode_class=AircraftODE,
                  num_segments=num_seg,
                  segment_ends=seg_ends,
                  transcription_order=5,
                  compressed=False)

    # Pass Reference Area from an external source
    assumptions = p.model.add_subsystem('assumptions', IndepVarComp())
    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(initial_bounds=(0, 0),
                           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_control('mach', units=None, opt=False)

    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.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:mach'][:] = 0.8
    p['phase0.controls:alt'][:] = 10.0

    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_ex_aircraft_steady_flight_rec.db')

    plt.plot(phase.get_values('time', nodes='all'),
             phase.get_values('alt', nodes='all'), 'ro')
    plt.plot(exp_out.get_values('time'), exp_out.get_values('alt'), 'b-')
    plt.suptitle('altitude vs time')
    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('altitude rate vs time')
    plt.figure()
    plt.plot(phase.get_values('time', nodes='all'),
             phase.get_values('mass_fuel', nodes='all'), 'ro')
    plt.plot(exp_out.get_values('time'), exp_out.get_values('mass_fuel'), 'b-')
    plt.suptitle('fuel mass vs time')
    plt.figure()
    plt.plot(phase.get_values('time', nodes='all'),
             phase.get_values('propulsion.dXdt:mass_fuel', nodes='all'), 'ro')
    plt.plot(exp_out.get_values('time'),
             exp_out.get_values('propulsion.dXdt:mass_fuel'), 'b-')
    plt.suptitle('fuel mass flow rate vs time')
    plt.figure()
    plt.plot(phase.get_values('time', nodes='all'),
             phase.get_values('mach', nodes='all'), 'ro')
    plt.plot(exp_out.get_values('time'), exp_out.get_values('mach'), 'b-')
    plt.suptitle('mach vs time')
    plt.figure()
    plt.plot(phase.get_values('time', nodes='all'),
             phase.get_values('mach_rate', nodes='all'), 'ro')
    plt.plot(exp_out.get_values('time'), exp_out.get_values('mach_rate'), 'b-')
    plt.suptitle('mach rate vs time')

    print('time')
    print(phase.get_values('time', nodes='all').T)

    print('alt')
    print(phase.get_values('alt', nodes='all').T)

    print('alt_rate')
    print(phase.get_values('alt_rate', nodes='all').T)

    print('alt_rate2')
    print(phase.get_values('alt_rate2', nodes='all').T)

    print('range')
    print(phase.get_values('range', nodes='all').T)

    print('flight path angle')
    print(phase.get_values('gam_comp.gam').T)

    print('true airspeed')
    print(phase.get_values('tas_comp.TAS', units='m/s').T)

    print('coef of lift')
    print(phase.get_values('aero.CL').T)

    print('coef of drag')
    print(phase.get_values('aero.CD').T)

    print('atmos density')
    print(phase.get_values('atmos.rho').T)

    print('alpha')
    print(phase.get_values('flight_equilibrium.alpha', units='rad').T)

    print('coef of thrust')
    print(phase.get_values('flight_equilibrium.CT').T)

    print('fuel flow rate')
    print(phase.get_values('propulsion.dXdt:mass_fuel').T)

    print('max_thrust')
    print(phase.get_values('propulsion.max_thrust', units='N').T)

    print('tau')
    print(phase.get_values('propulsion.tau').T)

    print('dynamic pressure')
    print(phase.get_values('q_comp.q', units='Pa').T)

    print('S')
    print(phase.get_values('S', units='m**2').T)

    plt.show()

    return p
Example #13
0
phase0.set_state_options("v", fix_initial=True, fix_final=True, units="ft/s", rate_source="vdot", targets=["v"], lower=0)#, ref=25600, defect_ref=25600, ref0=2500

phase0.add_control("alpha", units="rad", opt=True, lower=-np.pi/2, upper=np.pi/2, targets=["alpha"])
phase0.add_control("beta", units="rad", opt=True, lower=-89*np.pi/180, upper=1*np.pi/180, targets=["beta"])

phase0.add_path_constraint("q", lower=0, upper=70, units="Btu/ft**2/s", ref=70)#

phase0.add_objective("theta", loc="final", ref=-1)

prob.driver = ScipyOptimizeDriver()
prob.driver.declare_coloring()
prob.driver.options["maxiter"] = 100

prob.setup(check=True)

prob.set_val("traj.phase0.states:h", phase0.interpolate(ys=[260000, 80000], nodes="state_input"), units="ft")
prob.set_val("traj.phase0.states:gamma", phase0.interpolate(ys=[-1*np.pi/180, -5*np.pi/180], nodes="state_input"), units="rad")
prob.set_val("traj.phase0.states:phi", phase0.interpolate(ys=[0, 75*np.pi/180], nodes="state_input"), units="rad")
prob.set_val("traj.phase0.states:psi", phase0.interpolate(ys=[90*np.pi/180, 10*np.pi/180], nodes="state_input"), units="rad")
prob.set_val("traj.phase0.states:theta", phase0.interpolate(ys=[0, 25*np.pi/180], nodes="state_input"), units="rad")
prob.set_val("traj.phase0.states:v", phase0.interpolate(ys=[25600, 2500], nodes="state_input"), units="ft/s")
prob.set_val("traj.phase0.t_initial", 0, units="s")
prob.set_val("traj.phase0.t_duration", 2000, units="s")
prob.set_val("traj.phase0.controls:alpha", phase0.interpolate(ys=[17.4*np.pi/180, 17.4*np.pi/180], nodes="control_input"), units="rad")
prob.set_val("traj.phase0.controls:beta", phase0.interpolate(ys=[-75*np.pi/180, 0*np.pi/180], nodes="control_input"), units="rad")

recorder = SqliteRecorder("reentry.sql")
prob.driver.add_recorder(recorder)

prob.run_driver()
# prob.run_model()
    def test_brachistochrone_for_docs_gauss_lobatto_without_simul_derivs(self):
        from openmdao.api import Problem, Group, pyOptSparseDriver, 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 = pyOptSparseDriver()
        p.driver.options['optimizer'] = 'SLSQP'

        phase = Phase('gauss-lobatto',
                      ode_class=BrachistochroneODE,
                      num_segments=100,
                      transcription_order=3,
                      compressed=True)

        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)
def min_time_climb_problem(num_seg=3,
                           transcription_order=5,
                           transcription='gauss-lobatto',
                           top_level_densejacobian=True):

    p = Problem(model=Group())

    p.driver = pyOptSparseDriver()
    p.driver.options['optimizer'] = 'SNOPT'
    p.driver.opt_settings['Major iterations limit'] = 500
    p.driver.opt_settings['Iterations limit'] = 1000000000
    p.driver.opt_settings['iSumm'] = 6
    p.driver.opt_settings['Major feasibility tolerance'] = 1.0E-10
    p.driver.opt_settings['Major optimality tolerance'] = 1.0E-10
    p.driver.opt_settings['Verify level'] = 1
    p.driver.opt_settings['Function precision'] = 1.0E-6
    p.driver.opt_settings['Linesearch tolerance'] = .1
    p.driver.options['dynamic_simul_derivs'] = True

    phase = Phase(transcription,
                  ode_class=MinTimeClimbODE,
                  num_segments=num_seg,
                  transcription_order=transcription_order)

    p.model.add_subsystem('phase', phase)

    phase.set_time_options(opt_initial=False,
                           duration_bounds=(100, 100),
                           duration_ref=100.0)

    phase.set_state_options('r',
                            fix_initial=True,
                            lower=0,
                            upper=1.0E8,
                            scaler=1.0E-4,
                            defect_scaler=1.0E-3,
                            units='m')

    phase.set_state_options('h',
                            lower=0,
                            upper=20000.0,
                            scaler=1.0E-3,
                            defect_scaler=1.0E-3,
                            units='m')

    phase.set_state_options('v',
                            lower=10.0,
                            upper=500.,
                            scaler=1.0E-2,
                            defect_scaler=1.0E-2,
                            units='m/s')

    phase.set_state_options('gam',
                            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,
                            units='kg')

    phase.add_control('alpha',
                      units='deg',
                      lower=-8.0,
                      upper=8.0,
                      scaler=1.0,
                      rate_continuity=True)

    phase.add_control('S', val=49.2386, units='m**2', dynamic=False, opt=False)
    phase.add_control('throttle',
                      val=1.0,
                      opt=True,
                      lower=0.,
                      upper=1.,
                      rate_continuity=False)

    phase.add_path_constraint(name='h',
                              lower=1e4,
                              upper=1e4,
                              ref=20000,
                              units='m')
    phase.add_path_constraint(name='aero.mach', lower=1.2, upper=1.2)

    phase.add_objective('time', loc='final', ref=-100.0)

    p.model.linear_solver = DirectSolver(assemble_jac=True)
    p.model.options['assembled_jac_type'] = 'csc'

    p.setup(mode='fwd', check=True)

    p['phase.t_initial'] = 0.0
    p['phase.t_duration'] = 2000.
    p['phase.states:r'] = phase.interpolate(ys=[0.0, 1e6], nodes='disc')
    p['phase.states:h'][:] = 1e4
    p['phase.states:v'][:] = 250.
    p['phase.states:gam'][:] = 0.
    p['phase.states:m'] = phase.interpolate(ys=[50e3, 49e3], nodes='disc')

    return p
    def test_two_phase_cannonball_for_docs(self):
        from openmdao.api import Problem, Group, IndepVarComp, DirectSolver, SqliteRecorder, \
            pyOptSparseDriver
        from openmdao.utils.assert_utils import assert_rel_error

        from dymos import Phase, Trajectory, Radau, GaussLobatto
        from dymos.examples.cannonball.cannonball_ode import CannonballODE

        from dymos.examples.cannonball.size_comp import CannonballSizeComp

        p = Problem(model=Group())

        p.driver = pyOptSparseDriver()
        p.driver.options['optimizer'] = 'SLSQP'
        p.driver.options['dynamic_simul_derivs'] = True

        external_params = p.model.add_subsystem('external_params', IndepVarComp())

        external_params.add_output('radius', val=0.10, units='m')
        external_params.add_output('dens', val=7.87, units='g/cm**3')

        external_params.add_design_var('radius', lower=0.01, upper=0.10, ref0=0.01, ref=0.10)

        p.model.add_subsystem('size_comp', CannonballSizeComp())

        traj = p.model.add_subsystem('traj', Trajectory())

        transcription = Radau(num_segments=5, order=3, compressed=True)
        ascent = Phase(ode_class=CannonballODE, transcription=transcription)

        ascent = traj.add_phase('ascent', ascent)

        # All initial states except flight path angle are fixed
        # Final flight path angle is fixed (we will set it to zero so that the phase ends at apogee)
        ascent.set_time_options(fix_initial=True, duration_bounds=(1, 100),
                                duration_ref=100, units='s')
        ascent.set_state_options('r', fix_initial=True, fix_final=False)
        ascent.set_state_options('h', fix_initial=True, fix_final=False)
        ascent.set_state_options('gam', fix_initial=False, fix_final=True)
        ascent.set_state_options('v', fix_initial=False, fix_final=False)

        # Limit the muzzle energy
        ascent.add_boundary_constraint('kinetic_energy.ke', loc='initial', units='J',
                                       upper=400000, lower=0, ref=100000, shape=(1,))

        # Second Phase (descent)
        transcription = GaussLobatto(num_segments=5, order=3, compressed=True)
        descent = Phase(ode_class=CannonballODE, transcription=transcription)

        traj.add_phase('descent', descent)

        # All initial states and time are free (they will be linked to the final states of ascent.
        # Final altitude is fixed (we will set it to zero so that the phase ends at ground impact)
        descent.set_time_options(initial_bounds=(.5, 100), duration_bounds=(.5, 100),
                                 duration_ref=100)
        descent.set_state_options('r', fix_initial=False, fix_final=False)
        descent.set_state_options('h', fix_initial=False, fix_final=True)
        descent.set_state_options('gam', fix_initial=False, fix_final=False)
        descent.set_state_options('v', fix_initial=False, fix_final=False)

        descent.add_objective('r', loc='final', scaler=-1.0)

        # Add internally-managed design parameters to the trajectory.
        traj.add_design_parameter('CD', val=0.5, units=None, opt=False)
        traj.add_design_parameter('CL', val=0.0, units=None, opt=False)
        traj.add_design_parameter('T', val=0.0, units='N', opt=False)
        traj.add_design_parameter('alpha', val=0.0, units='deg', opt=False)

        # Add externally-provided design parameters to the trajectory.
        traj.add_input_parameter('mass',
                                 target_params={'ascent': 'm', 'descent': 'm'},
                                 val=1.0)

        traj.add_input_parameter('S', val=0.005)

        # Link Phases (link time and all state variables)
        traj.link_phases(phases=['ascent', 'descent'], vars=['*'])

        # Issue Connections
        p.model.connect('external_params.radius', 'size_comp.radius')
        p.model.connect('external_params.dens', 'size_comp.dens')

        p.model.connect('size_comp.mass', 'traj.input_parameters:mass')
        p.model.connect('size_comp.S', 'traj.input_parameters:S')

        # Finish Problem Setup
        p.model.linear_solver = DirectSolver()

        p.driver.add_recorder(SqliteRecorder('ex_two_phase_cannonball.db'))

        p.setup(check=True)

        # Set Initial Guesses
        p.set_val('external_params.radius', 0.05, units='m')
        p.set_val('external_params.dens', 7.87, units='g/cm**3')

        p.set_val('traj.design_parameters:CD', 0.5)
        p.set_val('traj.design_parameters:CL', 0.0)
        p.set_val('traj.design_parameters:T', 0.0)

        p.set_val('traj.ascent.t_initial', 0.0)
        p.set_val('traj.ascent.t_duration', 10.0)

        p.set_val('traj.ascent.states:r', ascent.interpolate(ys=[0, 100], nodes='state_input'))
        p.set_val('traj.ascent.states:h', ascent.interpolate(ys=[0, 100], nodes='state_input'))
        p.set_val('traj.ascent.states:v', ascent.interpolate(ys=[200, 150], nodes='state_input'))
        p.set_val('traj.ascent.states:gam', ascent.interpolate(ys=[25, 0], nodes='state_input'),
                  units='deg')

        p.set_val('traj.descent.t_initial', 10.0)
        p.set_val('traj.descent.t_duration', 10.0)

        p.set_val('traj.descent.states:r', descent.interpolate(ys=[100, 200], nodes='state_input'))
        p.set_val('traj.descent.states:h', descent.interpolate(ys=[100, 0], nodes='state_input'))
        p.set_val('traj.descent.states:v', descent.interpolate(ys=[150, 200], nodes='state_input'))
        p.set_val('traj.descent.states:gam', descent.interpolate(ys=[0, -45], nodes='state_input'),
                  units='deg')

        p.run_driver()

        assert_rel_error(self, p.get_val('traj.descent.states:r')[-1],
                         3183.25, tolerance=1.0E-2)

        exp_out = traj.simulate()

        print('optimal radius: {0:6.4f} m '.format(p.get_val('external_params.radius',
                                                             units='m')[0]))
        print('cannonball mass: {0:6.4f} kg '.format(p.get_val('size_comp.mass',
                                                               units='kg')[0]))
        print('launch angle: {0:6.4f} '
              'deg '.format(p.get_val('traj.ascent.timeseries.states:gam',  units='deg')[0, 0]))
        print('maximum range: {0:6.4f} '
              'm '.format(p.get_val('traj.descent.timeseries.states:r')[-1, 0]))

        fig, axes = plt.subplots(nrows=1, ncols=1, figsize=(10, 6))

        time_imp = {'ascent': p.get_val('traj.ascent.timeseries.time'),
                    'descent': p.get_val('traj.descent.timeseries.time')}

        time_exp = {'ascent': exp_out.get_val('traj.ascent.timeseries.time'),
                    'descent': exp_out.get_val('traj.descent.timeseries.time')}

        r_imp = {'ascent': p.get_val('traj.ascent.timeseries.states:r'),
                 'descent': p.get_val('traj.descent.timeseries.states:r')}

        r_exp = {'ascent': exp_out.get_val('traj.ascent.timeseries.states:r'),
                 'descent': exp_out.get_val('traj.descent.timeseries.states:r')}

        h_imp = {'ascent': p.get_val('traj.ascent.timeseries.states:h'),
                 'descent': p.get_val('traj.descent.timeseries.states:h')}

        h_exp = {'ascent': exp_out.get_val('traj.ascent.timeseries.states:h'),
                 'descent': exp_out.get_val('traj.descent.timeseries.states:h')}

        axes.plot(r_imp['ascent'], h_imp['ascent'], 'bo')

        axes.plot(r_imp['descent'], h_imp['descent'], 'ro')

        axes.plot(r_exp['ascent'], h_exp['ascent'], 'b--')

        axes.plot(r_exp['descent'], h_exp['descent'], 'r--')

        axes.set_xlabel('range (m)')
        axes.set_ylabel('altitude (m)')

        fig, axes = plt.subplots(nrows=4, ncols=1, figsize=(10, 6))
        states = ['r', 'h', 'v', 'gam']
        for i, state in enumerate(states):
            x_imp = {'ascent': p.get_val('traj.ascent.timeseries.states:{0}'.format(state)),
                     'descent': p.get_val('traj.descent.timeseries.states:{0}'.format(state))}

            x_exp = {'ascent': exp_out.get_val('traj.ascent.timeseries.states:{0}'.format(state)),
                     'descent': exp_out.get_val('traj.descent.timeseries.states:{0}'.format(state))}

            axes[i].set_ylabel(state)

            axes[i].plot(time_imp['ascent'], x_imp['ascent'], 'bo')
            axes[i].plot(time_imp['descent'], x_imp['descent'], 'ro')
            axes[i].plot(time_exp['ascent'], x_exp['ascent'], 'b--')
            axes[i].plot(time_exp['descent'], x_exp['descent'], 'r--')

        params = ['CL', 'CD', 'T', 'alpha', 'm', 'S']
        fig, axes = plt.subplots(nrows=6, ncols=1, figsize=(12, 6))
        for i, param in enumerate(params):
            p_imp = {
                'ascent': p.get_val('traj.ascent.timeseries.traj_parameters:{0}'.format(param)),
                'descent': p.get_val('traj.descent.timeseries.traj_parameters:{0}'.format(param))}

            p_exp = {'ascent': exp_out.get_val('traj.ascent.timeseries.'
                                               'traj_parameters:{0}'.format(param)),
                     'descent': exp_out.get_val('traj.descent.timeseries.'
                                                'traj_parameters:{0}'.format(param))}

            axes[i].set_ylabel(param)

            axes[i].plot(time_imp['ascent'], p_imp['ascent'], 'bo')
            axes[i].plot(time_imp['descent'], p_imp['descent'], 'ro')
            axes[i].plot(time_exp['ascent'], p_exp['ascent'], 'b--')
            axes[i].plot(time_exp['descent'], p_exp['descent'], 'r--')

        plt.show()
Example #17
0
def brachistochrone_min_time(transcription='gauss-lobatto',
                             num_segments=8,
                             transcription_order=3,
                             run_driver=True,
                             compressed=True,
                             optimizer='SLSQP'):
    p = Problem(model=Group())

    # if optimizer == 'SNOPT':
    p.driver = pyOptSparseDriver()
    p.driver.options['optimizer'] = optimizer
    p.driver.options['dynamic_simul_derivs'] = True

    if transcription == 'gauss-lobatto':
        t = GaussLobatto(num_segments=num_segments,
                         order=transcription_order,
                         compressed=compressed)
    elif transcription == 'radau-ps':
        t = Radau(num_segments=num_segments,
                  order=transcription_order,
                  compressed=compressed)
    elif transcription == 'runge-kutta':
        t = RungeKutta(num_segments=num_segments,
                       order=transcription_order,
                       compressed=compressed)

    phase = Phase(ode_class=BrachistochroneODE, transcription=t)

    p.model.add_subsystem('phase0', phase)

    phase.set_time_options(fix_initial=True, duration_bounds=(.5, 10))

    phase.set_state_options('x',
                            fix_initial=True,
                            fix_final=False,
                            solve_segments=False)
    phase.set_state_options('y',
                            fix_initial=True,
                            fix_final=False,
                            solve_segments=False)
    phase.set_state_options('v',
                            fix_initial=True,
                            fix_final=False,
                            solve_segments=False)

    phase.add_control('theta',
                      continuity=True,
                      rate_continuity=True,
                      units='deg',
                      lower=0.01,
                      upper=179.9)

    phase.add_input_parameter('g', units='m/s**2', val=9.80665)

    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.model.linear_solver = DirectSolver()
    p.setup(check=True)

    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],
                                                   nodes='control_input')
    p['phase0.input_parameters:g'] = 9.80665

    p.run_model()

    if run_driver:
        p.run_driver()

    # Plot results
    if SHOW_PLOTS:
        exp_out = phase.simulate()

        fig, ax = plt.subplots()
        fig.suptitle('Brachistochrone Solution')

        x_imp = p.get_val('phase0.timeseries.states:x')
        y_imp = p.get_val('phase0.timeseries.states:y')

        x_exp = exp_out.get_val('phase0.timeseries.states:x')
        y_exp = exp_out.get_val('phase0.timeseries.states:y')

        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_phase')
        y_imp = p.get_val('phase0.timeseries.controls:theta')

        x_exp = exp_out.get_val('phase0.timeseries.time_phase')
        y_exp = exp_out.get_val('phase0.timeseries.controls:theta')

        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 (rad)')
        ax.grid(True)
        ax.legend(loc='lower right')

        plt.show()

    return p
Example #18
0
def escort_problem(optimizer='SLSQP',
                   num_seg=3,
                   transcription_order=5,
                   transcription='gauss-lobatto',
                   meeting_altitude=14000.,
                   climb_time=350.,
                   starting_mass=19030.468):

    p = Problem(model=Group())

    p.driver = pyOptSparseDriver()
    p.driver.options['optimizer'] = optimizer
    if optimizer == 'SNOPT':
        p.driver.opt_settings['Major iterations limit'] = 1000
        p.driver.opt_settings['Iterations limit'] = 100000000
        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-5
        p.driver.opt_settings['Verify level'] = -1
        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

    phase_class = _phase_map[transcription]

    climb = Phase('gauss-lobatto',
                  ode_class=MinTimeClimbODE,
                  num_segments=num_seg,
                  transcription_order=transcription_order)

    climb.set_time_options(duration_bounds=(50, climb_time),
                           duration_ref=100.0)

    climb.set_state_options('r',
                            fix_initial=True,
                            lower=0,
                            upper=1.0E6,
                            scaler=1.0E-3,
                            defect_scaler=1.0E-2,
                            units='m')

    climb.set_state_options('h',
                            fix_initial=True,
                            lower=0,
                            upper=20000.0,
                            scaler=1.0E-3,
                            defect_scaler=1.0E-3,
                            units='m')

    climb.set_state_options('v',
                            fix_initial=True,
                            lower=10.0,
                            scaler=1.0E-2,
                            defect_scaler=1.0E-2,
                            units='m/s')

    climb.set_state_options('gam',
                            fix_initial=True,
                            lower=-1.5,
                            upper=1.5,
                            ref=1.0,
                            defect_scaler=1.0,
                            units='rad')

    climb.set_state_options('m',
                            fix_initial=True,
                            lower=10.0,
                            upper=1.0E5,
                            scaler=1.0E-3,
                            defect_scaler=1.0E-3)

    climb.add_control('alpha',
                      units='deg',
                      lower=-8.0,
                      upper=8.0,
                      scaler=1.0,
                      rate_continuity=True)

    climb.add_control('S', val=49.2386, units='m**2', dynamic=False, opt=False)
    climb.add_control('Isp', val=5000.0, units='s', dynamic=False, opt=False)
    climb.add_control('throttle', val=1.0, dynamic=False, opt=False)

    climb.add_boundary_constraint('h',
                                  loc='final',
                                  equals=meeting_altitude,
                                  scaler=1.0E-3,
                                  units='m')
    climb.add_boundary_constraint('aero.mach',
                                  loc='final',
                                  equals=1.0,
                                  units=None)
    climb.add_boundary_constraint('gam', loc='final', equals=0.0, units='rad')

    # climb.add_boundary_constraint('time', loc='final', upper=climb_time, units='s')

    climb.add_path_constraint(name='h', lower=100.0, upper=20000, ref=20000)
    climb.add_path_constraint(name='aero.mach', lower=0.1, upper=1.8)

    # Minimize time at the end of the climb
    climb.set_objective('time', loc='final', ref=100.0)

    p.model.add_subsystem('climb', climb)

    escort = Phase('gauss-lobatto',
                   ode_class=MinTimeClimbODE,
                   num_segments=num_seg * 2,
                   transcription_order=transcription_order)

    escort.set_time_options(duration_bounds=(50, 10000),
                            opt_initial=True,
                            duration_ref=100.0)

    escort.set_state_options('r',
                             lower=0,
                             upper=1.0E6,
                             scaler=1.0E-3,
                             defect_scaler=1.0E-2,
                             units='m')

    escort.set_state_options('h',
                             lower=0,
                             upper=20000.0,
                             scaler=1.0E-3,
                             defect_scaler=1.0E-3,
                             units='m')

    escort.set_state_options('v',
                             lower=10.0,
                             scaler=1.0E-2,
                             defect_scaler=1.0E-2,
                             units='m/s')

    escort.set_state_options('gam',
                             lower=-1.5,
                             upper=1.5,
                             ref=1.0,
                             defect_scaler=1.0,
                             units='rad')

    escort.set_state_options('m',
                             lower=10.0,
                             upper=1.0E5,
                             scaler=1.0E-3,
                             defect_scaler=1.0E-3)

    escort.add_control('alpha',
                       units='deg',
                       lower=-8.0,
                       upper=8.0,
                       scaler=1.0,
                       rate_continuity=True)

    escort.add_control('S',
                       val=49.2386,
                       units='m**2',
                       dynamic=False,
                       opt=False)
    escort.add_control('Isp', val=1600.0, units='s', dynamic=False, opt=False)

    escort.add_control('throttle', val=1.0, lower=0., upper=1., opt=True)
    # escort.add_control('throttle', val=1.0, dynamic=False, opt=False)

    # escort.add_boundary_constraint('h', loc='final', equals=20000, scaler=1.0E-3, units='m')
    # escort.add_boundary_constraint('aero.mach', loc='final', equals=1.0, units=None)
    # escort.add_boundary_constraint('gam', loc='final', equals=0.0, units='rad')
    escort.add_boundary_constraint('m',
                                   loc='final',
                                   equals=15000.0,
                                   units='kg')

    escort.add_path_constraint(name='h',
                               lower=meeting_altitude,
                               upper=meeting_altitude,
                               ref=meeting_altitude)
    escort.add_path_constraint(name='aero.mach', equals=1.0)

    # Maximize distance at the end of the escort
    # escort.set_objective('r', loc='final', ref=-1e5)

    p.model.add_subsystem('escort', escort)

    # Connect the phases
    linkage_comp = PhaseLinkageComp()
    linkage_comp.add_linkage(name='L01',
                             vars=['t'],
                             units='s',
                             equals=0.0,
                             linear=True)
    linkage_comp.add_linkage(name='L01',
                             vars=['r'],
                             units='m',
                             equals=0.0,
                             linear=True)
    linkage_comp.add_linkage(name='L01',
                             vars=['h'],
                             units='m',
                             equals=0.0,
                             linear=True)
    linkage_comp.add_linkage(name='L01',
                             vars=['v'],
                             units='m/s',
                             equals=0.0,
                             linear=True)
    linkage_comp.add_linkage(name='L01',
                             vars=['gam'],
                             units='rad',
                             equals=0.0,
                             linear=True)
    linkage_comp.add_linkage(name='L01',
                             vars=['m'],
                             units='kg',
                             equals=0.0,
                             linear=True)
    linkage_comp.add_linkage(name='L01',
                             vars=['alpha'],
                             units='rad',
                             equals=0.0,
                             linear=True)
    linkage_comp.add_linkage(name='L01',
                             vars=['throttle'],
                             equals=0.0,
                             linear=True)

    p.model.connect('climb.time++', 'linkages.L01_t:lhs')
    p.model.connect('escort.time--', 'linkages.L01_t:rhs')

    p.model.connect('climb.states:r++', 'linkages.L01_r:lhs')
    p.model.connect('escort.states:r--', 'linkages.L01_r:rhs')

    p.model.connect('climb.states:h++', 'linkages.L01_h:lhs')
    p.model.connect('escort.states:h--', 'linkages.L01_h:rhs')
    #
    p.model.connect('climb.states:v++', 'linkages.L01_v:lhs')
    p.model.connect('escort.states:v--', 'linkages.L01_v:rhs')
    #
    p.model.connect('climb.states:gam++', 'linkages.L01_gam:lhs')
    p.model.connect('escort.states:gam--', 'linkages.L01_gam:rhs')

    p.model.connect('climb.states:m++', 'linkages.L01_m:lhs')
    p.model.connect('escort.states:m--', 'linkages.L01_m:rhs')

    p.model.connect('climb.controls:alpha++', 'linkages.L01_alpha:lhs')
    p.model.connect('escort.controls:alpha--', 'linkages.L01_alpha:rhs')

    p.model.connect('climb.controls:throttle++', 'linkages.L01_throttle:lhs')
    p.model.connect('escort.controls:throttle--', 'linkages.L01_throttle:rhs')

    p.model.add_subsystem('linkages', linkage_comp)

    p.model.linear_solver = DirectSolver(assemble_jac=True)
    p.model.options['assembled_jac_type'] = 'csc'

    # p.driver.add_recorder(SqliteRecorder('escort.db'))

    p.setup(mode='fwd', check=True)

    p['climb.t_initial'] = 0.0
    p['climb.t_duration'] = 200.
    p['climb.states:r'] = climb.interpolate(ys=[0.0, 111319.54], nodes='disc')
    p['climb.states:h'] = climb.interpolate(ys=[100.0, 20000.0], nodes='disc')
    p['climb.states:v'] = climb.interpolate(ys=[135.964, 283.159],
                                            nodes='disc')
    p['climb.states:gam'] = climb.interpolate(ys=[0.0, 0.0], nodes='disc')
    p['climb.states:m'] = climb.interpolate(ys=[starting_mass, 16841.431],
                                            nodes='disc')
    p['climb.controls:alpha'] = climb.interpolate(ys=[0.0, 0.0], nodes='all')

    p['escort.t_initial'] = 200.
    p['escort.t_duration'] = 1000.
    p['escort.states:r'] = escort.interpolate(ys=[111319.54, 400000.],
                                              nodes='disc')
    p['escort.states:h'] = escort.interpolate(
        ys=[meeting_altitude, meeting_altitude], nodes='disc')
    p['escort.states:v'] = escort.interpolate(ys=[250., 250.], nodes='disc')
    p['escort.states:gam'] = escort.interpolate(ys=[0.0, 0.0], nodes='disc')
    p['escort.states:m'] = escort.interpolate(ys=[17000., 15000.],
                                              nodes='disc')
    p['escort.controls:alpha'] = escort.interpolate(ys=[0.0, 0.0], nodes='all')

    return p
Example #19
0
    def test_battery_power(self):
        """
            for battery explicit integration testings
        """
        _, local_opt = set_pyoptsparse_opt('SNOPT')
        if local_opt != 'SNOPT':
            raise unittest.SkipTest("pyoptsparse is not providing SNOPT")

        p = om.Problem()

        p.driver = om.pyOptSparseDriver()
        p.driver.options['optimizer'] = 'SNOPT'
        p.driver.opt_settings['Major iterations limit'] = 100
        p.driver.opt_settings['Major optimality tolerance'] = 5.0E-3
        p.driver.opt_settings['Major feasibility tolerance'] = 1e-6
        p.driver.opt_settings['iSumm'] = 6

        transcription = Radau(num_segments=15, order=3, compressed=True)

        phase0 = Phase(transcription=transcription, ode_class=BatteryGroup)

        phase0.set_time_options(fix_initial=True, duration_bounds=(30, 30))

        p.model.add_subsystem(name='phase0', subsys=phase0)

        phase0.add_state('SOC',
                         fix_initial=True,
                         rate_source='dXdt:SOC',
                         lower=0.0,
                         upper=1.)
        phase0.add_state('U_Th',
                         units='V',
                         fix_initial=False,
                         rate_source='dXdt:V_{thev}',
                         lower=0.0,
                         upper=5.0)

        # phase0.add_parameter('P_out', units='W', opt=False)

        # phase0.add_boundary_constraint('U_pack', units='V', loc='initial', equals=5100)

        phase0.add_objective('time', loc='final', ref=1)

        p.model.linear_solver = om.DirectSolver(assemble_jac=True)

        phase0.add_timeseries_output('Q_{batt}',
                                     output_name='Q_{batt}',
                                     units='W')
        # phase0.add_timeseries_output('U_pack', output_name='V', units='V')

        p.setup()

        # p.check_partials()

        T0 = 10 + 273

        p['phase0.t_initial'] = 0.0
        p['phase0.t_duration'] = 30

        p['phase0.states:SOC'] = phase0.interpolate(ys=[1.0, 0.0],
                                                    nodes='state_input')
        p['phase0.states:U_Th'] = phase0.interpolate(ys=[0.1, 0.1],
                                                     nodes='state_input')
        # p['phase0.parameters:P_out'][:] = 72000.

        p.run_driver()

        fig, ax = plt.subplots(3, 1, sharex=True)
        fig.suptitle('Temperature Plots')

        t_opt = p.get_val('phase0.timeseries.time')
        SOC_opt = p.get_val('phase0.timeseries.states:SOC', units=None)

        Q_batt_opt = p.get_val('phase0.timeseries.Q_{batt}', units='kW')

        ax[1].plot(t_opt, Q_batt_opt * 128 * 40, 'r', label='$Q_{cell}$')

        ax[2].plot(t_opt, SOC_opt, 'r', label='$SOC$')

        #spot check final values
        # assert_rel_error(self, T_batt_opt[-1], 1.25934406, tolerance=1.0E-6)

        # ax[3].plot(t_opt, V_opt, 'r', label='$Voltage$')

        # axarr = fig.add_subplot(1, 2, 2)
        # axarr.plot(sim_out.get_values('time'),sim_out.get_values('electric.battery.I_Li'), 'b')
        # # # axarr.plot(p['phase0.state_interp.state_col:r'],
        # # #            p['phase0.controls:h'], 'bo', ms=4)
        # axarr.set_ylabel('I_Li, amps')
        # axarr.set_xlabel('time, s')
        # axarr.axes.get_xaxis().set_visible(True)

        import matplotlib
        matplotlib.use(
            'agg')  # <--- comment out if you want to show this plot.
        plt.show()
def thermal_mission_problem(num_seg=5, transcription_order=3, meeting_altitude=20000., Q_env=0., Q_sink=0., Q_out=0., m_recirculated=0., opt_m_recirculated=False, opt_m_burn=False, opt_throttle=True, engine_heat_coeff=0., pump_heat_coeff=0., T=None, T_o=None, opt_m=False, m_initial=20.e3, transcription='gauss-lobatto'):

    p = Problem(model=Group())

    p.driver = pyOptSparseDriver()
    p.driver.options['optimizer'] = 'SNOPT'
    p.driver.opt_settings['Major iterations limit'] = 5000
    p.driver.opt_settings['Iterations limit'] = 5000000000000000
    p.driver.opt_settings['iSumm'] = 6
    p.driver.opt_settings['Major feasibility tolerance'] = 1.0E-8
    p.driver.opt_settings['Major optimality tolerance'] = 1.0E-8
    p.driver.opt_settings['Verify level'] = -1
    p.driver.opt_settings['Linesearch tolerance'] = .1
    p.driver.opt_settings['Major step limit'] = .1
    p.driver.options['dynamic_simul_derivs'] = True

    phase = Phase(transcription, ode_class=ThermalMissionODE,
                        ode_init_kwargs={'engine_heat_coeff':engine_heat_coeff, 'pump_heat_coeff':pump_heat_coeff}, num_segments=num_seg,
                        transcription_order=transcription_order)

    p.model.add_subsystem('phase', phase)

    phase.set_time_options(opt_initial=False, 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=5.0E-0, 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=not opt_m, lower=15.e3, upper=80e3,
                            scaler=1.0E-3, defect_scaler=1.0E-3, units='kg')

    phase.add_control('alpha', units='deg', lower=-8.0, upper=8.0, scaler=1.0,
                      rate_continuity=True)

    phase.add_design_parameter('S', val=1., units='m**2', opt=False)

    if opt_throttle:
        phase.add_control('throttle', val=1.0, lower=0.0, upper=1.0, opt=True, rate_continuity=True)
    else:
        phase.add_design_parameter('throttle', val=1.0, opt=False)

    phase.add_design_parameter('W0', val=10.5e3, opt=False, units='kg')

    phase.add_boundary_constraint('h', loc='final', equals=meeting_altitude, scaler=1.0E-3, units='m')
    phase.add_boundary_constraint('aero.mach', loc='final', equals=1., 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='time', upper=110.)

    # Minimize time at the end of the phase
    phase.add_objective('time', loc='final', ref=100.0)
    # phase.add_objective('energy', loc='final', ref=100.0)
    # phase.add_objective('m', loc='final', ref=-10000.0)

    # Set the state options for mass, temperature, and energy.
    phase.set_state_options('T', fix_initial=True, ref=300, defect_scaler=1e-2)
    phase.set_state_options('energy', fix_initial=True, ref=10e3, defect_scaler=1e-4)

    # Allow the optimizer to vary the fuel flow
    if opt_m_recirculated:
        phase.add_control('m_recirculated', val=m_recirculated, lower=0., opt=True, rate_continuity=True, ref=20.)
    else:
        phase.add_control('m_recirculated', val=m_recirculated, opt=False)

    phase.add_design_parameter('Q_env', val=Q_env, opt=False)
    phase.add_design_parameter('Q_sink', val=Q_sink, opt=False)
    phase.add_design_parameter('Q_out', val=Q_out, opt=False)

    # Constrain the temperature, 2nd derivative of fuel mass in the tank, and make
    # sure that the amount recirculated is at least 0, otherwise we'd burn
    # more fuel than we pumped.
    if opt_m_recirculated:
        phase.add_path_constraint('m_flow', lower=0., upper=50., units='kg/s', ref=10.)

    if T is not None:
        phase.add_path_constraint('T', upper=T, units='K')

    if T_o is not None:
        phase.add_path_constraint('T_o', upper=T_o, units='K', ref=300.)

    # phase.add_path_constraint('m_flow', lower=0., upper=20., units='kg/s', ref=10.)

    p.setup(mode='fwd', check=True)

    p['phase.t_initial'] = 0.0
    p['phase.t_duration'] = 200.
    p['phase.states:r'] = phase.interpolate(ys=[0.0, 111319.54], nodes='state_input')
    p['phase.states:h'] = phase.interpolate(ys=[100.0, meeting_altitude], nodes='state_input')
    # p['phase.states:h'][:] = 10000.

    p['phase.states:v'] = phase.interpolate(ys=[135.964, 283.159], nodes='state_input')
    # p['phase.states:v'][:] = 200.
    p['phase.states:gam'] = phase.interpolate(ys=[0.0, 0.0], nodes='state_input')
    p['phase.states:m'] = phase.interpolate(ys=[m_initial, 12.e3], nodes='state_input')
    p['phase.controls:alpha'] = phase.interpolate(ys=[1., 1.], nodes='control_input')

    # Give initial values for the phase states, controls, and time
    p['phase.states:T'] = 310.

    return p
    def test_cruise_results_gl(self):
        p = Problem(model=Group())
        if optimizer == 'SNOPT':
            p.driver = pyOptSparseDriver()
            p.driver.options['optimizer'] = optimizer
            p.driver.options['dynamic_simul_derivs'] = True
            p.driver.opt_settings['Major iterations limit'] = 100
            p.driver.opt_settings['Major step limit'] = 0.05
            p.driver.opt_settings['Major feasibility tolerance'] = 1.0E-6
            p.driver.opt_settings['Major optimality tolerance'] = 1.0E-6
            p.driver.opt_settings["Linesearch tolerance"] = 0.10
            p.driver.opt_settings['iSumm'] = 6
            p.driver.opt_settings['Verify level'] = 3
        else:
            p.driver = ScipyOptimizeDriver()
            p.driver.options['dynamic_simul_derivs'] = True

        transcription = GaussLobatto(num_segments=1,
                                     order=13,
                                     compressed=False)
        phase = Phase(ode_class=AircraftODE, transcription=transcription)
        p.model.add_subsystem('phase0', phase)

        # Pass Reference Area from an external source
        assumptions = p.model.add_subsystem('assumptions', IndepVarComp())
        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')

        phase.set_time_options(initial_bounds=(0, 0),
                               duration_bounds=(3600, 3600),
                               duration_ref=3600)

        phase.set_state_options('range',
                                units='km',
                                fix_initial=True,
                                fix_final=False,
                                scaler=0.01,
                                defect_scaler=0.01)
        phase.set_state_options('mass_fuel',
                                fix_final=True,
                                upper=20000.0,
                                lower=0.0,
                                scaler=1.0E-4,
                                defect_scaler=1.0E-2)
        phase.set_state_options('alt', units='km', fix_initial=True)

        phase.add_control('mach', units=None, opt=False)
        phase.add_control('climb_rate', units='m/s', opt=False)

        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,
                                  shape=(1, ))

        phase.add_timeseries_output('tas_comp.TAS', units='m/s')

        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('time', loc='final', ref=3600)

        p.model.linear_solver = DirectSolver()

        p.setup()

        p['phase0.t_initial'] = 0.0
        p['phase0.t_duration'] = 1.515132 * 3600.0
        p['phase0.states:range'] = phase.interpolate(ys=(0, 1296.4),
                                                     nodes='state_input')
        p['phase0.states:mass_fuel'] = phase.interpolate(ys=(12236.594555, 0),
                                                         nodes='state_input')
        p['phase0.states:alt'] = 5.0
        p['phase0.controls:mach'] = 0.8
        p['phase0.controls:climb_rate'] = 0.0

        p['assumptions.S'] = 427.8
        p['assumptions.mass_empty'] = 0.15E6
        p['assumptions.mass_payload'] = 84.02869 * 400

        p.run_driver()

        time = p.get_val('phase0.timeseries.time')
        tas = p.get_val('phase0.timeseries.TAS', units='km/s')
        range = p.get_val('phase0.timeseries.states:range')

        assert_rel_error(self, range, tas * time, tolerance=1.0E-4)
    def test_double_integrator_for_docs(self):
        import numpy as np
        import matplotlib.pyplot as plt
        from openmdao.api import Problem, Group, ScipyOptimizeDriver, DirectSolver
        from dymos import Phase
        from dymos.examples.double_integrator.double_integrator_ode import DoubleIntegratorODE

        p = Problem(model=Group())
        p.driver = ScipyOptimizeDriver()
        p.driver.options['dynamic_simul_derivs'] = True

        phase = Phase('gauss-lobatto',
                      ode_class=DoubleIntegratorODE,
                      num_segments=20,
                      transcription_order=3,
                      compressed=True)

        p.model.add_subsystem('phase0', phase)

        phase.set_time_options(initial_bounds=(0, 0),
                               duration_bounds=(1.0, 1.0))

        phase.set_state_options('x', fix_initial=True)
        phase.set_state_options('v', fix_initial=True, fix_final=True)

        phase.add_control('u',
                          units='m/s**2',
                          scaler=0.01,
                          continuity=False,
                          rate_continuity=False,
                          rate2_continuity=False,
                          lower=-1.0,
                          upper=1.0)

        # Maximize distance travelled in one second.
        phase.add_objective('x', loc='final', scaler=-1)

        p.model.linear_solver = DirectSolver(assemble_jac=True)

        p.setup(check=True)

        p['phase0.t_initial'] = 0.0
        p['phase0.t_duration'] = 1.0

        p['phase0.states:x'] = phase.interpolate(ys=[0, 0.25],
                                                 nodes='state_input')
        p['phase0.states:v'] = phase.interpolate(ys=[0, 0],
                                                 nodes='state_input')
        p['phase0.controls:u'] = phase.interpolate(ys=[1, -1],
                                                   nodes='control_input')

        p.run_driver()

        exp_out = phase.simulate(times=np.linspace(p['phase0.t_initial'],
                                                   p['phase0.t_duration'],
                                                   100),
                                 record=False)

        # Plot results
        fig, axes = plt.subplots(3, 1)
        fig.suptitle('Double Integrator Direct Collocation Solution')

        t_imp = phase.get_values('time', nodes='all')
        x_imp = phase.get_values('x', nodes='all')
        v_imp = phase.get_values('v', nodes='all')
        u_imp = phase.get_values('u', nodes='all')

        t_exp = exp_out.get_values('time')
        x_exp = exp_out.get_values('x')
        v_exp = exp_out.get_values('v')
        u_exp = exp_out.get_values('u')

        axes[0].plot(t_imp, x_imp, 'ro', label='implicit')
        axes[0].plot(t_exp, x_exp, 'b-', label='explicit')

        axes[0].set_xlabel('time (s)')
        axes[0].set_ylabel('x (m)')
        axes[0].grid(True)
        axes[0].legend(loc='best')

        axes[1].plot(t_imp, v_imp, 'ro', label='implicit')
        axes[1].plot(t_exp, v_exp, 'b-', label='explicit')

        axes[1].set_xlabel('time (s)')
        axes[1].set_ylabel('v (m/s)')
        axes[1].grid(True)
        axes[1].legend(loc='best')

        axes[2].plot(t_imp, u_imp, 'ro', label='implicit')
        axes[2].plot(t_exp, u_exp, 'b-', label='explicit')

        axes[2].set_xlabel('time (s)')
        axes[2].set_ylabel('u (m/s**2)')
        axes[2].grid(True)
        axes[2].legend(loc='best')

        plt.show()
Example #23
0
    def setUpClass(cls):

        cls.traj = Trajectory()
        p = Problem(model=cls.traj)

        # Since we're only testing features like get_values that don't rely on a converged
        # solution, no driver is attached.  We'll just invoke run_model.

        # First Phase (burn)
        burn1 = Phase('gauss-lobatto',
                      ode_class=FiniteBurnODE,
                      num_segments=4,
                      transcription_order=3,
                      compressed=True)

        cls.traj.add_phase('burn1', burn1)

        burn1.set_time_options(fix_initial=True, duration_bounds=(.5, 10))
        burn1.set_state_options('r', fix_initial=True, fix_final=False)
        burn1.set_state_options('theta', fix_initial=True, fix_final=False)
        burn1.set_state_options('vr',
                                fix_initial=True,
                                fix_final=False,
                                defect_scaler=0.1)
        burn1.set_state_options('vt',
                                fix_initial=True,
                                fix_final=False,
                                defect_scaler=0.1)
        burn1.set_state_options('accel', fix_initial=True, fix_final=False)
        burn1.set_state_options('deltav', fix_initial=True, fix_final=False)
        burn1.add_control('u1',
                          rate_continuity=True,
                          rate2_continuity=True,
                          units='deg')
        burn1.add_design_parameter('c', opt=False, val=1.5)

        # Second Phase (Coast)

        coast = Phase('gauss-lobatto',
                      ode_class=FiniteBurnODE,
                      num_segments=10,
                      transcription_order=3,
                      compressed=True)

        cls.traj.add_phase('coast', coast)

        coast.set_time_options(initial_bounds=(0.5, 20),
                               duration_bounds=(.5, 10))
        coast.set_state_options('r', fix_initial=False, fix_final=False)
        coast.set_state_options('theta', fix_initial=False, fix_final=False)
        coast.set_state_options('vr', fix_initial=False, fix_final=False)
        coast.set_state_options('vt', fix_initial=False, fix_final=False)
        coast.set_state_options('accel', fix_initial=True, fix_final=True)
        coast.set_state_options('deltav', fix_initial=False, fix_final=False)
        coast.add_control('u1', opt=False, val=0.0, units='deg')
        coast.add_design_parameter('c', opt=False, val=1.5)

        # Third Phase (burn)

        burn2 = Phase('gauss-lobatto',
                      ode_class=FiniteBurnODE,
                      num_segments=3,
                      transcription_order=3,
                      compressed=True)

        cls.traj.add_phase('burn2', burn2)

        burn2.set_time_options(initial_bounds=(0.5, 20),
                               duration_bounds=(.5, 10))
        burn2.set_state_options('r',
                                fix_initial=False,
                                fix_final=True,
                                defect_scaler=1.0)
        burn2.set_state_options('theta',
                                fix_initial=False,
                                fix_final=False,
                                defect_scaler=1.0)
        burn2.set_state_options('vr',
                                fix_initial=False,
                                fix_final=True,
                                defect_scaler=0.1)
        burn2.set_state_options('vt',
                                fix_initial=False,
                                fix_final=True,
                                defect_scaler=0.1)
        burn2.set_state_options('accel',
                                fix_initial=False,
                                fix_final=False,
                                defect_scaler=1.0)
        burn2.set_state_options('deltav',
                                fix_initial=False,
                                fix_final=False,
                                defect_scaler=1.0)
        burn2.add_control('u1',
                          rate_continuity=True,
                          rate2_continuity=True,
                          units='deg',
                          ref0=0,
                          ref=10)
        burn2.add_design_parameter('c', opt=False, val=1.5)

        burn2.add_objective('deltav', loc='final')

        # Link Phases
        cls.traj.link_phases(phases=['burn1', 'coast', 'burn2'],
                             vars=['time', 'r', 'theta', 'vr', 'vt', 'deltav'])
        cls.traj.link_phases(phases=['burn1', 'burn2'], vars=['accel'])

        # Finish Problem Setup

        p.model.options['assembled_jac_type'] = 'csc'
        p.model.linear_solver = DirectSolver(assemble_jac=True)

        p.model.add_recorder(SqliteRecorder('test_trajectory_rec.db'))

        p.setup(check=True)

        # Set Initial Guesses

        p.set_val('burn1.t_initial', value=0.0)
        p.set_val('burn1.t_duration', value=2.25)

        p.set_val('burn1.states:r',
                  value=burn1.interpolate(ys=[1, 1.5], nodes='state_input'))
        p.set_val('burn1.states:theta',
                  value=burn1.interpolate(ys=[0, 1.7], nodes='state_input'))
        p.set_val('burn1.states:vr',
                  value=burn1.interpolate(ys=[0, 0], nodes='state_input'))
        p.set_val('burn1.states:vt',
                  value=burn1.interpolate(ys=[1, 1], nodes='state_input'))
        p.set_val('burn1.states:accel',
                  value=burn1.interpolate(ys=[0.1, 0], nodes='state_input'))
        p.set_val('burn1.states:deltav',
                  value=burn1.interpolate(ys=[0, 0.1], nodes='state_input'))
        p.set_val('burn1.controls:u1',
                  value=burn1.interpolate(ys=[-3.5, 13.0],
                                          nodes='control_input'))
        p.set_val('burn1.design_parameters:c', value=1.5)

        p.set_val('coast.t_initial', value=2.25)
        p.set_val('coast.t_duration', value=3.0)

        p.set_val('coast.states:r',
                  value=coast.interpolate(ys=[1.3, 1.5], nodes='state_input'))
        p.set_val('coast.states:theta',
                  value=coast.interpolate(ys=[2.1767, 1.7],
                                          nodes='state_input'))
        p.set_val('coast.states:vr',
                  value=coast.interpolate(ys=[0.3285, 0], nodes='state_input'))
        p.set_val('coast.states:vt',
                  value=coast.interpolate(ys=[0.97, 1], nodes='state_input'))
        p.set_val('coast.states:accel',
                  value=coast.interpolate(ys=[0, 0], nodes='state_input'))
        p.set_val('coast.controls:u1',
                  value=coast.interpolate(ys=[0, 0], nodes='control_input'))
        p.set_val('coast.design_parameters:c', value=1.5)

        p.set_val('burn2.t_initial', value=5.25)
        p.set_val('burn2.t_duration', value=1.75)

        p.set_val('burn2.states:r',
                  value=burn2.interpolate(ys=[1, 3], nodes='state_input'))
        p.set_val('burn2.states:theta',
                  value=burn2.interpolate(ys=[0, 4.0], nodes='state_input'))
        p.set_val('burn2.states:vr',
                  value=burn2.interpolate(ys=[0, 0], nodes='state_input'))
        p.set_val('burn2.states:vt',
                  value=burn2.interpolate(ys=[1, np.sqrt(1 / 3)],
                                          nodes='state_input'))
        p.set_val('burn2.states:accel',
                  value=burn2.interpolate(ys=[0.1, 0], nodes='state_input'))
        p.set_val('burn2.states:deltav',
                  value=burn2.interpolate(ys=[0.1, 0.2], nodes='state_input'))
        p.set_val('burn2.controls:u1',
                  value=burn2.interpolate(ys=[1, 1], nodes='control_input'))
        p.set_val('burn2.design_parameters:c', value=1.5)

        p.run_model()
Example #24
0
                               units='rad')

phase.add_objective('time', loc='final', scaler=1.0)

p.model.add_constraint('phase0.rhs_disc.pairwise.dist', lower=20.0)
p.setup()

phase = p.model.phase0

p['phase0.t_initial'] = 0.0
p['phase0.t_duration'] = max_time / 2.0

for i in range(n_traj):
    theta, heading, start_x, start_y, end_x, end_y = locs[i]

    p['phase0.states:p%dx' % i] = phase.interpolate(ys=[start_x, end_x],
                                                    nodes='state_input')
    p['phase0.states:p%dy' % i] = phase.interpolate(ys=[start_y, end_y],
                                                    nodes='state_input')

    #p['phase0.states:p%dmass' % i] = phase.interpolate(ys=[start_mass, start_mass], nodes='state_input')
    #p['phase0.states:L%d' % i] = phase.interpolate(ys=[0, 0], nodes='state_input')

p.run_driver()

exp_out = phase.simulate()

import matplotlib.pyplot as plt
circle = plt.Circle((0, 0), r_space, fill=False)
plt.gca().add_artist(circle)

t = exp_out.get_val('phase0.timeseries.time')
Example #25
0
    def test_timeseries_gl(self):
        p = Problem(model=Group())

        p.driver = ScipyOptimizeDriver()
        p.driver.options['dynamic_simul_derivs'] = True

        phase = Phase(ode_class=BrachistochroneODE,
                      transcription=GaussLobatto(num_segments=8,
                                                 order=3,
                                                 compressed=True))

        p.model.add_subsystem('phase0', phase)

        phase.set_time_options(fix_initial=True, 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, 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)

        # Minimize time at the end of the phase
        phase.add_objective('time_phase', loc='final', scaler=10)

        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'] = 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],
                                                       nodes='control_input')
        p['phase0.design_parameters:g'] = 9.80665

        p.run_driver()

        gd = phase.options['transcription'].grid_data
        state_input_idxs = gd.subset_node_indices['state_input']
        control_input_idxs = gd.subset_node_indices['control_input']
        col_idxs = gd.subset_node_indices['col']

        assert_rel_error(self, p.get_val('phase0.time'),
                         p.get_val('phase0.timeseries.time')[:, 0])

        assert_rel_error(self, p.get_val('phase0.time_phase'),
                         p.get_val('phase0.timeseries.time_phase')[:, 0])

        for state in ('x', 'y', 'v'):
            assert_rel_error(
                self, p.get_val('phase0.states:{0}'.format(state)),
                p.get_val('phase0.timeseries.states:'
                          '{0}'.format(state))[state_input_idxs])

            assert_rel_error(
                self,
                p.get_val('phase0.state_interp.state_col:{0}'.format(state)),
                p.get_val('phase0.timeseries.states:'
                          '{0}'.format(state))[col_idxs])

        for control in ('theta', ):
            assert_rel_error(
                self, p.get_val('phase0.controls:{0}'.format(control)),
                p.get_val('phase0.timeseries.controls:'
                          '{0}'.format(control))[control_input_idxs])

        for dp in ('g', ):
            for i in range(gd.subset_num_nodes['all']):
                assert_rel_error(
                    self,
                    p.get_val('phase0.design_parameters:{0}'.format(dp))[0, :],
                    p.get_val('phase0.timeseries.design_parameters:{0}'.format(
                        dp))[i])
Example #26
0
    def test_brachistochrone_integrated_control_radau_ps(self):
        import numpy as np
        from openmdao.api import Problem, Group, ScipyOptimizeDriver, DirectSolver
        from openmdao.utils.assert_utils import assert_rel_error
        from dymos import Phase, Radau

        p = Problem(model=Group())
        p.driver = ScipyOptimizeDriver()

        phase = Phase(ode_class=BrachistochroneODE,
                      transcription=Radau(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.set_state_options('theta', targets='theta', fix_initial=False)

        phase.add_control('theta_dot',
                          units='deg/s',
                          rate_continuity=True,
                          lower=0,
                          upper=60)

        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()
        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.states:theta'] = np.radians(
            phase.interpolate(ys=[0.05, 100.0], nodes='state_input'))
        p['phase0.controls:theta_dot'] = phase.interpolate(
            ys=[50, 50], nodes='control_input')

        # Solve for the optimal trajectory
        p.run_driver()

        # Test the results
        assert_rel_error(self,
                         p.get_val('phase0.timeseries.time')[-1],
                         1.8016,
                         tolerance=1.0E-3)

        sim_out = phase.simulate(times_per_seg=20)

        x_sol = p.get_val('phase0.timeseries.states:x')
        y_sol = p.get_val('phase0.timeseries.states:y')
        v_sol = p.get_val('phase0.timeseries.states:v')
        theta_sol = p.get_val('phase0.timeseries.states:theta')
        theta_dot_sol = p.get_val('phase0.timeseries.controls:theta_dot')
        time_sol = p.get_val('phase0.timeseries.time')

        x_sim = sim_out.get_val('phase0.timeseries.states:x')
        y_sim = sim_out.get_val('phase0.timeseries.states:y')
        v_sim = sim_out.get_val('phase0.timeseries.states:v')
        theta_sim = sim_out.get_val('phase0.timeseries.states:theta')
        theta_dot_sim = sim_out.get_val('phase0.timeseries.controls:theta_dot')
        time_sim = sim_out.get_val('phase0.timeseries.time')

        x_interp = interp1d(time_sim[:, 0], x_sim[:, 0])
        y_interp = interp1d(time_sim[:, 0], y_sim[:, 0])
        v_interp = interp1d(time_sim[:, 0], v_sim[:, 0])
        theta_interp = interp1d(time_sim[:, 0], theta_sim[:, 0])
        theta_dot_interp = interp1d(time_sim[:, 0], theta_dot_sim[:, 0])

        assert_rel_error(self, x_interp(time_sol), x_sol, tolerance=1.0E-5)
        assert_rel_error(self, y_interp(time_sol), y_sol, tolerance=1.0E-5)
        assert_rel_error(self, v_interp(time_sol), v_sol, tolerance=1.0E-5)
        assert_rel_error(self,
                         theta_interp(time_sol),
                         theta_sol,
                         tolerance=1.0E-5)
        assert_rel_error(self,
                         theta_dot_interp(time_sol),
                         theta_dot_sol,
                         tolerance=1.0E-5)
Example #27
0
    def test_two_burn_orbit_raise_gl_rk_gl_constrained(self):
        import numpy as np

        import matplotlib.pyplot as plt

        from openmdao.api import Problem, Group, pyOptSparseDriver, DirectSolver
        from openmdao.utils.assert_utils import assert_rel_error
        from openmdao.utils.general_utils import set_pyoptsparse_opt

        from dymos import Phase, GaussLobatto, RungeKutta, Trajectory
        from dymos.examples.finite_burn_orbit_raise.finite_burn_eom import FiniteBurnODE

        traj = Trajectory()
        p = Problem(model=Group())
        p.model.add_subsystem('traj', traj)

        p.driver = pyOptSparseDriver()
        _, optimizer = set_pyoptsparse_opt('SNOPT', fallback=True)
        p.driver.options['optimizer'] = optimizer

        p.driver.options['dynamic_simul_derivs'] = True

        traj.add_design_parameter('c', opt=False, val=1.5, units='DU/TU')

        # First Phase (burn)

        burn1 = Phase(ode_class=FiniteBurnODE,
                      transcription=GaussLobatto(num_segments=10, order=3, compressed=True))

        burn1 = traj.add_phase('burn1', burn1)

        burn1.set_time_options(fix_initial=True, duration_bounds=(.5, 10))
        burn1.set_state_options('r', fix_initial=True, fix_final=False)
        burn1.set_state_options('theta', fix_initial=True, fix_final=False)
        burn1.set_state_options('vr', fix_initial=True, fix_final=False)
        burn1.set_state_options('vt', fix_initial=True, fix_final=False)
        burn1.set_state_options('accel', fix_initial=True, fix_final=False)
        burn1.set_state_options('deltav', fix_initial=True, fix_final=False)
        burn1.add_control('u1', rate_continuity=True, rate2_continuity=True, units='deg',
                          scaler=0.01, lower=-30, upper=30)

        # Second Phase (Coast)
        coast = Phase(ode_class=FiniteBurnODE,
                      transcription=RungeKutta(num_segments=20, compressed=True))

        traj.add_phase('coast', coast)

        coast.set_time_options(initial_bounds=(0.5, 20), duration_bounds=(.5, 10), duration_ref=10)
        coast.set_state_options('r', fix_initial=False, fix_final=False)
        coast.set_state_options('theta', fix_initial=False, fix_final=False)
        coast.set_state_options('vr', fix_initial=False, fix_final=False)
        coast.set_state_options('vt', fix_initial=False, fix_final=False)
        coast.set_state_options('accel', fix_initial=True, fix_final=False)
        coast.set_state_options('deltav', fix_initial=False, fix_final=False)
        coast.add_design_parameter('u1', opt=False, val=0.0)

        # Third Phase (burn)

        burn2 = Phase(ode_class=FiniteBurnODE,
                      transcription=GaussLobatto(num_segments=10, order=3, compressed=True))

        traj.add_phase('burn2', burn2)

        burn2.set_time_options(initial_bounds=(0.5, 20), duration_bounds=(.5, 10), initial_ref=10)
        burn2.set_state_options('r', fix_initial=False, fix_final=True)
        burn2.set_state_options('theta', fix_initial=False, fix_final=False)
        burn2.set_state_options('vr', fix_initial=False, fix_final=True)
        burn2.set_state_options('vt', fix_initial=False, fix_final=True)
        burn2.set_state_options('accel', fix_initial=False, fix_final=False, defect_scaler=1.0)
        burn2.set_state_options('deltav', fix_initial=False, fix_final=False, defect_scaler=1.0)
        burn2.add_control('u1', rate_continuity=True, rate2_continuity=True, units='deg',
                          scaler=0.01, lower=-30, upper=30)

        burn2.add_objective('deltav', loc='final', scaler=1.0)

        burn1.add_timeseries_output('pos_x', units='DU')
        coast.add_timeseries_output('pos_x', units='DU')
        burn2.add_timeseries_output('pos_x', units='DU')

        burn1.add_timeseries_output('pos_y', units='DU')
        coast.add_timeseries_output('pos_y', units='DU')
        burn2.add_timeseries_output('pos_y', units='DU')

        # Link Phases
        traj.link_phases(phases=['burn1', 'coast', 'burn2'],
                         vars=['time', 'r', 'theta', 'vr', 'vt', 'deltav'])
        traj.link_phases(phases=['burn1', 'burn2'], vars=['accel'])

        # Finish Problem Setup
        p.model.linear_solver = DirectSolver()

        p.setup(check=True, force_alloc_complex=True)

        # Set Initial Guesses
        p.set_val('traj.design_parameters:c', value=1.5)

        p.set_val('traj.burn1.t_initial', value=0.0)
        p.set_val('traj.burn1.t_duration', value=2.25)

        p.set_val('traj.burn1.states:r',
                  value=burn1.interpolate(ys=[1, 1.5], nodes='state_input'))
        p.set_val('traj.burn1.states:theta',
                  value=burn1.interpolate(ys=[0, 1.7], nodes='state_input'))
        p.set_val('traj.burn1.states:vr',
                  value=burn1.interpolate(ys=[0, 0], nodes='state_input'))
        p.set_val('traj.burn1.states:vt',
                  value=burn1.interpolate(ys=[1, 1], nodes='state_input'))
        p.set_val('traj.burn1.states:accel',
                  value=burn1.interpolate(ys=[0.1, 0], nodes='state_input'))
        p.set_val('traj.burn1.states:deltav',
                  value=burn1.interpolate(ys=[0, 0.1], nodes='state_input'), )
        p.set_val('traj.burn1.controls:u1',
                  value=burn1.interpolate(ys=[-3.5, 13.0], nodes='control_input'))

        p.set_val('traj.coast.t_initial', value=2.25)
        p.set_val('traj.coast.t_duration', value=3.0)

        p.set_val('traj.coast.states:r',
                  value=coast.interpolate(ys=[1.3, 1.5], nodes='state_input'))
        p.set_val('traj.coast.states:theta',
                  value=coast.interpolate(ys=[2.1767, 1.7], nodes='state_input'))
        p.set_val('traj.coast.states:vr',
                  value=coast.interpolate(ys=[0.3285, 0], nodes='state_input'))
        p.set_val('traj.coast.states:vt',
                  value=coast.interpolate(ys=[0.97, 1], nodes='state_input'))
        p.set_val('traj.coast.states:accel',
                  value=coast.interpolate(ys=[0, 0], nodes='state_input'))
        # p.set_val('traj.coast.controls:u1',
        #           value=coast.interpolate(ys=[0, 0], nodes='control_input'))

        p.set_val('traj.burn2.t_initial', value=5.25)
        p.set_val('traj.burn2.t_duration', value=1.75)

        p.set_val('traj.burn2.states:r',
                  value=burn2.interpolate(ys=[1.8, 3], nodes='state_input'))
        p.set_val('traj.burn2.states:theta',
                  value=burn2.interpolate(ys=[3.2, 4.0], nodes='state_input'))
        p.set_val('traj.burn2.states:vr',
                  value=burn2.interpolate(ys=[.5, 0], nodes='state_input'))
        p.set_val('traj.burn2.states:vt',
                  value=burn2.interpolate(ys=[1, np.sqrt(1 / 3)], nodes='state_input'))
        p.set_val('traj.burn2.states:accel',
                  value=burn2.interpolate(ys=[0.1, 0], nodes='state_input'))
        p.set_val('traj.burn2.states:deltav',
                  value=burn2.interpolate(ys=[0.1, 0.2], nodes='state_input'))
        p.set_val('traj.burn2.controls:u1',
                  value=burn2.interpolate(ys=[1, 1], nodes='control_input'))

        p.run_driver()

        assert_rel_error(self,
                         p.get_val('traj.burn2.timeseries.states:deltav')[-1],
                         0.3995,
                         tolerance=2.0E-3)

        # Plot results
        exp_out = traj.simulate()

        fig = plt.figure(figsize=(8, 4))
        fig.suptitle('Two Burn Orbit Raise Solution')
        ax_u1 = plt.subplot2grid((2, 2), (0, 0))
        ax_deltav = plt.subplot2grid((2, 2), (1, 0))
        ax_xy = plt.subplot2grid((2, 2), (0, 1), rowspan=2)

        span = np.linspace(0, 2 * np.pi, 100)
        ax_xy.plot(np.cos(span), np.sin(span), 'k--', lw=1)
        ax_xy.plot(3 * np.cos(span), 3 * np.sin(span), 'k--', lw=1)
        ax_xy.set_xlim(-4.5, 4.5)
        ax_xy.set_ylim(-4.5, 4.5)

        ax_xy.set_xlabel('x ($R_e$)')
        ax_xy.set_ylabel('y ($R_e$)')

        ax_u1.set_xlabel('time ($TU$)')
        ax_u1.set_ylabel('$u_1$ ($deg$)')
        ax_u1.grid(True)

        ax_deltav.set_xlabel('time ($TU$)')
        ax_deltav.set_ylabel('${\Delta}v$ ($DU/TU$)')
        ax_deltav.grid(True)

        t_sol = dict((phs, p.get_val('traj.{0}.timeseries.time'.format(phs)))
                     for phs in ['burn1', 'coast', 'burn2'])
        x_sol = dict((phs, p.get_val('traj.{0}.timeseries.pos_x'.format(phs)))
                     for phs in ['burn1', 'coast', 'burn2'])
        y_sol = dict((phs, p.get_val('traj.{0}.timeseries.pos_y'.format(phs)))
                     for phs in ['burn1', 'coast', 'burn2'])
        dv_sol = dict((phs, p.get_val('traj.{0}.timeseries.states:deltav'.format(phs)))
                      for phs in ['burn1', 'coast', 'burn2'])
        u1_sol = dict((phs, p.get_val('traj.{0}.timeseries.controls:u1'.format(phs), units='deg'))
                      for phs in ['burn1', 'burn2'])

        t_exp = dict((phs, exp_out.get_val('traj.{0}.timeseries.time'.format(phs)))
                     for phs in ['burn1', 'coast', 'burn2'])
        x_exp = dict((phs, exp_out.get_val('traj.{0}.timeseries.pos_x'.format(phs)))
                     for phs in ['burn1', 'coast', 'burn2'])
        y_exp = dict((phs, exp_out.get_val('traj.{0}.timeseries.pos_y'.format(phs)))
                     for phs in ['burn1', 'coast', 'burn2'])
        dv_exp = dict((phs, exp_out.get_val('traj.{0}.timeseries.states:deltav'.format(phs)))
                      for phs in ['burn1', 'coast', 'burn2'])
        u1_exp = dict((phs, exp_out.get_val('traj.{0}.timeseries.controls:u1'.format(phs),
                                            units='deg'))
                      for phs in ['burn1', 'burn2'])

        for phs in ['burn1', 'coast', 'burn2']:
            try:
                ax_u1.plot(t_sol[phs], u1_sol[phs], 'ro', ms=3)
                ax_u1.plot(t_exp[phs], u1_exp[phs], 'b-')
            except KeyError:
                pass

            ax_deltav.plot(t_sol[phs], dv_sol[phs], 'ro', ms=3)
            ax_deltav.plot(t_exp[phs], dv_exp[phs], 'b-')

            ax_xy.plot(x_sol[phs], y_sol[phs], 'ro', ms=3, label='implicit')
            ax_xy.plot(x_exp[phs], y_exp[phs], 'b-', label='explicit')

        plt.show()
Example #28
0
def two_burn_orbit_raise_problem(transcription='gauss-lobatto',
                                 optimizer='SNOPT',
                                 transcription_order=3,
                                 compressed=True,
                                 show_plots=False):

    traj = Trajectory()
    p = Problem(model=traj)

    if optimizer == 'SNOPT':
        p.driver = pyOptSparseDriver()
        p.driver.options['optimizer'] = optimizer
        p.driver.options['dynamic_simul_derivs'] = True
        p.driver.opt_settings['Major iterations limit'] = 100
        p.driver.opt_settings['Major feasibility tolerance'] = 1.0E-6
        p.driver.opt_settings['Major optimality tolerance'] = 1.0E-6
        p.driver.opt_settings['iSumm'] = 6
    else:
        p.driver = pyOptSparseDriver()
        p.driver.options['dynamic_simul_derivs'] = True

    traj.add_design_parameter('c', opt=False, val=1.5, units='DU/TU')

    # First Phase (burn)

    burn1 = Phase(transcription,
                  ode_class=FiniteBurnODE,
                  num_segments=10,
                  transcription_order=transcription_order,
                  compressed=compressed)

    burn1 = traj.add_phase('burn1', burn1)

    burn1.set_time_options(fix_initial=True, duration_bounds=(.5, 10))
    burn1.set_state_options('r',
                            fix_initial=True,
                            fix_final=False,
                            defect_scaler=100.0)
    burn1.set_state_options('theta',
                            fix_initial=True,
                            fix_final=False,
                            defect_scaler=100.0)
    burn1.set_state_options('vr',
                            fix_initial=True,
                            fix_final=False,
                            defect_scaler=100.0)
    burn1.set_state_options('vt',
                            fix_initial=True,
                            fix_final=False,
                            defect_scaler=100.0)
    burn1.set_state_options('accel', fix_initial=True, fix_final=False)
    burn1.set_state_options('deltav', fix_initial=True, fix_final=False)
    burn1.add_control('u1',
                      rate_continuity=True,
                      rate2_continuity=True,
                      units='deg',
                      scaler=0.01,
                      rate_continuity_scaler=0.001,
                      rate2_continuity_scaler=0.001,
                      lower=-30,
                      upper=30)

    # Second Phase (Coast)

    coast = Phase(transcription,
                  ode_class=FiniteBurnODE,
                  num_segments=10,
                  transcription_order=transcription_order,
                  compressed=compressed)

    traj.add_phase('coast', coast)

    coast.set_time_options(initial_bounds=(0.5, 20),
                           duration_bounds=(.5, 10),
                           duration_ref=10)
    coast.set_state_options('r',
                            fix_initial=False,
                            fix_final=False,
                            defect_scaler=100.0)
    coast.set_state_options('theta',
                            fix_initial=False,
                            fix_final=False,
                            defect_scaler=100.0)
    coast.set_state_options('vr',
                            fix_initial=False,
                            fix_final=False,
                            defect_scaler=100.0)
    coast.set_state_options('vt',
                            fix_initial=False,
                            fix_final=False,
                            defect_scaler=100.0)
    coast.set_state_options('accel', fix_initial=True, fix_final=True)
    coast.set_state_options('deltav', fix_initial=False, fix_final=False)
    coast.add_control('u1', opt=False, val=0.0, units='deg')

    # Third Phase (burn)

    burn2 = Phase(transcription,
                  ode_class=FiniteBurnODE,
                  num_segments=10,
                  transcription_order=transcription_order,
                  compressed=compressed)

    traj.add_phase('burn2', burn2)

    burn2.set_time_options(initial_bounds=(0.5, 20),
                           duration_bounds=(.5, 10),
                           initial_ref=10)
    burn2.set_state_options('r',
                            fix_initial=False,
                            fix_final=True,
                            defect_scaler=100.0)
    burn2.set_state_options('theta',
                            fix_initial=False,
                            fix_final=False,
                            defect_scaler=100.0)
    burn2.set_state_options('vr',
                            fix_initial=False,
                            fix_final=True,
                            defect_scaler=100.0)
    burn2.set_state_options('vt',
                            fix_initial=False,
                            fix_final=True,
                            defect_scaler=100.0)
    burn2.set_state_options('accel',
                            fix_initial=False,
                            fix_final=False,
                            defect_scaler=1.0)
    burn2.set_state_options('deltav',
                            fix_initial=False,
                            fix_final=False,
                            defect_scaler=1.0)
    burn2.add_control('u1',
                      rate_continuity=True,
                      rate2_continuity=True,
                      units='deg',
                      scaler=0.01,
                      rate_continuity_scaler=0.001,
                      rate2_continuity_scaler=0.001,
                      lower=-10,
                      upper=10)

    burn2.add_objective('deltav', loc='final', scaler=100.0)

    # Link Phases
    traj.link_phases(phases=['burn1', 'coast', 'burn2'],
                     vars=['time', 'r', 'theta', 'vr', 'vt', 'deltav'])
    traj.link_phases(phases=['burn1', 'burn2'], vars=['accel'])

    # Finish Problem Setup

    p.model.options['assembled_jac_type'] = 'csc'
    p.model.linear_solver = DirectSolver(assemble_jac=True)

    p.driver.add_recorder(SqliteRecorder('two_burn_orbit_raise_example.db'))

    p.setup(check=True)

    # Set Initial Guesses
    p.set_val('design_parameters:c', value=1.5)

    p.set_val('burn1.t_initial', value=0.0)
    p.set_val('burn1.t_duration', value=2.25)

    p.set_val('burn1.states:r',
              value=burn1.interpolate(ys=[1, 1.5], nodes='state_input'))
    p.set_val('burn1.states:theta',
              value=burn1.interpolate(ys=[0, 1.7], nodes='state_input'))
    p.set_val('burn1.states:vr',
              value=burn1.interpolate(ys=[0, 0], nodes='state_input'))
    p.set_val('burn1.states:vt',
              value=burn1.interpolate(ys=[1, 1], nodes='state_input'))
    p.set_val('burn1.states:accel',
              value=burn1.interpolate(ys=[0.1, 0], nodes='state_input'))
    p.set_val(
        'burn1.states:deltav',
        value=burn1.interpolate(ys=[0, 0.1], nodes='state_input'),
    )
    p.set_val('burn1.controls:u1',
              value=burn1.interpolate(ys=[-3.5, 13.0], nodes='control_input'))

    p.set_val('coast.t_initial', value=2.25)
    p.set_val('coast.t_duration', value=3.0)

    p.set_val('coast.states:r',
              value=coast.interpolate(ys=[1.3, 1.5], nodes='state_input'))
    p.set_val('coast.states:theta',
              value=coast.interpolate(ys=[2.1767, 1.7], nodes='state_input'))
    p.set_val('coast.states:vr',
              value=coast.interpolate(ys=[0.3285, 0], nodes='state_input'))
    p.set_val('coast.states:vt',
              value=coast.interpolate(ys=[0.97, 1], nodes='state_input'))
    p.set_val('coast.states:accel',
              value=coast.interpolate(ys=[0, 0], nodes='state_input'))
    p.set_val('coast.controls:u1',
              value=coast.interpolate(ys=[0, 0], nodes='control_input'))

    p.set_val('burn2.t_initial', value=5.25)
    p.set_val('burn2.t_duration', value=1.75)

    p.set_val('burn2.states:r',
              value=burn2.interpolate(ys=[1, 3], nodes='state_input'))
    p.set_val('burn2.states:theta',
              value=burn2.interpolate(ys=[0, 4.0], nodes='state_input'))
    p.set_val('burn2.states:vr',
              value=burn2.interpolate(ys=[0, 0], nodes='state_input'))
    p.set_val('burn2.states:vt',
              value=burn2.interpolate(ys=[1, np.sqrt(1 / 3)],
                                      nodes='state_input'))
    p.set_val('burn2.states:accel',
              value=burn2.interpolate(ys=[0.1, 0], nodes='state_input'))
    p.set_val('burn2.states:deltav',
              value=burn2.interpolate(ys=[0.1, 0.2], nodes='state_input'))
    p.set_val('burn2.controls:u1',
              value=burn2.interpolate(ys=[1, 1], nodes='control_input'))

    p.run_driver()

    # Plot results
    exp_out = traj.simulate(times=50, num_procs=3)

    fig = plt.figure(figsize=(8, 4))
    fig.suptitle('Two Burn Orbit Raise Solution')
    ax_u1 = plt.subplot2grid((2, 2), (0, 0))
    ax_deltav = plt.subplot2grid((2, 2), (1, 0))
    ax_xy = plt.subplot2grid((2, 2), (0, 1), rowspan=2)

    span = np.linspace(0, 2 * np.pi, 100)
    ax_xy.plot(np.cos(span), np.sin(span), 'k--', lw=1)
    ax_xy.plot(3 * np.cos(span), 3 * np.sin(span), 'k--', lw=1)
    ax_xy.set_xlim(-4.5, 4.5)
    ax_xy.set_ylim(-4.5, 4.5)

    ax_xy.set_xlabel('x ($R_e$)')
    ax_xy.set_ylabel('y ($R_e$)')

    ax_u1.set_xlabel('time ($TU$)')
    ax_u1.set_ylabel('$u_1$ ($deg$)')
    ax_u1.grid(True)

    ax_deltav.set_xlabel('time ($TU$)')
    ax_deltav.set_ylabel('${\Delta}v$ ($DU/TU$)')
    ax_deltav.grid(True)

    t_sol = traj.get_values('time', flat=True)
    x_sol = traj.get_values('pos_x', flat=True)
    y_sol = traj.get_values('pos_y', flat=True)
    dv_sol = traj.get_values('deltav', flat=True)
    u1_sol = traj.get_values('u1', units='deg', flat=True)

    t_exp = exp_out.get_values('time', flat=True)
    x_exp = exp_out.get_values('pos_x', flat=True)
    y_exp = exp_out.get_values('pos_y', flat=True)
    dv_exp = exp_out.get_values('deltav', flat=True)
    u1_exp = exp_out.get_values('u1', units='deg', flat=True)

    ax_u1.plot(t_sol, u1_sol, 'ro', ms=3)
    ax_u1.plot(t_exp, u1_exp, 'b-')

    ax_deltav.plot(t_sol, dv_sol, 'ro', ms=3)
    ax_deltav.plot(t_exp, dv_exp, 'b-')

    ax_xy.plot(x_sol, y_sol, 'ro', ms=3, label='implicit')
    ax_xy.plot(x_exp, y_exp, 'b-', label='explicit')

    if show_plots:
        plt.show()

    return p
phase.add_objective('m', loc='final', ref=-10000.0)
# phase.set_objective('r', loc='final', ref=-100000.0)

p.model.linear_solver = DirectSolver(assemble_jac=True)
p.model.options['assembled_jac_type'] = 'csc'

# p.driver.add_recorder(SqliteRecorder('out.db'))
p.setup(mode='fwd', check=True)
# from openmdao.api import view_model
# view_model(p)
# exit()

p['phase.t_initial'] = 0.0
p['phase.t_duration'] = 500.

p['phase.states:r'] = phase.interpolate(ys=[0.0, 150.], nodes='disc')
p['phase.states:gam'] = phase.interpolate(ys=[0.0, 0.0], nodes='disc')
p['phase.states:m'] = phase.interpolate(ys=[5e4, 4.9e4], nodes='disc')
p['phase.states:h'][:] = 1e4
p['phase.states:h'][0] = 0
p['phase.states:h'][-1] = 0
p['phase.controls:alpha'] = phase.interpolate(ys=[0.1, 0.1], nodes='all')

p['phase.states:v'][:] = 200.

# Create CRM geometry
for phase_name in ['phase.rhs_disc.aero.OAS_group.', 'phase.rhs_col.aero.OAS_group.']:
    p[phase_name + 'wing_chord_dv'] = np.array([ 107.4 , 285.8 , 536.2 , 285.8 , 107.4 ]) * 0.0254
    p[phase_name + 'wing_twist_dv'] = np.array([ -3.75 ,  0.76 ,  6.72 ,  0.76 , -3.75 ]) * np.pi / 180.
    p[phase_name + 'wing_displacement_x_dv'] = np.array([  1780 ,  1226 ,   904 ,  1226 ,  1780 ]) * 0.0254
    p[phase_name + 'wing_displacement_y_dv'] = np.array([ 263.8 , 181.1 , 174.1 , 181.1 , 263.8 ]) * 0.0254
Example #30
0
    def test_two_phase_cannonball_for_docs(self):
        from openmdao.api import Problem, Group, IndepVarComp, DirectSolver, SqliteRecorder, \
            pyOptSparseDriver
        from openmdao.utils.assert_utils import assert_rel_error

        from dymos import Phase, Trajectory, load_simulation_results
        from dymos.examples.cannonball.cannonball_ode import CannonballODE

        from dymos.examples.cannonball.size_comp import CannonballSizeComp

        p = Problem(model=Group())

        p.driver = pyOptSparseDriver()
        p.driver.options['optimizer'] = 'SLSQP'
        p.driver.options['dynamic_simul_derivs'] = True

        external_params = p.model.add_subsystem('external_params',
                                                IndepVarComp())

        external_params.add_output('radius', val=0.10, units='m')
        external_params.add_output('dens', val=7.87, units='g/cm**3')

        external_params.add_design_var('radius',
                                       lower=0.01,
                                       upper=0.10,
                                       ref0=0.01,
                                       ref=0.10)

        p.model.add_subsystem('size_comp', CannonballSizeComp())

        traj = p.model.add_subsystem('traj', Trajectory())

        # First Phase (ascent)
        ascent = Phase('radau-ps',
                       ode_class=CannonballODE,
                       num_segments=5,
                       transcription_order=3,
                       compressed=True)

        ascent = traj.add_phase('ascent', ascent)

        # All initial states except flight path angle are fixed
        # Final flight path angle is fixed (we will set it to zero so that the phase ends at apogee)
        ascent.set_time_options(fix_initial=True,
                                duration_bounds=(1, 100),
                                duration_ref=100)
        ascent.set_state_options('r', fix_initial=True, fix_final=False)
        ascent.set_state_options('h', fix_initial=True, fix_final=False)
        ascent.set_state_options('gam', fix_initial=False, fix_final=True)
        ascent.set_state_options('v', fix_initial=False, fix_final=False)

        # Limit the muzzle energy
        ascent.add_boundary_constraint('kinetic_energy.ke',
                                       loc='initial',
                                       units='J',
                                       upper=400000,
                                       lower=0,
                                       ref=100000)

        # Second Phase (descent)
        descent = Phase('gauss-lobatto',
                        ode_class=CannonballODE,
                        num_segments=5,
                        transcription_order=3,
                        compressed=True)

        traj.add_phase('descent', descent)

        # All initial states and time are free (they will be linked to the final states of ascent.
        # Final altitude is fixed (we will set it to zero so that the phase ends at ground impact)
        descent.set_time_options(initial_bounds=(.5, 100),
                                 duration_bounds=(.5, 100),
                                 duration_ref=100)
        descent.set_state_options('r', fix_initial=False, fix_final=False)
        descent.set_state_options('h', fix_initial=False, fix_final=True)
        descent.set_state_options('gam', fix_initial=False, fix_final=False)
        descent.set_state_options('v', fix_initial=False, fix_final=False)

        descent.add_objective('r', loc='final', scaler=-1.0)

        # Add internally-managed design parameters to the trajectory.
        traj.add_design_parameter('CD', val=0.5, units=None, opt=False)
        traj.add_design_parameter('CL', val=0.0, units=None, opt=False)
        traj.add_design_parameter('T', val=0.0, units='N', opt=False)
        traj.add_design_parameter('alpha', val=0.0, units='deg', opt=False)

        # Add externally-provided design parameters to the trajectory.
        traj.add_input_parameter('mass',
                                 targets={
                                     'ascent': 'm',
                                     'descent': 'm'
                                 },
                                 val=1.0,
                                 units='kg')

        traj.add_input_parameter('S', val=0.005, units='m**2')

        # Link Phases (link time and all state variables)
        traj.link_phases(phases=['ascent', 'descent'], vars=['*'])

        # Issue Connections
        p.model.connect('external_params.radius', 'size_comp.radius')
        p.model.connect('external_params.dens', 'size_comp.dens')

        p.model.connect('size_comp.mass', 'traj.input_parameters:mass')
        p.model.connect('size_comp.S', 'traj.input_parameters:S')

        # Finish Problem Setup
        p.model.options['assembled_jac_type'] = 'csc'
        p.model.linear_solver = DirectSolver(assemble_jac=True)

        p.driver.add_recorder(SqliteRecorder('ex_two_phase_cannonball.db'))

        p.setup(check=True)

        # Set Initial Guesses
        p.set_val('external_params.radius', 0.05, units='m')
        p.set_val('external_params.dens', 7.87, units='g/cm**3')

        p.set_val('traj.design_parameters:CD', 0.5)
        p.set_val('traj.design_parameters:CL', 0.0)
        p.set_val('traj.design_parameters:T', 0.0)

        p.set_val('traj.ascent.t_initial', 0.0)
        p.set_val('traj.ascent.t_duration', 10.0)

        p.set_val('traj.ascent.states:r',
                  ascent.interpolate(ys=[0, 100], nodes='state_input'))
        p.set_val('traj.ascent.states:h',
                  ascent.interpolate(ys=[0, 100], nodes='state_input'))
        p.set_val('traj.ascent.states:v',
                  ascent.interpolate(ys=[200, 150], nodes='state_input'))
        p.set_val('traj.ascent.states:gam',
                  ascent.interpolate(ys=[25, 0], nodes='state_input'),
                  units='deg')

        p.set_val('traj.descent.t_initial', 10.0)
        p.set_val('traj.descent.t_duration', 10.0)

        p.set_val('traj.descent.states:r',
                  descent.interpolate(ys=[100, 200], nodes='state_input'))
        p.set_val('traj.descent.states:h',
                  descent.interpolate(ys=[100, 0], nodes='state_input'))
        p.set_val('traj.descent.states:v',
                  descent.interpolate(ys=[150, 200], nodes='state_input'))
        p.set_val('traj.descent.states:gam',
                  descent.interpolate(ys=[0, -45], nodes='state_input'),
                  units='deg')

        p.run_driver()

        assert_rel_error(self,
                         traj.get_values('r')['descent'][-1],
                         3191.83945861,
                         tolerance=1.0E-2)

        exp_out = traj.simulate(times=100,
                                record_file='ex_two_phase_cannonball_sim.db')

        # exp_out_loaded = load_simulation_results('ex_two_phase_cannonball_sim.db')

        print('optimal radius: {0:6.4f} m '.format(
            p.get_val('external_params.radius', units='m')[0]))
        print('cannonball mass: {0:6.4f} kg '.format(
            p.get_val('size_comp.mass', units='kg')[0]))

        fig, axes = plt.subplots(nrows=3, ncols=1, figsize=(8, 6))

        axes[0].plot(
            traj.get_values('r')['ascent'],
            traj.get_values('h')['ascent'], 'bo')

        axes[0].plot(
            traj.get_values('r')['descent'],
            traj.get_values('h')['descent'], 'ro')

        axes[0].plot(
            exp_out.get_values('r')['ascent'],
            exp_out.get_values('h')['ascent'], 'b--')

        axes[0].plot(
            exp_out.get_values('r')['descent'],
            exp_out.get_values('h')['descent'], 'r--')

        axes[0].set_xlabel('range (m)')
        axes[0].set_ylabel('altitude (m)')

        # plt.suptitle('Kinetic Energy vs Time')

        axes[1].plot(
            traj.get_values('time')['ascent'],
            traj.get_values('kinetic_energy.ke')['ascent'], 'bo')

        axes[1].plot(
            traj.get_values('time')['descent'],
            traj.get_values('kinetic_energy.ke')['descent'], 'ro')

        axes[1].plot(
            exp_out.get_values('time')['ascent'],
            exp_out.get_values('kinetic_energy.ke')['ascent'], 'b--')

        axes[1].plot(
            exp_out.get_values('time')['descent'],
            exp_out.get_values('kinetic_energy.ke')['descent'], 'r--')

        # axes[1].plot(exp_out_loaded.get_values('time')['ascent'],
        #              exp_out_loaded.get_values('kinetic_energy.ke')['ascent'],
        #              'b--')
        #
        # axes[1].plot(exp_out_loaded.get_values('time')['descent'],
        #              exp_out_loaded.get_values('kinetic_energy.ke')['descent'],
        #              'r--')

        axes[1].set_xlabel('time (s)')
        axes[1].set_ylabel(r'kinetic energy (J)')

        # plt.figure()

        axes[2].plot(
            traj.get_values('time')['ascent'],
            traj.get_values('gam', units='deg')['ascent'], 'bo')
        axes[2].plot(
            traj.get_values('time')['descent'],
            traj.get_values('gam', units='deg')['descent'], 'ro')

        axes[2].plot(
            exp_out.get_values('time')['ascent'],
            exp_out.get_values('gam', units='deg')['ascent'], 'b--')

        axes[2].plot(
            exp_out.get_values('time')['descent'],
            exp_out.get_values('gam', units='deg')['descent'], 'r--')

        axes[2].set_xlabel('time (s)')
        axes[2].set_ylabel(r'flight path angle (deg)')

        plt.show()