def _masking_case(mode): p = Problem() dv = p.model.add_subsystem('dv', IndepVarComp(), promotes=['*']) dv.add_output('z', [1., 1.]) p.model.add_subsystem('double_sellar', DoubleSellar()) p.model.connect('z', ['double_sellar.g1.z', 'double_sellar.g2.z']) p.model.add_design_var('z', lower=-10, upper=10) p.model.add_objective('double_sellar.g1.y1') p.setup(mode=mode) p.model.double_sellar.g1.jacobian = CSCJacobian() p.model.double_sellar.g1.linear_solver = DirectSolver() p.model.double_sellar.g1.nonlinear_solver = NewtonSolver() p.model.double_sellar.g2.jacobian = CSCJacobian() p.model.double_sellar.g2.linear_solver = DirectSolver() p.model.double_sellar.g2.nonlinear_solver = NewtonSolver() p.model.nonlinear_solver = NewtonSolver() p.model.nonlinear_solver.options['solve_subsystems'] = True p.model.linear_solver = ScipyKrylov() p.model.linear_solver.precon = LinearRunOnce() p.run_model() objective = p['double_sellar.g1.y1'] jac = p.compute_totals() return objective, jac
def test_one_src_2_tgts_csc_error(self): size = 10 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), y=np.zeros(size), z=np.zeros(size))) prob.model.jacobian = CSCJacobian() 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') prob.model.connect('indeps.x', 'G1.C1.y') prob.setup(mode='fwd') 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.eye(10) * 5.0, .0001)
def test_one_src_2_tgts_with_src_indices_cscjac_error(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 = CSCJacobian() 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() with self.assertRaises(Exception) as context: prob.final_setup() self.assertEqual( str(context.exception), "Keys [('G1.C1.z', 'G1.C1.x'), ('G1.C1.z', 'G1.C1.y')] map to the same " "sub-jacobian of a CSC or CSR partial jacobian and at least one of them " "is either not dense or uses src_indices. This can occur when multiple " "inputs on the same component are connected to the same output.")
def test_assembled_jacobian_submat_indexing_csc(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() prob.model.jacobian = DenseJacobian() prob.model.linear_solver = DirectSolver() G1.jacobian = CSCJacobian() G1.linear_solver = DirectSolver() G1.nonlinear_solver = NewtonSolver() # 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_solve_subsystems_basic_csc(self): prob = Problem(model=DoubleSellar()) model = prob.model model.jacobian = CSCJacobian() g1 = model.g1 g1.jacobian = DenseJacobian() g1.nonlinear_solver = NewtonSolver() g1.nonlinear_solver.options['rtol'] = 1.0e-5 g1.linear_solver = DirectSolver() g2 = model.g2 g2.jacobian = DenseJacobian() 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.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 setup(self): self.add_subsystem('n1', Node(n_in=1, n_out=2), promotes_inputs=[('I_in:0', 'I_in')]) self.add_subsystem('n2', Node()) # leaving defaults self.add_subsystem('R1', Resistor(R=100.), promotes_inputs=[('V_out', 'Vg')]) self.add_subsystem('R2', Resistor(R=10000.)) self.add_subsystem('D1', Diode(), promotes_inputs=[('V_out', 'Vg')]) self.connect('n1.V', ['R1.V_in', 'R2.V_in']) self.connect('R1.I', 'n1.I_out:0') self.connect('R2.I', 'n1.I_out:1') self.connect('n2.V', ['R2.V_out', 'D1.V_in']) self.connect('R2.I', 'n2.I_in:0') self.connect('D1.I', 'n2.I_out:0') self.nonlinear_solver = NewtonSolver() self.nonlinear_solver.options['iprint'] = 2 self.nonlinear_solver.options['maxiter'] = 20 self.linear_solver = DirectSolver() ############################## # Assemble at the group level ############################## self.jacobian = CSCJacobian()
def test_newton_with_cscjac_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 = CSCJacobian() 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_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 = CSCJacobian() sub1.linear_solver = DirectSolver() sub2.jacobian = CSCJacobian() 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)