def test_solve_subsystems_assembled_jac_subgroup(self): prob = Problem(model=DoubleSellar()) model = prob.model g1 = model.g1 g1.nonlinear_solver = NewtonSolver() g1.nonlinear_solver.options['rtol'] = 1.0e-5 g1.linear_solver = DirectSolver() g1.jacobian = DenseJacobian() g2 = model.g2 g2.nonlinear_solver = NewtonSolver() g2.nonlinear_solver.options['rtol'] = 1.0e-5 g2.linear_solver = DirectSolver() model.nonlinear_solver = NewtonSolver() model.linear_solver = ScipyKrylov() prob.setup() prob.run_model() assert_rel_error(self, prob['g1.y1'], 0.64, .00001) assert_rel_error(self, prob['g1.y2'], 0.80, .00001) assert_rel_error(self, prob['g2.y1'], 0.64, .00001) assert_rel_error(self, prob['g2.y2'], 0.80, .00001)
def test_solve_subsystems_assembled_jac_top_implicit_scaling(self): prob = Problem() model = prob.model = DoubleSellarImplicit(scaling=True) model.jacobian = DenseJacobian() g1 = model.get_subsystem('g1') g1.nonlinear_solver = NewtonSolver() g1.nonlinear_solver.options['rtol'] = 1.0e-5 g1.linear_solver = DirectSolver() g2 = model.get_subsystem('g2') g2.nonlinear_solver = NewtonSolver() g2.nonlinear_solver.options['rtol'] = 1.0e-5 g2.linear_solver = DirectSolver() model.nonlinear_solver = NewtonSolver() model.linear_solver = ScipyIterativeSolver() model.nonlinear_solver.options['solve_subsystems'] = True prob.setup() prob.run_model() assert_rel_error(self, prob['g1.y1'], 0.64, .00001) assert_rel_error(self, prob['g1.y2'], 0.80, .00001) assert_rel_error(self, prob['g2.y1'], 0.64, .00001) assert_rel_error(self, prob['g2.y2'], 0.80, .00001)
def test_component_assembled_jac(self): prob = Problem() model = prob.model = Group() model.add_subsystem('px', IndepVarComp('x', 1.0), promotes=['x']) model.add_subsystem('pz', IndepVarComp('z', np.array([5.0, 2.0])), promotes=['z']) model.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2']) model.add_subsystem('d2', SellarDis2withDerivatives(), promotes=['z', 'y1', 'y2']) model.add_subsystem('obj_cmp', ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)', z=np.array([0.0, 0.0]), x=0.0), promotes=['obj', 'x', 'z', 'y1', 'y2']) model.add_subsystem('con_cmp1', ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1']) model.add_subsystem('con_cmp2', ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2']) model.nonlinear_solver = NewtonSolver() model.linear_solver = ScipyKrylov() d1 = prob.model.d1 d1.jacobian = DenseJacobian() prob.set_solver_print(level=0) prob.setup(check=False) prob.run_model() assert_rel_error(self, prob['y1'], 25.58830273, .00001) assert_rel_error(self, prob['y2'], 12.05848819, .00001)
def test_assembled_jacobian_submat_indexing_dense(self): prob = Problem() indeps = prob.model.add_subsystem('indeps', IndepVarComp()) indeps.add_output('x', 1.0) indeps.add_output('y', 5.0) indeps.add_output('z', 9.0) G1 = prob.model.add_subsystem('G1', Group()) G1.add_subsystem('C1', ExecComp('y=2.0*x*x')) G1.add_subsystem('C2', ExecComp('y=3.0*x*x')) prob.model.nonlinear_solver = NewtonSolver() G1.jacobian = DenseJacobian() G1.linear_solver = DirectSolver() # before the fix, we got bad offsets into the _ext_mtx matrix. # to get entries in _ext_mtx, there must be at least one connection # to an input in the system that owns the AssembledJacobian, from # a source that is outside of that system. In this case, the 'indeps' # system is outside of the 'G1' group which owns the AssembledJacobian. prob.model.connect('indeps.y', 'G1.C1.x') prob.model.connect('indeps.z', 'G1.C2.x') prob.setup(check=False) prob.run_model() assert_rel_error(self, prob['G1.C1.y'], 50.0) assert_rel_error(self, prob['G1.C2.y'], 243.0)
def test_basic_dense_jac(self): """Test that output values and total derivatives are correct.""" prob = Problem(model=UnitConvGroup()) prob.model.jacobian = DenseJacobian() prob.model.linear_solver = DirectSolver() # Check the outputs after running to test the unit conversions prob.setup(check=False, mode='fwd') prob.run_model() assert_rel_error(self, prob['src.x2'], 100.0, 1e-6) assert_rel_error(self, prob['tgtF.x3'], 212.0, 1e-6) assert_rel_error(self, prob['tgtC.x3'], 100.0, 1e-6) assert_rel_error(self, prob['tgtK.x3'], 373.15, 1e-6) # Check the total derivatives in forward mode wrt = ['px1.x1'] of = ['tgtF.x3', 'tgtC.x3', 'tgtK.x3'] J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') assert_rel_error(self, J['tgtF.x3', 'px1.x1'][0][0], 1.8, 1e-6) assert_rel_error(self, J['tgtC.x3', 'px1.x1'][0][0], 1.0, 1e-6) assert_rel_error(self, J['tgtK.x3', 'px1.x1'][0][0], 1.0, 1e-6) # Check the total derivatives in reverse mode prob.setup(check=False, mode='rev') prob.run_model() J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') assert_rel_error(self, J['tgtF.x3', 'px1.x1'][0][0], 1.8, 1e-6) assert_rel_error(self, J['tgtC.x3', 'px1.x1'][0][0], 1.0, 1e-6) assert_rel_error(self, J['tgtK.x3', 'px1.x1'][0][0], 1.0, 1e-6)
def test_solve_subsystems_assembled_jac_top_implicit_scaling_units(self): prob = Problem(model=DoubleSellarImplicit(units=True, scaling=True)) model = prob.model model.jacobian = DenseJacobian() g1 = model.g1 g1.nonlinear_solver = NewtonSolver() g1.nonlinear_solver.options['rtol'] = 1.0e-5 g1.linear_solver = DirectSolver() g2 = model.g2 g2.nonlinear_solver = NewtonSolver() g2.nonlinear_solver.options['rtol'] = 1.0e-5 g2.linear_solver = DirectSolver() model.nonlinear_solver = NewtonSolver() model.linear_solver = ScipyKrylov() model.nonlinear_solver.options['solve_subsystems'] = True prob.setup() prob.run_model() assert_rel_error(self, prob['g1.y1'], 0.053333333, .00001) assert_rel_error(self, prob['g1.y2'], 0.80, .00001) assert_rel_error(self, prob['g2.y1'], 0.053333333, .00001) assert_rel_error(self, prob['g2.y2'], 0.80, .00001)
def test_globaljac_err(self): prob = Problem() model = prob.model = Group() model.add_subsystem('x_param', IndepVarComp('length', 3.0), promotes=['length']) model.add_subsystem('mycomp', TestExplCompSimpleDense(), promotes=['length', 'width', 'area']) model.linear_solver = self.linear_solver_class() prob.set_solver_print(level=0) prob.model.jacobian = DenseJacobian() prob.setup(check=False, mode='fwd') prob['width'] = 2.0 prob.run_model() of = ['area'] wrt = ['length'] with self.assertRaises(RuntimeError) as context: prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') self.assertEqual( str(context.exception), "A block linear solver 'LN: LNBGS' is being used with" " an AssembledJacobian in system ''")
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_renamed_vars(self): n = 1 prob = Problem(model=Group()) bal = BalanceComp() bal.add_balance('x', use_mult=True, mult_name='MUL', lhs_name='XSQ', rhs_name='TARGETXSQ') tgt = IndepVarComp(name='y_tgt', val=4) mult_ivc = IndepVarComp(name='mult', val=2.0) exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1}) prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt']) prob.model.add_subsystem(name='mult_comp', subsys=mult_ivc, promotes_outputs=['mult']) prob.model.add_subsystem(name='exec', subsys=exec_comp) prob.model.add_subsystem(name='balance', subsys=bal) prob.model.connect('y_tgt', 'balance.TARGETXSQ') prob.model.connect('mult', 'balance.MUL') prob.model.connect('balance.x', 'exec.x') prob.model.connect('exec.y', 'balance.XSQ') prob.model.linear_solver = DirectSolver() prob.model.nonlinear_solver = NewtonSolver() prob.model.nonlinear_solver.options['maxiter'] = 100 prob.model.nonlinear_solver.options['iprint'] = 0 prob.model.jacobian = DenseJacobian() prob.setup() prob['balance.x'] = np.random.rand(n) prob.run_model() assert_almost_equal(prob['balance.x'], np.sqrt(2), decimal=7) with printoptions(linewidth=1024): cpd = prob.check_partials() for (of, wrt) in cpd['balance']: assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5)
def test_jacobian_changed_component(self): prob = Problem() model = prob.model = Group() model.add_subsystem('px', IndepVarComp('x', 1.0), promotes=['x']) model.add_subsystem('pz', IndepVarComp('z', np.array([5.0, 2.0])), promotes=['z']) model.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2']) model.add_subsystem('d2', SellarDis2withDerivatives(), promotes=['z', 'y1', 'y2']) model.add_subsystem('obj_cmp', ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)', z=np.array([0.0, 0.0]), x=0.0), promotes=['obj', 'x', 'z', 'y1', 'y2']) model.add_subsystem('con_cmp1', ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1']) model.add_subsystem('con_cmp2', ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2']) model.nonlinear_solver = NewtonSolver() model.linear_solver = ScipyKrylov() prob.setup(check=False) prob.final_setup() d1 = prob.model.d1 d1.jacobian = DenseJacobian() msg = "d1: jacobian has changed and setup was not called." with assertRaisesRegex(self, Exception, msg): prob.run_model()
def test_vectorized_with_mult(self): n = 100 prob = Problem(model=Group()) bal = BalanceComp() bal.add_balance('x', val=np.ones(n)) tgt = IndepVarComp(name='y_tgt', val=4 * np.ones(n)) mult_ivc = IndepVarComp(name='mult', val=2.0 * np.ones(n)) exec_comp = ExecComp('y=x**2', x={'value': np.ones(n)}, y={'value': np.ones(n)}) prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt']) prob.model.add_subsystem(name='mult_comp', subsys=mult_ivc, promotes_outputs=['mult']) prob.model.add_subsystem(name='exec', subsys=exec_comp) prob.model.add_subsystem(name='balance', subsys=bal) prob.model.connect('y_tgt', 'balance.rhs:x') prob.model.connect('mult', 'balance.mult:x') prob.model.connect('balance.x', 'exec.x') prob.model.connect('exec.y', 'balance.lhs:x') prob.model.linear_solver = DirectSolver() prob.model.nonlinear_solver = NewtonSolver() prob.model.nonlinear_solver.options['maxiter'] = 100 prob.model.nonlinear_solver.options['iprint'] = 0 prob.model.jacobian = DenseJacobian() prob.setup() prob['balance.x'] = np.random.rand(n) prob.run_model() assert_almost_equal(prob['balance.x'], np.sqrt(2), decimal=7) np.set_printoptions(linewidth=1024) cpd = prob.check_partials() for (of, wrt) in cpd['balance']: assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5)
def test_scalar_with_guess_func_additional_input(self): n = 1 prob = Problem(model=Group()) bal = BalanceComp() bal.add_balance('x', guess_func=lambda inputs, resids: inputs['guess_x']) bal.add_input('guess_x', val=0.0) ivc = IndepVarComp() ivc.add_output(name='y_tgt', val=4) ivc.add_output(name='guess_x', val=2.5) exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1}) prob.model.add_subsystem(name='ivc', subsys=ivc, promotes_outputs=['y_tgt', 'guess_x']) prob.model.add_subsystem(name='exec', subsys=exec_comp) prob.model.add_subsystem(name='balance', subsys=bal) prob.model.connect('guess_x', 'balance.guess_x') prob.model.connect('y_tgt', 'balance.rhs:x') prob.model.connect('balance.x', 'exec.x') prob.model.connect('exec.y', 'balance.lhs:x') prob.model.linear_solver = DirectSolver() prob.model.nonlinear_solver = NewtonSolver() prob.model.nonlinear_solver.options['maxiter'] = 100 prob.model.nonlinear_solver.options['iprint'] = 0 prob.model.jacobian = DenseJacobian() prob.setup() prob['balance.x'] = np.random.rand(n) prob.run_model() assert_almost_equal(prob['balance.x'], 2.0, decimal=7) with printoptions(linewidth=1024): cpd = prob.check_partials() for (of, wrt) in cpd['balance']: assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5)
def test_newton_resid_scaling(self): class SimpleComp(ImplicitComponent): def setup(self): self.add_input('x', val=6.0) self.add_output('y', val=1.0, ref=100.0, res_ref=10.1) self.declare_partials('*', '*') def apply_nonlinear(self, inputs, outputs, residuals): residuals['y'] = 3.0*outputs['y'] - inputs['x'] def linearize(self, inputs, outputs, jacobian): jacobian['y', 'x'] = -1.0 jacobian['y', 'y'] = 3.0 prob = Problem() model = prob.model = Group() model.add_subsystem('p1', IndepVarComp('x', 6.0)) model.add_subsystem('comp', SimpleComp()) model.connect('p1.x', 'comp.x') model.nonlinear_solver = NewtonSolver() model.linear_solver = DirectSolver() prob.setup(check=False) prob.run_model() assert_rel_error(self, prob['comp.y'], 2.0) # Now, let's try with an AssembledJacobian. prob = Problem() model = prob.model = Group() model.add_subsystem('p1', IndepVarComp('x', 6.0)) model.add_subsystem('comp', SimpleComp()) model.connect('p1.x', 'comp.x') model.nonlinear_solver = NewtonSolver() model.linear_solver = DirectSolver() model.jacobian = DenseJacobian() prob.setup(check=False) prob.run_model() assert_rel_error(self, prob['comp.y'], 2.0)
def test_feature_scalar(self): from numpy.testing import assert_almost_equal from openmdao.api import Problem, Group, IndepVarComp, ExecComp, NewtonSolver, DirectSolver, DenseJacobian, BalanceComp n = 1 prob = Problem(model=Group()) bal = BalanceComp() bal.add_balance('x') tgt = IndepVarComp(name='y_tgt', val=4) mult_ivc = IndepVarComp(name='mult', val=2.0) exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1}) prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt']) prob.model.add_subsystem(name='mult_comp', subsys=mult_ivc, promotes_outputs=['mult']) prob.model.add_subsystem(name='exec', subsys=exec_comp) prob.model.add_subsystem(name='balance', subsys=bal) prob.model.connect('y_tgt', 'balance.rhs:x') prob.model.connect('mult', 'balance.mult:x') prob.model.connect('balance.x', 'exec.x') prob.model.connect('exec.y', 'balance.lhs:x') prob.model.linear_solver = DirectSolver() prob.model.nonlinear_solver = NewtonSolver() prob.model.nonlinear_solver.options['maxiter'] = 100 prob.model.nonlinear_solver.options['iprint'] = 0 prob.model.jacobian = DenseJacobian() prob.setup(check=False) # A reasonable initial guess to find the positive root. prob['balance.x'] = 1.0 prob.run_model() print('x = ', prob['balance.x']) assert_almost_equal(prob['balance.x'], np.sqrt(2), decimal=7)
def test_newton_with_densejac_under_full_model_fd(self): # Basic sellar test. prob = Problem() model = prob.model = Group() sub = model.add_subsystem('sub', Group(), promotes=['*']) model.add_subsystem('px', IndepVarComp('x', 1.0), promotes=['x']) model.add_subsystem('pz', IndepVarComp('z', np.array([5.0, 2.0])), promotes=['z']) sub.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2']) sub.add_subsystem('d2', SellarDis2withDerivatives(), promotes=['z', 'y1', 'y2']) model.add_subsystem('obj_cmp', ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)', z=np.array([0.0, 0.0]), x=0.0), promotes=['obj', 'x', 'z', 'y1', 'y2']) model.add_subsystem('con_cmp1', ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1']) model.add_subsystem('con_cmp2', ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2']) sub.nonlinear_solver = NewtonSolver() sub.linear_solver = ScipyKrylov() model.jacobian = DenseJacobian() model.approx_totals(method='fd', step=1e-5) prob.setup(check=False) prob.set_solver_print(level=0) prob.run_model() assert_rel_error(self, prob['y1'], 25.58830273, .00001) assert_rel_error(self, prob['y2'], 12.05848819, .00001) wrt = ['z'] of = ['obj'] J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') assert_rel_error(self, J['obj', 'z'][0][0], 9.61001056, .00001) assert_rel_error(self, J['obj', 'z'][0][1], 1.78448534, .00001)
def test_feature_vector(self): import numpy as np from numpy.testing import assert_almost_equal from openmdao.api import Problem, Group, ExecComp, NewtonSolver, DirectSolver, \ DenseJacobian, BalanceComp n = 100 prob = Problem(model=Group()) exec_comp = ExecComp('y=b*x+c', b={'value': np.random.uniform(0.01, 100, size=n)}, c={'value': np.random.rand(n)}, x={'value': np.zeros(n)}, y={'value': np.ones(n)}) prob.model.add_subsystem(name='exec', subsys=exec_comp) prob.model.add_subsystem(name='balance', subsys=BalanceComp('x', val=np.ones(n))) prob.model.connect('balance.x', 'exec.x') prob.model.connect('exec.y', 'balance.lhs:x') prob.model.linear_solver = DirectSolver() prob.model.nonlinear_solver = NewtonSolver() prob.model.nonlinear_solver.options['maxiter'] = 100 prob.model.nonlinear_solver.options['iprint'] = 0 prob.model.jacobian = DenseJacobian() prob.setup(check=False) prob['balance.x'] = np.random.rand(n) prob.run_model() b = prob['exec.b'] c = prob['exec.c'] assert_almost_equal(prob['balance.x'], -c / b, decimal=6) print('solution') print(prob['balance.x']) print('expected') print(-c / b)
def test_raise_error_on_singular_with_densejac(self): prob = Problem() prob.model = model = Group() comp = IndepVarComp() comp.add_output('dXdt:TAS', val=1.0) comp.add_output('accel_target', val=2.0) model.add_subsystem('des_vars', comp, promotes=['*']) teg = model.add_subsystem('thrust_equilibrium_group', subsys=Group()) teg.add_subsystem('dynamics', ExecComp('z = 2.0*thrust'), promotes=['*']) thrust_bal = BalanceComp() thrust_bal.add_balance(name='thrust', val=1207.1, lhs_name='dXdt:TAS', rhs_name='accel_target', eq_units='m/s**2', lower=-10.0, upper=10000.0) teg.add_subsystem(name='thrust_bal', subsys=thrust_bal, promotes_inputs=['dXdt:TAS', 'accel_target'], promotes_outputs=['thrust']) teg.linear_solver = DirectSolver() teg.jacobian = DenseJacobian() teg.nonlinear_solver = NewtonSolver() teg.nonlinear_solver.options['solve_subsystems'] = True teg.nonlinear_solver.options['max_sub_solves'] = 1 teg.nonlinear_solver.options['atol'] = 1e-4 prob.setup(check=False) prob.set_solver_print(level=0) with self.assertRaises(RuntimeError) as cm: prob.run_model() expected_msg = "Singular entry found in 'thrust_equilibrium_group' for row associated with state/residual 'thrust'." self.assertEqual(expected_msg, str(cm.exception))
def test_error_under_assembled_jac(self): prob = Problem() model = prob.model model.add_subsystem('p', IndepVarComp('a', 5.0)) comp = model.add_subsystem('comp', SimpleImp()) model.connect('p.a', 'comp.a') comp.linear_solver = self.linear_solver_class() comp.jacobian = DenseJacobian() prob.setup(check=False, mode='fwd') with self.assertRaises(RuntimeError) as context: prob.compute_totals(of=['comp.x'], wrt=['p.a']) self.assertEqual( str(context.exception), "A block linear solver 'LN: LNBGS' is being used with" " an AssembledJacobian in system 'comp'")
def test_rhs_val(self): """ Test solution with a default RHS value and no connected RHS variable. """ n = 1 prob = Problem(model=Group()) bal = BalanceComp('x', rhs_val=4.0) exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1}) prob.model.add_subsystem(name='exec', subsys=exec_comp) prob.model.add_subsystem(name='balance', subsys=bal) prob.model.connect('balance.x', 'exec.x') prob.model.connect('exec.y', 'balance.lhs:x') prob.model.linear_solver = DirectSolver() prob.model.nonlinear_solver = NewtonSolver() prob.model.nonlinear_solver.options['maxiter'] = 100 prob.model.nonlinear_solver.options['iprint'] = 0 prob.model.jacobian = DenseJacobian() prob.setup() prob['balance.x'] = np.random.rand(n) prob.run_model() assert_almost_equal(prob['balance.x'], 2.0, decimal=7) with printoptions(linewidth=1024): cpd = prob.check_partials() for (of, wrt) in cpd['balance']: assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5)
def test_assembled_jac_bad_key(self): # this test fails if AssembledJacobian._update sets in_start with 'output' instead of 'input' prob = Problem() prob.model = Group() prob.model.add_subsystem('indep', IndepVarComp('x', 1.0)) prob.model.add_subsystem('C1', ExecComp('c=a*2.0+b')) c2 = prob.model.add_subsystem('C2', ExecComp('d=a*2.0+b+c')) c3 = prob.model.add_subsystem('C3', ExecComp('ee=a*2.0')) prob.model.nonlinear_solver = NewtonSolver() c3.jacobian = DenseJacobian() prob.model.connect('indep.x', 'C1.a') prob.model.connect('indep.x', 'C2.a') prob.model.connect('C1.c', 'C2.b') prob.model.connect('C2.d', 'C3.a') prob.set_solver_print(level=0) prob.setup(check=False) prob.run_model() assert_rel_error(self, prob['C3.ee'], 8.0, 0000.1)
def test_one_src_2_tgts_with_src_indices_densejac(self): size = 4 prob = Problem() indeps = prob.model.add_subsystem('indeps', IndepVarComp('x', np.ones(size))) G1 = prob.model.add_subsystem('G1', Group()) G1.add_subsystem('C1', ExecComp('z=2.0*y+3.0*x', x=np.zeros(size//2), y=np.zeros(size//2), z=np.zeros(size//2))) prob.model.jacobian = DenseJacobian() prob.model.linear_solver = DirectSolver() prob.model.add_objective('G1.C1.z') prob.model.add_design_var('indeps.x') prob.model.connect('indeps.x', 'G1.C1.x', src_indices=[0,1]) prob.model.connect('indeps.x', 'G1.C1.y', src_indices=[2,3]) prob.setup(check=False) prob.run_model() J = prob.compute_totals(of=['G1.C1.z'], wrt=['indeps.x']) assert_rel_error(self, J['G1.C1.z', 'indeps.x'], np.array([[ 3., 0., 2., 0.], [-0., 3., 0., 2.]]), .0001)
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() 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') model.jacobian = DenseJacobian() prob.setup() msg = "AssembledJacobian not supported if any subcomponent is matrix-free." with assertRaisesRegex(self, Exception, msg): prob.run_model() # Nested prob = Problem() model = prob.model = Group() 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') model.jacobian = DenseJacobian() prob.setup() msg = "AssembledJacobian not supported if any subcomponent is matrix-free." 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() 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') model.jacobian = DenseJacobian() prob.setup() msg = "AssembledJacobian not supported if any subcomponent is matrix-free." with assertRaisesRegex(self, Exception, msg): prob.run_model() # Make sure regular comps don't give an error. prob = Problem() model = prob.model = Group() 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') model.jacobian = DenseJacobian() 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() 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') model.jacobian = DenseJacobian() prob.setup() msg = "AssembledJacobian not supported if any subcomponent is matrix-free." with assertRaisesRegex(self, Exception, msg): prob.run_model()
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 = Group() 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.jacobian = DenseJacobian() sub1.linear_solver = DirectSolver() sub2.jacobian = DenseJacobian() sub2.linear_solver = DirectSolver() 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_sellar_state_connection_densejac(self): # Test derivatives across a converged Sellar model. prob = Problem() prob.model = SellarStateConnection(linear_solver=self.linear_solver_class(), nl_atol=1e-12) prob.set_solver_print(level=0) prob.setup(check=False, mode='fwd') prob.model.sub.d1.jacobian = DenseJacobian() prob.model.sub.d2.jacobian = DenseJacobian() prob.model.sub.state_eq_group.state_eq.jacobian = DenseJacobian() prob.model.obj_cmp.jacobian = DenseJacobian() prob.model.con_cmp1.jacobian = DenseJacobian() prob.model.con_cmp2.jacobian = DenseJacobian() prob.run_model() # Just make sure we are at the right answer assert_rel_error(self, prob['y1'], 25.58830273, .00001) assert_rel_error(self, prob['d2.y2'], 12.05848819, .00001) wrt = ['x', 'z'] of = ['obj', 'con1', 'con2'] Jbase = {} Jbase['con1', 'x'] = [[-0.98061433]] Jbase['con1', 'z'] = np.array([[-9.61002285, -0.78449158]]) Jbase['con2', 'x'] = [[0.09692762]] Jbase['con2', 'z'] = np.array([[1.94989079, 1.0775421]]) Jbase['obj', 'x'] = [[2.98061392]] Jbase['obj', 'z'] = np.array([[9.61001155, 1.78448534]]) J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') for key, val in iteritems(Jbase): assert_rel_error(self, J[key], val, .00001) prob = Problem() prob.model = SellarStateConnection(linear_solver=self.linear_solver_class(), nl_atol=1e-12) prob.set_solver_print(level=0) prob.setup(check=False, mode='rev') prob.model.sub.d1.jacobian = DenseJacobian() prob.model.sub.d2.jacobian = DenseJacobian() prob.model.sub.state_eq_group.state_eq.jacobian = DenseJacobian() prob.model.obj_cmp.jacobian = DenseJacobian() prob.model.con_cmp1.jacobian = DenseJacobian() prob.model.con_cmp2.jacobian = DenseJacobian() prob.run_model() J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') for key, val in iteritems(Jbase): assert_rel_error(self, J[key], val, .00001)