def test_reports_system_mpi_basic( self): # example taken from TestScipyOptimizeDriverMPI setup_default_reports() prob = om.Problem() prob.model = SellarMDA() prob.driver = om.ScipyOptimizeDriver(optimizer='SLSQP', tol=1e-8) prob.model.add_design_var('x', lower=0, upper=10) prob.model.add_design_var('z', lower=0, upper=10) prob.model.add_objective('obj') prob.model.add_constraint('con1', upper=0) prob.model.add_constraint('con2', upper=0) prob.setup() prob.set_solver_print(level=0) prob.run_driver() # get the path to the problem subdirectory problem_reports_dir = pathlib.Path(_reports_dir).joinpath(prob._name) path = pathlib.Path(problem_reports_dir).joinpath(self.n2_filename) self.assertTrue(path.is_file(), f'The N2 report file, {str(path)} was not found') path = pathlib.Path(problem_reports_dir).joinpath( self.scaling_filename) self.assertTrue( path.is_file(), f'The scaling report file, {str(path)}, was not found')
def test_xdsmjs_mdf(self): filename = 'xdsmjs_mdf' out_format = 'html' prob = om.Problem(model=SellarMDA()) model = prob.model prob.driver = om.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() prob.final_setup() # Write output om.write_xdsm(prob, filename=filename, out_format=out_format, show_browser=SHOW, include_solver=True) # Check if file was created self.assertTrue(os.path.isfile('.'.join([filename, out_format])))
def test_sellar_opt(self): import openmdao.api as om from openmdao.test_suite.components.sellar_feature import SellarMDA prob = om.Problem() prob.model = SellarMDA() prob.driver = om.ScipyOptimizeDriver() prob.driver.options['optimizer'] = 'SLSQP' # prob.driver.options['maxiter'] = 100 prob.driver.options['tol'] = 1e-8 prob.model.add_design_var('x', lower=0, upper=10) prob.model.add_design_var('z', lower=0, upper=10) prob.model.add_objective('obj') prob.model.add_constraint('con1', upper=0) prob.model.add_constraint('con2', upper=0) prob.setup() prob.set_solver_print(level=0) # Ask OpenMDAO to finite-difference across the model to compute the gradients for the optimizer prob.model.approx_totals() prob.run_driver() print('minimum found at') assert_near_equal(prob['x'][0], 0., 1e-5) assert_near_equal(prob['z'], [1.977639, 0.], 1e-5) print('minumum objective') assert_near_equal(prob['obj'][0], 3.18339395045, 1e-5)
def test_pyxdsm_mda(self): filename = 'pyxdsm_mda' out_format = PYXDSM_OUT p = om.Problem(model=SellarMDA()) p.setup() p.final_setup() # Write output write_xdsm(p, filename=filename, out_format=out_format, quiet=QUIET, show_browser=SHOW, include_solver=True) # Check if file was created self.assertTrue(os.path.isfile(filename + '.' + out_format))
def test_sellar(self): prob = om.Problem() prob.model = SellarMDA() prob.setup() prob.run_model() assert_near_equal(prob['y1'], 25.58830273, .00001) assert_near_equal(prob['y2'], 12.05848819, .00001) # Make sure we aren't iterating like crazy self.assertLess(prob.model.nonlinear_solver._iter_count, 8)
def test_xdsmjs_mda(self): filename = 'xdsmjs_mda' out_format = 'html' 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, embed_data=True, embeddable=True, include_solver=True) # Check if file was created self.assertTrue(os.path.isfile('.'.join([filename, out_format])))
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_sellar(self): # Just tests Newton on Sellar with FD derivs. prob = Problem() prob.model = SellarMDA() prob.setup(check=False) prob.run_model() assert_rel_error(self, prob['y1'], 25.58830273, .00001) assert_rel_error(self, prob['y2'], 12.05848819, .00001) # Make sure we aren't iterating like crazy self.assertLess(prob.model.nonlinear_solver._iter_count, 8)
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=False, include_solver=True) # Check if file was created self.assertTrue(os.path.isfile('.'.join([filename, out_format])))
def test_mpi_bug_solver(self): # This test verifies that mpi doesn't hang due to collective calls in the solver. prob = om.Problem() prob.model = SellarMDA() prob.model.add_design_var('x', lower=0, upper=10) prob.model.add_design_var('z', lower=0, upper=10) prob.model.add_objective('obj') prob.driver = om.DifferentialEvolutionDriver(run_parallel=True) # Set these low because we don't need to run long. prob.driver.options['max_gen'] = 2 prob.driver.options['pop_size'] = 5 prob.setup() prob.set_solver_print(level=0) prob.run_driver()
def test_sellar(self): self.pb = pb = Problem(SellarMDA()) pb.model.add_design_var("x", lower=0, upper=10) pb.model.add_design_var("z", lower=0, upper=10) pb.model.add_objective("obj") pb.model.add_constraint("con1", upper=0) pb.model.add_constraint("con2", upper=0) pb.driver = OneraSegoDriver(optimizer="SEGOMOE") pb.driver.opt_settings["maxiter"] = 10 self.case_recorder_filename = "test_segomoe_driver_sellar.sqlite" recorder = SqliteRecorder(self.case_recorder_filename) pb.model.add_recorder(recorder) pb.setup() self.pb.run_driver() self.assertTrue(os.path.exists(self.case_recorder_filename)) reader = CaseReader(self.case_recorder_filename) for case_id in reader.list_cases(): case = reader.get_case(case_id) print(case.outputs["obj"])
def test_setup_memleak(self): # Record the memory still in use after each run mem_used = [] # Setup of the Sellar poblem prob = om.Problem() tracemalloc.start() for memtest in ITERS: prob.model = SellarMDA() snapshots = [] for i in range(memtest): prob.setup(check=False) # called here causes memory leak prob.run_driver() totals = prob.compute_totals("z", "x") del totals # Force garbage collection now instead of waiting for an # optimal/arbitrary point since we're tracking memory usage gc.collect() snapshots.append(tracemalloc.take_snapshot()) top_stats = snapshots[memtest - 1].compare_to( snapshots[0], 'lineno') total_mem = 0 for stat in top_stats: tb_str = str(stat.traceback) # Ignore memory allocations by tracemalloc itself, which throw things off: if "/tracemalloc.py:" not in tb_str: total_mem += stat.size mem_used.append(total_mem) tracemalloc.stop() mem_diff = (mem_used[1] - mem_used[0]) / 1024 self.assertLess( mem_diff, MAX_MEM_DIFF_KB, "Memory leak in setup(): %.1f KiB difference between %d and %d iter runs" % (mem_diff, ITERS[0], ITERS[1]))
def test_pyxdsm_mdf(self): filename = 'pyxdsm_mdf' out_format = PYXDSM_OUT p = om.Problem(model=SellarMDA()) model = p.model p.driver = om.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) p.setup() p.final_setup() # Write output write_xdsm(p, filename=filename, out_format=out_format, quiet=QUIET, show_browser=SHOW, include_solver=True) # Check if file was created self.assertTrue(os.path.isfile(filename + '.' + out_format))
import openmdao.api as om from openmdao.test_suite.components.sellar_feature import SellarMDA prob = om.Problem() prob.model = SellarMDA() prob.driver = om.ScipyOptimizeDriver() prob.driver.options['optimizer'] = 'SLSQP' # prob.driver.options['maxiter'] = 100 prob.driver.options['tol'] = 1e-8 prob.model.add_design_var('x', lower=0, upper=10) prob.model.add_design_var('z', lower=0, upper=10) prob.model.add_objective('obj') prob.model.add_constraint('con1', upper=0) prob.model.add_constraint('con2', upper=0) prob.setup() prob.set_solver_print(level=0) # Ask OpenMDAO to finite-difference across the model to compute the gradients for the optimizer prob.model.approx_totals() prob.run_driver() print('minimum found at') print(prob['x'][0]) print(prob['z']) print('minumum objective') print(prob['obj'][0])
def test_pyxdsm_tikz_content(self): # Check if TiKZ file was created. # Compare the content of the sample below and the newly created TiKZ file. # The texts are cleaned up before comparison from whitespaces, line ends and comments # Despite this different versions of pyxdsm *might* produce different outputs. If the test fails for you, # it might be that the program still produces the correct output. # The ordering of some lines might be different at different runs, but the test should work regardless # of these changes. # The sample text should be replaced if changes in the formatting or in the test problem are made. sample_tikz_txt = r""" %%% Preamble Requirements %%% % \usepackage{geometry} % \usepackage{amsfonts} % \usepackage{amsmath} % \usepackage{amssymb} % \usepackage{tikz} % Optional packages such as sfmath set through python interface % \usepackage{sfmath} % \usetikzlibrary{arrows,chains,positioning,scopes,shapes.geometric,shapes.misc,shadows} %%% End Preamble Requirements %%% \input{"path/to/diagram_styles"} \begin{tikzpicture} \matrix[MatrixSetup]{ %Row 0 \node [Optimization] (Driver) {$\text{\text{0, 10 $ \rightarrow $ 1: Driver}}$};& & & & & & & \\ %Row 1 & \node [Function] (indeps) {$\begin{array}{c}\text{1: indeps} \\ \text{\textit{IndepVarComp}}\end{array}$};& & \node [DataInter] (indeps-cycle@d1) {$\begin{array}{c}x, z\end{array}$};& \node [DataInter] (indeps-cycle@d2) {$\begin{array}{c}z\end{array}$};& \node [DataInter] (indeps-obj@cmp) {$\begin{array}{c}x, z\end{array}$};& & \\ %Row 2 & & \node [MDA] (cycle@solver) {$\text{\text{2, 5 $ \rightarrow $ 3: NL: NLBGS}}$};& \node [DataInter] (cycle@solver-cycle@d1) {$\begin{array}{c}y2^{t}\end{array}$};& \node [DataInter] (cycle@solver-cycle@d2) {$\begin{array}{c}y1^{t}\end{array}$};& & & \\ %Row 3 & & \node [DataInter] (cycle@d1-cycle@solver) {$\begin{array}{c}y1\end{array}$};& \node [Function] (cycle@d1) {$\begin{array}{c}\text{3: d1} \\ \text{\textit{SellarDis1}}\end{array}$};& \node [DataInter] (cycle@d1-cycle@d2) {$\begin{array}{c}y1\end{array}$};& \node [DataInter] (cycle@d1-obj@cmp) {$\begin{array}{c}y1\end{array}$};& \node [DataInter] (cycle@d1-con@cmp1) {$\begin{array}{c}y1\end{array}$};& \\ %Row 4 & & \node [DataInter] (cycle@d2-cycle@solver) {$\begin{array}{c}y2\end{array}$};& \node [DataInter] (cycle@d2-cycle@d1) {$\begin{array}{c}y2\end{array}$};& \node [Function] (cycle@d2) {$\begin{array}{c}\text{4: d2} \\ \text{\textit{SellarDis2}}\end{array}$};& \node [DataInter] (cycle@d2-obj@cmp) {$\begin{array}{c}y2\end{array}$};& & \node [DataInter] (cycle@d2-con@cmp2) {$\begin{array}{c}y2\end{array}$};\\ %Row 5 & & & & & \node [Function] (obj@cmp) {$\begin{array}{c}\text{6: obj\_cmp} \\ \text{\textit{ExecComp}}\end{array}$};& & \\ %Row 6 & & & & & & \node [Function] (con@cmp1) {$\begin{array}{c}\text{7: con\_cmp1} \\ \text{\textit{ExecComp}}\end{array}$};& \\ %Row 7 & & & & & & & \node [Function] (con@cmp2) {$\begin{array}{c}\text{8: con\_cmp2} \\ \text{\textit{ExecComp}}\end{array}$};\\ }; % XDSM process chains { [start chain=process] \begin{pgfonlayer}{process} \chainin (Driver); \chainin (indeps) [join=by ProcessHV]; \chainin (cycle@solver) [join=by ProcessHV]; \chainin (obj@cmp) [join=by ProcessHV]; \chainin (con@cmp1) [join=by ProcessHV]; \chainin (con@cmp2) [join=by ProcessHV]; \chainin (Driver) [join=by ProcessHV]; \end{pgfonlayer} }{ [start chain=process] \begin{pgfonlayer}{process} \chainin (cycle@solver); \chainin (cycle@d1) [join=by ProcessHV]; \chainin (cycle@d2) [join=by ProcessHV]; \chainin (cycle@solver) [join=by ProcessHV]; \end{pgfonlayer} } \begin{pgfonlayer}{data} \path % Horizontal edges (cycle@solver) edge [DataLine] (cycle@solver-cycle@d2) (cycle@d1) edge [DataLine] (cycle@d1-cycle@solver) (cycle@solver) edge [DataLine] (cycle@solver-cycle@d1) (cycle@d2) edge [DataLine] (cycle@d2-cycle@solver) (cycle@d1) edge [DataLine] (cycle@d1-obj@cmp) (cycle@d1) edge [DataLine] (cycle@d1-con@cmp1) (cycle@d1) edge [DataLine] (cycle@d1-cycle@d2) (cycle@d2) edge [DataLine] (cycle@d2-obj@cmp) (cycle@d2) edge [DataLine] (cycle@d2-con@cmp2) (cycle@d2) edge [DataLine] (cycle@d2-cycle@d1) (indeps) edge [DataLine] (indeps-cycle@d1) (indeps) edge [DataLine] (indeps-obj@cmp) (indeps) edge [DataLine] (indeps-cycle@d2) % Vertical edges (cycle@solver-cycle@d2) edge [DataLine] (cycle@d2) (cycle@d1-cycle@solver) edge [DataLine] (cycle@solver) (cycle@solver-cycle@d1) edge [DataLine] (cycle@d1) (cycle@d2-cycle@solver) edge [DataLine] (cycle@solver) (cycle@d1-obj@cmp) edge [DataLine] (obj@cmp) (cycle@d1-con@cmp1) edge [DataLine] (con@cmp1) (cycle@d1-cycle@d2) edge [DataLine] (cycle@d2) (cycle@d2-obj@cmp) edge [DataLine] (obj@cmp) (cycle@d2-con@cmp2) edge [DataLine] (con@cmp2) (cycle@d2-cycle@d1) edge [DataLine] (cycle@d1) (indeps-cycle@d1) edge [DataLine] (cycle@d1) (indeps-obj@cmp) edge [DataLine] (obj@cmp) (indeps-cycle@d2) edge [DataLine] (cycle@d2); \end{pgfonlayer} \end{tikzpicture}""" def filter_lines(lns): # Empty lines are excluded. # Leading and trailing whitespaces are removed # Comments are removed. return [ln.strip() for ln in lns if ln.strip() and not ln.strip().startswith('%')] filename = 'pyxdsm_mda_tikz' out_format = PYXDSM_OUT p = om.Problem(model=SellarMDA()) p.setup() p.final_setup() # Write output write_xdsm(p, filename=filename, out_format=out_format, quiet=QUIET, show_browser=SHOW, include_solver=True) # Check if file was created tikz_file = filename + '.tikz' self.assertTrue(os.path.isfile(tikz_file)) sample_lines = sample_tikz_txt.split('\n') sample_lines = filter_lines(sample_lines) with open(tikz_file, "r") as f: new_lines = filter_lines(f.readlines()) no_match_sample = [] # Sample text no_match_new = [] # New text for new_line, sample_line in zip(new_lines, sample_lines): if new_line.startswith(r"\input{"): continue if new_line != sample_line: # else everything is okay # This can be because of the different ordering of lines or because of an error. no_match_sample.append(new_line) no_match_new.append(sample_line) # Sort both sets of suspicious lines no_match_sample.sort() no_match_new.sort() for sample_line, new_line in zip(no_match_sample, no_match_new): # Now the lines should match, if only the ordering was different self.assertEqual(sample_line, new_line) # To be sure, check the length, otherwise a missing last line could get unnoticed because of using zip self.assertEqual(len(new_lines), len(sample_lines))