def test_par_fd(self, size, num_par_fd, method): if MPI: if MPI.COMM_WORLD.rank == 0: mat = np.random.random(5 * size).reshape((5, size)) - 0.5 else: mat = None mat = MPI.COMM_WORLD.bcast(mat, root=0) else: mat = np.random.random(5 * size).reshape((5, size)) - 0.5 p = om.Problem() model = p.model model.add_subsystem('indep', om.IndepVarComp('x', val=np.ones(mat.shape[1]))) comp = model.add_subsystem('comp', MatMultComp(mat, approx_method=method, num_par_fd=num_par_fd)) model.connect('indep.x', 'comp.x') p.setup(mode='fwd', force_alloc_complex=(method == 'cs')) p.run_model() comp.num_computes = 0 J = p.compute_totals(of=['comp.y'], wrt=['indep.x']) ncomputes = comp.num_computes if comp.comm.rank == 0 else 0 norm = np.linalg.norm(J['comp.y','indep.x'] - comp.mat) self.assertLess(norm, 1.e-7) if MPI: self.assertEqual(MPI.COMM_WORLD.allreduce(ncomputes), size) norm = np.linalg.norm(comp._jacobian['y', 'x'] - comp.mat) self.assertLess(norm, 1.e-7) # make sure check_partials works data = p.check_partials(out_stream=None, step=1.1e-6) # step needs to be different # than compute step, otherwise we get an error norm = np.linalg.norm(data['comp']['y', 'x']['J_fd'] - comp.mat) self.assertLess(norm, 1.e-7)
def _setup_problem(mat, total_method='exact', partial_method='exact', total_num_par_fd=1, partial_num_par_fd=1, approx_totals=False): p = Problem(model=Group(num_par_fd=total_num_par_fd)) model = p.model model.add_subsystem('indep', IndepVarComp('x', val=np.ones(mat.shape[1]))) model.add_subsystem( 'comp', MatMultComp(mat, approx_method=partial_method, num_par_fd=partial_num_par_fd)) model.connect('indep.x', 'comp.x') if approx_totals: p.model.approx_totals() p.setup(mode='fwd', force_alloc_complex='cs' in (total_method, partial_method)) return p
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 if total: grp = Group(num_par_fd=num_par_fd1) else: grp = Group() p = Problem(model=grp) model = p.model model.add_subsystem('indep', IndepVarComp('x', val=np.ones(mat1.shape[1]))) par = model.add_subsystem('par', ParallelGroup()) if total: C1 = par.add_subsystem('C1', MatMultComp(mat1, approx_method='exact')) C2 = par.add_subsystem('C2', MatMultComp(mat2, approx_method='exact')) model.approx_totals(method=method) else: C1 = par.add_subsystem( 'C1', MatMultComp(mat1, approx_method=method, num_par_fd=num_par_fd1)) C2 = par.add_subsystem( 'C2', MatMultComp(mat2, approx_method=method, 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) if not total: # if total is True, the partials won't be computed during the compute_totals call if C1 in par._subsystems_myproc: norm = np.linalg.norm(C1._jacobian['y', 'x'] - C1.mat) self.assertLess(norm, 1.e-7) if C2 in par._subsystems_myproc: norm = np.linalg.norm(C2._jacobian['y', 'x'] - C2.mat) self.assertLess(norm, 1.e-7) # make sure check_partials works data = p.check_partials(out_stream=None) if 'par.C1' in data: norm = np.linalg.norm(data['par.C1']['y', 'x']['J_fd'] - C1.mat) self.assertLess(norm, 1.e-7) if 'par.C2' in data: norm = np.linalg.norm(data['par.C2']['y', 'x']['J_fd'] - C2.mat) self.assertLess(norm, 1.e-7)