Example #1
0
    def test_vanderpol_for_docs_optimize_refine(self):
        import dymos as dm
        from dymos.examples.plotting import plot_results
        from dymos.examples.vanderpol.vanderpol_dymos import vanderpol

        # Create the Dymos problem instance
        p = vanderpol(transcription='gauss-lobatto',
                      num_segments=15,
                      transcription_order=3,
                      compressed=True,
                      optimizer='SLSQP')

        # Enable grid refinement and find optimal control solution to stop oscillation
        p.model.traj.phases.phase0.set_refine_options(refine=True)
        dm.run_problem(p, refine=True, refine_iteration_limit=10)

        # check validity by using scipy.integrate.solve_ivp to integrate the solution
        exp_out = p.model.traj.simulate()

        # Display the results
        plot_results([
            ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.states:x1',
             'time (s)', 'x1 (V)'),
            ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.states:x0',
             'time (s)', 'x0 (V/s)'),
            ('traj.phase0.timeseries.states:x0',
             'traj.phase0.timeseries.states:x1', 'x0 vs x1', 'x0 vs x1'),
            ('traj.phase0.timeseries.time',
             'traj.phase0.timeseries.controls:u', 'time (s)', 'control u'),
        ],
                     title='Van Der Pol Optimization with Grid Refinement',
                     p_sol=p,
                     p_sim=exp_out)

        plt.show()
Example #2
0
    def test_vanderpol_for_docs_simulation(self):
        from dymos.examples.plotting import plot_results
        from dymos.examples.vanderpol.vanderpol_dymos import vanderpol

        # Create the Dymos problem instance
        p = vanderpol(transcription='gauss-lobatto', num_segments=75)

        # Run the problem (simulate only)
        p.run_model()

        # check validity by using scipy.integrate.solve_ivp to integrate the solution
        exp_out = p.model.traj.simulate()

        # Display the results
        plot_results([
            ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.states:x1',
             'time (s)', 'x1 (V)'),
            ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.states:x0',
             'time (s)', 'x0 (V/s)'),
            ('traj.phase0.timeseries.states:x0',
             'traj.phase0.timeseries.states:x1', 'x0 vs x1', 'x0 vs x1'),
            ('traj.phase0.timeseries.time',
             'traj.phase0.timeseries.controls:u', 'time (s)', 'control u'),
        ],
                     title='Van Der Pol Simulation',
                     p_sol=p,
                     p_sim=exp_out)

        plt.show()
    def test_doc_ssto_linear_tangent_guidance(self):
        import numpy as np
        import matplotlib.pyplot as plt
        import openmdao.api as om
        from openmdao.utils.assert_utils import assert_rel_error
        import dymos as dm
        from dymos.examples.plotting import plot_results

        g = 1.61544  # lunar gravity, m/s**2

        class LaunchVehicle2DEOM(om.ExplicitComponent):
            """
            Simple 2D Cartesian Equations of Motion for a launch vehicle subject to thrust and drag.
            """
            def initialize(self):
                self.options.declare('num_nodes', types=int)

            def setup(self):
                nn = self.options['num_nodes']

                # Inputs
                self.add_input('vx',
                               val=np.zeros(nn),
                               desc='x velocity',
                               units='m/s')

                self.add_input('vy',
                               val=np.zeros(nn),
                               desc='y velocity',
                               units='m/s')

                self.add_input('m', val=np.zeros(nn), desc='mass', units='kg')

                self.add_input('theta',
                               val=np.zeros(nn),
                               desc='pitch angle',
                               units='rad')

                self.add_input('thrust',
                               val=2100000 * np.ones(nn),
                               desc='thrust',
                               units='N')

                self.add_input('Isp',
                               val=265.2 * np.ones(nn),
                               desc='specific impulse',
                               units='s')

                # Outputs
                self.add_output('xdot',
                                val=np.zeros(nn),
                                desc='velocity component in x',
                                units='m/s')

                self.add_output('ydot',
                                val=np.zeros(nn),
                                desc='velocity component in y',
                                units='m/s')

                self.add_output('vxdot',
                                val=np.zeros(nn),
                                desc='x acceleration magnitude',
                                units='m/s**2')

                self.add_output('vydot',
                                val=np.zeros(nn),
                                desc='y acceleration magnitude',
                                units='m/s**2')

                self.add_output('mdot',
                                val=np.zeros(nn),
                                desc='mass rate of change',
                                units='kg/s')

                # Setup partials
                ar = np.arange(self.options['num_nodes'])

                self.declare_partials(of='xdot',
                                      wrt='vx',
                                      rows=ar,
                                      cols=ar,
                                      val=1.0)
                self.declare_partials(of='ydot',
                                      wrt='vy',
                                      rows=ar,
                                      cols=ar,
                                      val=1.0)

                self.declare_partials(of='vxdot', wrt='vx', rows=ar, cols=ar)
                self.declare_partials(of='vxdot', wrt='m', rows=ar, cols=ar)
                self.declare_partials(of='vxdot',
                                      wrt='theta',
                                      rows=ar,
                                      cols=ar)
                self.declare_partials(of='vxdot',
                                      wrt='thrust',
                                      rows=ar,
                                      cols=ar)

                self.declare_partials(of='vydot', wrt='m', rows=ar, cols=ar)
                self.declare_partials(of='vydot',
                                      wrt='theta',
                                      rows=ar,
                                      cols=ar)
                self.declare_partials(of='vydot', wrt='vy', rows=ar, cols=ar)
                self.declare_partials(of='vydot',
                                      wrt='thrust',
                                      rows=ar,
                                      cols=ar)

                self.declare_partials(of='mdot',
                                      wrt='thrust',
                                      rows=ar,
                                      cols=ar)
                self.declare_partials(of='mdot', wrt='Isp', rows=ar, cols=ar)

            def compute(self, inputs, outputs):
                theta = inputs['theta']
                cos_theta = np.cos(theta)
                sin_theta = np.sin(theta)
                vx = inputs['vx']
                vy = inputs['vy']
                m = inputs['m']
                F_T = inputs['thrust']
                Isp = inputs['Isp']

                outputs['xdot'] = vx
                outputs['ydot'] = vy
                outputs['vxdot'] = F_T * cos_theta / m
                outputs['vydot'] = F_T * sin_theta / m - g
                outputs['mdot'] = -F_T / (g * Isp)

            def compute_partials(self, inputs, jacobian):
                theta = inputs['theta']
                cos_theta = np.cos(theta)
                sin_theta = np.sin(theta)
                m = inputs['m']
                F_T = inputs['thrust']
                Isp = inputs['Isp']

                # jacobian['vxdot', 'vx'] = -CDA * rho * vx / m
                jacobian['vxdot', 'm'] = -(F_T * cos_theta) / m**2
                jacobian['vxdot', 'theta'] = -(F_T / m) * sin_theta
                jacobian['vxdot', 'thrust'] = cos_theta / m

                # jacobian['vydot', 'vy'] = -CDA * rho * vy / m
                jacobian['vydot', 'm'] = -(F_T * sin_theta) / m**2
                jacobian['vydot', 'theta'] = (F_T / m) * cos_theta
                jacobian['vydot', 'thrust'] = sin_theta / m

                jacobian['mdot', 'thrust'] = -1.0 / (g * Isp)
                jacobian['mdot', 'Isp'] = F_T / (g * Isp**2)

        class LinearTangentGuidanceComp(om.ExplicitComponent):
            """ Compute pitch angle from static controls governing linear expression for
                pitch angle tangent as function of time.
            """
            def initialize(self):
                self.options.declare('num_nodes', types=int)

            def setup(self):
                nn = self.options['num_nodes']

                self.add_input('a_ctrl',
                               val=np.zeros(nn),
                               desc='linear tangent slope',
                               units='1/s')

                self.add_input('b_ctrl',
                               val=np.zeros(nn),
                               desc='tangent of theta at t=0',
                               units=None)

                self.add_input('time_phase',
                               val=np.zeros(nn),
                               desc='time',
                               units='s')

                self.add_output('theta',
                                val=np.zeros(nn),
                                desc='pitch angle',
                                units='rad')

                # Setup partials
                arange = np.arange(self.options['num_nodes'])

                self.declare_partials(of='theta',
                                      wrt='a_ctrl',
                                      rows=arange,
                                      cols=arange,
                                      val=1.0)
                self.declare_partials(of='theta',
                                      wrt='b_ctrl',
                                      rows=arange,
                                      cols=arange,
                                      val=1.0)
                self.declare_partials(of='theta',
                                      wrt='time_phase',
                                      rows=arange,
                                      cols=arange,
                                      val=1.0)

            def compute(self, inputs, outputs):
                a = inputs['a_ctrl']
                b = inputs['b_ctrl']
                t = inputs['time_phase']
                outputs['theta'] = np.arctan(a * t + b)

            def compute_partials(self, inputs, jacobian):
                a = inputs['a_ctrl']
                b = inputs['b_ctrl']
                t = inputs['time_phase']

                x = a * t + b
                denom = x**2 + 1.0

                jacobian['theta', 'a_ctrl'] = t / denom
                jacobian['theta', 'b_ctrl'] = 1.0 / denom
                jacobian['theta', 'time_phase'] = a / denom

        @dm.declare_time(units='s', targets=['guidance.time_phase'])
        @dm.declare_state('x', rate_source='eom.xdot', units='m')
        @dm.declare_state('y', rate_source='eom.ydot', units='m')
        @dm.declare_state('vx',
                          rate_source='eom.vxdot',
                          targets=['eom.vx'],
                          units='m/s')
        @dm.declare_state('vy',
                          rate_source='eom.vydot',
                          targets=['eom.vy'],
                          units='m/s')
        @dm.declare_state('m',
                          rate_source='eom.mdot',
                          targets=['eom.m'],
                          units='kg')
        @dm.declare_parameter('thrust', targets=['eom.thrust'], units='N')
        @dm.declare_parameter('a_ctrl',
                              targets=['guidance.a_ctrl'],
                              units='1/s')
        @dm.declare_parameter('b_ctrl',
                              targets=['guidance.b_ctrl'],
                              units=None)
        @dm.declare_parameter('Isp', targets=['eom.Isp'], units='s')
        class LaunchVehicleLinearTangentODE(om.Group):
            """
            The LaunchVehicleLinearTangentODE for this case consists of a guidance component and
            the EOM.  Guidance is simply an OpenMDAO ExecComp which computes the arctangent of the
            tan_theta variable.
            """
            def initialize(self):
                self.options.declare(
                    'num_nodes',
                    types=int,
                    desc='Number of nodes to be evaluated in the RHS')

            def setup(self):
                nn = self.options['num_nodes']
                self.add_subsystem('guidance',
                                   LinearTangentGuidanceComp(num_nodes=nn))
                self.add_subsystem('eom', LaunchVehicle2DEOM(num_nodes=nn))
                self.connect('guidance.theta', 'eom.theta')

        #
        # Setup and solve the optimal control problem
        #
        p = om.Problem(model=om.Group())

        p.driver = om.pyOptSparseDriver()
        p.driver.declare_coloring()

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

        phase = dm.Phase(ode_class=LaunchVehicleLinearTangentODE,
                         transcription=dm.GaussLobatto(num_segments=10,
                                                       order=5,
                                                       compressed=True))

        traj.add_phase('phase0', phase)

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

        phase.add_state('x', fix_initial=True, lower=0)
        phase.add_state('y', fix_initial=True, lower=0)
        phase.add_state('vx', fix_initial=True, lower=0)
        phase.add_state('vy', fix_initial=True)
        phase.add_state('m', fix_initial=True)

        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)

        phase.add_design_parameter('a_ctrl', units='1/s', opt=True)
        phase.add_design_parameter('b_ctrl', units=None, opt=True)
        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.linear_solver = om.DirectSolver()

        phase.add_timeseries_output('guidance.theta', units='deg')

        p.setup(check=True)

        p['traj.phase0.t_initial'] = 0.0
        p['traj.phase0.t_duration'] = 500.0
        p['traj.phase0.states:x'] = phase.interpolate(ys=[0, 350000.0],
                                                      nodes='state_input')
        p['traj.phase0.states:y'] = phase.interpolate(ys=[0, 185000.0],
                                                      nodes='state_input')
        p['traj.phase0.states:vx'] = phase.interpolate(ys=[0, 1627.0],
                                                       nodes='state_input')
        p['traj.phase0.states:vy'] = phase.interpolate(ys=[1.0E-6, 0],
                                                       nodes='state_input')
        p['traj.phase0.states:m'] = phase.interpolate(ys=[50000, 50000],
                                                      nodes='state_input')
        p['traj.phase0.design_parameters:a_ctrl'] = -0.01
        p['traj.phase0.design_parameters:b_ctrl'] = 3.0

        p.run_driver()

        #
        # Check the results.
        #
        assert_rel_error(self,
                         p.get_val('traj.phase0.timeseries.time')[-1],
                         481,
                         tolerance=0.01)

        #
        # Get the explitly simulated results
        #
        exp_out = traj.simulate()

        #
        # Plot the results
        #
        plot_results(
            [('traj.phase0.timeseries.states:x',
              'traj.phase0.timeseries.states:y', 'range (m)', 'altitude (m)'),
             ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.theta',
              'range (m)', 'altitude (m)')],
            title=
            'Single Stage to Orbit Solution Using Linear Tangent Guidance',
            p_sol=p,
            p_sim=exp_out)

        plt.show()
Example #4
0
    def test_hyper_sensitive_for_docs(self):
        import openmdao.api as om
        from openmdao.utils.assert_utils import assert_near_equal
        import dymos as dm
        from dymos.examples.plotting import plot_results
        from dymos.examples.hyper_sensitive.hyper_sensitive_ode import HyperSensitiveODE

        # Initialize the problem and assign the driver
        p = om.Problem(model=om.Group())
        p.driver = om.pyOptSparseDriver()
        p.driver.options['optimizer'] = 'SLSQP'
        p.driver.declare_coloring()

        # Setup the trajectory and its phase
        traj = p.model.add_subsystem('traj', dm.Trajectory())

        transcription = dm.Radau(num_segments=30, order=3, compressed=False)

        phase = traj.add_phase('phase0',
                               dm.Phase(ode_class=HyperSensitiveODE, transcription=transcription))

        phase.set_time_options(fix_initial=True, fix_duration=True)
        phase.add_state('x', fix_initial=True, fix_final=False, rate_source='x_dot', targets=['x'])
        phase.add_state('xL', fix_initial=True, fix_final=False, rate_source='L', targets=['xL'])
        phase.add_control('u', opt=True, targets=['u'])

        phase.add_boundary_constraint('x', loc='final', equals=1)

        phase.add_objective('xL', loc='final')

        p.setup(check=True)

        p.set_val('traj.phase0.states:x', phase.interpolate(ys=[1.5, 1], nodes='state_input'))
        p.set_val('traj.phase0.states:xL', phase.interpolate(ys=[0, 1], nodes='state_input'))
        p.set_val('traj.phase0.t_initial', 0)
        p.set_val('traj.phase0.t_duration', tf)
        p.set_val('traj.phase0.controls:u', phase.interpolate(ys=[-0.6, 2.4], nodes='control_input'))

        #
        # Solve the problem.
        #
        dm.run_problem(p)

        #
        # Verify that the results are correct.
        #
        ui, uf, J = solution()

        assert_near_equal(p.get_val('traj.phase0.timeseries.controls:u')[0],
                          ui,
                          tolerance=1.5e-2)

        assert_near_equal(p.get_val('traj.phase0.timeseries.controls:u')[-1],
                          uf,
                          tolerance=1.5e-2)

        assert_near_equal(p.get_val('traj.phase0.timeseries.states:xL')[-1],
                          J,
                          tolerance=1e-2)

        #
        # Simulate the explicit solution and plot the results.
        #
        exp_out = traj.simulate()

        plot_results([('traj.phase0.timeseries.time', 'traj.phase0.timeseries.states:x',
                       'time (s)', 'x $(m)$'),
                      ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.controls:u',
                       'time (s)', 'u $(m/s^2)$')],
                     title='Hyper Sensitive Problem Solution\nRadau Pseudospectral Method',
                     p_sol=p, p_sim=exp_out)

        plt.show()
    def test_brachistochrone_for_docs_coloring_demo_solve_segments(self):
        import openmdao.api as om
        from openmdao.utils.assert_utils import assert_near_equal
        import dymos as dm
        from dymos.examples.plotting import plot_results
        from dymos.examples.brachistochrone import BrachistochroneODE
        from openmdao.utils.general_utils import set_pyoptsparse_opt

        #
        # Initialize the Problem and the optimization driver
        #
        p = om.Problem(model=om.Group())
        _, optimizer = set_pyoptsparse_opt('IPOPT', fallback=True)
        p.driver = om.pyOptSparseDriver(optimizer=optimizer)
        p.driver.opt_settings['print_level'] = 5
        # p.driver.declare_coloring()

        #
        # Create a trajectory and add a phase to it
        #
        traj = p.model.add_subsystem('traj', dm.Trajectory())

        #
        # In this case the phase has many segments to demonstrate the impact of coloring.
        #
        phase = traj.add_phase(
            'phase0',
            dm.Phase(ode_class=BrachistochroneODE,
                     transcription=dm.Radau(num_segments=100,
                                            solve_segments=True)))

        #
        # Set the variables
        #
        phase.set_time_options(initial_bounds=(0, 0), duration_bounds=(.5, 10))

        phase.add_state(
            'x',
            rate_source=BrachistochroneODE.states['x']['rate_source'],
            units=BrachistochroneODE.states['x']['units'],
            fix_initial=True)

        phase.add_state(
            'y',
            rate_source=BrachistochroneODE.states['y']['rate_source'],
            units=BrachistochroneODE.states['y']['units'],
            fix_initial=True)

        phase.add_state(
            'v',
            rate_source=BrachistochroneODE.states['v']['rate_source'],
            units=BrachistochroneODE.states['v']['units'],
            fix_initial=True)

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

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

        #
        # Replace state terminal bounds with nonlinear constraints
        #
        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 = om.DirectSolver()

        #
        # Setup the Problem
        #
        p.setup()

        #
        # Set the initial values
        #
        p['traj.phase0.t_initial'] = 0.0
        p['traj.phase0.t_duration'] = 2.0

        p['traj.phase0.states:x'] = phase.interpolate(ys=[0, 10],
                                                      nodes='state_input')
        p['traj.phase0.states:y'] = phase.interpolate(ys=[10, 5],
                                                      nodes='state_input')
        p['traj.phase0.states:v'] = phase.interpolate(ys=[0, 9.9],
                                                      nodes='state_input')
        p['traj.phase0.controls:theta'] = phase.interpolate(
            ys=[5, 100.5], nodes='control_input')

        #
        # Solve for the optimal trajectory
        #
        dm.run_problem(p)

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

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

        plot_results(
            [('traj.phase0.timeseries.states:x',
              'traj.phase0.timeseries.states:y', 'x (m)', 'y (m)'),
             ('traj.phase0.timeseries.time',
              'traj.phase0.timeseries.controls:theta', 'time (s)',
              'theta (deg)')],
            title='Brachistochrone Solution\nRadau Pseudospectral Method',
            p_sol=p,
            p_sim=exp_out)

        plt.show()
Example #6
0
    def test_brachistochrone_for_docs_gauss_lobatto(self):
        import openmdao.api as om
        from openmdao.utils.assert_utils import assert_near_equal
        import dymos as dm
        from dymos.examples.plotting import plot_results
        from dymos.examples.brachistochrone import BrachistochroneODE

        #
        # Initialize the Problem and the optimization driver
        #
        p = om.Problem(model=om.Group())
        p.driver = om.ScipyOptimizeDriver()
        p.driver.declare_coloring()

        #
        # Create a trajectory and add a phase to it
        #
        traj = p.model.add_subsystem('traj', dm.Trajectory())

        phase = traj.add_phase(
            'phase0',
            dm.Phase(ode_class=BrachistochroneODE,
                     transcription=dm.GaussLobatto(num_segments=10)))

        #
        # Set the variables
        #
        phase.set_time_options(initial_bounds=(0, 0), duration_bounds=(.5, 10))

        phase.add_state(
            'x',
            rate_source=BrachistochroneODE.states['x']['rate_source'],
            units=BrachistochroneODE.states['x']['units'],
            fix_initial=True,
            fix_final=True,
            solve_segments=False)

        phase.add_state(
            'y',
            rate_source=BrachistochroneODE.states['y']['rate_source'],
            units=BrachistochroneODE.states['y']['units'],
            fix_initial=True,
            fix_final=True,
            solve_segments=False)

        phase.add_state(
            'v',
            rate_source=BrachistochroneODE.states['v']['rate_source'],
            targets=BrachistochroneODE.states['v']['targets'],
            units=BrachistochroneODE.states['v']['units'],
            fix_initial=True,
            fix_final=False,
            solve_segments=False)

        phase.add_control(
            'theta',
            targets=BrachistochroneODE.parameters['theta']['targets'],
            continuity=True,
            rate_continuity=True,
            units='deg',
            lower=0.01,
            upper=179.9)

        phase.add_input_parameter(
            'g',
            targets=BrachistochroneODE.parameters['g']['targets'],
            units='m/s**2',
            val=9.80665)
        #
        # Minimize time at the end of the phase
        #
        phase.add_objective('time', loc='final', scaler=10)

        p.model.linear_solver = om.DirectSolver()

        #
        # Setup the Problem
        #
        p.setup()

        #
        # Set the initial values
        #
        p['traj.phase0.t_initial'] = 0.0
        p['traj.phase0.t_duration'] = 2.0

        p['traj.phase0.states:x'] = phase.interpolate(ys=[0, 10],
                                                      nodes='state_input')
        p['traj.phase0.states:y'] = phase.interpolate(ys=[10, 5],
                                                      nodes='state_input')
        p['traj.phase0.states:v'] = phase.interpolate(ys=[0, 9.9],
                                                      nodes='state_input')
        p['traj.phase0.controls:theta'] = phase.interpolate(
            ys=[5, 100.5], nodes='control_input')

        #
        # Solve for the optimal trajectory
        #
        dm.run_problem(p)

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

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

        plot_results(
            [('traj.phase0.timeseries.states:x',
              'traj.phase0.timeseries.states:y', 'x (m)', 'y (m)'),
             ('traj.phase0.timeseries.time',
              'traj.phase0.timeseries.controls:theta', 'time (s)',
              'theta (deg)')],
            title='Brachistochrone Solution\nHigh-Order Gauss-Lobatto Method',
            p_sol=p,
            p_sim=exp_out)

        plt.show()
    def test_double_integrator_for_docs(self):
        import matplotlib.pyplot as plt
        import openmdao.api as om
        from openmdao.utils.assert_utils import assert_near_equal
        import dymos as dm
        from dymos.examples.plotting import plot_results
        from dymos.examples.double_integrator.double_integrator_ode import DoubleIntegratorODE

        # Initialize the problem and assign the driver
        p = om.Problem(model=om.Group())
        p.driver = om.pyOptSparseDriver()
        p.driver.options['optimizer'] = 'SLSQP'
        p.driver.declare_coloring()

        # Setup the trajectory and its phase
        traj = p.model.add_subsystem('traj', dm.Trajectory())

        transcription = dm.Radau(num_segments=30, order=3, compressed=False)

        phase = traj.add_phase(
            'phase0',
            dm.Phase(ode_class=DoubleIntegratorODE,
                     transcription=transcription))

        #
        # Set the options for our variables.
        #
        phase.set_time_options(fix_initial=True, fix_duration=True, units='s')
        phase.add_state('x', fix_initial=True, rate_source='v', units='m')
        phase.add_state('v',
                        fix_initial=True,
                        fix_final=True,
                        rate_source='u',
                        units='m/s')

        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.
        #
        phase.add_objective('x', loc='final', scaler=-1)

        p.model.linear_solver = om.DirectSolver()

        #
        # Setup the problem and set our initial values.
        #
        p.setup(check=True)

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

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

        #
        # Solve the problem.
        #
        dm.run_problem(p)

        #
        # Verify that the results are correct.
        #
        x = p.get_val('traj.phase0.timeseries.states:x')
        v = p.get_val('traj.phase0.timeseries.states:v')

        assert_near_equal(x[0], 0.0, tolerance=1.0E-4)
        assert_near_equal(x[-1], 0.25, tolerance=1.0E-4)

        assert_near_equal(v[0], 0.0, tolerance=1.0E-4)
        assert_near_equal(v[-1], 0.0, tolerance=1.0E-4)

        #
        # Simulate the explicit solution and plot the results.
        #
        exp_out = traj.simulate()

        plot_results(
            [('traj.phase0.timeseries.time', 'traj.phase0.timeseries.states:x',
              'time (s)', 'x $(m)$'),
             ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.states:v',
              'time (s)', 'v $(m/s)$'),
             ('traj.phase0.timeseries.time',
              'traj.phase0.timeseries.controls:u', 'time (s)', 'u $(m/s^2)$')],
            title='Double Integrator Solution\nRadau Pseudospectral Method',
            p_sol=p,
            p_sim=exp_out)

        plt.show()
    def test_steady_aircraft_for_docs(self):
        import matplotlib.pyplot as plt

        import openmdao.api as om
        from openmdao.utils.assert_utils import assert_near_equal

        import dymos as dm

        from dymos.examples.aircraft_steady_flight.aircraft_ode import AircraftODE
        from dymos.examples.plotting import plot_results
        from dymos.utils.lgl import lgl

        p = om.Problem(model=om.Group())
        p.driver = om.pyOptSparseDriver()
        p.driver.options['optimizer'] = 'SLSQP'
        p.driver.declare_coloring()

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

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

        phase = traj.add_phase(
            'phase0',
            dm.Phase(ode_class=AircraftODE,
                     transcription=dm.Radau(num_segments=num_seg,
                                            segment_ends=seg_ends,
                                            order=3,
                                            compressed=False)))

        # Pass Reference Area from an external source
        assumptions = p.model.add_subsystem('assumptions', om.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(fix_initial=True,
                               duration_bounds=(300, 10000),
                               duration_ref=5600)

        phase.add_state('range',
                        units='NM',
                        rate_source='range_rate_comp.dXdt:range',
                        fix_initial=True,
                        fix_final=False,
                        ref=1e-3,
                        defect_ref=1e-3,
                        lower=0,
                        upper=2000)

        phase.add_state('mass_fuel',
                        units='lbm',
                        rate_source='propulsion.dXdt:mass_fuel',
                        fix_initial=True,
                        fix_final=True,
                        upper=1.5E5,
                        lower=0.0,
                        ref=1e2,
                        defect_ref=1e2)

        phase.add_state('alt',
                        units='kft',
                        rate_source='climb_rate',
                        fix_initial=True,
                        fix_final=True,
                        lower=0.0,
                        upper=60,
                        ref=1e-3,
                        defect_ref=1e-3)

        phase.add_control('climb_rate',
                          units='ft/min',
                          opt=True,
                          lower=-3000,
                          upper=3000,
                          targets=['gam_comp.climb_rate'],
                          rate_continuity=True,
                          rate2_continuity=False)

        phase.add_control('mach',
                          targets=['tas_comp.mach', 'aero.mach'],
                          units=None,
                          opt=False)

        phase.add_parameter(
            'S',
            targets=['aero.S', 'flight_equilibrium.S', 'propulsion.S'],
            units='m**2')

        phase.add_parameter('mass_empty',
                            targets=['mass_comp.mass_empty'],
                            units='kg')
        phase.add_parameter('mass_payload',
                            targets=['mass_comp.mass_payload'],
                            units='kg')

        phase.add_path_constraint('propulsion.tau',
                                  lower=0.01,
                                  upper=2.0,
                                  shape=(1, ))

        p.model.connect('assumptions.S', 'traj.phase0.parameters:S')
        p.model.connect('assumptions.mass_empty',
                        'traj.phase0.parameters:mass_empty')
        p.model.connect('assumptions.mass_payload',
                        'traj.phase0.parameters:mass_payload')

        phase.add_objective('range', loc='final', ref=-1.0e-4)

        phase.add_timeseries_output('aero.CL')
        phase.add_timeseries_output('aero.CD')

        p.setup()

        p['traj.phase0.t_initial'] = 0.0
        p['traj.phase0.t_duration'] = 3600.0
        p['traj.phase0.states:range'][:] = phase.interpolate(
            ys=(0, 724.0), nodes='state_input')
        p['traj.phase0.states:mass_fuel'][:] = phase.interpolate(
            ys=(30000, 1e-3), nodes='state_input')
        p['traj.phase0.states:alt'][:] = 10.0

        p['traj.phase0.controls:mach'][:] = 0.8

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

        dm.run_problem(p)

        assert_near_equal(p.get_val('traj.phase0.timeseries.states:range',
                                    units='NM')[-1],
                          726.85,
                          tolerance=1.0E-2)

        exp_out = traj.simulate()

        assert_near_equal(p.get_val('traj.phase0.timeseries.CL')[0],
                          exp_out.get_val('traj.phase0.timeseries.CL')[0],
                          tolerance=1.0E-9)

        assert_near_equal(p.get_val('traj.phase0.timeseries.CD')[0],
                          exp_out.get_val('traj.phase0.timeseries.CD')[0],
                          tolerance=1.0E-9)

        plot_results(
            [('traj.phase0.timeseries.states:range',
              'traj.phase0.timeseries.states:alt', 'range (NM)',
              'altitude (kft)'),
             ('traj.phase0.timeseries.time',
              'traj.phase0.timeseries.states:mass_fuel', 'time (s)',
              'fuel mass (lbm)'),
             ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.CL',
              'time (s)', 'lift coefficient'),
             ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.CD',
              'time (s)', 'drag coefficient')],
            title='Commercial Aircraft Optimization',
            p_sol=p,
            p_sim=exp_out)

        plt.show()
p['traj.phase0.states:fuel_burnt'][:] = 0
p['traj.phase0.controls:P_gen1'][:] = 1
p['traj.phase0.controls:P_gen2'][:] = 1

# Solve for the optimal trajectory
dm.run_problem(p)

# Test the results
print(p.get_val('traj.phase0.timeseries.states:fuel_burnt')[-1])

# # generate the explicitly simulated trajectory
exp_out = traj.simulate()

fig, axs = plot_results([
    ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.controls:P_gen1',
     'time (s)', 'P1 (kW)'),
    ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.controls:P_gen2',
     'time (s)', 'P2 (kW)'),
    ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.states:fuel_burnt',
     'time (s)', 'fuel burnt (kg)')
],
                        title='Twin Turboelectric Test Case',
                        p_sol=p,
                        p_sim=exp_out)

axs[0].set_ylim(0, 1.1)
axs[1].set_ylim(0, 1.1)
plt.show()

print(p.get_val('traj.phase0.timeseries.states:fuel_burnt')[-1])
Example #10
0
    def test_reentry(self):
        import openmdao.api as om
        from openmdao.utils.assert_utils import assert_near_equal
        import dymos as dm
        from dymos.examples.shuttle_reentry.shuttle_ode import ShuttleODE
        from dymos.examples.plotting import plot_results

        # Instantiate the problem, add the driver, and allow it to use coloring
        p = om.Problem(model=om.Group())
        p.driver = om.pyOptSparseDriver()
        p.driver.declare_coloring()
        p.driver.options['optimizer'] = 'SLSQP'

        # Instantiate the trajectory and add a phase to it
        traj = p.model.add_subsystem('traj', dm.Trajectory())
        phase0 = traj.add_phase('phase0',
                                dm.Phase(ode_class=ShuttleODE,
                                         transcription=dm.Radau(num_segments=15, order=3)))

        phase0.set_time_options(fix_initial=True, units='s', duration_ref=200)
        phase0.add_state('h', fix_initial=True, fix_final=True, units='ft', rate_source='hdot',
                         lower=0, ref0=75000, ref=300000, defect_ref=1000)
        phase0.add_state('gamma', fix_initial=True, fix_final=True, units='rad',
                         rate_source='gammadot',
                         lower=-89. * np.pi / 180, upper=89. * np.pi / 180)
        phase0.add_state('phi', fix_initial=True, fix_final=False, units='rad',
                         rate_source='phidot', lower=0, upper=89. * np.pi / 180)
        phase0.add_state('psi', fix_initial=True, fix_final=False, units='rad',
                         rate_source='psidot', lower=0, upper=90. * np.pi / 180)
        phase0.add_state('theta', fix_initial=True, fix_final=False, units='rad',
                         rate_source='thetadot',
                         lower=-89. * np.pi / 180, upper=89. * np.pi / 180)
        phase0.add_state('v', fix_initial=True, fix_final=True, units='ft/s',
                         rate_source='vdot', lower=0, ref0=2500, ref=25000)
        phase0.add_control('alpha', units='rad', opt=True, lower=-np.pi / 2, upper=np.pi / 2, )
        phase0.add_control('beta', units='rad', opt=True, lower=-89 * np.pi / 180, upper=1 * np.pi / 180, )

        # The original implementation by Betts includes a heating rate path constraint.
        # This will work with the SNOPT optimizer but SLSQP has difficulty converging the solution.
        # phase0.add_path_constraint('q', lower=0, upper=70, ref=70)
        phase0.add_timeseries_output('q', shape=(1,))

        phase0.add_objective('theta', loc='final', ref=-0.01)

        p.setup(check=True)

        p.set_val('traj.phase0.t_initial', 0, units='s')
        p.set_val('traj.phase0.t_duration', 2000, units='s')

        p.set_val('traj.phase0.states:h',
                  phase0.interp('h', [260000, 80000]), units='ft')
        p.set_val('traj.phase0.states:gamma',
                  phase0.interp('gamma', [-1, -5]), units='deg')
        p.set_val('traj.phase0.states:phi',
                  phase0.interp('phi', [0, 75]), units='deg')
        p.set_val('traj.phase0.states:psi',
                  phase0.interp('psi', [90, 10]), units='deg')
        p.set_val('traj.phase0.states:theta',
                  phase0.interp('theta', [0, 25]), units='deg')
        p.set_val('traj.phase0.states:v',
                  phase0.interp('v', [25600, 2500]), units='ft/s')

        p.set_val('traj.phase0.controls:alpha',
                  phase0.interp('alpha', ys=[17.4, 17.4]), units='deg')
        p.set_val('traj.phase0.controls:beta',
                  phase0.interp('beta', ys=[-75, 0]), units='deg')

        # Run the driver
        dm.run_problem(p)

        # Check the validity of the solution
        assert_near_equal(p.get_val('traj.phase0.timeseries.time')[-1], 2008.59,
                          tolerance=1e-3)
        assert_near_equal(p.get_val('traj.phase0.timeseries.states:theta', units='deg')[-1],
                          34.1412, tolerance=1e-3)

        # Run the simulation to check if the model is physically valid
        sim_out = traj.simulate()

        # Plot the results

        plot_results([('traj.phase0.timeseries.time', 'traj.phase0.timeseries.controls:alpha',
                       'time (s)', 'alpha (rad)'),
                      ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.controls:beta',
                       'time (s)', 'beta (rad)'),
                      ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.states:theta',
                       'time (s)', 'theta (rad)'),
                      ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.q',
                       'time (s)', 'q (btu/ft/ft/s')], title='Reentry Solution', p_sol=p,
                     p_sim=sim_out)

        plt.show()
Example #11
0
    def test_min_time_climb_for_docs_gauss_lobatto(self):
        import matplotlib.pyplot as plt

        import openmdao.api as om
        from openmdao.utils.assert_utils import assert_near_equal

        import dymos as dm
        from dymos.examples.min_time_climb.min_time_climb_ode import MinTimeClimbODE
        from dymos.examples.plotting import plot_results

        #
        # Instantiate the problem and configure the optimization driver
        #
        p = om.Problem(model=om.Group())

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

        #
        # Instantiate the trajectory and phase
        #
        traj = dm.Trajectory()

        phase = dm.Phase(ode_class=MinTimeClimbODE,
                         transcription=dm.GaussLobatto(num_segments=15,
                                                       compressed=False))

        traj.add_phase('phase0', phase)

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

        #
        # Set the options on the optimization variables
        # Note the use of explicit state units here since much of the ODE uses imperial units
        # and we prefer to solve this problem using metric units.
        #
        phase.set_time_options(fix_initial=True,
                               duration_bounds=(50, 400),
                               duration_ref=100.0)

        phase.add_state('r',
                        fix_initial=True,
                        lower=0,
                        upper=1.0E6,
                        units='m',
                        ref=1.0E3,
                        defect_ref=1.0E3,
                        rate_source='flight_dynamics.r_dot')

        phase.add_state('h',
                        fix_initial=True,
                        lower=0,
                        upper=20000.0,
                        units='m',
                        ref=1.0E2,
                        defect_ref=1.0E2,
                        rate_source='flight_dynamics.h_dot')

        phase.add_state('v',
                        fix_initial=True,
                        lower=10.0,
                        units='m/s',
                        ref=1.0E2,
                        defect_ref=1.0E2,
                        rate_source='flight_dynamics.v_dot')

        phase.add_state('gam',
                        fix_initial=True,
                        lower=-1.5,
                        upper=1.5,
                        units='rad',
                        ref=1.0,
                        defect_ref=1.0,
                        rate_source='flight_dynamics.gam_dot')

        phase.add_state('m',
                        fix_initial=True,
                        lower=10.0,
                        upper=1.0E5,
                        units='kg',
                        ref=1.0E3,
                        defect_ref=1.0E3,
                        rate_source='prop.m_dot')

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

        phase.add_parameter('S',
                            val=49.2386,
                            units='m**2',
                            opt=False,
                            targets=['S'])
        phase.add_parameter('Isp',
                            val=1600.0,
                            units='s',
                            opt=False,
                            targets=['Isp'])
        phase.add_parameter('throttle',
                            val=1.0,
                            opt=False,
                            targets=['throttle'])

        #
        # Setup the boundary and path constraints
        #
        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,
                                      shape=(1, ))
        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,
                                  shape=(1, ))

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

        p.model.linear_solver = om.DirectSolver()

        #
        # Setup the problem and set the initial guess
        #
        p.setup(check=True)

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

        p['traj.phase0.states:r'] = phase.interpolate(ys=[0.0, 50000.0],
                                                      nodes='state_input')
        p['traj.phase0.states:h'] = phase.interpolate(ys=[100.0, 20000.0],
                                                      nodes='state_input')
        p['traj.phase0.states:v'] = phase.interpolate(ys=[135.964, 283.159],
                                                      nodes='state_input')
        p['traj.phase0.states:gam'] = phase.interpolate(ys=[0.0, 0.0],
                                                        nodes='state_input')
        p['traj.phase0.states:m'] = phase.interpolate(ys=[19030.468, 10000.],
                                                      nodes='state_input')
        p['traj.phase0.controls:alpha'] = phase.interpolate(
            ys=[0.0, 0.0], nodes='control_input')

        #
        # Solve for the optimal trajectory
        #
        dm.run_problem(p)

        #
        # Test the results
        #
        assert_near_equal(p.get_val('traj.phase0.t_duration'),
                          321.0,
                          tolerance=1.0E-1)

        #
        # Get the explicitly simulated solution and plot the results
        #
        exp_out = traj.simulate()

        plot_results(
            [('traj.phase0.timeseries.time', 'traj.phase0.timeseries.states:h',
              'time (s)', 'altitude (m)'),
             ('traj.phase0.timeseries.time',
              'traj.phase0.timeseries.controls:alpha', 'time (s)',
              'alpha (deg)')],
            title='Supersonic Minimum Time-to-Climb Solution',
            p_sol=p,
            p_sim=exp_out)

        plt.show()
Example #12
0
    def test_brachistochrone_for_docs_runge_kutta_polynomial_controls(self):
        import openmdao.api as om
        from openmdao.utils.assert_utils import assert_near_equal
        import dymos as dm
        from dymos.examples.plotting import plot_results
        from dymos.examples.brachistochrone import BrachistochroneODE

        #
        # Initialize the Problem and the optimization driver
        #
        p = om.Problem(model=om.Group())
        p.driver = om.ScipyOptimizeDriver()
        p.driver.declare_coloring()

        #
        # Create a trajectory and add a phase to it
        #
        traj = p.model.add_subsystem('traj', dm.Trajectory())

        phase = traj.add_phase('phase0',
                               dm.Phase(ode_class=BrachistochroneODE,
                                        transcription=dm.RungeKutta(num_segments=10)))

        #
        # Set the variables
        #
        phase.set_time_options(initial_bounds=(0, 0), duration_bounds=(.5, 10))

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

        phase.add_polynomial_control('theta', order=1,
                                     units='deg', lower=0.01, upper=179.9)

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

        #
        # Final state values are not optimization variables, so we must enforce final values
        # with boundary constraints, not simple bounds.
        #
        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 = om.DirectSolver()

        #
        # Setup the Problem
        #
        p.setup()

        #
        # Set the initial values
        #
        p['traj.phase0.t_initial'] = 0.0
        p['traj.phase0.t_duration'] = 2.0

        p['traj.phase0.states:x'] = phase.interpolate(ys=[0, 10], nodes='state_input')
        p['traj.phase0.states:y'] = phase.interpolate(ys=[10, 5], nodes='state_input')
        p['traj.phase0.states:v'] = phase.interpolate(ys=[0, 9.9], nodes='state_input')
        p['traj.phase0.polynomial_controls:theta'][:] = 5.0

        #
        # Solve for the optimal trajectory
        #
        dm.run_problem(p)

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

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

        plot_results([('traj.phase0.timeseries.states:x', 'traj.phase0.timeseries.states:y',
                       'x (m)', 'y (m)'),
                      ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.polynomial_controls:theta',
                       'time (s)', 'theta (deg)')],
                     title='Brachistochrone Solution\nRK4 Shooting and Polynomial Controls',
                     p_sol=p, p_sim=exp_out)

        plt.show()
Example #13
0
    def test_brachistochrone_for_docs_radau(self):
        from openmdao.api import Problem, Group, ScipyOptimizeDriver, DirectSolver, SqliteRecorder
        from openmdao.utils.assert_utils import assert_rel_error
        import dymos as dm
        from dymos.examples.plotting import plot_results
        from dymos.examples.brachistochrone import BrachistochroneODE

        #
        # Initialize the Problem and the optimization driver
        #
        p = Problem(model=Group())
        p.driver = ScipyOptimizeDriver()
        p.driver.options['dynamic_simul_derivs'] = True

        #
        # Create a trajectory and add a phase to it
        #
        traj = p.model.add_subsystem('traj', dm.Trajectory())

        phase = traj.add_phase(
            'phase0',
            dm.Phase(ode_class=BrachistochroneODE,
                     transcription=dm.Radau(num_segments=10)))

        #
        # Set the variables
        #
        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', 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()

        #
        # Setup the Problem
        #
        p.setup()

        #
        # Set the initial values
        #
        p['traj.phase0.t_initial'] = 0.0
        p['traj.phase0.t_duration'] = 2.0

        p['traj.phase0.states:x'] = phase.interpolate(ys=[0, 10],
                                                      nodes='state_input')
        p['traj.phase0.states:y'] = phase.interpolate(ys=[10, 5],
                                                      nodes='state_input')
        p['traj.phase0.states:v'] = phase.interpolate(ys=[0, 9.9],
                                                      nodes='state_input')
        p['traj.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('traj.phase0.timeseries.time')[-1],
                         1.8016,
                         tolerance=1.0E-3)

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

        plot_results(
            [('traj.phase0.timeseries.states:x',
              'traj.phase0.timeseries.states:y', 'x (m)', 'y (m)'),
             ('traj.phase0.timeseries.time',
              'traj.phase0.timeseries.controls:theta', 'time (s)',
              'theta (deg)')],
            title='Brachistochrone Solution\nRadau Pseudospectral Method',
            p_sol=p,
            p_sim=exp_out)

        plt.show()
Example #14
0
                              loc='final',
                              units='K',
                              upper=60,
                              lower=20,
                              shape=(1, ))
phase.add_parameter('d', opt=True, lower=0.00001, upper=0.1)
phase.add_objective('d', loc='final', scaler=1)
p.model.linear_solver = om.DirectSolver()
p.setup()
p['traj.phase0.t_initial'] = 0.0
p['traj.phase0.states:T'] = phase.interpolate(ys=[20, 60], nodes='state_input')
dm.run_problem(p)
exp_out = traj.simulate()
plot_results([('traj.phase0.timeseries.time',
               'traj.phase0.timeseries.states:T', 'time (s)', 'temp (K)')],
             title='Temps',
             p_sol=p,
             p_sim=exp_out)
plt.show()

# t = np.linspace(0, 45, 101)

# def dT_calc(Ts,t):

#     Tf = Ts[0]
#     Tc = Ts[1]
#     K = 0.03 # W/mk
#     A = .102*.0003 # m^2
#     d = 0.003 #m
#     m = 0.06 #kg
#     Cp = 3.58 #kJ/kgK
Example #15
0
p.model.linear_solver = om.DirectSolver()

# Setup the Problem
p.setup()

# Set the initial values
p['traj.phase0.t_initial'] = 0.0
p['traj.phase0.t_duration'] = 2.0

p['traj.phase0.states:x'] = phase.interpolate(ys=[0, 10], nodes='state_input')
p['traj.phase0.states:y'] = phase.interpolate(ys=[10, 5], nodes='state_input')
p['traj.phase0.states:v'] = phase.interpolate(ys=[0, 9.9], nodes='state_input')
p['traj.phase0.controls:theta'] = phase.interpolate(ys=[5, 100.5], nodes='control_input')

# Solve for the optimal trajectory
dm.run_problem(p)

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

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

plot_results([('traj.phase0.timeseries.states:x', 'traj.phase0.timeseries.states:y',
               'x (m)', 'y (m)'),
              ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.controls:theta',
               'time (s)', 'theta (deg)')],
             title='Brachistochrone Solution\nHigh-Order Gauss-Lobatto Method',
             p_sol=p, p_sim=exp_out)

plt.show()