def test_desvar_inf_bounds(self): # make sure no overflow when there is no specified upper/lower bound and significatn scaling prob = om.Problem() prob.model = SellarDerivatives() prob.model.nonlinear_solver = om.NonlinearBlockGS() prob.model.add_design_var('x', scaler=1e6) prob.model.add_objective('obj', scaler=1e6) prob.model.add_constraint('con1', scaler=1e6) prob.model.add_constraint('con2', scaler=1e6) prob.setup() des_vars = prob.model.get_design_vars() self.assertFalse(np.isinf(des_vars['x']['upper'])) self.assertFalse(np.isinf(-des_vars['x']['lower'])) responses = prob.model.get_responses() self.assertFalse(np.isinf(responses['con_cmp1.con1']['upper'])) self.assertFalse(np.isinf(responses['con_cmp2.con2']['upper'])) self.assertFalse(np.isinf(-responses['con_cmp1.con1']['lower'])) self.assertFalse(np.isinf(-responses['con_cmp2.con2']['lower']))
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.Group(), 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(iprint=1) # try iprint=2 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_desvar_affine_mapping(self): prob = om.Problem() prob.model = SellarDerivatives() prob.model.nonlinear_solver = om.NonlinearBlockGS() prob.model.add_design_var('x', lower=-100, upper=100, ref0=-100.0, ref=100) prob.model.add_design_var('z', lower=-100, upper=100) prob.model.add_objective('obj') prob.model.add_constraint('con1') prob.model.add_constraint('con2') prob.setup() des_vars = prob.model.get_design_vars() x_ref0 = des_vars['x']['ref0'] x_ref = des_vars['x']['ref'] x_scaler = des_vars['x']['scaler'] x_adder = des_vars['x']['adder'] self.assertAlmostEqual(x_scaler * (x_ref0 + x_adder), 0.0, places=12) self.assertAlmostEqual(x_scaler * (x_ref + x_adder), 1.0, places=12)
def test_distributed_norm_distcomp(self): prob = om.Problem() top_group = prob.model top_group.add_subsystem("distributed_quad", DistribQuadtric(size=3)) top_group.add_subsystem("serial_linear", SerialLinear(size=3)) # Connect variables between components top_group.connect('serial_linear.x', 'distributed_quad.x') top_group.connect('distributed_quad.y', 'serial_linear.y', src_indices=om.slicer[:]) # Need a nonlinear solver since the model is coupled top_group.nonlinear_solver = om.NonlinearBlockGS(iprint=0, maxiter=20) prob.setup() prob.run_model() vec = prob.model._vectors['output']['nonlinear'] norm_val = vec.get_norm() assert_near_equal(norm_val, 0.22595230821097395, 1e-10) # test petsc dot while we're at it vec.set_val(3.) vec2 = prob.model._vectors['residual']['linear'] vec2.set_val(4.) assert_near_equal(vec.dot(vec2), 12. * 6, 1e-10)
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])) self.add_subsystem("d1", SellarDis1(), promotes=["y1", "y2"]) self.add_subsystem("d2", SellarDis2(), promotes=["y1", "y2"]) self.connect("x", "d1.x") self.connect("z", ["d1.z", "d2.z"]) # Nonlinear Block Gauss Seidel is a gradient free solver to handle implicit loops self.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 setup(self): self.add_subsystem('px', om.IndepVarComp('x', 1.0), promotes=['x']) self.add_subsystem('pz', om.IndepVarComp('z', np.array([5.0, 2.0])), promotes=['z']) cycle = self.add_subsystem('cycle', om.Group(), promotes=['x', 'z', 'y1', 'y2']) d1 = cycle.add_subsystem('d1', SellarDis1CS(), promotes=['x', 'z', 'y1', 'y2']) d2 = cycle.add_subsystem('d2', SellarDis2CS(), promotes=['z', 'y1', 'y2']) 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']) self.nonlinear_solver = om.NonlinearBlockGS() self.linear_solver = om.ScipyKrylov()
def setup(self): indeps = self.add_subsystem('indeps', om.IndepVarComp()) indeps.add_output('x', 1.0) indeps.add_output('z', np.array([5.0, 2.0])) cycle = self.add_subsystem('cycle', om.Group()) cycle.add_subsystem('d1', SellarDis1()) cycle.add_subsystem('d2', SellarDis2()) cycle.connect('d1.y1', 'd2.y1') cycle.connect('d2.y2', 'd1.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)) self.add_subsystem('con_cmp1', om.ExecComp('con1 = 3.16 - y1')) self.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0')) self.connect('indeps.x', ['cycle.d1.x', 'obj_cmp.x']) self.connect('indeps.z', ['cycle.d1.z', 'cycle.d2.z', 'obj_cmp.z']) self.connect('cycle.d1.y1', ['obj_cmp.y1', 'con_cmp1.y1']) self.connect('cycle.d2.y2', ['obj_cmp.y2', 'con_cmp2.y2'])
def setup(self): cycle = self.add_subsystem('cycle', om.Group(), promotes=['*']) d1 = cycle.add_subsystem('d1', SellarDis1(), promotes_inputs=['x', 'z', 'y2'], promotes_outputs=['y1']) d2 = cycle.add_subsystem('d2', SellarDis2(), promotes_inputs=['z', 'y1'], promotes_outputs=['y2']) self.set_input_defaults('x', 1.0) self.set_input_defaults('z', np.array([5.0, 2.0])) cycle.nonlinear_solver = om.NonlinearBlockGS() cycle.linear_solver = om.DirectSolver() 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_pyxdsm_solver(self): import openmdao.api as om out_format = PYXDSM_OUT p = om.Problem() p.model = model = SellarNoDerivatives() model.nonlinear_solver = om.NonlinearBlockGS() p.driver = om.ScipyOptimizeDriver() p.model.add_objective('obj') p.setup() p.run_model() filename = 'pyxdsm_solver' # 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)) filename = 'pyxdsm_solver2' # Write output write_xdsm(p, filename=filename, out_format=out_format, quiet=QUIET, show_browser=SHOW, include_solver=True, recurse=False) # Check if file was created self.assertTrue(os.path.isfile(filename + '.' + out_format))
def test_specify_subgroup_solvers(self): import openmdao.api as om from openmdao.test_suite.components.double_sellar import DoubleSellar prob = om.Problem() model = prob.model = DoubleSellar() # each SubSellar group converges itself g1 = model.g1 g1.nonlinear_solver = om.NewtonSolver(solve_subsystems=False) g1.linear_solver = om.DirectSolver() # used for derivatives g2 = model.g2 g2.nonlinear_solver = om.NewtonSolver(solve_subsystems=False) g2.linear_solver = om.DirectSolver() # Converge the outer loop with Gauss Seidel, with a looser tolerance. model.nonlinear_solver = om.NonlinearBlockGS(rtol=1.0e-5) model.linear_solver = om.ScipyKrylov() model.linear_solver.precon = om.LinearBlockGS() prob.setup() prob.run_model() assert_near_equal(prob.get_val('g1.y1'), 0.64, .00001) assert_near_equal(prob.get_val('g1.y2'), 0.80, .00001) assert_near_equal(prob.get_val('g2.y1'), 0.64, .00001) assert_near_equal(prob.get_val('g2.y2'), 0.80, .00001)
def setup(self): cycle = self.add_subsystem('cycle', om.Group(), promotes=['*']) cycle.add_subsystem('d1', SellarDis1(), promotes_inputs=['x', 'z']) cycle.add_subsystem('d2', SellarDis2(), promotes_inputs=['z']) cycle.connect('d1.y1', 'd2.y1') cycle.connect('d2.y2', 'd1.y2') cycle.set_input_defaults('x', 1.0) cycle.set_input_defaults('z', np.array([5.0, 2.0])) # 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_inputs=['x', 'z']) self.add_subsystem('con_cmp1', om.ExecComp('con1 = 3.16 - y1')) self.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0')) self.connect('d1.y1', ['con_cmp1.y1', 'obj_cmp.y1']) self.connect('d2.y2', ['con_cmp2.y2', 'obj_cmp.y2'])
def setup(self): self.add_subsystem('c1', om.ExecComp('y = 2.7951 + 10.56*x**2 - 5.4*x**3 + 0.5*x**4'), promotes=['*']) self.add_subsystem('c2', om.ExecComp('x = y/8.954'), promotes=['*']) self.nonlinear_solver = om.NonlinearBlockGS() self.nonlinear_solver.options['maxiter'] = 100 self.nonlinear_solver.options['atol'] = 1e-6
def test_api_response_on_model(self): prob = om.Problem() prob.model = SellarDerivatives() prob.model.nonlinear_solver = om.NonlinearBlockGS() prob.model.add_design_var('x', lower=-100, upper=100) prob.model.add_design_var('z', lower=-100, upper=100) prob.model.add_response('obj', type_="obj") prob.model.add_response('con1', type_="con") prob.model.add_response('con2', type_="con") prob.setup() des_vars = prob.model.get_design_vars() responses = prob.model.get_responses() obj = prob.model.get_objectives() constraints = prob.model.get_constraints() self.assertEqual(set(des_vars.keys()), {'x', 'z'}) self.assertEqual(set(obj.keys()), {'obj_cmp.obj'}) self.assertEqual(set(constraints.keys()), {'con_cmp1.con1', 'con_cmp2.con2'}) self.assertEqual(set(responses.keys()), {'obj_cmp.obj', 'con_cmp1.con1', 'con_cmp2.con2'})
def test_constraint_affine_mapping(self): prob = om.Problem() prob.model = SellarDerivatives() prob.model.nonlinear_solver = om.NonlinearBlockGS() 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', lower=-100, upper=100, ref0=-100.0, ref=100) prob.model.add_constraint('con2') prob.setup() constraints = prob.model.get_constraints() con1_ref0 = constraints['con_cmp1.con1']['ref0'] con1_ref = constraints['con_cmp1.con1']['ref'] con1_scaler = constraints['con_cmp1.con1']['scaler'] con1_adder = constraints['con_cmp1.con1']['adder'] self.assertAlmostEqual(con1_scaler * (con1_ref0 + con1_adder), 0.0, places=12) self.assertAlmostEqual(con1_scaler * (con1_ref + con1_adder), 1.0, places=12)
def test_feature_maxiter(self): import numpy as np import openmdao.api as om from openmdao.test_suite.components.sellar import SellarDis1withDerivatives, SellarDis2withDerivatives 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']) model.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2']) model.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']) nlbgs = model.nonlinear_solver = om.NonlinearBlockGS() nlbgs.options['maxiter'] = 2 prob.setup() prob.set_solver_print() prob.run_model() assert_near_equal(prob['y1'], 25.58914915, .00001) assert_near_equal(prob['y2'], 12.05857185, .00001)
def test_NLBGS_Aitken_initial_factor(self): prob = om.Problem(model=SellarDerivatives()) model = prob.model model.nonlinear_solver = om.NonlinearBlockGS() prob.setup() y1_0 = prob.get_val('y1') y2_0 = prob.get_val('y2') model.nonlinear_solver.options['use_aitken'] = True model.nonlinear_solver.options['aitken_initial_factor'] = 0.33 model.nonlinear_solver.options['maxiter'] = 1 prob.run_model() self.assertTrue(model.nonlinear_solver._theta_n_1 == 0.33) model.nonlinear_solver.options['maxiter'] = 10 prob.run_model() # should converge to the same solution assert_near_equal(prob.get_val('y1'), 25.58830273, .00001) assert_near_equal(prob.get_val('y2'), 12.05848819, .00001) # in more iterations self.assertTrue(model.nonlinear_solver._iter_count == 7) #check that the relaxation factor is updated correctly (should tend towards 1) assert_near_equal(model.nonlinear_solver._theta_n_1, 1.00, 0.001)
def test_sellar_analysis_error(self): # Tests Sellar behavior when AnalysisError is raised. 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']) model.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2']) model.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']) nlbgs = model.nonlinear_solver = om.NonlinearBlockGS() nlbgs.options['maxiter'] = 2 nlbgs.options['err_on_non_converge'] = True prob.setup() prob.set_solver_print(level=0) 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_res_ref(self): class ContrivedSellarDis1(SellarDis1): def setup(self): super().setup() self.add_output('highly_nonlinear', val=1.0, res_ref=1e-4) def compute(self, inputs, outputs): super().compute(inputs, outputs) outputs['highly_nonlinear'] = 10 * np.sin(10 * inputs['y2']) p = om.Problem() model = p.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']) model.add_subsystem('d1', ContrivedSellarDis1(), promotes=['x', 'z', 'y1', 'y2']) model.add_subsystem('d2', SellarDis2(), promotes=['z', 'y1', 'y2']) nlbgs = model.nonlinear_solver = om.NonlinearBlockGS() nlbgs.options['maxiter'] = 20 nlbgs.options['atol'] = 1e-6 nlbgs.options['rtol'] = 1e-100 p.setup() p.run_model() self.assertEqual(nlbgs._iter_count, 10, 'res_ref should make this take more iters.')
def test_feature_atol(self): import numpy as np import openmdao.api as om from openmdao.test_suite.components.sellar import SellarDis1withDerivatives, SellarDis2withDerivatives prob = om.Problem() model = prob.model model.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2']) model.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']) nlbgs = model.nonlinear_solver = om.NonlinearBlockGS() nlbgs.options['atol'] = 1e-4 prob.setup() prob.set_val('x', 1.) prob.set_val('z', np.array([5.0, 2.0])) prob.run_model() assert_near_equal(prob.get_val('y1'), 25.5882856302, .00001) assert_near_equal(prob.get_val('y2'), 12.05848819, .00001)
def setup(self): indeps = self.add_subsystem('indeps', om.IndepVarComp(), promotes=['*']) indeps.add_output('x1', 1.0) indeps.add_output('x2', 1.0) indeps.add_output('x3', 1.0) cycle = self.add_subsystem('cycle', om.Group(), promotes=['*']) cycle.add_subsystem('d1', Analysis1(), promotes_inputs=['x1', 'x2', 'y12'], promotes_outputs=['y21', 'g1']) cycle.add_subsystem('d2', Analysis2(), promotes_inputs=['x1', 'x2', 'x3', 'y21'], promotes_outputs=['y12', 'g2']) # Nonlinear Block Gauss Seidel is a gradient free solver cycle.nonlinear_solver = om.NonlinearBlockGS() self.add_subsystem('obj_cmp', om.ExecComp('obj = x1**2 + x2**2 + x3**2 ', x1=0.0, x2=0.0, x3=0.0), promotes=['x1', 'x2', 'x3', 'obj']) self.add_subsystem('con_cmp1', om.ExecComp('con1 = g1'), promotes=['con1', 'g1']) self.add_subsystem('con_cmp2', om.ExecComp('con2 = g2'), promotes=['con2', 'g2'])
def test_multi_cycles_non_default(self): p = om.Problem() root = p.model root.add_subsystem("indep", om.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', om.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 = om.LinearBlockGS() root.nonlinear_solver = om.NonlinearBlockGS() testlogger = TestLogger() p.setup(check=['cycles', 'out_of_order', 'unconnected_inputs'], logger=testlogger) p.final_setup() expected_info = ( "The following groups contain cycles:\n" " Group 'G1' has the following cycles: " "[['C13', 'C12', 'C11'], ['C23', 'C22', 'C21'], ['C3', 'C2', 'C1']]\n" ) 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('info', expected_info) testlogger.find_in('warning', expected_warning_1)
def test_specify_solver(self): import numpy as np import openmdao.api as om from openmdao.test_suite.components.sellar import SellarDis1withDerivatives, SellarDis2withDerivatives 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']) model.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2']) model.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']) model.nonlinear_solver = om.NonlinearBlockGS() model.linear_solver = om.LinearBlockJac() prob.setup() prob.run_model() wrt = ['z'] of = ['obj'] J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') assert_near_equal(J['obj', 'z'][0][0], 9.61001056, .00001) assert_near_equal(J['obj', 'z'][0][1], 1.78448534, .00001)
def test_api_array_on_model(self): prob = om.Problem() prob.model = SellarDerivatives() prob.model.nonlinear_solver = om.NonlinearBlockGS() prob.model.add_design_var('x', lower=-100, upper=100) prob.model.add_design_var('z', lower=np.array([-100, -20]), upper=np.array([100, 20])) prob.model.add_objective('obj') prob.model.add_constraint('con1') prob.model.add_constraint('con2') prob.setup() des_vars = prob.model.get_design_vars() obj = prob.model.get_objectives() constraints = prob.model.get_constraints() self.assertEqual(set(des_vars.keys()), {'x', 'z'}) self.assertEqual(set(obj.keys()), { 'obj_cmp.obj', }) self.assertEqual(set(constraints.keys()), {'con_cmp1.con1', 'con_cmp2.con2'})
def test_objective_affine_mapping(self): prob = om.Problem() prob.model = SellarDerivatives() prob.model.nonlinear_solver = om.NonlinearBlockGS() 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', ref0=1000, ref=1010) prob.model.add_objective('con2') prob.setup() objectives = prob.model.get_objectives() obj_ref0 = objectives['obj_cmp.obj']['ref0'] obj_ref = objectives['obj_cmp.obj']['ref'] obj_scaler = objectives['obj_cmp.obj']['scaler'] obj_adder = objectives['obj_cmp.obj']['adder'] self.assertAlmostEqual(obj_scaler * (obj_ref0 + obj_adder), 0.0, places=12) self.assertAlmostEqual(obj_scaler * (obj_ref + obj_adder), 1.0, places=12)
def test_constraint_invalid_bounds(self): prob = om.Problem() prob.model = SellarDerivatives() prob.model.nonlinear_solver = om.NonlinearBlockGS() with self.assertRaises(TypeError) as context: prob.model.add_design_var('x', lower='foo', upper=[0, 100], ref0=-100.0, ref=100) self.assertEqual( str(context.exception), 'Expected values of lower to' ' be an Iterable of numeric' ' values, or a scalar numeric' ' value. Got foo instead.') with self.assertRaises(ValueError) as context: prob.model.add_design_var('x', lower=0.0, upper=['a', 'b'], ref0=-100.0, ref=100)
def test_get_variables_from_problem_sellar_without_promotion_without_computation(): group = om.Group() indeps = group.add_subsystem("indeps", om.IndepVarComp()) indeps.add_output("x", 1.0, units="Pa") indeps.add_output("z", [5.0, 2.0], units="m**2") group.add_subsystem("disc2", Disc2()) group.add_subsystem("disc1", Disc1()) group.add_subsystem("functions", Functions()) group.nonlinear_solver = om.NonlinearBlockGS() group.connect("indeps.x", "disc1.x") group.connect("indeps.x", "functions.x") group.connect("indeps.z", "disc1.z") group.connect("indeps.z", "disc2.z") group.connect("indeps.z", "functions.z") group.connect("disc1.y1", "disc2.y1") group.connect("disc1.y1", "functions.y1") group.connect("disc2.y2", "disc1.y2") group.connect("disc2.y2", "functions.y2") problem = om.Problem(group) expected_vars = [ Variable(name="indeps.x", value=np.array([1.0]), units="Pa", is_input=True), Variable(name="indeps.z", value=np.array([5.0, 2.0]), units="m**2", is_input=True), Variable(name="disc1.x", value=np.array([np.nan]), units=None, is_input=True), Variable(name="disc1.z", value=np.array([5.0, 2.0]), units="m**2", is_input=True), Variable(name="disc1.y1", value=np.array([1.0]), units=None, is_input=False), Variable(name="disc1.y2", value=np.array([1.0]), units=None, is_input=False), Variable(name="disc2.z", value=np.array([5.0, 2.0]), units="m**2", is_input=False), Variable(name="disc2.y1", value=np.array([1.0]), units=None, is_input=False), Variable(name="disc2.y2", value=np.array([1.0]), units=None, is_input=False), Variable(name="functions.x", value=np.array([2]), units=None, is_input=True), Variable(name="functions.z", value=np.array([np.nan, np.nan]), units="m**2", is_input=True), Variable(name="functions.y1", value=np.array([1.0]), units=None, is_input=False), Variable(name="functions.y2", value=np.array([1.0]), units=None, is_input=False), Variable(name="functions.g1", value=np.array([1.0]), units=None, is_input=False), Variable(name="functions.g2", value=np.array([1.0]), units=None, is_input=False), Variable(name="functions.f", value=np.array([1.0]), units=None, is_input=False), ] _test_and_check_get_variables_from_problem(problem, True, expected_vars) expected_computed_vars = [ # Here links are done, even without computations Variable(name="indeps.x", value=np.array([1.0]), units="Pa"), Variable(name="indeps.z", value=np.array([5.0, 2.0]), units="m**2"), Variable(name="disc1.x", value=np.array([1.0]), units=None), Variable(name="disc1.z", value=np.array([5.0, 2.0]), units="m**2"), Variable(name="disc1.y1", value=np.array([1.0]), units=None), Variable(name="disc1.y2", value=np.array([1.0]), units=None), Variable(name="disc2.z", value=np.array([5.0, 2.0]), units="m**2"), Variable(name="disc2.y1", value=np.array([1.0]), units=None), Variable(name="disc2.y2", value=np.array([1.0]), units=None), Variable(name="functions.x", value=np.array([1.0]), units=None), Variable(name="functions.z", value=np.array([5.0, 2.0]), units="m**2"), Variable(name="functions.y1", value=np.array([1.0]), units=None), Variable(name="functions.y2", value=np.array([1.0]), units=None), Variable(name="functions.g1", value=np.array([1.0]), units=None), Variable(name="functions.g2", value=np.array([1.0]), units=None), Variable(name="functions.f", value=np.array([1.0]), units=None), ] _test_and_check_get_variables_from_problem(problem, False, expected_computed_vars)
def __init__(self): super().__init__() self.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2']) self.add_subsystem('d2', SellarDis2withDerivatives(), promotes=['z', 'y1', 'y2']) self.nonlinear_solver = om.NonlinearBlockGS() self.linear_solver = om.ScipyKrylov()
def test_breguet_with_rubber_engine(): ivc = om.IndepVarComp() ivc.add_output("data:mission:sizing:main_route:cruise:altitude", 35000, units="ft") ivc.add_output("data:TLAR:cruise_mach", 0.78) ivc.add_output("data:TLAR:range", 500, units="NM") ivc.add_output("data:TLAR:NPAX", 150) ivc.add_output("data:aerodynamics:aircraft:cruise:L_D_max", 16.0) ivc.add_output("data:weight:aircraft:MTOW", 74000, units="kg") ivc.add_output("data:propulsion:rubber_engine:bypass_ratio", 5) ivc.add_output("data:propulsion:rubber_engine:maximum_mach", 0.95) ivc.add_output("data:propulsion:rubber_engine:design_altitude", 35000, units="ft") ivc.add_output("data:propulsion:MTO_thrust", 100000, units="N") ivc.add_output("data:propulsion:rubber_engine:overall_pressure_ratio", 30) ivc.add_output("data:propulsion:rubber_engine:turbine_inlet_temperature", 1500, units="K") # With rubber engine OM component group = om.Group() group.add_subsystem("breguet", OMBreguet(), promotes=["*"]) group.add_subsystem("engine", OMRubberEngineComponent(), promotes=["*"]) group.nonlinear_solver = om.NonlinearBlockGS() problem = run_system(group, ivc) assert_allclose(problem["data:mission:sizing:ZFW"], 65076.0, atol=1) assert_allclose(problem["data:mission:sizing:fuel"], 8924.0, atol=1) assert_allclose(problem["data:mission:sizing:fuel:unitary"], 0.0642, rtol=1e-3) # With direct call to rubber engine problem2 = run_system( OMBreguet(propulsion_id="fastoad.wrapper.propulsion.rubber_engine"), ivc) assert_allclose(problem2["data:mission:sizing:ZFW"], 65076.0, atol=1) assert_allclose(problem2["data:mission:sizing:fuel"], 8924.0, atol=1) assert_allclose(problem2["data:mission:sizing:fuel:unitary"], 0.0642, rtol=1e-3) engine = RubberEngine(5, 30, 1500, 100000, 0.95, 35000 * foot, -50) directly_computed_flight_point = FlightPoint( mach=0.78, altitude=35000 * foot, engine_setting=EngineSetting.CRUISE, thrust=problem["data:propulsion:required_thrust"], ) engine.compute_flight_points(directly_computed_flight_point) assert_allclose( directly_computed_flight_point.sfc, problem["data:propulsion:SFC"], )
def test_api_on_subsystems(self): prob = om.Problem() model = prob.model model.add_subsystem('px', om.IndepVarComp('x', 1.0)) model.add_subsystem('pz', om.IndepVarComp('z', np.array([5.0, 2.0]))) model.add_subsystem('d1', SellarDis1withDerivatives()) model.add_subsystem('d2', SellarDis2withDerivatives()) 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)) model.add_subsystem('con_cmp1', om.ExecComp('con1 = 3.16 - y1')) model.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0')) model.connect('px.x', ['d1.x', 'obj_cmp.x']) model.connect('pz.z', ['d1.z', 'd2.z', 'obj_cmp.z']) model.connect('d1.y1', ['d2.y1', 'obj_cmp.y1', 'con_cmp1.y1']) model.connect('d2.y2', ['d1.y2', 'obj_cmp.y2', 'con_cmp2.y2']) model.nonlinear_solver = om.NonlinearBlockGS() model.linear_solver = om.ScipyKrylov() px = prob.model.px px.add_design_var('x', lower=-100, upper=100) pz = prob.model.pz pz.add_design_var('z', lower=-100, upper=100) obj = prob.model.obj_cmp obj.add_objective('obj') con_comp1 = prob.model.con_cmp1 con_comp1.add_constraint('con1') con_comp2 = prob.model.con_cmp2 con_comp2.add_constraint('con2') prob.setup() des_vars = prob.model.get_design_vars() obj = prob.model.get_objectives() constraints = prob.model.get_constraints() self.assertEqual(set(des_vars.keys()), {'px.x', 'pz.z'}) self.assertEqual(set(obj.keys()), { 'obj_cmp.obj', }) self.assertEqual(set(constraints.keys()), {'con_cmp1.con1', 'con_cmp2.con2'})
def setup(self): if "::" in self.options["mission_file_path"]: # The configuration file parser will have added the working directory before # the file name. But as the user-provided string begins with "::", we just # have to ignore all before "::". i = self.options["mission_file_path"].index("::") file_name = self.options["mission_file_path"][i + 2:] + ".yml" with path(resources, file_name) as mission_input_file: self.options["mission_file_path"] = MissionDefinition( mission_input_file) mission_wrapper = MissionWrapper(self.options["mission_file_path"]) if self.options["mission_name"] is None: self.options[ "mission_name"] = mission_wrapper.get_unique_mission_name() mission_name = self.options["mission_name"] self.add_subsystem("ZFW_computation", self._get_zfw_component(mission_name), promotes=["*"]) if self.options["adjust_fuel"]: self.options["compute_TOW"] = True self.connect( "data:mission:%s:needed_block_fuel" % mission_name, "data:mission:%s:block_fuel" % mission_name, ) if self.options["add_solver"]: self.nonlinear_solver = om.NonlinearBlockGS(maxiter=30, rtol=1.0e-4, iprint=0) self.linear_solver = om.DirectSolver() if self.options["compute_TOW"]: self.add_subsystem("TOW_computation", self._get_tow_component(mission_name), promotes=["*"]) else: self.add_subsystem( "block_fuel_computation", self._get_block_fuel_component(mission_name), promotes=["*"], ) mission_options = dict(self.options.items()) del mission_options["adjust_fuel"] del mission_options["compute_TOW"] del mission_options["add_solver"] del mission_options["mission_file_path"] mission_options["mission_wrapper"] = mission_wrapper mission_options["mission_name"] = mission_name self.add_subsystem("mission_computation", MissionComponent(**mission_options), promotes=["*"])