예제 #1
0
    def test_remote_voi(self):
        prob = Problem()

        prob.model.add_subsystem('par', ParallelGroup())

        prob.model.par.add_subsystem('G1', Mygroup())
        prob.model.par.add_subsystem('G2', Mygroup())

        prob.model.add_subsystem('Obj', ExecComp('obj=y1+y2'))

        prob.model.connect('par.G1.y', 'Obj.y1')
        prob.model.connect('par.G2.y', 'Obj.y2')

        prob.model.add_objective('Obj.obj')

        prob.driver = pyOptSparseDriver()
        prob.driver.options['optimizer'] = 'SLSQP'
        prob.setup(vector_class=PETScVector)

        prob.run_driver()

        J = prob.compute_totals(of=['Obj.obj', 'par.G1.c', 'par.G2.c'],
                                wrt=['par.G1.x', 'par.G2.x'])

        assert_rel_error(self, J['Obj.obj', 'par.G1.x'], np.array([[2.0]]), 1e-6)
        assert_rel_error(self, J['Obj.obj', 'par.G2.x'], np.array([[2.0]]), 1e-6)
        assert_rel_error(self, J['par.G1.c', 'par.G1.x'], np.array([[1.0]]), 1e-6)
        assert_rel_error(self, J['par.G1.c', 'par.G2.x'], np.array([[0.0]]), 1e-6)
        assert_rel_error(self, J['par.G2.c', 'par.G1.x'], np.array([[0.0]]), 1e-6)
        assert_rel_error(self, J['par.G2.c', 'par.G2.x'], np.array([[1.0]]), 1e-6)
예제 #2
0
    def set_optimizer(self, optStr):
        assert type(optStr) == type(''), 'Input optimizer must be a string'
        self.optimizer = optStr.upper()

        # Reset all design variables and constraints
        self.design_variables = []
        self.constraints = []
        self.objective = None
        
        # Establish the optimization driver
        if self.optimizer in ['SOGA','SOPSO','NM','SUBPLEX']:
            from openmdao.api import HeuristicDriverParallel
            self.prob.driver = HeuristicDriverParallel()
        #elif self.optimizer in ['SUBPLEX']:
            #from openmdao.api import HeuristicDriver
            #self.prob.driver = HeuristicDriver()
        elif self.optimizer in ['COBYLA','SLSQP']:
            self.prob.driver = ScipyOptimizer()
        elif self.optimizer in ['CONMIN', 'PSQP','SNOPT','NSGA2','ALPSO']:
            from openmdao.api import pyOptSparseDriver
            self.prob.driver = pyOptSparseDriver()
        else:
            raise ValueError('Unknown or unworking optimizer. '+self.optimizer)

        # Set default options
        self.prob.driver.options['optimizer'] = self.optimizer
        if self.optimizer == 'CONMIN':
            self.prob.driver.opt_settings['ITMAX'] = 1000
        elif self.optimizer in ['PSQP']:
            self.prob.driver.opt_settings['MIT'] = 1000
        elif self.optimizer in ['SOGA','SOPSO','NM','SUBPLEX']:
            self.prob.driver.options['population'] = 50
            self.prob.driver.options['generations'] = 500
        elif self.optimizer in ['NSGA2']:
            self.prob.driver.opt_settings['PopSize'] = 200
            self.prob.driver.opt_settings['maxGen'] = 500
        elif self.optimizer in ['SNOPT']:
            self.prob.driver.opt_settings['Iterations limit'] = 500
            self.prob.driver.opt_settings['Major optimality tolerance'] = 1e-4
            self.prob.driver.opt_settings['Major feasibility tolerance'] = 1e-6
            self.prob.driver.opt_settings['Minor feasibility tolerance'] = 1e-6
            self.prob.driver.opt_settings['Function precision'] = 1e-8
        elif self.optimizer in ['COBYLA','SLSQP']:
            self.prob.driver.options['tol'] = 1e-6
            self.prob.driver.options['maxiter'] = 1000
예제 #3
0
    def benchmark_mppt(self):
        model = MPPT_MDP()

        model.add_design_var('pt0.param.CP_Isetpt', lower=0., upper=0.4)
        model.add_design_var('pt1.param.CP_Isetpt', lower=0., upper=0.4)
        model.add_objective('perf.result')

        # create problem and add optimizer
        prob = Problem(model)
        prob.driver = pyOptSparseDriver(optimizer='SNOPT')
        prob.driver.opt_settings = {
            'Major optimality tolerance': 1e-3,
            'Major feasibility tolerance': 1.0e-5,
            'Iterations limit': 500000000,
            'New basis file': 10
        }
        prob.setup()
        prob.run_driver()

        assert_rel_error(self, prob['perf.result'], -9.4308562238E+03, 1e-6)
    # prob = Problem(model)
    # prob.setup()
    # prob.run_model()
    # print(prob['paraboloid.mean_QoI'])
    # print(prob['paraboloid.mean_xi'])

    #------------ Run optimization using SNOPT
    prob = Problem()
    indeps = prob.model.add_subsystem('indeps', IndepVarComp(), promotes=['*'])
    indeps.add_output('mean_xi', 10 * np.ones(3))
    prob.model.add_subsystem('paraboloid',
                             Paraboloid(),
                             promotes_inputs=['mean_xi'])

    # Set up the Optimization
    prob.driver = pyOptSparseDriver()
    prob.driver.options['optimizer'] = 'SNOPT'
    prob.driver.opt_settings['Major optimality tolerance'] = 3e-7
    prob.driver.opt_settings['Major feasibility tolerance'] = 3e-7
    prob.driver.opt_settings['Major iterations limit'] = 1000
    prob.driver.opt_settings['Verify level'] = -1
    prob.model.add_design_var('mean_xi',
                              lower=-20 * np.ones(3),
                              upper=20 * np.ones(3))
    prob.model.add_objective('paraboloid.mean_QoI')

    prob.setup()
    prob.run_driver()
    print(prob['paraboloid.mean_QoI'])
    print(prob['paraboloid.mean_xi'])
예제 #5
0
    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'] = 4
        # 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='forward')))

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

        phase.add_state('x', fix_initial=True)

        phase.add_state('y', fix_initial=True)

        phase.add_state('v', 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()
예제 #6
0
def min_time_climb(optimizer='SLSQP', num_seg=3, transcription='gauss-lobatto',
                   transcription_order=3, force_alloc_complex=False):

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

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

    if optimizer == 'SNOPT':
        p.driver.opt_settings['Major iterations limit'] = 1000
        p.driver.opt_settings['iSumm'] = 6
        p.driver.opt_settings['Major feasibility tolerance'] = 1.0E-6
        p.driver.opt_settings['Major optimality tolerance'] = 1.0E-6
        p.driver.opt_settings['Function precision'] = 1.0E-12
        p.driver.opt_settings['Linesearch tolerance'] = 0.1
        p.driver.opt_settings['Major step limit'] = 0.5

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

    traj = dm.Trajectory()

    phase = dm.Phase(ode_class=MinTimeClimbODE, transcription=t[transcription])
    traj.add_phase('phase0', phase)

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

    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,
                    ref=1.0E3, defect_ref=1.0E3, units='m',
                    rate_source='flight_dynamics.r_dot')

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

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

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

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

    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, targets=['alpha'])

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

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

    # Unnecessary but included to test capability
    phase.add_path_constraint(name='alpha', units='deg', lower=-8, upper=8)
    phase.add_path_constraint(name='time', lower=0, upper=400)
    phase.add_path_constraint(name='time_phase', lower=0, upper=400)

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

    # test mixing wildcard ODE variable expansion and unit overrides
    phase.add_timeseries_output(['aero.*', 'prop.thrust', 'prop.m_dot'],
                                units={'aero.f_lift': 'lbf', 'prop.thrust': 'lbf'})

    p.model.linear_solver = om.DirectSolver()

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

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

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

    p.run_driver()

    return p
예제 #7
0
    def test_ex_double_integrator_input_times(self, compressed=True):
        """
        Tests that externally connected t_initial and t_duration function as expected.
        """

        p = om.Problem(model=om.Group())
        p.driver = om.pyOptSparseDriver()
        p.driver.declare_coloring()

        times_ivc = p.model.add_subsystem('times_ivc',
                                          om.IndepVarComp(),
                                          promotes_outputs=['t0', 'tp'])
        times_ivc.add_output(name='t0', val=0.0, units='s')
        times_ivc.add_output(name='tp', val=1.0, units='s')

        transcription = dm.Radau(num_segments=20,
                                 order=3,
                                 compressed=compressed)
        phase = dm.Phase(ode_class=DoubleIntegratorODE,
                         transcription=transcription)
        p.model.add_subsystem('phase0', phase)

        p.model.connect('t0', 'phase0.t_initial')
        p.model.connect('tp', 'phase0.t_duration')

        phase.set_time_options(input_initial=True,
                               input_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 in one second.
        phase.add_objective('x', loc='final', scaler=-1)

        p.model.linear_solver = om.DirectSolver()

        p.setup(check=True)

        p['t0'] = 0.0
        p['tp'] = 1.0

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

        p.run_driver()
예제 #8
0
def two_burn_orbit_raise_problem(transcription='gauss-lobatto', optimizer='SLSQP', r_target=3.0,
                                 transcription_order=3, compressed=False,
                                 show_output=True):

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

    p.driver = om.pyOptSparseDriver()
    p.driver.options['optimizer'] = optimizer
    p.driver.declare_coloring()
    if optimizer == 'SNOPT':
        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
        if show_output:
            p.driver.opt_settings['iSumm'] = 6
    elif optimizer == 'IPOPT':
        p.driver.opt_settings['hessian_approximation'] = 'limited-memory'
        p.driver.opt_settings['nlp_scaling_method'] = 'gradient-based'
        p.driver.opt_settings['print_level'] = 4
        p.driver.opt_settings['linear_solver'] = 'mumps'
        p.driver.opt_settings['mu_strategy'] = 'adaptive'
        # p.driver.opt_settings['derivative_test'] = 'first-order'

    traj = make_traj(transcription=transcription, transcription_order=transcription_order,
                     compressed=compressed)
    p.model.add_subsystem('traj', subsys=traj)

    # Needed to move the direct solver down into the phases for use with MPI.
    #  - After moving down, used fewer iterations (about 30 less)

    p.setup(check=True)

    # Set Initial Guesses
    p.set_val('traj.parameters:c', value=1.5, units='DU/TU')

    burn1 = p.model.traj.phases.burn1
    burn2 = p.model.traj.phases.burn2
    coast = p.model.traj.phases.coast

    if burn1 in p.model.traj.phases._subsystems_myproc:
        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'))

    if coast in p.model.traj.phases._subsystems_myproc:
        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'))

    if burn2 in p.model.traj.phases._subsystems_myproc:
        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, r_target],
                  nodes='state_input'))
        p.set_val('traj.burn2.states:theta', value=burn2.interpolate(ys=[0, 4.0],
                  nodes='state_input'))
        p.set_val('traj.burn2.states:vr', value=burn2.interpolate(ys=[0, 0],
                                                                  nodes='state_input'))
        p.set_val('traj.burn2.states:vt',
                  value=burn2.interpolate(ys=[1, np.sqrt(1 / r_target)],
                                          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.states:accel', value=burn2.interpolate(ys=[0.1, 0],
                  nodes='state_input'))

        p.set_val('traj.burn2.controls:u1', value=burn2.interpolate(ys=[0, 0],
                  nodes='control_input'))

    dm.run_problem(p, run_driver=False, simulate=True, make_plots=True)

    return p
예제 #9
0
    def test_two_burn_orbit_raise_for_docs(self):
        import numpy as np

        import matplotlib.pyplot as plt

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

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

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

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

        traj.add_design_parameter('c', opt=False, val=1.5)

        # First Phase (burn)

        burn1 = Phase('gauss-lobatto',
                      ode_class=FiniteBurnODE,
                      num_segments=10,
                      transcription_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,
                                defect_scaler=100.0)
        burn1.set_state_options('theta',
                                fix_initial=True,
                                fix_final=False,
                                defect_scaler=100.0)
        burn1.set_state_options('vr',
                                fix_initial=True,
                                fix_final=False,
                                defect_scaler=100.0)
        burn1.set_state_options('vt',
                                fix_initial=True,
                                fix_final=False,
                                defect_scaler=100.0)
        burn1.set_state_options('accel', fix_initial=True, fix_final=False)
        burn1.set_state_options('deltav', fix_initial=True, fix_final=False)
        burn1.add_control('u1',
                          rate_continuity=True,
                          rate2_continuity=True,
                          units='deg',
                          scaler=0.01,
                          rate_continuity_scaler=0.001,
                          rate2_continuity_scaler=0.001,
                          lower=-30,
                          upper=30)

        # Second Phase (Coast)

        coast = Phase('gauss-lobatto',
                      ode_class=FiniteBurnODE,
                      num_segments=10,
                      transcription_order=3,
                      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,
                                defect_scaler=100.0)
        coast.set_state_options('theta',
                                fix_initial=False,
                                fix_final=False,
                                defect_scaler=100.0)
        coast.set_state_options('vr',
                                fix_initial=False,
                                fix_final=False,
                                defect_scaler=100.0)
        coast.set_state_options('vt',
                                fix_initial=False,
                                fix_final=False,
                                defect_scaler=100.0)
        coast.set_state_options('accel', fix_initial=True, fix_final=True)
        coast.set_state_options('deltav', fix_initial=False, fix_final=False)
        coast.add_control('u1', opt=False, val=0.0, units='deg')

        # Third Phase (burn)

        burn2 = Phase('gauss-lobatto',
                      ode_class=FiniteBurnODE,
                      num_segments=10,
                      transcription_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,
                                defect_scaler=100.0)
        burn2.set_state_options('theta',
                                fix_initial=False,
                                fix_final=False,
                                defect_scaler=100.0)
        burn2.set_state_options('vr',
                                fix_initial=False,
                                fix_final=True,
                                defect_scaler=100.0)
        burn2.set_state_options('vt',
                                fix_initial=False,
                                fix_final=True,
                                defect_scaler=100.0)
        burn2.set_state_options('accel',
                                fix_initial=False,
                                fix_final=False,
                                defect_scaler=1.0)
        burn2.set_state_options('deltav',
                                fix_initial=False,
                                fix_final=False,
                                defect_scaler=1.0)
        burn2.add_control('u1',
                          rate_continuity=True,
                          rate2_continuity=True,
                          units='deg',
                          scaler=0.01,
                          rate_continuity_scaler=0.001,
                          rate2_continuity_scaler=0.001,
                          lower=-30,
                          upper=30)

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

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

        # Finish Problem Setup

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

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

        p.setup(check=True)

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

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

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

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

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

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

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

        p.run_driver()

        assert_rel_error(self,
                         traj.get_values('deltav', flat=True)[-1],
                         0.3995,
                         tolerance=2.0E-3)

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

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

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

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

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

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

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

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

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

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

            ax_xy.plot(x_sol[phase_name],
                       y_sol[phase_name],
                       'ro',
                       ms=3,
                       label='implicit' if phase_name == 'burn1' else None)
            ax_xy.plot(x_exp[phase_name],
                       y_exp[phase_name],
                       'b-',
                       label='explicit' if phase_name == 'burn1' else None)

        plt.show()
예제 #10
0
    def setUp(self):

        # --- geometry ----
        # --- geometry ----
        z_param = np.array([0.0, 43.8, 87.6])
        d_param = np.array([6.0, 4.935, 3.87])
        t_param = np.array([0.027*1.3, 0.023*1.3, 0.019*1.3])
        n = 15
        z_full = np.linspace(0.0, 87.6, n)
        L_reinforced = 30.0*np.ones(n)  # [m] buckling length
        theta_stress = 0.0*np.ones(n)
        yaw = 0.0

        # --- material props ---
        E = 210e9*np.ones(n)
        G = 80.8e9*np.ones(n)
        rho = 8500.0*np.ones(n)
        sigma_y = 450.0e6*np.ones(n)

        # --- spring reaction data.  Use float('inf') for rigid constraints. ---
        kidx = np.array([0], dtype=int)  # applied at base
        kx = np.array([float('inf')])
        ky = np.array([float('inf')])
        kz = np.array([float('inf')])
        ktx = np.array([float('inf')])
        kty = np.array([float('inf')])
        ktz = np.array([float('inf')])
        nK = len(kidx)

        # --- extra mass ----
        midx = np.array([n-1], dtype=int)  # RNA mass at top
        m = np.array([285598.8])
        mIxx = np.array([1.14930678e+08])
        mIyy = np.array([2.20354030e+07])
        mIzz = np.array([1.87597425e+07])
        mIxy = np.array([0.00000000e+00])
        mIxz = np.array([5.03710467e+05])
        mIyz = np.array([0.00000000e+00])
        mrhox = np.array([-1.13197635])
        mrhoy = np.array([0.])
        mrhoz = np.array([0.50875268])
        nMass = len(midx)
        addGravityLoadForExtraMass = True
        # -----------

        # --- wind ---
        wind_zref = 90.0
        wind_z0 = 0.0
        shearExp = 0.2
        # ---------------

        # if addGravityLoadForExtraMass=True be sure not to double count by adding those force here also
        # # --- loading case 1: max Thrust ---
        wind_Uref1 = 11.73732
        plidx1 = np.array([n-1], dtype=int)  # at  top
        Fx1 = np.array([1284744.19620519])
        Fy1 = np.array([0.])
        Fz1 = np.array([-2914124.84400512])
        Mxx1 = np.array([3963732.76208099])
        Myy1 = np.array([-2275104.79420872])
        Mzz1 = np.array([-346781.68192839])
        nPL = len(plidx1)
        # # ---------------

        # # --- loading case 2: max wind speed ---
        wind_Uref2 = 70.0
        plidx2 = np.array([n-1], dtype=int)  # at  top
        Fx2 = np.array([930198.60063279])
        Fy2 = np.array([0.])
        Fz2 = np.array([-2883106.12368949])
        Mxx2 = np.array([-1683669.22411597])
        Myy2 = np.array([-2522475.34625363])
        Mzz2 = np.array([147301.97023764])
        # # ---------------

        # --- safety factors ---
        gamma_f = 1.35
        gamma_m = 1.3
        gamma_n = 1.0
        gamma_b = 1.1
        # ---------------

        # --- fatigue ---
        z_DEL = np.array([0.000, 1.327, 3.982, 6.636, 9.291, 11.945, 14.600, 17.255, 19.909, 22.564, 25.218, 27.873, 30.527, 33.182, 35.836, 38.491, 41.145, 43.800, 46.455, 49.109, 51.764, 54.418, 57.073, 59.727, 62.382, 65.036, 67.691, 70.345, 73.000, 75.655, 78.309, 80.964, 83.618, 86.273, 87.600])
        M_DEL = 1e3*np.array([8.2940E+003, 8.1518E+003, 7.8831E+003, 7.6099E+003, 7.3359E+003, 7.0577E+003, 6.7821E+003, 6.5119E+003, 6.2391E+003, 5.9707E+003, 5.7070E+003, 5.4500E+003, 5.2015E+003, 4.9588E+003, 4.7202E+003, 4.4884E+003, 4.2577E+003, 4.0246E+003, 3.7942E+003, 3.5664E+003, 3.3406E+003, 3.1184E+003, 2.8977E+003, 2.6811E+003, 2.4719E+003, 2.2663E+003, 2.0673E+003, 1.8769E+003, 1.7017E+003, 1.5479E+003, 1.4207E+003, 1.3304E+003, 1.2780E+003, 1.2673E+003, 1.2761E+003])
        nDEL = len(z_DEL)
        gamma_fatigue = 1.35*1.3*1.0
        life = 20.0
        m_SN = 4
        # ---------------


        # --- constraints ---
        min_d_to_t = 120.0
        min_taper = 0.4
        # ---------------

        # # V_max = 80.0  # tip speed
        # # D = 126.0
        # # .freq1p = V_max / (D/2) / (2*pi)  # convert to Hz

        nPoints = len(z_param)
        nFull = len(z_full)
        wind = 'PowerWind'

        prob = Problem()
        root = prob.root = Group()

        prob.driver = pyOptSparseDriver()
        prob.driver.options['optimizer'] = 'SNOPT'
        prob.driver.opt_settings['Major iterations limit'] = 1000

        root.add('z_param', IndepVarComp('z_param', z_param))
        root.add('d_param', IndepVarComp('d_param', d_param))
        root.add('t_param', IndepVarComp('t_param', t_param))
        root.add('TowerSE', TowerSE(nPoints, nFull, nK, nMass, nPL, nDEL, wind=wind))


        prob.driver.add_objective('TowerSE.tower1.mass', scaler=1E-6)
        prob.driver.add_desvar('z_param.z_param', lower=np.zeros(nPoints), upper=np.ones(nPoints)*1000., scaler=1E-2)
        prob.driver.add_desvar('t_param.t_param', lower=np.ones(nPoints)*0.001, upper=np.ones(nPoints)*1000., scaler=1E-6)
        prob.driver.add_desvar('d_param.d_param', np.array([2,2.1,2.2]), upper=np.ones(nPoints)*1000., scaler=1E-6)

        prob.root.connect('z_param.z_param', 'TowerSE.z_param')
        prob.root.connect('d_param.d_param', 'TowerSE.d_param')
        prob.root.connect('t_param.t_param', 'TowerSE.t_param')

        prob.driver.add_constraint('TowerSE.tower1.stress', upper=np.ones(n))
        prob.driver.add_constraint('TowerSE.tower2.stress', upper=np.ones(n))
        prob.driver.add_constraint('TowerSE.tower1.global_buckling', upper=np.ones(n))
        prob.driver.add_constraint('TowerSE.tower2.global_buckling', upper=np.ones(n))
        prob.driver.add_constraint('TowerSE.tower1.shell_buckling', upper=np.ones(n))
        prob.driver.add_constraint('TowerSE.tower2.shell_buckling', upper=np.ones(n))
        prob.driver.add_constraint('TowerSE.tower1.damage', upper=np.ones(n)*0.8)
        prob.driver.add_constraint('TowerSE.gc.weldability', upper=np.zeros(n))
        prob.driver.add_constraint('TowerSE.gc.manufacturability', upper=np.zeros(n))
        freq1p = 0.2  # 1P freq in Hz
        prob.driver.add_constraint('TowerSE.tower1.f1', lower=1.1*freq1p)
        prob.driver.add_constraint('TowerSE.tower2.f1', lower=1.1*freq1p)

        prob.setup()

        if wind=='PowerWind':
            prob['TowerSE.wind1.shearExp'] = shearExp
            prob['TowerSE.wind2.shearExp'] = shearExp

        # assign values to params

        # --- geometry ----
        #prob['TowerSE.z_param'] = z_param
        #prob['TowerSE.d_param'] = d_param
        #prob['TowerSE.t_param'] = t_param
        prob['TowerSE.z_full'] = z_full
        prob['TowerSE.tower1.L_reinforced'] = L_reinforced
        prob['TowerSE.distLoads1.yaw'] = yaw

        # --- material props ---
        prob['TowerSE.tower1.E'] = E
        prob['TowerSE.tower1.G'] = G
        prob['TowerSE.tower1.rho'] = rho
        prob['TowerSE.tower1.sigma_y'] = sigma_y

        # --- spring reaction data.  Use float('inf') for rigid constraints. ---
        prob['TowerSE.tower1.kidx'] = kidx
        prob['TowerSE.tower1.kx'] = kx
        prob['TowerSE.tower1.ky'] = ky
        prob['TowerSE.tower1.kz'] = kz
        prob['TowerSE.tower1.ktx'] = ktx
        prob['TowerSE.tower1.kty'] = kty
        prob['TowerSE.tower1.ktz'] = ktz

        # --- extra mass ----
        prob['TowerSE.tower1.midx'] = midx
        prob['TowerSE.tower1.m'] = m
        prob['TowerSE.tower1.mIxx'] = mIxx
        prob['TowerSE.tower1.mIyy'] = mIyy
        prob['TowerSE.tower1.mIzz'] = mIzz
        prob['TowerSE.tower1.mIxy'] = mIxy
        prob['TowerSE.tower1.mIxz'] = mIxz
        prob['TowerSE.tower1.mIyz'] = mIyz
        prob['TowerSE.tower1.mrhox'] = mrhox
        prob['TowerSE.tower1.mrhoy'] = mrhoy
        prob['TowerSE.tower1.mrhoz'] = mrhoz
        prob['TowerSE.tower1.addGravityLoadForExtraMass'] = addGravityLoadForExtraMass
        # -----------

        # --- wind ---
        prob['TowerSE.wind1.zref'] = wind_zref
        prob['TowerSE.wind1.z0'] = wind_z0
        # ---------------

        # # --- loading case 1: max Thrust ---
        prob['TowerSE.wind1.Uref'] = wind_Uref1
        prob['TowerSE.tower1.plidx'] = plidx1
        prob['TowerSE.tower1.Fx'] = Fx1
        prob['TowerSE.tower1.Fy'] = Fy1
        prob['TowerSE.tower1.Fz'] = Fz1
        prob['TowerSE.tower1.Mxx'] = Mxx1
        prob['TowerSE.tower1.Myy'] = Myy1
        prob['TowerSE.tower1.Mzz'] = Mzz1
        # # ---------------

        # # --- loading case 2: max Wind Speed ---
        prob['TowerSE.wind2.Uref'] = wind_Uref2
        prob['TowerSE.tower2.plidx'] = plidx2
        prob['TowerSE.tower2.Fx'] = Fx2
        prob['TowerSE.tower2.Fy'] = Fy2
        prob['TowerSE.tower2.Fz'] = Fz2
        prob['TowerSE.tower2.Mxx'] = Mxx2
        prob['TowerSE.tower2.Myy'] = Myy2
        prob['TowerSE.tower2.Mzz'] = Mzz2
        # # ---------------

        # --- safety factors ---
        prob['TowerSE.tower1.gamma_f'] = gamma_f
        prob['TowerSE.tower1.gamma_m'] = gamma_m
        prob['TowerSE.tower1.gamma_n'] = gamma_n
        prob['TowerSE.tower1.gamma_b'] = gamma_b
        # ---------------

        # --- fatigue ---
        prob['TowerSE.tower1.z_DEL'] = z_DEL
        prob['TowerSE.tower1.M_DEL'] = M_DEL
        prob['TowerSE.tower1.gamma_fatigue'] = gamma_fatigue
        prob['TowerSE.tower1.life'] = life
        prob['TowerSE.tower1.m_SN'] = m_SN
        # ---------------

        # --- constraints ---
        prob['TowerSE.gc.min_d_to_t'] = min_d_to_t
        prob['TowerSE.gc.min_taper'] = min_taper
        # ---------------

        # # --- run ---
        prob.run()

        print prob['TowerSE.gc.weldability']
        print prob['TowerSE.gc.manufacturability']

        self.J = prob.check_total_derivatives(out_stream=None)
        """
예제 #11
0
    def _test_integrate_polynomial_control_rate2(self, transcription):
        #
        # Define the OpenMDAO problem
        #
        p = om.Problem(model=om.Group())

        #
        # Define a Trajectory object
        #
        traj = dm.Trajectory()

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

        #
        # Define a Dymos Phase object with GaussLobatto Transcription
        #
        phase = dm.Phase(ode_class=BrachistochroneODE,
                         transcription=transcription(num_segments=20, order=3))

        traj.add_phase(name='phase0', phase=phase)

        #
        # Set the time options
        # Time has no targets in our ODE.
        # We fix the initial time so that the it is not a design variable in the optimization.
        # The duration of the phase is allowed to be optimized, but is bounded on [0.5, 10].
        #
        phase.set_time_options(fix_initial=True,
                               duration_bounds=(1.0, 10.0),
                               units='s')

        #
        # Set the time options
        # Initial values of positions and velocity are all fixed.
        # The final value of position are fixed, but the final velocity is a free variable.
        # The equations of motion are not functions of position, so 'x' and 'y' have no targets.
        # The rate source points to the output in the ODE which provides the time derivative of the
        # given state.
        phase.add_state('x', fix_initial=True, fix_final=True)
        phase.add_state('y', fix_initial=True, fix_final=True)
        phase.add_state('v', fix_initial=True)

        phase.add_state('int_theta_dot',
                        fix_initial=False,
                        rate_source='theta_rate2')
        phase.add_state('int_theta',
                        fix_initial=False,
                        rate_source='int_theta_dot',
                        targets=['theta'])

        # Define theta as a control.
        phase.add_polynomial_control(name='theta',
                                     order=11,
                                     units='rad',
                                     shape=(1, ),
                                     targets=None)

        # Force the initial value of the theta polynomial control to equal the initial value of the theta state.
        traj.add_linkage_constraint(phase_a='phase0',
                                    phase_b='phase0',
                                    var_a='theta',
                                    var_b='int_theta',
                                    loc_a='initial',
                                    loc_b='initial')

        traj.add_linkage_constraint(phase_a='phase0',
                                    phase_b='phase0',
                                    var_a='int_theta_dot',
                                    var_b='theta_rate',
                                    loc_a='initial',
                                    loc_b='initial',
                                    units='rad/s')

        # Minimize final time.
        phase.add_objective('time', loc='final')

        # Set the driver.
        p.driver = om.pyOptSparseDriver(optimizer='SLSQP')

        # Allow OpenMDAO to automatically determine our sparsity pattern.
        # Doing so can significant speed up the execution of Dymos.
        p.driver.declare_coloring()

        # Setup the problem
        p.setup(check=True)

        # Now that the OpenMDAO problem is setup, we can set the values of the states.

        p.set_val('traj.phase0.t_initial', 0.0, units='s')
        p.set_val('traj.phase0.t_duration', 5.0, units='s')

        p.set_val('traj.phase0.states:x',
                  phase.interp('x', [0, 10]),
                  units='m')
        p.set_val('traj.phase0.states:y',
                  phase.interp('y', [10, 5]),
                  units='m')
        p.set_val('traj.phase0.states:v',
                  phase.interp('v', [0, 5]),
                  units='m/s')
        p.set_val('traj.phase0.states:int_theta',
                  phase.interp('int_theta', [0.1, 45]),
                  units='deg')
        p.set_val('traj.phase0.states:int_theta_dot',
                  phase.interp('int_theta_dot', [0, 0]),
                  units='deg/s')
        p.set_val('traj.phase0.polynomial_controls:theta', 45.0, units='deg')

        # Run the driver to solve the problem
        dm.run_problem(p, simulate=True, make_plots=True)

        sol = om.CaseReader('dymos_solution.db').get_case('final')
        sim = om.CaseReader('dymos_simulation.db').get_case('final')

        t_sol = sol.get_val('traj.phase0.timeseries.time')
        t_sim = sim.get_val('traj.phase0.timeseries.time')

        x_sol = sol.get_val('traj.phase0.timeseries.states:x')
        x_sim = sim.get_val('traj.phase0.timeseries.states:x')

        y_sol = sol.get_val('traj.phase0.timeseries.states:y')
        y_sim = sim.get_val('traj.phase0.timeseries.states:y')

        v_sol = sol.get_val('traj.phase0.timeseries.states:v')
        v_sim = sim.get_val('traj.phase0.timeseries.states:v')

        int_theta_sol = sol.get_val('traj.phase0.timeseries.states:int_theta')
        int_theta_sim = sim.get_val('traj.phase0.timeseries.states:int_theta')

        theta_sol = sol.get_val(
            'traj.phase0.timeseries.polynomial_controls:theta')
        theta_sim = sim.get_val(
            'traj.phase0.timeseries.polynomial_controls:theta')

        assert_timeseries_near_equal(t_sol,
                                     x_sol,
                                     t_sim,
                                     x_sim,
                                     tolerance=1.0E-2)
        assert_timeseries_near_equal(t_sol,
                                     y_sol,
                                     t_sim,
                                     y_sim,
                                     tolerance=1.0E-2)
        assert_timeseries_near_equal(t_sol,
                                     v_sol,
                                     t_sim,
                                     v_sim,
                                     tolerance=1.0E-2)
        assert_timeseries_near_equal(t_sol,
                                     int_theta_sol,
                                     t_sim,
                                     int_theta_sim,
                                     tolerance=1.0E-2)
예제 #12
0
def hp_transient(transcription='gauss-lobatto',
                 num_segments=5,
                 transcription_order=3,
                 compressed=False,
                 optimizer='SLSQP',
                 run_driver=True,
                 force_alloc_complex=True,
                 solve_segments=False,
                 show_plots=False,
                 save=True,
                 Tf_final=370):
    p = om.Problem(model=om.Group())
    model = p.model
    nn = 1
    p.driver = om.ScipyOptimizeDriver()
    p.driver = om.pyOptSparseDriver(optimizer=optimizer)

    p.driver.declare_coloring()

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

    phase = traj.add_phase(
        'phase',
        dm.Phase(ode_class=HeatPipeRun,
                 transcription=dm.GaussLobatto(num_segments=num_segments,
                                               order=transcription_order,
                                               compressed=compressed)))

    phase.set_time_options(fix_initial=True,
                           fix_duration=False,
                           duration_bounds=(1., 3200.))

    phase.add_state(
        'T_cond',
        rate_source='cond.Tdot',
        targets='cond.T',
        units='K',  # ref=333.15, defect_ref=333.15,
        fix_initial=True,
        fix_final=False,
        solve_segments=solve_segments)
    phase.add_state(
        'T_cond2',
        rate_source='cond2.Tdot',
        targets='cond2.T',
        units='K',  # ref=333.15, defect_ref=333.15,
        fix_initial=True,
        fix_final=False,
        solve_segments=solve_segments)

    phase.add_control('T_evap', targets='evap.Rex.T_in', units='K', opt=False)

    phase.add_boundary_constraint('T_cond', loc='final', equals=Tf_final)

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

    phase.add_timeseries_output('evap_bridge.Rv.q',
                                output_name='eRvq',
                                units='W')
    phase.add_timeseries_output('evap_bridge.Rwa.q',
                                output_name='eRwaq',
                                units='W')
    phase.add_timeseries_output('evap_bridge.Rwka.q',
                                output_name='eRwkq',
                                units='W')
    phase.add_timeseries_output('cond_bridge.Rv.q',
                                output_name='cRvq',
                                units='W')
    phase.add_timeseries_output('cond_bridge.Rwa.q',
                                output_name='cRwaq',
                                units='W')
    phase.add_timeseries_output('cond_bridge.Rwka.q',
                                output_name='cRwkq',
                                units='W')
    phase.add_timeseries_output('evap.pcm.PS', output_name='ePS', units=None)
    phase.add_timeseries_output('cond.pcm.PS', output_name='cPS', units=None)
    phase.add_timeseries_output('cond2.pcm.PS', output_name='c2PS', units=None)

    p.model.linear_solver = om.DirectSolver()
    p.setup(force_alloc_complex=force_alloc_complex)

    p['traj.phase.t_initial'] = 0.0
    p['traj.phase.t_duration'] = 195.
    p['traj.phase.states:T_cond'] = phase.interpolate(ys=[293.15, 333.15],
                                                      nodes='state_input')
    p['traj.phase.states:T_cond2'] = phase.interpolate(ys=[293.15, 333.15],
                                                       nodes='state_input')
    p['traj.phase.controls:T_evap'] = phase.interpolate(ys=[333., 338.],
                                                        nodes='control_input')

    p.run_model()

    opt = p.run_driver()
    # sim = traj.simulate(times_per_seg=10)

    print('********************************')

    # save_csv(p, sim, '../../output/output.csv',
    #          y_name=['parameters:T_evap', 'states:T_cond', 'states:T_cond2',
    #                  'eRvq', 'eRwaq', 'eRwkq', 'cRvq', 'cRwaq', 'cRwkq'],
    #          y_units=['K', 'K', 'K', 'W', 'W', 'W', 'W', 'W', 'W'])

    if show_plots:
        import matplotlib.pyplot as plt

        # time = sim.get_val('traj.phase.timeseries.time', units='s')
        time_opt = p.get_val('traj.phase.timeseries.time', units='s')
        # T_cond = sim.get_val('traj.phase.timeseries.states:T_cond', units='K')
        T_cond_opt = p.get_val('traj.phase.timeseries.states:T_cond',
                               units='K')
        # T_cond2 = sim.get_val('traj.phase.timeseries.states:T_cond2', units='K')
        T_cond2_opt = p.get_val('traj.phase.timeseries.states:T_cond2',
                                units='K')
        # T_evap = sim.get_val('traj.phase.timeseries.controls:T_evap', units='K')
        T_evap_opt = p.get_val('traj.phase.timeseries.controls:T_evap',
                               units='K')

        ePS_opt = p.get_val('traj.phase.timeseries.ePS')
        cPS_opt = p.get_val('traj.phase.timeseries.cPS')
        c2PS_opt = p.get_val('traj.phase.timeseries.c2PS')

        plt.plot(time_opt, T_cond_opt)
        # plt.plot(time, T_cond)

        plt.plot(time_opt, T_cond2_opt)
        # plt.plot(time, T_cond2)

        plt.plot(time_opt, T_evap_opt)
        # plt.plot(time, T_evap)

        plt.xlabel('time, s')
        plt.ylabel('T_cond, K')

        plt.show()

        plt.plot(time_opt, cPS_opt)
        # plt.plot(time, EPS)

        plt.plot(time_opt, c2PS_opt)
        # plt.plot(time, T_cond2)

        plt.plot(time_opt, ePS_opt)
        # plt.plot(time, T_evap)

        plt.xlabel('time, s')
        plt.ylabel('percent solid')

        plt.show()

    return p
예제 #13
0
    def _run_transcription(self, transcription):
        p = om.Problem(model=om.Group())

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

        #
        # First Phase: Standard Brachistochrone
        #
        num_segments = 10
        transcription_order = 3
        compressed = False

        if transcription == 'gauss-lobatto':
            tx0 = dm.GaussLobatto(num_segments=num_segments,
                                  order=transcription_order,
                                  compressed=compressed)
            tx1 = dm.GaussLobatto(num_segments=num_segments * 2,
                                  order=transcription_order * 3,
                                  compressed=compressed)

        elif transcription == 'radau-ps':
            tx0 = dm.Radau(num_segments=num_segments,
                           order=transcription_order,
                           compressed=compressed)
            tx1 = dm.Radau(num_segments=num_segments * 2,
                           order=transcription_order * 3,
                           compressed=compressed)

        phase0 = dm.Phase(ode_class=BrachistochroneODE, transcription=tx0)

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

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

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

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

        phase0.add_control('theta',
                           units='deg',
                           rate_continuity=False,
                           lower=0.01,
                           upper=179.9)

        phase0.add_boundary_constraint('x', loc='final', equals=10)
        phase0.add_boundary_constraint('y', loc='final', equals=5)

        # Add alternative timeseries output to provide control inputs for the next phase
        phase0.add_timeseries('timeseries2',
                              transcription=tx1,
                              subset='control_input')

        #
        # Second Phase: Integration of ArcLength
        #

        phase1 = dm.Phase(ode_class=BrachistochroneArclengthODE,
                          transcription=tx1)

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

        phase1.set_time_options(fix_initial=True, input_duration=True)

        phase1.add_state('S',
                         fix_initial=True,
                         fix_final=False,
                         rate_source='Sdot')

        phase1.add_control('theta', opt=False, units='deg', targets=['theta'])
        phase1.add_control('v', opt=False, units='m/s', targets=['v'])

        #
        # Connect the two phases
        #
        p.model.connect('phase0.t_duration', 'phase1.t_duration')

        p.model.connect('phase0.timeseries2.controls:theta',
                        'phase1.controls:theta')
        p.model.connect('phase0.timeseries2.states:v', 'phase1.controls:v')

        # Minimize time at the end of the phase
        # phase1.add_objective('time', loc='final', scaler=1)
        # phase1.add_boundary_constraint('S', loc='final', upper=12)

        phase1.add_objective('S', loc='final', ref=1)

        p.model.linear_solver = om.DirectSolver()
        p.setup(check=True)

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

        p['phase0.states:x'] = phase0.interpolate(ys=[0, 10],
                                                  nodes='state_input')
        p['phase0.states:y'] = phase0.interpolate(ys=[10, 5],
                                                  nodes='state_input')
        p['phase0.states:v'] = phase0.interpolate(ys=[0, 9.9],
                                                  nodes='state_input')
        p['phase0.controls:theta'] = phase0.interpolate(ys=[5, 100],
                                                        nodes='control_input')
        p['phase0.parameters:g'] = 9.80665

        p['phase1.states:S'] = 0.0

        p.run_driver()

        expected = np.sqrt((10 - 0)**2 + (10 - 5)**2)
        assert_near_equal(p['phase1.timeseries.states:S'][-1],
                          expected,
                          tolerance=1.0E-3)
예제 #14
0
    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_near_equal
        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

        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(fix_initial=True,
                               duration_bounds=(10, 1000),
                               targets=['guidance.time_phase'])

        phase.add_state('x',
                        fix_initial=True,
                        lower=0,
                        rate_source='eom.xdot',
                        units='m')
        phase.add_state('y',
                        fix_initial=True,
                        lower=0,
                        rate_source='eom.ydot',
                        units='m')
        phase.add_state('vx',
                        fix_initial=True,
                        lower=0,
                        rate_source='eom.vxdot',
                        targets=['eom.vx'],
                        units='m/s')
        phase.add_state('vy',
                        fix_initial=True,
                        rate_source='eom.vydot',
                        targets=['eom.vy'],
                        units='m/s')
        phase.add_state('m',
                        fix_initial=True,
                        rate_source='eom.mdot',
                        targets=['eom.m'],
                        units='kg')

        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_parameter('a_ctrl',
                            units='1/s',
                            opt=True,
                            targets=['guidance.a_ctrl'])
        phase.add_parameter('b_ctrl',
                            units=None,
                            opt=True,
                            targets=['guidance.b_ctrl'])
        phase.add_parameter('thrust',
                            units='N',
                            opt=False,
                            val=3.0 * 50000.0 * 1.61544,
                            targets=['eom.thrust'])
        phase.add_parameter('Isp',
                            units='s',
                            opt=False,
                            val=1.0E6,
                            targets=['eom.Isp'])

        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.parameters:a_ctrl'] = -0.01
        p['traj.phase0.parameters:b_ctrl'] = 3.0

        dm.run_problem(p)

        #
        # Check the results.
        #
        assert_near_equal(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()
예제 #15
0
    def test_tandem_phases_for_docs(self):
        p = om.Problem(model=om.Group())

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

        #
        # First Phase: Standard Brachistochrone
        #
        num_segments = 10
        transcription_order = 3
        compressed = False

        tx0 = dm.GaussLobatto(num_segments=num_segments,
                              order=transcription_order,
                              compressed=compressed)

        tx1 = dm.Radau(num_segments=num_segments * 2,
                       order=transcription_order * 3,
                       compressed=compressed)

        phase0 = dm.Phase(ode_class=BrachistochroneODE, transcription=tx0)

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

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

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

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

        phase0.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)

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

        phase0.add_input_parameter(
            'g',
            targets=BrachistochroneODE.parameters['g']['targets'],
            units='m/s**2',
            val=9.80665)

        phase0.add_boundary_constraint('x', loc='final', equals=10)
        phase0.add_boundary_constraint('y', loc='final', equals=5)

        # Add alternative timeseries output to provide control inputs for the next phase
        phase0.add_timeseries('timeseries2',
                              transcription=tx1,
                              subset='control_input')

        #
        # Second Phase: Integration of ArcLength
        #

        phase1 = dm.Phase(ode_class=BrachistochroneArclengthODE,
                          transcription=tx1)

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

        phase1.set_time_options(fix_initial=True, input_duration=True)

        phase1.add_state('S',
                         fix_initial=True,
                         fix_final=False,
                         rate_source='Sdot',
                         units='m')

        phase1.add_control('theta', opt=False, units='deg', targets='theta')
        phase1.add_control('v', opt=False, units='m/s', targets='v')

        #
        # Connect the two phases
        #
        p.model.connect('phase0.t_duration', 'phase1.t_duration')

        p.model.connect('phase0.timeseries2.controls:theta',
                        'phase1.controls:theta')
        p.model.connect('phase0.timeseries2.states:v', 'phase1.controls:v')

        # Minimize time at the end of the phase
        # phase1.add_objective('time', loc='final', scaler=1)
        # phase1.add_boundary_constraint('S', loc='final', upper=12)

        phase1.add_objective('S', loc='final', ref=1)

        p.model.linear_solver = om.DirectSolver()
        p.setup(check=True)

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

        p['phase0.states:x'] = phase0.interpolate(ys=[0, 10],
                                                  nodes='state_input')
        p['phase0.states:y'] = phase0.interpolate(ys=[10, 5],
                                                  nodes='state_input')
        p['phase0.states:v'] = phase0.interpolate(ys=[0, 9.9],
                                                  nodes='state_input')
        p['phase0.controls:theta'] = phase0.interpolate(ys=[5, 100],
                                                        nodes='control_input')
        p['phase0.input_parameters:g'] = 9.80665

        p['phase1.states:S'] = 0.0

        p.run_driver()

        expected = np.sqrt((10 - 0)**2 + (10 - 5)**2)
        assert_rel_error(self,
                         p['phase1.timeseries.states:S'][-1],
                         expected,
                         tolerance=1.0E-3)

        fig, (ax0, ax1) = plt.subplots(2, 1)
        fig.tight_layout()
        ax0.plot(p.get_val('phase0.timeseries.states:x'),
                 p.get_val('phase0.timeseries.states:y'), '.')
        ax0.set_xlabel('x (m)')
        ax0.set_ylabel('y (m)')
        ax1.plot(p.get_val('phase1.timeseries.time'),
                 p.get_val('phase1.timeseries.states:S'), '+')
        ax1.set_xlabel('t (s)')
        ax1.set_ylabel('S (m)')
        plt.show()
예제 #16
0
def _make_problem(transcription='gauss-lobatto', num_segments=8, transcription_order=3,
                  compressed=True, optimizer='SLSQP', force_alloc_complex=False,
                  solve_segments=False, y_bounds=None):
    p = om.Problem(model=om.Group())

    p.driver = om.pyOptSparseDriver()
    p.driver.options['optimizer'] = optimizer
    if optimizer == 'SNOPT':
        p.driver.opt_settings['iSumm'] = 6
        p.driver.opt_settings['Verify level'] = 3
    elif optimizer == 'IPOPT':
        p.driver.opt_settings['mu_init'] = 1e-3
        p.driver.opt_settings['max_iter'] = 500
        p.driver.opt_settings['print_level'] = 5
        p.driver.opt_settings['nlp_scaling_method'] = 'gradient-based'  # for faster convergence
        p.driver.opt_settings['alpha_for_y'] = 'safer-min-dual-infeas'
        p.driver.opt_settings['mu_strategy'] = 'monotone'
    p.driver.declare_coloring(tol=1.0E-12)

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

    traj = dm.Trajectory()
    phase = dm.Phase(ode_class=BrachistochroneODE, transcription=t)
    p.model.add_subsystem('traj0', traj)
    traj.add_phase('phase0', phase)

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

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

    if y_bounds is not None:
        phase.set_state_options('y', lower=y_bounds[0], upper=y_bounds[1])

    # Note that by omitting the targets here Dymos will automatically attempt to connect
    # to a top-level input named 'v' in the ODE, and connect to nothing if it's not found.
    phase.add_state('v', fix_initial=False, fix_final=False, solve_segments=solve_segments)

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

    phase.add_parameter('g', targets=['g'], units='m/s**2')

    phase.add_boundary_constraint('x', loc='initial', equals=0)
    phase.add_boundary_constraint('y', loc='initial', equals=10)
    phase.add_boundary_constraint('v', loc='initial', equals=0)

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

    p.set_solver_print(0)

    p.setup(check=['unconnected_inputs'], force_alloc_complex=force_alloc_complex)

    p['traj0.phase0.t_initial'] = 0.0
    p['traj0.phase0.t_duration'] = 1.5

    p['traj0.phase0.states:x'] = phase.interp('x', [0, 10])
    p['traj0.phase0.states:y'] = phase.interp('y', [10, 5])
    p['traj0.phase0.states:v'] = phase.interp('v', [0, 9.9])
    p['traj0.phase0.controls:theta'] = phase.interp('theta', [5, 100])
    p['traj0.phase0.parameters:g'] = 9.80665

    return p
예제 #17
0
    def make_problem(self, transcription=Radau, optimizer='SLSQP', numseg=30):
        p = Problem(model=Group())
        p.driver = pyOptSparseDriver()
        p.driver.declare_coloring()
        OPT, OPTIMIZER = set_pyoptsparse_opt(optimizer, fallback=False)
        p.driver.options['optimizer'] = OPTIMIZER
        if OPTIMIZER == 'SNOPT':
            p.driver.opt_settings['iSumm'] = 6
            p.driver.opt_settings['Verify level'] = 3
        elif OPTIMIZER == 'IPOPT':
            p.driver.opt_settings['nlp_scaling_method'] = 'gradient-based'
            p.driver.opt_settings['max_iter'] = 500
            p.driver.opt_settings['print_level'] = 5
        traj = p.model.add_subsystem('traj', Trajectory())

        phase = traj.add_phase(
            'phase',
            Phase(ode_class=RobotArmODE,
                  transcription=transcription(num_segments=numseg, order=3)))
        phase.set_time_options(fix_initial=True, fix_duration=False)

        phase.add_state('x0',
                        fix_initial=True,
                        fix_final=True,
                        rate_source='x0_dot',
                        units='m')
        phase.add_state('x1',
                        fix_initial=True,
                        fix_final=True,
                        rate_source='x1_dot',
                        units='rad')
        phase.add_state('x2',
                        fix_initial=True,
                        fix_final=True,
                        rate_source='x2_dot',
                        units='rad')
        phase.add_state('x3',
                        fix_initial=True,
                        fix_final=True,
                        rate_source='x3_dot',
                        units='m/s')
        phase.add_state('x4',
                        fix_initial=True,
                        fix_final=True,
                        rate_source='x4_dot',
                        units='rad/s')
        phase.add_state('x5',
                        fix_initial=True,
                        fix_final=True,
                        rate_source='x5_dot',
                        units='rad/s')

        phase.add_control('u0',
                          opt=True,
                          lower=-1,
                          upper=1,
                          scaler=0.1,
                          units='m**2/s**2',
                          continuity=False,
                          rate_continuity=False)
        phase.add_control('u1',
                          opt=True,
                          lower=-1,
                          upper=1,
                          scaler=0.1,
                          units='m**3*rad/s**2',
                          continuity=False,
                          rate_continuity=False)
        phase.add_control('u2',
                          opt=True,
                          lower=-1,
                          upper=1,
                          scaler=0.1,
                          units='m**3*rad/s**2',
                          continuity=False,
                          rate_continuity=False)

        phase.add_path_constraint('u0',
                                  lower=-1,
                                  upper=1,
                                  scaler=0.1,
                                  units='m**2/s**2')
        phase.add_path_constraint('u1',
                                  lower=-1,
                                  upper=1,
                                  scaler=0.1,
                                  units='m**3*rad/s**2')
        phase.add_path_constraint('u2',
                                  lower=-1,
                                  upper=1,
                                  scaler=0.1,
                                  units='m**3*rad/s**2')

        phase.add_objective('time', ref=0.1)

        phase.set_refine_options(refine=True, tol=1e-5, smoothness_factor=1.2)

        p.setup(check=True, force_alloc_complex=False, mode='auto')

        p.set_val('traj.phase.t_initial', 0)
        p.set_val('traj.phase.t_duration', 10)
        p.set_val('traj.phase.states:x0',
                  phase.interpolate(ys=[4.5, 4.5], nodes='state_input'))
        p.set_val(
            'traj.phase.states:x1',
            phase.interpolate(ys=[0.0, 2 * np.pi / 3], nodes='state_input'))
        p.set_val(
            'traj.phase.states:x2',
            phase.interpolate(ys=[np.pi / 4, np.pi / 4], nodes='state_input'))
        p.set_val('traj.phase.states:x3',
                  phase.interpolate(ys=[0.0, 0.0], nodes='state_input'))
        p.set_val('traj.phase.states:x4',
                  phase.interpolate(ys=[0.0, 0.0], nodes='state_input'))
        p.set_val('traj.phase.states:x5',
                  phase.interpolate(ys=[0.0, 0.0], nodes='state_input'))

        return p
예제 #18
0
    def test_discs(self):

        OPT, OPTIMIZER = set_pyoptsparse_opt('SNOPT')

        if OPTIMIZER is not 'SNOPT':
            raise unittest.SkipTest("pyoptsparse is not providing SNOPT or SLSQP")

        # So we compare the same starting locations.
        np.random.seed(123)

        radius = 1.0
        pin = 15.0
        n_disc = 7

        prob = Problem()
        prob.root = root = Group()

        from openmdao.api import pyOptSparseDriver
        driver = prob.driver = pyOptSparseDriver()
        driver.options['optimizer'] = 'SNOPT'
        driver.options['print_results'] = False

        # Note, active tolerance requires relevance reduction to work.
        root.ln_solver.options['single_voi_relevance_reduction'] = True

        # Also, need to be in adjoint
        root.ln_solver.options['mode'] = 'rev'

        obj_expr = 'obj = '
        sep = ''
        for i in range(n_disc):

            dist = "dist_%d" % i
            x1var = 'x_%d' % i

            # First disc is pinned
            if i == 0:
                root.add('p_%d' % i, IndepVarComp(x1var, pin), promotes=(x1var, ))

            # The rest are design variables for the optimizer.
            else:
                init_val = 5.0*np.random.random() - 5.0 + pin
                root.add('p_%d' % i, IndepVarComp(x1var, init_val), promotes=(x1var, ))
                driver.add_desvar(x1var)

            for j in range(i):

                x2var = 'x_%d' % j
                yvar = 'y_%d_%d' % (i, j)
                name = dist + "_%d" % j
                expr = '%s= (%s - %s)**2' % (yvar, x1var, x2var)
                root.add(name, ExecComp(expr), promotes = (x1var, x2var, yvar))

                # Constraint (you can experiment with turning on/off the active_tol)
                #driver.add_constraint(yvar, lower=radius)
                driver.add_constraint(yvar, lower=radius, active_tol=radius*3.0)

                # This pair's contribution to objective
                obj_expr += sep + yvar
                sep = ' + '

        root.add('sum_dist', ExecComp(obj_expr), promotes=('*', ))
        driver.add_objective('obj')

        prob.setup(check=False)
        prob.run()
예제 #19
0
def setup_problem(
        trans=dm.GaussLobatto(num_segments=10), polynomial_control=False):
    from dymos.examples.brachistochrone.brachistochrone_ode import BrachistochroneODE
    from dymos.transcriptions.runge_kutta.runge_kutta import RungeKutta

    p = om.Problem(model=om.Group())
    if isinstance(trans, RungeKutta):
        p.driver = om.pyOptSparseDriver()
    else:
        p.driver = om.ScipyOptimizeDriver()

    phase = dm.Phase(ode_class=BrachistochroneODE, transcription=trans)

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

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

    phase.add_state('x',
                    fix_initial=True,
                    fix_final=not isinstance(trans, RungeKutta))
    phase.add_state('y',
                    fix_initial=True,
                    fix_final=not isinstance(trans, RungeKutta))
    phase.add_state('v', fix_initial=True)

    if not polynomial_control:
        phase.add_control('theta',
                          units='deg',
                          rate_continuity=False,
                          lower=0.01,
                          upper=179.9)
    else:
        phase.add_polynomial_control('theta',
                                     order=1,
                                     units='deg',
                                     lower=0.01,
                                     upper=179.9)

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

    if isinstance(trans, RungeKutta):
        phase.add_timeseries_output('check', units='m/s', shape=(1, ))
        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()

    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')
    if not polynomial_control:
        p['phase0.controls:theta'] = phase.interpolate(ys=[5, 100.5],
                                                       nodes='control_input')
    else:
        p['phase0.polynomial_controls:theta'][:] = 5.0

    return p
예제 #20
0
    model.add_constraint('%s.ConS1' % name, upper=0.0, parallel_deriv_color='con4')
    model.add_constraint('%s_con5.val' % name, equals=0.0)

# Add broadcast parameters
model.add_design_var('bp.cellInstd', lower=0., upper=1.0)
model.add_design_var('bp.finAngle', lower=0., upper=np.pi/2.)
model.add_design_var('bp.antAngle', lower=-np.pi/4, upper=np.pi/4)

# Add objective
model.add_objective('obj.val')

# Instantiate Problem with driver (SNOPT) and recorder
prob = Problem(model)

if 'nopt' not in argv:
    prob.driver = pyOptSparseDriver(optimizer='SNOPT')
    prob.driver.opt_settings = {
        'Major optimality tolerance': 1e-3,
        'Major feasibility tolerance': 1.0e-5,
        'Iterations limit': 500000000
    }

if 'record' in argv:
    if MPI:
        print('recording not supported for parallel runs.')
    else:
        prob.driver.add_recorder(SqliteRecorder('data.sql'))

prob.setup()

# For Parallel execution, we must use KSP or LinearGS
예제 #21
0
    def test_double_integrator_for_docs(self):
        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
        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.
        #
        p.run_driver()

        #
        # 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_rel_error(self, x[0], 0.0, tolerance=1.0E-4)
        assert_rel_error(self, x[-1], 0.25, tolerance=1.0E-4)

        assert_rel_error(self, v[0], 0.0, tolerance=1.0E-4)
        assert_rel_error(self, 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()
예제 #22
0
def flying_robot_direct_collocation(transcription='gauss-lobatto',
                                    compressed=True):

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

    if transcription == 'gauss-lobatto':
        t = dm.GaussLobatto(num_segments=8, order=5, compressed=compressed)
    elif transcription == "radau-ps":
        t = dm.Radau(num_segments=8, order=5, compressed=compressed)
    else:
        raise ValueError('invalid transcription')

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

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

    phase.set_time_options(fix_initial=True,
                           fix_duration=False,
                           duration_bounds=(0.1, 1E4),
                           units='s')

    phase.add_state('x',
                    shape=(2, ),
                    fix_initial=True,
                    fix_final=True,
                    rate_source='v',
                    units='m')
    phase.add_state('v',
                    shape=(2, ),
                    fix_initial=True,
                    fix_final=True,
                    rate_source='u',
                    units='m/s')
    phase.add_state('J',
                    fix_initial=True,
                    fix_final=False,
                    rate_source='u_mag2',
                    units='m**2/s**3')

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

    # Minimize the control effort
    phase.add_objective('time', loc='final')

    p.model.linear_solver = om.DirectSolver()

    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, 0.0],
                                                      [-100.0, 100.0]],
                                                  nodes='state_input')
    p['traj.phase0.states:v'] = phase.interpolate(ys=[[0.0, 0.0], [0.0, 0.0]],
                                                  nodes='state_input')
    p['traj.phase0.controls:u'] = phase.interpolate(ys=[[1, 1], [-1, -1]],
                                                    nodes='control_input')

    p.run_driver()

    return p
def ex_aircraft_steady_flight(optimizer='SLSQP',
                              solve_segments=False,
                              use_boundary_constraints=False,
                              compressed=False):
    p = Problem(model=Group())
    p.driver = pyOptSparseDriver()
    _, optimizer = set_pyoptsparse_opt(optimizer, fallback=False)
    p.driver.options['optimizer'] = optimizer
    p.driver.options['dynamic_simul_derivs'] = True
    if optimizer == 'SNOPT':
        p.driver.opt_settings['Major iterations limit'] = 20
        p.driver.opt_settings['Major feasibility tolerance'] = 1.0E-6
        p.driver.opt_settings['Major optimality tolerance'] = 1.0E-6
        p.driver.opt_settings["Linesearch tolerance"] = 0.10
        p.driver.opt_settings['iSumm'] = 6
    if optimizer == 'SLSQP':
        p.driver.opt_settings['MAXIT'] = 50

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

    phase = dm.Phase(ode_class=AircraftODE,
                     transcription=dm.Radau(num_segments=num_seg,
                                            segment_ends=seg_ends,
                                            order=3,
                                            compressed=compressed,
                                            solve_segments=solve_segments))

    # Pass Reference Area from an external source
    assumptions = p.model.add_subsystem('assumptions', IndepVarComp())
    assumptions.add_output('S', val=427.8, units='m**2')
    assumptions.add_output('mass_empty', val=1.0, units='kg')
    assumptions.add_output('mass_payload', val=1.0, units='kg')

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

    phase.set_time_options(initial_bounds=(0, 0),
                           duration_bounds=(300, 10000),
                           duration_ref=5600)

    fix_final = True
    if use_boundary_constraints:
        fix_final = False
        phase.add_boundary_constraint('mass_fuel',
                                      loc='final',
                                      units='lbm',
                                      equals=1e-3,
                                      linear=False)
        phase.add_boundary_constraint('alt',
                                      loc='final',
                                      units='kft',
                                      equals=10.0,
                                      linear=False)

    phase.set_state_options('range',
                            units='NM',
                            fix_initial=True,
                            fix_final=False,
                            ref=1e-3,
                            defect_ref=1e-3,
                            lower=0,
                            upper=2000)
    phase.set_state_options('mass_fuel',
                            units='lbm',
                            fix_initial=True,
                            fix_final=fix_final,
                            upper=1.5E5,
                            lower=0.0,
                            ref=1e2,
                            defect_ref=1e2)
    phase.set_state_options('alt',
                            units='kft',
                            fix_initial=True,
                            fix_final=fix_final,
                            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,
                      rate_continuity=True,
                      rate2_continuity=False)

    phase.add_control('mach', units=None, opt=False)

    phase.add_input_parameter('S', units='m**2')
    phase.add_input_parameter('mass_empty', units='kg')
    phase.add_input_parameter('mass_payload', units='kg')

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

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

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

    p.setup()

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

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

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

    p.run_driver()

    return p
예제 #24
0
def EESG_Opt_example():
	opt_problem=Problem(root=EESG_Opt())
	
	#Example optimization of an EESG for costs on a 5 MW reference turbine
	
	# add optimizer and set-up problem (using user defined input on objective function)
#	
	opt_problem.driver=pyOptSparseDriver()
	opt_problem.driver.options['optimizer'] = 'CONMIN'
	opt_problem.driver.add_objective('Costs')					# Define Objective
	opt_problem.driver.opt_settings['IPRINT'] = 4
	opt_problem.driver.opt_settings['ITRM'] = 3
	opt_problem.driver.opt_settings['ITMAX'] = 10
	opt_problem.driver.opt_settings['DELFUN'] = 1e-3
	opt_problem.driver.opt_settings['DABFUN'] = 1e-3
	opt_problem.driver.opt_settings['IFILE'] = 'CONMIN_EESG.out'
	opt_problem.root.deriv_options['type']='fd'
	
	# Specificiency target efficiency(%)
	Eta_Target = 93.0	
	
	# Set bounds for design variables for an EESG designed for a 5MW turbine
	
	opt_problem.driver.add_desvar('r_s',lower=0.5,upper=9.0)
	opt_problem.driver.add_desvar('l_s', lower=0.5, upper=2.5)
	opt_problem.driver.add_desvar('h_s', lower=0.06, upper=0.15)
	opt_problem.driver.add_desvar('tau_p', lower=0.04, upper=0.2)
	opt_problem.driver.add_desvar('N_f', lower=10, upper=300)
	opt_problem.driver.add_desvar('I_f', lower=1, upper=500)
	opt_problem.driver.add_desvar('n_r', lower=5.0, upper=15.0)
	opt_problem.driver.add_desvar('h_yr', lower=0.01, upper=0.25)
	opt_problem.driver.add_desvar('h_ys', lower=0.01, upper=0.25)
	opt_problem.driver.add_desvar('b_r', lower=0.1, upper=1.5)
	opt_problem.driver.add_desvar('d_r', lower=0.1, upper=1.5)
	opt_problem.driver.add_desvar('t_wr', lower=0.001, upper=0.2)
	opt_problem.driver.add_desvar('n_s', lower=5.0, upper=15.0)
	opt_problem.driver.add_desvar('b_st', lower=0.1, upper=1.5)
	opt_problem.driver.add_desvar('d_s', lower=0.1, upper=1.5)
	opt_problem.driver.add_desvar('t_ws', lower=0.001, upper=0.2)
	
	# set up constraints for the PMSG_arms generator
	
	opt_problem.driver.add_constraint('B_symax',upper=2.0-1.0e-6)							#1
	opt_problem.driver.add_constraint('B_rymax',upper=2.0-1.0e-6)							#2
	opt_problem.driver.add_constraint('B_tmax',upper=2.0-1.0e-6)							#3
	opt_problem.driver.add_constraint('B_gfm',lower=0.617031,upper=1.057768)  #4
	opt_problem.driver.add_constraint('B_g',lower=0.7,upper=1.2)							#5
	opt_problem.driver.add_constraint('B_pc',upper=2.0)									  		#6
	opt_problem.driver.add_constraint('E_s',lower=500.0,upper=5000.0)					#7
	opt_problem.driver.add_constraint('con_uAs',lower=0.0+1.0e-6)							#8
	opt_problem.driver.add_constraint('con_zAs',lower=0.0+1.0e-6)							#9
	opt_problem.driver.add_constraint('con_yAs',lower=0.0+1.0e-6)  						#10
	opt_problem.driver.add_constraint('con_uAr',lower=0.0+1.0e-6)							#11
	opt_problem.driver.add_constraint('con_zAr',lower=0.0+1.0e-6)							#12
	opt_problem.driver.add_constraint('con_yAr',lower=0.0+1.0e-6) 						#13
	opt_problem.driver.add_constraint('con_TC2',lower=0.0+1.0e-6)							#14
	opt_problem.driver.add_constraint('con_TC3',lower=0.0+1e-6)								#15
	opt_problem.driver.add_constraint('con_br',lower=0.0+1e-6)								#16
	opt_problem.driver.add_constraint('con_bst',lower=0.0-1e-6)								#17
	opt_problem.driver.add_constraint('A_1',upper=60000.0-1e-6)								#18
	opt_problem.driver.add_constraint('J_s',upper=6.0) 									   		#19
	opt_problem.driver.add_constraint('J_f',upper=6.0)												#20
	opt_problem.driver.add_constraint('A_Cuscalc',lower=5.0,upper=300) 				#22
	opt_problem.driver.add_constraint('A_Curcalc',lower=10,upper=300)					#23
	opt_problem.driver.add_constraint('K_rad',lower=0.2+1e-6,upper=0.27)			#24
	opt_problem.driver.add_constraint('Slot_aspect_ratio',lower=4.0,upper=10.0)#25
	opt_problem.driver.add_constraint('gen_eff',lower=Eta_Target)							#26
	opt_problem.driver.add_constraint('n_brushes',upper=6)							      #27
	opt_problem.driver.add_constraint('Power_ratio',upper=2-1.0e-6)						#28
	
	opt_problem.setup()
	
	# Specify Target machine parameters
	opt_problem['machine_rating']=5000000.0
	opt_problem['Torque']=4.143289e6
	
	opt_problem['n_nom']=12.1
	
	# Initial design variables 
	opt_problem['r_s']=3.2
	opt_problem['l_s']=1.4
	opt_problem['h_s']= 0.060
	opt_problem['tau_p']= 0.170
	opt_problem['I_f']= 69
	opt_problem['N_f']= 100
	opt_problem['h_ys']= 0.130
	opt_problem['h_yr']= 0.120
	opt_problem['n_s']= 5
	opt_problem['b_st']= 0.470
	opt_problem['n_r']=5
	opt_problem['b_r']= 0.480
	opt_problem['d_r']= 0.510
	opt_problem['d_s']= 0.400
	opt_problem['t_wr']=0.140
	opt_problem['t_ws']=0.070
	opt_problem['R_o']=0.43      #10MW: 0.523950817,#5MW: 0.43, #3MW:0.363882632 #1.5MW: 0.2775  0.75MW: 0.17625
	
	# Costs
	opt_problem['C_Cu']=4.786
	opt_problem['C_Fe']= 0.556
	opt_problem['C_Fes']=0.50139
	
	#Material properties
	
	opt_problem['rho_Fe']= 7700                 #Magnetic Steel/iron density
	opt_problem['rho_Fes']= 7850                 #structural Steel density
	opt_problem['rho_Copper']=8900                  # Kg/m3 copper density
	
	opt_problem['main_shaft_cm']=np.array([0.0, 0.0, 0.0])
	opt_problem['main_shaft_length'] =2.0
	
	#Run optimization
	opt_problem.run()
		
	"""Uncomment to print solution to screen/an excel file 
def setup_energy_opt(num_seg,
                     order,
                     Q_env=0.,
                     Q_sink=0.,
                     Q_out=0.,
                     m_flow=0.1,
                     m_burn=0.,
                     opt_m_flow=False,
                     opt_m_burn=False):
    """
    Helper function to set up and return a problem instance for an energy minimization
    of a simple thermal system.

    Parameters
    ----------
    num_seg : int
        The number of ODE segments to use when discretizing the problem.
    order : int
        The order for the polynomial interpolation for the collocation methods.
    """

    # Instantiate the problem and set the optimizer
    p = Problem(model=Group())
    p.driver = pyOptSparseDriver()
    p.driver.options['optimizer'] = 'SNOPT'
    p.driver.opt_settings['Major iterations limit'] = 2000
    p.driver.opt_settings['Major feasibility tolerance'] = 1.0E-7
    p.driver.opt_settings['Major optimality tolerance'] = 1.0E-7
    p.driver.opt_settings['Verify level'] = -1

    # Set up the phase for the defined ODE function, can be LGR or LGL
    phase = Phase('gauss-lobatto',
                  ode_class=TankAloneODE,
                  ode_init_kwargs={},
                  num_segments=num_seg,
                  transcription_order=order,
                  compressed=True)

    # Do not allow the time to vary during the optimization
    phase.set_time_options(opt_initial=False, opt_duration=False)

    # Set the state options for mass, temperature, and energy.
    phase.set_state_options('m', lower=1., upper=10., fix_initial=False)
    phase.set_state_options('T', fix_initial=True)
    phase.set_state_options('energy', fix_initial=True)

    # Minimize the energy used to pump the fuel
    # phase.add_objective('energy', loc='final')
    # phase.add_objective('m', loc='initial')
    phase.add_objective('time', loc='final')

    # Allow the optimizer to vary the fuel flow
    if opt_m_flow:
        phase.add_control('m_flow',
                          val=m_flow,
                          lower=0.01,
                          opt=True,
                          rate_continuity=True)
    else:
        phase.add_control('m_flow', val=m_flow, opt=False)

    if opt_m_burn:
        phase.add_control('m_burn',
                          val=m_burn,
                          lower=0.01,
                          opt=True,
                          rate_continuity=True)
    else:
        phase.add_control('m_burn', val=m_burn, opt=False)

    phase.add_control('Q_env', val=Q_env, dynamic=False, opt=False)
    phase.add_control('Q_sink', val=Q_sink, dynamic=False, opt=False)
    phase.add_control('Q_out', val=Q_out, dynamic=False, 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_flow:
        phase.add_path_constraint('T', upper=1.)
        phase.add_path_constraint('m_flow_rate', upper=0.)
        phase.add_path_constraint('m_recirculated', lower=0.)
        phase.add_path_constraint('m_flow', upper=3.)

    # Add the phase to the problem and set it up
    p.model.add_subsystem('phase', phase)
    p.driver.add_recorder(SqliteRecorder('out.db'))
    p.setup(check=True, force_alloc_complex=True, mode='fwd')

    # Give initial values for the phase states, controls, and time
    p['phase.states:m'] = 2.
    p['phase.states:T'] = 1.
    p['phase.states:energy'] = 0.
    p['phase.t_initial'] = 0.
    p['phase.t_duration'] = 10.

    p.set_solver_print(level=-1)

    return p
                    num_inputs = nn
                elif 'bandwidth' in varied_term:
                    bandwidth = nn

                print(
                    f'Running {num_repeats} cases of {num_inputs} num_inputs, {num_outputs} num_outputs, {bandwidth} bandwidth'
                )

                prob = om.Problem()
                prob.model = MatrixGroup(comp_type=MatrixComp,
                                         num_inputs=num_inputs,
                                         num_outputs=num_outputs,
                                         bandwidth=bandwidth,
                                         random_seed=random_seed)

                prob.driver = om.pyOptSparseDriver()
                prob.driver.options['optimizer'] = 'SNOPT'
                prob.driver.opt_settings['Major optimality tolerance'] = 1e-8
                prob.driver.opt_settings['Major print level'] = 0
                prob.driver.opt_settings['Minor print level'] = 0
                prob.driver.opt_settings['iPrint'] = 0

                prob.model.add_design_var('x', lower=-10, upper=10)
                prob.model.add_objective('obj')

                if 'inputs' in varied_term or 'bandwidth' in varied_term:
                    prob.setup(mode='rev')
                else:
                    prob.setup(mode='fwd')

                prob['x'][:] = 2.
    def test_ssto_simulate_root_trajectory(self):
        """
        Tests that we can properly simulate a trajectory even if the trajectory is the root
        group of the model.  In this case the name of the trajectory in the output will
        be 'sim_traj'.
        """
        import numpy as np
        import matplotlib.pyplot as plt
        import openmdao.api as om
        from openmdao.utils.assert_utils import assert_near_equal
        import dymos as dm

        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 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',
                    om.ExecComp('theta=arctan(tan_theta)',
                                theta={
                                    'value': np.ones(nn),
                                    'units': 'rad'
                                },
                                tan_theta={'value': np.ones(nn)}))

                self.add_subsystem('eom', LaunchVehicle2DEOM(num_nodes=nn))

                self.connect('guidance.theta', 'eom.theta')

        #
        # Setup and solve the optimal control problem
        #
        traj = dm.Trajectory()

        p = om.Problem(model=traj)

        phase = dm.Phase(ode_class=LaunchVehicleLinearTangentODE,
                         transcription=dm.Radau(num_segments=20,
                                                order=3,
                                                compressed=False))
        traj.add_phase('phase0', phase)

        phase.set_time_options(fix_initial=True,
                               duration_bounds=(10, 1000),
                               units='s')

        #
        # Set the state options.  We include rate_source, units, and targets here since the ODE
        # is not decorated with their default values.
        #
        phase.add_state('x', fix_initial=True, lower=0, rate_source='eom.xdot')
        phase.add_state('y', fix_initial=True, lower=0, rate_source='eom.ydot')
        phase.add_state('vx',
                        fix_initial=True,
                        lower=0,
                        rate_source='eom.vxdot',
                        units='m/s',
                        targets=['eom.vx'])
        phase.add_state('vy',
                        fix_initial=True,
                        rate_source='eom.vydot',
                        units='m/s',
                        targets=['eom.vy'])
        phase.add_state('m',
                        fix_initial=True,
                        rate_source='eom.mdot',
                        units='kg',
                        targets=['eom.m'])

        #
        # The tangent of theta is modeled as a linear polynomial over the duration of the phase.
        #
        phase.add_polynomial_control('tan_theta',
                                     order=1,
                                     units=None,
                                     opt=True,
                                     targets=['guidance.tan_theta'])

        #
        # Parameters values for thrust and specific impulse are design parameters. They are
        # provided by an IndepVarComp in the phase, but with opt=False their values are not
        # design variables in the optimization problem.
        #
        phase.add_parameter('thrust',
                            units='N',
                            opt=False,
                            val=3.0 * 50000.0 * 1.61544,
                            targets=['eom.thrust'])
        phase.add_parameter('Isp',
                            units='s',
                            opt=False,
                            val=1.0E6,
                            targets=['eom.Isp'])

        #
        # Set the boundary constraints.  These are all states which could also be handled
        # by setting fix_final=True and including the correct final value in the initial guess.
        #
        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_objective('time', index=-1, scaler=0.01)

        #
        # Add theta as a timeseries output since it's not included by default.
        #
        phase.add_timeseries_output('guidance.theta', units='deg')

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

        #
        # We don't strictly need to define a linear solver here since our problem is entirely
        # feed-forward with no iterative loops.  It's good practice to add one, however, since
        # failing to do so can cause incorrect derivatives if iterative processes are ever
        # introduced to the system.
        #
        p.model.linear_solver = om.DirectSolver()

        p.setup(check=True)

        #
        # Assign initial guesses for the independent variables in the problem.
        #
        p['phase0.t_initial'] = 0.0
        p['phase0.t_duration'] = 500.0
        p['phase0.states:x'] = phase.interp('x', [0, 350000.0])
        p['phase0.states:y'] = phase.interp('y', [0, 185000.0])
        p['phase0.states:vx'] = phase.interp('vx', [0, 1627.0])
        p['phase0.states:vy'] = phase.interp('vy', [1.0E-6, 0])
        p['phase0.states:m'] = phase.interp('m', [50000, 50000])
        p['phase0.polynomial_controls:tan_theta'] = [[0.5 * np.pi], [0.0]]

        #
        # Solve the problem.
        #
        p.run_driver()

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

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

        #
        # Plot the results
        #
        fig, axes = plt.subplots(nrows=2, ncols=1, figsize=(10, 8))

        axes[0].plot(p.get_val('phase0.timeseries.states:x'),
                     p.get_val('phase0.timeseries.states:y'),
                     marker='o',
                     ms=4,
                     linestyle='None',
                     label='solution')

        axes[0].plot(exp_out.get_val('sim_traj.phase0.timeseries.states:x'),
                     exp_out.get_val('sim_traj.phase0.timeseries.states:y'),
                     marker=None,
                     linestyle='-',
                     label='simulation')

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

        axes[1].plot(p.get_val('phase0.timeseries.time'),
                     p.get_val('phase0.timeseries.theta'),
                     marker='o',
                     ms=4,
                     linestyle='None')

        axes[1].plot(exp_out.get_val('sim_traj.phase0.timeseries.time'),
                     exp_out.get_val('sim_traj.phase0.timeseries.theta'),
                     linestyle='-',
                     marker=None)

        axes[1].set_xlabel('time (s)')
        axes[1].set_ylabel('theta (deg)')

        plt.suptitle(
            'Single Stage to Orbit Solution Using Polynomial Controls')
        fig.legend(loc='lower center', ncol=2)

        plt.show()
예제 #28
0
    def test_static_parameter_connections_radau(self):
        class TrajectoryODE(om.Group):
            def initialize(self):
                self.options.declare('num_nodes', types=int)

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

                self.add_subsystem(
                    'sum',
                    om.ExecComp('m_tot = sum(m)',
                                m={
                                    'val': np.zeros((2, 2)),
                                    'units': 'kg'
                                },
                                m_tot={
                                    'val': np.zeros(nn),
                                    'units': 'kg'
                                }))

                self.add_subsystem('eom', FlightPathEOM2D(num_nodes=nn))

                self.connect('sum.m_tot', 'eom.m')

        optimizer = 'SLSQP'
        num_segments = 1
        transcription_order = 5

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

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

        seg_ends, _ = lgl(num_segments + 1)

        phase = dm.Phase(ode_class=TrajectoryODE,
                         transcription=dm.Radau(num_segments=num_segments,
                                                order=transcription_order,
                                                segment_ends=seg_ends))

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

        phase.set_time_options(initial_bounds=(0.0, 100.0),
                               duration_bounds=(0., 100.))

        phase.add_state('h',
                        fix_initial=True,
                        fix_final=True,
                        lower=0.0,
                        units='m',
                        rate_source='eom.h_dot')
        phase.add_state('v',
                        fix_initial=True,
                        fix_final=False,
                        units='m/s',
                        rate_source='eom.v_dot')

        phase.add_parameter('m',
                            val=[[1, 2], [3, 4]],
                            units='kg',
                            targets='sum.m',
                            static_target=True)

        p.model.linear_solver = om.DirectSolver()

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

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

        p['phase0.states:h'] = phase.interp('h', [20, 0])
        p['phase0.states:v'] = phase.interp('v', [0, -5])

        p.run_model()

        expected = np.array([[1, 2], [3, 4]])
        assert_near_equal(p.get_val('phase0.rhs_all.sum.m'), expected)
    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', units=None, shape=(1, ))
        phase.add_timeseries_output('aero.CD', units=None, shape=(1, ))

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

        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()
예제 #30
0
    def test_min_time_climb_for_docs_partial_coloring(self):
        import openmdao.api as om
        from openmdao.utils.assert_utils import assert_near_equal

        import dymos as dm
        from dymos.examples.min_time_climb.doc.min_time_climb_ode_partial_coloring import MinTimeClimbODE

        for fd in (False, True):
            if fd:
                pc_options = (False, True)
            else:
                pc_options = (False, )
            for pc in pc_options:
                with self.subTest(
                        f'Finite Differencing: {fd}  Partial Coloring: {pc}'):
                    print(f'Finite Differencing: {fd}  Partial Coloring: {pc}')

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

                    p.driver = om.pyOptSparseDriver()
                    p.driver.options['optimizer'] = 'IPOPT'
                    p.driver.declare_coloring(tol=1.0E-12)
                    p.driver.opt_settings['max_iter'] = 500
                    p.driver.opt_settings[
                        'alpha_for_y'] = 'safer-min-dual-infeas'

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

                    phase = dm.Phase(
                        ode_class=MinTimeClimbODE,
                        ode_init_kwargs={
                            'fd': fd,
                            'partial_coloring': pc
                        },
                        transcription=dm.GaussLobatto(num_segments=30))

                    traj.add_phase('phase0', phase)

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

                    #
                    # Set the options on the optimization variables
                    #
                    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,
                                    ref=1.0E3,
                                    defect_ref=1.0E3,
                                    units='m',
                                    rate_source='flight_dynamics.r_dot')

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

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

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

                    phase.add_state('m',
                                    fix_initial=True,
                                    lower=10.0,
                                    upper=1.0E5,
                                    ref=1.0E3,
                                    defect_ref=1.0E3,
                                    units='kg',
                                    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,
                                      targets=['alpha'])

                    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)
                    phase.add_boundary_constraint('aero.mach',
                                                  loc='final',
                                                  equals=1.0)
                    phase.add_boundary_constraint('gam',
                                                  loc='final',
                                                  equals=0.0)

                    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)

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

                    p.model.linear_solver = om.DirectSolver()

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

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

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

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

                    #
                    # This code is intended to save the coloring plots for the documentation.
                    # In practice, use the command line interface to view these files instead:
                    # `openmdao view_coloring coloring_files/total_coloring.pkl --view`
                    #
                    stfd = '_fd' if fd else ''
                    stpc = '_pc' if pc else ''
                    coloring_dir = f'coloring_files{stfd}{stpc}'
                    if fd or pc:
                        if os.path.exists(coloring_dir):
                            shutil.rmtree(coloring_dir)
                        shutil.move('coloring_files', coloring_dir)

                    _view_coloring(
                        os.path.join(coloring_dir, 'total_coloring.pkl'))

                    #
                    # Test the results
                    #
                    assert_near_equal(p.get_val('traj.phase0.t_duration'),
                                      321.0,
                                      tolerance=1.0E-1)
예제 #31
0
    def setUp(self):
        solver = 'SLSQP'
        num_seg = 10
        seg_ncn = 2
        rel_lengths = 'lgl'

        # Instantiate a problem and set it's root to an empty Trajectory
        prob = Problem()
        prob.add_traj(Trajectory("traj0"))

        if solver == 'SNOPT' and pyOptSparseDriver is not None:
            driver = pyOptSparseDriver()
            driver.options['optimizer'] = solver
            driver.opt_settings['Major iterations limit'] = 1000
            driver.opt_settings['iSumm'] = 6
            driver.opt_settings['Major step limit'] = 0.5
            driver.opt_settings["Major feasibility tolerance"] = 1.0E-5
            driver.opt_settings["Major optimality tolerance"] = 1.0E-5
            driver.opt_settings["Minor feasibility tolerance"] = 1.0E-4
            driver.opt_settings['Verify level'] = 3
        else:
            driver = ScipyOptimizer()
            driver.options['tol'] = 1.0E-6
            driver.options['disp'] = True
            driver.options['maxiter'] = 500

        prob.driver = driver

        dynamic_controls = [{'name': 'theta', 'units': 'rad'},
                            {'name': 'psi', 'units': 'rad'}]

        static_controls = [{'name': 'mass', 'units': 'kg'},
                           {'name': 'g', 'units': 'm/s/s'},
                           {'name': 'Cd', 'units': 'unitless'},
                           {'name': 'D_magnetic', 'units': 'N'},
                           {'name': 'R', 'units': 'J/(kg*K)'},
                           {'name': 'S', 'units': 'm**2'},
                           {'name': 'T_ambient', 'units': 'K'},
                           {'name': 'p_tube', 'units': 'Pa'}]

        phase0 = CollocationPhase(name='phase0', rhs_class=MagnePlaneRHS,
                                  num_seg=num_seg, seg_ncn=seg_ncn,
                                  rel_lengths=rel_lengths,
                                  dynamic_controls=dynamic_controls,
                                  static_controls=static_controls)
        prob.trajectories["traj0"].add_phase(phase0)

        phase0.set_state_options('x', lower=0, upper=100,
                                 ic_val=0, ic_fix=True,
                                 fc_val=10, fc_fix=True,
                                 scaler=10.0, defect_scaler=0.1)

        phase0.set_state_options('y', lower=0, upper=0,
                                 ic_val=0, ic_fix=True,
                                 fc_val=0, fc_fix=True,
                                 scaler=10.0, defect_scaler=0.1)

        phase0.set_state_options('z', lower=-10, upper=10,
                                 ic_val=-10, ic_fix=True,
                                 fc_val=-5, fc_fix=True,
                                 scaler=10.0, defect_scaler=0.1)

        phase0.set_state_options('v', lower=0, upper=np.inf,
                                 ic_val=0.0, ic_fix=True,
                                 fc_val=10.0, fc_fix=False,
                                 scaler=10.0, defect_scaler=0.1)

        phase0.set_dynamic_control_options('theta', ic_val=-1.57, fc_val=0.2,
                                           opt=True, lower=-1.58, upper=1.58,
                                           scaler=0.01)

        phase0.set_dynamic_control_options('psi', ic_val=0.0, fc_val=0.0,
                                           opt=True, lower=0.0, upper=0.0,
                                           scaler=0.01)

        phase0.set_static_control_options(name='g', val=9.80665, opt=False)
        phase0.set_static_control_options(name='mass', val=1200, opt=False)
        phase0.set_static_control_options(name='Cd', val=0.0, opt=False)
        phase0.set_static_control_options(name='S', val=0.0, opt=False)
        phase0.set_static_control_options(name='p_tube', val=0.0, opt=False)
        phase0.set_static_control_options(name='T_ambient', val=298.0,
                                          opt=False)
        phase0.set_static_control_options(name='R', val=287.0, opt=False)

        # Set D_magnetic equal to the thrust value for now, no net forces
        # on the pod except gravity.
        phase0.set_static_control_options(name='D_magnetic', val=30000.0,
                                          opt=False)

        phase0.set_time_options(t0_val=0, t0_lower=0, t0_upper=0, tp_val=1.81,
                                tp_lower=0.5, tp_upper=10.0)

        prob.trajectories["traj0"].add_objective(name="t", phase="phase0",
                                                 place="end", scaler=1.0)

        # Do top-level FD
        prob.root.deriv_options['type'] = 'fd'

        self.prob = prob
예제 #32
0
if __name__ == '__main__':
    # Setup and run the model.

    from openmdao.core.problem import Problem
    from openmdao.drivers.scipy_optimizer import ScipyOptimizer
    from openmdao.api import pyOptSparseDriver
    from openmdao.api import SqliteRecorder

    top = Problem()
    top.root = SellarDerivatives()

    # top.driver = ScipyOptimizer()
    # top.driver.options['optimizer'] = 'SLSQP'
    # top.driver.options['tol'] = 1.0e-8

    top.driver = pyOptSparseDriver()
    top.driver.options['optimizer'] = 'SNOPT'


    top.driver.add_desvar('z', lower=np.array([-10.0, 0.0]),
                         upper=np.array([10.0, 10.0]))
    top.driver.add_desvar('x', lower=0.0, upper=10.0)

    top.driver.add_objective('obj')
    top.driver.add_constraint('con1', upper=0.0)
    top.driver.add_constraint('con2', upper=0.0)
    rec = SqliteRecorder('sellar_snopt.db')
    top.driver.add_recorder(rec)
    rec.options['record_derivs'] = True

    top.setup()
예제 #33
0
    def test_discs(self):

        OPT, OPTIMIZER = set_pyoptsparse_opt('SNOPT')

        if OPTIMIZER is not 'SNOPT':
            raise unittest.SkipTest("pyoptsparse is not providing SNOPT or SLSQP")

        # So we compare the same starting locations.
        np.random.seed(123)

        radius = 1.0
        pin = 15.0
        n_disc = 7

        prob = Problem()
        prob.root = root = Group()

        from openmdao.api import pyOptSparseDriver
        driver = prob.driver = pyOptSparseDriver()
        driver.options['optimizer'] = 'SNOPT'
        driver.options['print_results'] = False

        # Note, active tolerance requires relevance reduction to work.
        root.ln_solver.options['single_voi_relevance_reduction'] = True

        # Also, need to be in adjoint
        root.ln_solver.options['mode'] = 'rev'

        obj_expr = 'obj = '
        sep = ''
        for i in range(n_disc):

            dist = "dist_%d" % i
            x1var = 'x_%d' % i

            # First disc is pinned
            if i == 0:
                root.add('p_%d' % i, IndepVarComp(x1var, pin), promotes=(x1var, ))

            # The rest are design variables for the optimizer.
            else:
                init_val = 5.0*np.random.random() - 5.0 + pin
                root.add('p_%d' % i, IndepVarComp(x1var, init_val), promotes=(x1var, ))
                driver.add_desvar(x1var)

            for j in range(i):

                x2var = 'x_%d' % j
                yvar = 'y_%d_%d' % (i, j)
                name = dist + "_%d" % j
                expr = '%s= (%s - %s)**2' % (yvar, x1var, x2var)
                root.add(name, ExecComp(expr), promotes = (x1var, x2var, yvar))

                # Constraint (you can experiment with turning on/off the active_tol)
                #driver.add_constraint(yvar, lower=radius)
                driver.add_constraint(yvar, lower=radius, active_tol=radius*3.0)

                # This pair's contribution to objective
                obj_expr += sep + yvar
                sep = ' + '

        root.add('sum_dist', ExecComp(obj_expr), promotes=('*', ))
        driver.add_objective('obj')

        prob.setup(check=False)
        prob.run()
예제 #34
0
    def test_simple_no_exception(self):
        p = om.Problem(model=om.Group())

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

        p.driver.declare_coloring()

        transcription = dm.GaussLobatto(num_segments=3,
                                        order=3,
                                        compressed=True,
                                        solve_segments='forward')
        fix_final = True

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

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

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

        # can't fix final position if you're solving the segments
        phase.add_state('pos',
                        rate_source='pos_dot',
                        units='m',
                        fix_initial=True)

        # test add_boundary_constraint with arrays:
        expected = np.array([10, 5])
        phase.add_boundary_constraint(name='pos',
                                      loc='final',
                                      lower=expected - 1)
        phase.add_boundary_constraint(name='pos',
                                      loc='final',
                                      upper=expected + 1)
        phase.add_boundary_constraint(name='pos', loc='final', equals=expected)

        phase.add_state('v',
                        rate_source='vdot',
                        units='m/s',
                        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_parameter('g', units='m/s**2', val=9.80665, opt=False)

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

        p.model.linear_solver = om.DirectSolver()
        p.setup(check=True, force_alloc_complex=True)
        p.final_setup()

        p['traj0.phase0.t_initial'] = 0.0
        p['traj0.phase0.t_duration'] = 1.8016

        pos0 = [0, 10]
        posf = [10, 5]

        p['traj0.phase0.states:pos'] = phase.interpolate(ys=[pos0, posf],
                                                         nodes='state_input')
        p['traj0.phase0.states:v'] = phase.interpolate(ys=[0, 9.9],
                                                       nodes='state_input')
        p['traj0.phase0.controls:theta'] = phase.interpolate(
            ys=[5, 100], nodes='control_input')
        p['traj0.phase0.parameters:g'] = 9.80665

        p.run_driver()
예제 #35
0
    def test_radau(self):
        p = om.Problem(model=om.Group())

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

        t = dm.Radau(num_segments=20, order=[3, 5] * 10, compressed=True)

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

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

        phase.set_time_options(fix_initial=True, 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=False,
            solve_segments=False)
        phase.add_state(
            'y',
            rate_source=BrachistochroneODE.states['y']['rate_source'],
            units=BrachistochroneODE.states['y']['units'],
            fix_initial=True,
            fix_final=False,
            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)

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

        p.model.linear_solver = om.DirectSolver()
        p.setup(check=True)

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

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

        p.run_driver()

        exp_out = phase.simulate()

        t_initial = p.get_val('phase0.timeseries.time')[0]
        tf = p.get_val('phase0.timeseries.time')[-1]

        x0 = p.get_val('phase0.timeseries.states:x')[0]
        xf = p.get_val('phase0.timeseries.states:x')[-1]

        y0 = p.get_val('phase0.timeseries.states:y')[0]
        yf = p.get_val('phase0.timeseries.states:y')[-1]

        v0 = p.get_val('phase0.timeseries.states:v')[0]
        vf = p.get_val('phase0.timeseries.states:v')[-1]

        g = p.get_val('phase0.timeseries.input_parameters:g')[0]

        thetaf = exp_out.get_val('phase0.timeseries.controls:theta')[-1]

        assert_almost_equal(t_initial, 0.0)
        assert_almost_equal(x0, 0.0)
        assert_almost_equal(y0, 10.0)
        assert_almost_equal(v0, 0.0)

        assert_almost_equal(tf, 1.8016, decimal=3)
        assert_almost_equal(xf, 10.0, decimal=3)
        assert_almost_equal(yf, 5.0, decimal=3)
        assert_almost_equal(vf, 9.902, decimal=3)
        assert_almost_equal(g, 9.80665, decimal=3)

        assert_almost_equal(thetaf, 100.12, decimal=0)
예제 #36
0
def min_time_climb(optimizer='SLSQP', num_seg=3, transcription='gauss-lobatto',
                   transcription_order=3, top_level_jacobian='csc', simul_derivs=True,
                   force_alloc_complex=False):

    p = Problem(model=Group())

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

    if optimizer == 'SNOPT':
        p.driver.opt_settings['Major iterations limit'] = 1000
        p.driver.opt_settings['iSumm'] = 6
        p.driver.opt_settings['Major feasibility tolerance'] = 1.0E-6
        p.driver.opt_settings['Major optimality tolerance'] = 1.0E-6
        p.driver.opt_settings['Function precision'] = 1.0E-6
        p.driver.opt_settings['Linesearch tolerance'] = 0.10
        p.driver.opt_settings['Major step limit'] = 0.5
        # p.driver.opt_settings['Verify level'] = 3

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

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

    phase.set_time_options(fix_initial=True, duration_bounds=(50, 400),
                           duration_ref=100.0)

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

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

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

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

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

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

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

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

    phase.add_path_constraint(name='h', lower=100.0, upper=20000, ref=20000)
    phase.add_path_constraint(name='aero.mach', lower=0.1, upper=1.8)
    phase.add_path_constraint(name='alpha', lower=-8, upper=8)

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

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

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

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

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

    p.run_driver()

    if SHOW_PLOTS:
        exp_out = phase.simulate(times=np.linspace(0, p['phase0.t_duration'], 100))

        import matplotlib.pyplot as plt
        plt.plot(phase.get_values('time'), phase.get_values('h'), 'ro')
        plt.plot(exp_out.get_values('time'), exp_out.get_values('h'), 'b-')
        plt.xlabel('time (s)')
        plt.ylabel('altitude (m)')

        plt.figure()
        plt.plot(phase.get_values('v'), phase.get_values('h'), 'ro')
        plt.plot(exp_out.get_values('v'), exp_out.get_values('h'), 'b-')
        plt.xlabel('airspeed (m/s)')
        plt.ylabel('altitude (m)')

        plt.figure()
        plt.plot(phase.get_values('time'), phase.get_values('alpha'), 'ro')
        plt.plot(exp_out.get_values('time'), exp_out.get_values('alpha'), 'b-')
        plt.xlabel('time (s)')
        plt.ylabel('alpha (rad)')

        plt.figure()
        plt.plot(phase.get_values('time'), phase.get_values('prop.thrust', units='lbf'), 'ro')
        plt.plot(exp_out.get_values('time'), exp_out.get_values('prop.thrust', units='lbf'), 'b-')
        plt.xlabel('time (s)')
        plt.ylabel('thrust (lbf)')

        plt.show()

    return p
예제 #37
0
import openmdao.api as om
from testbed_components import simple_1D_low, simple_1D_high

np.random.seed(314)

mm = om.MultiFiMetaModelUnStructuredComp(nfi=2)
mm.add_input("x", np.zeros((1, )))
mm.add_output("y", np.zeros((1, )))

# Surrrogate model that implements the multifidelity cokriging method.
mm.options["default_surrogate"] = om.MultiFiCoKrigingSurrogate(normalize=False)

prob = om.Problem()
prob.model.add_subsystem("mm", mm, promotes=["*"])

prob.driver = om.pyOptSparseDriver()  # om.ScipyOptimizeDriver() #
prob.driver.options["optimizer"] = "SNOPT"
# prob.driver.opt_settings['Verify level'] = -1

# --- Objective ---
prob.model.add_objective("y")

prob.model.add_design_var("x", lower=0.0, upper=1.0)

prob.setup()

prob["x"] = 0.8

s = time()

num_high = 5
    def test(self):

        from openaerostruct.geometry.utils import generate_mesh, write_FFD_file
        from openaerostruct.geometry.geometry_group import Geometry
        from openaerostruct.transfer.displacement_transfer import DisplacementTransfer

        from openaerostruct.aerodynamics.aero_groups import AeroPoint
        from openaerostruct.integration.multipoint_comps import MultiCD

        from openmdao.api import IndepVarComp, Problem, Group, NewtonSolver, ScipyIterativeSolver, LinearBlockGS, NonlinearBlockGS, DirectSolver, LinearBlockGS, PetscKSP, ScipyOptimizeDriver, ExplicitComponent# TODO, SqliteRecorder, CaseReader, profile
        from openmdao.devtools import iprofile
        from openmdao.api import view_model
        from openmdao.utils.assert_utils import assert_check_partials
        from pygeo import DVGeometry

        # Create a dictionary to store options about the surface
        mesh_dict = {'num_y' : 5,
                     'num_x' : 3,
                     'wing_type' : 'CRM',
                     'symmetry' : True,
                     'num_twist_cp' : 5,
                     'span_cos_spacing' : 0.}

        mesh, _ = generate_mesh(mesh_dict)

        surf_dict = {
                    # Wing definition
                    'name' : 'wing',        # name of the surface
                    'type' : 'aero',
                    'symmetry' : True,     # if true, model one half of wing
                                            # reflected across the plane y = 0
                    'S_ref_type' : 'wetted', # how we compute the wing area,
                                             # can be 'wetted' or 'projected'
                    'fem_model_type' : 'tube',

                    'mesh' : mesh,
                    'mx' : 2,
                    'my' : 3,
                    'geom_manipulator' : 'FFD',

                    # Aerodynamic performance of the lifting surface at
                    # an angle of attack of 0 (alpha=0).
                    # These CL0 and CD0 values are added to the CL and CD
                    # obtained from aerodynamic analysis of the surface to get
                    # the total CL and CD.
                    # These CL0 and CD0 values do not vary wrt alpha.
                    'CL0' : 0.0,            # CL of the surface at alpha=0
                    'CD0' : 0.015,            # CD of the surface at alpha=0

                    # Airfoil properties for viscous drag calculation
                    'k_lam' : 0.05,         # percentage of chord with laminar
                                            # flow, used for viscous drag
                    't_over_c_cp' : np.array([0.15]),      # thickness over chord ratio (NACA0015)
                    'c_max_t' : .303,       # chordwise location of maximum (NACA0015)
                                            # thickness
                    'with_viscous' : True,  # if true, compute viscous drag
                    'with_wave' : False,     # if true, compute wave drag
                    }

        surfaces = [surf_dict]

        n_points = 2

        # Create the problem and the model group
        prob = Problem()

        indep_var_comp = IndepVarComp()
        indep_var_comp.add_output('v', val=248.136, units='m/s')
        indep_var_comp.add_output('alpha', val=np.ones(n_points)*6.64, units='deg')
        indep_var_comp.add_output('M', val=0.84)
        indep_var_comp.add_output('re', val=1.e6, units='1/m')
        indep_var_comp.add_output('rho', val=0.38, units='kg/m**3')
        indep_var_comp.add_output('cg', val=np.zeros((3)), units='m')

        prob.model.add_subsystem('prob_vars',
            indep_var_comp,
            promotes=['*'])


        # Loop through and add a certain number of aero points
        for i in range(n_points):

            # Create the aero point group and add it to the model
            aero_group = AeroPoint(surfaces=surfaces)
            point_name = 'aero_point_{}'.format(i)
            prob.model.add_subsystem(point_name, aero_group)

            # Connect flow properties to the analysis point
            prob.model.connect('v', point_name + '.v')
            prob.model.connect('alpha', point_name + '.alpha', src_indices=[i])
            prob.model.connect('M', point_name + '.M')
            prob.model.connect('re', point_name + '.re')
            prob.model.connect('rho', point_name + '.rho')
            prob.model.connect('cg', point_name + '.cg')

            # Connect the parameters within the model for each aero point
            for surface in surfaces:

                filename = write_FFD_file(surface, surface['mx'], surface['my'])
                DVGeo = DVGeometry(filename)
                geom_group = Geometry(surface=surface, DVGeo=DVGeo)

                # Add tmp_group to the problem as the name of the surface.
                # Note that is a group and performance group for each
                # individual surface.
                aero_group.add_subsystem(surface['name'] + '_geom', geom_group)

                name = surface['name']
                prob.model.connect(point_name + '.CD', 'multi_CD.' + str(i) + '_CD')

                # Connect the mesh from the geometry component to the analysis point
                prob.model.connect(point_name + '.' + name + '_geom.mesh', point_name + '.' + name + '.def_mesh')

                # Perform the connections with the modified names within the
                # 'aero_states' group.
                prob.model.connect(point_name + '.' + name + '_geom.mesh', point_name + '.aero_states.' + name + '_def_mesh')

                prob.model.connect(point_name + '.' + name + '_geom.t_over_c', point_name + '.' + name + '_perf.' + 't_over_c')

        prob.model.add_subsystem('multi_CD', MultiCD(n_points=n_points), promotes_outputs=['CD'])

        from openmdao.api import pyOptSparseDriver
        prob.driver = pyOptSparseDriver()
        prob.driver.options['optimizer'] = "SNOPT"
        prob.driver.opt_settings = {'Major optimality tolerance': 1.0e-5,
                                    'Major feasibility tolerance': 1.0e-5}

        # # Setup problem and add design variables, constraint, and objective
        prob.model.add_design_var('alpha', lower=-15, upper=15)

        prob.model.add_design_var('aero_point_0.wing_geom.shape', lower=-3, upper=2)
        prob.model.add_constraint('aero_point_0.wing_perf.CL', equals=0.45)

        prob.model.add_design_var('aero_point_1.wing_geom.shape', lower=-3, upper=2)
        prob.model.add_constraint('aero_point_1.wing_perf.CL', equals=0.5)

        prob.model.add_objective('CD', scaler=1e4)

        # Set up the problem
        prob.setup()

        prob.run_model()

        # Check the partials at this point in the design space
        data = prob.check_partials(compact_print=True, out_stream=None, method='cs', step=1e-40)
        assert_check_partials(data, atol=1e20, rtol=1e-6)
예제 #39
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)
        phase.add_boundary_constraint('aero.mach', loc='final', equals=1.0)
        phase.add_boundary_constraint('gam', loc='final', equals=0.0)

        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)

        # 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.set_val('traj.phase0.states:r', phase.interp('r', [0.0, 50000.0]))
        p.set_val('traj.phase0.states:h', phase.interp('h', [100.0, 20000.0]))
        p.set_val('traj.phase0.states:v', phase.interp('v',
                                                       [135.964, 283.159]))
        p.set_val('traj.phase0.states:gam', phase.interp('gam', [0.0, 0.0]))
        p.set_val('traj.phase0.states:m', phase.interp('m',
                                                       [19030.468, 10000.]))
        p.set_val('traj.phase0.controls:alpha',
                  phase.interp('alpha', [0.0, 0.0]))

        #
        # 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()
예제 #40
0
                               params_IdepVar_func=add_floris_params_IndepVarComps,
                               params_IndepVar_args={}))

    jensen_prob = Problem(root=OptAEP(nTurbines=nTurbines, nDirections=nDirections, use_rotor_components=False,
                               wake_model=jensen_wrapper, wake_model_options={'variant': 'CosineYaw_1R',
                                                                              'radius multiplier': 1.0}, datasize=0,
                               params_IdepVar_func=add_jensen_params_IndepVarComps,
                               params_IndepVar_args={'use_angle': True}))

    probs = [gauss_prob, floris_prob, jensen_prob]
    names = ['gauss', 'floris', 'jensen']

    for indx, prob in enumerate(probs):

        # set up optimizer
        prob.driver = pyOptSparseDriver()
        prob.driver.options['optimizer'] = 'SNOPT'
        prob.driver.add_objective('obj', scaler=1E-5)
    
        # set optimizer options
        prob.driver.opt_settings['Verify level'] = 3
        prob.driver.opt_settings['Print file'] = 'SNOPT_print_exampleOptYaw_%s.out' % names[indx]
        prob.driver.opt_settings['Summary file'] = 'SNOPT_summary_exampleOptYaw_%s.out' % names[indx]
        prob.driver.opt_settings['Major iterations limit'] = 1000
    
        # select design variables
        for direction_id in range(0, nDirections):
            prob.driver.add_desvar('yaw%i' % direction_id, lower=-30.0, upper=30.0, scaler=1)

        prob.setup()
예제 #41
0
    def setup_prob(self):
        """
        Short method to select the optimizer. Uses pyOptSparse if available,
        or Scipy's SLSQP otherwise.
        """

        try:  # Use pyOptSparse optimizer if installed
            from openmdao.api import pyOptSparseDriver
            self.prob.driver = pyOptSparseDriver()
            if self.prob_dict['optimizer'] == 'SNOPT':
                self.prob.driver.options['optimizer'] = "SNOPT"
                self.prob.driver.opt_settings = {'Major optimality tolerance': 1.0e-8,
                                                 'Major feasibility tolerance': 1.0e-8,
                                                 'Major iterations limit':400,
                                                 'Minor iterations limit':2000,
                                                 'Iterations limit':1000
                                                 }
            elif self.prob_dict['optimizer'] == 'ALPSO':
                self.prob.driver.options['optimizer'] = 'ALPSO'
                self.prob.driver.opt_settings = {'SwarmSize': 40,
                                                'maxOuterIter': 200,
                                                'maxInnerIter': 6,
                                                'rtol': 1e-5,
                                                'atol': 1e-5,
                                                'dtol': 1e-5,
                                                'printOuterIters': 1
                                                 }
            elif self.prob_dict['optimizer'] == 'NOMAD':
                self.prob.driver.options['optimizer'] = 'NOMAD'
                self.prob.driver.opt_settings = {'maxiter':1000,
                                                'minmeshsize':1e-12,
                                                'minpollsize':1e-12,
                                                'displaydegree':0,
                                                'printfile':1
                                                }
            elif self.prob_dict['optimizer'] == 'SLSQP':
                self.prob.driver.options['optimizer'] = 'SLSQP'
                self.prob.driver.opt_settings = {'ACC' : 1e-10
                                                }

        except:  # Use Scipy SLSQP optimizer if pyOptSparse not installed
            self.prob.driver = ScipyOptimizer()
            self.prob.driver.options['optimizer'] = 'SLSQP'
            self.prob.driver.options['disp'] = True
            self.prob.driver.options['tol'] = 1.0e-10

        # Actually call the OpenMDAO functions to add the design variables,
        # constraints, and objective.
        for desvar_name, desvar_data in iteritems(self.desvars):
            self.prob.driver.add_desvar(desvar_name, **desvar_data)
        for con_name, con_data in iteritems(self.constraints):
            self.prob.driver.add_constraint(con_name, **con_data)
        for obj_name, obj_data in iteritems(self.objective):
            self.prob.driver.add_objective(obj_name, **obj_data)

        # Use finite differences over the entire model if user selected it
        if self.prob_dict['force_fd']:
            self.prob.root.deriv_options['type'] = 'fd'

        # Record optimization history to a database.
        # Data saved here can be examined using `plot_all.py` or `OptView.py`
        if self.prob_dict['record_db']:
            recorder = SqliteRecorder(self.prob_dict['prob_name']+".db")
            recorder.options['record_params'] = True
            recorder.options['record_derivs'] = True
            self.prob.driver.add_recorder(recorder)

        # Profile (time) the problem
        if self.prob_dict['profile']:
            profile.setup(self.prob)
            profile.start()

        # Set up the problem
        self.prob.setup()

        # Use warm start from previous db file if desired.
        # Note that we only have access to the unknowns, not the gradient history.
        if self.prob_dict['previous_case_db'] is not None:

            # Open the previous case and start from the last iteration.
            # Change the -1 value in get_case() if you want to select a different iteration.
            cr = CaseReader(self.prob_dict['previous_case_db'])
            case = cr.get_case(-1)

            # Loop through the unknowns and set them for this problem.
            for param_name, param_data in iteritems(case.unknowns):
                self.prob[param_name] = param_data