Пример #1
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)
Пример #2
0
    def test_initial_val_and_final_val_stick(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))

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

        phase.set_time_options(fix_initial=False, fix_duration=False,
                               initial_val=0.01, duration_val=1.9)

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

        assert_rel_error(self, p['phase0.t_initial'], 0.01)
        assert_rel_error(self, p['phase0.t_duration'], 1.9)
Пример #3
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)
Пример #4
0
def ssto_moon(transcription='gauss-lobatto',
              num_seg=10,
              optimizer='SLSQP',
              top_level_jacobian='csc',
              transcription_order=5,
              compressed=False):

    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['iSumm'] = 6
        p.driver.opt_settings['Verify level'] = 3
    else:
        p.driver = ScipyOptimizeDriver()
        p.driver.options['dynamic_simul_derivs'] = True

    phase = Phase(transcription,
                  ode_class=LaunchVehicleODE,
                  ode_init_kwargs={'central_body': 'moon'},
                  num_segments=num_seg,
                  compressed=compressed,
                  transcription_order=3)

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

    phase.set_time_options(initial_bounds=(0, 0), duration_bounds=(10, 1000))

    phase.set_state_options('x', fix_initial=True, scaler=1.0E-5, lower=0)
    phase.set_state_options('y', fix_initial=True, scaler=1.0E-5, lower=0)
    phase.set_state_options('vx', fix_initial=True, scaler=1.0E-3, lower=0)
    phase.set_state_options('vy', fix_initial=True, scaler=1.0E-3)
    phase.set_state_options('m', fix_initial=True, scaler=1.0E-3)

    phase.add_boundary_constraint('y', loc='final', equals=1.85E5, linear=True)
    phase.add_boundary_constraint('vx', loc='final', equals=1627.0)
    phase.add_boundary_constraint('vy', loc='final', equals=0)

    if transcription == 'radau-ps':
        # This constraint is necessary using the Radau-Pseudospectral method since the
        # last value of the control does not impact the collocation defects.
        phase.add_boundary_constraint('theta_rate2', loc='final', equals=0)

    phase.add_control('theta', units='rad', lower=-1.57, upper=1.57)
    phase.add_design_parameter('thrust',
                               units='N',
                               opt=False,
                               val=3.0 * 50000.0 * 1.61544)
    phase.add_design_parameter('Isp', units='s', opt=False, val=1.0E6)

    phase.add_objective('time', index=-1, scaler=0.01)

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

    return p
Пример #5
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')
Пример #7
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')
Пример #8
0
    def setUpClass(cls):

        p = cls.p = Problem(model=Group())

        p.driver = pyOptSparseDriver()
        p.driver.options['optimizer'] = 'SNOPT'
        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

        phase = Phase('radau-ps',
                      ode_class=CadreOrbitODE,
                      num_segments=10,
                      transcription_order=7,
                      compressed=False)

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

        phase.set_time_options(fix_initial=True, duration_bounds=(duration, duration))

        phase.set_state_options('r_e2b_I', defect_scaler=1000, fix_initial=True, units='km')
        phase.set_state_options('v_e2b_I', defect_scaler=1000, fix_initial=True, units='km/s')
        # phase.set_state_options('SOC', defect_scaler=1, fix_initial=True, units=None)

        # phase.add_design_parameter('P_bat', opt=False, units='W')
        phase.add_design_parameter('Gamma', opt=False, units='rad')

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

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

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

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

        # print(phase.grid_data.num_nodes)
        #
        p['phase0.states:r_e2b_I'][:, 0] = rmag
        p['phase0.states:r_e2b_I'][:, 1] = 0.0
        p['phase0.states:r_e2b_I'][:, 2] = 0.0

        p['phase0.states:v_e2b_I'][:, 0] = 0.0
        p['phase0.states:v_e2b_I'][:, 1] = vcirc
        p['phase0.states:v_e2b_I'][:, 2] = 0.0

        # p['phase0.design_parameters:P_bat'] = 2.0
        p['phase0.design_parameters:Gamma'] = 0.0

        p.run_model()
        p.run_driver()
Пример #9
0
    def test_add_existing_control_as_design_parameter(self):

        p = Phase(ode_class=BrachistochroneODE,
                  transcription=GaussLobatto(num_segments=8, order=3))

        p.add_control('theta')

        with self.assertRaises(ValueError) as e:
            p.add_design_parameter('theta')

        expected = 'theta has already been added as a control.'
        self.assertEqual(str(e.exception), expected)
Пример #10
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)
Пример #11
0
    def test_add_existing_design_parameter_as_input_parameter(self):
        p = Phase(ode_class=_A,
                  transcription=GaussLobatto(num_segments=14,
                                             order=3,
                                             compressed=True))

        p.add_design_parameter('theta')

        with self.assertRaises(ValueError) as e:
            p.add_input_parameter('theta')

        expected = 'theta has already been added as a design parameter.'
        self.assertEqual(str(e.exception), expected)
Пример #12
0
    def test_invalid_design_parameter_name(self):

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

        with self.assertRaises(ValueError) as e:

            p.add_design_parameter('foo')

        expected = 'foo is not a controllable parameter in the ODE system.'
        self.assertEqual(str(e.exception), expected)
Пример #13
0
    def test_add_existing_design_parameter_as_input_parameter(self):

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

        p.add_design_parameter('theta')

        with self.assertRaises(ValueError) as e:
            p.add_input_parameter('theta')

        expected = 'theta has already been added as a design parameter.'
        self.assertEqual(str(e.exception), expected)
Пример #14
0
    def test_invalid_options_nonoptimal_design_param(self):
        p = Problem(model=Group())

        p.driver = ScipyOptimizeDriver()

        p.driver.options['dynamic_simul_derivs'] = True
        phase = Phase(ode_class=BrachistochroneODE,
                      transcription=GaussLobatto(num_segments=16,
                                                 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,
                          opt=False)

        phase.add_design_parameter('g',
                                   units='m/s**2',
                                   opt=False,
                                   lower=5,
                                   upper=10,
                                   ref0=5,
                                   ref=10,
                                   scaler=1,
                                   adder=0)

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

        p.model.linear_solver = DirectSolver()

        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter('always')
            p.setup(check=False)

        print('\n'.join([str(ww.message) for ww in w]))

        expected = 'Invalid options for non-optimal design_parameter \'g\' in phase \'phase0\': ' \
                   'lower, upper, scaler, adder, ref, ref0'

        self.assertIn(expected, [str(ww.message) for ww in w])
Пример #15
0
    def test_fixed_time_invalid_options(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))

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

        phase.set_time_options(fix_initial=True, fix_duration=True,
                               initial_bounds=(1.0, 5.0), initial_adder=0.0,
                               initial_scaler=1.0, initial_ref0=0.0,
                               initial_ref=1.0, duration_bounds=(1.0, 5.0),
                               duration_adder=0.0, duration_scaler=1.0,
                               duration_ref0=0.0, duration_ref=1.0)

        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.linear_solver = DirectSolver()

        expected_msg0 = 'Phase time options have no effect because fix_initial=True for ' \
                        'phase \'phase0\': initial_bounds, initial_scaler, initial_adder, ' \
                        'initial_ref, initial_ref0'

        expected_msg1 = 'Phase time options have no effect because fix_duration=True for' \
                        ' phase \'phase0\': duration_bounds, duration_scaler, ' \
                        'duration_adder, duration_ref, duration_ref0'

        with warnings.catch_warnings(record=True) as ctx:
            warnings.simplefilter('always')
            p.setup(check=True)

        self.assertIn(expected_msg0, [str(w.message) for w in ctx])
        self.assertIn(expected_msg1, [str(w.message) for w in ctx])
Пример #16
0
    def test_ex_double_integrator_input_and_fixed_times_warns(self):
        """
        Tests that time optimization options cause a ValueError to be raised when t_initial and
        t_duration are connected to external sources.
        """
        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))

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

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

        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.linear_solver = DirectSolver()

        with warnings.catch_warnings(record=True) as ctx:
            warnings.simplefilter('always')
            p.setup(check=True)

        expected_msg0 = 'Phase \'phase0\' initial time is an externally-connected input, therefore ' \
                        'fix_initial has no effect.'

        expected_msg1 = 'Phase \'phase0\' time duration is an externally-connected input, ' \
                        'therefore fix_duration has no effect.'

        self.assertIn(expected_msg0, [str(w.message) for w in ctx])
        self.assertIn(expected_msg1, [str(w.message) for w in ctx])
Пример #17
0
    def test_invalid_options_nonoptimal_design_param(self):

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

        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter('always')
            p.add_design_parameter('g', opt=False, lower=5, upper=10, ref0=5, ref=10,
                                   scaler=1, adder=0)

        expected = 'Invalid options for non-optimal design parameter "g":' \
                   'lower, upper, scaler, adder, ref, ref0'

        self.assertEqual(len(w), 1)
        self.assertEqual(str(w[0].message), expected)
Пример #18
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
Пример #19
0
def ssto_earth(transcription='gauss-lobatto', num_seg=10, transcription_order=5,
               top_level_jacobian='csc', optimizer='SLSQP', compressed=False):
    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['iSumm'] = 6
        p.driver.opt_settings['Verify level'] = 3
    else:
        p.driver = ScipyOptimizeDriver()
        p.driver.options['dynamic_simul_derivs'] = True

    phase = Phase(transcription,
                  ode_class=LaunchVehicleODE,
                  ode_init_kwargs={'central_body': 'earth'},
                  num_segments=num_seg,
                  transcription_order=transcription_order,
                  compressed=compressed)

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

    phase.set_time_options(initial_bounds=(0, 0), duration_bounds=(10, 500))

    phase.set_state_options('x', fix_initial=True, scaler=1.0E-5)
    phase.set_state_options('y', fix_initial=True, scaler=1.0E-5)
    phase.set_state_options('vx', fix_initial=True, scaler=1.0E-3)
    phase.set_state_options('vy', fix_initial=True, scaler=1.0E-3)
    phase.set_state_options('m', fix_initial=True, scaler=1.0E-3)

    phase.add_boundary_constraint('y', loc='final', equals=1.85E5, linear=True)
    phase.add_boundary_constraint('vx', loc='final', equals=7796.6961)
    phase.add_boundary_constraint('vy', loc='final', equals=0)

    phase.add_control('theta', units='rad', lower=-1.57, upper=1.57)
    phase.add_design_parameter('thrust', units='N', opt=False, val=2100000.0)

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

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

    return p
Пример #20
0
    def test_invalid_ode_wrong_class(self):

        p = Problem(model=Group())

        p.driver = ScipyOptimizeDriver()

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

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

        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.linear_solver = DirectSolver()

        with self.assertRaises(ValueError) as e:
            p.setup(check=True)

        self.assertEqual(
            str(e.exception),
            'ode_class must be derived from openmdao.core.System.')
    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)
Пример #22
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()
Пример #23
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])
Пример #24
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()
    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'])
Пример #26
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()
Пример #27
0
    def setUpClass(cls):

        p = cls.p = Problem(model=Group())

        # p.driver = pyOptSparseDriver()
        # p.driver.options['optimizer'] = 'SNOPT'
        # p.driver.options['dynamic_simul_derivs'] = True
        # p.driver.opt_settings['Major iterations limit'] = 1000
        # p.driver.opt_settings['Major feasibility tolerance'] = 1.0E-4
        # p.driver.opt_settings['Major optimality tolerance'] = 1.0E-4
        # p.driver.opt_settings['iSumm'] = 6

        NUM_SEG = 10
        TRANSCRIPTION_ORDER = 7

        orbit_phase = Phase('radau-ps',
                            ode_class=CadreOrbitODE,
                            num_segments=NUM_SEG,
                            transcription_order=TRANSCRIPTION_ORDER,
                            compressed=False)

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

        orbit_phase.set_time_options(fix_initial=True, fix_duration=True)
        orbit_phase.set_state_options('r_e2b_I',
                                      defect_scaler=1000,
                                      fix_initial=True,
                                      units='km')
        orbit_phase.set_state_options('v_e2b_I',
                                      defect_scaler=1000,
                                      fix_initial=True,
                                      units='km/s')
        # orbit_phase.set_state_options('SOC', defect_scaler=1, fix_initial=True, units=None)
        # orbit_phase.add_design_parameter('P_bat', opt=False, units='W')
        orbit_phase.add_design_parameter('Gamma', opt=False, units='rad')
        orbit_phase.add_objective('time', loc='final', scaler=10)

        # Add a control interp comp to interpolate the rates of O_BI from the orbit phase.
        faux_control_options = {'O_BI': {'units': None, 'shape': (3, 3)}}
        p.model.add_subsystem(
            'obi_rate_interp_comp',
            ControlInterpComp(control_options=faux_control_options,
                              time_units='s',
                              grid_data=orbit_phase.grid_data),
            promotes_outputs=[('control_rates:O_BI_rate', 'Odot_BI')])

        control_input_nodes_idxs = orbit_phase.grid_data.subset_node_indices[
            'control_input']
        src_idxs = get_src_indices_by_row(control_input_nodes_idxs,
                                          shape=(3, 3))
        p.model.connect('orbit_phase.rhs_all.O_BI',
                        'obi_rate_interp_comp.controls:O_BI',
                        src_indices=src_idxs,
                        flat_src_indices=True)
        p.model.connect(
            'orbit_phase.time.dt_dstau',
            ('obi_rate_interp_comp.dt_dstau', 'w_B_rate_interp_comp.dt_dstau'))

        # Use O_BI and Odot_BI to compute the angular velocity vector
        p.model.add_subsystem(
            'angular_velocity_comp',
            AngularVelocityComp(num_nodes=orbit_phase.grid_data.num_nodes))
        p.model.connect('orbit_phase.rhs_all.O_BI',
                        'angular_velocity_comp.O_BI')
        p.model.connect('Odot_BI', 'angular_velocity_comp.Odot_BI')

        # Add another interpolation comp to compute the rate of w_B
        faux_control_options = {'w_B': {'units': '1/s', 'shape': (3, )}}
        p.model.add_subsystem(
            'w_B_rate_interp_comp',
            ControlInterpComp(control_options=faux_control_options,
                              time_units='s',
                              grid_data=orbit_phase.grid_data),
            promotes_outputs=[('control_rates:w_B_rate', 'wdot_B')])

        src_idxs = get_src_indices_by_row(control_input_nodes_idxs,
                                          shape=(3, ))
        p.model.connect('angular_velocity_comp.w_B',
                        'w_B_rate_interp_comp.controls:w_B',
                        src_indices=src_idxs,
                        flat_src_indices=True)

        # Now add the systems phase

        systems_phase = Phase('radau-ps',
                              ode_class=CadreSystemsODE,
                              num_segments=NUM_SEG,
                              transcription_order=TRANSCRIPTION_ORDER,
                              compressed=False)

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

        systems_phase.set_time_options(fix_initial=True, fix_duration=True)
        systems_phase.set_state_options('SOC',
                                        defect_ref=1,
                                        fix_initial=True,
                                        units=None)
        systems_phase.set_state_options('w_RW',
                                        defect_ref=100,
                                        fix_initial=True,
                                        units='1/s')
        systems_phase.set_state_options('data',
                                        defect_ref=10,
                                        fix_initial=True,
                                        units='Gibyte')
        systems_phase.set_state_options('temperature',
                                        ref0=273,
                                        ref=373,
                                        defect_ref=100,
                                        fix_initial=True,
                                        units='degK')

        systems_phase.add_design_parameter('LD', opt=False, units='d')
        systems_phase.add_design_parameter('fin_angle',
                                           opt=False,
                                           lower=0.,
                                           upper=np.pi / 2.)
        systems_phase.add_design_parameter('antAngle',
                                           opt=False,
                                           lower=-np.pi / 4,
                                           upper=np.pi / 4)
        systems_phase.add_design_parameter('cellInstd',
                                           opt=False,
                                           lower=0.0,
                                           upper=1.0,
                                           ref=1.0)

        # Add r_e2b_I and O_BI as non-optimized controls, allowing them to be connected to external sources
        systems_phase.add_control('r_e2b_I', opt=False, units='km')
        systems_phase.add_control('O_BI', opt=False)
        systems_phase.add_control('w_B', opt=False)
        systems_phase.add_control('wdot_B', opt=False)
        systems_phase.add_control('P_comm',
                                  opt=False,
                                  lower=0.0,
                                  upper=30.0,
                                  units='W')
        systems_phase.add_control('Isetpt',
                                  opt=False,
                                  lower=0.0,
                                  upper=0.4,
                                  units='A')

        # Connect r_e2b_I and O_BI values from all nodes in the orbit phase to the input values
        # in the attitude phase.
        src_idxs = get_src_indices_by_row(control_input_nodes_idxs,
                                          shape=(3, ))
        p.model.connect('orbit_phase.states:r_e2b_I',
                        'systems_phase.controls:r_e2b_I',
                        src_indices=src_idxs,
                        flat_src_indices=True)
        p.model.connect('angular_velocity_comp.w_B',
                        'systems_phase.controls:w_B',
                        src_indices=src_idxs,
                        flat_src_indices=True)
        p.model.connect('wdot_B',
                        'systems_phase.controls:wdot_B',
                        src_indices=src_idxs,
                        flat_src_indices=True)

        src_idxs = get_src_indices_by_row(control_input_nodes_idxs,
                                          shape=(3, 3))
        p.model.connect('orbit_phase.rhs_all.O_BI',
                        'systems_phase.controls:O_BI',
                        src_indices=src_idxs,
                        flat_src_indices=True)

        p.setup(check=True)

        # from openmdao.api import view_model
        # view_model(p.model)

        # Initialize values in the orbit phase

        p['orbit_phase.t_initial'] = 0.0
        p['orbit_phase.t_duration'] = duration

        # p['systems_phase.states:w_RW'][:, 0] = 0.0
        # p['systems_phase.states:w_RW'][:, 1] = 0.0
        # p['systems_phase.states:w_RW'][:, 2] = 0.0

        # Default starting orbit
        # [ 2.89078958e+03  5.69493134e+03 -2.55340189e+03  2.56640460e-01
        #               3.00387409e+00  6.99018448e+00]

        p['orbit_phase.states:r_e2b_I'][:, 0] = 2.89078958e+03
        p['orbit_phase.states:r_e2b_I'][:, 1] = 5.69493134e+03
        p['orbit_phase.states:r_e2b_I'][:, 2] = -2.55340189e+03

        p['orbit_phase.states:v_e2b_I'][:, 0] = 2.56640460e-01
        p['orbit_phase.states:v_e2b_I'][:, 1] = 3.00387409e+00
        p['orbit_phase.states:v_e2b_I'][:, 2] = 6.99018448e+00

        # Initialize values in the systems phase

        p['systems_phase.t_initial'] = 0.0
        p['systems_phase.t_duration'] = duration

        # p['systems_phase.states:w_RW'][:, 0] = 0.0
        # p['systems_phase.states:w_RW'][:, 1] = 0.0
        # p['systems_phase.states:w_RW'][:, 2] = 0.0

        p['systems_phase.states:SOC'] = 1.0
        p['systems_phase.states:w_RW'] = 100.0
        p['systems_phase.states:data'] = 0.0
        p['systems_phase.states:temperature'] = 273.0

        # p['systems_phase.states:v_e2b_I'][:, 0] = 0.0
        # p['systems_phase.states:v_e2b_I'][:, 1] = vcirc
        # p['systems_phase.states:v_e2b_I'][:, 2] = 0.0

        p['systems_phase.design_parameters:LD'] = 5233.5
        p['systems_phase.design_parameters:fin_angle'] = 70.0

        p.run_model()
Пример #28
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)
Пример #29
0
                            fix_initial=True,
                            fix_final=False)
    # phase.set_state_options('p%dmass' % i,
    #                         scaler=0.01, defect_scaler=0.1, fix_initial=True,
    #                         lower=0.0)
    # phase.set_state_options('p%dimpulse' % i,
    #                         scaler=0.01, defect_scaler=0.1, fix_initial=True)

    phase.add_boundary_constraint('space%d.err_space_dist' % i,
                                  constraint_name='space%d_err_space_dist' % i,
                                  loc='final',
                                  lower=0.0)

    phase.add_design_parameter('speed%d' % i,
                               opt=True,
                               val=1.0,
                               upper=20,
                               lower=1e-9,
                               units='m/s')

    phase.add_design_parameter('heading%d' % i,
                               opt=False,
                               val=heading,
                               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
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