def test_sellar_idf(self): prob = Problem(SellarIDF()) prob.driver = ScipyOptimizeDriver(optimizer='SLSQP', disp=False) prob.setup() # check derivatives prob['dv.y1'] = 100 prob['equal.rhs:y1'] = 1 prob.run_model() cpd = prob.check_partials(out_stream=None) for (of, wrt) in cpd['equal']: assert_almost_equal(cpd['equal'][of, wrt]['abs error'], 0.0, decimal=5) assert_check_partials(cpd, atol=1e-5, rtol=1e-5) # check results prob.run_driver() assert_rel_error(self, prob['dv.x'], 0., 1e-5) assert_rel_error(self, prob['dv.z'], [1.977639, 0.], 1e-5) assert_rel_error(self, prob['obj_cmp.obj'], 3.18339395045, 1e-5) assert_almost_equal(prob['dv.y1'], 3.16) assert_almost_equal(prob['d1.y1'], 3.16) assert_almost_equal(prob['dv.y2'], 3.7552778) assert_almost_equal(prob['d2.y2'], 3.7552778) assert_almost_equal(prob['equal.y1'], 0.0) assert_almost_equal(prob['equal.y2'], 0.0)
def test_rhs_val(self): prob = Problem() model = prob.model # find where x^2 == 4 model.add_subsystem('indep', IndepVarComp('x', val=1.)) model.add_subsystem('f', ExecComp('y=x**2', x=1.)) model.add_subsystem('equal', EQConstraintComp('y', rhs_val=4.)) model.connect('indep.x', 'f.x') model.connect('f.y', 'equal.lhs:y') model.add_design_var('indep.x', lower=0., upper=10.) model.add_constraint('equal.y', equals=0.) model.add_objective('f.y') prob.setup(mode='fwd') prob.driver = ScipyOptimizeDriver(disp=False) prob.run_driver() assert_rel_error(self, prob['equal.y'], 0., 1e-6) assert_rel_error(self, prob['indep.x'], 2., 1e-6) assert_rel_error(self, prob['f.y'], 4., 1e-6) cpd = prob.check_partials(out_stream=None) for (of, wrt) in cpd['equal']: assert_almost_equal(cpd['equal'][of, wrt]['abs error'], 0.0, decimal=5) assert_check_partials(cpd, atol=1e-5, rtol=1e-5)
def test_rk_with_time_invariant(self): np.random.seed(1) indeps = IndepVarComp() rktest = RKTest(NTIME) indeps.add_output('yi', np.random.random((2, 3))) indeps.add_output('yv', np.random.random((2, NTIME))) indeps.add_output('x0', np.random.random((2,))) prob = Problem() prob.model.add_subsystem('indeps', indeps, promotes=['*']) prob.model.add_subsystem('rktest', rktest, promotes=['*']) prob.setup() prob.run_model() # check partials partials = prob.check_partials(out_stream=None) assert_check_partials(partials, atol=6e-5, rtol=6e-5) # check totals inputs = ['yi', 'yv', 'x0'] outputs = ['x'] J = prob.check_totals(of=outputs, wrt=inputs, out_stream=None) for outp in outputs: for inp in inputs: Jn = J[outp, inp]['J_fd'] Jf = J[outp, inp]['J_fwd'] diff = abs(Jf - Jn) assert_rel_error(self, diff.max(), 0.0, 6e-5)
def test_complex_step(self): prob = Problem() model = prob.model # find where 2*x == x^2 model.add_subsystem('indep', IndepVarComp('x', val=1.)) model.add_subsystem('multx', IndepVarComp('m', val=2.)) model.add_subsystem('f', ExecComp('y=x**2', x=1.)) model.add_subsystem('equal', EQConstraintComp('y', use_mult=True)) model.connect('indep.x', 'f.x') model.connect('indep.x', 'equal.lhs:y') model.connect('multx.m', 'equal.mult:y') model.connect('f.y', 'equal.rhs:y') model.add_design_var('indep.x', lower=0., upper=10.) model.add_constraint('equal.y', equals=0.) model.add_objective('f.y') prob.setup(mode='fwd', force_alloc_complex=True) prob.driver = ScipyOptimizeDriver(disp=False) prob.run_driver() with warnings.catch_warnings(): warnings.filterwarnings(action="error", category=np.ComplexWarning) cpd = prob.check_partials(out_stream=None, method='cs') assert_check_partials(cpd, atol=1e-10, rtol=1e-10)
def test_vectorized_with_default_mult(self): prob = Problem() model = prob.model n = 100 # find where 2*x == x^2, vectorized model.add_subsystem('indep', IndepVarComp('x', val=np.ones(n))) model.add_subsystem('f', ExecComp('y=x**2', x=np.ones(n), y=np.ones(n))) model.add_subsystem('equal', EQConstraintComp('y', val=np.ones(n), use_mult=True, mult_val=2., add_constraint=True)) model.add_subsystem('obj_cmp', ExecComp('obj=sum(y)', y=np.zeros(n))) model.connect('indep.x', 'f.x') model.connect('indep.x', 'equal.lhs:y') model.connect('f.y', 'equal.rhs:y') model.connect('f.y', 'obj_cmp.y') model.add_design_var('indep.x', lower=np.zeros(n), upper=np.ones(n)*10.) model.add_objective('obj_cmp.obj') prob.setup(mode='fwd') prob.driver = ScipyOptimizeDriver(disp=False) prob.run_driver() assert_rel_error(self, prob['equal.y'], np.zeros(n), 1e-6) assert_rel_error(self, prob['indep.x'], np.ones(n)*2., 1e-6) assert_rel_error(self, prob['f.y'], np.ones(n)*4., 1e-6) cpd = prob.check_partials(out_stream=None) for (of, wrt) in cpd['equal']: assert_almost_equal(cpd['equal'][of, wrt]['abs error'], 0.0, decimal=5) assert_check_partials(cpd, atol=1e-5, rtol=1e-5)
def test_assert_check_partials_no_exception_expected(self): import numpy as np from openmdao.api import Problem, ExplicitComponent from openmdao.utils.assert_utils import assert_check_partials class MyComp(ExplicitComponent): def setup(self): self.add_input('x1', 3.0) self.add_input('x2', 5.0) self.add_output('y', 5.5) self.declare_partials(of='*', wrt='*') def compute(self, inputs, outputs): outputs['y'] = 3.0 * inputs['x1'] + 4.0 * inputs['x2'] def compute_partials(self, inputs, partials): """Correct derivative.""" J = partials J['y', 'x1'] = np.array([3.0]) J['y', 'x2'] = np.array([4.0]) prob = Problem() prob.model = MyComp() prob.set_solver_print(level=0) prob.setup(check=False) prob.run_model() data = prob.check_partials(out_stream=None) atol = 1.e-6 rtol = 1.e-6 assert_check_partials(data, atol, rtol)
def test_assert_check_partials_exception_expected(self): class MyComp(ExplicitComponent): def setup(self): self.add_input('x1', 3.0) self.add_input('x2', 5.0) self.add_output('y', 5.5) self.declare_partials(of='*', wrt='*') def compute(self, inputs, outputs): outputs['y'] = 3.0 * inputs['x1'] + 4.0 * inputs['x2'] def compute_partials(self, inputs, partials): """Intentionally incorrect derivative.""" J = partials J['y', 'x1'] = np.array([4.0]) J['y', 'x2'] = np.array([40]) prob = Problem() prob.model = MyComp() prob.set_solver_print(level=0) prob.setup(check=False) prob.run_model() data = prob.check_partials(out_stream=None) atol = 1.e-6 rtol = 1.e-6 try: assert_check_partials(data, atol, rtol) except ValueError as err: err_string = str(err) self.assertEqual(err_string.count('Assert Check Partials failed for the following Components'), 1) self.assertEqual(err_string.count('1e-06'), 2) self.assertEqual(err_string.count('Component:'), 1) self.assertEqual(err_string.count('< output > wrt < variable >'), 1) self.assertEqual(err_string.count('norm'), 2) self.assertEqual(err_string.count('y wrt x1'), 4) self.assertEqual(err_string.count('y wrt x2'), 4) self.assertEqual(err_string.count('abs'), 6) self.assertEqual(err_string.count('rel'), 6) self.assertEqual(err_string.count('fwd-fd'), 4) self.assertEqual(err_string.count('rev-fd'), 4) else: self.fail('Exception expected.')
def test_vectorized_no_normalization(self): prob = Problem() model = prob.model n = 100 # find intersection of two non-parallel lines, vectorized model.add_subsystem('indep', IndepVarComp('x', val=-2.0*np.ones(n))) model.add_subsystem('f', ExecComp('y=3*x-3', x=np.ones(n), y=np.ones(n))) model.add_subsystem('g', ExecComp('y=2.3*x+4', x=np.ones(n), y=np.ones(n))) model.add_subsystem('equal', EQConstraintComp('y', val=np.ones(n), add_constraint=True, normalize=False)) model.add_subsystem('obj_cmp', ExecComp('obj=sum(y)', y=np.zeros(n))) model.connect('indep.x', 'f.x') model.connect('indep.x', 'g.x') model.connect('f.y', 'equal.lhs:y') model.connect('g.y', 'equal.rhs:y') model.connect('f.y', 'obj_cmp.y') model.add_design_var('indep.x', lower=np.zeros(n), upper=20.*np.ones(n)) model.add_objective('obj_cmp.obj') prob.setup(mode='fwd') prob.driver = ScipyOptimizeDriver(disp=False) # verify that the output is not being normalized prob.run_model() lhs = prob['f.y'] rhs = prob['g.y'] diff = lhs - rhs assert_rel_error(self, prob['equal.y'], diff) prob.run_driver() assert_almost_equal(prob['equal.y'], np.zeros(n)) assert_almost_equal(prob['indep.x'], np.ones(n)*10.) assert_almost_equal(prob['f.y'], np.ones(n)*27.) assert_almost_equal(prob['g.y'], np.ones(n)*27.) cpd = prob.check_partials(out_stream=None) for (of, wrt) in cpd['equal']: assert_almost_equal(cpd['equal'][of, wrt]['abs error'], 0.0, decimal=5) assert_check_partials(cpd, atol=1e-5, rtol=1e-5)
def test_create_on_init_add_constraint_no_normalization(self): prob = Problem() model = prob.model # find intersection of two non-parallel lines model.add_subsystem('indep', IndepVarComp('x', val=-2.0)) model.add_subsystem('f', ExecComp('y=3*x-3', x=0.)) model.add_subsystem('g', ExecComp('y=2.3*x+4', x=0.)) model.add_subsystem('equal', EQConstraintComp('y', add_constraint=True, normalize=False, ref0=0, ref=100.0)) model.connect('indep.x', 'f.x') model.connect('indep.x', 'g.x') model.connect('f.y', 'equal.lhs:y') model.connect('g.y', 'equal.rhs:y') model.add_design_var('indep.x', lower=0., upper=20.) model.add_objective('f.y') prob.setup(mode='fwd') # verify that the constraint has been added as requested self.assertTrue('equal.y' in model.get_constraints()) # verify that the output is not being normalized prob.run_model() lhs = prob['f.y'] rhs = prob['g.y'] diff = lhs - rhs assert_rel_error(self, prob['equal.y'], diff) prob.driver = ScipyOptimizeDriver(disp=False) prob.run_driver() assert_almost_equal(prob['equal.y'], 0.) assert_almost_equal(prob['indep.x'], 10.) assert_almost_equal(prob['f.y'], 27.) assert_almost_equal(prob['g.y'], 27.) cpd = prob.check_partials(out_stream=None) for (of, wrt) in cpd['equal']: assert_almost_equal(cpd['equal'][of, wrt]['abs error'], 0.0, decimal=5) assert_check_partials(cpd, atol=1e-5, rtol=1e-5)
def test_create_on_init(self): prob = Problem() model = prob.model # find intersection of two non-parallel lines model.add_subsystem('indep', IndepVarComp('x', val=0.)) model.add_subsystem('f', ExecComp('y=3*x-3', x=0.)) model.add_subsystem('g', ExecComp('y=2.3*x+4', x=0.)) model.add_subsystem('equal', EQConstraintComp('y', val=11.)) model.connect('indep.x', 'f.x') model.connect('indep.x', 'g.x') model.connect('f.y', 'equal.lhs:y') model.connect('g.y', 'equal.rhs:y') model.add_design_var('indep.x', lower=0., upper=20.) model.add_objective('f.y') prob.setup(mode='fwd') # verify that the output variable has been initialized self.assertEqual(prob['equal.y'], 11.) # verify that the constraint has not been added self.assertFalse('equal.y' in model.get_constraints()) # manually add the constraint model.add_constraint('equal.y', equals=0.) prob.setup(mode='fwd') prob.driver = ScipyOptimizeDriver(disp=False) prob.run_driver() assert_almost_equal(prob['equal.y'], 0.) assert_almost_equal(prob['indep.x'], 10.) assert_almost_equal(prob['f.y'], 27.) assert_almost_equal(prob['g.y'], 27.) cpd = prob.check_partials(out_stream=None) for (of, wrt) in cpd['equal']: assert_almost_equal(cpd['equal'][of, wrt]['abs error'], 0.0, decimal=5) assert_check_partials(cpd, atol=1e-5, rtol=1e-5)
def test_taper_symmetry(self): symmetry = True mesh = get_mesh(symmetry) prob = Problem() group = prob.model val = np.random.random(1) comp = Taper(val=val, mesh=mesh, symmetry=symmetry) group.add_subsystem('comp', comp) prob.setup() prob.run_model() check = prob.check_partials(compact_print=True, abs_err_tol=1e-5, rel_err_tol=1e-5) assert_check_partials(check, atol=1e-6, rtol=1e-6)
def test_assembled_jac(self): surfaces = get_default_surfaces() comp = EvalVelMtx(surfaces=surfaces, num_eval_points=2, eval_name='test_name') prob = Problem() prob.model.add_subsystem('comp', comp) from openmdao.api import DirectSolver prob.model.linear_solver = DirectSolver(assemble_jac=True) prob.model.options['assembled_jac_type'] = 'csc' prob.setup(force_alloc_complex=True) prob.run_model() 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_scalex(self): symmetry = False mesh = get_mesh(symmetry) prob = Problem() group = prob.model val = np.random.random(NY) comp = ScaleX(val=val, mesh_shape=mesh.shape) group.add_subsystem('comp', comp) prob.setup() prob['comp.in_mesh'] = mesh prob.run_model() check = prob.check_partials(compact_print=True, abs_err_tol=1e-5, rel_err_tol=1e-5) assert_check_partials(check, atol=1e-6, rtol=1e-6)
def test_assert_check_partials_exception_expected(self): class MyComp(ExplicitComponent): def setup(self): self.add_input('x1', 3.0) self.add_input('x2', 5.0) self.add_output('y', 5.5) self.declare_partials(of='*', wrt='*') def compute(self, inputs, outputs): """ Doesn't do much. """ outputs['y'] = 3.0 * inputs['x1'] + 4.0 * inputs['x2'] def compute_partials(self, inputs, partials): """Intentionally incorrect derivative.""" J = partials J['y', 'x1'] = np.array([4.0]) J['y', 'x2'] = np.array([40]) prob = Problem() prob.model = MyComp() prob.set_solver_print(level=0) prob.setup(check=False) prob.run_model() data = prob.check_partials(suppress_output=True) atol = 1.e-6 rtol = 1.e-6 try: assert_check_partials(data, atol, rtol) except AssertionError as err: expected_str = "error in partial of y wrt x1 in" self.assertTrue(expected_str in str(err), msg="\n\nActual err msg:\n{} \n\ndoes not contain expected string:\n\n{}".format(str(err), expected_str)) else: self.fail('Exception expected.')
def run_test(test_obj, comp, complex_flag=False, compact_print=True, method='fd', step=1e-6, atol=1e-5, rtol=1e-5, view=False): prob = Problem() prob.model.add_subsystem('comp', comp) prob.setup(force_alloc_complex=complex_flag) prob.run_model() if method=='cs': step = 1e-40 check = prob.check_partials(compact_print=compact_print, method=method, step=step) if view: # Loop through this `check` dictionary and visualize the approximated # and computed derivatives for key, subjac in iteritems(check[list(check.keys())[0]]): view_mat(subjac['J_fd'],subjac['J_fwd'],key) assert_check_partials(check, atol=atol, rtol=rtol) return prob
def test_scalex(self): symmetry = False mesh = get_mesh(symmetry) prob = om.Problem() group = prob.model val = np.random.random(NY) comp = ScaleX(val=val, mesh_shape=mesh.shape) group.add_subsystem('comp', comp) prob.setup() prob['comp.in_mesh'] = mesh prob.run_model() check = prob.check_partials(compact_print=True, abs_err_tol=1e-5, rel_err_tol=1e-5) assert_check_partials(check, atol=1e-6, rtol=1e-6)
def test_average_multiple_matrix_along1(): import omtools.examples.valid.ex_average_multiple_matrix_along1 as example n = 3 m = 6 M1 = np.arange(n * m).reshape((n, m)) M2 = np.arange(n * m, 2 * n * m).reshape((n, m)) desired_multiple_matrix_average_axis_1 = np.average((M1 + M2) / 2., axis=1) np.testing.assert_almost_equal( example.prob['multiple_matrix_average_along_1'], desired_multiple_matrix_average_axis_1) partials_error_multiple_matrix_axis_1 = example.prob.check_partials( includes=['comp_multiple_matrix_average_along_1'], out_stream=None, compact_print=True) assert_check_partials(partials_error_multiple_matrix_axis_1, atol=1.e-6, rtol=1.e-6)
def test_scalar_with_guess_func(self): n = 1 model=om.Group(assembled_jac_type='dense') def guess_function(inputs, outputs, residuals): outputs['x'] = np.sqrt(inputs['rhs:x']) bal = om.BalanceComp('x', guess_func=guess_function) # test guess_func as kwarg tgt = om.IndepVarComp(name='y_tgt', val=4) exec_comp = om.ExecComp('y=x**2', x={'value': 1}, y={'value': 1}) model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt']) model.add_subsystem(name='exec', subsys=exec_comp) model.add_subsystem(name='balance', subsys=bal) model.connect('y_tgt', 'balance.rhs:x') model.connect('balance.x', 'exec.x') model.connect('exec.y', 'balance.lhs:x') model.linear_solver = om.DirectSolver(assemble_jac=True) model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False, maxiter=100, iprint=0) prob = om.Problem(model) prob.setup() prob['balance.x'] = np.random.rand(n) prob.run_model() assert_almost_equal(prob['balance.x'], 2.0, decimal=7) # should converge with no iteration due to the guess function self.assertEqual(model.nonlinear_solver._iter_count, 1) cpd = prob.check_partials(out_stream=None) assert_check_partials(cpd, atol=1e-5, rtol=1e-5)
def test_scalar(self): n = 1 prob = om.Problem(model=om.Group(assembled_jac_type='dense')) bal = om.BalanceComp() bal.add_balance('x') tgt = om.IndepVarComp(name='y_tgt', val=4) exec_comp = om.ExecComp('y=x**2', x={'value': 1}, y={'value': 1}) prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt']) prob.model.add_subsystem(name='exec', subsys=exec_comp) prob.model.add_subsystem(name='balance', subsys=bal) 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 = om.DirectSolver(assemble_jac=True) prob.model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False, maxiter=100, iprint=0) prob.setup() prob['balance.x'] = np.random.rand(n) prob.run_model() assert_almost_equal(prob['balance.x'], 2.0, decimal=7) cpd = prob.check_partials(out_stream=None) assert_check_partials(cpd, atol=1e-5, rtol=1e-5)
def test_complex_step(self): n = 1 prob = om.Problem(model=om.Group(assembled_jac_type='dense')) bal = om.BalanceComp() bal.add_balance('x') tgt = om.IndepVarComp(name='y_tgt', val=4) exec_comp = om.ExecComp('y=x**2', x={'value': 1}, y={'value': 1}) prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt']) prob.model.add_subsystem(name='exec', subsys=exec_comp) prob.model.add_subsystem(name='balance', subsys=bal) 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 = om.DirectSolver(assemble_jac=True) prob.model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False, maxiter=100, iprint=0) prob.setup(force_alloc_complex=True) prob['balance.x'] = np.random.rand(n) prob.run_model() with warnings.catch_warnings(): warnings.filterwarnings(action="error", category=np.ComplexWarning) cpd = prob.check_partials(out_stream=None, method='cs') assert_check_partials(cpd, atol=1e-10, rtol=1e-10)
def test_vectorized(self): prob = Problem() model = prob.model n = 100 # find intersection of two non-parallel lines, vectorized model.add_subsystem('indep', IndepVarComp('x', val=np.ones(n))) model.add_subsystem('f', ExecComp('y=3*x-3', x=np.ones(n), y=np.ones(n))) model.add_subsystem('g', ExecComp('y=2.3*x+4', x=np.ones(n), y=np.ones(n))) model.add_subsystem('equal', EQConstraintComp('y', val=np.ones(n), add_constraint=True)) model.add_subsystem('obj_cmp', ExecComp('obj=sum(y)', y=np.zeros(n))) model.connect('indep.x', 'f.x') model.connect('indep.x', 'g.x') model.connect('f.y', 'equal.lhs:y') model.connect('g.y', 'equal.rhs:y') model.connect('f.y', 'obj_cmp.y') model.add_design_var('indep.x', lower=np.zeros(n), upper=20.*np.ones(n)) model.add_objective('obj_cmp.obj') prob.setup(mode='fwd') prob.driver = ScipyOptimizeDriver(disp=False) prob.run_driver() assert_almost_equal(prob['equal.y'], np.zeros(n)) assert_almost_equal(prob['indep.x'], np.ones(n)*10.) assert_almost_equal(prob['f.y'], np.ones(n)*27.) assert_almost_equal(prob['g.y'], np.ones(n)*27.) cpd = prob.check_partials(out_stream=None) for (of, wrt) in cpd['equal']: assert_almost_equal(cpd['equal'][of, wrt]['abs error'], 0.0, decimal=5) assert_check_partials(cpd, atol=1e-5, rtol=1e-5)
def test_create_on_init_add_constraint(self): prob = Problem() model = prob.model # find intersection of two non-parallel lines model.add_subsystem('indep', IndepVarComp('x', val=0.)) model.add_subsystem('f', ExecComp('y=3*x-3', x=0.)) model.add_subsystem('g', ExecComp('y=2.3*x+4', x=0.)) model.add_subsystem('equal', EQConstraintComp('y', add_constraint=True)) model.connect('indep.x', 'f.x') model.connect('indep.x', 'g.x') model.connect('f.y', 'equal.lhs:y') model.connect('g.y', 'equal.rhs:y') model.add_design_var('indep.x', lower=0., upper=20.) model.add_objective('f.y') prob.setup(mode='fwd') # verify that the constraint has been added as requested self.assertTrue('equal.y' in model.get_constraints()) prob.driver = ScipyOptimizeDriver(disp=False) prob.run_driver() assert_almost_equal(prob['equal.y'], 0.) assert_almost_equal(prob['indep.x'], 10.) assert_almost_equal(prob['f.y'], 27.) assert_almost_equal(prob['g.y'], 27.) cpd = prob.check_partials(out_stream=None) for (of, wrt) in cpd['equal']: assert_almost_equal(cpd['equal'][of, wrt]['abs error'], 0.0, decimal=5) assert_check_partials(cpd, atol=1e-5, rtol=1e-5)
def test_quadratic_no_rate_units(self): num_nodes = self.num_nodes nn_tot = num_nodes x = np.linspace(0, nn_tot - 1, nn_tot) fprime = 4 * x**2 - 8 * x + 5 f = 4 * x**3 / 3 - 8 * x**2 / 2 + 5 * x prob = Problem( IntegratorTestGroup(num_nodes=self.num_nodes, integrator=self.integrator, diff_units='s')) prob.setup(check=True, force_alloc_complex=True) prob['iv.rate_to_integrate'] = fprime prob.run_model() assert_near_equal(prob.get_val('integral.q', units=None), f, tolerance=1e-14) assert_near_equal(prob.get_val('integral.q_final', units=None), f[-1], tolerance=1e-14) partials = prob.check_partials(method='cs', compact_print=True) assert_check_partials(partials, atol=1e-8, rtol=1e0)
def test_average_single_tensor(): import omtools.examples.valid.ex_average_single_tensor as example n = 3 m = 6 p = 7 q = 10 T1 = np.arange(n * m * p * q).reshape((n, m, p, q)) desired_tensor_average = np.average(T1) np.testing.assert_almost_equal(example.prob['single_tensor_average'], desired_tensor_average) partials_error_tensor_average = example.prob.check_partials( includes=['comp_single_tensor_average'], out_stream=None, compact_print=True) assert_check_partials(partials_error_tensor_average, atol=1.e-5, rtol=1.e-5)
def test_case1(self): # 4 cases to check against for i, data in enumerate(ref_data): self.prob['inlet.ram_recovery'] = data[h_map['eRamBase']] # input flowstation self.prob['flow_start.P'] = data[h_map['Fl_I.Pt']] self.prob['flow_start.T'] = data[h_map['Fl_I.Tt']] self.prob['inlet.MN'] = data[h_map['Fl_O.MN']] self.prob['flow_start.MN'] = data[h_map['Fl_I.MN']] self.prob['flow_start.W'] = data[h_map['Fl_I.W']] self.prob['inlet.Fl_I:stat:V'] = data[h_map['Fl_I.V']] self.prob.run_model() # check outputs pt, ht, Fram, ps, ts = data[h_map['Fl_O.Pt']], data[ h_map['Fl_O.ht']], data[h_map['Fram']], data[ h_map['Fl_O.Ps']], data[h_map['Fl_O.Ts']] pt_computed = self.prob['inlet.Fl_O:tot:P'] ht_computed = self.prob['inlet.Fl_O:tot:h'] Fram_computed = self.prob['inlet.F_ram'] ps_computed = self.prob['inlet.Fl_O:stat:P'] ts_computed = self.prob['inlet.Fl_O:stat:T'] tol = 1e-4 assert_near_equal(pt_computed, pt, tol) assert_near_equal(ht_computed, ht, tol) assert_near_equal(Fram_computed, Fram, tol) assert_near_equal(ps_computed, ps, tol) assert_near_equal(ts_computed, ts, tol) partial_data = self.prob.check_partials( out_stream=None, method='cs', includes=['inlet.*'], excludes=['*.base_thermo.*']) assert_check_partials(partial_data, atol=1e-8, rtol=1e-8)
def test_quadratic_three_phase_units_unequal_dt(self): n_int_per_seg = self.num_intervals nn_tot = (n_int_per_seg*2 + 1) x1 = np.linspace(0, nn_tot-1, nn_tot) x2 = np.linspace(nn_tot-1, 3*(nn_tot-1), nn_tot) x3 = np.linspace(3*(nn_tot-1), 6*(nn_tot-1), nn_tot) x = np.concatenate([x1, x2, x3]) fprime = 4 * x **2 - 8*x + 5 f = 4 * x ** 3 / 3 - 8 * x ** 2 / 2 + 5*x prob = Problem(MultiPhaseIntegratorTestGroup(segment_names=['climb','cruise','descent'], num_intervals=self.num_intervals, integrator=self.integrator, quantity_units='kg', diff_units='s')) prob.setup(check=True, force_alloc_complex=True) prob['iv.rate_to_integrate'] = fprime prob['iv.climb|dt'] = 1 prob['iv.cruise|dt'] = 2 prob['iv.descent|dt'] = 3 prob.run_model() assert_rel_error(self, prob.get_val('integral.q', units='kg'), f, tolerance=1e-14) assert_rel_error(self, prob.get_val('integral.q_final', units='kg'), f[-1], tolerance=1e-14) partials = prob.check_partials(method='cs',compact_print=True) assert_check_partials(partials, atol=1e-8, rtol=1e0)
def test_reshape_tensor2vector(): import omtools.examples.valid.ex_reshape_tensor2_vector as example i = 2 j = 3 k = 4 l = 5 shape = (i, j, k, l) tensor = np.arange(np.prod(shape)).reshape(shape) vector = np.arange(np.prod(shape)) # TENSOR TO VECTOR desired_output = vector np.testing.assert_almost_equal(example.prob['reshape_tensor2vector'], desired_output) partials_error = example.prob.check_partials( includes=['comp_reshape_tensor2vector'], out_stream=None, compact_print=True) assert_check_partials(partials_error, atol=1.e-6, rtol=1.e-6)
def test_comp(self): num_nodes = 3 prob = Problem() prob.model.add_subsystem( 'test', thermal.ThermalComponentWithMass(num_nodes=num_nodes), promotes=['*']) prob.setup(check=True, force_alloc_complex=True) # Set the values prob.set_val('q_in', np.array([10., 14., 4.]), units='kW') prob.set_val('q_out', np.array([9., 14., 12.]), units='kW') prob.set_val('mass', 7., units='kg') prob.run_model() assert_near_equal(prob.get_val('dTdt', units='K/s'), np.array([.1551109043, 0., -1.2408872344]), tolerance=1e-9) partials = prob.check_partials(method='cs', compact_print=True) assert_check_partials(partials)
def test_ccblade_geometry(self): n_span = 10 prob = om.Problem() comp = CCBladeGeometry(n_span=n_span) prob.model.add_subsystem("comp", comp, promotes=["*"]) prob.setup(force_alloc_complex=True) prob.set_val("Rtip", 80.0, units="m") prob.set_val("precurve_in", np.random.rand(n_span), units="m") prob.set_val("presweep_in", np.random.rand(n_span), units="m") prob.set_val("precone", 2.2, units="deg") prob.run_model() check = prob.check_partials(out_stream=None, compact_print=True, method="fd") assert_check_partials(check)
def test(self): nPoints = 20 z = np.linspace(0.1, 100.0, nPoints) prob = om.Problem() root = prob.model = om.Group() root.add_subsystem('p', env.LogWind(nPoints=nPoints)) prob.setup() prob['p.Uref'] = 10.0 prob['p.zref'] = 100.0 prob['p.z0'] = 0.1 #Fails when z0 = 0 prob.run_model() check = prob.check_partials(out_stream=None, compact_print=True, method='fd') assert_check_partials(check)
def test_nondefault_settings(self): prob = Problem( MotorTestGroup( vec_size=10, use_defaults=False, efficiency=0.95, weight_inc=1 / 3000, weight_base=2, cost_inc=1 / 500, cost_base=3, )) prob.setup(check=True, force_alloc_complex=True) prob.run_model() assert_rel_error(self, prob.get_val('motor.shaft_power_out', units='kW'), np.ones(10) * 90 * 0.95, tolerance=1e-15) assert_rel_error(self, prob.get_val('motor.elec_load', units='kW'), np.ones(10) * 90, tolerance=1e-15) assert_rel_error(self, prob.get_val('motor.heat_out', units='kW'), np.ones(10) * 90 * 0.05, tolerance=1e-15) assert_rel_error(self, prob.get_val('motor.component_sizing_margin'), np.ones(10) * 0.90, tolerance=1e-15) assert_rel_error(self, prob.get_val('motor.component_cost', units='USD'), 203, tolerance=1e-15) assert_rel_error(self, prob.get_val('motor.component_weight', units='kg'), 35.333333333333333333, tolerance=1e-10) partials = prob.check_partials(method='cs', compact_print=True) assert_check_partials(partials)
def test_derivs_with_sideslip(self): surfaces = get_default_surfaces() # Use Tail since it is not symmetric. comp = LiftDrag(surface=surfaces[1]) prob = Problem() prob.model.add_subsystem('comp', comp) prob.setup(force_alloc_complex=True) prob['comp.alpha'] = 3.0 prob['comp.beta'] = 15.0 prob['comp.sec_forces'] = 10.0 * np.random.random( prob['comp.sec_forces'].shape) prob.run_model() check = prob.check_partials(compact_print=True, method='cs', step=1e-40) assert_check_partials(check)
def test_vectorized(self): nn = 5 p = Problem() p.model = CFM56(num_nodes=nn) p.setup(force_alloc_complex=True) p.set_val('throttle', np.linspace(0.0001, 1., nn)) p.set_val('fltcond|h', np.linspace(0, 40e3, nn), units='ft') p.set_val('fltcond|M', np.linspace(0.1, 0.9, nn)) p.run_model() assert_near_equal(p.get_val('thrust', units='lbf'), np.array([1445.41349482, 3961.46624224, 5278.43191982, 5441.44404298, 6479.00525867]), tolerance=5e-3) assert_near_equal(p.get_val('fuel_flow', units='kg/s'), np.array([0.17032429, 0.25496437, 0.35745638, 0.40572545, 0.4924194]), tolerance=5e-3) assert_near_equal(p.get_val('T4', units='degK'), np.array([1005.38911171, 1207.57548728, 1381.94820904, 1508.07901676, 1665.37063872]), tolerance=5e-3) partials = p.check_partials(method='cs',compact_print=True) assert_check_partials(partials)
def test_vectorized_all_derivs(self): xcp = np.array([1.0, 2.0, 4.0, 6.0, 10.0, 12.0]) ycp = np.array([[5.0, 12.0, 14.0, 16.0, 21.0, 29.0], [7.0, 13.0, 9.0, 6.0, 12.0, 14.0]]) n = 12 x = np.linspace(1.0, 12.0, n) for method in SPLINE_METHODS: prob = om.Problem() # These methods have their own test. if method in ['akima', 'bsplines']: continue opts = {} comp = om.SplineComp(method=method, vec_size=2, x_cp_val=xcp, x_interp_val=x, interp_options=opts) comp.add_spline(y_cp_name='ycp', y_interp_name='y_val', y_cp_val=ycp) prob.model.add_subsystem('interp1', comp) prob.setup(force_alloc_complex=True) prob.run_model() if method.startswith('scipy'): derivs = prob.check_partials(out_stream=None) assert_check_partials(derivs, atol=1e-7, rtol=1e-7) else: derivs = prob.check_partials(out_stream=None, method='cs') assert_check_partials(derivs, atol=1e-12, rtol=1e-12)
def test_specified_shape_rhs_val(self): prob = om.Problem() model = prob.model shape = (3, 2, 4) rhs = np.zeros(shape) model.add_subsystem('indep', om.IndepVarComp('x', val=np.ones(shape))) model.add_subsystem( 'equal', om.EQConstraintComp('y', val=np.ones(shape), rhs_val=rhs)) model.connect('indep.x', 'equal.lhs:y') prob.setup() prob.run_model() assert_near_equal(prob['equal.y'], np.ones(shape) - rhs, 1e-6) cpd = prob.check_partials(out_stream=None) assert_check_partials(cpd, atol=1e-5, rtol=1e-5)
def check_derivs(self, mode, shape, use_jit): def func(a, b, c): x = np.sin(a) * b + 3. * c return x f = omf.wrap(func).defaults(shape=shape).declare_partials(of='*', wrt='*', method='jax') p = om.Problem() p.model.add_subsystem('comp', om.ExplicitFuncComp(f, use_jax=True, use_jit=use_jit)) p.setup(mode=mode) p['comp.a'] = 1.0 p['comp.b'] = 2.0 p['comp.c'] = 3.0 p.run_model() assert_check_partials(p.check_partials(includes=['comp'], method='fd', out_stream=None), atol=1e-5) J = p.compute_totals(of=['comp.x'], wrt=['comp.a', 'comp.b', 'comp.c']) I = np.eye(np.product(shape)) if shape else np.eye(1) assert_near_equal(J['comp.x', 'comp.a'], I * p['comp.b'].ravel() * np.cos(p['comp.a']).ravel(), tolerance=1e-7) assert_near_equal(J['comp.x', 'comp.b'], I * np.sin(p['comp.a']).ravel(), tolerance=1e-7) assert_near_equal(J['comp.x', 'comp.c'], I * 3., tolerance=1e-7)
def test_distributions(self): nspline = 10 prob = om.Problem() prob.model.add_subsystem("comp1", WeibullCDF(nspline=nspline), promotes_inputs=["*"]) prob.model.add_subsystem("comp2", WeibullWithMeanCDF(nspline=nspline), promotes_inputs=["*"]) prob.model.add_subsystem("comp3", RayleighCDF(nspline=nspline), promotes_inputs=["*"]) prob.setup(force_alloc_complex=True) # Add some arbitrary inputs prob.set_val("x", np.random.rand(nspline), units="m/s") prob.set_val("xbar", 1.5, units="m/s") prob.set_val("k", 1.5) prob.set_val("A", 1.2) prob.run_model() check = prob.check_partials(out_stream=None, compact_print=True, method="fd") assert_check_partials(check, atol=1e-5)
def test_bspline_interp_basic(self): prob = om.Problem() model = prob.model n_cp = 80 n_point = 160 t = np.linspace(0, 3.0*np.pi, n_cp) tt = np.linspace(0, 3.0*np.pi, n_point) x = np.sin(t) model.add_subsystem('px', om.IndepVarComp('x', val=x)) bspline_options = {'order': 4} comp = om.SplineComp(method='bsplines', x_interp_val=tt, num_cp=n_cp, interp_options=bspline_options) prob.model.add_subsystem('interp', comp) comp.add_spline(y_cp_name='h_cp', y_interp_name='h', y_cp_val=x, y_units='km') model.connect('px.x', 'interp.h_cp') prob.setup(force_alloc_complex=True) prob.run_model() xx = prob['interp.h'].flatten() tt = np.linspace(0, 3.0*np.pi, n_point) x_expected = np.sin(tt) delta = xx - x_expected # Here we test that we don't have crazy interpolation error. self.assertLess(max(delta), .15) # And that it gets middle points a little better. self.assertLess(max(delta[15:-15]), .06) derivs = prob.check_partials(out_stream=None, method='cs') assert_check_partials(derivs, atol=1e-14, rtol=1e-14)
def test_777ish_regression(self): nx = 3 ny = 4 p = om.Problem(PlanformMesh(num_x=nx, num_y=ny)) p.setup() p.set_val("S", 427.8, units="m**2") p.set_val("AR", 9.82) p.set_val("taper", 0.149) p.set_val("sweep", 31.6, units="deg") p.run_model() mesh = np.array([ [ [19.50929722, -32.40754542, 0.0], [12.04879827, -21.60503028, 0.0], [4.58829932, -10.80251514, 0.0], [-2.87219963, 0.0, 0.0], ], [ [20.36521271, -32.40754542, 0.0], [14.53420835, -21.60503028, 0.0], [8.70320399, -10.80251514, 0.0], [2.87219963, 0.0, 0.0], ], [ [21.2211282, -32.40754542, 0.0], [17.01961843, -21.60503028, 0.0], [12.81810866, -10.80251514, 0.0], [8.61659889, 0.0, 0.0], ], ]) assert_near_equal(p.get_val("mesh", units="m"), mesh, tolerance=1e-10) partials = p.check_partials(out_stream=None, compact_print=True, show_only_incorrect=True) assert_check_partials(partials, atol=2e-5)
def test_case1(self): # 6 cases to check against for i, data in enumerate(ref_data): self.prob['fc.alt'] = data[h_map['alt']] self.prob['fc.MN'] = data[h_map['MN']] self.prob['fc.dTs'] = data[h_map['dTs']] if self.prob['fc.MN'] < 1e-10: self.prob['fc.MN'] += 1e-6 self.prob.run_model() # check outputs Pt = data[h_map['Pt']] Pt_c = self.prob['fc.Fl_O:tot:P'] Ps = data[h_map['Ps']] Ps_c = self.prob['fc.Fl_O:stat:P'] Tt = data[h_map['Tt']] Tt_c = self.prob['fc.Fl_O:tot:T'] Ts = data[h_map['Ts']] Ts_c = self.prob['fc.Fl_O:stat:T'] tol = 1e-4 assert_near_equal(Pt_c, Pt, tol) assert_near_equal(Ps_c, Ps, tol) assert_near_equal(Tt_c, Tt, tol) assert_near_equal(Ps_c, Ps, tol) partial_data = self.prob.check_partials( out_stream=None, method='cs', includes=['fc.*'], excludes=['*.base_thermo.*', 'fc.ambient.readAtmTable']) assert_check_partials(partial_data, atol=1e-8, rtol=1e-8)
def test_complex_step_multipoint(self): E = 1. L = 1. b = 0.1 volume = 0.01 num_cp = 5 num_elements = 50 num_load_cases = 2 model = MultipointBeamGroup(E=E, L=L, b=b, volume=volume, num_elements=num_elements, num_cp=num_cp, num_load_cases=num_load_cases) prob = om.Problem(model=model) prob.driver = om.ScipyOptimizeDriver() prob.driver.options['optimizer'] = 'SLSQP' prob.driver.options['tol'] = 1e-9 prob.driver.options['disp'] = True prob.setup(force_alloc_complex=True) prob.run_model() derivs = prob.check_totals(method='cs', out_stream=None) assert_near_equal( derivs[('obj_sum.obj', 'interp.h_cp')]['rel error'][0], 0.0, 1e-8) assert_near_equal( derivs[('volume_comp.volume', 'interp.h_cp')]['rel error'][0], 0.0, 1e-8) derivs = prob.check_partials(method='cs', out_stream=None) assert_check_partials(derivs, rtol=1e-15)
def test_partials(self): self.p.setup(force_alloc_complex=True) v0 = 100.0 gam0 = np.radians(30.0) t_duration = 10.0 phase = self.p.model.phase0 self.p['phase0.t_initial'] = 0.0 self.p['phase0.t_duration'] = t_duration self.p['phase0.states:r'] = phase.interpolate(ys=[0, v0 * np.cos(gam0) * t_duration], nodes='state_disc') self.p['phase0.states:h'] = phase.interpolate(ys=[0, 0], nodes='state_input') self.p['phase0.states:v'] = phase.interpolate(ys=[v0, v0], nodes='state_input') self.p['phase0.states:gam'] = phase.interpolate(ys=[gam0, -gam0], nodes='state_input') self.p.run_model() cpd = self.p.check_partials(compact_print=True, method='cs') assert_check_partials(cpd)
def test_default_settings(self): prob = Problem(BatteryTestGroup(vec_size=10, use_defaults=True)) prob.setup(check=True, force_alloc_complex=True) prob.run_model() assert_rel_error(self, prob['battery.heat_out'], np.ones(10) * 100 * 0.0, tolerance=1e-15) assert_rel_error(self, prob['battery.component_sizing_margin'], np.ones(10) * 0.20, tolerance=1e-15) assert_rel_error(self, prob['battery.component_cost'], 5001, tolerance=1e-15) assert_rel_error(self, prob.get_val('battery.max_energy', units='W*h'), 300 * 100, tolerance=1e-15) partials = prob.check_partials(method='cs', compact_print=True) assert_check_partials(partials)
def test_scale_to_pg(self): surfaces = get_default_surfaces() comp = ScaleToPrandtlGlauert(surfaces=surfaces, rotational=True) prob = om.Problem() prob.model.add_subsystem('comp', comp) prob.setup(force_alloc_complex=True) prob['comp.Mach_number'] = np.random.random(prob['comp.Mach_number'].shape) prob['comp.coll_pts_w_frame'] = np.random.random(prob['comp.coll_pts_w_frame'].shape) prob['comp.bound_vecs_w_frame'] = np.random.random(prob['comp.bound_vecs_w_frame'].shape) prob['comp.rotational_velocities_w_frame'] = np.random.random(prob['comp.rotational_velocities_w_frame'].shape) prob['comp.wing_def_mesh_w_frame'] = np.random.random(prob['comp.wing_def_mesh_w_frame'].shape) prob['comp.tail_def_mesh_w_frame'] = np.random.random(prob['comp.tail_def_mesh_w_frame'].shape) prob['comp.tail_normals_w_frame'] = np.random.random(prob['comp.tail_normals_w_frame'].shape) prob['comp.wing_normals_w_frame'] = np.random.random(prob['comp.wing_normals_w_frame'].shape) prob.run_model() check = prob.check_partials(compact_print=True, method='cs', step=1e-40) assert_check_partials(check)
def test_taper(self): nx = 2 ny = 3 p = om.Problem(PlanformMesh(num_x=nx, num_y=ny)) p.setup() p.set_val("S", 1.3, units="m**2") p.set_val("AR", 4 / 1.3) # pick S and AR for half span and root chord of 1 p.set_val("taper", 0.3) p.set_val("sweep", 0.0, units="deg") p.run_model() mesh = np.zeros((nx, ny, 3)) mesh[:, :, 0] = np.array([[-0.075, -0.1625, -0.25], [0.225, 0.4875, 0.75]]) mesh[:, :, 1] = np.array([[-1, -0.5, 0], [-1, -0.5, 0]]) assert_near_equal(p.get_val("mesh", units="m"), mesh) partials = p.check_partials(out_stream=None, compact_print=True, show_only_incorrect=True) assert_check_partials(partials)
def test_renamed_vars(self): prob = Problem() model = prob.model # find intersection of two non-parallel lines, fx_y and gx_y equal = EQConstraintComp('y', lhs_name='fx_y', rhs_name='gx_y', add_constraint=True) model.add_subsystem('indep', IndepVarComp('x', val=0.)) model.add_subsystem('f', ExecComp('y=3*x-3', x=0.)) model.add_subsystem('g', ExecComp('y=2.3*x+4', x=0.)) model.add_subsystem('equal', equal) model.connect('indep.x', 'f.x') model.connect('indep.x', 'g.x') model.connect('f.y', 'equal.fx_y') model.connect('g.y', 'equal.gx_y') model.add_design_var('indep.x', lower=0., upper=20.) model.add_objective('f.y') prob.setup(mode='fwd') prob.driver = ScipyOptimizeDriver(disp=False) prob.run_driver() assert_almost_equal(prob['equal.y'], 0.) assert_almost_equal(prob['indep.x'], 10.) assert_almost_equal(prob['f.y'], 27.) assert_almost_equal(prob['g.y'], 27.) cpd = prob.check_partials(out_stream=None) for (of, wrt) in cpd['equal']: assert_almost_equal(cpd['equal'][of, wrt]['abs error'], 0.0, decimal=5) assert_check_partials(cpd, atol=1e-5, rtol=1e-5)
def test(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=np.array([1., 2.5])) 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(2): 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, internally_connect_fuelburn=False) 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', src_indices=[i]) prob.model.connect('fuel_mass', point_name + '.total_perf.L_equals_W.fuelburn') prob.model.connect('fuel_mass', point_name + '.total_perf.CG.fuelburn') for surface in surfaces: prob.model.connect('load_factor', point_name + '.coupled.load_factor', src_indices=[i]) 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_mass', point_name + '.coupled.' + name + '.element_mass') # Connect performance calculation variables prob.model.connect(name + '.nodes', com_name + 'nodes') prob.model.connect(name + '.cg_location', point_name + '.' + 'total_perf.' + name + '_cg_location') prob.model.connect(name + '.structural_mass', point_name + '.' + 'total_perf.' + name + '_structural_mass') # Connect wingbox properties to von Mises stress calcs prob.model.connect(name + '.Qz', com_name + 'Qz') prob.model.connect(name + '.J', com_name + 'J') prob.model.connect(name + '.A_enc', com_name + 'A_enc') prob.model.connect(name + '.htop', com_name + 'htop') prob.model.connect(name + '.hbottom', com_name + 'hbottom') prob.model.connect(name + '.hfront', com_name + 'hfront') prob.model.connect(name + '.hrear', com_name + 'hrear') prob.model.connect(name + '.spar_thickness', com_name + 'spar_thickness') prob.model.connect(name + '.t_over_c', com_name + 't_over_c') #======================================================================================= # Here we add the fuel volume constraint componenet to the model #======================================================================================= prob.model.add_subsystem('fuel_vol_delta', WingboxFuelVolDelta(surface=surface)) prob.model.connect('wing.struct_setup.fuel_vols', 'fuel_vol_delta.fuel_vols') prob.model.connect('AS_point_0.fuelburn', 'fuel_vol_delta.fuelburn') 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') prob.model.connect('wing.struct_setup.fuel_vols', 'AS_point_1.coupled.wing.struct_states.fuel_vols') prob.model.connect('fuel_mass', 'AS_point_1.coupled.wing.struct_states.fuel_mass') comp = ExecComp('fuel_diff = (fuel_mass - fuelburn) / fuelburn', units='kg') prob.model.add_subsystem('fuel_diff', comp, promotes_inputs=['fuel_mass'], promotes_outputs=['fuel_diff']) prob.model.connect('AS_point_0.fuelburn', 'fuel_diff.fuelburn') comp = ExecComp('fuel_diff_25 = (fuel_mass - fuelburn) / fuelburn') prob.model.add_subsystem('fuel_diff_25', comp, promotes_inputs=['fuel_mass'], promotes_outputs=['fuel_diff_25']) prob.model.connect('AS_point_1.fuelburn', 'fuel_diff_25.fuelburn') #======================================================================================= #======================================================================================= from openmdao.api import ScipyOptimizeDriver prob.driver = ScipyOptimizeDriver() prob.driver.options['tol'] = 1e-9 prob.driver.options['maxiter'] = 5 # 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.) prob.model.add_constraint('fuel_diff_25', 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 5 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_partials(self): partials = self.p.check_partials(method='fd', out_stream=None) assert_check_partials(partials)
def test_partials(self): np.set_printoptions(linewidth=1024) cpd = self.p.check_partials(compact_print=False, method='cs', out_stream=None) assert_check_partials(cpd, atol=1.0E-8, rtol=1.0E-8)
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 from openmdao.api import IndepVarComp, Problem, Group, NewtonSolver, ScipyIterativeSolver, LinearBlockGS, NonlinearBlockGS, DirectSolver, LinearBlockGS, PetscKSP, ScipyOptimizeDriver, ExplicitComponent# TODO, SqliteRecorder, CaseReader, profile from openmdao.devtools import iprofile from openmdao.api import view_model from openmdao.utils.assert_utils import assert_check_partials from pygeo import DVGeometry # 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, _ = 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, 'mx' : 2, 'my' : 3, 'geom_manipulator' : 'FFD', # Aerodynamic performance of the lifting surface at # an angle of attack of 0 (alpha=0). # These CL0 and CD0 values are added to the CL and CD # obtained from aerodynamic analysis of the surface to get # the total CL and CD. # These CL0 and CD0 values do not vary wrt alpha. 'CL0' : 0.0, # CL of the surface at alpha=0 'CD0' : 0.015, # CD of the surface at alpha=0 # Airfoil properties for viscous drag calculation 'k_lam' : 0.05, # percentage of chord with laminar # flow, used for viscous drag 't_over_c_cp' : np.array([0.15]), # thickness over chord ratio (NACA0015) 'c_max_t' : .303, # chordwise location of maximum (NACA0015) # thickness 'with_viscous' : True, # if true, compute viscous drag 'with_wave' : False, # if true, compute wave drag } surfaces = [surf_dict] 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: filename = write_FFD_file(surface, surface['mx'], surface['my']) DVGeo = DVGeometry(filename) geom_group = Geometry(surface=surface, DVGeo=DVGeo) # 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 pyOptSparseDriver prob.driver = pyOptSparseDriver() prob.driver.options['optimizer'] = "SNOPT" prob.driver.opt_settings = {'Major optimality tolerance': 1.0e-5, 'Major feasibility tolerance': 1.0e-5} # # 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.shape', lower=-3, upper=2) prob.model.add_constraint('aero_point_0.wing_perf.CL', equals=0.45) prob.model.add_design_var('aero_point_1.wing_geom.shape', lower=-3, upper=2) prob.model.add_constraint('aero_point_1.wing_perf.CL', equals=0.5) prob.model.add_objective('CD', scaler=1e4) # Set up the problem prob.setup() prob.run_model() # 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(self): # Create a dictionary to store options about the surface mesh_dict = {'num_y' : 7, 'wing_type' : 'uCRM_based', 'symmetry' : True, 'num_twist_cp' : 5} mesh, twist_cp = generate_mesh(mesh_dict) surf_dict = { # Wing definition 'name' : 'wing', # name of the surface # 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', 'symmetry' : True, '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' : False, 'distributed_fuel_weight' : True, # Constraints 'exact_failure_constraint' : True, # 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 } # 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.) indep_var_comp.add_output('fuel_mass', val=10000., units='kg') 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) if surf_dict['distributed_fuel_weight']: prob.model.connect('wing.fuel_mass', 'wing.struct_states.fuel_mass') prob.model.connect('wing.struct_setup.fuel_vols', 'wing.struct_states.fuel_vols') from openmdao.api import ScipyOptimizeDriver prob.driver = ScipyOptimizeDriver() prob.driver.options['tol'] = 1e-9 # Setup problem and add design variables, constraint, and objective prob.model.add_design_var('wing.spar_thickness_cp', lower=0.01, upper=0.5, ref=1e-1) prob.model.add_design_var('wing.skin_thickness_cp', lower=0.01, upper=0.5, ref=1e-1) prob.model.add_constraint('wing.failure', upper=0.) #prob.model.add_constraint('wing.thickness_intersects', upper=0.) # Add design variables, constraisnt, and objective on the problem prob.model.add_objective('wing.structural_mass', scaler=1e-5) # Set up the problem prob.setup(force_alloc_complex=False) prob.run_model() data = prob.check_partials(compact_print=True, out_stream=None, method='fd') assert_check_partials(data, atol=1e20, rtol=1e-6) prob.run_driver() assert_rel_error(self, prob['wing.structural_mass'], 16704.07393593, 1e-6)
def test_derivs_wetted(self): # This is a much richer test with the following attributes: # - 5x7 mesh so that each dimension of all variables is unique. # - Random values given as inputs. # - The mesh has been given a random z height at all points. # - S_ref_type option is "wetted" # Create a dictionary to store options about the mesh mesh_dict = {'num_y' : 7, 'num_x' : 5, 'wing_type' : 'CRM', 'symmetry' : True, 'num_twist_cp' : 5} # Generate the aerodynamic mesh based on the previous dictionary mesh, twist_cp = generate_mesh(mesh_dict) mesh[:, :, 2] = np.random.random(mesh[:, :, 2].shape) # Create a dictionary with info and options about the aerodynamic # lifting surface surface = { # 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', 'twist_cp' : twist_cp, 'mesh' : mesh, # Aerodynamic performance of the lifting surface at # an angle of attack of 0 (alpha=0). # These CL0 and CD0 values are added to the CL and CD # obtained from aerodynamic analysis of the surface to get # the total CL and CD. # These CL0 and CD0 values do not vary wrt alpha. 'CL0' : 0.0, # CL of the surface at alpha=0 'CD0' : 0.015, # CD of the surface at alpha=0 # Airfoil properties for viscous drag calculation 'k_lam' : 0.05, # percentage of chord with laminar # flow, used for viscous drag 't_over_c_cp' : np.array([0.15]), # thickness over chord ratio (NACA0015) 'c_max_t' : .303, # chordwise location of maximum (NACA0015) # thickness 'with_viscous' : True, # if true, compute viscous drag 'with_wave' : False, # if true, compute wave drag } #surfaces = get_default_surfaces() surfaces = [surface] prob = Problem() group = prob.model 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') prob.setup() prob['geom.def_mesh'] = np.random.random(prob['geom.def_mesh'].shape) prob.run_model() check = prob.check_partials(compact_print=True) assert_check_partials(check, atol=3e-5, rtol=1e-5)