def test_error_change_after_setup(self): # Tests error messages for the 5 options that we should never change # after setup is called. top = Problem() top.root = SellarStateConnection() top.setup(check=False) # Not permitted to change this with self.assertRaises(RuntimeError) as err: top.root.fd_options['form'] = 'complex_step' expected_msg = "The 'form' option cannot be changed after setup." self.assertEqual(str(err.exception), expected_msg) top = Problem() top.root = SellarStateConnection() top.setup(check=False) # Not permitted to change this with self.assertRaises(RuntimeError) as err: top.root.fd_options['extra_check_partials_form'] = 'complex_step' expected_msg = "The 'extra_check_partials_form' option cannot be changed after setup." self.assertEqual(str(err.exception), expected_msg) top = Problem() top.root = SellarStateConnection() top.setup(check=False) # Not permitted to change this with self.assertRaises(RuntimeError) as err: top.root.fd_options['force_fd'] = True expected_msg = "The 'force_fd' option cannot be changed after setup." self.assertEqual(str(err.exception), expected_msg) top = Problem() top.root = SellarStateConnection() top.setup(check=False) # Not permitted to change this with self.assertRaises(RuntimeError) as err: top.root.ln_solver.options['mode'] = 'rev' expected_msg = "The 'mode' option cannot be changed after setup." self.assertEqual(str(err.exception), expected_msg) top = Problem() top.root = SellarStateConnection() top.setup(check=False) # Not permitted to change this with self.assertRaises(RuntimeError) as err: top.root.ln_solver.options['single_voi_relevance_reduction'] = True expected_msg = "The 'single_voi_relevance_reduction' option cannot be changed after setup." self.assertEqual(str(err.exception), expected_msg)
def test_index_array_param(self): prob = Problem() prob.root = SellarStateConnection() prob.driver = ScipyOptimizer() prob.driver.options['optimizer'] = 'SLSQP' prob.driver.options['tol'] = 1.0e-8 prob.driver.add_desvar('z', lower=np.array([-10.0]), upper=np.array([10.0]), indices=[0]) prob.driver.add_desvar('x', lower=0.0, upper=10.0) prob.driver.add_objective('obj') prob.driver.add_constraint('con1', upper=0.0) prob.driver.add_constraint('con2', upper=0.0) prob.driver.options['disp'] = False prob.setup(check=False) prob['z'][1] = 5.0 prob.run() assert_rel_error(self, prob['z'][0], 0.1005, 1e-3) assert_rel_error(self, prob['z'][1], 5.0, 1e-3) assert_rel_error(self, prob['x'], 0.0, 1e-3)
def test_newton_with_backtracking_analysis_error(self): top = Problem() top.root = SellarStateConnection() top.root.nl_solver.line_search.options['atol'] = 1e-12 top.root.nl_solver.line_search.options['rtol'] = 1e-12 top.root.nl_solver.line_search.options['maxiter'] = 2 top.root.nl_solver.line_search.options['err_on_maxiter'] = True # This is a very contrived test, but we step 8 times farther than we # should, then allow the line search to backtrack 3 steps, which # takes us back to 1.0. top.root.nl_solver.options['alpha'] = 8.0 top.setup(check=False) try: top.run() except AnalysisError as err: self.assertEqual( str(err), "Solve in '': BackTracking failed to converge after 2 iterations." ) else: self.fail("AnalysisError expected")
def test_sellar_specify_linear_solver(self): prob = Problem() prob.root = SellarStateConnection() prob.root.nl_solver = Newton() # Use bad settings for this one so that problem doesn't converge. # That way, we test that we are really using Newton's Lin Solver # instead. prob.root.ln_solver = ScipyGMRES() prob.root.ln_solver.options['maxiter'] = 1 # The good solver prob.root.nl_solver.ln_solver = ScipyGMRES() prob.setup(check=False) prob.run() assert_rel_error(self, prob['y1'], 25.58830273, .00001) assert_rel_error(self, prob['state_eq.y2_command'], 12.05848819, .00001) # Make sure we aren't iterating like crazy self.assertLess(prob.root.nl_solver.iter_count, 8) self.assertEqual(prob.root.ln_solver.iter_count, 0) self.assertGreater(prob.root.nl_solver.ln_solver.iter_count, 0)
def test_driver_param_indices_force_fd_shift(self): """ Test driver param indices with shifted indices and force_fd=True """ prob = Problem() prob.root = SellarStateConnection() prob.root.fd_options['force_fd'] = True prob.driver.add_desvar('z', lower=np.array([-10.0, -10.0]), upper=np.array([10.0, 10.0]), indices=[1]) prob.driver.add_desvar('x', lower=0.0, upper=10.0) prob.driver.add_objective('obj') prob.driver.add_constraint('con1', upper=0.0) prob.driver.add_constraint('con2', upper=0.0) #prob.driver.options['disp'] = False prob.setup(check=False) prob['z'][1] = 0.0 prob.run() J = prob.calc_gradient(['x', 'z'], ['obj'], mode='fd', return_format='array') assert_rel_error(self, J[0][1], 1.78402, 1e-3)
def test_driver_param_indices(self): """ Test driver param indices with pyOptSparse and force_fd=False """ prob = Problem() prob.root = SellarStateConnection() prob.root.fd_options['force_fd'] = False prob.driver = pyOptSparseDriver() prob.driver.options['optimizer'] = OPTIMIZER prob.driver.options['print_results'] = False prob.driver.add_desvar('z', lower=np.array([-10.0]), upper=np.array([10.0]), indices=[0]) prob.driver.add_desvar('x', lower=0.0, upper=10.0) prob.driver.add_objective('obj') prob.driver.add_constraint('con1', upper=0.0) prob.driver.add_constraint('con2', upper=0.0) prob.setup(check=False) prob['z'][1] = 0.0 prob.run() assert_rel_error(self, prob['z'][0], 1.9776, 1e-3) assert_rel_error(self, prob['z'][1], 0.0, 1e-3) assert_rel_error(self, prob['x'], 0.0, 1e-3)
def test_Sellar_state_SLSQP(self): prob = Problem() prob.root = SellarStateConnection() prob.driver = ScipyOptimizer() prob.driver.options['optimizer'] = 'SLSQP' prob.driver.options['tol'] = 1.0e-8 prob.driver.add_param('z', low=np.array([-10.0, 0.0]), high=np.array([10.0, 10.0])) prob.driver.add_param('x', low=0.0, high=10.0) prob.driver.add_objective('obj') prob.driver.add_constraint('con1') prob.driver.add_constraint('con2') prob.driver.options['disp'] = False prob.setup(check=False) prob.run() assert_rel_error(self, prob['z'][0], 1.9776, 1e-3) assert_rel_error(self, prob['z'][1], 0.0, 1e-3) assert_rel_error(self, prob['x'], 0.0, 1e-3)
def test_Sellar_state_SLSQP(self): """ Baseline Sellar test case without specifying indices. """ prob = Problem() prob.root = SellarStateConnection() prob.driver = ScipyOptimizer() prob.driver.options['optimizer'] = 'SLSQP' prob.driver.options['tol'] = 1.0e-8 prob.driver.add_desvar('z', lower=np.array([-10.0, 0.0]), upper=np.array([10.0, 10.0])) prob.driver.add_desvar('x', lower=0.0, upper=10.0) prob.driver.add_objective('obj') prob.driver.add_constraint('con1', upper=0.0) prob.driver.add_constraint('con2', upper=0.0) prob.driver.options['disp'] = False prob.setup(check=False) prob.run() assert_rel_error(self, prob['z'][0], 1.9776, 1e-3) assert_rel_error(self, prob['z'][1], 0.0, 1e-3) assert_rel_error(self, prob['x'], 0.0, 1e-3)
def test_iprint(self): top = Problem() top.root = SellarStateConnection() top.setup(check=False) base_stdout = sys.stdout try: ostream = cStringIO() sys.stdout = ostream top.run() finally: sys.stdout = base_stdout printed = ostream.getvalue() self.assertEqual(printed, '') # Turn on all iprints top.print_all_convergence() try: ostream = cStringIO() sys.stdout = ostream top.run() finally: sys.stdout = base_stdout printed = ostream.getvalue() self.assertEqual(printed.count('NEWTON'), 3) self.assertEqual(printed.count('GMRES'), 4) self.assertTrue('[root] NL: NEWTON 0 | ' in printed) self.assertTrue(' [root.sub] LN: GMRES 0 | ' in printed)
def test_driver_param_indices_slsqp_force_fd(self): """ Test driver param indices with ScipyOptimizer SLSQP and force_fd=True """ prob = Problem() prob.root = SellarStateConnection() prob.root.fd_options['force_fd'] = True prob.driver = ScipyOptimizer() prob.driver.options['optimizer'] = 'SLSQP' prob.driver.options['tol'] = 1.0e-8 prob.driver.options['disp'] = False prob.driver.add_desvar('z', lower=np.array([-10.0]), upper=np.array([10.0]), indices=[0]) prob.driver.add_desvar('x', lower=0.0, upper=10.0) prob.driver.add_objective('obj') prob.driver.add_constraint('con1', upper=0.0) prob.driver.add_constraint('con2', upper=0.0) #prob.driver.options['disp'] = False prob.setup(check=False) prob['z'][1] = 0.0 prob.run() assert_rel_error(self, prob['z'][0], 1.9776, 1e-3) assert_rel_error(self, prob['z'][1], 0.0, 1e-3) assert_rel_error(self, prob['x'], 0.0, 1e-3)
def test_sellar_state_connection(self): prob = Problem() prob.root = SellarStateConnection() prob.root.nl_solver = Newton() prob.setup(check=False) prob.run() assert_rel_error(self, prob['y1'], 25.58830273, .00001) assert_rel_error(self, prob['state_eq.y2_command'], 12.05848819, .00001) # Make sure we aren't iterating like crazy self.assertLess(prob.root.nl_solver.iter_count, 8)
def test_change_solver_after_setup(self): top = Problem() top.root = SellarStateConnection() top.setup(check=False) top.root.ln_solver = ScipyGMRES() with self.assertRaises(RuntimeError) as err: top.run() expected_msg = "Before running the model, setup() must be called. If " + \ "the configuration has changed since it was called, then " + \ "setup must be called again before running the model." self.assertEqual(str(err.exception), expected_msg)
def test_newton_with_backtracking(self): top = Problem() top.root = SellarStateConnection() top.root.nl_solver.line_search.options['atol'] = 1e-12 top.root.nl_solver.line_search.options['rtol'] = 1e-12 top.root.nl_solver.line_search.options['maxiter'] = 3 # This is a very contrived test, but we step 8 times farther than we # should, then allow the line search to backtrack 3 steps, which # takes us back to 1.0. top.root.nl_solver.options['alpha'] = 8.0 top.setup(check=False) top.run() assert_rel_error(self, top['y1'], 25.58830273, .00001) assert_rel_error(self, top['state_eq.y2_command'], 12.05848819, .00001)
def test_generate_numpydocstring(self): prob = Problem() prob.root = SellarStateConnection() prob.driver = ScipyOptimizer() prob.driver.options['optimizer'] = 'SLSQP' prob.driver.options['tol'] = 1.0e-8 prob.driver.add_desvar('z', lower=np.array([-10.0]), upper=np.array([10.0]), indices=[0]) prob.driver.add_desvar('x', lower=0.0, upper=10.0) prob.driver.add_objective('obj') prob.driver.add_constraint('con1', upper=0.0) prob.driver.add_constraint('con2', upper=0.0) prob.driver.options['disp'] = False test_string = prob.driver.generate_docstring() original_string = ' """\n\n Options\n -------\n options[\'disp\'] : bool(False)\n Set to False to prevent printing of Scipy convergence messages\n options[\'maxiter\'] : int(200)\n Maximum number of iterations.\n options[\'optimizer\'] : str(\'SLSQP\')\n Name of optimizer to use\n options[\'tol\'] : float(1e-08)\n Tolerance for termination. For detailed control, use solver-specific options.\n\n """\n' self.assertEqual(original_string, test_string)
def test_newton_with_backtracking_analysis_error(self): top = Problem() top.root = SellarStateConnection() top.root.nl_solver.line_search = BackTracking() top.root.nl_solver.line_search.options['maxiter'] = 2 top.root.nl_solver.line_search.options['err_on_maxiter'] = True top.root.nl_solver.line_search.options['c'] = 1.0 top.root.nl_solver.options['alpha'] = 10.0 top.setup(check=False) try: top.run() except AnalysisError as err: self.assertEqual( str(err), "Solve in '': BackTracking failed to converge after 2 iterations." ) else: self.fail("AnalysisError expected")
def test_sellar_derivs_under_lin_GS(self): prob = Problem() prob.root = Group() prob.root.ln_solver = LinearGaussSeidel() nest = prob.root.add('nest', SellarStateConnection()) nest.ln_solver = DirectSolver() nest.ln_solver.options['jacobian_method'] = 'assemble' nest.nl_solver.options['atol'] = 1e-12 prob.setup(check=False) prob.run() # Just make sure we are at the right answer assert_rel_error(self, prob['nest.y1'], 25.58830273, .00001) assert_rel_error(self, prob['nest.d1.y2'], 12.05848819, .00001) indep_list = ['nest.x', 'nest.z'] unknown_list = ['nest.obj', 'nest.con1', 'nest.con2'] Jbase = {} Jbase['nest.con1'] = {} Jbase['nest.con1']['nest.x'] = -0.98061433 Jbase['nest.con1']['nest.z'] = np.array([-9.61002285, -0.78449158]) Jbase['nest.con2'] = {} Jbase['nest.con2']['nest.x'] = 0.09692762 Jbase['nest.con2']['nest.z'] = np.array([1.94989079, 1.0775421 ]) Jbase['nest.obj'] = {} Jbase['nest.obj']['nest.x'] = 2.98061392 Jbase['nest.obj']['nest.z'] = np.array([9.61001155, 1.78448534]) J = prob.calc_gradient(indep_list, unknown_list, mode='fwd', return_format='dict') for key1, val1 in Jbase.items(): for key2, val2 in val1.items(): assert_rel_error(self, J[key1][key2], val2, .00001) J = prob.calc_gradient(indep_list, unknown_list, mode='rev', return_format='dict') for key1, val1 in Jbase.items(): for key2, val2 in val1.items(): assert_rel_error(self, J[key1][key2], val2, .00001)
def test_generate_numpydocstring(self): prob = Problem() prob.root = SellarStateConnection() prob.driver = ScipyOptimizer() prob.driver.options['optimizer'] = 'SLSQP' prob.driver.options['tol'] = 1.0e-8 prob.driver.add_desvar('z', lower=np.array([-10.0]), upper=np.array([10.0]), indices=[0]) prob.driver.add_desvar('x', lower=0.0, upper=10.0) prob.driver.add_objective('obj') prob.driver.add_constraint('con1', upper=0.0) prob.driver.add_constraint('con2', upper=0.0) prob.driver.options['disp'] = False test_string = prob.driver.generate_docstring() original_string = \ """ \"\"\" Options ------- options['disp'] : bool(False) Set to False to prevent printing of Scipy convergence messages options['maxiter'] : int(200) Maximum number of iterations. options['optimizer'] : str('SLSQP') Name of optimizer to use options['tol'] : float(1e-08) Tolerance for termination. For detailed control, use solver-specific options. \"\"\" """ for sorig, stest in zip(original_string.split('\n'), test_string.split('\n')): self.assertEqual(sorig, stest)
def test_iprint(self): top = Problem() top.root = SellarStateConnection() # Can't do it before setup anymore. with self.assertRaises(RuntimeError) as err: top.print_all_convergence() expected_msg = "Please run setup before calling print_all_convergence." self.assertEqual(str(err.exception), expected_msg) top.setup(check=False) base_stdout = sys.stdout try: ostream = cStringIO() sys.stdout = ostream top.run() finally: sys.stdout = base_stdout printed = ostream.getvalue() self.assertEqual(printed, '') # Turn on all iprints top.print_all_convergence() try: ostream = cStringIO() sys.stdout = ostream top.run() finally: sys.stdout = base_stdout printed = ostream.getvalue() self.assertEqual(printed.count('NEWTON'), 3) self.assertEqual(printed.count('GMRES'), 4) self.assertTrue('[root] NL: NEWTON 0 | ' in printed) self.assertTrue(' [root.sub] LN: GMRES 1 | ' in printed) # Now, test out level = 1 top = Problem() top.root = SellarStateConnection() top.setup(check=False) base_stdout = sys.stdout top.print_all_convergence(level=1) try: ostream = cStringIO() sys.stdout = ostream top.run() finally: sys.stdout = base_stdout printed = ostream.getvalue() self.assertEqual(printed.count('NEWTON'), 2) self.assertEqual(printed.count('GMRES'), 4) self.assertTrue('[root] NL: NEWTON 0 | ' not in printed) self.assertTrue(' [root.sub] LN: GMRES 1 | ' not in printed) # Level -1 suppresses it all top = Problem() top.root = SellarStateConnection() top.setup(check=False) base_stdout = sys.stdout top.print_all_convergence(level=-1) try: ostream = cStringIO() sys.stdout = ostream top.run() finally: sys.stdout = base_stdout printed = ostream.getvalue() self.assertEqual(printed, '') # Lets just look at the top top = Problem() top.root = SellarStateConnection() top.setup(check=False) base_stdout = sys.stdout top.print_all_convergence(depth=0) try: ostream = cStringIO() sys.stdout = ostream top.run() finally: sys.stdout = base_stdout printed = ostream.getvalue() self.assertTrue('root' in printed) self.assertTrue('root.sub' not in printed)