def test_raise_no_error_on_singular(self):
        prob = Problem()
        model = prob.model

        comp = IndepVarComp()
        comp.add_output('dXdt:TAS', val=1.0)
        comp.add_output('accel_target', val=2.0)
        model.add_subsystem('des_vars', comp, promotes=['*'])

        teg = model.add_subsystem('thrust_equilibrium_group', subsys=Group())
        teg.add_subsystem('dynamics', ExecComp('z = 2.0*thrust'), promotes=['*'])

        thrust_bal = BalanceComp()
        thrust_bal.add_balance(name='thrust', val=1207.1, lhs_name='dXdt:TAS',
                               rhs_name='accel_target', eq_units='m/s**2', lower=-10.0, upper=10000.0)

        teg.add_subsystem(name='thrust_bal', subsys=thrust_bal,
                          promotes_inputs=['dXdt:TAS', 'accel_target'],
                          promotes_outputs=['thrust'])

        teg.linear_solver = DirectSolver(assemble_jac=False)

        teg.nonlinear_solver = NewtonSolver()
        teg.nonlinear_solver.options['solve_subsystems'] = True
        teg.nonlinear_solver.options['max_sub_solves'] = 1
        teg.nonlinear_solver.options['atol'] = 1e-4

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

        teg.linear_solver.options['err_on_singular'] = False
        prob.run_model()
Beispiel #2
0
    def test_shape(self):
        n = 100

        bal = BalanceComp()
        bal.add_balance('x', shape=(n,))

        tgt = IndepVarComp(name='y_tgt', val=4*np.ones(n))

        exe = ExecComp('y=x**2', x=np.zeros(n), y=np.zeros(n))

        model = Group()

        model.add_subsystem('tgt', tgt, promotes_outputs=['y_tgt'])
        model.add_subsystem('exe', exe)
        model.add_subsystem('bal', bal)

        model.connect('y_tgt', 'bal.rhs:x')
        model.connect('bal.x', 'exe.x')
        model.connect('exe.y', 'bal.lhs:x')

        model.linear_solver = DirectSolver(assemble_jac=True)
        model.nonlinear_solver = NewtonSolver(maxiter=100, iprint=0)

        prob = Problem(model)
        prob.setup()

        prob['bal.x'] = np.random.rand(n)

        prob.run_model()

        assert_almost_equal(prob['bal.x'], 2.0*np.ones(n), decimal=7)
Beispiel #3
0
    def test_feature_scalar_with_default_mult(self):
        from numpy.testing import assert_almost_equal
        from openmdao.api import Problem, Group, IndepVarComp, ExecComp, NewtonSolver, \
            DirectSolver, BalanceComp

        prob = Problem()

        bal = BalanceComp()
        bal.add_balance('x', use_mult=True, mult_val=2.0)

        tgt = IndepVarComp(name='y_tgt', val=4)

        exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1})

        prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt'])
        prob.model.add_subsystem(name='exec', subsys=exec_comp)
        prob.model.add_subsystem(name='balance', subsys=bal)

        prob.model.connect('y_tgt', 'balance.rhs:x')
        prob.model.connect('balance.x', 'exec.x')
        prob.model.connect('exec.y', 'balance.lhs:x')

        prob.model.linear_solver = DirectSolver(assemble_jac=True)
        prob.model.nonlinear_solver = NewtonSolver(maxiter=100, iprint=0)

        prob.setup(check=False)

        # A reasonable initial guess to find the positive root.
        prob['balance.x'] = 1.0

        prob.run_model()

        assert_almost_equal(prob['balance.x'], np.sqrt(2), decimal=7)
Beispiel #4
0
    def test_scalar_with_guess_func_additional_input(self):

        model = Group(assembled_jac_type='dense')

        bal = BalanceComp()
        bal.add_balance('x')
        bal.add_input('guess_x', val=0.0)

        ivc = IndepVarComp()
        ivc.add_output(name='y_tgt', val=4)
        ivc.add_output(name='guess_x', val=2.5)

        exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1})

        model.add_subsystem(name='ivc', subsys=ivc, promotes_outputs=['y_tgt', 'guess_x'])
        model.add_subsystem(name='exec', subsys=exec_comp)
        model.add_subsystem(name='balance', subsys=bal)

        model.connect('guess_x', 'balance.guess_x')
        model.connect('y_tgt', 'balance.rhs:x')
        model.connect('balance.x', 'exec.x')
        model.connect('exec.y', 'balance.lhs:x')

        model.linear_solver = DirectSolver(assemble_jac=True)
        model.nonlinear_solver = NewtonSolver(maxiter=100, iprint=0)

        prob = Problem(model)
        prob.setup()

        # run problem without a guess function
        prob['balance.x'] = .5
        prob.run_model()

        assert_almost_equal(prob['balance.x'], 2.0, decimal=7)

        iters_no_guess = model.nonlinear_solver._iter_count

        # run problem with same initial value and a guess function
        def guess_function(inputs, outputs, resids):
            outputs['x'] = inputs['guess_x']

        bal.options['guess_func'] = guess_function

        prob['balance.x'] = .5
        prob.run_model()

        assert_almost_equal(prob['balance.x'], 2.0, decimal=7)

        iters_with_guess = model.nonlinear_solver._iter_count

        # verify it converges faster with the guess function
        self.assertTrue(iters_with_guess < iters_no_guess)
Beispiel #5
0
    def test_scalar_example(self):

        prob = Problem(model=Group())

        bal = BalanceComp()

        bal.add_balance('x', val=1.0)

        tgt = IndepVarComp(name='y_tgt', val=2)

        exec_comp = ExecComp('y=x**2')

        prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt'])

        prob.model.add_subsystem(name='exec', subsys=exec_comp)

        prob.model.add_subsystem(name='balance', subsys=bal)

        prob.model.connect('y_tgt', 'balance.rhs:x')
        prob.model.connect('balance.x', 'exec.x')
        prob.model.connect('exec.y', 'balance.lhs:x')

        # do one test in an unconverged state, to capture accuracy of partials
        prob.setup()

        prob['y_tgt'] = 100000 #set rhs and lhs to very different values. Trying to capture some derivatives wrt
        prob['exec.y'] = .001

        prob.run_model()

        cpd = prob.check_partials()

        for (of, wrt) in cpd['balance']:
            assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5)

        # set an actual solver, and re-setup. Then check derivatives at a converged point
        prob.model.linear_solver = DirectSolver()
        prob.model.nonlinear_solver = NewtonSolver()

        prob.setup()

        prob.run_model()

        assert_almost_equal(prob['balance.x'], np.sqrt(2), decimal=7)

        np.set_printoptions(linewidth=1024)

        cpd = prob.check_partials()

        for (of, wrt) in cpd['balance']:
            assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5)
Beispiel #6
0
    def test_renamed_vars(self):

        n = 1

        prob = Problem(model=Group())

        bal = BalanceComp()

        bal.add_balance('x', use_mult=True, mult_name='MUL', lhs_name='XSQ', rhs_name='TARGETXSQ')

        tgt = IndepVarComp(name='y_tgt', val=4)

        mult_ivc = IndepVarComp(name='mult', val=2.0)

        exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1})

        prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt'])
        prob.model.add_subsystem(name='mult_comp', subsys=mult_ivc, promotes_outputs=['mult'])

        prob.model.add_subsystem(name='exec', subsys=exec_comp)

        prob.model.add_subsystem(name='balance', subsys=bal)

        prob.model.connect('y_tgt', 'balance.TARGETXSQ')
        prob.model.connect('mult', 'balance.MUL')
        prob.model.connect('balance.x', 'exec.x')
        prob.model.connect('exec.y', 'balance.XSQ')

        prob.model.linear_solver = DirectSolver()

        prob.model.nonlinear_solver = NewtonSolver()
        prob.model.nonlinear_solver.options['maxiter'] = 100
        prob.model.nonlinear_solver.options['iprint'] = 0

        prob.model.jacobian = DenseJacobian()

        prob.setup()

        prob['balance.x'] = np.random.rand(n)

        prob.run_model()

        assert_almost_equal(prob['balance.x'], np.sqrt(2), decimal=7)

        np.set_printoptions(linewidth=1024)

        cpd = prob.check_partials()

        for (of, wrt) in cpd['balance']:
            assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5)
Beispiel #7
0
    def test_scalar_with_guess_func_additional_input(self):

        n = 1

        prob = Problem(model=Group())

        bal = BalanceComp()

        bal.add_balance('x', guess_func=lambda inputs, resids: inputs['guess_x'])
        bal.add_input('guess_x', val=0.0)

        ivc = IndepVarComp()
        ivc.add_output(name='y_tgt', val=4)
        ivc.add_output(name='guess_x', val=2.5)

        exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1})

        prob.model.add_subsystem(name='ivc', subsys=ivc, promotes_outputs=['y_tgt', 'guess_x'])

        prob.model.add_subsystem(name='exec', subsys=exec_comp)

        prob.model.add_subsystem(name='balance', subsys=bal)

        prob.model.connect('guess_x', 'balance.guess_x')
        prob.model.connect('y_tgt', 'balance.rhs:x')
        prob.model.connect('balance.x', 'exec.x')
        prob.model.connect('exec.y', 'balance.lhs:x')

        prob.model.linear_solver = DirectSolver()

        prob.model.nonlinear_solver = NewtonSolver()
        prob.model.nonlinear_solver.options['maxiter'] = 100
        prob.model.nonlinear_solver.options['iprint'] = 0

        prob.model.jacobian = DenseJacobian()

        prob.setup()

        prob['balance.x'] = np.random.rand(n)

        prob.run_model()

        assert_almost_equal(prob['balance.x'], 2.0, decimal=7)

        np.set_printoptions(linewidth=1024)

        cpd = prob.check_partials()

        for (of, wrt) in cpd['balance']:
            assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5)
Beispiel #8
0
    def test_feature_scalar(self):
        from numpy.testing import assert_almost_equal
        from openmdao.api import Problem, Group, IndepVarComp, ExecComp, NewtonSolver, DirectSolver, DenseJacobian, BalanceComp

        n = 1

        prob = Problem(model=Group())

        bal = BalanceComp()

        bal.add_balance('x', use_mult=True)

        tgt = IndepVarComp(name='y_tgt', val=4)

        mult_ivc = IndepVarComp(name='mult', val=2.0)

        exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1})

        prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt'])
        prob.model.add_subsystem(name='mult_comp', subsys=mult_ivc, promotes_outputs=['mult'])

        prob.model.add_subsystem(name='exec', subsys=exec_comp)

        prob.model.add_subsystem(name='balance', subsys=bal)

        prob.model.connect('y_tgt', 'balance.rhs:x')
        prob.model.connect('mult', 'balance.mult:x')
        prob.model.connect('balance.x', 'exec.x')
        prob.model.connect('exec.y', 'balance.lhs:x')

        prob.model.linear_solver = DirectSolver()

        prob.model.nonlinear_solver = NewtonSolver()
        prob.model.nonlinear_solver.options['maxiter'] = 100
        prob.model.nonlinear_solver.options['iprint'] = 0

        prob.model.jacobian = DenseJacobian()

        prob.setup(check=False)

        # A reasonable initial guess to find the positive root.
        prob['balance.x'] = 1.0

        prob.run_model()

        print('x = ', prob['balance.x'])

        assert_almost_equal(prob['balance.x'], np.sqrt(2), decimal=7)
    def test_debug_after_raised_error(self):
        prob = Problem()
        model = prob.model

        comp = IndepVarComp()
        comp.add_output('dXdt:TAS', val=1.0)
        comp.add_output('accel_target', val=2.0)
        model.add_subsystem('des_vars', comp, promotes=['*'])

        teg = model.add_subsystem('thrust_equilibrium_group', subsys=Group())
        teg.add_subsystem('dynamics', ExecComp('z = 2.0*thrust'), promotes=['*'])

        thrust_bal = BalanceComp()
        thrust_bal.add_balance(name='thrust', val=1207.1, lhs_name='dXdt:TAS',
                               rhs_name='accel_target', eq_units='m/s**2', lower=-10.0, upper=10000.0)

        teg.add_subsystem(name='thrust_bal', subsys=thrust_bal,
                          promotes_inputs=['dXdt:TAS', 'accel_target'],
                          promotes_outputs=['thrust'])

        teg.linear_solver = DirectSolver()

        teg.nonlinear_solver = NewtonSolver()
        teg.nonlinear_solver.options['solve_subsystems'] = True
        teg.nonlinear_solver.options['max_sub_solves'] = 1
        teg.nonlinear_solver.options['atol'] = 1e-4
        teg.nonlinear_solver.options['debug_print'] = True

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

        stdout = sys.stdout
        strout = StringIO()
        sys.stdout = strout

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

        sys.stdout = stdout

        output = strout.getvalue()
        target = "'thrust_equilibrium_group.thrust_bal.thrust'"
        self.assertTrue(target in output, msg=target + "NOT FOUND IN" + output)

        # Make sure exception is unchanged.
        expected_msg = "Singular entry found in 'thrust_equilibrium_group' for row associated with state/residual 'thrust'."
        self.assertEqual(expected_msg, str(cm.exception))
Beispiel #10
0
    def test_vectorized(self):

        n = 100

        prob = Problem(model=Group())

        bal = BalanceComp()

        bal.add_balance('x', val=np.ones(n))

        tgt = IndepVarComp(name='y_tgt', val=4*np.ones(n))

        exec_comp = ExecComp('y=x**2', x={'value': np.ones(n)}, y={'value': np.ones(n)})

        prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt'])

        prob.model.add_subsystem(name='exec', subsys=exec_comp)

        prob.model.add_subsystem(name='balance', subsys=bal)

        prob.model.connect('y_tgt', 'balance.rhs:x')
        prob.model.connect('balance.x', 'exec.x')
        prob.model.connect('exec.y', 'balance.lhs:x')

        prob.model.linear_solver = DirectSolver()

        prob.model.nonlinear_solver = NewtonSolver()
        prob.model.nonlinear_solver.options['maxiter'] = 100
        prob.model.nonlinear_solver.options['iprint'] = 0

        prob.model.jacobian = DenseJacobian()

        prob.setup()

        prob['balance.x'] = np.random.rand(n)

        prob.run_model()

        assert_almost_equal(prob['balance.x'], 2.0, decimal=7)

        np.set_printoptions(linewidth=1024)

        cpd = prob.check_partials()

        for (of, wrt) in cpd['balance']:
            assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5)
Beispiel #11
0
    def test_vectorized(self):

        n = 100

        prob = Problem(model=Group(assembled_jac_type='dense'))

        bal = BalanceComp()

        bal.add_balance('x', val=np.ones(n))

        tgt = IndepVarComp(name='y_tgt', val=4 * np.ones(n))

        exec_comp = ExecComp('y=x**2',
                             x={'value': np.ones(n)},
                             y={'value': np.ones(n)})

        prob.model.add_subsystem(name='target',
                                 subsys=tgt,
                                 promotes_outputs=['y_tgt'])

        prob.model.add_subsystem(name='exec', subsys=exec_comp)

        prob.model.add_subsystem(name='balance', subsys=bal)

        prob.model.connect('y_tgt', 'balance.rhs:x')
        prob.model.connect('balance.x', 'exec.x')
        prob.model.connect('exec.y', 'balance.lhs:x')

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

        prob.model.nonlinear_solver = NewtonSolver(maxiter=100, iprint=0)

        prob.setup()

        prob['balance.x'] = np.random.rand(n)

        prob.run_model()

        assert_almost_equal(prob['balance.x'], 2.0, decimal=7)

        cpd = prob.check_partials(out_stream=None)

        for (of, wrt) in cpd['balance']:
            assert_almost_equal(cpd['balance'][of, wrt]['abs error'],
                                0.0,
                                decimal=5)
Beispiel #12
0
    def test_feature_scalar(self):

        n = 1

        prob = Problem(model=Group())

        bal = BalanceComp()

        bal.add_balance('x')

        tgt = IndepVarComp(name='y_tgt', val=4)

        mult_ivc = IndepVarComp(name='mult', val=2.0)

        exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1})

        prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt'])
        prob.model.add_subsystem(name='mult_comp', subsys=mult_ivc, promotes_outputs=['mult'])

        prob.model.add_subsystem(name='exec', subsys=exec_comp)

        prob.model.add_subsystem(name='balance', subsys=bal)

        prob.model.connect('y_tgt', 'balance.rhs:x')
        prob.model.connect('mult', 'balance.mult:x')
        prob.model.connect('balance.x', 'exec.x')
        prob.model.connect('exec.y', 'balance.lhs:x')

        prob.model.linear_solver = DirectSolver()

        prob.model.nonlinear_solver = NewtonSolver()
        prob.model.nonlinear_solver.options['maxiter'] = 100
        prob.model.nonlinear_solver.options['iprint'] = 0

        prob.model.jacobian = DenseJacobian()

        prob.setup(check=False)

        # A reasonable initial guess to find the positive root.
        prob['balance.x'] = 1.0

        prob.run_model()

        print('x = ', prob['balance.x'])

        assert_almost_equal(prob['balance.x'], np.sqrt(2), decimal=7)
Beispiel #13
0
    def test_scalar(self):

        n = 1

        prob = Problem(model=Group())

        bal = BalanceComp()

        bal.add_balance('x')

        tgt = IndepVarComp(name='y_tgt', val=4)

        exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1})

        prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt'])

        prob.model.add_subsystem(name='exec', subsys=exec_comp)

        prob.model.add_subsystem(name='balance', subsys=bal)

        prob.model.connect('y_tgt', 'balance.rhs:x')
        prob.model.connect('balance.x', 'exec.x')
        prob.model.connect('exec.y', 'balance.lhs:x')

        prob.model.linear_solver = DirectSolver()

        prob.model.nonlinear_solver = NewtonSolver()
        prob.model.nonlinear_solver.options['maxiter'] = 100
        prob.model.nonlinear_solver.options['iprint'] = 0

        prob.model.jacobian = DenseJacobian()

        prob.setup()

        prob['balance.x'] = np.random.rand(n)

        prob.run_model()

        assert_almost_equal(prob['balance.x'], 2.0, decimal=7)

        np.set_printoptions(linewidth=1024)

        cpd = prob.check_partials()

        for (of, wrt) in cpd['balance']:
            assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5)
Beispiel #14
0
    def test_scalar_with_mult(self):

        n = 1

        prob = Problem(model=Group(assembled_jac_type='dense'))

        bal = BalanceComp()

        bal.add_balance('x', use_mult=True)

        tgt = IndepVarComp(name='y_tgt', val=4)

        mult_ivc = IndepVarComp(name='mult', val=2.0)

        exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1})

        prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt'])
        prob.model.add_subsystem(name='mult_comp', subsys=mult_ivc, promotes_outputs=['mult'])

        prob.model.add_subsystem(name='exec', subsys=exec_comp)

        prob.model.add_subsystem(name='balance', subsys=bal)

        prob.model.connect('y_tgt', 'balance.rhs:x')
        prob.model.connect('mult', 'balance.mult:x')
        prob.model.connect('balance.x', 'exec.x')
        prob.model.connect('exec.y', 'balance.lhs:x')

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

        prob.model.nonlinear_solver = NewtonSolver(maxiter=100, iprint=0)

        prob.setup()

        prob['balance.x'] = np.random.rand(n)

        prob.run_model()

        assert_almost_equal(prob['balance.x'], np.sqrt(2), decimal=7)

        with printoptions(linewidth=1024):

            cpd = prob.check_partials()

            for (of, wrt) in cpd['balance']:
                assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5)
    def test_raise_error_on_singular_with_densejac(self):
        prob = Problem()
        model = prob.model

        comp = IndepVarComp()
        comp.add_output('dXdt:TAS', val=1.0)
        comp.add_output('accel_target', val=2.0)
        model.add_subsystem('des_vars', comp, promotes=['*'])

        teg = model.add_subsystem('thrust_equilibrium_group', subsys=Group())
        teg.add_subsystem('dynamics',
                          ExecComp('z = 2.0*thrust'),
                          promotes=['*'])

        thrust_bal = BalanceComp()
        thrust_bal.add_balance(name='thrust',
                               val=1207.1,
                               lhs_name='dXdt:TAS',
                               rhs_name='accel_target',
                               eq_units='m/s**2',
                               lower=-10.0,
                               upper=10000.0)

        teg.add_subsystem(name='thrust_bal',
                          subsys=thrust_bal,
                          promotes_inputs=['dXdt:TAS', 'accel_target'],
                          promotes_outputs=['thrust'])

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

        teg.nonlinear_solver = NewtonSolver()
        teg.nonlinear_solver.options['solve_subsystems'] = True
        teg.nonlinear_solver.options['max_sub_solves'] = 1
        teg.nonlinear_solver.options['atol'] = 1e-4

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

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

        expected_msg = "Singular entry found in 'thrust_equilibrium_group' for column associated with state/residual 'thrust'."

        self.assertEqual(expected_msg, str(cm.exception))
Beispiel #16
0
    def test_feature_scalar_with_default_mult(self):
        from numpy.testing import assert_almost_equal
        from openmdao.api import Problem, Group, IndepVarComp, ExecComp, NewtonSolver, \
            DirectSolver, DenseJacobian, BalanceComp

        prob = Problem(model=Group())

        bal = BalanceComp()

        bal.add_balance('x', use_mult=True, mult_val=2.0)

        tgt = IndepVarComp(name='y_tgt', val=4)

        exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1})

        prob.model.add_subsystem(name='target',
                                 subsys=tgt,
                                 promotes_outputs=['y_tgt'])

        prob.model.add_subsystem(name='exec', subsys=exec_comp)

        prob.model.add_subsystem(name='balance', subsys=bal)

        prob.model.connect('y_tgt', 'balance.rhs:x')
        prob.model.connect('balance.x', 'exec.x')
        prob.model.connect('exec.y', 'balance.lhs:x')

        prob.model.linear_solver = DirectSolver()

        prob.model.nonlinear_solver = NewtonSolver()
        prob.model.nonlinear_solver.options['maxiter'] = 100
        prob.model.nonlinear_solver.options['iprint'] = 0

        prob.model.jacobian = DenseJacobian()

        prob.setup(check=False)

        # A reasonable initial guess to find the positive root.
        prob['balance.x'] = 1.0

        prob.run_model()

        print('x = ', prob['balance.x'])

        assert_almost_equal(prob['balance.x'], np.sqrt(2), decimal=7)
Beispiel #17
0
    def test_complex_step(self):

        n = 1

        prob = Problem(model=Group(assembled_jac_type='dense'))

        bal = BalanceComp()

        bal.add_balance('x')

        tgt = IndepVarComp(name='y_tgt', val=4)

        exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1})

        prob.model.add_subsystem(name='target',
                                 subsys=tgt,
                                 promotes_outputs=['y_tgt'])

        prob.model.add_subsystem(name='exec', subsys=exec_comp)

        prob.model.add_subsystem(name='balance', subsys=bal)

        prob.model.connect('y_tgt', 'balance.rhs:x')
        prob.model.connect('balance.x', 'exec.x')
        prob.model.connect('exec.y', 'balance.lhs:x')

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

        prob.model.nonlinear_solver = NewtonSolver(maxiter=100, iprint=0)

        prob.setup(force_alloc_complex=True)

        prob['balance.x'] = np.random.rand(n)

        prob.run_model()

        with warnings.catch_warnings():
            warnings.filterwarnings(action="error", category=np.ComplexWarning)
            cpd = prob.check_partials(out_stream=None, method='cs')

        for (of, wrt) in cpd['balance']:
            assert_almost_equal(cpd['balance'][of, wrt]['abs error'],
                                0.0,
                                decimal=10)
    def test_feature_scalar(self):
        from numpy.testing import assert_almost_equal
        from openmdao.api import Problem, Group, IndepVarComp, ExecComp, NewtonSolver, \
            DirectSolver, BalanceComp

        prob = Problem(model=Group(assembled_jac_type='dense'))

        bal = BalanceComp()

        bal.add_balance('x', use_mult=True)

        tgt = IndepVarComp(name='y_tgt', val=4)

        mult_ivc = IndepVarComp(name='mult', val=2.0)

        exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1})

        prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt'])
        prob.model.add_subsystem(name='mult_comp', subsys=mult_ivc, promotes_outputs=['mult'])

        prob.model.add_subsystem(name='exec', subsys=exec_comp)

        prob.model.add_subsystem(name='balance', subsys=bal)

        prob.model.connect('y_tgt', 'balance.rhs:x')
        prob.model.connect('mult', 'balance.mult:x')
        prob.model.connect('balance.x', 'exec.x')
        prob.model.connect('exec.y', 'balance.lhs:x')

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

        prob.model.nonlinear_solver = NewtonSolver(maxiter=100, iprint=0)

        prob.setup(check=False)

        # A reasonable initial guess to find the positive root.
        prob['balance.x'] = 1.0

        prob.run_model()

        print('x = ', prob['balance.x'])

        assert_almost_equal(prob['balance.x'], np.sqrt(2), decimal=7)
    def test_scalar_with_guess_func(self):

        n = 1

        prob = Problem(model=Group(assembled_jac_type='dense'))

        bal = BalanceComp()

        bal.add_balance('x', guess_func=lambda inputs, outputs, resids: np.sqrt(inputs['rhs:x']))

        tgt = IndepVarComp(name='y_tgt', val=4)

        exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1})

        prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt'])

        prob.model.add_subsystem(name='exec', subsys=exec_comp)

        prob.model.add_subsystem(name='balance', subsys=bal)

        prob.model.connect('y_tgt', 'balance.rhs:x')
        prob.model.connect('balance.x', 'exec.x')
        prob.model.connect('exec.y', 'balance.lhs:x')

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

        prob.model.nonlinear_solver = NewtonSolver(maxiter=100, iprint=0)

        prob.setup()

        prob['balance.x'] = np.random.rand(n)

        prob.run_model()

        assert_almost_equal(prob['balance.x'], 2.0, decimal=7)

        with printoptions(linewidth=1024):

            cpd = prob.check_partials()

            for (of, wrt) in cpd['balance']:
                assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5)
Beispiel #20
0
    def test_complex_step(self):

        n = 1

        prob = Problem(model=Group(assembled_jac_type='dense'))

        bal = BalanceComp()

        bal.add_balance('x')

        tgt = IndepVarComp(name='y_tgt', val=4)

        exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1})

        prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt'])

        prob.model.add_subsystem(name='exec', subsys=exec_comp)

        prob.model.add_subsystem(name='balance', subsys=bal)

        prob.model.connect('y_tgt', 'balance.rhs:x')
        prob.model.connect('balance.x', 'exec.x')
        prob.model.connect('exec.y', 'balance.lhs:x')

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

        prob.model.nonlinear_solver = NewtonSolver(maxiter=100, iprint=0)

        prob.setup(force_alloc_complex=True)

        prob['balance.x'] = np.random.rand(n)

        prob.run_model()

        with warnings.catch_warnings():
            warnings.filterwarnings(action="error", category=np.ComplexWarning)
            cpd = prob.check_partials(out_stream=None, method='cs')

        for (of, wrt) in cpd['balance']:
            assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=10)
Beispiel #21
0
    def test_vectorized_no_normalization(self):

        n = 100

        prob = Problem(model=Group(assembled_jac_type='dense'))

        bal = BalanceComp()

        bal.add_balance('x', val=np.ones(n), normalize=False)

        tgt = IndepVarComp(name='y_tgt', val=1.7*np.ones(n))

        exec_comp = ExecComp('y=x**2', x={'value': np.ones(n)}, y={'value': np.ones(n)})

        prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt'])

        prob.model.add_subsystem(name='exec', subsys=exec_comp)

        prob.model.add_subsystem(name='balance', subsys=bal)

        prob.model.connect('y_tgt', 'balance.rhs:x')
        prob.model.connect('balance.x', 'exec.x')
        prob.model.connect('exec.y', 'balance.lhs:x')

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

        prob.model.nonlinear_solver = NewtonSolver(maxiter=100, iprint=0)

        prob.setup()

        prob['balance.x'] = np.random.rand(n)

        prob.run_model()

        assert_almost_equal(prob['balance.x'], np.sqrt(1.7), decimal=7)

        cpd = prob.check_partials(out_stream=None)

        for (of, wrt) in cpd['balance']:
            assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5)
    def test_raise_no_error_on_singular(self):
        prob = Problem()
        model = prob.model

        comp = IndepVarComp()
        comp.add_output('dXdt:TAS', val=1.0)
        comp.add_output('accel_target', val=2.0)
        model.add_subsystem('des_vars', comp, promotes=['*'])

        teg = model.add_subsystem('thrust_equilibrium_group', subsys=Group())
        teg.add_subsystem('dynamics',
                          ExecComp('z = 2.0*thrust'),
                          promotes=['*'])

        thrust_bal = BalanceComp()
        thrust_bal.add_balance(name='thrust',
                               val=1207.1,
                               lhs_name='dXdt:TAS',
                               rhs_name='accel_target',
                               eq_units='m/s**2',
                               lower=-10.0,
                               upper=10000.0)

        teg.add_subsystem(name='thrust_bal',
                          subsys=thrust_bal,
                          promotes_inputs=['dXdt:TAS', 'accel_target'],
                          promotes_outputs=['thrust'])

        teg.linear_solver = DirectSolver(assemble_jac=False)

        teg.nonlinear_solver = NewtonSolver()
        teg.nonlinear_solver.options['solve_subsystems'] = True
        teg.nonlinear_solver.options['max_sub_solves'] = 1
        teg.nonlinear_solver.options['atol'] = 1e-4

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

        teg.linear_solver.options['err_on_singular'] = False
        prob.run_model()
Beispiel #23
0
    def test_raise_error_on_singular_with_densejac(self):
        prob = Problem()
        model = prob.model

        comp = IndepVarComp()
        comp.add_output('dXdt:TAS', val=1.0)
        comp.add_output('accel_target', val=2.0)
        model.add_subsystem('des_vars', comp, promotes=['*'])

        teg = model.add_subsystem('thrust_equilibrium_group', subsys=Group())
        teg.add_subsystem('dynamics', ExecComp('z = 2.0*thrust'), promotes=['*'])

        thrust_bal = BalanceComp()
        thrust_bal.add_balance(name='thrust', val=1207.1, lhs_name='dXdt:TAS',
                               rhs_name='accel_target', eq_units='m/s**2', lower=-10.0, upper=10000.0)

        teg.add_subsystem(name='thrust_bal', subsys=thrust_bal,
                          promotes_inputs=['dXdt:TAS', 'accel_target'],
                          promotes_outputs=['thrust'])

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

        teg.nonlinear_solver = NewtonSolver()
        teg.nonlinear_solver.options['solve_subsystems'] = True
        teg.nonlinear_solver.options['max_sub_solves'] = 1
        teg.nonlinear_solver.options['atol'] = 1e-4

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

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

        expected_msg = "Singular entry found in 'thrust_equilibrium_group' for column associated with state/residual 'thrust'."

        self.assertEqual(expected_msg, str(cm.exception))
Beispiel #24
0
    def setup(self):
        thermo_data = self.options['thermo_data']
        elements = self.options['elements']

        self.add_subsystem('fs',
                           FlowStart(thermo_data=thermo_data,
                                     elements=elements),
                           promotes_outputs=['Fl_O:*'],
                           promotes_inputs=['W'])

        balance = BalanceComp()
        balance.add_balance('P',
                            val=10.,
                            units='psi',
                            eq_units='psi',
                            lhs_name='Ps_computed',
                            rhs_name='Ps',
                            lower=1e-1)
        #guess_func=lambda inputs, resids: 5.)
        balance.add_balance('T',
                            val=800.,
                            units='degR',
                            eq_units='ft/s',
                            lhs_name='V_computed',
                            rhs_name='V',
                            lower=1e-1)
        #guess_func=lambda inputs, resids: 400.)
        balance.add_balance('MN',
                            val=.3,
                            eq_units='inch**2',
                            lhs_name='area_computed',
                            rhs_name='area',
                            lower=1e-6)
        #guess_func=lambda inputs, resids: .6)

        self.add_subsystem('balance',
                           balance,
                           promotes_inputs=['Ps', 'V', 'area'])
        self.connect('Fl_O:stat:P', 'balance.Ps_computed')
        self.connect('Fl_O:stat:V', 'balance.V_computed')
        self.connect('Fl_O:stat:area', 'balance.area_computed')

        self.connect('balance.P', 'fs.P')
        self.connect('balance.T', 'fs.T')
        self.connect('balance.MN', 'fs.MN')

        newton = self.nonlinear_solver = NewtonSolver()
        newton.options['solve_subsystems'] = True
        newton.options['maxiter'] = 10
        # newton.linesearch = BoundsEnforceLS()
        # newton.linesearch.options['print_bound_enforce'] = True

        self.linear_solver = DirectSolver(assemble_jac=True)
Beispiel #25
0
def compute_drag_polar(Mach, alphas, surfaces, trimmed=False):

    if isinstance(surfaces, dict):
        surfaces = [
            surfaces,
        ]

    # Create the OpenMDAO problem
    prob = Problem()
    # Create an independent variable component that will supply the flow
    # conditions to the problem.
    indep_var_comp = IndepVarComp()
    indep_var_comp.add_output('v', val=248.136, units='m/s')
    indep_var_comp.add_output('alpha', val=0., units='deg')
    indep_var_comp.add_output('Mach_number', val=Mach)
    indep_var_comp.add_output('re', val=1.e6, units='1/m')
    indep_var_comp.add_output('rho', val=0.38, units='kg/m**3')
    indep_var_comp.add_output('cg', val=np.zeros((3)), units='m')
    # Add this IndepVarComp to the problem model
    prob.model.add_subsystem('prob_vars', indep_var_comp, promotes=['*'])

    for surface in surfaces:
        name = surface['name']
        # Create and add a group that handles the geometry for the
        # aerodynamic lifting surface
        geom_group = Geometry(surface=surface)
        prob.model.add_subsystem(name, geom_group)

        # Connect the mesh from the geometry component to the analysis point
        prob.model.connect(name + '.mesh', 'aero.' + name + '.def_mesh')
        # Perform the connections with the modified names within the
        # 'aero_states' group.
        prob.model.connect(name + '.mesh',
                           'aero.aero_states.' + name + '_def_mesh')

    # Create the aero point group, which contains the actual aerodynamic
    # analyses
    point_name = 'aero'
    aero_group = AeroPoint(surfaces=surfaces)
    prob.model.add_subsystem(
        point_name,
        aero_group,
        promotes_inputs=['v', 'alpha', 'Mach_number', 're', 'rho', 'cg'])

    # For trimmed polar, setup balance component
    if trimmed == True:
        bal = BalanceComp()
        bal.add_balance(name='tail_rotation', rhs_val=0., units='deg')
        prob.model.add_subsystem('balance',
                                 bal,
                                 promotes_outputs=['tail_rotation'])
        prob.model.connect('aero.CM',
                           'balance.lhs:tail_rotation',
                           src_indices=[1])
        prob.model.connect('tail_rotation', 'tail.twist_cp')

        prob.model.nonlinear_solver = NonlinearBlockGS(use_aitken=True)

        prob.model.nonlinear_solver.options['iprint'] = 2
        prob.model.nonlinear_solver.options['maxiter'] = 100
        prob.model.linear_solver = DirectSolver()

    prob.setup()

    #prob['tail_rotation'] = -0.75

    prob.run_model()
    #prob.check_partials(compact_print = True)
    #prob.model.list_outputs(prom_name = True)

    prob.model.list_outputs(residuals=True)

    CLs = []
    CDs = []
    CMs = []

    for a in alphas:
        prob['alpha'] = a
        prob.run_model()
        CLs.append(prob['aero.CL'][0])
        CDs.append(prob['aero.CD'][0])
        CMs.append(prob['aero.CM'][1])  # Take only the longitudinal CM
        #print(a, prob['aero.CL'], prob['aero.CD'], prob['aero.CM'][1])

    # Plot CL vs alpha and drag polar
    fig, axes = plt.subplots(nrows=3)
    axes[0].plot(alphas, CLs)
    axes[1].plot(alphas, CMs)
    axes[2].plot(CLs, CDs)
    fig.savefig('drag_polar.pdf')
    #plt.show()

    return CLs, CDs, CMs
Beispiel #26
0
    def setup(self):

        map_data = self.options['map_data']
        design = self.options['design']
        method = self.options['interp_method']
        extrap = self.options['extrap']

        params = map_data.param_data
        outputs = map_data.output_data

        # Define map which will be used
        readmap = MetaModelStructuredComp(method=method, extrapolate=extrap)
        for p in params:
            readmap.add_input(p['name'],
                              val=p['default'],
                              units=p['units'],
                              training_data=p['values'])
        for o in outputs:
            readmap.add_output(o['name'],
                               val=o['default'],
                               units=o['units'],
                               training_data=o['values'])

        # Create instance of map for evaluating actual operating point
        if design:
            # In design mode, operating point specified by default values for RlineMap, NcMap and alphaMap
            mapDesPt = IndepVarComp()
            mapDesPt.add_output('NcMap',
                                val=map_data.defaults['NcMap'],
                                units='rpm')
            mapDesPt.add_output('RlineMap',
                                val=map_data.defaults['RlineMap'],
                                units=None)
            self.add_subsystem('mapDesPt', subsys=mapDesPt, promotes=['*'])

            # Evaluate map using design point values
            self.add_subsystem(
                'map',
                readmap,
                promotes_inputs=['RlineMap', 'NcMap', 'alphaMap'],
                promotes_outputs=['effMap', 'PRmap', 'WcMap'])

            # Compute map scalars based on input PR, eff, Nc and Wc as well as unscaled map values
            self.add_subsystem(
                'scalars',
                MapScalars(),
                promotes_inputs=[
                    'PR', 'eff', 'Nc', 'Wc', 'NcMap', 'effMap', 'PRmap',
                    'WcMap'
                ],
                promotes_outputs=['s_Nc', 's_PR', 's_eff', 's_Wc'])

        else:
            # In off-design mode, RlineMap, NcMap and alphaMap are input to map
            self.add_subsystem(
                'map',
                readmap,
                promotes_inputs=['RlineMap', 'NcMap', 'alphaMap'],
                promotes_outputs=['effMap', 'PRmap', 'WcMap'])

            # Compute scaled map outputs base on input scalars and unscaled map values
            self.add_subsystem('scaledOutput',
                               ScaledMapValues(),
                               promotes_inputs=[
                                   's_PR', 's_eff', 's_Wc', 's_Nc', 'NcMap',
                                   'effMap', 'PRmap', 'WcMap'
                               ],
                               promotes_outputs=['PR', 'eff'])

            # Use balance component to vary NcMap and RlineMap to match incoming corrected flow and speed
            map_bal = BalanceComp()
            map_bal.add_balance('NcMap',
                                val=map_data.defaults['NcMap'],
                                units='rpm',
                                eq_units='rpm')
            map_bal.add_balance('RlineMap',
                                val=map_data.defaults['RlineMap'],
                                units=None,
                                eq_units='lbm/s',
                                lower=map_data.RlineStall)
            self.add_subsystem(name='map_bal',
                               subsys=map_bal,
                               promotes_inputs=[('lhs:NcMap', 'Nc'),
                                                ('lhs:RlineMap', 'Wc')],
                               promotes_outputs=['NcMap', 'RlineMap'])
            self.connect('scaledOutput.Nc', 'map_bal.rhs:NcMap')
            self.connect('scaledOutput.Wc', 'map_bal.rhs:RlineMap')

        # Define the Rline corresponding to stall
        RlineStall = IndepVarComp()
        RlineStall.add_output('RlineStall',
                              val=map_data.RlineStall,
                              units=None)
        self.add_subsystem('stall_R', subsys=RlineStall)

        # Evaluate map for the constant speed stall margin (SMN)
        SMN_map = MetaModelStructuredComp(method=method, extrapolate=extrap)
        for p in params:
            SMN_map.add_input(p['name'],
                              val=p['default'],
                              units=p['units'],
                              training_data=p['values'])
        for o in outputs:
            SMN_map.add_output(o['name'],
                               val=o['default'],
                               units=o['units'],
                               training_data=o['values'])

        self.add_subsystem('SMN_map',
                           SMN_map,
                           promotes_inputs=['NcMap', 'alphaMap'])
        self.connect('stall_R.RlineStall', 'SMN_map.RlineMap')

        # Evaluate map for the constant speed stall margin (SMN)
        SMW_map = MetaModelStructuredComp(method=method, extrapolate=extrap)
        for p in params:
            SMW_map.add_input(p['name'],
                              val=p['default'],
                              units=p['units'],
                              training_data=p['values'])
        for o in outputs:
            SMW_map.add_output(o['name'],
                               val=o['default'],
                               units=o['units'],
                               training_data=o['values'])
        self.add_subsystem('SMW_map', SMW_map, promotes_inputs=['alphaMap'])
        self.connect('stall_R.RlineStall', 'SMW_map.RlineMap')

        # Use balance to vary NcMap on SMW map to hold corrected flow constant
        SMW_bal = BalanceComp()
        SMW_bal.add_balance('NcMap',
                            val=map_data.defaults['NcMap'],
                            units='rpm',
                            eq_units='lbm/s')
        self.add_subsystem(name='SMW_bal', subsys=SMW_bal)
        self.connect('SMW_bal.NcMap', 'SMW_map.NcMap')
        self.connect('WcMap', 'SMW_bal.lhs:NcMap')
        self.connect('SMW_map.WcMap', 'SMW_bal.rhs:NcMap')

        # Compute the stall margins
        self.add_subsystem('stall_margins',
                           StallCalcs(),
                           promotes_inputs=[('PR_actual', 'PRmap'),
                                            ('Wc_actual', 'WcMap')],
                           promotes_outputs=['SMN', 'SMW'])
        self.connect('SMN_map.PRmap', 'stall_margins.PR_SMN')
        self.connect('SMW_map.PRmap', 'stall_margins.PR_SMW')
        self.connect('SMN_map.WcMap', 'stall_margins.Wc_SMN')
Beispiel #27
0
    def test_result(self):
        import numpy as np
        from numpy.testing import assert_almost_equal

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

        prob = Problem(model=Group())

        ivc = IndepVarComp()

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

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

        bal = BalanceComp()

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

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

        bal.guess_nonlinear = guess_func

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

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

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

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

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

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

        prob.setup()

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

        prob.run_model()

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

        print('E (deg) = ', np.degrees(prob['E'][0]))
def compute_drag_polar(Mach, alphas, surfaces, trimmed=False):

    if isinstance(surfaces, dict):
        surfaces = [surfaces,]

    # Create the OpenMDAO problem
    prob = Problem()
    # Create an independent variable component that will supply the flow
    # conditions to the problem.
    indep_var_comp = IndepVarComp()
    indep_var_comp.add_output('v', val=248.136, units='m/s')
    indep_var_comp.add_output('alpha', val=0., units = 'deg')
    indep_var_comp.add_output('M', val=Mach)
    indep_var_comp.add_output('re', val=1.e6, units='1/m')
    indep_var_comp.add_output('rho', val=0.38, units='kg/m**3')
    indep_var_comp.add_output('cg', val=np.zeros((3)), units='m')
    # Add this IndepVarComp to the problem model
    prob.model.add_subsystem('prob_vars',
        indep_var_comp,
        promotes=['*'])


    for surface in surfaces:
        name = surface['name']
        # Create and add a group that handles the geometry for the
        # aerodynamic lifting surface
        geom_group = Geometry(surface=surface)
        prob.model.add_subsystem(name, geom_group)

        # Connect the mesh from the geometry component to the analysis point
        prob.model.connect(name + '.mesh', 'aero.' + name + '.def_mesh')
        # Perform the connections with the modified names within the
        # 'aero_states' group.
        prob.model.connect(name + '.mesh', 'aero.aero_states.' + name + '_def_mesh')

    # Create the aero point group, which contains the actual aerodynamic
    # analyses
    point_name = 'aero'
    aero_group = AeroPoint(surfaces=surfaces)
    prob.model.add_subsystem(point_name, aero_group,
        promotes_inputs=['v', 'alpha', 'M', 're', 'rho', 'cg'])

    # For trimmed polar, setup balance component
    if trimmed == True:
        bal = BalanceComp()
        bal.add_balance(name='tail_rotation', rhs_val = 0., units = 'deg')
        prob.model.add_subsystem('balance', bal,
            promotes_outputs = ['tail_rotation'])
        prob.model.connect('aero.CM', 'balance.lhs:tail_rotation', src_indices = [1])
        prob.model.connect('tail_rotation', 'tail.twist_cp', src_indices = np.zeros((1,5), dtype = int))

        # Use Newton Solver
        # prob.model.nonlinear_solver = NewtonSolver()
        # prob.model.nonlinear_solver.options['solve_subsystems'] = True

        # Use Broyden Solver
        prob.model.nonlinear_solver = BroydenSolver()
        prob.model.nonlinear_solver.options['state_vars'] = ['tail_rotation']

        # prob.model.nonlinear_solver.linesearch = ArmijoGoldsteinLS()

        prob.model.nonlinear_solver.options['iprint'] = 2
        prob.model.nonlinear_solver.options['maxiter'] = 20
        prob.model.linear_solver = DirectSolver()


    prob.setup()

    #prob['tail_rotation'] = -0.75

    prob.run_model()
    #prob.check_partials(compact_print = True)
    #prob.model.list_outputs(prom_name = True)

    prob.model.list_outputs(residuals = True)

    CLs = []
    CDs = []
    CMs = []

    for a in alphas:
        prob['alpha'] =  a
        prob.run_model()
        CLs.append(prob['aero.CL'][0])
        CDs.append(prob['aero.CD'][0])
        CMs.append(prob['aero.CM'][1]) # Take only the longitudinal CM
        #print(a, prob['aero.CL'], prob['aero.CD'], prob['aero.CM'][1])

    # Plot CL vs alpha and drag polar
    fig,axes =  plt.subplots(nrows=3)
    axes[0].plot(alphas, CLs)
    axes[1].plot(alphas, CMs)
    axes[2].plot(CLs, CDs)
    fig.savefig('drag_polar.pdf')
    #plt.show()

    return CLs, CDs, CMs
Beispiel #29
0
    def test_result(self):
        import numpy as np
        from numpy.testing import assert_almost_equal

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

        prob = Problem(model=Group())

        ivc = IndepVarComp()

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

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

        bal = BalanceComp()

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

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

        bal.guess_nonlinear = guess_func

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

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

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

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

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

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

        prob.setup()

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

        prob.run_model()

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

        print('E (deg) = ', np.degrees(prob['E'][0]))
Beispiel #30
0
    def setup(self):

        map_data = self.options['map_data']
        design = self.options['design']
        method = self.options['interp_method']
        extrap = self.options['extrap']

        params = map_data.param_data
        outputs = map_data.output_data

        # Define map which will be used
        readmap = MetaModelStructuredComp(method=method, extrapolate=extrap)
        for p in params:
            readmap.add_input(p['name'],
                              val=p['default'],
                              units=p['units'],
                              training_data=p['values'])
        for o in outputs:
            readmap.add_output(o['name'],
                               val=o['default'],
                               units=o['units'],
                               training_data=o['values'])

        if design:
            # In design mode, operating point specified by default values for RlineMap, NcMap and alphaMap
            mapDesPt = IndepVarComp()
            mapDesPt.add_output('NpMap',
                                val=map_data.defaults['NpMap'],
                                units='rpm')
            mapDesPt.add_output('PRmap',
                                val=map_data.defaults['PRmap'],
                                units=None)
            self.add_subsystem('mapDesPt', subsys=mapDesPt, promotes=['*'])

            # Evaluate map using design point values
            self.add_subsystem('readMap',
                               readmap,
                               promotes_inputs=['alphaMap', 'NpMap', 'PRmap'],
                               promotes_outputs=['effMap', 'WpMap'])

            # Compute map scalars based on input PR, eff, Np and Wp as well as unscaled map values
            self.add_subsystem(
                'scalars',
                MapScalars(),
                promotes_inputs=[
                    'PR', 'eff', 'Np', 'Wp', 'NpMap', 'effMap', 'PRmap',
                    'WpMap'
                ],
                promotes_outputs=['s_Np', 's_PR', 's_eff', 's_Wp'])

        else:
            # In off-design mode, PRmap, NpMap and alphaMap are input to map
            self.add_subsystem('readMap',
                               readmap,
                               promotes_inputs=['alphaMap', 'NpMap', 'PRmap'],
                               promotes_outputs=['effMap', 'WpMap'])

            # Compute scaled map outputs base on input scalars and unscaled map values
            self.add_subsystem('scaledOutput',
                               ScaledMapValues(),
                               promotes_inputs=[
                                   's_PR', 's_eff', 's_Wp', 's_Np', 'NpMap',
                                   'effMap', 'PRmap', 'WpMap'
                               ],
                               promotes_outputs=['PR', 'eff'])

            # Use balance component to vary NpMap and PRmap to match incoming corrected flow and speed
            map_bal = BalanceComp()
            map_bal.add_balance('NpMap',
                                val=map_data.defaults['NpMap'],
                                units='rpm',
                                eq_units='rpm',
                                lower=1.,
                                upper=200.)
            map_bal.add_balance('PRmap',
                                val=map_data.defaults['PRmap'],
                                units=None,
                                eq_units='lbm/s',
                                lower=1.01)
            self.add_subsystem(name='map_bal',
                               subsys=map_bal,
                               promotes_inputs=[('lhs:NpMap', 'Np'),
                                                ('lhs:PRmap', 'Wp')],
                               promotes_outputs=['NpMap', 'PRmap'])
            self.connect('scaledOutput.Np', 'map_bal.rhs:NpMap')
            self.connect('scaledOutput.Wp', 'map_bal.rhs:PRmap')