示例#1
0
    def test_reraise_error(self):

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

        g1 = model.g1
        g1.nonlinear_solver = om.BroydenSolver()
        g1.nonlinear_solver.options['maxiter'] = 1
        g1.nonlinear_solver.options['err_on_non_converge'] = True
        g1.linear_solver = om.DirectSolver(assemble_jac=True)

        g2 = model.g2
        g2.nonlinear_solver = om.BroydenSolver()
        g2.nonlinear_solver.options['maxiter'] = 1
        g2.nonlinear_solver.options['err_on_non_converge'] = True
        g2.linear_solver = om.DirectSolver(assemble_jac=True)

        model.nonlinear_solver = om.BroydenSolver()
        model.linear_solver = om.DirectSolver(assemble_jac=True)
        model.nonlinear_solver.options['err_on_non_converge'] = True
        model.nonlinear_solver.options['reraise_child_analysiserror'] = True

        prob.setup()

        with self.assertRaises(om.AnalysisError) as context:
            prob.run_model()

        msg = "Solver 'NL: BROYDEN' on system 'g1' failed to converge in 1 iterations."
        self.assertEqual(str(context.exception), msg)
示例#2
0
    def test_distributed_comp_states(self):
        prob = om.Problem()
        model = prob.model
        sub = model.add_subsystem('sub', om.Group(), promotes=['*'])

        sub.add_subsystem('d1',
                          DistribExecComp(
                              ['y1 = 28 - 0.2*y2', 'y1 = 18 - 0.2*y2'],
                              arr_size=2),
                          promotes=['y1', 'y2'])
        sub.add_subsystem('d2',
                          DistribExecComp(
                              ['y2 = y1**.5 + 7', 'y2 = y1**.5 - 3'],
                              arr_size=2),
                          promotes=['y1', 'y2'])

        sub.nonlinear_solver = om.BroydenSolver(state_vars=['y1', 'y2'])
        sub.linear_solver = om.DirectSolver()
        model.linear_solver = om.DirectSolver()

        prob.setup(check=False, force_alloc_complex=True)
        prob.set_solver_print(level=2)

        prob.run_model()

        np.testing.assert_allclose(prob.get_val('y1', get_remote=True),
                                   np.array([25.58830237, 17.75721382]),
                                   .00001)
示例#3
0
    def test_distributed_comp(self):
        prob = om.Problem()
        model = prob.model
        sub = model.add_subsystem('sub', om.Group(), promotes=['*'])

        sub.add_subsystem('d1',
                          DistribExecComp(
                              ['y1 = 28 - 0.2*y2', 'y1 = 18 - 0.2*y2'],
                              arr_size=2),
                          promotes=['y1', 'y2'])
        sub.add_subsystem('d2',
                          DistribExecComp(
                              ['y2 = y1**.5 + 7', 'y2 = y1**.5 - 3'],
                              arr_size=2),
                          promotes=['y1', 'y2'])

        sub.nonlinear_solver = om.BroydenSolver()
        sub.linear_solver = om.LinearBlockGS()
        model.linear_solver = om.LinearBlockGS()

        prob.setup(check=False, force_alloc_complex=True)

        with self.assertRaises(Exception) as cm:
            prob.run_model()

        self.assertEqual(
            str(cm.exception),
            "Group (sub) has a BroydenSolver solver and contains a distributed system."
        )
示例#4
0
    def test_circuit_options(self):
        import openmdao.api as om
        from openmdao.test_suite.scripts.circuit_analysis import Circuit

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

        model.add_subsystem('circuit', Circuit(), promotes_inputs=[('Vg', 'V'), ('I_in', 'I')])
        model.set_input_defaults('V', 0., units='V')
        model.set_input_defaults('I', 0.1, units='A')

        p.setup()

        # Replace existing solver with BroydenSolver
        model.circuit.nonlinear_solver = om.BroydenSolver()
        model.circuit.nonlinear_solver.options['maxiter'] = 20
        model.circuit.nonlinear_solver.options['converge_limit'] = 0.1
        model.circuit.nonlinear_solver.options['max_converge_failures'] = 1

        # Specify states for Broyden to solve
        model.circuit.nonlinear_solver.options['state_vars'] = ['n1.V', 'n2.V']

        # set some initial guesses
        p.set_val('circuit.n1.V', 10.)
        p.set_val('circuit.n2.V', 1.)

        p.set_solver_print(level=2)
        p.run_model()

        assert_near_equal(p.get_val('circuit.n1.V'), 9.90804735, 1e-5)
        assert_near_equal(p.get_val('circuit.n2.V'), 0.71278226, 1e-5)

        # sanity check: should sum to .1 Amps
        assert_near_equal(p.get_val('circuit.R1.I') + p.get_val('circuit.D1.I'), .1, 1e-6)
    def test_feature_stall_detection_broyden(self):
        import openmdao.api as om

        prob = om.Problem()

        prob.model.add_subsystem('comp',
                                 om.ExecComp('y=3*x+1'),
                                 promotes=['*'])

        balance = prob.model.add_subsystem('balance',
                                           om.BalanceComp(),
                                           promotes=['*'])
        balance.add_balance('x', lower=-.1, upper=10, rhs_val=0, lhs_name='y')

        nl_solver = prob.model.nonlinear_solver = om.BroydenSolver()
        nl_solver.options['stall_limit'] = 3
        nl_solver.options['stall_tol'] = 1e-8
        nl_solver.options['maxiter'] = 100

        prob.model.linear_solver = om.DirectSolver()

        prob.setup()
        prob.set_solver_print()

        prob.run_model()
示例#6
0
    def test_circuit_full(self):
        import openmdao.api as om
        from openmdao.test_suite.scripts.circuit_analysis import Circuit

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

        model.add_subsystem('ground', om.IndepVarComp('V', 0., units='V'))
        model.add_subsystem('source', om.IndepVarComp('I', 0.1, units='A'))
        model.add_subsystem('circuit', Circuit())

        model.connect('source.I', 'circuit.I_in')
        model.connect('ground.V', 'circuit.Vg')

        p.setup()

        # Replace existing solver with BroydenSolver
        model.circuit.nonlinear_solver = om.BroydenSolver()
        model.circuit.nonlinear_solver.options['maxiter'] = 20
        model.circuit.nonlinear_solver.linear_solver = om.DirectSolver()

        # set some initial guesses
        p['circuit.n1.V'] = 10.
        p['circuit.n2.V'] = 1.

        p.set_solver_print(level=2)
        p.run_model()

        assert_rel_error(self, p['circuit.n1.V'], 9.90804735, 1e-5)
        assert_rel_error(self, p['circuit.n2.V'], 0.71278226, 1e-5)

        # sanity check: should sum to .1 Amps
        assert_rel_error(self, p['circuit.R1.I'] + p['circuit.D1.I'], .1, 1e-6)
示例#7
0
    def test_mixed_jacobian(self):
        # Testing Broyden on a 5 state case split among 3 vars.

        prob = om.Problem()
        model = prob.model

        model.add_subsystem('p1', om.IndepVarComp('c', 0.01))
        model.add_subsystem('mixed', MixedEquation())

        model.connect('p1.c', 'mixed.c')

        model.nonlinear_solver = om.BroydenSolver()
        model.nonlinear_solver.options['state_vars'] = [
            'mixed.x12', 'mixed.x3', 'mixed.x45'
        ]
        model.nonlinear_solver.options['maxiter'] = 15
        model.nonlinear_solver.linear_solver = om.DirectSolver()

        prob.setup()

        prob.run_model()

        assert_rel_error(self, prob['mixed.x12'], np.zeros((2, )), 1e-6)
        assert_rel_error(self, prob['mixed.x3'], 0.0, 1e-6)
        assert_rel_error(self, prob['mixed.x45'], np.zeros((2, )), 1e-6)

        # Normally takes about 13 iters, but takes around 4 if you calculate an initial
        # Jacobian.
        self.assertTrue(model.nonlinear_solver._iter_count < 6)
示例#8
0
    def test_distributed_comp_states(self):
        prob = om.Problem()
        model = prob.model
        sub = model.add_subsystem('sub', om.Group(), promotes=['*'])

        sub.add_subsystem('d1',
                          DistribExecComp(
                              ['y1 = 28 - 0.2*y2', 'y1 = 18 - 0.2*y2'],
                              arr_size=2),
                          promotes=['y1', 'y2'])
        sub.add_subsystem('d2',
                          DistribExecComp(
                              ['y2 = y1**.5 + 7', 'y2 = y1**.5 - 3'],
                              arr_size=2),
                          promotes=['y1', 'y2'])

        sub.nonlinear_solver = om.BroydenSolver(state_vars=['y1', 'y2'])
        sub.linear_solver = om.DirectSolver()
        model.linear_solver = om.DirectSolver()

        prob.setup(check=False, force_alloc_complex=True)
        prob.set_solver_print(level=2)

        prob.run_model()

        # TODO - prob.get not working correctly on distributed vars. Once this is fixed, we can
        # test all values on all ranks.
        if model.comm.rank == 0:
            assert_rel_error(self, prob.get_val('y1', get_remote=True),
                             25.58830237, .00001)
        elif model.comm.rank == 1:
            assert_rel_error(self, prob.get_val('y1', get_remote=True),
                             17.75721382, .00001)
示例#9
0
    def test_mixed_promoted_vars(self):
        # Testing Broyden on a 5 state case split among 3 vars.

        prob = om.Problem()
        model = prob.model

        model.add_subsystem('p1', om.IndepVarComp('c', 0.01))
        model.add_subsystem('mixed',
                            MixedEquation(),
                            promotes_outputs=['x12', 'x3', 'x45'])

        model.connect('p1.c', 'mixed.c')

        model.nonlinear_solver = om.BroydenSolver()
        model.nonlinear_solver.options['state_vars'] = ['x12', 'x3', 'x45']
        model.nonlinear_solver.options['maxiter'] = 15
        model.nonlinear_solver.options['compute_jacobian'] = False

        prob.setup()

        prob.run_model()

        assert_rel_error(self, prob['x12'], np.zeros((2, )), 1e-6)
        assert_rel_error(self, prob['x3'], 0.0, 1e-6)
        assert_rel_error(self, prob['x45'], np.zeros((2, )), 1e-6)
示例#10
0
    def test_jacobian_update_diverge_limit(self):
        # This model needs jacobian updates to converge.

        prob = om.Problem()
        model = prob.model

        model.add_subsystem('p1', om.IndepVarComp('x', np.array([0, 20.0])))
        model.add_subsystem('comp', SpedicatoHuang())

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

        model.nonlinear_solver = om.BroydenSolver()
        model.nonlinear_solver.options['state_vars'] = ['comp.y']
        model.nonlinear_solver.options['maxiter'] = 20
        model.nonlinear_solver.options['diverge_limit'] = 0.5
        model.nonlinear_solver.linear_solver = om.DirectSolver()

        prob.setup()

        prob.set_solver_print(level=2)
        prob.run_model()

        assert_rel_error(self, prob['comp.y'],
                         np.array([-36.26230985, 10.20857237, -54.17658612]),
                         1e-6)
示例#11
0
    def test_backtracking(self):
        top = om.Problem()
        top.model.add_subsystem('px', om.IndepVarComp('x', 1.0))
        top.model.add_subsystem('comp', ImplCompTwoStates())
        top.model.connect('px.x', 'comp.x')

        top.model.nonlinear_solver = om.BroydenSolver()
        top.model.nonlinear_solver.options['maxiter'] = 25
        top.model.nonlinear_solver.options['diverge_limit'] = 0.5
        top.model.nonlinear_solver.options['state_vars'] = ['comp.y', 'comp.z']

        top.model.linear_solver = om.DirectSolver()

        top.setup()
        top.model.nonlinear_solver.linesearch = om.BoundsEnforceLS(
            bound_enforcement='vector')

        # Setup again because we assigned a new linesearch
        top.setup()

        top.set_solver_print(level=2)
        # Test lower bound: should go to the lower bound and stall
        top['px.x'] = 2.0
        top['comp.y'] = 0.0
        top['comp.z'] = 1.6
        top.run_model()
        assert_rel_error(self, top['comp.z'], 1.5, 1e-8)

        # Test upper bound: should go to the upper bound and stall
        top['px.x'] = 0.5
        top['comp.y'] = 0.0
        top['comp.z'] = 2.4
        top.run_model()
        assert_rel_error(self, top['comp.z'], 2.5, 1e-8)
示例#12
0
    def test_circuit_full(self):

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

        model.add_subsystem('circuit',
                            Circuit(),
                            promotes_inputs=[('Vg', 'V'), ('I_in', 'I')])
        model.set_input_defaults('V', 0., units='V')
        model.set_input_defaults('I', 0.1, units='A')

        p.setup()

        # Replace existing solver with BroydenSolver
        model.circuit.nonlinear_solver = om.BroydenSolver()
        model.circuit.nonlinear_solver.options['maxiter'] = 20
        model.circuit.nonlinear_solver.linear_solver = om.DirectSolver()

        # set some initial guesses
        p.set_val('circuit.n1.V', 10.)
        p.set_val('circuit.n2.V', 1.)

        p.set_solver_print(level=2)
        p.run_model()

        assert_near_equal(p.get_val('circuit.n1.V'), 9.90804735, 1e-5)
        assert_near_equal(p.get_val('circuit.n2.V'), 0.71278226, 1e-5)

        # sanity check: should sum to .1 Amps
        assert_near_equal(
            p.get_val('circuit.R1.I') + p.get_val('circuit.D1.I'), .1, 1e-6)
示例#13
0
    def test_missing_state_warning(self):
        # Testing Broyden on a 5 state case split among 3 vars.

        prob = om.Problem()
        model = prob.model

        model.add_subsystem('p1', om.IndepVarComp('c', 0.01))
        model.add_subsystem('mixed', MixedEquation())

        model.connect('p1.c', 'mixed.c')

        model.nonlinear_solver = om.BroydenSolver()
        model.nonlinear_solver.options['state_vars'] = ['mixed.x12']
        model.nonlinear_solver.options['maxiter'] = 15
        model.nonlinear_solver.options['compute_jacobian'] = False

        prob.setup()

        msg = "The following states are not covered by a solver, and may have been " \
              "omitted from the BroydenSolver 'state_vars': mixed.x3, mixed.x45"

        with assert_warning(UserWarning, msg):
            prob.run_model()

        # Try again with promoted names.
        prob = om.Problem()
        model = prob.model

        model.add_subsystem('p1', om.IndepVarComp('c', 0.01))
        model.add_subsystem('mixed', MixedEquation(), promotes=['*'])

        model.connect('p1.c', 'c')

        model.nonlinear_solver = om.BroydenSolver()
        model.nonlinear_solver.options['state_vars'] = ['x12']
        model.nonlinear_solver.options['maxiter'] = 15
        model.nonlinear_solver.options['compute_jacobian'] = False

        prob.setup()

        msg = "The following states are not covered by a solver, and may have been " \
              "omitted from the BroydenSolver 'state_vars': x3, x45"

        with assert_warning(UserWarning, msg):
            prob.run_model()
示例#14
0
    def test_cs_around_broyden_linesearch(self):
        prob = om.Problem()
        model = prob.model
        sub = model.add_subsystem('sub', om.ParallelGroup(), promotes=['*'])

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

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

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

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

        sub.nonlinear_solver = om.BroydenSolver()
        sub.nonlinear_solver.linesearch = om.BoundsEnforceLS(
            bound_enforcement='vector')
        sub.linear_solver = om.DirectSolver()
        model.linear_solver = om.DirectSolver()

        prob.model.add_design_var('x', lower=-100, upper=100)
        prob.model.add_design_var('z', lower=-100, upper=100)
        prob.model.add_objective('obj')
        prob.model.add_constraint('con1', upper=0.0)
        prob.model.add_constraint('con2', upper=0.0)

        prob.setup(check=False, force_alloc_complex=True)
        prob.set_solver_print(level=2)

        prob.run_model()

        assert_rel_error(self, prob.get_val('y1', get_remote=True),
                         25.58830237, .00001)

        totals = prob.check_totals(method='cs', out_stream=None)

        for key, val in iteritems(totals):
            assert_rel_error(self, val['rel error'][0], 0.0, 1e-6)
示例#15
0
    def test_cs_around_broyden_compute_jac_dense(self):
        # Basic sellar test.

        prob = om.Problem()
        model = prob.model
        sub = model.add_subsystem('sub', om.Group(), promotes=['*'])

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

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

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

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

        sub.nonlinear_solver = om.BroydenSolver()
        sub.linear_solver = om.DirectSolver()
        model.linear_solver = om.DirectSolver()

        prob.model.add_design_var('x', lower=-100, upper=100)
        prob.model.add_design_var('z', lower=-100, upper=100)
        prob.model.add_objective('obj')
        prob.model.add_constraint('con1', upper=0.0)
        prob.model.add_constraint('con2', upper=0.0)

        prob.setup(check=False, force_alloc_complex=True)
        prob.set_solver_print(level=0)

        prob.run_model()

        sub.nonlinear_solver.options['compute_jacobian'] = True

        totals = prob.check_totals(method='cs', out_stream=None)

        for key, val in iteritems(totals):
            assert_rel_error(self, val['rel error'][0], 0.0, 1e-6)
    def test_broyden(self):
        p = om.Problem()

        comp = p.model.add_subsystem('comp', QuadraticComp())
        comp.nonlinear_solver = om.BroydenSolver()
        comp.linear_solver = om.DirectSolver()

        p.setup(force_alloc_complex=True)
        p.run_model()

        partials = p.check_partials(includes=['comp'],
                                    method='cs',
                                    out_stream=None)
        assert_check_partials(partials)
示例#17
0
    def test_error_need_direct_solver(self):
        # Test top level Sellar (i.e., not grouped).

        prob = om.Problem()
        model = prob.model = SellarStateConnection(nonlinear_solver=om.BroydenSolver(),
                                                   linear_solver=om.LinearRunOnce())

        prob.setup()

        with self.assertRaises(ValueError) as context:
            prob.run_model()

        msg = "BroydenSolver in SellarStateConnection (<model>): Linear solver must be DirectSolver when solving the full model."
        self.assertEqual(str(context.exception), msg)
示例#18
0
    def test_linsearch_3_deprecation(self):
        prob = om.Problem()
        model = prob.model = SellarStateConnection(
            nonlinear_solver=om.BroydenSolver(),
            linear_solver=om.LinearRunOnce())
        prob.setup()

        model.nonlinear_solver.options['state_vars'] = ['state_eq.y2_command']
        model.nonlinear_solver.options['compute_jacobian'] = False

        msg = 'Deprecation warning: In V 3.0, the default Broyden solver setup will change ' + \
              'to use the BoundsEnforceLS line search.'

        with assert_warning(DeprecationWarning, msg):
            prob.final_setup()
示例#19
0
    def test_error_badname(self):
        # Test top level Sellar (i.e., not grouped).

        prob = om.Problem()
        model = prob.model = SellarStateConnection(nonlinear_solver=om.BroydenSolver(),
                                                   linear_solver=om.LinearRunOnce())

        prob.setup()

        model.nonlinear_solver.options['state_vars'] = ['junk']

        with self.assertRaises(ValueError) as context:
            prob.run_model()

        msg = "BroydenSolver in SellarStateConnection (<model>): The following variable names were not found: junk"
        self.assertEqual(str(context.exception), msg)
示例#20
0
    def test_simple_sellar(self):
        # Test top level Sellar (i.e., not grouped).

        prob = om.Problem()
        model = prob.model = SellarStateConnection(nonlinear_solver=om.BroydenSolver(),
                                                   linear_solver=om.LinearRunOnce())

        prob.setup()

        model.nonlinear_solver.options['state_vars'] = ['state_eq.y2_command']
        model.nonlinear_solver.options['compute_jacobian'] = False

        prob.run_model()

        assert_near_equal(prob['y1'], 25.58830273, .00001)
        assert_near_equal(prob['state_eq.y2_command'], 12.05848819, .00001)
示例#21
0
    def test_simple_sellar_cycle(self):
        # Test top level Sellar (i.e., not grouped).

        prob = om.Problem()
        model = prob.model = SellarDerivatives(nonlinear_solver=om.BroydenSolver(),
                                               linear_solver=om.LinearRunOnce())

        prob.setup()

        model.nonlinear_solver.options['state_vars'] = ['y1']
        model.nonlinear_solver.options['compute_jacobian'] = True

        prob.set_solver_print(level=2)

        prob.run_model()

        assert_near_equal(prob['y1'], 25.58830273, .00001)
        assert_near_equal(prob['y2'], 12.05848819, .00001)
示例#22
0
    def test_sellar(self):
        import openmdao.api as om
        from openmdao.test_suite.components.sellar import SellarStateConnection

        prob = om.Problem()
        model = prob.model = SellarStateConnection(nonlinear_solver=om.BroydenSolver(),
                                                   linear_solver=om.LinearRunOnce())

        prob.setup()

        model.nonlinear_solver.options['state_vars'] = ['state_eq.y2_command']
        model.nonlinear_solver.options['compute_jacobian'] = False

        prob.set_solver_print(level=2)
        prob.run_model()

        assert_near_equal(prob['y1'], 25.58830273, .00001)
        assert_near_equal(prob['state_eq.y2_command'], 12.05848819, .00001)
示例#23
0
    def test_simple_sellar_full_jacobian(self):
        # Test top level Sellar (i.e., not grouped).

        prob = om.Problem()
        model = prob.model = SellarStateConnection(nonlinear_solver=om.BroydenSolver(),
                                                   linear_solver=om.LinearRunOnce())

        prob.setup()

        model.nonlinear_solver.linear_solver = om.DirectSolver()

        prob.run_model()

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

        # Normally takes about 5 iters, but takes around 4 if you calculate an initial
        # Jacobian.
        self.assertTrue(model.nonlinear_solver._iter_count < 5)
示例#24
0
    def test_simple_sellar_jacobian_assembled_dense(self):
        # Test top level Sellar (i.e., not grouped).

        prob = om.Problem()
        model = prob.model = SellarStateConnection(nonlinear_solver=om.BroydenSolver(),
                                                   linear_solver=om.LinearRunOnce())

        prob.setup()

        model.options['assembled_jac_type'] = 'dense'
        model.nonlinear_solver.linear_solver = om.DirectSolver(assemble_jac=True)

        prob.run_model()

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

        # Normally takes about 4 iters, but takes around 3 if you calculate an initial
        # Jacobian.
        self.assertTrue(model.nonlinear_solver._iter_count < 4)
示例#25
0
    def test_sellar_state_connection_fd_system(self):
        # Sellar model closes loop with state connection instead of a cycle.
        # This test is just fd.
        prob = om.Problem()
        model = prob.model = SellarStateConnection(nonlinear_solver=om.BroydenSolver(),
                                                   linear_solver=om.LinearRunOnce())
        prob.model.approx_totals(method='fd')

        prob.setup()

        model.nonlinear_solver.options['state_vars'] = ['state_eq.y2_command']
        model.nonlinear_solver.options['compute_jacobian'] = False

        prob.run_model()

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

        # Make sure we aren't iterating like crazy
        self.assertLess(prob.model.nonlinear_solver._iter_count, 6)
示例#26
0
    def test_vector(self):
        # Testing Broyden on a 5 state single vector case.

        prob = om.Problem()
        model = prob.model

        model.add_subsystem('p1', om.IndepVarComp('c', 0.01))
        model.add_subsystem('vec', VectorEquation())

        model.connect('p1.c', 'vec.c')

        model.nonlinear_solver = om.BroydenSolver()
        model.nonlinear_solver.options['state_vars'] = ['vec.x']
        model.nonlinear_solver.options['maxiter'] = 15
        model.nonlinear_solver.options['compute_jacobian'] = False

        prob.setup()

        prob.run_model()

        assert_rel_error(self, prob['vec.x'], np.zeros((5, )), 1e-6)
示例#27
0
    def test_distributed_comp(self):
        prob = om.Problem()
        model = prob.model
        sub = model.add_subsystem('sub', om.Group(), promotes=['*'])

        sub.add_subsystem('d1', DistribExecComp(['y1 = 28 - 0.2*y2', 'y1 = 18 - 0.2*y2'], arr_size=2),
                          promotes=['y1', 'y2'])
        sub.add_subsystem('d2', DistribExecComp(['y2 = y1**.5 + 7', 'y2 = y1**.5 - 3'], arr_size=2),
                          promotes=['y1', 'y2'])

        sub.nonlinear_solver = om.BroydenSolver()
        sub.linear_solver = om.LinearBlockGS()
        model.linear_solver = om.LinearBlockGS()

        prob.setup(check=False, force_alloc_complex=True)

        with self.assertRaises(Exception) as cm:
            prob.run_model()

        msg = "BroydenSolver linear solver in Group (sub) cannot be used in or above a ParallelGroup or a " + \
            "distributed component."
        self.assertEqual(str(cm.exception), msg)
示例#28
0
    def test_circuit_options(self):
        import openmdao.api as om
        from openmdao.test_suite.scripts.circuit_analysis import Circuit

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

        model.add_subsystem('ground', om.IndepVarComp('V', 0., units='V'))
        model.add_subsystem('source', om.IndepVarComp('I', 0.1, units='A'))
        model.add_subsystem('circuit', Circuit())

        model.connect('source.I', 'circuit.I_in')
        model.connect('ground.V', 'circuit.Vg')

        p.setup()

        # Replace existing solver with BroydenSolver
        model.circuit.nonlinear_solver = om.BroydenSolver()
        model.circuit.nonlinear_solver.options['maxiter'] = 20
        model.circuit.nonlinear_solver.options['converge_limit'] = 0.1
        model.circuit.nonlinear_solver.options['max_converge_failures'] = 1

        # Specify states for Broyden to solve
        model.circuit.nonlinear_solver.options['state_vars'] = ['n1.V', 'n2.V']

        # set some initial guesses
        p['circuit.n1.V'] = 10.
        p['circuit.n2.V'] = 1.

        p.set_solver_print(level=2)
        p.run_model()

        assert_near_equal(p['circuit.n1.V'], 9.90804735, 1e-5)
        assert_near_equal(p['circuit.n2.V'], 0.71278226, 1e-5)

        # sanity check: should sum to .1 Amps
        assert_near_equal(p['circuit.R1.I'] + p['circuit.D1.I'], .1, 1e-6)
    solver_flag = 'newton'

    if solver_flag == 'newton':
        prob.model.nonlinear_solver = om.NewtonSolver(iprint=2)
        # solve_subsystems should almost always be turned on
        # it improves solver robustness
        prob.model.nonlinear_solver.options['solve_subsystems'] = True
        prob.model.nonlinear_solver.options['maxiter'] = 100
        # these options control how tightly the solver converges the system
        prob.model.nonlinear_solver.options['atol'] = 1e-8
        prob.model.nonlinear_solver.options['rtol'] = 1e-8
        # the Newton solver requires a linear solver
        prob.model.linear_solver = om.DirectSolver()

    elif solver_flag == 'broyden':
        prob.model.nonlinear_solver = om.BroydenSolver(iprint=2)
        # TODO: Try using broyden with and without a computed jacobian. What happens?
        prob.model.nonlinear_solver.options['compute_jacobian'] = True
        prob.model.nonlinear_solver.options['maxiter'] = 100
        # these options control how tightly the solver converges the system
        prob.model.nonlinear_solver.options['atol'] = 1e-8
        prob.model.nonlinear_solver.options['rtol'] = 1e-8
        # the Broyden solver requires a linear solver *if* options['compute_jacobian'] = True
        prob.model.linear_solver = om.DirectSolver()

    elif solver_flag == 'nlbgs':
        # The nonlinear block Gauss-Seidel solver is an iterative solvver
        # Requires no linear solver and works even without derivatives
        prob.model.nonlinear_solver = om.NonlinearBlockGS(iprint=2)
        prob.model.nonlinear_solver.options['maxiter'] = 400
        prob.model.nonlinear_solver.options['atol'] = 1e-8