コード例 #1
0
 def test_one_to_two_fd(self):
     
     top = set_as_top(Assembly())
     
     exp1 = ["y1 = 3.0*x", "y2 = 4.0*x"]
     exp2 = ["y = -2.0*x"]
     exp3 = ["y = 5.0*x"]
     
     deriv1 = ["dy1_dx = 3.0", "dy2_dx = 4.0"]
     deriv2 = ["dy_dx = -2.0"]
     deriv3 = ["dy_dx = 5.0"]
     
     top.add('comp1', ExecCompWithDerivatives(exp1, deriv1))
     top.add('comp2', ExecCompWithDerivatives(exp2, deriv2))
     top.add('comp3', ExecCompWithDerivatives(exp3, deriv3))
     top.add('driver', SimpleDriver())
     
     top.driver.workflow.add(['comp1', 'comp2', 'comp3'])
     top.connect('comp1.y1', 'comp2.x')
     top.connect('comp1.y2', 'comp3.x')
     top.driver.add_parameter('comp1.x', low=-100, high=100)
     top.driver.add_constraint('comp2.y < 1000')
     top.driver.add_constraint('comp3.y < 1000')
     top.run()
     
     J = top.driver.workflow.calc_gradient(mode='fd',
                                           return_format='dict')
     J = top.driver.workflow._system.get_combined_J(J)
     
     collective_assert_rel_error(self, 
                                 J['_pseudo_0.out0']['comp1.x'][0][0], 
                                 -6.0, 0.0001)
     collective_assert_rel_error(self,
                                 J['_pseudo_1.out0']['comp1.x'][0][0], 
                                 20.0, 0.0001)        
コード例 #2
0
    def test_parameter_groups(self):

        self.top = set_as_top(Assembly())

        exp1 = ['y = 2.0*x']
        deriv1 = ['dy_dx = 2.0']
        self.top.add('driver', Driv())

        self.top.add('comp1', ExecCompWithDerivatives(exp1, deriv1))
        self.top.add('comp2', ExecCompWithDerivatives(exp1, deriv1))

        self.top.driver.workflow.add(['comp1', 'comp2'])

        # Top driver setup
        self.top.driver.differentiator = Analytic()
        obj = 'comp1.y+comp2.y'
        self.top.driver.add_parameter(['comp1.x', 'comp2.x'],
                                      low=-100.,
                                      high=100.,
                                      fd_step=.001)
        self.top.driver.add_objective(obj)

        self.top.comp1.x1 = 1.0
        self.top.comp2.x2 = 1.0
        self.top.run()
        self.top.driver.differentiator.calc_gradient()

        grad = self.top.driver.differentiator.get_gradient(obj)
        assert_rel_error(self, grad[0], 4.0, .001)
コード例 #3
0
    def test_diverge_converge_LinGS_adjoint(self):
        
        self.top = set_as_top(Assembly())

        exp1 = ['y1 = 2.0*x1**2',
                'y2 = 3.0*x1']
        deriv1 = ['dy1_dx1 = 4.0*x1',
                  'dy2_dx1 = 3.0']

        exp2 = ['y1 = 0.5*x1']
        deriv2 = ['dy1_dx1 = 0.5']

        exp3 = ['y1 = 3.5*x1']
        deriv3 = ['dy1_dx1 = 3.5']

        exp4 = ['y1 = x1 + 2.0*x2',
                'y2 = 3.0*x1',
                'y3 = x1*x2']
        deriv4 = ['dy1_dx1 = 1.0',
                  'dy1_dx2 = 2.0',
                  'dy2_dx1 = 3.0',
                  'dy2_dx2 = 0.0',
                  'dy3_dx1 = x2',
                  'dy3_dx2 = x1']

        exp5 = ['y1 = x1 + 3.0*x2 + 2.0*x3']
        deriv5 = ['dy1_dx1 = 1.0',
                  'dy1_dx2 = 3.0',
                  'dy1_dx3 = 2.0']

        self.top.add('comp1', ExecCompWithDerivatives(exp1, deriv1))
        self.top.add('comp2', ExecCompWithDerivatives(exp2, deriv2))
        self.top.add('comp3', ExecCompWithDerivatives(exp3, deriv3))
        self.top.add('comp4', ExecCompWithDerivatives(exp4, deriv4))
        self.top.add('comp5', ExecCompWithDerivatives(exp5, deriv5))

        self.top.driver.workflow.add(['comp1', 'comp2', 'comp3', 'comp4', 'comp5'])

        self.top.connect('comp1.y1', 'comp2.x1')
        self.top.connect('comp1.y2', 'comp3.x1')
        self.top.connect('comp2.y1', 'comp4.x1')
        self.top.connect('comp3.y1', 'comp4.x2')
        self.top.connect('comp4.y1', 'comp5.x1')
        self.top.connect('comp4.y2', 'comp5.x2')
        self.top.connect('comp4.y3', 'comp5.x3')
        
        self.top.comp1.x1 = 2.0        
        self.top.driver.gradient_options.lin_solver = 'linear_gs'
        self.top.driver.gradient_options.maxiter = 1
        self.top.run()

        J = self.top.driver.calc_gradient(inputs=['comp1.x1'],
                                          outputs=['comp5.y1'],
                                          mode='adjoint',
                                          return_format='dict')
        
        collective_assert_rel_error(self, 
                                    J['comp5.y1']['comp1.x1'][0][0], 
                                    313.0, 0.0001)
コード例 #4
0
    def test_diverge_converge_adjoint(self):
        
        self.top = set_as_top(Assembly())

        exp1 = ['y1 = 2.0*x1**2',
                'y2 = 3.0*x1']
        deriv1 = ['dy1_dx1 = 4.0*x1',
                  'dy2_dx1 = 3.0']

        exp2 = ['y1 = 0.5*x1']
        deriv2 = ['dy1_dx1 = 0.5']

        exp3 = ['y1 = 3.5*x1']
        deriv3 = ['dy1_dx1 = 3.5']

        exp4 = ['y1 = x1 + 2.0*x2',
                'y2 = 3.0*x1',
                'y3 = x1*x2']
        deriv4 = ['dy1_dx1 = 1.0',
                  'dy1_dx2 = 2.0',
                  'dy2_dx1 = 3.0',
                  'dy2_dx2 = 0.0',
                  'dy3_dx1 = x2',
                  'dy3_dx2 = x1']

        exp5 = ['y1 = x1 + 3.0*x2 + 2.0*x3']
        deriv5 = ['dy1_dx1 = 1.0',
                  'dy1_dx2 = 3.0',
                  'dy1_dx3 = 2.0']

        self.top.add('comp1', ExecCompWithDerivatives(exp1, deriv1))
        self.top.add('comp2', ExecCompWithDerivatives(exp2, deriv2))
        self.top.add('comp3', ExecCompWithDerivatives(exp3, deriv3))
        self.top.add('comp4', ExecCompWithDerivatives(exp4, deriv4))
        self.top.add('comp5', ExecCompWithDerivatives(exp5, deriv5))

        self.top.driver.workflow.add(['comp1', 'comp2', 'comp3', 'comp4', 'comp5'])

        self.top.connect('comp1.y1', 'comp2.x1')
        self.top.connect('comp1.y2', 'comp3.x1')
        self.top.connect('comp2.y1', 'comp4.x1')
        self.top.connect('comp3.y1', 'comp4.x2')
        self.top.connect('comp4.y1', 'comp5.x1')
        self.top.connect('comp4.y2', 'comp5.x2')
        self.top.connect('comp4.y3', 'comp5.x3')
        
        self.top.comp1.x1 = 2.0        
        self.top.run()

        J = self.top.driver.calc_gradient(inputs=['comp1.x1'],
                                          outputs=['comp5.y1'],
                                          mode='adjoint',
                                          return_format='dict')
        #from openmdao.util.dotgraph import plot_system_tree
        #plot_system_tree(self.top._system)
        #print J
        collective_assert_rel_error(self, 
                                    J['comp5.y1']['comp1.x1'][0][0], 
                                    313.0, 0.0001)
コード例 #5
0
    def test_smarter_nondifferentiable_blocks(self):

        top = set_as_top(Assembly())
        top.add(
            'comp1',
            ExecCompWithDerivatives(['y=2.0*x + 3.0*x2'],
                                    ['dy_dx = 2.0', 'dy_dx2 = 3.0']))
        top.add('comp2', ExecComp(['y=2.0*x + 3.0*x2', 'y2=4.0*x + 5.0*x2']))
        top.add(
            'comp3',
            ExecCompWithDerivatives(['y=2.0*x + 3.0*x2'],
                                    ['dy_dx = 2.0', 'dy_dx2 = 3.0']))
        top.add('comp4', ExecComp(['y=2.0*x + 3.0*x2']))
        top.add(
            'comp5',
            ExecCompWithDerivatives(['y=2.0*x + 3.0*x2'],
                                    ['dy_dx = 2.0', 'dy_dx2 = 3.0']))
        top.driver.workflow.add(['comp1', 'comp2', 'comp3', 'comp4', 'comp5'])

        top.connect('comp1.y', 'comp2.x')
        top.connect('comp2.y', 'comp3.x')
        top.connect('comp2.y2', 'comp4.x')
        top.connect('comp3.y', 'comp4.x2')
        top.connect('comp4.y', 'comp5.x')

        top.run()

        J = top.driver.workflow.calc_gradient(inputs=['comp1.x'],
                                              outputs=['comp5.y'],
                                              mode='forward')

        pa1 = top.driver.workflow._derivative_graph.node['~0']['pa_object']
        self.assertTrue('comp1' not in pa1.comps)
        self.assertTrue('comp2' in pa1.comps)
        self.assertTrue('comp3' in pa1.comps)
        self.assertTrue('comp4' in pa1.comps)
        self.assertTrue('comp5' not in pa1.comps)
        self.assertTrue(pa1.comps == pa1.itercomps)

        top.replace(
            'comp4',
            ExecCompWithDerivatives(['y=2.0*x + 3.0*x2'],
                                    ['dy_dx = 2.0', 'dy_dx2 = 3.0']))

        top.run()

        top.driver.workflow.config_changed()
        J = top.driver.workflow.calc_gradient(inputs=['comp1.x'],
                                              outputs=['comp5.y'],
                                              mode='forward')

        pa1 = top.driver.workflow._derivative_graph.node['~0']['pa_object']
        self.assertTrue('comp1' not in pa1.comps)
        self.assertTrue('comp2' in pa1.comps)
        self.assertTrue('comp3' not in pa1.comps)
        self.assertTrue('comp4' not in pa1.comps)
        self.assertTrue('comp5' not in pa1.comps)
        self.assertTrue(pa1.comps == pa1.itercomps)
コード例 #6
0
    def test_smarter_nondifferentiable_blocks(self):

        top = set_as_top(Assembly())
        top.add(
            'comp1',
            ExecCompWithDerivatives(['y=2.0*x + 3.0*x2'],
                                    ['dy_dx = 2.0', 'dy_dx2 = 3.0']))
        top.add('comp2', ExecComp(['y=2.0*x + 3.0*x2', 'y2=4.0*x + 5.0*x2']))
        top.add(
            'comp3',
            ExecCompWithDerivatives(['y=2.0*x + 3.0*x2'],
                                    ['dy_dx = 2.0', 'dy_dx2 = 3.0']))
        top.add('comp4', ExecComp(['y=2.0*x + 3.0*x2']))
        top.add(
            'comp5',
            ExecCompWithDerivatives(['y=2.0*x + 3.0*x2'],
                                    ['dy_dx = 2.0', 'dy_dx2 = 3.0']))
        top.driver.workflow.add(['comp1', 'comp2', 'comp3', 'comp4', 'comp5'])

        top.connect('comp1.y', 'comp2.x')
        top.connect('comp2.y', 'comp3.x')
        top.connect('comp2.y2', 'comp4.x')
        top.connect('comp3.y', 'comp4.x2')
        top.connect('comp4.y', 'comp5.x')

        top.run()

        J = top.driver.calc_gradient(inputs=['comp1.x'],
                                     outputs=['comp5.y'],
                                     mode='forward')

        self.assertTrue(len(top.driver.workflow._system.subsystems()) == 4)
        comp_list = simple_node_iter(
            top.driver.workflow._system.subsystems()[2]._nodes)
        self.assertTrue(len(comp_list) == 3)
        self.assertTrue('comp2' in comp_list)
        self.assertTrue('comp3' in comp_list)
        self.assertTrue('comp4' in comp_list)

        top.replace(
            'comp4',
            ExecCompWithDerivatives(['y=2.0*x + 3.0*x2'],
                                    ['dy_dx = 2.0', 'dy_dx2 = 3.0']))

        top.run()

        J = top.driver.calc_gradient(inputs=['comp1.x'],
                                     outputs=['comp5.y'],
                                     mode='forward')

        self.assertTrue(len(top.driver.workflow._system.subsystems()) == 6)
        comp_list = simple_node_iter(
            top.driver.workflow._system.subsystems()[2]._nodes)
        self.assertTrue(len(comp_list) == 1)
        self.assertTrue('comp2' in comp_list)
コード例 #7
0
    def test_medium_coupled(self):

        self.top = set_as_top(Assembly())

        exp0 = ['y=x']
        deriv0 = ['dy_dx = 1.0']

        exp1 = ['y2 = 0.5*sin(x1) - 0.5*x1*y1']
        deriv1 = ['dy2_dx1 = 0.5*cos(x1) - 0.5*y1', 'dy2_dy1 = -0.5*x1']

        exp2 = ['y1 = x2*x2*y2']
        deriv2 = ['dy1_dx2 = 2.0*y2*x2', 'dy1_dy2 = x2*x2']

        exp4 = ['y=3.0*x']
        deriv4 = ['dy_dx = 3.0']

        self.top.add('driver', Driv())

        self.top.add('comp0', ExecCompWithDerivatives(exp0, deriv0))
        self.top.add('comp1', ExecCompWithDerivatives(exp1, deriv1))
        self.top.add('comp2', ExecCompWithDerivatives(exp2, deriv2))
        self.top.add('comp3', ExecCompWithDerivatives(exp4, deriv4))
        #self.top.add('comp1', ExecComp(exp1))
        #self.top.add('comp2', ExecComp(exp2))
        self.top.add('solver', BroydenSolver())

        self.top.driver.workflow.add(['solver'])
        self.top.solver.workflow.add(['comp0', 'comp1', 'comp2', 'comp3'])
        self.top.connect('comp0.y', 'comp1.x1')
        self.top.connect('comp1.y2', 'comp2.y2')
        self.top.connect('comp2.y1', 'comp3.x')

        # Solver setup
        self.top.solver.add_parameter('comp1.y1', low=-1.e99, high=1.e99)
        self.top.solver.add_constraint('comp2.y1 = comp1.y1')

        # Top driver setup
        #self.top.driver.differentiator = FiniteDifference()
        self.top.driver.differentiator = Analytic()
        obj = 'comp3.y'
        self.top.driver.add_parameter('comp0.x',
                                      low=-100.,
                                      high=100.,
                                      fd_step=.001)
        self.top.driver.add_objective(obj)

        self.top.comp0.x = 1.0
        self.top.comp2.x2 = 1.0
        self.top.run()
        self.top.driver.differentiator.calc_gradient()

        grad = self.top.driver.differentiator.get_gradient(obj)
        assert_rel_error(self, grad[0], 3.0 * 0.08660, .001)
コード例 #8
0
    def test_baseline_case(self):

        top = set_as_top(Assembly())
        top.add('comp1', ExecCompWithDerivatives(['y1=2.0*x',
                                                  'y2=3.0*x',
                                                  'y3=4.0*x',
                                                  'y4=5.0*x'],
                                                 ['dy1_dx = 2.0',
                                                  'dy2_dx = 3.0',
                                                  'dy3_dx = 4.0',
                                                  'dy4_dx = 5.0']))

        top.add('comp2', ExecComp(['y = 2.0*x1 + x2 + x3 + x4']))
        top.driver.workflow.add(['comp1', 'comp2'])
        top.connect('comp1.y1', 'comp2.x1')
        top.connect('comp1.y2', 'comp2.x2')
        top.connect('comp1.y3', 'comp2.x3')
        top.connect('comp1.y4', 'comp2.x4')

        top.run()
        self.assertEqual(top.comp2.exec_count, 1)
        top.driver.gradient_options.directional_fd = True

        J = top.driver.calc_gradient(inputs=['comp1.x'],
                                     outputs=['comp2.y'])

        # Ran 1 times, not 4.
        self.assertEqual(top.comp2.exec_count, 2)
        assert_rel_error(self, J[0, 0], 16.0, 0.0001)

        top.driver.gradient_options.directional_fd = False

        J = top.driver.calc_gradient(inputs=['comp1.x'],
                                     outputs=['comp2.y'])

        # Ran 4 times (4 fd steps).
        self.assertEqual(top.comp2.exec_count, 6)
        assert_rel_error(self, J[0, 0], 16.0, 0.0001)

        # Next, test param / obj

        top.add('driver', SimpleDriver())
        top.driver.add_parameter('comp1.x', low=-1000, high=1000)
        top.driver.add_objective('comp2.y')
        top.run()
        self.assertEqual(top.comp2.exec_count, 7)

        top.driver.gradient_options.directional_fd = True

        J = top.driver.calc_gradient()

        # Ran 1 more times.
        self.assertEqual(top.comp2.exec_count, 8)
        assert_rel_error(self, J[0, 0], 16.0, 0.0001)

        J = top.driver.calc_gradient(mode='fd')

        # Ran 1 more times (full model fd, 2 edges).
        self.assertEqual(top.comp2.exec_count, 9)
        assert_rel_error(self, J[0, 0], 16.0, 0.0001)
コード例 #9
0
    def test_derivative_state_connection_internal_solve_apply_deriv(self):

        model = set_as_top(Assembly())
        model.add('driver', SimpleDriver())

        model.add('comp', MyComp_Deriv())
        model.comp.add('c', Float(2.0, iotype="in"))
        model.comp.eval_only = False

        model.add('comp2', ExecCompWithDerivatives(["y=2*x"], ["dy_dx=2"]))
        model.driver.workflow.add(['comp', 'comp2'])
        model.connect('comp.z', 'comp2.x')

        model.run()
        #print model.comp.x, model.comp.y, model.comp.z, model.comp.res
        J = model.driver.calc_gradient(inputs=['comp.c'], outputs=['comp2.y'])
        assert_rel_error(self, J[0][0], -0.1666, 2e-3)

        J = model.driver.calc_gradient(inputs=['comp.c'],
                                       outputs=['comp2.y'],
                                       mode='adjoint')
        assert_rel_error(self, J[0][0], -0.1666, 2e-3)

        J = model.driver.calc_gradient(inputs=['comp.c'],
                                       outputs=['comp2.y'],
                                       mode='fd')
        assert_rel_error(self, J[0][0], -0.1666, 2e-3)
コード例 #10
0
    def test_simple_coupled_adjoint(self):

        self.top = set_as_top(Assembly())

        exp1 = ['y2 = 0.5*sin(x1) - 0.5*x1*y1']
        deriv1 = ['dy2_dx1 = 0.5*cos(x1) - 0.5*y1', 'dy2_dy1 = -0.5*x1']

        exp2 = ['y1 = x2*x2*y2']
        deriv2 = ['dy1_dx2 = 2.0*y2*x2', 'dy1_dy2 = x2*x2']

        self.top.add('driver', Driv())

        self.top.add('comp1', ExecCompWithDerivatives(exp1, deriv1))
        self.top.add('comp2', ExecCompWithDerivatives(exp2, deriv2))
        #self.top.add('comp1', ExecComp(exp1))
        #self.top.add('comp2', ExecComp(exp2))
        self.top.add('solver', BroydenSolver())

        self.top.driver.workflow.add(['solver'])
        self.top.solver.workflow.add(['comp1', 'comp2'])
        self.top.connect('comp1.y2', 'comp2.y2')

        # Solver setup
        self.top.solver.add_parameter('comp1.y1', low=-1.e99, high=1.e99)
        self.top.solver.add_constraint('comp2.y1 = comp1.y1')

        # Top driver setup
        self.top.driver.differentiator = Analytic()
        self.top.driver.differentiator.mode = 'adjoint'
        obj = 'comp2.y1'
        self.top.driver.add_parameter('comp1.x1',
                                      low=-100.,
                                      high=100.,
                                      fd_step=.001)
        self.top.driver.add_parameter('comp2.x2',
                                      low=-100.,
                                      high=100.,
                                      fd_step=.0001)
        self.top.driver.add_objective(obj)

        self.top.comp1.x1 = 1.0
        self.top.comp2.x2 = 1.0
        self.top.run()
        self.top.driver.differentiator.calc_gradient()

        grad = self.top.driver.differentiator.get_gradient(obj)
        assert_rel_error(self, grad[0], 0.08660, .001)
コード例 #11
0
    def test_equation(self):

        top = set_as_top(Assembly())

        top.add('precomp', ExecCompWithDerivatives(['y=x'], ['dy_dx = 1']))
        top.precomp.x = 1.0

        expr = ['y = 3.0*x*x -4.0*x']
        deriv = ['dy_dx = 6.0*x -4.0']

        top.add('comp', ExecCompWithDerivatives(expr, deriv))
        top.driver.workflow.add(['comp'])

        top.add('driver', NewtonSolver())
        top.driver.add_parameter('comp.x')
        top.driver.add_constraint('precomp.y - comp.y = 1.0 - 2.0')

        top.run()

        print top.comp.x, top.comp.y
        assert_rel_error(self, top.comp.x, -0.38742588, 1e-4)
コード例 #12
0
    def test_derivative_state_connection_external_solve_ProvideJ(self):

        model = set_as_top(Assembly())
        model.add('comp', MyComp_Deriv_ProvideJ())
        model.comp.add('c', Float(2.0, iotype="in", fd_step=.001))

        model.add('comp2', ExecCompWithDerivatives(["y=2*x"], ["dy_dx=2"]))

        model.add('solver', BroydenSolver())
        model.solver.workflow.add(['comp', 'comp2'])
        model.driver.workflow.add(['solver'])
        model.connect('comp.z', 'comp2.x')

        model.solver.add_parameter('comp.x', low=-100, high=100)
        model.solver.add_parameter('comp.y', low=-100, high=100)
        model.solver.add_parameter('comp.z', low=-100, high=100)

        model.solver.add_constraint('comp.res[0] = 0')
        model.solver.add_constraint('comp.res[1] = 0')
        model.solver.add_constraint('comp.res[2] = 0')

        model.comp.eval_only = True

        model.run()
        # print model.comp.x, model.comp.y, model.comp.z, model.comp.res
        J = model.driver.workflow.calc_gradient(inputs=['comp.c'],
                                                outputs=['comp2.y'])
        info = model.driver.workflow.get_implicit_info()
        # print info
        self.assertEqual(
            set(info[('_pseudo_0.out0', '_pseudo_1.out0', '_pseudo_2.out0')]),
            set([('comp.x', ), ('comp.y', ), ('comp.z', )]))
        self.assertEqual(len(info), 1)

        edges = model.driver.workflow._edges
        # print edges
        self.assertEqual(set(edges['@in0']), set(['comp.c']))
        self.assertEqual(set(edges['comp2.y']), set(['@out0']))

        assert_rel_error(self, J[0][0], -0.1666, 1e-3)

        model.driver.workflow.config_changed()
        J = model.driver.workflow.calc_gradient(inputs=['comp.c'],
                                                outputs=['comp2.y'],
                                                mode='adjoint')
        assert_rel_error(self, J[0][0], -0.1666, 1e-3)

        model.driver.workflow.config_changed()
        J = model.driver.workflow.calc_gradient(inputs=['comp.c'],
                                                outputs=['comp2.y'],
                                                mode='fd')
        assert_rel_error(self, J[0][0], -0.1666, 1e-3)
コード例 #13
0
    def test_three_comp_diamond_forward(self):
        
        self.top = set_as_top(Assembly())

        exp1 = ['y1 = 50.0*x1',
                'y2 = 1.0*x1']
        deriv1 = ['dy1_dx1 = 50.0',
                  'dy2_dx1 = 1.0']

        exp2 = ['y1 = 1.2*x1']
        deriv2 = ['dy1_dx1 = 1.2']
    
        exp3 = ['y1 = 100.0*x1*x2 + 30*x1 + 0.3*x2']
        deriv3 = ['dy1_dx1 = 100.0*x2 + 30',
                  'dy1_dx2 = 100.0*x1 + 0.3']

        self.top.add('comp1', ExecCompWithDerivatives(exp1, deriv1))
        self.top.add('comp2', ExecCompWithDerivatives(exp2, deriv2))
        self.top.add('comp3', ExecCompWithDerivatives(exp3, deriv3))
        self.top.add('driver', SimpleDriver())

        self.top.driver.workflow.add(['comp1', 'comp2', 'comp3'])

        self.top.connect('comp1.y1', 'comp2.x1')
        self.top.connect('comp1.y2', 'comp3.x1')
        self.top.connect('comp2.y1', 'comp3.x2')

        self.top.driver.add_parameter('comp1.x1', low=-100, high=100)
        self.top.driver.add_objective('comp3.y1')
        self.top.comp1.x1 = 2.0
        self.top.run()

        J = self.top.driver.calc_gradient(inputs=['comp1.x1'],
                                          outputs=['comp3.y1'],
                                          mode='forward',
                                          return_format='dict')
        if self.comm.rank == 0:
            assert_rel_error(self, J['comp3.y1']['comp1.x1'][0][0], 
                             24048.0, 0.0001)
コード例 #14
0
    def test_two_to_one_adjoint_bcast(self):
        
        top = set_as_top(Assembly())
        
        exp1 = ["y = 3.0*x"]
        exp2 = ["y = -2.0*x"]
        exp3 = ["y = 5.0*x1 + 4.0*x2"]
        
        deriv1 = ["dy_dx = 3.0"]
        deriv2 = ["dy_dx = -2.0"]
        deriv3 = ["dy_dx1 = 5.0", "dy_dx2 = 4.0"]
        
        top.add('comp1', ExecCompWithDerivatives(exp1, deriv1))
        top.add('comp2', ExecCompWithDerivatives(exp2, deriv2))
        top.add('comp3', ExecCompWithDerivatives(exp3, deriv3))
        top.add('driver', SimpleDriver())
        
        top.driver.workflow.add(['comp1', 'comp2', 'comp3'])
        top.connect('comp1.y', 'comp3.x1')
        top.connect('comp2.y', 'comp3.x2')
        top.driver.add_parameter(('comp1.x', 'comp2.x'), 
                                 low=-100, high=100)
        top.driver.add_constraint('comp3.y < 1000')
        top.run()

        J = top.driver.workflow.calc_gradient(mode='adjoint',
                                              return_format='dict')

        J = top.driver.workflow._system.get_combined_J(J)

        #from openmdao.util.dotgraph import plot_system_tree
        #plot_system_tree(top._system)

        collective_assert_rel_error(self, 
                                    J['_pseudo_0.out0']['comp1.x'][0][0], 
                                    7.0, 0.0001)
コード例 #15
0
    def test_cascade_opt(self):

        raise SkipTest(
            "We currently don't allow a component instance in multiple workflows."
        )

        top = set_as_top(Assembly())

        eq = ['f = (x-3)**2 + x*y + (y+4)**2 - 3']
        deriv = ['df_dx = 2.0*x - 6.0 + y', 'df_dy = 2.0*y + 8.0 + x']
        top.add('comp', ExecCompWithDerivatives(eq, deriv))
        top.add('driver', SimpleDriver())
        top.add('opt1', SLSQPdriver())
        top.add('opt2', SLSQPdriver())

        top.opt1.workflow.add(['comp'])
        top.opt2.workflow.add(['comp'])
        top.driver.workflow.add(['opt1', 'opt2'])

        top.opt1.add_parameter('comp.x', low=-100, high=100)
        top.opt1.add_parameter('comp.y', low=-100, high=100)
        top.opt1.add_objective('comp.f')
        top.opt1.maxiter = 2
        top.opt2.add_parameter('comp.x', low=-100, high=100)
        top.opt2.add_parameter('comp.y', low=-100, high=100)
        top.opt2.add_objective('comp.f')
        top.opt2.maxiter = 50

        top.run()

        assert_rel_error(self, top.comp.x, 6.666309, 0.01)
        assert_rel_error(self, top.comp.y, -7.333026, 0.01)

        J = top.driver.calc_gradient(inputs=['comp.x', 'comp.y'],
                                     outputs=['comp.f'])
        edges = top.driver.workflow._edges
        print edges
        self.assertEqual(set(edges['@in0']),
                         set(['~opt1.comp|x', '~opt2.comp|x']))
        self.assertEqual(set(edges['@in1']),
                         set(['~opt1.comp|y', '~opt2.comp|y']))
        self.assertEqual(set(edges['~opt1.comp|f']), set(['@out0']))
        self.assertEqual(set(edges['~opt2.comp|f']), set(['@out0']))
コード例 #16
0
    def test_derivative_state_connection_external_solve_ProvideJ(self):

        model = set_as_top(Assembly())
        model.add('driver', SimpleDriver())

        model.add('comp', MyComp_Deriv_ProvideJ())
        model.comp.add('c', Float(2.0, iotype="in", fd_step=.001))

        model.add('comp2', ExecCompWithDerivatives(["y=2*x"], ["dy_dx=2"]))

        model.add('solver', BroydenSolver())
        model.solver.workflow.add(['comp', 'comp2'])
        model.driver.workflow.add(['solver'])
        model.connect('comp.z', 'comp2.x')

        model.solver.add_parameter('comp.x', low=-100, high=100)
        model.solver.add_parameter('comp.y', low=-100, high=100)
        model.solver.add_parameter('comp.z', low=-100, high=100)

        model.solver.add_constraint('comp.res[0] = 0')
        model.solver.add_constraint('comp.res[1] = 0')
        model.solver.add_constraint('comp.res[2] = 0')

        model.comp.eval_only = True

        model.run()
        #print model.comp.x, model.comp.y, model.comp.z, model.comp.res
        J = model.driver.calc_gradient(inputs=['comp.c'],
                                       outputs=['comp2.y'],
                                       mode='forward')
        assert_rel_error(self, J[0][0], -0.1666, 2e-3)

        J = model.driver.calc_gradient(inputs=['comp.c'],
                                       outputs=['comp2.y'],
                                       mode='adjoint')
        assert_rel_error(self, J[0][0], -0.1666, 2e-3)

        J = model.driver.calc_gradient(inputs=['comp.c'],
                                       outputs=['comp2.y'],
                                       mode='fd')
        assert_rel_error(self, J[0][0], -0.1666, 2e-3)
コード例 #17
0
    def test_execcomp_derivatives(self):
        exp1 = ['y1 = 2.0*x1 + x2*x2', 'y2 = 3.0*x1*x2']
        deriv1 = [
            'dy1_dx1 = 2.0', 'dy1_dx2 = 2.0*x2', 'dy2_dx1 = 3.0*x2',
            'dy2_dx2 = 3.0*x1'
        ]

        self.top.add('comp1', ExecCompWithDerivatives(exp1, deriv1))
        self.top.driver.workflow.add('comp1')

        self.top.comp1.x1 = 3.0
        self.top.comp1.x2 = 5.0
        self.top.comp1.run()
        J = self.top.driver.workflow.calc_gradient(
            inputs=['comp1.x1', 'comp1.x2'], outputs=['comp1.y1', 'comp1.y2'])

        assert_rel_error(self, J[0, 0], 2.0, 0.0001)
        assert_rel_error(self, J[0, 1], 10.0, 0.0001)
        assert_rel_error(self, J[1, 0], 15.0, 0.0001)
        assert_rel_error(self, J[1, 1], 9.0, 0.0001)
        self.assertEqual(self.top.comp1.y2, 45.0)
コード例 #18
0
    def test_derivative_state_connection_internal_solve_apply_deriv(self):

        model = set_as_top(Assembly())
        model.add('comp', MyComp_Deriv())
        model.comp.add('c', Float(2.0, iotype="in", fd_step=.001))

        model.add('comp2', ExecCompWithDerivatives(["y=2*x"], ["dy_dx=2"]))
        model.driver.workflow.add(['comp', 'comp2'])
        model.connect('comp.z', 'comp2.x')

        model.run()
        # print model.comp.x, model.comp.y, model.comp.z, model.comp.res
        J = model.driver.workflow.calc_gradient(inputs=['comp.c'],
                                                outputs=['comp2.y'])
        info = model.driver.workflow.get_implicit_info()
        # print info
        self.assertEqual(set(info[('comp.res', )]),
                         set(['comp.x', 'comp.y', 'comp.z']))
        self.assertEqual(len(info), 1)

        edges = model.driver.workflow._edges
        # print edges
        self.assertEqual(set(edges['@in0']), set(['comp.c']))
        self.assertEqual(set(edges['comp2.y']), set(['@out0']))

        assert_rel_error(self, J[0][0], -0.1666, 1e-3)

        model.driver.workflow.config_changed()
        J = model.driver.workflow.calc_gradient(inputs=['comp.c'],
                                                outputs=['comp2.y'],
                                                mode='adjoint')
        assert_rel_error(self, J[0][0], -0.1666, 1e-3)

        model.driver.workflow.config_changed()
        J = model.driver.workflow.calc_gradient(inputs=['comp.c'],
                                                outputs=['comp2.y'],
                                                mode='fd')
        assert_rel_error(self, J[0][0], -0.1666, 1e-3)
コード例 #19
0
    def test_execcomp_derivatives(self):

        exp1 = ['y1 = 2.0*x1 + x2*x2', 'y2 = 3.0*x1*x2']
        deriv1 = [
            'dy1_dx1 = 2.0', 'dy1_dx2 = 2.0*x2', 'dy2_dx1 = 3.0*x2',
            'dy2_dx2 = 3.0*x1'
        ]

        self.top.add('comp1', ExecCompWithDerivatives(exp1, deriv1))

        self.top.comp1.x1 = 3.0
        self.top.comp1.x2 = 5.0
        self.top.comp1.run()
        self.top.comp1.calc_derivatives(first=True, second=False)

        self.assertEqual(
            self.top.comp1.derivatives.first_derivatives['y1']['x1'], 2.0)
        self.assertEqual(
            self.top.comp1.derivatives.first_derivatives['y1']['x2'], 10.0)
        self.assertEqual(
            self.top.comp1.derivatives.first_derivatives['y2']['x1'], 15.0)
        self.assertEqual(
            self.top.comp1.derivatives.first_derivatives['y2']['x2'], 9.0)
        self.assertEqual(self.top.comp1.y2, 45.0)
コード例 #20
0
    def test_diverge_converge_nondiff_comp3_forward(self):
        
        self.top = set_as_top(Assembly())

        exp1 = ['y1 = 2.0*x1**2',
                'y2 = 3.0*x1']
        deriv1 = ['dy1_dx1 = 4.0*x1',
                  'dy2_dx1 = 3.0']

        exp2 = ['y1 = 0.5*x1']
        deriv2 = ['dy1_dx1 = 0.5']

        exp3 = ['y1 = 3.5*x1']
        deriv3 = ['dy1_dx1 = 3.5']

        exp4 = ['y1 = x1 + 2.0*x2',
                'y2 = 3.0*x1',
                'y3 = x1*x2']
        deriv4 = ['dy1_dx1 = 1.0',
                  'dy1_dx2 = 2.0',
                  'dy2_dx1 = 3.0',
                  'dy2_dx2 = 0.0',
                  'dy3_dx1 = x2',
                  'dy3_dx2 = x1']

        exp5 = ['y1 = x1 + 3.0*x2 + 2.0*x3']
        deriv5 = ['dy1_dx1 = 1.0',
                  'dy1_dx2 = 3.0',
                  'dy1_dx3 = 2.0']
        
        self.top.add('driver', SimpleDriver())
        self.top.add('comp1', ExecCompWithDerivatives(exp1, deriv1))
        self.top.add('comp2', ExecCompWithDerivatives(exp2, deriv2))
        self.top.add('comp3', ExecComp(exp3))
        self.top.add('comp4', ExecCompWithDerivatives(exp4, deriv4))
        self.top.add('comp5', ExecCompWithDerivatives(exp5, deriv5))

        self.top.driver.workflow.add(['comp1', 'comp2', 'comp3', 'comp4', 'comp5'])

        self.top.connect('comp1.y1', 'comp2.x1')
        self.top.connect('comp1.y2', 'comp3.x1')
        self.top.connect('comp2.y1', 'comp4.x1')
        self.top.connect('comp3.y1', 'comp4.x2')
        self.top.connect('comp4.y1', 'comp5.x1')
        self.top.connect('comp4.y2', 'comp5.x2')
        self.top.connect('comp4.y3', 'comp5.x3')
        
        self.top.driver.add_parameter('comp1.x1', low=-100, high=100)
        self.top.driver.add_objective('comp5.y1')
        
        self.top.comp1.x1 = 2.0        
        self.top.run()

        J = self.top.driver.calc_gradient(inputs=['comp1.x1'],
                                          outputs=['comp5.y1'],
                                          mode='forward',
                                          return_format='dict')
        
        collective_assert_rel_error(self, 
                                    J['comp5.y1']['comp1.x1'][0][0], 
                                    313.0, 0.0001)
コード例 #21
0
    def test_find_edges(self):
        # Verifies that we don't chain derivatives for inputs that are
        # connected in a parent assembly, but are not germain to our subassy
        # derivative.

        self.top = set_as_top(Assembly())

        exp1 = ['y1 = 2.0*x1**2', 'y2 = 3.0*x1']
        deriv1 = ['dy1_dx1 = 4.0*x1', 'dy2_dx1 = 3.0']

        exp2 = ['y1 = 0.5*x1']
        deriv2 = ['dy1_dx1 = 0.5']

        exp3 = ['y1 = 3.5*x1']
        deriv3 = ['dy1_dx1 = 3.5']

        exp4 = ['y1 = x1 + 2.0*x2', 'y2 = 3.0*x1', 'y3 = x1*x2']
        deriv4 = [
            'dy1_dx1 = 1.0', 'dy1_dx2 = 2.0', 'dy2_dx1 = 3.0', 'dy2_dx2 = 0.0',
            'dy3_dx1 = x2', 'dy3_dx2 = x1'
        ]

        exp5 = ['y1 = x1 + 3.0*x2 + 2.0*x3']
        deriv5 = ['dy1_dx1 = 1.0', 'dy1_dx2 = 3.0', 'dy1_dx3 = 2.0']

        self.top.add('nest1', Assembly())
        self.top.add('comp1', ExecCompWithDerivatives(exp1, deriv1))
        self.top.nest1.add('driver', Driv())
        self.top.nest1.add('comp2', ExecCompWithDerivatives(exp2, deriv2))
        self.top.nest1.add('comp3', ExecCompWithDerivatives(exp3, deriv3))
        self.top.nest1.add('comp4', ExecCompWithDerivatives(exp4, deriv4))
        self.top.add('comp5', ExecCompWithDerivatives(exp5, deriv5))

        self.top.driver.workflow.add(['comp1', 'nest1', 'comp5'])
        self.top.nest1.driver.workflow.add(['comp2', 'comp3', 'comp4'])

        self.top.nest1.driver.differentiator = ChainRule()

        obj = 'comp4.y1'
        con = 'comp3.y1-comp3.y1 > 0'
        self.top.nest1.driver.add_parameter('comp2.x1',
                                            low=-50.,
                                            high=50.,
                                            fd_step=.0001)
        self.top.nest1.driver.add_objective(obj)
        self.top.nest1.driver.add_constraint(con)

        self.top.nest1.add('real_c3_x1',
                           Float(iotype='in', desc='I am really here'))
        self.top.nest1.add('real_c4_y2',
                           Float(iotype='out', desc='I am really here'))

        self.top.connect('comp1.y1', 'nest1.comp2.x1')
        #self.top.connect('comp1.y1', 'nest1.comp2.x1')
        self.top.connect('comp1.y2', 'nest1.real_c3_x1')
        self.top.nest1.connect('real_c3_x1', 'comp3.x1')
        self.top.nest1.connect('comp2.y1', 'comp4.x1')
        self.top.nest1.connect('comp3.y1', 'comp4.x2')
        self.top.nest1.connect('comp4.y2', 'real_c4_y2')
        self.top.connect('nest1.real_c4_y2', 'comp5.x2')
        self.top.connect('nest1.comp4.y1', 'comp5.x1')
        self.top.connect('nest1.comp4.y3', 'comp5.x3')
        #self.top.connect('nest1.comp4.y2 + 1.0*nest1.comp4.y3', 'comp5.x3')

        self.top.comp1.x1 = 2.0
        self.top.run()
        self.top.nest1.driver.differentiator.calc_gradient()

        edge_dict = self.top.nest1.driver.differentiator.edge_dicts[
            'nest1.driver']
        self.assertTrue('x1' in edge_dict['comp2'][0])
        self.assertTrue('x1' not in edge_dict['comp3'][0])
        self.assertTrue('y1' in edge_dict['comp4'][1])
        self.assertTrue('y2' not in edge_dict['comp4'][1])
コード例 #22
0
    def test_large_dataflow_mixed_finite_difference_three(self):

        self.top = set_as_top(Assembly())

        exp1 = ['y1 = 2.0*x1**2', 'y2 = 3.0*x1']
        deriv1 = ['dy1_dx1 = 4.0*x1', 'dy2_dx1 = 3.0']

        exp2 = ['y1 = 0.5*x1']
        deriv2 = ['dy1_dx1 = 0.5']

        exp3 = ['y1 = 3.5*x1']
        deriv3 = ['dy1_dx1 = 3.5']

        exp4 = ['y1 = x1 + 2.0*x2', 'y2 = 3.0*x1', 'y3 = x1*x2']
        deriv4 = [
            'dy1_dx1 = 1.0', 'dy1_dx2 = 2.0', 'dy2_dx1 = 3.0', 'dy2_dx2 = 0.0',
            'dy3_dx1 = x2', 'dy3_dx2 = x1'
        ]

        exp5 = ['y1 = x1 + 3.0*x2 + 2.0*x3']
        deriv5 = ['dy1_dx1 = 1.0', 'dy1_dx2 = 3.0', 'dy1_dx3 = 2.0']

        self.top.add('comp1', ExecComp(exp1))
        self.top.add('comp2', ExecCompWithDerivatives(exp2, deriv2))
        self.top.add('comp3', ExecComp(exp3))
        self.top.add('comp4', ExecCompWithDerivatives(exp4, deriv4))
        self.top.add('comp5', ExecComp(exp5))

        self.top.add('driver', Driv())
        self.top.driver.workflow.add(
            ['comp1', 'comp2', 'comp3', 'comp4', 'comp5'])

        self.top.driver.differentiator = Analytic()

        obj = 'comp5.y1'
        con = 'comp5.y1-comp3.y1 > 0'
        self.top.driver.add_parameter('comp1.x1',
                                      low=-50.,
                                      high=50.,
                                      fd_step=.0001)
        self.top.driver.add_objective(obj)
        self.top.driver.add_constraint(con)

        self.top.connect('1.0*comp1.y1', 'comp2.x1')
        self.top.connect('comp1.y2', 'comp3.x1')
        self.top.connect('comp2.y1', 'comp4.x1')
        self.top.connect('comp3.y1', 'comp4.x2')
        self.top.connect('2.0*comp4.y1', 'comp5.x1')
        self.top.connect('2.0*comp4.y2', 'comp5.x2')
        self.top.connect('2.0*comp4.y3', 'comp5.x3')

        self.top.comp1.x1 = 2.0
        self.top.run()
        self.top.driver.differentiator.calc_gradient()

        grad = self.top.driver.differentiator.get_gradient(obj)
        assert_rel_error(self, grad[0], 626.0, .001)

        grad = self.top.driver.differentiator.get_gradient(
            'comp5.y1-comp3.y1>0')
        assert_rel_error(self, grad[0], -626.0 + 10.5, .001)
コード例 #23
0
    def test_large_dataflow_nested_assys(self):

        self.top = set_as_top(Assembly())

        exp1 = ['y1 = 2.0*x1**2', 'y2 = 3.0*x1']
        deriv1 = ['dy1_dx1 = 4.0*x1', 'dy2_dx1 = 3.0']

        exp2 = ['y1 = 0.5*x1']
        deriv2 = ['dy1_dx1 = 0.5']

        exp3 = ['y1 = 3.5*x1']
        deriv3 = ['dy1_dx1 = 3.5']

        exp4 = ['y1 = x1 + 2.0*x2', 'y2 = 3.0*x1', 'y3 = x1*x2']
        deriv4 = [
            'dy1_dx1 = 1.0', 'dy1_dx2 = 2.0', 'dy2_dx1 = 3.0', 'dy2_dx2 = 0.0',
            'dy3_dx1 = x2', 'dy3_dx2 = x1'
        ]

        exp5 = ['y1 = x1 + 3.0*x2 + 2.0*x3']
        deriv5 = ['dy1_dx1 = 1.0', 'dy1_dx2 = 3.0', 'dy1_dx3 = 2.0']

        self.top.add('nest1', Assembly())
        self.top.add('comp1', ExecCompWithDerivatives(exp1, deriv1))
        self.top.nest1.add('comp2', ExecCompWithDerivatives(exp2, deriv2))
        self.top.nest1.add('comp3', ExecCompWithDerivatives(exp3, deriv3))
        self.top.nest1.add('comp4', ExecCompWithDerivatives(exp4, deriv4))
        self.top.add('comp5', ExecCompWithDerivatives(exp5, deriv5))

        self.top.add('driver', Driv())
        self.top.driver.workflow.add(['comp1', 'nest1', 'comp5'])
        self.top.nest1.driver.workflow.add(['comp2', 'comp3', 'comp4'])

        self.top.driver.differentiator = Analytic()

        obj = 'comp5.y1'
        con = 'comp5.y1-nest1.comp3.y1 > 0'
        self.top.driver.add_parameter('comp1.x1',
                                      low=-50.,
                                      high=50.,
                                      fd_step=.0001)
        self.top.driver.add_objective(obj)
        self.top.driver.add_constraint(con)

        self.top.nest1.add('real_c2_x1',
                           Float(iotype='in', desc='I am really here'))
        self.top.nest1.add('real_c3_x1',
                           Float(iotype='in', desc='I am really here'))
        self.top.nest1.add('real_c4_y1',
                           Float(iotype='out', desc='I am really here'))
        self.top.nest1.add('real_c4_y2',
                           Float(iotype='out', desc='I am really here'))
        self.top.nest1.add('real_c4_y3',
                           Float(iotype='out', desc='I am really here'))

        #self.top.connect('comp1.y1', 'nest1.comp2.x1')
        self.top.connect('comp1.y1', 'nest1.real_c2_x1')
        self.top.connect('comp1.y2', 'nest1.real_c3_x1')
        self.top.nest1.connect('real_c2_x1', 'comp2.x1')
        self.top.nest1.connect('real_c3_x1', 'comp3.x1')
        self.top.nest1.connect('comp2.y1', 'comp4.x1')
        self.top.nest1.connect('comp3.y1', 'comp4.x2')
        self.top.nest1.connect('comp4.y1', 'real_c4_y1')
        self.top.nest1.connect('comp4.y2', 'real_c4_y2')
        self.top.nest1.connect('comp4.y3', 'real_c4_y3')
        self.top.connect('nest1.real_c4_y1', 'comp5.x1')
        self.top.connect('nest1.real_c4_y2', 'comp5.x2')
        self.top.connect('nest1.real_c4_y3', 'comp5.x3')
        #self.top.connect('nest1.comp4.y1', 'comp5.x1')
        #self.top.connect('nest1.comp4.y3', 'comp5.x3')

        self.top.comp1.x1 = 2.0
        self.top.run()
        self.top.driver.differentiator.calc_gradient()

        grad = self.top.driver.differentiator.get_gradient(obj)
        assert_rel_error(self, grad[0], 313.0, .001)

        grad = self.top.driver.differentiator.get_gradient(
            'comp5.y1-nest1.comp3.y1>0')
        assert_rel_error(self, grad[0], -313.0 + 10.5, .001)
コード例 #24
0
    def test_input_as_output(self):

        top = set_as_top(Assembly())
        top.add(
            'comp1',
            ExecCompWithDerivatives(['y=2.0*x + 3.0*x2'],
                                    ['dy_dx = 2.0', 'dy_dx2 = 3.0']))
        top.add('comp2', ExecCompWithDerivatives(['y=3.0*x'], ['dy_dx = 3.0']))
        top.connect('comp1.y', 'comp2.x')
        top.add('driver', SimpleDriver())
        top.driver.workflow.add(['comp1', 'comp2'])
        #top.driver.add_parameter('comp1.x', low=-100, high=100)
        top.driver.add_objective('comp1.y + comp2.y + 5*comp1.x')
        top.driver.gradient_options.lin_solver = 'petsc_ksp'

        objs = top.driver.get_objectives().values()
        obj = '%s.out0' % objs[0].pcomp_name

        top.comp1.x = 1.0
        top.run()

        J = top.driver.calc_gradient(inputs=['comp1.x'],
                                     outputs=[obj],
                                     mode='forward')

        assert_rel_error(self, J[0, 0], 13.0, 0.0001)

        J = top.driver.calc_gradient(inputs=['comp1.x'],
                                     outputs=[obj],
                                     mode='fd')
        assert_rel_error(self, J[0, 0], 13.0, 0.0001)

        top.driver.run()

        J = top.driver.calc_gradient(inputs=['comp1.x'],
                                     outputs=[obj],
                                     mode='adjoint')
        assert_rel_error(self, J[0, 0], 13.0, 0.0001)

        J = top.driver.calc_gradient(inputs=['comp1.x', 'comp1.x2'],
                                     outputs=[obj],
                                     mode='forward')
        assert_rel_error(self, J[0, 0], 13.0, 0.0001)
        assert_rel_error(self, J[0, 1], 12.0, 0.0001)

        J = top.driver.calc_gradient(inputs=['comp1.x', 'comp1.x2'],
                                     outputs=[obj],
                                     mode='adjoint')
        assert_rel_error(self, J[0, 0], 13.0, 0.0001)
        assert_rel_error(self, J[0, 1], 12.0, 0.0001)

        J = top.driver.calc_gradient(inputs=[('comp1.x', ), ('comp1.x2', )],
                                     outputs=[obj],
                                     mode='forward')
        assert_rel_error(self, J[0, 0], 13.0, 0.0001)
        assert_rel_error(self, J[0, 1], 12.0, 0.0001)

        J = top.driver.calc_gradient(inputs=[('comp1.x', ), ('comp1.x2', )],
                                     outputs=[obj],
                                     mode='adjoint')
        assert_rel_error(self, J[0, 0], 13.0, 0.0001)
        assert_rel_error(self, J[0, 1], 12.0, 0.0001)