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 setup_model(self, mode): asize = 3 prob = Problem() root = prob.model root.linear_solver = LinearBlockGS() p = root.add_subsystem('p', IndepVarComp('x', np.arange(asize, dtype=float)+1.0)) G1 = root.add_subsystem('G1', ParallelGroup()) G1.linear_solver = LinearBlockGS() c2 = G1.add_subsystem('c2', ExecComp('y = x * 2.0', x=np.zeros(asize), y=np.zeros(asize))) c3 = G1.add_subsystem('c3', ExecComp('y = ones(3).T*x.dot(arange(3.,6.))', x=np.zeros(asize), y=np.zeros(asize))) c4 = root.add_subsystem('c4', ExecComp('y = x * 4.0', x=np.zeros(asize), y=np.zeros(asize))) c5 = root.add_subsystem('c5', ExecComp('y = x * 5.0', x=np.zeros(asize), y=np.zeros(asize))) prob.model.add_design_var('p.x', indices=[1, 2]) prob.model.add_constraint('c4.y', upper=0.0, indices=[1], parallel_deriv_color='par_resp') prob.model.add_constraint('c5.y', upper=0.0, indices=[2], parallel_deriv_color='par_resp') root.connect('p.x', 'G1.c2.x') root.connect('p.x', 'G1.c3.x') root.connect('G1.c2.y', 'c4.x') root.connect('G1.c3.y', 'c5.x') prob.setup(check=False, mode=mode) prob.run_driver() return prob
def test_vectorized_rhs_val(self): prob = Problem() model = prob.model n = 100 # find where x^2 == 4, vectorized model.add_subsystem('indep', IndepVarComp('x', val=np.ones(n))) model.add_subsystem('f', ExecComp('y=x**2', x=np.ones(n), y=np.ones(n))) model.add_subsystem('equal', EQConstraintComp('y', val=np.ones(n), rhs_val=np.ones(n)*4., use_mult=True, mult_val=2.)) model.add_subsystem('obj_cmp', ExecComp('obj=sum(y)', y=np.zeros(n))) model.connect('indep.x', 'f.x') model.connect('indep.x', 'equal.lhs:y') model.connect('f.y', 'obj_cmp.y') model.add_design_var('indep.x', lower=np.zeros(n), upper=np.ones(n)*10.) model.add_constraint('equal.y', equals=0.) model.add_objective('obj_cmp.obj') prob.setup(mode='fwd') prob.driver = ScipyOptimizeDriver(disp=False) prob.run_driver() assert_rel_error(self, prob['equal.y'], np.zeros(n), 1e-6) assert_rel_error(self, prob['indep.x'], np.ones(n)*2., 1e-6) assert_rel_error(self, prob['f.y'], np.ones(n)*4., 1e-6) cpd = prob.check_partials(out_stream=None) for (of, wrt) in cpd['equal']: assert_almost_equal(cpd['equal'][of, wrt]['abs error'], 0.0, decimal=5)
def test_complex_step(self): prob = Problem() model = prob.model # find where 2*x == x^2 model.add_subsystem('indep', IndepVarComp('x', val=1.)) model.add_subsystem('multx', IndepVarComp('m', val=2.)) model.add_subsystem('f', ExecComp('y=x**2', x=1.)) model.add_subsystem('equal', EQConstraintComp('y', use_mult=True)) model.connect('indep.x', 'f.x') model.connect('indep.x', 'equal.lhs:y') model.connect('multx.m', 'equal.mult:y') model.connect('f.y', 'equal.rhs:y') model.add_design_var('indep.x', lower=0., upper=10.) model.add_constraint('equal.y', equals=0.) model.add_objective('f.y') prob.setup(mode='fwd', force_alloc_complex=True) prob.driver = ScipyOptimizeDriver(disp=False) prob.run_driver() with warnings.catch_warnings(): warnings.filterwarnings(action="error", category=np.ComplexWarning) cpd = prob.check_partials(out_stream=None, method='cs') assert_check_partials(cpd, atol=1e-10, rtol=1e-10)
def test_rhs_val(self): prob = Problem() model = prob.model # find where x^2 == 4 model.add_subsystem('indep', IndepVarComp('x', val=1.)) model.add_subsystem('f', ExecComp('y=x**2', x=1.)) model.add_subsystem('equal', EQConstraintComp('y', rhs_val=4.)) model.connect('indep.x', 'f.x') model.connect('f.y', 'equal.lhs:y') model.add_design_var('indep.x', lower=0., upper=10.) model.add_constraint('equal.y', equals=0.) model.add_objective('f.y') prob.setup(mode='fwd') prob.driver = ScipyOptimizeDriver(disp=False) prob.run_driver() assert_rel_error(self, prob['equal.y'], 0., 1e-6) assert_rel_error(self, prob['indep.x'], 2., 1e-6) assert_rel_error(self, prob['f.y'], 4., 1e-6) cpd = prob.check_partials(out_stream=None) for (of, wrt) in cpd['equal']: assert_almost_equal(cpd['equal'][of, wrt]['abs error'], 0.0, decimal=5) assert_check_partials(cpd, atol=1e-5, rtol=1e-5)
def test_basic_with_assert(self): from openmdao.api import Problem, Group, IndepVarComp, SimpleGADriver from openmdao.test_suite.components.branin import Branin prob = Problem() model = prob.model = Group() model.add_subsystem('p1', IndepVarComp('xC', 7.5)) model.add_subsystem('p2', IndepVarComp('xI', 0.0)) model.add_subsystem('comp', Branin()) model.connect('p2.xI', 'comp.x0') model.connect('p1.xC', 'comp.x1') model.add_design_var('p2.xI', lower=-5.0, upper=10.0) model.add_design_var('p1.xC', lower=0.0, upper=15.0) model.add_objective('comp.f') prob.driver = SimpleGADriver() prob.driver.options['bits'] = {'p1.xC': 8} prob.driver._randomstate = 1 prob.setup() prob.run_driver() # Optimal solution assert_rel_error(self, prob['comp.f'], 0.49399549, 1e-4)
def test_option_pop_size(self): from openmdao.api import Problem, Group, IndepVarComp, SimpleGADriver from openmdao.test_suite.components.branin import Branin prob = Problem() model = prob.model = Group() model.add_subsystem('p1', IndepVarComp('xC', 7.5)) model.add_subsystem('p2', IndepVarComp('xI', 0.0)) model.add_subsystem('comp', Branin()) model.connect('p2.xI', 'comp.x0') model.connect('p1.xC', 'comp.x1') model.add_design_var('p2.xI', lower=-5.0, upper=10.0) model.add_design_var('p1.xC', lower=0.0, upper=15.0) model.add_objective('comp.f') prob.driver = SimpleGADriver() prob.driver.options['bits'] = {'p1.xC': 8} prob.driver.options['pop_size'] = 10 prob.setup() prob.run_driver() # Optimal solution print('comp.f', prob['comp.f']) print('p2.xI', prob['p2.xI']) print('p1.xC', prob['p1.xC'])
def test_concurrent_eval_padded(self): # This test only makes sure we don't lock up if we overallocate our integer desvar space # to the next power of 2. class GAGroup(Group): def setup(self): self.add_subsystem('p1', IndepVarComp('x', 1.0)) self.add_subsystem('p2', IndepVarComp('y', 1.0)) self.add_subsystem('p3', IndepVarComp('z', 1.0)) self.add_subsystem('comp', ExecComp(['f = x + y + z'])) self.add_design_var('p1.x', lower=-100, upper=100) self.add_design_var('p2.y', lower=-100, upper=100) self.add_design_var('p3.z', lower=-100, upper=100) self.add_objective('comp.f') prob = Problem() prob.model = GAGroup() driver = prob.driver = SimpleGADriver() driver.options['max_gen'] = 5 driver.options['pop_size'] = 40 driver.options['run_parallel'] = True prob.setup() # No meaningful result from a short run; just make sure we don't hang. prob.run_driver()
def test_mixed_integer_branin(self): np.random.seed(1) prob = Problem() model = prob.model = Group() model.add_subsystem('p1', IndepVarComp('xC', 7.5)) model.add_subsystem('p2', IndepVarComp('xI', 0.0)) model.add_subsystem('comp', Branin()) model.connect('p2.xI', 'comp.x0') model.connect('p1.xC', 'comp.x1') model.add_design_var('p2.xI', lower=-5.0, upper=10.0) model.add_design_var('p1.xC', lower=0.0, upper=15.0) model.add_objective('comp.f') prob.driver = SimpleGADriver(max_gen=75, pop_size=25) prob.driver.options['bits'] = {'p1.xC': 8} prob.driver._randomstate = 1 prob.setup(check=False) prob.run_driver() # Optimal solution assert_rel_error(self, prob['comp.f'], 0.49398, 1e-4) self.assertTrue(int(prob['p2.xI']) in [3, -3])
def test_vector_desvars_multiobj(self): prob = Problem() indeps = prob.model.add_subsystem('indeps', IndepVarComp()) indeps.add_output('x', 3) indeps.add_output('y', [4.0, -4]) prob.model.add_subsystem('paraboloid1', ExecComp('f = (x+5)**2- 3')) prob.model.add_subsystem('paraboloid2', ExecComp('f = (y[0]-3)**2 + (y[1]-1)**2 - 3', y=[0, 0])) prob.model.connect('indeps.x', 'paraboloid1.x') prob.model.connect('indeps.y', 'paraboloid2.y') prob.driver = SimpleGADriver() prob.model.add_design_var('indeps.x', lower=-5, upper=5) prob.model.add_design_var('indeps.y', lower=[-10, 0], upper=[10, 3]) prob.model.add_objective('paraboloid1.f') prob.model.add_objective('paraboloid2.f') prob.setup() prob.run_driver() np.testing.assert_array_almost_equal(prob['indeps.x'], -5) np.testing.assert_array_almost_equal(prob['indeps.y'], [3, 1])
def test_sellar_idf(self): prob = Problem(SellarIDF()) prob.driver = ScipyOptimizeDriver(optimizer='SLSQP', disp=False) prob.setup() # check derivatives prob['dv.y1'] = 100 prob['equal.rhs:y1'] = 1 prob.run_model() cpd = prob.check_partials(out_stream=None) for (of, wrt) in cpd['equal']: assert_almost_equal(cpd['equal'][of, wrt]['abs error'], 0.0, decimal=5) assert_check_partials(cpd, atol=1e-5, rtol=1e-5) # check results prob.run_driver() assert_rel_error(self, prob['dv.x'], 0., 1e-5) assert_rel_error(self, prob['dv.z'], [1.977639, 0.], 1e-5) assert_rel_error(self, prob['obj_cmp.obj'], 3.18339395045, 1e-5) assert_almost_equal(prob['dv.y1'], 3.16) assert_almost_equal(prob['d1.y1'], 3.16) assert_almost_equal(prob['dv.y2'], 3.7552778) assert_almost_equal(prob['d2.y2'], 3.7552778) assert_almost_equal(prob['equal.y1'], 0.0) assert_almost_equal(prob['equal.y2'], 0.0)
def test_debug_print_option_totals_color(self): prob = Problem() prob.model = FanInGrouped() prob.model.linear_solver = LinearBlockGS() prob.model.sub.linear_solver = LinearBlockGS() prob.model.add_design_var('iv.x1', parallel_deriv_color='par_dv') prob.model.add_design_var('iv.x2', parallel_deriv_color='par_dv') prob.model.add_design_var('iv.x3') prob.model.add_objective('c3.y') prob.driver.options['debug_print'] = ['totals'] prob.setup(check=False, mode='fwd') prob.set_solver_print(level=0) prob.run_driver() indep_list = ['iv.x1', 'iv.x2', 'iv.x3'] unknown_list = ['c3.y'] stdout = sys.stdout strout = StringIO() sys.stdout = strout try: _ = prob.compute_totals(unknown_list, indep_list, return_format='flat_dict', debug_print=not prob.comm.rank) finally: sys.stdout = stdout output = strout.getvalue() if not prob.comm.rank: self.assertTrue('Solving color: par_dv (iv.x1, iv.x2)' in output) self.assertTrue('Solving variable: iv.x3' in output)
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_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_debug_print_option(self): from openmdao.api import Problem, Group, IndepVarComp, ScipyOptimizeDriver, ExecComp from openmdao.test_suite.components.paraboloid import Paraboloid 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) prob.run_driver()
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_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.setup(vector_class=PETScVector) prob.run_driver() J = prob.compute_totals(of=['Obj.obj', 'par.G1.c', 'par.G2.c'], wrt=['par.G1.x', 'par.G2.x']) assert_rel_error(self, J['Obj.obj', 'par.G1.x'], np.array([[2.0]]), 1e-6) assert_rel_error(self, J['Obj.obj', 'par.G2.x'], np.array([[2.0]]), 1e-6) assert_rel_error(self, J['par.G1.c', 'par.G1.x'], np.array([[1.0]]), 1e-6) assert_rel_error(self, J['par.G1.c', 'par.G2.x'], np.array([[0.0]]), 1e-6) assert_rel_error(self, J['par.G2.c', 'par.G1.x'], np.array([[0.0]]), 1e-6) assert_rel_error(self, J['par.G2.c', 'par.G2.x'], np.array([[1.0]]), 1e-6)
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_partials_no_compute(self): prob = Problem() model = prob.model model.add_subsystem('px', IndepVarComp('x', val=np.array([5.0, 4.0]))) ks_comp = model.add_subsystem('ks', KSComp(width=2)) model.connect('px.x', 'ks.g') prob.setup(check=False) prob.run_driver() # compute partials with the current model inputs inputs = { 'g': prob['ks.g'] } partials = {} ks_comp.compute_partials(inputs, partials) assert_rel_error(self, partials[('KS', 'g')], np.array([1., 0.]), 1e-6) # swap inputs and call compute partials again, without calling compute inputs['g'][0][0] = 4 inputs['g'][0][1] = 5 ks_comp.compute_partials(inputs, partials) assert_rel_error(self, partials[('KS', 'g')], np.array([0., 1.]), 1e-6)
def test_beam_stress(self): E = 1. L = 1. b = 0.1 volume = 0.01 max_bending = 100.0 num_cp = 5 num_elements = 25 num_load_cases = 2 prob = Problem(model=MultipointBeamGroup(E=E, L=L, b=b, volume=volume, max_bending = max_bending, num_elements=num_elements, num_cp=num_cp, num_load_cases=num_load_cases)) prob.driver = ScipyOptimizeDriver() prob.driver.options['optimizer'] = 'SLSQP' prob.driver.options['tol'] = 1e-9 prob.driver.options['disp'] = False prob.setup(mode='rev') prob.run_driver() stress0 = prob['parallel.sub_0.stress_comp.stress_0'] stress1 = prob['parallel.sub_0.stress_comp.stress_1'] # Test that the the maximum constraint prior to aggregation is close to "active". assert_rel_error(self, max(stress0), 100.0, tolerance=5e-2) assert_rel_error(self, max(stress1), 100.0, tolerance=5e-2) # Test that no original constraint is violated. self.assertTrue(np.all(stress0 < 100.0)) self.assertTrue(np.all(stress1 < 100.0))
def test_vectorized(self): prob = Problem() prob.model = model = Group() x = np.zeros((3, 5)) x[0, :] = np.array([3.0, 5.0, 11.0, 13.0, 17.0]) x[1, :] = np.array([13.0, 11.0, 5.0, 17.0, 3.0])*2 x[2, :] = np.array([11.0, 3.0, 17.0, 5.0, 13.0])*3 model.add_subsystem('px', IndepVarComp(name="x", val=x)) model.add_subsystem('ks', KSComp(width=5, vec_size=3)) model.connect('px.x', 'ks.g') model.add_design_var('px.x') model.add_constraint('ks.KS', upper=0.0) prob.setup(check=False) prob.run_driver() assert_rel_error(self, prob['ks.KS'][0], 17.0) assert_rel_error(self, prob['ks.KS'][1], 34.0) assert_rel_error(self, prob['ks.KS'][2], 51.0) partials = prob.check_partials(includes=['ks'], out_stream=None) for (of, wrt) in partials['ks']: assert_rel_error(self, partials['ks'][of, wrt]['abs error'][0], 0.0, 1e-6)
def test_deprecated_ks_component(self): # run same test as above, only with the deprecated component, # to ensure we get the warning and the correct answer. # self-contained, to be removed when class name goes away. from openmdao.components.ks_comp import KSComponent # deprecated prob = Problem() prob.model = model = Group() model.add_subsystem('px', IndepVarComp(name="x", val=np.ones((2,)))) model.add_subsystem('comp', DoubleArrayComp()) msg = "'KSComponent' has been deprecated. Use 'KSComp' instead." with assert_warning(DeprecationWarning, msg): model.add_subsystem('ks', KSComponent(width=2)) model.connect('px.x', 'comp.x1') model.connect('comp.y2', 'ks.g') model.add_design_var('px.x') model.add_objective('comp.y1') model.add_constraint('ks.KS', upper=0.0) prob.setup(check=False) prob.run_driver() assert_rel_error(self, max(prob['comp.y2']), prob['ks.KS'][0])
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() assert_rel_error(self, prob['inputs_comp.h'], [0.14915754, 0.14764328, 0.14611321, 0.14456715, 0.14300421, 0.14142417, 0.13982611, 0.13820976, 0.13657406, 0.13491866, 0.13324268, 0.13154528, 0.12982575, 0.12808305, 0.12631658, 0.12452477, 0.12270701, 0.12086183, 0.11898809, 0.11708424, 0.11514904, 0.11318072, 0.11117762, 0.10913764, 0.10705891, 0.10493903, 0.10277539, 0.10056526, 0.09830546, 0.09599246, 0.09362243, 0.09119084, 0.08869265, 0.08612198, 0.08347229, 0.08073573, 0.07790323, 0.07496382, 0.07190453, 0.06870925, 0.0653583, 0.06182632, 0.05808044, 0.05407658, 0.04975295, 0.0450185, 0.03972912, 0.03363155, 0.02620192, 0.01610863], 1e-4)
def test_unsupported_equality(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'] = 'COBYLA' prob.driver.options['tol'] = 1e-9 prob.driver.options['disp'] = False 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', equals=-15.0) prob.setup(check=False) with self.assertRaises(Exception) as raises_cm: prob.run_driver() exception = raises_cm.exception msg = "Constraints of type 'eq' not handled by COBYLA." self.assertEqual(exception.args[0], msg)
def test_multipoint_with_coloring(self): size = 10 num_pts = self.N_PROCS np.random.seed(11) p = Problem() p.driver = pyOptSparseDriver() p.driver.options['optimizer'] = OPTIMIZER p.driver.options['dynamic_simul_derivs'] = True if OPTIMIZER == 'SNOPT': p.driver.opt_settings['Major iterations limit'] = 100 p.driver.opt_settings['Major feasibility tolerance'] = 1.0E-6 p.driver.opt_settings['Major optimality tolerance'] = 1.0E-6 p.driver.opt_settings['iSumm'] = 6 model = p.model for i in range(num_pts): model.add_subsystem('indep%d' % i, IndepVarComp('x', val=np.ones(size))) model.add_design_var('indep%d.x' % i) par1 = model.add_subsystem('par1', ParallelGroup()) for i in range(num_pts): mat = _get_mat(5, size) par1.add_subsystem('comp%d' % i, ExecComp('y=A.dot(x)', A=mat, x=np.ones(size), y=np.ones(5))) model.connect('indep%d.x' % i, 'par1.comp%d.x' % i) par2 = model.add_subsystem('par2', ParallelGroup()) for i in range(num_pts): mat = _get_mat(size, 5) par2.add_subsystem('comp%d' % i, ExecComp('y=A.dot(x)', A=mat, x=np.ones(5), y=np.ones(size))) model.connect('par1.comp%d.y' % i, 'par2.comp%d.x' % i) par2.add_constraint('comp%d.y' % i, lower=-1.) model.add_subsystem('normcomp%d' % i, ExecComp("y=sum(x*x)", x=np.ones(size))) model.connect('par2.comp%d.y' % i, 'normcomp%d.x' % i) model.add_subsystem('obj', ExecComp("y=" + '+'.join(['x%d' % i for i in range(num_pts)]))) for i in range(num_pts): model.connect('normcomp%d.y' % i, 'obj.x%d' % i) model.add_objective('obj.y') p.setup() p.run_driver() J = p.compute_totals() for i in range(num_pts): vname = 'par2.comp%d.A' % i if vname in model._var_abs_names['input']: norm = np.linalg.norm(J['par2.comp%d.y'%i,'indep%d.x'%i] - getattr(par2, 'comp%d'%i)._inputs['A'].dot(getattr(par1, 'comp%d'%i)._inputs['A'])) self.assertLess(norm, 1.e-7) elif vname not in model._var_allprocs_abs_names['input']: self.fail("Can't find variable par2.comp%d.A" % i)
def benchmark_cadre_mdp_derivs_full(self): # These numbers are for the CADRE problem in the paper. n = 1500 m = 300 npts = 6 # instantiate model model = CADRE_MDP_Group(n=n, m=m, npts=npts) # add design variables and constraints to each CADRE instance. names = ['pt%s' % i for i in range(npts)] for i, name in enumerate(names): model.add_design_var('%s.CP_Isetpt' % name, lower=0., upper=0.4) model.add_design_var('%s.CP_gamma' % name, lower=0, upper=np.pi/2.) model.add_design_var('%s.CP_P_comm' % name, lower=0., upper=25.) model.add_design_var('%s.iSOC' % name, indices=[0], lower=0.2, upper=1.) model.add_constraint('%s.ConCh' % name, upper=0.0) model.add_constraint('%s.ConDs' % name, upper=0.0) model.add_constraint('%s.ConS0' % name, upper=0.0) model.add_constraint('%s.ConS1' % name, upper=0.0) model.add_constraint('%s_con5.val' % name, equals=0.0) # add broadcast parameters model.add_design_var('bp.cellInstd', lower=0., upper=1.0) model.add_design_var('bp.finAngle', lower=0., upper=np.pi/2.) model.add_design_var('bp.antAngle', lower=-np.pi/4, upper=np.pi/4) # add objective model.add_objective('obj.val') # create problem prob = Problem(model) prob.setup() # for serial execution, we will use LinearBlockGS model.linear_solver = LinearBlockGS() model.parallel.linear_solver = LinearBlockGS() model.parallel.pt0.linear_solver = LinearBlockGS() model.parallel.pt1.linear_solver = LinearBlockGS() model.parallel.pt2.linear_solver = LinearBlockGS() model.parallel.pt3.linear_solver = LinearBlockGS() model.parallel.pt4.linear_solver = LinearBlockGS() model.parallel.pt5.linear_solver = LinearBlockGS() # run prob.set_solver_print(0) prob.run_driver() # ---------------------------------------- # This is what we are really profiling # ---------------------------------------- J = prob.compute_totals() assert_rel_error(self, J['obj.val', 'bp.antAngle'][0][0], 67.15777407, 1e-4) assert_rel_error(self, J['obj.val', 'parallel.pt1.design.CP_gamma'][-1][-1], -0.62410223816776056, 1e-4)
def test_bug_in_eq_constraints(self): # We were getting extra constraints created because lower and upper are maxfloat instead of # None when unused. p = Problem(model=SineFitter()) p.driver = ScipyOptimizeDriver() p.setup(check=False) p.run_driver() max_defect = np.max(np.abs(p['defect.defect'])) assert_rel_error(self, max_defect, 0.0, 1e-10)
def test_simple_test_func(self): np.random.seed(11) class MyComp(ExplicitComponent): def setup(self): self.add_input('x', np.zeros((2, ))) self.add_output('a', 0.0) self.add_output('b', 0.0) self.add_output('c', 0.0) self.add_output('d', 0.0) def compute(self, inputs, outputs): x = inputs['x'] outputs['a'] = (2.0*x[0] - 3.0*x[1])**2 outputs['b'] = 18.0 - 32.0*x[0] + 12.0*x[0]**2 + 48.0*x[1] - 36.0*x[0]*x[1] + 27.0*x[1]**2 outputs['c'] = (x[0] + x[1] + 1.0)**2 outputs['d'] = 19.0 - 14.0*x[0] + 3.0*x[0]**2 - 14.0*x[1] + 6.0*x[0]*x[1] + 3.0*x[1]**2 prob = Problem() prob.model = model = Group() model.add_subsystem('px', IndepVarComp('x', np.array([0.2, -0.2]))) model.add_subsystem('comp', MyComp()) model.add_subsystem('obj', ExecComp('f=(30 + a*b)*(1 + c*d)')) model.connect('px.x', 'comp.x') model.connect('comp.a', 'obj.a') model.connect('comp.b', 'obj.b') model.connect('comp.c', 'obj.c') model.connect('comp.d', 'obj.d') # Played with bounds so we don't get subtractive cancellation of tiny numbers. model.add_design_var('px.x', lower=np.array([0.2, -1.0]), upper=np.array([1.0, -0.2])) model.add_objective('obj.f') prob.driver = SimpleGADriver() prob.driver.options['bits'] = {'px.x': 16} prob.driver.options['max_gen'] = 75 prob.driver._randomstate = 11 prob.setup(check=False) prob.run_driver() # TODO: Satadru listed this solution, but I get a way better one. # Solution: xopt = [0.2857, -0.8571], fopt = 23.2933 assert_rel_error(self, prob['obj.f'], 12.37341703, 1e-4) assert_rel_error(self, prob['px.x'][0], 0.2, 1e-4) assert_rel_error(self, prob['px.x'][1], -0.88654333, 1e-4)
def test_debug_print_response_physical(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 + 1', 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) model.add_design_var('p2.y', indices=[1], lower=-50.0, upper=50.0) model.add_objective('comp.f_xy', index=1, ref=1.5) model.add_constraint('con.c', indices=[1], upper=-15.0, ref=1.02) prob.setup(check=False) prob.driver.options['debug_print'] = ['objs', 'nl_cons'] 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], "{'con.c': array([ 1.])}") self.assertEqual(output[6], "{'comp.f_xy': array([ 7622.])}")
def test_fan_in_grouped(self): size = 3 prob = Problem() prob.model = root = Group() root.add_subsystem('P1', IndepVarComp('x', numpy.ones(size, dtype=float))) root.add_subsystem('P2', IndepVarComp('x', numpy.ones(size, dtype=float))) sub = root.add_subsystem('sub', ParallelGroup()) sub.add_subsystem('C1', ExecComp(['y=-2.0*x'], x=numpy.zeros(size, dtype=float), y=numpy.zeros(size, dtype=float))) sub.add_subsystem('C2', ExecComp(['y=5.0*x'], x=numpy.zeros(size, dtype=float), y=numpy.zeros(size, dtype=float))) root.add_subsystem('C3', DistribExecComp(['y=3.0*x1+7.0*x2', 'y=1.5*x1+3.5*x2'], arr_size=size, x1=numpy.zeros(size, dtype=float), x2=numpy.zeros(size, dtype=float), y=numpy.zeros(size, dtype=float))) root.add_subsystem('C4', ExecComp(['y=x'], x=numpy.zeros(size, dtype=float), y=numpy.zeros(size, dtype=float))) root.connect("sub.C1.y", "C3.x1") root.connect("sub.C2.y", "C3.x2") root.connect("P1.x", "sub.C1.x") root.connect("P2.x", "sub.C2.x") root.connect("C3.y", "C4.x") root.linear_solver = LinearBlockGS() sub.linear_solver = LinearBlockGS() prob.set_solver_print(0) prob.setup(mode='fwd') prob.run_driver() diag1 = numpy.diag([-6.0, -6.0, -3.0]) diag2 = numpy.diag([35.0, 35.0, 17.5]) J = prob.compute_totals(of=['C4.y'], wrt=['P1.x', 'P2.x']) assert_rel_error(self, J['C4.y', 'P1.x'], diag1, 1e-6) assert_rel_error(self, J['C4.y', 'P2.x'], diag2, 1e-6) prob.setup(check=False, mode='rev') prob.run_driver() J = prob.compute_totals(of=['C4.y'], wrt=['P1.x', 'P2.x']) assert_rel_error(self, J['C4.y', 'P1.x'], diag1, 1e-6) assert_rel_error(self, J['C4.y', 'P2.x'], diag2, 1e-6)
def main(tot_iter): objectives = { 0: "compliance", 1: "stress", 2: "conduction", 3: "coupled_heat" } loadFolder = loadFolder0 + "" restart_iter = 66 import os try: os.mkdir(loadFolder + 'restart_' + str(restart_iter)) except: pass try: os.mkdir(loadFolder + 'restart_' + str(restart_iter) + '/figs') except: pass inspctFlag = False if tot_iter < 0: inspctFlag = True tot_iter = restart_iter + 1 # select which problem to solve obj_flag = 3 print(locals()) print("solving %s problem" % objectives[obj_flag]) print("restarting from %d ..." % restart_iter) fname0 = loadFolder + 'phi%03i.pkl' % restart_iter with open(fname0, 'rb') as f: raw = pickle.load(f) phi0 = raw['phi'] fname0 = loadFolder0 + 'const.pkl' with open(fname0, 'rb') as f: raw = pickle.load(f) # nodes = raw['mesh'] nodes = raw['nodes'] elem = raw['elem'] GF_e = raw['GF_e'] GF_t = raw['GF_t'] BCid_e = raw['BCid_e'] BCid_t = raw['BCid_t'] E = raw['E'] nu = raw['nu'] f = raw['f'] K_cond = raw['K_cond'] alpha = raw['alpha'] nelx = raw['nelx'] nely = raw['nely'] length_x = raw['length_x'] length_y = raw['length_y'] coord_e = raw['coord_e'] tol_e = raw['tol_e'] ######################################################## ################# FEA #################### ######################################################## # NB: only Q4 elements + integer-spaced mesh are assumed ls2fe_x = length_x / float(nelx) ls2fe_y = length_y / float(nely) num_nodes_x = nelx + 1 num_nodes_y = nely + 1 nELEM = nelx * nely nNODE = num_nodes_x * num_nodes_y # Declare FEA object (OpenLSTO_FEA) ====================== fea_solver = py_FEA(lx=length_x, ly=length_y, nelx=nelx, nely=nely, element_order=2) [node, elem, elem_dof] = fea_solver.get_mesh() # validate the mesh if nELEM != elem.shape[0]: error("error found in the element") if nNODE != node.shape[0]: error("error found in the node") nDOF_t = nNODE * 1 # each node has one temperature DOF nDOF_e = nNODE * 2 # each node has two displacement DOFs # constitutive properties ================================= fea_solver.set_material(E=E, nu=nu, rho=1.0) # Boundary Conditions ===================================== fea_solver.set_boundary(coord=coord_e, tol=tol_e) BCid_e = fea_solver.get_boundary() nDOF_e_wLag = nDOF_e + len(BCid_e) # elasticity DOF nDOF_t_wLag = nDOF_t + len(BCid_t) # temperature DOF ######################################################## ################# LSM #################### ######################################################## movelimit = 0.5 # Declare Level-set object lsm_solver = py_LSM(nelx=nelx, nely=nely, moveLimit=movelimit) lsm_solver.add_holes([], [], []) lsm_solver.set_levelset() lsm_solver.set_phi_re(phi0) lsm_solver.reinitialise() for i_HJ in range(restart_iter, tot_iter): (bpts_xy, areafraction, seglength) = lsm_solver.discretise() ######################################################## ############### OpenMDAO ################ ######################################################## # Declare Group if (objectives[obj_flag] == "compliance"): model = ComplianceGroup(fea_solver=fea_solver, lsm_solver=lsm_solver, nelx=nelx, nely=nely, force=GF_e, movelimit=movelimit, BCid=BCid_e) elif (objectives[obj_flag] == "stress"): # TODO: sensitivity has not been verified yet model = StressGroup(fea_solver=fea_solver, lsm_solver=lsm_solver, nelx=nelx, nely=nely, force=GF_e, movelimit=movelimit, pval=5.0, E=E, nu=nu) elif (objectives[obj_flag] == "conduction"): model = ConductionGroup(fea_solver=fea_solver, lsm_solver=lsm_solver, nelx=nelx, nely=nely, force=GF_t, movelimit=movelimit, K_cond=K_cond, BCid=BCid_t) elif (objectives[obj_flag] == "coupled_heat"): model = HeatCouplingGroup( fea_solver=fea_solver, lsm_solver=lsm_solver, nelx=nelx, nely=nely, force_e=GF_e, force_t=GF_t, movelimit=movelimit, K_cond=K_cond, BCid_e=BCid_e, BCid_t=BCid_t, E=E, nu=nu, alpha=alpha, w=0.0 ) # if w = 0.0, thermoelastic + conduction, if w = 1.0, conduction only # One Problem per one OpenMDAO object prob = Problem(model) # optimize ... prob.driver = pyOptSparseDriver() prob.driver.options['optimizer'] = 'IPOPT' prob.driver.opt_settings['linear_solver'] = 'ma27' prob.setup(check=False) prob.run_model() # Total derivative using MAUD ===================== total = prob.compute_totals() if (objectives[obj_flag] == "compliance"): ff = total['compliance_comp.compliance', 'inputs_comp.Vn'][0] gg = total['weight_comp.weight', 'inputs_comp.Vn'][0] elif (objectives[obj_flag] == "stress"): ff = total['pnorm_comp.pnorm', 'inputs_comp.Vn'][0] gg = total['weight_comp.weight', 'inputs_comp.Vn'][0] elif (objectives[obj_flag] == "conduction"): ff = total['compliance_comp.compliance', 'inputs_comp.Vn'][0] gg = total['weight_comp.weight', 'inputs_comp.Vn'][0] elif (objectives[obj_flag] == "coupled_heat"): ff = total['objective_comp.y', 'inputs_comp.Vn'][0] gg = total['weight_comp.weight', 'inputs_comp.Vn'][0] nBpts = int(bpts_xy.shape[0]) # # WIP checking sensitivity 10/23 Sf = -ff[:nBpts] # equal to M2DO-perturbation Cf = np.multiply(Sf, seglength) Sg = -gg[:nBpts] Cg = np.multiply(Sf, seglength) # ## WIP # previous ver. # Cf = -ff[:nBpts] # Cg = -gg[:nBpts] # Sf = np.divide(Cf, seglength) # Sg = np.divide(Cg, seglength) # bracketing Sf and Sg Sg[Sg < -1.5] = -1.5 Sg[Sg > 0.5] = 0.5 # Sg[:] = -1.0 Cg = np.multiply(Sg, seglength) ######################################################## ############## suboptimize ################ ######################################################## if 1: suboptim = Solvers(bpts_xy=bpts_xy, Sf=Sf, Sg=Sg, Cf=Cf, Cg=Cg, length_x=length_x, length_y=length_y, areafraction=areafraction, movelimit=movelimit) # suboptimization if 1: # simplex Bpt_Vel = suboptim.simplex(isprint=False) else: # bisection.. Bpt_Vel = suboptim.bisection(isprint=False) timestep = 1.0 elif 1: # works okay now. bpts_sens = np.zeros((nBpts, 2)) # issue: scaling problem # bpts_sens[:, 0] = Sf bpts_sens[:, 1] = Sg lsm_solver.set_BptsSens(bpts_sens) scales = lsm_solver.get_scale_factors() (lb2, ub2) = lsm_solver.get_Lambda_Limits() constraint_distance = (0.4 * nelx * nely) - areafraction.sum() model = LSM2D_slpGroup(lsm_solver=lsm_solver, num_bpts=nBpts, ub=ub2, lb=lb2, Sf=bpts_sens[:, 0], Sg=bpts_sens[:, 1], constraintDistance=constraint_distance, movelimit=movelimit) subprob = Problem(model) subprob.setup() subprob.driver = ScipyOptimizeDriver() subprob.driver.options['optimizer'] = 'SLSQP' subprob.driver.options['disp'] = True subprob.driver.options['tol'] = 1e-10 subprob.run_driver() lambdas = subprob['inputs_comp.lambdas'] displacements_ = subprob['displacement_comp.displacements'] displacements_[displacements_ > movelimit] = movelimit displacements_[displacements_ < -movelimit] = -movelimit timestep = 1.0 #abs(lambdas[0]*scales[0]) Bpt_Vel = displacements_ / timestep # print(timestep) del subprob else: # branch: perturb-suboptim bpts_sens = np.zeros((nBpts, 2)) # issue: scaling problem # bpts_sens[:, 0] = Sf bpts_sens[:, 1] = Sg lsm_solver.set_BptsSens(bpts_sens) scales = lsm_solver.get_scale_factors() (lb2, ub2) = lsm_solver.get_Lambda_Limits() constraint_distance = (0.4 * nelx * nely) - areafraction.sum() constraintDistance = np.array([constraint_distance]) scaled_constraintDist = lsm_solver.compute_scaledConstraintDistance( constraintDistance) def objF_nocallback(x): displacement = lsm_solver.compute_displacement(x) displacement_np = np.asarray(displacement) return lsm_solver.compute_delF(displacement_np) def conF_nocallback(x): displacement = lsm_solver.compute_displacement(x) displacement_np = np.asarray(displacement) return lsm_solver.compute_delG(displacement_np, scaled_constraintDist, 1) cons = ({'type': 'eq', 'fun': lambda x: conF_nocallback(x)}) res = sp_optim.minimize(objF_nocallback, np.zeros(2), method='SLSQP', options={'disp': True}, bounds=((lb2[0], ub2[0]), (lb2[1], ub2[1])), constraints=cons) lambdas = res.x displacements_ = lsm_solver.compute_unscaledDisplacement(lambdas) displacements_[displacements_ > movelimit] = movelimit displacements_[displacements_ < -movelimit] = -movelimit timestep = 1.0 #abs(lambdas[0]*scales[0]) Bpt_Vel = displacements_ / timestep # scaling # Bpt_Vel = Bpt_Vel#/np.max(np.abs(Bpt_Vel)) lsm_solver.advect(Bpt_Vel, timestep) lsm_solver.reinitialise() if not inspctFlag: # quickplot plt.figure(1) plt.clf() plt.scatter(bpts_xy[:, 0], bpts_xy[:, 1], 10) plt.axis("equal") plt.savefig(loadFolder + 'restart_' + str(restart_iter) + "/" + "figs/bpts_%d.png" % i_HJ) print('loop %d is finished' % i_HJ) area = areafraction.sum() / (nelx * nely) try: u = prob['temp_comp.disp'] compliance = np.dot(u, GF_t[:nNODE]) except: u = prob['disp_comp.disp'] # compliance = np.dot(u, GF_e[:nDOF_e]) pass if 1: # quickplot plt.figure(1) plt.clf() plt.scatter(bpts_xy[:, 0], bpts_xy[:, 1], 10) plt.axis("equal") plt.savefig(loadFolder + 'restart_' + str(restart_iter) + "/" + "figs/bpts_%d.png" % i_HJ) if obj_flag == 3 or obj_flag == 2: plt.figure(2) plt.clf() [xx, yy] = np.meshgrid(range(0, 161), range(0, 81)) plt.contourf(xx, yy, np.reshape(u, [81, 161])) plt.colorbar() plt.axis("equal") plt.scatter(bpts_xy[:, 0], bpts_xy[:, 1], 5) plt.savefig(loadFolder + 'restart_' + str(restart_iter) + "/" + "figs/temp_%d.png" % i_HJ) if (objectives[obj_flag] == "compliance" and not inspctFlag): compliance = prob['compliance_comp.compliance'] print(compliance, area) fid = open( loadFolder + 'restart_' + str(restart_iter) + "/" + "log.txt", "a+") fid.write(str(compliance) + ", " + str(area) + "\n") fid.close() elif (objectives[obj_flag] == "stress" and not inspctFlag): print(prob['pnorm_comp.pnorm'][0], area) fid = open( loadFolder + 'restart_' + str(restart_iter) + "/" + "log.txt", "a+") fid.write( str(prob['pnorm_comp.pnorm'][0]) + ", " + str(area) + "\n") fid.close() elif (objectives[obj_flag] == "coupled_heat" and not inspctFlag): obj1 = prob['objective_comp.x1'][0] obj2 = prob['objective_comp.x2'][0] obj = prob['objective_comp.y'][0] print([obj1, obj2, obj, area]) fid = open( loadFolder + 'restart_' + str(restart_iter) + "/" + "log.txt", "a+") fid.write( str(obj1) + ", " + str(obj2) + ", " + str(obj) + ", " + str(area) + "\n") fid.close() # Saving Phi phi = lsm_solver.get_phi() if not inspctFlag: raw = {} raw['phi'] = phi filename = loadFolder + 'restart_' + str( restart_iter) + '/' + 'phi%03i.pkl' % i_HJ with open(filename, 'wb') as f: pickle.dump(raw, f) del model del prob mem = virtual_memory() print(str(mem.available / 1024. / 1024. / 1024.) + "GB") if mem.available / 1024. / 1024. / 1024. < 3.0: print("memory explodes at iteration %3i " % i_HJ) exit()
def run_open_mdao(): if USE_SCALING: # prepare scaling global offset_weight global offset_stress global scale_weight global scale_stress runner = MultiRun(use_calcu=not USE_ABA, use_aba=USE_ABA, non_liner=False, project_name_prefix=PROJECT_NAME_PREFIX, force_recalc=False) p1 = runner.new_project_r_t(range_rib[0], range_shell[0]) runner.run_project(p1) offset_weight = p1.calc_wight() max_stress = p1.resultsAba.stressMisesMax p2 = runner.new_project_r_t(range_rib[1], range_shell[1]) runner.run_project(p2) max_weight = p2.calc_wight() offset_stress = p2.resultsAba.stressMisesMax scale_weight = (max_weight - offset_weight) scale_stress = (max_stress - offset_stress) write_mdao_log('iter,time,ribs(float),ribs,shell,stress,weight') model = Group() indeps = IndepVarComp() indeps.add_output('ribs', (20 - offset_rib) / scale_rib) indeps.add_output('shell', (0.0025 - offset_shell) / scale_shell) model.add_subsystem('des_vars', indeps) model.add_subsystem('wing', WingStructure()) model.connect('des_vars.ribs', ['wing.ribs', 'con_cmp1.ribs']) model.connect('des_vars.shell', 'wing.shell') # design variables, limits and constraints model.add_design_var('des_vars.ribs', lower=(range_rib[0] - offset_rib) / scale_rib, upper=(range_rib[1] - offset_rib) / scale_rib) model.add_design_var('des_vars.shell', lower=(range_shell[0] - offset_shell) / scale_shell, upper=(range_shell[1] - offset_shell) / scale_shell) # objective model.add_objective('wing.weight', scaler=1) # constraint print('constrain stress: ' + str((max_shear_strength - offset_stress) / scale_stress)) model.add_constraint('wing.stress', upper=(max_shear_strength - offset_stress) / scale_stress) model.add_subsystem('con_cmp1', ExecComp('con1 = (ribs * ' + str(scale_rib) + ') - int(ribs[0] * ' + str(scale_rib) + ')')) model.add_constraint('con_cmp1.con1', upper=.5) prob = Problem(model) # setup the optimization if USE_PYOPTSPARSE: prob.driver = pyOptSparseDriver() prob.driver.options['optimizer'] = OPTIMIZER prob.driver.opt_settings['SwarmSize'] = 6 prob.driver.opt_settings['stopIters'] = 5 else: prob.driver = ScipyOptimizeDriver() prob.driver.options['optimizer'] = OPTIMIZER # ['Nelder-Mead', 'Powell', 'CG', 'BFGS', 'Newton-CG', 'L-BFGS-B', 'TNC', 'COBYLA', 'SLSQP'] prob.driver.options['tol'] = TOL prob.driver.options['disp'] = True prob.driver.options['maxiter'] = 3 #prob.driver.opt_settings['etol'] = 100 prob.setup() prob.set_solver_print(level=0) prob.model.approx_totals() prob.setup(check=True, mode='fwd') prob.run_driver() print('done') print('ribs: ' + str((prob['wing.ribs'] * scale_rib) + offset_rib)) print('shell: ' + str((prob['wing.shell'] * scale_shell) + offset_shell) + ' m') print('weight= ' + str((prob['wing.weight'] * scale_weight) + offset_weight)) print('stress= ' + str((prob['wing.stress'] * scale_stress) + offset_stress) + ' ~ ' + str(prob['wing.stress'])) print('execution counts wing: ' + str(prob.model.wing.executionCounter))
def test(self): import numpy as np from openaerostruct.geometry.utils import generate_mesh from openaerostruct.geometry.geometry_group import Geometry from openaerostruct.integration.aerostruct_groups import Aerostruct, AerostructPoint from openmdao.api import IndepVarComp, Problem, Group, SqliteRecorder # Create a dictionary to store options about the surface mesh_dict = { 'num_y': 5, 'num_x': 2, 'wing_type': 'CRM', 'symmetry': True, 'num_twist_cp': 5 } mesh, twist_cp = generate_mesh(mesh_dict) surface = { # 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': 'tube', 'thickness_cp': np.array([.1, .2, .3]), 'twist_cp': twist_cp, 'mesh': mesh, 'num_x': mesh.shape[0], 'num_y': mesh.shape[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.015, # CD of the surface at alpha=0 # Airfoil properties for viscous drag calculation 'k_lam': 0.05, # percentage of chord with laminar # flow, used for viscous drag 't_over_c_cp': np.array([0.15]), # thickness over chord ratio (NACA0015) 'c_max_t': .303, # chordwise location of maximum (NACA0015) # thickness 'with_viscous': True, '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': 2., 'struct_weight_relief': False, # True to add the weight of the structure to the loads on the structure # Constraints 'exact_failure_constraint': False, # if false, use KS function } # 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('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('CT', val=9.80665 * 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('a', 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=['*']) aerostruct_group = Aerostruct(surface=surface) name = 'wing' # Add tmp_group to the problem with the name of the surface. prob.model.add_subsystem(name, aerostruct_group, promotes_inputs=['load_factor']) point_name = 'AS_point_0' # Create the aero point group and add it to the model AS_point = AerostructPoint(surfaces=[surface]) prob.model.add_subsystem(point_name, AS_point, promotes_inputs=[ 'v', 'alpha', 'M', 're', 'rho', 'CT', 'R', 'W0', 'a', 'empty_cg', '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 + '.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_weight', point_name + '.' + 'total_perf.' + name + '_structural_weight') 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 recorder = SqliteRecorder("aerostruct.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_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(check=True) prob.run_driver() assert_rel_error(self, prob['AS_point_0.fuelburn'][0], 104400.0251030171, 1e-8)
def test_dv_at_apogee(self): prob = Problem(model=Group()) model = prob.model ivc = model.add_subsystem('ivc', IndepVarComp(), promotes_outputs=['*']) ivc.add_output('mu', val=0.0, units='km**3/s**2') ivc.add_output('r1', val=0.0, units='km') ivc.add_output('r2', val=0.0, units='km') ivc.add_output('dinc1', val=0.0, units='deg') ivc.add_output('dinc2', val=0.0, units='deg') model.add_subsystem('leo', subsys=VCircComp()) model.add_subsystem('geo', subsys=VCircComp()) model.add_subsystem('transfer', subsys=TransferOrbitComp()) model.connect('r1', ['leo.r', 'transfer.rp']) model.connect('r2', ['geo.r', 'transfer.ra']) model.connect('mu', ['leo.mu', 'geo.mu', 'transfer.mu']) model.add_subsystem('dv1', subsys=DeltaVComp()) model.connect('leo.vcirc', 'dv1.v1') model.connect('transfer.vp', 'dv1.v2') model.connect('dinc1', 'dv1.dinc') model.add_subsystem('dv2', subsys=DeltaVComp()) model.connect('transfer.va', 'dv2.v1') model.connect('geo.vcirc', 'dv2.v2') model.connect('dinc2', 'dv2.dinc') model.add_subsystem('dv_total', subsys=ExecComp('delta_v=dv1+dv2', delta_v={'units': 'km/s'}, dv1={'units': 'km/s'}, dv2={'units': 'km/s'}), promotes=['delta_v']) model.connect('dv1.delta_v', 'dv_total.dv1') model.connect('dv2.delta_v', 'dv_total.dv2') model.add_subsystem('dinc_total', subsys=ExecComp('dinc=dinc1+dinc2', dinc={'units': 'deg'}, dinc1={'units': 'deg'}, dinc2={'units': 'deg'}), promotes=['dinc']) model.connect('dinc1', 'dinc_total.dinc1') model.connect('dinc2', 'dinc_total.dinc2') prob.driver = ScipyOptimizer() model.add_design_var('dinc1', lower=0, upper=28.5) model.add_design_var('dinc2', lower=0, upper=28.5) model.add_constraint('dinc', lower=28.5, upper=28.5, scaler=1.0) model.add_objective('delta_v', scaler=1.0) # Setup the problem prob.setup() prob['mu'] = 398600.4418 prob['r1'] = 6778.137 prob['r2'] = 42164.0 prob['dinc1'] = 0 prob['dinc2'] = 28.5 # Execute the model with the given inputs prob.run_model() print('Delta-V (km/s):', prob['delta_v'][0]) print('Inclination change split (deg):', prob['dinc1'][0], prob['dinc2'][0]) print() prob.run_driver() print() print('Optimized Delta-V (km/s):', prob['delta_v'][0]) print('Inclination change split (deg):', prob['dinc1'][0], prob['dinc2'][0])
def ex_aircraft_steady_flight(optimizer='SLSQP', transcription='gauss-lobatto'): p = Problem(model=Group()) p.driver = pyOptSparseDriver() p.driver.options['optimizer'] = optimizer p.driver.options['dynamic_simul_derivs'] = True if optimizer == 'SNOPT': p.driver.opt_settings['Major iterations limit'] = 1000 p.driver.opt_settings['Major feasibility tolerance'] = 1.0E-6 p.driver.opt_settings['Major optimality tolerance'] = 1.0E-6 p.driver.opt_settings["Linesearch tolerance"] = 0.10 p.driver.opt_settings['iSumm'] = 6 num_seg = 15 seg_ends, _ = lgl(num_seg + 1) phase = Phase(transcription, ode_class=AircraftODE, num_segments=num_seg, segment_ends=seg_ends, transcription_order=5, compressed=False) # Pass Reference Area from an external source assumptions = p.model.add_subsystem('assumptions', IndepVarComp()) assumptions.add_output('S', val=427.8, units='m**2') assumptions.add_output('mass_empty', val=1.0, units='kg') assumptions.add_output('mass_payload', val=1.0, units='kg') p.model.add_subsystem('phase0', phase) phase.set_time_options(initial_bounds=(0, 0), duration_bounds=(300, 10000), duration_ref=3600) phase.set_state_options('range', units='NM', fix_initial=True, fix_final=False, scaler=0.001, defect_scaler=1.0E-2) phase.set_state_options('mass_fuel', units='lbm', fix_initial=True, fix_final=True, upper=1.5E5, lower=0.0, scaler=1.0E-5, defect_scaler=1.0E-1) phase.add_control('alt', units='kft', opt=True, lower=0.0, upper=50.0, rate_param='climb_rate', rate_continuity=True, rate_continuity_scaler=1.0, rate2_continuity=True, rate2_continuity_scaler=1.0, ref=1.0, fix_initial=True, fix_final=True) phase.add_control('mach', units=None, opt=False) phase.add_input_parameter('S', units='m**2') phase.add_input_parameter('mass_empty', units='kg') phase.add_input_parameter('mass_payload', units='kg') phase.add_path_constraint('propulsion.tau', lower=0.01, upper=1.0) phase.add_path_constraint('alt_rate', units='ft/min', lower=-3000, upper=3000, ref=3000) p.model.connect('assumptions.S', 'phase0.input_parameters:S') p.model.connect('assumptions.mass_empty', 'phase0.input_parameters:mass_empty') p.model.connect('assumptions.mass_payload', 'phase0.input_parameters:mass_payload') phase.add_objective('range', loc='final', ref=-1.0) p.model.linear_solver = DirectSolver(assemble_jac=True) p.setup() p['phase0.t_initial'] = 0.0 p['phase0.t_duration'] = 3600.0 p['phase0.states:range'] = phase.interpolate(ys=(0, 1000.0), nodes='state_input') p['phase0.states:mass_fuel'] = phase.interpolate(ys=(30000, 0), nodes='state_input') p['phase0.controls:mach'][:] = 0.8 p['phase0.controls:alt'][:] = 10.0 p['assumptions.S'] = 427.8 p['assumptions.mass_empty'] = 0.15E6 p['assumptions.mass_payload'] = 84.02869 * 400 p.run_driver() exp_out = phase.simulate( times=np.linspace(0, p['phase0.t_duration'], 500), record=True, record_file='test_ex_aircraft_steady_flight_rec.db') plt.plot(phase.get_values('time', nodes='all'), phase.get_values('alt', nodes='all'), 'ro') plt.plot(exp_out.get_values('time'), exp_out.get_values('alt'), 'b-') plt.suptitle('altitude vs time') plt.figure() plt.plot(phase.get_values('time', nodes='all'), phase.get_values('alt_rate', nodes='all', units='ft/min'), 'ro') plt.plot(exp_out.get_values('time'), exp_out.get_values('alt_rate', units='ft/min'), 'b-') plt.suptitle('altitude rate vs time') plt.figure() plt.plot(phase.get_values('time', nodes='all'), phase.get_values('mass_fuel', nodes='all'), 'ro') plt.plot(exp_out.get_values('time'), exp_out.get_values('mass_fuel'), 'b-') plt.suptitle('fuel mass vs time') plt.figure() plt.plot(phase.get_values('time', nodes='all'), phase.get_values('propulsion.dXdt:mass_fuel', nodes='all'), 'ro') plt.plot(exp_out.get_values('time'), exp_out.get_values('propulsion.dXdt:mass_fuel'), 'b-') plt.suptitle('fuel mass flow rate vs time') plt.figure() plt.plot(phase.get_values('time', nodes='all'), phase.get_values('mach', nodes='all'), 'ro') plt.plot(exp_out.get_values('time'), exp_out.get_values('mach'), 'b-') plt.suptitle('mach vs time') plt.figure() plt.plot(phase.get_values('time', nodes='all'), phase.get_values('mach_rate', nodes='all'), 'ro') plt.plot(exp_out.get_values('time'), exp_out.get_values('mach_rate'), 'b-') plt.suptitle('mach rate vs time') print('time') print(phase.get_values('time', nodes='all').T) print('alt') print(phase.get_values('alt', nodes='all').T) print('alt_rate') print(phase.get_values('alt_rate', nodes='all').T) print('alt_rate2') print(phase.get_values('alt_rate2', nodes='all').T) print('range') print(phase.get_values('range', nodes='all').T) print('flight path angle') print(phase.get_values('gam_comp.gam').T) print('true airspeed') print(phase.get_values('tas_comp.TAS', units='m/s').T) print('coef of lift') print(phase.get_values('aero.CL').T) print('coef of drag') print(phase.get_values('aero.CD').T) print('atmos density') print(phase.get_values('atmos.rho').T) print('alpha') print(phase.get_values('flight_equilibrium.alpha', units='rad').T) print('coef of thrust') print(phase.get_values('flight_equilibrium.CT').T) print('fuel flow rate') print(phase.get_values('propulsion.dXdt:mass_fuel').T) print('max_thrust') print(phase.get_values('propulsion.max_thrust', units='N').T) print('tau') print(phase.get_values('propulsion.tau').T) print('dynamic pressure') print(phase.get_values('q_comp.q', units='Pa').T) print('S') print(phase.get_values('S', units='m**2').T) plt.show() return p
def run_opt(driver_class, mode, color_info=None, sparsity=None, **options): p = Problem() p.model.linear_solver = RunOnceCounter() indeps = p.model.add_subsystem('indeps', IndepVarComp(), promotes_outputs=['*']) # the following were randomly generated using np.random.random(10)*2-1 to randomly # disperse them within a unit circle centered at the origin. indeps.add_output( 'x', np.array([ 0.55994437, -0.95923447, 0.21798656, -0.02158783, 0.62183717, 0.04007379, 0.46044942, -0.10129622, 0.27720413, -0.37107886 ])) indeps.add_output( 'y', np.array([ 0.52577864, 0.30894559, 0.8420792, 0.35039912, -0.67290778, -0.86236787, -0.97500023, 0.47739414, 0.51174103, 0.10052582 ])) indeps.add_output('r', .7) p.model.add_subsystem('circle', ExecComp('area=pi*r**2')) p.model.add_subsystem( 'r_con', ExecComp('g=x**2 + y**2 - r', g=np.ones(SIZE), x=np.ones(SIZE), y=np.ones(SIZE))) thetas = np.linspace(0, np.pi / 4, SIZE) p.model.add_subsystem( 'theta_con', ExecComp('g=arctan(y/x) - theta', g=np.ones(SIZE), x=np.ones(SIZE), y=np.ones(SIZE), theta=thetas)) p.model.add_subsystem( 'delta_theta_con', ExecComp('g = arctan(y/x)[::2]-arctan(y/x)[1::2]', g=np.ones(SIZE // 2), x=np.ones(SIZE), y=np.ones(SIZE))) thetas = np.linspace(0, np.pi / 4, SIZE) p.model.add_subsystem('l_conx', ExecComp('g=x-1', g=np.ones(SIZE), x=np.ones(SIZE))) p.model.connect('r', ('circle.r', 'r_con.r')) p.model.connect('x', ['r_con.x', 'theta_con.x', 'delta_theta_con.x']) p.model.connect('x', 'l_conx.x') p.model.connect('y', ['r_con.y', 'theta_con.y', 'delta_theta_con.y']) p.driver = driver_class() p.driver.options.update(options) p.model.add_design_var('x') p.model.add_design_var('y') p.model.add_design_var('r', lower=.5, upper=10) # nonlinear constraints p.model.add_constraint('r_con.g', equals=0) IND = np.arange(SIZE, dtype=int) ODD_IND = IND[0::2] # all odd indices p.model.add_constraint('theta_con.g', lower=-1e-5, upper=1e-5, indices=ODD_IND) p.model.add_constraint('delta_theta_con.g', lower=-1e-5, upper=1e-5) # this constrains x[0] to be 1 (see definition of l_conx) p.model.add_constraint('l_conx.g', equals=0, linear=False, indices=[ 0, ]) # linear constraint p.model.add_constraint('y', equals=0, indices=[ 0, ], linear=True) p.model.add_objective('circle.area', ref=-1) # # setup coloring if color_info is not None: p.driver.set_simul_deriv_color(color_info) elif sparsity is not None: p.driver.set_total_jac_sparsity(sparsity) p.setup(mode=mode) p.run_driver() return p
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(self): import numpy as np from openaerostruct.geometry.utils import generate_mesh from openaerostruct.geometry.geometry_group import Geometry from openaerostruct.transfer.displacement_transfer import DisplacementTransfer from openaerostruct.structures.struct_groups import SpatialBeamAlone from openmdao.api import IndepVarComp, Problem, Group, SqliteRecorder # Create a dictionary to store options about the surface mesh_dict = { 'num_y': 7, 'wing_type': 'CRM', 'symmetry': True, 'num_twist_cp': 5 } 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 'fem_model_type': 'tube', 'mesh': mesh, # 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 't_over_c_cp': np.array([0.15]), # maximum airfoil thickness 'thickness_cp': np.ones((3)) * .1, 'wing_weight_ratio': 2., 'struct_weight_relief': False, # True to add the weight of the structure to the loads on the structure 'distributed_fuel_weight': False, 'exact_failure_constraint': False, } # Create the problem and assign the model group prob = Problem() ny = surf_dict['mesh'].shape[1] indep_var_comp = IndepVarComp() indep_var_comp.add_output('loads', val=np.ones((ny, 6)) * 2e5, units='N') indep_var_comp.add_output('load_factor', val=1.) struct_group = SpatialBeamAlone(surface=surf_dict) # Add indep_vars to the structural group struct_group.add_subsystem('indep_vars', indep_var_comp, promotes=['*']) prob.model.add_subsystem(surf_dict['name'], struct_group) from openmdao.api import ScipyOptimizeDriver prob.driver = ScipyOptimizeDriver() prob.driver.options['disp'] = True prob.driver.options['tol'] = 1e-9 recorder = SqliteRecorder('struct.db') prob.driver.add_recorder(recorder) prob.driver.recording_options['record_derivatives'] = True prob.driver.recording_options['includes'] = ['*'] # Setup problem and add design variables, constraint, and objective prob.model.add_design_var('wing.thickness_cp', lower=0.01, upper=0.5, ref=1e-1) prob.model.add_constraint('wing.failure', upper=0.) prob.model.add_constraint('wing.thickness_intersects', upper=0.) # Add design variables, constraisnt, and objective on the problem prob.model.add_objective('wing.structural_mass', scaler=1e-5) # Set up the problem prob.setup(force_alloc_complex=False) # prob.run_model() # prob.check_partials(compact_print=False, method='fd') # exit() prob.run_driver() assert_rel_error(self, prob['wing.structural_mass'][0], 71088.4682399, 1e-8)
def test_in_driver(self): # This test assures that the driver is correctly seeing unscaled (physical) data. prob = Problem() model = prob.model inputs_comp = IndepVarComp() inputs_comp.add_output('x1_u_u', val=1.0) inputs_comp.add_output('x1_u_s', val=1.0) inputs_comp.add_output('x1_s_u', val=1.0, ref=3.0) inputs_comp.add_output('x1_s_s', val=1.0, ref=3.0) inputs_comp.add_output('ox1_u_u', val=1.0) inputs_comp.add_output('ox1_u_s', val=1.0) inputs_comp.add_output('ox1_s_u', val=1.0, ref=3.0) inputs_comp.add_output('ox1_s_s', val=1.0, ref=3.0) model.add_subsystem('p', inputs_comp) mycomp = model.add_subsystem('comp', MyComp()) model.connect('p.x1_u_u', 'comp.x2_u_u') model.connect('p.x1_u_s', 'comp.x2_u_s') model.connect('p.x1_s_u', 'comp.x2_s_u') model.connect('p.x1_s_s', 'comp.x2_s_s') driver = prob.driver = MyDriver() model.add_design_var('p.x1_u_u', lower=-11, upper=11) model.add_design_var('p.x1_u_s', ref=7.0, lower=-11, upper=11) model.add_design_var('p.x1_s_u', lower=-11, upper=11) model.add_design_var('p.x1_s_s', ref=7.0, lower=-11, upper=11) # easy constraints for basic check model.add_constraint('p.x1_u_u', upper=3.3) model.add_constraint('p.x1_u_s', upper=3.3, ref=13.0) model.add_constraint('p.x1_s_u', upper=3.3) model.add_constraint('p.x1_s_s', upper=3.3, ref=13.0) # harder to calculate constraints model.add_constraint('comp.x3_u_u', upper=3.3) model.add_constraint('comp.x3_u_s', upper=3.3, ref=17.0) model.add_constraint('comp.x3_s_u', upper=3.3) model.add_constraint('comp.x3_s_s', upper=3.3, ref=17.0) model.add_objective('p.ox1_u_u') model.add_objective('p.ox1_u_s', ref=15.0) model.add_objective('p.ox1_s_u') model.add_objective('p.ox1_s_s', ref=15.0) prob.setup() prob.run_driver() # Parameter values assert_rel_error(self, driver.param_vals['p.x1_u_u'], 1.0) assert_rel_error(self, driver.param_vals['p.x1_u_s'], 1.0 / 7.0) assert_rel_error(self, driver.param_vals['p.x1_s_u'], 1.0) assert_rel_error(self, driver.param_vals['p.x1_s_s'], 1.0 / 7.0) assert_rel_error(self, driver.param_meta['p.x1_u_u']['upper'], 11.0) assert_rel_error(self, driver.param_meta['p.x1_u_s']['upper'], 11.0 / 7.0) assert_rel_error(self, driver.param_meta['p.x1_s_u']['upper'], 11.0) assert_rel_error(self, driver.param_meta['p.x1_s_s']['upper'], 11.0 / 7.0) assert_rel_error(self, driver.con_meta['p.x1_u_u']['upper'], 3.3) assert_rel_error(self, driver.con_meta['p.x1_u_s']['upper'], 3.3 / 13.0) assert_rel_error(self, driver.con_meta['p.x1_s_u']['upper'], 3.3) assert_rel_error(self, driver.con_meta['p.x1_s_s']['upper'], 3.3 / 13.0) assert_rel_error(self, driver.con_vals['p.x1_u_u'], 1.0) assert_rel_error(self, driver.con_vals['p.x1_u_s'], 1.0 / 13.0) assert_rel_error(self, driver.con_vals['p.x1_s_u'], 1.0) assert_rel_error(self, driver.con_vals['p.x1_s_s'], 1.0 / 13.0) assert_rel_error(self, driver.obj_vals['p.ox1_u_u'], 1.0) assert_rel_error(self, driver.obj_vals['p.ox1_u_s'], 1.0 / 15.0) assert_rel_error(self, driver.obj_vals['p.ox1_s_u'], 1.0) assert_rel_error(self, driver.obj_vals['p.ox1_s_s'], 1.0 / 15.0) J = model.comp.J assert_rel_error(self, driver.sens_dict['comp.x3_u_u']['p.x1_u_u'][0][0], J[0, 0]) assert_rel_error(self, driver.sens_dict['comp.x3_u_s']['p.x1_u_u'][0][0], J[1, 0] / 17.0) assert_rel_error(self, driver.sens_dict['comp.x3_s_u']['p.x1_u_u'][0][0], J[2, 0]) assert_rel_error(self, driver.sens_dict['comp.x3_s_s']['p.x1_u_u'][0][0], J[3, 0] / 17.0) assert_rel_error(self, driver.sens_dict['comp.x3_u_u']['p.x1_u_s'][0][0], J[0, 1] * 7.0) assert_rel_error(self, driver.sens_dict['comp.x3_u_s']['p.x1_u_s'][0][0], J[1, 1] / 17.0 * 7.0) assert_rel_error(self, driver.sens_dict['comp.x3_s_u']['p.x1_u_s'][0][0], J[2, 1] * 7.0) assert_rel_error(self, driver.sens_dict['comp.x3_s_s']['p.x1_u_s'][0][0], J[3, 1] / 17.0 * 7.0) assert_rel_error(self, driver.sens_dict['comp.x3_u_u']['p.x1_s_u'][0][0], J[0, 2]) assert_rel_error(self, driver.sens_dict['comp.x3_u_s']['p.x1_s_u'][0][0], J[1, 2] / 17.0) assert_rel_error(self, driver.sens_dict['comp.x3_s_u']['p.x1_s_u'][0][0], J[2, 2]) assert_rel_error(self, driver.sens_dict['comp.x3_s_s']['p.x1_s_u'][0][0], J[3, 2] / 17.0) assert_rel_error(self, driver.sens_dict['comp.x3_u_u']['p.x1_s_s'][0][0], J[0, 3] * 7.0) assert_rel_error(self, driver.sens_dict['comp.x3_u_s']['p.x1_s_s'][0][0], J[1, 3] / 17.0 * 7.0) assert_rel_error(self, driver.sens_dict['comp.x3_s_u']['p.x1_s_s'][0][0], J[2, 3] * 7.0) assert_rel_error(self, driver.sens_dict['comp.x3_s_s']['p.x1_s_s'][0][0], J[3, 3] / 17.0 * 7.0) totals = prob.check_totals(compact_print=True, out_stream=None) for (of, wrt) in totals: assert_rel_error(self, totals[of, wrt]['abs error'][0], 0.0, 1e-7)
p['phase0.t_initial'] = 0.0 p['phase0.t_duration'] = max_time / 2.0 for i in range(n_traj): theta, heading, start_x, start_y, end_x, end_y = locs[i] p['phase0.states:p%dx' % i] = phase.interpolate(ys=[start_x, end_x], nodes='state_input') p['phase0.states:p%dy' % i] = phase.interpolate(ys=[start_y, end_y], nodes='state_input') #p['phase0.states:p%dmass' % i] = phase.interpolate(ys=[start_mass, start_mass], nodes='state_input') #p['phase0.states:L%d' % i] = phase.interpolate(ys=[0, 0], nodes='state_input') p.run_driver() exp_out = phase.simulate() import matplotlib.pyplot as plt circle = plt.Circle((0, 0), r_space, fill=False) plt.gca().add_artist(circle) t = exp_out.get_val('phase0.timeseries.time') print("total time:", t[-1]) data = {'t': t} for i in range(n_traj): x = exp_out.get_val('phase0.timeseries.states:p%dx' % i) y = exp_out.get_val('phase0.timeseries.states:p%dy' % i) speed = exp_out.get_val('phase0.timeseries.design_parameters:speed%d' % i) #mass = exp_out.get_val('phase0.timeseries.states:p%dmass' % i)
def test(self): # Create a dictionary to store options about the surface mesh_dict = {'num_y' : 7, 'num_x' : 3, 'wing_type' : 'CRM', 'symmetry' : True, 'num_twist_cp' : 5} 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' : 'tube', 'twist_cp' : twist_cp, 'mesh' : mesh, # Aerodynamic performance of the lifting surface at # an angle of attack of 0 (alpha=0). # These CL0 and CD0 values are added to the CL and CD # obtained from aerodynamic analysis of the surface to get # the total CL and CD. # These CL0 and CD0 values do not vary wrt alpha. 'CL0' : 0.0, # CL of the surface at alpha=0 'CD0' : 0.015, # CD of the surface at alpha=0 # Airfoil properties for viscous drag calculation 'k_lam' : 0.05, # percentage of chord with laminar # flow, used for viscous drag 't_over_c_cp' : np.array([0.15]), # thickness over chord ratio (NACA0015) 'c_max_t' : .303, # chordwise location of maximum (NACA0015) # thickness 'with_viscous' : True, # if true, compute viscous drag 'with_wave' : False, # if true, compute wave drag } surfaces = [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('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('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('Mach_number', point_name + '.Mach_number') 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') recorder = SqliteRecorder("aero_analysis.db") prob.driver.add_recorder(recorder) prob.driver.recording_options['record_derivatives'] = True prob.driver.recording_options['includes'] = ['*'] # Set up the problem prob.setup() # from openmdao.api import view_model # view_model(prob) prob.run_driver() assert_rel_error(self, prob['aero_point_0.wing_perf.CD'][0], 0.038041969673747206, 1e-6) assert_rel_error(self, prob['aero_point_0.wing_perf.CL'][0], 0.5112640267782032, 1e-6) assert_rel_error(self, prob['aero_point_0.CM'][1], -1.735548800386354, 1e-6)
pb.model.add_constraint('con_dpdx', upper=0.) pb.model.add_constraint('con_dt', upper=0.) pb.model.add_constraint('con_sigma1', upper=0.) pb.model.add_constraint('con_sigma2', upper=0.) pb.model.add_constraint('con_sigma3', upper=0.) pb.model.add_constraint('con_sigma4', upper=0.) pb.model.add_constraint('con_sigma5', upper=0.) pb.model.add_constraint('con_temp', upper=0.) pb.model.add_constraint('con_theta_low', upper=0.) pb.model.add_constraint('con_theta_up', upper=0.) pb.setup() initialize(pb) pb.run_driver() print("x_aer= {}".format(pb['x_aer'])) print("x_pro= {}".format(pb['x_pro'])) print("x_str= {}".format(pb['x_str'])) print("z= {}".format(pb['z'])) if options.batch: exit(0) # reader = CaseReader(case_recorder_filename) # cases = reader.list_cases('problem') # print(cases) # for i in range(len(cases)):
## run optimisation ## COBYLA Prob.driver = ScipyOptimizeDriver() Prob.driver.options['optimizer'] = 'COBYLA' Prob.driver.options['maxiter'] = 1000 Prob.driver.options['tol'] = 1e-9 model.add_design_var('Ori_1', lower=-90, upper=90) model.add_design_var('Ori_2', lower=-90, upper=90) model.add_objective(objectif) Prob.setup() Prob.run_driver() print(Prob['Ori_1']) print(Prob['Ori_2']) print(Prob[objectif]) End = time() print("Elapsed time : {0}".format(End - Start)) #creation of a log file file = open("logfile.txt", "w") file.write("Optimisation COBYLA\n") file.write(name + "\n") file.write("Orientation départ 1 = {0}\n".format(Ori1Dep)) file.write("Orientation départ 2 = {0}\n".format(Ori2Dep))
def test_betz(self): from openmdao.api import Problem, ScipyOptimizer, IndepVarComp, ExplicitComponent class ActuatorDisc(ExplicitComponent): """Simple wind turbine model based on actuator disc theory""" def setup(self): # Inputs self.add_input('a', 0.5, desc="Induced Velocity Factor") self.add_input('Area', 10.0, units="m**2", desc="Rotor disc area") self.add_input('rho', 1.225, units="kg/m**3", desc="air density") self.add_input( 'Vu', 10.0, units="m/s", desc="Freestream air velocity, upstream of rotor") # Outputs self.add_output('Vr', 0.0, units="m/s", desc="Air velocity at rotor exit plane") self.add_output( 'Vd', 0.0, units="m/s", desc="Slipstream air velocity, downstream of rotor") self.add_output('Ct', 0.0, desc="Thrust Coefficient") self.add_output('thrust', 0.0, units="N", desc="Thrust produced by the rotor") self.add_output('Cp', 0.0, desc="Power Coefficient") self.add_output('power', 0.0, units="W", desc="Power produced by the rotor") self.declare_partials('Vr', ['a', 'Vu']) self.declare_partials('Vd', 'a') self.declare_partials('Ct', 'a') self.declare_partials('thrust', ['a', 'Area', 'rho', 'Vu']) self.declare_partials('Cp', 'a') self.declare_partials('power', ['a', 'Area', 'rho', 'Vu']) def compute(self, inputs, outputs): """ Considering the entire rotor as a single disc that extracts velocity uniformly from the incoming flow and converts it to power.""" a = inputs['a'] Vu = inputs['Vu'] qA = .5 * inputs['rho'] * inputs['Area'] * Vu**2 outputs['Vd'] = Vd = Vu * (1 - 2 * a) outputs['Vr'] = .5 * (Vu + Vd) outputs['Ct'] = Ct = 4 * a * (1 - a) outputs['thrust'] = Ct * qA outputs['Cp'] = Cp = Ct * (1 - a) outputs['power'] = Cp * qA * Vu def compute_partials(self, inputs, J): """ Jacobian of partial derivatives.""" a = inputs['a'] Vu = inputs['Vu'] Area = inputs['Area'] rho = inputs['rho'] # pre-compute commonly needed quantities a_times_area = a * Area one_minus_a = 1.0 - a a_area_rho_vu = a_times_area * rho * Vu J['Vr', 'a'] = -Vu J['Vr', 'Vu'] = one_minus_a J['Vd', 'a'] = -2.0 * Vu J['Ct', 'a'] = 4.0 - 8.0 * a J['thrust', 'a'] = .5 * rho * Vu**2 * Area * J['Ct', 'a'] J['thrust', 'Area'] = 2.0 * Vu**2 * a * rho * one_minus_a J['thrust', 'rho'] = 2.0 * a_times_area * Vu**2 * (one_minus_a) J['thrust', 'Vu'] = 4.0 * a_area_rho_vu * (one_minus_a) J['Cp', 'a'] = 4.0 * a * (2.0 * a - 2.0) + 4.0 * (one_minus_a)**2 J['power', 'a'] = 2.0 * Area * Vu**3 * a * rho * ( 2.0 * a - 2.0) + 2.0 * Area * Vu**3 * rho * one_minus_a**2 J['power', 'Area'] = 2.0 * Vu**3 * a * rho * one_minus_a**2 J['power', 'rho'] = 2.0 * a_times_area * Vu**3 * (one_minus_a)**2 J['power', 'Vu'] = 6.0 * Area * Vu**2 * a * rho * one_minus_a**2 # build the model prob = Problem() indeps = prob.model.add_subsystem('indeps', IndepVarComp(), promotes=['*']) indeps.add_output('a', .5) indeps.add_output('Area', 10.0, units='m**2') indeps.add_output('rho', 1.225, units='kg/m**3') indeps.add_output('Vu', 10.0, units='m/s') prob.model.add_subsystem('a_disk', ActuatorDisc(), promotes_inputs=['a', 'Area', 'rho', 'Vu']) # setup the optimization prob.driver = ScipyOptimizer() prob.driver.options['optimizer'] = 'SLSQP' prob.model.add_design_var('a', lower=0., upper=1.) prob.model.add_design_var('Area', lower=0., upper=1.) # negative one so we maximize the objective prob.model.add_objective('a_disk.Cp', scaler=-1) prob.setup() prob.run_driver() # minimum value assert_rel_error(self, prob['a_disk.Cp'], 16. / 27., 1e-4) assert_rel_error(self, prob['a'], 0.33333, 1e-4) assert_rel_error(self, prob['Area'], 5.65272869, 1e-4)
def test_simul_coloring_example(self): from openmdao.api import Problem, IndepVarComp, ExecComp, ScipyOptimizeDriver import numpy as np p = Problem() indeps = p.model.add_subsystem('indeps', IndepVarComp(), promotes_outputs=['*']) # the following were randomly generated using np.random.random(10)*2-1 to randomly # disperse them within a unit circle centered at the origin. indeps.add_output( 'x', np.array([ 0.55994437, -0.95923447, 0.21798656, -0.02158783, 0.62183717, 0.04007379, 0.46044942, -0.10129622, 0.27720413, -0.37107886 ])) indeps.add_output( 'y', np.array([ 0.52577864, 0.30894559, 0.8420792, 0.35039912, -0.67290778, -0.86236787, -0.97500023, 0.47739414, 0.51174103, 0.10052582 ])) indeps.add_output('r', .7) p.model.add_subsystem('circle', ExecComp('area=pi*r**2')) p.model.add_subsystem( 'r_con', ExecComp('g=x**2 + y**2 - r', g=np.ones(SIZE), x=np.ones(SIZE), y=np.ones(SIZE))) thetas = np.linspace(0, np.pi / 4, SIZE) p.model.add_subsystem( 'theta_con', ExecComp('g=arctan(y/x) - theta', g=np.ones(SIZE), x=np.ones(SIZE), y=np.ones(SIZE), theta=thetas)) p.model.add_subsystem( 'delta_theta_con', ExecComp('g = arctan(y/x)[::2]-arctan(y/x)[1::2]', g=np.ones(SIZE // 2), x=np.ones(SIZE), y=np.ones(SIZE))) thetas = np.linspace(0, np.pi / 4, SIZE) p.model.add_subsystem( 'l_conx', ExecComp('g=x-1', g=np.ones(SIZE), x=np.ones(SIZE))) p.model.connect('r', ('circle.r', 'r_con.r')) p.model.connect('x', ['r_con.x', 'theta_con.x', 'delta_theta_con.x']) p.model.connect('x', 'l_conx.x') p.model.connect('y', ['r_con.y', 'theta_con.y', 'delta_theta_con.y']) p.driver = ScipyOptimizeDriver() p.driver.options['optimizer'] = 'SLSQP' p.driver.options['disp'] = False p.model.add_design_var('x') p.model.add_design_var('y') p.model.add_design_var('r', lower=.5, upper=10) # nonlinear constraints p.model.add_constraint('r_con.g', equals=0) IND = np.arange(SIZE, dtype=int) ODD_IND = IND[0::2] # all odd indices p.model.add_constraint('theta_con.g', lower=-1e-5, upper=1e-5, indices=ODD_IND) p.model.add_constraint('delta_theta_con.g', lower=-1e-5, upper=1e-5) # this constrains x[0] to be 1 (see definition of l_conx) p.model.add_constraint('l_conx.g', equals=0, linear=False, indices=[ 0, ]) # linear constraint p.model.add_constraint('y', equals=0, indices=[ 0, ], linear=True) p.model.add_objective('circle.area', ref=-1) # setup coloring color_info = { "fwd": [ [ [20], # uncolored column list [0, 2, 4, 6, 8], # color 1 [1, 3, 5, 7, 9], # color 2 [10, 12, 14, 16, 18], # color 3 [11, 13, 15, 17, 19], # color 4 ], [ [1, 11, 16, 21], # column 0 [2, 16], # column 1 [3, 12, 17], # column 2 [4, 17], # column 3 [5, 13, 18], # column 4 [6, 18], # column 5 [7, 14, 19], # column 6 [8, 19], # column 7 [9, 15, 20], # column 8 [10, 20], # column 9 [1, 11, 16], # column 10 [2, 16], # column 11 [3, 12, 17], # column 12 [4, 17], # column 13 [5, 13, 18], # column 14 [6, 18], # column 15 [7, 14, 19], # column 16 [8, 19], # column 17 [9, 15, 20], # column 18 [10, 20], # column 19 None, # column 20 ] ], "sparsity": None } p.driver.set_simul_deriv_color(color_info) p.setup(mode='fwd') p.run_driver() assert_almost_equal(p['circle.area'], np.pi, decimal=7)
def test(self): from openaerostruct.geometry.utils import generate_mesh, write_FFD_file from openaerostruct.geometry.geometry_group import Geometry from openaerostruct.integration.aerostruct_groups import Aerostruct, AerostructPoint from openmdao.api import IndepVarComp, Problem, Group, SqliteRecorder from pygeo import DVGeometry # Create a dictionary to store options about the surface mesh_dict = { 'num_y': 5, 'num_x': 2, 'wing_type': 'CRM', 'symmetry': True, 'num_twist_cp': 5 } 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': 'tube', 'thickness_cp': np.array([.1, .2, .3]), 'mesh': mesh, 'num_x': mesh.shape[0], 'num_y': mesh.shape[1], 'geom_manipulator': 'FFD', 'mx': 2, 'my': 3, # 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': 0.15, # thickness over chord ratio (NACA0015) 'c_max_t': .303, # chordwise location of maximum (NACA0015) # thickness 'with_viscous': True, # 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': 2., # 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.) 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('CT', val=9.80665 * 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('a', 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'] filename = write_FFD_file(surface, surface['mx'], surface['my']) DVGeo = DVGeometry(filename) aerostruct_group = Aerostruct(surface=surface, DVGeo=DVGeo) # 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') # 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_weight', point_name + '.' + 'total_perf.' + name + '_structural_weight') # Import the Scipy Optimizer and set the driver of the problem to use # it, which defaults to an SLSQP optimization method from openmdao.api import ScipyOptimizeDriver prob.driver = ScipyOptimizeDriver() recorder = SqliteRecorder("aerostruct_ffd.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.shape', lower=-3, upper=2) 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) # iprofile.setup() # iprofile.start() # Set up the problem prob.setup() # from openmdao.api import view_model # view_model(prob, outfile='aerostruct_ffd', show_browser=False) # prob.run_model() prob.run_driver() # prob.check_partials(compact_print=True) # print("\nWing CL:", prob['aero_point_0.wing_perf.CL']) # print("Wing CD:", prob['aero_point_0.wing_perf.CD']) # from helper import plot_3d_points # # mesh = prob['aero_point_0.wing.def_mesh'] # plot_3d_points(mesh) # # filename = mesh_dict['wing_type'] + '_' + str(mesh_dict['num_x']) + '_' + str(mesh_dict['num_y']) # filename += '_' + str(surf_dict['mx']) + '_' + str(surf_dict['my']) + '.mesh' # np.save(filename, mesh) assert_rel_error(self, prob['AS_point_0.fuelburn'][0], 104675.0989232741, 1e-4)
def test(self): import numpy as np from openmdao.api import IndepVarComp, Problem, Group, NewtonSolver, \ ScipyIterativeSolver, LinearBlockGS, NonlinearBlockGS, \ DirectSolver, LinearBlockGS, PetscKSP, SqliteRecorder from openaerostruct.geometry.utils import generate_mesh from openaerostruct.geometry.geometry_group import Geometry from openaerostruct.aerodynamics.aero_groups import AeroPoint from openaerostruct.common.atmos_group import AtmosGroup # Create a dictionary to store options about the mesh mesh_dict = {'num_y' : 7, 'num_x' : 2, 'wing_type' : 'CRM', 'symmetry' : True, 'num_twist_cp' : 5} # Generate the aerodynamic mesh based on the previous dictionary mesh, twist_cp = generate_mesh(mesh_dict) # Create a dictionary with info and options about the aerodynamic # lifting surface surface = { # 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' : 'tube', 'twist_cp' : twist_cp, 'mesh' : mesh, 'num_x' : mesh.shape[0], 'num_y' : mesh.shape[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.015, # CD of the surface at alpha=0 # Airfoil properties for viscous drag calculation 'k_lam' : 0.05, # percentage of chord with laminar # flow, used for viscous drag 't_over_c_cp' : np.array([0.15]), # thickness over chord ratio (NACA0015) 'c_max_t' : .303, # chordwise location of maximum (NACA0015) # thickness 'with_viscous' : True, # if true, compute viscous drag 'with_wave' : False, # if true, compute wave drag } # Create the OpenMDAO problem prob = Problem() # Create an independent variable component that will supply the flow # conditions to the problem. indep_var_comp = IndepVarComp() 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('altitude', val=35000., units='ft') # Add this IndepVarComp to the problem model prob.model.add_subsystem('prob_vars', indep_var_comp, promotes=['*']) # Add this IndepVarComp to the problem model prob.model.add_subsystem('atmos', AtmosGroup(), promotes=['*']) # Create and add a group that handles the geometry for the # aerodynamic lifting surface geom_group = Geometry(surface=surface) prob.model.add_subsystem(surface['name'], geom_group) # Create the aero point group, which contains the actual aerodynamic # analyses aero_group = AeroPoint(surfaces=[surface]) point_name = 'aero_point_0' prob.model.add_subsystem(point_name, aero_group, promotes_inputs=['v', 'alpha', 'Mach_number', 're', 'rho', 'cg']) 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') # Import the Scipy Optimizer and set the driver of the problem to use # it, which defaults to an SLSQP optimization method 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=-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 and run the optimization problem prob.setup() # prob.check_partials(compact_print=True) # exit() prob.run_driver() assert_rel_error(self, prob['aero_point_0.wing_perf.CD'][0], 0.030471796067577953, 1e-6) assert_rel_error(self, prob['aero_point_0.wing_perf.CL'][0], 0.5, 1e-6) assert_rel_error(self, prob['aero_point_0.CM'][1], -1.7331840488188963, 1e-6)
def test(self): # Create a dictionary to store options about the surface mesh_dict = { 'num_y': 5, 'num_x': 3, 'wing_type': 'rect', 'symmetry': True, 'span_cos_spacing': 1., 'span': 10, 'chord': 1 } mesh = generate_mesh(mesh_dict) surf_dict = { # Wing definition 'name': 'wing', # name of the surface 'type': 'structural', 'symmetry': True, # if true, model one half of wing # reflected across the plane y = 0 'fem_model_type': 'tube', 'mesh': mesh, 'num_x': mesh.shape[0], 'num_y': mesh.shape[1], # 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 't_over_c': 0.15, # maximum airfoil thickness 'thickness_cp': np.ones((3)) * .0075, 'wing_weight_ratio': 1., 'exact_failure_constraint': False, } # Create the problem and assign the model group prob = Problem() ny = surf_dict['num_y'] loads = np.zeros((ny, 6)) loads[0, 2] = 1e4 indep_var_comp = IndepVarComp() indep_var_comp.add_output('loads', val=loads, units='N') indep_var_comp.add_output('load_factor', val=1.) struct_group = SpatialBeamAlone(surface=surf_dict) # Add indep_vars to the structural group struct_group.add_subsystem('indep_vars', indep_var_comp, promotes=['*']) prob.model.add_subsystem(surf_dict['name'], struct_group) from openmdao.api import ScipyOptimizeDriver prob.driver = ScipyOptimizeDriver() prob.driver.options['disp'] = True # Setup problem and add design variables, constraint, and objective prob.model.add_design_var('wing.thickness_cp', lower=0.001, upper=0.25, scaler=1e2) prob.model.add_constraint('wing.failure', upper=0.) prob.model.add_constraint('wing.thickness_intersects', upper=0.) # Add design variables, constraisnt, and objective on the problem prob.model.add_objective('wing.structural_weight', 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['wing.structural_weight'][0], 1144.8503583047038, 1e-4)
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', point_name + '.coupled.load_factor') com_name = point_name + '.' + name + '_perf.' prob.model.connect(name + '.local_stiff_transformed', point_name + '.coupled.' + name + '.local_stiff_transformed') # Connect aerodyamic mesh to coupled group mesh prob.model.connect(name + '.mesh', point_name + '.coupled.' + name + '.mesh') prob.model.connect(name + '.element_mass', point_name + '.coupled.' + name + '.element_mass') 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_mass', point_name + '.' + 'total_perf.' + name + '_structural_mass') # Connect wingbox properties to von Mises stress calcs prob.model.connect(name + '.Qz', com_name + 'Qz') prob.model.connect(name + '.J', com_name + 'J') prob.model.connect(name + '.A_enc', com_name + 'A_enc') prob.model.connect(name + '.htop', com_name + 'htop') prob.model.connect(name + '.hbottom', com_name + 'hbottom') prob.model.connect(name + '.hfront', com_name + 'hfront') prob.model.connect(name + '.hrear', com_name + 'hrear') prob.model.connect(name + '.spar_thickness', com_name + 'spar_thickness') prob.model.connect(name + '.t_over_c', com_name + 't_over_c') #======================================================================================= # Here we add the fuel volume constraint componenet to the model #======================================================================================= prob.model.add_subsystem('fuel_vol_delta', WingboxFuelVolDelta(surface=surface)) prob.model.connect('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', 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 # 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_driver() # prob.check_partials(form='central', compact_print=True) print(prob['AS_point_0.fuelburn'][0]) print(prob['wing.structural_mass'][0]/1.25) assert_rel_error(self, prob['AS_point_0.fuelburn'][0], 82444.7895704, 1e-5) assert_rel_error(self, prob['wing.structural_mass'][0]/1.25, 15174.9970923, 1e-5)
def two_burn_orbit_raise_problem(transcription='gauss-lobatto', optimizer='SNOPT', transcription_order=3, compressed=True, show_plots=False): traj = Trajectory() p = Problem(model=traj) if optimizer == 'SNOPT': p.driver = pyOptSparseDriver() p.driver.options['optimizer'] = optimizer p.driver.options['dynamic_simul_derivs'] = True p.driver.opt_settings['Major iterations limit'] = 100 p.driver.opt_settings['Major feasibility tolerance'] = 1.0E-6 p.driver.opt_settings['Major optimality tolerance'] = 1.0E-6 p.driver.opt_settings['iSumm'] = 6 else: p.driver = pyOptSparseDriver() p.driver.options['dynamic_simul_derivs'] = True traj.add_design_parameter('c', opt=False, val=1.5, units='DU/TU') # First Phase (burn) burn1 = Phase(transcription, ode_class=FiniteBurnODE, num_segments=10, transcription_order=transcription_order, compressed=compressed) burn1 = traj.add_phase('burn1', burn1) burn1.set_time_options(fix_initial=True, duration_bounds=(.5, 10)) burn1.set_state_options('r', fix_initial=True, fix_final=False, defect_scaler=100.0) burn1.set_state_options('theta', fix_initial=True, fix_final=False, defect_scaler=100.0) burn1.set_state_options('vr', fix_initial=True, fix_final=False, defect_scaler=100.0) burn1.set_state_options('vt', fix_initial=True, fix_final=False, defect_scaler=100.0) burn1.set_state_options('accel', fix_initial=True, fix_final=False) burn1.set_state_options('deltav', fix_initial=True, fix_final=False) burn1.add_control('u1', rate_continuity=True, rate2_continuity=True, units='deg', scaler=0.01, rate_continuity_scaler=0.001, rate2_continuity_scaler=0.001, lower=-30, upper=30) # Second Phase (Coast) coast = Phase(transcription, ode_class=FiniteBurnODE, num_segments=10, transcription_order=transcription_order, compressed=compressed) traj.add_phase('coast', coast) coast.set_time_options(initial_bounds=(0.5, 20), duration_bounds=(.5, 10), duration_ref=10) coast.set_state_options('r', fix_initial=False, fix_final=False, defect_scaler=100.0) coast.set_state_options('theta', fix_initial=False, fix_final=False, defect_scaler=100.0) coast.set_state_options('vr', fix_initial=False, fix_final=False, defect_scaler=100.0) coast.set_state_options('vt', fix_initial=False, fix_final=False, defect_scaler=100.0) coast.set_state_options('accel', fix_initial=True, fix_final=True) coast.set_state_options('deltav', fix_initial=False, fix_final=False) coast.add_control('u1', opt=False, val=0.0, units='deg') # Third Phase (burn) burn2 = Phase(transcription, ode_class=FiniteBurnODE, num_segments=10, transcription_order=transcription_order, compressed=compressed) traj.add_phase('burn2', burn2) burn2.set_time_options(initial_bounds=(0.5, 20), duration_bounds=(.5, 10), initial_ref=10) burn2.set_state_options('r', fix_initial=False, fix_final=True, defect_scaler=100.0) burn2.set_state_options('theta', fix_initial=False, fix_final=False, defect_scaler=100.0) burn2.set_state_options('vr', fix_initial=False, fix_final=True, defect_scaler=100.0) burn2.set_state_options('vt', fix_initial=False, fix_final=True, defect_scaler=100.0) burn2.set_state_options('accel', fix_initial=False, fix_final=False, defect_scaler=1.0) burn2.set_state_options('deltav', fix_initial=False, fix_final=False, defect_scaler=1.0) burn2.add_control('u1', rate_continuity=True, rate2_continuity=True, units='deg', scaler=0.01, rate_continuity_scaler=0.001, rate2_continuity_scaler=0.001, lower=-10, upper=10) burn2.add_objective('deltav', loc='final', scaler=100.0) # Link Phases traj.link_phases(phases=['burn1', 'coast', 'burn2'], vars=['time', 'r', 'theta', 'vr', 'vt', 'deltav']) traj.link_phases(phases=['burn1', 'burn2'], vars=['accel']) # Finish Problem Setup p.model.options['assembled_jac_type'] = 'csc' p.model.linear_solver = DirectSolver(assemble_jac=True) p.driver.add_recorder(SqliteRecorder('two_burn_orbit_raise_example.db')) p.setup(check=True) # Set Initial Guesses p.set_val('design_parameters:c', value=1.5) p.set_val('burn1.t_initial', value=0.0) p.set_val('burn1.t_duration', value=2.25) p.set_val('burn1.states:r', value=burn1.interpolate(ys=[1, 1.5], nodes='state_input')) p.set_val('burn1.states:theta', value=burn1.interpolate(ys=[0, 1.7], nodes='state_input')) p.set_val('burn1.states:vr', value=burn1.interpolate(ys=[0, 0], nodes='state_input')) p.set_val('burn1.states:vt', value=burn1.interpolate(ys=[1, 1], nodes='state_input')) p.set_val('burn1.states:accel', value=burn1.interpolate(ys=[0.1, 0], nodes='state_input')) p.set_val( 'burn1.states:deltav', value=burn1.interpolate(ys=[0, 0.1], nodes='state_input'), ) p.set_val('burn1.controls:u1', value=burn1.interpolate(ys=[-3.5, 13.0], nodes='control_input')) p.set_val('coast.t_initial', value=2.25) p.set_val('coast.t_duration', value=3.0) p.set_val('coast.states:r', value=coast.interpolate(ys=[1.3, 1.5], nodes='state_input')) p.set_val('coast.states:theta', value=coast.interpolate(ys=[2.1767, 1.7], nodes='state_input')) p.set_val('coast.states:vr', value=coast.interpolate(ys=[0.3285, 0], nodes='state_input')) p.set_val('coast.states:vt', value=coast.interpolate(ys=[0.97, 1], nodes='state_input')) p.set_val('coast.states:accel', value=coast.interpolate(ys=[0, 0], nodes='state_input')) p.set_val('coast.controls:u1', value=coast.interpolate(ys=[0, 0], nodes='control_input')) p.set_val('burn2.t_initial', value=5.25) p.set_val('burn2.t_duration', value=1.75) p.set_val('burn2.states:r', value=burn2.interpolate(ys=[1, 3], nodes='state_input')) p.set_val('burn2.states:theta', value=burn2.interpolate(ys=[0, 4.0], nodes='state_input')) p.set_val('burn2.states:vr', value=burn2.interpolate(ys=[0, 0], nodes='state_input')) p.set_val('burn2.states:vt', value=burn2.interpolate(ys=[1, np.sqrt(1 / 3)], nodes='state_input')) p.set_val('burn2.states:accel', value=burn2.interpolate(ys=[0.1, 0], nodes='state_input')) p.set_val('burn2.states:deltav', value=burn2.interpolate(ys=[0.1, 0.2], nodes='state_input')) p.set_val('burn2.controls:u1', value=burn2.interpolate(ys=[1, 1], nodes='control_input')) p.run_driver() # Plot results exp_out = traj.simulate(times=50, num_procs=3) fig = plt.figure(figsize=(8, 4)) fig.suptitle('Two Burn Orbit Raise Solution') ax_u1 = plt.subplot2grid((2, 2), (0, 0)) ax_deltav = plt.subplot2grid((2, 2), (1, 0)) ax_xy = plt.subplot2grid((2, 2), (0, 1), rowspan=2) span = np.linspace(0, 2 * np.pi, 100) ax_xy.plot(np.cos(span), np.sin(span), 'k--', lw=1) ax_xy.plot(3 * np.cos(span), 3 * np.sin(span), 'k--', lw=1) ax_xy.set_xlim(-4.5, 4.5) ax_xy.set_ylim(-4.5, 4.5) ax_xy.set_xlabel('x ($R_e$)') ax_xy.set_ylabel('y ($R_e$)') ax_u1.set_xlabel('time ($TU$)') ax_u1.set_ylabel('$u_1$ ($deg$)') ax_u1.grid(True) ax_deltav.set_xlabel('time ($TU$)') ax_deltav.set_ylabel('${\Delta}v$ ($DU/TU$)') ax_deltav.grid(True) t_sol = traj.get_values('time', flat=True) x_sol = traj.get_values('pos_x', flat=True) y_sol = traj.get_values('pos_y', flat=True) dv_sol = traj.get_values('deltav', flat=True) u1_sol = traj.get_values('u1', units='deg', flat=True) t_exp = exp_out.get_values('time', flat=True) x_exp = exp_out.get_values('pos_x', flat=True) y_exp = exp_out.get_values('pos_y', flat=True) dv_exp = exp_out.get_values('deltav', flat=True) u1_exp = exp_out.get_values('u1', units='deg', flat=True) ax_u1.plot(t_sol, u1_sol, 'ro', ms=3) ax_u1.plot(t_exp, u1_exp, 'b-') ax_deltav.plot(t_sol, dv_sol, 'ro', ms=3) ax_deltav.plot(t_exp, dv_exp, 'b-') ax_xy.plot(x_sol, y_sol, 'ro', ms=3, label='implicit') ax_xy.plot(x_exp, y_exp, 'b-', label='explicit') if show_plots: plt.show() return p
def test(self): import numpy as np from openaerostruct.geometry.utils import generate_mesh from openaerostruct.geometry.geometry_group import Geometry from openaerostruct.aerodynamics.aero_groups import AeroPoint from openmdao.api import IndepVarComp, Problem, Group # Instantiate 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('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('cg', val=np.zeros((3)), units='m') prob.model.add_subsystem('prob_vars', indep_var_comp, promotes=['*']) # Create a dictionary to store options about the surface mesh_dict = { 'num_y': 5, 'num_x': 3, 'wing_type': 'rect', 'symmetry': True, 'span': 10., 'chord': 1, 'span_cos_spacing': 1. } mesh = generate_mesh(mesh_dict) surface = { # 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' 'twist_cp': np.zeros(2), '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.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.12]), # thickness over chord ratio (NACA0015) 'c_max_t': .303, # chordwise location of maximum (NACA0015) # thickness 'with_viscous': False, # if true, compute viscous drag, 'with_wave': False, # if true, compute wave drag 'sweep': 0., 'dihedral': 0., 'taper': 1., } # end of surface dictionary 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) # Create the aero point group and add it to the model aero_group = AeroPoint(surfaces=[surface]) point_name = 'aero_point_0' 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('Mach_number', point_name + '.Mach_number') prob.model.connect('re', point_name + '.re') prob.model.connect('rho', point_name + '.rho') prob.model.connect('cg', point_name + '.cg') name = 'wing' # 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() # # Setup problem and add design variables, constraint, and objective prob.model.add_design_var('wing.twist_cp', lower=-10., upper=15.) prob.model.add_design_var('wing.sweep', lower=-10., upper=30.) prob.model.add_design_var('wing.dihedral', 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.CD'][0],\ 0.0049392534859265614, 1e-6)
# user_update_routine = set_web3_offset ) rotor.setup() rotor = Init_RotorSE_wRefBlade(rotor, blade, Analysis_Level=Analysis_Level, fst_vt=fst_vt) # rotor['chord_in'] = np.array([3.542, 3.54451799, 2.42342374, 2.44521374, 4.69032208, 6.3306303, 4.41245811, 1.419]) # rotor['theta_in'] = np.array([13.30800018, 13.30800018, 0.92624531, 10.41054813, 11.48955724, -0.60858835, -1.41595352, 4.89747605]) # rotor['sparT_in'] = np.array([0.00047, 0.00059925, 0.07363709, 0.13907431, 0.19551095, 0.03357394, 0.12021584, 0.00047]) # rotor['r_in'] = np.array([0., 0.02565783, 0.23892874, 0.39114299, 0.54335725, 0.6955715, 0.84778575, 1.]) # === run and outputs === tt = time.time() rotor.run_driver() #rotor.check_partials(compact_print=True, step=1e-6, form='central') refBlade.write_ontology(fname_output, rotor['blade_out'], refBlade.wt_ref) print('Run Time = ', time.time() - tt) print('AEP =', rotor['AEP']) print('diameter =', rotor['diameter']) print('ratedConditions.V =', rotor['rated_V']) print('ratedConditions.Omega =', rotor['rated_Omega']) print('ratedConditions.pitch =', rotor['rated_pitch']) print('ratedConditions.T =', rotor['rated_T']) print('ratedConditions.Q =', rotor['rated_Q']) print('mass_one_blade =', rotor['mass_one_blade']) print('mass_all_blades =', rotor['mass_all_blades']) print('I_all_blades =', rotor['I_all_blades'])
point_name + '.aero_states.' + name + '_def_mesh') prob.model.connect(name + '.t_over_c', point_name + '.' + name + '_perf.' + 't_over_c') # Import the Scipy Optimizer and set the driver of the problem to use # it, which defaults to an SLSQP optimization method from openmdao.api import ScipyOptimizeDriver prob.driver = ScipyOptimizeDriver() prob.driver.options['tol'] = 1e-9 recorder = SqliteRecorder("aero.db") prob.driver.add_recorder(recorder) prob.driver.recording_options['record_derivatives'] = True prob.driver.recording_options['includes'] = ['*'] # 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 and run the optimization problem prob.setup() # prob.check_partials(compact_print=True) # exit() prob.run_driver() print('The Drag Coefficient is:', prob['aero_point_0.wing_perf.CD'][0]) print('The Lift Coefficient is:', prob['aero_point_0.wing_perf.CL'][0])
def test_double_integrator_for_docs(self): import matplotlib.pyplot as plt from openmdao.api import Problem, Group, pyOptSparseDriver, DirectSolver from openmdao.utils.assert_utils import assert_rel_error import dymos as dm from dymos.examples.plotting import plot_results from dymos.examples.double_integrator.double_integrator_ode import DoubleIntegratorODE # Initialize the problem and assign the driver p = Problem(model=Group()) p.driver = pyOptSparseDriver() p.driver.options['optimizer'] = 'SLSQP' p.driver.options['dynamic_simul_derivs'] = True # Setup the trajectory and its phase traj = p.model.add_subsystem('traj', dm.Trajectory()) transcription = dm.Radau(num_segments=30, order=3, compressed=False) phase = traj.add_phase( 'phase0', dm.Phase(ode_class=DoubleIntegratorODE, transcription=transcription)) # # Set the options for our variables. # phase.set_time_options(fix_initial=True, fix_duration=True, units='s') phase.set_state_options('x', fix_initial=True, rate_source='v', units='m') phase.set_state_options('v', fix_initial=True, fix_final=True, rate_source='u', units='m/s') phase.add_control('u', units='m/s**2', scaler=0.01, continuity=False, rate_continuity=False, rate2_continuity=False, lower=-1.0, upper=1.0) # # Maximize distance travelled. # phase.add_objective('x', loc='final', scaler=-1) p.model.linear_solver = DirectSolver() # # Setup the problem and set our initial values. # p.setup(check=True) p['traj.phase0.t_initial'] = 0.0 p['traj.phase0.t_duration'] = 1.0 p['traj.phase0.states:x'] = phase.interpolate(ys=[0, 0.25], nodes='state_input') p['traj.phase0.states:v'] = phase.interpolate(ys=[0, 0], nodes='state_input') p['traj.phase0.controls:u'] = phase.interpolate(ys=[1, -1], nodes='control_input') # # Solve the problem. # p.run_driver() # # Verify that the results are correct. # x = p.get_val('traj.phase0.timeseries.states:x') v = p.get_val('traj.phase0.timeseries.states:v') assert_rel_error(self, x[0], 0.0, tolerance=1.0E-4) assert_rel_error(self, x[-1], 0.25, tolerance=1.0E-4) assert_rel_error(self, v[0], 0.0, tolerance=1.0E-4) assert_rel_error(self, v[-1], 0.0, tolerance=1.0E-4) # # Simulate the explicit solution and plot the results. # exp_out = traj.simulate() plot_results( [('traj.phase0.timeseries.time', 'traj.phase0.timeseries.states:x', 'time (s)', 'x $(m)$'), ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.states:v', 'time (s)', 'v $(m/s)$'), ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.controls:u', 'time (s)', 'u $(m/s^2)$')], title='Double Integrator Solution\nRadau Pseudospectral Method', p_sol=p, p_sim=exp_out) plt.show()
def test(self): from openaerostruct.geometry.utils import generate_mesh, write_FFD_file from openaerostruct.geometry.geometry_group import Geometry from openaerostruct.transfer.displacement_transfer import DisplacementTransfer from openaerostruct.aerodynamics.aero_groups import AeroPoint from openaerostruct.integration.multipoint_comps import MultiCD, GeomMatch from openmdao.api import IndepVarComp, Problem, Group, NewtonSolver, ScipyIterativeSolver, LinearBlockGS, NonlinearBlockGS, DirectSolver, LinearBlockGS, PetscKSP, ScipyOptimizeDriver, ExplicitComponent # TODO, SqliteRecorder, CaseReader, profile # Create a dictionary to store options about the surface mesh_dict = { 'num_y': 5, 'num_x': 3, 'wing_type': 'CRM', 'symmetry': True, 'num_twist_cp': 5, 'span_cos_spacing': 0. } mesh, twist_cp = generate_mesh(mesh_dict) surf_dict = { # Wing definition 'name': 'wing', # name of the surface 'type': 'aero', 'symmetry': True, # if true, model one half of wing # reflected across the plane y = 0 'S_ref_type': 'wetted', # how we compute the wing area, # can be 'wetted' or 'projected' 'fem_model_type': 'tube', 'mesh': mesh, '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.015, # CD of the surface at alpha=0 # Airfoil properties for viscous drag calculation 'k_lam': 0.05, # percentage of chord with laminar # flow, used for viscous drag 't_over_c_cp': np.array([0.15]), # thickness over chord ratio (NACA0015) 'c_max_t': .303, # chordwise location of maximum (NACA0015) # thickness 'with_viscous': True, # if true, compute viscous drag 'with_wave': False, # if true, compute wave drag } surf_dict['num_x'], surf_dict['num_y'] = surf_dict['mesh'].shape[:2] surfaces = [surf_dict] n_points = 2 # Create the problem and the model group prob = Problem() indep_var_comp = IndepVarComp() indep_var_comp.add_output('v', val=248.136, units='m/s') indep_var_comp.add_output('alpha', val=np.ones(n_points) * 6.64, units='deg') indep_var_comp.add_output('M', val=0.84) indep_var_comp.add_output('re', val=1.e6, units='1/m') indep_var_comp.add_output('rho', val=0.38, units='kg/m**3') indep_var_comp.add_output('cg', val=np.zeros((3)), units='m') prob.model.add_subsystem('prob_vars', indep_var_comp, promotes=['*']) # Loop through and add a certain number of aero points for i in range(n_points): # Create the aero point group and add it to the model aero_group = AeroPoint(surfaces=surfaces) point_name = 'aero_point_{}'.format(i) prob.model.add_subsystem(point_name, aero_group) # Connect flow properties to the analysis point prob.model.connect('v', point_name + '.v') prob.model.connect('alpha', point_name + '.alpha', src_indices=[i]) prob.model.connect('M', point_name + '.M') prob.model.connect('re', point_name + '.re') prob.model.connect('rho', point_name + '.rho') prob.model.connect('cg', point_name + '.cg') # Connect the parameters within the model for each aero point for surface in surfaces: 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. aero_group.add_subsystem(surface['name'] + '_geom', geom_group) name = surface['name'] prob.model.connect(point_name + '.CD', 'multi_CD.' + str(i) + '_CD') # Connect the mesh from the geometry component to the analysis point prob.model.connect(point_name + '.' + name + '_geom.mesh', point_name + '.' + name + '.def_mesh') # Perform the connections with the modified names within the # 'aero_states' group. prob.model.connect( point_name + '.' + name + '_geom.mesh', point_name + '.aero_states.' + name + '_def_mesh') prob.model.connect( point_name + '.' + name + '_geom.t_over_c', point_name + '.' + name + '_perf.' + 't_over_c') prob.model.add_subsystem('multi_CD', MultiCD(n_points=n_points), promotes_outputs=['CD']) from openmdao.api import ScipyOptimizeDriver prob.driver = ScipyOptimizeDriver() prob.driver.options['tol'] = 1e-9 # # Setup problem and add design variables, constraint, and objective prob.model.add_design_var('alpha', lower=-15, upper=15) prob.model.add_design_var('aero_point_0.wing_geom.twist_cp', lower=-5, upper=8) prob.model.add_constraint('aero_point_0.wing_perf.CL', equals=0.45) prob.model.add_design_var('aero_point_1.wing_geom.twist_cp', lower=-5, upper=8) prob.model.add_constraint('aero_point_1.wing_perf.CL', equals=0.5) prob.model.add_objective('CD', scaler=1e4) # Set up the problem prob.setup() # prob.run_model() prob.run_driver() # prob.check_partials(compact_print=True) assert_rel_error(self, prob['aero_point_0.wing_perf.CL'][0], 0.45, 1e-6) assert_rel_error(self, prob['aero_point_0.wing_perf.CD'][0], 0.03231556149303963, 1e-6) assert_rel_error(self, prob['aero_point_1.wing_perf.CL'][0], 0.5, 1e-6) assert_rel_error(self, prob['aero_point_1.wing_perf.CD'][0], 0.03376555561457066, 1e-6)
def test_multi_obj(self): class Box(ExplicitComponent): def setup(self): self.add_input('length', val=1.) self.add_input('width', val=1.) self.add_input('height', val=1.) self.add_output('front_area', val=1.0) self.add_output('top_area', val=1.0) self.add_output('area', val=1.0) self.add_output('volume', val=1.) def compute(self, inputs, outputs): length = inputs['length'] width = inputs['width'] height = inputs['height'] outputs['top_area'] = length * width outputs['front_area'] = length * height outputs[ 'area'] = 2 * length * height + 2 * length * width + 2 * height * width outputs['volume'] = length * height * width prob = Problem() prob.model.add_subsystem('box', Box(), promotes=['*']) indeps = prob.model.add_subsystem('indeps', IndepVarComp(), promotes=['*']) indeps.add_output('length', 1.5) indeps.add_output('width', 1.5) indeps.add_output('height', 1.5) # setup the optimization prob.driver = SimpleGADriver() prob.driver.options['max_gen'] = 100 prob.driver.options['bits'] = {'length': 8, 'width': 8, 'height': 8} prob.driver.options['multi_obj_exponent'] = 1. prob.driver.options['penalty_parameter'] = 10. prob.driver.options['multi_obj_weights'] = { 'box.front_area': 0.1, 'box.top_area': 0.9 } prob.driver.options['multi_obj_exponent'] = 1 prob.model.add_design_var('length', lower=0.1, upper=2.) prob.model.add_design_var('width', lower=0.1, upper=2.) prob.model.add_design_var('height', lower=0.1, upper=2.) prob.model.add_objective('front_area', scaler=-1) # maximize prob.model.add_objective('top_area', scaler=-1) # maximize prob.model.add_constraint('volume', upper=1.) # run #1 prob.setup() prob.run_driver() front = prob['front_area'] top = prob['top_area'] l1 = prob['length'] w1 = prob['width'] h1 = prob['height'] print('Box dims: ', l1, w1, h1) print('Front and top area: ', front, top) print('Volume: ', prob['volume']) # should be around 1 # run #2 # weights changed prob2 = Problem() prob2.model.add_subsystem('box', Box(), promotes=['*']) indeps2 = prob2.model.add_subsystem('indeps', IndepVarComp(), promotes=['*']) indeps2.add_output('length', 1.5) indeps2.add_output('width', 1.5) indeps2.add_output('height', 1.5) # setup the optimization prob2.driver = SimpleGADriver() prob2.driver.options['max_gen'] = 100 prob2.driver.options['bits'] = {'length': 8, 'width': 8, 'height': 8} prob2.driver.options['multi_obj_exponent'] = 1. prob2.driver.options['penalty_parameter'] = 10. prob2.driver.options['multi_obj_weights'] = { 'box.front_area': 0.9, 'box.top_area': 0.1 } prob2.driver.options['multi_obj_exponent'] = 1 prob2.model.add_design_var('length', lower=0.1, upper=2.) prob2.model.add_design_var('width', lower=0.1, upper=2.) prob2.model.add_design_var('height', lower=0.1, upper=2.) prob2.model.add_objective('front_area', scaler=-1) # maximize prob2.model.add_objective('top_area', scaler=-1) # maximize prob2.model.add_constraint('volume', upper=1.) # run #1 prob2.setup() prob2.run_driver() front2 = prob2['front_area'] top2 = prob2['top_area'] l2 = prob2['length'] w2 = prob2['width'] h2 = prob2['height'] print('Box dims: ', l2, w2, h2) print('Front and top area: ', front2, top2) print('Volume: ', prob['volume']) # should be around 1 self.assertGreater(w1, w2) # front area does not depend on width self.assertGreater(h2, h1) # top area does not depend on height
def test(self): # Create a dictionary to store options about the surface # OM: vary 'num_y' and 'num_x' to change the size of the mesh mesh_dict = { 'num_y': 5, 'num_x': 2, 'wing_type': 'rect', 'symmetry': True } mesh = 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': 'tube', 'thickness_cp': np.ones((2)) * .1, 'twist_cp': np.ones((2)), 'mesh': mesh, # Aerodynamic performance of the lifting surface at # an angle of attack of 0 (alpha=0). # These CL0 and CD0 values are added to the CL and CD # obtained from aerodynamic analysis of the surface to get # the total CL and CD. # These CL0 and CD0 values do not vary wrt alpha. 'CL0': 0.0, # CL of the surface at alpha=0 'CD0': 0.015, # CD of the surface at alpha=0 # Airfoil properties for viscous drag calculation 'k_lam': 0.05, # percentage of chord with laminar # flow, used for viscous drag 't_over_c_cp': np.array([0.15]), # thickness over chord ratio (NACA0015) 'c_max_t': .303, # chordwise location of maximum (NACA0015) # thickness 'with_viscous': True, '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': 2., '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=9., 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=9.80665 * 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: prob.model.connect('load_factor', name + '.load_factor') 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_weight', point_name + '.' + 'total_perf.' + name + '_structural_weight') 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=-10., 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() prob.run_driver() assert_rel_error(self, prob['AS_point_0.fuelburn'][0], 70754.19144483653, 1e-5)
def test_mixed_integer_3bar_default_bits(self): # Tests bug where letting openmdao calcualate the bits didn't preserve integer status unless range # was a power of 2. np.random.seed(1) class ObjPenalty(ExplicitComponent): """ Weight objective with penalty on stress constraint. """ def setup(self): self.add_input('obj', 0.0) self.add_input('stress', val=np.zeros((3, ))) self.add_output('weighted', 0.0) def compute(self, inputs, outputs): obj = inputs['obj'] stress = inputs['stress'] pen = 0.0 for j in range(len(stress)): if stress[j] > 1.0: pen += 10.0 * (stress[j] - 1.0)**2 outputs['weighted'] = obj + pen prob = Problem() model = prob.model = Group() model.add_subsystem('xc_a1', IndepVarComp('area1', 5.0, units='cm**2'), promotes=['*']) model.add_subsystem('xc_a2', IndepVarComp('area2', 5.0, units='cm**2'), promotes=['*']) model.add_subsystem('xc_a3', IndepVarComp('area3', 5.0, units='cm**2'), promotes=['*']) model.add_subsystem('xi_m1', IndepVarComp('mat1', 1), promotes=['*']) model.add_subsystem('xi_m2', IndepVarComp('mat2', 1), promotes=['*']) model.add_subsystem('xi_m3', IndepVarComp('mat3', 1), promotes=['*']) model.add_subsystem('comp', ThreeBarTruss(), promotes=['*']) model.add_subsystem('obj_with_penalty', ObjPenalty(), promotes=['*']) model.add_design_var('area1', lower=1.2, upper=1.3) model.add_design_var('area2', lower=2.0, upper=2.1) model.add_design_var('mat1', lower=2, upper=4) model.add_design_var('mat2', lower=2, upper=4) model.add_design_var('mat3', lower=1, upper=4) model.add_objective('weighted') prob.driver = SimpleGADriver() prob.driver.options['bits'] = {'area1': 6, 'area2': 6} prob.driver.options['max_gen'] = 75 prob.driver._randomstate = 1 prob.setup(check=False) prob['area3'] = 0.0005 prob.run_driver() # Note, GA doesn't do so well with the continuous vars, naturally, so we reduce the space # as much as we can. Objective is still rather random, but it is close. GA does a great job # of picking the correct values for the integer desvars though. self.assertLess(prob['mass'], 6.0) assert_rel_error(self, prob['mat1'], 3, 1e-5) assert_rel_error(self, prob['mat2'], 3, 1e-5)
def init_ssbj_mda(): """ Runs the analysis once. """ prob = Problem() # Mean point is chosen for the design variables scalers = {} #scalers['z'] = np.array([0.06, 60000., 1.4, 2.475, 69.85, 1500.0]) # optimum scalers['z'] = np.array([0.05, 45000., 1.6, 5.500, 55.00, 1000.0]) # start point scalers['x_aer']=1.#0.75 scalers['x_str']=np.array([.25, 1.])#np.array([0.28959593,0.75]) scalers['x_pro']=.5#0.15621093 # Others variables are unknowns for the moment so Scale=1.0 scalers['WT']=1.0 scalers['Theta']=1.0 scalers['L']=1.0 scalers['WF']=1.0 scalers['D']=1.0 scalers['ESF']=1.0 scalers['WE']=1.0 scalers['fin']=1.0 scalers['SFC']=1.0 scalers['R']=1.0 scalers['DT']=1.0 scalers['Temp']=1.0 scalers['dpdx']=1.0 scalers['sigma']=np.array([1.0,1.0,1.0,1.0,1.0]) prob.model = SSBJ_MDA(scalers) prob.setup() #Initialization of acceptable values as initial values for the polynomial functions Z = prob['z']*scalers['z'] Wfo = 2000 Wo = 25000 We = 3*4360.0*(1.0**1.05) t = Z[0]*Z[5]/np.sqrt(Z[5]*Z[3]) Wfw = (5.*Z[5]/18.)*(2.0/3.0*t)*(42.5) Fo = 1.0 Wtotal = 80000. Wtot=1.1*Wtotal while abs(Wtot - Wtotal) > Wtotal*0.0001: Wtot = Wtotal Ww = Fo*(.0051*((Wtot*6.0)**0.557)*Z[5]**.649*Z[3]**.5*Z[0]**-.4*((1.0+0.25)**.1)*\ ((np.cos(Z[4]*np.pi/180))**-1)*((.1875*Z[5])**.1)) Wtotal = Wo + Ww + Wfo + Wfw + We prob['WT'] = Wtotal # prob['sap']['Aero.WT'] = Wtotal # prob['sap']['Struc.L'] = Wtotal prob['L'] = Wtotal prob.run_driver() #Update the scalers dictionary for key in iterkeys(scalers): if key not in ['z', 'x_str', 'x_aer', 'x_pro']: scalers[key] = prob[key] return scalers
def test_brachistochrone_integrated_control_radau_ps(self): import numpy as np from openmdao.api import Problem, Group, ScipyOptimizeDriver, DirectSolver from openmdao.utils.assert_utils import assert_rel_error from dymos import Phase, Radau p = Problem(model=Group()) p.driver = ScipyOptimizeDriver() phase = Phase(ode_class=BrachistochroneODE, transcription=Radau(num_segments=10)) p.model.add_subsystem('phase0', phase) phase.set_time_options(initial_bounds=(0, 0), duration_bounds=(.5, 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) phase.set_state_options('theta', targets='theta', fix_initial=False) phase.add_control('theta_dot', units='deg/s', rate_continuity=True, lower=0, upper=60) phase.add_design_parameter('g', units='m/s**2', opt=False, val=9.80665) # Minimize time at the end of the phase phase.add_objective('time', loc='final', scaler=10) p.model.linear_solver = DirectSolver() p.model.options['assembled_jac_type'] = 'csc' p.setup() 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.states:theta'] = np.radians( phase.interpolate(ys=[0.05, 100.0], nodes='state_input')) p['phase0.controls:theta_dot'] = phase.interpolate( ys=[50, 50], nodes='control_input') # Solve for the optimal trajectory p.run_driver() # Test the results assert_rel_error(self, p.get_val('phase0.timeseries.time')[-1], 1.8016, tolerance=1.0E-3) sim_out = phase.simulate(times_per_seg=20) x_sol = p.get_val('phase0.timeseries.states:x') y_sol = p.get_val('phase0.timeseries.states:y') v_sol = p.get_val('phase0.timeseries.states:v') theta_sol = p.get_val('phase0.timeseries.states:theta') theta_dot_sol = p.get_val('phase0.timeseries.controls:theta_dot') time_sol = p.get_val('phase0.timeseries.time') x_sim = sim_out.get_val('phase0.timeseries.states:x') y_sim = sim_out.get_val('phase0.timeseries.states:y') v_sim = sim_out.get_val('phase0.timeseries.states:v') theta_sim = sim_out.get_val('phase0.timeseries.states:theta') theta_dot_sim = sim_out.get_val('phase0.timeseries.controls:theta_dot') time_sim = sim_out.get_val('phase0.timeseries.time') x_interp = interp1d(time_sim[:, 0], x_sim[:, 0]) y_interp = interp1d(time_sim[:, 0], y_sim[:, 0]) v_interp = interp1d(time_sim[:, 0], v_sim[:, 0]) theta_interp = interp1d(time_sim[:, 0], theta_sim[:, 0]) theta_dot_interp = interp1d(time_sim[:, 0], theta_dot_sim[:, 0]) assert_rel_error(self, x_interp(time_sol), x_sol, tolerance=1.0E-5) assert_rel_error(self, y_interp(time_sol), y_sol, tolerance=1.0E-5) assert_rel_error(self, v_interp(time_sol), v_sol, tolerance=1.0E-5) assert_rel_error(self, theta_interp(time_sol), theta_sol, tolerance=1.0E-5) assert_rel_error(self, theta_dot_interp(time_sol), theta_dot_sol, tolerance=1.0E-5)