def test_record_line_search_armijo_goldstein(self, m):
        self.setup_endpoints(m)
        recorder = WebRecorder(self._accepted_token, suppress_output=True)
        self.setup_sellar_model()

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

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

        # This is pretty bogus, but it ensures that we get a few LS iterations.
        ls.options['c'] = 100.0
        ls.add_recorder(recorder)

        self.prob.setup(check=False)

        t0, t1 = run_driver(self.prob)

        self.prob.cleanup()

        expected_abs_error = 3.49773898733e-9
        expected_rel_error = expected_abs_error / 2.9086436370499857e-08

        solver_iteration = json.loads(self.solver_iterations)

        self.assertAlmostEqual(solver_iteration['abs_err'], expected_abs_error)
        self.assertAlmostEqual(solver_iteration['rel_err'], expected_rel_error)
        self.assertEqual(len(solver_iteration['solver_output']), 7)
        self.assertEqual(solver_iteration['solver_residuals'], [])
    def test_record_line_search_bounds_enforce(self, m):
        self.setup_endpoints(m)
        recorder = WebRecorder(self._accepted_token, suppress_output=True)
        self.setup_sellar_model()

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

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

        ls.add_recorder(recorder)

        self.prob.setup(check=False)

        t0, t1 = run_driver(self.prob)

        self.prob.cleanup()

        expected_abs_error = 7.02783609310096e-10
        expected_rel_error = 8.078674883382422e-07

        solver_iteration = json.loads(self.solver_iterations)
        self.assertAlmostEqual(solver_iteration['abs_err'], expected_abs_error)
        self.assertAlmostEqual(solver_iteration['rel_err'], expected_rel_error)
        self.assertEqual(len(solver_iteration['solver_output']), 7)
        self.assertEqual(solver_iteration['solver_residuals'], [])
    def test_only_desvars_recorded(self, m):
        self.setup_endpoints(m)

        recorder = WebRecorder(self._accepted_token, suppress_output=True)

        self.setup_sellar_model()

        self.prob.driver.recording_options['record_desvars'] = True
        self.prob.driver.recording_options['record_responses'] = False
        self.prob.driver.recording_options['record_objectives'] = False
        self.prob.driver.recording_options['record_constraints'] = False
        self.prob.driver.add_recorder(recorder)

        self.prob.setup(check=False)

        t0, t1 = run_driver(self.prob)

        self.prob.cleanup()

        driver_iteration_data = json.loads(self.driver_iteration_data)
        self.driver_iteration_data = None
        self.assertTrue({'name': 'px.x', 'values': [1.0]} in driver_iteration_data['desvars'])
        self.assertTrue({'name': 'pz.z', 'values': [5.0, 2.0]} in driver_iteration_data['desvars'])
        self.assertEqual(driver_iteration_data['responses'], [])
        self.assertEqual(driver_iteration_data['objectives'], [])
        self.assertEqual(driver_iteration_data['constraints'], [])
    def test_record_solver_nonlinear_nonlinear_run_once(self, m):
        self.setup_endpoints(m)
        recorder = WebRecorder(self._accepted_token, suppress_output=True)
        self.setup_sellar_model()

        self.prob.model.nonlinear_solver = NonlinearRunOnce()
        self.prob.model.nonlinear_solver.add_recorder(recorder)

        self.prob.setup(check=False)

        t0, t1 = run_driver(self.prob)

        self.prob.cleanup()

        # No norms so no expected norms
        expected_abs_error = 0.0
        expected_rel_error = 0.0
        expected_solver_residuals = None
        expected_solver_output = None

        solver_iteration = json.loads(self.solver_iterations)

        self.assertEqual(expected_abs_error, solver_iteration['abs_err'])
        self.assertEqual(expected_rel_error, solver_iteration['rel_err'])
        self.assertEqual(solver_iteration['solver_residuals'], [])
        self.assertEqual(len(solver_iteration['solver_output']), 7)
예제 #5
0
    def test_only_objectives_recorded(self, m):
        self.setup_endpoints(m)
        recorder = WebRecorder(self._accepted_token, suppress_output=True)

        self.setup_sellar_model()

        self.prob.driver.recording_options['record_desvars'] = False
        self.prob.driver.recording_options['record_responses'] = False
        self.prob.driver.recording_options['record_objectives'] = True
        self.prob.driver.recording_options['record_constraints'] = False
        self.prob.driver.add_recorder(recorder)
        self.prob.setup(check=False)

        t0, t1 = run_driver(self.prob)

        self.prob.cleanup()

        driver_iteration_data = json.loads(self.driver_iteration_data)
        self.assertAlmostEqual(
            driver_iteration_data['objectives'][0]['values'][0], 28.5883082)
        self.assertEqual(driver_iteration_data['objectives'][0]['name'],
                         'obj_cmp.obj')
        self.assertEqual(driver_iteration_data['desvars'], [])
        self.assertEqual(driver_iteration_data['responses'], [])
        self.assertEqual(driver_iteration_data['constraints'], [])
    def test_record_solver_linear_scipy_iterative_solver(self, m):
        self.setup_endpoints(m)
        recorder = WebRecorder(self._accepted_token, suppress_output=True)
        self.setup_sellar_model()

        self.prob.model.nonlinear_solver = NewtonSolver()
        # used for analytic derivatives
        self.prob.model.nonlinear_solver.linear_solver = ScipyKrylov()

        linear_solver = self.prob.model.nonlinear_solver.linear_solver
        linear_solver.recording_options['record_abs_error'] = True
        linear_solver.recording_options['record_rel_error'] = True
        linear_solver.recording_options['record_solver_residuals'] = True
        self.prob.model.nonlinear_solver.linear_solver.add_recorder(recorder)

        self.prob.setup(check=False)
        t0, t1 = run_driver(self.prob)

        expected_abs_error = 0.0
        expected_rel_error = 0.0

        expected_solver_output = [
            {'name': 'px.x', 'values': [0.0]},
            {'name': 'pz.z', 'values': [0.0, 0.0]},
        ]

        solver_iteration = json.loads(self.solver_iterations)

        self.assertAlmostEqual(0.0, solver_iteration['abs_err'])
        self.assertAlmostEqual(0.0, solver_iteration['rel_err'])

        for o in expected_solver_output:
            self.assert_array_close(o, solver_iteration['solver_output'])
    def test_sysincludes_recorded_with_excludes(self, m):
        self.setup_endpoints(m)
        recorder = WebRecorder(self._accepted_token, suppress_output=True)

        self.setup_sellar_model()

        self.prob.driver.recording_options['record_desvars'] = False
        self.prob.driver.recording_options['record_responses'] = False
        self.prob.driver.recording_options['record_objectives'] = False
        self.prob.driver.recording_options['record_constraints'] = False
        self.prob.driver.recording_options['includes'] = ['*']
        self.prob.driver.recording_options['excludes'] = ['obj_cmp.obj']
        self.prob.driver.add_recorder(recorder)
        self.prob.setup(check=False)

        t0, t1 = run_driver(self.prob)

        self.prob.cleanup()

        driver_iteration_data = json.loads(self.driver_iteration_data)
        self.assertEqual(len(driver_iteration_data['sysincludes']), 2)
        self.assertEqual(len(driver_iteration_data['objectives']), 0)
        self.assertEqual(len(driver_iteration_data['desvars']), 0)
        self.assertEqual(len(driver_iteration_data['constraints']), 0)
        self.assertEqual(len(driver_iteration_data['responses']), 0)
예제 #8
0
    def test_distrib_record_driver(self):
        # create distributed variables of different sizes to catch mismatched collective calls
        sizes = [7, 10, 12, 25, 33, 42]

        prob = om.Problem()

        ivc = prob.model.add_subsystem('ivc',
                                       om.IndepVarComp(),
                                       promotes_outputs=['*'])
        for n, size in enumerate(sizes):
            ivc.add_output(f'in{n}', np.ones(size), distributed=True)
            prob.model.add_design_var(f'in{n}')

        prob.model.add_subsystem('adder',
                                 DistributedAdder(sizes),
                                 promotes=['*'])

        prob.model.add_subsystem('summer',
                                 Summer(sizes),
                                 promotes_outputs=['sum'])
        for n, size in enumerate(sizes):
            prob.model.promotes('summer',
                                inputs=[f'summand{n}'],
                                src_indices=om.slicer[:],
                                src_shape=size)
        prob.model.add_objective('sum')

        prob.driver.recording_options['record_desvars'] = True
        prob.driver.recording_options['record_objectives'] = True
        prob.driver.recording_options['record_constraints'] = True
        prob.driver.recording_options['includes'] = [
            f'out{n}' for n in range(len(sizes))
        ]
        prob.driver.add_recorder(self.recorder)

        prob.setup()
        t0, t1 = run_driver(prob)
        prob.cleanup()

        coordinate = [0, 'Driver', (0, )]

        expected_desvars = {}
        for n in range(len(sizes)):
            expected_desvars[f'ivc.in{n}'] = prob.get_val(f'ivc.in{n}',
                                                          get_remote=True)

        expected_objectives = {"summer.sum": prob['summer.sum']}

        expected_outputs = expected_desvars.copy()
        for n in range(len(sizes)):
            expected_outputs[f'adder.out{n}'] = prob.get_val(f'adder.out{n}',
                                                             get_remote=True)

        if prob.comm.rank == 0:
            expected_outputs.update(expected_objectives)

            expected_data = ((coordinate, (t0, t1), expected_outputs, None,
                              None), )
            assertDriverIterDataRecorded(self, expected_data, self.eps)
예제 #9
0
    def test_record_solver_linear_linear_run_once(self, m):
        self.setup_endpoints(m)
        recorder = WebRecorder(self._accepted_token, suppress_output=True)
        # raise unittest.SkipTest("Linear Solver recording not working yet")
        self.setup_sellar_model()

        self.prob.model.nonlinear_solver = NewtonSolver()
        # used for analytic derivatives
        self.prob.model.nonlinear_solver.linear_solver = LinearRunOnce()

        linear_solver = self.prob.model.nonlinear_solver.linear_solver
        linear_solver.recording_options['record_abs_error'] = True
        linear_solver.recording_options['record_rel_error'] = True
        linear_solver.recording_options['record_solver_residuals'] = True
        self.prob.model.nonlinear_solver.linear_solver.add_recorder(recorder)

        self.prob.setup(check=False)
        t0, t1 = run_driver(self.prob)

        solver_iteration = json.loads(self.solver_iterations)
        expected_abs_error = 0.0
        expected_rel_error = 0.0

        expected_solver_output = [
            {
                'name': 'px.x',
                'values': [0.0]
            },
            {
                'name': 'pz.z',
                'values': [0.0, 0.0]
            },
            {
                'name': 'd1.y1',
                'values': [-4.15366975e-05]
            },
            {
                'name': 'd2.y2',
                'values': [-4.10568454e-06]
            },
            {
                'name': 'obj_cmp.obj',
                'values': [-4.15366737e-05]
            },
            {
                'name': 'con_cmp1.con1',
                'values': [4.15366975e-05]
            },
            {
                'name': 'con_cmp2.con2',
                'values': [-4.10568454e-06]
            },
        ]

        self.assertAlmostEqual(expected_abs_error, solver_iteration['abs_err'])
        self.assertAlmostEqual(expected_rel_error, solver_iteration['rel_err'])

        for o in expected_solver_output:
            self.assert_array_close(o, solver_iteration['solver_output'])
    def test_simple_driver_recording(self, m):
        self.setup_endpoints(m)
        recorder = WebRecorder(self._accepted_token, suppress_output=True)

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

        model.add_subsystem('p1', IndepVarComp('x', 50.0), promotes=['*'])
        model.add_subsystem('p2', IndepVarComp('y', 50.0), promotes=['*'])
        model.add_subsystem('comp', Paraboloid(), promotes=['*'])
        model.add_subsystem('con', ExecComp('c = - x + y'), promotes=['*'])

        model.suppress_solver_output = True

        prob.driver = pyOptSparseDriver()

        prob.driver.add_recorder(recorder)
        prob.driver.recording_options['record_desvars'] = True
        prob.driver.recording_options['record_responses'] = True
        prob.driver.recording_options['record_objectives'] = True
        prob.driver.recording_options['record_constraints'] = True

        prob.driver.options['optimizer'] = OPTIMIZER
        if OPTIMIZER == 'SLSQP':
            prob.driver.opt_settings['ACC'] = 1e-9

        model.add_design_var('x', lower=-50.0, upper=50.0)
        model.add_design_var('y', lower=-50.0, upper=50.0)
        model.add_objective('f_xy')
        model.add_constraint('c', upper=-15.0)
        prob.setup(check=False)

        t0, t1 = run_driver(prob)

        prob.cleanup()

        driver_iteration_data = json.loads(self.driver_iteration_data)

        expected_desvars = [
            {'name': 'p1.x', 'values': [7.1666666]},
            {'name': 'p2.y', 'values': [-7.8333333]}
        ]

        expected_objectives = [
            {'name': 'comp.f_xy', 'values': [-27.083333]}
        ]

        expected_constraints = [
            {'name': 'con.c', 'values': [-15.0]}
        ]

        for d in expected_desvars:
            self.assert_array_close(d, driver_iteration_data['desvars'])

        for o in expected_objectives:
            self.assert_array_close(o, driver_iteration_data['objectives'])

        for c in expected_constraints:
            self.assert_array_close(c, driver_iteration_data['constraints'])
예제 #11
0
    def test_record_solver_linear_block_gs(self, m):
        self.setup_endpoints(m)
        recorder = WebRecorder(self._accepted_token, suppress_output=True)
        self.setup_sellar_model()

        self.prob.model.nonlinear_solver = NewtonSolver()
        # used for analytic derivatives
        self.prob.model.nonlinear_solver.linear_solver = LinearBlockGS()

        linear_solver = self.prob.model.nonlinear_solver.linear_solver
        linear_solver.recording_options['record_abs_error'] = True
        linear_solver.recording_options['record_rel_error'] = True
        linear_solver.recording_options['record_solver_residuals'] = True
        self.prob.model.nonlinear_solver.linear_solver.add_recorder(recorder)

        self.prob.setup(check=False)
        t0, t1 = run_driver(self.prob)

        solver_iteration = json.loads(self.solver_iterations)
        expected_abs_error = 9.109083208861876e-11
        expected_rel_error = 9.114367543620551e-12

        expected_solver_output = [
            {
                'name': 'px.x',
                'values': [0.0]
            },
            {
                'name': 'pz.z',
                'values': [0.0, 0.0]
            },
            {
                'name': 'd1.y1',
                'values': [0.00045069]
            },
            {
                'name': 'd2.y2',
                'values': [-0.00225346]
            },
            {
                'name': 'obj_cmp.obj',
                'values': [0.00045646]
            },
            {
                'name': 'con_cmp1.con1',
                'values': [-0.00045069]
            },
            {
                'name': 'con_cmp2.con2',
                'values': [-0.00225346]
            },
        ]

        self.assertAlmostEqual(expected_abs_error, solver_iteration['abs_err'])
        self.assertAlmostEqual(expected_rel_error, solver_iteration['rel_err'])

        for o in expected_solver_output:
            self.assert_array_close(o, solver_iteration['solver_output'])
예제 #12
0
    def test_record_solver_linear_block_jac(self, m):
        self.setup_endpoints(m)
        recorder = WebRecorder(self._accepted_token, suppress_output=True)
        self.setup_sellar_model()

        self.prob.model.nonlinear_solver = NewtonSolver()
        # used for analytic derivatives
        self.prob.model.nonlinear_solver.linear_solver = LinearBlockJac()

        linear_solver = self.prob.model.nonlinear_solver.linear_solver
        linear_solver.recording_options['record_abs_error'] = True
        linear_solver.recording_options['record_rel_error'] = True
        linear_solver.recording_options['record_solver_residuals'] = True
        self.prob.model.nonlinear_solver.linear_solver.add_recorder(recorder)

        self.prob.setup(check=False)
        t0, t1 = run_driver(self.prob)

        solver_iteration = json.loads(self.solver_iterations)
        expected_abs_error = 9.947388408259769e-11
        expected_rel_error = 4.330301334141486e-08

        expected_solver_output = [
            {
                'name': 'px.x',
                'values': [0.0]
            },
            {
                'name': 'pz.z',
                'values': [0.0, 0.0]
            },
            {
                'name': 'd1.y1',
                'values': [4.55485639e-09]
            },
            {
                'name': 'd2.y2',
                'values': [-2.27783334e-08]
            },
            {
                'name': 'obj_cmp.obj',
                'values': [-2.28447051e-07]
            },
            {
                'name': 'con_cmp1.con1',
                'values': [2.28461863e-07]
            },
            {
                'name': 'con_cmp2.con2',
                'values': [-2.27742837e-08]
            },
        ]

        self.assertAlmostEqual(expected_abs_error, solver_iteration['abs_err'])
        self.assertAlmostEqual(expected_rel_error, solver_iteration['rel_err'])

        for o in expected_solver_output:
            self.assert_array_close(o, solver_iteration['solver_output'])
예제 #13
0
    def test_implicit_component(self, m):
        self.setup_endpoints(m)
        recorder = WebRecorder(self._accepted_token, suppress_output=True)
        from openmdao.core.tests.test_impl_comp import QuadraticLinearize, QuadraticJacVec
        group = Group()
        group.add_subsystem('comp1',
                            IndepVarComp([('a', 1.0), ('b', 1.0), ('c', 1.0)]))
        group.add_subsystem('comp2', QuadraticLinearize())
        group.add_subsystem('comp3', QuadraticJacVec())
        group.connect('comp1.a', 'comp2.a')
        group.connect('comp1.b', 'comp2.b')
        group.connect('comp1.c', 'comp2.c')
        group.connect('comp1.a', 'comp3.a')
        group.connect('comp1.b', 'comp3.b')
        group.connect('comp1.c', 'comp3.c')

        prob = Problem(model=group)
        prob.setup(check=False)

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

        comp2 = prob.model.comp2  # ImplicitComponent
        comp2.add_recorder(recorder)

        t0, t1 = run_driver(prob)
        prob.cleanup()

        expected_inputs = [{
            'name': 'comp2.a',
            'values': [1.0]
        }, {
            'name': 'comp2.b',
            'values': [-4.0]
        }, {
            'name': 'comp2.c',
            'values': [3.0]
        }]
        expected_outputs = [{'name': 'comp2.x', 'values': [3.0]}]
        expected_residuals = [{'name': 'comp2.x', 'values': [0.0]}]

        system_iteration = json.loads(self.system_iterations)

        for i in expected_inputs:
            self.assert_array_close(i, system_iteration['inputs'])

        for r in expected_residuals:
            self.assert_array_close(r, system_iteration['residuals'])

        for o in expected_outputs:
            self.assert_array_close(o, system_iteration['outputs'])
    def test_record_solver_nonlinear_block_gs(self, m):
        self.setup_endpoints(m)
        recorder = WebRecorder(self._accepted_token, suppress_output=True)
        self.setup_sellar_model()

        self.prob.model.nonlinear_solver = NonlinearBlockGS()
        self.prob.model.nonlinear_solver.add_recorder(recorder)
        nonlinear_solver = self.prob.model.nonlinear_solver
        nonlinear_solver.recording_options['record_solver_residuals'] = True

        self.prob.setup(check=False)

        t0, t1 = run_driver(self.prob)

        self.prob.cleanup()

        coordinate = [0, 'Driver', (0,), 'root._solve_nonlinear', (0,), 'NonlinearBlockGS', (6, )]
        expected_abs_error = 1.31880284470753394998e-10
        expected_rel_error = 3.6299074030587596e-12

        expected_solver_output = [
            {'name': 'px.x', 'values': [1.0]},
            {'name': 'pz.z', 'values': [5., 2.]},
            {'name': 'd1.y1', 'values': [25.58830237]},
            {'name': 'd2.y2', 'values': [12.05848815]},
            {'name': 'obj_cmp.obj', 'values': [28.58830817]},
            {'name': 'con_cmp1.con1', 'values': [-22.42830237]},
            {'name': 'con_cmp2.con2', 'values': [-11.94151185]}
        ]

        expected_solver_residuals = [
            {'name': 'px.x', 'values': [-0]},
            {'name': 'pz.z', 'values': [-0., -0.]},
            {'name': 'd1.y1', 'values': [1.31880284e-10]},
            {'name': 'd2.y2', 'values': [0.]},
            {'name': 'obj_cmp.obj', 'values': [0.]},
            {'name': 'con_cmp1.con1', 'values': [0.]},
            {'name': 'con_cmp2.con2', 'values': [0.]},
        ]

        solver_iteration = json.loads(self.solver_iterations)

        self.assertAlmostEqual(solver_iteration['abs_err'], expected_abs_error)
        self.assertAlmostEqual(solver_iteration['rel_err'], expected_rel_error)

        for o in expected_solver_output:
            self.assert_array_close(o, solver_iteration['solver_output'])

        for r in expected_solver_residuals:
            self.assert_array_close(r, solver_iteration['solver_residuals'])
예제 #15
0
    def test_only_constraints_recorded(self, m):
        self.setup_endpoints(m)
        recorder = WebRecorder(self._accepted_token, suppress_output=True)

        self.setup_sellar_model()

        self.prob.driver.recording_options['record_desvars'] = False
        self.prob.driver.recording_options['record_responses'] = False
        self.prob.driver.recording_options['record_objectives'] = False
        self.prob.driver.recording_options['record_constraints'] = True
        self.prob.driver.add_recorder(recorder)
        self.prob.setup(check=False)

        t0, t1 = run_driver(self.prob)

        self.prob.cleanup()

        driver_iteration_data = json.loads(self.driver_iteration_data)
        if driver_iteration_data['constraints'][0]['name'] == 'con_cmp1.con1':
            self.assertAlmostEqual(
                driver_iteration_data['constraints'][0]['values'][0],
                -22.42830237)
            self.assertAlmostEqual(
                driver_iteration_data['constraints'][1]['values'][0],
                -11.94151185)
            self.assertEqual(driver_iteration_data['constraints'][1]['name'],
                             'con_cmp2.con2')
            self.assertEqual(driver_iteration_data['constraints'][0]['name'],
                             'con_cmp1.con1')
        elif driver_iteration_data['constraints'][0][
                'name'] == 'con_cmp2.con2':
            self.assertAlmostEqual(
                driver_iteration_data['constraints'][1]['values'][0],
                -22.42830237)
            self.assertAlmostEqual(
                driver_iteration_data['constraints'][0]['values'][0],
                -11.94151185)
            self.assertEqual(driver_iteration_data['constraints'][0]['name'],
                             'con_cmp2.con2')
            self.assertEqual(driver_iteration_data['constraints'][1]['name'],
                             'con_cmp1.con1')
        else:
            self.assertTrue(
                False, 'Driver iteration data did not contain\
             the expected names for constraints')

        self.assertEqual(driver_iteration_data['desvars'], [])
        self.assertEqual(driver_iteration_data['objectives'], [])
        self.assertEqual(driver_iteration_data['responses'], [])
    def test_distrib_record_driver(self):
        size = 100  # how many items in the array
        prob = Problem()

        prob.model.add_subsystem('des_vars',
                                 IndepVarComp('x', np.ones(size)),
                                 promotes=['x'])
        prob.model.add_subsystem('plus',
                                 DistributedAdder(size),
                                 promotes=['x', 'y'])
        prob.model.add_subsystem('summer',
                                 Summer(size),
                                 promotes_outputs=['sum'])
        prob.model.promotes('summer', inputs=['y'], src_indices=slicer[:])
        prob.driver.recording_options['record_desvars'] = True
        prob.driver.recording_options['record_objectives'] = True
        prob.driver.recording_options['record_constraints'] = True
        prob.driver.recording_options['includes'] = ['y']
        prob.driver.add_recorder(self.recorder)

        prob.model.add_design_var('x')
        prob.model.add_objective('sum')

        prob.setup()

        prob['x'] = np.ones(size)

        t0, t1 = run_driver(prob)
        prob.cleanup()

        coordinate = [0, 'Driver', (0, )]

        expected_desvars = {
            "des_vars.x": prob['des_vars.x'],
        }

        expected_objectives = {
            "summer.sum": prob['summer.sum'],
        }

        expected_outputs = expected_desvars.copy()
        expected_outputs['plus.y'] = prob.get_val('plus.y', get_remote=True)

        if prob.comm.rank == 0:
            expected_outputs.update(expected_objectives)

            expected_data = ((coordinate, (t0, t1), expected_outputs, None,
                              None), )
            assertDriverIterDataRecorded(self, expected_data, self.eps)
    def test_record_solver(self, m):
        self.setup_endpoints(m)
        recorder = WebRecorder(self._accepted_token, suppress_output=True)

        self.setup_sellar_model()

        nonlinear_solver = self.prob.model._nonlinear_solver
        nonlinear_solver.recording_options['record_abs_error'] = True
        nonlinear_solver.recording_options['record_rel_error'] = True
        nonlinear_solver.recording_options['record_solver_residuals'] = True
        self.prob.model._nonlinear_solver.add_recorder(recorder)

        self.prob.setup(check=False)

        t0, t1 = run_driver(self.prob)

        self.prob.cleanup()

        expected_solver_output = [
            {'name': 'con_cmp1.con1', 'values': [-22.42830237000701]},
            {'name': 'd1.y1', 'values': [25.58830237000701]},
            {'name': 'con_cmp2.con2', 'values': [-11.941511849375644]},
            {'name': 'pz.z', 'values': [5.0, 2.0]},
            {'name': 'obj_cmp.obj', 'values': [28.588308165163074]},
            {'name': 'd2.y2', 'values': [12.058488150624356]},
            {'name': 'px.x', 'values': [1.0]}
        ]

        expected_solver_residuals = [
            {'name': 'con_cmp1.con1', 'values': [0.0]},
            {'name': 'd1.y1', 'values': [1.318802844707534e-10]},
            {'name': 'con_cmp2.con2', 'values': [0.0]},
            {'name': 'pz.z', 'values': [0.0, 0.0]},
            {'name': 'obj_cmp.obj', 'values': [0.0]},
            {'name': 'd2.y2', 'values': [0.0]},
            {'name': 'px.x', 'values': [0.0]}
        ]

        solver_iteration = json.loads(self.solver_iterations)

        self.assertAlmostEqual(solver_iteration['abs_err'], 1.31880284470753394998e-10)
        self.assertAlmostEqual(solver_iteration['rel_err'], 3.6299074030587596e-12)

        for o in expected_solver_output:
            self.assert_array_close(o, solver_iteration['solver_output'])

        for r in expected_solver_residuals:
            self.assert_array_close(r, solver_iteration['solver_residuals'])
    def test_record_solver_linear_direct_solver(self, m):
        self.setup_endpoints(m)
        recorder = WebRecorder(self._accepted_token, suppress_output=True)
        self.setup_sellar_model()

        self.prob.model.nonlinear_solver = NewtonSolver()
        # used for analytic derivatives
        self.prob.model.nonlinear_solver.linear_solver = DirectSolver()

        linear_solver = self.prob.model.nonlinear_solver.linear_solver
        linear_solver.recording_options['record_abs_error'] = True
        linear_solver.recording_options['record_rel_error'] = True
        linear_solver.recording_options['record_solver_residuals'] = True
        self.prob.model.nonlinear_solver.linear_solver.add_recorder(recorder)

        self.prob.setup(check=False)
        t0, t1 = run_driver(self.prob)

        expected_solver_output = [
            {'name': 'px.x', 'values': [0.0]},
            {'name': 'pz.z', 'values': [0.0, 0.0]},
            {'name': 'd1.y1', 'values': [0.00045069]},
            {'name': 'd2.y2', 'values': [-0.00225346]},
            {'name': 'obj_cmp.obj', 'values': [0.00045646]},
            {'name': 'con_cmp1.con1', 'values': [-0.00045069]},
            {'name': 'con_cmp2.con2', 'values': [-0.00225346]},
        ]

        expected_solver_residuals = [
            {'name': 'px.x', 'values': [0.0]},
            {'name': 'pz.z', 'values': [-0., -0.]},
            {'name': 'd1.y1', 'values': [0.0]},
            {'name': 'd2.y2', 'values': [-0.00229801]},
            {'name': 'obj_cmp.obj', 'values': [5.75455956e-06]},
            {'name': 'con_cmp1.con1', 'values': [-0.]},
            {'name': 'con_cmp2.con2', 'values': [-0.]},
        ]

        solver_iteration = json.loads(self.solver_iterations)

        self.assertAlmostEqual(0.0, solver_iteration['abs_err'])
        self.assertAlmostEqual(0.0, solver_iteration['rel_err'])

        for o in expected_solver_output:
            self.assert_array_close(o, solver_iteration['solver_output'])

        for r in expected_solver_residuals:
            self.assert_array_close(r, solver_iteration['solver_residuals'])
    def test_driver_everything_recorded_by_default(self, m):
        self.setup_endpoints(m)
        recorder = WebRecorder(self._accepted_token, suppress_output=True)

        self.setup_sellar_model()
        self.prob.driver.add_recorder(recorder)
        self.prob.setup(check=False)

        t0, t1 = run_driver(self.prob)

        self.prob.cleanup()

        driver_iteration_data = json.loads(self.driver_iteration_data)
        self.assertEqual(len(driver_iteration_data['sysincludes']), 2)
        self.assertEqual(len(driver_iteration_data['objectives']), 1)
        self.assertEqual(len(driver_iteration_data['desvars']), 2)
        self.assertEqual(len(driver_iteration_data['constraints']), 2)
        self.assertEqual(driver_iteration_data['responses'], [])
    def test_distrib_record_driver(self):

        size = 100  # how many items in the array
        prob = Problem()
        prob.model = Group()

        prob.model.add_subsystem('des_vars',
                                 IndepVarComp('x', np.ones(size)),
                                 promotes=['x'])
        prob.model.add_subsystem('plus',
                                 DistributedAdder(size),
                                 promotes=['x', 'y'])
        prob.model.add_subsystem('summer', Summer(size), promotes=['y', 'sum'])
        prob.driver.recording_options['record_desvars'] = True
        prob.driver.recording_options['record_responses'] = True
        prob.driver.recording_options['record_objectives'] = True
        prob.driver.recording_options['record_constraints'] = True
        prob.driver.recording_options['includes'] = []
        prob.driver.add_recorder(self.recorder)

        prob.model.add_design_var('x')
        prob.model.add_objective('sum')

        prob.setup(vector_class=PETScVector, check=False)

        prob['x'] = np.ones(size)

        t0, t1 = run_driver(prob)
        prob.cleanup()

        if prob.comm.rank == 0:
            coordinate = [0, 'Driver', (0, )]

            expected_desvars = {
                "des_vars.x": prob['des_vars.x'],
            }

            expected_objectives = {
                "summer.sum": prob['summer.sum'],
            }

            self.assertDriverIterationDataRecorded(
                ((coordinate, (t0, t1), expected_desvars, None,
                  expected_objectives, None, None), ), self.eps)
    def test_distrib_record_driver(self):
        size = 100  # how many items in the array
        prob = Problem()
        prob.model = Group()

        prob.model.add_subsystem('des_vars', IndepVarComp('x', np.ones(size)), promotes=['x'])
        prob.model.add_subsystem('plus', DistributedAdder(size), promotes=['x', 'y'])
        prob.model.add_subsystem('summer', Summer(size), promotes=['y', 'sum'])
        prob.driver.recording_options['record_desvars'] = True
        prob.driver.recording_options['record_responses'] = True
        prob.driver.recording_options['record_objectives'] = True
        prob.driver.recording_options['record_constraints'] = True
        prob.driver.recording_options['includes'] = []
        prob.driver.add_recorder(self.recorder)

        prob.model.add_design_var('x')
        prob.model.add_objective('sum')

        prob.setup(check=False)

        prob['x'] = np.ones(size)

        t0, t1 = run_driver(prob)
        prob.cleanup()

        if prob.comm.rank == 0:
            coordinate = [0, 'Driver', (0,)]

            expected_desvars = {
                "des_vars.x": prob['des_vars.x'],
            }

            expected_objectives = {
                "summer.sum": prob['summer.sum'],
            }

            expected_outputs = expected_desvars
            expected_outputs.update(expected_objectives)

            expected_data = ((coordinate, (t0, t1), expected_outputs, None),)
            assertDriverIterDataRecorded(self, expected_data, self.eps)
    def test_record_solver_nonlinear_newton(self, m):
        self.setup_endpoints(m)
        recorder = WebRecorder(self._accepted_token, suppress_output=True)
        self.setup_sellar_model()

        self.prob.model.nonlinear_solver = NewtonSolver()
        self.prob.model.nonlinear_solver.add_recorder(recorder)

        self.prob.setup(check=False)

        t0, t1 = run_driver(self.prob)

        self.prob.cleanup()

        solver_iteration = json.loads(self.solver_iterations)

        expected_abs_error = 2.1677810075550974e-10
        expected_rel_error = 5.966657077752565e-12
        self.assertAlmostEqual(expected_abs_error, solver_iteration['abs_err'])
        self.assertAlmostEqual(expected_rel_error, solver_iteration['rel_err'])
        self.assertEqual(solver_iteration['solver_residuals'], [])
        self.assertEqual(len(solver_iteration['solver_output']), 7)
    def test_record_solver_nonlinear_block_jac(self, m):
        self.setup_endpoints(m)
        recorder = WebRecorder(self._accepted_token, suppress_output=True)
        self.setup_sellar_model()

        self.prob.model.nonlinear_solver = NonlinearBlockJac()
        self.prob.model.nonlinear_solver.add_recorder(recorder)

        self.prob.setup(check=False)

        t0, t1 = run_driver(self.prob)

        self.prob.cleanup()

        solver_iteration = json.loads(self.solver_iterations)

        expected_abs_error = 7.234027587097439e-07
        expected_rel_error = 1.991112651729199e-08
        self.assertAlmostEqual(expected_abs_error, solver_iteration['abs_err'])
        self.assertAlmostEqual(expected_rel_error, solver_iteration['rel_err'])
        self.assertEqual(solver_iteration['solver_residuals'], [])
        self.assertEqual(len(solver_iteration['solver_output']), 7)
    def test_recording_remote_voi(self):
        # Create a parallel model
        model = Group()

        model.add_subsystem('par', ParallelGroup())
        model.par.add_subsystem('G1', Mygroup())
        model.par.add_subsystem('G2', Mygroup())
        model.connect('par.G1.y', 'Obj.y1')
        model.connect('par.G2.y', 'Obj.y2')

        model.add_subsystem('Obj', ExecComp('obj=y1+y2'))
        model.add_objective('Obj.obj')

        # Configure driver to record VOIs on both procs
        driver = ScipyOptimizeDriver(disp=False)

        driver.recording_options['record_desvars'] = True
        driver.recording_options['record_responses'] = True
        driver.recording_options['record_objectives'] = True
        driver.recording_options['record_constraints'] = True
        driver.recording_options['includes'] = ['par.G1.y', 'par.G2.y']

        driver.add_recorder(self.recorder)

        # Create problem and run driver
        prob = Problem(model, driver)
        prob.setup()
        t0, t1 = run_driver(prob)
        prob.cleanup()

        # Since the test will compare the last case recorded, just check the
        # current values in the problem. This next section is about getting those values

        # These involve collective gathers so all ranks need to run this
        expected_outputs = prob.driver.get_design_var_values()
        expected_outputs.update(prob.driver.get_objective_values())
        expected_outputs.update(prob.driver.get_constraint_values())

        # includes for outputs are specified as promoted names but we need absolute names
        prom2abs = model._var_allprocs_prom2abs_list['output']
        abs_includes = [
            prom2abs[n][0] for n in prob.driver.recording_options['includes']
        ]

        # Absolute path names of includes on this rank
        rrank = model.comm.rank
        rowned = model._owning_rank
        local_includes = [n for n in abs_includes if rrank == rowned[n]]

        # Get values for all vars on this rank
        inputs, outputs, residuals = model.get_nonlinear_vectors()

        # Get values for includes on this rank
        local_vars = {n: outputs[n] for n in local_includes}

        # Gather values for includes on all ranks
        all_vars = model.comm.gather(local_vars, root=0)

        if prob.comm.rank == 0:
            # Only on rank 0 do we have all the values. The all_vars variable is a list of
            # dicts from all ranks 0,1,... In this case, just ranks 0 and 1
            dct = all_vars[-1]
            for d in all_vars[:-1]:
                dct.update(d)

            expected_includes = {
                'par.G1.Cy.y': dct['par.G1.Cy.y'],
                'par.G2.Cy.y': dct['par.G2.Cy.y'],
            }

            expected_outputs.update(expected_includes)

            coordinate = [0, 'ScipyOptimize_SLSQP', (driver.iter_count - 1, )]

            expected_data = ((coordinate, (t0, t1), expected_outputs, None), )
            assertDriverIterDataRecorded(self, expected_data, self.eps)
    def test_recording_remote_voi(self):
        # Create a parallel model
        model = Group()

        model.add_subsystem('par', ParallelGroup())
        model.par.add_subsystem('G1', Mygroup())
        model.par.add_subsystem('G2', Mygroup())
        model.connect('par.G1.y', 'Obj.y1')
        model.connect('par.G2.y', 'Obj.y2')

        model.add_subsystem('Obj', ExecComp('obj=y1+y2'))
        model.add_objective('Obj.obj')

        # Configure driver to record VOIs on both procs
        driver = ScipyOptimizeDriver(disp=False)

        driver.recording_options['record_desvars'] = True
        driver.recording_options['record_responses'] = True
        driver.recording_options['record_objectives'] = True
        driver.recording_options['record_constraints'] = True
        driver.recording_options['includes'] = ['par.G1.y', 'par.G2.y']

        driver.add_recorder(self.recorder)

        # Create problem and run driver
        prob = Problem(model, driver)
        prob.add_recorder(self.recorder)
        prob.setup()

        t0, t1 = run_driver(prob)
        prob.record_iteration('final')
        t2 = time()

        prob.cleanup()

        # Since the test will compare the last case recorded, just check the
        # current values in the problem. This next section is about getting those values

        # These involve collective gathers so all ranks need to run this
        expected_outputs = driver.get_design_var_values()
        expected_outputs.update(driver.get_objective_values())
        expected_outputs.update(driver.get_constraint_values())

        # includes for outputs are specified as promoted names but we need absolute names
        prom2abs = model._var_allprocs_prom2abs_list['output']
        abs_includes = [prom2abs[n][0] for n in prob.driver.recording_options['includes']]

        # Absolute path names of includes on this rank
        rrank = model.comm.rank
        rowned = model._owning_rank
        local_includes = [n for n in abs_includes if rrank == rowned[n]]

        # Get values for all vars on this rank
        inputs, outputs, residuals = model.get_nonlinear_vectors()

        # Get values for includes on this rank
        local_vars = {n: outputs[n] for n in local_includes}

        # Gather values for includes on all ranks
        all_vars = model.comm.gather(local_vars, root=0)

        if prob.comm.rank == 0:
            # Only on rank 0 do we have all the values. The all_vars variable is a list of
            # dicts from all ranks 0,1,... In this case, just ranks 0 and 1
            dct = all_vars[-1]
            for d in all_vars[:-1]:
                dct.update(d)

            expected_includes = {
                'par.G1.Cy.y': dct['par.G1.Cy.y'],
                'par.G2.Cy.y': dct['par.G2.Cy.y'],
            }

            expected_outputs.update(expected_includes)

            coordinate = [0, 'ScipyOptimize_SLSQP', (driver.iter_count-1,)]

            expected_data = ((coordinate, (t0, t1), expected_outputs, None),)
            assertDriverIterDataRecorded(self, expected_data, self.eps)

            expected_data = (('final', (t1, t2), expected_outputs),)
            assertProblemDataRecorded(self, expected_data, self.eps)
예제 #26
0
    def test_recording_remote_voi(self):
        prob = Problem()

        prob.model.add_subsystem('par', ParallelGroup())

        prob.model.par.add_subsystem('G1', Mygroup())
        prob.model.par.add_subsystem('G2', Mygroup())

        prob.model.add_subsystem('Obj', ExecComp('obj=y1+y2'))

        prob.model.connect('par.G1.y', 'Obj.y1')
        prob.model.connect('par.G2.y', 'Obj.y2')

        prob.model.add_objective('Obj.obj')

        prob.driver = pyOptSparseDriver()
        prob.driver.options['optimizer'] = 'SLSQP'

        prob.driver.recording_options['record_desvars'] = True
        prob.driver.recording_options['record_responses'] = True
        prob.driver.recording_options['record_objectives'] = True
        prob.driver.recording_options['record_constraints'] = True
        prob.driver.recording_options['includes'] = ['par.G1.Cy.y','par.G2.Cy.y']

        prob.driver.add_recorder(self.recorder)

        prob.setup(vector_class=PETScVector)
        t0, t1 = run_driver(prob)
        prob.cleanup()

        # Since the test will compare the last case recorded, just check the
        #   current values in the problem. This next section is about getting those values

        # These involve collective gathers so all ranks need to run this
        expected_desvars = prob.driver.get_design_var_values()
        expected_objectives = prob.driver.get_objective_values()
        expected_constraints = prob.driver.get_constraint_values()

        # Determine the expected values for the sysincludes
        # this gets all of the outputs but just locally
        rrank = prob.comm.rank  # root ( aka model ) rank.
        rowned = prob.model._owning_rank['output']
        # names of sysincl vars on this rank
        local_inclnames = [n for n in prob.driver.recording_options['includes'] if rrank == rowned[n]]
        # Get values for vars on this rank
        inputs, outputs, residuals = prob.model.get_nonlinear_vectors()
        #   Potential local sysvars are in this
        sysvars = outputs._names
        # Just get the values for the sysincl vars on this rank
        local_vars = {c: sysvars[c] for c in local_inclnames}
        # Gather up the values for all the sysincl vars on all ranks
        all_vars = prob.model.comm.gather(local_vars, root=0)

        if prob.comm.rank == 0:
            # Only on rank 0 do we have all the values and only on rank 0
            #   are we doing the testing.
            # The all_vars variable is list of dicts from rank 0,1,... In this case just ranks 0 and 1
            dct = all_vars[-1]
            for d in all_vars[:-1]:
                dct.update(d)

            expected_includes = {
                'par.G1.Cy.y': dct['par.G1.Cy.y'],
                'par.G2.Cy.y': dct['par.G2.Cy.y'],
            }


        if prob.comm.rank == 0:
            coordinate = [0, 'SLSQP', (49,)]
            self.assertDriverIterationDataRecorded(((coordinate, (t0, t1), expected_desvars, None,
                                                     expected_objectives, expected_constraints,
                                                     expected_includes),), self.eps)
    def test_recording_remote_voi(self):
        prob = Problem()

        prob.model.add_subsystem('par', ParallelGroup())

        prob.model.par.add_subsystem('G1', Mygroup())
        prob.model.par.add_subsystem('G2', Mygroup())

        prob.model.add_subsystem('Obj', ExecComp('obj=y1+y2'))

        prob.model.connect('par.G1.y', 'Obj.y1')
        prob.model.connect('par.G2.y', 'Obj.y2')

        prob.model.add_objective('Obj.obj')

        prob.driver = pyOptSparseDriver()
        prob.driver.options['optimizer'] = 'SLSQP'

        prob.driver.recording_options['record_desvars'] = True
        prob.driver.recording_options['record_responses'] = True
        prob.driver.recording_options['record_objectives'] = True
        prob.driver.recording_options['record_constraints'] = True
        prob.driver.recording_options['includes'] = [
            'par.G1.Cy.y', 'par.G2.Cy.y'
        ]

        prob.driver.add_recorder(self.recorder)

        prob.setup()
        t0, t1 = run_driver(prob)
        prob.cleanup()

        # Since the test will compare the last case recorded, just check the
        #   current values in the problem. This next section is about getting those values

        # These involve collective gathers so all ranks need to run this
        expected_outputs = prob.driver.get_design_var_values()
        expected_outputs.update(prob.driver.get_objective_values())
        expected_outputs.update(prob.driver.get_constraint_values())

        # Determine the expected values for the sysincludes
        # this gets all of the outputs but just locally
        rrank = prob.comm.rank  # root ( aka model ) rank.
        rowned = prob.model._owning_rank
        # names of sysincl vars on this rank
        local_inclnames = [
            n for n in prob.driver.recording_options['includes']
            if rrank == rowned[n]
        ]
        # Get values for vars on this rank
        inputs, outputs, residuals = prob.model.get_nonlinear_vectors()
        #   Potential local sysvars are in this
        sysvars = outputs._views
        # Just get the values for the sysincl vars on this rank
        local_vars = {c: sysvars[c] for c in local_inclnames}
        # Gather up the values for all the sysincl vars on all ranks
        all_vars = prob.model.comm.gather(local_vars, root=0)

        if prob.comm.rank == 0:
            # Only on rank 0 do we have all the values. The all_vars variable is a list of
            # dicts from all ranks 0,1,... In this case, just ranks 0 and 1
            dct = all_vars[-1]
            for d in all_vars[:-1]:
                dct.update(d)

            expected_includes = {
                'par.G1.Cy.y': dct['par.G1.Cy.y'],
                'par.G2.Cy.y': dct['par.G2.Cy.y'],
            }

            expected_outputs.update(expected_includes)

            coordinate = [0, 'SLSQP', (48, )]

            expected_data = ((coordinate, (t0, t1), expected_outputs, None), )
            assertDriverIterDataRecorded(self, expected_data, self.eps)
    def test_record_driver_system_solver(self, m):
        # Test what happens when all three types are recorded:
        #    Driver, System, and Solver
        self.setup_endpoints(m)
        recorder = WebRecorder(self._accepted_token, suppress_output=True)

        self.setup_sellar_grouped_model()

        self.prob.driver = pyOptSparseDriver()
        self.prob.driver.options['optimizer'] = OPTIMIZER
        self.prob.driver.opt_settings['ACC'] = 1e-9

        # Add recorders
        # Driver
        self.prob.driver.recording_options['record_metadata'] = True
        self.prob.driver.recording_options['record_desvars'] = True
        self.prob.driver.recording_options['record_responses'] = True
        self.prob.driver.recording_options['record_objectives'] = True
        self.prob.driver.recording_options['record_constraints'] = True
        self.prob.driver.add_recorder(recorder)
        # System
        pz = self.prob.model.pz  # IndepVarComp which is an ExplicitComponent
        pz.recording_options['record_metadata'] = True
        pz.recording_options['record_inputs'] = True
        pz.recording_options['record_outputs'] = True
        pz.recording_options['record_residuals'] = True
        pz.add_recorder(recorder)
        # Solver
        mda = self.prob.model.mda
        mda.nonlinear_solver.recording_options['record_metadata'] = True
        mda.nonlinear_solver.recording_options['record_abs_error'] = True
        mda.nonlinear_solver.recording_options['record_rel_error'] = True
        mda.nonlinear_solver.recording_options['record_solver_residuals'] = True
        mda.nonlinear_solver.add_recorder(recorder)

        self.prob.setup(check=False, mode='rev')
        t0, t1 = run_driver(self.prob)
        self.prob.cleanup()

        # Driver recording test
        coordinate = [0, 'SLSQP', (7, )]

        expected_desvars = [
            {'name': 'pz.z', 'values': self.prob['pz.z']},
            {'name': 'px.x', 'values': self.prob['px.x']}
        ]

        expected_objectives = [
            {'name': 'obj_cmp.obj', 'values': self.prob['obj_cmp.obj']}
        ]

        expected_constraints = [
            {'name': 'con_cmp1.con1', 'values': self.prob['con_cmp1.con1']},
            {'name': 'con_cmp2.con2', 'values': self.prob['con_cmp2.con2']}
        ]

        driver_iteration_data = json.loads(self.driver_iteration_data)

        for d in expected_desvars:
            self.assert_array_close(d, driver_iteration_data['desvars'])

        for o in expected_objectives:
            self.assert_array_close(o, driver_iteration_data['objectives'])

        for c in expected_constraints:
            self.assert_array_close(c, driver_iteration_data['constraints'])

        # System recording test
        expected_inputs = []
        expected_outputs = [{'name': 'pz.z', 'values': [1.978467, -1.6464114e-13]}]
        expected_residuals = [{'name': 'pz.z', 'values': [0.0, 0.0]}]

        system_iteration = json.loads(self.system_iterations)

        self.assertEqual(expected_inputs, system_iteration['inputs'])

        for o in expected_outputs:
            self.assert_array_close(o, system_iteration['outputs'])

        for r in expected_residuals:
            self.assert_array_close(r, system_iteration['residuals'])

        # Solver recording test
        expected_abs_error = 3.90598e-11
        expected_rel_error = 2.0701941e-06

        expected_solver_output = [
            {'name': 'mda.d2.y2', 'values': [3.75610598]},
            {'name': 'mda.d1.y1', 'values': [3.16]}
        ]

        expected_solver_residuals = [
            {'name': 'mda.d2.y2', 'values': [0.0]},
            {'name': 'mda.d1.y1', 'values': [0.0]}
        ]

        solver_iteration = json.loads(self.solver_iterations)

        np.testing.assert_almost_equal(expected_abs_error, solver_iteration['abs_err'], decimal=5)
        np.testing.assert_almost_equal(expected_rel_error, solver_iteration['rel_err'], decimal=5)

        for o in expected_solver_output:
            self.assert_array_close(o, solver_iteration['solver_output'])

        for r in expected_solver_residuals:
            self.assert_array_close(r, solver_iteration['solver_residuals'])
    def test_record_system(self, m):
        self.setup_endpoints(m)
        recorder = WebRecorder(self._accepted_token, suppress_output=True)

        self.setup_sellar_model()

        self.prob.model.recording_options['record_inputs'] = True
        self.prob.model.recording_options['record_outputs'] = True
        self.prob.model.recording_options['record_residuals'] = True
        self.prob.model.recording_options['record_metadata'] = True

        self.prob.model.add_recorder(recorder)

        d1 = self.prob.model.d1  # instance of SellarDis1withDerivatives, a Group
        d1.add_recorder(recorder)

        obj_cmp = self.prob.model.obj_cmp  # an ExecComp
        obj_cmp.add_recorder(recorder)

        self.prob.setup(check=False)

        t0, t1 = run_driver(self.prob)

        self.prob.cleanup()

        system_iterations = json.loads(self.system_iterations)

        inputs = [
            {'name': 'd1.z', 'values': [5.0, 2.0]},
            {'name': 'd1.x', 'values': [1.0]},
            {'name': 'd2.z', 'values': [5.0, 2.0]},
            {'name': 'd1.y2', 'values': [12.05848815]}
        ]

        outputs = [
            {'name': 'd1.y1', 'values': [25.58830237]}
        ]

        residuals = [
            {'name': 'd1.y1', 'values': [0.0]}
        ]

        for i in inputs:
            self.assert_array_close(i, system_iterations['inputs'])
        for o in outputs:
            self.assert_array_close(o, system_iterations['outputs'])
        for r in residuals:
            self.assert_array_close(r, system_iterations['residuals'])

        inputs = [
            {'name': 'con_cmp2.y2', 'values': [12.058488150624356]},
            {'name': 'obj_cmp.y1', 'values': [25.58830237000701]},
            {'name': 'obj_cmp.x', 'values': [1.0]},
            {'name': 'obj_cmp.z', 'values': [5.0, 2.0]}
        ]

        outputs = [
            {'name': 'obj_cmp.obj', 'values': [28.58830816]}
        ]

        residuals = [
            {'name': 'obj_cmp.obj', 'values': [0.0]}
        ]

        for i in inputs:
            self.assert_array_close(i, system_iterations['inputs'])
        for o in outputs:
            self.assert_array_close(o, system_iterations['outputs'])
        for r in residuals:
            self.assert_array_close(r, system_iterations['residuals'])