def test_fd_partials(self): mat = np.arange(30, dtype=float).reshape(5, 6) p = Problem() model = p.model model.add_subsystem('indep', IndepVarComp('x', val=np.ones(mat.shape[1]))) comp = model.add_subsystem('comp', MatMultComp(mat, approx_method='fd', num_par_fd=3)) model.connect('indep.x', 'comp.x') p.setup(mode='fwd') p.run_model() pre_count = comp.num_computes # calling compute_totals will result in the computation of partials for comp p.compute_totals(of=['comp.y'], wrt=['indep.x']) # get the partial jacobian matrix J = comp._jacobian['y', 'x'] post_count = comp.num_computes # how many computes were used in this proc to compute the partial jacobian? # Each proc should be doing 2 computes. jac_count = post_count - pre_count self.assertEqual(jac_count, 2) # J and mat should be the same self.assertLess(np.linalg.norm(J - mat), 1.e-7)
def test_basic_implicit_conn(self): """Test units with all implicit connections.""" prob = Problem(model=Group()) prob.model.add_subsystem('px1', IndepVarComp('x1', 100.0), promotes_outputs=['x1']) prob.model.add_subsystem('src', SrcComp(), promotes_inputs=['x1'], promotes_outputs=['x2']) prob.model.add_subsystem('tgtF', TgtCompF(), promotes_inputs=['x2']) prob.model.add_subsystem('tgtC', TgtCompC(), promotes_inputs=['x2']) prob.model.add_subsystem('tgtK', TgtCompK(), promotes_inputs=['x2']) # Check the outputs after running to test the unit conversions prob.setup(check=False) prob.run_model() assert_rel_error(self, prob['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 = ['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', 'x1'][0][0], 1.8, 1e-6) assert_rel_error(self, J['tgtC.x3', 'x1'][0][0], 1.0, 1e-6) assert_rel_error(self, J['tgtK.x3', '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', 'x1'][0][0], 1.8, 1e-6) assert_rel_error(self, J['tgtC.x3', 'x1'][0][0], 1.0, 1e-6) assert_rel_error(self, J['tgtK.x3', 'x1'][0][0], 1.0, 1e-6)
def test_converge_diverge(self): prob = Problem() prob.model = ConvergeDiverge() prob.setup(vector_class=PETScVector, check=False, mode='fwd') prob.set_solver_print(level=0) prob.run_model() assert_rel_error(self, prob['c7.y1'], -102.7, 1e-6) indep_list = ['iv.x'] unknown_list = ['c7.y1'] J = prob.compute_totals(of=unknown_list, wrt=indep_list) assert_rel_error(self, J['c7.y1', 'iv.x'][0][0], -40.75, 1e-6) prob.setup(vector_class=PETScVector, check=False, mode='rev') prob.run_model() assert_rel_error(self, prob['c7.y1'], -102.7, 1e-6) J = prob.compute_totals(of=unknown_list, wrt=indep_list) assert_rel_error(self, J['c7.y1', 'iv.x'][0][0], -40.75, 1e-6) assert_rel_error(self, prob['c7.y1'], -102.7, 1e-6)
def test_diamond(self): prob = Problem() prob.model = Diamond() prob.setup(vector_class=PETScVector, check=False, mode='fwd') prob.set_solver_print(level=0) prob.run_model() assert_rel_error(self, prob['c4.y1'], 46.0, 1e-6) assert_rel_error(self, prob['c4.y2'], -93.0, 1e-6) indep_list = ['iv.x'] unknown_list = ['c4.y1', 'c4.y2'] J = prob.compute_totals(of=unknown_list, wrt=indep_list) assert_rel_error(self, J['c4.y1', 'iv.x'][0][0], 25, 1e-6) assert_rel_error(self, J['c4.y2', 'iv.x'][0][0], -40.5, 1e-6) prob.setup(vector_class=PETScVector, check=False, mode='rev') prob.run_model() assert_rel_error(self, prob['c4.y1'], 46.0, 1e-6) assert_rel_error(self, prob['c4.y2'], -93.0, 1e-6) J = prob.compute_totals(of=unknown_list, wrt=indep_list) assert_rel_error(self, J['c4.y1', 'iv.x'][0][0], 25, 1e-6) assert_rel_error(self, J['c4.y2', 'iv.x'][0][0], -40.5, 1e-6)
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_fan_in_grouped(self): prob = Problem() prob.model = FanInGrouped2() prob.setup(vector_class=PETScVector, check=False, mode='fwd') prob.set_solver_print(level=0) prob.run_model() indep_list = ['p1.x', 'p2.x'] unknown_list = ['c3.y'] assert_rel_error(self, prob['c3.y'], 29.0, 1e-6) J = prob.compute_totals(of=unknown_list, wrt=indep_list) assert_rel_error(self, J['c3.y', 'p1.x'][0][0], -6.0, 1e-6) assert_rel_error(self, J['c3.y', 'p2.x'][0][0], 35.0, 1e-6) assert_rel_error(self, prob['c3.y'], 29.0, 1e-6) prob.setup(vector_class=PETScVector, check=False, mode='rev') prob.run_model() assert_rel_error(self, prob['c3.y'], 29.0, 1e-6) J = prob.compute_totals(of=unknown_list, wrt=indep_list) assert_rel_error(self, J['c3.y', 'p1.x'][0][0], -6.0, 1e-6) assert_rel_error(self, J['c3.y', 'p2.x'][0][0], 35.0, 1e-6) assert_rel_error(self, prob['c3.y'], 29.0, 1e-6)
def test_fan_out_grouped(self): prob = Problem(FanOutGrouped()) of=['c2.y', "c3.y"] wrt=['iv.x'] prob.setup(vector_class=PETScVector, check=False, mode='fwd') prob.set_solver_print(level=0) prob.run_model() J = prob.compute_totals(of=['c2.y', "c3.y"], wrt=['iv.x']) assert_rel_error(self, J['c2.y', 'iv.x'][0][0], -6.0, 1e-6) assert_rel_error(self, J['c3.y', 'iv.x'][0][0], 15.0, 1e-6) assert_rel_error(self, prob['c2.y'], -6.0, 1e-6) assert_rel_error(self, prob['c3.y'], 15.0, 1e-6) prob.setup(vector_class=PETScVector, check=False, mode='rev') prob.run_model() J = prob.compute_totals(of=['c2.y', "c3.y"], wrt=['iv.x']) assert_rel_error(self, J['c2.y', 'iv.x'][0][0], -6.0, 1e-6) assert_rel_error(self, J['c3.y', 'iv.x'][0][0], 15.0, 1e-6) assert_rel_error(self, prob['c2.y'], -6.0, 1e-6) assert_rel_error(self, prob['c3.y'], 15.0, 1e-6)
def ttest_reconf_comp(self): p = Problem() p.model = Group() p.model.add_subsystem('c1', IndepVarComp('x', 1.0), promotes_outputs=['x']) p.model.add_subsystem('c2', ReconfComp(), promotes_inputs=['x'], promotes_outputs=['y']) p.model.add_subsystem('c3', Comp(), promotes_inputs=['x'], promotes_outputs=['z']) p.setup() p['x'] = 3. # First run the model once; counter = 1, size of y = 1 p.run_model() totals = p.compute_totals(wrt=['x'], of=['y']) assert_rel_error(self, p['x'], 3.0) assert_rel_error(self, p['y'], 6.0) assert_rel_error(self, p['z'], 9.0) assert_rel_error(self, totals['y', 'x'], 2.0) print(p['x'], p['y'], p['z'], totals['y', 'x'].flatten()) # Run the model again, which will trigger reconfiguration; counter = 2, size of y = 2 p.run_model() totals = p.compute_totals(wrt=['x'], of=['y']) assert_rel_error(self, p['x'], 3.0) assert_rel_error(self, p['y'], 6.0 * np.ones(2)) assert_rel_error(self, p['z'], 9.0) assert_rel_error(self, totals['y', 'x'], 2.0 * np.ones(2, 1))
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 = LinearBlockJac() prob.set_solver_print(level=0) prob.model.jacobian = AssembledJacobian() 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: LNBJ' is being used with" " an AssembledJacobian in system ''")
def test_error_on_singular_with_densejac_bug(self): prob = Problem(model=Group()) model = prob.model model.add_subsystem('p', IndepVarComp('x', 2.0*np.ones((2, 2)))) model.add_subsystem('c1', ExecComp('y = 4.0*x', x=np.zeros((2, 2)), y=np.zeros((2, 2)))) model.add_subsystem('c2', ExecComp('y = 4.0*x', x=np.zeros((2, 2)), y=np.zeros((2, 2)))) model.add_subsystem('c3', ExecComp('y = 3.0*x', x=np.zeros((2, 2)), y=np.zeros((2, 2)))) model.add_subsystem('c4', ExecComp('y = 2.0*x', x=np.zeros((2, 2)), y=np.zeros((2, 2)))) model.add_subsystem('c5', SingularComp()) model.connect('p.x', 'c1.x') model.connect('c1.y', 'c2.x') model.connect('c2.y', 'c3.x') model.connect('c3.y', 'c4.x') model.connect('c4.y', 'c5.x', src_indices=([0])) model.linear_solver = DirectSolver(assemble_jac=True) model.options['assembled_jac_type'] = 'dense' prob.setup() prob.run_model() with self.assertRaises(RuntimeError) as cm: prob.compute_totals(of=['c5.y'], wrt=['p.x']) expected_msg = "Singular entry found in '' for column associated with state/residual 'c5.y'." self.assertEqual(expected_msg, str(cm.exception))
def test_converge_diverge_groups(self): # Test derivatives for converge-diverge-groups topology. prob = Problem() model = prob.model = ConvergeDivergeGroups() model.linear_solver = LinearRunOnce() model.g1.linear_solver = LinearRunOnce() model.g1.g2.linear_solver = LinearRunOnce() model.g3.linear_solver = LinearRunOnce() prob.set_solver_print(level=0) prob.setup(check=False, mode='fwd') prob.run_model() wrt = ['iv.x'] of = ['c7.y1'] # Make sure value is fine. assert_rel_error(self, prob['c7.y1'], -102.7, 1e-6) J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') assert_rel_error(self, J['c7.y1', 'iv.x'][0][0], -40.75, 1e-6) 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['c7.y1', 'iv.x'][0][0], -40.75, 1e-6)
def test_simple_matvec(self): # Tests derivatives on a simple comp that defines compute_jacvec. # Note, For DirectSolver, assemble_jac must be False for mat-vec. prob = Problem() model = prob.model = Group() model.add_subsystem('x_param', IndepVarComp('length', 3.0), promotes=['length']) model.add_subsystem('mycomp', TestExplCompSimpleJacVec(), promotes=['length', 'width', 'area']) model.linear_solver = self.linear_solver_class() prob.set_solver_print(level=0) prob.setup(check=False, mode='fwd') # Note, For DirectSolver, assemble_jac must be False for mat-vec. if isinstance(model.linear_solver, DirectSolver): model.linear_solver.options['assemble_jac'] = False prob['width'] = 2.0 prob.run_model() of = ['area'] wrt = ['length'] J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') assert_rel_error(self, J['area', 'length'], [[2.0]], 1e-6) prob.setup(check=False, mode='rev') prob['width'] = 2.0 prob.run_model() J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') assert_rel_error(self, J['area', 'length'], [[2.0]], 1e-6)
def test_sellar_state_connection(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.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.setup(check=False, mode='rev') 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)
def test_error_on_NaN_bug(self): prob = Problem() model = prob.model model.add_subsystem('p', IndepVarComp('x', 2.0*np.ones((2, 2)))) model.add_subsystem('c1', ExecComp('y = 4.0*x', x=np.zeros((2, 2)), y=np.zeros((2, 2)))) model.add_subsystem('c2', ExecComp('y = 4.0*x', x=np.zeros((2, 2)), y=np.zeros((2, 2)))) model.add_subsystem('c3', ExecComp('y = 3.0*x', x=np.zeros((2, 2)), y=np.zeros((2, 2)))) model.add_subsystem('c4', ExecComp('y = 2.0*x', x=np.zeros((2, 2)), y=np.zeros((2, 2)))) model.add_subsystem('c5', NanComp()) model.connect('p.x', 'c1.x') model.connect('c1.y', 'c2.x') model.connect('c2.y', 'c3.x') model.connect('c3.y', 'c4.x') model.connect('c4.y', 'c5.x', src_indices=([0])) model.linear_solver = DirectSolver(assemble_jac=True) prob.setup() prob.run_model() with self.assertRaises(RuntimeError) as cm: prob.compute_totals(of=['c5.y'], wrt=['p.x']) expected_msg = "NaN entries found in '' for rows associated with states/residuals ['c5.y']." self.assertEqual(expected_msg, str(cm.exception))
def test_raise_error_on_nan_dense(self): prob = Problem(model=Group(assembled_jac_type='dense')) model = prob.model model.add_subsystem('p', IndepVarComp('x', 2.0)) model.add_subsystem('c1', ExecComp('y = 4.0*x')) sub = model.add_subsystem('sub', Group()) sub.add_subsystem('c2', NanComp()) model.add_subsystem('c3', ExecComp('y = 4.0*x')) model.add_subsystem('c4', NanComp2()) model.add_subsystem('c5', ExecComp('y = 3.0*x')) model.add_subsystem('c6', ExecComp('y = 2.0*x')) model.connect('p.x', 'c1.x') model.connect('c1.y', 'sub.c2.x') model.connect('sub.c2.y', 'c3.x') model.connect('c3.y', 'c4.x') model.connect('c4.y', 'c5.x') model.connect('c4.y2', 'c6.x') model.linear_solver = DirectSolver(assemble_jac=True) prob.setup() prob.run_model() with self.assertRaises(RuntimeError) as cm: prob.compute_totals(of=['c5.y'], wrt=['p.x']) expected_msg = "NaN entries found in '' for rows associated with states/residuals ['sub.c2.y', 'c4.y']." self.assertEqual(expected_msg, str(cm.exception))
def test_two_simple(self): size = 3 group = Group() # import pydevd # pydevd.settrace('localhost', port=10000+MPI.COMM_WORLD.rank, # stdoutToServer=True, stderrToServer=True) group.add_subsystem('P', IndepVarComp('x', numpy.arange(size))) group.add_subsystem('C1', DistribExecComp(['y=2.0*x', 'y=3.0*x'], arr_size=size, x=numpy.zeros(size), y=numpy.zeros(size))) group.add_subsystem('C2', ExecComp(['z=3.0*y'], y=numpy.zeros(size), z=numpy.zeros(size))) prob = Problem() prob.model = group prob.model.linear_solver = LinearBlockGS() prob.model.connect('P.x', 'C1.x') prob.model.connect('C1.y', 'C2.y') prob.setup(check=False, mode='fwd') prob.run_model() J = prob.compute_totals(['C2.z'], ['P.x']) assert_rel_error(self, J['C2.z', 'P.x'], numpy.diag([6.0, 6.0, 9.0]), 1e-6) prob.setup(check=False, mode='rev') prob.run_model() J = prob.compute_totals(['C2.z'], ['P.x']) assert_rel_error(self, J['C2.z', 'P.x'], numpy.diag([6.0, 6.0, 9.0]), 1e-6)
def test(self): p = Problem() p.model = Group() p.model.add_subsystem('c1', IndepVarComp('x', 1.0), promotes_outputs=['x']) p.model.add_subsystem('c2', ReconfComp(), promotes_inputs=['x'], promotes_outputs=['y']) p.model.add_subsystem('c3', Comp(), promotes_inputs=['x'], promotes_outputs=['z']) # First run the usual setup method on Problem; size of y = 1 p.setup() p['x'] = 2 p.run_model() totals = p.compute_totals(wrt=['x'], of=['y']) assert_rel_error(self, p['x'], 2.0) assert_rel_error(self, p['y'], 4.0) assert_rel_error(self, p['z'], 6.0) assert_rel_error(self, totals['y', 'x'], [[2.0]]) # Now run the setup method on the root system; size of y = 2 p.model.resetup() p['x'] = 3 p.run_model() totals = p.compute_totals(wrt=['x'], of=['y']) assert_rel_error(self, p['x'], 3.0) assert_rel_error(self, p['y'], 6.0 * np.ones(2)) assert_rel_error(self, p['z'], 9.0) assert_rel_error(self, totals['y', 'x'], 2.0 * np.ones((2, 1))) # Now reconfigure from c2 and update in root; size of y = 3; the value of x is preserved p.model.c2.resetup('reconf') p.model.resetup('update') p.run_model() totals = p.compute_totals(wrt=['x'], of=['y']) assert_rel_error(self, p['x'], 3.0) assert_rel_error(self, p['y'], 6.0 * np.ones(3)) assert_rel_error(self, p['z'], 9.0) assert_rel_error(self, totals['y', 'x'], 2.0 * np.ones((3, 1))) # Now reconfigure from c3 and update in root; size of y = 3; the value of x is preserved p.model.c3.resetup('reconf') p.model.resetup('update') p.run_model() totals = p.compute_totals(wrt=['x'], of=['y']) assert_rel_error(self, p['x'], 3.0) assert_rel_error(self, p['y'], 6.0 * np.ones(3)) assert_rel_error(self, p['z'], 9.0) assert_rel_error(self, totals['y', 'x'], 2.0 * np.ones((3, 1))) # Finally, setup reconf from root; size of y = 4 # Since we are at the root, calling setup('full') and setup('reconf') have the same effect. # In both cases, variable values are lost so we have to set x=3 again. p.model.resetup('reconf') p['x'] = 3 p.run_model() totals = p.compute_totals(wrt=['x'], of=['y']) assert_rel_error(self, p['x'], 3.0) assert_rel_error(self, p['y'], 6.0 * np.ones(4)) assert_rel_error(self, p['z'], 9.0) assert_rel_error(self, totals['y', 'x'], 2.0 * np.ones((4, 1)))
def test_basic_fd_comps(self): prob = Problem() prob.model = Group() prob.model.add_subsystem('px1', IndepVarComp('x1', 100.0), promotes=['x1']) prob.model.add_subsystem('src', SrcCompFD()) prob.model.add_subsystem('tgtF', TgtCompFFD()) prob.model.add_subsystem('tgtC', TgtCompCFD()) prob.model.add_subsystem('tgtK', TgtCompKFD()) prob.model.connect('x1', 'src.x1') prob.model.connect('src.x2', 'tgtF.x2') prob.model.connect('src.x2', 'tgtC.x2') prob.model.connect('src.x2', 'tgtK.x2') prob.setup(check=False) 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) indep_list = ['x1'] unknown_list = ['tgtF.x3', 'tgtC.x3', 'tgtK.x3'] J = prob.compute_totals(of=unknown_list, wrt=indep_list, return_format='dict') assert_rel_error(self, J['tgtF.x3']['x1'][0][0], 1.8, 1e-6) assert_rel_error(self, J['tgtC.x3']['x1'][0][0], 1.0, 1e-6) assert_rel_error(self, J['tgtK.x3']['x1'][0][0], 1.0, 1e-6) prob.setup(check=False, mode='rev') prob.run_model() J = prob.compute_totals(of=unknown_list, wrt=indep_list, return_format='dict') assert_rel_error(self, J['tgtF.x3']['x1'][0][0], 1.8, 1e-6) assert_rel_error(self, J['tgtC.x3']['x1'][0][0], 1.0, 1e-6) assert_rel_error(self, J['tgtK.x3']['x1'][0][0], 1.0, 1e-6) prob.model.approx_totals(method='fd') prob.setup(check=False, mode='rev') prob.run_model() J = prob.compute_totals(of=unknown_list, wrt=indep_list, return_format='dict') assert_rel_error(self, J['tgtF.x3']['x1'][0][0], 1.8, 1e-6) assert_rel_error(self, J['tgtC.x3']['x1'][0][0], 1.0, 1e-6) assert_rel_error(self, J['tgtK.x3']['x1'][0][0], 1.0, 1e-6) # Make sure check partials handles conversion data = prob.check_partials() for key1, val1 in iteritems(data): for key2, val2 in iteritems(val1): assert_rel_error(self, val2['abs error'][0], 0.0, 1e-6) assert_rel_error(self, val2['abs error'][1], 0.0, 1e-6) assert_rel_error(self, val2['abs error'][2], 0.0, 1e-6) assert_rel_error(self, val2['rel error'][0], 0.0, 1e-6) assert_rel_error(self, val2['rel error'][1], 0.0, 1e-6) assert_rel_error(self, val2['rel error'][2], 0.0, 1e-6)
def test_fan_in_grouped(self): size = 3 prob = Problem() prob.model = root = Group() root.add_subsystem('P1', IndepVarComp('x', numpy.ones(size, dtype=float))) root.add_subsystem('P2', IndepVarComp('x', numpy.ones(size, dtype=float))) sub = root.add_subsystem('sub', ParallelGroup()) sub.add_subsystem('C1', ExecComp(['y=-2.0*x'], x=numpy.zeros(size, dtype=float), y=numpy.zeros(size, dtype=float))) sub.add_subsystem('C2', ExecComp(['y=5.0*x'], x=numpy.zeros(size, dtype=float), y=numpy.zeros(size, dtype=float))) root.add_subsystem('C3', DistribExecComp(['y=3.0*x1+7.0*x2', 'y=1.5*x1+3.5*x2'], arr_size=size, x1=numpy.zeros(size, dtype=float), x2=numpy.zeros(size, dtype=float), y=numpy.zeros(size, dtype=float))) root.add_subsystem('C4', ExecComp(['y=x'], x=numpy.zeros(size, dtype=float), y=numpy.zeros(size, dtype=float))) root.connect("sub.C1.y", "C3.x1") root.connect("sub.C2.y", "C3.x2") root.connect("P1.x", "sub.C1.x") root.connect("P2.x", "sub.C2.x") root.connect("C3.y", "C4.x") root.linear_solver = LinearBlockGS() sub.linear_solver = LinearBlockGS() prob.set_solver_print(0) prob.setup(mode='fwd') prob.run_driver() diag1 = numpy.diag([-6.0, -6.0, -3.0]) diag2 = numpy.diag([35.0, 35.0, 17.5]) J = prob.compute_totals(of=['C4.y'], wrt=['P1.x', 'P2.x']) assert_rel_error(self, J['C4.y', 'P1.x'], diag1, 1e-6) assert_rel_error(self, J['C4.y', 'P2.x'], diag2, 1e-6) prob.setup(check=False, mode='rev') prob.run_driver() J = prob.compute_totals(of=['C4.y'], wrt=['P1.x', 'P2.x']) assert_rel_error(self, J['C4.y', 'P1.x'], diag1, 1e-6) assert_rel_error(self, J['C4.y', 'P2.x'], diag2, 1e-6)
def test_fan_out_grouped(self): size = 3 prob = Problem() prob.model = root = Group() root.add_subsystem('P', IndepVarComp('x', numpy.ones(size, dtype=float))) root.add_subsystem('C1', DistribExecComp(['y=3.0*x', 'y=2.0*x'], arr_size=size, x=numpy.zeros(size, dtype=float), y=numpy.zeros(size, dtype=float))) sub = root.add_subsystem('sub', ParallelGroup()) sub.add_subsystem('C2', ExecComp('y=1.5*x', x=numpy.zeros(size), y=numpy.zeros(size))) sub.add_subsystem('C3', ExecComp(['y=5.0*x'], x=numpy.zeros(size, dtype=float), y=numpy.zeros(size, dtype=float))) root.add_subsystem('C2', ExecComp(['y=x'], x=numpy.zeros(size, dtype=float), y=numpy.zeros(size, dtype=float))) root.add_subsystem('C3', ExecComp(['y=x'], x=numpy.zeros(size, dtype=float), y=numpy.zeros(size, dtype=float))) root.connect('sub.C2.y', 'C2.x') root.connect('sub.C3.y', 'C3.x') root.connect("C1.y", "sub.C2.x") root.connect("C1.y", "sub.C3.x") root.connect("P.x", "C1.x") prob.setup(check=False, mode='fwd') prob.run_model() diag1 = [4.5, 4.5, 3.0] diag2 = [15.0, 15.0, 10.0] assert_rel_error(self, prob['C2.y'], diag1) assert_rel_error(self, prob['C3.y'], diag2) diag1 = numpy.diag(diag1) diag2 = numpy.diag(diag2) J = prob.compute_totals(of=['C2.y', "C3.y"], wrt=['P.x']) assert_rel_error(self, J['C2.y', 'P.x'], diag1, 1e-6) assert_rel_error(self, J['C3.y', 'P.x'], diag2, 1e-6) prob.setup(check=False, mode='rev') prob.run_model() J = prob.compute_totals(of=['C2.y', "C3.y"], wrt=['P.x']) assert_rel_error(self, J['C2.y', 'P.x'], diag1, 1e-6) assert_rel_error(self, J['C3.y', 'P.x'], diag2, 1e-6)
def test_rev_mode_bug(self): prob = Problem() prob.model = SellarDerivatives(nonlinear_solver=NewtonSolver(), linear_solver=DirectSolver()) prob.setup(check=False, mode='rev') 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 = ['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) # In the bug, the solver mode got switched from fwd to rev when it shouldn't # have been, causing a singular matrix and NaNs in the output. prob.run_model() assert_rel_error(self, prob['y1'], 25.58830273, .00001) assert_rel_error(self, prob['y2'], 12.05848819, .00001)
def test_sparse_jacobian(self): import numpy as np from openmdao.api import Problem, Group, IndepVarComp, ExplicitComponent class SparsePartialComp(ExplicitComponent): def setup(self): self.add_input('x', shape=(4,)) self.add_output('f', shape=(2,)) self.declare_partials(of='f', wrt='x', rows=[0, 1, 1, 1], cols=[0, 1, 2, 3]) def compute_partials(self, inputs, partials): # Corresponds to the [(0,0), (1,1), (1,2), (1,3)] entries. partials['f', 'x'] = [1., 2., 3., 4.] model = Group() comp = IndepVarComp() comp.add_output('x', np.ones(4)) model.add_subsystem('input', comp) model.add_subsystem('example', SparsePartialComp()) model.connect('input.x', 'example.x') problem = Problem(model=model) problem.setup(check=False) problem.run_model() totals = problem.compute_totals(['example.f'], ['input.x']) assert_rel_error(self, totals['example.f', 'input.x'], [[1., 0., 0., 0.], [0., 2., 3., 4.]])
def test_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_reference(self): class TmpComp(ExplicitComponent): def initialize(self): self.A = np.ones((3, 3)) def setup(self): self.add_output('y', shape=(3,)) self.add_output('z', shape=(3,)) self.add_input('x', shape=(3,), units='degF') self.declare_partials(of='*', wrt='*') def compute_partials(self, inputs, partials): partials['y', 'x'] = self.A partials['z', 'x'] = self.A p = Problem() model = p.model = Group() indep = model.add_subsystem('indep', IndepVarComp(), promotes=['*']) indep.add_output('x', val=100., shape=(3,), units='degK') model.add_subsystem('comp', TmpComp(), promotes=['*']) p.setup() p.run_model() totals = p.compute_totals(['y', 'z'], ['x']) expected_totals = { ('y', 'x'): 9/5 * np.ones((3, 3)), ('z', 'x'): 9/5 * np.ones((3, 3)), } assert_rel_error(self, totals, expected_totals, 1e-6)
def test_const_jacobian(self): model = Group() comp = IndepVarComp() for name, val in (('x', 1.), ('y1', np.ones(2)), ('y2', np.ones(2)), ('y3', np.ones(2)), ('z', np.ones((2, 2)))): comp.add_output(name, val) model.add_subsystem('input_comp', comp, promotes=['x', 'y1', 'y2', 'y3', 'z']) problem = Problem(model=model) problem.set_solver_print(level=0) model.linear_solver = ScipyKrylov() model.jacobian = COOJacobian() model.add_subsystem('simple', SimpleCompConst(), promotes=['x', 'y1', 'y2', 'y3', 'z', 'f', 'g']) problem.setup(check=False) problem.run_model() totals = problem.compute_totals(['f', 'g'], ['x', 'y1', 'y2', 'y3', 'z']) jacobian = {} jacobian['f', 'x'] = [[1.]] jacobian['f', 'z'] = np.ones((1, 4)) jacobian['f', 'y1'] = np.zeros((1, 2)) jacobian['f', 'y2'] = np.zeros((1, 2)) jacobian['f', 'y3'] = np.zeros((1, 2)) jacobian['g', 'y1'] = [[1, 0], [1, 0], [0, 1], [0, 1]] jacobian['g', 'y2'] = [[1, 0], [0, 1], [1, 0], [0, 1]] jacobian['g', 'y3'] = [[1, 0], [1, 0], [0, 1], [0, 1]] jacobian['g', 'x'] = [[1], [0], [0], [1]] jacobian['g', 'z'] = np.zeros((4, 4)) assert_rel_error(self, totals, jacobian)
def test_scaled_derivs(self): prob = Problem() prob.model = model = SellarDerivatives() model.add_design_var('z') model.add_objective('obj') model.add_constraint('con1') prob.set_solver_print(level=0) prob.setup(check=False) prob.run_model() base = prob.compute_totals(of=['obj', 'con1'], wrt=['z']) prob = Problem() prob.model = model = SellarDerivatives() model.add_design_var('z', ref=2.0, ref0=0.0) model.add_objective('obj', ref=1.0, ref0=0.0) model.add_constraint('con1', lower=0, ref=2.0, ref0=0.0) prob.set_solver_print(level=0) prob.setup(check=False) prob.run_model() derivs = prob.driver._compute_totals(of=['obj_cmp.obj', 'con_cmp1.con1'], wrt=['pz.z'], return_format='dict') assert_rel_error(self, base[('con1', 'z')][0], derivs['con_cmp1.con1']['pz.z'][0], 1e-5) assert_rel_error(self, base[('obj', 'z')][0]*2.0, derivs['obj_cmp.obj']['pz.z'][0], 1e-5)
def test_scaling(self): # Make sure values are unscaled/dimensional. def custom_method(d_outputs, d_residuals, mode): if d_outputs['out_var'][0] != 12.0: raise ValueError('This value should be unscaled.') return False, 0, 0 class ScaledComp(ImplicitComponent): def setup(self): self.add_input('a', val=10., units='m') self.add_output('states', val=20.0, ref=3333.0) self.add_output('out_var', val=20.0, ref=12.0) p = Problem() p.model.add_subsystem('des_vars', IndepVarComp('a', val=10., units='m'), promotes=['*']) p.model.add_subsystem('icomp', ScaledComp(), promotes=['*']) model = p.model model.linear_solver = LinearUserDefined(custom_method) p.setup(vector_class=PETScVector, mode='rev', check=False) p.run_model() jac = p.compute_totals(of=['out_var'], wrt=['a'], return_format='dict')
def test_debug_print_option_totals_color(self): prob = Problem() prob.model = FanInGrouped() prob.model.linear_solver = LinearBlockGS() prob.model.sub.linear_solver = LinearBlockGS() prob.model.add_design_var('iv.x1', parallel_deriv_color='par_dv') prob.model.add_design_var('iv.x2', parallel_deriv_color='par_dv') prob.model.add_design_var('iv.x3') prob.model.add_objective('c3.y') prob.driver.options['debug_print'] = ['totals'] prob.setup(check=False, mode='fwd') prob.set_solver_print(level=0) prob.run_driver() indep_list = ['iv.x1', 'iv.x2', 'iv.x3'] unknown_list = ['c3.y'] stdout = sys.stdout strout = StringIO() sys.stdout = strout try: _ = prob.compute_totals(unknown_list, indep_list, return_format='flat_dict', debug_print=not prob.comm.rank) finally: sys.stdout = stdout output = strout.getvalue() if not prob.comm.rank: self.assertTrue('Solving color: par_dv (iv.x1, iv.x2)' in output) self.assertTrue('Solving variable: iv.x3' in output)
def test_specify_solver(self): import numpy as np from openmdao.api import Problem, Group, IndepVarComp, ExecComp, LinearBlockJac, NonlinearBlockGS from openmdao.test_suite.components.sellar import SellarDis1withDerivatives, SellarDis2withDerivatives 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 = NonlinearBlockGS() model.linear_solver = LinearBlockJac() prob.setup() prob.run_model() 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_simple(self): """Tests feature for adding a Scipy GMRES solver and calculating the derivatives.""" from openmdao.api import Problem, Group, IndepVarComp, ScipyKrylov from openmdao.test_suite.components.expl_comp_simple import TestExplCompSimpleDense # Tests derivatives on a simple comp that defines compute_jacvec. prob = Problem() model = prob.model model.add_subsystem('x_param', IndepVarComp('length', 3.0), promotes=['length']) model.add_subsystem('mycomp', TestExplCompSimpleDense(), promotes=['length', 'width', 'area']) model.linear_solver = ScipyKrylov() prob.set_solver_print(level=0) prob.setup(check=False, mode='fwd') prob['width'] = 2.0 prob.run_model() of = ['area'] wrt = ['length'] J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') assert_rel_error(self, J['area', 'length'][0][0], 2.0, 1e-6)
def test_matmat(self): indep_var_comp = IndepVarComp() indep_var_comp.add_output('alpha', 2.2) indep_var_comp.add_output('shape', 0., shape=8*12*2) indep_var_comp.add_output('twist', 0., shape=8-1) prob = Problem() prob.model.add_subsystem('indep_var_comp', indep_var_comp, promotes=['*']) prob.model.add_subsystem('adflow_comp', ADFLOWComp(), promotes=['*']) prob.model.add_design_var('shape', lower=-2., upper=2., scaler=100.) prob.model.add_design_var('twist', lower=-8., upper=8.) prob.model.add_design_var('alpha', lower=-5., upper=5.) prob.model.add_objective('cd') prob.model.add_constraint('cl', equals=.5) prob.model.add_constraint('thickness', lower=.5, upper=5., vectorize_derivs=True) prob.setup(mode='rev') # this will hang if the bug is present. prob.compute_totals(of=['cd', 'cl', 'thickness'], wrt=['shape', 'twist', 'alpha'])
def test_single_diamond(self): # Test derivatives for flat diamond topology. prob = Problem() prob.model = DiamondFlat() prob.model.linear_solver = self.linear_solver_class() prob.set_solver_print(level=0) prob.setup(check=False, mode='fwd') prob.run_model() wrt = ['iv.x'] of = ['c4.y1', 'c4.y2'] J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') assert_rel_error(self, J['c4.y1', 'iv.x'], [[25]], 1e-6) assert_rel_error(self, J['c4.y2', 'iv.x'], [[-40.5]], 1e-6) 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['c4.y1', 'iv.x'], [[25]], 1e-6) assert_rel_error(self, J['c4.y2', 'iv.x'], [[-40.5]], 1e-6)
def test_specify_ksp_type(self): import numpy as np from openmdao.api import Problem, Group, IndepVarComp, NonlinearBlockGS, PETScKrylov, \ ExecComp from openmdao.test_suite.components.sellar import SellarDis1withDerivatives, \ SellarDis2withDerivatives 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 = NonlinearBlockGS() model.linear_solver = PETScKrylov() model.linear_solver.options['ksp_type'] = 'gmres' prob.setup() prob.run_model() 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_fan_in_grouped(self): # Test derivatives for fan-in-grouped topology. prob = Problem() prob.model = FanInGrouped() prob.model.linear_solver = self.linear_solver_class() prob.set_solver_print(level=0) prob.setup(check=False, mode='fwd') prob.run_model() wrt = ['iv.x1', 'iv.x2'] of = ['c3.y'] J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') assert_rel_error(self, J['c3.y', 'iv.x1'], [[-6.0]], 1e-6) assert_rel_error(self, J['c3.y', 'iv.x2'], [[35.0]], 1e-6) 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['c3.y', 'iv.x1'], [[-6.0]], 1e-6) assert_rel_error(self, J['c3.y', 'iv.x2'], [[35.0]], 1e-6)
def test_error_on_singular_with_densejac_bug(self): prob = Problem(model=Group()) model = prob.model model.add_subsystem('p', IndepVarComp('x', 2.0 * np.ones((2, 2)))) model.add_subsystem( 'c1', ExecComp('y = 4.0*x', x=np.zeros((2, 2)), y=np.zeros( (2, 2)))) model.add_subsystem( 'c2', ExecComp('y = 4.0*x', x=np.zeros((2, 2)), y=np.zeros( (2, 2)))) model.add_subsystem( 'c3', ExecComp('y = 3.0*x', x=np.zeros((2, 2)), y=np.zeros( (2, 2)))) model.add_subsystem( 'c4', ExecComp('y = 2.0*x', x=np.zeros((2, 2)), y=np.zeros( (2, 2)))) model.add_subsystem('c5', SingularComp()) model.connect('p.x', 'c1.x') model.connect('c1.y', 'c2.x') model.connect('c2.y', 'c3.x') model.connect('c3.y', 'c4.x') model.connect('c4.y', 'c5.x', src_indices=([0])) model.linear_solver = DirectSolver(assemble_jac=True) model.options['assembled_jac_type'] = 'dense' prob.setup() prob.run_model() with self.assertRaises(RuntimeError) as cm: prob.compute_totals(of=['c5.y'], wrt=['p.x']) expected_msg = "Singular entry found in '' for column associated with state/residual 'c5.y'." self.assertEqual(expected_msg, str(cm.exception))
def test_simple_matvec_subbed_like_multipoint(self): # Tests derivatives on a group that contains a simple comp that # defines compute_jacvec. For this one, the indepvarcomp is also # in the subsystem. prob = Problem() model = prob.model sub = model.add_subsystem('sub', Group(), promotes=['length', 'width', 'area']) sub.add_subsystem('x_param', IndepVarComp('length', 3.0), promotes=['length']) sub.add_subsystem('mycomp', TestExplCompSimpleJacVec(), promotes=['length', 'width', 'area']) model.linear_solver = self.linear_solver_class() prob.set_solver_print(level=0) prob.setup(check=False, mode='fwd') prob['width'] = 2.0 # Note, For DirectSolver, assemble_jac must be False for mat-vec. if isinstance(model.linear_solver, DirectSolver): model.linear_solver.options['assemble_jac'] = False prob.run_model() of = ['area'] wrt = ['length'] J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') assert_near_equal(J['area', 'length'], [[2.0]], 1e-6) prob.setup(check=False, mode='rev') prob['width'] = 2.0 prob.run_model() J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') assert_near_equal(J['area', 'length'], [[2.0]], 1e-6)
def test_fd_count(self): # Make sure we aren't doing extra FD steps. class ParaboloidA(ExplicitComponent): 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) self.add_output('g_xy', val=0.0) # makes extra calls to the model with no actual steps self.declare_partials(of='*', wrt='*', method='fd', form='forward', step=1e-6) self.count = 0 def compute(self, inputs, outputs): x = inputs['x'] y = inputs['y'] outputs['f_xy'] = (x - 3.0)**2 + x * y + (y + 4.0)**2 - 3.0 g_xy = (x - 3.0)**2 + x * y + (y + 4.0)**2 - 3.0 outputs['g_xy'] = g_xy * 3 self.count += 1 prob = Problem() model = prob.model model.add_subsystem('px', IndepVarComp('x', val=3.0)) model.add_subsystem('py', IndepVarComp('y', val=5.0)) model.add_subsystem('parab', ParaboloidA()) model.connect('px.x', 'parab.x') model.connect('py.y', 'parab.y') model.add_design_var('px.x', lower=-50, upper=50) model.add_design_var('py.y', lower=-50, upper=50) model.add_objective('parab.f_xy') prob.setup(check=False) prob.run_model() print(prob.compute_totals(of=['parab.f_xy'], wrt=['px.x', 'py.y'])) # 1. run_model; 2. step x; 3. step y self.assertEqual(model.parab.count, 3)
def test_simple_matvec(self): # Tests derivatives on a simple comp that defines compute_jacvec. # Note, For DirectSolver, assemble_jac must be False for mat-vec. prob = Problem() model = prob.model model.add_subsystem('x_param', IndepVarComp('length', 3.0), promotes=['length']) model.add_subsystem('mycomp', TestExplCompSimpleJacVec(), promotes=['length', 'width', 'area']) model.linear_solver = self.linear_solver_class() prob.set_solver_print(level=0) prob.setup(check=False, mode='fwd') # Note, For DirectSolver, assemble_jac must be False for mat-vec. if isinstance(model.linear_solver, DirectSolver): model.linear_solver.options['assemble_jac'] = False prob['width'] = 2.0 prob.run_model() of = ['area'] wrt = ['length'] J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') assert_rel_error(self, J['area', 'length'], [[2.0]], 1e-6) prob.setup(check=False, mode='rev') prob['width'] = 2.0 prob.run_model() J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') assert_rel_error(self, J['area', 'length'], [[2.0]], 1e-6)
def test_specify_solver(self): prob = Problem() model = prob.model = SellarDerivatives() model.linear_solver = DirectSolver() prob.setup() prob.run_model() 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_sellar_state_connection(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.run_model() # Just make sure we are at the right answer assert_near_equal(prob['y1'], 25.58830273, .00001) assert_near_equal(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 Jbase.items(): assert_near_equal(J[key], val, .00001) prob.setup(check=False, mode='rev') prob.run_model() J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') for key, val in Jbase.items(): assert_near_equal(J[key], val, .00001)
def test_converge_diverge_groups(self): # Test derivatives for converge-diverge-groups topology. prob = Problem() prob.model = ConvergeDivergeGroups() prob.model.linear_solver = self.linear_solver_class() prob.set_solver_print(level=0) prob.setup(check=False, mode='fwd') prob.run_model() wrt = ['iv.x'] of = ['c7.y1'] # Make sure value is fine. assert_near_equal(prob['c7.y1'], -102.7, 1e-6) J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') assert_near_equal(J['c7.y1', 'iv.x'], [[-40.75]], 1e-6) prob.setup(check=False, mode='rev') prob.run_model() J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') assert_near_equal(J['c7.y1', 'iv.x'], [[-40.75]], 1e-6)
def test_caching_rev(self): p = Problem() p.model.add_subsystem( 'indeps', IndepVarComp('x', val=np.arange(10, dtype=float))) p.model.add_subsystem('C1', CacheUsingComp()) p.model.connect('indeps.x', 'C1.x') p.model.add_design_var('indeps.x') p.model.add_objective('C1.y', cache_linear_solution=True) p.setup(mode='rev') p.run_model() for i in range(10): p['indeps.x'] += np.arange(10, dtype=float) p.run_model() J = p.compute_totals(of=['C1.y'], wrt=['indeps.x'])
def test_error_on_NaN_bug(self): prob = Problem() model = prob.model model.add_subsystem('p', IndepVarComp('x', 2.0 * np.ones((2, 2)))) model.add_subsystem( 'c1', ExecComp('y = 4.0*x', x=np.zeros((2, 2)), y=np.zeros( (2, 2)))) model.add_subsystem( 'c2', ExecComp('y = 4.0*x', x=np.zeros((2, 2)), y=np.zeros( (2, 2)))) model.add_subsystem( 'c3', ExecComp('y = 3.0*x', x=np.zeros((2, 2)), y=np.zeros( (2, 2)))) model.add_subsystem( 'c4', ExecComp('y = 2.0*x', x=np.zeros((2, 2)), y=np.zeros( (2, 2)))) model.add_subsystem('c5', NanComp()) model.connect('p.x', 'c1.x') model.connect('c1.y', 'c2.x') model.connect('c2.y', 'c3.x') model.connect('c3.y', 'c4.x') model.connect('c4.y', 'c5.x', src_indices=([0])) model.linear_solver = DirectSolver(assemble_jac=True) prob.setup() prob.run_model() with self.assertRaises(RuntimeError) as cm: prob.compute_totals(of=['c5.y'], wrt=['p.x']) expected_msg = "NaN entries found in '' for rows associated with states/residuals ['c5.y']." self.assertEqual(expected_msg, str(cm.exception))
def test_compute_totals_return_array_non_square(self): prob = Problem() prob.model = model = Group() model.add_subsystem('px', IndepVarComp(name="x", val=np.ones((2, )))) comp = model.add_subsystem('comp', NonSquareArrayComp()) model.connect('px.x', 'comp.x1') model.add_design_var('px.x') model.add_objective('px.x') model.add_constraint('comp.y1') model.add_constraint('comp.y2') prob.setup(check=False) failed = prob.run_driver() self.assertFalse(failed, "Optimization failed.") derivs = prob.compute_totals(of=['comp.y1'], wrt=['px.x'], return_format='array') J = comp.JJ[0:3, 0:2] assert_rel_error(self, J, derivs, 1.0e-3) # Support for a name to be in 'of' and 'wrt' derivs = prob.compute_totals(of=['comp.y2', 'px.x', 'comp.y1'], wrt=['px.x'], return_format='array') assert_rel_error(self, J, derivs[3:, :], 1.0e-3) assert_rel_error(self, comp.JJ[3:4, 0:2], derivs[0:1, :], 1.0e-3) assert_rel_error(self, np.eye(2), derivs[1:3, :], 1.0e-3)
def test_compute_totals_relevancy(self): # When a model has desvars and responses defined, components that don't lie in the relevancy # graph between them do not take part in the linear solve. This led to some derivatives # being returned as zero in certain instances when it was called with wrt or of not in the # set. class DParaboloid(ExplicitComponent): def setup(self): ndvs = 3 self.add_input('w', val=1.) self.add_input('x', shape=ndvs) self.add_output('y', shape=1) self.add_output('z', shape=ndvs) self.declare_partials('y', 'x') self.declare_partials('y', 'w') self.declare_partials('z', 'x') def compute(self, inputs, outputs): x = inputs['x'] y_g = np.sum((x - 5)**2) outputs['y'] = np.sum(y_g) + (inputs['w'] - 10)**2 outputs['z'] = x**2 def compute_partials(self, inputs, J): x = inputs['x'] J['y', 'x'] = 2 * (x - 5) J['y', 'w'] = 2 * (inputs['w'] - 10) J['z', 'x'] = np.diag(2 * x) p = Problem() d_ivc = p.model.add_subsystem('distrib_ivc', IndepVarComp(), promotes=['*']) ndvs = 3 d_ivc.add_output('x', 2 * np.ones(ndvs)) ivc = p.model.add_subsystem('ivc', IndepVarComp(), promotes=['*']) ivc.add_output('w', 2.0) p.model.add_subsystem('dp', DParaboloid(), promotes=['*']) p.model.add_design_var('x', lower=-100, upper=100) p.model.add_objective('y') p.setup(mode='rev') p.run_model() J = p.compute_totals(of=['y', 'z'], wrt=['w', 'x']) assert (J['y', 'w'][0, 0] == -16)
def check_derivs(lin_sys_comp): prob = Problem() prob.model.add_subsystem('p1', IndepVarComp('A', A)) prob.model.add_subsystem('p2', IndepVarComp('b', b)) lingrp = prob.model.add_subsystem('lingrp', Group(), promotes=['*']) lingrp.add_subsystem('lin', lin_sys_comp) prob.model.connect('p1.A', 'lin.A') prob.model.connect('p2.b', 'lin.b') prob.setup(check=False) prob.set_solver_print(level=0) prob.run_model() prob.model.run_linearize() # prob.check_partials() # Compare against calculated derivs # Ainv = np.linalg.inv(A) # Don't use linalg.inv or a mathematician will die Ainv = np.array([[3., -2., 1.], [-3., 3., -2.], [1., -1., 1.]]) dx_dA = np.outer(Ainv, -x).reshape(3, 9) dx_db = Ainv d_inputs, d_outputs, d_residuals = lingrp.get_linear_vectors() # Forward mode with RHS of self.b d_residuals['lin.x'] = b lingrp.run_solve_linear(['linear'], 'fwd') sol = d_outputs['lin.x'] assert_rel_error(self, sol, x, .0001) # Reverse mode with RHS of self.b_T d_outputs['lin.x'] = b_T lingrp.run_solve_linear(['linear'], 'rev') sol = d_residuals['lin.x'] assert_rel_error(self, sol, x, .0001) J = prob.compute_totals(['lin.x'], ['p1.A', 'p2.b'], return_format='flat_dict') assert_rel_error(self, J['lin.x', 'p1.A'], dx_dA, .0001) assert_rel_error(self, J['lin.x', 'p2.b'], dx_db, .0001)
def test_sellar(self): # Basic sellar test. 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']) nlbgs = prob.model.nonlinear_solver = NonlinearBlockGS() 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_maxiter(self): import numpy as np from openmdao.api import Problem, Group, IndepVarComp, ExecComp, LinearBlockGS, NonlinearBlockGS from openmdao.test_suite.components.sellar import SellarDis1withDerivatives, SellarDis2withDerivatives 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 = NonlinearBlockGS() model.linear_solver = LinearBlockGS() model.linear_solver.options['maxiter'] = 2 prob.setup() prob.run_model() 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.60230118004, .00001) assert_rel_error(self, J['obj', 'z'][0][1], 1.78022500547, .00001)
def test_arguments(self): import numpy as np from openmdao.api import Problem, Group, IndepVarComp, ScipyKrylov, ExplicitComponent class CompOne(ExplicitComponent): def setup(self): self.add_input('x', val=0.0) self.add_output('y', val=np.zeros(25)) self._exec_count = 0 def compute(self, inputs, outputs): x = inputs['x'] outputs['y'] = np.arange(25) * x self._exec_count += 1 class CompTwo(ExplicitComponent): def setup(self): self.add_input('y', val=np.zeros(25)) self.add_output('z', val=0.0) self._exec_count = 0 def compute(self, inputs, outputs): y = inputs['y'] outputs['z'] = np.sum(y) self._exec_count += 1 prob = Problem() model = prob.model = Group() model.add_subsystem('p1', IndepVarComp('x', 1.0), promotes=['x']) model.add_subsystem('comp1', CompOne(), promotes=['x', 'y']) comp2 = model.add_subsystem('comp2', CompTwo(), promotes=['y', 'z']) model.linear_solver = ScipyKrylov() model.approx_totals(method='fd', step=1e-7, form='central', step_calc='rel') prob.setup() prob.run_model() of = ['z'] wrt = ['x'] derivs = prob.compute_totals(of=of, wrt=wrt) assert_rel_error(self, derivs['z', 'x'], [[300.0]], 1e-6)
def test_fd_glob(self): import numpy as np from openmdao.api import Problem, Group, IndepVarComp, ExplicitComponent class FDPartialComp(ExplicitComponent): def setup(self): self.add_input('x', shape=(4, )) self.add_input('y', shape=(2, )) self.add_input('y2', shape=(2, )) self.add_output('f', shape=(2, )) self.declare_partials('f', 'y*', method='fd') self.declare_partials('f', 'x', method='fd') def compute(self, inputs, outputs): f = outputs['f'] x = inputs['x'] y = inputs['y'] f[0] = x[0] + y[0] f[1] = np.dot([0, 2, 3, 4], x) + y[1] model = Group() comp = IndepVarComp() comp.add_output('x', np.ones(4)) comp.add_output('y', np.ones(2)) model.add_subsystem('input', comp) model.add_subsystem('example', FDPartialComp()) model.connect('input.x', 'example.x') model.connect('input.y', 'example.y') problem = Problem(model=model) problem.setup(check=False) problem.run_model() totals = problem.compute_totals(['example.f'], ['input.x', 'input.y']) assert_rel_error(self, totals['example.f', 'input.x'], [[1., 0., 0., 0.], [0., 2., 3., 4.]], tolerance=1e-8) assert_rel_error(self, totals['example.f', 'input.y'], [[1., 0.], [0., 1.]], tolerance=1e-8)
def test_common_shape(self): p = Problem() model = p.model model.add_subsystem('indep', IndepVarComp('x', val=np.ones(5))) model.add_subsystem('comp', ExecComp('y=3.0*x + 2.5', shape=(5, ))) model.connect('indep.x', 'comp.x') p.setup() p.run_model() J = p.compute_totals(of=['comp.y'], wrt=['indep.x'], return_format='array') assert_almost_equal(J, np.eye(5) * 3., decimal=6)
def test_compute_totals_no_args_promoted(self): p = Problem() dv = p.model.add_subsystem('des_vars', IndepVarComp(), promotes=['*']) dv.add_output('x', val=2.) p.model.add_subsystem('calc', ExecComp('y=2*x'), promotes=['*']) p.model.add_design_var('x') p.model.add_objective('y') p.setup() p.run_model() derivs = p.compute_totals() assert_rel_error(self, derivs['calc.y', 'des_vars.x'], [[2.0]], 1e-6)
def test_method(self): p = Problem() p.model.add_subsystem('des_vars', IndepVarComp('a', val=10., units='m'), promotes=['*']) p.model.add_subsystem('icomp', DistribStateImplicit(), promotes=['*']) model = p.model model.linear_solver = PETScKrylov() model.linear_solver.precon = LinearRunOnce() p.setup(vector_class=PETScVector, mode='rev', check=False) p.run_model() jac = p.compute_totals(of=['out_var'], wrt=['a'], return_format='dict') assert_rel_error(self, 15.0, jac['out_var']['a'][0][0])
def test_sparse_jacobian_in_place(self): import numpy as np from openmdao.api import Problem, Group, IndepVarComp, ExplicitComponent class SparsePartialComp(ExplicitComponent): def setup(self): self.add_input('x', shape=(4, )) self.add_output('f', shape=(2, )) self.declare_partials(of='f', wrt='x', rows=[0, 1, 1, 1], cols=[0, 1, 2, 3]) def compute_partials(self, inputs, partials): pd = partials['f', 'x'] # Corresponds to the (0, 0) entry pd[0] = 1. # (1,1) entry pd[1] = 2. # (1, 2) entry pd[2] = 3. # (1, 3) entry pd[3] = 4 model = Group() comp = IndepVarComp() comp.add_output('x', np.ones(4)) model.add_subsystem('input', comp) model.add_subsystem('example', SparsePartialComp()) model.connect('input.x', 'example.x') problem = Problem(model=model) problem.setup(check=False) problem.run_model() totals = problem.compute_totals(['example.f'], ['input.x']) assert_rel_error(self, totals['example.f', 'input.x'], [[1., 0., 0., 0.], [0., 2., 3., 4.]])
def run_model(self, size, num_par_fd1, num_par_fd2, method, total=False): if MPI: if MPI.COMM_WORLD.rank == 0: mat1 = np.random.random(5 * size).reshape((5, size)) - 0.5 else: mat1 = None mat1 = MPI.COMM_WORLD.bcast(mat1, root=0) else: mat1 = np.random.random(5 * size).reshape((5, size)) - 0.5 mat2 = mat1 * 5.0 p = Problem() model = p.model model.add_subsystem('indep', IndepVarComp('x', val=np.ones(mat1.shape[1]))) par = model.add_subsystem('par', ParallelGroup()) if total: meth = 'exact' else: meth = method C1 = par.add_subsystem('C1', MatMultComp(mat1, approx_method=meth)) C2 = par.add_subsystem('C2', MatMultComp(mat2, approx_method=meth)) if total: model.options['num_par_fd'] = num_par_fd1 model.approx_totals(method=method) else: C1.options['num_par_fd'] = num_par_fd1 C2.options['num_par_fd'] = num_par_fd2 model.connect('indep.x', 'par.C1.x') model.connect('indep.x', 'par.C2.x') p.setup(mode='fwd', force_alloc_complex=(method == 'cs')) p.run_model() J = p.compute_totals(of=['par.C1.y', 'par.C2.y'], wrt=['indep.x']) norm = np.linalg.norm(J['par.C1.y', 'indep.x'] - C1.mat) self.assertLess(norm, 1.e-7) norm = np.linalg.norm(J['par.C2.y', 'indep.x'] - C2.mat) self.assertLess(norm, 1.e-7)
def test_simple_totals(self, method): prob = Problem(coloring_dir=self.tempdir) model = prob.model = CounterGroup() prob.driver = pyOptSparseDriver(optimizer='SLSQP') prob.driver.declare_coloring() mask = np.array([[1, 0, 0, 1, 1], [0, 1, 0, 1, 1], [0, 1, 0, 1, 1], [1, 0, 0, 0, 0], [0, 1, 1, 0, 0]]) isplit = 2 sparsity = setup_sparsity(mask) indeps, conns = setup_indeps(isplit, mask.shape[1], 'indeps', 'comp') model.add_subsystem('indeps', indeps) comp = model.add_subsystem( 'comp', SparseCompExplicit(sparsity, method, isplit=isplit, osplit=2)) model.connect('indeps.x0', 'comp.x0') model.connect('indeps.x1', 'comp.x1') model.declare_coloring('*', method=method, step=1e-6 if method == 'fd' else None) model.comp.add_objective( 'y0', index=0 ) # pyoptsparse SLSQP requires a scalar objective, so pick index 0 model.comp.add_constraint('y1', lower=[1., 2.]) model.add_design_var('indeps.x0', lower=np.ones(3), upper=np.ones(3) + .1) model.add_design_var('indeps.x1', lower=np.ones(2), upper=np.ones(2) + .1) model.approx_totals(method=method) prob.setup(check=False, mode='fwd') prob.set_solver_print(level=0) prob.run_driver() # need this to trigger the dynamic coloring prob.driver._total_jac = None start_nruns = model._nruns derivs = prob.compute_totals() _check_total_matrix(model, derivs, sparsity[[0, 3, 4], :], method) nruns = model._nruns - start_nruns self.assertEqual(nruns, 3)
def test_units_fd(self): class UnitCompBase(ExplicitComponent): def setup(self): self.add_input('T', val=284., units="degR", desc="Temperature") self.add_input('P', val=1., units='lbf/inch**2', desc="Pressure") self.add_output('flow:T', val=284., units="degR", desc="Temperature") self.add_output('flow:P', val=1., units='lbf/inch**2', desc="Pressure") self.declare_partials(of='*', wrt='*', method='fd') def compute(self, inputs, outputs): outputs['flow:T'] = inputs['T'] outputs['flow:P'] = inputs['P'] p = Problem() model = p.model = Group() indep = model.add_subsystem('indep', IndepVarComp(), promotes=['*']) indep.add_output('T', val=100., units='degK') indep.add_output('P', val=1., units='bar') units = model.add_subsystem('units', UnitCompBase(), promotes=['*']) p.setup() p.run_model() totals = p.compute_totals(['flow:T', 'flow:P'], ['T', 'P']) expected_totals = { ('flow:T', 'T'): [[9/5]], ('flow:P', 'T'): [[0.]], ('flow:T', 'P'): [[0.]], ('flow:P', 'P'): [[14.50377]], } assert_rel_error(self, totals, expected_totals, 1e-6) expected_subjacs = { ('units.flow:T', 'units.T'): [[-1.]], ('units.flow:P', 'units.T'): [[0.]], ('units.flow:T', 'units.P'): [[0.]], ('units.flow:P', 'units.P'): [[-1.]], } jac = units._jacobian._subjacs for deriv, val in iteritems(expected_subjacs): assert_rel_error(self, jac[deriv], val, 1e-6)
def test_basic(self): import numpy as np from openmdao.api import Problem, Group, IndepVarComp, ScipyIterativeSolver, ExplicitComponent class CompOne(ExplicitComponent): def setup(self): self.add_input('x', val=0.0) self.add_output('y', val=np.zeros(25)) self._exec_count = 0 def compute(self, inputs, outputs): x = inputs['x'] outputs['y'] = np.arange(25) * x self._exec_count += 1 class CompTwo(ExplicitComponent): def setup(self): self.add_input('y', val=np.zeros(25)) self.add_output('z', val=0.0) self._exec_count = 0 def compute(self, inputs, outputs): y = inputs['y'] outputs['z'] = np.sum(y) self._exec_count += 1 prob = Problem() model = prob.model = Group() model.add_subsystem('p1', IndepVarComp('x', 0.0), promotes=['x']) model.add_subsystem('comp1', CompOne(), promotes=['x', 'y']) comp2 = model.add_subsystem('comp2', CompTwo(), promotes=['y', 'z']) model.linear_solver = ScipyIterativeSolver() model.approx_totals() prob.setup() prob.run_model() of = ['z'] wrt = ['x'] derivs = prob.compute_totals(of=of, wrt=wrt) assert_rel_error(self, derivs['z', 'x'], [[300.0]], 1e-6) self.assertEqual(comp2._exec_count, 2)
def test_simple_implicit(self): # This verifies that we can perform lgs around an implicit comp and get the right answer # as long as we slot a non-lgs linear solver on that component. prob = Problem() model = prob.model = Group() model.add_subsystem('p', IndepVarComp('a', 5.0)) comp = model.add_subsystem('comp', SimpleImp()) model.connect('p.a', 'comp.a') model.linear_solver = self.linear_solver_class() comp.linear_solver = DirectSolver() prob.setup(check=False, mode='fwd') prob.run_model() deriv = prob.compute_totals(of=['comp.x'], wrt=['p.a']) self.assertEqual(deriv['comp.x', 'p.a'], -1.5)
def test_multi_inputs_same_src_sparse_comp(self): p = Problem() indeps = p.model.add_subsystem('indeps', IndepVarComp('x', np.ones(2))) p.model.add_subsystem('C1', MySparseComp()) p.model.options['assembled_jac_type'] = 'csc' p.model.linear_solver = DirectSolver(assemble_jac=True) p.model.connect('indeps.x', ('C1.x', 'C1.y')) p.setup() p.run_model() J = p.compute_totals(of=['C1.z'], wrt=['indeps.x'], return_format='array') np.testing.assert_almost_equal(p.model._assembled_jac._int_mtx._matrix.toarray(), np.array([[-1., 0., 0., 0.], [ 0., -1., 0., 0.], [ 9., 8., -1., 0.], [ 5., 10., 0., -1.]]))