def test_derivs(self): surface = get_default_surfaces()[0] surface['n_point_masses'] = 2 comp = ComputePointMassLoads(surface=surface) group = Group() indep_var_comp = IndepVarComp() ny = surface['mesh'].shape[1] nodesval = np.array([[0., 0., 0.], [0., 1., 0.], [0., 2., 0.], [0., 3., 0.]]) point_masses = np.array([[2., 1.]]) point_mass_locations = np.array([[2.1, 0.1, 0.2], [3.2, 1.2, 0.3]]) indep_var_comp.add_output('nodes', val=nodesval, units='m') indep_var_comp.add_output('point_masses', val=point_masses, units='kg') indep_var_comp.add_output('point_mass_locations', val=point_mass_locations, units='m') group.add_subsystem('indep_var_comp', indep_var_comp, promotes=['*']) group.add_subsystem('compute_point_mass_loads', comp, promotes=['*']) prob = run_test(self, group, complex_flag=True, step=1e-8, atol=1e-5, compact_print=True)
def test_simple_values(self): surface = get_default_surfaces()[0] surface['n_point_masses'] = 1 comp = ComputePointMassLoads(surface=surface) group = Group() indep_var_comp = IndepVarComp() ny = surface['mesh'].shape[1] nodesval = np.array([[0., 0., 0.], [0., 1., 0.], [0., 2., 0.], [0., 3., 0.]]) point_masses = np.array([[1/9.8]]) point_mass_locations = np.array([[.55012, 0.1, 0.]]) indep_var_comp.add_output('nodes', val=nodesval, units='m') indep_var_comp.add_output('point_masses', val=point_masses, units='kg') indep_var_comp.add_output('point_mass_locations', val=point_mass_locations, units='m') group.add_subsystem('indep_var_comp', indep_var_comp, promotes=['*']) group.add_subsystem('compute_point_mass_loads', comp, promotes=['*']) prob = run_test(self, group, complex_flag=True, step=1e-8, atol=1e-5, compact_print=True) truth_array = np.array([0, 0, -1., 0., 0.55012, 0.]) assert_rel_error(self, prob['comp.loads_from_point_masses'][0, :], truth_array, 1e-6)
def test_case1_vs_npss(self): root = Group() root.add('p', breakpoint_levitation.BreakPointDrag()) root.add('q', breakpoint_levitation.MagMass()) prob = Problem(root) prob.setup() prob['p.m_pod'] = 3000.0 prob['p.b_res'] = 1.48 prob['p.num_mag_hal'] = 4.0 prob['p.mag_thk'] = .15 prob['p.l_pod'] = 22.0 prob['p.gamma'] = 1.0 prob['p.w_mag'] = 3.0 prob['p.spacing'] = 0.0 prob['p.d_pod'] = 1.0 prob['p.w_strip'] = .005 prob['p.num_sheets'] = 1.0 prob['p.delta_c'] = .0005334 prob['p.strip_c'] = .0105 prob['p.rc'] = 1.713e-8 prob['p.MU0'] = 4.0*np.pi*(1.0e-7) prob['p.track_factor'] = .75 prob['p.vel_b'] = 23.0 prob['p.h_lev'] = .01 prob['p.g'] = 9.81 prob['q.m_pod'] = 3000.0 prob['q.mag_thk'] = .15 prob['q.rho_mag'] = 7500.0 prob['q.l_pod'] = 22.0 prob['q.gamma'] = 1.0 prob['q.cost_per_kg'] = 44.0 prob['q.w_mag'] = 3.0 prob['q.d_pod'] = 1.0 prob['q.track_factor'] = .75 prob.run() # Print Statement for debugging # print('track_ind is %12.12f' % prob['comp.Drag.track_ind']) # Test Values assert np.isclose(prob['q.mag_area'], 16.500000, rtol = .01) assert np.isclose(prob['q.m_mag'], 18562.500000, rtol = .01) assert np.isclose(prob['q.cost'], 816750.000000, rtol = .01) assert np.isclose(prob['q.total_pod_mass'], 21562.500000, rtol = .01) assert np.isclose(prob['p.lam'], 0.600000, rtol = .01) assert np.isclose(prob['p.track_ind'], 4.28571e-6, rtol = .01) assert np.isclose(prob['p.b0'], 1.055475, rtol = .01) assert np.isclose(prob['p.mag_area'], 16.500000, rtol = .01) assert np.isclose(prob['p.omegab'], 240.855437, rtol = .01) assert np.isclose(prob['p.w_track'], .75, rtol = .01) assert np.isclose(prob['p.fyu'], 520814.278077, rtol = .01) assert np.isclose(prob['p.fxu'], 2430517.899848, rtol = .01) assert np.isclose(prob['p.ld_ratio'], 0.214281, rtol = .01) assert np.isclose(prob['p.pod_weight'], 29430.000000, rtol = .01) assert np.isclose(prob['p.track_res'], 0.004817, rtol = .01)
def test_conflicting_connections(self): # verify we get an error if we have conflicting implicit and explicit connections root = Group() # promoting G1.x will create an implicit connection to G3.x # this is a conflict because G3.x (aka G3.C4.x) is already connected # to G3.C3.x G2 = root.add('G2', Group(), promotes=['x']) # BAD PROMOTE G2.add('C1', IndepVarComp('x', 5.), promotes=['x']) G1 = G2.add('G1', Group(), promotes=['x']) G1.add('C2', ExecComp('y=x*2.0'), promotes=['x']) G3 = root.add('G3', Group(), promotes=['x']) G3.add('C3', ExecComp('y=x*2.0')) G3.add('C4', ExecComp('y=x*2.0'), promotes=['x']) root.connect('G2.G1.C2.y', 'G3.C3.x') G3.connect('C3.y', 'x') prob = Problem(root) try: prob.setup(check=False) except Exception as error: msg = "Target 'G3.C4.x' is connected to multiple unknowns: ['G2.C1.x', 'G3.C3.y']" self.assertTrue(msg in str(error)) else: self.fail("Error expected")
def test_double_arraycomp(self): # Mainly testing a bug in the array return for multiple arrays group = Group() group.add('x_param1', IndepVarComp('x1', np.ones((2))), promotes=['*']) group.add('x_param2', IndepVarComp('x2', np.ones((2))), promotes=['*']) group.add('mycomp', DoubleArrayComp(), promotes=['*']) prob = Problem(impl=impl) prob.root = group prob.root.ln_solver = PetscKSP() prob.setup(check=False) prob.run() Jbase = group.mycomp.JJ J = prob.calc_gradient(['x1', 'x2'], ['y1', 'y2'], mode='fwd', return_format='array') diff = np.linalg.norm(J - Jbase) assert_rel_error(self, diff, 0.0, 1e-8) J = prob.calc_gradient(['x1', 'x2'], ['y1', 'y2'], mode='fd', return_format='array') diff = np.linalg.norm(J - Jbase) assert_rel_error(self, diff, 0.0, 1e-8) J = prob.calc_gradient(['x1', 'x2'], ['y1', 'y2'], mode='rev', return_format='array') diff = np.linalg.norm(J - Jbase) assert_rel_error(self, diff, 0.0, 1e-8)
def test_options(self): """Verify that the SciPy solver specific options are declared.""" group = Group() group.linear_solver = self.linear_solver_class() self.assertEqual(group.linear_solver.options['solver'], self.linear_solver_name)
def test_conflicting_promotions(self): # verify we get an error if we have conflicting promotions root = Group() # promoting G1.x will create an implicit connection to G3.x # this is a conflict because G3.x (aka G3.C4.x) is already connected # to G3.C3.x G2 = root.add('G2', Group()) G2.add('C1', IndepVarComp('x', 5.), promotes=['x']) G1 = G2.add('G1', Group(), promotes=['x']) G1.add('C2', ExecComp('y=x*2.0'), promotes=['x']) G3 = root.add('G3', Group(), promotes=['x']) G3.add('C3', ExecComp('y=x*2.0'), promotes=['y']) # promoting y G3.add('C4', ExecComp('y=x*2.0'), promotes=['x', 'y']) # promoting y again.. BAD prob = Problem(root) try: prob.setup(check=False) except Exception as error: msg = "'G3': promoted name 'y' matches multiple unknowns: ('G3.C3.y', 'G3.C4.y')" self.assertEqual(text_type(error), msg) else: self.fail("Error expected")
def test_guess_nonlinear_resids_read_only(self): class ImpWithInitial(ImplicitComponent): def setup(self): self.add_input('x', 3.0) self.add_output('y', 4.0) def guess_nonlinear(self, inputs, outputs, resids): # inputs is read_only, should not be allowed resids['y'] = 0. group = Group() group.add_subsystem('px', IndepVarComp('x', 77.0)) group.add_subsystem('comp1', ImpWithInitial()) group.add_subsystem('comp2', ImpWithInitial()) group.connect('px.x', 'comp1.x') group.connect('comp1.y', 'comp2.x') group.nonlinear_solver = NewtonSolver() group.nonlinear_solver.options['maxiter'] = 1 prob = Problem(model=group) prob.set_solver_print(level=0) prob.setup(check=False) with self.assertRaises(ValueError) as cm: prob.run_model() self.assertEqual(str(cm.exception), "Attempt to set value of 'y' in residual vector " "when it is read only.")
def test_deprecated_solver_names(self): class DummySolver(): pass model = Group() # check nl_solver setter & getter msg = "The 'nl_solver' attribute provides backwards compatibility " \ "with OpenMDAO 1.x ; use 'nonlinear_solver' instead." with assert_warning(DeprecationWarning, msg): model.nl_solver = DummySolver() with assert_warning(DeprecationWarning, msg): solver = model.nl_solver self.assertTrue(isinstance(solver, DummySolver)) # check ln_solver setter & getter msg = "The 'ln_solver' attribute provides backwards compatibility " \ "with OpenMDAO 1.x ; use 'linear_solver' instead." with assert_warning(DeprecationWarning, msg): model.ln_solver = DummySolver() with assert_warning(DeprecationWarning, msg): solver = model.ln_solver self.assertTrue(isinstance(solver, DummySolver))
def test_generate_numpydocstring(self): group = Group() group.add("x_param", IndepVarComp("x", 1.0), promotes=["*"]) group.add("mycomp", SimpleCompDerivMatVec(), promotes=["x", "y"]) prob = Problem() prob.root = group prob.root.ln_solver = ScipyGMRES() test_string = prob.root.ln_solver.generate_docstring() original_string = """ \"\"\" Options ------- options['atol'] : float(1e-12) Absolute convergence tolerance. options['err_on_maxiter'] : bool(False) If True, raise an AnalysisError if not converged at maxiter. options['iprint'] : int(0) Set to 0 to disable printing, set to 1 to print iteration totals to stdout, set to 2 to print the residual each iteration to stdout. options['maxiter'] : int(1000) Maximum number of iterations. options['mode'] : str('auto') Derivative calculation mode, set to 'fwd' for forward mode, 'rev' for reverse mode, or 'auto' to let OpenMDAO determine the best mode. options['restart'] : int(20) Number of iterations between restarts. Larger values increase iteration cost, but may be necessary for convergence \"\"\" """ for sorig, stest in zip(original_string.split("\n"), test_string.split("\n")): self.assertEqual(sorig, stest)
def test_guess_nonlinear_inputs_read_only_reset(self): class ImpWithInitial(ImplicitComponent): def setup(self): self.add_input('x', 3.0) self.add_output('y', 4.0) def guess_nonlinear(self, inputs, outputs, resids): raise AnalysisError("It's just a scratch.") group = Group() group.add_subsystem('px', IndepVarComp('x', 77.0)) group.add_subsystem('comp1', ImpWithInitial()) group.add_subsystem('comp2', ImpWithInitial()) group.connect('px.x', 'comp1.x') group.connect('comp1.y', 'comp2.x') group.nonlinear_solver = NewtonSolver() group.nonlinear_solver.options['maxiter'] = 1 prob = Problem(model=group) prob.set_solver_print(level=0) prob.setup(check=False) with self.assertRaises(AnalysisError): prob.run_model() # verify read_only status is reset after AnalysisError prob['comp1.x'] = 111.
def test_double_arraycomp(self): # Mainly testing a bug in the array return for multiple arrays group = Group() group.add("x_param1", IndepVarComp("x1", np.ones((2))), promotes=["*"]) group.add("x_param2", IndepVarComp("x2", np.ones((2))), promotes=["*"]) group.add("mycomp", DoubleArrayComp(), promotes=["*"]) prob = Problem() prob.root = group prob.root.ln_solver = ScipyGMRES() prob.setup(check=False) prob.run() Jbase = group.mycomp.JJ J = prob.calc_gradient(["x1", "x2"], ["y1", "y2"], mode="fwd", return_format="array") diff = np.linalg.norm(J - Jbase) assert_rel_error(self, diff, 0.0, 1e-8) J = prob.calc_gradient(["x1", "x2"], ["y1", "y2"], mode="fd", return_format="array") diff = np.linalg.norm(J - Jbase) assert_rel_error(self, diff, 0.0, 1e-8) J = prob.calc_gradient(["x1", "x2"], ["y1", "y2"], mode="rev", return_format="array") diff = np.linalg.norm(J - Jbase) assert_rel_error(self, diff, 0.0, 1e-8)
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 test_options(self): """Verify that the PETScKrylov specific options are declared.""" group = Group() group.linear_solver = PETScKrylov() assert(group.linear_solver.options['ksp_type'] == 'fgmres')
def test_simple_matvec(self): class VerificationComp(SimpleCompDerivMatVec): def linearize(self, params, unknowns, resids): raise RuntimeError("Derivative functions on this comp should not run.") def apply_linear(self, params, unknowns, dparams, dunknowns, dresids, mode): raise RuntimeError("Derivative functions on this comp should not run.") sub = Group() sub.add('mycomp', VerificationComp()) prob = Problem() prob.root = Group() prob.root.add('sub', sub) prob.root.add('x_param', IndepVarComp('x', 1.0)) prob.root.connect('x_param.x', "sub.mycomp.x") sub.fd_options['force_fd'] = True prob.setup(check=False) prob.run() J = prob.calc_gradient(['x_param.x'], ['sub.mycomp.y'], mode='fwd', return_format='dict') assert_rel_error(self, J['sub.mycomp.y']['x_param.x'][0][0], 2.0, 1e-6) J = prob.calc_gradient(['x_param.x'], ['sub.mycomp.y'], mode='rev', return_format='dict') assert_rel_error(self, J['sub.mycomp.y']['x_param.x'][0][0], 2.0, 1e-6)
def test_case1_vs_inductrack(self): root = Group() root.add('lev', levitation_group.LevGroup()) prob = Problem(root) 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)) prob.root.connect('input_vars.m_pod', 'lev.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') prob.setup() prob['lev.Drag.b_res'] = 1.48 prob['lev.Drag.num_mag_hal'] = 4.0 prob['lev.Drag.gamma'] = 1.0 prob['lev.Drag.w_mag'] = 3.0 prob['lev.Drag.spacing'] = 0.0 prob['lev.Drag.w_strip'] = .005 prob['lev.Drag.num_sheets'] = 1.0 prob['lev.Drag.delta_c'] = .0005334 prob['lev.Drag.strip_c'] = .0105 prob['lev.Drag.rc'] = 1.713e-8 prob['lev.Drag.MU0'] = 4.0*np.pi*(1.0e-7) prob['lev.Drag.track_factor'] = .75 prob['lev.Drag.g'] = 9.81 prob['lev.Drag.mag_thk'] = .15 prob['lev.Mass.mag_thk'] = .15 prob['lev.Mass.rho_mag'] = 7500.0 prob['lev.Mass.gamma'] = 1.0 prob['lev.Mass.cost_per_kg'] = 44.0 prob['lev.Mass.w_mag'] = 3.0 prob['lev.Mass.track_factor'] = .75 prob.run() # Print Statements for debugging # print('Mag Mass %f' % prob['lev.m_mag']) # print('Mag Drag is %f' % prob['lev.mag_drag']) # Test Values assert np.isclose(prob['lev.mag_drag'], 9025.39, rtol=.01) assert np.isclose(prob['lev.total_pod_mass'], 21562.50, rtol=.01)
def test_bad_sysname(self): group = Group() try: group.add("0", ExecComp("y=x*2.0"), promotes=["x"]) except NameError as err: self.assertEqual(str(err), ": '0' is not a valid system name.") try: group.add("foo:bar", ExecComp("y=x*2.0"), promotes=["x"]) except NameError as err: self.assertEqual(str(err), ": 'foo:bar' is not a valid system name.")
def test_bad_sysname(self): group = Group() try: group.add('0', ExecComp('y=x*2.0'), promotes=['x']) except NameError as err: self.assertEqual(str(err), ": '0' is not a valid system name.") try: group.add('foo:bar', ExecComp('y=x*2.0'), promotes=['x']) except NameError as err: self.assertEqual(str(err), ": 'foo:bar' is not a valid system name.")
def test_vectorized_A(self): """Check against the scipy solver.""" model = Group() x = np.array([[1, 2, -3], [2, -1, 4]]) A = np.array([[[5.0, -3.0, 2.0], [1.0, 7.0, -4.0], [1.0, 0.0, 8.0]], [[2.0, 3.0, 4.0], [1.0, -1.0, -2.0], [3.0, 2.0, -2.0]]]) b = np.einsum('ijk,ik->ij', A, x) model.add_subsystem('p1', IndepVarComp('A', A)) model.add_subsystem('p2', IndepVarComp('b', b)) lingrp = model.add_subsystem('lingrp', Group(), promotes=['*']) lingrp.add_subsystem('lin', LinearSystemComp(size=3, vec_size=2, vectorize_A=True)) model.connect('p1.A', 'lin.A') model.connect('p2.b', 'lin.b') prob = Problem(model) prob.setup() lingrp.linear_solver = ScipyKrylov() prob.set_solver_print(level=0) prob.run_model() assert_rel_error(self, prob['lin.x'], x, .0001) assert_rel_error(self, prob.model._residuals.get_norm(), 0.0, 1e-10) model.run_apply_nonlinear() with model._scaled_context_all(): val = model.lingrp.lin._residuals['x'] assert_rel_error(self, val, np.zeros((2, 3)), tolerance=1e-8)
def test_group_add(self): model = Group() ecomp = ExecComp('b=2.0*a', a=3.0, b=6.0) msg = "The 'add' method provides backwards compatibility with OpenMDAO <= 1.x ; " \ "use 'add_subsystem' instead." with assert_warning(DeprecationWarning, msg): comp1 = model.add('comp1', ecomp) self.assertTrue(ecomp is comp1)
def test_multiple_connect_alt(self): root = Group() C1 = root.add("C1", ExecComp("y=x*2.0")) C2 = root.add("C2", ExecComp("y=x*2.0")) C3 = root.add("C3", ExecComp("y=x*2.0")) with self.assertRaises(TypeError) as err: root.connect("C1.y", "C2.x", "C3.x") msg = "src_indices must be an index array, did you mean connect('C1.y', ['C2.x', 'C3.x'])?" self.assertEqual(msg, str(err.exception))
def test_generate_numpydocstring(self): group = Group() group.add('x_param', IndepVarComp('x', 1.0), promotes=['*']) group.add('mycomp', SimpleCompDerivMatVec(), promotes=['x', 'y']) prob = Problem() prob.root = group prob.root.ln_solver = ScipyGMRES() test_string = prob.root.ln_solver.generate_docstring() original_string = ' """\n\n Options\n -------\n options[\'atol\'] : float(1e-12)\n Absolute convergence tolerance.\n options[\'iprint\'] : int(0)\n Set to 0 to disable printing, set to 1 to print the residual to stdout each iteration, set to 2 to print subiteration residuals as well.\n options[\'maxiter\'] : int(1000)\n Maximum number of iterations.\n options[\'mode\'] : str(\'auto\')\n Derivative calculation mode, set to \'fwd\' for forward mode, \'rev\' for reverse mode, or \'auto\' to let OpenMDAO determine the best mode.\n options[\'precondition\'] : bool(False)\n Set to True to turn on preconditioning.\n options[\'restart\'] : int(20)\n Number of iterations between restarts. Larger values increase iteration cost, but may be necessary for convergence\n\n """\n' self.assertEqual(original_string, test_string)
def test_group_add(self): model=Group() ecomp = ExecComp('b=2.0*a', a=3.0, b=6.0) with warnings.catch_warnings(record=True) as w: comp1 = model.add('comp1', ecomp) self.assertEqual(len(w), 1) self.assertTrue(issubclass(w[0].category, DeprecationWarning)) self.assertEqual(str(w[0].message), "The 'add' method provides backwards compatibility " "with OpenMDAO <= 1.x ; use 'add_subsystem' instead.") self.assertTrue(ecomp is comp1)
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 test_array2D_index_connection(self): group = Group() group.add('x_param', IndepVarComp('x', np.ones((2, 2))), promotes=['*']) sub = group.add('sub', Group(), promotes=['*']) sub.add('mycomp', ArrayComp2D(), promotes=['x', 'y']) group.add('obj', ExecComp('b = a')) group.connect('y', 'obj.a', src_indices=[3]) prob = Problem() prob.root = group prob.root.ln_solver = LinearGaussSeidel() prob.setup(check=False) prob.run() J = prob.calc_gradient(['x'], ['obj.b'], mode='fwd', return_format='dict') Jbase = prob.root.sub.mycomp._jacobian_cache assert_rel_error(self, Jbase[('y', 'x')][3][0], J['obj.b']['x'][0][0], 1e-8) assert_rel_error(self, Jbase[('y', 'x')][3][1], J['obj.b']['x'][0][1], 1e-8) assert_rel_error(self, Jbase[('y', 'x')][3][2], J['obj.b']['x'][0][2], 1e-8) assert_rel_error(self, Jbase[('y', 'x')][3][3], J['obj.b']['x'][0][3], 1e-8) J = prob.calc_gradient(['x'], ['obj.b'], mode='rev', return_format='dict') Jbase = prob.root.sub.mycomp._jacobian_cache assert_rel_error(self, Jbase[('y', 'x')][3][0], J['obj.b']['x'][0][0], 1e-8) assert_rel_error(self, Jbase[('y', 'x')][3][1], J['obj.b']['x'][0][1], 1e-8) assert_rel_error(self, Jbase[('y', 'x')][3][2], J['obj.b']['x'][0][2], 1e-8) assert_rel_error(self, Jbase[('y', 'x')][3][3], J['obj.b']['x'][0][3], 1e-8)
def test_deprecated_solver_names(self): class DummySolver(): pass model = Group() # check nl_solver setter with warnings.catch_warnings(record=True) as w: model.nl_solver = DummySolver() self.assertEqual(len(w), 1) self.assertTrue(issubclass(w[0].category, DeprecationWarning)) self.assertEqual(str(w[0].message), "The 'nl_solver' attribute provides backwards compatibility " "with OpenMDAO 1.x ; use 'nonlinear_solver' instead.") # check nl_solver getter with warnings.catch_warnings(record=True) as w: solver = model.nl_solver self.assertEqual(len(w), 1) self.assertTrue(issubclass(w[0].category, DeprecationWarning)) self.assertEqual(str(w[0].message), "The 'nl_solver' attribute provides backwards compatibility " "with OpenMDAO 1.x ; use 'nonlinear_solver' instead.") self.assertTrue(isinstance(solver, DummySolver)) # check ln_solver setter with warnings.catch_warnings(record=True) as w: model.ln_solver = DummySolver() self.assertEqual(len(w), 1) self.assertTrue(issubclass(w[0].category, DeprecationWarning)) self.assertEqual(str(w[0].message), "The 'ln_solver' attribute provides backwards compatibility " "with OpenMDAO 1.x ; use 'linear_solver' instead.") # check ln_solver getter with warnings.catch_warnings(record=True) as w: solver = model.ln_solver self.assertEqual(len(w), 1) self.assertTrue(issubclass(w[0].category, DeprecationWarning)) self.assertEqual(str(w[0].message), "The 'ln_solver' attribute provides backwards compatibility " "with OpenMDAO 1.x ; use 'linear_solver' instead.") self.assertTrue(isinstance(solver, DummySolver))
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_simple(self): group = Group() group.add('x_param', IndepVarComp('x', 1.0), promotes=['*']) group.add('mycomp', SimpleCompDerivMatVec(), promotes=['x', 'y']) prob = Problem(impl=impl) prob.root = group prob.root.ln_solver = PetscKSP() prob.setup(check=False) prob.run() J = prob.calc_gradient(['x'], ['y'], mode='fwd', return_format='dict') assert_rel_error(self, J['y']['x'][0][0], 2.0, 1e-6) J = prob.calc_gradient(['x'], ['y'], mode='rev', return_format='dict') assert_rel_error(self, J['y']['x'][0][0], 2.0, 1e-6)
def test_simple_matvec(self): group = Group() group.add("x_param", IndepVarComp("x", 1.0), promotes=["*"]) group.add("mycomp", SimpleCompDerivMatVec(), promotes=["x", "y"]) prob = Problem() prob.root = group prob.root.ln_solver = ScipyGMRES() prob.setup(check=False) prob.run() J = prob.calc_gradient(["x"], ["y"], mode="fwd", return_format="dict") assert_rel_error(self, J["y"]["x"][0][0], 2.0, 1e-6) J = prob.calc_gradient(["x"], ["y"], mode="rev", return_format="dict") assert_rel_error(self, J["y"]["x"][0][0], 2.0, 1e-6)
def test_simple_jac(self): group = Group() group.add('x_param', IndepVarComp('x', 1.0), promotes=['*']) group.add('mycomp', ExecComp(['y=2.0*x']), promotes=['x', 'y']) prob = Problem() prob.root = group prob.root.ln_solver = ScipyGMRES() prob.setup(check=False) prob.run() J = prob.calc_gradient(['x'], ['y'], mode='fwd', return_format='dict') assert_rel_error(self, J['y']['x'][0][0], 2.0, 1e-6) J = prob.calc_gradient(['x'], ['y'], mode='rev', return_format='dict') assert_rel_error(self, J['y']['x'][0][0], 2.0, 1e-6)
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 assertRaisesRegex(self, 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 assertRaisesRegex(self, 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 assertRaisesRegex(self, 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 assertRaisesRegex(self, Exception, msg): prob.run_model()
def setUp(self): group = Group() comp1 = group.add_subsystem('comp1', IndepVarComp()) comp1.add_output('a', 1.0) comp1.add_output('b', -4.0) comp1.add_output('c', 3.0) group.add_subsystem('comp2', QuadraticLinearize()) group.add_subsystem('comp3', QuadraticJacVec()) group.connect('comp1.a', 'comp2.a') group.connect('comp1.b', 'comp2.b') group.connect('comp1.c', 'comp2.c') group.connect('comp1.a', 'comp3.a') group.connect('comp1.b', 'comp3.b') group.connect('comp1.c', 'comp3.c') prob = Problem(model=group) prob.setup(check=False) self.prob = prob
for tur in range(nt): distance[tur] = [ distance_to_front(layout_x[tur], layout_y[tur], angle), tur, layout_x[tur], layout_y[tur] ] distance.sort() unknowns['turbine_index'] = array([x[1] for x in distance]) unknowns['ordered_layout_x'] = array([x[2] for x in distance]) unknowns['ordered_layout_y'] = array([x[3] for x in distance]) if __name__ == '__main__': # nt = 9 root = Group() root.add( 'farm_x', IndepVarComp( 'x', array([0., 560., 1120., 1680., 2240., 2800., 3360., 3920., 4480.]))) root.add('farm_y', IndepVarComp('y', array([0., 0., 0., 0., 0., 0., 0., 0., 0.]))) root.add('theta', IndepVarComp('angle', 0.0)) root.add('order', OrderLayout()) root.connect('farm_x.x', 'order.layout_x') root.connect('farm_y.y', 'order.layout_y') root.connect('theta.angle', 'order.angle')
def setUp(self): from openmdao.api import Group, Problem, IndepVarComp from openmdao.core.tests.test_impl_comp import QuadraticComp group = Group() comp1 = group.add_subsystem('comp1', IndepVarComp()) comp1.add_output('a', 1.0) comp1.add_output('b', 1.0) comp1.add_output('c', 1.0) sub = group.add_subsystem('sub', Group()) sub.add_subsystem('comp2', QuadraticComp()) sub.add_subsystem('comp3', QuadraticComp()) group.connect('comp1.a', 'sub.comp2.a') group.connect('comp1.b', 'sub.comp2.b') group.connect('comp1.c', 'sub.comp2.c') group.connect('comp1.a', 'sub.comp3.a') group.connect('comp1.b', 'sub.comp3.b') group.connect('comp1.c', 'sub.comp3.c') global prob prob = Problem(model=group) prob.setup() prob['comp1.a'] = 1. prob['comp1.b'] = -4. prob['comp1.c'] = 3. prob.run_model()
def test_guess_nonlinear_transfer_subbed2(self): # Test that data is transfered to a component before calling guess_nonlinear. class ImpWithInitial(ImplicitComponent): def setup(self): self.add_input('x', 3.0) self.add_output('y', 4.0) def solve_nonlinear(self, inputs, outputs): """ Do nothing. """ pass def apply_nonlinear(self, inputs, outputs, resids): """ Do nothing. """ resids['y'] = 1.0e-6 pass def guess_nonlinear(self, inputs, outputs, resids): # Passthrough outputs['y'] = inputs['x'] group = Group() sub = Group() group.add_subsystem('px', IndepVarComp('x', 77.0)) sub.add_subsystem('comp1', ImpWithInitial()) sub.add_subsystem('comp2', ImpWithInitial()) group.connect('px.x', 'sub.comp1.x') group.connect('sub.comp1.y', 'sub.comp2.x') group.add_subsystem('sub', sub) sub.nonlinear_solver = NewtonSolver() sub.nonlinear_solver.options['maxiter'] = 1 prob = Problem(model=group) prob.set_solver_print(level=0) prob.setup(check=False) prob.run_model() assert_rel_error(self, prob['sub.comp2.y'], 77., 1e-5)
def test_implicit_scale_with_scalar_jac(self): raise unittest.SkipTest( 'Cannot specify an n by m subjac with a scalar yet.') class ImpCompArrayScale(TestImplCompArrayDense): def setup(self): self.add_input('rhs', val=np.ones(2)) self.add_output('x', val=np.zeros(2), ref=np.array([2.0, 3.0]), ref0=np.array([4.0, 9.0]), res_ref=np.array([7.0, 11.0])) self.add_output('extra', val=np.zeros(2), ref=np.array([12.0, 13.0]), ref0=np.array([14.0, 17.0])) def apply_nonlinear(self, inputs, outputs, residuals): super(ImpCompArrayScale, self).apply_nonlinear(inputs, outputs, residuals) residuals['extra'] = 2.0 * self.mtx.dot( outputs['x']) - 3.0 * inputs['rhs'] def linearize(self, inputs, outputs, jacobian): # These are incorrect derivatives, but we aren't doing any calculations, and it makes # it much easier to check that the scales are correct. jacobian['x', 'x'][:] = 1.0 jacobian['x', 'extra'][:] = 1.0 jacobian['extra', 'x'][:] = 1.0 jacobian['x', 'rhs'] = -np.eye(2) prob = Problem() model = prob.model = Group() model.add_subsystem('p1', IndepVarComp('x', np.ones(2))) comp = model.add_subsystem('comp', ImpCompArrayScale()) model.connect('p1.x', 'comp.rhs') prob.setup(check=False) prob.run_model() base_x = model.comp._outputs['x'].copy() base_ex = model.comp._outputs['extra'].copy() base_res_x = model.comp._residuals['x'].copy() with model._scaled_context_all(): val = model.comp._outputs['x'] assert_rel_error(self, val[0], (base_x[0] - 4.0) / (2.0 - 4.0)) assert_rel_error(self, val[1], (base_x[1] - 9.0) / (3.0 - 9.0)) val = model.comp._outputs['extra'] assert_rel_error(self, val[0], (base_ex[0] - 14.0) / (12.0 - 14.0)) assert_rel_error(self, val[1], (base_ex[1] - 17.0) / (13.0 - 17.0)) val = model.comp._residuals['x'].copy() assert_rel_error(self, val[0], (base_res_x[0]) / (7.0)) assert_rel_error(self, val[1], (base_res_x[1]) / (11.0)) model.run_linearize() with model._scaled_context_all(): subjacs = comp._jacobian assert_rel_error(self, subjacs['comp.x', 'comp.x'][0][0], (2.0 - 4.0) / (7.0 - 13.0)) assert_rel_error(self, subjacs['comp.x', 'comp.x'][1][0], (2.0 - 4.0) / (11.0 - 18.0)) assert_rel_error(self, subjacs['comp.x', 'comp.x'][0][1], (3.0 - 9.0) / (7.0 - 13.0)) assert_rel_error(self, subjacs['comp.x', 'comp.x'][1][1], (3.0 - 9.0) / (11.0 - 18.0)) assert_rel_error(self, subjacs['comp.x', 'comp.extra'][0][0], (12.0 - 14.0) / (7.0 - 13.0)) assert_rel_error(self, subjacs['comp.x', 'comp.extra'][1][0], (12.0 - 14.0) / (11.0 - 18.0)) assert_rel_error(self, subjacs['comp.x', 'comp.extra'][0][1], (13.0 - 17.0) / (7.0 - 13.0)) assert_rel_error(self, subjacs['comp.x', 'comp.extra'][1][1], (13.0 - 17.0) / (11.0 - 18.0)) assert_rel_error(self, subjacs['comp.x', 'comp.rhs'][0][0], -1.0 / (7.0 - 13.0)) assert_rel_error(self, subjacs['comp.x', 'comp.rhs'][1][0], 0.0) assert_rel_error(self, subjacs['comp.x', 'comp.rhs'][0][1], 0.0) assert_rel_error(self, subjacs['comp.x', 'comp.rhs'][1][1], -1.0 / (11.0 - 18.0))
self.add_subsystem('wing',WingWeight_SmallTurboprop(),promotes_inputs=["*"],promotes_outputs=["*"]) self.add_subsystem('empennage',EmpennageWeight_SmallTurboprop(),promotes_inputs=["*"],promotes_outputs=["*"]) self.add_subsystem('fuselage',FuselageWeight_SmallTurboprop(),promotes_inputs=["*"],promotes_outputs=["*"]) self.add_subsystem('nacelle',NacelleWeight_SmallSingleTurboprop(),promotes_inputs=["*"],promotes_outputs=["*"]) self.add_subsystem('gear',LandingGearWeight_SmallTurboprop(),promotes_inputs=["*"],promotes_outputs=["*"]) self.add_subsystem('fuelsystem', FuelSystemWeight_SmallTurboprop(), promotes_inputs=["*"],promotes_outputs=["*"]) self.add_subsystem('equipment',EquipmentWeight_SmallTurboprop(), promotes_inputs=["*"],promotes_outputs=["*"]) self.add_subsystem('structural',AddSubtractComp(output_name='W_structure',input_names=['W_wing','W_fuselage','W_nacelle','W_empennage','W_gear'], units='lb'),promotes_outputs=['*'],promotes_inputs=["*"]) self.add_subsystem('structural_fudge',ElementMultiplyDivideComp(output_name='W_structure_adjusted',input_names=['W_structure','structural_fudge'],input_units=['lb','m/m']),promotes_inputs=["*"],promotes_outputs=["*"]) self.add_subsystem('totalempty',AddSubtractComp(output_name='OEW',input_names=['W_structure_adjusted','W_fuelsystem','W_equipment','W_engine','W_propeller','W_fluids'], units='lb'),promotes_outputs=['*'],promotes_inputs=["*"]) if __name__ == "__main__": from openmdao.api import IndepVarComp, Problem prob = Problem() prob.model = Group() dvs = prob.model.add_subsystem('dvs',IndepVarComp(),promotes_outputs=["*"]) AR = 41.5**2/193.75 dvs.add_output('ac|weights|MTOW',7394.0, units='lb') dvs.add_output('ac|geom|wing|S_ref',193.75, units='ft**2') dvs.add_output('ac|geom|wing|AR',AR) dvs.add_output('ac|geom|wing|c4sweep',1.0, units='deg') dvs.add_output('ac|geom|wing|taper',0.622) dvs.add_output('ac|geom|wing|toverc',0.16) #dvs.add_output('V_H',255, units='kn') dvs.add_output('ac|geom|hstab|S_ref',47.5, units='ft**2') #dvs.add_output('AR_h',4.13) dvs.add_output('ac|geom|vstab|S_ref',31.36, units='ft**2') #dvs.add_output('AR_v',1.2) #dvs.add_output('troot_h',0.8, units='ft')
def test_simple_list_vars_options(self): from openmdao.api import IndepVarComp, Group, Problem, ExecComp prob = Problem() prob.model = model = Group() model.add_subsystem( 'p1', IndepVarComp('x', 12.0, lower=1.0, upper=100.0, ref=1.1, ref0=2.1, units='inch')) model.add_subsystem( 'p2', IndepVarComp('y', 1.0, lower=2.0, upper=200.0, ref=1.2, res_ref=2.2, units='ft')) model.add_subsystem( 'comp', ExecComp('z=x+y', x={ 'value': 0.0, 'units': 'inch' }, y={ 'value': 0.0, 'units': 'inch' }, z={ 'value': 0.0, 'units': 'inch' })) model.connect('p1.x', 'comp.x') model.connect('p2.y', 'comp.y') prob.setup() prob.set_solver_print(level=0) prob.run_model() # list_inputs tests # Can't do exact equality here because units cause comp.y to be slightly different than 12.0 stream = cStringIO() inputs = prob.model.list_inputs(units=True, out_stream=stream) tol = 1e-7 for actual, expected in zip(sorted(inputs), [('comp.x', { 'value': [12.], 'units': 'inch' }), ('comp.y', { 'value': [12.], 'units': 'inch' })]): self.assertEqual(expected[0], actual[0]) self.assertEqual(expected[1]['units'], actual[1]['units']) assert_rel_error(self, expected[1]['value'], actual[1]['value'], tol) text = stream.getvalue() self.assertEqual(1, text.count("Input(s) in 'model'")) self.assertEqual(1, text.count('varname')) self.assertEqual(1, text.count('value')) self.assertEqual(1, text.count('top')) self.assertEqual(1, text.count(' comp')) self.assertEqual(1, text.count(' x')) self.assertEqual(1, text.count(' y')) num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()]) self.assertEqual(8, num_non_empty_lines) # list_outputs tests # list outputs for implicit comps - should get none outputs = prob.model.list_outputs(implicit=True, explicit=False, out_stream=None) self.assertEqual(outputs, []) # list outputs with out_stream - just check to see if it was logged to stream = cStringIO() outputs = prob.model.list_outputs(out_stream=stream) text = stream.getvalue() self.assertEqual(1, text.count('Explicit Output')) self.assertEqual(1, text.count('Implicit Output')) # list outputs with out_stream and all the optional display values True stream = cStringIO() outputs = prob.model.list_outputs(values=True, units=True, shape=True, bounds=True, residuals=True, scaling=True, hierarchical=False, print_arrays=False, out_stream=stream) self.assertEqual([ ('comp.z', { 'value': [24.], 'resids': [0.], 'units': 'inch', 'shape': (1, ), 'lower': None, 'upper': None, 'ref': 1.0, 'ref0': 0.0, 'res_ref': 1.0 }), ('p1.x', { 'value': [12.], 'resids': [0.], 'units': 'inch', 'shape': (1, ), 'lower': [1.], 'upper': [100.], 'ref': 1.1, 'ref0': 2.1, 'res_ref': 1.1 }), ('p2.y', { 'value': [1.], 'resids': [0.], 'units': 'ft', 'shape': (1, ), 'lower': [2.], 'upper': [200.], 'ref': 1.2, 'ref0': 0.0, 'res_ref': 2.2 }), ], sorted(outputs)) text = stream.getvalue() self.assertEqual(1, text.count('varname')) self.assertEqual(1, text.count('value')) self.assertEqual(1, text.count('resids')) self.assertEqual(1, text.count('units')) self.assertEqual(1, text.count('shape')) self.assertEqual(1, text.count('lower')) self.assertEqual(1, text.count('upper')) self.assertEqual(3, text.count('ref')) self.assertEqual(1, text.count('ref0')) self.assertEqual(1, text.count('res_ref')) self.assertEqual(1, text.count('p1.x')) self.assertEqual(1, text.count('p2.y')) self.assertEqual(1, text.count('comp.z')) num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()]) self.assertEqual(9, num_non_empty_lines)
def test_for_feature_docs_list_vars_options(self): from openmdao.api import IndepVarComp, Group, Problem, ExecComp prob = Problem() prob.model = model = Group() model.add_subsystem( 'p1', IndepVarComp( 'x', 12.0, lower=1.0, upper=100.0, ref=1.1, ref0=2.1, units='inch', )) model.add_subsystem( 'p2', IndepVarComp( 'y', 1.0, lower=2.0, upper=200.0, ref=1.2, res_ref=2.2, units='ft', )) model.add_subsystem( 'comp', ExecComp('z=x+y', x={ 'value': 0.0, 'units': 'inch' }, y={ 'value': 0.0, 'units': 'inch' }, z={ 'value': 0.0, 'units': 'inch' })) model.connect('p1.x', 'comp.x') model.connect('p2.y', 'comp.y') prob.setup() prob.set_solver_print(level=0) prob.run_model() inputs = prob.model.list_inputs(units=True) print(inputs) outputs = prob.model.list_outputs(implicit=False, values=True, units=True, shape=True, bounds=True, residuals=True, scaling=True, hierarchical=False, print_arrays=False) self.assertEqual(sorted(outputs), [ ('comp.z', { 'value': [24.], 'resids': [0.], 'units': 'inch', 'shape': (1, ), 'lower': None, 'upper': None, 'ref': 1.0, 'ref0': 0.0, 'res_ref': 1.0 }), ('p1.x', { 'value': [12.], 'resids': [0.], 'units': 'inch', 'shape': (1, ), 'lower': [1.], 'upper': [100.], 'ref': 1.1, 'ref0': 2.1, 'res_ref': 1.1 }), ('p2.y', { 'value': [1.], 'resids': [0.], 'units': 'ft', 'shape': (1, ), 'lower': [2.], 'upper': [200.], 'ref': 1.2, 'ref0': 0.0, 'res_ref': 2.2 }), ]) outputs = prob.model.list_outputs(implicit=False, values=True, units=True, shape=True, bounds=True, residuals=True, scaling=True, hierarchical=True, print_arrays=False)
def benchmark_100(self): p = Problem(root=Group()) create_dyncomps(p.root, 100, 10, 10, 5) p.setup(check=False)
def setUp(self): transcription = 'gauss-lobatto' gd = GridData(num_segments=4, segment_ends=np.array([0., 2., 4., 5., 12.]), transcription=transcription, transcription_order=3) self.p = Problem(model=Group()) state_options = { 'x': { 'units': 'm', 'shape': (1, ) }, 'v': { 'units': 'm/s', 'shape': (3, 2) } } indep_comp = IndepVarComp() self.p.model.add_subsystem('indep', indep_comp, promotes_outputs=['*']) indep_comp.add_output('dt_dstau', val=np.zeros((gd.subset_num_nodes['col']))) indep_comp.add_output('f_approx:x', val=np.zeros((gd.subset_num_nodes['col'], 1)), units='m') indep_comp.add_output('f_computed:x', val=np.zeros((gd.subset_num_nodes['col'], 1)), units='m') indep_comp.add_output('f_approx:v', val=np.zeros((gd.subset_num_nodes['col'], 3, 2)), units='m/s') indep_comp.add_output('f_computed:v', val=np.zeros((gd.subset_num_nodes['col'], 3, 2)), units='m/s') self.p.model.add_subsystem('defect_comp', subsys=CollocationComp( grid_data=gd, state_options=state_options)) self.p.model.connect('f_approx:x', 'defect_comp.f_approx:x') self.p.model.connect('f_approx:v', 'defect_comp.f_approx:v') self.p.model.connect('f_computed:x', 'defect_comp.f_computed:x') self.p.model.connect('f_computed:v', 'defect_comp.f_computed:v') self.p.model.connect('dt_dstau', 'defect_comp.dt_dstau') self.p.setup(force_alloc_complex=True) self.p['dt_dstau'] = np.random.random(gd.subset_num_nodes['col']) self.p['f_approx:x'] = np.random.random( (gd.subset_num_nodes['col'], 1)) self.p['f_approx:v'] = np.random.random( (gd.subset_num_nodes['col'], 3, 2)) self.p['f_computed:x'] = np.random.random( (gd.subset_num_nodes['col'], 1)) self.p['f_computed:v'] = np.random.random( (gd.subset_num_nodes['col'], 3, 2)) self.p.run_model()
if t > t_crit: u['t'] = t else: u['t'] = t_crit u['dF_buoyancy'] = p['rho_water'] * p['g'] * p['A_tube'] u['material_cost'] = (np.pi * ((r + u['t'])**2) - p['A_tube'] ) * p['rho_tube'] * p['unit_cost_tube'] u['m_prime'] = (np.pi * ((r + u['t'])**2) - p['A_tube']) * p['rho_tube'] u['t_crit'] = t_crit if __name__ == '__main__': top = Problem() root = top.root = Group() root.add('p', SubmergedTube()) top.setup() top['p.p_tube'] = 850.0 # top['p.m_pod']= 10000.0 import csv # f = open('/Users/kennethdecker/Desktop/Paper figures/water_structural_trades.csv', 'wt') # writer = csv.writer(f) # writer.writerow(('A_tube', 't 20m', 't 40m', 't 60m', 'cost 20m', 'cost 40m', 'cost 60m')) depth = np.linspace(20.0, 60.0, num=3) A_tube = np.linspace(20.0, 50.0, num=30)
def test_basics(self): # create a metamodel component mm = MetaModel() mm.add_input('x1', 0.) mm.add_input('x2', 0.) mm.add_output('y1', 0.) mm.add_output('y2', 0., surrogate=FloatKrigingSurrogate()) mm.default_surrogate = ResponseSurface() # add metamodel to a problem prob = Problem(model=Group()) prob.model.add_subsystem('mm', mm) prob.setup(check=False) # check that surrogates were properly assigned surrogate = mm._metadata('y1').get('surrogate') self.assertTrue(isinstance(surrogate, ResponseSurface)) surrogate = mm._metadata('y2').get('surrogate') self.assertTrue(isinstance(surrogate, FloatKrigingSurrogate)) # populate training data mm.metadata['train:x1'] = [1.0, 2.0, 3.0] mm.metadata['train:x2'] = [1.0, 3.0, 4.0] mm.metadata['train:y1'] = [3.0, 2.0, 1.0] mm.metadata['train:y2'] = [1.0, 4.0, 7.0] # run problem for provided data point and check prediction prob['mm.x1'] = 2.0 prob['mm.x2'] = 3.0 self.assertTrue(mm.train) # training will occur before 1st run prob.run_model() assert_rel_error(self, prob['mm.y1'], 2.0, .00001) assert_rel_error(self, prob['mm.y2'], 4.0, .00001) # run problem for interpolated data point and check prediction prob['mm.x1'] = 2.5 prob['mm.x2'] = 3.5 self.assertFalse(mm.train) # training will not occur before 2nd run prob.run_model() assert_rel_error(self, prob['mm.y1'], 1.5934, .001) # change default surrogate, re-setup and check that metamodel re-trains mm.default_surrogate = FloatKrigingSurrogate() prob.setup(check=False) surrogate = mm._metadata('y1').get('surrogate') self.assertTrue(isinstance(surrogate, FloatKrigingSurrogate)) self.assertTrue(mm.train) # training will occur after re-setup mm.warm_restart = True # use existing training data prob['mm.x1'] = 2.5 prob['mm.x2'] = 3.5 prob.run_model() assert_rel_error(self, prob['mm.y1'], 1.5, 1e-2)
def min_time_climb(optimizer='SLSQP', num_seg=3, transcription='gauss-lobatto', transcription_order=3, force_alloc_complex=False): p = Problem(model=Group()) p.driver = pyOptSparseDriver() p.driver.options['optimizer'] = optimizer p.driver.options['dynamic_simul_derivs'] = True if optimizer == 'SNOPT': p.driver.opt_settings['Major iterations limit'] = 1000 p.driver.opt_settings['iSumm'] = 6 p.driver.opt_settings['Major feasibility tolerance'] = 1.0E-6 p.driver.opt_settings['Major optimality tolerance'] = 1.0E-6 p.driver.opt_settings['Function precision'] = 1.0E-12 p.driver.opt_settings['Linesearch tolerance'] = 0.1 p.driver.opt_settings['Major step limit'] = 0.5 # p.driver.opt_settings['Verify level'] = 3 t = { 'gauss-lobatto': dm.GaussLobatto(num_segments=num_seg, order=transcription_order), 'radau-ps': dm.Radau(num_segments=num_seg, order=transcription_order), 'runge-kutta': dm.RungeKutta(num_segments=num_seg) } traj = dm.Trajectory() phase = dm.Phase(ode_class=MinTimeClimbODE, transcription=t[transcription]) traj.add_phase('phase0', phase) p.model.add_subsystem('traj', traj) phase.set_time_options(fix_initial=True, duration_bounds=(50, 400), duration_ref=100.0) phase.set_state_options('r', fix_initial=True, lower=0, upper=1.0E6, ref=1.0E3, defect_ref=1.0E3, units='m') phase.set_state_options('h', fix_initial=True, lower=0, upper=20000.0, ref=1.0E2, defect_ref=1.0E2, units='m') phase.set_state_options('v', fix_initial=True, lower=10.0, ref=1.0E2, defect_ref=1.0E2, units='m/s') phase.set_state_options('gam', fix_initial=True, lower=-1.5, upper=1.5, ref=1.0, defect_ref=1.0, units='rad') phase.set_state_options('m', fix_initial=True, lower=10.0, upper=1.0E5, ref=1.0E3, defect_ref=1.0E3) phase.add_control('alpha', units='deg', lower=-8.0, upper=8.0, scaler=1.0, rate_continuity=True, rate_continuity_scaler=100.0, rate2_continuity=False) phase.add_design_parameter('S', val=49.2386, units='m**2', opt=False) phase.add_design_parameter('Isp', val=1600.0, units='s', opt=False) phase.add_design_parameter('throttle', val=1.0, opt=False) phase.add_boundary_constraint('h', loc='final', equals=20000, scaler=1.0E-3, units='m') phase.add_boundary_constraint('aero.mach', loc='final', equals=1.0) phase.add_boundary_constraint('gam', loc='final', equals=0.0, units='rad') phase.add_path_constraint(name='h', lower=100.0, upper=20000, ref=20000) phase.add_path_constraint(name='aero.mach', lower=0.1, upper=1.8) # Unnecessary but included to test capability phase.add_path_constraint(name='alpha', units='deg', lower=-8, upper=8) phase.add_path_constraint(name='time', lower=0, upper=400) phase.add_path_constraint(name='time_phase', lower=0, upper=400) # Minimize time at the end of the phase phase.add_objective('time', loc='final', ref=1.0) p.model.linear_solver = DirectSolver() p.setup(check=True, force_alloc_complex=force_alloc_complex) p['traj.phase0.t_initial'] = 0.0 p['traj.phase0.t_duration'] = 300.0 p['traj.phase0.states:r'] = phase.interpolate(ys=[0.0, 111319.54], nodes='state_input') p['traj.phase0.states:h'] = phase.interpolate(ys=[100.0, 20000.0], nodes='state_input') p['traj.phase0.states:v'] = phase.interpolate(ys=[135.964, 283.159], nodes='state_input') p['traj.phase0.states:gam'] = phase.interpolate(ys=[0.0, 0.0], nodes='state_input') p['traj.phase0.states:m'] = phase.interpolate(ys=[19030.468, 16841.431], nodes='state_input') p['traj.phase0.controls:alpha'] = phase.interpolate(ys=[0.0, 0.0], nodes='control_input') p.run_driver() return p
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_scale_and_add_array_with_array(self): class ExpCompArrayScale(TestExplCompArrayDense): def setup(self): self.add_input('lengths', val=np.ones((2, 2))) self.add_input('widths', val=np.ones((2, 2))) self.add_output('areas', val=np.ones((2, 2)), ref=np.array([[2.0, 3.0], [5.0, 7.0]]), ref0=np.array([[0.1, 0.2], [0.3, 0.4]]), lower=-1000.0, upper=1000.0) self.add_output('stuff', val=np.ones((2, 2)), ref=np.array([[11.0, 13.0], [17.0, 19.0]]), ref0=np.array([[0.6, 0.7], [0.8, 0.9]]), lower=np.array([[-5000.0, -4000.0], [-3000.0, -2000.0]]), upper=np.array([[5000.0, 4000.0], [3000.0, 2000.0]])) self.add_output('total_volume', val=1.) def compute(self, inputs, outputs): super(ExpCompArrayScale, self).compute(inputs, outputs) outputs['stuff'] = inputs['widths'] + inputs['lengths'] prob = Problem() model = prob.model = Group() model.add_subsystem('p1', IndepVarComp('x', np.ones((2, 2)))) model.add_subsystem('comp', ExpCompArrayScale()) model.connect('p1.x', 'comp.lengths') prob.setup(check=False) prob['comp.widths'] = np.ones((2, 2)) prob.run_model() assert_rel_error(self, prob['comp.total_volume'], 4.) with model._scaled_context_all(): val = model.comp._outputs['areas'] assert_rel_error(self, val[0, 0], (1.0 - 0.1) / (2 - 0.1)) assert_rel_error(self, val[0, 1], (1.0 - 0.2) / (3 - 0.2)) assert_rel_error(self, val[1, 0], (1.0 - 0.3) / (5 - 0.3)) assert_rel_error(self, val[1, 1], (1.0 - 0.4) / (7 - 0.4)) val = model.comp._outputs['stuff'] assert_rel_error(self, val[0, 0], (2.0 - 0.6) / (11 - 0.6)) assert_rel_error(self, val[0, 1], (2.0 - 0.7) / (13 - 0.7)) assert_rel_error(self, val[1, 0], (2.0 - 0.8) / (17 - 0.8)) assert_rel_error(self, val[1, 1], (2.0 - 0.9) / (19 - 0.9)) lb = model.comp._lower_bounds['areas'] assert_rel_error(self, lb[0, 0], (-1000.0 - 0.1) / (2 - 0.1)) assert_rel_error(self, lb[0, 1], (-1000.0 - 0.2) / (3 - 0.2)) assert_rel_error(self, lb[1, 0], (-1000.0 - 0.3) / (5 - 0.3)) assert_rel_error(self, lb[1, 1], (-1000.0 - 0.4) / (7 - 0.4)) ub = model.comp._upper_bounds['areas'] assert_rel_error(self, ub[0, 0], (1000.0 - 0.1) / (2 - 0.1)) assert_rel_error(self, ub[0, 1], (1000.0 - 0.2) / (3 - 0.2)) assert_rel_error(self, ub[1, 0], (1000.0 - 0.3) / (5 - 0.3)) assert_rel_error(self, ub[1, 1], (1000.0 - 0.4) / (7 - 0.4)) lb = model.comp._lower_bounds['stuff'] assert_rel_error(self, lb[0, 0], (-5000.0 - 0.6) / (11 - 0.6)) assert_rel_error(self, lb[0, 1], (-4000.0 - 0.7) / (13 - 0.7)) assert_rel_error(self, lb[1, 0], (-3000.0 - 0.8) / (17 - 0.8)) assert_rel_error(self, lb[1, 1], (-2000.0 - 0.9) / (19 - 0.9)) ub = model.comp._upper_bounds['stuff'] assert_rel_error(self, ub[0, 0], (5000.0 - 0.6) / (11 - 0.6)) assert_rel_error(self, ub[0, 1], (4000.0 - 0.7) / (13 - 0.7)) assert_rel_error(self, ub[1, 0], (3000.0 - 0.8) / (17 - 0.8)) assert_rel_error(self, ub[1, 1], (2000.0 - 0.9) / (19 - 0.9))
structure_problem_params = StaticStructureProblemParams( node_id, node_id_all) aero_problem_params = AeroProblemParams() na = aero_problem_dimensions.na network_info = aero_problem_dimensions.network_info node_coord = structure_problem_params.node_coord node_coord_all = structure_problem_params.node_coord_all t = structure_problem_params.t m = structure_problem_params.m apoints_coord = aero_problem_params.apoints_coord top = Problem() top.root = root = Group() # top.root.deriv_options['type'] = 'fd' # top.root.deriv_options['step_size'] = 1.0e-1 #Add independent variables root.add('wing_area', IndepVarComp('Sw', Sw), promotes=['*']) root.add('airspeed', IndepVarComp('V', V), promotes=['*']) root.add('sigma_y', IndepVarComp('sigma_y', sigma_y), promotes=['*']) root.add('t_ip', IndepVarComp('t_ip', t_ip), promotes=['*']) root.add('stress_ref', IndepVarComp('s0', s0), promotes=['*']) root.add('tick_ref', IndepVarComp('s1', s1), promotes=['*']) root.add('air_density', IndepVarComp('rho_a', rho_a), promotes=['*']) root.add('Mach_number', IndepVarComp('Mach', Mach), promotes=['*']) root.add('young_module', IndepVarComp('E', E), promotes=['*']) root.add('weight', IndepVarComp('W', W), promotes=['*']) root.add('mat_density', IndepVarComp('rho_s', rho_s), promotes=['*']) root.add('poisson', IndepVarComp('nu', nu), promotes=['*'])
def test_simple_list_vars_options(self): from openmdao.api import Group, Problem, IndepVarComp class QuadraticComp(ImplicitComponent): """ A Simple Implicit Component representing a Quadratic Equation. R(a, b, c, x) = ax^2 + bx + c Solution via Quadratic Formula: x = (-b + sqrt(b^2 - 4ac)) / 2a """ def setup(self): self.add_input('a', val=1., units='ft') self.add_input('b', val=1., units='inch') self.add_input('c', val=1., units='ft') self.add_output('x', val=0., lower=1.0, upper=100.0, ref=1.1, ref0=2.1, units='inch') 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) group = Group() comp1 = group.add_subsystem('comp1', IndepVarComp()) comp1.add_output('a', 1.0, units='ft') comp1.add_output('b', 1.0, units='inch') comp1.add_output('c', 1.0, units='ft') sub = group.add_subsystem('sub', Group()) sub.add_subsystem('comp2', QuadraticComp()) sub.add_subsystem('comp3', QuadraticComp()) group.connect('comp1.a', 'sub.comp2.a') group.connect('comp1.b', 'sub.comp2.b') group.connect('comp1.c', 'sub.comp2.c') group.connect('comp1.a', 'sub.comp3.a') group.connect('comp1.b', 'sub.comp3.b') group.connect('comp1.c', 'sub.comp3.c') global prob prob = Problem(model=group) prob.setup() prob['comp1.a'] = 1. prob['comp1.b'] = -4. prob['comp1.c'] = 3. prob.run_model() # list_inputs test stream = cStringIO() inputs = prob.model.list_inputs(values=False, out_stream=stream) text = stream.getvalue() self.assertEqual(sorted(inputs), [ ('sub.comp2.a', {}), ('sub.comp2.b', {}), ('sub.comp2.c', {}), ('sub.comp3.a', {}), ('sub.comp3.b', {}), ('sub.comp3.c', {}), ]) self.assertEqual(1, text.count("6 Input(s) in 'model'")) self.assertEqual(1, text.count("top")) self.assertEqual(1, text.count(" sub")) self.assertEqual(1, text.count(" comp2")) self.assertEqual(2, text.count(" a")) num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()]) self.assertEqual(num_non_empty_lines, 14) # list_outputs tests # list implicit outputs outputs = prob.model.list_outputs(explicit=False, out_stream=None) text = stream.getvalue() self.assertEqual(sorted(outputs), [('sub.comp2.x', { 'value': [3.] }), ('sub.comp3.x', { 'value': [3.] })]) # list explicit outputs stream = cStringIO() outputs = prob.model.list_outputs(implicit=False, out_stream=None) self.assertEqual(sorted(outputs), [ ('comp1.a', { 'value': [1.] }), ('comp1.b', { 'value': [-4.] }), ('comp1.c', { 'value': [3.] }), ])
def test_hierarchy_list_vars_options(self): prob = Problem() model = prob.model model.add_subsystem('pz', IndepVarComp('z', np.array([5.0, 2.0]))) sub1 = model.add_subsystem('sub1', Group()) sub2 = sub1.add_subsystem('sub2', Group()) g1 = sub2.add_subsystem('g1', SubSellar()) g2 = model.add_subsystem('g2', SubSellar()) model.connect('pz.z', 'sub1.sub2.g1.z') model.connect('sub1.sub2.g1.y2', 'g2.x') model.connect('g2.y2', 'sub1.sub2.g1.x') model.nonlinear_solver = NewtonSolver() model.linear_solver = ScipyKrylov() model.nonlinear_solver.options['solve_subsystems'] = True model.nonlinear_solver.options['max_sub_solves'] = 0 g1.nonlinear_solver = NewtonSolver() g1.linear_solver = LinearBlockGS() g2.nonlinear_solver = NewtonSolver() g2.linear_solver = ScipyKrylov() g2.linear_solver.precon = LinearBlockGS() g2.linear_solver.precon.options['maxiter'] = 2 prob.setup(check=False) prob.run_driver() # logging inputs # out_stream - not hierarchical - extras - no print_arrays stream = cStringIO() prob.model.list_inputs(values=True, units=True, hierarchical=False, print_arrays=False, out_stream=stream) text = stream.getvalue() self.assertEqual(1, text.count("10 Input(s) in 'model'")) # make sure they are in the correct order self.assertTrue( text.find("sub1.sub2.g1.d1.z") < text.find('sub1.sub2.g1.d1.x') < text.find('sub1.sub2.g1.d1.y2') < text.find('sub1.sub2.g1.d2.z') < text.find('sub1.sub2.g1.d2.y1') < text.find('g2.d1.z') < text.find( 'g2.d1.x') < text.find('g2.d1.y2') < text.find( 'g2.d2.z') < text.find('g2.d2.y1')) num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()]) self.assertEqual(14, num_non_empty_lines) # out_stream - hierarchical - extras - no print_arrays stream = cStringIO() prob.model.list_inputs(values=True, units=True, hierarchical=True, print_arrays=False, out_stream=stream) text = stream.getvalue() self.assertEqual(1, text.count("10 Input(s) in 'model'")) num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()]) self.assertEqual(23, num_non_empty_lines) self.assertEqual(1, text.count('top')) self.assertEqual(1, text.count(' sub1')) self.assertEqual(1, text.count(' sub2')) self.assertEqual(1, text.count(' g1')) self.assertEqual(1, text.count(' d1')) self.assertEqual(2, text.count(' z')) # logging outputs # out_stream - not hierarchical - extras - no print_arrays stream = cStringIO() prob.model.list_outputs(values=True, units=True, shape=True, bounds=True, residuals=True, scaling=True, hierarchical=False, print_arrays=False, out_stream=stream) text = stream.getvalue() self.assertEqual(text.count('5 Explicit Output'), 1) # make sure they are in the correct order self.assertTrue( text.find("pz.z") < text.find('sub1.sub2.g1.d1.y1') < text.find( 'sub1.sub2.g1.d2.y2') < text.find('g2.d1.y1') < text.find( 'g2.d2.y2')) num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()]) self.assertEqual(11, num_non_empty_lines) # Hierarchical stream = cStringIO() prob.model.list_outputs(values=True, units=True, shape=True, bounds=True, residuals=True, scaling=True, hierarchical=True, print_arrays=False, out_stream=stream) text = stream.getvalue() self.assertEqual(text.count('top'), 1) self.assertEqual(text.count(' y1'), 1) self.assertEqual(text.count(' g2'), 1) num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()]) self.assertEqual(num_non_empty_lines, 21)
def test_continuity_comp(self, transcription='gauss-lobatto', compressed='compressed'): num_seg = 3 gd = GridData(num_segments=num_seg, transcription_order=[5, 3, 3], segment_ends=[0.0, 3.0, 10.0, 20], transcription=transcription, compressed=compressed == 'compressed') self.p = Problem(model=Group()) ivp = self.p.model.add_subsystem('ivc', subsys=IndepVarComp(), promotes_outputs=['*']) nn = gd.subset_num_nodes['all'] ivp.add_output('x', val=np.arange(nn), units='m') ivp.add_output('y', val=np.arange(nn), units='m/s') ivp.add_output('u', val=np.zeros((nn, 3)), units='deg') ivp.add_output('v', val=np.arange(nn), units='N') ivp.add_output('u_rate', val=np.zeros((nn, 3)), units='deg/s') ivp.add_output('v_rate', val=np.arange(nn), units='N/s') ivp.add_output('u_rate2', val=np.zeros((nn, 3)), units='deg/s**2') ivp.add_output('v_rate2', val=np.arange(nn), units='N/s**2') ivp.add_output('t_duration', val=121.0, units='s') self.p.model.add_design_var('x', lower=0, upper=100) state_options = {'x': StateOptionsDictionary(), 'y': StateOptionsDictionary()} control_options = {'u': ControlOptionsDictionary(), 'v': ControlOptionsDictionary()} state_options['x']['units'] = 'm' state_options['y']['units'] = 'm/s' control_options['u']['units'] = 'deg' control_options['u']['shape'] = (3,) control_options['u']['continuity'] = True control_options['v']['units'] = 'N' if transcription == 'gauss-lobatto': cnty_comp = GaussLobattoContinuityComp(grid_data=gd, time_units='s', state_options=state_options, control_options=control_options) elif transcription == 'radau-ps': cnty_comp = RadauPSContinuityComp(grid_data=gd, time_units='s', state_options=state_options, control_options=control_options) else: raise ValueError('unrecognized transcription') self.p.model.add_subsystem('cnty_comp', subsys=cnty_comp) # The sub-indices of state_disc indices that are segment ends segment_end_idxs = gd.subset_node_indices['segment_ends'] if compressed != 'compressed': self.p.model.connect('x', 'cnty_comp.states:x', src_indices=segment_end_idxs) self.p.model.connect('y', 'cnty_comp.states:y', src_indices=segment_end_idxs) self.p.model.connect('t_duration', 'cnty_comp.t_duration') size_u = nn * np.prod(control_options['u']['shape']) src_idxs_u = np.arange(size_u).reshape((nn,) + control_options['u']['shape']) src_idxs_u = src_idxs_u[gd.subset_node_indices['segment_ends'], ...] size_v = nn * np.prod(control_options['v']['shape']) src_idxs_v = np.arange(size_v).reshape((nn,) + control_options['v']['shape']) src_idxs_v = src_idxs_v[gd.subset_node_indices['segment_ends'], ...] # if transcription =='radau-ps' or compressed != 'compressed': self.p.model.connect('u', 'cnty_comp.controls:u', src_indices=src_idxs_u, flat_src_indices=True) self.p.model.connect('u_rate', 'cnty_comp.control_rates:u_rate', src_indices=src_idxs_u, flat_src_indices=True) self.p.model.connect('u_rate2', 'cnty_comp.control_rates:u_rate2', src_indices=src_idxs_u, flat_src_indices=True) # if transcription =='radau-ps' or compressed != 'compressed': self.p.model.connect('v', 'cnty_comp.controls:v', src_indices=src_idxs_v, flat_src_indices=True) self.p.model.connect('v_rate', 'cnty_comp.control_rates:v_rate', src_indices=src_idxs_v, flat_src_indices=True) self.p.model.connect('v_rate2', 'cnty_comp.control_rates:v_rate2', src_indices=src_idxs_v, flat_src_indices=True) self.p.setup(check=True, force_alloc_complex=True) self.p['x'] = np.random.rand(*self.p['x'].shape) self.p['y'] = np.random.rand(*self.p['y'].shape) self.p['u'] = np.random.rand(*self.p['u'].shape) self.p['v'] = np.random.rand(*self.p['v'].shape) self.p['u_rate'] = np.random.rand(*self.p['u'].shape) self.p['v_rate'] = np.random.rand(*self.p['v'].shape) self.p['u_rate2'] = np.random.rand(*self.p['u'].shape) self.p['v_rate2'] = np.random.rand(*self.p['v'].shape) self.p.run_model() if compressed != 'compressed': for state in ('x', 'y'): xpectd = self.p[state][segment_end_idxs, ...][2::2, ...] - \ self.p[state][segment_end_idxs, ...][1:-1:2, ...] assert_rel_error(self, self.p['cnty_comp.defect_states:{0}'.format(state)], xpectd.reshape((num_seg - 1,) + state_options[state]['shape'])) for ctrl in ('u', 'v'): xpectd = self.p[ctrl][segment_end_idxs, ...][2::2, ...] - \ self.p[ctrl][segment_end_idxs, ...][1:-1:2, ...] if compressed != 'compressed': assert_rel_error(self, self.p['cnty_comp.defect_controls:{0}'.format(ctrl)], xpectd.reshape((num_seg-1,) + control_options[ctrl]['shape'])) np.set_printoptions(linewidth=1024) cpd = self.p.check_partials(method='cs', out_stream=None) assert_check_partials(cpd)
def test_resid_scale_default(self): # This model checks the contents of the residual in both scaled and unscaled states. # The model is a cycle that iterates once, so the first component in the cycle carries # a residual. class Simple(ExplicitComponent): def initialize(self): self.options.declare('ref', default=1.0) self.options.declare('ref0', default=0.0) self.options.declare('res_ref', default=None) self.options.declare('res_ref0', default=None) def setup(self): ref = self.options['ref'] ref0 = self.options['ref0'] res_ref = self.options['res_ref'] self.add_input('x', val=1.0) self.add_output('y', val=1.0, ref=ref, ref0=ref0, res_ref=res_ref) self.declare_partials('*', '*') def compute(self, inputs, outputs): outputs['y'] = 2.0 * (inputs['x'] + 1.0) def compute_partials(self, inputs, partials): """ Jacobian for Sellar discipline 1. """ partials['y', 'x'] = 2.0 # Baseline - all should be equal. prob = Problem() model = prob.model = Group() model.add_subsystem('p1', Simple()) model.add_subsystem('p2', Simple()) model.connect('p1.y', 'p2.x') model.connect('p2.y', 'p1.x') model.nonlinear_solver = NonlinearBlockGS() model.nonlinear_solver.options['maxiter'] = 1 model.nonlinear_solver.options['use_apply_nonlinear'] = True prob.set_solver_print(level=0) prob.setup(check=False) prob.run_model() res1 = -model.p1._residuals._data[0] out1 = model.p1._outputs._data[0] out2 = model.p2._outputs._data[0] self.assertEqual(res1, out1 - 2.0 * (out2 + 1.0)) with model._scaled_context_all(): res1 = -model.p1._residuals._data[0] out1 = model.p1._outputs._data[0] out2 = model.p2._outputs._data[0] self.assertEqual(res1, out1 - 2.0 * (out2 + 1.0)) # Jacobian is unscaled prob.model.run_linearize() deriv = model.p1._jacobian assert_rel_error(self, deriv['p1.y', 'p1.x'], [[2.0]]) # Scale the outputs only. # Residual scaling uses output scaling by default. ref = 1.0 ref0 = 1.5 prob = Problem() model = prob.model = Group() model.add_subsystem('p1', Simple(ref=ref, ref0=ref0)) model.add_subsystem('p2', Simple(ref=ref, ref0=ref0)) model.connect('p1.y', 'p2.x') model.connect('p2.y', 'p1.x') model.nonlinear_solver = NonlinearBlockGS() model.nonlinear_solver.options['maxiter'] = 1 model.nonlinear_solver.options['use_apply_nonlinear'] = True prob.set_solver_print(level=0) prob.setup(check=False) prob.run_model() res1 = -model.p1._residuals._data[0] out1 = model.p1._outputs._data[0] out2 = model.p2._outputs._data[0] self.assertEqual(res1, (out1 - 2.0 * (out2 + 1.0))) with model._scaled_context_all(): res1a = -model.p1._residuals._data[0] self.assertEqual(res1a, (res1) / (ref)) # Jacobian is unscaled prob.model.run_linearize() deriv = model.p1._jacobian assert_rel_error(self, deriv['p1.y', 'p1.x'], [[2.0]]) # Scale the residual res_ref = 4.0 prob = Problem() model = prob.model = Group() model.add_subsystem('p1', Simple(res_ref=res_ref)) model.add_subsystem('p2', Simple(res_ref=res_ref)) model.connect('p1.y', 'p2.x') model.connect('p2.y', 'p1.x') model.nonlinear_solver = NonlinearBlockGS() model.nonlinear_solver.options['maxiter'] = 1 model.nonlinear_solver.options['use_apply_nonlinear'] = True prob.set_solver_print(level=0) prob.setup(check=False) prob.run_model() res1 = -model.p1._residuals._data[0] out1 = model.p1._outputs._data[0] out2 = model.p2._outputs._data[0] self.assertEqual(res1, out1 - 2.0 * (out2 + 1.0)) with model._scaled_context_all(): res1a = -model.p1._residuals._data[0] self.assertEqual(res1a, res1 / res_ref) # Jacobian is unscaled prob.model.run_linearize() deriv = model.p1._jacobian assert_rel_error(self, deriv['p1.y', 'p1.x'], [[2.0]]) # Simultaneously scale the residual and output with different values ref = 3.0 ref0 = 2.75 res_ref = 4.0 prob = Problem() model = prob.model = Group() model.add_subsystem('p1', Simple(ref=ref, ref0=ref0, res_ref=res_ref)) model.add_subsystem('p2', Simple(ref=ref, ref0=ref0, res_ref=res_ref)) model.connect('p1.y', 'p2.x') model.connect('p2.y', 'p1.x') model.nonlinear_solver = NonlinearBlockGS() model.nonlinear_solver.options['maxiter'] = 1 model.nonlinear_solver.options['use_apply_nonlinear'] = True prob.set_solver_print(level=0) prob.setup(check=False) prob.run_model() res1 = -model.p1._residuals._data[0] out1 = model.p1._outputs._data[0] out2 = model.p2._outputs._data[0] self.assertEqual(res1, out1 - 2.0 * (out2 + 1.0)) with model._scaled_context_all(): res1a = -model.p1._residuals._data[0] self.assertEqual(res1a, (res1) / (res_ref)) # Jacobian is unscaled prob.model.run_linearize() deriv = model.p1._jacobian assert_rel_error(self, deriv['p1.y', 'p1.x'], [[2.0]])
def test_array_list_vars_options(self): class ArrayAdder(ExplicitComponent): """ Just a simple component that has array inputs and outputs """ def __init__(self, size): super(ArrayAdder, self).__init__() self.size = size def setup(self): self.add_input('x', val=np.zeros(self.size), units='inch') self.add_output('y', val=np.zeros(self.size), units='ft') def compute(self, inputs, outputs): outputs['y'] = inputs['x'] + 10.0 size = 100 # how many items in the array prob = Problem() prob.model = Group() prob.model.add_subsystem('des_vars', IndepVarComp('x', np.ones(size), units='inch'), promotes=['x']) prob.model.add_subsystem('mult', ArrayAdder(size), promotes=['x', 'y']) prob.setup(check=False) prob['x'] = np.ones(size) prob.run_driver() # logging inputs # out_stream - not hierarchical - extras - no print_arrays stream = cStringIO() prob.model.list_inputs(values=True, units=True, hierarchical=False, print_arrays=False, out_stream=stream) text = stream.getvalue() self.assertEqual(1, text.count("1 Input(s) in 'model'")) self.assertEqual(1, text.count('mult.x')) num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()]) self.assertEqual(5, num_non_empty_lines) # out_stream - hierarchical - extras - no print_arrays stream = cStringIO() prob.model.list_inputs(values=True, units=True, hierarchical=True, print_arrays=False, out_stream=stream) text = stream.getvalue() self.assertEqual(1, text.count("1 Input(s) in 'model'")) num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()]) self.assertEqual(7, num_non_empty_lines) self.assertEqual(1, text.count('top')) self.assertEqual(1, text.count(' mult')) self.assertEqual(1, text.count(' x')) # logging outputs # out_stream - not hierarchical - extras - no print_arrays stream = cStringIO() prob.model.list_outputs(values=True, units=True, shape=True, bounds=True, residuals=True, scaling=True, hierarchical=False, print_arrays=False, out_stream=stream) text = stream.getvalue() self.assertEqual(text.count('2 Explicit Output'), 1) # make sure they are in the correct order self.assertTrue(text.find("des_vars.x") < text.find('mult.y')) num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()]) self.assertEqual(8, num_non_empty_lines) # Hierarchical - no print arrays stream = cStringIO() prob.model.list_outputs(values=True, units=True, shape=True, bounds=True, residuals=True, scaling=True, hierarchical=True, print_arrays=False, out_stream=stream) text = stream.getvalue() self.assertEqual(text.count('top'), 1) self.assertEqual(text.count(' des_vars'), 1) self.assertEqual(text.count(' x'), 1) self.assertEqual(text.count(' mult'), 1) self.assertEqual(text.count(' y'), 1) num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()]) self.assertEqual(num_non_empty_lines, 11) # Need to explicitly set this to make sure all ways of running this test # result in the same format of the output. When running this test from the # top level via testflo, the format comes out different than if the test is # run individually opts = { 'edgeitems': 3, 'infstr': 'inf', 'linewidth': 75, 'nanstr': 'nan', 'precision': 8, 'suppress': False, 'threshold': 1000, } from distutils.version import LooseVersion if LooseVersion(np.__version__) >= LooseVersion("1.14"): opts['legacy'] = '1.13' with printoptions(**opts): # logging outputs # out_stream - not hierarchical - extras - print_arrays stream = cStringIO() prob.model.list_outputs(values=True, units=True, shape=True, bounds=True, residuals=True, scaling=True, hierarchical=False, print_arrays=True, out_stream=stream) text = stream.getvalue() self.assertEqual(text.count('2 Explicit Output'), 1) self.assertEqual(text.count('value:'), 2) self.assertEqual(text.count('resids:'), 2) self.assertEqual(text.count('['), 4) # make sure they are in the correct order self.assertTrue(text.find("des_vars.x") < text.find('mult.y')) num_non_empty_lines = sum( [1 for s in text.splitlines() if s.strip()]) self.assertEqual(37, num_non_empty_lines) # Hierarchical stream = cStringIO() prob.model.list_outputs(values=True, units=True, shape=True, bounds=True, residuals=True, scaling=True, hierarchical=True, print_arrays=True, out_stream=stream) text = stream.getvalue() self.assertEqual(text.count('2 Explicit Output'), 1) self.assertEqual(text.count('value:'), 2) self.assertEqual(text.count('resids:'), 2) self.assertEqual(text.count('['), 4) self.assertEqual(text.count('top'), 1) self.assertEqual(text.count(' des_vars'), 1) self.assertEqual(text.count(' x'), 1) self.assertEqual(text.count(' mult'), 1) self.assertEqual(text.count(' y'), 1) num_non_empty_lines = sum( [1 for s in text.splitlines() if s.strip()]) self.assertEqual(num_non_empty_lines, 40)
def test_for_docs_array_list_vars_options(self): import numpy as np from openmdao.api import Problem, Group, IndepVarComp, ExplicitComponent class ArrayAdder(ExplicitComponent): """ Just a simple component that has array inputs and outputs """ def __init__(self, size): super(ArrayAdder, self).__init__() self.size = size def setup(self): self.add_input('x', val=np.zeros(self.size), units='inch') self.add_output('y', val=np.zeros(self.size), units='ft') def compute(self, inputs, outputs): outputs['y'] = inputs['x'] + 10.0 size = 30 prob = Problem() prob.model = Group() prob.model.add_subsystem('des_vars', IndepVarComp('x', np.ones(size), units='inch'), promotes=['x']) prob.model.add_subsystem('mult', ArrayAdder(size), promotes=['x', 'y']) prob.setup(check=False) prob['x'] = np.arange(size) prob.run_driver() prob.model.list_inputs(values=True, units=True, hierarchical=True, print_arrays=True) with printoptions(edgeitems=3, infstr='inf', linewidth=75, nanstr='nan', precision=8, suppress=False, threshold=1000, formatter=None): prob.model.list_outputs(values=True, implicit=False, units=True, shape=True, bounds=True, residuals=True, scaling=True, hierarchical=False, print_arrays=True) prob.model.list_outputs(values=True, implicit=False, units=True, shape=True, bounds=True, residuals=True, scaling=True, hierarchical=True, print_arrays=True)
def solve_nonlinear(self, params, unknowns, resids): ''' f(y,z) = y + z ''' y = params['y'] z = params['z'] unknowns['f_yz'] = y + z if __name__ == '__main__': # Instantiate a Problem 'sub' # Instantiate a Group and add it to sub sub = Problem() sub.root = Group() # Add the 'Paraboloid' Component to sub's root Group. sub.root.add('Paraboloid', Paraboloid()) # Initialize x as a IndepVarComp and add it to sub's root group as 'p1.x' # p1.x and p2.y_i are initialized to 0.0 since neither was explicity initialized # and they both have ranges of -50 to +50. Default initialization: (+50 - (-50)) / 2.0 = 0 sub.root.add('p1', IndepVarComp('x', 0.0)) sub.root.add('p2', IndepVarComp('y_i', 0.0)) # Initialize z as a IndepVarComp and add it to sub's root group as 'p3.z' # Not sure if we will support running PETs with un-driven Problem Inputs but let's initialize it to 0.0 sub.root.add('p3', IndepVarComp('z', 0.0)) # Connect components
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.)
def test_set_checks_shape(self): indep = IndepVarComp() indep.add_output('a') indep.add_output('x', shape=(5, 1)) g1 = Group() g1.add_subsystem('Indep', indep, promotes=['a', 'x']) g2 = g1.add_subsystem('G2', Group(), promotes=['*']) g2.add_subsystem('C1', ExecComp('b=2*a'), promotes=['a', 'b']) g2.add_subsystem('C2', ExecComp('y=2*x', x=np.zeros((5, 1)), y=np.zeros((5, 1))), promotes=['x', 'y']) model = Group() model.add_subsystem('G1', g1, promotes=['b', 'y']) model.add_subsystem('Sink', ExecComp(('c=2*b', 'z=2*y'), y=np.zeros((5, 1)), z=np.zeros((5, 1))), promotes=['b', 'y']) p = Problem(model=model) p.setup() p.set_solver_print(level=0) p.run_model() msg = "Incompatible shape for '.*': Expected (.*) but got (.*)" num_val = -10 arr_val = -10 * np.ones((5, 1)) bad_val = -10 * np.ones((10)) inputs, outputs, residuals = g2.get_nonlinear_vectors() # # set input # # assign array to scalar with assertRaisesRegex(self, ValueError, msg): inputs['C1.a'] = arr_val # assign scalar to array inputs['C2.x'] = num_val assert_rel_error(self, inputs['C2.x'], arr_val, 1e-10) # assign array to array inputs['C2.x'] = arr_val assert_rel_error(self, inputs['C2.x'], arr_val, 1e-10) # assign bad array shape to array with assertRaisesRegex(self, ValueError, msg): inputs['C2.x'] = bad_val # assign list to array inputs['C2.x'] = arr_val.tolist() assert_rel_error(self, inputs['C2.x'], arr_val, 1e-10) # assign bad list shape to array with assertRaisesRegex(self, ValueError, msg): inputs['C2.x'] = bad_val.tolist() # # set output # # assign array to scalar with assertRaisesRegex(self, ValueError, msg): outputs['C1.b'] = arr_val # assign scalar to array outputs['C2.y'] = num_val assert_rel_error(self, outputs['C2.y'], arr_val, 1e-10) # assign array to array outputs['C2.y'] = arr_val assert_rel_error(self, outputs['C2.y'], arr_val, 1e-10) # assign bad array shape to array with assertRaisesRegex(self, ValueError, msg): outputs['C2.y'] = bad_val # assign list to array outputs['C2.y'] = arr_val.tolist() assert_rel_error(self, outputs['C2.y'], arr_val, 1e-10) # assign bad list shape to array with assertRaisesRegex(self, ValueError, msg): outputs['C2.y'] = bad_val.tolist() # # set residual # # assign array to scalar with assertRaisesRegex(self, ValueError, msg): residuals['C1.b'] = arr_val # assign scalar to array residuals['C2.y'] = num_val assert_rel_error(self, residuals['C2.y'], arr_val, 1e-10) # assign array to array residuals['C2.y'] = arr_val assert_rel_error(self, residuals['C2.y'], arr_val, 1e-10) # assign bad array shape to array with assertRaisesRegex(self, ValueError, msg): residuals['C2.y'] = bad_val # assign list to array residuals['C2.y'] = arr_val.tolist() assert_rel_error(self, residuals['C2.y'], arr_val, 1e-10) # assign bad list shape to array with assertRaisesRegex(self, ValueError, msg): residuals['C2.y'] = bad_val.tolist()
def test_guess_nonlinear(self): class ImpWithInitial(QuadraticLinearize): def solve_nonlinear(self, inputs, outputs): """ Do nothing. """ pass def guess_nonlinear(self, inputs, outputs, resids): # Solution at x=1 and x=3. Default value takes us to the x=1 solution. Here # we set it to a value that will take us to the x=3 solution. outputs['x'] = 5.0 group = Group() group.add_subsystem('pa', IndepVarComp('a', 1.0)) group.add_subsystem('pb', IndepVarComp('b', 1.0)) group.add_subsystem('pc', IndepVarComp('c', 1.0)) group.add_subsystem('comp2', ImpWithInitial()) group.connect('pa.a', 'comp2.a') group.connect('pb.b', 'comp2.b') group.connect('pc.c', 'comp2.c') prob = Problem(model=group) group.nonlinear_solver = NewtonSolver() group.nonlinear_solver.options['solve_subsystems'] = True group.nonlinear_solver.options['max_sub_solves'] = 1 group.linear_solver = ScipyKrylov() prob.setup(check=False) prob['pa.a'] = 1. prob['pb.b'] = -4. prob['pc.c'] = 3. # Making sure that guess_nonlinear is called early enough to eradicate this. prob['comp2.x'] = np.NaN prob.run_model() assert_rel_error(self, prob['comp2.x'], 3.)
def test_vector_context_managers(self): g1 = Group() g1.add_subsystem('Indep', IndepVarComp('a', 5.0), promotes=['a']) g2 = g1.add_subsystem('G2', Group(), promotes=['*']) g2.add_subsystem('C1', ExecComp('b=2*a'), promotes=['a', 'b']) model = Group() model.add_subsystem('G1', g1, promotes=['b']) model.add_subsystem('Sink', ExecComp('c=2*b'), promotes=['b']) p = Problem(model=model) p.set_solver_print(level=0) # Test pre-setup errors with self.assertRaises(Exception) as cm: inputs, outputs, residuals = model.get_nonlinear_vectors() self.assertEqual( str(cm.exception), "Cannot get vectors because setup has not yet been called.") with self.assertRaises(Exception) as cm: d_inputs, d_outputs, d_residuals = model.get_linear_vectors('vec') self.assertEqual( str(cm.exception), "Cannot get vectors because setup has not yet been called.") p.setup() p.run_model() # Test inputs with original values inputs, outputs, residuals = model.get_nonlinear_vectors() self.assertEqual(inputs['G1.G2.C1.a'], 5.) inputs, outputs, residuals = g1.get_nonlinear_vectors() self.assertEqual(inputs['G2.C1.a'], 5.) # Test inputs after setting a new value inputs, outputs, residuals = g2.get_nonlinear_vectors() inputs['C1.a'] = -1. inputs, outputs, residuals = model.get_nonlinear_vectors() self.assertEqual(inputs['G1.G2.C1.a'], -1.) inputs, outputs, residuals = g1.get_nonlinear_vectors() self.assertEqual(inputs['G2.C1.a'], -1.) # Test outputs with original values inputs, outputs, residuals = model.get_nonlinear_vectors() self.assertEqual(outputs['G1.G2.C1.b'], 10.) inputs, outputs, residuals = g2.get_nonlinear_vectors() # Test outputs after setting a new value inputs, outputs, residuals = model.get_nonlinear_vectors() outputs['G1.G2.C1.b'] = 123. self.assertEqual(outputs['G1.G2.C1.b'], 123.) inputs, outputs, residuals = g2.get_nonlinear_vectors() outputs['C1.b'] = 789. self.assertEqual(outputs['C1.b'], 789.) # Test residuals inputs, outputs, residuals = model.get_nonlinear_vectors() residuals['G1.G2.C1.b'] = 99.0 self.assertEqual(residuals['G1.G2.C1.b'], 99.0) # Test linear d_inputs, d_outputs, d_residuals = model.get_linear_vectors('linear') d_outputs['G1.G2.C1.b'] = 10. self.assertEqual(d_outputs['G1.G2.C1.b'], 10.) # Test linear with invalid vec_name with self.assertRaises(Exception) as cm: d_inputs, d_outputs, d_residuals = model.get_linear_vectors( 'bad_name') self.assertEqual(str(cm.exception), "There is no linear vector named %s" % 'bad_name')
def test_bounds_backtracking(self): class SimpleImplicitComp1(Component): """ A Simple Implicit Component with an additional output equation. f(x,z) = xz + z - 4 y = x + 2z Sol: when x = 0.5, z = 2.666 Sol: when x = 2.0, z = 1.333 Coupled derivs: y = x + 8/(x+1) dy_dx = 1 - 8/(x+1)**2 = -2.5555555555555554 z = 4/(x+1) dz_dx = -4/(x+1)**2 = -1.7777777777777777 """ def __init__(self): super(SimpleImplicitComp1, self).__init__() # Params self.add_param('x', 0.5) # Unknowns self.add_output('y', 0.0) # States self.add_state('z', 2.0, lower=1.4, upper=2.5) self.maxiter = 10 self.atol = 1.0e-12 def solve_nonlinear(self, params, unknowns, resids): pass def apply_nonlinear(self, params, unknowns, resids): """ Don't solve; just calculate the residual.""" x = params['x'] z = unknowns['z'] resids['z'] = x*z + z - 4.0 # Output equations need to evaluate a residual just like an explicit comp. resids['y'] = x + 2.0*z - unknowns['y'] def linearize(self, params, unknowns, resids): """Analytical derivatives.""" J = {} # Output equation J[('y', 'x')] = np.array([1.0]) J[('y', 'z')] = np.array([2.0]) # State equation J[('z', 'z')] = np.array([params['x'] + 1.0]) J[('z', 'x')] = np.array([unknowns['z']]) return J class SimpleImplicitComp2(Component): """ A Simple Implicit Component with an additional output equation. f(x,z) = xz + z - 4 y = x + 2z Sol: when x = 0.5, z = 2.666 Sol: when x = 2.0, z = 1.333 Coupled derivs: y = x + 8/(x+1) dy_dx = 1 - 8/(x+1)**2 = -2.5555555555555554 z = 4/(x+1) dz_dx = -4/(x+1)**2 = -1.7777777777777777 """ def __init__(self): super(SimpleImplicitComp2, self).__init__() # Params self.add_param('x', 0.5) # Unknowns self.add_output('y', 0.0) # States self.add_state('z', 2.0, lower=1.5, upper=2.5) self.maxiter = 10 self.atol = 1.0e-12 def solve_nonlinear(self, params, unknowns, resids): pass def apply_nonlinear(self, params, unknowns, resids): """ Don't solve; just calculate the residual.""" x = params['x'] z = unknowns['z'] resids['z'] = x*z + z - 4.0 # Output equations need to evaluate a residual just like an explicit comp. resids['y'] = x + 2.0*z - unknowns['y'] def linearize(self, params, unknowns, resids): """Analytical derivatives.""" J = {} # Output equation J[('y', 'x')] = np.array([1.0]) J[('y', 'z')] = np.array([2.0]) # State equation J[('z', 'z')] = np.array([params['x'] + 1.0]) J[('z', 'x')] = np.array([unknowns['z']]) return J #------------------------------------------------------ # Test that Newton doesn't drive it past lower bounds #------------------------------------------------------ top = Problem(impl=impl) top.root = Group() par = top.root.add('par', ParallelGroup()) par.add('comp1', SimpleImplicitComp1()) par.add('comp2', SimpleImplicitComp2()) top.root.ln_solver = lin_solver() top.root.nl_solver = Newton() top.root.nl_solver.options['maxiter'] = 5 top.root.add('px1', IndepVarComp('x', 1.0)) top.root.add('px2', IndepVarComp('x', 1.0)) # TODO: This is to get around a bug in checks. It should be fixed soon. par.ln_solver = lin_solver() top.root.connect('px1.x', 'par.comp1.x') top.root.connect('px2.x', 'par.comp2.x') top.setup(check=False) top['px1.x'] = 2.0 top['px2.x'] = 2.0 top.run() # Comp2 has a tighter lower bound. This test makes sure that we # allgathered and used the lowest alpha. if top.root.par.comp1.is_active(): self.assertEqual(top['par.comp1.z'], 1.5) if top.root.par.comp2.is_active(): self.assertEqual(top['par.comp2.z'], 1.5)
def _test_link(self): nn = 1 p2 = self.prob2 = Problem(model=Group()) p2.model.add_subsystem('evap', Radial_Stack(num_nodes=nn, n_in=0, n_out=1), promotes_inputs=['D_od', 't_wk', 't_w', 'k_wk', 'k_w', 'D_v', 'L_adiabatic', 'alpha']) # promote shared values (geometry, mat props) p2.model.add_subsystem('cond', Radial_Stack(num_nodes=nn, n_in=1, n_out=0), promotes_inputs=['D_od', 't_wk', 't_w', 'k_wk', 'k_w', 'D_v', 'L_adiabatic', 'alpha']) thermal_link(p2.model, 'evap', 'cond', num_nodes=nn) p2.model.set_input_defaults('k_w', 11.4) p2.setup(force_alloc_complex=True) Rexe = 0.0000001 Rexc = 0.0000001 # Rwe = 0.2545383947014702 # Rwke = 0.7943030881649811 # Rv = 8.852701208752846e-06 # Rintere = 0.00034794562965549745 # Rinterc = 0.00017397281482774872 # Rwkc = 0.39715154408249054 # Rwka = 744.3007160198263 # Rwa = 456.90414284754644 # Rwc = 0.1272691973507351 self.prob2['evap.Rex.R'] = Rexe # self.prob2['evap.Rw.R'] = Rwe # self.prob2['evap.Rwk.R'] = Rwke # self.prob2['evap.Rinter.R'] = Rintere # self.prob2['cond.Rinter.R'] = Rinterc # self.prob2['cond.Rwk.R'] = Rwkc # self.prob2['cond.Rw.R'] = Rwc self.prob2['cond.Rex.R'] = Rexc self.prob2['cond.L_flux'] = 0.02 self.prob2['evap.L_flux'] = 0.01 self.prob2['L_adiabatic'] = 0.03 # self.prob2['h_fg'] = # self.prob2['T_hp'] = # self.prob2['v_fg'] = # self.prob2['R_g'] = # self.prob2['P_v'] = # self.prob2['k_l'] = self.prob2['t_wk'] = 0.00069 self.prob2['t_w'] = 0.0005 self.prob2['D_od'] = 0.006 self.prob2['k_w'] = 11.4 self.prob2['epsilon'] = 0.46 self.prob2['D_v'] = 0.00362 self.prob2['L_eff'] = (self.prob2['cond.L_flux'] + self.prob2['evap.L_flux']) / 2. + self.prob2['L_adiabatic'] # self.prob2['k_wk'] = (1-self.prob2['epsilon'])*self.prob2['k_w']+self.prob2['epsilon']*self.prob2['k_l'] # Bridge # self.prob2['A_cond'] = np.pi*self.prob2['D_od']*self.prob2['L_cond'] # self.prob2['A_evap'] = np.pi*self.prob2['D_od']*self.prob2['L_evap'] # self.prob2['A_w'] = np.pi*((self.prob2['D_od']/2.)**2-(self.prob2['D_od']/2.-self.prob2['t_w'])**2) # self.prob2['A_wk'] = np.pi*((self.prob2['D_od']/2.-self.prob2['t_w'])**2-(self.prob2['D_v']/2.)**2) # self.prob2['A_inter'] = np.pi*self.prob2['D_v']*self.prob2['L_evap'] # self.prob2['evap_bridge.Rv.R'] = Rv # self.prob2['evap_bridge.Rwka.R'] = Rwka # self.prob2['evap_bridge.Rwa.R'] = Rwa self.prob2['evap.Rex.T_in'] = 100 self.prob2['cond.Rex.T_in'] = 20 p2.run_model() # p2.model.list_inputs(values=True, prom_name=True) # p2.model.list_outputs(values=True, prom_name=True) # n2(p2) # view_connections(p2) Rtot3 = (self.prob2.get_val('evap.n1.T') - self.prob2.get_val('cond.n1.T')) / np.abs( self.prob2.get_val('cond.Rex.q')) ans = 16731692103737332239244353077427184638278095509511778941. / 10680954190791611228174081719413008273307025000000000000. assert_near_equal(Rtot3, ans, tolerance=3.0E-5)