def setup(self): self.add_subsystem('ivc', om.IndepVarComp('x', 0.), promotes_outputs=['*']) self.add_subsystem('dst', DistribComp(), promotes_inputs=['*']) self.add_subsystem('sum', om.ExecComp('z = sum(y)', y=np.zeros((N,)), z=0.0)) self.connect('dst.y', 'sum.y') self.add_subsystem('par', om.ParallelGroup(), promotes_inputs=['*']) self.par.add_subsystem('c1', om.ExecComp(['y=2.0*x']), promotes_inputs=['*']) self.par.add_subsystem('c2', om.ExecComp(['y=5.0*x']), promotes_inputs=['*'])
def setup_model(self, mode): asize = 3 prob = om.Problem() root = prob.model root.linear_solver = om.LinearBlockGS() G1 = root.add_subsystem('G1', om.ParallelGroup()) G1.linear_solver = om.LinearBlockGS() par1 = G1.add_subsystem('par1', om.Group()) par1.linear_solver = om.LinearBlockGS() par2 = G1.add_subsystem('par2', om.Group()) par2.linear_solver = om.LinearBlockGS() p1 = par1.add_subsystem( 'p', om.IndepVarComp('x', np.arange(asize, dtype=float) + 1.0)) p2 = par2.add_subsystem( 'p', om.IndepVarComp('x', np.arange(asize, dtype=float) + 10.0)) c2 = par1.add_subsystem( 'c2', om.ExecComp('y = x * 2.0', x=np.zeros(asize), y=np.zeros(asize))) c3 = par2.add_subsystem( 'c3', om.ExecComp('y = ones(3).T*x.dot(arange(3.,6.))', x=np.zeros(asize), y=np.zeros(asize))) c4 = par1.add_subsystem( 'c4', om.ExecComp('y = x * 4.0', x=np.zeros(asize), y=np.zeros(asize))) c5 = par2.add_subsystem( 'c5', om.ExecComp('y = x * 5.0', x=np.zeros(asize), y=np.zeros(asize))) prob.model.add_design_var('G1.par1.p.x', indices=[1, 2]) prob.model.add_design_var('G1.par2.p.x', indices=[1, 2]) prob.model.add_constraint('G1.par1.c4.y', upper=0.0, indices=[1], parallel_deriv_color='par_resp') prob.model.add_constraint('G1.par2.c5.y', upper=0.0, indices=[2], parallel_deriv_color='par_resp') root.connect('G1.par1.p.x', 'G1.par1.c2.x') root.connect('G1.par2.p.x', 'G1.par2.c3.x') root.connect('G1.par1.c2.y', 'G1.par1.c4.x') root.connect('G1.par2.c3.y', 'G1.par2.c5.x') prob.setup(check=False, mode=mode) prob.run_driver() return prob
def test_aitken(self): prob = om.Problem() model = prob.model model.add_subsystem('px', om.IndepVarComp('x', 1.0), promotes=['x']) model.add_subsystem('pz', om.IndepVarComp('z', np.array([5.0, 2.0])), promotes=['z']) p1 = model.add_subsystem('p1', om.ParallelGroup(), promotes=['*']) p1.add_subsystem('d1a', SellarDis1withDerivatives(), promotes=['x', 'z']) p1.add_subsystem('d1b', SellarDis1withDerivatives(), promotes=['x', 'z']) p2 = model.add_subsystem('p2', om.ParallelGroup(), promotes=['*']) p2.add_subsystem('d2a', SellarDis2withDerivatives(), promotes=['z']) p2.add_subsystem('d2b', SellarDis2withDerivatives(), promotes=['z']) model.connect('d1a.y1', 'd2a.y1') model.connect('d1b.y1', 'd2b.y1') model.connect('d2a.y2', 'd1a.y2') model.connect('d2b.y2', 'd1b.y2') model.nonlinear_solver = om.NonlinearBlockGS() prob.setup() prob.set_solver_print(level=2) model.nonlinear_solver.options['use_aitken'] = True # Set one branch of Sellar close to the solution. prob.set_val('d2b.y2', 12.05848815) prob.set_val('d1b.y1', 25.58830237) prob.run_model() print(prob.get_val('d1a.y1', get_remote=True)) print(prob.get_val('d2a.y1', get_remote=True)) print(prob.get_val('d1b.y2', get_remote=True)) print(prob.get_val('d2b.y2', get_remote=True)) assert_near_equal(prob.get_val('d1a.y1', get_remote=True), 25.58830273, .00001) assert_near_equal(prob.get_val('d1b.y1', get_remote=True), 25.58830273, .00001) assert_near_equal(prob.get_val('d2a.y2', get_remote=True), 12.05848819, .00001) assert_near_equal(prob.get_val('d2b.y2', get_remote=True), 12.05848819, .00001) # Test that Aitken accelerated the convergence, normally takes 7. self.assertTrue(model.nonlinear_solver._iter_count == 6)
def test_parallel_group_order(self): prob = om.Problem() model = prob.model model.add_subsystem('p1', om.IndepVarComp('x', 1.0)) model.add_subsystem('p2', om.IndepVarComp('x', 1.0)) parallel = model.add_subsystem('parallel', om.ParallelGroup()) parallel.add_subsystem('c1', om.ExecComp(['y=-2.0*x'])) parallel.add_subsystem('c2', om.ExecComp(['y=5.0*x'])) parallel.connect('c1.y', 'c2.x') parallel = model.add_subsystem('parallel_copy', om.ParallelGroup()) parallel.add_subsystem('comp1', om.ExecComp(['y=-2.0*x'])) parallel.add_subsystem('comp2', om.ExecComp(['y=5.0*x'])) parallel.connect('comp1.y', 'comp2.x') model.add_subsystem('c3', om.ExecComp(['y=3.0*x1+7.0*x2'])) model.add_subsystem('c4', om.ExecComp(['y=3.0*x_copy_1+7.0*x_copy_2'])) model.connect("parallel.c1.y", "c3.x1") model.connect("parallel.c2.y", "c3.x2") model.connect("parallel_copy.comp1.y", "c4.x_copy_1") model.connect("parallel_copy.comp2.y", "c4.x_copy_2") model.connect("p1.x", "parallel.c1.x") model.connect("p1.x", "parallel_copy.comp1.x") testlogger = TestLogger() prob.setup(check=True, mode='fwd', logger=testlogger) msg = "Need to attach NonlinearBlockJac, NewtonSolver, or BroydenSolver to 'parallel' when " \ "connecting components inside parallel groups" with assert_warning(UserWarning, msg): prob.run_model() expected_warning = ( "The following systems are executed out-of-order:\n" " System 'parallel.c2' executes out-of-order with respect to its source systems ['parallel.c1']\n" " System 'parallel_copy.comp2' executes out-of-order with respect to its source systems ['parallel_copy.comp1']\n" ) testlogger.find_in('warning', expected_warning)
def test_crossover(self, mode, auto): # multiple crossovers in fwd and rev prob = om.Problem() model = prob.model model.add_subsystem('ivc', om.IndepVarComp('x')) par1 = model.add_subsystem('par1', om.ParallelGroup()) par1.add_subsystem('C1', om.ExecComp('y = 1.5 * x')) par1.add_subsystem('C2', om.ExecComp('y = 2.5 * x')) model.add_subsystem('C3', om.ExecComp('y = 3.5 * x1 - .5 * x2')) par2 = model.add_subsystem('par2', om.ParallelGroup()) par2.add_subsystem('C4', om.ExecComp('y = 4.5 * x')) par2.add_subsystem('C5', om.ExecComp('y = 5.5 * x')) model.add_subsystem('C6', om.ExecComp('y = 6.5 * x1 + 1.1 * x2')) model.connect('ivc.x', 'par1.C1.x') model.connect('ivc.x', 'par1.C2.x') model.connect('par1.C1.y', 'C3.x1') model.connect('par1.C2.y', 'C3.x2') model.connect('C3.y', 'par2.C4.x') model.connect('C3.y', 'par2.C5.x') model.connect('par2.C4.y', 'C6.x1') model.connect('par2.C5.y', 'C6.x2') of = ['C6.y'] wrt = ['ivc.x'] prob.setup(check=False, mode=mode) prob.set_solver_print(level=0) prob.run_model() np.testing.assert_allclose(prob.get_val('C6.y', get_remote=True), 141.2) J = prob.compute_totals(of=of, wrt=wrt) print(J) np.testing.assert_allclose(J['C6.y', 'ivc.x'][0][0], 141.2) np.testing.assert_allclose(prob.get_val('C6.y', get_remote=True), 141.2)
def test_prob_getval_dist_par_disc(self): size = 3 p = om.Problem() top = p.model par = top.add_subsystem('par', om.ParallelGroup()) C1 = par.add_subsystem( "C1", DistribInputDistribOutputDiscreteComp(arr_size=size)) C2 = par.add_subsystem( "C2", DistribInputDistribOutputDiscreteComp(arr_size=size)) p.setup() # Conclude setup but don't run model. p.final_setup() if C1 in p.model.par._subsystems_myproc: C1._inputs['invec'] = np.array(range(C1._inputs._data.size, 0, -1), float) C1._discrete_inputs['disc_in'] = 'C1foo' if C2 in p.model.par._subsystems_myproc: C2._inputs['invec'] = np.array(range(C2._inputs._data.size, 0, -1), float) * 3 C2._discrete_inputs['disc_in'] = 'C2foo' p.run_model() ans = p.get_val('par.C2.invec', get_remote=True) np.testing.assert_allclose(ans, np.array([6, 3, 3], dtype=float)) ans = p.get_val('par.C2.outvec', get_remote=True) np.testing.assert_allclose(ans, np.array([12, 6, 6], dtype=float)) ans = p.get_val('par.C1.invec', get_remote=True) np.testing.assert_allclose(ans, np.array([2, 1, 1], dtype=float)) ans = p.get_val('par.C1.outvec', get_remote=True) np.testing.assert_allclose(ans, np.array([4, 2, 2], dtype=float)) if C1 in p.model.par._subsystems_myproc: ans = p.get_val('par.C1.disc_in', get_remote=False) self.assertEqual(ans, 'C1foo') ans = p.get_val('par.C1.disc_out', get_remote=False) self.assertEqual(ans, 'C1foobar') if C2 in p.model.par._subsystems_myproc: ans = p.get_val('par.C2.disc_in', get_remote=False) self.assertEqual(ans, 'C2foo') ans = p.get_val('par.C2.disc_out', get_remote=False) self.assertEqual(ans, 'C2foobar') ans = p.get_val('par.C1.disc_in', get_remote=True) self.assertEqual(ans, 'C1foo') ans = p.get_val('par.C2.disc_in', get_remote=True) self.assertEqual(ans, 'C2foo') ans = p.get_val('par.C1.disc_out', get_remote=True) self.assertEqual(ans, 'C1foobar') ans = p.get_val('par.C2.disc_out', get_remote=True) self.assertEqual(ans, 'C2foobar')
def test_discrete_fan_out(self): p = om.Problem() model = p.model par = model.add_subsystem('par', om.ParallelGroup(), promotes=['x']) par.add_subsystem('C1', PathCompEx(), promotes=['x']) par.add_subsystem('C2', PathCompEx(), promotes=['x']) p.setup() p.run_model() self.assertEqual(p.get_val('par.C1.y', get_remote=True), 'par.C1/') self.assertEqual(p.get_val('par.C2.y', get_remote=True), 'par.C2/')
def setup(self): super().setup() self._setup_design_parameters() phases_group = self.add_subsystem('phases', subsys=om.ParallelGroup(), promotes_inputs=['*'], promotes_outputs=['*']) for name, phs in self._phases.items(): g = phases_group.add_subsystem(name, phs) g.linear_solver = om.DirectSolver()
def setup_model(self, size): class DelayComp(om.ExplicitComponent): def initialize(self): self.counter = 0 self.options.declare('time', default=3.0) self.options.declare('size', default=1) def setup(self): size = self.options['size'] self.add_input('x', shape=size) self.add_output('y', shape=size) self.add_output('y2', shape=size) self.declare_partials('y', 'x') self.declare_partials('y2', 'x') def compute(self, inputs, outputs): waittime = self.options['time'] size = self.options['size'] outputs['y'] = np.linspace(3, 10, size) * inputs['x'] outputs['y2'] = np.linspace(2, 4, size) * inputs['x'] def compute_jacvec_product(self, inputs, d_inputs, d_outputs, mode): waittime = self.options['time'] size = self.options['size'] if mode == 'fwd': time.sleep(waittime) if 'x' in d_inputs: self.counter += 1 if 'y' in d_outputs: d_outputs['y'] += np.linspace(3, 10, size)*d_inputs['x'] if 'y2' in d_outputs: d_outputs['y2'] += np.linspace(2, 4, size)*d_inputs['x'] elif mode == 'rev': if 'x' in d_inputs: self.counter += 1 time.sleep(waittime) if 'y' in d_outputs: d_inputs['x'] += np.linspace(3, 10, size)*d_outputs['y'] if 'y2' in d_outputs: d_inputs['x'] += np.linspace(2, 4, size)*d_outputs['y2'] model = om.Group() iv = om.IndepVarComp() mysize = size iv.add_output('x', val=3.0 * np.ones((mysize, ))) model.add_subsystem('iv', iv) pg = model.add_subsystem('pg', om.ParallelGroup(), promotes=['*']) pg.add_subsystem('dc1', DelayComp(size=mysize, time=0.0)) pg.add_subsystem('dc2', DelayComp(size=mysize, time=0.0)) pg.add_subsystem('dc3', DelayComp(size=mysize, time=0.0)) model.connect('iv.x', ['dc1.x', 'dc2.x', 'dc3.x']) model.linear_solver = om.LinearRunOnce() model.add_design_var('iv.x', lower=-1.0, upper=1.0) return model
def test_fan_out_with_dup(self, size, toset, auto, before): # this connects an auto_ivc to 3 variables. 2 are under a parallel group and 1 is # duplicated in all procs p = om.Problem() model = p.model if not auto: ivc = model.add_subsystem('indeps', om.IndepVarComp()) ivc.add_output('x', np.ones(size)) c3 = om.ExecComp('y = 4. * x', x=np.ones(size), y=np.ones(size)) if before: model.add_subsystem('C3', c3, promotes_inputs=['x']) par = model.add_subsystem('par', om.ParallelGroup(), promotes_inputs=['x']) par.add_subsystem('C1', om.ExecComp('y = 3 * x', x=np.ones(size), y=np.ones(size)), promotes_inputs=['x']) par.add_subsystem('C2', om.ExecComp('y = 5 * x', x=np.ones(size), y=np.ones(size)), promotes_inputs=['x']) if not before: model.add_subsystem('C3', c3, promotes_inputs=['x']) if not auto: model.connect('indeps.x', 'x') p.setup() inval = np.arange(size) + 1.0 p[toset] = inval p.run_model() np.testing.assert_allclose(p.get_val('par.C1.y', get_remote=True), inval * 3.) np.testing.assert_allclose(p.get_val('par.C2.y', get_remote=True), inval * 5.) np.testing.assert_allclose(p.get_val('C3.y', get_remote=True), inval * 4.) of = ['par.C1.y', 'par.C2.y', 'C3.y'] if auto: wrt = ['x'] else: wrt = ['indeps.x'] J = p.compute_totals(of=of, wrt=wrt, return_format='flat_dict') np.testing.assert_allclose(J['par.C1.y', wrt[0]], 3. * np.eye(size)) np.testing.assert_allclose(J['par.C2.y', wrt[0]], 5. * np.eye(size)) np.testing.assert_allclose(J['C3.y', wrt[0]], 4. * np.eye(size)) # try with absolute names if not auto: J = p.compute_totals(of=of, wrt=['indeps.x'], return_format='flat_dict') np.testing.assert_allclose(J['par.C1.y', 'indeps.x'], 3. * np.eye(size)) np.testing.assert_allclose(J['par.C2.y', 'indeps.x'], 5. * np.eye(size)) np.testing.assert_allclose(J['C3.y', 'indeps.x'], 4. * np.eye(size))
def test_cs_around_broyden_linesearch(self): prob = om.Problem() model = prob.model sub = model.add_subsystem('sub', om.ParallelGroup(), promotes=['*']) model.add_subsystem('px', om.IndepVarComp('x', 1.0), promotes=['x']) model.add_subsystem('pz', om.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', om.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', om.ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1']) model.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2']) sub.nonlinear_solver = om.BroydenSolver() sub.nonlinear_solver.linesearch = om.BoundsEnforceLS( bound_enforcement='vector') sub.linear_solver = om.DirectSolver() model.linear_solver = om.DirectSolver() prob.model.add_design_var('x', lower=-100, upper=100) prob.model.add_design_var('z', lower=-100, upper=100) prob.model.add_objective('obj') prob.model.add_constraint('con1', upper=0.0) prob.model.add_constraint('con2', upper=0.0) prob.setup(check=False, force_alloc_complex=True) prob.set_solver_print(level=2) prob.run_model() assert_rel_error(self, prob.get_val('y1', get_remote=True), 25.58830237, .00001) totals = prob.check_totals(method='cs', out_stream=None) for key, val in iteritems(totals): assert_rel_error(self, val['rel error'][0], 0.0, 1e-6)
def test_fan_out_grouped(self, nlsolver): size = 3 prob = om.Problem() prob.model = root = om.Group() root.add_subsystem('P', om.IndepVarComp('x', np.ones(size, dtype=float))) root.add_subsystem('C1', DistribExecComp(['y=3.0*x', 'y=2.0*x'], arr_size=size, x=np.zeros(size, dtype=float), y=np.zeros(size, dtype=float))) sub = root.add_subsystem('sub', om.ParallelGroup()) sub.add_subsystem('C2', om.ExecComp('y=1.5*x', x=np.zeros(size), y=np.zeros(size))) sub.add_subsystem('C3', om.ExecComp(['y=5.0*x'], x=np.zeros(size, dtype=float), y=np.zeros(size, dtype=float))) root.add_subsystem('C2', om.ExecComp(['y=x'], x=np.zeros(size, dtype=float), y=np.zeros(size, dtype=float))) root.add_subsystem('C3', om.ExecComp(['y=x'], x=np.zeros(size, dtype=float), y=np.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") root.nonlinear_solver = nlsolver() prob.setup(check=False, mode='fwd') prob.run_model() diag1 = [4.5, 4.5, 3.0] diag2 = [15.0, 15.0, 10.0] assert_near_equal(prob['C2.y'], diag1) assert_near_equal(prob['C3.y'], diag2) diag1 = np.diag(diag1) diag2 = np.diag(diag2) J = prob.compute_totals(of=['C2.y', "C3.y"], wrt=['P.x']) assert_near_equal(J['C2.y', 'P.x'], diag1, 1e-6) assert_near_equal(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_near_equal(J['C2.y', 'P.x'], diag1, 1e-6) assert_near_equal(J['C3.y', 'P.x'], diag2, 1e-6)
def test_discrete_fan_out2(self): p = om.Problem() model = p.model par = model.add_subsystem('par', om.ParallelGroup(), promotes=['x']) par.add_subsystem('C1', PathCompEx('foo'), promotes=['x']) par.add_subsystem('C2', PathCompEx('bar'), promotes=['x']) try: p.setup() except Exception as err: self.assertEqual(str(err), "<model> <class Group>: The following inputs, ['par.C1.x', 'par.C2.x'], promoted to 'x', are connected but their metadata entries ['val'] differ. Call <group>.set_input_defaults('x', val=?), where <group> is the Group named 'par' to remove the ambiguity.") else: self.fail("Exception expected.")
def test_fan_in_grouped(self, nlsolver): size = 3 prob = om.Problem() prob.model = root = om.Group() root.add_subsystem('P1', om.IndepVarComp('x', np.ones(size, dtype=float))) root.add_subsystem('P2', om.IndepVarComp('x', np.ones(size, dtype=float))) sub = root.add_subsystem('sub', om.ParallelGroup()) sub.add_subsystem('C1', om.ExecComp(['y=-2.0*x'], x=np.zeros(size, dtype=float), y=np.zeros(size, dtype=float))) sub.add_subsystem('C2', om.ExecComp(['y=5.0*x'], x=np.zeros(size, dtype=float), y=np.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=np.zeros(size, dtype=float), x2=np.zeros(size, dtype=float), y=np.zeros(size, dtype=float))) root.add_subsystem('C4', om.ExecComp(['y=x'], x=np.zeros(size, dtype=float), y=np.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.nonlinear_solver = nlsolver() prob.set_solver_print(0) prob.setup(mode='fwd') prob.run_driver() diag1 = np.diag([-6.0, -6.0, -3.0]) diag2 = np.diag([35.0, 35.0, 17.5]) J = prob.compute_totals(of=['C4.y'], wrt=['P1.x', 'P2.x']) assert_near_equal(J['C4.y', 'P1.x'], diag1, 1e-6) assert_near_equal(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_near_equal(J['C4.y', 'P1.x'], diag1, 1e-6) assert_near_equal(J['C4.y', 'P2.x'], diag2, 1e-6)
def __init__(self): super(ConvergeDivergeGroups, self).__init__() self.add_subsystem('iv', om.IndepVarComp('x', 2.0)) g1 = self.add_subsystem('g1', om.ParallelGroup()) g1.add_subsystem('c1', om.ExecComp(['y1 = 2.0*x1**2', 'y2 = 3.0*x1' ])) g2 = g1.add_subsystem('g2', om.ParallelGroup()) g2.add_subsystem('c2', om.ExecComp('y1 = 0.5*x1')) g2.add_subsystem('c3', om.ExecComp('y1 = 3.5*x1')) g1.add_subsystem('c4', om.ExecComp(['y1 = x1 + 2.0*x2', 'y2 = 3.0*x1 - 5.0*x2' ])) g3 = self.add_subsystem('g3', om.ParallelGroup()) g3.add_subsystem('c5', om.ExecComp('y1 = 0.8*x1')) g3.add_subsystem('c6', om.ExecComp('y1 = 0.5*x1')) self.add_subsystem('c7', om.ExecComp('y1 = x1 + 3.0*x2')) # make connections self.connect('iv.x', 'g1.c1.x1') g1.connect('c1.y1', 'g2.c2.x1') g1.connect('c1.y2', 'g2.c3.x1') self.connect('g1.g2.c2.y1', 'g1.c4.x1') self.connect('g1.g2.c3.y1', 'g1.c4.x2') self.connect('g1.c4.y1', 'g3.c5.x1') self.connect('g1.c4.y2', 'g3.c6.x1') self.connect('g3.c5.y1', 'c7.x1') self.connect('g3.c6.y1', 'c7.x2')
def test_prob_getitem_err(self): size = 3 p = om.Problem() top = p.model par = top.add_subsystem('par', om.ParallelGroup()) C1 = par.add_subsystem("C1", DistribInputDistribOutputComp(arr_size=size)) C2 = par.add_subsystem("C2", DistribInputDistribOutputComp(arr_size=size)) p.setup() # Conclude setup but don't run model. p.final_setup() if C1 in p.model.par._subsystems_myproc: C1._inputs['invec'] = np.array(range(C1._inputs._data.size, 0, -1), float) if C2 in p.model.par._subsystems_myproc: C2._inputs['invec'] = np.array(range(C2._inputs._data.size, 0, -1), float) * 3 p.run_model() # test that getitem from Problem on a distrib var raises an exception with self.assertRaises(Exception) as context: ans = p.get_val('par.C2.invec', get_remote=True) self.assertEqual( str(context.exception), "Retrieval of the full distributed variable 'par.C2.invec' is not supported." ) with self.assertRaises(Exception) as context: ans = p.get_val('par.C2.outvec', get_remote=True) self.assertEqual( str(context.exception), "Retrieval of the full distributed variable 'par.C2.outvec' is not supported." ) with self.assertRaises(Exception) as context: ans = p.get_val('par.C1.invec', get_remote=True) self.assertEqual( str(context.exception), "Retrieval of the full distributed variable 'par.C1.invec' is not supported." ) with self.assertRaises(Exception) as context: ans = p.get_val('par.C1.outvec', get_remote=True) self.assertEqual( str(context.exception), "Retrieval of the full distributed variable 'par.C1.outvec' is not supported." )
def test_complex_step(self): prob = om.Problem() model = prob.model sub = model.add_subsystem('sub', om.ParallelGroup(), promotes=['*']) model.add_subsystem('px', om.IndepVarComp('x', 1.0), promotes=['x']) model.add_subsystem('pz', om.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', om.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', om.ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1']) model.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2']) sub.nonlinear_solver = om.BroydenSolver() sub.linear_solver = om.DirectSolver() model.linear_solver = om.DirectSolver() prob.model.add_design_var('x', lower=-100, upper=100) prob.model.add_design_var('z', lower=-100, upper=100) prob.model.add_objective('obj') prob.model.add_constraint('con1', upper=0.0) prob.model.add_constraint('con2', upper=0.0) prob.setup(check=False, force_alloc_complex=True) prob.set_solver_print(level=0) prob.run_model() totals = prob.check_totals(method='cs', out_stream=None) for key, val in totals.items(): assert_near_equal(val['rel error'][0], 0.0, 1e-7)
def test_nonlinear_analysis_error(self): prob = om.Problem() model = prob.model model.add_subsystem('px', om.IndepVarComp('x', 1.0), promotes=['x']) model.add_subsystem('pz', om.IndepVarComp('z', np.array([5.0, 2.0])), promotes=['z']) p1 = model.add_subsystem('p1', om.ParallelGroup(), promotes=['*']) p1.add_subsystem('d1a', SellarDis1withDerivatives(), promotes=['x', 'z']) p1.add_subsystem('d1b', SellarDis1withDerivatives(), promotes=['x', 'z']) p2 = model.add_subsystem('p2', om.ParallelGroup(), promotes=['*']) p2.add_subsystem('d2a', SellarDis2withDerivatives(), promotes=['z']) p2.add_subsystem('d2b', SellarDis2withDerivatives(), promotes=['z']) model.connect('d1a.y1', 'd2a.y1') model.connect('d1b.y1', 'd2b.y1') model.connect('d2a.y2', 'd1a.y2') model.connect('d2b.y2', 'd1b.y2') model.nonlinear_solver = om.NonlinearBlockGS(maxiter=2, err_on_non_converge=True) prob.setup() prob.set_solver_print(level=2) # Set one branch of Sellar close to the solution. prob.set_val('d2b.y2', 12.05848815) prob.set_val('d1b.y1', 25.58830237) # test if the analysis error is raised properly on all procs try: prob.run_model() except om.AnalysisError as err: self.assertEqual(str(err), "Solver 'NL: NLBGS' on system '' failed to converge in 2 iterations.") else: self.fail("expected AnalysisError")
def test_multi_promotes_mpi(self): p = om.Problem() par = p.model.add_subsystem('par', om.ParallelGroup()) g1 = par.add_subsystem('g1', om.Group(), promotes_inputs=['x']) g2 = par.add_subsystem('g2', om.Group(), promotes_inputs=['x']) g1.add_subsystem('C1', om.ExecComp('y = 3*x', shape=3)) g2.add_subsystem('C2', om.ExecComp('y = 2*x', shape=2)) g1.promotes('C1', inputs=['x'], src_indices=om.slicer[:, 1], src_shape=(3, 2), flat_src_indices=True) g2.promotes('C2', inputs=['x'], src_indices=[1, 5], src_shape=(3, 2), flat_src_indices=True) # we want the connection to x to have a shape of (3,2), which differs from the # shapes of either of the connected absolute inputs. par.set_input_defaults('x', src_shape=(3, 2)) # we want the auto_ivc output to have a shape of (3,3) p.model.promotes('par', inputs=['x'], src_indices=om.slicer[:, :-1], src_shape=(3, 3)) p.setup() commsize = p.comm.size inp = np.random.random((3, 3)) if commsize > 1: if p.comm.rank == 0: p.comm.bcast(inp, root=0) else: inp = p.comm.bcast(None, root=0) reduced_inp = inp[:, :-1] p.set_val('x', reduced_inp) p.run_model() if commsize == 1 or p.comm.rank == 0: assert_near_equal(p['par.g1.C1.y'], reduced_inp[:, 1] * 3.) elif commsize == 1 or p.comm.rank == 1: assert_near_equal(p['par.g2.C2.y'], reduced_inp.flatten()[[1, 5]] * 2.)
def test_prob_split_comm(self): colors = [0, 0, 1, 1] comm = MPI.COMM_WORLD.Split(colors[MPI.COMM_WORLD.rank]) # split the size 4 comm into 2 size 2 comms self.assertEqual(comm.size, 2) prob = om.Problem(comm=comm) model = prob.model p1 = model.add_subsystem('p1', om.IndepVarComp('x', 99.0)) p1.add_design_var('x', lower=-50.0, upper=50.0) par = model.add_subsystem('par', om.ParallelGroup()) c1 = par.add_subsystem('C1', om.ExecComp('y = x*x')) c2 = par.add_subsystem('C2', om.ExecComp('y = x*x')) model.add_subsystem('obj', om.ExecComp('o = a + b + 2.')) model.connect('p1.x', ['par.C1.x', 'par.C2.x']) model.connect('par.C1.y', 'obj.a') model.connect('par.C2.y', 'obj.b') model.add_objective('obj.o') prob.set_solver_print(level=0) prob.driver = om.pyOptSparseDriver() prob.driver.options['optimizer'] = OPTIMIZER prob.driver.options['print_results'] = False prob.setup() prob.run_model() failed = prob.run_driver() all_failed = comm.allgather(failed) if any(all_failed): all_msgs = comm.allgather(str( prob.driver.pyopt_solution.optInform)) for i, tup in enumerate(zip(all_failed, all_msgs)): failed, msg = tup if failed: self.fail("Optimization failed on rank %d: %s" % (i, msg)) objs = comm.allgather(prob['obj.o']) for i, obj in enumerate(objs): assert_near_equal(obj, 2.0, 1e-6)
def test_par_jac_bug(self): p = om.Problem() model = p.model par = model.add_subsystem('par', om.ParallelGroup()) par.add_subsystem('p1', SubGroup(1)) par.add_subsystem('p2', SubGroup(1)) p.setup(mode='rev') p.run_model() J1 = p.driver._compute_totals(of=['par.p1.ode.deltav_dot'], wrt=['par.p1.ode.deltav_dot'], return_format='array') Jsave = J1.copy() J2 = p.driver._compute_totals(of=['par.p1.ode.deltav_dot'], wrt=['par.p1.ode.deltav_dot'], return_format='array') self.assertLess(np.max(np.abs(J2 - Jsave)), 1e-20)
def test_multipoint2(self): p = om.Problem() par = p.model.add_subsystem('par', om.ParallelGroup()) g1 = par.add_subsystem('g1', om.Group(), promotes_inputs=['x']) g1.add_subsystem('C1', om.ExecComp('y = 3*x', shape=1)) g1.promotes('C1', inputs=['x'], src_indices=[0], src_shape=(2,)) g2 = par.add_subsystem('g2', om.Group(), promotes_inputs=['x']) g2.add_subsystem('C2', om.ExecComp('y = 2*x', shape=1)) g2.promotes('C2', inputs=['x'], src_indices=[1], src_shape=(2,)) p.model.set_input_defaults('par.x', val=[7., -5.]) p.setup() p.run_model()
def test_indivisible_error(self): prob = om.Problem() model = prob.model model.add_subsystem('par', om.ParallelGroup()) prob.driver = om.DifferentialEvolutionDriver() prob.driver.options['run_parallel'] = True prob.driver.options['procs_per_model'] = 3 with self.assertRaises(RuntimeError) as context: prob.setup() self.assertEqual(str(context.exception), "The total number of processors is not evenly divisible by the " "specified number of processors per model.\n Provide a number of " "processors that is a multiple of 3, or specify a number " "of processors per model that divides into 4.")
def setup(self): indeps = self.add_subsystem('indeps', om.IndepVarComp(), promotes=['*']) indeps.add_output('x', 1.0) indeps.add_output('z', np.array([5.0, 2.0])) cycle = self.add_subsystem('cycle', om.ParallelGroup(), promotes=['*']) cycle.add_subsystem('d1', SellarDis1(), promotes_inputs=['x', 'z', 'y2'], promotes_outputs=['y1']) cycle.add_subsystem('d2', SellarDis2(), promotes_inputs=['z', 'y1'], promotes_outputs=['y2']) # Nonlinear Block Gauss Seidel is a gradient free solver cycle.nonlinear_solver = om.NonlinearBlockGS() self.add_subsystem('obj_cmp', om.ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)', z=np.array([0.0, 0.0]), x=0.0), promotes=['x', 'z', 'y1', 'y2', 'obj']) self.add_subsystem('con_cmp1', om.ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1']) self.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2'])
def test_is_local(self): p = om.Problem() p.model.add_subsystem('indep', om.IndepVarComp('x', 1.0)) par = p.model.add_subsystem('par', om.ParallelGroup()) par.add_subsystem('C1', om.ExecComp('y=2*x')) par.add_subsystem('C2', om.ExecComp('y=3*x')) p.model.connect('indep.x', ['par.C1.x', 'par.C2.x']) with self.assertRaises(RuntimeError) as cm: loc = p.is_local('indep.x') self.assertEqual(str(cm.exception), "Problem: is_local('indep.x') was called before setup() completed.") with self.assertRaises(RuntimeError) as cm: loc = p.is_local('par.C1') self.assertEqual(str(cm.exception), "Problem: is_local('par.C1') was called before setup() completed.") with self.assertRaises(RuntimeError) as cm: loc = p.is_local('par.C1.y') self.assertEqual(str(cm.exception), "Problem: is_local('par.C1.y') was called before setup() completed.") with self.assertRaises(RuntimeError) as cm: loc = p.is_local('par.C1.x') self.assertEqual(str(cm.exception), "Problem: is_local('par.C1.x') was called before setup() completed.") p.setup() p.final_setup() self.assertTrue(p.is_local('indep'), 'indep should be local') self.assertTrue(p.is_local('indep.x'), 'indep.x should be local') if p.comm.rank == 0: self.assertTrue(p.is_local('par.C1'), 'par.C1 should be local') self.assertTrue(p.is_local('par.C1.x'), 'par.C1.x should be local') self.assertTrue(p.is_local('par.C1.y'), 'par.C1.y should be local') self.assertFalse(p.is_local('par.C2'), 'par.C1 should be remote') self.assertFalse(p.is_local('par.C2.x'), 'par.C1.x should be remote') self.assertFalse(p.is_local('par.C2.y'), 'par.C1.y should be remote') else: self.assertFalse(p.is_local('par.C1'), 'par.C1 should be remote') self.assertFalse(p.is_local('par.C1.x'), 'par.C1.x should be remote') self.assertFalse(p.is_local('par.C1.y'), 'par.C1.y should be remote') self.assertTrue(p.is_local('par.C2'), 'par.C2 should be local') self.assertTrue(p.is_local('par.C2.x'), 'par.C2.x should be local') self.assertTrue(p.is_local('par.C2.y'), 'par.C2.y should be local')
def setup(self): """ Setup the Trajectory Group. """ super(Trajectory, self).setup() if self.parameter_options: self._setup_parameters() phases_group = self.add_subsystem('phases', subsys=om.ParallelGroup()) for name, phs in self._phases.items(): phases_group.add_subsystem(name, phs, **self._phase_add_kwargs[name]) if self._linkages: self._setup_linkages()
def test_option_procs_per_model(self): prob = om.Problem() model = prob.model model.add_subsystem('p1', om.IndepVarComp('xC', 2.5)) model.add_subsystem('p2', om.IndepVarComp('xI', 3.0)) par = model.add_subsystem('par', om.ParallelGroup()) par.add_subsystem('comp1', Branin()) par.add_subsystem('comp2', Branin()) model.connect('p2.xI', 'par.comp1.x0') model.connect('p1.xC', 'par.comp1.x1') model.connect('p2.xI', 'par.comp2.x0') model.connect('p1.xC', 'par.comp2.x1') model.add_subsystem('comp', om.ExecComp('f = f1 + f2')) model.connect('par.comp1.f', 'comp.f1') model.connect('par.comp2.f', 'comp.f2') model.add_design_var('p2.xI', lower=-5.0, upper=10.0) model.add_design_var('p1.xC', lower=0.0, upper=15.0) model.add_objective('comp.f') cma_es = CMAES() cma_es.options['popsize'] = 25 cma_es.options['verbose'] = -9 # silence output prob.driver = GenericDriver(algorithm=cma_es) prob.driver.options['run_parallel'] = True prob.driver.options['procs_per_model'] = 2 prob.setup() prob.run_driver() # Optimal solution from DifferentialEvolutionDriver: # comp.f [0.80220303] # p2.xI [3.11628575] # p1.xC [2.28300608] if extra_prints: print('comp.f', prob.get_val('comp.f')) print('p2.xI', prob.get_val('p2.xI')) print('p1.xC', prob.get_val('p1.xC'))
def test_distributed_norm_parallel_group(self): prob = om.Problem() model = prob.model comp = om.IndepVarComp() comp.add_output('v1', val=np.array([3.0, 5.0, 8.0])) comp.add_output('v2', val=np.array([17.0])) model.add_subsystem('des_vars', comp) sub = model.add_subsystem('pp', om.ParallelGroup()) sub.add_subsystem( 'calc1', om.ExecComp('y = 2.0*x', x=np.ones((3, )), y=np.ones((3, )))) sub.add_subsystem( 'calc2', om.ExecComp('y = 5.0*x', x=np.ones((3, )), y=np.ones((3, )))) sub.add_subsystem( 'calc3', om.ExecComp('y = 7.0*x', x=np.ones((3, )), y=np.ones((3, )))) model.connect('des_vars.v1', 'pp.calc1.x') model.connect('des_vars.v1', 'pp.calc2.x') model.connect('des_vars.v1', 'pp.calc3.x') model.linear_solver = om.LinearBlockGS() prob.setup() prob.run_model() vec = prob.model._vectors['output']['nonlinear'] norm_val = vec.get_norm() assert_near_equal(norm_val, 89.61584681293817, 1e-10) J = prob.compute_totals(of=['pp.calc1.y', 'pp.calc2.y', 'pp.calc3.y'], wrt=['des_vars.v1']) vec = prob.model._vectors['output']['linear'] norm_val = vec.get_norm() assert_near_equal(norm_val, 8.888194417315589, 1e-10) # test petsc dot while we're at it vec.set_const(3.) vec2 = prob.model._vectors['residual']['linear'] vec2.set_const(4.) assert_near_equal(vec.dot(vec2), 12. * 13, 1e-10)
def __init__(self): super(FanInGrouped2, self).__init__() p1 = self.add_subsystem('p1', om.IndepVarComp('x', 1.0)) p2 = self.add_subsystem('p2', om.IndepVarComp('x', 1.0)) self.sub = self.add_subsystem('sub', om.ParallelGroup()) self.sub.add_subsystem('c1', om.ExecComp(['y=-2.0*x'])) self.sub.add_subsystem('c2', om.ExecComp(['y=5.0*x'])) self.add_subsystem('c3', om.ExecComp(['y=3.0*x1+7.0*x2'])) self.connect("sub.c1.y", "c3.x1") self.connect("sub.c2.y", "c3.x2") self.connect("p1.x", "sub.c1.x") self.connect("p2.x", "sub.c2.x")
def test_is_local(self): p = om.Problem() p.model.add_subsystem('indep', om.IndepVarComp('x', 1.0)) par = p.model.add_subsystem('par', om.ParallelGroup()) par.add_subsystem('C1', om.ExecComp('y=2*x')) par.add_subsystem('C2', om.ExecComp('y=3*x')) p.model.connect('indep.x', ['par.C1.x', 'par.C2.x']) with self.assertRaisesRegex(RuntimeError, "Problem .*: is_local\('indep\.x'\) was called before setup\(\) completed\."): loc = p.is_local('indep.x') with self.assertRaisesRegex(RuntimeError, "Problem .*: is_local\('par\.C1'\) was called before setup\(\) completed\."): loc = p.is_local('par.C1') with self.assertRaisesRegex(RuntimeError, "Problem .*: is_local\('par\.C1\.y'\) was called before setup\(\) completed\."): loc = p.is_local('par.C1.y') with self.assertRaisesRegex(RuntimeError, "Problem .*: is_local\('par\.C1\.x'\) was called before setup\(\) completed\."): loc = p.is_local('par.C1.x') p.setup() p.final_setup() self.assertTrue(p.is_local('indep'), 'indep should be local') self.assertTrue(p.is_local('indep.x'), 'indep.x should be local') if p.comm.rank == 0: self.assertTrue(p.is_local('par.C1'), 'par.C1 should be local') self.assertTrue(p.is_local('par.C1.x'), 'par.C1.x should be local') self.assertTrue(p.is_local('par.C1.y'), 'par.C1.y should be local') self.assertFalse(p.is_local('par.C2'), 'par.C1 should be remote') self.assertFalse(p.is_local('par.C2.x'), 'par.C1.x should be remote') self.assertFalse(p.is_local('par.C2.y'), 'par.C1.y should be remote') else: self.assertFalse(p.is_local('par.C1'), 'par.C1 should be remote') self.assertFalse(p.is_local('par.C1.x'), 'par.C1.x should be remote') self.assertFalse(p.is_local('par.C1.y'), 'par.C1.y should be remote') self.assertTrue(p.is_local('par.C2'), 'par.C2 should be local') self.assertTrue(p.is_local('par.C2.x'), 'par.C2.x should be local') self.assertTrue(p.is_local('par.C2.y'), 'par.C2.y should be local')