Exemple #1
0
    def test_solve_subsystems_basic(self):
        from openmdao.api import Problem, NewtonSolver, DirectSolver, ScipyKrylov
        from openmdao.test_suite.components.double_sellar import DoubleSellar

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

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

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

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

        model.nonlinear_solver.options['solve_subsystems'] = True

        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)
    def test_inp_inp_promoted_w_explicit_src(self):
        p = Problem(model=Group())
        root = p.model

        G1 = root.add_subsystem("G1", Group())
        G2 = G1.add_subsystem("G2", Group(), promotes=['x'])
        G2.add_subsystem("C1", ExecComp('y=x*2.0'))
        G2.add_subsystem("C2", IndepVarComp('x', 1.0), promotes=['x'])

        G3 = root.add_subsystem("G3", Group())
        G4 = G3.add_subsystem("G4", Group(), promotes=['x'])
        C3 = G4.add_subsystem("C3", ExecComp('y=x*2.0'), promotes=['x'])
        C4 = G4.add_subsystem("C4", ExecComp('y=x*2.0'), promotes=['x'])

        p.model.connect('G1.x', 'G3.x')
        p.setup(check=False)
        p.set_solver_print(level=0)

        # setting promoted name will set the value into the outputs, but will
        # not propagate it to the inputs. That will happen during run_model().
        p['G1.x'] = 999.

        p.run_model()
        self.assertEqual(C3._inputs['x'], 999.)
        self.assertEqual(C4._inputs['x'], 999.)
    def test_basic(self):
        prob = Problem()
        model = prob.model

        n_cp = 80
        n_point = 160

        t = np.linspace(0, 3.0*np.pi, n_cp)
        x = np.sin(t)

        model.add_subsystem('px', IndepVarComp('x', val=x))
        model.add_subsystem('interp', BsplinesComp(num_control_points=n_cp,
                                                   num_points=n_point,
                                                   in_name='h_cp',
                                                   out_name='h',
                                                   distribution='uniform'))

        model.connect('px.x', 'interp.h_cp')

        prob.setup(check=False)
        prob.run_model()

        xx = prob['interp.h'].flatten()
        tt = np.linspace(0, 3.0*np.pi, n_point)

        x_expected = np.sin(tt)
        delta = xx - x_expected

        # Here we test that we don't have crazy interpolation error.
        self.assertLess(max(delta), .15)
        # And that it gets middle points a little better.
        self.assertLess(max(delta[15:-15]), .06)
Exemple #4
0
    def test_solve_subsystems_basic(self):
        prob = Problem(model=DoubleSellar())
        model = prob.model

        g1 = model.g1
        g1.nonlinear_solver = NewtonSolver()
        g1.nonlinear_solver.options['rtol'] = 1.0e-5
        g1.linear_solver = DirectSolver(assemble_jac=True)
        g1.options['assembled_jac_type'] = 'dense'

        g2 = model.g2
        g2.nonlinear_solver = NewtonSolver()
        g2.nonlinear_solver.options['rtol'] = 1.0e-5
        g2.linear_solver = DirectSolver(assemble_jac=True)
        g2.options['assembled_jac_type'] = 'dense'

        model.nonlinear_solver = NewtonSolver()
        model.linear_solver = ScipyKrylov(assemble_jac=True)
        model.options['assembled_jac_type'] = 'dense'

        model.nonlinear_solver.options['solve_subsystems'] = True

        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)
    def test_specify_subgroup_solvers(self):
        from openmdao.api import Problem, NewtonSolver, ScipyKrylov, DirectSolver, NonlinearBlockGS, LinearBlockGS
        from openmdao.test_suite.components.double_sellar import DoubleSellar

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

        # each SubSellar group converges itself
        g1 = model.g1
        g1.nonlinear_solver = NewtonSolver()
        g1.linear_solver = DirectSolver()  # used for derivatives

        g2 = model.g2
        g2.nonlinear_solver = NewtonSolver()
        g2.linear_solver = DirectSolver()

        # Converge the outer loop with Gauss Seidel, with a looser tolerance.
        model.nonlinear_solver = NonlinearBlockGS(rtol=1.0e-5)
        model.linear_solver = ScipyKrylov()
        model.linear_solver.precon = LinearBlockGS()

        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)
    def test_converge_diverge_groups(self):
        # Test derivatives for converge-diverge-groups topology.
        prob = Problem()
        model = prob.model = ConvergeDivergeGroups()

        model.linear_solver = LinearRunOnce()
        model.g1.linear_solver = LinearRunOnce()
        model.g1.g2.linear_solver = LinearRunOnce()
        model.g3.linear_solver = LinearRunOnce()

        prob.set_solver_print(level=0)
        prob.setup(check=False, mode='fwd')
        prob.run_model()

        wrt = ['iv.x']
        of = ['c7.y1']

        # Make sure value is fine.
        assert_rel_error(self, prob['c7.y1'], -102.7, 1e-6)

        J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict')
        assert_rel_error(self, J['c7.y1', 'iv.x'][0][0], -40.75, 1e-6)

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

        J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict')
        assert_rel_error(self, J['c7.y1', 'iv.x'][0][0], -40.75, 1e-6)
    def test_linear_system(self):
        """Check against the scipy solver."""

        model = Group()

        x = np.array([1, 2, -3])
        A = np.array([[5.0, -3.0, 2.0], [1.0, 7.0, -4.0], [1.0, 0.0, 8.0]])
        b = A.dot(x)

        model.add_subsystem('p1', IndepVarComp('A', A))
        model.add_subsystem('p2', IndepVarComp('b', b))

        lingrp = model.add_subsystem('lingrp', Group(), promotes=['*'])
        lingrp.add_subsystem('lin', LinearSystemComp(size=3, partial_type="matrix_free"))

        model.connect('p1.A', 'lin.A')
        model.connect('p2.b', 'lin.b')

        prob = Problem(model)
        prob.setup()

        lingrp.linear_solver = ScipyKrylov()

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

        assert_rel_error(self, prob['lin.x'], x, .0001)
        assert_rel_error(self, prob.model._residuals.get_norm(), 0.0, 1e-10)
    def test_fan_in_grouped(self):

        prob = Problem()
        prob.model = FanInGrouped2()
        prob.setup(vector_class=PETScVector, check=False, mode='fwd')
        prob.set_solver_print(level=0)
        prob.run_model()


        indep_list = ['p1.x', 'p2.x']
        unknown_list = ['c3.y']

        assert_rel_error(self, prob['c3.y'], 29.0, 1e-6)

        J = prob.compute_totals(of=unknown_list, wrt=indep_list)
        assert_rel_error(self, J['c3.y', 'p1.x'][0][0], -6.0, 1e-6)
        assert_rel_error(self, J['c3.y', 'p2.x'][0][0], 35.0, 1e-6)

        assert_rel_error(self, prob['c3.y'], 29.0, 1e-6)

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

        assert_rel_error(self, prob['c3.y'], 29.0, 1e-6)

        J = prob.compute_totals(of=unknown_list, wrt=indep_list)
        assert_rel_error(self, J['c3.y', 'p1.x'][0][0], -6.0, 1e-6)
        assert_rel_error(self, J['c3.y', 'p2.x'][0][0], 35.0, 1e-6)

        assert_rel_error(self, prob['c3.y'], 29.0, 1e-6)
Exemple #9
0
    def test_setup_bug1(self):
        # This tests a bug where, if you run setup more than once on a derived component class,
        # the list of var names continually gets prepended with the component global path.

        class NewBase(Component):
            def __init__(self, **kwargs):
                super(NewBase, self).__init__(**kwargs)

        class MyComp(NewBase):
            def __init__(self, **kwargs):
                super(MyComp, self).__init__(**kwargs)

            def setup(self):
                self.add_input('x', val=0.0)
                self.add_output('y', val=0.0)

        prob = Problem()
        model = prob.model = Group()
        comp = model.add_subsystem('comp', MyComp())

        prob.setup(check=False)
        self.assertEqual(comp._var_abs_names['input'], ['comp.x'])
        self.assertEqual(comp._var_abs_names['output'], ['comp.y'])

        prob.run_model()
        prob.setup(check=False)
        self.assertEqual(comp._var_abs_names['input'], ['comp.x'])
        self.assertEqual(comp._var_abs_names['output'], ['comp.y'])
    def test_converge_diverge(self):

        prob = Problem()
        prob.model = ConvergeDiverge()
        prob.setup(vector_class=PETScVector, check=False, mode='fwd')
        prob.set_solver_print(level=0)
        prob.run_model()

        assert_rel_error(self, prob['c7.y1'], -102.7, 1e-6)

        indep_list = ['iv.x']
        unknown_list = ['c7.y1']

        J = prob.compute_totals(of=unknown_list, wrt=indep_list)
        assert_rel_error(self, J['c7.y1', 'iv.x'][0][0], -40.75, 1e-6)

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

        assert_rel_error(self, prob['c7.y1'], -102.7, 1e-6)

        J = prob.compute_totals(of=unknown_list, wrt=indep_list)
        assert_rel_error(self, J['c7.y1', 'iv.x'][0][0], -40.75, 1e-6)

        assert_rel_error(self, prob['c7.y1'], -102.7, 1e-6)
    def test_fan_out_grouped(self):
        prob = Problem(FanOutGrouped())

        of=['c2.y', "c3.y"]
        wrt=['iv.x']

        prob.setup(vector_class=PETScVector, check=False, mode='fwd')
        prob.set_solver_print(level=0)
        prob.run_model()

        J = prob.compute_totals(of=['c2.y', "c3.y"], wrt=['iv.x'])

        assert_rel_error(self, J['c2.y', 'iv.x'][0][0], -6.0, 1e-6)
        assert_rel_error(self, J['c3.y', 'iv.x'][0][0], 15.0, 1e-6)

        assert_rel_error(self, prob['c2.y'], -6.0, 1e-6)
        assert_rel_error(self, prob['c3.y'], 15.0, 1e-6)

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

        J = prob.compute_totals(of=['c2.y', "c3.y"], wrt=['iv.x'])

        assert_rel_error(self, J['c2.y', 'iv.x'][0][0], -6.0, 1e-6)
        assert_rel_error(self, J['c3.y', 'iv.x'][0][0], 15.0, 1e-6)

        assert_rel_error(self, prob['c2.y'], -6.0, 1e-6)
        assert_rel_error(self, prob['c3.y'], 15.0, 1e-6)
    def test_fan_in_grouped_feature(self):

        from openmdao.api import Problem, IndepVarComp, ParallelGroup, ExecComp, PETScVector

        prob = Problem()
        model = prob.model

        model.add_subsystem('p1', IndepVarComp('x', 1.0))
        model.add_subsystem('p2', IndepVarComp('x', 1.0))

        parallel = model.add_subsystem('parallel', ParallelGroup())
        parallel.add_subsystem('c1', ExecComp(['y=-2.0*x']))
        parallel.add_subsystem('c2', ExecComp(['y=5.0*x']))

        model.add_subsystem('c3', ExecComp(['y=3.0*x1+7.0*x2']))

        model.connect("parallel.c1.y", "c3.x1")
        model.connect("parallel.c2.y", "c3.x2")

        model.connect("p1.x", "parallel.c1.x")
        model.connect("p2.x", "parallel.c2.x")

        prob.setup(vector_class=PETScVector, check=False, mode='fwd')
        prob.set_solver_print(level=0)
        prob.run_model()

        assert_rel_error(self, prob['c3.y'], 29.0, 1e-6)
    def test_diamond(self):

        prob = Problem()
        prob.model = Diamond()
        prob.setup(vector_class=PETScVector, check=False, mode='fwd')
        prob.set_solver_print(level=0)
        prob.run_model()

        assert_rel_error(self, prob['c4.y1'], 46.0, 1e-6)
        assert_rel_error(self, prob['c4.y2'], -93.0, 1e-6)

        indep_list = ['iv.x']
        unknown_list = ['c4.y1', 'c4.y2']

        J = prob.compute_totals(of=unknown_list, wrt=indep_list)
        assert_rel_error(self, J['c4.y1', 'iv.x'][0][0], 25, 1e-6)
        assert_rel_error(self, J['c4.y2', 'iv.x'][0][0], -40.5, 1e-6)

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

        assert_rel_error(self, prob['c4.y1'], 46.0, 1e-6)
        assert_rel_error(self, prob['c4.y2'], -93.0, 1e-6)

        J = prob.compute_totals(of=unknown_list, wrt=indep_list)
        assert_rel_error(self, J['c4.y1', 'iv.x'][0][0], 25, 1e-6)
        assert_rel_error(self, J['c4.y2', 'iv.x'][0][0], -40.5, 1e-6)
class TestDeprecatedExternalCode(unittest.TestCase):

    def setUp(self):
        self.startdir = os.getcwd()
        self.tempdir = tempfile.mkdtemp(prefix='test_extcode-')
        os.chdir(self.tempdir)
        shutil.copy(os.path.join(DIRECTORY, 'extcode_example.py'),
                    os.path.join(self.tempdir, 'extcode_example.py'))

        msg = "'ExternalCode' has been deprecated. Use 'ExternalCodeComp' instead."

        with assert_warning(DeprecationWarning, msg):
            self.extcode = DeprecatedExternalCodeForTesting()

        self.prob = Problem()

        self.prob.model.add_subsystem('extcode', self.extcode)

    def tearDown(self):
        os.chdir(self.startdir)
        try:
            shutil.rmtree(self.tempdir)
        except OSError:
            pass

    def test_normal(self):
        self.extcode.options['command'] = [
            'python', 'extcode_example.py', 'extcode.out'
        ]

        self.extcode.options['external_input_files'] = ['extcode_example.py']
        self.extcode.options['external_output_files'] = ['extcode.out']

        self.prob.setup(check=True)
        self.prob.run_model()
    def test_feature_simple(self):
        """Tests feature for adding a Scipy GMRES solver and calculating the
        derivatives."""
        from openmdao.api import Problem, Group, IndepVarComp, ScipyKrylov
        from openmdao.test_suite.components.expl_comp_simple import TestExplCompSimpleDense

        # Tests derivatives on a simple comp that defines compute_jacvec.
        prob = Problem()
        model = prob.model
        model.add_subsystem('x_param', IndepVarComp('length', 3.0),
                            promotes=['length'])
        model.add_subsystem('mycomp', TestExplCompSimpleDense(),
                            promotes=['length', 'width', 'area'])

        model.linear_solver = ScipyKrylov()
        prob.set_solver_print(level=0)

        prob.setup(check=False, mode='fwd')
        prob['width'] = 2.0
        prob.run_model()

        of = ['area']
        wrt = ['length']

        J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict')
        assert_rel_error(self, J['area', 'length'][0][0], 2.0, 1e-6)
Exemple #16
0
    def runO(x):
        p = Problem()
        p.model.add_subsystem('hs', HeatSink(num_nodes=1))

        p.setup(check=False)

        p['hs.fin_gap'] = x[0]
        p['hs.fin_w'] = x[1]

        p.run_model()



        def printstuff():
            print('=============')
            print('V_in (m/s) : %f' %p['hs.V_in'])
            print('V_fin (m/s) : %f' %p['hs.V_fin'])
            print('Nu : %f' %p['hs.Nu'])
            print('Pr : %f' %p['hs.Pr'])
            print('Re : %f' %p['hs.Re'])
            print('fin height: %f' %p['hs.fin_h'])
            print('# of fins : %f' %p['hs.n_fins'])
            print('-------------')
            print('fin thickness (m): %f' % p['hs.fin_w'])
            print('fin gap (m): %f' % p['hs.fin_gap'])
            print('Volumetric Flow Rate (m^3/s): %f' % p['hs.V_dot'])
            print('Maximum thermal resistance (K/W): %f' %p['hs.R_max'])
            print('Actual total thermal resistance (K/W): %f' % p['hs.R_tot'])
            #print('Actual total thermal resistance1 (K/W): %f' % p['hs.R_tot1'])
            #print('h %f' % p['hs.h'])
            print('Pressure Drop (Pa): %f' % p['hs.dP'])
            print()
        printstuff()

        return np.array([p['hs.R_tot']*10000 + p['hs.dP']*1.4])
    def test_rk_with_time_invariant(self):
        np.random.seed(1)

        indeps = IndepVarComp()
        rktest = RKTest(NTIME)

        indeps.add_output('yi', np.random.random((2, 3)))
        indeps.add_output('yv', np.random.random((2, NTIME)))
        indeps.add_output('x0', np.random.random((2,)))

        prob = Problem()

        prob.model.add_subsystem('indeps', indeps, promotes=['*'])
        prob.model.add_subsystem('rktest', rktest, promotes=['*'])

        prob.setup()
        prob.run_model()

        # check partials
        partials = prob.check_partials(out_stream=None)
        assert_check_partials(partials, atol=6e-5, rtol=6e-5)

        # check totals
        inputs = ['yi', 'yv', 'x0']
        outputs = ['x']

        J = prob.check_totals(of=outputs, wrt=inputs, out_stream=None)

        for outp in outputs:
            for inp in inputs:
                Jn = J[outp, inp]['J_fd']
                Jf = J[outp, inp]['J_fwd']
                diff = abs(Jf - Jn)
                assert_rel_error(self, diff.max(), 0.0, 6e-5)
    def test_globaljac_err(self):
        prob = Problem()
        model = prob.model = Group()
        model.add_subsystem('x_param', IndepVarComp('length', 3.0),
                            promotes=['length'])
        model.add_subsystem('mycomp', TestExplCompSimpleDense(),
                            promotes=['length', 'width', 'area'])

        model.linear_solver = LinearBlockJac()
        prob.set_solver_print(level=0)

        prob.model.jacobian = AssembledJacobian()
        prob.setup(check=False, mode='fwd')

        prob['width'] = 2.0
        prob.run_model()

        of = ['area']
        wrt = ['length']

        with self.assertRaises(RuntimeError) as context:
            prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict')

            self.assertEqual(str(context.exception),
                             "A block linear solver 'LN: LNBJ' is being used with"
                             " an AssembledJacobian in system ''")
    def test_specify_solver(self):
        import numpy as np

        from openmdao.api import Problem, Group, IndepVarComp, ExecComp, LinearBlockJac, NonlinearBlockGS
        from openmdao.test_suite.components.sellar import SellarDis1withDerivatives, SellarDis2withDerivatives

        prob = Problem()
        model = prob.model = Group()

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

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

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

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

        model.nonlinear_solver = NonlinearBlockGS()
        model.linear_solver = LinearBlockJac()

        prob.setup()
        prob.run_model()

        wrt = ['z']
        of = ['obj']

        J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict')
        assert_rel_error(self, J['obj', 'z'][0][0], 9.61001056, .00001)
        assert_rel_error(self, J['obj', 'z'][0][1], 1.78448534, .00001)
    def test_rhs_val(self):
        """ Test solution with a default RHS value and no connected RHS variable. """

        n = 1

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

        bal = BalanceComp('x', rhs_val=4.0)

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

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

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

        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)
    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)
    def test_create_on_init_no_normalization(self):

        prob = Problem(model=Group())

        bal = BalanceComp('x', val=1.0, normalize=False)

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

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

        prob.model.linear_solver = DirectSolver()
        prob.model.nonlinear_solver = NewtonSolver(iprint=0)

        prob.setup()

        prob.run_model()

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

        assert_almost_equal(prob.model.balance._scale_factor, 1.0)

        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)
Exemple #23
0
    def test_noncontiguous_idxs(self):
        # take even input indices in 0 rank and odd ones in 1 rank
        size = 11

        p = Problem(model=Group())
        top = p.model
        C1 = top.add_subsystem("C1", InOutArrayComp(size))
        C2 = top.add_subsystem("C2", DistribNoncontiguousComp(size))
        C3 = top.add_subsystem("C3", DistribGatherComp(size))
        top.connect('C1.outvec', 'C2.invec')
        top.connect('C2.outvec', 'C3.invec')
        p.setup(check=False)

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

        C1._inputs['invec'] = np.array(range(size), float)

        p.run_model()

        if MPI:
            if self.comm.rank == 0:
                self.assertTrue(all(C2._outputs['outvec'] ==
                                    np.array(list(take_nth(0, 2, range(size))), 'f')*4))
            else:
                self.assertTrue(all(C2._outputs['outvec'] ==
                                    np.array(list(take_nth(1, 2, range(size))), 'f')*4))

            full_list = list(take_nth(0, 2, range(size))) + list(take_nth(1, 2, range(size)))
            self.assertTrue(all(C3._outputs['outvec'] == np.array(full_list, 'f')*4))
        else:
            self.assertTrue(all(C2._outputs['outvec'] == C1._outputs['outvec']*2.))
            self.assertTrue(all(C3._outputs['outvec'] == C2._outputs['outvec']))
Exemple #24
0
    def test_obj_pass(self):
        prob = Problem()
        model = prob.model

        indep = model.add_subsystem('indep', IndepVarComp(), promotes_outputs=['x'])
        indep.add_discrete_output('x', _DiscreteVal(19))

        G = model.add_subsystem('G', ParallelGroup(), promotes_inputs=['x'])

        G1 = G.add_subsystem('G1', Group(), promotes_inputs=['x'], promotes_outputs=['y'])
        G1.add_subsystem('C1_1', ObjAdderCompEx(_DiscreteVal(5)), promotes_inputs=['x'])
        G1.add_subsystem('C1_2', ObjAdderCompEx(_DiscreteVal(7)), promotes_outputs=['y'])
        G1.connect('C1_1.y', 'C1_2.x')

        G2 = G.add_subsystem('G2', Group(), promotes_inputs=['x'])
        G2.add_subsystem('C2_1', ObjAdderCompEx(_DiscreteVal(1)), promotes_inputs=['x'])
        G2.add_subsystem('C2_2', ObjAdderCompEx(_DiscreteVal(11)), promotes_outputs=['y'])
        G2.connect('C2_1.y', 'C2_2.x')

        model.add_subsystem('C3', ObjAdderCompEx(_DiscreteVal(9)))
        model.add_subsystem('C4', ObjAdderCompEx(_DiscreteVal(21)))

        model.connect('G.y', 'C3.x')
        model.connect('G.G2.y', 'C4.x')

        prob.setup()
        prob.run_model()

        self.assertEqual(prob['C3.y'].getval(), 40)
        self.assertEqual(prob['C4.y'].getval(), 52)
    def test_implicit_cycle_precon(self):
        prob = Problem()
        model = prob.model = Group()

        model.add_subsystem('p1', IndepVarComp('x', 1.0))
        model.add_subsystem('d1', SellarImplicitDis1())
        model.add_subsystem('d2', SellarImplicitDis2())
        model.connect('d1.y1', 'd2.y1')
        model.connect('d2.y2', 'd1.y2')

        model.nonlinear_solver = NewtonSolver()
        model.nonlinear_solver.options['maxiter'] = 5
        model.nonlinear_solver.linesearch = BoundsEnforceLS()
        model.linear_solver = ScipyKrylov()
        model.linear_solver.precon = self.linear_solver_class()

        prob.setup(check=False)

        prob['d1.y1'] = 4.0
        prob.set_solver_print()
        prob.run_model()
        res = model._residuals.get_norm()

        # Newton is kinda slow on this for some reason, this is how far it gets with directsolver too.
        self.assertLess(res, 2.0e-2)
Exemple #26
0
    def test_scaling(self):
        # Make sure values are unscaled/dimensional.

        def custom_method(d_outputs, d_residuals, mode):
            if d_outputs['out_var'][0] != 12.0:
                raise ValueError('This value should be unscaled.')
            return False, 0, 0


        class ScaledComp(ImplicitComponent):

            def setup(self):

                self.add_input('a', val=10., units='m')

                self.add_output('states', val=20.0, ref=3333.0)
                self.add_output('out_var', val=20.0, ref=12.0)


        p = Problem()
        p.model.add_subsystem('des_vars', IndepVarComp('a', val=10., units='m'), promotes=['*'])
        p.model.add_subsystem('icomp', ScaledComp(), promotes=['*'])
        model = p.model

        model.linear_solver = LinearUserDefined(custom_method)

        p.setup(vector_class=PETScVector, mode='rev', check=False)
        p.run_model()
        jac = p.compute_totals(of=['out_var'], wrt=['a'], return_format='dict')
    def test_detailed(self):
        """ This is a longer version of the previous method, with plotting. """

        # Load in default lifting surfaces to setup the comparison
        surfaces = get_default_surfaces()

        # Instantiate an OpenMDAO problem and add the component we want to test
        # as asubsystem, giving that component a default lifting surface
        prob = Problem()
        prob.model.add_subsystem('tube', SectionPropertiesTube(surface=surfaces[0]))

        # Set up the problem and ensure it uses complex arrays so we can check
        # the derivatives using complex step
        prob.setup(force_alloc_complex=True)

        # Actually run the model, which is just a component in this case, then
        # check the derivatives and store the results in the `check` dict
        prob.run_model()
        check = prob.check_partials(compact_print=False)

        # Loop through this `check` dictionary and visualize the approximated
        # and computed derivatives
        for key, subjac in iteritems(check[list(check.keys())[0]]):
            print()
            print(key)
            view_mat(subjac['J_fd'],subjac['J_fwd'],key)

        # Loop through the `check` dictionary and perform assert that the
        # approximated deriv must be very close to the computed deriv
        for key, subjac in iteritems(check[list(check.keys())[0]]):
            if subjac['magnitude'].fd > 1e-6:
                assert_almost_equal(
                    subjac['rel error'].forward, 0., err_msg='deriv of %s wrt %s' % key)
                assert_almost_equal(
                    subjac['rel error'].reverse, 0., err_msg='deriv of %s wrt %s' % key)
Exemple #28
0
    def test_overlapping_inputs_idxs(self):
        # distrib comp with src_indices that overlap, i.e. the same
        # entries are distributed to multiple processes
        size = 11

        p = Problem(model=Group())
        top = p.model
        C1 = top.add_subsystem("C1", InOutArrayComp(size))
        C2 = top.add_subsystem("C2", DistribOverlappingInputComp(size))
        top.connect('C1.outvec', 'C2.invec')
        p.setup(check=False)

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

        C1._inputs['invec'] = np.array(range(size, 0, -1), float)

        p.run_model()

        self.assertTrue(all(C2._outputs['outvec'][:4] == np.array(range(size, 0, -1), float)[:4]*4))
        self.assertTrue(all(C2._outputs['outvec'][8:] == np.array(range(size, 0, -1), float)[8:]*4))

        # overlapping part should be double size of the rest
        self.assertTrue(all(C2._outputs['outvec'][4:8] ==
                            np.array(range(size, 0, -1), float)[4:8]*8))
Exemple #29
0
    def test_feature_atol(self):
        import numpy as np

        from openmdao.api import Problem, Group, IndepVarComp, NewtonSolver, LinearBlockGS, ExecComp, DirectSolver
        from openmdao.test_suite.components.sellar import SellarDis1withDerivatives, SellarDis2withDerivatives

        prob = Problem()
        model = prob.model

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

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

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

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

        model.linear_solver = DirectSolver()

        nlgbs = model.nonlinear_solver = NewtonSolver()
        nlgbs.options['atol'] = 1e-4

        prob.setup()

        prob.run_model()

        assert_rel_error(self, prob['y1'], 25.5882856302, .00001)
        assert_rel_error(self, prob['y2'], 12.05848819, .00001)
    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)
Exemple #31
0
def main():
    interp = ViternaAirfoil().create_akima('mh117',
                                           Re_scaling=False,
                                           extend_alpha=True)

    def ccblade_interp(alpha, Re, Mach):
        shape = alpha.shape
        x = np.concatenate(
            [alpha.flatten()[:, np.newaxis],
             Re.flatten()[:, np.newaxis]],
            axis=-1)
        y = interp(x)
        y.shape = shape + (2, )
        return y[..., 0], y[..., 1]

    num_nodes = 1
    num_blades = 3
    num_radial = 15
    num_cp = 6
    chord = 10.
    theta = np.linspace(65., 25., num_cp) * np.pi / 180.
    pitch = 0.

    hub_diameter = 30.  # cm
    prop_diameter = 150.  # cm
    c0 = np.sqrt(1.4 * 287.058 * 300.)  # meters/second
    rho0 = 1.4 * 98600. / (c0 * c0)  # kg/m^3
    omega = 236.

    prob = Problem()

    comp = IndepVarComp()
    comp.add_discrete_input('B', val=num_blades)
    comp.add_output('rho', val=rho0, shape=num_nodes, units='kg/m**3')
    comp.add_output('mu', val=1., shape=num_nodes, units='N/m**2*s')
    comp.add_output('asound', val=c0, shape=num_nodes, units='m/s')
    comp.add_output('v', val=77.2, shape=num_nodes, units='m/s')
    comp.add_output('alpha', val=0., shape=num_nodes, units='rad')
    comp.add_output('incidence', val=0., shape=num_nodes, units='rad')
    comp.add_output('precone', val=0., units='deg')
    comp.add_output('omega', val=omega, shape=num_nodes, units='rad/s')
    comp.add_output('hub_diameter',
                    val=hub_diameter,
                    shape=num_nodes,
                    units='cm')
    comp.add_output('prop_diameter',
                    val=prop_diameter,
                    shape=num_nodes,
                    units='cm')
    comp.add_output('pitch', val=pitch, shape=num_nodes, units='rad')
    comp.add_output('chord_dv', val=chord, shape=num_cp, units='cm')
    comp.add_output('theta_dv', val=theta, shape=num_cp, units='rad')
    prob.model.add_subsystem('inputs_comp', comp, promotes=['*'])

    comp = GeometryGroup(num_nodes=num_nodes,
                         num_cp=num_cp,
                         num_radial=num_radial)
    prob.model.add_subsystem(
        'geometry_group',
        comp,
        promotes_inputs=[
            'hub_diameter', 'prop_diameter', 'chord_dv', 'theta_dv', 'pitch'
        ],
        promotes_outputs=['radii', 'dradii', 'chord', 'theta'])

    comp = CCBladeGroup(num_nodes=num_nodes,
                        num_radial=num_radial,
                        airfoil_interp=ccblade_interp,
                        turbine=False,
                        phi_residual_solve_nonlinear=False)
    prob.model.add_subsystem('ccblade_group',
                             comp,
                             promotes_inputs=[
                                 'B', 'radii', 'dradii', 'chord', 'theta',
                                 'rho', 'mu', 'asound', 'v', 'precone',
                                 'omega', 'hub_diameter', 'prop_diameter'
                             ],
                             promotes_outputs=[('Np', 'ccblade_normal_load'),
                                               ('Tp', 'ccblade_circum_load')])

    prob.setup()
    prob.final_setup()

    eps = 1e-2
    num_phi = 45
    phi = np.linspace(-0.5 * np.pi + eps, 0.0 - eps, num_phi)
    phi = np.tile(phi[:, np.newaxis, np.newaxis], (1, num_nodes, num_radial))
    phi_residual = np.zeros_like(phi)

    for i in range(num_phi):
        p = phi[i, :, :]

        prob.set_val('ccblade_group.ccblade_comp.phi', p, units='rad')
        prob.run_model()
        prob.model.run_apply_nonlinear()
        inputs, outputs, residuals = prob.model.get_nonlinear_vectors()
        phi_residual[i, :, :] = residuals['ccblade_group.ccblade_comp.phi']

    make_individual_plots(prob, phi, phi_residual, 'phi_residual-r{:02d}.png')
Exemple #32
0
 def test_simple(self):
     prob = Problem(RectangleComp())
     prob.setup(check=False)
     prob.run_model()
    def support_design_model(self, TIs, depths):
        #  Redefine method in subclass of AbstractSupportStructureDesign with specific model that has same inputs and outputs.
        pass


if __name__ == '__main__':
    from openmdao.api import Problem, Group, IndepVarComp

    class TeamPlay(AbstractSupportStructureDesign):
        def compute(self, inputs, outputs):
            TI = inputs['TI']
            depth = inputs['depth']
            outputs['cost_support'] = TI * depth**3.0

    model = Group()
    ivc = IndepVarComp()

    ivc.add_output('TI', 0.12)
    ivc.add_output('depth', 14.0)

    model.add_subsystem('indep', ivc)
    model.add_subsystem('teamplay', TeamPlay())

    model.connect('indep.TI', 'teamplay.TI')
    model.connect('indep.depth', 'teamplay.depth')

    prob = Problem(model)
    prob.setup()
    prob.run_model()
    print(prob['teamplay.cost_support'])
    def test_fan_out_grouped(self):
        size = 3
        prob = Problem()
        prob.model = root = Group()
        root.add_subsystem('P', IndepVarComp('x', numpy.ones(size,
                                                             dtype=float)))
        root.add_subsystem(
            'C1',
            DistribExecComp(['y=3.0*x', 'y=2.0*x'],
                            arr_size=size,
                            x=numpy.zeros(size, dtype=float),
                            y=numpy.zeros(size, dtype=float)))
        sub = root.add_subsystem('sub', ParallelGroup())
        sub.add_subsystem(
            'C2', ExecComp('y=1.5*x', x=numpy.zeros(size),
                           y=numpy.zeros(size)))
        sub.add_subsystem(
            'C3',
            ExecComp(['y=5.0*x'],
                     x=numpy.zeros(size, dtype=float),
                     y=numpy.zeros(size, dtype=float)))

        root.add_subsystem(
            'C2',
            ExecComp(['y=x'],
                     x=numpy.zeros(size, dtype=float),
                     y=numpy.zeros(size, dtype=float)))
        root.add_subsystem(
            'C3',
            ExecComp(['y=x'],
                     x=numpy.zeros(size, dtype=float),
                     y=numpy.zeros(size, dtype=float)))
        root.connect('sub.C2.y', 'C2.x')
        root.connect('sub.C3.y', 'C3.x')

        root.connect("C1.y", "sub.C2.x")
        root.connect("C1.y", "sub.C3.x")
        root.connect("P.x", "C1.x")

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

        diag1 = [4.5, 4.5, 3.0]
        diag2 = [15.0, 15.0, 10.0]

        assert_rel_error(self, prob['C2.y'], diag1)
        assert_rel_error(self, prob['C3.y'], diag2)

        diag1 = numpy.diag(diag1)
        diag2 = numpy.diag(diag2)

        J = prob.compute_totals(of=['C2.y', "C3.y"], wrt=['P.x'])
        assert_rel_error(self, J['C2.y', 'P.x'], diag1, 1e-6)
        assert_rel_error(self, J['C3.y', 'P.x'], diag2, 1e-6)

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

        J = prob.compute_totals(of=['C2.y', "C3.y"], wrt=['P.x'])
        assert_rel_error(self, J['C2.y', 'P.x'], diag1, 1e-6)
        assert_rel_error(self, J['C3.y', 'P.x'], diag2, 1e-6)
Exemple #35
0
    def test(self):
        p = Problem()

        p.model = Group()
        p.model.add_subsystem('c1',
                              IndepVarComp('x', 1.0),
                              promotes_outputs=['x'])
        p.model.add_subsystem('c2',
                              ReconfComp(),
                              promotes_inputs=['x'],
                              promotes_outputs=['y'])
        p.model.add_subsystem('c3',
                              Comp(),
                              promotes_inputs=['x'],
                              promotes_outputs=['z'])

        # First run the usual setup method on Problem; size of y = 1
        p.setup()
        p['x'] = 2
        p.run_model()
        totals = p.compute_totals(wrt=['x'], of=['y'])
        assert_rel_error(self, p['x'], 2.0)
        assert_rel_error(self, p['y'], 4.0)
        assert_rel_error(self, p['z'], 6.0)
        assert_rel_error(self, totals['y', 'x'], [[2.0]])

        # Now run the setup method on the root system; size of y = 2
        p.model.resetup()
        p['x'] = 3
        p.run_model()
        totals = p.compute_totals(wrt=['x'], of=['y'])
        assert_rel_error(self, p['x'], 3.0)
        assert_rel_error(self, p['y'], 6.0 * np.ones(2))
        assert_rel_error(self, p['z'], 9.0)
        assert_rel_error(self, totals['y', 'x'], 2.0 * np.ones((2, 1)))

        # Now reconfigure from c2 and update in root; size of y = 3; the value of x is preserved
        p.model.get_subsystem('c2').resetup('reconf')
        p.model.resetup('update')
        p.run_model()
        totals = p.compute_totals(wrt=['x'], of=['y'])
        assert_rel_error(self, p['x'], 3.0)
        assert_rel_error(self, p['y'], 6.0 * np.ones(3))
        assert_rel_error(self, p['z'], 9.0)
        assert_rel_error(self, totals['y', 'x'], 2.0 * np.ones((3, 1)))

        # Now reconfigure from c3 and update in root; size of y = 3; the value of x is preserved
        p.model.get_subsystem('c3').resetup('reconf')
        p.model.resetup('update')
        p.run_model()
        totals = p.compute_totals(wrt=['x'], of=['y'])
        assert_rel_error(self, p['x'], 3.0)
        assert_rel_error(self, p['y'], 6.0 * np.ones(3))
        assert_rel_error(self, p['z'], 9.0)
        assert_rel_error(self, totals['y', 'x'], 2.0 * np.ones((3, 1)))

        # Finally, setup reconf from root; size of y = 4
        # Since we are at the root, calling setup('full') and setup('reconf') have the same effect.
        # In both cases, variable values are lost so we have to set x=3 again.
        p.model.resetup('reconf')
        p['x'] = 3
        p.run_model()
        totals = p.compute_totals(wrt=['x'], of=['y'])
        assert_rel_error(self, p['x'], 3.0)
        assert_rel_error(self, p['y'], 6.0 * np.ones(4))
        assert_rel_error(self, p['z'], 9.0)
        assert_rel_error(self, totals['y', 'x'], 2.0 * np.ones((4, 1)))
    def test_distribcomp_feature(self):
        import numpy as np

        from openmdao.api import Problem, ExplicitComponent, Group, IndepVarComp
        from openmdao.utils.mpi import MPI
        from openmdao.utils.array_utils import evenly_distrib_idxs

        if not MPI:
            raise unittest.SkipTest()

        rank = MPI.COMM_WORLD.rank
        size = 15

        class DistribComp(ExplicitComponent):
            def __init__(self, size):
                super(DistribComp, self).__init__()
                self.size = size
                self.options['distributed'] = True

            def compute(self, inputs, outputs):
                if self.comm.rank == 0:
                    outputs['outvec'] = inputs['invec'] * 2.0
                else:
                    outputs['outvec'] = inputs['invec'] * -3.0

            def setup(self):
                comm = self.comm
                rank = comm.rank

                # results in 8 entries for proc 0 and 7 entries for proc 1 when using 2 processes.
                sizes, offsets = evenly_distrib_idxs(comm.size, self.size)
                start = offsets[rank]
                end = start + sizes[rank]

                self.add_input('invec',
                               np.ones(sizes[rank], float),
                               src_indices=np.arange(start, end, dtype=int))
                self.add_output('outvec', np.ones(sizes[rank], float))

        class Summer(ExplicitComponent):
            """Sums a distributed input."""
            def __init__(self, size):
                super(Summer, self).__init__()
                self.size = size

            def setup(self):
                # this results in 8 entries for proc 0 and 7 entries for proc 1
                # when using 2 processes.
                sizes, offsets = evenly_distrib_idxs(self.comm.size, self.size)
                start = offsets[rank]
                end = start + sizes[rank]

                # NOTE: you must specify src_indices here for the input. Otherwise,
                #       you'll connect the input to [0:local_input_size] of the
                #       full distributed output!
                self.add_input('invec',
                               np.ones(sizes[self.comm.rank], float),
                               src_indices=np.arange(start, end, dtype=int))
                self.add_output('out', 0.0)

            def compute(self, inputs, outputs):
                data = np.zeros(1)
                data[0] = np.sum(self._inputs['invec'])
                total = np.zeros(1)
                self.comm.Allreduce(data, total, op=MPI.SUM)
                self._outputs['out'] = total[0]

        p = Problem(model=Group())
        top = p.model
        top.add_subsystem("indep", IndepVarComp('x', np.zeros(size)))
        top.add_subsystem("C2", DistribComp(size))
        top.add_subsystem("C3", Summer(size))

        top.connect('indep.x', 'C2.invec')
        top.connect('C2.outvec', 'C3.invec')

        p.setup()

        p['indep.x'] = np.ones(size)

        p.run_model()

        assert_rel_error(self, p['C3.out'], -5.)
    def test_distrib_idx_in_full_out_deprecated(self):
        class DeprecatedDistribInputComp(ExplicitComponent):
            """Deprecated version of DistribInputComp, uses attribute instead of option."""
            def __init__(self, arr_size=11):
                super(DeprecatedDistribInputComp, self).__init__()
                self.arr_size = arr_size
                self.distributed = True

            def compute(self, inputs, outputs):
                if MPI:
                    self.comm.Allgatherv(inputs['invec'] * 2.0, [
                        outputs['outvec'], self.sizes, self.offsets, MPI.DOUBLE
                    ])
                else:
                    outputs['outvec'] = inputs['invec'] * 2.0

            def setup(self):
                comm = self.comm
                rank = comm.rank

                self.sizes, self.offsets = evenly_distrib_idxs(
                    comm.size, self.arr_size)
                start = self.offsets[rank]
                end = start + self.sizes[rank]

                self.add_input('invec',
                               np.ones(self.sizes[rank], float),
                               src_indices=np.arange(start, end, dtype=int))
                self.add_output('outvec',
                                np.ones(self.arr_size, float),
                                shape=np.int32(self.arr_size))

        size = 11

        p = Problem()
        top = p.model

        C1 = top.add_subsystem("C1", InOutArrayComp(size))

        # check deprecation on setter
        msg = "The 'distributed' property provides backwards compatibility " \
              "with OpenMDAO <= 2.4.0 ; use the 'distributed' option instead."

        with warnings.catch_warnings(record=True) as w:
            C2 = top.add_subsystem("C2", DeprecatedDistribInputComp(size))

        self.assertEqual(len(w), 1)
        self.assertTrue(issubclass(w[0].category, DeprecationWarning))
        self.assertEqual(str(w[0].message), msg)

        # check deprecation on getter
        with warnings.catch_warnings(record=True) as w:
            C2.distributed

        self.assertEqual(len(w), 1)
        self.assertTrue(issubclass(w[0].category, DeprecationWarning))
        self.assertEqual(str(w[0].message), msg)

        # continue to make sure everything still works with the deprecation
        top.connect('C1.outvec', 'C2.invec')

        # Conclude setup but don't run model.
        with warnings.catch_warnings(record=True) as w:
            p.setup(check=False)

        if PETScVector is None:
            self.assertEqual(len(w), 1)
            self.assertTrue(issubclass(w[0].category, UserWarning))
            self.assertEqual(
                str(w[0].message),
                "The 'distributed' option is set to True for Component C2, "
                "but there is no distributed vector implementation (MPI/PETSc) "
                "available. The default non-distributed vectors will be used.")

        p.final_setup()

        C1._inputs['invec'] = np.array(range(size, 0, -1), float)

        p.run_model()

        self.assertTrue(
            all(C2._outputs['outvec'] == np.array(range(size, 0, -1), float) *
                4))
Exemple #38
0
    def test_group_assembled_jac_with_ext_mat(self):
        class TwoSellarDis1(ExplicitComponent):
            """
            Component containing Discipline 1 -- no derivatives version.
            """
            def setup(self):
                self.add_input('z', val=np.zeros(2))
                self.add_input('x', val=np.zeros(2))
                self.add_input('y2', val=np.ones(2))
                self.add_output('y1', val=np.ones(2))

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

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

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

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

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

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

            def compute(self, inputs, outputs):

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

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

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

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

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

        prob = Problem()
        model = prob.model

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

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

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

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

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

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

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

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

        # Make sure we don't get a size mismatch.
        derivs = prob.compute_totals(of=of, wrt=wrt)
Exemple #39
0
    def test_guess_nonlinear_complex_step(self):
        class ImpWithInitial(ImplicitComponent):
            """
            An implicit component to solve the quadratic equation: x^2 - 4x + 3
            (solutions at x=1 and x=3)
            """
            def setup(self):
                self.add_input('a', val=1.)
                self.add_input('b', val=-4.)
                self.add_input('c', val=3.)

                self.add_output('x', val=0.)

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

            def apply_nonlinear(self, inputs, outputs, residuals):
                a = inputs['a']
                b = inputs['b']
                c = inputs['c']
                x = outputs['x']
                residuals['x'] = a * x**2 + b * x + c

            def linearize(self, inputs, outputs, partials):
                a = inputs['a']
                b = inputs['b']
                c = inputs['c']
                x = outputs['x']

                partials['x', 'a'] = x**2
                partials['x', 'b'] = x
                partials['x', 'c'] = 1.0
                partials['x', 'x'] = 2 * a * x + b

            def guess_nonlinear(self, inputs, outputs, resids):

                if outputs._data.dtype == np.complex:
                    raise RuntimeError(
                        'Vector should not be complex when guess_nonlinear is called.'
                    )

                # Default initial state of zero for x takes us to x=1 solution.
                # Here we set it to a value that will take us to the x=3 solution.
                outputs['x'] = 5.0

        prob = Problem()
        model = prob.model = Group()

        indep = IndepVarComp()
        indep.add_output('a', 1.0)
        indep.add_output('b', -4.0)
        indep.add_output('c', 3.0)
        model.add_subsystem('p', indep)
        model.add_subsystem('comp', ImpWithInitial())
        model.add_subsystem('fn',
                            ExecComp(['y = .03*a*x*x - .04*a*a*b*x - c']))

        model.connect('p.a', 'comp.a')
        model.connect('p.a', 'fn.a')
        model.connect('p.b', 'fn.b')
        model.connect('p.c', 'fn.c')
        model.connect('comp.x', 'fn.x')

        model.nonlinear_solver = NewtonSolver()
        model.nonlinear_solver.options['rtol'] = 1e-12
        model.nonlinear_solver.options['atol'] = 1e-12
        model.nonlinear_solver.options['maxiter'] = 15
        model.linear_solver = ScipyKrylov()

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

        assert_rel_error(self, prob['comp.x'], 3.)

        totals = prob.check_totals(of=['fn.y'],
                                   wrt=['p.a'],
                                   method='cs',
                                   out_stream=None)

        for key, val in iteritems(totals):
            assert_rel_error(self, val['rel error'][0], 0.0, 1e-9)
Exemple #40
0
    def test_assembled_jacobian_unsupported_cases(self):
        class ParaboloidApply(ImplicitComponent):
            def setup(self):
                self.add_input('x', val=0.0)
                self.add_input('y', val=0.0)

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

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

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

        # One level deep

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

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

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

        prob.setup()

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

        # Nested

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

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

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

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

        prob.setup()

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

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

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

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

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

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

        prob.setup()

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

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

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

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

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

        prob.setup()
        prob.final_setup()

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

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

        # One level deep

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

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

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

        prob.setup()

        msg = "AssembledJacobian not supported for matrix-free subcomponent."
        with self.assertRaisesRegex(Exception, msg):
            prob.run_model()
    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()

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

        # Use M (mean anomaly) as the initial guess for E (eccentric anomaly)
        def guess_function(inputs, outputs, residuals):
            outputs['E'] = inputs['M']

        bal.options['guess_func'] = guess_function

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

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

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

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

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

        # Set up solvers
        prob.model.linear_solver = DirectSolver()
        prob.model.nonlinear_solver = NewtonSolver(maxiter=100, 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)
Exemple #42
0
    def test_csc_masking(self):
        class CCBladeResidualComp(ImplicitComponent):
            def initialize(self):
                self.options.declare('num_nodes', types=int)
                self.options.declare('num_radial', types=int)

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

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

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

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

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

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

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

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

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

        prob = Problem()
        model = prob.model

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

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

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

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

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

        np.testing.assert_allclose(totals, expected)
Exemple #43
0
        super(EngUnitStaticProps, self).setup()


if __name__ == "__main__":

    from openmdao.api import Problem, Group, IndepVarComp
    from pycycle.cea import species_data

    thermo = species_data.Thermo(species_data.co2_co_o2)

    p = Problem()
    model = p.model = Group()
    indep = model.add_subsystem('indep', IndepVarComp(), promotes=['*'])
    # indep.add_output('T', val=100., units='degK')
    # indep.add_output('P', val=1., units='bar')
    indep.add_output('T', val=100., units='degR')
    indep.add_output('P', val=1., units='psi')

    model.add_subsystem('units', EngUnitProps(thermo=thermo), promotes=['*'])

    p.setup()

    p.run_model()

    p.model.run_linearize()
    jac = p.model.get_subsystem('units').jacobian._subjacs

    for pair in jac:
        print(pair)
        print(jac[pair])
        print()
Exemple #44
0
    def test_simple_list_vars_options(self):
        from openmdao.api import Group, Problem, IndepVarComp

        class QuadraticComp(ImplicitComponent):
            """
            A Simple Implicit Component representing a Quadratic Equation.

            R(a, b, c, x) = ax^2 + bx + c

            Solution via Quadratic Formula:
            x = (-b + sqrt(b^2 - 4ac)) / 2a
            """
            def setup(self):
                self.add_input('a', val=1., units='ft')
                self.add_input('b', val=1., units='inch')
                self.add_input('c', val=1., units='ft')
                self.add_output('x',
                                val=0.,
                                lower=1.0,
                                upper=100.0,
                                ref=1.1,
                                ref0=2.1,
                                units='inch')

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

            def apply_nonlinear(self, inputs, outputs, residuals):
                a = inputs['a']
                b = inputs['b']
                c = inputs['c']
                x = outputs['x']
                residuals['x'] = a * x**2 + b * x + c

            def solve_nonlinear(self, inputs, outputs):
                a = inputs['a']
                b = inputs['b']
                c = inputs['c']
                outputs['x'] = (-b + (b**2 - 4 * a * c)**0.5) / (2 * a)

        group = Group()

        comp1 = group.add_subsystem('comp1', IndepVarComp())
        comp1.add_output('a', 1.0, units='ft')
        comp1.add_output('b', 1.0, units='inch')
        comp1.add_output('c', 1.0, units='ft')

        sub = group.add_subsystem('sub', Group())
        sub.add_subsystem('comp2', QuadraticComp())
        sub.add_subsystem('comp3', QuadraticComp())

        group.connect('comp1.a', 'sub.comp2.a')
        group.connect('comp1.b', 'sub.comp2.b')
        group.connect('comp1.c', 'sub.comp2.c')

        group.connect('comp1.a', 'sub.comp3.a')
        group.connect('comp1.b', 'sub.comp3.b')
        group.connect('comp1.c', 'sub.comp3.c')

        global prob
        prob = Problem(model=group)
        prob.setup()

        prob['comp1.a'] = 1.
        prob['comp1.b'] = -4.
        prob['comp1.c'] = 3.
        prob.run_model()

        # list_inputs test
        stream = cStringIO()
        inputs = prob.model.list_inputs(values=False, out_stream=stream)
        text = stream.getvalue()
        self.assertEqual(sorted(inputs), [
            ('sub.comp2.a', {}),
            ('sub.comp2.b', {}),
            ('sub.comp2.c', {}),
            ('sub.comp3.a', {}),
            ('sub.comp3.b', {}),
            ('sub.comp3.c', {}),
        ])
        self.assertEqual(1, text.count("6 Input(s) in 'model'"))
        self.assertEqual(1, text.count("top"))
        self.assertEqual(1, text.count("  sub"))
        self.assertEqual(1, text.count("    comp2"))
        self.assertEqual(2, text.count("      a"))
        num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()])
        self.assertEqual(num_non_empty_lines, 14)

        # list_outputs tests
        # list implicit outputs
        outputs = prob.model.list_outputs(explicit=False, out_stream=None)
        text = stream.getvalue()
        self.assertEqual(sorted(outputs), [('sub.comp2.x', {
            'value': [3.]
        }), ('sub.comp3.x', {
            'value': [3.]
        })])
        # list explicit outputs
        stream = cStringIO()
        outputs = prob.model.list_outputs(implicit=False, out_stream=None)
        self.assertEqual(sorted(outputs), [
            ('comp1.a', {
                'value': [1.]
            }),
            ('comp1.b', {
                'value': [-4.]
            }),
            ('comp1.c', {
                'value': [3.]
            }),
        ])
Exemple #45
0
    def test_turbine_cooling(self):
        """test the flow calculations and final temperatures for multiple rows"""
        p = Problem()
        # p = self.prob

        # n_init = np.array([3.23319258e-04, 1.00000000e-10, 1.10131241e-05, 1.00000000e-10,
        #                    1.63212420e-10, 6.18813039e-09, 1.00000000e-10, 2.69578835e-02,
        #                    1.00000000e-10, 7.23198770e-03])

        # need ivc here, because b0 is shape_by_conn
        b0_air = [
            3.23319258e-04, 1.10132241e-05, 5.39157736e-02, 1.44860147e-02
        ]
        b0_mix = [0.00031378, 0.00211278, 0.00420881, 0.05232509, 0.01405863]
        ivc = p.model.add_subsystem('ivc', IndepVarComp())
        ivc.add_output('air_composition', b0_air)
        ivc.add_output('mix_composition', b0_mix)

        # p.model.set_input_defaults('turb_cool.Fl_cool:tot:composition', val=b0_air)  # product ratios for clean air
        p.model.set_input_defaults('turb_cool.turb_pwr',
                                   val=24193.5,
                                   units='hp')
        p.model.set_input_defaults('turb_cool.Fl_turb_I:tot:P',
                                   val=616.736,
                                   units='psi')
        p.model.set_input_defaults('turb_cool.Fl_turb_O:tot:P',
                                   val=149.113,
                                   units='psi')
        p.model.set_input_defaults('turb_cool.Fl_turb_I:stat:W',
                                   val=62.15,
                                   units='lbm/s')
        p.model.set_input_defaults('turb_cool.Fl_turb_I:tot:T',
                                   val=3400.00,
                                   units='degR')
        p.model.set_input_defaults('turb_cool.Fl_cool:tot:T',
                                   val=1721.97,
                                   units='degR')
        p.model.set_input_defaults('turb_cool.Fl_turb_I:tot:h',
                                   val=250.097,
                                   units='Btu/lbm')
        p.model.set_input_defaults('turb_cool.Fl_cool:tot:h',
                                   val=298.48,
                                   units='Btu/lbm')

        cool_comp = p.model.add_subsystem(
            'turb_cool',
            cooling.TurbineCooling(n_stages=2,
                                   T_metal=2460.,
                                   T_safety=150.,
                                   thermo_method='CEA',
                                   thermo_data=species_data.janaf))

        cool_comp.Fl_I_data['Fl_turb_I'] = CEA_AIR_FUEL_COMPOSITION
        cool_comp.Fl_I_data['Fl_cool'] = CEA_AIR_COMPOSITION
        cool_comp.Fl_I_data['Fl_turb_O'] = CEA_AIR_FUEL_COMPOSITION
        cool_comp.pyc_setup_output_ports()

        p.model.connect('ivc.mix_composition', [
            'turb_cool.Fl_turb_I:tot:composition',
            'turb_cool.Fl_turb_I:stat:composition'
        ])
        p.model.connect('ivc.mix_composition', [
            'turb_cool.Fl_turb_O:tot:composition',
            'turb_cool.Fl_turb_O:stat:composition'
        ])
        p.model.connect('ivc.air_composition', [
            'turb_cool.Fl_cool:tot:composition',
            'turb_cool.Fl_cool:stat:composition'
        ])

        p.setup()
        p.set_solver_print(0)

        p.set_val('turb_cool.x_factor', .9)

        p.run_model()

        tol = 4e-4

        assert_near_equal(p['turb_cool.row_0.Fl_O:tot:T'], 3299.28, tol)
        assert_near_equal(p['turb_cool.row_1.Fl_O:tot:T'], 2846.45, tol)
        assert_near_equal(p['turb_cool.row_2.Fl_O:tot:T'], 2821.58, tol)
        assert_near_equal(p['turb_cool.row_3.Fl_O:tot:T'], 2412.12, tol)

        assert_near_equal(p['turb_cool.row_0.W_cool'], 4.44635, tol)
        assert_near_equal(p['turb_cool.row_1.W_cool'][0], 2.2981, tol)
        assert_near_equal(p['turb_cool.row_2.W_cool'], 1.7079, tol)
        assert_near_equal(p['turb_cool.row_3.W_cool'][0], 0.91799, tol)

        np.set_printoptions(precision=5)
        check = p.check_partials(includes=[
            'turb_cool.row_0.cooling_calcs', 'turb_cool.row_1.cooling_calcs'
        ],
                                 out_stream=None)

        assert_check_partials(check, atol=1e-6, rtol=1e2)
Exemple #46
0
    def test_case_sanity_check(self):

        p = Problem()

        params = p.model.add_subsystem('params',
                                       IndepVarComp(),
                                       promotes=['*'])
        params.add_output('MN', val=0.8)
        params.add_output('alt', val=35000., units='ft')
        params.add_output('W', val=15., units='lbm/s')

        p.model.add_subsystem('fc',
                              FlightConditions(),
                              promotes_inputs=['MN', 'alt', 'W'])

        p.model.add_subsystem(
            'cfd_start',
            CFDStart())  #, promotes_inputs=['Ps', 'V', 'area', 'W'])
        p.model.connect('fc.Fl_O:stat:P', 'cfd_start.Ps')
        p.model.connect('fc.Fl_O:stat:area', 'cfd_start.area')
        p.model.connect('fc.Fl_O:stat:V', 'cfd_start.V')
        p.model.connect('fc.Fl_O:stat:W', 'cfd_start.W')
        p.set_solver_print(level=-1)
        # p.set_solver_print(level=2, depth=1)
        p.setup(check=False)
        p.run_model()

        tol = 1e-6
        assert_rel_error(self, p['cfd_start.Fl_O:tot:P'], p['fc.Fl_O:tot:P'],
                         tol)
        assert_rel_error(self, p['cfd_start.Fl_O:tot:T'], p['fc.Fl_O:tot:T'],
                         tol)
        assert_rel_error(self, p['cfd_start.Fl_O:tot:h'], p['fc.Fl_O:tot:h'],
                         tol)
        assert_rel_error(self, p['cfd_start.Fl_O:tot:S'], p['fc.Fl_O:tot:S'],
                         tol)
        assert_rel_error(self, p['cfd_start.Fl_O:tot:gamma'],
                         p['fc.Fl_O:tot:gamma'], tol)

        p['MN'] = 1.2
        p['alt'] = 50000.
        p['W'] = 125.

        p.run_model()

        tol = 1e-6
        assert_rel_error(self, p['cfd_start.Fl_O:tot:P'], p['fc.Fl_O:tot:P'],
                         tol)
        assert_rel_error(self, p['cfd_start.Fl_O:tot:T'], p['fc.Fl_O:tot:T'],
                         tol)
        assert_rel_error(self, p['cfd_start.Fl_O:tot:h'], p['fc.Fl_O:tot:h'],
                         tol)
        assert_rel_error(self, p['cfd_start.Fl_O:tot:S'], p['fc.Fl_O:tot:S'],
                         tol)
        assert_rel_error(self, p['cfd_start.Fl_O:tot:gamma'],
                         p['fc.Fl_O:tot:gamma'], tol)

        p['MN'] = 0.25
        p['alt'] = 100.
        p['W'] = 12.

        # needs some initial guesses or it won't converge
        p['cfd_start.balance.P'] = 14
        p['cfd_start.balance.T'] = 300
        p['cfd_start.balance.MN'] = .2

        p.run_model()

        tol = 5e-3
        assert_rel_error(self, p['cfd_start.Fl_O:tot:P'], p['fc.Fl_O:tot:P'],
                         tol)
        assert_rel_error(self, p['cfd_start.Fl_O:tot:T'], p['fc.Fl_O:tot:T'],
                         tol)
        assert_rel_error(self, p['cfd_start.Fl_O:tot:h'], p['fc.Fl_O:tot:h'],
                         tol)
        assert_rel_error(self, p['cfd_start.Fl_O:tot:S'], p['fc.Fl_O:tot:S'],
                         tol)
        assert_rel_error(self, p['cfd_start.Fl_O:tot:gamma'],
                         p['fc.Fl_O:tot:gamma'], tol)
class ConditionalComponent(ExplicitComponent):
    def initialize(self):
        self.options.declare('out_name', types=str)
        self.options.declare('condition', types=Variable)
        self.options.declare('expr_true', types=Variable)
        self.options.declare('expr_false', types=Variable)
        self.options.declare('n2', types=bool, default=False)
        self.condition = Problem()
        self.condition.model = Group()
        self.ptrue = Problem()
        self.ptrue.model = Group()
        self.pfalse = Problem()
        self.pfalse.model = Group()

        # self.all_outputs: Set[str] = set()
        self.in_exprs_condition: Dict[Set[Input]] = dict()
        self.in_exprs_true: Dict[Set[Input]] = dict()
        self.in_exprs_false: Dict[Set[Input]] = dict()

        self.derivs = dict()

    # TODO: allow condition to be an input
    # TODO: check number of expressions for expr_true, expr_false
    def setup(self):
        out_name = self.options['out_name']
        condition = self.options['condition']
        if isinstance(condition, Input):
            raise TypeError("Condition must not be an Input object")
        expr_true = self.options['expr_true']
        if isinstance(expr_true, Input):
            raise TypeError(
                "Variable object to evaluate when condition is TRUE must not be an Input object"
            )
        expr_false = self.options['expr_false']
        if isinstance(expr_false, Input):
            raise TypeError(
                "Variable object to evaluate when condition is FALSE must not be an Input object"
            )

        if expr_true.shape != expr_false.shape:
            raise ValueError(
                "Variable shapes must be the same for Variable objects for both branches of execution"
            )

        self.add_output(
            out_name,
            shape=expr_true.shape,
            val=expr_true.val,
        )

        # collect input expressions for all three problems
        self.in_exprs_condition = set(
            collect_input_exprs([], condition, condition))
        self.in_exprs_true = set(collect_input_exprs([], expr_true, expr_true))
        self.in_exprs_false = set(
            collect_input_exprs([], expr_false, expr_false))

        # TODO: enable multiple outputs
        # self.all_inputs[out_name] = in_exprs
        # self.all_outputs = self.all_outputs.union({out_name})

        # add inputs, declare partials (out wrt in)
        for in_expr in set(self.in_exprs_condition, self.in_exprs_true,
                           self.in_exprs_false):
            if in_expr.name != out_name:
                self.add_input(
                    in_expr.name,
                    shape=in_expr.shape,
                    val=in_expr.val,
                )
                self.declare_partials(
                    of=out_name,
                    wrt=in_expr.name,
                )

        # setup response variables
        self.condition.model.add_constraint(condition.name)
        self.ptrue.model.add_constraint(expr_true.name)
        self.pfalse.model.add_constraint(expr_false.name)

        # setup input variables
        for in_expr in self.in_exprs_condition:
            in_name = in_expr.name
            if in_name in self.condition.model._design_vars or in_name in self.condition.model._static_design_vars:
                pass
            else:
                self.condition.model.add_design_var(in_name)
        for in_expr in self.in_exprs_true:
            in_name = in_expr.name
            if in_name in self.ptrue.model._design_vars or in_name in self.ptrue.model._static_design_vars:
                pass
            else:
                self.ptrue.model.add_design_var(in_name)
        for in_expr in self.in_exprs_false:
            in_name = in_expr.name
            if in_name in self.pfalse.model._design_vars or in_name in self.pfalse.model._static_design_vars:
                pass
            else:
                self.pfalse.model.add_design_var(in_name)

        # setup internal problems
        self.condition.model._root = deepcopy(condition)
        self.condition.setup()
        self.ptrue.model._root = deepcopy(expr_true)
        self.ptrue.setup()
        self.pfalse.model._root = deepcopy(expr_false)
        self.pfalse.setup()

        # create n2 diagram of internal model for debugging
        if self.options['n2'] == True:
            self.ptrue.run_model()
            self.ptrue.model.list_inputs()
            self.ptrue.model.list_outputs()
            self.pfalse.run_model()
            self.pfalse.model.list_inputs()
            self.pfalse.model.list_outputs()
            from openmdao.api import n2
            # TODO: check that two n2 diagrams are created, make sure
            # both show up in docs
            n2(self.ptrue)
            n2(self.pfalse)

    def _set_values(self, inputs):
        for in_expr in self.in_exprs_condition:
            self.condition[in_expr.name] = inputs[in_expr.name]
        for in_expr in self.in_exprs_true:
            self.ptrue[in_expr.name] = inputs[in_expr.name]
        for in_expr in self.in_exprs_false:
            self.pfalse[in_expr.name] = inputs[in_expr.name]

    def compute(self, inputs, outputs):
        out_name = self.options['out_name']
        condition = self.options['condition']

        self.condition.run_model()
        prob = None
        if self.condition[condition.name] > 0:
            prob = self.ptrue
        else:
            prob = self.pfalse
        prob.run_model()
        outputs[out_name] = np.array(prob[out_name])

    def compute_partials(self, inputs, partials):
        out_name = self.options['out_name']
        condition = self.options['condition']
        expr_true = self.options['expr_true']
        expr_false = self.options['expr_false']

        self._set_values(inputs)
        prob = None
        in_exprs = set()
        branch_expr_name = ''
        if self.condition[condition.name] > 0:
            prob = self.ptrue
            in_exprs = self.in_exprs_true
            branch_expr_name = expr_true.name
        else:
            prob = self.pfalse
            in_exprs = self.in_exprs_false
            branch_expr_name = expr_false.name
        jac = prob.compute_totals(
            of=branch_expr_name,
            wrt=[in_expr.name
                 for in_expr in list(in_exprs)] + branch_expr_name,
        )
        for in_expr in in_exprs:
            partials[out_name, in_expr.name] = jac[branch_expr_name,
                                                   in_expr.name]
    def test(self):

        # Create a dictionary to store options about the surface
        mesh_dict = {
            'num_y': 7,
            'num_x': 2,
            'wing_type': 'rect',
            'symmetry': True
        }

        mesh = generate_mesh(mesh_dict)

        surf_dict = {
            # Wing definition
            'name': 'wing',  # name of the surface
            'symmetry': True,  # if true, model one half of wing
            # reflected across the plane y = 0
            'S_ref_type': 'wetted',  # how we compute the wing area,
            # can be 'wetted' or 'projected'
            'fem_model_type': 'tube',
            'mesh': mesh,

            # Aerodynamic performance of the lifting surface at
            # an angle of attack of 0 (alpha=0).
            # These CL0 and CD0 values are added to the CL and CD
            # obtained from aerodynamic analysis of the surface to get
            # the total CL and CD.
            # These CL0 and CD0 values do not vary wrt alpha.
            'CL0': 0.0,  # CL of the surface at alpha=0
            'CD0': 0.015,  # CD of the surface at alpha=0

            # Airfoil properties for viscous drag calculation
            'k_lam': 0.05,  # percentage of chord with laminar
            # flow, used for viscous drag
            't_over_c_cp':
            np.array([0.15]),  # thickness over chord ratio (NACA0015)
            'c_max_t': .303,  # chordwise location of maximum (NACA0015)
            # thickness
            'with_viscous': True,  # if true, compute viscous drag
            'with_wave': False,  # if true, compute wave drag
        }

        # Create a dictionary to store options about the surface
        mesh_dict = {
            'num_y': 5,
            'num_x': 3,
            'wing_type': 'rect',
            'symmetry': True,
            'offset': np.array([50, 0., 0.])
        }

        mesh = generate_mesh(mesh_dict)

        surf_dict2 = {
            # Wing definition
            'name': 'tail',  # name of the surface
            'symmetry': True,  # if true, model one half of wing
            # reflected across the plane y = 0
            'S_ref_type': 'wetted',  # how we compute the wing area,
            # can be 'wetted' or 'projected'
            'mesh': mesh,

            # Aerodynamic performance of the lifting surface at
            # an angle of attack of 0 (alpha=0).
            # These CL0 and CD0 values are added to the CL and CD
            # obtained from aerodynamic analysis of the surface to get
            # the total CL and CD.
            # These CL0 and CD0 values do not vary wrt alpha.
            'CL0': 0.0,  # CL of the surface at alpha=0
            'CD0': 0.0,  # CD of the surface at alpha=0
            'fem_origin': 0.35,

            # Airfoil properties for viscous drag calculation
            'k_lam': 0.05,  # percentage of chord with laminar
            # flow, used for viscous drag
            't_over_c_cp':
            np.array([0.15]),  # thickness over chord ratio (NACA0015)
            'c_max_t': .303,  # chordwise location of maximum (NACA0015)
            # thickness
            'with_viscous': True,  # if true, compute viscous drag
            'with_wave': False,  # if true, compute wave drag
        }

        surfaces = [surf_dict, surf_dict2]

        # Create the problem and the model group
        prob = Problem()

        indep_var_comp = IndepVarComp()
        indep_var_comp.add_output('v', val=248.136, units='m/s')
        indep_var_comp.add_output('alpha', val=5., units='deg')
        indep_var_comp.add_output('Mach_number', val=0.84)
        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')

        prob.model.add_subsystem('prob_vars', indep_var_comp, promotes=['*'])

        # Loop over each surface in the surfaces list
        for surface in surfaces:

            geom_group = Geometry(surface=surface)

            # Add tmp_group to the problem as the name of the surface.
            # Note that is a group and performance group for each
            # individual surface.
            prob.model.add_subsystem(surface['name'], geom_group)

        # Loop through and add a certain number of aero points
        for i in range(1):

            # Create the aero point group and add it to the model
            aero_group = AeroPoint(surfaces=surfaces)
            point_name = 'aero_point_{}'.format(i)
            prob.model.add_subsystem(point_name, aero_group)

            # Connect flow properties to the analysis point
            prob.model.connect('v', point_name + '.v')
            prob.model.connect('alpha', point_name + '.alpha')
            prob.model.connect('Mach_number', point_name + '.Mach_number')
            prob.model.connect('re', point_name + '.re')
            prob.model.connect('rho', point_name + '.rho')
            prob.model.connect('cg', point_name + '.cg')

            # Connect the parameters within the model for each aero point
            for surface in surfaces:

                name = surface['name']

                # Connect the mesh from the geometry component to the analysis point
                prob.model.connect(name + '.mesh',
                                   point_name + '.' + name + '.def_mesh')

                # Perform the connections with the modified names within the
                # 'aero_states' group.
                prob.model.connect(
                    name + '.mesh',
                    point_name + '.aero_states.' + name + '_def_mesh')

                prob.model.connect(
                    name + '.t_over_c',
                    point_name + '.' + name + '_perf.' + 't_over_c')

        # Set up the problem
        prob.setup()

        prob.run_model()

        assert_rel_error(self, prob['aero_point_0.wing_perf.CD'][0],
                         0.035076501750605345, 1e-6)
        assert_rel_error(self, prob['aero_point_0.wing_perf.CL'][0],
                         0.4523608754613204, 1e-6)
        assert_rel_error(self, prob['aero_point_0.CM'][1], -10.59426779178033,
                         1e-6)
Exemple #49
0
class TestExternalCodeComp(unittest.TestCase):
    def setUp(self):
        self.startdir = os.getcwd()
        self.tempdir = tempfile.mkdtemp(prefix='test_extcode-')
        os.chdir(self.tempdir)
        shutil.copy(os.path.join(DIRECTORY, 'extcode_example.py'),
                    os.path.join(self.tempdir, 'extcode_example.py'))

        self.prob = Problem()

        self.extcode = self.prob.model.add_subsystem('extcode',
                                                     ExternalCodeComp())

    def tearDown(self):
        os.chdir(self.startdir)
        try:
            shutil.rmtree(self.tempdir)
        except OSError:
            pass

    def test_normal(self):
        self.extcode.options['command'] = [
            'python', 'extcode_example.py', 'extcode.out'
        ]

        self.extcode.options['external_input_files'] = [
            'extcode_example.py',
        ]
        self.extcode.options['external_output_files'] = [
            'extcode.out',
        ]

        dev_null = open(os.devnull, 'w')
        self.prob.setup(check=True)
        self.prob.run_model()

    def test_timeout_raise(self):
        self.extcode.options['command'] = [
            'python', 'extcode_example.py', 'extcode.out', '--delay', '3'
        ]
        self.extcode.options['timeout'] = 1.0

        self.extcode.options['external_input_files'] = [
            'extcode_example.py',
        ]

        dev_null = open(os.devnull, 'w')
        self.prob.setup(check=True)
        try:
            self.prob.run_model()
        except AnalysisError as exc:
            self.assertEqual(str(exc), 'Timed out after 1.0 sec.')
        else:
            self.fail('Expected AnalysisError')

    def test_error_code_raise(self):
        self.extcode.options['command'] = [
            'python', 'extcode_example.py', 'extcode.out', '--delay', '-3'
        ]
        self.extcode.options['timeout'] = 1.0

        self.extcode.options['external_input_files'] = [
            'extcode_example.py',
        ]

        dev_null = open(os.devnull, 'w')
        self.prob.setup(check=True)
        try:
            self.prob.run_model()
        except RuntimeError as exc:
            self.assertTrue('Traceback' in str(exc),
                            "no traceback found in '%s'" % str(exc))
            self.assertEqual(self.extcode.return_code, 1)
        else:
            self.fail('Expected RuntimeError')

    def test_error_code_soft(self):
        self.extcode.options['command'] = [
            'python', 'extcode_example.py', 'extcode.out', '--delay', '-3'
        ]
        self.extcode.options['timeout'] = 1.0
        self.extcode.options['fail_hard'] = False

        self.extcode.options['external_input_files'] = [
            'extcode_example.py',
        ]

        dev_null = open(os.devnull, 'w')
        self.prob.setup(check=True)
        try:
            self.prob.run_model()
        except AnalysisError as err:
            self.assertTrue(
                "delay must be >= 0" in str(err),
                "expected 'delay must be >= 0' to be in '%s'" % str(err))
            self.assertTrue('Traceback' in str(err),
                            "no traceback found in '%s'" % str(err))
        else:
            self.fail("AnalysisError expected")

    def test_allowed_return_code(self):
        self.extcode.options['allowed_return_codes'] = set(range(5))
        self.extcode.options['command'] = [
            'python', 'extcode_example.py', 'extcode.out', '--return_code', '4'
        ]

        self.extcode.options['external_input_files'] = [
            'extcode_example.py',
        ]

        dev_null = open(os.devnull, 'w')
        self.prob.setup(check=True)
        self.prob.run_model()

    def test_disallowed_return_code(self):
        self.extcode.options['allowed_return_codes'] = list(range(5))
        self.extcode.options['command'] = [
            'python', 'extcode_example.py', 'extcode.out', '--return_code', '7'
        ]

        self.extcode.options['external_input_files'] = [
            'extcode_example.py',
        ]

        dev_null = open(os.devnull, 'w')
        self.prob.setup(check=True)
        try:
            self.prob.run_model()
        except RuntimeError as err:
            self.assertTrue(
                "return_code = 7" in str(err),
                "expected 'return_code = 7' to be in '%s'" % str(err))
        else:
            self.fail("RuntimeError expected")

    def test_badcmd(self):
        # Set command to nonexistant path.
        self.extcode.options['command'] = [
            'no-such-command',
        ]

        self.prob.setup(check=False)
        try:
            self.prob.run_model()
        except ValueError as exc:
            msg = "The command to be executed, 'no-such-command', cannot be found"
            self.assertEqual(str(exc), msg)
            self.assertEqual(self.extcode.return_code, -999999)
        else:
            self.fail('Expected ValueError')

    def test_nullcmd(self):
        self.extcode.stdout = 'nullcmd.out'
        self.extcode.stderr = STDOUT

        self.prob.setup(check=False)
        try:
            self.prob.run_model()
        except ValueError as exc:
            self.assertEqual(str(exc), 'Empty command list')
        else:
            self.fail('Expected ValueError')
        finally:
            if os.path.exists(self.extcode.stdout):
                os.remove(self.extcode.stdout)

    def test_env_vars(self):
        self.extcode.options['env_vars'] = {
            'TEST_ENV_VAR': 'SOME_ENV_VAR_VALUE'
        }
        self.extcode.options['command'] = [
            'python', 'extcode_example.py', 'extcode.out',
            '--write_test_env_var'
        ]

        dev_null = open(os.devnull, 'w')
        self.prob.setup(check=True)
        self.prob.run_model()

        # Check to see if output file contains the env var value
        with open(os.path.join(self.tempdir, 'extcode.out'), 'r') as out:
            file_contents = out.read()
        self.assertTrue(
            'SOME_ENV_VAR_VALUE' in file_contents,
            "'SOME_ENV_VAR_VALUE' missing from '%s'" % file_contents)
    def test(self):

        from openaerostruct.geometry.utils import generate_mesh, write_FFD_file
        from openaerostruct.geometry.geometry_group import Geometry
        from openaerostruct.transfer.displacement_transfer import DisplacementTransfer

        from openaerostruct.aerodynamics.aero_groups import AeroPoint
        from openaerostruct.integration.multipoint_comps import MultiCD

        from openmdao.api import IndepVarComp, Problem, Group, NewtonSolver, ScipyIterativeSolver, LinearBlockGS, NonlinearBlockGS, DirectSolver, LinearBlockGS, PetscKSP, ScipyOptimizeDriver, ExplicitComponent  # TODO, SqliteRecorder, CaseReader, profile
        from openmdao.devtools import iprofile
        from openmdao.api import view_model
        from openmdao.utils.assert_utils import assert_check_partials
        from pygeo import DVGeometry

        # Create a dictionary to store options about the surface
        mesh_dict = {
            'num_y': 5,
            'num_x': 3,
            'wing_type': 'CRM',
            'symmetry': True,
            'num_twist_cp': 5,
            'span_cos_spacing': 0.
        }

        mesh, _ = generate_mesh(mesh_dict)

        surf_dict = {
            # Wing definition
            'name': 'wing',  # name of the surface
            'symmetry': True,  # if true, model one half of wing
            # reflected across the plane y = 0
            'S_ref_type': 'wetted',  # how we compute the wing area,
            # can be 'wetted' or 'projected'
            'fem_model_type': 'tube',
            'mesh': mesh,
            'mx': 2,
            'my': 3,
            'geom_manipulator': 'FFD',

            # Aerodynamic performance of the lifting surface at
            # an angle of attack of 0 (alpha=0).
            # These CL0 and CD0 values are added to the CL and CD
            # obtained from aerodynamic analysis of the surface to get
            # the total CL and CD.
            # These CL0 and CD0 values do not vary wrt alpha.
            'CL0': 0.0,  # CL of the surface at alpha=0
            'CD0': 0.015,  # CD of the surface at alpha=0

            # Airfoil properties for viscous drag calculation
            'k_lam': 0.05,  # percentage of chord with laminar
            # flow, used for viscous drag
            't_over_c_cp':
            np.array([0.15]),  # thickness over chord ratio (NACA0015)
            'c_max_t': .303,  # chordwise location of maximum (NACA0015)
            # thickness
            'with_viscous': True,  # if true, compute viscous drag
            'with_wave': False,  # if true, compute wave drag
        }

        surfaces = [surf_dict]

        n_points = 2

        # Create the problem and the model group
        prob = Problem()

        indep_var_comp = IndepVarComp()
        indep_var_comp.add_output('v', val=248.136, units='m/s')
        indep_var_comp.add_output('alpha',
                                  val=np.ones(n_points) * 6.64,
                                  units='deg')
        indep_var_comp.add_output('Mach_number', val=0.84)
        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')

        prob.model.add_subsystem('prob_vars', indep_var_comp, promotes=['*'])

        # Loop through and add a certain number of aero points
        for i in range(n_points):

            # Create the aero point group and add it to the model
            aero_group = AeroPoint(surfaces=surfaces)
            point_name = 'aero_point_{}'.format(i)
            prob.model.add_subsystem(point_name, aero_group)

            # Connect flow properties to the analysis point
            prob.model.connect('v', point_name + '.v')
            prob.model.connect('alpha', point_name + '.alpha', src_indices=[i])
            prob.model.connect('Mach_number', point_name + '.Mach_number')
            prob.model.connect('re', point_name + '.re')
            prob.model.connect('rho', point_name + '.rho')
            prob.model.connect('cg', point_name + '.cg')

            # Connect the parameters within the model for each aero point
            for surface in surfaces:

                filename = write_FFD_file(surface, surface['mx'],
                                          surface['my'])
                DVGeo = DVGeometry(filename)
                geom_group = Geometry(surface=surface, DVGeo=DVGeo)

                # Add tmp_group to the problem as the name of the surface.
                # Note that is a group and performance group for each
                # individual surface.
                aero_group.add_subsystem(surface['name'] + '_geom', geom_group)

                name = surface['name']
                prob.model.connect(point_name + '.CD',
                                   'multi_CD.' + str(i) + '_CD')

                # Connect the mesh from the geometry component to the analysis point
                prob.model.connect(point_name + '.' + name + '_geom.mesh',
                                   point_name + '.' + name + '.def_mesh')

                # Perform the connections with the modified names within the
                # 'aero_states' group.
                prob.model.connect(
                    point_name + '.' + name + '_geom.mesh',
                    point_name + '.aero_states.' + name + '_def_mesh')

                prob.model.connect(
                    point_name + '.' + name + '_geom.t_over_c',
                    point_name + '.' + name + '_perf.' + 't_over_c')

        prob.model.add_subsystem('multi_CD',
                                 MultiCD(n_points=n_points),
                                 promotes_outputs=['CD'])

        from openmdao.api import pyOptSparseDriver
        prob.driver = pyOptSparseDriver()
        prob.driver.options['optimizer'] = "SNOPT"
        prob.driver.opt_settings = {
            'Major optimality tolerance': 1.0e-5,
            'Major feasibility tolerance': 1.0e-5
        }

        # # Setup problem and add design variables, constraint, and objective
        prob.model.add_design_var('alpha', lower=-15, upper=15)

        prob.model.add_design_var('aero_point_0.wing_geom.shape',
                                  lower=-3,
                                  upper=2)
        prob.model.add_constraint('aero_point_0.wing_perf.CL', equals=0.45)

        prob.model.add_design_var('aero_point_1.wing_geom.shape',
                                  lower=-3,
                                  upper=2)
        prob.model.add_constraint('aero_point_1.wing_perf.CL', equals=0.5)

        prob.model.add_objective('CD', scaler=1e4)

        # Set up the problem
        prob.setup()

        prob.run_model()

        # Check the partials at this point in the design space
        data = prob.check_partials(compact_print=True,
                                   out_stream=None,
                                   method='cs',
                                   step=1e-40)
        assert_check_partials(data, atol=1e20, rtol=1e-6)
    def test_deep_analysis_error_iprint(self):
        class ImplCompTwoStatesAE(ImplicitComponent):
            def setup(self):
                self.add_input('x', 0.5)
                self.add_output('y', 0.0)
                self.add_output('z', 2.0, lower=1.5, upper=2.5)

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

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

                self.counter = 0

            def apply_nonlinear(self, inputs, outputs, residuals):
                """
                Don't solve; just calculate the residual.
                """

                x = inputs['x']
                y = outputs['y']
                z = outputs['z']

                residuals['y'] = y - x - 2.0 * z
                residuals['z'] = x * z + z - 4.0

                self.counter += 1
                if self.counter > 5 and self.counter < 11:
                    raise AnalysisError('catch me')

            def linearize(self, inputs, outputs, jac):
                """
                Analytical derivatives.
                """

                # Output equation
                jac[('y', 'x')] = -1.0
                jac[('y', 'y')] = 1.0
                jac[('y', 'z')] = -2.0

                # State equation
                jac[('z', 'z')] = -inputs['x'] + 1.0
                jac[('z', 'x')] = -outputs['z']

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

        sub = top.model.add_subsystem('sub', Group())
        sub.add_subsystem('comp', ImplCompTwoStatesAE())

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

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

        sub.nonlinear_solver = NewtonSolver()
        sub.nonlinear_solver.options['maxiter'] = 2
        sub.linear_solver = ScipyKrylov()

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

        top.setup(check=False)
        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')
        self.assertTrue(output[26].startswith('|  LS: AG 5'))
Exemple #52
0
    def test_simple_external_code_implicit_comp(self):
        from openmdao.api import Group, NewtonSolver, Problem, IndepVarComp, DirectSolver, \
            ExternalCodeImplicitComp

        class MachExternalCodeComp(ExternalCodeImplicitComp):
            def initialize(self):
                self.options.declare('super_sonic', types=bool)

            def setup(self):
                self.add_input('area_ratio', val=1.0, units=None)
                self.add_output('mach', val=1., units=None)
                self.declare_partials(of='mach', wrt='area_ratio', method='fd')

                self.input_file = 'mach_input.dat'
                self.output_file = 'mach_output.dat'

                # providing these are optional; the component will verify that any input
                # files exist before execution and that the output files exist after.
                self.options['external_input_files'] = [
                    self.input_file,
                ]
                self.options['external_output_files'] = [
                    self.output_file,
                ]

                self.options['command_apply'] = [
                    'python',
                    'extcode_mach.py',
                    self.input_file,
                    self.output_file,
                ]
                self.options['command_solve'] = [
                    'python',
                    'extcode_mach.py',
                    self.input_file,
                    self.output_file,
                ]

            def apply_nonlinear(self, inputs, outputs, residuals):
                with open(self.input_file, 'w') as input_file:
                    input_file.write('residuals\n')
                    input_file.write('{}\n'.format(inputs['area_ratio'][0]))
                    input_file.write('{}\n'.format(outputs['mach'][0]))

                # the parent apply_nonlinear function actually runs the external code
                super(MachExternalCodeComp,
                      self).apply_nonlinear(inputs, outputs, residuals)

                # parse the output file from the external code and set the value of mach
                with open(self.output_file, 'r') as output_file:
                    mach = float(output_file.read())
                residuals['mach'] = mach

            def solve_nonlinear(self, inputs, outputs):
                with open(self.input_file, 'w') as input_file:
                    input_file.write('outputs\n')
                    input_file.write('{}\n'.format(inputs['area_ratio'][0]))
                    input_file.write('{}\n'.format(
                        self.options['super_sonic']))
                # the parent apply_nonlinear function actually runs the external code
                super(MachExternalCodeComp,
                      self).solve_nonlinear(inputs, outputs)

                # parse the output file from the external code and set the value of mach
                with open(self.output_file, 'r') as output_file:
                    mach = float(output_file.read())
                outputs['mach'] = mach

        group = Group()
        group.add_subsystem('ar', IndepVarComp('area_ratio', 0.5))
        mach_comp = group.add_subsystem('comp',
                                        MachExternalCodeComp(),
                                        promotes=['*'])
        prob = Problem(model=group)
        group.nonlinear_solver = NewtonSolver()
        group.nonlinear_solver.options['solve_subsystems'] = True
        group.nonlinear_solver.options['iprint'] = 0
        group.nonlinear_solver.options['maxiter'] = 20
        group.linear_solver = DirectSolver()

        prob.setup(check=False)

        area_ratio = 1.3
        super_sonic = False
        prob['area_ratio'] = area_ratio
        mach_comp.options['super_sonic'] = super_sonic
        prob.run_model()
        assert_rel_error(self, prob['mach'],
                         mach_solve(area_ratio, super_sonic=super_sonic), 1e-8)

        area_ratio = 1.3
        super_sonic = True
        prob['area_ratio'] = area_ratio
        mach_comp.options['super_sonic'] = super_sonic
        prob.run_model()
        assert_rel_error(self, prob['mach'],
                         mach_solve(area_ratio, super_sonic=super_sonic), 1e-8)
Exemple #53
0
class CompressorTestCase(unittest.TestCase):
    def setUp(self):

        thermo = Thermo(janaf, constants.AIR_MIX)

        self.prob = Problem()

        self.prob.model.add_subsystem(
            'flow_start', FlowStart(thermo_data=janaf, elements=AIR_MIX))
        self.prob.model.add_subsystem(
            'compressor', Compressor(design=True, elements=AIR_MIX))

        self.prob.model.set_input_defaults('flow_start.P', 17., units='psi')
        self.prob.model.set_input_defaults('flow_start.T', 500., units='degR')
        self.prob.model.set_input_defaults('compressor.MN', 0.5)
        self.prob.model.set_input_defaults('flow_start.W', 10., units='lbm/s')
        self.prob.model.set_input_defaults('compressor.PR', 6.)
        self.prob.model.set_input_defaults('compressor.eff', 0.9)

        connect_flow(self.prob.model, "flow_start.Fl_O", "compressor.Fl_I")

        self.prob.set_solver_print(level=-1)
        self.prob.setup(check=False)

    def test_case1(self):
        np.seterr(divide='raise')
        # 6 cases to check against
        for i, data in enumerate(ref_data):
            self.prob['compressor.PR'] = data[h_map['comp.PRdes']]
            self.prob['compressor.eff'] = data[h_map['comp.effDes']]
            self.prob['compressor.MN'] = data[h_map['comp.Fl_O.MN']]

            # input flowstation
            self.prob['flow_start.P'] = data[h_map['start.Pt']]
            self.prob['flow_start.T'] = data[h_map['start.Tt']]
            self.prob['flow_start.W'] = data[h_map['start.W']]
            self.prob.run_model()

            tol = 1e-3

            npss = data[h_map['comp.Fl_O.Pt']]
            pyc = self.prob['compressor.Fl_O:tot:P'][0]
            print('Pt out:', npss, pyc)
            assert_near_equal(pyc, npss, tol)

            npss = data[h_map['comp.Fl_O.Tt']]
            pyc = self.prob['compressor.Fl_O:tot:T'][0]
            print('Tt out:', npss, pyc)
            assert_near_equal(pyc, npss, tol)

            npss = data[h_map['comp.Fl_O.ht']] - data[h_map['start.Fl_O.ht']]
            pyc = self.prob['compressor.Fl_O:tot:h'] - self.prob[
                'flow_start.Fl_O:tot:h']
            print('delta h:', npss, pyc)
            assert_near_equal(pyc, npss, tol)

            npss = data[h_map['start.Fl_O.s']]
            pyc = self.prob['flow_start.Fl_O:tot:S'][0]
            print('S in:', npss, pyc)
            assert_near_equal(pyc, npss, tol)

            npss = data[h_map['comp.Fl_O.s']]
            pyc = self.prob['compressor.Fl_O:tot:S'][0]
            print('S out:', npss, pyc)
            assert_near_equal(pyc, npss, tol)

            npss = data[h_map['comp.pwr']]
            pyc = self.prob['compressor.power'][0]
            print('Power:', npss, pyc)
            assert_near_equal(pyc, npss, tol)

            npss = data[h_map['Fl_O.Ps']]
            pyc = self.prob['compressor.Fl_O:stat:P'][0]
            print('Ps out:', npss, pyc)
            assert_near_equal(pyc, npss, tol)

            npss = data[h_map['Fl_O.Ts']]
            pyc = self.prob['compressor.Fl_O:stat:T'][0]
            print('Ts out:', npss, pyc)
            assert_near_equal(pyc, npss, tol)

            npss = data[h_map['comp.effPoly']]
            pyc = self.prob['compressor.eff_poly'][0]
            print('effPoly:', npss, pyc)
            assert_near_equal(pyc, npss, tol)
            print("")

            check_element_partials(self, self.prob, tol=5e-5)
Exemple #54
0
class TestControlEndpointDefectComp(unittest.TestCase):
    def setUp(self):
        gd = GridData(num_segments=2,
                      segment_ends=np.array([0., 2., 4.]),
                      transcription='radau-ps',
                      transcription_order=3)

        self.gd = gd

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

        control_opts = {
            'u': {
                'units': 'm',
                'shape': (1, ),
                'dynamic': True,
                'opt': True
            },
            'v': {
                'units': 'm',
                'shape': (3, 2),
                'dynamic': True,
                'opt': True
            }
        }

        indep_comp = IndepVarComp()
        self.p.model.add_subsystem('indep', indep_comp, promotes=['*'])

        indep_comp.add_output('controls:u',
                              val=np.zeros((gd.subset_num_nodes['all'], 1)),
                              units='m')

        indep_comp.add_output('controls:v',
                              val=np.zeros((gd.subset_num_nodes['all'], 3, 2)),
                              units='m')

        self.p.model.add_subsystem('endpoint_defect_comp',
                                   subsys=ControlEndpointDefectComp(
                                       grid_data=gd,
                                       control_options=control_opts))

        self.p.model.connect('controls:u', 'endpoint_defect_comp.controls:u')
        self.p.model.connect('controls:v', 'endpoint_defect_comp.controls:v')

        self.p.setup(force_alloc_complex=True)

        self.p['controls:u'] = np.random.random(
            (gd.subset_num_nodes['all'], 1))
        self.p['controls:v'] = np.random.random(
            (gd.subset_num_nodes['all'], 3, 2))

        self.p.run_model()

    def test_results(self):

        u_coefs = np.polyfit(self.gd.node_ptau[-4:-1],
                             self.p['controls:u'][-4:-1],
                             deg=2)
        u_poly = np.poly1d(u_coefs.ravel())
        u_interp = u_poly(1.0)
        u_given = self.p['controls:u'][-1]
        assert_rel_error(
            self,
            np.ravel(
                self.p['endpoint_defect_comp.control_endpoint_defects:u']),
            np.ravel(u_given - u_interp),
            tolerance=1.0E-12)

    def test_partials(self):
        cpd = self.p.check_partials(compact_print=False, method='cs')
        assert_check_partials(cpd)
Exemple #55
0
# -*- coding: utf-8 -*-
"""
  run_analysis.py generated by WhatsOpt 1.7.1
"""
# DO NOT EDIT unless you know what you are doing
# analysis_id: 77

from openmdao.api import Problem
from run_parameters_init import initialize
from lanceur_prop_solide import LanceurPropSolide

pb = Problem(LanceurPropSolide())
pb.setup()

initialize(pb)

pb.run_model()
pb.model.list_inputs(print_arrays=False)
pb.model.list_outputs(print_arrays=False)
    def test_analysis_error(self):
        class ParaboloidAE(ExplicitComponent):
            """ Evaluates the equation f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3
            This version raises an analysis error if x < 2.0
            The AE in ParaboloidAE stands for AnalysisError."""
            def __init__(self):
                super(ParaboloidAE, self).__init__()
                self.fail_hard = False

            def setup(self):
                self.add_input('x', val=0.0)
                self.add_input('y', val=0.0)

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

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

            def compute(self, inputs, outputs):
                """f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3
                Optimal solution (minimum): x = 6.6667; y = -7.3333
                """
                x = inputs['x']
                y = inputs['y']

                if x < 1.75:
                    raise AnalysisError('Try Again.')

                outputs['f_xy'] = (x - 3.0)**2 + x * y + (y + 4.0)**2 - 3.0

            def compute_partials(self, inputs, partials):
                """ Jacobian for our paraboloid."""
                x = inputs['x']
                y = inputs['y']

                partials['f_xy', 'x'] = 2.0 * x - 6.0 + y
                partials['f_xy', 'y'] = 2.0 * y + 8.0 + x

        top = Problem()
        top.model = Group()
        top.model.add_subsystem('px', 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 = NewtonSolver()
        top.model.nonlinear_solver.options['maxiter'] = 1
        top.model.linear_solver = ScipyKrylov()

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

        top.setup(check=False)

        # Test lower bound: should go as far as it can without going past 1.75 and triggering an
        # AnalysisError. It doesn't do a great job, so ends up at 1.8 instead of 1.75
        top['px.x'] = 2.0
        top['comp.y'] = 0.0
        top['comp.z'] = 2.1
        top.run_model()
        assert_rel_error(self, top['comp.z'], 1.8, 1e-8)

        # Test the behavior with the switch turned off.

        top = Problem()
        top.model = Group()
        top.model.add_subsystem('px', 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 = NewtonSolver()
        top.model.nonlinear_solver.options['maxiter'] = 1
        top.model.linear_solver = ScipyKrylov()

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

        top.setup(check=False)

        top['px.x'] = 2.0
        top['comp.y'] = 0.0
        top['comp.z'] = 2.1

        with self.assertRaises(AnalysisError) as context:
            top.run_model()

        self.assertEqual(str(context.exception), 'Try Again.')
Exemple #57
0
    def test_sellar_specify_linear_direct_solver(self):

        prob = Problem()
        model = prob.model

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

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

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

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

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

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

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

        model.nonlinear_solver = NewtonSolver()

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

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

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

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

        # Make sure we aren't iterating like crazy
        self.assertLess(model.nonlinear_solver._iter_count, 8)
        self.assertEqual(model.linear_solver._iter_count, 0)
Exemple #58
0
class CompressorTestCase(unittest.TestCase):

    def setUp(self):

        self.prob = Problem()

        des_vars = self.prob.model.add_subsystem('des_vars', IndepVarComp(), promotes=['*'])
        des_vars.add_output('P', 17., units='psi')
        des_vars.add_output('T', 500., units='degR')
        des_vars.add_output('MN', 0.5)
        des_vars.add_output('W', 10., units='lbm/s')
        des_vars.add_output('PR', 6.)
        des_vars.add_output('eff', 0.9)
        self.prob.model.connect("P", "flow_start.P")
        self.prob.model.connect("T", "flow_start.T")
        self.prob.model.connect("W", "flow_start.W")
        self.prob.model.connect("MN", "compressor.MN")
        self.prob.model.connect('PR', 'compressor.PR')
        self.prob.model.connect('eff', 'compressor.eff')

        self.prob.model.add_subsystem('flow_start', FlowStart(thermo_data=janaf, elements=AIR_MIX))
        self.prob.model.add_subsystem('compressor', Compressor(design=True, elements=AIR_MIX))

        connect_flow(self.prob.model, "flow_start.Fl_O", "compressor.Fl_I")

        self.prob.set_solver_print(level=-1)
        self.prob.setup(check=False)

        # from openmdao.api import view_model
        # view_model(self.prob)
        # exit()

    def test_case1(self):
        np.seterr(divide='raise')
        # 6 cases to check against
        for i, data in enumerate(ref_data):
            self.prob['PR'] = data[h_map['comp.PRdes']]
            self.prob['eff'] = data[h_map['comp.effDes']]
            self.prob['MN'] = data[h_map['comp.Fl_O.MN']]

            # input flowstation
            self.prob['P'] = data[h_map['start.Pt']]
            self.prob['T'] = data[h_map['start.Tt']]
            self.prob['W'] = data[h_map['start.W']]
            self.prob.run_model()

            # print("    mapPRdes     :         PRdes       :        PR       :      scalarsPRmapDes : scaledOutput.PR")
            # print(self.prob['PR'], data[h_map['comp.PRdes']], self.prob[
            #       'PR'], self.prob['compressor.map.PRmap'])
            # print("s_PR", self.prob['compressor.s_PR'])

            # print("    mapeffDes     :         effDes       :        eff       :      scalars_effMapDes : scaledOutput.eff")
            # print(self.prob['compressor.map.effDes'], data[h_map['comp.effDes']], self.prob[
            #       'compressor.eff'], self.prob['compressor.map.scalars.effMapDes'])
            # print("Rline", self.prob['compressor.map.RlineMap'])

            # print(self.prob.model.resids._dat.keys())

            #print("errWc: ", self.prob.model.resids['compressor.map.RlineMap'])

            # quit()
            # check outputs
            tol = 1e-3

            npss = data[h_map['comp.Fl_O.Pt']]
            pyc = self.prob['compressor.Fl_O:tot:P'][0]
            print('Pt out:', npss, pyc)
            assert_rel_error(self, pyc, npss, tol)

            npss = data[h_map['comp.Fl_O.Tt']]
            pyc = self.prob['compressor.Fl_O:tot:T'][0]
            # print('foo test:', self.prob['compressor.enth_rise.ht_out'][0], data[h_map['start.Fl_O.ht']])
            print('Tt out:', npss, pyc)
            assert_rel_error(self, pyc, npss, tol)

            npss = data[h_map['comp.Fl_O.ht']] - data[h_map['start.Fl_O.ht']]
            pyc = self.prob['compressor.Fl_O:tot:h'] - self.prob['flow_start.Fl_O:tot:h']
            print('delta h:', npss, pyc)
            assert_rel_error(self, pyc, npss, tol)

            npss = data[h_map['start.Fl_O.s']]
            pyc = self.prob['flow_start.Fl_O:tot:S'][0]
            print('S in:', npss, pyc)
            assert_rel_error(self, pyc, npss, tol)

            npss = data[h_map['comp.Fl_O.s']]
            pyc = self.prob['compressor.Fl_O:tot:S'][0]
            print('S out:', npss, pyc)
            assert_rel_error(self, pyc, npss, tol)

            npss = data[h_map['comp.pwr']]
            pyc = self.prob['compressor.power'][0]
            print('Power:', npss, pyc)
            assert_rel_error(self, pyc, npss, tol)

            npss = data[h_map['Fl_O.Ps']]
            pyc = self.prob['compressor.Fl_O:stat:P'][0]
            print('Ps out:', npss, pyc)
            assert_rel_error(self, pyc, npss, tol)

            npss = data[h_map['Fl_O.Ts']]
            pyc = self.prob['compressor.Fl_O:stat:T'][0]
            print('Ts out:', npss, pyc)
            assert_rel_error(self, pyc, npss, tol)

            npss = data[h_map['comp.effPoly']]
            pyc = self.prob['compressor.eff_poly'][0]
            print('effPoly:', npss, pyc)
            assert_rel_error(self, pyc, npss, tol)
            print("")

            check_element_partials(self, self.prob,tol = 5e-5)
    def test_multifidelity_warm_start(self):
        mm = MultiFiMetaModelUnStructured(nfi=2)
        surr = MockSurrogate()

        mm.add_input('x', 0.)
        mm.add_output('y', 0., surrogate=surr)

        mm.warm_restart = True

        prob = Problem(Group())
        prob.model.add_subsystem('mm', mm)
        prob.setup(check=False)

        mm.metadata['train:x'] = [0.0, 0.4, 1.0]
        mm.metadata['train:x_fi2'] = [0.1, 0.2, 0.3, 0.5, 0.6]
        mm.metadata['train:y'] = [1.0, 1.4, 2.0]
        mm.metadata['train:y_fi2'] = [1.1, 1.2, 1.3, 1.5, 1.6]

        prob.run_model()
        expected_xtrain = [
            np.array([[0.0], [0.4], [1.0]]),
            np.array([[0.1], [0.2], [0.3], [0.5], [0.6]])
        ]
        expected_ytrain = [
            np.array([[1.0], [1.4], [2.0]]),
            np.array([[1.1], [1.2], [1.3], [1.5], [1.6]])
        ]
        np.testing.assert_array_equal(surr.xtrain[0], expected_xtrain[0])
        np.testing.assert_array_equal(surr.xtrain[1], expected_xtrain[1])

        np.testing.assert_array_equal(surr.ytrain[0], expected_ytrain[0])
        np.testing.assert_array_equal(surr.ytrain[1], expected_ytrain[1])

        # Test adding only one lowest fidelity sample
        mm.metadata['train:x'] = []
        mm.metadata['train:y'] = []
        mm.metadata['train:x_fi2'] = [2.0]
        mm.metadata['train:y_fi2'] = [1.0]
        mm.train = True

        prob.run_model()
        expected_xtrain = [
            np.array([[0.0], [0.4], [1.0]]),
            np.array([[0.1], [0.2], [0.3], [0.5], [0.6], [2.0]])
        ]
        expected_ytrain = [
            np.array([[1.0], [1.4], [2.0]]),
            np.array([[1.1], [1.2], [1.3], [1.5], [1.6], [1.0]])
        ]

        np.testing.assert_array_equal(surr.xtrain[0], expected_xtrain[0])
        np.testing.assert_array_equal(surr.xtrain[1], expected_xtrain[1])
        np.testing.assert_array_equal(surr.ytrain[0], expected_ytrain[0])
        np.testing.assert_array_equal(surr.ytrain[1], expected_ytrain[1])

        # Test adding high and low fidelity points
        mm.metadata['train:x'] = [3.0]
        mm.metadata['train:x_fi2'] = [3.0]
        mm.metadata['train:y'] = [4.0]
        mm.metadata['train:y_fi2'] = [4.0]

        mm.train = True
        prob.run_model()

        expected_xtrain = [
            np.array([[0.0], [0.4], [1.0], [3.0]]),
            np.array([[0.1], [0.2], [0.3], [0.5], [0.6], [2.0], [3.0]])
        ]
        expected_ytrain = [
            np.array([[1.0], [1.4], [2.0], [4.0]]),
            np.array([[1.1], [1.2], [1.3], [1.5], [1.6], [1.0], [4.0]])
        ]
        np.testing.assert_array_equal(surr.xtrain[0], expected_xtrain[0])
        np.testing.assert_array_equal(surr.xtrain[1], expected_xtrain[1])
        np.testing.assert_array_equal(surr.ytrain[0], expected_ytrain[0])
        np.testing.assert_array_equal(surr.ytrain[1], expected_ytrain[1])
Exemple #60
0
    def test_solve_subsystems_internals(self):
        # Here we test that this feature is doing what it should do by counting the
        # number of calls in various places.

        class CountNewton(NewtonSolver):
            """ This version of Newton also counts how many times it runs in total."""
            def __init__(self, **kwargs):
                super(CountNewton, self).__init__(**kwargs)
                self.total_count = 0

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

        class CountDS(DirectSolver):
            """ This version of Newton also counts how many times it linearizes"""
            def __init__(self, **kwargs):
                super(DirectSolver, self).__init__(**kwargs)
                self.lin_count = 0

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

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

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

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

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

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

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

        prob.setup()
        prob.run_model()

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

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

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

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

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

        # Enforce Behavior: baseline

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

        prob.setup()
        prob.run_model()

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

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

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

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

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

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

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

        prob.setup()
        prob.run_model()

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