def test_opt_over_doe_uq(self): np.random.seed(42) prob = Problem(impl=impl, root=Group()) prob.root.deriv_options['type'] = 'fd' subprob = Problem(impl=impl, root=SellarDerivatives()) subprob.root.deriv_options['type'] = 'fd' if MPI: npardoe = self.N_PROCS else: npardoe = 1 subprob.driver = UQTestDriver(nsamples=100, num_par_doe=npardoe) subprob.driver.add_desvar('z', std_dev=1e-2) subprob.driver.add_desvar('x', std_dev=1e-2) subprob.driver.add_response('obj') subprob.driver.add_response('con1') subprob.driver.add_response('con2') #subprob.driver.recorders.append(SqliteRecorder("subsellar.db")) prob.root.add("indeps", IndepVarComp([('x', 1.0), ('z', np.array([5.0, 2.0]))]), promotes=['x', 'z']) prob.root.add("sub", SubProblem(subprob, params=['z','x'], unknowns=['obj', 'con1', 'con2'])) prob.root.connect('x', 'sub.x') prob.root.connect('z', 'sub.z') # top level driver setup prob.driver = ScipyOptimizer() prob.driver.options['optimizer'] = 'SLSQP' prob.driver.options['tol'] = 1.0e-8 prob.driver.options['maxiter'] = 50 prob.driver.options['disp'] = False 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('sub.obj') prob.driver.add_constraint('sub.con1', upper=0.0) prob.driver.add_constraint('sub.con2', upper=0.0) #prob.driver.recorders.append(SqliteRecorder("sellar.db")) prob.setup(check=False) prob.run() tol = 1.e-3 assert_rel_error(self, prob['sub.obj'], 3.1833940, tol) assert_rel_error(self, prob['z'][0], 1.977639, tol) assert_rel_error(self, prob['z'][1], 0.0, tol) assert_rel_error(self, prob['x'], 0.0, tol)
def test_root_derivs_array(self): prob = Problem() prob.root = SellarDerivativesGrouped() 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, 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.add_recorder(self.recorder) self.recorder.options['record_metadata'] = False self.recorder.options['record_derivs'] = True prob.setup(check=False) prob.run() prob.cleanup() sout = open(self.filename) lines = sout.readlines() self.assertEqual(lines[12].rstrip(), 'Derivatives:') self.assertTrue('9.61' in lines[13]) self.assertTrue('0.784' in lines[14]) self.assertTrue('1.077' in lines[15])
def test_pbo_desvar_slsqp_scipy(self): top = Problem() root = top.root = Group() root.add('p1', IndepVarComp('x', u'var_x', pass_by_obj=True)) root.add('p2', IndepVarComp('y', -4.0)) root.add('p', PassByObjParaboloid()) root.connect('p1.x', 'p.x') root.connect('p2.y', 'p.y') top.driver = ScipyOptimizer() top.driver.options['optimizer'] = 'SLSQP' top.driver.add_desvar('p1.x') top.driver.add_desvar('p2.y') top.driver.add_objective('p.f_xy') try: top.setup(check=False) except Exception as err: self.assertEqual(str(err), "Parameter 'p1.x' is a 'pass_by_obj' variable and " "can't be used with a gradient based driver of type 'SLSQP'.") else: self.fail("Exception expected")
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_driver_records_unknown_types_metadata(self): prob = Problem() root = prob.root = Group() # Need an optimization problem to test to make sure # the is_desvar, is_con, is_obj metadata is being # recorded for the Unknowns root.add('p1', IndepVarComp('x', 50.0)) root.add('p2', IndepVarComp('y', 50.0)) root.add('comp', Paraboloid()) root.connect('p1.x', 'comp.x') root.connect('p2.y', 'comp.y') prob.driver = ScipyOptimizer() prob.driver.options['optimizer'] = 'SLSQP' prob.driver.add_desvar('p1.x', lower=-50.0, upper=50.0) prob.driver.add_desvar('p2.y', lower=-50.0, upper=50.0) prob.driver.add_objective('comp.f_xy') prob.driver.options['disp'] = False prob.driver.add_recorder(self.recorder) self.recorder.options['record_metadata'] = True prob.setup(check=False) prob.cleanup() # close recorders expected_params = list(iteritems(prob.root.params)) expected_unknowns = list(iteritems(prob.root.unknowns)) expected_resids = list(iteritems(prob.root.resids)) self.assertMetadataRecorded((expected_params, expected_unknowns, expected_resids))
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_beam_tutorial_viewtree(self): top = Problem() top.root = BeamTutorial() top.driver = ScipyOptimizer() top.driver.options['optimizer'] = 'SLSQP' top.driver.options['tol'] = 1.0e-8 top.driver.options['maxiter'] = 10000 #maximum number of solver iterations top.driver.options['disp'] = False #room length and width bounds top.driver.add_desvar('ivc_rlength.room_length', lower=5.0*12.0, upper=50.0*12.0) #domain: 1in <= length <= 50ft top.driver.add_desvar('ivc_rwidth.room_width', lower=5.0*12.0, upper=30.0*12.0) #domain: 1in <= width <= 30ft top.driver.add_objective('d_neg_area.neg_room_area') #minimize negative area (or maximize area) top.driver.add_constraint('d_len_minus_wid.length_minus_width', lower=0.0) #room_length >= room_width top.driver.add_constraint('d_deflection.deflection', lower=720.0) #deflection >= 720 top.driver.add_constraint('d_bending.bending_stress_ratio', upper=0.5) #bending < 0.5 top.driver.add_constraint('d_shear.shear_stress_ratio', upper=1.0/3.0) #shear < 1/3 top.setup(check=False) from openmdao.api import view_tree view_tree(top, show_browser=False) import os.path self.assertTrue(os.path.isfile('partition_tree_n2.html')) os.remove('partition_tree_n2.html')
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): """ 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_unconstrainted(self): from openmdao.api import Problem, ScipyOptimizeDriver, IndepVarComp # We'll use the component that was defined in the last tutorial from openmdao.test_suite.components.paraboloid import Paraboloid # build the model prob = Problem() indeps = prob.model.add_subsystem('indeps', IndepVarComp()) indeps.add_output('x', 3.0) indeps.add_output('y', -4.0) prob.model.add_subsystem('paraboloid', Paraboloid()) prob.model.connect('indeps.x', 'paraboloid.x') prob.model.connect('indeps.y', 'paraboloid.y') # setup the optimization prob.driver = ScipyOptimizeDriver() prob.driver.options['optimizer'] = 'COBYLA' prob.model.add_design_var('indeps.x', lower=-50, upper=50) prob.model.add_design_var('indeps.y', lower=-50, upper=50) prob.model.add_objective('paraboloid.f_xy') prob.setup() prob.run_driver() # minimum value assert_rel_error(self, prob['paraboloid.f_xy'], -27.33333, 1e-6) # location of the minimum assert_rel_error(self, prob['indeps.x'], 6.6667, 1e-4) assert_rel_error(self, prob['indeps.y'], -7.33333, 1e-4)
def test_optimize_derivs(self): from openmdao.api import Problem, IndepVarComp from openmdao.api import ScipyOptimizeDriver from openmdao.components.tests.test_external_code_comp import ParaboloidExternalCodeCompDerivs prob = Problem() model = prob.model # create and connect inputs model.add_subsystem('p1', IndepVarComp('x', 3.0)) model.add_subsystem('p2', IndepVarComp('y', -4.0)) model.add_subsystem('p', ParaboloidExternalCodeCompDerivs()) model.connect('p1.x', 'p.x') model.connect('p2.y', 'p.y') # find optimal solution with SciPy optimize # solution (minimum): x = 6.6667; y = -7.3333 prob.driver = ScipyOptimizeDriver() prob.driver.options['optimizer'] = 'SLSQP' prob.model.add_design_var('p1.x', lower=-50, upper=50) prob.model.add_design_var('p2.y', lower=-50, upper=50) prob.model.add_objective('p.f_xy') prob.driver.options['tol'] = 1e-9 prob.driver.options['disp'] = True prob.setup() prob.run_driver() assert_rel_error(self, prob['p1.x'], 6.66666667, 1e-6) assert_rel_error(self, prob['p2.y'], -7.3333333, 1e-6)
def test_load_balanced_doe(self): problem = Problem(impl=impl) root = problem.root = Group() root.add('indep_var', IndepVarComp('x', val=1.0)) root.add('const', IndepVarComp('c', val=2.0)) root.add('mult', ExecComp4Test("y=c*x")) root.connect('indep_var.x', 'mult.x') root.connect('const.c', 'mult.c') num_levels = 25 problem.driver = FullFactorialDriver(num_levels=num_levels, num_par_doe=self.N_PROCS, load_balance=True) problem.driver.add_desvar('indep_var.x', lower=1.0, upper=float(num_levels)) problem.driver.add_objective('mult.y') problem.driver.add_recorder(InMemoryRecorder()) problem.setup(check=False) problem.run() for data in problem.driver.recorders[0].iters: self.assertEqual(data['unknowns']['indep_var.x']*2.0, data['unknowns']['mult.y']) num_cases = len(problem.driver.recorders[0].iters) if MPI: lens = problem.comm.allgather(num_cases) self.assertEqual(sum(lens), num_levels) else: self.assertEqual(num_cases, num_levels)
def test_sellar_opt(self): from openmdao.api import Problem, ScipyOptimizeDriver, ExecComp, IndepVarComp, DirectSolver from openmdao.test_suite.components.sellar_feature import SellarMDA prob = Problem() prob.model = SellarMDA() prob.driver = ScipyOptimizeDriver() prob.driver.options['optimizer'] = 'SLSQP' # prob.driver.options['maxiter'] = 100 prob.driver.options['tol'] = 1e-8 prob.model.add_design_var('x', lower=0, upper=10) prob.model.add_design_var('z', lower=0, upper=10) prob.model.add_objective('obj') prob.model.add_constraint('con1', upper=0) prob.model.add_constraint('con2', upper=0) prob.setup() prob.set_solver_print(level=0) # Ask OpenMDAO to finite-difference across the model to compute the gradients for the optimizer prob.model.approx_totals() prob.run_driver() print('minimum found at') assert_rel_error(self, prob['x'][0], 0., 1e-5) assert_rel_error(self, prob['z'], [1.977639, 0.], 1e-5) print('minumum objective') assert_rel_error(self, prob['obj'][0], 3.18339395045, 1e-5)
def test_sellar_sand_architecture(self): top = Problem() top.root = SellarSAND() top.driver = ScipyOptimizer() top.driver.options['optimizer'] = 'SLSQP' top.driver.options['tol'] = 1.0e-12 top.driver.options['disp'] = False top.driver.add_desvar('z', lower=np.array([-10.0, 0.0]), upper=np.array([10.0, 10.0])) top.driver.add_desvar('x', lower=0.0, upper=10.0) top.driver.add_desvar('y1', lower=-10.0, upper=10.0) top.driver.add_desvar('y2', lower=-10.0, upper=10.0) top.driver.add_objective('obj') top.driver.add_constraint('con1', upper=0.0) top.driver.add_constraint('con2', upper=0.0) top.driver.add_constraint('resid1', equals=0.0) top.driver.add_constraint('resid2', equals=0.0) top.setup(check=False) top.run() assert_rel_error(self, top['z'][0], 1.9776, 1e-3) assert_rel_error(self, top['z'][1], 0.0000, 1e-3) assert_rel_error(self, top['x'], 0.0000, 1e-3) assert_rel_error(self, top['d1.y1'], 3.1600, 1e-3) assert_rel_error(self, top['d1.y2'], 3.7553, 1e-3) assert_rel_error(self, top['obj'], 3.1834, 1e-3)
def test_paraboloid_optimize_unconstrained(self): top = Problem() root = top.root = Group() root.add('p1', IndepVarComp('x', 3.0)) root.add('p2', IndepVarComp('y', -4.0)) root.add('p', ParaboloidOptUnCon()) root.connect('p1.x', 'p.x') root.connect('p2.y', 'p.y') top.driver = ScipyOptimizer() top.driver.options['optimizer'] = 'SLSQP' top.driver.options['disp'] = False top.driver.add_desvar('p1.x', lower=-50, upper=50) top.driver.add_desvar('p2.y', lower=-50, upper=50) top.driver.add_objective('p.f_xy') top.setup(check=False) top.run() assert_rel_error(self, top['p.x'], 6.666667, 1e-6) assert_rel_error(self, top['p.y'], -7.333333, 1e-6)
def test_beam_tutorial(self): top = Problem() top.root = BeamTutorial() top.driver = ScipyOptimizer() top.driver.options['optimizer'] = 'SLSQP' top.driver.options['tol'] = 1.0e-8 top.driver.options['maxiter'] = 10000 #maximum number of solver iterations top.driver.options['disp'] = False #room length and width bounds top.driver.add_desvar('ivc_rlength.room_length', lower=5.0*12.0, upper=50.0*12.0) #domain: 1in <= length <= 50ft top.driver.add_desvar('ivc_rwidth.room_width', lower=5.0*12.0, upper=30.0*12.0) #domain: 1in <= width <= 30ft top.driver.add_objective('d_neg_area.neg_room_area') #minimize negative area (or maximize area) top.driver.add_constraint('d_len_minus_wid.length_minus_width', lower=0.0) #room_length >= room_width top.driver.add_constraint('d_deflection.deflection', lower=720.0) #deflection >= 720 top.driver.add_constraint('d_bending.bending_stress_ratio', upper=0.5) #bending < 0.5 top.driver.add_constraint('d_shear.shear_stress_ratio', upper=1.0/3.0) #shear < 1/3 top.setup(check=False) top.run() assert_rel_error(self, -top['d_neg_area.neg_room_area'], 51655.257618, .01) assert_rel_error(self, top['ivc_rwidth.room_width'], 227.277956, .01) assert_rel_error(self,top['ivc_rlength.room_length'], 227.277904, .01) assert_rel_error(self,top['d_deflection.deflection'], 720, .01) assert_rel_error(self,top['d_bending.bending_stress_ratio'], 0.148863, .001) assert_rel_error(self,top['d_shear.shear_stress_ratio'], 0.007985, .0001)
def test_sellar_state_connection(self): top = Problem() top.root = SellarStateConnection() top.driver = ScipyOptimizer() top.driver.options['optimizer'] = 'SLSQP' top.driver.options['tol'] = 1.0e-8 top.driver.options['disp'] = False top.driver.add_desvar('z', lower=np.array([-10.0, 0.0]), upper=np.array([10.0, 10.0])) top.driver.add_desvar('x', lower=0.0, upper=10.0) top.driver.add_objective('obj') top.driver.add_constraint('con1', upper=0.0) top.driver.add_constraint('con2', upper=0.0) top.setup(check=False) top.run() assert_rel_error(self, top['z'][0], 1.977639, 1e-5) assert_rel_error(self, top['z'][1], 0.0, 1e-5) assert_rel_error(self, top['x'], 0.0, 1e-5) assert_rel_error(self, top['obj'], 3.1833940, 1e-5)
def test_simple_paraboloid_lower(self): prob = Problem() root = prob.root = Group() root.add('p1', IndepVarComp('x', 50.0), promotes=['*']) root.add('p2', IndepVarComp('y', 50.0), promotes=['*']) root.add('comp', Paraboloid(), promotes=['*']) root.add('con', ExecComp('c = x - y'), promotes=['*']) prob.driver = pyOptSparseDriver() prob.driver.options['optimizer'] = OPTIMIZER if OPTIMIZER == 'SLSQP': prob.driver.opt_settings['ACC'] = 1e-9 prob.driver.options['print_results'] = False prob.driver.add_desvar('x', lower=-50.0, upper=50.0) prob.driver.add_desvar('y', lower=-50.0, upper=50.0) prob.driver.add_objective('f_xy') prob.driver.add_constraint('c', lower=15.0) prob.setup(check=False) prob.run() # Minimum should be at (7.166667, -7.833334) assert_rel_error(self, prob['x'], 7.16667, 1e-6) assert_rel_error(self, prob['y'], -7.833334, 1e-6)
def test_root_derivs_dict(self): if OPT is None: raise unittest.SkipTest("pyoptsparse is not installed") if OPTIMIZER is None: raise unittest.SkipTest("pyoptsparse is not providing SNOPT or SLSQP") prob = Problem() prob.root = SellarDerivativesGrouped() prob.driver = pyOptSparseDriver() prob.driver.options['optimizer'] = 'SLSQP' prob.driver.opt_settings['ACC'] = 1e-9 prob.driver.options['print_results'] = False 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.add_recorder(self.recorder) self.recorder.options['record_metadata'] = False self.recorder.options['record_derivs'] = True prob.setup(check=False) prob.run() prob.cleanup() self.io.seek(0) csv_reader = csv.DictReader(self.io) rows = [row for row in csv_reader] # execution row = rows[0] self.assertEqual(row['Derivatives'], '') # derivatives row = rows[1] self.assertEqual(row['obj'], '') J1 = eval(row['Derivatives'])[0] Jbase = {} Jbase['con1'] = {} Jbase['con1']['x'] = -0.98061433 Jbase['con1']['z'] = np.array([-9.61002285, -0.78449158]) Jbase['con2'] = {} Jbase['con2']['x'] = 0.09692762 Jbase['con2']['z'] = np.array([1.94989079, 1.0775421 ]) Jbase['obj'] = {} Jbase['obj']['x'] = 2.98061392 Jbase['obj']['z'] = np.array([9.61001155, 1.78448534]) for key1, val1 in Jbase.items(): for key2, val2 in val1.items(): assert_rel_error(self, J1[key1][key2], val2, .00001)
def test_simple_paraboloid_scaled_objective_rev(self): prob = Problem() root = prob.root = Group() root.add('p1', IndepVarComp('x', 50.0), promotes=['*']) root.add('p2', IndepVarComp('y', 50.0), promotes=['*']) root.add('comp', Paraboloid(), promotes=['*']) root.add('con', ExecComp('c = x - y'), promotes=['*']) prob.driver = pyOptSparseDriver() prob.driver.options['optimizer'] = OPTIMIZER if OPTIMIZER == 'SNOPT': prob.driver.opt_settings['Verify level'] = 3 prob.driver.options['print_results'] = False prob.driver.add_desvar('x', lower=-50.0, upper=50.0) prob.driver.add_desvar('y', lower=-50.0, upper=50.0) prob.driver.add_objective('f_xy', scaler=1/10.) prob.driver.add_constraint('c', lower=10.0, upper=11.0) root.ln_solver.options['mode'] = 'rev' prob.setup(check=False) prob.run() # Minimum should be at (7.166667, -7.833334) assert_rel_error(self, prob['x'] - prob['y'], 11.0, 1e-6)
def test_inf_as_desvar_bounds(self): # User may use np.inf as a bound. It is unneccessary, but the user # may do it anyway, so make sure SLSQP doesn't blow up with it (bug # reported by rfalck) prob = Problem() root = prob.root = Group() root.add('p1', IndepVarComp('x', 50.0), promotes=['*']) root.add('p2', IndepVarComp('y', 50.0), promotes=['*']) root.add('comp', Paraboloid(), promotes=['*']) root.add('con', ExecComp('c = - x + y'), promotes=['*']) prob.driver = pyOptSparseDriver() prob.driver.options['optimizer'] = 'SLSQP' prob.driver.opt_settings['ACC'] = 1e-9 prob.driver.options['print_results'] = False prob.driver.add_desvar('x', lower=-np.inf, upper=np.inf) prob.driver.add_desvar('y', lower=-50.0, upper=50.0) prob.driver.add_objective('f_xy') prob.driver.add_constraint('c', upper=-15.0) prob.setup(check=False) prob.run() # Minimum should be at (7.166667, -7.833334) assert_rel_error(self, prob['x'], 7.16667, 1e-6) assert_rel_error(self, prob['y'], -7.833334, 1e-6)
def test(self): import numpy as np from openmdao.api import Problem, ScipyOptimizeDriver from openmdao.test_suite.test_examples.beam_optimization.beam_group import BeamGroup E = 1. L = 1. b = 0.1 volume = 0.01 num_elements = 50 prob = Problem(model=BeamGroup(E=E, L=L, b=b, volume=volume, num_elements=num_elements)) prob.driver = ScipyOptimizeDriver() prob.driver.options['optimizer'] = 'SLSQP' prob.driver.options['tol'] = 1e-9 prob.driver.options['disp'] = True prob.setup() prob.run_driver() print(prob['inputs_comp.h'])
def test_undefined_jacobian(self): prob = Problem(root=Group()) root = prob.root root.add(name="ivc_a", system=IndepVarComp(name="a", val=5.0), promotes=["a"]) root.add(name="ivc_b", system=IndepVarComp(name="b", val=10.0), promotes=["b"]) root.add(name="g", system=MyGroup3()) root.connect("a", "g.input.A") root.connect("b", "g.input.B") prob.driver = ScipyOptimizer() prob.driver.options["disp"] = False prob.driver.add_objective("g.exec.y") prob.driver.add_desvar(name="a") prob.driver.add_desvar(name="b") prob.setup(check=False) try: prob.run() except ValueError as err: self.assertEqual(str(err), "No derivatives defined for Component 'g.input'") else: self.fail("expecting ValueError due to undefined linearize")
def test_case_driver(self): problem = Problem() root = problem.root = Group() root.add("indep_var", IndepVarComp("x", val=1.0)) root.add("const", IndepVarComp("c", val=2.0)) root.add("mult", ExecComp4Test("y=c*x")) root.connect("indep_var.x", "mult.x") root.connect("const.c", "mult.c") cases = [ [("indep_var.x", 3.0), ("const.c", 1.5)], [("indep_var.x", 4.0), ("const.c", 2.0)], [("indep_var.x", 5.5), ("const.c", 3.0)], ] problem.driver = CaseDriver(cases) problem.driver.add_desvar("indep_var.x") problem.driver.add_desvar("const.c") problem.driver.add_recorder(InMemoryRecorder()) problem.setup(check=False) problem.run() for i, data in enumerate(problem.driver.recorders[0].iters): data["unknowns"] = dict(data["unknowns"]) self.assertEqual(data["unknowns"]["indep_var.x"] * data["unknowns"]["const.c"], data["unknowns"]["mult.y"]) self.assertEqual(cases[i][0][1] * cases[i][1][1], data["unknowns"]["mult.y"]) self.assertEqual(len(problem.driver.recorders[0].iters), 3)
def test_tldr(self): from openmdao.api import Problem, ScipyOptimizeDriver, ExecComp, IndepVarComp # build the model prob = Problem() indeps = prob.model.add_subsystem('indeps', IndepVarComp()) indeps.add_output('x', 3.0) indeps.add_output('y', -4.0) prob.model.add_subsystem('paraboloid', ExecComp('f = (x-3)**2 + x*y + (y+4)**2 - 3')) prob.model.connect('indeps.x', 'paraboloid.x') prob.model.connect('indeps.y', 'paraboloid.y') # setup the optimization prob.driver = ScipyOptimizeDriver() prob.driver.options['optimizer'] = 'SLSQP' prob.model.add_design_var('indeps.x', lower=-50, upper=50) prob.model.add_design_var('indeps.y', lower=-50, upper=50) prob.model.add_objective('paraboloid.f') prob.setup() prob.run_driver() # minimum value assert_rel_error(self, prob['paraboloid.f'], -27.33333, 1e-6) # location of the minimum assert_rel_error(self, prob['indeps.x'], 6.6667, 1e-4) assert_rel_error(self, prob['indeps.y'], -7.33333, 1e-4)
def test_index_error_messages_con(self): prob = Problem() prob.root = Group() prob.root.fd_options['force_fd'] = True prob.root.ln_solver.options['mode'] = 'auto' prob.root.add('myparams', IndepVarComp('x', np.zeros(4))) prob.root.add('rosen', Rosenbrock(4)) prob.root.connect('myparams.x', 'rosen.x') prob.driver = MySimpleDriver() prob.driver.add_desvar('myparams.x') prob.driver.add_constraint('rosen.xxx', upper=0.0, indices=[4]) prob.setup(check=False) # Make sure we can't do this with self.assertRaises(IndexError) as cm: prob.run() msg = "Index for constraint 'rosen.xxx' is out of bounds. " msg += "Requested index: [4], " msg += "shape: (4,)." raised_error = str(cm.exception) raised_error = raised_error.replace('(4L,', '(4,') self.assertEqual(msg, raised_error)
def test_multiproc_doe(self): problem = Problem() root = problem.root = Group() root.add('indep_var', IndepVarComp('x', val=1.0)) root.add('const', IndepVarComp('c', val=2.0)) root.add('mult', ExecComp4Test("y=c*x", nl_delay=1.0)) root.connect('indep_var.x', 'mult.x') root.connect('const.c', 'mult.c') num_levels = 25 problem.driver = FullFactorialDriver(num_levels=num_levels, num_par_doe=7, load_balance=True) problem.driver.options['auto_add_response'] = True problem.driver.add_desvar('indep_var.x', lower=1.0, upper=float(num_levels)) problem.driver.add_objective('mult.y') problem.setup(check=False) problem.run() num_cases = 0 for responses, success, msg in problem.driver.get_responses(): responses = dict(responses) num_cases += 1 self.assertEqual(responses['indep_var.x']*2.0, responses['mult.y']) self.assertEqual(num_cases, num_levels)
def test_empty_jacobian(self): prob = Problem(root=Group()) root = prob.root root.add(name="ivc_a", system=IndepVarComp(name="a", val=5.0), promotes=["a"]) root.add(name="ivc_b", system=IndepVarComp(name="b", val=10.0), promotes=["b"]) root.add(name="g", system=MyGroup()) root.connect("a", "g.input.A") root.connect("b", "g.input.B") prob.driver = ScipyOptimizer() prob.driver.options["disp"] = False prob.driver.add_objective("g.exec.y") prob.driver.add_desvar(name="a") prob.driver.add_desvar(name="b") prob.setup(check=False) prob.run()
def test_simple_paraboloid_scaled_constraint_rev(self): prob = Problem() root = prob.root = Group() root.add('p1', IndepVarComp('x', 50.0), promotes=['*']) root.add('p2', IndepVarComp('y', 50.0), promotes=['*']) root.add('comp', Paraboloid(), promotes=['*']) root.add('con', ExecComp('c = x - y'), promotes=['*']) prob.driver = ScipyOptimizer() prob.driver.options['optimizer'] = 'SLSQP' prob.driver.options['tol'] = 1.0e-8 prob.driver.options['disp'] = False prob.driver.add_desvar('x', lower=-50.0, upper=50.0) prob.driver.add_desvar('y', lower=-50.0, upper=50.0) prob.driver.add_objective('f_xy') prob.driver.add_constraint('c', lower=10.0, upper=11.0, scaler=1/10.) root.ln_solver.options['mode'] = 'rev' prob.setup(check=False) prob.run() # Minimum should be at (7.166667, -7.833334) assert_rel_error(self, prob['x'] - prob['y'], 11.0, 1e-6)
def test_simple_paraboloid_equality_linear(self): prob = Problem() root = prob.root = Group() root.add('p1', IndepVarComp('x', 50.0), promotes=['*']) root.add('p2', IndepVarComp('y', 50.0), promotes=['*']) root.add('comp', Paraboloid(), promotes=['*']) root.add('con', ExecComp('c = - x + y'), promotes=['*']) prob.driver = pyOptSparseDriver() prob.driver.options['optimizer'] = OPTIMIZER if OPTIMIZER == 'SLSQP': prob.driver.opt_settings['ACC'] = 1e-9 prob.driver.options['print_results'] = False prob.driver.add_desvar('x', lower=-50.0, upper=50.0) prob.driver.add_desvar('y', lower=-50.0, upper=50.0) prob.driver.add_objective('f_xy') prob.driver.add_constraint('c', equals=-15.0, linear=True) if OPTIMIZER == 'SNOPT': # there is currently a bug in SNOPT, it requires at least one # nonlinear inequality constraint, so provide a 'fake' one prob.driver.add_constraint('x', lower=-100.0) prob.setup(check=False) prob.run() # Minimum should be at (7.166667, -7.833334) assert_rel_error(self, prob['x'], 7.16667, 1e-6) assert_rel_error(self, prob['y'], -7.833334, 1e-6)
def test(self): """ This is an opt problem that tests the wingbox model with wave drag and the fuel vol constraint """ # Create a dictionary to store options about the surface mesh_dict = { 'num_y': 7, 'num_x': 2, 'wing_type': 'CRM', 'symmetry': True, 'num_twist_cp': 6, 'chord_cos_spacing': 0, 'span_cos_spacing': 0, } mesh, twist_cp = generate_mesh(mesh_dict) surf_dict = { # Wing definition 'name': 'wing', # name of the surface 'symmetry': True, # if true, model one half of wing # reflected across the plane y = 0 'S_ref_type': 'wetted', # how we compute the wing area, # can be 'wetted' or 'projected' 'fem_model_type': 'wingbox', 'spar_thickness_cp': np.array([0.004, 0.005, 0.005, 0.008, 0.008, 0.01]), # [m] 'skin_thickness_cp': np.array([0.005, 0.01, 0.015, 0.020, 0.025, 0.026]), 'twist_cp': np.array([4., 5., 8., 8., 8., 9.]), 'mesh': mesh, 'data_x_upper': upper_x, 'data_x_lower': lower_x, 'data_y_upper': upper_y, 'data_y_lower': lower_y, 'strength_factor_for_upper_skin': 1., # Aerodynamic performance of the lifting surface at # an angle of attack of 0 (alpha=0). # These CL0 and CD0 values are added to the CL and CD # obtained from aerodynamic analysis of the surface to get # the total CL and CD. # These CL0 and CD0 values do not vary wrt alpha. 'CL0': 0.0, # CL of the surface at alpha=0 'CD0': 0.0078, # CD of the surface at alpha=0 # Airfoil properties for viscous drag calculation 'k_lam': 0.05, # percentage of chord with laminar # flow, used for viscous drag 't_over_c_cp': np.array([0.08, 0.08, 0.08, 0.10, 0.10, 0.08]), 'original_wingbox_airfoil_t_over_c': 0.12, 'c_max_t': .38, # chordwise location of maximum thickness 'with_viscous': True, 'with_wave': True, # if true, compute wave drag # Structural values are based on aluminum 7075 'E': 73.1e9, # [Pa] Young's modulus 'G': ( 73.1e9 / 2 / 1.33 ), # [Pa] shear modulus (calculated using E and the Poisson's ratio here) 'yield': (420.e6 / 1.5), # [Pa] allowable yield stress 'mrho': 2.78e3, # [kg/m^3] material density 'strength_factor_for_upper_skin': 1.0, # the yield stress is multiplied by this factor for the upper skin # 'fem_origin' : 0.35, # normalized chordwise location of the spar 'wing_weight_ratio': 1.25, 'struct_weight_relief': True, 'distributed_fuel_weight': True, # Constraints 'exact_failure_constraint': False, # if false, use KS function 'fuel_density': 803., # [kg/m^3] fuel density (only needed if the fuel-in-wing volume constraint is used) 'Wf_reserve': 15000., # [kg] reserve fuel mass } surfaces = [surf_dict] # Create the problem and assign the model group prob = Problem() # Add problem information as an independent variables component indep_var_comp = IndepVarComp() indep_var_comp.add_output('v', val=.85 * 295.07, units='m/s') indep_var_comp.add_output('alpha', val=0., units='deg') indep_var_comp.add_output('Mach_number', val=0.85) indep_var_comp.add_output('re', val=0.348 * 295.07 * .85 * 1. / (1.43 * 1e-5), units='1/m') indep_var_comp.add_output('rho', val=0.348, units='kg/m**3') indep_var_comp.add_output('CT', val=0.53 / 3600, units='1/s') indep_var_comp.add_output('R', val=14.307e6, units='m') indep_var_comp.add_output('W0', val=148000 + surf_dict['Wf_reserve'], units='kg') indep_var_comp.add_output('speed_of_sound', val=295.07, units='m/s') indep_var_comp.add_output('load_factor', val=1.) indep_var_comp.add_output('empty_cg', val=np.zeros((3)), units='m') indep_var_comp.add_output('fuel_mass', val=10000., units='kg') prob.model.add_subsystem('prob_vars', indep_var_comp, promotes=['*']) # Loop over each surface in the surfaces list for surface in surfaces: # Get the surface name and create a group to contain components # only for this surface name = surface['name'] aerostruct_group = AerostructGeometry(surface=surface) # Add tmp_group to the problem with the name of the surface. prob.model.add_subsystem(name, aerostruct_group) # Loop through and add a certain number of aero points for i in range(1): point_name = 'AS_point_{}'.format(i) # Connect the parameters within the model for each aero point # Create the aero point group and add it to the model AS_point = AerostructPoint(surfaces=surfaces) prob.model.add_subsystem(point_name, AS_point) # Connect flow properties to the analysis point prob.model.connect('v', point_name + '.v') prob.model.connect('alpha', point_name + '.alpha') prob.model.connect('Mach_number', point_name + '.Mach_number') prob.model.connect('re', point_name + '.re') prob.model.connect('rho', point_name + '.rho') prob.model.connect('CT', point_name + '.CT') prob.model.connect('R', point_name + '.R') prob.model.connect('W0', point_name + '.W0') prob.model.connect('speed_of_sound', point_name + '.speed_of_sound') prob.model.connect('empty_cg', point_name + '.empty_cg') prob.model.connect('load_factor', point_name + '.load_factor') for surface in surfaces: prob.model.connect('load_factor', name + '.load_factor') prob.model.connect('load_factor', point_name + '.coupled.load_factor') com_name = point_name + '.' + name + '_perf.' prob.model.connect(name + '.K', point_name + '.coupled.' + name + '.K') prob.model.connect(name + '.nodes', point_name + '.coupled.' + name + '.nodes') # Connect aerodyamic mesh to coupled group mesh prob.model.connect(name + '.mesh', point_name + '.coupled.' + name + '.mesh') prob.model.connect( name + '.element_weights', point_name + '.coupled.' + name + '.element_weights') # Connect performance calculation variables prob.model.connect(name + '.nodes', com_name + 'nodes') prob.model.connect( name + '.cg_location', point_name + '.' + 'total_perf.' + name + '_cg_location') prob.model.connect( name + '.structural_weight', point_name + '.' + 'total_perf.' + name + '_structural_weight') # Connect wingbox properties to von Mises stress calcs prob.model.connect(name + '.Qz', com_name + 'Qz') prob.model.connect(name + '.Iz', com_name + 'Iz') prob.model.connect(name + '.J', com_name + 'J') prob.model.connect(name + '.A_enc', com_name + 'A_enc') prob.model.connect(name + '.htop', com_name + 'htop') prob.model.connect(name + '.hbottom', com_name + 'hbottom') prob.model.connect(name + '.hfront', com_name + 'hfront') prob.model.connect(name + '.hrear', com_name + 'hrear') prob.model.connect(name + '.spar_thickness', com_name + 'spar_thickness') prob.model.connect(name + '.skin_thickness', com_name + 'skin_thickness') prob.model.connect(name + '.t_over_c', com_name + 't_over_c') #======================================================================================= # Here we add the fuel volume constraint componenet to the model #======================================================================================= prob.model.add_subsystem('fuel_vol_delta', WingboxFuelVolDelta(surface=surface)) prob.model.connect('AS_point_0.fuelburn', 'fuel_vol_delta.fuelburn') prob.model.connect('wing.struct_setup.fuel_vols', 'fuel_vol_delta.fuel_vols') prob.model.connect( 'wing.struct_setup.fuel_vols', 'AS_point_0.coupled.wing.struct_states.fuel_vols') prob.model.connect( 'fuel_mass', 'AS_point_0.coupled.wing.struct_states.fuel_mass') comp = ExecComp('fuel_diff = (fuel_mass - fuelburn) / fuelburn', fuel_mass={ 'value': 1.0, 'units': 'kg' }, fuelburn={ 'value': 1.0, 'units': 'kg' }) prob.model.add_subsystem('fuel_diff', comp, promotes_inputs=['fuel_mass'], promotes_outputs=['fuel_diff']) prob.model.connect('AS_point_0.fuelburn', 'fuel_diff.fuelburn') #======================================================================================= #======================================================================================= from openmdao.api import ScipyOptimizeDriver prob.driver = ScipyOptimizeDriver() prob.driver.options['tol'] = 1e-9 prob.driver.options['maxiter'] = 2 # from openmdao.api import pyOptSparseDriver # prob.driver = pyOptSparseDriver() # prob.driver.add_recorder(SqliteRecorder("cases.sql")) # prob.driver.options['optimizer'] = "SNOPT" # prob.driver.opt_settings['Major optimality tolerance'] = 1e-6 # prob.driver.opt_settings['Major feasibility tolerance'] = 1e-8 # prob.driver.opt_settings['Major iterations limit'] = 200 prob.model.add_objective('AS_point_0.fuelburn', scaler=1e-5) prob.model.add_design_var('wing.twist_cp', lower=-15., upper=15., scaler=0.1) prob.model.add_design_var('wing.spar_thickness_cp', lower=0.003, upper=0.1, scaler=1e2) prob.model.add_design_var('wing.skin_thickness_cp', lower=0.003, upper=0.1, scaler=1e2) prob.model.add_design_var('wing.geometry.t_over_c_cp', lower=0.07, upper=0.2, scaler=10.) prob.model.add_design_var('fuel_mass', lower=0., upper=2e5, scaler=1e-5) prob.model.add_constraint('AS_point_0.CL', equals=0.5) prob.model.add_constraint('AS_point_0.wing_perf.failure', upper=0.) #======================================================================================= # Here we add the fuel volume constraint #======================================================================================= prob.model.add_constraint('fuel_vol_delta.fuel_vol_delta', lower=0.) prob.model.add_constraint('fuel_diff', equals=0.) #======================================================================================= #======================================================================================= # Set up the problem prob.setup() # from openmdao.api import view_model # view_model(prob) prob.run_model() # Check the partials at the initial point in the design space, # only care about relative error data = prob.check_partials(compact_print=True, out_stream=None, method='cs', step=1e-40) assert_check_partials(data, atol=1e20, rtol=1e-6) # Run the optimizer for 2 iterations prob.run_driver() # Check the partials at this point in the design space data = prob.check_partials(compact_print=True, out_stream=None, method='cs', step=1e-40) assert_check_partials(data, atol=1e20, rtol=1e-6)
def test_control_rate2_boundary_constraint_gl(self): p = Problem(model=Group()) p.driver = ScipyOptimizeDriver() p.driver.options['dynamic_simul_derivs'] = True phase = Phase(ode_class=BrachistochroneODE, transcription=GaussLobatto(num_segments=20, order=3, compressed=True)) p.model.add_subsystem('phase0', phase) phase.set_time_options(fix_initial=True, duration_bounds=(0.1, 10)) phase.set_state_options('x', fix_initial=True, fix_final=True) phase.set_state_options('y', fix_initial=True, fix_final=True) phase.set_state_options('v', fix_initial=True, fix_final=False) phase.add_control('theta', continuity=True, rate_continuity=True, rate2_continuity=True, units='deg', lower=0.01, upper=179.9) phase.add_design_parameter('g', units='m/s**2', opt=False, val=9.80665) phase.add_boundary_constraint('theta_rate2', loc='final', equals=0.0, units='deg/s**2') # Minimize time at the end of the phase phase.add_objective('time') p.model.linear_solver = DirectSolver() p.setup(check=True) p['phase0.t_initial'] = 0.0 p['phase0.t_duration'] = 2.0 p['phase0.states:x'] = phase.interpolate(ys=[0, 10], nodes='state_input') p['phase0.states:y'] = phase.interpolate(ys=[10, 5], nodes='state_input') p['phase0.states:v'] = phase.interpolate(ys=[0, 9.9], nodes='state_input') p['phase0.controls:theta'] = phase.interpolate(ys=[5, 100], nodes='control_input') p['phase0.design_parameters:g'] = 8 p.run_driver() plt.plot(p.get_val('phase0.timeseries.states:x'), p.get_val('phase0.timeseries.states:y'), 'ko') plt.figure() plt.plot(p.get_val('phase0.timeseries.time'), p.get_val('phase0.timeseries.controls:theta'), 'ro') plt.plot(p.get_val('phase0.timeseries.time'), p.get_val('phase0.timeseries.control_rates:theta_rate'), 'bo') plt.plot(p.get_val('phase0.timeseries.time'), p.get_val('phase0.timeseries.control_rates:theta_rate2'), 'go') plt.show() assert_rel_error( self, p.get_val('phase0.timeseries.control_rates:theta_rate2')[-1], 0, tolerance=1.0E-6)
y2=0.0), promotes=['obj', 'z', 'x', 'y1', 'y2']) self.add('con_cmp1', ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1']) self.add('con_cmp2', ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2']) if __name__ == '__main__': top = Problem() top.root = SellarSAND() top.driver = ScipyOptimizer() top.driver.options['optimizer'] = 'SLSQP' top.driver.options['tol'] = 1.0e-12 top.driver.add_desvar('z', lower=np.array([-10.0, 0.0]), upper=np.array([10.0, 10.0])) top.driver.add_desvar('x', lower=0.0, upper=10.0) top.driver.add_desvar('y1', lower=-10.0, upper=10.0) top.driver.add_desvar('y2', lower=-10.0, upper=10.0) top.driver.add_objective('obj') top.driver.add_constraint('con1', upper=0.0) top.driver.add_constraint('con2', upper=0.0) top.driver.add_constraint('resid1', equals=0.0) top.driver.add_constraint('resid2', equals=0.0)
if optimize: # --- optimizer imports --- from openmdao.api import pyOptSparseDriver # ---------------------- # --- Setup Optimizer --- N = len(z_param) prob = Problem( root=TowerSE(nPoints, nFull, nK, nMass, nPL, nDEL, wind=wind)) prob.root.add('p1', IndepVarComp('z_param', z_param)) prob.root.add('p2', IndepVarComp('d_param', d_param)) prob.root.add('p3', IndepVarComp('t_param', t_param)) prob.driver = pyOptSparseDriver() prob.driver.options['optimizer'] = 'SNOPT' prob.driver.opt_settings['Major iterations limit'] = 1000 # ---------------------- # --- Objective --- prob.driver.add_objective('tower1.mass') # ---------------------- # --- Design Variables --- prob.driver.add_desvar('p1.z_param', lower=np.ones(N) * 0.0, upper=np.ones(N) * max(z_param)) prob.driver.add_desvar('p2.d_param', lower=np.ones(N) * 3,
def setUp(self): if OPT is None: raise unittest.SkipTest("pyoptsparse is not installed") if OPTIMIZER is None: raise unittest.SkipTest( "pyoptsparse is not providing SNOPT or SLSQP") prob = Problem(impl=impl) root = prob.root = Group() #root.ln_solver = lin_solver() root.ln_solver = LinearGaussSeidel() par = root.add('par', ParallelGroup()) par.ln_solver = LinearGaussSeidel() ser1 = par.add('ser1', Group()) ser1.ln_solver = LinearGaussSeidel() ser1.add('p1', IndepVarComp('x', np.zeros([2]))) ser1.add('comp', SimpleArrayComp()) ser1.add( 'con', ExecComp('c = y - 20.0', c=np.array([0.0, 0.0]), y=np.array([0.0, 0.0]))) ser1.add('obj', ExecComp('o = y[0]', y=np.array([0.0, 0.0]))) ser2 = par.add('ser2', Group()) ser2.ln_solver = LinearGaussSeidel() ser2.add('p1', IndepVarComp('x', np.zeros([2]))) ser2.add('comp', SimpleArrayComp()) ser2.add( 'con', ExecComp('c = y - 30.0', c=np.array([0.0, 0.0]), y=np.array([0.0, 0.0]))) ser2.add('obj', ExecComp('o = y[0]', y=np.array([0.0, 0.0]))) root.add('total', ExecComp('obj = x1 + x2')) ser1.connect('p1.x', 'comp.x') ser1.connect('comp.y', 'con.y') ser1.connect('comp.y', 'obj.y') root.connect('par.ser1.obj.o', 'total.x1') ser2.connect('p1.x', 'comp.x') ser2.connect('comp.y', 'con.y') ser2.connect('comp.y', 'obj.y') root.connect('par.ser2.obj.o', 'total.x2') prob.driver = pyOptSparseDriver() prob.driver.options['optimizer'] = OPTIMIZER prob.driver.options['print_results'] = False prob.driver.add_desvar('par.ser1.p1.x', lower=-50.0, upper=50.0) prob.driver.add_desvar('par.ser2.p1.x', lower=-50.0, upper=50.0) prob.driver.add_objective('total.obj') prob.driver.add_constraint('par.ser1.con.c', equals=0.0) prob.driver.add_constraint('par.ser2.con.c', equals=0.0) self.prob = prob
prob.model.add_constraint('climb.throttle', upper=1.05 * np.ones(num_nodes)) prob.model.add_objective('fuel_burn') else: print( '======Analyzing Fuel Burn for Given Mision============' ) prob.model.add_design_var('cruise.hybridization', lower=0.01, upper=0.5) prob.model.add_constraint( 'descent.propmodel.batt1.SOC_final', lower=0.0) prob.model.add_objective('descent.fuel_used_final') prob.driver = ScipyOptimizeDriver() prob.driver.options['dynamic_simul_derivs'] = True #prob.driver.options['tol'] = 1e-13 if write_logs: filename_to_save = 'case_' + str(spec_energy) + '_' + str( design_range) + '.sql' if os.path.isfile(filename_to_save): if design_range != 300: last_successful_opt = filename_to_save else: last_successful_opt = 'case_' + str( spec_energy + 50) + '_' + str(700) + '.sql' print('Skipping ' + filename_to_save) continue recorder = SqliteRecorder(filename_to_save) prob.driver.add_recorder(recorder)
def runOpenMdao(): prob = Problem() #first guesses here indeps = prob.model.add_subsystem('indeps', IndepVarComp(), promotes=['*']) # load defaults from BPAirfoil bp = BPAirfoil() # read last optimization result if available (has to be copied here manually) if os.path.isfile(INPUT_DIR + '/' + 'airfoil.txt'): bp.read_parameters_from_file(INPUT_DIR + '/' + 'airfoil.txt') indeps.add_output('r_le', bp.r_le) indeps.add_output('beta_te', bp.beta_te) indeps.add_output('x_t', bp.x_t) indeps.add_output('gamma_le', bp.gamma_le) indeps.add_output('x_c', bp.x_c) indeps.add_output('y_c', bp.y_c) indeps.add_output('alpha_te', bp.alpha_te) #indeps.add_output('z_te', bp.z_te) indeps.add_output('b_8', bp.b_8) indeps.add_output('b_15', bp.b_15) indeps.add_output('b_0', bp.b_0) indeps.add_output('b_2', bp.b_2) indeps.add_output('b_17', bp.b_17) prob.model.add_subsystem('airfoil_cfd', AirfoilCFD()) prob.model.connect('r_le', 'airfoil_cfd.r_le') prob.model.connect('beta_te', 'airfoil_cfd.beta_te') prob.model.connect('x_t', 'airfoil_cfd.x_t') prob.model.connect('gamma_le', 'airfoil_cfd.gamma_le') prob.model.connect('x_c', 'airfoil_cfd.x_c') prob.model.connect('y_c', 'airfoil_cfd.y_c') prob.model.connect('alpha_te', 'airfoil_cfd.alpha_te') #prob.model.connect('z_te', 'airfoil_cfd.z_te') prob.model.connect('b_8', 'airfoil_cfd.b_8') prob.model.connect('b_15', 'airfoil_cfd.b_15') prob.model.connect('b_0', 'airfoil_cfd.b_0') prob.model.connect('b_2', 'airfoil_cfd.b_2') prob.model.connect('b_17', 'airfoil_cfd.b_17') # setup the optimization prob.driver = ScipyOptimizeDriver() #'Nelder-Mead', 'Powell', 'CG', 'BFGS', 'Newton-CG', 'L-BFGS-B', 'TNC', 'COBYLA', 'SLSQP'] prob.driver.options['optimizer'] = 'COBYLA' prob.driver.options['tol'] = 1e-6 prob.driver.options['maxiter'] = 100000 # setup recorder recorder = SqliteRecorder(WORKING_DIR + '/openMdaoLog.sql') 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 #limits and constraints lowerPro = 0.9 upperPro = 1.1 prob.model.add_design_var('r_le', lower=-0.1, upper=-0.015) prob.model.add_design_var('beta_te', lower=0, upper=0.3) #prob.model.add_design_var('dz_te', lower=0., upper=0.) prob.model.add_design_var('x_t', lower=0.25, upper=0.4) #prob.model.add_design_var('y_t')#, lower=0.075, upper=0.09) prob.model.add_design_var('gamma_le', lower=0.05, upper=0.4) prob.model.add_design_var('x_c', lower=0.2, upper=0.5) prob.model.add_design_var('y_c', lower=0., upper=0.04) prob.model.add_design_var('alpha_te', lower=-0.5, upper=0) #prob.model.add_design_var('z_te')#, lower=0., upper=0.) prob.model.add_design_var('b_8', lower=0.0000001, upper=0.06) prob.model.add_design_var('b_15', lower=0.2, upper=1.) prob.model.add_design_var('b_0', lower=0., upper=0.3) prob.model.add_design_var('b_2', lower=-.1, upper=0.7) prob.model.add_design_var('b_17', lower=0.7, upper=1.) prob.model.add_objective('airfoil_cfd.c_d', scaler=1) prob.model.add_constraint('airfoil_cfd.cabin_height', lower=cabinHeigth * 0.99, upper=cabinHeigth * 1.05) prob.model.add_constraint('airfoil_cfd.c_l', lower=0.145, upper=.155) prob.model.add_constraint('airfoil_cfd.c_m', lower=-0.05, upper=99.) write_to_log( 'iterations,time,c_l,c_d,c_m,CL/CD,cfdIterations,cabin_height,offsetFront,angle,r_le,beta_te,x_t,y_t,gamma_le,x_c,y_c,alpha_te,z_te,b_8,b_15,b_0,b_17,b_2]))' ) prob.setup() prob.set_solver_print(level=0) prob.model.approx_totals() prob.run_driver() print('done') print('cabin frontOffset: ' + str(prob['airfoil_cfd.offsetFront'])) print('cabin angle: ' + str(-1. * prob['airfoil_cfd.angle']) + ' deg') print('c_l= ' + str(prob['airfoil_cfd.c_l'])) print('c_d= ' + str(prob['airfoil_cfd.c_d'])) print('c_m= ' + str(prob['airfoil_cfd.c_m'])) print('execution counts airfoil cfd: ' + str(prob.model.airfoil_cfd.executionCounter))
def test(self): # Create a dictionary to store options about the surface mesh_dict = { 'num_y': 7, 'num_x': 2, 'wing_type': 'CRM', 'symmetry': False, 'num_twist_cp': 2, 'span_cos_spacing': 1. } mesh, twist_cp = generate_mesh(mesh_dict) surf_dict = { # Wing definition 'name': 'wing', # name of the surface 'symmetry': False, # if true, model one half of wing # reflected across the plane y = 0 'S_ref_type': 'wetted', # how we compute the wing area, # can be 'wetted' or 'projected' 'fem_model_type': 'tube', 'thickness_cp': np.ones(2) * 0.06836728, 'twist_cp': twist_cp, 'mesh': mesh, # Aerodynamic performance of the lifting surface at # an angle of attack of 0 (alpha=0). # These CL0 and CD0 values are added to the CL and CD # obtained from aerodynamic analysis of the surface to get # the total CL and CD. # These CL0 and CD0 values do not vary wrt alpha. 'CL0': 0.0, # CL of the surface at alpha=0 'CD0': 0.015, # CD of the surface at alpha=0 # Airfoil properties for viscous drag calculation 'k_lam': 0.05, # percentage of chord with laminar # flow, used for viscous drag 't_over_c_cp': np.array([0.12]), # thickness over chord ratio (NACA0015) 'c_max_t': .303, # chordwise location of maximum (NACA0015) # thickness 'with_viscous': True, 'with_wave': False, # if true, compute wave drag # Structural values are based on aluminum 7075 'E': 70.e9, # [Pa] Young's modulus of the spar 'G': 30.e9, # [Pa] shear modulus of the spar 'yield': 500.e6 / 2.5, # [Pa] yield stress divided by 2.5 for limiting case 'mrho': 3.e3, # [kg/m^3] material density 'fem_origin': 0.35, # normalized chordwise location of the spar 'wing_weight_ratio': 1., 'struct_weight_relief': False, # True to add the weight of the structure to the loads on the structure 'distributed_fuel_weight': False, # Constraints 'exact_failure_constraint': False, # if false, use KS function } surfaces = [surf_dict] # Create the problem and assign the model group prob = Problem() # Add problem information as an independent variables component indep_var_comp = IndepVarComp() indep_var_comp.add_output('v', val=248.136, units='m/s') indep_var_comp.add_output('alpha', val=5., units='deg') indep_var_comp.add_output('Mach_number', val=0.84) indep_var_comp.add_output('re', val=1.e6, units='1/m') indep_var_comp.add_output('rho', val=0.38, units='kg/m**3') indep_var_comp.add_output('CT', val=grav_constant * 17.e-6, units='1/s') indep_var_comp.add_output('R', val=11.165e6, units='m') indep_var_comp.add_output('W0', val=0.4 * 3e5, units='kg') indep_var_comp.add_output('speed_of_sound', val=295.4, units='m/s') indep_var_comp.add_output('load_factor', val=1.) indep_var_comp.add_output('empty_cg', val=np.zeros((3)), units='m') prob.model.add_subsystem('prob_vars', indep_var_comp, promotes=['*']) # Loop over each surface in the surfaces list for surface in surfaces: # Get the surface name and create a group to contain components # only for this surface name = surface['name'] aerostruct_group = AerostructGeometry(surface=surface) # Add tmp_group to the problem with the name of the surface. prob.model.add_subsystem(name, aerostruct_group) # Loop through and add a certain number of aero points for i in range(1): point_name = 'AS_point_{}'.format(i) # Connect the parameters within the model for each aero point # Create the aero point group and add it to the model AS_point = AerostructPoint(surfaces=surfaces) prob.model.add_subsystem(point_name, AS_point) # Connect flow properties to the analysis point prob.model.connect('v', point_name + '.v') prob.model.connect('alpha', point_name + '.alpha') prob.model.connect('Mach_number', point_name + '.Mach_number') prob.model.connect('re', point_name + '.re') prob.model.connect('rho', point_name + '.rho') prob.model.connect('CT', point_name + '.CT') prob.model.connect('R', point_name + '.R') prob.model.connect('W0', point_name + '.W0') prob.model.connect('speed_of_sound', point_name + '.speed_of_sound') prob.model.connect('empty_cg', point_name + '.empty_cg') prob.model.connect('load_factor', point_name + '.load_factor') for surface in surfaces: com_name = point_name + '.' + name + '_perf' prob.model.connect( name + '.local_stiff_transformed', point_name + '.coupled.' + name + '.local_stiff_transformed') prob.model.connect(name + '.nodes', point_name + '.coupled.' + name + '.nodes') # Connect aerodyamic mesh to coupled group mesh prob.model.connect(name + '.mesh', point_name + '.coupled.' + name + '.mesh') # Connect performance calculation variables prob.model.connect(name + '.radius', com_name + '.radius') prob.model.connect(name + '.thickness', com_name + '.thickness') prob.model.connect(name + '.nodes', com_name + '.nodes') prob.model.connect( name + '.cg_location', point_name + '.' + 'total_perf.' + name + '_cg_location') prob.model.connect( name + '.structural_mass', point_name + '.' + 'total_perf.' + name + '_structural_mass') prob.model.connect(name + '.t_over_c', com_name + '.t_over_c') from openmdao.api import ScipyOptimizeDriver prob.driver = ScipyOptimizeDriver() prob.driver.options['tol'] = 1e-9 # Setup problem and add design variables, constraint, and objective prob.model.add_design_var('wing.twist_cp', lower=-15., upper=15.) prob.model.add_design_var('wing.thickness_cp', lower=0.01, upper=0.5, scaler=1e2) prob.model.add_constraint('AS_point_0.wing_perf.failure', upper=0.) prob.model.add_constraint('AS_point_0.wing_perf.thickness_intersects', upper=0.) # Add design variables, constraisnt, and objective on the problem prob.model.add_design_var('alpha', lower=-10., upper=10.) prob.model.add_constraint('AS_point_0.L_equals_W', equals=0.) prob.model.add_objective('AS_point_0.fuelburn', scaler=1e-5) # Set up the problem prob.setup() # from openmdao.api import view_model # view_model(prob) prob.run_driver() assert_rel_error(self, prob['AS_point_0.wing_perf.CL'][0], 0.469128339791, 1e-6) assert_rel_error(self, prob['AS_point_0.fuelburn'][0], 95393.7772462, 1.5e-6) assert_rel_error(self, prob['AS_point_0.wing_perf.failure'][0], 0., 1e-6) assert_rel_error(self, prob['AS_point_0.CM'][1], -1.3154462936779994, 1e-4)
def setUp(self): # --- geometry ---- # --- geometry ---- z_param = np.array([0.0, 43.8, 87.6]) d_param = np.array([6.0, 4.935, 3.87]) t_param = np.array([0.027 * 1.3, 0.023 * 1.3, 0.019 * 1.3]) n = 15 z_full = np.linspace(0.0, 87.6, n) L_reinforced = 30.0 * np.ones(n) # [m] buckling length theta_stress = 0.0 * np.ones(n) yaw = 0.0 # --- material props --- E = 210e9 * np.ones(n) G = 80.8e9 * np.ones(n) rho = 8500.0 * np.ones(n) sigma_y = 450.0e6 * np.ones(n) # --- spring reaction data. Use float('inf') for rigid constraints. --- kidx = np.array([0], dtype=int) # applied at base kx = np.array([float('inf')]) ky = np.array([float('inf')]) kz = np.array([float('inf')]) ktx = np.array([float('inf')]) kty = np.array([float('inf')]) ktz = np.array([float('inf')]) nK = len(kidx) # --- extra mass ---- midx = np.array([n - 1], dtype=int) # RNA mass at top m = np.array([285598.8]) mIxx = np.array([1.14930678e+08]) mIyy = np.array([2.20354030e+07]) mIzz = np.array([1.87597425e+07]) mIxy = np.array([0.00000000e+00]) mIxz = np.array([5.03710467e+05]) mIyz = np.array([0.00000000e+00]) mrhox = np.array([-1.13197635]) mrhoy = np.array([0.]) mrhoz = np.array([0.50875268]) nMass = len(midx) addGravityLoadForExtraMass = True # ----------- # --- wind --- wind_zref = 90.0 wind_z0 = 0.0 shearExp = 0.2 # --------------- # if addGravityLoadForExtraMass=True be sure not to double count by adding those force here also # # --- loading case 1: max Thrust --- wind_Uref1 = 11.73732 plidx1 = np.array([n - 1], dtype=int) # at top Fx1 = np.array([1284744.19620519]) Fy1 = np.array([0.]) Fz1 = np.array([-2914124.84400512]) Mxx1 = np.array([3963732.76208099]) Myy1 = np.array([-2275104.79420872]) Mzz1 = np.array([-346781.68192839]) nPL = len(plidx1) # # --------------- # # --- loading case 2: max wind speed --- wind_Uref2 = 70.0 plidx2 = np.array([n - 1], dtype=int) # at top Fx2 = np.array([930198.60063279]) Fy2 = np.array([0.]) Fz2 = np.array([-2883106.12368949]) Mxx2 = np.array([-1683669.22411597]) Myy2 = np.array([-2522475.34625363]) Mzz2 = np.array([147301.97023764]) # # --------------- # --- safety factors --- gamma_f = 1.35 gamma_m = 1.3 gamma_n = 1.0 gamma_b = 1.1 # --------------- # --- fatigue --- z_DEL = np.array([ 0.000, 1.327, 3.982, 6.636, 9.291, 11.945, 14.600, 17.255, 19.909, 22.564, 25.218, 27.873, 30.527, 33.182, 35.836, 38.491, 41.145, 43.800, 46.455, 49.109, 51.764, 54.418, 57.073, 59.727, 62.382, 65.036, 67.691, 70.345, 73.000, 75.655, 78.309, 80.964, 83.618, 86.273, 87.600 ]) M_DEL = 1e3 * np.array([ 8.2940E+003, 8.1518E+003, 7.8831E+003, 7.6099E+003, 7.3359E+003, 7.0577E+003, 6.7821E+003, 6.5119E+003, 6.2391E+003, 5.9707E+003, 5.7070E+003, 5.4500E+003, 5.2015E+003, 4.9588E+003, 4.7202E+003, 4.4884E+003, 4.2577E+003, 4.0246E+003, 3.7942E+003, 3.5664E+003, 3.3406E+003, 3.1184E+003, 2.8977E+003, 2.6811E+003, 2.4719E+003, 2.2663E+003, 2.0673E+003, 1.8769E+003, 1.7017E+003, 1.5479E+003, 1.4207E+003, 1.3304E+003, 1.2780E+003, 1.2673E+003, 1.2761E+003 ]) nDEL = len(z_DEL) gamma_fatigue = 1.35 * 1.3 * 1.0 life = 20.0 m_SN = 4 # --------------- # --- constraints --- min_d_to_t = 120.0 min_taper = 0.4 # --------------- # # V_max = 80.0 # tip speed # # D = 126.0 # # .freq1p = V_max / (D/2) / (2*pi) # convert to Hz nPoints = len(z_param) nFull = len(z_full) wind = 'PowerWind' prob = Problem() root = prob.root = Group() prob.driver = pyOptSparseDriver() prob.driver.options['optimizer'] = 'SNOPT' prob.driver.opt_settings['Major iterations limit'] = 1000 root.add('z_param', IndepVarComp('z_param', z_param)) root.add('d_param', IndepVarComp('d_param', d_param)) root.add('t_param', IndepVarComp('t_param', t_param)) root.add('TowerSE', TowerSE(nPoints, nFull, nK, nMass, nPL, nDEL, wind=wind)) prob.driver.add_objective('TowerSE.tower1.mass', scaler=1E-6) prob.driver.add_desvar('z_param.z_param', lower=np.zeros(nPoints), upper=np.ones(nPoints) * 1000., scaler=1E-2) prob.driver.add_desvar('t_param.t_param', lower=np.ones(nPoints) * 0.001, upper=np.ones(nPoints) * 1000., scaler=1E-6) prob.driver.add_desvar('d_param.d_param', np.array([2, 2.1, 2.2]), upper=np.ones(nPoints) * 1000., scaler=1E-6) prob.root.connect('z_param.z_param', 'TowerSE.z_param') prob.root.connect('d_param.d_param', 'TowerSE.d_param') prob.root.connect('t_param.t_param', 'TowerSE.t_param') prob.driver.add_constraint('TowerSE.tower1.stress', upper=np.ones(n)) prob.driver.add_constraint('TowerSE.tower2.stress', upper=np.ones(n)) prob.driver.add_constraint('TowerSE.tower1.global_buckling', upper=np.ones(n)) prob.driver.add_constraint('TowerSE.tower2.global_buckling', upper=np.ones(n)) prob.driver.add_constraint('TowerSE.tower1.shell_buckling', upper=np.ones(n)) prob.driver.add_constraint('TowerSE.tower2.shell_buckling', upper=np.ones(n)) prob.driver.add_constraint('TowerSE.tower1.damage', upper=np.ones(n) * 0.8) prob.driver.add_constraint('TowerSE.gc.weldability', upper=np.zeros(n)) prob.driver.add_constraint('TowerSE.gc.manufacturability', upper=np.zeros(n)) freq1p = 0.2 # 1P freq in Hz prob.driver.add_constraint('TowerSE.tower1.f1', lower=1.1 * freq1p) prob.driver.add_constraint('TowerSE.tower2.f1', lower=1.1 * freq1p) prob.setup() if wind == 'PowerWind': prob['TowerSE.wind1.shearExp'] = shearExp prob['TowerSE.wind2.shearExp'] = shearExp # assign values to params # --- geometry ---- #prob['TowerSE.z_param'] = z_param #prob['TowerSE.d_param'] = d_param #prob['TowerSE.t_param'] = t_param prob['TowerSE.z_full'] = z_full prob['TowerSE.tower1.L_reinforced'] = L_reinforced prob['TowerSE.distLoads1.yaw'] = yaw # --- material props --- prob['TowerSE.tower1.E'] = E prob['TowerSE.tower1.G'] = G prob['TowerSE.tower1.rho'] = rho prob['TowerSE.tower1.sigma_y'] = sigma_y # --- spring reaction data. Use float('inf') for rigid constraints. --- prob['TowerSE.tower1.kidx'] = kidx prob['TowerSE.tower1.kx'] = kx prob['TowerSE.tower1.ky'] = ky prob['TowerSE.tower1.kz'] = kz prob['TowerSE.tower1.ktx'] = ktx prob['TowerSE.tower1.kty'] = kty prob['TowerSE.tower1.ktz'] = ktz # --- extra mass ---- prob['TowerSE.tower1.midx'] = midx prob['TowerSE.tower1.m'] = m prob['TowerSE.tower1.mIxx'] = mIxx prob['TowerSE.tower1.mIyy'] = mIyy prob['TowerSE.tower1.mIzz'] = mIzz prob['TowerSE.tower1.mIxy'] = mIxy prob['TowerSE.tower1.mIxz'] = mIxz prob['TowerSE.tower1.mIyz'] = mIyz prob['TowerSE.tower1.mrhox'] = mrhox prob['TowerSE.tower1.mrhoy'] = mrhoy prob['TowerSE.tower1.mrhoz'] = mrhoz prob[ 'TowerSE.tower1.addGravityLoadForExtraMass'] = addGravityLoadForExtraMass # ----------- # --- wind --- prob['TowerSE.wind1.zref'] = wind_zref prob['TowerSE.wind1.z0'] = wind_z0 # --------------- # # --- loading case 1: max Thrust --- prob['TowerSE.wind1.Uref'] = wind_Uref1 prob['TowerSE.tower1.plidx'] = plidx1 prob['TowerSE.tower1.Fx'] = Fx1 prob['TowerSE.tower1.Fy'] = Fy1 prob['TowerSE.tower1.Fz'] = Fz1 prob['TowerSE.tower1.Mxx'] = Mxx1 prob['TowerSE.tower1.Myy'] = Myy1 prob['TowerSE.tower1.Mzz'] = Mzz1 # # --------------- # # --- loading case 2: max Wind Speed --- prob['TowerSE.wind2.Uref'] = wind_Uref2 prob['TowerSE.tower2.plidx'] = plidx2 prob['TowerSE.tower2.Fx'] = Fx2 prob['TowerSE.tower2.Fy'] = Fy2 prob['TowerSE.tower2.Fz'] = Fz2 prob['TowerSE.tower2.Mxx'] = Mxx2 prob['TowerSE.tower2.Myy'] = Myy2 prob['TowerSE.tower2.Mzz'] = Mzz2 # # --------------- # --- safety factors --- prob['TowerSE.tower1.gamma_f'] = gamma_f prob['TowerSE.tower1.gamma_m'] = gamma_m prob['TowerSE.tower1.gamma_n'] = gamma_n prob['TowerSE.tower1.gamma_b'] = gamma_b # --------------- # --- fatigue --- prob['TowerSE.tower1.z_DEL'] = z_DEL prob['TowerSE.tower1.M_DEL'] = M_DEL prob['TowerSE.tower1.gamma_fatigue'] = gamma_fatigue prob['TowerSE.tower1.life'] = life prob['TowerSE.tower1.m_SN'] = m_SN # --------------- # --- constraints --- prob['TowerSE.gc.min_d_to_t'] = min_d_to_t prob['TowerSE.gc.min_taper'] = min_taper # --------------- # # --- run --- prob.run() print prob['TowerSE.gc.weldability'] print prob['TowerSE.gc.manufacturability'] self.J = prob.check_total_derivatives(out_stream=None) """
def test_distributed_list_vars(self): from openmdao.utils.general_utils import set_pyoptsparse_opt from openmdao.utils.mpi import MPI if MPI: from openmdao.api import PETScVector vector_class = PETScVector else: PETScVector = None # check that pyoptsparse is installed. if it is, try to use SLSQP. OPT, OPTIMIZER = set_pyoptsparse_opt('SLSQP') if OPTIMIZER: from openmdao.drivers.pyoptsparse_driver import pyOptSparseDriver else: raise unittest.SkipTest("pyOptSparseDriver is required.") from openmdao.core.parallel_group import ParallelGroup from openmdao.components.exec_comp import ExecComp class Mygroup(Group): def setup(self): self.add_subsystem('indep_var_comp', IndepVarComp('x'), promotes=['*']) self.add_subsystem('Cy', ExecComp('y=2*x'), promotes=['*']) self.add_subsystem('Cc', ExecComp('c=x+2'), promotes=['*']) self.add_design_var('x') self.add_constraint('c', lower=-3.) 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.setup(vector_class=PETScVector) prob.run_driver() prob.cleanup() stream = cStringIO() inputs = sorted(prob.model.list_inputs(values=True, print_arrays=True, out_stream=stream)) self.assertEqual(inputs[0][0], 'Obj.y1') self.assertEqual(inputs[1][0], 'Obj.y2') if prob.comm.rank: # Only rank 0 prints self.assertEqual(inputs[2][0], 'par.G2.Cc.x') self.assertEqual(inputs[3][0], 'par.G2.Cy.x') else: self.assertEqual(inputs[2][0], 'par.G1.Cc.x') self.assertEqual(inputs[3][0], 'par.G1.Cy.x') self.assertTrue('value' in inputs[0][1]) self.assertEqual(4, len(inputs)) text = stream.getvalue() if prob.comm.rank: # Only rank 0 prints self.assertEqual(len(text), 0) else: self.assertEqual(1, text.count("6 Input(s) in 'model'"), 1) self.assertEqual(1, text.count('value')) self.assertEqual(1, text.count(' par')) self.assertEqual(1, text.count(' G1')) self.assertEqual(1, text.count(' G2')) self.assertEqual(2, text.count(' Cy')) self.assertEqual(2, text.count(' Cc')) self.assertEqual(4, text.count(' x')) self.assertEqual(1, text.count(' Obj')) self.assertEqual(1, text.count(' y1')) self.assertEqual(1, text.count(' y2')) stream = cStringIO() outputs = sorted(prob.model.list_outputs(values=True, units=True, shape=True, bounds=True, residuals=True, scaling=True, hierarchical=True, print_arrays=True, out_stream=stream)) self.assertEqual(outputs[0][0], 'Obj.obj') if prob.comm.rank: # outputs only return what is on their proc self.assertEqual(outputs[1][0], 'par.G2.Cc.c') self.assertEqual(outputs[2][0], 'par.G2.Cy.y') self.assertEqual(outputs[3][0], 'par.G2.indep_var_comp.x') else: self.assertEqual(outputs[1][0], 'par.G1.Cc.c') self.assertEqual(outputs[2][0], 'par.G1.Cy.y') self.assertEqual(outputs[3][0], 'par.G1.indep_var_comp.x') self.assertEqual(4, len(outputs)) self.assertTrue('value' in outputs[0][1]) self.assertTrue('units' in outputs[0][1]) text = stream.getvalue() if prob.comm.rank: # Only rank 0 prints self.assertEqual(len(text), 0) else: self.assertEqual(1, text.count("7 Explicit Output(s) in 'model'")) self.assertEqual(1, text.count('value')) self.assertEqual(1, text.count('units')) self.assertEqual(1, text.count(' par')) self.assertEqual(1, text.count(' G1')) self.assertEqual(1, text.count(' G2')) self.assertEqual(2, text.count(' Cy')) self.assertEqual(2, text.count(' Cc')) self.assertEqual(2, text.count(' indep_var_comp')) self.assertEqual(2, text.count(' x')) self.assertEqual(2, text.count(' y')) self.assertEqual(2, text.count(' c')) self.assertEqual(1, text.count(' Obj')) self.assertEqual(1, text.count(' obj'))
self.connect('ConfigWeight.mass_W', 'con3.mass_W') self.connect('scale6.scaled', 'con3.mtow') self.connect('ConfigWeight.mass_rotor', 'con4.mass_rotor') self.connect('HoverPower.hoverPower_Vtip', 'con4.hoverPower_Vtip') self.connect('HoverPower.hoverPower_VAutoRotation', 'con4.hoverPower_VAutoRotation') self.connect('scale4.scaled', 'con5.mBattery') self.connect('scale6.scaled', 'con5.mtow') if __name__ == '__main__': # SubProblem: define a Problem to optimize the system sub = Problem(root=TopLevelSystem()) # SubProblem: set up the optimizer sub.driver = ScipyOptimizer() sub.driver.options[ 'optimizer'] = 'COBYLA' # The 'COBYLA' optimizer is supported by OpenMETA. # Unlike the 'SLSQP' optimizer, the 'COBYLA' optimizer doesn't require a Jacobian matrix. sub.driver.options['disp'] = True # enable optimizer output sub.driver.options['maxiter'] = 1000 sub.driver.options['tol'] = 0.001 #sub.driver.opt_settings['rhobeg'] = 100.0 # SubProblem: set design variables for sub.driver sub.driver.add_desvar('indep2.rProp', lower=10.0, upper=100.0) sub.driver.add_desvar('indep3.cruiseSpeed', lower=30.0, upper=80.0) sub.driver.add_desvar('indep4.batteryMass', lower=1.0, upper=99.90) sub.driver.add_desvar('indep5.motorMass', lower=0.10, upper=99.90) sub.driver.add_desvar('indep6.mtom', lower=1.0, upper=99.990)
def test_hohmann_result(self): prob = Problem(root=Group()) root = prob.root root.add('mu_comp', IndepVarComp('mu', val=0.0, units='km**3/s**2'), promotes=['mu']) root.add('r1_comp', IndepVarComp('r1', val=0.0, units='km'), promotes=['r1']) root.add('r2_comp', IndepVarComp('r2', val=0.0, units='km'), promotes=['r2']) root.add('dinc1_comp', IndepVarComp('dinc1', val=0.0, units='deg'), promotes=['dinc1']) root.add('dinc2_comp', IndepVarComp('dinc2', val=0.0, units='deg'), promotes=['dinc2']) root.add('leo', system=VCircComp()) root.add('geo', system=VCircComp()) root.add('transfer', system=TransferOrbitComp()) root.connect('r1', ['leo.r', 'transfer.rp']) root.connect('r2', ['geo.r', 'transfer.ra']) root.connect('mu', ['leo.mu', 'geo.mu', 'transfer.mu']) root.add('dv1', system=DeltaVComp()) root.connect('leo.vcirc', 'dv1.v1') root.connect('transfer.vp', 'dv1.v2') root.connect('dinc1', 'dv1.dinc') root.add('dv2', system=DeltaVComp()) root.connect('transfer.va', 'dv2.v1') root.connect('geo.vcirc', 'dv2.v2') root.connect('dinc2', 'dv2.dinc') root.add('dv_total', system=ExecComp('delta_v=dv1+dv2', units={ 'delta_v': 'km/s', 'dv1': 'km/s', 'dv2': 'km/s' }), promotes=['delta_v']) root.connect('dv1.delta_v', 'dv_total.dv1') root.connect('dv2.delta_v', 'dv_total.dv2') root.add('dinc_total', system=ExecComp('dinc=dinc1+dinc2', units={ 'dinc': 'deg', 'dinc1': 'deg', 'dinc2': 'deg' }), promotes=['dinc']) root.connect('dinc1', 'dinc_total.dinc1') root.connect('dinc2', 'dinc_total.dinc2') prob.driver = ScipyOptimizer() prob.driver.add_desvar('dinc1', lower=0, upper=28.5) prob.driver.add_desvar('dinc2', lower=0, upper=28.5) prob.driver.add_constraint('dinc', lower=28.5, upper=28.5, scaler=1.0) prob.driver.add_objective('delta_v', scaler=1.0) # Setup the problem prob.setup() # Set initial values prob['mu'] = 398600.4418 prob['r1'] = 6778.137 prob['r2'] = 42164.0 prob['dinc1'] = 0.0 prob['dinc2'] = 0.0 # Go! prob.run() self.assertAlmostEqual(prob['delta_v'], 9.00599000737, places=7) self.assertAlmostEqual(prob['dinc1'], 1.6672269916, places=7) self.assertAlmostEqual(prob['dinc2'], 26.8327730084, places=7)
from optparse import OptionParser parser = OptionParser() parser.add_option("-b", "--batch", action="store_true", dest="batch", default=False, help="do not plot anything") parser.add_option("-n", "--ncases", type="int", dest="n_cases", default=50, help="number of samples") parser.add_option("-p", "--parallel", action="store_true", default=False, help="run doe in parallel") (options, args) = parser.parse_args() pb = Problem(LanceurPropSolideWithoutTrajectoryVersion2()) pb.driver = SmtDOEDriver(sampling_method_name='LHS', n_cases=options.n_cases, sampling_method_options={'criterion': 'ese'}) pb.driver.options['run_parallel'] = options.parallel case_recorder_filename = 'lanceur_prop_solide_without_trajectory_version2_doe.sqlite' recorder = SqliteRecorder(case_recorder_filename) pb.driver.add_recorder(recorder) pb.model.nonlinear_solver.options['err_on_non_converge'] = True pb.model.add_design_var('Mnozzle', lower=-sys.float_info.max, upper=sys.float_info.max) pb.model.add_objective('F_T') pb.model.add_objective('Isp') pb.model.add_objective('Lconv') pb.model.add_objective('Ldiv')
def test_debug_print_desvar_physical_with_indices(self): prob = Problem() model = prob.model = Group() size = 3 model.add_subsystem('p1', IndepVarComp('x', np.array([50.0] * size))) model.add_subsystem('p2', IndepVarComp('y', np.array([50.0] * size))) model.add_subsystem( 'comp', ExecComp('f_xy = (x-3.0)**2 + x*y + (y+4.0)**2 - 3.0', x=np.zeros(size), y=np.zeros(size), f_xy=np.zeros(size))) model.add_subsystem( 'con', ExecComp('c = - x + y', c=np.zeros(size), x=np.zeros(size), y=np.zeros(size))) model.connect('p1.x', 'comp.x') model.connect('p2.y', 'comp.y') model.connect('p1.x', 'con.x') model.connect('p2.y', 'con.y') prob.set_solver_print(level=0) prob.driver = ScipyOptimizeDriver() prob.driver.options['optimizer'] = 'SLSQP' prob.driver.options['tol'] = 1e-9 prob.driver.options['disp'] = False model.add_design_var('p1.x', indices=[1], lower=-50.0, upper=50.0, ref=[ 5.0, ]) model.add_design_var('p2.y', indices=[1], lower=-50.0, upper=50.0) model.add_objective('comp.f_xy', index=1) model.add_constraint('con.c', indices=[1], upper=-15.0) prob.setup(check=False) prob.driver.options['debug_print'] = [ 'desvars', ] stdout = sys.stdout strout = StringIO() sys.stdout = strout try: # formatting has changed in numpy 1.14 and beyond. if LooseVersion(np.__version__) >= LooseVersion("1.14"): with printoptions(precision=2, legacy="1.13"): prob.run_driver() else: with printoptions(precision=2): prob.run_driver() finally: sys.stdout = stdout output = strout.getvalue().split('\n') # should see unscaled (physical) and the full arrays, not just what is indicated by indices self.assertEqual( output[3], "{'p1.x': array([ 50., 50., 50.]), 'p2.y': array([ 50., 50., 50.])}" )
self.connect("dv_StaggerRow.stagger_row" , "Friction.stagger_row") self.connect("dv_afCol.af_col" , "Friction.af_col") self.connect("dv_afRow.af_row" , "Friction.af_row") self.connect("dv_aspect.aspect" , "Friction.aspect") # Connect AVL outputs to L2D calculation inputs self.connect("AVL.CDtot", "L2D.CD") self.connect("AVL.CLtot", "L2D.CL") self.connect("Friction.CDtotal", "L2D.CDf") # Iniatate the the OpenMDAO problem openMDAOProblem = Problem() openMDAOProblem.model = MaxLtoD() # Set design driver parameters openMDAOProblem.driver = om.SimpleGADriver() # openMDAOProblem.driver.options['bits'] = {'dvStagger.stagger': 8, # 'dvStaggerRow.stagger_row': 8, # 'dvGap.gap': 8,} openMDAOProblem.driver.options['max_gen'] = 10 openMDAOProblem.driver.options['pop_size'] = 50 openMDAOProblem.driver.options['run_parallel'] = True openMDAOProblem.driver.options['procs_per_model'] = 2 openMDAOProblem.driver.options['debug_print'] = ['desvars', 'objs', 'totals'] openMDAOProblem.model.add_design_var("dv_Gap.gap", lower=0.5, upper=5.0) # Geometry design values openMDAOProblem.model.add_design_var("dv_Stagger.stagger", lower=0.5, upper=5.0) # Geometry design values openMDAOProblem.model.add_design_var("dv_StaggerRow.stagger_row", lower=0.0, upper=5.0) openMDAOProblem.model.add_design_var("dv_afCol.af_col", lower=1.0, upper=5.0) openMDAOProblem.model.add_design_var("dv_afRow.af_row", lower=1.0, upper=5.0) openMDAOProblem.model.add_design_var("dv_aspect.aspect", lower=5.0, upper=10.0)
if __name__ == '__main__': # import pylab import time model = MPPT_MDP() model.add_design_var('pt0.param.CP_Isetpt', lower=0., upper=0.4) model.add_design_var('pt1.param.CP_Isetpt', lower=0., upper=0.4) model.add_objective('perf.result') # create problem and add optimizer prob = Problem(model) prob.driver = pyOptSparseDriver(optimizer='SNOPT') prob.driver.opt_settings = { 'Major optimality tolerance': 1e-3, 'Major feasibility tolerance': 1.0e-5, 'Iterations limit': 500000000, 'New basis file': 10 } prob.setup() # pylab.figure() # pylab.subplot(211) # pylab.plot(prob['parallel.pt0.param.CP_Isetpt'].T) # pylab.plot(prob['parallel.pt1.param.CP_Isetpt'].T) t = time.time() prob.run_driver()
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)
prob.model.add_subsystem('con', ExecComp('c = x + y')) # Connect the model prob.model.connect('indeps.x', 'paraboloid.x') prob.model.connect('indeps.y', 'paraboloid.y') prob.model.connect('indeps.x', 'con.x') prob.model.connect('indeps.y', 'con.y') # Define the optimization problem prob.model.add_design_var('indeps.x', lower=-50, upper=50) prob.model.add_design_var('indeps.y', lower=-50, upper=50) prob.model.add_objective('paraboloid.f') prob.model.add_constraint('con.c', lower=0.0) # Create the ParOpt driver prob.driver = ParOptDriver() # Set options for the driver prob.driver.options['optimizer'] = args.optimizer prob.driver.options['output_file'] = 'paropt.out' prob.driver.options['tr_output_file'] = 'tr_paropt.out' # Run the problem prob.setup() prob.run_driver() # Print the minimum value print("Minimum value = {fmin:.2f}".format(fmin=prob['paraboloid.f'][0])) # Print the x/y location of the minimum print("(x, y) = ({x:.2f}, {y:.2f})".format(x=prob['indeps.x'][0],
# Add paraboloidProblem to ParaboloidOptimization as a SubProblem called 'ParaboloidProblem' # Include paraboloidProblem's Problem Inputs and Problem Outputs in 'params' and 'unknowns' fields SubProblem ParaboloidOptimization.root.add( 'ParaboloidProblem', SubProblem(paraboloidProblem, params=['p1.x', 'p2.y'], unknowns=['Paraboloid.f_xy']) ) # This is where you designate what to expose to the outside world # Connect ParaboloidOptimization's IndepVarComps to ParaboloidProblem's params ParaboloidOptimization.root.connect('p1.x', 'ParaboloidProblem.p1.x') ParaboloidOptimization.root.connect('p2.y', 'ParaboloidProblem.p2.y') # Add driver ParaboloidOptimization.driver = ScipyOptimizer() # Modify the optimization driver's settings ParaboloidOptimization.driver.options[ 'optimizer'] = 'COBYLA' # Type of Optimizer. 'COBYLA' does not require derivatives ParaboloidOptimization.driver.options[ 'tol'] = 1.0e-4 # Tolerance for termination. Not sure exactly what it represents. Default: 1.0e-6 ParaboloidOptimization.driver.options[ 'maxiter'] = 200 # Maximum iterations. Default: 200 #ParaboloidOptimization.driver.opt_settings['rhobeg'] = 1.0 # COBYLA-specific setting. Initial step size. Default: 1.0 #ParaboloidOptimization.driver.opt_settings['catol'] = 0.1 # COBYLA-specific setting. Absolute tolerance for constraint violations. Default: 0.1 # Add design variables, objective, and constraints to the optimization driver ParaboloidOptimization.driver.add_desvar('p1.x', lower=-50, upper=50) ParaboloidOptimization.driver.add_desvar('p2.y', lower=-50, upper=50) ParaboloidOptimization.driver.add_objective(
def test(self): # Create a dictionary to store options about the surface mesh_dict = { 'num_y': 11, 'num_x': 3, 'wing_type': 'CRM', 'symmetry': False, 'num_twist_cp': 5 } mesh, twist_cp = generate_mesh(mesh_dict) surf_dict = { # Wing definition 'name': 'wing', # name of the surface 'type': 'aero', 'symmetry': False, # if true, model one half of wing # reflected across the plane y = 0 'S_ref_type': 'wetted', # how we compute the wing area, # can be 'wetted' or 'projected' 'mesh': mesh, 'num_x': mesh.shape[0], 'num_y': mesh.shape[1], 'twist_cp': twist_cp, # Aerodynamic performance of the lifting surface at # an angle of attack of 0 (alpha=0). # These CL0 and CD0 values are added to the CL and CD # obtained from aerodynamic analysis of the surface to get # the total CL and CD. # These CL0 and CD0 values do not vary wrt alpha. 'CL0': 0.0, # CL of the surface at alpha=0 'CD0': 0.0, # CD of the surface at alpha=0 # Airfoil properties for viscous drag calculation 'k_lam': 0.05, # percentage of chord with laminar # flow, used for viscous drag 't_over_c_cp': np.array([0.15]), # thickness over chord ratio (NACA0015) 'c_max_t': .303, # chordwise location of maximum (NACA0015) # thickness 'with_viscous': True, # if true, compute viscous drag 'with_wave': True, # if true, compute wave drag } surfaces = [surf_dict] # Create the problem and the model group prob = Problem() indep_var_comp = IndepVarComp() indep_var_comp.add_output('v', val=248.136, units='m/s') indep_var_comp.add_output('alpha', val=5., units='deg') indep_var_comp.add_output('M', val=0.84) indep_var_comp.add_output('re', val=1.e6, units='1/m') indep_var_comp.add_output('rho', val=0.38, units='kg/m**3') indep_var_comp.add_output('cg', val=np.zeros((3)), units='m') prob.model.add_subsystem('prob_vars', indep_var_comp, promotes=['*']) # Loop over each surface in the surfaces list for surface in surfaces: geom_group = Geometry(surface=surface) # Add tmp_group to the problem as the name of the surface. # Note that is a group and performance group for each # individual surface. prob.model.add_subsystem(surface['name'], geom_group) # Loop through and add a certain number of aero points for i in range(1): # Create the aero point group and add it to the model aero_group = AeroPoint(surfaces=surfaces) point_name = 'aero_point_{}'.format(i) prob.model.add_subsystem(point_name, aero_group) # Connect flow properties to the analysis point prob.model.connect('v', point_name + '.v') prob.model.connect('alpha', point_name + '.alpha') prob.model.connect('M', point_name + '.M') prob.model.connect('re', point_name + '.re') prob.model.connect('rho', point_name + '.rho') prob.model.connect('cg', point_name + '.cg') # Connect the parameters within the model for each aero point for surface in surfaces: name = surface['name'] # Connect the mesh from the geometry component to the analysis point prob.model.connect(name + '.mesh', point_name + '.' + name + '.def_mesh') # Perform the connections with the modified names within the # 'aero_states' group. prob.model.connect( name + '.mesh', point_name + '.aero_states.' + name + '_def_mesh') prob.model.connect( name + '.t_over_c', point_name + '.' + name + '_perf.' + 't_over_c') from openmdao.api import ScipyOptimizeDriver prob.driver = ScipyOptimizeDriver() prob.driver.options['tol'] = 1e-9 recorder = SqliteRecorder("aero_opt_wavedrag.db") prob.driver.add_recorder(recorder) prob.driver.recording_options['record_derivatives'] = True # Setup problem and add design variables, constraint, and objective prob.model.add_design_var('wing.twist_cp', lower=-10., upper=15.) prob.model.add_constraint(point_name + '.wing_perf.CL', equals=0.5) prob.model.add_objective(point_name + '.wing_perf.CD', scaler=1e4) # Set up the problem prob.setup() prob.run_driver() assert_rel_error(self, prob['aero_point_0.wing_perf.CL'][0], 0.5, 1e-6) assert_rel_error(self, prob['aero_point_0.wing_perf.CD'][0], 0.02257921, 1e-6) assert_rel_error(self, prob['aero_point_0.CM'][1], -0.179451279, 1e-6)
def test_pyxdsm_identical_relative_names(self): class TimeComp(ExplicitComponent): def setup(self): self.add_input('t_initial', val=0.) self.add_input('t_duration', val=1.) self.add_output('time', shape=(2, )) def compute(self, inputs, outputs): t_initial = inputs['t_initial'] t_duration = inputs['t_duration'] outputs['time'][0] = t_initial outputs['time'][1] = t_initial + t_duration class Phase(Group): def setup(self): super(Phase, self).setup() indep = IndepVarComp() for var in ['t_initial', 't_duration']: indep.add_output(var, val=1.0) self.add_subsystem('time_extents', indep, promotes_outputs=['*']) time_comp = TimeComp() self.add_subsystem('time', time_comp) self.connect('t_initial', 'time.t_initial') self.connect('t_duration', 'time.t_duration') self.set_order(['time_extents', 'time']) p = Problem() p.driver = ScipyOptimizeDriver() orbit_phase = Phase() p.model.add_subsystem('orbit_phase', orbit_phase) systems_phase = Phase() p.model.add_subsystem('systems_phase', systems_phase) systems_phase = Phase() p.model.add_subsystem('extra_phase', systems_phase) p.model.add_design_var('orbit_phase.t_initial') p.model.add_design_var('orbit_phase.t_duration') p.setup(check=True) p.run_model() # requesting 'pdf', but if 'pdflatex' is not found we will only get 'tex' pdflatex = find_executable('pdflatex') # Test non unique local names write_xdsm(p, 'xdsm3', out_format='pdf', quiet=QUIET, show_browser=False) self.assertTrue(os.path.isfile('.'.join(['xdsm3', 'tex']))) self.assertTrue(not pdflatex or os.path.isfile('.'.join(['xdsm3', 'pdf']))) # Check formatting # Max character box formatting write_xdsm(p, 'xdsm4', out_format='pdf', quiet=QUIET, show_browser=False, box_stacking='cut_chars', box_width=15) self.assertTrue(os.path.isfile('.'.join(['xdsm4', 'tex']))) self.assertTrue(not pdflatex or os.path.isfile('.'.join(['xdsm4', 'pdf']))) # Cut characters box formatting write_xdsm(p, 'xdsm5', out_format='pdf', quiet=True, show_browser=False, box_stacking='max_chars', box_width=15) self.assertTrue(os.path.isfile('.'.join(['xdsm5', 'tex']))) self.assertTrue(not pdflatex or os.path.isfile('.'.join(['xdsm5', 'pdf'])))
def test_distributed_driver_debug_print_options(self): # check that pyoptsparse is installed. if it is, try to use SLSQP. OPT, OPTIMIZER = set_pyoptsparse_opt('SLSQP') if OPTIMIZER: from openmdao.drivers.pyoptsparse_driver import pyOptSparseDriver else: raise unittest.SkipTest("pyOptSparseDriver is required.") class Mygroup(Group): def setup(self): self.add_subsystem('indep_var_comp', IndepVarComp('x'), promotes=['*']) self.add_subsystem('Cy', ExecComp('y=2*x'), promotes=['*']) self.add_subsystem('Cc', ExecComp('c=x+2'), promotes=['*']) self.add_design_var('x') self.add_constraint('c', lower=-3.) 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.options['print_results'] = False prob.driver.options['debug_print'] = [ 'desvars', 'ln_cons', 'nl_cons', 'objs' ] prob.setup() stdout = sys.stdout strout = StringIO() sys.stdout = strout sys.stdout = strout try: prob.run_driver() finally: sys.stdout = stdout output = strout.getvalue().split('\n') if MPI.COMM_WORLD.rank == 0: # Just make sure we have more than one. Not sure we will always have the same number # of iterations self.assertTrue( output.count("Design Vars") > 1, "Should be more than one design vars header printed") self.assertTrue( output.count("Nonlinear constraints") > 1, "Should be more than one nonlinear constraint header printed") self.assertTrue( output.count("Linear constraints") > 1, "Should be more than one linear constraint header printed") self.assertTrue( output.count("Objectives") > 1, "Should be more than one objective header printed") self.assertTrue( len([s for s in output if 'par.G1.indep_var_comp.x' in s]) > 1, "Should be more than one par.G1.indep_var_comp.x printed") self.assertTrue( len([s for s in output if 'par.G2.indep_var_comp.x' in s]) > 1, "Should be more than one par.G2.indep_var_comp.x printed") self.assertTrue( len([s for s in output if 'par.G1.Cc.c' in s]) > 1, "Should be more than one par.G1.Cc.c printed") self.assertTrue( len([s for s in output if 'par.G2.Cc.c' in s]) > 1, "Should be more than one par.G2.Cc.c printed") self.assertTrue( len([s for s in output if s.startswith('None')]) > 1, "Should be more than one None printed") self.assertTrue( len([s for s in output if 'Obj.obj' in s]) > 1, "Should be more than one Obj.obj printed") else: self.assertEqual(output, [''])
def test_feature_vectorized_derivs(self): import numpy as np from openmdao.api import ExplicitComponent, ExecComp, IndepVarComp, Problem, ScipyOptimizeDriver SIZE = 5 class ExpensiveAnalysis(ExplicitComponent): def setup(self): self.add_input('x', val=np.ones(SIZE)) self.add_input('y', val=np.ones(SIZE)) self.add_output('f', shape=1) self.declare_partials('f', 'x') self.declare_partials('f', 'y') def compute(self, inputs, outputs): outputs['f'] = np.sum(inputs['x']**inputs['y']) def compute_partials(self, inputs, J): J['f', 'x'] = inputs['y'] * inputs['x']**(inputs['y'] - 1) J['f', 'y'] = (inputs['x']**inputs['y']) * np.log(inputs['x']) class CheapConstraint(ExplicitComponent): def setup(self): self.add_input('y', val=np.ones(SIZE)) self.add_output('g', shape=SIZE) row_col = np.arange(SIZE, dtype=int) self.declare_partials('g', 'y', rows=row_col, cols=row_col) self.limit = 2 * np.arange(SIZE) def compute(self, inputs, outputs): outputs['g'] = inputs['y']**2 - self.limit def compute_partials(self, inputs, J): J['g', 'y'] = 2 * inputs['y'] p = Problem() dvs = p.model.add_subsystem('des_vars', IndepVarComp(), promotes=['*']) dvs.add_output('x', 2 * np.ones(SIZE)) dvs.add_output('y', 2 * np.ones(SIZE)) p.model.add_subsystem('obj', ExpensiveAnalysis(), promotes=['x', 'y', 'f']) p.model.add_subsystem('constraint', CheapConstraint(), promotes=['y', 'g']) p.model.add_design_var('x', lower=.1, upper=10000) p.model.add_design_var('y', lower=-1000, upper=10000) p.model.add_constraint('g', upper=0, vectorize_derivs=True) p.model.add_objective('f') p.setup(mode='rev') p.run_model() p.driver = ScipyOptimizeDriver() p.run_driver() assert_rel_error(self, p['x'], [0.10000691, 0.1, 0.1, 0.1, 0.1], 1e-5) assert_rel_error(self, p['y'], [0, 1.41421, 2.0, 2.44948, 2.82842], 1e-5)
def test_parallel(self): from openmdao.api import ParallelGroup, NonlinearBlockGS class SellarMDA(Group): """ Group containing the Sellar MDA. """ def setup(self): indeps = self.add_subsystem('indeps', IndepVarComp(), promotes=['*']) indeps.add_output('x', 1.0) indeps.add_output('z', np.array([5.0, 2.0])) cycle = self.add_subsystem('cycle', ParallelGroup(), promotes=['*']) cycle.add_subsystem('d1', SellarDis1(), promotes_inputs=['x', 'z', 'y2'], promotes_outputs=['y1']) cycle.add_subsystem('d2', SellarDis2(), promotes_inputs=['z', 'y1'], promotes_outputs=['y2']) # Nonlinear Block Gauss Seidel is a gradient free solver cycle.nonlinear_solver = NonlinearBlockGS() self.add_subsystem('obj_cmp', ExecComp( 'obj = x**2 + z[1] + y1 + exp(-y2)', z=np.array([0.0, 0.0]), x=0.0), promotes=['x', 'z', 'y1', 'y2', 'obj']) self.add_subsystem('con_cmp1', ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1']) self.add_subsystem('con_cmp2', ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2']) filename = 'pyxdsm_parallel' out_format = 'pdf' prob = Problem(model=SellarMDA()) model = prob.model prob.driver = ScipyOptimizeDriver() model.add_design_var('z', lower=np.array([-10.0, 0.0]), upper=np.array([10.0, 10.0]), indices=np.arange(2, dtype=int)) model.add_design_var('x', lower=0.0, upper=10.0) model.add_objective('obj') model.add_constraint('con1', equals=np.zeros(1)) model.add_constraint('con2', upper=0.0) prob.setup(check=False) prob.final_setup() # Write output write_xdsm(prob, filename=filename, out_format=out_format, quiet=QUIET, show_browser=False, show_parallel=True) # Check if file was created self.assertTrue(os.path.isfile('.'.join([filename, out_format])))
def test(self): # Create a dictionary to store options about the surface mesh_dict = { 'num_y': 5, 'num_x': 3, 'wing_type': 'CRM', 'symmetry': True, 'num_twist_cp': 6, 'chord_cos_spacing': 0, 'span_cos_spacing': 0, } mesh, twist_cp = generate_mesh(mesh_dict) surf_dict = { # Wing definition 'name': 'wing', # name of the surface 'type': 'aerostruct', 'symmetry': True, # if true, model one half of wing # reflected across the plane y = 0 'S_ref_type': 'wetted', # how we compute the wing area, # can be 'wetted' or 'projected' 'fem_model_type': 'wingbox', 'spar_thickness_cp': np.array([0.004, 0.005, 0.005, 0.008, 0.008, 0.01]), # [m] 'skin_thickness_cp': np.array([0.005, 0.01, 0.015, 0.020, 0.025, 0.026]), 'twist_cp': np.array([4., 5., 8., 8., 8., 9.]), 'mesh': mesh, 'num_x': mesh.shape[0], 'num_y': mesh.shape[1], 'data_x_upper': upper_x, 'data_x_lower': lower_x, 'data_y_upper': upper_y, 'data_y_lower': lower_y, 'strength_factor_for_upper_skin': 1., # Aerodynamic performance of the lifting surface at # an angle of attack of 0 (alpha=0). # These CL0 and CD0 values are added to the CL and CD # obtained from aerodynamic analysis of the surface to get # the total CL and CD. # These CL0 and CD0 values do not vary wrt alpha. 'CL0': 0.0, # CL of the surface at alpha=0 'CD0': 0.0078, # CD of the surface at alpha=0 # Airfoil properties for viscous drag calculation 'k_lam': 0.05, # percentage of chord with laminar # flow, used for viscous drag 't_over_c_cp': np.array([0.08, 0.08, 0.08, 0.10, 0.10, 0.08]), 'original_wingbox_airfoil_t_over_c': 0.12, 'c_max_t': .38, # chordwise location of maximum thickness 'with_viscous': True, 'with_wave': True, # if true, compute wave drag # Structural values are based on aluminum 7075 'E': 73.1e9, # [Pa] Young's modulus 'G': ( 73.1e9 / 2 / 1.33 ), # [Pa] shear modulus (calculated using E and the Poisson's ratio here) 'yield': (420.e6 / 1.5), # [Pa] allowable yield stress 'mrho': 2.78e3, # [kg/m^3] material density 'strength_factor_for_upper_skin': 1.0, # the yield stress is multiplied by this factor for the upper skin # 'fem_origin' : 0.35, # normalized chordwise location of the spar 'wing_weight_ratio': 1.25, 'struct_weight_relief': True, # True to add the weight of the structure to the loads on the structure # Constraints 'exact_failure_constraint': False, # if false, use KS function } surfaces = [surf_dict] # Create the problem and assign the model group prob = Problem() # Add problem information as an independent variables component indep_var_comp = IndepVarComp() indep_var_comp.add_output('v', val=.85 * 295.07, units='m/s') indep_var_comp.add_output('alpha', val=0., units='deg') indep_var_comp.add_output('M', val=0.85) indep_var_comp.add_output('re', val=0.348 * 295.07 * .85 * 1. / (1.43 * 1e-5), units='1/m') indep_var_comp.add_output('rho', val=0.348, units='kg/m**3') indep_var_comp.add_output('CT', val=0.53 / 3600, units='1/s') indep_var_comp.add_output('R', val=14.307e6, units='m') indep_var_comp.add_output('W0', val=(143000 - 2.5 * 11600 + 34000) + 15000, units='kg') indep_var_comp.add_output('a', val=295.07, units='m/s') indep_var_comp.add_output('load_factor', val=1.) indep_var_comp.add_output('empty_cg', val=np.zeros((3)), units='m') prob.model.add_subsystem('prob_vars', indep_var_comp, promotes=['*']) # Loop over each surface in the surfaces list for surface in surfaces: # Get the surface name and create a group to contain components # only for this surface name = surface['name'] aerostruct_group = Aerostruct(surface=surface) # Add tmp_group to the problem with the name of the surface. prob.model.add_subsystem(name, aerostruct_group) # Loop through and add a certain number of aero points for i in range(1): point_name = 'AS_point_{}'.format(i) # Connect the parameters within the model for each aero point # Create the aero point group and add it to the model AS_point = AerostructPoint(surfaces=surfaces) prob.model.add_subsystem(point_name, AS_point) # Connect flow properties to the analysis point prob.model.connect('v', point_name + '.v') prob.model.connect('alpha', point_name + '.alpha') prob.model.connect('M', point_name + '.M') prob.model.connect('re', point_name + '.re') prob.model.connect('rho', point_name + '.rho') prob.model.connect('CT', point_name + '.CT') prob.model.connect('R', point_name + '.R') prob.model.connect('W0', point_name + '.W0') prob.model.connect('a', point_name + '.a') prob.model.connect('empty_cg', point_name + '.empty_cg') prob.model.connect('load_factor', point_name + '.load_factor') for surface in surfaces: prob.model.connect('load_factor', name + '.load_factor') com_name = point_name + '.' + name + '_perf.' prob.model.connect(name + '.K', point_name + '.coupled.' + name + '.K') # Connect aerodyamic mesh to coupled group mesh prob.model.connect(name + '.mesh', point_name + '.coupled.' + name + '.mesh') prob.model.connect( name + '.element_weights', point_name + '.coupled.' + name + '.element_weights') prob.model.connect(name + '.nodes', point_name + '.coupled.' + name + '.nodes') # Connect performance calculation variables prob.model.connect(name + '.nodes', com_name + 'nodes') prob.model.connect( name + '.cg_location', point_name + '.' + 'total_perf.' + name + '_cg_location') prob.model.connect( name + '.structural_weight', point_name + '.' + 'total_perf.' + name + '_structural_weight') # Connect wingbox properties to von Mises stress calcs prob.model.connect(name + '.Qz', com_name + 'Qz') prob.model.connect(name + '.Iz', com_name + 'Iz') prob.model.connect(name + '.J', com_name + 'J') prob.model.connect(name + '.A_enc', com_name + 'A_enc') prob.model.connect(name + '.htop', com_name + 'htop') prob.model.connect(name + '.hbottom', com_name + 'hbottom') prob.model.connect(name + '.hfront', com_name + 'hfront') prob.model.connect(name + '.hrear', com_name + 'hrear') prob.model.connect(name + '.spar_thickness', com_name + 'spar_thickness') prob.model.connect(name + '.skin_thickness', com_name + 'skin_thickness') prob.model.connect(name + '.t_over_c', com_name + 't_over_c') from openmdao.api import ScipyOptimizeDriver prob.driver = ScipyOptimizeDriver() prob.driver.options['tol'] = 1e-9 # Set up the problem prob.setup() # # from openmdao.api import view_model # view_model(prob) prob.run_model() # prob.model.list_outputs(values=True, # implicit=False, # units=True, # shape=True, # bounds=True, # residuals=True, # scaling=True, # hierarchical=False, # print_arrays=True) # print(prob['AS_point_0.fuelburn'][0]) # print(prob['wing.structural_weight'][0]/1.25) # print(prob['AS_point_0.wing_perf.failure'][0]) assert_rel_error(self, prob['AS_point_0.fuelburn'][0], 112532.399999, 1e-5) assert_rel_error(self, prob['wing.structural_weight'][0] / 1.25, 235533.421185, 1e-5) assert_rel_error(self, prob['AS_point_0.wing_perf.failure'][0], 1.70644139941, 1e-5)
def test_brachistochrone_for_docs_runge_kutta_polynomial_controls(self): from openmdao.api import Problem, Group, ScipyOptimizeDriver, DirectSolver, SqliteRecorder from openmdao.utils.assert_utils import assert_rel_error import dymos as dm from dymos.examples.plotting import plot_results from dymos.examples.brachistochrone import BrachistochroneODE # # Initialize the Problem and the optimization driver # p = Problem(model=Group()) p.driver = ScipyOptimizeDriver() p.driver.options['dynamic_simul_derivs'] = True # # Create a trajectory and add a phase to it # traj = p.model.add_subsystem('traj', dm.Trajectory()) phase = traj.add_phase( 'phase0', dm.Phase(ode_class=BrachistochroneODE, transcription=dm.RungeKutta(num_segments=10))) # # Set the variables # phase.set_time_options(initial_bounds=(0, 0), duration_bounds=(.5, 10)) phase.set_state_options('x', fix_initial=True) phase.set_state_options('y', fix_initial=True) phase.set_state_options('v', fix_initial=True) phase.add_polynomial_control('theta', units='deg', lower=0.01, upper=179.9, order=1) phase.add_design_parameter('g', units='m/s**2', opt=False, val=9.80665) # # Final state values are not optimization variables, so we must enforce final values # with boundary constraints, not simple bounds. # phase.add_boundary_constraint('x', loc='final', equals=10) phase.add_boundary_constraint('y', loc='final', equals=5) # # Minimize time at the end of the phase # phase.add_objective('time', loc='final', scaler=10) p.model.linear_solver = DirectSolver() # # Setup the Problem # p.setup() # # Set the initial values # p['traj.phase0.t_initial'] = 0.0 p['traj.phase0.t_duration'] = 2.0 p['traj.phase0.states:x'] = phase.interpolate(ys=[0, 10], nodes='state_input') p['traj.phase0.states:y'] = phase.interpolate(ys=[10, 5], nodes='state_input') p['traj.phase0.states:v'] = phase.interpolate(ys=[0, 9.9], nodes='state_input') p['traj.phase0.polynomial_controls:theta'][:] = 5.0 # # Solve for the optimal trajectory # p.run_driver() # Test the results assert_rel_error(self, p.get_val('traj.phase0.timeseries.time')[-1], 1.8016, tolerance=1.0E-3) # Generate the explicitly simulated trajectory exp_out = traj.simulate() plot_results( [('traj.phase0.timeseries.states:x', 'traj.phase0.timeseries.states:y', 'x (m)', 'y (m)'), ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.polynomial_controls:theta', 'time (s)', 'theta (deg)')], title= 'Brachistochrone Solution\nRK4 Shooting and Polynomial Controls', p_sol=p, p_sim=exp_out) plt.show()
def test_debug_print_option_totals(self): 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=['*']) prob.set_solver_print(level=0) prob.driver = ScipyOptimizeDriver() prob.driver.options['optimizer'] = 'SLSQP' prob.driver.options['tol'] = 1e-9 prob.driver.options['disp'] = False prob.driver.options['debug_print'] = ['totals'] 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, mode='rev') failed, output = run_driver(prob) self.assertFalse(failed, "Optimization failed.") self.assertTrue('Solving variable: comp.f_xy' in output) self.assertTrue('Solving variable: con.c' in output) 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=['*']) prob.set_solver_print(level=0) prob.driver = ScipyOptimizeDriver() prob.driver.options['optimizer'] = 'SLSQP' prob.driver.options['tol'] = 1e-9 prob.driver.options['disp'] = False prob.driver.options['debug_print'] = ['totals'] 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, mode='fwd') failed, output = run_driver(prob) self.assertFalse(failed, "Optimization failed.") self.assertTrue('Solving variable: p1.x' in output) self.assertTrue('Solving variable: p2.y' in output)
# Add paraboloidProblem to ParaboloidParameterStudy as a SubProblem called 'ParaboloidProblem' # Include paraboloidProblem's Problem Inputs and Problem Outputs in 'params' and 'unknowns' fields SubProblem ParaboloidParameterStudy.root.add( 'ParaboloidProblem', SubProblem(paraboloidProblem, params=['p1.x', 'p2.y'], unknowns=['Paraboloid.f_xy']) ) # This is where you designate what to expose to the outside world # Connect ParaboloidParameterStudy's IndepVarComps to ParaboloidProblem's params ParaboloidParameterStudy.root.connect('p1.x', 'ParaboloidProblem.p1.x') ParaboloidParameterStudy.root.connect('p2.y', 'ParaboloidProblem.p2.y') # Add driver ParaboloidParameterStudy.driver = FullFactorialDriver(num_levels=11) # Add design variables and objectives to the parameter study driver ParaboloidParameterStudy.driver.add_desvar('p1.x', lower=-50, upper=50) ParaboloidParameterStudy.driver.add_desvar('p2.y', lower=-50, upper=50) ParaboloidParameterStudy.driver.add_objective( 'ParaboloidProblem.Paraboloid.f_xy') # Data collection recorder = SqliteRecorder('record_results') recorder.options['record_params'] = True recorder.options['record_metadata'] = True ParaboloidParameterStudy.driver.add_recorder(recorder) # Setup ParaboloidParameterStudy.setup(check=False)
def test_debug_print_option(self): 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=['*']) prob.set_solver_print(level=0) prob.driver = ScipyOptimizeDriver() prob.driver.options['optimizer'] = 'SLSQP' prob.driver.options['tol'] = 1e-9 prob.driver.options['disp'] = False prob.driver.options['debug_print'] = [ 'desvars', 'ln_cons', 'nl_cons', 'objs' ] 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) stdout = sys.stdout strout = StringIO() sys.stdout = strout try: prob.run_driver() finally: sys.stdout = stdout output = strout.getvalue().split('\n') self.assertTrue( output.count("Design Vars") > 1, "Should be more than one design vars header printed") self.assertTrue( output.count("Nonlinear constraints") > 1, "Should be more than one nonlinear constraint header printed") self.assertTrue( output.count("Linear constraints") > 1, "Should be more than one linear constraint header printed") self.assertTrue( output.count("Objectives") > 1, "Should be more than one objective header printed") self.assertTrue( len([s for s in output if s.startswith("{'p1.x")]) > 1, "Should be more than one p1.x printed") self.assertTrue( len([s for s in output if "'p2.y'" in s]) > 1, "Should be more than one p2.y printed") self.assertTrue( len([s for s in output if s.startswith("{'con.c")]) > 1, "Should be more than one con.c printed") self.assertTrue( len([s for s in output if s.startswith("{'comp.f_xy")]) > 1, "Should be more than one comp.f_xy printed")
sub = Problem() sub.root = Group() # Add the 'Parabola' Component to sub's root Group. sub.root.add('Parabola', Parabola()) # Initialize x as a IndepVarComp and add it to sub's root group as 'p1.x' # run_mdao already does something like this for all driver design variables # p1.x is initialized to 0.0 because the OpenMETA Design Variable 'x' has a range of -50 to +50 sub.root.add('p1', IndepVarComp('x', 0.0)) # Connect the IndepVarComp p1.x to Parabola.x sub.root.connect('p1.x', 'Parabola.x') # Add driver sub.driver = ScipyOptimizer() # Modify the optimization driver's settings sub.driver.options[ 'optimizer'] = 'COBYLA' # Type of Optimizer. 'COBYLA' does not require derivatives sub.driver.options[ 'tol'] = 1.0e-4 # Tolerance for termination. Not sure exactly what it represents. Default: 1.0e-6 sub.driver.options['maxiter'] = 200 # Maximum iterations. Default: 200 #sub.driver.opt_settings['rhobeg'] = 1.0 # COBYLA-specific setting. Initial step size. Default: 1.0 #sub.driver.opt_settings['catol'] = 0.1 # COBYLA-specific setting. Absolute tolerance for constraint violations. Default: 0.1 # Add design variables, objective, and constraints to the optimization driver sub.driver.add_desvar('p1.x', lower=-50, upper=50) sub.driver.add_objective('Parabola.f_x') # Data collection