def test_sellar_idf(self):
        prob = Problem(SellarIDF())
        prob.driver = ScipyOptimizeDriver(optimizer='SLSQP', disp=False)
        prob.setup()

        # check derivatives
        prob['dv.y1'] = 100
        prob['equal.rhs:y1'] = 1

        prob.run_model()

        cpd = prob.check_partials(out_stream=None)

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

        assert_check_partials(cpd, atol=1e-5, rtol=1e-5)

        # check results
        prob.run_driver()

        assert_rel_error(self, prob['dv.x'], 0., 1e-5)
        assert_rel_error(self, prob['dv.z'], [1.977639, 0.], 1e-5)

        assert_rel_error(self, prob['obj_cmp.obj'], 3.18339395045, 1e-5)

        assert_almost_equal(prob['dv.y1'], 3.16)
        assert_almost_equal(prob['d1.y1'], 3.16)

        assert_almost_equal(prob['dv.y2'], 3.7552778)
        assert_almost_equal(prob['d2.y2'], 3.7552778)

        assert_almost_equal(prob['equal.y1'], 0.0)
        assert_almost_equal(prob['equal.y2'], 0.0)
    def test_rhs_val(self):
        prob = Problem()
        model = prob.model

        # find where x^2 == 4
        model.add_subsystem('indep', IndepVarComp('x', val=1.))
        model.add_subsystem('f', ExecComp('y=x**2', x=1.))
        model.add_subsystem('equal', EQConstraintComp('y', rhs_val=4.))

        model.connect('indep.x', 'f.x')
        model.connect('f.y', 'equal.lhs:y')

        model.add_design_var('indep.x', lower=0., upper=10.)
        model.add_constraint('equal.y', equals=0.)
        model.add_objective('f.y')

        prob.setup(mode='fwd')
        prob.driver = ScipyOptimizeDriver(disp=False)
        prob.run_driver()

        assert_rel_error(self, prob['equal.y'], 0., 1e-6)
        assert_rel_error(self, prob['indep.x'], 2., 1e-6)
        assert_rel_error(self, prob['f.y'], 4., 1e-6)

        cpd = prob.check_partials(out_stream=None)

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

        assert_check_partials(cpd, atol=1e-5, rtol=1e-5)
Beispiel #3
0
    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_complex_step(self):
        prob = Problem()
        model = prob.model

        # find where 2*x == x^2
        model.add_subsystem('indep', IndepVarComp('x', val=1.))
        model.add_subsystem('multx', IndepVarComp('m', val=2.))
        model.add_subsystem('f', ExecComp('y=x**2', x=1.))
        model.add_subsystem('equal', EQConstraintComp('y', use_mult=True))

        model.connect('indep.x', 'f.x')

        model.connect('indep.x', 'equal.lhs:y')
        model.connect('multx.m', 'equal.mult:y')
        model.connect('f.y', 'equal.rhs:y')

        model.add_design_var('indep.x', lower=0., upper=10.)
        model.add_constraint('equal.y', equals=0.)
        model.add_objective('f.y')

        prob.setup(mode='fwd', force_alloc_complex=True)
        prob.driver = ScipyOptimizeDriver(disp=False)
        prob.run_driver()

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

        assert_check_partials(cpd, atol=1e-10, rtol=1e-10)
    def test_vectorized_with_default_mult(self):
        prob = Problem()
        model = prob.model

        n = 100

        # find where 2*x == x^2, vectorized
        model.add_subsystem('indep', IndepVarComp('x', val=np.ones(n)))
        model.add_subsystem('f', ExecComp('y=x**2', x=np.ones(n), y=np.ones(n)))
        model.add_subsystem('equal', EQConstraintComp('y', val=np.ones(n),
                            use_mult=True, mult_val=2., add_constraint=True))
        model.add_subsystem('obj_cmp', ExecComp('obj=sum(y)', y=np.zeros(n)))

        model.connect('indep.x', 'f.x')

        model.connect('indep.x', 'equal.lhs:y')
        model.connect('f.y', 'equal.rhs:y')
        model.connect('f.y', 'obj_cmp.y')

        model.add_design_var('indep.x', lower=np.zeros(n), upper=np.ones(n)*10.)
        model.add_objective('obj_cmp.obj')

        prob.setup(mode='fwd')
        prob.driver = ScipyOptimizeDriver(disp=False)
        prob.run_driver()

        assert_rel_error(self, prob['equal.y'], np.zeros(n), 1e-6)
        assert_rel_error(self, prob['indep.x'], np.ones(n)*2., 1e-6)
        assert_rel_error(self, prob['f.y'], np.ones(n)*4., 1e-6)

        cpd = prob.check_partials(out_stream=None)
        for (of, wrt) in cpd['equal']:
            assert_almost_equal(cpd['equal'][of, wrt]['abs error'], 0.0, decimal=5)

        assert_check_partials(cpd, atol=1e-5, rtol=1e-5)
Beispiel #6
0
    def test_assert_check_partials_no_exception_expected(self):
        import numpy as np
        from openmdao.api import Problem, ExplicitComponent
        from openmdao.utils.assert_utils import assert_check_partials

        class MyComp(ExplicitComponent):
            def setup(self):
                self.add_input('x1', 3.0)
                self.add_input('x2', 5.0)

                self.add_output('y', 5.5)

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

            def compute(self, inputs, outputs):
                outputs['y'] = 3.0 * inputs['x1'] + 4.0 * inputs['x2']

            def compute_partials(self, inputs,     partials):
                """Correct derivative."""
                J = partials
                J['y', 'x1'] = np.array([3.0])
                J['y', 'x2'] = np.array([4.0])

        prob = Problem()
        prob.model = MyComp()

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

        data = prob.check_partials(out_stream=None)
        atol = 1.e-6
        rtol = 1.e-6
        assert_check_partials(data, atol, rtol)
Beispiel #7
0
    def test_assert_check_partials_exception_expected(self):
        class MyComp(ExplicitComponent):
            def setup(self):
                self.add_input('x1', 3.0)
                self.add_input('x2', 5.0)

                self.add_output('y', 5.5)

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

            def compute(self, inputs, outputs):
                outputs['y'] = 3.0 * inputs['x1'] + 4.0 * inputs['x2']

            def compute_partials(self, inputs, partials):
                """Intentionally incorrect derivative."""
                J = partials
                J['y', 'x1'] = np.array([4.0])
                J['y', 'x2'] = np.array([40])

        prob = Problem()
        prob.model = MyComp()

        prob.set_solver_print(level=0)

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

        data = prob.check_partials(out_stream=None)

        atol = 1.e-6
        rtol = 1.e-6
        try:
            assert_check_partials(data, atol, rtol)
        except ValueError as err:
            err_string = str(err)
            self.assertEqual(err_string.count('Assert Check Partials failed for the following Components'), 1)
            self.assertEqual(err_string.count('1e-06'), 2)
            self.assertEqual(err_string.count('Component:'), 1)
            self.assertEqual(err_string.count('< output > wrt < variable >'), 1)
            self.assertEqual(err_string.count('norm'), 2)
            self.assertEqual(err_string.count('y wrt x1'), 4)
            self.assertEqual(err_string.count('y wrt x2'), 4)
            self.assertEqual(err_string.count('abs'), 6)
            self.assertEqual(err_string.count('rel'), 6)
            self.assertEqual(err_string.count('fwd-fd'), 4)
            self.assertEqual(err_string.count('rev-fd'), 4)
        else:
            self.fail('Exception expected.')
    def test_vectorized_no_normalization(self):
        prob = Problem()
        model = prob.model

        n = 100

        # find intersection of two non-parallel lines, vectorized
        model.add_subsystem('indep', IndepVarComp('x', val=-2.0*np.ones(n)))
        model.add_subsystem('f', ExecComp('y=3*x-3', x=np.ones(n), y=np.ones(n)))
        model.add_subsystem('g', ExecComp('y=2.3*x+4', x=np.ones(n), y=np.ones(n)))
        model.add_subsystem('equal', EQConstraintComp('y', val=np.ones(n), add_constraint=True,
                                                      normalize=False))
        model.add_subsystem('obj_cmp', ExecComp('obj=sum(y)', y=np.zeros(n)))

        model.connect('indep.x', 'f.x')
        model.connect('indep.x', 'g.x')
        model.connect('f.y', 'equal.lhs:y')
        model.connect('g.y', 'equal.rhs:y')
        model.connect('f.y', 'obj_cmp.y')

        model.add_design_var('indep.x', lower=np.zeros(n), upper=20.*np.ones(n))
        model.add_objective('obj_cmp.obj')

        prob.setup(mode='fwd')

        prob.driver = ScipyOptimizeDriver(disp=False)

        # verify that the output is not being normalized
        prob.run_model()
        lhs = prob['f.y']
        rhs = prob['g.y']
        diff = lhs - rhs
        assert_rel_error(self, prob['equal.y'], diff)

        prob.run_driver()

        assert_almost_equal(prob['equal.y'], np.zeros(n))
        assert_almost_equal(prob['indep.x'], np.ones(n)*10.)
        assert_almost_equal(prob['f.y'], np.ones(n)*27.)
        assert_almost_equal(prob['g.y'], np.ones(n)*27.)

        cpd = prob.check_partials(out_stream=None)

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

        assert_check_partials(cpd, atol=1e-5, rtol=1e-5)
    def test_create_on_init_add_constraint_no_normalization(self):
        prob = Problem()
        model = prob.model

        # find intersection of two non-parallel lines
        model.add_subsystem('indep', IndepVarComp('x', val=-2.0))
        model.add_subsystem('f', ExecComp('y=3*x-3', x=0.))
        model.add_subsystem('g', ExecComp('y=2.3*x+4', x=0.))
        model.add_subsystem('equal', EQConstraintComp('y', add_constraint=True, normalize=False,
                                                      ref0=0, ref=100.0))

        model.connect('indep.x', 'f.x')
        model.connect('indep.x', 'g.x')

        model.connect('f.y', 'equal.lhs:y')
        model.connect('g.y', 'equal.rhs:y')

        model.add_design_var('indep.x', lower=0., upper=20.)
        model.add_objective('f.y')

        prob.setup(mode='fwd')

        # verify that the constraint has been added as requested
        self.assertTrue('equal.y' in model.get_constraints())

        # verify that the output is not being normalized
        prob.run_model()
        lhs = prob['f.y']
        rhs = prob['g.y']
        diff = lhs - rhs
        assert_rel_error(self, prob['equal.y'], diff)

        prob.driver = ScipyOptimizeDriver(disp=False)

        prob.run_driver()

        assert_almost_equal(prob['equal.y'], 0.)
        assert_almost_equal(prob['indep.x'], 10.)
        assert_almost_equal(prob['f.y'], 27.)
        assert_almost_equal(prob['g.y'], 27.)

        cpd = prob.check_partials(out_stream=None)

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

        assert_check_partials(cpd, atol=1e-5, rtol=1e-5)
    def test_create_on_init(self):
        prob = Problem()
        model = prob.model

        # find intersection of two non-parallel lines
        model.add_subsystem('indep', IndepVarComp('x', val=0.))
        model.add_subsystem('f', ExecComp('y=3*x-3', x=0.))
        model.add_subsystem('g', ExecComp('y=2.3*x+4', x=0.))
        model.add_subsystem('equal', EQConstraintComp('y', val=11.))

        model.connect('indep.x', 'f.x')
        model.connect('indep.x', 'g.x')

        model.connect('f.y', 'equal.lhs:y')
        model.connect('g.y', 'equal.rhs:y')

        model.add_design_var('indep.x', lower=0., upper=20.)
        model.add_objective('f.y')

        prob.setup(mode='fwd')

        # verify that the output variable has been initialized
        self.assertEqual(prob['equal.y'], 11.)

        # verify that the constraint has not been added
        self.assertFalse('equal.y' in model.get_constraints())

        # manually add the constraint
        model.add_constraint('equal.y', equals=0.)
        prob.setup(mode='fwd')

        prob.driver = ScipyOptimizeDriver(disp=False)

        prob.run_driver()

        assert_almost_equal(prob['equal.y'], 0.)
        assert_almost_equal(prob['indep.x'], 10.)
        assert_almost_equal(prob['f.y'], 27.)
        assert_almost_equal(prob['g.y'], 27.)

        cpd = prob.check_partials(out_stream=None)

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

        assert_check_partials(cpd, atol=1e-5, rtol=1e-5)
    def test_taper_symmetry(self):
        symmetry = True
        mesh = get_mesh(symmetry)

        prob = Problem()
        group = prob.model

        val = np.random.random(1)

        comp = Taper(val=val, mesh=mesh, symmetry=symmetry)
        group.add_subsystem('comp', comp)

        prob.setup()
        prob.run_model()

        check = prob.check_partials(compact_print=True, abs_err_tol=1e-5, rel_err_tol=1e-5)
        assert_check_partials(check, atol=1e-6, rtol=1e-6)
    def test_assembled_jac(self):
        surfaces = get_default_surfaces()

        comp = EvalVelMtx(surfaces=surfaces, num_eval_points=2, eval_name='test_name')

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

        from openmdao.api import DirectSolver
        prob.model.linear_solver = DirectSolver(assemble_jac=True)
        prob.model.options['assembled_jac_type'] = 'csc'

        prob.setup(force_alloc_complex=True)

        prob.run_model()

        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_scalex(self):
        symmetry = False
        mesh = get_mesh(symmetry)

        prob = Problem()
        group = prob.model

        val = np.random.random(NY)

        comp = ScaleX(val=val, mesh_shape=mesh.shape)
        group.add_subsystem('comp', comp)

        prob.setup()

        prob['comp.in_mesh'] = mesh

        prob.run_model()

        check = prob.check_partials(compact_print=True, abs_err_tol=1e-5, rel_err_tol=1e-5)
        assert_check_partials(check, atol=1e-6, rtol=1e-6)
Beispiel #14
0
    def test_assert_check_partials_exception_expected(self):
        class MyComp(ExplicitComponent):
            def setup(self):
                self.add_input('x1', 3.0)
                self.add_input('x2', 5.0)

                self.add_output('y', 5.5)

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

            def compute(self, inputs, outputs):
                """ Doesn't do much. """
                outputs['y'] = 3.0 * inputs['x1'] + 4.0 * inputs['x2']

            def compute_partials(self, inputs, partials):
                """Intentionally incorrect derivative."""
                J = partials
                J['y', 'x1'] = np.array([4.0])
                J['y', 'x2'] = np.array([40])

        prob = Problem()
        prob.model = MyComp()

        prob.set_solver_print(level=0)

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

        data = prob.check_partials(suppress_output=True)

        atol = 1.e-6
        rtol = 1.e-6
        try:
            assert_check_partials(data, atol, rtol)
        except AssertionError as err:
            expected_str = "error in partial of y wrt x1 in"
            self.assertTrue(expected_str in str(err),
                            msg="\n\nActual err msg:\n{} \n\ndoes not contain expected string:\n\n{}".format(str(err),
                                                                                                     expected_str))
        else:
            self.fail('Exception expected.')
Beispiel #15
0
def run_test(test_obj, comp, complex_flag=False, compact_print=True, method='fd', step=1e-6, atol=1e-5, rtol=1e-5, view=False):
    prob = Problem()
    prob.model.add_subsystem('comp', comp)
    prob.setup(force_alloc_complex=complex_flag)

    prob.run_model()

    if method=='cs':
        step = 1e-40

    check = prob.check_partials(compact_print=compact_print, method=method, step=step)

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

    assert_check_partials(check, atol=atol, rtol=rtol)

    return prob
    def test_scalex(self):
        symmetry = False
        mesh = get_mesh(symmetry)

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

        val = np.random.random(NY)

        comp = ScaleX(val=val, mesh_shape=mesh.shape)
        group.add_subsystem('comp', comp)

        prob.setup()

        prob['comp.in_mesh'] = mesh

        prob.run_model()

        check = prob.check_partials(compact_print=True,
                                    abs_err_tol=1e-5,
                                    rel_err_tol=1e-5)
        assert_check_partials(check, atol=1e-6, rtol=1e-6)
Beispiel #17
0
def test_average_multiple_matrix_along1():
    import omtools.examples.valid.ex_average_multiple_matrix_along1 as example

    n = 3
    m = 6

    M1 = np.arange(n * m).reshape((n, m))
    M2 = np.arange(n * m, 2 * n * m).reshape((n, m))

    desired_multiple_matrix_average_axis_1 = np.average((M1 + M2) / 2., axis=1)

    np.testing.assert_almost_equal(
        example.prob['multiple_matrix_average_along_1'],
        desired_multiple_matrix_average_axis_1)

    partials_error_multiple_matrix_axis_1 = example.prob.check_partials(
        includes=['comp_multiple_matrix_average_along_1'],
        out_stream=None,
        compact_print=True)
    assert_check_partials(partials_error_multiple_matrix_axis_1,
                          atol=1.e-6,
                          rtol=1.e-6)
Beispiel #18
0
    def test_scalar_with_guess_func(self):

        n = 1

        model=om.Group(assembled_jac_type='dense')

        def guess_function(inputs, outputs, residuals):
            outputs['x'] = np.sqrt(inputs['rhs:x'])

        bal = om.BalanceComp('x', guess_func=guess_function)  # test guess_func as kwarg

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

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

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

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

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

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

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

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

        # should converge with no iteration due to the guess function
        self.assertEqual(model.nonlinear_solver._iter_count, 1)

        cpd = prob.check_partials(out_stream=None)
        assert_check_partials(cpd, atol=1e-5, rtol=1e-5)
Beispiel #19
0
    def test_scalar(self):

        n = 1

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

        bal = om.BalanceComp()

        bal.add_balance('x')

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

        exec_comp = om.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 = om.DirectSolver(assemble_jac=True)

        prob.model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False, 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)

        assert_check_partials(cpd, atol=1e-5, rtol=1e-5)
Beispiel #20
0
    def test_complex_step(self):

        n = 1

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

        bal = om.BalanceComp()

        bal.add_balance('x')

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

        exec_comp = om.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 = om.DirectSolver(assemble_jac=True)

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

        prob.setup(force_alloc_complex=True)

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

        prob.run_model()

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

        assert_check_partials(cpd, atol=1e-10, rtol=1e-10)
Beispiel #21
0
    def test_vectorized(self):
        prob = Problem()
        model = prob.model

        n = 100

        # find intersection of two non-parallel lines, vectorized
        model.add_subsystem('indep', IndepVarComp('x', val=np.ones(n)))
        model.add_subsystem('f', ExecComp('y=3*x-3', x=np.ones(n), y=np.ones(n)))
        model.add_subsystem('g', ExecComp('y=2.3*x+4', x=np.ones(n), y=np.ones(n)))
        model.add_subsystem('equal', EQConstraintComp('y', val=np.ones(n), add_constraint=True))
        model.add_subsystem('obj_cmp', ExecComp('obj=sum(y)', y=np.zeros(n)))

        model.connect('indep.x', 'f.x')
        model.connect('indep.x', 'g.x')
        model.connect('f.y', 'equal.lhs:y')
        model.connect('g.y', 'equal.rhs:y')
        model.connect('f.y', 'obj_cmp.y')

        model.add_design_var('indep.x', lower=np.zeros(n), upper=20.*np.ones(n))
        model.add_objective('obj_cmp.obj')

        prob.setup(mode='fwd')

        prob.driver = ScipyOptimizeDriver(disp=False)

        prob.run_driver()

        assert_almost_equal(prob['equal.y'], np.zeros(n))
        assert_almost_equal(prob['indep.x'], np.ones(n)*10.)
        assert_almost_equal(prob['f.y'], np.ones(n)*27.)
        assert_almost_equal(prob['g.y'], np.ones(n)*27.)

        cpd = prob.check_partials(out_stream=None)

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

        assert_check_partials(cpd, atol=1e-5, rtol=1e-5)
Beispiel #22
0
    def test_create_on_init_add_constraint(self):
        prob = Problem()
        model = prob.model

        # find intersection of two non-parallel lines
        model.add_subsystem('indep', IndepVarComp('x', val=0.))
        model.add_subsystem('f', ExecComp('y=3*x-3', x=0.))
        model.add_subsystem('g', ExecComp('y=2.3*x+4', x=0.))
        model.add_subsystem('equal', EQConstraintComp('y', add_constraint=True))

        model.connect('indep.x', 'f.x')
        model.connect('indep.x', 'g.x')

        model.connect('f.y', 'equal.lhs:y')
        model.connect('g.y', 'equal.rhs:y')

        model.add_design_var('indep.x', lower=0., upper=20.)
        model.add_objective('f.y')

        prob.setup(mode='fwd')

        # verify that the constraint has been added as requested
        self.assertTrue('equal.y' in model.get_constraints())

        prob.driver = ScipyOptimizeDriver(disp=False)

        prob.run_driver()

        assert_almost_equal(prob['equal.y'], 0.)
        assert_almost_equal(prob['indep.x'], 10.)
        assert_almost_equal(prob['f.y'], 27.)
        assert_almost_equal(prob['g.y'], 27.)

        cpd = prob.check_partials(out_stream=None)

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

        assert_check_partials(cpd, atol=1e-5, rtol=1e-5)
    def test_quadratic_no_rate_units(self):
        num_nodes = self.num_nodes
        nn_tot = num_nodes
        x = np.linspace(0, nn_tot - 1, nn_tot)
        fprime = 4 * x**2 - 8 * x + 5
        f = 4 * x**3 / 3 - 8 * x**2 / 2 + 5 * x

        prob = Problem(
            IntegratorTestGroup(num_nodes=self.num_nodes,
                                integrator=self.integrator,
                                diff_units='s'))
        prob.setup(check=True, force_alloc_complex=True)
        prob['iv.rate_to_integrate'] = fprime
        prob.run_model()
        assert_near_equal(prob.get_val('integral.q', units=None),
                          f,
                          tolerance=1e-14)
        assert_near_equal(prob.get_val('integral.q_final', units=None),
                          f[-1],
                          tolerance=1e-14)
        partials = prob.check_partials(method='cs', compact_print=True)
        assert_check_partials(partials, atol=1e-8, rtol=1e0)
Beispiel #24
0
def test_average_single_tensor():
    import omtools.examples.valid.ex_average_single_tensor as example

    n = 3
    m = 6
    p = 7
    q = 10

    T1 = np.arange(n * m * p * q).reshape((n, m, p, q))

    desired_tensor_average = np.average(T1)

    np.testing.assert_almost_equal(example.prob['single_tensor_average'],
                                   desired_tensor_average)

    partials_error_tensor_average = example.prob.check_partials(
        includes=['comp_single_tensor_average'],
        out_stream=None,
        compact_print=True)
    assert_check_partials(partials_error_tensor_average,
                          atol=1.e-5,
                          rtol=1.e-5)
Beispiel #25
0
    def test_case1(self):
        # 4 cases to check against
        for i, data in enumerate(ref_data):
            self.prob['inlet.ram_recovery'] = data[h_map['eRamBase']]

            # input flowstation
            self.prob['flow_start.P'] = data[h_map['Fl_I.Pt']]
            self.prob['flow_start.T'] = data[h_map['Fl_I.Tt']]
            self.prob['inlet.MN'] = data[h_map['Fl_O.MN']]
            self.prob['flow_start.MN'] = data[h_map['Fl_I.MN']]
            self.prob['flow_start.W'] = data[h_map['Fl_I.W']]
            self.prob['inlet.Fl_I:stat:V'] = data[h_map['Fl_I.V']]

            self.prob.run_model()

            # check outputs

            pt, ht, Fram, ps, ts = data[h_map['Fl_O.Pt']], data[
                h_map['Fl_O.ht']], data[h_map['Fram']], data[
                    h_map['Fl_O.Ps']], data[h_map['Fl_O.Ts']]
            pt_computed = self.prob['inlet.Fl_O:tot:P']
            ht_computed = self.prob['inlet.Fl_O:tot:h']
            Fram_computed = self.prob['inlet.F_ram']
            ps_computed = self.prob['inlet.Fl_O:stat:P']
            ts_computed = self.prob['inlet.Fl_O:stat:T']

            tol = 1e-4
            assert_near_equal(pt_computed, pt, tol)
            assert_near_equal(ht_computed, ht, tol)
            assert_near_equal(Fram_computed, Fram, tol)
            assert_near_equal(ps_computed, ps, tol)
            assert_near_equal(ts_computed, ts, tol)

            partial_data = self.prob.check_partials(
                out_stream=None,
                method='cs',
                includes=['inlet.*'],
                excludes=['*.base_thermo.*'])
            assert_check_partials(partial_data, atol=1e-8, rtol=1e-8)
Beispiel #26
0
 def test_quadratic_three_phase_units_unequal_dt(self):
     n_int_per_seg = self.num_intervals
     nn_tot = (n_int_per_seg*2 + 1)
     x1 = np.linspace(0, nn_tot-1, nn_tot)
     x2 = np.linspace(nn_tot-1, 3*(nn_tot-1), nn_tot)
     x3 = np.linspace(3*(nn_tot-1), 6*(nn_tot-1), nn_tot)
     x = np.concatenate([x1, x2, x3])
     fprime = 4 * x **2 - 8*x + 5
     f = 4 * x ** 3 / 3 - 8 * x ** 2 / 2 + 5*x
     prob = Problem(MultiPhaseIntegratorTestGroup(segment_names=['climb','cruise','descent'],
                                                  num_intervals=self.num_intervals, integrator=self.integrator,
                                                  quantity_units='kg', diff_units='s'))
     prob.setup(check=True, force_alloc_complex=True)
     prob['iv.rate_to_integrate'] = fprime
     prob['iv.climb|dt'] = 1
     prob['iv.cruise|dt'] = 2
     prob['iv.descent|dt'] = 3
     prob.run_model()
     assert_rel_error(self, prob.get_val('integral.q', units='kg'), f, tolerance=1e-14)
     assert_rel_error(self, prob.get_val('integral.q_final', units='kg'), f[-1], tolerance=1e-14)
     partials = prob.check_partials(method='cs',compact_print=True)
     assert_check_partials(partials, atol=1e-8, rtol=1e0)
Beispiel #27
0
def test_reshape_tensor2vector():
    import omtools.examples.valid.ex_reshape_tensor2_vector as example

    i = 2
    j = 3
    k = 4
    l = 5
    shape = (i, j, k, l)

    tensor = np.arange(np.prod(shape)).reshape(shape)
    vector = np.arange(np.prod(shape))

    # TENSOR TO VECTOR
    desired_output = vector
    np.testing.assert_almost_equal(example.prob['reshape_tensor2vector'],
                                   desired_output)

    partials_error = example.prob.check_partials(
        includes=['comp_reshape_tensor2vector'],
        out_stream=None,
        compact_print=True)
    assert_check_partials(partials_error, atol=1.e-6, rtol=1.e-6)
Beispiel #28
0
    def test_comp(self):
        num_nodes = 3
        prob = Problem()
        prob.model.add_subsystem(
            'test',
            thermal.ThermalComponentWithMass(num_nodes=num_nodes),
            promotes=['*'])
        prob.setup(check=True, force_alloc_complex=True)

        # Set the values
        prob.set_val('q_in', np.array([10., 14., 4.]), units='kW')
        prob.set_val('q_out', np.array([9., 14., 12.]), units='kW')
        prob.set_val('mass', 7., units='kg')

        prob.run_model()

        assert_near_equal(prob.get_val('dTdt', units='K/s'),
                          np.array([.1551109043, 0., -1.2408872344]),
                          tolerance=1e-9)

        partials = prob.check_partials(method='cs', compact_print=True)
        assert_check_partials(partials)
Beispiel #29
0
    def test_ccblade_geometry(self):
        n_span = 10

        prob = om.Problem()

        comp = CCBladeGeometry(n_span=n_span)
        prob.model.add_subsystem("comp", comp, promotes=["*"])

        prob.setup(force_alloc_complex=True)

        prob.set_val("Rtip", 80.0, units="m")
        prob.set_val("precurve_in", np.random.rand(n_span), units="m")
        prob.set_val("presweep_in", np.random.rand(n_span), units="m")
        prob.set_val("precone", 2.2, units="deg")

        prob.run_model()

        check = prob.check_partials(out_stream=None,
                                    compact_print=True,
                                    method="fd")

        assert_check_partials(check)
Beispiel #30
0
    def test(self):

        nPoints = 20
        z = np.linspace(0.1, 100.0, nPoints)

        prob = om.Problem()
        root = prob.model = om.Group()
        root.add_subsystem('p', env.LogWind(nPoints=nPoints))

        prob.setup()

        prob['p.Uref'] = 10.0
        prob['p.zref'] = 100.0
        prob['p.z0'] = 0.1  #Fails when z0 = 0

        prob.run_model()

        check = prob.check_partials(out_stream=None,
                                    compact_print=True,
                                    method='fd')

        assert_check_partials(check)
Beispiel #31
0
 def test_nondefault_settings(self):
     prob = Problem(
         MotorTestGroup(
             vec_size=10,
             use_defaults=False,
             efficiency=0.95,
             weight_inc=1 / 3000,
             weight_base=2,
             cost_inc=1 / 500,
             cost_base=3,
         ))
     prob.setup(check=True, force_alloc_complex=True)
     prob.run_model()
     assert_rel_error(self,
                      prob.get_val('motor.shaft_power_out', units='kW'),
                      np.ones(10) * 90 * 0.95,
                      tolerance=1e-15)
     assert_rel_error(self,
                      prob.get_val('motor.elec_load', units='kW'),
                      np.ones(10) * 90,
                      tolerance=1e-15)
     assert_rel_error(self,
                      prob.get_val('motor.heat_out', units='kW'),
                      np.ones(10) * 90 * 0.05,
                      tolerance=1e-15)
     assert_rel_error(self,
                      prob.get_val('motor.component_sizing_margin'),
                      np.ones(10) * 0.90,
                      tolerance=1e-15)
     assert_rel_error(self,
                      prob.get_val('motor.component_cost', units='USD'),
                      203,
                      tolerance=1e-15)
     assert_rel_error(self,
                      prob.get_val('motor.component_weight', units='kg'),
                      35.333333333333333333,
                      tolerance=1e-10)
     partials = prob.check_partials(method='cs', compact_print=True)
     assert_check_partials(partials)
Beispiel #32
0
    def test_derivs_with_sideslip(self):
        surfaces = get_default_surfaces()

        # Use Tail since it is not symmetric.
        comp = LiftDrag(surface=surfaces[1])

        prob = Problem()
        prob.model.add_subsystem('comp', comp)
        prob.setup(force_alloc_complex=True)

        prob['comp.alpha'] = 3.0
        prob['comp.beta'] = 15.0
        prob['comp.sec_forces'] = 10.0 * np.random.random(
            prob['comp.sec_forces'].shape)

        prob.run_model()

        check = prob.check_partials(compact_print=True,
                                    method='cs',
                                    step=1e-40)

        assert_check_partials(check)
Beispiel #33
0
    def test_vectorized(self):
        nn = 5
        p = Problem()
        p.model = CFM56(num_nodes=nn)

        p.setup(force_alloc_complex=True)

        p.set_val('throttle', np.linspace(0.0001, 1., nn))
        p.set_val('fltcond|h', np.linspace(0, 40e3, nn), units='ft')
        p.set_val('fltcond|M', np.linspace(0.1, 0.9, nn))

        p.run_model()

        assert_near_equal(p.get_val('thrust', units='lbf'), np.array([1445.41349482, 3961.46624224,
                            5278.43191982, 5441.44404298, 6479.00525867]), tolerance=5e-3)
        assert_near_equal(p.get_val('fuel_flow', units='kg/s'), np.array([0.17032429, 0.25496437,
                            0.35745638, 0.40572545, 0.4924194]), tolerance=5e-3)
        assert_near_equal(p.get_val('T4', units='degK'), np.array([1005.38911171, 1207.57548728,
                            1381.94820904, 1508.07901676, 1665.37063872]), tolerance=5e-3)

        partials = p.check_partials(method='cs',compact_print=True)
        assert_check_partials(partials)
Beispiel #34
0
    def test_vectorized_all_derivs(self):

        xcp = np.array([1.0, 2.0, 4.0, 6.0, 10.0, 12.0])
        ycp = np.array([[5.0, 12.0, 14.0, 16.0, 21.0, 29.0],
                        [7.0, 13.0, 9.0, 6.0, 12.0, 14.0]])
        n = 12
        x = np.linspace(1.0, 12.0, n)

        for method in SPLINE_METHODS:

            prob = om.Problem()

            # These methods have their own test.
            if method in ['akima', 'bsplines']:
                continue

            opts = {}

            comp = om.SplineComp(method=method,
                                 vec_size=2,
                                 x_cp_val=xcp,
                                 x_interp_val=x,
                                 interp_options=opts)

            comp.add_spline(y_cp_name='ycp',
                            y_interp_name='y_val',
                            y_cp_val=ycp)
            prob.model.add_subsystem('interp1', comp)

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

            if method.startswith('scipy'):
                derivs = prob.check_partials(out_stream=None)
                assert_check_partials(derivs, atol=1e-7, rtol=1e-7)

            else:
                derivs = prob.check_partials(out_stream=None, method='cs')
                assert_check_partials(derivs, atol=1e-12, rtol=1e-12)
    def test_specified_shape_rhs_val(self):
        prob = om.Problem()
        model = prob.model

        shape = (3, 2, 4)

        rhs = np.zeros(shape)

        model.add_subsystem('indep', om.IndepVarComp('x', val=np.ones(shape)))
        model.add_subsystem(
            'equal', om.EQConstraintComp('y', val=np.ones(shape), rhs_val=rhs))

        model.connect('indep.x', 'equal.lhs:y')

        prob.setup()
        prob.run_model()

        assert_near_equal(prob['equal.y'], np.ones(shape) - rhs, 1e-6)

        cpd = prob.check_partials(out_stream=None)

        assert_check_partials(cpd, atol=1e-5, rtol=1e-5)
Beispiel #36
0
    def check_derivs(self, mode, shape, use_jit):
        def func(a, b, c):
            x = np.sin(a) * b + 3. * c
            return x

        f = omf.wrap(func).defaults(shape=shape).declare_partials(of='*', wrt='*', method='jax')
        p = om.Problem()
        p.model.add_subsystem('comp', om.ExplicitFuncComp(f, use_jax=True, use_jit=use_jit))
        p.setup(mode=mode)
        p['comp.a'] = 1.0
        p['comp.b'] = 2.0
        p['comp.c'] = 3.0
        p.run_model()

        assert_check_partials(p.check_partials(includes=['comp'], method='fd', out_stream=None), atol=1e-5)

        J = p.compute_totals(of=['comp.x'], wrt=['comp.a', 'comp.b', 'comp.c'])

        I = np.eye(np.product(shape)) if shape else np.eye(1)
        assert_near_equal(J['comp.x', 'comp.a'], I * p['comp.b'].ravel() * np.cos(p['comp.a']).ravel(), tolerance=1e-7)
        assert_near_equal(J['comp.x', 'comp.b'], I * np.sin(p['comp.a']).ravel(), tolerance=1e-7)
        assert_near_equal(J['comp.x', 'comp.c'], I * 3., tolerance=1e-7)
Beispiel #37
0
    def test_distributions(self):
        nspline = 10

        prob = om.Problem()

        prob.model.add_subsystem("comp1", WeibullCDF(nspline=nspline), promotes_inputs=["*"])
        prob.model.add_subsystem("comp2", WeibullWithMeanCDF(nspline=nspline), promotes_inputs=["*"])
        prob.model.add_subsystem("comp3", RayleighCDF(nspline=nspline), promotes_inputs=["*"])

        prob.setup(force_alloc_complex=True)

        # Add some arbitrary inputs
        prob.set_val("x", np.random.rand(nspline), units="m/s")
        prob.set_val("xbar", 1.5, units="m/s")
        prob.set_val("k", 1.5)
        prob.set_val("A", 1.2)

        prob.run_model()

        check = prob.check_partials(out_stream=None, compact_print=True, method="fd")

        assert_check_partials(check, atol=1e-5)
Beispiel #38
0
    def test_bspline_interp_basic(self):
        prob = om.Problem()
        model = prob.model

        n_cp = 80
        n_point = 160

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

        model.add_subsystem('px', om.IndepVarComp('x', val=x))

        bspline_options = {'order': 4}
        comp = om.SplineComp(method='bsplines', x_interp_val=tt, num_cp=n_cp,
                            interp_options=bspline_options)

        prob.model.add_subsystem('interp', comp)

        comp.add_spline(y_cp_name='h_cp', y_interp_name='h', y_cp_val=x, y_units='km')

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

        prob.setup(force_alloc_complex=True)
        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)

        derivs = prob.check_partials(out_stream=None, method='cs')
        assert_check_partials(derivs, atol=1e-14, rtol=1e-14)
    def test_777ish_regression(self):
        nx = 3
        ny = 4
        p = om.Problem(PlanformMesh(num_x=nx, num_y=ny))
        p.setup()
        p.set_val("S", 427.8, units="m**2")
        p.set_val("AR", 9.82)
        p.set_val("taper", 0.149)
        p.set_val("sweep", 31.6, units="deg")
        p.run_model()

        mesh = np.array([
            [
                [19.50929722, -32.40754542, 0.0],
                [12.04879827, -21.60503028, 0.0],
                [4.58829932, -10.80251514, 0.0],
                [-2.87219963, 0.0, 0.0],
            ],
            [
                [20.36521271, -32.40754542, 0.0],
                [14.53420835, -21.60503028, 0.0],
                [8.70320399, -10.80251514, 0.0],
                [2.87219963, 0.0, 0.0],
            ],
            [
                [21.2211282, -32.40754542, 0.0],
                [17.01961843, -21.60503028, 0.0],
                [12.81810866, -10.80251514, 0.0],
                [8.61659889, 0.0, 0.0],
            ],
        ])

        assert_near_equal(p.get_val("mesh", units="m"), mesh, tolerance=1e-10)

        partials = p.check_partials(out_stream=None,
                                    compact_print=True,
                                    show_only_incorrect=True)
        assert_check_partials(partials, atol=2e-5)
    def test_case1(self):

        # 6 cases to check against
        for i, data in enumerate(ref_data):
            self.prob['fc.alt'] = data[h_map['alt']]
            self.prob['fc.MN'] = data[h_map['MN']]
            self.prob['fc.dTs'] = data[h_map['dTs']]

            if self.prob['fc.MN'] < 1e-10:
                self.prob['fc.MN'] += 1e-6

            self.prob.run_model()

            # check outputs
            Pt = data[h_map['Pt']]
            Pt_c = self.prob['fc.Fl_O:tot:P']

            Ps = data[h_map['Ps']]
            Ps_c = self.prob['fc.Fl_O:stat:P']

            Tt = data[h_map['Tt']]
            Tt_c = self.prob['fc.Fl_O:tot:T']

            Ts = data[h_map['Ts']]
            Ts_c = self.prob['fc.Fl_O:stat:T']

            tol = 1e-4
            assert_near_equal(Pt_c, Pt, tol)
            assert_near_equal(Ps_c, Ps, tol)
            assert_near_equal(Tt_c, Tt, tol)
            assert_near_equal(Ps_c, Ps, tol)

            partial_data = self.prob.check_partials(
                out_stream=None,
                method='cs',
                includes=['fc.*'],
                excludes=['*.base_thermo.*', 'fc.ambient.readAtmTable'])
            assert_check_partials(partial_data, atol=1e-8, rtol=1e-8)
    def test_complex_step_multipoint(self):
        E = 1.
        L = 1.
        b = 0.1
        volume = 0.01

        num_cp = 5
        num_elements = 50
        num_load_cases = 2

        model = MultipointBeamGroup(E=E,
                                    L=L,
                                    b=b,
                                    volume=volume,
                                    num_elements=num_elements,
                                    num_cp=num_cp,
                                    num_load_cases=num_load_cases)

        prob = om.Problem(model=model)

        prob.driver = om.ScipyOptimizeDriver()
        prob.driver.options['optimizer'] = 'SLSQP'
        prob.driver.options['tol'] = 1e-9
        prob.driver.options['disp'] = True

        prob.setup(force_alloc_complex=True)

        prob.run_model()

        derivs = prob.check_totals(method='cs', out_stream=None)
        assert_near_equal(
            derivs[('obj_sum.obj', 'interp.h_cp')]['rel error'][0], 0.0, 1e-8)
        assert_near_equal(
            derivs[('volume_comp.volume', 'interp.h_cp')]['rel error'][0], 0.0,
            1e-8)

        derivs = prob.check_partials(method='cs', out_stream=None)
        assert_check_partials(derivs, rtol=1e-15)
Beispiel #42
0
    def test_partials(self):
        self.p.setup(force_alloc_complex=True)

        v0 = 100.0
        gam0 = np.radians(30.0)
        t_duration = 10.0

        phase = self.p.model.phase0

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

        self.p['phase0.states:r'] = phase.interpolate(ys=[0, v0 * np.cos(gam0) * t_duration],
                                                      nodes='state_disc')
        self.p['phase0.states:h'] = phase.interpolate(ys=[0, 0], nodes='state_input')
        self.p['phase0.states:v'] = phase.interpolate(ys=[v0, v0], nodes='state_input')
        self.p['phase0.states:gam'] = phase.interpolate(ys=[gam0, -gam0], nodes='state_input')

        self.p.run_model()

        cpd = self.p.check_partials(compact_print=True, method='cs')

        assert_check_partials(cpd)
Beispiel #43
0
    def test_default_settings(self):
        prob = Problem(BatteryTestGroup(vec_size=10, use_defaults=True))
        prob.setup(check=True, force_alloc_complex=True)
        prob.run_model()
        assert_rel_error(self,
                         prob['battery.heat_out'],
                         np.ones(10) * 100 * 0.0,
                         tolerance=1e-15)
        assert_rel_error(self,
                         prob['battery.component_sizing_margin'],
                         np.ones(10) * 0.20,
                         tolerance=1e-15)
        assert_rel_error(self,
                         prob['battery.component_cost'],
                         5001,
                         tolerance=1e-15)
        assert_rel_error(self,
                         prob.get_val('battery.max_energy', units='W*h'),
                         300 * 100,
                         tolerance=1e-15)

        partials = prob.check_partials(method='cs', compact_print=True)
        assert_check_partials(partials)
    def test_scale_to_pg(self):
        surfaces = get_default_surfaces()

        comp = ScaleToPrandtlGlauert(surfaces=surfaces, rotational=True)

        prob = om.Problem()
        prob.model.add_subsystem('comp', comp)
        prob.setup(force_alloc_complex=True)

        prob['comp.Mach_number'] = np.random.random(prob['comp.Mach_number'].shape)
        prob['comp.coll_pts_w_frame'] = np.random.random(prob['comp.coll_pts_w_frame'].shape)
        prob['comp.bound_vecs_w_frame'] = np.random.random(prob['comp.bound_vecs_w_frame'].shape)
        prob['comp.rotational_velocities_w_frame'] = np.random.random(prob['comp.rotational_velocities_w_frame'].shape)
        prob['comp.wing_def_mesh_w_frame'] = np.random.random(prob['comp.wing_def_mesh_w_frame'].shape)
        prob['comp.tail_def_mesh_w_frame'] = np.random.random(prob['comp.tail_def_mesh_w_frame'].shape)
        prob['comp.tail_normals_w_frame'] = np.random.random(prob['comp.tail_normals_w_frame'].shape)
        prob['comp.wing_normals_w_frame'] = np.random.random(prob['comp.wing_normals_w_frame'].shape)

        prob.run_model()

        check = prob.check_partials(compact_print=True, method='cs', step=1e-40)

        assert_check_partials(check)
    def test_taper(self):
        nx = 2
        ny = 3
        p = om.Problem(PlanformMesh(num_x=nx, num_y=ny))
        p.setup()
        p.set_val("S", 1.3, units="m**2")
        p.set_val("AR",
                  4 / 1.3)  # pick S and AR for half span and root chord of 1
        p.set_val("taper", 0.3)
        p.set_val("sweep", 0.0, units="deg")
        p.run_model()

        mesh = np.zeros((nx, ny, 3))
        mesh[:, :, 0] = np.array([[-0.075, -0.1625, -0.25],
                                  [0.225, 0.4875, 0.75]])
        mesh[:, :, 1] = np.array([[-1, -0.5, 0], [-1, -0.5, 0]])

        assert_near_equal(p.get_val("mesh", units="m"), mesh)

        partials = p.check_partials(out_stream=None,
                                    compact_print=True,
                                    show_only_incorrect=True)
        assert_check_partials(partials)
    def test_renamed_vars(self):
        prob = Problem()
        model = prob.model

        # find intersection of two non-parallel lines, fx_y and gx_y
        equal = EQConstraintComp('y', lhs_name='fx_y', rhs_name='gx_y',
                                        add_constraint=True)

        model.add_subsystem('indep', IndepVarComp('x', val=0.))
        model.add_subsystem('f', ExecComp('y=3*x-3', x=0.))
        model.add_subsystem('g', ExecComp('y=2.3*x+4', x=0.))
        model.add_subsystem('equal', equal)

        model.connect('indep.x', 'f.x')
        model.connect('indep.x', 'g.x')

        model.connect('f.y', 'equal.fx_y')
        model.connect('g.y', 'equal.gx_y')

        model.add_design_var('indep.x', lower=0., upper=20.)
        model.add_objective('f.y')

        prob.setup(mode='fwd')
        prob.driver = ScipyOptimizeDriver(disp=False)
        prob.run_driver()

        assert_almost_equal(prob['equal.y'], 0.)
        assert_almost_equal(prob['indep.x'], 10.)
        assert_almost_equal(prob['f.y'], 27.)
        assert_almost_equal(prob['g.y'], 27.)

        cpd = prob.check_partials(out_stream=None)

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

        assert_check_partials(cpd, atol=1e-5, rtol=1e-5)
    def test(self):
        """
        This is an opt problem that tests the wingbox model with wave drag and the fuel vol constraint
        """

        # Create a dictionary to store options about the surface
        mesh_dict = {'num_y' : 7,
                     'num_x' : 2,
                     'wing_type' : 'CRM',
                     'symmetry' : True,
                     'num_twist_cp' : 6,
                     'chord_cos_spacing' : 0,
                     'span_cos_spacing' : 0,
                     }

        mesh, twist_cp = 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' : 'wingbox',

                    'spar_thickness_cp' : np.array([0.004, 0.005, 0.005, 0.008, 0.008, 0.01]), # [m]
                    'skin_thickness_cp' : np.array([0.005, 0.01, 0.015, 0.020, 0.025, 0.026]),
                    'twist_cp' : np.array([4., 5., 8., 8., 8., 9.]),
                    'mesh' : mesh,

                    'data_x_upper' : upper_x,
                    'data_x_lower' : lower_x,
                    'data_y_upper' : upper_y,
                    'data_y_lower' : lower_y,
                    'strength_factor_for_upper_skin' : 1.,

                    # 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.0078,            # 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.08, 0.08, 0.08, 0.10, 0.10, 0.08]),
                    'original_wingbox_airfoil_t_over_c' : 0.12,
                    'c_max_t' : .38,       # chordwise location of maximum thickness
                    'with_viscous' : True,
                    'with_wave' : True,     # if true, compute wave drag

                    # Structural values are based on aluminum 7075
                    'E' : 73.1e9,              # [Pa] Young's modulus
                    'G' : (73.1e9/2/1.33),     # [Pa] shear modulus (calculated using E and the Poisson's ratio here)
                    'yield' : (420.e6 / 1.5),  # [Pa] allowable yield stress
                    'mrho' : 2.78e3,           # [kg/m^3] material density
                    'strength_factor_for_upper_skin' : 1.0, # the yield stress is multiplied by this factor for the upper skin
                    # 'fem_origin' : 0.35,    # normalized chordwise location of the spar
                    'wing_weight_ratio' : 1.25,
                    'struct_weight_relief' : True,
                    'distributed_fuel_weight' : True,
                    # Constraints
                    'exact_failure_constraint' : False, # if false, use KS function
                    'fuel_density' : 803.,      # [kg/m^3] fuel density (only needed if the fuel-in-wing volume constraint is used)
                    'Wf_reserve' :15000.,       # [kg] reserve fuel mass
                    }

        surfaces = [surf_dict]

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

        # Add problem information as an independent variables component
        indep_var_comp = IndepVarComp()
        indep_var_comp.add_output('v', val=.85 * 295.07, units='m/s')
        indep_var_comp.add_output('alpha', val=0., units='deg')
        indep_var_comp.add_output('Mach_number', val=0.85)
        indep_var_comp.add_output('re', val=0.348*295.07*.85*1./(1.43*1e-5), units='1/m')
        indep_var_comp.add_output('rho', val=0.348, units='kg/m**3')
        indep_var_comp.add_output('CT', val=0.53/3600, units='1/s')
        indep_var_comp.add_output('R', val=14.307e6, units='m')
        indep_var_comp.add_output('W0', val=148000 + surf_dict['Wf_reserve'],  units='kg')
        indep_var_comp.add_output('speed_of_sound', val=295.07, units='m/s')
        indep_var_comp.add_output('load_factor', val=np.array([1., 2.5]))
        indep_var_comp.add_output('empty_cg', val=np.zeros((3)), units='m')
        indep_var_comp.add_output('fuel_mass', val=10000., units='kg')

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

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

            # Get the surface name and create a group to contain components
            # only for this surface
            name = surface['name']

            aerostruct_group = AerostructGeometry(surface=surface)

            # Add tmp_group to the problem with the name of the surface.
            prob.model.add_subsystem(name, aerostruct_group)

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

            point_name = 'AS_point_{}'.format(i)
            # Connect the parameters within the model for each aero point

            # Create the aero point group and add it to the model
            AS_point = AerostructPoint(surfaces=surfaces, internally_connect_fuelburn=False)

            prob.model.add_subsystem(point_name, AS_point)

            # 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('CT', point_name + '.CT')
            prob.model.connect('R', point_name + '.R')
            prob.model.connect('W0', point_name + '.W0')
            prob.model.connect('speed_of_sound', point_name + '.speed_of_sound')
            prob.model.connect('empty_cg', point_name + '.empty_cg')
            prob.model.connect('load_factor', point_name + '.load_factor', src_indices=[i])
            prob.model.connect('fuel_mass', point_name + '.total_perf.L_equals_W.fuelburn')
            prob.model.connect('fuel_mass', point_name + '.total_perf.CG.fuelburn')

            for surface in surfaces:

                prob.model.connect('load_factor', point_name + '.coupled.load_factor', src_indices=[i])

                com_name = point_name + '.' + name + '_perf.'
                prob.model.connect(name + '.local_stiff_transformed', point_name + '.coupled.' + name + '.local_stiff_transformed')
                prob.model.connect(name + '.nodes', point_name + '.coupled.' + name + '.nodes')

                # Connect aerodyamic mesh to coupled group mesh
                prob.model.connect(name + '.mesh', point_name + '.coupled.' + name + '.mesh')
                prob.model.connect(name + '.element_mass', point_name + '.coupled.' + name + '.element_mass')

                # Connect performance calculation variables
                prob.model.connect(name + '.nodes', com_name + 'nodes')
                prob.model.connect(name + '.cg_location', point_name + '.' + 'total_perf.' + name + '_cg_location')
                prob.model.connect(name + '.structural_mass', point_name + '.' + 'total_perf.' + name + '_structural_mass')

                # Connect wingbox properties to von Mises stress calcs
                prob.model.connect(name + '.Qz', com_name + 'Qz')
                prob.model.connect(name + '.J', com_name + 'J')
                prob.model.connect(name + '.A_enc', com_name + 'A_enc')
                prob.model.connect(name + '.htop', com_name + 'htop')
                prob.model.connect(name + '.hbottom', com_name + 'hbottom')
                prob.model.connect(name + '.hfront', com_name + 'hfront')
                prob.model.connect(name + '.hrear', com_name + 'hrear')

                prob.model.connect(name + '.spar_thickness', com_name + 'spar_thickness')
                prob.model.connect(name + '.t_over_c', com_name + 't_over_c')

        #=======================================================================================
        # Here we add the fuel volume constraint componenet to the model
        #=======================================================================================
        prob.model.add_subsystem('fuel_vol_delta', WingboxFuelVolDelta(surface=surface))
        prob.model.connect('wing.struct_setup.fuel_vols', 'fuel_vol_delta.fuel_vols')

        prob.model.connect('AS_point_0.fuelburn', 'fuel_vol_delta.fuelburn')
        prob.model.connect('wing.struct_setup.fuel_vols', 'AS_point_0.coupled.wing.struct_states.fuel_vols')
        prob.model.connect('fuel_mass', 'AS_point_0.coupled.wing.struct_states.fuel_mass')

        prob.model.connect('wing.struct_setup.fuel_vols', 'AS_point_1.coupled.wing.struct_states.fuel_vols')
        prob.model.connect('fuel_mass', 'AS_point_1.coupled.wing.struct_states.fuel_mass')

        comp = ExecComp('fuel_diff = (fuel_mass - fuelburn) / fuelburn', units='kg')
        prob.model.add_subsystem('fuel_diff', comp,
            promotes_inputs=['fuel_mass'],
            promotes_outputs=['fuel_diff'])
        prob.model.connect('AS_point_0.fuelburn', 'fuel_diff.fuelburn')

        comp = ExecComp('fuel_diff_25 = (fuel_mass - fuelburn) / fuelburn')
        prob.model.add_subsystem('fuel_diff_25', comp,
            promotes_inputs=['fuel_mass'],
            promotes_outputs=['fuel_diff_25'])
        prob.model.connect('AS_point_1.fuelburn', 'fuel_diff_25.fuelburn')
        #=======================================================================================
        #=======================================================================================

        from openmdao.api import ScipyOptimizeDriver
        prob.driver = ScipyOptimizeDriver()
        prob.driver.options['tol'] = 1e-9
        prob.driver.options['maxiter'] = 5

        # from openmdao.api import pyOptSparseDriver
        # prob.driver = pyOptSparseDriver()
        # prob.driver.add_recorder(SqliteRecorder("cases.sql"))
        # prob.driver.options['optimizer'] = "SNOPT"
        # prob.driver.opt_settings['Major optimality tolerance'] = 1e-6
        # prob.driver.opt_settings['Major feasibility tolerance'] = 1e-8
        # prob.driver.opt_settings['Major iterations limit'] = 200

        prob.model.add_objective('AS_point_0.fuelburn', scaler=1e-5)

        prob.model.add_design_var('wing.twist_cp', lower=-15., upper=15., scaler=0.1)
        prob.model.add_design_var('wing.spar_thickness_cp', lower=0.003, upper=0.1, scaler=1e2)
        prob.model.add_design_var('wing.skin_thickness_cp', lower=0.003, upper=0.1, scaler=1e2)
        prob.model.add_design_var('wing.geometry.t_over_c_cp', lower=0.07, upper=0.2, scaler=10.)
        prob.model.add_design_var('fuel_mass', lower=0., upper=2e5, scaler=1e-5)

        prob.model.add_constraint('AS_point_0.CL', equals=0.5)
        prob.model.add_constraint('AS_point_0.wing_perf.failure', upper=0.)

        #=======================================================================================
        # Here we add the fuel volume constraint
        #=======================================================================================
        prob.model.add_constraint('fuel_vol_delta.fuel_vol_delta', lower=0.)
        prob.model.add_constraint('fuel_diff', equals=0.)
        prob.model.add_constraint('fuel_diff_25', equals=0.)
        #=======================================================================================
        #=======================================================================================

        # Set up the problem
        prob.setup()

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

        prob.run_model()

        # Check the partials at the initial point in the design space,
        # only care about relative error
        data = prob.check_partials(compact_print=True, out_stream=None, method='cs', step=1e-40)
        assert_check_partials(data, atol=1e20, rtol=1e-6)

        # Run the optimizer for 5 iterations
        prob.run_driver()

        # 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_partials(self):
     partials = self.p.check_partials(method='fd', out_stream=None)
     assert_check_partials(partials)
Beispiel #49
0
 def test_partials(self):
     np.set_printoptions(linewidth=1024)
     cpd = self.p.check_partials(compact_print=False, method='cs', out_stream=None)
     assert_check_partials(cpd, atol=1.0E-8, rtol=1.0E-8)
    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
                    'type' : 'aero',
                    '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('M', 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('M', point_name + '.M')
            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(self):

        # Create a dictionary to store options about the surface
        mesh_dict = {'num_y' : 7,
                    'wing_type' : 'uCRM_based',
                    'symmetry' : True,
                    'num_twist_cp' : 5}

        mesh, twist_cp = generate_mesh(mesh_dict)

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

                    'spar_thickness_cp' : np.array([0.004, 0.005, 0.005, 0.008, 0.008, 0.01]), # [m]
                    'skin_thickness_cp' : np.array([0.005, 0.01, 0.015, 0.020, 0.025, 0.026]),
                    'twist_cp' : np.array([4., 5., 8., 8., 8., 9.]),
                    'mesh' : mesh,

                    'data_x_upper' : upper_x,
                    'data_x_lower' : lower_x,
                    'data_y_upper' : upper_y,
                    'data_y_lower' : lower_y,
                    'strength_factor_for_upper_skin' : 1.,

                    # 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.0078,            # 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.08, 0.08, 0.08, 0.10, 0.10, 0.08]),
                    'original_wingbox_airfoil_t_over_c' : 0.12,
                    'c_max_t' : .38,       # chordwise location of maximum thickness
                    'with_viscous' : True,
                    'with_wave' : True,     # if true, compute wave drag

                    # Structural values are based on aluminum 7075
                    'E' : 73.1e9,              # [Pa] Young's modulus
                    'G' : (73.1e9/2/1.33),     # [Pa] shear modulus (calculated using E and the Poisson's ratio here)
                    'yield' : (420.e6 / 1.5),  # [Pa] allowable yield stress
                    'mrho' : 2.78e3,           # [kg/m^3] material density
                    'strength_factor_for_upper_skin' : 1.0, # the yield stress is multiplied by this factor for the upper skin
                    # 'fem_origin' : 0.35,    # normalized chordwise location of the spar
                    'wing_weight_ratio' : 1.25,
                    'struct_weight_relief' : False,
                    'distributed_fuel_weight' : True,
                    # Constraints
                    'exact_failure_constraint' : True, # if false, use KS function
                    'fuel_density' : 803.,      # [kg/m^3] fuel density (only needed if the fuel-in-wing volume constraint is used)
                    'Wf_reserve' :15000.,       # [kg] reserve fuel mass
                    }

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

        ny = surf_dict['mesh'].shape[1]

        indep_var_comp = IndepVarComp()
        indep_var_comp.add_output('loads', val=np.ones((ny, 6)) * 2e5, units='N')
        indep_var_comp.add_output('load_factor', val=1.)
        indep_var_comp.add_output('fuel_mass', val=10000., units='kg')
        struct_group = SpatialBeamAlone(surface=surf_dict)
        # Add indep_vars to the structural group
        struct_group.add_subsystem('indep_vars',
            indep_var_comp,
            promotes=['*'])
        prob.model.add_subsystem(surf_dict['name'], struct_group)
        if surf_dict['distributed_fuel_weight']:
            prob.model.connect('wing.fuel_mass', 'wing.struct_states.fuel_mass')
            prob.model.connect('wing.struct_setup.fuel_vols', 'wing.struct_states.fuel_vols')

        from openmdao.api import ScipyOptimizeDriver
        prob.driver = ScipyOptimizeDriver()
        prob.driver.options['tol'] = 1e-9

        # Setup problem and add design variables, constraint, and objective
        prob.model.add_design_var('wing.spar_thickness_cp', lower=0.01, upper=0.5, ref=1e-1)
        prob.model.add_design_var('wing.skin_thickness_cp', lower=0.01, upper=0.5, ref=1e-1)
        prob.model.add_constraint('wing.failure', upper=0.)
        #prob.model.add_constraint('wing.thickness_intersects', upper=0.)

        # Add design variables, constraisnt, and objective on the problem
        prob.model.add_objective('wing.structural_mass', scaler=1e-5)

        # Set up the problem
        prob.setup(force_alloc_complex=False)

        prob.run_model()
        data = prob.check_partials(compact_print=True, out_stream=None, method='fd')
        assert_check_partials(data, atol=1e20, rtol=1e-6)

        prob.run_driver()
        assert_rel_error(self, prob['wing.structural_mass'], 16704.07393593, 1e-6)
    def test_derivs_wetted(self):
        # This is a much richer test with the following attributes:
        # - 5x7 mesh so that each dimension of all variables is unique.
        # - Random values given as inputs.
        # - The mesh has been given a random z height at all points.
        # - S_ref_type option is "wetted"
        # Create a dictionary to store options about the mesh
        mesh_dict = {'num_y' : 7,
                     'num_x' : 5,
                     'wing_type' : 'CRM',
                     'symmetry' : True,
                     'num_twist_cp' : 5}

        # Generate the aerodynamic mesh based on the previous dictionary
        mesh, twist_cp = generate_mesh(mesh_dict)

        mesh[:, :, 2] = np.random.random(mesh[:, :, 2].shape)

        # Create a dictionary with info and options about the aerodynamic
        # lifting surface
        surface = {
                    # Wing definition
                    'name' : 'wing',        # name of the surface
                    'type' : 'aero',
                    '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',

                    'twist_cp' : twist_cp,
                    '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
                    }

        #surfaces = get_default_surfaces()
        surfaces = [surface]

        prob = Problem()
        group = prob.model

        comp = VLMGeometry(surface=surfaces[0])

        indep_var_comp = IndepVarComp()
        indep_var_comp.add_output('def_mesh', val=surfaces[0]['mesh'], units='m')

        group.add_subsystem('geom', comp)
        group.add_subsystem('indep_var_comp', indep_var_comp)

        group.connect('indep_var_comp.def_mesh', 'geom.def_mesh')

        prob.setup()

        prob['geom.def_mesh'] = np.random.random(prob['geom.def_mesh'].shape)

        prob.run_model()

        check = prob.check_partials(compact_print=True)
        assert_check_partials(check, atol=3e-5, rtol=1e-5)