示例#1
0
    def test_linesearch_vector_bound_enforcement(self):
        top = self.top

        ls = top.model.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS(
            bound_enforcement='vector')
        ls.options['c'] = .1

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

        # Test lower bounds: should go to the lower bound and stall
        top['px.x'] = 2.0
        top['comp.y'] = 0.
        top['comp.z'] = 1.6
        top.run_model()
        for ind in range(3):
            assert_rel_error(self, top['comp.z'][ind], [1.5], 1e-8)

        # Test upper bounds: should go to the minimum upper bound and stall
        top['px.x'] = 0.5
        top['comp.y'] = 0.
        top['comp.z'] = 2.4
        top.run_model()
        for ind in range(3):
            assert_rel_error(self, top['comp.z'][ind], [2.5], 1e-8)
示例#2
0
    def test_with_subsolves(self):

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

        g1 = model.g1
        g1.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)
        g1.nonlinear_solver.options['rtol'] = 1.0e-5
        g1.linear_solver = om.DirectSolver()

        g2 = model.g2
        g2.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)
        g2.nonlinear_solver.options['rtol'] = 1.0e-5
        g2.linear_solver = om.DirectSolver()

        model.nonlinear_solver = om.NewtonSolver()
        model.linear_solver = om.ScipyKrylov()

        model.nonlinear_solver.options['solve_subsystems'] = True
        model.nonlinear_solver.options['max_sub_solves'] = 4
        ls = model.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS(
            bound_enforcement='vector')

        prob.set_solver_print(level=0)

        prob.setup()
        prob.run_model()

        assert_near_equal(prob['g1.y1'], 0.64, .00001)
        assert_near_equal(prob['g1.y2'], 0.80, .00001)
        assert_near_equal(prob['g2.y1'], 0.64, .00001)
        assert_near_equal(prob['g2.y2'], 0.80, .00001)
    def test_circuit_voltage_source(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'))

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

        model.add_subsystem('circuit', Circuit())
        model.add_subsystem('batt_deltaV', om.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 = om.NonlinearRunOnce()
        p.model.circuit.linear_solver = om.LinearRunOnce()

        # Put Newton at the top so it can also converge the new BalanceComp residual
        newton = p.model.nonlinear_solver = om.NewtonSolver()
        p.model.linear_solver = om.DirectSolver()
        newton.options['iprint'] = 2
        newton.options['maxiter'] = 20
        newton.options['solve_subsystems'] = True
        newton.linesearch = om.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_near_equal(p['circuit.n1.V'], 1.5, 1e-5)
        assert_near_equal(p['circuit.n2.V'], 0.65113362, 1e-5)
        assert_near_equal(p['circuit.R1.I'], 0.015, 1e-5)
        assert_near_equal(p['circuit.R2.I'], 8.48866375e-05, 1e-5)
        assert_near_equal(p['circuit.D1.I'], 8.48866375e-05, 1e-5)
示例#4
0
    def setup(self):
        self.add_subsystem('n1',
                           Node(n_in=1, n_out=2),
                           promotes_inputs=[('I_in:0', 'I_in')])
        self.add_subsystem('n2', Node())  # leaving defaults

        self.add_subsystem('R1',
                           Resistor(R=100.),
                           promotes_inputs=[('V_out', 'Vg')])
        self.add_subsystem('R2', Resistor(R=10000.))
        self.add_subsystem('D1', Diode(), promotes_inputs=[('V_out', 'Vg')])

        self.connect('n1.V', ['R1.V_in', 'R2.V_in'])
        self.connect('R1.I', 'n1.I_out:0')
        self.connect('R2.I', 'n1.I_out:1')

        self.connect('n2.V', ['R2.V_out', 'D1.V_in'])
        self.connect('R2.I', 'n2.I_in:0')
        self.connect('D1.I', 'n2.I_out:0')

        self.nonlinear_solver = om.NewtonSolver()
        self.linear_solver = om.DirectSolver()

        self.nonlinear_solver.options['iprint'] = 2
        self.nonlinear_solver.options['maxiter'] = 10
        self.nonlinear_solver.options['solve_subsystems'] = True
        self.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS()
        self.nonlinear_solver.linesearch.options['maxiter'] = 10
        self.nonlinear_solver.linesearch.options['iprint'] = 2
示例#5
0
    def test_feature_armijo_print_bound_enforce(self):
        import numpy as np

        import openmdao.api as om
        from openmdao.test_suite.components.implicit_newton_linesearch import ImplCompTwoStatesArrays

        top = om.Problem()
        top.model.add_subsystem('px', om.IndepVarComp('x', np.ones((3, 1))))
        top.model.add_subsystem('comp', ImplCompTwoStatesArrays())
        top.model.connect('px.x', 'comp.x')

        newt = top.model.nonlinear_solver = om.NewtonSolver(
            solve_subsystems=False)
        top.model.nonlinear_solver.options['maxiter'] = 2
        top.model.linear_solver = om.ScipyKrylov()

        ls = newt.linesearch = om.ArmijoGoldsteinLS()
        ls.options['print_bound_enforce'] = True

        top.set_solver_print(level=2)
        top.setup()

        # Test lower bounds: should go to the lower bound and stall
        top['px.x'] = 2.0
        top['comp.y'] = 0.
        top['comp.z'] = 1.6
        top.run_model()

        for ind in range(3):
            assert_near_equal(top['comp.z'][ind], [1.5], 1e-8)
示例#6
0
    def test_feature_armijo_boundscheck_scalar(self):
        import numpy as np

        import openmdao.api as om
        from openmdao.test_suite.components.implicit_newton_linesearch import ImplCompTwoStatesArrays

        top = om.Problem()
        top.model.add_subsystem('px', om.IndepVarComp('x', np.ones((3, 1))))
        top.model.add_subsystem('comp', ImplCompTwoStatesArrays())
        top.model.connect('px.x', 'comp.x')

        top.model.nonlinear_solver = om.NewtonSolver()
        top.model.nonlinear_solver.options['maxiter'] = 10
        top.model.linear_solver = om.ScipyKrylov()

        ls = top.model.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS(
            bound_enforcement='scalar')

        top.setup()
        top.run_model()

        # Test lower bounds: should stop just short of the lower bound
        top['px.x'] = 2.0
        top['comp.y'] = 0.
        top['comp.z'] = 1.6
        top.run_model()
示例#7
0
    def test_feature_armijo_boundscheck_wall(self):
        import numpy as np

        import openmdao.api as om
        from openmdao.test_suite.components.implicit_newton_linesearch import ImplCompTwoStatesArrays

        top = om.Problem()
        top.model.add_subsystem('comp',
                                ImplCompTwoStatesArrays(),
                                promotes_inputs=['x'])

        top.model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)
        top.model.nonlinear_solver.options['maxiter'] = 10
        top.model.linear_solver = om.ScipyKrylov()

        top.model.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS(
            bound_enforcement='wall')

        top.setup()

        top.set_val('x', np.array([0.5, 0.5, 0.5]).reshape(3, 1))

        # Test upper bounds: should go to the upper bound and stall
        top.set_val('comp.y', 0.)
        top.set_val('comp.z', 2.4)
        top.run_model()

        assert_near_equal(top.get_val('comp.z', indices=0), [2.6], 1e-8)
        assert_near_equal(top.get_val('comp.z', indices=1), [2.5], 1e-8)
        assert_near_equal(top.get_val('comp.z', indices=2), [2.65], 1e-8)
示例#8
0
    def test_feature_armijo_boundscheck_scalar(self):
        import numpy as np

        import openmdao.api as om
        from openmdao.test_suite.components.implicit_newton_linesearch import ImplCompTwoStatesArrays

        top = om.Problem()
        top.model.add_subsystem('comp',
                                ImplCompTwoStatesArrays(),
                                promotes_inputs=['x'])

        top.model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)
        top.model.nonlinear_solver.options['maxiter'] = 10
        top.model.linear_solver = om.ScipyKrylov()

        ls = top.model.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS(
            bound_enforcement='scalar')

        top.setup()
        top.set_val('x', np.array([2., 2, 2]).reshape(3, 1))
        top.run_model()

        # Test lower bounds: should stop just short of the lower bound
        top.set_val('comp.y', 0.)
        top.set_val('comp.z', 1.6)
        top.run_model()
示例#9
0
    def test_feature_armijo_boundscheck_vector(self):

        top = om.Problem()
        top.model.add_subsystem('comp',
                                ImplCompTwoStatesArrays(),
                                promotes_inputs=['x'])

        top.model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)
        top.model.nonlinear_solver.options['maxiter'] = 10
        top.model.linear_solver = om.ScipyKrylov()

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

        top.setup()

        top.set_val('x', np.array([2., 2, 2]).reshape(3, 1))

        # Test lower bounds: should go to the lower bound and stall
        top.set_val('comp.y', 0.)
        top.set_val('comp.z', 1.6)
        top.run_model()

        for ind in range(3):
            assert_near_equal(top.get_val('comp.z', indices=ind), [1.5], 1e-8)
示例#10
0
    def test_feature_goldstein(self):

        top = om.Problem()
        top.model.add_subsystem('px', om.IndepVarComp('x', np.ones((3, 1))))
        top.model.add_subsystem('comp', ImplCompTwoStatesArrays())
        top.model.connect('px.x', 'comp.x')

        top.model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)
        top.model.nonlinear_solver.options['maxiter'] = 10
        top.model.linear_solver = om.ScipyKrylov()

        ls = top.model.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS(
            bound_enforcement='vector')
        ls.options['method'] = 'Goldstein'

        top.setup()

        # Test lower bounds: should go to the lower bound and stall
        top['px.x'] = 2.0
        top['comp.y'] = 0.
        top['comp.z'] = 1.6
        top.run_model()

        for ind in range(3):
            assert_near_equal(top['comp.z'][ind], [1.5], 1e-8)
示例#11
0
    def test_with_subsolves(self):
        prob = om.Problem()
        model = prob.model = DoubleSellar()

        g1 = model.g1
        g1.nonlinear_solver = om.NewtonSolver()
        g1.nonlinear_solver.options['rtol'] = 1.0e-5
        g1.linear_solver = om.DirectSolver()

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

        model.nonlinear_solver = om.NewtonSolver()
        model.linear_solver = om.ScipyKrylov()

        model.nonlinear_solver.options['solve_subsystems'] = True
        model.nonlinear_solver.options['max_sub_solves'] = 4
        ls = model.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS(
            bound_enforcement='vector')

        # This is pretty bogus, but it ensures that we get a few LS iterations.
        ls.options['c'] = 100.0  # FIXME c should be 0 <= c <= 1

        prob.set_solver_print(level=0)

        prob.setup()
        prob.run_model()

        assert_rel_error(self, prob['g1.y1'], 0.64, .00001)
        assert_rel_error(self, prob['g1.y2'], 0.80, .00001)
        assert_rel_error(self, prob['g2.y1'], 0.64, .00001)
        assert_rel_error(self, prob['g2.y2'], 0.80, .00001)
示例#12
0
    def test_feature_armijogoldsteinls_basic(self):
        import numpy as np

        import openmdao.api as om
        from openmdao.test_suite.components.implicit_newton_linesearch import ImplCompTwoStatesArrays

        top = om.Problem()
        top.model.add_subsystem('comp',
                                ImplCompTwoStatesArrays(),
                                promotes_inputs=['x'])

        top.model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)
        top.model.nonlinear_solver.options['maxiter'] = 10
        top.model.linear_solver = om.ScipyKrylov()

        top.model.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS()

        top.setup()
        top.set_val('x', np.array([2., 2, 2]).reshape(3, 1))
        # Test lower bounds: should go to the lower bound and stall
        top.set_val('comp.y', 0.)
        top.set_val('comp.z', 1.6)
        top.run_model()

        for ind in range(3):
            assert_near_equal(top.get_val('comp.z', indices=ind), [1.5], 1e-8)
示例#13
0
    def test_feature_armijogoldsteinls_basic(self):
        import numpy as np

        import openmdao.api as om
        from openmdao.test_suite.components.implicit_newton_linesearch import ImplCompTwoStatesArrays

        top = om.Problem()
        top.model.add_subsystem('px', om.IndepVarComp('x', np.ones((3, 1))))
        top.model.add_subsystem('comp', ImplCompTwoStatesArrays())
        top.model.connect('px.x', 'comp.x')

        top.model.nonlinear_solver = om.NewtonSolver()
        top.model.nonlinear_solver.options['maxiter'] = 10
        top.model.linear_solver = om.ScipyKrylov()

        top.model.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS()

        top.setup()

        # Test lower bounds: should go to the lower bound and stall
        top['px.x'] = 2.0
        top['comp.y'] = 0.
        top['comp.z'] = 1.6
        top.run_model()

        for ind in range(3):
            assert_rel_error(self, top['comp.z'][ind], [1.5], 1e-8)
示例#14
0
    def test_linesearch_bounds_scalar(self):
        top = self.top

        ls = top.model.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS(
            bound_enforcement='scalar')
        ls.options['maxiter'] = 10
        ls.options['alpha'] = 1.0

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

        # Test lower bound: should stop just short of the lower bound
        top['px.x'] = 2.0
        top['comp.y'] = 0.0
        top['comp.z'] = 1.6
        top.run_model()
        self.assertGreaterEqual(top['comp.z'], 1.5)
        self.assertLessEqual(top['comp.z'], 1.6)

        # Test lower bound: should stop just short of the upper bound
        top['px.x'] = 0.5
        top['comp.y'] = 0.0
        top['comp.z'] = 2.4
        top.run_model()
        self.assertGreaterEqual(top['comp.z'], 2.5)
        self.assertLessEqual(top['comp.z'], 2.5)
示例#15
0
    def test_feature_armijo_boundscheck_wall(self):
        import numpy as np

        import openmdao.api as om
        from openmdao.test_suite.components.implicit_newton_linesearch import ImplCompTwoStatesArrays

        top = om.Problem()
        top.model.add_subsystem('px', om.IndepVarComp('x', np.ones((3, 1))))
        top.model.add_subsystem('comp', ImplCompTwoStatesArrays())
        top.model.connect('px.x', 'comp.x')

        top.model.nonlinear_solver = om.NewtonSolver()
        top.model.nonlinear_solver.options['maxiter'] = 10
        top.model.linear_solver = om.ScipyKrylov()

        top.model.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS(
            bound_enforcement='wall')

        top.setup()

        # Test upper bounds: should go to the upper bound and stall
        top['px.x'] = 0.5
        top['comp.y'] = 0.
        top['comp.z'] = 2.4
        top.run_model()

        assert_rel_error(self, top['comp.z'][0], [2.6], 1e-8)
        assert_rel_error(self, top['comp.z'][1], [2.5], 1e-8)
        assert_rel_error(self, top['comp.z'][2], [2.65], 1e-8)
示例#16
0
    def setup(self):

        npts = self.npts
        nodes = self.nodes
        n_in = len(nodes)

        self.add_subsystem('sc',
                           SolarCell(nodes=nodes, npts=npts),
                           promotes=['*'])
        self.add_subsystem('el',
                           ElectricPower(n_in=n_in, npts=npts),
                           promotes=['*'])
        self.add_subsystem('QS',
                           QSmtxComp(nn=self.nn, nodes=nodes, npts=npts),
                           promotes=['*'])
        self.add_subsystem('temps',
                           TempsComp(n=self.nn, npts=self.npts),
                           promotes=['*'])

        self.nonlinear_solver = om.NewtonSolver(solve_subsystems=True)
        self.nonlinear_solver.options['iprint'] = 2
        self.nonlinear_solver.options['maxiter'] = 15
        self.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS()
        self.nonlinear_solver.linesearch.options['maxiter'] = 10
        self.nonlinear_solver.linesearch.options['iprint'] = 2
        self.linear_solver = om.DirectSolver()
        self.linear_solver.options['assemble_jac'] = False
示例#17
0
def thermal_link(model, l_comp, r_comp):
    l_name = l_comp
    r_name = r_comp

    b_name = '{}_bridge'.format(l_comp)
    # model.add_subsystem(name='eff_length',
    #                     subsys=om.ExecComp('L_eff = (L1+L2)/2+L_adiabatic', units='m'),
    #                     promotes_inputs=['L_adiabatic',('L1','{}.L_flux'.format(l_name,r_name)],
    #                     promotes_outputs=['L_eff'])

    model.add_subsystem(b_name, Bridge(),
                        promotes_inputs=['A_w','A_wk','D_v','R_g','mu_v','h_fg','P_v','rho_v','L_eff','k_w','k_l','epsilon','T_hp'],
                        promotes_outputs=['k_wk'])
    
    model.set_input_defaults('L_eff', val=0.045)  # TODO set higher up?
    # Link Geometry
    model.connect('{}.size.A_w'.format(l_name),'A_w') # this can come from either component
    model.connect('{}.size.A_wk'.format(l_name),'A_wk') # this can come from either component

    model.connect('{}.R_g'.format(r_name),'R_g')
    model.connect('{}.mu_v'.format(r_name),'mu_v')
    model.connect('{}.P_v'.format(r_name),'P_v')
    model.connect('{}.h_fg'.format(r_name),'h_fg')
    model.connect('{}.rho_v'.format(r_name),'rho_v')
    model.connect('{}.k_l'.format(r_name),'k_l')
    model.connect('{}.T_hp'.format(r_name),'T_hp')



    # Link thermal network
    # left node 1
    model.connect('{}.n1.T'.format(l_name),'{}.Rwa.T_in'.format(b_name))
    model.connect('{}.Rwa.q'.format(b_name),'{}.n1.q_out:1'.format(l_name))
    # left node 2
    model.connect('{}.n2.T'.format(l_name),'{}.Rwka.T_in'.format(b_name))
    model.connect('{}.Rwka.q'.format(b_name),'{}.n2.q_out:1'.format(l_name))
    # left node 4
    model.connect('{}.n4.T'.format(l_name),'{}.Rv.T_in'.format(b_name))
    model.connect('{}.Rv.q'.format(b_name),'{}.n4.q_out:0'.format(l_name))

    # right node 1
    model.connect('{}.n1.T'.format(r_name),'{}.Rwa.T_out'.format(b_name))
    model.connect('{}.Rwa.q'.format(b_name),'{}.n1.q_in:1'.format(r_name))
    # right node 2
    model.connect('{}.n2.T'.format(r_name),'{}.Rwka.T_out'.format(b_name))
    model.connect('{}.Rwka.q'.format(b_name),'{}.n2.q_in:1'.format(r_name))
    # right node 4
    model.connect('{}.n4.T'.format(r_name),'{}.Rv.T_out'.format(b_name))
    model.connect('{}.Rv.q'.format(b_name),'{}.n4.q_in:1'.format(r_name))


    model.nonlinear_solver = om.NewtonSolver(solve_subsystems=True)
    model.nonlinear_solver.options['iprint'] = 2
    model.nonlinear_solver.options['maxiter'] = 20
    model.linear_solver = om.DirectSolver()
    model.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS()
    model.nonlinear_solver.linesearch.options['maxiter'] = 10
    model.nonlinear_solver.linesearch.options['iprint'] = 2
示例#18
0
    def test_read_only_bug(self):
        # this tests for a bug in which guess_nonlinear failed due to the output
        # vector being left in a read only state after the AnalysisError

        top = om.Problem()
        top.model.add_subsystem('px', om.IndepVarComp('x', 7.0))

        sub = top.model.add_subsystem('sub', om.Group())
        sub.add_subsystem('comp', ImplCompTwoStatesAE())
        sub.upper = 20
        sub.lower = 25

        top.model.connect('px.x', 'sub.comp.x')

        top.model.nonlinear_solver = om.NewtonSolver()
        top.model.nonlinear_solver.options['maxiter'] = 2
        top.model.nonlinear_solver.options['solve_subsystems'] = True
        top.model.nonlinear_solver.linesearch = None
        top.model.linear_solver = om.ScipyKrylov()

        sub.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)
        sub.nonlinear_solver.options['maxiter'] = 2
        sub.nonlinear_solver.linesearch = None
        sub.linear_solver = om.ScipyKrylov()

        ls = top.model.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS(
            bound_enforcement='wall')
        ls.options['maxiter'] = 5
        ls.options['alpha'] = 10.0
        ls.options['retry_on_analysis_error'] = True
        ls.options['c'] = 1.0

        top.setup()
        top.set_solver_print(level=2)

        stdout = sys.stdout
        strout = StringIO()

        sys.stdout = strout
        try:
            top.run_model()
        finally:
            sys.stdout = stdout

        output = strout.getvalue().split('\n')

        correct = False
        for line in output:
            # make sure a line starting with this string is present in stdout
            if line.startswith('|  LS: AG 3'):
                correct = True
                break
        self.assertTrue(correct,
                        msg='Expected line search output not found in stdout')
示例#19
0
    def setUp(self):
        top = om.Problem()
        top.model.add_subsystem('px', om.IndepVarComp('x', 1.0))
        top.model.add_subsystem('comp', ImplCompTwoStates())
        top.model.add_subsystem('par', ParaboloidAE())
        top.model.connect('px.x', 'comp.x')
        top.model.connect('comp.z', 'par.x')

        top.model.nonlinear_solver = om.NewtonSolver()
        top.model.nonlinear_solver.options['maxiter'] = 1
        top.model.linear_solver = om.ScipyKrylov()

        ls = top.model.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS(bound_enforcement='vector')
        ls.options['maxiter'] = 10
        ls.options['alpha'] = 1.0
        top.set_solver_print(level=0)

        self.top = top
        self.ls = ls
示例#20
0
    def test_set_total_SP(self):

        #

        p = om.Problem()
        p.model = Thermo(mode='total_SP', 
                         method = 'CEA', 
                         thermo_kwargs={'composition': constants.CEA_CO2_CO_O2_COMPOSITION, 
                                        'spec': species_data.co2_co_o2 }) 
       
        r = p.model


        p.setup(check=False)

        # NOTE: This case is very touchy and requires weird solver settings
        p.model.nonlinear_solver.options['solve_subsystems'] = True
        p.model.base_thermo.chem_eq.nonlinear_solver.options['maxiter'] = 1

        p.model.base_thermo.chem_eq.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS()
        p.model.base_thermo.chem_eq.nonlinear_solver.linesearch.options['maxiter'] = 2
        
        p.set_solver_print(level=2)
        p.final_setup()

        # p.model.nonlinear_solver.options['maxiter'] = 0

        p.set_val('S', 2.35711010759, units="Btu/(lbm*degR)")
        p.set_val('P', 1.034210, units="bar")

        p.run_model()

        assert_near_equal(p['gamma'], 1.19054696779, 1e-4)

        # 1500K
        p['T'] = 4000. 

        p['S'] = 1.5852424435
        p.run_model()

        assert_near_equal(p['gamma'], 1.16396871, 1e-4)
    def test_circuit_advanced_newton(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()

        # you can change the NewtonSolver settings in circuit after setup is called
        newton = p.model.circuit.nonlinear_solver
        newton.options['iprint'] = 2
        newton.options['maxiter'] = 10
        newton.options['solve_subsystems'] = True
        newton.linesearch = om.ArmijoGoldsteinLS()
        newton.linesearch.options['maxiter'] = 10
        newton.linesearch.options['iprint'] = 2

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

        p.run_model()

        assert_rel_error(self, p['circuit.n1.V'], 9.90804735, 1e-5)
        assert_rel_error(self, p['circuit.n2.V'], 0.71278185, 1e-5)
        assert_rel_error(self, p['circuit.R1.I'], 0.09908047, 1e-5)
        assert_rel_error(self, p['circuit.R2.I'], 0.00091953, 1e-5)
        assert_rel_error(self, p['circuit.D1.I'], 0.00091953, 1e-5)

        # sanity check: should sum to .1 Amps
        assert_rel_error(self, p['circuit.R1.I'] + p['circuit.D1.I'], .1, 1e-6)
示例#22
0
    def test_bound_enforce_print_bug(self):
        # Error during print if bound was one-sided.

        class OneSidedBounds(ImplCompTwoStatesArrays):
            def setup(self):
                self.add_input('x', np.zeros((3, 1)))
                self.add_output('y', np.zeros((3, 1)))
                self.add_output('z',
                                2.0 * np.ones((3, 1)),
                                upper=np.array([2.6, 2.5, 2.65]).reshape(
                                    (3, 1)))

                self.maxiter = 10
                self.atol = 1.0e-12

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

        top = om.Problem()
        top.model.add_subsystem('px', om.IndepVarComp('x', np.ones((3, 1))))
        top.model.add_subsystem('comp', OneSidedBounds())
        top.model.connect('px.x', 'comp.x')

        newt = top.model.nonlinear_solver = om.NewtonSolver(
            solve_subsystems=False)
        top.model.nonlinear_solver.options['maxiter'] = 2
        top.model.linear_solver = om.ScipyKrylov()

        ls = newt.linesearch = om.ArmijoGoldsteinLS()
        ls.options['print_bound_enforce'] = True

        top.set_solver_print(level=2)
        top.setup()

        top['px.x'] = 2.0
        top['comp.y'] = 0.
        top['comp.z'] = 1.6

        # Should run without an exception being raised.
        top.run_model()
示例#23
0
    def test_line_search_deprecated(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.NewtonSolver()
        top.model.nonlinear_solver.options['maxiter'] = 10
        top.model.linear_solver = om.ScipyKrylov()

        msg = "The 'line_search' attribute provides backwards compatibility with OpenMDAO 1.x ; " \
              "use 'linesearch' instead."

        with assert_warning(DeprecationWarning, msg):
            top.model.nonlinear_solver.line_search = om.ArmijoGoldsteinLS(
                bound_enforcement='vector')

        with assert_warning(DeprecationWarning, msg):
            ls = top.model.nonlinear_solver.line_search

        ls.options['maxiter'] = 10
        ls.options['alpha'] = 1.0

        top.setup()

        # 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)
示例#24
0
    def test_linesearch_wall_bound_enforcement_wall(self):
        top = self.top

        top.model.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS(bound_enforcement='wall')

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

        # Test lower bounds: should go to the lower bound and stall
        top['px.x'] = 2.0
        top['comp.y'] = 0.
        top['comp.z'] = 1.6
        top.run_model()
        for ind in range(3):
            assert_rel_error(self, top['comp.z'][ind], [1.5], 1e-8)

        # Test upper bounds: should go to the upper bound and stall
        top['px.x'] = 0.5
        top['comp.y'] = 0.
        top['comp.z'] = 2.4
        top.run_model()
        for ind in range(3):
            assert_rel_error(self, top['comp.z'][ind], [self.ub[ind]], 1e-8)
示例#25
0
    def test_linesearch_wall_bound_enforcement_scalar(self):
        top = self.top

        top.model.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS(bound_enforcement='scalar')

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

        # Test lower bounds: should stop just short of the lower bound
        top['px.x'] = 2.0
        top['comp.y'] = 0.
        top['comp.z'] = 1.6
        top.run_model()
        for ind in range(3):
            self.assertTrue(1.5 <= top['comp.z'][ind] <= 1.6)

        # Test upper bounds: should stop just short of the minimum upper bound
        top['px.x'] = 0.5
        top['comp.y'] = 0.
        top['comp.z'] = 2.4
        top.run_model()
        for ind in range(3):
            self.assertTrue(2.4 <= top['comp.z'][ind] <= self.ub[ind])
示例#26
0
    def test_linesearch_bounds_wall(self):
        top = self.top

        ls = top.model.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS(bound_enforcement='wall')
        ls.options['maxiter'] = 10
        ls.options['alpha'] = 10.0

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

        # 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)
示例#27
0
    def setup(self):

        # Evaporator
        self.add_subsystem('Rex_e', Resistor())
        self.add_subsystem('Rwe', Resistor())#, promotes_inputs=[('T_in', 'T_hot')]) # evaporator wall
        self.add_subsystem('Rwke', Resistor()) # evaporator wick
        self.add_subsystem('Rinter_e', Resistor())
        # Axial
        self.add_subsystem('Rv', Resistor()) # vapor
        self.add_subsystem('Rwka', Resistor()) # wick adiabatic
        self.add_subsystem('Rwa', Resistor()) # wall adiabatic
        # Condensor
        self.add_subsystem('Rinter_c', Resistor()) #
        self.add_subsystem('Rwkc', Resistor()) # condensor wick
        self.add_subsystem('Rwc', Resistor())#, promotes_inputs=[('T_out', 'T_cold')]) #condensor wall
        self.add_subsystem('Rex_c', Resistor())

        self.add_subsystem('n1', Node(n_in=1, n_out=2))  # 1, 2 out
        self.add_subsystem('n2', Node(n_in=1, n_out=2))  # 1, 2 out
        self.add_subsystem('n3', Node(n_in=1, n_out=1))  # 1
        self.add_subsystem('n4', Node(n_in=1, n_out=1))  # 1
        self.add_subsystem('n5', Node(n_in=1, n_out=1))  # 1
        self.add_subsystem('n6', Node(n_in=1, n_out=1))  # 1
        self.add_subsystem('n7', Node(n_in=2, n_out=1))  # 2 in, 1
        self.add_subsystem('n8', Node(n_in=2, n_out=1))  # 2 in, 1

        # node 1 (6 connections, 1 in, 2 out)
        self.connect('n1.T', ['Rex_e.T_out','Rwe.T_in', 'Rwa.T_in']) # define temperature node as resitor inputs
        self.connect('Rex_e.q','n1.q_in:0')
        self.connect('Rwe.q','n1.q_out:0')
        self.connect('Rwa.q','n1.q_out:1')

        # node 2 (6 connections, 1 in, 2 out)
        self.connect('n2.T', ['Rwe.T_out', 'Rwka.T_in','Rwke.T_in'])
        self.connect('Rwe.q', 'n2.q_in:0')
        self.connect('Rwka.q', 'n2.q_out:0') 
        self.connect('Rwke.q', 'n2.q_out:1')

        # node 3 (4 connections)
        self.connect('n3.T', ['Rwke.T_out','Rinter_e.T_in'])
        self.connect('Rwke.q', 'n3.q_in:0')
        self.connect('Rinter_e.q', 'n3.q_out:0')

        # node 4 (4 connections)
        self.connect('n4.T', ['Rinter_e.T_out','Rv.T_in'])
        self.connect('Rinter_e.q', 'n4.q_in:0')
        self.connect('Rv.q', 'n4.q_out:0')

        # node 5 (4 connections)
        self.connect('n5.T', ['Rv.T_out','Rinter_c.T_in'])
        self.connect('Rv.q', 'n5.q_in:0')
        self.connect('Rinter_c.q', 'n5.q_out:0')

        # node 6 (4 connections)
        self.connect('n6.T', ['Rinter_c.T_out','Rwkc.T_in'])
        self.connect('Rinter_c.q', 'n6.q_in:0')
        self.connect('Rwkc.q', 'n6.q_out:0')
        
        # node 7 (4 connections, 2 in, 1 out)
        self.connect('n7.T', ['Rwka.T_out','Rwkc.T_out','Rwc.T_in'])
        self.connect('Rwka.q', 'n7.q_in:0')
        self.connect('Rwkc.q', 'n7.q_in:1')
        self.connect('Rwc.q', 'n7.q_out:0')

        # node 8 (6 connections, 2 in, 1 out)
        self.connect('n8.T',['Rwa.T_out','Rwc.T_out','Rex_c.T_in'])
        self.connect('Rwa.q','n8.q_in:0')
        self.connect('Rwc.q','n8.q_in:1')
        self.connect('Rex_c.q','n8.q_out:0')



        self.nonlinear_solver = om.NewtonSolver(solve_subsystems=True)
        self.nonlinear_solver.options['iprint'] = 2
        self.nonlinear_solver.options['maxiter'] = 20
        self.linear_solver = om.DirectSolver()
        self.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS()
        self.nonlinear_solver.linesearch.options['maxiter'] = 10
        self.nonlinear_solver.linesearch.options['iprint'] = 2
示例#28
0
    # 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 = om.NonlinearRunOnce()
    p.model.circuit.linear_solver = om.LinearRunOnce()

    # Put Newton at the top so it can also converge the new BalanceComp residual
    newton = p.model.nonlinear_solver = om.NewtonSolver()
    p.model.linear_solver = om.DirectSolver()
    newton.options['iprint'] = 2
    newton.options['maxiter'] = 20
    newton.options['solve_subsystems'] = True
    newton.linesearch = om.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()
示例#29
0
    def setup(self):

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

        self.pyc_add_element(
            'fc',
            pyc.FlightConditions(thermo_data=thermo_spec,
                                 elements=pyc.AIR_MIX))
        self.pyc_add_element(
            'inlet',
            pyc.Inlet(design=design,
                      thermo_data=thermo_spec,
                      elements=pyc.AIR_MIX))
        self.pyc_add_element('fan',
                             pyc.Compressor(map_data=FanMap,
                                            design=design,
                                            thermo_data=thermo_spec,
                                            elements=pyc.AIR_MIX,
                                            map_extrap=True,
                                            bleed_names=[]),
                             promotes_inputs=[('Nmech', 'Fan_Nmech')])
        self.pyc_add_element(
            'splitter',
            pyc.Splitter(design=design,
                         thermo_data=thermo_spec,
                         elements=pyc.AIR_MIX))
        self.pyc_add_element(
            'duct2',
            pyc.Duct(design=design,
                     expMN=2.0,
                     thermo_data=thermo_spec,
                     elements=pyc.AIR_MIX))
        self.pyc_add_element('lpc',
                             pyc.Compressor(map_data=LPCMap,
                                            design=design,
                                            thermo_data=thermo_spec,
                                            elements=pyc.AIR_MIX,
                                            map_extrap=True),
                             promotes_inputs=[('Nmech', 'LP_Nmech')])
        self.pyc_add_element('bld25',
                             pyc.BleedOut(design=design, bleed_names=['sbv']))
        self.pyc_add_element(
            'duct25',
            pyc.Duct(design=design,
                     expMN=2.0,
                     thermo_data=thermo_spec,
                     elements=pyc.AIR_MIX))
        self.pyc_add_element(
            'hpc',
            pyc.Compressor(map_data=HPCMap,
                           design=design,
                           thermo_data=thermo_spec,
                           elements=pyc.AIR_MIX,
                           map_extrap=True,
                           bleed_names=['bld_inlet', 'bld_exit', 'cust']),
            promotes_inputs=[('Nmech', 'HP_Nmech')])
        self.pyc_add_element(
            'bld3',
            pyc.BleedOut(design=design, bleed_names=['bld_inlet', 'bld_exit']))
        self.pyc_add_element(
            'burner',
            pyc.Combustor(design=design,
                          thermo_data=thermo_spec,
                          inflow_elements=pyc.AIR_MIX,
                          air_fuel_elements=pyc.AIR_FUEL_MIX,
                          fuel_type='Jet-A(g)'))
        self.pyc_add_element('hpt',
                             pyc.Turbine(map_data=HPTMap,
                                         design=design,
                                         thermo_data=thermo_spec,
                                         elements=pyc.AIR_FUEL_MIX,
                                         map_extrap=True,
                                         bleed_names=['bld_inlet',
                                                      'bld_exit']),
                             promotes_inputs=[('Nmech', 'HP_Nmech')])
        self.pyc_add_element(
            'duct45',
            pyc.Duct(design=design,
                     expMN=2.0,
                     thermo_data=thermo_spec,
                     elements=pyc.AIR_FUEL_MIX))
        self.pyc_add_element('lpt',
                             pyc.Turbine(map_data=LPTMap,
                                         design=design,
                                         thermo_data=thermo_spec,
                                         elements=pyc.AIR_FUEL_MIX,
                                         map_extrap=True,
                                         bleed_names=['bld_inlet',
                                                      'bld_exit']),
                             promotes_inputs=[('Nmech', 'LP_Nmech')])
        self.pyc_add_element(
            'duct5',
            pyc.Duct(design=design,
                     expMN=2.0,
                     thermo_data=thermo_spec,
                     elements=pyc.AIR_FUEL_MIX))
        self.pyc_add_element(
            'core_nozz',
            pyc.Nozzle(nozzType='CV',
                       lossCoef='Cv',
                       thermo_data=thermo_spec,
                       elements=pyc.AIR_FUEL_MIX))

        self.pyc_add_element(
            'byp_bld', pyc.BleedOut(design=design, bleed_names=['bypBld']))
        self.pyc_add_element(
            'duct17',
            pyc.Duct(design=design,
                     expMN=2.0,
                     thermo_data=thermo_spec,
                     elements=pyc.AIR_MIX))
        self.pyc_add_element(
            'byp_nozz',
            pyc.Nozzle(nozzType='CV',
                       lossCoef='Cv',
                       thermo_data=thermo_spec,
                       elements=pyc.AIR_MIX))

        self.pyc_add_element('fan_shaft',
                             pyc.Shaft(num_ports=2),
                             promotes_inputs=[('Nmech', 'Fan_Nmech')])
        self.pyc_add_element('gearbox',
                             pyc.Gearbox(design=design),
                             promotes_inputs=[('N_in', 'LP_Nmech'),
                                              ('N_out', 'Fan_Nmech')])
        self.pyc_add_element('lp_shaft',
                             pyc.Shaft(num_ports=3),
                             promotes_inputs=[('Nmech', 'LP_Nmech')])
        self.pyc_add_element('hp_shaft',
                             pyc.Shaft(num_ports=2),
                             promotes_inputs=[('Nmech', 'HP_Nmech')])
        self.pyc_add_element('perf',
                             pyc.Performance(num_nozzles=2, num_burners=1))

        self.connect('inlet.Fl_O:tot:P', 'perf.Pt2')
        self.connect('hpc.Fl_O:tot:P', 'perf.Pt3')
        self.connect('burner.Wfuel', 'perf.Wfuel_0')
        self.connect('inlet.F_ram', 'perf.ram_drag')
        self.connect('core_nozz.Fg', 'perf.Fg_0')
        self.connect('byp_nozz.Fg', 'perf.Fg_1')

        self.connect('fan.trq', 'fan_shaft.trq_0')
        self.connect('gearbox.trq_out', 'fan_shaft.trq_1')
        self.connect('gearbox.trq_in', 'lp_shaft.trq_0')
        self.connect('lpc.trq', 'lp_shaft.trq_1')
        self.connect('lpt.trq', 'lp_shaft.trq_2')
        self.connect('hpc.trq', 'hp_shaft.trq_0')
        self.connect('hpt.trq', 'hp_shaft.trq_1')
        self.connect('fc.Fl_O:stat:P', 'core_nozz.Ps_exhaust')
        self.connect('fc.Fl_O:stat:P', 'byp_nozz.Ps_exhaust')

        self.add_subsystem(
            'ext_ratio',
            om.ExecComp(
                'ER = core_V_ideal * core_Cv / ( byp_V_ideal *  byp_Cv )',
                core_V_ideal={
                    'value': 1000.0,
                    'units': 'ft/s'
                },
                core_Cv={
                    'value': 0.98,
                    'units': None
                },
                byp_V_ideal={
                    'value': 1000.0,
                    'units': 'ft/s'
                },
                byp_Cv={
                    'value': 0.98,
                    'units': None
                },
                ER={
                    'value': 1.4,
                    'units': None
                }))

        self.connect('core_nozz.ideal_flow.V', 'ext_ratio.core_V_ideal')
        self.connect('byp_nozz.ideal_flow.V', 'ext_ratio.byp_V_ideal')

        main_order = [
            'fc', 'inlet', 'fan', 'splitter', 'duct2', 'lpc', 'bld25',
            'duct25', 'hpc', 'bld3', 'burner', 'hpt', 'duct45', 'lpt', 'duct5',
            'core_nozz', 'byp_bld', 'duct17', 'byp_nozz', 'gearbox',
            'fan_shaft', 'lp_shaft', 'hp_shaft', 'perf', 'ext_ratio'
        ]

        balance = self.add_subsystem('balance', om.BalanceComp())
        if design:

            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('lpt_PR',
                                val=10.937,
                                lower=1.001,
                                upper=20,
                                eq_units='hp',
                                rhs_val=0.,
                                res_ref=1e4)
            self.connect('balance.lpt_PR', 'lpt.PR')
            self.connect('lp_shaft.pwr_net', 'balance.lhs:lpt_PR')

            balance.add_balance('hpt_PR',
                                val=4.185,
                                lower=1.001,
                                upper=8,
                                eq_units='hp',
                                rhs_val=0.,
                                res_ref=1e4)
            self.connect('balance.hpt_PR', 'hpt.PR')
            self.connect('hp_shaft.pwr_net', 'balance.lhs:hpt_PR')

            balance.add_balance('gb_trq',
                                val=23928.0,
                                units='ft*lbf',
                                eq_units='hp',
                                rhs_val=0.0)
            self.connect('balance.gb_trq', 'gearbox.trq_base')
            self.connect('fan_shaft.pwr_net', 'balance.lhs:gb_trq')

            balance.add_balance('hpc_PR', val=14.0, units=None, eq_units=None)
            self.connect('balance.hpc_PR', ['hpc.PR', 'opr_calc.HPCPR'])
            # self.connect('perf.OPR', 'balance.lhs:hpc_PR')
            self.connect('opr_calc.OPR_simple', 'balance.lhs:hpc_PR')

            balance.add_balance('fan_eff',
                                val=0.9689,
                                units=None,
                                eq_units=None)
            self.connect('balance.fan_eff', 'fan.eff')
            self.connect('fan.eff_poly', 'balance.lhs:fan_eff')

            balance.add_balance('lpc_eff',
                                val=0.8895,
                                units=None,
                                eq_units=None)
            self.connect('balance.lpc_eff', 'lpc.eff')
            self.connect('lpc.eff_poly', 'balance.lhs:lpc_eff')

            # balance.add_balance('hpc_eff', val=0.8470, units=None, eq_units=None)
            # self.connect('balance.hpc_eff', 'hpc.eff')
            # self.connect('hpc.eff_poly', 'balance.lhs:hpc_eff')

            balance.add_balance('hpt_eff',
                                val=0.9226,
                                units=None,
                                eq_units=None)
            self.connect('balance.hpt_eff', 'hpt.eff')
            self.connect('hpt.eff_poly', 'balance.lhs:hpt_eff')

            balance.add_balance('lpt_eff',
                                val=0.9401,
                                units=None,
                                eq_units=None)
            self.connect('balance.lpt_eff', 'lpt.eff')
            self.connect('lpt.eff_poly', 'balance.lhs:lpt_eff')

            self.add_subsystem(
                'hpc_CS',
                om.ExecComp('CS = Win *(pow(Tout/518.67,0.5)/(Pout/14.696))',
                            Win={
                                'value': 10.0,
                                'units': 'lbm/s'
                            },
                            Tout={
                                'value': 14.696,
                                'units': 'degR'
                            },
                            Pout={
                                'value': 518.67,
                                'units': 'psi'
                            },
                            CS={
                                'value': 10.0,
                                'units': 'lbm/s'
                            }))
            self.connect('duct25.Fl_O:stat:W', 'hpc_CS.Win')
            self.connect('hpc.Fl_O:tot:T', 'hpc_CS.Tout')
            self.connect('hpc.Fl_O:tot:P', 'hpc_CS.Pout')
            self.add_subsystem(
                'hpc_EtaBalance',
                SmallCoreEffBalance(eng_type='large', tech_level=0))
            self.connect('hpc_CS.CS', 'hpc_EtaBalance.CS')
            self.connect('hpc.eff_poly', 'hpc_EtaBalance.eta_p')
            self.connect('hpc_EtaBalance.eta_a', 'hpc.eff')

            self.add_subsystem(
                'fan_dia',
                om.ExecComp('FanDia = 2.0*(area/(pi*(1.0-hub_tip**2.0)))**0.5',
                            area={
                                'value': 7000.0,
                                'units': 'inch**2'
                            },
                            hub_tip={
                                'value': 0.3125,
                                'units': None
                            },
                            FanDia={
                                'value': 100.0,
                                'units': 'inch'
                            }))
            self.connect('inlet.Fl_O:stat:area', 'fan_dia.area')

            self.add_subsystem(
                'opr_calc',
                om.ExecComp('OPR_simple = FPR*LPCPR*HPCPR',
                            FPR={
                                'value': 1.3,
                                'units': None
                            },
                            LPCPR={
                                'value': 3.0,
                                'units': None
                            },
                            HPCPR={
                                'value': 14.0,
                                'units': None
                            },
                            OPR_simple={
                                'value': 55.0,
                                'units': None
                            }))

            # order_add = ['hpc_CS', 'fan_dia', 'opr_calc']
            order_add = ['hpc_CS', 'hpc_EtaBalance', 'fan_dia', 'opr_calc']

        else:

            balance.add_balance('FAR', val=0.017, lower=1e-4, eq_units='lbf')
            self.connect('balance.FAR', 'burner.Fl_I:FAR')
            self.connect('perf.Fn', 'balance.lhs:FAR')
            # self.connect('burner.Fl_O:tot:T', 'balance.lhs:FAR')

            balance.add_balance('W',
                                units='lbm/s',
                                lower=10.,
                                upper=2500.,
                                eq_units='inch**2')
            self.connect('balance.W', 'fc.W')
            self.connect('core_nozz.Throat:stat:area', 'balance.lhs:W')

            balance.add_balance('BPR', lower=15., upper=40.)
            self.connect('balance.BPR', 'splitter.BPR')
            self.connect('fan.map.RlineMap', 'balance.lhs:BPR')

            balance.add_balance('fan_Nmech',
                                val=2000.0,
                                units='rpm',
                                lower=500.,
                                eq_units='hp',
                                rhs_val=0.,
                                res_ref=1e2)
            self.connect('balance.fan_Nmech', 'Fan_Nmech')
            self.connect('fan_shaft.pwr_net', 'balance.lhs:fan_Nmech')

            balance.add_balance('lp_Nmech',
                                val=6000.0,
                                units='rpm',
                                lower=500.,
                                eq_units='hp',
                                rhs_val=0.,
                                res_ref=1e2)
            self.connect('balance.lp_Nmech', 'LP_Nmech')
            self.connect('lp_shaft.pwr_net', 'balance.lhs:lp_Nmech')

            balance.add_balance('hp_Nmech',
                                val=20000.0,
                                units='rpm',
                                lower=500.,
                                eq_units='hp',
                                rhs_val=0.,
                                res_ref=1e2)
            self.connect('balance.hp_Nmech', 'HP_Nmech')
            self.connect('hp_shaft.pwr_net', 'balance.lhs:hp_Nmech')

            order_add = []

        if cooling:
            self.add_subsystem(
                'hpt_cooling',
                pyc.TurbineCooling(n_stages=2,
                                   thermo_data=pyc.species_data.janaf,
                                   T_metal=2460.))
            self.add_subsystem('hpt_chargable', pyc.CombineCooling(n_ins=3))

            self.pyc_connect_flow('bld3.bld_inlet',
                                  'hpt_cooling.Fl_cool',
                                  connect_stat=False)
            self.pyc_connect_flow('burner.Fl_O', 'hpt_cooling.Fl_turb_I')
            self.pyc_connect_flow('hpt.Fl_O', 'hpt_cooling.Fl_turb_O')

            self.connect('hpt_cooling.row_1.W_cool', 'hpt_chargable.W_1')
            self.connect('hpt_cooling.row_2.W_cool', 'hpt_chargable.W_2')
            self.connect('hpt_cooling.row_3.W_cool', 'hpt_chargable.W_3')
            self.connect('hpt.power', 'hpt_cooling.turb_pwr')

            balance.add_balance('hpt_nochrg_cool_frac',
                                val=0.063660111,
                                lower=0.02,
                                upper=.15,
                                eq_units='lbm/s')
            self.connect('balance.hpt_nochrg_cool_frac',
                         'bld3.bld_inlet:frac_W')
            self.connect('bld3.bld_inlet:stat:W',
                         'balance.lhs:hpt_nochrg_cool_frac')
            self.connect('hpt_cooling.row_0.W_cool',
                         'balance.rhs:hpt_nochrg_cool_frac')

            balance.add_balance('hpt_chrg_cool_frac',
                                val=0.07037185,
                                lower=0.02,
                                upper=.15,
                                eq_units='lbm/s')
            self.connect('balance.hpt_chrg_cool_frac', 'bld3.bld_exit:frac_W')
            self.connect('bld3.bld_exit:stat:W',
                         'balance.lhs:hpt_chrg_cool_frac')
            self.connect('hpt_chargable.W_cool',
                         'balance.rhs:hpt_chrg_cool_frac')

            order_add = ['hpt_cooling', 'hpt_chargable']

        self.set_order(main_order + order_add + ['balance'])

        self.pyc_connect_flow('fc.Fl_O', 'inlet.Fl_I')
        self.pyc_connect_flow('inlet.Fl_O', 'fan.Fl_I')
        self.pyc_connect_flow('fan.Fl_O', 'splitter.Fl_I')
        self.pyc_connect_flow('splitter.Fl_O1', 'duct2.Fl_I')
        self.pyc_connect_flow('duct2.Fl_O', 'lpc.Fl_I')
        self.pyc_connect_flow('lpc.Fl_O', 'bld25.Fl_I')
        self.pyc_connect_flow('bld25.Fl_O', 'duct25.Fl_I')
        self.pyc_connect_flow('duct25.Fl_O', 'hpc.Fl_I')
        self.pyc_connect_flow('hpc.Fl_O', 'bld3.Fl_I')
        self.pyc_connect_flow('bld3.Fl_O', 'burner.Fl_I')
        self.pyc_connect_flow('burner.Fl_O', 'hpt.Fl_I')
        self.pyc_connect_flow('hpt.Fl_O', 'duct45.Fl_I')
        self.pyc_connect_flow('duct45.Fl_O', 'lpt.Fl_I')
        self.pyc_connect_flow('lpt.Fl_O', 'duct5.Fl_I')
        self.pyc_connect_flow('duct5.Fl_O', 'core_nozz.Fl_I')
        self.pyc_connect_flow('splitter.Fl_O2', 'byp_bld.Fl_I')
        self.pyc_connect_flow('byp_bld.Fl_O', 'duct17.Fl_I')
        self.pyc_connect_flow('duct17.Fl_O', 'byp_nozz.Fl_I')

        self.pyc_connect_flow('hpc.bld_inlet',
                              'lpt.bld_inlet',
                              connect_stat=False)
        self.pyc_connect_flow('hpc.bld_exit',
                              'lpt.bld_exit',
                              connect_stat=False)
        self.pyc_connect_flow('bld3.bld_inlet',
                              'hpt.bld_inlet',
                              connect_stat=False)
        self.pyc_connect_flow('bld3.bld_exit',
                              'hpt.bld_exit',
                              connect_stat=False)

        newton = self.nonlinear_solver = om.NewtonSolver()
        newton.options['atol'] = 1e-4
        newton.options['rtol'] = 1e-4
        newton.options['iprint'] = 2
        newton.options['maxiter'] = 10
        newton.options['solve_subsystems'] = True
        newton.options['max_sub_solves'] = 10
        newton.options['reraise_child_analysiserror'] = False
        # newton.linesearch = om.BoundsEnforceLS()
        newton.linesearch = om.ArmijoGoldsteinLS()
        # newton.linesearch.options['maxiter'] = 2
        newton.linesearch.options['bound_enforcement'] = 'scalar'
        newton.linesearch.options['iprint'] = -1
        # if design:
        #     newton.linesearch.options['print_bound_enforce'] = True

        # newton.options['debug_print'] = True

        self.linear_solver = om.DirectSolver(assemble_jac=True)
示例#30
0
    def setup(self):

        newton = self.nonlinear_solver = om.NewtonSolver()
        newton.options['maxiter'] = 100
        newton.options['iprint'] = 2
        newton.options['atol'] = 1e-10
        newton.options['rtol'] = 1e-10

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

        # ln_bt = newton.linesearch = om.BoundsEnforceLS()
        ln_bt = newton.linesearch = om.ArmijoGoldsteinLS()
        ln_bt.options['maxiter'] = 2
        ln_bt.options['bound_enforcement'] = 'scalar'
        ln_bt.options['iprint'] = -1
        #ln_bt.options['maxiter'] = 1

        # Once the concentration of a species reaches its minimum, we
        # can essentially remove it from the problem. This switch controls
        # whether to do this.
        self.remove_trace_species = False

        # multiply a damping function that scales down the residual for trace species
        self.use_trace_damping = True

        thermo = self.options['thermo']
        mode = self.options['mode']

        num_prod = thermo.num_prod
        num_element = thermo.num_element

        # Input vars
        self.add_input(
            'init_prod_amounts',
            val=thermo.init_prod_amounts,
            shape=(num_prod, ),
            desc="initial mass fractions of products, before equilibrating")

        self.add_input('P', val=1.0, units="bar", desc="Pressure")

        if mode == "T":  # T is an input
            self.add_input('T', val=400., units="degK", desc="Temperature")
        elif mode == "h" or mode == "S":  # T becomes another state variable
            if mode == "h":  # hP solve
                self.add_input('h', val=0., units="cal/g", desc="Enthalpy")
            elif mode == "S":  # SP solve
                self.add_input('S',
                               val=0.,
                               units="cal/(g*degK)",
                               desc="Entropy")

            self.T_idx = num_prod + num_element
            self.add_output('T',
                            val=400.,
                            units="degK",
                            desc="Temperature",
                            lower=1.,
                            res_ref=100)

        # State vars
        self.n_init = np.ones(num_prod) / num_prod / 10  # initial guess for n

        # for a known solution, these are the orders of magnitude of the variables.
        # We'll try setting scaling to +/1 1 order around thee values

        mag = np.array([
            3.23319258e-04, 1.00000000e-10, 1.10131241e-05, 1.00000000e-10,
            1.15755853e-08, 2.95692989e-09, 1.00000000e-10, 2.69578794e-02,
            1.00000000e-10, 7.23198523e-03
        ])

        #mag = np.ones(num_prod)
        self.add_output('n',
                        shape=num_prod,
                        val=self.n_init,
                        desc="mole fractions of the mixture",
                        lower=1e-10,
                        res_ref=10000.)

        self.add_output(
            'pi',
            val=np.ones(num_element),
            desc="modified lagrange multipliers from the Gibbs lagrangian")

        # Explicit Outputs
        self.add_output(
            'b0',
            shape=num_element,  # when converged, b0=b
            desc='assigned kg-atoms of element i per total kg of reactant '
            'for the initial prod amounts')
        self.add_output('n_moles',
                        lower=1e-10,
                        val=0.034,
                        shape=1,
                        desc="1/molecular weight of gas")

        # allocate the newton Jacobian
        self.size = size = num_prod + num_element
        if mode != "T":
            size += 1  # added T as a state variable

        self._dRdy = np.zeros((size, size))
        self._rhs = np.zeros(size)  # used for solve_linear

        # Cached stuff for speed
        self.H0_T = None
        self.S0_T = None
        self.dH0_dT = None
        self.dS0_dT = None
        self.sum_n_H0_T = None

        # self.deriv_options['check_type'] = 'cs'
        # self.deriv_options['check_step_size'] = 1e-50
        # self.deriv_options['type'] = 'fd'
        # self.deriv_options['step_size'] = 1e-5

        self.declare_partials('n', ['n', 'pi', 'P', 'T'])
        self.declare_partials('pi', ['n', 'init_prod_amounts'])
        self.declare_partials('b0', ['b0', 'init_prod_amounts'])
        self.declare_partials('n_moles', 'n')
        self.declare_partials('n_moles', 'n_moles', val=-1)

        if mode == 'h':
            self.declare_partials('T', ['n', 'h', 'T'])
        elif mode == 'S':
            self.declare_partials('T', ['n', 'S', 'T', 'P'])