def setUp(self): self.nn = 100 self.p = Problem(model=Group()) ivc = IndepVarComp() ivc.add_output(name='a', shape=(self.nn, 4)) ivc.add_output(name='b', shape=(self.nn, 4)) self.p.model.add_subsystem(name='ivc', subsys=ivc, promotes_outputs=['a', 'b']) self.p.model.add_subsystem(name='dot_prod_comp', subsys=DotProductComp(vec_size=self.nn, length=4)) self.p.model.connect('a', 'dot_prod_comp.a') self.p.model.connect('b', 'dot_prod_comp.b') self.p.setup() self.p['a'] = np.random.rand(self.nn, 4) self.p['b'] = np.random.rand(self.nn, 4) self.p.run_model()
def setUp(self): self.nn = 5 self.p = Problem(model=Group()) ivc = IndepVarComp() ivc.add_output(name='A', shape=(self.nn, 6, 4)) ivc.add_output(name='x', shape=(self.nn, 4)) self.p.model.add_subsystem(name='ivc', subsys=ivc, promotes_outputs=['A', 'x']) self.p.model.add_subsystem(name='mat_vec_product_comp', subsys=MatrixVectorProductComp(vec_size=self.nn, A_shape=(6, 4))) self.p.model.connect('A', 'mat_vec_product_comp.A') self.p.model.connect('x', 'mat_vec_product_comp.x') self.p.setup(force_alloc_complex=True) self.p['A'] = np.random.rand(self.nn, 6, 4) self.p['x'] = np.random.rand(self.nn, 4) self.p.run_model()
def setUp(self): self.nn = 10 self.p = Problem(model=Group()) ivc = IndepVarComp() ivc.add_output(name='a', shape=(self.nn,)) ivc.add_output(name='b', shape=(self.nn,)) self.p.model.add_subsystem(name='ivc', subsys=ivc, promotes_outputs=['a', 'b']) demux_comp = self.p.model.add_subsystem(name='demux_comp', subsys=DemuxComp(vec_size=self.nn)) demux_comp.add_var('a', shape=(self.nn,)) demux_comp.add_var('b', shape=(self.nn,)) self.p.model.connect('a', 'demux_comp.a') self.p.model.connect('b', 'demux_comp.b') self.p.setup(force_alloc_complex=True) self.p['a'] = np.random.rand(self.nn) self.p['b'] = np.random.rand(self.nn) self.p.run_model()
def test_structural_weight_loads(self): surface = get_default_surfaces()[0] comp = StructureWeightLoads(surface=surface) group = Group() indep_var_comp = IndepVarComp() ny = surface['mesh'].shape[1] #carefully chosen "random" values that give non-uniform derivatives outputs that are good for testing nodesval = np.array([[1., 2., 4.], [20., 22., 7.], [8., 17., 14.], [13., 14., 16.]],dtype=complex) element_weights_val = np.arange(ny-1)+1 indep_var_comp.add_output('nodes', val=nodesval,units='m') indep_var_comp.add_output('element_weights', val=element_weights_val,units='N') group.add_subsystem('indep_var_comp', indep_var_comp, promotes=['*']) group.add_subsystem('load', comp, promotes=['*']) p = run_test(self, group, complex_flag=True, compact_print=True)
def setUp(self): self.nn = 5 self.p = Problem(model=Group()) ivc = IndepVarComp() ivc.add_output(name='a', shape=(self.nn, 3)) ivc.add_output(name='b', shape=(self.nn, 3)) self.p.model.add_subsystem(name='ivc', subsys=ivc, promotes_outputs=['a', 'b']) adder=self.p.model.add_subsystem(name='add_subtract_comp', subsys=AddSubtractComp()) adder.add_equation('adder_output',['input_a','input_b'],vec_size=self.nn,length=3) self.p.model.connect('a', 'add_subtract_comp.input_a') self.p.model.connect('b', 'add_subtract_comp.input_b') self.p.setup() self.p['a'] = np.random.rand(self.nn, 3) self.p['b'] = np.random.rand(self.nn, 3) self.p.run_model()
def test_const_jacobian(self): import numpy as np from openmdao.api import Problem, Group, IndepVarComp, DirectSolver, DenseJacobian from openmdao.jacobians.tests.test_jacobian_features import SimpleCompConst model = Group() comp = IndepVarComp() for name, val in (('x', 1.), ('y1', np.ones(2)), ('y2', np.ones(2)), ('y3', np.ones(2)), ('z', np.ones((2, 2)))): comp.add_output(name, val) model.add_subsystem('input_comp', comp, promotes=['x', 'y1', 'y2', 'y3', 'z']) problem = Problem(model=model) model.suppress_solver_output = True model.linear_solver = DirectSolver() model.jacobian = DenseJacobian() model.add_subsystem('simple', SimpleCompConst(), promotes=['x', 'y1', 'y2', 'y3', 'z', 'f', 'g']) problem.setup(check=False) problem.run_model() totals = problem.compute_totals(['f', 'g'], ['x', 'y1', 'y2', 'y3', 'z']) assert_rel_error(self, totals['f', 'x'], [[1.]]) assert_rel_error(self, totals['f', 'z'], np.ones((1, 4))) assert_rel_error(self, totals['f', 'y1'], np.zeros((1, 2))) assert_rel_error(self, totals['f', 'y2'], np.zeros((1, 2))) assert_rel_error(self, totals['f', 'y3'], np.zeros((1, 2))) assert_rel_error(self, totals['g', 'x'], [[1], [0], [0], [1]]) assert_rel_error(self, totals['g', 'z'], np.zeros((4, 4))) assert_rel_error(self, totals['g', 'y1'], [[1, 0], [1, 0], [0, 1], [0, 1]]) assert_rel_error(self, totals['g', 'y2'], [[1, 0], [0, 1], [1, 0], [0, 1]]) assert_rel_error(self, totals['g', 'y3'], [[1, 0], [1, 0], [0, 1], [0, 1]])
def setup(self, compname, inputs, state0): # create instance of component type try: comp = eval('%s(NTIME)' % compname) except TypeError: try: comp = eval('%s()' % compname) except TypeError: comp = eval('%s(NTIME, 300)' % compname) # collect metadata for component inputs prob = Problem(comp) prob.setup() prob.final_setup() self.inputs_dict = {} for name, meta in prob.model.list_inputs(units=True, out_stream=None): self.inputs_dict[name.split('.')[-1]] = meta # create independent vars for each input, initialized with random values indep = IndepVarComp() for item in inputs + state0: shape = self.inputs_dict[item]['value'].shape units = self.inputs_dict[item]['units'] indep.add_output(item, np.random.random(shape), units=units) # setup problem for test self.prob = Problem() self.prob.model.add_subsystem('indep', indep, promotes=['*']) self.prob.model.add_subsystem('comp', comp, promotes=['*']) self.prob.setup()
def test_iimplicit(self): # Testing that our scale/unscale contexts leave the output vector in the correct state when # linearize is called on implicit components. prob = Problem() model = prob.model inputs_comp = IndepVarComp() inputs_comp.add_output('x1_u', val=1.0) model.add_subsystem('p', inputs_comp) mycomp = model.add_subsystem('comp', MyImplicitComp()) model.connect('p.x1_u', 'comp.x2_u') model.linear_solver = DirectSolver() model.nonlinear_solver = NewtonSolver() model.nonlinear_solver.options['atol'] = 1e-12 model.nonlinear_solver.options['rtol'] = 1e-12 model.add_design_var('p.x1_u', lower=-11, upper=11) model.add_constraint('p.x1_u', upper=3.3) model.add_objective('comp.x3_u') model.add_objective('comp.x3_s') prob.setup() prob.run_model() 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)
def setUp(self): self.nn = 5 self.p = Problem(model=Group()) ivc = IndepVarComp() ivc.add_output(name='a', shape=(self.nn, 3, 1)) ivc.add_output(name='b', shape=(self.nn, 3, 1)) self.p.model.add_subsystem(name='ivc', subsys=ivc, promotes_outputs=['a', 'b']) self.p.model.add_subsystem(name='cross_prod_comp', subsys=CrossProductComp(vec_size=self.nn)) self.p.model.connect('a', 'cross_prod_comp.a') self.p.model.connect('b', 'cross_prod_comp.b') self.p.setup(force_alloc_complex=True) self.p['a'] = np.random.rand(self.nn, 3, 1) self.p['b'] = np.random.rand(self.nn, 3, 1) self.p['a'][:, 0, 0] = 2.0 self.p['a'][:, 1, 0] = 3.0 self.p['a'][:, 2, 0] = 4.0 self.p['b'][:, 0, 0] = 5.0 self.p['b'][:, 1, 0] = 6.0 self.p['b'][:, 2, 0] = 7.0 self.p.run_model()
def setup(self): surface = self.options['surface'] mesh = surface['mesh'] nx = mesh.shape[0] ny = mesh.shape[1] # Add independent variables that do not belong to a specific component indep_var_comp = IndepVarComp() # Add structural components to the surface-specific group self.add_subsystem('indep_vars', indep_var_comp, promotes=['*']) if 'struct' in surface['type']: self.add_subsystem('radius_comp', RadiusComp(surface=surface), promotes_inputs=['mesh', 't_over_c'], promotes_outputs=['radius']) if 'thickness_cp' in surface.keys(): n_cp = len(surface['thickness_cp']) # Add bspline components for active bspline geometric variables. self.add_subsystem('thickness_bsp', BsplinesComp( in_name='thickness_cp', out_name='thickness', units='m', num_control_points=n_cp, num_points=int(ny-1), bspline_order=min(n_cp, 4), distribution='uniform'), promotes_inputs=['thickness_cp'], promotes_outputs=['thickness']) indep_var_comp.add_output('thickness_cp', val=surface['thickness_cp'], units='m') self.add_subsystem('tube', SectionPropertiesTube(surface=surface), promotes_inputs=['thickness', 'radius'], promotes_outputs=['A', 'Iy', 'Iz', 'J'])
def test_speed(self): from openmdao.api import Problem, Group, IndepVarComp, ExecComp from openmdao.core.tests.test_units import SpeedComp comp = IndepVarComp() comp.add_output('distance', val=1., units='m') comp.add_output('time', val=1., units='s') prob = Problem(model=Group()) prob.model.add_subsystem('c1', comp) prob.model.add_subsystem('c2', SpeedComp()) prob.model.add_subsystem('c3', ExecComp('f=speed',speed={'units': 'm/s'})) prob.model.connect('c1.distance', 'c2.distance') prob.model.connect('c1.time', 'c2.time') prob.model.connect('c2.speed', 'c3.speed') prob.setup() prob.run_model() assert_rel_error(self, prob['c1.distance'], 1.) # units: m assert_rel_error(self, prob['c2.distance'], 1.e-3) # units: km assert_rel_error(self, prob['c1.time'], 1.) # units: s assert_rel_error(self, prob['c2.time'], 1./3600.) # units: h assert_rel_error(self, prob['c2.speed'], 3.6) # units: km/h assert_rel_error(self, prob['c3.f'], 1.0) # units: km/h
def setUp(self): self.nn = 5 self.p = Problem(model=Group()) ivc = IndepVarComp() ivc.add_output(name='a', shape=(self.nn, 3), units='lbf') ivc.add_output(name='b', shape=(self.nn, 3), units='ft/s') self.p.model.add_subsystem(name='ivc', subsys=ivc, promotes_outputs=['a', 'b']) self.p.model.add_subsystem(name='dot_prod_comp', subsys=DotProductComp(vec_size=self.nn, a_units='N', b_units='m/s', c_units='W')) self.p.model.connect('a', 'dot_prod_comp.a') self.p.model.connect('b', 'dot_prod_comp.b') self.p.setup() self.p['a'] = np.random.rand(self.nn, 3) self.p['b'] = np.random.rand(self.nn, 3) self.p.run_model()
def test_const_jacobian(self): model = Group() comp = IndepVarComp() for name, val in (('x', 1.), ('y1', np.ones(2)), ('y2', np.ones(2)), ('y3', np.ones(2)), ('z', np.ones((2, 2)))): comp.add_output(name, val) model.add_subsystem('input_comp', comp, promotes=['x', 'y1', 'y2', 'y3', 'z']) problem = Problem(model=model) problem.set_solver_print(level=0) model.linear_solver = ScipyKrylov() model.jacobian = COOJacobian() model.add_subsystem('simple', SimpleCompConst(), promotes=['x', 'y1', 'y2', 'y3', 'z', 'f', 'g']) problem.setup(check=False) problem.run_model() totals = problem.compute_totals(['f', 'g'], ['x', 'y1', 'y2', 'y3', 'z']) jacobian = {} jacobian['f', 'x'] = [[1.]] jacobian['f', 'z'] = np.ones((1, 4)) jacobian['f', 'y1'] = np.zeros((1, 2)) jacobian['f', 'y2'] = np.zeros((1, 2)) jacobian['f', 'y3'] = np.zeros((1, 2)) jacobian['g', 'y1'] = [[1, 0], [1, 0], [0, 1], [0, 1]] jacobian['g', 'y2'] = [[1, 0], [0, 1], [1, 0], [0, 1]] jacobian['g', 'y3'] = [[1, 0], [1, 0], [0, 1], [0, 1]] jacobian['g', 'x'] = [[1], [0], [0], [1]] jacobian['g', 'z'] = np.zeros((4, 4)) assert_rel_error(self, totals, jacobian)
def test_sparse_jacobian(self): import numpy as np from openmdao.api import Problem, Group, IndepVarComp, ExplicitComponent class SparsePartialComp(ExplicitComponent): def setup(self): self.add_input('x', shape=(4,)) self.add_output('f', shape=(2,)) self.declare_partials(of='f', wrt='x', rows=[0, 1, 1, 1], cols=[0, 1, 2, 3]) def compute_partials(self, inputs, partials): # Corresponds to the [(0,0), (1,1), (1,2), (1,3)] entries. partials['f', 'x'] = [1., 2., 3., 4.] model = Group() comp = IndepVarComp() comp.add_output('x', np.ones(4)) model.add_subsystem('input', comp) model.add_subsystem('example', SparsePartialComp()) model.connect('input.x', 'example.x') problem = Problem(model=model) problem.setup(check=False) problem.run_model() totals = problem.compute_totals(['example.f'], ['input.x']) assert_rel_error(self, totals['example.f', 'input.x'], [[1., 0., 0., 0.], [0., 2., 3., 4.]])
def test_raise_no_error_on_singular(self): prob = Problem() model = prob.model comp = IndepVarComp() comp.add_output('dXdt:TAS', val=1.0) comp.add_output('accel_target', val=2.0) model.add_subsystem('des_vars', comp, promotes=['*']) teg = model.add_subsystem('thrust_equilibrium_group', subsys=Group()) teg.add_subsystem('dynamics', ExecComp('z = 2.0*thrust'), promotes=['*']) thrust_bal = BalanceComp() thrust_bal.add_balance(name='thrust', val=1207.1, lhs_name='dXdt:TAS', rhs_name='accel_target', eq_units='m/s**2', lower=-10.0, upper=10000.0) teg.add_subsystem(name='thrust_bal', subsys=thrust_bal, promotes_inputs=['dXdt:TAS', 'accel_target'], promotes_outputs=['thrust']) teg.linear_solver = DirectSolver(assemble_jac=False) teg.nonlinear_solver = NewtonSolver() teg.nonlinear_solver.options['solve_subsystems'] = True teg.nonlinear_solver.options['max_sub_solves'] = 1 teg.nonlinear_solver.options['atol'] = 1e-4 prob.setup(check=False) prob.set_solver_print(level=0) teg.linear_solver.options['err_on_singular'] = False prob.run_model()
def test(self): # 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, 'radius_cp' : np.ones((5)) * 0.5, # 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) # Set up the problem prob.setup() prob.run_model() assert_rel_error(self, prob['wing.structural_mass'][0], 117819.798089, 1e-4)
def setup(self): E = self.metadata['E'] L = self.metadata['L'] b = self.metadata['b'] volume = self.metadata['volume'] num_elements = self.metadata['num_elements'] num_nodes = num_elements + 1 force_vector = np.zeros(2 * num_nodes) force_vector[-2] = -1. inputs_comp = IndepVarComp() inputs_comp.add_output('h', shape=num_elements) self.add_subsystem('inputs_comp', inputs_comp) I_comp = MomentOfInertiaComp(num_elements=num_elements, b=b) self.add_subsystem('I_comp', I_comp) comp = LocalStiffnessMatrixComp(num_elements=num_elements, E=E, L=L) self.add_subsystem('local_stiffness_matrix_comp', comp) comp = GlobalStiffnessMatrixComp(num_elements=num_elements) self.add_subsystem('global_stiffness_matrix_comp', comp) comp = StatesComp(num_elements=num_elements, force_vector=force_vector) self.add_subsystem('states_comp', comp) comp = DisplacementsComp(num_elements=num_elements) self.add_subsystem('displacements_comp', comp) comp = ComplianceComp(num_elements=num_elements, force_vector=force_vector) self.add_subsystem('compliance_comp', comp) comp = VolumeComp(num_elements=num_elements, b=b, L=L) self.add_subsystem('volume_comp', comp) self.connect('inputs_comp.h', 'I_comp.h') self.connect('I_comp.I', 'local_stiffness_matrix_comp.I') self.connect( 'local_stiffness_matrix_comp.K_local', 'global_stiffness_matrix_comp.K_local') self.connect( 'global_stiffness_matrix_comp.K', 'states_comp.K') self.connect( 'states_comp.d', 'displacements_comp.d') self.connect( 'displacements_comp.displacements', 'compliance_comp.displacements') self.connect( 'inputs_comp.h', 'volume_comp.h') self.add_design_var('inputs_comp.h', lower=1e-2, upper=10.) self.add_objective('compliance_comp.compliance') self.add_constraint('volume_comp.volume', equals=volume)
def test_add_output(self): """Define two independent variables using the add_output method.""" from openmdao.api import Problem, IndepVarComp comp = IndepVarComp() comp.add_output('indep_var_1', val=1.0, lower=0, upper=10) comp.add_output('indep_var_2', val=2.0, lower=1, upper=20) prob = Problem(comp).setup(check=False) assert_rel_error(self, prob['indep_var_1'], 1.0) assert_rel_error(self, prob['indep_var_2'], 2.0)
def test_scalar_with_guess_func_additional_input(self): model = Group(assembled_jac_type='dense') bal = BalanceComp() bal.add_balance('x') bal.add_input('guess_x', val=0.0) ivc = IndepVarComp() ivc.add_output(name='y_tgt', val=4) ivc.add_output(name='guess_x', val=2.5) exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1}) model.add_subsystem(name='ivc', subsys=ivc, promotes_outputs=['y_tgt', 'guess_x']) model.add_subsystem(name='exec', subsys=exec_comp) model.add_subsystem(name='balance', subsys=bal) model.connect('guess_x', 'balance.guess_x') model.connect('y_tgt', 'balance.rhs:x') model.connect('balance.x', 'exec.x') model.connect('exec.y', 'balance.lhs:x') model.linear_solver = DirectSolver(assemble_jac=True) model.nonlinear_solver = NewtonSolver(maxiter=100, iprint=0) prob = Problem(model) prob.setup() # run problem without a guess function prob['balance.x'] = .5 prob.run_model() assert_almost_equal(prob['balance.x'], 2.0, decimal=7) iters_no_guess = model.nonlinear_solver._iter_count # run problem with same initial value and a guess function def guess_function(inputs, outputs, resids): outputs['x'] = inputs['guess_x'] bal.options['guess_func'] = guess_function prob['balance.x'] = .5 prob.run_model() assert_almost_equal(prob['balance.x'], 2.0, decimal=7) iters_with_guess = model.nonlinear_solver._iter_count # verify it converges faster with the guess function self.assertTrue(iters_with_guess < iters_no_guess)
def test_keys(self): p = Problem() comp = IndepVarComp() comp.add_output('v1', val=1.0) comp.add_output('v2', val=2.0) p.model.add_subsystem('des_vars', comp, promotes=['*']) p.setup() p.final_setup() keys = sorted(p.model._outputs.keys()) expected = ['des_vars.v1', 'des_vars.v2'] self.assertListEqual(keys, expected, msg='keys() is not returning the expected names')
def test_iter(self): p = Problem() comp = IndepVarComp() comp.add_output('v1', val=1.0) comp.add_output('v2', val=2.0) p.model.add_subsystem('des_vars', comp, promotes=['*']) p.setup() p.final_setup() outputs = [n for n in p.model._outputs] expected = ['des_vars.v1', 'des_vars.v2'] self.assertListEqual(outputs, expected, msg='Iter is not returning the expected names')
def test_dot(self): p = Problem() comp = IndepVarComp() comp.add_output('v1', val=1.0) comp.add_output('v2', val=2.0) p.model.add_subsystem('des_vars', comp, promotes=['*']) p.setup() p.final_setup() new_vec = p.model._outputs._clone() new_vec.set_const(3.) self.assertEqual(new_vec.dot(p.model._outputs), 9.)
def test_scalar_with_guess_func_additional_input(self): n = 1 prob = Problem(model=Group()) bal = BalanceComp() bal.add_balance('x', guess_func=lambda inputs, resids: inputs['guess_x']) bal.add_input('guess_x', val=0.0) ivc = IndepVarComp() ivc.add_output(name='y_tgt', val=4) ivc.add_output(name='guess_x', val=2.5) exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1}) prob.model.add_subsystem(name='ivc', subsys=ivc, promotes_outputs=['y_tgt', 'guess_x']) prob.model.add_subsystem(name='exec', subsys=exec_comp) prob.model.add_subsystem(name='balance', subsys=bal) prob.model.connect('guess_x', 'balance.guess_x') prob.model.connect('y_tgt', 'balance.rhs:x') prob.model.connect('balance.x', 'exec.x') prob.model.connect('exec.y', 'balance.lhs:x') prob.model.linear_solver = DirectSolver() prob.model.nonlinear_solver = NewtonSolver() prob.model.nonlinear_solver.options['maxiter'] = 100 prob.model.nonlinear_solver.options['iprint'] = 0 prob.model.jacobian = DenseJacobian() prob.setup() prob['balance.x'] = np.random.rand(n) prob.run_model() assert_almost_equal(prob['balance.x'], 2.0, decimal=7) np.set_printoptions(linewidth=1024) cpd = prob.check_partials() for (of, wrt) in cpd['balance']: assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5)
def test_add_output_type_bug(self): prob = Problem() model = prob.model ivc = IndepVarComp() ivc.add_output('x1', val=[1, 2, 3], lower=0, upper=10) model.add_subsystem('p', ivc) prob.setup() prob['p.x1'][0] = 0.5 prob.run_model() assert_rel_error(self, prob['p.x1'][0], 0.5)
def test(self): surface = get_default_surfaces()[0] ny = surface['mesh'].shape[1] group = Group() ivc = IndepVarComp() ivc.add_output('nodes', val=np.random.random_sample((ny, 3))) comp = Weight(surface=surface) group.add_subsystem('ivc', ivc, promotes=['*']) group.add_subsystem('comp', comp, promotes=['*']) run_test(self, group, compact_print=False, complex_flag=True)
def test(self): """ An example demonstrating a trivial use case of DemuxComp """ import numpy as np from openmdao.api import Problem, Group, IndepVarComp, DemuxComp, ExecComp from openmdao.utils.assert_utils import assert_rel_error # The number of elements to be demuxed n = 3 # The size of each element to be demuxed m = 100 p = Problem(model=Group()) ivc = IndepVarComp() ivc.add_output(name='pos_ecef', shape=(m, 3), units='km') p.model.add_subsystem(name='ivc', subsys=ivc, promotes_outputs=['pos_ecef']) mux_comp = p.model.add_subsystem(name='demux', subsys=DemuxComp(vec_size=n)) mux_comp.add_var('pos', shape=(m, n), axis=1, units='km') p.model.add_subsystem(name='longitude_comp', subsys=ExecComp('long = atan(y/x)', x={'value': np.ones(m), 'units': 'km'}, y={'value': np.ones(m), 'units': 'km'}, long={'value': np.ones(m), 'units': 'rad'})) p.model.connect('demux.pos_0', 'longitude_comp.x') p.model.connect('demux.pos_1', 'longitude_comp.y') p.model.connect('pos_ecef', 'demux.pos') p.setup() p['pos_ecef'][:, 0] = 6378 * np.cos(np.linspace(0, 2*np.pi, m)) p['pos_ecef'][:, 1] = 6378 * np.sin(np.linspace(0, 2*np.pi, m)) p['pos_ecef'][:, 2] = 0.0 p.run_model() expected = np.arctan(p['pos_ecef'][:, 1] / p['pos_ecef'][:, 0]) assert_rel_error(self, p.get_val('longitude_comp.long'), expected)
def test_dot_petsc(self): if not PETScVector: raise unittest.SkipTest("PETSc is not installed") p = Problem() comp = IndepVarComp() comp.add_output('v1', val=1.0) comp.add_output('v2', val=2.0) p.model.add_subsystem('des_vars', comp, promotes=['*']) p.setup() p.final_setup() new_vec = p.model._outputs._clone() new_vec.set_const(3.) self.assertEqual(new_vec.dot(p.model._outputs), 9.)
def test_debug_after_raised_error(self): prob = Problem() model = prob.model comp = IndepVarComp() comp.add_output('dXdt:TAS', val=1.0) comp.add_output('accel_target', val=2.0) model.add_subsystem('des_vars', comp, promotes=['*']) teg = model.add_subsystem('thrust_equilibrium_group', subsys=Group()) teg.add_subsystem('dynamics', ExecComp('z = 2.0*thrust'), promotes=['*']) thrust_bal = BalanceComp() thrust_bal.add_balance(name='thrust', val=1207.1, lhs_name='dXdt:TAS', rhs_name='accel_target', eq_units='m/s**2', lower=-10.0, upper=10000.0) teg.add_subsystem(name='thrust_bal', subsys=thrust_bal, promotes_inputs=['dXdt:TAS', 'accel_target'], promotes_outputs=['thrust']) teg.linear_solver = DirectSolver() teg.nonlinear_solver = NewtonSolver() teg.nonlinear_solver.options['solve_subsystems'] = True teg.nonlinear_solver.options['max_sub_solves'] = 1 teg.nonlinear_solver.options['atol'] = 1e-4 teg.nonlinear_solver.options['debug_print'] = True prob.setup(check=False) prob.set_solver_print(level=0) stdout = sys.stdout strout = StringIO() sys.stdout = strout with self.assertRaises(RuntimeError) as cm: prob.run_model() sys.stdout = stdout output = strout.getvalue() target = "'thrust_equilibrium_group.thrust_bal.thrust'" self.assertTrue(target in output, msg=target + "NOT FOUND IN" + output) # Make sure exception is unchanged. expected_msg = "Singular entry found in 'thrust_equilibrium_group' for row associated with state/residual 'thrust'." self.assertEqual(expected_msg, str(cm.exception))
def test(self): surfaces = get_default_surfaces() group = Group() comp = VLMGeometry(surface=surfaces[0]) indep_var_comp = IndepVarComp() indep_var_comp.add_output('def_mesh', val=surfaces[0]['mesh'], units='m') group.add_subsystem('geom', comp) group.add_subsystem('indep_var_comp', indep_var_comp) group.connect('indep_var_comp.def_mesh', 'geom.def_mesh') run_test(self, group)
def test2(self): surfaces = get_default_surfaces() group = Group() comp = MomentCoefficient(surfaces=surfaces) indep_var_comp = IndepVarComp() indep_var_comp.add_output('S_ref_total', val=1e4, units='m**2') group.add_subsystem('moment_calc', comp) group.add_subsystem('indep_var_comp', indep_var_comp) group.connect('indep_var_comp.S_ref_total', 'moment_calc.S_ref_total') run_test(self, group)
def test_group_assembled_jac_with_ext_mat(self): class TwoSellarDis1(ExplicitComponent): """ Component containing Discipline 1 -- no derivatives version. """ def setup(self): self.add_input('z', val=np.zeros(2)) self.add_input('x', val=np.zeros(2)) self.add_input('y2', val=np.ones(2)) self.add_output('y1', val=np.ones(2)) self.declare_partials(of='*', wrt='*') def compute(self, inputs, outputs): z1 = inputs['z'][0] z2 = inputs['z'][1] x1 = inputs['x'] y2 = inputs['y2'] outputs['y1'][0] = z1**2 + z2 + x1[0] - 0.2 * y2[0] outputs['y1'][1] = z1**2 + z2 + x1[0] - 0.2 * y2[0] def compute_partials(self, inputs, partials): """ Jacobian for Sellar discipline 1. """ partials['y1', 'y2'] = np.array([[-0.2, 0.], [0., -0.2]]) partials['y1', 'z'] = np.array([[2.0 * inputs['z'][0], 1.0], [2.0 * inputs['z'][0], 1.0]]) partials['y1', 'x'] = np.eye(2) class TwoSellarDis2(ExplicitComponent): def setup(self): self.add_input('z', val=np.zeros(2)) self.add_input('y1', val=np.ones(2)) self.add_output('y2', val=np.ones(2)) self.declare_partials('*', '*', method='fd') def compute(self, inputs, outputs): z1 = inputs['z'][0] z2 = inputs['z'][1] y1 = inputs['y1'] # Note: this may cause some issues. However, y1 is constrained to be # above 3.16, so lets just let it converge, and the optimizer will # throw it out if y1[0].real < 0.0: y1[0] *= -1 if y1[1].real < 0.0: y1[1] *= -1 outputs['y2'][0] = y1[0]**.5 + z1 + z2 outputs['y2'][1] = y1[1]**.5 + z1 + z2 def compute_partials(self, inputs, J): y1 = inputs['y1'] if y1[0].real < 0.0: y1[0] *= -1 if y1[1].real < 0.0: y1[1] *= -1 J['y2', 'y1'] = np.array([[.5 * y1[0]**-.5, 0.], [0., .5 * y1[1]**-.5]]) J['y2', 'z'] = np.array([[1.0, 1.0], [1.0, 1.0]]) prob = Problem() model = prob.model model.add_subsystem('px', IndepVarComp('x', np.array([1.0, 1.0])), promotes=['x']) model.add_subsystem('pz', IndepVarComp('z', np.array([5.0, 2.0])), promotes=['z']) sup = model.add_subsystem('sup', Group(), promotes=['*']) sub1 = sup.add_subsystem('sub1', Group(), promotes=['*']) sub2 = sup.add_subsystem('sub2', Group(), promotes=['*']) d1 = sub1.add_subsystem('d1', TwoSellarDis1(), promotes=['x', 'z', 'y1', 'y2']) sub2.add_subsystem('d2', TwoSellarDis2(), promotes=['z', 'y1', 'y2']) model.add_subsystem('con_cmp1', ExecComp('con1 = 3.16 - y1[0] - y1[1]', y1=np.array([0.0, 0.0])), promotes=['con1', 'y1']) model.add_subsystem('con_cmp2', ExecComp('con2 = y2[0] + y2[1] - 24.0', y2=np.array([0.0, 0.0])), promotes=['con2', 'y2']) model.linear_solver = LinearBlockGS() sup.linear_solver = LinearBlockGS() sub1.linear_solver = DirectSolver(assemble_jac=True) sub2.linear_solver = DirectSolver(assemble_jac=True) prob.set_solver_print(level=0) prob.setup(check=False, mode='rev') prob.run_model() of = ['con1', 'con2'] wrt = ['x', 'z'] # Make sure we don't get a size mismatch. derivs = prob.compute_totals(of=of, wrt=wrt)
def test_model_path_and_recursion(self): from openmdao.api import Problem, IndepVarComp p = Problem() model = p.model group = model.add_subsystem('G1', Group(), promotes=['*']) group2 = model.add_subsystem('G2', Group()) group.add_subsystem('ground', IndepVarComp('V', 0., units='V')) group.add_subsystem('source', IndepVarComp('I', 0.1, units='A')) group2.add_subsystem('source2', IndepVarComp('I', 0.1, units='A')) group.add_subsystem('circuit', Circuit()) group.connect('source.I', 'circuit.I_in') group.connect('ground.V', 'circuit.Vg') model.add_design_var('ground.V') model.add_design_var('source.I') model.add_objective('circuit.D1.I') p.setup(check=False) # set some initial guesses p['circuit.n1.V'] = 10. p['circuit.n2.V'] = 1. p.run_model() # No model path, no recursion write_xdsm(p, 'xdsm_circuit', out_format=PYXDSM_OUT, quiet=QUIET, show_browser=SHOW, recurse=False) self.assertTrue(os.path.isfile('.'.join(['xdsm_circuit', PYXDSM_OUT]))) # Model path given + recursion write_xdsm(p, 'xdsm_circuit2', out_format=PYXDSM_OUT, quiet=QUIET, show_browser=SHOW, recurse=True, model_path='G2', include_external_outputs=False) self.assertTrue(os.path.isfile('.'.join(['xdsm_circuit2', PYXDSM_OUT]))) # Model path given + no recursion write_xdsm(p, 'xdsm_circuit3', out_format=PYXDSM_OUT, quiet=QUIET, show_browser=SHOW, recurse=False, model_path='G1') self.assertTrue(os.path.isfile('.'.join(['xdsm_circuit3', PYXDSM_OUT]))) # Invalid model path, should raise error with self.assertRaises(ValueError): write_xdsm(p, 'xdsm_circuit4', out_format='tex', quiet=QUIET, show_browser=SHOW, recurse=False, model_path='G3')
def test_csc_masking(self): class CCBladeResidualComp(ImplicitComponent): def initialize(self): self.options.declare('num_nodes', types=int) self.options.declare('num_radial', types=int) def setup(self): num_nodes = self.options['num_nodes'] num_radial = self.options['num_radial'] self.add_input('chord', shape=(1, num_radial)) self.add_input('theta', shape=(1, num_radial)) self.add_output('phi', lower=-0.5 * np.pi, upper=0.0, shape=(num_nodes, num_radial)) self.add_output('Tp', shape=(num_nodes, num_radial)) of_names = ('phi', 'Tp') row_col = np.arange(num_radial) for name in of_names: self.declare_partials(name, 'chord', rows=row_col, cols=row_col) self.declare_partials(name, 'theta', rows=row_col, cols=row_col, val=0.0) self.declare_partials(name, 'phi', rows=row_col, cols=row_col) self.declare_partials('Tp', 'Tp', rows=row_col, cols=row_col, val=1.) def linearize(self, inputs, outputs, partials): partials['phi', 'chord'] = np.array([1., 2, 3, 4]) partials['phi', 'phi'] = np.array([5., 6, 7, 8]) partials['Tp', 'chord'] = np.array([9., 10, 11, 12]) partials['Tp', 'phi'] = np.array([13., 14, 15, 16]) prob = Problem() model = prob.model comp = IndepVarComp() comp.add_output('chord', val=np.ones((4, ))) model.add_subsystem('indep_var_comp', comp, promotes=['*']) comp = CCBladeResidualComp(num_nodes=1, num_radial=4, assembled_jac_type='csc') comp.linear_solver = DirectSolver(assemble_jac=True) model.add_subsystem('ccblade_comp', comp, promotes_inputs=['chord'], promotes_outputs=['Tp']) prob.setup(mode='fwd') prob.run_model() totals = prob.compute_totals(of=['Tp'], wrt=['chord'], return_format='array') expected = np.array([[-6.4, 0., 0., 0.], [0., -5.33333333, 0., 0.], [0., 0., -4.57142857, 0.], [0., 0., 0., -4.]]) np.testing.assert_allclose(totals, expected)
apoints_coord = aero_problem_params.apoints_coord geom_propts = GeometricalProperties(Ln,Vn,tn,an,sn,t_0,l_0,s_0_tot,Ix_0_tot,Iy_0_tot) t = geom_propts.t a = geom_propts.a s = geom_propts.s Ix = geom_propts.Ix Iy = geom_propts.Iy top = Problem() top.root = root = Group() #Add independent variables root.add('wing_area', IndepVarComp('Sw', Sw), promotes=['*']) root.add('airspeed', IndepVarComp('V', V), promotes=['*']) root.add('air_density', IndepVarComp('rho_a', rho_a), promotes=['*']) root.add('Mach_number', IndepVarComp('Mach', Mach), promotes=['*']) root.add('angle_of_attack', IndepVarComp('alpha', alpha), promotes=['*']) root.add('wing_span', IndepVarComp('b', b), promotes=['*']) root.add('wing_chord', IndepVarComp('c', c), promotes=['*']) root.add('s_coord', IndepVarComp('node_coord', node_coord), promotes=['*']) root.add('s_coord_all', IndepVarComp('node_coord_all', node_coord_all), promotes=['*']) root.add('a_coord', IndepVarComp('apoints_coord', apoints_coord), promotes=['*']) root.add('load_factor', IndepVarComp('n', n), promotes=['*']) root.add('thicknesses', IndepVarComp('t', t), promotes=['*']) if an > 0: root.add('rod_sections', IndepVarComp('a', a), promotes=['*']) root.add('bar_sections', IndepVarComp('s', s), promotes=['*'])
Length = L1 + L2 Width = W1 + W2 Height = H1 + H2 Volume = Length * Width * Height Mass = L1 * W1 * H1 * D1 + L2 * W2 * H2 * D2 return (Length, Width, Height, Volume, Mass) if __name__ == "__main__": top = Problem() root = top.root = Group() # TODO: Add reasonable input values for testing purposes root.add('L1', IndepVarComp('y', 1.0)) root.add('W1', IndepVarComp('y', 2.0)) root.add('H1', IndepVarComp('y', 3.0)) root.add('L2', IndepVarComp('y', 4.0)) root.add('W2', IndepVarComp('y', 5.0)) root.add('H2', IndepVarComp('y', 6.0)) root.add('Optimize_Container', Optimize_Container()) root.connect('L1.y', 'Optimize_Container.L1') root.connect('W1.y', 'Optimize_Container.W1') root.connect('H1.y', 'Optimize_Container.H1') root.connect('L2.y', 'Optimize_Container.L2') root.connect('W2.y', 'Optimize_Container.W2') root.connect('H2.y', 'Optimize_Container.H2')
def compute_partials(self, inputs, partials): x = inputs['x'] derivs = partials['y', 'x'].reshape((num_nodes, 2)) derivs[:, 0] = np.cos(x[:, 0]) derivs[:, 1] = -np.sin(x[:, 1]) if __name__ == '__main__': from openmdao.api import Problem, IndepVarComp num_nodes = 5 prob = Problem() comp = IndepVarComp() comp.add_output('x', val=np.random.random((num_nodes, 2))) prob.model.add_subsystem('ivc', comp, promotes=['*']) comp = CosComp(num_nodes=num_nodes) prob.model.add_subsystem('cos_comp', comp, promotes=['*']) prob.setup() prob.run_model() print(prob['x']) print(prob['y']) prob.check_partials(compact_print=True)
self.connect('D1.I', 'n2.I_out:0') self.nonlinear_solver = NewtonSolver() self.nonlinear_solver.options['iprint'] = 2 self.nonlinear_solver.options['maxiter'] = 20 self.linear_solver = DirectSolver() if __name__ == "__main__": from openmdao.api import ArmijoGoldsteinLS, Problem, IndepVarComp, BalanceComp, ExecComp from openmdao.api import NewtonSolver, DirectSolver, NonlinearRunOnce, LinearRunOnce p = Problem() model = p.model model.add_subsystem('ground', IndepVarComp('V', 0., units='V')) # replacing the fixed current source with a BalanceComp to represent a fixed Voltage source # model.add_subsystem('source', IndepVarComp('I', 0.1, units='A')) model.add_subsystem('batt', IndepVarComp('V', 1.5, units='V')) bal = model.add_subsystem('batt_balance', BalanceComp()) bal.add_balance('I', units='A', eq_units='V') model.add_subsystem('circuit', Circuit()) model.add_subsystem('batt_deltaV', ExecComp('dV = V1 - V2', V1={'units':'V'}, V2={'units':'V'}, dV={'units':'V'})) # current into the circuit is now the output state from the batt_balance comp model.connect('batt_balance.I', 'circuit.I_in') model.connect('ground.V', ['circuit.Vg','batt_deltaV.V2']) model.connect('circuit.n1.V', 'batt_deltaV.V1')
sum([j * j for j in xrange(10000000)]) # dummy delay (busy loop) unknowns['y'] = params['c'] * params['x'] if __name__ == "__main__": if MPI: # pragma: no cover # if you called this script with 'mpirun', then use the petsc data passing from openmdao.core.petsc_impl import PetscImpl as impl else: # if you didn't use `mpirun`, then use the numpy data passing from openmdao.api import BasicImpl as impl problem = Problem(impl=impl) root = problem.root = Group() root.add('indep_var', IndepVarComp('x', val=7.0)) root.add('const', IndepVarComp('c', val=3.0, pass_by_obj=False)) root.add('dut', DUT()) root.connect('indep_var.x', 'dut.x') root.connect('const.c', 'dut.c') problem.driver = UniformDriver(num_samples=10, num_par_doe=5) problem.driver.add_desvar('indep_var.x', low=4410.0, high=4450.0) problem.driver.add_objective('dut.y') recorder = DumpRecorder() problem.driver.add_recorder(recorder) problem.setup() problem.run()
# Define Parameters params = (('m_pod', 3000.0, { 'units': 'kg' }), ('l_pod', 22.0, { 'units': 'm' }), ('d_pod', 1.0, { 'units': 'm' }), ('vel_b', 23.0, { 'units': 'm/s' }), ('h_lev', 0.01, { 'unit': 'm' }), ('vel', 350.0, { 'units': 'm/s' })) prob.root.add('input_vars', IndepVarComp(params)) # Constraint Equation #root.add('con1', ExecComp('c1 = (fyu - m_pod * g)/1e5')) # Connect #prob.root.connect('lev.Drag.fyu', 'con1.fyu') #prob.root.connect('lev.Drag.g', 'con1.g') prob.root.connect('input_vars.m_pod', 'lev.m_pod') #prob.root.connect('lev.m_pod', 'con1.m_pod') prob.root.connect('input_vars.l_pod', 'lev.l_pod') prob.root.connect('input_vars.d_pod', 'lev.d_pod') prob.root.connect('input_vars.vel_b', 'lev.vel_b') prob.root.connect('input_vars.h_lev', 'lev.h_lev') prob.root.connect('input_vars.vel', 'lev.vel')
def test_case1(self): prob = Problem() model = prob.model = Cycle() model.options['thermo_method'] = 'CEA' model.options['thermo_data'] = species_data.janaf model.add_subsystem( 'ivc', IndepVarComp('in_composition', [ 3.23319235e-04, 1.10132233e-05, 5.39157698e-02, 1.44860137e-02 ])) model.add_subsystem('flow_start', FlowStart()) model.add_subsystem('combustor', Combustor()) model.pyc_connect_flow('flow_start.Fl_O', 'combustor.Fl_I') # model.set_input_defaults('Fl_I:tot:P', 100.0, units='lbf/inch**2') # model.set_input_defaults('Fl_I:tot:h', 100.0, units='Btu/lbm') # model.set_input_defaults('Fl_I:stat:W', 100.0, units='lbm/s') model.set_input_defaults('combustor.Fl_I:FAR', 0.0) model.set_input_defaults('combustor.MN', 0.5) # needed because composition is sized by connection # model.connect('ivc.in_composition', ['Fl_I:tot:composition', 'Fl_I:stat:composition', ]) prob.set_solver_print(level=2) prob.setup(check=False, force_alloc_complex=True) # 6 cases to check against for i, data in enumerate(ref_data): # input flowstation # prob['Fl_I:tot:P'] = data[h_map['Fl_I.Pt']] # prob['Fl_I:tot:h'] = data[h_map['Fl_I.ht']] # prob['Fl_I:stat:W'] = data[h_map['Fl_I.W']] # prob['Fl_I:FAR'] = data[h_map['FAR']] prob.set_val('flow_start.P', data[h_map['Fl_I.Pt']], units='psi') prob.set_val('flow_start.T', data[h_map['Fl_I.Tt']], units='degR') prob.set_val('flow_start.W', data[h_map['Fl_I.W']], units='lbm/s') prob['combustor.Fl_I:FAR'] = data[h_map['FAR']] prob['combustor.MN'] = data[h_map['Fl_O.MN']] prob.run_model() # prob.model.combustor.mix_fuel.list_inputs(print_arrays=True) # prob.model.combustor.mix_fuel.list_outputs(print_arrays=True) # print(prob['combustor.Fl_I:tot:composition']) # print(prob['combustor.Fl_I:tot:n']) print(prob['combustor.Fl_I:tot:h']) print(prob['combustor.Fl_I:tot:P']) # exit() # check outputs tol = 1.0e-2 npss = data[h_map['Fl_O.Pt']] pyc = prob['combustor.Fl_O:tot:P'] rel_err = abs(npss - pyc) / npss print('Pt out:', npss, pyc, rel_err) self.assertLessEqual(rel_err, tol) npss = data[h_map['Fl_O.Tt']] pyc = prob['combustor.Fl_O:tot:T'] rel_err = abs(npss - pyc) / npss print('Tt out:', npss, pyc, rel_err) self.assertLessEqual(rel_err, tol) npss = data[h_map['Fl_O.ht']] pyc = prob['combustor.Fl_O:tot:h'] rel_err = abs(npss - pyc) / npss print('ht out:', npss, pyc, rel_err) self.assertLessEqual(rel_err, tol) npss = data[h_map['Fl_O.Ps']] pyc = prob['combustor.Fl_O:stat:P'] rel_err = abs(npss - pyc) / npss print('Ps out:', npss, pyc, rel_err) self.assertLessEqual(rel_err, tol) npss = data[h_map['Fl_O.Ts']] pyc = prob['combustor.Fl_O:stat:T'] rel_err = abs(npss - pyc) / npss print('Ts out:', npss, pyc, rel_err) self.assertLessEqual(rel_err, tol) npss = data[h_map['Wfuel']] pyc = prob['combustor.Fl_I:stat:W'] * (prob['combustor.Fl_I:FAR']) rel_err = abs(npss - pyc) / npss print('Wfuel:', npss, pyc, rel_err) self.assertLessEqual(rel_err, tol) print('') partial_data = prob.check_partials(out_stream=None, method='cs', includes=[ 'combustor.*', ], excludes=[ '*.base_thermo.*', ]) assert_check_partials(partial_data, atol=1e-8, rtol=1e-8)
def test(self): """ This is an opt problem that tests the wingbox model with wave drag and the fuel vol constraint """ # Create a dictionary to store options about the surface mesh_dict = { 'num_y': 7, 'num_x': 2, 'wing_type': 'CRM', 'symmetry': True, 'num_twist_cp': 6, 'chord_cos_spacing': 0, 'span_cos_spacing': 0, } mesh, twist_cp = generate_mesh(mesh_dict) surf_dict = { # Wing definition 'name': 'wing', # name of the surface 'symmetry': True, # if true, model one half of wing # reflected across the plane y = 0 'S_ref_type': 'wetted', # how we compute the wing area, # can be 'wetted' or 'projected' 'fem_model_type': 'wingbox', 'spar_thickness_cp': np.array([0.004, 0.005, 0.005, 0.008, 0.008, 0.01]), # [m] 'skin_thickness_cp': np.array([0.005, 0.01, 0.015, 0.020, 0.025, 0.026]), 'twist_cp': np.array([4., 5., 8., 8., 8., 9.]), 'mesh': mesh, 'data_x_upper': upper_x, 'data_x_lower': lower_x, 'data_y_upper': upper_y, 'data_y_lower': lower_y, 'strength_factor_for_upper_skin': 1., # Aerodynamic performance of the lifting surface at # an angle of attack of 0 (alpha=0). # These CL0 and CD0 values are added to the CL and CD # obtained from aerodynamic analysis of the surface to get # the total CL and CD. # These CL0 and CD0 values do not vary wrt alpha. 'CL0': 0.0, # CL of the surface at alpha=0 'CD0': 0.0078, # CD of the surface at alpha=0 # Airfoil properties for viscous drag calculation 'k_lam': 0.05, # percentage of chord with laminar # flow, used for viscous drag 't_over_c_cp': np.array([0.08, 0.08, 0.08, 0.10, 0.10, 0.08]), 'original_wingbox_airfoil_t_over_c': 0.12, 'c_max_t': .38, # chordwise location of maximum thickness 'with_viscous': True, 'with_wave': True, # if true, compute wave drag # Structural values are based on aluminum 7075 'E': 73.1e9, # [Pa] Young's modulus 'G': ( 73.1e9 / 2 / 1.33 ), # [Pa] shear modulus (calculated using E and the Poisson's ratio here) 'yield': (420.e6 / 1.5), # [Pa] allowable yield stress 'mrho': 2.78e3, # [kg/m^3] material density 'strength_factor_for_upper_skin': 1.0, # the yield stress is multiplied by this factor for the upper skin # 'fem_origin' : 0.35, # normalized chordwise location of the spar 'wing_weight_ratio': 1.25, 'struct_weight_relief': True, 'distributed_fuel_weight': True, # Constraints 'exact_failure_constraint': False, # if false, use KS function 'fuel_density': 803., # [kg/m^3] fuel density (only needed if the fuel-in-wing volume constraint is used) 'Wf_reserve': 15000., # [kg] reserve fuel mass } surfaces = [surf_dict] # Create the problem and assign the model group prob = Problem() # Add problem information as an independent variables component indep_var_comp = IndepVarComp() indep_var_comp.add_output('v', val=.85 * 295.07, units='m/s') indep_var_comp.add_output('alpha', val=0., units='deg') indep_var_comp.add_output('Mach_number', val=0.85) indep_var_comp.add_output('re', val=0.348 * 295.07 * .85 * 1. / (1.43 * 1e-5), units='1/m') indep_var_comp.add_output('rho', val=0.348, units='kg/m**3') indep_var_comp.add_output('CT', val=0.53 / 3600, units='1/s') indep_var_comp.add_output('R', val=14.307e6, units='m') indep_var_comp.add_output('W0', val=148000 + surf_dict['Wf_reserve'], units='kg') indep_var_comp.add_output('speed_of_sound', val=295.07, units='m/s') indep_var_comp.add_output('load_factor', val=1.) indep_var_comp.add_output('empty_cg', val=np.zeros((3)), units='m') indep_var_comp.add_output('fuel_mass', val=10000., units='kg') prob.model.add_subsystem('prob_vars', indep_var_comp, promotes=['*']) # Loop over each surface in the surfaces list for surface in surfaces: # Get the surface name and create a group to contain components # only for this surface name = surface['name'] aerostruct_group = AerostructGeometry(surface=surface) # Add tmp_group to the problem with the name of the surface. prob.model.add_subsystem(name, aerostruct_group) # Loop through and add a certain number of aero points for i in range(1): point_name = 'AS_point_{}'.format(i) # Connect the parameters within the model for each aero point # Create the aero point group and add it to the model AS_point = AerostructPoint(surfaces=surfaces) prob.model.add_subsystem(point_name, AS_point) # Connect flow properties to the analysis point prob.model.connect('v', point_name + '.v') prob.model.connect('alpha', point_name + '.alpha') prob.model.connect('Mach_number', point_name + '.Mach_number') prob.model.connect('re', point_name + '.re') prob.model.connect('rho', point_name + '.rho') prob.model.connect('CT', point_name + '.CT') prob.model.connect('R', point_name + '.R') prob.model.connect('W0', point_name + '.W0') prob.model.connect('speed_of_sound', point_name + '.speed_of_sound') prob.model.connect('empty_cg', point_name + '.empty_cg') prob.model.connect('load_factor', point_name + '.load_factor') for surface in surfaces: prob.model.connect('load_factor', name + '.load_factor') prob.model.connect('load_factor', point_name + '.coupled.load_factor') com_name = point_name + '.' + name + '_perf.' prob.model.connect( name + '.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') prob.model.connect( name + '.element_weights', point_name + '.coupled.' + name + '.element_weights') # Connect performance calculation variables prob.model.connect(name + '.nodes', com_name + 'nodes') prob.model.connect( name + '.cg_location', point_name + '.' + 'total_perf.' + name + '_cg_location') prob.model.connect( name + '.structural_weight', point_name + '.' + 'total_perf.' + name + '_structural_weight') # Connect wingbox properties to von Mises stress calcs prob.model.connect(name + '.Qz', com_name + 'Qz') prob.model.connect(name + '.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', fuel_mass={ 'value': 1.0, 'units': 'kg' }, fuelburn={ 'value': 1.0, 'units': 'kg' }) prob.model.add_subsystem('fuel_diff', comp, promotes_inputs=['fuel_mass'], promotes_outputs=['fuel_diff']) prob.model.connect('AS_point_0.fuelburn', 'fuel_diff.fuelburn') #======================================================================================= #======================================================================================= from openmdao.api import ScipyOptimizeDriver prob.driver = ScipyOptimizeDriver() prob.driver.options['tol'] = 1e-9 prob.driver.options['maxiter'] = 2 # from openmdao.api import pyOptSparseDriver # prob.driver = pyOptSparseDriver() # prob.driver.add_recorder(SqliteRecorder("cases.sql")) # prob.driver.options['optimizer'] = "SNOPT" # prob.driver.opt_settings['Major optimality tolerance'] = 1e-6 # prob.driver.opt_settings['Major feasibility tolerance'] = 1e-8 # prob.driver.opt_settings['Major iterations limit'] = 200 prob.model.add_objective('AS_point_0.fuelburn', scaler=1e-5) prob.model.add_design_var('wing.twist_cp', lower=-15., upper=15., scaler=0.1) prob.model.add_design_var('wing.spar_thickness_cp', lower=0.003, upper=0.1, scaler=1e2) prob.model.add_design_var('wing.skin_thickness_cp', lower=0.003, upper=0.1, scaler=1e2) prob.model.add_design_var('wing.geometry.t_over_c_cp', lower=0.07, upper=0.2, scaler=10.) prob.model.add_design_var('fuel_mass', lower=0., upper=2e5, scaler=1e-5) prob.model.add_constraint('AS_point_0.CL', equals=0.5) prob.model.add_constraint('AS_point_0.wing_perf.failure', upper=0.) #======================================================================================= # Here we add the fuel volume constraint #======================================================================================= prob.model.add_constraint('fuel_vol_delta.fuel_vol_delta', lower=0.) prob.model.add_constraint('fuel_diff', equals=0.) #======================================================================================= #======================================================================================= # Set up the problem prob.setup() # from openmdao.api import view_model # view_model(prob) prob.run_model() # Check the partials at the initial point in the design space, # only care about relative error data = prob.check_partials(compact_print=True, out_stream=None, method='cs', step=1e-40) assert_check_partials(data, atol=1e20, rtol=1e-6) # Run the optimizer for 2 iterations prob.run_driver() # Check the partials at this point in the design space data = prob.check_partials(compact_print=True, out_stream=None, method='cs', step=1e-40) assert_check_partials(data, atol=1e20, rtol=1e-6)
def test_opt_over_doe_uq(self): np.random.seed(42) prob = Problem(impl=impl, root=Group()) prob.root.deriv_options['type'] = 'fd' subprob = Problem(impl=impl, root=SellarDerivatives()) subprob.root.deriv_options['type'] = 'fd' if MPI: npardoe = self.N_PROCS else: npardoe = 1 subprob.driver = UQTestDriver(nsamples=100, num_par_doe=npardoe) subprob.driver.add_desvar('z', std_dev=1e-2) subprob.driver.add_desvar('x', std_dev=1e-2) subprob.driver.add_response('obj') subprob.driver.add_response('con1') subprob.driver.add_response('con2') #subprob.driver.recorders.append(SqliteRecorder("subsellar.db")) prob.root.add("indeps", IndepVarComp([('x', 1.0), ('z', np.array([5.0, 2.0]))]), promotes=['x', 'z']) prob.root.add( "sub", SubProblem(subprob, params=['z', 'x'], unknowns=['obj', 'con1', 'con2'])) prob.root.connect('x', 'sub.x') prob.root.connect('z', 'sub.z') # top level driver setup prob.driver = ScipyOptimizer() prob.driver.options['optimizer'] = 'SLSQP' prob.driver.options['tol'] = 1.0e-8 prob.driver.options['maxiter'] = 50 prob.driver.options['disp'] = False prob.driver.add_desvar('z', lower=np.array([-10.0, 0.0]), upper=np.array([10.0, 10.0])) prob.driver.add_desvar('x', lower=0.0, upper=10.0) prob.driver.add_objective('sub.obj') prob.driver.add_constraint('sub.con1', upper=0.0) prob.driver.add_constraint('sub.con2', upper=0.0) #prob.driver.recorders.append(SqliteRecorder("sellar.db")) prob.setup(check=False) prob.run() tol = 1.e-3 assert_rel_error(self, prob['sub.obj'], 3.1833940, tol) assert_rel_error(self, prob['z'][0], 1.977639, tol) assert_rel_error(self, prob['z'][1], 0.0, tol) assert_rel_error(self, prob['x'], 0.0, tol)
def test(self): # 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' : 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 } # Create a dictionary to store options about the surface mesh_dict = {'num_y' : 7, 'num_x' : 2, 'wing_type' : 'rect', 'symmetry' : True, 'offset' : np.array([50, 0., 0.])} mesh = generate_mesh(mesh_dict) surf_dict2 = { # Wing definition 'name' : 'tail', # 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' : 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.0, # CD of the surface at alpha=0 'fem_origin' : 0.35, # 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, surf_dict2] # 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') # Set up the problem prob.setup() prob.run_model() assert_rel_error(self, prob['aero_point_0.wing_perf.CD'][0], 0.037210478659832125, 1e-6) assert_rel_error(self, prob['aero_point_0.wing_perf.CL'][0], 0.5124736932248048, 1e-6) assert_rel_error(self, prob['aero_point_0.CM'][1], -1.7028233361964462, 1e-6)
def test_fan_out_grouped(self): prob = Problem(impl=impl) prob.root = root = Group() root.add('p', IndepVarComp('x', 1.0)) root.add('comp1', ExecComp(['y=3.0*x'])) sub = root.add('sub', ParallelGroup()) sub.add('comp2', ExecComp(['y=-2.0*x'])) sub.add('comp3', ExecComp(['y=5.0*x'])) root.add('c2', ExecComp(['y=-x'])) root.add('c3', ExecComp(['y=3.0*x'])) root.connect('sub.comp2.y', 'c2.x') root.connect('sub.comp3.y', 'c3.x') root.connect("comp1.y", "sub.comp2.x") root.connect("comp1.y", "sub.comp3.x") root.connect("p.x", "comp1.x") prob.root.ln_solver = LinearGaussSeidel() prob.root.sub.ln_solver = LinearGaussSeidel() prob.setup(check=False) prob.run() param = 'p.x' unknown_list = ['sub.comp2.y', "sub.comp3.y"] J = prob.calc_gradient([param], unknown_list, mode='fwd', return_format='dict') assert_rel_error(self, J[unknown_list[0]][param][0][0], -6.0, 1e-6) assert_rel_error(self, J[unknown_list[1]][param][0][0], 15.0, 1e-6) J = prob.calc_gradient([param], unknown_list, mode='rev', return_format='dict') assert_rel_error(self, J[unknown_list[0]][param][0][0], -6.0, 1e-6) assert_rel_error(self, J[unknown_list[1]][param][0][0], 15.0, 1e-6) unknown_list = ['c2.y', "c3.y"] J = prob.calc_gradient([param], unknown_list, mode='fwd', return_format='dict') assert_rel_error(self, J[unknown_list[0]][param][0][0], 6.0, 1e-6) assert_rel_error(self, J[unknown_list[1]][param][0][0], 45.0, 1e-6) J = prob.calc_gradient([param], unknown_list, mode='rev', return_format='dict') assert_rel_error(self, J[unknown_list[0]][param][0][0], 6.0, 1e-6) assert_rel_error(self, J[unknown_list[1]][param][0][0], 45.0, 1e-6)
def add_subsystems(self): self.add_subsystem('A', IndepVarComp('x', 0.)) self.add_subsystem('B', CompB()) self.connect('A.x', 'B.x')
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() # print('gona check') # prob.run_model() # prob.check_partials(compact_print=True) # exit() prob.run_driver() 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 __init__(self, RefBlade): super(FloatingTurbine, self).__init__() self.add('hub_height', IndepVarComp('hub_height', 0.0), promotes=['*']) # TODO: #Weibull/Rayleigh CDF # Rotor self.add('rotor', RotorSE(RefBlade), promotes=['*']) # RNA self.add('rna', RNA(1), promotes=['downwind']) # Tower and substructure myfloat = FloatingSE() self.add('sm', myfloat, promotes=['*']) # Turbine constraints self.add('tcons', TurbineConstraints(myfloat.nFullTow), promotes=['*']) # Turbine costs self.add('tcost', Turbine_CostsSE_2015(), promotes=['*']) # Balance of station self.add('wobos', WindOBOS(), promotes=['*']) # LCOE Calculation self.add('lcoe', PlantFinance(), promotes=['*']) # Define all input variables from all models self.add('offshore', IndepVarComp('offshore', True, pass_by_obj=True), promotes=['*']) self.add('crane', IndepVarComp('crane', False, pass_by_obj=True), promotes=['*']) # Turbine Costs # REMOVE ONCE DRIVESE AND GENERATORSE ARE CONNECTED self.add('bearing_number', IndepVarComp('bearing_number', 0, pass_by_obj=True), promotes=['*']) self.add('bedplate_mass', IndepVarComp('bedplate_mass', 0.0), promotes=['*']) self.add('crane_cost', IndepVarComp('crane_cost', 0.0), promotes=['*']) self.add('gearbox_mass', IndepVarComp('gearbox_mass', 0.0), promotes=['*']) self.add('generator_mass', IndepVarComp('generator_mass', 0.0), promotes=['*']) self.add('hss_mass', IndepVarComp('hss_mass', 0.0), promotes=['*']) self.add('hvac_mass', IndepVarComp('hvac_mass', 0.0), promotes=['*']) self.add('lss_mass', IndepVarComp('lss_mass', 0.0), promotes=['*']) self.add('main_bearing_mass', IndepVarComp('main_bearing_mass', 0.0), promotes=['*']) self.add('cover_mass', IndepVarComp('cover_mass', 0.0), promotes=['*']) self.add('platforms_mass', IndepVarComp('platforms_mass', 0.0), promotes=['*']) self.add('pitch_system_mass', IndepVarComp('pitch_system_mass', 0.0), promotes=['*']) self.add('spinner_mass', IndepVarComp('spinner_mass', 0.0), promotes=['*']) self.add('transformer_mass', IndepVarComp('transformer_mass', 0.0), promotes=['*']) self.add('vs_electronics_mass', IndepVarComp('vs_electronics_mass', 0.0), promotes=['*']) self.add('yaw_mass', IndepVarComp('yaw_mass', 0.0), promotes=['*']) # Tower #self.add('stress_standard_value', IndepVarComp('stress_standard_value', 0.0), promotes=['*']) #self.add('fatigue_parameters', IndepVarComp('fatigue_parameters', np.zeros(nDEL)), promotes=['*']) #self.add('fatigue_z', IndepVarComp('fatigue_z', np.zeros(nDEL)), promotes=['*']) #self.add('frame3dd_matrix_method', IndepVarComp('frame3dd_matrix_method', 0, pass_by_obj=True), promotes=['*']) #self.add('compute_stiffnes', IndepVarComp('compute_stiffnes', False, pass_by_obj=True), promotes=['*']) self.add('project_lifetime', IndepVarComp('project_lifetime', 0.0), promotes=['*']) #self.add('lumped_mass_matrix', IndepVarComp('lumped_mass_matrix', 0, pass_by_obj=True), promotes=['*']) #self.add('slope_SN', IndepVarComp('slope_SN', 0, pass_by_obj=True), promotes=['*']) #self.add('number_of_modes', IndepVarComp('number_of_modes', 0, pass_by_obj=True), promotes=['*']) #self.add('compute_shear', IndepVarComp('compute_shear', True, pass_by_obj=True), promotes=['*']) #self.add('shift_value', IndepVarComp('shift_value', 0.0), promotes=['*']) #self.add('frame3dd_convergence_tolerance', IndepVarComp('frame3dd_convergence_tolerance', 1e-9), promotes=['*']) # TODO: Multiple load cases # Environment self.add('air_density', IndepVarComp('air_density', 0.0), promotes=['*']) self.add('air_viscosity', IndepVarComp('air_viscosity', 0.0), promotes=['*']) self.add('wind_reference_speed', IndepVarComp('wind_reference_speed', 0.0), promotes=['*']) self.add('wind_reference_height', IndepVarComp('wind_reference_height', 0.0), promotes=['*']) self.add('shearExp', IndepVarComp('shearExp', 0.0), promotes=['*']) self.add('wind_bottom_height', IndepVarComp('wind_bottom_height', 0.0), promotes=['*']) self.add('wind_beta', IndepVarComp('wind_beta', 0.0), promotes=['*']) self.add('cd_usr', IndepVarComp('cd_usr', np.inf), promotes=['*']) # Environment self.add('water_depth', IndepVarComp('water_depth', 0.0), promotes=['*']) self.add('water_density', IndepVarComp('water_density', 0.0), promotes=['*']) self.add('water_viscosity', IndepVarComp('water_viscosity', 0.0), promotes=['*']) self.add('wave_height', IndepVarComp('wave_height', 0.0), promotes=['*']) self.add('wave_period', IndepVarComp('wave_period', 0.0), promotes=['*']) self.add('mean_current_speed', IndepVarComp('mean_current_speed', 0.0), promotes=['*']) #self.add('wave_beta', IndepVarComp('wave_beta', 0.0), promotes=['*']) #self.add('wave_velocity_z0', IndepVarComp('wave_velocity_z0', 0.0), promotes=['*']) #self.add('wave_acceleration_z0', IndepVarComp('wave_acceleration_z0', 0.0), promotes=['*']) # Design standards self.add('gamma_freq', IndepVarComp('gamma_freq', 0.0), promotes=['*']) self.add('gamma_f', IndepVarComp('gamma_f', 0.0), promotes=['*']) self.add('gamma_m', IndepVarComp('gamma_m', 0.0), promotes=['*']) self.add('gamma_b', IndepVarComp('gamma_b', 0.0), promotes=['*']) self.add('gamma_fatigue', IndepVarComp('gamma_fatigue', 0.0), promotes=['*']) self.add('gamma_n', IndepVarComp('gamma_n', 0.0), promotes=['*']) # RNA self.add('dummy_mass', IndepVarComp('dummy_mass', 0.0), promotes=['*']) self.add('hub_mass', IndepVarComp('hub_mass', 0.0), promotes=['*']) self.add('nac_mass', IndepVarComp('nac_mass', 0.0), promotes=['*']) self.add('hub_cm', IndepVarComp('hub_cm', np.zeros((3, ))), promotes=['*']) self.add('nac_cm', IndepVarComp('nac_cm', np.zeros((3, ))), promotes=['*']) self.add('hub_I', IndepVarComp('hub_I', np.zeros(6)), promotes=['*']) self.add('nac_I', IndepVarComp('nac_I', np.zeros(6)), promotes=['*']) self.add('rna_weightM', IndepVarComp('rna_weightM', True, pass_by_obj=True), promotes=['*']) # Column self.add('morison_mass_coefficient', IndepVarComp('morison_mass_coefficient', 0.0), promotes=['*']) self.add('material_density', IndepVarComp('material_density', 0.0), promotes=['*']) self.add('E', IndepVarComp('E', 0.0), promotes=['*']) self.add('nu', IndepVarComp('nu', 0.0), promotes=['*']) self.add('yield_stress', IndepVarComp('yield_stress', 0.0), promotes=['*']) # Pontoons self.add('G', IndepVarComp('G', 0.0), promotes=['*']) # LCOE self.add('number_of_turbines', IndepVarComp('number_of_turbines', 0, pass_by_obj=True), promotes=['*']) self.add('annual_opex', IndepVarComp('annual_opex', 0.0), promotes=['*']) # TODO: Replace with output connection self.add('fixed_charge_rate', IndepVarComp('fixed_charge_rate', 0.0), promotes=['*']) self.add('discount_rate', IndepVarComp('discount_rate', 0.0), promotes=['*']) # Connect all input variables from all models self.connect('water_depth', ['waterD', 'sea_depth']) self.connect('hub_height', 'hubH') self.connect('tower_outer_diameter', 'towerD', src_indices=[0]) self.connect('wind_beta', 'beta') self.connect('mean_current_speed', 'Uc') self.connect('project_lifetime', ['struc.lifetime', 'projLife']) #self.connect('slope_SN', 'm_SN') #self.connect('compute_shear', 'shear') #self.connect('compute_stiffnes', 'geom') #self.connect('frame3dd_matrix_method', 'Mmethod') #self.connect('shift_value', 'shift') # TODO: #self.connect('number_of_modes', ['nM', 'nF']) #self.connect('frame3dd_convergence_tolerance', 'tol') #self.connect('lumped_mass_matrix', 'lump') #self.connect('stress_standard_value', 'DC') self.connect('rna.loads.top_F', 'rna_force') self.connect('rna.loads.top_M', 'rna_moment') self.connect('rna.rna_I_TT', 'rna_I') self.connect('rna.rna_mass', ['rnaM', 'rna_mass']) self.connect('rna.rna_cm', 'rna_cg') self.connect('mass_all_blades', 'rna.blades_mass') self.connect('I_all_blades', 'rna.blades_I') self.connect('hub_mass', 'rna.hub_mass') self.connect('nac_mass', 'rna.nac_mass') self.connect('hub_cm', 'rna.hub_cm') self.connect('nac_cm', 'rna.nac_cm') self.connect('hub_I', 'rna.hub_I') self.connect('nac_I', 'rna.nac_I') self.connect('tilt', 'rna.tilt') self.connect('Fxyz_total', 'rna.loads.F') self.connect('Mxyz_total', 'rna.loads.M') self.connect('rna_weightM', 'rna.rna_weightM') self.connect('air_density', ['main.windLoads.rho', 'analysis.rho']) self.connect('air_viscosity', ['main.windLoads.mu', 'analysis.mu']) self.connect('water_density', 'water_density') self.connect('water_viscosity', 'main.waveLoads.mu') self.connect('wave_height', 'Hs') self.connect('wave_period', 'T') self.connect('wind_reference_speed', 'Uref') self.connect('wind_reference_height', ['zref', 'wind.zref']) self.connect('wind_bottom_height', ['z0', 'wind.z0']) self.connect('shearExp', 'wind.shearExp') self.connect('morison_mass_coefficient', 'cm') self.connect('ballast_cost_rate', 'ballCR') self.connect('mooring_cost_rate', 'moorCR') self.connect('mooring_cost', 'moorCost') self.connect('mooring_diameter', 'moorDia') self.connect('number_of_mooring_lines', 'moorLines') self.connect('material_cost_rate', 'sSteelCR') self.connect('main.tapered_column_cost_rate', ['spStifColCR', 'spTapColCR', 'ssStifColCR']) self.connect('pontoon_cost_rate', 'ssTrussCR') self.connect('nBlades', 'blade_number') self.connect('mass_one_blade', 'blade_mass') self.connect('control_maxOmega', 'rotor_omega') self.connect('structural_frequencies', 'tower_freq') self.connect('turbine_cost_kW', 'turbCapEx') self.connect('machine_rating', 'turbR') self.connect('diameter', 'rotorD') self.connect('bladeLength', 'bladeL') self.connect('hub_diameter', 'hubD') # Link outputs from one model to inputs to another self.connect('tower_mass', 'towerM') self.connect('dummy_mass', 'off.stack_mass_in') self.connect('total_cost', 'subTotCost') self.connect('total_mass', 'subTotM') self.connect('total_bos_cost', 'bos_costs') self.connect('number_of_turbines', ['nTurb', 'turbine_number']) self.connect('annual_opex', 'avg_annual_opex') self.connect('AEP', 'net_aep') self.connect('totInstTime', 'construction_time') # Use complex number finite differences typeStr = 'fd' formStr = 'central' stepVal = 1e-5 stepStr = 'relative' self.deriv_options['type'] = typeStr self.deriv_options['form'] = formStr self.deriv_options['step_size'] = stepVal self.deriv_options['step_calc'] = stepStr
def test_assembled_jacobian_unsupported_cases(self): class ParaboloidApply(ImplicitComponent): def setup(self): self.add_input('x', val=0.0) self.add_input('y', val=0.0) self.add_output('f_xy', val=0.0) def linearize(self, inputs, outputs, jacobian): return def apply_linear(self, inputs, outputs, d_inputs, d_outputs, d_residuals, mode): d_residuals['x'] += ( np.exp(outputs['x']) - 2 * inputs['a']**2 * outputs['x']) * d_outputs['x'] d_residuals['x'] += (-2 * inputs['a'] * outputs['x']**2) * d_inputs['a'] # One level deep prob = Problem() model = prob.model = Group(assembled_jac_type='dense') model.linear_solver = DirectSolver(assemble_jac=True) model.add_subsystem('p1', IndepVarComp('x', val=1.0)) model.add_subsystem('p2', IndepVarComp('y', val=1.0)) model.add_subsystem('comp', ParaboloidApply()) model.connect('p1.x', 'comp.x') model.connect('p2.y', 'comp.y') prob.setup() msg = "AssembledJacobian not supported for matrix-free subcomponent." with self.assertRaisesRegex(Exception, msg): prob.run_model() # Nested prob = Problem() model = prob.model = Group(assembled_jac_type='dense') model.linear_solver = DirectSolver(assemble_jac=True) sub = model.add_subsystem('sub', Group()) model.add_subsystem('p1', IndepVarComp('x', val=1.0)) model.add_subsystem('p2', IndepVarComp('y', val=1.0)) sub.add_subsystem('comp', ParaboloidApply()) model.connect('p1.x', 'sub.comp.x') model.connect('p2.y', 'sub.comp.y') prob.setup() msg = "AssembledJacobian not supported for matrix-free subcomponent." with self.assertRaisesRegex(Exception, msg): prob.run_model() # Try a component that is derived from a matrix-free one class FurtherDerived(ParaboloidApply): def do_nothing(self): pass prob = Problem() model = prob.model = Group(assembled_jac_type='dense') model.linear_solver = DirectSolver(assemble_jac=True) model.add_subsystem('p1', IndepVarComp('x', val=1.0)) model.add_subsystem('p2', IndepVarComp('y', val=1.0)) model.add_subsystem('comp', FurtherDerived()) model.connect('p1.x', 'comp.x') model.connect('p2.y', 'comp.y') prob.setup() msg = "AssembledJacobian not supported for matrix-free subcomponent." with self.assertRaisesRegex(Exception, msg): prob.run_model() # Make sure regular comps don't give an error. prob = Problem() model = prob.model = Group(assembled_jac_type='dense') model.linear_solver = DirectSolver(assemble_jac=True) model.add_subsystem('p1', IndepVarComp('x', val=1.0)) model.add_subsystem('p2', IndepVarComp('y', val=1.0)) model.add_subsystem('comp', Paraboloid()) model.connect('p1.x', 'comp.x') model.connect('p2.y', 'comp.y') prob.setup() prob.final_setup() class ParaboloidJacVec(Paraboloid): def linearize(self, inputs, outputs, jacobian): return def compute_jacvec_product(self, inputs, d_inputs, d_outputs, d_residuals, mode): d_residuals['x'] += ( np.exp(outputs['x']) - 2 * inputs['a']**2 * outputs['x']) * d_outputs['x'] d_residuals['x'] += (-2 * inputs['a'] * outputs['x']**2) * d_inputs['a'] # One level deep prob = Problem() model = prob.model = Group(assembled_jac_type='dense') model.linear_solver = DirectSolver(assemble_jac=True) model.add_subsystem('p1', IndepVarComp('x', val=1.0)) model.add_subsystem('p2', IndepVarComp('y', val=1.0)) model.add_subsystem('comp', ParaboloidJacVec()) model.connect('p1.x', 'comp.x') model.connect('p2.y', 'comp.y') prob.setup() msg = "AssembledJacobian not supported for matrix-free subcomponent." with self.assertRaisesRegex(Exception, msg): prob.run_model()
def setup(self): fe_model = self.options['fe_model'] nelx = self.options['num_ele_x'] nely = self.options['num_ele_y'] penal = self.options['penal_factor'] volume_fraction = self.options['volume_fraction'] radius = self.options['filter_radius'] max_buckling_load = self.options['max_buckling_load'] initial_x = self.options['initial_densities'] data_recorder = self.options['data_recorder'] # Check FEA assembly and evaluate dimensions of the sparse matrix n_elements = nelx * nely n_dof = 2 * (nelx + 1) * (nely + 1) unknown_dof = fe_model.unknown_dof # Inside default parameters n_eigenvalues = 5 eigenvalue_gap = 1.01 #aggregation_parameter = 30.0 minimum_x = 1e-6 # Setup design variables ['densities'] comp = IndepVarComp() comp.add_output('densities', val=initial_x, shape=n_elements) comp.add_design_var('densities', lower=0.0, upper=1.0) self.add_subsystem('input_comp', comp) self.connect('input_comp.densities', 'filter_comp.densities') # Density Filter comp = DensityFilterComp(num_ele_x=nelx, num_ele_y=nely, radius=radius) self.add_subsystem('filter_comp', comp) self.connect('filter_comp.densities_f', 'penalization_comp.densities') self.connect('filter_comp.densities_f', 'volume_comp.densities') # Penalization comp = PenalizationComp(penal=penal, n_elements=n_elements) self.add_subsystem('penalization_comp', comp) self.connect('penalization_comp.multipliers', 'states_comp.multipliers') ## STATES COMP comp = States_comp(number_of_elements=n_elements, number_of_dof=n_dof, finite_elements_model=fe_model) self.add_subsystem('states_comp', comp) self.connect('states_comp.states', 'compliance_comp.displacements') # Compliance comp = ComplianceComp(fe_model=fe_model, ndof=n_dof, unknown_dof=unknown_dof, data_recorder=data_recorder) self.add_subsystem('compliance_comp', comp) # Volume comp = VolumeComp(nelements=n_elements, data_recorder=data_recorder) self.add_subsystem('volume_comp', comp) # Design variables self.add_design_var('input_comp.densities', upper=1) # Objective #self.add_objective('volume_comp.volume') self.add_objective('compliance_comp.compliance') # Constraints: self.add_constraint('volume_comp.volume', upper=volume_fraction, linear=True)
def test1(self): r = np.array([2.8667, 5.6000, 8.3333, 11.7500, 15.8500, 19.9500, 24.0500, 28.1500, 32.2500, 36.3500, 40.4500, 44.5500, 48.6500, 52.7500, 56.1667, 58.9000, 61.6333]) chord = np.array([3.542, 3.854, 4.167, 4.557, 4.652, 4.458, 4.249, 4.007, 3.748, 3.502, 3.256, 3.010, 2.764, 2.518, 2.313, 2.086, 1.419]) theta = np.array([13.308, 13.308, 13.308, 13.308, 11.480, 10.162, 9.011, 7.795, 6.544, 5.361, 4.188, 3.125, 2.319, 1.526, 0.863, 0.370, 0.106]) Rhub = 1.5 Rtip = 63.0 hubHt = 80.0 precone = 2.5 tilt = -5.0 yaw = 0.0 B = 3 rho = 1.225 mu = 1.81206e-5 shearExp = 0.2 nSector = 4 precurve = np.zeros(len(r)) precurveTip = 0.0 # airfoils basepath = os.path.join(os.path.dirname(os.path.realpath(__file__)), '5MW_AFFiles/') # load all airfoils airfoil_types = [0]*8 airfoil_types[0] = basepath + 'Cylinder1.dat' airfoil_types[1] = basepath + 'Cylinder2.dat' airfoil_types[2] = basepath + 'DU40_A17.dat' airfoil_types[3] = basepath + 'DU35_A17.dat' airfoil_types[4] = basepath + 'DU30_A17.dat' airfoil_types[5] = basepath + 'DU25_A17.dat' airfoil_types[6] = basepath + 'DU21_A17.dat' airfoil_types[7] = basepath + 'NACA64_A17.dat' # place at appropriate radial stations af_idx = [0, 0, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7] n = len(r) af = [0]*n for i in range(n): af[i] = airfoil_types[af_idx[i]] airfoil_files = np.array(af) run_case = 'power' Uhub = np.array([3.0, 4.15789473684, 5.31578947368, 6.47368421053, 7.63157894737, 8.78947368421, 9.94736842105, 11.1052631579, 12.2631578947, 13.4210526316, 14.5789473684, 15.7368421053, 16.8947368421, 18.0526315789, 19.2105263158, 20.3684210526, 21.5263157895, 22.6842105263, 23.8421052632, 25.0]) Omega = np.array([3.43647024491, 4.76282718154, 6.08918411817, 7.41554105481, 8.74189799144, 10.0682549281, 11.3946118647, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0]) pitch = np.array([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) n2 = len(Uhub) prob = Problem() prob.root = Group() prob.root.add('comp', CCBlade(run_case, n, n2), promotes=['*']) prob.root.add('r', IndepVarComp('r', np.zeros(len(r))), promotes=['*']) prob.root.add('chord', IndepVarComp('chord', np.zeros(len(chord))), promotes=['*']) prob.root.add('theta', IndepVarComp('theta', np.zeros(len(theta))), promotes=['*']) prob.root.add('Rhub', IndepVarComp('Rhub', 0.0), promotes=['*']) prob.root.add('Rtip', IndepVarComp('Rtip', 0.0), promotes=['*']) prob.root.add('hubHt', IndepVarComp('hubHt', 0.0), promotes=['*']) prob.root.add('precone', IndepVarComp('precone', 0.0), promotes=['*']) prob.root.add('precurve', IndepVarComp('precurve', precurve), promotes=['*']) prob.root.add('precurveTip', IndepVarComp('precurveTip', 0.0), promotes=['*']) prob.root.add('tilt', IndepVarComp('tilt', 0.0), promotes=['*']) prob.root.add('yaw', IndepVarComp('yaw', 0.0), promotes=['*']) prob.root.add('B', IndepVarComp('B', 0), promotes=['*']) prob.root.add('rho', IndepVarComp('rho', 0.0), promotes=['*']) prob.root.add('mu', IndepVarComp('mu', 0.0), promotes=['*']) prob.root.add('shearExp', IndepVarComp('shearExp', 0.0, pass_by_obj=True), promotes=['*']) prob.root.add('nSector', IndepVarComp('nSector', nSector), promotes=['*']) prob.root.add('airfoil_files', IndepVarComp('airfoil_files', airfoil_files), promotes=['*']) prob.root.add('Uhub', IndepVarComp('Uhub', np.zeros(len(Uhub))), promotes=['*']) prob.root.add('Omega', IndepVarComp('Omega', np.zeros(len(Omega))), promotes=['*']) prob.root.add('pitch', IndepVarComp('pitch', np.zeros(len(pitch))), promotes=['*']) prob.setup(check=False) prob['r'] = r prob['chord'] = chord prob['theta'] = theta prob['Rhub'] = Rhub prob['Rtip'] = Rtip prob['hubHt'] = hubHt prob['precone'] = precone prob['tilt'] = tilt prob['yaw'] = yaw prob['B'] = B prob['rho'] = rho prob['mu'] = mu prob['shearExp'] = shearExp prob['nSector'] = nSector prob['airfoil_files'] = airfoil_files prob['Uhub'] = Uhub prob['Omega'] = Omega prob['pitch'] = pitch prob['precurve'] = precurve prob['precurveTip'] = precurveTip check_gradient_unit_test(self, prob, tol=1e-3, display=True)
def __init__(self): super(EESG_Opt, self).__init__() self.add('machine_rating', IndepVarComp('machine_rating',0.0),promotes=['*']) self.add('Torque',IndepVarComp('Torque', val=0.0),promotes=['*']) self.add('n_nom', IndepVarComp('n_nom', val=0.0),promotes=['*']) self.add('main_shaft_cm', IndepVarComp('main_shaft_cm',val=np.array([0.0, 0.0, 0.0])),promotes=['*']) self.add('main_shaft_length',IndepVarComp('main_shaft_length',val=0.0),promotes=['*']) self.add('r_s',IndepVarComp('r_s',0.0),promotes=['*']) self.add('l_s',IndepVarComp('l_s',0.0),promotes=['*']) self.add('h_s',IndepVarComp('h_s',0.0),promotes=['*']) self.add('tau_p',IndepVarComp('tau_p',0.0),promotes=['*']) self.add('I_f',IndepVarComp('I_f',0.0),promotes=['*']) self.add('N_f',IndepVarComp('N_f',0.0),promotes=['*']) self.add('h_ys',IndepVarComp('h_ys',0.0),promotes=['*']) self.add('h_yr',IndepVarComp('h_yr',0.0),promotes=['*']) self.add('n_s',IndepVarComp('n_s',0.0),promotes=['*']) self.add('b_st',IndepVarComp('b_st',0.0),promotes=['*']) self.add('n_r',IndepVarComp('n_r',0.0),promotes=['*']) self.add('b_r',IndepVarComp('b_r',0.0),promotes=['*']) self.add('d_r',IndepVarComp('d_r',0.0),promotes=['*']) self.add('d_s',IndepVarComp('d_s',0.0),promotes=['*']) self.add('t_wr',IndepVarComp('t_wr',0.0),promotes=['*']) self.add('t_ws',IndepVarComp('t_ws',0.0),promotes=['*']) self.add('R_o',IndepVarComp('R_o',0.0),promotes=['*']) self.add('rho_Fes',IndepVarComp('rho_Fes',0.0),promotes=['*']) self.add('rho_Fe',IndepVarComp('rho_Fe',0.0),promotes=['*']) self.add('rho_Copper',IndepVarComp('rho_Copper',0.0),promotes=['*']) # add EESG component, create constraint equations self.add('EESG',EESG(),promotes=['*']) self.add('con_uAs', ExecComp('con_uAs =u_all_s-u_As'),promotes=['*']) self.add('con_zAs', ExecComp('con_zAs =z_all_s-z_A_s'),promotes=['*']) self.add('con_yAs', ExecComp('con_yAs =y_all-y_As'),promotes=['*']) self.add('con_bst', ExecComp('con_bst =b_all_s-b_st'),promotes=['*']) self.add('con_uAr', ExecComp('con_uAr =u_all_r-u_Ar'),promotes=['*']) self.add('con_zAr', ExecComp('con_zAr =z_all_r-z_A_r'),promotes=['*']) self.add('con_yAr', ExecComp('con_yAr =y_all-y_Ar'),promotes=['*']) self.add('con_br', ExecComp('con_br =b_all_r-b_r'),promotes=['*']) self.add('con_TC2', ExecComp('con_TC2 =TC2-TC1'),promotes=['*']) self.add('con_TC3', ExecComp('con_TC3 =TC3-TC1'),promotes=['*']) # add EESG_Cost component self.add('EESG_Cost',EESG_Cost(),promotes=['*']) self.add('C_Cu',IndepVarComp('C_Cu',val=0.0),promotes=['*']) self.add('C_Fe',IndepVarComp('C_Fe',val=0.0),promotes=['*']) self.add('C_Fes',IndepVarComp('C_Fes',val=0.0),promotes=['*'])
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 } # Create the problem and assign the model group prob = Problem() # Add problem information as an independent variables component indep_var_comp = IndepVarComp() indep_var_comp.add_output('v', val=248.136, units='m/s') indep_var_comp.add_output('alpha', val=5., units='deg') indep_var_comp.add_output('Mach_number', val=0.84) indep_var_comp.add_output('re', val=1.e6, units='1/m') indep_var_comp.add_output('rho', val=0.38, units='kg/m**3') indep_var_comp.add_output('CT', val=grav_constant * 17.e-6, units='1/s') indep_var_comp.add_output('R', val=11.165e6, units='m') indep_var_comp.add_output('W0', val=0.4 * 3e5, units='kg') indep_var_comp.add_output('speed_of_sound', val=295.4, units='m/s') indep_var_comp.add_output('load_factor', val=1.) indep_var_comp.add_output('empty_cg', val=np.zeros((3)), units='m') prob.model.add_subsystem('prob_vars', indep_var_comp, promotes=['*']) aerostruct_group = AerostructGeometry(surface=surface)
def setup_helper(self, NozzType, LossType): self.prob = Problem() self.prob.model = Group() des_vars = self.prob.model.add_subsystem('des_vars', IndepVarComp(), promotes=['*']) des_vars.add_output('Pt', 17.0, units='psi') des_vars.add_output('Tt', 500.0, units='degR') des_vars.add_output('W', 0.0, units='lbm/s') des_vars.add_output('MN', 0.2) des_vars.add_output('Ps_exhaust', 17.0, units='psi') des_vars.add_output('Cv', 0.99) des_vars.add_output('Cfg', 0.99) self.prob.model.add_subsystem('flow_start', FlowStart(thermo_data=janaf, elements=AIR_MIX)) self.prob.model.add_subsystem('nozzle', Nozzle(nozzType=NozzType, lossCoef=LossType, thermo_data=janaf, elements=AIR_MIX, internal_solver=True)) connect_flow(self.prob.model, "flow_start.Fl_O", "nozzle.Fl_I") self.prob.model.connect("Pt", "flow_start.P") self.prob.model.connect("Tt", "flow_start.T") self.prob.model.connect("W", "flow_start.W") self.prob.model.connect("MN", "flow_start.MN") self.prob.model.connect("Ps_exhaust", "nozzle.Ps_exhaust") if LossType == 'Cv': self.prob.model.connect("Cv", "nozzle.Cv") elif LossType == 'Cfg': self.prob.model.connect("Cfg", "nozzle.Cfg") # self.prob.model.connect("area_targ", "compressor.area") self.prob.set_solver_print(level=2) self.prob.setup(check=False) header = [ 'Cfg', 'Cv', 'PsExh', 'Fl_I.W', 'Fl_I.MN', 'Fl_I.s', 'Fl_I.Pt', 'Fl_I.Tt', 'Fl_I.ht', 'Fl_I.rhot', 'Fl_I.gamt', 'Fl_O.MN', 'Fl_O.s', 'Fl_O.Pt', 'Fl_O.Tt', 'Fl_O.ht', 'Fl_O.rhot', 'Fl_O.gamt', 'Fl_O.Ps', 'Fl_Th.MN', 'Fl_Th.s', 'Fl_Th.Pt', 'Fl_Th.Tt', 'Fl_Th.ht', 'Fl_Th.rhot', 'Fl_Th.gamt', 'Fl_Th.Ps', 'Fl_Th.Aphy', 'Fg', 'FgIdeal', 'Vactual', 'AthCold', 'AR', 'PR'] self.h_map = dict(((v_name, i) for i, v_name in enumerate(header))) self.fpath = os.path.dirname(os.path.realpath(__file__))
def setup(self): num_times = self.options['num_times'] num_cp = self.options['num_cp'] step_size = self.options['step_size'] cubesat = self.options['cubesat'] mtx = self.options['mtx'] Ground_station = self.options['Ground_station'] times = np.linspace(0., step_size * (num_times - 1), num_times) comp = IndepVarComp() comp.add_output('times', units='s', val=times) comp.add_output('Initial_Data', val=np.zeros((1, ))) self.add_subsystem('inputs_comp', comp, promotes=['*']) group = AttitudeGroup( num_times=num_times, num_cp=num_cp, cubesat=cubesat, mtx=mtx, ) self.add_subsystem('attitude_group', group, promotes=['*']) group = PropulsionGroup( num_times=num_times, num_cp=num_cp, step_size=step_size, cubesat=cubesat, mtx=mtx, ) self.add_subsystem('propulsion_group', group, promotes=['*']) group = AerodynamicsGroup( num_times=num_times, num_cp=num_cp, step_size=step_size, cubesat=cubesat, mtx=mtx, ) self.add_subsystem('aerodynamics_group', group, promotes=['*']) group = OrbitGroup( num_times=num_times, num_cp=num_cp, step_size=step_size, cubesat=cubesat, mtx=mtx, ) self.add_subsystem('orbit_group', group, promotes=['*']) for Ground_station in cubesat.children: name = Ground_station['name'] group = CommGroup( num_times=num_times, num_cp=num_cp, step_size=step_size, Ground_station=Ground_station, mtx=mtx, ) # self.connect('times', '{}_comm_group.times'.format(name)) self.add_subsystem('{}_comm_group'.format(name), group) # name = cubesat['name'] shape = (1, num_times) rho = 100. # cubesat_name = cubesat['name'] comp = ElementwiseMaxComp(shape=shape, in_names=[ 'UCSD_comm_group_Download_rate', 'UIUC_comm_group_Download_rate', 'Georgia_comm_group_Download_rate', 'Montana_comm_group_Download_rate', ], out_name='KS_Download_rate', rho=rho) self.add_subsystem('KS_Download_rate_comp', comp, promotes=['*']) for Ground_station in cubesat.children: Ground_station_name = Ground_station['name'] self.connect( '{}_comm_group.Download_rate'.format(Ground_station_name), '{}_comm_group_Download_rate'.format(Ground_station_name), ) # self.connect( # '{}_comm_group.Download_rate'.format(Ground_station_name), # '{}_comm_group_Download_rate'.format(Ground_station_name), # ) comp = DataDownloadComp( num_times=num_times, step_size=step_size, ) self.add_subsystem('Data_download_rk4_comp', comp, promotes=['*']) comp = ExecComp( 'total_Data = Data[-1] - Data[0]', Data=np.empty(num_times), ) self.add_subsystem('KS_total_Data_comp', comp, promotes=['*'])
def test2(self): r = np.array([2.8667, 5.6000, 8.3333, 11.7500, 15.8500, 19.9500, 24.0500, 28.1500, 32.2500, 36.3500, 40.4500, 44.5500, 48.6500, 52.7500, 56.1667, 58.9000, 61.6333]) chord = np.array([3.542, 3.854, 4.167, 4.557, 4.652, 4.458, 4.249, 4.007, 3.748, 3.502, 3.256, 3.010, 2.764, 2.518, 2.313, 2.086, 1.419]) theta = np.array([13.308, 13.308, 13.308, 13.308, 11.480, 10.162, 9.011, 7.795, 6.544, 5.361, 4.188, 3.125, 2.319, 1.526, 0.863, 0.370, 0.106]) Rhub = 1.5 Rtip = 63.0 hubHt = 80.0 precone = 2.5 tilt = -5.0 yaw = 0.0 B = 3 rho = 1.225 mu = 1.81206e-5 shearExp = 0.2 nSector = 4 precurve = np.zeros(len(r)) # airfoils basepath = os.path.join(os.path.dirname(os.path.realpath(__file__)), '5MW_AFFiles/') # load all airfoils airfoil_types = [0]*8 airfoil_types[0] = basepath + 'Cylinder1.dat' airfoil_types[1] = basepath + 'Cylinder2.dat' airfoil_types[2] = basepath + 'DU40_A17.dat' airfoil_types[3] = basepath + 'DU35_A17.dat' airfoil_types[4] = basepath + 'DU30_A17.dat' airfoil_types[5] = basepath + 'DU25_A17.dat' airfoil_types[6] = basepath + 'DU21_A17.dat' airfoil_types[7] = basepath + 'NACA64_A17.dat' # place at appropriate radial stations af_idx = [0, 0, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7] n = len(r) af = [0]*n for i in range(n): af[i] = airfoil_types[af_idx[i]] airfoil_files = np.array(af) run_case = 'loads' V_load = 12.0 Omega_load = 10.0 pitch_load = 0.0 azimuth_load = 180.0 n2 = 1 prob = Problem() prob.root = Group() prob.root.add('comp', CCBlade(run_case, n, n2), promotes=['*']) prob.root.add('r', IndepVarComp('r', np.zeros(len(r))), promotes=['*']) prob.root.add('chord', IndepVarComp('chord', np.zeros(len(chord))), promotes=['*']) prob.root.add('theta', IndepVarComp('theta', np.zeros(len(theta))), promotes=['*']) prob.root.add('Rhub', IndepVarComp('Rhub', 0.0), promotes=['*']) prob.root.add('Rtip', IndepVarComp('Rtip', 0.0), promotes=['*']) prob.root.add('hubHt', IndepVarComp('hubHt', 0.0), promotes=['*']) prob.root.add('precone', IndepVarComp('precone', 0.0), promotes=['*']) prob.root.add('tilt', IndepVarComp('tilt', 0.0), promotes=['*']) prob.root.add('yaw', IndepVarComp('yaw', 0.0), promotes=['*']) prob.root.add('B', IndepVarComp('B', 0), promotes=['*']) prob.root.add('rho', IndepVarComp('rho', 0.0), promotes=['*']) prob.root.add('mu', IndepVarComp('mu', 0.0), promotes=['*']) prob.root.add('shearExp', IndepVarComp('shearExp', 0.0, pass_by_obj=True), promotes=['*']) prob.root.add('precurve', IndepVarComp('precurve', precurve), promotes=['*']) prob.root.add('nSector', IndepVarComp('nSector', nSector), promotes=['*']) prob.root.add('airfoil_files', IndepVarComp('airfoil_files', airfoil_files), promotes=['*']) prob.root.add('V_load', IndepVarComp('V_load', 0.0), promotes=['*']) prob.root.add('Omega_load', IndepVarComp('Omega_load', 0.0), promotes=['*']) prob.root.add('pitch_load', IndepVarComp('pitch_load', 0.0), promotes=['*']) prob.root.add('azimuth_load', IndepVarComp('azimuth_load', 0.0), promotes=['*']) prob.setup(check=False) prob['r'] = r prob['chord'] = chord prob['theta'] = theta prob['Rhub'] = Rhub prob['Rtip'] = Rtip prob['hubHt'] = hubHt prob['precone'] = precone prob['tilt'] = tilt prob['yaw'] = yaw prob['B'] = B prob['rho'] = rho prob['mu'] = mu prob['shearExp'] = shearExp prob['nSector'] = nSector prob['airfoil_files'] = airfoil_files prob['V_load'] = V_load prob['Omega_load'] = Omega_load prob['pitch_load'] = pitch_load prob['azimuth_load'] = azimuth_load prob['precurve'] = precurve check_gradient_unit_test(self, prob, tol=1e-3, display=True)
def test_pyxdsm_pdf(self): """ Makes an XDSM of the Sphere test case. It also adds a design variable, constraint and objective. """ class Rosenbrock(ExplicitComponent): def __init__(self, problem): super(Rosenbrock, self).__init__() self.problem = problem self.counter = 0 def setup(self): self.add_input('x', np.array([1.5, 1.5])) self.add_output('f', 0.0) self.declare_partials('f', 'x', method='fd', form='central', step=1e-4) def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): x = inputs['x'] outputs['f'] = sum(x**2) x0 = np.array([1.2, 1.5]) filename = 'xdsm2' prob = Problem() indeps = prob.model.add_subsystem('indeps', IndepVarComp(problem=prob), promotes=['*']) indeps.add_output('x', list(x0)) prob.model.add_subsystem('sphere', Rosenbrock(problem=prob), promotes=['*']) prob.model.add_subsystem('con', ExecComp('c=sum(x)', x=np.ones(2)), promotes=['*']) prob.driver = ScipyOptimizeDriver() prob.model.add_design_var('x') prob.model.add_objective('f') prob.model.add_constraint('c', lower=1.0) prob.setup(check=False) prob.final_setup() # requesting 'pdf', but if 'pdflatex' is not found we will only get 'tex' pdflatex = find_executable('pdflatex') # Write output write_xdsm(prob, filename=filename, out_format='pdf', show_browser=SHOW, quiet=QUIET) # Check if file was created self.assertTrue(os.path.isfile('.'.join([filename, 'tex']))) # Check if PDF was created (only if pdflatex is installed) self.assertTrue(not pdflatex or os.path.isfile('.'.join([filename, 'pdf'])))
def test_guess_nonlinear_feature(self): from openmdao.api import Problem, Group, ImplicitComponent, IndepVarComp, NewtonSolver, ScipyKrylov class ImpWithInitial(ImplicitComponent): def setup(self): self.add_input('a', val=1.) self.add_input('b', val=1.) self.add_input('c', val=1.) self.add_output('x', val=0.) self.declare_partials(of='*', wrt='*') def apply_nonlinear(self, inputs, outputs, residuals): a = inputs['a'] b = inputs['b'] c = inputs['c'] x = outputs['x'] residuals['x'] = a * x**2 + b * x + c def solve_nonlinear(self, inputs, outputs): a = inputs['a'] b = inputs['b'] c = inputs['c'] outputs['x'] = (-b + (b**2 - 4 * a * c)**0.5) / 2 / a def linearize(self, inputs, outputs, partials): a = inputs['a'] b = inputs['b'] c = inputs['c'] x = outputs['x'] partials['x', 'a'] = x**2 partials['x', 'b'] = x partials['x', 'c'] = 1.0 partials['x', 'x'] = 2 * a * x + b self.inv_jac = 1.0 / (2 * a * x + b) def solve_nonlinear(self, inputs, outputs): """ Do nothing. """ pass def guess_nonlinear(self, inputs, outputs, resids): # Solution at 1 and 3. Default value takes us to -1 solution. Here # we set it to a value that will tke us to the 3 solution. outputs['x'] = 5.0 prob = Problem() model = prob.model = Group() model.add_subsystem('pa', IndepVarComp('a', 1.0)) model.add_subsystem('pb', IndepVarComp('b', 1.0)) model.add_subsystem('pc', IndepVarComp('c', 1.0)) model.add_subsystem('comp2', ImpWithInitial()) model.connect('pa.a', 'comp2.a') model.connect('pb.b', 'comp2.b') model.connect('pc.c', 'comp2.c') model.nonlinear_solver = NewtonSolver() model.nonlinear_solver.options['solve_subsystems'] = True model.nonlinear_solver.options['max_sub_solves'] = 1 model.linear_solver = ScipyKrylov() prob.setup(check=False) prob['pa.a'] = 1. prob['pb.b'] = -4. prob['pc.c'] = 3. prob.run_model() assert_rel_error(self, prob['comp2.x'], 3.)
# # Build the model # model = Group() # ivc = IndepVarComp() # ivc.add_output('mean_xi', 8*np.ones(3)) # model.add_subsystem('des_vars', ivc) # model.add_subsystem('paraboloid', Paraboloid()) # model.connect('des_vars.mean_xi', 'paraboloid.mean_xi') # prob = Problem(model) # prob.setup() # prob.run_model() # print(prob['paraboloid.mean_QoI']) # print(prob['paraboloid.mean_xi']) #------------ Run optimization using SNOPT prob = Problem() indeps = prob.model.add_subsystem('indeps', IndepVarComp(), promotes=['*']) indeps.add_output('mean_xi', 10 * np.ones(3)) prob.model.add_subsystem('paraboloid', Paraboloid(), promotes_inputs=['mean_xi']) # Set up the Optimization prob.driver = pyOptSparseDriver() prob.driver.options['optimizer'] = 'SNOPT' prob.driver.opt_settings['Major optimality tolerance'] = 3e-7 prob.driver.opt_settings['Major feasibility tolerance'] = 3e-7 prob.driver.opt_settings['Major iterations limit'] = 1000 prob.driver.opt_settings['Verify level'] = -1 prob.model.add_design_var('mean_xi', lower=-20 * np.ones(3), upper=20 * np.ones(3))
def setup(self): swarm = self.options['swarm'] mtx = self.options['mtx'] num_times = swarm['num_times'] num_cp = swarm['num_cp'] step_size = swarm['step_size'] shape = (3, num_times) times = np.linspace(0., step_size * (num_times - 1), num_times) comp = IndepVarComp() comp.add_output('times', val=times) self.add_subsystem('inputs_comp', comp, promotes=['*']) comp = SunDirectionComp( num_times=num_times, launch_date=swarm['launch_date'], ) self.add_subsystem('sun_direction_comp', comp, promotes=['*']) # group = ConstantOrbitGroup( # num_times=num_times, # num_cp=num_cp, # step_size=step_size, # cubesat=swarm.children[0], # ) # self.add_subsystem('constant_orbit_group', group, promotes=['*']) comp = CrossProductComp( shape_no_3=(num_times, ), out_index=0, in1_index=0, in2_index=0, out_name='normal_cross_vec', in1_name='velocity_unit_vec', in2_name='position_unit_vec', ) self.add_subsystem('normal_cross_vec_comp', comp, promotes=['*']) comp = CrossProductComp( shape_no_3=(num_times, ), out_index=0, in1_index=0, in2_index=0, out_name='observation_cross_vec', in1_name='position_unit_vec', in2_name='sun_unit_vec', ) self.add_subsystem('observation_cross_vec_comp', comp, promotes=['*']) group = DecomposeVectorGroup( num_times=num_times, vec_name='normal_cross_vec', norm_name='normal_cross_norm', unit_vec_name='normal_cross_unit_vec', ) self.add_subsystem('normal_cross_decomposition_group', group, promotes=['*']) group = DecomposeVectorGroup( num_times=num_times, vec_name='observation_cross_vec', norm_name='observation_cross_norm', unit_vec_name='observation_cross_unit_vec', ) self.add_subsystem('observation_cross_decomposition_group', group, promotes=['*']) comp = DotProductComp(vec_size=3, length=num_times, a_name='observation_cross_unit_vec', b_name='normal_cross_unit_vec', c_name='observation_dot', a_units=None, b_units=None, c_units=None) self.add_subsystem('observation_dot_comp', comp, promotes=['*']) comp = MaskVecComp( num_times=num_times, swarm=swarm, ) self.add_subsystem('mask_vec_comp', comp, promotes=['*']) # Separation separation_constraint_names = [ ('sunshade', 'optics'), ('optics', 'detector'), ] for name1, name2 in [ ('sunshade', 'optics'), ('sunshade', 'detector'), ('optics', 'detector'), ]: position_name = 'position_{}_{}_km'.format(name1, name2) distance_name = 'distance_{}_{}_km'.format(name1, name2) unit_vec_name = 'unit_vec_{}_{}_km'.format(name1, name2) comp = LinearCombinationComp( shape=(3, num_times), out_name=position_name, coeffs_dict={ '{}_cubesat_group_position_km'.format(name1): 1., '{}_cubesat_group_position_km'.format(name2): -1., }, ) self.add_subsystem('{}_comp'.format(position_name), comp, promotes=['*']) group = DecomposeVectorGroup( num_times=num_times, vec_name=position_name, norm_name=distance_name, unit_vec_name=unit_vec_name, ) self.add_subsystem('{}_{}_decomposition_group'.format( name1, name2), group, promotes=['*']) # Transverse displacement transverse_constraint_names = [ ('sunshade', 'detector'), ('optics', 'detector'), ] for name1, name2 in transverse_constraint_names: position_name = 'position_{}_{}_km'.format(name1, name2) projected_position_name = 'projected_position_{}_{}_km'.format( name1, name2) normal_position_name = 'normal_position_{}_{}_km'.format( name1, name2) normal_distance_name = 'normal_distance_{}_{}_km'.format( name1, name2) normal_unit_vec_name = 'normal_unit_vec_{}_{}_km'.format( name1, name2) group = ProjectionGroup( num_times=num_times, in1_name='sun_unit_vec', in2_name=position_name, out_name=projected_position_name, ) self.add_subsystem('{}_group'.format(projected_position_name), group, promotes=['*']) comp = LinearCombinationComp( shape=(3, num_times), out_name=normal_position_name, coeffs_dict={ position_name: 1., projected_position_name: -1., }, ) self.add_subsystem('{}_comp'.format(normal_position_name), comp, promotes=['*']) group = DecomposeVectorGroup( num_times=num_times, vec_name=normal_position_name, norm_name=normal_distance_name, unit_vec_name=normal_unit_vec_name, ) self.add_subsystem( '{}_decomposition_group'.format(normal_position_name), group, promotes=['*']) for constraint_name in [ 'normal_distance_{}_{}'.format(name1, name2) for name1, name2 in transverse_constraint_names ] + [ 'distance_{}_{}'.format(name1, name2) for name1, name2 in separation_constraint_names ]: comp = PowerCombinationComp( shape=(num_times, ), out_name='{}_mm'.format(constraint_name), coeff=1.e6, powers_dict={ '{}_km'.format(constraint_name): 1., }) self.add_subsystem('{}_mm_comp'.format(constraint_name), comp, promotes=['*']) comp = PowerCombinationComp( shape=(num_times, ), out_name='masked_{}_mm'.format(constraint_name), powers_dict={ 'mask_vec': 1., '{}_mm'.format(constraint_name): 1., }) self.add_subsystem('masked_{}_mm_comp'.format(constraint_name), comp, promotes=['*']) comp = KSComp( in_name='masked_{}_mm'.format(constraint_name), out_name='ks_masked_{}_mm'.format(constraint_name), shape=(1, ), constraint_size=num_times, rho=100., ) self.add_subsystem('ks_masked_{}_mm_comp'.format(constraint_name), comp, promotes=['*']) comp = PowerCombinationComp( shape=(num_times, ), out_name='masked_{}_mm_sq'.format(constraint_name), powers_dict={ 'masked_{}_mm'.format(constraint_name): 2., }) self.add_subsystem('masked_{}_mm_sq_comp'.format(constraint_name), comp, promotes=['*']) comp = ScalarContractionComp( shape=(num_times, ), out_name='masked_{}_mm_sq_sum'.format(constraint_name), in_name='masked_{}_mm_sq'.format(constraint_name), ) self.add_subsystem( 'masked_{}_mm_sq_sum_comp'.format(constraint_name), comp, promotes=['*'])
x = params['x'] y = params['y'] J = {} J['f_xy', 'x'] = 2.0 * x - 6.0 + y J['f_xy', 'y'] = 2.0 * y + 8.0 + x return J if __name__ == "__main__": top = Problem() root = top.root = Group() root.add('p1', IndepVarComp('x', 3.0)) root.add('p2', IndepVarComp('y', -4.0)) root.add('p', Paraboloid()) # Constraint Equation root.add('con', ExecComp('c = x-y')) root.connect('p1.x', 'p.x') root.connect('p2.y', 'p.y') root.connect('p.x', 'con.x') root.connect('p.y', 'con.y') top.driver = ScipyOptimizer() top.driver.options['optimizer'] = 'SLSQP' top.driver.add_desvar('p1.x', lower=-50, upper=50)