Exemplo n.º 1
0
    def test_brachistochrone_forward_shooting_path_constrained_ode_output(self):
        from openmdao.api import Problem, Group, ScipyOptimizeDriver, DirectSolver
        from openmdao.utils.assert_utils import assert_rel_error
        from dymos import Phase, RungeKutta
        from dymos.examples.brachistochrone.brachistochrone_ode import BrachistochroneODE

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

        phase = Phase(ode_class=BrachistochroneODE,
                      transcription=RungeKutta(num_segments=20))

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

        phase.set_time_options(initial_bounds=(0, 0), duration_bounds=(0.5, 2.0))

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

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

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

        # Final state values can't be controlled with simple bounds in ExplicitPhase,
        # so use nonlinear boundary constraints instead.
        phase.add_boundary_constraint('x', loc='final', equals=10)
        phase.add_boundary_constraint('y', loc='final', equals=5)
        phase.add_path_constraint('check', lower=-500, upper=500, shape=(1,), units='m/s')

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

        p.model.linear_solver = DirectSolver()

        p.setup(check=True)

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

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

        # Solve for the optimal trajectory
        p.run_driver()

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

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

        assert_rel_error(self, exp_out.get_val('phase0.timeseries.states:x')[-1, 0], 10,
                         tolerance=1.0E-3)
        assert_rel_error(self, exp_out.get_val('phase0.timeseries.states:y')[-1, 0], 5,
                         tolerance=1.0E-3)
Exemplo n.º 2
0
    def test_control_rate_path_constraint_gl(self):
        from openmdao.api import Problem, Group, ScipyOptimizeDriver, DirectSolver
        from openmdao.utils.assert_utils import assert_rel_error
        from dymos import Phase, GaussLobatto
        from dymos.examples.brachistochrone.brachistochrone_ode import BrachistochroneODE

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

        phase = Phase(ode_class=BrachistochroneODE,
                      transcription=GaussLobatto(num_segments=10))

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

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

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

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

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

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

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

        p.model.linear_solver = DirectSolver()

        p.setup()

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

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

        # Solve for the optimal trajectory
        p.run_driver()

        # Test the results
        assert_rel_error(self,
                         p.get_val('phase0.timeseries.time')[-1],
                         1.8016,
                         tolerance=1.0E-3)
Exemplo n.º 3
0
    def test_min_time_climb_for_docs_gauss_lobatto(self):
        import numpy as np

        import matplotlib
        matplotlib.use('Agg')
        import matplotlib.pyplot as plt

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

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

        p = Problem(model=Group())

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

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

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

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

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

        phase.set_state_options('r',
                                fix_initial=True,
                                lower=0,
                                upper=1.0E6,
                                ref=1.0E3,
                                defect_ref=1000.0,
                                units='m')

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

        phase.set_state_options('v',
                                fix_initial=True,
                                lower=10.0,
                                ref=1.0E2,
                                defect_ref=0.1,
                                units='m/s')

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

        phase.set_state_options('m',
                                fix_initial=True,
                                lower=10.0,
                                upper=1.0E5,
                                ref=1.0E3,
                                defect_ref=0.1)

        rate_continuity = True

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

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

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

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

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

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

        p.setup(check=True)

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

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

        # Solve for the optimal trajectory
        p.run_driver()

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

        exp_out = phase.simulate(times=50)

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

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

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

        plt.show()
Exemplo n.º 4
0
phase0 = Phase(ode_class=ShuttleODE, transcription=Radau(num_segments=20, order=3))
traj.add_phase(name="phase0", phase=phase0)

phase0.set_time_options(fix_initial=True, units="s", duration_ref=200)#, duration_ref=2000, duration_bounds=(50, 3000)

phase0.set_state_options("h", fix_initial=True, fix_final=True, units="ft", rate_source="hdot", targets=["h"], lower=0)#, ref=260000, defect_ref=260000, ref0=80000
phase0.set_state_options("gamma", fix_initial=True, fix_final=True, units="rad", rate_source="gammadot", targets=["gamma"], lower=-89.*np.pi/180, upper=89.*np.pi/180)
phase0.set_state_options("phi", fix_initial=True, fix_final=False, units="rad", rate_source="phidot", lower=0, upper=89.*np.pi/180)
phase0.set_state_options("psi", fix_initial=True, fix_final=False, units="rad", rate_source="psidot", targets=["psi"], lower=0, upper=90.*np.pi/180)
phase0.set_state_options("theta", fix_initial=True, fix_final=False, units="rad", rate_source="thetadot", targets=["theta"], lower=-89.*np.pi/180, upper=89.*np.pi/180)
phase0.set_state_options("v", fix_initial=True, fix_final=True, units="ft/s", rate_source="vdot", targets=["v"], lower=0)#, ref=25600, defect_ref=25600, ref0=2500

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

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

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

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

prob.setup(check=True)

prob.set_val("traj.phase0.states:h", phase0.interpolate(ys=[260000, 80000], nodes="state_input"), units="ft")
prob.set_val("traj.phase0.states:gamma", phase0.interpolate(ys=[-1*np.pi/180, -5*np.pi/180], nodes="state_input"), units="rad")
prob.set_val("traj.phase0.states:phi", phase0.interpolate(ys=[0, 75*np.pi/180], nodes="state_input"), units="rad")
prob.set_val("traj.phase0.states:psi", phase0.interpolate(ys=[90*np.pi/180, 10*np.pi/180], nodes="state_input"), units="rad")
prob.set_val("traj.phase0.states:theta", phase0.interpolate(ys=[0, 25*np.pi/180], nodes="state_input"), units="rad")
prob.set_val("traj.phase0.states:v", phase0.interpolate(ys=[25600, 2500], nodes="state_input"), units="ft/s")
Exemplo n.º 5
0
def ex_aircraft_steady_flight(optimizer='SLSQP',
                              transcription='gauss-lobatto'):
    p = Problem(model=Group())
    p.driver = pyOptSparseDriver()
    p.driver.options['optimizer'] = optimizer
    p.driver.options['dynamic_simul_derivs'] = True
    if optimizer == 'SNOPT':
        p.driver.opt_settings['Major iterations limit'] = 1000
        p.driver.opt_settings['Major feasibility tolerance'] = 1.0E-6
        p.driver.opt_settings['Major optimality tolerance'] = 1.0E-6
        p.driver.opt_settings["Linesearch tolerance"] = 0.10
        p.driver.opt_settings['iSumm'] = 6

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

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

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

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

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

    phase.set_state_options('range',
                            units='NM',
                            fix_initial=True,
                            fix_final=False,
                            scaler=0.001,
                            defect_scaler=1.0E-2)
    phase.set_state_options('mass_fuel',
                            units='lbm',
                            fix_initial=True,
                            fix_final=True,
                            upper=1.5E5,
                            lower=0.0,
                            scaler=1.0E-5,
                            defect_scaler=1.0E-1)

    phase.add_control('alt',
                      units='kft',
                      opt=True,
                      lower=0.0,
                      upper=50.0,
                      rate_param='climb_rate',
                      rate_continuity=True,
                      rate_continuity_scaler=1.0,
                      rate2_continuity=True,
                      rate2_continuity_scaler=1.0,
                      ref=1.0,
                      fix_initial=True,
                      fix_final=True)

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

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

    phase.add_path_constraint('propulsion.tau', lower=0.01, upper=1.0)
    phase.add_path_constraint('alt_rate',
                              units='ft/min',
                              lower=-3000,
                              upper=3000,
                              ref=3000)

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

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

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

    p.setup()

    p['phase0.t_initial'] = 0.0
    p['phase0.t_duration'] = 3600.0
    p['phase0.states:range'] = phase.interpolate(ys=(0, 1000.0),
                                                 nodes='state_input')
    p['phase0.states:mass_fuel'] = phase.interpolate(ys=(30000, 0),
                                                     nodes='state_input')

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

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

    p.run_driver()

    exp_out = phase.simulate(
        times=np.linspace(0, p['phase0.t_duration'], 500),
        record=True,
        record_file='test_ex_aircraft_steady_flight_rec.db')

    plt.plot(phase.get_values('time', nodes='all'),
             phase.get_values('alt', nodes='all'), 'ro')
    plt.plot(exp_out.get_values('time'), exp_out.get_values('alt'), 'b-')
    plt.suptitle('altitude vs time')
    plt.figure()
    plt.plot(phase.get_values('time', nodes='all'),
             phase.get_values('alt_rate', nodes='all', units='ft/min'), 'ro')
    plt.plot(exp_out.get_values('time'),
             exp_out.get_values('alt_rate', units='ft/min'), 'b-')
    plt.suptitle('altitude rate vs time')
    plt.figure()
    plt.plot(phase.get_values('time', nodes='all'),
             phase.get_values('mass_fuel', nodes='all'), 'ro')
    plt.plot(exp_out.get_values('time'), exp_out.get_values('mass_fuel'), 'b-')
    plt.suptitle('fuel mass vs time')
    plt.figure()
    plt.plot(phase.get_values('time', nodes='all'),
             phase.get_values('propulsion.dXdt:mass_fuel', nodes='all'), 'ro')
    plt.plot(exp_out.get_values('time'),
             exp_out.get_values('propulsion.dXdt:mass_fuel'), 'b-')
    plt.suptitle('fuel mass flow rate vs time')
    plt.figure()
    plt.plot(phase.get_values('time', nodes='all'),
             phase.get_values('mach', nodes='all'), 'ro')
    plt.plot(exp_out.get_values('time'), exp_out.get_values('mach'), 'b-')
    plt.suptitle('mach vs time')
    plt.figure()
    plt.plot(phase.get_values('time', nodes='all'),
             phase.get_values('mach_rate', nodes='all'), 'ro')
    plt.plot(exp_out.get_values('time'), exp_out.get_values('mach_rate'), 'b-')
    plt.suptitle('mach rate vs time')

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    plt.show()

    return p
def setup_energy_opt(num_seg, order, q_tank, q_hx1, q_hx2, opt_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.
    q_tank : float
        The amount of inputted heat to the fuel tank. Positive is heat inputted
        to the fuel tank.
    q_hx1 : float
        A measure of the amount of heat added to the fuel at the first heat exchanger.
        This mimics the fuel handling the heat generated from a thermal load,
        such as avionicsc or air conditioners.
    q_hx2 : float
        A measure of the amount of heat added to the fuel at the second heat exchanger.
        This may be a negative number, which means that heat is being taken out
        of the fuel in some way.
    opt_burn : boolean
        If true, we allow the optimizer to control the amount of fuel burned
        in the system. This mimics the cost of the fuel needed in the plane
        to provide thrust.
    """

    # 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=SimpleHeatODE,
                  ode_init_kwargs={
                      'q_tank': q_tank,
                      'q_hx1': q_hx1,
                      'q_hx2': q_hx2
                  },
                  num_segments=num_seg,
                  transcription_order=order)

    # 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=True)
    phase.set_state_options('T', fix_initial=True, defect_scaler=.01)
    phase.set_state_options('energy', fix_initial=True)

    # Minimize the energy used to pump the fuel
    phase.set_objective('energy', loc='final')

    # Allow the optimizer to vary the fuel flow
    phase.add_control('m_flow',
                      opt=True,
                      lower=0.,
                      upper=5.,
                      rate_continuity=True)

    # Optimize the burned fuel amount, if selected
    if opt_burn:
        phase.add_control('m_burn',
                          opt=opt_burn,
                          lower=.2,
                          upper=5.,
                          dynamic=False)
    else:
        phase.add_control('m_burn', opt=opt_burn)

    # 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.
    phase.add_path_constraint('T', upper=1.)
    phase.add_path_constraint('m_flow_rate', upper=0.)
    phase.add_path_constraint('m_flow', upper=1.)
    phase.add_path_constraint('fuel_burner.m_recirculated', lower=0.)

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

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

    return p
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=1e3, upper=1.0E6,
                        scaler=1.0E-3, defect_scaler=1.0E-3)

phase.add_control('alpha', units='rad', lower=-8. * np.pi/180., upper=8. * np.pi/180., scaler=1, rate_continuity=True)

phase.add_control('throttle', val=1.0, lower=0., upper=1., opt=True, rate_continuity=True)

phase.add_boundary_constraint('h', loc='final', equals=100., scaler=1.0E-3, units='m')
phase.add_boundary_constraint('r', loc='final', equals=1500., units='km')
# phase.add_boundary_constraint('gam', loc='final', equals=0.0, units='rad')

phase.add_path_constraint(name='aero.mach', lower=0.01, upper=.9)
# phase.add_path_constraint(name='prop.m_dot', upper=0.)
# phase.add_path_constraint(name='flight_dynamics.r_dot', lower=0.)
# phase.add_path_constraint(name='m', lower=1e4)
phase.add_path_constraint(name='h', lower=0.)

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

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

# p.driver.add_recorder(SqliteRecorder('out.db'))
p.setup(mode='fwd', check=True)
# from openmdao.api import view_model
Exemplo n.º 8
0
def escort_problem(optimizer='SLSQP',
                   num_seg=3,
                   transcription_order=5,
                   transcription='gauss-lobatto',
                   meeting_altitude=14000.,
                   climb_time=350.,
                   starting_mass=19030.468):

    p = Problem(model=Group())

    p.driver = pyOptSparseDriver()
    p.driver.options['optimizer'] = optimizer
    if optimizer == 'SNOPT':
        p.driver.opt_settings['Major iterations limit'] = 1000
        p.driver.opt_settings['Iterations limit'] = 100000000
        p.driver.opt_settings['iSumm'] = 6
        p.driver.opt_settings['Major feasibility tolerance'] = 1.0E-6
        p.driver.opt_settings['Major optimality tolerance'] = 1.0E-5
        p.driver.opt_settings['Verify level'] = -1
        p.driver.opt_settings['Function precision'] = 1.0E-6
        p.driver.opt_settings['Linesearch tolerance'] = 0.10
        p.driver.opt_settings['Major step limit'] = 0.5

    phase_class = _phase_map[transcription]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    return p
def thermal_mission_problem(num_seg=5, transcription_order=3, meeting_altitude=20000., Q_env=0., Q_sink=0., Q_out=0., m_recirculated=0., opt_m_recirculated=False, opt_m_burn=False, opt_throttle=True, engine_heat_coeff=0., pump_heat_coeff=0., T=None, T_o=None, opt_m=False, m_initial=20.e3, transcription='gauss-lobatto'):

    p = Problem(model=Group())

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

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

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

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

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

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

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

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

    phase.set_state_options('m', fix_initial=not opt_m, lower=15.e3, upper=80e3,
                            scaler=1.0E-3, defect_scaler=1.0E-3, units='kg')

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

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

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

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

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

    phase.add_path_constraint(name='h', lower=100.0, upper=20000, ref=20000)
    phase.add_path_constraint(name='aero.mach', lower=0.1, upper=1.8)
    # phase.add_path_constraint(name='time', upper=110.)

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

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

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

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

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

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

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

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

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

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

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

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

    return p
def min_time_climb_problem(num_seg=3,
                           transcription_order=5,
                           transcription='gauss-lobatto',
                           top_level_densejacobian=True):

    p = Problem(model=Group())

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        p.model.linear_solver = DirectSolver()

        p.setup()

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

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

        p.run_driver()

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

        assert_rel_error(self, range, tas * time, tolerance=1.0E-4)
Exemplo n.º 12
0
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-10
    p.driver.opt_settings['Major optimality tolerance'] = 1.0E-10
    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', units='kg', lower=1e2, upper=1e5, fix_initial=True)
    phase.set_state_options('T', units='K', 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', ref=10e2)
    # 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', lower=0.)
        phase.add_path_constraint('T', upper=333.)
        phase.add_path_constraint('T_o', lower=0., units='K')
        phase.add_path_constraint('T_o', upper=333., units='K')
        # phase.add_path_constraint('m_flow_rate', upper=0.)
        phase.add_path_constraint('m_recirculated', lower=0., units='kg/s')
        phase.add_path_constraint('m_flow', lower=0., upper=50.)

    # 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'] = 6000
    p['phase.states:T'] = 300.
    p['phase.states:energy'] = 0.
    # p['phase.controls:m_burn'][:10] = np.atleast_2d(np.linspace(2., .5, num_seg*order)[:10]).T**2
    # p['phase.controls:m_burn'][10:] = 2.2
    p['phase.t_initial'] = 0.
    p['phase.t_duration'] = 9000

    p.set_solver_print(level=-1)

    return p
    def test_brachistochrone_vector_ode_path_constraints_rk_partial_indices(
            self):

        p = Problem(model=Group())

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

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

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

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

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

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

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

        phase.add_boundary_constraint('pos', loc='final', equals=[10, 5])

        phase.add_path_constraint('pos_dot',
                                  shape=(2, ),
                                  units='m/s',
                                  indices=[1],
                                  lower=-4,
                                  upper=4)

        phase.add_timeseries_output('pos_dot', shape=(2, ), units='m/s')

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

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

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

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

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

        p.run_driver()

        assert_rel_error(self,
                         np.min(p.get_val('phase0.timeseries.pos_dot')[:, -1]),
                         -4,
                         tolerance=1.0E-2)

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

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

            x_imp = p.get_val('phase0.timeseries.states:pos')[:, 0]
            y_imp = p.get_val('phase0.timeseries.states:pos')[:, 1]

            x_exp = exp_out.get_val('phase0.timeseries.states:pos')[:, 0]
            y_exp = exp_out.get_val('phase0.timeseries.states:pos')[:, 1]

            ax.plot(x_imp, y_imp, 'ro', label='implicit')
            ax.plot(x_exp, y_exp, 'b-', label='explicit')

            ax.set_xlabel('x (m)')
            ax.set_ylabel('y (m)')
            ax.grid(True)
            ax.legend(loc='upper right')

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

            t_imp = p.get_val('phase0.timeseries.time')
            t_exp = exp_out.get_val('phase0.timeseries.time')

            xdot_imp = p.get_val('phase0.timeseries.pos_dot')[:, 0]
            ydot_imp = p.get_val('phase0.timeseries.pos_dot')[:, 1]

            xdot_exp = exp_out.get_val('phase0.timeseries.pos_dot')[:, 0]
            ydot_exp = exp_out.get_val('phase0.timeseries.pos_dot')[:, 1]

            ax.plot(t_imp, xdot_imp, 'bo', label='implicit')
            ax.plot(t_exp, xdot_exp, 'b-', label='explicit')

            ax.plot(t_imp, ydot_imp, 'ro', label='implicit')
            ax.plot(t_exp, ydot_exp, 'r-', label='explicit')

            ax.set_xlabel('t (s)')
            ax.set_ylabel('v (m/s)')
            ax.grid(True)
            ax.legend(loc='upper right')

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

            x_imp = p.get_val('phase0.timeseries.time')
            y_imp = p.get_val('phase0.timeseries.control_rates:theta_rate2')

            x_exp = exp_out.get_val('phase0.timeseries.time')
            y_exp = exp_out.get_val(
                'phase0.timeseries.control_rates:theta_rate2')

            ax.plot(x_imp, y_imp, 'ro', label='implicit')
            ax.plot(x_exp, y_exp, 'b-', label='explicit')

            ax.set_xlabel('time (s)')
            ax.set_ylabel('theta rate2 (rad/s**2)')
            ax.grid(True)
            ax.legend(loc='lower right')

            plt.show()

        return p
Exemplo n.º 14
0
                      upper=10,
                      lower=-10.0,
                      scaler=200.0,
                      adder=-10)
    phase.add_control('vy%d' % i,
                      rate_continuity=False,
                      units='m/s',
                      opt=True,
                      upper=10,
                      lower=-10.0,
                      scaler=200.0,
                      adder=-10)
    #phase.add_control('chi%d' % i, units='deg', opt=True, upper=180, lower=-180)
    phase.add_path_constraint(name='schedule%d.err_d' % i,
                              constraint_name='schedule_err%d' % i,
                              scaler=100.0,
                              upper=10.0,
                              units='m')
    phase.add_path_constraint(name='keepout%d.dist' % i,
                              constraint_name='keepout%d' % i,
                              scaler=0.1,
                              lower=keepout_radius,
                              units='m')
for i, j in combinations([i for i in range(n_traj)], 2):
    phase.add_path_constraint(name='distance_%d_%d.dist' % (i, j),
                              constraint_name='distance_%d_%d' % (i, j),
                              scaler=0.1,
                              lower=personal_zone,
                              units='m')

# Minimize time to target
Exemplo n.º 15
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
    def test_steady_aircraft_for_docs(self):
        import numpy as np
        import matplotlib.pyplot as plt

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

        from dymos import Phase

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

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

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

        phase = Phase('gauss-lobatto',
                      ode_class=AircraftODE,
                      num_segments=num_seg,
                      segment_ends=seg_ends,
                      transcription_order=5,
                      compressed=False)

        # Pass design parameters in externally from an external source
        assumptions = p.model.add_subsystem('assumptions', IndepVarComp())
        assumptions.add_output('mach', val=0.8, units=None)
        assumptions.add_output('S', val=427.8, units='m**2')
        assumptions.add_output('mass_empty', val=1.0, units='kg')
        assumptions.add_output('mass_payload', val=1.0, units='kg')

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

        phase.set_time_options(fix_initial=True,
                               duration_bounds=(300, 10000),
                               duration_ref=3600)

        phase.set_state_options('range', units='NM', fix_initial=True, fix_final=False,
                                scaler=0.001,
                                defect_scaler=1.0E-2)

        phase.set_state_options('mass_fuel', units='lbm', fix_initial=True, fix_final=True,
                                upper=1.5E5, lower=0.0, scaler=1.0E-5, defect_scaler=1.0E-1)

        phase.add_control('alt', units='kft', opt=True, lower=0.0, upper=50.0,
                          rate_param='climb_rate',
                          rate_continuity=True, rate_continuity_scaler=1.0,
                          rate2_continuity=True, rate2_continuity_scaler=1.0, ref=1.0,
                          fix_initial=True, fix_final=True)

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

        phase.add_path_constraint('propulsion.tau', lower=0.01, upper=1.0)
        phase.add_path_constraint('alt_rate', units='ft/min', lower=-3000, upper=3000, ref=3000)

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

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

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

        p.setup()

        p['phase0.t_initial'] = 0.0
        p['phase0.t_duration'] = 3600.0
        p['phase0.states:range'] = phase.interpolate(ys=(0, 1000.0), nodes='state_input')
        p['phase0.states:mass_fuel'] = phase.interpolate(ys=(30000, 0), nodes='state_input')

        p['phase0.controls:alt'][:] = 10.0

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

        p.run_driver()

        exp_out = phase.simulate(times=np.linspace(0, p['phase0.t_duration'], 500), record=True,
                                 record_file='test_doc_aircraft_steady_flight_rec.db')

        assert_rel_error(self, phase.get_values('range', units='NM')[-1], 726.7, tolerance=1.0E-2)

        plt.figure()

        plt.plot(phase.get_values('time', nodes='all'),
                 phase.get_values('alt', nodes='all', units='ft'),
                 'ro')

        plt.plot(exp_out.get_values('time'),
                 exp_out.get_values('alt', units='ft'),
                 'b-')

        plt.suptitle('Altitude vs Time')
        plt.xlabel('Time (s)')
        plt.ylabel('Altitude (ft)')

        plt.figure()
        plt.plot(phase.get_values('time', nodes='all'),
                 phase.get_values('alt_rate', nodes='all', units='ft/min'),
                 'ro')
        plt.plot(exp_out.get_values('time'),
                 exp_out.get_values('alt_rate', units='ft/min'),
                 'b-')

        plt.suptitle('Climb Rate vs Time')
        plt.xlabel('Time (s)')
        plt.ylabel('Climb Rate (ft/min)')

        plt.figure()
        plt.plot(phase.get_values('time', nodes='all'),
                 phase.get_values('mass_fuel', nodes='all', units='lbm'),
                 'ro')

        plt.plot(exp_out.get_values('time'),
                 exp_out.get_values('mass_fuel', units='lbm'),
                 'b-')

        plt.suptitle('Fuel Mass vs Time')
        plt.xlabel('Time (s)')
        plt.ylabel('Fuel Mass (lbm)')

        plt.show()