def test_implicit(self): prob = Problem() model = prob.model model.add_subsystem('indep', IndepVarComp('y', 1.0)) model.add_subsystem('statecomp', StateConnection()) model.connect('indep.y', 'statecomp.y2_actual') # perform setup with checks but don't run model testlogger = TestLogger() prob.setup(check=True, logger=testlogger) prob.final_setup() # should trigger warnings due to having states without solves self.assertTrue(testlogger.contains('warning', "StateConnection 'statecomp' contains implicit variables, " "but does not have an iterative nonlinear solver and does not " "implement 'solve_nonlinear'.")) self.assertTrue(testlogger.contains('warning', "StateConnection 'statecomp' contains implicit variables, " "but does not have an iterative linear solver and does not " "implement 'solve_linear'."))
def test_component(self, name, comp_class): try: comp = comp_class(n) except TypeError: try: comp = comp_class() except TypeError: comp = comp_class(n, 300) self.assertTrue(isinstance(comp, comp_class), 'Could not create instance of %s' % comp_class.__name__) prob = Problem(comp) prob.setup() prob.final_setup() inputs = comp.list_inputs(out_stream=None) outputs = comp.list_outputs(out_stream=None) for var, meta in inputs: if var in setd: prob[var] = setd[var] comp.h = h # some components need this prob.run_model() for var, meta in outputs: if var in setd: tval = setd[var] assert(np.linalg.norm(tval - prob[var]) / np.linalg.norm(tval) < 1e-3), \ '%s: Expected\n%s\nbut got\n%s' % (var, str(tval), str(prob[var]))
def _build_model(nsubs, min_procs=None, max_procs=None, weights=None, top=None, mode='fwd'): p = Problem() if min_procs is None: min_procs = [1]*nsubs if max_procs is None: max_procs = [None]*nsubs if weights is None: weights = [1.0]*nsubs model = p.model #import wingdbstub model.add_subsystem('indep', IndepVarComp('x', 1.0)) par = model.add_subsystem('par', ParallelGroup()) for i in range(nsubs): par.add_subsystem("C%d" % i, ExecComp("y=2.0*x"), min_procs=min_procs[i], max_procs=max_procs[i], proc_weight=weights[i]) model.connect('indep.x', 'par.C%d.x' % i) s_sum = '+'.join(['x%d' % i for i in range(nsubs)]) model.add_subsystem('objective', ExecComp("y=%s" % s_sum)) for i in range(nsubs): model.connect('par.C%d.y' % i, 'objective.x%d' % i) model.add_design_var('indep.x') model.add_objective('objective.y') p.setup(vector_class=vector_class, mode=mode, check=False) p.final_setup() return p
def test_implicit_iter_subgroup(self): prob = Problem() model = prob.model model.add_subsystem('indep', IndepVarComp('y', 1.0)) model.add_subsystem("G1", Group()) model.G1.add_subsystem('statecomp', StateConnection(), promotes_inputs=['y2_actual']) model.connect('indep.y', 'G1.y2_actual') # provide iterative solvers for implicit group model.linear_solver = LinearBlockGS() model.nonlinear_solver = NonlinearBlockGS() # perform setup with checks but don't run model testlogger = TestLogger() prob.setup(check=True, logger=testlogger) prob.final_setup() # should not trigger solver warning because iterates in parent group # but will have recorder warning warnings = testlogger.get('warning') self.assertEqual(len(warnings), 1)
def test_cycle_direct(self): prob = Problem() model = prob.model C1 = model.add_subsystem("C1", ExecComp('y=2.0*x')) C2 = model.add_subsystem("C2", ExecComp('y=2.0*x')) C3 = model.add_subsystem("C3", ExecComp('y=2.0*x')) model.connect('C1.y','C2.x') model.connect('C2.y','C3.x') model.connect('C3.y','C1.x') # provide direct linear solver and iterative nonlinear solver model.linear_solver = DirectSolver() model.nonlinear_solver = NonlinearBlockGS() # perform setup with checks but don't run model testlogger = TestLogger() prob.setup(check=True, logger=testlogger) prob.final_setup() # should not trigger any solver warnings warnings = testlogger.get('warning') # but one warning exists due to problem not having a recorder self.assertEqual(len(warnings), 1)
def test_implicit_iter_subgroups(self): prob = Problem() model = prob.model model.add_subsystem('indep', IndepVarComp('y', 1.0)) model.add_subsystem("G1", Group()) model.G1.add_subsystem('statecomp1', StateConnection(), promotes_inputs=['y2_actual']) model.add_subsystem("G2", Group()) model.G2.add_subsystem('statecomp2', StateConnection(), promotes_inputs=['y2_actual']) model.connect('indep.y', ['G1.y2_actual', 'G2.y2_actual']) # do not provide iterative linear solver for G2 model.nonlinear_solver = NonlinearBlockGS() model.G1.linear_solver = LinearBlockGS() # perform setup with checks but don't run model testlogger = TestLogger() prob.setup(check=True, logger=testlogger) prob.final_setup() # should trigger a linear solver warning only for group 2 self.assertTrue(testlogger.contains('warning', "StateConnection 'G2.statecomp2' contains implicit " "variables, but does not have an iterative linear solver " "and does not implement 'solve_linear'."))
def test_solve_linear_scipy_maxiter(self): """Verify that ScipyKrylov abides by the 'maxiter' option.""" group = TestImplicitGroup(lnSolverClass=self.linear_solver_class) group.linear_solver.options['maxiter'] = 2 p = Problem(group) p.setup(check=False) p.set_solver_print(level=0) # Conclude setup but don't run model. p.final_setup() d_inputs, d_outputs, d_residuals = group.get_linear_vectors() # forward d_residuals.set_const(1.0) d_outputs.set_const(0.0) group.run_solve_linear(['linear'], 'fwd') self.assertTrue(group.linear_solver._iter_count == 2) # reverse d_outputs.set_const(1.0) d_residuals.set_const(0.0) group.run_solve_linear(['linear'], 'rev') self.assertTrue(group.linear_solver._iter_count == 2)
def test_cycle_iter_subgroup(self): prob = Problem() model = prob.model G1 = model.add_subsystem("G1", Group()) C1 = G1.add_subsystem("C1", ExecComp('y=2.0*x')) C2 = G1.add_subsystem("C2", ExecComp('y=2.0*x')) C3 = G1.add_subsystem("C3", ExecComp('y=2.0*x')) G1.connect('C1.y','C2.x') G1.connect('C2.y','C3.x') G1.connect('C3.y','C1.x') # provide iterative solvers to handle cycle model.linear_solver = LinearBlockGS() model.nonlinear_solver = NonlinearBlockGS() # perform setup with checks but don't run model testlogger = TestLogger() prob.setup(check=True, logger=testlogger) prob.final_setup() # should not trigger solver warning because iterates in parent group # but one warning exists due to problem not having a recorder warnings = testlogger.get('warning') self.assertEqual(len(warnings), 1)
def test_solve_linear_ksp_gmres(self): """Solve implicit system with PETScKrylov using 'gmres' method.""" group = TestImplicitGroup(lnSolverClass=PETScKrylov, use_varsets=False) group.linear_solver.options['ksp_type'] = 'gmres' p = Problem(group) p.setup(vector_class=PETScVector, check=False) p.set_solver_print(level=0) # Conclude setup but don't run model. p.final_setup() d_inputs, d_outputs, d_residuals = group.get_linear_vectors() # forward d_residuals.set_const(1.0) d_outputs.set_const(0.0) group.run_solve_linear(['linear'], 'fwd') output = d_outputs._data assert_rel_error(self, output[0], group.expected_solution[0], 1e-15) # reverse d_outputs.set_const(1.0) d_residuals.set_const(0.0) group.run_solve_linear(['linear'], 'rev') output = d_residuals._data assert_rel_error(self, output[0], group.expected_solution[0], 1e-15)
def test_solve_linear_scipy(self): """Solve implicit system with ScipyKrylov.""" # use ScipyIterativeSolver here to check for deprecation warning and verify that the deprecated # class still gets the right answer without duplicating this test. msg = "ScipyIterativeSolver is deprecated. Use ScipyKrylov instead." with assert_warning(DeprecationWarning, msg): group = TestImplicitGroup(lnSolverClass=lambda : ScipyIterativeSolver(solver=self.linear_solver_name)) p = Problem(group) p.setup(check=False) p.set_solver_print(level=0) # Conclude setup but don't run model. p.final_setup() d_inputs, d_outputs, d_residuals = group.get_linear_vectors() # forward d_residuals.set_const(1.0) d_outputs.set_const(0.0) group.run_solve_linear(['linear'], 'fwd') output = d_outputs._data assert_rel_error(self, output, group.expected_solution, 1e-15) # reverse d_outputs.set_const(1.0) d_residuals.set_const(0.0) group.run_solve_linear(['linear'], 'rev') output = d_residuals._data assert_rel_error(self, output, group.expected_solution, 1e-15)
def test_list_states_allprocs(self): class StateComp(ImplicitComponent): def initialize(self): self.mtx = np.array([ [0.99, 0.01], [0.01, 0.99], ]) def setup(self): self.add_input('rhs', val=np.ones(2)) self.add_output('x', val=np.zeros(2)) self.declare_partials(of='*', wrt='*') def apply_nonlinear(self, inputs, outputs, residuals): residuals['x'] = self.mtx.dot(outputs['x']) - inputs['rhs'] def solve_nonlinear(self, inputs, outputs): outputs['x'] = np.linalg.solve(self.mtx, inputs['rhs']) p = Problem(model=ParallelGroup()) p.model.add_subsystem('C1', StateComp()) p.model.add_subsystem('C2', StateComp()) p.model.add_subsystem('C3', ExecComp('y=2.0*x')) p.model.add_subsystem('C4', StateComp()) p.setup() p.final_setup() self.assertEqual(p.model._list_states_allprocs(), ['C1.x', 'C2.x', 'C4.x'])
def setup(self, compname, inputs, state0): # create instance of component type try: comp = eval('%s(NTIME)' % compname) except TypeError: try: comp = eval('%s()' % compname) except TypeError: comp = eval('%s(NTIME, 300)' % compname) # collect metadata for component inputs prob = Problem(comp) prob.setup() prob.final_setup() self.inputs_dict = {} for name, meta in prob.model.list_inputs(units=True, out_stream=None): self.inputs_dict[name.split('.')[-1]] = meta # create independent vars for each input, initialized with random values indep = IndepVarComp() for item in inputs + state0: shape = self.inputs_dict[item]['value'].shape units = self.inputs_dict[item]['units'] indep.add_output(item, np.random.random(shape), units=units) # setup problem for test self.prob = Problem() self.prob.model.add_subsystem('indep', indep, promotes=['*']) self.prob.model.add_subsystem('comp', comp, promotes=['*']) self.prob.setup()
def test_noncontiguous_idxs(self): # take even input indices in 0 rank and odd ones in 1 rank size = 11 p = Problem(model=Group()) top = p.model C1 = top.add_subsystem("C1", InOutArrayComp(size)) C2 = top.add_subsystem("C2", DistribNoncontiguousComp(size)) C3 = top.add_subsystem("C3", DistribGatherComp(size)) top.connect('C1.outvec', 'C2.invec') top.connect('C2.outvec', 'C3.invec') p.setup(check=False) # Conclude setup but don't run model. p.final_setup() C1._inputs['invec'] = np.array(range(size), float) p.run_model() if MPI: if self.comm.rank == 0: self.assertTrue(all(C2._outputs['outvec'] == np.array(list(take_nth(0, 2, range(size))), 'f')*4)) else: self.assertTrue(all(C2._outputs['outvec'] == np.array(list(take_nth(1, 2, range(size))), 'f')*4)) full_list = list(take_nth(0, 2, range(size))) + list(take_nth(1, 2, range(size))) self.assertTrue(all(C3._outputs['outvec'] == np.array(full_list, 'f')*4)) else: self.assertTrue(all(C2._outputs['outvec'] == C1._outputs['outvec']*2.)) self.assertTrue(all(C3._outputs['outvec'] == C2._outputs['outvec']))
def test_overlapping_inputs_idxs(self): # distrib comp with src_indices that overlap, i.e. the same # entries are distributed to multiple processes size = 11 p = Problem(model=Group()) top = p.model C1 = top.add_subsystem("C1", InOutArrayComp(size)) C2 = top.add_subsystem("C2", DistribOverlappingInputComp(size)) top.connect('C1.outvec', 'C2.invec') p.setup(check=False) # Conclude setup but don't run model. p.final_setup() C1._inputs['invec'] = np.array(range(size, 0, -1), float) p.run_model() self.assertTrue(all(C2._outputs['outvec'][:4] == np.array(range(size, 0, -1), float)[:4]*4)) self.assertTrue(all(C2._outputs['outvec'][8:] == np.array(range(size, 0, -1), float)[8:]*4)) # overlapping part should be double size of the rest self.assertTrue(all(C2._outputs['outvec'][4:8] == np.array(range(size, 0, -1), float)[4:8]*8))
def test_multi_cycles(self): p = Problem() root = p.model root.add_subsystem("indep", IndepVarComp('x', 1.0)) def make_cycle(root, start, end): # systems within a cycle will be declared out of order, but # should not be reported since they're internal to a cycle. for i in range(end, start-1, -1): root.add_subsystem("C%d" % i, MyComp()) for i in range(start, end): root.connect("C%d.y" % i, "C%d.a" % (i+1)) root.connect("C%d.y" % end, "C%d.a" % start) G1 = root.add_subsystem('G1', Group()) make_cycle(G1, 1, 3) G1.add_subsystem("N1", MyComp()) make_cycle(G1, 11, 13) G1.add_subsystem("N2", MyComp()) make_cycle(G1, 21, 23) G1.add_subsystem("N3", MyComp()) G1.connect("N1.z", "C12.b") G1.connect("C13.z", "N2.b") G1.connect("N2.z", "C21.b") G1.connect("C23.z", "N3.b") G1.connect("N3.z", "C2.b") G1.connect("C11.z", "C3.b") # set iterative solvers since we have cycles root.linear_solver = LinearBlockGS() root.nonlinear_solver = NonlinearBlockGS() testlogger = TestLogger() p.setup(check=True, logger=testlogger) p.final_setup() expected_warning_1 = ( "The following systems are executed out-of-order:\n" " System 'G1.C2' executes out-of-order with respect to its source systems ['G1.N3']\n" " System 'G1.C3' executes out-of-order with respect to its source systems ['G1.C11']\n" ) testlogger.find_in('warning', expected_warning_1)
def test_dot(self): p = Problem() comp = IndepVarComp() comp.add_output('v1', val=1.0) comp.add_output('v2', val=2.0) p.model.add_subsystem('des_vars', comp, promotes=['*']) p.setup() p.final_setup() new_vec = p.model._outputs._clone() new_vec.set_const(3.) self.assertEqual(new_vec.dot(p.model._outputs), 9.)
def test_iter(self): p = Problem() comp = IndepVarComp() comp.add_output('v1', val=1.0) comp.add_output('v2', val=2.0) p.model.add_subsystem('des_vars', comp, promotes=['*']) p.setup() p.final_setup() outputs = [n for n in p.model._outputs] expected = ['des_vars.v1', 'des_vars.v2'] self.assertListEqual(outputs, expected, msg='Iter is not returning the expected names')
def test_keys(self): p = Problem() comp = IndepVarComp() comp.add_output('v1', val=1.0) comp.add_output('v2', val=2.0) p.model.add_subsystem('des_vars', comp, promotes=['*']) p.setup() p.final_setup() keys = sorted(p.model._outputs.keys()) expected = ['des_vars.v1', 'des_vars.v2'] self.assertListEqual(keys, expected, msg='keys() is not returning the expected names')
def test_wrong_out_format(self): """Incorrect output format error.""" filename = 'xdsm_wrong_format' # this name is needed for XDSMjs prob = Problem() prob.model = SellarNoDerivatives() prob.setup(check=False) prob.final_setup() # no output checking, just make sure no exceptions raised with self.assertRaises(ValueError): write_xdsm(prob, filename=filename, out_format='jpg', subs=(), show_browser=SHOW)
def test_dataflow_multi_level(self): p = Problem() root = p.model root.add_subsystem("indep", IndepVarComp('x', 1.0)) G1 = root.add_subsystem("G1", Group()) G1.add_subsystem("C1", MyComp()) G1.add_subsystem("C2", MyComp()) root.add_subsystem("C3", MyComp()) root.add_subsystem("C4", MyComp()) root.connect("C4.y", "G1.C2.a") root.connect("C4.y", "C3.a") root.connect("G1.C2.y", "G1.C1.a") root.connect("G1.C1.y", "C4.a") # make sure no system has dangling inputs so we avoid that warning root.connect("indep.x", "G1.C1.b") root.connect("indep.x", "G1.C2.b") root.connect("indep.x", "C3.b") root.connect("indep.x", "C4.b") # set iterative solvers since we have cycles root.linear_solver = LinearBlockGS() root.nonlinear_solver = NonlinearBlockGS() testlogger = TestLogger() p.setup(check=['cycles', 'out_of_order'], logger=testlogger) p.final_setup() expected_info = ( "The following groups contain cycles:\n" " Group '' has the following cycles: [['G1', 'C4']]\n" ) expected_warning = ( "The following systems are executed out-of-order:\n" " System 'C3' executes out-of-order with respect to its source systems ['C4']\n" " System 'G1.C1' executes out-of-order with respect to its source systems ['G1.C2']\n" ) testlogger.find_in('info', expected_info) testlogger.find_in('warning', expected_warning) # test comps_only cycle check graph = root.compute_sys_graph(comps_only=True) sccs = [sorted(s) for s in get_sccs_topo(graph) if len(s) > 1] self.assertEqual([['C4', 'G1.C1', 'G1.C2']], sccs)
def test_custom_writer(self): from openmdao.devtools.xdsm_viewer.xdsm_writer import XDSMjsWriter class CustomWriter(XDSMjsWriter): """Customized XDSM writer, based on the XDSMjs writer.""" @staticmethod def format_block(names, **kwargs): """This method is overwritten, to implement some different formatting.""" return [name.upper() for name in names] prob = Problem() prob.model = SellarNoDerivatives() prob.setup(check=False) prob.final_setup() my_writer = CustomWriter() filename = 'xdsm_custom_writer' # this name is needed for XDSMjs # Write output write_xdsm(prob, filename=filename, writer=my_writer, show_browser=SHOW) # Check if file was created self.assertTrue( os.path.isfile('.'.join([filename, my_writer.extension]))) # Check that error is raised in case of wrong writer type filename = 'xdsm_custom_writer2' # this name is needed for XDSMjs with self.assertRaises(TypeError): # Wrong type passed for writer write_xdsm(prob, filename=filename, writer=1, subs=(), show_browser=SHOW) # Check warning, if settings for custom writer are not found my_writer2 = CustomWriter(name='my_writer') filename = 'xdsm_custom_writer3' msg = 'Writer name "my_writer" not found, there will be no character ' \ 'substitutes used. Add "my_writer" to your settings, or provide a tuple for' \ 'character substitutes.' # Write output with assert_warning(Warning, msg): write_xdsm(prob, filename=filename, writer=my_writer2, show_browser=SHOW)
def test_dataflow_multi_level(self): p = Problem(model=Group()) root = p.model indep = root.add_subsystem("indep", IndepVarComp('x', 1.0)) G1 = root.add_subsystem("G1", Group()) C1 = G1.add_subsystem("C1", MyComp()) C2 = G1.add_subsystem("C2", MyComp()) C3 = root.add_subsystem("C3", MyComp()) C4 = root.add_subsystem("C4", MyComp()) root.connect("C4.y", "G1.C2.a") root.connect("C4.y", "C3.a") root.connect("G1.C2.y", "G1.C1.a") root.connect("G1.C1.y", "C4.a") # make sure no system has dangling inputs so we avoid that warning root.connect("indep.x", "G1.C1.b") root.connect("indep.x", "G1.C2.b") root.connect("indep.x", "C3.b") root.connect("indep.x", "C4.b") testlogger = TestLogger() p.setup(check=True, logger=testlogger) # Conclude setup but don't run model. p.final_setup() warnings = testlogger.get('warning') self.assertEqual(len(warnings), 2) info = testlogger.get('info') self.assertEqual(info[0], "Group '' has the following cycles: [['G1', 'C4']]") self.assertEqual( warnings[0], "System 'C3' executes out-of-order with respect to its source systems ['C4']" ) self.assertEqual( warnings[1], "System 'G1.C1' executes out-of-order with respect to its source systems ['G1.C2']" ) # test comps_only cycle check graph = root.compute_sys_graph(comps_only=True) sccs = [sorted(s) for s in get_sccs_topo(graph) if len(s) > 1] self.assertEqual([['C4', 'G1.C1', 'G1.C2']], sccs)
def test_parallel(self): from openmdao.api import ParallelGroup, NonlinearBlockGS class SellarMDA(Group): """ Group containing the Sellar MDA. """ def setup(self): indeps = self.add_subsystem('indeps', IndepVarComp(), promotes=['*']) indeps.add_output('x', 1.0) indeps.add_output('z', np.array([5.0, 2.0])) cycle = self.add_subsystem('cycle', 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 = NonlinearBlockGS() self.add_subsystem('obj_cmp', 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', ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1']) self.add_subsystem('con_cmp2', ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2']) filename = 'xdsmjs_parallel' out_format = 'html' prob = Problem(model=SellarMDA()) model = prob.model prob.driver = ScipyOptimizeDriver() model.add_design_var('z', lower=np.array([-10.0, 0.0]), upper=np.array([10.0, 10.0]), indices=np.arange(2, dtype=int)) model.add_design_var('x', lower=0.0, upper=10.0) model.add_objective('obj') model.add_constraint('con1', equals=np.zeros(1)) model.add_constraint('con2', upper=0.0) prob.setup(check=False) prob.final_setup() # Write output write_xdsm(prob, filename=filename, out_format=out_format, quiet=QUIET, show_browser=SHOW, show_parallel=True) # Check if file was created self.assertTrue(os.path.isfile('.'.join([filename, out_format])))
def test_prob_getitem_err(self): size = 3 p = Problem(model=Group()) top = p.model par = top.add_subsystem('par', ParallelGroup()) C1 = par.add_subsystem("C1", DistribInputDistribOutputComp(arr_size=size)) C2 = par.add_subsystem("C2", DistribInputDistribOutputComp(arr_size=size)) p.setup(check=False) # 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_set_checks_shape(self): model = Group() indep = model.add_subsystem('indep', IndepVarComp()) indep.add_output('num') indep.add_output('arr', shape=(10, 1)) prob = Problem(model) prob.setup() msg = "Incompatible shape for '.*': Expected (.*) but got (.*)" # check valid scalar value new_val = -10. prob['indep.num'] = new_val assert_rel_error(self, prob['indep.num'], new_val, 1e-10) # check bad scalar value bad_val = -10*np.ones((10)) prob['indep.num'] = bad_val with assertRaisesRegex(self, ValueError, msg): prob.final_setup() prob._initial_condition_cache = {} # check assign scalar to array arr_val = new_val*np.ones((10, 1)) prob['indep.arr'] = new_val prob.final_setup() assert_rel_error(self, prob['indep.arr'], arr_val, 1e-10) # check valid array value new_val = -10*np.ones((10, 1)) prob['indep.arr'] = new_val assert_rel_error(self, prob['indep.arr'], new_val, 1e-10) # check bad array value bad_val = -10*np.ones((10)) with assertRaisesRegex(self, ValueError, msg): prob['indep.arr'] = bad_val # check valid list value new_val = new_val.tolist() prob['indep.arr'] = new_val assert_rel_error(self, prob['indep.arr'], new_val, 1e-10) # check bad list value bad_val = bad_val.tolist() with assertRaisesRegex(self, ValueError, msg): prob['indep.arr'] = bad_val
def test_sin_metamodel(self): # create a MetaModelUnStructuredComp for sine and add it to a Problem sin_mm = MetaModelUnStructuredComp() sin_mm.add_input('x', 0.) sin_mm.add_output('f_x', 0.) prob = Problem() prob.model.add_subsystem('sin_mm', sin_mm) # check that missing surrogate is detected in check_config testlogger = TestLogger() prob.setup(check=True, logger=testlogger) # Conclude setup but don't run model. prob.final_setup() msg = ("No default surrogate model is defined and the " "following outputs do not have a surrogate model:\n" "['f_x']\n" "Either specify a default_surrogate, or specify a " "surrogate model for all outputs.") self.assertEqual(len(testlogger.get('error')), 1) self.assertTrue(msg in testlogger.get('error')[0]) # check that output with no specified surrogate gets the default sin_mm.options['default_surrogate'] = FloatKrigingSurrogate() prob.setup(check=False) surrogate = sin_mm._metadata('f_x').get('surrogate') self.assertTrue(isinstance(surrogate, FloatKrigingSurrogate), 'sin_mm.f_x should get the default surrogate') # check error message when no training data is provided with self.assertRaises(RuntimeError) as cm: prob.run_model() msg = ( "MetaModelUnStructuredComp: The following training data sets must be " "provided as options for sin_mm: ['train:x', 'train:f_x']") self.assertEqual(str(cm.exception), msg) # train the surrogate and check predicted value sin_mm.options['train:x'] = np.linspace(0, 10, 20) sin_mm.options['train:f_x'] = .5 * np.sin(sin_mm.options['train:x']) prob['sin_mm.x'] = 2.1 prob.run_model() assert_rel_error(self, prob['sin_mm.f_x'], .5 * np.sin(prob['sin_mm.x']), 1e-4)
def test_multi_cycles(self): p = Problem(model=Group()) root = p.model indep = root.add_subsystem("indep", IndepVarComp('x', 1.0)) def make_cycle(root, start, end): # systems within a cycle will be declared out of order, but # should not be reported since they're internal to a cycle. for i in range(end, start-1, -1): root.add_subsystem("C%d" % i, MyComp()) for i in range(start, end): root.connect("C%d.y" % i, "C%d.a" % (i+1)) root.connect("C%d.y" % end, "C%d.a" % start) make_cycle(root, 1, 3) root.add_subsystem("N1", MyComp()) make_cycle(root, 11, 13) root.add_subsystem("N2", MyComp()) make_cycle(root, 21, 23) root.add_subsystem("N3", MyComp()) root.connect("N1.z", "C12.b") root.connect("C13.z", "N2.b") root.connect("N2.z", "C21.b") root.connect("C23.z", "N3.b") root.connect("N3.z", "C2.b") root.connect("C11.z", "C3.b") testlogger = TestLogger() p.setup(logger=testlogger) # Conclude setup but don't run model. p.final_setup() warnings = testlogger.get('warning') self.assertEqual(len(warnings), 4) self.assertTrue("The following inputs are not connected:" in warnings[0]) self.assertEqual(warnings[1], "Group '' has the following cycles: [['C11', 'C12', 'C13'], ['C21', 'C22', 'C23'], ['C1', 'C2', 'C3']]") self.assertEqual(warnings[2], "System 'C2' executes out-of-order with respect to its source systems ['N3']") self.assertEqual(warnings[3], "System 'C3' executes out-of-order with respect to its source systems ['C11']")
def test_pyxdsm_pdf(self): """ Makes an XDSM of the Sphere test case. It also adds a design variable, constraint and objective. """ class Rosenbrock(ExplicitComponent): def __init__(self, problem): super(Rosenbrock, self).__init__() self.problem = problem self.counter = 0 def setup(self): self.add_input('x', np.array([1.5, 1.5])) self.add_output('f', 0.0) self.declare_partials('f', 'x', method='fd', form='central', step=1e-4) def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): x = inputs['x'] outputs['f'] = sum(x**2) x0 = np.array([1.2, 1.5]) filename = 'xdsm2' prob = Problem() indeps = prob.model.add_subsystem('indeps', IndepVarComp(problem=prob), promotes=['*']) indeps.add_output('x', list(x0)) prob.model.add_subsystem('sphere', Rosenbrock(problem=prob), promotes=['*']) prob.model.add_subsystem('con', ExecComp('c=sum(x)', x=np.ones(2)), promotes=['*']) prob.driver = ScipyOptimizeDriver() prob.model.add_design_var('x') prob.model.add_objective('f') prob.model.add_constraint('c', lower=1.0) prob.setup(check=False) prob.final_setup() # requesting 'pdf', but if 'pdflatex' is not found we will only get 'tex' pdflatex = find_executable('pdflatex') # Write output write_xdsm(prob, filename=filename, out_format='pdf', show_browser=SHOW, quiet=QUIET) # Check if file was created self.assertTrue(os.path.isfile('.'.join([filename, 'tex']))) # Check if PDF was created (only if pdflatex is installed) self.assertTrue(not pdflatex or os.path.isfile('.'.join([filename, 'pdf'])))
def test_sin_metamodel(self): # create a MetaModelUnStructured for sine and add it to a Problem sin_mm = MetaModelUnStructured() sin_mm.add_input('x', 0.) sin_mm.add_output('f_x', 0.) prob = Problem() prob.model.add_subsystem('sin_mm', sin_mm) # check that missing surrogate is detected in check_config testlogger = TestLogger() prob.setup(check=True, logger=testlogger) # Conclude setup but don't run model. prob.final_setup() msg = ("No default surrogate model is defined and the " "following outputs do not have a surrogate model:\n" "['f_x']\n" "Either specify a default_surrogate, or specify a " "surrogate model for all outputs.") self.assertEqual(len(testlogger.get('error')), 1) self.assertTrue(msg in testlogger.get('error')[0]) # check that output with no specified surrogate gets the default sin_mm.default_surrogate = FloatKrigingSurrogate() prob.setup(check=False) surrogate = sin_mm._metadata('f_x').get('surrogate') self.assertTrue(isinstance(surrogate, FloatKrigingSurrogate), 'sin_mm.f_x should get the default surrogate') # check error message when no training data is provided with self.assertRaises(RuntimeError) as cm: prob.run_model() msg = ("MetaModelUnStructured: The following training data sets must be " "provided as metadata for sin_mm: ['train:x', 'train:f_x']") self.assertEqual(str(cm.exception), msg) # train the surrogate and check predicted value sin_mm.metadata['train:x'] = np.linspace(0,10,20) sin_mm.metadata['train:f_x'] = .5*np.sin(sin_mm.metadata['train:x']) prob['sin_mm.x'] = 2.1 prob.run_model() assert_rel_error(self, prob['sin_mm.f_x'], .5*np.sin(prob['sin_mm.x']), 1e-4)
def test_math(self): prob = Problem(model=Group()) C1 = prob.model.add_subsystem('C1', ExecComp('y=sin(x)', x=2.0)) prob.setup(check=False) # Conclude setup but don't run model. prob.final_setup() self.assertTrue('x' in C1._inputs) self.assertTrue('y' in C1._outputs) prob.set_solver_print(level=0) prob.run_model() assert_rel_error(self, C1._outputs['y'], math.sin(2.0), 0.00001)
def test_dot_petsc(self): if not PETScVector: raise unittest.SkipTest("PETSc is not installed") p = Problem() comp = IndepVarComp() comp.add_output('v1', val=1.0) comp.add_output('v2', val=2.0) p.model.add_subsystem('des_vars', comp, promotes=['*']) p.setup() p.final_setup() new_vec = p.model._outputs._clone() new_vec.set_const(3.) self.assertEqual(new_vec.dot(p.model._outputs), 9.)
def test_raise_error_on_dup_partials(self): prob = Problem() model = prob.model model.add_subsystem('des_vars', IndepVarComp('x', 1.0), promotes=['*']) model.add_subsystem('dupcomp', DupPartialsComp()) model.linear_solver = DirectSolver(assemble_jac=True) with self.assertRaises(Exception) as cm: prob.setup(check=False) prob.final_setup() expected_msg = "CSC matrix data contains the following duplicate row/col entries: [(('dupcomp.x', 'dupcomp.c'), [(10, 2)])]\nThis would break internal indexing." self.assertEqual(expected_msg, str(cm.exception))
def test_mixed_type(self): prob = Problem(model=Group()) C1 = prob.model.add_subsystem('C1', ExecComp('y=sum(x)', x=np.arange(10, dtype=float))) prob.setup(check=False) # Conclude setup but don't run model. prob.final_setup() self.assertTrue('x' in C1._inputs) self.assertTrue('y' in C1._outputs) prob.set_solver_print(level=0) prob.run_model() assert_rel_error(self, C1._outputs['y'], 45.0, 0.00001)
def test_mixed_type(self): prob = Problem(model=Group()) C1 = prob.model.add_subsystem( 'C1', ExecComp('y=sum(x)', x=np.arange(10, dtype=float))) prob.setup(check=False) # Conclude setup but don't run model. prob.final_setup() self.assertTrue('x' in C1._inputs) self.assertTrue('y' in C1._outputs) prob.set_solver_print(level=0) prob.run_model() assert_rel_error(self, C1._outputs['y'], 45.0, 0.00001)
def test_pyxdsm_mda(self): filename = 'pyxdsm_mda' out_format = PYXDSM_OUT prob = Problem(model=SellarMDA()) prob.setup(check=False) prob.final_setup() # Write output write_xdsm(prob, filename=filename, out_format=out_format, quiet=QUIET, show_browser=SHOW, include_solver=True) # Check if file was created self.assertTrue(os.path.isfile('.'.join([filename, out_format])))
def test_dot_petsc(self): if not PETScVector: raise unittest.SkipTest("PETSc is not installed") p = Problem() comp = IndepVarComp() comp.add_output('v1', val=1.0) comp.add_output('v2', val=2.0) p.model.add_subsystem('des_vars', comp, promotes=['*']) p.setup(vector_class=PETScVector) p.final_setup() new_vec = p.model._outputs._clone() new_vec.set_const(3.) self.assertEqual(new_vec.dot(p.model._outputs), 9.)
class Test(unittest.TestCase): def setUp(self): group = GroupG() self.p = Problem(group) self.p.model.linear_solver = LinearBlockGS() self.p.setup(check=False) # Conclude setup but don't run model. self.p.final_setup() #view_model(self.p, show_browser=False) def test_apply_linear(self): root = self.p.model self.p.set_solver_print(level=0) d_inputs, d_outputs, d_residuals = root.get_linear_vectors() d_outputs.set_const(1.0) root.run_apply_linear(['linear'], 'fwd') output = d_residuals._data[0] assert_rel_error(self, output, [7, 3]) d_residuals.set_const(1.0) root.run_apply_linear(['linear'], 'rev') output = d_outputs._data[0] assert_rel_error(self, output, [7, 3]) def test_solve_linear(self): root = self.p.model self.p.set_solver_print(level=0) d_inputs, d_outputs, d_residuals = root.get_linear_vectors() d_residuals.set_const(11.0) d_outputs.set_const(0.0) root.run_solve_linear(['linear'], 'fwd') output = d_outputs._data[0] assert_rel_error(self, output, [1, 5], 1e-10) d_outputs.set_const(11.0) d_residuals.set_const(0.0) root.run_solve_linear(['linear'], 'rev') output = d_residuals._data[0] assert_rel_error(self, output, [1, 5], 1e-10)
def test_warning_bug(self): # Make sure we don't warn that we are doing FD when the surrogate has analytic derivs. x_train = np.arange(0., 10.) y_train = np.arange(10., 20.) z_train = x_train**2 + y_train**2 p = Problem() p.model = m = Group() params = IndepVarComp() params.add_output('x', val=0.) params.add_output('y', val=0.) m.add_subsystem('params', params, promotes=['*']) sm = MetaModelUnStructuredComp(default_surrogate=ResponseSurface()) sm.add_input('x', val=0.) sm.add_input('y', val=0.) sm.add_output('z', val=0.) sm.options['train:x'] = x_train sm.options['train:y'] = y_train sm.options['train:z'] = z_train # With or without the line below does not matter # Only when method is set to fd, then RuntimeWarning disappears sm.declare_partials('*', '*', method='exact') m.add_subsystem('sm', sm, promotes=['*']) m.add_design_var('x', lower=0., upper=10.) m.add_design_var('y', lower=0., upper=10.) m.add_objective('z') p.setup(check=True) stderr = sys.stderr str_err = StringIO() sys.stderr = str_err try: p.final_setup() finally: sys.stderr = stderr output = str_err.getvalue() self.assertTrue('finite difference' not in output)
def test_is_local(self): p = Problem() p.model.add_subsystem('indep', IndepVarComp('x', 1.0)) par = p.model.add_subsystem('par', ParallelGroup()) par.add_subsystem('C1', ExecComp('y=2*x')) par.add_subsystem('C2', 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 test_implicit_with_solves(self): prob = Problem() model = prob.model model.add_subsystem('indep', IndepVarComp('y', 1.0)) model.add_subsystem('statecomp', StateConnWithSolves()) model.connect('indep.y', 'statecomp.y2_actual') # perform setup with checks but don't run model testlogger = TestLogger() prob.setup(check=True, logger=testlogger) prob.final_setup() # should not trigger any solver warnings because solve methods are implemented warnings = testlogger.get('warning') self.assertEqual(len(warnings), 0)
def test_model_viewer_has_correct_data_from_problem(self): """ Verify that the correct model structure data exists when stored as compared to the expected structure, using the SellarStateConnection model. """ p = Problem(model=SellarStateConnection()) p.setup() p.final_setup() model_viewer_data = _get_viewer_data(p) # check expected model tree self.check_model_viewer_data( model_viewer_data, self.expected_tree, self.expected_pathnames, self.expected_conns, self.expected_abs2prom, self.expected_declare_partials, self.expected_driver_name, self.expected_design_vars_names, self.expected_responses_names)
def test_array(self): prob = Problem(model=Group()) C1 = prob.model.add_subsystem( 'C1', ExecComp('y=x[1]', x=np.array([1., 2., 3.]), y=0.0)) prob.setup(check=False) # Conclude setup but don't run model. prob.final_setup() self.assertTrue('x' in C1._inputs) self.assertTrue('y' in C1._outputs) prob.set_solver_print(level=0) prob.run_model() assert_rel_error(self, C1._outputs['y'], 2.0, 0.00001)
def test_with_promotion(self): """ Illustrative examples showing how to access variables and subjacs. """ c1 = IndepVarComp('x') c2 = ExecComp('y=2*x') c3 = ExecComp('z=3*x') g = Group() g.add_subsystem('c1', c1, promotes=['*']) g.add_subsystem('c2', c2, promotes=['*']) g.add_subsystem('c3', c3, promotes=['*']) model = Group() model.add_subsystem('g', g, promotes=['*']) p = Problem(model) p.setup(check=False) # ------------------------------------------------------------------- # inputs p['g.c2.x'] = 5.0 self.assertEqual(p['g.c2.x'], 5.0) # outputs p['g.c2.y'] = 5.0 self.assertEqual(p['g.c2.y'], 5.0) p['y'] = 5.0 self.assertEqual(p['y'], 5.0) # Conclude setup but don't run model. p.final_setup() inputs, outputs, residuals = g.get_nonlinear_vectors() # inputs inputs['c2.x'] = 5.0 self.assertEqual(inputs['c2.x'], 5.0) # outputs outputs['c2.y'] = 5.0 self.assertEqual(outputs['c2.y'], 5.0) outputs['y'] = 5.0 self.assertEqual(outputs['y'], 5.0)
def test_dataflow_1_level(self): p = Problem(model=Group()) root = p.model indep = root.add_subsystem("indep", IndepVarComp('x', 1.0)) C1 = root.add_subsystem("C1", MyComp()) C2 = root.add_subsystem("C2", MyComp()) C3 = root.add_subsystem("C3", MyComp()) C4 = root.add_subsystem("C4", MyComp()) root.connect("C4.y", "C2.a") root.connect("C4.y", "C3.a") root.connect("C2.y", "C1.a") root.connect("C1.y", "C4.a") # make sure no system has dangling inputs so we avoid that warning root.connect("indep.x", "C1.b") root.connect("indep.x", "C2.b") root.connect("indep.x", "C3.b") root.connect("indep.x", "C4.b") # set iterative solvers since we have cycles root.linear_solver = LinearBlockGS() root.nonlinear_solver = NonlinearBlockGS() testlogger = TestLogger() p.setup(check=True, logger=testlogger) # Conclude setup but don't run model. p.final_setup() warnings = testlogger.get('warning') info = testlogger.get('info') self.assertEqual(len(warnings), 1) self.assertEqual(len(info), 1) self.assertEqual( info[0], "The following groups contain cycles:\n Group '' has the following cycles: [['C1', 'C2', 'C4']]\n" ) self.assertEqual( warnings[0], "The following systems are executed out-of-order:\n System 'C3' executes out-of-order with respect to its source systems ['C4']\n" )
def test_with_promotion(self): """ Illustrative examples showing how to access variables and subjacs. """ c1 = IndepVarComp('x') c2 = ExecComp('y=2*x') c3 = ExecComp('z=3*x') g = Group() g.add_subsystem('c1', c1, promotes=['*']) g.add_subsystem('c2', c2, promotes=['*']) g.add_subsystem('c3', c3, promotes=['*']) model = Group() model.add_subsystem('g', g, promotes=['*']) p = Problem(model) p.setup() # ------------------------------------------------------------------- # inputs p['g.c2.x'] = 5.0 self.assertEqual(p['g.c2.x'], 5.0) # outputs p['g.c2.y'] = 5.0 self.assertEqual(p['g.c2.y'], 5.0) p['y'] = 5.0 self.assertEqual(p['y'], 5.0) # Conclude setup but don't run model. p.final_setup() inputs, outputs, residuals = g.get_nonlinear_vectors() # inputs inputs['c2.x'] = 5.0 self.assertEqual(inputs['c2.x'], 5.0) # outputs outputs['c2.y'] = 5.0 self.assertEqual(outputs['c2.y'], 5.0) outputs['y'] = 5.0 self.assertEqual(outputs['y'], 5.0)
def test_solve_on_subsystem(self): """solve an implicit system with DirectSolver attached to a subsystem""" p = Problem() model = p.model dv = model.add_subsystem('des_vars', IndepVarComp()) # just need a dummy variable so the sizes don't match between root and g1 dv.add_output('dummy', val=1.0, shape=10) g1 = model.add_subsystem('g1', TestImplicitGroup(lnSolverClass=DirectSolver)) p.setup(check=False) p.set_solver_print(level=0) # Conclude setup but don't run model. p.final_setup() # forward d_inputs, d_outputs, d_residuals = g1.get_linear_vectors() d_residuals.set_const(1.0) d_outputs.set_const(0.0) g1._linearize(g1._assembled_jac) g1.linear_solver._linearize() g1.run_solve_linear(['linear'], 'fwd') output = d_outputs._data # The empty first entry in _data is due to the dummy # variable being in a different variable set not owned by g1 assert_rel_error(self, output[1], g1.expected_solution[0], 1e-15) assert_rel_error(self, output[5], g1.expected_solution[1], 1e-15) # reverse d_inputs, d_outputs, d_residuals = g1.get_linear_vectors() d_outputs.set_const(1.0) d_residuals.set_const(0.0) g1.linear_solver._linearize() g1.run_solve_linear(['linear'], 'rev') output = d_residuals._data assert_rel_error(self, output[1], g1.expected_solution[0], 3e-15) assert_rel_error(self, output[5], g1.expected_solution[1], 3e-15)
def test_unsupported_discrete_desvar(self): prob = Problem() indep = IndepVarComp() indep.add_discrete_output('xI', val=0) prob.model.add_subsystem('p', indep) prob.model.add_design_var('p.xI') prob.driver = ScipyOptimizeDriver() prob.setup() with self.assertRaises(RuntimeError) as context: prob.final_setup() msg = "Discrete design variables are not supported by this driver: p.xI" self.assertEqual(str(context.exception), msg)
def test_array_lhs(self): prob = Problem(model=Group()) C1 = prob.model.add_subsystem('C1', ExecComp(['y[0]=x[1]', 'y[1]=x[0]'], x=np.array([1., 2., 3.]), y=np.array([0., 0.]))) prob.setup(check=False) # Conclude setup but don't run model. prob.final_setup() self.assertTrue('x' in C1._inputs) self.assertTrue('y' in C1._outputs) prob.set_solver_print(level=0) prob.run_model() assert_rel_error(self, C1._outputs['y'], np.array([2., 1.]), 0.00001)
def test_distrib_idx_in_full_out(self): size = 11 p = Problem(model=Group()) top = p.model C1 = top.add_subsystem("C1", InOutArrayComp(size)) C2 = top.add_subsystem("C2", DistribInputComp(size)) top.connect('C1.outvec', 'C2.invec') p.setup(vector_class=PETScVector, check=False) # Conclude setup but don't run model. p.final_setup() C1._inputs['invec'] = np.array(range(size, 0, -1), float) p.run_model() self.assertTrue(all(C2._outputs['outvec'] == np.array(range(size, 0, -1), float)*4))
def test_implicit_with_solves(self): prob = Problem() model = prob.model model.add_subsystem('indep', IndepVarComp('y', 1.0)) model.add_subsystem('statecomp', StateConnWithSolves()) model.connect('indep.y', 'statecomp.y2_actual') # perform setup with checks but don't run model testlogger = TestLogger() prob.setup(check=True, logger=testlogger) prob.final_setup() # should not trigger any solver warnings because solve methods are implemented # but there is a warning about the lack of recorder warnings = testlogger.get('warning') self.assertEqual(len(warnings), 1)
def test_comp_has_no_outputs(self): p = Problem() root = p.model indep = root.add_subsystem("indep", IndepVarComp('x', 1.0)) comp1 = root.add_subsystem("comp1", ExplicitComponent()) comp1.add_input('x', val=0.) root.connect('indep.x', 'comp1.x') testlogger = TestLogger() p.setup(check=True, logger=testlogger) p.final_setup() expected = ("The following Components do not have any outputs:\n" " comp1\n") self.assertTrue(testlogger.contains('warning', expected))
def test_solve_on_subsystem(self): """solve an implicit system with GMRES attached to a subsystem""" p = Problem() model = p.model = Group() dv = model.add_subsystem('des_vars', IndepVarComp()) # just need a dummy variable so the sizes don't match between root and g1 dv.add_output('dummy', val=1.0, shape=10) grp = TestImplicitGroup(lnSolverClass=self.linear_solver_class) g1 = model.add_subsystem('g1', grp) p.model.linear_solver.options['maxiter'] = 1 p.setup(check=False) p.set_solver_print(level=0) # Conclude setup but don't run model. p.final_setup() # forward d_inputs, d_outputs, d_residuals = g1.get_linear_vectors() d_residuals.set_const(1.0) d_outputs.set_const(0.0) g1.run_solve_linear(['linear'], 'fwd') output = d_outputs._data # The empty first entry in _data is due to the dummy # variable being in a different variable set not owned by g1 assert_rel_error(self, output[1], g1.expected_solution[0], 1e-15) assert_rel_error(self, output[5], g1.expected_solution[1], 1e-15) # reverse d_inputs, d_outputs, d_residuals = g1.get_linear_vectors() d_outputs.set_const(1.0) d_residuals.set_const(0.0) g1.linear_solver._linearize() g1.run_solve_linear(['linear'], 'rev') output = d_residuals._data assert_rel_error(self, output[1], g1.expected_solution[0], 3e-15) assert_rel_error(self, output[5], g1.expected_solution[1], 3e-15)
def test_implicit_without_solve_nonlinear(self): prob = Problem() model = prob.model model.add_subsystem('indep', IndepVarComp('y', 1.0)) model.add_subsystem('statecomp', StateConnWithSolveLinear()) model.connect('indep.y', 'statecomp.y2_actual') # perform setup with checks but don't run model testlogger = TestLogger() prob.setup(check=True, logger=testlogger) prob.final_setup() # should trigger solver warning because there is no nonlinear solve self.assertTrue(testlogger.contains('warning', "StateConnWithSolveLinear 'statecomp' contains implicit " "variables, but does not have an iterative nonlinear solver " "and does not implement 'solve_nonlinear'."))
def test_distrib_full_in_out(self): size = 11 p = Problem(model=Group()) top = p.model C1 = top.add_subsystem("C1", InOutArrayComp(size)) C2 = top.add_subsystem("C2", DistribCompSimple(size)) top.connect('C1.outvec', 'C2.invec') p.setup(check=False) # Conclude setup but don't run model. p.final_setup() C1._inputs['invec'] = np.ones(size, float) * 5.0 p.run_model() self.assertTrue(all(C2._outputs['outvec'] == np.ones(size, float)*7.5))
def test_hierarchy_iprint(self): prob = Problem() model = prob.model model.add_subsystem('pz', IndepVarComp('z', np.array([5.0, 2.0]))) sub1 = model.add_subsystem('sub1', Group()) sub2 = sub1.add_subsystem('sub2', Group()) g1 = sub2.add_subsystem('g1', SubSellar()) g2 = model.add_subsystem('g2', SubSellar()) model.connect('pz.z', 'sub1.sub2.g1.z') model.connect('sub1.sub2.g1.y2', 'g2.x') model.connect('g2.y2', 'sub1.sub2.g1.x') model.nonlinear_solver = NewtonSolver() model.linear_solver = ScipyKrylov() model.nonlinear_solver.options['solve_subsystems'] = True model.nonlinear_solver.options['max_sub_solves'] = 0 g1.nonlinear_solver = NewtonSolver() g1.linear_solver = LinearBlockGS() g2.nonlinear_solver = NewtonSolver() g2.linear_solver = ScipyKrylov() g2.linear_solver.precon = LinearBlockGS() g2.linear_solver.precon.options['maxiter'] = 2 prob.set_solver_print(level=2) prob.setup(check=False) # Conclude setup but don't run model. prob.final_setup() # if USE_PROC_FILES is not set, solver convergence messages # should only appear on proc 0 output = run_model(prob) if model.comm.rank == 0 or os.environ.get('USE_PROC_FILES'): self.assertTrue(output.count('\nNL: Newton Converged') == 1) else: self.assertTrue(output.count('\nNL: Newton Converged') == 0)