예제 #1
0
    def test_solve_linear_maxiter(self):
        # Test that using options that should not exist in class cause an error
        solver = DirectSolver()

        msg = "\"Option '%s' cannot be set because it has not been declared.\""

        for option in ['atol', 'rtol', 'maxiter', 'err_on_maxiter']:
            with self.assertRaises(KeyError) as context:
                solver.options[option] = 1

            self.assertEqual(str(context.exception), msg % option)
예제 #2
0
    def test_no_promotion_errors(self):
        """
        Tests for error-handling for invalid variable names and keys.
        """
        g = Group(assembled_jac_type='dense')
        g.linear_solver = DirectSolver(assemble_jac=True)
        c = g.add_subsystem('c', ExecComp('y=2*x'))

        p = Problem()
        model = p.model
        model.add_subsystem('g', g)
        p.setup(check=False)

        # -------------------------------------------------------------------

        msg = 'Variable name "{}" not found.'

        # inputs
        with assertRaisesRegex(self, KeyError, msg.format('x')):
            p['x'] = 5.0
            p.final_setup()
        p._initial_condition_cache = {}

        with assertRaisesRegex(self, KeyError, msg.format('x')):
            x = p['x']

        # outputs
        with assertRaisesRegex(self, KeyError, msg.format('y')):
            p['y'] = 5.0
            p.final_setup()
        p._initial_condition_cache = {}

        with assertRaisesRegex(self, KeyError, msg.format('y')):
            y = p['y']

        msg = 'Variable name "{}" not found.'
        inputs, outputs, residuals = g.get_nonlinear_vectors()

        # inputs
        with assertRaisesRegex(self, KeyError, msg.format('x')):
            inputs['x'] = 5.0
        with assertRaisesRegex(self, KeyError, msg.format('x')):
            x = inputs['x']
        with assertRaisesRegex(self, KeyError, msg.format('g.c.x')):
            inputs['g.c.x'] = 5.0
        with assertRaisesRegex(self, KeyError, msg.format('g.c.x')):
            gcx = inputs['g.c.x']

        # outputs
        with assertRaisesRegex(self, KeyError, msg.format('y')):
            outputs['y'] = 5.0
        with assertRaisesRegex(self, KeyError, msg.format('y')):
            y = outputs['y']
        with assertRaisesRegex(self, KeyError, msg.format('g.c.y')):
            outputs['g.c.y'] = 5.0
        with assertRaisesRegex(self, KeyError, msg.format('g.c.y')):
            out = outputs['g.c.y']

        msg = 'Variable name pair \("{}", "{}"\) not found.'
        jac = g.linear_solver._assembled_jac

        # d(output)/d(input)
        with assertRaisesRegex(self, KeyError, msg.format('y', 'x')):
            jac['y', 'x'] = 5.0
        with assertRaisesRegex(self, KeyError, msg.format('y', 'x')):
            dydx = jac['y', 'x']
        # allow absolute keys now
        #with assertRaisesRegex(self, KeyError, msg.format('g.c.y', 'g.c.x')):
        #jac['g.c.y', 'g.c.x'] = 5.0
        #with assertRaisesRegex(self, KeyError, msg.format('g.c.y', 'g.c.x')):
        #deriv = jac['g.c.y', 'g.c.x']

        # d(output)/d(output)
        with assertRaisesRegex(self, KeyError, msg.format('y', 'y')):
            jac['y', 'y'] = 5.0
        with assertRaisesRegex(self, KeyError, msg.format('y', 'y')):
            dydy = jac['y', 'y']
예제 #3
0
    def __init__(self, num_segments=15, transcription_order=3,
                 transcription_type='LGR', solve_segments=False,
                 ivc_pert=None, use_polynomial_control=True,
                 read_coloring_file=True):

        self.num_segments = num_segments
        self.transcription_order = transcription_order
        self.transcription_type = transcription_type
        self.solve_segments = solve_segments
        self.use_polynomial_control = use_polynomial_control

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

        self.p.driver = pyOptSparseDriver()
        self.p.driver.options['optimizer'] = 'SNOPT'
        self.p.driver.options['dynamic_simul_derivs'] = False

        self.p.driver.opt_settings['Major iterations limit'] = 1000
        # self.p.driver.opt_settings['iSumm'] = 6
        self.p.driver.opt_settings['Major feasibility tolerance'] = 1.0E-9
        self.p.driver.opt_settings['Major optimality tolerance'] = 1.0E-9
        self.p.driver.opt_settings['Function precision'] = 1.0E-12
        self.p.driver.opt_settings['Linesearch tolerance'] = 0.1
        self.p.driver.opt_settings['Major step limit'] = 0.5
        self.p.driver.options['print_results'] = False
        if read_coloring_file:
            fname = os.environ['HOME'] + '/UserApps/pyStatReduce/pystatreduce/examples/supersonic_interceptor/coloring_files/total_coloring.pkl'
            self.p.driver.use_fixed_coloring(fname)
            # self.p.driver.use_fixed_coloring('/users/pandak/UserApps/pyStatReduce/pystatreduce/examples/supersonic_interceptor/coloring_files/total_coloring.pkl')

        # Add an indep_var_comp that will talk to external calls from pyStatReduce
        if ivc_pert is None:
            seed_perturbation = np.zeros(self.transcription_order*self.num_segments)
        else:
            seed_perturbation = ivc_pert
        random_perturbations = self.p.model.add_subsystem('random_perturbations', IndepVarComp())
        random_perturbations.add_output('rho_pert', val=seed_perturbation, units='kg/m**3',
                                        desc="perturbations introduced into the density data")

        lgl =  dm.GaussLobatto(num_segments=self.num_segments, order=self.transcription_order, solve_segments=self.solve_segments)
        lgr = dm.Radau(num_segments=self.num_segments,
                       order=self.transcription_order,
                       solve_segments=self.solve_segments)
        rk4 = dm.RungeKutta(num_segments=100)

        traj = dm.Trajectory()
        if self.transcription_type is 'RK4':
            phase = dm.Phase(ode_class=MinTimeClimbODE, transcription=rk4)
        elif self.transcription_type is 'LGL':
            phase = dm.Phase(ode_class=MinTimeClimbODE, transcription=lgl)
        elif self.transcription_type is 'LGR':
            phase = dm.Phase(ode_class=MinTimeClimbODE, transcription=lgr)
        else:
            raise NotImplementedError

        traj.add_phase('phase0', phase)
        self.p.model.add_subsystem('traj', traj)

        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=1.0E3, units='m',solve_segments=self.solve_segments)

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

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

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

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

        if self.use_polynomial_control:
            phase.add_polynomial_control('alpha', units='deg', lower=-8., upper=8., order=5)
        else:
            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)

        # # Add the random parameters to dymos
        # phase.add_input_parameter('rho_pert', shape=(60,), dynamic=False, units='kg/m**3')

        # Add the density perturbation as a control
        phase.add_control('rho_pert', units='kg/m**3', opt=False)

        self.p.model.connect('random_perturbations.rho_pert', 'traj.phase0.controls:rho_pert')

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

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

        self.p.model.linear_solver = DirectSolver()

        self.p.setup()

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

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

        if self.transcription_type is 'RK4' or self.transcription_type is 'LGR':

            if self.use_polynomial_control:
                self.p['traj.phase0.polynomial_controls:alpha'] = np.array([[4.86918595],
                                                                            [1.30322324],
                                                                            [1.41897019],
                                                                            [1.10227365],
                                                                            [3.58780732],
                                                                            [5.36233472]])
                self.p['traj.phase0.t_duration'] = 346.13171325
            else:
                # self.p['traj.phase0.controls:alpha'] = phase.interpolate(ys=[0.0, 0.0], nodes='control_input')
                self.p['traj.phase0.controls:alpha'] = np.array([[ 5.28001465],
                                                               [ 3.13975533],
                                                               [ 1.98865951],
                                                               [ 2.05967779],
                                                               [ 2.22378148],
                                                               [ 1.66812216],
                                                               [ 1.30331958],
                                                               [ 0.69713879],
                                                               [ 0.95481437],
                                                               [ 1.30067776],
                                                               [ 1.89992733],
                                                               [ 1.61608848],
                                                               [ 1.25793436],
                                                               [ 0.61321823],
                                                               [ 0.78469243],
                                                               [ 1.09529382],
                                                               [ 1.75985378],
                                                               [ 2.06015107],
                                                               [ 2.00622047],
                                                               [ 1.80482513],
                                                               [ 1.54044227],
                                                               [ 1.46002774],
                                                               [ 1.31279412],
                                                               [ 1.22493615],
                                                               [ 1.22498241],
                                                               [ 1.2379623 ],
                                                               [ 1.24779616],
                                                               [ 1.24895759],
                                                               [ 1.24532979],
                                                               [ 1.22320548],
                                                               [ 1.21206765],
                                                               [ 1.18520735],
                                                               [ 1.15116935],
                                                               [ 1.14112692],
                                                               [ 1.22312977],
                                                               [ 1.67973464],
                                                               [ 1.90722158],
                                                               [ 2.4858537 ],
                                                               [ 3.32375899],
                                                               [ 3.59849829],
                                                               [ 3.9384917 ],
                                                               [ 3.44095692],
                                                               [ 3.04996246],
                                                               [ 1.07581437],
                                                               [-4.76838553]])
        elif self.solve_segments is True:
            self.p['traj.phase0.t_duration'] = 346.13171325
예제 #4
0
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.opt_settings['Major step limit'] = .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=(50, 1e8),
                           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', 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, upper=500.,
                            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, 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=49.2386, units='m**2', opt=False)
    # phase.add_design_parameter('throttle', val=1.0, opt=False)
    phase.add_control('throttle', val=1.0, opt=True, lower=0., upper=1., rate_continuity=False)

    phase.add_boundary_constraint('h', loc='final', equals=100., 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_boundary_constraint('r', loc='final', equals=1e6, units='m')

    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='prop.m_dot', upper=0.)
    # phase.add_path_constraint(name='flight_dynamics.r_dot', lower=0.)

    # Minimize time at the end of the phase
    # phase.add_objective('time', loc='final', ref=100.0)
    phase.add_objective('m', loc='final', ref=-1000.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='state_input')
    p['phase.states:h'] = phase.interpolate(ys=[100.0, 1e4], nodes='state_input')
    p['phase.states:v'] = phase.interpolate(ys=[135.964, 283.159], nodes='state_input')
    p['phase.states:gam'] = phase.interpolate(ys=[0.0, 0.0], nodes='state_input')
    p['phase.states:m'] = phase.interpolate(ys=[30e3, 29e3], nodes='state_input')
    # p['phase.controls:alpha'] = phase.interpolate(ys=[0.50, 0.50], nodes='all')

    return p
예제 #5
0
    def test_circuit_voltage_source(self):
        from openmdao.api import ArmijoGoldsteinLS, Problem, IndepVarComp, BalanceComp, ExecComp
        from openmdao.api import NewtonSolver, DirectSolver, NonlinearRunOnce, LinearRunOnce

        from openmdao.test_suite.test_examples.test_circuit_analysis import Circuit

        p = Problem()
        model = p.model

        model.add_subsystem('ground', IndepVarComp('V', 0., units='V'))

        # replacing the fixed current source with a BalanceComp to represent a fixed Voltage source
        # model.add_subsystem('source', IndepVarComp('I', 0.1, units='A'))
        model.add_subsystem('batt', IndepVarComp('V', 1.5, units='V'))
        bal = model.add_subsystem('batt_balance', BalanceComp())
        bal.add_balance('I', units='A', eq_units='V')

        model.add_subsystem('circuit', Circuit())
        model.add_subsystem(
            'batt_deltaV',
            ExecComp('dV = V1 - V2',
                     V1={'units': 'V'},
                     V2={'units': 'V'},
                     dV={'units': 'V'}))

        # current into the circuit is now the output state from the batt_balance comp
        model.connect('batt_balance.I', 'circuit.I_in')
        model.connect('ground.V', ['circuit.Vg', 'batt_deltaV.V2'])
        model.connect('circuit.n1.V', 'batt_deltaV.V1')

        # set the lhs and rhs for the battery residual
        model.connect('batt.V', 'batt_balance.rhs:I')
        model.connect('batt_deltaV.dV', 'batt_balance.lhs:I')

        p.setup()

        ###################
        # Solver Setup
        ###################

        # change the circuit solver to RunOnce because we're
        # going to converge at the top level of the model with newton instead
        p.model.circuit.nonlinear_solver = NonlinearRunOnce()
        p.model.circuit.linear_solver = LinearRunOnce()

        # Put Newton at the top so it can also converge the new BalanceComp residual
        newton = p.model.nonlinear_solver = NewtonSolver()
        p.model.linear_solver = DirectSolver()
        newton.options['iprint'] = 2
        newton.options['maxiter'] = 20
        newton.options['solve_subsystems'] = True
        newton.linesearch = ArmijoGoldsteinLS()
        newton.linesearch.options['maxiter'] = 10
        newton.linesearch.options['iprint'] = 2

        # set initial guesses from the current source problem
        p['circuit.n1.V'] = 9.8
        p['circuit.n2.V'] = .7

        p.run_model()

        assert_rel_error(self, p['circuit.n1.V'], 1.5, 1e-5)
        assert_rel_error(self, p['circuit.n2.V'], 0.676232, 1e-5)
        assert_rel_error(self, p['circuit.R1.I'], 0.015, 1e-5)
        assert_rel_error(self, p['circuit.R2.I'], 8.23767999e-05, 1e-5)
        assert_rel_error(self, p['circuit.D1.I'], 8.23767999e-05, 1e-5)
예제 #6
0
    def test_no_promotion_errors(self):
        """
        Tests for error-handling for invalid variable names and keys.
        """
        g = Group(assembled_jac_type='dense')
        g.linear_solver = DirectSolver(assemble_jac=True)
        g.add_subsystem('c', ExecComp('y=2*x'))

        p = Problem()
        model = p.model
        model.add_subsystem('g', g)
        p.setup()

        # -------------------------------------------------------------------

        msg = '\'Group (<model>): Variable "{}" not found.\''

        # inputs
        with self.assertRaises(KeyError) as ctx:
            p['x'] = 5.0
            p.final_setup()
        self.assertEqual(str(ctx.exception), msg.format('x'))
        p._initial_condition_cache = {}

        with self.assertRaises(KeyError) as ctx:
            p['x']
        self.assertEqual(str(ctx.exception), msg.format('x'))

        # outputs
        with self.assertRaises(KeyError) as ctx:
            p['y'] = 5.0
            p.final_setup()
        self.assertEqual(str(ctx.exception), msg.format('y'))
        p._initial_condition_cache = {}

        with self.assertRaises(KeyError) as ctx:
            p['y']
        self.assertEqual(str(ctx.exception), msg.format('y'))

        msg = '\'Variable name "{}" not found.\''
        inputs, outputs, residuals = g.get_nonlinear_vectors()

        # inputs
        with self.assertRaisesRegex(KeyError, msg.format('x')):
            inputs['x'] = 5.0
        with self.assertRaisesRegex(KeyError, msg.format('x')):
            inputs['x']
        with self.assertRaisesRegex(KeyError, msg.format('g.c.x')):
            inputs['g.c.x'] = 5.0
        with self.assertRaisesRegex(KeyError, msg.format('g.c.x')):
            inputs['g.c.x']

        # outputs
        with self.assertRaisesRegex(KeyError, msg.format('y')):
            outputs['y'] = 5.0
        with self.assertRaisesRegex(KeyError, msg.format('y')):
            outputs['y']
        with self.assertRaisesRegex(KeyError, msg.format('g.c.y')):
            outputs['g.c.y'] = 5.0
        with self.assertRaisesRegex(KeyError, msg.format('g.c.y')):
            outputs['g.c.y']

        msg = r'Variable name pair \("{}", "{}"\) not found.'
        jac = g.linear_solver._assembled_jac

        # d(output)/d(input)
        with self.assertRaisesRegex(KeyError, msg.format('y', 'x')):
            jac['y', 'x'] = 5.0
        with self.assertRaisesRegex(KeyError, msg.format('y', 'x')):
            jac['y', 'x']
        # allow absolute keys now
        # with self.assertRaisesRegex(KeyError, msg.format('g.c.y', 'g.c.x')):
        #     jac['g.c.y', 'g.c.x'] = 5.0
        # with self.assertRaisesRegex(KeyError, msg.format('g.c.y', 'g.c.x')):
        #     deriv = jac['g.c.y', 'g.c.x']

        # d(output)/d(output)
        with self.assertRaisesRegex(KeyError, msg.format('y', 'y')):
            jac['y', 'y'] = 5.0
        with self.assertRaisesRegex(KeyError, msg.format('y', 'y')):
            jac['y', 'y']
예제 #7
0
    def test_with_promotion_errors(self):
        """
        Tests for error-handling for invalid variable names and keys.
        """
        c1 = IndepVarComp('x')
        c2 = ExecComp('y=2*x')
        c3 = ExecComp('z=3*x')

        g = Group(assembled_jac_type='dense')
        g.add_subsystem('c1', c1, promotes=['*'])
        g.add_subsystem('c2', c2, promotes=['*'])
        g.add_subsystem('c3', c3, promotes=['*'])
        g.linear_solver = DirectSolver(assemble_jac=True)

        model = Group()
        model.add_subsystem('g', g, promotes=['*'])

        p = Problem(model)
        p.setup()

        # Conclude setup but don't run model.
        p.final_setup()

        # -------------------------------------------------------------------

        msg1 = 'Variable name "{}" not found.'
        msg2 = "The promoted name x is invalid because it refers to multiple inputs: " \
               "[g.c2.x ,g.c3.x]. Access the value from the connected output variable x instead."

        inputs, outputs, residuals = g.get_nonlinear_vectors()

        # inputs
        with self.assertRaises(Exception) as context:
            inputs['x'] = 5.0
        self.assertEqual(str(context.exception), msg2)
        with self.assertRaises(Exception) as context:
            self.assertEqual(inputs['x'], 5.0)
        self.assertEqual(str(context.exception), msg2)

        with self.assertRaisesRegex(KeyError, msg1.format('g.c2.x')):
            inputs['g.c2.x'] = 5.0
        with self.assertRaisesRegex(KeyError, msg1.format('g.c2.x')):
            self.assertEqual(inputs['g.c2.x'], 5.0)

        # outputs
        with self.assertRaisesRegex(KeyError, msg1.format('g.c2.y')):
            outputs['g.c2.y'] = 5.0
        with self.assertRaisesRegex(KeyError, msg1.format('g.c2.y')):
            self.assertEqual(outputs['g.c2.y'], 5.0)

        msg1 = r'Variable name pair \("{}", "{}"\) not found.'

        jac = g.linear_solver._assembled_jac

        # d(outputs)/d(inputs)
        with self.assertRaises(Exception) as context:
            jac['y', 'x'] = 5.0
        self.assertEqual(str(context.exception), msg2)

        with self.assertRaises(Exception) as context:
            self.assertEqual(jac['y', 'x'], 5.0)
        self.assertEqual(str(context.exception), msg2)
예제 #8
0
    ivc.add_output('T_0', 0.015, units='N',desc='Constant Thrust Value')

    #Building Model
    p = Problem()
    model = p.modelomponent is the basic building block of a model. You will always define components as a subclass of either ExplicitComponent or ImplicitComponent. Since our simple paraboloid function is explicit, we’ll use the ExplicitComponent. You see two methods defined:


    model.add_subsystem('init_cond', ivc, promotes=['*'])
    model.add_subsystem('comp', FullComp(), promotes=['*'])

    #Optimization Set-Up
    p.driver = ScipyOptimizeDriver()
    p.driver.options['optimizer'] = 'SLSQP'
    # p.driver.options['optimizer'] = 'COBYLA'
    p.driver.options
    model.linear_solver = DirectSolver(iprint=2)

    # model.add_design_var('eta_sa', lower = 0.01, upper=1)
    model.add_design_var('M_ps', lower=0.01, upper=100)
    model.add_constraint('con1',)
    model.add_objective('t_tot')

    #Case Recorder Setting
    recorder = SqliteRecorder('test.sql')
    p.driver.add_recorder(recorder)
    p.add_recorder(recorder)

    #Set-up and Run
    p.setup()
    p.set_solver_print(2)
    p.run_driver()
예제 #9
0
    def test_csc_masking(self):
        class CCBladeResidualComp(ImplicitComponent):
            def initialize(self):
                self.options.declare('num_nodes', types=int)
                self.options.declare('num_radial', types=int)

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

                self.add_input('chord', shape=(1, num_radial))
                self.add_input('theta', shape=(1, num_radial))

                self.add_output('phi',
                                lower=-0.5 * np.pi,
                                upper=0.0,
                                shape=(num_nodes, num_radial))
                self.add_output('Tp', shape=(num_nodes, num_radial))

                of_names = ('phi', 'Tp')
                row_col = np.arange(num_radial)

                for name in of_names:
                    self.declare_partials(name,
                                          'chord',
                                          rows=row_col,
                                          cols=row_col)
                    self.declare_partials(name,
                                          'theta',
                                          rows=row_col,
                                          cols=row_col,
                                          val=0.0)
                    self.declare_partials(name,
                                          'phi',
                                          rows=row_col,
                                          cols=row_col)

                self.declare_partials('Tp',
                                      'Tp',
                                      rows=row_col,
                                      cols=row_col,
                                      val=1.)

            def linearize(self, inputs, outputs, partials):

                partials['phi', 'chord'] = np.array([1., 2, 3, 4])
                partials['phi', 'phi'] = np.array([5., 6, 7, 8])

                partials['Tp', 'chord'] = np.array([9., 10, 11, 12])
                partials['Tp', 'phi'] = np.array([13., 14, 15, 16])

        prob = Problem()
        model = prob.model

        comp = IndepVarComp()
        comp.add_output('chord', val=np.ones((4, )))
        model.add_subsystem('indep_var_comp', comp, promotes=['*'])

        comp = CCBladeResidualComp(num_nodes=1,
                                   num_radial=4,
                                   assembled_jac_type='csc')

        comp.linear_solver = DirectSolver(assemble_jac=True)
        model.add_subsystem('ccblade_comp',
                            comp,
                            promotes_inputs=['chord'],
                            promotes_outputs=['Tp'])

        prob.setup(mode='fwd')
        prob.run_model()
        totals = prob.compute_totals(of=['Tp'],
                                     wrt=['chord'],
                                     return_format='array')

        expected = np.array([[-6.4, 0., 0., 0.], [0., -5.33333333, 0., 0.],
                             [0., 0., -4.57142857, 0.], [0., 0., 0., -4.]])

        np.testing.assert_allclose(totals, expected)
예제 #10
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()
예제 #11
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
예제 #12
0
                                      promotes_inputs=['*'],
                                      promotes_outputs=['*'])

        self.connect('T_motor_initial',
                     'v0v1.propmodel.motorheatsink.T_initial')
        self.connect('T_res_initial', 'v0v1.propmodel.reservoir.T_initial')


if __name__ == "__main__":
    num_nodes = 11
    prob = Problem()
    prob.model = ElectricTBMAnalysisGroup()

    prob.model.nonlinear_solver = NewtonSolver(iprint=2)
    prob.model.options['assembled_jac_type'] = 'csc'
    prob.model.linear_solver = DirectSolver(assemble_jac=True)
    prob.model.nonlinear_solver.options['solve_subsystems'] = True
    prob.model.nonlinear_solver.options['maxiter'] = 20
    prob.model.nonlinear_solver.options['atol'] = 1e-8
    prob.model.nonlinear_solver.options['rtol'] = 1e-8
    prob.model.nonlinear_solver.linesearch = BoundsEnforceLS(
        bound_enforcement='scalar', print_bound_enforce=False)

    prob.model.add_design_var('mission_range',
                              lower=100,
                              upper=300,
                              scaler=1e-2)
    prob.model.add_constraint('descent.propmodel.batt1.SOC_final', lower=0.0)
    prob.model.add_objective('mission_range', scaler=-1.0)
    prob.driver = ScipyOptimizeDriver()
    prob.driver.options['dynamic_simul_derivs'] = True
예제 #13
0
    prob_ref['overhang']                       = 8.5
    prob_ref['drive.distance_hub2mb']          = 3.5
    prob_ref['significant_wave_height']        = 4.52
    prob_ref['significant_wave_period']        = 9.45
    prob_ref['monopile']                       = True
    prob_ref['foundation_height']              = -30.
    prob_ref['water_depth']                    = 30.
    prob_ref['suctionpile_depth']              = 45.
    prob_ref['wind_reference_height']          = 150.
    prob_ref['hub_height']                     = 150.
    prob_ref['tower_section_height']           = np.array([10., 10., 10., 10., 10., 12.5,  12.5,  12.5,  12.5,  12.5,  12.5,  12.5,  12.5,  12.5, 13.6679])
    prob_ref['tower_outer_diameter']           = np.array([10., 10., 10., 10., 10., 10., 9.8457, 9.47, 9.041, 8.5638, 8.1838, 8.0589, 7.9213, 7.8171, 7.3356, 6.5])
    prob_ref['tower_wall_thickness']           = np.array([0.1, 0.1, 0.1, 0.1, 0.1, 0.0431, 0.041, 0.0397, 0.0384, 0.037, 0.0348, 0.0313, 0.0279, 0.0248, 0.0299])

    prob_ref.model.nonlinear_solver = NonlinearRunOnce()
    prob_ref.model.linear_solver    = DirectSolver()
    print('Running at Initial Position:')
    prob_ref.run_driver()
    #prob_ref.model.list_inputs(units=True)
    #refBlade.write_ontology(fname_output, prob_ref['blade_out'], refBlade.wt_ref)
    
    print(prob_ref['hub_height'])
    print(prob_ref['rna_mass'])
    print('mIxx', prob_ref['tow.pre.mIxx'])
    print('mIyy', prob_ref['tow.pre.mIyy'])
    print('mIzz', prob_ref['tow.pre.mIzz'])
    print('mIxy', prob_ref['tow.pre.mIxy'])
    print('mIxz', prob_ref['tow.pre.mIxz'])
    print('mIyz', prob_ref['tow.pre.mIyz'])
    print('rna_F', prob_ref['tow.pre.rna_F'])
    print('rna_M', prob_ref['tow.pre.rna_M'])
예제 #14
0
    def test_record_solver_linear_direct_solver(self, m):
        self.setup_endpoints(m)
        recorder = WebRecorder(self._accepted_token, suppress_output=True)
        self.setup_sellar_model()

        self.prob.model.nonlinear_solver = NewtonSolver()
        # used for analytic derivatives
        self.prob.model.nonlinear_solver.linear_solver = DirectSolver()

        linear_solver = self.prob.model.nonlinear_solver.linear_solver
        linear_solver.recording_options['record_abs_error'] = True
        linear_solver.recording_options['record_rel_error'] = True
        linear_solver.recording_options['record_solver_residuals'] = True
        self.prob.model.nonlinear_solver.linear_solver.add_recorder(recorder)

        self.prob.setup(check=False)
        t0, t1 = run_driver(self.prob)

        expected_solver_output = [
            {
                'name': 'px.x',
                'values': [0.0]
            },
            {
                'name': 'pz.z',
                'values': [0.0, 0.0]
            },
            {
                'name': 'd1.y1',
                'values': [0.00045069]
            },
            {
                'name': 'd2.y2',
                'values': [-0.00225346]
            },
            {
                'name': 'obj_cmp.obj',
                'values': [0.00045646]
            },
            {
                'name': 'con_cmp1.con1',
                'values': [-0.00045069]
            },
            {
                'name': 'con_cmp2.con2',
                'values': [-0.00225346]
            },
        ]

        expected_solver_residuals = [
            {
                'name': 'px.x',
                'values': [0.0]
            },
            {
                'name': 'pz.z',
                'values': [-0., -0.]
            },
            {
                'name': 'd1.y1',
                'values': [0.0]
            },
            {
                'name': 'd2.y2',
                'values': [-0.00229801]
            },
            {
                'name': 'obj_cmp.obj',
                'values': [5.75455956e-06]
            },
            {
                'name': 'con_cmp1.con1',
                'values': [-0.]
            },
            {
                'name': 'con_cmp2.con2',
                'values': [-0.]
            },
        ]

        solver_iteration = json.loads(self.solver_iterations)

        self.assertAlmostEqual(0.0, solver_iteration['abs_err'])
        self.assertAlmostEqual(0.0, solver_iteration['rel_err'])

        for o in expected_solver_output:
            self.assert_array_close(o, solver_iteration['solver_output'])

        for r in expected_solver_residuals:
            self.assert_array_close(r, solver_iteration['solver_residuals'])
예제 #15
0
    def test_sellar_specify_linear_direct_solver(self):

        prob = Problem()
        model = prob.model

        model.add_subsystem('px', IndepVarComp('x', 1.0), promotes=['x'])
        model.add_subsystem('pz',
                            IndepVarComp('z', np.array([5.0, 2.0])),
                            promotes=['z'])

        proms = [
            'x', 'z', 'y1', 'state_eq.y2_actual', 'state_eq.y2_command',
            'd1.y2', 'd2.y2'
        ]
        sub = model.add_subsystem('sub', Group(), promotes=proms)

        subgrp = sub.add_subsystem(
            'state_eq_group',
            Group(),
            promotes=['state_eq.y2_actual', 'state_eq.y2_command'])
        subgrp.linear_solver = ScipyKrylov()
        subgrp.add_subsystem('state_eq', StateConnection())

        sub.add_subsystem('d1',
                          SellarDis1withDerivatives(),
                          promotes=['x', 'z', 'y1'])
        sub.add_subsystem('d2',
                          SellarDis2withDerivatives(),
                          promotes=['z', 'y1'])

        model.connect('state_eq.y2_command', 'd1.y2')
        model.connect('d2.y2', 'state_eq.y2_actual')

        model.add_subsystem('obj_cmp',
                            ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)',
                                     z=np.array([0.0, 0.0]),
                                     x=0.0,
                                     y1=0.0,
                                     y2=0.0),
                            promotes=['x', 'z', 'y1', 'obj'])
        model.connect('d2.y2', 'obj_cmp.y2')

        model.add_subsystem('con_cmp1',
                            ExecComp('con1 = 3.16 - y1'),
                            promotes=['con1', 'y1'])
        model.add_subsystem('con_cmp2',
                            ExecComp('con2 = y2 - 24.0'),
                            promotes=['con2'])
        model.connect('d2.y2', 'con_cmp2.y2')

        model.nonlinear_solver = NewtonSolver()

        # Use bad settings for this one so that problem doesn't converge.
        # That way, we test that we are really using Newton's Lin Solver
        # instead.
        sub.linear_solver = ScipyKrylov()
        sub.linear_solver.options['maxiter'] = 1

        # The good solver
        model.nonlinear_solver.linear_solver = DirectSolver()

        prob.set_solver_print(level=0)
        prob.setup(check=False)
        prob.run_model()

        assert_rel_error(self, prob['y1'], 25.58830273, .00001)
        assert_rel_error(self, prob['state_eq.y2_command'], 12.05848819,
                         .00001)

        # Make sure we aren't iterating like crazy
        self.assertLess(model.nonlinear_solver._iter_count, 8)
        self.assertEqual(model.linear_solver._iter_count, 0)
예제 #16
0
    def test_solve_linear_ksp_precon_left(self):
        """Solve implicit system with PETScKrylov using a preconditioner."""

        group = TestImplicitGroup(lnSolverClass=PETScKrylov)
        precon = group.linear_solver.precon = DirectSolver(assemble_jac=False)
        group.linear_solver.options['precon_side'] = 'left'
        group.linear_solver.options['ksp_type'] = 'richardson'

        p = Problem(group)
        p.setup(check=False)
        p.set_solver_print(level=0)

        # Conclude setup but don't run model.
        p.final_setup()

        d_inputs, d_outputs, d_residuals = group.get_linear_vectors()

        # forward
        d_residuals.set_const(1.0)
        d_outputs.set_const(0.0)
        group.run_linearize()
        group.run_solve_linear(['linear'], 'fwd')

        output = d_outputs._data
        assert_rel_error(self, output, group.expected_solution, 1e-15)

        # reverse
        d_outputs.set_const(1.0)
        d_residuals.set_const(0.0)
        group.run_linearize()
        group.run_solve_linear(['linear'], 'rev')

        output = d_residuals._data
        assert_rel_error(self, output, group.expected_solution, 3e-15)

        # test the direct solver and make sure KSP correctly recurses for _linearize
        precon = group.linear_solver.precon = DirectSolver(assemble_jac=False)
        group.linear_solver.options['precon_side'] = 'left'
        group.linear_solver.options['ksp_type'] = 'richardson'

        p.setup(check=False)

        # Conclude setup but don't run model.
        p.final_setup()

        d_inputs, d_outputs, d_residuals = group.get_linear_vectors()

        # forward
        d_residuals.set_const(1.0)
        d_outputs.set_const(0.0)
        group.linear_solver._linearize()
        group.run_solve_linear(['linear'], 'fwd')

        output = d_outputs._data
        assert_rel_error(self, output, group.expected_solution, 1e-15)

        # reverse
        d_outputs.set_const(1.0)
        d_residuals.set_const(0.0)
        group.linear_solver._linearize()
        group.run_solve_linear(['linear'], 'rev')

        output = d_residuals._data
        assert_rel_error(self, output, group.expected_solution, 3e-15)
예제 #17
0
    def test_group_assembled_jac_with_ext_mat(self):
        class TwoSellarDis1(ExplicitComponent):
            """
            Component containing Discipline 1 -- no derivatives version.
            """
            def setup(self):
                self.add_input('z', val=np.zeros(2))
                self.add_input('x', val=np.zeros(2))
                self.add_input('y2', val=np.ones(2))
                self.add_output('y1', val=np.ones(2))

                self.declare_partials(of='*', wrt='*')

            def compute(self, inputs, outputs):
                z1 = inputs['z'][0]
                z2 = inputs['z'][1]
                x1 = inputs['x']
                y2 = inputs['y2']

                outputs['y1'][0] = z1**2 + z2 + x1[0] - 0.2 * y2[0]
                outputs['y1'][1] = z1**2 + z2 + x1[0] - 0.2 * y2[0]

            def compute_partials(self, inputs, partials):
                """
                Jacobian for Sellar discipline 1.
                """
                partials['y1', 'y2'] = np.array([[-0.2, 0.], [0., -0.2]])
                partials['y1', 'z'] = np.array([[2.0 * inputs['z'][0], 1.0],
                                                [2.0 * inputs['z'][0], 1.0]])
                partials['y1', 'x'] = np.eye(2)

        class TwoSellarDis2(ExplicitComponent):
            def setup(self):
                self.add_input('z', val=np.zeros(2))
                self.add_input('y1', val=np.ones(2))
                self.add_output('y2', val=np.ones(2))

                self.declare_partials('*', '*', method='fd')

            def compute(self, inputs, outputs):

                z1 = inputs['z'][0]
                z2 = inputs['z'][1]
                y1 = inputs['y1']

                # Note: this may cause some issues. However, y1 is constrained to be
                # above 3.16, so lets just let it converge, and the optimizer will
                # throw it out
                if y1[0].real < 0.0:
                    y1[0] *= -1
                if y1[1].real < 0.0:
                    y1[1] *= -1

                outputs['y2'][0] = y1[0]**.5 + z1 + z2
                outputs['y2'][1] = y1[1]**.5 + z1 + z2

            def compute_partials(self, inputs, J):
                y1 = inputs['y1']
                if y1[0].real < 0.0:
                    y1[0] *= -1
                if y1[1].real < 0.0:
                    y1[1] *= -1

                J['y2', 'y1'] = np.array([[.5 * y1[0]**-.5, 0.],
                                          [0., .5 * y1[1]**-.5]])
                J['y2', 'z'] = np.array([[1.0, 1.0], [1.0, 1.0]])

        prob = Problem()
        model = prob.model

        model.add_subsystem('px',
                            IndepVarComp('x', np.array([1.0, 1.0])),
                            promotes=['x'])
        model.add_subsystem('pz',
                            IndepVarComp('z', np.array([5.0, 2.0])),
                            promotes=['z'])
        sup = model.add_subsystem('sup', Group(), promotes=['*'])

        sub1 = sup.add_subsystem('sub1', Group(), promotes=['*'])
        sub2 = sup.add_subsystem('sub2', Group(), promotes=['*'])

        d1 = sub1.add_subsystem('d1',
                                TwoSellarDis1(),
                                promotes=['x', 'z', 'y1', 'y2'])
        sub2.add_subsystem('d2', TwoSellarDis2(), promotes=['z', 'y1', 'y2'])

        model.add_subsystem('con_cmp1',
                            ExecComp('con1 = 3.16 - y1[0] - y1[1]',
                                     y1=np.array([0.0, 0.0])),
                            promotes=['con1', 'y1'])
        model.add_subsystem('con_cmp2',
                            ExecComp('con2 = y2[0] + y2[1] - 24.0',
                                     y2=np.array([0.0, 0.0])),
                            promotes=['con2', 'y2'])

        model.linear_solver = LinearBlockGS()
        sup.linear_solver = LinearBlockGS()

        sub1.linear_solver = DirectSolver(assemble_jac=True)
        sub2.linear_solver = DirectSolver(assemble_jac=True)
        prob.set_solver_print(level=0)

        prob.setup(check=False, mode='rev')
        prob.run_model()

        of = ['con1', 'con2']
        wrt = ['x', 'z']

        # Make sure we don't get a size mismatch.
        derivs = prob.compute_totals(of=of, wrt=wrt)
예제 #18
0
    def test_cruise_results(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

        phase = Phase('gauss-lobatto',
                      ode_class=AircraftODE,
                      num_segments=1,
                      transcription_order=13)

        # 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=(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.add_control('alt',
                          units='km',
                          opt=False,
                          rate_param='climb_rate')

        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)

        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(assemble_jac=True)
        p.model.options['assembled_jac_type'] = 'csc'

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

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

        p.run_driver()

        tas = phase.get_values('tas_comp.TAS', units='m/s')
        time = phase.get_values('time', units='s')
        range = phase.get_values('range', units='m')

        assert_rel_error(self, range, tas * time, tolerance=1.0E-9)
예제 #19
0
    def test_assembled_jacobian_unsupported_cases(self):
        class ParaboloidApply(ImplicitComponent):
            def setup(self):
                self.add_input('x', val=0.0)
                self.add_input('y', val=0.0)

                self.add_output('f_xy', val=0.0)

            def linearize(self, inputs, outputs, jacobian):
                return

            def apply_linear(self, inputs, outputs, d_inputs, d_outputs,
                             d_residuals, mode):
                d_residuals['x'] += (
                    np.exp(outputs['x']) -
                    2 * inputs['a']**2 * outputs['x']) * d_outputs['x']
                d_residuals['x'] += (-2 * inputs['a'] *
                                     outputs['x']**2) * d_inputs['a']

        # One level deep

        prob = Problem()
        model = prob.model = Group(assembled_jac_type='dense')
        model.linear_solver = DirectSolver(assemble_jac=True)

        model.add_subsystem('p1', IndepVarComp('x', val=1.0))
        model.add_subsystem('p2', IndepVarComp('y', val=1.0))
        model.add_subsystem('comp', ParaboloidApply())

        model.connect('p1.x', 'comp.x')
        model.connect('p2.y', 'comp.y')

        prob.setup()

        msg = "AssembledJacobian not supported for matrix-free subcomponent."
        with self.assertRaisesRegex(Exception, msg):
            prob.run_model()

        # Nested

        prob = Problem()
        model = prob.model = Group(assembled_jac_type='dense')
        model.linear_solver = DirectSolver(assemble_jac=True)

        sub = model.add_subsystem('sub', Group())

        model.add_subsystem('p1', IndepVarComp('x', val=1.0))
        model.add_subsystem('p2', IndepVarComp('y', val=1.0))
        sub.add_subsystem('comp', ParaboloidApply())

        model.connect('p1.x', 'sub.comp.x')
        model.connect('p2.y', 'sub.comp.y')

        prob.setup()

        msg = "AssembledJacobian not supported for matrix-free subcomponent."
        with self.assertRaisesRegex(Exception, msg):
            prob.run_model()

        # Try a component that is derived from a matrix-free one

        class FurtherDerived(ParaboloidApply):
            def do_nothing(self):
                pass

        prob = Problem()
        model = prob.model = Group(assembled_jac_type='dense')
        model.linear_solver = DirectSolver(assemble_jac=True)

        model.add_subsystem('p1', IndepVarComp('x', val=1.0))
        model.add_subsystem('p2', IndepVarComp('y', val=1.0))
        model.add_subsystem('comp', FurtherDerived())

        model.connect('p1.x', 'comp.x')
        model.connect('p2.y', 'comp.y')

        prob.setup()

        msg = "AssembledJacobian not supported for matrix-free subcomponent."
        with self.assertRaisesRegex(Exception, msg):
            prob.run_model()

        # Make sure regular comps don't give an error.

        prob = Problem()
        model = prob.model = Group(assembled_jac_type='dense')
        model.linear_solver = DirectSolver(assemble_jac=True)

        model.add_subsystem('p1', IndepVarComp('x', val=1.0))
        model.add_subsystem('p2', IndepVarComp('y', val=1.0))
        model.add_subsystem('comp', Paraboloid())

        model.connect('p1.x', 'comp.x')
        model.connect('p2.y', 'comp.y')

        prob.setup()
        prob.final_setup()

        class ParaboloidJacVec(Paraboloid):
            def linearize(self, inputs, outputs, jacobian):
                return

            def compute_jacvec_product(self, inputs, d_inputs, d_outputs,
                                       d_residuals, mode):
                d_residuals['x'] += (
                    np.exp(outputs['x']) -
                    2 * inputs['a']**2 * outputs['x']) * d_outputs['x']
                d_residuals['x'] += (-2 * inputs['a'] *
                                     outputs['x']**2) * d_inputs['a']

        # One level deep

        prob = Problem()
        model = prob.model = Group(assembled_jac_type='dense')
        model.linear_solver = DirectSolver(assemble_jac=True)

        model.add_subsystem('p1', IndepVarComp('x', val=1.0))
        model.add_subsystem('p2', IndepVarComp('y', val=1.0))
        model.add_subsystem('comp', ParaboloidJacVec())

        model.connect('p1.x', 'comp.x')
        model.connect('p2.y', 'comp.y')

        prob.setup()

        msg = "AssembledJacobian not supported for matrix-free subcomponent."
        with self.assertRaisesRegex(Exception, msg):
            prob.run_model()
예제 #20
0
    def test_nested_promotion_errors(self):
        """
        Tests for error-handling for promoted input variable names.
        """
        c1 = IndepVarComp('x')
        c2 = ExecComp('y=2*x')
        c3 = ExecComp('z=3*x')

        g = Group(assembled_jac_type='dense')
        g.add_subsystem('c2', c2, promotes=['*'])
        g.add_subsystem('c3', c3, promotes=['*'])
        g.linear_solver = DirectSolver(assemble_jac=True)

        model = Group()
        model.add_subsystem('c1', c1, promotes=['*'])
        model.add_subsystem('g', g)

        p = Problem(model)
        p.setup()

        # -------------------------------------------------------------------

        msg1 = "The promoted name g.x is invalid because it refers to multiple inputs: " \
               "[g.c2.x, g.c3.x] that are not connected to an output variable."

        # inputs (g.x is not connected)
        # with self.assertRaisesRegex(RuntimeError, msg1.format('g.x')):
        with self.assertRaises(Exception) as context:
            p['g.x'] = 5.0
            p.final_setup()

        self.assertEqual(str(context.exception), msg1)

        # Repeat test for post final_setup when vectors are allocated.
        p = Problem(model)
        p.setup()
        p.final_setup()

        # -------------------------------------------------------------------

        # inputs (g.x is not connected)
        with self.assertRaises(Exception) as context:
            p['g.x'] = 5.0
            p.final_setup()
        self.assertEqual(str(context.exception), msg1)

        # Start from a clean state again
        p = Problem(model)
        p.setup()

        with self.assertRaises(Exception) as context:
            self.assertEqual(p['g.x'], 5.0)
        self.assertEqual(str(context.exception), msg1)

        msg2 = "The promoted name x is invalid because it refers to multiple inputs: " \
               "[g.c2.x, g.c3.x] that are not connected to an output variable."

        jac = g.linear_solver._assembled_jac
        # d(outputs)/d(inputs)
        with self.assertRaises(Exception) as context:
            jac['y', 'x'] = 5.0
        self.assertEqual(str(context.exception), msg2)

        with self.assertRaises(Exception) as context:
            self.assertEqual(jac['y', 'x'], 5.0)
        self.assertEqual(str(context.exception), msg2)

        # -------------------------------------------------------------------

        # Repeat test for post final_setup when vectors are allocated.
        p = Problem(model)
        p.setup()
        p.final_setup()

        with self.assertRaises(Exception) as context:
            self.assertEqual(p['g.x'], 5.0)
        self.assertEqual(str(context.exception), msg1)

        # d(outputs)/d(inputs)
        with self.assertRaises(Exception) as context:
            jac['y', 'x'] = 5.0
        self.assertEqual(str(context.exception), msg2)

        with self.assertRaises(Exception) as context:
            self.assertEqual(jac['y', 'x'], 5.0)
        self.assertEqual(str(context.exception), msg2)

        # -------------------------------------------------------------------

        msg1 = "The promoted name g.x is invalid because it refers to multiple inputs: " \
               "[g.c2.x ,g.c3.x]. Access the value from the connected output variable x instead."

        # From here, 'g.x' has a valid source.
        model.connect('x', 'g.x')

        p = Problem(model)
        p.setup()

        # inputs (g.x is connected to x)
        p['g.x'] = 5.0
        with self.assertRaises(Exception) as context:
            p.final_setup()
        self.assertEqual(str(context.exception), msg1)

        # Repeat test for post final_setup when vectors are allocated.
        p = Problem(model)
        p.setup()
        p.final_setup()

        # inputs (g.x is connected to x)
        with self.assertRaises(Exception) as context:
            p['g.x'] = 5.0
        self.assertEqual(str(context.exception), msg1)

        # Final test, the getitem
        p = Problem(model)
        p.setup()

        with self.assertRaises(Exception) as context:
            self.assertEqual(p['g.x'], 5.0)
        self.assertEqual(str(context.exception), msg1)

        # d(outputs)/d(inputs)
        with self.assertRaises(Exception) as context:
            jac['y', 'x'] = 5.0
        self.assertEqual(str(context.exception), msg2)

        with self.assertRaises(Exception) as context:
            self.assertEqual(jac['y', 'x'],
                             5.0)  # Start from a clean state again
        self.assertEqual(str(context.exception), msg2)

        # Repeat test for post final_setup when vectors are allocated.
        p = Problem(model)
        p.setup()
        p.final_setup()

        with self.assertRaises(Exception) as context:
            self.assertEqual(p['g.x'], 5.0)
        self.assertEqual(str(context.exception), msg1)

        # d(outputs)/d(inputs)
        with self.assertRaises(Exception) as context:
            jac['y', 'x'] = 5.0
        self.assertEqual(str(context.exception), msg2)

        with self.assertRaises(Exception) as context:
            self.assertEqual(jac['y', 'x'], 5.0)
        self.assertEqual(str(context.exception), msg2)
    def test_brachistochrone_recording_for_docs(self):
        import numpy as np
        import matplotlib
        matplotlib.use('Agg')
        import matplotlib.pyplot as plt
        from openmdao.api import Problem, Group, ScipyOptimizeDriver, DirectSolver, \
            SqliteRecorder, CaseReader
        from openmdao.utils.assert_utils import assert_rel_error
        from dymos import Phase
        from dymos.examples.brachistochrone.brachistochrone_ode import BrachistochroneODE

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

        phase = Phase('gauss-lobatto',
                      ode_class=BrachistochroneODE,
                      num_segments=10)

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

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

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

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

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

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

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

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

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

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

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

        p.setup()

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

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

        # Solve for the optimal trajectory
        p.run_driver()

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

        cr = CaseReader('brachistochrone_solution.db')

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

        assert_rel_error(
            self, p['phase0.controls:theta'],
            outputs['phase0.indep_controls.controls:theta']['value'])

        phase0_options = cr.system_metadata['phase0']['component_options']

        num_segments = phase0_options['num_segments']
        transcription_order = phase0_options['transcription_order']
        segment_ends = phase0_options['segment_ends']
        ode_class = phase0_options['ode_class']

        print(num_segments)
        print(transcription_order)
        print(ode_class)
        print(segment_ends)
예제 #22
0
class PlanesIntersection(Group):
    def setup(self):
        self.add_subsystem('p3', Plane3())
        self.add_subsystem('p1', Plane1())
        self.add_subsystem('p2', Plane2())

        self.connect('p1.y', 'p2.y')
        self.connect('p1.y', 'p3.y')
        self.connect('p2.x', 'p3.x')
        self.connect('p2.x', 'p1.x')
        self.connect('p3.z', 'p1.z')
        self.connect('p3.z', 'p2.z')


if __name__ == '__main__':

    prob = Problem()

    prob.model = PlanesIntersection()
    a = prob.model.nonlinear_solver = NewtonSolver()
    a = prob.model.linear_solver = DirectSolver()

    a.options['maxiter'] = 10

    prob.setup()
    # view_model(prob)

    prob.run_model()
    print(prob['p1.y'], prob['p1.x'], prob['p1.z'])
예제 #23
0
    def test_solve_subsystems_internals(self):
        # Here we test that this feature is doing what it should do by counting the
        # number of calls in various places.

        class CountNewton(NewtonSolver):
            """ This version of Newton also counts how many times it runs in total."""

            def __init__(self, **kwargs):
                super(CountNewton, self).__init__(**kwargs)
                self.total_count = 0

            def _iter_execute(self):
                super(CountNewton, self)._iter_execute()
                self.total_count += 1

        class CountDS(DirectSolver):
            """ This version of Newton also counts how many times it linearizes"""

            def __init__(self, **kwargs):
                super(DirectSolver, self).__init__(**kwargs)
                self.lin_count = 0

            def _linearize(self):
                super(CountDS, self)._linearize()
                self.lin_count += 1

        prob = Problem(model=DoubleSellar())
        model = prob.model

        # each SubSellar group converges itself
        g1 = model.g1
        g1.nonlinear_solver = CountNewton()
        g1.nonlinear_solver.options['rtol'] = 1.0e-5
        g1.linear_solver = CountDS()  # used for derivatives

        g2 = model.g2
        g2.nonlinear_solver = CountNewton()
        g2.nonlinear_solver.options['rtol'] = 1.0e-5
        g2.linear_solver = DirectSolver()

        # Converge the outer loop with Gauss Seidel, with a looser tolerance.
        model.nonlinear_solver = NewtonSolver()
        model.linear_solver = ScipyKrylov()

        # Enfore behavior: max_sub_solves = 0 means we run once during init

        model.nonlinear_solver.options['maxiter'] = 5
        model.nonlinear_solver.options['solve_subsystems'] = True
        model.nonlinear_solver.options['max_sub_solves'] = 0
        prob.set_solver_print(level=0)

        prob.setup()
        prob.run_model()

        # Verifying subsolvers ran
        self.assertEqual(g1.nonlinear_solver.total_count, 2)
        self.assertEqual(g2.nonlinear_solver.total_count, 2)
        self.assertEqual(g1.linear_solver.lin_count, 2)

        prob = Problem(model=DoubleSellar())
        model = prob.model

        # each SubSellar group converges itself
        g1 = model.g1
        g1.nonlinear_solver = CountNewton()
        g1.nonlinear_solver.options['rtol'] = 1.0e-5
        g1.linear_solver = CountDS()  # used for derivatives

        g2 = model.g2
        g2.nonlinear_solver = CountNewton()
        g2.nonlinear_solver.options['rtol'] = 1.0e-5
        g2.linear_solver = DirectSolver()

        # Converge the outer loop with Gauss Seidel, with a looser tolerance.
        model.nonlinear_solver = NewtonSolver()
        model.linear_solver = ScipyKrylov()

        # Enforce Behavior: baseline

        model.nonlinear_solver.options['maxiter'] = 5
        model.nonlinear_solver.options['solve_subsystems'] = True
        model.nonlinear_solver.options['max_sub_solves'] = 5
        prob.set_solver_print(level=0)

        prob.setup()
        prob.run_model()

        # Verifying subsolvers ran
        self.assertEqual(g1.nonlinear_solver.total_count, 5)
        self.assertEqual(g2.nonlinear_solver.total_count, 5)
        self.assertEqual(g1.linear_solver.lin_count, 5)

        prob = Problem(model=DoubleSellar())
        model = prob.model

        # each SubSellar group converges itself
        g1 = model.g1
        g1.nonlinear_solver = CountNewton()
        g1.nonlinear_solver.options['rtol'] = 1.0e-5
        g1.linear_solver = CountDS()  # used for derivatives

        g2 = model.g2
        g2.nonlinear_solver = CountNewton()
        g2.nonlinear_solver.options['rtol'] = 1.0e-5
        g2.linear_solver = DirectSolver()

        # Converge the outer loop with Gauss Seidel, with a looser tolerance.
        model.nonlinear_solver = NewtonSolver()
        model.linear_solver = ScipyKrylov()

        # Enfore behavior: max_sub_solves = 1 means we run during init and first iteration of iter_execute

        model.nonlinear_solver.options['maxiter'] = 5
        model.nonlinear_solver.options['solve_subsystems'] = True
        model.nonlinear_solver.options['max_sub_solves'] = 1
        prob.set_solver_print(level=0)

        prob.setup()
        prob.run_model()

        # Verifying subsolvers ran
        self.assertEqual(g1.nonlinear_solver.total_count, 4)
        self.assertEqual(g2.nonlinear_solver.total_count, 4)
        self.assertEqual(g1.linear_solver.lin_count, 4)
예제 #24
0
    def setup(self):

        thermo_spec = species_data.janaf
        design = self.options['design']

        # Add engine elements
        self.add_subsystem(
            'fc', FlightConditions(thermo_data=thermo_spec, elements=AIR_MIX))
        self.add_subsystem(
            'inlet',
            Inlet(design=design, thermo_data=thermo_spec, elements=AIR_MIX))
        self.add_subsystem('comp',
                           Compressor(
                               map_data=AXI5,
                               design=design,
                               thermo_data=thermo_spec,
                               elements=AIR_MIX,
                           ),
                           promotes_inputs=[('Nmech', 'HP_Nmech')])
        self.add_subsystem(
            'burner',
            Combustor(design=design,
                      thermo_data=thermo_spec,
                      inflow_elements=AIR_MIX,
                      air_fuel_elements=AIR_FUEL_MIX,
                      fuel_type='JP-7'))
        self.add_subsystem('turb',
                           Turbine(
                               map_data=LPT2269,
                               design=design,
                               thermo_data=thermo_spec,
                               elements=AIR_FUEL_MIX,
                           ),
                           promotes_inputs=[('Nmech', 'HP_Nmech')])
        self.add_subsystem('pt',
                           Turbine(
                               map_data=LPT2269,
                               design=design,
                               thermo_data=thermo_spec,
                               elements=AIR_FUEL_MIX,
                           ),
                           promotes_inputs=[('Nmech', 'LP_Nmech')])
        self.add_subsystem(
            'nozz',
            Nozzle(nozzType='CV',
                   lossCoef='Cv',
                   thermo_data=thermo_spec,
                   elements=AIR_FUEL_MIX))
        self.add_subsystem('HP_shaft',
                           Shaft(num_ports=2),
                           promotes_inputs=[('Nmech', 'HP_Nmech')])
        self.add_subsystem('LP_shaft',
                           Shaft(num_ports=1),
                           promotes_inputs=[('Nmech', 'LP_Nmech')])
        self.add_subsystem('perf', Performance(num_nozzles=1, num_burners=1))

        # Connect flow stations
        connect_flow(self, 'fc.Fl_O', 'inlet.Fl_I', connect_w=False)
        connect_flow(self, 'inlet.Fl_O', 'comp.Fl_I')
        connect_flow(self, 'comp.Fl_O', 'burner.Fl_I')
        connect_flow(self, 'burner.Fl_O', 'turb.Fl_I')
        connect_flow(self, 'turb.Fl_O', 'pt.Fl_I')
        connect_flow(self, 'pt.Fl_O', 'nozz.Fl_I')

        # Connect turbomachinery elements to shaft
        self.connect('comp.trq', 'HP_shaft.trq_0')
        self.connect('turb.trq', 'HP_shaft.trq_1')
        self.connect('pt.trq', 'LP_shaft.trq_0')

        # Connnect nozzle exhaust to freestream static conditions
        self.connect('fc.Fl_O:stat:P', 'nozz.Ps_exhaust')

        # Connect outputs to pefromance element
        self.connect('inlet.Fl_O:tot:P', 'perf.Pt2')
        self.connect('comp.Fl_O:tot:P', 'perf.Pt3')
        self.connect('burner.Wfuel', 'perf.Wfuel_0')
        self.connect('inlet.F_ram', 'perf.ram_drag')
        self.connect('nozz.Fg', 'perf.Fg_0')
        self.connect('LP_shaft.pwr_net', 'perf.power')

        # Add balances for design and off-design
        balance = self.add_subsystem('balance', BalanceComp())
        if design:

            balance.add_balance('W', val=27.0, units='lbm/s', eq_units=None)
            self.connect('balance.W', 'inlet.Fl_I:stat:W')
            self.connect('nozz.PR', 'balance.lhs:W')

            balance.add_balance('FAR', eq_units='degR', lower=1e-4, val=.017)
            self.connect('balance.FAR', 'burner.Fl_I:FAR')
            self.connect('burner.Fl_O:tot:T', 'balance.lhs:FAR')

            balance.add_balance('turb_PR',
                                val=3.0,
                                lower=1.001,
                                upper=8,
                                eq_units='hp',
                                rhs_val=0.)
            self.connect('balance.turb_PR', 'turb.PR')
            self.connect('HP_shaft.pwr_net', 'balance.lhs:turb_PR')

            balance.add_balance('pt_PR',
                                val=3.0,
                                lower=1.001,
                                upper=8,
                                eq_units='hp')
            self.connect('balance.pt_PR', 'pt.PR')
            self.connect('LP_shaft.pwr_net', 'balance.lhs:pt_PR')

        else:

            balance.add_balance('FAR', eq_units='hp', lower=1e-4, val=.3)
            self.connect('balance.FAR', 'burner.Fl_I:FAR')
            self.connect('LP_shaft.pwr_net', 'balance.lhs:FAR')

            balance.add_balance('HP_Nmech',
                                val=1.5,
                                units='rpm',
                                lower=500.,
                                eq_units='hp',
                                rhs_val=0.)
            self.connect('balance.HP_Nmech', 'HP_Nmech')
            self.connect('HP_shaft.pwr_net', 'balance.lhs:HP_Nmech')

            balance.add_balance('W',
                                val=27.0,
                                units='lbm/s',
                                eq_units='inch**2')
            self.connect('balance.W', 'inlet.Fl_I:stat:W')
            self.connect('nozz.Throat:stat:area', 'balance.lhs:W')

        # Setup solver to converge engine
        self.set_order([
            'balance', 'fc', 'inlet', 'comp', 'burner', 'turb', 'pt', 'nozz',
            'HP_shaft', 'LP_shaft', 'perf'
        ])

        newton = self.nonlinear_solver = NewtonSolver()
        newton.options['atol'] = 1e-6
        newton.options['rtol'] = 1e-6
        newton.options['iprint'] = 2
        newton.options['maxiter'] = 15
        newton.options['solve_subsystems'] = True
        newton.options['max_sub_solves'] = 100
        newton.linesearch = BoundsEnforceLS()
        # newton.linesearch = ArmijoGoldsteinLS()
        # newton.linesearch.options['c'] = .0001
        newton.linesearch.options['bound_enforcement'] = 'scalar'
        newton.linesearch.options['iprint'] = -1

        self.linear_solver = DirectSolver(assemble_jac=True)
예제 #25
0
    def setup(self):

        F = 4 * 10**7

        indeps = self.add_subsystem("indeps", IndepVarComp())
        indeps.add_output(
            "n0_x_reaction_direction",
            0,
            units="rad",
            desc=
            "Direction of horizontal reaction force of pinned joint on node 0")
        indeps.add_output(
            "n0_y_reaction_direction",
            math.pi / 2,
            units="rad",
            desc=
            "Direction of vertical reaction force of pinned joint on node 0")
        indeps.add_output(
            "n1_x_reaction_direction",
            0,
            units="rad",
            desc="Direction of reaction force of roller joint on node 1")
        indeps.add_output("n0_beam0",
                          math.pi * 7 / 4,
                          units="rad",
                          desc="Direction of beam 0 at node 0")
        indeps.add_output("n0_beam1",
                          math.pi * 3 / 2,
                          units="rad",
                          desc="Direction of beam 1 at node 0")
        indeps.add_output("n1_beam1",
                          math.pi / 2,
                          units="rad",
                          desc="Direction of beam 1 at node 1")
        indeps.add_output("n1_beam2",
                          0,
                          units="rad",
                          desc="Direction of beam 2 at node 1")
        indeps.add_output("n1_beam3",
                          math.pi * 5 / 3,
                          units="rad",
                          desc="Direction of beam 3 at node 1")
        indeps.add_output("n2_beam3",
                          math.pi * 2 / 3,
                          units="rad",
                          desc="Direction of beam 2 at node 2")
        indeps.add_output("n2_beam4",
                          math.pi / 3,
                          units="rad",
                          desc="Direction of beam 4 at node 2")
        indeps.add_output("n3_beam4",
                          math.pi * 5 / 3,
                          units="rad",
                          desc="Direction of beam 4 at node 3")
        indeps.add_output("n3_beam2",
                          math.pi,
                          units="rad",
                          desc="Direction of beam 5 at node 3")
        indeps.add_output("n3_beam0",
                          math.pi * 3 / 4,
                          units="rad",
                          desc="Direction of beam 0 at node 4")
        indeps.add_output("ext",
                          F,
                          units="N",
                          desc="Force applied to beam structure")
        indeps.add_output("ext_direction",
                          math.pi * 3 / 2,
                          units="rad",
                          desc="Direction of force applied to beam structure")

        indeps.add_output("A0", 1)
        indeps.add_output("A1", 1)
        indeps.add_output("A2", 1)
        indeps.add_output("A3", 1)
        indeps.add_output("A4", 1)
        indeps.add_output("L1")
        indeps.add_output("L2")

        cycle = self.add_subsystem("cycle", Group())
        cycle.add_subsystem("node0", Node(n_loads=2, n_reactions=2))
        cycle.add_subsystem("node1", Node(n_loads=3, n_reactions=1))
        cycle.add_subsystem("node2", Node(n_loads=2, n_external_forces=1))
        cycle.add_subsystem("node3", Node(n_loads=3))
        cycle.add_subsystem("beam0", Beam())
        cycle.add_subsystem("beam1", Beam())
        cycle.add_subsystem("beam2", Beam())
        cycle.add_subsystem("beam3", Beam())
        cycle.add_subsystem("beam4", Beam())

        #Node 0 connections
        self.connect("indeps.n0_x_reaction_direction",
                     "cycle.node0.direction0_reaction")
        self.connect("indeps.n0_y_reaction_direction",
                     "cycle.node0.direction1_reaction")
        self.connect("indeps.n0_beam0", "cycle.node0.direction0_load")
        self.connect("indeps.n0_beam1", "cycle.node0.direction1_load")
        #Node 1 connections
        self.connect("indeps.n1_x_reaction_direction",
                     "cycle.node1.direction0_reaction")
        self.connect("indeps.n1_beam1", "cycle.node1.direction0_load")
        self.connect("indeps.n1_beam2", "cycle.node1.direction1_load")
        self.connect("indeps.n1_beam3", "cycle.node1.direction2_load")
        #Node 2 connections
        self.connect("indeps.n2_beam3", "cycle.node2.direction0_load")
        self.connect("indeps.n2_beam4", "cycle.node2.direction1_load")
        self.connect("indeps.ext", "cycle.node2.force0_ext")
        self.connect("indeps.ext_direction", "cycle.node2.direction0_ext")
        #Node 3 connections
        self.connect("indeps.n3_beam0", "cycle.node3.direction0_load")
        self.connect("indeps.n3_beam2", "cycle.node3.direction1_load")
        self.connect("indeps.n3_beam4", "cycle.node3.direction2_load")
        #Inter-node connections
        self.connect("cycle.node0.load_out0", "cycle.beam0.force0")
        self.connect("cycle.node0.load_out1", "cycle.beam1.force0")
        self.connect("cycle.node1.load_out0", "cycle.beam1.force1")
        self.connect("cycle.node1.load_out1", "cycle.beam2.force0")
        self.connect("cycle.node1.load_out2", "cycle.beam3.force0")
        self.connect("cycle.node2.load_out0", "cycle.beam3.force1")
        self.connect("cycle.node2.load_out1", "cycle.beam4.force0")
        self.connect("cycle.node3.load_out0", "cycle.beam0.force1")
        self.connect("cycle.node3.load_out1", "cycle.beam2.force1")
        self.connect("cycle.node3.load_out2", "cycle.beam4.force1")
        self.connect("cycle.beam0.beam_force",
                     ["cycle.node0.load_in0", "cycle.node3.load_in0"])
        self.connect("cycle.beam1.beam_force",
                     ["cycle.node0.load_in1", "cycle.node1.load_in0"])
        self.connect("cycle.beam2.beam_force",
                     ["cycle.node1.load_in1", "cycle.node3.load_in1"])
        self.connect("cycle.beam3.beam_force",
                     ["cycle.node1.load_in2", "cycle.node2.load_in0"])
        self.connect("cycle.beam4.beam_force",
                     ["cycle.node2.load_in1", "cycle.node3.load_in2"])

        cycle.nonlinear_solver = NewtonSolver()
        cycle.nonlinear_solver.options['atol'] = 1e-7
        cycle.nonlinear_solver.options['solve_subsystems'] = True
        cycle.nonlinear_solver.options["iprint"] = 2
        cycle.linear_solver = DirectSolver()

        self.add_subsystem(
            "obj_cmp", ExecComp("obj = L1 * (A3 + A1 + A2 + A4) + L2 * A0"))
        self.add_subsystem("con0", ExecComp("con = 400 - abs(sigma)"))
        self.add_subsystem("con1", ExecComp("con = 400 - abs(sigma)"))
        self.add_subsystem("con2", ExecComp("con = 400 - abs(sigma)"))
        self.add_subsystem("con3", ExecComp("con = 400 - abs(sigma)"))
        self.add_subsystem("con4", ExecComp("con = 400 - abs(sigma)"))

        self.connect("indeps.L1", ["obj_cmp.L1"])
        self.connect("indeps.L2", ["obj_cmp.L2"])
        self.connect("cycle.beam0.sigma", ["con0.sigma"])
        self.connect("cycle.beam1.sigma", ["con1.sigma"])
        self.connect("cycle.beam2.sigma", ["con2.sigma"])
        self.connect("cycle.beam3.sigma", ["con3.sigma"])
        self.connect("cycle.beam4.sigma", ["con4.sigma"])
        self.connect("indeps.A0", ["cycle.beam0.A", "obj_cmp.A0"])
        self.connect("indeps.A1", ["cycle.beam1.A", "obj_cmp.A1"])
        self.connect("indeps.A2", ["cycle.beam2.A", "obj_cmp.A2"])
        self.connect("indeps.A3", ["cycle.beam3.A", "obj_cmp.A3"])
        self.connect("indeps.A4", ["cycle.beam4.A", "obj_cmp.A4"])
예제 #26
0
def brachistochrone_min_time(transcription='gauss-lobatto',
                             num_segments=8,
                             transcription_order=3,
                             compressed=True,
                             sim_record='brach_min_time_sim.db',
                             optimizer='SLSQP',
                             dynamic_simul_derivs=True,
                             force_alloc_complex=False,
                             solve_segments=False,
                             run_driver=True):
    p = Problem(model=Group())

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

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

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

    phase = Phase(ode_class=BrachistochroneVectorStatesODE,
                  transcription=transcription)

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

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

    fix_final = not solve_segments  # can't fix final position if you're solving the segments
    phase.set_state_options('pos',
                            fix_initial=True,
                            fix_final=fix_final,
                            solve_segments=solve_segments)
    phase.set_state_options('v',
                            fix_initial=True,
                            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_design_parameter('g', units='m/s**2', opt=False, val=9.80665)

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

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

    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_model()
    if run_driver:
        p.run_driver()

    # Plot results
    if SHOW_PLOTS:
        p.run_driver()
        exp_out = phase.simulate(record_file=sim_record)

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

        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
예제 #27
0
    def test_result(self):
        prob = Problem(model=Group())

        ivc = IndepVarComp()

        ivc.add_output(name='M', val=0.0, units='deg', desc='Mean anomaly')

        ivc.add_output(name='ecc',
                       val=0.0,
                       units=None,
                       desc='orbit eccentricity')

        bal = BalanceComp()

        bal.add_balance(name='E',
                        val=0.0,
                        units='rad',
                        eq_units='rad',
                        rhs_name='M')

        # Override the guess_nonlinear method, always initialize E to the value of M
        def guess_func(inputs, outputs, residuals):
            outputs['E'] = inputs['M']

        bal.guess_nonlinear = guess_func

        # ExecComp used to compute the LHS of Kepler's equation.
        lhs_comp = ExecComp('lhs=E - ecc * sin(E)',
                            lhs={
                                'value': 0.0,
                                'units': 'rad'
                            },
                            E={
                                'value': 0.0,
                                'units': 'rad'
                            },
                            ecc={'value': 0.0})

        prob.model.add_subsystem(name='ivc',
                                 subsys=ivc,
                                 promotes_outputs=['M', 'ecc'])

        prob.model.add_subsystem(name='balance',
                                 subsys=bal,
                                 promotes_inputs=['M'],
                                 promotes_outputs=['E'])

        prob.model.add_subsystem(name='lhs_comp',
                                 subsys=lhs_comp,
                                 promotes_inputs=['E', 'ecc'])

        # Explicit connections
        prob.model.connect('lhs_comp.lhs', 'balance.lhs:E')

        # Setup solvers
        prob.model.linear_solver = DirectSolver()
        prob.model.nonlinear_solver = NewtonSolver()
        prob.model.nonlinear_solver.options['maxiter'] = 100
        prob.model.nonlinear_solver.options['iprint'] = 0

        prob.setup()

        prob['M'] = 85.0
        prob['ecc'] = 0.6

        prob.run_model()

        assert_almost_equal(np.degrees(prob['E']), 115.9, decimal=1)

        print('E (deg) = ', np.degrees(prob['E'][0]))
    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
예제 #29
0
    def setup(self):
        surfaces = self.options['surfaces']

        coupled = Group()

        for surface in surfaces:

            name = surface['name']

            # Connect the output of the loads component with the FEM
            # displacement parameter. This links the coupling within the coupled
            # group that necessitates the subgroup solver.
            coupled.connect(name + '_loads.loads', name + '.loads')

            # Perform the connections with the modified names within the
            # 'aero_states' group.
            coupled.connect(name + '.normals', 'aero_states.' + name + '_normals')
            coupled.connect(name + '.def_mesh', 'aero_states.' + name + '_def_mesh')

            # Connect the results from 'coupled' to the performance groups
            coupled.connect(name + '.def_mesh', name + '_loads.def_mesh')
            coupled.connect('aero_states.' + name + '_sec_forces', name + '_loads.sec_forces')

            # Connect the results from 'aero_states' to the performance groups
            self.connect('coupled.aero_states.' + name + '_sec_forces', name + '_perf' + '.sec_forces')

            # Connection performance functional variables
            self.connect(name + '_perf.CL', 'total_perf.' + name + '_CL')
            self.connect(name + '_perf.CD', 'total_perf.' + name + '_CD')
            self.connect('coupled.aero_states.' + name + '_sec_forces', 'total_perf.' + name + '_sec_forces')
            self.connect('coupled.' + name + '.chords', name + '_perf.aero_funcs.chords')

            # Connect parameters from the 'coupled' group to the performance
            # groups for the individual surfaces.
            self.connect('coupled.' + name + '.disp', name + '_perf.disp')
            self.connect('coupled.' + name + '.S_ref', name + '_perf.S_ref')
            self.connect('coupled.' + name + '.widths', name + '_perf.widths')
            # self.connect('coupled.' + name + '.chords', name + '_perf.chords')
            self.connect('coupled.' + name + '.lengths', name + '_perf.lengths')
            self.connect('coupled.' + name + '.cos_sweep', name + '_perf.cos_sweep')

            # Connect parameters from the 'coupled' group to the total performance group.
            self.connect('coupled.' + name + '.S_ref', 'total_perf.' + name + '_S_ref')
            self.connect('coupled.' + name + '.widths', 'total_perf.' + name + '_widths')
            self.connect('coupled.' + name + '.chords', 'total_perf.' + name + '_chords')
            self.connect('coupled.' + name + '.b_pts', 'total_perf.' + name + '_b_pts')

            # Add components to the 'coupled' group for each surface.
            # The 'coupled' group must contain all components and parameters
            # needed to converge the aerostructural system.
            coupled_AS_group = CoupledAS(surface=surface)

            if surface['distributed_fuel_weight']:
                promotes = ['load_factor']
            else:
                promotes = []

            coupled.add_subsystem(name, coupled_AS_group, promotes_inputs=promotes)

        # Add a single 'aero_states' component for the whole system within the
        # coupled group.
        coupled.add_subsystem('aero_states',
            VLMStates(surfaces=surfaces),
            promotes_inputs=['v', 'alpha', 'rho'])

        # Explicitly connect parameters from each surface's group and the common
        # 'aero_states' group.
        for surface in surfaces:
            name = surface['name']

            # Add a loads component to the coupled group
            coupled.add_subsystem(name + '_loads', LoadTransfer(surface=surface))

        """
        ### Change the solver settings here ###
        """

        # Set solver properties for the coupled group
        # coupled.linear_solver = ScipyIterativeSolver()
        # coupled.linear_solver.precon = LinearRunOnce()

        coupled.nonlinear_solver = NonlinearBlockGS(use_aitken=True)
        coupled.nonlinear_solver.options['maxiter'] = 50
        coupled.nonlinear_solver.options['atol'] = 5e-6
        coupled.nonlinear_solver.options['rtol'] = 1e-12

        # coupled.linear_solver = DirectSolver()

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

        # coupled.nonlinear_solver = NewtonSolver(solve_subsystems=True)
        # coupled.nonlinear_solver.options['maxiter'] = 50
        coupled.nonlinear_solver.options['iprint'] = 0

        """
        ### End change of solver settings ###
        """

        # Add the coupled group to the model problem
        self.add_subsystem('coupled', coupled, promotes_inputs=['v', 'alpha', 'rho'])

        for surface in surfaces:
            name = surface['name']

            # Add a performance group which evaluates the data after solving
            # the coupled system
            perf_group = CoupledPerformance(surface=surface)

            self.add_subsystem(name + '_perf', perf_group, promotes_inputs=['rho', 'v', 'alpha', 're', 'Mach_number'])

        # Add functionals to evaluate performance of the system.
        # Note that only the interesting results are promoted here; not all
        # of the parameters.
        self.add_subsystem('total_perf',
                 TotalPerformance(surfaces=surfaces,
                 user_specified_Sref=self.options['user_specified_Sref'],
                 internally_connect_fuelburn=self.options['internally_connect_fuelburn']),
                 promotes_inputs=['v', 'rho', 'empty_cg', 'total_weight', 'CT', 'speed_of_sound', 'R', 'Mach_number', 'W0', 'load_factor', 'S_ref_total'],
                 promotes_outputs=['L_equals_W', 'fuelburn', 'CL', 'CD', 'CM', 'cg'])
예제 #30
0
    def test_result(self):
        import numpy as np
        from numpy.testing import assert_almost_equal

        from openmdao.api import Problem, Group, IndepVarComp, BalanceComp, \
            ExecComp, DirectSolver, NewtonSolver

        prob = Problem(model=Group())

        ivc = IndepVarComp()

        ivc.add_output(name='M', val=0.0, units='deg', desc='Mean anomaly')

        ivc.add_output(name='ecc',
                       val=0.0,
                       units=None,
                       desc='orbit eccentricity')

        bal = BalanceComp()

        def guess_function(inputs, outputs):
            return inputs['M']

        bal.add_balance(name='E',
                        val=0.0,
                        units='rad',
                        eq_units='rad',
                        rhs_name='M',
                        guess_func=guess_function)

        # ExecComp used to compute the LHS of Kepler's equation.
        lhs_comp = ExecComp('lhs=E - ecc * sin(E)',
                            lhs={
                                'value': 0.0,
                                'units': 'rad'
                            },
                            E={
                                'value': 0.0,
                                'units': 'rad'
                            },
                            ecc={'value': 0.0})

        prob.model.add_subsystem(name='ivc',
                                 subsys=ivc,
                                 promotes_outputs=['M', 'ecc'])

        prob.model.add_subsystem(name='balance',
                                 subsys=bal,
                                 promotes_inputs=['M'],
                                 promotes_outputs=['E'])

        prob.model.add_subsystem(name='lhs_comp',
                                 subsys=lhs_comp,
                                 promotes_inputs=['E', 'ecc'])

        # Explicit connections
        prob.model.connect('lhs_comp.lhs', 'balance.lhs:E')

        # Setup solvers
        prob.model.linear_solver = DirectSolver()
        prob.model.nonlinear_solver = NewtonSolver()
        prob.model.nonlinear_solver.options['maxiter'] = 100
        prob.model.nonlinear_solver.options['iprint'] = 0

        prob.setup()

        prob['M'] = 85.0
        prob['ecc'] = 0.6

        prob.run_model()

        assert_almost_equal(np.degrees(prob['E']), 115.9, decimal=1)

        print('E (deg) = ', np.degrees(prob['E'][0]))
예제 #31
0
    def test_solve_linear_ksp_precon(self):
        """Solve implicit system with PETScKrylov using a preconditioner."""

        group = TestImplicitGroup(lnSolverClass=PETScKrylov)
        precon = group.linear_solver.precon = LinearBlockGS()

        p = Problem(group)
        p.setup(vector_class=PETScVector, check=False)
        p.set_solver_print(level=0)

        # Conclude setup but don't run model.
        p.final_setup()

        d_inputs, d_outputs, d_residuals = group.get_linear_vectors()

        # forward
        d_residuals.set_const(1.0)
        d_outputs.set_const(0.0)
        group.run_solve_linear(['linear'], 'fwd')

        output = d_outputs._data
        assert_rel_error(self, output[1], group.expected_solution[0], 1e-15)
        assert_rel_error(self, output[5], group.expected_solution[1], 1e-15)

        self.assertTrue(precon._iter_count > 0)

        # reverse
        d_outputs.set_const(1.0)
        d_residuals.set_const(0.0)
        group.run_solve_linear(['linear'], 'rev')

        output = d_residuals._data
        assert_rel_error(self, output[1], group.expected_solution[0], 3e-15)
        assert_rel_error(self, output[5], group.expected_solution[1], 3e-15)

        self.assertTrue(precon._iter_count > 0)

        # test the direct solver and make sure KSP correctly recurses for _linearize
        precon = group.linear_solver.precon = DirectSolver()
        p.setup(vector_class=PETScVector, check=False)

        # Conclude setup but don't run model.
        p.final_setup()

        d_inputs, d_outputs, d_residuals = group.get_linear_vectors()

        # forward
        d_residuals.set_const(1.0)
        d_outputs.set_const(0.0)
        group.linear_solver._linearize()
        group.run_solve_linear(['linear'], 'fwd')

        output = d_outputs._data
        assert_rel_error(self, output[1], group.expected_solution[0], 1e-15)
        assert_rel_error(self, output[5], group.expected_solution[1], 1e-15)

        # reverse
        d_outputs.set_const(1.0)
        d_residuals.set_const(0.0)
        group.linear_solver._linearize()
        group.run_solve_linear(['linear'], 'rev')

        output = d_residuals._data
        assert_rel_error(self, output[1], group.expected_solution[0], 3e-15)
        assert_rel_error(self, output[5], group.expected_solution[1], 3e-15)